Decompiled source of GoodItemScan v1.0.1

GoodItemScan.dll

Decompiled 4 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
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.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.InputSystem;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("ClientNetworkTransform")]
[assembly: IgnoresAccessChecksTo("DissonanceVoip")]
[assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")]
[assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")]
[assembly: IgnoresAccessChecksTo("Unity.Burst")]
[assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")]
[assembly: IgnoresAccessChecksTo("Unity.Collections")]
[assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[assembly: IgnoresAccessChecksTo("Unity.Jobs")]
[assembly: IgnoresAccessChecksTo("Unity.Mathematics")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")]
[assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")]
[assembly: IgnoresAccessChecksTo("Unity.Services.QoS")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Relay")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("Unity.Timeline")]
[assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("TestAccount666.GoodItemScan")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Yet another scan mod")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1+589ac525ccd35f12bd625aeff37623f4d2dc7497")]
[assembly: AssemblyProduct("GoodItemScan")]
[assembly: AssemblyTitle("TestAccount666.GoodItemScan")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 GoodItemScan
{
	public static class ConfigManager
	{
		public static ConfigEntry<bool> preferClosestNodes;

		public static ConfigEntry<int> scanNodesHardLimit;

		public static ConfigEntry<float> scanNodeDelay;

		public static ConfigEntry<bool> sendDebugMessages;

		internal static void Initialize(ConfigFile configFile)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			preferClosestNodes = configFile.Bind<bool>("General", "Prefer Closest Nodes", true, "If true, will prefer scanning the closest nodes first. This might cause performance issues.");
			scanNodesHardLimit = configFile.Bind<int>("General", "Scan Nodes Hard Limit", 666, new ConfigDescription("Defines the maximum amount of scan nodes on screen. If you feel like your screen is cluttered, try lowering this value.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(30, 666), Array.Empty<object>()));
			scanNodeDelay = configFile.Bind<float>("General", "Scan Node Delay", 0.1f, new ConfigDescription("Defines the delay between each scan node being added to the UI. This will look stupid if set too high. This value is divided by 100.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			sendDebugMessages = configFile.Bind<bool>("Debug", "Send Debug Messages", false, "If set to true, will spam your log with debug messages.");
		}
	}
	[BepInPlugin("TestAccount666.GoodItemScan", "GoodItemScan", "1.0.1")]
	public class GoodItemScan : BaseUnityPlugin
	{
		public static GoodItemScan Instance { get; private set; }

		internal static ManualLogSource Logger { get; private set; }

		internal static Harmony? Harmony { get; set; }

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			ConfigManager.Initialize(((BaseUnityPlugin)this).Config);
			ConfigManager.scanNodesHardLimit.SettingChanged += delegate
			{
				SetIncreasedMaximumScanNodes(HUDManager.Instance);
			};
			Patch();
			Logger.LogInfo((object)"TestAccount666.GoodItemScan v1.0.1 has loaded!");
		}

		internal static void Patch()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			if (Harmony == null)
			{
				Harmony = new Harmony("TestAccount666.GoodItemScan");
			}
			LogDebug("Patching...");
			Harmony.PatchAll();
			LogDebug("Finished patching!");
		}

		internal static void Unpatch()
		{
			LogDebug("Unpatching...");
			Harmony? harmony = Harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			LogDebug("Finished unpatching!");
		}

		internal static void SetIncreasedMaximumScanNodes(HUDManager? hudManager)
		{
			//IL_0078: 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)
			if (hudManager != null)
			{
				RectTransform[] scanElements = hudManager.scanElements;
				foreach (RectTransform val in scanElements)
				{
					hudManager.scanNodes.Remove(val);
					((Component)val).gameObject.SetActive(false);
				}
				hudManager.scanNodesHit = (RaycastHit[])(object)new RaycastHit[ConfigManager.scanNodesHardLimit.Value];
				RectTransform val2 = hudManager.scanElements[0];
				List<RectTransform> list = new List<RectTransform>();
				for (int j = 0; j < ConfigManager.scanNodesHardLimit.Value; j++)
				{
					list.Add(Object.Instantiate<RectTransform>(val2, ((Transform)val2).position, ((Transform)val2).rotation, ((Transform)val2).parent));
				}
				hudManager.scanElements = list.ToArray();
			}
		}

		internal static void LogDebug(object data)
		{
			if (ConfigManager.sendDebugMessages.Value)
			{
				Logger.LogInfo(data);
			}
		}
	}
	public static class Scanner
	{
		private static readonly int _ScanAnimatorHash = Animator.StringToHash("scan");

		public static void Scan()
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: 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)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB localPlayerController = StartOfRound.Instance.localPlayerController;
			if (localPlayerController == null)
			{
				return;
			}
			HUDManager instance = HUDManager.Instance;
			if (!instance.CanPlayerScan() || (double)instance.playerPingingScan > -1.0)
			{
				return;
			}
			instance.playerPingingScan = 0.3f;
			((Component)instance.scanEffectAnimator).transform.position = ((Component)localPlayerController.gameplayCamera).transform.position;
			instance.scanEffectAnimator.SetTrigger(_ScanAnimatorHash);
			instance.UIAudio.PlayOneShot(instance.scanSFX);
			GoodItemScan.LogDebug("Scan Initiated!");
			ScanNodeProperties[] array = Object.FindObjectsOfType<ScanNodeProperties>(false);
			if (array == null)
			{
				array = Array.Empty<ScanNodeProperties>();
			}
			GoodItemScan.LogDebug($"Got '{array.Length}' nodes!");
			long num = 0L;
			Vector3 playerLocation = ((Component)localPlayerController).transform.position;
			if (ConfigManager.preferClosestNodes.Value)
			{
				array = array.OrderBy((ScanNodeProperties node) => Vector3.Distance(playerLocation, ((Component)node).transform.position)).ToArray();
			}
			ScanNodeProperties[] array2 = array;
			foreach (ScanNodeProperties val in array2)
			{
				if (val == null)
				{
					continue;
				}
				Vector3 position = ((Component)val).transform.position;
				float num2 = Vector3.Distance(position, playerLocation);
				if (!(num2 > (float)val.maxRange) && !(num2 < (float)val.minRange) && (!val.requiresLineOfSight || !Physics.Linecast(((Component)localPlayerController.gameplayCamera).transform.position, position, 256, (QueryTriggerInteraction)1)) && IsScanNodeValid(val))
				{
					num++;
					if (num > ConfigManager.scanNodesHardLimit.Value)
					{
						GoodItemScan.LogDebug($"Hard Limit of {ConfigManager.scanNodesHardLimit.Value} reached!");
						break;
					}
					((MonoBehaviour)localPlayerController).StartCoroutine(AddScanNodeToUI(val, num));
				}
			}
		}

		private static bool IsScanNodeValid(ScanNodeProperties scanNodeProperties)
		{
			Transform parent = ((Component)scanNodeProperties).transform.parent;
			if (parent == null)
			{
				return false;
			}
			GrabbableObject component = ((Component)parent).GetComponent<GrabbableObject>();
			if ((component != null && component.isHeld) || (component != null && component.isHeldByEnemy) || (component != null && component.deactivated))
			{
				return false;
			}
			return !(((Component)parent).GetComponent<EnemyAI>()?.isEnemyDead ?? false);
		}

		private static IEnumerator AddScanNodeToUI(ScanNodeProperties scanNodeProperties, long currentScanNodeCount)
		{
			yield return (object)new WaitForSeconds(ConfigManager.scanNodeDelay.Value / 100f * (float)currentScanNodeCount);
			PlayerControllerB localPlayer = StartOfRound.Instance.localPlayerController;
			if (localPlayer == null)
			{
				yield break;
			}
			HUDManager hudManager = HUDManager.Instance;
			if (hudManager != null)
			{
				GoodItemScan.LogDebug($"Scanning node '{currentScanNodeCount}'!");
				if (scanNodeProperties.nodeType == 2)
				{
					hudManager.scannedScrapNum++;
				}
				if (!hudManager.nodesOnScreen.Contains(scanNodeProperties))
				{
					hudManager.nodesOnScreen.Add(scanNodeProperties);
				}
				hudManager.AssignNodeToUIElement(scanNodeProperties);
			}
		}

		public static bool IsScanNodeVisible(ScanNodeProperties node)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: 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_0059: 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_0081: Unknown result type (might be due to invalid IL or missing references)
			if (!((Component)node).gameObject.activeSelf)
			{
				return false;
			}
			PlayerControllerB localPlayerController = StartOfRound.Instance.localPlayerController;
			if (localPlayerController == null)
			{
				return false;
			}
			Camera gameplayCamera = localPlayerController.gameplayCamera;
			Vector3 val = ((Component)node).transform.position - ((Component)gameplayCamera).transform.position;
			((Vector3)(ref val)).Normalize();
			float num = Mathf.Cos(gameplayCamera.fieldOfView * 0.6f * (MathF.PI / 180f));
			if (Vector3.Dot(val, ((Component)gameplayCamera).transform.forward) < num)
			{
				return false;
			}
			return IsScanNodeValid(node);
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "TestAccount666.GoodItemScan";

		public const string PLUGIN_NAME = "GoodItemScan";

		public const string PLUGIN_VERSION = "1.0.1";
	}
}
namespace GoodItemScan.Patches
{
	[HarmonyPatch(typeof(HUDManager))]
	public static class HUDManagerPatch
	{
		[HarmonyPatch("AssignNewNodes")]
		[HarmonyPrefix]
		private static bool DontAssignNewNodes()
		{
			return false;
		}

		[HarmonyPatch("MeetsScanNodeRequirements")]
		[HarmonyPrefix]
		private static bool MeetsScanNodeRequirements(ref bool __result)
		{
			__result = true;
			return false;
		}

		[HarmonyPatch("NodeIsNotVisible")]
		[HarmonyPrefix]
		private static bool NodeIsNotVisible(ScanNodeProperties node, int elementIndex, ref bool __result)
		{
			HUDManager instance = HUDManager.Instance;
			RectTransform val = ((instance != null) ? instance.scanElements[elementIndex] : null);
			if (instance == null || val == null)
			{
				return false;
			}
			PlayerControllerB localPlayerController = StartOfRound.Instance.localPlayerController;
			if (localPlayerController == null)
			{
				return false;
			}
			if (Scanner.IsScanNodeVisible(node))
			{
				__result = false;
				return false;
			}
			if (node.nodeType == 2)
			{
				instance.totalScrapScanned = Mathf.Clamp(instance.totalScrapScanned - node.scrapValue, 0, 100000);
			}
			((Component)val).gameObject.SetActive(false);
			instance.scanNodes.Remove(val);
			__result = true;
			return false;
		}

		[HarmonyPatch("PingScan_performed")]
		[HarmonyPrefix]
		private static bool PingScanPerformed(ref CallbackContext context)
		{
			if (!((CallbackContext)(ref context)).performed)
			{
				return false;
			}
			Scanner.Scan();
			return false;
		}

		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		private static void AfterHudManagerAwake(HUDManager __instance)
		{
			GoodItemScan.SetIncreasedMaximumScanNodes(__instance);
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}