Decompiled source of ChumBucket v1.1.0

ChumBucket.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ChumBucket.Bucket;
using ChumBucket.Input;
using ChumBucket.Net;
using FishNet;
using FishNet.Broadcast;
using FishNet.Connection;
using FishNet.Managing;
using FishNet.Managing.Client;
using FishNet.Object;
using FishNet.Serializing;
using FishNet.Transporting;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Steamworks;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.InputSystem.Utilities;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("ChumBucket")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Azumatt")]
[assembly: AssemblyProduct("ChumBucket")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("AAB794F9-C222-428E-A7EB-C5140C9DCA16")]
[assembly: AssemblyFileVersion("1.1.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class ExtensionMarkerAttribute : Attribute
	{
		public ExtensionMarkerAttribute(string name)
		{
		}
	}
}
namespace ChumBucket
{
	[BepInPlugin("Azumatt.ChumBucket", "ChumBucket", "1.1.0")]
	public class ChumBucketPlugin : BaseUnityPlugin
	{
		public enum Toggle
		{
			On = 1,
			Off = 0
		}

		internal const string ModName = "ChumBucket";

		internal const string ModVersion = "1.1.0";

		internal const string Author = "Azumatt";

		private const string ModGUID = "Azumatt.ChumBucket";

		private const string ConfigFileName = "Azumatt.ChumBucket.cfg";

		private static readonly string ConfigFileFullPath;

		internal static readonly ManualLogSource ChumBucketLogger;

		private readonly Harmony harmony = new Harmony("Azumatt.ChumBucket");

		internal static ConfigEntry<Toggle> modEnabled;

		internal static ConfigEntry<KeyboardShortcut> placeKey;

		internal static ConfigEntry<string> bucketSize;

		internal static ConfigEntry<float> placeDistance;

		internal static ConfigEntry<float> headroom;

		internal static ConfigEntry<Color> bucketColor;

		internal static ConfigEntry<Color> buttonColor;

		internal static ConfigEntry<float> maxSellDistance;

		internal static ConfigEntry<float> maxSellBoxSize;

		private static string sizeRaw;

		private static Vector3 size;

		internal static bool IsEnabled
		{
			get
			{
				ConfigEntry<Toggle> val = modEnabled;
				if (val != null)
				{
					return val.Value == Toggle.On;
				}
				return false;
			}
		}

		internal static Vector3 Size
		{
			get
			{
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: 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_0050: 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_0060: Unknown result type (might be due to invalid IL or missing references)
				//IL_0065: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				string value = bucketSize.Value;
				if (value == sizeRaw)
				{
					return size;
				}
				sizeRaw = value;
				Vector3 val = ParseVector(value);
				size = new Vector3(Mathf.Max(0.4f, val.x), Mathf.Max(0.3f, val.y), Mathf.Max(0.4f, val.z));
				return size;
			}
		}

		public void Awake()
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Expected O, but got Unknown
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Expected O, but got Unknown
			//IL_0107: 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_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Expected O, but got Unknown
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Expected O, but got Unknown
			bool saveOnConfigSet = ((BaseUnityPlugin)this).Config.SaveOnConfigSet;
			((BaseUnityPlugin)this).Config.SaveOnConfigSet = false;
			AddColorConverter();
			modEnabled = config("1 - General", "Enabled", Toggle.On, "Turn the whole mod off without unloading it.");
			placeKey = config<KeyboardShortcut>("1 - General", "Place Key", new KeyboardShortcut((KeyCode)106, Array.Empty<KeyCode>()), "Key that drops the bucket in front of you and picks it back up. Modifiers work, so 'J + LeftAlt' is fine. Vanilla already owns WASD, QEFRZXCVB, 1-9, space, tab, shift, ctrl and escape.");
			bucketSize = config("2 - Bucket", "Bucket Size", "1.4, 0.8, 1.4", "Outer x, y, z of the bucket in meters. Bigger holds more fish and is more of an eyesore.");
			placeDistance = config("2 - Bucket", "Place Distance", 1.2f, new ConfigDescription("How far in front of you the bucket lands.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 4f), Array.Empty<object>()));
			headroom = config("2 - Bucket", "Headroom", 0.25f, new ConfigDescription("How far above the rim still counts as inside. A fish poking out of the top sells with the rest.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>()));
			bucketColor = config<Color>("2 - Bucket", "Bucket Color", new Color(0.22f, 0.26f, 0.3f), "Color of the walls and floor.");
			buttonColor = config<Color>("2 - Bucket", "Button Color", new Color(0.85f, 0.68f, 0.15f), "Color of the sell button on the rim.");
			maxSellDistance = config("3 - Host", "Max Sell Distance", 8f, new ConfigDescription("Host side. A sell request is dropped unless a player is standing this close to the box being sold. Only the host's value matters.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 50f), Array.Empty<object>()));
			maxSellBoxSize = config("3 - Host", "Max Sell Box Size", 6f, new ConfigDescription("Host side. Biggest half extent a client is allowed to ask us to sell, in meters. Stops a modified client selling the whole island. Only the host's value matters.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 20f), Array.Empty<object>()));
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			harmony.PatchAll(executingAssembly);
			SetupWatcher();
			if (saveOnConfigSet)
			{
				((BaseUnityPlugin)this).Config.SaveOnConfigSet = saveOnConfigSet;
				((BaseUnityPlugin)this).Config.Save();
			}
		}

		private void OnDestroy()
		{
			((BaseUnityPlugin)this).Config.Save();
		}

		private void SetupWatcher()
		{
			FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, "Azumatt.ChumBucket.cfg");
			fileSystemWatcher.Changed += ReadConfigValues;
			fileSystemWatcher.Created += ReadConfigValues;
			fileSystemWatcher.Renamed += ReadConfigValues;
			fileSystemWatcher.IncludeSubdirectories = true;
			fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
			fileSystemWatcher.EnableRaisingEvents = true;
		}

		private void ReadConfigValues(object sender, FileSystemEventArgs e)
		{
			if (!File.Exists(ConfigFileFullPath))
			{
				return;
			}
			try
			{
				((BaseUnityPlugin)this).Config.Reload();
			}
			catch
			{
				ChumBucketLogger.LogError((object)"There was an issue loading your Azumatt.ChumBucket.cfg");
				ChumBucketLogger.LogError((object)"Please check your config entries for spelling and format!");
			}
		}

		private static Vector3 ParseVector(string raw)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			string[] array = raw.Split(new char[1] { ',' });
			Vector3 zero = Vector3.zero;
			for (int i = 0; i < 3 && i < array.Length; i++)
			{
				if (float.TryParse(array[i].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
				{
					((Vector3)(ref zero))[i] = result;
				}
			}
			return zero;
		}

		private ConfigEntry<T> config<T>(string group, string name, T value, ConfigDescription description)
		{
			return ((BaseUnityPlugin)this).Config.Bind<T>(group, name, value, description);
		}

		private ConfigEntry<T> config<T>(string group, string name, T value, string description)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()));
		}

		private static void AddColorConverter()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			if (!TomlTypeConverter.CanConvert(typeof(Color)))
			{
				Color val = default(Color);
				TomlTypeConverter.AddConverter(typeof(Color), new TypeConverter
				{
					ConvertToString = (object value, Type _) => "#" + ColorUtility.ToHtmlStringRGBA((Color)value),
					ConvertToObject = (string value, Type _) => ColorUtility.TryParseHtmlString(value.Trim(), ref val) ? val : Color.white
				});
			}
		}

		static ChumBucketPlugin()
		{
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			string configPath = Paths.ConfigPath;
			char directorySeparatorChar = Path.DirectorySeparatorChar;
			ConfigFileFullPath = configPath + directorySeparatorChar + "Azumatt.ChumBucket.cfg";
			ChumBucketLogger = Logger.CreateLogSource("ChumBucket");
			modEnabled = null;
			placeKey = null;
			bucketSize = null;
			placeDistance = null;
			headroom = null;
			bucketColor = null;
			buttonColor = null;
			maxSellDistance = null;
			maxSellBoxSize = null;
			sizeRaw = null;
			size = new Vector3(1.4f, 0.8f, 1.4f);
		}
	}
	public static class Patches
	{
		[HarmonyPatch(typeof(Player), "InitializePlayer")]
		private static class SpawnBucketSpawner
		{
			private static bool spawned;

			private static void Postfix(Player __instance)
			{
				BucketNet.EnsureRegistered();
				if (!((Object)(object)__instance != (Object)(object)Player.LocalPlayer))
				{
					if (!spawned)
					{
						spawned = true;
						BucketSpawner.Create();
					}
					BucketNet.SayHello();
				}
			}
		}
	}
}
namespace ChumBucket.Net
{
	internal struct BucketPlace : IBroadcast
	{
		internal bool Placed;

		internal Vector3 Position;

		internal float Yaw;

		internal Vector3 Size;

		internal float Headroom;
	}
	internal struct BucketSell : IBroadcast
	{
		internal int Owner;
	}
	internal struct BucketHello : IBroadcast
	{
		internal byte Protocol;
	}
	internal struct BucketState : IBroadcast
	{
		internal int Owner;

		internal ulong SteamId;

		internal bool Placed;

		internal Vector3 Position;

		internal float Yaw;

		internal Vector3 Size;

		internal float Headroom;
	}
	internal static class BucketMessages
	{
		private static bool registered;

		internal static void Register()
		{
			if (!registered)
			{
				registered = true;
				GenericWriter<BucketPlace>.SetWrite((Action<Writer, BucketPlace>)delegate(Writer w, BucketPlace v)
				{
					//IL_000e: 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)
					w.WriteBoolean(v.Placed);
					w.WriteVector3(v.Position);
					w.WriteSingle(v.Yaw);
					w.WriteVector3(v.Size);
					w.WriteSingle(v.Headroom);
				});
				GenericReader<BucketPlace>.SetRead((Func<Reader, BucketPlace>)((Reader r) => new BucketPlace
				{
					Placed = r.ReadBoolean(),
					Position = r.ReadVector3(),
					Yaw = r.ReadSingle(),
					Size = r.ReadVector3(),
					Headroom = r.ReadSingle()
				}));
				GenericWriter<BucketSell>.SetWrite((Action<Writer, BucketSell>)delegate(Writer w, BucketSell v)
				{
					w.WriteInt32(v.Owner);
				});
				GenericReader<BucketSell>.SetRead((Func<Reader, BucketSell>)((Reader r) => new BucketSell
				{
					Owner = r.ReadInt32()
				}));
				GenericWriter<BucketHello>.SetWrite((Action<Writer, BucketHello>)delegate(Writer w, BucketHello v)
				{
					w.WriteUInt8Unpacked(v.Protocol);
				});
				GenericReader<BucketHello>.SetRead((Func<Reader, BucketHello>)((Reader r) => new BucketHello
				{
					Protocol = r.ReadUInt8Unpacked()
				}));
				GenericWriter<BucketState>.SetWrite((Action<Writer, BucketState>)delegate(Writer w, BucketState v)
				{
					//IL_0026: Unknown result type (might be due to invalid IL or missing references)
					//IL_003e: Unknown result type (might be due to invalid IL or missing references)
					w.WriteInt32(v.Owner);
					w.WriteUInt64(v.SteamId);
					w.WriteBoolean(v.Placed);
					w.WriteVector3(v.Position);
					w.WriteSingle(v.Yaw);
					w.WriteVector3(v.Size);
					w.WriteSingle(v.Headroom);
				});
				GenericReader<BucketState>.SetRead((Func<Reader, BucketState>)((Reader r) => new BucketState
				{
					Owner = r.ReadInt32(),
					SteamId = r.ReadUInt64(),
					Placed = r.ReadBoolean(),
					Position = r.ReadVector3(),
					Yaw = r.ReadSingle(),
					Size = r.ReadVector3(),
					Headroom = r.ReadSingle()
				}));
			}
		}
	}
	internal static class BucketNet
	{
		private const byte Protocol = 1;

		private const float MinSize = 0.4f;

		internal const float HostReplyTimeout = 3f;

		private static NetworkManager? registeredOn;

		private static bool wireSeen;

		private static bool warnedNoHost;

		private static readonly Dictionary<int, BucketState> Placements = new Dictionary<int, BucketState>();

		private static readonly List<Item> Sellable = new List<Item>();

		internal static int StatesForMe { get; private set; }

		internal static int LocalClientId
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)registeredOn))
				{
					return -1;
				}
				return registeredOn.ClientManager.Connection.ClientId;
			}
		}

		internal static void EnsureRegistered()
		{
			NetworkManager networkManager = InstanceFinder.NetworkManager;
			if (Object.op_Implicit((Object)(object)networkManager) && networkManager != registeredOn)
			{
				registeredOn = networkManager;
				warnedNoHost = false;
				BucketMessages.Register();
				networkManager.ClientManager.RegisterBroadcast<BucketState>((Action<BucketState, Channel>)OnState);
				networkManager.ClientManager.OnClientConnectionState += OnClientConnectionState;
				networkManager.ServerManager.RegisterBroadcast<BucketPlace>((Action<NetworkConnection, BucketPlace, Channel>)OnPlace, true);
				networkManager.ServerManager.RegisterBroadcast<BucketSell>((Action<NetworkConnection, BucketSell, Channel>)OnSell, true);
				networkManager.ServerManager.RegisterBroadcast<BucketHello>((Action<NetworkConnection, BucketHello, Channel>)OnHello, true);
				networkManager.ServerManager.OnRemoteConnectionState += OnRemoteConnectionState;
				networkManager.ServerManager.OnServerConnectionState += OnServerConnectionState;
				ChumBucketPlugin.ChumBucketLogger.LogInfo((object)$"Broadcasts registered. I'm client {LocalClientId}, server started {InstanceFinder.IsServerStarted}");
			}
		}

		internal static void SayHello()
		{
			Send<BucketHello>(new BucketHello
			{
				Protocol = 1
			}, (Action<NetworkConnection, BucketHello, Channel>)OnHello);
		}

		internal static void RequestPlace(Vector3 position, float yaw, Vector3 size, float headroom)
		{
			//IL_0012: 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_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if (Send<BucketPlace>(new BucketPlace
			{
				Placed = true,
				Position = position,
				Yaw = yaw,
				Size = size,
				Headroom = headroom
			}, (Action<NetworkConnection, BucketPlace, Channel>)OnPlace))
			{
				BucketSpawner.WatchForHostReply(StatesForMe);
			}
		}

		internal static void RequestRecall()
		{
			if (Send<BucketPlace>(default(BucketPlace), (Action<NetworkConnection, BucketPlace, Channel>)OnPlace))
			{
				BucketSpawner.WatchForHostReply(StatesForMe);
			}
		}

		internal static void RequestSell(int owner)
		{
			Send<BucketSell>(new BucketSell
			{
				Owner = owner
			}, (Action<NetworkConnection, BucketSell, Channel>)OnSell);
		}

		private static bool Send<T>(T message, Action<NetworkConnection, T, Channel> handler) where T : struct, IBroadcast
		{
			ClientManager clientManager = InstanceFinder.ClientManager;
			if (clientManager == null || !clientManager.Started)
			{
				return false;
			}
			if (InstanceFinder.IsServerStarted)
			{
				handler(clientManager.Connection, message, (Channel)0);
				return false;
			}
			clientManager.Broadcast<T>(message, (Channel)0);
			return true;
		}

		internal static void ReportNoHostReply(int seenWhenSent)
		{
			if (!warnedNoHost && StatesForMe == seenWhenSent)
			{
				warnedNoHost = true;
				ChumBucketPlugin.ChumBucketLogger.LogWarning((object)$"No answer from the host in {3f}s. It almost certainly doesn't have ChumBucket installed - the host needs it, nothing else can sell.");
				ChatManager.ChatMessage("<color=#D9AD26>ChumBucket:</color> the host doesn't have the mod, so buckets can't be placed.");
			}
		}

		private static void OnPlace(NetworkConnection conn, BucketPlace msg, Channel channel)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: 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_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			if (!ChumBucketPlugin.IsEnabled || conn == (NetworkConnection)null)
			{
				return;
			}
			int clientId = conn.ClientId;
			if (!msg.Placed)
			{
				if (Placements.Remove(clientId))
				{
					Publish(new BucketState
					{
						Owner = clientId,
						Placed = false
					});
				}
				return;
			}
			if (!NearAPlayer(msg.Position))
			{
				ChumBucketPlugin.ChumBucketLogger.LogWarning((object)$"Dropped a bucket placement at {msg.Position} from client {clientId}, nobody is standing near it");
				return;
			}
			float num = ChumBucketPlugin.maxSellBoxSize.Value * 2f;
			BucketState bucketState = new BucketState
			{
				Owner = clientId,
				SteamId = SteamIdOf(conn),
				Placed = true,
				Position = msg.Position,
				Yaw = msg.Yaw,
				Size = new Vector3(Mathf.Clamp(msg.Size.x, 0.4f, num), Mathf.Clamp(msg.Size.y, 0.4f, num), Mathf.Clamp(msg.Size.z, 0.4f, num)),
				Headroom = Mathf.Clamp(msg.Headroom, 0f, num)
			};
			Placements[clientId] = bucketState;
			Publish(bucketState);
		}

		private static void OnSell(NetworkConnection conn, BucketSell msg, Channel channel)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: 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_008a: Unknown result type (might be due to invalid IL or missing references)
			if (!ChumBucketPlugin.IsEnabled || conn == (NetworkConnection)null || !Placements.TryGetValue(msg.Owner, out var value))
			{
				return;
			}
			if (!NearAPlayer(value.Position))
			{
				ChumBucketPlugin.ChumBucketLogger.LogWarning((object)$"Dropped a sell request for bucket {msg.Owner}, nobody is standing near it");
				return;
			}
			ChumBucket.Bucket.Bucket.CollectContents(ChumBucket.Bucket.Bucket.InteriorCenterFor(value.Position, value.Size, value.Headroom), ChumBucket.Bucket.Bucket.InteriorHalfExtentsFor(value.Size, value.Headroom), Quaternion.Euler(0f, value.Yaw, 0f), Sellable);
			foreach (Item item in Sellable)
			{
				MoneyManager.SellItem(item);
				item.DestroyItem((byte)0, byte.MaxValue);
			}
			ChumBucketPlugin.ChumBucketLogger.LogInfo((object)$"Sold {Sellable.Count} item(s) out of bucket {msg.Owner}");
			Sellable.Clear();
		}

		private static void OnHello(NetworkConnection conn, BucketHello msg, Channel channel)
		{
			if (conn == (NetworkConnection)null || msg.Protocol != 1)
			{
				return;
			}
			foreach (BucketState value in Placements.Values)
			{
				InstanceFinder.ServerManager.Broadcast<BucketState>(conn, value, true, (Channel)0);
			}
		}

		private static void OnRemoteConnectionState(NetworkConnection conn, RemoteConnectionStateArgs args)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			if ((int)args.ConnectionState == 0 && Placements.Remove(conn.ClientId))
			{
				Publish(new BucketState
				{
					Owner = conn.ClientId,
					Placed = false
				});
			}
		}

		private static void OnServerConnectionState(ServerConnectionStateArgs args)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			if ((int)args.ConnectionState == 1)
			{
				Placements.Clear();
			}
		}

		private static void Publish(BucketState state)
		{
			InstanceFinder.ServerManager.Broadcast<BucketState>(state, true, (Channel)0);
			if (InstanceFinder.IsClientStarted)
			{
				ChumBucket.Bucket.Bucket.Apply(state);
			}
		}

		private static bool NearAPlayer(Vector3 position)
		{
			//IL_000b: 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_0025: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			float value = ChumBucketPlugin.maxSellDistance.Value;
			Player nearestAlivePlayer = PlayerManager.GetNearestAlivePlayer(position);
			if (Object.op_Implicit((Object)(object)nearestAlivePlayer))
			{
				Vector3 val = nearestAlivePlayer.Transform.position - position;
				return ((Vector3)(ref val)).sqrMagnitude <= value * value;
			}
			return false;
		}

		private static ulong SteamIdOf(NetworkConnection conn)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			if (!ConnectionManager.IsUsingSteam)
			{
				return SteamUser.GetSteamID().m_SteamID;
			}
			if (!ulong.TryParse(conn.GetAddress(), out var result))
			{
				return 0uL;
			}
			return result;
		}

		private static void OnState(BucketState state, Channel channel)
		{
			if (!wireSeen)
			{
				wireSeen = true;
				ChumBucketPlugin.ChumBucketLogger.LogInfo((object)"First bucket state came back over the wire, the broadcast path is good");
			}
			if (state.Owner == LocalClientId)
			{
				StatesForMe++;
			}
			ChumBucket.Bucket.Bucket.Apply(state);
		}

		private static void OnClientConnectionState(ClientConnectionStateArgs args)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			if ((int)args.ConnectionState == 1)
			{
				warnedNoHost = false;
				ChumBucket.Bucket.Bucket.ClearAll();
			}
		}
	}
}
namespace ChumBucket.Input
{
	public static class KeyboardExtensions
	{
		[SpecialName]
		public sealed class <G>$8D1D3E80A18AA9715780B6CB7003B2F1
		{
			[SpecialName]
			public static class <M>$895AB635D4D087636CF1C26BA650BA11
			{
			}

			[ExtensionMarker("<M>$895AB635D4D087636CF1C26BA650BA11")]
			public bool IsKeyDown()
			{
				throw null;
			}

			[ExtensionMarker("<M>$895AB635D4D087636CF1C26BA650BA11")]
			public bool IsKeyHeld()
			{
				throw null;
			}

			[ExtensionMarker("<M>$895AB635D4D087636CF1C26BA650BA11")]
			public string? VanillaAction()
			{
				throw null;
			}
		}

		private static readonly Dictionary<KeyCode, Key> Keys = BuildKeyLookup();

		public static bool IsKeyDown(this KeyboardShortcut shortcut)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			KeyControl val = Control(((KeyboardShortcut)(ref shortcut)).MainKey);
			if (val != null && ((ButtonControl)val).wasPressedThisFrame)
			{
				return ((KeyboardShortcut)(ref shortcut)).Modifiers.All(IsHeld);
			}
			return false;
		}

		public static bool IsKeyHeld(this KeyboardShortcut shortcut)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			KeyControl val = Control(((KeyboardShortcut)(ref shortcut)).MainKey);
			if (val != null && ((ButtonControl)val).isPressed)
			{
				return ((KeyboardShortcut)(ref shortcut)).Modifiers.All(IsHeld);
			}
			return false;
		}

		public static string? VanillaAction(this KeyboardShortcut shortcut)
		{
			//IL_0002: 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_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			KeyControl val = Control(((KeyboardShortcut)(ref shortcut)).MainKey);
			if (val == null || !Object.op_Implicit((Object)(object)GameInfo._instance) || !Object.op_Implicit((Object)(object)GameInfo.Input) || !Object.op_Implicit((Object)(object)GameInfo.Input.actions))
			{
				return null;
			}
			foreach (InputAction action in GameInfo.Input.actions)
			{
				Enumerator<InputBinding> enumerator2 = action.bindings.GetEnumerator();
				try
				{
					while (enumerator2.MoveNext())
					{
						InputBinding current2 = enumerator2.Current;
						if (!((InputBinding)(ref current2)).isComposite && InputControlPath.Matches(((InputBinding)(ref current2)).effectivePath, (InputControl)(object)val))
						{
							return action.name;
						}
					}
				}
				finally
				{
					((IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose();
				}
			}
			return null;
		}

		private static KeyControl? Control(KeyCode code)
		{
			//IL_000e: 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)
			Keyboard current = Keyboard.current;
			if (current == null || !Keys.TryGetValue(code, out var value))
			{
				return null;
			}
			return current[value];
		}

		private static bool IsHeld(KeyCode code)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			KeyControl val = Control(code);
			if (val != null)
			{
				return ((ButtonControl)val).isPressed;
			}
			return false;
		}

		private static Dictionary<KeyCode, Key> BuildKeyLookup()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<KeyCode, Key> dictionary = new Dictionary<KeyCode, Key>();
			foreach (KeyCode value in Enum.GetValues(typeof(KeyCode)))
			{
				string text = ((object)value/*cast due to .constrained prefix*/).ToString();
				if (text.StartsWith("Alpha"))
				{
					text = "Digit" + text.Substring(5);
				}
				else if (text.StartsWith("Keypad"))
				{
					text = "Numpad" + text.Substring(6);
				}
				else
				{
					string text2;
					switch (text)
					{
					case "Return":
						text2 = "Enter";
						break;
					case "LeftControl":
						text2 = "LeftCtrl";
						break;
					case "RightControl":
						text2 = "RightCtrl";
						break;
					case "LeftWindows":
					case "LeftCommand":
					case "LeftApple":
						text2 = "LeftMeta";
						break;
					case "RightWindows":
					case "RightCommand":
					case "RightApple":
						text2 = "RightMeta";
						break;
					case "BackQuote":
						text2 = "Backquote";
						break;
					case "Print":
						text2 = "PrintScreen";
						break;
					default:
						text2 = text;
						break;
					}
					text = text2;
				}
				if (Enum.TryParse<Key>(text, ignoreCase: true, out Key result) && (int)result != 0)
				{
					dictionary[value] = result;
				}
			}
			return dictionary;
		}
	}
}
namespace ChumBucket.Bucket
{
	public class Bucket : MonoBehaviour
	{
		private const float WallThickness = 0.06f;

		private const float ScanInterval = 0.1f;

		internal static readonly Dictionary<int, Bucket> All = new Dictionary<int, Bucket>();

		private static Collider[] hits = (Collider[])(object)new Collider[128];

		private static Shader? litShader;

		private static Material? panelMaterial;

		private static Material? buttonMaterial;

		private readonly List<Item> contents = new List<Item>();

		private Vector3 interiorCenterLocal;

		private float nextScan;

		private BucketState state;

		internal int Count { get; private set; }

		internal int Worth { get; private set; }

		internal int Owner => state.Owner;

		internal bool IsMine => state.Owner == BucketNet.LocalClientId;

		internal string OwnerName { get; private set; } = "";

		internal Vector3 InteriorCenter => ((Component)this).transform.TransformPoint(interiorCenterLocal);

		internal Vector3 InteriorHalfExtents { get; private set; }

		internal static Bucket? Mine
		{
			get
			{
				if (!All.TryGetValue(BucketNet.LocalClientId, out Bucket value))
				{
					return null;
				}
				return value;
			}
		}

		internal static Material PanelMaterial => Tint(ref panelMaterial, ChumBucketPlugin.bucketColor.Value);

		internal static Material ButtonMaterial => Tint(ref buttonMaterial, ChumBucketPlugin.buttonColor.Value);

		internal static void Apply(BucketState incoming)
		{
			All.TryGetValue(incoming.Owner, out Bucket value);
			if (!incoming.Placed)
			{
				if (Object.op_Implicit((Object)(object)value))
				{
					Object.Destroy((Object)(object)((Component)value).gameObject);
				}
			}
			else if (!Object.op_Implicit((Object)(object)value) || !value.Matches(incoming))
			{
				if (Object.op_Implicit((Object)(object)value))
				{
					Object.Destroy((Object)(object)((Component)value).gameObject);
				}
				All[incoming.Owner] = Build(incoming);
			}
		}

		internal static void ClearAll()
		{
			foreach (Bucket item in new List<Bucket>(All.Values))
			{
				if (Object.op_Implicit((Object)(object)item))
				{
					Object.Destroy((Object)(object)((Component)item).gameObject);
				}
			}
			All.Clear();
		}

		internal static Vector3 InteriorCenterFor(Vector3 pos, Vector3 size, float headroom)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: 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_0025: Unknown result type (might be due to invalid IL or missing references)
			return pos + Vector3.up * (0.06f + (size.y - 0.06f + headroom) * 0.5f);
		}

		internal static Vector3 InteriorHalfExtentsFor(Vector3 size, float headroom)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: 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)
			return new Vector3((size.x - 0.12f) * 0.5f, (size.y - 0.06f + headroom) * 0.5f, (size.z - 0.12f) * 0.5f);
		}

		private static Bucket Build(BucketState incoming)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//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)
			//IL_008e: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Expected O, but got Unknown
			//IL_00d2: 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_00fa: 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_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Expected O, but got Unknown
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Expected O, but got Unknown
			//IL_015f: 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_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Expected O, but got Unknown
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: 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_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Expected O, but got Unknown
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			Vector3 size = incoming.Size;
			float num = size.y - 0.06f;
			GameObject val = new GameObject("ChumBucket");
			val.SetActive(false);
			val.transform.SetPositionAndRotation(incoming.Position, Quaternion.Euler(0f, incoming.Yaw, 0f));
			Material mat = PanelMaterial;
			int layer = LayerMask.NameToLayer("Level");
			Panel(val, mat, layer, new Vector3(0f, 0.03f, 0f), new Vector3(size.x, 0.06f, size.z));
			Panel(val, mat, layer, new Vector3(0f, 0.06f + num * 0.5f, (size.z - 0.06f) * 0.5f), new Vector3(size.x, num, 0.06f));
			Panel(val, mat, layer, new Vector3(0f, 0.06f + num * 0.5f, (0f - (size.z - 0.06f)) * 0.5f), new Vector3(size.x, num, 0.06f));
			Panel(val, mat, layer, new Vector3((size.x - 0.06f) * 0.5f, 0.06f + num * 0.5f, 0f), new Vector3(0.06f, num, size.z - 0.12f));
			Panel(val, mat, layer, new Vector3((0f - (size.x - 0.06f)) * 0.5f, 0.06f + num * 0.5f, 0f), new Vector3(0.06f, num, size.z - 0.12f));
			Bucket bucket = val.AddComponent<Bucket>();
			bucket.state = incoming;
			bucket.interiorCenterLocal = new Vector3(0f, 0.06f + (num + incoming.Headroom) * 0.5f, 0f);
			bucket.InteriorHalfExtents = InteriorHalfExtentsFor(size, incoming.Headroom);
			if (!bucket.IsMine && incoming.SteamId != 0L)
			{
				bucket.OwnerName = SteamFriends.GetFriendPersonaName(new CSteamID(incoming.SteamId));
			}
			SellButton.Attach(val, bucket, new Vector3(0f, size.y + 0.08f, 0f - (size.z * 0.5f + 0.04f)));
			val.SetActive(true);
			return bucket;
		}

		private bool Matches(BucketState incoming)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: 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)
			if (state.Position == incoming.Position && state.Yaw == incoming.Yaw && state.Size == incoming.Size && state.Headroom == incoming.Headroom)
			{
				return state.SteamId == incoming.SteamId;
			}
			return false;
		}

		private static GameObject Panel(GameObject parent, Material mat, int layer, Vector3 localPos, Vector3 localScale)
		{
			//IL_002a: 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)
			GameObject val = GameObject.CreatePrimitive((PrimitiveType)3);
			((Object)val).name = "Panel";
			val.transform.SetParent(parent.transform, false);
			val.transform.localPosition = localPos;
			val.transform.localScale = localScale;
			if (layer >= 0)
			{
				val.layer = layer;
			}
			MeshRenderer val2 = default(MeshRenderer);
			if (val.TryGetComponent<MeshRenderer>(ref val2))
			{
				((Renderer)val2).sharedMaterial = mat;
			}
			return val;
		}

		private static Material Tint(ref Material? material, Color color)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)material))
			{
				if (!Object.op_Implicit((Object)(object)litShader))
				{
					litShader = Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Universal Render Pipeline/Unlit") ?? Shader.Find("Sprites/Default");
				}
				material = new Material(litShader);
			}
			material.color = color;
			if (material.HasProperty("_BaseColor"))
			{
				material.SetColor("_BaseColor", color);
			}
			return material;
		}

		internal static void ApplyColors()
		{
			//IL_0016: 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)
			if (Object.op_Implicit((Object)(object)panelMaterial))
			{
				Tint(ref panelMaterial, ChumBucketPlugin.bucketColor.Value);
			}
			if (Object.op_Implicit((Object)(object)buttonMaterial))
			{
				Tint(ref buttonMaterial, ChumBucketPlugin.buttonColor.Value);
			}
		}

		internal static void ResendMine()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			Bucket mine = Mine;
			if (mine != null)
			{
				BucketNet.RequestPlace(((Component)mine).transform.position, mine.state.Yaw, ChumBucketPlugin.Size, ChumBucketPlugin.headroom.Value);
			}
		}

		internal static void CollectContents(Vector3 center, Vector3 halfExtents, Quaternion rotation, List<Item> into)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: 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_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_003a: 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)
			into.Clear();
			int num;
			for (num = Physics.OverlapBoxNonAlloc(center, halfExtents, hits, rotation, LayerMask.op_Implicit(GameInfo.ItemLayer)); num == hits.Length; num = Physics.OverlapBoxNonAlloc(center, halfExtents, hits, rotation, LayerMask.op_Implicit(GameInfo.ItemLayer)))
			{
				hits = (Collider[])(object)new Collider[hits.Length * 2];
			}
			for (int i = 0; i < num; i++)
			{
				Collider val = hits[i];
				if (((Component)((Component)val).transform).CompareTag("Item"))
				{
					Item val2 = ItemManager.Get(val);
					if (Object.op_Implicit((Object)(object)val2) && !Object.op_Implicit((Object)(object)val2.Holder) && !val2.IsDestroying && !((NetworkBehaviour)val2).IsDeinitializing && !Object.op_Implicit((Object)(object)val2.DeadPlayer) && (!Object.op_Implicit((Object)(object)val2.Creature) || val2.Creature.IsDead) && !into.Contains(val2))
					{
						into.Add(val2);
					}
				}
			}
		}

		internal void Refresh()
		{
			//IL_0020: 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_0031: Unknown result type (might be due to invalid IL or missing references)
			if (Time.unscaledTime < nextScan)
			{
				return;
			}
			nextScan = Time.unscaledTime + 0.1f;
			CollectContents(InteriorCenter, InteriorHalfExtents, ((Component)this).transform.rotation, contents);
			int num = 0;
			foreach (Item content in contents)
			{
				num += content.TotalWorth;
			}
			Count = contents.Count;
			Worth = num;
		}

		private void OnDestroy()
		{
			if (All.TryGetValue(state.Owner, out Bucket value) && (Object)(object)value == (Object)(object)this)
			{
				All.Remove(state.Owner);
			}
		}
	}
	public class BucketSpawner : MonoBehaviour
	{
		private static BucketSpawner? instance;

		internal static void Create()
		{
			//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_0010: Expected O, but got Unknown
			GameObject val = new GameObject("BucketSpawner");
			Object.DontDestroyOnLoad((Object)val);
			instance = val.AddComponent<BucketSpawner>();
			WarnOnVanillaKey();
			ChumBucketPlugin.placeKey.SettingChanged += delegate
			{
				WarnOnVanillaKey();
			};
			ChumBucketPlugin.bucketColor.SettingChanged += delegate
			{
				Bucket.ApplyColors();
			};
			ChumBucketPlugin.buttonColor.SettingChanged += delegate
			{
				Bucket.ApplyColors();
			};
			ChumBucketPlugin.bucketSize.SettingChanged += delegate
			{
				Bucket.ResendMine();
			};
			ChumBucketPlugin.headroom.SettingChanged += delegate
			{
				Bucket.ResendMine();
			};
		}

		internal static void WatchForHostReply(int seenWhenSent)
		{
			if (Object.op_Implicit((Object)(object)instance))
			{
				((MonoBehaviour)instance).StartCoroutine(WaitForHostReply(seenWhenSent));
			}
		}

		private static IEnumerator WaitForHostReply(int seenWhenSent)
		{
			yield return (object)new WaitForSecondsRealtime(3f);
			BucketNet.ReportNoHostReply(seenWhenSent);
		}

		private static void WarnOnVanillaKey()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			string text = ChumBucketPlugin.placeKey.Value.VanillaAction();
			if (text != null)
			{
				ChumBucketPlugin.ChumBucketLogger.LogWarning((object)$"Place Key is {ChumBucketPlugin.placeKey.Value}, which the game already uses for '{text}'. Both will fire. Pick something else in the config.");
			}
		}

		private void Update()
		{
			//IL_000d: 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)
			//IL_0049: 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_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: 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)
			//IL_0074: 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_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: 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_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			if (!ChumBucketPlugin.IsEnabled || !ChumBucketPlugin.placeKey.Value.IsKeyDown())
			{
				return;
			}
			Player localPlayer = Player.LocalPlayer;
			if (!Object.op_Implicit((Object)(object)localPlayer) || localPlayer.BlockInputs)
			{
				return;
			}
			if (Object.op_Implicit((Object)(object)Bucket.Mine))
			{
				BucketNet.RequestRecall();
				return;
			}
			Vector3 val = localPlayer.CurPlayerRot * Vector3.forward;
			Vector3 val2 = localPlayer.Transform.position + val * ChumBucketPlugin.placeDistance.Value;
			RaycastHit val3 = default(RaycastHit);
			if (Physics.Raycast(val2 + Vector3.up * 1.5f, Vector3.down, ref val3, 4f, LayerMask.op_Implicit(GameInfo.LevelLayer)))
			{
				val2 = ((RaycastHit)(ref val3)).point;
			}
			Vector3 position = val2;
			Quaternion val4 = Quaternion.LookRotation(val, Vector3.up);
			BucketNet.RequestPlace(position, ((Quaternion)(ref val4)).eulerAngles.y, ChumBucketPlugin.Size, ChumBucketPlugin.headroom.Value);
		}
	}
	public class SellButton : Interactable
	{
		private Bucket bucket;

		private string hoverText = "";

		private int shownWorth = -1;

		private int shownCount = -1;

		internal static SellButton Attach(GameObject root, Bucket bucket, Vector3 localPos)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_002a: 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_00a5: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("SellButton");
			val.SetActive(false);
			val.transform.SetParent(root.transform, false);
			val.transform.localPosition = localPos;
			val.layer = LayerMask.NameToLayer("Interactable");
			val.tag = "Interactable";
			BoxCollider val2 = val.AddComponent<BoxCollider>();
			val2.size = new Vector3(0.22f, 0.16f, 0.1f);
			GameObject val3 = GameObject.CreatePrimitive((PrimitiveType)3);
			((Object)val3).name = "Mesh";
			val3.transform.SetParent(val.transform, false);
			val3.transform.localScale = new Vector3(0.2f, 0.14f, 0.08f);
			Object.Destroy((Object)(object)val3.GetComponent<Collider>());
			MeshRenderer val4 = default(MeshRenderer);
			if (val3.TryGetComponent<MeshRenderer>(ref val4))
			{
				((Renderer)val4).sharedMaterial = Bucket.ButtonMaterial;
			}
			SellButton sellButton = val.AddComponent<SellButton>();
			sellButton.bucket = bucket;
			((Interactable)sellButton)._interactCol = (Collider)(object)val2;
			((Interactable)sellButton)._textTarget = val.transform;
			((Interactable)sellButton)._modelsToOutline = (GameObject[])(object)new GameObject[1] { val3 };
			val.SetActive(true);
			return sellButton;
		}

		public override void Hover()
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			bucket.Refresh();
			if (!base._isHovering)
			{
				shownWorth = -1;
				shownCount = -1;
				hoverText = BuildText();
				PlayerUI.SetLookAtText(hoverText, ((Interactable)this).TextTarget, default(Vector3), false);
			}
			((Interactable)this).Hover();
			RefreshText();
		}

		public override void UnHover()
		{
			PlayerUI.HideLookAtText(hoverText);
			((Interactable)this).UnHover();
		}

		public override void Interact(Player player)
		{
			((Interactable)this).Interact(player);
			if (bucket.Count > 0)
			{
				BucketNet.RequestSell(bucket.Owner);
			}
			PlayerUI.HideLookAtText(hoverText);
		}

		private void RefreshText()
		{
			if (bucket.Worth != shownWorth || bucket.Count != shownCount)
			{
				hoverText = BuildText();
				PlayerUI.UpdateLookAtText(hoverText);
			}
		}

		private string BuildText()
		{
			shownWorth = bucket.Worth;
			shownCount = bucket.Count;
			if (shownCount == 0)
			{
				return "Empty bucket";
			}
			string text = ((shownCount == 1) ? "" : "s");
			return $"Sell {shownCount} item{text} - ${shownWorth}\n{SpriteManager.GetPickUpInput()}";
		}
	}
}