Decompiled source of DALCompass v0.3.0

plugins/DALCompass/DalCompass.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using DalCompass.Logic;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[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: InternalsVisibleTo("DALCompass.Harness")]
[assembly: AssemblyCompany("Laoch")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright (c) Laoch")]
[assembly: AssemblyFileVersion("0.3.0.0")]
[assembly: AssemblyInformationalVersion("0.3.0+0b87f607d633e34fe3e0de7410f731404f5b15df")]
[assembly: AssemblyProduct("DALCompass")]
[assembly: AssemblyTitle("DalCompass")]
[assembly: AssemblyVersion("0.3.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 DalCompass
{
	[BepInPlugin("com.laoch.dalcompass", "DAL Compass", "0.3.0")]
	public class DalCompassPlugin : BaseUnityPlugin
	{
		public const string Guid = "com.laoch.dalcompass";

		public const string Version = "0.3.0";

		private ConfigEntry<bool> _show;

		private ConfigEntry<bool> _showDeaths;

		private ConfigEntry<KeyCode> _toggleKey;

		private ConfigEntry<KeyCode> _clearKey;

		private ConfigEntry<KeyCode> _styleKey;

		private ConfigEntry<CompassStyle> _style;

		private ConfigEntry<float> _barX;

		private ConfigEntry<float> _barY;

		private ConfigEntry<float> _dialX;

		private ConfigEntry<float> _dialY;

		private ConfigEntry<float> _textX;

		private ConfigEntry<float> _textY;

		private Harmony _harmony;

		private GUIStyle _label;

		private GUIStyle _major;

		private GUIStyle _small;

		private Texture2D _white;

		private DeathMarkBook _book = new DeathMarkBook();

		private string _bookPath;

		private const float GraveMatchRadius = 60f;

		private bool _dragging;

		private Vector2 _grab;

		private Vector2 _dragOffset;

		internal static DalCompassPlugin Instance { get; private set; }

		internal static ManualLogSource Log => ((BaseUnityPlugin)Instance).Logger;

		private static bool InWorld
		{
			get
			{
				if ((Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsDedicated())
				{
					return (Object)(object)Player.m_localPlayer != (Object)null;
				}
				return false;
			}
		}

		internal DeathMarkBook BookForTest
		{
			get
			{
				EnsureLoaded();
				return _book;
			}
		}

		private void Awake()
		{
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Expected O, but got Unknown
			Instance = this;
			_show = ((BaseUnityPlugin)this).Config.Bind<bool>("Compass", "ShowCompass", true, "Show the heading bar at the top of the screen. Personal preference; has no effect on anyone else.");
			_toggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Compass", "ToggleKey", (KeyCode)290, "Key that shows or hides the compass.");
			_style = ((BaseUnityPlugin)this).Config.Bind<CompassStyle>("Compass", "Style", CompassStyle.Bar, "Bar: a heading strip across the top. Dial: a round compass in the top-right corner. Text: just a line of text.");
			_styleKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Compass", "StyleKey", (KeyCode)289, "Key that switches to the next style (Bar, Dial, Text). The choice is remembered.");
			_barX = ((BaseUnityPlugin)this).Config.Bind<float>("Position", "BarOffsetX", 0f, "Where you dragged the Bar style, as a fraction of the screen width from its home position. Drag it with the mouse while the inventory is open; middle-click it to reset.");
			_barY = ((BaseUnityPlugin)this).Config.Bind<float>("Position", "BarOffsetY", 0f, "Same, vertical (fraction of screen height).");
			_dialX = ((BaseUnityPlugin)this).Config.Bind<float>("Position", "DialOffsetX", 0f, "Same for the Dial style.");
			_dialY = ((BaseUnityPlugin)this).Config.Bind<float>("Position", "DialOffsetY", 0f, "Same for the Dial style, vertical.");
			_textX = ((BaseUnityPlugin)this).Config.Bind<float>("Position", "TextOffsetX", 0f, "Same for the Text style.");
			_textY = ((BaseUnityPlugin)this).Config.Bind<float>("Position", "TextOffsetY", 0f, "Same for the Text style, vertical.");
			_showDeaths = ((BaseUnityPlugin)this).Config.Bind<bool>("Deaths", "ShowDeathMarkers", true, "Mark your last three deaths on the bar (red, newest brightest) with a rounded distance.");
			_clearKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Deaths", "ClearKey", (KeyCode)291, "Key that forgets all remembered death markers.");
			_harmony = new Harmony("com.laoch.dalcompass");
			_harmony.PatchAll(typeof(DalCompassPlugin).Assembly);
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		private string PathFor()
		{
			string text = (((Object)(object)Game.instance != (Object)null && Game.instance.GetPlayerProfile() != null) ? Game.instance.GetPlayerProfile().GetName() : "unknown");
			long num = ((ZNet.World != null) ? ZNet.World.m_uid : 0);
			char[] invalidFileNameChars = Path.GetInvalidFileNameChars();
			foreach (char oldChar in invalidFileNameChars)
			{
				text = text.Replace(oldChar, '_');
			}
			return Path.Combine(Paths.ConfigPath, "DalCompass", num + "-" + text + ".txt");
		}

		private void EnsureLoaded()
		{
			string text = PathFor();
			if (text == _bookPath)
			{
				return;
			}
			_bookPath = text;
			try
			{
				_book = DeathMarkBook.Parse(File.Exists(text) ? File.ReadAllText(text) : "");
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not read death markers (" + ex.Message + "); starting empty."));
				_book = new DeathMarkBook();
			}
		}

		private void Save()
		{
			try
			{
				Directory.CreateDirectory(Path.GetDirectoryName(_bookPath));
				string text = _bookPath + ".tmp";
				File.WriteAllText(text, _book.Serialize());
				if (File.Exists(_bookPath))
				{
					File.Delete(_bookPath);
				}
				File.Move(text, _bookPath);
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not save death markers: " + ex.Message));
			}
		}

		internal void RecordDeath(Vector3 at)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			EnsureLoaded();
			_book.Add(at.x, at.z, DateTimeOffset.UtcNow.ToUnixTimeSeconds());
			Save();
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Death marker saved (" + _book.Items.Count + " kept)."));
		}

		internal void LogGraveProblem(Exception e)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not clear a grave marker: " + e.Message));
		}

		internal void GraveEmptied(Vector3 at)
		{
			//IL_0014: 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)
			if (InWorld)
			{
				EnsureLoaded();
				if (!_book.RemoveNearest(at.x, at.z, 60f))
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)"A grave of yours vanished but no marker was near it.");
					return;
				}
				((BaseUnityPlugin)this).Logger.LogInfo((object)("Grave emptied: its marker was cleared (" + _book.Items.Count + " left)."));
				Save();
				((Character)Player.m_localPlayer).Message((MessageType)1, "Grave marker cleared", 0, (Sprite)null, false);
			}
		}

		private void Update()
		{
			//IL_0030: 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_0097: Unknown result type (might be due to invalid IL or missing references)
			if (!InWorld)
			{
				_bookPath = null;
				return;
			}
			bool flag = (Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus();
			if (Input.GetKeyDown(_toggleKey.Value))
			{
				_show.Value = !_show.Value;
			}
			if (Input.GetKeyDown(_styleKey.Value) && !flag)
			{
				_style.Value = CompassStyles.Next(_style.Value);
				_show.Value = true;
			}
			if (Input.GetKeyDown(_clearKey.Value) && (!((Object)(object)Chat.instance != (Object)null) || !Chat.instance.HasFocus()))
			{
				EnsureLoaded();
				int count = _book.Items.Count;
				_book.Clear();
				Save();
				((Character)Player.m_localPlayer).Message((MessageType)1, (count == 0) ? "No death markers to clear" : "Death markers cleared", 0, (Sprite)null, false);
			}
		}

		private void OnGUI()
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: 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_010e: 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_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Expected O, but got Unknown
			//IL_00bf: 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_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Expected O, but got Unknown
			//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_00f1: Expected O, but got Unknown
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Invalid comparison between Unknown and I4
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Invalid comparison between Unknown and I4
			//IL_0185: 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_019b: 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_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: 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_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_0364: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: 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)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0317: Unknown result type (might be due to invalid IL or missing references)
			//IL_034f: Unknown result type (might be due to invalid IL or missing references)
			if (!_show.Value || !InWorld || (Object)(object)GameCamera.instance == (Object)null || Player.m_localPlayer.IsSleeping() || ((Object)(object)Hud.instance != (Object)null && !Hud.instance.m_rootObject.activeSelf))
			{
				return;
			}
			EnsureLoaded();
			if ((Object)(object)_white == (Object)null)
			{
				_white = new Texture2D(1, 1);
				_white.SetPixel(0, 0, Color.white);
				_white.Apply();
			}
			if (_label == null)
			{
				_label = new GUIStyle(GUI.skin.label)
				{
					alignment = (TextAnchor)4,
					fontSize = 14
				};
				_major = new GUIStyle(_label)
				{
					fontSize = 17,
					fontStyle = (FontStyle)1
				};
				_small = new GUIStyle(_label)
				{
					fontSize = 12
				};
			}
			Rect home = HomeRect(_style.Value);
			Vector2 val = CurrentOffset(_style.Value, home);
			Rect box = default(Rect);
			((Rect)(ref box))..ctor(((Rect)(ref home)).x + val.x, ((Rect)(ref home)).y + val.y, ((Rect)(ref home)).width, ((Rect)(ref home)).height);
			bool flag = Cursor.visible && (int)Cursor.lockState != 1;
			Event current = Event.current;
			if ((int)current.type != 7)
			{
				if (flag)
				{
					HandleMouse(current, home, box);
				}
				return;
			}
			float heading = CompassMath.Normalize(((Component)GameCamera.instance).transform.eulerAngles.y);
			Color color = GUI.color;
			Matrix4x4 matrix = GUI.matrix;
			GUI.matrix = Matrix4x4.Translate(new Vector3(val.x, val.y, 0f)) * matrix;
			switch (_style.Value)
			{
			case CompassStyle.Dial:
				DrawDial(heading);
				break;
			case CompassStyle.Text:
				DrawText(heading);
				break;
			default:
				DrawBar(heading);
				break;
			}
			GUI.matrix = matrix;
			if (flag)
			{
				GUI.color = (_dragging ? new Color(1f, 0.85f, 0.4f, 0.9f) : new Color(1f, 1f, 1f, 0.35f));
				float num = 1.5f;
				GUI.DrawTexture(new Rect(((Rect)(ref box)).x, ((Rect)(ref box)).y, ((Rect)(ref box)).width, num), (Texture)(object)_white);
				GUI.DrawTexture(new Rect(((Rect)(ref box)).x, ((Rect)(ref box)).yMax - num, ((Rect)(ref box)).width, num), (Texture)(object)_white);
				GUI.DrawTexture(new Rect(((Rect)(ref box)).x, ((Rect)(ref box)).y, num, ((Rect)(ref box)).height), (Texture)(object)_white);
				GUI.DrawTexture(new Rect(((Rect)(ref box)).xMax - num, ((Rect)(ref box)).y, num, ((Rect)(ref box)).height), (Texture)(object)_white);
				GUI.color = new Color(1f, 1f, 1f, 0.8f);
				GUI.Label(new Rect(((Rect)(ref box)).center.x - 150f, Mathf.Min(((Rect)(ref box)).yMax + 2f, (float)Screen.height - 20f), 300f, 18f), "drag to move  ·  middle-click to reset", _small);
			}
			GUI.color = color;
		}

		private static Rect HomeRect(CompassStyle s)
		{
			//IL_0039: 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_007d: Unknown result type (might be due to invalid IL or missing references)
			float num = Screen.width;
			return (Rect)(s switch
			{
				CompassStyle.Dial => new Rect(num - 62f - 40f - 62f - 14f, 26f, 152f, 218f), 
				CompassStyle.Text => new Rect(num / 2f - 150f, 14f, 300f, 80f), 
				_ => new Rect(num / 2f - 260f, 14f, 520f, 52f), 
			});
		}

		private ConfigEntry<float> OffsetX(CompassStyle s)
		{
			return (ConfigEntry<float>)(s switch
			{
				CompassStyle.Text => _textX, 
				CompassStyle.Dial => _dialX, 
				_ => _barX, 
			});
		}

		private ConfigEntry<float> OffsetY(CompassStyle s)
		{
			return (ConfigEntry<float>)(s switch
			{
				CompassStyle.Text => _textY, 
				CompassStyle.Dial => _dialY, 
				_ => _barY, 
			});
		}

		private Vector2 CurrentOffset(CompassStyle s, Rect home)
		{
			//IL_0072: 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)
			if (_dragging)
			{
				return _dragOffset;
			}
			float dx = DragMath.FromFraction(OffsetX(s).Value, Screen.width);
			float dy = DragMath.FromFraction(OffsetY(s).Value, Screen.height);
			DragMath.Clamp(((Rect)(ref home)).x, ((Rect)(ref home)).y, ((Rect)(ref home)).width, ((Rect)(ref home)).height, Screen.width, Screen.height, ref dx, ref dy);
			return new Vector2(dx, dy);
		}

		private void HandleMouse(Event ev, Rect home, Rect box)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: 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_00c5: Invalid comparison between Unknown and I4
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Invalid comparison between Unknown and I4
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: 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_007d: Unknown result type (might be due to invalid IL or missing references)
			CompassStyle value = _style.Value;
			Vector2 mousePosition = ev.mousePosition;
			if ((int)ev.type == 0 && ((Rect)(ref box)).Contains(mousePosition))
			{
				if (ev.button == 0)
				{
					_dragging = true;
					_grab = mousePosition - new Vector2(((Rect)(ref box)).x, ((Rect)(ref box)).y);
					_dragOffset = new Vector2(((Rect)(ref box)).x - ((Rect)(ref home)).x, ((Rect)(ref box)).y - ((Rect)(ref home)).y);
					ev.Use();
				}
				else if (ev.button == 2)
				{
					OffsetX(value).Value = 0f;
					OffsetY(value).Value = 0f;
					ev.Use();
				}
			}
			else if ((int)ev.type == 3 && _dragging)
			{
				float dx = mousePosition.x - _grab.x - ((Rect)(ref home)).x;
				float dy = mousePosition.y - _grab.y - ((Rect)(ref home)).y;
				DragMath.Clamp(((Rect)(ref home)).x, ((Rect)(ref home)).y, ((Rect)(ref home)).width, ((Rect)(ref home)).height, Screen.width, Screen.height, ref dx, ref dy);
				_dragOffset = new Vector2(dx, dy);
				ev.Use();
			}
			else if ((int)ev.type == 1 && _dragging)
			{
				_dragging = false;
				OffsetX(value).Value = DragMath.ToFraction(_dragOffset.x, Screen.width);
				OffsetY(value).Value = DragMath.ToFraction(_dragOffset.y, Screen.height);
				ev.Use();
			}
		}

		private void DrawBar(float heading)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: 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_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			float num = 2.8888888f;
			float num2 = (float)Screen.width / 2f;
			GUI.color = new Color(0f, 0f, 0f, 0.35f);
			GUI.DrawTexture(new Rect(num2 - 260f, 14f, 520f, 30f), (Texture)(object)_white);
			foreach (CompassTick item in CompassMath.Ticks(heading, 90f, 15f))
			{
				float num3 = num2 + item.Offset * num;
				float num4 = 1f - Mathf.Abs(item.Offset) / 90f * 0.7f;
				GUI.color = new Color(1f, 0.93f, 0.75f, num4);
				if (item.Major)
				{
					GUI.Label(new Rect(num3 - 20f, 16f, 40f, 24f), item.Label, _major);
				}
				else
				{
					GUI.DrawTexture(new Rect(num3 - 0.5f, 25f, 1f, 8f), (Texture)(object)_white);
				}
			}
			GUI.color = new Color(1f, 0.85f, 0.4f, 1f);
			GUI.DrawTexture(new Rect(num2 - 1f, 15f, 2f, 5f), (Texture)(object)_white);
			if (_showDeaths.Value)
			{
				DrawDeaths(heading, 90f, num, num2, 14f);
			}
		}

		private void DrawDial(float heading)
		{
			//IL_002d: 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_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: 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_0132: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0287: Unknown result type (might be due to invalid IL or missing references)
			//IL_02af: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0302: 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_031f: Unknown result type (might be due to invalid IL or missing references)
			float num = (float)Screen.width - 62f - 40f;
			float num2 = 102f;
			GUI.color = new Color(0f, 0f, 0f, 0.35f);
			GUI.DrawTexture(new Rect(num - 62f - 14f, num2 - 62f - 14f, 152f, 152f), (Texture)(object)_white);
			for (int i = 0; i < 360; i += 15)
			{
				CompassStyles.DialPoint(CompassMath.Delta(heading, i), 62f, out var right, out var up);
				if (i % 45 == 0)
				{
					GUI.color = new Color(1f, 0.93f, 0.75f, 1f);
					GUI.Label(new Rect(num + right - 20f, num2 - up - 12f, 40f, 24f), CompassMath.Cardinal(i), (i % 90 == 0) ? _major : _label);
				}
				else
				{
					GUI.color = new Color(1f, 0.93f, 0.75f, 0.6f);
					GUI.DrawTexture(new Rect(num + right - 1.5f, num2 - up - 1.5f, 3f, 3f), (Texture)(object)_white);
				}
			}
			GUI.color = new Color(1f, 0.85f, 0.4f, 1f);
			GUI.DrawTexture(new Rect(num - 2f, num2 - 62f - 16f, 4f, 8f), (Texture)(object)_white);
			GUI.Label(new Rect(num - 30f, num2 - 11f, 60f, 22f), Mathf.RoundToInt(heading) + "°", _small);
			if (_showDeaths.Value)
			{
				Vector3 position = ((Component)Player.m_localPlayer).transform.position;
				IReadOnlyList<DeathMark> items = _book.Items;
				for (int num3 = items.Count - 1; num3 >= 0; num3--)
				{
					DeathMark deathMark = items[num3];
					CompassStyles.DialPoint(CompassMath.Delta(heading, MarkerMath.Bearing(position.x, position.z, deathMark.X, deathMark.Z)), 38f, out var right2, out var up2);
					float num4 = num3 switch
					{
						1 => 0.75f, 
						0 => 1f, 
						_ => 0.5f, 
					};
					GUI.color = new Color(0.9f, 0.15f, 0.12f, num4);
					GUI.DrawTexture(new Rect(num + right2 - 5f, num2 - up2 - 5f, 10f, 10f), (Texture)(object)_white);
					GUI.color = new Color(1f, 0.85f, 0.8f, num4);
					GUI.Label(new Rect(num - 50f, num2 + 62f + 18f + (float)num3 * 16f, 100f, 18f), num3 + 1 + "  " + FormatDistance(MarkerMath.Distance(position.x, position.z, deathMark.X, deathMark.Z)), _small);
				}
			}
		}

		private void DrawText(float heading)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: 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_00df: 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_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			float num = (float)Screen.width / 2f;
			GUI.color = new Color(1f, 0.93f, 0.75f, 1f);
			GUI.Label(new Rect(num - 150f, 14f, 300f, 26f), CompassMath.Cardinal(heading) + "  " + Mathf.RoundToInt(heading) + "°", _major);
			if (_showDeaths.Value)
			{
				Vector3 position = ((Component)Player.m_localPlayer).transform.position;
				IReadOnlyList<DeathMark> items = _book.Items;
				for (int i = 0; i < items.Count; i++)
				{
					DeathMark deathMark = items[i];
					GUI.color = new Color(1f, 0.6f, 0.55f, i switch
					{
						1 => 0.75f, 
						0 => 1f, 
						_ => 0.5f, 
					});
					float deg = MarkerMath.Bearing(position.x, position.z, deathMark.X, deathMark.Z);
					GUI.Label(new Rect(num - 150f, 40f + (float)i * 18f, 300f, 18f), "Grave " + (i + 1) + ": " + FormatDistance(MarkerMath.Distance(position.x, position.z, deathMark.X, deathMark.Z)) + " " + CompassMath.Cardinal(deg), _small);
				}
			}
		}

		private void DrawDeaths(float heading, float halfSpan, float pxPerDeg, float cx, float y)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: 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_0052: 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_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: 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_0152: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)Player.m_localPlayer).transform.position;
			IReadOnlyList<DeathMark> items = _book.Items;
			for (int num = items.Count - 1; num >= 0; num--)
			{
				DeathMark deathMark = items[num];
				float meters = MarkerMath.Distance(position.x, position.z, deathMark.X, deathMark.Z);
				BarPlacement barPlacement = MarkerMath.Place(heading, MarkerMath.Bearing(position.x, position.z, deathMark.X, deathMark.Z), halfSpan);
				float num2 = cx + barPlacement.Offset * pxPerDeg;
				float num3 = num switch
				{
					1 => 0.75f, 
					0 => 1f, 
					_ => 0.5f, 
				};
				GUI.color = new Color(0.9f, 0.15f, 0.12f, num3);
				GUI.DrawTexture(new Rect(num2 - 5f, y + 8f, 10f, 14f), (Texture)(object)_white);
				GUI.color = new Color(1f, 0.85f, 0.8f, num3);
				string text = FormatDistance(meters);
				if (barPlacement.PinnedToEdge)
				{
					text = ((barPlacement.Offset < 0f) ? ("< " + text) : (text + " >"));
				}
				GUI.Label(new Rect(num2 - 45f, y + 31f, 90f, 18f), text, _small);
			}
		}

		internal static string FormatDistance(float meters)
		{
			if (meters < 1000f)
			{
				return (Mathf.Round(meters / 10f) * 10f).ToString("F0") + " m";
			}
			return (meters / 1000f).ToString("F1") + " km";
		}
	}
	[HarmonyPatch(typeof(ZNetScene), "OnZDODestroyed")]
	internal static class GraveDestroyedPatch
	{
		private static readonly int Tombstone = StringExtensionMethods.GetStableHashCode("Player_tombstone");

		private static void Prefix(ZDO zdo)
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (zdo != null && zdo.GetPrefab() == Tombstone && !((Object)(object)DalCompassPlugin.Instance == (Object)null) && !((Object)(object)Player.m_localPlayer == (Object)null) && !((Object)(object)Game.instance == (Object)null) && zdo.GetLong(ZDOVars.s_owner, 0L) == Game.instance.GetPlayerProfile().GetPlayerID())
				{
					DalCompassPlugin.Instance.GraveEmptied(zdo.GetPosition());
				}
			}
			catch (Exception e)
			{
				DalCompassPlugin.Instance?.LogGraveProblem(e);
			}
		}
	}
	[HarmonyPatch(typeof(Player), "OnDeath")]
	internal static class PlayerOnDeathPatch
	{
		private static void Prefix(Player __instance)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)__instance == (Object)null) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && !((Object)(object)DalCompassPlugin.Instance == (Object)null))
			{
				DalCompassPlugin.Instance.RecordDeath(((Component)__instance).transform.position);
			}
		}
	}
	internal static class ModReporter
	{
		private struct Entry
		{
			public string Guid;

			public string Version;

			public string Hash;
		}

		private const string ReportRpc = "DAL_ModReport";

		private const string VerdictRpc = "DAL_ModVerdict";

		private const int ReportVersion = 1;

		private static List<Entry> _cache;

		private static List<Entry> Collect()
		{
			if (_cache != null)
			{
				return _cache;
			}
			List<Entry> list = new List<Entry>();
			foreach (PluginInfo value in Chainloader.PluginInfos.Values)
			{
				string hash = "";
				try
				{
					using SHA256 sHA = SHA256.Create();
					using FileStream inputStream = File.OpenRead(value.Location);
					byte[] array = sHA.ComputeHash(inputStream);
					StringBuilder stringBuilder = new StringBuilder(array.Length * 2);
					byte[] array2 = array;
					foreach (byte b in array2)
					{
						stringBuilder.Append(b.ToString("x2"));
					}
					hash = stringBuilder.ToString();
				}
				catch (Exception)
				{
				}
				list.Add(new Entry
				{
					Guid = value.Metadata.GUID,
					Version = value.Metadata.Version.ToString(),
					Hash = hash
				});
			}
			list.Sort((Entry a, Entry entry) => string.CompareOrdinal(a.Guid, entry.Guid));
			_cache = list;
			WriteMyMods(list);
			return list;
		}

		private static void WriteMyMods(List<Entry> list)
		{
			try
			{
				StringBuilder stringBuilder = new StringBuilder("# The mods this game is running, in the server's ModAllowlist.txt format. Copy the lines you want to allow.\n# Any version is accepted unless a line says otherwise: add |1.2.3 after the id to require that version, or |1.2.3|sha256 to require the exact file.\n");
				foreach (Entry item in list)
				{
					stringBuilder.Append(item.Guid).Append("  # ").Append(item.Version)
						.Append('\n');
				}
				string text = Path.Combine(Paths.ConfigPath, "DalCompass");
				Directory.CreateDirectory(text);
				File.WriteAllText(Path.Combine(text, "my-mods.txt"), stringBuilder.ToString());
			}
			catch (Exception)
			{
			}
		}

		internal static void Send(ZNetPeer peer)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			List<Entry> list = Collect();
			ZPackage val = new ZPackage();
			val.Write(1);
			val.Write(list.Count);
			foreach (Entry item in list)
			{
				val.Write(item.Guid);
				val.Write(item.Version);
				val.Write(item.Hash);
			}
			peer.m_rpc.Invoke("DAL_ModReport", new object[1] { val });
			peer.m_rpc.Register<string>("DAL_ModVerdict", (Action<ZRpc, string>)delegate(ZRpc rpc, string reason)
			{
				DalCompassPlugin.Log.LogWarning((object)reason);
			});
		}
	}
	[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
	internal static class ReportOnConnect
	{
		private static void Postfix(ZNet __instance, ZNetPeer peer)
		{
			if ((Object)(object)__instance == (Object)null || __instance.IsServer() || peer == null || !peer.m_server)
			{
				return;
			}
			try
			{
				ModReporter.Send(peer);
			}
			catch (Exception ex)
			{
				DalCompassPlugin.Log.LogWarning((object)("Could not send the mod report: " + ex.Message));
			}
		}
	}
}
namespace DalCompass.Logic
{
	public struct CompassTick
	{
		public float Offset;

		public string Label;

		public bool Major;
	}
	public static class CompassMath
	{
		private static readonly string[] Names = new string[8] { "N", "NE", "E", "SE", "S", "SW", "W", "NW" };

		public static float Normalize(float deg)
		{
			deg %= 360f;
			if (!(deg < 0f))
			{
				return deg;
			}
			return deg + 360f;
		}

		public static float Delta(float from, float target)
		{
			float num = Normalize(target - from);
			if (!(num > 180f))
			{
				return num;
			}
			return num - 360f;
		}

		public static string Cardinal(float deg)
		{
			int num = (int)Math.Round(Normalize(deg) / 45f) % 8;
			return Names[num];
		}

		public static List<CompassTick> Ticks(float heading, float halfSpan, float step)
		{
			List<CompassTick> list = new List<CompassTick>();
			for (float num = (float)Math.Ceiling((heading - halfSpan) / step) * step; num <= heading + halfSpan + 0.001f; num += step)
			{
				float num2 = Normalize(num);
				bool flag = Math.Abs(num2 % 45f) < 0.001f || Math.Abs(num2 % 45f - 45f) < 0.001f;
				list.Add(new CompassTick
				{
					Offset = num - heading,
					Label = (flag ? Cardinal(num2) : ""),
					Major = flag
				});
			}
			return list;
		}
	}
	public struct DeathMark
	{
		public float X;

		public float Z;

		public long Utc;
	}
	public sealed class DeathMarkBook
	{
		public const int Capacity = 3;

		private readonly List<DeathMark> _items = new List<DeathMark>();

		public IReadOnlyList<DeathMark> Items => _items;

		public void Add(float x, float z, long utc)
		{
			_items.Insert(0, new DeathMark
			{
				X = x,
				Z = z,
				Utc = utc
			});
			while (_items.Count > 3)
			{
				_items.RemoveAt(_items.Count - 1);
			}
		}

		public void Clear()
		{
			_items.Clear();
		}

		public bool RemoveNearest(float x, float z, float radius)
		{
			int num = -1;
			float num2 = float.MaxValue;
			for (int i = 0; i < _items.Count; i++)
			{
				float num3 = _items[i].X - x;
				float num4 = _items[i].Z - z;
				float num5 = (float)Math.Sqrt(num3 * num3 + num4 * num4);
				if (num5 <= radius && num5 < num2)
				{
					num = i;
					num2 = num5;
				}
			}
			if (num < 0)
			{
				return false;
			}
			_items.RemoveAt(num);
			return true;
		}

		public string Serialize()
		{
			StringBuilder stringBuilder = new StringBuilder();
			foreach (DeathMark item in _items)
			{
				float x = item.X;
				StringBuilder stringBuilder2 = stringBuilder.Append(x.ToString("R", CultureInfo.InvariantCulture)).Append('|');
				x = item.Z;
				StringBuilder stringBuilder3 = stringBuilder2.Append(x.ToString("R", CultureInfo.InvariantCulture)).Append('|');
				long utc = item.Utc;
				stringBuilder3.Append(utc.ToString(CultureInfo.InvariantCulture)).Append('\n');
			}
			return stringBuilder.ToString();
		}

		public static DeathMarkBook Parse(string text)
		{
			DeathMarkBook deathMarkBook = new DeathMarkBook();
			if (string.IsNullOrEmpty(text))
			{
				return deathMarkBook;
			}
			string[] array = text.Split(new char[1] { '\n' });
			for (int i = 0; i < array.Length; i++)
			{
				string[] array2 = array[i].Trim().Split(new char[1] { '|' });
				if (array2.Length == 3 && float.TryParse(array2[0], NumberStyles.Float, CultureInfo.InvariantCulture, out var result) && float.TryParse(array2[1], NumberStyles.Float, CultureInfo.InvariantCulture, out var result2) && !float.IsNaN(result) && !float.IsInfinity(result) && !float.IsNaN(result2) && !float.IsInfinity(result2) && long.TryParse(array2[2], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result3) && deathMarkBook._items.Count < 3)
				{
					deathMarkBook._items.Add(new DeathMark
					{
						X = result,
						Z = result2,
						Utc = result3
					});
				}
			}
			return deathMarkBook;
		}
	}
	public struct BarPlacement
	{
		public float Offset;

		public bool PinnedToEdge;
	}
	public static class MarkerMath
	{
		public static float Bearing(float fromX, float fromZ, float toX, float toZ)
		{
			return CompassMath.Normalize((float)(Math.Atan2(toX - fromX, toZ - fromZ) * 180.0 / Math.PI));
		}

		public static float Distance(float fromX, float fromZ, float toX, float toZ)
		{
			float num = toX - fromX;
			float num2 = toZ - fromZ;
			return (float)Math.Sqrt(num * num + num2 * num2);
		}

		public static BarPlacement Place(float heading, float bearing, float halfSpan)
		{
			float num = CompassMath.Delta(heading, bearing);
			if (num > halfSpan)
			{
				return new BarPlacement
				{
					Offset = halfSpan,
					PinnedToEdge = true
				};
			}
			if (num < 0f - halfSpan)
			{
				return new BarPlacement
				{
					Offset = 0f - halfSpan,
					PinnedToEdge = true
				};
			}
			return new BarPlacement
			{
				Offset = num
			};
		}
	}
	public enum CompassStyle
	{
		Bar,
		Dial,
		Text
	}
	public static class CompassStyles
	{
		public static CompassStyle Next(CompassStyle s)
		{
			return (CompassStyle)((int)(s + 1) % 3);
		}

		public static void DialPoint(float offsetDeg, float radius, out float right, out float up)
		{
			double num = (double)offsetDeg * Math.PI / 180.0;
			right = (float)(Math.Sin(num) * (double)radius);
			up = (float)(Math.Cos(num) * (double)radius);
		}
	}
	public static class DragMath
	{
		public static void Clamp(float x, float y, float w, float h, float screenW, float screenH, ref float dx, ref float dy)
		{
			float num = 0f - x;
			float num2 = screenW - w - x;
			float num3 = 0f - y;
			float num4 = screenH - h - y;
			if (num2 < num)
			{
				num2 = num;
			}
			if (num4 < num3)
			{
				num4 = num3;
			}
			dx = Math.Max(num, Math.Min(num2, float.IsNaN(dx) ? 0f : dx));
			dy = Math.Max(num3, Math.Min(num4, float.IsNaN(dy) ? 0f : dy));
		}

		public static float ToFraction(float pixels, float screenSize)
		{
			if (!(screenSize < 1f))
			{
				return pixels / screenSize;
			}
			return 0f;
		}

		public static float FromFraction(float fraction, float screenSize)
		{
			if (!float.IsNaN(fraction) && !float.IsInfinity(fraction))
			{
				return fraction * screenSize;
			}
			return 0f;
		}
	}
}