Decompiled source of SeagullFishing v1.2.0

BepInEx\plugins\SeagullFishing\SeagullFishing.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using FishNet;
using FishNet.Connection;
using FishNet.Managing;
using FishNet.Managing.Object;
using FishNet.Object;
using HarmonyLib;
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("SeagullFishing")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("钓海鸥")]
[assembly: AssemblyFileVersion("1.2.0.0")]
[assembly: AssemblyInformationalVersion("1.2.0")]
[assembly: AssemblyProduct("SeagullFishing")]
[assembly: AssemblyTitle("SeagullFishing")]
[assembly: AssemblyVersion("1.2.0.0")]
namespace SeagullFishing;

[HarmonyPatch(typeof(CreatureManager), "HookItem")]
internal static class Patch_CreatureManager_HookItem
{
	private static bool Prefix(CreatureManager __instance, Item itemPrefab, Bait bait)
	{
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if (!Plugin.Enabled.Value)
			{
				return true;
			}
			Creature val = (((Object)(object)itemPrefab != (Object)null) ? itemPrefab.Creature : null);
			if ((Object)(object)val != (Object)null && (int)val.BossType != 0)
			{
				return true;
			}
			if (Random.value < Plugin.DynamiteChance.Value)
			{
				Item dynamitePrefab = SeagullLogic.GetDynamitePrefab();
				if ((Object)(object)dynamitePrefab != (Object)null)
				{
					SeagullLogic.HookDynamite(__instance, dynamitePrefab, bait);
					return false;
				}
				Plugin.LogWarn("Dynamite prefab not found; falling through to the seagull roll");
			}
			if (Random.value < Plugin.CatchChance.Value)
			{
				Item seagullPrefab = SeagullLogic.GetSeagullPrefab();
				if ((Object)(object)seagullPrefab != (Object)null)
				{
					SeagullLogic.HookSeagull(__instance, seagullPrefab, bait);
					return false;
				}
				Plugin.LogWarn("Seagull prefab not found; this catch falls back to a normal fish");
			}
			return true;
		}
		catch (Exception ex)
		{
			Plugin.LogWarn("HookItem Prefix error: " + ex.Message);
			return true;
		}
	}
}
[HarmonyPatch(typeof(BirdManager), "SimulateBird")]
internal static class Patch_BirdManager_SimulateBird
{
	private static bool Prefix(Bird bird)
	{
		try
		{
			if (Plugin.Enabled.Value && SeagullLogic.TrySprint(bird))
			{
				return false;
			}
		}
		catch (Exception ex)
		{
			Plugin.LogWarn("SimulateBird Prefix error: " + ex.Message);
		}
		return true;
	}
}
[HarmonyPatch(typeof(Bird), "SetAttackingFood")]
internal static class Patch_Bird_SetAttackingFood
{
	private static bool Prefix(Bird __instance, Item item)
	{
		try
		{
			if (Plugin.Enabled.Value && (Object)(object)item != (Object)null && SeagullLogic.IsModSeagull(__instance))
			{
				return false;
			}
		}
		catch (Exception ex)
		{
			Plugin.LogWarn("SetAttackingFood Prefix error: " + ex.Message);
		}
		return true;
	}
}
[HarmonyPatch(typeof(Bird), "OnStopClient")]
internal static class Patch_Bird_OnStopClient
{
	private static void Postfix(Bird __instance)
	{
		try
		{
			if (Plugin.Enabled.Value)
			{
				SeagullLogic.RemoveModSeagull(__instance);
			}
		}
		catch (Exception ex)
		{
			Plugin.LogWarn("Bird.OnStopClient Postfix error: " + ex.Message);
		}
	}
}
[HarmonyPatch(typeof(Item), "RemoveBaitJointOnItemReleased")]
internal static class Patch_Item_RemoveBaitJointOnItemReleased
{
	private static void Postfix(Item __instance)
	{
		try
		{
			if (Plugin.Enabled.Value)
			{
				Bird val = (Bird)(object)((__instance is Bird) ? __instance : null);
				if (val != null && ((NetworkBehaviour)val).IsServerInitialized)
				{
					SeagullLogic.ReleaseSeagullToSky(val);
				}
			}
		}
		catch (Exception ex)
		{
			Plugin.LogWarn("RemoveBaitJointOnItemReleased Postfix error: " + ex.Message);
		}
	}
}
[HarmonyPatch(typeof(Explosive), "ServerExplode")]
internal static class Patch_Explosive_ServerExplode
{
	private static void Prefix(Explosive __instance)
	{
		try
		{
			if (Plugin.Enabled.Value)
			{
				SeagullLogic.CleanupExplodedDynamite(__instance);
			}
		}
		catch (Exception ex)
		{
			Plugin.LogWarn("ServerExplode Prefix error: " + ex.Message);
		}
	}
}
[BepInPlugin("com.yw.seagullfishing", "Seagull Fishing", "1.2.0")]
public class Plugin : BaseUnityPlugin
{
	internal static ManualLogSource Log;

	internal static ConfigEntry<bool> Enabled;

	internal static ConfigEntry<float> CatchChance;

	internal static ConfigEntry<float> DynamiteChance;

	internal static ConfigEntry<float> DynamiteFuse;

	internal static ConfigEntry<float> SeagullFlyHeight;

	internal static void LogInfo(string msg)
	{
		try
		{
			Log.LogInfo((object)msg);
		}
		catch
		{
		}
	}

	internal static void LogWarn(string msg)
	{
		try
		{
			Log.LogWarning((object)msg);
		}
		catch
		{
		}
	}

	private void Awake()
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Expected O, but got Unknown
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		Log = ((BaseUnityPlugin)this).Logger;
		InitConfig();
		Harmony val = new Harmony("com.yw.seagullfishing");
		int num = 0;
		int num2 = 0;
		Type[] types = typeof(Plugin).Assembly.GetTypes();
		foreach (Type type in types)
		{
			if (type.GetCustomAttributes(typeof(HarmonyPatch), inherit: false).Length != 0)
			{
				try
				{
					new PatchClassProcessor(val, type).Patch();
					num++;
				}
				catch (Exception ex)
				{
					num2++;
					LogWarn("Patch apply failed: " + type.Name + " => " + ex.GetType().Name + ": " + ex.Message);
				}
			}
		}
		LogInfo("Harmony patches applied (ok " + num + ", failed " + num2 + ")");
		LogInfo("Seagull Fishing loaded! (cfg: " + Paths.ConfigPath + ")");
	}

	private void InitConfig()
	{
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Expected O, but got Unknown
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Expected O, but got Unknown
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: Expected O, but got Unknown
		//IL_0105: Unknown result type (might be due to invalid IL or missing references)
		//IL_010f: Expected O, but got Unknown
		Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "总开关(Master switch;关闭后钓鱼行为与原版完全一致)");
		CatchChance = ((BaseUnityPlugin)this).Config.Bind<float>("General", "CatchChance", 0.15f, new ConfigDescription("咬钩替换为海鸥的概率,0-1(Chance to catch a seagull instead of a fish, 0-1;默认 0.15 = 15%)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
		DynamiteChance = ((BaseUnityPlugin)this).Config.Bind<float>("General", "DynamiteChance", 0.05f, new ConfigDescription("咬钩替换为点燃炸药的概率,0-1(Chance to hook a lit dynamite instead of a fish, 0-1;默认 0.05 = 5%)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
		DynamiteFuse = ((BaseUnityPlugin)this).Config.Bind<float>("General", "DynamiteFuse", 10f, new ConfigDescription("钓上的炸药引信时长,秒(Fuse duration of hooked dynamite in seconds;默认 10)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 30f), Array.Empty<object>()));
		SeagullFlyHeight = ((BaseUnityPlugin)this).Config.Bind<float>("General", "SeagullFlyHeight", 50f, new ConfigDescription("海鸥脱钩后向上飞行的天空高度,米(相对释放点/水面;Sky height a released seagull flies up to, in meters above the release point/water;默认 50)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 100f), Array.Empty<object>()));
	}
}
internal static class SeagullLogic
{
	private static Item _cachedSeagull;

	private static Item _cachedDynamite;

	private static float _lastSeagullFail;

	private static float _lastDynamiteFail;

	private const float RetryCooldown = 5f;

	private static readonly HashSet<Bird> ModSeagulls = new HashSet<Bird>();

	public const float SeagullSprintSpeed = 60f;

	private static readonly HashSet<Bird> SprintingSeagulls = new HashSet<Bird>();

	private static readonly FieldInfo ExplosiveActivatedDelayField = AccessTools.Field(typeof(Explosive), "_activatedExplosionDelay");

	private static readonly PropertyInfo FlyHeigthProperty = AccessTools.Property(typeof(Bird), "FlyHeigth");

	private static readonly MethodInfo FlyHeigthSetter = ((FlyHeigthProperty != null) ? FlyHeigthProperty.GetSetMethod(nonPublic: true) : null);

	private static readonly FieldInfo FlyHeigthBackingField = AccessTools.Field(typeof(Bird), "<FlyHeigth>k__BackingField");

	public static bool IsModSeagull(Bird bird)
	{
		if ((Object)(object)bird != (Object)null)
		{
			return ModSeagulls.Contains(bird);
		}
		return false;
	}

	public static void RemoveModSeagull(Bird bird)
	{
		if ((Object)(object)bird != (Object)null)
		{
			ModSeagulls.Remove(bird);
			SprintingSeagulls.Remove(bird);
		}
	}

	public static bool TrySprint(Bird bird)
	{
		//IL_0031: 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_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: 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)
		try
		{
			if ((Object)(object)bird == (Object)null || !SprintingSeagulls.Contains(bird))
			{
				return false;
			}
			if (((Creature)bird)._hp.Value <= 0 || ((Component)bird).transform.position.y >= bird.FlyHeigth)
			{
				SprintingSeagulls.Remove(bird);
				ModSeagulls.Remove(bird);
				return true;
			}
			Transform transform = ((Component)bird).transform;
			transform.position += Vector3.up * (60f * Time.deltaTime);
			bird.SetAnimState((byte)4);
			((Component)bird).transform.rotation = Quaternion.FromToRotation(((Component)bird).transform.forward, Vector3.up) * ((Component)bird).transform.rotation;
			return true;
		}
		catch (Exception ex)
		{
			Plugin.LogWarn("TrySprint error: " + ex.Message);
			return false;
		}
	}

	public static Item GetSeagullPrefab()
	{
		return GetPrefab<Bird>(ref _cachedSeagull, ref _lastSeagullFail, "Seagull");
	}

	public static Item GetDynamitePrefab()
	{
		return GetPrefab<Explosive>(ref _cachedDynamite, ref _lastDynamiteFail, "Dynamite");
	}

	private static Item GetPrefab<T>(ref Item cache, ref float lastFail, string name) where T : Component
	{
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if ((Object)(object)cache != (Object)null)
			{
				return cache;
			}
			if (Time.time - lastFail < 5f)
			{
				return null;
			}
			T[] array = Resources.FindObjectsOfTypeAll<T>();
			T val = default(T);
			int num = 0;
			T[] array2 = array;
			foreach (T val2 in array2)
			{
				if ((Object)(object)val2 == (Object)null || (Object)(object)((Component)val2).gameObject == (Object)null)
				{
					continue;
				}
				Scene scene = ((Component)val2).gameObject.scene;
				if (((Scene)(ref scene)).IsValid())
				{
					continue;
				}
				num++;
				if ((Object)(object)val == (Object)null)
				{
					val = val2;
				}
				if (((Object)((Component)val2).gameObject).name == name)
				{
					Item component = ((Component)val2).GetComponent<Item>();
					if ((Object)(object)component != (Object)null)
					{
						Cache(ref cache, component, name);
						return component;
					}
				}
			}
			if (num == 1 && (Object)(object)val != (Object)null)
			{
				Item component2 = ((Component)val).GetComponent<Item>();
				if ((Object)(object)component2 != (Object)null)
				{
					Cache(ref cache, component2, name);
					return component2;
				}
			}
			Item val3 = TryGetFromSpawnablePrefabs(name);
			if ((Object)(object)val3 != (Object)null)
			{
				Cache(ref cache, val3, name);
				return val3;
			}
			lastFail = Time.time;
			return null;
		}
		catch (Exception ex)
		{
			Plugin.LogWarn("GetPrefab(" + name + ") error: " + ex.Message);
			lastFail = Time.time;
			return null;
		}
	}

	private static void Cache(ref Item cache, Item prefab, string name)
	{
		cache = prefab;
		TryEnsureRegistered(prefab, name);
		Plugin.LogInfo(name + " prefab cached: " + ((Object)((Component)prefab).gameObject).name);
	}

	private static Item TryGetFromSpawnablePrefabs(string name)
	{
		try
		{
			NetworkManager networkManager = InstanceFinder.NetworkManager;
			if ((Object)(object)networkManager == (Object)null)
			{
				return null;
			}
			PrefabObjects spawnablePrefabs = networkManager.SpawnablePrefabs;
			if ((Object)(object)spawnablePrefabs == (Object)null)
			{
				return null;
			}
			Type type = ((object)spawnablePrefabs).GetType();
			MethodInfo method = type.GetMethod("GetObjectMatches", new Type[2]
			{
				typeof(bool),
				typeof(string)
			});
			object obj = null;
			if (method != null)
			{
				obj = method.Invoke(spawnablePrefabs, new object[2] { false, name });
			}
			else
			{
				method = type.GetMethod("GetObjectMatches", new Type[1] { typeof(string) });
				if (method != null)
				{
					obj = method.Invoke(spawnablePrefabs, new object[1] { name });
				}
			}
			if (obj is IEnumerable enumerable)
			{
				foreach (object item in enumerable)
				{
					GameObject val = (GameObject)((item is GameObject) ? item : null);
					if (val != null && (Object)(object)val != (Object)null)
					{
						Item component = val.GetComponent<Item>();
						if ((Object)(object)component != (Object)null)
						{
							return component;
						}
					}
				}
			}
			return null;
		}
		catch
		{
			return null;
		}
	}

	private static void TryEnsureRegistered(Item prefab, string name)
	{
		try
		{
			NetworkManager networkManager = InstanceFinder.NetworkManager;
			if ((Object)(object)networkManager == (Object)null)
			{
				return;
			}
			PrefabObjects spawnablePrefabs = networkManager.SpawnablePrefabs;
			if ((Object)(object)spawnablePrefabs == (Object)null)
			{
				return;
			}
			Type type = ((object)spawnablePrefabs).GetType();
			MethodInfo method = type.GetMethod("Contains", new Type[1] { typeof(GameObject) });
			if (!(method != null) || !(bool)method.Invoke(spawnablePrefabs, new object[1] { ((Component)prefab).gameObject }))
			{
				MethodInfo method2 = type.GetMethod("Add", new Type[1] { typeof(GameObject) });
				if (method2 != null)
				{
					method2.Invoke(spawnablePrefabs, new object[1] { ((Component)prefab).gameObject });
					Plugin.LogInfo(name + " prefab registered to FishNet spawnables");
				}
			}
		}
		catch (Exception ex)
		{
			Plugin.LogWarn("TryEnsureRegistered error: " + ex.Message);
		}
	}

	public static void HookSeagull(CreatureManager manager, Item prefab, Bait bait)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: 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_006e: 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_00a6: 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)
		try
		{
			Vector3 position = ((Component)bait).transform.position;
			position.y = WaterManager.WaterHeight + Random.Range(3f, 6f);
			Item val = Object.Instantiate<Item>(prefab, position, Quaternion.identity);
			val.SetAttachedRod(bait.FishingRod);
			bait.AddItemOnBait(val, true);
			val.RigidbodySync.ServerSetSyncedSimulator(((NetworkBehaviour)((Item)bait.FishingRod).Holder).Owner);
			((NetworkBehaviour)manager).Spawn(((Component)val).gameObject, (NetworkConnection)null, default(Scene));
			Creature creature = val.Creature;
			Bird val2 = (Bird)(object)((creature is Bird) ? creature : null);
			if ((Object)(object)val2 != (Object)null)
			{
				ModSeagulls.Add(val2);
			}
			Plugin.LogInfo("Seagull hooked! (bait at " + ((object)((Component)bait).transform.position/*cast due to .constrained prefix*/).ToString() + ")");
		}
		catch (Exception ex)
		{
			Plugin.LogWarn("HookSeagull error: " + ex.Message);
		}
	}

	public static void ReleaseSeagullToSky(Bird bird)
	{
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0062: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if (!((Object)(object)bird == (Object)null) && ((Creature)bird)._hp.Value > 0)
			{
				if (((Component)bird).transform.position.y < WaterManager.WaterHeight + 0.5f)
				{
					Vector3 position = ((Component)bird).transform.position;
					position.y = WaterManager.WaterHeight + 0.5f;
					((Component)bird).transform.position = position;
				}
				float num = Mathf.Max(((Component)bird).transform.position.y, WaterManager.WaterHeight) + Plugin.SeagullFlyHeight.Value;
				if (FlyHeigthSetter != null)
				{
					FlyHeigthSetter.Invoke(bird, new object[1] { num });
				}
				else if (FlyHeigthBackingField != null)
				{
					FlyHeigthBackingField.SetValue(bird, num);
				}
				if ((Object)(object)BirdManager.Instance != (Object)null)
				{
					BirdManager.Instance.AddFlyingBird(bird);
				}
				((Item)bird).RigidbodySync.Freeze(true, false);
				SprintingSeagulls.Add(bird);
				Plugin.LogInfo("Seagull escaped: sprinting up to " + num + "m");
			}
		}
		catch (Exception ex)
		{
			Plugin.LogWarn("ReleaseSeagullToSky error: " + ex.Message);
		}
	}

	public static void ReleaseFromRod(Item item)
	{
		try
		{
			if (!((Object)(object)item == (Object)null))
			{
				FishingRod attachedRod = item.AttachedRod;
				if (!((Object)(object)attachedRod == (Object)null) && !((Object)(object)attachedRod.Bait == (Object)null))
				{
					item.SetAttachedRod((FishingRod)null);
					attachedRod.Bait.AddItemOnBait((Item)null, true);
				}
			}
		}
		catch (Exception ex)
		{
			Plugin.LogWarn("ReleaseFromRod error: " + ex.Message);
		}
	}

	public static void CleanupExplodedDynamite(Explosive ex)
	{
		try
		{
			ReleaseFromRod((Item)(object)ex);
		}
		catch (Exception ex2)
		{
			Plugin.LogWarn("CleanupExplodedDynamite error: " + ex2.Message);
		}
	}

	public static void HookDynamite(CreatureManager manager, Item prefab, Bait bait)
	{
		//IL_0007: 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_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			Item val = Object.Instantiate<Item>(prefab, ((Component)bait).transform.position, Quaternion.identity);
			Explosive val2 = (Explosive)(object)((val is Explosive) ? val : null);
			if ((Object)(object)val2 == (Object)null)
			{
				Object.Destroy((Object)(object)((Component)val).gameObject);
				Plugin.LogWarn("Hooked prefab is not an Explosive; dynamite catch aborted");
				return;
			}
			float num = Mathf.Max(1f, Plugin.DynamiteFuse.Value);
			if (ExplosiveActivatedDelayField != null)
			{
				ExplosiveActivatedDelayField.SetValue(val2, num);
			}
			val.SetAttachedRod(bait.FishingRod);
			bait.AddItemOnBait(val, true);
			val.RigidbodySync.ServerSetSyncedSimulator(((NetworkBehaviour)((Item)bait.FishingRod).Holder).Owner);
			((NetworkBehaviour)manager).Spawn(((Component)val).gameObject, (NetworkConnection)null, default(Scene));
			val2.ObserverActivate(InstanceFinder.TimeManager.Tick, false, false, (Player)null);
			Plugin.LogInfo("Lit dynamite hooked! (fuse " + num + "s)");
		}
		catch (Exception ex)
		{
			Plugin.LogWarn("HookDynamite error: " + ex.Message);
		}
	}
}