Decompiled source of KeepInventory v1.3.0

Mods/KeepInventory.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using BoneLib;
using BoneLib.BoneMenu;
using BoneLib.Notifications;
using HarmonyLib;
using Il2CppCysharp.Threading.Tasks;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.Marrow.Data;
using Il2CppSLZ.Marrow.Pool;
using Il2CppSLZ.Marrow.SceneStreaming;
using Il2CppSLZ.Marrow.Utilities;
using Il2CppSLZ.Marrow.Warehouse;
using Il2CppSystem;
using KeepInventory;
using KeepInventory.Fusion;
using KeepInventory.Fusion.Managers;
using KeepInventory.Helper;
using KeepInventory.Managers;
using KeepInventory.Menu;
using KeepInventory.Patches;
using KeepInventory.Saves.V0;
using KeepInventory.Saves.V1;
using KeepInventory.Saves.V2;
using KeepInventory.Utilities;
using LabFusion.Entities;
using LabFusion.Extensions;
using LabFusion.Marrow.Extenders;
using LabFusion.Network;
using LabFusion.Player;
using LabFusion.RPC;
using LabFusion.SDK.Gamemodes;
using LabFusion.UI.Popups;
using LabFusion.Utilities;
using MelonLoader;
using MelonLoader.Pastel;
using MelonLoader.Preferences;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using Semver;
using Tomlet;
using Tomlet.Attributes;
using Tomlet.Models;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Core), "KeepInventory", "1.3.0", "HAHOOS", "https://thunderstore.io/c/bonelab/p/HAHOOS/KeepInventory/")]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: MelonAuthorColor(0, 255, 165, 0)]
[assembly: MelonColor(0, 255, 255, 0)]
[assembly: MelonOptionalDependencies(new string[] { "LabFusion", "KeepInventory.Fusion" })]
[assembly: AssemblyTitle("Keep your inventory when switching between mod levels, as well as when quitting the game!")]
[assembly: AssemblyDescription("Keep your inventory when switching between mod levels, as well as when quitting the game!")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("HAHOOS")]
[assembly: AssemblyProduct("KeepInventory")]
[assembly: AssemblyFileVersion("1.3.0")]
[assembly: AssemblyInformationalVersion("1.3.0")]
[assembly: ComVisible(false)]
[assembly: Guid("b45d7a48-e5c2-49b2-a7a2-331de9c55d26")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyVersion("1.3.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class ParamCollectionAttribute : Attribute
	{
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace KeepInventory
{
	public class Core : MelonMod
	{
		public const string Version = "1.3.0";

		internal static FunctionElement statusElement;

		internal static LevelInfo levelInfo;

		private bool InitialLoad = true;

		public static KeepInventory.Saves.V2.Save CurrentSave
		{
			get
			{
				return SaveManager.Saves.FirstOrDefault((KeepInventory.Saves.V2.Save x) => x.ID == PreferencesManager.DefaultSave.Value);
			}
			set
			{
				if (value == null)
				{
					PreferencesManager.DefaultSave.Value = string.Empty;
				}
				PreferencesManager.DefaultSave.Value = value.ID;
				PreferencesManager.Save();
				Core.DefaultSaveChanged?.Invoke();
			}
		}

		public static Core Instance { get; internal set; }

		internal static Instance Logger { get; private set; }

		public static bool HasFusion => MelonBase.FindMelon("LabFusion", "Lakatrazz") != null;

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


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


		internal static Thunderstore ThunderstoreInstance { get; private set; }

		internal static bool IsLatestVersion { get; private set; } = true;


		internal static Package ThunderstorePackage { get; private set; }

		internal static bool Deinit { get; private set; } = false;


		public static event Action DefaultSaveChanged;

		public override void OnInitializeMelon()
		{
			Deinit = false;
			Logger = ((MelonBase)this).LoggerInstance;
			Instance = this;
			((MelonBase)this).LoggerInstance.Msg("Setting up KeepInventory");
			CheckVersion();
			if (!HasFusion)
			{
				((MelonBase)this).LoggerInstance.Warning("Could not find LabFusion, the mod will not use any of Fusion's functionality");
			}
			if (HasFusion)
			{
				((MelonBase)this).LoggerInstance.Msg("Attempting to load the Fusion Support Library");
				if (DependencyManager.TryLoadDependency("KeepInventory.Fusion"))
				{
					IsFusionLibraryInitialized = true;
				}
				else
				{
					FailedFLLoad = true;
				}
			}
			if (!HasFusion)
			{
				Hooking.OnLevelLoaded += LevelLoadedEvent;
			}
			else
			{
				Fusion.TargetLevelLoadEvent(delegate
				{
					//IL_000b: Unknown result type (might be due to invalid IL or missing references)
					LevelLoadedEvent(new LevelInfo(SceneStreamer.Session.Level));
				});
			}
			Hooking.OnLevelUnloaded += LevelUnloadedEvent;
			if (IsFusionLibraryInitialized)
			{
				Fusion.SetupFusionLibrary();
			}
			if (HasFusion)
			{
				Fusion.Setup();
			}
			BlacklistManager.Add(new Blacklist("default_labworks", "LABWORKS", enabled: true, new List<Level>(16)
			{
				new Level("volx4.LabWorksBoneworksPort.Level.BoneworksLoadingScreen"),
				new Level("volx4.LabWorksBoneworksPort.Level.BoneworksMainMenu"),
				new Level("volx4.LabWorksBoneworksPort.Level.Boneworks01Breakroom"),
				new Level("volx4.LabWorksBoneworksPort.Level.Boneworks02Museum"),
				new Level("volx4.LabWorksBoneworksPort.Level.Boneworks03Streets"),
				new Level("volx4.LabWorksBoneworksPort.Level.Boneworks04Runoff"),
				new Level("volx4.LabWorksBoneworksPort.Level.Boneworks05Sewers"),
				new Level("volx4.LabWorksBoneworksPort.Level.Boneworks06Warehouse"),
				new Level("volx4.LabWorksBoneworksPort.Level.Boneworks07CentralStation"),
				new Level("volx4.LabWorksBoneworksPort.Level.Boneworks08Tower"),
				new Level("volx4.LabWorksBoneworksPort.Level.Boneworks09TimeTower"),
				new Level("volx4.LabWorksBoneworksPort.Level.Boneworks10Dungeon"),
				new Level("volx4.LabWorksBoneworksPort.Level.Boneworks11Arena"),
				new Level("volx4.LabWorksBoneworksPort.Level.Boneworks12ThroneRoom"),
				new Level("volx4.LabWorksBoneworksPort.Level.BoneworksCutscene01"),
				new Level("volx4.LabWorksBoneworksPort.Level.sceneTheatrigonMovie02")
			}));
			BlacklistManager.Add(new Blacklist("default_bonelab", "BONELAB", enabled: true, new List<Level>(19)
			{
				new Level("SLZ.BONELAB.Content.Level.LevelOutro"),
				new Level("c2534c5a-db71-49cf-b694-24584c657665"),
				new Level("c2534c5a-4197-4879-8cd3-4a695363656e"),
				new Level("c2534c5a-54df-470b-baaf-741f4c657665"),
				new Level("c2534c5a-56a6-40ab-a8ce-23074c657665"),
				new Level("c2534c5a-7601-4443-bdfe-7f235363656e"),
				new Level("SLZ.BONELAB.Content.Level.LevelBigAnomalyB"),
				new Level("SLZ.BONELAB.Content.Level.LevelStreetPunch"),
				new Level("SLZ.BONELAB.Content.Level.SprintBridge04"),
				new Level("SLZ.BONELAB.Content.Level.SceneMagmaGate"),
				new Level("SLZ.BONELAB.Content.Level.MoonBase"),
				new Level("SLZ.BONELAB.Content.Level.LevelKartRace"),
				new Level("c2534c5a-c056-4883-ac79-e051426f6964"),
				new Level("c2534c5a-162f-4661-a04d-975d5363656e"),
				new Level("fa534c5a868247138f50c62e424c4144.Level.LevelArenaMin"),
				new Level("c2534c5a-c180-40e0-b2b7-325c5363656e"),
				new Level("c2534c5a-de61-4df9-8f6c-416954726547"),
				new Level("c2534c5a-4f3b-480e-ad2f-69175363656e"),
				new Level("c2534c5a-80e1-4a29-93ca-f3254d656e75")
			}));
			PreferencesManager.Setup();
			SaveManager.Setup();
			BoneMenu.Setup();
			AmmoManager.Track("light");
			AmmoManager.Track("medium");
			AmmoManager.Track("heavy");
			AmmoManager.Init();
			((MelonBase)this).LoggerInstance.Msg("Initialized.");
		}

		public override void OnDeinitializeMelon()
		{
			Deinit = true;
			((MelonBase)this).LoggerInstance.Msg("Deinitialize requested, cleaning up.");
			AmmoManager.Destroy();
			PreferencesManager.Save();
			SaveManager.Saves.ForEach(delegate(KeepInventory.Saves.V2.Save x)
			{
				x.IsFileWatcherEnabled = false;
				x.TrySaveToFile();
			});
		}

		private void CheckVersion()
		{
			ThunderstoreInstance = new Thunderstore("KeepInventory / 1.3.0 A BONELAB MelonLoader Mod");
			try
			{
				ThunderstorePackage = ThunderstoreInstance.GetPackage("HAHOOS", "KeepInventory");
				if (ThunderstorePackage != null)
				{
					if (ThunderstorePackage.Latest != null && !string.IsNullOrWhiteSpace(ThunderstorePackage.Latest.Version))
					{
						IsLatestVersion = ThunderstorePackage.IsLatestVersion("1.3.0");
						if (!IsLatestVersion)
						{
							((MelonBase)this).LoggerInstance.Warning($"A new version of KeepInventory is available: v{ThunderstorePackage.Latest.Version} while the current is v{"1.3.0"}. It is recommended that you update");
						}
						else if (SemVersion.Parse("1.3.0", false) == ThunderstorePackage.Latest.SemanticVersion)
						{
							((MelonBase)this).LoggerInstance.Msg("Latest version of KeepInventory is installed! --> v1.3.0");
						}
						else
						{
							((MelonBase)this).LoggerInstance.Msg($"Beta release of KeepInventory is installed (v{ThunderstorePackage.Latest.Version} is newest, v{"1.3.0"} is installed)");
						}
					}
					else
					{
						((MelonBase)this).LoggerInstance.Warning("Latest version could not be found or the version is empty");
					}
				}
				else
				{
					((MelonBase)this).LoggerInstance.Warning("Could not find thunderstore package for KeepInventory");
				}
			}
			catch (Exception ex)
			{
				((MelonBase)this).LoggerInstance.Error("An unexpected error has occurred while trying to check if KeepInventory is the latest version", ex);
			}
		}

		private void LevelUnloadedEvent()
		{
			if (!PreferencesManager.SaveOnLevelUnload.Value)
			{
				return;
			}
			if (!IsBlacklisted(((ScannableReference)levelInfo.levelReference).Barcode))
			{
				if (CurrentSave != null)
				{
					InventoryManager.SaveInventory(CurrentSave);
				}
				else
				{
					((MelonBase)this).LoggerInstance.Warning("No default save is set, cannot save");
				}
			}
			else
			{
				((MelonBase)this).LoggerInstance.Warning("Not saving due to the level being blacklisted");
			}
		}

		private void LevelLoadedEvent(LevelInfo obj)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			BoneMenu.SetupPredefinedBlacklists();
			levelInfo = obj;
			if (InitialLoad)
			{
				if (FailedFLLoad)
				{
					BLHelper.SendNotification("Failure", "The Fusion Library has failed to load, which will cause the Sharing feature to not work. If this occurs again, create an issue on Github or DM the developer (@hahoos)", showTitleOnPopup: true, 10f, (NotificationType)2);
					IsFusionLibraryInitialized = false;
				}
				if (!IsLatestVersion && ThunderstorePackage != null)
				{
					BLHelper.SendNotification(NotificationText.op_Implicit("Update!"), new NotificationText("There is a new version of KeepInventory. Go to Thunderstore and download the latest version which is <color=#00FF00>v" + ThunderstorePackage.Latest.Version + "</color>", Color.white, true), showTitleOnPopup: true, 5f, (NotificationType)1);
				}
				InitialLoad = false;
			}
			if (CurrentSave == null)
			{
				return;
			}
			if (!IsBlacklisted(((ScannableReference)obj.levelReference).Barcode))
			{
				if (PreferencesManager.LoadOnLevelLoad.Value)
				{
					try
					{
						((Element)statusElement).ElementName = "Current level is not blacklisted";
						((Element)statusElement).ElementColor = Color.green;
						InventoryManager.LoadSavedInventory(CurrentSave);
					}
					catch (Exception ex)
					{
						((MelonBase)this).LoggerInstance.Error("An error occurred while loading the inventory", ex);
						BLHelper.SendNotification("Failure", "Failed to load the inventory, check the logs or console for more details", showTitleOnPopup: true, 5f, (NotificationType)2);
					}
				}
			}
			else
			{
				((MelonBase)this).LoggerInstance.Warning("Not loading inventory because level is blacklisted");
				BLHelper.SendNotification("This level is blacklisted from loading/saving inventory", "Blacklisted", showTitleOnPopup: true, 5f, (NotificationType)1);
				((Element)statusElement).ElementName = "Current level is blacklisted";
				((Element)statusElement).ElementColor = Color.red;
			}
		}

		private static bool IsBlacklisted(Barcode barcode)
		{
			if (!BlacklistManager.IsLevelBlacklisted(barcode))
			{
				return PreferencesManager.BlacklistedLevels.Value.Contains(barcode.ID);
			}
			return true;
		}
	}
}
namespace KeepInventory.Utilities
{
	public static class Fusion
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static ServerEvent <0>__OnJoinLeave;
		}

		[CompilerGenerated]
		private sealed class <Internal_GetPlayers>d__13 : IEnumerable<FusionPlayer>, IEnumerable, IEnumerator<FusionPlayer>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private FusionPlayer <>2__current;

			private int <>l__initialThreadId;

			private HashSet<NetworkPlayer>.Enumerator <>7__wrap1;

			FusionPlayer IEnumerator<FusionPlayer>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <Internal_GetPlayers>d__13(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<>7__wrap1 = default(HashSet<NetworkPlayer>.Enumerator);
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<>7__wrap1 = NetworkPlayer.Players.GetEnumerator();
						<>1__state = -3;
						break;
					case 1:
						<>1__state = -3;
						break;
					}
					if (<>7__wrap1.MoveNext())
					{
						NetworkPlayer current = <>7__wrap1.Current;
						<>2__current = new FusionPlayer(current.PlayerID.SmallID, current.PlayerID.PlatformID, current.Username);
						<>1__state = 1;
						return true;
					}
					<>m__Finally1();
					<>7__wrap1 = default(HashSet<NetworkPlayer>.Enumerator);
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				((IDisposable)<>7__wrap1).Dispose();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<FusionPlayer> IEnumerable<FusionPlayer>.GetEnumerator()
			{
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					return this;
				}
				return new <Internal_GetPlayers>d__13(0);
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<FusionPlayer>)this).GetEnumerator();
			}
		}

		public static bool IsConnected
		{
			get
			{
				if (Core.HasFusion)
				{
					return Internal_IsConnected();
				}
				return false;
			}
		}

		public static bool SharingEnabled
		{
			get
			{
				if (Core.IsFusionLibraryInitialized && Core.HasFusion)
				{
					return Internal_SharingEnabled();
				}
				return false;
			}
		}

		public static bool IsGamemodeStarted
		{
			get
			{
				if (!IsConnected)
				{
					return false;
				}
				return Internal_IsGamemodeStarted();
			}
		}

		internal static void SetupFusionLibrary()
		{
			Core.Logger.Msg("Setting up the library");
			try
			{
				FusionModule.Setup(Core.Logger);
				FusionModule.LoadModule();
				ShareManager.Setup();
			}
			catch (Exception ex)
			{
				Core.FailedFLLoad = true;
				Core.Logger.Error("An unexpected error has occurred while setting up and/or loading the fusion module", ex);
			}
		}

		internal static void Setup()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			ShareManager.OnShared += delegate(KeepInventory.Saves.V2.Save save, byte sender)
			{
				//IL_0047: 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_0052: Unknown result type (might be due to invalid IL or missing references)
				//IL_005c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0063: Unknown result type (might be due to invalid IL or missing references)
				//IL_006a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0094: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00de: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
				//IL_0102: Unknown result type (might be due to invalid IL or missing references)
				//IL_012c: Expected O, but got Unknown
				NetworkPlayer val4 = default(NetworkPlayer);
				string value = default(string);
				if (NetworkPlayerManager.TryGetPlayer(sender, ref val4) && !SaveManager.Saves.Any((KeepInventory.Saves.V2.Save x) => x.ID == save.ID) && MetadataHelper.TryGetDisplayName(val4.PlayerID, ref value))
				{
					Notifier.Send(new Notification
					{
						Title = NotificationText.op_Implicit("KeepInventory | Save shared!"),
						SaveToMenu = true,
						ShowPopup = true,
						Message = NotificationText.op_Implicit($"{value} has shared a save with you called '<color=#{save.DrawingColor.ToHEX()}>{save.Name}</color>'. Go to the LabFusion notifications menu, press accept to add save, decline will disregard this"),
						PopupLength = 15f,
						Type = (NotificationType)0,
						OnAccepted = delegate
						{
							SaveManager.RegisterSave(save);
						},
						OnDeclined = delegate
						{
							Core.Logger.Msg("Save share ignored");
						}
					});
				}
			};
			object obj = <>O.<0>__OnJoinLeave;
			if (obj == null)
			{
				ServerEvent val = OnJoinLeave;
				<>O.<0>__OnJoinLeave = val;
				obj = (object)val;
			}
			MultiplayerHooking.OnStartedServer += (ServerEvent)obj;
			object obj2 = <>O.<0>__OnJoinLeave;
			if (obj2 == null)
			{
				ServerEvent val2 = OnJoinLeave;
				<>O.<0>__OnJoinLeave = val2;
				obj2 = (object)val2;
			}
			MultiplayerHooking.OnJoinedServer += (ServerEvent)obj2;
			object obj3 = <>O.<0>__OnJoinLeave;
			if (obj3 == null)
			{
				ServerEvent val3 = OnJoinLeave;
				<>O.<0>__OnJoinLeave = val3;
				obj3 = (object)val3;
			}
			MultiplayerHooking.OnDisconnected += (ServerEvent)obj3;
		}

		private static bool Internal_SharingEnabled()
		{
			return ShareManager.Entry_SharingEnabled?.Value ?? false;
		}

		private static void OnJoinLeave()
		{
			BoneMenu.SetupSaves();
		}

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

		internal static void Internal_ShareSave(byte SmallID, KeepInventory.Saves.V2.Save save)
		{
			NetworkPlayer val = default(NetworkPlayer);
			if (NetworkPlayerManager.TryGetPlayer(SmallID, ref val))
			{
				ShareManager.Share(save, PlayerID.op_Implicit(val.PlayerID));
				return;
			}
			throw new Exception($"Player with small ID {SmallID} could not be found");
		}

		public static void ShareSave(byte SmallID, KeepInventory.Saves.V2.Save save)
		{
			if (Core.HasFusion && Core.IsFusionLibraryInitialized && IsConnected)
			{
				Internal_ShareSave(SmallID, save);
			}
		}

		internal static List<FusionPlayer> Internal_GetShareablePlayers()
		{
			List<byte> allShareablePlayers = ShareManager.GetAllShareablePlayers();
			List<FusionPlayer> list = new List<FusionPlayer>();
			string displayName = default(string);
			foreach (byte item in allShareablePlayers)
			{
				PlayerID playerID = PlayerIDManager.GetPlayerID(item);
				if (playerID != null && MetadataHelper.TryGetDisplayName(playerID, ref displayName))
				{
					list.Add(new FusionPlayer(item, playerID.PlatformID, displayName));
				}
			}
			return list;
		}

		public static List<FusionPlayer> GetShareablePlayers()
		{
			if (Core.HasFusion && Core.IsFusionLibraryInitialized && IsConnected)
			{
				return Internal_GetShareablePlayers();
			}
			return new List<FusionPlayer>();
		}

		[IteratorStateMachine(typeof(<Internal_GetPlayers>d__13))]
		internal static IEnumerable<FusionPlayer> Internal_GetPlayers()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <Internal_GetPlayers>d__13(-2);
		}

		public static List<FusionPlayer> GetPlayers()
		{
			if (Core.HasFusion && IsConnected)
			{
				return Internal_GetPlayers().ToList();
			}
			return new List<FusionPlayer>();
		}

		internal static byte Internal_GetLocalPlayerSmallID()
		{
			return PlayerIDManager.LocalSmallID;
		}

		public static byte GetLocalPlayerSmallID()
		{
			if (Core.HasFusion && IsConnected)
			{
				return Internal_GetLocalPlayerSmallID();
			}
			return 0;
		}

		public static bool IsLocalPlayer(this RigManager rigManager)
		{
			if (!IsConnected)
			{
				return true;
			}
			return rigManager.Internal_IsLocalPlayer();
		}

		private static bool Internal_IsLocalPlayer(this RigManager rigManager)
		{
			return FusionPlayer.IsLocalPlayer(rigManager);
		}

		internal static bool GamemodeCheck()
		{
			if (!IsConnected)
			{
				return false;
			}
			return Internal_GamemodeCheck();
		}

		internal static bool Internal_GamemodeCheck()
		{
			if (!GamemodeManager.IsGamemodeStarted && !GamemodeManager.StartTimerActive)
			{
				return GamemodeManager.IsGamemodeReady;
			}
			return true;
		}

		internal static void TargetLevelLoadEvent(Action action)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			MultiplayerHooking.OnTargetLevelLoaded += (UpdateEvent)delegate
			{
				action();
			};
		}

		internal static bool Internal_IsGamemodeStarted()
		{
			return GamemodeManager.IsGamemodeStarted;
		}

		internal static bool DoesGamemodeAllow()
		{
			if (!IsConnected)
			{
				return false;
			}
			Gamemode activeGamemode = GamemodeManager.ActiveGamemode;
			if (activeGamemode == null)
			{
				return true;
			}
			if (!GamemodeCheck())
			{
				return true;
			}
			string text = default(string);
			bool result = default(bool);
			return activeGamemode.Metadata != null && activeGamemode.Metadata.TryGetMetadata("AllowKeepInventory", ref text) && text != null && bool.TryParse(text, out result) && result;
		}

		internal static void Fusion_LoadMagazine(this Gun gun, int rounds = -1, Action callback = null)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			SpawnRequestInfo val = default(SpawnRequestInfo);
			val.Position = Player.Head.position;
			val.Rotation = Player.Head.rotation;
			val.Spawnable = gun.defaultMagazine.spawnable;
			val.SpawnEffect = false;
			val.SpawnCallback = delegate(SpawnCallbackInfo spawn)
			{
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				NetworkEntity val2 = GunExtender.Cache.Get(gun);
				if (val2 != null)
				{
					AmmoSocketExtender extender = val2.GetExtender<AmmoSocketExtender>();
					Magazine component = spawn.Spawned.GetComponent<Magazine>();
					if (extender != null && !((Object)(object)component == (Object)null))
					{
						object obj;
						if (extender == null)
						{
							obj = null;
						}
						else
						{
							AmmoSocket component2 = ((EntityComponentExtender<AmmoSocket>)(object)extender).Component;
							obj = ((component2 != null) ? component2._magazinePlug : null);
						}
						AmmoPlug val3 = (AmmoPlug)obj;
						if ((Object)(object)val3 != (Object)null && (Object)(object)val3 != (Object)(object)component.magazinePlug)
						{
							AlignPlugExtensions.ForceEject((AlignPlug)(object)val3);
						}
						InteractableHostExtensions.TryDetach(((Plug)component.magazinePlug).host);
						((AlignPlug)component.magazinePlug).InsertPlug((Socket)(object)((EntityComponentExtender<AmmoSocket>)(object)extender).Component);
						gun.MagazineState.SetCartridge(rounds);
						callback?.Invoke();
					}
				}
			};
			NetworkAssetSpawner.Spawn(val);
		}

		public static void LoadMagazine(this Gun gun, int rounds = -1, Action callback = null)
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: 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_00a6: Expected O, but got Unknown
			if (rounds == -1)
			{
				rounds = gun.defaultMagazine.rounds;
			}
			if (IsConnected)
			{
				gun.Fusion_LoadMagazine(rounds, callback);
				return;
			}
			gun.ammoSocket.ForceLoadAsync(new MagazineData
			{
				spawnable = gun.defaultMagazine.spawnable,
				rounds = rounds,
				platform = gun.defaultMagazine.platform
			}).GetAwaiter().OnCompleted((Action)something);
			void something()
			{
				gun.MagazineState.SetCartridge(rounds);
				callback?.Invoke();
			}
		}

		internal static void MsgFusionPrefix(string message)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			MsgPrefix("Fusion", message, Color.cyan);
		}

		internal static void Warn(string message)
		{
			Core.Logger.Warning("[Fusion] " + message);
		}

		internal static void Error(string message)
		{
			Core.Logger.Warning("[Fusion] " + message);
		}

		internal static void MsgPrefix(string prefix, string message, Color color)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			Core.Logger.Msg("[" + ConsoleExtensions.Pastel(prefix, color.ToHEX()) + "] " + message);
		}
	}
	public class FusionPlayer
	{
		public string DisplayName { get; }

		public byte SmallID { get; }

		public ulong PlatformID { get; }

		public FusionPlayer(byte SmallID, ulong PlatformID, string displayName)
		{
			DisplayName = displayName;
			this.SmallID = SmallID;
			this.PlatformID = PlatformID;
			base..ctor();
		}
	}
	public class SynchronousFileSystemWatcher : IDisposable
	{
		private readonly FileSystemWatcher _watcher = new FileSystemWatcher();

		private readonly List<EventArgs> _Queue = new List<EventArgs>();

		public bool EnableRaisingEvents
		{
			get
			{
				return _watcher.EnableRaisingEvents;
			}
			set
			{
				_watcher.EnableRaisingEvents = value;
			}
		}

		public NotifyFilters NotifyFilter
		{
			get
			{
				return _watcher.NotifyFilter;
			}
			set
			{
				_watcher.NotifyFilter = value;
			}
		}

		public string Filter
		{
			get
			{
				return _watcher.Filter;
			}
			set
			{
				_watcher.Filter = value;
			}
		}

		public Collection<string> Filters => _watcher.Filters;

		public string Path
		{
			get
			{
				return _watcher.Path;
			}
			set
			{
				_watcher.Path = value;
			}
		}

		public IReadOnlyList<EventArgs> Queue => _Queue.AsReadOnly();

		public event EventHandler<RenamedEventArgs> Renamed;

		public event EventHandler<FileSystemEventArgs> Created;

		public event EventHandler<FileSystemEventArgs> Deleted;

		public event EventHandler<FileSystemEventArgs> Changed;

		public event EventHandler Disposed;

		public event EventHandler<ErrorEventArgs> Error;

		public SynchronousFileSystemWatcher()
		{
			Init();
		}

		public SynchronousFileSystemWatcher(string path)
		{
			_watcher.Path = path;
			Init();
		}

		public SynchronousFileSystemWatcher(string path, string filter)
		{
			_watcher.Path = path;
			_watcher.Filter = filter;
			Init();
		}

		private void Init()
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Expected O, but got Unknown
			_watcher.Renamed += delegate(object sender, RenamedEventArgs e)
			{
				_Queue.Add(e);
			};
			_watcher.Created += delegate(object sender, FileSystemEventArgs e)
			{
				_Queue.Add(e);
			};
			_watcher.Deleted += delegate(object sender, FileSystemEventArgs e)
			{
				_Queue.Add(e);
			};
			_watcher.Changed += delegate(object sender, FileSystemEventArgs e)
			{
				_Queue.Add(e);
			};
			_watcher.Disposed += delegate(object? sender, EventArgs e)
			{
				_Queue.Add(e);
			};
			_watcher.Error += delegate(object sender, ErrorEventArgs e)
			{
				_Queue.Add(e);
			};
			((MelonEventBase<LemonAction>)(object)MelonEvents.OnUpdate).Subscribe(new LemonAction(Update), 0, false);
		}

		private void Update()
		{
			if (Queue.Count <= 0)
			{
				return;
			}
			for (int num = Queue.Count - 1; num >= 0; num--)
			{
				EventArgs eventArgs = _Queue[num];
				try
				{
					if (eventArgs is RenamedEventArgs e)
					{
						this.Renamed?.Invoke(this, e);
					}
					else if (eventArgs is FileSystemEventArgs fileSystemEventArgs)
					{
						if (fileSystemEventArgs.ChangeType == WatcherChangeTypes.Created)
						{
							this.Created?.Invoke(this, fileSystemEventArgs);
						}
						else if (fileSystemEventArgs.ChangeType == WatcherChangeTypes.Deleted)
						{
							this.Deleted?.Invoke(this, fileSystemEventArgs);
						}
						else if (fileSystemEventArgs.ChangeType == WatcherChangeTypes.Changed)
						{
							this.Changed?.Invoke(this, fileSystemEventArgs);
						}
					}
					else if (eventArgs is ErrorEventArgs e2)
					{
						this.Error?.Invoke(this, e2);
					}
					else if (eventArgs != null)
					{
						EventArgs e3 = eventArgs;
						try
						{
							this.Disposed?.Invoke(this, e3);
						}
						catch (Exception ex)
						{
							MelonLogger.Error("SynchronousFileSystemWatcher | An unexpected error has occurred while running Disposed event", ex);
						}
						finally
						{
							Dispose();
						}
					}
				}
				catch (Exception ex2)
				{
					MelonLogger.Error("SynchronousFileSystemWatcher | An unexpected error has occurred while triggering file system watcher events", ex2);
				}
				finally
				{
					_Queue.RemoveAt(num);
				}
			}
		}

		public void Dispose()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			try
			{
				_watcher.Dispose();
			}
			catch (Exception ex)
			{
				MelonLogger.Error("SynchronousFileSystemWatcher | An exception occurred while disposing of FileSystemWatcher", ex);
			}
			((MelonEventBase<LemonAction>)(object)MelonEvents.OnUpdate).Unsubscribe(new LemonAction(Update));
			GC.SuppressFinalize(this);
		}
	}
	public class Thunderstore
	{
		public readonly string UserAgent;

		public bool IsV1Deprecated;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		public HttpStatusCode HttpStatusCode { get; }

		public ThunderstoreErrorException()
		{
		}

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

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

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

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

		public string Name { get; }

		public string Version { get; }

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

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

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

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

		public ThunderstorePackageNotFoundException()
		{
		}

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

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

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

		public ThunderstorePackageNotFoundException(string message, HttpResponseMessage response)
			: base(message, response)
		{
		}
	}
}
namespace KeepInventory.Saves.V2
{
	[JsonSourceGenerationOptions(WriteIndented = false)]
	public class GunInfo
	{
		[JsonPropertyName("IsMag")]
		public bool IsMag { get; set; }

		[JsonPropertyName("IsBulletInChamber")]
		public bool IsBulletInChamber { get; set; }

		[JsonPropertyName("FireMode")]
		public FireMode FireMode { get; set; }

		[JsonPropertyName("RoundsLeft")]
		public int RoundsLeft { get; set; }

		[JsonPropertyName("HammerState")]
		public HammerStates HammerState { get; set; }

		[JsonPropertyName("SlideState")]
		public SlideStates SlideState { get; set; }

		[JsonPropertyName("CartridgeState")]
		public CartridgeStates CartridgeState { get; set; }

		[JsonPropertyName("HasFiredOnce")]
		public bool HasFiredOnce { get; set; }

		[JsonConstructor]
		public GunInfo()
		{
		}

		public static GunInfo Parse(Gun gun)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			GunInfo gunInfo = new GunInfo
			{
				IsMag = gun.HasMagazine(),
				IsBulletInChamber = ((Object)(object)gun.chamberedCartridge != (Object)null),
				FireMode = gun.fireMode,
				HammerState = gun.hammerState,
				SlideState = gun.slideState,
				HasFiredOnce = gun.hasFiredOnce,
				CartridgeState = gun.cartridgeState
			};
			if (gun.MagazineState != null)
			{
				gunInfo.RoundsLeft = gun.MagazineState.AmmoCount;
			}
			return gunInfo;
		}

		public static GunInfo Parse(KeepInventory.Saves.V1.GunInfo gunInfoV1)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			if (gunInfoV1 == null)
			{
				return null;
			}
			return new GunInfo
			{
				IsMag = gunInfoV1.IsMag,
				IsBulletInChamber = gunInfoV1.IsBulletInChamber,
				FireMode = gunInfoV1.FireMode,
				HammerState = gunInfoV1.HammerState,
				SlideState = gunInfoV1.SlideState,
				HasFiredOnce = gunInfoV1.HasFiredOnce,
				CartridgeState = gunInfoV1.CartridgeState,
				RoundsLeft = gunInfoV1.RoundsLeft
			};
		}

		public MagazineData GetMagazineData(Gun gun)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_0034: Expected O, but got Unknown
			return new MagazineData
			{
				spawnable = gun.defaultMagazine.spawnable,
				rounds = RoundsLeft,
				platform = gun.defaultMagazine.platform
			};
		}

		public string Serialize()
		{
			return JsonSerializer.Serialize(this, new JsonSerializerOptions
			{
				WriteIndented = false
			});
		}

		public static string Serialize(GunInfo gunInfo)
		{
			return JsonSerializer.Serialize(gunInfo, new JsonSerializerOptions
			{
				WriteIndented = false
			});
		}

		public static GunInfo Deserialize(string json)
		{
			return JsonSerializer.Deserialize<GunInfo>(json);
		}
	}
	[JsonSourceGenerationOptions(WriteIndented = true, IncludeFields = true, IgnoreReadOnlyFields = false, IgnoreReadOnlyProperties = false)]
	public class Save
	{
		[JsonPropertyName("Version")]
		public readonly int Version = 2;

		[JsonIgnore]
		private string _name;

		[JsonIgnore]
		private string _id;

		[JsonIgnore]
		public Color DrawingColor = Color.white;

		[JsonIgnore]
		private string _filePath;

		[JsonIgnore]
		private int _lightAmmo = -1;

		[JsonIgnore]
		private int _mediumAmmo = -1;

		[JsonIgnore]
		private int _heavyAmmo = -1;

		private List<SaveSlot> _inventorySlots;

		internal bool Saving;

		[JsonPropertyName("Name")]
		public string Name
		{
			get
			{
				return _name;
			}
			set
			{
				string name = _name;
				_name = value;
				this.OnPropertyChanged?.Invoke("Name", name, value);
			}
		}

		[JsonPropertyName("ID")]
		public string ID
		{
			get
			{
				return _id;
			}
			set
			{
				string id = _id;
				_id = value;
				this.OnPropertyChanged?.Invoke("ID", id, value);
			}
		}

		[JsonPropertyName("Color")]
		public float[] Color
		{
			get
			{
				return new float[3]
				{
					DrawingColor.r * 255f,
					DrawingColor.g * 255f,
					DrawingColor.b * 255f
				};
			}
			set
			{
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				//IL_003d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0052: Unknown result type (might be due to invalid IL or missing references)
				//IL_0059: Unknown result type (might be due to invalid IL or missing references)
				if (value == null || value.Length != 3)
				{
					DrawingColor = Color.white;
					return;
				}
				Color drawingColor = DrawingColor;
				DrawingColor = new Color(value[0] / 255f, value[1] / 255f, value[2] / 255f);
				this.OnPropertyChanged?.Invoke("Color", drawingColor, DrawingColor);
			}
		}

		[JsonIgnore]
		public bool IsFileWatcherEnabled { get; set; } = true;


		[JsonIgnore]
		public string FilePath
		{
			get
			{
				return _filePath;
			}
			internal set
			{
				string filePath = _filePath;
				_filePath = value;
				this.OnPropertyChanged?.Invoke("FilePath", filePath, value);
			}
		}

		[JsonPropertyName("LightAmmo")]
		public int LightAmmo
		{
			get
			{
				return _lightAmmo;
			}
			set
			{
				int lightAmmo = _lightAmmo;
				_lightAmmo = value;
				this.OnPropertyChanged?.Invoke("LightAmmo", lightAmmo, value);
			}
		}

		[JsonPropertyName("MediumAmmo")]
		public int MediumAmmo
		{
			get
			{
				return _mediumAmmo;
			}
			set
			{
				int mediumAmmo = _mediumAmmo;
				_mediumAmmo = value;
				this.OnPropertyChanged?.Invoke("MediumAmmo", mediumAmmo, value);
			}
		}

		[JsonPropertyName("HeavyAmmo")]
		public int HeavyAmmo
		{
			get
			{
				return _heavyAmmo;
			}
			set
			{
				int heavyAmmo = _heavyAmmo;
				_heavyAmmo = value;
				this.OnPropertyChanged?.Invoke("HeavyAmmo", heavyAmmo, value);
			}
		}

		[JsonPropertyName("InventorySlots")]
		public List<SaveSlot> InventorySlots
		{
			get
			{
				return _inventorySlots;
			}
			set
			{
				List<SaveSlot> inventorySlots = _inventorySlots;
				_inventorySlots = value;
				this.OnPropertyChanged?.Invoke("InventorySlots", inventorySlots, value);
			}
		}

		public event Action<string, object, object> OnPropertyChanged;

		[JsonConstructor]
		public Save()
		{
		}//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)


		public Save(Save old)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			_name = old.Name;
			_id = old.ID;
			Color = old.Color;
			_lightAmmo = old.LightAmmo;
			_mediumAmmo = old.MediumAmmo;
			_heavyAmmo = old.HeavyAmmo;
			_inventorySlots = old.InventorySlots.ToList();
		}

		public Save(int Version, string Name, string ID, float[] Color, int LightAmmo, int MediumAmmo, int HeavyAmmo, List<SaveSlot> InventorySlots)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			if (Version != 2)
			{
				throw new ArgumentException($"The V2 save object is not made for saves with version '{Version}'");
			}
			this.Version = Version;
			_name = Name;
			_id = ID;
			this.Color = Color;
			_lightAmmo = LightAmmo;
			_mediumAmmo = MediumAmmo;
			_heavyAmmo = HeavyAmmo;
			_inventorySlots = InventorySlots;
			if (string.IsNullOrWhiteSpace(_id))
			{
				throw new Exception("ID cannot be null or empty");
			}
		}

		public Save(string id, string name, Color color, KeepInventory.Saves.V1.Save v1save)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			_id = id;
			_name = name;
			DrawingColor = color;
			_lightAmmo = v1save.LightAmmo;
			_mediumAmmo = v1save.MediumAmmo;
			_heavyAmmo = v1save.HeavyAmmo;
			List<SaveSlot> _new = new List<SaveSlot>();
			v1save.InventorySlots?.ForEach(delegate(KeepInventory.Saves.V1.SaveSlot x)
			{
				_new.Add(new SaveSlot(x));
			});
			_inventorySlots = _new;
		}

		public Save(string id, string name, Color color, KeepInventory.Saves.V0.Save v0save)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			_id = id;
			_name = name;
			DrawingColor = color;
			_lightAmmo = v0save.AmmoLight;
			_mediumAmmo = v0save.AmmoMedium;
			_heavyAmmo = v0save.AmmoHeavy;
			List<SaveSlot> _new = new List<SaveSlot>();
			v0save.ItemSlots?.ForEach(delegate(KeyValuePair<string, string> x)
			{
				_new.Add(new SaveSlot
				{
					Barcode = x.Value,
					SlotName = x.Key,
					Type = SaveSlot.SpawnableType.Other,
					GunInfo = null
				});
			});
			_inventorySlots = _new;
		}

		internal void Update(Save save)
		{
			ArgumentNullException.ThrowIfNull(save, "save");
			if (!string.IsNullOrWhiteSpace(save.ID))
			{
				if (SaveManager.Saves.Any((Save x) => x.ID == save.ID && x != this))
				{
					Core.Logger.Error("The new ID is already used in another save, will not overwrite");
					throw new ArgumentException("The new ID is already used in another save, will not overwrite");
				}
				ID = save.ID;
				if (Name != save.Name)
				{
					Name = save.Name;
				}
				if (Color != save.Color)
				{
					Color = save.Color;
				}
				if (InventorySlots != save.InventorySlots)
				{
					InventorySlots = save.InventorySlots;
				}
				if (HeavyAmmo != save.HeavyAmmo)
				{
					HeavyAmmo = save.HeavyAmmo;
				}
				if (MediumAmmo != save.MediumAmmo)
				{
					MediumAmmo = save.MediumAmmo;
				}
				if (LightAmmo != save.LightAmmo)
				{
					LightAmmo = save.LightAmmo;
				}
				return;
			}
			Core.Logger.Error("The new ID is null or empty, will not overwrite");
			throw new ArgumentException("The new ID is null or empty, will not overwrite");
		}

		public void SaveToFile(bool printMessage = true)
		{
			if (!string.IsNullOrWhiteSpace(FilePath) && File.Exists(FilePath))
			{
				Saving = true;
				if (printMessage)
				{
					Core.Logger.Msg("Saving '" + ID + "' to file...");
				}
				try
				{
					string value = JsonSerializer.Serialize(this, SaveManager.SerializeOptions);
					FileStream fileStream = File.Create(FilePath);
					using StreamWriter streamWriter = new StreamWriter(fileStream)
					{
						AutoFlush = true
					};
					fileStream.Position = 0L;
					streamWriter.Write(value);
					streamWriter.DisposeAsync().AsTask().ContinueWith(delegate(Task task)
					{
						if (task.IsCompletedSuccessfully)
						{
							if (printMessage)
							{
								Core.Logger.Msg("Saved '" + ID + "' to file successfully!");
							}
						}
						else if (printMessage)
						{
							Core.Logger.Error("Failed to save '" + ID + "' to file", (Exception)task.Exception);
						}
						Saving = false;
					});
					return;
				}
				catch (Exception ex)
				{
					if (printMessage)
					{
						Core.Logger.Error("Failed to save '" + ID + "' to file", ex);
					}
					Saving = false;
					throw;
				}
			}
			if (printMessage)
			{
				Core.Logger.Error("Save '" + ID + "' does not have a file set or it doesn't exist!");
			}
			throw new FileNotFoundException("Save does not have a file!");
		}

		public bool TrySaveToFile(bool printMessage = true)
		{
			try
			{
				SaveToFile(printMessage);
				return true;
			}
			catch (Exception)
			{
				return false;
			}
		}

		internal void Update(string path)
		{
			SaveManager.IgnoredFilePaths.Add(FilePath);
			if (string.IsNullOrWhiteSpace(path))
			{
				throw new ArgumentNullException("path");
			}
			if (!File.Exists(path))
			{
				throw new FileNotFoundException("Save file at '" + path + "' could be found");
			}
			string text = SaveManager.ReadAllTextUsedFile(path);
			if (string.IsNullOrWhiteSpace(text) || !SaveManager.IsJSON(text))
			{
				Core.Logger.Error("A save file at '" + path + "' was changed and the content are no longer suitable for loading as a save. This means that the save at runtime will not be overwritten by new content");
				throw new Exception("A save file at '" + path + "' was changed and the content are no longer suitable for loading as a save. This means that the save at runtime will not be overwritten by new content");
			}
			Save save = JsonSerializer.Deserialize<Save>(text, SaveManager.SerializeOptions);
			if (save != null)
			{
				Update(save);
				return;
			}
			Core.Logger.Error("A save file at '" + path + "' was changed and the content are no longer suitable for loading as a save. This means that the save at runtime will not be overwritten by new content");
			throw new Exception("A save file at '" + path + "' was changed and the content are no longer suitable for loading as a save. This means that the save at runtime will not be overwritten by new content");
		}

		public override string ToString()
		{
			return Name;
		}
	}
	public class SaveSlot
	{
		public enum SpawnableType
		{
			Gun,
			Other
		}

		[JsonPropertyName("SlotName")]
		public string SlotName { get; set; }

		[JsonPropertyName("Barcode")]
		public string Barcode { get; set; }

		[JsonPropertyName("Type")]
		public SpawnableType Type { get; set; }

		[JsonPropertyName("GunInfo")]
		public GunInfo GunInfo { get; set; }

		[JsonConstructor]
		public SaveSlot()
		{
		}

		public SaveSlot(string slotName, Barcode barcode)
		{
			SlotName = slotName;
			Barcode = barcode.ID;
			Type = SpawnableType.Other;
			GunInfo = null;
		}

		public SaveSlot(string slotName, Barcode barcode, SpawnableType type)
		{
			SlotName = slotName;
			Barcode = barcode.ID;
			Type = type;
			GunInfo = null;
		}

		public SaveSlot(string slotName, Barcode barcode, SpawnableType type, GunInfo gunInfo)
		{
			SlotName = slotName;
			Barcode = barcode.ID;
			Type = type;
			GunInfo = gunInfo;
		}

		public SaveSlot(string slotName, Barcode barcode, GunInfo gunInfo)
		{
			SlotName = slotName;
			Barcode = barcode.ID;
			Type = SpawnableType.Gun;
			GunInfo = gunInfo;
		}

		public SaveSlot(KeepInventory.Saves.V1.SaveSlot v1)
		{
			SlotName = v1.SlotName;
			Barcode = v1.Barcode;
			Type = (SpawnableType)v1.Type;
			GunInfo = GunInfo.Parse(v1.GunInfo);
		}
	}
}
namespace KeepInventory.Saves.V1
{
	[JsonSourceGenerationOptions(WriteIndented = false)]
	public class GunInfo
	{
		[JsonPropertyName("IsMag")]
		public bool IsMag { get; set; }

		[JsonPropertyName("IsBulletInChamber")]
		public bool IsBulletInChamber { get; set; }

		[JsonPropertyName("FireMode")]
		public FireMode FireMode { get; set; }

		[JsonPropertyName("RoundsLeft")]
		public int RoundsLeft { get; set; }

		[JsonPropertyName("HammerState")]
		public HammerStates HammerState { get; set; }

		[JsonPropertyName("SlideState")]
		public SlideStates SlideState { get; set; }

		[JsonPropertyName("CartridgeState")]
		public CartridgeStates CartridgeState { get; set; }

		[JsonPropertyName("HasFiredOnce")]
		public bool HasFiredOnce { get; set; }

		[JsonConstructor]
		public GunInfo()
		{
		}

		public static GunInfo Parse(Gun gun)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			GunInfo gunInfo = new GunInfo
			{
				IsMag = gun.HasMagazine(),
				IsBulletInChamber = ((Object)(object)gun.chamberedCartridge != (Object)null),
				FireMode = gun.fireMode,
				HammerState = gun.hammerState,
				SlideState = gun.slideState,
				HasFiredOnce = gun.hasFiredOnce,
				CartridgeState = gun.cartridgeState
			};
			if (gun.MagazineState != null)
			{
				gunInfo.RoundsLeft = gun.MagazineState.AmmoCount;
			}
			return gunInfo;
		}

		public MagazineData GetMagazineData(Gun gun)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_0034: Expected O, but got Unknown
			return new MagazineData
			{
				spawnable = gun.defaultMagazine.spawnable,
				rounds = RoundsLeft,
				platform = gun.defaultMagazine.platform
			};
		}

		public string Serialize()
		{
			return JsonSerializer.Serialize(this, new JsonSerializerOptions
			{
				WriteIndented = false
			});
		}

		public static string Serialize(GunInfo gunInfo)
		{
			return JsonSerializer.Serialize(gunInfo, new JsonSerializerOptions
			{
				WriteIndented = false
			});
		}

		public static GunInfo Deserialize(string json)
		{
			return JsonSerializer.Deserialize<GunInfo>(json);
		}
	}
	public class Save
	{
		[TomlPrecedingComment("The version of the save")]
		public readonly int Version = 1;

		[TomlPrecedingComment("The amount of light ammo left")]
		public int LightAmmo;

		[TomlPrecedingComment("The amount of medium ammo left")]
		public int MediumAmmo;

		[TomlPrecedingComment("The amount of heavy ammo left")]
		public int HeavyAmmo;

		[TomlPrecedingComment("List of all slots & the spawnables stored in them")]
		public List<SaveSlot> InventorySlots = new List<SaveSlot>();

		public Save()
		{
		}

		public Save(Save old)
		{
			LightAmmo = old.LightAmmo;
			MediumAmmo = old.MediumAmmo;
			HeavyAmmo = old.HeavyAmmo;
			InventorySlots = old.InventorySlots.ToList();
		}
	}
	public class SaveSlot
	{
		public enum SpawnableType
		{
			Gun,
			Other
		}

		public string SlotName { get; set; }

		public string Barcode { get; set; }

		public SpawnableType Type { get; set; }

		[TomlNonSerialized]
		public GunInfo GunInfo { get; set; }

		[TomlProperty("GunInfo")]
		public string GunInfo_JSON
		{
			get
			{
				return JsonSerializer.Serialize(GunInfo, new JsonSerializerOptions
				{
					WriteIndented = false
				});
			}
			set
			{
				if (!string.IsNullOrWhiteSpace(value) && value != "null" && IsJSON(value))
				{
					GunInfo = JsonSerializer.Deserialize<GunInfo>(value);
				}
			}
		}

		public SaveSlot()
		{
		}

		public SaveSlot(string slotName, Barcode barcode)
		{
			SlotName = slotName;
			Barcode = barcode.ID;
			Type = SpawnableType.Other;
			GunInfo = null;
		}

		public SaveSlot(string slotName, Barcode barcode, SpawnableType type)
		{
			SlotName = slotName;
			Barcode = barcode.ID;
			Type = type;
			GunInfo = null;
		}

		public SaveSlot(string slotName, Barcode barcode, SpawnableType type, GunInfo gunInfo)
		{
			SlotName = slotName;
			Barcode = barcode.ID;
			Type = type;
			GunInfo = gunInfo;
		}

		public SaveSlot(string slotName, Barcode barcode, SpawnableType type, string gunInfoJSON)
		{
			SlotName = slotName;
			Barcode = barcode.ID;
			Type = type;
			GunInfo_JSON = gunInfoJSON;
		}

		public SaveSlot(string slotName, Barcode barcode, GunInfo gunInfo)
		{
			SlotName = slotName;
			Barcode = barcode.ID;
			Type = SpawnableType.Gun;
			GunInfo = gunInfo;
		}

		public SaveSlot(string slotName, Barcode barcode, string gunInfoJSON)
		{
			SlotName = slotName;
			Barcode = barcode.ID;
			Type = SpawnableType.Gun;
			GunInfo_JSON = gunInfoJSON;
		}

		private static bool IsJSON(string text)
		{
			try
			{
				using (JsonDocument.Parse(text))
				{
					return true;
				}
			}
			catch (JsonException)
			{
				return false;
			}
		}
	}
}
namespace KeepInventory.Saves.V0
{
	public class Save
	{
		[TomlPrecedingComment("The version of the save")]
		public readonly int Version;

		[TomlPrecedingComment("The amount of light ammo left")]
		public int AmmoLight;

		[TomlPrecedingComment("The amount of medium ammo left")]
		public int AmmoMedium;

		[TomlPrecedingComment("The amount of heavy ammo left")]
		public int AmmoHeavy;

		[TomlPrecedingComment("List of all slots & the spawnables stored in them")]
		public Dictionary<string, string> ItemSlots = new Dictionary<string, string>();
	}
}
namespace KeepInventory.Patches
{
	[HarmonyPatch(typeof(AmmoInventory), "Awake")]
	public static class AmmoInventoryPatches
	{
		public static KeepInventory.Saves.V2.Save Save { get; set; }

		public static void Postfix(AmmoInventory __instance)
		{
			if (Save == null || !PreferencesManager.AmmoSaving.Value || (Object)(object)__instance != (Object)(object)AmmoInventory.Instance)
			{
				return;
			}
			try
			{
				InventoryManager.AddSavedAmmo(Save);
			}
			catch (Exception ex)
			{
				Core.Logger.Error("An unexpected error has occurred while attempting to add saved ammo", ex);
			}
			finally
			{
				Save = null;
			}
		}
	}
	[HarmonyPatch(typeof(Player_Health), "Death")]
	public static class HealthPatches
	{
		private static void HolsterItem(Hand hand)
		{
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			GameObject currentAttachedGO = hand.m_CurrentAttachedGO;
			if ((Object)(object)currentAttachedGO == (Object)null)
			{
				return;
			}
			Grip component = currentAttachedGO.GetComponent<Grip>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			IGrippable host = ((HandReciever)component).Host;
			GameObject hostGameObject = host.GetHostGameObject();
			WeaponSlot val = ((hostGameObject != null) ? hostGameObject.GetComponentInChildren<WeaponSlot>() : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			List<InventorySlotReceiver> list = Player.RigManager?.GetAllSlots();
			if (list == null || list.Count == 0)
			{
				return;
			}
			foreach (InventorySlotReceiver item in list)
			{
				if (!((Object)(object)item._slottedWeapon != (Object)null) && item.slotType == val.slotType)
				{
					((InventoryHandReceiver)item).OnHandDrop(host);
				}
			}
		}

		public static void Prefix(Player_Health __instance)
		{
			RigManager rigManager = ((Health)__instance)._rigManager;
			if (rigManager != null && rigManager.IsLocalPlayer() && PreferencesManager.HolsterHeldWeaponsOnDeath.Value && !Fusion.IsGamemodeStarted)
			{
				HolsterItem(Player.LeftHand);
				HolsterItem(Player.RightHand);
			}
		}
	}
}
namespace KeepInventory.Menu
{
	public class BlankElement
	{
		public readonly FunctionElement Element;

		public BlankElement()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			Element = new FunctionElement(string.Empty, Color.white, (Action)null);
			((Element)Element).SetProperty((ElementProperties)1);
		}
	}
	public static class BoneMenu
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static Action <0>__UpdatePresetsPage;

			public static Action <1>__ClearInventory;

			public static Action <2>__SetupBlacklistView;

			public static ServerEvent <3>__SetupSharingBlacklist;

			public static Action <4>__SetupSharingBlacklist;
		}

		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static Action <>9__52_0;

			public static Action <>9__52_1;

			public static Action <>9__52_2;

			public static Action<bool> <>9__58_0;

			public static PlayerUpdate <>9__58_1;

			public static PlayerUpdate <>9__58_2;

			public static Predicate<FusionPlayer> <>9__59_0;

			public static Action <>9__60_3;

			public static Action <>9__62_3;

			internal void <Setup>b__52_0()
			{
				//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
				//IL_006f: Unknown result type (might be due to invalid IL or missing references)
				if (BlacklistManager.IsCurrentLevelInBlacklist())
				{
					BLHelper.SendNotification("Failure", "The current level is already in a predefined blacklist. Use the predefined blacklist to blacklist this level instead", showTitleOnPopup: true, 4f, (NotificationType)2);
					return;
				}
				List<string> value = PreferencesManager.BlacklistedLevels.Value;
				if (value.Contains(Core.levelInfo.barcode))
				{
					try
					{
						int num = value.IndexOf(Core.levelInfo.barcode);
						if (num != -1)
						{
							value.RemoveAt(num);
							((Element)Core.statusElement).ElementName = "Current Level is not blacklisted";
							((Element)Core.statusElement).ElementColor = Color.green;
							BLHelper.SendNotification("Success", "Successfully unblacklisted current level (" + Core.levelInfo.title + ") from having the inventory saved and/or loaded!", showTitleOnPopup: true, 2.5f, (NotificationType)3);
						}
						return;
					}
					catch (Exception ex)
					{
						Core.Logger.Error("An unexpected error has occurred while unblacklisting the current level", ex);
						BLHelper.SendNotification("Failure", "An unexpected error has occurred while unblacklisting the current level, check the console or logs for more details", showTitleOnPopup: true, 3f, (NotificationType)2);
						return;
					}
				}
				try
				{
					value.Add(Core.levelInfo.barcode);
					((Element)Core.statusElement).ElementName = "Current Level is blacklisted";
					((Element)Core.statusElement).ElementColor = Color.red;
					BLHelper.SendNotification("Success", "Successfully blacklisted current level (" + Core.levelInfo.title + ") from having the inventory saved and/or loaded!", showTitleOnPopup: true, 2.5f, (NotificationType)3);
				}
				catch (Exception ex2)
				{
					Core.Logger.Error("An unexpected error has occurred while removing the current level from blacklist", ex2);
					BLHelper.SendNotification("Failure", "An unexpected error has occurred while blacklisting the current level, check the console or logs for more details", showTitleOnPopup: true, 3f, (NotificationType)2);
				}
			}

			internal void <Setup>b__52_1()
			{
				if (Core.CurrentSave != null)
				{
					InventoryManager.LoadSavedInventory(Core.CurrentSave);
				}
				else
				{
					BLHelper.SendNotification("Failure", "There is no default save!", showTitleOnPopup: true, 2f, (NotificationType)2);
				}
			}

			internal void <Setup>b__52_2()
			{
				Core.Logger.Msg("The current version is v1.3.0!!!!");
			}

			internal void <SetupSharing>b__58_0(bool val)
			{
				ShareManager.Entry_SharingEnabled.Value = val;
				ShareManager.Category.SaveToFile(false);
			}

			internal void <SetupSharing>b__58_1(PlayerID _)
			{
				SetupSharingBlacklist();
			}

			internal void <SetupSharing>b__58_2(PlayerID _)
			{
				SetupSharingBlacklist();
			}

			internal bool <SetupSharingBlacklist>b__59_0(FusionPlayer x)
			{
				return x.SmallID == Fusion.GetLocalPlayerSmallID();
			}

			internal void <SetupSaves>b__60_3()
			{
				SetupSaves();
			}

			internal void <UpdatePresetsPage>b__62_3()
			{
				Core.Logger.Msg("Save removal denied");
			}
		}

		private static readonly Dictionary<string, Page> PredefinedBlacklistPages = new Dictionary<string, Page>();

		private static readonly List<Element> defaultSaveElements = new List<Element>();

		private static readonly List<SavePage> SavePages = new List<SavePage>();

		public static Page AuthorPage { get; private set; }

		public static Page ModPage { get; private set; }

		public static Page SavesPage { get; private set; }

		public static Page SavingConfigPage { get; private set; }

		public static Page EventsPage { get; private set; }

		public static Page SharingPage { get; private set; }

		public static Page SharingBlacklistPage { get; private set; }

		public static Page BlacklistPage { get; private set; }

		public static Page BlacklistViewPage { get; private set; }

		public static Page PredefinedBlacklistPage { get; private set; }

		public static Page OtherPage { get; private set; }

		public static bool IsSetup { get; private set; }

		public static bool RemoveSavesOnPress { get; private set; }

		internal static void Setup()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: 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)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: 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_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			AuthorPage = Page.Root.CreatePage("HAHOOS", Color.white, 0, true);
			ModPage = AuthorPage.CreatePage("KeepInventory", Color.yellow, 0, true);
			SetupSaves();
			Core.DefaultSaveChanged += UpdatePresetsPage;
			EventsPage = ModPage.CreatePage("Events", Color.yellow, 0, true);
			EventsPage.CreateBoolPref("Save on Level Unload", Color.red, ref PreferencesManager.SaveOnLevelUnload, null, null, null, prefDefaultValue: true);
			EventsPage.CreateBoolPref("Load on Level Load", Color.green, ref PreferencesManager.LoadOnLevelLoad, null, null, null, prefDefaultValue: true);
			if (Core.HasFusion && Core.IsFusionLibraryInitialized)
			{
				SetupSharing();
			}
			BlacklistPage = ModPage.CreatePage("Blacklist", Color.red, 0, true);
			PredefinedBlacklistPage = BlacklistPage.CreatePage("Predefined Blacklists", Color.cyan, 0, true);
			SetupPredefinedBlacklists();
			BlacklistViewPage = BlacklistPage.CreatePage("View All", Color.magenta, 0, true);
			SetupBlacklistView();
			Core.statusElement = BlacklistPage.CreateFunction("Blacklist Level from Saving/Loading", Color.red, (Action)delegate
			{
				//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
				//IL_006f: Unknown result type (might be due to invalid IL or missing references)
				if (BlacklistManager.IsCurrentLevelInBlacklist())
				{
					BLHelper.SendNotification("Failure", "The current level is already in a predefined blacklist. Use the predefined blacklist to blacklist this level instead", showTitleOnPopup: true, 4f, (NotificationType)2);
					return;
				}
				List<string> value = PreferencesManager.BlacklistedLevels.Value;
				if (value.Contains(Core.levelInfo.barcode))
				{
					try
					{
						int num = value.IndexOf(Core.levelInfo.barcode);
						if (num != -1)
						{
							value.RemoveAt(num);
							((Element)Core.statusElement).ElementName = "Current Level is not blacklisted";
							((Element)Core.statusElement).ElementColor = Color.green;
							BLHelper.SendNotification("Success", "Successfully unblacklisted current level (" + Core.levelInfo.title + ") from having the inventory saved and/or loaded!", showTitleOnPopup: true, 2.5f, (NotificationType)3);
						}
						return;
					}
					catch (Exception ex)
					{
						Core.Logger.Error("An unexpected error has occurred while unblacklisting the current level", ex);
						BLHelper.SendNotification("Failure", "An unexpected error has occurred while unblacklisting the current level, check the console or logs for more details", showTitleOnPopup: true, 3f, (NotificationType)2);
						return;
					}
				}
				try
				{
					value.Add(Core.levelInfo.barcode);
					((Element)Core.statusElement).ElementName = "Current Level is blacklisted";
					((Element)Core.statusElement).ElementColor = Color.red;
					BLHelper.SendNotification("Success", "Successfully blacklisted current level (" + Core.levelInfo.title + ") from having the inventory saved and/or loaded!", showTitleOnPopup: true, 2.5f, (NotificationType)3);
				}
				catch (Exception ex2)
				{
					Core.Logger.Error("An unexpected error has occurred while removing the current level from blacklist", ex2);
					BLHelper.SendNotification("Failure", "An unexpected error has occurred while blacklisting the current level, check the console or logs for more details", showTitleOnPopup: true, 3f, (NotificationType)2);
				}
			});
			SavingConfigPage = ModPage.CreatePage("Saving Config", Color.yellow, 4, true);
			SavingConfigPage.CreateBoolPref("Save Items", Color.white, ref PreferencesManager.ItemSaving, null, null, null, prefDefaultValue: true);
			SavingConfigPage.CreateBoolPref("Save Ammo", Color.white, ref PreferencesManager.AmmoSaving, null, null, null, prefDefaultValue: true);
			SavingConfigPage.CreateBoolPref("Save Gun Data", Color.white, ref PreferencesManager.SaveGunData, null, null, null, prefDefaultValue: true);
			OtherPage = ModPage.CreatePage("Other", Color.white, 0, true);
			OtherPage.CreateBoolPref("Show Notifications", Color.green, ref PreferencesManager.ShowNotifications, null, null, null, prefDefaultValue: true);
			OtherPage.CreateBoolPref("Holster Held Weapons on Death", Color.magenta, ref PreferencesManager.HolsterHeldWeaponsOnDeath);
			OtherPage.CreateFunction("Clear Inventory", Color.yellow, (Action)InventoryManager.ClearInventory);
			ModPage.CreateBlank();
			ModPage.CreateFunction("Load inventory from default save", Color.yellow, (Action)delegate
			{
				if (Core.CurrentSave != null)
				{
					InventoryManager.LoadSavedInventory(Core.CurrentSave);
				}
				else
				{
					BLHelper.SendNotification("Failure", "There is no default save!", showTitleOnPopup: true, 2f, (NotificationType)2);
				}
			});
			((Element)ModPage.CreateFunction((Core.IsLatestVersion || Core.ThunderstorePackage == null) ? "Current Version: v1.3.0" : "Current Version: v1.3.0<br><color=#00FF00>(Update available!)</color>", Color.white, (Action)delegate
			{
				Core.Logger.Msg("The current version is v1.3.0!!!!");
			})).SetProperty((ElementProperties)1);
			IsSetup = true;
		}

		internal static void SetupPredefinedBlacklists()
		{
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			if (PredefinedBlacklistPage == null)
			{
				return;
			}
			PredefinedBlacklistPage.RemoveAll();
			foreach (Blacklist blacklist in BlacklistManager.Blacklist)
			{
				if (!PredefinedBlacklistPages.ContainsKey(blacklist.ID))
				{
					PredefinedBlacklistPages.Add(blacklist.ID, PredefinedBlacklistPage.CreatePage(blacklist.DisplayName, (Color)(blacklist.Enabled ? Color.red : new Color(0f, 1f, 0f)), 0, false));
				}
				PredefinedBlacklistPage.CreateFunction($"{blacklist.DisplayName} ({blacklist.Levels.Length})", (Color)(blacklist.Enabled ? Color.red : new Color(0f, 1f, 0f)), (Action)delegate
				{
					Menu.OpenPage(PredefinedBlacklistPages[blacklist.ID]);
				});
				SetupPredefinedBlacklistPage(blacklist.ID);
			}
		}

		internal static void SetupPredefinedBlacklistPage(string id)
		{
			//IL_007c: 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)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Expected O, but got Unknown
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			Page val2 = PredefinedBlacklistPages[id];
			if (val2 == null)
			{
				return;
			}
			Blacklist blacklist = BlacklistManager.Blacklist.FirstOrDefault((Blacklist x) => x.ID == id);
			if (blacklist == null)
			{
				return;
			}
			val2.Name = blacklist.DisplayName;
			val2.Color = (Color)(blacklist.Enabled ? Color.red : new Color(0f, 1f, 0f));
			val2.RemoveAll();
			val2.CreateLabel("ID: " + blacklist.ID, Color.white);
			val2.CreateLabel("DisplayName: " + blacklist.DisplayName, Color.white);
			val2.CreateLabel($"Level Count: {blacklist.Levels.Length}", Color.white);
			val2.CreateBool("Enabled", Color.green, blacklist.Enabled, (Action<bool>)delegate(bool val)
			{
				BlacklistManager.SetEnabled(id, val);
			});
			val2.CreateBlank();
			Level[] levels = blacklist.Levels;
			foreach (Level level in levels)
			{
				LevelCrateReference val3 = new LevelCrateReference(level.Barcode);
				object obj;
				if ((int)val3 == 0)
				{
					obj = null;
				}
				else
				{
					LevelCrate crate = ((CrateReferenceT<LevelCrate>)val3).Crate;
					obj = ((crate != null) ? ((Scannable)crate).Title : null);
				}
				string text = (string)obj;
				ToggleFunctionElement toggleFunctionElement = val2.CreateToggleFunction(string.IsNullOrWhiteSpace(text) ? level.Barcode : (text + " (" + level.Barcode + ")"), Color.red, new Color(0f, 1f, 0f), null, !level.IsBlacklisted);
				toggleFunctionElement.OnStart += delegate
				{
					BlacklistManager.SetLevelBlacklisted(blacklist.ID, level.Barcode, blacklisted: false);
				};
				toggleFunctionElement.OnCancel += delegate
				{
					BlacklistManager.SetLevelBlacklisted(blacklist.ID, level.Barcode, blacklisted: true);
				};
			}
		}

		private static void SetupBlacklistView()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			if (BlacklistViewPage == null)
			{
				return;
			}
			BlacklistViewPage.RemoveAll();
			BlacklistViewPage.CreateFunction("Refresh", Color.yellow, (Action)SetupBlacklistView);
			BlacklistViewPage.CreateBlank();
			LevelCrate val = default(LevelCrate);
			foreach (string level in PreferencesManager.BlacklistedLevels.Value)
			{
				if (!((CrateReferenceT<LevelCrate>)new LevelCrateReference(level)).TryGetCrate(ref val))
				{
					continue;
				}
				FunctionElement element = null;
				element = BlacklistViewPage.CreateFunction(((Scannable)val).Title, Color.white, (Action)delegate
				{
					//IL_0051: Unknown result type (might be due to invalid IL or missing references)
					PreferencesManager.BlacklistedLevels.Value.Remove(level);
					BlacklistViewPage.Remove((Element)(object)element);
					if (Core.levelInfo.barcode == level)
					{
						((Element)Core.statusElement).ElementName = "Current level is not blacklisted";
						((Element)Core.statusElement).ElementColor = Color.green;
					}
				});
			}
		}

		internal static void SetupSharing()
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: 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)
			//IL_00a6: Expected O, but got Unknown
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Expected O, but got Unknown
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Expected O, but got Unknown
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Expected O, but got Unknown
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Expected O, but got Unknown
			if (SharingPage == null)
			{
				SharingPage = ModPage.CreatePage("Sharing", Color.cyan, 0, true);
			}
			SharingPage.CreateBool("Enabled", Color.red, ShareManager.Entry_SharingEnabled.Value, (Action<bool>)delegate(bool val)
			{
				ShareManager.Entry_SharingEnabled.Value = val;
				ShareManager.Category.SaveToFile(false);
			});
			if (SharingBlacklistPage == null)
			{
				SharingBlacklistPage = SharingPage.CreatePage("Blacklist", Color.red, 0, true);
			}
			SetupSharingBlacklist();
			object obj = <>O.<3>__SetupSharingBlacklist;
			if (obj == null)
			{
				ServerEvent val2 = SetupSharingBlacklist;
				<>O.<3>__SetupSharingBlacklist = val2;
				obj = (object)val2;
			}
			MultiplayerHooking.OnDisconnected += (ServerEvent)obj;
			object obj2 = <>O.<3>__SetupSharingBlacklist;
			if (obj2 == null)
			{
				ServerEvent val3 = SetupSharingBlacklist;
				<>O.<3>__SetupSharingBlacklist = val3;
				obj2 = (object)val3;
			}
			MultiplayerHooking.OnJoinedServer += (ServerEvent)obj2;
			object obj3 = <>O.<3>__SetupSharingBlacklist;
			if (obj3 == null)
			{
				ServerEvent val4 = SetupSharingBlacklist;
				<>O.<3>__SetupSharingBlacklist = val4;
				obj3 = (object)val4;
			}
			MultiplayerHooking.OnStartedServer += (ServerEvent)obj3;
			object obj4 = <>c.<>9__58_1;
			if (obj4 == null)
			{
				PlayerUpdate val5 = delegate
				{
					SetupSharingBlacklist();
				};
				<>c.<>9__58_1 = val5;
				obj4 = (object)val5;
			}
			MultiplayerHooking.OnPlayerJoined += (PlayerUpdate)obj4;
			object obj5 = <>c.<>9__58_2;
			if (obj5 == null)
			{
				PlayerUpdate val6 = delegate
				{
					SetupSharingBlacklist();
				};
				<>c.<>9__58_2 = val6;
				obj5 = (object)val6;
			}
			MultiplayerHooking.OnPlayerLeft += (PlayerUpdate)obj5;
		}

		internal static void SetupSharingBlacklist()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			SharingBlacklistPage.RemoveAll();
			SharingBlacklistPage.CreateFunction("Refresh", Color.yellow, (Action)SetupSharingBlacklist);
			SharingBlacklistPage.CreateBlank();
			List<FusionPlayer> players = Fusion.GetPlayers();
			players.RemoveAll((FusionPlayer x) => x.SmallID == Fusion.GetLocalPlayerSmallID());
			if (players.Count == 0)
			{
				SharingBlacklistPage.CreateLabel("Nothing to show here :(", Color.white);
				return;
			}
			foreach (FusionPlayer player in players)
			{
				ToggleFunctionElement toggleFunctionElement = SharingBlacklistPage.CreateToggleFunction(player.DisplayName, Color.white, null, ShareManager.Entry_SharingBlacklist.Value.Contains(player.PlatformID));
				toggleFunctionElement.OnStart += delegate
				{
					ShareManager.Entry_SharingBlacklist.Value.Add(player.PlatformID);
					ShareManager.Category.SaveToFile(false);
				};
				toggleFunctionElement.OnCancel += delegate
				{
					ShareManager.Entry_SharingBlacklist.Value.Remove(player.PlatformID);
					ShareManager.Category.SaveToFile(false);
				};
			}
		}

		internal static void SetupSaves()
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			if (SavesPage == null)
			{
				SavesPage = ModPage.CreatePage("Saves", Color.cyan, 0, true);
			}
			SavesPage.RemoveAll();
			StringElement nameElement = SavesPage.CreateString("Name", Color.white, string.Empty, (Action<string>)null);
			FunctionElement item = SavesPage.CreateFunction("<color=#00FF00>Create</color>", Color.white, (Action)delegate
			{
				SaveManager.RegisterSave(new KeepInventory.Saves.V2.Save
				{
					Name = nameElement.Value,
					InventorySlots = new List<KeepInventory.Saves.V2.SaveSlot>(),
					HeavyAmmo = 0,
					LightAmmo = 0,
					MediumAmmo = 0,
					ID = nameElement.Value.ToLower() + "-" + SaveManager.GenerateRandomID(6)
				});
			});
			ToggleFunctionElement func = SavesPage.CreateToggleFunction("Remove [OFF]", Color.cyan, Color.red, null);
			func.OnStart += delegate
			{
				((Element)func.Element).ElementName = "Remove [ON]";
				RemoveSavesOnPress = true;
			};
			func.OnCancel += delegate
			{
				((Element)func.Element).ElementName = "Remove [OFF]";
				RemoveSavesOnPress = false;
			};
			FunctionElement item2 = SavesPage.CreateFunction("Refresh", Color.yellow, (Action)delegate
			{
				SetupSaves();
			});
			BlankElement blankElement = SavesPage.CreateBlank();
			if (defaultSaveElements.Count == 0)
			{
				defaultSaveElements.Add((Element)(object)nameElement);
				defaultSaveElements.Add((Element)(object)item);
				defaultSaveElements.Add((Element)(object)item2);
				defaultSaveElements.Add((Element)(object)func.Element);
				defaultSaveElements.Add((Element)(object)blankElement.Element);
			}
			UpdatePresetsPage();
		}

		internal static void UpdatePresetsPage()
		{
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			if (SavesPage == null)
			{
				return;
			}
			SavesPage.RemoveAll();
			defaultSaveElements.ForEach((Action<Element>)SavesPage.Add);
			foreach (KeepInventory.Saves.V2.Save save in SaveManager.Saves)
			{
				if (save == null)
				{
					Core.Logger.Error("Save is null, cannot generate element");
					continue;
				}
				if (string.IsNullOrWhiteSpace(save.ID))
				{
					Core.Logger.Error("ID is null or empty, cannot generate element");
				}
				Page page = null;
				SavePage savePage = SavePages.FirstOrDefault((SavePage x) => x.CurrentSave == save && x.Page != null);
				if (savePage == null)
				{
					page = SavesPage.CreatePage($"<color=#{save.Color}>{save.Name}</color>", Color.white, 0, false);
					savePage = new SavePage(page, save);
					SavePages.Add(savePage);
				}
				else
				{
					page = savePage.Page;
					savePage.Setup();
				}
				FunctionElement link = null;
				link = SavesPage.CreateFunction((Core.CurrentSave == save) ? $"<color=#{save.DrawingColor.ToHEX() ?? "FFFFFF"}>+ {save.Name} +</color>" : $"<color=#{save.DrawingColor.ToHEX() ?? "FFFFFF"}>{save.Name}</color>", Color.white, (Action)delegate
				{
					if (RemoveSavesOnPress)
					{
						Menu.DisplayDialog("Destructive action", "You are about to delete a save file which after done, cannot be reversed. Are you sure?", Dialog.WarningIcon, (Action)delegate
						{
							try
							{
								SaveManager.UnregisterSave(save.ID);
								SavesPage.Remove((Element)(object)link);
							}
							catch (Exception ex)
							{
								BLHelper.SendNotification("Error", "Failed to remove save, check logs or console for more information", showTitleOnPopup: true, 2f, (NotificationType)2);
								Core.Logger.Error("An unexpected error has occurred while attempting to remove save", ex);
							}
						}, (Action)delegate
						{
							Core.Logger.Msg("Save removal denied");
						});
					}
					else
					{
						Menu.OpenPage(page);
					}
				});
			}
		}
	}
	public class