Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of SteamFriends v0.8.2
plugins/SteamFriends.dll
Decompiled 2 days ago
The result has been truncated due to the large size, download it to view full contents!
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