Decompiled source of Summit v1.0.7

Summit.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyCompany("Altimeter")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+7db9a4b2496a77f405144c7e63e00769ede8c21e")]
[assembly: AssemblyProduct("Altimeter")]
[assembly: AssemblyTitle("Altimeter")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Summit
{
	[Serializable]
	public class PeakRecord
	{
		public string character;

		public long worldUID;

		public float peak;

		public string timestamp;
	}
	[Serializable]
	public class SummitDataStore
	{
		public List<PeakRecord> records = new List<PeakRecord>();
	}
	public class SummitData
	{
		private static readonly string FilePath = Path.Combine(Paths.ConfigPath, "norsetools.summit.data.json");

		private SummitDataStore store;

		private SummitData(SummitDataStore store)
		{
			this.store = store;
		}

		public static SummitData Load()
		{
			if (File.Exists(FilePath))
			{
				try
				{
					SummitDataStore summitDataStore = JsonUtility.FromJson<SummitDataStore>(File.ReadAllText(FilePath));
					if (summitDataStore != null)
					{
						return new SummitData(summitDataStore);
					}
				}
				catch (Exception ex)
				{
					Debug.LogWarning((object)$"[Summit] Failed to load data: {ex.Message}");
				}
			}
			return new SummitData(new SummitDataStore());
		}

		public void Save()
		{
			try
			{
				string contents = JsonUtility.ToJson((object)store, true);
				File.WriteAllText(FilePath, contents);
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)$"[Summit] Failed to save data: {ex.Message}");
			}
		}

		public float GetPeak(string character, long worldUID)
		{
			return FindRecord(character, worldUID)?.peak ?? 0f;
		}

		public void SetPeak(string character, long worldUID, float peak)
		{
			PeakRecord peakRecord = FindRecord(character, worldUID);
			if (peakRecord != null)
			{
				peakRecord.peak = peak;
				peakRecord.timestamp = DateTime.UtcNow.ToString("o");
				return;
			}
			store.records.Add(new PeakRecord
			{
				character = character,
				worldUID = worldUID,
				peak = peak,
				timestamp = DateTime.UtcNow.ToString("o")
			});
		}

		public List<PeakRecord> GetAllRecords()
		{
			return store.records;
		}

		private PeakRecord FindRecord(string character, long worldUID)
		{
			foreach (PeakRecord record in store.records)
			{
				if (record.character == character && record.worldUID == worldUID)
				{
					return record;
				}
			}
			return null;
		}
	}
	[BepInPlugin("norsetools.summit", "Summit", "1.0.7")]
	public class SummitPlugin : BaseUnityPlugin
	{
		public const string PluginGUID = "norsetools.summit";

		public const string PluginName = "Summit";

		public const string PluginVersion = "1.0.7";

		private const float SeaLevel = 30f;

		private const float PaddingH = 24f;

		private const float PaddingV = 8f;

		private const float MinWidth = 140f;

		private const float BoxHeight = 58f;

		private ConfigEntry<KeyboardShortcut> toggleEditMode;

		private ConfigEntry<KeyboardShortcut> summitKey;

		private ConfigEntry<int> fontSize;

		private ConfigEntry<float> posX;

		private ConfigEntry<float> posY;

		private ConfigEntry<float> summitThreshold;

		private float currentAltitude;

		private float personalBest;

		private float newRecordTimer;

		private string currentCharacter;

		private long currentWorldUID;

		private bool editMode;

		private bool isDragging;

		private Vector2 dragOffset;

		private GUIStyle boxStyle;

		private GUIStyle altitudeStyle;

		private GUIStyle peakStyle;

		private GUIStyle recordStyle;

		private GUIStyle editLabelStyle;

		private bool stylesInitialized;

		private SummitData data;

		private Rect windowRect;

		private Font norseFont;

		private bool fontResolved;

		private static SummitPlugin instance;

		private void Awake()
		{
			//IL_002a: 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)
			instance = this;
			toggleEditMode = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("UI", "ToggleEditMode", new KeyboardShortcut((KeyCode)289, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }), "Hotkey to toggle drag-to-reposition mode");
			summitKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("UI", "SummitShout", new KeyboardShortcut((KeyCode)277, Array.Empty<KeyCode>()), "Hotkey to shout your summit stats");
			fontSize = ((BaseUnityPlugin)this).Config.Bind<int>("UI", "FontSize", 18, "HUD font size");
			posX = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "PositionX", 0.5f, "Horizontal position (0-1, left to right)");
			posY = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "PositionY", 0.02f, "Vertical position (0-1, top to bottom)");
			summitThreshold = ((BaseUnityPlugin)this).Config.Bind<float>("Gameplay", "SummitThreshold", 5f, "Must be within this many Wood Poles of your peak to shout");
			data = SummitData.Load();
		}

		private void Update()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)Player.m_localPlayer == (Object)null))
			{
				KeyboardShortcut value = toggleEditMode.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					editMode = !editMode;
					SetCursorState(editMode);
				}
				value = summitKey.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					DoSummitShout();
				}
				string playerName = Player.m_localPlayer.GetPlayerName();
				long num = (((Object)(object)ZNet.instance != (Object)null) ? ZNet.instance.GetWorldUID() : 0);
				if (playerName != currentCharacter || num != currentWorldUID)
				{
					currentCharacter = playerName;
					currentWorldUID = num;
					personalBest = data.GetPeak(currentCharacter, currentWorldUID);
				}
				currentAltitude = ((Component)Player.m_localPlayer).transform.position.y - 30f;
				if (currentAltitude > personalBest)
				{
					personalBest = currentAltitude;
					newRecordTimer = 3f;
					data.SetPeak(currentCharacter, currentWorldUID, personalBest);
					data.Save();
				}
				if (newRecordTimer > 0f)
				{
					newRecordTimer -= Time.deltaTime;
				}
			}
		}

		private void DoSummitShout()
		{
			if (!((Object)(object)Chat.instance == (Object)null) && !((Object)(object)Player.m_localPlayer == (Object)null))
			{
				if (personalBest - currentAltitude > summitThreshold.Value)
				{
					((Character)Player.m_localPlayer).Message((MessageType)2, "You must be near your peak to announce your summit.", 0, (Sprite)null);
					return;
				}
				string text = $"Summit: {personalBest:F0} Wood Poles above sea level!";
				Chat.instance.SendText((Type)2, text);
			}
		}

		private void SetCursorState(bool visible)
		{
			Cursor.lockState = (CursorLockMode)(!visible);
			Cursor.visible = visible;
			if ((Object)(object)GameCamera.instance != (Object)null)
			{
				((Behaviour)GameCamera.instance).enabled = !visible;
			}
		}

		private void OnGUI()
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			//IL_0066: 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_0081: Expected O, but got Unknown
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: 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_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Expected O, but got Unknown
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)Player.m_localPlayer == (Object)null))
			{
				if (editMode)
				{
					Cursor.lockState = (CursorLockMode)0;
					Cursor.visible = true;
				}
				ResolveFont();
				InitStyles();
				string text = $"{currentAltitude:F0} Wood Poles";
				string text2 = $"Peak: {personalBest:F0} Wood Poles";
				float x = altitudeStyle.CalcSize(new GUIContent(text)).x;
				float x2 = peakStyle.CalcSize(new GUIContent(text2)).x;
				float num = Mathf.Max(x, x2);
				float num2 = Mathf.Max(140f, num + 48f);
				float num3 = 58f;
				float num4 = (float)Screen.width * posX.Value - num2 / 2f;
				float num5 = (float)Screen.height * posY.Value;
				windowRect = new Rect(num4, num5, num2, num3);
				if (editMode)
				{
					HandleDrag();
				}
				GUI.Box(windowRect, "", boxStyle);
				GUI.Label(new Rect(((Rect)(ref windowRect)).x, ((Rect)(ref windowRect)).y + 8f, num2, 24f), text, altitudeStyle);
				GUIStyle val = ((newRecordTimer > 0f) ? recordStyle : peakStyle);
				GUI.Label(new Rect(((Rect)(ref windowRect)).x, ((Rect)(ref windowRect)).y + 8f + 26f, num2, 20f), text2, val);
				if (editMode)
				{
					string text3 = "Drag to reposition | Ctrl+F8 to exit";
					float num6 = editLabelStyle.CalcSize(new GUIContent(text3)).x + 12f;
					GUI.Label(new Rect(((Rect)(ref windowRect)).x + (num2 - num6) / 2f, ((Rect)(ref windowRect)).y - 20f, num6, 18f), text3, editLabelStyle);
				}
			}
		}

		private void ResolveFont()
		{
			if (fontResolved)
			{
				return;
			}
			fontResolved = true;
			norseFont = ((IEnumerable<Font>)Resources.FindObjectsOfTypeAll<Font>()).FirstOrDefault((Func<Font, bool>)((Font f) => ((Object)f).name == "Norsebold"));
			if ((Object)(object)norseFont == (Object)null)
			{
				norseFont = ((IEnumerable<Font>)Resources.FindObjectsOfTypeAll<Font>()).FirstOrDefault((Func<Font, bool>)((Font f) => ((Object)f).name.Contains("Norse")));
			}
			if ((Object)(object)norseFont == (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"Could not find Norsebold font, falling back to default.");
			}
		}

		private void HandleDrag()
		{
			//IL_0007: 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: Invalid comparison between Unknown and I4
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Invalid comparison between Unknown and I4
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: 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)
			Event current = Event.current;
			if ((int)current.type == 0 && ((Rect)(ref windowRect)).Contains(current.mousePosition))
			{
				isDragging = true;
				dragOffset = current.mousePosition - new Vector2(((Rect)(ref windowRect)).x, ((Rect)(ref windowRect)).y);
				current.Use();
			}
			if ((int)current.type == 3 && isDragging)
			{
				float num = (current.mousePosition.x - dragOffset.x + ((Rect)(ref windowRect)).width / 2f) / (float)Screen.width;
				float num2 = (current.mousePosition.y - dragOffset.y) / (float)Screen.height;
				posX.Value = Mathf.Clamp01(num);
				posY.Value = Mathf.Clamp01(num2);
				current.Use();
			}
			if ((int)current.type == 1 && isDragging)
			{
				isDragging = false;
				current.Use();
			}
		}

		private void InitStyles()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_0048: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Expected O, but got Unknown
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Expected O, but got Unknown
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Expected O, but got Unknown
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Expected O, but got Unknown
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Expected O, but got Unknown
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			if (!stylesInitialized)
			{
				stylesInitialized = true;
				boxStyle = new GUIStyle(GUI.skin.box);
				boxStyle.normal.background = MakeRoundedTex(32, 32, new Color(0.1f, 0.1f, 0.13f, 0.62f), new Color(0.28f, 0.28f, 0.32f, 0.45f), 5);
				boxStyle.border = new RectOffset(8, 8, 8, 8);
				altitudeStyle = new GUIStyle(GUI.skin.label)
				{
					fontSize = fontSize.Value,
					alignment = (TextAnchor)4,
					fontStyle = (FontStyle)1
				};
				altitudeStyle.normal.textColor = Color.white;
				if ((Object)(object)norseFont != (Object)null)
				{
					altitudeStyle.font = norseFont;
				}
				peakStyle = new GUIStyle(GUI.skin.label)
				{
					fontSize = fontSize.Value - 4,
					alignment = (TextAnchor)4
				};
				peakStyle.normal.textColor = new Color(0.78f, 0.78f, 0.8f);
				if ((Object)(object)norseFont != (Object)null)
				{
					peakStyle.font = norseFont;
				}
				recordStyle = new GUIStyle(peakStyle);
				recordStyle.normal.textColor = new Color(1f, 0.84f, 0f);
				recordStyle.fontStyle = (FontStyle)1;
				editLabelStyle = new GUIStyle(GUI.skin.label)
				{
					fontSize = 11,
					alignment = (TextAnchor)4
				};
				editLabelStyle.normal.textColor = new Color(1f, 1f, 1f, 0.8f);
			}
		}

		private static Texture2D MakeRoundedTex(int w, int h, Color fill, Color border, int radius)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_004c: 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_007d: 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_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: 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_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: 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_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(w, h);
			Color[] array = (Color[])(object)new Color[w * h];
			for (int i = 0; i < h; i++)
			{
				for (int j = 0; j < w; j++)
				{
					bool flag = j < 1 || j >= w - 1 || i < 1 || i >= h - 1;
					bool flag2 = false;
					if (j < radius && i < radius)
					{
						flag2 = Vector2.Distance(new Vector2((float)j, (float)i), new Vector2((float)radius, (float)radius)) > (float)radius;
					}
					else if (j >= w - radius && i < radius)
					{
						flag2 = Vector2.Distance(new Vector2((float)j, (float)i), new Vector2((float)(w - radius - 1), (float)radius)) > (float)radius;
					}
					else if (j < radius && i >= h - radius)
					{
						flag2 = Vector2.Distance(new Vector2((float)j, (float)i), new Vector2((float)radius, (float)(h - radius - 1))) > (float)radius;
					}
					else if (j >= w - radius && i >= h - radius)
					{
						flag2 = Vector2.Distance(new Vector2((float)j, (float)i), new Vector2((float)(w - radius - 1), (float)(h - radius - 1))) > (float)radius;
					}
					if (flag2)
					{
						array[i * w + j] = Color.clear;
					}
					else if (flag)
					{
						array[i * w + j] = border;
					}
					else
					{
						array[i * w + j] = fill;
					}
				}
			}
			val.SetPixels(array);
			val.Apply();
			((Texture)val).filterMode = (FilterMode)1;
			return val;
		}
	}
}