projet-massimo-pfe/PFE OmniVR/Assets/Scripts/Omni/Utils/OmniConnectionComponent.cs
jimmy tremblay-Bernier c1bf5a4ca1 initial commit
2022-03-12 22:04:30 -04:00

260 lines
11 KiB
C#

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;
}
/// <summary>
/// Gets the Authentication depending on version needed.
/// </summary>
/// <param name="result"></param>
/// <returns></returns>
private IEnumerator GetSecureAuthentication(Action<SecureAuthenticationProtocolState> 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);
}
}
}
}
}