Decompiled source of MODMENU v0.1.0

BepInEx/plugins/MODMENU/SupermarketTogetherMODMENU.dll

Decompiled 4 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mirror;
using Rewired;
using StarterAssets;
using SupermarketTogetherAnyPlaceBuilder;
using SupermarketTogetherFlyMod;
using SupermarketTogetherMovementSpeedMenu;
using SupermarketTogetherObjectManipulator;
using SupermarketTogetherObjectSpawner;
using SupermarketTogetherTeleportMenu;
using UnityEngine;
using UnityEngine.AI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("SupermarketTogetherMODMENU")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("SupermarketTogetherMODMENU")]
[assembly: AssemblyTitle("SupermarketTogetherMODMENU")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[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 SupermarketTogetherObjectManipulator
{
	internal sealed class ObjectManipulatorMenu : MonoBehaviour
	{
		private enum PendingKeyBinding
		{
			None,
			Duplicate,
			Delete
		}

		private const float SpawnDistance = 3.5f;

		private const float DefaultObjectGrabReach = 4f;

		private const float ButtonHeight = 28f;

		private ManualLogSource? logger;

		private ObjectManipulatorSettings? settings;

		private PendingKeyBinding pendingKeyBinding;

		private string statusMessage = "Ready.";

		public void Initialize(ManualLogSource pluginLogger, ObjectManipulatorSettings manipulatorSettings)
		{
			logger = pluginLogger;
			settings = manipulatorSettings;
		}

		internal void ShowPanel()
		{
			pendingKeyBinding = PendingKeyBinding.None;
		}

		internal void HidePanel()
		{
			pendingKeyBinding = PendingKeyBinding.None;
		}

		private void Update()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			if (settings != null && settings.Enabled.Value && pendingKeyBinding == PendingKeyBinding.None)
			{
				if (Input.GetKeyDown(settings.DuplicateHeldItemKey.Value))
				{
					DuplicateHeldItem();
				}
				if (Input.GetKeyDown(settings.DeleteObjectKey.Value))
				{
					DeleteLookTarget();
				}
			}
		}

		internal void DrawPanelContent()
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			CapturePendingKey(Event.current);
			if (settings != null)
			{
				GUILayout.Space(8f);
				GUILayout.BeginVertical(GUI.skin.box, Array.Empty<GUILayoutOption>());
				GUILayout.Label("現在のキー", Array.Empty<GUILayoutOption>());
				GUILayout.Label($"Copy held item: {settings.DuplicateHeldItemKey.Value}", Array.Empty<GUILayoutOption>());
				GUILayout.Label($"Delete look target: {settings.DeleteObjectKey.Value}", Array.Empty<GUILayoutOption>());
				GUILayout.EndVertical();
				GUILayout.Space(10f);
				GUILayout.BeginVertical(GUI.skin.box, Array.Empty<GUILayoutOption>());
				GUILayout.Label("キー設定", Array.Empty<GUILayoutOption>());
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				if (GUILayout.Button(GetBindingButtonLabel(PendingKeyBinding.Duplicate), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) }))
				{
					pendingKeyBinding = PendingKeyBinding.Duplicate;
					statusMessage = "Press a key for copy. Escape cancels.";
				}
				if (GUILayout.Button(GetBindingButtonLabel(PendingKeyBinding.Delete), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) }))
				{
					pendingKeyBinding = PendingKeyBinding.Delete;
					statusMessage = "Press a key for delete. Escape cancels.";
				}
				GUILayout.EndHorizontal();
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				if (GUILayout.Button("Reset V / B", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) }))
				{
					settings.DuplicateHeldItemKey.Value = (KeyCode)118;
					settings.DeleteObjectKey.Value = (KeyCode)98;
					((ConfigEntryBase)settings.DuplicateHeldItemKey).ConfigFile.Save();
					statusMessage = "Reset copy to V and delete to B.";
				}
				GUILayout.EndHorizontal();
				GUILayout.EndVertical();
				GUILayout.Space(8f);
				GUILayout.BeginVertical(GUI.skin.box, Array.Empty<GUILayoutOption>());
				GUILayout.Label(statusMessage, Array.Empty<GUILayoutOption>());
				GUILayout.EndVertical();
			}
		}

		private string GetBindingButtonLabel(PendingKeyBinding binding)
		{
			if (pendingKeyBinding != binding)
			{
				if (binding != PendingKeyBinding.Duplicate)
				{
					return "Change Delete Key";
				}
				return "Change Copy Key";
			}
			return "Press key...";
		}

		private void CapturePendingKey(Event currentEvent)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Invalid comparison between Unknown and I4
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Invalid comparison between Unknown and I4
			//IL_003e: 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_005a: 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_0073: 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_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			if (settings == null || pendingKeyBinding == PendingKeyBinding.None || (int)currentEvent.type != 4)
			{
				return;
			}
			if ((int)currentEvent.keyCode == 27)
			{
				pendingKeyBinding = PendingKeyBinding.None;
				statusMessage = "Key change canceled.";
				currentEvent.Use();
			}
			else
			{
				if ((int)currentEvent.keyCode == 0)
				{
					return;
				}
				KeyCode val = ((pendingKeyBinding == PendingKeyBinding.Duplicate) ? settings.DeleteObjectKey.Value : settings.DuplicateHeldItemKey.Value);
				if (currentEvent.keyCode == val)
				{
					statusMessage = $"{currentEvent.keyCode} is already used by the other action.";
					currentEvent.Use();
					return;
				}
				if (pendingKeyBinding == PendingKeyBinding.Duplicate)
				{
					settings.DuplicateHeldItemKey.Value = currentEvent.keyCode;
					statusMessage = $"Copy key set to {currentEvent.keyCode}.";
				}
				else
				{
					settings.DeleteObjectKey.Value = currentEvent.keyCode;
					statusMessage = $"Delete key set to {currentEvent.keyCode}.";
				}
				((ConfigEntryBase)settings.DuplicateHeldItemKey).ConfigFile.Save();
				pendingKeyBinding = PendingKeyBinding.None;
				currentEvent.Use();
			}
		}

		private void DuplicateHeldItem()
		{
			//IL_0058: 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)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: 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_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: 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_00e0: Unknown result type (might be due to invalid IL or missing references)
			PlayerNetwork localPlayer = GetLocalPlayer();
			if ((Object)(object)localPlayer == (Object)null)
			{
				SetStatus("Local player was not found.", warning: true);
				return;
			}
			if (localPlayer.equippedItem <= 0 || localPlayer.equippedItem == 4)
			{
				SetStatus("No supported held item to copy.", warning: true);
				return;
			}
			GameData instance = GameData.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				SetStatus("GameData was not found.", warning: true);
				return;
			}
			Vector3 spawnPosition = GetSpawnPosition(localPlayer);
			Quaternion rotation = ((Component)localPlayer).transform.rotation;
			float y = ((Quaternion)(ref rotation)).eulerAngles.y;
			NetworkSpawner component = ((Component)instance).GetComponent<NetworkSpawner>();
			ManagerBlackboard component2 = ((Component)instance).GetComponent<ManagerBlackboard>();
			switch (localPlayer.equippedItem)
			{
			case 16:
				component2.CmdSpawnManufacturingBoxFromPlayer(spawnPosition, localPlayer.extraParameter1, localPlayer.extraParameter2, y, localPlayer.extraParameter3);
				break;
			case 13:
			case 14:
			case 15:
				component.CmdSpawnProp(localPlayer.equippedItem, spawnPosition, Vector3.zero);
				break;
			case 12:
				component.CmdSpawnOrderBoxFromPlayer(spawnPosition, y, localPlayer.orderNumberData, localPlayer.orderCustomerNameData, localPlayer.orderItemsInBoxData);
				break;
			case 11:
				component.CmdSpawnProp(11, spawnPosition, new Vector3(0f, y, 0f));
				break;
			case 10:
				component.CmdSpawnProp(10, spawnPosition, new Vector3(180f, y, 0f));
				break;
			case 9:
				component.CmdSpawnTrayFromPlayer(spawnPosition, localPlayer.trayData, y);
				break;
			case 8:
				component.CmdSpawnProp(8, spawnPosition, new Vector3(15f, y, 0f));
				break;
			case 7:
				component.CmdSpawnProp(7, spawnPosition, new Vector3(0f, y, 0f));
				break;
			case 6:
				component.CmdSpawnProp(6, spawnPosition, new Vector3(180f, y, 0f));
				break;
			case 5:
				component.CmdSpawnProp(5, spawnPosition, new Vector3(270f, y, 0f));
				break;
			case 3:
				component.CmdSpawnProp(3, spawnPosition, new Vector3(270f, y, 0f));
				break;
			case 2:
				component.CmdSpawnProp(2, spawnPosition, new Vector3(0f, y, 90f));
				break;
			case 1:
				component2.CmdSpawnBoxFromPlayer(spawnPosition, localPlayer.extraParameter1, localPlayer.extraParameter2, y);
				break;
			default:
				SetStatus($"Held item #{localPlayer.equippedItem} is not supported.", warning: true);
				return;
			}
			SetStatus($"Copied held item #{localPlayer.equippedItem}.", warning: false);
		}

		private void DeleteLookTarget()
		{
			GameData instance = GameData.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				SetStatus("GameData was not found.", warning: true);
				return;
			}
			if (!TryGetLookTarget(out GameObject target))
			{
				SetStatus("No deletable network object in sight.", warning: true);
				return;
			}
			((Component)instance).GetComponent<NetworkSpawner>().CmdDestroyBox(target);
			SetStatus("Deleted " + CleanPrefabName(((Object)target).name) + ".", warning: false);
		}

		private static bool TryGetLookTarget(out GameObject target)
		{
			//IL_002a: 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)
			target = null;
			Transform val = (((Object)(object)Camera.main != (Object)null) ? ((Component)Camera.main).transform : null);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			RaycastHit val2 = default(RaycastHit);
			if (!Physics.Raycast(val.position, val.forward, ref val2, GetObjectGrabReach(), -1, (QueryTriggerInteraction)1))
			{
				return false;
			}
			NetworkIdentity componentInParent = ((Component)((RaycastHit)(ref val2)).transform).GetComponentInParent<NetworkIdentity>();
			if ((Object)(object)componentInParent == (Object)null || IsProtectedDeleteTarget(((Component)componentInParent).gameObject))
			{
				return false;
			}
			target = ((Component)componentInParent).gameObject;
			return true;
		}

		private static float GetObjectGrabReach()
		{
			if ((Type.GetType("SupermarketTogetherMODMENU.PlayerReachPatch, SupermarketTogetherMODMENU")?.GetProperty("ReachDistance", BindingFlags.Static | BindingFlags.Public))?.GetValue(null) is float num)
			{
				return Mathf.Clamp(num, 0.5f, 100f);
			}
			return 4f;
		}

		private static bool IsProtectedDeleteTarget(GameObject target)
		{
			if (!((Object)(object)target.GetComponent<PlayerNetwork>() != (Object)null) && !((Object)(object)target.GetComponent<PlayerObjectController>() != (Object)null) && !((Object)(object)target.GetComponent<GameData>() != (Object)null))
			{
				return (Object)(object)target.GetComponent<NetworkSpawner>() != (Object)null;
			}
			return true;
		}

		private static Vector3 GetSpawnPosition(PlayerNetwork player)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			Transform val = (((Object)(object)Camera.main != (Object)null) ? ((Component)Camera.main).transform : null);
			Vector3 val2 = (((Object)(object)val != (Object)null) ? val.position : ((Component)player).transform.position);
			Vector3 val3 = (((Object)(object)val != (Object)null) ? val.forward : ((Component)player).transform.forward);
			RaycastHit val4 = default(RaycastHit);
			if (Physics.Raycast(val2, val3, ref val4, 3.5f, -1, (QueryTriggerInteraction)1))
			{
				Vector3 point = ((RaycastHit)(ref val4)).point;
				Vector3 normal = ((RaycastHit)(ref val4)).normal;
				return point + ((Vector3)(ref normal)).normalized * 0.5f;
			}
			return val2 + val3 * 3.5f;
		}

		private static PlayerNetwork? GetLocalPlayer()
		{
			PlayerNetwork[] array = Object.FindObjectsByType<PlayerNetwork>((FindObjectsSortMode)0);
			foreach (PlayerNetwork val in array)
			{
				if ((Object)(object)val != (Object)null && ((NetworkBehaviour)val).isLocalPlayer)
				{
					return val;
				}
			}
			return null;
		}

		private static string CleanPrefabName(string prefabName)
		{
			return prefabName.Replace("(Clone)", "").Trim();
		}

		private void SetStatus(string message, bool warning)
		{
			statusMessage = message;
			if (warning)
			{
				ManualLogSource? obj = logger;
				if (obj != null)
				{
					obj.LogWarning((object)message);
				}
			}
			else
			{
				ManualLogSource? obj2 = logger;
				if (obj2 != null)
				{
					obj2.LogInfo((object)message);
				}
			}
		}
	}
	internal sealed class ObjectManipulatorSettings
	{
		public ConfigEntry<bool> Enabled { get; }

		public ConfigEntry<KeyCode> DuplicateHeldItemKey { get; }

		public ConfigEntry<KeyCode> DeleteObjectKey { get; }

		public ObjectManipulatorSettings(ConfigEntry<bool> enabled, ConfigEntry<KeyCode> duplicateHeldItemKey, ConfigEntry<KeyCode> deleteObjectKey)
		{
			Enabled = enabled;
			DuplicateHeldItemKey = duplicateHeldItemKey;
			DeleteObjectKey = deleteObjectKey;
		}
	}
}
namespace SupermarketTogetherObjectSpawner
{
	internal static class NoCostPlaceableSpawnPatch
	{
		[HarmonyPatch(typeof(NetworkSpawner), "UserCode_CmdSpawn__Int32__Vector3__Vector3")]
		[HarmonyPrefix]
		private static bool SpawnBuildableWithoutCost(NetworkSpawner __instance, int prefabID, Vector3 pos, Vector3 rot)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			if (!ObjectSpawnerFeatureState.NoCostPlaceableSpawnEnabled)
			{
				return true;
			}
			if (__instance.buildables == null || prefabID < 0 || prefabID >= __instance.buildables.Length)
			{
				return false;
			}
			GameObject val = __instance.buildables[prefabID];
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			Data_Container component = val.GetComponent<Data_Container>();
			int num = (((Object)(object)component != (Object)null) ? component.parentIndex : 0);
			GameObject obj = Object.Instantiate<GameObject>(val, pos, Quaternion.Euler(rot));
			obj.transform.SetParent(__instance.levelPropsOBJ.transform.GetChild(num));
			NetworkServer.Spawn(obj, (NetworkConnection)null);
			return false;
		}

		[HarmonyPatch(typeof(NetworkSpawner), "UserCode_CmdSpawnManufacturing__Int32__Vector3__Vector3")]
		[HarmonyPrefix]
		private static bool SpawnManufacturingWithoutCost(NetworkSpawner __instance, int prefabID, Vector3 pos, Vector3 rot)
		{
			//IL_0052: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			if (!ObjectSpawnerFeatureState.NoCostPlaceableSpawnEnabled)
			{
				return true;
			}
			if (__instance.manufacturingBuildables == null || prefabID < 0 || prefabID >= __instance.manufacturingBuildables.Length)
			{
				return false;
			}
			GameObject val = __instance.manufacturingBuildables[prefabID];
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			ManufacturingContainer component = val.GetComponent<ManufacturingContainer>();
			int num = (((Object)(object)component != (Object)null) ? component.parentIndex : 10);
			GameObject obj = Object.Instantiate<GameObject>(val, pos, Quaternion.Euler(rot));
			obj.transform.SetParent(__instance.levelPropsOBJ.transform.GetChild(num));
			NetworkServer.Spawn(obj, (NetworkConnection)null);
			return false;
		}
	}
	internal sealed class ObjectSpawnCatalog
	{
		public bool TryBuildEntries(out List<ObjectSpawnEntry> entries)
		{
			entries = new List<ObjectSpawnEntry>();
			NetworkSpawner networkSpawner = GetNetworkSpawner();
			if ((Object)(object)networkSpawner == (Object)null)
			{
				return false;
			}
			AddProductBoxEntries(entries);
			AddHeldItemEntries(entries, networkSpawner.props);
			AddPlaceableObjectEntries(entries, "Buildable", networkSpawner.buildables);
			AddPlaceableObjectEntries(entries, "Manufacturing", networkSpawner.manufacturingBuildables);
			AddPlaceableObjectEntries(entries, "Decoration", networkSpawner.decorationProps);
			AddSceneOutdoorTrashCanEntries(entries);
			AddNpcEntries(entries);
			return true;
		}

		private static void AddProductBoxEntries(List<ObjectSpawnEntry> entries)
		{
			ProductListing instance = ProductListing.Instance;
			if (instance?.productsData == null)
			{
				return;
			}
			for (int i = 0; i < instance.productsData.Length; i++)
			{
				ProductData val = instance.productsData[i];
				if (val != null)
				{
					string localizedText = GetLocalizedText($"product{i}");
					string displayName = (string.IsNullOrWhiteSpace(localizedText) ? $"Product {i}" : localizedText);
					entries.Add(ObjectSpawnEntry.ProductBox(i, displayName, val.maxItemsPerBox));
				}
			}
		}

		private static void AddHeldItemEntries(List<ObjectSpawnEntry> entries, GameObject[]? prefabs)
		{
			if (prefabs == null)
			{
				return;
			}
			for (int i = 0; i < prefabs.Length; i++)
			{
				GameObject val = prefabs[i];
				if (!((Object)(object)val == (Object)null))
				{
					entries.Add(ObjectSpawnEntry.HeldItem(i, CleanPrefabName(((Object)val).name)));
				}
			}
		}

		private static void AddPlaceableObjectEntries(List<ObjectSpawnEntry> entries, string source, GameObject[]? prefabs)
		{
			if (prefabs == null)
			{
				return;
			}
			for (int i = 0; i < prefabs.Length; i++)
			{
				GameObject val = prefabs[i];
				if (!((Object)(object)val == (Object)null))
				{
					string placeableDisplayName = GetPlaceableDisplayName(val, source);
					entries.Add(ObjectSpawnEntry.PlaceableObject(i, placeableDisplayName, source, val));
					if ((Object)(object)val.GetComponent<TrashPlace>() != (Object)null)
					{
						entries.Add(ObjectSpawnEntry.OutdoorTrashCan(i, placeableDisplayName, source, val));
					}
				}
			}
		}

		private static void AddSceneOutdoorTrashCanEntries(List<ObjectSpawnEntry> entries)
		{
			TrashPlace[] array = Object.FindObjectsByType<TrashPlace>((FindObjectsSortMode)0);
			int num = 0;
			TrashPlace[] array2 = array;
			foreach (TrashPlace val in array2)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).GetComponent<TrashSpawn>() != (Object)null))
				{
					GameObject gameObject = ((Component)val).gameObject;
					entries.Add(ObjectSpawnEntry.SceneOutdoorTrashCan(num, CleanPrefabName(((Object)gameObject).name) + " [Scene]", gameObject));
					num++;
				}
			}
		}

		private static void AddNpcEntries(List<ObjectSpawnEntry> entries)
		{
			entries.Add(ObjectSpawnEntry.Npc(0, "客", ObjectSpawnNpcKind.Customer));
			entries.Add(ObjectSpawnEntry.Npc(1, "通行人", ObjectSpawnNpcKind.Bystander));
			entries.Add(ObjectSpawnEntry.Npc(2, "泥棒客", ObjectSpawnNpcKind.ThiefCustomer));
			entries.Add(ObjectSpawnEntry.Npc(3, "Mister Grusch", ObjectSpawnNpcKind.MisterGrusch));
		}

		private static string GetPlaceableDisplayName(GameObject prefab, string source)
		{
			string text = source switch
			{
				"Buildable" => GetBuildableLocalizedName(prefab), 
				"Manufacturing" => GetManufacturingLocalizedName(prefab), 
				"Decoration" => GetDecorationLocalizedName(prefab), 
				_ => "", 
			};
			return (string.IsNullOrWhiteSpace(text) ? CleanPrefabName(((Object)prefab).name) : text) + " [" + GetPlaceableSourceLabel(source) + "]";
		}

		private static string GetBuildableLocalizedName(GameObject prefab)
		{
			Data_Container component = prefab.GetComponent<Data_Container>();
			if ((Object)(object)component == (Object)null)
			{
				return "";
			}
			return FirstLocalizedText(component.buildableTag, $"buildable{component.containerID}", $"container{component.containerID}", $"furniture{component.containerID}");
		}

		private static string GetManufacturingLocalizedName(GameObject prefab)
		{
			ManufacturingContainer component = prefab.GetComponent<ManufacturingContainer>();
			if ((Object)(object)component == (Object)null)
			{
				return "";
			}
			return FirstLocalizedText($"manufacturing{component.containerID}", $"manufacturingcontainer{component.containerID}", $"mcontainer{component.containerID}", $"buildable{component.containerID}");
		}

		private static string GetDecorationLocalizedName(GameObject prefab)
		{
			BuildableInfo component = prefab.GetComponent<BuildableInfo>();
			if ((Object)(object)component == (Object)null)
			{
				return "";
			}
			return FirstLocalizedText($"decoration{component.decorationID}", $"decoprop{component.decorationID}", $"deco{component.decorationID}", $"buildable{component.decorationID}");
		}

		private static string FirstLocalizedText(params string[] keys)
		{
			for (int i = 0; i < keys.Length; i++)
			{
				string localizedTextOrEmpty = GetLocalizedTextOrEmpty(keys[i]);
				if (!string.IsNullOrWhiteSpace(localizedTextOrEmpty))
				{
					return localizedTextOrEmpty;
				}
			}
			return "";
		}

		private static string GetPlaceableSourceLabel(string source)
		{
			return source switch
			{
				"Buildable" => "設置物", 
				"Manufacturing" => "製造", 
				"Decoration" => "装飾", 
				_ => source, 
			};
		}

		private static string GetLocalizedText(string key)
		{
			if ((Object)(object)LocalizationManager.instance == (Object)null)
			{
				return "";
			}
			return LocalizationManager.instance.GetLocalizationString(key);
		}

		private static string GetLocalizedTextOrEmpty(string key)
		{
			if (string.IsNullOrWhiteSpace(key) || (Object)(object)LocalizationManager.instance == (Object)null)
			{
				return "";
			}
			string localizationString = LocalizationManager.instance.GetLocalizationString(key);
			if (string.IsNullOrWhiteSpace(localizationString) || localizationString == key || localizationString.Equals("locError", StringComparison.OrdinalIgnoreCase))
			{
				return "";
			}
			return localizationString;
		}

		private static NetworkSpawner? GetNetworkSpawner()
		{
			if (!((Object)(object)GameData.Instance != (Object)null))
			{
				return Object.FindFirstObjectByType<NetworkSpawner>();
			}
			return ((Component)GameData.Instance).GetComponent<NetworkSpawner>();
		}

		private static string CleanPrefabName(string prefabName)
		{
			return prefabName.Replace("(Clone)", "").Trim();
		}
	}
	internal enum ObjectSpawnEntryKind
	{
		ProductBox,
		HeldItem,
		PlaceableObject,
		OutdoorTrashCan,
		Npc
	}
	internal enum ObjectSpawnNpcKind
	{
		None,
		Customer,
		Bystander,
		ThiefCustomer,
		MisterGrusch
	}
	internal enum ObjectSpawnPlaceableSource
	{
		None,
		Buildable,
		Manufacturing,
		Decoration,
		SceneClone
	}
	internal sealed class ObjectSpawnEntry
	{
		public ObjectSpawnEntryKind Kind { get; }

		public int Id { get; }

		public string DisplayName { get; }

		public int Quantity { get; }

		public ObjectSpawnPlaceableSource PlaceableSource { get; }

		public ObjectSpawnNpcKind NpcKind { get; }

		public GameObject? Prefab { get; }

		private ObjectSpawnEntry(ObjectSpawnEntryKind kind, int id, string displayName, int quantity, ObjectSpawnPlaceableSource placeableSource, ObjectSpawnNpcKind npcKind, GameObject? prefab)
		{
			Kind = kind;
			Id = id;
			DisplayName = displayName;
			Quantity = quantity;
			PlaceableSource = placeableSource;
			NpcKind = npcKind;
			Prefab = prefab;
		}

		public static ObjectSpawnEntry ProductBox(int productId, string displayName, int quantity)
		{
			return new ObjectSpawnEntry(ObjectSpawnEntryKind.ProductBox, productId, displayName, quantity, ObjectSpawnPlaceableSource.None, ObjectSpawnNpcKind.None, null);
		}

		public static ObjectSpawnEntry HeldItem(int itemId, string displayName)
		{
			return new ObjectSpawnEntry(ObjectSpawnEntryKind.HeldItem, itemId, displayName, 1, ObjectSpawnPlaceableSource.None, ObjectSpawnNpcKind.None, null);
		}

		public static ObjectSpawnEntry PlaceableObject(int objectId, string displayName, string source, GameObject prefab)
		{
			return new ObjectSpawnEntry(ObjectSpawnEntryKind.PlaceableObject, objectId, displayName, 0, ParsePlaceableSource(source), ObjectSpawnNpcKind.None, prefab);
		}

		public static ObjectSpawnEntry OutdoorTrashCan(int objectId, string displayName, string source, GameObject prefab)
		{
			return new ObjectSpawnEntry(ObjectSpawnEntryKind.OutdoorTrashCan, objectId, displayName, 0, ParsePlaceableSource(source), ObjectSpawnNpcKind.None, prefab);
		}

		public static ObjectSpawnEntry SceneOutdoorTrashCan(int objectId, string displayName, GameObject template)
		{
			return new ObjectSpawnEntry(ObjectSpawnEntryKind.OutdoorTrashCan, objectId, displayName, 0, ObjectSpawnPlaceableSource.SceneClone, ObjectSpawnNpcKind.None, template);
		}

		public static ObjectSpawnEntry Npc(int npcId, string displayName, ObjectSpawnNpcKind npcKind)
		{
			return new ObjectSpawnEntry(ObjectSpawnEntryKind.Npc, npcId, displayName, 0, ObjectSpawnPlaceableSource.None, npcKind, null);
		}

		private static ObjectSpawnPlaceableSource ParsePlaceableSource(string source)
		{
			return source switch
			{
				"Buildable" => ObjectSpawnPlaceableSource.Buildable, 
				"Manufacturing" => ObjectSpawnPlaceableSource.Manufacturing, 
				"Decoration" => ObjectSpawnPlaceableSource.Decoration, 
				_ => ObjectSpawnPlaceableSource.None, 
			};
		}
	}
	internal sealed class ObjectSpawnerMenu : MonoBehaviour
	{
		private readonly struct CategoryTab
		{
			public ObjectSpawnEntryKind Kind { get; }

			public string Label { get; }

			public CategoryTab(ObjectSpawnEntryKind kind, string label)
			{
				Kind = kind;
				Label = label;
			}
		}

		private const float ButtonHeight = 28f;

		private const float CategoryButtonWidth = 142f;

		private const float EntryRowHeight = 30f;

		private const float EntryListHeight = 430f;

		private readonly List<ObjectSpawnEntry> entries = new List<ObjectSpawnEntry>();

		private readonly CategoryTab[] categories = new CategoryTab[5]
		{
			new CategoryTab(ObjectSpawnEntryKind.ProductBox, "商品箱"),
			new CategoryTab(ObjectSpawnEntryKind.HeldItem, "手持ちアイテム"),
			new CategoryTab(ObjectSpawnEntryKind.PlaceableObject, "設置オブジェクト"),
			new CategoryTab(ObjectSpawnEntryKind.OutdoorTrashCan, "店外ゴミ箱"),
			new CategoryTab(ObjectSpawnEntryKind.Npc, "NPC")
		};

		private ManualLogSource? logger;

		private ObjectSpawnCatalog? catalog;

		private ObjectSpawnExecutor? executor;

		private Font? japaneseFont;

		private Vector2 scrollPosition;

		private ObjectSpawnEntryKind selectedCategory;

		private string searchText = "";

		private string statusMessage = "ゲームに入ってから「更新」を押してください。";

		private bool hasLoadedEntries;

		private readonly List<ObjectSpawnEntry> visibleEntries = new List<ObjectSpawnEntry>();

		private ObjectSpawnEntryKind cachedCategory;

		private string cachedSearchText = "";

		private int entriesVersion;

		private int cachedEntriesVersion = -1;

		public void Initialize(ManualLogSource pluginLogger, ObjectSpawnerSettings objectSpawnerSettings)
		{
			logger = pluginLogger;
			catalog = new ObjectSpawnCatalog();
			executor = new ObjectSpawnExecutor(pluginLogger, objectSpawnerSettings);
		}

		internal void ShowPanel()
		{
			if (!hasLoadedEntries)
			{
				RefreshEntries();
			}
		}

		internal void DrawPanelContent()
		{
			ApplyJapaneseFont();
			GUILayout.BeginVertical(GUI.skin.box, Array.Empty<GUILayoutOption>());
			GUILayout.Label("カテゴリ", Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			CategoryTab[] array = categories;
			for (int i = 0; i < array.Length; i++)
			{
				CategoryTab categoryTab = array[i];
				bool num = selectedCategory == categoryTab.Kind;
				string text = $"{categoryTab.Label} ({CountEntries(categoryTab.Kind)})";
				if (GUILayout.Toggle(num, text, GUIStyle.op_Implicit("Button"), (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(142f),
					GUILayout.Height(28f)
				}))
				{
					selectedCategory = categoryTab.Kind;
				}
			}
			GUILayout.EndHorizontal();
			GUILayout.EndVertical();
			GUILayout.Space(8f);
			GUILayout.BeginVertical(GUI.skin.box, Array.Empty<GUILayoutOption>());
			GUILayout.Label("検索と更新", Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("検索", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(52f) });
			searchText = GUILayout.TextField(searchText, 64, Array.Empty<GUILayoutOption>());
			if (GUILayout.Button("クリア", (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(72f),
				GUILayout.Height(28f)
			}))
			{
				searchText = "";
			}
			if (GUILayout.Button("更新", (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(96f),
				GUILayout.Height(28f)
			}))
			{
				RefreshEntries();
			}
			GUILayout.EndHorizontal();
			GUILayout.EndVertical();
			GUILayout.Space(6f);
			GUILayout.BeginVertical(GUI.skin.box, Array.Empty<GUILayoutOption>());
			DrawEntries();
			GUILayout.EndVertical();
			GUILayout.Space(6f);
			GUILayout.BeginVertical(GUI.skin.box, Array.Empty<GUILayoutOption>());
			GUILayout.Label(statusMessage, Array.Empty<GUILayoutOption>());
			GUILayout.EndVertical();
		}

		private void DrawEntries()
		{
			//IL_0090: 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)
			RebuildVisibleEntriesIfNeeded();
			GUILayout.Label($"{GetCategoryLabel(selectedCategory)}: {visibleEntries.Count}", Array.Empty<GUILayoutOption>());
			if (visibleEntries.Count == 0)
			{
				GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(430f) });
				GUILayout.Space(16f);
				GUILayout.Label(string.IsNullOrWhiteSpace(searchText) ? "表示できる項目がありません。必要なら「更新」を押してください。" : "検索条件に一致する項目がありません。", Array.Empty<GUILayoutOption>());
				GUILayout.EndVertical();
				return;
			}
			scrollPosition = GUILayout.BeginScrollView(scrollPosition, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(430f) });
			int num = Mathf.Clamp((int)(scrollPosition.y / 30f), 0, visibleEntries.Count - 1);
			int num2 = Mathf.CeilToInt(14.333333f) + 2;
			int num3 = Mathf.Min(visibleEntries.Count, num + num2);
			GUILayout.Space((float)num * 30f);
			for (int i = num; i < num3; i++)
			{
				ObjectSpawnEntry objectSpawnEntry = visibleEntries[i];
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Label($"#{objectSpawnEntry.Id}", (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(48f),
					GUILayout.Height(30f)
				});
				GUILayout.Label(objectSpawnEntry.DisplayName, (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.MinWidth(260f),
					GUILayout.Height(30f)
				});
				if (GUILayout.Button("召喚", (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(96f),
					GUILayout.Height(28f)
				}))
				{
					SpawnSelectedEntry(objectSpawnEntry);
				}
				GUILayout.EndHorizontal();
			}
			GUILayout.Space((float)(visibleEntries.Count - num3) * 30f);
			GUILayout.EndScrollView();
		}

		private void RefreshEntries()
		{
			if (catalog == null)
			{
				return;
			}
			entries.Clear();
			if (!catalog.TryBuildEntries(out List<ObjectSpawnEntry> collection))
			{
				hasLoadedEntries = false;
				statusMessage = "NetworkSpawner が見つかりません。セーブデータに入ってから実行してください。";
				ManualLogSource? obj = logger;
				if (obj != null)
				{
					obj.LogWarning((object)statusMessage);
				}
				return;
			}
			entries.AddRange(collection);
			entriesVersion++;
			hasLoadedEntries = true;
			statusMessage = $"{entries.Count} 件を読み込みました。";
			ManualLogSource? obj2 = logger;
			if (obj2 != null)
			{
				obj2.LogInfo((object)statusMessage);
			}
		}

		private void RebuildVisibleEntriesIfNeeded()
		{
			if (cachedEntriesVersion == entriesVersion && cachedCategory == selectedCategory && string.Equals(cachedSearchText, searchText, StringComparison.Ordinal))
			{
				return;
			}
			visibleEntries.Clear();
			foreach (ObjectSpawnEntry entry in entries)
			{
				if (entry.Kind == selectedCategory && (string.IsNullOrWhiteSpace(searchText) || entry.DisplayName.IndexOf(searchText, StringComparison.OrdinalIgnoreCase) >= 0))
				{
					visibleEntries.Add(entry);
				}
			}
			cachedEntriesVersion = entriesVersion;
			cachedCategory = selectedCategory;
			cachedSearchText = searchText;
		}

		private void SpawnSelectedEntry(ObjectSpawnEntry entry)
		{
			if (executor == null)
			{
				return;
			}
			statusMessage = executor.Spawn(entry);
			if (!statusMessage.StartsWith("召喚しました:", StringComparison.Ordinal))
			{
				ManualLogSource? obj = logger;
				if (obj != null)
				{
					obj.LogWarning((object)statusMessage);
				}
			}
		}

		private int CountEntries(ObjectSpawnEntryKind kind)
		{
			int num = 0;
			foreach (ObjectSpawnEntry entry in entries)
			{
				if (entry.Kind == kind)
				{
					num++;
				}
			}
			return num;
		}

		private void ApplyJapaneseFont()
		{
			if (japaneseFont == null)
			{
				japaneseFont = Font.CreateDynamicFontFromOSFont(new string[4] { "Yu Gothic UI", "Yu Gothic", "Meiryo", "MS Gothic" }, 14);
			}
			if (!((Object)(object)japaneseFont == (Object)null) && !((Object)(object)GUI.skin.font == (Object)(object)japaneseFont))
			{
				GUI.skin.font = japaneseFont;
				GUI.skin.label.font = japaneseFont;
				GUI.skin.button.font = japaneseFont;
				GUI.skin.toggle.font = japaneseFont;
				GUI.skin.textField.font = japaneseFont;
				GUI.skin.window.font = japaneseFont;
			}
		}

		private string GetCategoryLabel(ObjectSpawnEntryKind kind)
		{
			CategoryTab[] array = categories;
			for (int i = 0; i < array.Length; i++)
			{
				CategoryTab categoryTab = array[i];
				if (categoryTab.Kind == kind)
				{
					return categoryTab.Label;
				}
			}
			return kind.ToString();
		}
	}
	internal sealed class ObjectSpawnerSettings
	{
		public ConfigEntry<bool> NoCostPlaceableSpawnEnabled { get; }

		public ConfigEntry<float> SpawnDistance { get; }

		public ObjectSpawnerSettings(ConfigEntry<bool> noCostPlaceableSpawnEnabled, ConfigEntry<float> spawnDistance)
		{
			NoCostPlaceableSpawnEnabled = noCostPlaceableSpawnEnabled;
			SpawnDistance = spawnDistance;
			ObjectSpawnerFeatureState.NoCostPlaceableSpawnEnabled = noCostPlaceableSpawnEnabled.Value;
			noCostPlaceableSpawnEnabled.SettingChanged += delegate
			{
				ObjectSpawnerFeatureState.NoCostPlaceableSpawnEnabled = noCostPlaceableSpawnEnabled.Value;
			};
		}
	}
	internal static class ObjectSpawnerFeatureState
	{
		public static bool NoCostPlaceableSpawnEnabled { get; set; } = true;
	}
	internal sealed class ObjectSpawnExecutor
	{
		private readonly ManualLogSource logger;

		private readonly ObjectSpawnerSettings settings;

		public ObjectSpawnExecutor(ManualLogSource logger, ObjectSpawnerSettings settings)
		{
			this.logger = logger;
			this.settings = settings;
		}

		public string Spawn(ObjectSpawnEntry entry)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			GameData instance = GameData.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return "GameData が見つかりません。";
			}
			Vector3 spawnPosition = GetSpawnPosition(GetLocalPlayer());
			float spawnYRotation = GetSpawnYRotation();
			switch (entry.Kind)
			{
			case ObjectSpawnEntryKind.ProductBox:
				((Component)instance).GetComponent<ManagerBlackboard>().CmdSpawnBoxFromPlayer(spawnPosition, entry.Id, entry.Quantity, spawnYRotation);
				break;
			case ObjectSpawnEntryKind.HeldItem:
				((Component)instance).GetComponent<NetworkSpawner>().CmdSpawnProp(entry.Id, spawnPosition, GetHeldItemRotation(entry.Id, spawnYRotation));
				break;
			case ObjectSpawnEntryKind.PlaceableObject:
			case ObjectSpawnEntryKind.OutdoorTrashCan:
			{
				string text2 = SpawnPlaceableObject(((Component)instance).GetComponent<NetworkSpawner>(), entry, spawnPosition, spawnYRotation);
				if (!string.IsNullOrWhiteSpace(text2))
				{
					return text2;
				}
				break;
			}
			case ObjectSpawnEntryKind.Npc:
			{
				string text = SpawnNpc(entry, spawnPosition);
				if (!string.IsNullOrWhiteSpace(text))
				{
					return text;
				}
				break;
			}
			}
			string text3 = "召喚しました: " + entry.DisplayName;
			logger.LogInfo((object)text3);
			return text3;
		}

		private static string SpawnPlaceableObject(NetworkSpawner spawner, ObjectSpawnEntry entry, Vector3 spawnPosition, float yRotation)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0070: 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)
			if (entry.PlaceableSource == ObjectSpawnPlaceableSource.SceneClone)
			{
				return SpawnSceneClone(entry, spawnPosition, yRotation);
			}
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(0f, yRotation, 0f);
			switch (entry.PlaceableSource)
			{
			case ObjectSpawnPlaceableSource.Buildable:
				spawner.CmdSpawn(entry.Id, spawnPosition, val);
				return "";
			case ObjectSpawnPlaceableSource.Manufacturing:
				spawner.CmdSpawnManufacturing(entry.Id, spawnPosition, val);
				return "";
			case ObjectSpawnPlaceableSource.Decoration:
				spawner.CmdSpawnDecoration(entry.Id, spawnPosition, val);
				return "";
			default:
				return "未対応の設置オブジェクトです。";
			}
		}

		private static string SpawnSceneClone(ObjectSpawnEntry entry, Vector3 spawnPosition, float yRotation)
		{
			//IL_001a: 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)
			if ((Object)(object)entry.Prefab == (Object)null)
			{
				return "複製元の店外ゴミ箱が見つかりません。";
			}
			GameObject val = Object.Instantiate<GameObject>(entry.Prefab, spawnPosition, Quaternion.Euler(0f, yRotation, 0f));
			if ((Object)(object)entry.Prefab.transform.parent != (Object)null)
			{
				val.transform.SetParent(entry.Prefab.transform.parent);
			}
			if (NetworkServer.active && (Object)(object)val.GetComponent<NetworkIdentity>() != (Object)null)
			{
				NetworkServer.Spawn(val, (NetworkConnection)null);
			}
			return "";
		}

		private static string SpawnNpc(ObjectSpawnEntry entry, Vector3 spawnPosition)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: 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)
			if (!NetworkServer.active)
			{
				return "NPC召喚はホスト/サーバーでのみ実行できます。";
			}
			NPC_Manager instance = NPC_Manager.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return "NPC_Manager が見つかりません。";
			}
			switch (entry.NpcKind)
			{
			case ObjectSpawnNpcKind.Customer:
				SpawnCustomerNpc(instance, spawnPosition, isThief: false);
				return "";
			case ObjectSpawnNpcKind.Bystander:
				SpawnBystanderNpc(instance, spawnPosition);
				return "";
			case ObjectSpawnNpcKind.ThiefCustomer:
				SpawnCustomerNpc(instance, spawnPosition, isThief: true);
				return "";
			case ObjectSpawnNpcKind.MisterGrusch:
				SpawnMisterGrusch(spawnPosition);
				return "";
			default:
				return "未対応のNPCです。";
			}
		}

		private static void SpawnCustomerNpc(NPC_Manager npcManager, Vector3 spawnPosition, bool isThief)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = InstantiateNpcAgent(npcManager, spawnPosition, npcManager.customersnpcParentOBJ.transform);
			NPC_Info component = val.GetComponent<NPC_Info>();
			component.NetworkNPCID = GetRandomNpcId(npcManager);
			component.NetworkisCustomer = true;
			component.isAThief = isThief;
			component.productItemPlaceWait = 0.5f;
			AddRandomProductsToBuy(component);
			NavMeshAgent component2 = val.GetComponent<NavMeshAgent>();
			ConfigureNpcAgent(component2);
			component2.destination = GetCustomerDestination(npcManager, spawnPosition);
			component.state = 0;
			NetworkServer.Spawn(val, (NetworkConnection)null);
		}

		private static void SpawnBystanderNpc(NPC_Manager npcManager, Vector3 spawnPosition)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = InstantiateNpcAgent(npcManager, spawnPosition, npcManager.dummynpcParentOBJ.transform);
			NPC_Info component = obj.GetComponent<NPC_Info>();
			component.NetworkNPCID = GetRandomNpcId(npcManager);
			component.isBystander = true;
			NavMeshAgent component2 = obj.GetComponent<NavMeshAgent>();
			ConfigureNpcAgent(component2);
			component2.destination = GetRandomChildPosition(npcManager.randomPointsOBJ, spawnPosition);
			NetworkServer.Spawn(obj, (NetworkConnection)null);
		}

		private static void SpawnMisterGrusch(Vector3 spawnPosition)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			NetworkSpawner networkSpawner = GetNetworkSpawner();
			if (!((Object)(object)networkSpawner == (Object)null) && !((Object)(object)networkSpawner.misterGruschPrefabOBJ == (Object)null))
			{
				GameObject val = Object.Instantiate<GameObject>(networkSpawner.misterGruschPrefabOBJ, spawnPosition, Quaternion.identity);
				if ((Object)(object)networkSpawner.gruschesParentOBJ != (Object)null)
				{
					val.transform.SetParent(networkSpawner.gruschesParentOBJ.transform);
				}
				InitializeMisterGruschFields(val);
				NetworkServer.Spawn(val, (NetworkConnection)null);
			}
		}

		private static void InitializeMisterGruschFields(GameObject grusch)
		{
			MisterGrusch component = grusch.GetComponent<MisterGrusch>();
			if (!((Object)(object)component == (Object)null))
			{
				Transform obj = grusch.transform.Find("Pivot_MisterGrusch");
				SetPrivateField(component, "pivotAnimator", (obj != null) ? ((Component)obj).GetComponent<Animator>() : null);
				SetPrivateField(component, "speedComponent", grusch.GetComponent<NPC_Speed>());
				Transform obj2 = grusch.transform.Find("BoinkAudio");
				SetPrivateField(component, "boinkAudioOBJ", (obj2 != null) ? ((Component)obj2).gameObject : null);
				Transform obj3 = grusch.transform.Find("OtherScreams");
				SetPrivateField(component, "screamAudioSource", (obj3 != null) ? ((Component)obj3).GetComponent<AudioSource>() : null);
				Transform obj4 = grusch.transform.Find("Pivot_MisterGrusch/NumberCanvas/Number");
				SetPrivateField(component, "numberField", (obj4 != null) ? ((Component)obj4).GetComponent("TextMeshProUGUI") : null);
				SetPrivateField(component, "shelvesOBJ", NPC_Manager.Instance?.shelvesOBJ);
				SetPrivateField(component, "storageOBJ", NPC_Manager.Instance?.storageOBJ);
				NavMeshAgent component2 = grusch.GetComponent<NavMeshAgent>();
				if ((Object)(object)component2 != (Object)null)
				{
					((Behaviour)component2).enabled = true;
					SetPrivateField(component, "agent", component2);
				}
			}
		}

		private static void SetPrivateField(object target, string fieldName, object? value)
		{
			if (value != null)
			{
				target.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(target, value);
			}
		}

		private static GameObject InstantiateNpcAgent(NPC_Manager npcManager, Vector3 spawnPosition, Transform parent)
		{
			//IL_0006: 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)
			GameObject obj = Object.Instantiate<GameObject>(npcManager.npcAgentPrefab, spawnPosition, Quaternion.identity);
			obj.transform.SetParent(parent);
			return obj;
		}

		private static int GetRandomNpcId(NPC_Manager npcManager)
		{
			if (npcManager.NPCsArray == null || npcManager.NPCsArray.Length == 0)
			{
				return 0;
			}
			return Random.Range(0, npcManager.NPCsArray.Length);
		}

		private static void AddRandomProductsToBuy(NPC_Info npcInfo)
		{
			List<int> list = ProductListing.Instance?.availableProducts;
			if (list != null && list.Count != 0)
			{
				int num = Mathf.Clamp(Random.Range(1, 4), 1, list.Count);
				for (int i = 0; i < num; i++)
				{
					npcInfo.productsIDToBuy.Add(list[Random.Range(0, list.Count)]);
				}
				npcInfo.productsIDToBuy.Sort();
			}
		}

		private static void ConfigureNpcAgent(NavMeshAgent agent)
		{
			((Behaviour)agent).enabled = true;
			agent.stoppingDistance = 1f;
			agent.speed = 2.2f;
			agent.angularSpeed = 140f;
			agent.acceleration = 10f;
		}

		private static Vector3 GetCustomerDestination(NPC_Manager npcManager, Vector3 fallback)
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)npcManager.shelvesOBJ != (Object)null && npcManager.shelvesOBJ.transform.childCount > 0)
			{
				Transform child = npcManager.shelvesOBJ.transform.GetChild(Random.Range(0, npcManager.shelvesOBJ.transform.childCount));
				Transform val = child.Find("Standspot");
				if (!((Object)(object)val != (Object)null))
				{
					return child.position;
				}
				return val.position;
			}
			return GetRandomChildPosition(npcManager.randomPointsOBJ, fallback);
		}

		private static Vector3 GetRandomChildPosition(GameObject parentObject, Vector3 fallback)
		{
			//IL_0016: 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)
			if ((Object)(object)parentObject == (Object)null || parentObject.transform.childCount == 0)
			{
				return fallback;
			}
			return parentObject.transform.GetChild(Random.Range(0, parentObject.transform.childCount)).position;
		}

		private Vector3 GetSpawnPosition(PlayerNetwork? player)
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: 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_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: 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_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Clamp(settings.SpawnDistance.Value, 1f, 20f);
			Transform val = (((Object)(object)Camera.main != (Object)null) ? ((Component)Camera.main).transform : null);
			Vector3 val2 = (((Object)(object)val != (Object)null) ? val.position : ((player != null) ? ((Component)player).transform.position : Vector3.zero));
			Vector3 val3 = (((Object)(object)val != (Object)null) ? val.forward : ((player != null) ? ((Component)player).transform.forward : Vector3.forward));
			RaycastHit val4 = default(RaycastHit);
			if (Physics.Raycast(val2, val3, ref val4, num, -1, (QueryTriggerInteraction)1))
			{
				Vector3 point = ((RaycastHit)(ref val4)).point;
				Vector3 normal = ((RaycastHit)(ref val4)).normal;
				return point + ((Vector3)(ref normal)).normalized * 0.5f;
			}
			return val2 + val3 * num;
		}

		private static float GetSpawnYRotation()
		{
			//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_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: 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)
			PlayerNetwork localPlayer = GetLocalPlayer();
			Quaternion rotation;
			if ((Object)(object)localPlayer != (Object)null)
			{
				rotation = ((Component)localPlayer).transform.rotation;
				return ((Quaternion)(ref rotation)).eulerAngles.y;
			}
			if (!((Object)(object)Camera.main != (Object)null))
			{
				return 0f;
			}
			rotation = ((Component)Camera.main).transform.rotation;
			return ((Quaternion)(ref rotation)).eulerAngles.y;
		}

		private static Vector3 GetHeldItemRotation(int itemId, float yRotation)
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: 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_005e: 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)
			switch (itemId)
			{
			case 6:
			case 10:
				return new Vector3(180f, yRotation, 0f);
			case 8:
				return new Vector3(15f, yRotation, 0f);
			case 3:
			case 5:
				return new Vector3(270f, yRotation, 0f);
			case 2:
				return new Vector3(0f, yRotation, 90f);
			case 13:
			case 14:
			case 15:
				return Vector3.zero;
			default:
				return new Vector3(0f, yRotation, 0f);
			}
		}

		private static NetworkSpawner? GetNetworkSpawner()
		{
			if (!((Object)(object)GameData.Instance != (Object)null))
			{
				return Object.FindFirstObjectByType<NetworkSpawner>();
			}
			return ((Component)GameData.Instance).GetComponent<NetworkSpawner>();
		}

		private static PlayerNetwork? GetLocalPlayer()
		{
			PlayerNetwork[] array = Object.FindObjectsByType<PlayerNetwork>((FindObjectsSortMode)0);
			foreach (PlayerNetwork val in array)
			{
				if ((Object)(object)val != (Object)null && ((NetworkBehaviour)val).isLocalPlayer)
				{
					return val;
				}
			}
			return null;
		}
	}
}
namespace SupermarketTogetherAnyPlaceBuilder
{
	internal sealed class AnyPlaceBuilderController : MonoBehaviour
	{
		private static readonly FieldInfo? MainDummyField = Field(typeof(Builder_Main), "dummyOBJ");

		private static readonly FieldInfo? MainCurrentElementIndexField = Field(typeof(Builder_Main), "currentElementIndex");

		private static readonly FieldInfo? MainCurrentPropIndexField = Field(typeof(Builder_Main), "currentPropIndex");

		private static readonly FieldInfo? MainCurrentTabIndexField = Field(typeof(Builder_Main), "currentTabIndex");

		private static readonly FieldInfo? DecorationDummyField = Field(typeof(Builder_Decoration), "dummyOBJ");

		private static readonly FieldInfo? DecorationCurrentIndexField = Field(typeof(Builder_Decoration), "currentIndex");

		private ManualLogSource? logger;

		private AnyPlaceBuilderSettings? settings;

		public void Initialize(ManualLogSource pluginLogger, AnyPlaceBuilderSettings anyPlaceBuilderSettings)
		{
			logger = pluginLogger;
			settings = anyPlaceBuilderSettings;
		}

		private void Update()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			if (settings != null && settings.Enabled.Value && !settings.SuppressPlacePreviewInput && Input.GetKeyDown(settings.PlacePreviewKey.Value) && !TryPlaceFromMainBuilder() && !TryPlaceFromDecorationBuilder())
			{
				ManualLogSource? obj = logger;
				if (obj != null)
				{
					obj.LogWarning((object)"No active placeable preview was found. Open the builder and select an object first.");
				}
			}
		}

		private bool TryPlaceFromMainBuilder()
		{
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			Builder_Main val = Object.FindObjectOfType<Builder_Main>();
			if ((Object)(object)val == (Object)null || (Object)(object)val.canvasBuilderOBJ == (Object)null || !val.canvasBuilderOBJ.activeInHierarchy)
			{
				return false;
			}
			GameObject fieldValue = GetFieldValue<GameObject>(MainDummyField, val);
			if ((Object)(object)fieldValue == (Object)null)
			{
				return false;
			}
			if (GetFieldValue<int>(MainCurrentElementIndexField, val) <= 1)
			{
				ManualLogSource? obj = logger;
				if (obj != null)
				{
					obj.LogWarning((object)"Current builder mode is move/delete, not a new object placement.");
				}
				return true;
			}
			NetworkSpawner networkSpawner = GetNetworkSpawner();
			if ((Object)(object)networkSpawner == (Object)null)
			{
				ManualLogSource? obj2 = logger;
				if (obj2 != null)
				{
					obj2.LogWarning((object)"NetworkSpawner was not found. Load into a save before placing objects.");
				}
				return true;
			}
			int fieldValue2 = GetFieldValue<int>(MainCurrentPropIndexField, val);
			int fieldValue3 = GetFieldValue<int>(MainCurrentTabIndexField, val);
			Quaternion rotation = fieldValue.transform.rotation;
			Vector3 eulerAngles = ((Quaternion)(ref rotation)).eulerAngles;
			if (val.furnitureTabsIndexes != null && val.furnitureTabsIndexes.Contains(fieldValue3))
			{
				networkSpawner.CmdSpawn(fieldValue2, fieldValue.transform.position, eulerAngles);
				LogPlaced("Buildable", fieldValue2, fieldValue.transform);
				return true;
			}
			if (fieldValue3 == 2)
			{
				networkSpawner.CmdSpawnManufacturing(fieldValue2, fieldValue.transform.position, eulerAngles);
				LogPlaced("Manufacturing", fieldValue2, fieldValue.transform);
				return true;
			}
			networkSpawner.CmdSpawnDecoration(fieldValue2, fieldValue.transform.position, eulerAngles);
			LogPlaced("Decoration", fieldValue2, fieldValue.transform);
			return true;
		}

		private bool TryPlaceFromDecorationBuilder()
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			Builder_Decoration val = Object.FindObjectOfType<Builder_Decoration>();
			if ((Object)(object)val == (Object)null || !((Behaviour)val).isActiveAndEnabled)
			{
				return false;
			}
			GameObject fieldValue = GetFieldValue<GameObject>(DecorationDummyField, val);
			int fieldValue2 = GetFieldValue<int>(DecorationCurrentIndexField, val);
			if ((Object)(object)fieldValue == (Object)null || fieldValue2 <= 0)
			{
				return false;
			}
			NetworkSpawner networkSpawner = GetNetworkSpawner();
			if ((Object)(object)networkSpawner == (Object)null)
			{
				ManualLogSource? obj = logger;
				if (obj != null)
				{
					obj.LogWarning((object)"NetworkSpawner was not found. Load into a save before placing objects.");
				}
				return true;
			}
			Vector3 position = fieldValue.transform.position;
			Quaternion rotation = fieldValue.transform.rotation;
			networkSpawner.CmdSpawnDecoration(fieldValue2, position, ((Quaternion)(ref rotation)).eulerAngles);
			LogPlaced("Decoration", fieldValue2, fieldValue.transform);
			return true;
		}

		private void LogPlaced(string source, int prefabId, Transform transform)
		{
			//IL_0026: 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_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			ManualLogSource? obj = logger;
			if (obj != null)
			{
				object[] obj2 = new object[4]
				{
					source,
					prefabId,
					FormatVector(transform.position),
					null
				};
				Quaternion rotation = transform.rotation;
				obj2[3] = FormatVector(((Quaternion)(ref rotation)).eulerAngles);
				obj.LogInfo((object)string.Format("Placed {0} #{1} at {2} rot {3}.", obj2));
			}
		}

		private static NetworkSpawner? GetNetworkSpawner()
		{
			if (!((Object)(object)GameData.Instance != (Object)null))
			{
				return Object.FindObjectOfType<NetworkSpawner>();
			}
			return ((Component)GameData.Instance).GetComponent<NetworkSpawner>();
		}

		private static T GetFieldValue<T>(FieldInfo? field, object target)
		{
			if (field == null)
			{
				return default(T);
			}
			object value = field.GetValue(target);
			if (value is T)
			{
				return (T)value;
			}
			return default(T);
		}

		private static FieldInfo? Field(Type type, string name)
		{
			return type.GetField(name, BindingFlags.Instance | BindingFlags.NonPublic);
		}

		private static string FormatVector(Vector3 value)
		{
			//IL_0005: 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_001b: Unknown result type (might be due to invalid IL or missing references)
			return $"({value.x:0.###}, {value.y:0.###}, {value.z:0.###})";
		}
	}
	internal sealed class AnyPlaceBuilderSettings
	{
		public ConfigEntry<bool> Enabled { get; }

		public ConfigEntry<KeyCode> PlacePreviewKey { get; }

		public bool SuppressPlacePreviewInput { get; set; }

		public AnyPlaceBuilderSettings(ConfigEntry<bool> enabled, ConfigEntry<KeyCode> placePreviewKey)
		{
			Enabled = enabled;
			PlacePreviewKey = placePreviewKey;
		}
	}
}
namespace SupermarketTogetherTeleportMenu
{
	[Serializable]
	internal sealed class TeleportLocationData
	{
		public string Id = "";

		public string Name = "";

		public float X;

		public float Y;

		public float Z;

		public float Yaw;

		public KeyCode ShortcutKey;

		public Vector3 Position => new Vector3(X, Y, Z);

		public TeleportLocationData()
		{
		}

		public TeleportLocationData(string id, string name, Vector3 position, float yaw, KeyCode shortcutKey = (KeyCode)0)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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_0059: Unknown result type (might be due to invalid IL or missing references)
			Id = id;
			Name = name;
			X = position.x;
			Y = position.y;
			Z = position.z;
			Yaw = yaw;
			ShortcutKey = shortcutKey;
		}

		public TeleportLocationData WithName(string name)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			return new TeleportLocationData(Id, name, Position, Yaw, ShortcutKey);
		}

		public TeleportLocationData WithShortcutKey(KeyCode shortcutKey)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			return new TeleportLocationData(Id, Name, Position, Yaw, shortcutKey);
		}
	}
	[Serializable]
	internal sealed class TeleportLocationCollection
	{
		public List<TeleportLocationData> Locations = new List<TeleportLocationData>();
	}
	internal sealed class TeleportLocationStorage
	{
		private readonly string filePath;

		private readonly ManualLogSource logger;

		public TeleportLocationStorage(string configPath, ManualLogSource pluginLogger)
		{
			filePath = Path.Combine(configPath, "uta_a.supermarkettogether.teleportmenu.locations.json");
			logger = pluginLogger;
		}

		public List<TeleportLocationData> Load()
		{
			if (!File.Exists(filePath))
			{
				return new List<TeleportLocationData>();
			}
			try
			{
				string text = File.ReadAllText(filePath);
				if (string.IsNullOrWhiteSpace(text))
				{
					return new List<TeleportLocationData>();
				}
				return JsonUtility.FromJson<TeleportLocationCollection>(text)?.Locations ?? new List<TeleportLocationData>();
			}
			catch (Exception ex)
			{
				logger.LogError((object)("Failed to load teleport locations: " + ex.Message));
				return new List<TeleportLocationData>();
			}
		}

		public void Save(IReadOnlyList<TeleportLocationData> locations)
		{
			try
			{
				Directory.CreateDirectory(Path.GetDirectoryName(filePath) ?? ".");
				string contents = JsonUtility.ToJson((object)new TeleportLocationCollection
				{
					Locations = new List<TeleportLocationData>(locations)
				}, true);
				File.WriteAllText(filePath, contents);
			}
			catch (Exception ex)
			{
				logger.LogError((object)("Failed to save teleport locations: " + ex.Message));
			}
		}
	}
	internal sealed class TeleportMenu : MonoBehaviour
	{
		private enum TeleportTab
		{
			Locations,
			Players,
			LookTeleport
		}

		private enum ShortcutTargetKind
		{
			None,
			Location,
			Player,
			LookTeleport
		}

		private sealed class RowDraft
		{
			public string Name { get; set; }

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

		private const string WindowTitle = "Teleport Menu";

		private const string LocalPlayerObjectName = "LocalGamePlayer";

		private const float ButtonHeight = 28f;

		private const float HeaderDragHeight = 34f;

		private const float SmallButtonWidth = 64f;

		private const float MediumButtonWidth = 84f;

		private const float PlayerOffsetDistance = 1.5f;

		private const float LookTeleportMaxDistance = 1000f;

		private const float LookTeleportSurfaceOffset = 0.15f;

		private const int DefaultMaxLocations = 20;

		private static readonly KeyCode[] ShortcutKeyCandidates = Enum.GetValues(typeof(KeyCode)).Cast<KeyCode>().Where(IsAllowedShortcutKey)
			.ToArray();

		private readonly List<TeleportLocationData> locations = new List<TeleportLocationData>();

		private readonly List<PlayerShortcutData> playerShortcuts = new List<PlayerShortcutData>();

		private readonly Dictionary<string, RowDraft> drafts = new Dictionary<string, RowDraft>();

		private ManualLogSource? logger;

		private TeleportMenuSettings? settings;

		private TeleportLocationStorage? locationStorage;

		private TeleportShortcutStorage? shortcutStorage;

		private FirstPersonController? cachedFirstPersonController;

		private PlayerObjectController? cachedLocalPlayer;

		private Vector2 locationScrollPosition;

		private Vector2 playerScrollPosition;

		private TeleportTab activeTab;

		private ShortcutTargetKind listeningKind;

		private string listeningTargetId = "";

		private string listeningTargetName = "";

		private string newLocationName = "";

		private KeyCode lookTeleportKey;

		private string statusMessage = "Load into a save, then save your current position.";

		public void Initialize(ManualLogSource pluginLogger, TeleportMenuSettings menuSettings, string configPath)
		{
			//IL_0072: 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)
			logger = pluginLogger;
			settings = menuSettings;
			locationStorage = new TeleportLocationStorage(configPath, pluginLogger);
			shortcutStorage = new TeleportShortcutStorage(configPath, pluginLogger);
			locations.AddRange(NormalizeLoadedLocations(locationStorage.Load()).Take(GetMaxLocations()));
			TeleportShortcutCollection teleportShortcutCollection = shortcutStorage.Load();
			playerShortcuts.AddRange(NormalizeLoadedPlayerShortcuts(teleportShortcutCollection.PlayerShortcuts));
			lookTeleportKey = (KeyCode)(IsAllowedShortcutKey(teleportShortcutCollection.LookTeleportKey) ? ((int)teleportShortcutCollection.LookTeleportKey) : 0);
			EnforceGlobalShortcutUniqueness();
			RebuildDrafts();
		}

		internal void ShowPanel()
		{
			RefreshPlayerReferences();
			RebuildDrafts();
		}

		private void Update()
		{
			if (settings != null && (listeningKind == ShortcutTargetKind.None || !TryCaptureShortcutKey()) && settings.ShortcutsEnabled.Value)
			{
				HandleShortcuts();
			}
		}

		internal void DrawPanel(float availableHeight)
		{
			GUILayout.Label("Teleport Menu", Array.Empty<GUILayoutOption>());
			GUILayout.Space(8f);
			DrawTabs();
			GUILayout.Space(8f);
			switch (activeTab)
			{
			case TeleportTab.Locations:
				DrawLocationsTab(availableHeight);
				break;
			case TeleportTab.Players:
				DrawPlayersTab(availableHeight);
				break;
			case TeleportTab.LookTeleport:
				DrawLookTeleportTab();
				break;
			}
			GUILayout.Space(8f);
			GUILayout.Label(statusMessage, Array.Empty<GUILayoutOption>());
		}

		private void DrawTabs()
		{
			GUILayout.BeginVertical(GUIStyle.op_Implicit("box"), Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			DrawTabButton(TeleportTab.Locations, "Locations");
			DrawTabButton(TeleportTab.Players, "Players");
			DrawTabButton(TeleportTab.LookTeleport, "Look TP");
			GUILayout.FlexibleSpace();
			GUILayout.EndHorizontal();
			GUILayout.EndVertical();
		}

		private void DrawTabButton(TeleportTab tab, string label)
		{
			GUI.enabled = activeTab != tab;
			if (GUILayout.Button(label, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(120f),
				GUILayout.Height(32f)
			}))
			{
				activeTab = tab;
			}
			GUI.enabled = true;
		}

		private void DrawLocationsTab(float availableHeight)
		{
			DrawSaveCurrentSection();
			GUILayout.Space(10f);
			GUILayout.Label($"Saved locations: {locations.Count}/{GetMaxLocations()}", Array.Empty<GUILayoutOption>());
			DrawLocationRows(Mathf.Max(180f, availableHeight - 130f));
		}

		private void DrawPlayersTab(float availableHeight)
		{
			//IL_0011: 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)
			GUILayout.Label("Players", Array.Empty<GUILayoutOption>());
			playerScrollPosition = GUILayout.BeginScrollView(playerScrollPosition, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(Mathf.Max(180f, availableHeight - 80f)) });
			DrawPlayerRows();
			GUILayout.EndScrollView();
		}

		private void DrawLookTeleportTab()
		{
			GUILayout.Label("Teleport to the point you are looking at.", Array.Empty<GUILayoutOption>());
			GUILayout.Space(8f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label(GetLookTeleportShortcutLabel(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(120f) });
			if (GUILayout.Button("Set", (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(64f),
				GUILayout.Height(28f)
			}))
			{
				BeginListening(ShortcutTargetKind.LookTeleport, "", "Look TP");
			}
			if (GUILayout.Button("Clear", (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(64f),
				GUILayout.Height(28f)
			}))
			{
				SetLookTeleportShortcut((KeyCode)0);
			}
			if (GUILayout.Button("TP", (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(64f),
				GUILayout.Height(28f)
			}))
			{
				TeleportToLookPoint();
			}
			GUILayout.EndHorizontal();
		}

		private void DrawSaveCurrentSection()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			FirstPersonController firstPersonController = GetFirstPersonController();
			string text = (((Object)(object)firstPersonController != (Object)null) ? FormatPosition(((Component)firstPersonController).transform.position) : "(player not found)");
			GUILayout.Label("Current position: " + text, Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("Name", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(44f) });
			newLocationName = GUILayout.TextField(newLocationName, 32, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(200f) });
			if (GUILayout.Button("Save Current", (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(120f),
				GUILayout.Height(28f)
			}))
			{
				SaveCurrentLocation();
			}
			GUILayout.EndHorizontal();
		}

		private void DrawLocationRows(float scrollHeight)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			locationScrollPosition = GUILayout.BeginScrollView(locationScrollPosition, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(scrollHeight) });
			foreach (TeleportLocationData item in locations.ToList())
			{
				if (!drafts.TryGetValue(item.Id, out RowDraft value))
				{
					value = new RowDraft(item.Name);
					drafts[item.Id] = value;
				}
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				value.Name = GUILayout.TextField(value.Name, 32, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(170f) });
				GUILayout.Label(FormatLocation(item), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(190f) });
				GUILayout.Label(GetShortcutLabel(item.ShortcutKey), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) });
				if (GUILayout.Button("Set", (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(64f),
					GUILayout.Height(28f)
				}))
				{
					BeginListening(ShortcutTargetKind.Location, item.Id, item.Name);
				}
				if (GUILayout.Button("Clear", (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(64f),
					GUILayout.Height(28f)
				}))
				{
					SetLocationShortcut(item.Id, (KeyCode)0);
				}
				if (GUILayout.Button("Save", (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(64f),
					GUILayout.Height(28f)
				}))
				{
					SaveRow(item, value);
				}
				if (GUILayout.Button("TP", (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(64f),
					GUILayout.Height(28f)
				}))
				{
					TeleportTo(item);
				}
				if (GUILayout.Button("Delete", (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(84f),
					GUILayout.Height(28f)
				}))
				{
					DeleteLocation(item);
				}
				GUILayout.EndHorizontal();
			}
			GUILayout.EndScrollView();
		}

		private void DrawPlayerRows()
		{
			//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_009d: 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_0112: Invalid comparison between Unknown and I4
			IReadOnlyList<PlayerObjectController> players = GetPlayers();
			if (players.Count == 0)
			{
				GUILayout.Label("(no players found)", Array.Empty<GUILayoutOption>());
				return;
			}
			PlayerObjectController localPlayer = GetLocalPlayer();
			foreach (PlayerObjectController item in players)
			{
				if (!((Object)(object)item == (Object)null))
				{
					string playerId = GetPlayerId(item);
					string text = GetPlayerDisplayName(item);
					KeyCode playerShortcutKey = GetPlayerShortcutKey(playerId);
					bool flag = (Object)(object)item == (Object)(object)localPlayer;
					if (flag)
					{
						text += " (self)";
					}
					GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
					GUILayout.Label(text, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(180f) });
					GUILayout.Label(GetShortcutLabel(playerShortcutKey), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) });
					GUI.enabled = !flag;
					if (GUILayout.Button("Set", (GUILayoutOption[])(object)new GUILayoutOption[2]
					{
						GUILayout.Width(64f),
						GUILayout.Height(28f)
					}))
					{
						BeginListening(ShortcutTargetKind.Player, playerId, text);
						UpsertPlayerShortcutName(playerId, GetPlayerDisplayName(item));
					}
					GUI.enabled = !flag || (int)playerShortcutKey > 0;
					if (GUILayout.Button("Clear", (GUILayoutOption[])(object)new GUILayoutOption[2]
					{
						GUILayout.Width(64f),
						GUILayout.Height(28f)
					}))
					{
						SetPlayerShortcut(playerId, GetPlayerDisplayName(item), (KeyCode)0);
					}
					GUI.enabled = !flag;
					if (GUILayout.Button("TP To", (GUILayoutOption[])(object)new GUILayoutOption[2]
					{
						GUILayout.Width(84f),
						GUILayout.Height(28f)
					}))
					{
						TeleportSelfToPlayer(item);
					}
					if (GUILayout.Button("Bring", (GUILayoutOption[])(object)new GUILayoutOption[2]
					{
						GUILayout.Width(84f),
						GUILayout.Height(28f)
					}))
					{
						TeleportPlayerToSelf(item);
					}
					GUI.enabled = true;
					GUILayout.EndHorizontal();
				}
			}
		}

		private void SaveCurrentLocation()
		{
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			FirstPersonController firstPersonController = GetFirstPersonController();
			if ((Object)(object)firstPersonController == (Object)null)
			{
				statusMessage = "Player controller was not found. Load into a save first.";
				ManualLogSource? obj = logger;
				if (obj != null)
				{
					obj.LogWarning((object)statusMessage);
				}
				return;
			}
			if (locations.Count >= GetMaxLocations())
			{
				statusMessage = $"Cannot save more than {GetMaxLocations()} locations.";
				return;
			}
			string name = (string.IsNullOrWhiteSpace(newLocationName) ? $"Point {locations.Count + 1}" : newLocationName.Trim());
			string id = Guid.NewGuid().ToString("N");
			Vector3 position = ((Component)firstPersonController).transform.position;
			Quaternion rotation = ((Component)firstPersonController).transform.rotation;
			TeleportLocationData teleportLocationData = new TeleportLocationData(id, name, position, ((Quaternion)(ref rotation)).eulerAngles.y, (KeyCode)0);
			locations.Add(teleportLocationData);
			drafts[teleportLocationData.Id] = new RowDraft(teleportLocationData.Name);
			SaveLocations();
			newLocationName = "";
			statusMessage = "Saved location: " + teleportLocationData.Name;
			ManualLogSource? obj2 = logger;
			if (obj2 != null)
			{
				obj2.LogInfo((object)statusMessage);
			}
		}

		private void SaveRow(TeleportLocationData location, RowDraft draft)
		{
			string text = draft.Name.Trim();
			if (string.IsNullOrWhiteSpace(text))
			{
				statusMessage = "Name cannot be empty. Example: Storage";
				return;
			}
			int num = locations.FindIndex((TeleportLocationData item) => item.Id == location.Id);
			if (num < 0)
			{
				statusMessage = "Location was not found.";
				return;
			}
			TeleportLocationData teleportLocationData = location.WithName(text);
			locations[num] = teleportLocationData;
			drafts[teleportLocationData.Id] = new RowDraft(teleportLocationData.Name);
			SaveLocations();
			statusMessage = "Saved changes: " + teleportLocationData.Name;
		}

		private void DeleteLocation(TeleportLocationData location)
		{
			locations.RemoveAll((TeleportLocationData item) => item.Id == location.Id);
			drafts.Remove(location.Id);
			SaveLocations();
			statusMessage = "Deleted location: " + location.Name;
		}

		private void TeleportTo(TeleportLocationData location)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			FirstPersonController firstPersonController = GetFirstPersonController();
			if ((Object)(object)firstPersonController == (Object)null)
			{
				statusMessage = "Player controller was not found. Load into a save first.";
				ManualLogSource? obj = logger;
				if (obj != null)
				{
					obj.LogWarning((object)statusMessage);
				}
				return;
			}
			MoveTransform(((Component)firstPersonController).transform, location.Position, Quaternion.Euler(0f, location.Yaw, 0f));
			statusMessage = "Teleported to: " + location.Name;
			ManualLogSource? obj2 = logger;
			if (obj2 != null)
			{
				obj2.LogInfo((object)statusMessage);
			}
		}

		private void TeleportSelfToPlayer(PlayerObjectController targetPlayer)
		{
			//IL_0022: 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_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			FirstPersonController firstPersonController = GetFirstPersonController();
			if ((Object)(object)firstPersonController == (Object)null)
			{
				statusMessage = "Player controller was not found.";
				return;
			}
			Vector3 destination = ((Component)targetPlayer).transform.position - ((Component)targetPlayer).transform.forward * 1.5f;
			MoveTransform(((Component)firstPersonController).transform, destination, ((Component)firstPersonController).transform.rotation);
			statusMessage = "Teleported to " + GetPlayerDisplayName(targetPlayer) + ".";
			ManualLogSource? obj = logger;
			if (obj != null)
			{
				obj.LogInfo((object)statusMessage);
			}
		}

		private void TeleportPlayerToSelf(PlayerObjectController targetPlayer)
		{
			//IL_0022: 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_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			PlayerObjectController localPlayer = GetLocalPlayer();
			if ((Object)(object)localPlayer == (Object)null)
			{
				statusMessage = "Local player was not found.";
				return;
			}
			Vector3 destination = ((Component)localPlayer).transform.position + ((Component)localPlayer).transform.forward * 1.5f;
			MoveTransform(((Component)targetPlayer).transform, destination, ((Component)targetPlayer).transform.rotation);
			statusMessage = "Teleported " + GetPlayerDisplayName(targetPlayer) + " to you.";
			ManualLogSource? obj = logger;
			if (obj != null)
			{
				obj.LogInfo((object)statusMessage);
			}
		}

		private void TeleportToLookPoint()
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: 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_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: 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_0094: Unknown result type (might be due to invalid IL or missing references)
			FirstPersonController firstPersonController = GetFirstPersonController();
			if ((Object)(object)firstPersonController == (Object)null)
			{
				statusMessage = "Player controller was not found. Load into a save first.";
				return;
			}
			Camera main = Camera.main;
			if ((Object)(object)main == (Object)null)
			{
				statusMessage = "Main camera was not found.";
				return;
			}
			Transform transform = ((Component)main).transform;
			RaycastHit val = default(RaycastHit);
			if (!Physics.Raycast(transform.position, transform.forward, ref val, 1000f, -5, (QueryTriggerInteraction)1))
			{
				statusMessage = "No surface found in view.";
				return;
			}
			Vector3 destination = ((RaycastHit)(ref val)).point + ((RaycastHit)(ref val)).normal * 0.15f;
			MoveTransform(((Component)firstPersonController).transform, destination, ((Component)firstPersonController).transform.rotation);
			statusMessage = "Teleported to look point.";
			ManualLogSource? obj = logger;
			if (obj != null)
			{
				obj.LogInfo((object)statusMessage);
			}
		}

		private void HandleShortcuts()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: 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_0101: Unknown result type (might be due to invalid IL or missing references)
			foreach (TeleportLocationData location in locations)
			{
				if ((int)location.ShortcutKey != 0 && Input.GetKeyDown(location.ShortcutKey))
				{
					TeleportTo(location);
					return;
				}
			}
			foreach (PlayerShortcutData playerShortcut in playerShortcuts)
			{
				if ((int)playerShortcut.ShortcutKey != 0 && Input.GetKeyDown(playerShortcut.ShortcutKey))
				{
					PlayerObjectController val = FindPlayerById(playerShortcut.PlayerId);
					if ((Object)(object)val == (Object)null)
					{
						statusMessage = "Player is not online: " + playerShortcut.PlayerName;
					}
					else if ((Object)(object)val == (Object)(object)GetLocalPlayer())
					{
						statusMessage = "Shortcut points to yourself: " + playerShortcut.PlayerName;
					}
					else
					{
						TeleportSelfToPlayer(val);
					}
					return;
				}
			}
			if ((int)lookTeleportKey != 0 && Input.GetKeyDown(lookTeleportKey))
			{
				TeleportToLookPoint();
			}
		}

		private bool TryCaptureShortcutKey()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			if (settings != null && Input.GetKeyDown(settings.ToggleMenuKey.Value))
			{
				statusMessage = $"{settings.ToggleMenuKey.Value} is reserved for the menu.";
				return true;
			}
			if (Input.GetKeyDown((KeyCode)27))
			{
				ClearListening();
				statusMessage = "Shortcut setup cancelled.";
				return true;
			}
			KeyCode[] shortcutKeyCandidates = ShortcutKeyCandidates;
			foreach (KeyCode val in shortcutKeyCandidates)
			{
				if (Input.GetKeyDown(val))
				{
					ApplyCapturedShortcut(val);
					ClearListening();
					return true;
				}
			}
			return false;
		}

		private void ApplyCapturedShortcut(KeyCode shortcutKey)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			switch (listeningKind)
			{
			case ShortcutTargetKind.Location:
				SetLocationShortcut(listeningTargetId, shortcutKey);
				break;
			case ShortcutTargetKind.Player:
				SetPlayerShortcut(listeningTargetId, listeningTargetName, shortcutKey);
				break;
			case ShortcutTargetKind.LookTeleport:
				SetLookTeleportShortcut(shortcutKey);
				break;
			}
		}

		private void SetLocationShortcut(string locationId, KeyCode shortcutKey)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			int num = locations.FindIndex((TeleportLocationData location) => location.Id == locationId);
			if (num < 0)
			{
				statusMessage = "Location was not found.";
				return;
			}
			if ((int)shortcutKey != 0)
			{
				ClearShortcutKeyFromOtherActions(shortcutKey, ShortcutTargetKind.Location, locationId);
			}
			TeleportLocationData teleportLocationData = locations[num];
			locations[num] = teleportLocationData.WithShortcutKey(shortcutKey);
			SaveLocations();
			SaveShortcuts();
			statusMessage = (((int)shortcutKey == 0) ? ("Cleared shortcut: " + teleportLocationData.Name) : $"Set shortcut {shortcutKey}: {teleportLocationData.Name}");
		}

		private void SetPlayerShortcut(string playerId, string playerName, KeyCode shortcutKey)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrWhiteSpace(playerId))
			{
				statusMessage = "Player was not found.";
				return;
			}
			if ((int)shortcutKey != 0)
			{
				ClearShortcutKeyFromOtherActions(shortcutKey, ShortcutTargetKind.Player, playerId);
			}
			int num = playerShortcuts.FindIndex((PlayerShortcutData shortcut) => shortcut.PlayerId == playerId);
			if ((int)shortcutKey == 0)
			{
				if (num >= 0)
				{
					playerShortcuts.RemoveAt(num);
				}
				SaveShortcuts();
				statusMessage = "Cleared shortcut: " + playerName;
			}
			else
			{
				if (num >= 0)
				{
					playerShortcuts[num] = new PlayerShortcutData(playerId, playerName, shortcutKey);
				}
				else
				{
					playerShortcuts.Add(new PlayerShortcutData(playerId, playerName, shortcutKey));
				}
				SaveShortcuts();
				statusMessage = $"Set shortcut {shortcutKey}: {playerName}";
			}
		}

		private void SetLookTeleportShortcut(KeyCode shortcutKey)
		{
			//IL_0000: 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_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			if ((int)shortcutKey != 0)
			{
				ClearShortcutKeyFromOtherActions(shortcutKey, ShortcutTargetKind.LookTeleport, "");
			}
			lookTeleportKey = shortcutKey;
			SaveLocations();
			SaveShortcuts();
			statusMessage = (((int)shortcutKey == 0) ? "Cleared shortcut: Look TP" : $"Set shortcut {shortcutKey}: Look TP");
		}

		private void ClearShortcutKeyFromOtherActions(KeyCode shortcutKey, ShortcutTargetKind exceptKind, string exceptId)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < locations.Count; i++)
			{
				TeleportLocationData teleportLocationData = locations[i];
				if ((exceptKind != ShortcutTargetKind.Location || !(teleportLocationData.Id == exceptId)) && teleportLocationData.ShortcutKey == shortcutKey)
				{
					locations[i] = teleportLocationData.WithShortcutKey((KeyCode)0);
				}
			}
			for (int j = 0; j < playerShortcuts.Count; j++)
			{
				PlayerShortcutData playerShortcutData = playerShortcuts[j];
				if ((exceptKind != ShortcutTargetKind.Player || !(playerShortcutData.PlayerId == exceptId)) && playerShortcutData.ShortcutKey == shortcutKey)
				{
					playerShortcuts[j] = new PlayerShortcutData(playerShortcutData.PlayerId, playerShortcutData.PlayerName, (KeyCode)0);
				}
			}
			playerShortcuts.RemoveAll((PlayerShortcutData shortcut) => (int)shortcut.ShortcutKey == 0);
			if (exceptKind != ShortcutTargetKind.LookTeleport && lookTeleportKey == shortcutKey)
			{
				lookTeleportKey = (KeyCode)0;
			}
		}

		private void EnforceGlobalShortcutUniqueness()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: 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_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			HashSet<KeyCode> hashSet = new HashSet<KeyCode>();
			bool flag = false;
			for (int i = 0; i < locations.Count; i++)
			{
				TeleportLocationData teleportLocationData = locations[i];
				if ((int)teleportLocationData.ShortcutKey != 0 && !hashSet.Add(teleportLocationData.ShortcutKey))
				{
					locations[i] = teleportLocationData.WithShortcutKey((KeyCode)0);
					flag = true;
				}
			}
			for (int j = 0; j < playerShortcuts.Count; j++)
			{
				PlayerShortcutData playerShortcutData = playerShortcuts[j];
				if ((int)playerShortcutData.ShortcutKey != 0 && !hashSet.Add(playerShortcutData.ShortcutKey))
				{
					playerShortcuts[j] = new PlayerShortcutData(playerShortcutData.PlayerId, playerShortcutData.PlayerName, (KeyCode)0);
					flag = true;
				}
			}
			playerShortcuts.RemoveAll((PlayerShortcutData shortcut) => (int)shortcut.ShortcutKey == 0);
			if ((int)lookTeleportKey != 0 && !hashSet.Add(lookTeleportKey))
			{
				lookTeleportKey = (KeyCode)0;
				flag = true;
			}
			if (flag)
			{
				SaveLocations();
				SaveShortcuts();
			}
		}

		private void BeginListening(ShortcutTargetKind kind, string targetId, string targetName)
		{
			listeningKind = kind;
			listeningTargetId = targetId;
			listeningTargetName = targetName;
			statusMessage = "Press a key for: " + targetName + ". Esc cancels.";
		}

		private void ClearListening()
		{
			listeningKind = ShortcutTargetKind.None;
			listeningTargetId = "";
			listeningTargetName = "";
		}

		private void UpsertPlayerShortcutName(string playerId, string playerName)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			int num = playerShortcuts.FindIndex((PlayerShortcutData shortcut) => shortcut.PlayerId == playerId);
			if (num >= 0)
			{
				PlayerShortcutData playerShortcutData = playerShortcuts[num];
				playerShortcuts[num] = new PlayerShortcutData(playerId, playerName, playerShortcutData.ShortcutKey);
				SaveShortcuts();
			}
		}

		private void SaveL