Decompiled source of REPOForge v1.6.34

REPOForge.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using REPOForge.Compat;
using REPOForge.Network;
using REPOForge.Shop;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.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 REPOForge
{
	public sealed class CompatManifest
	{
		public string Guid { get; set; } = "";

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

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

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

		public List<string> PrefabPaths { get; } = new List<string>();

		public List<string> PatchClaims { get; } = new List<string>();
	}
	public sealed class DriftReportEvent
	{
		public bool HardMismatch { get; set; }

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

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

		public List<string> Findings { get; set; } = new List<string>();
	}
	public static class Forge
	{
		public static class Bus
		{
			public static void Subscribe<T>(Action<T> handler)
			{
				PluginBus.Subscribe(handler);
			}

			public static void Unsubscribe<T>(Action<T> handler)
			{
				PluginBus.Unsubscribe(handler);
			}

			public static void Publish<T>(T evt)
			{
				PluginBus.Publish(evt);
			}
		}

		public static class Library
		{
			public static int Count => ModLibrary.Entries.Count;

			public static bool ShopSkip(string itemName)
			{
				return ModLibrary.ShopSkip(itemName);
			}

			public static bool SelfSpawns(string itemName)
			{
				return ModLibrary.SelfSpawns(itemName);
			}
		}

		public static class Shop
		{
			public static string LastManifestHash => ShopCoordinator.LastHash;

			public static void Register(ShopIntent intent)
			{
				ShopCoordinator.Register(intent);
			}

			public static void Unregister(string itemName)
			{
				ShopCoordinator.Unregister(itemName);
			}
		}

		public static class Compat
		{
			public static string Fingerprint => DiscrepancyGuard.LocalFingerprint;

			public static void Declare(CompatManifest manifest)
			{
				DiscrepancyGuard.Declare(manifest);
			}
		}

		public static class Network
		{
			public static bool RegisterPrefab(string path, GameObject prefab)
			{
				return PrefabRegistry.Register(path, prefab);
			}

			public static GameObject SpawnItem(object item, Vector3 position, Quaternion rotation)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				return PrefabRegistry.SpawnItem(item, position, rotation);
			}
		}

		public static class Harmony
		{
			public static void Claim(string method, HarmonyLane lane, string owner)
			{
				HarmonyArbiter.Claim(method, lane, owner);
			}
		}
	}
	internal static class GameAccess
	{
		private const BindingFlags Flags = BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

		private static readonly Dictionary<(Type, string), MemberInfo> Cache = new Dictionary<(Type, string), MemberInfo>();

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

		private static bool _roleLogged;

		internal static Type Type(string name)
		{
			return AccessTools.TypeByName(name) ?? AccessTools.TypeByName(name + ", Assembly-CSharp");
		}

		internal static object Instance(string typeName)
		{
			Type type = Type(typeName);
			if (type == null)
			{
				return null;
			}
			return GetStatic(type, "instance") ?? GetStatic(type, "Instance") ?? GetStatic(type, "Singleton");
		}

		internal static bool IsMaster()
		{
			bool? flag = PhotonIsMaster();
			if (flag.HasValue)
			{
				LogRoleOnce(flag.Value);
				return flag.Value;
			}
			try
			{
				Type type = Type("SemiFunc");
				MethodInfo methodInfo = ((type != null) ? type.GetMethod("IsMasterClientOrSingleplayer", BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) : null) ?? ((type != null) ? type.GetMethod("IsMasterClient", BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) : null);
				if (methodInfo != null)
				{
					bool num = (bool)methodInfo.Invoke(null, null);
					LogRoleOnce(num);
					return num;
				}
			}
			catch (Exception)
			{
			}
			return !IsMultiplayer();
		}

		private static bool? PhotonIsMaster()
		{
			try
			{
				Type type = Type("Photon.Pun.PhotonNetwork") ?? Type("PhotonNetwork");
				if (type == null)
				{
					return null;
				}
				bool? flag = StaticBool(type, "IsMasterClient") ?? StaticBool(type, "isMasterClient");
				bool? flag2 = StaticBool(type, "InRoom") ?? StaticBool(type, "inRoom");
				if (flag2 == true && flag.HasValue)
				{
					return flag.Value;
				}
				if ((StaticBool(type, "OfflineMode") ?? StaticBool(type, "offlineMode")) == true)
				{
					return true;
				}
				return (flag2 == false) | flag;
			}
			catch (Exception)
			{
				return null;
			}
		}

		private static void LogRoleOnce(bool master)
		{
			if (_roleLogged)
			{
				return;
			}
			_roleLogged = true;
			try
			{
				Plugin.Log.LogInfo((object)(master ? "Co-op: this machine is the host. Shop items spawn here; others receive them." : "Co-op: this machine is a client. Shop spawn is skipped here so it does not desync."));
			}
			catch (Exception)
			{
			}
		}

		internal static void ResetRoleLog()
		{
			_roleLogged = false;
		}

		internal static bool IsMultiplayer()
		{
			try
			{
				Type type = Type("Photon.Pun.PhotonNetwork") ?? Type("PhotonNetwork");
				if (type != null)
				{
					bool? flag = StaticBool(type, "InRoom") ?? StaticBool(type, "inRoom");
					bool? flag2 = StaticBool(type, "OfflineMode") ?? StaticBool(type, "offlineMode");
					if (flag == true && flag2 != true)
					{
						return true;
					}
					object obj = GetStatic(type, "CountOfPlayersInRooms") ?? GetStatic(type, "CountOfPlayers");
					if (obj is int && (int)obj > 1)
					{
						return true;
					}
				}
			}
			catch (Exception)
			{
			}
			try
			{
				Type type2 = Type("SemiFunc") ?? Type("GameManager");
				MethodInfo methodInfo = ((type2 != null) ? type2.GetMethod("IsMultiplayer", BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) : null) ?? ((type2 != null) ? type2.GetMethod("Multiplayer", BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) : null);
				if (methodInfo != null)
				{
					return (bool)methodInfo.Invoke(null, null);
				}
			}
			catch (Exception)
			{
			}
			return false;
		}

		private static bool? StaticBool(Type t, string name)
		{
			object obj = GetStatic(t, name);
			if (obj is bool)
			{
				return (bool)obj;
			}
			return null;
		}

		internal static object PhotonLocalPlayer()
		{
			Type type = Type("Photon.Pun.PhotonNetwork") ?? Type("PhotonNetwork");
			object obj;
			if (!(type == null))
			{
				obj = GetStatic(type, "LocalPlayer");
				if (obj == null)
				{
					return GetStatic(type, "localPlayer");
				}
			}
			else
			{
				obj = null;
			}
			return obj;
		}

		internal static IEnumerable<object> PhotonPlayers()
		{
			Type type = Type("Photon.Pun.PhotonNetwork") ?? Type("PhotonNetwork");
			object obj = ((type == null) ? null : (GetStatic(type, "PlayerList") ?? GetStatic(type, "playerList")));
			IEnumerable enumerable = (IEnumerable)((obj is IEnumerable) ? obj : null);
			if (enumerable == null)
			{
				yield break;
			}
			IEnumerator enumerator = enumerable.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					object current = enumerator.Current;
					if (current != null)
					{
						yield return current;
					}
				}
			}
			finally
			{
				((IDisposable)((enumerator is IDisposable) ? enumerator : null))?.Dispose();
			}
		}

		internal static bool IsNotMaster()
		{
			return !IsMaster();
		}

		internal static bool PhotonInRoom()
		{
			Type type = Type("Photon.Pun.PhotonNetwork") ?? Type("PhotonNetwork");
			if (type == null)
			{
				return false;
			}
			try
			{
				if (!((GetStatic(type, "InRoom") ?? GetStatic(type, "inRoom")) is bool result))
				{
					object obj = GetStatic(type, "IsConnectedAndReady");
					bool flag = false;
					int num;
					if (obj is bool)
					{
						flag = (bool)obj;
						num = 1;
					}
					else
					{
						num = 0;
					}
					return (byte)(num & (flag ? 1 : 0)) != 0;
				}
				return result;
			}
			catch (Exception)
			{
				return false;
			}
		}

		internal static IList ListField(object obj, string name)
		{
			object obj2 = Read(obj, name);
			return (IList)((obj2 is IList) ? obj2 : null);
		}

		internal static IEnumerable<object> AllStatItems()
		{
			object stats = Instance("StatsManager");
			if (stats == null)
			{
				yield break;
			}
			DumpType(stats.GetType());
			Type itemType = Type("Item");
			HashSet<int> seen = new HashSet<int>();
			FieldInfo[] fields = stats.GetType().GetFields(BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			FieldInfo[] array = fields;
			foreach (FieldInfo fieldInfo in array)
			{
				object value;
				try
				{
					value = fieldInfo.GetValue(stats);
				}
				catch (Exception)
				{
					continue;
				}
				IDictionary dictionary = (IDictionary)((value is IDictionary) ? value : null);
				if (dictionary != null)
				{
					IDictionaryEnumerator enumerator = dictionary.GetEnumerator();
					try
					{
						while (enumerator.MoveNext())
						{
							object value2 = ((DictionaryEntry)enumerator.Current).Value;
							if (value2 != null && (!(itemType != null) || itemType.IsInstanceOfType(value2)) && seen.Add(value2.GetHashCode()))
							{
								yield return value2;
							}
						}
					}
					finally
					{
						((IDisposable)((enumerator is IDisposable) ? enumerator : null))?.Dispose();
					}
					continue;
				}
				IList list = (IList)((value is IList) ? value : null);
				if (list == null)
				{
					continue;
				}
				IEnumerator enumerator2 = list.GetEnumerator();
				try
				{
					while (enumerator2.MoveNext())
					{
						object current = enumerator2.Current;
						if (current != null && (!(itemType != null) || itemType.IsInstanceOfType(current)) && seen.Add(current.GetHashCode()))
						{
							yield return current;
						}
					}
				}
				finally
				{
					((IDisposable)((enumerator2 is IDisposable) ? enumerator2 : null))?.Dispose();
				}
			}
		}

		internal static GameObject PrefabObject(object item)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			if (item == null)
			{
				return null;
			}
			object member = GetMember(item, "prefab");
			return (GameObject)(((member is GameObject) ? member : null) ?? null);
		}

		internal static void SetEnum(object obj, string name, string value)
		{
			if (obj == null || string.IsNullOrEmpty(value))
			{
				return;
			}
			FieldInfo field = obj.GetType().GetField(name, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			if (field == null || !field.FieldType.IsEnum)
			{
				return;
			}
			try
			{
				field.SetValue(obj, Enum.Parse(field.FieldType, value, ignoreCase: true));
			}
			catch (Exception)
			{
			}
		}

		internal static IList NewItemList(object item)
		{
			Type type = Type("Item");
			if (type == null || item == null)
			{
				return null;
			}
			try
			{
				IList obj = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(type));
				obj.Add(item);
				return obj;
			}
			catch (Exception)
			{
				return null;
			}
		}

		internal static void SetField(object obj, string name, object value)
		{
			FieldInfo field = obj.GetType().GetField(name, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			if (field != null)
			{
				field.SetValue(obj, value);
			}
		}

		internal static void DumpType(Type t)
		{
			DumpOnce(t);
		}

		internal static int ReadInt(object obj, string name, int fallback = 0)
		{
			object obj2 = Read(obj, name);
			if (obj2 is int)
			{
				return (int)obj2;
			}
			if (obj2 is float)
			{
				return (int)(float)obj2;
			}
			return fallback;
		}

		internal static void RaiseInt(object obj, string name, int atLeast)
		{
			if (obj != null && atLeast > 0)
			{
				int num = ReadInt(obj, name);
				if (atLeast > num)
				{
					SetField(obj, name, atLeast);
				}
			}
		}

		internal static object[] FindAll(string typeName, bool includeInactive = false)
		{
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Expected O, but got Unknown
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Expected O, but got Unknown
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Expected O, but got Unknown
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Expected O, but got Unknown
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: 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)
			Type type = Type(typeName);
			if (type == null)
			{
				return Array.Empty<object>();
			}
			try
			{
				MethodInfo methodInfo = AccessTools.Method(typeof(Resources), "FindObjectsOfTypeAll", new Type[1] { typeof(Type) }, (Type[])null);
				if (methodInfo != null && methodInfo.Invoke(null, new object[1] { type }) is Array { Length: >0 } array)
				{
					List<object> list = new List<object>(array.Length);
					for (int i = 0; i < array.Length; i++)
					{
						object value = array.GetValue(i);
						if (value == null || (Object)((value is Object) ? value : null) == (Object)null)
						{
							continue;
						}
						try
						{
							Component val = (Component)((value is Component) ? value : null);
							if ((Object)val != (Object)null)
							{
								if ((int)((Object)val).hideFlags != 0 || ((Object)val.transform != (Object)null && val.transform.position.y < -500f))
								{
									continue;
								}
								Scene scene = val.gameObject.scene;
								if (!((Scene)(ref scene)).IsValid() || (((Scene)(ref scene)).name ?? "").IndexOf("DontDestroyOnLoad", StringComparison.OrdinalIgnoreCase) >= 0)
								{
									continue;
								}
							}
						}
						catch (Exception)
						{
						}
						list.Add(value);
					}
					if (list.Count > 0)
					{
						return list.ToArray();
					}
				}
			}
			catch (Exception)
			{
			}
			try
			{
				object[] array2 = InvokeFind(typeof(Object), "FindObjectsOfType", type, includeInactive: true);
				if (array2 != null && array2.Length != 0)
				{
					return array2;
				}
				return InvokeFind(typeof(Object), "FindObjectsOfType", type, includeInactive);
			}
			catch (Exception)
			{
				return Array.Empty<object>();
			}
		}

		private static object[] InvokeFind(Type host, string method, Type target, bool includeInactive = false)
		{
			MethodInfo[] methods = host.GetMethods(BindingFlags.Static | BindingFlags.Public);
			foreach (MethodInfo methodInfo in methods)
			{
				if (methodInfo.Name != method)
				{
					continue;
				}
				ParameterInfo[] parameters = methodInfo.GetParameters();
				object[] array = null;
				if (parameters.Length == 2 && parameters[0].ParameterType == typeof(Type) && parameters[1].ParameterType == typeof(bool))
				{
					array = new object[2] { target, includeInactive };
				}
				else if (!includeInactive && parameters.Length == 1 && parameters[0].ParameterType == typeof(Type))
				{
					array = new object[1] { target };
				}
				if (array != null)
				{
					object obj = methodInfo.Invoke(null, array);
					Array array2 = (Array)((obj is Array) ? obj : null);
					if (array2 != null && array2.Length > 0)
					{
						object[] array3 = new object[array2.Length];
						array2.CopyTo(array3, 0);
						return array3;
					}
				}
			}
			return Array.Empty<object>();
		}

		internal static object GetMember(object obj, string name)
		{
			return Read(obj, name);
		}

		internal static string ItemName(object item)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			object obj = Read(item, "itemName");
			object obj2 = ((obj is string) ? obj : null);
			if (obj2 == null)
			{
				object obj3 = Read(item, "name");
				obj2 = ((obj3 is string) ? obj3 : null);
				if (obj2 == null)
				{
					object obj4 = ((item is Object) ? item : null);
					obj2 = ((obj4 != null) ? ((Object)obj4).name : null) ?? item.ToString();
				}
			}
			return (string)obj2;
		}

		internal static string PrefabPath(object item)
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			DumpOnce(item.GetType());
			object obj = Read(item, "prefab");
			if (obj != null)
			{
				DumpOnce(obj.GetType());
				object obj2 = Read(obj, "resourcePath");
				string text = (string)(((obj2 is string) ? obj2 : null) ?? null);
				if (!string.IsNullOrEmpty(text))
				{
					return text;
				}
				GameObject val = (GameObject)(((obj is GameObject) ? obj : null) ?? null);
				if ((Object)(object)val != (Object)null)
				{
					return "Items/" + ((Object)val).name;
				}
			}
			return "Items/" + ItemName(item);
		}

		internal static string ItemVolume(object item)
		{
			return (Read(item, "itemVolume") ?? Read(item, "volume") ?? Read(item, "itemType"))?.ToString() ?? "Medium";
		}

		internal static int MaxInShop(object item)
		{
			if ((Read(item, "maxAmountInShop") ?? Read(item, "maxAmount") ?? Read(item, "maxPurchaseAmount")) is int val)
			{
				return Math.Max(1, val);
			}
			return 1;
		}

		internal static int AveragePrice(object item)
		{
			object obj = Read(item, "value") ?? Read(item, "valuePreset") ?? Read(item, "ValuePreset");
			if (obj != null)
			{
				DumpOnce(obj.GetType());
			}
			object obj2 = obj ?? item;
			int num = CoerceInt(Read(obj2, "valueMin") ?? Read(obj2, "min") ?? Read(obj2, "from") ?? Read(obj2, "x"));
			int num2 = CoerceInt(Read(obj2, "valueMax") ?? Read(obj2, "max") ?? Read(obj2, "to") ?? Read(obj2, "y"));
			if (num <= 0 && num2 <= 0)
			{
				num = CoerceInt(Read(obj2, "value"));
			}
			if (num <= 0)
			{
				num = 8000;
			}
			if (num2 <= 0)
			{
				num2 = num;
			}
			return Math.Max(1, (num + num2) / 2);
		}

		private static int CoerceInt(object v)
		{
			if (v is int)
			{
				return (int)v;
			}
			if (v is float)
			{
				return (int)(float)v;
			}
			if (v is double)
			{
				return (int)(double)v;
			}
			if (v is short)
			{
				return (short)v;
			}
			return 0;
		}

		private static object GetStatic(Type t, string name)
		{
			MemberInfo memberInfo = Resolve(t, name);
			try
			{
				FieldInfo fieldInfo = (FieldInfo)((memberInfo is FieldInfo) ? memberInfo : null);
				if (fieldInfo != null)
				{
					return fieldInfo.GetValue(null);
				}
				PropertyInfo propertyInfo = (PropertyInfo)((memberInfo is PropertyInfo) ? memberInfo : null);
				if (propertyInfo != null && propertyInfo.CanRead)
				{
					return propertyInfo.GetValue(null);
				}
			}
			catch (Exception)
			{
			}
			return null;
		}

		private static object Read(object obj, string name)
		{
			if (obj == null)
			{
				return null;
			}
			MemberInfo memberInfo = Resolve(obj.GetType(), name);
			try
			{
				FieldInfo fieldInfo = (FieldInfo)((memberInfo is FieldInfo) ? memberInfo : null);
				if (fieldInfo != null)
				{
					return fieldInfo.GetValue(obj);
				}
				PropertyInfo propertyInfo = (PropertyInfo)((memberInfo is PropertyInfo) ? memberInfo : null);
				if (propertyInfo != null && propertyInfo.CanRead)
				{
					return propertyInfo.GetValue(obj);
				}
			}
			catch (Exception)
			{
			}
			return null;
		}

		private static MemberInfo Resolve(Type t, string name)
		{
			(Type, string) tuple = default((Type, string));
			tuple = (t, name);
			MemberInfo value = null;
			if (Cache.TryGetValue(tuple, out value))
			{
				return value;
			}
			MemberInfo memberInfo = t.GetField(name, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			if (memberInfo == null)
			{
				memberInfo = t.GetProperty(name, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			}
			Cache[tuple] = memberInfo;
			return memberInfo;
		}

		private static void DumpOnce(Type t)
		{
			if (t == null || !Dumped.Add(t.FullName ?? t.Name))
			{
				return;
			}
			try
			{
				List<string> list = new List<string>();
				FieldInfo[] fields = t.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (FieldInfo fieldInfo in fields)
				{
					list.Add(fieldInfo.FieldType.Name + " " + fieldInfo.Name);
				}
				PropertyInfo[] properties = t.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (PropertyInfo propertyInfo in properties)
				{
					if (propertyInfo.GetIndexParameters().Length == 0)
					{
						list.Add(propertyInfo.PropertyType.Name + " " + propertyInfo.Name + "{get}");
					}
				}
				Plugin.Log.LogInfo((object)("[reflect] " + t.Name + ": " + ((list.Count == 0) ? "(no instance members)" : string.Join(", ", list))));
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[reflect] " + t.Name + " dump failed: " + ex.Message));
			}
		}
	}
	public enum HarmonyLane
	{
		Core = 0,
		Forge = 100,
		Content = 400,
		Override = 800
	}
	public enum ItemVolumeKind
	{
		Small,
		Medium,
		Large,
		Large_wide,
		Power_crystal,
		Large_high,
		Rubber_duck,
		Health_pack,
		Large_plus
	}
	public static class MyPluginInfo
	{
		public const string GUID = "com.repoforge.core";

		public const string Name = "REPOForge";

		public const string Version = "1.6.2";
	}
	[BepInPlugin("com.repoforge.core", "REPOForge", "1.6.34")]
	public sealed class Plugin : BaseUnityPlugin
	{
		[Serializable]
		private sealed class __c
		{
			public static readonly __c __9 = new __c();

			public static Action __9__28_0;

			public static Action __9__28_1;

			public static Action __9__28_2;

			public static Action __9__28_3;

			internal void Awake_b__28_0()
			{
				HarmonyArbiter.Install(Harmony);
			}

			internal void Awake_b__28_1()
			{
				PrefabRegistry.Install(Harmony);
			}

			internal void Awake_b__28_2()
			{
				ShopCoordinator.Install(Harmony);
			}

			internal void Awake_b__28_3()
			{
				DiscrepancyGuard.Install(Harmony);
			}
		}

		internal static ConfigEntry<bool> Enabled;

		internal static ConfigEntry<bool> Handshake;

		internal static ConfigEntry<bool> KickOnHardMismatch;

		internal static ConfigEntry<bool> PlaceholderMissingPrefabs;

		internal static ConfigEntry<bool> VerboseLogging;

		internal static ConfigEntry<bool> ShopPipeline;

		internal static ConfigEntry<bool> PriceWeight;

		internal static ConfigEntry<int> ExtraShelves;

		internal static ConfigEntry<int> ItemSpawnTargetAmount;

		internal static ConfigEntry<bool> FillEmptyVolumes;

		internal static ConfigEntry<bool> DiversifyPool;

		internal static ConfigEntry<bool> PreferModItems;

		internal static ConfigEntry<int> MaxVolumesConsidered;

		internal static ConfigEntry<int> MaxPlacementAttempts;

		internal static ConfigEntry<int> FillTimeBudgetMs;

		internal static ConfigEntry<bool> SoftSafeFill;

		internal static ConfigEntry<int> MaxCopiesPerItem;

		internal static ConfigEntry<bool> RemapSmallToMedium;

		internal static ConfigEntry<bool> AdoptUnlistedMods;

		internal static ConfigEntry<bool> RefreshLibrary;

		private static bool _deferredBootDone;

		private static bool _deferredBootScheduled;

		private static bool _deferredBootHooked;

		private static bool _deferredUpdateLogged;

		private static long _deferredBootStartTicks;

		private const double DeferredMinWaitSec = 1.0;

		private const double DeferredMaxWaitSec = 12.0;

		internal static Plugin Instance { get; private set; }

		internal static ManualLogSource Log { get; private set; }

		internal static Harmony Harmony { get; private set; }

		private void Awake()
		{
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Expected O, but got Unknown
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Expected O, but got Unknown
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Expected O, but got Unknown
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Expected O, but got Unknown
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Expected O, but got Unknown
			//IL_02af: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Expected O, but got Unknown
			//IL_03d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e3: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			Log.LogInfo((object)"REPOForge 1.6.34 waking.");
			Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master switch.");
			Handshake = ((BaseUnityPlugin)this).Config.Bind<bool>("Compat", "Handshake", false, "In co-op, compare loaded mods with other players and log a mismatch. Default OFF — avoids Photon hang when not connected.");
			KickOnHardMismatch = ((BaseUnityPlugin)this).Config.Bind<bool>("Compat", "KickOnHardMismatch", false, "Kick clients with hard mismatches. Default is warn-only.");
			PlaceholderMissingPrefabs = ((BaseUnityPlugin)this).Config.Bind<bool>("Compat", "PlaceholderMissingPrefabs", true, "Spawn a placeholder instead of crashing when a prefab is missing on a client.");
			VerboseLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Compat", "VerboseLogging", false, "Extra log lines for patches and shop rolls.");
			ShopPipeline = ((BaseUnityPlugin)this).Config.Bind<bool>("Shop", "Pipeline", true, "Intercept shop item lists and spawn through the host manifest.");
			PriceWeight = ((BaseUnityPlugin)this).Config.Bind<bool>("Shop", "UseShopPriceForItemSelection", false, "Reorder the pool so cheaper items spawn more often. Off by default — vanilla/MSI already weight by duplicate entries.");
			ExtraShelves = ((BaseUnityPlugin)this).Config.Bind<int>("Shop", "ExtraShelves", 0, new ConfigDescription("Unused. Kept so old configs still load.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 6), Array.Empty<object>()));
			ItemSpawnTargetAmount = ((BaseUnityPlugin)this).Config.Bind<int>("Shop", "ItemSpawnTargetAmount", 0, new ConfigDescription("Hard cap. Ignored while FillEmptyVolumes is on. 0 = do not override.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 256), Array.Empty<object>()));
			FillEmptyVolumes = ((BaseUnityPlugin)this).Config.Bind<bool>("Shop", "FillEmptyVolumes", true, "Raise spawn budgets to match empty shelf slots. SoftSafeFill HARD-SETS to ≤ MaxVolumesConsidered when NISL / huge volume counts.");
			DiversifyPool = ((BaseUnityPlugin)this).Config.Bind<bool>("Shop", "DiversifyPool", true, "Round-robin unique items so one type cannot fill every slot (e.g. only medium health packs).");
			PreferModItems = ((BaseUnityPlugin)this).Config.Bind<bool>("Shop", "PreferModItems", true, "Give non-vanilla (REPOLib / other mods) items a guaranteed shelf slot before vanilla repeats.");
			MaxVolumesConsidered = ((BaseUnityPlugin)this).Config.Bind<int>("Shop", "MaxVolumesConsidered", 96, new ConfigDescription("SoftSafeFill budget cap. 1.6.34: 96 dense shelves without 125-spawn start hitch. Range 8–128.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(8, 128), Array.Empty<object>()));
			MaxPlacementAttempts = ((BaseUnityPlugin)this).Config.Bind<int>("Shop", "MaxPlacementAttempts", 32, new ConfigDescription("Max remap tries per shop visit. 1.6.34: 32.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(8, 512), Array.Empty<object>()));
			FillTimeBudgetMs = ((BaseUnityPlugin)this).Config.Bind<int>("Shop", "FillTimeBudgetMs", 1200, new ConfigDescription("Remap wall-clock budget. Force-place is deferred 1/frame. 1.6.34: 1200.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(50, 8000), Array.Empty<object>()));
			SoftSafeFill = ((BaseUnityPlugin)this).Config.Bind<bool>("Shop", "SoftSafeFill", true, "When NoItemSpawnLimit is present or volume count exceeds MaxVolumesConsidered, HARD-SET spawn budgets to ≤ MaxVolumesConsidered (1.6.34: default cap 80 fills shelves without MEDVAC flood).");
			MaxCopiesPerItem = ((BaseUnityPlugin)this).Config.Bind<int>("Shop", "MaxCopiesPerItem", 2, new ConfigDescription("Max copies of one prefab on the shelves. 1 = all unique, 2 = at most a pair.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 16), Array.Empty<object>()));
			RemapSmallToMedium = ((BaseUnityPlugin)this).Config.Bind<bool>("Shop", "RemapSmallItemsOntoMediumVolumes", true, "If no unused item matches the shelf volume, place a different unused item instead of a duplicate.");
			AdoptUnlistedMods = ((BaseUnityPlugin)this).Config.Bind<bool>("Shop", "AdoptUnlistedMods", false, "Off: only items already in the shop roll (REPOLib RegisterItem / vanilla GetAll). On: also pull extra StatsManager items that look like shop gear (never valuables or secret attic loot).");
			RefreshLibrary = ((BaseUnityPlugin)this).Config.Bind<bool>("Compat", "RefreshLibrary", false, "On Start, scan BepInEx/plugins manifests and optionally fetch the Thunderstore R.E.P.O. package index. Default OFF — full catalog (+31585) froze lobby join.");
			if (AdoptUnlistedMods.Value)
			{
				Log.LogWarning((object)"Shop.AdoptUnlistedMods was on (1.2.0 stuffed level loot into the shop). Turning off. Future shop mods still appear via REPOLib RegisterItem.");
				AdoptUnlistedMods.Value = false;
			}
			if (FillEmptyVolumes.Value && ItemSpawnTargetAmount.Value > 0 && ItemSpawnTargetAmount.Value <= 28)
			{
				Log.LogWarning((object)$"Shop.ItemSpawnTargetAmount was {ItemSpawnTargetAmount.Value} (old cap). Ignored — FillEmptyVolumes fills every shelf. Set FillEmptyVolumes=false if you want a hard cap.");
				ItemSpawnTargetAmount.Value = 0;
			}
			if (MaxCopiesPerItem.Value >= 6)
			{
				Log.LogWarning((object)$"Shop.MaxCopiesPerItem was {MaxCopiesPerItem.Value} (old default). Reset to 2 so shelves are not walls of the same crystal/pan.");
				MaxCopiesPerItem.Value = 2;
			}
			Harmony = new Harmony("com.repoforge.core");
			if (!Enabled.Value)
			{
				Log.LogWarning((object)"REPOForge is disabled in config.");
				return;
			}
			Log.LogInfo((object)"REPOForge 1.6.34 config bound; Harmony patches deferred until after Steam/Photon auth (Lobby / ConnectedToMaster).");
			try
			{
				ScheduleDeferredBoot();
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("Deferred boot schedule from Awake failed: " + ex.Message));
			}
		}

		private void Start()
		{
			if (!Enabled.Value)
			{
				return;
			}
			try
			{
				try
				{
					string path = Path.Combine(Paths.ConfigPath, "com.repoforge.library.cache.json");
					if (File.Exists(path) && !RefreshLibrary.Value)
					{
						File.Delete(path);
						Log.LogInfo((object)"Deleted com.repoforge.library.cache.json (RefreshLibrary=false).");
					}
				}
				catch (Exception ex)
				{
					Log.LogDebug((object)("Cache cleanup: " + ex.Message));
				}
			}
			catch (Exception ex2)
			{
				Log.LogWarning((object)("Cache cleanup skipped: " + ex2.Message));
			}
			ScheduleDeferredBoot();
		}

		private static bool IsPastNetworkAuth()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (GameAccess.PhotonInRoom())
				{
					return true;
				}
			}
			catch (Exception)
			{
			}
			try
			{
				Scene activeScene = SceneManager.GetActiveScene();
				string name = ((Scene)(ref activeScene)).name;
				if (!string.IsNullOrEmpty(name) && (name.IndexOf("Lobby", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("Menu", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("Shop", StringComparison.OrdinalIgnoreCase) >= 0 || name.Equals("Main", StringComparison.OrdinalIgnoreCase)))
				{
					return true;
				}
			}
			catch (Exception)
			{
			}
			try
			{
				Type type = GameAccess.Type("Photon.Pun.PhotonNetwork") ?? GameAccess.Type("PhotonNetwork");
				if (type == null)
				{
					return false;
				}
				PropertyInfo propertyInfo = AccessTools.Property(type, "InRoom");
				if (propertyInfo != null)
				{
					object value = propertyInfo.GetValue(null, null);
					bool flag = false;
					int num;
					if (value is bool)
					{
						flag = (bool)value;
						num = 1;
					}
					else
					{
						num = 0;
					}
					if (((uint)num & (flag ? 1u : 0u)) != 0)
					{
						return true;
					}
				}
				PropertyInfo propertyInfo2 = AccessTools.Property(type, "CloudRegion");
				if (!string.IsNullOrEmpty(((propertyInfo2 != null) ? propertyInfo2.GetValue(null, null) : null) as string))
				{
					return true;
				}
				PropertyInfo propertyInfo3 = AccessTools.Property(type, "NetworkClientState");
				if (propertyInfo3 != null)
				{
					object value2 = propertyInfo3.GetValue(null, null);
					string text = ((value2 != null) ? value2.ToString() : "");
					if (!string.IsNullOrEmpty(text) && (text.IndexOf("ConnectedToMaster", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("JoinedLobby", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Joined", StringComparison.OrdinalIgnoreCase) >= 0))
					{
						return true;
					}
				}
			}
			catch (Exception)
			{
			}
			return false;
		}

		private static double DeferredElapsedSec()
		{
			return (double)(DateTime.UtcNow.Ticks - _deferredBootStartTicks) / 10000000.0;
		}

		private void ScheduleDeferredBoot()
		{
			if (!_deferredBootDone && Enabled.Value)
			{
				if (!_deferredBootScheduled)
				{
					_deferredBootScheduled = true;
					_deferredBootStartTicks = DateTime.UtcNow.Ticks;
					Log.LogInfo((object)"Deferred boot armed (Update + sceneLoaded; DateTime clock, no Unity Time).");
				}
				HookDeferredSceneLoaded();
				TryFinishDeferredBoot("schedule");
			}
		}

		private void HookDeferredSceneLoaded()
		{
			if (_deferredBootHooked)
			{
				return;
			}
			_deferredBootHooked = true;
			try
			{
				SceneManager.sceneLoaded += OnDeferredSceneLoaded;
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("sceneLoaded hook failed: " + ex.Message));
			}
		}

		private void OnDeferredSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			try
			{
				string text = ((Scene)(ref scene)).name ?? "";
				Log.LogInfo((object)("Deferred boot saw scene: " + text));
				TryFinishDeferredBoot("scene:" + text);
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("OnDeferredSceneLoaded: " + ex.Message));
			}
		}

		private void Update()
		{
			if (!_deferredBootScheduled || _deferredBootDone)
			{
				return;
			}
			if (!_deferredUpdateLogged)
			{
				_deferredUpdateLogged = true;
				try
				{
					Log.LogInfo((object)"Deferred boot Update() is running.");
				}
				catch (Exception)
				{
				}
			}
			TryFinishDeferredBoot("update");
		}

		private void TryFinishDeferredBoot(string reason)
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			if (_deferredBootDone || !_deferredBootScheduled || !Enabled.Value)
			{
				return;
			}
			double num = DeferredElapsedSec();
			if (num < 0.0)
			{
				num = 0.0;
			}
			bool flag = false;
			bool flag2 = false;
			try
			{
				flag = num >= 1.0 && IsPastNetworkAuth();
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("IsPastNetworkAuth threw: " + ex.Message));
			}
			if (!flag && num >= 3.0)
			{
				try
				{
					Scene activeScene = SceneManager.GetActiveScene();
					string text = ((Scene)(ref activeScene)).name ?? "";
					if (text.IndexOf("Main", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Lobby", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Shop", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Menu", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						flag = true;
					}
				}
				catch (Exception)
				{
				}
			}
			if (!flag && num >= 12.0)
			{
				flag2 = true;
				flag = true;
			}
			if (!flag)
			{
				return;
			}
			_deferredBootDone = true;
			try
			{
				if (_deferredBootHooked)
				{
					SceneManager.sceneLoaded -= OnDeferredSceneLoaded;
					_deferredBootHooked = false;
				}
			}
			catch (Exception)
			{
			}
			if (flag2)
			{
				Log.LogWarning((object)$"Deferred boot timed out after {num:0.0}s ({reason}) — applying patches anyway.");
			}
			else
			{
				Log.LogInfo((object)$"Past network auth after {num:0.0}s ({reason}) — applying deferred Harmony installs.");
			}
			try
			{
				ApplyDeferredInstalls();
			}
			catch (Exception ex4)
			{
				Log.LogError((object)("ApplyDeferredInstalls failed: " + ex4.ToString()));
			}
		}

		private void ApplyDeferredInstalls()
		{
			object obj = (Action)delegate
			{
				HarmonyArbiter.Install(Harmony);
			};
			SafeInstall("HarmonyArbiter", (Action)obj);
			object obj2 = (Action)delegate
			{
				PrefabRegistry.Install(Harmony);
			};
			SafeInstall("PrefabRegistry", (Action)obj2);
			object obj3 = (Action)delegate
			{
				ShopCoordinator.Install(Harmony);
			};
			SafeInstall("ShopCoordinator", (Action)obj3);
			object obj4 = (Action)delegate
			{
				DiscrepancyGuard.Install(Harmony);
			};
			SafeInstall("DiscrepancyGuard", (Action)obj4);
			try
			{
				ShopCartRescue.TryPatch(Harmony);
			}
			catch (Exception ex)
			{
				Log.LogDebug((object)("ShopCartRescue: " + ex.Message));
			}
			Log.LogInfo((object)"REPOForge 1.6.34 loaded (deferred). Duplicate copies of this GUID are skipped by BepInEx — keep one folder.");
			try
			{
				ModLibrary.Boot();
			}
			catch (Exception ex2)
			{
				Log.LogWarning((object)("Library boot skipped: " + ex2.Message));
			}
			try
			{
				DiscrepancyGuard.DiscoverLoadedPlugins();
			}
			catch (Exception ex3)
			{
				Log.LogWarning((object)("Auto-discover skipped: " + ex3.Message));
			}
			try
			{
				DiscrepancyGuard.BeginWatch((MonoBehaviour)(object)this);
			}
			catch (Exception ex4)
			{
				Log.LogWarning((object)("Handshake watch skipped: " + ex4.Message));
			}
		}

		private void OnDestroy()
		{
			Harmony harmony = Harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		private static void SafeInstall(string name, Action fn)
		{
			try
			{
				fn();
			}
			catch (Exception ex)
			{
				Log.LogError((object)(name + " install failed (continuing): " + ex.GetBaseException().Message));
			}
		}
	}
	public static class PluginBus
	{
		private static readonly Dictionary<Type, List<Delegate>> _subs = new Dictionary<Type, List<Delegate>>();

		public static void Subscribe<T>(Action<T> handler)
		{
			Type typeFromHandle = typeof(T);
			List<Delegate> value = null;
			if (!_subs.TryGetValue(typeFromHandle, out value))
			{
				value = new List<Delegate>();
				_subs[typeFromHandle] = value;
			}
			value.Add(handler);
		}

		public static void Unsubscribe<T>(Action<T> handler)
		{
			List<Delegate> value = null;
			if (_subs.TryGetValue(typeof(T), out value))
			{
				value.Remove(handler);
			}
		}

		public static void Publish<T>(T evt)
		{
			List<Delegate> value = null;
			if (evt == null || !_subs.TryGetValue(typeof(T), out value))
			{
				return;
			}
			Delegate[] array = value.ToArray();
			foreach (Delegate obj in array)
			{
				try
				{
					((Action<T>)obj)(evt);
				}
				catch (Exception arg)
				{
					Plugin.Log.LogError((object)$"Bus handler for {typeof(T).Name} threw: {arg}");
				}
			}
		}
	}
	public enum ShopCategoryKind
	{
		Items,
		Consumables,
		Upgrades,
		Health,
		Secret
	}
	public sealed class ShopIntent
	{
		public string ItemName { get; set; } = "";

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

		public float Weight { get; set; } = 10f;

		public int MaxInShop { get; set; } = 1;

		public ItemVolumeKind Volume { get; set; } = ItemVolumeKind.Medium;

		public ShopCategoryKind Category { get; set; }

		public int PriceMin { get; set; } = 4000;

		public int PriceMax { get; set; } = 8000;

		public object Item { get; set; }
	}
	public sealed class ShopReadyEvent
	{
		public string ManifestHash { get; set; } = "";

		public int Count { get; set; }

		public int Seed { get; set; }
	}
}
namespace REPOForge.Shop
{
	internal static class ShopCartRescue
	{
		private static bool _patched;

		private static bool _spawnedThisVisit;

		private static float _retryAt;

		private static int _retries;

		private static GameObject _liveCart;

		private static Vector3 _spawnAnchor;

		private static bool _haveSpawnAnchor;

		private static int _lastPopulateVolumes = -1;

		private static float _populateAt;

		private static string _lastLevelKey = "";

		private static readonly (string key, float x, float y, float z, float yaw)[] FixedShopSlots = new(string, float, float, float, float)[7]
		{
			("Dead Forest", 0.56f, 4.55f, 8.94f, 0f),
			("Shop Forest", 1.44f, 4.55f, 6.94f, 0f),
			("Harbor", -0.31f, 4.55f, 6.93f, 0f),
			("Suburb", -3.81f, 4.55f, 2.75f, 0f),
			("Wasteland", 0.57f, 4.55f, 7.19f, 0f),
			("Museum", 2.4f, 4.75f, 10.7f, 0f),
			("Arctic", 1.84f, 4.75f, 9.73f, 0f)
		};

		private static ManualLogSource Log => Plugin.Log;

		internal static void TryPatch(Harmony harmony)
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Expected O, but got Unknown
			if (_patched)
			{
				return;
			}
			try
			{
				Type type = AccessTools.TypeByName("ShopCartMod.ShopCartPlugin");
				if (type == null)
				{
					Log.LogDebug((object)"ShopCartRescue: ShopCart plugin type not found (mod absent).");
					return;
				}
				MethodInfo methodInfo = AccessTools.Method(type, "SpawnCart", (Type[])null, (Type[])null);
				MethodInfo methodInfo2 = AccessTools.Method(type, "Update", (Type[])null, (Type[])null);
				if (methodInfo != null)
				{
					harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(ShopCartRescue), "SpawnCartPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				if (methodInfo2 != null)
				{
					harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(typeof(ShopCartRescue), "UpdatePostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				_patched = true;
				Log.LogInfo((object)"ShopCartRescue 1.6.34: wait for vanilla cart row, allocate Photon ViewID.");
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("ShopCartRescue patch failed: " + ex.Message));
			}
		}

		internal static void OnShopPopulate(int activeVolumes)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			if (!(Time.unscaledTime - _populateAt < 8f))
			{
				string text = CurrentShopLevelName();
				if ((Object)_liveCart != (Object)null && string.Equals(text, _lastLevelKey, StringComparison.Ordinal) && _spawnedThisVisit)
				{
					_populateAt = Time.unscaledTime;
					return;
				}
				_lastPopulateVolumes = activeVolumes;
				_populateAt = Time.unscaledTime;
				Log.LogInfo((object)$"ShopCartRescue: new shop populate volumes={activeVolumes} level='{text}' — arm respawn");
				ClearLiveCart();
				_spawnedThisVisit = false;
				_retries = 0;
				_retryAt = Time.unscaledTime + 4f;
				_haveSpawnAnchor = false;
			}
		}

		private static void ClearLiveCart()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			if ((Object)_liveCart != (Object)null)
			{
				try
				{
					Object.Destroy((Object)(object)_liveCart);
				}
				catch
				{
				}
			}
			_liveCart = null;
		}

		private static bool SpawnCartPrefix()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			try
			{
				if (!SemiFunc.RunIsShop())
				{
					return false;
				}
			}
			catch
			{
				return false;
			}
			DetectBayChange();
			if (_spawnedThisVisit || (Object)_liveCart != (Object)null)
			{
				return false;
			}
			if (_retryAt <= 0f)
			{
				_retryAt = Time.unscaledTime + 4f;
				_retries = 0;
			}
			return false;
		}

		private static void DetectBayChange()
		{
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: 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_00c6: Expected O, but got Unknown
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Expected O, but got Unknown
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				string text = CurrentShopLevelName();
				if (!string.IsNullOrEmpty(text) && !string.IsNullOrEmpty(_lastLevelKey) && !string.Equals(text, _lastLevelKey, StringComparison.Ordinal) && Time.unscaledTime - _populateAt > 2f)
				{
					Log.LogInfo((object)("ShopCartRescue: shop level changed '" + _lastLevelKey + "' -> '" + text + "' — arm respawn"));
					ClearLiveCart();
					_spawnedThisVisit = false;
					_retries = 0;
					_retryAt = Time.unscaledTime + 2f;
					_haveSpawnAnchor = false;
				}
				if (!string.IsNullOrEmpty(text))
				{
					_lastLevelKey = text;
				}
				Vector3 val = Vector3.zero;
				bool flag = false;
				if ((Object)ShopManager.instance != (Object)null)
				{
					Transform extractionPoint = ShopManager.instance.extractionPoint;
					if ((Object)extractionPoint != (Object)null)
					{
						val = extractionPoint.position;
						flag = true;
					}
				}
				if (flag)
				{
					if (_haveSpawnAnchor && Vector3.Distance(val, _spawnAnchor) > 20f && Time.unscaledTime - _populateAt > 5f)
					{
						Log.LogInfo((object)$"ShopCartRescue: shop bay changed ({Vector3.Distance(val, _spawnAnchor):F1}m) — arm respawn");
						ClearLiveCart();
						_spawnedThisVisit = false;
						_retries = 0;
						_retryAt = Time.unscaledTime + 2f;
					}
					_spawnAnchor = val;
					_haveSpawnAnchor = true;
				}
			}
			catch
			{
			}
		}

		private static void UpdatePostfix()
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Expected O, but got Unknown
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Expected O, but got Unknown
			try
			{
				if (!SemiFunc.RunIsShop())
				{
					_spawnedThisVisit = false;
					ClearLiveCart();
					_retryAt = 0f;
					_retries = 0;
					_haveSpawnAnchor = false;
					_lastPopulateVolumes = -1;
					return;
				}
			}
			catch
			{
				return;
			}
			DetectBayChange();
			if (_spawnedThisVisit && (Object)_liveCart == (Object)null)
			{
				_spawnedThisVisit = false;
				_retryAt = Time.unscaledTime + 1f;
			}
			if (_spawnedThisVisit || (Object)_liveCart != (Object)null)
			{
				return;
			}
			if (_retryAt <= 0f)
			{
				_retryAt = Time.unscaledTime + 4f;
			}
			else
			{
				if (Time.unscaledTime < _retryAt)
				{
					return;
				}
				if (!((Object)ShopManager.instance != (Object)null) && _retries < 6)
				{
					_retries++;
					_retryAt = Time.unscaledTime + 0.8f;
					return;
				}
				if (TryLocalSpawn())
				{
					_spawnedThisVisit = true;
					_retryAt = 0f;
					_lastLevelKey = CurrentShopLevelName();
					return;
				}
				_retries++;
				if (_retries >= 12)
				{
					_spawnedThisVisit = true;
					_retryAt = 0f;
					Log.LogWarning((object)"ShopCartRescue: gave up this bay after retries.");
				}
				else
				{
					_retryAt = Time.unscaledTime + 1.2f;
				}
			}
		}

		private static bool TryLocalSpawn()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: 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_0094: Unknown result type (might be due to invalid IL or missing references)
			if (!SemiFunc.IsMasterClientOrSingleplayer())
			{
				return false;
			}
			List<GameObject> list = FindLiveCarts();
			if (list.Count > 0)
			{
				_liveCart = list[0];
				PullLiveCarts(list);
				return true;
			}
			GameObject val = FindTemplate();
			if ((Object)val == (Object)null)
			{
				Log.LogWarning((object)"ShopCartRescue: template not ready.");
				return false;
			}
			if (!ShopFloorPose(out var target, out var rot))
			{
				return false;
			}
			GameObject obj = Object.Instantiate<GameObject>(val, target, rot);
			((Object)obj).name = "SosoTeam Shop Cart (local)";
			((Object)obj).hideFlags = (HideFlags)0;
			obj.SetActive(true);
			AssignPhotonViewIDs(obj);
			ForceEnableVisuals(obj);
			PushOverlappingCartsOut(obj, target, rot);
			WakePhysics(obj, target);
			_liveCart = obj;
			Log.LogInfo((object)("ShopCartRescue: local cart at " + ((Vector3)(ref target)).ToString("F2") + " (per-map spawn, ViewID allocated)"));
			return true;
		}

		private static void AssignPhotonViewIDs(GameObject go)
		{
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Expected O, but got Unknown
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			Type type = AccessTools.TypeByName("Photon.Pun.PhotonNetwork") ?? AccessTools.TypeByName("PhotonNetwork");
			Type type2 = AccessTools.TypeByName("Photon.Pun.PhotonView") ?? AccessTools.TypeByName("PhotonView");
			if (type2 == null)
			{
				Log.LogWarning((object)"ShopCartRescue: PhotonView type missing.");
				return;
			}
			MethodInfo methodInfo = ((type != null) ? AccessTools.Method(type, "AllocateSceneViewID", new Type[1] { type2 }, (Type[])null) : null);
			MethodInfo methodInfo2 = ((type != null) ? AccessTools.Method(type, "AllocateRoomViewID", new Type[1] { type2 }, (Type[])null) : null);
			MethodInfo methodInfo3 = ((type != null) ? AccessTools.Method(type, "AllocateViewID", new Type[1] { type2 }, (Type[])null) : null);
			Component[] componentsInChildren = go.GetComponentsInChildren(type2, true);
			foreach (Component val in componentsInChildren)
			{
				if ((Object)val == (Object)null)
				{
					continue;
				}
				try
				{
					PropertyInfo property = type2.GetProperty("ViewID", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					int num = 0;
					if (property != null && property.CanRead)
					{
						num = (int)property.GetValue(val, null);
					}
					if (num == 0)
					{
						bool flag = false;
						if (methodInfo != null)
						{
							object obj = methodInfo.Invoke(null, new object[1] { val });
							flag = obj is bool && (bool)obj;
						}
						if (!flag && methodInfo2 != null)
						{
							object obj2 = methodInfo2.Invoke(null, new object[1] { val });
							flag = obj2 is bool && (bool)obj2;
						}
						if (!flag && methodInfo3 != null)
						{
							object obj3 = methodInfo3.Invoke(null, new object[1] { val });
							flag = obj3 is bool && (bool)obj3;
						}
						int num2 = num;
						if (property != null && property.CanRead)
						{
							num2 = (int)property.GetValue(val, null);
						}
						try
						{
							((Behaviour)val).enabled = true;
						}
						catch
						{
						}
						Log.LogInfo((object)$"ShopCartRescue: PhotonView allocate ok={flag} viewID={num2}");
					}
				}
				catch (Exception ex)
				{
					Log.LogWarning((object)("ShopCartRescue: AllocateViewID failed: " + ex.Message));
				}
			}
		}

		private static void ForceEnableVisuals(GameObject go)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			Transform val = go.transform.Find("SHOPPING C.A.R.T. Model");
			if ((Object)val != (Object)null && !((Component)val).gameObject.activeSelf)
			{
				((Component)val).gameObject.SetActive(true);
			}
			if (!go.activeSelf)
			{
				go.SetActive(true);
			}
			Renderer[] componentsInChildren = go.GetComponentsInChildren<Renderer>(true);
			int num = 0;
			int num2 = 0;
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				if (!((Object)componentsInChildren[i] == (Object)null))
				{
					if (!componentsInChildren[i].enabled)
					{
						componentsInChildren[i].enabled = true;
						num2++;
					}
					num++;
				}
			}
			Log.LogInfo((object)$"ShopCartRescue: visuals chrome={(Object)(object)val != (Object)null} renderers={num} enabledNow={num2}");
		}

		private static void WakePhysics(GameObject go, Vector3 target)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			Rigidbody[] componentsInChildren = go.GetComponentsInChildren<Rigidbody>(true);
			foreach (Rigidbody val in componentsInChildren)
			{
				if (!((Object)val == (Object)null))
				{
					val.constraints = (RigidbodyConstraints)0;
					val.isKinematic = false;
					val.detectCollisions = true;
					val.velocity = Vector3.zero;
					val.angularVelocity = Vector3.zero;
					val.position = target;
				}
			}
			Collider[] componentsInChildren2 = go.GetComponentsInChildren<Collider>(true);
			for (int j = 0; j < componentsInChildren2.Length; j++)
			{
				if ((Object)componentsInChildren2[j] != (Object)null)
				{
					componentsInChildren2[j].enabled = true;
				}
			}
		}

		private static GameObject FindTemplate()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Expected O, but got Unknown
			GameObject[] array = Resources.FindObjectsOfTypeAll<GameObject>();
			foreach (GameObject val in array)
			{
				if (!((Object)val == (Object)null))
				{
					string text = ((Object)val).name ?? "";
					if (text.IndexOf("SosoTeam Shop Cart", StringComparison.OrdinalIgnoreCase) >= 0 && !val.activeInHierarchy && text.IndexOf("(local)", StringComparison.OrdinalIgnoreCase) < 0)
					{
						return val;
					}
				}
			}
			MonoBehaviour[] array2 = Resources.FindObjectsOfTypeAll<MonoBehaviour>();
			foreach (MonoBehaviour val2 in array2)
			{
				if (!((Object)val2 == (Object)null) && !(((object)val2).GetType().Name != "ShopCartMarker"))
				{
					GameObject gameObject = ((Component)val2).gameObject;
					if (!((Object)gameObject == (Object)null) && !gameObject.activeInHierarchy)
					{
						return gameObject;
					}
				}
			}
			return null;
		}

		private static List<GameObject> FindLiveCarts()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			List<GameObject> list = new List<GameObject>();
			MonoBehaviour[] array = Resources.FindObjectsOfTypeAll<MonoBehaviour>();
			foreach (MonoBehaviour val in array)
			{
				if ((Object)val == (Object)null)
				{
					continue;
				}
				Type type = ((object)val).GetType();
				if (type == null)
				{
					continue;
				}
				string name = type.Name;
				if (name != "ShopCartMarker" && name != "PhysGrabCart")
				{
					continue;
				}
				GameObject gameObject = ((Component)val).gameObject;
				if ((Object)gameObject == (Object)null || !gameObject.activeInHierarchy)
				{
					continue;
				}
				string text = ((Object)gameObject).name ?? "";
				if (text.IndexOf("SosoTeam", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("SHOPPING C.A.R.T", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("(local)", StringComparison.OrdinalIgnoreCase) >= 0 || name == "ShopCartMarker")
				{
					Scene scene = gameObject.scene;
					if (((Scene)(ref scene)).IsValid() && !(gameObject.transform.position.y < -200f) && !list.Contains(gameObject))
					{
						list.Add(gameObject);
					}
				}
			}
			return list;
		}

		private static void PullLiveCarts(List<GameObject> carts)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: 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_0064: Unknown result type (might be due to invalid IL or missing references)
			if (!ShopFloorPose(out var target, out var rot) || carts == null || carts.Count == 0)
			{
				return;
			}
			GameObject val = carts[0];
			for (int i = 1; i < carts.Count; i++)
			{
				try
				{
					Object.Destroy((Object)(object)carts[i]);
				}
				catch
				{
				}
			}
			AssignPhotonViewIDs(val);
			ForceEnableVisuals(val);
			val.transform.SetPositionAndRotation(target, rot);
			PushOverlappingCartsOut(val, target, rot);
			WakePhysics(val, target);
			Log.LogInfo((object)("ShopCartRescue: pulled cart to " + ((Vector3)(ref target)).ToString("F2")));
		}

		private static string CurrentShopLevelName()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)RunManager.instance != (Object)null && (Object)RunManager.instance.levelCurrent != (Object)null)
				{
					string text = ((Object)RunManager.instance.levelCurrent).name ?? "";
					if (text.Length > 0)
					{
						return text;
					}
				}
			}
			catch
			{
			}
			try
			{
				Scene activeScene = SceneManager.GetActiveScene();
				string text2 = ((Scene)(ref activeScene)).name ?? "";
				if (text2.Length > 0 && text2.IndexOf("Shop", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return text2;
				}
			}
			catch
			{
			}
			return "";
		}

		private static bool ShopFloorPose(out Vector3 target, out Quaternion rot)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			target = Vector3.zero;
			rot = Quaternion.identity;
			try
			{
				string text = CurrentShopLevelName();
				if (TryPoseBesideShopMediums(out target, out rot, out var mediumY))
				{
					target.y = mediumY;
					Log.LogInfo((object)string.Format("ShopCartRescue: Medium-row slot {0} mediumY={1:F2} level={2}", ((Vector3)(ref target)).ToString("F2"), mediumY, text));
					return true;
				}
				if (_retries >= 8 && TryCheckoutPoseSameDeck(out target, out rot))
				{
					Log.LogInfo((object)("ShopCartRescue: checkout-same-deck " + ((Vector3)(ref target)).ToString("F2") + " level=" + text));
					return true;
				}
				return false;
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("ShopCartRescue: ShopFloorPose failed: " + ex.Message));
				return false;
			}
		}

		private static bool TryFixedShopSlot(string level, out Vector3 target, out Quaternion rot)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			target = Vector3.zero;
			rot = Quaternion.identity;
			if (string.IsNullOrEmpty(level))
			{
				return false;
			}
			for (int i = 0; i < FixedShopSlots.Length; i++)
			{
				(string, float, float, float, float) tuple = FixedShopSlots[i];
				if (level.IndexOf(tuple.Item1, StringComparison.OrdinalIgnoreCase) >= 0)
				{
					target = new Vector3(tuple.Item2, tuple.Item3, tuple.Item4);
					rot = Quaternion.Euler(0f, tuple.Item5, 0f);
					TryAlignYawToNearbyMedium(ref target, ref rot);
					return true;
				}
			}
			return false;
		}

		private static void TryAlignYawToNearbyMedium(ref Vector3 target, ref Quaternion rot)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Expected O, but got Unknown
			//IL_00d2: 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_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				PhysGrabCart[] array = Object.FindObjectsOfType<PhysGrabCart>();
				PhysGrabCart val = null;
				float num = 6f;
				foreach (PhysGrabCart val2 in array)
				{
					if ((Object)val2 == (Object)null || val2.isSmallCart)
					{
						continue;
					}
					GameObject gameObject = ((Component)val2).gameObject;
					if ((Object)gameObject == (Object)null || !gameObject.activeInHierarchy)
					{
						continue;
					}
					string text = ((Object)gameObject).name ?? "";
					if (text.IndexOf("SosoTeam", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("(local)", StringComparison.OrdinalIgnoreCase) < 0)
					{
						float num2 = Vector3.Distance(gameObject.transform.position, target);
						if (num2 < num)
						{
							num = num2;
							val = val2;
						}
					}
				}
				if ((Object)val != (Object)null)
				{
					Transform transform = ((Component)val).transform;
					target = transform.position + transform.right * 2.4f;
					rot = transform.rotation;
				}
			}
			catch
			{
			}
		}

		private static bool TryCheckoutPose(out Vector3 target, out Quaternion rot)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: 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_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: 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_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			target = Vector3.zero;
			rot = Quaternion.identity;
			if ((Object)ShopManager.instance == (Object)null)
			{
				return false;
			}
			Transform extractionPoint = ShopManager.instance.extractionPoint;
			if ((Object)extractionPoint == (Object)null)
			{
				return false;
			}
			target = extractionPoint.position - extractionPoint.forward * 3.2f + extractionPoint.right * 2.4f + Vector3.up * 1.2f;
			rot = Quaternion.Euler(0f, extractionPoint.eulerAngles.y + 180f, 0f);
			return true;
		}

		private static bool TryPoseBesideShopMediums(out Vector3 target, out Quaternion rot, out float mediumY)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected O, but got Unknown
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Expected O, but got Unknown
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Expected O, but got Unknown
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0301: Unknown result type (might be due to invalid IL or missing references)
			//IL_0306: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0370: Unknown result type (might be due to invalid IL or missing references)
			//IL_037e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0383: Unknown result type (might be due to invalid IL or missing references)
			//IL_038a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0391: Unknown result type (might be due to invalid IL or missing references)
			//IL_039b: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_032e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0333: Unknown result type (might be due to invalid IL or missing references)
			//IL_040a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0406: Unknown result type (might be due to invalid IL or missing references)
			//IL_040c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0425: Unknown result type (might be due to invalid IL or missing references)
			//IL_042b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0447: Unknown result type (might be due to invalid IL or missing references)
			//IL_0443: Unknown result type (might be due to invalid IL or missing references)
			//IL_0449: Unknown result type (might be due to invalid IL or missing references)
			//IL_044d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0452: Unknown result type (might be due to invalid IL or missing references)
			//IL_0490: Unknown result type (might be due to invalid IL or missing references)
			//IL_0497: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0461: Unknown result type (might be due to invalid IL or missing references)
			//IL_0463: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f6: Unknown result type (might be due to invalid IL or missing references)
			target = Vector3.zero;
			rot = Quaternion.identity;
			mediumY = 0f;
			List<PhysGrabCart> list = new List<PhysGrabCart>();
			PhysGrabCart[] array = Object.FindObjectsOfType<PhysGrabCart>();
			Vector3 val = Vector3.zero;
			bool flag = false;
			try
			{
				if ((Object)ShopManager.instance != (Object)null && (Object)ShopManager.instance.extractionPoint != (Object)null)
				{
					val = ShopManager.instance.extractionPoint.position;
					flag = true;
				}
			}
			catch
			{
			}
			foreach (PhysGrabCart val2 in array)
			{
				if ((Object)val2 == (Object)null)
				{
					continue;
				}
				GameObject gameObject = ((Component)val2).gameObject;
				if ((Object)gameObject == (Object)null || !gameObject.activeInHierarchy)
				{
					continue;
				}
				string text = ((Object)gameObject).name ?? "";
				if (text.IndexOf("SosoTeam", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("(local)", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("SHOPPING C.A.R.T", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					continue;
				}
				bool flag2 = false;
				MonoBehaviour[] components = gameObject.GetComponents<MonoBehaviour>();
				for (int j = 0; j < components.Length; j++)
				{
					if ((Object)components[j] != (Object)null && ((object)components[j]).GetType().Name == "ShopCartMarker")
					{
						flag2 = true;
						break;
					}
				}
				if (!flag2 && !val2.isSmallCart)
				{
					list.Add(val2);
				}
			}
			if (list.Count == 0)
			{
				return false;
			}
			float num = float.MaxValue;
			for (int k = 0; k < list.Count; k++)
			{
				float y = ((Component)list[k]).transform.position.y;
				if (y < num)
				{
					num = y;
				}
			}
			List<PhysGrabCart> list2 = new List<PhysGrabCart>();
			for (int l = 0; l < list.Count; l++)
			{
				if (((Component)list[l]).transform.position.y <= num + 0.75f)
				{
					list2.Add(list[l]);
				}
			}
			if (list2.Count == 0)
			{
				list2 = list;
			}
			PhysGrabCart val3 = list2[0];
			if (flag)
			{
				float num2 = float.MaxValue;
				for (int m = 0; m < list2.Count; m++)
				{
					Vector3 position = ((Component)list2[m]).transform.position;
					float num3 = position.x - val.x;
					float num4 = position.z - val.z;
					float num5 = num3 * num3 + num4 * num4;
					if (num5 < num2)
					{
						num2 = num5;
						val3 = list2[m];
					}
				}
			}
			List<PhysGrabCart> list3 = new List<PhysGrabCart>();
			Vector3 position2 = ((Component)val3).transform.position;
			for (int n = 0; n < list2.Count; n++)
			{
				if (Vector3.Distance(((Component)list2[n]).transform.position, position2) <= 8f)
				{
					list3.Add(list2[n]);
				}
			}
			Transform transform = ((Component)val3).transform;
			Vector3 right = transform.right;
			right.y = 0f;
			if (((Vector3)(ref right)).sqrMagnitude < 0.01f)
			{
				right = Vector3.right;
			}
			((Vector3)(ref right)).Normalize();
			list3.Sort(delegate(PhysGrabCart a, PhysGrabCart b)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				float num8 = Vector3.Dot(((Component)a).transform.position, right);
				float value = Vector3.Dot(((Component)b).transform.position, right);
				return num8.CompareTo(value);
			});
			Transform transform2 = ((Component)list3[list3.Count - 1]).transform;
			mediumY = transform2.position.y;
			rot = transform2.rotation;
			Vector3 val4 = transform2.position + transform2.right * 2.4f;
			Vector3 val5 = transform2.position - transform2.right * 2.4f;
			val4.y = mediumY;
			val5.y = mediumY;
			int num6 = CountCartsNear(val4, 1.4f, null);
			int num7 = CountCartsNear(val5, 1.4f, null);
			bool flag3 = num6 <= num7;
			target = (flag3 ? val4 : val5);
			string text2 = (flag3 ? "+right" : "-right");
			if (SlotBlockedByStatics(transform2.position, target, 1.55f))
			{
				Vector3 val6 = (flag3 ? val5 : val4);
				if (!SlotBlockedByStatics(transform2.position, val6, 1.55f))
				{
					target = val6;
					text2 = (flag3 ? "-right(clearance)" : "+right(clearance)");
					Log.LogInfo((object)"ShopCartRescue: default slot blocked — switched side");
				}
				else
				{
					Vector3 val7 = transform2.position - transform2.forward * 1.25f + (flag3 ? transform2.right : (-transform2.right)) * 2.4f;
					val7.y = mediumY;
					if (!SlotBlockedByStatics(transform2.position, val7, 1.55f))
					{
						target = val7;
						text2 = "nudge-back(clearance)";
						Log.LogInfo((object)"ShopCartRescue: both sides blocked — nudged back from Medium");
					}
					else
					{
						Log.LogInfo((object)"ShopCartRescue: clearance failed — keeping default slot");
					}
				}
			}
			Log.LogInfo((object)$"ShopCartRescue: Medium cluster={list3.Count}/{list.Count} floorMinY={num:F2} end={((Object)transform2).name} endY={mediumY:F2} side={text2} clearR={num6} clearL={num7}");
			return true;
		}

		private static bool SlotBlockedByStatics(Vector3 mediumPos, Vector3 slot, float minOutwardClear)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: 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_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: 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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = slot - mediumPos;
			val.y = 0f;
			float magnitude = ((Vector3)(ref val)).magnitude;
			if (magnitude < 0.05f)
			{
				return false;
			}
			Vector3 val2 = val / magnitude;
			RaycastHit val3 = default(RaycastHit);
			if (Physics.Raycast(mediumPos + Vector3.up * 0.55f, val2, ref val3, magnitude + 0.4f, -5, (QueryTriggerInteraction)1) && !IsCartCollider(((RaycastHit)(ref val3)).collider) && ((RaycastHit)(ref val3)).distance < magnitude + 0.25f)
			{
				return true;
			}
			if (Physics.Raycast(slot + Vector3.up * 0.55f, val2, ref val3, minOutwardClear, -5, (QueryTriggerInteraction)1) && !IsCartCollider(((RaycastHit)(ref val3)).collider))
			{
				return true;
			}
			return false;
		}

		private static bool IsCartCollider(Collider col)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			if ((Object)col == (Object)null)
			{
				return false;
			}
			try
			{
				if ((Object)((Component)col).GetComponentInParent<PhysGrabCart>() != (Object)null)
				{
					return true;
				}
			}
			catch
			{
			}
			return false;
		}

		private static int CountCartsNear(Vector3 pos, float radius, GameObject ignore)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: 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)
			int num = 0;
			PhysGrabCart[] array = Object.FindObjectsOfType<PhysGrabCart>();
			float num2 = radius * radius;
			foreach (PhysGrabCart val in array)
			{
				if ((Object)val == (Object)null)
				{
					continue;
				}
				GameObject gameObject = ((Component)val).gameObject;
				if (!((Object)gameObject == (Object)null) && gameObject.activeInHierarchy && (!((Object)ignore != (Object)null) || !((Object)(object)gameObject == (Object)(object)ignore)) && !((Object)(object)((Component)val).GetComponent("ShopCartMarker") != (Object)null))
				{
					Vector3 val2 = gameObject.transform.position - pos;
					if (((Vector3)(ref val2)).sqrMagnitude <= num2)
					{
						num++;
					}
				}
			}
			return num;
		}

		private static void PushOverlappingCartsOut(GameObject chrome, Vector3 chromePos, Quaternion chromeRot)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected O, but got Unknown
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: 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_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Expected O, but got Unknown
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: 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_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)chrome == (Object)null)
			{
				return;
			}
			Vector3 val = chromeRot * Vector3.right;
			val.y = 0f;
			if (((Vector3)(ref val)).sqrMagnitude < 0.01f)
			{
				val = Vector3.right;
			}
			((Vector3)(ref val)).Normalize();
			PhysGrabCart[] array = Object.FindObjectsOfType<PhysGrabCart>();
			int num = 0;
			foreach (PhysGrabCart val2 in array)
			{
				if ((Object)val2 == (Object)null)
				{
					continue;
				}
				GameObject gameObject = ((Component)val2).gameObject;
				if ((Object)gameObject == (Object)null || (Object)(object)gameObject == (Object)(object)chrome || !gameObject.activeInHierarchy || (Object)(object)((Component)val2).GetComponent("ShopCartMarker") != (Object)null || !val2.isSmallCart)
				{
					continue;
				}
				Vector3 position = gameObject.transform.position;
				Vector3 val3 = position - chromePos;
				val3.y = 0f;
				if (!(((Vector3)(ref val3)).sqrMagnitude > 4.84f))
				{
					Vector3 val4 = chromePos + val * 3.2f;
					Vector3 val5 = val4 - chromePos;
					if (((Vector3)(ref val5)).sqrMagnitude < 0.5f)
					{
						val4 = chromePos - val * 3.2f;
					}
					val4.y = position.y;
					gameObject.transform.position = val4;
					Rigidbody component = gameObject.GetComponent<Rigidbody>();
					if ((Object)component != (Object)null)
					{
						component.velocity = Vector3.zero;
						component.angularVelocity = Vector3.zero;
						component.position = val4;
					}
					num++;
					Log.LogInfo((object)("ShopCartRescue: pushed overlapping '" + ((Object)gameObject).name + "' out to " + ((Vector3)(ref val4)).ToString("F2")));
				}
			}
			if (num > 0)
			{
				Log.LogInfo((object)$"ShopCartRescue: cleared {num} cart(s) from inside chrome");
			}
		}

		private static bool TryCheckoutPoseSameDeck(out Vector3 target, out Quaternion rot)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: 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_007d: 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_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			target = Vector3.zero;
			rot = Quaternion.identity;
			if ((Object)ShopManager.instance == (Object)null)
			{
				return false;
			}
			Transform extractionPoint = ShopManager.instance.extractionPoint;
			if ((Object)extractionPoint == (Object)null)
			{
				return false;
			}
			target = extractionPoint.position - extractionPoint.forward * 3.2f + extractionPoint.right * 2.4f;
			target.y = extractionPoint.position.y;
			rot = Quaternion.Euler(0f, extractionPoint.eulerAngles.y + 180f, 0f);
			return true;
		}

		private static void SnapToFloor(ref Vector3 target)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			RaycastHit val = default(RaycastHit);
			if (Physics.Raycast(target + Vector3.up * 0.8f, Vector3.down, ref val, 2.5f))
			{
				target.y = ((RaycastHit)(ref val)).point.y + 0.35f;
			}
		}
	}
	internal static class ShopCoordinator
	{
		private sealed class Group
		{
			internal string Path = "";

			internal string Name = "";

			internal object Item;

			internal int Count;

			internal bool Mod;
		}

		private sealed class __c__DisplayClass14_0
		{
			public ShopIntent intent;

			internal bool Register_b__0(ShopIntent i)
			{
				return i.ItemName == intent.ItemName;
			}
		}

		private sealed class __c__DisplayClass15_0
		{
			public string itemName;

			internal bool Unregister_b__0(ShopIntent i)
			{
				return i.ItemName == itemName;
			}
		}

		private static readonly List<ShopIntent> _intents = new List<ShopIntent>();

		private static readonly List<object> _reservedMods = new List<object>();

		private static readonly HashSet<string> _placedThisVisit = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		private static readonly object _gate = new object();

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

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

		private static readonly HashSet<string> _usedSlots = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		private static string _lastAttempt;

		private static int _placementAttempts;

		private static bool _fillBudgetWarned;

		private static bool _safeFillActive;

		private static readonly Stopwatch _fillWatch = new Stopwatch();

		private static bool _forceOnePerTick;

		private static bool _forceArmed;

		private static int _forceTickPlaced;

		private static Stopwatch _forceTickWatch;

		private static readonly HashSet<string> _incompatTried = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		private static List<GameObject> _cloneIndex;

		private static int _cloneIndexFrame = -1;

		internal static string LastHash { get; private set; }

		private static void SpawnLog(string msg)
		{
			if (Plugin.VerboseLogging != null && Plugin.VerboseLogging.Value)
			{
				Plugin.Log.LogDebug((object)("[spawn] " + msg));
			}
		}

		private static void BeginFillSession()
		{
			_placementAttempts = 0;
			_fillBudgetWarned = false;
			_safeFillActive = false;
			_incompatTried.Clear();
			_fillWatch.Reset();
			_fillWatch.Start();
		}

		private static bool DetectNoItemSpawnLimit()
		{
			try
			{
				foreach (PluginInfo value in Chainloader.PluginInfos.Values)
				{
					if (((value != null) ? value.Metadata : null) != null)
					{
						string text = value.Metadata.GUID ?? "";
						string text2 = value.Metadata.Name ?? "";
						if (text.IndexOf("NoItemSpawnLimit", StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf("NoItemSpawnLimit", StringComparison.OrdinalIgnoreCase) >= 0)
						{
							return true;
						}
					}
				}
			}
			catch
			{
			}
			return false;
		}

		private static bool PlacementBudgetOk(string where)
		{
			int num = Plugin.MaxPlacementAttempts?.Value ?? 80;
			int num2 = Plugin.FillTimeBudgetMs?.Value ?? 400;
			if (_placementAttempts >= num || (_fillWatch.IsRunning && _fillWatch.ElapsedMilliseconds > num2))
			{
				if (!_fillBudgetWarned)
				{
					_fillBudgetWarned = true;
					Plugin.Log.LogWarning((object)$"Shop fill budget hit at {where}: attempts={_placementAttempts}/{num} elapsedMs={_fillWatch.ElapsedMilliseconds}/{num2} safeFill={_safeFillActive}. Skipping further remaps/placements this visit.");
				}
				return false;
			}
			return true;
		}

		internal static void Install(Harmony harmony)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Expected O, but got Unknown
			//IL_011a: Expected O, but got Unknown
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Expected O, but got Unknown
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Expected O, but got Unknown
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Expected O, but got Unknown
			Type type = GameAccess.Type("ShopManager");
			MethodInfo methodInfo = AccessTools.Method(type, "GetAllItemsFromStatsManager", (Type[])null, (Type[])null);
			if (methodInfo != null)
			{
				harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(ShopCoordinator), "GetAllPostfix", (Type[])null)
				{
					priority = 0
				}, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				Plugin.Log.LogInfo((object)"Patched ShopManager.GetAllItemsFromStatsManager (postfix last).");
			}
			else
			{
				Plugin.Log.LogWarning((object)"ShopManager.GetAllItemsFromStatsManager not found.");
			}
			Type type2 = GameAccess.Type("PunManager");
			MethodInfo methodInfo2 = AccessTools.Method(type2, "SpawnShopItem", (Type[])null, (Type[])null);
			if (methodInfo2 != null)
			{
				ParameterInfo[] parameters = methodInfo2.GetParameters();
				Plugin.Log.LogInfo((object)("Patched PunManager.SpawnShopItem (" + string.Join(", ", Array.ConvertAll(parameters, (ParameterInfo p) => p.ParameterType.Name + " " + p.Name)) + ")."));
				harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(ShopCoordinator), "SpawnPrefix", (Type[])null)
				{
					priority = 100
				}, new HarmonyMethod(typeof(ShopCoordinator), "SpawnPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			else
			{
				Plugin.Log.LogWarning((object)"PunManager.SpawnShopItem not found — volume matching still runs via GetAll postfix.");
			}
			MethodInfo methodInfo3 = AccessTools.Method(type2, "ShopPopulateItemVolumes", (Type[])null, (Type[])null);
			if (methodInfo3 != null)
			{
				harmony.Patch((MethodBase)methodInfo3, new HarmonyMethod(typeof(ShopCoordinator), "PopulatePrefix", (Type[])null)
				{
					priority = 800
				}, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				harmony.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, new HarmonyMethod(typeof(ShopCoordinator), "PopulatePostfix", (Type[])null)
				{
					priority = 0
				}, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo4 = AccessTools.Method(type, "GetAllItemVolumesInScene", (Type[])null, (Type[])null);
			if (methodInfo4 != null)
			{
				harmony.Patch((MethodBase)methodInfo4, (HarmonyMethod)null, new HarmonyMethod(typeof(ShopCoordinator), "VolumesPostfix", (Type[])null)
				{
					priority = 0
				}, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
		}

		internal static void Register(ShopIntent intent)
		{
			__c__DisplayClass14_0 CS__8__locals10 = new __c__DisplayClass14_0();
			CS__8__locals10.intent = intent;
			if (CS__8__locals10.intent == null || string.IsNullOrEmpty(CS__8__locals10.intent.ItemName))
			{
				return;
			}
			lock (_gate)
			{
				_intents.RemoveAll((ShopIntent i) => i.ItemName == CS__8__locals10.intent.ItemName);
				_intents.Add(CS__8__locals10.intent);
				if (CS__8__locals10.intent.Item != null)
				{
					GameAccess.SetEnum(CS__8__locals10.intent.Item, "itemVolume", CS__8__locals10.intent.Volume.ToString());
				}
			}
			if (Plugin.VerboseLogging.Value)
			{
				Plugin.Log.LogInfo((object)("Shop intent registered: " + CS__8__locals10.intent.ItemName + " (" + CS__8__locals10.intent.PrefabPath + ")"));
			}
		}

		internal static void Unregister(string itemName)
		{
			__c__DisplayClass15_0 CS__8__locals2 = new __c__DisplayClass15_0();
			CS__8__locals2.itemName = itemName;
			lock (_gate)
			{
				_intents.RemoveAll((ShopIntent i) => i.ItemName == CS__8__locals2.itemName);
			}
		}

		private static void GetAllPostfix(object __instance)
		{
			if (!Plugin.Enabled.Value || !Plugin.ShopPipeline.Value)
			{
				return;
			}
			if (GameAccess.IsNotMaster())
			{
				Plugin.Log.LogInfo((object)"Shop mix skipped — client. Host fills the shelves; you receive them.");
				return;
			}
			try
			{
				_spawned.Clear();
				_reservedMods.Clear();
				_placedThisVisit.Clear();
				_homeVol.Clear();
				_usedSlots.Clear();
				BeginFillSession();
				StripSelfSpawnFromPools(__instance);
				ReconcileLists(__instance);
				StripSelfSpawnFromPools(__instance);
				string text = (LastHash = ComputeHash(__instance));
				int count = CountItems(__instance);
				PluginBus.Publish(new ShopReadyEvent
				{
					ManifestHash = text,
					Count = count,
					Seed = Environment.TickCount
				});
				int num = GameAccess.ListField(__instance, "potentialItems")?.Count ?? 0;
				int num2 = GameAccess.ListField(__instance, "potentialItemConsumables")?.Count ?? 0;
				int num3 = GameAccess.ListField(__instance, "potentialItemUpgrades")?.Count ?? 0;
				int num4 = GameAccess.ListField(__instance, "potentialItemHealthPacks")?.Count ?? 0;
				object member = GameAccess.GetMember(__instance, "itemSpawnTargetAmo