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 PortalPicker v1.2.3
PortalPicker.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using Splatform; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("PortalPicker")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.2.3.0")] [assembly: AssemblyInformationalVersion("1.2.3")] [assembly: AssemblyProduct("PortalPicker")] [assembly: AssemblyTitle("PortalPicker")] [assembly: AssemblyVersion("1.2.3.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 PortalPicker { internal sealed class ColorField : MaskableGraphic { private const int Cells = 12; internal bool HueStrip; private float hue; internal float Hue { get { return hue; } set { if (!Mathf.Approximately(hue, value)) { hue = value; ((Graphic)this).SetVerticesDirty(); } } } protected override void OnPopulateMesh(VertexHelper vh) { //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) //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_004d: 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_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: 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_00a6: 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) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) vh.Clear(); Rect pixelAdjustedRect = ((Graphic)this).GetPixelAdjustedRect(); if (HueStrip) { for (int i = 0; i < 6; i++) { Color val = Color.HSVToRGB((float)i / 6f, 1f, 1f); Color val2 = Color.HSVToRGB((float)((i + 1) % 6) / 6f, 1f, 1f); float num = ((Rect)(ref pixelAdjustedRect)).yMax - ((Rect)(ref pixelAdjustedRect)).height * (float)i / 6f; float num2 = ((Rect)(ref pixelAdjustedRect)).yMax - ((Rect)(ref pixelAdjustedRect)).height * (float)(i + 1) / 6f; Quad(vh, new Rect(((Rect)(ref pixelAdjustedRect)).xMin, num2, ((Rect)(ref pixelAdjustedRect)).width, num - num2), val2, val2, val, val); } return; } Rect rect = default(Rect); for (int j = 0; j < 12; j++) { for (int k = 0; k < 12; k++) { float num3 = (float)k / 12f; float num4 = (float)(k + 1) / 12f; float num5 = (float)j / 12f; float num6 = (float)(j + 1) / 12f; ((Rect)(ref rect))..ctor(((Rect)(ref pixelAdjustedRect)).xMin + ((Rect)(ref pixelAdjustedRect)).width * num3, ((Rect)(ref pixelAdjustedRect)).yMin + ((Rect)(ref pixelAdjustedRect)).height * num5, ((Rect)(ref pixelAdjustedRect)).width / 12f, ((Rect)(ref pixelAdjustedRect)).height / 12f); Quad(vh, rect, Color.HSVToRGB(hue, num3, num5), Color.HSVToRGB(hue, num4, num5), Color.HSVToRGB(hue, num3, num6), Color.HSVToRGB(hue, num4, num6)); } } } private static void Quad(VertexHelper vh, Rect rect, Color lb, Color rb, Color lt, Color rt) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //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_0026: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: 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_004f: 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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0092: 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_0099: 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_00a3: Unknown result type (might be due to invalid IL or missing references) int currentVertCount = vh.currentVertCount; vh.AddVert(new Vector3(((Rect)(ref rect)).xMin, ((Rect)(ref rect)).yMin), Color32.op_Implicit(lb), Vector4.op_Implicit(Vector2.zero)); vh.AddVert(new Vector3(((Rect)(ref rect)).xMax, ((Rect)(ref rect)).yMin), Color32.op_Implicit(rb), Vector4.op_Implicit(Vector2.zero)); vh.AddVert(new Vector3(((Rect)(ref rect)).xMin, ((Rect)(ref rect)).yMax), Color32.op_Implicit(lt), Vector4.op_Implicit(Vector2.zero)); vh.AddVert(new Vector3(((Rect)(ref rect)).xMax, ((Rect)(ref rect)).yMax), Color32.op_Implicit(rt), Vector4.op_Implicit(Vector2.zero)); vh.AddTriangle(currentVertCount, currentVertCount + 2, currentVertCount + 3); vh.AddTriangle(currentVertCount, currentVertCount + 3, currentVertCount + 1); } } internal enum IconCategory { All, Places, Trophies, Gear, Food, Resources, Buildings } internal sealed class IconDef { public string Key; public IconCategory Category; public string Token; public Sprite Source; public bool Plain; public string Search; public string Title => Localization.instance.Localize(Token); } internal static class IconLibrary { private static readonly string[] SkipPlaces = new string[6] { "player", "ping", "shout", "randevent", "eventarea", "checked" }; private static readonly string[] FirstPlaces = new string[14] { "mapicon_house", "mapicon_fire", "mapicon_hammer", "mapicon_trader", "mapicon_boss", "mapicon_death", "mapicon_bogwitch_camp", "mapicon_mysteriousplace2", "mapicon_start", "mapicon_memorialplace", "mapicon_bed", "mapicon_hildir_wagon", "mapicon_portal", "mapicon_pin" }; internal static readonly string[] DefaultRecent = new string[8] { "map:mapicon_house", "map:mapicon_fire", "map:mapicon_hammer", "map:mapicon_trader", "map:mapicon_boss", "map:mapicon_start", "item:TrophyEikthyr", "item:PickaxeIron" }; private static readonly Dictionary<string, IconDef> byKey = new Dictionary<string, IconDef>(); private static readonly List<IconDef> all = new List<IconDef>(); private static readonly Dictionary<Sprite, Sprite> converted = new Dictionary<Sprite, Sprite>(); private static bool built; internal static bool Ready { get { if ((Object)(object)ObjectDB.instance != (Object)null && ObjectDB.instance.m_items.Count > 0) { return (Object)(object)Minimap.instance != (Object)null; } return false; } } internal static IReadOnlyList<IconDef> All { get { EnsureBuilt(); return all; } } internal static void Reset() { built = false; byKey.Clear(); all.Clear(); } internal static IconDef Find(string key) { if (string.IsNullOrEmpty(key)) { return null; } EnsureBuilt(); if (!byKey.TryGetValue(key, out var value)) { return null; } return value; } internal static Sprite SpriteOf(string key) { IconDef iconDef = Find(key); if (iconDef == null) { return null; } return Display(iconDef); } internal static bool IsCheap(IconDef def) { if (!def.Plain && !((Object)(object)def.Source == (Object)null)) { return converted.ContainsKey(def.Source); } return true; } internal static Sprite Display(IconDef def) { if (def.Plain || (Object)(object)def.Source == (Object)null) { return def.Source; } if (!converted.TryGetValue(def.Source, out var value)) { value = IconArt.Monochrome(def.Source) ?? def.Source; converted[def.Source] = value; } return value; } internal static Sprite PortalPin() { //IL_0035: 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_003b: 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: Invalid comparison between Unknown and I4 //IL_0044: Unknown result type (might be due to invalid IL or missing references) Sprite val = SpriteOf("map:mapicon_portal"); if ((Object)(object)val == (Object)null && (Object)(object)Minimap.instance != (Object)null) { foreach (SpriteData icon in Minimap.instance.m_icons) { if ((int)icon.m_name == 6) { val = icon.m_icon; } } } return val; } private static void EnsureBuilt() { //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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0082: 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) if (built || !Ready) { return; } built = true; HashSet<Sprite> hashSet = new HashSet<Sprite>(); List<IconDef> list = new List<IconDef>(); foreach (SpriteData icon in Minimap.instance.m_icons) { AddPlace(list, hashSet, icon.m_icon); } foreach (LocationSpriteData locationIcon in Minimap.instance.m_locationIcons) { AddPlace(list, hashSet, locationIcon.m_icon); } list.Sort(delegate(IconDef a, IconDef b) { int num = Array.IndexOf(FirstPlaces, ((Object)a.Source).name); int num2 = Array.IndexOf(FirstPlaces, ((Object)b.Source).name); if (num < 0) { num = 1000; } if (num2 < 0) { num2 = 1000; } return (num == num2) ? string.CompareOrdinal(((Object)a.Source).name, ((Object)b.Source).name) : num.CompareTo(num2); }); List<IconDef> list2 = new List<IconDef>(); List<IconDef> list3 = new List<IconDef>(); HashSet<PieceTable> hashSet2 = new HashSet<PieceTable>(); foreach (GameObject item in ObjectDB.instance.m_items) { ItemDrop val = (((Object)(object)item != (Object)null) ? item.GetComponent<ItemDrop>() : null); if (!((Object)(object)val == (Object)null) && val.m_itemData?.m_shared != null) { SharedData shared = val.m_itemData.m_shared; if ((Object)(object)shared.m_buildPieces != (Object)null) { hashSet2.Add(shared.m_buildPieces); } Sprite val2 = ((shared.m_icons != null && shared.m_icons.Length != 0) ? shared.m_icons[0] : null); if (!((Object)(object)val2 == (Object)null) && !Junk(((Object)item).name) && hashSet.Add(val2)) { list2.Add(new IconDef { Key = "item:" + ((Object)item).name, Category = CategoryOf(shared.m_itemType), Token = shared.m_name, Source = val2 }); } } } foreach (PieceTable item2 in hashSet2) { foreach (GameObject piece in item2.m_pieces) { Piece val3 = (((Object)(object)piece != (Object)null) ? piece.GetComponent<Piece>() : null); if (!((Object)(object)val3 == (Object)null) && !((Object)(object)val3.m_icon == (Object)null) && !Junk(((Object)piece).name) && hashSet.Add(val3.m_icon)) { list3.Add(new IconDef { Key = "piece:" + ((Object)piece).name, Category = IconCategory.Buildings, Token = val3.m_name, Source = val3.m_icon }); } } } foreach (IconDef item3 in list) { Register(item3); } list2.AddRange(list3); foreach (IconDef item4 in list2) { item4.Search = item4.Title.ToLowerInvariant(); } list2.Sort((IconDef a, IconDef b) => (a.Category == b.Category) ? string.Compare(a.Search, b.Search, StringComparison.CurrentCulture) : a.Category.CompareTo(b.Category)); foreach (IconDef item5 in list2) { Register(item5); } PortalPickerPlugin.Log.LogInfo((object)$"Portal icons: {list.Count} map marks, {list2.Count - list3.Count} items, {list3.Count} pieces"); } private static void AddPlace(List<IconDef> places, HashSet<Sprite> seen, Sprite sprite) { if ((Object)(object)sprite == (Object)null || !seen.Add(sprite)) { return; } string text = ((Object)sprite).name ?? ""; string[] skipPlaces = SkipPlaces; foreach (string value in skipPlaces) { if (text.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0) { return; } } string text2 = (text.StartsWith("mapicon_") ? text.Substring(8) : text); IconDef iconDef = new IconDef { Key = "map:" + text, Category = IconCategory.Places, Token = "$q8pp_icon_" + text2, Source = sprite, Plain = true }; if (iconDef.Title.StartsWith("[")) { iconDef.Token = text2.Replace('_', ' '); } iconDef.Search = iconDef.Title.ToLowerInvariant(); places.Add(iconDef); } private static void Register(IconDef def) { if (!byKey.ContainsKey(def.Key)) { byKey.Add(def.Key, def); all.Add(def); } } private static bool Junk(string prefab) { string text = prefab.ToLowerInvariant(); if (!text.Contains("cheat") && !text.Contains("debug") && !text.EndsWith("_old")) { return text.Contains("test"); } return true; } private static IconCategory CategoryOf(ItemType type) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Invalid comparison between Unknown and I4 //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Invalid comparison between Unknown and I4 if ((int)type <= 2) { if ((int)type <= 1) { goto IL_0023; } if ((int)type == 2) { return IconCategory.Food; } } else { if ((int)type == 13) { return IconCategory.Trophies; } if ((int)type == 16 || (int)type == 21) { goto IL_0023; } } return IconCategory.Gear; IL_0023: return IconCategory.Resources; } } internal static class IconArt { private const int Pad = 2; internal static Sprite Monochrome(Sprite source) { //IL_0008: 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_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Expected O, but got Unknown //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_010e: 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_0130: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_02bb: Unknown result type (might be due to invalid IL or missing references) //IL_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_02c7: Unknown result type (might be due to invalid IL or missing references) //IL_02ce: Unknown result type (might be due to invalid IL or missing references) //IL_02e4: Unknown result type (might be due to invalid IL or missing references) //IL_02ec: Unknown result type (might be due to invalid IL or missing references) //IL_0304: Unknown result type (might be due to invalid IL or missing references) //IL_0313: Unknown result type (might be due to invalid IL or missing references) //IL_0322: Expected O, but got Unknown //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Unknown result type (might be due to invalid IL or missing references) try { Texture2D texture = source.texture; Rect textureRect = source.textureRect; int num = Mathf.RoundToInt(((Rect)(ref textureRect)).width); int num2 = Mathf.RoundToInt(((Rect)(ref textureRect)).height); if ((Object)(object)texture == (Object)null || num <= 0 || num2 <= 0) { return null; } RenderTexture temporary = RenderTexture.GetTemporary(((Texture)texture).width, ((Texture)texture).height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)0); RenderTexture active = RenderTexture.active; Color32[] pixels; try { Graphics.Blit((Texture)(object)texture, temporary); RenderTexture.active = temporary; Texture2D val = new Texture2D(num, num2, (TextureFormat)4, false); val.ReadPixels(new Rect(((Rect)(ref textureRect)).x, ((Rect)(ref textureRect)).y, (float)num, (float)num2), 0, 0); val.Apply(false); pixels = val.GetPixels32(); Object.Destroy((Object)val); } finally { RenderTexture.active = active; RenderTexture.ReleaseTemporary(temporary); } int num3 = num + 4; int num4 = num2 + 4; float[] array = new float[num3 * num4]; float[] array2 = new float[num3 * num4]; for (int i = 0; i < num2; i++) { for (int j = 0; j < num; j++) { Color32 val2 = pixels[i * num + j]; int num5 = (i + 2) * num3 + j + 2; array[num5] = (float)(int)val2.a / 255f; float num6 = (0.299f * (float)(int)val2.r + 0.587f * (float)(int)val2.g + 0.114f * (float)(int)val2.b) / 255f; array2[num5] = Mathf.Min(1f, 0.47f + 0.75f * num6); } } Color32[] array3 = (Color32[])(object)new Color32[num3 * num4]; for (int k = 0; k < num4; k++) { for (int l = 0; l < num3; l++) { float num7 = 0f; for (int m = -2; m <= 2; m++) { int num8 = k + m; if (num8 < 0 || num8 >= num4) { continue; } for (int n = -2; n <= 2; n++) { int num9 = l + n; if (num9 >= 0 && num9 < num3 && array[num8 * num3 + num9] > num7) { num7 = array[num8 * num3 + num9]; } } } int num10 = k * num3 + l; float num11 = array[num10]; float num12 = num11 + num7 * (1f - num11); byte b = (byte)Mathf.RoundToInt(Mathf.Clamp01((num12 > 0f) ? ((array2[num10] * num11 + 0.086f * num7 * (1f - num11)) / num12) : 0f) * 255f); array3[num10] = new Color32(b, b, b, (byte)Mathf.RoundToInt(Mathf.Clamp01(num12) * 255f)); } } Texture2D val3 = new Texture2D(num3, num4, (TextureFormat)4, false) { wrapMode = (TextureWrapMode)1, filterMode = (FilterMode)1, name = "q8pp_" + ((Object)source).name }; val3.SetPixels32(array3); val3.Apply(false, true); Sprite obj = Sprite.Create(val3, new Rect(0f, 0f, (float)num3, (float)num4), new Vector2(0.5f, 0.5f), 100f); ((Object)obj).name = "q8pp_" + ((Object)source).name; return obj; } catch (Exception ex) { PortalPickerPlugin.Log.LogWarning((object)("Icon " + ((Object)source).name + " kept in colour: " + ex.Message)); return null; } } } internal static class MapPins { private sealed class Mark { public ZDOID Id; public string Name; public Vector3 Pos; public string Icon; public int Color; public string Owner; public bool Public; } private const string SnapshotKey = "q8pp_portals"; private const int SnapshotFormat = 2; private static readonly Dictionary<PinData, Mark> pins = new Dictionary<PinData, Mark>(); private static readonly Dictionary<PinData, Image> badges = new Dictionary<PinData, Image>(); private static Minimap pinsOn; private static object shownItem; private static string shownSnapshot; private static int shownVersion = -1; private static bool faulted; private static bool linked; private static Func<ItemData> held; private static Func<Minimap, Vector3, bool> isDrawn; private static RectTransform tip; private static TextMeshProUGUI tipText; private static Mark tipMark; internal static void Reset() { pins.Clear(); badges.Clear(); pinsOn = null; shownItem = null; shownSnapshot = null; shownVersion = -1; tip = null; tipText = null; tipMark = null; faulted = false; } internal static bool LinkParchment(Harmony harmony) { //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Expected O, but got Unknown Type type = AccessTools.TypeByName("ParchmentMap.MapSession"); MethodInfo methodInfo = ((type != null) ? AccessTools.PropertyGetter(type, "Held") : null); MethodInfo methodInfo2 = ((type != null) ? AccessTools.Method(type, "IsDrawn", new Type[2] { typeof(Minimap), typeof(Vector3) }, (Type[])null) : null); MethodInfo methodInfo3 = ((type != null) ? AccessTools.Method(type, "UseTable", new Type[3] { typeof(MapTable), typeof(Humanoid), typeof(bool) }, (Type[])null) : null); if (methodInfo == null || methodInfo2 == null || methodInfo3 == null) { return false; } held = (Func<ItemData>)Delegate.CreateDelegate(typeof(Func<ItemData>), methodInfo); isDrawn = (Func<Minimap, Vector3, bool>)Delegate.CreateDelegate(typeof(Func<Minimap, Vector3, bool>), methodInfo2); harmony.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, new HarmonyMethod(typeof(MapPins), "UseTablePostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); linked = true; return true; } internal static void Update() { if (faulted) { return; } try { UpdateCore(); } catch (Exception ex) { faulted = true; PortalPickerPlugin.Log.LogError((object)("Portal marks on the map are switched off until you re-enter the world: " + ex)); } } internal static void Colorize(Minimap minimap) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)minimap != (Object)(object)pinsOn) { return; } foreach (KeyValuePair<PinData, Mark> pin in pins) { PinData key = pin.Key; if ((Object)(object)key.m_iconElement != (Object)null) { ((Graphic)key.m_iconElement).color = PortalMeta.ColorOf(pin.Value.Color); } if ((Object)(object)key.m_uiElement != (Object)null && (!badges.TryGetValue(key, out var value) || (Object)(object)value == (Object)null || (Object)(object)((Component)value).transform.parent != (Object)(object)key.m_uiElement)) { badges[key] = AddBadge(key.m_uiElement); } } } private static Image AddBadge(RectTransform pinElement) { //IL_000b: 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_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0046: 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) Image obj = UiKit.Picture("q8pp_badge", (Transform)(object)pinElement, UiKit.PortalBadgeSprite, Color.white); RectTransform rectTransform = ((Graphic)obj).rectTransform; rectTransform.anchorMin = new Vector2(-0.07f, -0.07f); rectTransform.anchorMax = new Vector2(0.46f, 0.46f); rectTransform.offsetMin = Vector2.zero; rectTransform.offsetMax = Vector2.zero; return obj; } private static void UseTablePostfix(bool __result) { //IL_0054: 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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) if (!__result || !PortalList.Received || (Object)(object)Minimap.instance == (Object)null) { return; } try { ItemData val = held(); if (val == null) { return; } List<Mark> list = new List<Mark>(); foreach (PortalList.Entry entry in PortalList.Entries) { if (isDrawn(Minimap.instance, entry.Position)) { list.Add(new Mark { Id = entry.Id, Name = PortalHover.CleanName(entry.Name), Pos = entry.Position, Icon = (entry.Icon ?? ""), Color = entry.Color, Owner = (entry.OwnerName ?? ""), Public = PortalMeta.IsPublic(entry.OwnerId) }); } } val.m_customData["q8pp_portals"] = Serialize(list); PortalPickerPlugin.Log.LogInfo((object)$"Cartography table: {list.Count} of {PortalList.Entries.Count} portals are on the parchment"); } catch (Exception ex) { PortalPickerPlugin.Log.LogWarning((object)("Could not write portals onto the parchment: " + ex.Message)); } } private static void UpdateCore() { //IL_0108: 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_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) Minimap instance = Minimap.instance; if ((Object)(object)instance == (Object)null) { return; } if ((Object)(object)instance != (Object)(object)pinsOn) { pins.Clear(); badges.Clear(); pinsOn = instance; shownItem = null; shownSnapshot = null; shownVersion = -1; } if (linked) { ItemData val = (((Object)(object)Player.m_localPlayer != (Object)null) ? held() : null); string value = null; val?.m_customData.TryGetValue("q8pp_portals", out value); if (val != shownItem || !string.Equals(value, shownSnapshot) || shownVersion < 0) { shownItem = val; shownSnapshot = value; shownVersion = 0; Rebuild(instance, Parse(value)); } } else if (PortalList.Version != shownVersion) { shownVersion = PortalList.Version; List<Mark> list = new List<Mark>(); foreach (PortalList.Entry entry in PortalList.Entries) { list.Add(new Mark { Id = entry.Id, Name = PortalHover.CleanName(entry.Name), Pos = entry.Position, Icon = (entry.Icon ?? ""), Color = entry.Color, Owner = (entry.OwnerName ?? ""), Public = PortalMeta.IsPublic(entry.OwnerId) }); } Rebuild(instance, list); } UpdateTooltip(instance); } private static void Rebuild(Minimap minimap, List<Mark> marks) { //IL_0065: 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) foreach (PinData key in pins.Keys) { minimap.RemovePin(key); } pins.Clear(); badges.Clear(); Sprite val = null; foreach (Mark mark in marks) { PinData val2 = minimap.AddPin(mark.Pos, (PinType)6, mark.Name, false, false, 0L, default(PlatformUserID)); Sprite val3 = IconLibrary.SpriteOf(mark.Icon); if ((Object)(object)val3 == (Object)null) { val3 = val ?? (val = IconLibrary.PortalPin()); } if ((Object)(object)val3 != (Object)null) { val2.m_icon = val3; } pins[val2] = mark; } } private static void UpdateTooltip(Minimap minimap) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Expected O, but got Unknown //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) Mark mark = null; if ((int)minimap.m_mode == 2 && (Object)(object)minimap.m_largeRoot != (Object)null && minimap.m_largeRoot.activeInHierarchy) { Vector3 pointerPosition = ZInput.pointerPosition; foreach (KeyValuePair<PinData, Mark> pin in pins) { RectTransform uiElement = pin.Key.m_uiElement; if ((Object)(object)uiElement != (Object)null && ((Component)uiElement).gameObject.activeInHierarchy && RectTransformUtility.RectangleContainsScreenPoint(uiElement, Vector2.op_Implicit(pointerPosition), CameraOf((Transform)(object)uiElement))) { mark = pin.Value; break; } } } if (mark == null) { if ((Object)(object)tip != (Object)null) { ((Component)tip).gameObject.SetActive(false); } tipMark = null; return; } if ((Object)(object)tip == (Object)null) { BuildTooltip(minimap.m_largeRoot.transform); } if (mark != tipMark) { tipMark = mark; string text = ((mark.Name.Length > 0) ? Localization.instance.Localize("$q8pp_header").Replace("{0}", mark.Name) : Localization.instance.Localize("$q8pp_header_unnamed")); string text2 = "<b>" + text + "</b>"; if (mark.Public) { text2 = text2 + "\n<size=85%><b><color=#96BEEB>" + Localization.instance.Localize("$q8pp_public_portal") + "</color></b></size>"; } else if (mark.Owner.Length > 0) { text2 = text2 + "\n<size=85%><color=#BFBFBF>" + Localization.instance.Localize("$q8pp_owned_by") + " </color><b><color=#96BEEB>" + mark.Owner + "</color></b></size>"; } ((TMP_Text)tipText).text = text2; Vector2 preferredValues = ((TMP_Text)tipText).GetPreferredValues(text2); tip.sizeDelta = new Vector2(preferredValues.x + 22f, preferredValues.y + 14f); } RectTransform val = (RectTransform)((Transform)tip).parent; Vector2 val2 = default(Vector2); if (RectTransformUtility.ScreenPointToLocalPointInRectangle(val, Vector2.op_Implicit(ZInput.pointerPosition), CameraOf((Transform)(object)val), ref val2)) { tip.anchoredPosition = val2 + new Vector2(18f, -14f); } ((Component)tip).gameObject.SetActive(true); ((Transform)tip).SetAsLastSibling(); } private static void BuildTooltip(Transform parent) { //IL_001f: 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_0036: 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_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: 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_00cd: Unknown result type (might be due to invalid IL or missing references) RectTransform val = UiKit.Rect("q8pp_maptip", parent); Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(0.5f, 0.5f); val.anchorMax = val2; val.anchorMin = val2; val.pivot = new Vector2(0f, 1f); ((Component)val).gameObject.AddComponent<CanvasRenderer>(); Image obj = ((Component)val).gameObject.AddComponent<Image>(); obj.sprite = UiKit.PanelSprite; obj.type = (Type)1; ((Graphic)obj).raycastTarget = false; tipText = UiKit.Label("text", (Transform)(object)val, 16f, UiKit.Text, (TextAlignmentOptions)4097); RectTransform rectTransform = ((TMP_Text)tipText).rectTransform; rectTransform.anchorMin = Vector2.zero; rectTransform.anchorMax = Vector2.one; rectTransform.offsetMin = new Vector2(11f, 7f); rectTransform.offsetMax = new Vector2(-11f, -7f); tip = val; } private static Camera CameraOf(Transform element) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) Canvas componentInParent = ((Component)element).GetComponentInParent<Canvas>(); if (!((Object)(object)componentInParent == (Object)null) && (int)componentInParent.renderMode != 0) { return componentInParent.worldCamera; } return null; } private static string Serialize(List<Mark> marks) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_002c: 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) ZPackage val = new ZPackage(); val.Write(2); val.Write(marks.Count); foreach (Mark mark in marks) { val.Write(mark.Id); val.Write(mark.Name); val.Write(mark.Pos); val.Write(mark.Icon); val.Write(mark.Color); val.Write(mark.Owner); val.Write(mark.Public); } return val.GetBase64(); } private static List<Mark> Parse(string snapshot) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown //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_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) List<Mark> list = new List<Mark>(); if (string.IsNullOrEmpty(snapshot)) { return list; } try { ZPackage val = new ZPackage(snapshot); int num = val.ReadInt(); if (num != 1 && num != 2) { return list; } int num2 = val.ReadInt(); for (int i = 0; i < num2; i++) { list.Add(new Mark { Id = val.ReadZDOID(), Name = val.ReadString(), Pos = val.ReadVector3(), Icon = val.ReadString(), Color = PortalMeta.NormalizeColor(val.ReadInt()), Owner = val.ReadString(), Public = (num >= 2 && val.ReadBool()) }); } } catch (Exception ex) { PortalPickerPlugin.Log.LogWarning((object)("Portals on this parchment cannot be read: " + ex.Message)); list.Clear(); } return list; } } [HarmonyPatch(typeof(Game), "Start")] internal static class GameStartPatch { private static void Postfix() { PlayerNames.OnGameStart(); PortalList.OnGameStart(); PortalHover.OnGameStart(); IconLibrary.Reset(); WheelHud.Reset(); PortalPanel.Reset(); MapPins.Reset(); } } [HarmonyPatch(typeof(ZNet), "Shutdown")] internal static class ShutdownPatch { private static void Prefix() { PlayerNames.Flush(); } } [HarmonyPatch(typeof(Game), "ConnectPortals")] internal static class NoPairingPatch { private static bool Prefix() { return false; } } [HarmonyPatch(typeof(TeleportWorldTrigger), "OnTriggerEnter")] internal static class NoWalkInPatch { private static bool Prefix() { return false; } } [HarmonyPatch(typeof(TeleportWorld), "Awake")] internal static class PortalAwakePatch { private static void Postfix(ZNetView ___m_nview) { if ((Object)(object)___m_nview != (Object)null && ___m_nview.GetZDO() != null) { PortalMeta.Register(___m_nview); } } } [HarmonyPatch(typeof(TeleportWorld), "GetHoverText")] internal static class HoverTextPatch { private static bool Prefix(ZNetView ___m_nview, ref string __result) { ZDO val = (((Object)(object)___m_nview != (Object)null) ? ___m_nview.GetZDO() : null); __result = ((WheelHud.Working || val == null) ? " " : PortalHover.FallbackText(val)); return false; } } [HarmonyPatch(typeof(TeleportWorld), "Interact")] internal static class InteractPatch { private static bool Prefix(TeleportWorld __instance, ZNetView ___m_nview, Humanoid human, bool hold, bool alt, ref bool __result) { ZDO val = (((Object)(object)___m_nview != (Object)null) ? ___m_nview.GetZDO() : null); if (hold || val == null) { __result = false; } else if (alt) { __result = PortalHover.Configure(__instance, human); } else { __result = PortalHover.Teleport(__instance, val, (Player)(object)((human is Player) ? human : null)); } return false; } } [HarmonyPatch(typeof(TeleportWorld), "HaveTarget")] internal static class HaveTargetPatch { private static bool Prefix(ZNetView ___m_nview, ref bool __result) { __result = PortalHover.HasTargets(___m_nview); return false; } } [HarmonyPatch(typeof(TeleportWorld), "TargetFound")] internal static class TargetFoundPatch { private static bool Prefix(ZNetView ___m_nview, ref bool __result) { __result = PortalHover.HasTargets(___m_nview); return false; } } [HarmonyPatch(typeof(Minimap), "UpdatePins")] internal static class PinColorPatch { private static void Postfix(Minimap __instance) { MapPins.Colorize(__instance); } } [HarmonyPatch(typeof(GameCamera), "UpdateCamera")] internal static class CameraZoomPatch { private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { MethodInfo wheel = AccessTools.Method(typeof(ZInput), "GetMouseScrollWheel", (Type[])null, (Type[])null); MethodInfo ours = AccessTools.Method(typeof(PortalHover), "CameraScrollWheel", (Type[])null, (Type[])null); int replaced = 0; foreach (CodeInstruction instruction in instructions) { if (CodeInstructionExtensions.Calls(instruction, wheel)) { instruction.operand = ours; replaced++; } yield return instruction; } if (replaced == 0) { PortalPickerPlugin.Log.LogWarning((object)"Camera zoom by the wheel not found: the wheel will also zoom while choosing a portal"); } } } [HarmonyPatch(typeof(HotkeyBar), "Update")] internal static class HotbarPatch { private static bool Prefix() { if (ZInput.IsGamepadActive()) { return !PortalHover.ListOpen(); } return true; } } internal static class PlayerNames { private const string Folder = "portalpicker"; private const float SaveDelay = 10f; private static readonly Dictionary<long, string> names = new Dictionary<long, string>(); private static string path; private static long world; private static bool dirty; private static float saveAt; internal static IReadOnlyDictionary<long, string> All => names; internal static void OnGameStart() { names.Clear(); path = null; world = 0L; dirty = false; } internal static string NameOf(long id) { if (id == 0L || !names.TryGetValue(id, out var value)) { return ""; } return value; } internal static void Update() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) EnsureLoaded(); foreach (ZNetPeer peer in ZNet.instance.GetPeers()) { if (peer != null && !((ZDOID)(ref peer.m_characterID)).IsNone()) { ZDO zDO = ZDOMan.instance.GetZDO(peer.m_characterID); if (zDO != null) { Learn(zDO.GetLong(ZDOVars.s_playerID, 0L), zDO.GetString(ZDOVars.s_playerName, "")); } } } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { Learn(localPlayer.GetPlayerID(), localPlayer.GetPlayerName()); } if (dirty && Time.time >= saveAt) { Save(); } } internal static void Flush() { if (dirty) { Save(); } } private static void Learn(long id, string name) { name = Clean(name); if (id != 0L && name.Length != 0 && !(name == "...") && (!names.TryGetValue(id, out var value) || value != name)) { names[id] = name; if (!dirty) { saveAt = Time.time + 10f; } dirty = true; } } private static string Clean(string name) { return (name ?? "").Replace('\t', ' ').Replace('\r', ' ').Replace('\n', ' ') .Trim(); } private static void LearnFromWorld() { if (!(AccessTools.Field(typeof(ZDOMan), "m_objectsByID")?.GetValue(ZDOMan.instance) is Dictionary<ZDOID, ZDO> dictionary)) { PortalPickerPlugin.Log.LogWarning((object)"Player names: the world's objects are not reachable, names come only from players who join"); return; } int count = names.Count; foreach (ZDO value in dictionary.Values) { string text = value.GetString(ZDOVars.s_ownerName, ""); if (text.Length > 0) { LearnIfUnknown(value.GetLong(ZDOVars.s_owner, 0L), text); } string text2 = value.GetString(ZDOVars.s_creatorName, ""); if (text2.Length > 0) { LearnIfUnknown(value.GetLong(ZDOVars.s_creator, 0L), text2); } } PortalPickerPlugin.Log.LogInfo((object)$"Player names: {names.Count - count} more from beds, wards and tombstones, {names.Count} known"); } private static void LearnIfUnknown(long id, string name) { name = Clean(name); if (id != 0L && name.Length != 0 && !(name == "...") && !names.ContainsKey(id)) { names[id] = name; if (!dirty) { saveAt = Time.time + 10f; } dirty = true; } } private static void EnsureLoaded() { long worldUID = ZNet.instance.GetWorldUID(); if (PlayerNames.path != null && world == worldUID) { return; } names.Clear(); dirty = false; world = worldUID; try { string path = Path.Combine(Utils.GetSaveDataPath((FileSource)2), "portalpicker"); Directory.CreateDirectory(path); PlayerNames.path = Path.Combine(path, SafeName(ZNet.instance.GetWorldName()) + "." + worldUID.ToString("X") + ".players"); if (File.Exists(PlayerNames.path)) { string[] array = File.ReadAllLines(PlayerNames.path, Encoding.UTF8); foreach (string text in array) { int num = text.IndexOf('\t'); if (num > 0 && long.TryParse(text.Substring(0, num), out var result) && result != 0L) { string text2 = Clean(text.Substring(num + 1)); if (text2.Length > 0) { names[result] = text2; } } } } PortalPickerPlugin.Log.LogInfo((object)$"Player names: {PlayerNames.path}, {names.Count} known"); } catch (Exception ex) { PortalPickerPlugin.Log.LogWarning((object)("Player names are kept only until the server stops: " + ex.Message)); PlayerNames.path = ""; } try { LearnFromWorld(); } catch (Exception ex2) { PortalPickerPlugin.Log.LogWarning((object)("Player names from the world failed: " + ex2.Message)); } } private static void Save() { dirty = false; if (string.IsNullOrEmpty(path)) { return; } try { StringBuilder stringBuilder = new StringBuilder(); foreach (KeyValuePair<long, string> name in names) { stringBuilder.Append(name.Key).Append('\t').Append(name.Value) .Append('\n'); } string sourceFileName = path + ".tmp"; File.WriteAllText(sourceFileName, stringBuilder.ToString(), new UTF8Encoding(encoderShouldEmitUTF8Identifier: false)); if (File.Exists(path)) { File.Delete(path); } File.Move(sourceFileName, path); } catch (Exception ex) { PortalPickerPlugin.Log.LogWarning((object)("Could not save player names: " + ex.Message)); } } private static string SafeName(string name) { StringBuilder stringBuilder = new StringBuilder(); string text = name ?? "world"; foreach (char c in text) { stringBuilder.Append((char.IsLetterOrDigit(c) || c == '-' || c == '_') ? c : '_'); } if (stringBuilder.Length <= 0) { return "world"; } return stringBuilder.ToString(); } } [BepInPlugin("qua8ion.valheim.portalpicker", "PortalPicker", "1.2.3")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInIncompatibility("yay.spikehimself.xportal")] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public class PortalPickerPlugin : BaseUnityPlugin { public const string PluginGuid = "qua8ion.valheim.portalpicker"; public const string PluginName = "PortalPicker"; public const string PluginVersion = "1.2.3"; internal static ManualLogSource Log; internal static ConfigEntry<bool> ShowDistance; internal static ConfigEntry<int> NameLength; internal static ConfigEntry<string> RecentIcons; internal static ConfigEntry<string> RecentColors; private void Awake() { //IL_002a: 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_0037: Expected O, but got Unknown //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0041: 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_009d: 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_00af: Expected O, but got Unknown //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Expected O, but got Unknown //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Expected O, but got Unknown //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Expected O, but got Unknown //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; ShowDistance = ((BaseUnityPlugin)this).Config.Bind<bool>("Rules", "ShowDistance", true, new ConfigDescription("Show in the list how far each portal is from the one you are looking at.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true } })); NameLength = ((BaseUnityPlugin)this).Config.Bind<int>("Display", "NameLength", 30, new ConfigDescription("Longest portal name you can type (the game's own limit is 10).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 60), Array.Empty<object>())); RecentIcons = ((BaseUnityPlugin)this).Config.Bind<string>("Display", "RecentIcons", "", new ConfigDescription("Icons you gave portals lately, newest first (filled by the game).", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes { Browsable = false } })); RecentColors = ((BaseUnityPlugin)this).Config.Bind<string>("Display", "RecentColors", "", new ConfigDescription("Your own colours you gave portals lately, RRGGBB, newest first (filled by the game).", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes { Browsable = false } })); AddLocalization(); Harmony val = new Harmony("qua8ion.valheim.portalpicker"); val.PatchAll(typeof(PortalPickerPlugin).Assembly); if (MapPins.LinkParchment(val)) { Log.LogInfo((object)"ParchmentMap found: portals appear on a parchment at a cartography table"); } } private void Update() { PortalList.Update(); if (!GUIManager.IsHeadless()) { PortalHover.Update(); PortalPanel.Update(); MapPins.Update(); } } private void LateUpdate() { if (!GUIManager.IsHeadless()) { WheelHud.LateUpdate(); } } private static void AddLocalization() { CustomLocalization localization = LocalizationManager.Instance.GetLocalization(); string text = "English"; localization.AddTranslation(ref text, new Dictionary<string, string> { { "q8pp_header", "Portal \"{0}\"" }, { "q8pp_header_unnamed", "Portal without a name" }, { "q8pp_owned_by", "owned by" }, { "q8pp_unnamed", "no name" }, { "q8pp_unknown_owner", "unknown" }, { "q8pp_public", "public" }, { "q8pp_public_portal", "public portal" }, { "q8pp_owner_public", "— public, no owner —" }, { "q8pp_none", "No other portals yet" }, { "q8pp_loading", "Waiting for the list of portals" }, { "q8pp_go", "Travel" }, { "q8pp_choose", "Choose" }, { "q8pp_wheel", "Wheel" }, { "q8pp_m", "m" }, { "q8pp_km", "km" }, { "q8pp_decimal", "." }, { "q8pp_panel_title", "Portal" }, { "q8pp_label_name", "Name" }, { "q8pp_label_owner", "Owner" }, { "q8pp_label_icon", "Icon" }, { "q8pp_label_color", "Colour" }, { "q8pp_quick", "quick" }, { "q8pp_own_palette", "own palette" }, { "q8pp_palette_title", "Palette" }, { "q8pp_label_code", "Colour code" }, { "q8pp_label_recent_colors", "Recent" }, { "q8pp_recent_colors_click", "click to use it at once" }, { "q8pp_recent_colors_empty", "colours you choose will appear here" }, { "q8pp_palette_mouse", "square and strip with the mouse" }, { "q8pp_label_preview", "In the list" }, { "q8pp_label_favorite", "Favourite" }, { "q8pp_favorite_note", "only yours: the wheel at this portal starts on the portal you choose here" }, { "q8pp_no_favorite", "— none —" }, { "q8pp_ward_favorite_only", "someone else's ward: only your favourite can be changed" }, { "q8pp_keys_save", "save" }, { "q8pp_keys_cancel", "cancel" }, { "q8pp_recent", "recent" }, { "q8pp_all_icons", "all icons" }, { "q8pp_all_title", "All icons" }, { "q8pp_search", "search by name" }, { "q8pp_save", "Save" }, { "q8pp_cancel", "Cancel" }, { "q8pp_mouse_rest", "the rest with the mouse" }, { "q8pp_pick", "click to choose" }, { "q8pp_back", "Back" }, { "q8pp_tab_all", "All" }, { "q8pp_tab_places", "Places" }, { "q8pp_tab_trophies", "Trophies" }, { "q8pp_tab_gear", "Gear" }, { "q8pp_tab_food", "Food" }, { "q8pp_tab_resources", "Resources" }, { "q8pp_tab_buildings", "Buildings" }, { "q8pp_icon_house", "House" }, { "q8pp_icon_fire", "Campfire" }, { "q8pp_icon_hammer", "Hammer" }, { "q8pp_icon_trader", "Trader" }, { "q8pp_icon_boss", "Boss" }, { "q8pp_icon_death", "Skull" }, { "q8pp_icon_bogwitch_camp", "Cauldron" }, { "q8pp_icon_mysteriousplace2", "Cave" }, { "q8pp_icon_start", "Start" }, { "q8pp_icon_memorialplace", "Runestone" }, { "q8pp_icon_bed", "Bed" }, { "q8pp_icon_hildir_wagon", "Wagon" }, { "q8pp_icon_portal", "Portal" }, { "q8pp_icon_pin", "Dot" }, { "q8pp_icon_hildir", "Hildir" }, { "q8pp_icon_hildir_dress", "Shirt" }, { "q8pp_icon_hildir1", "Question" }, { "q8pp_icon_hildir2", "Question" }, { "q8pp_icon_hildir3", "Question" }, { "q8pp_icon_upgradestation", "Statue" } }); text = "Russian"; localization.AddTranslation(ref text, new Dictionary<string, string> { { "q8pp_header", "Портал «{0}»" }, { "q8pp_header_unnamed", "Портал без названия" }, { "q8pp_owned_by", "принадлежит" }, { "q8pp_unnamed", "без названия" }, { "q8pp_unknown_owner", "неизвестно" }, { "q8pp_public", "общий" }, { "q8pp_public_portal", "общий портал" }, { "q8pp_owner_public", "— общий, без владельца —" }, { "q8pp_none", "Других порталов пока нет" }, { "q8pp_loading", "Жду список порталов" }, { "q8pp_go", "Переместиться" }, { "q8pp_choose", "Выбрать" }, { "q8pp_wheel", "Колесо" }, { "q8pp_m", "м" }, { "q8pp_km", "км" }, { "q8pp_decimal", "," }, { "q8pp_panel_title", "Портал" }, { "q8pp_label_name", "Название" }, { "q8pp_label_owner", "Владелец" }, { "q8pp_label_icon", "Значок" }, { "q8pp_label_color", "Цвет" }, { "q8pp_quick", "быстрые" }, { "q8pp_own_palette", "своя палитра" }, { "q8pp_palette_title", "Палитра" }, { "q8pp_label_code", "Код цвета" }, { "q8pp_label_recent_colors", "Последние" }, { "q8pp_recent_colors_click", "щелчок — сразу этот цвет" }, { "q8pp_recent_colors_empty", "здесь будут цвета, которые ты выбирал" }, { "q8pp_palette_mouse", "квадрат и полоса — мышью" }, { "q8pp_label_preview", "В списке" }, { "q8pp_label_favorite", "Избранный" }, { "q8pp_favorite_note", "только у тебя: колесо у этого портала сразу встаёт на выбранный здесь портал" }, { "q8pp_no_favorite", "— нет —" }, { "q8pp_ward_favorite_only", "чужой вард: менять можно только избранного" }, { "q8pp_keys_save", "сохранить" }, { "q8pp_keys_cancel", "отмена" }, { "q8pp_recent", "последние" }, { "q8pp_all_icons", "все значки" }, { "q8pp_all_title", "Все значки" }, { "q8pp_search", "поиск по названию" }, { "q8pp_save", "Сохранить" }, { "q8pp_cancel", "Отмена" }, { "q8pp_mouse_rest", "остальное — мышью" }, { "q8pp_pick", "щелчок — выбрать" }, { "q8pp_back", "Назад" }, { "q8pp_tab_all", "Все" }, { "q8pp_tab_places", "Места" }, { "q8pp_tab_trophies", "Трофеи" }, { "q8pp_tab_gear", "Орудия" }, { "q8pp_tab_food", "Еда" }, { "q8pp_tab_resources", "Ресурсы" }, { "q8pp_tab_buildings", "Постройки" }, { "q8pp_icon_house", "Дом" }, { "q8pp_icon_fire", "Костёр" }, { "q8pp_icon_hammer", "Молот" }, { "q8pp_icon_trader", "Торговец" }, { "q8pp_icon_boss", "Босс" }, { "q8pp_icon_death", "Череп" }, { "q8pp_icon_bogwitch_camp", "Котёл" }, { "q8pp_icon_mysteriousplace2", "Пещера" }, { "q8pp_icon_start", "Старт" }, { "q8pp_icon_memorialplace", "Рунный камень" }, { "q8pp_icon_bed", "Кровать" }, { "q8pp_icon_hildir_wagon", "Повозка" }, { "q8pp_icon_portal", "Портал" }, { "q8pp_icon_pin", "Точка" }, { "q8pp_icon_hildir", "Хильдир" }, { "q8pp_icon_hildir_dress", "Рубаха" }, { "q8pp_icon_hildir1", "Вопрос" }, { "q8pp_icon_hildir2", "Вопрос" }, { "q8pp_icon_hildir3", "Вопрос" }, { "q8pp_icon_upgradestation", "Статуя" } }); } } internal static class PortalHover { internal struct Target { public PortalList.Entry Entry; public string Name; public float Distance; public int Group; public string Owner; public string Key; public bool Favorite; } private static string sourceKey; private static string choiceFor; private static string choice; private static string arrivedAt; private static string arrivedFrom; private static readonly List<Target> targets = new List<Target>(); private static ZDOID targetsFor = ZDOID.None; private static int targetsVersion = -1; private static long targetsMe; private static int targetsMemory = -1; private static int openFrame = -1; private static TeleportWorld openPortal; private static ZDO openZdo; internal static IReadOnlyList<Target> Targets => targets; internal static void OnGameStart() { //IL_001e: 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) sourceKey = (choiceFor = (choice = (arrivedAt = (arrivedFrom = null)))); targetsFor = ZDOID.None; targetsVersion = -1; targetsMemory = -1; TripMemory.Reset(); } internal static void Update() { if (!ListOpen()) { return; } int num = 0; float mouseScrollWheel = ZInput.GetMouseScrollWheel(); if (mouseScrollWheel > 0f) { num = -1; } else if (mouseScrollWheel < 0f) { num = 1; } if (ZInput.IsGamepadActive() && !ZInput.GetButton("JoyAltKeys")) { if (ZInput.GetButtonDown("JoyHotbarLeft")) { num = -1; } else if (ZInput.GetButtonDown("JoyHotbarRight")) { num = 1; } } if (num != 0 && targets.Count > 0) { int index = (SelectedIndex() + num + targets.Count) % targets.Count; choiceFor = sourceKey; choice = targets[index].Key; } } internal static bool Hovered(out TeleportWorld portal, out ZDO zdo) { Refresh(); portal = openPortal; zdo = openZdo; if ((Object)(object)portal != (Object)null) { return zdo != null; } return false; } internal static bool ListOpen() { if (Hovered(out var _, out var zdo)) { return PrepareTargets(zdo) > 0; } return false; } internal static float CameraScrollWheel() { if (!ListOpen()) { return ZInput.GetMouseScrollWheel(); } return 0f; } internal static bool HasTargets(ZNetView view) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) ZDO val = (((Object)(object)view != (Object)null) ? view.GetZDO() : null); if (val != null) { return PortalList.HasOtherThan(val.m_uid); } return false; } internal static int PrepareTargets(ZDO zdo) { //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_0060: 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_0085: Unknown result type (might be due to invalid IL or missing references) long num = (((Object)(object)Player.m_localPlayer != (Object)null) ? Player.m_localPlayer.GetPlayerID() : 0); if (zdo.m_uid == targetsFor && PortalList.Version == targetsVersion && num == targetsMe && TripMemory.Version == targetsMemory) { return targets.Count; } sourceKey = TripMemory.KeyOf(zdo.GetPosition()); string favorite = TripMemory.FavoriteOf(sourceKey); targetsFor = zdo.m_uid; targetsVersion = PortalList.Version; targetsMe = num; targetsMemory = TripMemory.Version; BuildTargets(zdo, num, targets); int num2 = ((favorite != null) ? targets.FindIndex((Target t) => t.Key == favorite) : (-1)); if (num2 >= 0) { Target item = targets[num2]; item.Favorite = true; targets.RemoveAt(num2); targets.Insert(0, item); } return targets.Count; } internal static List<Target> SortedTargets(ZDO zdo) { List<Target> list = new List<Target>(); BuildTargets(zdo, ((Object)(object)Player.m_localPlayer != (Object)null) ? Player.m_localPlayer.GetPlayerID() : 0, list); return list; } private static void BuildTargets(ZDO zdo, long me, List<Target> into) { //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) //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_005f: 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_00c0: Unknown result type (might be due to invalid IL or missing references) into.Clear(); Vector3 position = zdo.GetPosition(); foreach (PortalList.Entry entry in PortalList.Entries) { if (!(entry.Id == zdo.m_uid)) { into.Add(new Target { Entry = entry, Name = CleanName(entry.Name), Distance = Utils.DistanceXZ(position, entry.Position), Group = ((me == 0L || entry.OwnerId != me) ? (PortalMeta.IsPublic(entry.OwnerId) ? 1 : (string.IsNullOrEmpty(entry.OwnerName) ? 3 : 2)) : 0), Owner = (entry.OwnerName ?? ""), Key = TripMemory.KeyOf(entry.Position) }); } } into.Sort(CompareTargets); } private static int CompareTargets(Target a, Target b) { //IL_00e6: Unknown result type (might be due to invalid IL or missing references) if (a.Group != b.Group) { return a.Group.CompareTo(b.Group); } if (a.Group == 2) { int num = string.Compare(a.Owner, b.Owner, StringComparison.CurrentCultureIgnoreCase); if (num != 0) { return num; } if (a.Entry.OwnerId != b.Entry.OwnerId) { return a.Entry.OwnerId.CompareTo(b.Entry.OwnerId); } } bool flag = a.Name.Length > 0; bool flag2 = b.Name.Length > 0; if (flag != flag2) { if (!flag) { return 1; } return -1; } if (flag) { int num2 = string.Compare(a.Name, b.Name, StringComparison.CurrentCultureIgnoreCase); if (num2 != 0) { return num2; } } int num3 = a.Distance.CompareTo(b.Distance); if (num3 == 0) { return ((ZDOID)(ref a.Entry.Id)).CompareTo(b.Entry.Id); } return num3; } internal static int SelectedIndex() { string to = null; if (sourceKey != null) { if (choiceFor == sourceKey) { to = choice; } else { if (targets.Count > 0 && targets[0].Favorite) { return 0; } if (!TripMemory.TryGet(sourceKey, out to) && arrivedAt == sourceKey) { to = arrivedFrom; } } } if (to != null) { for (int i = 0; i < targets.Count; i++) { if (targets[i].Key == to) { return i; } } } return 0; } internal static bool Teleport(TeleportWorld portal, ZDO zdo, Player player) { //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: 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_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: 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_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer) { return false; } if (PrepareTargets(zdo) == 0) { ((Character)player).Message((MessageType)2, PortalList.Received ? "$q8pp_none" : "$q8pp_loading", 0, (Sprite)null, false); return true; } Target target = targets[SelectedIndex()]; PortalList.Entry entry = target.Entry; string text = sourceKey; if (ZoneSystem.instance.GetGlobalKey((GlobalKeys)32)) { ((Character)player).Message((MessageType)2, "$msg_blocked", 0, (Sprite)null, false); return true; } float num = default(float); if (ZoneSystem.instance.GetGlobalKey((GlobalKeys)33) && (RandEventSystem.instance.GetBossEvent() != null || (ZoneSystem.instance.GetGlobalKey((GlobalKeys)47, ref num) && num > 0f))) { ((Character)player).Message((MessageType)2, "$msg_blockedbyboss", 0, (Sprite)null, false); return true; } if (!((Humanoid)player).IsTeleportable(portal.m_allowAllItems)) { ((Character)player).Message((MessageType)2, "$msg_noteleport", 0, (Sprite)null, false); return true; } Vector3 val = entry.Position + entry.Rotation * Vector3.forward * portal.m_exitDistance + Vector3.up; if (!((Character)player).TeleportTo(val, entry.Rotation, true)) { return true; } Game.instance.IncrementPlayerStat((PlayerStatType)15, 1f, false); PortalPickerPlugin.Log.LogInfo((object)($"Teleporting {player.GetPlayerName()} from portal {zdo.m_uid} to {entry.Id} " + "\"" + CleanName(entry.Name) + "\"")); TripMemory.Remember(text, target.Key); arrivedAt = target.Key; arrivedFrom = text; choiceFor = null; return true; } internal static bool Configure(TeleportWorld portal, Humanoid human) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) bool flag = PrivateArea.CheckAccess(((Component)portal).transform.position, 0f, true, false); if (PortalPanel.Working) { PortalPanel.Open(portal, flag); } else if (!flag) { ((Character)human).Message((MessageType)2, "$piece_noaccess", 0, (Sprite)null, false); } else { TextInput.instance.RequestText((TextReceiver)(object)portal, "$piece_portal_tag", PortalPickerPlugin.NameLength.Value); } return true; } internal static string FallbackText(ZDO zdo) { string text = CleanName(zdo.GetString(ZDOVars.s_tag, "")); string text2 = ((text.Length > 0) ? Localization.instance.Localize("$q8pp_header").Replace("{0}", text) : Localization.instance.Localize("$q8pp_header_unnamed")); if (PrepareTargets(zdo) == 0) { return text2 + "\n" + Localization.instance.Localize(PortalList.Received ? "$q8pp_none" : "$q8pp_loading"); } Target target = targets[SelectedIndex()]; string text3 = ((target.Name.Length > 0) ? target.Name : Localization.instance.Localize("$q8pp_unnamed")); return text2 + "\n<color=yellow><b>» " + text3 + "</b></color> " + WheelHud.FormatDistance(target.Distance) + Localization.instance.Localize("\n[<color=yellow><b>$KEY_Use</b></color>] $q8pp_go [<color=yellow><b>$q8pp_wheel</b></color>] $q8pp_choose"); } internal static string CleanName(string name) { if (!string.IsNullOrEmpty(name)) { return StringExtensionMethods.RemoveRichTextTags(name).Trim(); } return ""; } private static void Refresh() { if (openFrame == Time.frameCount) { return; } openFrame = Time.frameCount; openPortal = null; openZdo = null; Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead() || ((Character)localPlayer).IsTeleporting() || UiOpen()) { return; } GameObject hoverObject = ((Humanoid)localPlayer).GetHoverObject(); TeleportWorld val = (((Object)(object)hoverObject != (Object)null) ? hoverObject.GetComponentInParent<TeleportWorld>() : null); if (!((Object)(object)val == (Object)null)) { ZNetView component = ((Component)val).GetComponent<ZNetView>(); ZDO val2 = (((Object)(object)component != (Object)null) ? component.GetZDO() : null); if (val2 != null) { openPortal = val; openZdo = val2; } } } private static bool UiOpen() { if (!InventoryGui.IsVisible() && !Menu.IsVisible() && !TextInput.IsVisible() && !Minimap.IsOpen() && !Console.IsVisible() && (!((Object)(object)Chat.instance != (Object)null) || !Chat.instance.HasFocus()) && !StoreGui.IsVisible() && !Hud.InRadial() && !Hud.IsPieceSelectionVisible() && !GameCamera.InFreeFly() && (!((Object)(object)TextViewer.instance != (Object)null) || !TextViewer.instance.IsVisible())) { return PortalPanel.IsOpen; } return true; } } public static class PortalList { public struct Entry { public ZDOID Id; public string Name; public Vector3 Position; public Quaternion Rotation; public string Icon; public int Color; public long OwnerId; public string OwnerName; } private const string RpcPortals = "Q8PP_Portals"; private const string RpcRequest = "Q8PP_Request"; private const int Format = 2; private const float ScanInterval = 2f; private const float RequestInterval = 5f; private static List<Entry> entries = new List<Entry>(); private static List<KeyValuePair<long, string>> players = new List<KeyValuePair<long, string>>(); private static ulong lastHash; private static float nextScan; private static float nextRequest; private static ZPackage lastPackage; public static IReadOnlyList<Entry> Entries => entries; public static IReadOnlyList<KeyValuePair<long, string>> Players => players; public static int Version { get; private set; } public static bool Received { get; private set; } internal static void OnGameStart() { entries = new List<Entry>(); players = new List<KeyValuePair<long, string>>(); Version++; Received = false; lastHash = 0uL; nextScan = 0f; nextRequest = 0f; lastPackage = null; ZRoutedRpc.instance.Register<ZPackage>("Q8PP_Portals", (Action<long, ZPackage>)RPC_Portals); ZRoutedRpc.instance.Register("Q8PP_Request", (Action<long>)RPC_Request); } internal static void Update() { if ((Object)(object)ZNet.instance == (Object)null || ZRoutedRpc.instance == null || ZDOMan.instance == null || (Object)(object)Game.instance == (Object)null) { return; } if (ZNet.instance.IsServer()) { if (Time.time >= nextScan) { Scan(); } } else if (!Received && (Object)(object)Player.m_localPlayer != (Object)null && Time.time >= nextRequest) { ZNetPeer serverPeer = ZNet.instance.GetServerPeer(); if (serverPeer != null) { nextRequest = Time.time + 5f; ZRoutedRpc.instance.InvokeRoutedRPC(serverPeer.m_uid, "Q8PP_Request", Array.Empty<object>()); } } } public static bool HasOtherThan(ZDOID id) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) foreach (Entry entry in entries) { if (entry.Id != id) { return true; } } return false; } public static bool TryGet(ZDOID id, out Entry found) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) foreach (Entry entry in entries) { if (entry.Id == id) { found = entry; return true; } } found = default(Entry); return false; } public static void Scan() { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: 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) nextScan = Time.time + 2f; PlayerNames.Update(); List<ZDO> portalList = ZDOMan.instance.GetPortalList(); List<Entry> list = new List<Entry>(portalList.Count); foreach (ZDO item in portalList) { if (item != null && !((ZDOID)(ref item.m_uid)).IsNone()) { long num = PortalMeta.Owner(item); list.Add(new Entry { Id = item.m_uid, Name = item.GetString(ZDOVars.s_tag, ""), Position = item.GetPosition(), Rotation = item.GetRotation(), Icon = PortalMeta.Icon(item), Color = PortalMeta.ColorCode(item), OwnerId = num, OwnerName = PlayerNames.NameOf(num) }); } } list.Sort((Entry a, Entry b) => ((ZDOID)(ref a.Id)).CompareTo(b.Id)); List<KeyValuePair<long, string>> list2 = new List<KeyValuePair<long, string>>(PlayerNames.All); list2.Sort((KeyValuePair<long, string> a, KeyValuePair<long, string> b) => a.Key.CompareTo(b.Key)); ulong num2 = Hash(list, list2); if (!Received || num2 != lastHash) { lastHash = num2; entries = list; players = list2; Version++; Received = true; lastPackage = Pack(list, list2); int count = ZNet.instance.GetConnectedPeers().Count; if (count > 0) { ZRoutedRpc.instance.InvokeRoutedRPC(0L, "Q8PP_Portals", new object[1] { lastPackage }); } PortalPickerPlugin.Log.LogInfo((object)$"{list.Count} portals in the world, {list2.Count} player names, list sent to {count} players"); } } public static ZPackage Pack(List<Entry> list, List<KeyValuePair<long, string>> names) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_002f: 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_005c: Unknown result type (might be due to invalid IL or missing references) ZPackage val = new ZPackage(); val.Write(2); val.Write(list.Count); foreach (Entry item in list) { val.Write(item.Id); val.Write(item.Name ?? ""); val.Write(item.Position); val.Write(item.Rotation); val.Write(item.Icon ?? ""); val.Write(item.Color); val.Write(item.OwnerId); val.Write(item.OwnerName ?? ""); } val.Write(names.Count); foreach (KeyValuePair<long, string> name in names) { val.Write(name.Key); val.Write(name.Value ?? ""); } return val; } public static bool Unpack(ZPackage pkg, out List<Entry> list, out List<KeyValuePair<long, string>> names) { //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_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0077: 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) list = null; names = null; int num = pkg.ReadInt(); if (num != 2) { PortalPickerPlugin.Log.LogWarning((object)$"Portal list of unknown format {num} ignored"); return false; } int num2 = pkg.ReadInt(); list = new List<Entry>(num2); for (int i = 0; i < num2; i++) { list.Add(new Entry { Id = pkg.ReadZDOID(), Name = pkg.ReadString(), Position = pkg.ReadVector3(), Rotation = pkg.ReadQuaternion(), Icon = pkg.ReadString(), Color = PortalMeta.NormalizeColor(pkg.ReadInt()), OwnerId = pkg.ReadLong(), OwnerName = pkg.ReadString() }); } int num3 = pkg.ReadInt(); names = new List<KeyValuePair<long, string>>(num3); for (int j = 0; j < num3; j++) { names.Add(new KeyValuePair<long, string>(pkg.ReadLong(), pkg.ReadString())); } return true; } private static void RPC_Portals(long sender, ZPackage pkg) { ZNetPeer val = (((Object)(object)ZNet.instance != (Object)null) ? ZNet.instance.GetServerPeer() : null); if (val != null && !ZNet.instance.IsServer() && sender == val.m_uid && Unpack(pkg, out var list, out var names)) { entries = list; players = names; Version++; if (!Received) { PortalPickerPlugin.Log.LogInfo((object)$"Got the list of {list.Count} portals from the server"); } Received = true; } } private static void RPC_Request(long sender) { if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer()) { if (lastPackage == null) { Scan(); } ZRoutedRpc.instance.InvokeRoutedRPC(sender, "Q8PP_Portals", new object[1] { lastPackage }); } } private static ulong Hash(List<Entry> list, List<KeyValuePair<long, string>> names) { //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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0092: 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_00ce: Unknown result type (might be due to invalid IL or missing references) ulong num = 14695981039346656037uL; foreach (Entry item in list) { Entry current = item; ulong h = num; ZDOID id = current.Id; num = Mix(h, (ulong)((ZDOID)(ref id)).UserID); num = Mix(num, ((ZDOID)(ref current.Id)).ID); num = Mix(num, current.Name); num = Mix(num, (ulong)Mathf.RoundToInt(current.Position.x * 10f)); num = Mix(num, (ulong)Mathf.RoundToInt(current.Position.y * 10f)); num = Mix(num, (ulong)Mathf.RoundToInt(current.Position.z * 10f)); num = Mix(num, (ulong)Mathf.RoundToInt(current.Rotation.y * 1000f)); num = Mix(num, (ulong)Mathf.RoundToInt(current.Rotation.w * 1000f)); num = Mix(num, current.Icon); num = Mix(num, (ulong)current.Color); num = Mix(num, (ulong)current.OwnerId); num = Mix(num, current.OwnerName); } num = Mix(num, (ulong)list.Count); foreach (KeyValuePair<long, string> name in names) { num = Mix(num, (ulong)name.Key); num = Mix(num, name.Value); } return Mix(num, (ulong)names.Count); } private static ulong Mix(ulong h, string text) { string text2 = text ?? ""; foreach (char c in text2) { h = Mix(h, c); } return Mix(h, 65535uL); } private static ulong Mix(ulong h, ulong value) { for (int i = 0; i < 8; i++) { h ^= (value >> i * 8) & 0xFF; h *= 1099511628211L; } return h; } } internal static class PortalMeta { private const string Rpc = "Q8PP_SetMeta"; private static readonly int IconKey = StringExtensionMethods.GetStableHashCode("q8pp_icon"); private static readonly int ColorKey = StringExtensionMethods.GetStableHashCode("q8pp_color"); private static readonly int OwnerKey = StringExtensionMethods.GetStableHashCode("q8pp_owner"); internal static readonly Color[] Palette = (Color[])(object)new Color[9] { Color32.op_Implicit(new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue)), Color32.op_Implicit(new Color32(byte.MaxValue, (byte)216, (byte)74, byte.MaxValue)), Color32.op_Implicit(new Color32(byte.MaxValue, (byte)140, (byte)40, byte.MaxValue)), Color32.op_Implicit(new Color32((byte)230, (byte)70, (byte)58, byte.MaxValue)), Color32.op_Implicit(new Color32((byte)240, (byte)110, (byte)180, byte.MaxValue)), Color32.op_Implicit(new Color32((byte)160, (byte)110, (byte)240, byte.MaxValue)), Color32.op_Implicit(new Color32((byte)80, (byte)136, (byte)247, byte.MaxValue)), Color32.op_Implicit(new Color32((byte)60, (byte)205, (byte)200, byte.MaxValue)), Color32.op_Implicit(new Color32((byte)95, (byte)205, (byte)90, byte.MaxValue)) }; internal const int CustomFlag = 16777216; internal const long PublicOwner = long.MinValue; internal static bool IsPublic(long owner) { return owner == long.MinValue; } internal static string Icon(ZDO zdo) { return zdo.GetString(IconKey, ""); } internal static int ColorCode(ZDO zdo) { return NormalizeColor(zdo.GetInt(ColorKey, 0)); } internal static long Owner(ZDO zdo) { long num = zdo.GetLong(OwnerKey, 0L); if (num == 0L) { return zdo.GetLong(ZDOVars.s_creator, 0L); } return num; } internal static bool IsCustom(int code) { return (code & -16777216) == 16777216; } internal static int NormalizeColor(int code) { if (!IsCustom(code) && (code < 0 || code >= Palette.Length)) { return 0; } return code; } internal static Color ColorOf(int code) { //IL_002e: 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) if (IsCustom(code)) { return Color32.op_Implicit(new Color32((byte)(code >> 16), (byte)(code >> 8), (byte)code, byte.MaxValue)); } return Palette[NormalizeColor(code)]; } internal static int CodeOf(Color32 c) { //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_0014: 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_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0054: 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_0067: 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_0029: 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) for (int i = 0; i < Palette.Length; i++) { Color32 val = Color32.op_Implicit(Palette[i]); if (val.r == c.r && val.g == c.g && val.b == c.b) { return i; } } return 0x1000000 | (c.r << 16) | (c.g << 8) | c.b; } internal static void Register(ZNetView view) { view.Register<ZPackage>("Q8PP_SetMeta", (Action<long, ZPackage>)delegate(long sender, ZPackage pkg) { Apply(view, pkg); }); } internal static void Send(ZNetView view, string name, string icon, int color, long owner) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown //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) if (!((Object)(object)view == (Object)null) && view.IsValid()) { ZPackage val = new ZPackage(); val.Write(name ?? ""); val.Write(((object)((IUser)PlatformManager.DistributionPlatform.LocalUser).PlatformUserID/*cast due to .constrained prefix*/).ToString()); val.Write(icon ?? ""); val.Write(NormalizeColor(color)); val.Write(owner); view.InvokeRPC("Q8PP_SetMeta", new object[1] { val }); } } private static void Apply(ZNetView view, ZPackage pkg) { if (!((Object)(object)view == (Object)null) && view.IsValid() && view.IsOwner()) { string text = pkg.ReadString(); string text2 = pkg.ReadString(); string text3 = pkg.ReadString(); int num = NormalizeColor(pkg.ReadInt()); long num2 = pkg.ReadLong(); ZDO zDO = view.GetZDO(); zDO.Set(ZDOVars.s_tag, text); zDO.Set(ZDOVars.s_tagauthor, text2); zDO.Set(IconKey, text3); zDO.Set(ColorKey, num, false); if (num2 != 0L) { zDO.Set(OwnerKey, num2); } } } } internal static class PortalPanel { private sealed class IconCell { public RectTransform Rect; public Image Edge; public Image Icon; public TextMeshProUGUI Mark; public IconDef Def; public string Key; public bool Hover; } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Comparison<KeyValuePair<long, string>> <>9__82_0; public static Converter<int, string> <>9__110_0; public static UnityAction<string> <>9__115_0; public static UnityAction<int> <>9__115_1; public static UnityAction <>9__115_2; public static UnityAction <>9__115_3; public static UnityAction <>9__115_4; public static UnityAction<int> <>9__117_0; public static UnityAction<string> <>9__119_0; internal int <FillOwners>b__82_0(KeyValuePair<long, string> a, KeyValuePair<long, string> b) { return string.Compare(a.Value, b.Value, StringComparison.CurrentCultureIgnoreCase); } internal string <RememberRecentColor>b__110_0(int c) { return (c & 0xFFFFFF).ToString("X6", CultureInfo.InvariantCulture); } internal void <BuildMain>b__115_0(string _) { RefreshPreview(); } internal void <BuildMain>b__115_1(int i) { if (i >= 0 && i < ownerIds.Count) { pickedOwner = ownerIds[i]; RefreshPreview(); } } internal void <BuildMain>b__115_2() { if (!readOnly) { ShowPalette(show: true); } } internal void <BuildMain>b__115_3() { Close(save: false); } internal void <BuildMain>b__115_4() { Close(save: true); } internal void <BuildFavoriteDropdown>b__117_0(int i) { if (i >= 0 && i < favoriteKeys.Count) { pickedFavorite = favoriteKeys[i]; RefreshFavoriteCaption(); } } internal void <BuildAll>b__119_0(string _) { Filter(); } } private const int RecentShown = 8; private const int RecentKept = 16; private const int Cols = 10; private const int VisibleRows = 6; private const float Cell = 46f; private const float Gap = 7f; private const float Pitch = 53f; private const int ConvertPerFrame = 8; private const float MaxDistance = 8f; private const float PaletteX = 538f; private const int RecentColorsShown = 10; private const float SquareSize = 250f; private const float StripWidth = 24f; private static GameObject root; private static GameObject mainPanel; private static GameObject allPanel; private static GameObject palettePanel; private static bool blocking; private static bool faulted; private static InputField nameField; private static Dropdown ownerDropdown; private static readonly List<long> ownerIds = new List<long>(); private static readonly IconCell[] row = new IconCell[10]; private static readonly Image[] swatches = (Image[])(object)new Image[9]; private static Image paletteButton; private static Image paletteBadge; private static Image swatchRing; private static Image previewIcon; private static TextMeshProUGUI previewText; private static Dropdown favoriteDropdown; private static Image favoriteStar; private static readonly List<string> favoriteKeys = new List<string>(); private static readonly List<Color> favoriteColors = new List<Color>(); private static TextMeshProUGUI mainHint; private static InputField search; private static IconCategory tab = IconCategory.All; private static readonly TextMeshProUGUI[] tabLabels = (TextMeshProUGUI[])(object)new TextMeshProUGUI[7]; private static readonly Image[] tabMarks = (Image[])(object)new Image[7]; private static ScrollRect scroll; private static RectTransform viewport; private static RectTransform content; private static readonly IconCell[] pool = new IconCell[70]; private static readonly List<IconDef> filtered = new List<IconDef>(); private static RectTransform tooltip; private static TextMeshProUGUI tooltipText; private static int firstRow = -1; private static ColorField square; private static ColorField strip; private static RectTransform squareMark; private static RectTransform stripMark; private static InputField hexField; private static Image paletteSample; private static Image palettePreviewIcon; private static TextMeshProUGUI palettePreviewText; private static readonly Image[] recentSwatches = (Image[])(object)new Image[10]; private static readonly List<int> recentCodes = new List<int>(); private static TextMeshProUGUI recentCaption; private static float hue; private static float sat; private static float val; private static Color32 paletteColor; private static TeleportWorld portal; private static ZNetView view; private static string pickedIcon = ""; private static int pickedColor; private static long pickedOwner; private static long startOwner; private static bool readOnly; private static string portalKey; private static string pickedFavorite; private static string shownFavorite; internal static bool IsOpen { get { if ((Object)(object)root != (Object)null) { return root.activeSelf; } return false; } } internal static bool Working => !faulted; internal static void Reset() { if (blocking) { GUIManager.BlockInput(false); } blocking = false; faulted = false; if ((Object)(object)root != (Object)null) { Object.Destroy((Object)(object)root); } root = null; portal = null; view = null; } internal static void Open(TeleportWorld target, bool canEdit) { if (faulted) { return; } try { OpenCore(target, canEdit); } catch (Exception ex) { faulted = true; Close(save: false); PortalPickerPlugin.Log.LogError((object)("Portal window is switched off until you re-enter the world: " + ex)); } } internal static void Update() { if (!IsOpen) { return; } try { UpdateCore(); } catch (Exception ex) { faulted = true; Close(save: false); PortalPickerPlugin.Log.LogError((object)("Portal window is switched off until you re-enter the world: " + ex)); } } private static void OpenCore(TeleportWorld target, bool canEdit) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) view = ((Component)target).GetComponent<ZNetView>(); ZDO val = (((Object)(object)view != (Object)null) ? view.GetZDO() : null); if (val != null) { if ((Object)(object)root == (Object)null) { Build(); } portal = target; readOnly = !canEdit; portalKey = TripMemory.KeyOf(val.GetPosition()); pickedIcon = PortalMeta.Icon(val); pickedColor = PortalMeta.ColorCode(val); startOwner = (pickedOwner = PortalMeta.Owner(val)); nameField.characterLimit = PortalPickerPlugin.NameLength.Value; nameField.text = val.GetString(ZDOVars.s_tag, ""); ((Selectable)nameField).interactable = !readOnly; FillOwners(); if (readOnly) { ((Selectable)ownerDropdown).interactable = false; } RefreshRow(); RefreshSwatches(); FillFavorites(val); ((TMP_Text)mainHint).text = Localization.instance.Localize(readOnly ? "$q8pp_ward_favorite_only" : "<b>Enter</b> — $q8pp_keys_save <b>Esc</b> — $q8pp_keys_cancel"); allPanel.SetActive(false); palettePanel.SetActive(false); mainPanel.SetActive(true); root.SetActive(true); if (!blocking) { GUIManager.BlockInput(true); blocking = true; } if (!readOnly) { ((Selectable)nameField).Select(); nameField.ActivateInputField(); } } } private static void Close(bool save) { if (save && (Object)(object)view != (Object)null && view.IsValid()) { if (!readOnly) { string text = (nameField.text ?? "").Trim(); if (text.Length > PortalPickerPlugin.NameLength.Value) { text = text.Substring(0, PortalPickerPlugin.NameLength.Value); } PortalMeta.Send(view, text, pickedIcon, pickedColor, (pickedOwner != startOwner) ? pickedOwner : 0); RememberRecent(pickedIcon); RememberRecentColor(pickedColor); } if (pickedFavorite != shownFavorite) { TripMemory.SetFavorite(portalKey, pickedFavorite); } } if ((Object)(object)root != (Object)null) { root.SetActive(false); } if (blocking) { GUIManager.BlockInput(false); blocking = false; } portal = null; view = null; } private static void UpdateCore() { //IL_004b: 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_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_0173: Unknown result type (might be due to invalid IL or missing references) //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_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: 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) Player localPlayer = Player.m_localPlayer; if ((Object)(object)portal == (Object)null || (Object)(object)view == (Object)null || !view.IsValid() || (Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead() || ((Character)localPlayer).IsTeleporting() || Vector3.Distance(((Component)localPlayer).transform.position, ((Component)portal).transform.position) > 8f) { Close(save: false); return; } if (allPanel.activeSelf) { if (ZInput.GetKeyDown((KeyCode)27, true)) { ShowAll(show: false); return; } float mouseScrollWheel = ZInput.GetMouseScrollWheel(); if (mouseScrollWheel != 0f && RectTransformUtility.RectangleContainsScreenPoint(viewport, Vector2.op_Implicit(ZInput.pointerPosition), EventCamera())) { Rect rect = content.rect; float height = ((Rect)(ref rect)).height; rect = viewport.rect; float num = Mathf.Max(0f, height - ((Rect)(ref rect)).height); Vector2 anchoredPosition = content.anchoredPosition; anchoredPosition.y = Mathf.Clamp(anchoredPosition.y + ((mouseScrollWheel < 0f) ? 53f : (-53f)), 0f, num); content.anchoredPosition = anchoredPosition; } LayoutPool(force: false); ConvertVisible(); return; } if (palettePanel.activeSelf) { if (ZInput.GetKeyDown((KeyCode)27, true)) { ShowPalette(show: false); } else if (ZInput.GetKeyDown((KeyCode)13, true) || ZInput.GetKeyDown((KeyCode)271, true)) { PickColor(PortalMeta.CodeOf(paletteColor)); } return; } TintFavoriteIcons(); if (ZInput.GetKeyDown((KeyCode)27, true)) { if (!HideOpenList(ownerDropdown) && !HideOpenList(favoriteDropdown)) { Close(save: false); } } else if (ZInput.GetKeyDown((KeyCode)13, true) || ZInput.GetKeyDown((KeyCode)271, true)) { Close(save: true); } } private static void FillOwners() { //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Expected O, but got Unknown //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Expected O, but got Unknown long num = (((Object)(object)Player.m_localPlayer != (Object)null) ? Player.m_localPlayer.GetPlayerID() : 0); Dictionary<long, string> dictionary = new Dictionary<long, string>(); foreach (KeyValuePair<long, string> player in PortalList.Players) { dictionary[player.Key] = player.Value; } if (num != 0L && (Object)(object)Player.m_localPlayer != (Object)null) { dictionary[num] = Player.m_localPlayer.GetPlayerName(); } if (!PortalMeta.IsPublic(startOwner) && !dictionary.ContainsKey(startOwner)) { dictionary[startOwner] = Localization.instance.Localize("$q8pp_unknown_owner"); } List<KeyValuePair<long, string>> list = new List<KeyValuePair<long, string>>(dictionary); list.Sort((KeyValuePair<long, string> a, KeyValuePair<long, string> b) => string.Compare(a.Value, b.Value, StringComparison.CurrentCultureIgnoreCase)); ownerIds.Clear(); ownerIds.Add(long.MinValue); List<OptionData> list2 = new List<OptionData> { new OptionData(Localization.instance.Localize("$q8pp_owner_public")) }; int valueWithoutNotify = 0; foreach (KeyValuePair<long, string> item in list) { if (item.Key == startOwner) { valueWithoutNotify = ownerIds.Count; } ownerIds.Add(item.Key); list2.Add(new OptionData(item.Value)); } ownerDropdown.ClearOptions(); ownerDropdown.AddOptions(list2); ownerDropdown.SetValueWithoutNotify(valueWithoutNotify); ownerDropdown.RefreshShownValue(); ((Selectable)ownerDropdown).interactable = true; } private static List<string> Recent() { List<string> list = new List<string>(); string[] array = (PortalPickerPlugin.RecentIcons.Value ?? "").Split(new char[1] { ',' }); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length > 0 && !list.Contains(text) && IconLibrary.Find(text) != null) { list.Add(text); } } array = IconLibrary.DefaultRecent; foreach (string text2 in array) { if (list.Count >= 8) { break; } if (!list.Contains(text2) && IconLibrary.Find(text2) != null) { list.Add(text2); } } return list; } private static void RememberRecent(string key) { if (string.IsNullOrEmpty(key)) { return; } List<string> list = new List<string> { key }; foreach (string item in Recent()) { if (item != key && list.Count < 16) { list.Add(item); } } PortalPickerPlugin.RecentIcons.Value = string.Join(",", list); } private static void RefreshRow() { List<string> list = Recent(); List<string> list2 = new List<string>(); if (!string.IsNullOrEmpty(pickedIcon) && IconLibrary.Find(pickedIcon) != null) { list2.Add(pickedIcon); } foreach (string item in list) { if (list2.Count >= 8) { break; } if (item != pickedIcon) { list2.Add(item); } } for (int i = 0; i < 8; i++) { IconCell iconCell = row[i + 1];