Decompiled source of RunawayJoinButton v1.0.0

BepInEx/plugins/RunawayJoinButton/ZaboomafooW-RunawayJoinButton-v1.0.0.dll

Decompiled 4 hours ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using RunawayJoinButton.Controllers;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.UI;

[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("RunawayJoinButton")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+82336874e513993b46c860e1304e19d26b6a9ce1")]
[assembly: AssemblyProduct("RunawayJoinButton")]
[assembly: AssemblyTitle("RunawayJoinButton")]
[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 RunawayJoinButton
{
	[BepInPlugin("ZaboomafooW.RunawayJoinButton", "RunawayJoinButton", "1.0.0")]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "ZaboomafooW.RunawayJoinButton";

		public const string PluginName = "RunawayJoinButton";

		public const string PluginVersion = "1.0.0";

		private Harmony _harmony;

		internal static ManualLogSource ModLogger { get; private set; }

		private void Awake()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			ModLogger = ((BaseUnityPlugin)this).Logger;
			_harmony = new Harmony("ZaboomafooW.RunawayJoinButton");
			_harmony.PatchAll();
			ModLogger.LogInfo((object)"[RunawayJoinButton] Loaded v1.0.0");
		}

		private void OnApplicationQuit()
		{
			if (_harmony != null)
			{
				_harmony.UnpatchSelf();
				_harmony = null;
			}
		}
	}
}
namespace RunawayJoinButton.Patches
{
	[HarmonyPatch(typeof(LobbySlot), "Awake")]
	internal static class LobbySlotAwakePatch
	{
		private static bool _hookSuccessLogged;

		private static bool _hookFailureLogged;

		[HarmonyPostfix]
		private static void Postfix(LobbySlot __instance)
		{
			Button val = FindJoinButton(__instance);
			if ((Object)(object)val == (Object)null)
			{
				if (!_hookFailureLogged)
				{
					_hookFailureLogged = true;
					Plugin.ModLogger.LogError((object)"[RunawayJoinButton] Hook failed: no serialized Button listener targeting LobbySlot.JoinButton was found under a LobbySlot.");
				}
				return;
			}
			Transform transform = ((Component)val).transform;
			RectTransform val2 = (RectTransform)(object)((transform is RectTransform) ? transform : null);
			if ((Object)(object)val2 == (Object)null)
			{
				if (!_hookFailureLogged)
				{
					_hookFailureLogged = true;
					Plugin.ModLogger.LogError((object)"[RunawayJoinButton] Hook failed: the verified lobby Join button did not expose a RectTransform.");
				}
			}
			else if (!((Object)(object)((Component)val).GetComponent<RunawayJoinButtonController>() != (Object)null))
			{
				((Component)val).gameObject.AddComponent<RunawayJoinButtonController>().Initialize(val2);
				if (!_hookSuccessLogged)
				{
					_hookSuccessLogged = true;
					Plugin.ModLogger.LogInfo((object)"[RunawayJoinButton] Hook succeeded: bound the serialized LobbySlot.JoinButton control for server rows.");
				}
			}
		}

		private static Button FindJoinButton(LobbySlot lobbySlot)
		{
			Button[] componentsInChildren = ((Component)lobbySlot).GetComponentsInChildren<Button>(true);
			foreach (Button val in componentsInChildren)
			{
				ButtonClickedEvent onClick = val.onClick;
				if (onClick == null)
				{
					continue;
				}
				int persistentEventCount = ((UnityEventBase)onClick).GetPersistentEventCount();
				for (int j = 0; j < persistentEventCount; j++)
				{
					if (((UnityEventBase)onClick).GetPersistentTarget(j) == (Object)(object)lobbySlot && ((UnityEventBase)onClick).GetPersistentMethodName(j) == "JoinButton")
					{
						return val;
					}
				}
			}
			return null;
		}
	}
}
namespace RunawayJoinButton.Controllers
{
	public sealed class RunawayJoinButtonController : MonoBehaviour
	{
		private const float TriggerDistancePixels = 90f;

		private const float MinimumRadiusFromOriginalPixels = 125f;

		private const float MaximumRadiusFromOriginalPixels = 210f;

		private const float MinimumMouseClearancePixels = 100f;

		private const float MinimumVisibleMovePixels = 45f;

		private const float MaximumAwayAngleDegrees = 70f;

		private const float ScreenPaddingPixels = 8f;

		private const float LogThrottleSeconds = 2f;

		private const int RandomCandidateAttempts = 16;

		private static int _nextControllerSeed = 1;

		private static bool _topLayerLogWritten;

		private readonly Vector3[] _worldCorners = (Vector3[])(object)new Vector3[4];

		private RectTransform _targetRect;

		private RectTransform _parentRect;

		private Canvas _parentCanvas;

		private Vector3 _originalParentLocalPosition;

		private float _nextFeatureLogTime;

		private uint _randomState;

		private bool _initialized;

		private bool _conversionFailureLogged;

		public void Initialize(RectTransform targetRect)
		{
			//IL_006e: 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_0078: Unknown result type (might be due to invalid IL or missing references)
			_targetRect = targetRect;
			ref RectTransform parentRect = ref _parentRect;
			Transform parent = ((Transform)_targetRect).parent;
			parentRect = (RectTransform)(object)((parent is RectTransform) ? parent : null);
			_parentCanvas = ((Component)_targetRect).GetComponentInParent<Canvas>();
			if ((Object)(object)_parentRect == (Object)null || (Object)(object)_parentCanvas == (Object)null)
			{
				Plugin.ModLogger.LogError((object)"[RunawayJoinButton] Hook failed: lobby-row Join button did not belong to a RectTransform parent and Canvas.");
				((Behaviour)this).enabled = false;
				return;
			}
			_originalParentLocalPosition = ((Transform)_parentRect).InverseTransformPoint(((Transform)_targetRect).position);
			uint nextControllerSeed = (uint)_nextControllerSeed;
			_nextControllerSeed++;
			_randomState = (uint)(-1640531527 ^ ((int)nextControllerSeed * -2048144789));
			if (_randomState == 0)
			{
				_randomState = 2738958700u;
			}
			PromoteButtonToTopLayer();
			_initialized = true;
		}

		private void PromoteButtonToTopLayer()
		{
			Canvas val = ((Component)_targetRect).GetComponent<Canvas>();
			if ((Object)(object)val == (Object)null)
			{
				val = ((Component)_targetRect).gameObject.AddComponent<Canvas>();
			}
			val.overrideSorting = true;
			val.sortingLayerID = _parentCanvas.sortingLayerID;
			val.sortingOrder = ((_parentCanvas.sortingOrder < int.MaxValue) ? (_parentCanvas.sortingOrder + 1) : _parentCanvas.sortingOrder);
			if ((Object)(object)((Component)_targetRect).GetComponent<GraphicRaycaster>() == (Object)null)
			{
				((Component)_targetRect).gameObject.AddComponent<GraphicRaycaster>();
			}
			if (!_topLayerLogWritten)
			{
				_topLayerLogWritten = true;
				Plugin.ModLogger.LogInfo((object)"[RunawayJoinButton] Join buttons promoted above the surrounding lobby-row UI for visibility.");
			}
		}

		private void Update()
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: 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_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: 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_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: 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_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			if (!_initialized || (Object)(object)_targetRect == (Object)null || (Object)(object)_parentRect == (Object)null || (Object)(object)_parentCanvas == (Object)null || !((Component)_targetRect).gameObject.activeInHierarchy)
			{
				return;
			}
			Mouse current = Mouse.current;
			if (current == null)
			{
				return;
			}
			Camera eventCamera = GetEventCamera(_parentCanvas);
			Vector2 val = ((InputControl<Vector2>)(object)((Pointer)current).position).ReadValue();
			Rect screenRect = GetScreenRect(_targetRect, eventCamera);
			if (DistanceToRect(val, screenRect) > 90f)
			{
				return;
			}
			Vector3 val2 = ((Transform)_parentRect).TransformPoint(_originalParentLocalPosition);
			Vector2 originalScreenPosition = RectTransformUtility.WorldToScreenPoint(eventCamera, val2);
			if (!TryChooseNearbyEscapePosition(val, screenRect, originalScreenPosition, out var destination, out var radiusFromOriginal))
			{
				return;
			}
			Vector3 position = default(Vector3);
			if (!RectTransformUtility.ScreenPointToWorldPointInRectangle(_parentRect, destination, eventCamera, ref position))
			{
				if (!_conversionFailureLogged)
				{
					_conversionFailureLogged = true;
					Plugin.ModLogger.LogError((object)"[RunawayJoinButton] Could not convert the dodge position into the Join button parent UI plane.");
				}
				return;
			}
			((Transform)_targetRect).position = position;
			if (Time.unscaledTime >= _nextFeatureLogTime)
			{
				_nextFeatureLogTime = Time.unscaledTime + 2f;
				int num = Mathf.RoundToInt(val.x);
				int num2 = Mathf.RoundToInt(val.y);
				int num3 = Mathf.RoundToInt(destination.x);
				int num4 = Mathf.RoundToInt(destination.y);
				int num5 = Mathf.RoundToInt(radiusFromOriginal);
				Plugin.ModLogger.LogInfo((object)("[RunawayJoinButton] Lobby Join button dodged within " + num5 + "px of its original position: mouse (" + num + ", " + num2 + ") -> button (" + num3 + ", " + num4 + ")."));
			}
		}

		private bool TryChooseNearbyEscapePosition(Vector2 mousePosition, Rect targetScreenRect, Vector2 originalScreenPosition, out Vector2 destination, out float radiusFromOriginal)
		{
			//IL_001e: 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_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: 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_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: 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_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: 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_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: 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_0107: 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_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			float num = ((Rect)(ref targetScreenRect)).width * 0.5f;
			float num2 = ((Rect)(ref targetScreenRect)).height * 0.5f;
			Vector2 center = ((Rect)(ref targetScreenRect)).center;
			Vector2 val = originalScreenPosition - mousePosition;
			bool flag = ((Vector2)(ref val)).sqrMagnitude < 0.001f;
			float num3 = (flag ? (NextFloat01() * 360f) : (Mathf.Atan2(val.y, val.x) * 57.29578f));
			for (int i = 0; i < 16; i++)
			{
				float num4 = Mathf.Lerp(125f, 210f, NextFloat01());
				float num5;
				if (flag)
				{
					num5 = NextFloat01() * 360f;
				}
				else
				{
					float num6 = Mathf.Lerp(-70f, 70f, NextFloat01());
					num5 = num3 + num6;
				}
				float num7 = num5 * (MathF.PI / 180f);
				Vector2 val2 = originalScreenPosition + new Vector2(Mathf.Cos(num7), Mathf.Sin(num7)) * num4;
				if (IsFullyOnScreen(val2, num, num2) && !(Vector2.Distance(center, val2) < 45f))
				{
					Rect rect = Rect.MinMaxRect(val2.x - num, val2.y - num2, val2.x + num, val2.y + num2);
					if (!(DistanceToRect(mousePosition, rect) < 100f))
					{
						destination = val2;
						radiusFromOriginal = num4;
						return true;
					}
				}
			}
			Vector2 val3 = originalScreenPosition - mousePosition;
			if (((Vector2)(ref val3)).sqrMagnitude < 0.001f)
			{
				float num8 = NextFloat01() * 360f * (MathF.PI / 180f);
				((Vector2)(ref val3))..ctor(Mathf.Cos(num8), Mathf.Sin(num8));
			}
			else
			{
				((Vector2)(ref val3)).Normalize();
			}
			Vector2 val4 = originalScreenPosition + val3 * 210f;
			val4.x = Mathf.Clamp(val4.x, num + 8f, (float)Screen.width - num - 8f);
			val4.y = Mathf.Clamp(val4.y, num2 + 8f, (float)Screen.height - num2 - 8f);
			Rect rect2 = Rect.MinMaxRect(val4.x - num, val4.y - num2, val4.x + num, val4.y + num2);
			float num9 = Vector2.Distance(originalScreenPosition, val4);
			if (num9 <= 210f && Vector2.Distance(center, val4) >= 45f && DistanceToRect(mousePosition, rect2) >= 100f)
			{
				destination = val4;
				radiusFromOriginal = num9;
				return true;
			}
			destination = center;
			radiusFromOriginal = 0f;
			return false;
		}

		private static bool IsFullyOnScreen(Vector2 center, float halfWidth, float halfHeight)
		{
			//IL_0000: 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_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			if (center.x - halfWidth >= 8f && center.x + halfWidth <= (float)Screen.width - 8f && center.y - halfHeight >= 8f)
			{
				return center.y + halfHeight <= (float)Screen.height - 8f;
			}
			return false;
		}

		private uint NextRandom()
		{
			uint randomState = _randomState;
			randomState ^= randomState << 13;
			randomState ^= randomState >> 17;
			randomState ^= randomState << 5;
			if (randomState == 0)
			{
				randomState = 2738958700u;
			}
			_randomState = randomState;
			return randomState;
		}

		private float NextFloat01()
		{
			return (float)(NextRandom() & 0xFFFFFF) / 16777215f;
		}

		private static Camera GetEventCamera(Canvas targetCanvas)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			if ((int)targetCanvas.renderMode == 0)
			{
				return null;
			}
			return targetCanvas.worldCamera;
		}

		private Rect GetScreenRect(RectTransform rectTransform, Camera eventCamera)
		{
			//IL_0014: 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_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: 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)
			//IL_0070: 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_00a1: Unknown result type (might be due to invalid IL or missing references)
			rectTransform.GetWorldCorners(_worldCorners);
			Vector2 val = RectTransformUtility.WorldToScreenPoint(eventCamera, _worldCorners[0]);
			float num = val.x;
			float num2 = val.x;
			float num3 = val.y;
			float num4 = val.y;
			for (int i = 1; i < _worldCorners.Length; i++)
			{
				Vector2 val2 = RectTransformUtility.WorldToScreenPoint(eventCamera, _worldCorners[i]);
				num = Mathf.Min(num, val2.x);
				num2 = Mathf.Max(num2, val2.x);
				num3 = Mathf.Min(num3, val2.y);
				num4 = Mathf.Max(num4, val2.y);
			}
			return Rect.MinMaxRect(num, num3, num2, num4);
		}

		private static float DistanceToRect(Vector2 point, Rect rect)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Clamp(point.x, ((Rect)(ref rect)).xMin, ((Rect)(ref rect)).xMax);
			float num2 = Mathf.Clamp(point.y, ((Rect)(ref rect)).yMin, ((Rect)(ref rect)).yMax);
			return Vector2.Distance(point, new Vector2(num, num2));
		}
	}
}