Decompiled source of FishGatherer v0.5.1

HTFTest.dll

Decompiled a month 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 System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using FishNet.Object;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("HTFTest")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("HTFTest")]
[assembly: AssemblyTitle("HTFTest")]
[assembly: AssemblyVersion("1.0.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 HTFTest
{
	public enum GatherMode
	{
		All,
		FishOnly,
		ItemsOnly
	}
	[BepInPlugin("com.dan.htf.test", "HTF Test", "0.5.1")]
	public class Plugin : BaseUnityPlugin
	{
		private ConfigEntry<KeyCode> _key;

		private ConfigEntry<float> _distance;

		private ConfigEntry<GatherMode> _mode;

		private ConfigEntry<KeyCode> _cycleKey;

		private ConfigEntry<KeyCode> _sellKey;

		private ConfigEntry<bool> _netEnabled;

		private ConfigEntry<float> _netMargin;

		private ConfigEntry<float> _netMinSpeed;

		private ConfigEntry<KeyCode> _netToggleKey;

		private Boat _netBoat;

		private Bounds _netBounds;

		private readonly Dictionary<Item, float> _netPending = new Dictionary<Item, float>();

		private readonly HashSet<Item> _netDone = new HashSet<Item>();

		private int _netSlot;

		private string _toast = "";

		private float _toastUntil;

		private float _boatSpeed = -1f;

		private Transform _netFrame;

		private static readonly FieldInfo ReceivedOnBoat = typeof(RigidbodySync).GetField("_receivedOnBoat", BindingFlags.Instance | BindingFlags.NonPublic);

		private void Awake()
		{
			_key = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "GatherKey", (KeyCode)289, "Teleport all loose items in front of you");
			_distance = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Distance", 3f, "Meters in front of the player");
			_mode = ((BaseUnityPlugin)this).Config.Bind<GatherMode>("General", "Mode", GatherMode.All, "Only affects the GatherKey teleport: All, FishOnly (fish, dead ones included) or ItemsOnly (everything that is not a fish)");
			_cycleKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "CycleModeKey", (KeyCode)290, "Cycles the gather mode in-game");
			_sellKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "SellFishKey", (KeyCode)291, "Sell every loose dead fish and gull (host only)");
			_netEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("BoatNet", "Enabled", true, "Auto-collect loose items/fish near the boat while it's moving");
			_netMargin = ((BaseUnityPlugin)this).Config.Bind<float>("BoatNet", "Margin", 1.5f, "Extra meters around the boat's hitbox that count as 'in the net'");
			_netMinSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("BoatNet", "MinSpeed", 1f, "Boat must be moving at least this fast for the net to work");
			_netToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("BoatNet", "ToggleKey", (KeyCode)292, "Toggles the boat net on/off in-game");
			((BaseUnityPlugin)this).Logger.LogInfo((object)"HTF Test 0.5.1 loaded");
		}

		private void Update()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			if (Input.GetKeyDown(_cycleKey.Value))
			{
				_mode.Value = (GatherMode)((int)(_mode.Value + 1) % 3);
				Notify("Gather mode: " + _mode.Value);
			}
			if (Input.GetKeyDown(_sellKey.Value))
			{
				SellFish();
			}
			if (Input.GetKeyDown(_key.Value))
			{
				if ((Object)(object)Player.LocalPlayer != (Object)null)
				{
					Notify("Gathering (" + _mode.Value.ToString() + ")...");
					((MonoBehaviour)this).StartCoroutine(Gather());
				}
				else
				{
					Notify("Gather: no local player");
				}
			}
			if (Input.GetKeyDown(_netToggleKey.Value))
			{
				_netEnabled.Value = !_netEnabled.Value;
				Notify("Boat net: " + (_netEnabled.Value ? "ON" : "OFF"));
			}
			UpdateBoatNet();
		}

		private void Notify(string msg)
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)msg);
			_toast = msg;
			_toastUntil = Time.time + 4f;
		}

		private void OnGUI()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: 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)
			GUIStyle val = new GUIStyle(GUI.skin.label)
			{
				fontSize = 14,
				richText = true
			};
			string text = ((_boatSpeed < 0f) ? "no boat" : $"speed {_boatSpeed:F1}/{_netMinSpeed.Value:F1}, pending {_netPending.Count}");
			string text2 = $"<b>[F8]</b> gather: {_mode.Value} (F9 cycle)   <b>[F10]</b> sell\n" + "<b>[F11]</b> boat net: " + (_netEnabled.Value ? "<color=lime>ON</color>" : "<color=red>OFF</color>") + " (" + text + ")";
			if (Time.time < _toastUntil)
			{
				text2 = text2 + "\n<color=yellow>" + _toast + "</color>";
			}
			GUI.color = new Color(0f, 0f, 0f, 0.8f);
			GUI.Label(new Rect(11f, 11f, 600f, 80f), Regex.Replace(text2, "<.*?>", ""), val);
			GUI.color = Color.white;
			GUI.Label(new Rect(10f, 10f, 600f, 80f), text2, val);
		}

		private bool BuildBoatBounds(Boat boat)
		{
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: 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: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: 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_0106: 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_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: 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)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			BoatTrigger val = ((Component)boat).GetComponentInChildren<BoatTrigger>(true);
			if (!Object.op_Implicit((Object)(object)val))
			{
				val = Object.FindAnyObjectByType<BoatTrigger>();
			}
			List<Vector3> pts = new List<Vector3>();
			int count = 0;
			if (Object.op_Implicit((Object)(object)val))
			{
				_netFrame = ((Component)val).transform;
				Collider[] componentsInChildren = ((Component)val).GetComponentsInChildren<Collider>(true);
				foreach (Collider val2 in componentsInChildren)
				{
					BoxCollider val3 = (BoxCollider)(object)((val2 is BoxCollider) ? val2 : null);
					if (val3 != null)
					{
						AddBox(((Component)val2).transform, val3.center, val3.size * 0.5f);
					}
					else
					{
						AddWorld(val2.bounds);
					}
				}
			}
			if (count == 0)
			{
				_netFrame = boat.VisualBoat;
				MeshRenderer[] componentsInChildren2 = ((Component)boat.VisualBoat).GetComponentsInChildren<MeshRenderer>();
				for (int i = 0; i < componentsInChildren2.Length; i++)
				{
					AddWorld(((Renderer)componentsInChildren2[i]).bounds);
				}
			}
			bool flag = false;
			foreach (Vector3 item in pts)
			{
				Vector3 val4 = _netFrame.InverseTransformPoint(item);
				if (!flag)
				{
					_netBounds = new Bounds(val4, Vector3.zero);
					flag = true;
				}
				else
				{
					((Bounds)(ref _netBounds)).Encapsulate(val4);
				}
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("Boat net: frame {0} ({1}), {2} bounds", Object.op_Implicit((Object)(object)_netFrame) ? ((Object)_netFrame).name : "none", Object.op_Implicit((Object)(object)val) ? "BoatTrigger" : "renderers", count));
			return flag;
			void AddBox(Transform t, Vector3 center, Vector3 half)
			{
				//IL_001b: 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_0039: Unknown result type (might be due to invalid IL or missing references)
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0043: Unknown result type (might be due to invalid IL or missing references)
				//IL_0048: Unknown result type (might be due to invalid IL or missing references)
				count++;
				for (int j = 0; j < 8; j++)
				{
					pts.Add(t.TransformPoint(center + Vector3.Scale(half, new Vector3((float)((j & 1) * 2 - 1), (float)(((j >> 1) & 1) * 2 - 1), (float)(((j >> 2) & 1) * 2 - 1)))));
				}
			}
			void AddWorld(Bounds wb)
			{
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_0044: Unknown result type (might be due to invalid IL or missing references)
				//IL_0049: Unknown result type (might be due to invalid IL or missing references)
				//IL_004e: Unknown result type (might be due to invalid IL or missing references)
				count++;
				for (int j = 0; j < 8; j++)
				{
					pts.Add(((Bounds)(ref wb)).center + Vector3.Scale(((Bounds)(ref wb)).extents, new Vector3((float)((j & 1) * 2 - 1), (float)(((j >> 1) & 1) * 2 - 1), (float)(((j >> 2) & 1) * 2 - 1))));
				}
			}
		}

		private void UpdateBoatNet()
		{
			//IL_00e5: 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_00f5: 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_0110: 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_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_03aa: 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_03e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0400: Unknown result type (might be due to invalid IL or missing references)
			//IL_0405: Unknown result type (might be due to invalid IL or missing references)
			//IL_040e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0413: Unknown result type (might be due to invalid IL or missing references)
			//IL_045f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0461: Unknown result type (might be due to invalid IL or missing references)
			//IL_043b: Unknown result type (might be due to invalid IL or missing references)
			//IL_043d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0442: Unknown result type (might be due to invalid IL or missing references)
			//IL_0445: Unknown result type (might be due to invalid IL or missing references)
			//IL_044a: Unknown result type (might be due to invalid IL or missing references)
			//IL_044f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0451: Unknown result type (might be due to invalid IL or missing references)
			//IL_0456: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			if (!_netEnabled.Value)
			{
				return;
			}
			Boat boat = BoatManager.Boat;
			_boatSpeed = (Object.op_Implicit((Object)(object)boat) ? boat.VelocityMag : (-1f));
			if (!Object.op_Implicit((Object)(object)boat) || !Object.op_Implicit((Object)(object)boat.VisualBoat))
			{
				return;
			}
			if ((Object)(object)boat != (Object)(object)_netBoat)
			{
				_netPending.Clear();
				_netDone.Clear();
				if (!BuildBoatBounds(boat))
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)"Boat net: no volume found for the boat");
					return;
				}
				_netBoat = boat;
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"Boat net: bounds center {((Bounds)(ref _netBounds)).center} size {((Bounds)(ref _netBounds)).size}");
			}
			if (boat.VelocityMag >= _netMinSpeed.Value)
			{
				Transform netFrame = _netFrame;
				Bounds val = default(Bounds);
				((Bounds)(ref val))..ctor(((Bounds)(ref _netBounds)).center, ((Bounds)(ref _netBounds)).size + Vector3.one * (_netMargin.Value * 2f));
				foreach (Item value in ItemManager.Items.Values)
				{
					if (Object.op_Implicit((Object)(object)value) && _netDone.Contains(value))
					{
						if (!((Bounds)(ref val)).Contains(netFrame.InverseTransformPoint(((Component)value).transform.position)))
						{
							_netDone.Remove(value);
						}
					}
					else if (Object.op_Implicit((Object)(object)value) && !_netPending.ContainsKey(value) && (!Object.op_Implicit((Object)(object)value.Creature) || value.CanPickUp) && (!Object.op_Implicit((Object)(object)value.Bird) || ((Creature)value.Bird).IsDead) && !Object.op_Implicit((Object)(object)value.DeadPlayer) && !Object.op_Implicit((Object)(object)value.SyncedHolder) && !value.IsInInventory && !Object.op_Implicit((Object)(object)value.AttachedRod) && Object.op_Implicit((Object)(object)value.RigidbodySync) && !value.RigidbodySync.OnBoat && ((Bounds)(ref val)).Contains(netFrame.InverseTransformPoint(((Component)value).transform.position)))
					{
						if (!value.RigidbodySync.IsSimulatedLocal)
						{
							Server.Instance.SetSyncedSimulator(value, ((NetworkBehaviour)Server.Instance).Owner);
						}
						_netPending[value] = Time.time;
					}
				}
			}
			if (_netPending.Count == 0)
			{
				return;
			}
			Transform netFrame2 = _netFrame;
			Transform visualBoat = boat.VisualBoat;
			int num = 0;
			List<Item> list = null;
			foreach (KeyValuePair<Item, float> item in _netPending)
			{
				Item key = item.Key;
				if (Object.op_Implicit((Object)(object)key) && !key.RigidbodySync.IsSimulatedLocal && Time.time - item.Value < 3f)
				{
					continue;
				}
				(list ?? (list = new List<Item>())).Add(key);
				if (Object.op_Implicit((Object)(object)key) && key.RigidbodySync.IsSimulatedLocal)
				{
					if (num++ >= 8)
					{
						list.RemoveAt(list.Count - 1);
						break;
					}
					int num2 = _netSlot++;
					float num3 = (float)num2 * 0.618f % 1f - 0.5f;
					float num4 = (float)num2 * 0.414f % 1f - 0.5f;
					Vector3 val2 = netFrame2.TransformPoint(new Vector3(((Bounds)(ref _netBounds)).center.x + num3 * 1.2f, ((Bounds)(ref _netBounds)).min.y + 0.15f + (float)(num2 / 12 % 4) * 0.3f, ((Bounds)(ref _netBounds)).center.z + num4 * 4f));
					Quaternion val3 = ((Component)key).transform.rotation;
					if (ReceivedOnBoat != null && (bool)ReceivedOnBoat.GetValue(key.RigidbodySync))
					{
						val2 = visualBoat.InverseTransformPoint(val2);
						val3 = Quaternion.Inverse(visualBoat.rotation) * val3;
					}
					key.RigidbodySync.TeleportToPosRot(val2, val3, (float[])null, (Quaternion[])null);
					ZeroRigs(key);
					_netDone.Add(key);
					Notify("Boat net gathered " + ((Object)key).name);
				}
			}
			if (list == null)
			{
				return;
			}
			foreach (Item item2 in list)
			{
				_netPending.Remove(item2);
			}
		}

		private static void ZeroRigs(Item item)
		{
			//IL_0091: 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)
			Physics.SyncTransforms();
			List<Rigidbody> list = new List<Rigidbody> { item.Rig };
			if (item.RigidbodySync.ExtraHinges != null)
			{
				list.AddRange(item.RigidbodySync.ExtraHinges);
			}
			if (item.ExtraRigs != null)
			{
				ItemExtraRigidbody[] extraRigs = item.ExtraRigs;
				foreach (ItemExtraRigidbody val in extraRigs)
				{
					if (Object.op_Implicit((Object)(object)val))
					{
						list.Add(val.Rig);
					}
				}
			}
			foreach (Rigidbody item2 in list)
			{
				if (Object.op_Implicit((Object)(object)item2) && !item2.isKinematic)
				{
					item2.linearVelocity = Vector3.zero;
					item2.angularVelocity = Vector3.zero;
				}
			}
		}

		private void SellFish()
		{
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Invalid comparison between Unknown and I4
			if (!Object.op_Implicit((Object)(object)Server.Instance) || !((NetworkBehaviour)Server.Instance).IsServerInitialized)
			{
				Notify("Selling only works as host");
				return;
			}
			HashSet<Item> hashSet = new HashSet<Item>();
			List<Item> list = new List<Item>();
			foreach (Item value in ItemManager.Items.Values)
			{
				if (Object.op_Implicit((Object)(object)value) && hashSet.Add(value) && (((int)value.Type == 1 && Object.op_Implicit((Object)(object)value.Creature) && value.Creature.IsDead) || (Object.op_Implicit((Object)(object)value.Bird) && ((Creature)value.Bird).IsDead)) && !Object.op_Implicit((Object)(object)value.Holder) && !Object.op_Implicit((Object)(object)value.SyncedHolder) && !value.IsInInventory && !Object.op_Implicit((Object)(object)value.AttachedRod) && !((NetworkBehaviour)value).IsDeinitializing && !value.IsDestroying)
				{
					list.Add(value);
				}
			}
			int num = 0;
			foreach (Item item in list)
			{
				num += item.TotalWorth;
				MoneyManager.SellItem(item);
				item.DestroyItem((byte)0, byte.MaxValue);
			}
			Notify($"Sold {list.Count} fish/gulls for {num}");
		}

		private bool Matches(Item item)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			bool flag = (int)item.Type == 1;
			if (_mode.Value != GatherMode.All)
			{
				return _mode.Value == GatherMode.FishOnly == flag;
			}
			return true;
		}

		private IEnumerator Gather()
		{
			Transform transform = Player.LocalPlayer.Transform;
			Vector3 target = transform.position + transform.forward * _distance.Value + Vector3.up;
			List<Item> list = new List<Item>();
			HashSet<Item> seen = new HashSet<Item>();
			foreach (Item value in ItemManager.Items.Values)
			{
				if (Object.op_Implicit((Object)(object)value) && seen.Add(value) && (!Object.op_Implicit((Object)(object)value.Creature) || value.CanPickUp) && !Object.op_Implicit((Object)(object)value.Bird) && !Object.op_Implicit((Object)(object)value.DeadPlayer) && !Object.op_Implicit((Object)(object)value.SyncedHolder) && !value.IsInInventory && !Object.op_Implicit((Object)(object)value.AttachedRod) && Object.op_Implicit((Object)(object)value.RigidbodySync) && Matches(value))
				{
					list.Add(value);
				}
			}
			foreach (Item item in list)
			{
				if (!item.RigidbodySync.IsSimulatedLocal)
				{
					Server.Instance.SetSyncedSimulator(item, ((NetworkBehaviour)Server.Instance).Owner);
				}
			}
			float t = 0f;
			while (t < 4f && (t < 0.5f || list.Exists((Item i) => Object.op_Implicit((Object)(object)i) && !i.RigidbodySync.IsSimulatedLocal)))
			{
				t += Time.deltaTime;
				yield return null;
			}
			int num = 0;
			int num2 = 0;
			Vector3 val = default(Vector3);
			foreach (Item item2 in list)
			{
				if (Object.op_Implicit((Object)(object)item2) && item2.RigidbodySync.IsSimulatedLocal)
				{
					((Vector3)(ref val))..ctor(((float)(num % 8) - 3.5f) * 1.2f, (float)(num / 64) * 1.2f, ((float)(num / 8 % 8) - 3.5f) * 1.2f);
					item2.RigidbodySync.TeleportToPosRot(target + val, ((Component)item2).transform.rotation, (float[])null, (Quaternion[])null);
					ZeroRigs(item2);
					num++;
					num2++;
				}
			}
			Notify($"Gathered {num2}/{list.Count} items (registered {seen.Count}, not simulated locally {list.Count - num2})");
		}
	}
}