Please disclose if any significant portion of your mod was created 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 SoulFly v1.0.1
SoulFly.dll
Decompiled 12 hours agousing System; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using UnityEngine; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyVersion("0.0.0.0")] namespace SoulFly; internal class SoulFlyController : MonoBehaviour { internal static SoulFlyController Instance; internal static bool SoulActive; private static readonly FieldInfo FieldAnimator = AccessTools.Field(typeof(PlayerAvatarVisuals), "animator"); private static readonly MethodInfo MethodApplyLocalVisibility = AccessTools.Method(typeof(PlayerAvatarVisuals), "ApplyLocalVisibility", new Type[1] { typeof(ShadowCastingMode) }, (Type[])null); private static readonly FieldInfo FieldDeadSet = AccessTools.Field(typeof(PlayerAvatar), "deadSet"); private static readonly FieldInfo FieldSpectating = AccessTools.Field(typeof(PlayerAvatar), "spectating"); private PlayerController playerController; private PlayerAvatar playerAvatar; private PlayerAvatarVisuals visuals; private PlayerLocalCamera localCamera; private Camera mainCamera; private Transform cameraParent; private Transform aimTransform; private Animator animator; private float animatorSpeed = 1f; private bool animatorSpeedCaptured; private Vector3 flyPosition; private float flyYaw; private float flyPitch; private Quaternion frozenBodyRotation = Quaternion.identity; private Quaternion frozenAimRotation = Quaternion.identity; private void Awake() { Instance = this; } private void Update() { if ((Object)(object)GameDirector.instance == (Object)null) { return; } bool flag = CanToggle(); if (flag && SoulFlyHotkey.HotkeyDown()) { if (SoulActive) { Exit(); } else { Enter(); } } if (!SoulActive) { return; } if (!Validate()) { Exit(); return; } HoldPlayer(); if (flag && SemiFunc.NoTextInputsActive()) { UpdateLook(); UpdateMovement(); } } private void LateUpdate() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) if (SoulActive && !((Object)(object)mainCamera == (Object)null)) { ((Component)mainCamera).transform.SetPositionAndRotation(flyPosition, Quaternion.Euler(flyPitch, flyYaw, 0f)); } } private bool CanToggle() { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Invalid comparison between Unknown and I4 if ((Object)(object)GameDirector.instance == (Object)null) { return false; } if (GameDirector.instance.DisableInput) { return false; } if (!SemiFunc.NoTextInputsActive()) { return false; } return (int)GameDirector.instance.currentState == 2; } private void Enter() { //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) PlayerController instance = PlayerController.instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.playerAvatarScript == (Object)null) { return; } Camera val = (((Object)(object)GameDirector.instance != (Object)null) ? GameDirector.instance.MainCamera : null); if ((Object)(object)val == (Object)null) { SoulFlyPlugin.Warn("找不到主相机,无法进入灵魂出窍。"); return; } PlayerAvatar playerAvatarScript = instance.playerAvatarScript; if (!IsDead(playerAvatarScript)) { playerController = instance; playerAvatar = playerAvatarScript; visuals = playerAvatarScript.playerAvatarVisuals; localCamera = playerAvatarScript.localCamera; mainCamera = val; cameraParent = ((Component)val).transform.parent; aimTransform = (((Object)(object)CameraAim.Instance != (Object)null) ? ((Component)CameraAim.Instance).transform : cameraParent); flyPosition = ((Component)val).transform.position; Vector3 eulerAngles = ((Component)val).transform.eulerAngles; flyYaw = eulerAngles.y; flyPitch = NormalizePitch(eulerAngles.x); frozenBodyRotation = ((Component)playerAvatarScript).transform.rotation; frozenAimRotation = (((Object)(object)aimTransform != (Object)null) ? aimTransform.localRotation : Quaternion.identity); SoulActive = true; ((Component)val).transform.SetParent((Transform)null, true); FreezeVisuals(); SoulFlyPlugin.LogInfo("进入灵魂出窍。"); } } private void Exit() { if (SoulActive) { SoulActive = false; RestoreCamera(); RestoreVisuals(); RestoreAim(); playerController = null; playerAvatar = null; visuals = null; localCamera = null; animator = null; animatorSpeedCaptured = false; mainCamera = null; SoulFlyPlugin.LogInfo("退出灵魂出窍。"); } } internal void ForceExit() { if (SoulActive) { Exit(); } } private void RestoreCamera() { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)mainCamera == (Object)null)) { Transform val = (((Object)(object)cameraParent != (Object)null) ? cameraParent : (((Object)(object)aimTransform != (Object)null) ? aimTransform : null)); if (!((Object)(object)val == (Object)null)) { ((Component)mainCamera).transform.SetParent(val, false); ((Component)mainCamera).transform.localPosition = Vector3.zero; ((Component)mainCamera).transform.localRotation = Quaternion.identity; } } } private void RestoreAim() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)CameraAim.Instance != (Object)null) { CameraAim.Instance.SetPlayerAim(frozenAimRotation, true); } } private void FreezeVisuals() { if (!((Object)(object)visuals == (Object)null)) { if (FieldAnimator != null) { ref Animator reference = ref animator; object? value = FieldAnimator.GetValue(visuals); reference = (Animator)((value is Animator) ? value : null); } if ((Object)(object)animator != (Object)null) { animatorSpeed = animator.speed; animatorSpeedCaptured = true; animator.speed = 0f; } if ((Object)(object)visuals.meshParent != (Object)null) { visuals.meshParent.SetActive(true); } SetVisibility((ShadowCastingMode)1); } } private void RestoreVisuals() { if ((Object)(object)animator != (Object)null && animatorSpeedCaptured) { animator.speed = animatorSpeed; } if ((Object)(object)visuals != (Object)null) { SetVisibility((ShadowCastingMode)3); } } private void SetVisibility(ShadowCastingMode mode) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)visuals == (Object)null || MethodApplyLocalVisibility == null) { return; } try { MethodApplyLocalVisibility.Invoke(visuals, new object[1] { mode }); } catch (Exception ex) { SoulFlyPlugin.Warn("设置模型可见性失败:" + ex.Message); } } private void HoldPlayer() { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)playerController == (Object)null)) { playerController.InputDisable(0.25f); playerController.Kinematic(0.25f); ((Component)playerController).transform.rotation = frozenBodyRotation; if ((Object)(object)aimTransform != (Object)null) { aimTransform.localRotation = frozenAimRotation; } } } private void UpdateLook() { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)InputManager.instance == (Object)null)) { float num = (((Object)(object)CameraAim.Instance != (Object)null) ? CameraAim.Instance.AimSpeedGet() : 1f); float num2 = ((SoulFlyPlugin.Sensitivity != null) ? SoulFlyPlugin.Sensitivity.Value : 1f); float num3 = SemiFunc.InputMouseX(); float num4 = SemiFunc.InputMouseY(); if (InputManager.instance.AimIsGamepad()) { Vector2 val = InputManager.instance.GamepadAimDeltaGet(); num3 = val.x; num4 = val.y; } if (InputManager.instance.AimInvertVerticalGet()) { num4 = 0f - num4; } flyYaw += num3 * num * num2; flyPitch -= num4 * num * num2; flyPitch = Mathf.Clamp(flyPitch, -89f, 89f); } } private void UpdateMovement() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) Vector2 val = SemiFunc.InputMovement(); float num = 0f; if (SemiFunc.InputHold((InputKey)1)) { num += 1f; } if (SemiFunc.InputHold((InputKey)12)) { num -= 1f; } Quaternion val2 = Quaternion.Euler(flyPitch, flyYaw, 0f); Vector3 val3 = val2 * new Vector3(val.x, 0f, val.y); val3 += Vector3.up * num; if (((Vector3)(ref val3)).sqrMagnitude > 1f) { ((Vector3)(ref val3)).Normalize(); } float num2 = ((SoulFlyPlugin.FlySpeed != null) ? SoulFlyPlugin.FlySpeed.Value : 8f); if (SemiFunc.InputHold((InputKey)15) && SoulFlyPlugin.SprintMultiplier != null) { num2 *= SoulFlyPlugin.SprintMultiplier.Value; } if (num2 < 0f) { num2 = 0f; } flyPosition += val3 * (num2 * Time.deltaTime); } private bool Validate() { //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Invalid comparison between Unknown and I4 if ((Object)(object)playerController == (Object)null || (Object)(object)playerAvatar == (Object)null) { return false; } if ((Object)(object)PlayerController.instance != (Object)(object)playerController) { return false; } if ((Object)(object)playerController.playerAvatarScript != (Object)(object)playerAvatar) { return false; } if ((Object)(object)mainCamera == (Object)null) { return false; } if ((Object)(object)GameDirector.instance == (Object)null || (int)GameDirector.instance.currentState != 2) { return false; } if (IsDead(playerAvatar)) { return false; } return true; } private static bool IsDead(PlayerAvatar avatar) { if ((Object)(object)avatar == (Object)null) { return true; } if (FieldDeadSet != null) { object value = FieldDeadSet.GetValue(avatar); if (value is bool && (bool)value) { return true; } } if (FieldSpectating != null) { object value2 = FieldSpectating.GetValue(avatar); if (value2 is bool && (bool)value2) { return true; } } return false; } internal static Transform PinnedOverrideTransform(PlayerLocalCamera candidate) { if (!SoulActive || (Object)(object)candidate == (Object)null) { return null; } SoulFlyController instance = Instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.localCamera == (Object)null || (Object)(object)candidate != (Object)(object)instance.localCamera) { return null; } if ((Object)(object)instance.aimTransform != (Object)null) { return instance.aimTransform; } return instance.cameraParent; } internal static bool ShouldFreezeVisuals(PlayerAvatarVisuals target) { if (!SoulActive || (Object)(object)target == (Object)null) { return false; } SoulFlyController instance = Instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.visuals == (Object)null) { return false; } return (Object)(object)target == (Object)(object)instance.visuals; } private static float NormalizePitch(float angle) { if (angle > 180f) { angle -= 360f; } return Mathf.Clamp(angle, -89f, 89f); } } internal static class SoulFlyHotkey { private static bool probed; private static bool legacyAvailable = true; private static string parsedName; private static KeyCode parsedKey = (KeyCode)0; internal static bool LegacyInputAvailable() { if (probed) { return legacyAvailable; } probed = true; try { Input.GetKeyDown((KeyCode)0); legacyAvailable = true; } catch (Exception) { legacyAvailable = false; SoulFlyPlugin.Warn("旧输入接口不可用,热键功能将无法响应。"); } return legacyAvailable; } internal static KeyCode GetHotkey() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: 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_002f: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) string text = ((SoulFlyPlugin.HotkeyName == null) ? null : SoulFlyPlugin.HotkeyName.Value); if (text == parsedName) { return parsedKey; } parsedName = text; parsedKey = ParseKeyCode(text); return parsedKey; } private static KeyCode ParseKeyCode(string name) { //IL_004b: 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_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(name)) { return (KeyCode)0; } try { return (KeyCode)Enum.Parse(typeof(KeyCode), name.Trim(), ignoreCase: true); } catch (Exception) { SoulFlyPlugin.Warn("无法解析热键名 " + name + ",热键已禁用。"); return (KeyCode)0; } } internal static bool HotkeyDown() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_0024: Unknown result type (might be due to invalid IL or missing references) if ((int)GetHotkey() == 0) { return false; } if (!LegacyInputAvailable()) { return false; } try { return Input.GetKeyDown(GetHotkey()); } catch (Exception) { return false; } } } [HarmonyPatch(typeof(PlayerAvatarVisuals), "Update")] internal static class PlayerAvatarVisualsUpdatePatch { private static bool Prefix(PlayerAvatarVisuals __instance) { if (!SoulFlyController.ShouldFreezeVisuals(__instance)) { return true; } return false; } } [HarmonyPatch(typeof(CameraAim), "Update")] internal static class CameraAimUpdatePatch { private static bool Prefix() { return !SoulFlyController.SoulActive; } } [HarmonyPatch(typeof(PlayerLocalCamera), "GetOverrideTransform")] internal static class PlayerLocalCameraOverrideTransformPatch { private static void Postfix(PlayerLocalCamera __instance, ref Transform __result) { Transform val = SoulFlyController.PinnedOverrideTransform(__instance); if ((Object)(object)val != (Object)null) { __result = val; } } } [BepInProcess("REPO.exe")] [BepInPlugin("com.aartyns.soulfly", "SoulFly", "1.0.1")] public class SoulFlyPlugin : BaseUnityPlugin { internal static ManualLogSource Log; internal static SoulFlyPlugin Instance; internal static ConfigEntry<string> HotkeyName; internal static ConfigEntry<float> FlySpeed; internal static ConfigEntry<float> SprintMultiplier; internal static ConfigEntry<float> Sensitivity; internal static ConfigEntry<bool> Verbose; private Harmony harmony; private SoulFlyController controller; private void Awake() { //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Expected O, but got Unknown //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; HotkeyName = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Hotkey", "Z", "灵魂出窍切换热键键名,取值同 KeyCode 名称,例如 Z、V、F2、LeftAlt、Mouse3;留空表示关闭热键。"); FlySpeed = ((BaseUnityPlugin)this).Config.Bind<float>("General", "FlySpeed", 8f, "灵魂视角的移动速度,单位米/秒。"); SprintMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("General", "SprintMultiplier", 2.5f, "按住冲刺键时灵魂视角的速度倍率。"); Sensitivity = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Sensitivity", 1f, "灵魂视角鼠标灵敏度倍率,1 表示与游戏本体一致。"); Verbose = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "Verbose", false, "输出详细调试日志。"); harmony = new Harmony("com.aartyns.soulfly"); harmony.PatchAll(); GameObject val = new GameObject("SoulFlyController"); Object.DontDestroyOnLoad((Object)(object)val); controller = val.AddComponent<SoulFlyController>(); Log.LogInfo((object)("SoulFly 已加载,热键:" + HotkeyName.Value)); } private void OnDestroy() { if ((Object)(object)controller != (Object)null) { controller.ForceExit(); } if (harmony != null) { harmony.UnpatchSelf(); } } internal static void LogInfo(string message) { if (Log != null) { Log.LogInfo((object)message); } } internal static void Debug(string message) { if (Log != null && Verbose != null && Verbose.Value) { Log.LogInfo((object)message); } } internal static void Warn(string message) { if (Log != null) { Log.LogWarning((object)message); } } }