Decompiled source of REPO FullLook v1.0.0

FullLook.dll

Decompiled 2 hours ago
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyTitle("REPO FullLook")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace RepoFullLook;

[BepInPlugin("local.repo.fulllook", "REPO FullLook", "1.0.0")]
[BepInProcess("REPO.exe")]
public sealed class FullLookPlugin : BaseUnityPlugin
{
	public const string Id = "local.repo.fulllook";

	private Harmony harmony;

	private void Awake()
	{
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Expected O, but got Unknown
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Expected O, but got Unknown
		//IL_0170: Unknown result type (might be due to invalid IL or missing references)
		//IL_017a: Expected O, but got Unknown
		//IL_0194: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a0: Expected O, but got Unknown
		PitchPatch.Log = ((BaseUnityPlugin)this).Logger;
		bool value = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable FullLook. Restart the game after any config change.").Value;
		float value2 = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "LookUpDegrees", 90f, new ConfigDescription("Upward limit. If the view twists at exactly 90, try 89.9. Restart required.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(70f, 90f), new object[0])).Value;
		float value3 = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "LookDownDegrees", 90f, new ConfigDescription("Downward limit. If the view twists at exactly 90, try 89.9. Restart required.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(80f, 90f), new object[0])).Value;
		if (!value)
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)"FullLook is disabled in config.");
			return;
		}
		if (!PitchPatch.ValidLimits(value2, value3))
		{
			((BaseUnityPlugin)this).Logger.LogError((object)"FullLook: invalid/non-finite limits; patch was not installed.");
			return;
		}
		PitchPatch.Up = value2;
		PitchPatch.Down = value3;
		try
		{
			Type type = AccessTools.TypeByName("CameraAim");
			MethodInfo methodInfo = ((type == null) ? null : AccessTools.DeclaredMethod(type, "Update", Type.EmptyTypes, (Type[])null));
			if (methodInfo == null || methodInfo.IsStatic || methodInfo.ReturnType != typeof(void) || type.Assembly.GetName().Name != "Assembly-CSharp")
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"FullLook: compatible CameraAim.Update was not found; no patch installed.");
				return;
			}
			harmony = new Harmony("local.repo.fulllook");
			harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(PitchPatch), "Transpiler", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
			if (PitchPatch.LastMatched)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"FullLook active: up={value2} degrees, down={value3} degrees. Local manual-look clamp patched; in-game validation still required.");
				return;
			}
			harmony.UnpatchSelf();
			((BaseUnityPlugin)this).Logger.LogError((object)"FullLook inactive: expected camera clamp was not found uniquely.");
		}
		catch (Exception ex)
		{
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			((BaseUnityPlugin)this).Logger.LogError((object)("FullLook could not install its patch: " + ex));
		}
	}

	private void OnDestroy()
	{
		if (harmony != null)
		{
			harmony.UnpatchSelf();
		}
	}
}
internal static class PitchPatch
{
	internal static float Up = 90f;

	internal static float Down = 90f;

	internal static bool LastMatched;

	internal static ManualLogSource Log;

	internal static bool ValidLimits(float up, float down)
	{
		if (!float.IsNaN(up) && !float.IsInfinity(up) && up >= 70f && up <= 90f && !float.IsNaN(down) && !float.IsInfinity(down) && down >= 80f)
		{
			return down <= 90f;
		}
		return false;
	}

	private static bool IsPitchField(object operand)
	{
		FieldInfo fieldInfo = operand as FieldInfo;
		if (fieldInfo != null && !fieldInfo.IsStatic && fieldInfo.Name == "aimVertical" && fieldInfo.FieldType == typeof(float) && fieldInfo.DeclaringType != null && fieldInfo.DeclaringType.FullName == "CameraAim")
		{
			return fieldInfo.DeclaringType.Assembly.GetName().Name == "Assembly-CSharp";
		}
		return false;
	}

	private static bool IsClamp(object operand)
	{
		MethodInfo methodInfo = operand as MethodInfo;
		if (methodInfo != null && methodInfo.IsStatic && methodInfo.Name == "Clamp" && methodInfo.DeclaringType != null && methodInfo.DeclaringType.FullName == "UnityEngine.Mathf" && methodInfo.ReturnType == typeof(float))
		{
			return (from p in methodInfo.GetParameters()
				select p.ParameterType).SequenceEqual(new Type[3]
			{
				typeof(float),
				typeof(float),
				typeof(float)
			});
		}
		return false;
	}

	internal static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
	{
		List<CodeInstruction> list = instructions.ToList();
		List<int> list2 = new List<int>();
		for (int i = 1; i + 3 < list.Count; i++)
		{
			if (list[i - 1].opcode == OpCodes.Ldfld && IsPitchField(list[i - 1].operand) && list[i].opcode == OpCodes.Ldc_R4 && list[i].operand is float && (float)list[i].operand == -70f && list[i + 1].opcode == OpCodes.Ldc_R4 && list[i + 1].operand is float && (float)list[i + 1].operand == 80f && list[i + 2].opcode == OpCodes.Call && IsClamp(list[i + 2].operand) && list[i + 3].opcode == OpCodes.Stfld && IsPitchField(list[i + 3].operand))
			{
				list2.Add(i);
			}
		}
		LastMatched = list2.Count == 1 && ValidLimits(Up, Down);
		if (!LastMatched)
		{
			if (Log != null)
			{
				Log.LogError((object)"FullLook: camera clamp pattern missing/ambiguous or invalid limits. Leaving this instruction stream unchanged (game update or another camera mod?).");
			}
			return list;
		}
		int num = list2[0];
		list[num].operand = 0f - Up;
		list[num + 1].operand = Down;
		return list;
	}
}