Decompiled source of ColorMe v1.0.0

ValheimArmorColors.dll

Decompiled 3 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("ValheimArmorColors")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ValheimArmorColors")]
[assembly: AssemblyTitle("ValheimArmorColors")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ValheimArmorColors
{
	public static class ArmorColorConfig
	{
		private static ConfigFile _cfg;

		public const string DefaultColor = "0,0,0,0";

		public static void Init(ConfigFile cfg)
		{
			_cfg = cfg;
		}

		public static string MakeKey(string charKey, string itemName)
		{
			return charKey + "::" + itemName;
		}

		public static Color GetColor(string charKey, string itemName)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			ConfigEntry<string> val = _cfg.Bind<string>("ItemColors", MakeKey(charKey, itemName), "0,0,0,0", (ConfigDescription)null);
			return Parse(val.Value);
		}

		public static void SetColor(string charKey, string itemName, Color color)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			ConfigEntry<string> val = _cfg.Bind<string>("ItemColors", MakeKey(charKey, itemName), "0,0,0,0", (ConfigDescription)null);
			val.Value = Serialize(color);
		}

		public static void ClearColor(string charKey, string itemName)
		{
			ConfigEntry<string> val = _cfg.Bind<string>("ItemColors", MakeKey(charKey, itemName), "0,0,0,0", (ConfigDescription)null);
			val.Value = "0,0,0,0";
		}

		public static Color Parse(string value)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: 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)
			string[] array = value.Split(new char[1] { ',' });
			if (array.Length < 3)
			{
				return Color.clear;
			}
			float num = TryParse(array[0]);
			float num2 = TryParse(array[1]);
			float num3 = TryParse(array[2]);
			float num4 = ((array.Length >= 4) ? TryParse(array[3]) : 255f);
			return new Color(num / 255f, num2 / 255f, num3 / 255f, num4 / 255f);
		}

		public static string Serialize(Color c)
		{
			//IL_0005: 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_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			return $"{Mathf.RoundToInt(c.r * 255f)}," + $"{Mathf.RoundToInt(c.g * 255f)}," + $"{Mathf.RoundToInt(c.b * 255f)}," + $"{Mathf.RoundToInt(c.a * 255f)}";
		}

		private static float TryParse(string s)
		{
			float result;
			return float.TryParse(s.Trim(), out result) ? Mathf.Clamp(result, 0f, 255f) : 255f;
		}
	}
	[BepInPlugin("com.yourname.valheim.armorcolors", "ArmorColors", "1.0.0")]
	[BepInProcess("valheim.exe")]
	public class ArmorColorsPlugin : BaseUnityPlugin
	{
		public const string PluginGUID = "com.yourname.valheim.armorcolors";

		public const string PluginName = "ArmorColors";

		public const string PluginVersion = "1.0.0";

		internal static ManualLogSource Log;

		private Harmony _harmony;

		private void Awake()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			try
			{
				Log = ((BaseUnityPlugin)this).Logger;
				_harmony = new Harmony("com.yourname.valheim.armorcolors");
				_harmony.PatchAll();
				ArmorColorConfig.Init(((BaseUnityPlugin)this).Config);
				((Component)this).gameObject.AddComponent<ColorPickerUI>();
				((Component)this).gameObject.AddComponent<ArmorTintManager>();
				GameObject val = new GameObject("ArmorColors_Debug");
				Object.DontDestroyOnLoad((Object)(object)val);
				val.AddComponent<ArmorDressDebug>();
				Log.LogInfo((object)"ArmorColors loaded. Numpad * = color picker, Numpad 0 = debug dump.");
			}
			catch (Exception arg)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)$"[ArmorColorsPlugin] Failed to initialise: {arg}");
			}
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
	public class ArmorDressDebug : MonoBehaviour
	{
		private static readonly BindingFlags Flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

		private static readonly (string label, string nameField, string instanceField, bool single)[] Slots = new(string, string, string, bool)[6]
		{
			("Helmet", "m_helmetItem", "m_helmetItemInstance", true),
			("Chest", "m_chestItem", "m_chestItemInstances", false),
			("Legs", "m_legItem", "m_legItemInstances", false),
			("Shoulder", "m_shoulderItem", "m_shoulderItemInstances", false),
			("Utility", "m_utilityItem", "m_utilityItemInstances", false),
			("Trinket", "m_trinketItem", "m_trinketItemInstances", false)
		};

		private float _autoTimer = 0f;

		private const float AutoInterval = 5f;

		private bool _invisibleDumpFired = false;

		private void Start()
		{
			ArmorColorsPlugin.Log.LogInfo((object)("[ArmorDressDebug] Component alive on GO: " + ((Object)((Component)this).gameObject).name));
			Dump("STARTUP");
		}

		private void Update()
		{
			_autoTimer += Time.deltaTime;
			if (_autoTimer >= 5f)
			{
				_autoTimer = 0f;
				if ((Object)(object)Player.m_localPlayer != (Object)null)
				{
					Dump("AUTO");
				}
			}
			if (Input.GetKeyDown((KeyCode)256))
			{
				Dump("MANUAL");
			}
			if (Input.GetKeyDown((KeyCode)288))
			{
				try
				{
					DumpStands();
				}
				catch (Exception arg)
				{
					ArmorColorsPlugin.Log.LogError((object)$"[DumpStands] Exception: {arg}");
				}
			}
			if (!_invisibleDumpFired && (Object)(object)Player.m_localPlayer != (Object)null)
			{
				CheckForInvisibleStandDress();
			}
		}

		private void CheckForInvisibleStandDress()
		{
			Type typeFromHandle = typeof(VisEquipment);
			ArmorStand[] array = Object.FindObjectsOfType<ArmorStand>();
			foreach (ArmorStand val in array)
			{
				VisEquipment componentInChildren = ((Component)val).GetComponentInChildren<VisEquipment>();
				if ((Object)(object)componentInChildren == (Object)null)
				{
					continue;
				}
				string value = typeFromHandle.GetField("m_chestItem", Flags)?.GetValue(componentInChildren) as string;
				if (string.IsNullOrEmpty(value))
				{
					continue;
				}
				object? obj = typeFromHandle.GetField("m_visual", Flags)?.GetValue(componentInChildren);
				GameObject val2 = (GameObject)((obj is GameObject) ? obj : null);
				if ((Object)(object)val2 == (Object)null)
				{
					continue;
				}
				Renderer[] componentsInChildren = val2.GetComponentsInChildren<Renderer>(true);
				foreach (Renderer val3 in componentsInChildren)
				{
					if (!val3.enabled)
					{
						continue;
					}
					Material[] materials = val3.materials;
					foreach (Material val4 in materials)
					{
						if (val4.HasProperty("_MainTex"))
						{
							Texture texture = val4.GetTexture("_MainTex");
							Texture2D val5 = (Texture2D)(object)((texture is Texture2D) ? texture : null);
							if ((Object)(object)val5 == (Object)null || !Object.op_Implicit((Object)(object)val5) || ((Object)val5).name.StartsWith("tinted_"))
							{
								_invisibleDumpFired = true;
								ArmorColorsPlugin.Log.LogInfo((object)("[ArmorDressDebug] INVISIBLE RENDERER DETECTED on stand mat='" + ((Object)val4).name + "' _MainTex='" + (((Object)(object)val5 != (Object)null) ? ((Object)val5).name : "NULL") + "' -- dumping stands now"));
								DumpStands();
								return;
							}
						}
					}
				}
			}
		}

		private void Dump(string trigger)
		{
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_03aa: Unknown result type (might be due to invalid IL or missing references)
			ManualLogSource log = ArmorColorsPlugin.Log;
			log.LogInfo((object)("====== ArmorColors DEBUG [" + trigger + "] ======"));
			if ((Object)(object)ArmorTintManager.Instance != (Object)null)
			{
				ArmorTintManager.Instance.ResetColorLog();
			}
			log.LogInfo((object)("TintManager.Instance: " + (((Object)(object)ArmorTintManager.Instance == (Object)null) ? "NULL !!!" : "alive")));
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				log.LogInfo((object)"Player.m_localPlayer: NULL (not in-game yet)");
				log.LogInfo((object)"===========================================");
				return;
			}
			string playerName = localPlayer.GetPlayerName();
			log.LogInfo((object)("Player name: '" + playerName + "'"));
			VisEquipment component = ((Component)localPlayer).GetComponent<VisEquipment>();
			if ((Object)(object)component == (Object)null)
			{
				log.LogInfo((object)"VisEquipment: NULL");
				log.LogInfo((object)"===========================================");
				return;
			}
			log.LogInfo((object)$"VisEquipment instance ID: {((Object)component).GetInstanceID()}");
			Type typeFromHandle = typeof(VisEquipment);
			bool flag = false;
			(string, string, string, bool)[] slots = Slots;
			for (int i = 0; i < slots.Length; i++)
			{
				(string, string, string, bool) tuple = slots[i];
				string item = tuple.Item1;
				string item2 = tuple.Item2;
				string item3 = tuple.Item3;
				bool item4 = tuple.Item4;
				string text = typeFromHandle.GetField(item2, Flags)?.GetValue(component) as string;
				if (string.IsNullOrEmpty(text))
				{
					continue;
				}
				flag = true;
				Color color = ArmorColorConfig.GetColor(playerName, text);
				log.LogInfo((object)$"  [{item}] item='{text}' configColor=a:{color.a:F2} r:{color.r:F2} g:{color.g:F2} b:{color.b:F2}");
				List<GameObject> list = new List<GameObject>();
				if (item4)
				{
					object? obj = typeFromHandle.GetField(item3, Flags)?.GetValue(component);
					GameObject val = (GameObject)((obj is GameObject) ? obj : null);
					if ((Object)(object)val != (Object)null)
					{
						list.Add(val);
					}
				}
				else if (typeFromHandle.GetField(item3, Flags)?.GetValue(component) is List<GameObject> collection)
				{
					list.AddRange(collection);
				}
				if (list.Count == 0)
				{
					log.LogInfo((object)"    Slot GOs: NONE — item not yet instantiated by VisEquipment");
					continue;
				}
				foreach (GameObject item5 in list)
				{
					if ((Object)(object)item5 == (Object)null)
					{
						log.LogInfo((object)"    GO: null");
						continue;
					}
					log.LogInfo((object)$"    GO: '{((Object)item5).name}' active={item5.activeInHierarchy}");
					Renderer[] componentsInChildren = item5.GetComponentsInChildren<Renderer>(true);
					foreach (Renderer val2 in componentsInChildren)
					{
						log.LogInfo((object)$"      Renderer: {((object)val2).GetType().Name} '{((Object)((Component)val2).gameObject).name}' enabled={val2.enabled}");
						Material[] materials = val2.materials;
						foreach (Material val3 in materials)
						{
							object obj2;
							if (!val3.HasProperty("_MainTex"))
							{
								obj2 = "no_MainTex";
							}
							else
							{
								Texture texture = val3.GetTexture("_MainTex");
								obj2 = ((texture != null) ? ((Object)texture).name : null) ?? "null";
							}
							string text2 = (string)obj2;
							string text3 = (val3.HasProperty("_Color") ? $"{val3.color}" : "no_Color");
							log.LogInfo((object)("        mat='" + ((Object)val3).name + "' _MainTex='" + text2 + "' _Color=" + text3));
						}
					}
				}
			}
			if (!flag)
			{
				log.LogInfo((object)"  No items equipped in any slot");
			}
			object? obj3 = typeFromHandle.GetField("m_visual", Flags)?.GetValue(component);
			GameObject val4 = (GameObject)((obj3 is GameObject) ? obj3 : null);
			if ((Object)(object)val4 == (Object)null)
			{
				log.LogInfo((object)"  m_visual: NULL");
			}
			else
			{
				log.LogInfo((object)$"  m_visual: '{((Object)val4).name}' active={val4.activeInHierarchy}");
				Renderer[] componentsInChildren2 = val4.GetComponentsInChildren<Renderer>(true);
				foreach (Renderer val5 in componentsInChildren2)
				{
					log.LogInfo((object)$"    Renderer: {((object)val5).GetType().Name} '{((Object)((Component)val5).gameObject).name}' enabled={val5.enabled}");
					Material[] materials2 = val5.materials;
					foreach (Material val6 in materials2)
					{
						object obj4;
						if (!val6.HasProperty("_MainTex"))
						{
							obj4 = "-";
						}
						else
						{
							Texture texture2 = val6.GetTexture("_MainTex");
							obj4 = ((texture2 != null) ? ((Object)texture2).name : null) ?? "null";
						}
						string text4 = (string)obj4;
						object obj5;
						if (!val6.HasProperty("_ChestTex"))
						{
							obj5 = "-";
						}
						else
						{
							Texture texture3 = val6.GetTexture("_ChestTex");
							obj5 = ((texture3 != null) ? ((Object)texture3).name : null) ?? "null";
						}
						string text5 = (string)obj5;
						log.LogInfo((object)("      mat='" + ((Object)val6).name + "' _MainTex='" + text4 + "' _ChestTex='" + text5 + "'"));
					}
				}
			}
			object? obj6 = typeFromHandle.GetField("m_bodyModel", Flags)?.GetValue(component);
			SkinnedMeshRenderer val7 = (SkinnedMeshRenderer)((obj6 is SkinnedMeshRenderer) ? obj6 : null);
			log.LogInfo((object)("  m_bodyModel: " + (((Object)(object)val7 == (Object)null) ? "NULL" : ("found enabled=" + ((Renderer)val7).enabled))));
			log.LogInfo((object)"===========================================");
		}

		private void DumpStands()
		{
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: 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_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_06e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e8: Unknown result type (might be due to invalid IL or missing references)
			ManualLogSource log = ArmorColorsPlugin.Log;
			log.LogInfo((object)"====== ArmorColors STAND DEBUG (searching...) ======");
			ArmorStand[] array;
			try
			{
				array = Object.FindObjectsOfType<ArmorStand>();
			}
			catch (Exception ex)
			{
				log.LogError((object)("FindObjectsOfType<ArmorStand> threw: " + ex.Message));
				return;
			}
			log.LogInfo((object)$"Found {array.Length} ArmorStand(s)");
			ArmorStand[] array2 = array;
			foreach (ArmorStand val in array2)
			{
				ZNetView component = ((Component)val).GetComponent<ZNetView>();
				if ((Object)(object)component == (Object)null || !component.IsValid())
				{
					log.LogInfo((object)"  stand: no valid ZNetView");
					continue;
				}
				string text = $"stand_{component.GetZDO().m_uid}";
				log.LogInfo((object)("  Stand key: " + text));
				VisEquipment componentInChildren = ((Component)val).GetComponentInChildren<VisEquipment>();
				if ((Object)(object)componentInChildren == (Object)null)
				{
					log.LogInfo((object)"    VisEquipment: NULL");
					continue;
				}
				log.LogInfo((object)$"    VisEquipment instanceID: {((Object)componentInChildren).GetInstanceID()}");
				Type typeFromHandle = typeof(VisEquipment);
				string[] array3 = new string[5] { "m_helmetItem", "m_chestItem", "m_legItem", "m_shoulderItem", "m_utilityItem" };
				string[] array4 = new string[5] { "helmet", "chest", "leg", "shoulder", "utility" };
				for (int j = 0; j < array3.Length; j++)
				{
					string text2 = typeFromHandle.GetField(array3[j], Flags)?.GetValue(componentInChildren) as string;
					if (!string.IsNullOrEmpty(text2))
					{
						Color color = ArmorColorConfig.GetColor(text, text2);
						log.LogInfo((object)$"    [{array4[j]}] item='{text2}' configColor=a:{color.a:F2} r:{color.r:F2} g:{color.g:F2} b:{color.b:F2}");
					}
				}
				string[] array5 = new string[5] { "m_helmetItem", "m_chestItem", "m_legItem", "m_shoulderItem", "m_utilityItem" };
				string[] array6 = new string[5] { "m_helmetItemInstance", "m_chestItemInstances", "m_legItemInstances", "m_shoulderItemInstances", "m_utilityItemInstances" };
				bool[] array7 = new bool[5] { true, false, false, false, false };
				string[] array8 = new string[5] { "helmet", "chest", "leg", "shoulder", "utility" };
				for (int k = 0; k < array5.Length; k++)
				{
					string text3 = typeFromHandle.GetField(array5[k], Flags)?.GetValue(componentInChildren) as string;
					if (string.IsNullOrEmpty(text3))
					{
						continue;
					}
					List<GameObject> list = new List<GameObject>();
					if (array7[k])
					{
						object? obj = typeFromHandle.GetField(array6[k], Flags)?.GetValue(componentInChildren);
						GameObject val2 = (GameObject)((obj is GameObject) ? obj : null);
						if ((Object)(object)val2 != (Object)null)
						{
							list.Add(val2);
						}
					}
					else if (typeFromHandle.GetField(array6[k], Flags)?.GetValue(componentInChildren) is List<GameObject> collection)
					{
						list.AddRange(collection);
					}
					log.LogInfo((object)("    [" + array8[k] + "] item='" + text3 + "' slotGOs=" + list.Count));
					foreach (GameObject item in list)
					{
						if ((Object)(object)item == (Object)null)
						{
							log.LogInfo((object)"      GO: null");
							continue;
						}
						log.LogInfo((object)("      GO: '" + ((Object)item).name + "' active=" + item.activeInHierarchy));
						Renderer[] componentsInChildren = item.GetComponentsInChildren<Renderer>(true);
						foreach (Renderer val3 in componentsInChildren)
						{
							Material[] materials = val3.materials;
							foreach (Material val4 in materials)
							{
								object obj2;
								if (!val4.HasProperty("_MainTex"))
								{
									obj2 = "-";
								}
								else
								{
									Texture texture = val4.GetTexture("_MainTex");
									obj2 = ((texture != null) ? ((Object)texture).name : null) ?? "null";
								}
								string text4 = (string)obj2;
								object obj3;
								if (!val4.HasProperty("_Color"))
								{
									obj3 = "no_Color";
								}
								else
								{
									Color color2 = val4.color;
									obj3 = ((object)(Color)(ref color2)).ToString();
								}
								string text5 = (string)obj3;
								log.LogInfo((object)("        mat='" + ((Object)val4).name + "' _MainTex='" + text4 + "' _Color=" + text5));
							}
						}
					}
				}
				object? obj4 = typeFromHandle.GetField("m_visual", Flags)?.GetValue(componentInChildren);
				GameObject val5 = (GameObject)((obj4 is GameObject) ? obj4 : null);
				log.LogInfo((object)("    m_visual: " + (((Object)(object)val5 == (Object)null) ? "NULL" : ("'" + ((Object)val5).name + "' active=" + val5.activeInHierarchy))));
				if ((Object)(object)val5 != (Object)null)
				{
					Renderer[] componentsInChildren2 = val5.GetComponentsInChildren<Renderer>(true);
					foreach (Renderer val6 in componentsInChildren2)
					{
						log.LogInfo((object)("      Renderer: " + ((object)val6).GetType().Name + " '" + ((Object)((Component)val6).gameObject).name + "'"));
						Material[] materials2 = val6.materials;
						foreach (Material val7 in materials2)
						{
							object obj5;
							if (!val7.HasProperty("_MainTex"))
							{
								obj5 = "-";
							}
							else
							{
								Texture texture2 = val7.GetTexture("_MainTex");
								obj5 = ((texture2 != null) ? ((Object)texture2).name : null) ?? "null";
							}
							string text6 = (string)obj5;
							string text7 = (val7.HasProperty("_Color") ? $"{val7.color}" : "no_Color");
							Shader shader = val7.shader;
							string text8 = ((shader != null) ? ((Object)shader).name : null) ?? "?";
							log.LogInfo((object)("        mat='" + ((Object)val7).name + "' shader='" + text8 + "' _MainTex='" + text6 + "' _Color=" + text7));
						}
					}
				}
				object? obj6 = typeFromHandle.GetField("m_bodyModel", Flags)?.GetValue(componentInChildren);
				SkinnedMeshRenderer val8 = (SkinnedMeshRenderer)((obj6 is SkinnedMeshRenderer) ? obj6 : null);
				if ((Object)(object)val8 == (Object)null)
				{
					log.LogInfo((object)"    m_bodyModel: NULL");
					continue;
				}
				log.LogInfo((object)("    m_bodyModel: found enabled=" + ((Renderer)val8).enabled));
				Material[] materials3 = ((Renderer)val8).materials;
				foreach (Material val9 in materials3)
				{
					object obj7;
					if (!val9.HasProperty("_MainTex"))
					{
						obj7 = "-";
					}
					else
					{
						Texture texture3 = val9.GetTexture("_MainTex");
						obj7 = ((texture3 != null) ? ((Object)texture3).name : null) ?? "null";
					}
					string text9 = (string)obj7;
					object obj8;
					if (!val9.HasProperty("_ChestTex"))
					{
						obj8 = "-";
					}
					else
					{
						Texture texture4 = val9.GetTexture("_ChestTex");
						obj8 = ((texture4 != null) ? ((Object)texture4).name : null) ?? "null";
					}
					string text10 = (string)obj8;
					Texture2D val10 = (Texture2D)(val9.HasProperty("_ChestTex") ? /*isinst with value type is only supported in some contexts*/: null);
					string text11 = (((Object)(object)val10 != (Object)null) ? (((Texture)val10).width + "x" + ((Texture)val10).height) : "n/a");
					string[] obj9 = new string[10]
					{
						"      body mat='",
						((Object)val9).name,
						"' shader='",
						null,
						null,
						null,
						null,
						null,
						null,
						null
					};
					Shader shader2 = val9.shader;
					obj9[3] = ((shader2 != null) ? ((Object)shader2).name : null) ?? "?";
					obj9[4] = "' _MainTex='";
					obj9[5] = text9;
					obj9[6] = "' _ChestTex='";
					obj9[7] = text10;
					obj9[8] = "' chestTexSize=";
					obj9[9] = text11;
					log.LogInfo((object)string.Concat(obj9));
				}
			}
			log.LogInfo((object)"===========================================");
		}
	}
	public static class ArmorStandSync
	{
		private static readonly BindingFlags Flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

		private const string ZdoPrefix = "ArmorColor_";

		private static readonly string[] SlotNames = new string[5] { "helmet", "chest", "leg", "shoulder", "utility" };

		private static readonly string[] LegacySlotNames = new string[5] { "helmet", "chest", "legs", "cape", "utility" };

		private static readonly string[] ItemFields = new string[5] { "m_helmetItem", "m_chestItem", "m_legItem", "m_shoulderItem", "m_utilityItem" };

		public static void SetStandColor(ZNetView znv, string slot, Color color)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)znv == (Object)null) && znv.IsValid())
			{
				znv.GetZDO().Set("ArmorColor_" + slot, ColorUtility.ToHtmlStringRGBA(color));
			}
		}

		public static bool TryGetStandColor(ZNetView znv, string slot, out Color color)
		{
			//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)
			color = Color.clear;
			if ((Object)(object)znv == (Object)null || !znv.IsValid())
			{
				return false;
			}
			string @string = znv.GetZDO().GetString("ArmorColor_" + slot, "");
			if (string.IsNullOrEmpty(@string))
			{
				return false;
			}
			return ColorUtility.TryParseHtmlString("#" + @string, ref color);
		}

		public static void ClearStandColor(ZNetView znv, string slot)
		{
			if (!((Object)(object)znv == (Object)null) && znv.IsValid())
			{
				znv.GetZDO().Set("ArmorColor_" + slot, "");
			}
		}

		public static void ApplyStandTints(VisEquipment ve, ZNetView znv)
		{
			//IL_002a: 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_0086: 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)
			if ((Object)(object)znv == (Object)null || !znv.IsValid())
			{
				return;
			}
			string charKey = $"stand_{znv.GetZDO().m_uid}";
			Type typeFromHandle = typeof(VisEquipment);
			for (int i = 0; i < SlotNames.Length; i++)
			{
				if ((TryGetStandColor(znv, SlotNames[i], out var color) && color.a != 0f) || (TryGetStandColor(znv, LegacySlotNames[i], out color) && color.a != 0f))
				{
					string text = typeFromHandle.GetField(ItemFields[i], Flags)?.GetValue(ve) as string;
					if (!string.IsNullOrEmpty(text))
					{
						ArmorColorConfig.SetColor(charKey, text, color);
					}
				}
			}
		}
	}
	public class ArmorTintManager : MonoBehaviour
	{
		private class TexState
		{
			[CompilerGenerated]
			private sealed class <DestroyNextFrame>d__4 : IEnumerator<object>, IDisposable, IEnumerator
			{
				private int <>1__state;

				private object <>2__current;

				public Texture2D tex;

				object IEnumerator<object>.Current
				{
					[DebuggerHidden]
					get
					{
						return <>2__current;
					}
				}

				object IEnumerator.Current
				{
					[DebuggerHidden]
					get
					{
						return <>2__current;
					}
				}

				[DebuggerHidden]
				public <DestroyNextFrame>d__4(int <>1__state)
				{
					this.<>1__state = <>1__state;
				}

				[DebuggerHidden]
				void IDisposable.Dispose()
				{
					<>1__state = -2;
				}

				private bool MoveNext()
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<>2__current = null;
						<>1__state = 1;
						return true;
					case 1:
						<>1__state = -1;
						if (Object.op_Implicit((Object)(object)tex))
						{
							Object.Destroy((Object)(object)tex);
						}
						return false;
					}
				}

				bool IEnumerator.MoveNext()
				{
					//ILSpy generated this explicit interface implementation from .override directive in MoveNext
					return this.MoveNext();
				}

				[DebuggerHidden]
				void IEnumerator.Reset()
				{
					throw new NotSupportedException();
				}
			}

			public readonly Dictionary<string, Texture2D> Originals = new Dictionary<string, Texture2D>();

			public readonly Dictionary<string, Texture2D> Tinted = new Dictionary<string, Texture2D>();

			public string LastChestItem = null;

			public void Clear(MonoBehaviour owner)
			{
				foreach (Texture2D value in Originals.Values)
				{
					if (Object.op_Implicit((Object)(object)value))
					{
						owner.StartCoroutine(DestroyNextFrame(value));
					}
				}
				foreach (Texture2D value2 in Tinted.Values)
				{
					if (Object.op_Implicit((Object)(object)value2))
					{
						owner.StartCoroutine(DestroyNextFrame(value2));
					}
				}
				Originals.Clear();
				Tinted.Clear();
			}

			[IteratorStateMachine(typeof(<DestroyNextFrame>d__4))]
			private static IEnumerator DestroyNextFrame(Texture2D tex)
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <DestroyNextFrame>d__4(0)
				{
					tex = tex
				};
			}
		}

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

		private static readonly (string nameField, string instanceField, bool single)[] Slots = new(string, string, bool)[6]
		{
			("m_helmetItem", "m_helmetItemInstance", true),
			("m_chestItem", "m_chestItemInstances", false),
			("m_legItem", "m_legItemInstances", false),
			("m_shoulderItem", "m_shoulderItemInstances", false),
			("m_utilityItem", "m_utilityItemInstances", false),
			("m_trinketItem", "m_trinketItemInstances", false)
		};

		private readonly Dictionary<int, TexState> _texStates = new Dictionary<int, TexState>();

		private readonly Dictionary<int, string> _equipHashes = new Dictionary<int, string>();

		private ArmorStand[] _cachedStands;

		private GameObject[] _cachedCompanions;

		private int _scanTimer = 0;

		private readonly HashSet<string> _loggedMaterials = new HashSet<string>();

		public static ArmorTintManager Instance { get; private set; }

		public void ResetColorLog()
		{
			_loggedMaterials.Clear();
		}

		private void Awake()
		{
			Instance = this;
		}

		private void OnDestroy()
		{
			ClearAllTexStates();
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}

		private TexState GetTexState(VisEquipment ve)
		{
			int instanceID = ((Object)ve).GetInstanceID();
			if (!_texStates.TryGetValue(instanceID, out TexState value))
			{
				value = (_texStates[instanceID] = new TexState());
			}
			return value;
		}

		private void ClearAllTexStates()
		{
			foreach (TexState value in _texStates.Values)
			{
				value.Clear((MonoBehaviour)(object)this);
			}
			_texStates.Clear();
		}

		private void LateUpdate()
		{
			//IL_0358: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer != (Object)null)
			{
				string playerName = localPlayer.GetPlayerName();
				if (!string.IsNullOrEmpty(playerName))
				{
					VisEquipment component = ((Component)localPlayer).GetComponent<VisEquipment>();
					if ((Object)(object)component != (Object)null)
					{
						ProcessVisEquipment(component, ((Humanoid)localPlayer).GetInventory(), playerName);
					}
				}
			}
			_scanTimer++;
			if (_scanTimer >= 60)
			{
				_scanTimer = 0;
				_cachedStands = Object.FindObjectsOfType<ArmorStand>();
				List<GameObject> list = new List<GameObject>();
				ZNetView[] array = Object.FindObjectsOfType<ZNetView>();
				foreach (ZNetView val in array)
				{
					if ((Object)(object)val != (Object)null && ((Object)((Component)val).gameObject).name == "HC_Companion(Clone)")
					{
						list.Add(((Component)val).gameObject);
					}
				}
				_cachedCompanions = list.ToArray();
				List<int> list2 = new List<int>();
				HashSet<int> hashSet = new HashSet<int>();
				if ((Object)(object)localPlayer != (Object)null)
				{
					VisEquipment component2 = ((Component)localPlayer).GetComponent<VisEquipment>();
					if ((Object)(object)component2 != (Object)null)
					{
						hashSet.Add(((Object)component2).GetInstanceID());
					}
				}
				if (_cachedStands != null)
				{
					ArmorStand[] cachedStands = _cachedStands;
					foreach (ArmorStand val2 in cachedStands)
					{
						if (!((Object)(object)val2 == (Object)null))
						{
							VisEquipment componentInChildren = ((Component)val2).GetComponentInChildren<VisEquipment>();
							if ((Object)(object)componentInChildren != (Object)null)
							{
								hashSet.Add(((Object)componentInChildren).GetInstanceID());
							}
						}
					}
				}
				if (_cachedCompanions != null)
				{
					GameObject[] cachedCompanions = _cachedCompanions;
					foreach (GameObject val3 in cachedCompanions)
					{
						if (!((Object)(object)val3 == (Object)null))
						{
							VisEquipment component3 = val3.GetComponent<VisEquipment>();
							if ((Object)(object)component3 != (Object)null)
							{
								hashSet.Add(((Object)component3).GetInstanceID());
							}
						}
					}
				}
				foreach (int key in _texStates.Keys)
				{
					if (!hashSet.Contains(key))
					{
						list2.Add(key);
					}
				}
				foreach (int item in list2)
				{
					_texStates[item].Clear((MonoBehaviour)(object)this);
					_texStates.Remove(item);
					_equipHashes.Remove(item);
				}
			}
			if (_cachedStands != null)
			{
				ArmorStand[] cachedStands2 = _cachedStands;
				foreach (ArmorStand val4 in cachedStands2)
				{
					if ((Object)(object)val4 == (Object)null)
					{
						continue;
					}
					ZNetView component4 = ((Component)val4).GetComponent<ZNetView>();
					if (!((Object)(object)component4 == (Object)null) && component4.IsValid())
					{
						VisEquipment componentInChildren2 = ((Component)val4).GetComponentInChildren<VisEquipment>();
						if (!((Object)(object)componentInChildren2 == (Object)null))
						{
							ArmorStandSync.ApplyStandTints(componentInChildren2, component4);
							ProcessVisEquipment(componentInChildren2, null, $"stand_{component4.GetZDO().m_uid}");
						}
					}
				}
			}
			if (_cachedCompanions == null)
			{
				return;
			}
			GameObject[] cachedCompanions2 = _cachedCompanions;
			foreach (GameObject val5 in cachedCompanions2)
			{
				if ((Object)(object)val5 == (Object)null)
				{
					continue;
				}
				ZNetView component5 = val5.GetComponent<ZNetView>();
				if (!((Object)(object)component5 == (Object)null) && component5.IsValid())
				{
					VisEquipment component6 = val5.GetComponent<VisEquipment>();
					if (!((Object)(object)component6 == (Object)null))
					{
						CompanionSync.SyncToConfig(component5);
						ProcessVisEquipment(component6, null, CompanionSync.GetCharKey(component5));
					}
				}
			}
		}

		private void ProcessVisEquipment(VisEquipment ve, Inventory inv, string charName)
		{
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04de: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_047a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0506: Unknown result type (might be due to invalid IL or missing references)
			//IL_0508: Unknown result type (might be due to invalid IL or missing references)
			//IL_0520: Unknown result type (might be due to invalid IL or missing references)
			//IL_0519: Unknown result type (might be due to invalid IL or missing references)
			//IL_051e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0536: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_034f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_030e: Unknown result type (might be due to invalid IL or missing references)
			Type typeFromHandle = typeof(VisEquipment);
			int instanceID = ((Object)ve).GetInstanceID();
			string equipmentHash = GetEquipmentHash(ve, typeFromHandle);
			if (!_equipHashes.TryGetValue(instanceID, out string value) || equipmentHash != value)
			{
				if (_texStates.TryGetValue(instanceID, out TexState value2))
				{
					value2.Clear((MonoBehaviour)(object)this);
				}
				_texStates[instanceID] = new TexState();
				_equipHashes[instanceID] = equipmentHash;
			}
			Dictionary<string, Color> dictionary = new Dictionary<string, Color>();
			(string, string, bool)[] slots = Slots;
			for (int i = 0; i < slots.Length; i++)
			{
				(string, string, bool) tuple = slots[i];
				string item = tuple.Item1;
				string item2 = tuple.Item2;
				bool item3 = tuple.Item3;
				string text = typeFromHandle.GetField(item, Flags)?.GetValue(ve) as string;
				if (string.IsNullOrEmpty(text))
				{
					continue;
				}
				Color val = Color.clear;
				ItemData val2 = ((inv != null) ? FindItemInInventory(inv, text) : null);
				if (val2 != null && ItemColorSync.TryGetItemColor(val2, out var color))
				{
					val = color;
				}
				else if (charName != null)
				{
					val = ArmorColorConfig.GetColor(charName, text);
				}
				if (val.a == 0f)
				{
					continue;
				}
				List<GameObject> list = new List<GameObject>();
				if (item3)
				{
					object? obj = typeFromHandle.GetField(item2, Flags)?.GetValue(ve);
					GameObject val3 = (GameObject)((obj is GameObject) ? obj : null);
					if ((Object)(object)val3 != (Object)null)
					{
						list.Add(val3);
					}
				}
				else if (typeFromHandle.GetField(item2, Flags)?.GetValue(ve) is List<GameObject> collection)
				{
					list.AddRange(collection);
				}
				foreach (GameObject item5 in list)
				{
					if ((Object)(object)item5 == (Object)null)
					{
						continue;
					}
					Renderer[] componentsInChildren = item5.GetComponentsInChildren<Renderer>(true);
					foreach (Renderer val4 in componentsInChildren)
					{
						Material[] materials = val4.materials;
						foreach (Material val5 in materials)
						{
							if (((object)val4).GetType().Name == "ParticleSystemRenderer")
							{
								if (val5.HasProperty("_Color"))
								{
									val5.color = val;
								}
								continue;
							}
							if (val5.HasProperty("_Color"))
							{
								val5.color = val;
								string item4 = StripSuffix(((Object)val5).name);
								if (!_loggedMaterials.Contains(item4))
								{
									_loggedMaterials.Add(item4);
									ManualLogSource log = ArmorColorsPlugin.Log;
									string[] obj2 = new string[6]
									{
										"[TintManager] SET _Color on '",
										((Object)val5).name,
										"' shader='",
										null,
										null,
										null
									};
									Shader shader = val5.shader;
									obj2[3] = ((shader != null) ? ((Object)shader).name : null);
									obj2[4] = "' ";
									obj2[5] = $"tint={val} readback={val5.color}";
									log.LogInfo((object)string.Concat(obj2));
								}
							}
							string key = StripSuffix(((Object)val5).name);
							if (!dictionary.ContainsKey(key))
							{
								dictionary[key] = val;
							}
						}
					}
				}
			}
			if (dictionary.Count == 0)
			{
				return;
			}
			object? obj3 = typeFromHandle.GetField("m_visual", Flags)?.GetValue(ve);
			GameObject val6 = (GameObject)((obj3 is GameObject) ? obj3 : null);
			if ((Object)(object)val6 != (Object)null)
			{
				Renderer[] componentsInChildren2 = val6.GetComponentsInChildren<Renderer>(true);
				foreach (Renderer val7 in componentsInChildren2)
				{
					if (((object)val7).GetType().Name == "ParticleSystemRenderer")
					{
						continue;
					}
					Material[] materials2 = val7.materials;
					foreach (Material val8 in materials2)
					{
						if (dictionary.TryGetValue(StripSuffix(((Object)val8).name), out var value3) && val8.HasProperty("_Color"))
						{
							val8.color = value3;
						}
					}
				}
			}
			string text2 = typeFromHandle.GetField("m_chestItem", Flags)?.GetValue(ve) as string;
			if (!string.IsNullOrEmpty(text2))
			{
				Color val9 = Color.clear;
				ItemData val10 = ((inv != null) ? FindItemInInventory(inv, text2) : null);
				if (val10 != null && ItemColorSync.TryGetItemColor(val10, out var color2))
				{
					val9 = color2;
				}
				else if (charName != null)
				{
					val9 = ArmorColorConfig.GetColor(charName, text2);
				}
				if (val9.a > 0f)
				{
					TintChestTex(ve, val9);
				}
			}
		}

		private void TintChestTex(VisEquipment ve, Color tint)
		{
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			object? obj = typeof(VisEquipment).GetField("m_bodyModel", Flags)?.GetValue(ve);
			SkinnedMeshRenderer val = (SkinnedMeshRenderer)((obj is SkinnedMeshRenderer) ? obj : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			string text = (typeof(VisEquipment).GetField("m_chestItem", Flags)?.GetValue(ve) as string) ?? "";
			TexState texState = GetTexState(ve);
			if (text != texState.LastChestItem)
			{
				Material[] materials = ((Renderer)val).materials;
				foreach (Material val2 in materials)
				{
					if (!val2.HasProperty("_ChestTex"))
					{
						continue;
					}
					Texture texture = val2.GetTexture("_ChestTex");
					Texture2D val3 = (Texture2D)(object)((texture is Texture2D) ? texture : null);
					if ((Object)(object)val3 != (Object)null && ((Object)val3).name.StartsWith("tinted_"))
					{
						string key = ((Object)val3).name.Substring("tinted_".Length);
						if (texState.Originals.TryGetValue(key, out Texture2D value) && Object.op_Implicit((Object)(object)value))
						{
							val2.SetTexture("_ChestTex", (Texture)(object)value);
						}
					}
				}
				texState.Clear((MonoBehaviour)(object)this);
				texState.LastChestItem = text;
			}
			Material[] materials2 = ((Renderer)val).materials;
			foreach (Material mat in materials2)
			{
				TintMaterialTex(mat, "_ChestTex", tint, texState);
			}
		}

		private void TintMaterialTex(Material mat, string texProp, Color tint, TexState state)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			if (!mat.HasProperty(texProp) || tint == Color.white)
			{
				return;
			}
			Texture texture = mat.GetTexture(texProp);
			Texture2D val = (Texture2D)(object)((texture is Texture2D) ? texture : null);
			if ((Object)(object)val == (Object)null || string.IsNullOrEmpty(((Object)val).name))
			{
				return;
			}
			string text = ColorUtility.ToHtmlStringRGBA(tint);
			string text2 = ((Object)val).name;
			if (text2.StartsWith("tinted_"))
			{
				string text3 = text2.Substring("tinted_".Length);
				if (!state.Originals.ContainsKey(text3))
				{
					return;
				}
				string key = text3 + "|" + text;
				if (state.Tinted.TryGetValue(key, out Texture2D value) && Object.op_Implicit((Object)(object)value) && (Object)(object)mat.GetTexture(texProp) == (Object)(object)value)
				{
					return;
				}
				text2 = text3;
			}
			if (!state.Originals.ContainsKey(text2))
			{
				try
				{
					Texture2D val2 = GpuBlit(val);
					((Object)val2).name = text2;
					state.Originals[text2] = val2;
				}
				catch (Exception ex)
				{
					ArmorColorsPlugin.Log.LogError((object)("[ArmorTintManager] Failed to capture '" + text2 + "': " + ex.Message));
					return;
				}
			}
			string key2 = text2 + "|" + text;
			if (!state.Tinted.TryGetValue(key2, out Texture2D value2))
			{
				if (!state.Originals.TryGetValue(text2, out Texture2D value3))
				{
					return;
				}
				try
				{
					value2 = TintTexture(value3, tint);
					((Object)value2).name = "tinted_" + text2;
					state.Tinted[key2] = value2;
				}
				catch (Exception ex2)
				{
					ArmorColorsPlugin.Log.LogError((object)("[ArmorTintManager] TintTexture failed: " + ex2.Message));
					return;
				}
			}
			mat.SetTexture(texProp, (Texture)(object)value2);
		}

		private static Texture2D GpuBlit(Texture2D source)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			RenderTexture temporary = RenderTexture.GetTemporary(((Texture)source).width, ((Texture)source).height, 0, (RenderTextureFormat)0);
			RenderTexture active = RenderTexture.active;
			Graphics.Blit((Texture)(object)source, temporary);
			RenderTexture.active = temporary;
			Texture2D val = new Texture2D(((Texture)source).width, ((Texture)source).height, (TextureFormat)5, false);
			val.ReadPixels(new Rect(0f, 0f, (float)((Texture)source).width, (float)((Texture)source).height), 0, 0);
			val.Apply();
			RenderTexture.active = active;
			RenderTexture.ReleaseTemporary(temporary);
			return val;
		}

		private static Texture2D TintTexture(Texture2D source, Color tint)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: 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_00c5: 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_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = GpuBlit(source);
			Color[] pixels = val.GetPixels();
			float num = 0.299f * tint.r + 0.587f * tint.g + 0.114f * tint.b;
			float num2 = TintSaturation(tint);
			Color val3 = default(Color);
			Color val4 = default(Color);
			for (int i = 0; i < pixels.Length; i++)
			{
				Color val2 = pixels[i];
				float num3 = 0.299f * val2.r + 0.587f * val2.g + 0.114f * val2.b;
				float num4 = num3 / Mathf.Max(num, 0.001f);
				((Color)(ref val3))..ctor(Mathf.Clamp01(tint.r * num4), Mathf.Clamp01(tint.g * num4), Mathf.Clamp01(tint.b * num4), val2.a);
				((Color)(ref val4))..ctor(val2.r * tint.r, val2.g * tint.g, val2.b * tint.b, val2.a);
				pixels[i] = Color.Lerp(val4, val3, num2);
			}
			val.SetPixels(pixels);
			val.Apply();
			return val;
		}

		private static float TintSaturation(Color c)
		{
			//IL_0009: 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_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: 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)
			float num = Mathf.Max(new float[3] { c.r, c.g, c.b });
			float num2 = Mathf.Min(new float[3] { c.r, c.g, c.b });
			return (num < 0.001f) ? 0f : ((num - num2) / num);
		}

		private static string StripSuffix(string name)
		{
			int num = name.IndexOf(" (Instance)");
			return (num >= 0) ? name.Substring(0, num) : name;
		}

		private static string GetEquipmentHash(VisEquipment ve, Type veType)
		{
			StringBuilder stringBuilder = new StringBuilder();
			string[] array = new string[6] { "m_helmetItem", "m_chestItem", "m_legItem", "m_shoulderItem", "m_utilityItem", "m_trinketItem" };
			foreach (string name in array)
			{
				string value = (veType.GetField(name, Flags)?.GetValue(ve) as string) ?? "";
				stringBuilder.Append(value).Append('|');
			}
			return stringBuilder.ToString();
		}

		private static ItemData FindItemInInventory(Inventory inv, string itemName)
		{
			if (inv == null)
			{
				return null;
			}
			foreach (ItemData allItem in inv.GetAllItems())
			{
				if ((Object)(object)allItem.m_dropPrefab != (Object)null && ((Object)allItem.m_dropPrefab).name.Equals(itemName, StringComparison.OrdinalIgnoreCase))
				{
					return allItem;
				}
			}
			return null;
		}
	}
	public class ColorPickerUI : MonoBehaviour
	{
		private struct EquippedItem
		{
			public string SlotLabel;

			public string ItemName;

			public string DisplayName;

			public string SlotKey;
		}

		private bool _visible = false;

		private Rect _windowRect = new Rect(0f, 0f, 380f, 560f);

		private bool _windowPositioned = false;

		private KeyCode _toggleKey = (KeyCode)268;

		private List<EquippedItem> _items = new List<EquippedItem>();

		private int _selectedIndex = -1;

		private string _lastEquipHash = "";

		private ZNetView _targetCompanion = null;

		private VisEquipment _targetCompanionVE = null;

		private string _targetCompanionName = "";

		private Color _editColor = Color.white;

		private Color _savedColor = Color.white;

		private string _hexInput = "FFFFFFFF";

		private bool _hexDirty = false;

		private GUIStyle _selectedStyle;

		private GUIStyle _swatchStyle;

		private GUIStyle _hexFieldStyle;

		private GUIStyle _headerStyle;

		private Texture2D _selectedTex;

		private Texture2D _swatchTex;

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

		private static readonly MethodInfo _updateVisualsMethod = typeof(VisEquipment).GetMethod("UpdateLodgroup", Flags);

		private static readonly (string label, string field)[] SlotDefs = new(string, string)[6]
		{
			("Helmet", "m_helmetItem"),
			("Chest", "m_chestItem"),
			("Legs", "m_legItem"),
			("Cape", "m_shoulderItem"),
			("Utility", "m_utilityItem"),
			("Trinket", "m_trinketItem")
		};

		private void Update()
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (Input.GetKeyDown(_toggleKey))
				{
					_visible = !_visible;
					if (_visible)
					{
						_windowPositioned = false;
						RefreshEquippedItems();
					}
				}
				if (_visible)
				{
					string equipHash = GetEquipHash();
					if (equipHash != _lastEquipHash)
					{
						RefreshEquippedItems();
					}
				}
			}
			catch (Exception arg)
			{
				ArmorColorsPlugin.Log.LogError((object)$"[ColorPickerUI.Update] {arg}");
			}
		}

		private void OnGUI()
		{
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Expected O, but got Unknown
			//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)
			if (!_visible)
			{
				return;
			}
			if (!_windowPositioned)
			{
				((Rect)(ref _windowRect)).x = (float)Screen.width / 2f - ((Rect)(ref _windowRect)).width / 2f;
				((Rect)(ref _windowRect)).y = (float)Screen.height / 2f - ((Rect)(ref _windowRect)).height / 2f;
				_windowPositioned = true;
			}
			try
			{
				if (_selectedStyle == null)
				{
					BuildStyles();
				}
				string text = (((Object)(object)Player.m_localPlayer != (Object)null) ? VisEquipmentPatch.GetCharacterName(Player.m_localPlayer) : "");
				string text2 = (((Object)(object)_targetCompanion != (Object)null) ? ("  ⚔  Coloring: " + _targetCompanionName) : (string.IsNullOrEmpty(text) ? "  ⚔  Armor Colors" : ("  ⚔  " + text + "'s Armor Colors")));
				_windowRect = GUI.Window(0, _windowRect, new WindowFunction(DrawWindow), text2);
			}
			catch (Exception arg)
			{
				ArmorColorsPlugin.Log.LogError((object)$"[ColorPickerUI.OnGUI] {arg}");
				_visible = false;
			}
		}

		private void OnDestroy()
		{
			if ((Object)(object)_selectedTex != (Object)null)
			{
				Object.Destroy((Object)(object)_selectedTex);
			}
			if ((Object)(object)_swatchTex != (Object)null)
			{
				Object.Destroy((Object)(object)_swatchTex);
			}
		}

		private void DrawWindow(int id)
		{
			//IL_0688: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bb: Invalid comparison between Unknown and I4
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c9: Invalid comparison between Unknown and I4
			//IL_0361: Unknown result type (might be due to invalid IL or missing references)
			//IL_0366: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_042d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0469: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0520: Unknown result type (might be due to invalid IL or missing references)
			//IL_054c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0568: Unknown result type (might be due to invalid IL or missing references)
			//IL_056b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_057d: Unknown result type (might be due to invalid IL or missing references)
			//IL_057f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0586: Unknown result type (might be due to invalid IL or missing references)
			//IL_0303: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.Space(6f);
			GUILayout.Label("EQUIPPED ITEMS", _headerStyle, Array.Empty<GUILayoutOption>());
			GUILayout.Space(2f);
			if (_items.Count == 0)
			{
				GUILayout.Label("  No armor equipped.", Array.Empty<GUILayoutOption>());
			}
			else
			{
				Player localPlayer = Player.m_localPlayer;
				string charKey = (((Object)(object)_targetCompanion != (Object)null) ? CompanionSync.GetCharKey(_targetCompanion) : (((Object)(object)localPlayer != (Object)null) ? VisEquipmentPatch.GetCharacterName(localPlayer) : ""));
				for (int i = 0; i < _items.Count; i++)
				{
					EquippedItem equippedItem = _items[i];
					GUIStyle val = (GUIStyle)((i == _selectedIndex) ? ((object)_selectedStyle) : ((object)GUI.skin.button));
					Color color = ArmorColorConfig.GetColor(charKey, equippedItem.ItemName);
					string text = ((color.a > 0f) ? "● " : "○ ");
					if (GUILayout.Button(text + "[" + equippedItem.SlotLabel + "]  " + equippedItem.DisplayName, val, Array.Empty<GUILayoutOption>()))
					{
						SelectItem(i);
					}
				}
			}
			GUILayout.Space(10f);
			if (_selectedIndex >= 0 && _selectedIndex < _items.Count)
			{
				GUILayout.Label("EDITING: " + _items[_selectedIndex].DisplayName.ToUpper(), _headerStyle, Array.Empty<GUILayoutOption>());
				GUILayout.Space(6f);
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Label("HEX", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(36f) });
				GUILayout.Label("#", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(12f) });
				GUI.SetNextControlName("HexField");
				string text2 = GUILayout.TextField(_hexInput, 8, _hexFieldStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) });
				if (text2 != _hexInput)
				{
					_hexInput = text2.ToUpper();
					_hexDirty = true;
					Color editColor = default(Color);
					if ((text2.Length == 6 || text2.Length == 8) && ColorUtility.TryParseHtmlString("#" + text2, ref editColor))
					{
						_editColor = editColor;
						_hexDirty = false;
					}
				}
				if ((int)Event.current.type == 4 && (int)Event.current.keyCode == 13 && GUI.GetNameOfFocusedControl() == "HexField")
				{
					Color editColor2 = default(Color);
					if (ColorUtility.TryParseHtmlString("#" + _hexInput, ref editColor2))
					{
						_editColor = editColor2;
						_hexDirty = false;
					}
					Event.current.Use();
				}
				GUILayout.FlexibleSpace();
				GUILayout.EndHorizontal();
				GUILayout.Space(8f);
				GUILayout.Label("PREVIEW", _headerStyle, Array.Empty<GUILayoutOption>());
				GUILayout.Space(2f);
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				Color color2 = GUI.color;
				GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(160f) });
				GUILayout.Label("New", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(160f) });
				GUI.color = _editColor;
				GUILayout.Box(GUIContent.none, _swatchStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(160f),
					GUILayout.Height(50f)
				});
				GUI.color = color2;
				GUILayout.EndVertical();
				GUILayout.Space(8f);
				GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(160f) });
				GUILayout.Label("Saved", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(160f) });
				GUI.color = _savedColor;
				GUILayout.Box(GUIContent.none, _swatchStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(160f),
					GUILayout.Height(50f)
				});
				GUI.color = color2;
				GUILayout.EndVertical();
				GUILayout.EndHorizontal();
				GUILayout.Space(8f);
				GUILayout.Label("SLIDERS", _headerStyle, Array.Empty<GUILayoutOption>());
				GUILayout.Space(2f);
				SliderRow("R", _editColor.r, new Color(1f, 0f, 0f), out var newValue);
				SliderRow("G", _editColor.g, new Color(0f, 1f, 0f), out var newValue2);
				SliderRow("B", _editColor.b, new Color(0f, 0f, 1f), out var newValue3);
				SliderRow("A", _editColor.a, new Color(1f, 1f, 1f), out var newValue4);
				Color val2 = default(Color);
				((Color)(ref val2))..ctor(newValue, newValue2, newValue3, newValue4);
				if (val2 != _editColor)
				{
					_editColor = val2;
					_hexInput = ColorUtility.ToHtmlStringRGBA(_editColor);
					_hexDirty = false;
				}
				GUILayout.Space(10f);
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				if (GUILayout.Button("Apply", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) }))
				{
					ApplyColor();
				}
				if (GUILayout.Button("Reset to Default", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) }))
				{
					ResetColor();
				}
				GUILayout.EndHorizontal();
			}
			GUILayout.FlexibleSpace();
			GUILayout.Space(4f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("Numpad * to toggle", GUI.skin.box, Array.Empty<GUILayoutOption>());
			if (GUILayout.Button("Refresh", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(70f) }))
			{
				RefreshEquippedItems();
			}
			GUILayout.EndHorizontal();
			GUI.DragWindow(new Rect(0f, 0f, 10000f, 24f));
		}

		private void RefreshEquippedItems()
		{
			//IL_00a9: 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)
			_items.Clear();
			_selectedIndex = -1;
			_targetCompanion = null;
			_targetCompanionVE = null;
			_targetCompanionName = "";
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return;
			}
			float num = 5f;
			ZNetView[] array = Object.FindObjectsOfType<ZNetView>();
			foreach (ZNetView val in array)
			{
				if (!((Object)(object)val == (Object)null) && val.IsValid() && !(((Object)((Component)val).gameObject).name != "HC_Companion(Clone)"))
				{
					float num2 = Vector3.Distance(((Component)localPlayer).transform.position, ((Component)val).transform.position);
					if (num2 < num)
					{
						num = num2;
						_targetCompanion = val;
						_targetCompanionVE = ((Component)val).GetComponent<VisEquipment>();
						_targetCompanionName = val.GetZDO().GetString("HC_Name", ((Object)((Component)val).gameObject).name);
					}
				}
			}
			VisEquipment obj;
			if ((Object)(object)_targetCompanion != (Object)null && (Object)(object)_targetCompanionVE != (Object)null)
			{
				obj = _targetCompanionVE;
				string charKey = CompanionSync.GetCharKey(_targetCompanion);
				ArmorColorsPlugin.Log.LogInfo((object)("[ColorPickerUI] Targeting companion " + _targetCompanionName));
			}
			else
			{
				obj = ((Component)localPlayer).GetComponent<VisEquipment>();
				string charKey = VisEquipmentPatch.GetCharacterName(localPlayer);
				if (charKey == null)
				{
					return;
				}
			}
			Type typeFromHandle = typeof(VisEquipment);
			(string, string)[] slotDefs = SlotDefs;
			for (int j = 0; j < slotDefs.Length; j++)
			{
				(string, string) tuple = slotDefs[j];
				string item = tuple.Item1;
				string item2 = tuple.Item2;
				string text = typeFromHandle.GetField(item2, Flags)?.GetValue(obj) as string;
				if (!string.IsNullOrEmpty(text))
				{
					_items.Add(new EquippedItem
					{
						SlotLabel = item,
						ItemName = text,
						DisplayName = Prettify(text),
						SlotKey = item2.Replace("m_", "").Replace("Item", "")
					});
				}
			}
			ArmorColorsPlugin.Log.LogInfo((object)$"[ColorPickerUI] Found {_items.Count} equipped item(s).");
			_lastEquipHash = GetEquipHash();
		}

		private void SelectItem(int index)
		{
			//IL_005a: 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_0066: 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_0072: Unknown result type (might be due to invalid IL or missing references)
			_selectedIndex = index;
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null))
			{
				string text = (((Object)(object)_targetCompanion != (Object)null) ? CompanionSync.GetCharKey(_targetCompanion) : VisEquipmentPatch.GetCharacterName(localPlayer));
				if (text != null)
				{
					_editColor = ArmorColorConfig.GetColor(text, _items[index].ItemName);
					_savedColor = _editColor;
					_hexInput = ColorUtility.ToHtmlStringRGBA(_editColor);
					_hexDirty = false;
				}
			}
		}

		private void ApplyColor()
		{
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || _selectedIndex < 0)
			{
				return;
			}
			string itemName = _items[_selectedIndex].ItemName;
			string slotKey = _items[_selectedIndex].SlotKey;
			if ((Object)(object)_targetCompanion != (Object)null && (Object)(object)_targetCompanionVE != (Object)null)
			{
				string charKey = CompanionSync.GetCharKey(_targetCompanion);
				ArmorColorConfig.SetColor(charKey, itemName, _editColor);
				CompanionSync.SetColor(_targetCompanion, slotKey, _editColor);
				_updateVisualsMethod?.Invoke(_targetCompanionVE, null);
				ArmorColorsPlugin.Log.LogInfo((object)("[ColorPickerUI] Applied " + slotKey + " to companion " + _targetCompanionName));
			}
			else
			{
				string characterName = VisEquipmentPatch.GetCharacterName(localPlayer);
				if (characterName == null)
				{
					return;
				}
				ArmorColorConfig.SetColor(characterName, itemName, _editColor);
				ItemData val = FindEquippedItem(localPlayer, itemName);
				if (val != null)
				{
					ItemColorSync.SetItemColor(val, _editColor);
				}
				ItemColorSync.BroadcastColor(localPlayer, itemName, _editColor);
				ApplyToNearbyStand(slotKey, _editColor);
				_updateVisualsMethod?.Invoke(((Component)localPlayer).GetComponent<VisEquipment>(), null);
				ArmorColorsPlugin.Log.LogInfo((object)("[ColorPickerUI] Saved color for " + characterName + "::" + itemName));
			}
			_savedColor = _editColor;
		}

		private void ResetColor()
		{
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || _selectedIndex < 0)
			{
				return;
			}
			string itemName = _items[_selectedIndex].ItemName;
			string slotKey = _items[_selectedIndex].SlotKey;
			if ((Object)(object)_targetCompanion != (Object)null && (Object)(object)_targetCompanionVE != (Object)null)
			{
				string charKey = CompanionSync.GetCharKey(_targetCompanion);
				ArmorColorConfig.ClearColor(charKey, itemName);
				CompanionSync.SetColor(_targetCompanion, slotKey, Color.clear);
				_updateVisualsMethod?.Invoke(_targetCompanionVE, null);
			}
			else
			{
				string characterName = VisEquipmentPatch.GetCharacterName(localPlayer);
				if (characterName == null)
				{
					return;
				}
				ArmorColorConfig.ClearColor(characterName, itemName);
				ItemData val = FindEquippedItem(localPlayer, itemName);
				if (val != null)
				{
					ItemColorSync.ClearItemColor(val);
				}
				ItemColorSync.BroadcastReset(localPlayer, itemName);
				ApplyToNearbyStand(slotKey, Color.clear);
				_updateVisualsMethod?.Invoke(((Component)localPlayer).GetComponent<VisEquipment>(), null);
			}
			_editColor = Color.white;
			_savedColor = Color.white;
			_hexInput = "FFFFFFFF";
		}

		private static void ApplyToNearbyStand(string slotKey, Color color)
		{
			//IL_003c: 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_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return;
			}
			ArmorStand val = null;
			float num = 5f;
			ArmorStand[] array = Object.FindObjectsOfType<ArmorStand>();
			foreach (ArmorStand val2 in array)
			{
				float num2 = Vector3.Distance(((Component)localPlayer).transform.position, ((Component)val2).transform.position);
				if (num2 < num)
				{
					num = num2;
					val = val2;
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			ZNetView component = ((Component)val).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid())
			{
				return;
			}
			if (color.a == 0f)
			{
				ArmorStandSync.ClearStandColor(component, slotKey);
			}
			else
			{
				ArmorStandSync.SetStandColor(component, slotKey, color);
			}
			string charKey = $"stand_{component.GetZDO().m_uid}";
			VisEquipment componentInChildren = ((Component)val).GetComponentInChildren<VisEquipment>();
			if (!((Object)(object)componentInChildren != (Object)null))
			{
				return;
			}
			string text = typeof(VisEquipment).GetField("m_" + slotKey + "Item", Flags)?.GetValue(componentInChildren) as string;
			if (!string.IsNullOrEmpty(text))
			{
				if (color.a == 0f)
				{
					ArmorColorConfig.ClearColor(charKey, text);
				}
				else
				{
					ArmorColorConfig.SetColor(charKey, text, color);
				}
			}
		}

		private static void SliderRow(string label, float value, Color labelColor, out float newValue)
		{
			//IL_000c: 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_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			Color contentColor = GUI.contentColor;
			GUI.contentColor = labelColor;
			GUILayout.Label(label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(16f) });
			GUI.contentColor = contentColor;
			newValue = GUILayout.HorizontalSlider(value, 0f, 1f, Array.Empty<GUILayoutOption>());
			GUILayout.Label(Mathf.RoundToInt(newValue * 255f).ToString("D3"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(32f) });
			GUILayout.EndHorizontal();
		}

		private void BuildStyles()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Expected O, but got Unknown
			//IL_00b2: 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_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Expected O, but got Unknown
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Expected O, but got Unknown
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			_selectedTex = MakeTex(new Color(0.2f, 0.5f, 1f, 0.7f));
			_selectedStyle = new GUIStyle(GUI.skin.button)
			{
				fontStyle = (FontStyle)1
			};
			_selectedStyle.normal.background = _selectedTex;
			_selectedStyle.hover.background = _selectedTex;
			_swatchTex = MakeTex(Color.white);
			GUIStyle val = new GUIStyle(GUI.skin.box);
			val.normal.background = _swatchTex;
			_swatchStyle = val;
			_hexFieldStyle = new GUIStyle(GUI.skin.textField)
			{
				fontSize = 14,
				fontStyle = (FontStyle)1,
				alignment = (TextAnchor)3
			};
			_headerStyle = new GUIStyle(GUI.skin.label)
			{
				fontStyle = (FontStyle)1,
				fontSize = 10
			};
			_headerStyle.normal.textColor = new Color(0.7f, 0.85f, 1f);
		}

		private static Texture2D MakeTex(Color col)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			//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_001a: 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_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: 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)
			Texture2D val = new Texture2D(2, 2);
			val.SetPixels((Color[])(object)new Color[4] { col, col, col, col });
			val.Apply();
			return val;
		}

		private string GetEquipHash()
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return "";
			}
			VisEquipment component = ((Component)localPlayer).GetComponent<VisEquipment>();
			StringBuilder stringBuilder = new StringBuilder();
			Type typeFromHandle = typeof(VisEquipment);
			(string, string)[] slotDefs = SlotDefs;
			for (int i = 0; i < slotDefs.Length; i++)
			{
				string item = slotDefs[i].Item2;
				string value = (typeFromHandle.GetField(item, Flags)?.GetValue(component) as string) ?? "";
				stringBuilder.Append(value).Append('|');
			}
			return stringBuilder.ToString();
		}

		private static ItemData FindEquippedItem(Player player, string itemName)
		{
			foreach (ItemData allItem in ((Humanoid)player).GetInventory().GetAllItems())
			{
				if ((Object)(object)allItem.m_dropPrefab != (Object)null && ((Object)allItem.m_dropPrefab).name.Equals(itemName, StringComparison.OrdinalIgnoreCase))
				{
					return allItem;
				}
			}
			return null;
		}

		private static string Prettify(string raw)
		{
			if (string.IsNullOrEmpty(raw))
			{
				return raw;
			}
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append(raw[0]);
			for (int i = 1; i < raw.Length; i++)
			{
				if (char.IsUpper(raw[i]) && !char.IsUpper(raw[i - 1]))
				{
					stringBuilder.Append(' ');
				}
				stringBuilder.Append(raw[i]);
			}
			return stringBuilder.ToString();
		}
	}
	public static class CompanionSync
	{
		private static readonly BindingFlags BF = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

		private const string ZdoPrefix = "ArmorColor_";

		private static readonly string[] Slots = new string[5] { "helmet", "chest", "leg", "shoulder", "utility" };

		public static void SetColor(ZNetView znv, string slot, Color color)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)znv == (Object)null) && znv.IsValid())
			{
				znv.GetZDO().Set("ArmorColor_" + slot, ColorUtility.ToHtmlStringRGBA(color));
			}
		}

		public static bool TryGetColor(ZNetView znv, string slot, out Color color)
		{
			//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)
			color = Color.white;
			if ((Object)(object)znv == (Object)null || !znv.IsValid())
			{
				return false;
			}
			string @string = znv.GetZDO().GetString("ArmorColor_" + slot, "");
			if (string.IsNullOrEmpty(@string))
			{
				return false;
			}
			return ColorUtility.TryParseHtmlString("#" + @string, ref color);
		}

		public static string GetCharKey(ZNetView znv)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)znv == (Object)null || !znv.IsValid())
			{
				return null;
			}
			ZDOID uid = znv.GetZDO().m_uid;
			return "companion_" + ((object)(ZDOID)(ref uid)).ToString();
		}

		public static void SyncToConfig(ZNetView znv)
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)znv == (Object)null || !znv.IsValid())
			{
				return;
			}
			string charKey = GetCharKey(znv);
			VisEquipment component = ((Component)znv).GetComponent<VisEquipment>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			Dictionary<string, string> slotItems = GetSlotItems(component);
			string[] slots = Slots;
			foreach (string text in slots)
			{
				if (slotItems.TryGetValue(text, out var value) && !string.IsNullOrEmpty(value) && TryGetColor(znv, text, out var color))
				{
					ArmorColorConfig.SetColor(charKey, value, color);
				}
			}
		}

		public static Dictionary<string, string> GetSlotItems(VisEquipment ve)
		{
			Type typeFromHandle = typeof(VisEquipment);
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			dictionary["helmet"] = (typeFromHandle.GetField("m_helmetItem", BF)?.GetValue(ve) as string) ?? "";
			dictionary["chest"] = (typeFromHandle.GetField("m_chestItem", BF)?.GetValue(ve) as string) ?? "";
			dictionary["leg"] = (typeFromHandle.GetField("m_legItem", BF)?.GetValue(ve) as string) ?? "";
			dictionary["shoulder"] = (typeFromHandle.GetField("m_shoulderItem", BF)?.GetValue(ve) as string) ?? "";
			dictionary["utility"] = (typeFromHandle.GetField("m_utilityItem", BF)?.GetValue(ve) as string) ?? "";
			return dictionary;
		}
	}
	public static class ItemColorSync
	{
		[HarmonyPatch(typeof(Player), "Awake")]
		public static class PlayerAwakePatch
		{
			[HarmonyPostfix]
			private static void Postfix(Player __instance)
			{
				Player __instance2 = __instance;
				ZNetView component = ((Component)__instance2).GetComponent<ZNetView>();
				if ((Object)(object)component == (Object)null)
				{
					return;
				}
				component.Register<string>("ArmorColors_Sync", (Action<long, string>)delegate(long sender, string payload)
				{
					//IL_008c: Unknown result type (might be due to invalid IL or missing references)
					try
					{
						if (!((Object)(object)__instance2 == (Object)(object)Player.m_localPlayer))
						{
							string[] array = payload.Split(new char[1] { '|' });
							if (array.Length == 2)
							{
								string itemName = array[0];
								string text = array[1];
								string playerName = __instance2.GetPlayerName();
								Color color = default(Color);
								if (text == "RESET")
								{
									ArmorColorConfig.ClearColor(playerName, itemName);
								}
								else if (ColorUtility.TryParseHtmlString("#" + text, ref color))
								{
									ArmorColorConfig.SetColor(playerName, itemName, color);
								}
								VisEquipment component2 = ((Component)__instance2).GetComponent<VisEquipment>();
								typeof(VisEquipment).GetMethod("UpdateLodgroup", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(component2, null);
							}
						}
					}
					catch (Exception ex)
					{
						ArmorColorsPlugin.Log.LogError((object)("[ItemColorSync] RPC error: " + ex.Message));
					}
				});
			}
		}

		private const string CustomDataKey = "ArmorColor";

		private const string RpcName = "ArmorColors_Sync";

		public static bool TryGetItemColor(ItemData item, out Color color)
		{
			//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)
			color = Color.white;
			if (item?.m_customData == null)
			{
				return false;
			}
			if (!item.m_customData.TryGetValue("ArmorColor", out var value))
			{
				return false;
			}
			return ColorUtility.TryParseHtmlString("#" + value, ref color);
		}

		public static void SetItemColor(ItemData item, Color color)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			if (item?.m_customData != null)
			{
				item.m_customData["ArmorColor"] = ColorUtility.ToHtmlStringRGBA(color);
			}
		}

		public static void ClearItemColor(ItemData item)
		{
			item?.m_customData?.Remove("ArmorColor");
		}

		public static void BroadcastColor(Player player, string itemName, Color color)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			ZNetView component = ((Component)player).GetComponent<ZNetView>();
			if (!((Object)(object)component == (Object)null) && component.IsValid())
			{
				component.InvokeRPC(ZNetView.Everybody, "ArmorColors_Sync", new object[1] { itemName + "|" + ColorUtility.ToHtmlStringRGBA(color) });
			}
		}

		public static void BroadcastReset(Player player, string itemName)
		{
			ZNetView component = ((Component)player).GetComponent<ZNetView>();
			if (!((Object)(object)component == (Object)null) && component.IsValid())
			{
				component.InvokeRPC(ZNetView.Everybody, "ArmorColors_Sync", new object[1] { itemName + "|RESET" });
			}
		}
	}
	public static class VisEquipmentPatch
	{
		public static string GetCharacterName(Player player)
		{
			string playerName = player.GetPlayerName();
			return string.IsNullOrEmpty(playerName) ? null : playerName;
		}
	}
}