using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;
using UnityEngine.InputSystem;
using Zorro.ControllerSupport;
using Zorro.Core;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("PEAK")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("PEAK")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("94d12321-9932-43d2-ba03-502c40b6fcee")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
[BepInPlugin("com.leer.alivespectator", "Alive Spectator", "1.3.0")]
public class AliveSpectator : BaseUnityPlugin
{
[HarmonyPatch(typeof(MainCameraMovement), "LateUpdate")]
private class Patch_LateUpdate
{
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_00b4: Expected O, but got Unknown
//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
//IL_00c2: Expected O, but got Unknown
List<CodeInstruction> list = new List<CodeInstruction>(instructions);
FieldInfo fieldInfo = AccessTools.Field(typeof(Character), "localCharacter");
FieldInfo fieldInfo2 = AccessTools.Field(typeof(Character), "data");
FieldInfo fieldInfo3 = AccessTools.Field(typeof(CharacterData), "fullyPassedOut");
MethodInfo methodInfo = AccessTools.Method(typeof(AliveSpectator), "IsManualSpectating", (Type[])null, (Type[])null);
for (int i = 0; i < list.Count - 4; i++)
{
if (CodeInstructionExtensions.LoadsField(list[i], fieldInfo, false) && CodeInstructionExtensions.LoadsField(list[i + 1], fieldInfo2, false) && CodeInstructionExtensions.LoadsField(list[i + 2], fieldInfo3, false))
{
list.InsertRange(i + 3, (IEnumerable<CodeInstruction>)(object)new CodeInstruction[2]
{
new CodeInstruction(OpCodes.Call, (object)methodInfo),
new CodeInstruction(OpCodes.Or, (object)null)
});
break;
}
}
return list;
}
}
[HarmonyPatch(typeof(CharacterInput), "Sample")]
private class Patch_CharacterInput_Sample
{
private static void Prefix(ref bool playerMovementActive)
{
if (IsManualSpectating())
{
playerMovementActive = false;
}
}
private static void Postfix(CharacterInput __instance)
{
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0097: Unknown result type (might be due to invalid IL or missing references)
if (!IsManualSpectating())
{
return;
}
resetInputMethod?.Invoke(__instance, null);
if (CharacterInput.action_look != null)
{
__instance.lookInput = CharacterInput.action_look.ReadValue<Vector2>();
}
else
{
__instance.lookInput = Vector2.zero;
}
if ((int)InputHandler.GetCurrentUsedInputScheme() == 0)
{
__instance.spectateLeftWasPressed = __instance.HotbarKeyWasPressed(0);
__instance.spectateRightWasPressed = __instance.HotbarKeyWasPressed(1);
}
else
{
InputAction action_selectSlotBackward = CharacterInput.action_selectSlotBackward;
__instance.spectateLeftWasPressed = action_selectSlotBackward != null && action_selectSlotBackward.IsPressed();
InputAction action_selectSlotForward = CharacterInput.action_selectSlotForward;
__instance.spectateRightWasPressed = action_selectSlotForward != null && action_selectSlotForward.IsPressed();
}
float num = 0f;
num += Input.mouseScrollDelta.y;
if (Gamepad.current != null)
{
float num2 = 30f;
if (Gamepad.current.leftShoulder.isPressed)
{
num -= num2 * Time.deltaTime;
}
if (Gamepad.current.rightShoulder.isPressed)
{
num += num2 * Time.deltaTime;
}
}
__instance.scrollInput = num;
Gamepad current = Gamepad.current;
__instance.scrollForwardIsPressed = current != null && current.rightShoulder.isPressed;
Gamepad current2 = Gamepad.current;
__instance.scrollBackwardIsPressed = current2 != null && current2.leftShoulder.isPressed;
}
}
private static bool manualSpectateActive;
private MainCameraMovement cameraMovement;
private ConfigEntry<KeyCode> toggleKey;
private ConfigEntry<KeyCode> gamepadKey1;
private ConfigEntry<KeyCode> gamepadKey2;
private static MethodInfo resetInputMethod;
private void Awake()
{
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
toggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Binds", "KeyboardToggle", (KeyCode)288, "Keyboard key for toggling spectator mode on/off");
gamepadKey1 = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Binds", "GamepadToggle1", (KeyCode)334, "First gamepad button for toggle activation (e.g., LB)");
gamepadKey2 = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Binds", "GamepadToggle2", (KeyCode)335, "Second gamepad button for toggle activation (e.g., RB)");
new Harmony("com.leer.alivespectator").PatchAll(Assembly.GetExecutingAssembly());
resetInputMethod = typeof(CharacterInput).GetMethod("ResetInput", BindingFlags.Instance | BindingFlags.NonPublic);
}
private void Update()
{
if (IsTogglePressed() && !((Object)(object)Character.localCharacter == (Object)null) && !((Object)(object)Character.localCharacter.data == (Object)null) && !Character.localCharacter.data.fullyPassedOut)
{
if ((Object)(object)cameraMovement == (Object)null)
{
cameraMovement = Singleton<MainCameraMovement>.Instance;
}
if (!((Object)(object)cameraMovement == (Object)null))
{
manualSpectateActive = !manualSpectateActive;
}
}
}
private bool IsTogglePressed()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
bool keyDown = Input.GetKeyDown(toggleKey.Value);
bool flag = (Input.GetKeyDown(gamepadKey1.Value) && Input.GetKey(gamepadKey2.Value)) || (Input.GetKeyDown(gamepadKey2.Value) && Input.GetKey(gamepadKey1.Value));
return keyDown || flag;
}
public static bool IsManualSpectating()
{
return manualSpectateActive;
}
}