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 Odins Thread v0.1.0
plugins/OdinsThread.dll
Decompiled 2 weeks agousing System; using System.Collections.Generic; using System.Diagnostics; 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 Microsoft.CodeAnalysis; 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.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("OdinsThread")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.1.0+09b78a1d38205390742e0f7810357cfaa3cad2c2")] [assembly: AssemblyProduct("OdinsThread")] [assembly: AssemblyTitle("OdinsThread")] [assembly: AssemblyVersion("0.1.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace OdinsThread { internal sealed class MapLayers : MonoBehaviour { private const float ConfirmSeconds = 3f; private const string CutLabel = "Cut the thread"; private const string ConfirmLabel = "Cut it? Click again."; private const string DoneLabel = "Thread cut."; private Minimap _map; private TrailGraphic _small; private TrailGraphic _large; private GameObject _button; private TMP_Text _buttonText; private float _confirmUntil = -1f; private float _labelResetAt = -1f; private void Update() { Minimap instance = Minimap.instance; if ((Object)(object)instance == (Object)null) { return; } if ((Object)(object)instance != (Object)(object)_map || (Object)(object)_small == (Object)null || (Object)(object)_large == (Object)null) { Build(instance); } bool flag = Plugin.Enabled.Value && (Object)(object)Trail.Instance != (Object)null && !Trail.Instance.Hidden; SetActive(_small, flag && Plugin.OnMinimap.Value); SetActive(_large, flag && Plugin.OnMap.Value); if ((Object)(object)_button == (Object)null) { EnsureButton(instance); } if ((Object)(object)_button != (Object)null) { bool flag2 = Plugin.Enabled.Value && Plugin.OnMap.Value; if (_button.activeSelf != flag2) { _button.SetActive(flag2); } if (_labelResetAt > 0f && Time.unscaledTime >= _labelResetAt) { _labelResetAt = -1f; _confirmUntil = -1f; _buttonText.text = "Cut the thread"; } } } private void Build(Minimap map) { _map = map; if ((Object)(object)_small != (Object)null) { Object.Destroy((Object)(object)((Component)_small).gameObject); } if ((Object)(object)_large != (Object)null) { Object.Destroy((Object)(object)((Component)_large).gameObject); } _small = Create(map.m_mapImageSmall, large: false); _large = Create(map.m_mapImageLarge, large: true); Plugin.Log.LogInfo((object)"Thread laid over the minimap and the big map."); } private static TrailGraphic Create(RawImage mapImage, bool large) { //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_0039: 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_004f: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(large ? "OdinsThread_Large" : "OdinsThread_Small", new Type[1] { typeof(RectTransform) }); val.transform.SetParent(((Component)mapImage).transform, false); RectTransform val2 = (RectTransform)val.transform; val2.anchorMin = Vector2.zero; val2.anchorMax = Vector2.one; val2.pivot = Vector2.zero; val2.offsetMin = Vector2.zero; val2.offsetMax = Vector2.zero; TrailGraphic trailGraphic = val.AddComponent<TrailGraphic>(); trailGraphic.Map = mapImage; trailGraphic.Large = large; return trailGraphic; } private static void SetActive(TrailGraphic layer, bool on) { if ((Object)(object)layer != (Object)null && ((Component)layer).gameObject.activeSelf != on) { ((Component)layer).gameObject.SetActive(on); } } private void EnsureButton(Minimap map) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: 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_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Expected O, but got Unknown //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Expected O, but got Unknown //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_018c: 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_019c: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) TMP_Text val = (((Object)(object)MessageHud.instance != (Object)null) ? MessageHud.instance.m_messageCenterText : null); if (!((Object)(object)val == (Object)null) && !((Object)(object)val.font == (Object)null) && !((Object)(object)map.m_largeRoot == (Object)null)) { _button = new GameObject("OdinsThread_Cut", new Type[1] { typeof(RectTransform) }); _button.transform.SetParent(map.m_largeRoot.transform, false); RectTransform val2 = (RectTransform)_button.transform; Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(0f, 1f); val2.anchorMax = val3; val2.anchorMin = val3; val2.pivot = new Vector2(0f, 1f); val2.anchoredPosition = new Vector2(24f, -24f); val2.sizeDelta = new Vector2(240f, 40f); Image val4 = _button.AddComponent<Image>(); ((Graphic)val4).color = new Color(0f, 0f, 0f, 0.55f); Button obj = _button.AddComponent<Button>(); ((Selectable)obj).targetGraphic = (Graphic)(object)val4; ((UnityEvent)obj.onClick).AddListener(new UnityAction(OnCut)); GameObject val5 = new GameObject("Label", new Type[1] { typeof(RectTransform) }); val5.transform.SetParent(_button.transform, false); RectTransform val6 = (RectTransform)val5.transform; val6.anchorMin = Vector2.zero; val6.anchorMax = Vector2.one; val3 = (val6.offsetMin = (val6.offsetMax = Vector2.zero)); _buttonText = (TMP_Text)(object)val5.AddComponent<TextMeshProUGUI>(); _buttonText.font = val.font; _buttonText.fontSharedMaterial = val.fontSharedMaterial; _buttonText.fontSize = 20f; _buttonText.alignment = (TextAlignmentOptions)514; ((Graphic)_buttonText).color = new Color(1f, 0.86f, 0.62f); ((Graphic)_buttonText).raycastTarget = false; _buttonText.text = "Cut the thread"; } } private void OnCut() { if (!((Object)(object)Trail.Instance == (Object)null)) { if (_confirmUntil > 0f && Time.unscaledTime <= _confirmUntil) { Trail.Instance.Clear(); _buttonText.text = "Thread cut."; _confirmUntil = -1f; _labelResetAt = Time.unscaledTime + 3f; } else { _confirmUntil = Time.unscaledTime + 3f; _labelResetAt = _confirmUntil; _buttonText.text = "Cut it? Click again."; } } } private void OnDestroy() { if ((Object)(object)_small != (Object)null) { Object.Destroy((Object)(object)((Component)_small).gameObject); } if ((Object)(object)_large != (Object)null) { Object.Destroy((Object)(object)((Component)_large).gameObject); } if ((Object)(object)_button != (Object)null) { Object.Destroy((Object)(object)_button); } } } [HarmonyPatch(typeof(TeleportWorld), "Teleport")] internal static class PortalPatch { private static void Prefix(Player player) { if ((Object)(object)player != (Object)null && (Object)(object)player == (Object)(object)Player.m_localPlayer) { Trail.PortalPending = true; } } private static void Postfix() { Trail.PortalPending = false; } } [HarmonyPatch(typeof(Player), "TeleportTo")] internal static class TeleportPatch { private static void Postfix(Player __instance, bool __result) { if (__result && (Object)(object)__instance == (Object)(object)Player.m_localPlayer) { Trail.Instance?.OnTeleportStart(__instance, Trail.PortalPending); } } } [HarmonyPatch(typeof(Player), "OnDeath")] internal static class DeathPatch { private static void Prefix(Player __instance) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer) { Trail.Instance?.OnDeath(__instance); } } } [HarmonyPatch(typeof(Game), "Shutdown")] internal static class ShutdownPatch { private static void Prefix() { Trail.Instance?.Save("logging out"); } } [BepInPlugin("hevyh2o.valheim.odinsthread", "Odin's Thread", "0.1.0")] public class Plugin : BaseUnityPlugin { public const string Guid = "hevyh2o.valheim.odinsthread"; public const string Name = "Odin's Thread"; public const string Version = "0.1.0"; internal static ManualLogSource Log; internal static Harmony Patcher; internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<KeyboardShortcut> ToggleKey; internal static ConfigEntry<bool> OnMinimap; internal static ConfigEntry<bool> OnMap; internal static ConfigEntry<string> Colour; internal static ConfigEntry<float> Opacity; internal static ConfigEntry<bool> MarkDeaths; internal static ConfigEntry<bool> MarkPortals; internal static ConfigEntry<float> Spacing; internal static ConfigEntry<int> MaxDays; internal static ConfigEntry<int> MaxPoints; internal static ConfigEntry<bool> DebugLog; private Trail _trail; private void Awake() { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Expected O, but got Unknown //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Expected O, but got Unknown //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Expected O, but got Unknown //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Expected O, but got Unknown //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master switch. Off = nothing is recorded and nothing is drawn. The trail you already have is kept."); ToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "ToggleKey", KeyboardShortcut.Empty, "Hides or shows the thread on both maps. Recording carries on while it's hidden. Unbound by default; any key or combination works, e.g. F7 or T + LeftAlt."); OnMinimap = ((BaseUnityPlugin)this).Config.Bind<bool>("Display", "OnMinimap", true, "Draw the thread on the minimap."); OnMap = ((BaseUnityPlugin)this).Config.Bind<bool>("Display", "OnMap", true, "Draw the thread on the big map, with the \"Cut the thread\" button."); Colour = ((BaseUnityPlugin)this).Config.Bind<string>("Display", "Colour", "gold", "Colour of the thread: gold, amber, silver, white, red, blue, green, purple, or #RRGGBB."); Opacity = ((BaseUnityPlugin)this).Config.Bind<float>("Display", "Opacity", 0.6f, new ConfigDescription("How strong today's trail is, 0.1 to 1. Older trail is fainter.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 1f), Array.Empty<object>())); MarkDeaths = ((BaseUnityPlugin)this).Config.Bind<bool>("Display", "MarkDeaths", true, "A small cross where you died."); MarkPortals = ((BaseUnityPlugin)this).Config.Bind<bool>("Display", "MarkPortals", true, "A small ring at both ends of every portal trip."); Spacing = ((BaseUnityPlugin)this).Config.Bind<float>("Trail", "Spacing", 4f, new ConfigDescription("Metres you move between trail points, 1 to 20. Straight stretches are thinned out further.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 20f), Array.Empty<object>())); MaxDays = ((BaseUnityPlugin)this).Config.Bind<int>("Trail", "MaxDays", 10, new ConfigDescription("In-game days before old trail is forgotten, 0 to 100. 0 = keep everything (it still fades, and MaxPoints still applies).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())); MaxPoints = ((BaseUnityPlugin)this).Config.Bind<int>("Trail", "MaxPoints", 20000, new ConfigDescription("Most trail points kept per character per world, 1000 to 100000. The oldest go first.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1000, 100000), Array.Empty<object>())); DebugLog = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "DebugLog", false, "Write loads, saves, breaks in the thread, deaths and portal trips to the BepInEx log."); ((BaseUnityPlugin)this).Config.SettingChanged += delegate { Trail.Instance?.SettingsChanged(); }; Patcher = new Harmony("hevyh2o.valheim.odinsthread"); Patcher.PatchAll(typeof(Plugin).Assembly); _trail = ((Component)this).gameObject.AddComponent<Trail>(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Odin's Thread 0.1.0 loaded. Odin is holding the other end."); } private void OnDestroy() { Harmony patcher = Patcher; if (patcher != null) { patcher.UnpatchSelf(); } if ((Object)(object)_trail != (Object)null) { Object.Destroy((Object)(object)_trail); } } } internal sealed class Trail : MonoBehaviour { private const float JumpMetres = 60f; private const float StraightTolerance = 0.75f; private const float MaxStraightRun = 60f; private const float SaveInterval = 60f; private const float PruneInterval = 30f; private const float DefaultDayLength = 1200f; internal static bool PortalPending; internal readonly List<TrailPoint> Points = new List<TrailPoint>(); private string _path; private ZNet _net; private PlayerProfile _profile; private Player _player; private Vector3 _lastFramePos; private bool _breakNext = true; private bool _teleporting; private bool _teleportIsPortal; private bool _dirty; private float _nextSave; private float _nextPrune; private MapLayers _layers; private static readonly Dictionary<string, Color> Named = new Dictionary<string, Color>(StringComparer.OrdinalIgnoreCase) { ["gold"] = new Color(0.91f, 0.76f, 0.35f), ["amber"] = new Color(1f, 0.62f, 0.2f), ["silver"] = new Color(0.8f, 0.82f, 0.86f), ["white"] = Color.white, ["red"] = new Color(0.86f, 0.3f, 0.26f), ["blue"] = new Color(0.4f, 0.66f, 0.95f), ["green"] = new Color(0.5f, 0.78f, 0.38f), ["purple"] = new Color(0.66f, 0.5f, 0.86f) }; internal static Trail Instance { get; private set; } internal int Revision { get; private set; } internal bool Hidden { get; private set; } internal Color BaseColour { get; private set; } = new Color(0.91f, 0.76f, 0.35f); internal static float DayLength { get { if (!((Object)(object)EnvMan.instance != (Object)null) || EnvMan.instance.m_dayLengthSec <= 0) { return 1200f; } return EnvMan.instance.m_dayLengthSec; } } internal static double Now { get { if (!((Object)(object)ZNet.instance != (Object)null)) { return 0.0; } return ZNet.instance.GetTimeSeconds(); } } private void Awake() { Instance = this; _layers = ((Component)this).gameObject.AddComponent<MapLayers>(); ReadColour(); } private void OnDestroy() { Save("unloading"); if ((Object)(object)_layers != (Object)null) { Object.Destroy((Object)(object)_layers); } if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } private void OnApplicationQuit() { Save("quitting"); } internal void SettingsChanged() { ReadColour(); Trim(); Revision++; } private void Update() { //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) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { if ((Object)(object)_player != (Object)null) { _player = null; _breakNext = true; Save("player gone"); } } else if (EnsureLoaded()) { if ((Object)(object)localPlayer != (Object)(object)_player) { _player = localPlayer; _breakNext = true; _teleporting = false; _lastFramePos = ((Component)localPlayer).transform.position; } HandleToggleKey(localPlayer); if (Time.time >= _nextPrune) { _nextPrune = Time.time + 30f; Trim(); } if (_dirty && Time.time >= _nextSave) { Save("autosave"); } if (Plugin.Enabled.Value) { Record(localPlayer); } } } private void Record(Player player) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_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_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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_005f: 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_00e0: 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_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: 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_0133: 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_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_02a4: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) Vector3 position = ((Component)player).transform.position; if (((Character)player).IsDead() || ((Character)player).InIntro()) { _breakNext = true; _lastFramePos = position; return; } if (((Character)player).IsTeleporting()) { _teleporting = true; _lastFramePos = position; return; } if (_teleporting) { _teleporting = false; _breakNext = false; _lastFramePos = position; if (!Character.InInterior(position)) { Add(position, (byte)(1 | (_teleportIsPortal ? 4 : 0))); Debug(_teleportIsPortal ? ("Came out of a portal at " + Where(position) + ".") : ("Arrived at " + Where(position) + ".")); } else { _breakNext = true; } _teleportIsPortal = false; return; } if (Character.InInterior(position)) { _breakNext = true; _lastFramePos = position; return; } Vector3 val = Flat(position - _lastFramePos); if (((Vector3)(ref val)).sqrMagnitude > 3600f) { val = Flat(position - _lastFramePos); Debug($"Jumped {((Vector3)(ref val)).magnitude:0} m in one frame. The thread breaks."); _breakNext = true; } _lastFramePos = position; if (_breakNext || Points.Count == 0) { _breakNext = false; Add(position, 1); return; } TrailPoint value = Points[Points.Count - 1]; float value2 = Plugin.Spacing.Value; if (Sqr(position.x - value.X) + Sqr(position.z - value.Z) < value2 * value2) { return; } if (Points.Count >= 2 && value.Flags == 0) { TrailPoint trailPoint = Points[Points.Count - 2]; if (!trailPoint.Has(2) && !trailPoint.Has(4) && Sqr(position.x - trailPoint.X) + Sqr(position.z - trailPoint.Z) < 3600f && DistanceToLine(value.X, value.Z, trailPoint.X, trailPoint.Z, position.x, position.z) < 0.75f) { value.X = position.x; value.Z = position.z; value.Time = Now; Points[Points.Count - 1] = value; Changed(); return; } } Add(position, 0); } internal void OnTeleportStart(Player player, bool portal) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0077: 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) if (EnsureLoaded() && Plugin.Enabled.Value) { Vector3 position = ((Component)player).transform.position; _teleporting = true; _teleportIsPortal = portal; if (!Character.InInterior(position)) { Add(position, (byte)((_breakNext ? 1u : 0u) | (uint)(portal ? 4 : 0))); _breakNext = true; Debug(portal ? ("Into a portal at " + Where(position) + ".") : ("Teleporting from " + Where(position) + ".")); } } } internal void OnDeath(Player player) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) if (EnsureLoaded() && Plugin.Enabled.Value) { Vector3 position = ((Component)player).transform.position; if (!Character.InInterior(position)) { Add(position, (byte)((_breakNext ? 1u : 0u) | 2u)); } _breakNext = true; Debug("Died at " + Where(position) + ". Marked."); Save("death"); } } internal void Clear() { Points.Clear(); _breakNext = true; Changed(); if (_path != null) { try { TrailStore.Delete(_path); _dirty = false; } catch (Exception ex) { Plugin.Log.LogWarning((object)("Couldn't delete " + _path + ": " + ex.Message)); } } Plugin.Log.LogInfo((object)"Thread cut. This character's trail in this world is gone."); } private void Add(Vector3 pos, byte flags) { //IL_0010: 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) Points.Add(new TrailPoint { X = pos.x, Z = pos.z, Time = Now, Flags = flags }); if (Points.Count > Plugin.MaxPoints.Value) { Trim(); } Changed(); } private void Changed() { Revision++; if (!_dirty) { _dirty = true; _nextSave = Time.time + 60f; } } private void Trim() { int i = 0; int value = Plugin.MaxDays.Value; if (value > 0 && (Object)(object)ZNet.instance != (Object)null) { for (double num = Now - (double)value * (double)DayLength; i < Points.Count && Points[i].Time < num; i++) { } } int value2 = Plugin.MaxPoints.Value; if (Points.Count - i > value2) { i = Points.Count - value2 + value2 / 20; } if (i > 0) { i = Math.Min(i, Points.Count); Points.RemoveRange(0, i); if (Points.Count > 0) { TrailPoint value3 = Points[0]; value3.Flags |= 1; Points[0] = value3; } Changed(); Debug($"Forgot {i} old points; {Points.Count} left."); } } private bool EnsureLoaded() { ZNet instance = ZNet.instance; PlayerProfile val = (((Object)(object)Game.instance != (Object)null) ? Game.instance.GetPlayerProfile() : null); if (_path != null && (Object)(object)instance == (Object)(object)_net && val == _profile) { return true; } string text = TrailStore.PathFor(val, instance); if (text == null) { return false; } _net = instance; _profile = val; if (text == _path) { return true; } if (_path != null) { Save("changing worlds"); } _path = text; Points.Clear(); _dirty = false; _breakNext = true; try { Points.AddRange(TrailStore.Load(text)); Plugin.Log.LogInfo((object)$"Loaded {Points.Count} trail points from {Path.GetFileName(text)}."); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Couldn't read " + Path.GetFileName(text) + " (" + ex.Message + "). Starting a fresh thread; the old file is kept as .bad.")); try { File.Copy(text, text + ".bad", overwrite: true); } catch (Exception) { } Points.Clear(); } Revision++; return true; } internal void Save(string why) { if (_path == null || !_dirty) { return; } try { TrailStore.Save(_path, Points); _dirty = false; Debug($"Saved {Points.Count} points ({why})."); } catch (Exception ex) { _nextSave = Time.time + 60f; Plugin.Log.LogWarning((object)("Couldn't save the thread to " + _path + ": " + ex.Message)); } } private void HandleToggleKey(Player player) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) if (Pressed(Plugin.ToggleKey.Value) && !Typing()) { Hidden = !Hidden; Revision++; ((Character)player).Message((MessageType)1, Hidden ? "Odin's Thread: hidden. Still recording." : "Odin's Thread: shown", 0, (Sprite)null, false); } } private static bool Typing() { if ((!((Object)(object)Chat.instance != (Object)null) || !Chat.instance.HasFocus()) && !Console.IsVisible() && !TextInput.IsVisible() && !Minimap.InTextInput()) { return Menu.IsVisible(); } return true; } private static bool Pressed(KeyboardShortcut key) { //IL_0002: 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_002a: Unknown result type (might be due to invalid IL or missing references) if ((int)((KeyboardShortcut)(ref key)).MainKey == 0 || !ZInput.GetKeyDown(((KeyboardShortcut)(ref key)).MainKey, false)) { return false; } foreach (KeyCode modifier in ((KeyboardShortcut)(ref key)).Modifiers) { if (!ZInput.GetKey(modifier, false)) { return false; } } return true; } private void ReadColour() { //IL_0029: 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_0055: 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_0061: 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) string text = (Plugin.Colour.Value ?? "").Trim(); if (Named.TryGetValue(text, out var value)) { BaseColour = value; return; } Color val = default(Color); if (ColorUtility.TryParseHtmlString(text, ref val) || ColorUtility.TryParseHtmlString("#" + text, ref val)) { BaseColour = new Color(val.r, val.g, val.b); return; } BaseColour = Named["gold"]; Plugin.Log.LogWarning((object)("Colour \"" + text + "\" isn't a colour Odin knows. Using gold.")); } private static Vector3 Flat(Vector3 v) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) return new Vector3(v.x, 0f, v.z); } private static float Sqr(float v) { return v * v; } private static string Where(Vector3 p) { //IL_0005: 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) return $"({p.x:0}, {p.z:0})"; } private static float DistanceToLine(float px, float pz, float ax, float az, float bx, float bz) { float num = bx - ax; float num2 = bz - az; float num3 = Mathf.Sqrt(num * num + num2 * num2); if (num3 < 0.001f) { return Mathf.Sqrt(Sqr(px - ax) + Sqr(pz - az)); } return Mathf.Abs(num * (az - pz) - (ax - px) * num2) / num3; } private static void Debug(string message) { if (Plugin.DebugLog.Value) { Plugin.Log.LogInfo((object)message); } } } internal sealed class TrailGraphic : MaskableGraphic { private const float MinStep = 1.5f; private const float RefreshSeconds = 5f; private const int MaxQuads = 16000; private static readonly Color DeathColour = new Color(0.85f, 0.22f, 0.16f); private static readonly Color PortalColour = new Color(0.55f, 0.78f, 1f); internal RawImage Map; internal bool Large; private Rect _lastUv; private Vector2 _lastSize; private int _lastRevision = -1; private float _nextRefresh; private bool _warned; private readonly List<Vector2> _deaths = new List<Vector2>(); private readonly List<float> _deathAlpha = new List<float>(); private readonly List<Vector2> _portals = new List<Vector2>(); private readonly List<float> _portalAlpha = new List<float>(); private readonly UIVertex[] _quad = (UIVertex[])(object)new UIVertex[4]; private int _quads; protected override void Awake() { ((UIBehaviour)this).Awake(); ((Graphic)this).raycastTarget = false; } private void LateUpdate() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0040: 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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007d: 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_004c: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) Trail instance = Trail.Instance; if (!((Object)(object)Map == (Object)null) && !((Object)(object)instance == (Object)null)) { Rect uvRect = Map.uvRect; Rect rect = ((Graphic)this).rectTransform.rect; Vector2 size = ((Rect)(ref rect)).size; if (uvRect != _lastUv || size != _lastSize || instance.Revision != _lastRevision || Time.unscaledTime >= _nextRefresh) { _lastUv = uvRect; _lastSize = size; _lastRevision = instance.Revision; _nextRefresh = Time.unscaledTime + 5f; ((Graphic)this).SetVerticesDirty(); } } } protected override void OnPopulateMesh(VertexHelper vh) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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_0057: Unknown result type (might be due to invalid IL or missing references) //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_019b: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_0351: Unknown result type (might be due to invalid IL or missing references) //IL_0356: Unknown result type (might be due to invalid IL or missing references) //IL_0376: Unknown result type (might be due to invalid IL or missing references) //IL_037f: Unknown result type (might be due to invalid IL or missing references) //IL_02ef: Unknown result type (might be due to invalid IL or missing references) //IL_02f1: Unknown result type (might be due to invalid IL or missing references) //IL_02f3: Unknown result type (might be due to invalid IL or missing references) //IL_02f5: Unknown result type (might be due to invalid IL or missing references) //IL_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_02c9: Unknown result type (might be due to invalid IL or missing references) //IL_02cb: Unknown result type (might be due to invalid IL or missing references) //IL_02cd: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: 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_0315: Unknown result type (might be due to invalid IL or missing references) //IL_0319: Unknown result type (might be due to invalid IL or missing references) //IL_03a0: Unknown result type (might be due to invalid IL or missing references) //IL_03a5: Unknown result type (might be due to invalid IL or missing references) //IL_03c5: Unknown result type (might be due to invalid IL or missing references) //IL_03da: Unknown result type (might be due to invalid IL or missing references) vh.Clear(); Trail instance = Trail.Instance; Minimap instance2 = Minimap.instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance2 == (Object)null || (Object)(object)Map == (Object)null || instance.Points.Count == 0) { return; } Rect uvRect = Map.uvRect; Rect rect = ((Graphic)this).rectTransform.rect; if (((Rect)(ref uvRect)).width <= 0f || ((Rect)(ref uvRect)).height <= 0f || ((Rect)(ref rect)).width <= 0f || ((Rect)(ref rect)).height <= 0f) { return; } float num = (Large ? 2.5f : 2f); float num2 = instance2.m_textureSize / 2; float num3 = instance2.m_textureSize; float pixelSize = instance2.m_pixelSize; float num4 = ((Rect)(ref rect)).width / ((Rect)(ref uvRect)).width; float num5 = ((Rect)(ref rect)).height / ((Rect)(ref uvRect)).height; double now = Trail.Now; float dayLength = Trail.DayLength; int value = Plugin.MaxDays.Value; float value2 = Plugin.Opacity.Value; Color baseColour = instance.BaseColour; bool value3 = Plugin.MarkDeaths.Value; bool value4 = Plugin.MarkPortals.Value; Rect r = default(Rect); ((Rect)(ref r))..ctor(((Rect)(ref rect)).xMin - num, ((Rect)(ref rect)).yMin - num, ((Rect)(ref rect)).width + 2f * num, ((Rect)(ref rect)).height + 2f * num); _deaths.Clear(); _deathAlpha.Clear(); _portals.Clear(); _portalAlpha.Clear(); _quads = 0; Vector2 val = default(Vector2); bool flag = false; List<TrailPoint> points = instance.Points; Vector2 val2 = default(Vector2); for (int i = 0; i < points.Count; i++) { TrailPoint trailPoint = points[i]; float num6 = (trailPoint.X / pixelSize + num2) / num3; float num7 = (trailPoint.Z / pixelSize + num2) / num3; ((Vector2)(ref val2))..ctor(((Rect)(ref rect)).xMin + (num6 - ((Rect)(ref uvRect)).xMin) * num4, ((Rect)(ref rect)).yMin + (num7 - ((Rect)(ref uvRect)).yMin) * num5); float num8 = Fade(now - trailPoint.Time, dayLength, value) * value2; if (trailPoint.Has(2) && value3 && ((Rect)(ref rect)).Contains(val2)) { _deaths.Add(val2); _deathAlpha.Add(Mathf.Max(num8, 0.5f)); } if (trailPoint.Has(4) && value4 && ((Rect)(ref rect)).Contains(val2)) { _portals.Add(val2); _portalAlpha.Add(Mathf.Max(num8, 0.5f)); } if (trailPoint.Has(1) || !flag) { val = val2; flag = true; continue; } if ((trailPoint.Flags & 6) == 0) { Vector2 val3 = val2 - val; if (((Vector2)(ref val3)).sqrMagnitude < 2.25f && i < points.Count - 1) { continue; } } Vector2 a = val; Vector2 b = val2; val = val2; if (Clip(ref a, ref b, r)) { baseColour.a = num8; if (!AddSegment(vh, a, b, num, baseColour)) { break; } } } float num9 = (Large ? 5f : 3.5f); for (int j = 0; j < _portals.Count; j++) { Color portalColour = PortalColour; portalColour.a = _portalAlpha[j]; Ring(vh, _portals[j], num9, num, portalColour); } for (int k = 0; k < _deaths.Count; k++) { Color deathColour = DeathColour; deathColour.a = _deathAlpha[k]; Cross(vh, _deaths[k], num9 + 1f, num + 0.5f, deathColour); } } private static float Fade(double ageSeconds, float day, int maxDays) { float num = Mathf.Max(0f, (float)(ageSeconds / (double)day)); if (maxDays > 0) { return Mathf.Lerp(1f, 0.15f, num / (float)maxDays); } return Mathf.Max(0.25f, 1f - num * 0.075f); } private bool AddSegment(VertexHelper vh, Vector2 a, Vector2 b, float width, Color colour) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_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_001a: 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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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_003f: 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_0042: 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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_0073: 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_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_007f: 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) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) Vector2 val = b - a; float magnitude = ((Vector2)(ref val)).magnitude; if (magnitude < 0.0001f) { return true; } Vector2 val2 = new Vector2(0f - val.y, val.x) / magnitude * (width * 0.5f); Vector2 val3 = val / magnitude * (width * 0.35f); return Quad(vh, a - val3 - val2, a - val3 + val2, b + val3 + val2, b + val3 - val2, colour); } private bool Quad(VertexHelper vh, Vector2 v0, Vector2 v1, Vector2 v2, Vector2 v3, Color colour) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: 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_005e: 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_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0072: 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_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) if (_quads >= 16000) { if (!_warned) { _warned = true; Plugin.Log.LogInfo((object)"The thread is too busy to draw in full at this zoom. Zoom in for the rest."); } return false; } _quads++; Color32 colour2 = Color32.op_Implicit(colour); _quad[0] = Vertex(v0, colour2); _quad[1] = Vertex(v1, colour2); _quad[2] = Vertex(v2, colour2); _quad[3] = Vertex(v3, colour2); vh.AddUIVertexQuad(_quad); return true; } private static UIVertex Vertex(Vector2 pos, Color32 colour) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0008: 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_000e: 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) //IL_001b: Unknown result type (might be due to invalid IL or missing references) UIVertex simpleVert = UIVertex.simpleVert; simpleVert.position = Vector2.op_Implicit(pos); simpleVert.color = colour; return simpleVert; } private void Cross(VertexHelper vh, Vector2 at, float size, float width, Color colour) { //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) //IL_0017: 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_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0025: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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) //IL_0038: 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) Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(size, size); Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(size, 0f - size); AddSegment(vh, at - val, at + val, width, colour); AddSegment(vh, at - val2, at + val2, width, colour); } private void Ring(VertexHelper vh, Vector2 at, float radius, float width, Color colour) { //IL_0000: 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_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0055: 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_005e: Unknown result type (might be due to invalid IL or missing references) Vector2 a = at + new Vector2(radius, 0f); for (int i = 1; i <= 10; i++) { float num = (float)i * (float)Math.PI * 2f / 10f; Vector2 val = at + new Vector2(Mathf.Cos(num), Mathf.Sin(num)) * radius; AddSegment(vh, a, val, width * 0.8f, colour); a = val; } } private static bool Clip(ref Vector2 a, ref Vector2 b, Rect r) { //IL_009b: 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_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) float t = 0f; float t2 = 1f; float num = b.x - a.x; float num2 = b.y - a.y; if (!ClipEdge(0f - num, a.x - ((Rect)(ref r)).xMin, ref t, ref t2)) { return false; } if (!ClipEdge(num, ((Rect)(ref r)).xMax - a.x, ref t, ref t2)) { return false; } if (!ClipEdge(0f - num2, a.y - ((Rect)(ref r)).yMin, ref t, ref t2)) { return false; } if (!ClipEdge(num2, ((Rect)(ref r)).yMax - a.y, ref t, ref t2)) { return false; } Vector2 val = a; if (t2 < 1f) { b = val + new Vector2(num, num2) * t2; } if (t > 0f) { a = val + new Vector2(num, num2) * t; } return true; } private static bool ClipEdge(float p, float q, ref float t0, ref float t1) { if (Mathf.Approximately(p, 0f)) { return q >= 0f; } float num = q / p; if (p < 0f) { if (num > t1) { return false; } if (num > t0) { t0 = num; } } else { if (num < t0) { return false; } if (num < t1) { t1 = num; } } return true; } } internal struct TrailPoint { public const byte Start = 1; public const byte Death = 2; public const byte Portal = 4; public float X; public float Z; public double Time; public byte Flags; public bool Has(byte flag) { return (Flags & flag) != 0; } } internal static class TrailStore { private const uint Magic = 1380471887u; private const int FormatVersion = 1; internal static string Folder => Path.Combine(Paths.ConfigPath, "OdinsThread"); internal static string PathFor(PlayerProfile profile, ZNet net) { if (profile == null || (Object)(object)net == (Object)null) { return null; } string worldName = net.GetWorldName(); if (string.IsNullOrEmpty(worldName)) { return null; } string text = profile.GetFilename(); if (string.IsNullOrEmpty(text)) { text = profile.GetName(); } string path = $"{Clean(text)}__{Clean(worldName)}_{net.GetWorldUID():x}.thread"; return Path.Combine(Folder, path); } internal static List<TrailPoint> Load(string path) { List<TrailPoint> list = new List<TrailPoint>(); if (!File.Exists(path)) { return list; } using BinaryReader binaryReader = new BinaryReader(File.OpenRead(path)); if (binaryReader.ReadUInt32() != 1380471887) { throw new InvalidDataException("not an Odin's Thread file"); } int num = binaryReader.ReadInt32(); if (num != 1) { throw new InvalidDataException($"file version {num}, this build reads {1}"); } int num2 = binaryReader.ReadInt32(); if (num2 < 0 || num2 > 10000000) { throw new InvalidDataException($"implausible point count {num2}"); } list.Capacity = num2; for (int i = 0; i < num2; i++) { list.Add(new TrailPoint { X = binaryReader.ReadSingle(), Z = binaryReader.ReadSingle(), Time = binaryReader.ReadDouble(), Flags = binaryReader.ReadByte() }); } return list; } internal static void Save(string path, List<TrailPoint> points) { Directory.CreateDirectory(Path.GetDirectoryName(path)); string text = path + ".tmp"; using (BinaryWriter binaryWriter = new BinaryWriter(File.Create(text))) { binaryWriter.Write(1380471887u); binaryWriter.Write(1); binaryWriter.Write(points.Count); foreach (TrailPoint point in points) { binaryWriter.Write(point.X); binaryWriter.Write(point.Z); binaryWriter.Write(point.Time); binaryWriter.Write(point.Flags); } } if (File.Exists(path)) { File.Replace(text, path, null); } else { File.Move(text, path); } } internal static void Delete(string path) { if (File.Exists(path)) { File.Delete(path); } } private static string Clean(string s) { StringBuilder stringBuilder = new StringBuilder(s.Length); char[] invalidFileNameChars = Path.GetInvalidFileNameChars(); foreach (char c in s) { stringBuilder.Append((Array.IndexOf(invalidFileNameChars, c) >= 0) ? '-' : c); } return stringBuilder.ToString().Trim(); } } internal static class BuildInfo { public const string Version = "0.1.0"; } }