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 FreeflySpeedControl v2.1.0
plugins/FreeflySpeedControl.dll
Decompiled 2 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = "")] [assembly: AssemblyCompany("FreeflySpeedControl")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("FreeflySpeedControl")] [assembly: AssemblyTitle("FreeflySpeedControl")] [assembly: AssemblyVersion("1.0.0.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 FreeflySpeedControl { [BepInPlugin("com.mitch.freeflyspeedcontrol", "Freefly Speed Control", "2.1.0")] public class FreeflySpeedControlPlugin : BaseUnityPlugin { [HarmonyPatch(typeof(GameCamera), "UpdateFreeFly")] public class FreeFlyTranspiler { private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { List<CodeInstruction> list = new List<CodeInstruction>(instructions); bool flag = false; for (int i = 0; i < list.Count - 2; i++) { if (list[i].opcode == OpCodes.Ldc_R4 && list[i].operand is float num && Mathf.Approximately(num, 1f) && list[i + 1].opcode == OpCodes.Ldc_R4 && list[i + 1].operand is float num2 && Mathf.Approximately(num2, 1000f) && list[i + 2].opcode == OpCodes.Call && list[i + 2].operand is MethodInfo methodInfo && methodInfo.Name == "Clamp") { list[i].operand = minSpeed.Value; list[i + 1].operand = maxSpeed.Value; flag = true; FreeflySpeedControlPlugin instance = FreeflySpeedControlPlugin.instance; if (instance != null) { ((BaseUnityPlugin)instance).Logger.LogInfo((object)($"Transpiler: Patched Clamp({num}, {num2}) " + $"→ Clamp({minSpeed.Value}, {maxSpeed.Value})")); } break; } } if (!flag) { FreeflySpeedControlPlugin instance2 = FreeflySpeedControlPlugin.instance; if (instance2 != null) { ((BaseUnityPlugin)instance2).Logger.LogWarning((object)"Transpiler: Could not find Clamp(1f, 1000f) pattern!"); } } return list; } } [HarmonyPatch(typeof(GameCamera), "UpdateFreeFly")] public class FreeFlyMousePatch { private static Quaternion rotationBefore; private static FieldInfo speedField; private static bool fieldSearchDone; private static void Prefix(GameCamera __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) if (linkMouseToSpeed.Value) { rotationBefore = ((Component)__instance).transform.rotation; } } private static void Postfix(GameCamera __instance) { //IL_00b9: 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_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) if (!linkMouseToSpeed.Value) { return; } if (!fieldSearchDone) { speedField = typeof(GameCamera).GetField("m_freeFlySpeed", BindingFlags.Instance | BindingFlags.NonPublic); fieldSearchDone = true; } if (!(speedField == null)) { float num = (float)speedField.GetValue(__instance); float num2 = num / maxSpeed.Value; float num3 = Mathf.Lerp(1f, num2, mouseLinkStrength.Value); num3 = Mathf.Max(num3, 0.02f); if (!Mathf.Approximately(num3, 1f)) { Quaternion rotation = ((Component)__instance).transform.rotation; Quaternion val = rotation * Quaternion.Inverse(rotationBefore); Quaternion val2 = Quaternion.Slerp(Quaternion.identity, val, num3); ((Component)__instance).transform.rotation = val2 * rotationBefore; } } } } public static ConfigEntry<float> minSpeed; public static ConfigEntry<float> maxSpeed; public static ConfigEntry<bool> linkMouseToSpeed; public static ConfigEntry<float> mouseLinkStrength; private static FreeflySpeedControlPlugin instance; private Harmony harmony; private void Awake() { //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown instance = this; minSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Speed", "MinSpeed", 0.05f, "Minimum freefly movement speed. Vanilla is 1.0. 0.05 = ultra-slow cinematic crawl."); maxSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Speed", "MaxSpeed", 50f, "Maximum freefly movement speed. Vanilla is 1000. 50 = fast but controlled. Raise if you need to cover ground quickly."); linkMouseToSpeed = ((BaseUnityPlugin)this).Config.Bind<bool>("Mouse", "LinkMouseToSpeed", true, "When true, mouse look speed automatically scales with movement speed. Slow movement = slow mouse look. Fast movement = normal mouse look. One scroll wheel controls everything."); mouseLinkStrength = ((BaseUnityPlugin)this).Config.Bind<float>("Mouse", "MouseLinkStrength", 0.7f, "How tightly mouse look follows movement speed (0.0 to 1.0). 1.0 = fully linked (mouse slows down exactly as much as movement). 0.5 = partially linked (mouse slows less than movement). 0.0 = not linked (mouse always at vanilla speed)."); harmony = new Harmony("com.mitch.freeflyspeedcontrol"); harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Freefly Speed Control v2.1.0 loaded!"); ((BaseUnityPlugin)this).Logger.LogInfo((object)$" MinSpeed: {minSpeed.Value}"); ((BaseUnityPlugin)this).Logger.LogInfo((object)$" MaxSpeed: {maxSpeed.Value}"); ((BaseUnityPlugin)this).Logger.LogInfo((object)$" LinkMouseToSpeed: {linkMouseToSpeed.Value}"); ((BaseUnityPlugin)this).Logger.LogInfo((object)$" MouseLinkStrength: {mouseLinkStrength.Value}"); } private void OnDestroy() { Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } } }