using System; using System.Collections; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text; using UnityEngine; namespace Omni { public enum SecureAuthenticationProtocolState { SAPEnabled, SAPDisabled, SAPError }; public class OmniConnectionComponent : MonoBehaviour { public delegate IntPtr WndProcDelegate(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam); private OmniManager omniManager; private OmniDataComponent omniDataComponent; private SecureAuthenticationProtocolState mySAPStatus = SecureAuthenticationProtocolState.SAPError; private int SAPErrorChecks = 0; //Has the Omni been found [HideInInspector] public bool omniFound = false; public void Connect(OmniDataComponent dataComponent) { omniDataComponent = dataComponent; Start_TryingtoReconnect(); } #region reconnecting logic IntPtr hMainWindow; IntPtr oldWndProcPtr; IntPtr newWndProcPtr; WndProcDelegate newWndProc; bool isrunning = false; [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] public static extern System.IntPtr GetForegroundWindow(); [DllImport("user32.dll")] static extern IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong); [DllImport("user32.dll")] static extern IntPtr CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); IntPtr wndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam) { if (msg == 0x0219) { //Debug.LogError("Event Triggered; " + wParam.ToInt32());// + "; " + lParam.ToInt32()); switch (wParam.ToInt32()) { case 0x8000: // DBT_DEVICEARRIVAL //case 0x8004: // DBT_DEVICEREMOVECOMPLETE //case 0x0007: // DBT_DEVNODES_CHANGED: AttemptToReconnectTheOmni(); break; } } return CallWindowProc(oldWndProcPtr, hWnd, msg, wParam, lParam); } #endregion void AttemptToReconnectTheOmni() { if (omniManager == null) omniManager = new OmniManager(); if (!omniManager.omniDisconnected) return; if (omniManager.FindOmni()) { Debug.Log(System.DateTime.Now.ToLongTimeString() + ": OmniConnectionComponent(AttemptToReconnectTheOmni) - Successfully found the Omni for reconnect."); omniFound = true; } else { Debug.LogError(System.DateTime.Now.ToLongTimeString() + ": OmniConnectionComponent(AttemptToReconnectTheOmni) - Attempted to Reconnect the Omni, but Omni not found."); omniFound = false; return; } } void Start_TryingtoReconnect() { if (isrunning) return; hMainWindow = GetForegroundWindow(); newWndProc = new WndProcDelegate(wndProc); newWndProcPtr = Marshal.GetFunctionPointerForDelegate(newWndProc); oldWndProcPtr = SetWindowLongPtr(hMainWindow, -4, newWndProcPtr); isrunning = true; } public void StopReconnectAttempts() { // Disable the reconnect attempting Debug.Log(System.DateTime.Now.ToLongTimeString() + ": OmniConnectionComponent(OnDisable) - Uninstall Hook"); if (!isrunning) return; SetWindowLongPtr(hMainWindow, -4, oldWndProcPtr); hMainWindow = IntPtr.Zero; oldWndProcPtr = IntPtr.Zero; newWndProcPtr = IntPtr.Zero; newWndProc = null; isrunning = false; } public IEnumerator ConfigureOmniConnect() { yield return new WaitForSeconds(3f); StartCoroutine(SetGameMode()); SAPErrorChecks = 0; mySAPStatus = SecureAuthenticationProtocolState.SAPError; StartCoroutine(VerifySAP()); yield return new WaitForSeconds(10f); string systemReadyCheckUrl = "http://localhost:8085/systemReady"; string systemReadyWebResponse = "-1"; yield return StartCoroutine(OmniConnectWebRequest.CoroutineGetRequest(systemReadyCheckUrl, value => systemReadyWebResponse = value)); if (systemReadyWebResponse.Contains("OK;Secure;MotionDisabled")) { Debug.LogError("Authentication Protocol Failed. Your Omni is not registered and therefore cannot be enabled. Please contact your Omni provider to register your Omni."); } } private IEnumerator VerifySAP() { SecureAuthenticationProtocolState SAPGetResponse = SecureAuthenticationProtocolState.SAPError; yield return StartCoroutine(GetSecureAuthentication(value => SAPGetResponse = value)); mySAPStatus = SAPGetResponse; if (mySAPStatus == SecureAuthenticationProtocolState.SAPEnabled) { Debug.Log("SAP Enabled. Initializing SDK."); /* For Initialization to work, you must create a developer account, and register your game with Virtuix by * emailing your Omni provider. Please provide the serial number for any Omnis that you wish to use for development.*/ OVSDK.Init(1000, "01ec17dac7140c0fbe936ee128310000", "omni=1"); omniDataComponent.ResetHasSetCouplingPercentage(); } else if (mySAPStatus == SecureAuthenticationProtocolState.SAPDisabled) { Debug.Log("SAP Disabled."); omniDataComponent.ResetHasSetCouplingPercentage(); } else { if (SAPErrorChecks < 3) { SAPErrorChecks++; yield return new WaitForSeconds(2f); StartCoroutine(VerifySAP()); } else { Debug.LogError("There is an error with your configuration in Omni Connect. Ensure that Omni Connect is installed and running on your system. " + "Verify that it is updated to the latest version and that the PODs are connected and on."); } } } private IEnumerator SetGameMode() { //Check the Game Mode to see if it is already set to "Gamepad" string coroutineUrl = "http://localhost:8085/gamemode"; string GameModeGetResponse = "-1"; yield return StartCoroutine(OmniConnectWebRequest.CoroutineGetRequest(coroutineUrl, value => GameModeGetResponse = value)); //Set Game mode to "Gamepad" if it is not already. if (!GameModeGetResponse.Contains("Gamepad") && GameModeGetResponse != "Error") { OmniConnectMode omniConnectMode = new OmniConnectMode { Data = "Gamepad" }; string json = JsonUtility.ToJson(omniConnectMode); byte[] pData = Encoding.ASCII.GetBytes(json.ToCharArray()); string webPostResponse = "-1"; yield return StartCoroutine(OmniConnectWebRequest.CoroutinePostRequest(coroutineUrl, pData, value => webPostResponse = value)); } } public SecureAuthenticationProtocolState GetSAPStatus() { return mySAPStatus; } /// /// Gets the Authentication depending on version needed. /// /// /// private IEnumerator GetSecureAuthentication(Action result) { string versionCheckUrl = "http://localhost:8085/version"; string versionWebResponse = "-1"; yield return StartCoroutine(OmniConnectWebRequest.CoroutineGetRequest(versionCheckUrl, value => versionWebResponse = value)); string v1 = versionWebResponse[23].ToString() + versionWebResponse[24].ToString() + versionWebResponse[25].ToString() + versionWebResponse[26].ToString() + versionWebResponse[27].ToString() + versionWebResponse[28].ToString() + versionWebResponse[29].ToString(); string v2 = "1.3.4.0"; var version1 = new Version(v1); var version2 = new Version(v2); int versionComparisonResult = version1.CompareTo(version2); if (versionComparisonResult >= 0) { //If 1.3.4.0 or newer, use the new healthcheck endpoint. string healthCheckUrl = "http://localhost:8085/healthcheck"; string SACWebResponse = "-1"; yield return StartCoroutine(OmniConnectWebRequest.CoroutineGetRequest(healthCheckUrl, value => SACWebResponse = value)); if (SACWebResponse != "Error") { switch (SACWebResponse[10]) { case 'B': Debug.Log("Secure Authentication Protocol Enabled"); result(SecureAuthenticationProtocolState.SAPEnabled); break; case 'U': Debug.Log("Secure Authentication Protocol Disabled"); result(SecureAuthenticationProtocolState.SAPDisabled); break; case '-': Debug.Log("Omni Not Connected: Please Connect Omni"); result(SecureAuthenticationProtocolState.SAPError); break; default: Debug.Log("Secure Authentication Protocol check failed. Returned Default."); result(SecureAuthenticationProtocolState.SAPError); break; } } } else if (versionComparisonResult < 0) { //If older than 1.3.4.0, use the old methods. string systemReadyCheckUrl = "http://localhost:8085/systemReady"; string systemReadyWebResponse = "-1"; yield return StartCoroutine(OmniConnectWebRequest.CoroutineGetRequest(systemReadyCheckUrl, value => systemReadyWebResponse = value)); if (systemReadyWebResponse.Contains("OK;Unsecure")) { result(SecureAuthenticationProtocolState.SAPDisabled); } else if (systemReadyWebResponse.Contains("OK;Secure")) { result(SecureAuthenticationProtocolState.SAPEnabled); } else { result(SecureAuthenticationProtocolState.SAPError); } } } } }