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 records = new List(); } 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(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 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 toggleEditMode; private ConfigEntry summitKey; private ConfigEntry fontSize; private ConfigEntry posX; private ConfigEntry posY; private ConfigEntry 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("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("UI", "SummitShout", new KeyboardShortcut((KeyCode)277, Array.Empty()), "Hotkey to shout your summit stats"); fontSize = ((BaseUnityPlugin)this).Config.Bind("UI", "FontSize", 18, "HUD font size"); posX = ((BaseUnityPlugin)this).Config.Bind("UI", "PositionX", 0.5f, "Horizontal position (0-1, left to right)"); posY = ((BaseUnityPlugin)this).Config.Bind("UI", "PositionY", 0.02f, "Vertical position (0-1, top to bottom)"); summitThreshold = ((BaseUnityPlugin)this).Config.Bind("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)Resources.FindObjectsOfTypeAll()).FirstOrDefault((Func)((Font f) => ((Object)f).name == "Norsebold")); if ((Object)(object)norseFont == (Object)null) { norseFont = ((IEnumerable)Resources.FindObjectsOfTypeAll()).FirstOrDefault((Func)((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; } } }