Decompiled source of SteamFriends v0.8.2

plugins/SteamFriends.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using GUIFramework;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Splatform;
using Steamworks;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.UI;
using Valheim.SettingsGui;
using Valheim.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[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 SteamFriendsTab
{
	internal static class AppNames
	{
		private static Dictionary<uint, string> names;

		private static readonly HashSet<uint> asked = new HashSet<uint>();

		private static readonly Queue<uint> queue = new Queue<uint>();

		private static bool busy;

		private static float next;

		private static string FilePath => Path.Combine(Path.Combine(Paths.CachePath, "SteamFriends"), "appnames.txt");

		internal static string Get(uint app)
		{
			if (app == 0)
			{
				return null;
			}
			Load();
			if (names.TryGetValue(app, out var value))
			{
				if (value.Length <= 0)
				{
					return null;
				}
				return value;
			}
			if (Plugin.GameNames.Value && asked.Add(app))
			{
				queue.Enqueue(app);
			}
			return null;
		}

		internal static void Tick(MonoBehaviour host)
		{
			if (!busy && queue.Count != 0 && !(Time.unscaledTime < next))
			{
				host.StartCoroutine(Fetch(queue.Dequeue()));
			}
		}

		private static IEnumerator Fetch(uint app)
		{
			busy = true;
			UnityWebRequest request = UnityWebRequest.Get($"https://store.steampowered.com/api/appdetails?appids={app}&filters=basic&l=english");
			try
			{
				request.timeout = 10;
				yield return request.SendWebRequest();
				string text = null;
				if ((int)request.result == 1)
				{
					Match match = Regex.Match(request.downloadHandler.text, "\"name\"\\s*:\\s*\"((?:[^\"\\\\]|\\\\.)*)\"");
					if (match.Success)
					{
						try
						{
							text = Regex.Unescape(match.Groups[1].Value).Trim();
						}
						catch
						{
							text = null;
						}
					}
				}
				else
				{
					Plugin.Debug($"game name {app}: {request.error}");
				}
				if (!string.IsNullOrEmpty(text))
				{
					names[app] = text;
					Save(app, text);
					Friends.AppNameArrived(app);
				}
			}
			finally
			{
				((IDisposable)request)?.Dispose();
			}
			busy = false;
			next = Time.unscaledTime + 1.5f;
		}

		private static void Load()
		{
			if (names != null)
			{
				return;
			}
			names = new Dictionary<uint, string>();
			try
			{
				if (!File.Exists(FilePath))
				{
					return;
				}
				string[] array = File.ReadAllLines(FilePath);
				foreach (string text in array)
				{
					int num = text.IndexOf('\t');
					if (num > 0 && uint.TryParse(text.Substring(0, num), out var result))
					{
						names[result] = text.Substring(num + 1);
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Warn("game names: " + ex.Message);
			}
		}

		private static void Save(uint app, string name)
		{
			try
			{
				Directory.CreateDirectory(Path.GetDirectoryName(FilePath));
				File.AppendAllText(FilePath, app + "\t" + name.Replace("\t", " ").Replace("\n", " ").Replace("\r", " ") + "\n");
			}
			catch (Exception ex)
			{
				Plugin.Warn("game names: " + ex.Message);
			}
		}
	}
	internal enum CharacterListMode
	{
		Joining,
		Always,
		Off
	}
	[HarmonyPatch(typeof(FejdStartup), "Start")]
	internal static class CharacterMenuPatch
	{
		private static void Postfix(FejdStartup __instance)
		{
			Build(__instance);
		}

		internal static void Build(FejdStartup __instance)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			try
			{
				GameObject val = new GameObject("SteamFriends characters", new Type[1] { typeof(RectTransform) });
				val.transform.SetParent(__instance.m_characterSelectScreen.transform, false);
				val.AddComponent<CharacterMenu>().Build(__instance, (RectTransform)val.transform);
			}
			catch (Exception ex)
			{
				Plugin.Warn("characters: the menu was not added: " + ex);
			}
		}
	}
	internal sealed class CharacterMenu : MonoBehaviour
	{
		private const int PortraitWidth = 112;

		private const int PortraitHeight = 144;

		private static readonly Dictionary<string, Texture2D> portraits = new Dictionary<string, Texture2D>();

		private static readonly FieldRef<FejdStartup, List<PlayerProfile>> profilesOf = AccessTools.FieldRefAccess<FejdStartup, List<PlayerProfile>>("m_profiles");

		private static readonly FieldRef<FejdStartup, int> indexOf = AccessTools.FieldRefAccess<FejdStartup, int>("m_profileIndex");

		private static readonly FieldRef<FejdStartup, ServerJoinData> queuedOf = AccessTools.FieldRefAccess<FejdStartup, ServerJoinData>("m_queuedJoinServer");

		private FejdStartup menu;

		private RectTransform panel;

		private RectTransform content;

		private RectTransform list;

		private ScrollRect scroll;

		private Image background;

		private readonly List<(PlayerProfile profile, Button button, Image picture, TMP_Text label)> entries = new List<(PlayerProfile, Button, Image, TMP_Text)>();

		private Button create;

		private Button saves;

		private readonly List<GameObject> hiddenBar = new List<GameObject>();

		private int shownCount = -1;

		private int shownIndex = -1;

		private bool rendering;

		private bool shown;

		internal void Build(FejdStartup owner, RectTransform root)
		{
			//IL_0008: 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_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_0025: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected O, but got Unknown
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: 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_00b4: 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_011b: Unknown result type (might be due to invalid IL or missing references)
			menu = owner;
			root.anchorMin = Vector2.zero;
			root.anchorMax = Vector2.one;
			Vector2 offsetMin = (root.offsetMax = Vector2.zero);
			root.offsetMin = offsetMin;
			GameObject val = new GameObject("window", new Type[1] { typeof(RectTransform) });
			val.transform.SetParent((Transform)(object)root, false);
			panel = (RectTransform)val.transform;
			RectTransform obj = panel;
			RectTransform obj2 = panel;
			RectTransform obj3 = panel;
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(1f, 1f);
			obj3.pivot = val2;
			offsetMin = (obj2.anchorMax = val2);
			obj.anchorMin = offsetMin;
			panel.anchoredPosition = new Vector2(-40f, -40f);
			panel.sizeDelta = new Vector2(300f, 200f);
			background = MenuUi.Skin(menu, val);
			content = MenuUi.Scrolling(panel, out scroll, 10);
			MenuUi.Text(menu, content, Texts.Get(S.Characters), 22f, MenuUi.Orange, (TextAlignmentOptions)514, 30f);
			list = MenuUi.Box(content, "list");
			create = MenuUi.Button(menu, content, Texts.Get(S.NewCharacter), delegate
			{
				menu.OnCharacterNew();
			}, 36f);
			saves = MenuUi.Button(menu, content, GameButtonLabel("OnManageSaves") ?? "Manage saves", delegate
			{
				menu.OnManageSaves(1);
			}, 36f);
			UiLook.Created(panel);
			val.SetActive(false);
		}

		private string GameButtonLabel(string method)
		{
			Transform val = (((Object)(object)menu.m_csStartButton != (Object)null) ? ((Component)menu.m_csStartButton).transform.parent : null);
			while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)menu.m_characterSelectScreen.transform.parent)
			{
				Button[] componentsInChildren = ((Component)val).GetComponentsInChildren<Button>(true);
				foreach (Button val2 in componentsInChildren)
				{
					for (int j = 0; j < ((UnityEventBase)val2.onClick).GetPersistentEventCount(); j++)
					{
						if (((UnityEventBase)val2.onClick).GetPersistentMethodName(j) == method)
						{
							TMP_Text componentInChildren = ((Component)val2).GetComponentInChildren<TMP_Text>(true);
							if (componentInChildren == null)
							{
								return null;
							}
							return componentInChildren.text;
						}
					}
				}
				val = val.parent;
			}
			return null;
		}

		private void HideBar(bool hide)
		{
			if (!hide)
			{
				foreach (GameObject item in hiddenBar)
				{
					if ((Object)(object)item != (Object)null)
					{
						item.SetActive(true);
					}
				}
				hiddenBar.Clear();
				return;
			}
			if (hiddenBar.Count > 0)
			{
				foreach (GameObject item2 in hiddenBar)
				{
					if ((Object)(object)item2 != (Object)null && item2.activeSelf)
					{
						item2.SetActive(false);
					}
				}
				return;
			}
			if ((Object)(object)menu.m_csStartButton == (Object)null || (Object)(object)menu.m_csRemoveButton == (Object)null)
			{
				return;
			}
			Transform val = ((Component)menu.m_csStartButton).transform;
			while ((Object)(object)val != (Object)null && !((Component)menu.m_csRemoveButton).transform.IsChildOf(val))
			{
				val = val.parent;
			}
			if ((Object)(object)val == (Object)null || (Object)(object)val == (Object)(object)menu.m_characterSelectScreen.transform)
			{
				return;
			}
			if ((Object)(object)menu.m_csName != (Object)null && menu.m_csName.transform.IsChildOf(val))
			{
				hiddenBar.AddRange(from b in ((Component)val).GetComponentsInChildren<Button>(false)
					where !((Component)b).transform.IsChildOf(((Component)this).transform)
					select ((Component)b).gameObject);
			}
			else
			{
				hiddenBar.Add(((Component)val).gameObject);
			}
			foreach (GameObject item3 in hiddenBar)
			{
				item3.SetActive(false);
			}
		}

		private bool Wanted()
		{
			if ((Object)(object)menu == (Object)null || !menu.m_characterSelectScreen.activeInHierarchy || menu.m_newCharacterPanel.activeInHierarchy)
			{
				return false;
			}
			switch (Plugin.CharacterList.Value)
			{
			case CharacterListMode.Off:
				return false;
			case CharacterListMode.Always:
				return true;
			default:
				if (Party.InParty)
				{
					return true;
				}
				return ((ServerJoinData)(ref queuedOf.Invoke(menu))).IsValid;
			}
		}

		private void LateUpdate()
		{
			if ((Object)(object)menu == (Object)null)
			{
				return;
			}
			try
			{
				HideBar(Party.InParty && menu.m_characterSelectScreen.activeInHierarchy && !menu.m_newCharacterPanel.activeInHierarchy);
				bool flag = Wanted();
				if (flag != shown)
				{
					shown = flag;
					((Component)panel).gameObject.SetActive(flag);
					ShowBottom(!flag);
				}
				if (!flag)
				{
					return;
				}
				MenuUi.Fit(panel, content, scroll, 1f, 350f);
				ShowBottom(show: false);
				List<PlayerProfile> list = profilesOf.Invoke(menu);
				int num = indexOf.Invoke(menu);
				if (list != null)
				{
					if (list.Count != shownCount)
					{
						Fill(list);
					}
					if (num != shownIndex)
					{
						shownIndex = num;
						Mark(num);
					}
					if (!rendering && entries.Exists(((PlayerProfile profile, Button button, Image picture, TMP_Text label) e) => (Object)(object)e.picture.sprite == (Object)null))
					{
						((MonoBehaviour)this).StartCoroutine(RenderPortraits());
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Warn("characters: " + ex.Message);
				shown = false;
				((Component)panel).gameObject.SetActive(false);
				ShowBottom(show: true);
				((Behaviour)this).enabled = false;
			}
		}

		private void OnDisable()
		{
			if ((Object)(object)menu != (Object)null && shown)
			{
				ShowBottom(show: true);
			}
			shown = false;
			if ((Object)(object)menu != (Object)null)
			{
				HideBar(hide: false);
			}
		}

		private void ShowBottom(bool show)
		{
			if ((Object)(object)menu.m_csLeftButton != (Object)null)
			{
				((Component)menu.m_csLeftButton).gameObject.SetActive(show);
			}
			if ((Object)(object)menu.m_csRightButton != (Object)null)
			{
				((Component)menu.m_csRightButton).gameObject.SetActive(show);
			}
			if ((Object)(object)menu.m_csNewButton != (Object)null && !show)
			{
				((Component)menu.m_csNewButton).gameObject.SetActive(false);
			}
			if (show && (Object)(object)menu.m_csNewButton != (Object)null)
			{
				GameObject gameObject = ((Component)menu.m_csNewButton).gameObject;
				List<PlayerProfile> obj = profilesOf.Invoke(menu);
				gameObject.SetActive(obj != null && obj.Count > 0);
			}
		}

		private void Fill(List<PlayerProfile> profiles)
		{
			//IL_0316: Unknown result type (might be due to invalid IL or missing references)
			//IL_031b: Unknown result type (might be due to invalid IL or missing references)
			//IL_032e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0346: Unknown result type (might be due to invalid IL or missing references)
			//IL_0357: Unknown result type (might be due to invalid IL or missing references)
			//IL_035c: Unknown result type (might be due to invalid IL or missing references)
			//IL_035d: Unknown result type (might be due to invalid IL or missing references)
			//IL_035e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0370: Unknown result type (might be due to invalid IL or missing references)
			//IL_0377: Unknown result type (might be due to invalid IL or missing references)
			//IL_0379: Unknown result type (might be due to invalid IL or missing references)
			//IL_037a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0381: Unknown result type (might be due to invalid IL or missing references)
			//IL_0388: Unknown result type (might be due to invalid IL or missing references)
			//IL_0393: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a7: 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_00d8: 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_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_040f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0419: Expected O, but got Unknown
			//IL_03e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: 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_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			shownCount = profiles.Count;
			shownIndex = -1;
			foreach (var entry in entries)
			{
				Object.Destroy((Object)(object)((Component)entry.button).gameObject);
			}
			entries.Clear();
			Vector2 val6 = default(Vector2);
			for (int i = 0; i < profiles.Count; i++)
			{
				PlayerProfile val = profiles[i];
				int at = i;
				Button val2 = Button(list, "", 92f);
				TMP_Text componentInChildren = ((Component)val2).GetComponentInChildren<TMP_Text>(true);
				Vector2 anchorMin;
				if ((Object)(object)componentInChildren != (Object)null)
				{
					componentInChildren.alignment = (TextAlignmentOptions)4097;
					componentInChildren.richText = true;
					RectTransform rectTransform = componentInChildren.rectTransform;
					rectTransform.anchorMin = Vector2.zero;
					rectTransform.anchorMax = Vector2.one;
					rectTransform.offsetMin = new Vector2(84f, 2f);
					rectTransform.offsetMax = new Vector2(-8f, -2f);
					string text = BoundWorld(val);
					componentInChildren.text = "<noparse>" + (val.GetName() ?? "").Replace("</noparse>", "") + "</noparse>" + ((text != null) ? " <color=#ff4a3a><b>!</b></color>" : "") + (FileHelpers.CloudAndLocalStorageSupported ? ("\n<size=72%><color=#d8c8a8>" + Localization.instance.Localize(FileHelpers.GetSourceString(val.m_fileSource)) + "</color></size>") : "");
					Sprite val3 = SourceIcon(val.m_fileSource);
					if ((Object)(object)val3 != (Object)null)
					{
						GameObject val4 = new GameObject("source", new Type[1] { typeof(RectTransform) });
						val4.transform.SetParent(((Component)val2).transform, false);
						Image obj = val4.AddComponent<Image>();
						obj.sprite = val3;
						obj.preserveAspect = true;
						((Graphic)obj).raycastTarget = false;
						val4.AddComponent<LayoutElement>().ignoreLayout = true;
						RectTransform val5 = (RectTransform)val4.transform;
						((Vector2)(ref val6))..ctor(1f, 0.5f);
						val5.pivot = val6;
						anchorMin = (val5.anchorMax = val6);
						val5.anchorMin = anchorMin;
						val5.anchoredPosition = new Vector2(-8f, 0f);
						val5.sizeDelta = new Vector2(22f, 22f);
						rectTransform.offsetMax = new Vector2(-34f, -2f);
					}
					if (text != null)
					{
						UITooltip obj2 = ((Component)val2).gameObject.AddComponent<UITooltip>();
						obj2.m_tooltipPrefab = (from x in Resources.FindObjectsOfTypeAll<UITooltip>()
							select x.m_tooltipPrefab).FirstOrDefault((Func<GameObject, bool>)((GameObject x) => (Object)(object)x != (Object)null));
						obj2.m_text = string.Format(Texts.Get(S.CharacterBusy), text);
					}
				}
				GameObject val8 = new GameObject("portrait", new Type[1] { typeof(RectTransform) });
				val8.transform.SetParent(((Component)val2).transform, false);
				Image val9 = val8.AddComponent<Image>();
				val9.preserveAspect = true;
				((Graphic)val9).raycastTarget = false;
				val8.AddComponent<LayoutElement>().ignoreLayout = true;
				RectTransform val10 = (RectTransform)val8.transform;
				((Vector2)(ref val6))..ctor(0f, 0.5f);
				val10.pivot = val6;
				anchorMin = (val10.anchorMax = val6);
				val10.anchorMin = anchorMin;
				val10.anchoredPosition = new Vector2(6f, 0f);
				val10.sizeDelta = new Vector2(66f, 84f);
				if (portraits.TryGetValue(Key(val), out var value))
				{
					val9.sprite = Sprite.Create(value, new Rect(0f, 0f, (float)((Texture)value).width, (float)((Texture)value).height), new Vector2(0.5f, 0.5f));
				}
				((UnityEvent)val2.onClick).AddListener((UnityAction)delegate
				{
					Choose(at);
				});
				entries.Add((val, val2, val9, componentInChildren));
			}
		}

		private void Choose(int index)
		{
			Traverse obj = Traverse.Create((object)menu);
			obj.Field("m_profileIndex").SetValue((object)index);
			obj.Method("UpdateCharacterList", Array.Empty<object>()).GetValue();
		}

		private void Mark(int index)
		{
			//IL_0057: 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)
			for (int i = 0; i < entries.Count; i++)
			{
				if ((Object)(object)entries[i].label != (Object)null)
				{
					((Graphic)entries[i].label).color = ((i == index) ? new Color(1f, 0.75f, 0.3f) : new Color(0.95f, 0.86f, 0.65f));
				}
			}
		}

		private Sprite SourceIcon(FileSource source)
		{
			//IL_001c: 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)
			if ((Object)(object)menu.m_csFileSource == (Object)null || !FileHelpers.CloudAndLocalStorageSupported)
			{
				return null;
			}
			string text = (FileSourceHelper.IsCloud(source) ? "source_cloud" : (FileSourceHelper.IsLegacy(source) ? "source_legacy" : "source_local"));
			Transform val = menu.m_csFileSource.transform.Find(text);
			Image val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponentInChildren<Image>(true) : null);
			if (!((Object)(object)val2 != (Object)null))
			{
				return null;
			}
			return val2.sprite;
		}

		private Button Button(RectTransform parent, string text, float height)
		{
			Button obj = FriendsWindow.CloneButton(((Object)(object)menu.m_csNewButton != (Object)null) ? menu.m_csNewButton : menu.m_csStartButton, (Transform)(object)parent, "button", text);
			LayoutElement obj2 = ((Component)obj).gameObject.AddComponent<LayoutElement>();
			obj2.preferredHeight = height;
			obj2.minHeight = height;
			return obj;
		}

		private static string BoundWorld(PlayerProfile profile)
		{
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: 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)
			try
			{
				if (!Chainloader.PluginInfos.ContainsKey("local.valheim.adminmenu"))
				{
					return null;
				}
				string path = Path.Combine(Path.Combine(Paths.ConfigPath, "AdminMenu.characters"), "bindings");
				string path2 = Path.Combine(path, Sha(profile.GetFilename() ?? "") + ".bind");
				if (!File.Exists(path2))
				{
					path2 = Path.Combine(path, "id-" + profile.GetPlayerID().ToString("x16") + ".bind");
				}
				if (!File.Exists(path2))
				{
					return null;
				}
				byte[] array = File.ReadAllBytes(path2);
				if (array.Length <= 40)
				{
					return "?";
				}
				byte[] array2 = new byte[array.Length - 40];
				Array.Copy(array, 40, array2, 0, array2.Length);
				ZPackage val = new ZPackage(array2);
				val.ReadLong();
				val.ReadLong();
				string text = val.ReadString();
				return string.IsNullOrEmpty(text) ? "?" : text;
			}
			catch
			{
				return "?";
			}
		}

		private static string Sha(string text)
		{
			using SHA256 sHA = SHA256.Create();
			return BitConverter.ToString(sHA.ComputeHash(Encoding.UTF8.GetBytes(text))).Replace("-", "").ToLowerInvariant();
		}

		private static string Key(PlayerProfile p)
		{
			return p.GetFilename() + "|" + ((object)Unsafe.As<FileSource, FileSource>(ref p.m_fileSource)/*cast due to .constrained prefix*/).ToString();
		}

		private IEnumerator RenderPortraits()
		{
			rendering = true;
			foreach (var item in entries.ToList())
			{
				if ((Object)(object)this == (Object)null || !shown)
				{
					break;
				}
				if ((Object)(object)item.picture == (Object)null || (Object)(object)item.picture.sprite != (Object)null)
				{
					continue;
				}
				if (!portraits.TryGetValue(Key(item.profile), out var value))
				{
					try
					{
						value = Render(item.profile);
					}
					catch (Exception ex)
					{
						Plugin.Debug("portrait: " + ex.Message);
						value = null;
					}
					if ((Object)(object)value != (Object)null)
					{
						portraits[Key(item.profile)] = value;
					}
				}
				if ((Object)(object)value != (Object)null && (Object)(object)item.picture != (Object)null)
				{
					item.picture.sprite = Sprite.Create(value, new Rect(0f, 0f, (float)((Texture)value).width, (float)((Texture)value).height), new Vector2(0.5f, 0.5f));
				}
				else if ((Object)(object)item.picture != (Object)null)
				{
					((Behaviour)item.picture).enabled = false;
				}
				yield return null;
			}
			rendering = false;
		}

		private Texture2D Render(PlayerProfile profile)
		{
			//IL_0024: 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_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: 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_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Expected O, but got Unknown
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: 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_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_026b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0290: Unknown result type (might be due to invalid IL or missing references)
			//IL_029c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ad: Expected O, but got Unknown
			Transform characterPreviewPoint = menu.m_characterPreviewPoint;
			GameObject val = null;
			GameObject val2 = null;
			RenderTexture val3 = null;
			try
			{
				ZNetView.m_forceDisableInit = true;
				try
				{
					val = Object.Instantiate<GameObject>(menu.m_playerPrefab, characterPreviewPoint.position, characterPreviewPoint.rotation);
				}
				finally
				{
					ZNetView.m_forceDisableInit = false;
				}
				Object.DestroyImmediate((Object)(object)val.GetComponent<Rigidbody>());
				Player component = val.GetComponent<Player>();
				profile.LoadPlayerData(component);
				VisEquipment component2 = val.GetComponent<VisEquipment>();
				if ((Object)(object)component2 != (Object)null)
				{
					Traverse.Create((object)component2).Method("UpdateVisuals", Array.Empty<object>()).GetValue();
				}
				Animator[] componentsInChildren = val.GetComponentsInChildren<Animator>();
				foreach (Animator obj in componentsInChildren)
				{
					obj.updateMode = (AnimatorUpdateMode)0;
					obj.Update(0f);
				}
				Transform[] componentsInChildren2 = val.GetComponentsInChildren<Transform>(true);
				for (int i = 0; i < componentsInChildren2.Length; i++)
				{
					((Component)componentsInChildren2[i]).gameObject.layer = 31;
				}
				Transform value = Traverse.Create((object)component).Field("m_head").GetValue<Transform>();
				Vector3 val4 = Vector3.Lerp(((Object)(object)value != (Object)null) ? value.position : (val.transform.position + Vector3.up * 1.65f), val.transform.position + Vector3.up * 1f, 0.45f);
				val2 = new GameObject("SteamFriends portrait camera");
				Camera obj2 = val2.AddComponent<Camera>();
				((Behaviour)obj2).enabled = false;
				obj2.cullingMask = int.MinValue;
				obj2.clearFlags = (CameraClearFlags)2;
				obj2.backgroundColor = new Color(0.16f, 0.12f, 0.08f, 1f);
				obj2.fieldOfView = 30f;
				obj2.nearClipPlane = 0.05f;
				obj2.farClipPlane = 10f;
				obj2.aspect = 7f / 9f;
				Transform transform = val2.transform;
				Vector3 val5 = val.transform.forward + val.transform.right * 0.25f;
				transform.position = val4 + ((Vector3)(ref val5)).normalized * 1.9f + Vector3.up * 0.1f;
				val2.transform.LookAt(val4);
				val3 = (obj2.targetTexture = RenderTexture.GetTemporary(112, 144, 24));
				obj2.Render();
				RenderTexture active = RenderTexture.active;
				RenderTexture.active = val3;
				Texture2D val6 = new Texture2D(112, 144, (TextureFormat)3, false)
				{
					name = "SteamFriends portrait"
				};
				val6.ReadPixels(new Rect(0f, 0f, 112f, 144f), 0, 0);
				val6.Apply(false, false);
				RenderTexture.active = active;
				return val6;
			}
			finally
			{
				if ((Object)(object)val3 != (Object)null)
				{
					RenderTexture.ReleaseTemporary(val3);
				}
				if ((Object)(object)val2 != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)val2);
				}
				if ((Object)(object)val != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)val);
				}
			}
		}
	}
	internal static class Demo
	{
		internal enum Role
		{
			Host,
			Member
		}

		private static readonly List<CSteamID> ids = new List<CSteamID>();

		private static readonly Dictionary<ulong, string> emotes = new Dictionary<ulong, string>();

		private static readonly List<Party.Message> partyLines = new List<Party.Message>();

		private static readonly List<FriendChat.Line> chatLines = new List<FriendChat.Line>();

		private static int shown;

		private static Role shownRole;

		private static bool dismissed;

		private static bool allReady;

		private static float nextEmote;

		private static int emoteCount;

		private static readonly string[] played = new string[8] { "wave", "cheer", "laugh", "thumbsup", "toast", "flex", "bow", "headbang" };

		private static readonly string[] worlds = new string[5] { "Fjordheim", "Ashvale", "Mistholm", "Frostgard", "Ironwood" };

		private static readonly Vector3[] hairColours = (Vector3[])(object)new Vector3[5]
		{
			new Vector3(0.9f, 0.75f, 0.5f),
			new Vector3(0.45f, 0.3f, 0.2f),
			new Vector3(0.25f, 0.18f, 0.12f),
			new Vector3(0.7f, 0.35f, 0.2f),
			new Vector3(0.6f, 0.6f, 0.6f)
		};

		private static readonly string[] chests = new string[5] { "ArmorLeatherChest", "ArmorBronzeChest", "ArmorRootChest", "ArmorWolfChest", "ArmorTrollLeatherChest" };

		private static readonly string[] legs = new string[5] { "ArmorLeatherLegs", "ArmorBronzeLegs", "ArmorRootLegs", "ArmorWolfLegs", "ArmorTrollLeatherLegs" };

		private static readonly string[] capes = new string[4] { "CapeDeerHide", "CapeTrollHide", "CapeWolf", "CapeLinen" };

		internal static bool On
		{
			get
			{
				if (Plugin.DemoParty != null && Plugin.DemoParty.Value > 0 && Friends.Ready)
				{
					return !dismissed;
				}
				return false;
			}
		}

		internal static bool Hosting
		{
			get
			{
				if (Plugin.DemoRole != null)
				{
					return Plugin.DemoRole.Value == Role.Host;
				}
				return true;
			}
		}

		internal static bool Is(CSteamID id)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			if (On)
			{
				return ids.Contains(id);
			}
			return false;
		}

		internal static void Changed()
		{
			dismissed = false;
		}

		internal static void Dismiss()
		{
			dismissed = true;
			Plugin.Log("demo: the stand-in party is hidden until DemoParty changes");
		}

		internal static void Tick()
		{
			//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_006d: 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_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: 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_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)
			int num = (On ? Plugin.DemoParty.Value : 0);
			Role role = ((!Hosting) ? Role.Member : Role.Host);
			if (num != shown || (num > 0 && role != shownRole))
			{
				Apply(num, role);
			}
			if (shown != 0)
			{
				KeyboardShortcut value = Plugin.DemoInviteKey.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					InviteNotice.ShowDemo(ids[0]);
				}
				value = Plugin.DemoOnlineKey.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					Social.Show(string.Format(Texts.Get(S.FriendInValheim), Plugin.NameOf(ids[ids.Count - 1])));
				}
				value = Plugin.DemoReadyKey.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					allReady = !allReady;
					Party.Refresh();
				}
				if ((Object)(object)FejdStartup.instance != (Object)null && !Party.Real && Time.unscaledTime >= nextEmote)
				{
					nextEmote = Time.unscaledTime + Random.Range(5f, 9f);
					CSteamID val = ids[Random.Range(0, ids.Count)];
					Dictionary<ulong, string> dictionary = emotes;
					ulong steamID = val.m_SteamID;
					string obj = played[Random.Range(0, played.Length)];
					int num2 = ++emoteCount;
					dictionary[steamID] = obj + "|" + num2;
					Party.Refresh();
				}
			}
		}

		private static void Apply(int count, Role role)
		{
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: 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_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: 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)
			List<CSteamID> list = ids.ToList();
			ids.Clear();
			emotes.Clear();
			Party.Chat.RemoveAll((Party.Message m) => partyLines.Contains(m));
			partyLines.Clear();
			foreach (FriendChat.Line chatLine in chatLines)
			{
				foreach (List<FriendChat.Line> value in FriendChat.History.Values)
				{
					value.Remove(chatLine);
				}
			}
			chatLines.Clear();
			foreach (CSteamID item in list)
			{
				FriendChat.Unread.Remove(item.m_SteamID);
				Invites.Invited.Remove(item.m_SteamID);
			}
			shown = count;
			shownRole = role;
			allReady = false;
			if (count > 0)
			{
				ids.AddRange(Pick(count));
				if (ids.Count == 0)
				{
					shown = 0;
					Plugin.Warn("demo: no Steam friends to stand in");
				}
			}
			if (ids.Count > 0)
			{
				foreach (CSteamID id in ids)
				{
					Plugin.NameOf(id);
				}
				CSteamID val = ids[0];
				CSteamID val2 = ids[Math.Min(1, ids.Count - 1)];
				Say(val, "The fire is warm, come sit down!");
				Say(val2, "Bringing the mead.");
				Say(val, "Ready when you are.");
				Write(val, mine: false, "Are you on tonight?");
				Write(val, mine: true, "Yes! Making a party at the fire.");
				Write(val, mine: false, "Coming, give me a minute.");
				FriendChat.Unread[val.m_SteamID] = 1;
				FriendChat.Revision++;
				Plugin.Log($"demo: {ids.Count} stand-in friends, you are the {role}; nothing is sent to them");
			}
			else if (list.Count > 0)
			{
				if (!Party.Real)
				{
					Party.Chat.Clear();
				}
				Plugin.Log("demo: off");
			}
			Friends.Reread(list.Concat(ids));
			Party.Refresh();
		}

		private static void Say(CSteamID from, string text)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			Party.Message item = new Party.Message
			{
				From = Plugin.NameOf(from),
				Text = text
			};
			partyLines.Add(item);
			Party.Chat.Add(item);
		}

		private static void Write(CSteamID with, bool mine, string text)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			FriendChat.Line line = new FriendChat.Line
			{
				Mine = mine,
				Text = text
			};
			chatLines.Add(line);
			FriendChat.Add(with.m_SteamID, line);
		}

		private static List<CSteamID> Pick(int count)
		{
			//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_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_0028: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Invalid comparison between Unknown and I4
			//IL_0041: 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_0036: Invalid comparison between Unknown and I4
			List<KeyValuePair<CSteamID, int>> list = new List<KeyValuePair<CSteamID, int>>();
			int friendCount = SteamFriends.GetFriendCount((EFriendFlags)4);
			for (int i = 0; i < friendCount; i++)
			{
				CSteamID friendByIndex = SteamFriends.GetFriendByIndex(i, (EFriendFlags)4);
				if (((CSteamID)(ref friendByIndex)).IsValid())
				{
					EPersonaState friendPersonaState = SteamFriends.GetFriendPersonaState(friendByIndex);
					int value = (((int)friendPersonaState == 0 || (int)friendPersonaState == 7) ? 2 : (((int)friendPersonaState != 1) ? 1 : 0));
					list.Add(new KeyValuePair<CSteamID, int>(friendByIndex, value));
				}
			}
			return (from p in list.OrderBy((KeyValuePair<CSteamID, int> p) => p.Value).Take(count)
				select p.Key).ToList();
		}

		internal static void Fill(List<Party.Member> members)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: 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)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			CSteamID me = Friends.Me;
			bool hosting = Hosting;
			if (!hosting && ids.Count > 0)
			{
				members.Add(Stand(0, host: true));
			}
			members.Add(new Party.Member
			{
				Id = me,
				Name = Plugin.NameOf(me),
				Look = Party.OwnLook,
				Ready = Party.Ready,
				Host = hosting
			});
			for (int i = ((!hosting) ? 1 : 0); i < ids.Count; i++)
			{
				members.Add(Stand(i, host: false));
			}
		}

		private static Party.Member Stand(int i, bool host)
		{
			//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_0011: 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_0026: 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)
			CSteamID val = ids[i];
			emotes.TryGetValue(val.m_SteamID, out var value);
			return new Party.Member
			{
				Id = val,
				Name = Plugin.NameOf(val),
				Host = host,
				Look = "demo:" + i,
				Emote = value,
				Ready = (!host && (allReady || i < ids.Count - 1))
			};
		}

		internal static void Dress(Friend f)
		{
			//IL_0001: 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_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			int num = (Is(f.Id) ? ids.IndexOf(f.Id) : (-1));
			if (num >= 0)
			{
				f.State = (EPersonaState)1;
				f.InValheim = true;
				f.InOtherGame = false;
				f.AppId = 892970u;
				f.Lobby = CSteamID.Nil;
				f.LobbyName = (f.LobbyVersion = null);
				f.LobbyPassword = false;
				f.WorldShared = worlds[num % worlds.Length];
				f.ServerShared = null;
				f.ConnectShared = "+connect_lobby 0";
			}
		}

		internal static bool Dress(GameObject go, string look)
		{
			if (look == null || !look.StartsWith("demo:"))
			{
				return false;
			}
			int.TryParse(look.Substring(5), out var result);
			try
			{
				FejdStartup instance = FejdStartup.instance;
				Traverse val = (((Object)(object)instance != (Object)null) ? Traverse.Create((object)instance) : null);
				List<PlayerProfile> obj = ((val != null) ? val.Field("m_profiles").GetValue<List<PlayerProfile>>() : null);
				int selected = ((val != null) ? val.Field("m_profileIndex").GetValue<int>() : (-1));
				List<PlayerProfile> list = obj?.Where((PlayerProfile p, int k) => p != null && k != selected).ToList();
				VisEquipment component = go.GetComponent<VisEquipment>();
				if (list != null && result < list.Count)
				{
					list[result].LoadPlayerData(go.GetComponent<Player>());
				}
				else if ((Object)(object)component != (Object)null)
				{
					Random(component, result);
				}
				if ((Object)(object)component != (Object)null)
				{
					Traverse.Create((object)component).Method("UpdateVisuals", Array.Empty<object>()).GetValue();
				}
			}
			catch (Exception ex)
			{
				Plugin.Warn("demo look: " + ex.Message);
			}
			return true;
		}

		private static void Random(VisEquipment vis, int i)
		{
			//IL_0025: 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_0045: 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)
			Random random = new Random(7919 * (i + 1));
			bool flag = random.Next(2) == 0;
			vis.SetModel((!flag) ? 1 : 0);
			vis.SetSkinColor(Vector3.Lerp(Vector3.one, new Vector3(0.55f, 0.45f, 0.4f), (float)random.NextDouble()));
			vis.SetHairColor(hairColours[random.Next(hairColours.Length)]);
			vis.SetHairItem(StringExtensionMethods.GetStableHashCode("Hair" + random.Next(1, 15)));
			vis.SetBeardItem(flag ? StringExtensionMethods.GetStableHashCode("Beard" + random.Next(1, 12)) : 0);
			vis.SetChestItem(StringExtensionMethods.GetStableHashCode(chests[random.Next(chests.Length)]));
			vis.SetLegItem(StringExtensionMethods.GetStableHashCode(legs[random.Next(legs.Length)]));
			vis.SetShoulderItem(StringExtensionMethods.GetStableHashCode(capes[random.Next(capes.Length)]), 0, 1);
		}
	}
	internal sealed class FriendPicker : MonoBehaviour
	{
		private sealed class Row
		{
			internal Friend F;

			internal GameObject Go;

			internal Image Avatar;

			internal TMP_Text Text;

			internal Button Invite;
		}

		internal static FriendPicker Current;

		private FejdStartup menu;

		private RectTransform window;

		private RectTransform list;

		private TMP_InputField search;

		private readonly List<Row> rows = new List<Row>();

		private Sprite noAvatar;

		private int seen = -1;

		private float nextFill;

		internal void Build(FejdStartup owner, RectTransform root)
		{
			//IL_000e: 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_0025: 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)
			//IL_0032: 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)
			//IL_0057: Expected O, but got Unknown
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			//IL_0098: 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_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: 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_00b6: 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_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Expected O, but got Unknown
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			//IL_028c: Expected O, but got Unknown
			//IL_02c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e6: Expected O, but got Unknown
			menu = owner;
			Current = this;
			root.anchorMin = Vector2.zero;
			root.anchorMax = Vector2.one;
			Vector2 offsetMin = (root.offsetMax = Vector2.zero);
			root.offsetMin = offsetMin;
			GameObject val = new GameObject("window", new Type[1] { typeof(RectTransform) });
			val.transform.SetParent((Transform)(object)root, false);
			window = (RectTransform)val.transform;
			RectTransform obj = window;
			RectTransform obj2 = window;
			RectTransform obj3 = window;
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(0.5f, 0.5f);
			obj3.pivot = val2;
			offsetMin = (obj2.anchorMax = val2);
			obj.anchorMin = offsetMin;
			window.anchoredPosition = Vector2.zero;
			window.sizeDelta = new Vector2(560f, 640f);
			MenuUi.Skin(menu, val);
			VerticalLayoutGroup obj4 = val.AddComponent<VerticalLayoutGroup>();
			((LayoutGroup)obj4).padding = new RectOffset(16, 16, 14, 14);
			((HorizontalOrVerticalLayoutGroup)obj4).spacing = 8f;
			bool childControlWidth = (((HorizontalOrVerticalLayoutGroup)obj4).childControlHeight = true);
			((HorizontalOrVerticalLayoutGroup)obj4).childControlWidth = childControlWidth;
			((HorizontalOrVerticalLayoutGroup)obj4).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj4).childForceExpandHeight = false;
			RectTransform val4 = MenuUi.Row(window, 34f);
			HorizontalLayoutGroup component = ((Component)val4).GetComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)component).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)component).childForceExpandHeight = false;
			((LayoutGroup)component).childAlignment = (TextAnchor)3;
			((Component)MenuUi.Text(menu, val4, Texts.Get(S.PartyCallFriend), 24f, MenuUi.Orange, (TextAlignmentOptions)513, 34f)).GetComponent<LayoutElement>().flexibleWidth = 1f;
			Button obj5 = MenuUi.Button(menu, val4, "×", Close, 30f);
			LayoutElement component2 = ((Component)obj5).GetComponent<LayoutElement>();
			float preferredWidth = (component2.minWidth = 30f);
			component2.preferredWidth = preferredWidth;
			component2.flexibleWidth = 0f;
			component2.flexibleHeight = 0f;
			TMP_Text val5 = MenuUi.Label(obj5);
			if ((Object)(object)val5 != (Object)null)
			{
				RectTransform rectTransform = val5.rectTransform;
				offsetMin = (val5.rectTransform.offsetMax = Vector2.zero);
				rectTransform.offsetMin = offsetMin;
				val5.enableAutoSizing = false;
				val5.fontSize = 22f;
			}
			search = MenuUi.Input(menu, window, Texts.Get(S.PartySearch), 40, 40f);
			if ((Object)(object)search != (Object)null)
			{
				((UnityEvent<string>)(object)search.onValueChanged).AddListener((UnityAction<string>)delegate
				{
					Fill();
				});
			}
			GameObject val6 = new GameObject("list frame", new Type[1] { typeof(RectTransform) });
			val6.transform.SetParent((Transform)(object)window, false);
			val6.AddComponent<LayoutElement>().flexibleHeight = 1f;
			((Graphic)val6.AddComponent<Image>()).color = new Color(0f, 0f, 0f, 0.25f);
			list = MenuUi.Scrolling((RectTransform)val6.transform, out var _, 6);
			((Selectable)MenuUi.Button(menu, window, Texts.Get(S.PartyInviteSteam), Party.InviteWindow, 38f)).interactable = Invites.OverlayAvailable;
			noAvatar = (from e in Resources.FindObjectsOfTypeAll<SessionPlayerListEntry>()
				select e.OtherPlatformPlayerPic).FirstOrDefault((Func<Sprite, bool>)((Sprite s) => (Object)(object)s != (Object)null));
			UiLook.Created(window);
			val.SetActive(false);
		}

		internal static void Toggle()
		{
			if (!((Object)(object)Current == (Object)null))
			{
				if (((Component)Current.window).gameObject.activeSelf)
				{
					Current.Close();
				}
				else
				{
					Current.Open();
				}
			}
		}

		private void Open()
		{
			((Component)window).gameObject.SetActive(true);
			if ((Object)(object)search != (Object)null)
			{
				search.text = "";
			}
			Fill();
		}

		private void Close()
		{
			((Component)window).gameObject.SetActive(false);
		}

		private void Update()
		{
			if (((Component)window).gameObject.activeSelf)
			{
				if (!Party.InParty || !Party.IsHost || !menu.m_characterSelectScreen.activeInHierarchy || MenuUi.GameBusy(menu))
				{
					Close();
				}
				else if (Friends.Revision != seen || Time.unscaledTime >= nextFill)
				{
					Refresh();
				}
			}
		}

		private void Fill()
		{
			foreach (Row row in rows)
			{
				Object.Destroy((Object)(object)row.Go);
			}
			rows.Clear();
			HashSet<ulong> inParty = new HashSet<ulong>(Party.Members.Select((Party.Member m) => m.Id.m_SteamID));
			string query = (((Object)(object)search != (Object)null) ? search.text.Trim() : "");
			foreach (Friend item in (from f in Friends.Load()
				where !inParty.Contains(f.Id.m_SteamID) && (query.Length == 0 || f.Name.IndexOf(query, StringComparison.CurrentCultureIgnoreCase) >= 0)
				orderby f.Rank
				select f).ThenBy<Friend, string>((Friend f) => f.Name, StringComparer.CurrentCultureIgnoreCase).Take(80))
			{
				rows.Add(MakeRow(item));
			}
			Refresh();
		}

		private Row MakeRow(Friend f)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			//IL_00ab: 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_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Expected O, but got Unknown
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Expected O, but got Unknown
			GameObject val = new GameObject("friend", new Type[1] { typeof(RectTransform) });
			val.transform.SetParent((Transform)(object)list, false);
			HorizontalLayoutGroup obj = val.AddComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)obj).spacing = 10f;
			((LayoutGroup)obj).padding = new RectOffset(4, 4, 3, 3);
			bool childControlWidth = (((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true);
			((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = childControlWidth;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false;
			((LayoutGroup)obj).childAlignment = (TextAnchor)3;
			val.AddComponent<LayoutElement>().preferredHeight = 54f;
			GameObject val2 = new GameObject("avatar", new Type[1] { typeof(RectTransform) });
			val2.transform.SetParent(val.transform, false);
			Image val3 = val2.AddComponent<Image>();
			val3.preserveAspect = true;
			((Graphic)val3).raycastTarget = false;
			LayoutElement obj2 = val2.AddComponent<LayoutElement>();
			float preferredWidth = (obj2.minWidth = 46f);
			obj2.preferredWidth = preferredWidth;
			preferredWidth = (obj2.minHeight = 46f);
			obj2.preferredHeight = preferredWidth;
			TMP_Text val4 = MenuUi.Text(menu, (RectTransform)val.transform, "", 18f, MenuUi.Beige, (TextAlignmentOptions)4097, 48f);
			val4.textWrappingMode = (TextWrappingModes)0;
			val4.overflowMode = (TextOverflowModes)1;
			((Component)val4).GetComponent<LayoutElement>().flexibleWidth = 1f;
			Row row = new Row
			{
				F = f,
				Go = val,
				Avatar = val3,
				Text = val4
			};
			row.Invite = MenuUi.Button(menu, (RectTransform)val.transform, Texts.Get(S.Invite), delegate
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				if (Party.Invite(f.Id))
				{
					((Selectable)row.Invite).interactable = false;
					MenuUi.Label(row.Invite).text = Texts.Get(S.Invited);
				}
			}, 40f);
			LayoutElement component = ((Component)row.Invite).GetComponent<LayoutElement>();
			preferredWidth = (component.minWidth = 150f);
			component.preferredWidth = preferredWidth;
			return row;
		}

		private void Refresh()
		{
			seen = Friends.Revision;
			nextFill = Time.unscaledTime + 5f;
			foreach (Row row in rows)
			{
				Friend f = row.F;
				row.Avatar.sprite = Friends.Avatar(f) ?? noAvatar;
				((Behaviour)row.Avatar).enabled = (Object)(object)row.Avatar.sprite != (Object)null;
				row.Text.text = MenuUi.Plain(f.Name) + "\n<size=80%>" + FriendsWindow.Status(f, here: false) + "</size>";
				(row.Go.GetComponent<CanvasGroup>() ?? row.Go.AddComponent<CanvasGroup>()).alpha = (f.Offline ? 0.55f : 1f);
			}
		}
	}
	internal sealed class Friend
	{
		internal CSteamID Id;

		internal string Name = "";

		internal EPersonaState State;

		internal bool InValheim;

		internal bool InOtherGame;

		internal CSteamID Lobby = CSteamID.Nil;

		internal uint AppId;

		internal string LobbyName;

		internal string LobbyVersion;

		internal bool LobbyPassword;

		internal string WorldShared;

		internal string ServerShared;

		internal string ConnectShared;

		internal bool Offline
		{
			get
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_000f: Invalid comparison between Unknown and I4
				if ((int)State != 0)
				{
					return (int)State == 7;
				}
				return true;
			}
		}

		internal bool Idle
		{
			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_0010: Invalid comparison between Unknown and I4
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Invalid comparison between Unknown and I4
				if ((int)State != 3 && (int)State != 4)
				{
					return (int)State == 2;
				}
				return true;
			}
		}

		internal int Rank
		{
			get
			{
				if (!InValheim)
				{
					if (!InOtherGame && (Offline || Idle))
					{
						if (!Idle)
						{
							return 3;
						}
						return 2;
					}
					return 1;
				}
				return 0;
			}
		}
	}
	internal static class Friends
	{
		[HarmonyPatch(typeof(SteamManager), "OnDestroy")]
		private static class ShutdownPatch
		{
			private static void Prefix(SteamManager __instance)
			{
				if ((Object)(object)__instance != (Object)(object)SteamManager.instance)
				{
					return;
				}
				closed = true;
				try
				{
					personaChanged?.Dispose();
					avatarLoaded?.Dispose();
					joinRequested?.Dispose();
					lobbyData?.Dispose();
					richPresence?.Dispose();
					personaChanged = null;
					avatarLoaded = null;
					joinRequested = null;
					lobbyData = null;
					richPresence = null;
					Party.Release();
					FriendChat.Release();
					Plugin.Debug("Steam callbacks released before Steam's shutdown");
				}
				catch (Exception ex)
				{
					Plugin.Warn("releasing Steam callbacks: " + ex.Message);
				}
			}
		}

		internal const uint ValheimAppId = 892970u;

		private static Callback<PersonaStateChange_t> personaChanged;

		private static Callback<AvatarImageLoaded_t> avatarLoaded;

		private static Callback<GameRichPresenceJoinRequested_t> joinRequested;

		private static Callback<LobbyDataUpdate_t> lobbyData;

		private static Callback<FriendRichPresenceUpdate_t> richPresence;

		private static readonly HashSet<ulong> lobbyRequested = new HashSet<ulong>();

		private static readonly HashSet<ulong> presenceRequested = new HashSet<ulong>();

		private static readonly Dictionary<ulong, Friend> byId = new Dictionary<ulong, Friend>();

		private static readonly Dictionary<int, Sprite> sprites = new Dictionary<int, Sprite>();

		private static readonly HashSet<ulong> requested = new HashSet<ulong>();

		internal static readonly HashSet<ulong> Changed = new HashSet<ulong>();

		internal static int Revision;

		private static CSteamID me = CSteamID.Nil;

		private static bool closed;

		internal static bool Ready
		{
			get
			{
				if (SteamManager.Initialized)
				{
					return personaChanged != null;
				}
				return false;
			}
		}

		internal static CSteamID Me
		{
			get
			{
				//IL_001d: 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_0018: Unknown result type (might be due to invalid IL or missing references)
				if (!((CSteamID)(ref me)).IsValid() && SteamManager.Initialized)
				{
					me = SteamUser.GetSteamID();
				}
				return me;
			}
		}

		internal static void Tick()
		{
			if (!closed && personaChanged == null && SteamManager.Initialized)
			{
				personaChanged = Callback<PersonaStateChange_t>.Create((DispatchDelegate<PersonaStateChange_t>)OnPersonaChanged);
				avatarLoaded = Callback<AvatarImageLoaded_t>.Create((DispatchDelegate<AvatarImageLoaded_t>)OnAvatarLoaded);
				joinRequested = Callback<GameRichPresenceJoinRequested_t>.Create((DispatchDelegate<GameRichPresenceJoinRequested_t>)Invites.OnJoinRequested);
				lobbyData = Callback<LobbyDataUpdate_t>.Create((DispatchDelegate<LobbyDataUpdate_t>)OnLobbyData);
				richPresence = Callback<FriendRichPresenceUpdate_t>.Create((DispatchDelegate<FriendRichPresenceUpdate_t>)OnRichPresence);
				Party.Init();
				FriendChat.Init();
				Load();
				Plugin.Debug("Steam callbacks registered");
			}
		}

		internal static List<Friend> Load()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: 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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: 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)
			List<Friend> list = new List<Friend>();
			if (!Ready)
			{
				return list;
			}
			int friendCount = SteamFriends.GetFriendCount((EFriendFlags)4);
			for (int i = 0; i < friendCount; i++)
			{
				CSteamID friendByIndex = SteamFriends.GetFriendByIndex(i, (EFriendFlags)4);
				if (((CSteamID)(ref friendByIndex)).IsValid())
				{
					if (!byId.TryGetValue(friendByIndex.m_SteamID, out var value))
					{
						Dictionary<ulong, Friend> dictionary = byId;
						ulong steamID = friendByIndex.m_SteamID;
						Friend obj = new Friend
						{
							Id = friendByIndex
						};
						value = obj;
						dictionary[steamID] = obj;
					}
					Read(value);
					list.Add(value);
				}
			}
			return list;
		}

		private static void Read(Friend f)
		{
			//IL_0002: 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_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_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)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: 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_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			f.Name = Plugin.NameOf(f.Id);
			f.State = SteamFriends.GetFriendPersonaState(f.Id);
			f.InValheim = (f.InOtherGame = false);
			f.Lobby = CSteamID.Nil;
			f.AppId = 0u;
			FriendGameInfo_t val = default(FriendGameInfo_t);
			if (SteamFriends.GetFriendGamePlayed(f.Id, ref val) && ((CGameID)(ref val.m_gameID)).IsValid())
			{
				uint num = (f.AppId = ((CGameID)(ref val.m_gameID)).AppID().m_AppId);
				f.InValheim = num == 892970 || num == SteamManager.APP_ID;
				f.InOtherGame = !f.InValheim;
				if (f.InValheim && ((CSteamID)(ref val.m_steamIDLobby)).IsValid())
				{
					f.Lobby = val.m_steamIDLobby;
				}
			}
			f.LobbyName = (f.LobbyVersion = null);
			f.LobbyPassword = false;
			if (((CSteamID)(ref f.Lobby)).IsValid())
			{
				string text = SteamMatchmaking.GetLobbyData(f.Lobby, "name");
				if (!string.IsNullOrEmpty(text))
				{
					f.LobbyName = text;
					f.LobbyVersion = SteamMatchmaking.GetLobbyData(f.Lobby, "version");
					f.LobbyPassword = SteamMatchmaking.GetLobbyData(f.Lobby, "password") == "1";
				}
				else if (lobbyRequested.Add(f.Lobby.m_SteamID))
				{
					SteamMatchmaking.RequestLobbyData(f.Lobby);
				}
			}
			f.WorldShared = (f.ServerShared = (f.ConnectShared = null));
			if (f.InValheim)
			{
				if (presenceRequested.Add(f.Id.m_SteamID))
				{
					SteamFriends.RequestFriendRichPresence(f.Id);
				}
				f.WorldShared = Shared(f, "steamfriends_world");
				f.ServerShared = Shared(f, "steamfriends_server");
				f.ConnectShared = Shared(f, "connect");
			}
			Demo.Dress(f);
		}

		internal static void Reread(IEnumerable<CSteamID> ids)
		{
			//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_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			foreach (CSteamID id in ids)
			{
				if (byId.TryGetValue(id.m_SteamID, out var value))
				{
					Read(value);
					Changed.Add(id.m_SteamID);
					Revision++;
				}
			}
		}

		private static string Shared(Friend f, string key)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			string friendRichPresence = SteamFriends.GetFriendRichPresence(f.Id, key);
			if (!string.IsNullOrEmpty(friendRichPresence))
			{
				return friendRichPresence;
			}
			return null;
		}

		private static void OnLobbyData(LobbyDataUpdate_t data)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			foreach (Friend value in byId.Values)
			{
				if (value.Lobby.m_SteamID == data.m_ulSteamIDLobby)
				{
					Read(value);
					Changed.Add(value.Id.m_SteamID);
					Revision++;
				}
			}
		}

		private static void OnRichPresence(FriendRichPresenceUpdate_t data)
		{
			//IL_0005: 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)
			if (byId.TryGetValue(data.m_steamIDFriend.m_SteamID, out var value))
			{
				Read(value);
				Changed.Add(value.Id.m_SteamID);
				Revision++;
			}
		}

		internal static void AppNameArrived(uint app)
		{
			foreach (Friend value in byId.Values)
			{
				if (value.AppId == app)
				{
					Changed.Add(value.Id.m_SteamID);
					Revision++;
				}
			}
		}

		private static void OnPersonaChanged(PersonaStateChange_t data)
		{
			//IL_0005: 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)
			if (byId.TryGetValue(data.m_ulSteamID, out var value))
			{
				bool wasOnline = !value.Offline;
				bool inValheim = value.InValheim;
				Read(value);
				Changed.Add(data.m_ulSteamID);
				Revision++;
				Social.FriendChanged(value, wasOnline, inValheim);
			}
		}

		private static void OnAvatarLoaded(AvatarImageLoaded_t data)
		{
			//IL_0005: 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_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			if (byId.ContainsKey(data.m_steamID.m_SteamID))
			{
				Changed.Add(data.m_steamID.m_SteamID);
				Revision++;
			}
		}

		internal static Sprite Avatar(Friend f)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return Avatar(f.Id);
		}

		internal static Sprite Avatar(CSteamID id)
		{
			//IL_0000: 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_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Expected O, but got Unknown
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			int mediumFriendAvatar = SteamFriends.GetMediumFriendAvatar(id);
			switch (mediumFriendAvatar)
			{
			case -1:
				return null;
			case 0:
				if (requested.Add(id.m_SteamID))
				{
					SteamFriends.RequestUserInformation(id, false);
				}
				return null;
			default:
			{
				if (sprites.TryGetValue(mediumFriendAvatar, out var value))
				{
					return value;
				}
				uint num = default(uint);
				uint num2 = default(uint);
				if (!SteamUtils.GetImageSize(mediumFriendAvatar, ref num, ref num2) || num == 0 || num2 == 0)
				{
					return null;
				}
				byte[] array = new byte[num * num2 * 4];
				if (!SteamUtils.GetImageRGBA(mediumFriendAvatar, array, array.Length))
				{
					return null;
				}
				byte[] array2 = new byte[array.Length];
				int num3 = (int)(num * 4);
				for (int i = 0; i < num2; i++)
				{
					Buffer.BlockCopy(array, i * num3, array2, ((int)(num2 - 1) - i) * num3, num3);
				}
				Texture2D val = new Texture2D((int)num, (int)num2, (TextureFormat)4, false)
				{
					name = "SteamFriends avatar",
					wrapMode = (TextureWrapMode)1
				};
				val.LoadRawTextureData(array2);
				val.Apply(false, true);
				value = Sprite.Create(val, new Rect(0f, 0f, (float)num, (float)num2), new Vector2(0.5f, 0.5f), 100f);
				((Object)value).name = ((Object)val).name;
				sprites[mediumFriendAvatar] = value;
				return value;
			}
			}
		}
	}
	[HarmonyPatch(typeof(SessionPlayerList), "Start")]
	internal static class PlayerListPatch
	{
		private static void Postfix(SessionPlayerList __instance)
		{
			if (__instance.LoadHistoricalList || !Friends.Ready)
			{
				return;
			}
			try
			{
				((Component)__instance).gameObject.AddComponent<FriendsWindow>().Build(__instance);
			}
			catch (Exception ex)
			{
				Plugin.Warn("player list: the friends tab was not added: " + ex);
			}
		}
	}
	internal sealed class FriendsWindow : MonoBehaviour
	{
		private sealed class Row
		{
			internal Friend F;

			internal GameObject Go;

			internal Image Avatar;

			internal TMP_Text Name;

			internal TMP_Text Status;

			internal TMP_Text InviteLabel;

			internal Button Invite;

			internal Button Join;

			internal Button Write;

			internal RectTransform Actions;

			internal float TextMargin = -1f;

			internal UITooltip Tip;

			internal UITooltip JoinTip;

			internal TMP_Text JoinLabel;

			internal TMP_Text WriteLabel;

			internal CanvasGroup Group;

			internal float FailedUntil;
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static UnityAction <0>__OpenOverlay;
		}

		private const float TabHeight = 46f;

		private const float SearchHeight = 42f;

		private const float ShareHeight = 36f;

		private const float Gap = 8f;

		private static readonly Color Orange = new Color(1f, 0.63f, 0.24f);

		private readonly List<GameObject> playersPage = new List<GameObject>();

		private readonly List<GameObject> friendsPage = new List<GameObject>();

		private readonly Button[] tabs = (Button[])(object)new Button[2];

		private readonly Dictionary<ulong, Row> rows = new Dictionary<ulong, Row>();

		private List<Friend> friends = new List<Friend>();

		private ScrollRect friendsScroll;

		private RectTransform friendsBar;

		private TMP_InputField search;

		private Button overlay;

		private TMP_Text empty;

		private GameObject rowTemplate;

		private string avatarPath;

		private string namePath;

		private string statusPath;

		private string cardPath;

		private string invitePath;

		private string joinPath;

		private string writePath;

		private string actionsPath;

		private Sprite noAvatar;

		private bool loading;

		private bool loaded;

		private int seenRevision = -1;

		private float nextApply;

		private float nextButtons;

		private static GameObject tooltipPrefab;

		private const float ButtonMax = 150f;

		private const float ButtonMin = 84f;

		private const float NameMin = 150f;

		private const float ActionsRight = 16f;

		private static readonly Vector3[] corners = (Vector3[])(object)new Vector3[4];

		private GameObject chatPane;

		private TMP_Text chatTitle;

		private TMP_Text chatLines;

		private TMP_InputField chatInput;

		private Friend chatWith;

		private int seenChat = -1;

		internal void Build(SessionPlayerList list)
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Expected O, but got Unknown
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Expected O, but got Unknown
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: 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_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ee: Expected O, but got Unknown
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c6: Expected O, but got Unknown
			//IL_0327: Unknown result type (might be due to invalid IL or missing references)
			//IL_033e: 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_02d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: Expected O, but got Unknown
			//IL_038e: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_056a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0574: Expected O, but got Unknown
			//IL_03f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_040c: Unknown result type (might be due to invalid IL or missing references)
			//IL_041d: Unknown result type (might be due to invalid IL or missing references)
			Traverse val = Traverse.Create((object)list);
			ScrollRect value = val.Field("_scrollRect").GetValue<ScrollRect>();
			Button value2 = val.Field("_backButton").GetValue<Button>();
			SessionPlayerListEntry value3 = val.Field("_ownPlayer").GetValue<SessionPlayerListEntry>();
			if ((Object)(object)value == (Object)null || (Object)(object)value2 == (Object)null || (Object)(object)value3 == (Object)null)
			{
				Plugin.Warn("player list: the window is not as expected (the game changed?): no friends tab");
				return;
			}
			if (Plugin.DebugLog.Value)
			{
				Plugin.Log("player list layout:\n" + Dump(((Component)list).transform, ""));
			}
			RectTransform val2 = (RectTransform)((Component)value).transform.parent;
			RectTransform r = (RectTransform)((Component)value).transform;
			RectTransform val3 = ((!((Object)(object)value.verticalScrollbar != (Object)null) || ((Component)value.verticalScrollbar).transform.IsChildOf(((Component)value).transform)) ? ((RectTransform)null) : ((RectTransform)((Component)value.verticalScrollbar).transform));
			LayoutGroup component = ((Component)val2).GetComponent<LayoutGroup>();
			LayoutElement component2 = ((Component)value).GetComponent<LayoutElement>();
			bool flag = (Object)(object)component != (Object)null && ((Behaviour)component).enabled && ((Object)(object)component2 == (Object)null || !component2.ignoreLayout);
			Rect val4 = LocalRect(r, val2);
			RectTransform strip = (flag ? LayoutRow(val2, "SteamFriends tabs", 46f, ((Component)value).transform.GetSiblingIndex()) : Box("SteamFriends tabs", val2, new Vector2(((Rect)(ref val4)).center.x, ((Rect)(ref val4)).yMax - 23f), new Vector2(((Rect)(ref val4)).width, 46f)));
			if (!flag)
			{
				ShrinkTop(r, 54f);
				if ((Object)(object)val3 != (Object)null)
				{
					ShrinkTop(val3, 54f);
				}
			}
			playersPage.Add(((Component)value).gameObject);
			if ((Object)(object)val3 != (Object)null)
			{
				playersPage.Add(((Component)val3).gameObject);
			}
			GameObject val5 = Object.Instantiate<GameObject>(((Component)value).gameObject, (Transform)(object)val2, false);
			((Object)val5).name = "SteamFriends list";
			val5.transform.SetSiblingIndex(((Component)value).transform.GetSiblingIndex() + 1);
			friendsScroll = val5.GetComponent<ScrollRect>();
			RectTransform content = friendsScroll.content;
			for (int num = ((Transform)content).childCount - 1; num >= 0; num--)
			{
				Object.DestroyImmediate((Object)(object)((Component)((Transform)content).GetChild(num)).gameObject);
			}
			friendsPage.Add(val5);
			if ((Object)(object)val3 != (Object)null)
			{
				GameObject val6 = Object.Instantiate<GameObject>(((Component)val3).gameObject, ((Transform)val3).parent, false);
				((Object)val6).name = "SteamFriends scrollbar";
				friendsScroll.verticalScrollbar = val6.GetComponent<Scrollbar>();
				friendsPage.Add(val6);
				friendsBar = (RectTransform)val6.transform;
				if (!flag)
				{
					ShrinkTop((RectTransform)val6.transform, 50f);
				}
			}
			RectTransform r2 = (RectTransform)val5.transform;
			val4 = LocalRect(r2, val2);
			RectTransform val7;
			if (flag)
			{
				val7 = LayoutRow(val2, "SteamFriends search", 42f, val5.transform.GetSiblingIndex());
			}
			else
			{
				val7 = Box("SteamFriends search", val2, new Vector2(((Rect)(ref val4)).center.x, ((Rect)(ref val4)).yMax - 21f), new Vector2(((Rect)(ref val4)).width, 42f));
				ShrinkTop(r2, 50f);
			}
			friendsPage.Add(((Component)val7).gameObject);
			Plugin.Debug(string.Format("friends tab: built into {0}, list {1}", flag ? "the window's layout group" : "strips over the list", val4));
			BuildSearch(val7, value2);
			Toggle val8 = SettingsToggle();
			if ((Object)(object)val8 != (Object)null)
			{
				val4 = LocalRect(r2, val2);
				RectTransform val9;
				if (flag)
				{
					val9 = LayoutRow(val2, "SteamFriends share", 36f, val5.transform.GetSiblingIndex());
				}
				else
				{
					val9 = Box("SteamFriends share", val2, new Vector2(((Rect)(ref val4)).center.x, ((Rect)(ref val4)).yMax - 18f), new Vector2(((Rect)(ref val4)).width, 36f));
					ShrinkTop(r2, 44f);
					if ((Object)(object)friendsBar != (Object)null)
					{
						ShrinkTop(friendsBar, 44f);
					}
				}
				friendsPage.Add(((Component)val9).gameObject);
				BuildTick(val9, val8, S.ShareWorld, Plugin.ShareWorld, 0f, 0.5f);
				BuildTick(val9, val8, S.NotifyFriends, Plugin.NotifyFriends, 0.5f, 1f);
			}
			Button val10 = TabTemplate();
			if ((Object)(object)val10 == (Object)null)
			{
				val10 = value2;
			}
			tabs[0] = Tab(strip, val10, Texts.Get(S.Players), 0);
			tabs[1] = Tab(strip, val10, Texts.Get(S.SteamFriends), 1);
			PlaceTabs();
			BuildRowTemplate(value3, value2);
			TextMeshProUGUI value4 = val.Field("_headerText").GetValue<TextMeshProUGUI>();
			Texts.Relabel((TMP_Text)(object)value4);
			empty = Text((Transform)(object)content, "SteamFriends empty", (TMP_Text)(object)value4, 22f);
			((Component)empty).gameObject.AddComponent<LayoutElement>().preferredHeight = 60f;
			((Component)empty).gameObject.SetActive(false);
			Select(Mathf.Clamp(Plugin.LastTab.Value, 0, 1), remember: false);
			UiLook.Created((RectTransform)((Component)list).transform);
		}

		private static Button TabTemplate()
		{
			GameObject val = (((Object)(object)Menu.instance != (Object)null) ? Menu.instance.m_settingsPrefab : null);
			TabHandler val2 = (((Object)(object)val != (Object)null) ? val.GetComponentInChildren<TabHandler>(true) : null);
			Button val3 = (((Object)(object)val2 != (Object)null) ? val2.m_tabs.Select((Tab x) => x.m_button).FirstOrDefault((Func<Button, bool>)((Button b) => (Object)(object)b != (Object)null)) : null);
			if ((Object)(object)val3 == (Object)null && (Object)(object)InventoryGui.instance != (Object)null)
			{
				val3 = InventoryGui.instance.m_tabCraft;
			}
			return val3;
		}

		private Button Tab(RectTransform strip, Button template, string label, int index)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			GameObject val = Object.Instantiate<GameObject>(((Component)template).gameObject, (Transform)(object)strip, false);
			((Object)val).name = "SteamFriends tab " + index;
			Strip(val);
			val.SetActive(true);
			Button component = val.GetComponent<Button>();
			component.onClick = new ButtonClickedEvent();
			((UnityEvent)component.onClick).AddListener((UnityAction)delegate
			{
				Select(index, remember: true);
			});
			TMP_Text[] componentsInChildren = val.GetComponentsInChildren<TMP_Text>(true);
			foreach (TMP_Text obj in componentsInChildren)
			{
				obj.text = label;
				obj.textWrappingMode = (TextWrappingModes)0;
			}
			LayoutElement component2 = val.GetComponent<LayoutElement>();
			if ((Object)(object)component2 != (Object)null)
			{
				component2.ignoreLayout = true;
			}
			return component;
		}

		private void PlaceTabs()
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: 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_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: 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_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: 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_00a7: Unknown result type (might be due to invalid IL or missing references)
			float[] array = tabs.Select(delegate(Button b)
			{
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				TMP_Text componentInChildren = ((Component)b).GetComponentInChildren<TMP_Text>(true);
				return Mathf.Max(190f, (((Object)(object)componentInChildren != (Object)null) ? componentInChildren.GetPreferredValues().x : 150f) + 56f);
			}).ToArray();
			float num = (0f - (array.Sum() + 8f)) / 2f;
			Vector2 val2 = default(Vector2);
			for (int num2 = 0; num2 < tabs.Length; num2++)
			{
				RectTransform val = (RectTransform)((Component)tabs[num2]).transform;
				((Vector2)(ref val2))..ctor(0.5f, 0.5f);
				val.pivot = val2;
				Vector2 anchorMin = (val.anchorMax = val2);
				val.anchorMin = anchorMin;
				val.sizeDelta = new Vector2(array[num2], 46f);
				val.anchoredPosition = new Vector2(num + array[num2] / 2f, 0f);
				num += array[num2] + 8f;
			}
		}

		private void Select(int index, bool remember)
		{
			for (int i = 0; i < tabs.Length; i++)
			{
				((Selectable)tabs[i]).interactable = i != index;
				Transform val = ((Component)tabs[i]).transform.Find("Selected");
				if ((Object)(object)val != (Object)null)
				{
					((Component)val).gameObject.SetActive(i == index);
				}
			}
			foreach (GameObject item in playersPage)
			{
				item.SetActive(index == 0);
			}
			foreach (GameObject item2 in friendsPage)
			{
				item2.SetActive(index == 1 && (Object)(object)item2 != (Object)(object)chatPane);
			}
			if (index == 1 && chatWith != null)
			{
				ShowChat(open: true);
			}
			if (remember)
			{
				Plugin.LastTab.Value = index;
			}
			if (index == 1 && !loaded && !loading)
			{
				((MonoBehaviour)this).StartCoroutine(Load());
			}
		}

		private void BuildSearch(RectTransform row, Button back)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: 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_0083: 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_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: 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_0043: 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_004e: Expected O, but got Unknown
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: 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_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			float num = 0f;
			if (Invites.OverlayAvailable)
			{
				overlay = CloneButton(back, (Transform)(object)row, "SteamFriends overlay", Texts.Get(S.InviteWindow));
				ButtonClickedEvent onClick = overlay.onClick;
				object obj = <>O.<0>__OpenOverlay;
				if (obj == null)
				{
					UnityAction val = Invites.OpenOverlay;
					<>O.<0>__OpenOverlay = val;
					obj = (object)val;
				}
				((UnityEvent)onClick).AddListener((UnityAction)obj);
				RectTransform val2 = (RectTransform)((Component)overlay).transform;
				val2.anchorMin = new Vector2(1f, 0f);
				val2.anchorMax = new Vector2(1f, 1f);
				val2.pivot = new Vector2(1f, 0.5f);
				val2.anchoredPosition = Vector2.zero;
				val2.sizeDelta = new Vector2(num = 300f, 0f);
			}
			GuiInputField val3 = (((Object)(object)TextInput.instance != (Object)null) ? TextInput.instance.m_inputField : null);
			if (!((Object)(object)val3 == (Object)null))
			{
				GameObject val4 = Object.Instantiate<GameObject>(((Component)val3).gameObject, (Transform)(object)row, false);
				((Object)val4).name = "SteamFriends search field";
				val4.SetActive(true);
				Strip(val4);
				search = val4.GetComponent<TMP_InputField>();
				Detach((Component)(object)search);
				MenuUi.Fields.Add(search);
				search.text = "";
				search.characterLimit = 40;
				search.lineType = (LineType)0;
				Graphic placeholder = search.placeholder;
				TMP_Text val5 = (TMP_Text)(object)((placeholder is TMP_Text) ? placeholder : null);
				if (val5 != null)
				{
					val5.text = Texts.Get(S.Search);
					((Component)val5).gameObject.SetActive(true);
				}
				((UnityEvent<string>)(object)search.onValueChanged).AddListener((UnityAction<string>)delegate
				{
					Filter();
				});
				RectTransform val6 = (RectTransform)val4.transform;
				val6.anchorMin = Vector2.zero;
				val6.anchorMax = Vector2.one;
				val6.pivot = new Vector2(0f, 0.5f);
				val6.offsetMin = Vector2.zero;
				val6.offsetMax = new Vector2((num > 0f) ? (0f - (num + 8f)) : 0f, 0f);
			}
		}

		private static Toggle SettingsToggle()
		{
			GameObject val = (((Object)(object)Menu.instance != (Object)null) ? Menu.instance.m_settingsPrefab : null);
			GraphicsSettings val2 = (((Object)(object)val != (Object)null) ? val.GetComponentInChildren<GraphicsSettings>(true) : null);
			if (!((Object)(object)val2 != (Object)null))
			{
				return null;
			}
			return Traverse.Create((object)val2).Field("m_vsyncToggle").GetValue<Toggle>();
		}

		private void BuildTick(RectTransform row, Toggle template, S text, ConfigEntry<bool> setting, float from, float to)
		{
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Expected O, but got Unknown
			//IL_029d: 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_02aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02db: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_031a: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(((Component)template).gameObject, (Transform)(object)row, false);
			((Object)val).name = "SteamFriends tick " + text;
			Strip(val);
			MonoBehaviour[] componentsInChildren = val.GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val2 in componentsInChildren)
			{
				if ((Object)(object)val2 != (Object)null && ((object)val2).GetType().Namespace == "Valheim.SettingsGui")
				{
					Object.DestroyImmediate((Object)(object)val2);
				}
			}
			val.SetActive(true);
			Toggle component = val.GetComponent<Toggle>();
			component.onValueChanged = new ToggleEvent();
			component.SetIsOnWithoutNotify(setting.Value);
			((UnityEvent<bool>)(object)component.onValueChanged).AddListener((UnityAction<bool>)delegate(bool v)
			{
				setting.Value = v;
			});
			Transform obj = val.transform.Find("Label");
			TMP_Text val3 = ((obj != null) ? ((Component)obj).GetComponent<TMP_Text>() : null) ?? val.GetComponentInChildren<TMP_Text>(true);
			if ((Object)(object)val3 != (Object)null)
			{
				val3.text = Texts.Get(text);
				val3.textWrappingMode = (TextWrappingModes)0;
				val3.enableAutoSizing = true;
				val3.fontSizeMin = 10f;
				val3.fontSizeMax = Mathf.Max(14f, val3.fontSize);
				val3.overflowMode = (TextOverflowModes)1;
			}
			RectTransform val4 = (((Object)(object)((Selectable)component).targetGraphic != (Object)null) ? ((Selectable)component).targetGraphic.rectTransform : null);
			if ((Object)(object)val4 != (Object)null && (Object)(object)((Transform)val4).parent == (Object)(object)val.transform && (Object)(object)val3 != (Object)null && (Object)(object)val3.transform.parent == (Object)(object)val.transform)
			{
				float[] array = new float[3];
				Rect rect = val4.rect;
				array[0] = ((Rect)(ref rect)).width;
				rect = val4.rect;
				array[1] = ((Rect)(ref rect)).height;
				array[2] = 24f;
				float num = Mathf.Max(array);
				Vector2 val5 = default(Vector2);
				((Vector2)(ref val5))..ctor(1f, 0.5f);
				val4.pivot = val5;
				Vector2 anchorMin = (val4.anchorMax = val5);
				val4.anchorMin = anchorMin;
				val4.anchoredPosition = Vector2.zero;
				RectTransform rectTransform = val3.rectTransform;
				rectTransform.anchorMin = Vector2.zero;
				rectTransform.anchorMax = Vector2.one;
				rectTransform.pivot = new Vector2(0.5f, 0.5f);
				rectTransform.offsetMin = Vector2.zero;
				rectTransform.offsetMax = new Vector2(0f - (num + 8f), 0f);
				val3.alignment = (TextAlignmentOptions)4100;
			}
			LayoutElement component2 = val.GetComponent<LayoutElement>();
			if ((Object)(object)component2 != (Object)null)
			{
				component2.ignoreLayout = true;
			}
			RectTransform val7 = (RectTransform)val.transform;
			val7.anchorMin = new Vector2(from, 0f);
			val7.anchorMax = new Vector2(to, 1f);
			val7.pivot = new Vector2(0.5f, 0.5f);
			val7.offsetMin = new Vector2((from > 0f) ? 4f : 0f, 0f);
			val7.offsetMax = new Vector2((to < 1f) ? (-4f) : 0f, 0f);
		}

		private void BuildRowTemplate(SessionPlayerListEntry own, Button back)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Expected O, but got Unknown
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: Expected O, but got Unknown
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Expected O, but got Unknown
			//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02de: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0311: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("SteamFriends templates", new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(((Component)this).transform, false);
			val.SetActive(false);
			GameObject val2 = Object.Instantiate<GameObject>(((Component)own).gameObject, val.transform, false);
			((Object)val2).name = "SteamFriends friend";
			SessionPlayerListEntry component = val2.GetComponent<SessionPlayerListEntry>();
			Traverse val3 = Traverse.Create((object)component);
			Image value = val3.Field("_gamerpic").GetValue<Image>();
			TMP_Text value2 = val3.Field("_gamertagText").GetValue<TMP_Text>();
			TMP_Text value3 = val3.Field("_characterNameText").GetValue<TMP_Text>();
			TMP_Text value4 = val3.Field("_platformUserIdText").GetValue<TMP_Text>();
			Button value5 = val3.Field("_button").GetValue<Button>();
			noAvatar = val3.Field("otherPlatformPlayerPic").GetValue<Sprite>();
			Image value6 = val3.Field("_selection").GetValue<Image>();
			if ((Object)(object)value6 != (Object)null)
			{
				((Behaviour)value6).enabled = false;
			}
			string[] array = new string[13]
			{
				"_hostIcon", "_outline", "_viewPlayerCard", "_focusPoint", "_reportButton", "_reportButtonImage", "_muteButton", "_muteButtonImage", "_blockButton", "_blockButtonImage",
				"_kickButton", "_kickButtonImage", "m_platformIdentifier"
			};
			foreach (string text in array)
			{
				object value7 = val3.Field(text).GetValue();
				Component val4 = (Component)((value7 is Component) ? value7 : null);
				GameObject val5 = (GameObject)((val4 != null) ? val4.gameObject : ((value7 is GameObject) ? value7 : null));
				if ((Object)(object)val5 != (Object)null && (Object)(object)val5 != (Object)(object)val2)
				{
					val5.SetActive(false);
				}
			}
			if ((Object)(object)value4 != (Object)null)
			{
				((Component)value4).gameObject.SetActive(false);
			}
			Object.DestroyImmediate((Object)(object)component);
			Strip(val2);
			if ((Object)(object)value5 != (Object)null)
			{
				value5.onClick = new ButtonClickedEvent();
			}
			if ((Object)(object)value2 != (Object)null)
			{
				value2.richText = false;
			}
			if ((Object)(object)value3 != (Object)null)
			{
				value3.richText = true;
			}
			TMP_Text[] array2 = (TMP_Text[])(object)new TMP_Text[2] { value2, value3 };
			foreach (TMP_Text val6 in array2)
			{
				if ((Object)(object)val6 != (Object)null)
				{
					val6.textWrappingMode = (TextWrappingModes)0;
					val6.overflowMode = (TextOverflowModes)1;
				}
			}
			GameObject val7 = new GameObject("SteamFriends actions", new Type[1] { typeof(RectTransform) });
			val7.transform.SetParent(val2.transform, false);
			val7.AddComponent<LayoutElement>().ignoreLayout = true;
			RectTransform val8 = (RectTransform)val7.transform;
			Vector2 val9 = default(Vector2);
			((Vector2)(ref val9))..ctor(1f, 0.5f);
			val8.pivot = val9;
			Vector2 anchorMin = (val8.anchorMax = val9);
			val8.anchorMin = anchorMin;
			val8.anchoredPosition = new Vector2(-16f, 0f);
			val8.sizeDelta = new Vector2(500f, 42f);
			HorizontalLayoutGroup obj = val7.AddComponent<HorizontalLayoutGroup>();
			((LayoutGroup)obj).childAlignment = (TextAnchor)5;
			((HorizontalOrVerticalLayoutGroup)obj).spacing = 8f;
			bool childControlWidth = (((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true);
			((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = childControlWidth;
			childControlWidth = (((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false);
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = childControlWidth;
			Button val11 = CloneButton(back, val7.transform, "join", Texts.Get(S.Join));
			LayoutElement obj2 = ((Component)val11).gameObject.AddComponent<LayoutElement>();
			obj2.preferredWidth = 168f;
			obj2.preferredHeight = 42f;
			((Component)val11).gameObject.AddComponent<UITooltip>().m_tooltipPrefab = TooltipPrefab();
			Button val12 = CloneButton(back, val7.transform, "invite", Texts.Get(S.Invite));
			LayoutElement obj3 = ((Component)val12).gameObject.AddComponent<LayoutElement>();
			obj3.preferredWidth = 150f;
			obj3.preferredHeight = 42f;
			((Component)val12).gameObject.AddComponent<UITooltip>().m_tooltipPrefab = TooltipPrefab();
			Button val13 = CloneButto