Decompiled source of PaintYourself v1.0.6

BepInEx\plugins\BigWalk.PaintYourself\BigWalk.PaintYourself.dll

Decompiled a day ago
using System;
using System.Diagnostics;
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.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem.Collections.Generic;
using Mirror;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("BigWalk.PaintYourself")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.6.0")]
[assembly: AssemblyInformationalVersion("1.0.6")]
[assembly: AssemblyProduct("Big Walk Paint Yourself")]
[assembly: AssemblyTitle("BigWalk.PaintYourself")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.6.0")]
[module: UnverifiableCode]
namespace BigWalk.PaintYourself;

public sealed class PaintYourselfController : MonoBehaviour
{
	private static MirrorCamera[] _cachedMirrors;

	private static float _nextMirrorCacheTime;

	private void Update()
	{
		//IL_0042: 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_00ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0105: Invalid comparison between Unknown and I4
		//IL_012b: 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_0130: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: Unknown result type (might be due to invalid IL or missing references)
		//IL_0136: 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_013e: 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_0158: Unknown result type (might be due to invalid IL or missing references)
		if (!Plugin.Enabled.Value || !WasPrimaryDown())
		{
			return;
		}
		if (TryGetMirrorPaintTarget(out var player, out var brush, out var part, out var score, out var via))
		{
			Verbose($"Mirror paint target LookPart.{part} via {via} (aimScore={score:F3})");
			ApplyPaint(player, brush, part, $"{via} (aimScore={score:F3})");
			return;
		}
		if (!TryGetLocalBrush(out player, out brush))
		{
			Verbose("Click ignored: no local player holding a SalonBrush.");
			return;
		}
		Camera aimCamera = GetAimCamera(player);
		if (!((Object)(object)aimCamera == (Object)null))
		{
			Vector3 val = (Vector3)(((int)Cursor.lockState == 1) ? new Vector3((float)Screen.width * 0.5f, (float)Screen.height * 0.5f, 0f) : Input.mousePosition);
			Ray ray = aimCamera.ScreenPointToRay(val);
			if (TryFindOwnLookPart(player, ray, Plugin.MirrorMaxDistance.Value, null, out var part2, out var hit))
			{
				ApplyPaint(player, brush, part2, $"direct self-hit ({((RaycastHit)(ref hit)).distance:F2}m)");
			}
			else
			{
				Verbose("Click with brush but no mirror / own LookPart under crosshair. hitInfo=" + DescribeFirstHit(ray, Plugin.MirrorMaxDistance.Value));
			}
		}
	}

	private static MirrorCamera[] GetMirrors()
	{
		if (_cachedMirrors != null && Time.unscaledTime < _nextMirrorCacheTime)
		{
			return _cachedMirrors;
		}
		try
		{
			_cachedMirrors = Il2CppArrayBase<MirrorCamera>.op_Implicit(Object.FindObjectsOfType<MirrorCamera>(true));
		}
		catch
		{
			_cachedMirrors = null;
		}
		_nextMirrorCacheTime = Time.unscaledTime + 2f;
		return _cachedMirrors;
	}

	private bool TryGetMirrorPaintTarget(out PlayerCharacter player, out SalonBrush brush, out LookPart part, out float score, out string via)
	{
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Invalid comparison between Unknown and I4
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: 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_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: 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_0093: 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)
		//IL_00af: 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_00cf: 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_0109: Unknown result type (might be due to invalid IL or missing references)
		//IL_010a: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: Unknown result type (might be due to invalid IL or missing references)
		player = null;
		brush = null;
		part = (LookPart)0;
		score = float.MaxValue;
		via = null;
		if (!TryGetLocalBrush(out player, out brush))
		{
			return false;
		}
		Camera aimCamera = GetAimCamera(player);
		if ((Object)(object)aimCamera == (Object)null)
		{
			return false;
		}
		Vector3 val = (Vector3)(((int)Cursor.lockState == 1) ? new Vector3((float)Screen.width * 0.5f, (float)Screen.height * 0.5f, 0f) : Input.mousePosition);
		Ray val2 = aimCamera.ScreenPointToRay(val);
		if (!TryHitMirror(val2, Plugin.MirrorMaxDistance.Value, out var mirror, out var hit))
		{
			return false;
		}
		if (!TryGetMirrorViewport(mirror, hit, out var viewport))
		{
			return false;
		}
		if (viewport.x < -0.05f || viewport.x > 1.05f || viewport.y < -0.05f || viewport.y > 1.05f)
		{
			return false;
		}
		viewport.x = Mathf.Clamp01(viewport.x);
		viewport.y = Mathf.Clamp01(viewport.y);
		Camera cameraObject = mirror.cameraObject;
		if ((Object)(object)cameraObject == (Object)null)
		{
			return false;
		}
		return TryPickCombined(player, val2, hit, cameraObject, viewport, out part, out score, out via);
	}

	private static bool TryPickCombined(PlayerCharacter player, Ray aimRay, RaycastHit mirrorHit, Camera mirrorCam, Vector2 meshUv, out LookPart part, out float bestScore, out string via)
	{
		//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_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: 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_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: 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_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: 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_0088: 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_0099: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: 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_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: 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_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0169: Unknown result type (might be due to invalid IL or missing references)
		//IL_016f: Expected I4, but got Unknown
		part = (LookPart)0;
		bestScore = float.MaxValue;
		via = null;
		PlayerLooks looks = player.looks;
		if (looks == null)
		{
			return false;
		}
		Vector3 val = ((RaycastHit)(ref mirrorHit)).normal;
		if (Vector3.Dot(val, -((Ray)(ref aimRay)).direction) < 0f)
		{
			val = -val;
		}
		Vector3 direction = ((Ray)(ref aimRay)).direction;
		Vector3 val2 = Vector3.Reflect(((Vector3)(ref direction)).normalized, ((Vector3)(ref val)).normalized);
		Ray bodyRay = new Ray(((RaycastHit)(ref mirrorHit)).point + val2 * 0.03f, val2);
		Vector2[] uvCandidates = (Vector2[])(object)new Vector2[4]
		{
			meshUv,
			new Vector2(meshUv.x, 1f - meshUv.y),
			new Vector2(1f - meshUv.x, meshUv.y),
			new Vector2(1f - meshUv.x, 1f - meshUv.y)
		};
		LookPart bestPart = part;
		float best = bestScore;
		string bestVia = null;
		Consider(looks.headRenderers, (LookPart)0);
		Consider(looks.torsoRenderers, (LookPart)1);
		Consider(looks.legsRenderers, (LookPart)2);
		if (bestVia == null || best >= 1.25f)
		{
			return false;
		}
		part = (LookPart)(int)bestPart;
		bestScore = best;
		via = bestVia;
		return true;
		void Consider(Il2CppReferenceArray<LooksRenderer> arr, LookPart lookPart)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: 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_0027: 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_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: 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_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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_0048: 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)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: 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_012e: Unknown result type (might be due to invalid IL or missing references)
			if (TryGetArrayBounds(arr, preferRemote: true, out var bounds))
			{
				Vector3 center = ((Bounds)(ref bounds)).center;
				float num = float.MaxValue;
				Vector3 val3 = mirrorCam.WorldToViewportPoint(center);
				if (val3.z > 0.05f)
				{
					foreach (Vector2 val4 in uvCandidates)
					{
						float num2 = val3.x - val4.x;
						float num3 = val3.y - val4.y;
						float num4 = Mathf.Sqrt(num2 * num2 + num3 * num3);
						if (num4 < num)
						{
							num = num4;
						}
					}
				}
				float num5 = default(float);
				float num6;
				if (((Bounds)(ref bounds)).IntersectRay(bodyRay, ref num5) && num5 > 0.05f)
				{
					num6 = DistancePointToRay(bodyRay, center);
				}
				else
				{
					float num7 = Vector3.Dot(center - ((Ray)(ref bodyRay)).origin, ((Ray)(ref bodyRay)).direction);
					if (num7 < 0.05f || num7 > Plugin.ReflectionMaxDistance.Value)
					{
						return;
					}
					num6 = DistancePointToRay(bodyRay, center);
				}
				float num8 = num * 1.35f + num6 * 0.4f;
				if (!(num8 >= best))
				{
					best = num8;
					bestPart = lookPart;
					bestVia = $"combined glass={num:F2} plane={num6:F2}";
				}
			}
		}
	}

	private static bool WasPrimaryDown()
	{
		if (!Input.GetMouseButtonDown(0))
		{
			return Input.GetKeyDown((KeyCode)323);
		}
		return true;
	}

	private static void ApplyPaint(PlayerCharacter player, SalonBrush brush, LookPart part, string via)
	{
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Expected O, but got Unknown
		//IL_0078: 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)
		int currentColorId = brush.currentColorId;
		PlayerNetworking playerNetworking = player.playerNetworking;
		if ((Object)(object)playerNetworking == (Object)null)
		{
			Plugin.Log.LogWarning((object)"Local player has no playerNetworking; cannot CmdChangeLook.");
			return;
		}
		ManualLogSource log = Plugin.Log;
		bool flag = default(bool);
		BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(38, 3, ref flag);
		if (flag)
		{
			((BepInExLogInterpolatedStringHandler)val).AppendLiteral("PaintYourself: LookPart.");
			((BepInExLogInterpolatedStringHandler)val).AppendFormatted<LookPart>(part);
			((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" colorId=");
			((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(currentColorId);
			((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" via ");
			((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(via);
		}
		log.LogInfo(val);
		playerNetworking.CmdChangeLook(currentColorId, part);
	}

	private static bool TryGetArrayBounds(Il2CppReferenceArray<LooksRenderer> arr, bool preferRemote, out Bounds bounds)
	{
		//IL_0001: 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_007a: 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_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00de: 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_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
		bounds = default(Bounds);
		if (arr == null || ((Il2CppArrayBase<LooksRenderer>)(object)arr).Length == 0)
		{
			return false;
		}
		bool flag = false;
		for (int i = 0; i < 2; i++)
		{
			for (int j = 0; j < ((Il2CppArrayBase<LooksRenderer>)(object)arr).Length; j++)
			{
				LooksRenderer val = ((Il2CppArrayBase<LooksRenderer>)(object)arr)[j];
				if (val == null || (Object)(object)val.renderer == (Object)null)
				{
					continue;
				}
				try
				{
					if (i == 0 && ((preferRemote && val.local && !val.remote) || (!preferRemote && val.remote && !val.local)))
					{
						continue;
					}
				}
				catch
				{
				}
				Bounds bounds2 = val.renderer.bounds;
				if (!flag)
				{
					bounds = bounds2;
					flag = true;
				}
				else
				{
					((Bounds)(ref bounds)).Encapsulate(bounds2);
				}
			}
			if (flag)
			{
				return true;
			}
		}
		for (int k = 0; k < ((Il2CppArrayBase<LooksRenderer>)(object)arr).Length; k++)
		{
			LooksRenderer val2 = ((Il2CppArrayBase<LooksRenderer>)(object)arr)[k];
			if (val2 != null && !((Object)(object)val2.renderer == (Object)null))
			{
				Bounds bounds3 = val2.renderer.bounds;
				if (!flag)
				{
					bounds = bounds3;
					flag = true;
				}
				else
				{
					((Bounds)(ref bounds)).Encapsulate(bounds3);
				}
			}
		}
		return flag;
	}

	private static float DistancePointToRay(Ray ray, Vector3 point)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: 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_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_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		float num = Vector3.Dot(point - ((Ray)(ref ray)).origin, ((Ray)(ref ray)).direction);
		return Vector3.Distance(((Ray)(ref ray)).origin + ((Ray)(ref ray)).direction * num, point);
	}

	private static Camera GetAimCamera(PlayerCharacter player)
	{
		try
		{
			if ((Object)(object)player != (Object)null && (Object)(object)player.cameraTransform != (Object)null)
			{
				Camera component = ((Component)player.cameraTransform).GetComponent<Camera>();
				if ((Object)(object)component != (Object)null)
				{
					return component;
				}
				component = ((Component)player.cameraTransform).GetComponentInChildren<Camera>();
				if ((Object)(object)component != (Object)null)
				{
					return component;
				}
			}
		}
		catch
		{
		}
		return Camera.main;
	}

	private static bool TryGetLocalBrush(out PlayerCharacter player, out SalonBrush brush)
	{
		player = FindLocalPlayer();
		brush = null;
		if ((Object)(object)player == (Object)null || player.hands == null)
		{
			return false;
		}
		Prop heldProp = player.hands.heldProp;
		if ((Object)(object)heldProp == (Object)null)
		{
			return false;
		}
		brush = ((Component)heldProp).GetComponent<SalonBrush>() ?? ((Component)heldProp).GetComponentInChildren<SalonBrush>() ?? ((Component)heldProp).GetComponentInParent<SalonBrush>();
		return (Object)(object)brush != (Object)null;
	}

	private static PlayerCharacter FindLocalPlayer()
	{
		try
		{
			List<PlayerCharacter> allPlayerCharacters = PlayerCharacter.allPlayerCharacters;
			if (allPlayerCharacters == null)
			{
				return null;
			}
			for (int i = 0; i < allPlayerCharacters.Count; i++)
			{
				PlayerCharacter val = allPlayerCharacters[i];
				if ((Object)(object)val != (Object)null && ((NetworkBehaviour)val).isLocalPlayer)
				{
					return val;
				}
			}
		}
		catch
		{
		}
		return null;
	}

	private static bool TryHitMirror(Ray ray, float maxDist, out MirrorCamera mirror, out RaycastHit hit)
	{
		//IL_0004: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: 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_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_0144: Unknown result type (might be due to invalid IL or missing references)
		//IL_0146: Unknown result type (might be due to invalid IL or missing references)
		//IL_0104: Unknown result type (might be due to invalid IL or missing references)
		//IL_0124: Unknown result type (might be due to invalid IL or missing references)
		//IL_0126: 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_00a5: Unknown result type (might be due to invalid IL or missing references)
		mirror = null;
		hit = default(RaycastHit);
		Il2CppStructArray<RaycastHit> val = Physics.RaycastAll(ray, maxDist, -1, (QueryTriggerInteraction)2);
		if (val != null && ((Il2CppArrayBase<RaycastHit>)(object)val).Length > 0)
		{
			SortByDistance(Il2CppArrayBase<RaycastHit>.op_Implicit((Il2CppArrayBase<RaycastHit>)(object)val));
			for (int i = 0; i < ((Il2CppArrayBase<RaycastHit>)(object)val).Length; i++)
			{
				RaycastHit val2 = ((Il2CppArrayBase<RaycastHit>)(object)val)[i];
				if (!((Object)(object)((RaycastHit)(ref val2)).collider == (Object)null))
				{
					MirrorCamera val3 = ((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent<MirrorCamera>() ?? ((Component)((RaycastHit)(ref val2)).collider).GetComponentInChildren<MirrorCamera>();
					if ((Object)(object)val3 == (Object)null)
					{
						val3 = FindMirrorByRenderer(((RaycastHit)(ref val2)).collider);
					}
					if (!((Object)(object)val3 == (Object)null) && !((Object)(object)val3.cameraObject == (Object)null))
					{
						mirror = val3;
						hit = val2;
						return true;
					}
				}
			}
		}
		MirrorCamera[] mirrors = GetMirrors();
		if (mirrors == null || mirrors.Length == 0)
		{
			return false;
		}
		float num = float.MaxValue;
		MirrorCamera val4 = null;
		RaycastHit val5 = default(RaycastHit);
		foreach (MirrorCamera val6 in mirrors)
		{
			if (!((Object)(object)val6 == (Object)null) && !((Object)(object)val6.cameraObject == (Object)null) && TryRaycastMirrorSurface(val6, ray, maxDist, out var hit2) && !(((RaycastHit)(ref hit2)).distance >= num))
			{
				num = ((RaycastHit)(ref hit2)).distance;
				val4 = val6;
				val5 = hit2;
			}
		}
		if ((Object)(object)val4 == (Object)null)
		{
			return false;
		}
		mirror = val4;
		hit = val5;
		return true;
	}

	private static bool TryRaycastMirrorSurface(MirrorCamera mirror, Ray ray, float maxDist, out RaycastHit hit)
	{
		//IL_0001: 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_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: 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_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		hit = default(RaycastHit);
		float num = float.MaxValue;
		bool result = false;
		Renderer targetRenderer = mirror.targetRenderer;
		if ((Object)(object)targetRenderer != (Object)null)
		{
			Collider val = ((Component)targetRenderer).GetComponent<Collider>() ?? ((Component)targetRenderer).GetComponentInChildren<Collider>() ?? ((Component)targetRenderer).GetComponentInParent<Collider>();
			RaycastHit val2 = default(RaycastHit);
			if ((Object)(object)val != (Object)null && val.Raycast(ray, ref val2, maxDist) && ((RaycastHit)(ref val2)).distance < num)
			{
				num = ((RaycastHit)(ref val2)).distance;
				hit = val2;
				result = true;
			}
		}
		Il2CppArrayBase<Collider> componentsInChildren = ((Component)mirror).GetComponentsInChildren<Collider>(true);
		if (componentsInChildren != null)
		{
			RaycastHit val4 = default(RaycastHit);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Collider val3 = componentsInChildren[i];
				if (!((Object)(object)val3 == (Object)null) && val3.Raycast(ray, ref val4, maxDist) && ((RaycastHit)(ref val4)).distance < num)
				{
					num = ((RaycastHit)(ref val4)).distance;
					hit = val4;
					result = true;
				}
			}
		}
		return result;
	}

	private static MirrorCamera FindMirrorByRenderer(Collider col)
	{
		if ((Object)(object)col == (Object)null)
		{
			return null;
		}
		Renderer val = ((Component)col).GetComponent<Renderer>() ?? ((Component)col).GetComponentInParent<Renderer>() ?? ((Component)col).GetComponentInChildren<Renderer>();
		if ((Object)(object)val == (Object)null)
		{
			return null;
		}
		MirrorCamera[] mirrors = GetMirrors();
		if (mirrors == null)
		{
			return null;
		}
		foreach (MirrorCamera val2 in mirrors)
		{
			if ((Object)(object)val2 != (Object)null && (Object)(object)val2.targetRenderer == (Object)(object)val)
			{
				return val2;
			}
		}
		return null;
	}

	private static string DescribeFirstHit(Ray ray, float maxDist)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		RaycastHit val = default(RaycastHit);
		if (!Physics.Raycast(ray, ref val, maxDist, -1, (QueryTriggerInteraction)2))
		{
			return "none";
		}
		DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(6, 2);
		Collider collider = ((RaycastHit)(ref val)).collider;
		defaultInterpolatedStringHandler.AppendFormatted((collider != null) ? ((Object)collider).name : null);
		defaultInterpolatedStringHandler.AppendLiteral(" dist=");
		defaultInterpolatedStringHandler.AppendFormatted(((RaycastHit)(ref val)).distance, "F2");
		return defaultInterpolatedStringHandler.ToStringAndClear();
	}

	private static bool TryGetMirrorViewport(MirrorCamera mirror, RaycastHit hit, out Vector2 viewport)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0009: 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_00bd: 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_00cc: 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_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: 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_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0101: Unknown result type (might be due to invalid IL or missing references)
		//IL_0103: Unknown result type (might be due to invalid IL or missing references)
		//IL_0105: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: 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_0118: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: 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_012a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0131: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0199: 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_013a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0141: Unknown result type (might be due to invalid IL or missing references)
		//IL_0207: Unknown result type (might be due to invalid IL or missing references)
		//IL_0213: Unknown result type (might be due to invalid IL or missing references)
		//IL_021d: Unknown result type (might be due to invalid IL or missing references)
		//IL_022c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0238: 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_01a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_014c: 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_0162: Unknown result type (might be due to invalid IL or missing references)
		//IL_0171: Unknown result type (might be due to invalid IL or missing references)
		//IL_017d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0187: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0254: Unknown result type (might be due to invalid IL or missing references)
		//IL_0259: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f6: 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)
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		viewport = default(Vector2);
		Vector2 textureCoord = ((RaycastHit)(ref hit)).textureCoord;
		if ((((RaycastHit)(ref hit)).collider is MeshCollider || textureCoord.x > 0.001f || textureCoord.y > 0.001f) && (((RaycastHit)(ref hit)).collider is MeshCollider || textureCoord.x != 0f || textureCoord.y != 0f))
		{
			viewport = textureCoord;
			return true;
		}
		Renderer val = mirror.targetRenderer;
		if ((Object)(object)val == (Object)null && (Object)(object)((RaycastHit)(ref hit)).collider != (Object)null)
		{
			val = ((Component)((RaycastHit)(ref hit)).collider).GetComponentInParent<Renderer>();
		}
		if ((Object)(object)val == (Object)null)
		{
			return false;
		}
		Vector3 val2 = ((Component)val).transform.InverseTransformPoint(((RaycastHit)(ref hit)).point);
		Bounds localBounds = default(Bounds);
		try
		{
			localBounds = val.localBounds;
		}
		catch
		{
			Bounds bounds = val.bounds;
			Vector3 val3 = ((Component)val).transform.InverseTransformPoint(((Bounds)(ref bounds)).min);
			Vector3 val4 = ((Component)val).transform.InverseTransformPoint(((Bounds)(ref bounds)).max);
			((Bounds)(ref localBounds))..ctor((val3 + val4) * 0.5f, val4 - val3);
		}
		Vector3 size = ((Bounds)(ref localBounds)).size;
		if (((Vector3)(ref size)).sqrMagnitude < 1E-08f)
		{
			return false;
		}
		float num;
		float num2;
		if (size.z <= size.x && size.z <= size.y)
		{
			num = InverseLerpSafe(((Bounds)(ref localBounds)).min.x, ((Bounds)(ref localBounds)).max.x, val2.x);
			num2 = InverseLerpSafe(((Bounds)(ref localBounds)).min.y, ((Bounds)(ref localBounds)).max.y, val2.y);
		}
		else if (size.y <= size.x && size.y <= size.z)
		{
			num = InverseLerpSafe(((Bounds)(ref localBounds)).min.x, ((Bounds)(ref localBounds)).max.x, val2.x);
			num2 = InverseLerpSafe(((Bounds)(ref localBounds)).min.z, ((Bounds)(ref localBounds)).max.z, val2.z);
		}
		else
		{
			num = InverseLerpSafe(((Bounds)(ref localBounds)).min.z, ((Bounds)(ref localBounds)).max.z, val2.z);
			num2 = InverseLerpSafe(((Bounds)(ref localBounds)).min.y, ((Bounds)(ref localBounds)).max.y, val2.y);
		}
		viewport = new Vector2(num, num2);
		return true;
	}

	private static float InverseLerpSafe(float a, float b, float v)
	{
		if (Mathf.Abs(b - a) < 1E-05f)
		{
			return 0.5f;
		}
		return Mathf.InverseLerp(a, b, v);
	}

	private static bool TryFindOwnLookPart(PlayerCharacter player, Ray ray, float maxDist, MirrorCamera ignoreMirror, out LookPart part, out RaycastHit hit)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: 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)
		part = (LookPart)0;
		hit = default(RaycastHit);
		if (!TryCollectOwnLookPartHits(player, ray, maxDist, ignoreMirror, out var hits, out var parts, out var _))
		{
			return false;
		}
		int num = -1;
		float num2 = float.MaxValue;
		for (int i = 0; i < hits.Length; i++)
		{
			if (!(((RaycastHit)(ref hits[i])).distance < 0.2f) && !(((RaycastHit)(ref hits[i])).distance >= num2))
			{
				num2 = ((RaycastHit)(ref hits[i])).distance;
				num = i;
			}
		}
		if (num < 0)
		{
			return false;
		}
		part = parts[num];
		hit = hits[num];
		return true;
	}

	private static bool TryCollectOwnLookPartHits(PlayerCharacter player, Ray ray, float maxDist, MirrorCamera ignoreMirror, out RaycastHit[] hits, out LookPart[] parts, out bool[] mappedToRenderer)
	{
		//IL_0018: 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_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_014b: Unknown result type (might be due to invalid IL or missing references)
		//IL_014d: 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_015d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0163: Expected I4, but got Unknown
		//IL_012d: Unknown result type (might be due to invalid IL or missing references)
		//IL_012f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0137: Unknown result type (might be due to invalid IL or missing references)
		//IL_013a: Expected I4, but got Unknown
		hits = null;
		parts = null;
		mappedToRenderer = null;
		PlayerLooks looks = player.looks;
		if (looks == null)
		{
			return false;
		}
		Il2CppStructArray<RaycastHit> val = Physics.RaycastAll(ray, maxDist, -1, (QueryTriggerInteraction)2);
		if (val == null || ((Il2CppArrayBase<RaycastHit>)(object)val).Length == 0)
		{
			return false;
		}
		SortByDistance(Il2CppArrayBase<RaycastHit>.op_Implicit((Il2CppArrayBase<RaycastHit>)(object)val));
		RaycastHit[] array = (RaycastHit[])(object)new RaycastHit[((Il2CppArrayBase<RaycastHit>)(object)val).Length];
		LookPart[] array2 = (LookPart[])(object)new LookPart[((Il2CppArrayBase<RaycastHit>)(object)val).Length];
		bool[] array3 = new bool[((Il2CppArrayBase<RaycastHit>)(object)val).Length];
		int num = 0;
		Transform transform = ((Component)player).transform;
		for (int i = 0; i < ((Il2CppArrayBase<RaycastHit>)(object)val).Length; i++)
		{
			RaycastHit val2 = ((Il2CppArrayBase<RaycastHit>)(object)val)[i];
			if ((Object)(object)((RaycastHit)(ref val2)).collider == (Object)null || ((Object)(object)ignoreMirror != (Object)null && ((Object)(object)(((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent<MirrorCamera>() ?? ((Component)((RaycastHit)(ref val2)).collider).GetComponentInChildren<MirrorCamera>()) == (Object)(object)ignoreMirror || ((Object)(object)ignoreMirror.targetRenderer != (Object)null && (Object)(object)(((Component)((RaycastHit)(ref val2)).collider).GetComponent<Renderer>() ?? ((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent<Renderer>()) == (Object)(object)ignoreMirror.targetRenderer))))
			{
				continue;
			}
			Transform transform2 = ((Component)((RaycastHit)(ref val2)).collider).transform;
			if (!((Object)(object)transform2 != (Object)(object)transform) || transform2.IsChildOf(transform))
			{
				if (TryMapRendererToLookPart(looks, ((RaycastHit)(ref val2)).collider, out var part))
				{
					array[num] = val2;
					array2[num] = (LookPart)(int)part;
					array3[num] = true;
					num++;
				}
				else
				{
					array[num] = val2;
					array2[num] = (LookPart)(int)InferLookPartByHeight(player, ((RaycastHit)(ref val2)).point);
					array3[num] = false;
					num++;
				}
			}
		}
		if (num == 0)
		{
			return false;
		}
		hits = (RaycastHit[])(object)new RaycastHit[num];
		parts = (LookPart[])(object)new LookPart[num];
		mappedToRenderer = new bool[num];
		for (int j = 0; j < num; j++)
		{
			hits[j] = array[j];
			parts[j] = array2[j];
			mappedToRenderer[j] = array3[j];
		}
		return true;
	}

	private static LookPart InferLookPartByHeight(PlayerCharacter player, Vector3 worldPoint)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		float y = ((Component)player).transform.InverseTransformPoint(worldPoint).y;
		if (!(y >= 1.2f))
		{
			if (!(y >= 0.55f))
			{
				return (LookPart)2;
			}
			return (LookPart)1;
		}
		return (LookPart)0;
	}

	private static bool TryMapRendererToLookPart(PlayerLooks looks, Collider col, out LookPart part)
	{
		part = (LookPart)0;
		if ((Object)(object)col == (Object)null)
		{
			return false;
		}
		Renderer hitRenderer = ((Component)col).GetComponent<Renderer>() ?? ((Component)col).GetComponentInParent<Renderer>() ?? ((Component)col).GetComponentInChildren<Renderer>();
		if (ContainsRenderer(looks.headRenderers, hitRenderer, ((Component)col).transform))
		{
			part = (LookPart)0;
			return true;
		}
		if (ContainsRenderer(looks.torsoRenderers, hitRenderer, ((Component)col).transform))
		{
			part = (LookPart)1;
			return true;
		}
		if (ContainsRenderer(looks.legsRenderers, hitRenderer, ((Component)col).transform))
		{
			part = (LookPart)2;
			return true;
		}
		return false;
	}

	private static bool ContainsRenderer(Il2CppReferenceArray<LooksRenderer> arr, Renderer hitRenderer, Transform hitTransform)
	{
		if (arr == null)
		{
			return false;
		}
		for (int i = 0; i < ((Il2CppArrayBase<LooksRenderer>)(object)arr).Length; i++)
		{
			LooksRenderer val = ((Il2CppArrayBase<LooksRenderer>)(object)arr)[i];
			if (val != null && !((Object)(object)val.renderer == (Object)null))
			{
				Renderer renderer = val.renderer;
				if ((Object)(object)hitRenderer != (Object)null && ((Object)(object)renderer == (Object)(object)hitRenderer || ((Component)hitRenderer).transform.IsChildOf(((Component)renderer).transform) || ((Component)renderer).transform.IsChildOf(((Component)hitRenderer).transform)))
				{
					return true;
				}
				if ((Object)(object)hitTransform != (Object)null && ((Object)(object)hitTransform == (Object)(object)((Component)renderer).transform || hitTransform.IsChildOf(((Component)renderer).transform) || ((Component)renderer).transform.IsChildOf(hitTransform)))
				{
					return true;
				}
			}
		}
		return false;
	}

	private static void SortByDistance(RaycastHit[] hits)
	{
		//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_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: 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)
		for (int i = 0; i < hits.Length; i++)
		{
			for (int j = i + 1; j < hits.Length; j++)
			{
				if (((RaycastHit)(ref hits[j])).distance < ((RaycastHit)(ref hits[i])).distance)
				{
					RaycastHit val = hits[i];
					hits[i] = hits[j];
					hits[j] = val;
				}
			}
		}
	}

	private static void Verbose(string msg)
	{
		if (Plugin.LogVerbose.Value)
		{
			Plugin.Log.LogInfo((object)msg);
		}
	}
}
[BepInPlugin("BigWalk.PaintYourself", "Big Walk Paint Yourself", "1.0.6")]
[BepInProcess("Big Walk.exe")]
public class Plugin : BasePlugin
{
	internal static Plugin Instance;

	internal static ManualLogSource Log;

	public static ConfigEntry<bool> Enabled;

	public static ConfigEntry<float> MirrorMaxDistance;

	public static ConfigEntry<float> ReflectionMaxDistance;

	public static ConfigEntry<bool> LogVerbose;

	public override void Load()
	{
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Expected O, but got Unknown
		//IL_009c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a6: Expected O, but got Unknown
		//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e2: Expected O, but got Unknown
		Instance = this;
		Log = ((BasePlugin)this).Log;
		Enabled = ((BasePlugin)this).Config.Bind<bool>("Paint", "Enabled", true, "Allow painting your own body by aiming a paintbrush at a mirror reflection.");
		MirrorMaxDistance = ((BasePlugin)this).Config.Bind<float>("Paint", "MirrorMaxDistance", 8f, new ConfigDescription("How far you can be from a mirror to paint.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 30f), Array.Empty<object>()));
		ReflectionMaxDistance = ((BasePlugin)this).Config.Bind<float>("Paint", "ReflectionMaxDistance", 12f, new ConfigDescription("How far the mirror camera ray searches for your body.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 40f), Array.Empty<object>()));
		LogVerbose = ((BasePlugin)this).Config.Bind<bool>("Paint", "LogVerbose", false, "Log mirror hit / paint attempts to the BepInEx log.");
		((BasePlugin)this).AddComponent<PaintYourselfController>();
		ManualLogSource log = Log;
		bool flag = default(bool);
		BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(62, 2, ref flag);
		if (flag)
		{
			((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("Big Walk Paint Yourself");
			((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" v");
			((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("1.0.6");
			((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" loaded. Aim a paintbrush at your reflection and left-click.");
		}
		log.LogInfo(val);
	}
}
public static class MyPluginInfo
{
	public const string PLUGIN_GUID = "BigWalk.PaintYourself";

	public const string PLUGIN_NAME = "Big Walk Paint Yourself";

	public const string PLUGIN_VERSION = "1.0.6";
}