Decompiled source of HowToFishTweaks v0.32.1

BepInEx\plugins\HowToFishTweaks.dll

Decompiled an hour ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using FishNet.Connection;
using FishNet.Managing.Logging;
using FishNet.Managing.Server;
using FishNet.Object;
using FishNet.Object.Synchronizing;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("HowToFishTweaks")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0")]
[assembly: AssemblyProduct("HowToFishTweaks")]
[assembly: AssemblyTitle("HowToFishTweaks")]
[assembly: AssemblyVersion("0.1.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 HowToFishTweaks
{
	internal static class AdminPatches
	{
		[HarmonyPatch(typeof(DazedCommands), "IsServerCommand")]
		internal static class IsServerCommand_Patch
		{
			private static bool Prefix(string fullCommand, ref bool __result)
			{
				if (string.IsNullOrEmpty(fullCommand) || !fullCommand.StartsWith("/"))
				{
					return true;
				}
				string[] array = fullCommand.Substring(1).Split(' ');
				string text = array[0].ToLowerInvariant();
				string text2 = ((array.Length > 1) ? string.Join(" ", array, 1, array.Length - 1).Trim() : "");
				switch (text)
				{
				case "kill":
				case "give":
				case "kick":
				case "jail":
				case "skins":
				case "worth":
				case "players":
				case "unjail":
				case "fly":
				case "tp":
				case "roulette":
					Plugin.Log.LogInfo((object)("[Admin] command '" + text + "' arg '" + text2 + "'"));
					if (text == null)
					{
						break;
					}
					goto default;
				default:
					switch (text.Length)
					{
					case 4:
					{
						char c = text[2];
						if ((uint)c <= 105u)
						{
							if (c != 'c')
							{
								if (c != 'i' || !(text == "jail"))
								{
									break;
								}
								Jail(text2);
							}
							else
							{
								if (!(text == "kick"))
								{
									break;
								}
								Kick(text2);
							}
						}
						else if (c != 'l')
						{
							if (c != 'v' || !(text == "give"))
							{
								break;
							}
							Say(ClientPowerPatches.Give(text2));
						}
						else
						{
							if (!(text == "kill"))
							{
								break;
							}
							Kill(text2);
						}
						goto IL_039d;
					}
					case 5:
					{
						char c = text[0];
						if (c != 's')
						{
							if (c != 'w' || !(text == "worth"))
							{
								break;
							}
							Say(ClientPowerPatches.Worth(text2));
						}
						else
						{
							if (!(text == "skins"))
							{
								break;
							}
							Say(SkinUnlockPatches.UnlockNow());
						}
						goto IL_039d;
					}
					case 7:
						if (!(text == "players"))
						{
							break;
						}
						ListPlayers();
						goto IL_039d;
					case 6:
						if (!(text == "unjail"))
						{
							break;
						}
						Unjail(text2);
						goto IL_039d;
					case 3:
						if (!(text == "fly"))
						{
							break;
						}
						Say(FlySharePatches.Handle(text2));
						goto IL_039d;
					case 2:
						if (!(text == "tp"))
						{
							break;
						}
						Say(Teleport(text2));
						goto IL_039d;
					case 8:
						{
							if (!(text == "roulette"))
							{
								break;
							}
							Say(Roulette(text2));
							goto IL_039d;
						}
						IL_039d:
						__result = true;
						return false;
					}
					break;
				case null:
					break;
				}
				return true;
			}
		}

		private static readonly List<string> _jailed = new List<string>();

		private static float _nextJailSweep;

		private static bool RequireHost()
		{
			if ((Object)(object)Server.Instance != (Object)null && ((NetworkBehaviour)Server.Instance).IsServerInitialized)
			{
				return true;
			}
			Say("only the host can kick people.");
			Plugin.Log.LogWarning((object)"[Admin] refused: not server-initialised (are you the host?)");
			return false;
		}

		private static bool RequireConnected()
		{
			if ((Object)(object)Server.Instance != (Object)null)
			{
				return true;
			}
			Say("not connected to a game.");
			return false;
		}

		private static void ListPlayers()
		{
			List<Player> players = PlayerManager.Players;
			if (players == null || players.Count == 0)
			{
				Say("no players.");
				return;
			}
			for (int i = 0; i < players.Count; i++)
			{
				Player val = players[i];
				if (Object.op_Implicit((Object)(object)val))
				{
					bool flag = IsJailed(val.SteamName);
					Say(string.Format("{0}: {1}{2}", i, val.SteamName, flag ? "  [JAILED]" : ""));
				}
			}
		}

		private static Player Find(string name)
		{
			if (string.IsNullOrEmpty(name))
			{
				Say("usage: /kick <name>");
				return null;
			}
			List<Player> players = PlayerManager.Players;
			if (players == null)
			{
				return null;
			}
			string text = Clean(name);
			if (text.Length == 0)
			{
				Say("usage: /kick <name>");
				return null;
			}
			List<Player> list = new List<Player>();
			foreach (Player item in players)
			{
				if (Object.op_Implicit((Object)(object)item) && !string.IsNullOrEmpty(item.SteamName) && !((Object)(object)item == (Object)(object)Player.LocalPlayer))
				{
					list.Add(item);
				}
			}
			int matches;
			string how;
			Player val = Match(list, text, out matches, out how);
			if ((Object)(object)val != (Object)null && matches == 1)
			{
				if (how != "exact")
				{
					Say("matched '" + name + "' -> " + val.SteamName + " (" + how + ").");
				}
				return val;
			}
			if (matches > 1)
			{
				Say($"'{name}' matches {matches} players - be more specific.");
				return null;
			}
			Say("no player matching '" + name + "'. Try /players.");
			Plugin.Log.LogWarning((object)$"[Admin] no match for '{name}' among {players.Count} player(s)");
			return null;
		}

		private static Player Match(List<Player> candidates, string wanted, out int matches, out string how)
		{
			Player result = Single(candidates, (Player p) => Clean(p.SteamName) == wanted, out matches);
			if (matches > 0)
			{
				how = "exact";
				return result;
			}
			result = Single(candidates, delegate(Player p)
			{
				string text = Clean(p.SteamName);
				return text.Contains(wanted) || wanted.Contains(text);
			}, out matches);
			if (matches > 0)
			{
				how = "partial";
				return result;
			}
			int budget = Mathf.Clamp(wanted.Length / 3, 1, 3);
			result = Single(candidates, (Player p) => Distance(Clean(p.SteamName), wanted) <= budget, out matches);
			how = "fuzzy";
			return result;
		}

		private static Player Single(List<Player> candidates, Func<Player, bool> test, out int matches)
		{
			Player val = null;
			matches = 0;
			foreach (Player candidate in candidates)
			{
				if (test(candidate))
				{
					matches++;
					if ((Object)(object)val == (Object)null)
					{
						val = candidate;
					}
				}
			}
			return val;
		}

		private static string Clean(string s)
		{
			if (string.IsNullOrEmpty(s))
			{
				return "";
			}
			StringBuilder stringBuilder = new StringBuilder(s.Length);
			foreach (char c in s)
			{
				if (char.IsLetterOrDigit(c))
				{
					stringBuilder.Append(char.ToLowerInvariant(c));
				}
			}
			return stringBuilder.ToString();
		}

		private static int Distance(string a, string b)
		{
			if (a == b)
			{
				return 0;
			}
			if (a.Length == 0)
			{
				return b.Length;
			}
			if (b.Length == 0)
			{
				return a.Length;
			}
			int[] array = new int[b.Length + 1];
			int[] array2 = new int[b.Length + 1];
			for (int i = 0; i <= b.Length; i++)
			{
				array[i] = i;
			}
			for (int j = 1; j <= a.Length; j++)
			{
				array2[0] = j;
				for (int k = 1; k <= b.Length; k++)
				{
					int num = ((a[j - 1] != b[k - 1]) ? 1 : 0);
					array2[k] = Mathf.Min(Mathf.Min(array2[k - 1] + 1, array[k] + 1), array[k - 1] + num);
				}
				int[] array3 = array;
				array = array2;
				array2 = array3;
			}
			return array[b.Length];
		}

		private static string Teleport(string name)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: 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)
			if (!RequireConnected())
			{
				return "not connected.";
			}
			if (string.IsNullOrEmpty(name))
			{
				return "usage: /tp <name>  (or /tp all)";
			}
			Player localPlayer = Player.LocalPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return "no local player.";
			}
			float y = localPlayer.Transform.eulerAngles.y;
			if (name.Trim().Equals("all", StringComparison.OrdinalIgnoreCase))
			{
				List<Player> players = PlayerManager.Players;
				if (players == null)
				{
					return "no players.";
				}
				int num = 0;
				for (int i = 0; i < players.Count; i++)
				{
					Player val = players[i];
					if (Object.op_Implicit((Object)(object)val) && !((Object)(object)val == (Object)(object)localPlayer))
					{
						Server.Instance.TeleportPlayer(val, SpotNear(localPlayer, num), y);
						num++;
					}
				}
				if (num != 0)
				{
					return $"pulled {num} player(s) to you.";
				}
				return "nobody else here.";
			}
			Player val2 = Find(name);
			if ((Object)(object)val2 == (Object)null)
			{
				return null_or(name);
			}
			Server.Instance.TeleportPlayer(val2, SpotNear(localPlayer, 0), y);
			return "pulled " + val2.SteamName + " to you.";
		}

		private static string null_or(string name)
		{
			return "no player matching '" + name + "'.";
		}

		private static Vector3 SpotNear(Player me, int index)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: 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)
			float num = (float)index * 60f * (MathF.PI / 180f);
			Vector3 val = new Vector3(Mathf.Cos(num), 0f, Mathf.Sin(num)) * 2f;
			return me.Transform.position + val + Vector3.up * 0.5f;
		}

		private static string Roulette(string arg)
		{
			arg = (arg ?? string.Empty).Trim();
			if (arg.Length == 0)
			{
				return "roulette is " + (Plugin.RouletteRigActive ? ("rigged to " + Plugin.RouletteColor.Value) : "fair") + ". Use /roulette green|red|black|off";
			}
			if (arg.Equals("off", StringComparison.OrdinalIgnoreCase))
			{
				Plugin.RouletteRigActive = false;
				return "roulette is fair again.";
			}
			if (!arg.Equals("green", StringComparison.OrdinalIgnoreCase) && !arg.Equals("red", StringComparison.OrdinalIgnoreCase) && !arg.Equals("black", StringComparison.OrdinalIgnoreCase))
			{
				return "pick green, red, black or off.";
			}
			if ((Object)(object)Server.Instance == (Object)null || !((NetworkBehaviour)Server.Instance).IsServerInitialized)
			{
				return "only the host can rig the roulette - their machine spins the ball.";
			}
			Plugin.RouletteColor.Value = arg.ToLowerInvariant();
			Plugin.RouletteRigActive = true;
			return "roulette will always land on " + Plugin.RouletteColor.Value + ((Plugin.RouletteColor.Value == "green") ? " (35x)." : ".");
		}

		private static void Kick(string name)
		{
			if (!RequireHost())
			{
				return;
			}
			Player val = Find(name);
			if (!((Object)(object)val == (Object)null))
			{
				string steamName = val.SteamName;
				NetworkConnection owner = ((NetworkBehaviour)val).Owner;
				if (owner == (NetworkConnection)null)
				{
					Say(steamName + " has no connection to kick.");
					return;
				}
				owner.Kick((KickReason)0, (LoggingType)3, "Kicked from the lobby by the host.");
				Say("kicked " + steamName + ".");
				Plugin.Log.LogInfo((object)("[Admin] kicked " + steamName));
			}
		}

		private static void Kill(string name)
		{
			if (RequireConnected())
			{
				Player val = Find(name);
				if (!((Object)(object)val == (Object)null))
				{
					KillPlayer(val);
					Say("killed " + val.SteamName + ".");
				}
			}
		}

		internal static void KillPlayer(Player p)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)p) && !((Object)(object)Server.Instance == (Object)null))
			{
				Server.Instance.HitPlayer(p, 99999, Vector3.zero, p.Transform.position, (byte)1, Player.LocalPlayer);
				Plugin.Log.LogInfo((object)("[Admin] killed " + p.SteamName));
			}
		}

		private static void Jail(string name)
		{
			if (!RequireConnected())
			{
				return;
			}
			Player val = Find(name);
			if (!((Object)(object)val == (Object)null))
			{
				if (IsJailed(val.SteamName))
				{
					Say(val.SteamName + " is already jailed.");
					return;
				}
				_jailed.Add(val.SteamName);
				KillPlayer(val);
				Say("jailed " + val.SteamName + " - they will keep dying until /unjail.");
			}
		}

		private static void Unjail(string name)
		{
			if (string.IsNullOrEmpty(name))
			{
				Say("usage: /unjail <name>");
				return;
			}
			for (int num = _jailed.Count - 1; num >= 0; num--)
			{
				string text = Clean(name);
				if (Clean(_jailed[num]).Contains(text) || text.Contains(Clean(_jailed[num])))
				{
					Say("released " + _jailed[num] + ".");
					_jailed.RemoveAt(num);
					return;
				}
			}
			Say("nobody jailed matching '" + name + "'.");
		}

		private static bool IsJailed(string steamName)
		{
			if (string.IsNullOrEmpty(steamName))
			{
				return false;
			}
			string text = Clean(steamName);
			foreach (string item in _jailed)
			{
				if (Clean(item) == text)
				{
					return true;
				}
			}
			return false;
		}

		internal static void Tick()
		{
			if (_jailed.Count == 0 || (Object)(object)Server.Instance == (Object)null || Time.time < _nextJailSweep)
			{
				return;
			}
			_nextJailSweep = Time.time + Mathf.Max(1f, Plugin.JailKillInterval.Value);
			List<Player> alivePlayers = PlayerManager.AlivePlayers;
			if (alivePlayers == null)
			{
				return;
			}
			for (int i = 0; i < alivePlayers.Count; i++)
			{
				Player val = alivePlayers[i];
				if (Object.op_Implicit((Object)(object)val) && !((Object)(object)val == (Object)(object)Player.LocalPlayer) && IsJailed(val.SteamName))
				{
					KillPlayer(val);
				}
			}
		}

		internal static void SmiteAimedPlayer()
		{
			//IL_0036: 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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: 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_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_00ab: Unknown result type (might be due to invalid IL or missing references)
			if (!RequireConnected())
			{
				return;
			}
			Player localPlayer = Player.LocalPlayer;
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)localPlayer.CamObject == (Object)null)
			{
				Say("no local player.");
				return;
			}
			Vector3 position = localPlayer.CamObject.position;
			Vector3 forward = localPlayer.CamObject.forward;
			Player val = null;
			float num = Plugin.SmiteFovDegrees.Value;
			List<Player> alivePlayers = PlayerManager.AlivePlayers;
			if (alivePlayers != null)
			{
				foreach (Player item in alivePlayers)
				{
					if (!Object.op_Implicit((Object)(object)item) || (Object)(object)item == (Object)(object)localPlayer)
					{
						continue;
					}
					Vector3 val2 = item.Transform.position - position;
					if (!(((Vector3)(ref val2)).sqrMagnitude < 0.01f))
					{
						float num2 = Vector3.Angle(forward, val2);
						if (!(num2 > num))
						{
							num = num2;
							val = item;
						}
					}
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				Say("nobody in your crosshair.");
				return;
			}
			KillPlayer(val);
			Say("smited " + val.SteamName + ".");
		}

		private static void Say(string message)
		{
			ChatManager.ChatMessage("[<color=#ff6666>Admin</color>] " + message);
			Plugin.Log.LogInfo((object)("[Admin] " + message));
		}
	}
	internal static class AimbotPatches
	{
		[HarmonyPatch(typeof(PlayerAimAssist), "CacheSettings")]
		internal static class CacheSettings_Patch
		{
			private static void Postfix(PlayerAimAssist __instance)
			{
				try
				{
					if (Plugin.AimbotActive)
					{
						Apply(__instance);
					}
				}
				catch (Exception ex)
				{
					Plugin.Log.LogWarning((object)("[Aimbot] CacheSettings: " + ex.Message));
				}
			}
		}

		[HarmonyPatch(typeof(PlayerAimAssist), "CanUseAimAssist")]
		internal static class CanUseAimAssist_Patch
		{
			private static void Postfix(PlayerAimAssist __instance, ref bool __result)
			{
				try
				{
					if (Plugin.AimbotActive)
					{
						Player value = Traverse.Create((object)__instance).Field("_player").GetValue<Player>();
						if (!((Object)(object)value == (Object)null) && !value.BlockInputs && !((Object)(object)value.Camera == (Object)null) && value.Camera.MouseLocked)
						{
							Apply(__instance);
							__result = true;
						}
					}
				}
				catch (Exception ex)
				{
					Plugin.Log.LogWarning((object)("[Aimbot] CanUseAimAssist: " + ex.Message));
				}
			}
		}

		private static void Apply(PlayerAimAssist aa)
		{
			float num = Mathf.Clamp(Plugin.AimbotFovDegrees.Value, 1f, 90f);
			float num2 = Mathf.Max(1f, Plugin.AimbotMaxDistance.Value);
			float num3 = Mathf.Min(num + 40f, 179f);
			float num4 = Mathf.Cos(num * (MathF.PI / 180f));
			Traverse obj = Traverse.Create((object)aa);
			obj.Field("_maxTargetDistance").SetValue((object)num2);
			obj.Field("_maxSqrTargetDistance").SetValue((object)(num2 * num2));
			obj.Field("_adsAcquireAngle").SetValue((object)num);
			obj.Field("_minAcquireAlignment").SetValue((object)num4);
			obj.Field("_acquireAlignmentRange").SetValue((object)Mathf.Max(1f - num4, Mathf.Epsilon));
			obj.Field("_trackingBreakAngle").SetValue((object)num3);
			obj.Field("_minTrackingAlignment").SetValue((object)Mathf.Cos(num3 * (MathF.PI / 180f)));
			obj.Field("_maxRotationSpeed").SetValue((object)Plugin.AimbotMaxRotationSpeed.Value);
			obj.Field("_trackingSharpness").SetValue((object)Plugin.AimbotSnapSharpness.Value);
		}
	}
	internal static class AmmoPatches
	{
		[HarmonyPatch(typeof(Weapon), "Shoot")]
		internal static class Weapon_Shoot_Patch
		{
			private static void Prefix(Weapon __instance)
			{
				if (Plugin.InfiniteAmmoActive)
				{
					Attachments attachments = __instance.Attachments;
					int num = (((Object)(object)attachments != (Object)null) ? attachments.AmmoPerMag : 999);
					Traverse.Create((object)__instance).Property("Ammo", (object[])null).SetValue((object)num);
				}
			}
		}
	}
	internal static class BossRushPatches
	{
		[HarmonyPatch(typeof(CreatureManager), "FindFishForBait")]
		internal static class FindFishForBait_Patch
		{
			private static void Prefix()
			{
				_inFindFishForBait = true;
			}

			private static void Finalizer()
			{
				_inFindFishForBait = false;
			}
		}

		[HarmonyPatch(typeof(CreatureManager), "GetRandomItem")]
		internal static class GetRandomItem_Patch
		{
			private static void Postfix(List<ItemInfoWeight> weights, ref Fishable __result)
			{
				if (Plugin.BossRushActive && _inFindFishForBait && !Object.op_Implicit((Object)(object)BossManager.Boss))
				{
					Fishable val = FindBossFishable(weights);
					if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.ItemToSpawn) && !((Object)(object)__result == (Object)(object)val))
					{
						__result = val;
						Plugin.Log.LogInfo((object)("[BossRush] forcing boss on the line: " + ((Object)val.ItemToSpawn).name));
					}
				}
			}
		}

		private static bool _inFindFishForBait;

		internal const string DefaultTargetName = "Mutated";

		private static Fishable _cachedBoss;

		private static float _lastScanTime = -999f;

		private const float RescanCooldown = 5f;

		private static Fishable _cachedNamed;

		private static string _cachedNamedFor;

		internal const string LocalTarget = "local";

		internal static string CurrentTargetLabel = "auto";

		private static Fishable FindBossFishable(List<ItemInfoWeight> weights)
		{
			string text = (Plugin.BossRushTargetName.Value ?? string.Empty).Trim();
			if (text.Length == 0)
			{
				text = "Mutated";
			}
			int num;
			if (!text.Equals("local", StringComparison.OrdinalIgnoreCase))
			{
				num = (text.Equals("auto", StringComparison.OrdinalIgnoreCase) ? 1 : 0);
				if (num == 0)
				{
					goto IL_0051;
				}
			}
			else
			{
				num = 1;
			}
			CurrentTargetLabel = "local";
			goto IL_0051;
			IL_0051:
			if (num == 0)
			{
				Fishable val = FindNamedBoss(text);
				if (Object.op_Implicit((Object)(object)val))
				{
					return val;
				}
			}
			Fishable val2 = PickBoss(weights);
			if (Object.op_Implicit((Object)(object)val2))
			{
				return val2;
			}
			if (Object.op_Implicit((Object)(object)_cachedBoss))
			{
				return _cachedBoss;
			}
			if (Time.time - _lastScanTime < 5f)
			{
				return null;
			}
			_lastScanTime = Time.time;
			_cachedBoss = ScanLoadedFishables();
			if (!Object.op_Implicit((Object)(object)_cachedBoss))
			{
				Plugin.Log.LogWarning((object)"[BossRush] no boss Fishable found among loaded assets yet.");
			}
			return _cachedBoss;
		}

		private static Fishable PickBoss(List<ItemInfoWeight> weights)
		{
			//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_0028: Invalid comparison between Unknown and I4
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Invalid comparison between Unknown and I4
			if (weights == null)
			{
				return null;
			}
			Fishable val = null;
			for (int i = 0; i < weights.Count; i++)
			{
				ItemInfoWeight obj = weights[i];
				Fishable val2 = ((obj != null) ? obj.Fishable : null);
				BossType bossType = GetBossType(val2);
				if ((int)bossType != 1)
				{
					if ((int)bossType == 2)
					{
						return val2;
					}
				}
				else if (!Object.op_Implicit((Object)(object)val))
				{
					val = val2;
				}
			}
			if (!Plugin.BossRushAllowMini.Value)
			{
				return null;
			}
			return val;
		}

		private static Fishable ScanLoadedFishables()
		{
			//IL_0011: 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_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Invalid comparison between Unknown and I4
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Invalid comparison between Unknown and I4
			Fishable val = null;
			Fishable[] array = Resources.FindObjectsOfTypeAll<Fishable>();
			foreach (Fishable val2 in array)
			{
				BossType bossType = GetBossType(val2);
				if ((int)bossType != 1)
				{
					if ((int)bossType == 2)
					{
						return val2;
					}
				}
				else if (!Object.op_Implicit((Object)(object)val))
				{
					val = val2;
				}
			}
			if (!Plugin.BossRushAllowMini.Value)
			{
				return null;
			}
			return val;
		}

		private static Fishable FindNamedBoss(string wanted)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Invalid comparison between Unknown and I4
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Invalid comparison between Unknown and I4
			if (Object.op_Implicit((Object)(object)_cachedNamed) && _cachedNamedFor == wanted)
			{
				return _cachedNamed;
			}
			Fishable val = null;
			BossType val2 = (BossType)0;
			Fishable[] array = Resources.FindObjectsOfTypeAll<Fishable>();
			foreach (Fishable val3 in array)
			{
				BossType bossType = GetBossType(val3);
				if ((int)bossType != 0 && ((Object)val3.ItemToSpawn).name.IndexOf(wanted, StringComparison.OrdinalIgnoreCase) >= 0 && (!Object.op_Implicit((Object)(object)val) || ((int)bossType == 2 && (int)val2 != 2)))
				{
					val = val3;
					val2 = bossType;
				}
			}
			if (Object.op_Implicit((Object)(object)val))
			{
				_cachedNamed = val;
				_cachedNamedFor = wanted;
				CurrentTargetLabel = ((Object)val.ItemToSpawn).name;
				Plugin.Log.LogInfo((object)$"[BossRush] target '{wanted}' resolved to {((Object)val.ItemToSpawn).name} ({val2}).");
				return val;
			}
			if (_cachedNamedFor != wanted)
			{
				_cachedNamedFor = wanted;
				Plugin.Log.LogWarning((object)("[BossRush] no boss matching '" + wanted + "' is loaded — falling back to this bait's boss. Check the [BossCatalog] dump for the exact names."));
			}
			return null;
		}

		internal static void CycleBoss(int delta)
		{
			List<string> list = LoadedBossNames();
			list.Insert(0, "local");
			string text = (Plugin.BossRushTargetName.Value ?? string.Empty).Trim();
			if (text.Length == 0)
			{
				text = "Mutated";
			}
			int num = -1;
			for (int i = 0; i < list.Count; i++)
			{
				if (list[i].IndexOf(text, StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf(list[i], StringComparison.OrdinalIgnoreCase) >= 0)
				{
					num = i;
					break;
				}
			}
			num += delta;
			if (num < 0)
			{
				num = list.Count - 1;
			}
			if (num >= list.Count)
			{
				num = 0;
			}
			string text2 = list[num];
			Plugin.BossRushTargetName.Value = text2;
			_cachedNamed = null;
			_cachedNamedFor = null;
			CurrentTargetLabel = text2;
			Plugin.Log.LogInfo((object)$"[BossRush] target {num + 1}/{list.Count}: {text2}");
		}

		private static List<string> LoadedBossNames()
		{
			//IL_001d: 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_0024: 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_0039: Invalid comparison between Unknown and I4
			List<string> list = new List<string>();
			List<string> list2 = new List<string>();
			Fishable[] array = Resources.FindObjectsOfTypeAll<Fishable>();
			foreach (Fishable val in array)
			{
				BossType bossType = GetBossType(val);
				if ((int)bossType != 0)
				{
					string name = ((Object)val.ItemToSpawn).name;
					List<string> list3 = (((int)bossType == 2) ? list2 : list);
					if (!list3.Contains(name))
					{
						list3.Add(name);
					}
				}
			}
			list.Sort();
			list2.Sort();
			list.AddRange(list2);
			return list;
		}

		internal static void DumpBossCatalog()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: 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)
			List<string> list = new List<string>();
			Fishable[] array = Resources.FindObjectsOfTypeAll<Fishable>();
			foreach (Fishable val in array)
			{
				BossType bossType = GetBossType(val);
				if ((int)bossType != 0)
				{
					string item = $"{bossType,-5} {((Object)val.ItemToSpawn).name}";
					if (!list.Contains(item))
					{
						list.Add(item);
					}
				}
			}
			list.Sort();
			Plugin.Log.LogInfo((object)$"[BossCatalog] {list.Count} boss creature(s) loaded:");
			foreach (string item2 in list)
			{
				Plugin.Log.LogInfo((object)("[BossCatalog]   " + item2));
			}
			if (list.Count == 0)
			{
				Plugin.Log.LogInfo((object)"[BossCatalog]   (none loaded yet — bosses load with their island)");
			}
		}

		private static BossType GetBossType(Fishable fishable)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)fishable) || !Object.op_Implicit((Object)(object)fishable.ItemToSpawn))
			{
				return (BossType)0;
			}
			Item itemToSpawn = fishable.ItemToSpawn;
			Creature val = (Creature)(object)((itemToSpawn is Creature) ? itemToSpawn : null);
			if (!Object.op_Implicit((Object)(object)val))
			{
				return (BossType)0;
			}
			return val.BossType;
		}
	}
	internal static class CasinoPatches
	{
		[HarmonyPatch(typeof(SlotMachineManager), "RollRandom")]
		internal static class RollRandom_Patch
		{
			private static void Prefix()
			{
				//IL_003c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0041: Unknown result type (might be due to invalid IL or missing references)
				//IL_0042: 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_0058: Unknown result type (might be due to invalid IL or missing references)
				string text = (Plugin.CasinoRarity.Value ?? string.Empty).Trim();
				if (text.Length == 0 || text.Equals("off", StringComparison.OrdinalIgnoreCase))
				{
					SlotMachineManager.SetCheatSkin((Item)null, byte.MaxValue);
					return;
				}
				Rarity val = ResolveRarity(text);
				if (!PickSkin(val, out var item, out var skinIndex))
				{
					Plugin.Log.LogWarning((object)$"[Casino] no {val} skin available to force this roll.");
					return;
				}
				SlotMachineManager.SetCheatSkin(item, skinIndex);
				Plugin.Log.LogInfo((object)string.Format("[Casino] forcing {0} ({1} skin {2}).", val, Object.op_Implicit((Object)(object)item) ? ((Object)item).name : "boat", skinIndex));
			}
		}

		internal const string ModeOff = "off";

		internal const string ModeGreen = "green";

		private static Rarity ResolveRarity(string mode)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			if (mode.Equals("legendary", StringComparison.OrdinalIgnoreCase))
			{
				return (Rarity)3;
			}
			if (mode.Equals("rare", StringComparison.OrdinalIgnoreCase))
			{
				return (Rarity)2;
			}
			if (mode.Equals("common", StringComparison.OrdinalIgnoreCase))
			{
				return (Rarity)1;
			}
			return GreenestRarity();
		}

		private static Rarity GreenestRarity()
		{
			//IL_0003: 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_0022: 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_003c: Unknown result type (might be due to invalid IL or missing references)
			Rarity best = (Rarity)2;
			float bestScore = float.NegativeInfinity;
			Consider((Rarity)1, GameInfo.CommonColor);
			Consider((Rarity)2, GameInfo.RareColor);
			Consider((Rarity)3, GameInfo.LegendaryColor);
			return best;
			void Consider(Rarity r, Color c)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: 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 num = c.g - Mathf.Max(c.r, c.b);
				if (num > bestScore)
				{
					bestScore = num;
					best = r;
				}
			}
		}

		private static bool PickSkin(Rarity target, out Item item, out byte skinIndex)
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			item = null;
			skinIndex = byte.MaxValue;
			List<Item> list = new List<Item>();
			if (SlotMachine.AvailableItems != null)
			{
				list.AddRange(SlotMachine.AvailableItems);
			}
			if (!SlotMachine.ExcludeBoat)
			{
				list.Add(null);
			}
			foreach (Item item2 in list)
			{
				SkinPreset val = (Object.op_Implicit((Object)(object)item2) ? item2.SkinPreset : (Object.op_Implicit((Object)(object)BoatManager.Boat) ? BoatManager.Boat.SkinPreset : null));
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				for (int i = 0; i < val.Skins.Count; i++)
				{
					ItemSkin val2 = val.Skins[i];
					if (((ItemSkin)(ref val2)).Rarity == target)
					{
						item = item2;
						skinIndex = (byte)i;
						return true;
					}
				}
			}
			return false;
		}

		internal static void Cycle()
		{
			string text = (Plugin.CasinoRarity.Value ?? string.Empty).Trim().ToLowerInvariant();
			string text2 = ((!(text == "off") && (text == null || text.Length != 0)) ? ((text == "green") ? "rare" : ((!(text == "rare")) ? "off" : "legendary")) : "green");
			Plugin.CasinoRarity.Value = text2;
			if (text2 == "off")
			{
				SlotMachineManager.SetCheatSkin((Item)null, byte.MaxValue);
			}
			Plugin.Log.LogInfo((object)("[Casino] rigged outcome: " + text2));
		}

		internal static string Label()
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			string text = (Plugin.CasinoRarity.Value ?? string.Empty).Trim();
			if (text.Length == 0)
			{
				return "off";
			}
			if (text.Equals("green", StringComparison.OrdinalIgnoreCase))
			{
				return $"green ({GreenestRarity()})";
			}
			return text.ToLowerInvariant();
		}
	}
	internal static class ClientPowerPatches
	{
		private static float _nextRevive;

		internal static void Tick()
		{
			if (!Plugin.AutoReviveActive || Time.time < _nextRevive)
			{
				return;
			}
			Player localPlayer = Player.LocalPlayer;
			if (!((Object)(object)localPlayer == (Object)null) && !((Object)(object)localPlayer.Vitals == (Object)null) && !((Object)(object)localPlayer.Dying == (Object)null) && localPlayer.Vitals.Health <= 0)
			{
				DeadPlayer deadPlayer = localPlayer.Dying.DeadPlayer;
				if (!((Object)(object)deadPlayer == (Object)null) && !((Object)(object)Server.Instance == (Object)null))
				{
					_nextRevive = Time.time + Mathf.Max(0.1f, Plugin.AutoReviveInterval.Value);
					Server.Instance.ResurrectPlayer(localPlayer, deadPlayer);
					Plugin.Log.LogInfo((object)"[Immortal] resurrected.");
				}
			}
		}

		internal static string Give(string query)
		{
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: 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_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			query = (query ?? string.Empty).Trim();
			if (query.Length == 0)
			{
				return "usage: /give <item name>   (/give list <text> to search)";
			}
			if (query.StartsWith("list", StringComparison.OrdinalIgnoreCase))
			{
				return Search((query.Length > 4) ? query.Substring(4).Trim() : "");
			}
			Player localPlayer = Player.LocalPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return "no local player.";
			}
			if ((Object)(object)Server.Instance == (Object)null)
			{
				return "not connected.";
			}
			if ((Object)(object)localPlayer.Holding != (Object)null && Object.op_Implicit((Object)(object)localPlayer.Holding.UninitializedHeldItem))
			{
				return "hands are busy - try again in a second.";
			}
			Item val = Resolve(query);
			if ((Object)(object)val == (Object)null)
			{
				return "no item called '" + query + "'. Try /give list " + query;
			}
			Item val2 = (((Object)(object)localPlayer.Holding != (Object)null) ? localPlayer.Holding.HeldItem : null);
			Vector3 val3 = localPlayer.Transform.position + localPlayer.Transform.forward * 1.5f + Vector3.up;
			Server.Instance.BuyItem(val.ID, localPlayer, val2, val3, Quaternion.identity, true);
			Plugin.Log.LogInfo((object)$"[Give] requested {((Object)val).name} (id {val.ID}) free.");
			return "spawned " + ((Object)val).name + ".";
		}

		private static string Key(string s)
		{
			if (!string.IsNullOrEmpty(s))
			{
				return s.Replace(" ", "").ToLowerInvariant();
			}
			return "";
		}

		private static Item Resolve(string query)
		{
			query = Key(query);
			Item spawnable = GameInfo.GetSpawnable(query);
			if ((Object)(object)spawnable != (Object)null)
			{
				return spawnable;
			}
			ICollection<string> collection = SpawnableNames();
			if (collection == null)
			{
				return null;
			}
			Item val = null;
			int num = 0;
			foreach (string item in collection)
			{
				if (item.IndexOf(query, StringComparison.OrdinalIgnoreCase) >= 0)
				{
					num++;
					if ((Object)(object)val == (Object)null)
					{
						val = GameInfo.GetSpawnable(item);
					}
				}
			}
			if (num != 1)
			{
				return null;
			}
			return val;
		}

		private static string Search(string term)
		{
			ICollection<string> collection = SpawnableNames();
			if (collection == null)
			{
				return "could not read the item list.";
			}
			term = Key(term);
			List<string> list = new List<string>();
			foreach (string item in collection)
			{
				if (term.Length <= 0 || item.IndexOf(term, StringComparison.OrdinalIgnoreCase) >= 0)
				{
					list.Add(item);
					if (list.Count >= 25)
					{
						break;
					}
				}
			}
			if (list.Count == 0)
			{
				return "nothing matching '" + term + "'.";
			}
			return $"{list.Count}: " + string.Join(", ", list.ToArray());
		}

		internal static string Worth(string arg)
		{
			Player localPlayer = Player.LocalPlayer;
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)Server.Instance == (Object)null)
			{
				return "not connected.";
			}
			Item val = (((Object)(object)localPlayer.Holding != (Object)null) ? localPlayer.Holding.HeldItem : null);
			if ((Object)(object)val == (Object)null)
			{
				return "hold the fish you want to inflate first.";
			}
			float num = Plugin.WorthMultiplier.Value;
			if (!string.IsNullOrEmpty(arg) && float.TryParse(arg.Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
			{
				num = result;
			}
			num = Mathf.Clamp(num, 1f, 100000f);
			Server.Instance.SetItemMultiplier(val, num);
			Plugin.Log.LogInfo((object)$"[Worth] set {((Object)val).name} multiplier to {num}");
			return $"{((Object)val).name} worth x{num:0} - sell it now. (Only works once per item.)";
		}

		private static ICollection<string> SpawnableNames()
		{
			return Traverse.Create(typeof(GameInfo)).Field("_nameToSpawnable").GetValue<Dictionary<string, Item>>()?.Keys;
		}
	}
	internal static class DripperPatches
	{
		[HarmonyPatch(typeof(SlotMachine), "OnTriggerStay")]
		internal static class OnTriggerStay_Patch
		{
			private static bool Prefix(Collider other)
			{
				if (!Plugin.DripperClamsActive)
				{
					return true;
				}
				if (!Object.op_Implicit((Object)(object)Server.Instance) || !((NetworkBehaviour)Server.Instance).IsServerInitialized)
				{
					return false;
				}
				if (SlotMachine.IsRolling)
				{
					return false;
				}
				Item val = ItemManager.Get(other);
				if (!Object.op_Implicit((Object)(object)val) || Object.op_Implicit((Object)(object)val.Holder))
				{
					return false;
				}
				if (!Accepts(val))
				{
					return false;
				}
				Player val2 = (Object.op_Implicit((Object)(object)val.Holder) ? val.Holder : val.LastHolder);
				if (!Object.op_Implicit((Object)(object)val2))
				{
					return false;
				}
				val.DestroyItem((byte)4, byte.MaxValue);
				SlotMachineManager.RollRandom(val2);
				return false;
			}
		}

		private static bool Accepts(Item item)
		{
			if (Object.op_Implicit((Object)(object)item.Creature) && !item.Creature.IsDead)
			{
				return false;
			}
			if (Plugin.DripperAcceptAnything.Value)
			{
				return true;
			}
			if ((!Object.op_Implicit((Object)(object)item.Creature) || (item.Creature.IsDead && item.Creature.IsDrip)) && (Object.op_Implicit((Object)(object)item.Creature) || item.IsQuestItem))
			{
				return true;
			}
			return ((Object)item).name.IndexOf("clam", StringComparison.OrdinalIgnoreCase) >= 0;
		}
	}
	internal static class FantasticPatches
	{
		[HarmonyPatch(typeof(PlayerPunching), "FindPunchTarget")]
		internal static class FindPunchTarget_Patch
		{
			private static void Prefix(PlayerPunching __instance)
			{
				//IL_0047: Unknown result type (might be due to invalid IL or missing references)
				//IL_004c: Unknown result type (might be due to invalid IL or missing references)
				//IL_008e: 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)
				Traverse obj = Traverse.Create((object)__instance);
				Traverse val = obj.Field("_range");
				Traverse val2 = obj.Field("_hitRadius");
				Traverse val3 = obj.Field("_noTargetHitPos");
				if (!_captured)
				{
					_baseRange = val.GetValue<float>();
					_baseHitRadius = val2.GetValue<float>();
					_baseNoTargetPos = val3.GetValue<Vector3>();
					_captured = true;
				}
				float num = (Plugin.MrFantasticActive ? Mathf.Max(1f, Plugin.MrFantasticReach.Value) : 1f);
				val.SetValue((object)(_baseRange * num));
				val3.SetValue((object)(_baseNoTargetPos * num));
				val2.SetValue((object)(_baseHitRadius * (Plugin.MrFantasticActive ? Mathf.Min(num, 4f) : 1f)));
			}
		}

		private static bool _captured;

		private static float _baseRange;

		private static float _baseHitRadius;

		private static Vector3 _baseNoTargetPos;
	}
	internal static class FishermanAimbotPatches
	{
		[HarmonyPatch(typeof(PlayerCamera), "ApplyAimAssist")]
		internal static class ApplyAimAssist_Patch
		{
			private static void Postfix(PlayerCamera __instance)
			{
				try
				{
					Run(__instance);
				}
				catch (Exception ex)
				{
					Plugin.Log.LogWarning((object)("[FishermanAimbot] " + ex.Message));
				}
			}

			private static void Run(PlayerCamera __instance)
			{
				//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c3: 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_00cd: 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_00f9: 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_01ce: Unknown result type (might be due to invalid IL or missing references)
				//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
				//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
				//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
				//IL_01db: Unknown result type (might be due to invalid IL or missing references)
				//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
				//IL_01e4: 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)
				//IL_021c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0223: Unknown result type (might be due to invalid IL or missing references)
				//IL_023d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0244: Unknown result type (might be due to invalid IL or missing references)
				//IL_0257: Unknown result type (might be due to invalid IL or missing references)
				//IL_0273: 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_0146: 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_015b: 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_015e: 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_0177: Unknown result type (might be due to invalid IL or missing references)
				//IL_0179: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
				if (!Plugin.FishermanAimbotActive)
				{
					return;
				}
				Player localPlayer = Player.LocalPlayer;
				if ((Object)(object)localPlayer == (Object)null || localPlayer.BlockInputs || (Object)(object)Traverse.Create((object)__instance).Field("_player").GetValue<Player>() != (Object)(object)localPlayer || (Object)(object)localPlayer.Camera == (Object)null || !localPlayer.Camera.MouseLocked)
				{
					return;
				}
				Item val = (((Object)(object)localPlayer.Holding != (Object)null) ? localPlayer.Holding.HeldItem : null);
				if ((Object)(object)val == (Object)null || (Object)(object)val.Weapon == (Object)null || !val.Weapon.IsAds)
				{
					return;
				}
				Vector3 position = __instance.CamTransform.position;
				Traverse val2 = Traverse.Create((object)__instance).Field("_rot");
				Vector3 value = val2.GetValue<Vector3>();
				Vector3 val3 = Quaternion.Euler(value) * Vector3.forward;
				float num = Mathf.Clamp(Plugin.FishermanFov.Value, 1f, 180f);
				Player val4 = null;
				float num2 = float.MaxValue;
				Vector3 val5 = Vector3.zero;
				foreach (Player alivePlayer in PlayerManager.AlivePlayers)
				{
					if ((Object)(object)alivePlayer == (Object)null || (Object)(object)alivePlayer == (Object)(object)localPlayer)
					{
						continue;
					}
					Vector3 val6 = (Object.op_Implicit((Object)(object)alivePlayer.Rigidbody) ? alivePlayer.Rigidbody.worldCenterOfMass : alivePlayer.Transform.position);
					Vector3 val7 = val6 - position;
					float magnitude = ((Vector3)(ref val7)).magnitude;
					if (magnitude < 0.01f)
					{
						continue;
					}
					float num3 = Vector3.Angle(val3, val7);
					if (!(num3 > num))
					{
						float num4 = num3 + magnitude * 0.01f;
						if (num4 < num2)
						{
							num2 = num4;
							val4 = alivePlayer;
							val5 = val6;
						}
					}
				}
				if (!((Object)(object)val4 == (Object)null))
				{
					Quaternion val8 = Quaternion.LookRotation(val5 - position, Vector3.up);
					Vector3 eulerAngles = ((Quaternion)(ref val8)).eulerAngles;
					float num5 = 1f - Mathf.Exp((0f - Mathf.Max(0.01f, Plugin.FishermanSharpness.Value)) * Time.deltaTime);
					value.x += Mathf.DeltaAngle(value.x, eulerAngles.x) * num5;
					value.y += Mathf.DeltaAngle(value.y, eulerAngles.y) * num5;
					value.x = Mathf.Clamp(value.x, -90f, 90f);
					val2.SetValue((object)value);
				}
			}
		}
	}
	internal static class FlyPatches
	{
		[HarmonyPatch(typeof(PlayerMovement), "Move")]
		internal static class Move_Patch
		{
			private static void Postfix(PlayerMovement __instance)
			{
				//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_008d: 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_0094: Unknown result type (might be due to invalid IL or missing references)
				//IL_0099: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a4: 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_00a7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ac: 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_00b9: 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)
				//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00de: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f9: 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_0115: Unknown result type (might be due to invalid IL or missing references)
				//IL_0117: 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_0121: 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_0174: 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)
				if (!Plugin.FlyActive || !Plugin.FlyAllowed || !Object.op_Implicit((Object)(object)__instance))
				{
					return;
				}
				Player localPlayer = Player.LocalPlayer;
				if ((Object)(object)localPlayer == (Object)null || (Object)(object)localPlayer.Movement != (Object)(object)__instance || localPlayer.BlockInputs || __instance.OnBoat)
				{
					return;
				}
				Rigidbody val = RigOf(__instance);
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				if (!_loggedOnce)
				{
					_loggedOnce = true;
					Plugin.Log.LogInfo((object)"[Fly] active - driving PlayerMovement._rig directly.");
				}
				Transform camObject = localPlayer.CamObject;
				if (!((Object)(object)camObject == (Object)null))
				{
					Vector3 forward = camObject.forward;
					Vector3 right = camObject.right;
					Vector3 val2 = Vector3.zero;
					if (Input.GetKey((KeyCode)119))
					{
						val2 += forward;
					}
					if (Input.GetKey((KeyCode)115))
					{
						val2 -= forward;
					}
					if (Input.GetKey((KeyCode)100))
					{
						val2 += right;
					}
					if (Input.GetKey((KeyCode)97))
					{
						val2 -= right;
					}
					if (Input.GetKey((KeyCode)32))
					{
						val2 += Vector3.up;
					}
					if (Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)99))
					{
						val2 += Vector3.down;
					}
					float num = Mathf.Clamp(Plugin.FlySpeed.Value, 1f, 200f);
					if (Input.GetKey((KeyCode)304))
					{
						num *= Mathf.Max(1f, Plugin.FlyBoost.Value);
					}
					val.linearVelocity = ((((Vector3)(ref val2)).sqrMagnitude < 0.01f) ? Vector3.zero : (((Vector3)(ref val2)).normalized * num));
					val.useGravity = false;
				}
			}
		}

		private static bool _loggedOnce;

		private static PlayerMovement _cachedFor;

		private static Rigidbody _cachedRig;

		private static Rigidbody RigOf(PlayerMovement movement)
		{
			if ((Object)(object)_cachedFor == (Object)(object)movement && (Object)(object)_cachedRig != (Object)null)
			{
				return _cachedRig;
			}
			_cachedRig = Traverse.Create((object)movement).Field("_rig").GetValue<Rigidbody>();
			_cachedFor = movement;
			return _cachedRig;
		}

		internal static void OnDisabled()
		{
			_loggedOnce = false;
			Player localPlayer = Player.LocalPlayer;
			if (!((Object)(object)localPlayer == (Object)null) && !((Object)(object)localPlayer.Movement == (Object)null))
			{
				Rigidbody val = RigOf(localPlayer.Movement);
				if ((Object)(object)val != (Object)null)
				{
					val.useGravity = true;
				}
			}
		}
	}
	internal static class FlySharePatches
	{
		[HarmonyPatch(typeof(ChatManager), "ChatMessage", new Type[] { typeof(string) })]
		internal static class ChatMessage_Patch
		{
			private static void Postfix(string message)
			{
				if (_sending || string.IsNullOrEmpty(message) || message.IndexOf("[Fly]", StringComparison.Ordinal) < 0)
				{
					return;
				}
				int startIndex = message.IndexOf("[Fly]", StringComparison.Ordinal) + "[Fly]".Length;
				string text = message.Substring(startIndex).Trim();
				bool flag;
				if (text.StartsWith("on for", StringComparison.OrdinalIgnoreCase))
				{
					flag = true;
				}
				else
				{
					if (!text.StartsWith("off for", StringComparison.OrdinalIgnoreCase))
					{
						return;
					}
					flag = false;
				}
				string s = text.Substring(text.IndexOf("for", StringComparison.OrdinalIgnoreCase) + 3).Trim();
				s = StripTags(s);
				Player localPlayer = Player.LocalPlayer;
				if (!((Object)(object)localPlayer == (Object)null) && !string.IsNullOrEmpty(localPlayer.SteamName) && (s.Equals("everyone", StringComparison.OrdinalIgnoreCase) || s.Equals(localPlayer.SteamName, StringComparison.OrdinalIgnoreCase)))
				{
					Plugin.FlyAllowed = flag;
					Plugin.Log.LogInfo((object)("[FlyShare] host set my fly permission to " + (flag ? "ALLOWED" : "DENIED")));
					if (!flag && Plugin.FlyActive)
					{
						Plugin.FlyActive = false;
						FlyPatches.OnDisabled();
					}
				}
			}
		}

		private const string Marker = "[Fly]";

		private const string Everyone = "everyone";

		private static readonly List<string> _granted = new List<string>();

		private static bool _everyoneAllowed;

		private static bool _sending;

		private static string StripTags(string s)
		{
			StringBuilder stringBuilder = new StringBuilder(s.Length);
			bool flag = false;
			foreach (char c in s)
			{
				switch (c)
				{
				case '<':
					flag = true;
					continue;
				case '>':
					flag = false;
					continue;
				}
				if (!flag)
				{
					stringBuilder.Append(c);
				}
			}
			return stringBuilder.ToString().Trim();
		}

		internal static string Handle(string arg)
		{
			if ((Object)(object)Server.Instance == (Object)null || !((NetworkBehaviour)Server.Instance).IsServerInitialized)
			{
				return "only the host decides who can fly.";
			}
			arg = (arg ?? string.Empty).Trim();
			if (arg.Length == 0)
			{
				return Status();
			}
			if (arg.Equals("all", StringComparison.OrdinalIgnoreCase))
			{
				_everyoneAllowed = true;
				_granted.Clear();
				Announce(on: true, "everyone");
				return "fly is on for everyone.";
			}
			if (arg.Equals("none", StringComparison.OrdinalIgnoreCase) || arg.Equals("off", StringComparison.OrdinalIgnoreCase))
			{
				_everyoneAllowed = false;
				_granted.Clear();
				Announce(on: false, "everyone");
				return "fly is off for everyone but you.";
			}
			Player val = FindByName(arg);
			if ((Object)(object)val == (Object)null)
			{
				return "no player matching '" + arg + "'. Try /players.";
			}
			string name = val.SteamName;
			bool flag = !IsGranted(name);
			if (flag)
			{
				_granted.Add(name);
			}
			else
			{
				_granted.RemoveAll((string n) => n.Equals(name, StringComparison.OrdinalIgnoreCase));
			}
			Announce(flag, name);
			return "fly " + (flag ? "ON" : "OFF") + " for " + name + ".";
		}

		private static string Status()
		{
			if (_everyoneAllowed)
			{
				return "fly is on for everyone. (/fly none to lock it)";
			}
			if (_granted.Count == 0)
			{
				return "nobody has been given fly yet. (/fly <name> or /fly all)";
			}
			return "fly is on for: " + string.Join(", ", _granted.ToArray());
		}

		private static void Announce(bool on, string who)
		{
			Player localPlayer = Player.LocalPlayer;
			ulong num = (((Object)(object)localPlayer != (Object)null) ? localPlayer.SteamID : 0);
			_sending = true;
			try
			{
				Server.Instance.SendChatMessage(num, "[Fly] " + (on ? "on" : "off") + " for " + who);
			}
			finally
			{
				_sending = false;
			}
			if (who.Equals("everyone", StringComparison.OrdinalIgnoreCase) && (Object)(object)localPlayer != (Object)null)
			{
				Plugin.FlyAllowed = true;
			}
		}

		private static bool IsGranted(string name)
		{
			foreach (string item in _granted)
			{
				if (item.Equals(name, StringComparison.OrdinalIgnoreCase))
				{
					return true;
				}
			}
			return false;
		}

		private static Player FindByName(string name)
		{
			List<Player> players = PlayerManager.Players;
			if (players == null)
			{
				return null;
			}
			Player val = null;
			int num = 0;
			foreach (Player item in players)
			{
				if (Object.op_Implicit((Object)(object)item) && !string.IsNullOrEmpty(item.SteamName) && !((Object)(object)item == (Object)(object)Player.LocalPlayer) && item.SteamName.IndexOf(name, StringComparison.OrdinalIgnoreCase) >= 0)
				{
					num++;
					if ((Object)(object)val == (Object)null)
					{
						val = item;
					}
				}
			}
			if (num != 1)
			{
				return null;
			}
			return val;
		}
	}
	internal static class IslandPatches
	{
		[HarmonyPatch(typeof(RadarUI), "Update")]
		internal static class RadarUI_Update_Patch
		{
			private static void Prefix(RadarUI __instance)
			{
				try
				{
					if (Plugin.RevealIslandsActive)
					{
						Traverse obj = Traverse.Create((object)__instance);
						obj.Field("_isOn").SetValue((object)true);
						CanvasGroup value = obj.Field("_canvasGroup").GetValue<CanvasGroup>();
						if ((Object)(object)value != (Object)null)
						{
							value.alpha = 1f;
						}
					}
				}
				catch (Exception ex)
				{
					Plugin.Log.LogWarning((object)("[Islands] RadarUI.Update: " + ex.Message));
				}
			}
		}

		[HarmonyPatch(typeof(RadarUI), "UpdateIslandDots")]
		internal static class UpdateIslandDots_Patch
		{
			private static void Prefix()
			{
				_inUpdateIslandDots = true;
			}

			private static void Finalizer()
			{
				_inUpdateIslandDots = false;
			}
		}

		[HarmonyPatch(typeof(IslandSpawner), "OnTriggerEnter")]
		internal static class IslandSpawner_OnTriggerEnter_Patch
		{
			private static void Prefix()
			{
				_inTravelTrigger = true;
			}

			private static void Finalizer()
			{
				_inTravelTrigger = false;
			}
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		internal static class MaxIslandUnlocked_Patch
		{
			private static void Postfix(ref byte __result)
			{
				if (Plugin.RevealIslandsActive && (_inUpdateIslandDots || (_inTravelTrigger && Plugin.UnlockIslandTravel.Value)))
				{
					int num = Mathf.Clamp(IslandManager.TotalIslands, 0, 255);
					if (num > __result)
					{
						__result = (byte)num;
					}
				}
			}
		}

		private static bool _inUpdateIslandDots;

		private static bool _inTravelTrigger;

		internal static void TeleportIsland(int delta)
		{
			if ((Object)(object)OnlineIslandManager.Instance == (Object)null)
			{
				Plugin.Log.LogWarning((object)"[Islands] no OnlineIslandManager yet.");
				return;
			}
			if ((Object)(object)Server.Instance == (Object)null || !((NetworkBehaviour)Server.Instance).IsServerInitialized)
			{
				Plugin.Log.LogWarning((object)"[Islands] island travel is server-side - host or play solo.");
				return;
			}
			int num = Mathf.Max(1, IslandManager.TotalIslands);
			int num2 = OnlineIslandManager.CurIsland + delta;
			if (num2 < 0)
			{
				num2 = num - 1;
			}
			if (num2 >= num)
			{
				num2 = 0;
			}
			OnlineIslandManager.TpToSpecificIsland((byte)num2);
			Plugin.Log.LogInfo((object)($"[Islands] travelling to island index {num2} of 0-{num - 1}" + ((num2 == num - 1) ? "  (the hidden DevIsland)" : "")));
		}
	}
	internal static class JoinFixPatches
	{
		[HarmonyPatch(typeof(Player), "InitializePlayer")]
		internal static class Player_InitializePlayer_Patch
		{
			private static bool Prefix(Player __instance)
			{
				if (_reentering)
				{
					return true;
				}
				NetworkConnection owner;
				try
				{
					owner = ((NetworkBehaviour)__instance).Owner;
				}
				catch (Exception ex)
				{
					Plugin.Log.LogWarning((object)("[JoinFix] could not read Owner: " + ex.Message));
					return true;
				}
				if (owner != (NetworkConnection)null && Client.Clients.ContainsKey(owner))
				{
					return true;
				}
				if (!_pending.Add(__instance))
				{
					return false;
				}
				Plugin.Log.LogWarning((object)("[JoinFix] Client object for connection " + ((owner == (NetworkConnection)null) ? "<null>" : owner.ClientId.ToString()) + " hasn't spawned yet — deferring InitializePlayer instead of letting it crash the spawn batch."));
				Plugin instance = Plugin.Instance;
				if ((Object)(object)instance == (Object)null)
				{
					_pending.Remove(__instance);
					return true;
				}
				((MonoBehaviour)instance).StartCoroutine(WaitForClientThenInitialize(__instance, owner));
				return false;
			}
		}

		private static bool _reentering;

		private static readonly HashSet<Player> _pending = new HashSet<Player>();

		private static readonly MethodInfo InitializePlayerMethod = AccessTools.Method(typeof(Player), "InitializePlayer", (Type[])null, (Type[])null);

		private const float WaitTimeoutSeconds = 15f;

		private static IEnumerator WaitForClientThenInitialize(Player player, NetworkConnection owner)
		{
			float deadline = Time.realtimeSinceStartup + 15f;
			while (Time.realtimeSinceStartup < deadline)
			{
				if ((Object)(object)player == (Object)null)
				{
					_pending.Remove(player);
					yield break;
				}
				if (owner != (NetworkConnection)null && Client.Clients.ContainsKey(owner))
				{
					_pending.Remove(player);
					RunOriginal(player, owner);
					yield break;
				}
				yield return null;
			}
			_pending.Remove(player);
			Plugin.Log.LogError((object)($"[JoinFix] gave up after {15f:0}s waiting for the Client of connection " + ((owner == (NetworkConnection)null) ? "<null>" : owner.ClientId.ToString()) + ". That player will stay uninitialized, but the rest of the world still loaded."));
		}

		private static void RunOriginal(Player player, NetworkConnection owner)
		{
			if (InitializePlayerMethod == null)
			{
				Plugin.Log.LogError((object)"[JoinFix] Player.InitializePlayer not found — cannot finish deferred init.");
				return;
			}
			try
			{
				_reentering = true;
				InitializePlayerMethod.Invoke(player, null);
				Plugin.Log.LogInfo((object)$"[JoinFix] deferred InitializePlayer completed for connection {owner.ClientId}.");
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)$"[JoinFix] deferred InitializePlayer failed: {ex.InnerException ?? ex}");
			}
			finally
			{
				_reentering = false;
			}
		}
	}
	internal static class LaserGunPatches
	{
		[HarmonyPatch(typeof(Weapon), "HasCooldown")]
		internal static class HasCooldown_Patch
		{
			private static void Postfix(Weapon __instance, ref bool __result)
			{
				if (Plugin.LaserGunActive && Object.op_Implicit((Object)(object)__instance) && IsLocal(__instance))
				{
					__result = false;
				}
			}
		}

		[HarmonyPatch(typeof(Weapon), "Update")]
		internal static class Update_Patch
		{
			private static void Prefix(Weapon __instance)
			{
				if (Plugin.LaserGunActive && Object.op_Implicit((Object)(object)__instance) && IsLocal(__instance))
				{
					Traverse.Create((object)__instance).Field("_fullAuto").SetValue((object)true);
				}
			}
		}

		[HarmonyPatch(typeof(Weapon), "Shoot")]
		internal static class Shoot_Patch
		{
			private static void Prefix(Weapon __instance)
			{
				_inLocalShot = Plugin.LaserGunActive && Object.op_Implicit((Object)(object)__instance) && IsLocal(__instance);
			}

			private static void Finalizer()
			{
				_inLocalShot = false;
			}
		}

		[HarmonyPatch(typeof(Weapon), "AddModelRecoil")]
		internal static class AddModelRecoil_Patch
		{
			private static bool Prefix()
			{
				return !Suppress;
			}
		}

		[HarmonyPatch(typeof(PlayerToolMovement), "Recoil")]
		internal static class ToolRecoil_Patch
		{
			private static bool Prefix()
			{
				return !Suppress;
			}
		}

		[HarmonyPatch(typeof(PlayerCamera), "Recoil")]
		internal static class CameraRecoil_Patch
		{
			private static bool Prefix()
			{
				return !Suppress;
			}
		}

		[HarmonyPatch(typeof(PlayerMovement), "Knockback")]
		internal static class Knockback_Patch
		{
			private static bool Prefix()
			{
				return !Suppress;
			}
		}

		private static bool _inLocalShot;

		private static bool Suppress
		{
			get
			{
				if (_inLocalShot)
				{
					return Plugin.LaserGunNoRecoil.Value;
				}
				return false;
			}
		}

		private static bool IsLocal(Weapon weapon)
		{
			Player value = Traverse.Create((object)weapon).Field("_holder").GetValue<Player>();
			if ((Object)(object)value != (Object)null)
			{
				return (Object)(object)value == (Object)(object)Player.LocalPlayer;
			}
			return false;
		}
	}
	internal static class LuckPatches
	{
		[HarmonyPatch(typeof(CreatureManager), "GetRandomItem")]
		internal static class GetRandomItem_Patch
		{
			private static bool Prefix(CreatureManager __instance, List<ItemInfoWeight> weights, ref Fishable __result)
			{
				float value = Plugin.LuckMultiplier.Value;
				if (value <= 1f || weights == null || weights.Count == 0)
				{
					return true;
				}
				try
				{
					double y = 1.0 / (double)value;
					double num = 0.0;
					double[] array = new double[weights.Count];
					for (int i = 0; i < weights.Count; i++)
					{
						num += (array[i] = Math.Pow(Math.Max(weights[i].Weight, 0f), y));
					}
					if (num <= 0.0)
					{
						return true;
					}
					double num2 = (double)Random.value * num;
					double num3 = 0.0;
					Fishable val = null;
					for (int j = 0; j < weights.Count; j++)
					{
						num3 += array[j];
						if (num2 <= num3)
						{
							val = weights[j].Fishable;
							break;
						}
					}
					if ((Object)(object)val == (Object)null)
					{
						val = weights[weights.Count - 1].Fishable;
					}
					if (IsBoss(val) && Object.op_Implicit((Object)(object)BossManager.Boss))
					{
						val = Traverse.Create((object)__instance).Field("_defaultFishable").GetValue<Fishable>();
					}
					__result = val;
					return false;
				}
				catch (Exception ex)
				{
					Plugin.Log.LogWarning((object)("[Luck] GetRandomItem fallback to vanilla: " + ex.Message));
					return true;
				}
			}
		}

		[HarmonyPatch(typeof(CreatureManager), "HookItem")]
		internal static class HookItem_Patch
		{
			private static void Prefix(CreatureManager __instance)
			{
				try
				{
					Traverse val = Traverse.Create((object)__instance).Field("_shinyCreatureChance");
					if (!_capturedBaseShiny)
					{
						_baseShiny = Mathf.Max(1, val.GetValue<int>());
						_capturedBaseShiny = true;
					}
					int num = Mathf.Clamp(Mathf.RoundToInt((float)_baseShiny * Plugin.LuckMultiplier.Value), 0, 100);
					val.SetValue((object)num);
				}
				catch (Exception ex)
				{
					Plugin.Log.LogWarning((object)("[Luck] shiny boost failed: " + ex.Message));
				}
			}
		}

		private static bool _capturedBaseShiny;

		private static int _baseShiny = 1;

		private static bool IsBoss(Fishable f)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Invalid comparison between Unknown and I4
			if (!Object.op_Implicit((Object)(object)f) || !Object.op_Implicit((Object)(object)f.ItemToSpawn))
			{
				return false;
			}
			Item itemToSpawn = f.ItemToSpawn;
			Creature val = (Creature)(object)((itemToSpawn is Creature) ? itemToSpawn : null);
			if ((Object)(object)val != (Object)null)
			{
				return (int)val.BossType > 0;
			}
			return false;
		}
	}
	internal static class MagmaWhalePatches
	{
		[HarmonyPatch(typeof(MainLava), "Awake")]
		internal static class MainLava_Awake_Patch
		{
			private static void Postfix(MainLava __instance)
			{
				if (!Object.op_Implicit((Object)(object)_cachedPrefab))
				{
					Creature value = Traverse.Create((object)__instance).Field("_mutatedWhalePrefab").GetValue<Creature>();
					if (Object.op_Implicit((Object)(object)value))
					{
						_cachedPrefab = value;
						Plugin.Log.LogInfo((object)("[MagmaWhale] cached " + ((Object)value).name + " - it can now be summoned from any island."));
					}
				}
			}
		}

		private static Creature _cachedPrefab;

		internal static void Summon()
		{
			if ((Object)(object)Server.Instance == (Object)null || !((NetworkBehaviour)Server.Instance).IsServerInitialized)
			{
				Plugin.Log.LogWarning((object)"[MagmaWhale] spawning is server-side - host or play solo.");
				return;
			}
			if (Object.op_Implicit((Object)(object)BossManager.Boss))
			{
				Plugin.Log.LogWarning((object)"[MagmaWhale] a boss is already alive - kill or lose it first.");
				return;
			}
			MainLava val = Object.FindAnyObjectByType<MainLava>();
			if (!Object.op_Implicit((Object)(object)val) || !SummonViaLava(val))
			{
				SummonRemote();
			}
		}

		private static bool SummonViaLava(MainLava lava)
		{
			MethodInfo methodInfo = AccessTools.Method(typeof(MainLava), "SpawnMutatedWhale", (Type[])null, (Type[])null);
			if (methodInfo == null)
			{
				return false;
			}
			if (!(methodInfo.Invoke(lava, null) is IEnumerator enumerator))
			{
				return false;
			}
			((MonoBehaviour)lava).StartCoroutine(enumerator);
			Plugin.Log.LogInfo((object)"[MagmaWhale] erupting the volcano - the whale spawns in ~3s.");
			return true;
		}

		private static void SummonRemote()
		{
			//IL_0041: 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_006d: 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_008d: 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_0097: 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_00ac: 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_00cf: 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_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)_cachedPrefab))
			{
				Plugin.Log.LogWarning((object)"[MagmaWhale] the whale prefab lives in Island5's scene and has not been loaded yet. Visit the lava island once this session (next-island key) and it can be summoned anywhere after that.");
				return;
			}
			Player localPlayer = Player.LocalPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				Plugin.Log.LogWarning((object)"[MagmaWhale] no local player to spawn in front of.");
				return;
			}
			Vector3 forward = localPlayer.Transform.forward;
			forward.y = 0f;
			if (((Vector3)(ref forward)).sqrMagnitude < 0.01f)
			{
				forward = Vector3.forward;
			}
			Vector3 val = localPlayer.Transform.position + ((Vector3)(ref forward)).normalized * Mathf.Max(5f, Plugin.MagmaWhaleDistance.Value);
			val.y = WaterManager.WaterHeight;
			Creature val2 = Object.Instantiate<Creature>(_cachedPrefab, val, Quaternion.LookRotation(-((Vector3)(ref forward)).normalized));
			((NetworkBehaviour)Server.Instance).Spawn(((Component)val2).gameObject, (NetworkConnection)null, default(Scene));
			Plugin.Log.LogInfo((object)($"[MagmaWhale] spawned {((Object)_cachedPrefab).name} {Plugin.MagmaWhaleDistance.Value:0}m ahead. " + "Note: its lava attacks aim at MainLava.LavaPosition, which is still the lava island's - expect odd behaviour off-island."));
		}
	}
	[HarmonyPatch(typeof(MoneyManager), "SellItem")]
	internal static class MoneyManager_SellItem_Patch
	{
		private static void Postfix(Item item)
		{
			MoneyManager instance = MoneyManager.Instance;
			if ((Object)(object)instance == (Object)null || !((NetworkBehaviour)instance).IsServerInitialized || (Object)(object)item == (Object)null)
			{
				return;
			}
			float value = Plugin.MoneyMultiplier.Value;
			if (value != 1f)
			{
				int num = Mathf.RoundToInt((float)item.TotalWorth * (value - 1f));
				if (num != 0)
				{
					SyncVar<int> money = instance._money;
					money.Value += num;
					Plugin.Log.LogInfo((object)$"[Economy] Sell x{value}: base {item.TotalWorth}, +{num} bonus");
				}
			}
		}
	}
	internal static class OnePunchPatches
	{
		[HarmonyPatch(typeof(PlayerPunching), "HitTarget")]
		internal static class HitTarget_Patch
		{
			private static void Prefix(PlayerPunching __instance)
			{
				_swapped = false;
				if (Plugin.OnePunchActive && Object.op_Implicit((Object)(object)__instance))
				{
					NetworkConnection owner = ((NetworkBehaviour)__instance).Owner;
					if (!(owner == (NetworkConnection)null) && owner.IsLocalClient)
					{
						Traverse obj = Traverse.Create((object)__instance).Field("_damage");
						_baseDamage = obj.GetValue<int>();
						obj.SetValue((object)Plugin.OnePunchDamage.Value);
						_swapped = true;
					}
				}
			}

			private static void Finalizer(PlayerPunching __instance)
			{
				if (_swapped)
				{
					_swapped = false;
					if (Object.op_Implicit((Object)(object)__instance))
					{
						Traverse.Create((object)__instance).Field("_damage").SetValue((object)_baseDamage);
					}
				}
			}
		}

		private static bool _swapped;

		private static int _baseDamage;
	}
	internal static class PlayerListGuard
	{
		private static int _lastReported;

		internal static void Sweep()
		{
			if (Plugin.PruneBrokenPlayers.Value)
			{
				int num = 0;
				num += Prune(PlayerManager.AlivePlayers);
				num += Prune(PlayerManager.Players);
				num += Prune(PlayerManager.OtherPlayers);
				if (num > 0)
				{
					_lastReported += num;
					Plugin.Log.LogWarning((object)($"[PlayerListGuard] dropped {num} player entry/entries with a missing Transform " + "(these break boat buoyancy and NPC targeting)."));
				}
			}
		}

		private static int Prune(List<Player> list)
		{
			if (list == null)
			{
				return 0;
			}
			int num = 0;
			for (int num2 = list.Count - 1; num2 >= 0; num2--)
			{
				Player val = list[num2];
				if ((Object)(object)val == (Object)null || (Object)(object)val.Transform == (Object)null)
				{
					list.RemoveAt(num2);
					num++;
				}
			}
			return num;
		}
	}
	[BepInPlugin("com.brade.howtofishtweaks", "How To Fish Tweaks", "0.32.1")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.brade.howtofishtweaks";

		public const string PluginName = "How To Fish Tweaks";

		public const string PluginVersion = "0.32.1";

		internal static ManualLogSource Log;

		internal static Plugin Instance;

		private const float MultMin = 1f;

		private const float MultMax = 100f;

		private const float MultStep = 1f;

		public static ConfigEntry<float> MoneyMultiplier;

		private ConfigEntry<KeyboardShortcut> _moneyDown;

		private ConfigEntry<KeyboardShortcut> _moneyUp;

		public static ConfigEntry<float> LuckMultiplier;

		private ConfigEntry<KeyboardShortcut> _luckDown;

		private ConfigEntry<KeyboardShortcut> _luckUp;

		public static ConfigEntry<bool> AimbotEnabled;

		public static ConfigEntry<float> AimbotFovDegrees;

		public static ConfigEntry<float> AimbotMaxDistance;

		public static ConfigEntry<float> AimbotSnapSharpness;

		public static ConfigEntry<float> AimbotMaxRotationSpeed;

		private ConfigEntry<KeyboardShortcut> _toggleAimbot;

		public static bool AimbotActive;

		public static ConfigEntry<bool> BunnyHopEnabled;

		private ConfigEntry<KeyboardShortcut> _toggleBunnyHop;

		public static bool BunnyHopActive;

		private float _lastHopTime;

		public static ConfigEntry<bool> RevealIslandsEnabled;

		private ConfigEntry<KeyboardShortcut> _toggleReveal;

		public static ConfigEntry<bool> UnlockIslandTravel;

		private ConfigEntry<KeyboardShortcut> _islandPrev;

		private ConfigEntry<KeyboardShortcut> _islandNext;

		public static bool RevealIslandsActive;

		public static ConfigEntry<bool> InfiniteAmmoEnabled;

		private ConfigEntry<KeyboardShortcut> _toggleInfiniteAmmo;

		public static bool InfiniteAmmoActive;

		public static ConfigEntry<bool> FishermanAimbotEnabled;

		public static ConfigEntry<float> FishermanFov;

		public static ConfigEntry<float> FishermanSharpness;

		private ConfigEntry<KeyboardShortcut> _toggleFisherman;

		public static bool FishermanAimbotActive;

		public static ConfigEntry<bool> JesusModeEnabled;

		public static ConfigEntry<float> JesusSurfaceOffset;

		private ConfigEntry<KeyboardShortcut> _toggleJesus;

		public static bool JesusModeActive;

		public static ConfigEntry<bool> MrFantasticEnabled;

		public static ConfigEntry<float> MrFantasticReach;

		private ConfigEntry<KeyboardShortcut> _toggleFantastic;

		public static bool MrFantasticActive;

		public static ConfigEntry<bool> BossRushEnabled;

		public static ConfigEntry<bool> BossRushAllowMini;

		public static ConfigEntry<string> BossRushTargetName;

		private ConfigEntry<KeyboardShortcut> _bossPrev;

		private ConfigEntry<KeyboardShortcut> _bossNext;

		private ConfigEntry<KeyboardShortcut> _summonMagmaWhale;

		public static ConfigEntry<float> MagmaWhaleDistance;

		private ConfigEntry<KeyboardShortcut> _toggleBossRush;

		public static bool BossRushActive;

		public static ConfigEntry<bool> LaserGunEnabled;

		public static ConfigEntry<bool> LaserGunNoRecoil;

		private ConfigEntry<KeyboardShortcut> _toggleLaserGun;

		public static bool LaserGunActive;

		public static ConfigEntry<bool> OnePunchEnabled;

		public static ConfigEntry<int> OnePunchDamage;

		private ConfigEntry<KeyboardShortcut> _toggleOnePunch;

		public static bool OnePunchActive;

		public const float SpeedMin = 1f;

		public const float SpeedMax = 40f;

		public static ConfigEntry<bool> SpeedModeEnabled;

		private static float _lastSpeed = 5f;

		public static ConfigEntry<float> SpeedMultiplier;

		private ConfigEntry<KeyboardShortcut> _toggleSpeed;

		private ConfigEntry<KeyboardShortcut> _speedDown;

		private ConfigEntry<KeyboardShortcut> _speedUp;

		public const float FlyMin = 1f;

		public const float FlyMax = 200f;

		public static ConfigEntry<float> FlySpeed;

		public static ConfigEntry<float> FlyBoost;

		private ConfigEntry<KeyboardShortcut> _toggleFly;

		public static bool FlyActive;

		public static bool FlyAllowed = true;

		public static ConfigEntry<bool> VisibilityEnabled;

		public static ConfigEntry<float> FogMultiplier;

		public static ConfigEntry<float> ViewDistance;

		private ConfigEntry<KeyboardShortcut> _toggleVisibility;

		public static bool VisibilityActive;

		public static ConfigEntry<bool> DripperClamsEnabled;

		public static ConfigEntry<bool> DripperAcceptAnything;

		private ConfigEntry<KeyboardShortcut> _toggleDripper;

		public static bool DripperClamsActive;

		public static ConfigEntry<string> CasinoRarity;

		private ConfigEntry<KeyboardShortcut> _cycleCasino;

		public static ConfigEntry<string> RouletteColor;

		public static bool RouletteRigActive;

		public static ConfigEntry<float> WorthMultiplier;

		private ConfigEntry<KeyboardShortcut> _toggleSpawnList;

		private ConfigEntry<KeyboardShortcut> _spawnListNext;

		private ConfigEntry<KeyboardShortcut> _spawnListBack;

		public static ConfigEntry<bool> UnlockAllSkins;

		public static ConfigEntry<float> JailKillInterval;

		public static ConfigEntry<float> SmiteFovDegrees;

		private ConfigEntry<KeyboardShortcut> _smite;

		public static ConfigEntry<bool> DevConsoleEnabled;

		private ConfigEntry<KeyboardShortcut> _toggleGodMode;

		public static ConfigEntry<float> AutoReviveInterval;

		public static bool AutoReviveActive;

		public static ConfigEntry<bool> PruneBrokenPlayers;

		private ConfigEntry<KeyboardShortcut> _toggleOverlay;

		private bool _showOverlay = true;

		private readonly Harmony _harmony = new Harmony("com.brade.howtofishtweaks");

		private const int PanelWidth = 560;

		private const int Margin = 10;

		private const int LineHeight = 20;

		private static readonly Color HeaderColour = new Color(0.55f, 0.85f, 1f);

		private static readonly Color DimColour = new Color(1f, 1f, 1f, 0.35f);

		internal static bool IsHosting
		{
			get
			{
				if ((Object)(object)Server.Instance != (Object)null)
				{
					return ((NetworkBehaviour)Server.Instance).IsServerInitialized;
				}
				return false;
			}
		}

		private void Awake()
		{
			//IL_002c: 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_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0325: Unknown result type (might be due to invalid IL or missing references)
			//IL_0374: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_045a: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0581: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_062b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0697: Unknown result type (might be due to invalid IL or missing references)
			//IL_070a: Unknown result type (might be due to invalid IL or missing references)
			//IL_077a: Unknown result type (might be due to invalid IL or missing references)
			//IL_07a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_07d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0846: Unknown result type (might be due to invalid IL or missing references)
			//IL_08da: Unknown result type (might be due to invalid IL or missing references)
			//IL_0926: Unknown result type (might be due to invalid IL or missing references)
			//IL_0996: Unknown result type (might be due to invalid IL or missing references)
			//IL_09e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a12: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a3e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ab1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b48: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			_toggleOverlay = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "ToggleOverlay", new KeyboardShortcut((KeyCode)282, Array.Empty<KeyCode>()), "Show/hide the on-screen mod indicator.");
			MoneyMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Economy", "MoneyMultiplier", 10f, "Multiplier applied to sell payouts (1-100). Adjustable live with the hotkeys.");
			_moneyDown = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Economy", "DecreaseKey", new KeyboardShortcut((KeyCode)284, Array.Empty<KeyCode>()), "Decrease the money multiplier.");
			_moneyUp = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Economy", "IncreaseKey", new KeyboardShortcut((KeyCode)285, Array.Empty<KeyCode>()), "Increase the money multiplier.");
			AimbotEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Aimbot", "Enabled", true, "Start with the fish aimbot on. Aims your weapon at the nearest fish while aiming down sights.");
			_toggleAimbot = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Aimbot", "ToggleKey", new KeyboardShortcut((KeyCode)283, Array.Empty<KeyCode>()), "Toggle the fish aimbot on/off.");
			AimbotFovDegrees = ((BaseUnityPlugin)this).Config.Bind<float>("Aimbot", "FovDegrees", 80f, "Half-angle of the targeting cone. Vanilla assist is 18. 90 = anything in front of you.");
			AimbotMaxDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Aimbot", "MaxDistance", 300f, "Max targeting distance (metres). Vanilla is 60.");
			AimbotSnapSharpness = ((BaseUnityPlugin)this).Config.Bind<float>("Aimbot", "SnapSharpness", 30f, "How aggressively aim snaps to target. Vanilla is 10.");
			AimbotMaxRotationSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Aimbot", "MaxRotationSpeed", 720f, "Max degrees/second the aim rotates toward a target. Vanilla is 120.");
			LuckMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Luck", "LuckMultiplier", 3f, "Boosts rare + shiny (lucky) fish (1-100). 1 = vanilla. Higher = rarer species more often and higher shiny chance (100 = always shiny).");
			_luckDown = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Luck", "DecreaseKey", new KeyboardShortcut((KeyCode)288, Array.Empty<KeyCode>()), "Decrease the luck multiplier.");
			_luckUp = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Luck", "IncreaseKey", new KeyboardShortcut((KeyCode)289, Array.Empty<KeyCode>()), "Increase the luck multiplier.");
			BunnyHopEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("BunnyHop", "Enabled", true, "Auto-jump the instant you land while holding Jump (Space).");
			_toggleBunnyHop = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("BunnyHop", "ToggleKey", new KeyboardShortcut((KeyCode)286, Array.Empty<KeyCode>()), "Toggle bunny hop on/off.");
			RevealIslandsEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Islands", "RevealIslands", true, "Force the radar on and show all island dots (also unlocks travel to all islands as host).");
			_toggleReveal = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Islands", "ToggleKey", new KeyboardShortcut((KeyCode)287, Array.Empty<KeyCode>()), "Toggle reveal islands on/off.");
			UnlockIslandTravel = ((BaseUnityPlugin)this).Config.Bind<bool>("Islands", "UnlockTravel", true, "Also unlock ACTUAL travel, not just the radar dots. Revealing dots and being allowed to sail somewhere are two separate reads of MaxIslandUnlocked; this covers the travel trigger too.");
			_islandPrev = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Islands", "PrevIslandKey", new KeyboardShortcut((KeyCode)44, Array.Empty<KeyCode>()), "Travel to the previous island immediately (host/solo).");
			_islandNext = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Islands", "NextIslandKey", new KeyboardShortcut((KeyCode)46, Array.Empty<KeyCode>()), "Travel to the next island immediately (host/solo). The last index is the hidden DevIsland.");
			InfiniteAmmoEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("InfiniteAmmo", "Enabled", true, "Never run out of ammo — the weapon refills to a full mag before every shot (no reloading).");
			_toggleInfiniteAmmo = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("InfiniteAmmo", "ToggleKey", new KeyboardShortcut((KeyCode)290, Array.Empty<KeyCode>()), "Toggle infinite ammo on/off.");
			FishermanAimbotEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("FishermanAimbot", "Enabled", false, "Aimbot that targets the nearest OTHER player (fisherman) while aiming a weapon down sights.");
			_toggleFisherman = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("FishermanAimbot", "ToggleKey", new KeyboardShortcut((KeyCode)278, Array.Empty<KeyCode>()), "Toggle the fisherman (player) aimbot on/off.");
			FishermanFov = ((BaseUnityPlugin)this).Config.Bind<float>("FishermanAimbot", "FovDegrees", 90f, "Only lock onto players within this angle of your view center.");
			FishermanSharpness = ((BaseUnityPlugin)this).Config.Bind<float>("FishermanAimbot", "SnapSharpness", 30f, "How aggressively aim snaps onto the target player. Higher = snappier.");
			JesusModeEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("JesusMode", "Enabled", false, "Walk on water — keeps you on the surface instead of swimming/sinking.");
			_toggleJesus = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("JesusMode", "ToggleKey", new KeyboardShortcut((KeyCode)292, Array.Empty<KeyCode>()), "Toggle Jesus mode (walk on water) on/off.");
			JesusSurfaceOffset = ((BaseUnityPlugin)this).Config.Bind<float>("JesusMode", "SurfaceOffset", 0.1f, "How high above the water line to stand. Raise a little if you still sink/swim.");
			MrFantasticEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("MrFantastic", "Enabled", false, "Stretchy long-arm punch: your fist reaches far and the arm stretches to follow.");
			MrFantasticReach = ((BaseUnityPlugin)this).Config.Bind<float>("MrFantastic", "ReachMultiplier", 20f, "How many times longer the punch reach is (default 20x).");
			_toggleFantastic = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("MrFantastic", "ToggleKey", new KeyboardShortcut((KeyCode)277, Array.Empty<KeyCode>()), "Toggle Mr. Fantastic mode (F12 is Steam's screenshot key, so this defaults to Insert).");
			BossRushEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("BossRush", "Enabled", false, "Every cast hooks the final boss (host/solo only — fish spawning is server-side). Skipped while a boss is already alive, since the boss fight is a single global state.");
			BossRushAllowMini = ((BaseUnityPlugin)this).Config.Bind<bool>("BossRush", "AllowMiniBoss", true, "If no final boss asset is loaded, settle for a mini boss instead of a normal fish.");
			BossRushTargetName = ((BaseUnityPlugin)this).Config.Bind<string>("BossRush", "TargetBossName", "Whale", "Name (or part of one) of the boss to force, searched across every loaded boss. Blank means 'Mutated' = the Mutated Bowhead Whale, the magma/lava final boss. Use 'Bowhead' for the ordinary island-5 whale instead. Write 'local' to go back to whichever boss owns the water you are fishing, which on island 1 is the Giant Piranha. Press the catalog key to log every loaded boss name.");
			_bossPrev = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("BossRush", "PrevBossKey", new KeyboardShortcut((KeyCode)59, Array.Empty<KeyCode>()), "Cycle the boss target backwards through every boss currently loaded. Bosses load with their island, so the list changes as you travel.");
			_bossNext = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("BossRush", "NextBossKey", new KeyboardShortcut((KeyCode)39, Array.Empty<KeyCode>()), "Cycle the boss target forwards (mini bosses first, then final bosses).");
			_summonMagmaWhale = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("BossRush", "SummonMagmaWhaleKey", new KeyboardShortcut((KeyCode)8, Array.Empty<KeyCode>()), "Summon the Mutated Bowhead Whale (the magma final boss). It is not fishable - vanilla spawns it when a dead Bowhead Whale is thrown into the lava. On Island5 this runs the real scripted spawn; elsewhere it drops the whale in front of you, but only once you have visited the lava island this session. Host only.");
			MagmaWhaleDistance = ((BaseUnityPlugin)this).Config.Bind<float>("BossRush", "MagmaWhaleSpawnDistance", 40f, "How far ahead of you the magma whale drops when summoned away from the lava island.");
			_toggleBossRush = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("BossRush", "ToggleKey", new KeyboardShortcut((KeyCode)279, Array.Empty<KeyCode>()), "Toggle boss-every-cast on/off.");
			LaserGunEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("LaserGun", "Enabled", false, "Every gun, sniper included, fires continuously with no pause between shots.");
			LaserGunNoRecoil = ((BaseUnityPlugin)this).Config.Bind<bool>("LaserGun", "NoRecoil", true, "Suppress the view kick so the stream stays on target - this is what makes it read as a laser.");
			_toggleLaserGun = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("LaserGun", "ToggleKey", new KeyboardShortcut((KeyCode)127, Array.Empty<KeyCode>()), "Toggle super auto guns on/off. Pair with infinite ammo (F9).");
			OnePunchEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("OnePunch", "Enabled", false, "One Punch Man: anything your fist connects with dies instantly.");
			OnePunchDamage = ((BaseUnityPlugin)this).Config.Bind<int>("OnePunch", "Damage", 999999, "Damage per punch. The game's own one-shot setting uses 99999; 999999 also flattens the final boss.");
			_toggleOnePunch = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("OnePunch", "ToggleKey", new KeyboardShortcut((KeyCode)281, Array.Empty<KeyCode>()), "Toggle One Punch Man on/off.");
			SpeedModeEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Speed", "Enabled", false, "Scale walk and sprint speed.");
			SpeedMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Speed", "SpeedMultiplier", 1f, "How many times faster you move (1-40). Live as soon as it is above 1 - the -/= keys are all you need.");
			_toggleSpeed = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Speed", "ToggleKey", new KeyboardShortcut((KeyCode)93, Array.Empty<KeyCode>()), "Snap the speed multiplier between 1x and your last setting. Speed is live whenever the multiplier is above 1 - there is no separate on/off.");
			_speedDown = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Speed", "DecreaseKey", new KeyboardShortcut((KeyCode)45, Array.Empty<KeyCode>()), "Decrease the speed multiplier.");
			_speedUp = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Speed", "IncreaseKey", new KeyboardShortcut((KeyCode)61, Array.Empty<KeyCode>()), "Increase the speed multiplier.");
			FlySpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Fly", "FlySpeed", 20f, "Flight speed in metres/second (1-200).");
			FlyBoost = ((BaseUnityPlugin)this).Config.Bind<float>("Fly", "ShiftBoost", 4f, "Speed multiplier while holding Left Shift.");
			_toggleFly = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Fly", "ToggleKey", new KeyboardShortcut((KeyCode)103, Array.Empty<KeyCode>()), "Toggle fly mode. WASD to move, Space up, Left Ctrl down, Shift to boost.");
			VisibilityEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Visibility", "Enabled", false, "See further: thins out the fog (including the thick underwater fog) and pushes the camera's far clip plane back.");
			FogMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Visibility", "FogMultiplier", 0.15f, "Fraction of the game's fog density to keep (0-1). 0 turns fog off entirely, 1 is vanilla.");
			ViewDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Visibility", "ViewDistance", 5000f, "Minimum camera far clip plane in metres. The plane is only ever pushed out, never pulled in. 0 leaves it alone.");
			_toggleVisibility = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Visibility", "ToggleKey", new KeyboardShortcut((KeyCode)91, Array.Empty<KeyCode>()), "Toggle the visibility boost on/off.");
			DripperClamsEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Dripper", "Enabled", false, "Let the Dripper (slot machine) accept clams as well as drip creatures and quest items.");
			_toggleDripper = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Dripper", "ToggleKey", new KeyboardShortcut((KeyCode)92, Array.Empty<KeyCode>()), "Toggle clams in the Dripper on/off.");
			DripperAcceptAnything = ((BaseUnityPlugin)this).Config.Bind<bool>("Dripper", "AcceptAnything", false, "Accept ANY dropped item, not just clams. Off by default - the machine destroys whatever it takes, so this will happily eat a rod you set down next to it.");
			CasinoRarity = ((BaseUnityPlugin)this).Config.Bind<string>("Casino", "ForceOutcome", "green", "What the Dripper always lands on: 'green' (whichever rarity is shown in green), 'rare', 'legendary', 'common', or 'off' for a fair roll. Host/solo only.");
			_cycleCasino = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Casino", "CycleKey", new KeyboardShortcut((KeyCode)47, Array.Empty<KeyCode>()), "Cycle the rigged slot-machine outcome: off / green / rare / legendary.");
			RouletteColor = ((BaseUnityPlugin)this).Config.Bind<string>("Roulette", "WinningColor", "green", "Colour the roulette always lands on: green (35x), red or black. Host only - the host's machine simulates the ball and decides the result.");
			_toggleSpawnList = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("SpawnList", "ToggleKey", new KeyboardShortcut((KeyCode)107, Array.Empty<KeyCode>()), "Show/hide the list of everything /give can spawn.");
			_spawnListNext = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("SpawnList", "NextPageKey", new KeyboardShortcut((KeyCode)110, Array.Empty<KeyCode>()), "Next page of the spawn list.");
			_spawnListBack = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("SpawnList", "PrevPageKey", new KeyboardShortcut((KeyCode)98, Array.Empty<KeyCode>()), "Previous page of the spawn list.");
			WorthMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Economy", "WorthMultiplier", 1000f, "Default multiplier used by /worth on the item you are holding. Works as a client, unlike the sell multiplier - but only once per item.");
			UnlockAllSkins = ((BaseUnityPlugin)this).Config.Bind<bool>("Skins", "UnlockAll", true, "Unlock every hat, outfit, accessory, item skin and boat skin. Re-run any time with /skins in chat.");
			_smite = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Admin", "SmiteKey", new KeyboardShortcut((KeyCode)280, Array.Empty<KeyCode>()), "Instantly kill whichever player is closest to your crosshair (host only).");
			SmiteFovDegrees = ((BaseUnityPlugin)this).Config.Bind<float>("Admin", "SmiteFovDegrees", 30f, "How far off your crosshair a player can be and still be smited.");
			JailKillInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Admin", "JailKillInterval", 3f, "Seconds between re-killing a jailed player.");
			DevConsoleEnabled = ((BaseUnityPlugin)this).Config.Bin