Please disclose if your mod was created primarily 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.0
ValheimArmorColors.dll
Decompiled 3 hours 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] [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; } } }