Decompiled source of Speedometer v1.1.2
Patch3_MelonLoader0.5/Mods/Speedometer.P3.ML5.dll
Decompiled 5 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using HarmonyLib; using MelonLoader; using MelonLoader.Preferences; using Microsoft.CodeAnalysis; using SLZ.Interaction; using SLZ.Marrow.SceneStreaming; using SLZ.Marrow.Warehouse; using SLZ.Rig; using Sst.Speedometer; using Sst.Utilities; using TMPro; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Speedometer")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany(null)] [assembly: AssemblyProduct("Speedometer")] [assembly: AssemblyCopyright("Created by jakzo")] [assembly: AssemblyTrademark(null)] [assembly: ComVisible(false)] [assembly: AssemblyFileVersion("1.1.2")] [assembly: NeutralResourcesLanguage("en")] [assembly: MelonInfo(typeof(Mod), "Speedometer", "1.1.2", "jakzo", "https://bonelab.thunderstore.io/package/jakzo/Speedometer/")] [assembly: MelonGame("Stress Level Zero", "BONELAB")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.1.2.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Sst { public class Metadata { public const string AUTHOR = "jakzo"; public const string COMPANY = null; public const string DEVELOPER = "Stress Level Zero"; public const string GAME = "BONELAB"; public const string GAME_BONEWORKS = "BONEWORKS"; } public class Dbg { private static MelonPreferences_Entry<bool> _prefPrintDebugLogs; public static void Init(string prefCategoryId) { _prefPrintDebugLogs = MelonPreferences.CreateCategory(prefCategoryId).CreateEntry<bool>("printDebugLogs", false, "Print debug logs to console", (string)null, false, false, (ValueValidator)null, (string)null); } public static void Log(string msg, params object[] data) { if (_prefPrintDebugLogs.Value) { MelonLogger.Msg("dbg: " + msg); } } } } namespace Sst.Utilities { internal static class LevelHooks { [HarmonyPatch(typeof(BasicTrackingRig), "Awake")] private class BasicTrackingRig_Awake_Patch { [CompilerGenerated] private static class <>O { public static LemonAction <0>__WaitForLoadFinished; } [HarmonyPrefix] internal static void Prefix(BasicTrackingRig __instance) { //IL_0015: 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_006b: 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_0076: Expected O, but got Unknown Dbg.Log("BasicTrackingRig_Awake_Patch"); _loadingScene = ((Component)__instance).gameObject.scene; if (Object.op_Implicit((Object)(object)CurrentLevel)) { PrevLevel = CurrentLevel; } CurrentLevel = null; NextLevel = SceneStreamer.Session.Level; RigManager = null; BasicTrackingRig = __instance; MelonEvent onUpdate = MelonEvents.OnUpdate; object obj = <>O.<0>__WaitForLoadFinished; if (obj == null) { LemonAction val = WaitForLoadFinished; <>O.<0>__WaitForLoadFinished = val; obj = (object)val; } ((MelonEventBase<LemonAction>)(object)onUpdate).Subscribe((LemonAction)obj, 0, false); LevelCrate nextLevel = NextLevel; Dbg.Log("OnLoad " + ((nextLevel != null) ? ((Scannable)nextLevel).Title : null)); SafeInvoke("OnLoad", LevelHooks.OnLoad, NextLevel); } } [HarmonyPatch(typeof(RigManager), "Awake")] private class RigManager_Awake_Patch { [HarmonyPrefix] internal static void Prefix(RigManager __instance) { Dbg.Log("RigManager_Awake_Patch"); RigManager = __instance; BasicTrackingRig = null; } } [CompilerGenerated] private static class <>O { public static LemonAction <0>__WaitForLoadFinished; } public static LevelCrate PrevLevel; public static LevelCrate CurrentLevel; public static LevelCrate NextLevel; public static RigManager RigManager; public static BasicTrackingRig BasicTrackingRig; private static Scene _loadingScene; public static bool IsLoading => !Object.op_Implicit((Object)(object)CurrentLevel); public static event Action<LevelCrate> OnLoad; public static event Action<LevelCrate> OnLevelStart; private static void SafeInvoke(string name, Action<LevelCrate> action, LevelCrate level) { try { action?.Invoke(level); } catch (Exception ex) { MelonLogger.Error("Failed to execute " + name + " event: " + ex.ToString()); } } private static void WaitForLoadFinished() { //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_002d: Expected O, but got Unknown if (!((Scene)(ref _loadingScene)).isLoaded) { MelonEvent onUpdate = MelonEvents.OnUpdate; object obj = <>O.<0>__WaitForLoadFinished; if (obj == null) { LemonAction val = WaitForLoadFinished; <>O.<0>__WaitForLoadFinished = val; obj = (object)val; } ((MelonEventBase<LemonAction>)(object)onUpdate).Unsubscribe((LemonAction)obj); CurrentLevel = NextLevel ?? SceneStreamer.Session.Level ?? CurrentLevel; NextLevel = null; LevelCrate currentLevel = CurrentLevel; Dbg.Log("OnLevelStart " + ((currentLevel != null) ? ((Scannable)currentLevel).Title : null)); SafeInvoke("OnLevelStart", LevelHooks.OnLevelStart, CurrentLevel); } } } public class Bonelab { private static Shader _highlightShader; public static Shader HighlightShader => _highlightShader ?? (_highlightShader = ((IEnumerable<Shader>)Resources.FindObjectsOfTypeAll<Shader>()).First((Shader shader) => ((Object)shader).name == "SLZ/Highlighter")); public static void DockToWrist(GameObject gameObject, bool rightHand = false) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) PhysicsRig physicsRig = LevelHooks.RigManager.physicsRig; Hand val = (rightHand ? physicsRig.rightHand : physicsRig.leftHand); gameObject.transform.SetParent(((Component)val).transform); gameObject.transform.localPosition = new Vector3(-0.31f, 0.3f, 0f); gameObject.transform.localRotation = Quaternion.Euler(32f, 4f, 3f); } public static TextMeshPro CreateTextOnWrist(string name, bool rightHand = false) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0033: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); TextMeshPro obj = val.AddComponent<TextMeshPro>(); ((TMP_Text)obj).alignment = (TextAlignmentOptions)1028; ((TMP_Text)obj).fontSize = 0.5f; ((TMP_Text)obj).rectTransform.sizeDelta = new Vector2(0.8f, 0.5f); DockToWrist(val, rightHand); return obj; } } } namespace Sst.Speedometer { internal static class AppVersion { public const string Value = "1.1.2"; } public static class BuildInfo { public const string NAME = "Speedometer"; } public class Mod : MelonMod { private enum Units { MS, KPH, MPH } private const string SPEEDOMETER_TEXT_NAME = "Speedometer"; private MelonPreferences_Entry<bool> _prefRightHand; private MelonPreferences_Entry<Units> _prefUnits; private MelonPreferences_Entry<float> _prefWindowDuration; private TextMeshPro _tmp; private SpeedTracker _speedTracker; public override void OnInitializeMelon() { Dbg.Init("Speedometer"); MelonPreferences_Category val = MelonPreferences.CreateCategory("Speedometer"); _prefRightHand = val.CreateEntry<bool>("right_hand", false, "Show speed reading on right hand instead of left", (string)null, false, false, (ValueValidator)null, (string)null); _prefUnits = val.CreateEntry<Units>("units", Units.MS, "Units to measure speed in", (string)null, false, false, (ValueValidator)null, (string)null); _prefWindowDuration = val.CreateEntry<float>("window_duration", 0.25f, "Number of seconds to average the speed over", (string)null, false, false, (ValueValidator)null, (string)null); LevelHooks.OnLevelStart += OnLevelStart; } public void OnLevelStart(LevelCrate level) { float value = _prefWindowDuration.Value; _speedTracker = new SpeedTracker { WindowDuration = value, BufferSize = Mathf.CeilToInt(value * 240f) }; _tmp = Bonelab.CreateTextOnWrist("Speedometer", _prefRightHand.Value); } public override void OnUpdate() { //IL_001f: 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_0030: 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) if (!LevelHooks.IsLoading && _speedTracker != null) { Vector3 position = ((Rig)LevelHooks.RigManager.physicsRig).m_head.position; _speedTracker.OnFrame(Time.time, position.x, position.z); TextMeshPro tmp = _tmp; if (tmp != null) { ((TMP_Text)tmp).SetText(GetSpeedText(_speedTracker.GetSpeed()), true); } } } private string GetSpeedText(float speedMs) { return _prefUnits.Value switch { Units.KPH => $"{speedMs * 3.6f:N1}kph", Units.MPH => $"{speedMs * 2.237f:N1}mph", _ => $"{speedMs:N2}m/s", }; } } internal class SpeedTracker { public int BufferSize = 1000; public float WindowDuration = 1f; private (float, float, float)[] _frames; private int _idxStart; private int _idxEnd; public SpeedTracker() { _frames = new(float, float, float)[BufferSize]; } public void OnFrame(float time, float posX, float posZ) { _frames[_idxEnd] = (time, posX, posZ); _idxEnd++; if (_idxEnd >= _frames.Length) { _idxEnd = 0; } if (_idxEnd == _idxStart) { _idxStart++; if (_idxStart >= _frames.Length) { _idxStart = 0; } } } public float GetSpeed() { if (_idxEnd == _idxStart) { return 0f; } (float, float, float) tuple = _frames[((_idxEnd <= 0) ? _frames.Length : _idxEnd) - 1]; float num = tuple.Item1 - WindowDuration; while (_idxStart != _idxEnd && _frames[_idxStart].Item1 < num) { _idxStart++; if (_idxStart >= _frames.Length) { _idxStart = 0; } } (float, float, float) tuple2 = _frames[_idxStart]; float num2 = tuple.Item2 - tuple2.Item2; float num3 = tuple.Item3 - tuple2.Item3; float num4 = tuple.Item1 - tuple2.Item1; return Mathf.Sqrt(num2 * num2 + num3 * num3) / num4; } } }
Patch4_MelonLoader0.6/Mods/Speedometer.P4.ML6.dll
Decompiled 5 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using HarmonyLib; using Il2CppSLZ.Interaction; using Il2CppSLZ.Marrow.SceneStreaming; using Il2CppSLZ.Marrow.Warehouse; using Il2CppSLZ.Rig; using Il2CppTMPro; using MelonLoader; using MelonLoader.Preferences; using Microsoft.CodeAnalysis; using Sst.Speedometer; using Sst.Utilities; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Speedometer")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany(null)] [assembly: AssemblyProduct("Speedometer")] [assembly: AssemblyCopyright("Created by jakzo")] [assembly: AssemblyTrademark(null)] [assembly: ComVisible(false)] [assembly: AssemblyFileVersion("1.1.2")] [assembly: NeutralResourcesLanguage("en")] [assembly: MelonInfo(typeof(Mod), "Speedometer", "1.1.2", "jakzo", "https://bonelab.thunderstore.io/package/jakzo/Speedometer/")] [assembly: MelonGame("Stress Level Zero", "BONELAB")] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyVersion("1.1.2.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Sst { public class Metadata { public const string AUTHOR = "jakzo"; public const string COMPANY = null; public const string DEVELOPER = "Stress Level Zero"; public const string GAME = "BONELAB"; public const string GAME_BONEWORKS = "BONEWORKS"; } public class Dbg { private static MelonPreferences_Entry<bool> _prefPrintDebugLogs; public static void Init(string prefCategoryId) { _prefPrintDebugLogs = MelonPreferences.CreateCategory(prefCategoryId).CreateEntry<bool>("printDebugLogs", false, "Print debug logs to console", (string)null, false, false, (ValueValidator)null, (string)null); } public static void Log(string msg, params object[] data) { if (_prefPrintDebugLogs.Value) { MelonLogger.Msg("dbg: " + msg); } } } } namespace Sst.Utilities { internal static class LevelHooks { [HarmonyPatch(typeof(BasicTrackingRig), "Awake")] private class BasicTrackingRig_Awake_Patch { [CompilerGenerated] private static class <>O { public static LemonAction <0>__WaitForLoadFinished; } [HarmonyPrefix] internal static void Prefix(BasicTrackingRig __instance) { //IL_0015: 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_006b: 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_0076: Expected O, but got Unknown Dbg.Log("BasicTrackingRig_Awake_Patch"); _loadingScene = ((Component)__instance).gameObject.scene; if (Object.op_Implicit((Object)(object)CurrentLevel)) { PrevLevel = CurrentLevel; } CurrentLevel = null; NextLevel = SceneStreamer.Session.Level; RigManager = null; BasicTrackingRig = __instance; MelonEvent onUpdate = MelonEvents.OnUpdate; object obj = <>O.<0>__WaitForLoadFinished; if (obj == null) { LemonAction val = WaitForLoadFinished; <>O.<0>__WaitForLoadFinished = val; obj = (object)val; } ((MelonEventBase<LemonAction>)(object)onUpdate).Subscribe((LemonAction)obj, 0, false); LevelCrate nextLevel = NextLevel; Dbg.Log("OnLoad " + ((nextLevel != null) ? ((Scannable)nextLevel).Title : null)); SafeInvoke("OnLoad", LevelHooks.OnLoad, NextLevel); } } [HarmonyPatch(typeof(RigManager), "Awake")] private class RigManager_Awake_Patch { [HarmonyPrefix] internal static void Prefix(RigManager __instance) { Dbg.Log("RigManager_Awake_Patch"); RigManager = __instance; BasicTrackingRig = null; } } [CompilerGenerated] private static class <>O { public static LemonAction <0>__WaitForLoadFinished; } public static LevelCrate PrevLevel; public static LevelCrate CurrentLevel; public static LevelCrate NextLevel; public static RigManager RigManager; public static BasicTrackingRig BasicTrackingRig; private static Scene _loadingScene; public static bool IsLoading => !Object.op_Implicit((Object)(object)CurrentLevel); public static event Action<LevelCrate> OnLoad; public static event Action<LevelCrate> OnLevelStart; private static void SafeInvoke(string name, Action<LevelCrate> action, LevelCrate level) { try { action?.Invoke(level); } catch (Exception ex) { MelonLogger.Error("Failed to execute " + name + " event: " + ex.ToString()); } } private static void WaitForLoadFinished() { //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_002d: Expected O, but got Unknown if (!((Scene)(ref _loadingScene)).isLoaded) { MelonEvent onUpdate = MelonEvents.OnUpdate; object obj = <>O.<0>__WaitForLoadFinished; if (obj == null) { LemonAction val = WaitForLoadFinished; <>O.<0>__WaitForLoadFinished = val; obj = (object)val; } ((MelonEventBase<LemonAction>)(object)onUpdate).Unsubscribe((LemonAction)obj); CurrentLevel = NextLevel ?? SceneStreamer.Session.Level ?? CurrentLevel; NextLevel = null; LevelCrate currentLevel = CurrentLevel; Dbg.Log("OnLevelStart " + ((currentLevel != null) ? ((Scannable)currentLevel).Title : null)); SafeInvoke("OnLevelStart", LevelHooks.OnLevelStart, CurrentLevel); } } } public class Bonelab { private static Shader _highlightShader; public static Shader HighlightShader => _highlightShader ?? (_highlightShader = ((IEnumerable<Shader>)Resources.FindObjectsOfTypeAll<Shader>()).First((Shader shader) => ((Object)shader).name == "SLZ/Highlighter")); public static void DockToWrist(GameObject gameObject, bool rightHand = false) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) PhysicsRig physicsRig = LevelHooks.RigManager.physicsRig; Hand val = (rightHand ? physicsRig.rightHand : physicsRig.leftHand); gameObject.transform.SetParent(((Component)val).transform); gameObject.transform.localPosition = new Vector3(-0.31f, 0.3f, 0f); gameObject.transform.localRotation = Quaternion.Euler(32f, 4f, 3f); } public static TextMeshPro CreateTextOnWrist(string name, bool rightHand = false) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0033: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); TextMeshPro obj = val.AddComponent<TextMeshPro>(); ((TMP_Text)obj).alignment = (TextAlignmentOptions)1028; ((TMP_Text)obj).fontSize = 0.5f; ((TMP_Text)obj).rectTransform.sizeDelta = new Vector2(0.8f, 0.5f); DockToWrist(val, rightHand); return obj; } } } namespace Sst.Speedometer { internal static class AppVersion { public const string Value = "1.1.2"; } public static class BuildInfo { public const string NAME = "Speedometer"; } public class Mod : MelonMod { private enum Units { MS, KPH, MPH } private const string SPEEDOMETER_TEXT_NAME = "Speedometer"; private MelonPreferences_Entry<bool> _prefRightHand; private MelonPreferences_Entry<Units> _prefUnits; private MelonPreferences_Entry<float> _prefWindowDuration; private TextMeshPro _tmp; private SpeedTracker _speedTracker; public override void OnInitializeMelon() { Dbg.Init("Speedometer"); MelonPreferences_Category val = MelonPreferences.CreateCategory("Speedometer"); _prefRightHand = val.CreateEntry<bool>("right_hand", false, "Show speed reading on right hand instead of left", (string)null, false, false, (ValueValidator)null, (string)null); _prefUnits = val.CreateEntry<Units>("units", Units.MS, "Units to measure speed in", (string)null, false, false, (ValueValidator)null, (string)null); _prefWindowDuration = val.CreateEntry<float>("window_duration", 0.25f, "Number of seconds to average the speed over", (string)null, false, false, (ValueValidator)null, (string)null); LevelHooks.OnLevelStart += OnLevelStart; } public void OnLevelStart(LevelCrate level) { float value = _prefWindowDuration.Value; _speedTracker = new SpeedTracker { WindowDuration = value, BufferSize = Mathf.CeilToInt(value * 240f) }; _tmp = Bonelab.CreateTextOnWrist("Speedometer", _prefRightHand.Value); } public override void OnUpdate() { //IL_001f: 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_0030: 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) if (!LevelHooks.IsLoading && _speedTracker != null) { Vector3 position = ((Rig)LevelHooks.RigManager.physicsRig).m_head.position; _speedTracker.OnFrame(Time.time, position.x, position.z); TextMeshPro tmp = _tmp; if (tmp != null) { ((TMP_Text)tmp).SetText(GetSpeedText(_speedTracker.GetSpeed()), true); } } } private string GetSpeedText(float speedMs) { return _prefUnits.Value switch { Units.KPH => $"{speedMs * 3.6f:N1}kph", Units.MPH => $"{speedMs * 2.237f:N1}mph", _ => $"{speedMs:N2}m/s", }; } } internal class SpeedTracker { public int BufferSize = 1000; public float WindowDuration = 1f; private (float, float, float)[] _frames; private int _idxStart; private int _idxEnd; public SpeedTracker() { _frames = new(float, float, float)[BufferSize]; } public void OnFrame(float time, float posX, float posZ) { _frames[_idxEnd] = (time, posX, posZ); _idxEnd++; if (_idxEnd >= _frames.Length) { _idxEnd = 0; } if (_idxEnd == _idxStart) { _idxStart++; if (_idxStart >= _frames.Length) { _idxStart = 0; } } } public float GetSpeed() { if (_idxEnd == _idxStart) { return 0f; } (float, float, float) tuple = _frames[((_idxEnd <= 0) ? _frames.Length : _idxEnd) - 1]; float num = tuple.Item1 - WindowDuration; while (_idxStart != _idxEnd && _frames[_idxStart].Item1 < num) { _idxStart++; if (_idxStart >= _frames.Length) { _idxStart = 0; } } (float, float, float) tuple2 = _frames[_idxStart]; float num2 = tuple.Item2 - tuple2.Item2; float num3 = tuple.Item3 - tuple2.Item3; float num4 = tuple.Item1 - tuple2.Item1; return Mathf.Sqrt(num2 * num2 + num3 * num3) / num4; } } }