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 RossPortals v0.2.5
plugins/RossPortals.Core.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using Microsoft.CodeAnalysis; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("RossPortals.Core")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+480bcd6cb67c3266f0fa61828561de272bc5b8f3")] [assembly: AssemblyProduct("RossPortals.Core")] [assembly: AssemblyTitle("RossPortals.Core")] [assembly: AssemblyVersion("1.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 RossPortals.Core { public enum RowKind { Group, Portal } public readonly struct DisplayRow { public RowKind Kind { get; } public int Depth { get; } public string Label { get; } public string GroupPath { get; } public bool Collapsed { get; } public int PortalCount { get; } public string PortalId { get; } public float Distance { get; } private DisplayRow(RowKind kind, int depth, string label, string groupPath, bool collapsed, int portalCount, string portalId, float distance) { Kind = kind; Depth = depth; Label = label; GroupPath = groupPath; Collapsed = collapsed; PortalCount = portalCount; PortalId = portalId; Distance = distance; } public static DisplayRow Group(int depth, string label, string path, bool collapsed, int portalCount) { return new DisplayRow(RowKind.Group, depth, label, path, collapsed, portalCount, null, 0f); } public static DisplayRow Portal(int depth, string label, string portalId, float distance) { return new DisplayRow(RowKind.Portal, depth, label, null, collapsed: false, 0, portalId, distance); } } public readonly struct PortalEntry { public string Id { get; } public string Name { get; } public Vec3 Position { get; } public string TargetId { get; } public bool HasTarget => !string.IsNullOrEmpty(TargetId); public PortalEntry(string id, string name, Vec3 position, string targetId = null) { Id = id; Name = name ?? string.Empty; Position = position; TargetId = targetId; } } public static class PortalListView { private sealed class Node { public string Segment { get; } public string Path { get; } public Dictionary<string, Node> Children { get; } = new Dictionary<string, Node>(StringComparer.OrdinalIgnoreCase); public List<PortalEntry> Leaves { get; } = new List<PortalEntry>(); public Node(string segment, string path) { Segment = segment; Path = path; } public Node Child(string segment, char separator) { if (!Children.TryGetValue(segment, out var value)) { string path = ((Path == null) ? segment : (Path + separator + segment)); value = new Node(segment, path); Children[segment] = value; } return value; } public int CountLeaves() { int num = Leaves.Count; foreach (Node value in Children.Values) { num += value.CountLeaves(); } return num; } } public static IReadOnlyList<DisplayRow> Build(IEnumerable<PortalEntry> portals, char separator, string query, SortMode sort, Vec3 playerPosition, IReadOnlyList<string> recentIds = null, IReadOnlyCollection<string> collapsedGroups = null) { if (portals == null) { throw new ArgumentNullException("portals"); } HashSet<string> collapsed = new HashSet<string>((IEnumerable<string>)(((object)collapsedGroups) ?? ((object)Array.Empty<string>())), StringComparer.Ordinal); Dictionary<string, int> recentIndex = BuildRecentIndex(recentIds ?? Array.Empty<string>()); string value = query?.Trim(); bool flag = !string.IsNullOrEmpty(value); List<PortalEntry> list = new List<PortalEntry>(); foreach (PortalEntry portal in portals) { if (portal.Id != null && (!flag || portal.Name.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0)) { list.Add(portal); } } List<DisplayRow> list2 = new List<DisplayRow>(); if (sort != SortMode.Name) { foreach (PortalEntry item in SortLeaves(list, separator, sort, playerPosition, recentIndex)) { list2.Add(DisplayRow.Portal(0, FlatLabel(item), item.Id, item.Position.DistanceTo(playerPosition))); } return list2; } Node node = new Node(null, null); foreach (PortalEntry item2 in list) { Insert(node, item2, separator); } Emit(node, 0, list2, separator, sort, playerPosition, recentIndex, collapsed); return list2; } private static Dictionary<string, int> BuildRecentIndex(IReadOnlyList<string> recent) { Dictionary<string, int> dictionary = new Dictionary<string, int>(StringComparer.Ordinal); for (int i = 0; i < recent.Count; i++) { if (recent[i] != null && !dictionary.ContainsKey(recent[i])) { dictionary[recent[i]] = i; } } return dictionary; } private static string FlatLabel(PortalEntry portal) { return portal.Name ?? string.Empty; } private static void Insert(Node root, PortalEntry portal, char separator) { IReadOnlyList<string> readOnlyList = PortalName.GroupPath(portal.Name, separator); Node node = root; foreach (string item in readOnlyList) { node = node.Child(item, separator); } node.Leaves.Add(portal); } private static void Emit(Node node, int depth, List<DisplayRow> rows, char separator, SortMode sort, Vec3 player, Dictionary<string, int> recentIndex, HashSet<string> collapsed) { foreach (Node item in node.Children.Values.OrderBy<Node, string>((Node c) => c.Segment, StringComparer.OrdinalIgnoreCase)) { bool flag = collapsed.Contains(item.Path); rows.Add(DisplayRow.Group(depth, item.Segment, item.Path, flag, item.CountLeaves())); if (!flag) { Emit(item, depth + 1, rows, separator, sort, player, recentIndex, collapsed); } } foreach (PortalEntry item2 in SortLeaves(node.Leaves, separator, sort, player, recentIndex)) { rows.Add(DisplayRow.Portal(depth, PortalName.Leaf(item2.Name, separator), item2.Id, item2.Position.DistanceTo(player))); } } private static IEnumerable<PortalEntry> SortLeaves(List<PortalEntry> leaves, char separator, SortMode sort, Vec3 player, Dictionary<string, int> recentIndex) { int value; return sort switch { SortMode.Nearest => leaves.OrderBy((PortalEntry p) => p.Position.DistanceTo(player)).ThenBy<PortalEntry, string>(Label, StringComparer.OrdinalIgnoreCase).ThenBy<PortalEntry, string>((PortalEntry p) => p.Id, StringComparer.Ordinal), SortMode.Recent => leaves.OrderBy((PortalEntry p) => (!recentIndex.TryGetValue(p.Id, out value)) ? int.MaxValue : value).ThenBy<PortalEntry, string>(Label, StringComparer.OrdinalIgnoreCase).ThenBy<PortalEntry, string>((PortalEntry p) => p.Id, StringComparer.Ordinal), _ => leaves.OrderBy<PortalEntry, string>(Label, StringComparer.OrdinalIgnoreCase).ThenBy<PortalEntry, string>((PortalEntry p) => p.Id, StringComparer.Ordinal), }; string Label(PortalEntry p) { return PortalName.Leaf(p.Name, separator); } } } public static class PortalName { public const char DefaultSeparator = '/'; public static IReadOnlyList<string> Segments(string name, char separator) { if (string.IsNullOrWhiteSpace(name)) { return Array.Empty<string>(); } string[] array = name.Split(separator); List<string> list = new List<string>(array.Length); string[] array2 = array; for (int i = 0; i < array2.Length; i++) { string text = array2[i].Trim(); if (text.Length > 0) { list.Add(text); } } return list; } public static string Leaf(string name, char separator) { IReadOnlyList<string> readOnlyList = Segments(name, separator); if (readOnlyList.Count != 0) { return readOnlyList[readOnlyList.Count - 1]; } return string.Empty; } public static IReadOnlyList<string> GroupPath(string name, char separator) { IReadOnlyList<string> readOnlyList = Segments(name, separator); if (readOnlyList.Count <= 1) { return Array.Empty<string>(); } List<string> list = new List<string>(readOnlyList.Count - 1); for (int i = 0; i < readOnlyList.Count - 1; i++) { list.Add(readOnlyList[i]); } return list; } } public enum SortMode { Name, Nearest, Recent } public readonly struct Vec3 { public float X { get; } public float Y { get; } public float Z { get; } public Vec3(float x, float y, float z) { X = x; Y = y; Z = z; } public float DistanceTo(Vec3 other) { float num = X - other.X; float num2 = Y - other.Y; float num3 = Z - other.Z; return (float)Math.Sqrt(num * num + num2 * num2 + num3 * num3); } } }
plugins/RossPortals.dll
Decompiled a day agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using RossPortals.Core; using RossPortals.Game.Framework; using RossPortals.Game.Portals; using RossPortals.Game.UI; using Splatform; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("assembly_valheim")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("RossPortals")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.2.0.0")] [assembly: AssemblyInformationalVersion("0.2.0+480bcd6cb67c3266f0fa61828561de272bc5b8f3")] [assembly: AssemblyProduct("RossPortals")] [assembly: AssemblyTitle("RossPortals")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.2.0.0")] [module: UnverifiableCode] [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 RossPortals.Game { internal static class ModInfo { public const string Guid = "com.rossdwest.rossportals"; public const string Name = "RossPortals"; public const string Version = "0.2.5"; public const string XPortalGuid = "yay.spikehimself.xportal"; public const string KeyTarget = "RossPortals_TargetId"; public const string KeyPrevious = "RossPortals_PreviousId"; public const string LegacyKeyTarget = "XPortal_TargetId"; public const string LegacyKeyPrevious = "XPortal_PreviousId"; public const string KeyDefault = "RossPortals_Default"; public const string KeyShowOnMap = "RossPortals_ShowOnMap"; public const string RpcResync = "RossPortals_Resync"; public const string RpcSyncPortal = "RossPortals_SyncPortal"; public const string RpcSyncRequest = "RossPortals_SyncRequest"; public const string RpcAddOrUpdate = "RossPortals_AddOrUpdate"; public const string RpcRemove = "RossPortals_Remove"; } [BepInPlugin("com.rossdwest.rossportals", "RossPortals", "0.2.5")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInIncompatibility("yay.spikehimself.xportal")] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public class RossPortalsPlugin : BaseUnityPlugin { internal static ManualLogSource Log; private Harmony _harmony; private void Awake() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown //IL_0041: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; _harmony = new Harmony("com.rossdwest.rossportals"); ValheimCompat.Verify(); PatchEachClassIndividually(); PortalConfig.Bind(((BaseUnityPlugin)this).Config); GameObject val = new GameObject("RossPortalsManager"); Object.DontDestroyOnLoad((Object)val); val.transform.SetParent(((Component)this).gameObject.transform); val.AddComponent<Scheduler>(); if (!GUIManager.IsHeadless()) { new PortalConfigPanel(); } MinimapManager.OnVanillaMapDataLoaded += PortalManager.RequestInitialSync; Log.LogInfo((object)"RossPortals 0.2.5 loaded"); } private void Update() { if (!Env.IsHeadless) { PortalConfigPanel.Instance?.HandleInput(); } } private void OnDestroy() { MinimapManager.OnVanillaMapDataLoaded -= PortalManager.RequestInitialSync; PortalConfigPanel.Instance?.Dispose(); Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private void PatchEachClassIndividually() { List<string> list = new List<string>(); try { Type[] typesFromAssembly = AccessTools.GetTypesFromAssembly(Assembly.GetExecutingAssembly()); foreach (Type type in typesFromAssembly) { if (type.GetCustomAttributes(typeof(HarmonyPatch), inherit: false).Length == 0) { continue; } try { List<MethodInfo> list2 = _harmony.CreateClassProcessor(type).Patch(); if (list2 == null || list2.Count == 0) { list.Add(type.Name + "=SKIPPED(Prepare() false or no target)"); continue; } foreach (MethodInfo item in list2) { list.Add(item.DeclaringType?.Name + "." + item.Name + "=OK(via " + type.Name + ")"); } } catch (Exception ex) { list.Add(type.Name + "=FAILED(" + ex.GetType().Name + ")"); Log.LogError((object)$"Harmony patch '{type.FullName}' failed to apply; continuing without it: {ex}"); } } } catch (Exception ex2) { list.Add("enumeration=FAILED(" + ex2.GetType().Name + ")"); Log.LogError((object)$"Harmony patching failed unexpectedly; continuing without the affected patch(es): {ex2}"); } Log.LogInfo((object)("RossPortals Harmony patches: " + string.Join("; ", list))); } } } namespace RossPortals.Game.UI { internal sealed class PortalConfigPanel { private readonly struct SelectableRow { public readonly Button Button; public readonly Text Label; public readonly string Key; public SelectableRow(Button button, Text label, string key) { Button = button; Label = label; Key = key; } } private const float PanelWidth = 640f; private const float PanelHeight = 600f; private const float RowHeight = 30f; private GameObject _panel; private InputField _nameField; private InputField _searchField; private Text _destinationText; private Toggle _defaultToggle; private Toggle _showMapToggle; private RectTransform _content; private Font _font; private readonly Dictionary<SortMode, Text> _sortLabels = new Dictionary<SortMode, Text>(); private bool _built; private PortalRecord _portal; private string _selectedKey; private SortMode _sort; private readonly HashSet<string> _collapsed = new HashSet<string>(); private List<DisplayRow> _lastRows; private readonly List<SelectableRow> _selectableRows = new List<SelectableRow>(); public static PortalConfigPanel Instance { get; private set; } public bool IsOpen { get { if ((Object)(object)_panel != (Object)null) { return _panel.activeSelf; } return false; } } public PortalConfigPanel() { Instance = this; GUIManager.OnCustomGUIAvailable += OnGuiRecreated; } private void OnGuiRecreated() { _built = false; _panel = null; _portal = null; _sortLabels.Clear(); _selectableRows.Clear(); _lastRows = null; } public void Open(PortalRecord portal) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) if (!Env.IsHeadless && EnsureBuilt()) { PortalManager.RefreshList(); _portal = portal; _selectedKey = (portal.HasTarget ? PortalKey.Of(portal.Target) : null); _nameField.text = portal.Name ?? string.Empty; _searchField.text = string.Empty; _defaultToggle.isOn = portal.IsDefault; _showMapToggle.isOn = portal.ShowOnMap; _panel.SetActive(true); GUIManager.BlockInput(true); _lastRows = null; Rebuild(); Scheduler.Instance?.NextFrame(delegate { _searchField.ActivateInputField(); }); } } public void Close() { if ((Object)(object)_panel != (Object)null) { _panel.SetActive(false); } GUIManager.BlockInput(false); _portal = null; } public void HandleInput() { if (IsOpen && Input.GetKeyDown((KeyCode)27)) { Close(); } } public void OnRegistryChanged() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (IsOpen && _portal != null) { _portal = PortalRegistry.Instance.GetById(_portal.Id) ?? _portal; Rebuild(); } } public void Dispose() { GUIManager.OnCustomGUIAvailable -= OnGuiRecreated; if ((Object)(object)_panel != (Object)null) { Object.Destroy((Object)(object)_panel); } _panel = null; _built = false; if (Instance == this) { Instance = null; } } private bool EnsureBuilt() { //IL_00a0: 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_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00de: 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_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_011f: 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_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: 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_0207: 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_0215: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Unknown result type (might be due to invalid IL or missing references) //IL_0261: 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_0290: Expected O, but got Unknown //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_02c5: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Unknown result type (might be due to invalid IL or missing references) //IL_02ee: Unknown result type (might be due to invalid IL or missing references) //IL_0340: Unknown result type (might be due to invalid IL or missing references) //IL_034a: Expected O, but got Unknown //IL_035f: Unknown result type (might be due to invalid IL or missing references) //IL_0360: Unknown result type (might be due to invalid IL or missing references) //IL_036b: Unknown result type (might be due to invalid IL or missing references) //IL_0390: Unknown result type (might be due to invalid IL or missing references) //IL_039a: Expected O, but got Unknown //IL_03af: Unknown result type (might be due to invalid IL or missing references) //IL_03b0: Unknown result type (might be due to invalid IL or missing references) //IL_03bb: Unknown result type (might be due to invalid IL or missing references) //IL_03e0: Unknown result type (might be due to invalid IL or missing references) //IL_03ea: Expected O, but got Unknown if (_built && (Object)(object)_panel != (Object)null) { return true; } if (GUIManager.Instance == null || (Object)(object)GUIManager.CustomGUIFront == (Object)null) { RossPortalsPlugin.Log.LogWarning((object)"GUI not ready; cannot open the portal panel yet."); return false; } _built = false; _sortLabels.Clear(); _selectableRows.Clear(); Font val = (_font = GUIManager.Instance.AveriaSerifBold); Transform transform = GUIManager.CustomGUIFront.transform; Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(0.5f, 0.5f); Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(0.5f, 1f); _panel = GUIManager.Instance.CreateWoodpanel(transform, val2, val2, Vector2.zero, 640f, 600f, false); _panel.SetActive(false); GUIManager.Instance.CreateText("Configure Portal", _panel.transform, val3, val3, new Vector2(0f, -28f), val, 24, Color.white, true, Color.black, 600f, 34f, false); _nameField = GUIManager.Instance.CreateInputField(_panel.transform, val3, val3, new Vector2(0f, -74f), (ContentType)0, "Portal name", 18, 580f, 36f).GetComponent<InputField>(); _searchField = GUIManager.Instance.CreateInputField(_panel.transform, val3, val3, new Vector2(0f, -118f), (ContentType)0, "Search portals...", 18, 580f, 34f).GetComponent<InputField>(); ((UnityEvent<string>)(object)_searchField.onValueChanged).AddListener((UnityAction<string>)delegate { Rebuild(); }); CreateSortButton((SortMode)0, "Name", -160f, val); CreateSortButton((SortMode)1, "Nearest", 0f, val); CreateSortButton((SortMode)2, "Recent", 160f, val); _destinationText = GUIManager.Instance.CreateText(string.Empty, _panel.transform, val3, val3, new Vector2(-110f, -198f), val, 18, Color.white, true, Color.black, 360f, 30f, false).GetComponent<Text>(); _destinationText.alignment = (TextAnchor)3; ((UnityEvent)GUIManager.Instance.CreateButton("Clear", _panel.transform, val3, val3, new Vector2(210f, -198f), 110f, 30f).GetComponent<Button>().onClick).AddListener((UnityAction)delegate { Select(null); }); GameObject obj = GUIManager.Instance.CreateScrollView(_panel.transform, false, true, 12f, 6f, HandleColors(), new Color(0f, 0f, 0f, 0.6f), 590f, 300f); ((RectTransform)obj.transform).anchoredPosition = new Vector2(0f, -85f); ScrollRect componentInChildren = obj.GetComponentInChildren<ScrollRect>(); _content = componentInChildren.content; componentInChildren.scrollSensitivity = 400f; VerticalLayoutGroup component = ((Component)_content).GetComponent<VerticalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)component).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)component).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)component).spacing = 2f; ((LayoutGroup)component).padding = new RectOffset(6, 6, 6, 6); ((UnityEvent)GUIManager.Instance.CreateButton("OK", _panel.transform, val3, val3, new Vector2(225f, -566f), 130f, 40f).GetComponent<Button>().onClick).AddListener(new UnityAction(Submit)); ((UnityEvent)GUIManager.Instance.CreateButton("Cancel", _panel.transform, val3, val3, new Vector2(81f, -566f), 130f, 40f).GetComponent<Button>().onClick).AddListener(new UnityAction(Close)); _defaultToggle = CreateCheckbox("Default", -278f, -566f, 70f); _showMapToggle = CreateCheckbox("Show on map", -150f, -566f, 130f); _built = true; return true; } private Toggle CreateCheckbox(string label, float x, float y, float labelWidth) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0061: 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_009f: 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_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(0.5f, 1f); GameObject val2 = GUIManager.Instance.CreateToggle(_panel.transform, 24f, 24f); RectTransform val3 = (RectTransform)val2.transform; val3.anchorMin = val; val3.anchorMax = val; val3.pivot = new Vector2(0.5f, 0.5f); val3.anchoredPosition = new Vector2(x, y); Text[] componentsInChildren = val2.GetComponentsInChildren<Text>(); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].text = string.Empty; } Text component = GUIManager.Instance.CreateText(label, _panel.transform, val, val, new Vector2(x + 18f + labelWidth / 2f, y), _font, 16, Color.white, true, Color.black, labelWidth, 24f, false).GetComponent<Text>(); component.alignment = (TextAnchor)3; ((Graphic)component).raycastTarget = false; return val2.GetComponent<Toggle>(); } private void CreateSortButton(SortMode mode, string token, float x, Font font) { //IL_000e: 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_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003e: 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_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown //IL_0081: Unknown result type (might be due to invalid IL or missing references) GameObject val = GUIManager.Instance.CreateButton(token, _panel.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(x, -156f), 150f, 30f); ((UnityEvent)val.GetComponent<Button>().onClick).AddListener((UnityAction)delegate { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) _sort = mode; Rebuild(); }); _sortLabels[mode] = val.GetComponentInChildren<Text>(); } private static ColorBlock HandleColors() { //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_001c: Unknown result type (might be due to invalid IL or missing references) //IL_003c: 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_0072: Unknown result type (might be due to invalid IL or missing references) ColorBlock defaultColorBlock = ColorBlock.defaultColorBlock; ((ColorBlock)(ref defaultColorBlock)).normalColor = new Color(0.35f, 0.35f, 0.35f, 1f); ((ColorBlock)(ref defaultColorBlock)).highlightedColor = new Color(0.5f, 0.5f, 0.5f, 1f); ((ColorBlock)(ref defaultColorBlock)).pressedColor = new Color(0.6f, 0.6f, 0.6f, 1f); ((ColorBlock)(ref defaultColorBlock)).colorMultiplier = 1f; return defaultColorBlock; } private void Rebuild() { //IL_002f: 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) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0040: 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_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006c: 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_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0141: 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_0181: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Expected O, but got Unknown //IL_019a: 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_01a2: Unknown result type (might be due to invalid IL or missing references) if (!_built || _portal == null) { return; } Vector3 val = (((Object)(object)Player.m_localPlayer != (Object)null) ? ((Component)Player.m_localPlayer).transform.position : Vector3.zero); IReadOnlyList<DisplayRow> readOnlyList = PortalListView.Build((IEnumerable<PortalEntry>)PortalRegistry.Instance.BuildEntries(_portal.Id), PortalConfig.Separator, _searchField.text, _sort, new Vec3(val.x, val.y, val.z), PortalManager.RecentKeys, (IReadOnlyCollection<string>)_collapsed); if (_lastRows != null && ((Transform)_content).childCount > 0 && RowsEqual(_lastRows, readOnlyList)) { return; } _lastRows = new List<DisplayRow>(readOnlyList); for (int num = ((Transform)_content).childCount - 1; num >= 0; num--) { Object.DestroyImmediate((Object)(object)((Component)((Transform)_content).GetChild(num)).gameObject); } _selectableRows.Clear(); _destinationText.text = "Destination: " + SelectedName(); foreach (KeyValuePair<SortMode, Text> sortLabel in _sortLabels) { ((Graphic)sortLabel.Value).color = ((sortLabel.Key == _sort) ? Color.yellow : Color.white); } BuildRow("(no destination)", "", 0, isGroup: false, _selectedKey == null, (UnityAction)delegate { Select(null); }, null, selectable: true); foreach (DisplayRow item in readOnlyList) { AddRow(item); } } private static bool RowsEqual(IReadOnlyList<DisplayRow> a, IReadOnlyList<DisplayRow> b) { //IL_0019: 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) //IL_0021: 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_0029: 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) if (a.Count != b.Count) { return false; } for (int i = 0; i < a.Count; i++) { DisplayRow val = a[i]; DisplayRow val2 = b[i]; if (((DisplayRow)(ref val)).Kind != ((DisplayRow)(ref val2)).Kind || ((DisplayRow)(ref val)).Depth != ((DisplayRow)(ref val2)).Depth || ((DisplayRow)(ref val)).Label != ((DisplayRow)(ref val2)).Label || ((DisplayRow)(ref val)).GroupPath != ((DisplayRow)(ref val2)).GroupPath || ((DisplayRow)(ref val)).Collapsed != ((DisplayRow)(ref val2)).Collapsed || ((DisplayRow)(ref val)).PortalCount != ((DisplayRow)(ref val2)).PortalCount || ((DisplayRow)(ref val)).PortalId != ((DisplayRow)(ref val2)).PortalId || FormatDistance(((DisplayRow)(ref val)).Distance) != FormatDistance(((DisplayRow)(ref val2)).Distance)) { return false; } } return true; } private void AddRow(DisplayRow row) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown if ((int)((DisplayRow)(ref row)).Kind == 0) { string arrow = (((DisplayRow)(ref row)).Collapsed ? "▶" : "▼"); string path = ((DisplayRow)(ref row)).GroupPath; BuildRow(((DisplayRow)(ref row)).Label, ((DisplayRow)(ref row)).PortalCount.ToString(), ((DisplayRow)(ref row)).Depth, isGroup: true, selected: false, (UnityAction)delegate { if (!_collapsed.Remove(path)) { _collapsed.Add(path); } Rebuild(); }, arrow); } else { string label = (string.IsNullOrEmpty(((DisplayRow)(ref row)).Label) ? "(no name)" : ((DisplayRow)(ref row)).Label); bool selected = ((DisplayRow)(ref row)).PortalId == _selectedKey; string key = ((DisplayRow)(ref row)).PortalId; BuildRow(label, FormatDistance(((DisplayRow)(ref row)).Distance), ((DisplayRow)(ref row)).Depth, isGroup: false, selected, (UnityAction)delegate { Select(key); }, null, selectable: true, key); } } private void BuildRow(string label, string trailer, int depth, bool isGroup, bool selected, UnityAction onClick, string arrow = null, bool selectable = false, string key = null) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_0052: 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_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: 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_00fe: 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) GameObject val = new GameObject("row", new Type[3] { typeof(RectTransform), typeof(Image), typeof(Button) }); val.transform.SetParent((Transform)(object)_content, false); Image component = val.GetComponent<Image>(); ((Graphic)component).color = Color.white; Button component2 = val.GetComponent<Button>(); ((Selectable)component2).targetGraphic = (Graphic)(object)component; ((Selectable)component2).transition = (Transition)1; ColorBlock val2 = (((Selectable)component2).colors = RowColors(isGroup, selected)); ((Behaviour)component2).enabled = false; ((Behaviour)component2).enabled = true; ((Graphic)component).canvasRenderer.SetColor(((ColorBlock)(ref val2)).normalColor); ((UnityEvent)component2.onClick).AddListener(onClick); LayoutElement obj = val.AddComponent<LayoutElement>(); obj.minHeight = 30f; obj.preferredHeight = 30f; obj.flexibleWidth = 1f; Color color = RowTextColor(isGroup, selected); float num = 12f + (float)depth * 22f; if (arrow != null) { AddLabel(val.transform, arrow, (TextAnchor)3, color, num, 60f, 11); num += 14f; } Text label2 = AddLabel(val.transform, label, (TextAnchor)3, color, num, 60f); if (!string.IsNullOrEmpty(trailer)) { AddLabel(val.transform, trailer, (TextAnchor)5, new Color(0.65f, 0.65f, 0.62f), 8f, 10f); } if (selectable) { _selectableRows.Add(new SelectableRow(component2, label2, key)); } } private Text AddLabel(Transform parent, string text, TextAnchor anchor, Color color, float leftPad, float rightPad, int fontSize = 17) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_004b: 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) //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_0066: 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_0080: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: 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_00e2: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("label", new Type[3] { typeof(RectTransform), typeof(Text), typeof(Outline) }); val.transform.SetParent(parent, false); RectTransform val2 = (RectTransform)val.transform; val2.anchorMin = Vector2.zero; val2.anchorMax = Vector2.one; val2.offsetMin = new Vector2(leftPad, 0f); val2.offsetMax = new Vector2(0f - rightPad, 0f); Text component = val.GetComponent<Text>(); component.font = _font; component.fontSize = fontSize; ((Graphic)component).color = color; component.alignment = anchor; component.horizontalOverflow = (HorizontalWrapMode)1; component.verticalOverflow = (VerticalWrapMode)0; component.text = text; ((Shadow)val.GetComponent<Outline>()).effectColor = new Color(0f, 0f, 0f, 0.6f); return component; } private static ColorBlock RowColors(bool isGroup, bool selected) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0056: 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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) Color val = (selected ? new Color(0.85f, 0.7f, 0.2f, 0.3f) : (isGroup ? new Color(1f, 1f, 1f, 0.1f) : new Color(1f, 1f, 1f, 0.02f))); ColorBlock defaultColorBlock = ColorBlock.defaultColorBlock; ((ColorBlock)(ref defaultColorBlock)).normalColor = val; ((ColorBlock)(ref defaultColorBlock)).highlightedColor = new Color(1f, 1f, 1f, 0.16f); ((ColorBlock)(ref defaultColorBlock)).pressedColor = new Color(1f, 1f, 1f, 0.24f); ((ColorBlock)(ref defaultColorBlock)).selectedColor = val; ((ColorBlock)(ref defaultColorBlock)).colorMultiplier = 1f; ((ColorBlock)(ref defaultColorBlock)).fadeDuration = 0.08f; return defaultColorBlock; } private void Select(string key) { //IL_0051: 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) _selectedKey = key; _destinationText.text = "Destination: " + SelectedName(); foreach (SelectableRow selectableRow in _selectableRows) { bool selected = selectableRow.Key == _selectedKey; ((Selectable)selectableRow.Button).colors = RowColors(isGroup: false, selected); ((Graphic)selectableRow.Label).color = RowTextColor(isGroup: false, selected); } } private static Color RowTextColor(bool isGroup, bool selected) { //IL_003f: 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_0015: Unknown result type (might be due to invalid IL or missing references) if (!selected) { if (!isGroup) { return new Color(0.92f, 0.9f, 0.85f); } return new Color(0.85f, 0.9f, 1f); } return new Color(1f, 0.86f, 0.4f); } private void Submit() { //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_003a: 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) ZDOID newTarget = ZDOID.None; if (_selectedKey != null) { PortalRecord byKey = PortalRegistry.Instance.GetByKey(_selectedKey); if (byKey != null) { newTarget = byKey.Id; } } PortalManager.SubmitPortalConfig(_portal, _nameField.text, newTarget, _defaultToggle.isOn, _showMapToggle.isOn); Close(); } private string SelectedName() { if (_selectedKey == null) { return "(none)"; } PortalRecord byKey = PortalRegistry.Instance.GetByKey(_selectedKey); if (byKey == null) { return "(none)"; } if (!string.IsNullOrEmpty(byKey.Name)) { return byKey.Name; } return "(no name)"; } private static string FormatDistance(float metres) { if (metres >= 1000f) { return $"{metres / 1000f:0.0} km"; } return $"{(int)metres} m"; } } } namespace RossPortals.Game.Portals { internal static class Env { public static bool IsServer { get { if ((Object)(object)ZNet.instance != (Object)null) { return ZNet.instance.IsServer(); } return false; } } public static bool IsHeadless => GUIManager.IsHeadless(); public static bool GameStarted { get; set; } public static bool ShuttingDown { get { if ((Object)(object)Game.instance != (Object)null) { return Game.instance.m_shuttingDown; } return false; } } public static long ServerPeerId => ZRoutedRpc.instance.GetServerPeerID(); } internal static class MapPins { private const PinType PinType = (PinType)6; private static readonly Dictionary<string, PinData> _pins = new Dictionary<string, PinData>(); public static void Refresh() { //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) if (Env.IsHeadless || (Object)(object)Minimap.instance == (Object)null) { return; } HashSet<string> seen = new HashSet<string>(); foreach (PortalRecord item in PortalRegistry.Instance.GetList()) { if (!item.ShowOnMap) { continue; } string key = item.Key; seen.Add(key); string text = (string.IsNullOrEmpty(item.Name) ? "Portal" : item.Name); if (_pins.TryGetValue(key, out var value)) { if (value.m_pos == item.Location && value.m_name == text) { continue; } Minimap.instance.RemovePin(value); } _pins[key] = Minimap.instance.AddPin(item.Location, (PinType)6, text, false, false, 0L, default(PlatformUserID)); } foreach (string item2 in _pins.Keys.Where((string k) => !seen.Contains(k)).ToList()) { Minimap.instance.RemovePin(_pins[item2]); _pins.Remove(item2); } } public static void Clear() { if ((Object)(object)Minimap.instance != (Object)null) { foreach (PinData value in _pins.Values) { Minimap.instance.RemovePin(value); } } _pins.Clear(); } } internal static class PortalConfig { private static ConfigEntry<string> _separator; public static char Separator { get { string text = _separator?.Value; if (!string.IsNullOrEmpty(text)) { return text[0]; } return '/'; } } public static void Bind(ConfigFile config) { _separator = config.Bind<string>("Grouping", "FolderSeparator", "/", "The character in a portal's name that starts a folder. \"Mines/Copper\" puts portal \"Copper\" in folder \"Mines\". Client-side; affects only how your own list is grouped."); } } internal static class PortalKey { public unsafe static string Of(ZDOID id) { return ((object)(*(ZDOID*)(&id))/*cast due to .constrained prefix*/).ToString(); } } internal static class PortalManager { private const int RecentCap = 30; private static readonly List<string> _recent = new List<string>(); public static IReadOnlyList<string> RecentKeys => _recent; public static void OnGameStarted() { PortalRegistry.Instance.Reset(); MapPins.Clear(); PortalRpc.Register(); } public static void RequestInitialSync() { PlayerProfile val = (((Object)(object)Game.instance != (Object)null) ? Game.instance.GetPlayerProfile() : null); PortalRpc.RequestSync(((val != null) ? val.GetName() : "a player") + " joined"); } public static void RefreshList() { PortalRpc.RequestSync("panel opened"); } public static void ProcessSyncRequest(string reason) { List<ZDO> portalList = ZDOMan.instance.GetPortalList(); PortalRegistry.Instance.ApplyPortalZdos(portalList); RossPortalsPlugin.Log.LogInfo((object)$"Portal sync ({reason}): server sees {portalList.Count} portal(s); broadcasting."); PortalRpc.BroadcastResync(PortalRegistry.Instance.Pack(), reason); } public static void ServerAddOrUpdate(PortalRecord record) { //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: 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_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) PortalRecord portalRecord = PortalRegistry.Instance.AddOrUpdate(record); WriteWithRetry(portalRecord, 5); PortalRpc.BroadcastPortal(portalRecord); if (portalRecord.IsDefault) { foreach (PortalRecord item in PortalRegistry.Instance.GetList()) { if (!(item.Id == portalRecord.Id) && item.IsDefault) { item.IsDefault = false; PortalZdo.Write(item); PortalRpc.BroadcastPortal(item); } } } if (portalRecord.HasTarget) { PortalRecord byId = PortalRegistry.Instance.GetById(portalRecord.Target); if (byId != null && !byId.HasTarget) { byId.Target = portalRecord.Id; ServerAddOrUpdate(byId); } } } public static void ServerRemove(ZDOID id) { //IL_0005: 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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) if (!PortalRegistry.Instance.Remove(id)) { return; } foreach (PortalRecord item in PortalRegistry.Instance.GetPortalsWithTarget(id)) { item.Target = ZDOID.None; ServerAddOrUpdate(item); } PortalRpc.BroadcastResync(PortalRegistry.Instance.Pack(), "portal removed"); } private static void WriteWithRetry(PortalRecord record, int attempts) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) if (ZDOMan.instance.GetZDO(record.Id) != null) { PortalZdo.Write(record); return; } if (attempts <= 0 || (Object)(object)Scheduler.Instance == (Object)null) { RossPortalsPlugin.Log.LogWarning((object)$"Portal ZDO {record.Id} never materialised; name/target not persisted."); return; } Scheduler.Instance.AfterFrames(3, delegate { WriteWithRetry(record, attempts - 1); }); } public static void OnPortalPlaced(ZDOID id, Vector3 location) { //IL_0005: 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_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: 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) ZDOMan.instance.ForceSendZDO(id); ZDOID target = ResolveDefaultTarget(id); PortalRpc.RequestAddOrUpdate(new PortalRecord(id) { Location = location, Target = target }); } public static void OnPortalDestroyed(ZDOID id) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) PortalRpc.RequestRemove(id); } public static string BuildHoverText(ZDOID id, Vector3 location) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) PortalRecord obj = PortalRegistry.Instance.GetById(id) ?? Adopt(id, location); string text = FriendlyName(obj.Name); string text2 = FriendlyTarget(obj); return Localization.instance.Localize("Name: " + text + "\nDestination: " + text2 + "\n[<color=yellow><b>$KEY_Use</b></color>] Configure"); } public static void OnPortalInteract(ZDOID id) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) if (!Env.IsHeadless && PortalConfigPanel.Instance != null) { ZDO zDO = ZDOMan.instance.GetZDO(id); PortalRecord portal = PortalRegistry.Instance.GetById(id) ?? Adopt(id, (zDO != null) ? zDO.GetPosition() : Vector3.zero); PortalConfigPanel.Instance.Open(portal); } } public static void SubmitPortalConfig(PortalRecord portal, string newName, ZDOID newTarget, bool isDefault, bool showOnMap) { //IL_0042: 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_0019: 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 (newName == null) { newName = string.Empty; } if (!(portal.Name == newName) || !(portal.Target == newTarget) || portal.IsDefault != isDefault || portal.ShowOnMap != showOnMap) { portal.Name = newName; portal.Target = newTarget; portal.IsDefault = isDefault; portal.ShowOnMap = showOnMap; PortalRpc.RequestAddOrUpdate(portal); } } public static void RecordUsed(ZDOID target) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) if (!(target == ZDOID.None)) { string item = PortalKey.Of(target); _recent.Remove(item); _recent.Insert(0, item); if (_recent.Count > 30) { _recent.RemoveRange(30, _recent.Count - 30); } } } public static void NotifyListChanged() { if (!Env.IsHeadless) { PortalConfigPanel.Instance?.OnRegistryChanged(); MapPins.Refresh(); } } public static ZDOID ResolveDefaultTarget(ZDOID excludeId) { //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_0052: 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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) foreach (PortalRecord item in PortalRegistry.Instance.GetList()) { if (item.IsDefault && item.Id != excludeId) { return item.Id; } } return ZDOID.None; } private static PortalRecord Adopt(ZDOID id, Vector3 location) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000c: 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_0014: 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_003c: 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) ZDO zDO = ZDOMan.instance.GetZDO(id); PortalRecord portalRecord = new PortalRecord(id) { Location = location, Name = ((zDO != null) ? (PortalZdo.GetName(zDO) ?? string.Empty) : string.Empty), Target = ((zDO != null) ? PortalZdo.GetTarget(zDO) : ZDOID.None) }; PortalRegistry.Instance.AddOrUpdate(portalRecord); PortalRpc.RequestSync("adopted an unknown portal"); return portalRecord; } private static string FriendlyName(string name) { if (!string.IsNullOrEmpty(name)) { return name; } return "(no name)"; } private static string FriendlyTarget(PortalRecord portal) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) if (!portal.HasTarget) { return "(none)"; } PortalRecord byId = PortalRegistry.Instance.GetById(portal.Target); if (byId == null) { return "(none)"; } return FriendlyName(byId.Name); } } internal sealed class PortalRecord { public ZDOID Id; public string Name; public Vector3 Location; public ZDOID Target; public bool IsDefault; public bool ShowOnMap = true; public bool HasTarget { get { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) if (Target != ZDOID.None) { return !((ZDOID)(ref Target)).IsNone(); } return false; } } public string Key => PortalKey.Of(Id); public PortalRecord(ZDOID id) { //IL_000e: 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_0020: 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_0030: Unknown result type (might be due to invalid IL or missing references) Id = id; Name = string.Empty; Location = Vector3.zero; Target = ZDOID.None; } public PortalEntry ToCore() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003e: 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) return new PortalEntry(Key, Name, new Vec3(Location.x, Location.y, Location.z), HasTarget ? PortalKey.Of(Target) : null); } public ZPackage Pack() { //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_0007: 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_0026: 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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(Id); val.Write(Name ?? string.Empty); val.Write(Location); val.Write(Target); val.Write(IsDefault); val.Write(ShowOnMap); return val; } public static PortalRecord FromPackage(ZPackage pkg) { //IL_0001: 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_001e: 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) return new PortalRecord(pkg.ReadZDOID()) { Name = pkg.ReadString(), Location = pkg.ReadVector3(), Target = pkg.ReadZDOID(), IsDefault = pkg.ReadBool(), ShowOnMap = pkg.ReadBool() }; } } internal sealed class PortalRegistry { private readonly Dictionary<ZDOID, PortalRecord> _portals = new Dictionary<ZDOID, PortalRecord>(); public static PortalRegistry Instance { get; } = new PortalRegistry(); public int Count => _portals.Count; private PortalRegistry() { } public bool Contains(ZDOID id) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return _portals.ContainsKey(id); } public PortalRecord GetById(ZDOID id) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) if (!_portals.TryGetValue(id, out var value)) { return null; } return value; } public PortalRecord GetByKey(string key) { if (key != null) { return _portals.Values.FirstOrDefault((PortalRecord p) => p.Key == key); } return null; } public List<PortalRecord> GetList() { return _portals.Values.ToList(); } public List<PortalRecord> GetPortalsWithTarget(ZDOID target) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) return _portals.Values.Where((PortalRecord p) => p.Target == target).ToList(); } public PortalRecord AddOrUpdate(PortalRecord portal) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) _portals[portal.Id] = portal; return portal; } public bool Remove(ZDOID id) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return _portals.Remove(id); } public void Reset() { _portals.Clear(); } public IReadOnlyList<PortalEntry> BuildEntries(ZDOID exclude) { //IL_002d: 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_003c: Unknown result type (might be due to invalid IL or missing references) List<PortalEntry> list = new List<PortalEntry>(_portals.Count); foreach (PortalRecord value in _portals.Values) { if (!(value.Id == exclude)) { list.Add(value.ToCore()); } } return list; } public ZPackage Pack() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown List<PortalRecord> list = GetList(); ZPackage val = new ZPackage(); val.Write(list.Count); foreach (PortalRecord item in list) { val.Write(item.Pack()); } return val; } public void ApplyResync(ZPackage pkg) { int num = pkg.ReadInt(); List<PortalRecord> list = new List<PortalRecord>(num); for (int i = 0; i < num; i++) { list.Add(PortalRecord.FromPackage(pkg.ReadPackage())); } ReplaceAll(list); } public void ApplyPortalZdos(IEnumerable<ZDO> zdos) { ReplaceAll(zdos.Select(PortalZdo.Read).ToList()); } private void ReplaceAll(List<PortalRecord> incoming) { //IL_00a8: 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_00b5: Unknown result type (might be due to invalid IL or missing references) foreach (PortalRecord item in incoming) { AddOrUpdate(item); } HashSet<ZDOID> incomingIds = new HashSet<ZDOID>(incoming.Select((PortalRecord p) => p.Id)); foreach (ZDOID item2 in _portals.Keys.Where((ZDOID id) => !incomingIds.Contains(id)).ToList()) { _portals.Remove(item2); } } } internal static class PortalRpc { public static void Register() { ZRoutedRpc instance = ZRoutedRpc.instance; instance.Register<string>("RossPortals_SyncRequest", (Action<long, string>)OnSyncRequest); instance.Register<ZPackage>("RossPortals_AddOrUpdate", (Action<long, ZPackage>)OnAddOrUpdate); instance.Register<ZDOID>("RossPortals_Remove", (Action<long, ZDOID>)OnRemove); instance.Register<ZPackage>("RossPortals_SyncPortal", (Action<long, ZPackage>)OnPortalSynced); instance.Register<ZPackage, string>("RossPortals_Resync", (Action<long, ZPackage, string>)OnResync); } public static void RequestSync(string reason) { ZRoutedRpc.instance.InvokeRoutedRPC(Env.ServerPeerId, "RossPortals_SyncRequest", new object[1] { reason }); } public static void RequestAddOrUpdate(PortalRecord record) { ZRoutedRpc.instance.InvokeRoutedRPC(Env.ServerPeerId, "RossPortals_AddOrUpdate", new object[1] { record.Pack() }); } public static void RequestRemove(ZDOID id) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) ZRoutedRpc.instance.InvokeRoutedRPC(Env.ServerPeerId, "RossPortals_Remove", new object[1] { id }); } public static void BroadcastPortal(PortalRecord record) { if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.GetConnectedPeers().Count != 0) { ZRoutedRpc.instance.InvokeRoutedRPC(0L, "RossPortals_SyncPortal", new object[1] { record.Pack() }); } } public static void BroadcastResync(ZPackage pkg, string reason) { if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.GetConnectedPeers().Count != 0) { ZRoutedRpc.instance.InvokeRoutedRPC(0L, "RossPortals_Resync", new object[2] { pkg, reason }); } } private static void OnSyncRequest(long sender, string reason) { if (Env.IsServer) { PortalManager.ProcessSyncRequest(reason); } } private static void OnAddOrUpdate(long sender, ZPackage pkg) { if (Env.IsServer) { PortalManager.ServerAddOrUpdate(PortalRecord.FromPackage(pkg)); } } private static void OnRemove(long sender, ZDOID id) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) if (Env.IsServer) { PortalManager.ServerRemove(id); } } private static void OnPortalSynced(long sender, ZPackage pkg) { if (!Env.IsServer) { PortalRegistry.Instance.AddOrUpdate(PortalRecord.FromPackage(pkg)); PortalManager.NotifyListChanged(); } } private static void OnResync(long sender, ZPackage pkg, string reason) { if (!Env.IsServer) { PortalRegistry.Instance.ApplyResync(pkg); RossPortalsPlugin.Log.LogInfo((object)$"Portal resync ({reason}): now know {PortalRegistry.Instance.Count} portal(s)."); PortalManager.NotifyListChanged(); } } } internal static class PortalZdo { public static string GetName(ZDO zdo) { return zdo.GetString(ZDOVars.s_tag, ""); } public static void SetName(ZDO zdo, string name) { zdo.Set(ZDOVars.s_tag, name ?? string.Empty); } public static ZDOID GetTarget(ZDO zdo) { //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_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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_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) ZDOID zDOID = zdo.GetZDOID("RossPortals_TargetId"); if (zDOID == ZDOID.None) { zDOID = zdo.GetZDOID("XPortal_TargetId"); } return zDOID; } public static ZDOID GetPrevious(ZDO zdo) { //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_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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_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) ZDOID zDOID = zdo.GetZDOID("RossPortals_PreviousId"); if (zDOID == ZDOID.None) { zDOID = zdo.GetZDOID("XPortal_PreviousId"); } return zDOID; } public static PortalRecord Read(ZDO zdo) { //IL_0001: 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_0027: 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_0033: Unknown result type (might be due to invalid IL or missing references) return new PortalRecord(zdo.m_uid) { Name = (GetName(zdo) ?? string.Empty), Location = zdo.GetPosition(), Target = GetTarget(zdo), IsDefault = zdo.GetBool("RossPortals_Default", false), ShowOnMap = zdo.GetBool("RossPortals_ShowOnMap", true) }; } public static void Write(PortalRecord record) { //IL_0006: 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_0061: Unknown result type (might be due to invalid IL or missing references) ZDO zDO = ZDOMan.instance.GetZDO(record.Id); if (zDO != null) { zDO.SetOwner(ZDOMan.GetSessionID()); SetName(zDO, record.Name); zDO.Set("RossPortals_PreviousId", zDO.m_uid); zDO.Set("RossPortals_Default", record.IsDefault); zDO.Set("RossPortals_ShowOnMap", record.ShowOnMap); SetTarget(zDO, record.Target); } } private static void SetTarget(ZDO zdo, ZDOID target) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) zdo.Set("RossPortals_TargetId", target); zdo.SetConnection((ConnectionType)1, target); } public static void RestoreConnections() { //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_004a: 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) //IL_004e: 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_005f: 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_009b: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_009f: 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_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00de: 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_0119: Unknown result type (might be due to invalid IL or missing references) List<ZDO> portalList = ZDOMan.instance.GetPortalList(); if (portalList == null || portalList.Count == 0) { return; } HashSet<ZDOID> hashSet = new HashSet<ZDOID>(); Dictionary<ZDOID, ZDOID> dictionary = new Dictionary<ZDOID, ZDOID>(); foreach (ZDO item in portalList) { hashSet.Add(item.m_uid); ZDOID previous = GetPrevious(item); if (previous != ZDOID.None) { dictionary[previous] = item.m_uid; } } foreach (ZDO item2 in portalList) { ZDOID value = GetTarget(item2); if (!(value == ZDOID.None) && (hashSet.Contains(value) || dictionary.TryGetValue(value, out value))) { item2.SetOwner(ZDOMan.GetSessionID()); item2.SetConnection((ConnectionType)1, value); item2.Set("RossPortals_TargetId", value); } } foreach (ZDO item3 in portalList) { item3.Set("RossPortals_PreviousId", item3.m_uid); } } } internal sealed class Scheduler : MonoBehaviour { public static Scheduler Instance { get; private set; } private void Awake() { Instance = this; } private void OnDestroy() { if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } public void NextFrame(Action action) { AfterFrames(1, action); } public void AfterFrames(int frames, Action action) { if (action != null) { if (!((Behaviour)this).isActiveAndEnabled) { action(); } else { ((MonoBehaviour)this).StartCoroutine(Run(frames, action)); } } } private static IEnumerator Run(int frames, Action action) { for (int i = 0; i < frames; i++) { yield return null; } action(); } } } namespace RossPortals.Game.Patches { [HarmonyPatch(typeof(Game), "Awake")] internal static class Game_Awake { private static void Prefix(ref bool ___isModded) { ___isModded = true; } } [HarmonyPatch(typeof(Game), "Start")] internal static class Game_Start { private static void Postfix() { Env.GameStarted = true; PortalManager.OnGameStarted(); } } [HarmonyPatch(typeof(Game), "ConnectPortals")] internal static class Game_ConnectPortals { private static bool Prepare() { return ValheimCompat.RequireMethod(typeof(Game), "ConnectPortals", "portal destinations"); } private static bool Prefix() { return false; } } [HarmonyPatch(typeof(Game), "ConnectPortalsCoroutine")] internal static class Game_ConnectPortalsCoroutine { private static bool Prepare() { return ValheimCompat.RequireMethod(typeof(Game), "ConnectPortalsCoroutine", "portal destinations"); } private static bool Prefix() { return false; } } [HarmonyPatch(typeof(Piece), "SetCreator")] internal static class Piece_SetCreator { private static void Postfix(Piece __instance) { //IL_0043: 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) if (!((Object)(object)__instance == (Object)null) && __instance.m_name != null && __instance.m_name.Contains("$piece_portal")) { ZNetView nview = __instance.m_nview; ZDO val = (((Object)(object)nview != (Object)null) ? nview.GetZDO() : null); if (val != null) { PortalManager.OnPortalPlaced(val.m_uid, val.GetPosition()); } } } } [HarmonyPatch(typeof(TeleportWorld), "GetHoverText")] internal static class TeleportWorld_GetHoverText { private static bool Prefix(TeleportWorld __instance, ref string __result) { //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) ZNetView nview = __instance.m_nview; if (Env.ShuttingDown || (Object)(object)nview == (Object)null || nview.GetZDO() == null) { __result = string.Empty; return false; } ZDO zDO = nview.GetZDO(); __result = PortalManager.BuildHoverText(zDO.m_uid, zDO.GetPosition()); return false; } } [HarmonyPatch(typeof(TeleportWorld), "Teleport")] internal static class TeleportWorld_Teleport { private static void Postfix(TeleportWorld __instance) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) ZNetView nview = __instance.m_nview; ZDO val = (((Object)(object)nview != (Object)null) ? nview.GetZDO() : null); if (val != null) { PortalManager.RecordUsed(val.GetConnectionZDOID((ConnectionType)1)); } } } [HarmonyPatch(typeof(TextInput), "RequestText")] internal static class TextInput_RequestText { private static bool Prefix(TextReceiver sign) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) TeleportWorld val = (TeleportWorld)(object)((sign is TeleportWorld) ? sign : null); if (val != null) { ZNetView nview = val.m_nview; ZDO val2 = (((Object)(object)nview != (Object)null) ? nview.GetZDO() : null); if (val2 != null) { PortalManager.OnPortalInteract(val2.m_uid); } return false; } return true; } } [HarmonyPatch(typeof(WearNTear), "Destroy")] internal static class WearNTear_Destroy { private static void Prefix(WearNTear __instance) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) Piece val = (((Object)(object)__instance != (Object)null) ? __instance.m_piece : null); if (!((Object)(object)val == (Object)null) && val.m_name != null && val.m_name.Contains("$piece_portal") && val.CanBeRemoved()) { ZNetView nview = val.m_nview; ZDO val2 = (((Object)(object)nview != (Object)null) ? nview.GetZDO() : null); if (val2 != null) { PortalManager.OnPortalDestroyed(val2.m_uid); } } } } [HarmonyPatch(typeof(ZDOMan), "ConnectPortals")] internal static class ZDOMan_ConnectPortals { private static bool Prepare() { return ValheimCompat.RequireMethod(typeof(ZDOMan), "ConnectPortals", "portal destinations"); } private static bool Prefix() { PortalZdo.RestoreConnections(); return false; } } } namespace RossPortals.Game.Framework { internal readonly struct CompatMember { public string Type { get; } public string Member { get; } public string Why { get; } public CompatMember(string type, string member, string why) { Type = type; Member = member; Why = why; } } internal static class ValheimCompat { private static readonly CompatMember[] Members = new CompatMember[23] { new CompatMember("TeleportWorld", "GetHoverText", "replace portal hover text"), new CompatMember("TeleportWorld", "Teleport", "note recently-used destinations"), new CompatMember("TeleportWorld", "m_nview", "reach a portal's ZDO"), new CompatMember("TextInput", "RequestText", "open our panel instead of the tag box"), new CompatMember("ZDOMan", "GetPortalList", "enumerate every portal (server)"), new CompatMember("ZDOMan", "ConnectPortals", "rebuild connections from stored destinations"), new CompatMember("ZDOMan", "GetZDO", "resolve a portal by id"), new CompatMember("ZDOMan", "GetSessionID", "own a portal ZDO before writing it"), new CompatMember("ZDOMan", "ForceSendZDO", "push a just-placed portal to the server"), new CompatMember("ZDO", "GetConnectionZDOID", "read a portal's live destination"), new CompatMember("ZDO", "SetConnection", "set the destination vanilla teleport reads"), new CompatMember("ZDO", "GetString", "read the portal tag/name"), new CompatMember("ZDO", "GetZDOID", "read stored destination/previous id"), new CompatMember("ZDO", "SetOwner", "own a portal ZDO before writing it"), new CompatMember("ZDO", "GetPosition", "a portal's world position"), new CompatMember("ZDOVars", "s_tag", "the vanilla portal-name ZDO key"), new CompatMember("ZRoutedRpc", "InvokeRoutedRPC", "sync the portal list"), new CompatMember("ZRoutedRpc", "Everybody", "broadcast to all peers"), new CompatMember("Piece", "SetCreator", "detect a placed portal"), new CompatMember("Piece", "CanBeRemoved", "confirm a portal is actually being removed"), new CompatMember("WearNTear", "Destroy", "detect a removed portal"), new CompatMember("Game", "ConnectPortals", "suppress vanilla tag pairing"), new CompatMember("Game", "ConnectPortalsCoroutine", "suppress vanilla tag pairing") }; public static void Verify() { List<string> list = FindMissing(Members); if (list.Count == 0) { RossPortalsPlugin.Log.LogInfo((object)$"Valheim compatibility check: all {Members.Length} referenced members present."); return; } RossPortalsPlugin.Log.LogError((object)($"Valheim compatibility check: {list.Count} of {Members.Length} referenced members are MISSING. " + "The affected features are disabled. This usually means a Valheim update moved something:")); foreach (string item in list) { RossPortalsPlugin.Log.LogError((object)(" - " + item)); } } public static List<string> FindMissing(IEnumerable<CompatMember> members) { List<string> list = new List<string>(); if (members == null) { return list; } foreach (CompatMember member in members) { Type type = AccessTools.TypeByName(member.Type); if (type == null) { list.Add(member.Type + " (whole type) -- " + member.Why); } else if (!HasMember(type, member.Member)) { list.Add(member.Type + "." + member.Member + " -- " + member.Why); } } return list; } private static bool HasMember(Type type, string name) { Type type2 = type; while (type2 != null) { if (type2.GetField(name, AccessTools.all) != null) { return true; } if (type2.GetProperty(name, AccessTools.all) != null) { return true; } if (type2.GetEvent(name, AccessTools.all) != null) { return true; } try { if (type2.GetMethod(name, AccessTools.all) != null) { return true; } } catch (AmbiguousMatchException) { return true; } type2 = type2.BaseType; } return false; } public static bool RequireMethod(Type type, string method, string featureName) { if (HasMethod(type, method)) { return true; } RossPortalsPlugin.Log.LogError((object)(type.Name + "." + method + " not found -- skipping that patch; " + featureName + " will not work. See the compatibility check above.")); return false; } private static bool HasMethod(Type type, string name) { Type type2 = type; while (type2 != null) { if (type2.GetMethods(AccessTools.all).Any((MethodInfo m) => m.Name == name)) { return true; } type2 = type2.BaseType; } return false; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }