From 5fd8e3d4d61f904c9da071e20ae2aca9bbdbfbff Mon Sep 17 00:00:00 2001
From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com>
Date: Fri, 17 Feb 2023 06:24:46 -0600
Subject: [PATCH] backport from experimental
---
DesktopVRSwitch/DesktopVRSwitch.cs | 124 +++++
DesktopVRSwitch/DesktopVRSwitch.csproj | 28 +-
DesktopVRSwitch/DesktopVRSwitchHelper.cs | 434 ------------------
DesktopVRSwitch/HarmonyPatches.cs | 92 ++++
DesktopVRSwitch/Main.cs | 65 +--
.../Patches/CVRPickupObjectTracker.cs | 60 +--
.../Patches/CameraFacingObjectTracker.cs | 24 +
DesktopVRSwitch/Patches/IKSystemTracker.cs | 57 +++
.../Patches/MovementSystemTracker.cs | 39 ++
.../Patches/ReferenceCameraPatch.cs | 91 ++++
.../Patches/VRModeSwitchTracker.cs | 33 ++
DesktopVRSwitch/Properties/AssemblyInfo.cs | 18 +-
DesktopVRSwitch/TryCatchHell.cs | 167 +++++++
DesktopVRSwitch/UIExpansionKitAddon.cs | 14 -
14 files changed, 686 insertions(+), 560 deletions(-)
create mode 100644 DesktopVRSwitch/DesktopVRSwitch.cs
delete mode 100644 DesktopVRSwitch/DesktopVRSwitchHelper.cs
create mode 100644 DesktopVRSwitch/HarmonyPatches.cs
create mode 100644 DesktopVRSwitch/Patches/CameraFacingObjectTracker.cs
create mode 100644 DesktopVRSwitch/Patches/IKSystemTracker.cs
create mode 100644 DesktopVRSwitch/Patches/MovementSystemTracker.cs
create mode 100644 DesktopVRSwitch/Patches/ReferenceCameraPatch.cs
create mode 100644 DesktopVRSwitch/Patches/VRModeSwitchTracker.cs
create mode 100644 DesktopVRSwitch/TryCatchHell.cs
delete mode 100644 DesktopVRSwitch/UIExpansionKitAddon.cs
diff --git a/DesktopVRSwitch/DesktopVRSwitch.cs b/DesktopVRSwitch/DesktopVRSwitch.cs
new file mode 100644
index 0000000..7da6495
--- /dev/null
+++ b/DesktopVRSwitch/DesktopVRSwitch.cs
@@ -0,0 +1,124 @@
+using NAK.Melons.DesktopVRSwitch.Patches;
+using System.Collections;
+using UnityEngine;
+using UnityEngine.XR;
+using Valve.VR;
+
+namespace NAK.Melons.DesktopVRSwitch;
+
+public class DesktopVRSwitch : MonoBehaviour
+{
+ //Settings
+ public bool _reloadLocalAvatar = true;
+
+ //Internal Stuff
+ private bool _switchInProgress = false;
+
+ void Start()
+ {
+ //do not pause game, this breaks dynbones & trackers
+ SteamVR_Settings.instance.pauseGameWhenDashboardVisible = false;
+ }
+
+ void Update()
+ {
+ if (Input.GetKeyDown(KeyCode.F6) && Input.GetKey(KeyCode.LeftControl))
+ {
+ SwitchVRMode();
+ }
+ }
+
+ public void SwitchVRMode()
+ {
+ if (_switchInProgress) return;
+ if (!IsInVR())
+ {
+ StartCoroutine(StartVRSystem());
+ }
+ else
+ {
+ StartCoroutine(StopVR());
+ }
+ }
+
+ public bool IsInVR() => XRSettings.enabled;
+
+ private IEnumerator StartVRSystem()
+ {
+ BeforeVRModeSwitch(true);
+ XRSettings.LoadDeviceByName("OpenVR");
+ yield return null;
+ if (string.IsNullOrEmpty(XRSettings.loadedDeviceName))
+ {
+ DesktopVRSwitchMod.Logger.Error("Initializing VR Failed. Is there no VR device connected?");
+ }
+ else
+ {
+ DesktopVRSwitchMod.Logger.Msg("Starting SteamVR...");
+ XRSettings.enabled = true;
+ //force steamvr to reinitialize input
+ //this does SteamVR_Input.actionSets[0].Activate() for us (we deactivate in StopVR())
+ //but only if SteamVR_Settings.instance.activateFirstActionSetOnStart is enabled
+ //which in ChilloutVR, it is, because all those settings are default
+ SteamVR_Input.Initialize(true);
+ yield return null;
+ AfterVRModeSwitch(true);
+ }
+ yield break;
+ }
+
+ private IEnumerator StopVR()
+ {
+ BeforeVRModeSwitch(false);
+ yield return null;
+ if (!string.IsNullOrEmpty(XRSettings.loadedDeviceName))
+ {
+ //deactivate the action set so SteamVR_Input.Initialize can reactivate
+ SteamVR_Input.actionSets[0].Deactivate(SteamVR_Input_Sources.Any);
+ SteamVR.SafeDispose(); //idk
+ XRSettings.LoadDeviceByName("");
+ XRSettings.enabled = false;
+ yield return null;
+ //reset physics time to Desktop default
+ Time.fixedDeltaTime = 0.02f;
+ AfterVRModeSwitch(false);
+ }
+ yield break;
+ }
+
+ //one frame before switch attempt
+ public void BeforeVRModeSwitch(bool enterVR)
+ {
+ //let tracked objects know we are attempting to switch
+ VRModeSwitchTracker.PreVRModeSwitch(enterVR);
+ }
+
+ //one frame after switch attempt
+ public void AfterVRModeSwitch(bool enterVR)
+ {
+ //these two must come first
+ TryCatchHell.SetCheckVR(enterVR);
+ TryCatchHell.SetMetaPort(enterVR);
+
+ //the bulk of funni changes
+ TryCatchHell.RepositionCohtmlHud(enterVR);
+ TryCatchHell.UpdateHudOperations(enterVR);
+ TryCatchHell.DisableMirrorCanvas();
+ TryCatchHell.SwitchActiveCameraRigs(enterVR);
+ TryCatchHell.ResetCVRInputManager();
+ TryCatchHell.UpdateRichPresence();
+ TryCatchHell.UpdateGestureReconizerCam();
+
+ //let tracked objects know we switched
+ VRModeSwitchTracker.PostVRModeSwitch(enterVR);
+
+ //reload avatar by default, optional for debugging
+ if (_reloadLocalAvatar)
+ {
+ TryCatchHell.ReloadLocalAvatar();
+ }
+
+ _switchInProgress = false;
+ }
+}
+
diff --git a/DesktopVRSwitch/DesktopVRSwitch.csproj b/DesktopVRSwitch/DesktopVRSwitch.csproj
index adb74e4..0e61fd5 100644
--- a/DesktopVRSwitch/DesktopVRSwitch.csproj
+++ b/DesktopVRSwitch/DesktopVRSwitch.csproj
@@ -16,19 +16,16 @@
C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Assembly-CSharp.dll
- ..\..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Assembly-CSharp-firstpass.dll
+ C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Assembly-CSharp-firstpass.dll
- ..\..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Aura2_Core.dll
+ C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Aura2_Core.dll
- ..\..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\cohtml.Net.dll
+ C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\cohtml.Net.dll
- ..\..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Cohtml.Runtime.dll
-
-
- ..\..\Giamoz\Giamoz\bin\Debug\net472\Giamoz.dll
+ C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Cohtml.Runtime.dll
C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\MelonLoader\MelonLoader.dll
@@ -37,16 +34,16 @@
C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\SteamVR.dll
- ..\..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\ChilloutVR\Mods\UIExpansionKit.dll
+ C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\Mods\UIExpansionKit.dll
- ..\..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Unity.Postprocessing.Runtime.dll
+ C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Unity.Postprocessing.Runtime.dll
- ..\..\..\DakyModsCVR\ManagedLibs\Unity.TextMeshPro.dll
+ C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Unity.TextMeshPro.dll
- ..\..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.AnimationModule.dll
+ C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.AnimationModule.dll
C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.CoreModule.dll
@@ -55,13 +52,16 @@
C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.InputLegacyModule.dll
- ..\..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.PhysicsModule.dll
+ C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.PhysicsModule.dll
- ..\..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.VRModule.dll
+ C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.VRModule.dll
+
+
+ C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.VRModule.dll
- ..\..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.XRModule.dll
+ ..\..\..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.XRModule.dll
diff --git a/DesktopVRSwitch/DesktopVRSwitchHelper.cs b/DesktopVRSwitch/DesktopVRSwitchHelper.cs
deleted file mode 100644
index ee7949d..0000000
--- a/DesktopVRSwitch/DesktopVRSwitchHelper.cs
+++ /dev/null
@@ -1,434 +0,0 @@
-using ABI_RC.Core;
-using ABI_RC.Core.EventSystem;
-using ABI_RC.Core.InteractionSystem;
-using ABI_RC.Core.Player;
-using ABI_RC.Core.Savior;
-using ABI_RC.Core.UI;
-using ABI_RC.Core.Util.Object_Behaviour;
-using ABI_RC.Systems.Camera;
-using ABI_RC.Systems.IK.SubSystems;
-using ABI_RC.Systems.MovementSystem;
-using DesktopVRSwitch.Patches;
-using HarmonyLib;
-using MelonLoader;
-using System.Collections;
-using UnityEngine;
-using UnityEngine.XR;
-using Valve.VR;
-using Object = UnityEngine.Object;
-
-namespace DesktopVRSwitch;
-
-public class DesktopVRSwitchHelper : MonoBehaviour
-{
- public static DesktopVRSwitchHelper Instance;
-
- //settings
- public bool SettingTimedErrorCatch = true;
- public float SettingTimedErrorTimer = 10f;
-
- //internal shit
- internal static bool isAttemptingSwitch = false;
- internal static float timedSwitch = 0f;
- internal static bool CurrentMode;
- internal static Vector3 avatarWorldPos;
- internal static Quaternion avatarWorldRot;
-
- public void SwitchMode(bool isTimedSwitch = false)
- {
- if (isAttemptingSwitch) return;
-
- isAttemptingSwitch = true;
- MelonCoroutines.Start(AttemptPlatformSwitch());
-
- //how long we wait until we assume an error occured
- if (isTimedSwitch)
- timedSwitch = Time.time + SettingTimedErrorTimer;
- }
-
- public void Start()
- {
- Instance = this;
- }
-
- public void Update()
- {
- // assuming CVRInputManager.switchMode button was originally for desktop/vr switching before being left to do literally nothing in rootlogic
- if (Input.GetKeyDown(KeyCode.F6) && (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl)) && !isAttemptingSwitch)
- {
- SwitchMode(true);
- }
-
- if (!isAttemptingSwitch) return;
-
- //catch if coroutine just decided to not finish... which happens?
- if (Time.time > timedSwitch)
- {
- MelonLogger.Error("Timer exceeded. Something is wrong and coroutine failed partway.");
- isAttemptingSwitch = false;
- if (SettingTimedErrorCatch)
- SwitchMode();
- }
- }
-
- //disables VRIK if it was on the current avatar during switch
- //absolutely bruteforcing the stupid vr playspace offset issue
- public void LateUpdate()
- {
- if (!isAttemptingSwitch) return;
-
- if (!PlayerSetup.Instance.avatarIsLoading && PlayerSetup.Instance._avatar != null)
- {
- BodySystem.TrackingEnabled = false;
- BodySystem.TrackingPositionWeight = 0f;
- PlayerSetup.Instance._avatar.transform.position = avatarWorldPos;
- PlayerSetup.Instance._avatar.transform.rotation = avatarWorldRot;
- MovementSystem.Instance.TeleportToPosRot(avatarWorldPos, avatarWorldRot, false);
- MovementSystem.Instance.UpdateColliderCenter(avatarWorldPos);
- }
- }
-
- internal static IEnumerator AttemptPlatformSwitch(bool forceMode = false)
- {
- //forceMode will attempt to backtrack to last working mode (if you dont like the mess, fix it yourself thx)
- CurrentMode = forceMode ? CurrentMode : MetaPort.Instance.isUsingVr;
- bool VRMode = forceMode ? CurrentMode : !CurrentMode;
-
- CloseMenuElements(VRMode);
- ToggleInputInteractions(false);
- DisableMirrorCanvas();
-
- //store current player position/rotation to correct VR/Desktop offsets
- avatarWorldPos = PlayerSetup.Instance._avatar.transform.position;
- avatarWorldRot = PlayerSetup.Instance._avatar.transform.rotation;
-
- //exit all movement states
- MovementSystem.Instance.ChangeCrouch(false);
- MovementSystem.Instance.ChangeProne(false);
- MovementSystem.Instance.canMove = false;
- MovementSystem.Instance.canRot = false;
-
- //load SteamVR
- InitializeSteamVR(VRMode);
-
- yield
- return new WaitForEndOfFrame();
-
- SetCheckVR(VRMode);
- SetMetaPort(VRMode);
-
- //reset rich presence
- if (MetaPort.Instance.settings.GetSettingsBool("ImplementationRichPresenceDiscordEnabled", true))
- {
- MetaPort.Instance.settings.SetSettingsBool("ImplementationRichPresenceDiscordEnabled", false);
- MetaPort.Instance.settings.SetSettingsBool("ImplementationRichPresenceDiscordEnabled", true);
- }
- if (MetaPort.Instance.settings.GetSettingsBool("ImplementationRichPresenceSteamEnabled", true))
- {
- MetaPort.Instance.settings.SetSettingsBool("ImplementationRichPresenceSteamEnabled", false);
- MetaPort.Instance.settings.SetSettingsBool("ImplementationRichPresenceSteamEnabled", true);
- }
-
- yield
- return new WaitForEndOfFrame();
-
- SwitchActiveCameraRigs(VRMode);
- UpdateCameraFacingObject();
- RepositionCohtmlHud(VRMode);
- UpdateHudOperations(VRMode);
- SwitchPickupOrigins();
-
- yield
- return new WaitForEndOfFrame();
-
- //needs to come after SetMovementSystem
- UpdateGestureReconizerCam();
-
- ResetCVRInputManager();
-
- //gonna try doing this last
- DisposeSteamVR(VRMode);
-
- ToggleInputInteractions(true);
-
- //reload current avatar
- AssetManagement.Instance.LoadLocalAvatar(MetaPort.Instance.currentAvatarGuid);
-
- yield return new WaitUntil(() => !PlayerSetup.Instance.avatarIsLoading);
-
- isAttemptingSwitch = false;
-
- BodySystem.TrackingEnabled = true;
- BodySystem.TrackingPositionWeight = 1f;
- MovementSystem.Instance.canMove = true;
- MovementSystem.Instance.canRot = true;
-
- if (!VRMode)
- //collision center is set to match headpos in VR, but desktop doesnt reset it
- MovementSystem.Instance.UpdateColliderCenter(PlayerSetup.Instance._avatar.transform.position);
-
- yield
- return new WaitForEndOfFrame();
-
- //one last teleport to correct VR offset
- MovementSystem.Instance.TeleportToPosRot(avatarWorldPos, avatarWorldRot, false);
-
- yield
- return null;
- }
-
- //shitton of try catch below
-
- internal static void InitializeSteamVR(bool isVR)
- {
- if (isVR)
- {
- //force SteamVR to fully initialize, this does all and more than what i did with LoadDevice()
- SteamVR.Initialize(true);
-
- //Just to make sure. Game does this natively when entering VR.
- SteamVR_Settings.instance.pauseGameWhenDashboardVisible = false;
-
- //TODO: something needs to be done to reinitialize SteamVR_Input or SteamVR_Actions
- //If you restart SteamVR after already have been in VRMode, the steamvr action handles break
- //ive tried:
- //SteamVR_Input.Initialize(true)
- //SteamVR_Actions.PreInitialize()
- //Destroying SteamVR_Settings on DesktopMode
- //Destroying SteamVR_Behavior on DesktopMode
- //Destroying SteamVR_Render on DesktopMode
- //Combinations of all of these..
- //Its probably really simple, but I just cannot figure out how.
- }
- }
-
- internal static void DisposeSteamVR(bool isVR)
- {
- if (!isVR)
- {
- //force SteamVR to let go of Chillout
- XRSettings.LoadDeviceByName("None");
- XRSettings.enabled = false;
-
- //destroy [SteamVR] gameobject as next SteamVR.Initialize creates a new one
- Object.Destroy(SteamVR_Behaviour.instance.gameObject);
-
- //what even does this do that is actually important?
- SteamVR.SafeDispose();
- }
- }
-
- // shouldn't be that important, right?
- internal static void CloseMenuElements(bool isVR)
- {
- if (ViewManager.Instance != null)
- {
- MelonLogger.Msg("Closed MainMenu Instance.");
- ViewManager.Instance.UiStateToggle(false);
- }
- else
- {
- MelonLogger.Msg("MainMenu Instance not found!!!");
- }
- if (ViewManager.Instance != null)
- {
- MelonLogger.Msg("Closed QuickMenu Instance.");
- CVR_MenuManager.Instance.ToggleQuickMenu(false);
- }
- else
- {
- MelonLogger.Msg("QuickMenu Instance not found!!!");
- }
- }
-
- internal static void ToggleInputInteractions(bool toggle)
- {
- //disable input during switch
- try
- {
- MelonLogger.Msg($"Toggling input & interactions to " + toggle);
- CVRInputManager.Instance.inputEnabled = toggle;
- CVR_InteractableManager.enableInteractions = toggle;
- }
- catch
- {
- MelonLogger.Error("Toggling input & interactions failed. Is something invalid?");
- MelonLogger.Msg("CVRInputManager.Instance: " + CVRInputManager.Instance);
- MelonLogger.Msg("CVR_InteractableManager: " + CVR_InteractableManager.enableInteractions);
- throw;
- }
- }
-
- internal static void SetCheckVR(bool isVR)
- {
- try
- {
- MelonLogger.Msg($"Set CheckVR hasVrDeviceLoaded to {isVR}.");
- CheckVR.Instance.hasVrDeviceLoaded = isVR;
- }
- catch
- {
- MelonLogger.Error("Setting CheckVR hasVrDeviceLoaded failed. Is CheckVR.Instance invalid?");
- MelonLogger.Msg("CheckVR.Instance: " + CheckVR.Instance);
- throw;
- }
- }
-
- internal static void SetMetaPort(bool isVR)
- {
- try
- {
- MelonLogger.Msg($"Set MetaPort isUsingVr to {isVR}.");
- MetaPort.Instance.isUsingVr = isVR;
- }
- catch
- {
- MelonLogger.Error("Setting MetaPort isUsingVr failed. Is MetaPort.Instance invalid?");
- MelonLogger.Msg("MetaPort.Instance: " + MetaPort.Instance);
- throw;
- }
- }
-
- internal static void SwitchActiveCameraRigs(bool isVR)
- {
- try
- {
- MelonLogger.Msg("Switched active camera rigs.");
- PlayerSetup.Instance.desktopCameraRig.SetActive(!isVR);
- PlayerSetup.Instance.vrCameraRig.SetActive(isVR);
- }
- catch
- {
- MelonLogger.Error("Error switching active cameras. Are the camera rigs invalid?");
- MelonLogger.Msg("PlayerSetup.Instance.desktopCameraRig: " + PlayerSetup.Instance.desktopCameraRig);
- MelonLogger.Msg("PlayerSetup.Instance.vrCameraRig: " + PlayerSetup.Instance.vrCameraRig);
- throw;
- }
- }
-
- internal static void RepositionCohtmlHud(bool isVR)
- {
- try
- {
- MelonLogger.Msg("Parented CohtmlHud to active camera.");
- CohtmlHud.Instance.gameObject.transform.parent = isVR ? PlayerSetup.Instance.vrCamera.transform : PlayerSetup.Instance.desktopCamera.transform;
-
- //sets hud position, rotation, ~~and scale~~ based on MetaPort isUsingVr
- CVRTools.ConfigureHudAffinity();
- CohtmlHud.Instance.gameObject.transform.localScale = new Vector3(1.2f, 1f, 1.2f);
- }
- catch
- {
- MelonLogger.Error("Error parenting CohtmlHud to active camera. Is CohtmlHud.Instance invalid?");
- MelonLogger.Msg("CohtmlHud.Instance: " + CohtmlHud.Instance);
- throw;
- }
- }
-
- internal static void ResetCVRInputManager()
- {
- try
- {
- MelonLogger.Msg("Enabling CVRInputManager inputEnabled & disabling blockedByUi!");
- //CVRInputManager.Instance.reload = true;
- //just in case
- CVRInputManager.Instance.inputEnabled = true;
- CVRInputManager.Instance.blockedByUi = false;
- //sometimes head can get stuck, so just in case
- CVRInputManager.Instance.independentHeadToggle = false;
- //just nice to load into desktop with idle gesture
- CVRInputManager.Instance.gestureLeft = 0f;
- CVRInputManager.Instance.gestureLeftRaw = 0f;
- CVRInputManager.Instance.gestureRight = 0f;
- CVRInputManager.Instance.gestureRightRaw = 0f;
- }
- catch
- {
- MelonLogger.Error("CVRInputManager reload failed. Is CVRInputManager.Instance invalid?");
- MelonLogger.Msg("CVRInputManager.Instance: " + CVRInputManager.Instance);
- throw;
- }
- }
-
- //every nameplate canvas uses CameraFacingObject :stare:
- internal static void UpdateCameraFacingObject()
- {
- try
- {
- MelonLogger.Msg("Updating all CameraFacingObject scripts to face new camera. (this fixes nameplates)");
- CameraFacingObject[] camfaceobjs = Object.FindObjectsOfType();
-
- for (int i = 0; i < camfaceobjs.Count(); i++)
- {
- camfaceobjs[i].m_Camera = PlayerSetup.Instance.GetActiveCamera().GetComponent();
- }
- }
- catch
- {
- MelonLogger.Error("Error updating CameraFacingObject objects! Nameplates will be wonk...");
- throw;
- }
- }
-
- internal static void UpdateHudOperations(bool isVR)
- {
- try
- {
- MelonLogger.Msg("Set HudOperations worldLoadingItem and worldLoadStatus to their respective Desktop/Vr parent.");
- HudOperations.Instance.worldLoadingItem = isVR ? HudOperations.Instance.worldLoadingItemVr : HudOperations.Instance.worldLoadingItemDesktop;
- HudOperations.Instance.worldLoadStatus = isVR ? HudOperations.Instance.worldLoadStatusVr : HudOperations.Instance.worldLoadStatusDesktop;
- }
- catch
- {
- MelonLogger.Error("Error updating HudOperations LoadingItem & LoadStatus!");
- throw;
- }
- }
-
- internal static void DisableMirrorCanvas()
- {
- try
- {
- //tell the game we are in mirror mode so itll disable it (if enabled)
- PortableCamera.Instance.mode = MirroringMode.Mirror;
- PortableCamera.Instance.ChangeMirroring();
- }
- catch
- {
- MelonLogger.Error("Error updating CVRGestureRecognizer camera!");
- throw;
- }
- }
-
- internal static void UpdateGestureReconizerCam()
- {
- try
- {
- MelonLogger.Msg("Set GestureReconizerCam camera to active camera.");
- Traverse.Create(CVRGestureRecognizer.Instance).Field("_camera").SetValue(PlayerSetup.Instance.GetActiveCamera().GetComponent());
- }
- catch
- {
- MelonLogger.Error("Error updating CVRGestureRecognizer camera!");
- throw;
- }
- }
-
- internal static void SwitchPickupOrigins()
- {
- try
- {
- MelonLogger.Msg("Switched pickup origins.");
- CVRPickupObjectTracker[] pickups = Object.FindObjectsOfType();
- for (int i = 0; i < pickups.Count(); i++)
- {
- pickups[i].OnSwitch();
- }
- }
- catch
- {
- MelonLogger.Error("Error switching pickup origins!");
- throw;
- }
- }
-}
\ No newline at end of file
diff --git a/DesktopVRSwitch/HarmonyPatches.cs b/DesktopVRSwitch/HarmonyPatches.cs
new file mode 100644
index 0000000..6790699
--- /dev/null
+++ b/DesktopVRSwitch/HarmonyPatches.cs
@@ -0,0 +1,92 @@
+using ABI.CCK.Components;
+using ABI_RC.Core.Player;
+using ABI_RC.Core.Savior;
+using ABI_RC.Core.Util.Object_Behaviour;
+using ABI_RC.Systems.IK;
+using ABI_RC.Systems.MovementSystem;
+using HarmonyLib;
+using NAK.Melons.DesktopVRSwitch.Patches;
+using UnityEngine;
+
+namespace NAK.Melons.DesktopVRSwitch.HarmonyPatches;
+
+internal class PlayerSetupPatches
+{
+ [HarmonyPostfix]
+ [HarmonyPatch(typeof(PlayerSetup), "Start")]
+ private static void Postfix_PlayerSetup_Start(ref PlayerSetup __instance)
+ {
+ if (CheckVR.Instance != null)
+ {
+ CheckVR.Instance.gameObject.AddComponent();
+ return;
+ }
+ __instance.gameObject.AddComponent();
+ DesktopVRSwitchMod.Logger.Error("CheckVR not found. Reverting to fallback method. This should never happen!");
+ }
+}
+
+internal class MovementSystemPatches
+{
+ [HarmonyPostfix]
+ [HarmonyPatch(typeof(MovementSystem), "Start")]
+ private static void Postfix_MovementSystem_Start(ref MovementSystem __instance)
+ {
+ __instance.gameObject.AddComponent();
+ }
+}
+
+internal class CVRPickupObjectPatches
+{
+ [HarmonyPrefix]
+ [HarmonyPatch(typeof(CVRPickupObject), "Start")]
+ private static void Prefix_CVRPickupObject_Start(ref CVRPickupObject __instance)
+ {
+ if (__instance.gripType == CVRPickupObject.GripType.Free) return;
+ Transform vrOrigin = __instance.gripOrigin;
+ Transform desktopOrigin = __instance.gripOrigin.Find("[Desktop]");
+ if (vrOrigin != null && desktopOrigin != null)
+ {
+ var tracker = __instance.gameObject.AddComponent();
+ tracker.pickupObject = __instance;
+ tracker.storedGripOrigin = (!MetaPort.Instance.isUsingVr ? vrOrigin : desktopOrigin);
+ }
+ }
+}
+
+internal class CVRWorldPatches
+{
+ [HarmonyPostfix]
+ [HarmonyPatch(typeof(CVRWorld), "SetDefaultCamValues")]
+ private static void CVRWorld_SetDefaultCamValues_Postfix()
+ {
+ ReferenceCameraPatch.OnWorldLoad();
+ }
+
+ [HarmonyPostfix]
+ [HarmonyPatch(typeof(CVRWorld), "CopyRefCamValues")]
+ private static void CVRWorld_CopyRefCamValues_Postfix()
+ {
+ ReferenceCameraPatch.OnWorldLoad();
+ }
+}
+
+internal class CameraFacingObjectPatches
+{
+ [HarmonyPostfix]
+ [HarmonyPatch(typeof(CameraFacingObject), "Start")]
+ private static void Postfix_CameraFacingObject_Start(ref CameraFacingObject __instance)
+ {
+ __instance.gameObject.AddComponent();
+ }
+}
+
+internal class IKSystemPatches
+{
+ [HarmonyPostfix]
+ [HarmonyPatch(typeof(IKSystem), "Start")]
+ private static void Postfix_IKSystem_Start(ref IKSystem __instance)
+ {
+ __instance.gameObject.AddComponent();
+ }
+}
\ No newline at end of file
diff --git a/DesktopVRSwitch/Main.cs b/DesktopVRSwitch/Main.cs
index a6ca2f9..4e61e12 100644
--- a/DesktopVRSwitch/Main.cs
+++ b/DesktopVRSwitch/Main.cs
@@ -1,59 +1,36 @@
-using ABI_RC.Core.Player;
-using MelonLoader;
+using MelonLoader;
-//tell the game to change VRMode/DesktopMode for Steam/Discord presence
-//RichPresence.PopulatePresence();
+namespace NAK.Melons.DesktopVRSwitch;
-//nvm that resets the RichPresence clock- i want people to know how long ive wasted staring at mirror
-
-namespace DesktopVRSwitch;
-
-public class DesktopVRSwitch : MelonMod
+public class DesktopVRSwitchMod : MelonMod
{
internal const string SettingsCategory = "DesktopVRSwitch";
internal static MelonPreferences_Category m_categoryDesktopVRSwitch;
- internal static MelonPreferences_Entry m_entryTimedErrorCatch;
- internal static MelonPreferences_Entry m_entryTimedErrorTimer;
+ internal static MelonLogger.Instance Logger;
public override void OnInitializeMelon()
{
+ Logger = LoggerInstance;
m_categoryDesktopVRSwitch = MelonPreferences.CreateCategory(SettingsCategory);
- m_entryTimedErrorCatch = m_categoryDesktopVRSwitch.CreateEntry("Timed Error Catch", true, description: "Attempt to switch back if an error is found after n seconds.");
- m_entryTimedErrorTimer = m_categoryDesktopVRSwitch.CreateEntry("Timed Error Timer", 10f, description: "Amount of seconds to wait before assuming there was an error.");
- m_categoryDesktopVRSwitch.SaveToFile(false);
- foreach (var setting in m_categoryDesktopVRSwitch.Entries)
- {
- setting.OnEntryValueChangedUntyped.Subscribe(OnUpdateSettings);
- }
-
- //UIExpansionKit addon
- if (MelonMod.RegisteredMelons.Any(it => it.Info.Name == "UI Expansion Kit"))
- {
- MelonLogger.Msg("Initializing UIExpansionKit support.");
- UiExtensionsAddon.Init();
- }
- MelonLoader.MelonCoroutines.Start(WaitForLocalPlayer());
+ ApplyPatches(typeof(HarmonyPatches.PlayerSetupPatches));
+ ApplyPatches(typeof(HarmonyPatches.CVRPickupObjectPatches));
+ ApplyPatches(typeof(HarmonyPatches.CVRWorldPatches));
+ ApplyPatches(typeof(HarmonyPatches.CameraFacingObjectPatches));
+ ApplyPatches(typeof(HarmonyPatches.IKSystemPatches));
+ ApplyPatches(typeof(HarmonyPatches.MovementSystemPatches));
}
- System.Collections.IEnumerator WaitForLocalPlayer()
+ private void ApplyPatches(Type type)
{
- while (PlayerSetup.Instance == null)
- yield return null;
-
- PlayerSetup.Instance.gameObject.AddComponent();
-
- while (DesktopVRSwitchHelper.Instance == null)
- yield return null;
-
- UpdateAllSettings();
- }
-
- private void OnUpdateSettings(object arg1, object arg2) => UpdateAllSettings();
- private void UpdateAllSettings()
- {
- if (!DesktopVRSwitchHelper.Instance) return;
- DesktopVRSwitchHelper.Instance.SettingTimedErrorCatch = m_entryTimedErrorCatch.Value;
- DesktopVRSwitchHelper.Instance.SettingTimedErrorTimer = m_entryTimedErrorTimer.Value;
+ try
+ {
+ HarmonyInstance.PatchAll(type);
+ }
+ catch (Exception e)
+ {
+ Logger.Msg($"Failed while patching {type.Name}!");
+ Logger.Error(e);
+ }
}
}
\ No newline at end of file
diff --git a/DesktopVRSwitch/Patches/CVRPickupObjectTracker.cs b/DesktopVRSwitch/Patches/CVRPickupObjectTracker.cs
index 5bb7943..3f73d51 100644
--- a/DesktopVRSwitch/Patches/CVRPickupObjectTracker.cs
+++ b/DesktopVRSwitch/Patches/CVRPickupObjectTracker.cs
@@ -1,61 +1,31 @@
using ABI.CCK.Components;
-using ABI_RC.Core.Savior;
-using HarmonyLib;
-using MelonLoader;
using UnityEngine;
//Thanks Ben! I was scared of transpiler so I reworked a bit...
-namespace DesktopVRSwitch.Patches;
-
-[HarmonyPatch]
-internal class CVRPickupObject_Patch
-{
- [HarmonyPrefix]
- [HarmonyPatch(typeof(CVRPickupObject), "Start")]
- private static void CVRPickupObject_Start_Prefix(ref CVRPickupObject __instance)
- {
- if (__instance.gripOrigin == null) return;
-
- Transform desktopOrigin = __instance.gripOrigin.Find("[Desktop]");
- if (desktopOrigin == null) return;
-
- var pickupTracker = __instance.GetComponent();
- if (pickupTracker != null) return;
-
- __instance.gameObject.AddComponent();
-
- StorePreviousPosition(__instance, (!MetaPort.Instance.isUsingVr) ? __instance.gripOrigin : desktopOrigin);
- }
-
- private static void StorePreviousPosition(CVRPickupObject pickupObject, Transform gripOrigin)
- {
- MelonLogger.Msg("Storing previous gripOrigin.");
- CVRPickupObjectTracker.previousGripOrigin[pickupObject] = gripOrigin;
- }
-}
+namespace NAK.Melons.DesktopVRSwitch.Patches;
public class CVRPickupObjectTracker : MonoBehaviour
{
- //maybe i should store both transforms instead and getcomponent for CVRPickupObject..?
- public static Dictionary previousGripOrigin = new();
+ public CVRPickupObject pickupObject;
+ public Transform storedGripOrigin;
- public void OnSwitch()
+ void Start()
{
- var pickupObject = GetComponent();
+ VRModeSwitchTracker.OnPostVRModeSwitch += PostVRModeSwitch;
+ }
+ void OnDestroy()
+ {
+ VRModeSwitchTracker.OnPostVRModeSwitch -= PostVRModeSwitch;
+ }
+
+ public void PostVRModeSwitch(bool enterVR, Camera activeCamera)
+ {
if (pickupObject != null)
{
- if (pickupObject.IsGrabbedByMe() && pickupObject._controllerRay != null) pickupObject._controllerRay.DropObject(true);
- (previousGripOrigin[pickupObject], pickupObject.gripOrigin) = (pickupObject.gripOrigin, previousGripOrigin[pickupObject]);
+ if (pickupObject._controllerRay != null) pickupObject._controllerRay.DropObject(true);
+ (storedGripOrigin, pickupObject.gripOrigin) = (pickupObject.gripOrigin, storedGripOrigin);
}
}
-
- private void OnDestroy()
- {
- var pickupObject = GetComponent();
-
- if (pickupObject != null)
- previousGripOrigin.Remove(pickupObject);
- }
}
diff --git a/DesktopVRSwitch/Patches/CameraFacingObjectTracker.cs b/DesktopVRSwitch/Patches/CameraFacingObjectTracker.cs
new file mode 100644
index 0000000..918e925
--- /dev/null
+++ b/DesktopVRSwitch/Patches/CameraFacingObjectTracker.cs
@@ -0,0 +1,24 @@
+using ABI_RC.Core.Util.Object_Behaviour;
+using UnityEngine;
+
+namespace NAK.Melons.DesktopVRSwitch.Patches;
+
+public class CameraFacingObjectTracker : MonoBehaviour
+{
+ public CameraFacingObject cameraFacingObject;
+ void Start()
+ {
+ cameraFacingObject = GetComponent();
+ VRModeSwitchTracker.OnPostVRModeSwitch += PostVRModeSwitch;
+ }
+
+ void OnDestroy()
+ {
+ VRModeSwitchTracker.OnPostVRModeSwitch -= PostVRModeSwitch;
+ }
+
+ public void PostVRModeSwitch(bool enterVR, Camera activeCamera)
+ {
+ cameraFacingObject.m_Camera = activeCamera;
+ }
+}
\ No newline at end of file
diff --git a/DesktopVRSwitch/Patches/IKSystemTracker.cs b/DesktopVRSwitch/Patches/IKSystemTracker.cs
new file mode 100644
index 0000000..f64acea
--- /dev/null
+++ b/DesktopVRSwitch/Patches/IKSystemTracker.cs
@@ -0,0 +1,57 @@
+using ABI_RC.Systems.IK;
+using ABI_RC.Systems.IK.SubSystems;
+using ABI_RC.Systems.IK.TrackingModules;
+using HarmonyLib;
+using UnityEngine;
+using System.Reflection;
+
+namespace NAK.Melons.DesktopVRSwitch.Patches;
+
+public class IKSystemTracker : MonoBehaviour
+{
+ public IKSystem ikSystem;
+ public Traverse _traverseModules;
+
+ void Start()
+ {
+ ikSystem = GetComponent();
+ _traverseModules = Traverse.Create(ikSystem).Field("_trackingModules");
+ VRModeSwitchTracker.OnPostVRModeSwitch += PostVRModeSwitch;
+ }
+ void OnDestroy()
+ {
+ VRModeSwitchTracker.OnPostVRModeSwitch -= PostVRModeSwitch;
+ }
+
+ public void PostVRModeSwitch(bool enterVR, Camera activeCamera)
+ {
+ var _trackingModules = _traverseModules.GetValue>();
+ SteamVRTrackingModule openVRTrackingModule = _trackingModules.FirstOrDefault(m => m is SteamVRTrackingModule) as SteamVRTrackingModule;
+ if (openVRTrackingModule != null)
+ {
+ if (enterVR)
+ {
+ openVRTrackingModule.ModuleStart();
+ }
+ else
+ {
+ //why named destroy when it doesnt ?
+ openVRTrackingModule.ModuleDestroy();
+ }
+ }
+ else
+ {
+ var steamVRTrackingModule = CreateSteamVRTrackingModule();
+ ikSystem.AddTrackingModule(steamVRTrackingModule);
+ }
+ }
+
+ //thanks for marking the constructor as internal
+ private SteamVRTrackingModule CreateSteamVRTrackingModule()
+ {
+ var steamVRTrackingModuleType = typeof(SteamVRTrackingModule);
+ var constructor = steamVRTrackingModuleType.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, null);
+ var instance = constructor.Invoke(null);
+ return (SteamVRTrackingModule)instance;
+ }
+}
\ No newline at end of file
diff --git a/DesktopVRSwitch/Patches/MovementSystemTracker.cs b/DesktopVRSwitch/Patches/MovementSystemTracker.cs
new file mode 100644
index 0000000..7aea4c9
--- /dev/null
+++ b/DesktopVRSwitch/Patches/MovementSystemTracker.cs
@@ -0,0 +1,39 @@
+using ABI_RC.Systems.MovementSystem;
+using UnityEngine;
+
+namespace NAK.Melons.DesktopVRSwitch.Patches;
+
+public class MovementSystemTracker : MonoBehaviour
+{
+ public MovementSystem movementSystem;
+
+ public Vector3 preSwitchWorldPosition;
+ public Quaternion preSwitchWorldRotation;
+
+ void Start()
+ {
+ movementSystem = GetComponent();
+ VRModeSwitchTracker.OnPostVRModeSwitch += PreVRModeSwitch;
+ VRModeSwitchTracker.OnPostVRModeSwitch += PostVRModeSwitch;
+ }
+
+ void OnDestroy()
+ {
+ VRModeSwitchTracker.OnPostVRModeSwitch -= PreVRModeSwitch;
+ VRModeSwitchTracker.OnPostVRModeSwitch -= PostVRModeSwitch;
+ }
+
+ public void PreVRModeSwitch(bool enterVR, Camera activeCamera)
+ {
+ preSwitchWorldPosition = movementSystem.rotationPivot.transform.position;
+ preSwitchWorldRotation = movementSystem.rotationPivot.transform.rotation;
+ }
+
+ public void PostVRModeSwitch(bool enterVR, Camera activeCamera)
+ {
+ //lazy way of correcting Desktop & VR offset issue (game does the maths)
+ movementSystem.TeleportToPosRot(preSwitchWorldPosition, preSwitchWorldRotation, false);
+ //recenter desktop collision to player object
+ if (!enterVR) movementSystem.UpdateColliderCenter(movementSystem.transform.position);
+ }
+}
\ No newline at end of file
diff --git a/DesktopVRSwitch/Patches/ReferenceCameraPatch.cs b/DesktopVRSwitch/Patches/ReferenceCameraPatch.cs
new file mode 100644
index 0000000..9681873
--- /dev/null
+++ b/DesktopVRSwitch/Patches/ReferenceCameraPatch.cs
@@ -0,0 +1,91 @@
+using ABI_RC.Core.Base;
+using ABI_RC.Core.Player;
+using ABI_RC.Core.Savior;
+using Aura2API;
+using BeautifyEffect;
+using UnityEngine;
+using UnityEngine.AzureSky;
+using UnityEngine.Rendering.PostProcessing;
+using Object = UnityEngine.Object;
+
+namespace NAK.Melons.DesktopVRSwitch.Patches;
+
+internal class ReferenceCameraPatch
+{
+ internal static void OnWorldLoad()
+ {
+ Camera activeCamera = (MetaPort.Instance.isUsingVr ? PlayerSetup.Instance.vrCamera : PlayerSetup.Instance.desktopCamera).GetComponent();
+ Camera inactiveCamera = (MetaPort.Instance.isUsingVr ? PlayerSetup.Instance.desktopCamera : PlayerSetup.Instance.vrCamera).GetComponent();
+ CopyToInactiveCam(activeCamera, inactiveCamera);
+ }
+
+ internal static void CopyToInactiveCam(Camera activeCam, Camera inactiveCam)
+ {
+ DesktopVRSwitchMod.Logger.Msg("Copying active camera settings & components to inactive camera.");
+
+ //steal basic settings
+ inactiveCam.farClipPlane = activeCam.farClipPlane;
+ inactiveCam.nearClipPlane = activeCam.nearClipPlane;
+ inactiveCam.cullingMask = activeCam.cullingMask;
+ inactiveCam.depthTextureMode = activeCam.depthTextureMode;
+
+ //steal post processing if added
+ PostProcessLayer ppLayerActiveCam = activeCam.GetComponent();
+ PostProcessLayer ppLayerInactiveCam = inactiveCam.AddComponentIfMissing();
+ if (ppLayerActiveCam != null && ppLayerInactiveCam != null)
+ {
+ ppLayerInactiveCam.enabled = ppLayerActiveCam.enabled;
+ ppLayerInactiveCam.volumeLayer = ppLayerActiveCam.volumeLayer;
+ }
+
+ //what even is this aura camera stuff
+ AuraCamera auraActiveCam = activeCam.GetComponent();
+ AuraCamera auraInactiveCam = inactiveCam.AddComponentIfMissing();
+ if (auraActiveCam != null && auraInactiveCam != null)
+ {
+ auraInactiveCam.enabled = auraActiveCam.enabled;
+ auraInactiveCam.frustumSettings = auraActiveCam.frustumSettings;
+ }
+ else
+ {
+ auraInactiveCam.enabled = false;
+ }
+
+ //flare layer thing? the sun :_:_:_:_:_:
+ FlareLayer flareActiveCam = activeCam.GetComponent();
+ FlareLayer flareInactiveCam = inactiveCam.AddComponentIfMissing();
+ if (flareActiveCam != null && flareInactiveCam != null)
+ {
+ flareInactiveCam.enabled = flareActiveCam.enabled;
+ }
+ else
+ {
+ flareInactiveCam.enabled = false;
+ }
+
+ //and now what the fuck is fog scattering
+ AzureFogScattering azureFogActiveCam = activeCam.GetComponent();
+ AzureFogScattering azureFogInactiveCam = inactiveCam.AddComponentIfMissing();
+ if (azureFogActiveCam != null && azureFogInactiveCam != null)
+ {
+ azureFogInactiveCam.fogScatteringMaterial = azureFogActiveCam.fogScatteringMaterial;
+ }
+ else
+ {
+ Object.Destroy(inactiveCam.GetComponent());
+ }
+
+ //why is there so many thingsssssssss
+ Beautify beautifyActiveCam = activeCam.GetComponent();
+ Beautify beautifyInactiveCam = inactiveCam.AddComponentIfMissing();
+ if (beautifyActiveCam != null && beautifyInactiveCam != null)
+ {
+ beautifyInactiveCam.quality = beautifyActiveCam.quality;
+ beautifyInactiveCam.profile = beautifyActiveCam.profile;
+ }
+ else
+ {
+ Object.Destroy(inactiveCam.gameObject.GetComponent());
+ }
+ }
+}
\ No newline at end of file
diff --git a/DesktopVRSwitch/Patches/VRModeSwitchTracker.cs b/DesktopVRSwitch/Patches/VRModeSwitchTracker.cs
new file mode 100644
index 0000000..d6f20c3
--- /dev/null
+++ b/DesktopVRSwitch/Patches/VRModeSwitchTracker.cs
@@ -0,0 +1,33 @@
+using ABI_RC.Core.Player;
+using UnityEngine;
+using UnityEngine.Events;
+
+namespace NAK.Melons.DesktopVRSwitch.Patches;
+
+public class VRModeSwitchTracker
+{
+ public static event UnityAction OnPreVRModeSwitch;
+ public static event UnityAction OnPostVRModeSwitch;
+
+ public static void PreVRModeSwitch(bool enterVR)
+ {
+ TryCatchHell.TryCatchWrapper(() =>
+ {
+ DesktopVRSwitchMod.Logger.Msg("Invoking VRModeSwitchTracker.OnPreVRModeSwitch.");
+ Camera activeCamera = PlayerSetup.Instance.GetActiveCamera().GetComponent();
+ VRModeSwitchTracker.OnPreVRModeSwitch?.Invoke(enterVR, activeCamera);
+ },
+ "Error while invoking VRModeSwitchTracker.OnPreVRModeSwitch. Did someone do a fucky?");
+ }
+
+ public static void PostVRModeSwitch(bool enterVR)
+ {
+ TryCatchHell.TryCatchWrapper(() =>
+ {
+ DesktopVRSwitchMod.Logger.Msg("Invoking VRModeSwitchTracker.OnPostVRModeSwitch.");
+ Camera activeCamera = PlayerSetup.Instance.GetActiveCamera().GetComponent();
+ VRModeSwitchTracker.OnPostVRModeSwitch?.Invoke(enterVR, activeCamera);
+ },
+ "Error while invoking VRModeSwitchTracker.OnPostVRModeSwitch. Did someone do a fucky?");
+ }
+}
\ No newline at end of file
diff --git a/DesktopVRSwitch/Properties/AssemblyInfo.cs b/DesktopVRSwitch/Properties/AssemblyInfo.cs
index 743b703..35df6ca 100644
--- a/DesktopVRSwitch/Properties/AssemblyInfo.cs
+++ b/DesktopVRSwitch/Properties/AssemblyInfo.cs
@@ -1,18 +1,17 @@
-using DesktopVRSwitch.Properties;
-using MelonLoader;
+using MelonLoader;
+using NAK.Melons.DesktopVRSwitch.Properties;
using System.Reflection;
-
[assembly: AssemblyVersion(AssemblyInfoParams.Version)]
[assembly: AssemblyFileVersion(AssemblyInfoParams.Version)]
[assembly: AssemblyInformationalVersion(AssemblyInfoParams.Version)]
-[assembly: AssemblyTitle(nameof(DesktopVRSwitch))]
+[assembly: AssemblyTitle(nameof(NAK.Melons.DesktopVRSwitch))]
[assembly: AssemblyCompany(AssemblyInfoParams.Author)]
-[assembly: AssemblyProduct(nameof(DesktopVRSwitch))]
+[assembly: AssemblyProduct(nameof(NAK.Melons.DesktopVRSwitch))]
[assembly: MelonInfo(
- typeof(DesktopVRSwitch.DesktopVRSwitch),
- nameof(DesktopVRSwitch),
+ typeof(NAK.Melons.DesktopVRSwitch.DesktopVRSwitchMod),
+ nameof(NAK.Melons.DesktopVRSwitch),
AssemblyInfoParams.Version,
AssemblyInfoParams.Author,
downloadLink: "https://github.com/NotAKidOnSteam/DesktopVRSwitch"
@@ -21,10 +20,11 @@ using System.Reflection;
[assembly: MelonGame("Alpha Blend Interactive", "ChilloutVR")]
[assembly: MelonPlatform(MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
[assembly: MelonPlatformDomain(MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
+[assembly: HarmonyDontPatchAll]
-namespace DesktopVRSwitch.Properties;
+namespace NAK.Melons.DesktopVRSwitch.Properties;
internal static class AssemblyInfoParams
{
- public const string Version = "3.0.5";
+ public const string Version = "4.2.4";
public const string Author = "NotAKidoS";
}
\ No newline at end of file
diff --git a/DesktopVRSwitch/TryCatchHell.cs b/DesktopVRSwitch/TryCatchHell.cs
new file mode 100644
index 0000000..ad3313b
--- /dev/null
+++ b/DesktopVRSwitch/TryCatchHell.cs
@@ -0,0 +1,167 @@
+using ABI_RC.Core;
+using ABI_RC.Core.EventSystem;
+using ABI_RC.Core.InteractionSystem;
+using ABI_RC.Core.Player;
+using ABI_RC.Core.Savior;
+using ABI_RC.Core.UI;
+using ABI_RC.Systems.Camera;
+using HarmonyLib;
+using UnityEngine;
+
+namespace NAK.Melons.DesktopVRSwitch;
+
+internal class TryCatchHell
+{
+ internal static void TryCatchWrapper(Action action, string errorMsg, params object[] msgArgs)
+ {
+ try
+ {
+ action();
+ }
+ catch (Exception ex)
+ {
+ DesktopVRSwitchMod.Logger.Error(string.Format(errorMsg, msgArgs));
+ DesktopVRSwitchMod.Logger.Msg(ex.Message);
+ }
+ }
+
+ internal static void SetCheckVR(bool isVR)
+ {
+ TryCatchWrapper(() =>
+ {
+ DesktopVRSwitchMod.Logger.Msg($"Setting CheckVR hasVrDeviceLoaded to {isVR}.");
+ CheckVR.Instance.hasVrDeviceLoaded = isVR;
+ },
+ "Setting CheckVR hasVrDeviceLoaded failed.");
+ }
+
+ internal static void SetMetaPort(bool isVR)
+ {
+ TryCatchWrapper(() =>
+ {
+ DesktopVRSwitchMod.Logger.Msg($"Setting MetaPort isUsingVr to {isVR}.");
+ MetaPort.Instance.isUsingVr = isVR;
+ },
+ "Setting MetaPort isUsingVr failed.");
+ }
+
+ internal static void RepositionCohtmlHud(bool isVR)
+ {
+ TryCatchWrapper(() =>
+ {
+ DesktopVRSwitchMod.Logger.Msg("Configuring new hud affinity for CohtmlHud.");
+ CohtmlHud.Instance.gameObject.transform.parent = isVR ? PlayerSetup.Instance.vrCamera.transform : PlayerSetup.Instance.desktopCamera.transform;
+ CVRTools.ConfigureHudAffinity();
+ CohtmlHud.Instance.gameObject.transform.localScale = new Vector3(1.2f, 1f, 1.2f);
+ },
+ "Error parenting CohtmlHud to active camera.");
+ }
+
+ internal static void UpdateHudOperations(bool isVR)
+ {
+ TryCatchWrapper(() =>
+ {
+ DesktopVRSwitchMod.Logger.Msg("Switching HudOperations worldLoadingItem & worldLoadStatus.");
+ HudOperations.Instance.worldLoadingItem = isVR ? HudOperations.Instance.worldLoadingItemVr : HudOperations.Instance.worldLoadingItemDesktop;
+ HudOperations.Instance.worldLoadStatus = isVR ? HudOperations.Instance.worldLoadStatusVr : HudOperations.Instance.worldLoadStatusDesktop;
+ },
+ "Failed switching HudOperations objects.");
+ }
+
+ internal static void DisableMirrorCanvas()
+ {
+ TryCatchWrapper(() =>
+ {
+ DesktopVRSwitchMod.Logger.Msg("Forcing PortableCamera canvas mirroring off.");
+ //tell the game we are in mirror mode so itll disable it (if enabled)
+ PortableCamera.Instance.mode = MirroringMode.Mirror;
+ PortableCamera.Instance.ChangeMirroring();
+ },
+ "Failed to disable PortableCamera canvas mirroring.");
+ }
+
+ internal static void SwitchActiveCameraRigs(bool isVR)
+ {
+ TryCatchWrapper(() =>
+ {
+ DesktopVRSwitchMod.Logger.Msg("Switching active PlayerSetup camera rigs. Updating Desktop camera FOV.");
+ PlayerSetup.Instance.desktopCameraRig.SetActive(!isVR);
+ PlayerSetup.Instance.vrCameraRig.SetActive(isVR);
+ CVR_DesktopCameraController.UpdateFov();
+ //uicamera has script that copies fov from desktop cam
+ //toggling the cameras on/off resets aspect ratio
+ //so when rigs switch, that is already handled
+ },
+ "Failed to switch active camera rigs or update Desktop camera FOV.");
+ }
+
+ internal static void PauseInputInteractions(bool toggle)
+ {
+ TryCatchWrapper(() =>
+ {
+ DesktopVRSwitchMod.Logger.Msg($"Setting CVRInputManager inputEnabled & CVR_InteractableManager enableInteractions to {!toggle}");
+ CVRInputManager.Instance.inputEnabled = !toggle;
+ CVR_InteractableManager.enableInteractions = !toggle;
+ },
+ "Failed to toggle CVRInputManager inputEnabled & CVR_InteractableManager enableInteractions.");
+ }
+
+ internal static void ResetCVRInputManager()
+ {
+ TryCatchWrapper(() =>
+ {
+ DesktopVRSwitchMod.Logger.Msg("Resetting CVRInputManager inputs.");
+ //just in case
+ CVRInputManager.Instance.blockedByUi = false;
+ //sometimes head can get stuck, so just in case
+ CVRInputManager.Instance.independentHeadToggle = false;
+ //just nice to load into desktop with idle gesture
+ CVRInputManager.Instance.gestureLeft = 0f;
+ CVRInputManager.Instance.gestureLeftRaw = 0f;
+ CVRInputManager.Instance.gestureRight = 0f;
+ CVRInputManager.Instance.gestureRightRaw = 0f;
+ },
+ "Failed to reset CVRInputManager inputs.");
+ }
+
+ internal static void ReloadLocalAvatar()
+ {
+ TryCatchWrapper(() =>
+ {
+ DesktopVRSwitchMod.Logger.Msg("Attempting to reload current local avatar from GUID.");
+ AssetManagement.Instance.LoadLocalAvatar(MetaPort.Instance.currentAvatarGuid);
+ },
+ "Failed to reload local avatar.");
+ }
+
+ internal static void UpdateRichPresence()
+ {
+ TryCatchWrapper(() =>
+ {
+ if (MetaPort.Instance.settings.GetSettingsBool("ImplementationRichPresenceDiscordEnabled", true))
+ {
+ DesktopVRSwitchMod.Logger.Msg("Forcing Discord Rich Presence update.");
+ MetaPort.Instance.settings.SetSettingsBool("ImplementationRichPresenceDiscordEnabled", false);
+ MetaPort.Instance.settings.SetSettingsBool("ImplementationRichPresenceDiscordEnabled", true);
+ }
+ if (MetaPort.Instance.settings.GetSettingsBool("ImplementationRichPresenceSteamEnabled", true))
+ {
+ DesktopVRSwitchMod.Logger.Msg("Forcing Steam Rich Presence update.");
+ MetaPort.Instance.settings.SetSettingsBool("ImplementationRichPresenceSteamEnabled", false);
+ MetaPort.Instance.settings.SetSettingsBool("ImplementationRichPresenceSteamEnabled", true);
+ }
+ },
+ "Failed to update Discord & Steam Rich Presence.");
+ }
+
+ internal static void UpdateGestureReconizerCam()
+ {
+ TryCatchWrapper(() =>
+ {
+ DesktopVRSwitchMod.Logger.Msg("Updating CVRGestureRecognizer _camera to active camera.");
+ Traverse.Create(CVRGestureRecognizer.Instance).Field("_camera").SetValue(PlayerSetup.Instance.GetActiveCamera().GetComponent());
+ },
+ "Failed to update CVRGestureRecognizer camera.");
+ }
+}
+
diff --git a/DesktopVRSwitch/UIExpansionKitAddon.cs b/DesktopVRSwitch/UIExpansionKitAddon.cs
deleted file mode 100644
index de9e9d7..0000000
--- a/DesktopVRSwitch/UIExpansionKitAddon.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using System.Runtime.CompilerServices;
-using UIExpansionKit.API;
-
-namespace DesktopVRSwitch;
-public static class UiExtensionsAddon
-{
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static void Init()
- {
- var settings = ExpansionKitApi.GetSettingsCategory(DesktopVRSwitch.SettingsCategory);
- settings.AddSimpleButton("Switch VRMode", SwitchModeButton);
- }
- internal static void SwitchModeButton() => DesktopVRSwitchHelper.Instance.SwitchMode(true);
-}
\ No newline at end of file