Decompiled source of Profile Cards v0.1.7

plugins/com.atomic.profileviewer.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Peak.Network;
using Peak.UI;
using Photon.Pun;
using Photon.Realtime;
using Portningsbolaget;
using Portningsbolaget.Platforms;
using Steamworks;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("com.atomic.profileviewer")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.7.0")]
[assembly: AssemblyInformationalVersion("0.1.7+726dccca8833dcb3d678f996d661f578d6d4060c")]
[assembly: AssemblyProduct("com.atomic.profileviewer")]
[assembly: AssemblyTitle("ProfileViewer")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.7.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace ProfileViewer
{
	public class ButtonDefinition
	{
		public string Name { get; }

		public string Icon { get; }

		public Func<ProfileController, bool> IsVisible { get; }

		public Action<ProfileController> OnClick { get; }

		public bool HideAfterClick { get; }

		public ButtonDefinition(string name, string icon, Func<ProfileController, bool> isVisible, Action<ProfileController> onClick, bool hideAfterClick = false)
		{
			Name = name;
			Icon = icon;
			IsVisible = isVisible;
			OnClick = onClick;
			HideAfterClick = hideAfterClick;
		}
	}
	[BepInPlugin("com.atomic.profileviewer", "ProfileViewer", "0.1.7")]
	public class Plugin : BaseUnityPlugin
	{
		public static bool TransferButtonEnabled = false;

		public static Harmony harmony = null;

		public static readonly ButtonDefinition[] ButtonDefinitions = new ButtonDefinition[4]
		{
			new ButtonDefinition("TransferButton", "ProfileViewer.Assets.Transfer-MasterClient.png", delegate(ProfileController controller)
			{
				//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)
				if (TransferButtonEnabled && controller.IsHost && !controller.IsLocal)
				{
					CSteamID steamId = controller.SteamId;
					return ((CSteamID)(ref steamId)).IsValid();
				}
				return false;
			}, delegate(ProfileController controller)
			{
				controller.TransferHost();
			}),
			new ButtonDefinition("AddFriendButton", "ProfileViewer.Assets.Add-Friend.png", (ProfileController controller) => !controller.IsLocal && controller.CanAddFriend && !controller.IsFriend, delegate(ProfileController controller)
			{
				controller.AddFriend();
			}, hideAfterClick: true),
			new ButtonDefinition("ProfileButton", "ProfileViewer.Assets.Open-Profile.png", (ProfileController controller) => controller.CanOpenProfile, delegate(ProfileController controller)
			{
				controller.OpenProfile();
			}),
			new ButtonDefinition("MuteButton", "ProfileViewer.Assets.Mute.png", (ProfileController controller) => controller.CanMute, delegate(ProfileController controller)
			{
				controller.Mute();
			})
		};

		private static readonly Dictionary<string, Sprite?> SpriteCache = new Dictionary<string, Sprite>();

		private const string KickIconName = "KickIcon";

		private const string MuteButtonPath = "PlayerUI/Buttons/Mute";

		private const float ButtonGap = 5f;

		public const string Id = "com.atomic.profileviewer";

		public static Plugin Instance { get; private set; } = null;

		internal static ManualLogSource Log { get; private set; } = null;

		public static string Name => "ProfileViewer";

		public static string Version => "0.1.7";

		private void Awake()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			harmony = new Harmony("com.atomic.profileviewer");
			harmony.PatchAll();
			Log.LogInfo((object)("Plugin " + Name + " is loaded!"));
		}

		public static CSteamID GetSteamId(Player? player)
		{
			//IL_0019: 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)
			if (player != null && ulong.TryParse(player.UserId, out var result))
			{
				return new CSteamID(result);
			}
			return CSteamID.Nil;
		}

		public static Sprite? LoadSprite(string resourceName)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			if (SpriteCache.TryGetValue(resourceName, out Sprite value))
			{
				return value;
			}
			Sprite val = null;
			using (Stream stream = typeof(Plugin).Assembly.GetManifestResourceStream(resourceName))
			{
				if (stream != null)
				{
					using MemoryStream memoryStream = new MemoryStream();
					stream.CopyTo(memoryStream);
					Texture2D val2 = new Texture2D(2, 2);
					if (ImageConversion.LoadImage(val2, memoryStream.ToArray()))
					{
						val = Sprite.Create(val2, new Rect(0f, 0f, (float)((Texture)val2).width, (float)((Texture)val2).height), new Vector2(0.5f, 0.5f));
					}
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				Log.LogWarning((object)("Could not load icon " + resourceName));
			}
			SpriteCache[resourceName] = val;
			return val;
		}

		public static void CreateUI(AudioLevelSlider slider)
		{
			VerticalLayoutGroup componentInParent = ((Component)slider).GetComponentInParent<VerticalLayoutGroup>();
			if ((Object)(object)componentInParent != (Object)null)
			{
				((HorizontalOrVerticalLayoutGroup)componentInParent).spacing = 30f;
			}
			Transform val = ((Component)slider).transform.Find("IsNotLocal");
			if (!((Object)(object)val == (Object)null))
			{
				if (IsModInstalled("lammas123.PEAKER"))
				{
					DisableViewportMask(slider);
				}
				ProfileController profileController = ((Component)slider).GetComponent<ProfileController>() ?? ((Component)slider).gameObject.AddComponent<ProfileController>();
				if (profileController.IsBuilt || BuildUI(slider, val, profileController))
				{
					profileController.Refresh();
				}
			}
		}

		private static bool BuildUI(AudioLevelSlider slider, Transform local, ProfileController controller)
		{
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			Transform val = local.Find("KickButton");
			Transform val2 = ((Component)slider).transform.Find("NameLayout");
			Transform val3 = ((Component)slider).transform.Find("PlayerUI/Avatar");
			RectTransform val4 = (RectTransform)(object)((val is RectTransform) ? val : null);
			if (val4 == null || (Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null || (Object)(object)val.Find("KickIcon") == (Object)null)
			{
				Log.LogWarning((object)"Profile UI skipped, the slider is missing children this mod expects.");
				return false;
			}
			Transform val5 = ((Component)slider).transform.Find("PlayerUI/Buttons/Mute");
			Button val6 = (((Object)(object)val5 != (Object)null) ? ((Component)val5).GetComponentInChildren<Button>(true) : null);
			if ((Object)(object)val6 == (Object)null)
			{
				Log.LogWarning((object)"'PlayerUI/Buttons/Mute' not found, the mute button will not be shown.");
			}
			((Component)val).gameObject.SetActive(true);
			val.localPosition += new Vector3(-60f, 15f, 0f);
			val2.localPosition += new Vector3(0f, 40f, 0f);
			Image icon = CreatePlatformIcon(val, local, ((Component)slider).transform);
			RectTransform val7 = CreateButtonRow(((Component)slider).transform, val4);
			ButtonDefinition[] buttonDefinitions = ButtonDefinitions;
			foreach (ButtonDefinition definition in buttonDefinitions)
			{
				controller.AddButton(definition, val, (Transform)(object)val7);
			}
			val.SetParent((Transform)(object)val7, false);
			val.SetAsLastSibling();
			Transform parent = CreateFrame(((Component)slider).transform, val2);
			val3.SetParent(parent);
			controller.Setup(slider, val, val7, val3, icon, val6);
			return true;
		}

		private static RectTransform CreateButtonRow(Transform parent, RectTransform kick)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: 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_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			Rect rect = kick.rect;
			Vector2 size = ((Rect)(ref rect)).size;
			if (size.x <= 0f || size.y <= 0f)
			{
				((Vector2)(ref size))..ctor(50f, 50f);
			}
			GameObject val = new GameObject("ButtonRow", new Type[2]
			{
				typeof(RectTransform),
				typeof(GridLayoutGroup)
			});
			RectTransform val2 = (RectTransform)val.transform;
			((Transform)val2).SetParent(parent, false);
			int num = ButtonDefinitions.Length + 1;
			Vector2 val3 = default(Vector2);
			((Vector2)(ref val3))..ctor(0.5f, 0.5f);
			val2.anchorMax = val3;
			val2.anchorMin = val3;
			val2.pivot = new Vector2(1f, 0.5f);
			val2.sizeDelta = new Vector2((size.x + 5f) * (float)num, size.y);
			((Transform)val2).localPosition = new Vector3(110f, 5f, 0f);
			GridLayoutGroup component = val.GetComponent<GridLayoutGroup>();
			component.cellSize = size;
			component.spacing = new Vector2(5f, 0f);
			component.startCorner = (Corner)0;
			component.startAxis = (Axis)0;
			((LayoutGroup)component).childAlignment = (TextAnchor)5;
			component.constraint = (Constraint)2;
			component.constraintCount = 1;
			return val2;
		}

		public static GameObject CloneKickButton(Transform kick, Transform parent, string name)
		{
			GameObject val = Object.Instantiate<GameObject>(((Component)kick).gameObject, parent);
			((Object)val).name = name;
			val.SetActive(true);
			KickButton val2 = default(KickButton);
			if (val.TryGetComponent<KickButton>(ref val2))
			{
				Object.Destroy((Object)(object)val2);
			}
			Animator val3 = default(Animator);
			if (val.TryGetComponent<Animator>(ref val3))
			{
				Object.Destroy((Object)(object)val3);
			}
			return val;
		}

		private static Image? CreatePlatformIcon(Transform kick, Transform local, Transform slider)
		{
			//IL_002f: 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)
			GameObject val = CloneKickButton(kick, local, "PlatformIcon");
			val.transform.SetParent(slider, true);
			val.transform.localPosition = new Vector3(155f, 15f, 0f);
			val.transform.localScale = new Vector3(1.25f, 1.25f, 1.25f);
			Transform val2 = val.transform.Find("KickIcon");
			Image result = default(Image);
			if ((Object)(object)val2 == (Object)null || !((Component)val2).TryGetComponent<Image>(ref result))
			{
				Object.Destroy((Object)(object)val);
				return null;
			}
			((Component)val2).gameObject.SetActive(true);
			return result;
		}

		private static Transform CreateFrame(Transform parent, Transform nameLayout)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: 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_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			TextMeshProUGUI componentInChildren = ((Component)nameLayout).GetComponentInChildren<TextMeshProUGUI>();
			GameObject val = new GameObject("ProfileFrame", new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(parent, false);
			val.transform.localScale = new Vector3(0.8f, 0.8f, 0.8f);
			val.AddComponent<Image>();
			val.AddComponent<Mask>();
			Outline val2 = val.AddComponent<Outline>();
			((Shadow)val2).effectColor = (((Object)(object)componentInChildren != (Object)null) ? ((Graphic)componentInChildren).color : Color.white);
			((Shadow)val2).effectDistance = new Vector2(4f, 3f);
			RectTransform val3 = (RectTransform)val.transform;
			val3.anchorMin = new Vector2(0f, 0.5f);
			val3.anchorMax = new Vector2(0f, 0.5f);
			val3.sizeDelta = new Vector2(100f, 100f);
			((Transform)val3).localPosition = new Vector3(-273f, 13f, 0f);
			return (Transform)(object)val3;
		}

		private static void DisableViewportMask(AudioLevelSlider slider)
		{
			Transform parent = ((Component)slider).transform.parent;
			Transform val = ((parent != null) ? parent.parent : null);
			if (!((Object)(object)val == (Object)null))
			{
				Image val2 = default(Image);
				if (((Component)val).TryGetComponent<Image>(ref val2))
				{
					((Behaviour)val2).enabled = false;
				}
				Mask val3 = default(Mask);
				if (((Component)val).TryGetComponent<Mask>(ref val3))
				{
					((Behaviour)val3).enabled = false;
				}
			}
		}

		private static bool IsModInstalled(string guid)
		{
			return Chainloader.PluginInfos.ContainsKey(guid);
		}

		internal static bool TryRequestHostTransfer(int targetActorNumber, CSteamID steamId)
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			Room currentRoom = PhotonNetwork.CurrentRoom;
			IMatchmakingAPI matchmaking = NetCode.Matchmaking;
			if (currentRoom == null || PhotonNetwork.OfflineMode || !PhotonNetwork.IsMasterClient || !matchmaking.InLobby)
			{
				return false;
			}
			if (!currentRoom.Players.TryGetValue(targetActorNumber, out var value))
			{
				return false;
			}
			if (value.IsLocal || value.IsInactive || !matchmaking.PlayerIsInLobby(value.UserId))
			{
				return false;
			}
			if (!ulong.TryParse(matchmaking.LobbyId, out var result))
			{
				return false;
			}
			CSteamID val = default(CSteamID);
			((CSteamID)(ref val))..ctor(result);
			if (SteamMatchmaking.GetLobbyOwner(val) != SteamUser.GetSteamID())
			{
				return false;
			}
			SteamMatchmaking.SetLobbyOwner(val, steamId);
			bool flag = PhotonNetwork.SetMasterClient(value);
			Log.LogInfo((object)$"Photon host transfer queued={flag}; target={value.NickName} ({value.ActorNumber})");
			return flag;
		}

		internal static void SyncLobbyOwner()
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			Player masterClient = PhotonNetwork.MasterClient;
			IMatchmakingAPI matchmaking = NetCode.Matchmaking;
			if (masterClient == null || !matchmaking.InLobby || !matchmaking.PlayerIsInLobby(masterClient.UserId) || !ulong.TryParse(matchmaking.LobbyId, out var result) || !ulong.TryParse(masterClient.UserId, out var result2))
			{
				return;
			}
			CSteamID val = default(CSteamID);
			((CSteamID)(ref val))..ctor(result);
			CSteamID val2 = default(CSteamID);
			((CSteamID)(ref val2))..ctor(result2);
			CSteamID lobbyOwner = SteamMatchmaking.GetLobbyOwner(val);
			if (!(lobbyOwner == val2) && !(lobbyOwner != SteamUser.GetSteamID()))
			{
				if (!SteamMatchmaking.SetLobbyOwner(val, val2))
				{
					Log.LogError((object)"Photon host changed, but Steam lobby ownership transfer failed.");
				}
				else
				{
					Log.LogInfo((object)$"Steam lobby ownership transferred to {masterClient.NickName} ({result2}).");
				}
			}
		}
	}
	public class ProfileController : MonoBehaviour, IPunOwnershipCallbacks
	{
		private class Entry
		{
			public ButtonDefinition Definition { get; }

			public GameObject GameObject { get; }

			public Entry(ButtonDefinition definition, GameObject gameObject)
			{
				Definition = definition;
				GameObject = gameObject;
			}
		}

		private const string XboxProfileUrl = "https://www.xbox.com/play/user/";

		private const string XboxApiUrl = "https://peoplehub-public.xboxlive.com/people/gt(";

		private static readonly Vector3 IconScale = new Vector3(0.7f, 0.7f, 0.7f);

		private static readonly Vector3 IconHoverScale = new Vector3(0.8f, 0.8f, 0.8f);

		private static readonly Vector3 AvatarScale = new Vector3(1.65f, -1.65f, 0f);

		private static readonly Vector3 PlatformIconAvatarScale = new Vector3(1.65f, 1.65f, 0f);

		private readonly List<Entry> entries = new List<Entry>();

		private static readonly Dictionary<string, Sprite> XboxAvatarCache = new Dictionary<string, Sprite>();

		private static readonly Dictionary<string, List<Image>> XboxWaiting = new Dictionary<string, List<Image>>();

		private static readonly HashSet<string> XboxFailedFetches = new HashSet<string>();

		private AudioLevelSlider slider;

		private Transform kick;

		private RectTransform row;

		private Transform avatar;

		private Image? platformIcon;

		private Button? muteSource;

		private Image? muteButtonImage;

		private Image? avatarImage;

		private bool isMutedLocal;

		private bool built;

		public bool IsBuilt => built;

		public string PlayerName { get; private set; } = string.Empty;

		public PlatformFamily Platform { get; private set; } = (PlatformFamily)1;

		public CSteamID SteamId { get; private set; } = CSteamID.Nil;

		public bool IsLocal { get; private set; }

		public bool IsHost { get; private set; }

		public bool IsMuted
		{
			get
			{
				Toggle val = default(Toggle);
				if ((Object)(object)muteSource != (Object)null && ((Component)muteSource).TryGetComponent<Toggle>(ref val))
				{
					return val.isOn;
				}
				return isMutedLocal;
			}
		}

		public bool CanOpenProfile
		{
			get
			{
				//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_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_000a: Invalid comparison between Unknown and I4
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_000f: Invalid comparison between Unknown and I4
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: Invalid comparison between Unknown and I4
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0031: Unknown result type (might be due to invalid IL or missing references)
				PlatformFamily platform = Platform;
				if ((int)platform != 16 && (int)platform != 32)
				{
					if ((int)platform == 64)
					{
						return !string.IsNullOrWhiteSpace(PlayerName);
					}
					CSteamID steamId = SteamId;
					return ((CSteamID)(ref steamId)).IsValid();
				}
				return false;
			}
		}

		public bool CanAddFriend => CanOpenProfile;

		public bool IsFriend
		{
			get
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Invalid comparison between Unknown and I4
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_0028: Invalid comparison between Unknown and I4
				if ((int)Platform == 1)
				{
					CSteamID steamId = SteamId;
					if (((CSteamID)(ref steamId)).IsValid())
					{
						try
						{
							return (int)SteamFriends.GetFriendRelationship(SteamId) == 3;
						}
						catch (Exception ex) when (((ex is InvalidOperationException || ex is DllNotFoundException) ? 1 : 0) != 0)
						{
							return false;
						}
					}
				}
				return false;
			}
		}

		public bool CanMute
		{
			get
			{
				if (!IsLocal)
				{
					return (Object)(object)muteSource != (Object)null;
				}
				return false;
			}
		}

		public void Setup(AudioLevelSlider owner, Transform kickButton, RectTransform buttonRow, Transform avatarObject, Image? icon, Button? mute)
		{
			slider = owner;
			kick = kickButton;
			row = buttonRow;
			avatar = avatarObject;
			platformIcon = icon;
			muteSource = mute;
			avatarImage = ((Component)avatar).GetComponent<Image>() ?? ((Component)avatar).GetComponentInChildren<Image>();
			built = true;
		}

		public void AddButton(ButtonDefinition definition, Transform template, Transform parent)
		{
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Expected O, but got Unknown
			GameObject val = Plugin.CloneKickButton(template, parent, definition.Name);
			Transform val2 = val.transform.Find("KickIcon");
			Button val3 = default(Button);
			if ((Object)(object)val2 == (Object)null || !val.TryGetComponent<Button>(ref val3))
			{
				Object.Destroy((Object)(object)val);
				return;
			}
			Sprite val4 = Plugin.LoadSprite(definition.Icon);
			Image val5 = default(Image);
			if ((Object)(object)val4 != (Object)null && ((Component)val2).TryGetComponent<Image>(ref val5))
			{
				val5.sprite = val4;
				if (definition.Name == "MuteButton")
				{
					muteButtonImage = val5;
				}
			}
			((Component)val2).gameObject.SetActive(true);
			val2.localScale = IconScale;
			Entry entry = new Entry(definition, val);
			((Behaviour)val3).enabled = true;
			((Selectable)val3).interactable = true;
			((UnityEventBase)val3.onClick).RemoveAllListeners();
			((UnityEvent)val3.onClick).AddListener((UnityAction)delegate
			{
				HandleClick(entry);
			});
			AddHoverEffects(val, val2);
			entries.Add(entry);
		}

		public void Refresh()
		{
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Invalid comparison between Unknown and I4
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Invalid comparison between Unknown and I4
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Invalid comparison between Unknown and I4
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			if (!built || (Object)(object)slider == (Object)null || !ReadPlayer())
			{
				return;
			}
			((Component)kick).gameObject.SetActive(!IsLocal && IsHost);
			if ((Object)(object)muteSource != (Object)null)
			{
				((Component)muteSource).gameObject.SetActive(false);
				Toggle val = default(Toggle);
				if (((Component)muteSource).TryGetComponent<Toggle>(ref val))
				{
					isMutedLocal = val.isOn;
				}
			}
			if ((Object)(object)muteButtonImage != (Object)null)
			{
				string resourceName = (IsMuted ? "ProfileViewer.Assets.Unmute.png" : "ProfileViewer.Assets.Mute.png");
				Sprite val2 = Plugin.LoadSprite(resourceName);
				if ((Object)(object)val2 == (Object)null && IsMuted)
				{
					val2 = Plugin.LoadSprite("ProfileViewer.Assets.Mute.png");
				}
				if ((Object)(object)val2 != (Object)null)
				{
					muteButtonImage.sprite = val2;
				}
			}
			foreach (Entry entry in entries)
			{
				entry.GameObject.SetActive(entry.Definition.IsVisible(this));
			}
			LayoutRebuilder.ForceRebuildLayoutImmediate(row);
			ShowPlatformIcon();
			if ((Object)(object)avatarImage != (Object)null)
			{
				if ((int)Platform == 64 && !string.IsNullOrWhiteSpace(PlayerName))
				{
					FetchXboxAvatar(PlayerName);
				}
				else
				{
					PlatformFamily platformFamily = PlatformManager.Platform.PlatformFamily;
					if (Platform != platformFamily)
					{
						PlatformFamily platform = Platform;
						string text = (((int)platform == 16) ? "ProfileViewer.Assets.Nintendo.png" : (((int)platform != 32) ? "ProfileViewer.Assets.Steam.png" : "ProfileViewer.Assets.Playstation.png"));
						string resourceName2 = text;
						Sprite val3 = Plugin.LoadSprite(resourceName2);
						if ((Object)(object)val3 != (Object)null)
						{
							avatarImage.sprite = val3;
						}
						avatar.localScale = PlatformIconAvatarScale;
					}
					else
					{
						avatar.localScale = AvatarScale;
					}
				}
			}
			((Shadow)((Component)avatar.parent).GetComponent<Outline>()).effectColor = ((Graphic)slider.playerName).color;
			avatar.localPosition = Vector3.zero;
		}

		private void FetchXboxAvatar(string gamertag)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			string text = gamertag.Replace(" ", "");
			avatar.localScale = PlatformIconAvatarScale;
			if (XboxAvatarCache.TryGetValue(text, out Sprite value))
			{
				avatarImage.sprite = value;
				return;
			}
			Sprite val = Plugin.LoadSprite("ProfileViewer.Assets.Xbox.png");
			if ((Object)(object)val != (Object)null)
			{
				avatarImage.sprite = val;
			}
			if (!XboxFailedFetches.Contains(text))
			{
				if (!XboxWaiting.TryGetValue(text, out List<Image> value2))
				{
					value2 = (XboxWaiting[text] = new List<Image>());
					((MonoBehaviour)Plugin.Instance).StartCoroutine(DownloadXboxAvatar(text));
				}
				if (!value2.Contains(avatarImage))
				{
					value2.Add(avatarImage);
				}
			}
		}

		private static IEnumerator DownloadXboxAvatar(string tag)
		{
			string error = null;
			string imageUrl = null;
			UnityWebRequest request = UnityWebRequest.Get("https://peoplehub-public.xboxlive.com/people/gt(" + Uri.EscapeDataString(tag) + ")");
			try
			{
				request.timeout = 10;
				request.SetRequestHeader("X-Xbl-Contract-Version", "3");
				request.SetRequestHeader("Accept-Language", "*");
				yield return request.SendWebRequest();
				if ((int)request.result != 1)
				{
					error = $"HTTP {request.responseCode} {request.error}";
				}
				else
				{
					Match match = Regex.Match(request.downloadHandler.text, "\"displayPicRaw\"\\s*:\\s*\"([^\"]+)\"");
					if (match.Success)
					{
						imageUrl = Regex.Unescape(match.Groups[1].Value);
					}
					else
					{
						error = "profile has no displayPicRaw";
					}
				}
			}
			finally
			{
				((IDisposable)request)?.Dispose();
			}
			Sprite sprite = null;
			if (imageUrl != null)
			{
				request = UnityWebRequest.Get(imageUrl);
				try
				{
					request.timeout = 10;
					yield return request.SendWebRequest();
					if ((int)request.result != 1)
					{
						error = $"image HTTP {request.responseCode} {request.error}";
					}
					else
					{
						Texture2D val = new Texture2D(2, 2);
						if (ImageConversion.LoadImage(val, request.downloadHandler.data))
						{
							sprite = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
						}
						else
						{
							error = "image could not be decoded";
						}
					}
				}
				finally
				{
					((IDisposable)request)?.Dispose();
				}
			}
			XboxWaiting.TryGetValue(tag, out List<Image> value);
			XboxWaiting.Remove(tag);
			if ((Object)(object)sprite == (Object)null)
			{
				XboxFailedFetches.Add(tag);
				Plugin.Log.LogWarning((object)("Xbox avatar fetch failed for '" + tag + "': " + error));
				yield break;
			}
			XboxAvatarCache[tag] = sprite;
			if (value == null)
			{
				yield break;
			}
			foreach (Image item in value)
			{
				if ((Object)(object)item != (Object)null)
				{
					item.sprite = sprite;
				}
			}
		}

		public void OpenProfile()
		{
			//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_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Invalid comparison between Unknown and I4
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Invalid comparison between Unknown and I4
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Invalid comparison between Unknown and I4
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			PlatformFamily platform = Platform;
			if ((int)platform != 16 && (int)platform != 32)
			{
				if ((int)platform == 64)
				{
					OpenWebPage("https://www.xbox.com/play/user/" + Uri.EscapeDataString(PlayerName));
				}
				else
				{
					SteamFriends.ActivateGameOverlayToUser("steamid", SteamId);
				}
			}
		}

		public void AddFriend()
		{
			//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_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Invalid comparison between Unknown and I4
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Invalid comparison between Unknown and I4
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Invalid comparison between Unknown and I4
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			PlatformFamily platform = Platform;
			if ((int)platform == 16 || (int)platform == 32 || (int)platform == 64)
			{
				OpenProfile();
			}
			else
			{
				SteamFriends.ActivateGameOverlayToUser("friendadd", SteamId);
			}
		}

		public void TransferHost()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			Plugin.TryRequestHostTransfer(slider.player.ActorNumber, SteamId);
			Transform parent = ((Component)slider).transform.parent;
			AudioLevels val = default(AudioLevels);
			if ((Object)(object)parent != (Object)null && ((Component)parent).TryGetComponent<AudioLevels>(ref val))
			{
				val.UpdateSliders();
			}
		}

		public void Mute()
		{
			if ((Object)(object)muteSource != (Object)null)
			{
				PlayerUiSlider voiceSlider = slider.m_PlayerUI.voiceSlider;
				voiceSlider.ToggleMute();
				isMutedLocal = voiceSlider.m_muteToggled;
				Refresh();
			}
		}

		private bool ReadPlayer()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			Player player = slider.player;
			if (player == null)
			{
				return false;
			}
			PlayerName = player.NickName ?? string.Empty;
			SteamId = Plugin.GetSteamId(player);
			IsLocal = player.IsLocal;
			IsHost = PhotonNetwork.LocalPlayer != null && PhotonNetwork.LocalPlayer.IsMasterClient;
			Platform = (PlatformFamily)1;
			if (player.CustomProperties != null && ((Dictionary<object, object>)(object)player.CustomProperties).TryGetValue((object)"PlatformFamily", out object value))
			{
				if (value is string value2 && Enum.TryParse<PlatformFamily>(value2, ignoreCase: true, out PlatformFamily result))
				{
					Platform = result;
				}
				else if (value is int num)
				{
					Platform = (PlatformFamily)num;
				}
				else if (value is byte b)
				{
					Platform = (PlatformFamily)b;
				}
			}
			return true;
		}

		private void ShowPlatformIcon()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Invalid comparison between Unknown and I4
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Invalid comparison between Unknown and I4
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Invalid comparison between Unknown and I4
			if (!((Object)(object)platformIcon == (Object)null))
			{
				PlatformFamily platform = Platform;
				string text = (((int)platform == 16) ? "ProfileViewer.Assets.Nintendo.png" : (((int)platform == 32) ? "ProfileViewer.Assets.Playstation.png" : (((int)platform != 64) ? "ProfileViewer.Assets.Steam.png" : "ProfileViewer.Assets.Xbox.png")));
				string resourceName = text;
				Sprite val = Plugin.LoadSprite(resourceName);
				if ((Object)(object)val != (Object)null)
				{
					platformIcon.sprite = val;
				}
			}
		}

		private void HandleClick(Entry entry)
		{
			if (built && !((Object)(object)slider == (Object)null) && ReadPlayer())
			{
				PlaySound(entry.GameObject, "SFX Click");
				try
				{
					entry.Definition.OnClick(this);
				}
				catch (Exception ex)
				{
					Plugin.Log.LogWarning((object)(entry.Definition.Name + " failed: " + ex.Message));
					return;
				}
				if (entry.Definition.HideAfterClick)
				{
					entry.GameObject.SetActive(false);
					LayoutRebuilder.ForceRebuildLayoutImmediate(row);
				}
			}
		}

		private static void OpenWebPage(string url)
		{
			try
			{
				SteamFriends.ActivateGameOverlayToWebPage(url, (EActivateGameOverlayToWebPageMode)0);
			}
			catch (Exception ex) when (((ex is InvalidOperationException || ex is DllNotFoundException) ? 1 : 0) != 0)
			{
				Application.OpenURL(url);
			}
		}

		private static void AddHoverEffects(GameObject buttonObject, Transform icon)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			EventTrigger val = buttonObject.GetComponent<EventTrigger>() ?? buttonObject.AddComponent<EventTrigger>();
			val.triggers.Clear();
			Entry val2 = new Entry
			{
				eventID = (EventTriggerType)0
			};
			((UnityEvent<BaseEventData>)(object)val2.callback).AddListener((UnityAction<BaseEventData>)delegate
			{
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				PlaySound(buttonObject, "SFX Hover");
				icon.localScale = IconHoverScale;
			});
			val.triggers.Add(val2);
			Entry val3 = new Entry
			{
				eventID = (EventTriggerType)1
			};
			((UnityEvent<BaseEventData>)(object)val3.callback).AddListener((UnityAction<BaseEventData>)delegate
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				icon.localScale = IconScale;
			});
			val.triggers.Add(val3);
		}

		private static void PlaySound(GameObject parent, string childName)
		{
			Transform val = parent.transform.Find(childName);
			if (!((Object)(object)val == (Object)null))
			{
				((Component)val).gameObject.SetActive(false);
				((Component)val).gameObject.SetActive(true);
			}
		}

		public void OnOwnershipRequest(PhotonView targetView, Player requestingPlayer)
		{
		}

		public void OnOwnershipTransfered(PhotonView targetView, Player previousOwner)
		{
			Plugin.SyncLobbyOwner();
		}

		public void OnOwnershipTransferFailed(PhotonView targetView, Player senderOfFailedRequest)
		{
		}
	}
	[HarmonyPatch]
	public class InitPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(AudioLevelSlider), "Init")]
		public static void AudioLevelSliderInit(AudioLevelSlider __instance)
		{
			if (__instance.player == null)
			{
				return;
			}
			try
			{
				Plugin.CreateUI(__instance);
			}
			catch (Exception arg)
			{
				Plugin.Log.LogWarning((object)$"Profile UI setup failed: {arg}");
			}
		}
	}
	[HarmonyPatch]
	public class SteamAvatarFixPatch
	{
		private static Callback<AvatarImageLoaded_t>? avatarLoadedCallback;

		[HarmonyPostfix]
		[HarmonyPatch(typeof(SteamRuntimeManager), "InitializeAfterSceneLoad")]
		public static void InitializeAvatarListener()
		{
			if (avatarLoadedCallback == null && SteamManager.Initialized)
			{
				avatarLoadedCallback = Callback<AvatarImageLoaded_t>.Create((DispatchDelegate<AvatarImageLoaded_t>)OnAvatarImageLoaded);
				Plugin.Log.LogInfo((object)"Initialized Steam Avatar callback listener.");
			}
		}

		private static void OnAvatarImageLoaded(AvatarImageLoaded_t param)
		{
			//IL_002b: 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_0031: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				PlayerUI[] array = Object.FindObjectsOfType<PlayerUI>();
				foreach (PlayerUI val in array)
				{
					if (val.m_player != null && ulong.TryParse(val.m_player.UserId, out var result) && new CSteamID(result) == param.m_steamID)
					{
						Traverse val2 = Traverse.Create((object)val);
						val2.Field("loadedSprite").SetValue((object)false);
						val2.Field("loadingSprite").SetValue((object)false);
						val.UpdateCell();
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Failed to handle AvatarImageLoaded callback: " + ex.Message));
			}
		}
	}
	[HarmonyPatch]
	public class SteamAvatarRequestPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(SteamRuntimeManager), "GetAvatarAsync", new Type[]
		{
			typeof(ulong),
			typeof(Action<Texture2D>)
		})]
		public static bool GetAvatar(ulong accountId, Action<Texture2D> callback)
		{
			//IL_0008: 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)
			CSteamID val = default(CSteamID);
			((CSteamID)(ref val))..ctor(accountId);
			if (SteamFriends.GetMediumFriendAvatar(val) == 0 && ((CSteamID)(ref val)).IsValid() && SteamFriends.RequestUserInformation(val, true))
			{
				Plugin.Log.LogInfo((object)$"Requested missing Steam avatar for account {accountId}.");
			}
			return true;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}