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);
}
}
}