using 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);
}
}
}
}
}