using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Mirror; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("EvenMoreSkinColors")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("EvenMoreSkinColors")] [assembly: AssemblyTitle("EvenMoreSkinColors")] [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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace EvenMoreSkinColors { internal static class Compatibility { internal static bool IsMoreSkinColorsPresent { get; private set; } internal static void DetectInstalledMods() { IsMoreSkinColorsPresent = Chainloader.PluginInfos.Values.Any(delegate(PluginInfo info) { string text = info.Metadata.GUID ?? string.Empty; string text2 = info.Metadata.Name ?? string.Empty; return text.Equals("ViViKo.MoreSkinColors", StringComparison.OrdinalIgnoreCase) || text2.Equals("MoreSkinColors", StringComparison.OrdinalIgnoreCase) || text.IndexOf("MoreSkinColors", StringComparison.OrdinalIgnoreCase) >= 0; }); if (IsMoreSkinColorsPresent) { Plugin.Log.LogInfo((object)"Compatibility mode active: detected MoreSkinColors. Vanilla swatches remain untouched; custom tone UI stays additive."); } } } public static class DebugApi { public sealed class LocalState { public bool hasLocalPlayer; public uint localNetId; public int activeLoadoutIndex; public int vanillaSkinColorIndex; public bool customToneEnabled; public string customColorHex; public bool previewOverrideApplied; public bool playerOverrideApplied; public string lastEvent; } public sealed class RemoteState { public uint netId; public bool isLocalPlayer; public int vanillaSkinColorIndex; public bool hasCustomTone; public string customColorHex; public bool overrideApplied; } public sealed class Snapshot { public LocalState local; public List players; } public static LocalState GetLocalState() { //IL_00c1: Unknown result type (might be due to invalid IL or missing references) PlayerInfo localPlayerInfo = GameManager.LocalPlayerInfo; PlayerCosmetics val = (((Object)(object)localPlayerInfo != (Object)null) ? localPlayerInfo.Cosmetics : null); PlayerCosmeticsSwitcher val2 = (((Object)(object)SingletonBehaviour.Instance != (Object)null && (Object)(object)SingletonBehaviour.Instance.characterPreview != (Object)null) ? SingletonBehaviour.Instance.characterPreview.cosmeticsSwitcher : null); return new LocalState { hasLocalPlayer = ((Object)(object)localPlayerInfo != (Object)null), localNetId = (((Object)(object)val != (Object)null) ? ((NetworkBehaviour)val).netId : 0u), activeLoadoutIndex = SkinToneState.ActiveLoadoutIndex, vanillaSkinColorIndex = (((Object)(object)val != (Object)null && (Object)(object)((Component)val).GetComponent() != (Object)null) ? ((Component)val).GetComponent().CurrentSkinColorIndex : (-1)), customToneEnabled = SkinToneState.LocalSelection.Enabled, customColorHex = SkinToneSelection.ToHtml(SkinToneState.LocalSelection.BaseColor), previewOverrideApplied = ((Object)(object)val2 != (Object)null && SkinToneState.LocalSelection.Enabled), playerOverrideApplied = ((Object)(object)val != (Object)null && SkinToneState.LocalSelection.Enabled), lastEvent = SkinToneDebugState.Current.LastEvent }; } public static List GetRemoteStates() { //IL_0113: 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) List list = new List(); foreach (KeyValuePair item in NetworkClient.spawned) { NetworkIdentity value = item.Value; if (!((Object)(object)value == (Object)null)) { PlayerCosmetics val = ((Component)value).GetComponent(); if ((Object)(object)val == (Object)null) { PlayerInfo component = ((Component)value).GetComponent(); val = (((Object)(object)component != (Object)null) ? component.Cosmetics : null); } if (!((Object)(object)val == (Object)null)) { PlayerCosmeticsSwitcher component2 = ((Component)val).GetComponent(); SkinToneSelection selection; bool flag = SkinToneState.TryGetRemoteSelection(((NetworkBehaviour)val).netId, out selection); list.Add(new RemoteState { netId = ((NetworkBehaviour)val).netId, isLocalPlayer = ((NetworkBehaviour)val).isLocalPlayer, vanillaSkinColorIndex = (((Object)(object)component2 != (Object)null) ? component2.CurrentSkinColorIndex : (-1)), hasCustomTone = (((NetworkBehaviour)val).isLocalPlayer ? SkinToneState.LocalSelection.Enabled : (flag && selection.Enabled)), customColorHex = (((NetworkBehaviour)val).isLocalPlayer ? SkinToneSelection.ToHtml(SkinToneState.LocalSelection.BaseColor) : (flag ? SkinToneSelection.ToHtml(selection.BaseColor) : string.Empty)), overrideApplied = (((NetworkBehaviour)val).isLocalPlayer ? SkinToneState.LocalSelection.Enabled : (flag && selection.Enabled)) }); } } } return list; } public static Snapshot GetSnapshot() { return new Snapshot { local = GetLocalState(), players = GetRemoteStates() }; } } [HarmonyPatch] internal static class Patches { [HarmonyPatch(typeof(PlayerCosmetics), "Awake")] [HarmonyPostfix] private static void PlayerCosmeticsAwakePostfix(PlayerCosmetics __instance) { SkinToneFollower skinToneFollower = ((Component)__instance).GetComponent(); if ((Object)(object)skinToneFollower == (Object)null) { skinToneFollower = ((Component)__instance).gameObject.AddComponent(); } skinToneFollower.Initialize(__instance); } [HarmonyPatch(typeof(PlayerCosmetics), "OnStartLocalPlayer")] [HarmonyPostfix] private static void PlayerCosmeticsOnStartLocalPlayerPostfix(PlayerCosmetics __instance) { SkinToneState.OnLocalPlayerStarted(__instance); } [HarmonyPatch(typeof(PlayerCosmeticsSwitcher), "SetSkinColor")] [HarmonyPostfix] private static void PlayerCosmeticsSwitcherSetSkinColorPostfix(PlayerCosmeticsSwitcher __instance) { if (!SkinToneState.IsRevertingToVanilla) { PlayerCosmetics component = ((Component)__instance).GetComponent(); if ((Object)(object)component != (Object)null) { SkinToneState.TryApplyFor(component); } else if ((Object)(object)SingletonBehaviour.Instance != (Object)null && (Object)(object)SingletonBehaviour.Instance.characterPreview != (Object)null && SingletonBehaviour.Instance.characterPreview.cosmeticsSwitcher == __instance) { SkinToneState.ApplyToPreview(SingletonBehaviour.Instance); } } } [HarmonyPatch(typeof(PlayerCustomizationMenu), "Start")] [HarmonyPostfix] private static void PlayerCustomizationMenuStartPostfix(PlayerCustomizationMenu __instance) { //IL_00ae: 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) //IL_0115: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance.skinColorTemplate == (Object)null || (Object)(object)__instance.skinColorTemplate.transform.parent == (Object)null) { return; } Transform val = null; if ((Object)(object)__instance.characterPreview != (Object)null) { val = ((Component)__instance.characterPreview).transform; } if ((Object)(object)val == (Object)null) { Transform parent = __instance.skinColorTemplate.transform.parent; val = (((Object)(object)parent.parent != (Object)null) ? parent.parent : parent); } if ((Object)(object)val.Find("EvenMoreSkinColors_CustomSkinTonePanel") != (Object)null) { return; } foreach (Transform item in ((Object)(object)val.parent != (Object)null) ? val.parent : val) { Transform val2 = item.Find("EvenMoreSkinColors_CustomSkinTonePanel"); if ((Object)(object)val2 != (Object)null && (Object)(object)val2.parent != (Object)(object)val) { Object.Destroy((Object)(object)((Component)val2).gameObject); } } GameObject val3 = new GameObject("EvenMoreSkinColors_CustomSkinTonePanel"); val3.transform.SetParent(val, false); val3.transform.SetAsLastSibling(); val3.AddComponent().Initialize(__instance); SkinToneState.ApplyToPreview(__instance); } [HarmonyPatch(typeof(PlayerCustomizationMenu), "SetLoadout")] [HarmonyPostfix] private static void PlayerCustomizationMenuSetLoadoutPostfix(int index) { SkinToneState.ActivateLoadout(index, applyPreview: true, broadcast: false); } [HarmonyPatch(typeof(PlayerCustomizationMenu), "SetSkinColorIndex")] [HarmonyPostfix] private static void PlayerCustomizationMenuSetSkinColorIndexPostfix(PlayerCustomizationMenu __instance) { SkinToneState.ApplyToPreview(__instance); } [HarmonyPatch(typeof(PlayerCustomizationMenu), "SaveLoadout")] [HarmonyPostfix] private static void PlayerCustomizationMenuSaveLoadoutPostfix() { SkinToneState.ActivateLoadout(SkinToneState.ActiveLoadoutIndex, applyPreview: true, broadcast: true); } } [BepInPlugin("cray.evenmoreskincolors", "EvenMoreSkinColors", "0.2.0")] public class Plugin : BaseUnityPlugin { public const string ModGuid = "cray.evenmoreskincolors"; public const string ModName = "EvenMoreSkinColors"; public const string ModVersion = "0.2.0"; internal static ManualLogSource Log; internal static Plugin Instance; internal ConfigEntry verboseLoggingConfig; private void Awake() { //IL_0081: Unknown result type (might be due to invalid IL or missing references) Instance = this; Log = ((BaseUnityPlugin)this).Logger; verboseLoggingConfig = ((BaseUnityPlugin)this).Config.Bind("Diagnostics", "VerboseLogging", false, "Emit per-event broadcast/receive/apply/revert logs. Off by default — flip on when reporting issues so the log shows the full skin-tone replication trace."); Compatibility.DetectInstalledMods(); SkinToneState.Initialize(((BaseUnityPlugin)this).Config, ((BaseUnityPlugin)this).Logger); SkinToneNetworkSerialization.Register(); NetworkClient.OnConnectedEvent = (Action)Delegate.Combine(NetworkClient.OnConnectedEvent, new Action(SkinToneNetwork.OnClientConnected)); new Harmony("cray.evenmoreskincolors").PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"EvenMoreSkinColors v0.2.0 loaded."); } private void OnDestroy() { NetworkClient.OnConnectedEvent = (Action)Delegate.Remove(NetworkClient.OnConnectedEvent, new Action(SkinToneNetwork.OnClientConnected)); } } internal static class SkinToneDebugState { internal struct Snapshot { public int ActiveLoadoutIndex; public bool LocalCustomToneEnabled; public string LocalColorHex; public uint LastAppliedNetId; public bool LastAppliedWasPreview; public string LastAppliedColorHex; public uint LastBroadcastNetId; public string LastBroadcastColorHex; public uint LastReceivedNetId; public string LastReceivedColorHex; public string LastEvent; } private static Snapshot _snapshot; internal static Snapshot Current => _snapshot; internal static void RecordLoadoutActivated(int loadoutIndex, SkinToneSelection selection) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) _snapshot.ActiveLoadoutIndex = loadoutIndex; _snapshot.LocalCustomToneEnabled = selection.Enabled; _snapshot.LocalColorHex = SkinToneSelection.ToHtml(selection.BaseColor); _snapshot.LastEvent = $"loadout:{loadoutIndex}"; } internal static void RecordSelectionChanged(int loadoutIndex, SkinToneSelection selection) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) _snapshot.ActiveLoadoutIndex = loadoutIndex; _snapshot.LocalCustomToneEnabled = selection.Enabled; _snapshot.LocalColorHex = SkinToneSelection.ToHtml(selection.BaseColor); _snapshot.LastEvent = $"selection:{loadoutIndex}"; } internal static void RecordBroadcast(uint netId, SkinToneSelection selection) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) _snapshot.LastBroadcastNetId = netId; _snapshot.LastBroadcastColorHex = SkinToneSelection.ToHtml(selection.BaseColor); _snapshot.LastEvent = $"broadcast:{netId}"; if ((Object)(object)Plugin.Instance != (Object)null && Plugin.Instance.verboseLoggingConfig.Value) { Plugin.Log.LogInfo((object)$"EMSC_DEBUG broadcast netId={netId} enabled={selection.Enabled} color={_snapshot.LastBroadcastColorHex}"); } } internal static void RecordReceive(uint netId, SkinToneSelection selection) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) _snapshot.LastReceivedNetId = netId; _snapshot.LastReceivedColorHex = SkinToneSelection.ToHtml(selection.BaseColor); _snapshot.LastEvent = $"receive:{netId}"; if ((Object)(object)Plugin.Instance != (Object)null && Plugin.Instance.verboseLoggingConfig.Value) { Plugin.Log.LogInfo((object)$"EMSC_DEBUG receive netId={netId} enabled={selection.Enabled} color={_snapshot.LastReceivedColorHex}"); } } internal static void RecordApplyPreview(SkinToneSelection selection) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) _snapshot.LastAppliedNetId = 0u; _snapshot.LastAppliedWasPreview = true; _snapshot.LastAppliedColorHex = SkinToneSelection.ToHtml(selection.BaseColor); _snapshot.LastEvent = "apply-preview"; if ((Object)(object)Plugin.Instance != (Object)null && Plugin.Instance.verboseLoggingConfig.Value) { Plugin.Log.LogInfo((object)$"EMSC_DEBUG apply preview enabled={selection.Enabled} color={_snapshot.LastAppliedColorHex}"); } } internal static void RecordApplyPlayer(uint netId, SkinToneSelection selection) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) _snapshot.LastAppliedNetId = netId; _snapshot.LastAppliedWasPreview = false; _snapshot.LastAppliedColorHex = SkinToneSelection.ToHtml(selection.BaseColor); _snapshot.LastEvent = $"apply-player:{netId}"; if ((Object)(object)Plugin.Instance != (Object)null && Plugin.Instance.verboseLoggingConfig.Value) { Plugin.Log.LogInfo((object)$"EMSC_DEBUG apply player netId={netId} enabled={selection.Enabled} color={_snapshot.LastAppliedColorHex}"); } } internal static void RecordRevert(uint netId, bool isPreview) { _snapshot.LastAppliedNetId = netId; _snapshot.LastAppliedWasPreview = isPreview; _snapshot.LastEvent = (isPreview ? "revert-preview" : $"revert-player:{netId}"); if ((Object)(object)Plugin.Instance != (Object)null && Plugin.Instance.verboseLoggingConfig.Value) { Plugin.Log.LogInfo((object)("EMSC_DEBUG revert " + (isPreview ? "preview" : $"player netId={netId}"))); } } } internal sealed class SkinToneFollower : MonoBehaviour { private PlayerCosmetics _cosmetics; private bool _hasLastApplied; private SkinToneSelection _lastApplied; internal void Initialize(PlayerCosmetics cosmetics) { _cosmetics = cosmetics; } private void Update() { if ((Object)(object)_cosmetics == (Object)null || (Object)(object)((Component)_cosmetics).GetComponent() == (Object)null || ((NetworkBehaviour)_cosmetics).netId == 0) { return; } SkinToneSelection selection; if (((NetworkBehaviour)_cosmetics).isLocalPlayer) { SkinToneSelection localSelection = SkinToneState.LocalSelection; if (!_hasLastApplied || !_lastApplied.Equals(localSelection)) { _hasLastApplied = true; _lastApplied = localSelection; SkinToneState.TryApplyFor(_cosmetics); } } else if (SkinToneState.TryGetRemoteSelection(((NetworkBehaviour)_cosmetics).netId, out selection)) { if (!_hasLastApplied || !_lastApplied.Equals(selection)) { _hasLastApplied = true; _lastApplied = selection; SkinToneState.TryApplyFor(_cosmetics); } } else if (_hasLastApplied) { _hasLastApplied = false; SkinToneState.RevertToVanilla(((Component)_cosmetics).GetComponent()); } } } internal static class SkinToneMaterialApplier { internal static void Apply(PlayerCosmeticsSwitcher switcher, SkinToneSelection selection) { //IL_0056: 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) //IL_008f: 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) //IL_0130: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)switcher == (Object)null || !selection.Enabled) { return; } Traverse obj = Traverse.Create((object)switcher); MaterialPropertyBlock val = (MaterialPropertyBlock)(((object)obj.Field("skinColorProps").Value) ?? ((object)new MaterialPropertyBlock())); obj.Field("skinColorProps").SetValue((object)val); ApplyColor(obj.Field("headRenderer").Value, val, selection.BaseColor); ApplyColor(obj.Field("bodyRenderer").Value, val, selection.BaseColor); ApplyColor(obj.Field("mouthRenderer").Value, val, selection.MouthColor); object value = obj.Field("currentHeadModel").GetValue(); if (value == null) { return; } object value2 = Traverse.Create(value).Field("cosmetic").GetValue(); if (value2 == null) { return; } bool value3 = Traverse.Create(value2).Field("requireSkinColorTint").GetValue(); int value4 = Traverse.Create(value2).Field("skinColorTintMaterialIndex").GetValue(); if (!value3) { return; } Component val2 = (Component)((value2 is Component) ? value2 : null); if ((Object)(object)val2 == (Object)null) { return; } Renderer[] componentsInChildren = val2.GetComponentsInChildren(true); foreach (Renderer val3 in componentsInChildren) { val3.GetPropertyBlock(val); val.SetColor("_Color", selection.BaseColor); if (value4 < 0) { val3.SetPropertyBlock(val); } else { val3.SetPropertyBlock(val, value4); } } } private static void ApplyColor(Renderer renderer, MaterialPropertyBlock propertyBlock, Color color) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)renderer == (Object)null)) { renderer.GetPropertyBlock(propertyBlock); propertyBlock.SetColor("_Color", color); renderer.SetPropertyBlock(propertyBlock); } } } public struct SkinToneUpdateRequestMsg : NetworkMessage { public bool enabled; public byte r; public byte g; public byte b; } public struct SkinToneStateMsg : NetworkMessage { public uint netId; public bool enabled; public byte r; public byte g; public byte b; } [StructLayout(LayoutKind.Sequential, Size = 1)] public struct SkinToneSnapshotRequestMsg : NetworkMessage { } internal static class SkinToneNetwork { private static bool _clientHandlersRegistered; private static bool _serverHandlersRegistered; private static bool _serverDisconnectHooked; private static readonly Dictionary ServerSelections = new Dictionary(); private static readonly HashSet ModdedConnections = new HashSet(); internal static void OnClientConnected() { RegisterClientHandlers(); RegisterServerHandlers(); if (NetworkClient.active) { NetworkClient.Send(default(SkinToneSnapshotRequestMsg), 0); } } internal static void TryBroadcastLocalSelection(SkinToneSelection selection) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: 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_0073: 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) if (NetworkClient.active) { RegisterClientHandlers(); RegisterServerHandlers(); Color32 val = Color32.op_Implicit(selection.BaseColor); SkinToneDebugState.RecordBroadcast((NetworkClient.connection != null && (Object)(object)((NetworkConnection)NetworkClient.connection).identity != (Object)null) ? ((NetworkConnection)NetworkClient.connection).identity.netId : 0u, selection); SkinToneUpdateRequestMsg skinToneUpdateRequestMsg = default(SkinToneUpdateRequestMsg); skinToneUpdateRequestMsg.enabled = selection.Enabled; skinToneUpdateRequestMsg.r = val.r; skinToneUpdateRequestMsg.g = val.g; skinToneUpdateRequestMsg.b = val.b; NetworkClient.Send(skinToneUpdateRequestMsg, 0); } } private static void RegisterClientHandlers() { if (!_clientHandlersRegistered) { NetworkClient.ReplaceHandler((Action)OnStateMessage, true); _clientHandlersRegistered = true; } } private static void RegisterServerHandlers() { if (NetworkServer.active && !_serverHandlersRegistered) { NetworkServer.ReplaceHandler((Action)OnUpdateRequest, true); NetworkServer.ReplaceHandler((Action)OnSnapshotRequest, true); if (!_serverDisconnectHooked) { NetworkServer.OnDisconnectedEvent = (Action)Delegate.Combine(NetworkServer.OnDisconnectedEvent, new Action(OnServerConnectionDisconnected)); _serverDisconnectHooked = true; } _serverHandlersRegistered = true; } } private static void OnServerConnectionDisconnected(NetworkConnectionToClient conn) { if (conn != null) { ModdedConnections.Remove(conn.connectionId); } } private static void SendToModdedConnections(SkinToneStateMsg state) { foreach (NetworkConnectionToClient value in NetworkServer.connections.Values) { if (value != null && ModdedConnections.Contains(value.connectionId)) { ((NetworkConnection)value).Send(state, 0); } } } private static void OnStateMessage(SkinToneStateMsg msg) { //IL_002e: 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) //IL_0038: Unknown result type (might be due to invalid IL or missing references) SkinToneSelection skinToneSelection = default(SkinToneSelection); skinToneSelection.Enabled = msg.enabled; skinToneSelection.BaseColor = Color32.op_Implicit(new Color32(msg.r, msg.g, msg.b, byte.MaxValue)); SkinToneSelection selection = skinToneSelection; SkinToneDebugState.RecordReceive(msg.netId, selection); if (selection.Enabled) { SkinToneState.SetRemoteSelection(msg.netId, selection); } else { SkinToneState.ClearRemoteSelection(msg.netId); } } private static void OnUpdateRequest(NetworkConnectionToClient conn, SkinToneUpdateRequestMsg msg) { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) if (conn == null || (Object)(object)((NetworkConnection)conn).identity == (Object)null) { return; } ModdedConnections.Add(conn.connectionId); PlayerCosmetics val = ((Component)((NetworkConnection)conn).identity).GetComponent(); if ((Object)(object)val == (Object)null) { PlayerInfo component = ((Component)((NetworkConnection)conn).identity).GetComponent(); val = (((Object)(object)component != (Object)null) ? component.Cosmetics : null); } if (!((Object)(object)val == (Object)null)) { SkinToneSelection skinToneSelection = default(SkinToneSelection); skinToneSelection.Enabled = msg.enabled; skinToneSelection.BaseColor = Color32.op_Implicit(new Color32(msg.r, msg.g, msg.b, byte.MaxValue)); SkinToneSelection skinToneSelection2 = skinToneSelection; if (skinToneSelection2.Enabled) { ServerSelections[((NetworkBehaviour)val).netId] = skinToneSelection2; } else { ServerSelections.Remove(((NetworkBehaviour)val).netId); } SendToModdedConnections(BuildState(((NetworkBehaviour)val).netId, skinToneSelection2)); } } private static void OnSnapshotRequest(NetworkConnectionToClient conn, SkinToneSnapshotRequestMsg _) { if (conn == null) { return; } ModdedConnections.Add(conn.connectionId); foreach (KeyValuePair serverSelection in ServerSelections) { ((NetworkConnection)conn).Send(BuildState(serverSelection.Key, serverSelection.Value), 0); } } private static SkinToneStateMsg BuildState(uint netId, SkinToneSelection selection) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: 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) //IL_0038: 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) Color32 val = Color32.op_Implicit(selection.BaseColor); SkinToneStateMsg result = default(SkinToneStateMsg); result.netId = netId; result.enabled = selection.Enabled; result.r = val.r; result.g = val.g; result.b = val.b; return result; } } internal static class SkinToneNetworkSerialization { internal static void Register() { Writer.write = WriteSkinToneUpdateRequest; Reader.read = ReadSkinToneUpdateRequest; Writer.write = WriteSkinToneState; Reader.read = ReadSkinToneState; Writer.write = WriteSkinToneSnapshotRequest; Reader.read = ReadSkinToneSnapshotRequest; } private static void WriteSkinToneUpdateRequest(NetworkWriter writer, SkinToneUpdateRequestMsg msg) { NetworkWriterExtensions.WriteBool(writer, msg.enabled); writer.WriteByte(msg.r); writer.WriteByte(msg.g); writer.WriteByte(msg.b); } private static SkinToneUpdateRequestMsg ReadSkinToneUpdateRequest(NetworkReader reader) { SkinToneUpdateRequestMsg result = default(SkinToneUpdateRequestMsg); result.enabled = NetworkReaderExtensions.ReadBool(reader); result.r = reader.ReadByte(); result.g = reader.ReadByte(); result.b = reader.ReadByte(); return result; } private static void WriteSkinToneState(NetworkWriter writer, SkinToneStateMsg msg) { NetworkWriterExtensions.WriteUInt(writer, msg.netId); NetworkWriterExtensions.WriteBool(writer, msg.enabled); writer.WriteByte(msg.r); writer.WriteByte(msg.g); writer.WriteByte(msg.b); } private static SkinToneStateMsg ReadSkinToneState(NetworkReader reader) { SkinToneStateMsg result = default(SkinToneStateMsg); result.netId = NetworkReaderExtensions.ReadUInt(reader); result.enabled = NetworkReaderExtensions.ReadBool(reader); result.r = reader.ReadByte(); result.g = reader.ReadByte(); result.b = reader.ReadByte(); return result; } private static void WriteSkinToneSnapshotRequest(NetworkWriter writer, SkinToneSnapshotRequestMsg msg) { } private static SkinToneSnapshotRequestMsg ReadSkinToneSnapshotRequest(NetworkReader reader) { return default(SkinToneSnapshotRequestMsg); } } internal sealed class SkinTonePickerPanel : MonoBehaviour { private sealed class ColorDragSurface : MonoBehaviour, IPointerDownHandler, IEventSystemHandler, IDragHandler, IPointerUpHandler, IEndDragHandler { internal Action Handler; internal Action EndHandler; public void OnPointerDown(PointerEventData eventData) { Forward(eventData); } public void OnDrag(PointerEventData eventData) { Forward(eventData); } public void OnPointerUp(PointerEventData eventData) { EndHandler?.Invoke(); } public void OnEndDrag(PointerEventData eventData) { EndHandler?.Invoke(); } private void Forward(PointerEventData eventData) { //IL_0017: 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) Transform transform = ((Component)this).transform; RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null); Vector2 arg = default(Vector2); if ((Object)(object)val != (Object)null && RectTransformUtility.ScreenPointToLocalPointInRectangle(val, eventData.position, eventData.pressEventCamera, ref arg)) { Handler?.Invoke(arg, val); } } } private sealed class ToggleButton : MonoBehaviour { private Button _button; private TMP_Text _label; private Image _background; internal event Action Clicked; internal void Initialize(Button button, TMP_Text label, Image background) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown _button = button; _label = label; _background = background; ((UnityEvent)_button.onClick).AddListener((UnityAction)delegate { this.Clicked?.Invoke(); }); } internal void SetLabel(string label) { _label.text = label; } internal void SetState(bool enabled) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) ((Graphic)_background).color = (enabled ? new Color(0.24f, 0.41f, 0.29f, 1f) : new Color(0.18f, 0.23f, 0.3f, 1f)); } } [CompilerGenerated] private static class <>O { public static UnityAction <0>__Hide; } private static readonly Color32[] PresetColors = (Color32[])(object)new Color32[6] { new Color32(byte.MaxValue, (byte)224, (byte)189, byte.MaxValue), new Color32((byte)241, (byte)194, (byte)125, byte.MaxValue), new Color32((byte)224, (byte)172, (byte)105, byte.MaxValue), new Color32((byte)198, (byte)134, (byte)66, byte.MaxValue), new Color32((byte)141, (byte)85, (byte)36, byte.MaxValue), new Color32((byte)92, (byte)51, (byte)23, byte.MaxValue) }; private const float ExpandedWidth = 500f; private const float ExpandedHeight = 470f; private const float MinimizedWidth = 150f; private const float MinimizedHeight = 44f; private PlayerCustomizationMenu _menu; private RectTransform _rootRect; private Image _backgroundImage; private GameObject _expandedContent; private GameObject _minimizedLauncher; private Image _launcherSwatch; private ToggleButton _toggleButton; private ToggleButton _minimizeButton; private Image _previewSwatch; private TMP_Text _hexLabel; private GameObject _advancedArea; private RectTransform _wheelHandle; private RectTransform _svHandle; private Texture2D _wheelTexture; private Texture2D _svTexture; private float _hue; private float _saturation; private float _value; private float _lastRegenHue = float.NaN; private Color32[] _svPixels; private bool _dragFinalizing; internal void Initialize(PlayerCustomizationMenu menu) { _menu = menu; BuildUi(); LoadFromState(); RefreshUi(); SkinToneState.ApplyToPreview(_menu); } private void OnDestroy() { if ((Object)(object)_wheelTexture != (Object)null) { Object.Destroy((Object)(object)_wheelTexture); } if ((Object)(object)_svTexture != (Object)null) { Object.Destroy((Object)(object)_svTexture); } } private void BuildUi() { //IL_0051: 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_0085: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Expected O, but got Unknown //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) ((Component)this).gameObject.AddComponent().ignoreLayout = true; _rootRect = ((Component)this).gameObject.GetComponent(); if ((Object)(object)_rootRect == (Object)null) { _rootRect = ((Component)this).gameObject.AddComponent(); } _rootRect.anchorMin = new Vector2(0f, 0f); _rootRect.anchorMax = new Vector2(0f, 0f); _rootRect.pivot = new Vector2(0f, 0f); _rootRect.sizeDelta = new Vector2(500f, 470f); _rootRect.anchoredPosition = new Vector2(12f, 12f); _backgroundImage = ((Component)this).gameObject.AddComponent(); ((Graphic)_backgroundImage).color = new Color(0.08f, 0.1f, 0.14f, 0.94f); ((Graphic)_backgroundImage).raycastTarget = true; _expandedContent = new GameObject("ExpandedContent", new Type[1] { typeof(RectTransform) }); _expandedContent.transform.SetParent(((Component)this).transform, false); RectTransform component = _expandedContent.GetComponent(); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; component.offsetMin = Vector2.zero; component.offsetMax = Vector2.zero; BuildExpandedChrome(component); BuildMinimizedLauncher(); } private void BuildExpandedChrome(RectTransform parent) { //IL_00b0: 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_0207: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Expected O, but got Unknown //IL_02e2: Unknown result type (might be due to invalid IL or missing references) //IL_0394: Unknown result type (might be due to invalid IL or missing references) //IL_03b8: Unknown result type (might be due to invalid IL or missing references) //IL_03c2: Expected O, but got Unknown float num = 468f; float num2 = 12f; _minimizeButton = CreateToggleButton(parent, 32f, 32f); SetAnchoredTopRow(((Component)_minimizeButton).GetComponent(), 452f, 12f, 32f, 32f); _minimizeButton.SetLabel("–"); _minimizeButton.Clicked += OnMinimizeClicked; TMP_Text obj = CreateLabelUnder(parent, Compatibility.IsMoreSkinColorsPresent ? "Custom Tone Override" : "Custom Tone"); SetAnchoredTopRow(obj.rectTransform, 16f, num2, num - 40f, 34f); obj.fontSize = 28f; ((Graphic)obj).color = Color.white; num2 += 42f; RectTransform parent2 = CreateHRowUnder(parent, "Toolbar", 16f, num2, num, 42f); _toggleButton = CreateToggleButton(parent2, 160f, 38f); _toggleButton.Clicked += OnToggleClicked; _previewSwatch = CreateSwatch(parent2, 38f); _hexLabel = CreateToolbarLabel(parent2, 160f, 38f); num2 += 50f; RectTransform parent3 = CreateHRowUnder(parent, "Actions", 16f, num2, num, 38f); CreateActionButton(parent3, "Hex", 88f, 34f, OpenHexEditor); CreateActionButton(parent3, "Vanilla", 104f, 34f, ResetToVanilla); CreateActionButton(parent3, "Default", 104f, 34f, ResetToDefaultPreset); num2 += 46f; RectTransform parent4 = CreateHRowUnder(parent, "Presets", 16f, num2, num, 34f); for (int i = 0; i < PresetColors.Length; i++) { int presetIndex = i; CreatePresetButton(parent4, Color32.op_Implicit(PresetColors[i]), 46f, 30f, delegate { ApplyPreset(presetIndex); }); } num2 += 42f; _advancedArea = new GameObject("AdvancedArea", new Type[1] { typeof(RectTransform) }); _advancedArea.transform.SetParent((Transform)(object)parent, false); RectTransform component = _advancedArea.GetComponent(); SetAnchoredTopRow(component, 16f, num2, num, 190f); float num3 = (num - 380f) * 0.5f; Image image; RectTransform val = CreateBoxAt(component, "WheelBox", Mathf.Max(0f, num3), 0f, 190f, out image); ((Graphic)image).color = new Color(0f, 0f, 0f, 0.18f); RawImage obj2 = CreateRawImage(val, "WheelImage"); _wheelTexture = GenerateHueWheelTexture(256, 0.3f, 0.48f); obj2.texture = (Texture)(object)_wheelTexture; _wheelHandle = CreateHandle(val, 16f); AddDragSurface(((Component)val).gameObject, OnWheelPointer); Image image2; RectTransform val2 = CreateBoxAt(component, "SvBox", Mathf.Max(0f, num3) + 190f + 10f, 0f, 190f, out image2); ((Graphic)image2).color = new Color(0f, 0f, 0f, 0.18f); RawImage obj3 = CreateRawImage(val2, "SvImage"); _svTexture = new Texture2D(256, 256, (TextureFormat)4, false); ((Texture)_svTexture).wrapMode = (TextureWrapMode)1; ((Texture)_svTexture).filterMode = (FilterMode)1; obj3.texture = (Texture)(object)_svTexture; _svHandle = CreateHandle(val2, 14f); AddDragSurface(((Component)val2).gameObject, OnSvPointer); } private static void SetAnchoredTopRow(RectTransform rect, float x, float y, float width, float height) { //IL_000b: 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_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) rect.anchorMin = new Vector2(0f, 1f); rect.anchorMax = new Vector2(0f, 1f); rect.pivot = new Vector2(0f, 1f); rect.sizeDelta = new Vector2(width, height); rect.anchoredPosition = new Vector2(x, 0f - y); } private RectTransform CreateHRowUnder(RectTransform parent, string name, float x, float y, float width, float height) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); val.transform.SetParent((Transform)(object)parent, false); RectTransform component = val.GetComponent(); SetAnchoredTopRow(component, x, y, width, height); HorizontalLayoutGroup obj = val.AddComponent(); ((HorizontalOrVerticalLayoutGroup)obj).spacing = 10f; ((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = false; ((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = false; ((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false; return component; } private void BuildMinimizedLauncher() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: 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_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Expected O, but got Unknown //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Expected O, but got Unknown //IL_01ac: 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_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) _minimizedLauncher = new GameObject("MinimizedLauncher", new Type[3] { typeof(RectTransform), typeof(Image), typeof(Button) }); _minimizedLauncher.transform.SetParent(((Component)this).transform, false); RectTransform component = _minimizedLauncher.GetComponent(); component.anchorMin = new Vector2(0f, 0f); component.anchorMax = new Vector2(0f, 0f); component.pivot = new Vector2(0f, 0f); component.sizeDelta = new Vector2(150f, 44f); component.anchoredPosition = Vector2.zero; Image component2 = _minimizedLauncher.GetComponent(); ((Graphic)component2).color = new Color(0.08f, 0.1f, 0.14f, 0.94f); ((Graphic)component2).raycastTarget = true; ((UnityEvent)_minimizedLauncher.GetComponent