Decompiled source of Fishing Chairs Mod v0.1.2

BepInEx/plugins/FishingChairsMod/FishingChairsMod.dll

Decompiled 2 weeks 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.Text;
using BepInEx;
using FishNet;
using FishNet.Broadcast;
using FishNet.Connection;
using FishNet.Managing;
using FishNet.Managing.Object;
using FishNet.Object;
using FishNet.Serializing;
using FishNet.Transporting;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace FishingChairsMod
{
	public static class Rules
	{
		public static readonly byte[] ItemIds = new byte[3] { 252, 253, 254 };

		public static readonly ushort[] PrefabCollections = new ushort[3] { 42437, 42438, 42439 };

		public static readonly int[] Prices = new int[3] { 250, 500, 750 };

		public const float UseRange = 4f;

		public const float VendorRange = 5f;

		public const float VendorLookDot = 0.72f;

		public const float DeployRange = 8f;

		public const float HoldSeconds = 0.8f;

		public static bool Finite(float value)
		{
			if (!float.IsNaN(value))
			{
				return !float.IsInfinity(value);
			}
			return false;
		}

		public static bool SurfaceAllowed(float normalY)
		{
			if (Finite(normalY))
			{
				return normalY >= 0.65f;
			}
			return false;
		}

		public static bool CanPickUp(bool freeSlot, bool emptyHands)
		{
			return freeSlot || emptyHands;
		}

		public static bool CanUseVendor(float distance, float lookDot)
		{
			if (Finite(distance) && Finite(lookDot) && distance <= 5.35f)
			{
				return lookDot >= 0.72f;
			}
			return false;
		}
	}
	[Serializable]
	public sealed class ChairData
	{
		public int serial;

		public int kind;

		public ulong owner;

		public ulong occupant;

		public string ownerName;

		public bool deployed;

		public bool available = true;

		public Vector3 position;

		public Vector3 surfaceNormal = Vector3.up;

		public float yaw;

		public Quaternion Rotation => Quaternion.FromToRotation(Vector3.up, (((Vector3)(ref surfaceNormal)).sqrMagnitude > 0.01f) ? surfaceNormal : Vector3.up) * Quaternion.Euler(0f, yaw, 0f);

		public Vector3 SeatPosition => position + Rotation * ((kind == 2) ? new Vector3(0f, 1.45f, 0.02f) : ((kind == 1) ? new Vector3(0f, 0.4f, 0f) : new Vector3(0f, 0.5f, 0f)));
	}
	[Serializable]
	public sealed class WorldData
	{
		public string name;

		public List<ChairData> chairs = new List<ChairData>();
	}
	[Serializable]
	public sealed class SaveData
	{
		public int version = 1;

		public int nextSerial = 1;

		public List<WorldData> worlds = new List<WorldData>();
	}
	[Serializable]
	public sealed class Command
	{
		public int protocol = 1;

		public int sequence;

		public int serial;

		public int kind;

		public string action;

		public Vector3 position;

		public Vector3 normal;
	}
	[Serializable]
	public sealed class Snapshot
	{
		public int protocol = 1;

		public string world;

		public List<ChairData> chairs = new List<ChairData>();
	}
	[Serializable]
	public sealed class Reply
	{
		public int sequence;

		public int serial;

		public string message;
	}
	public struct RequestMessage : IBroadcast
	{
		public string json;
	}
	public struct StateMessage : IBroadcast
	{
		public string json;
	}
	public struct ReplyMessage : IBroadcast
	{
		public string json;
	}
	public static class Codec
	{
		private sealed class Fields : DefaultContractResolver
		{
			protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization mode)
			{
				return (from f in type.GetFields(BindingFlags.Instance | BindingFlags.Public)
					where !f.IsNotSerialized
					select ((DefaultContractResolver)this).CreateProperty((MemberInfo)f, (MemberSerialization)2)).ToList();
			}
		}

		private static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
		{
			ContractResolver = (IContractResolver)(object)new Fields(),
			TypeNameHandling = (TypeNameHandling)0,
			ObjectCreationHandling = (ObjectCreationHandling)2,
			MaxDepth = 24
		};

		public static string ToJson(object value, bool pretty = false)
		{
			return JsonConvert.SerializeObject(value, (Formatting)(pretty ? 1 : 0), Settings);
		}

		public static T FromJson<T>(string json)
		{
			return JsonConvert.DeserializeObject<T>(json, Settings);
		}
	}
	public static class ChairItem
	{
		public static readonly Item[] Prefabs = (Item[])(object)new Item[3];

		private static GameObject storage;

		public static bool Ready => Prefabs.All((Item p) => (Object)(object)p != (Object)null);

		public static int Kind(Item item)
		{
			if (!((Object)(object)item == (Object)null))
			{
				return Array.IndexOf(Rules.ItemIds, item.ID);
			}
			return -1;
		}

		public static bool Is(Item item)
		{
			if (Kind(item) >= 0)
			{
				return (Object)(object)((Component)item).GetComponent<ChairVisual>() != (Object)null;
			}
			return false;
		}

		public static int Serial(Item item)
		{
			if (!Is(item))
			{
				return 0;
			}
			return Mathf.RoundToInt(item.BettingMultiplier);
		}

		public static string Name(int kind)
		{
			return kind switch
			{
				1 => "Lawn Chair", 
				0 => "Fishing Stool", 
				_ => "Perch Chair", 
			};
		}

		public static void Register()
		{
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Expected O, but got Unknown
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0363: Unknown result type (might be due to invalid IL or missing references)
			//IL_0368: Unknown result type (might be due to invalid IL or missing references)
			//IL_0393: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b7: Expected O, but got Unknown
			//IL_03db: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0617: Unknown result type (might be due to invalid IL or missing references)
			//IL_050b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0429: Unknown result type (might be due to invalid IL or missing references)
			//IL_0444: Unknown result type (might be due to invalid IL or missing references)
			if (Ready || (Object)(object)InstanceFinder.NetworkManager == (Object)null)
			{
				return;
			}
			Dictionary<byte, Item> dictionary = (Dictionary<byte, Item>)AccessTools.Field(typeof(GameInfo), "_idToSpawnable").GetValue(null);
			if (dictionary.Count == 0)
			{
				return;
			}
			Item val = (from i in dictionary.Values
				where (Object)(object)i != (Object)null && ((object)i).GetType() == typeof(Item) && (Object)(object)((Component)i).GetComponent<NetworkObject>() != (Object)null
				orderby i.ID
				select i).FirstOrDefault();
			if ((Object)(object)val == (Object)null)
			{
				throw new Exception("No compatible base item prefab found.");
			}
			Dictionary<byte, Item> dictionary2 = (Dictionary<byte, Item>)AccessTools.Field(typeof(GameInfo), "_allItems").GetValue(null);
			byte[] itemIds = Rules.ItemIds;
			for (int num = 0; num < itemIds.Length; num++)
			{
				byte key = itemIds[num];
				if (dictionary.ContainsKey(key) || dictionary2.ContainsKey(key))
				{
					throw new Exception("Fishing Chairs item ID " + key + " is occupied.");
				}
			}
			for (int num2 = 0; num2 < 3; num2++)
			{
				if (InstanceFinder.NetworkManager.GetPrefabObjects<SinglePrefabObjects>(Rules.PrefabCollections[num2], true).GetObjectCount() != 0)
				{
					throw new Exception("Fishing Chairs prefab collection " + Rules.PrefabCollections[num2] + " is occupied.");
				}
			}
			storage = new GameObject("Fishing Chairs prefabs");
			storage.SetActive(false);
			Object.DontDestroyOnLoad((Object)(object)storage);
			for (int num3 = 0; num3 < 3; num3++)
			{
				Item val2 = Object.Instantiate<Item>(val, storage.transform);
				((Object)val2).name = Name(num3);
				AccessTools.Field(typeof(Item), "_id").SetValue(val2, Rules.ItemIds[num3]);
				AccessTools.Field(typeof(Item), "_cost").SetValue(val2, Rules.Prices[num3]);
				AccessTools.Field(typeof(Item), "_worth").SetValue(val2, Rules.Prices[num3] / 2);
				AccessTools.Field(typeof(Item), "_ignoredBySeagulls").SetValue(val2, true);
				AccessTools.Field(typeof(Item), "_ignoredByMoneyNPC").SetValue(val2, false);
				AccessTools.Field(typeof(Item), "_ignoredByCloseDots").SetValue(val2, false);
				AccessTools.Field(typeof(Item), "_heldPos").SetValue(val2, (object)new Vector3(0.2f, -0.48f, 0.78f));
				AccessTools.Field(typeof(Item), "_heldRot").SetValue(val2, (object)new Vector3(8f, 12f, 0f));
				Renderer[] componentsInChildren = ((Component)val2).GetComponentsInChildren<Renderer>(true);
				for (int num = 0; num < componentsInChildren.Length; num++)
				{
					componentsInChildren[num].enabled = false;
				}
				Collider[] componentsInChildren2 = ((Component)val2).GetComponentsInChildren<Collider>(true);
				foreach (Collider val3 in componentsInChildren2)
				{
					if (!val3.isTrigger)
					{
						val3.enabled = false;
					}
				}
				List<Collider> list = new List<Collider>();
				if (num3 == 2)
				{
					GameObject val4 = new GameObject("PerchPostCollider");
					val4.transform.SetParent(((Component)val2).transform, false);
					BoxCollider val5 = val4.AddComponent<BoxCollider>();
					val5.center = new Vector3(0f, 0.53f, 0f);
					val5.size = new Vector3(0.26f, 1.06f, 0.26f);
					list.Add((Collider)(object)val5);
				}
				else
				{
					for (int num4 = -1; num4 <= 1; num4 += 2)
					{
						for (int num5 = -1; num5 <= 1; num5 += 2)
						{
							GameObject val6 = new GameObject("ChairLegCollider");
							val6.transform.SetParent(((Component)val2).transform, false);
							BoxCollider val7 = val6.AddComponent<BoxCollider>();
							val7.center = new Vector3((float)num4 * ((num3 == 0) ? 0.38f : 0.53f), 0.25f, (float)num5 * ((num3 == 0) ? 0.35f : 0.43f));
							val7.size = new Vector3(0.12f, 0.5f, 0.12f);
							list.Add((Collider)(object)val7);
						}
					}
				}
				AccessTools.Field(typeof(Item), "_worldColliders").SetValue(val2, list.ToArray());
				Collider val8 = (Collider)AccessTools.Field(typeof(Item), "_pickUpCollider").GetValue(val2);
				if ((Object)(object)val8 != (Object)null)
				{
					val8.isTrigger = true;
				}
				SphereCollider val9 = (SphereCollider)(object)((val8 is SphereCollider) ? val8 : null);
				if (val9 != null)
				{
					val9.radius = ((num3 == 2) ? 1.45f : 0.85f);
					val9.center = new Vector3(0f, (num3 == 2) ? 1.35f : 0.45f, 0f);
				}
				AccessTools.Field(typeof(Item), "_outOfHandHolder").SetValue(val2, null);
				AccessTools.Field(typeof(Item), "_inHandHolder").SetValue(val2, null);
				ChairVisual chairVisual = ((Component)val2).gameObject.AddComponent<ChairVisual>();
				chairVisual.Kind = num3;
				chairVisual.Build();
				AccessTools.Field(typeof(Item), "_mesh").SetValue(val2, chairVisual.InventoryMesh);
				AccessTools.Field(typeof(Item), "_inventoryMeshScale").SetValue(val2, (num3 == 2) ? 0.34f : 0.58f);
				AccessTools.Field(typeof(Item), "_inventoryMeshPos").SetValue(val2, (object)new Vector3(0f, -0.12f, 0f));
				AccessTools.Field(typeof(Item), "_inventoryMeshRot").SetValue(val2, (object)new Vector3(20f, 35f, 0f));
				AccessTools.Field(typeof(Item), "_renderers").SetValue(val2, (from r in ((Component)chairVisual).GetComponentsInChildren<Renderer>(true)
					where r.enabled
					select r).ToList());
				NetworkObject component = ((Component)val2).GetComponent<NetworkObject>();
				component.SetIsSpawnable(true);
				InstanceFinder.NetworkManager.GetPrefabObjects<SinglePrefabObjects>(Rules.PrefabCollections[num3], true).AddObject(component, false, true);
				dictionary.Add(Rules.ItemIds[num3], val2);
				((Dictionary<byte, Item>)AccessTools.Field(typeof(GameInfo), "_allItems").GetValue(null)).Add(Rules.ItemIds[num3], val2);
				((Dictionary<string, Item>)AccessTools.Field(typeof(GameInfo), "_nameToSpawnable").GetValue(null)).Add("fishingchairsmod" + num3, val2);
				Prefabs[num3] = val2;
			}
			Plugin.Log("Registered three Fishing Chairs items and network prefabs.");
		}
	}
	public sealed class ChairVisual : MonoBehaviour
	{
		public int Kind;

		public Mesh InventoryMesh;

		private Transform root;

		private static Material frame;

		private static Material dark;

		private static Material green;

		private static Material greenLight;

		private static Material wood;

		private static Material blue;

		private static Material cream;

		private static Material orange;

		private static Material Mat(Color c, float metallic = 0f)
		{
			//IL_0018: 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_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			Material val = new Material(Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Standard"))
			{
				color = c
			};
			if (val.HasProperty("_Metallic"))
			{
				val.SetFloat("_Metallic", metallic);
			}
			return val;
		}

		private static Transform Part(Transform p, string name, Vector3 pos, Vector3 size, Material material, Quaternion rot)
		{
			//IL_0020: 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)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = GameObject.CreatePrimitive((PrimitiveType)3);
			((Object)obj).name = name;
			obj.transform.SetParent(p, false);
			obj.transform.localPosition = pos;
			obj.transform.localRotation = rot;
			obj.transform.localScale = size;
			Object.DestroyImmediate((Object)(object)obj.GetComponent<Collider>());
			obj.GetComponent<Renderer>().sharedMaterial = material;
			return obj.transform;
		}

		private static void Beam(Transform p, string name, Vector3 a, Vector3 b, float width, Material mat)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: 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_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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)
			Vector3 pos = (a + b) * 0.5f;
			Vector3 val = b - a;
			Part(p, name, pos, new Vector3(width, ((Vector3)(ref val)).magnitude, width), mat, Quaternion.FromToRotation(Vector3.up, b - a));
		}

		public void Build()
		{
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: 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)
			if ((Object)(object)((Component)this).transform.Find("FishingChairModel") != (Object)null)
			{
				return;
			}
			if ((Object)(object)frame == (Object)null)
			{
				frame = Mat(new Color(0.55f, 0.57f, 0.59f), 0.68f);
				dark = Mat(new Color(0.12f, 0.12f, 0.15f));
				green = Mat(new Color(0.16f, 0.26f, 0.16f));
				greenLight = Mat(new Color(0.42f, 0.45f, 0.23f));
				wood = Mat(new Color(0.53f, 0.28f, 0.12f));
				blue = Mat(new Color(0.06f, 0.29f, 0.59f));
				cream = Mat(new Color(0.86f, 0.8f, 0.63f));
				orange = Mat(new Color(0.88f, 0.26f, 0.09f));
			}
			root = new GameObject("FishingChairModel").transform;
			root.SetParent(((Component)this).transform, false);
			try
			{
				InventoryMesh = ((Component)GlbModel.Create(root, Kind)).GetComponent<MeshFilter>().sharedMesh;
			}
			catch (Exception ex)
			{
				Plugin.Log("Could not load imported chair model " + Kind + ": " + ex);
				if (Kind == 0)
				{
					Stool();
				}
				else if (Kind == 1)
				{
					Lawn();
				}
				else
				{
					Perch();
				}
				InventoryMesh = ((Component)Part(root, "InventoryAnchor", new Vector3(0f, -0.04f, 0f), new Vector3(0.05f, 0.05f, 0.05f), dark, Quaternion.identity)).GetComponent<MeshFilter>().sharedMesh;
				((Component)root.Find("InventoryAnchor")).GetComponent<Renderer>().enabled = false;
			}
		}

		private void Stool()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: 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_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: 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_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			for (int i = -1; i <= 1; i += 2)
			{
				Beam(root, "CrossLegA", new Vector3((float)i * 0.55f, 0.06f, -0.38f), new Vector3((float)i * 0.55f, 0.54f, 0.38f), 0.065f, frame);
				Beam(root, "CrossLegB", new Vector3((float)i * 0.55f, 0.06f, 0.38f), new Vector3((float)i * 0.55f, 0.54f, -0.38f), 0.065f, frame);
				Part(root, "Pivot", new Vector3((float)i * 0.55f, 0.31f, 0f), new Vector3(0.11f, 0.11f, 0.11f), dark, Quaternion.identity);
			}
			Part(root, "CanvasLeft", new Vector3(-0.39f, 0.53f, 0f), new Vector3(0.4f, 0.055f, 0.82f), green, Quaternion.identity);
			Part(root, "CanvasCenter", new Vector3(0f, 0.5f, 0f), new Vector3(0.38f, 0.055f, 0.82f), greenLight, Quaternion.identity);
			Part(root, "CanvasRight", new Vector3(0.39f, 0.53f, 0f), new Vector3(0.4f, 0.055f, 0.82f), green, Quaternion.identity);
			for (int j = -1; j <= 1; j += 2)
			{
				Beam(root, "SeatRail", new Vector3((float)j * 0.61f, 0.54f, -0.42f), new Vector3((float)j * 0.61f, 0.54f, 0.42f), 0.075f, dark);
			}
		}

		private void Lawn()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: 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_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			for (int i = -1; i <= 1; i += 2)
			{
				float num = (float)i * 0.61f;
				Beam(root, "FrontLeg", new Vector3(num, 0.05f, 0.43f), new Vector3(num, 0.55f, 0.33f), 0.07f, frame);
				Beam(root, "BackLeg", new Vector3(num, 0.05f, -0.48f), new Vector3(num, 0.95f, -0.39f), 0.07f, frame);
				Beam(root, "BackFrame", new Vector3(num, 0.45f, -0.33f), new Vector3(num, 1.06f, -0.42f), 0.07f, frame);
				Part(root, "WoodArm", new Vector3(num, 0.7f, 0.06f), new Vector3(0.17f, 0.09f, 0.72f), wood, Quaternion.identity);
			}
			for (int j = 0; j < 7; j++)
			{
				Material obj;
				switch (j)
				{
				default:
					obj = blue;
					break;
				case 1:
				case 5:
					obj = cream;
					break;
				case 3:
					obj = orange;
					break;
				}
				Material material = obj;
				float num2 = (float)(j - 3) * 0.17f;
				Part(root, "StripedSeat", new Vector3(num2, 0.43f, 0.02f), new Vector3(0.17f, 0.045f, 0.86f), material, Quaternion.identity);
				Part(root, "StripedBack", new Vector3(num2, 0.77f, -0.39f), new Vector3(0.17f, 0.57f, 0.045f), material, Quaternion.Euler(9f, 0f, 0f));
			}
		}

		private void Perch()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: 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_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: 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_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_026b: Unknown result type (might be due to invalid IL or missing references)
			Part(root, "MainPost", new Vector3(0f, 0.72f, 0f), new Vector3(0.25f, 1.44f, 0.25f), wood, Quaternion.identity);
			for (int i = 0; i < 4; i++)
			{
				float num = (float)i * 90f * ((float)Math.PI / 180f);
				Beam(root, "PlatformBrace", new Vector3(0f, 0.86f, 0f), new Vector3(Mathf.Cos(num) * 0.51f, 1.38f, Mathf.Sin(num) * 0.46f), 0.1f, wood);
			}
			Part(root, "Platform", new Vector3(0f, 1.43f, 0f), new Vector3(1.38f, 0.12f, 1.12f), wood, Quaternion.identity);
			Part(root, "Seat", new Vector3(0f, 1.6f, 0.04f), new Vector3(0.92f, 0.1f, 0.76f), green, Quaternion.identity);
			Part(root, "Back", new Vector3(0f, 1.97f, -0.37f), new Vector3(0.96f, 0.72f, 0.1f), green, Quaternion.Euler(-5f, 0f, 0f));
			for (int j = -1; j <= 1; j += 2)
			{
				Part(root, "Arm", new Vector3((float)j * 0.58f, 1.83f, 0.04f), new Vector3(0.17f, 0.09f, 0.79f), wood, Quaternion.identity);
				Beam(root, "ArmPost", new Vector3((float)j * 0.58f, 1.48f, 0.27f), new Vector3((float)j * 0.58f, 1.82f, 0.27f), 0.09f, wood);
			}
			for (int k = 0; k < 3; k++)
			{
				Part(root, "PostBand", new Vector3(0f, 0.35f + (float)k * 0.39f, 0f), new Vector3(0.4f, 0.08f, 0.35f), wood, Quaternion.identity);
			}
		}

		private void LateUpdate()
		{
			//IL_0051: 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)
			Item component = ((Component)this).GetComponent<Item>();
			ChairData chairData = (((Object)(object)Plugin.Instance == (Object)null) ? null : Plugin.Instance.Find(ChairItem.Serial(component)));
			if (chairData != null && chairData.deployed && (Object)(object)component != (Object)null && (Object)(object)component.SyncedHolder == (Object)null)
			{
				((Component)this).transform.SetPositionAndRotation(chairData.position, chairData.Rotation);
			}
		}
	}
	internal static class GlbModel
	{
		private const uint JsonChunk = 1313821514u;

		private const uint BinaryChunk = 5130562u;

		private static readonly string[] Files = new string[3] { "stool.glb", "lawn.glb", "perch.glb" };

		private static readonly Mesh[] Meshes = (Mesh[])(object)new Mesh[3];

		private static readonly Material[] Materials = (Material[])(object)new Material[3];

		public static Transform Create(Transform parent, int kind)
		{
			if (kind < 0 || kind >= Files.Length)
			{
				throw new ArgumentOutOfRangeException("kind");
			}
			if ((Object)(object)Meshes[kind] != (Object)null)
			{
				return Instance(parent, kind);
			}
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("FishingChairsMod." + Files[kind]);
			if (stream == null)
			{
				throw new InvalidOperationException("Embedded chair model is missing.");
			}
			using BinaryReader binaryReader = new BinaryReader(stream);
			if (binaryReader.ReadUInt32() != 1179937895 || binaryReader.ReadUInt32() != 2)
			{
				throw new InvalidDataException("Fishing Chair model is not a glTF 2.0 binary model.");
			}
			uint num = binaryReader.ReadUInt32();
			string text = null;
			byte[] array = null;
			while (stream.Position < num)
			{
				int count = binaryReader.ReadInt32();
				uint num2 = binaryReader.ReadUInt32();
				byte[] array2 = binaryReader.ReadBytes(count);
				switch (num2)
				{
				case 1313821514u:
					text = Encoding.UTF8.GetString(array2).TrimEnd('\0', ' ', '\t', '\r', '\n');
					break;
				case 5130562u:
					array = array2;
					break;
				}
			}
			if (text == null || array == null)
			{
				throw new InvalidDataException("Fishing Chair GLB is missing JSON or mesh data.");
			}
			Build(JObject.Parse(text), array, kind);
			return Instance(parent, kind);
		}

		private static void Build(JObject gltf, byte[] binary, int kind)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: 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_00ff: 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_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: Expected O, but got Unknown
			JObject val = (JObject)gltf["meshes"][(object)0][(object)"primitives"][(object)0];
			JObject val2 = (JObject)val["attributes"];
			Vector3[] array = ReadVec3(gltf, binary, (int)val2["POSITION"]);
			Vector3[] array2 = ReadVec3(gltf, binary, (int)val2["NORMAL"]);
			Vector2[] array3 = ReadVec2(gltf, binary, (int)val2["TEXCOORD_0"]);
			int[] array4 = ReadIndices(gltf, binary, (int)val["indices"]);
			float num = float.MaxValue;
			float num2 = float.MinValue;
			float num3 = float.MaxValue;
			float num4 = float.MinValue;
			float num5 = float.MaxValue;
			float num6 = float.MinValue;
			foreach (Vector3 val3 in array)
			{
				num = Mathf.Min(num, val3.y);
				num2 = Mathf.Max(num2, val3.y);
				num3 = Mathf.Min(num3, val3.x);
				num4 = Mathf.Max(num4, val3.x);
				num5 = Mathf.Min(num5, val3.z);
				num6 = Mathf.Max(num6, val3.z);
			}
			Vector3 val4 = default(Vector3);
			((Vector3)(ref val4))..ctor((num3 + num4) * 0.5f, 0f, (num5 + num6) * 0.5f);
			float num7 = (new float[3] { 0.8f, 1.1f, 2.7f })[kind] / Mathf.Max(0.01f, num2 - num);
			for (int j = 0; j < array.Length; j++)
			{
				array[j] = new Vector3((0f - (array[j].x - val4.x)) * num7, (array[j].y - num) * num7, (array[j].z - val4.z) * num7);
			}
			for (int k = 0; k < array2.Length; k++)
			{
				array2[k] = new Vector3(0f - array2[k].x, array2[k].y, array2[k].z);
			}
			for (int l = 0; l < array3.Length; l++)
			{
				array3[l].y = 1f - array3[l].y;
			}
			for (int m = 0; m + 2 < array4.Length; m += 3)
			{
				int num8 = array4[m + 1];
				array4[m + 1] = array4[m + 2];
				array4[m + 2] = num8;
			}
			Mesh val5 = new Mesh
			{
				name = "Imported " + Files[kind]
			};
			val5.indexFormat = (IndexFormat)1;
			val5.vertices = array;
			val5.normals = array2;
			val5.uv = array3;
			val5.triangles = array4;
			val5.RecalculateBounds();
			Material val6 = Material(gltf, binary);
			Meshes[kind] = val5;
			Materials[kind] = val6;
		}

		private static Transform Instance(Transform parent, int kind)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("ImportedFishingChairModel");
			val.transform.SetParent(parent, false);
			val.AddComponent<MeshFilter>().sharedMesh = Meshes[kind];
			MeshRenderer obj = val.AddComponent<MeshRenderer>();
			((Renderer)obj).sharedMaterial = Materials[kind];
			((Renderer)obj).lightmapIndex = -1;
			((Renderer)obj).realtimeLightmapIndex = -1;
			return val.transform;
		}

		private static Material Material(JObject gltf, byte[] binary)
		{
			//IL_0018: 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_0028: 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_0034: Expected O, but got Unknown
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Expected O, but got Unknown
			//IL_0107: Expected O, but got Unknown
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Expected O, but got Unknown
			Material val = new Material(Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Standard"))
			{
				name = "Imported Fishing Chair Material",
				color = Color.white
			};
			JArray val2 = (JArray)gltf["images"];
			if (val2 != null && ((JContainer)val2).Count > 0)
			{
				int num = (int)gltf["materials"][(object)0][(object)"pbrMetallicRoughness"][(object)"baseColorTexture"][(object)"index"];
				int num2 = (int)gltf["textures"][(object)num][(object)"source"];
				int num3 = (int)((JObject)val2[num2])["bufferView"];
				JObject val3 = (JObject)gltf["bufferViews"][(object)num3];
				int srcOffset = Value(val3, "byteOffset");
				int num4 = Value(val3, "byteLength");
				byte[] array = new byte[num4];
				Buffer.BlockCopy(binary, srcOffset, array, 0, num4);
				Texture2D val4 = new Texture2D(2, 2, (TextureFormat)4, false)
				{
					name = "Imported Fishing Chair Base Texture",
					wrapMode = (TextureWrapMode)0
				};
				if (!ImageConversion.LoadImage(val4, array))
				{
					throw new InvalidDataException("Fishing Chair base texture could not be decoded.");
				}
				val.mainTexture = (Texture)(object)val4;
				if (val.HasProperty("_BaseMap"))
				{
					val.SetTexture("_BaseMap", (Texture)(object)val4);
				}
			}
			return val;
		}

		private static int Value(JObject value, string name)
		{
			JToken val = value[name];
			if (val != null)
			{
				return (int)val;
			}
			return 0;
		}

		private static int Offset(JObject gltf, int accessorIndex, out JObject accessor, out JObject view)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			accessor = (JObject)gltf["accessors"][(object)accessorIndex];
			view = (JObject)gltf["bufferViews"][(object)(int)accessor["bufferView"]];
			return Value(view, "byteOffset") + Value(accessor, "byteOffset");
		}

		private static Vector3[] ReadVec3(JObject gltf, byte[] data, int index)
		{
			//IL_0068: 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)
			JObject accessor;
			JObject view;
			int num = Offset(gltf, index, out accessor, out view);
			int num2 = (int)accessor["count"];
			int num3 = Value(view, "byteStride");
			if (num3 == 0)
			{
				num3 = 12;
			}
			Vector3[] array = (Vector3[])(object)new Vector3[num2];
			for (int i = 0; i < num2; i++)
			{
				int num4 = num + i * num3;
				array[i] = new Vector3(Float(data, num4), Float(data, num4 + 4), Float(data, num4 + 8));
			}
			return array;
		}

		private static Vector2[] ReadVec2(JObject gltf, byte[] data, int index)
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			JObject accessor;
			JObject view;
			int num = Offset(gltf, index, out accessor, out view);
			int num2 = (int)accessor["count"];
			int num3 = Value(view, "byteStride");
			if (num3 == 0)
			{
				num3 = 8;
			}
			Vector2[] array = (Vector2[])(object)new Vector2[num2];
			for (int i = 0; i < num2; i++)
			{
				int num4 = num + i * num3;
				array[i] = new Vector2(Float(data, num4), Float(data, num4 + 4));
			}
			return array;
		}

		private static int[] ReadIndices(JObject gltf, byte[] data, int index)
		{
			JObject accessor;
			JObject view;
			int num = Offset(gltf, index, out accessor, out view);
			int num2 = (int)accessor["count"];
			int num3 = (int)accessor["componentType"];
			int num4 = num3 switch
			{
				5123 => 2, 
				5125 => 4, 
				_ => 1, 
			};
			int num5 = Value(view, "byteStride");
			if (num5 == 0)
			{
				num5 = num4;
			}
			int[] array = new int[num2];
			for (int i = 0; i < num2; i++)
			{
				int num6 = num + i * num5;
				array[i] = num3 switch
				{
					5123 => BitConverter.ToUInt16(data, num6), 
					5125 => (int)BitConverter.ToUInt32(data, num6), 
					_ => data[num6], 
				};
			}
			return array;
		}

		private static float Float(byte[] data, int offset)
		{
			return BitConverter.ToSingle(data, offset);
		}
	}
	[BepInPlugin("ponyfisher.howtofish.fishingchairsmod", "Fishing Chairs Mod", "0.1.2")]
	[DefaultExecutionOrder(29300)]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string Guid = "ponyfisher.howtofish.fishingchairsmod";

		public static Plugin Instance;

		public List<ChairData> Current = new List<ChairData>();

		public int Selected;

		public string Status = "Look at a money vendor and press F4 to browse fishing chairs.";

		private SaveData save = new SaveData();

		private WorldData world;

		private NetworkManager manager;

		private Harmony harmony;

		private string savePath;

		private bool persistenceReady = true;

		private bool registrationFailed;

		private bool catalogReady;

		private bool nearMoneyVendor;

		private Component hoveredInteractable;

		private float nextTick;

		private float nextSave;

		private float nextState;

		private float nextVendorScan;

		private float nextIconRefresh;

		private float nextHello;

		private float statusUntil;

		private int sequence;

		private readonly Dictionary<int, int> lastSequence = new Dictionary<int, int>();

		private readonly Dictionary<int, float> rateLimit = new Dictionary<int, float>();

		private readonly Dictionary<int, Item> chairs = new Dictionary<int, Item>();

		private bool shopOpen;

		private CursorLockMode oldCursorLock;

		private bool oldCursorVisible;

		private int localSeat;

		private Vector3 lastExit;

		private bool previousCrouch;

		private PlayerCamera seatedCamera;

		private float originalCameraHeight;

		private float useStarted;

		private Item activeTarget;

		private bool holdFired;

		private bool seatPressed;

		private GUIStyle hintStyle;

		public bool ShopOpen => shopOpen;

		public bool IsLocalSeated => localSeat != 0;

		public int LocalSeatSerial => localSeat;

		public static void Log(string text)
		{
			if ((Object)(object)Instance != (Object)null)
			{
				((BaseUnityPlugin)Instance).Logger.LogInfo((object)text);
			}
		}

		private void Awake()
		{
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Expected O, but got Unknown
			Instance = this;
			savePath = Path.Combine(Paths.ConfigPath, "FishingChairsMod-worlds.json");
			try
			{
				if (File.Exists(savePath))
				{
					save = Codec.FromJson<SaveData>(File.ReadAllText(savePath));
					if (save == null || save.version != 1 || save.worlds == null)
					{
						throw new Exception("Unrecognized save format");
					}
				}
			}
			catch (Exception ex)
			{
				persistenceReady = false;
				Status = "Fishing Chair save data could not be read; actions are paused.";
				((BaseUnityPlugin)this).Logger.LogError((object)ex);
			}
			GenericWriter<RequestMessage>.SetWrite((Action<Writer, RequestMessage>)delegate(Writer w, RequestMessage v)
			{
				w.WriteString(v.json);
			});
			GenericReader<RequestMessage>.SetRead((Func<Reader, RequestMessage>)((Reader r) => new RequestMessage
			{
				json = r.ReadStringAllocated()
			}));
			GenericWriter<StateMessage>.SetWrite((Action<Writer, StateMessage>)delegate(Writer w, StateMessage v)
			{
				w.WriteString(v.json);
			});
			GenericReader<StateMessage>.SetRead((Func<Reader, StateMessage>)((Reader r) => new StateMessage
			{
				json = r.ReadStringAllocated()
			}));
			GenericWriter<ReplyMessage>.SetWrite((Action<Writer, ReplyMessage>)delegate(Writer w, ReplyMessage v)
			{
				w.WriteString(v.json);
			});
			GenericReader<ReplyMessage>.SetRead((Func<Reader, ReplyMessage>)((Reader r) => new ReplyMessage
			{
				json = r.ReadStringAllocated()
			}));
			harmony = new Harmony("ponyfisher.howtofish.fishingchairsmod");
			harmony.PatchAll(typeof(Plugin).Assembly);
			Log("Fishing Chairs Mod 0.1.2 loaded.");
		}

		private void Update()
		{
			//IL_030f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0315: Unknown result type (might be due to invalid IL or missing references)
			//IL_0319: Unknown result type (might be due to invalid IL or missing references)
			//IL_031f: Unknown result type (might be due to invalid IL or missing references)
			UpdateInteraction();
			if ((Object)(object)manager != (Object)(object)InstanceFinder.NetworkManager)
			{
				RegisterNetwork();
			}
			if (!registrationFailed && !ChairItem.Ready)
			{
				try
				{
					ChairItem.Register();
				}
				catch (Exception ex)
				{
					registrationFailed = true;
					Status = "Fishing Chair registration failed; see the BepInEx log.";
					((BaseUnityPlugin)this).Logger.LogError((object)ex);
				}
			}
			if (ChairItem.Ready && !catalogReady)
			{
				catalogReady = true;
				Log("Fishing Chair catalog ready.");
			}
			if (catalogReady && Time.unscaledTime >= nextVendorScan)
			{
				nextVendorScan = Time.unscaledTime + 0.15f;
				nearMoneyVendor = (Object)(object)FocusedMoneyVendor(Player.LocalPlayer, 5f) != (Object)null;
			}
			Keyboard current = Keyboard.current;
			if (catalogReady && nearMoneyVendor && current != null && ((ButtonControl)current.f4Key).wasPressedThisFrame)
			{
				SetShop(!shopOpen);
			}
			if (shopOpen && ((current != null && ((ButtonControl)current.escapeKey).wasPressedThisFrame) || !nearMoneyVendor))
			{
				SetShop(open: false);
			}
			if (catalogReady && Time.unscaledTime >= nextIconRefresh)
			{
				nextIconRefresh = Time.unscaledTime + 0.15f;
				FishingChairInventoryIcon.RefreshAll();
			}
			if (InstanceFinder.IsServerStarted && SaveManager.CurServerSave != null)
			{
				string name = SaveManager.CurServerSave.Name;
				if (world == null || world.name != name)
				{
					world = save.worlds.FirstOrDefault((WorldData w) => w.name == name);
					if (world == null)
					{
						world = new WorldData
						{
							name = name
						};
						save.worlds.Add(world);
					}
					Current = world.chairs;
					foreach (ChairData item in Current)
					{
						item.occupant = 0uL;
					}
					chairs.Clear();
					lastSequence.Clear();
					rateLimit.Clear();
				}
				if (Time.unscaledTime >= nextTick)
				{
					nextTick = Time.unscaledTime + 0.2f;
					AuditWorld();
				}
				if (Time.unscaledTime >= nextState)
				{
					nextState = Time.unscaledTime + 0.35f;
					Broadcast();
				}
				if (Time.unscaledTime >= nextSave)
				{
					nextSave = Time.unscaledTime + 8f;
					Persist();
				}
			}
			else if (!InstanceFinder.IsClientStarted)
			{
				world = null;
				Current = new List<ChairData>();
				chairs.Clear();
			}
			if (InstanceFinder.IsClientStarted && !InstanceFinder.IsServerStarted && Time.unscaledTime >= nextHello)
			{
				nextHello = Time.unscaledTime + 3f;
				Send("hello");
			}
			UpdateSeat();
			if (shopOpen)
			{
				Cursor.lockState = (CursorLockMode)0;
				Cursor.visible = true;
			}
		}

		private void SetShop(bool open)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			if (shopOpen != open)
			{
				if (open)
				{
					oldCursorLock = Cursor.lockState;
					oldCursorVisible = Cursor.visible;
					Cursor.lockState = (CursorLockMode)0;
					Cursor.visible = true;
				}
				else
				{
					Cursor.lockState = oldCursorLock;
					Cursor.visible = oldCursorVisible;
				}
				shopOpen = open;
			}
		}

		private void RegisterNetwork()
		{
			if ((Object)(object)manager != (Object)null)
			{
				manager.ServerManager.UnregisterBroadcast<RequestMessage>((Action<NetworkConnection, RequestMessage, Channel>)Receive);
				manager.ClientManager.UnregisterBroadcast<StateMessage>((Action<StateMessage, Channel>)ReceiveState);
				manager.ClientManager.UnregisterBroadcast<ReplyMessage>((Action<ReplyMessage, Channel>)ReceiveReply);
			}
			manager = InstanceFinder.NetworkManager;
			if (!((Object)(object)manager == (Object)null))
			{
				manager.ServerManager.RegisterBroadcast<RequestMessage>((Action<NetworkConnection, RequestMessage, Channel>)Receive, true);
				manager.ClientManager.RegisterBroadcast<StateMessage>((Action<StateMessage, Channel>)ReceiveState);
				manager.ClientManager.RegisterBroadcast<ReplyMessage>((Action<ReplyMessage, Channel>)ReceiveReply);
			}
		}

		public ChairData Find(int serial)
		{
			return Current.FirstOrDefault((ChairData g) => g.serial == serial);
		}

		public void Persist()
		{
			if (!persistenceReady || !InstanceFinder.IsServerStarted || world == null)
			{
				return;
			}
			try
			{
				string text = savePath + ".tmp";
				File.WriteAllText(text, Codec.ToJson(save, pretty: true));
				if (File.Exists(savePath))
				{
					File.Replace(text, savePath, savePath + ".bak");
				}
				else
				{
					File.Move(text, savePath);
				}
			}
			catch (Exception ex)
			{
				persistenceReady = false;
				Status = "Fishing Chairs Mod could not save; actions are paused.";
				((BaseUnityPlugin)this).Logger.LogError((object)ex);
			}
		}

		public void Send(string action, Vector3 position = default(Vector3), Vector3 normal = default(Vector3), int serial = 0, int kind = 0)
		{
			//IL_003b: 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_0042: 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)
			if ((Object)(object)Player.LocalPlayer == (Object)null)
			{
				SetStatus("Load into a game first.");
				return;
			}
			Command command = new Command
			{
				action = action,
				serial = ((serial > 0) ? serial : Selected),
				position = position,
				normal = normal,
				sequence = ++sequence,
				kind = kind
			};
			if (InstanceFinder.IsServerStarted)
			{
				Execute(Player.LocalPlayer, command, null);
			}
			else if ((Object)(object)manager != (Object)null && InstanceFinder.IsClientStarted)
			{
				manager.ClientManager.Broadcast<RequestMessage>(new RequestMessage
				{
					json = Codec.ToJson(command)
				}, (Channel)0);
				if (action != "hello")
				{
					SetStatus("Waiting for the host...");
				}
			}
		}

		private void Receive(NetworkConnection connection, RequestMessage message, Channel channel)
		{
			if (!InstanceFinder.IsServerStarted || message.json == null || message.json.Length > 2048)
			{
				return;
			}
			try
			{
				Command command = Codec.FromJson<Command>(message.json);
				if (command != null && command.protocol == 1 && command.sequence > 0 && (!lastSequence.TryGetValue(connection.ClientId, out var value) || command.sequence > value) && (!rateLimit.TryGetValue(connection.ClientId, out var value2) || !(Time.unscaledTime - value2 < 0.1f)))
				{
					lastSequence[connection.ClientId] = command.sequence;
					rateLimit[connection.ClientId] = Time.unscaledTime;
					Player val = ((IEnumerable<Player>)Object.FindObjectsByType<Player>()).FirstOrDefault((Func<Player, bool>)((Player p) => ((NetworkBehaviour)p).Owner == connection));
					if ((Object)(object)val != (Object)null)
					{
						Execute(val, command, connection);
					}
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Rejected Fishing Chair request: " + ex.Message));
			}
		}

		private void SetStatus(string message)
		{
			Status = message;
			statusUntil = Time.unscaledTime + 4f;
		}

		private void Respond(Command cmd, NetworkConnection connection, string message, int selected = 0)
		{
			Reply value = new Reply
			{
				sequence = cmd.sequence,
				serial = selected,
				message = message
			};
			if (connection == (NetworkConnection)null || connection.IsLocalClient)
			{
				SetStatus(message);
				if (selected > 0)
				{
					Selected = selected;
				}
			}
			else
			{
				manager.ServerManager.Broadcast<ReplyMessage>(connection, new ReplyMessage
				{
					json = Codec.ToJson(value)
				}, true, (Channel)0);
			}
		}

		private void ReceiveReply(ReplyMessage message, Channel channel)
		{
			Reply reply = Codec.FromJson<Reply>(message.json);
			if (reply != null)
			{
				SetStatus(reply.message);
				if (reply.serial > 0)
				{
					Selected = reply.serial;
				}
			}
		}

		private void ReceiveState(StateMessage message, Channel channel)
		{
			if (!InstanceFinder.IsServerStarted && message.json != null && message.json.Length <= 250000)
			{
				Snapshot snapshot = Codec.FromJson<Snapshot>(message.json);
				if (snapshot != null && snapshot.protocol == 1 && snapshot.chairs != null)
				{
					Current = snapshot.chairs;
				}
			}
		}

		private void Broadcast()
		{
			if ((Object)(object)manager != (Object)null && world != null)
			{
				manager.ServerManager.Broadcast<StateMessage>(new StateMessage
				{
					json = Codec.ToJson(new Snapshot
					{
						world = world.name,
						chairs = Current
					})
				}, true, (Channel)0);
			}
		}

		private void ScanChairs()
		{
			chairs.Clear();
			Item[] array = Object.FindObjectsByType<Item>((FindObjectsInactive)1);
			foreach (Item val in array)
			{
				if (ChairItem.Is(val) && ((NetworkBehaviour)val).IsSpawned && !((NetworkBehaviour)val).IsDeinitializing)
				{
					int num = ChairItem.Serial(val);
					if (num > 0 && !chairs.ContainsKey(num))
					{
						chairs.Add(num, val);
					}
				}
			}
		}

		private Item FindChair(int serial)
		{
			if (chairs.TryGetValue(serial, out var value) && (Object)(object)value != (Object)null && ((NetworkBehaviour)value).IsSpawned && !((NetworkBehaviour)value).IsDeinitializing)
			{
				return value;
			}
			value = ((IEnumerable<Item>)Object.FindObjectsByType<Item>((FindObjectsInactive)1)).FirstOrDefault((Func<Item, bool>)((Item i) => ChairItem.Is(i) && ((NetworkBehaviour)i).IsSpawned && !((NetworkBehaviour)i).IsDeinitializing && ChairItem.Serial(i) == serial));
			if ((Object)(object)value != (Object)null)
			{
				chairs[serial] = value;
			}
			return value;
		}

		private void AuditWorld()
		{
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			ScanChairs();
			foreach (KeyValuePair<int, Item> chair in chairs)
			{
				Item value = chair.Value;
				ChairData data = Find(chair.Key);
				if (data == null)
				{
					Player syncedHolder = value.SyncedHolder;
					data = new ChairData
					{
						serial = chair.Key,
						kind = ChairItem.Kind(value),
						owner = (((Object)(object)syncedHolder == (Object)null) ? 0 : syncedHolder.SteamID),
						ownerName = (((Object)(object)syncedHolder == (Object)null) ? null : syncedHolder.SteamName)
					};
					Current.Add(data);
					save.nextSerial = Math.Max(save.nextSerial, chair.Key + 1);
				}
				data.available = true;
				if ((Object)(object)value.SyncedHolder != (Object)null)
				{
					data.deployed = false;
					data.occupant = 0uL;
				}
				else if (data.deployed)
				{
					value.RigidbodySync.SetKinematic(true);
					if (Vector3.Distance(((Component)value).transform.position, data.position) > 0.05f)
					{
						value.RigidbodySync.TeleportToPosRot(data.position, data.Rotation, (float[])null, (Quaternion[])null);
					}
				}
				if (data.occupant != 0L && !Object.FindObjectsByType<Player>().Any((Player p) => p.SteamID == data.occupant && !p.Dying.IsDead))
				{
					data.occupant = 0uL;
				}
			}
			foreach (ChairData item in Current)
			{
				item.available = chairs.ContainsKey(item.serial);
			}
		}

		private int OpenSlot(Player player)
		{
			int num = (int)AccessTools.Method(typeof(PlayerInventory), "GetTotalSlots", (Type[])null, (Type[])null).Invoke(player.Inventory, null);
			Item val = default(Item);
			for (byte b = 0; b < num; b++)
			{
				if (!player.Inventory._items.TryGetValue(b, ref val) || (Object)(object)val == (Object)null)
				{
					return b;
				}
			}
			return -1;
		}

		private Item SpawnChair(Player player, int slot, int serial, int kind)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			//IL_007e: 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)
			Item val = Object.Instantiate<Item>(ChairItem.Prefabs[kind], ((Component)player).transform.position + Vector3.up, Quaternion.identity, Server.Instance.DynamicObjectsHolder);
			val.LoadFromSave(new SavedItem
			{
				Exists = true,
				ItemID = Rules.ItemIds[kind],
				BettingMultiplier = serial,
				Weight = 1f,
				KillScoreMultiplier = 1f
			});
			InstanceFinder.ServerManager.Spawn(((Component)val).gameObject, (NetworkConnection)null, default(Scene));
			val.SetSyncedHolder(player, true);
			player.Inventory.AddItem((byte)slot, val);
			if (!player.Inventory.HasItemInInventory(val))
			{
				InstanceFinder.ServerManager.Despawn(((Component)val).gameObject, (DespawnType?)null);
				throw new Exception("Inventory did not accept the Fishing Chair.");
			}
			return val;
		}

		private bool Ground(Player player, Command cmd, Item chair, out RaycastHit hit)
		{
			//IL_0002: 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_005c: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			hit = default(RaycastHit);
			if (!Rules.Finite(cmd.position.x) || !Rules.Finite(cmd.position.y) || !Rules.Finite(cmd.position.z) || !Rules.SurfaceAllowed(cmd.normal.y) || Vector3.Distance(cmd.position, player.CamObject.position) > 8.35f)
			{
				return false;
			}
			Vector3 normalized = ((Vector3)(ref cmd.normal)).normalized;
			foreach (RaycastHit item in from h in Physics.RaycastAll(cmd.position + normalized * 0.35f, -normalized, 0.8f, -1, (QueryTriggerInteraction)1)
				orderby ((RaycastHit)(ref h)).distance
				select h)
			{
				RaycastHit current = item;
				if (((Component)((RaycastHit)(ref current)).collider).gameObject.layer != LayerMask.NameToLayer("Water") && !((Object)(object)((Component)((RaycastHit)(ref current)).collider).GetComponentInParent<Player>() != (Object)null) && !((Object)(object)((Component)((RaycastHit)(ref current)).collider).GetComponentInParent<Item>() != (Object)null) && Rules.SurfaceAllowed(((RaycastHit)(ref current)).normal.y) && !(Vector3.Dot(((RaycastHit)(ref current)).normal, normalized) < 0.5f))
				{
					hit = current;
					return true;
				}
			}
			return false;
		}

		private float Distance(Player player, Item item)
		{
			//IL_0006: 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_002f: 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)
			return Mathf.Min(Vector3.Distance(((Component)player).transform.position, ((Component)item).transform.position), ((Object)(object)player.CamObject == (Object)null) ? float.MaxValue : Vector3.Distance(player.CamObject.position, ((Component)item).transform.position));
		}

		private void Execute(Player player, Command cmd, NetworkConnection connection)
		{
			//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_0665: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0393: Unknown result type (might be due to invalid IL or missing references)
			//IL_039a: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0402: Unknown result type (might be due to invalid IL or missing references)
			//IL_0408: Unknown result type (might be due to invalid IL or missing references)
			if (cmd.action == "hello")
			{
				Broadcast();
				return;
			}
			if (!persistenceReady || world == null || !ChairItem.Ready || player.Dying.IsDead)
			{
				Respond(cmd, connection, "Fishing Chairs Mod is not ready on the host.");
				return;
			}
			ScanChairs();
			try
			{
				if (cmd.action == "buy")
				{
					if (cmd.kind < 0 || cmd.kind >= 3)
					{
						return;
					}
					if ((Object)(object)FocusedMoneyVendor(player, 5f) == (Object)null)
					{
						Respond(cmd, connection, "Look at a money vendor to buy a chair.");
						return;
					}
					int num = OpenSlot(player);
					if (num < 0)
					{
						Respond(cmd, connection, "Free an inventory slot before buying a chair.");
						return;
					}
					int num2 = Rules.Prices[cmd.kind];
					if (!Wallet.Charge(player, num2))
					{
						Respond(cmd, connection, "You need $" + num2.ToString("N0") + " to buy a chair.");
						return;
					}
					int num3 = save.nextSerial++;
					try
					{
						SpawnChair(player, num, num3, cmd.kind);
					}
					catch
					{
						Wallet.Credit(player, num2);
						throw;
					}
					Current.Add(new ChairData
					{
						serial = num3,
						kind = cmd.kind,
						owner = player.SteamID,
						ownerName = player.SteamName
					});
					Persist();
					Broadcast();
					Respond(cmd, connection, ChairItem.Name(cmd.kind) + " purchased.", num3);
					return;
				}
				ChairData chairData = Find(cmd.serial);
				Item val = FindChair(cmd.serial);
				if (chairData == null || (Object)(object)val == (Object)null)
				{
					Respond(cmd, connection, "That Fishing Chair is unavailable.");
					return;
				}
				bool flag = (Object)(object)val.SyncedHolder == (Object)(object)player;
				if (!flag && Distance(player, val) > 4.35f)
				{
					Respond(cmd, connection, "Move within " + 4f.ToString("0") + " metres of the Fishing Chair.");
					return;
				}
				if (cmd.action == "deploy")
				{
					if (!flag || chairData.deployed)
					{
						Respond(cmd, connection, "Hold that Fishing Chair before deploying it.");
						return;
					}
					if (!Ground(player, cmd, val, out var hit))
					{
						Respond(cmd, connection, "Look at an upward-facing surface within 8 metres.");
						return;
					}
					val.SpawnFromInventory();
					player.Inventory.RemoveItem(val);
					if ((Object)(object)val.Holder != (Object)null)
					{
						val.Drop(false, default(Vector3), default(Vector3));
					}
					val.SetSyncedHolder((Player)null, true);
					val.ReconcileLocalHolderWithSyncedHolder();
					if ((Object)(object)player.Holding.HeldItem == (Object)(object)val)
					{
						player.Hands.DropItem(false, val);
						player.Holding.DropItem(false, val);
						player.Holding.SetHeldItem((Item)null);
					}
					if ((Object)(object)player.Holding.UninitializedHeldItem == (Object)(object)val)
					{
						player.Holding.SetUninitializedHeldItem((Item)null);
					}
					chairData.position = ((RaycastHit)(ref hit)).point + ((RaycastHit)(ref hit)).normal * 0.015f;
					chairData.surfaceNormal = ((RaycastHit)(ref hit)).normal;
					Quaternion curPlayerRot = player.CurPlayerRot;
					chairData.yaw = ((Quaternion)(ref curPlayerRot)).eulerAngles.y;
					chairData.deployed = true;
					val.RigidbodySync.ServerSetSyncedSimulator(((NetworkBehaviour)Server.Instance).Owner);
					val.RigidbodySync.TeleportToPosRot(chairData.position, chairData.Rotation, (float[])null, (Quaternion[])null);
					val.RigidbodySync.SetKinematic(true);
					Respond(cmd, connection, "Fishing Chair deployed.", chairData.serial);
				}
				else if (cmd.action == "pickup")
				{
					if (chairData.occupant != 0L)
					{
						Respond(cmd, connection, "Someone is sitting in that chair.");
						return;
					}
					if (flag)
					{
						Respond(cmd, connection, "The chair is already in your inventory.");
						return;
					}
					int num4 = OpenSlot(player);
					bool emptyHands = (Object)(object)player.Holding.HeldItem == (Object)null && (Object)(object)player.Holding.UninitializedHeldItem == (Object)null && (Object)(object)player.Inventory.SyncedCurItem == (Object)null;
					if (!Rules.CanPickUp(num4 >= 0, emptyHands))
					{
						Respond(cmd, connection, "Free an inventory slot or empty your hands first.");
						return;
					}
					chairData.deployed = false;
					val.RigidbodySync.SetKinematic(false);
					int value = player.Inventory._syncedCurSlot.Value;
					val.SetSyncedHolder(player, true);
					if (num4 >= 0)
					{
						player.Inventory.AddItem((byte)num4, val);
					}
					val.ReconcileLocalHolderWithSyncedHolder();
					if (num4 >= 0)
					{
						player.Inventory.ServerSetSyncedCurSlot(value);
					}
					Respond(cmd, connection, "Fishing Chair picked up.", chairData.serial);
				}
				else if (cmd.action == "sit")
				{
					if (!chairData.deployed || flag || chairData.occupant != 0L || Current.Any((ChairData d) => d.occupant == player.SteamID))
					{
						Respond(cmd, connection, "That chair is occupied or unavailable.");
						return;
					}
					chairData.occupant = player.SteamID;
					player.Movement.Teleport(chairData.SeatPosition, true);
					Respond(cmd, connection, "Seated. Tap E or Space to stand.", chairData.serial);
				}
				else
				{
					if (!(cmd.action == "stand") || chairData.occupant != player.SteamID)
					{
						return;
					}
					if (!SafeExit(chairData, out var point))
					{
						Respond(cmd, connection, "No safe place directly behind this chair to stand.");
						return;
					}
					chairData.occupant = 0uL;
					player.Movement.Teleport(point, true);
					Respond(cmd, connection, "Standing.", chairData.serial);
				}
				Persist();
				Broadcast();
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)ex);
				Respond(cmd, connection, "Fishing Chairs Mod could not complete that action. Check the BepInEx log.");
			}
		}

		public static bool IsMoneyVendor(NPC npc)
		{
			if ((Object)(object)npc == (Object)null)
			{
				return false;
			}
			FieldInfo fieldInfo = AccessTools.Field(typeof(NPC), "_quests");
			return ((fieldInfo == null) ? null : (fieldInfo.GetValue(npc) as IEnumerable<NPCQuest>))?.Any((NPCQuest q) => (Object)(object)q != (Object)null && (int)q.Type == 1) ?? false;
		}

		public void SetHoveredInteractable(Component value, bool active)
		{
			if (active)
			{
				hoveredInteractable = value;
			}
			else if ((Object)(object)hoveredInteractable == (Object)(object)value)
			{
				hoveredInteractable = null;
			}
		}

		private static NPC VendorFrom(Component component)
		{
			if ((Object)(object)component == (Object)null)
			{
				return null;
			}
			NPC componentInParent = component.GetComponentInParent<NPC>();
			if (!((Object)(object)componentInParent != (Object)null))
			{
				return component.GetComponentInChildren<NPC>(true);
			}
			return componentInParent;
		}

		public NPC FocusedMoneyVendor(Player player, float range)
		{
			//IL_0074: 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_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: 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_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null || (Object)(object)player.CamObject == (Object)null)
			{
				return null;
			}
			if ((Object)(object)player == (Object)(object)Player.LocalPlayer && (Object)(object)hoveredInteractable != (Object)null)
			{
				NPC val = VendorFrom(hoveredInteractable);
				if (IsMoneyVendor(val) && Vector3.Distance(((Component)player).transform.position, ((Component)val).transform.position) <= range + 0.35f)
				{
					return val;
				}
			}
			foreach (RaycastHit item in from h in Physics.RaycastAll(player.CamObject.position, player.CamObject.forward, range, -1, (QueryTriggerInteraction)2)
				orderby ((RaycastHit)(ref h)).distance
				select h)
			{
				RaycastHit current = item;
				if (!((Object)(object)((Component)((RaycastHit)(ref current)).collider).GetComponentInParent<Player>() == (Object)(object)player))
				{
					NPC componentInParent = ((Component)((RaycastHit)(ref current)).collider).GetComponentInParent<NPC>();
					if (IsMoneyVendor(componentInParent))
					{
						return componentInParent;
					}
					if (!((RaycastHit)(ref current)).collider.isTrigger)
					{
						break;
					}
				}
			}
			NPC result = null;
			float num = 0.72f;
			RaycastHit val3 = default(RaycastHit);
			foreach (NPC item2 in Object.FindObjectsByType<NPC>().Where(IsMoneyVendor))
			{
				Vector3 val2 = (((Object)(object)item2.MouthPosForItems != (Object)null) ? item2.MouthPosForItems.position : (((Component)item2).transform.position + Vector3.up)) - player.CamObject.position;
				float magnitude = ((Vector3)(ref val2)).magnitude;
				if (!(magnitude <= 0.01f))
				{
					float num2 = Vector3.Dot(player.CamObject.forward, val2 / magnitude);
					if (Rules.CanUseVendor(magnitude, num2) && !(num2 < num) && Physics.Raycast(player.CamObject.position, val2 / magnitude, ref val3, magnitude + 0.5f, -1, (QueryTriggerInteraction)2) && !((Object)(object)((Component)((RaycastHit)(ref val3)).collider).GetComponentInParent<NPC>() != (Object)(object)item2))
					{
						result = item2;
						num = num2;
					}
				}
			}
			return result;
		}

		public void CompleteSale(Item item)
		{
			if (!InstanceFinder.IsServerStarted || (Object)(object)item == (Object)null)
			{
				return;
			}
			int num = ChairItem.Serial(item);
			ChairData chairData = Find(num);
			if (chairData != null)
			{
				Current.Remove(chairData);
				chairs.Remove(num);
				if (Selected == num)
				{
					Selected = 0;
				}
				SetStatus("Fishing Chair sold.");
				Persist();
				Broadcast();
			}
		}

		private void RaiseSeatedCamera(Player player)
		{
			if (!((Object)(object)seatedCamera != (Object)null) && !((Object)(object)player.Camera == (Object)null))
			{
				FieldInfo fieldInfo = AccessTools.Field(typeof(PlayerCamera), "<CamHeight>k__BackingField");
				if (fieldInfo == null)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)"Could not find the player camera height field.");
					return;
				}
				seatedCamera = player.Camera;
				originalCameraHeight = seatedCamera.CamHeight;
				fieldInfo.SetValue(seatedCamera, originalCameraHeight + 0.42f);
			}
		}

		private void RestoreSeatedCamera()
		{
			if (!((Object)(object)seatedCamera == (Object)null))
			{
				FieldInfo fieldInfo = AccessTools.Field(typeof(PlayerCamera), "<CamHeight>k__BackingField");
				if (fieldInfo != null)
				{
					fieldInfo.SetValue(seatedCamera, originalCameraHeight);
				}
				seatedCamera = null;
			}
		}

		public bool SafeExit(ChairData data, out Vector3 point)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: 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)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			point = default(Vector3);
			if (data == null)
			{
				return false;
			}
			foreach (RaycastHit item in from h in Physics.RaycastAll(data.position - data.Rotation * Vector3.forward * 1.45f + Vector3.up * 2f, Vector3.down, 4f, -1, (QueryTriggerInteraction)1)
				orderby ((RaycastHit)(ref h)).distance
				select h)
			{
				RaycastHit current = item;
				if (!((Object)(object)((Component)((RaycastHit)(ref current)).collider).GetComponentInParent<Item>() != (Object)null) && !((Object)(object)((Component)((RaycastHit)(ref current)).collider).GetComponentInParent<Player>() != (Object)null) && ((Component)((RaycastHit)(ref current)).collider).gameObject.layer != LayerMask.NameToLayer("Water") && !(((RaycastHit)(ref current)).normal.y < 0.65f))
				{
					point = ((RaycastHit)(ref current)).point + Vector3.up * 0.08f;
					return true;
				}
			}
			return false;
		}

		private void UpdateSeat()
		{
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: 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_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			Player player = Player.LocalPlayer;
			if ((Object)(object)player == (Object)null)
			{
				return;
			}
			if (player.Dying.IsDead)
			{
				if (localSeat != 0)
				{
					AccessTools.Field(typeof(PlayerMovement), "_crouchInput").SetValue(player.Movement, previousCrouch);
					localSeat = 0;
				}
				RestoreSeatedCamera();
				return;
			}
			ChairData chairData = Current.FirstOrDefault((ChairData d) => d.deployed && d.occupant == player.SteamID);
			if (chairData != null)
			{
				if (localSeat == 0)
				{
					localSeat = chairData.serial;
					SafeExit(chairData, out lastExit);
					previousCrouch = (bool)AccessTools.Field(typeof(PlayerMovement), "_crouchInput").GetValue(player.Movement);
					player.LocalTeleport(chairData.SeatPosition, chairData.yaw, true);
					RaiseSeatedCamera(player);
				}
				AccessTools.Field(typeof(PlayerMovement), "_crouchInput").SetValue(player.Movement, true);
				if (localSeat == chairData.serial && Vector3.Distance(((Component)player).transform.position, chairData.SeatPosition) > 0.08f)
				{
					player.Movement.Teleport(chairData.SeatPosition, true);
				}
			}
			else if (localSeat != 0)
			{
				ChairData chairData2 = Find(localSeat);
				if (chairData2 != null && chairData2.available && SafeExit(chairData2, out var point))
				{
					player.Movement.Teleport(point, true);
				}
				AccessTools.Field(typeof(PlayerMovement), "_crouchInput").SetValue(player.Movement, previousCrouch);
				localSeat = 0;
				RestoreSeatedCamera();
			}
			if (localSeat != 0 && Keyboard.current != null && ((ButtonControl)Keyboard.current.spaceKey).wasPressedThisFrame)
			{
				int serial = localSeat;
				Send("stand", default(Vector3), default(Vector3), serial);
			}
		}

		private void OnDestroy()
		{
			RestoreSeatedCamera();
			SetShop(open: false);
			Persist();
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			Instance = null;
		}

		private void DrawVendorPrompt()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: 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_0044: Expected O, but got Unknown
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: 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_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Expected O, but got Unknown
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			if (catalogReady && nearMoneyVendor && !((Object)(object)Player.LocalPlayer == (Object)null))
			{
				GUIStyle val = new GUIStyle(GUI.skin.box)
				{
					alignment = (TextAnchor)4,
					fontSize = 16,
					fontStyle = (FontStyle)1
				};
				val.normal.textColor = Color.white;
				float num = 380f;
				float num2 = (float)Screen.width * 0.69f;
				float num3 = (float)Screen.height * 0.6f;
				GUI.Box(new Rect(num2, num3, num, 34f), "[F4] Fishing Chairs", val);
				if (Time.unscaledTime < statusUntil)
				{
					GUIStyle val2 = new GUIStyle(GUI.skin.box)
					{
						alignment = (TextAnchor)4,
						fontSize = 14,
						fontStyle = (FontStyle)1
					};
					val2.normal.textColor = Color.white;
					GUI.Box(new Rect(num2 + 20f, num3 + 42f, num - 40f, 30f), Status, val2);
				}
			}
		}

		private void OnGUI()
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			DrawInteractionHint();
			DrawVendorPrompt();
			if (!shopOpen)
			{
				return;
			}
			float num = (float)Screen.width * 0.5f - 190f;
			float num2 = (float)Screen.height * 0.32f;
			GUI.Box(new Rect(num, num2, 380f, 225f), "Fishing Chairs");
			for (int i = 0; i < 3; i++)
			{
				if (GUI.Button(new Rect(num + 20f, num2 + 40f + (float)(i * 50), 340f, 40f), ChairItem.Name(i) + " - $" + Rules.Prices[i]))
				{
					int kind = i;
					Send("buy", default(Vector3), default(Vector3), 0, kind);
					SetShop(open: false);
				}
			}
			if (GUI.Button(new Rect(num + 330f, num2 + 5f, 40f, 28f), "X"))
			{
				SetShop(open: false);
			}
		}

		public static bool IsDeployed(Item item)
		{
			if ((Object)(object)Instance != (Object)null && ChairItem.Is(item) && (Object)(object)item.SyncedHolder == (Object)null)
			{
				return Instance.Find(ChairItem.Serial(item))?.deployed ?? false;
			}
			return false;
		}

		private Item RayChair(float range)
		{
			//IL_0025: 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_006a: 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)
			Player localPlayer = Player.LocalPlayer;
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)localPlayer.CamObject == (Object)null)
			{
				return null;
			}
			foreach (RaycastHit item in from h in Physics.RaycastAll(localPlayer.CamObject.position, localPlayer.CamObject.forward, range, -1, (QueryTriggerInteraction)2)
				orderby ((RaycastHit)(ref h)).distance
				select h)
			{
				RaycastHit current = item;
				if ((Object)(object)((Component)((RaycastHit)(ref current)).collider).GetComponentInParent<Player>() == (Object)(object)localPlayer)
				{
					continue;
				}
				Item componentInParent = ((Component)((RaycastHit)(ref current)).collider).GetComponentInParent<Item>();
				if (!((Object)(object)componentInParent != (Object)null) || !((Object)(object)componentInParent.SyncedHolder == (Object)(object)localPlayer))
				{
					if (ChairItem.Is(componentInParent) && IsDeployed(componentInParent))
					{
						return componentInParent;
					}
					if (!((RaycastHit)(ref current)).collider.isTrigger)
					{
						return null;
					}
				}
			}
			return null;
		}

		private Item InteractionTarget()
		{
			Player localPlayer = Player.LocalPlayer;
			if (shopOpen || (Object)(object)localPlayer == (Object)null || localPlayer.BlockInputs || localPlayer.Dying.IsDead)
			{
				return null;
			}
			Item heldItem = localPlayer.Holding.HeldItem;
			if (ChairItem.Is(heldItem))
			{
				return heldItem;
			}
			return RayChair(4f);
		}

		public bool CapturesInteract()
		{
			if (!shopOpen && !IsLocalSeated && !((Object)(object)InteractionTarget() != (Object)null) && !((Object)(object)activeTarget != (Object)null))
			{
				return seatPressed;
			}
			return true;
		}

		private bool CrosshairSurface(Item held, out RaycastHit surface)
		{
			//IL_0001: 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)
			//IL_0037: 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_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			surface = default(RaycastHit);
			Player localPlayer = Player.LocalPlayer;
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)localPlayer.CamObject == (Object)null)
			{
				return false;
			}
			foreach (RaycastHit item in from h in Physics.RaycastAll(localPlayer.CamObject.position, localPlayer.CamObject.forward, 8f, -1, (QueryTriggerInteraction)1)
				orderby ((RaycastHit)(ref h)).distance
				select h)
			{
				RaycastHit current = item;
				if (!((Object)(object)((Component)((RaycastHit)(ref current)).collider).GetComponentInParent<Player>() == (Object)(object)localPlayer) && !((Object)(object)((Component)((RaycastHit)(ref current)).collider).GetComponentInParent<Item>() == (Object)(object)held))
				{
					if (((Component)((RaycastHit)(ref current)).collider).gameObject.layer == LayerMask.NameToLayer("Water") || !Rules.SurfaceAllowed(((RaycastHit)(ref current)).normal.y))
					{
						return false;
					}
					surface = current;
					return true;
				}
			}
			return false;
		}

		private void FireHeldAction(Item target)
		{
			//IL_0059: 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_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			Selected = ChairItem.Serial(target);
			if ((Object)(object)target.SyncedHolder == (Object)(object)Player.LocalPlayer)
			{
				if (!CrosshairSurface(target, out var surface))
				{
					SetStatus("Look at an upward-facing surface within 8 metres.");
				}
				else
				{
					Send("deploy", ((RaycastHit)(ref surface)).point, ((RaycastHit)(ref surface)).normal);
				}
			}
			else
			{
				Send("pickup");
			}
		}

		private void UpdateInteraction()
		{
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: 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)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			Keyboard current = Keyboard.current;
			if (current == null)
			{
				return;
			}
			if (((ButtonControl)current.eKey).wasPressedThisFrame)
			{
				seatPressed = IsLocalSeated;
				activeTarget = (seatPressed ? null : InteractionTarget());
				useStarted = Time.unscaledTime;
				holdFired = false;
			}
			if ((Object)(object)activeTarget != (Object)null && ((ButtonControl)current.eKey).isPressed && !holdFired && Time.unscaledTime - useStarted >= 0.8f)
			{
				holdFired = true;
				FireHeldAction(activeTarget);
			}
			if (((ButtonControl)current.eKey).wasReleasedThisFrame)
			{
				if (seatPressed)
				{
					int localSeatSerial = LocalSeatSerial;
					Send("stand", default(Vector3), default(Vector3), localSeatSerial);
				}
				else if ((Object)(object)activeTarget != (Object)null && !holdFired && (Object)(object)activeTarget.SyncedHolder != (Object)(object)Player.LocalPlayer)
				{
					int localSeatSerial = ChairItem.Serial(activeTarget);
					Send("sit", default(Vector3), default(Vector3), localSeatSerial);
				}
				activeTarget = null;
				holdFired = false;
				seatPressed = false;
			}
			if (!((ButtonControl)current.eKey).isPressed && !((ButtonControl)current.eKey).wasReleasedThisFrame && (Object)(object)activeTarget != (Object)null && Time.unscaledTime - useStarted > 2f)
			{
				activeTarget = null;
				holdFired = false;
			}
		}

		private void DrawInteractionHint()
		{
			//IL_0063: 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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Expected O, but got Unknown
			if (IsLocalSeated)
			{
				if (hintStyle == null)
				{
					hintStyle = new GUIStyle(GUI.skin.box)
					{
						fontSize = 15,
						fontStyle = (FontStyle)1,
						alignment = (TextAnchor)4
					};
				}
				GUI.Box(new Rect((float)Screen.width / 2f - 270f, (float)Screen.height * 0.73f, 540f, 42f), "Tap E or Space to stand", hintStyle);
				return;
			}
			Item val = activeTarget ?? InteractionTarget();
			if (!((Object)(object)val == (Object)null))
			{
				bool num = (Object)(object)val.SyncedHolder == (Object)(object)Player.LocalPlayer;
				ChairData chairData = Find(ChairItem.Serial(val));
				string text = (num ? ("Hold E to deploy " + ChairItem.Name(ChairItem.Kind(val))) : (((chairData != null && chairData.occupant != 0L) ? "Occupied - " : "Tap E to sit  |  Hold E to pick up  |  ") + ChairItem.Name(ChairItem.Kind(val)) + " - Owner: " + ((chairData == null || string.IsNullOrEmpty(chairData.ownerName)) ? "Unknown" : chairData.ownerName)));
				if ((Object)(object)activeTarget != (Object)null && Keyboard.current != null && ((ButtonControl)Keyboard.current.eKey).isPressed)
				{
					text = text + "   " + Mathf.Clamp01((Time.unscaledTime - useStarted) / 0.8f).ToString("P0");
				}
				if (hintStyle == null)
				{
					hintStyle = new GUIStyle(GUI.skin.box)
					{
						fontSize = 15,
						fontStyle = (FontStyle)1,
						alignment = (TextAnchor)4
					};
				}
				GUI.Box(new Rect((float)Screen.width / 2f - 370f, (float)Screen.height * 0.73f, 740f, 42f), text, hintStyle);
			}
		}
	}
	internal static class Wallet
	{
		private static Type WalletType => Type.GetType("NoSharedMoney.Wallets, NoSharedMoney", throwOnError: false);

		public static int Balance(Player player)
		{
			Type walletType = WalletType;
			if (walletType != null)
			{
				return (int)AccessTools.Method(walletType, "Get", new Type[1] { typeof(Player) }, (Type[])null).Invoke(null, new object[1] { player });
			}
			return MoneyManager.Money;
		}

		public static bool Charge(Player player, int cost)
		{
			Type walletType = WalletType;
			if (walletType != null)
			{
				MethodInfo methodInfo = AccessTools.Method(walletType, "Get", new Type[1] { typeof(Player) }, (Type[])null);
				MethodInfo methodInfo2 = AccessTools.Method(walletType, "Remove", new Type[2]
				{
					typeof(Player),
					typeof(int)
				}, (Type[])null);
				if ((int)methodInfo.Invoke(null, new object[1] { player }) < cost)
				{
					return false;
				}
				methodInfo2.Invoke(null, new object[2] { player, cost });
				return true;
			}
			if ((Object)(object)MoneyManager.Instance == (Object)null || !MoneyManager.CanAfford(cost))
			{
				return false;
			}
			MoneyManager.RemoveMoney(cost, player);
			return true;
		}

		public static void Credit(Player player, int amount)
		{
			Type walletType = WalletType;
			if (walletType != null)
			{
				AccessTools.Method(walletType, "Add", new Type[2]
				{
					typeof(Player),
					typeof(int)
				}, (Type[])null).Invoke(null, new object[2] { player, amount });
			}
			else
			{
				MoneyManager.AddMoney(amount, player);
			}
		}
	}
	[HarmonyPatch(typeof(PlayerHolding), "PickUpInput")]
	internal static class FishingChairCaptureInteract
	{
		private static bool Prefix()
		{
			if (!((Object)(object)Plugin.Instance == (Object)null))
			{
				return !Plugin.Instance.CapturesInteract();
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(GameInfo), "Awake")]
	internal static class RegisterFishingChair
	{
		private static void Postfix()
		{
			try
			{
				ChairItem.Register();
			}
			catch (Exception ex)
			{
				Plugin.Log("Fishing Chair registration deferred: " + ex.Message);
			}
		}
	}
	[HarmonyPatch(typeof(Interactable), "Hover")]
	internal static class FishingChairVendorHoverStart
	{
		private static void Postfix(Interactable __instance)
		{
			if ((Object)(object)Plugin.Instance != (Object)null)
			{
				Plugin.Instance.SetHoveredInteractable((Component)(object)__instance, active: true);
			}
		}
	}
	[HarmonyPatch(typeof(Interactable), "UnHover")]
	internal static class FishingChairVendorHoverStop
	{
		private static void Postfix(Interactable __instance)
		{
			if ((Object)(object)Plugin.Instance != (Object)null)
			{
				Plugin.Instance.SetHoveredInteractable((Component)(object)__instance, active: false);
			}
		}
	}
	[HarmonyPatch(typeof(Item), "GetName")]
	internal static class FishingChairName
	{
		private static bool Prefix(Item __instance, ref string __result)
		{
			if (!ChairItem.Is(__instance))
			{
				return true;
			}
			__result = ChairItem.Name(ChairItem.Kind(__instance));
			return false;
		}
	}
	[HarmonyPatch(typeof(MoneyManager), "SellItem")]
	internal static class FishingChairSale
	{
		private static void Postfix(Item item)
		{
			if (ChairItem.Is(item) && (Object)(object)Plugin.Instance != (Object)null)
			{
				Plugin.Instance.CompleteSale(item);
			}
		}
	}
	[HarmonyPatch(typeof(Item), "SetSyncedHolder")]
	internal static class FishingChairHolder
	{
		private static void Postfix(Item __instance)
		{
			if (ChairItem.Is(__instance) && !((Object)(object)__instance.SyncedHolder == (Object)null) && !((Object)(object)Plugin.Instance == (Object)null))
			{
				ChairData chairData = Plugin.Instance.Find(ChairItem.Serial(__instance));
				if (chairData != null)
				{
					chairData.deployed = false;
					chairData.occupant = 0uL;
				}
			}
		}
	}
	[HarmonyPatch(typeof(SaveManager), "SaveServer")]
	internal static class SaveFishingChairs
	{
		private static void Postfix()
		{
			if ((Object)(object)Plugin.Instance != (Object)null)
			{
				Plugin.Instance.Persist();
			}
		}
	}
	[HarmonyPatch(typeof(SaveManager), "GetWorldItemSavePriority")]
	internal static class FishingChairSavePriority
	{
		private static bool Prefix(Item item, ref int __result)
		{
			if (!ChairItem.Is(item))
			{
				return true;
			}
			__result = 0;
			return false;
		}
	}
	[HarmonyPatch(typeof(ItemManager), "RemoveItemsFarAwar")]
	internal static class KeepFishingChairs
	{
		private static void Prefix(List<Item> toRemove)
		{
			toRemove.RemoveAll(ChairItem.Is);
		}
	}
	[HarmonyPatch(typeof(Item), "PickUp")]
	internal static class NoDirectFishingChairPickup
	{
		private static bool Prefix(Item __instance, bool calledFromLocal, bool sendToServer)
		{
			if (calledFromLocal || sendToServer)
			{
				return !Plugin.IsDeployed(__instance);
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(Item), "get_CanPickUp")]
	internal static class FishingChairPickupPrompt
	{
		private static void Postfix(Item __instance, ref bool __result)
		{
			if (Plugin.IsDeployed(__instance))
			{
				__result = false;
			}
		}
	}
	[HarmonyPatch(typeof(Item), "DestroyItem")]
	internal static class ProtectFishingChair
	{
		private static bool Prefix(Item __instance)
		{
			return !Plugin.IsDeployed(__instance);
		}
	}
	[HarmonyPatch(typeof(RigidbodySync), "SetKinematic")]
	internal static class AnchorFishingChair
	{
		private static void Prefix(RigidbodySync __instance, ref bool kinematic)
		{
			if (Plugin.IsDeployed(((Component)__instance).GetComponent<Item>()))
			{
				kinematic = true;
			}
		}
	}
	[HarmonyPatch(typeof(RigidbodySync), "StartSimulateLocal")]
	internal static class PreventFishingChairExplosion
	{
		private static bool Prefix(RigidbodySync __instance)
		{
			return !Plugin.IsDeployed(((Component)__instance).GetComponent<Item>());
		}
	}
	[HarmonyPatch(typeof(Item), "UpdateLayer")]
	internal static class SolidFishingChair
	{
		private static void Prefix(Item __instance, ref bool ____disablePlayerColOnGround)
		{
			if (Plugin.IsDeployed(__instance))
			{
				____disablePlayerColOnGround = false;
			}
		}
	}
	[HarmonyPatch(typeof(PlayerMovement), "MoveInput")]
	internal static class SeatedMoveInput
	{
		private static bool Prefix(PlayerMovement __instance)
		{
			if (!((Object)(object)Plugin.Instance == (Object)null) && Plugin.Instance.IsLocalSeated && !((Object)(object)Player.LocalPlayer == (Object)null))
			{
				return (Object)(object)Player.LocalPlayer.Movement != (Object)(object)__instance;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(PlayerMovement), "JumpInput")]
	internal static class SeatedJumpInput
	{
		private static bool Prefix(PlayerMovement __instance)
		{
			if (!((Object)(object)Plugin.Instance == (Object)null) && Plugin.Instance.IsLocalSeated && !((Object)(object)Player.LocalPlayer == (Object)null))
			{
				return (Object)(object)Player.LocalPlayer.Movement != (Object)(object)__instance;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(PlayerMovement), "Move")]
	internal static class SeatedMove
	{
		private static bool Prefix(PlayerMovement __instance)
		{
			if (!((Object)(object)Plugin.Instance == (Object)null) && Plugin.Instance.IsLocalSeated && !((Object)(object)Player.LocalPlayer == (Object)null))
			{
				return (Object)(object)Player.LocalPlayer.Movement != (Object)(object)__instance;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(PlayerCamera), "MouseMovement")]
	internal static class ChairShopMouse
	{
		private static bool Prefix()
		{
			if (!((Object)(object)Plugin.Instance == (Object)null))
			{
				return !Plugin.Instance.ShopOpen;
			}
			return true;
		}
	}
	public sealed class FishingChairSlotIcon : MonoBehaviour
	{
		private InventorySlot slot;

		private Renderer previewRenderer;

		private MeshFilter filter;

		private GameObject overlay;

		private bool previousRenderer;

		private bool applied;

		private static readonly Texture2D[] icons = (Texture2D[])(object)new Texture2D[3];

		private static Texture2D Load(int kind)
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Expected O, but got Unknown
			if (kind < 0 || kind >= 3)
			{
				return null;
			}
			if ((Object)(object)icons[kind] != (Object)null)
			{
				return icons[kind];
			}
			using (Stream stream = typeof(FishingChairSlotIcon).Assembly.GetManifestResourceStream("FishingChairsMod." + (new string[3] { "stool", "lawn", "perch" })[kind] + ".png"))
			{
				if (stream == null)
				{
					return null;
				}
				using MemoryStream memoryStream = new MemoryStream();
				stream.CopyTo(memoryStream);
				icons[kind] = new Texture2D(2, 2, (TextureFormat)4, false);
				ImageConversion.LoadImage(icons[kind], memoryStream.ToArray());
				((Texture)icons[kind]).wrapMode = (TextureWrapMode)1;
			}
			return icons[kind];
		}

		private void CreateOverlay(RawImage nativeImage)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: 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_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_0094: 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_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unkn