Decompiled source of Supermans AFK Fishing v1.0.8

SupermansAFKFishing.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_utils")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace AFKFishing
{
	internal static class AutoFisher
	{
		private class FloatState
		{
			public float Since;

			public float NextScan;

			public float WaterSince = -1f;
		}

		private enum ScanResult
		{
			None,
			NoFish,
			WrongBait
		}

		internal static bool Active;

		internal static bool FishingNow;

		private static float _nextCastTime;

		private static bool _hadFloats;

		private static readonly Dictionary<FishingFloat, FloatState> _states = new Dictionary<FishingFloat, FloatState>();

		private static readonly List<FishingFloat> _floats = new List<FishingFloat>();

		private const float MinLineSpacing = 3f;

		private static int _solidMask;

		private static readonly Dictionary<Biome, string> BiomeBait = new Dictionary<Biome, string>
		{
			{
				(Biome)1,
				"FishingBait"
			},
			{
				(Biome)8,
				"FishingBaitForest"
			},
			{
				(Biome)2,
				"FishingBaitSwamp"
			},
			{
				(Biome)4,
				"FishingBaitCave"
			},
			{
				(Biome)16,
				"FishingBaitPlains"
			},
			{
				(Biome)256,
				"FishingBaitOcean"
			},
			{
				(Biome)512,
				"FishingBaitMistlands"
			},
			{
				(Biome)32,
				"FishingBaitAshlands"
			},
			{
				(Biome)64,
				"FishingBaitDeepNorth"
			}
		};

		private static string _lastMissingBaitMsg;

		private static ScanResult _scanResult;

		private static readonly Dictionary<Biome, List<Fish>> _regionFish = new Dictionary<Biome, List<Fish>>();

		private static FloatState StateOf(FishingFloat ff)
		{
			if (!_states.TryGetValue(ff, out var value))
			{
				Dictionary<FishingFloat, FloatState> states = _states;
				FloatState obj = new FloatState
				{
					Since = Time.time
				};
				value = obj;
				states[ff] = obj;
			}
			return value;
		}

		private static void CollectFloats(Player player)
		{
			_floats.Clear();
			foreach (FishingFloat allInstance in FishingFloat.GetAllInstances())
			{
				if (Object.op_Implicit((Object)(object)allInstance) && allInstance.m_nview.IsValid() && (Object)(object)allInstance.GetOwner() == (Object)(object)player)
				{
					_floats.Add(allInstance);
				}
			}
			if (_states.Count <= _floats.Count)
			{
				return;
			}
			List<FishingFloat> list = new List<FishingFloat>();
			foreach (FishingFloat key in _states.Keys)
			{
				if (!_floats.Contains(key))
				{
					list.Add(key);
				}
			}
			foreach (FishingFloat item in list)
			{
				_states.Remove(item);
			}
		}

		internal static void Update()
		{
			//IL_00a4: 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)
			Player localPlayer = Player.m_localPlayer;
			ItemData val = (Object.op_Implicit((Object)(object)localPlayer) ? GetRod(localPlayer) : null);
			if (!Plugin.ModEnabled.Value || (Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead())
			{
				if (Active)
				{
					Stop(null);
				}
				FishingNow = false;
				return;
			}
			if (val != null && Plugin.NoDurability.Value && val.m_shared.m_useDurability)
			{
				val.m_durability = val.GetMaxDurability();
			}
			CollectFloats(localPlayer);
			FishingNow = val != null && (Active || _floats.Count > 0 || ((Character)localPlayer).IsDrawingBow());
			KeyboardShortcut value = Plugin.ToggleKey.Value;
			if (((KeyboardShortcut)(ref value)).IsDown() && !TypingOrInMenu())
			{
				if (Active)
				{
					Stop("Auto fishing stopped");
				}
				else if (val == null)
				{
					((Character)localPlayer).Message((MessageType)2, "Hold a fishing rod to start auto fishing", 0, (Sprite)null, false);
				}
				else
				{
					Start(localPlayer);
				}
			}
			if (!Active)
			{
				return;
			}
			if (val == null)
			{
				Stop("Auto fishing stopped (no fishing rod in hand)");
			}
			else if (_floats.Count > 0)
			{
				_hadFloats = true;
				FishingFloat[] array = _floats.ToArray();
				foreach (FishingFloat val2 in array)
				{
					if (!val2.m_nview.IsOwner())
					{
						continue;
					}
					FloatState floatState = StateOf(val2);
					bool flag = !val2.IsInWater() && Time.time - floatState.Since > 5f;
					if ((Object)(object)val2.GetCatch() == (Object)null && (Time.time - floatState.Since > Plugin.RecastSeconds.Value || flag))
					{
						string text = (flag ? "Float landed out of water - face open water" : ((_scanResult == ScanResult.WrongBait) ? ("Fish nearby don't take " + BaitName(val2) + " - try another bait") : ((_scanResult == ScanResult.NoFish) ? "No fish near the float - try another spot" : null)));
						if (text != null)
						{
							((Character)localPlayer).Message((MessageType)2, text + ", recasting", 0, (Sprite)null, false);
						}
						val2.ReturnBait();
						val2.m_nview.Destroy();
						_states.Remove(val2);
					}
				}
			}
			else if (_hadFloats)
			{
				_hadFloats = false;
				_nextCastTime = Time.time + Plugin.CastDelay.Value;
			}
			else if (Time.time >= _nextCastTime && !((Character)localPlayer).InAttack())
			{
				Cast(localPlayer, val);
			}
		}

		private static void Start(Player player)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			Active = true;
			_scanResult = ScanResult.None;
			_states.Clear();
			_hadFloats = false;
			_nextCastTime = Time.time + 0.2f;
			((Character)player).Message((MessageType)2, "Auto fishing started (" + ((object)Plugin.ToggleKey.Value/*cast due to .constrained prefix*/).ToString() + " to stop)", 0, (Sprite)null, false);
		}

		private static void Stop(string message)
		{
			Active = false;
			_states.Clear();
			if (message != null && Object.op_Implicit((Object)(object)Player.m_localPlayer))
			{
				((Character)Player.m_localPlayer).Message((MessageType)2, message, 0, (Sprite)null, false);
			}
		}

		internal static void CastExtraLines(Attack attack)
		{
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: 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_01e7: 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_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0282: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0303: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			int num = Plugin.LineCount.Value - 1;
			if (!Active || num <= 0 || (Object)(object)localPlayer == (Object)null || (Object)(object)attack.m_character != (Object)(object)localPlayer || attack.m_weapon != GetRod(localPlayer))
			{
				return;
			}
			Projectile val = (Object.op_Implicit((Object)(object)attack.m_weapon.m_lastProjectile) ? attack.m_weapon.m_lastProjectile.GetComponent<Projectile>() : null);
			ItemData lastUsedAmmo = attack.m_lastUsedAmmo;
			if (!Object.op_Implicit((Object)(object)val) || lastUsedAmmo == null || !Object.op_Implicit((Object)(object)lastUsedAmmo.m_dropPrefab))
			{
				return;
			}
			GameObject val2 = (Object.op_Implicit((Object)(object)lastUsedAmmo.m_shared.m_attack.m_attackProjectile) ? lastUsedAmmo.m_shared.m_attack.m_attackProjectile : attack.m_attackProjectile);
			if (!Object.op_Implicit((Object)(object)val2))
			{
				return;
			}
			string name = ((Object)lastUsedAmmo.m_dropPrefab).name;
			Inventory inventory = ((Humanoid)localPlayer).GetInventory();
			int num2 = 0;
			foreach (ItemData allItem in inventory.GetAllItems())
			{
				if (IsBaitItem(allItem, name))
				{
					num2 += allItem.m_stack;
				}
			}
			int num3 = inventory.GetWidth() * inventory.GetHeight() - inventory.GetAllItems().Count - 1;
			int num4 = Mathf.Min(num, Mathf.Min(num2, num3));
			if (num4 < num)
			{
				((Character)localPlayer).Message((MessageType)1, "Casting " + (Mathf.Max(num4, 0) + 1) + " of " + (num + 1) + " lines (" + ((num2 < num3) ? "not enough bait" : "not enough free inventory slots") + ")", 0, (Sprite)null, false);
			}
			if (num4 <= 0)
			{
				return;
			}
			Vector3 vel = val.m_vel;
			Vector3 position = ((Component)val).transform.position;
			List<Vector3> list = PickWaterThrows(val, position, vel, num4);
			if (list.Count < num4)
			{
				((Character)localPlayer).Message((MessageType)1, "Casting " + (list.Count + 1) + " of " + (num + 1) + " lines (only room for " + (list.Count + 1) + " in the water in front of you)", 0, (Sprite)null, false);
			}
			foreach (Vector3 item in list)
			{
				ItemData val3 = null;
				foreach (ItemData allItem2 in inventory.GetAllItems())
				{
					if (IsBaitItem(allItem2, name))
					{
						val3 = allItem2;
						break;
					}
				}
				if (val3 == null)
				{
					break;
				}
				GameObject val4 = Object.Instantiate<GameObject>(val2, position, Quaternion.LookRotation(item));
				Projectile component = val4.GetComponent<Projectile>();
				if (!Object.op_Implicit((Object)(object)component))
				{
					Object.Destroy((Object)(object)val4);
					break;
				}
				component.Setup((Character)(object)localPlayer, item, val.m_hitNoise, (HitData)null, attack.m_weapon, lastUsedAmmo);
				component.m_spawnOnHit = val.m_spawnOnHit;
				component.m_spawnOnHitChance = val.m_spawnOnHitChance;
				inventory.RemoveItem(val3, 1);
			}
		}

		private static List<Vector3> PickWaterThrows(Projectile main, Vector3 origin, Vector3 velocity, int count)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: 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_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			List<Vector3> list = new List<Vector3>();
			List<Vector3> list2 = new List<Vector3>();
			if (PredictWaterLanding(main, origin, velocity, out var spot))
			{
				list2.Add(spot);
			}
			float[] array = new float[4] { 1f, 0.85f, 0.7f, 0.55f };
			for (int i = 0; i <= 15; i++)
			{
				if (list.Count >= count)
				{
					break;
				}
				for (int j = -1; j <= 1; j += 2)
				{
					if (list.Count >= count)
					{
						break;
					}
					if (i == 0 && j == 1)
					{
						continue;
					}
					float num = (float)i * 5f * (float)j;
					float[] array2 = array;
					foreach (float num2 in array2)
					{
						if (list.Count >= count)
						{
							break;
						}
						Vector3 val = Quaternion.Euler(0f, num, 0f) * velocity * num2;
						if (!PredictWaterLanding(main, origin, val, out var spot2))
						{
							continue;
						}
						bool flag = false;
						foreach (Vector3 item in list2)
						{
							if (Utils.DistanceXZ(spot2, item) < 3f)
							{
								flag = true;
								break;
							}
						}
						if (!flag)
						{
							list2.Add(spot2);
							list.Add(val);
						}
					}
				}
			}
			return list;
		}

		private static bool PredictWaterLanding(Projectile proj, Vector3 pos, Vector3 vel, out Vector3 spot)
		{
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00be: 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_00d4: 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_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: 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)
			if (_solidMask == 0)
			{
				_solidMask = LayerMask.GetMask(new string[7] { "Default", "static_solid", "Default_small", "piece", "piece_nonsolid", "terrain", "vehicle" });
			}
			float num = ((Time.fixedDeltaTime > 0f) ? Time.fixedDeltaTime : 0.02f);
			float num2 = ((proj.m_ttl > 0f) ? proj.m_ttl : 4f);
			RaycastHit val2 = default(RaycastHit);
			for (float num3 = 0f; num3 < num2; num3 += num)
			{
				Vector3 val = pos;
				vel += Vector3.down * (proj.m_gravity * num);
				float num4 = ((Vector3)(ref vel)).sqrMagnitude * proj.m_drag * num;
				vel += num4 * -((Vector3)(ref vel)).normalized;
				pos += vel * num;
				if (Physics.Linecast(val, pos, ref val2, _solidMask, (QueryTriggerInteraction)1))
				{
					spot = ((RaycastHit)(ref val2)).point;
					return false;
				}
				if (pos.y < Floating.GetLiquidLevel(pos, 1f, (LiquidType)10))
				{
					spot = pos;
					return true;
				}
			}
			spot = pos;
			return false;
		}

		private static bool IsBaitItem(ItemData item, string baitPrefab)
		{
			if (item != null && Object.op_Implicit((Object)(object)item.m_dropPrefab))
			{
				return ((Object)item.m_dropPrefab).name == baitPrefab;
			}
			return false;
		}

		private static void Cast(Player player, ItemData rod)
		{
			if (!((Humanoid)player).GetInventory().HaveEmptySlot())
			{
				Stop("Auto fishing stopped: inventory full");
				return;
			}
			if (Plugin.AutoSelectBait.Value)
			{
				SelectBait(player, rod);
			}
			if (!rod.m_shared.m_attack.StartDraw((Humanoid)(object)player, rod))
			{
				Stop("Auto fishing stopped: out of bait");
				return;
			}
			((Humanoid)player).m_attackDrawTime = 100f;
			bool flag = ((Character)player).StartAttack((Character)null, false);
			((Humanoid)player).m_attackDrawTime = 0f;
			_nextCastTime = Time.time + (flag ? 3f : 1f);
		}

		private static void SelectBait(Player player, ItemData rod)
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Invalid comparison between Unknown and I4
			//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_00db: 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_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Invalid comparison between Unknown and I4
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_02af: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0392: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<string, ItemData> dictionary = new Dictionary<string, ItemData>();
			foreach (ItemData allItem in ((Humanoid)player).GetInventory().GetAllItems())
			{
				if (!(allItem.m_shared.m_ammoType != rod.m_shared.m_ammoType) && !((Object)(object)allItem.m_dropPrefab == (Object)null) && ((int)allItem.m_shared.m_itemType == 9 || (int)allItem.m_shared.m_itemType == 23) && !dictionary.ContainsKey(((Object)allItem.m_dropPrefab).name))
				{
					dictionary[((Object)allItem.m_dropPrefab).name] = allItem;
				}
			}
			if (dictionary.Count == 0)
			{
				return;
			}
			Vector3 forward = ((Component)player).transform.forward;
			forward.y = 0f;
			Vector3 val = ((Component)player).transform.position + ((Vector3)(ref forward)).normalized * 15f;
			float num = Plugin.HookRange.Value + 15f;
			Dictionary<string, float> dictionary2 = new Dictionary<string, float>();
			HashSet<string> hashSet = new HashSet<string>();
			foreach (IMonoUpdater instance in Fish.Instances)
			{
				Fish val2 = (Fish)(object)((instance is Fish) ? instance : null);
				if (val2 == null || !Object.op_Implicit((Object)(object)val2) || val2.IsHooked())
				{
					continue;
				}
				Vector3 position = ((Component)val2).transform.position;
				if (val2.m_inWater <= -10000f || val2.m_inWater < position.y + val2.m_height)
				{
					continue;
				}
				float num2 = Vector3.Distance(position, val);
				if (num2 > num)
				{
					continue;
				}
				foreach (BaitSetting bait in val2.m_baits)
				{
					if (Object.op_Implicit((Object)(object)bait.m_bait) && !(bait.m_chance <= 0f))
					{
						string name = ((Object)bait.m_bait).name;
						hashSet.Add(name);
						if (dictionary.ContainsKey(name))
						{
							dictionary2.TryGetValue(name, out var value);
							dictionary2[name] = value + 1f + (num - num2) / num;
						}
					}
				}
			}
			string text = null;
			float num3 = 0f;
			foreach (KeyValuePair<string, float> item in dictionary2)
			{
				if (item.Value > num3)
				{
					num3 = item.Value;
					text = item.Key;
				}
			}
			string value2 = null;
			if (text == null)
			{
				Biome currentBiome = player.GetCurrentBiome();
				float num4 = 0f;
				foreach (Fish item2 in RegionFish(currentBiome))
				{
					foreach (BaitSetting bait2 in item2.m_baits)
					{
						if (Object.op_Implicit((Object)(object)bait2.m_bait) && !(bait2.m_chance <= 0f))
						{
							hashSet.Add(((Object)bait2.m_bait).name);
							if (dictionary.ContainsKey(((Object)bait2.m_bait).name) && bait2.m_chance > num4)
							{
								num4 = bait2.m_chance;
								text = ((Object)bait2.m_bait).name;
							}
						}
					}
				}
				if (text == null && BiomeBait.TryGetValue(currentBiome, out value2) && dictionary.ContainsKey(value2))
				{
					text = value2;
				}
			}
			if (text == null)
			{
				string text2 = ((hashSet.Count > 0) ? string.Join(", ", hashSet.Select(BaitDisplayName)) : ((value2 != null) ? BaitDisplayName(value2) : null));
				if (text2 != null && text2 != _lastMissingBaitMsg)
				{
					_lastMissingBaitMsg = text2;
					((Character)player).Message((MessageType)2, "You need " + text2 + " to fish here", 0, (Sprite)null, false);
				}
				return;
			}
			_lastMissingBaitMsg = null;
			ItemData val3 = dictionary[text];
			if (((Humanoid)player).GetAmmoItem() != val3)
			{
				((Humanoid)player).EquipItem(val3, true);
				((Character)player).Message((MessageType)1, "Bait: " + Localization.instance.Localize(val3.m_shared.m_name), 0, (Sprite)null, false);
			}
		}

		private static string BaitDisplayName(string prefabName)
		{
			GameObject val = (Object.op_Implicit((Object)(object)ZNetScene.instance) ? ZNetScene.instance.GetPrefab(prefabName) : null);
			ItemDrop val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<ItemDrop>() : null);
			return Localization.instance.Localize(Object.op_Implicit((Object)(object)val2) ? val2.m_itemData.m_shared.m_name : prefabName);
		}

		internal static void TryHookNearest(FishingFloat ff)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			FloatState floatState = StateOf(ff);
			if (!ff.IsInWater() || Time.time < floatState.NextScan)
			{
				return;
			}
			floatState.NextScan = Time.time + 0.5f;
			string bait = ff.GetBait();
			if (string.IsNullOrEmpty(bait))
			{
				return;
			}
			Vector3 position = ((Component)ff).transform.position;
			float value = Plugin.HookRange.Value;
			Fish val = null;
			float num = float.MaxValue;
			bool flag = false;
			foreach (IMonoUpdater instance in Fish.Instances)
			{
				Fish val2 = (Fish)(object)((instance is Fish) ? instance : null);
				if (val2 == null || !Object.op_Implicit((Object)(object)val2) || val2.IsHooked() || !val2.m_nview.IsValid())
				{
					continue;
				}
				Vector3 position2 = ((Component)val2).transform.position;
				if (val2.m_inWater <= -10000f || val2.m_inWater < position2.y + val2.m_height)
				{
					continue;
				}
				float num2 = Vector3.Distance(position2, position);
				if (!(num2 > value) && !((Object)(object)FishingFloat.FindFloat(val2) != (Object)null))
				{
					flag = true;
					if (TakesBait(val2, bait) && !(num2 >= num))
					{
						val = val2;
						num = num2;
					}
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				_scanResult = ((!flag) ? ScanResult.NoFish : ScanResult.WrongBait);
				if (floatState.WaterSince < 0f)
				{
					floatState.WaterSince = Time.time;
				}
				if (!Plugin.SpawnFishIfNone.Value || Time.time - floatState.WaterSince < Plugin.SpawnDelay.Value)
				{
					return;
				}
				Player localPlayer = Player.m_localPlayer;
				val = SpawnFishFor(bait, position, (Biome)(Object.op_Implicit((Object)(object)localPlayer) ? ((int)localPlayer.GetCurrentBiome()) : 0));
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
			}
			_scanResult = ScanResult.None;
			ff.m_nibbler = null;
			ff.SetCatch(val);
			ff.Message("$msg_fishing_hooked", true);
			Game.instance.IncrementPlayerStat((PlayerStatType)158, 1f, false);
		}

		private static List<Fish> RegionFish(Biome biome)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			if (_regionFish.TryGetValue(biome, out var value))
			{
				return value;
			}
			List<Fish> list = new List<Fish>();
			foreach (SpawnSystem instance in SpawnSystem.m_instances)
			{
				if (!Object.op_Implicit((Object)(object)instance))
				{
					continue;
				}
				foreach (SpawnSystemList spawnList in instance.m_spawnLists)
				{
					if (!Object.op_Implicit((Object)(object)spawnList))
					{
						continue;
					}
					foreach (SpawnData spawner in spawnList.m_spawners)
					{
						if (spawner != null && spawner.m_enabled && Object.op_Implicit((Object)(object)spawner.m_prefab) && (spawner.m_biome & biome) != 0)
						{
							Fish component = spawner.m_prefab.GetComponent<Fish>();
							if (Object.op_Implicit((Object)(object)component) && !list.Contains(component))
							{
								list.Add(component);
							}
						}
					}
				}
				break;
			}
			if (list.Count > 0)
			{
				_regionFish[biome] = list;
			}
			return list;
		}

		private static Fish SpawnFishFor(string bait, Vector3 floatPos, Biome biome)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: 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_01e9: Unknown result type (might be due to invalid IL or missing references)
			List<KeyValuePair<GameObject, float>> list = new List<KeyValuePair<GameObject, float>>();
			List<Fish> list2 = RegionFish(biome);
			foreach (Fish item in list2)
			{
				foreach (BaitSetting bait2 in item.m_baits)
				{
					if (Object.op_Implicit((Object)(object)bait2.m_bait) && ((Object)bait2.m_bait).name == bait && bait2.m_chance > 0f)
					{
						list.Add(new KeyValuePair<GameObject, float>(((Component)item).gameObject, bait2.m_chance));
					}
				}
			}
			if (list.Count == 0)
			{
				foreach (Fish item2 in list2)
				{
					list.Add(new KeyValuePair<GameObject, float>(((Component)item2).gameObject, 1f));
				}
			}
			if (list.Count == 0)
			{
				return null;
			}
			float num = 0f;
			foreach (KeyValuePair<GameObject, float> item3 in list)
			{
				num += item3.Value;
			}
			float num2 = Random.value * num;
			GameObject key = list[list.Count - 1].Key;
			foreach (KeyValuePair<GameObject, float> item4 in list)
			{
				num2 -= item4.Value;
				if (num2 <= 0f)
				{
					key = item4.Key;
					break;
				}
			}
			Vector3 val = floatPos + Vector3.down * 1f;
			return Object.Instantiate<GameObject>(key, val, Quaternion.Euler(0f, Random.Range(0f, 360f), 0f)).GetComponent<Fish>();
		}

		private static bool TakesBait(Fish fish, string bait)
		{
			foreach (BaitSetting bait2 in fish.m_baits)
			{
				if (Object.op_Implicit((Object)(object)bait2.m_bait) && ((Object)bait2.m_bait).name == bait && bait2.m_chance > 0f)
				{
					return true;
				}
			}
			return false;
		}

		private static string BaitName(FishingFloat ff)
		{
			return BaitDisplayName(ff.GetBait());
		}

		internal static ItemData GetRod(Player player)
		{
			ItemData rightItem = ((Humanoid)player).GetRightItem();
			if (IsRod(rightItem))
			{
				return rightItem;
			}
			rightItem = ((Humanoid)player).GetLeftItem();
			if (!IsRod(rightItem))
			{
				return null;
			}
			return rightItem;
		}

		private static bool IsRod(ItemData item)
		{
			if (item?.m_shared == null)
			{
				return false;
			}
			GameObject val = item.m_shared.m_attack?.m_attackProjectile;
			if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.GetComponent<FishingFloat>()))
			{
				return true;
			}
			string ammoType = item.m_shared.m_ammoType;
			if (!string.IsNullOrEmpty(ammoType) && ammoType.ToLowerInvariant().Contains("fishingbait"))
			{
				return true;
			}
			if (Object.op_Implicit((Object)(object)item.m_dropPrefab))
			{
				return ((Object)item.m_dropPrefab).name.StartsWith("FishingRod");
			}
			return false;
		}

		private static bool TypingOrInMenu()
		{
			if ((!Object.op_Implicit((Object)(object)Chat.instance) || !Chat.instance.HasFocus()) && !Console.IsVisible() && !TextInput.IsVisible() && !Menu.IsVisible() && !InventoryGui.IsVisible())
			{
				return Minimap.IsOpen();
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(FishingFloat), "FixedUpdate")]
	internal static class FishingFloat_FixedUpdate
	{
		internal static bool ForceReel;

		private static void Prefix(FishingFloat __instance)
		{
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			ForceReel = false;
			if (!AutoFisher.Active || !__instance.m_nview.IsValid() || !__instance.m_nview.IsOwner())
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)__instance.GetOwner() != (Object)(object)localPlayer)
			{
				return;
			}
			if ((Object)(object)__instance.GetCatch() == (Object)null)
			{
				__instance.TryToHook();
				if ((Object)(object)__instance.GetCatch() == (Object)null)
				{
					AutoFisher.TryHookNearest(__instance);
				}
			}
			if ((Object)(object)__instance.GetCatch() == (Object)null)
			{
				return;
			}
			ForceReel = true;
			__instance.m_maxDistance = Mathf.Max(__instance.m_maxDistance, 40f + Plugin.HookRange.Value * 2f);
			Transform rodTop = __instance.GetRodTop((Character)(object)localPlayer);
			if ((Object)(object)rodTop != (Object)null)
			{
				float num = Vector3.Distance(rodTop.position, ((Component)__instance).transform.position);
				float num2 = Mathf.Max(0.5f, __instance.m_breakDistance - 1.5f);
				if (num - __instance.m_lineLength > num2)
				{
					__instance.m_lineLength = num - num2;
				}
			}
		}

		private static void Finalizer()
		{
			ForceReel = false;
		}
	}
	[HarmonyPatch(typeof(Attack), "FireProjectileBurst")]
	internal static class Attack_FireProjectileBurst
	{
		private static void Postfix(Attack __instance)
		{
			AutoFisher.CastExtraLines(__instance);
		}
	}
	[HarmonyPatch(typeof(FishingFloat), "Setup")]
	internal static class FishingFloat_Setup
	{
		internal static bool InSetup;

		private static void Prefix()
		{
			InSetup = true;
		}

		private static void Finalizer()
		{
			InSetup = false;
		}
	}
	[HarmonyPatch(typeof(FishingFloat), "FindFloat", new Type[] { typeof(Character) })]
	internal static class FishingFloat_FindFloat
	{
		private static bool Prefix(ref FishingFloat __result)
		{
			if (!FishingFloat_Setup.InSetup || !AutoFisher.Active || Plugin.LineCount.Value <= 1)
			{
				return true;
			}
			__result = null;
			return false;
		}
	}
	[HarmonyPatch(typeof(Humanoid), "IsBlocking")]
	internal static class Humanoid_IsBlocking
	{
		private static void Postfix(Humanoid __instance, ref bool __result)
		{
			if (FishingFloat_FixedUpdate.ForceReel && (Object)(object)__instance == (Object)(object)Player.m_localPlayer)
			{
				__result = true;
			}
		}
	}
	[HarmonyPatch(typeof(Fish), "Escape")]
	internal static class Fish_Escape
	{
		private static bool Prefix(Fish __instance)
		{
			if (!AutoFisher.Active)
			{
				return true;
			}
			__instance.m_escapeTime = 0f;
			return false;
		}
	}
	[HarmonyPatch(typeof(Player), "UseStamina")]
	internal static class Player_UseStamina
	{
		private static bool Prefix(Player __instance)
		{
			if (Plugin.NoStamina.Value && AutoFisher.FishingNow)
			{
				return !((Object)(object)__instance == (Object)(object)Player.m_localPlayer);
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(Player), "HaveStamina")]
	internal static class Player_HaveStamina
	{
		private static bool Prefix(Player __instance, ref bool __result)
		{
			if (Plugin.NoStamina.Value && AutoFisher.FishingNow && (Object)(object)__instance == (Object)(object)Player.m_localPlayer)
			{
				__result = true;
				return false;
			}
			return true;
		}
	}
	[BepInPlugin("supermans.afkfishing", "Supermans AFK Fishing", "1.0.8")]
	public class Plugin : BaseUnityPlugin
	{
		public const string Guid = "supermans.afkfishing";

		public const string Name = "Supermans AFK Fishing";

		public const string Version = "1.0.8";

		internal static ManualLogSource Log;

		internal static ConfigEntry<bool> ModEnabled;

		internal static ConfigEntry<KeyboardShortcut> ToggleKey;

		internal static ConfigEntry<bool> NoStamina;

		internal static ConfigEntry<bool> NoDurability;

		internal static ConfigEntry<float> RecastSeconds;

		internal static ConfigEntry<float> CastDelay;

		internal static ConfigEntry<float> HookRange;

		internal static ConfigEntry<bool> AutoSelectBait;

		internal static ConfigEntry<bool> SpawnFishIfNone;

		internal static ConfigEntry<float> SpawnDelay;

		internal static ConfigEntry<int> LineCount;

		private Harmony _harmony;

		private FileSystemWatcher _configWatcher;

		private volatile bool _configChanged;

		private float _configReloadAt = -1f;

		private void Awake()
		{
			//IL_004b: 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_00d7: Expected O, but got Unknown
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Expected O, but got Unknown
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Expected O, but got Unknown
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Expected O, but got Unknown
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Expected O, but got Unknown
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			ModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "Enabled", true, "Master switch for the whole mod.");
			ToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("1 - General", "ToggleKey", new KeyboardShortcut((KeyCode)108, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), "Starts/stops auto fishing while the fishing rod is in your hand.");
			NoStamina = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Cheats", "NoStamina", true, "Fishing (casting, holding a fish, reeling) never uses stamina.");
			NoDurability = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Cheats", "NoDurability", true, "The fishing rod in your hand never loses durability.");
			RecastSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("3 - Auto fishing", "RecastSeconds", 60f, new ConfigDescription("Reel in and cast again if nothing bites for this many seconds.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 600f), Array.Empty<object>()));
			HookRange = ((BaseUnityPlugin)this).Config.Bind<float>("3 - Auto fishing", "HookRange", 20f, new ConfigDescription("Meters around the float searched for a fish that takes your bait; the nearest one is hooked.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 50f), Array.Empty<object>()));
			CastDelay = ((BaseUnityPlugin)this).Config.Bind<float>("3 - Auto fishing", "CastDelay", 1.5f, new ConfigDescription("Seconds to wait after a catch before casting again.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 10f), Array.Empty<object>()));
			AutoSelectBait = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Auto fishing", "AutoSelectBait", true, "Before every cast, equip the bait from your inventory that the fish in front of you take (falls back to the biome's bait).");
			SpawnFishIfNone = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Auto fishing", "SpawnFishIfNone", true, "Always catch something: if no fish that takes your bait is near the float, one is brought to the hook after SpawnDelay seconds.");
			SpawnDelay = ((BaseUnityPlugin)this).Config.Bind<float>("3 - Auto fishing", "SpawnDelay", 3f, new ConfigDescription("Seconds the float sits in the water, with no suitable fish nearby, before a fish is brought to the hook.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 60f), Array.Empty<object>()));
			LineCount = ((BaseUnityPlugin)this).Config.Bind<int>("3 - Auto fishing", "LineCount", 10, new ConfigDescription("Lines cast at once, fanned out in front of you; each one catches its own fish. Each line uses one bait and needs a free inventory slot.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10), Array.Empty<object>()));
			WatchConfigFile();
			_harmony = new Harmony("supermans.afkfishing");
			_harmony.PatchAll(typeof(Plugin).Assembly);
			Log.LogInfo((object)"Supermans AFK Fishing 1.0.8 loaded");
		}

		private void Update()
		{
			if (_configChanged)
			{
				_configChanged = false;
				_configReloadAt = Time.unscaledTime + 0.5f;
			}
			if (_configReloadAt >= 0f && Time.unscaledTime >= _configReloadAt)
			{
				_configReloadAt = -1f;
				try
				{
					((BaseUnityPlugin)this).Config.Reload();
					Log.LogInfo((object)"Config reloaded from file");
				}
				catch (Exception ex)
				{
					Log.LogWarning((object)("Config reload failed: " + ex.Message));
				}
			}
			AutoFisher.Update();
		}

		private void WatchConfigFile()
		{
			try
			{
				_configWatcher = new FileSystemWatcher(Path.GetDirectoryName(((BaseUnityPlugin)this).Config.ConfigFilePath), Path.GetFileName(((BaseUnityPlugin)this).Config.ConfigFilePath));
				_configWatcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.LastWrite;
				_configWatcher.Changed += OnConfigFileChanged;
				_configWatcher.Created += OnConfigFileChanged;
				_configWatcher.Renamed += OnConfigFileChanged;
				_configWatcher.EnableRaisingEvents = true;
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("Can't watch the config file, edits apply after a restart: " + ex.Message));
			}
		}

		private void OnConfigFileChanged(object sender, FileSystemEventArgs e)
		{
			_configChanged = true;
		}

		private void OnDestroy()
		{
			_configWatcher?.Dispose();
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}