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 DrakesTelemarker v0.1.0
DrakesTelemarker.dll
Decompiled a month agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Serialization.Json; using System.Runtime.Versioning; using System.Text; using BepInEx; using HarmonyLib; using Jotunn.Entities; using Jotunn.Managers; using Microsoft.CodeAnalysis; using Splatform; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("DrakesTelemarker")] [assembly: AssemblyDescription("Per-world console warp bookmarks (10 slots).")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("DrakeMods")] [assembly: AssemblyProduct("DrakesTelemarker")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("5DF97E86-BF46-46C5-894F-6B2D80EA6645")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")] [assembly: AssemblyVersion("0.1.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.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 DrakesTelemarker { [BepInPlugin("com.drakemods.DrakesTelemarker", "DrakesTelemarker", "0.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class DrakesTelemarkerPlugin : BaseUnityPlugin { private sealed class TelemarkCommand : ConsoleCommand { private readonly DrakesTelemarkerPlugin _plugin; public override string Name => "telemark"; public override string Help => "Not a cheat: prints usage. Subcommands list/set/recall/clear require cheat access — run with no args."; public override bool IsCheat => false; public TelemarkCommand(DrakesTelemarkerPlugin plugin) { _plugin = plugin; } public override List<string> CommandOptionList() { return BuildTelemarkTabCompletions(); } public override void Run(string[] args) { RouteTelemark(_plugin, args); } } private sealed class SetMarkCommand : ConsoleCommand { private readonly DrakesTelemarkerPlugin _plugin; public override string Name => "set"; public override string Help => $"Shortcut for telemark set mark <1-{10}>"; public override bool IsCheat => false; public SetMarkCommand(DrakesTelemarkerPlugin plugin) { _plugin = plugin; } public override List<string> CommandOptionList() { return BuildMarkAliasTabCompletions(); } public override void Run(string[] args) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0062: 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) if (!CanUseTelemarkerCheats()) { Notify("Need cheat access (devcommands or server admin). Run telemark for help."); return; } if (!TryParseMarkSlotArgs(args, out int slot, out string usageError)) { Notify(usageError); return; } Player localPlayerOrNotify = GetLocalPlayerOrNotify(); if (localPlayerOrNotify != null) { Vector3 position = ((Component)localPlayerOrNotify).transform.position; _plugin.TrySetSlot(slot, position, out string _); Notify($"Saved mark {slot} at {FormatVec(position)}."); } } } private sealed class RecallMarkCommand : ConsoleCommand { private readonly DrakesTelemarkerPlugin _plugin; public override string Name => "recall"; public override string Help => $"Shortcut for telemark recall mark <1-{10}>"; public override bool IsCheat => false; public RecallMarkCommand(DrakesTelemarkerPlugin plugin) { _plugin = plugin; } public override List<string> CommandOptionList() { return BuildMarkAliasTabCompletions(); } public override void Run(string[] args) { //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) if (!CanUseTelemarkerCheats()) { Notify("Need cheat access (devcommands or server admin). Run telemark for help."); return; } if (!TryParseMarkSlotArgs(args, out int slot, out string usageError)) { Notify(usageError); return; } Player localPlayerOrNotify = GetLocalPlayerOrNotify(); if (localPlayerOrNotify != null) { if (!_plugin.TryRecallSlot(slot, out Vector3 position, out string error)) { Notify(string.IsNullOrEmpty(error) ? $"Mark {slot} is empty." : error); return; } ((Component)localPlayerOrNotify).transform.position = position; Physics.SyncTransforms(); Notify($"Recalled mark {slot} -> {FormatVec(position)}."); } } } public const string ModName = "DrakesTelemarker"; public const string Version = "0.1.0"; public const string GUID = "com.drakemods.DrakesTelemarker"; internal const int SlotCount = 10; private void Awake() { TelemarkerClearDialog.RegisterForGuiRebuild(); CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new TelemarkCommand(this)); CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new SetMarkCommand(this)); CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new RecallMarkCommand(this)); TelemarkerMinimap.Init(this); ((BaseUnityPlugin)this).Logger.LogInfo((object)"DrakesTelemarker v0.1.0 loaded — type 'telemark' in console for commands."); } internal static string GetMarksFilePath() { string text = Path.Combine(Paths.ConfigPath, "DrakesTelemarker"); Directory.CreateDirectory(text); return Path.Combine(text, "TelemarkerMarks.json"); } internal static string GetWorldKey() { if ((Object)(object)ZNet.instance != (Object)null) { string worldName = ZNet.instance.GetWorldName(); if (!string.IsNullOrEmpty(worldName)) { return worldName; } } return "noworld"; } internal static string SanitizeWorldKey(string worldName) { char[] invalidFileNameChars = Path.GetInvalidFileNameChars(); foreach (char oldChar in invalidFileNameChars) { worldName = worldName.Replace(oldChar, '_'); } return string.IsNullOrEmpty(worldName) ? "world" : worldName; } internal static Player? GetLocalPlayerOrNotify() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { Notify("No local player (join a world first)."); } return localPlayer; } internal static void Notify(string message) { PrintToDeveloperConsole("[DrakesTelemarker] " + message); } private static void PrintToDeveloperConsole(string line) { try { object obj = TryGetValheimConsoleInstance(); if (obj == null) { Debug.Log((object)line); return; } MethodInfo method = obj.GetType().GetMethod("Print", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(string) }, null); if (method == null) { Debug.Log((object)line); return; } method.Invoke(obj, new object[1] { line }); } catch { Debug.Log((object)line); } } private static object? TryGetValheimConsoleInstance() { try { Type type = typeof(Player).Assembly.GetType("Console"); if (type == null) { return null; } PropertyInfo property = type.GetProperty("instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy); if (property != null) { return property.GetValue(null); } FieldInfo field = type.GetField("instance", BindingFlags.Static | BindingFlags.Public); if (field != null) { return field.GetValue(null); } return type.GetField("m_instance", BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(null); } catch { return null; } } private static void PrintMultilineToDeveloperConsole(string text) { string[] array = text.Split(new string[2] { "\r\n", "\n" }, StringSplitOptions.None); foreach (string text2 in array) { if (text2.Length > 0) { PrintToDeveloperConsole(text2); } } } internal bool TrySetSlot(int slot, Vector3 position, out string error) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) error = ""; string marksFilePath = GetMarksFilePath(); string worldKey = SanitizeWorldKey(GetWorldKey()); TelemarkerMarksDocument telemarkerMarksDocument = TelemarkerMarksDocument.Load(marksFilePath); telemarkerMarksDocument.UpsertSlot(worldKey, slot, position); TelemarkerMarksDocument.Save(marksFilePath, telemarkerMarksDocument); TelemarkerMinimap.RequestSync(); return true; } internal bool TryRecallSlot(int slot, out Vector3 position, out string error) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) position = default(Vector3); error = ""; string marksFilePath = GetMarksFilePath(); string worldKey = SanitizeWorldKey(GetWorldKey()); TelemarkerMarksDocument telemarkerMarksDocument = TelemarkerMarksDocument.Load(marksFilePath); return telemarkerMarksDocument.TryGetSlot(worldKey, slot, out position, out error); } internal bool TryClearSlot(int slot, out string error) { error = ""; string marksFilePath = GetMarksFilePath(); string worldKey = SanitizeWorldKey(GetWorldKey()); TelemarkerMarksDocument telemarkerMarksDocument = TelemarkerMarksDocument.Load(marksFilePath); if (!telemarkerMarksDocument.ClearSlot(worldKey, slot)) { error = $"Mark {slot} was already empty."; return false; } TelemarkerMarksDocument.Save(marksFilePath, telemarkerMarksDocument); TelemarkerMinimap.RequestSync(); return true; } internal bool TryClearAllSlots(out int clearedCount, out string error) { clearedCount = 0; error = ""; string marksFilePath = GetMarksFilePath(); string worldKey = SanitizeWorldKey(GetWorldKey()); TelemarkerMarksDocument telemarkerMarksDocument = TelemarkerMarksDocument.Load(marksFilePath); clearedCount = telemarkerMarksDocument.ClearAllSlotsForWorld(worldKey); if (clearedCount == 0) { error = "No marks to clear."; return false; } TelemarkerMarksDocument.Save(marksFilePath, telemarkerMarksDocument); TelemarkerMinimap.RequestSync(); return true; } internal static bool CanUseTelemarkerCheats() { if (IsDevcommandsClientFlagOn()) { return true; } try { SynchronizationManager instance = SynchronizationManager.Instance; if (instance != null && instance.PlayerIsAdmin) { return true; } } catch { } return false; } internal static bool IsDevcommandsClientFlagOn() { return ReadTerminalCheatsEnabledWithFallback(); } private static bool ReadTerminalCheatsEnabledWithFallback() { try { MethodInfo[] methods = typeof(Terminal).GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { if (methodInfo.Name != "IsCheatsEnabled" || methodInfo.ReturnType != typeof(bool) || methodInfo.GetParameters().Length != 0) { continue; } if (methodInfo.IsStatic) { if (methodInfo.Invoke(null, null) is bool result) { return result; } continue; } object obj = TryGetValheimConsoleInstance(); if (obj != null && methodInfo.Invoke(obj, null) is bool result2) { return result2; } } } catch { } return ReadTerminalCheatFlagViaReflection(); } private static bool ReadTerminalCheatFlagViaReflection() { try { object obj = TryGetValheimConsoleInstance(); FieldInfo field = typeof(Terminal).GetField("m_cheat", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null && obj != null && field.GetValue(obj) is bool result) { return result; } field = typeof(Terminal).GetField("m_cheat", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (field != null && field.IsStatic) { object value = field.GetValue(null); if (value is bool) { bool result2 = (bool)value; if (true) { return result2; } } } } catch { } return false; } internal static string[] ArgsTail(string[] args, int start) { int num = args.Length - start; if (num <= 0) { return Array.Empty<string>(); } string[] array = new string[num]; Array.Copy(args, start, array, 0, num); return array; } internal static string FormatVec(Vector3 p) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) return string.Format(CultureInfo.InvariantCulture, "({0:F1}, {1:F1}, {2:F1})", p.x, p.y, p.z); } internal static List<string> BuildTelemarkTabCompletions() { List<string> list = new List<string> { "help", "?", "list", "set", "recall", "clear", "mark", "all" }; for (int i = 1; i <= 10; i++) { list.Add(i.ToString(CultureInfo.InvariantCulture)); } return list; } internal static List<string> BuildMarkAliasTabCompletions() { List<string> list = new List<string> { "mark" }; for (int i = 1; i <= 10; i++) { list.Add(i.ToString(CultureInfo.InvariantCulture)); } return list; } internal static bool TryParseMarkSlotArgs(string[] args, out int slot, out string usageError) { slot = 0; usageError = ""; if (args == null || args.Length < 2 || !args[0].Equals("mark", StringComparison.OrdinalIgnoreCase)) { usageError = $"Usage: telemark set mark <1-{10}> | telemark recall mark <1-{10}> (aliases: set mark …, recall mark …)"; return false; } int num = 1; if (num < args.Length && args[num].Equals("mark", StringComparison.OrdinalIgnoreCase)) { num++; } if (num >= args.Length || !int.TryParse(args[num], NumberStyles.Integer, CultureInfo.InvariantCulture, out slot) || slot < 1 || slot > 10) { usageError = $"Slot must be 1-{10}."; return false; } return true; } private static void PrintTelemarkUsage() { string text = "[DrakesTelemarker] Cheat vs help:\r\n • Running telemark alone (or telemark help) is NOT a cheat — it only prints this guide.\r\n • telemark list / set / recall / clear ARE cheats — need devcommands or server admin.\r\n • Same for aliases: set mark … and recall mark … (cheat access required).\r\n\r\nCommands:\r\n telemark\r\n Show this help (always allowed).\r\n telemark list\r\n List every slot that has a saved position for this world (cheat).\r\n" + $" telemark set mark <1-{10}>\r\n" + " Save your current position into a slot (cheat).\r\n" + $" telemark recall mark <1-{10}>\r\n" + " Warp to a saved slot (cheat).\r\n" + $" telemark clear <1-{10}>\r\n" + " Opens a confirmation dialog — click Yes to erase that slot, No to cancel.\r\n telemark clear all\r\n Same dialog for wiping every mark in this world.\r\nAliases:\r\n set mark <n> Same as telemark set mark … (cheat).\r\n recall mark <n> Same as telemark recall mark … (cheat).\r\n\r\nCheat access = devcommands OR server admin (adminlist; Server Devcommands works well here).\r\nJotunn syncs admin status for PlayerIsAdmin. Open console (F5): devcommands\r\n\r\nMinimap:\r\n" + $" Numbered pins labeled Mark 1–Mark {10}. Right-click (or Ctrl+left-click) a pin to recall when cheat access matches console (devcommands / Server Devcommands admin, same as telemark recall).\r\n"; PrintMultilineToDeveloperConsole(text); } private static void RunTelemarkList() { //IL_0053: Unknown result type (might be due to invalid IL or missing references) string marksFilePath = GetMarksFilePath(); string text = SanitizeWorldKey(GetWorldKey()); TelemarkerMarksDocument telemarkerMarksDocument = TelemarkerMarksDocument.Load(marksFilePath); StringBuilder stringBuilder = new StringBuilder(); int num = 0; for (int i = 1; i <= 10; i++) { if (telemarkerMarksDocument.TryGetSlot(text, i, out Vector3 position, out string _)) { num++; stringBuilder.AppendLine($" slot {i}: {FormatVec(position)}"); } } if (num == 0) { Notify("No active marks for this world."); return; } PrintMultilineToDeveloperConsole(string.Format("[{0}] Active marks ({1}) for world \"{2}\":\n{3}", "DrakesTelemarker", num, text, stringBuilder.ToString().TrimEnd(Array.Empty<char>()))); } private static void RouteTelemark(DrakesTelemarkerPlugin plugin, string[] args) { //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) if (args == null || args.Length == 0) { PrintTelemarkUsage(); return; } string text = args[0].ToLowerInvariant(); if ((text == "help" || text == "?") ? true : false) { PrintTelemarkUsage(); return; } if (!CanUseTelemarkerCheats()) { Notify("That needs cheat access (devcommands or server admin). telemark alone only prints help — run it for the full list."); return; } switch (text) { case "list": RunTelemarkList(); break; case "set": { if (!TryParseMarkSlotArgs(ArgsTail(args, 1), out int slot, out string usageError)) { Notify(usageError); break; } Player localPlayerOrNotify = GetLocalPlayerOrNotify(); if (localPlayerOrNotify != null) { Vector3 position = ((Component)localPlayerOrNotify).transform.position; plugin.TrySetSlot(slot, position, out string _); Notify($"Saved mark {slot} at {FormatVec(position)}."); } break; } case "recall": { if (!TryParseMarkSlotArgs(ArgsTail(args, 1), out int slot2, out string usageError2)) { Notify(usageError2); break; } Player localPlayerOrNotify2 = GetLocalPlayerOrNotify(); if (localPlayerOrNotify2 != null) { if (!plugin.TryRecallSlot(slot2, out Vector3 position2, out string error2)) { Notify(string.IsNullOrEmpty(error2) ? $"Mark {slot2} is empty." : error2); break; } ((Component)localPlayerOrNotify2).transform.position = position2; Physics.SyncTransforms(); Notify($"Recalled mark {slot2} -> {FormatVec(position2)}."); } break; } case "clear": { if (args.Length < 2) { Notify($"Usage: telemark clear <1-{10}> | telemark clear all"); break; } string text2 = args[1]; int result; if (text2.Equals("all", StringComparison.OrdinalIgnoreCase)) { if (args.Length > 2) { Notify("Usage: telemark clear all"); } else { TelemarkerClearDialog.RequestConfirmation(plugin, clearAll: true, 0); } } else if (!int.TryParse(text2, NumberStyles.Integer, CultureInfo.InvariantCulture, out result) || result < 1 || result > 10) { Notify($"Usage: telemark clear <1-{10}> | telemark clear all"); } else if (args.Length > 2) { Notify($"Usage: telemark clear <1-{10}>"); } else { TelemarkerClearDialog.RequestConfirmation(plugin, clearAll: false, result); } break; } default: Notify("Unknown telemark subcommand '" + args[0] + "'. Check console log for full usage."); PrintTelemarkUsage(); break; } } } [DataContract] internal sealed class TelemarkerMarksDocument { [DataMember(Name = "schemaVersion")] public int SchemaVersion { get; set; } = 1; [DataMember(Name = "worlds")] public Dictionary<string, WorldMarkSlots> Worlds { get; set; } = new Dictionary<string, WorldMarkSlots>(); internal static TelemarkerMarksDocument Load(string path) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown if (!File.Exists(path)) { return new TelemarkerMarksDocument(); } try { using FileStream fileStream = File.OpenRead(path); DataContractJsonSerializer val = new DataContractJsonSerializer(typeof(TelemarkerMarksDocument)); if (((XmlObjectSerializer)val).ReadObject((Stream)fileStream) is TelemarkerMarksDocument telemarkerMarksDocument) { TelemarkerMarksDocument telemarkerMarksDocument2 = telemarkerMarksDocument; if (telemarkerMarksDocument2.Worlds == null) { Dictionary<string, WorldMarkSlots> dictionary2 = (telemarkerMarksDocument2.Worlds = new Dictionary<string, WorldMarkSlots>()); } foreach (WorldMarkSlots value in telemarkerMarksDocument.Worlds.Values) { WorldMarkSlots worldMarkSlots = value; if (worldMarkSlots.Slots == null) { Dictionary<string, MarkCoordinates> dictionary4 = (worldMarkSlots.Slots = new Dictionary<string, MarkCoordinates>()); } } return telemarkerMarksDocument; } } catch (Exception ex) { Debug.LogWarning((object)("[DrakesTelemarker] Could not read " + path + ", starting fresh: " + ex.Message)); } return new TelemarkerMarksDocument(); } internal static void Save(string path, TelemarkerMarksDocument doc) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown if (doc.Worlds == null) { Dictionary<string, WorldMarkSlots> dictionary2 = (doc.Worlds = new Dictionary<string, WorldMarkSlots>()); } string text = path + ".tmp"; using (FileStream fileStream = File.Create(text)) { DataContractJsonSerializer val = new DataContractJsonSerializer(typeof(TelemarkerMarksDocument)); ((XmlObjectSerializer)val).WriteObject((Stream)fileStream, (object)doc); } if (File.Exists(path)) { File.Delete(path); } File.Move(text, path); } internal void UpsertSlot(string worldKey, int slot1Based, Vector3 position) { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) Worlds.TryGetValue(worldKey, out WorldMarkSlots value); if (value == null) { value = new WorldMarkSlots(); Worlds[worldKey] = value; } WorldMarkSlots worldMarkSlots = value; if (worldMarkSlots.Slots == null) { Dictionary<string, MarkCoordinates> dictionary2 = (worldMarkSlots.Slots = new Dictionary<string, MarkCoordinates>()); } string key = slot1Based.ToString(CultureInfo.InvariantCulture); value.Slots[key] = new MarkCoordinates { X = position.x, Y = position.y, Z = position.z }; } internal bool TryGetSlot(string worldKey, int slot1Based, out Vector3 position, out string error) { //IL_0002: 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) position = default(Vector3); error = ""; if (!Worlds.TryGetValue(worldKey, out WorldMarkSlots value) || value?.Slots == null) { error = $"Mark {slot1Based} is empty."; return false; } string key = slot1Based.ToString(CultureInfo.InvariantCulture); if (!value.Slots.TryGetValue(key, out MarkCoordinates value2)) { error = $"Mark {slot1Based} is empty."; return false; } position = new Vector3(value2.X, value2.Y, value2.Z); return true; } internal bool ClearSlot(string worldKey, int slot1Based) { if (!Worlds.TryGetValue(worldKey, out WorldMarkSlots value) || value.Slots == null) { return false; } string key = slot1Based.ToString(CultureInfo.InvariantCulture); return value.Slots.Remove(key); } internal int ClearAllSlotsForWorld(string worldKey) { if (!Worlds.TryGetValue(worldKey, out WorldMarkSlots value) || value.Slots == null || value.Slots.Count == 0) { return 0; } int count = value.Slots.Count; value.Slots.Clear(); Worlds.Remove(worldKey); return count; } } [DataContract] internal sealed class WorldMarkSlots { [DataMember(Name = "slots")] public Dictionary<string, MarkCoordinates>? Slots { get; set; } } [DataContract] internal sealed class MarkCoordinates { [DataMember(Name = "x")] public float X { get; set; } [DataMember(Name = "y")] public float Y { get; set; } [DataMember(Name = "z")] public float Z { get; set; } } internal static class TelemarkerClearDialog { [CompilerGenerated] private static class <>O { public static UnityAction <0>__Close; } [CompilerGenerated] private sealed class <CoRetryOpen>d__11 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public DrakesTelemarkerPlugin plugin; public bool clearAll; public int slot1Based; private int <i>5__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <CoRetryOpen>d__11(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <i>5__1 = 0; break; case 1: <>1__state = -1; <i>5__1++; break; } if (<i>5__1 < 240) { if (TryOpenNow(plugin, clearAll, slot1Based)) { return false; } <>2__current = null; <>1__state = 1; return true; } DrakesTelemarkerPlugin.Notify("Confirmation UI is not ready yet. Try again in a moment."); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private const int TryOpenFrames = 240; private static GameObject? _root; private static Text? _questionText; private static Button? _buttonYes; private static Button? _buttonNo; private static bool _inputBlocked; private static bool _pendingAll; private static int _pendingSlot; private static string _lockedWorldKey = ""; internal static void RegisterForGuiRebuild() { GUIManager.OnCustomGUIAvailable += delegate { TearDownPanel(); }; } internal static void RequestConfirmation(DrakesTelemarkerPlugin plugin, bool clearAll, int slot1Based) { if (!TryOpenNow(plugin, clearAll, slot1Based)) { ((MonoBehaviour)plugin).StartCoroutine(CoRetryOpen(plugin, clearAll, slot1Based)); } } [IteratorStateMachine(typeof(<CoRetryOpen>d__11))] private static IEnumerator CoRetryOpen(DrakesTelemarkerPlugin plugin, bool clearAll, int slot1Based) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <CoRetryOpen>d__11(0) { plugin = plugin, clearAll = clearAll, slot1Based = slot1Based }; } internal static bool TryOpenNow(DrakesTelemarkerPlugin plugin, bool clearAll, int slot1Based) { GUIManager instance = GUIManager.Instance; if (instance == null || !Object.op_Implicit((Object)(object)GUIManager.CustomGUIFront)) { return false; } EnsurePanelBuilt(instance); if ((Object)(object)_root == (Object)null || (Object)(object)_questionText == (Object)null || (Object)(object)_buttonYes == (Object)null || (Object)(object)_buttonNo == (Object)null) { return false; } _pendingAll = clearAll; _pendingSlot = slot1Based; _lockedWorldKey = DrakesTelemarkerPlugin.SanitizeWorldKey(DrakesTelemarkerPlugin.GetWorldKey()); _questionText.text = (clearAll ? "Are you sure you want to clear ALL saved marks for this world?" : ("Are you sure you want to clear mark " + slot1Based.ToString(CultureInfo.InvariantCulture) + "?")); WireButtonsOnce(plugin); _root.SetActive(true); if (!_inputBlocked) { GUIManager.BlockInput(true); _inputBlocked = true; } return true; } private static void WireButtonsOnce(DrakesTelemarkerPlugin plugin) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown DrakesTelemarkerPlugin plugin2 = plugin; ((UnityEventBase)_buttonYes.onClick).RemoveAllListeners(); ((UnityEventBase)_buttonNo.onClick).RemoveAllListeners(); ((UnityEvent)_buttonYes.onClick).AddListener((UnityAction)delegate { OnYes(plugin2); }); ButtonClickedEvent onClick = _buttonNo.onClick; object obj = <>O.<0>__Close; if (obj == null) { UnityAction val = Close; <>O.<0>__Close = val; obj = (object)val; } ((UnityEvent)onClick).AddListener((UnityAction)obj); } private static void OnYes(DrakesTelemarkerPlugin plugin) { string b = DrakesTelemarkerPlugin.SanitizeWorldKey(DrakesTelemarkerPlugin.GetWorldKey()); if (!string.Equals(_lockedWorldKey, b, StringComparison.Ordinal)) { DrakesTelemarkerPlugin.Notify("World changed before confirmation — nothing was cleared. Run telemark clear … again."); Close(); return; } string error2; if (_pendingAll) { if (!plugin.TryClearAllSlots(out int clearedCount, out string error)) { DrakesTelemarkerPlugin.Notify(string.IsNullOrEmpty(error) ? "Nothing to clear." : error); } else { DrakesTelemarkerPlugin.Notify($"Cleared all {clearedCount} marks for this world."); } } else if (!plugin.TryClearSlot(_pendingSlot, out error2)) { DrakesTelemarkerPlugin.Notify(string.IsNullOrEmpty(error2) ? ("Mark " + _pendingSlot.ToString(CultureInfo.InvariantCulture) + " was already empty.") : error2); } else { DrakesTelemarkerPlugin.Notify("Cleared mark " + _pendingSlot.ToString(CultureInfo.InvariantCulture) + "."); } Close(); } private static void Close() { if ((Object)(object)_root != (Object)null) { _root.SetActive(false); } if (_inputBlocked) { GUIManager.BlockInput(false); _inputBlocked = false; } } private static void TearDownPanel() { if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); _root = null; } _questionText = null; _buttonYes = null; _buttonNo = null; if (_inputBlocked) { try { GUIManager.BlockInput(false); } catch { } _inputBlocked = false; } } private static void EnsurePanelBuilt(GUIManager gui) { //IL_002c: 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_0040: 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_0083: 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_00a0: 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_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0107: 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) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_root != (Object)null)) { Transform transform = GUIManager.CustomGUIFront.transform; _root = gui.CreateWoodpanel(transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, 380f, 200f, false); gui.CreateText("DrakesTelemarker", _root.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -36f), gui.AveriaSerifBold, 18, gui.ValheimOrange, true, Color.black, 340f, 28f, false); GameObject val = gui.CreateText("", _root.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 12f), gui.AveriaSerifBold, 15, Color.white, true, Color.black, 340f, 70f, false); _questionText = val.GetComponent<Text>(); _questionText.alignment = (TextAnchor)4; _questionText.horizontalOverflow = (HorizontalWrapMode)0; _buttonYes = gui.CreateButton("Yes", _root.transform, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(-70f, 36f), 110f, 32f).GetComponent<Button>(); _buttonNo = gui.CreateButton("No", _root.transform, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(70f, 36f), 110f, 32f).GetComponent<Button>(); _root.SetActive(false); } } } internal static class TelemarkerMinimap { [CompilerGenerated] private sealed class <DelayedSyncRoutine>d__12 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; private int <i>5__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <DelayedSyncRoutine>d__12(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; <i>5__1 = 0; break; case 2: <>1__state = -1; <i>5__1++; break; } if (<i>5__1 < 30 && (Object)(object)Minimap.instance == (Object)null) { <>2__current = null; <>1__state = 2; return true; } SyncPins(); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <SyncNextFrame>d__14 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <SyncNextFrame>d__14(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; SyncPins(); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static MethodInfo? ScreenToWorldPointMethod; private static MethodInfo? GetClosestPinMethod; private static MethodInfo? CreateMapNamePinMethod; private static readonly Dictionary<int, PinData> TrackedBySlot = new Dictionary<int, PinData>(); private static readonly Sprite?[] SlotSpriteCache = (Sprite?[])(object)new Sprite[11]; private static DrakesTelemarkerPlugin? _plugin; private static Harmony? _harmony; private static bool _loggedCreateMapNamePinFailure; internal static void Init(DrakesTelemarkerPlugin plugin) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Expected O, but got Unknown //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Expected O, but got Unknown //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Expected O, but got Unknown _plugin = plugin; ResolveMinimapReflection(); _harmony = new Harmony("com.drakemods.DrakesTelemarker.Minimap"); MethodInfo methodInfo = FindParameterlessInstanceMethod(typeof(Minimap), "LoadMapData"); if (methodInfo != null) { _harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(TelemarkerMinimap), "AfterMinimap_LoadMapData", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } else { Debug.LogWarning((object)"[DrakesTelemarker] Minimap.LoadMapData() not found — pins may not refresh when the map reloads."); } MethodInfo methodInfo2 = AccessTools.Method(typeof(Minimap), "OnMapRightClick", new Type[1] { typeof(UIInputHandler) }, (Type[])null); if (methodInfo2 != null && ScreenToWorldPointMethod != null) { _harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(TelemarkerMinimap), "OnMapRightClick_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } MethodInfo methodInfo3 = AccessTools.Method(typeof(Minimap), "OnMapLeftDown", new Type[1] { typeof(UIInputHandler) }, (Type[])null); if (methodInfo3 != null && ScreenToWorldPointMethod != null) { _harmony.Patch((MethodBase)methodInfo3, new HarmonyMethod(typeof(TelemarkerMinimap), "OnMapLeftDown_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } if (methodInfo2 == null && methodInfo3 == null) { Debug.LogWarning((object)"[DrakesTelemarker] Could not attach map click hooks — use telemark recall from console."); } MethodInfo methodInfo4 = AccessTools.Method(typeof(Minimap), "UpdatePins", (Type[])null, (Type[])null); if (methodInfo4 != null && CreateMapNamePinMethod != null) { HarmonyMethod val = new HarmonyMethod(typeof(TelemarkerMinimap), "After_UpdatePins_Postfix", (Type[])null) { priority = 0 }; _harmony.Patch((MethodBase)methodInfo4, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } ((MonoBehaviour)plugin).StartCoroutine(DelayedSyncRoutine()); } private static void ResolveMinimapReflection() { ScreenToWorldPointMethod = AccessTools.Method(typeof(Minimap), "ScreenToWorldPoint", new Type[1] { typeof(Vector3) }, (Type[])null); GetClosestPinMethod = AccessTools.Method(typeof(Minimap), "GetClosestPin", new Type[3] { typeof(Vector3), typeof(float), typeof(bool) }, (Type[])null); CreateMapNamePinMethod = AccessTools.Method(typeof(Minimap), "CreateMapNamePin", new Type[2] { typeof(PinData), typeof(RectTransform) }, (Type[])null); } private static MethodInfo? FindParameterlessInstanceMethod(Type type, string name) { MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { if (methodInfo.Name == name && methodInfo.GetParameters().Length == 0) { return methodInfo; } } return null; } private static void AfterMinimap_LoadMapData() { SyncPins(); } [IteratorStateMachine(typeof(<DelayedSyncRoutine>d__12))] private static IEnumerator DelayedSyncRoutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <DelayedSyncRoutine>d__12(0); } internal static void RequestSync() { if (!((Object)(object)_plugin == (Object)null)) { ((MonoBehaviour)_plugin).StartCoroutine(SyncNextFrame()); } } [IteratorStateMachine(typeof(<SyncNextFrame>d__14))] private static IEnumerator SyncNextFrame() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <SyncNextFrame>d__14(0); } internal static void SyncPins() { //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_plugin == (Object)null || (Object)(object)Minimap.instance == (Object)null) { return; } Minimap instance = Minimap.instance; foreach (PinData value in TrackedBySlot.Values) { if (value != null) { instance.RemovePin(value); } } TrackedBySlot.Clear(); _loggedCreateMapNamePinFailure = false; string marksFilePath = DrakesTelemarkerPlugin.GetMarksFilePath(); string worldKey = DrakesTelemarkerPlugin.SanitizeWorldKey(DrakesTelemarkerPlugin.GetWorldKey()); TelemarkerMarksDocument telemarkerMarksDocument = TelemarkerMarksDocument.Load(marksFilePath); long uID = ZNet.GetUID(); PlatformUserID val = default(PlatformUserID); for (int i = 1; i <= 10; i++) { if (telemarkerMarksDocument.TryGetSlot(worldKey, i, out Vector3 position, out string _)) { string text = $"Mark {i}"; PinData val2 = instance.AddPin(position, (PinType)3, text, false, false, uID, val); if (val2 != null) { val2.m_icon = GetOrCreateSlotSprite(i); val2.m_animate = false; val2.m_doubleSize = true; TrackedBySlot[i] = val2; } } } } private static RectTransform ResolvePinNameRoot(Minimap mm) { if (mm.m_mapLarge.gameObject.activeInHierarchy && mm.m_mapLarge.gameObject.activeSelf) { return mm.m_pinNameRootLarge; } return mm.m_pinNameRootSmall; } private static void After_UpdatePins_Postfix(Minimap __instance) { if ((Object)(object)__instance == (Object)null || TrackedBySlot.Count == 0 || CreateMapNamePinMethod == null) { return; } RectTransform val = ResolvePinNameRoot(__instance); foreach (PinData value in TrackedBySlot.Values) { if (value == null || (Object)(object)value.m_uiElement == (Object)null || (value.m_NamePinData != null && (Object)(object)value.m_NamePinData.PinNameGameObject != (Object)null)) { continue; } try { CreateMapNamePinMethod.Invoke(__instance, new object[2] { value, val }); } catch (Exception ex) { if (!_loggedCreateMapNamePinFailure) { _loggedCreateMapNamePinFailure = true; Debug.LogWarning((object)("[DrakesTelemarker] CreateMapNamePin failed (further errors suppressed): " + ex.Message)); } break; } } } private static bool OnMapRightClick_Prefix(Minimap __instance, UIInputHandler handler) { return HandleMapRecallInput(__instance, "right-click map pin"); } private static bool OnMapLeftDown_Prefix(Minimap __instance, UIInputHandler handler) { if (!Input.GetKey((KeyCode)306) && !Input.GetKey((KeyCode)305)) { return true; } return HandleMapRecallInput(__instance, "Ctrl+click map pin"); } private static bool HandleMapRecallInput(Minimap minimapInstance, string viaPhrase) { //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_plugin == (Object)null || (Object)(object)minimapInstance == (Object)null || TrackedBySlot.Count == 0) { return true; } if (ScreenToWorldPointMethod == null) { return true; } if (!DrakesTelemarkerPlugin.CanUseTelemarkerCheats()) { return true; } if (!TryGetTrackedSlotUnderCursor(minimapInstance, out var slot)) { return true; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return true; } if (!_plugin.TryRecallSlot(slot, out Vector3 position, out string error)) { DrakesTelemarkerPlugin.Notify(string.IsNullOrEmpty(error) ? $"Mark {slot} is empty." : error); return true; } ((Component)localPlayer).transform.position = position; Physics.SyncTransforms(); DrakesTelemarkerPlugin.Notify($"Recalled mark {slot} ({viaPhrase}) -> {DrakesTelemarkerPlugin.FormatVec(position)}."); return false; } private static Camera? CanvasUiCamera(RectTransform rt) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) Canvas componentInParent = ((Component)rt).GetComponentInParent<Canvas>(); if ((Object)(object)componentInParent == (Object)null) { return null; } return ((int)componentInParent.renderMode == 0) ? null : componentInParent.worldCamera; } private static float ScreenPivotSlackPixels(RectTransform rt) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) Rect rect = rt.rect; float num = Mathf.Abs(((Rect)(ref rect)).width * ((Transform)rt).lossyScale.x); rect = rt.rect; float num2 = Mathf.Abs(((Rect)(ref rect)).height * ((Transform)rt).lossyScale.y); float num3 = Mathf.Max(24f, Mathf.Min(num, num2)); return Mathf.Clamp(num3 * 0.65f + 32f, 40f, 140f); } private static bool TryLooseRectHit(RectTransform rt, Vector2 screen) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_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_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_0040: 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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) Camera val = CanvasUiCamera(rt); if (RectTransformUtility.RectangleContainsScreenPoint(rt, screen, val)) { return true; } Rect rect = rt.rect; Vector3 val2 = Vector2.op_Implicit(RectTransformUtility.WorldToScreenPoint(val, ((Transform)rt).TransformPoint(Vector2.op_Implicit(((Rect)(ref rect)).center)))); float num = ScreenPivotSlackPixels(rt); Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(val2.x, val2.y); Vector2 val4 = screen - val3; return ((Vector2)(ref val4)).sqrMagnitude <= num * num; } private static bool TryGetTrackedSlotUnderCursor(Minimap minimap, out int slot) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0382: Unknown result type (might be due to invalid IL or missing references) //IL_0387: Unknown result type (might be due to invalid IL or missing references) //IL_0389: Unknown result type (might be due to invalid IL or missing references) //IL_0390: Unknown result type (might be due to invalid IL or missing references) //IL_039a: Unknown result type (might be due to invalid IL or missing references) //IL_03a1: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: 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_00df: 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_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0101: 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_010e: 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_0261: Unknown result type (might be due to invalid IL or missing references) slot = 0; Vector3 mousePosition = Input.mousePosition; Vector2 val = Vector2.op_Implicit(mousePosition); int num = 0; float num2 = float.MaxValue; foreach (KeyValuePair<int, PinData> item in TrackedBySlot) { PinData value = item.Value; if (value == null) { continue; } RectTransform[] array = new RectTransform[3]; Image iconElement = value.m_iconElement; array[0] = ((iconElement != null) ? ((Graphic)iconElement).rectTransform : null); array[1] = value.m_uiElement; PinNameData namePinData = value.m_NamePinData; array[2] = ((namePinData != null) ? namePinData.PinNameRectTransform : null); RectTransform[] array2 = (RectTransform[])(object)array; RectTransform[] array3 = array2; foreach (RectTransform val2 in array3) { if (!((Object)(object)val2 == (Object)null) && TryLooseRectHit(val2, val)) { Camera val3 = CanvasUiCamera(val2); Rect rect = val2.rect; Vector3 val4 = Vector2.op_Implicit(RectTransformUtility.WorldToScreenPoint(val3, ((Transform)val2).TransformPoint(Vector2.op_Implicit(((Rect)(ref rect)).center)))); Vector2 val5 = new Vector2(val4.x, val4.y) - val; float sqrMagnitude = ((Vector2)(ref val5)).sqrMagnitude; if (!(sqrMagnitude >= num2)) { num2 = sqrMagnitude; num = item.Key; } } } } if (num != 0) { slot = num; return true; } MethodInfo screenToWorldPointMethod = ScreenToWorldPointMethod; if (screenToWorldPointMethod == null) { return false; } Vector3 val7; try { if (!(screenToWorldPointMethod.Invoke(minimap, new object[1] { mousePosition }) is Vector3 val6) || 1 == 0) { return false; } val7 = val6; } catch (Exception ex) { Debug.LogWarning((object)("[DrakesTelemarker] ScreenToWorldPoint reflex failed: " + ex.Message)); return false; } MethodInfo getClosestPinMethod = GetClosestPinMethod; if (getClosestPinMethod != null) { try { float num3 = Mathf.Max(minimap.m_removeRadius * 48f, 640f); bool[] array4 = new bool[2] { false, true }; foreach (bool flag in array4) { object obj = getClosestPinMethod.Invoke(minimap, new object[3] { val7, num3, flag }); PinData val8 = (PinData)((obj is PinData) ? obj : null); if (val8 == null) { continue; } foreach (KeyValuePair<int, PinData> item2 in TrackedBySlot) { if (item2.Value == val8) { slot = item2.Key; return true; } } } } catch (Exception ex2) { Debug.LogWarning((object)("[DrakesTelemarker] GetClosestPin reflex failed: " + ex2.Message)); } } float num4 = Mathf.Max(minimap.m_removeRadius * 40f, 450f); float num5 = num4 * num4; float num6 = float.PositiveInfinity; int num7 = 0; foreach (KeyValuePair<int, PinData> item3 in TrackedBySlot) { if (item3.Value != null) { Vector3 pos = item3.Value.m_pos; float num8 = val7.x - pos.x; float num9 = val7.z - pos.z; float num10 = num8 * num8 + num9 * num9; if (num10 < num6) { num6 = num10; num7 = item3.Key; } } } if (num7 == 0 || num6 > num5) { return false; } slot = num7; return true; } private static Sprite GetOrCreateSlotSprite(int slot) { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) if (slot < 1 || slot > 10) { slot = Mathf.Clamp(slot, 1, 10); } Sprite val = SlotSpriteCache[slot]; if ((Object)(object)val != (Object)null) { return val; } Texture2D val2 = TelemarkerPinTexture.Build(slot); ((Texture)val2).wrapMode = (TextureWrapMode)1; ((Texture)val2).filterMode = (FilterMode)2; Sprite val3 = Sprite.Create(val2, new Rect(0f, 0f, (float)((Texture)val2).width, (float)((Texture)val2).height), new Vector2(0.5f, 0.12f), Mathf.Max((float)((Texture)val2).width / 120f * 96f, 48f)); SlotSpriteCache[slot] = val3; return val3; } } internal static class TelemarkerPinTexture { private const int Res = 128; private static readonly string[][] DigitRows = new string[10][] { new string[5] { "01110", "10001", "10001", "10001", "01110" }, new string[5] { "00100", "01100", "00100", "00100", "01110" }, new string[5] { "01110", "10001", "00110", "01000", "11111" }, new string[5] { "11110", "00001", "01110", "00001", "11110" }, new string[5] { "10001", "10001", "11111", "00001", "00001" }, new string[5] { "11111", "10000", "11110", "00001", "11110" }, new string[5] { "01110", "10000", "11110", "10001", "01110" }, new string[5] { "11111", "00001", "00010", "00100", "01000" }, new string[5] { "01110", "10001", "01110", "10001", "01110" }, new string[5] { "01110", "10001", "01111", "00001", "01110" } }; public static Texture2D Build(int slotNumber) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(128, 128, (TextureFormat)4, false); ((Object)val).name = $"TelemarkerPin_{slotNumber}"; Color32[] array = (Color32[])(object)new Color32[16384]; Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(0.5f, 0.06f); Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(0.35180002f, 0.52f); Vector2 val4 = default(Vector2); ((Vector2)(ref val4))..ctor(0.6482f, 0.52f); int holeCx = Mathf.RoundToInt(63.5f); int holeCy = Mathf.RoundToInt(93.98f); int holeR = Mathf.RoundToInt(11.52f); for (int i = 0; i < 128; i++) { float num = (float)i / 127f; for (int j = 0; j < 128; j++) { float num2 = (float)j / 127f; bool flag = InsideEllipse(num2, num, 0.5f, 0.74f, 0.19f, 0.24f); bool flag2 = InsideTriangle(new Vector2(num2, num), val2, val3, val4); bool flag3 = flag || flag2; bool flag4 = InsideEllipse(num2, num, 0.5f, 0.74f, 0.1f, 0.11f); if (!flag3) { array[i * 128 + j] = new Color32((byte)0, (byte)0, (byte)0, (byte)0); continue; } if (flag4) { array[i * 128 + j] = new Color32((byte)32, (byte)38, (byte)48, byte.MaxValue); continue; } byte b = (byte)((num2 < 0.5f) ? byte.MaxValue : 228); bool flag5 = OutlineSample(num2, num, 0.5f, 0.74f, 0.19f, 0.24f, val2, val3, val4); byte b2 = ((b >= 247) ? b : ((byte)(b + 8))); array[i * 128 + j] = (flag5 ? new Color32((byte)200, (byte)200, (byte)210, byte.MaxValue) : new Color32(b, b, b2, byte.MaxValue)); } } BlitDigits(array, holeCx, holeCy, holeR, slotNumber); val.SetPixels32(array); val.Apply(false, false); return val; } private static bool OutlineSample(float ux, float uy, float cx, float cyHead, float headRx, float headRy, Vector2 tip, Vector2 shoulderL, Vector2 shoulderR) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) if (!InsidePin(ux, uy, cx, cyHead, headRx, headRy, tip, shoulderL, shoulderR)) { return false; } float[] array = new float[3] { -1f / 127f, 0f, 1f / 127f }; foreach (float num in array) { float[] array2 = new float[3] { -1f / 127f, 0f, 1f / 127f }; foreach (float num2 in array2) { if ((!(Mathf.Abs(num) < 0.0001f) || !(Mathf.Abs(num2) < 0.0001f)) && !InsidePin(ux + num, uy + num2, cx, cyHead, headRx, headRy, tip, shoulderL, shoulderR)) { return true; } } } return false; } private static bool InsidePin(float ux, float uy, float cx, float cyHead, float headRx, float headRy, Vector2 tip, Vector2 shoulderL, Vector2 shoulderR) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) return InsideEllipse(ux, uy, cx, cyHead, headRx, headRy) || InsideTriangle(new Vector2(ux, uy), tip, shoulderL, shoulderR); } private static bool InsideEllipse(float ux, float uy, float cx, float cy, float halfW, float halfH) { float num = (ux - cx) / halfW; float num2 = (uy - cy) / halfH; return num * num + num2 * num2 <= 1f; } private static bool InsideTriangle(Vector2 p, Vector2 a, Vector2 b, Vector2 c) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_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_0016: Unknown result type (might be due to invalid IL or missing references) float num = Sign(p, a, b); float num2 = Sign(p, b, c); float num3 = Sign(p, c, a); bool flag = num < 0f || num2 < 0f || num3 < 0f; bool flag2 = num > 0f || num2 > 0f || num3 > 0f; return !(flag && flag2); static float Sign(Vector2 p1, Vector2 p2, Vector2 p3) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001b: 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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) return (p1.x - p3.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p3.y); } } private static void BlitDigits(Color32[] pix, int holeCx, int holeCy, int holeR, int value) { string text = Mathf.Clamp(value, 1, 10).ToString(CultureInfo.InvariantCulture); float num = ((text.Length >= 2) ? 1.35f : 1f); int num2 = Mathf.Max(8, Mathf.RoundToInt((float)holeR * num * 0.55f)); int num3 = Mathf.Max(10, Mathf.RoundToInt((float)holeR * num * 0.62f)); int num4 = num2 * text.Length + Mathf.Max(0, text.Length - 1); int num5 = holeCx - num4 / 2; int oy = holeCy - num3 / 2; string text2 = text; foreach (char digit in text2) { DrawGlyph(pix, num5, oy, num2, num3, digit); num5 += num2 + 1; } } private static void DrawGlyph(Color32[] pix, int ox, int oy, int gw, int gh, char digit) { //IL_00c9: 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) if (!char.IsDigit(digit)) { return; } int num = digit - 48; string[] array = DigitRows[num]; int num2 = Mathf.Max(1, gh / 5); for (int i = 0; i < 5 && i < array.Length; i++) { string text = array[i]; int num3 = Mathf.Max(1, gw / 5); for (int j = 0; j < 5 && j < text.Length; j++) { if (text[j] != '1') { continue; } int num4 = ox + j * num3; int num5 = oy + gh - (i + 1) * num2; for (int k = num5; k < num5 + num2 && k < 128; k++) { if (k < 0) { continue; } for (int l = num4; l < num4 + num3 && l < 128; l++) { if (l >= 0) { pix[k * 128 + l] = new Color32((byte)246, (byte)248, byte.MaxValue, byte.MaxValue); } } } } } } } }