Please disclose if your mod was created primarily using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Sprint Toggle v1.0.3
BepInEx\plugins\CyranIndustries\ToggleSprint.dll
Decompiled 2 years agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq.Expressions; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using Microsoft.CodeAnalysis; using ToggleSprint.Utils; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("com.cyranindustries.toggle_sprint")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Toggle Sprint")] [assembly: AssemblyFileVersion("1.0.2.0")] [assembly: AssemblyInformationalVersion("1.0.2")] [assembly: AssemblyProduct("com.cyranindustries.toggle_sprint")] [assembly: AssemblyTitle("com.cyranindustries.toggle_sprint")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.2.0")] [module: UnverifiableCode] [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 ToggleSprint { [HarmonyPatch(typeof(PlayerControllerB))] public static class ToggleSprintPatch { private static readonly CodeSearch v45patch = new CodeSearch(new CodeSearchDescriptor((CodeInstruction i) => i.opcode == OpCodes.Call && i.operand.ToString().Contains("IngamePlayerSettings")), new CodeSearchDescriptor((CodeInstruction i) => i.opcode == OpCodes.Stloc_0), new CodeSearchDescriptor[3] { new CodeSearchDescriptor((CodeInstruction i) => i.opcode == OpCodes.Ldstr && i.operand.ToString().Contains("Sprint")), new CodeSearchDescriptor((CodeInstruction i) => i.opcode == OpCodes.Callvirt && i.operand.ToString().Contains("FindAction")), new CodeSearchDescriptor((CodeInstruction i) => i.opcode == OpCodes.Callvirt && i.operand.ToString().Contains("ReadValue")) }); private static readonly MethodInfo m_MyExtraMethod = SymbolExtensions.GetMethodInfo<PlayerControllerB, float>((Expression<Func<PlayerControllerB, float>>)((PlayerControllerB instance) => IsSprinting(instance))); public static bool __is_sprint_toggled = false; public static bool __was_pressed_last_frame = false; public static float IsSprinting(PlayerControllerB instance) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.toggleSprintEnabled.Value || !__is_sprint_toggled) { MovementActions movement = instance.playerActions.Movement; return ((MovementActions)(ref movement)).Sprint.ReadValue<float>(); } return 1f; } public static bool SprintIsTogglable(PlayerControllerB __instance) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) Vector2 val = IngamePlayerSettings.Instance.playerInput.actions.FindAction("Move", false).ReadValue<Vector2>(); if (!Plugin.alwaysToggleEnabled.Value) { return ((Vector2)(ref val)).sqrMagnitude >= 0.05f; } return true; } [HarmonyPatch("Update")] [HarmonyPrefix] public static bool UpdatePrefix(PlayerControllerB __instance) { if (!Plugin.toggleSprintEnabled.Value) { return true; } if (!SprintIsTogglable(__instance)) { if (__is_sprint_toggled) { __is_sprint_toggled = false; __was_pressed_last_frame = false; Plugin.StaticLogger.LogDebug((object)$"Sprint toggled by game state: {__is_sprint_toggled}"); } } else if ((double)IngamePlayerSettings.Instance.playerInput.actions.FindAction("Sprint", false).ReadValue<float>() > 0.3) { if (!__was_pressed_last_frame) { __is_sprint_toggled = !__is_sprint_toggled; Plugin.StaticLogger.LogDebug((object)$"Sprint toggled by player input: {__is_sprint_toggled}"); __was_pressed_last_frame = true; } } else { __was_pressed_last_frame = false; } return true; } [HarmonyPatch("Update")] [HarmonyTranspiler] public static IEnumerable<CodeInstruction> UpdateTranspile(IEnumerable<CodeInstruction> instructions) { //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Expected O, but got Unknown //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Expected O, but got Unknown Plugin.StaticLogger.LogInfo((object)"Transpiling Update"); List<CodeInstruction> list = new List<CodeInstruction>(instructions); Tuple<int, int> tuple = v45patch.FindPatch(list); Plugin.StaticLogger.LogDebug((object)"found v45 call"); if (tuple != null) { Plugin.StaticLogger.LogDebug((object)$"Found sprint call at {tuple.Item1} and {tuple.Item2}"); for (int i = tuple.Item1; i < tuple.Item2; i++) { Plugin.StaticLogger.LogDebug((object)$"Replacing {list[i].opcode} {list[i].operand} with Nop"); list[i].opcode = OpCodes.Nop; } list[tuple.Item2 - 2] = new CodeInstruction(OpCodes.Ldarg_0, (object)null); list[tuple.Item2 - 1] = new CodeInstruction(OpCodes.Call, (object)m_MyExtraMethod); Plugin.StaticLogger.LogInfo((object)"Successfully patched sprint lookup call"); } return list; } } [BepInPlugin("com.cyranindustries.toggle_sprint", "com.cyranindustries.toggle_sprint", "1.0.2")] public class Plugin : BaseUnityPlugin { public static ConfigEntry<bool> toggleSprintEnabled; public static ConfigEntry<bool> alwaysToggleEnabled; public static ConfigEntry<bool> uiEnabled; public static ManualLogSource StaticLogger; public static Texture2D sprintToggleUITexture; public static int versionDetected = -1; private static Texture2D LoadFromManifest(string resourceName) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_0033: Expected O, but got Unknown Stream? manifestResourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName); byte[] array = new byte[manifestResourceStream.Length]; manifestResourceStream.Read(array, 0, array.Length); Texture2D val = new Texture2D(2, 2); ImageConversion.LoadImage(val, array); return val; } private void Awake() { //IL_0070: Unknown result type (might be due to invalid IL or missing references) StaticLogger = ((BaseUnityPlugin)this).Logger; toggleSprintEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Whether or not toggle sprint is enabled."); alwaysToggleEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AlwaysToggleSprint", false, "Whether or not to always toggle the sprint, even if not moving"); uiEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("UI", "Enabled", true, "Whether or not toggle sprint icon is enabled in the UI when you're sprinting"); Harmony val = new Harmony("com.cyranindustries.toggle_sprint"); sprintToggleUITexture = LoadFromManifest("ToggleSprint.images.running.png"); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin com.cyranindustries.toggle_sprint is loaded!"); val.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"com.cyranindustries.toggle_sprint Patched all!"); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "com.cyranindustries.toggle_sprint"; public const string PLUGIN_NAME = "com.cyranindustries.toggle_sprint"; public const string PLUGIN_VERSION = "1.0.2"; } } namespace ToggleSprint.Utils { internal class CodeSearchDescriptor { private readonly Func<CodeInstruction, bool> matchFunction; public CodeSearchDescriptor(Func<CodeInstruction, bool> matchFunction) { this.matchFunction = matchFunction ?? throw new ArgumentNullException("matchFunction"); } public bool Matches(CodeInstruction instruction) { return matchFunction(instruction); } } internal class CodeSearch { private readonly CodeSearchDescriptor start; private readonly CodeSearchDescriptor end; private readonly IReadOnlyList<CodeSearchDescriptor> validators; public CodeSearch(CodeSearchDescriptor start, CodeSearchDescriptor end, IReadOnlyList<CodeSearchDescriptor> validators) { this.start = start ?? throw new ArgumentNullException("start"); this.end = end ?? throw new ArgumentNullException("end"); this.validators = validators; } public Tuple<int, int> FindPatch(List<CodeInstruction> instructions) { int? num = null; int? num2 = null; int num3 = 0; if (instructions == null) { return null; } for (int i = 0; i < instructions.Count; i++) { CodeInstruction val = instructions[i]; if (val != null) { if (start.Matches(val)) { num = i; num3 = 0; } if (start != null && validators != null && num3 < validators.Count && validators[num3].Matches(val)) { num3++; } if (end.Matches(val) && num.HasValue && (validators == null || num3 >= validators.Count)) { num2 = i; break; } } } if (num.HasValue && num2.HasValue) { return new Tuple<int, int>(num.Value, num2.Value); } return null; } } } namespace ToggleSprint.Patches { [HarmonyPatch(typeof(HUDManager))] public class HudManagerPatch { public static GameObject SprintToggleUI; [HarmonyPatch("Awake")] [HarmonyPrefix] public static bool AwakePrefix(HUDManager __instance) { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.uiEnabled.Value) { return true; } GameObject val = GameObject.Find("Self"); if ((Object)(object)SprintToggleUI == (Object)null) { SprintToggleUI = Object.Instantiate<GameObject>(val); ((Object)SprintToggleUI).name = "Sprint Toggle"; } SprintToggleUI.transform.parent = val.transform.parent; SprintToggleUI.transform.localScale = val.transform.localScale; SprintToggleUI.transform.localPosition = val.transform.localPosition + new Vector3(-10f, -100f, 0f); Image component = SprintToggleUI.GetComponent<Image>(); ((Component)component).transform.parent = SprintToggleUI.transform; ((Component)component).transform.localScale = new Vector3(0.33f, 0.33f, 1f); Plugin.StaticLogger.LogInfo((object)$"position = {((Component)component).transform.position}"); component.sprite = Sprite.Create(Plugin.sprintToggleUITexture, new Rect(0f, 0f, (float)((Texture)Plugin.sprintToggleUITexture).width, (float)((Texture)Plugin.sprintToggleUITexture).height), new Vector2(0f, 0f)); return true; } [HarmonyPatch("Update")] [HarmonyPostfix] public static void UpdatePostfix() { if (!((Object)(object)SprintToggleUI == (Object)null)) { Image component = SprintToggleUI.GetComponent<Image>(); if (!((Object)(object)component == (Object)null) && Plugin.uiEnabled.Value) { ((Graphic)component).CrossFadeAlpha(ToggleSprintPatch.__is_sprint_toggled ? 1f : 0f, 0.05f, false); } } } } }