Decompiled source of LethalHUD v1.6.3

plugins/LethalHUD/LethalHUD.dll

Decompiled 3 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using BetterScanVision;
using GameNetcodeStuff;
using HarmonyLib;
using LethalConfig;
using LethalConfig.ConfigItems;
using LethalConfig.ConfigItems.Options;
using LethalHUD.API;
using LethalHUD.Compats;
using LethalHUD.Configs;
using LethalHUD.CustomHUD;
using LethalHUD.CustomHUD.Refs;
using LethalHUD.HUD;
using LethalHUD.Misc;
using LethalHUD.NetcodePatcher;
using LethalHUD.Networking;
using LethalHUD.Scan;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json.Linq;
using SoftMasking;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("BepInEx")]
[assembly: IgnoresAccessChecksTo("BetterScanVision")]
[assembly: IgnoresAccessChecksTo("com.olegknyazev.softmask")]
[assembly: IgnoresAccessChecksTo("EladsHUD")]
[assembly: IgnoresAccessChecksTo("GoodItemScan")]
[assembly: IgnoresAccessChecksTo("Newtonsoft.Json")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("UnityEngine")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("s1ckboy")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright © 2025 s1ckboy")]
[assembly: AssemblyFileVersion("1.6.3.0")]
[assembly: AssemblyInformationalVersion("1.6.3+5f1b5c4d671b2cdaf0ce01d31de5da6200f46dae")]
[assembly: AssemblyProduct("LethalHUD")]
[assembly: AssemblyTitle("LethalHUD")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.6.3.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
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 LethalHUD
{
	public static class Enums
	{
		public enum ScanNodeType
		{
			Default,
			Scrap,
			Creature
		}

		public enum LoadingScreenPackMode
		{
			SinglePack,
			SelectedPacks,
			AllPacks
		}

		public enum SelfRedMode
		{
			Vanilla,
			ColoredFilled,
			RedFillUp
		}

		public enum BillboardGradientMode
		{
			Static,
			Wave,
			Pulse
		}

		public enum VertexGradientLayout
		{
			Horizontal,
			Vertical,
			Diagonal
		}

		public enum SlotEnums
		{
			None,
			Rainbow,
			Summer,
			Winter,
			Vaporwave,
			Deepmint,
			Radioactive,
			TideEmber
		}

		public enum ItemValue
		{
			Default,
			Dollar
		}

		public enum ScanMode
		{
			Default,
			Hold,
			Toggle
		}

		public enum BatteryTextDisplayMode
		{
			Number,
			Percent
		}

		public enum WeightDisplayLayout
		{
			Config,
			Vertical,
			Horizontal,
			ASCII
		}

		public enum WeightUnit
		{
			Pounds,
			Kilograms,
			Manuls
		}

		public enum WeightUnitDisplay
		{
			OnlyOne,
			KgAndPounds,
			PoundsAndManuls,
			KgAndManuls,
			KgPoundsAndManuls
		}

		public enum WeightDecimalFormat
		{
			Rounded,
			TwoDecimalsDot,
			TwoDecimalsComma
		}

		public enum MTColorMode
		{
			Solid,
			Gradient
		}

		public enum SprintStyle
		{
			Solid,
			Shades,
			Gradient
		}

		public enum ClockStyle
		{
			Regular,
			Compact
		}

		public enum HPDisplayMode
		{
			Plain,
			Percent,
			Label
		}

		public enum FPSPingLayout
		{
			Vertical,
			Horizontal
		}

		public enum TotalValuePrefix
		{
			Full,
			Short,
			None
		}

		internal static Color solarFlare = new Color(1f, 0.8f, 0.3f);

		internal static Color moltenCore = new Color(1f, 0.2f, 0f);

		internal static Color skyWave = new Color(0.4f, 0.65f, 1f);

		internal static Color moonlitMist = new Color(0.8f, 0.8f, 1f);

		internal static Color pinkPrism = new Color(1f, 0.4f, 1f);

		internal static Color aquaPulse = new Color(0.4f, 1f, 1f);

		internal static Color mintWave = new Color(0.5647f, 0.8706f, 0.7843f);

		internal static Color deepTeal = new Color(0.1608f, 0.2863f, 0.2549f);

		internal static Color neonLime = new Color(0.443f, 0.78f, 0f);

		internal static Color lemonGlow = new Color(0.941f, 1f, 0.471f);

		internal static Color crimsonSpark = new Color(1f, 0.27f, 0f);

		internal static Color deepOcean = new Color(0f, 0.48f, 0.54f);

		private static readonly float _baseIntensity = 352.08f;

		private static readonly float _customBaseIntensity = 100f;

		internal static void DirtIntensityHandlerByScanLine()
		{
			Bloom scanBloom = ScanController.ScanBloom;
			if (!((Object)(object)scanBloom == (Object)null))
			{
				string value = Plugins.ConfigEntries.SelectedScanlineMode.Value;
				if (value == "Default")
				{
					((VolumeParameter<float>)(object)scanBloom.dirtIntensity).Override(Mathf.Max(0f, _baseIntensity + Plugins.ConfigEntries.DirtIntensity.Value));
				}
				else
				{
					((VolumeParameter<float>)(object)scanBloom.dirtIntensity).Override(Mathf.Max(0f, _customBaseIntensity + Plugins.ConfigEntries.DirtIntensity.Value));
				}
			}
		}
	}
	internal class Loggers
	{
		private static void Log(LogLevel logLevel, object data)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			Plugins.Logger.Log(logLevel, data);
		}

		internal static void Info(object data)
		{
			Log((LogLevel)16, data);
		}

		internal static void Debug(object data)
		{
			Log((LogLevel)32, data);
		}

		internal static void Message(object data)
		{
			Log((LogLevel)8, data);
		}

		internal static void Warning(object data)
		{
			Log((LogLevel)4, data);
		}

		internal static void Error(object data)
		{
			Log((LogLevel)2, data);
		}

		internal static void Fatal(object data)
		{
			Log((LogLevel)1, data);
		}
	}
	[BepInPlugin("LethalHUD", "LethalHUD", "1.6.3")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugins : BaseUnityPlugin
	{
		internal struct ScanNodeTextures
		{
			public Sprite Outer;

			public Sprite Inner;
		}

		internal static readonly Dictionary<string, StyleEntry<GameObject>> HealthBarPrefabs = new Dictionary<string, StyleEntry<GameObject>>();

		internal static readonly Dictionary<string, StyleEntry<GameObject>> StaminaBarPrefabs = new Dictionary<string, StyleEntry<GameObject>>();

		internal static readonly Dictionary<string, StyleEntry<GameObject>> BatteryPrefabs = new Dictionary<string, StyleEntry<GameObject>>();

		internal static readonly Dictionary<string, StyleEntry<GameObject>> SlotPrefabs = new Dictionary<string, StyleEntry<GameObject>>();

		internal static Dictionary<string, string> ScanlineDisplayToKey = new Dictionary<string, string>();

		internal static Dictionary<string, StyleEntry<Texture2D>> ScanlineTextures = new Dictionary<string, StyleEntry<Texture2D>>();

		internal static Dictionary<string, StyleEntry<ScanNodeTextures>> ScanNodeSprites = new Dictionary<string, StyleEntry<ScanNodeTextures>>();

		internal static Texture2D DefaultScanlineTexture;

		internal static ScanNodeTextures DefaultScanNodeSprites;

		internal static bool NetworkingDisabled;

		internal static Plugins Instance { get; private set; }

		internal static Harmony Harmony { get; private set; }

		internal static ManualLogSource Logger { get; private set; }

		internal static ConfigFile Config { get; private set; }

		internal static ConfigEntries ConfigEntries { get; private set; }

		public void Awake()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			Harmony = new Harmony("LethalHUD");
			Logger = Logger.CreateLogSource("LethalHUD");
			ConfigFile val = ConfigUtils.CreateLocalConfigFile((BaseUnityPlugin)(object)this, "bootstrap", saveOnInit: true);
			ConfigEntry<bool> val2 = val.Bind<bool>("Main", "Use Local Config", false, "If enabled, uses a local config file instead of the global config. Requires restart.");
			ConfigEntry<bool> val3 = val.Bind<bool>("Main", "Disable Networked Features", false, "If enabled, disables all networked features. Requires restart.");
			bool value = val2.Value;
			NetworkingDisabled = val3.Value;
			if (!NetworkingDisabled)
			{
				SerializeNetworkVariables();
			}
			else
			{
				Loggers.Info("Networked HUD features are disabled via bootstrap config.");
			}
			Config = (value ? ConfigUtils.CreateLocalConfigFile((BaseUnityPlugin)(object)this) : ConfigUtils.CreateGlobalConfigFile((BaseUnityPlugin)(object)this));
			BundleLoader.Init();
			ImageLoader.LoadFromFolders();
			ConfigEntries = new ConfigEntries();
			Harmony.PatchAll();
			val.Save();
			Loggers.Info("Plugin LethalHUD loaded!");
		}

		private static void SerializeNetworkVariables()
		{
			NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedByMemcpy<PlayerColorInfo>();
			NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedIEquatable<PlayerColorInfo>();
		}

		internal static void CacheDefaults()
		{
			CacheDefaultScanline();
			CacheDefaultScannodes();
		}

		private static void CacheDefaultScanline()
		{
			if ((Object)(object)DefaultScanlineTexture != (Object)null)
			{
				return;
			}
			Bloom scanBloom = ScanController.ScanBloom;
			if (!((Object)(object)scanBloom == (Object)null))
			{
				Texture value = ((VolumeParameter<Texture>)(object)scanBloom.dirtTexture).value;
				Texture2D val = (Texture2D)(object)((value is Texture2D) ? value : null);
				if (val != null)
				{
					DefaultScanlineTexture = val;
					ScanlineTextures["Default"] = new StyleEntry<Texture2D>
					{
						Name = "Default",
						ModName = "Vanilla",
						Asset = val
					};
					Logger.LogInfo((object)"Cached vanilla scanline texture.");
				}
			}
		}

		private static void CacheDefaultScannodes()
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			if ((Object)(object)DefaultScanNodeSprites.Inner != (Object)null)
			{
				return;
			}
			GameObject val = GameObject.Find("UI/Canvas/ObjectScanner");
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			foreach (Transform item in val.transform)
			{
				Transform val2 = item;
				if (((Object)val2).name.StartsWith("ScanObject"))
				{
					Transform obj = val2.Find("Circle/Inner");
					Image val3 = ((obj != null) ? ((Component)obj).GetComponent<Image>() : null);
					Transform obj2 = val2.Find("Circle/Outer");
					Image val4 = ((obj2 != null) ? ((Component)obj2).GetComponent<Image>() : null);
					if (!((Object)(object)val3 == (Object)null) && !((Object)(object)val4 == (Object)null))
					{
						DefaultScanNodeSprites = new ScanNodeTextures
						{
							Inner = val3.sprite,
							Outer = val4.sprite
						};
						ScanNodeSprites["Default"] = new StyleEntry<ScanNodeTextures>
						{
							Name = "Default",
							ModName = "Vanilla",
							Asset = DefaultScanNodeSprites
						};
						Logger.LogInfo((object)"Cached vanilla scannode sprites.");
						break;
					}
				}
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "LethalHUD";

		public const string PLUGIN_NAME = "LethalHUD";

		public const string PLUGIN_VERSION = "1.6.3";
	}
}
namespace LethalHUD.Scan
{
	internal static class ScanController
	{
		private const float ScanDuration = 1.3f;

		private static Texture2D _lastRecoloredTexture;

		private static MeshRenderer _scanRenderer;

		private static Volume _cachedScanVolume;

		private static Material _scanMat;

		private static MeshRenderer ScanRenderer
		{
			get
			{
				if ((Object)(object)_scanRenderer == (Object)null && (Object)(object)HUDManager.Instance != (Object)null)
				{
					Animator scanEffectAnimator = HUDManager.Instance.scanEffectAnimator;
					if ((Object)(object)scanEffectAnimator != (Object)null)
					{
						_scanRenderer = ((Component)scanEffectAnimator).GetComponent<MeshRenderer>();
					}
				}
				return _scanRenderer;
			}
		}

		private static Volume ScanVolume
		{
			get
			{
				if ((Object)(object)_cachedScanVolume == (Object)null)
				{
					GameObject val = GameObject.Find("Systems/Rendering/ScanSphere/ScanVolume");
					if ((Object)(object)val != (Object)null)
					{
						_cachedScanVolume = val.GetComponent<Volume>();
					}
				}
				return _cachedScanVolume;
			}
		}

		private static Vignette ScanVignette
		{
			get
			{
				if ((Object)(object)ScanVolume == (Object)null)
				{
					return null;
				}
				if ((Object)(object)ScanVolume.profile == (Object)null)
				{
					return null;
				}
				return ScanVolume.profile.components?.OfType<Vignette>().FirstOrDefault();
			}
		}

		internal static Bloom ScanBloom
		{
			get
			{
				if ((Object)(object)ScanVolume == (Object)null)
				{
					return null;
				}
				if ((Object)(object)ScanVolume.profile == (Object)null)
				{
					return null;
				}
				return ScanVolume.profile.components?.OfType<Bloom>().FirstOrDefault();
			}
		}

		private static float ScanProgress
		{
			get
			{
				if ((Object)(object)HUDManager.Instance == (Object)null)
				{
					return 0f;
				}
				return (HUDManager.Instance.playerPingingScan + 1f) / 1.3f;
			}
		}

		private static bool IsInspecting
		{
			get
			{
				if ((Object)(object)StartOfRound.Instance == (Object)null)
				{
					return false;
				}
				if ((Object)(object)StartOfRound.Instance.localPlayerController == (Object)null)
				{
					return false;
				}
				return StartOfRound.Instance.localPlayerController.IsInspectingItem;
			}
		}

		private static Material ScanMaterial
		{
			get
			{
				if ((Object)(object)_scanMat == (Object)null && (Object)(object)ScanRenderer != (Object)null)
				{
					_scanMat = ((Renderer)ScanRenderer).sharedMaterial;
				}
				return _scanMat;
			}
		}

		private static void SetScanColorAlpha(float alpha)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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)
			if (!((Object)(object)ScanMaterial == (Object)null))
			{
				Color color = ScanMaterial.color;
				color.a = alpha;
				ScanMaterial.color = color;
			}
		}

		internal static void SetScanColor(Color? overrideColor = null)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: 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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			if (!IsInspecting)
			{
				Color val = (overrideColor.HasValue ? overrideColor.Value : ConfigHelper.GetScanColor());
				if (ModCompats.IsBetterScanVisionPresent)
				{
					BetterScanVisionProxy.OverrideNightVisionColor();
				}
				if ((Object)(object)ScanMaterial != (Object)null)
				{
					ScanMaterial.color = val;
				}
				Vignette scanVignette = ScanVignette;
				if ((Object)(object)scanVignette != (Object)null)
				{
					((VolumeParameter<Color>)(object)scanVignette.color).Override(val);
					UpdateVignetteIntensity();
				}
				Bloom scanBloom = ScanBloom;
				if ((Object)(object)scanBloom != (Object)null)
				{
					((VolumeParameter<Color>)(object)scanBloom.tint).Override(val);
					UpdateScanTexture();
				}
			}
		}

		internal static void UpdateScanAlpha()
		{
			if (!((Object)(object)HUDManager.Instance == (Object)null) && !((Object)(object)ScanRenderer == (Object)null) && !IsInspecting)
			{
				float value = Plugins.ConfigEntries.Alpha.Value;
				float num = value;
				if (Plugins.ConfigEntries.FadeOut.Value && HUDManager.Instance.playerPingingScan > -1f)
				{
					num *= ScanProgress;
				}
				SetScanColorAlpha(num);
			}
		}

		internal static void UpdateVignetteIntensity()
		{
			if (!IsInspecting)
			{
				Vignette scanVignette = ScanVignette;
				if ((Object)(object)scanVignette != (Object)null)
				{
					((VolumeParameter<float>)(object)scanVignette.intensity).Override(Plugins.ConfigEntries.VignetteIntensity.Value);
				}
			}
		}

		internal static void UpdateScanTexture()
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			Bloom scanBloom = ScanBloom;
			if ((Object)(object)scanBloom == (Object)null || IsInspecting)
			{
				return;
			}
			Enums.DirtIntensityHandlerByScanLine();
			Texture2D selectedTexture = GetSelectedTexture();
			if (!((Object)(object)selectedTexture == (Object)null))
			{
				if (Plugins.ConfigEntries.RecolorScanLines.Value)
				{
					RecolorAndApplyTexture(ConfigHelper.GetScanColor(), selectedTexture);
				}
				else
				{
					((VolumeParameter<Texture>)(object)scanBloom.dirtTexture).Override((Texture)(object)selectedTexture);
				}
			}
		}

		private static void RecolorAndApplyTexture(Color color, Texture2D baseTex)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			Texture2D readableTexture = HUDUtils.GetReadableTexture(baseTex);
			Texture2D texture = new Texture2D(((Texture)readableTexture).width, ((Texture)readableTexture).height, (TextureFormat)4, false);
			texture.SetPixels(readableTexture.GetPixels());
			HUDUtils.RecolorTexture(ref texture, color);
			texture.Apply(true, false);
			if ((Object)(object)_lastRecoloredTexture != (Object)null)
			{
				Object.Destroy((Object)(object)_lastRecoloredTexture);
			}
			_lastRecoloredTexture = texture;
			Bloom scanBloom = ScanBloom;
			if ((Object)(object)scanBloom != (Object)null)
			{
				((VolumeParameter<Texture>)(object)scanBloom.dirtTexture).Override((Texture)(object)_lastRecoloredTexture);
			}
		}

		private static Texture2D GetSelectedTexture()
		{
			string text = Plugins.ConfigEntries.SelectedScanlineMode.Value;
			if (text == "Default")
			{
				return Plugins.DefaultScanlineTexture;
			}
			if (Plugins.ScanlineDisplayToKey.TryGetValue(text, out var value))
			{
				text = value;
			}
			if (Plugins.ScanlineTextures.TryGetValue(text, out var value2) && (Object)(object)value2.Asset != (Object)null)
			{
				return value2.Asset;
			}
			Loggers.Warning("Scanline texture '" + text + "' missing. Falling back to Default.");
			return Plugins.DefaultScanlineTexture;
		}
	}
	internal static class ScanNodeClassifier
	{
		internal static Enums.ScanNodeType GetType(ScanNodeProperties node)
		{
			if ((Object)(object)node == (Object)null)
			{
				return Enums.ScanNodeType.Default;
			}
			return node.nodeType switch
			{
				2 => Enums.ScanNodeType.Scrap, 
				1 => Enums.ScanNodeType.Creature, 
				_ => Enums.ScanNodeType.Default, 
			};
		}
	}
	internal static class ScanNodeController
	{
		internal static float lifetime = Plugins.ConfigEntries.ScanNodeLifetime.Value;

		internal static float fadeDuration = Plugins.ConfigEntries.ScanNodeFadeDuration.Value;

		private static readonly Dictionary<ScanNodeProperties, float> _nodeAppearTimes = new Dictionary<ScanNodeProperties, float>();

		private static readonly HashSet<ScanNodeProperties> _seenThisFrame = new HashSet<ScanNodeProperties>();

		private static readonly List<ScanNodeProperties> _toRemove = new List<ScanNodeProperties>();

		private static readonly AnimationCurve _fadeCurve = AnimationCurve.EaseInOut(0f, 1f, 1f, 0f);

		internal static void UpdateTimers(Dictionary<RectTransform, ScanNodeProperties> scanNodes)
		{
			lifetime = Plugins.ConfigEntries.ScanNodeLifetime.Value;
			fadeDuration = Plugins.ConfigEntries.ScanNodeFadeDuration.Value;
			_seenThisFrame.Clear();
			IReadOnlyList<(RectTransform, ScanNodeProperties)> readOnlyList = GoodItemScanProxy.EnumerateAllNodes(scanNodes);
			for (int i = 0; i < readOnlyList.Count; i++)
			{
				var (val, val2) = readOnlyList[i];
				if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || !((Component)val).gameObject.activeInHierarchy)
				{
					continue;
				}
				_seenThisFrame.Add(val2);
				if (!_nodeAppearTimes.TryGetValue(val2, out var value))
				{
					value = Time.time;
					_nodeAppearTimes[val2] = value;
				}
				float num = Time.time - value;
				if (GoodItemScanProxy.IsGoodItemScanNode(val))
				{
					if (num >= lifetime)
					{
						RemoveNode(val, val2, scanNodes);
					}
					continue;
				}
				float num2 = lifetime + Mathf.Max(0f, fadeDuration);
				if (num >= num2)
				{
					RemoveNode(val, val2, scanNodes);
					continue;
				}
				float alpha = 1f;
				if (num > lifetime)
				{
					alpha = ((fadeDuration <= 0f) ? 0f : _fadeCurve.Evaluate(Mathf.Clamp01((num - lifetime) / fadeDuration)));
				}
				ScanNodeTextureManager.ApplyAlpha(val, val2, alpha);
			}
			CleanInvalidNodes();
		}

		private static void RemoveNode(RectTransform element, ScanNodeProperties node, Dictionary<RectTransform, ScanNodeProperties> scanNodes)
		{
			if (ModCompats.IsGoodItemScanPresent && GoodItemScanProxy.TryRemoveNode(element, node))
			{
				_nodeAppearTimes.Remove(node);
				return;
			}
			if ((Object)(object)element != (Object)null)
			{
				((Component)element).gameObject.SetActive(false);
			}
			scanNodes?.Remove(element);
			_nodeAppearTimes.Remove(node);
		}

		private static void CleanInvalidNodes()
		{
			_toRemove.Clear();
			foreach (KeyValuePair<ScanNodeProperties, float> nodeAppearTime in _nodeAppearTimes)
			{
				if ((Object)(object)nodeAppearTime.Key == (Object)null || !_seenThisFrame.Contains(nodeAppearTime.Key))
				{
					_toRemove.Add(nodeAppearTime.Key);
				}
			}
			for (int i = 0; i < _toRemove.Count; i++)
			{
				_nodeAppearTimes.Remove(_toRemove[i]);
			}
		}

		internal static void Reset()
		{
			_nodeAppearTimes.Clear();
			_seenThisFrame.Clear();
			_toRemove.Clear();
		}
	}
	internal static class ScanNodeTextureManager
	{
		private sealed class VisualCache
		{
			internal ScanNodeProperties Node;

			internal Image Inner;

			internal Image Outer;

			internal Image[] Images;

			internal ScanNodeColorMeshEffect[] ColorEffects;

			internal TextMeshProUGUI[] Texts;

			internal bool HandledByDawn;

			internal int LastSeenFrame;

			internal int NextDiscoveryFrame;
		}

		private static readonly Dictionary<RectTransform, VisualCache> _visualCache = new Dictionary<RectTransform, VisualCache>();

		private static readonly List<RectTransform> _deadCacheKeys = new List<RectTransform>();

		private static bool _settingsDirty = true;

		private static string _shapeDefault;

		private static string _shapeScrap;

		private static string _shapeCreature;

		private static string _hexDefault;

		private static string _hexScrap;

		private static string _hexCreature;

		private static Color _colorDefault;

		private static Color _colorScrap;

		private static Color _colorCreature;

		internal static void Tick(Dictionary<RectTransform, ScanNodeProperties> scanNodes)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			RefreshSettingsIfNeeded();
			IReadOnlyList<(RectTransform, ScanNodeProperties)> readOnlyList = GoodItemScanProxy.EnumerateAllNodes(scanNodes);
			for (int i = 0; i < readOnlyList.Count; i++)
			{
				var (val, val2) = readOnlyList[i];
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null))
				{
					VisualCache orRefreshCache = GetOrRefreshCache(val, val2);
					orRefreshCache.LastSeenFrame = Time.frameCount;
					if (orRefreshCache.HandledByDawn)
					{
						ApplyImageColorOverride(orRefreshCache, Color.white, enabled: false);
					}
					else
					{
						Apply(val, val2, orRefreshCache);
					}
				}
			}
			if (Time.frameCount % 300 == 0)
			{
				PruneCache();
			}
		}

		private static VisualCache GetOrRefreshCache(RectTransform rect, ScanNodeProperties node)
		{
			bool flag = false;
			if (!_visualCache.TryGetValue(rect, out var value))
			{
				value = new VisualCache();
				_visualCache[rect] = value;
				flag = true;
			}
			else if ((Object)(object)value.Node != (Object)(object)node)
			{
				flag = true;
			}
			else if (Time.frameCount >= value.NextDiscoveryFrame)
			{
				flag = true;
			}
			if (flag)
			{
				DiscoverVisuals(rect, node, value);
			}
			return value;
		}

		private static void DiscoverVisuals(RectTransform rect, ScanNodeProperties node, VisualCache cache)
		{
			cache.Node = node;
			Transform obj = ((Component)rect).transform.Find("Circle/Inner");
			cache.Inner = ((obj != null) ? ((Component)obj).GetComponent<Image>() : null);
			Transform obj2 = ((Component)rect).transform.Find("Circle/Outer");
			cache.Outer = ((obj2 != null) ? ((Component)obj2).GetComponent<Image>() : null);
			cache.Images = ((Component)rect).GetComponentsInChildren<Image>(true);
			cache.ColorEffects = null;
			cache.Texts = ((Component)rect).GetComponentsInChildren<TextMeshProUGUI>(true);
			cache.HandledByDawn = (Object)(object)((Component)rect).GetComponent("ForceScanColorOnItem") != (Object)null;
			int num = Math.Abs(((Object)rect).GetInstanceID() % 60);
			cache.NextDiscoveryFrame = Time.frameCount + 180 + num;
		}

		private static void Apply(RectTransform rect, ScanNodeProperties node, VisualCache cache)
		{
			//IL_0025: 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_003f: 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_00f6: 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_005e: 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_0115: 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_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: 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_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			if (!((Component)rect).gameObject.activeInHierarchy)
			{
				return;
			}
			Enums.ScanNodeType type = ScanNodeClassifier.GetType(node);
			string key;
			Color val;
			bool flag;
			switch (type)
			{
			case Enums.ScanNodeType.Scrap:
				key = _shapeScrap;
				val = _colorScrap;
				flag = IsDefault(type, _hexScrap);
				break;
			case Enums.ScanNodeType.Creature:
				key = _shapeCreature;
				val = _colorCreature;
				flag = IsDefault(type, _hexCreature);
				break;
			default:
				key = _shapeDefault;
				val = _colorDefault;
				flag = IsDefault(type, _hexDefault);
				break;
			}
			if (Plugins.ScanNodeSprites.TryGetValue(key, out var value))
			{
				Plugins.ScanNodeTextures asset = value.Asset;
				if ((Object)(object)cache.Inner != (Object)null && (Object)(object)cache.Inner.sprite != (Object)(object)asset.Inner)
				{
					cache.Inner.sprite = asset.Inner;
				}
				if ((Object)(object)cache.Outer != (Object)null && (Object)(object)cache.Outer.sprite != (Object)(object)asset.Outer)
				{
					cache.Outer.sprite = asset.Outer;
				}
			}
			ApplyImageColorOverride(cache, val, !flag);
			if (flag)
			{
				return;
			}
			float num = 0.299f * val.r + 0.587f * val.g + 0.114f * val.b;
			Color val2 = ((num > 0.5f) ? Color.black : Color.white);
			TextMeshProUGUI[] texts = cache.Texts;
			if (texts == null)
			{
				return;
			}
			Color val4 = default(Color);
			foreach (TextMeshProUGUI val3 in texts)
			{
				if (!((Object)(object)val3 == (Object)null))
				{
					Color color = ((Graphic)val3).color;
					((Color)(ref val4))..ctor(val2.r, val2.g, val2.b, color.a);
					if (color != val4)
					{
						((Graphic)val3).color = val4;
					}
				}
			}
		}

		private static void ApplyImageColorOverride(VisualCache cache, Color color, bool enabled)
		{
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			Image[] images = cache.Images;
			if (images == null || images.Length == 0)
			{
				return;
			}
			if (cache.ColorEffects == null || cache.ColorEffects.Length != images.Length)
			{
				cache.ColorEffects = new ScanNodeColorMeshEffect[images.Length];
			}
			for (int i = 0; i < images.Length; i++)
			{
				Image val = images[i];
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				ScanNodeColorMeshEffect scanNodeColorMeshEffect = cache.ColorEffects[i];
				if ((Object)(object)scanNodeColorMeshEffect == (Object)null)
				{
					scanNodeColorMeshEffect = ((Component)val).GetComponent<ScanNodeColorMeshEffect>();
					if ((Object)(object)scanNodeColorMeshEffect == (Object)null && !enabled)
					{
						continue;
					}
					if ((Object)(object)scanNodeColorMeshEffect == (Object)null)
					{
						scanNodeColorMeshEffect = ((Component)val).gameObject.AddComponent<ScanNodeColorMeshEffect>();
					}
					cache.ColorEffects[i] = scanNodeColorMeshEffect;
				}
				if (enabled)
				{
					scanNodeColorMeshEffect.SetColor(color);
				}
				else
				{
					scanNodeColorMeshEffect.ClearColor();
				}
			}
		}

		internal static void ApplyAlpha(RectTransform rect, ScanNodeProperties node, float alpha)
		{
			//IL_003c: 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_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)rect == (Object)null)
			{
				return;
			}
			VisualCache orRefreshCache = GetOrRefreshCache(rect, node);
			orRefreshCache.LastSeenFrame = Time.frameCount;
			Image[] images = orRefreshCache.Images;
			if (images != null)
			{
				foreach (Image val in images)
				{
					if (!((Object)(object)val == (Object)null))
					{
						Color color = ((Graphic)val).color;
						if (!Mathf.Approximately(color.a, alpha))
						{
							color.a = alpha;
							((Graphic)val).color = color;
						}
					}
				}
			}
			TextMeshProUGUI[] texts = orRefreshCache.Texts;
			if (texts == null)
			{
				return;
			}
			foreach (TextMeshProUGUI val2 in texts)
			{
				if (!((Object)(object)val2 == (Object)null))
				{
					Color color2 = ((Graphic)val2).color;
					if (!Mathf.Approximately(color2.a, alpha))
					{
						color2.a = alpha;
						((Graphic)val2).color = color2;
					}
				}
			}
		}

		private static void RefreshSettingsIfNeeded()
		{
			//IL_00eb: 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_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_0109: 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)
			string value = Plugins.ConfigEntries.ScanNodeShape_Default.Value;
			string value2 = Plugins.ConfigEntries.ScanNodeShape_Scrap.Value;
			string value3 = Plugins.ConfigEntries.ScanNodeShape_Creature.Value;
			string value4 = Plugins.ConfigEntries.ScanNodeColor_Default.Value;
			string value5 = Plugins.ConfigEntries.ScanNodeColor_Scrap.Value;
			string value6 = Plugins.ConfigEntries.ScanNodeColor_Creature.Value;
			if (_settingsDirty || !(value == _shapeDefault) || !(value2 == _shapeScrap) || !(value3 == _shapeCreature) || !(value4 == _hexDefault) || !(value5 == _hexScrap) || !(value6 == _hexCreature))
			{
				_settingsDirty = false;
				_shapeDefault = value;
				_shapeScrap = value2;
				_shapeCreature = value3;
				_hexDefault = value4;
				_hexScrap = value5;
				_hexCreature = value6;
				_colorDefault = HUDUtils.ParseHexColor(_hexDefault);
				_colorScrap = HUDUtils.ParseHexColor(_hexScrap);
				_colorCreature = HUDUtils.ParseHexColor(_hexCreature);
			}
		}

		private static bool IsDefault(Enums.ScanNodeType type, string hex)
		{
			return type switch
			{
				Enums.ScanNodeType.Scrap => hex.Equals("#38AB00", StringComparison.OrdinalIgnoreCase), 
				Enums.ScanNodeType.Creature => hex.Equals("#FF0A00", StringComparison.OrdinalIgnoreCase), 
				_ => hex.Equals("#0B00B2", StringComparison.OrdinalIgnoreCase), 
			};
		}

		private static void PruneCache()
		{
			_deadCacheKeys.Clear();
			foreach (KeyValuePair<RectTransform, VisualCache> item in _visualCache)
			{
				if ((Object)(object)item.Key == (Object)null || Time.frameCount - item.Value.LastSeenFrame > 600)
				{
					_deadCacheKeys.Add(item.Key);
				}
			}
			for (int i = 0; i < _deadCacheKeys.Count; i++)
			{
				_visualCache.Remove(_deadCacheKeys[i]);
			}
		}

		internal static void ForceRefresh()
		{
			_settingsDirty = true;
		}

		internal static void Reset()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			foreach (VisualCache value in _visualCache.Values)
			{
				ApplyImageColorOverride(value, Color.white, enabled: false);
			}
			_visualCache.Clear();
			_deadCacheKeys.Clear();
			_settingsDirty = true;
		}
	}
	internal sealed class ScanNodeColorMeshEffect : BaseMeshEffect
	{
		private Color32 _targetColor = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue);

		internal void SetColor(Color color)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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_0025: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			Color32 val = Color32.op_Implicit(color);
			bool flag = _targetColor.r != val.r || _targetColor.g != val.g || _targetColor.b != val.b;
			_targetColor = val;
			if (!((Behaviour)this).enabled)
			{
				((Behaviour)this).enabled = true;
			}
			else if (flag && (Object)(object)((BaseMeshEffect)this).graphic != (Object)null)
			{
				((BaseMeshEffect)this).graphic.SetVerticesDirty();
			}
		}

		internal void ClearColor()
		{
			if (((Behaviour)this).enabled)
			{
				((Behaviour)this).enabled = false;
			}
		}

		public override void ModifyMesh(VertexHelper vertexHelper)
		{
			//IL_000e: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: 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_0061: Unknown result type (might be due to invalid IL or missing references)
			if (((UIBehaviour)this).IsActive() && vertexHelper != null)
			{
				UIVertex val = default(UIVertex);
				int currentVertCount = vertexHelper.currentVertCount;
				for (int i = 0; i < currentVertCount; i++)
				{
					vertexHelper.PopulateUIVertex(ref val, i);
					val.color = new Color32(_targetColor.r, _targetColor.g, _targetColor.b, val.color.a);
					vertexHelper.SetUIVertex(val, i);
				}
			}
		}
	}
}
namespace LethalHUD.Patches
{
	[HarmonyPatch(typeof(GameNetworkManager))]
	internal static class GameNetworkManagerPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("NoPunctuation")]
		private static bool NoPunctuation_Prefix(string input, ref string __result)
		{
			__result = ChatController.NoPunctuation(input);
			return false;
		}
	}
	[HarmonyPatch(typeof(HUDManager))]
	internal static class HUDManagerPatch
	{
		private static InputAction _pingScanAction;

		private static CallbackContext _pingScan;

		private static bool _isScanToggled;

		private static Coroutine _toggleCoroutine;

		[HarmonyPrefix]
		[HarmonyPatch("PingScan_performed")]
		private static void OnScanTriggered_Prefix(ref CallbackContext context)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			_pingScan = context;
			LootInfoManager.LootScan();
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(HUDManager), "DisplaySignalTranslatorMessage")]
		private static bool OnHUDManagerDisplaySignalTranslatorMessage_Prefix(string signalMessage, int seed, SignalTranslator signalTranslator, ref IEnumerator __result)
		{
			if ((Object)(object)signalTranslator != (Object)null && !string.IsNullOrEmpty(signalMessage))
			{
				__result = SignalTranslatorController.DisplaySignalTranslatorMessage(signalMessage, seed, signalTranslator);
				return false;
			}
			return true;
		}

		[HarmonyPrefix]
		[HarmonyPatch("DisableAllScanElements")]
		private static void OnHUDManagerDisabledAllScanElements_Prefix()
		{
		}

		[HarmonyPostfix]
		[HarmonyPatch("SetClockVisible")]
		private static void OnHUDManagerSetClockVisible_Postfix(HUDManager __instance, bool visible)
		{
			ClockController.UpdateClockVisibility(ref visible);
			ClockController.ApplyClockAlpha(__instance, visible);
		}

		[HarmonyPrefix]
		[HarmonyPatch("UpdateHealthUI")]
		private static bool OnHUDManagerUpdateHealthUI_Prefix()
		{
			return !CustomHealthBar.UsingCustom;
		}

		[HarmonyPostfix]
		[HarmonyPatch("Start")]
		private static void OnHUDManagerStart_Postfix(HUDManager __instance)
		{
			InventoryFrames.ResetCache();
			WeightController.ResetCache();
			CompassController.ResetCache();
			SignalTranslatorController.ResetCache();
			PlanetInfoDisplay.ResetCache();
			HUDUtils.ResetLoadingTextCache();
			ScanNodeTextureManager.Reset();
			ScanNodeController.Reset();
			Plugins.CacheDefaults();
			ScrapValueDisplay.ResetForNewHUD();
			_pingScanAction = IngamePlayerSettings.Instance.playerInput.actions.FindAction("PingScan", false);
			ScanController.SetScanColor();
			ScanController.UpdateScanTexture();
			PlayerHPDisplay.Init();
			ScrapValueDisplay.Init();
			ClockController.ApplyClockAppearance();
			PlanetInfoDisplay.ApplyColors();
			SpectatorHUDController.ApplyColors();
			CustomBattery.Init();
			if (ModCompats.IsBetterScanVisionPresent)
			{
				BetterScanVisionProxy.OverrideNightVisionColor();
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("OnEnable")]
		private static void OnHUDManagerEnable_Postfix(HUDManager __instance)
		{
			if ((Object)(object)((Component)__instance).gameObject.GetComponent<LethalHUDMono>() == (Object)null)
			{
				((Component)__instance).gameObject.AddComponent<LethalHUDMono>();
			}
			if ((Object)(object)((Component)__instance).gameObject.GetComponent<StatsDisplay>() == (Object)null)
			{
				((Component)__instance).gameObject.AddComponent<StatsDisplay>();
			}
			CustomFrames.OnHUDEnable(__instance);
			CanvasGroup selfRedCanvasGroup = __instance.selfRedCanvasGroup;
			if (!((Object)(object)selfRedCanvasGroup == (Object)null))
			{
				PlayerRedCanvasController.Bind(selfRedCanvasGroup);
				CustomHealthBar.OnHUDEnable(__instance);
				ChatController.ColorChatInputField(HUDManager.Instance.chatTextField, Time.time * 0.25f);
				((MonoBehaviour)__instance).StartCoroutine(ApplySelfRedAfterTick(__instance));
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("OnDisable")]
		private static void OnHUDManagerDisable_Postfix(HUDManager __instance)
		{
			CustomFrames.OnHUDDisable(__instance);
		}

		[HarmonyPostfix]
		[HarmonyPatch("DisplayNewScrapFound")]
		private static void OnHUDManagerDisplayNewScrapFound_Postfix()
		{
			InventoryFrames.SetSlotColors();
		}

		[HarmonyPostfix]
		[HarmonyPatch("SetClock")]
		private static void OnHUDManagerSetClock_Postfix(HUDManager __instance, float timeNormalized, float numberOfHours)
		{
			ClockController.TryOverrideClock(__instance, timeNormalized, numberOfHours);
		}

		[HarmonyPostfix]
		[HarmonyPatch("Update")]
		private static void OnHUDManagerUpdate_Postfix(HUDManager __instance)
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			ScanController.UpdateScanAlpha();
			PlayerHPDisplay.UpdateNumber();
			ScanNodeTextureManager.Tick(__instance.scanNodes);
			if (Plugins.ConfigEntries.ScanNodeFade.Value)
			{
				ScanNodeController.UpdateTimers(__instance.scanNodes);
			}
			switch (Plugins.ConfigEntries.ScanModeType.Value)
			{
			case Enums.ScanMode.Default:
				StopToggleScan(__instance);
				break;
			case Enums.ScanMode.Hold:
				StopToggleScan(__instance);
				if (_pingScanAction.IsPressed())
				{
					__instance.PingScan_performed(_pingScan);
				}
				break;
			case Enums.ScanMode.Toggle:
				if (_pingScanAction.WasPressedThisFrame())
				{
					if (_isScanToggled)
					{
						StopToggleScan(__instance);
					}
					else
					{
						StartToggleScan(__instance);
					}
				}
				break;
			}
			if (CustomHealthBar.UsingCustom && (Object)(object)__instance.localPlayer != (Object)null)
			{
				CustomHealthBar.UpdateFromPlayer(__instance.localPlayer);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("UpdateHealthUI")]
		private static void OnHUDManagerUpdateHealthUI_Postfix(int health)
		{
			if (!CustomHealthBar.UsingCustom)
			{
				switch (Plugins.ConfigEntries.SelfRedCanvasMode.Value)
				{
				case Enums.SelfRedMode.Vanilla:
					break;
				case Enums.SelfRedMode.ColoredFilled:
					PlayerRedCanvasController.ApplyFillAndColor(health);
					break;
				case Enums.SelfRedMode.RedFillUp:
					PlayerRedCanvasController.ApplyFillWithRedFade(health);
					break;
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("AddChatMessage")]
		private static void OnHUDManagerAddChatMessage_Postfix(HUDManager __instance, string chatMessage, string nameOfUserWhoTyped, int playerWhoSent)
		{
			if (__instance.ChatMessageHistory == null || __instance.ChatMessageHistory.Count <= 0)
			{
				return;
			}
			int num = __instance.ChatMessageHistory.Count - 1;
			if (num < 0)
			{
				return;
			}
			string value;
			if (!string.IsNullOrEmpty(nameOfUserWhoTyped))
			{
				if (string.IsNullOrWhiteSpace(chatMessage))
				{
					return;
				}
				string coloredPlayerName = ChatController.GetColoredPlayerName(nameOfUserWhoTyped, playerWhoSent);
				string text = ColorChatMessageSafe(chatMessage);
				if (string.IsNullOrWhiteSpace(text))
				{
					return;
				}
				value = coloredPlayerName + ": " + text;
			}
			else
			{
				string text2 = __instance.ChatMessageHistory[num];
				if (string.IsNullOrWhiteSpace(text2))
				{
					return;
				}
				value = ColorChatMessageSafe(text2);
				if (string.IsNullOrWhiteSpace(value))
				{
					return;
				}
			}
			__instance.ChatMessageHistory[num] = value;
			StringBuilder stringBuilder = new StringBuilder();
			for (int i = 0; i < __instance.ChatMessageHistory.Count; i++)
			{
				string value2 = __instance.ChatMessageHistory[i];
				if (!string.IsNullOrWhiteSpace(value2))
				{
					stringBuilder.Append('\n');
					stringBuilder.Append(value2);
				}
			}
			((TMP_Text)__instance.chatText).text = stringBuilder.ToString();
			__instance.PingHUDElement(__instance.Chat, Plugins.ConfigEntries.ChatFadeDelayTime.Value, 1f, 0f);
		}

		private static string ColorChatMessageSafe(string message)
		{
			if (string.IsNullOrWhiteSpace(message))
			{
				return message;
			}
			if (message.Contains("<color=") || message.Contains("<gradient="))
			{
				return message;
			}
			Match match = Regex.Match(message, "^(<[^>]+>)+");
			string text = "";
			string text2 = message;
			if (match.Success)
			{
				text = match.Value;
				int length = match.Length;
				text2 = message.Substring(length, message.Length - length);
			}
			if (string.IsNullOrWhiteSpace(text2))
			{
				return message;
			}
			string coloredChatMessage = ChatController.GetColoredChatMessage(text2);
			if (!string.IsNullOrWhiteSpace(coloredChatMessage))
			{
				return text + coloredChatMessage;
			}
			return message;
		}

		[HarmonyPostfix]
		[HarmonyPatch("OpenMenu_performed")]
		private static void OnHUDManagerOpenMenu_performed_Postfix(HUDManager __instance)
		{
			__instance.PingHUDElement(__instance.Chat, Plugins.ConfigEntries.ChatFadeDelayTime.Value, 1f, 0f);
		}

		[HarmonyPostfix]
		[HarmonyPatch("ChangeControlTipMultiple")]
		private static void AfterChangeControlTipMultiple_Postfix()
		{
			ControlTipController.ApplyColor();
		}

		[HarmonyPostfix]
		[HarmonyPatch("ClearControlTips")]
		private static void AfterClearControlTips_Postfix()
		{
			ControlTipController.ApplyColor();
		}

		private static void StartToggleScan(HUDManager __instance)
		{
			if (_toggleCoroutine == null)
			{
				_isScanToggled = true;
				_toggleCoroutine = ((MonoBehaviour)__instance).StartCoroutine(ToggleScanRoutine(__instance));
			}
		}

		private static void StopToggleScan(HUDManager __instance)
		{
			if (_toggleCoroutine != null)
			{
				((MonoBehaviour)__instance).StopCoroutine(_toggleCoroutine);
				_toggleCoroutine = null;
				_isScanToggled = false;
			}
		}

		private static IEnumerator ToggleScanRoutine(HUDManager __instance)
		{
			while (true)
			{
				TryPerformScan(__instance);
				yield return null;
			}
		}

		private static void TryPerformScan(HUDManager __instance)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
			if ((Object)(object)localPlayerController == (Object)null)
			{
				return;
			}
			float playerPingingScan = __instance.playerPingingScan;
			if (!(playerPingingScan > -1f) && __instance.CanPlayerScan())
			{
				if (GoodItemScanProxy.TryScan())
				{
					LootInfoManager.LootScan();
					return;
				}
				__instance.playerPingingScan = 0.3f;
				((Component)__instance.scanEffectAnimator).transform.position = ((Component)localPlayerController.gameplayCamera).transform.position;
				__instance.scanEffectAnimator.SetTrigger("scan");
				__instance.PingHUDElement(__instance.Compass, 1f, 0.8f, 0.12f);
				__instance.UIAudio.PlayOneShot(__instance.scanSFX);
				LootInfoManager.LootScan();
			}
		}

		private static IEnumerator ApplySelfRedAfterTick(HUDManager hud)
		{
			yield return null;
			if ((Object)(object)hud == (Object)null || (Object)(object)hud.selfRedCanvasGroup == (Object)null)
			{
				yield break;
			}
			PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
			if (!((Object)(object)localPlayerController == (Object)null))
			{
				int health = localPlayerController.health;
				switch (Plugins.ConfigEntries.SelfRedCanvasMode.Value)
				{
				case Enums.SelfRedMode.Vanilla:
					break;
				case Enums.SelfRedMode.ColoredFilled:
					PlayerRedCanvasController.ApplyFillAndColor(health);
					break;
				case Enums.SelfRedMode.RedFillUp:
					PlayerRedCanvasController.ApplyFillWithRedFade(health);
					break;
				}
			}
		}

		private static string ColorMessagePreservingPrefixTags(string message)
		{
			if (string.IsNullOrEmpty(message))
			{
				return message;
			}
			if (message.Contains("<color=", StringComparison.OrdinalIgnoreCase) || message.Contains("<gradient=", StringComparison.OrdinalIgnoreCase))
			{
				return message;
			}
			Match match = Regex.Match(message, "^(<[^>]+>)+");
			string text = "";
			string message2 = message;
			if (match.Success)
			{
				text = match.Value;
				int length = match.Length;
				message2 = message.Substring(length, message.Length - length);
			}
			return text + ChatController.GetColoredChatMessage(message2);
		}
	}
	[HarmonyPatch(typeof(TextDropDownConfigItem), "CreateGameObjectForConfig")]
	internal static class LethalConfigPatch
	{
		internal static readonly Dictionary<TextDropDownConfigItem, List<TextMeshProUGUI>> Bindings = new Dictionary<TextDropDownConfigItem, List<TextMeshProUGUI>>();

		private static void Postfix(TextDropDownConfigItem __instance, ref GameObject __result)
		{
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__result == (Object)null)
			{
				return;
			}
			TMP_Dropdown componentInChildren = __result.GetComponentInChildren<TMP_Dropdown>();
			if ((Object)(object)componentInChildren == (Object)null)
			{
				return;
			}
			TextMeshProUGUI[] componentsInChildren = __result.GetComponentsInChildren<TextMeshProUGUI>(true);
			if (componentsInChildren.Length == 0)
			{
				return;
			}
			TextMeshProUGUI val = null;
			TextMeshProUGUI[] array = componentsInChildren;
			foreach (TextMeshProUGUI val2 in array)
			{
				if (!string.IsNullOrEmpty(((TMP_Text)val2).text) && ((TMP_Text)val2).text.Contains("Default"))
				{
					val = val2;
					break;
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				val = componentsInChildren[0];
			}
			Transform val3 = ((TMP_Text)val).transform.parent.Find("StyleSourceText");
			TextMeshProUGUI clone;
			if (!((Object)(object)val3 != (Object)null))
			{
				clone = Object.Instantiate<TextMeshProUGUI>(val, ((TMP_Text)val).transform.parent);
				((Object)clone).name = "StyleSourceText";
				TextMeshProUGUI obj = clone;
				((TMP_Text)obj).fontSize = ((TMP_Text)obj).fontSize * 0.85f;
				((Graphic)clone).color = new Color(0.7f, 0.7f, 0.7f, 1f);
				if (!Bindings.ContainsKey(__instance))
				{
					Bindings[__instance] = new List<TextMeshProUGUI>();
				}
				Bindings[__instance].Add(clone);
				Refresh();
				((UnityEvent<int>)(object)componentInChildren.onValueChanged).AddListener((UnityAction<int>)delegate
				{
					Refresh();
				});
			}
			void Refresh()
			{
				string value = GetValue(__instance);
				if (string.IsNullOrEmpty(value) || value == "Default")
				{
					((Component)clone).gameObject.SetActive(false);
				}
				else
				{
					((Component)clone).gameObject.SetActive(true);
					((TMP_Text)clone).text = "From: " + GetMod(value);
				}
			}
		}

		private static string GetValue(object item)
		{
			if (item == null)
			{
				return "Default";
			}
			Type type = item.GetType();
			PropertyInfo property = type.GetProperty("CurrentValue", BindingFlags.Instance | BindingFlags.NonPublic);
			if (property != null)
			{
				object value = property.GetValue(item);
				if (value != null)
				{
					return value.ToString();
				}
			}
			PropertyInfo property2 = type.GetProperty("BaseConfigEntry", BindingFlags.Instance | BindingFlags.NonPublic);
			if (property2 != null)
			{
				object value2 = property2.GetValue(item);
				if (value2 != null)
				{
					object obj = value2.GetType().GetProperty("BoxedValue")?.GetValue(value2);
					if (obj != null)
					{
						return obj.ToString();
					}
				}
			}
			return "Default";
		}

		private static string GetMod(string value)
		{
			if (value == "Default")
			{
				return "Vanilla";
			}
			string key = value;
			if (!Plugins.ScanlineTextures.ContainsKey(key) && Plugins.ScanlineDisplayToKey.TryGetValue(key, out var value2))
			{
				key = value2;
			}
			if (Plugins.ScanlineTextures.TryGetValue(key, out var value3))
			{
				return value3.ModName;
			}
			if (Plugins.HealthBarPrefabs.TryGetValue(key, out var value4))
			{
				return value4.ModName;
			}
			if (Plugins.StaminaBarPrefabs.TryGetValue(key, out var value5))
			{
				return value5.ModName;
			}
			if (Plugins.BatteryPrefabs.TryGetValue(key, out var value6))
			{
				return value6.ModName;
			}
			if (Plugins.SlotPrefabs.TryGetValue(key, out var value7))
			{
				return value7.ModName;
			}
			if (Plugins.ScanNodeSprites.TryGetValue(key, out var value8))
			{
				return value8.ModName;
			}
			return "Unknown";
		}
	}
	[HarmonyPatch(typeof(BaseConfigItem))]
	internal static class ConfigValueChangedPatch
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.PropertySetter(typeof(BaseConfigItem), "CurrentBoxedValue");
		}

		private static void Postfix(BaseConfigItem __instance)
		{
			TextDropDownConfigItem val = (TextDropDownConfigItem)(object)((__instance is TextDropDownConfigItem) ? __instance : null);
			if (val == null || !LethalConfigPatch.Bindings.TryGetValue(val, out var value))
			{
				return;
			}
			value.RemoveAll((TextMeshProUGUI t) => (Object)(object)t == (Object)null);
			foreach (TextMeshProUGUI item in value)
			{
				string value2 = GetValue(val);
				if (string.IsNullOrEmpty(value2) || value2 == "Default")
				{
					((Component)item).gameObject.SetActive(false);
					continue;
				}
				((Component)item).gameObject.SetActive(true);
				((TMP_Text)item).text = "From: " + GetMod(value2);
			}
		}

		private static string GetValue(object item)
		{
			return item.GetType().GetProperty("CurrentValue", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(item)?.ToString() ?? "Default";
		}

		private static string GetMod(string value)
		{
			if (value == "Default")
			{
				return "Vanilla";
			}
			string key = value;
			if (!Plugins.ScanlineTextures.ContainsKey(key) && Plugins.ScanlineDisplayToKey.TryGetValue(key, out var value2))
			{
				key = value2;
			}
			if (Plugins.ScanlineTextures.TryGetValue(key, out var value3))
			{
				return value3.ModName;
			}
			if (Plugins.HealthBarPrefabs.TryGetValue(key, out var value4))
			{
				return value4.ModName;
			}
			if (Plugins.StaminaBarPrefabs.TryGetValue(key, out var value5))
			{
				return value5.ModName;
			}
			if (Plugins.BatteryPrefabs.TryGetValue(key, out var value6))
			{
				return value6.ModName;
			}
			if (Plugins.SlotPrefabs.TryGetValue(key, out var value7))
			{
				return value7.ModName;
			}
			if (Plugins.ScanNodeSprites.TryGetValue(key, out var value8))
			{
				return value8.ModName;
			}
			return "Unknown";
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB))]
	internal static class PlayerControllerBPatch
	{
		private static int _lastHealth = int.MinValue;

		private static bool IsLocalPlayer(PlayerControllerB player)
		{
			GameNetworkManager instance = GameNetworkManager.Instance;
			if ((Object)(object)player != (Object)null && (Object)(object)instance != (Object)null)
			{
				return (Object)(object)player == (Object)(object)instance.localPlayerController;
			}
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch("Awake")]
		private static void OnPlayerControllerBAwake_Prefix(PlayerControllerB __instance)
		{
			PlayerColorNetworker playerColorNetworker = default(PlayerColorNetworker);
			if (!Plugins.NetworkingDisabled && !((Component)__instance).TryGetComponent<PlayerColorNetworker>(ref playerColorNetworker))
			{
				((Component)__instance).gameObject.AddComponent<PlayerColorNetworker>();
			}
			PlayerBillboardGradient playerBillboardGradient = default(PlayerBillboardGradient);
			if (!((Component)__instance).TryGetComponent<PlayerBillboardGradient>(ref playerBillboardGradient))
			{
				((Component)__instance).gameObject.AddComponent<PlayerBillboardGradient>();
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch("BeginGrabObject")]
		private static void OnPlayerControllerBBeginGrabObject(PlayerControllerB __instance)
		{
			if (IsLocalPlayer(__instance))
			{
				InventoryFrames.HandsFull();
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch("NoPunctuation")]
		private static bool NoPunctuation_Prefix(string input, ref string __result)
		{
			__result = ChatController.NoPunctuation(input);
			return false;
		}

		[HarmonyPostfix]
		[HarmonyPatch("Start")]
		private static void OnPlayerControllerBAwake_Postfix(PlayerControllerB __instance)
		{
			CustomStaminaMeter.Init(__instance);
		}

		[HarmonyPostfix]
		[HarmonyPatch("SwitchToItemSlot")]
		private static void OnPlayerControllerBSwitchToItemSlot(PlayerControllerB __instance, int slot, GrabbableObject fillSlotWithItem, bool __runOriginal)
		{
			if (!IsLocalPlayer(__instance))
			{
				return;
			}
			if (__runOriginal && ((NetworkBehaviour)__instance).IsOwner)
			{
				Image[] array = HUDManager.Instance?.itemSlotIconFrames;
				if (array != null)
				{
					for (int i = 0; i < array.Length; i++)
					{
						Animator val = (((Object)(object)array[i] != (Object)null) ? ((Component)array[i]).GetComponent<Animator>() : null);
						if (!((Object)(object)val == (Object)null))
						{
							CustomFrames.ForwardSlotBool(val, "selectedSlot", i == __instance.currentItemSlot);
							if ((Object)(object)fillSlotWithItem != (Object)null && i == slot)
							{
								CustomFrames.ForwardSlotTrigger(val, "GetItem", reset: true);
								CustomFrames.ForwardSlotTrigger(val, "GetItem", reset: false);
							}
						}
					}
				}
			}
			if (!Plugins.ConfigEntries.ShowItemValue.Value && ScrapValueDisplay.slotTexts != null)
			{
				ScrapValueDisplay.Hide(slot);
			}
			if (ScrapValueDisplay.slotTexts != null && slot >= 0 && slot < ScrapValueDisplay.slotTexts.Length)
			{
				if (__instance.ItemSlots != null && slot < __instance.ItemSlots.Length && (Object)(object)__instance.ItemSlots[slot] != (Object)null)
				{
					int scrapValue = __instance.ItemSlots[slot].scrapValue;
					ScrapValueDisplay.UpdateSlot(slot, scrapValue);
				}
				else
				{
					ScrapValueDisplay.UpdateSlot(slot, 0);
				}
				if (__instance.twoHanded)
				{
					HUDManager.Instance.PingHUDElement(HUDManager.Instance.Inventory, Plugins.ConfigEntries.SlotFadeDelayTime.Value / 2f, Math.Clamp(Plugins.ConfigEntries.SlotFade.Value + 0.25f, 0f, 1f), Plugins.ConfigEntries.SlotFade.Value);
				}
				else
				{
					HUDManager.Instance.PingHUDElement(HUDManager.Instance.Inventory, Plugins.ConfigEntries.SlotFadeDelayTime.Value, 1f, Plugins.ConfigEntries.SlotFade.Value);
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("DespawnHeldObject")]
		private static void OnPlayerControllerBDespawnHeldObject(PlayerControllerB __instance)
		{
			if (IsLocalPlayer(__instance))
			{
				ScrapValueDisplay.UpdateSlot(__instance.currentItemSlot, 0);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("DiscardHeldObject")]
		private static void OnPlayerControllerBDiscardHeldObject(PlayerControllerB __instance)
		{
			if (IsLocalPlayer(__instance))
			{
				ScrapValueDisplay.UpdateSlot(__instance.currentItemSlot, 0);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("DestroyItemInSlot")]
		private static void OnPlayerControllerBDestroyItemInSlot(PlayerControllerB __instance)
		{
			if (IsLocalPlayer(__instance))
			{
				ScrapValueDisplay.SyncFromLocalInventory(forceRefresh: true);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("DropAllHeldItems")]
		private static void OnPlayerControllerBDiscardAllHelditems(PlayerControllerB __instance)
		{
			if (IsLocalPlayer(__instance))
			{
				ScrapValueDisplay.SyncFromLocalInventory(forceRefresh: true);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("DamagePlayer")]
		private static void OnPlayerControllerBDamagePlayer(PlayerControllerB __instance)
		{
			PlayerHPDisplay.ShakeOnHit(__instance);
		}

		[HarmonyPostfix]
		[HarmonyPatch("SpawnPlayerAnimation")]
		private static void OnPlayerControllerBSpawnPlayerAnimation(PlayerControllerB __instance)
		{
			if (IsLocalPlayer(__instance))
			{
				ScrapValueDisplay.ClearItemSlots();
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("LateUpdate")]
		private static void OnPlayerLateUpdate(PlayerControllerB __instance)
		{
			if (__instance.isTypingChat)
			{
				ChatController.PlayerTypingIndicator();
			}
			SprintMeterController.UpdateSprintMeterColor();
			CustomStaminaMeter.UpdateFromPlayer(__instance);
			BatteryController.Update(__instance);
			int health = __instance.health;
			if (health != _lastHealth)
			{
				_lastHealth = health;
				PlayerRedCanvasController.ChangeSetting();
			}
		}
	}
	[HarmonyPatch(typeof(Terminal))]
	internal static class TerminalPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch("BeginUsingTerminal")]
		private static void OnTerminalBeginUsingTerminal()
		{
			HUDManager.Instance.PingHUDElement(HUDManager.Instance.Inventory, Plugins.ConfigEntries.TerminalFadeDelaysTime.Value, Plugins.ConfigEntries.SlotFade.Value, 0f);
			HUDManager.Instance.PingHUDElement(HUDManager.Instance.Chat, Plugins.ConfigEntries.TerminalFadeDelaysTime.Value, 0.13f, 0.01f);
			HUDManager.Instance.PingHUDElement(HUDManager.Instance.Compass, Plugins.ConfigEntries.TerminalFadeDelaysTime.Value, 0.8f, 0.01f);
		}

		[HarmonyPostfix]
		[HarmonyPatch("QuitTerminal")]
		private static void OnTerminalQuitTerminal()
		{
			HUDManager.Instance.PingHUDElement(HUDManager.Instance.Inventory, Plugins.ConfigEntries.TerminalFadeDelaysTime.Value, 0.13f, Plugins.ConfigEntries.SlotFade.Value);
			HUDManager.Instance.PingHUDElement(HUDManager.Instance.Chat, Plugins.ConfigEntries.TerminalFadeDelaysTime.Value, 0.13f, 0f);
			HUDManager.Instance.PingHUDElement(HUDManager.Instance.Compass, Plugins.ConfigEntries.TerminalFadeDelaysTime.Value, 0.8f, 0.12f);
		}
	}
	[HarmonyPatch(typeof(TimeOfDay))]
	internal static class TimeOfDayPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch("MoveTimeOfDay")]
		private static void OnTimeOfDayMoveTimeOfDay()
		{
			ClockController.ApplyRealtimeClock();
		}
	}
}
namespace LethalHUD.Networking
{
	[DisallowMultipleComponent]
	internal class PlayerColorNetworker : NetworkBehaviour
	{
		internal readonly NetworkVariable<PlayerColorInfo> _syncedPlayerColors = new NetworkVariable<PlayerColorInfo>(default(PlayerColorInfo), (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)1);

		public PlayerColorInfo PlayerColors { get; private set; }

		public override void OnNetworkSpawn()
		{
			if (Plugins.NetworkingDisabled)
			{
				((Behaviour)this).enabled = false;
				return;
			}
			((NetworkBehaviour)this).OnNetworkSpawn();
			NetworkVariable<PlayerColorInfo> syncedPlayerColors = _syncedPlayerColors;
			syncedPlayerColors.OnValueChanged = (OnValueChangedDelegate<PlayerColorInfo>)(object)Delegate.Combine((Delegate?)(object)syncedPlayerColors.OnValueChanged, (Delegate?)(object)(OnValueChangedDelegate<PlayerColorInfo>)delegate(PlayerColorInfo previousValue, PlayerColorInfo newValue)
			{
				PlayerColors = newValue;
			});
			RefreshColors();
		}

		public override void OnOwnershipChanged(ulong previous, ulong current)
		{
			if (!Plugins.NetworkingDisabled)
			{
				((NetworkBehaviour)this).OnOwnershipChanged(previous, current);
				RefreshColors();
			}
		}

		private void RefreshColors()
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: 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_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			if (((NetworkBehaviour)this).IsOwner)
			{
				string value = Plugins.ConfigEntries.GradientNameColorA.Value;
				string value2 = Plugins.ConfigEntries.GradientNameColorB.Value;
				Color val = default(Color);
				Color val2 = default(Color);
				PlayerColorInfo playerColors = new PlayerColorInfo(Color32.op_Implicit(ColorUtility.TryParseHtmlString(value, ref val) ? val : Color.red), ColorUtility.TryParseHtmlString(value2, ref val2) ? new Color32?(Color32.op_Implicit(val2)) : ((Color32?)null))
				{
					billboardMode = Plugins.ConfigEntries.BillboardMode.Value,
					billboardLayout = Plugins.ConfigEntries.BillboardLayout.Value
				};
				PlayerColors = playerColors;
				if (_syncedPlayerColors.Value != PlayerColors)
				{
					_syncedPlayerColors.Value = PlayerColors;
				}
			}
			PlayerColors = _syncedPlayerColors.Value;
		}

		internal static void RefreshColors(object obj, EventArgs args)
		{
			PlayerColorNetworker playerColorNetworker = default(PlayerColorNetworker);
			if ((Object)(object)GameNetworkManager.Instance != (Object)null && (Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)null && ((Component)GameNetworkManager.Instance.localPlayerController).TryGetComponent<PlayerColorNetworker>(ref playerColorNetworker))
			{
				playerColorNetworker.RefreshColors();
			}
		}

		protected override void __initializeVariables()
		{
			if (_syncedPlayerColors == null)
			{
				throw new Exception("PlayerColorNetworker._syncedPlayerColors cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)_syncedPlayerColors).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)_syncedPlayerColors, "_syncedPlayerColors");
			base.NetworkVariableFields.Add((NetworkVariableBase)(object)_syncedPlayerColors);
			((NetworkBehaviour)this).__initializeVariables();
		}

		protected override void __initializeRpcs()
		{
			((NetworkBehaviour)this).__initializeRpcs();
		}

		protected internal override string __getTypeName()
		{
			return "PlayerColorNetworker";
		}
	}
	public struct PlayerColorInfo : INetworkSerializable, IEquatable<PlayerColorInfo>
	{
		public Color32 colorA;

		public Color32 colorB;

		public Enums.BillboardGradientMode billboardMode;

		public Enums.VertexGradientLayout billboardLayout;

		public PlayerColorInfo(Color32 a, Color32? b = null)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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)
			billboardMode = Enums.BillboardGradientMode.Static;
			billboardLayout = Enums.VertexGradientLayout.Horizontal;
			colorA = a;
			colorB = b ?? a;
		}

		public unsafe void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
		{
			//IL_0024: 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_003a: 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)
			serializer.SerializeValue(ref colorA);
			serializer.SerializeValue(ref colorB);
			((BufferSerializer<Enums.BillboardGradientMode>*)(&serializer))->SerializeValue<Enums.BillboardGradientMode>(ref billboardMode, default(ForEnums));
			((BufferSerializer<Enums.VertexGradientLayout>*)(&serializer))->SerializeValue<Enums.VertexGradientLayout>(ref billboardLayout, default(ForEnums));
		}

		public readonly bool Equals(PlayerColorInfo other)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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_0022: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			if (((object)colorA/*cast due to .constrained prefix*/).Equals((object?)other.colorA) && ((object)colorB/*cast due to .constrained prefix*/).Equals((object?)other.colorB) && billboardMode == other.billboardMode)
			{
				return billboardLayout == other.billboardLayout;
			}
			return false;
		}

		public override readonly bool Equals(object obj)
		{
			if (obj is PlayerColorInfo other)
			{
				return Equals(other);
			}
			return false;
		}

		public static bool operator ==(PlayerColorInfo left, PlayerColorInfo right)
		{
			return left.Equals(right);
		}

		public static bool operator !=(PlayerColorInfo left, PlayerColorInfo right)
		{
			return !(left == right);
		}

		public override readonly int GetHashCode()
		{
			//IL_0001: 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)
			return HashCode.Combine<Color32, Color32, Enums.BillboardGradientMode, Enums.VertexGradientLayout>(colorA, colorB, billboardMode, billboardLayout);
		}
	}
}
namespace LethalHUD.Misc
{
	internal static class ControlTipController
	{
		private static readonly Color DefaultColorA = Color.white;

		private static readonly Color DefaultColorB = Color.white;

		private static TMP_Text[] _lastTips;

		private static string[] _lastTipTexts;

		private static string _lastHexA;

		private static string _lastHexB;

		private static Enums.MTColorMode _lastMode;

		internal static void ApplyColor()
		{
			//IL_0076: 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_008e: 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)
			HUDManager instance = HUDManager.Instance;
			if (instance?.controlTipLines == null || instance.controlTipLines.Length == 0 || ((object)instance.controlTipLines == _lastTips && !HasConfigChanged() && !HasTextChanged(instance)))
			{
				return;
			}
			string value = Plugins.ConfigEntries.MTColorGradientA.Value;
			string value2 = Plugins.ConfigEntries.MTColorGradientB.Value;
			switch (Plugins.ConfigEntries.MTColorSelection.Value)
			{
			case Enums.MTColorMode.Solid:
				ApplySingleColor(instance, value, DefaultColorA);
				break;
			case Enums.MTColorMode.Gradient:
				if (HUDUtils.HasCustomGradient(value, value2))
				{
					ApplyGradient(instance, value, value2, DefaultColorA, DefaultColorB);
				}
				else
				{
					ApplySingleColor(instance, value, DefaultColorA);
				}
				break;
			}
			CacheState(instance);
		}

		private static bool HasConfigChanged()
		{
			Enums.MTColorMode value = Plugins.ConfigEntries.MTColorSelection.Value;
			string value2 = Plugins.ConfigEntries.MTColorGradientA.Value;
			string value3 = Plugins.ConfigEntries.MTColorGradientB.Value;
			if (value == _lastMode && !(value2 != _lastHexA))
			{
				return value3 != _lastHexB;
			}
			return true;
		}

		private static bool HasTextChanged(HUDManager hud)
		{
			if (_lastTipTexts == null || _lastTipTexts.Length != hud.controlTipLines.Length)
			{
				return true;
			}
			for (int i = 0; i < hud.controlTipLines.Length; i++)
			{
				TextMeshProUGUI val = hud.controlTipLines[i];
				if (!((Object)(object)val == (Object)null))
				{
					string text = ((TMP_Text)val).text;
					if (_lastTipTexts[i] != text)
					{
						return true;
					}
				}
			}
			return false;
		}

		private static void CacheState(HUDManager hud)
		{
			TMP_Text[] controlTipLines = (TMP_Text[])(object)hud.controlTipLines;
			_lastTips = controlTipLines;
			_lastMode = Plugins.ConfigEntries.MTColorSelection.Value;
			_lastHexA = Plugins.ConfigEntries.MTColorGradientA.Value;
			_lastHexB = Plugins.ConfigEntries.MTColorGradientB.Value;
			_lastTipTexts = new string[hud.controlTipLines.Length];
			for (int i = 0; i < hud.controlTipLines.Length; i++)
			{
				string[] lastTipTexts = _lastTipTexts;
				int num = i;
				TextMeshProUGUI obj = hud.controlTipLines[i];
				lastTipTexts[num] = ((obj != null) ? ((TMP_Text)obj).text : null);
			}
		}

		private static void ApplySingleColor(HUDManager hud, string hex, Color fallback)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: 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)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			Color color = HUDUtils.ParseHexColor(hex, fallback);
			TextMeshProUGUI[] controlTipLines = hud.controlTipLines;
			foreach (TextMeshProUGUI val in controlTipLines)
			{
				if ((Object)(object)val != (Object)null)
				{
					((Graphic)val).color = color;
				}
			}
		}

		private static void ApplyGradient(HUDManager hud, string hexA, string hexB, Color fallbackA, Color fallbackB)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: 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)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: 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_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: 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_00c7: 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_00d7: 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_00e3: 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_00f5: 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_0105: 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_010c: Unknown result type (might be due to invalid IL or missing references)
			Color val = HUDUtils.ParseHexColor(hexA, fallbackA);
			Color val2 = HUDUtils.ParseHexColor(hexB, fallbackB);
			TextMeshProUGUI[] controlTipLines = hud.controlTipLines;
			foreach (TextMeshProUGUI val3 in controlTipLines)
			{
				if ((Object)(object)val3 == (Object)null)
				{
					continue;
				}
				((TMP_Text)val3).ForceMeshUpdate(false, false);
				TMP_TextInfo textInfo = ((TMP_Text)val3).textInfo;
				int characterCount = textInfo.characterCount;
				if (characterCount == 0)
				{
					continue;
				}
				for (int j = 0; j < characterCount; j++)
				{
					TMP_CharacterInfo val4 = textInfo.characterInfo[j];
					if (val4.isVisible)
					{
						float num = ((characterCount > 1) ? ((float)j / (float)(characterCount - 1)) : 0f);
						Color val5 = Color.Lerp(val, val2, num);
						int vertexIndex = val4.vertexIndex;
						TMP_MeshInfo val6 = textInfo.meshInfo[val4.materialReferenceIndex];
						val6.colors32[vertexIndex] = Color32.op_Implicit(val5);
						val6.colors32[vertexIndex + 1] = Color32.op_Implicit(val5);
						val6.colors32[vertexIndex + 2] = Color32.op_Implicit(val5);
						val6.colors32[vertexIndex + 3] = Color32.op_Implicit(val5);
					}
				}
				for (int k = 0; k < ((TMP_Text)val3).textInfo.meshInfo.Length; k++)
				{
					((TMP_Text)val3).textInfo.meshInfo[k].mesh.colors32 = ((TMP_Text)val3).textInfo.meshInfo[k].colors32;
					((TMP_Text)val3).UpdateGeometry(((TMP_Text)val3).textInfo.meshInfo[k].mesh, k);
				}
			}
		}
	}
	public static class LootInfoManager
	{
		private static GameObject _ship;

		private static GameObject _totalCounter;

		private static GameObject _shipCounter;

		private static GameObject _vanillaTotalLoot;

		private static TextMeshProUGUI _totalText;

		private static TextMeshProUGUI _shipText;

		private static TextMeshProUGUI _vanillaTotalNum;

		private static Image _totalBg;

		private static Image _shipBg;

		private static RectTransform _totalDiagonalRT;

		private static RectTransform _shipDiagonalRT;

		private static CanvasGroup _totalCG;

		private static CanvasGroup _shipCG;

		private static float _displayTimeLeft;

		private static bool _isCoroutineRunning;

		private static int _shipLootValue;

		private static int _scanRealTotal;

		private static int _scanDisplayTotal;

		private static Color _lootInfoColor = Color.white;

		private const float CountSpeed = 500f;

		private const float FadeDuration = 0.25f;

		private static readonly AnimationCurve FadeCurve = AnimationCurve.EaseInOut(0f, 0f, 1f, 1f);

		public static void ApplyLootInfoColor()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			_lootInfoColor = HUDUtils.ParseHexColor(Plugins.ConfigEntries.LootInfoColor.Value);
			ApplyColor(_totalText, _totalBg);
			ApplyColor(_shipText, _shipBg);
		}

		public static void ApplyLootInfoPos()
		{
			//IL_002a: 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_004b: 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_0061: 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_007c: 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)
			RectTransform component = _totalCounter.GetComponent<RectTransform>();
			component.anchoredPosition = new Vector2(Plugins.ConfigEntries.LootPosX.Value, Plugins.ConfigEntries.LootPosY.Value);
			((Transform)component).localRotation = Quaternion.identity;
			RectTransform component2 = _shipCounter.GetComponent<RectTransform>();
			((Transform)component2).localRotation = Quaternion.identity;
			((Transform)component2).localScale = ((Transform)component).localScale * 0.95f;
			component2.anchoredPosition = component.anchoredPosition + new Vector2(18f, -17f);
		}

		public static void OnDisplayTimeChanged()
		{
			_displayTimeLeft = Plugins.ConfigEntries.DisplayTime.Value;
		}

		public static void OnShowShipLootChanged()
		{
			if (!Plugins.ConfigEntries.ShowShipLoot.Value)
			{
				FadeOutCounter(_shipCounter, _shipCG);
			}
		}

		public static void OnReplaceScrapCounterVisualChanged()
		{
			if (!Plugins.ConfigEntries.ReplaceScrapCounterVisual.Value)
			{
				FadeOutCounter(_totalCounter, _totalCG);
				RestoreVanillaScanUI();
			}
		}

		public static void LootScan()
		{
			if (!((Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null))
			{
				_displayTimeLeft = Plugins.ConfigEntries.DisplayTime.Value;
				if (!_isCoroutineRunning)
				{
					((MonoBehaviour)GameNetworkManager.Instance).StartCoroutine(DisplayCoroutine());
				}
			}
		}

		private static IEnumerator DisplayCoroutine()
		{
			_isCoroutineRunning = true;
			EnsureTotalCounter();
			EnsureShipCounter();
			EnsureVanillaTotalLoot();
			AlignShipToTotalDiagonal();
			float timer = 0f;
			while (timer < _displayTimeLeft)
			{
				timer += Time.deltaTime;
				PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
				bool flag = (Object)(object)localPlayerController != (Object)null && localPlayerController.isInHangarShipRoom;
				if (Plugins.ConfigEntries.ReplaceScrapCounterVisual.Value)
				{
					UpdateVanillaScanTotal();
					_scanDisplayTotal = (int)Mathf.MoveTowards((float)_scanDisplayTotal, (float)_scanRealTotal, 500f * Time.deltaTime);
					if (_scanDisplayTotal > 0)
					{
						FadeInCounter(_totalCounter, _totalCG);
						((TMP_Text)_totalText).SetText($"Total: ${_scanDisplayTotal}", true);
						HideVanillaScanUI();
					}
					else
					{
						FadeOutCounter(_totalCounter, _totalCG);
					}
				}
				else
				{
					FadeOutCounter(_totalCounter, _totalCG);
					RestoreVanillaScanUI();
				}
				if (flag && Plugins.ConfigEntries.ShowShipLoot.Value)
				{
					_shipLootValue = CalculateShipLoot();
					FadeInCounter(_shipCounter, _shipCG);
					((TMP_Text)_shipText).SetText($"Ship: ${_shipLootValue}", true);
				}
				else
				{
					FadeOutCounter(_shipCounter, _shipCG);
				}
				yield return null;
			}
			FadeOutCounter(_totalCounter, _totalCG);
			FadeOutCounter(_shipCounter, _shipCG);
			_scanDisplayTotal = 0;
			_scanRealTotal = 0;
			_isCoroutineRunning = false;
		}

		private static void EnsureTotalCounter()
		{
			if ((Object)(object)_totalCounter != (Object)null)
			{
				return;
			}
			GameObject val = GameObject.Find("/Systems/UI/Canvas/IngamePlayerHUD/BottomMiddle/ValueCounter");
			if (Object.op_Implicit((Object)(object)val))
			{
				_totalCounter = Object.Instantiate<GameObject>(val, val.transform.parent, false);
				_totalText = _totalCounter.GetComponentInChildren<TextMeshProUGUI>(true);
				_totalBg = _totalCounter.GetComponentInChildren<Image>(true);
				Image? obj = ((IEnumerable<Image>)_totalCounter.GetComponentsInChildren<Image>(true)).FirstOrDefault((Func<Image, bool>)((Image i) => ((Object)i).name.ToLower().Contains("line")));
				_totalDiagonalRT = ((obj != null) ? ((Component)obj).GetComponent<RectTransform>() : null);
				_totalCG = _totalCounter.GetComponent<CanvasGroup>() ?? _totalCounter.AddComponent<CanvasGroup>();
				_totalCG.alpha = 0f;
				_totalCounter.SetActive(false);
				ApplyLootInfoColor();
			}
		}

		private static void EnsureShipCounter()
		{
			if (!((Object)(object)_shipCounter != (Object)null))
			{
				EnsureTotalCounter();
				_shipCounter = Object.Instantiate<GameObject>(_totalCounter, _totalCounter.transform.parent, false);
				_shipText = _shipCounter.GetComponentInChildren<TextMeshProUGUI>(true);
				_shipBg = _shipCounter.GetComponentInChildren<Image>(true);
				Image? obj = ((IEnumerable<Image>)_shipCounter.GetComponentsInChildren<Image>(true)).FirstOrDefault((Func<Image, bool>)((Image i) => ((Object)i).name.ToLower().Contains("line")));
				_shipDiagonalRT = ((obj != null) ? ((Component)obj).GetComponent<RectTransform>() : null);
				_shipCG = _shipCounter.GetComponent<CanvasGroup>() ?? _shipCounter.AddComponent<CanvasGroup>();
				_shipCG.alpha = 0f;
				_shipCounter.SetActive(false);
				ApplyLootInfoPos();
				ApplyLootInfoColor();
			}
		}

		private static IEnumerator Fade(CanvasGroup cg, float from, float to)
		{
			float t = 0f;
			while (t < 0.25f)
			{
				t += Time.deltaTime;
				float num = FadeCurve.Evaluate(t / 0.25f);
				cg.alpha = Mathf.Lerp(from, to, num);
				yield return null;
			}
			cg.alpha = to;
		}

		private static void FadeInCounter(GameObject go, CanvasGroup cg)
		{
			if (!((Object)(object)go == (Object)null) && !((Object)(object)cg == (Object)null) && !go.activeSelf && !(cg.alpha > 0.99f))
			{
				go.SetActive(true);
				((MonoBehaviour)GameNetworkManager.Instance).StartCoroutine(Fade(cg, 0f, 1f));
			}
		}

		private static void FadeOutCounter(GameObject go, CanvasGroup cg)
		{
			if (!((Object)(object)go == (Object)null) && !((Object)(object)cg == (Object)null) && go.activeSelf && !(cg.alpha < 0.01f))
			{
				((MonoBehaviour)GameNetworkManager.Instance).StartCoroutine(FadeOutRoutine(go, cg));
			}
		}

		private static IEnumerator FadeOutRoutine(GameObject go, CanvasGroup cg)
		{
			yield return Fade(cg, cg.alpha, 0f);
			go.SetActive(false);
		}

		private static void ApplyColor(TextMeshProUGUI text, Image bg)
		{
			//IL_000a: 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_0022: 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 ((Object)(object)text != (Object)null)
			{
				((Graphic)text).color = _lootInfoColor;
			}
			if ((Object)(object)bg != (Object)null)
			{
				Color lootInfoColor = _lootInfoColor;
				lootInfoColor.a *= 0.25f;
				((Graphic)bg).color = lootInfoColor;
			}
		}

		private static void AlignShipToTotalDiagonal()
		{
			//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_0038: 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)
			//IL_0042: 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_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: 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_0069: 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_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_totalDiagonalRT == (Object)null) && !((Object)(object)_shipDiagonalRT == (Object)null))
			{
				RectTransform component = _shipCounter.GetComponent<RectTransform>();
				RectTransform totalDiagonalRT = _totalDiagonalRT;
				Rect rect = _totalDiagonalRT.rect;
				float y = ((Transform)totalDiagonalRT).TransformPoint(Vector2.op_Implicit(((Rect)(ref rect)).min)).y;
				RectTransform shipDiagonalRT = _shipDiagonalRT;
				rect = _shipDiagonalRT.rect;
				float y2 = ((Transform)shipDiagonalRT).TransformPoint(Vector2.op_Implicit(((Rect)(ref rect)).max)).y;
				((Transform)component).position = ((Transform)component).position + new Vector3(0f, y - y2, 0f);
			}
		}

		private static int CalculateShipLoot()
		{
			if ((Object)(object)_ship == (Object)null)
			{
				_ship = GameObject.Find("/Environment/HangarShip");
			}
			if ((Object)(object)_ship == (Object)null)
			{
				return 0;
			}
			return (from o in _ship.GetComponentsInChildren<GrabbableObject>()
				where o.itemProperties.isScrap && !(o is RagdollGrabbableObject)
				select o).Sum((GrabbableObject o) => o.scrapValue);
		}

		private static void EnsureVanillaTotalLoot()
		{
			if ((Object)(object)_vanillaTotalLoot == (Object)null)
			{
				_vanillaTotalLoot = GameObject.Find("UI/Canvas/ObjectScanner/GlobalScanInfo/AnimContainer/Image");
			}
			if ((Object)(object)_vanillaTotalLoot != (Object)null && (Object)(object)_vanillaTotalNum == (Object)null)
			{
				_vanillaTotalNum = ((IEnumerable<TextMeshProUGUI>)_vanillaTotalLoot.GetComponentsInChildren<TextMeshProUGUI>(true)).FirstOrDefault((Func<TextMeshProUGUI, bool>)((TextMeshProUGUI t) => ((Object)((Component)t).gameObject).name == "TotalNum"));
			}
		}

		private static void UpdateVanillaScanTotal()
		{
			HUDManager instance = HUDManager.Instance;
			if (!((Object)(object)instance == (Object)null))
			{
				_scanRealTotal = instance.totalScrapScanned;
			}
		}

		private static void HideVanillaScanUI()
		{
			if (!((Object)(object)_vanillaTotalLoot == (Object)null))
			{
				CanvasGroup val = _vanillaTotalLoot.GetComponent<CanvasGroup>() ?? _vanillaTotalLoot.AddComponent<CanvasGroup>();
				val.alpha = 0f;
				val.interactable = false;
				val.blocksRaycasts = false;
			}
		}

		private static void RestoreVanillaScanUI()
		{
			if (!((Object)(object)_vanillaTotalLoot == (Object)null))
			{
				CanvasGroup component = _vanillaTotalLoot.GetComponent<CanvasGroup>();
				if (!((Object)(object)component == (Object)null))
				{
					component.alpha = 1f;
					component.interactable = true;
					component.blocksRaycasts = true;
				}
			}
		}
	}
	[DisallowMultipleComponent]
	internal class PlayerBillboardGradient : MonoBehaviour
	{
		private PlayerControllerB _player;

		private TextMeshProUGUI _text;

		private CanvasGroup _canvasAlpha;

		private PlayerColorNetworker _networker;

		[Header("Performance Options")]
		public float maxUpdateDistance = 30f;

		public float updateInterval = 0.033f;

		private float _timeSinceLastUpdate;

		private PlayerColorInfo _currentColors;

		private bool _hasColors;

		private bool _useNetworking;

		private static bool ColoringEnabled => Plugins.ConfigEntries.BillboardColor.Value;

		private void Awake()
		{
			_player = ((Component)this).GetComponent<PlayerControllerB>();
			if (!((Object)(object)_player == (Object)null))
			{
				_text = _player.usernameBillboardText;
				_canvasAlpha = _player.usernameAlpha;
				_useNetworking = !Plugins.NetworkingDisabled;
				if (_useNetworking)
				{
					_networker = ((Component)_player).GetComponent<PlayerColorNetworker>();
				}
				if ((Object)(object)_text != (Object)null)
				{
					((TMP_Text)_text).enableVertexGradient = true;
				}
			}
		}

		private void Start()
		{
			if (_useNetworking && !((Object)(object)_networker == (Object)null))
			{
				_currentColors = _networker._syncedPlayerColors.Value;
				_hasColors = true;
				NetworkVariable<PlayerColorInfo> syncedPlayerColors = _networker._syncedPlayerColors;
				syncedPlayerColors.OnValueChanged = (OnValueChangedDelegate<PlayerColorInfo>)(object)Delegate.Combine((Delegate?)(object)syncedPlayerColors.OnValueChanged, (Delegate?)(object)new OnValueChangedDelegate<PlayerColorInfo>(OnPlayerColorsChanged));
			}
		}

		private void OnPlayerColorsChanged(PlayerColorInfo previous, PlayerColorInfo current)
		{
			_currentColors = current;
			_hasColors = true;
		}

		private void LateUpdate()
		{
			//IL_0070: 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_008e: 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_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: 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_022a: 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_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			if (!ColoringEnabled)
			{
				ResetBillboardToDefault();
				return;
			}
			if (!((TMP_Text)_text).enableVertexGradient)
			{
				((TMP_Text)_text).enableVertexGradient = true;
			}
			if (_useNetworking)
			{
				if (!_hasColors || (Object)(object)_networker == (Object)null)
				{
					return;
				}
				_currentColors = _networker._syncedPlayerColors.Value;
			}
			else
			{
				_currentColors = new PlayerColorInfo(Color32.op_Implicit(HUDUtils.ParseHexColor(Plugins.ConfigEntries.GradientNameColorA.Value, Color.white)), Color32.op_Implicit(HUDUtils.ParseHexColor(Plugins.ConfigEntries.GradientNameColorB.Value, Color.white)))
				{
					billboardMode = Plugins.ConfigEntries.BillboardMode.Value,
					billboardLayout = Plugins.ConfigEntries.BillboardLayout.Value
				};
			}
			if ((Object)(object)_player == (Object)null || (Object)(object)_text == (Object)null || (Object)(object)_canvasAlpha == (Object)null || !((Component)_player.usernameCanvas).gameObject.activeSelf || _canvasAlpha.alpha < 0.95f || (Object)(object)GameNetworkManager.Instance?.localPlayerController == (Object)null)
			{
				return;
			}
			Vector3 val = ((Component)_player).transform.position - ((Component)GameNetworkManager.Instance.localPlayerController).transform.position;
			float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
			if (sqrMagnitude > maxUpdateDistance * maxUpdateDistance)
			{
				return;
			}
			_timeSinceLastUpdate += Time.deltaTime;
			if (!(_timeSinceLastUpdate < updateInterval))
			{
				_timeSinceLastUpdate = 0f;
				switch (_currentColors.billboardMode)
				{
				case Enums.BillboardGradientMode.Static:
					HUDUtils.ApplyStaticVertexGradient(_text, Color32.op_Implicit(_currentColors.colorA), Color32.op_Implicit(_currentColors.colorB), _currentColors.billboardLayout);
					break;
				case Enums.BillboardGradientMode.Wave:
					HUDUtils.ApplyWaveVertexGradient(_text, Color32.op_Implicit(_currentColors.colorA), Color32.op_Implicit(_currentColors.colorB), Time.time / 2f, _currentColors.billboardLayout);
					break;
				case Enums.BillboardGradientMode.Pulse:
					HUDUtils.ApplyPulsingVertexGradient(_text, Color32.op_Implicit(_currentColors.colorA), Color32.op_Implicit(_currentColors.colorB), Time.time / 2f, _currentColors.billboardLayout);
					break;
				}
			}
		}

		private void ResetBillboardToDefault()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_text == (Object)null))
			{
				((TMP_Text)_text).enableVertexGradient = false;
				((Graphic)_text).color = Color.white;
			}
		}
	}
	internal static class SpectatorHUDController
	{
		internal static void ApplyColors()
		{
			HUDManager instance = HUDManager.Instance;
			if (!((Object)(object)instance == (Object)null))
			{
				ConfigEntries configEntries = Plugins.ConfigEntries;
				ApplyColorPreserveAlpha(instance.spectatorTipText, configEntries.SpectatorTipColor.Value);
				ApplyColorPreserveAlpha(instance.spectatingPlayerText, configEntries.SpectatingPlayerColor.Value);
				ApplyColorPreserveAlpha(instance.holdButtonToEndGameEarlyText, configEntries.HoldEndGameColor.Value);
				ApplyColorPreserveAlpha(instance.holdButtonToEndGameEarlyVotesText, configEntries.HoldEndGameVotesColor.Value);
			}
		}

		private static void ApplyColorPreserveAlpha(TextMeshProUGUI text, string hexColor)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: 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_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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)
			if (!((Object)(object)text == (Object)null))
			{
				Color color = ((Graphic)text).color;
				Color color2 = HUDUtils.ParseHexColor(hexColor, color);
				color2.a = color.a;
				((Graphic)text).color = color2;
			}
		}
	}
	public class StatsDisplay : NetworkBehaviour
	{
		private float _deltaTime;

		private ulong _currentPing;

		private const float PingRefreshRate = 0.5f;

		private float _nextPingRefresh;

		private TextMeshProUGUI _statsText;

		private string _lastText = "";

		private Enums.MTColorMode _lastMode;

		private string _lastHexA = "";

		private string _lastHexB = "";

		private bool _lastSplit;

		private string _lastSeparateHex = "";

		private static readonly BindingFlags ReflectionFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

		private FieldInfo _connectionManagerField;

		private PropertyInfo _connectionProperty;

		private FieldInfo _connectionField;

		private MethodInfo _detailedStatusMethod;

		private void Start()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_009c: 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_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: 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)
			GameObject val = new GameObject("StatsDisplay");
			GameObject val2 = GameObject.Find("Systems/UI/Canvas/IngamePlayerHUD/");
			val.transform.SetParent(val2.transform, false);
			_statsText = val.AddComponent<TextMeshProUGUI>();
			((TMP_Text)_statsText).font = ((TMP_Text)HUDManager.Instance.chatText).font;
			((TMP_Text)_statsText).fontSize = 12f;
			((TMP_Text)_statsText).richText = true;
			((TMP_Text)_statsText).alignment = (TextAlignmentOptions)257;
			Material val3 = Object.Instantiate<Material>(((TMP_Text)_statsText).fontMaterial);
			val3.EnableKeyword("UNDERLAY_ON");
			val3.SetColor("_UnderlayColor", Color.black);
			val3.SetFloat("_UnderlayOffsetX", 1.2f);
			val3.SetFloat("_UnderlayOffsetY", -1.2f);
			val3.SetFloat("_UnderlaySoftness", 0.35f);
			((TMP_Text)_statsText).fontMaterial = val3;
			RectTransform rectTransform = ((TMP_Text)_statsText).rectTransform;
			rectTransform.anchorMin = new Vector2(0f, 1f);
			rectTransform.anchorMax = new Vector2(0f, 1f);
			rectTransform.pivot = new Vector2(0f, 1f);
			rectTransform.anchoredPosition =