Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ColorMe v1.0.1
ValheimArmorColors.dll
Decompiled a month agousing 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] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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] [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] [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 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>(); 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 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 text = znv.GetZDO().GetString("ArmorColor_" + slot, ""); if (string.IsNullOrEmpty(text)) { return false; } return ColorUtility.TryParseHtmlString("#" + text, 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 { public readonly Dictionary<string, Texture2D> Originals = new Dictionary<string, Texture2D>(); public readonly Dictionary<string, Texture2D> Tinted = new Dictionary<string, Texture2D>(); public readonly Dictionary<int, Material[]> RendererMats = new Dictionary<int, Material[]>(); public string LastChestItem = null; public void Clear(MonoBehaviour owner) { foreach (Material[] value2 in RendererMats.Values) { if (value2 == null) { continue; } Material[] array = value2; foreach (Material val in array) { if ((Object)(object)val == (Object)null || !val.HasProperty("_MainTex")) { continue; } Texture texture = val.GetTexture("_MainTex"); Texture2D val2 = (Texture2D)(object)((texture is Texture2D) ? texture : null); if ((Object)(object)val2 != (Object)null && ((Object)val2).name.StartsWith("tinted_")) { string key = ((Object)val2).name.Substring("tinted_".Length); if (Originals.TryGetValue(key, out Texture2D value) && Object.op_Implicit((Object)(object)value)) { val.SetTexture("_MainTex", (Texture)(object)value); } } } } RendererMats.Clear(); foreach (Texture2D value3 in Originals.Values) { if (Object.op_Implicit((Object)(object)value3)) { owner.StartCoroutine(DestroyNextFrame((Object)(object)value3)); } } foreach (Texture2D value4 in Tinted.Values) { if (Object.op_Implicit((Object)(object)value4)) { owner.StartCoroutine(DestroyNextFrame((Object)(object)value4)); } } Originals.Clear(); Tinted.Clear(); LastChestItem = null; } private static IEnumerator DestroyNextFrame(Object obj) { yield return null; if (Object.op_Implicit(obj)) { Object.Destroy(obj); } } } 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 string _lastCharName = null; public static ArmorTintManager Instance { get; private set; } private void Awake() { Instance = this; } private void OnEnable() { _lastCharName = null; } private void OnDestroy() { foreach (TexState value in _texStates.Values) { value.Clear((MonoBehaviour)(object)this); } _texStates.Clear(); 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 LateUpdate() { //IL_03d5: 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)) { if (playerName != _lastCharName) { VisEquipment component = ((Component)localPlayer).GetComponent<VisEquipment>(); if ((Object)(object)component != (Object)null) { int instanceID = ((Object)component).GetInstanceID(); if (_texStates.TryGetValue(instanceID, out TexState value)) { value.Clear((MonoBehaviour)(object)this); _texStates.Remove(instanceID); } _equipHashes.Remove(instanceID); } _lastCharName = playerName; } VisEquipment component2 = ((Component)localPlayer).GetComponent<VisEquipment>(); if ((Object)(object)component2 != (Object)null) { ProcessVisEquipment(component2, ((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(); HashSet<int> hashSet = new HashSet<int>(); if ((Object)(object)localPlayer != (Object)null) { VisEquipment component3 = ((Component)localPlayer).GetComponent<VisEquipment>(); if ((Object)(object)component3 != (Object)null) { hashSet.Add(((Object)component3).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 component4 = val3.GetComponent<VisEquipment>(); if ((Object)(object)component4 != (Object)null) { hashSet.Add(((Object)component4).GetInstanceID()); } } } } List<int> list2 = new List<int>(); 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 component5 = ((Component)val4).GetComponent<ZNetView>(); if (!((Object)(object)component5 == (Object)null) && component5.IsValid()) { VisEquipment componentInChildren2 = ((Component)val4).GetComponentInChildren<VisEquipment>(); if (!((Object)(object)componentInChildren2 == (Object)null)) { ArmorStandSync.ApplyStandTints(componentInChildren2, component5); ProcessVisEquipment(componentInChildren2, null, $"stand_{component5.GetZDO().m_uid}"); } } } } if (_cachedCompanions == null) { return; } GameObject[] cachedCompanions2 = _cachedCompanions; foreach (GameObject val5 in cachedCompanions2) { if ((Object)(object)val5 == (Object)null) { continue; } ZNetView component6 = val5.GetComponent<ZNetView>(); if (!((Object)(object)component6 == (Object)null) && component6.IsValid()) { VisEquipment component7 = val5.GetComponent<VisEquipment>(); if (!((Object)(object)component7 == (Object)null)) { CompanionSync.SyncToConfig(component6); ProcessVisEquipment(component7, null, CompanionSync.GetCharKey(component6)); } } } } private void ProcessVisEquipment(VisEquipment ve, Inventory inv, string charName) { //IL_00f9: 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_04d4: 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_04db: Unknown result type (might be due to invalid IL or missing references) //IL_04f1: Unknown result type (might be due to invalid IL or missing references) //IL_0468: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Unknown result type (might be due to invalid IL or missing references) //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_032d: Unknown result type (might be due to invalid IL or missing references) Type typeFromHandle = typeof(VisEquipment); int instanceID = ((Object)ve).GetInstanceID(); bool flag = inv != null; 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; } TexState texState = GetTexState(ve); 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 tint = GetTint(inv, charName, text); if (tint.a == 0f) { continue; } List<GameObject> list = new List<GameObject>(); if (item3) { object? obj = typeFromHandle.GetField(item2, Flags)?.GetValue(ve); GameObject val = (GameObject)((obj is GameObject) ? obj : null); if ((Object)(object)val != (Object)null) { list.Add(val); } } else if (typeFromHandle.GetField(item2, Flags)?.GetValue(ve) is List<GameObject> collection) { list.AddRange(collection); } foreach (GameObject item4 in list) { if ((Object)(object)item4 == (Object)null) { continue; } Renderer[] componentsInChildren = item4.GetComponentsInChildren<Renderer>(true); foreach (Renderer val2 in componentsInChildren) { bool flag2 = ((object)val2).GetType().Name == "ParticleSystemRenderer"; Material[] value3; if (flag && !flag2 && HasCreatureShader(val2)) { int instanceID2 = ((Object)val2).GetInstanceID(); if (!texState.RendererMats.TryGetValue(instanceID2, out value3)) { value3 = val2.materials; texState.RendererMats[instanceID2] = value3; } } else { value3 = val2.materials; } Material[] array = value3; foreach (Material val3 in array) { if ((Object)(object)val3 == (Object)null) { continue; } if (flag2) { if (val3.HasProperty("_Color")) { val3.color = tint; } continue; } if (val3.HasProperty("_Color")) { val3.color = tint; } if (flag) { Shader shader = val3.shader; if (((shader != null) ? ((Object)shader).name : null) == "Custom/Creature") { TintMaterialTex(val3, "_MainTex", tint, texState); } } string key = StripSuffix(((Object)val3).name); if (!dictionary.ContainsKey(key)) { dictionary[key] = tint; } } } } } if (dictionary.Count == 0) { return; } object? obj2 = typeFromHandle.GetField("m_visual", Flags)?.GetValue(ve); GameObject val4 = (GameObject)((obj2 is GameObject) ? obj2 : null); if ((Object)(object)val4 != (Object)null) { Renderer[] componentsInChildren2 = val4.GetComponentsInChildren<Renderer>(true); foreach (Renderer val5 in componentsInChildren2) { if (((object)val5).GetType().Name == "ParticleSystemRenderer") { continue; } Material[] sharedMaterials = val5.sharedMaterials; foreach (Material val6 in sharedMaterials) { if (!((Object)(object)val6 == (Object)null) && dictionary.TryGetValue(StripSuffix(((Object)val6).name), out var value4) && val6.HasProperty("_Color")) { val6.color = value4; } } } } if (!flag) { return; } string text2 = typeFromHandle.GetField("m_chestItem", Flags)?.GetValue(ve) as string; if (!string.IsNullOrEmpty(text2)) { Color tint2 = GetTint(inv, charName, text2); if (tint2.a > 0f) { TintChestTex(ve, tint2, texState); } } } private Color GetTint(Inventory inv, string charName, string itemName) { //IL_0021: 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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0031: 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_0041: Unknown result type (might be due to invalid IL or missing references) ItemData val = ((inv != null) ? FindItemInInventory(inv, itemName) : null); if (val != null && ItemColorSync.TryGetItemColor(val, out var color)) { return color; } if (charName != null) { return ArmorColorConfig.GetColor(charName, itemName); } return Color.clear; } private static bool HasCreatureShader(Renderer r) { Material[] sharedMaterials = r.sharedMaterials; foreach (Material val in sharedMaterials) { if ((Object)(object)val != (Object)null) { Shader shader = val.shader; if (((shader != null) ? ((Object)shader).name : null) == "Custom/Creature") { return true; } } } return false; } private void TintChestTex(VisEquipment ve, Color tint, TexState state) { //IL_0189: 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) ?? ""; if (text != state.LastChestItem) { Material[] materials = ((Renderer)val).materials; foreach (Material val2 in materials) { if ((Object)(object)val2 == (Object)null || !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 (state.Originals.TryGetValue(key, out Texture2D value) && Object.op_Implicit((Object)(object)value)) { val2.SetTexture("_ChestTex", (Texture)(object)value); } } } state.Clear((MonoBehaviour)(object)this); state.LastChestItem = text; } Material[] materials2 = ((Renderer)val).materials; foreach (Material mat in materials2) { TintMaterialTex(mat, "_ChestTex", tint, state); } } 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] GpuBlit failed '" + 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_0040: 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_004c: 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_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0089: 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_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: 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; for (int i = 0; i < pixels.Length; i++) { Color val2 = pixels[i]; float num2 = 0.299f * val2.r + 0.587f * val2.g + 0.114f * val2.b; float num3 = ((num > 0.001f) ? (num2 / num) : 0f); pixels[i] = new Color(Mathf.Clamp01(tint.r * num3), Mathf.Clamp01(tint.g * num3), Mathf.Clamp01(tint.b * num3), val2.a); } val.SetPixels(pixels); val.Apply(); return val; } 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('|'); } stringBuilder.Append(((Object)ve).GetInstanceID()); 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 text = znv.GetZDO().GetString("ArmorColor_" + slot, ""); if (string.IsNullOrEmpty(text)) { return false; } return ColorUtility.TryParseHtmlString("#" + text, ref color); } public unsafe 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*)(&uid))/*cast due to .constrained prefix*/).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) { ZNetView component = ((Component)__instance).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)__instance == (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 = __instance.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)__instance).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; } } }