Decompiled source of SupplyCrate v0.0.1

plugins/SupplyCrate.dll

Decompiled 16 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Json.Serialization;
using AIGraph;
using AK;
using Agents;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using BepInEx.Unity.IL2CPP.Utils.Collections;
using GTFO.API;
using GTFO.API.JSON.Converters;
using GTFO.API.Utilities;
using GameData;
using Gear;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppSystem;
using LevelGeneration;
using Localization;
using MTFO.API;
using Microsoft.CodeAnalysis;
using Player;
using SNetwork;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("SupplyCrate")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("SupplyCrate")]
[assembly: AssemblyTitle("SupplyCrate")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 SupplyCrate
{
	public enum CrateCategory
	{
		Resource = 0,
		Gear = 1,
		Weapon = 1
	}
	public enum GearSlot
	{
		Standard,
		Special,
		Melee,
		Class,
		Tool
	}
	public class Vec3
	{
		public float x { get; set; }

		public float y { get; set; }

		public float z { get; set; }

		public Vector3 ToVector3()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(x, y, z);
		}

		public Quaternion ToQuaternion()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return Quaternion.Euler(x, y, z);
		}
	}
	public class UniformEntry
	{
		public GearSlot? Slot { get; set; }

		public GearRef To { get; set; }
	}
	public class MapEntry
	{
		public GearRef From { get; set; }

		public GearRef To { get; set; }
	}
	public class CrateProfile
	{
		public int Index { get; set; }

		public string Type { get; set; } = "";

		public int Limit { get; set; } = -1;

		[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
		public int? PackUses { get; set; }

		[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
		public uint? ItemID { get; set; }

		[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
		public List<UniformEntry> GearList { get; set; }

		[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
		public List<MapEntry> GearMap { get; set; }
	}
	public class CrateDefinition
	{
		public string WorldEventObjectFilter { get; set; } = "";

		public CrateCategory Category { get; set; }

		public bool Enabled { get; set; } = true;

		public Vec3 Position { get; set; } = new Vec3();

		public Vec3 Rotation { get; set; } = new Vec3();

		public float InteractDuration { get; set; } = 2.5f;

		public List<CrateProfile> ProfileList { get; set; } = new List<CrateProfile>();

		public List<WardenObjectiveEventData> EventsOnUsed { get; set; } = new List<WardenObjectiveEventData>();

		public string TerminalItemKey { get; set; } = "";

		public eDimensionIndex DimensionIndex { get; set; }

		public LG_LayerType Layer { get; set; }

		public eLocalZoneIndex LocalIndex { get; set; }

		public int AreaIndex { get; set; }
	}
	public class LevelCrates
	{
		public uint MainLevelLayout { get; set; }

		public List<CrateDefinition> Crates { get; set; } = new List<CrateDefinition>();
	}
	public class SupplyCrateConfig
	{
		public string Prefab { get; set; } = "Assets/MyAssets/SupplyCrate.prefab";

		public List<LevelCrates> Levels { get; set; } = new List<LevelCrates>();

		public bool LiveEdit { get; set; } = true;

		public bool DebugLog { get; set; }
	}
	public class CrateBinder : MonoBehaviour
	{
		internal CrateInstance Instance;

		private float m_nextRefresh;

		public CrateBinder(IntPtr ptr)
			: base(ptr)
		{
		}

		internal void Attach(CrateInstance crate)
		{
			Instance = crate;
		}

		private void Update()
		{
			CrateInstance instance = Instance;
			if (instance != null)
			{
				CrateManager.TickPending(instance);
				if (instance.Category == CrateCategory.Gear && (Object)(object)instance.Interact != (Object)null && ((Interact_Base)instance.Interact).IsSelected && Time.time >= m_nextRefresh)
				{
					m_nextRefresh = Time.time + 0.25f;
					instance.RefreshPrompt();
				}
			}
		}

		private void OnDestroy()
		{
			if (Instance != null)
			{
				CrateManager.Unregister(Instance);
			}
			Instance = null;
		}
	}
	[HarmonyPatch(typeof(Interact_Timed), "PlayerCheckInput")]
	internal static class Patch_Interact_Timed_PlayerCheckInput
	{
		private static bool Prefix(Interact_Timed __instance, PlayerAgent agent, ref bool __result)
		{
			if ((Object)(object)agent == (Object)null || !CrateManager.TryGet(((Il2CppObjectBase)__instance).Pointer, out var crate))
			{
				return true;
			}
			if (!crate.BlockInput(agent))
			{
				return true;
			}
			__instance.OnInteractorStateChanged(agent, false);
			__result = false;
			return false;
		}
	}
	internal class CrateInstance
	{
		public bool Pending;

		public float PendingSince;

		private readonly CrateUI m_ui;

		public const uint SOUND_ENABLE = 1532659459u;

		public const uint SOUND_DISABLE = 463916619u;

		private const string USES_COLOR = "#00C8C8";

		public int Id { get; }

		public string Filter => Def.WorldEventObjectFilter;

		public CrateDefinition Def { get; }

		public CrateCategory Category => Def.Category;

		public GameObject Root { get; }

		public Interact_Timed Interact { get; private set; }

		public List<CrateProfile> Profiles { get; } = new List<CrateProfile>();

		public bool Enabled { get; private set; }

		public int ProfilePos { get; private set; } = -1;

		public int Remaining { get; private set; }

		public CrateProfile Profile
		{
			get
			{
				if (ProfilePos < 0 || ProfilePos >= Profiles.Count)
				{
					return null;
				}
				return Profiles[ProfilePos];
			}
		}

		public bool Usable
		{
			get
			{
				if (Enabled && Profile != null)
				{
					return Remaining != 0;
				}
				return false;
			}
		}

		public CrateInstance(int id, CrateDefinition def, GameObject root, Interact_Timed interact)
		{
			Id = id;
			Def = def;
			Root = root;
			Interact = interact;
			BuildProfiles();
			m_ui = (((Object)(object)root != (Object)null) ? new CrateUI(root, def.WorldEventObjectFilter) : null);
			SetupInteraction();
			Enabled = def.Enabled;
			ApplyProfile(0);
		}

		private void BuildProfiles()
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			//IL_074b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0751: Expected O, but got Unknown
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Expected O, but got Unknown
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Expected O, but got Unknown
			//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Expected O, but got Unknown
			//IL_034b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0350: Unknown result type (might be due to invalid IL or missing references)
			//IL_0640: Unknown result type (might be due to invalid IL or missing references)
			//IL_0646: Expected O, but got Unknown
			//IL_0608: Unknown result type (might be due to invalid IL or missing references)
			//IL_060f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03de: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0404: Unknown result type (might be due to invalid IL or missing references)
			//IL_040a: Expected O, but got Unknown
			//IL_0476: Unknown result type (might be due to invalid IL or missing references)
			bool flag = default(bool);
			foreach (CrateProfile item in Def.ProfileList ?? new List<CrateProfile>())
			{
				if (item == null)
				{
					continue;
				}
				string text = Effects.NormalizeType(item.Type, Category);
				if (text == null)
				{
					ManualLogSource l = Plugin.L;
					BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(50, 4, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Crate '");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Filter);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' (");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<CrateCategory>(Category);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("): profile ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(item.Index);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" has invalid Type '");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(item.Type);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("', skipped");
					}
					l.LogError(val);
					continue;
				}
				item.Type = text;
				if (Category == CrateCategory.Resource)
				{
					if (item.GearList != null || item.GearMap != null)
					{
						ManualLogSource l2 = Plugin.L;
						BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(61, 2, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Crate '");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(Filter);
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("': resource profile ");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(item.Index);
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" contains weapon settings, ignored");
						}
						l2.LogWarning(val2);
					}
					item.GearList = null;
					item.GearMap = null;
					CrateProfile crateProfile = item;
					int? packUses = crateProfile.PackUses;
					int valueOrDefault = packUses.GetValueOrDefault();
					if (!packUses.HasValue)
					{
						valueOrDefault = 1;
						int? num = (crateProfile.PackUses = valueOrDefault);
					}
				}
				else
				{
					if (item.PackUses.HasValue || item.ItemID.HasValue)
					{
						ManualLogSource l3 = Plugin.L;
						BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(61, 2, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Crate '");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(Filter);
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("': weapon profile ");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(item.Index);
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" contains resource settings, ignored");
						}
						l3.LogWarning(val2);
					}
					item.PackUses = null;
					item.ItemID = null;
					if (text == "Uniform")
					{
						CrateProfile crateProfile = item;
						if (crateProfile.GearList == null)
						{
							List<UniformEntry> list = (crateProfile.GearList = new List<UniformEntry>());
						}
						int count = item.GearList.Count;
						item.GearList.RemoveAll((UniformEntry e) => e == null || !e.Slot.HasValue);
						if (item.GearList.Count != count)
						{
							ManualLogSource l4 = Plugin.L;
							BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(64, 3, ref flag);
							if (flag)
							{
								((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Crate '");
								((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(Filter);
								((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("': Uniform profile ");
								((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(item.Index);
								((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" has ");
								((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(count - item.GearList.Count);
								((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" entry(s) without 'Slot', skipped");
							}
							l4.LogWarning(val2);
						}
						for (int num3 = item.GearList.Count - 1; num3 >= 0; num3--)
						{
							UniformEntry uniformEntry = item.GearList[num3];
							InventorySlot val3 = Effects.ToInventorySlot(uniformEntry.Slot.Value);
							if (!CheckGear(uniformEntry.To, $"Uniform profile {item.Index} GearList[{num3}].To", out var slot) || slot != (InventorySlot?)val3)
							{
								if (slot.HasValue && slot != (InventorySlot?)val3)
								{
									ManualLogSource l5 = Plugin.L;
									BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(68, 7, ref flag);
									if (flag)
									{
										((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Crate '");
										((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Filter);
										((BepInExLogInterpolatedStringHandler)val).AppendLiteral("': Uniform profile ");
										((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(item.Index);
										((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" GearList[");
										((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num3);
										((BepInExLogInterpolatedStringHandler)val).AppendLiteral("] skipped: Slot = ");
										((BepInExLogInterpolatedStringHandler)val).AppendFormatted<GearSlot?>(uniformEntry.Slot);
										((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (");
										((BepInExLogInterpolatedStringHandler)val).AppendFormatted<InventorySlot>(val3);
										((BepInExLogInterpolatedStringHandler)val).AppendLiteral("), To '");
										((BepInExLogInterpolatedStringHandler)val).AppendFormatted<GearRef>(uniformEntry.To);
										((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' is ");
										((BepInExLogInterpolatedStringHandler)val).AppendFormatted<InventorySlot?>(slot);
									}
									l5.LogError(val);
								}
								item.GearList.RemoveAt(num3);
							}
						}
						item.GearMap = null;
					}
					else
					{
						CrateProfile crateProfile = item;
						if (crateProfile.GearMap == null)
						{
							List<MapEntry> list3 = (crateProfile.GearMap = new List<MapEntry>());
						}
						item.GearMap.RemoveAll((MapEntry e) => e == null);
						for (int num4 = item.GearMap.Count - 1; num4 >= 0; num4--)
						{
							MapEntry mapEntry = item.GearMap[num4];
							InventorySlot? slot2;
							bool flag2 = CheckGear(mapEntry.From, $"Map profile {item.Index} GearMap[{num4}].From", out slot2);
							InventorySlot? slot3;
							bool flag3 = CheckGear(mapEntry.To, $"Map profile {item.Index} GearMap[{num4}].To", out slot3);
							if (!flag2 || !flag3 || slot2 != slot3)
							{
								if (flag2 && flag3)
								{
									ManualLogSource l6 = Plugin.L;
									BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(64, 7, ref flag);
									if (flag)
									{
										((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Crate '");
										((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Filter);
										((BepInExLogInterpolatedStringHandler)val).AppendLiteral("': Map profile ");
										((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(item.Index);
										((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" GearMap[");
										((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num4);
										((BepInExLogInterpolatedStringHandler)val).AppendLiteral("] skipped: From '");
										((BepInExLogInterpolatedStringHandler)val).AppendFormatted<GearRef>(mapEntry.From);
										((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' is ");
										((BepInExLogInterpolatedStringHandler)val).AppendFormatted<InventorySlot?>(slot2);
										((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", To '");
										((BepInExLogInterpolatedStringHandler)val).AppendFormatted<GearRef>(mapEntry.To);
										((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' is ");
										((BepInExLogInterpolatedStringHandler)val).AppendFormatted<InventorySlot?>(slot3);
									}
									l6.LogError(val);
								}
								item.GearMap.RemoveAt(num4);
							}
						}
						item.GearList = null;
					}
				}
				Profiles.Add(item);
			}
			if (Profiles.Count == 0)
			{
				ManualLogSource l7 = Plugin.L;
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(26, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Crate '");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Filter);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("': no valid profile");
				}
				l7.LogError(val);
			}
		}

		private bool CheckGear(GearRef r, string where, out InventorySlot? slot)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			slot = null;
			bool flag = default(bool);
			if (r == null)
			{
				ManualLogSource l = Plugin.L;
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(34, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Crate '");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Filter);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("': ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(where);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" is empty, entry skipped");
				}
				l.LogError(val);
				return false;
			}
			uint id = r.Resolve();
			slot = Effects.GetGearSlot(id);
			if (!slot.HasValue)
			{
				ManualLogSource l2 = Plugin.L;
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(70, 3, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Crate '");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Filter);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("': ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(where);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" '");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<GearRef>(r);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' is not a valid PlayerOfflineGearDataBlock, entry skipped");
				}
				l2.LogError(val);
				return false;
			}
			return true;
		}

		public int FindProfilePos(int index)
		{
			return Profiles.FindIndex((CrateProfile p) => p.Index == index);
		}

		public void ApplyProfile(int pos)
		{
			if (pos < 0 || pos >= Profiles.Count)
			{
				ProfilePos = -1;
				Remaining = 0;
			}
			else
			{
				ProfilePos = pos;
				Remaining = Profiles[pos].Limit;
			}
			UpdateActive();
		}

		public void SetEnabled(bool enabled)
		{
			bool num = Enabled != enabled;
			Enabled = enabled;
			UpdateActive();
			if (num)
			{
				PlaySound(enabled ? 1532659459u : 463916619u);
			}
		}

		private void PlaySound(uint id)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Vector3 val = (((Object)(object)Interact != (Object)null) ? ((Component)Interact).transform.position : (((Object)(object)Root != (Object)null) ? Root.transform.position : Vector3.zero));
				CellSound.Post(id, val);
			}
			catch (Exception ex)
			{
				ManualLogSource l = Plugin.L;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(17, 3, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Crate '");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(Filter);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' sound ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<uint>(id);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
				}
				l.LogError(val2);
			}
		}

		private void UpdateSprites()
		{
			string text = ((Category == CrateCategory.Gear) ? "Gear" : Profile?.Type);
			m_ui?.Apply((Profile == null) ? null : text, Usable);
		}

		public void Consume()
		{
			if (Remaining > 0)
			{
				SetRemaining(Remaining - 1);
			}
		}

		public void SetRemaining(int value)
		{
			bool num = Remaining != 0 && value == 0;
			Remaining = value;
			UpdateActive();
			if (num)
			{
				OnDepleted();
			}
		}

		public void ApplyState(bool enabled, int profilePos, int remaining)
		{
			ProfilePos = profilePos;
			Enabled = enabled;
			SetRemaining(remaining);
		}

		private void OnDepleted()
		{
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			Plugin.Debug("Crate '" + Filter + "' depleted");
			if (Enabled)
			{
				PlaySound(463916619u);
			}
			if (Def.EventsOnUsed == null)
			{
				return;
			}
			bool flag = default(bool);
			foreach (WardenObjectiveEventData item in Def.EventsOnUsed)
			{
				if (item == null)
				{
					continue;
				}
				try
				{
					WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(item, (eWardenObjectiveEventTrigger)0, true, 0f);
				}
				catch (Exception ex)
				{
					ManualLogSource l = Plugin.L;
					BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(23, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Crate '");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Filter);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' EventsOnUsed: ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
					}
					l.LogError(val);
				}
			}
		}

		private void UpdateActive()
		{
			if (!((Object)(object)Interact == (Object)null))
			{
				bool usable = Usable;
				if (((Interact_Base)Interact).IsActive != usable)
				{
					((Interact_Base)Interact).SetActive(usable);
				}
				UpdateSprites();
				RefreshPrompt();
			}
		}

		private void SetupInteraction()
		{
			if (!((Object)(object)Interact == (Object)null))
			{
				if (Def.InteractDuration >= 0f)
				{
					Interact.InteractDuration = Def.InteractDuration;
				}
				Interact_Timed interact = Interact;
				interact.ExternalPlayerCanInteract += Func<PlayerAgent, bool>.op_Implicit((Func<PlayerAgent, bool>)((PlayerAgent _) => Usable && !Pending));
				Interact_Timed interact2 = Interact;
				interact2.OnInteractionSelected += Action<PlayerAgent, bool>.op_Implicit((Action<PlayerAgent, bool>)OnSelected);
				Interact_Timed interact3 = Interact;
				interact3.OnInteractionTriggered += Action<PlayerAgent>.op_Implicit((Action<PlayerAgent>)OnTriggered);
			}
		}

		private void OnSelected(PlayerAgent agent, bool selected)
		{
			if (selected && (Object)(object)agent != (Object)null && ((Agent)agent).IsLocallyOwned)
			{
				RefreshPrompt(force: true);
			}
		}

		public bool BlockInput(PlayerAgent agent)
		{
			if (Category == CrateCategory.Gear)
			{
				return !Effects.Resolve(Profile, agent).Valid;
			}
			return false;
		}

		private string UsesSuffix()
		{
			CrateProfile profile = Profile;
			if (profile == null || profile.Limit < 0)
			{
				return "";
			}
			string text = Texts.Format("InGame.OnAdditionalInteractionText.SupplyCrate.Uses", " ({0}/{1})", Remaining, profile.Limit);
			string text2 = text.TrimStart();
			return text.Substring(0, text.Length - text2.Length) + $"<color={"#00C8C8"}>{text2}</color>";
		}

		private string Button(string additionalId, string additionalFallback)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			string text;
			try
			{
				text = Text.Format(827u, (Object[])(object)new Object[1] { Object.op_Implicit(InputMapper.GetBindingName(((Interact_Base)Interact).InputAction)) });
			}
			catch
			{
				text = "[E]";
			}
			return text + Texts.Get(additionalId, additionalFallback) + UsesSuffix();
		}

		private static string Orange(string s)
		{
			return "<color=orange>" + s + "</color>";
		}

		public void RefreshPrompt(bool force = false)
		{
			if ((Object)(object)Interact == (Object)null || !Usable || (!force && !((Interact_Base)Interact).IsSelected))
			{
				return;
			}
			PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent();
			if ((Object)(object)localPlayerAgent == (Object)null)
			{
				return;
			}
			string text;
			string text2;
			if (Category == CrateCategory.Resource)
			{
				text = Texts.ResourceHeader(Profile.Type);
				text2 = Button("InGame.OnAdditionalInteractionText.ResourceStation", " TO REPLENISH");
			}
			else
			{
				Effects.SwapPlan swapPlan = Effects.Resolve(Profile, localPlayerAgent);
				if (swapPlan.Valid)
				{
					text = Texts.Format("InGame.InteractionPrompt.WeaponStation.Swap", "将 {0} 换为 {1}", Orange(swapPlan.FromName), Orange(swapPlan.ToName));
					text2 = Button("InGame.OnAdditionalInteractionText.WeaponStation", " 以交换");
				}
				else
				{
					text = "<color=red>" + Texts.Get("InGame.InteractionPrompt.WeaponStation.CannotSwap", "当前武器无法交换") + "</color>";
					text2 = UsesSuffix().Trim();
				}
			}
			Interact.InteractionMessage = text;
			GuiManager.InteractionLayer.SetInteractPrompt(text, text2, (ePUIMessageStyle)0);
		}

		private void OnTriggered(PlayerAgent agent)
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected O, but got Unknown
			if ((Object)(object)agent == (Object)null || !((Agent)agent).IsLocallyOwned || !Usable)
			{
				return;
			}
			try
			{
				if (Category != CrateCategory.Gear || Effects.Resolve(Profile, agent).Valid)
				{
					if (Profile.Limit < 0)
					{
						Execute(agent);
					}
					else
					{
						CrateManager.RequestUse(this, agent);
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource l = Plugin.L;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(22, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Crate '");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Filter);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' OnTriggered: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				l.LogError(val);
			}
		}

		public void Execute(PlayerAgent agent)
		{
			CrateProfile profile = Profile;
			if (profile != null)
			{
				bool flag = false;
				if (Category == CrateCategory.Resource)
				{
					Effects.GiveResourcePack(agent, profile.ItemID ?? Effects.DefaultItemID(profile.Type), profile.PackUses ?? 1);
					flag = true;
				}
				else
				{
					flag = Effects.Swap(Effects.Resolve(profile, agent));
				}
				if (flag)
				{
					agent.Sound.Post(EVENTS.AMMOPACK_APPLY, true);
				}
				Plugin.Debug($"Crate '{Filter}' used by {agent.PlayerName} ok={flag}");
			}
		}

		public void Unhook()
		{
			Interact = null;
		}
	}
	internal static class CrateManager
	{
		public struct pUseRequest
		{
			public int CrateId;
		}

		public struct pUseGrant
		{
			public int CrateId;

			public byte Granted;
		}

		public struct pCrateState
		{
			public int CrateId;

			public byte Enabled;

			public int ProfilePos;

			public int Remaining;
		}

		public const uint EVENT_SET_CRATE_STATUS = 2000u;

		public const string INTERACTION_CHILD = "Interaction";

		private const string EV_REQ = "Neo.SupplyCrate.Req";

		private const string EV_GRANT = "Neo.SupplyCrate.Grant";

		private const string EV_STATE = "Neo.SupplyCrate.State.v3";

		private const float PENDING_TIMEOUT = 3f;

		private static readonly Dictionary<int, CrateInstance> s_crates = new Dictionary<int, CrateInstance>();

		private static readonly Dictionary<string, CrateInstance> s_byFilter = new Dictionary<string, CrateInstance>(StringComparer.OrdinalIgnoreCase);

		private static readonly Dictionary<int, pCrateState> s_earlyStates = new Dictionary<int, pCrateState>();

		private static bool s_built;

		public static uint CurrentLayout
		{
			get
			{
				try
				{
					ExpeditionInTierData activeExpedition = RundownManager.ActiveExpedition;
					return (activeExpedition != null) ? activeExpedition.LevelLayoutData : 0u;
				}
				catch
				{
					return 0u;
				}
			}
		}

		public static void Init()
		{
			NetworkAPI.RegisterEvent<pUseRequest>("Neo.SupplyCrate.Req", (Action<ulong, pUseRequest>)OnReceiveRequest);
			NetworkAPI.RegisterEvent<pUseGrant>("Neo.SupplyCrate.Grant", (Action<ulong, pUseGrant>)OnReceiveGrant);
			NetworkAPI.RegisterEvent<pCrateState>("Neo.SupplyCrate.State.v3", (Action<ulong, pCrateState>)OnReceiveState);
			WardenEvents.Add(2000u, SetCrateStatus);
			LevelAPI.OnBuildStart += Clear;
			LevelAPI.OnLevelCleanup += Clear;
			LevelAPI.OnBuildDone += SpawnLevelCrates;
		}

		public static bool TryGet(IntPtr interactPtr, out CrateInstance crate)
		{
			foreach (CrateInstance value in s_crates.Values)
			{
				if ((Object)(object)value.Interact != (Object)null && ((Il2CppObjectBase)value.Interact).Pointer == interactPtr)
				{
					crate = value;
					return true;
				}
			}
			crate = null;
			return false;
		}

		private static int StableHash(string s)
		{
			uint num = 2166136261u;
			foreach (char c in s)
			{
				num ^= c;
				num *= 16777619;
			}
			return (int)(num & 0x7FFFFFFF);
		}

		public static void Rebuild()
		{
			if (s_built)
			{
				Clear();
				s_built = true;
				SpawnLevelCrates();
			}
		}

		private static void Clear()
		{
			s_built = false;
			Effects.ResetCache();
			Texts.ResetCache();
			foreach (CrateInstance value in s_crates.Values)
			{
				value.Unhook();
				if ((Object)(object)value.Root != (Object)null)
				{
					Object.Destroy((Object)(object)value.Root);
				}
			}
			s_crates.Clear();
			s_byFilter.Clear();
			s_earlyStates.Clear();
		}

		public static void Unregister(CrateInstance crate)
		{
			if (crate != null)
			{
				if (s_crates.TryGetValue(crate.Id, out var value) && value == crate)
				{
					s_crates.Remove(crate.Id);
				}
				if (s_byFilter.TryGetValue(crate.Filter ?? "", out value) && value == crate)
				{
					s_byFilter.Remove(crate.Filter);
				}
				crate.Unhook();
			}
		}

		private static void SpawnLevelCrates()
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			s_built = true;
			uint currentLayout = CurrentLayout;
			bool flag = default(bool);
			foreach (LevelCrates level in Plugin.Config.Levels)
			{
				if (level == null || level.MainLevelLayout != currentLayout || level.Crates == null)
				{
					continue;
				}
				foreach (CrateDefinition crate in level.Crates)
				{
					if (crate == null)
					{
						continue;
					}
					try
					{
						Spawn(crate, currentLayout);
					}
					catch (Exception ex)
					{
						ManualLogSource l = Plugin.L;
						BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(23, 2, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Spawn crate '");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(crate.WorldEventObjectFilter);
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' failed: ");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
						}
						l.LogError(val);
					}
				}
			}
		}

		private static void Spawn(CrateDefinition def, uint layout)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Expected O, but got Unknown
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Expected O, but got Unknown
			if (string.IsNullOrWhiteSpace(def.WorldEventObjectFilter))
			{
				Plugin.L.LogError((object)"Crate without WorldEventObjectFilter skipped");
				return;
			}
			bool flag = default(bool);
			if (s_byFilter.ContainsKey(def.WorldEventObjectFilter))
			{
				ManualLogSource l = Plugin.L;
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(41, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("WorldEventObjectFilter '");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(def.WorldEventObjectFilter);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' is already used");
				}
				l.LogError(val);
				return;
			}
			string prefab = Plugin.Config.Prefab;
			GameObject val2 = (string.IsNullOrEmpty(prefab) ? null : AssetAPI.GetLoadedAsset<GameObject>(prefab));
			if ((Object)(object)val2 == (Object)null)
			{
				ManualLogSource l2 = Plugin.L;
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(30, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Crate '");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(def.WorldEventObjectFilter);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("': prefab '");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(prefab);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' not loaded");
				}
				l2.LogError(val);
				return;
			}
			GameObject val3 = Object.Instantiate<GameObject>(val2);
			val3.transform.SetPositionAndRotation(def.Position.ToVector3(), def.Rotation.ToQuaternion());
			Transform val4 = val3.transform.Find("Interaction");
			Interact_Timed val5 = (((Object)(object)val4 != (Object)null) ? ((Component)val4).GetComponentInChildren<Interact_Timed>(true) : null);
			if (val5 == null)
			{
				val5 = val3.GetComponentInChildren<Interact_Timed>(true);
			}
			if ((Object)(object)val5 == (Object)null)
			{
				ManualLogSource l3 = Plugin.L;
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(33, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Crate '");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(def.WorldEventObjectFilter);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("': no Interact_Timed in '");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(prefab);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'");
				}
				l3.LogError(val);
				Object.Destroy((Object)(object)val3);
				return;
			}
			SetupTerminalItem(val3, def);
			int num = StableHash($"{layout}:{def.WorldEventObjectFilter.ToLowerInvariant()}");
			CrateInstance crateInstance = new CrateInstance(num, def, val3, val5);
			s_crates[num] = crateInstance;
			s_byFilter[def.WorldEventObjectFilter] = crateInstance;
			((Component)val5).gameObject.AddComponent<CrateBinder>().Attach(crateInstance);
			if (s_earlyStates.Remove(num, out var value))
			{
				ApplyState(crateInstance, value);
			}
			Plugin.Debug($"Crate '{def.WorldEventObjectFilter}' ({def.Category}) spawned, id={num}");
		}

		private static void SetupTerminalItem(GameObject go, CrateDefinition def)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			LG_GenericTerminalItem componentInChildren = go.GetComponentInChildren<LG_GenericTerminalItem>(true);
			if ((Object)(object)componentInChildren == (Object)null || string.IsNullOrEmpty(def.TerminalItemKey))
			{
				return;
			}
			LG_Zone val = default(LG_Zone);
			if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(def.DimensionIndex, def.Layer, def.LocalIndex, ref val) || (Object)(object)val == (Object)null || def.AreaIndex < 0 || def.AreaIndex >= val.m_areas.Count)
			{
				ManualLogSource l = Plugin.L;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(52, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Crate '");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(def.WorldEventObjectFilter);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("': zone/area not found, terminal item skipped");
				}
				l.LogWarning(val2);
			}
			else
			{
				componentInChildren.Setup($"{def.TerminalItemKey}_{SerialGenerator.GetUniqueSerialNo()}", val.m_areas[def.AreaIndex].m_courseNode);
				componentInChildren.FloorItemLocation = val.NavInfo.GetFormattedText((LG_NavInfoFormat)7);
				componentInChildren.FloorItemStatus = (eFloorInventoryObjectStatus)0;
			}
		}

		private static void SetCrateStatus(WardenObjectiveEventData e)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Expected O, but got Unknown
			string worldEventObjectFilter = e.WorldEventObjectFilter;
			bool flag = default(bool);
			if (string.IsNullOrEmpty(worldEventObjectFilter) || !s_byFilter.TryGetValue(worldEventObjectFilter, out var value))
			{
				ManualLogSource l = Plugin.L;
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(34, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("SetCrateStatus: crate '");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(worldEventObjectFilter);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' not found");
				}
				l.LogError(val);
				return;
			}
			if (e.SustainedEventSlotIndex == 1)
			{
				int num = value.FindProfilePos(e.Count);
				if (num < 0)
				{
					ManualLogSource l2 = Plugin.L;
					BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(51, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("SetCrateStatus: crate '");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(worldEventObjectFilter);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' has no profile with Index ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(e.Count);
					}
					l2.LogError(val);
				}
				else
				{
					value.ApplyProfile(num);
				}
			}
			value.SetEnabled(e.Enabled);
			Plugin.Debug($"SetCrateStatus '{worldEventObjectFilter}': enabled={e.Enabled} slot={e.SustainedEventSlotIndex} count={e.Count}");
			if (SNet.IsMaster)
			{
				BroadcastState(value);
			}
		}

		public static void RequestUse(CrateInstance crate, PlayerAgent agent)
		{
			if (SNet.IsMaster)
			{
				if (MasterHandle(crate))
				{
					crate.Execute(agent);
				}
			}
			else if (!((Object)(object)SNet.Master == (Object)null))
			{
				crate.Pending = true;
				crate.PendingSince = Clock.Time;
				NetworkAPI.InvokeEvent<pUseRequest>("Neo.SupplyCrate.Req", new pUseRequest
				{
					CrateId = crate.Id
				}, SNet.Master, (SNet_ChannelType)2);
			}
		}

		private static bool MasterHandle(CrateInstance crate)
		{
			if (!crate.Usable)
			{
				return false;
			}
			crate.Consume();
			BroadcastState(crate);
			return true;
		}

		private static void OnReceiveRequest(ulong sender, pUseRequest req)
		{
			SNet_Player val = default(SNet_Player);
			if (SNet.IsMaster && SNet.TryGetPlayer(sender, ref val) && !((Object)(object)val == (Object)null))
			{
				CrateInstance value;
				bool flag = s_crates.TryGetValue(req.CrateId, out value) && MasterHandle(value);
				if (!flag && value != null)
				{
					SendState(value, val);
				}
				NetworkAPI.InvokeEvent<pUseGrant>("Neo.SupplyCrate.Grant", new pUseGrant
				{
					CrateId = req.CrateId,
					Granted = (flag ? ((byte)1) : ((byte)0))
				}, val, (SNet_ChannelType)2);
			}
		}

		private static void OnReceiveGrant(ulong sender, pUseGrant g)
		{
			if (s_crates.TryGetValue(g.CrateId, out var value))
			{
				value.Pending = false;
				PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent();
				if (g.Granted != 0 && (Object)(object)localPlayerAgent != (Object)null)
				{
					value.Execute(localPlayerAgent);
				}
			}
		}

		private static pCrateState MakeState(CrateInstance c)
		{
			return new pCrateState
			{
				CrateId = c.Id,
				Enabled = (c.Enabled ? ((byte)1) : ((byte)0)),
				ProfilePos = c.ProfilePos,
				Remaining = c.Remaining
			};
		}

		private static void BroadcastState(CrateInstance c)
		{
			NetworkAPI.InvokeEvent<pCrateState>("Neo.SupplyCrate.State.v3", MakeState(c), (SNet_ChannelType)2);
		}

		private static void SendState(CrateInstance c, SNet_Player to)
		{
			NetworkAPI.InvokeEvent<pCrateState>("Neo.SupplyCrate.State.v3", MakeState(c), to, (SNet_ChannelType)2);
		}

		private static void OnReceiveState(ulong sender, pCrateState st)
		{
			if (!SNet.IsMaster)
			{
				if (s_crates.TryGetValue(st.CrateId, out var value))
				{
					ApplyState(value, st);
				}
				else
				{
					s_earlyStates[st.CrateId] = st;
				}
			}
		}

		private static void ApplyState(CrateInstance c, pCrateState st)
		{
			c.ApplyState(st.Enabled != 0, st.ProfilePos, st.Remaining);
		}

		public static void TickPending(CrateInstance c)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			if (c.Pending && Clock.Time - c.PendingSince > 3f)
			{
				c.Pending = false;
				ManualLogSource l = Plugin.L;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(31, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Crate '");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(c.Filter);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("': no response from host");
				}
				l.LogWarning(val);
			}
		}
	}
	internal class CrateUI
	{
		private struct Part
		{
			public SpriteRenderer Renderer;

			public Color Default;
		}

		public const string UI_ROOT = "UI";

		public const string MISC = "UI_Misc";

		public const string BACKLIT = "UI_Backlit";

		private static readonly Color RED = new Color(1f, 0f, 0f, 1f);

		private static readonly (string type, string[] names)[] TypeNames = new(string, string[])[5]
		{
			("Medi", new string[1] { "UI_Medi" }),
			("Ammo", new string[1] { "UI_Ammo" }),
			("Tool", new string[1] { "UI_Tool" }),
			("Disinfect", new string[1] { "UI_Disinfect" }),
			("Gear", new string[1] { "UI_Gear" })
		};

		private readonly List<Part> m_misc = new List<Part>();

		private Part? m_backlit;

		private readonly Dictionary<string, Part> m_types = new Dictionary<string, Part>(StringComparer.OrdinalIgnoreCase);

		public CrateUI(GameObject root, string crateName)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			Transform val = root.transform.Find("UI");
			if ((Object)(object)val == (Object)null)
			{
				ManualLogSource l = Plugin.L;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(41, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Crate '");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(crateName);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("': child '");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>("UI");
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' not found, UI disabled");
				}
				l.LogWarning(val2);
				return;
			}
			foreach (SpriteRenderer componentsInChild in ((Component)val).GetComponentsInChildren<SpriteRenderer>(true))
			{
				string name = ((Object)((Component)componentsInChild).gameObject).name;
				Part part = new Part
				{
					Renderer = componentsInChild,
					Default = componentsInChild.color
				};
				if (name.StartsWith("UI_Misc"))
				{
					m_misc.Add(part);
					continue;
				}
				if (name.StartsWith("UI_Backlit"))
				{
					Part valueOrDefault = m_backlit.GetValueOrDefault();
					if (!m_backlit.HasValue)
					{
						valueOrDefault = part;
						m_backlit = valueOrDefault;
					}
					continue;
				}
				(string, string[])[] typeNames = TypeNames;
				for (int i = 0; i < typeNames.Length; i++)
				{
					(string, string[]) tuple = typeNames[i];
					var (key, _) = tuple;
					if (Array.IndexOf(tuple.Item2, name) >= 0)
					{
						if (!m_types.ContainsKey(key))
						{
							m_types[key] = part;
						}
						break;
					}
				}
			}
			Plugin.Debug($"Crate '{crateName}' UI: misc={m_misc.Count} backlit={m_backlit.HasValue} types={string.Join(",", m_types.Keys)}");
		}

		public void Apply(string type, bool available)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			foreach (Part item in m_misc)
			{
				Set(item, active: true, available ? item.Default : RED);
			}
			Part value = default(Part);
			bool flag = type != null && m_types.TryGetValue(type, out value);
			Part? backlit = m_backlit;
			if (backlit.HasValue)
			{
				Part valueOrDefault = backlit.GetValueOrDefault();
				Set(valueOrDefault, active: true, (!available) ? RED : (flag ? value.Default : valueOrDefault.Default));
			}
			foreach (KeyValuePair<string, Part> type2 in m_types)
			{
				bool active = flag && type2.Key.Equals(type, StringComparison.OrdinalIgnoreCase);
				Set(type2.Value, active, available ? type2.Value.Default : RED);
			}
		}

		private static void Set(Part p, bool active, Color c)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)p.Renderer == (Object)null))
			{
				GameObject gameObject = ((Component)p.Renderer).gameObject;
				if (gameObject.activeSelf != active)
				{
					gameObject.SetActive(active);
				}
				p.Renderer.color = c;
			}
		}
	}
	internal static class Effects
	{
		public struct SwapPlan
		{
			public InventorySlot Slot;

			public PlayerOfflineGearDataBlock Target;

			public string FromName;

			public string ToName;

			public bool Valid => Target != null;
		}

		public const float AMMO_PER_PACK_USE = 20f;

		private const string OFFLINE_PREFIX = "OfflineGear_ID_";

		public static readonly string[] ResourceTypes = new string[4] { "Ammo", "Medi", "Tool", "Disinfect" };

		public static readonly string[] WeaponTypes = new string[2] { "Uniform", "Map" };

		private static Dictionary<uint, uint> s_checksumToID;

		private static readonly Dictionary<uint, InventorySlot> s_slotCache = new Dictionary<uint, InventorySlot>();

		private static Dictionary<string, uint> s_nameToID;

		private static readonly HashSet<string> s_missingNames = new HashSet<string>();

		private static readonly Dictionary<uint, string> s_nameCache = new Dictionary<uint, string>();

		private static readonly HashSet<string> s_nameLogged = new HashSet<string>();

		private static bool s_rawInit;

		private static bool s_rawOk;

		private static uint s_offPublicName;

		private static uint s_offId;

		private static uint s_offText;

		public static string NormalizeType(string t, CrateCategory cat)
		{
			string[] array = ((cat == CrateCategory.Resource) ? ResourceTypes : WeaponTypes);
			foreach (string text in array)
			{
				if (text.Equals(t, StringComparison.OrdinalIgnoreCase))
				{
					return text;
				}
			}
			return null;
		}

		public static uint DefaultItemID(string type)
		{
			return type switch
			{
				"Medi" => 102u, 
				"Tool" => 127u, 
				"Disinfect" => 132u, 
				_ => 101u, 
			};
		}

		public static void GiveResourcePack(PlayerAgent player, uint id, int packUses)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: 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_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: 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_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: 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)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			ItemDataBlock block = GameDataBlockBase<ItemDataBlock>.GetBlock(id);
			if (block == null)
			{
				ManualLogSource l = Plugin.L;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(38, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("ResourcePack: ItemDataBlock ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<uint>(id);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" not found");
				}
				l.LogError(val);
				return;
			}
			float ammo = (float)Math.Max(1, packUses) * 20f;
			pItemData val2 = new pItemData
			{
				custom = new pItemData_Custom
				{
					ammo = ammo,
					byteId = 0,
					byteState = 0
				},
				itemID_gearCRC = id,
				slot = block.inventorySlot,
				originLayer = ((Agent)player).CourseNode.LayerType
			};
			((pCourseNode)(ref val2.originCourseNode)).Set(((Agent)player).CourseNode);
			ItemReplicationManager.SpawnItem(val2, DelegateSupport.ConvertDelegate<delItemCallback>((Delegate)(Action<ISyncedItem, PlayerAgent>)delegate(ISyncedItem item, PlayerAgent owner)
			{
				//IL_0041: Unknown result type (might be due to invalid IL or missing references)
				//IL_0054: Unknown result type (might be due to invalid IL or missing references)
				//IL_0057: Unknown result type (might be due to invalid IL or missing references)
				//IL_005d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0061: Unknown result type (might be due to invalid IL or missing references)
				//IL_0067: 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_0086: Unknown result type (might be due to invalid IL or missing references)
				//IL_0089: Unknown result type (might be due to invalid IL or missing references)
				//IL_008f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0093: Unknown result type (might be due to invalid IL or missing references)
				//IL_0099: Unknown result type (might be due to invalid IL or missing references)
				ItemInLevel val3 = ((Il2CppObjectBase)item).TryCast<ItemInLevel>();
				if (!((Object)(object)val3 == (Object)null) && !((Object)(object)owner == (Object)null))
				{
					ItemInLevel val4 = val3;
					if (val4.CourseNode == null)
					{
						AIG_CourseNode val5 = (val4.CourseNode = ((Agent)owner).CourseNode);
					}
					val3.internalSync.AttemptPickupInteraction((ePickupItemInteractionType)2, owner.Owner, new pItemData_Custom
					{
						ammo = ammo
					}, default(Vector3), default(Quaternion), (AIG_CourseNode)null, false, false);
					val3.internalSync.AttemptPickupInteraction((ePickupItemInteractionType)0, owner.Owner, default(pItemData_Custom), default(Vector3), default(Quaternion), (AIG_CourseNode)null, false, false);
				}
			}), (ItemMode)2, ((Agent)player).Position + new Vector3(0f, 0.06f, 0f), ((Agent)player).Rotation, ((Agent)player).CourseNode, player);
		}

		public static InventorySlot ToInventorySlot(GearSlot s)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			switch (s)
			{
			case GearSlot.Standard:
				return (InventorySlot)1;
			case GearSlot.Special:
				return (InventorySlot)2;
			case GearSlot.Melee:
				return (InventorySlot)10;
			case GearSlot.Class:
			case GearSlot.Tool:
				return (InventorySlot)3;
			default:
				return (InventorySlot)3;
			}
		}

		private static bool IsGearSlot(InventorySlot s)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Invalid comparison between Unknown and I4
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Invalid comparison between Unknown and I4
			if (s - 1 <= 2 || (int)s == 10)
			{
				return true;
			}
			return false;
		}

		public static uint? GetOfflineGearID(GearIDRange g)
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected O, but got Unknown
			if (g == null)
			{
				return null;
			}
			string playfabItemInstanceId = g.PlayfabItemInstanceId;
			if (playfabItemInstanceId != null && playfabItemInstanceId.StartsWith("OfflineGear_ID_") && uint.TryParse(playfabItemInstanceId.Substring("OfflineGear_ID_".Length), out var result) && GameDataBlockBase<PlayerOfflineGearDataBlock>.GetBlock(result) != null)
			{
				return result;
			}
			try
			{
				BuildChecksumMap();
				if (s_checksumToID.TryGetValue(g.GetChecksum(), out result))
				{
					return result;
				}
			}
			catch (Exception ex)
			{
				ManualLogSource l = Plugin.L;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(18, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("GetOfflineGearID: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
				}
				l.LogError(val);
			}
			return null;
		}

		private static void BuildChecksumMap()
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			if (s_checksumToID != null)
			{
				return;
			}
			s_checksumToID = new Dictionary<uint, uint>();
			foreach (PlayerOfflineGearDataBlock item in GameDataBlockBase<PlayerOfflineGearDataBlock>.GetAllBlocksForEditor())
			{
				if (item == null || string.IsNullOrEmpty(item.GearJSON))
				{
					continue;
				}
				try
				{
					uint checksum = new GearIDRange(item.GearJSON).GetChecksum();
					if (!s_checksumToID.ContainsKey(checksum))
					{
						s_checksumToID[checksum] = ((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)item).persistentID;
					}
				}
				catch
				{
				}
			}
			Plugin.Debug($"Offline gear checksum map: {s_checksumToID.Count} entries");
		}

		public static InventorySlot? GetGearSlot(uint id)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			if (id == 0)
			{
				return null;
			}
			if (s_slotCache.TryGetValue(id, out var value))
			{
				return value;
			}
			PlayerOfflineGearDataBlock block = GameDataBlockBase<PlayerOfflineGearDataBlock>.GetBlock(id);
			if (block == null || string.IsNullOrEmpty(block.GearJSON))
			{
				return null;
			}
			try
			{
				ItemDataBlock block2 = GameDataBlockBase<ItemDataBlock>.GetBlock(new GearIDRange(block.GearJSON).GetCompID((eGearComponent)3));
				if (block2 == null)
				{
					return null;
				}
				s_slotCache[id] = block2.inventorySlot;
				return block2.inventorySlot;
			}
			catch
			{
				return null;
			}
		}

		public static uint FindOfflineGearByName(string name)
		{
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Expected O, but got Unknown
			if (s_nameToID == null)
			{
				s_nameToID = new Dictionary<string, uint>(StringComparer.Ordinal);
				foreach (PlayerOfflineGearDataBlock item in GameDataBlockBase<PlayerOfflineGearDataBlock>.GetAllBlocksForEditor())
				{
					if (item != null && !string.IsNullOrEmpty(((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)item).name))
					{
						if (s_nameToID.ContainsKey(((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)item).name))
						{
							Plugin.Debug($"PlayerOfflineGearDataBlock name '{((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)item).name}' duplicated, using {s_nameToID[((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)item).name]} (ignoring {((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)item).persistentID})");
						}
						else
						{
							s_nameToID[((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)item).name] = ((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)item).persistentID;
						}
					}
				}
			}
			if (s_nameToID.TryGetValue(name, out var value))
			{
				return value;
			}
			if (s_missingNames.Add(name))
			{
				ManualLogSource l = Plugin.L;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(49, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("PlayerOfflineGearDataBlock with name '");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(name);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' not found");
				}
				l.LogError(val);
			}
			return 0u;
		}

		public static void ResetCache()
		{
			s_nameToID = null;
			s_missingNames.Clear();
			s_slotCache.Clear();
			s_nameLogged.Clear();
			s_checksumToID = null;
			s_nameCache.Clear();
		}

		private static GearIDRange GetGear(PlayerAgent p, InventorySlot slot)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			BackpackItem val = null;
			if (!PlayerBackpackManager.TryGetItem(p.Owner, slot, ref val))
			{
				return null;
			}
			if (val == null)
			{
				return null;
			}
			return val.GearIDRange;
		}

		public static string GearName(PlayerOfflineGearDataBlock block)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			if (s_nameCache.TryGetValue(((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)block).persistentID, out var value))
			{
				return value;
			}
			try
			{
				value = DisplayName(new GearIDRange(block.GearJSON));
			}
			catch
			{
			}
			if (string.IsNullOrEmpty(value))
			{
				value = ((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)block).name;
			}
			s_nameCache[((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)block).persistentID] = value;
			return value;
		}

		private static string Localized(LocalizedText t, StringBuilder log)
		{
			if (t == (LocalizedText)null)
			{
				log.Append(" PublicName=null");
				return null;
			}
			uint num = 0u;
			string text = null;
			StringBuilder stringBuilder;
			StringBuilder.AppendInterpolatedStringHandler handler;
			try
			{
				num = t.Id;
			}
			catch (Exception ex)
			{
				stringBuilder = log;
				StringBuilder stringBuilder2 = stringBuilder;
				handler = new StringBuilder.AppendInterpolatedStringHandler(4, 1, stringBuilder);
				handler.AppendLiteral(" Id!");
				handler.AppendFormatted(ex.Message);
				stringBuilder2.Append(ref handler);
			}
			try
			{
				text = t.UntranslatedText;
			}
			catch
			{
			}
			stringBuilder = log;
			StringBuilder stringBuilder3 = stringBuilder;
			handler = new StringBuilder.AppendInterpolatedStringHandler(31, 2, stringBuilder);
			handler.AppendLiteral(" PublicName.Id=");
			handler.AppendFormatted(num);
			handler.AppendLiteral(" Untranslated='");
			handler.AppendFormatted(text);
			handler.AppendLiteral("'");
			stringBuilder3.Append(ref handler);
			if (num != 0)
			{
				try
				{
					string text2 = Text.Get(num);
					stringBuilder = log;
					StringBuilder stringBuilder4 = stringBuilder;
					handler = new StringBuilder.AppendInterpolatedStringHandler(12, 1, stringBuilder);
					handler.AppendLiteral(" Text.Get='");
					handler.AppendFormatted(text2);
					handler.AppendLiteral("'");
					stringBuilder4.Append(ref handler);
					if (!string.IsNullOrWhiteSpace(text2))
					{
						return text2;
					}
				}
				catch (Exception ex2)
				{
					stringBuilder = log;
					StringBuilder stringBuilder5 = stringBuilder;
					handler = new StringBuilder.AppendInterpolatedStringHandler(10, 1, stringBuilder);
					handler.AppendLiteral(" Text.Get!");
					handler.AppendFormatted(ex2.Message);
					stringBuilder5.Append(ref handler);
				}
			}
			return text;
		}

		private static string ArchetypePublicName(ArchetypeDataBlock arch, StringBuilder log)
		{
			try
			{
				return Localized(arch.PublicName, log);
			}
			catch (Exception ex)
			{
				StringBuilder stringBuilder = log;
				StringBuilder stringBuilder2 = stringBuilder;
				StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(6, 1, stringBuilder);
				handler.AppendLiteral(" prop!");
				handler.AppendFormatted(ex.GetType().Name);
				stringBuilder2.Append(ref handler);
			}
			try
			{
				return Localized(arch._PublicName_k__BackingField, log);
			}
			catch (Exception ex2)
			{
				StringBuilder stringBuilder = log;
				StringBuilder stringBuilder3 = stringBuilder;
				StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(7, 1, stringBuilder);
				handler.AppendLiteral(" field!");
				handler.AppendFormatted(ex2.GetType().Name);
				stringBuilder3.Append(ref handler);
			}
			try
			{
				if (RawLocalizedText(((Il2CppObjectBase)arch).Pointer, out var id, out var untranslated))
				{
					StringBuilder stringBuilder = log;
					StringBuilder stringBuilder4 = stringBuilder;
					StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(24, 2, stringBuilder);
					handler.AppendLiteral(" raw Id=");
					handler.AppendFormatted(id);
					handler.AppendLiteral(" Untranslated='");
					handler.AppendFormatted(untranslated);
					handler.AppendLiteral("'");
					stringBuilder4.Append(ref handler);
					if (id != 0)
					{
						string text = Text.Get(id);
						stringBuilder = log;
						StringBuilder stringBuilder5 = stringBuilder;
						handler = new StringBuilder.AppendInterpolatedStringHandler(12, 1, stringBuilder);
						handler.AppendLiteral(" Text.Get='");
						handler.AppendFormatted(text);
						handler.AppendLiteral("'");
						stringBuilder5.Append(ref handler);
						if (!string.IsNullOrWhiteSpace(text))
						{
							return text;
						}
					}
					return untranslated;
				}
				log.Append(" raw: field not found");
			}
			catch (Exception ex3)
			{
				StringBuilder stringBuilder = log;
				StringBuilder stringBuilder6 = stringBuilder;
				StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(7, 2, stringBuilder);
				handler.AppendLiteral(" raw!");
				handler.AppendFormatted(ex3.GetType().Name);
				handler.AppendLiteral(": ");
				handler.AppendFormatted(ex3.Message);
				stringBuilder6.Append(ref handler);
			}
			return null;
		}

		private static IntPtr FindField(IntPtr cls, params string[] names)
		{
			foreach (string text in names)
			{
				IntPtr il2CppField = IL2CPP.GetIl2CppField(cls, text);
				if (il2CppField != IntPtr.Zero)
				{
					return il2CppField;
				}
			}
			return IntPtr.Zero;
		}

		private unsafe static bool RawLocalizedText(IntPtr archPtr, out uint id, out string untranslated)
		{
			id = 0u;
			untranslated = null;
			if (!s_rawInit)
			{
				s_rawInit = true;
				IntPtr nativeClassPtr = Il2CppClassPointerStore<ArchetypeDataBlock>.NativeClassPtr;
				IntPtr nativeClassPtr2 = Il2CppClassPointerStore<LocalizedText>.NativeClassPtr;
				IntPtr intPtr = FindField(nativeClassPtr, "<PublicName>k__BackingField", "PublicName");
				IntPtr intPtr2 = FindField(nativeClassPtr2, "<Id>k__BackingField", "Id");
				IntPtr intPtr3 = FindField(nativeClassPtr2, "<UntranslatedText>k__BackingField", "UntranslatedText");
				if (intPtr != IntPtr.Zero && intPtr2 != IntPtr.Zero && intPtr3 != IntPtr.Zero)
				{
					s_offPublicName = IL2CPP.il2cpp_field_get_offset(intPtr);
					uint num = (uint)(IntPtr.Size * 2);
					s_offId = IL2CPP.il2cpp_field_get_offset(intPtr2) - num;
					s_offText = IL2CPP.il2cpp_field_get_offset(intPtr3) - num;
					s_rawOk = true;
				}
			}
			if (!s_rawOk || archPtr == IntPtr.Zero)
			{
				return false;
			}
			byte* ptr = (byte*)(void*)archPtr + s_offPublicName;
			id = *(uint*)(ptr + s_offId);
			IntPtr intPtr4 = *(IntPtr*)(ptr + s_offText);
			untranslated = ((intPtr4 == IntPtr.Zero) ? null : IL2CPP.Il2CppStringToManaged(intPtr4));
			return true;
		}

		public static string DisplayName(GearIDRange gear)
		{
			//IL_0094: 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_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Expected I4, but got Unknown
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Expected O, but got Unknown
			if (gear == null)
			{
				return "";
			}
			string publicGearName = gear.PublicGearName;
			StringBuilder stringBuilder = new StringBuilder();
			string text = null;
			try
			{
				uint compID = gear.GetCompID((eGearComponent)2);
				uint compID2 = gear.GetCompID((eGearComponent)1);
				StringBuilder stringBuilder2 = stringBuilder;
				StringBuilder stringBuilder3 = stringBuilder2;
				StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(14, 2, stringBuilder2);
				handler.AppendLiteral("cat=");
				handler.AppendFormatted(compID);
				handler.AppendLiteral(" fireMode=");
				handler.AppendFormatted(compID2);
				stringBuilder3.Append(ref handler);
				GearCategoryDataBlock block = GameDataBlockBase<GearCategoryDataBlock>.GetBlock(compID);
				if (block == null)
				{
					stringBuilder.Append(" cat=null");
				}
				else
				{
					uint num;
					if (compID == 12)
					{
						num = 0u;
					}
					else
					{
						eWeaponFireMode val = (eWeaponFireMode)compID2;
						num = (val - 1) switch
						{
							0 => block.BurstArchetype, 
							1 => block.AutoArchetype, 
							2 => block.SemiBurstArchetype, 
							_ => block.SemiArchetype, 
						};
					}
					uint num2 = num;
					ArchetypeDataBlock val2 = ((compID == 12) ? SentryGunInstance_Firing_Bullets.GetArchetypeDataForFireMode((eWeaponFireMode)compID2) : GameDataBlockBase<ArchetypeDataBlock>.GetBlock(num2));
					stringBuilder2 = stringBuilder;
					StringBuilder stringBuilder4 = stringBuilder2;
					handler = new StringBuilder.AppendInterpolatedStringHandler(14, 2, stringBuilder2);
					handler.AppendLiteral(" archId=");
					handler.AppendFormatted(num2);
					handler.AppendLiteral(" arch=");
					handler.AppendFormatted((val2 == null) ? "null" : ((GameDataBlockBase<ArchetypeDataBlock>)(object)val2).name);
					stringBuilder4.Append(ref handler);
					if (val2 != null)
					{
						text = ArchetypePublicName(val2, stringBuilder);
					}
					if (string.IsNullOrWhiteSpace(text))
					{
						text = LocalizedText.op_Implicit(block.PublicName);
						stringBuilder2 = stringBuilder;
						StringBuilder stringBuilder5 = stringBuilder2;
						handler = new StringBuilder.AppendInterpolatedStringHandler(17, 1, stringBuilder2);
						handler.AppendLiteral(" catPublicName='");
						handler.AppendFormatted(text);
						handler.AppendLiteral("'");
						stringBuilder5.Append(ref handler);
					}
				}
			}
			catch (Exception ex)
			{
				StringBuilder stringBuilder2 = stringBuilder;
				StringBuilder stringBuilder6 = stringBuilder2;
				StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(13, 2, stringBuilder2);
				handler.AppendLiteral(" EXCEPTION ");
				handler.AppendFormatted(ex.GetType().Name);
				handler.AppendLiteral(": ");
				handler.AppendFormatted(ex.Message);
				stringBuilder6.Append(ref handler);
			}
			if (string.IsNullOrWhiteSpace(text))
			{
				text = publicGearName;
			}
			if (s_nameLogged.Add(publicGearName ?? ""))
			{
				ManualLogSource l = Plugin.L;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(22, 3, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Weapon name '");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(publicGearName);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("': ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<StringBuilder>(stringBuilder);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" -> '");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(text);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("'");
				}
				l.LogInfo(val3);
			}
			return text;
		}

		public static SwapPlan Resolve(CrateProfile profile, PlayerAgent p)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Expected O, but got Unknown
			//IL_028f: Unknown result type (might be due to invalid IL or missing references)
			SwapPlan result = new SwapPlan
			{
				Slot = (InventorySlot)0
			};
			if (profile == null || (Object)(object)p == (Object)null)
			{
				return result;
			}
			uint num = 0u;
			if (profile.Type == "Uniform")
			{
				List<UniformEntry> gearList = profile.GearList;
				if (gearList == null || gearList.Count == 0)
				{
					return result;
				}
				if (gearList.Count == 1)
				{
					result.Slot = ToInventorySlot(gearList[0].Slot.Value);
					num = gearList[0].To?.Resolve() ?? 0;
				}
				else
				{
					result.Slot = p.Inventory.WieldedSlot;
					bool flag = false;
					foreach (UniformEntry item in gearList)
					{
						if (ToInventorySlot(item.Slot.Value) == result.Slot)
						{
							num = item.To?.Resolve() ?? 0;
							flag = true;
							break;
						}
					}
					if (!flag)
					{
						return result;
					}
				}
			}
			else
			{
				List<MapEntry> gearMap = profile.GearMap;
				result.Slot = p.Inventory.WieldedSlot;
				if (gearMap == null || gearMap.Count == 0 || !IsGearSlot(result.Slot))
				{
					return result;
				}
				uint? offlineGearID = GetOfflineGearID(GetGear(p, result.Slot));
				if (!offlineGearID.HasValue)
				{
					return result;
				}
				bool flag2 = false;
				foreach (MapEntry item2 in gearMap)
				{
					if (item2.From != null && item2.From.Resolve() == offlineGearID.Value)
					{
						num = item2.To?.Resolve() ?? 0;
						flag2 = true;
						break;
					}
				}
				if (!flag2)
				{
					return result;
				}
			}
			if (num == 0)
			{
				return result;
			}
			GearIDRange gear = GetGear(p, result.Slot);
			if (gear == null)
			{
				return result;
			}
			if (GetOfflineGearID(gear) == num)
			{
				return result;
			}
			PlayerOfflineGearDataBlock block = GameDataBlockBase<PlayerOfflineGearDataBlock>.GetBlock(num);
			if (block == null)
			{
				ManualLogSource l = Plugin.L;
				bool flag3 = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(47, 1, ref flag3);
				if (flag3)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("SwapGear: PlayerOfflineGearDataBlock ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<uint>(num);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" not found");
				}
				l.LogError(val);
				return result;
			}
			result.Target = block;
			result.FromName = DisplayName(gear);
			if (result.FromName == gear.PublicGearName)
			{
				try
				{
					BackpackItem val2 = null;
					if (PlayerBackpackManager.TryGetItem(p.Owner, result.Slot, ref val2) && (Object)(object)((val2 != null) ? val2.Instance : null) != (Object)null)
					{
						ItemEquippable obj = ((Il2CppObjectBase)val2.Instance).TryCast<ItemEquippable>();
						string text = ((obj != null) ? ((Item)obj).ArchetypeName : null);
						if (!string.IsNullOrWhiteSpace(text))
						{
							result.FromName = text;
						}
					}
				}
				catch
				{
				}
			}
			result.ToName = GearName(block);
			return result;
		}

		public static bool Swap(SwapPlan plan)
		{
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Expected O, but got Unknown
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			if (!plan.Valid)
			{
				return false;
			}
			try
			{
				PlayerBackpackManager.EquipLocalGear(new GearIDRange(plan.Target.GearJSON)
				{
					PlayfabItemInstanceId = "OfflineGear_ID_" + ((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)plan.Target).persistentID
				});
				Plugin.Debug($"SwapGear {plan.Slot}: {plan.FromName} -> {((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)plan.Target).persistentID} {plan.ToName}");
				return true;
			}
			catch (Exception ex)
			{
				ManualLogSource l = Plugin.L;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(17, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("SwapGear failed: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				l.LogError(val);
				return false;
			}
		}
	}
	[JsonConverter(typeof(GearRefConverter))]
	public class GearRef
	{
		public uint ID { get; }

		public string Name { get; }

		public GearRef(uint id)
		{
			ID = id;
		}

		public GearRef(string name)
		{
			Name = name;
		}

		public uint Resolve()
		{
			if (Name != null)
			{
				return Effects.FindOfflineGearByName(Name);
			}
			return ID;
		}

		public override string ToString()
		{
			return Name ?? ID.ToString();
		}
	}
	public class GearRefConverter : JsonConverter<GearRef>
	{
		public override GearRef Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
		{
			switch (reader.TokenType)
			{
			case JsonTokenType.Number:
				return new GearRef(reader.GetUInt32());
			case JsonTokenType.String:
			{
				string text = reader.GetString()?.Trim();
				if (string.IsNullOrEmpty(text))
				{
					return null;
				}
				if (!uint.TryParse(text, out var result))
				{
					return new GearRef(text);
				}
				return new GearRef(result);
			}
			case JsonTokenType.Null:
				return null;
			default:
				throw new JsonException("Gear reference must be a persistentID or a name");
			}
		}

		public override void Write(Utf8JsonWriter writer, GearRef value, JsonSerializerOptions options)
		{
			if (value == null)
			{
				writer.WriteNullValue();
			}
			else if (value.Name != null)
			{
				writer.WriteStringValue(value.Name);
			}
			else
			{
				writer.WriteNumberValue(value.ID);
			}
		}
	}
	internal static class Json
	{
		private sealed class Vector3Converter : JsonConverter<Vector3>
		{
			public override Vector3 Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
			{
				//IL_009a: Unknown result type (might be due to invalid IL or missing references)
				//IL_009f: Unknown result type (might be due to invalid IL or missing references)
				//IL_011f: Unknown result type (might be due to invalid IL or missing references)
				//IL_006a: Unknown result type (might be due to invalid IL or missing references)
				if (reader.TokenType == JsonTokenType.String)
				{
					string[] array = reader.GetString().Trim('(', ')', ' ').Split(new char[2] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);
					if (array.Length == 3 && float.TryParse(array[0], out var result) && float.TryParse(array[1], out var result2) && float.TryParse(array[2], out var result3))
					{
						return new Vector3(result, result2, result3);
					}
					throw new JsonException("Invalid Vector3: " + reader.GetString());
				}
				if (reader.TokenType != JsonTokenType.StartObject)
				{
					throw new JsonException("Vector3 must be an object or string");
				}
				Vector3 zero = Vector3.zero;
				while (reader.Read() && reader.TokenType != JsonTokenType.EndObject)
				{
					string text = reader.GetString()?.ToLowerInvariant();
					reader.Read();
					float single = reader.GetSingle();
					switch (text)
					{
					case "x":
						zero.x = single;
						break;
					case "y":
						zero.y = single;
						break;
					case "z":
						zero.z = single;
						break;
					}
				}
				return zero;
			}

			public override void Write(Utf8JsonWriter writer, Vector3 value, JsonSerializerOptions options)
			{
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Unknown result type (might be due to invalid IL or missing references)
				writer.WriteStartObject();
				writer.WriteNumber("x", value.x);
				writer.WriteNumber("y", value.y);
				writer.WriteNumber("z", value.z);
				writer.WriteEndObject();
			}
		}

		public const string PDATA_GUID = "MTFO.Extension.PartialBlocks";

		public static readonly JsonSerializerOptions Options;

		public static bool PartialDataLoaded { get; private set; }

		static Json()
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			Options = new JsonSerializerOptions
			{
				ReadCommentHandling = JsonCommentHandling.Skip,
				AllowTrailingCommas = true,
				PropertyNameCaseInsensitive = true,
				IncludeFields = false,
				IgnoreReadOnlyProperties = true,
				WriteIndented = true,
				Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
			};
			Options.Converters.Add(new JsonStringEnumConverter());
			Options.Converters.Add(new Vector3Converter());
			Options.Converters.Add((JsonConverter)new LocalizedTextConverter());
			JsonConverter jsonConverter = FindPartialDataConverter();
			if (jsonConverter != null)
			{
				Options.Converters.Add(jsonConverter);
				PartialDataLoaded = true;
				Plugin.L.LogInfo((object)"PartialData support enabled");
			}
		}

		public static T Deserialize<T>(string json)
		{
			return JsonSerializer.Deserialize<T>(json, Options);
		}

		private static JsonConverter FindPartialDataConverter()
		{
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Expected O, but got Unknown
			try
			{
				if (!((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.TryGetValue("MTFO.Extension.PartialBlocks", out var value))
				{
					return null;
				}
				Assembly assembly = ((value == null) ? null : value.Instance?.GetType()?.Assembly);
				if (assembly == null)
				{
					return null;
				}
				Type[] source;
				try
				{
					source = assembly.GetTypes();
				}
				catch (ReflectionTypeLoadException ex)
				{
					source = ex.Types.Where((Type t) => t != null).ToArray();
				}
				Type type = source.FirstOrDefault((Type x) => x.Name == "PersistentIDConverter");
				return (type == null) ? null : ((JsonConverter)Activator.CreateInstance(type));
			}
			catch (Exception ex2)
			{
				ManualLogSource l = Plugin.L;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(37, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("PartialData converter not available: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex2.Message);
				}
				l.LogWarning(val);
				return null;
			}
		}
	}
	[BepInPlugin("Neo.SupplyCrate", "SupplyCrate", "2.8.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInIncompatibility("cris.SupplyCrateSetup")]
	public class Plugin : BasePlugin
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static Action <0>__LoadConfig;

			public static LiveEditEventHandler <1>__OnFileChanged;
		}

		public const string GUID = "Neo.SupplyCrate";

		public const string NAME = "SupplyCrate";

		public const string VERSION = "2.8.0";

		public const string CONFIG_FILE = "SupplyCrate.json";

		internal static ManualLogSource L;

		private static LiveEditListener s_listener;

		internal static SupplyCrateConfig Config { get; private set; } = new SupplyCrateConfig();

		internal static string ConfigPath { get; private set; }

		public override void Load()
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			L = ((BasePlugin)this).Log;
			ClassInjector.RegisterTypeInIl2Cpp<CrateBinder>();
			ConfigPath = ResolveConfigPath();
			EnsureConfigFile();
			LevelAPI.OnBuildStart += LoadConfig;
			CrateManager.Init();
			SetupLiveEdit();
			new Harmony("Neo.SupplyCrate").PatchAll();
			ManualLogSource l = L;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(18, 3, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("SupplyCrate");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("2.8.0");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" loaded. Config: ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ConfigPath);
			}
			l.LogInfo(val);
		}

		private static void SetupLiveEdit()
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			try
			{
				s_listener = LiveEdit.CreateListener(Path.GetDirectoryName(ConfigPath), "SupplyCrate.json", false);
				LiveEditListener obj = s_listener;
				object obj2 = <>O.<1>__OnFileChanged;
				if (obj2 == null)
				{
					LiveEditEventHandler val = OnFileChanged;
					<>O.<1>__OnFileChanged = val;
					obj2 = (object)val;
				}
				obj.FileChanged += (LiveEditEventHandler)obj2;
			}
			catch (Exception ex)
			{
				ManualLogSource l = L;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(23, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("LiveEdit setup failed: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
				}
				l.LogError(val2);
			}
		}

		private static void OnFileChanged(LiveEditEventArgs e)
		{
			if (!string.Equals(Path.GetFileName(e.FullPath), "SupplyCrate.json", StringComparison.OrdinalIgnoreCase))
			{
				return;
			}
			LiveEdit.TryReadFileContent(e.FullPath, (Action<string>)delegate(string content)
			{
				SupplyCrateConfig supplyCrateConfig = Parse(content);
				if (supplyCrateConfig != null)
				{
					Config = supplyCrateConfig;
					if (!supplyCrateConfig.LiveEdit)
					{
						L.LogInfo((object)"Config reloaded (LiveEdit off, applies next level)");
					}
					else
					{
						L.LogWarning((object)"LiveEdit: config reloaded, rebuilding crates");
						CrateManager.Rebuild();
					}
				}
			});
		}

		private static SupplyCrateConfig Parse(string content)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			try
			{
				SupplyCrateConfig supplyCrateConfig = Json.Deserialize<SupplyCrateConfig>(content);
				if (supplyCrateConfig == null)
				{
					return null;
				}
				if (string.IsNullOrEmpty(supplyCrateConfig.Prefab))
				{
					supplyCrateConfig.Prefab = "Assets/MyAssets/SupplyCrate.prefab";
				}
				SupplyCrateConfig supplyCrateConfig2 = supplyCrateConfig;
				if (supplyCrateConfig2.Levels == null)
				{
					List<LevelCrates> list = (supplyCrateConfig2.Levels = new List<LevelCrates>());
				}
				return supplyCrateConfig;
			}
			catch (Exception ex)
			{
				ManualLogSource l = L;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(43, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Failed to parse ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("SupplyCrate.json");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", keeping previous config: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
				}
				l.LogError(val);
				return null;
			}
		}

		internal static void Debug(string msg)
		{
			if (Config.DebugLog)
			{
				L.LogInfo((object)msg);
			}
		}

		private static string ResolveConfigPath()
		{
			try
			{
				string directoryName = Path.GetDirectoryName(typeof(Plugin).Assembly.Location);
				if (!string.IsNullOrEmpty(directoryName))
				{
					return Path.Combine(directoryName, "SupplyCrate.json");
				}
			}
			catch
			{
			}
			return Path.Combine(MTFOPathAPI.CustomPath, "SupplyCrate.json");
		}

		private static string ReadTemplate()
		{
			using Stream stream = typeof(Plugin).Assembly.GetManifestResourceStream("SupplyCrate.template.json");
			using StreamReader streamReader = new StreamReader(stream);
			return streamReader.ReadToEnd();
		}

		private static void EnsureConfigFile()
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			bool flag = default(bool);
			try
			{
				if (!File.Exists(ConfigPath))
				{
					Directory.CreateDirectory(Path.GetDirectoryName(ConfigPath));
					File.WriteAllText(ConfigPath, ReadTemplate());
					ManualLogSource l = L;
					BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(38, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Config not found, template written to ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ConfigPath);
					}
					l.LogWarning(val);
				}
			}
			catch (Exception ex)
			{
				ManualLogSource l2 = L;
				BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(26, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Failed to write template: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
				}
				l2.LogError(val2);
			}
		}

		internal static void LoadConfig()
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			bool flag = default(bool);
			try
			{
				if (!File.Exists(ConfigPath))
				{
					Directory.CreateDirectory(Path.GetDirectoryName(ConfigPath));
					File.WriteAllText(ConfigPath, ReadTemplate());
					ManualLogSource l = L;
					BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(38, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Config not found, template written to ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ConfigPath);
					}
					l.LogWarning(val);
				}
				SupplyCrateConfig supplyCrateConfig = Parse(File.ReadAllText(ConfigPath));
				if (supplyCrateConfig != null)
				{
					Config = supplyCrateConfig;
				}
			}
			catch (Exception ex)
			{
				ManualLogSource l2 = L;
				BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(42, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Failed to load ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ConfigPath);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", keeping previous config: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
				}
				l2.LogError(val2);
			}
		}
	}
	public static class Template
	{
		public static SupplyCrateConfig Create()
		{
			return new SupplyCrateConfig
			{
				Prefab = "Assets/MyAssets/SupplyCrate.prefab",
				Levels = 
				{
					new LevelCrates
					{
						MainLevelLayout = 0u,
						Crates = 
						{
							new CrateDefinition
							{
								WorldEventObjectFilter = "ResourceCrate_1",
								Category = CrateCategory.Resource,
								Position = new Vec3
								{
									x = 0f,
									y = 0f,
									z = 0f
								},
								Rotation = new Vec3
								{
									x = 0f,
									y = 0f,
									z = 0f
								},
								ProfileList = 
								{
									new CrateProfile
									{
										Index = 0,
										Type = "Tool",
										PackUses = 3,
										Limit = 4
									},
									new CrateProfile
									{
										Index = 1,
										Type = "Medi",
										PackUses = 2,
										Limit = 3
									}
								}
							},
							new CrateDefinition
							{
								WorldEventObjectFilter = "GearCrate_1",
								Category = CrateCategory.Gear,
								Position = new Vec3
								{
									x = 2f,
									y = 0f,
									z = 0f
								},
								Rotation = new Vec3
								{
									x = 0f,
									y = 0f,
									z = 0f
								},
								ProfileList = 
								{
									new CrateProfile
									{
										Index = 0,
										Type = "Uniform",
										Limit = 4,
										GearList = new List<UniformEntry>
										{
											new UniformEntry
											{
												Slot = GearSlot.Standard,
												To = new GearRef(1u)
											},
											new UniformEntry
											{
												Slot = GearSlot.Special,
												To = new GearRef("Gear_Name_Example")
											}
										}
									},
									new CrateProfile
									{
										Index = 1,
										Type = "Map",
										Limit = 3,
										GearMap = new List<MapEntry>
										{
											new MapEntry
											{
												From = new GearRef(1u),
												To = new GearRef(2u)
											},
											new MapEntry
											{
												From = new GearRef("Gear_Name_A"),
												To = new GearRef("Gear_Name_B")
											}
										}
									}
								}
							}
						}
					}
				}
			};
		}
	}
	internal static class Texts
	{
		public const string AMMO = "InGame.InteractionPrompt.AmmoStation";

		public const string MEDI = "InGame.InteractionPrompt.MediStation";

		public const string TOOL = "InGame.InteractionPrompt.ToolStation";

		public const string DISINFECT = "InGame.InteractionPrompt.DisinfectionStation";

		public const string RESOURCE_ADDITIONAL = "InGame.OnAdditionalInteractionText.ResourceStation";

		public const string WEAPON_SWAP = "InGame.InteractionPrompt.WeaponStation.Swap";

		public const string WEAPON_CANNOT = "InGame.InteractionPrompt.WeaponStation.CannotSwap";

		public const string WEAPON_ADDITIONAL = "InGame.OnAdditionalInteractionText.WeaponStation";

		public const string USES = "InGame.OnAdditionalInteractionText.SupplyCrate.Uses";

		private static Dictionary<string, uint> s_ids;

		public static void ResetCache()
		{
			s_ids = null;
		}

		public static string Get(string name, string fallback)
		{
			try
			{
				if (s_ids == null)
				{
					s_ids = new Dictionary<string, uint>(StringComparer.Ordinal);
					foreach (TextDataBlock allBlock in GameDataBlockBase<TextDataBlock>.GetAllBlocks())
					{
						if (allBlock != null && !string.IsNullOrEmpty(((GameDataBlockBase<TextDataBlock>)(object)allBlock).name))
						{
							s_ids[((GameDataBlockBase<TextDataBlock>)(object)allBlock).name] = ((GameDataBlockBase<TextDataBlock>)(object)allBlock).persistentID;
						}
					}
				}
				if (s_ids.TryGetValue(name, out var value))
				{
					return Text.Get(value);
				}
			}
			catch
			{
			}
			return fallback;
		}

		public static string Format(string name, string fallback, params object[] args)
		{
			string format = Get(name, fallback);
			try
			{
				return string.Format(format, args);
			}
			catch (FormatException)
			{
				return string.Format(fallback, args);
			}
		}

		public static string ResourceHeader(string type)
		{
			return type switch
			{
				"Medi" => Get("InGame.InteractionPrompt.MediStation", "HEALTH STATION"), 
				"Tool" => Get("InGame.InteractionPrompt.ToolStation", "TOOL STATION"), 
				"Disinfect" => Get("InGame.InteractionPrompt.DisinfectionStation", "DISINFECTION STATION"), 
				_ => Get("InGame.InteractionPrompt.AmmoStation", "AMMUNITION STATION"), 
			};
		}
	}
	internal static class WardenEvents
	{
		[HarmonyPatch(typeof(WardenObjectiveManager), "CheckAndExecuteEventsOnTrigger", new Type[]
		{
			typeof(WardenObjectiveEventData),
			typeof(eWardenObjectiveEventTrigger),
			typeof(bool),
			typeof(float)
		})]
		private static class Patch
		{
			private static bool Prefix(WardenObjectiveEventData eventToTrigger, eWardenObjectiveEventTrigger trigger, bool ignoreTrigger, float currentDuration)
			{
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_000e: 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_0034: Expected I4, but got Unknown
				if (eventToTrigger == null || (!ignoreTrigger && eventToTrigger.Trigger != trigger) || (currentDuration != 0f && eventToTrigger.Delay <= currentDuration))
				{
					return true;
				}
				if (!s_defs.ContainsKey((uint)(int)eventToTrigger.Type))
				{
					return true;
				}
				Coroutine val = CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(Handle(eventToTrigger, currentDuration)), (Action)null);
				WorldEventManager.m_worldEventEventCoroutines.Add(val);
				return false;
			}
		}

		private static readonly Dictionary<uint, Action<WardenObjectiveEventData>> s_defs = new Dictionary<uint, Action<WardenObjectiveEventData>>();

		public static void Add(uint id, Action<WardenObjectiveEventData> handler)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			if (Enum.IsDefined(typeof(eWardenObjectiveEventType), (int)id))
			{
				ManualLogSource l = Plugin.L;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(35, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Event ID ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<uint>(id);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" overrides a vanilla event");
				}
				l.LogWarning(val);
			}
			s_defs[id] = handler;
		}

		private static IEnumerator Handle(WardenObjectiveEventData e, float currentDuration)
		{
			float num = Mathf.Max(e.Delay - currentDuration, 0f);
			if (num > 0f)
			{
				yield return (object)new WaitForSeconds(num);
			}
			if (WorldEventManager.GetCondition(e.Condition.ConditionIndex) != e.Condition.IsTrue)
			{
				yield break;
			}
			WardenObjectiveManager.DisplayWardenIntel(e.Layer, e.WardenIntel);
			if (e.DialogueID != 0)
			{
				PlayerDialogManager.WantToStartDialog(e.DialogueID, -1, false, false);
			}
			if (e.SoundID != 0)
			{
				WardenObjectiveManager.Current.m_sound.Post(e.SoundID, true);
				LocalizedText soundSubtitle = e.SoundSubtitle;
				stri