Documentation for the Unity C# Library
Loading...
Searching...
No Matches
ApexSystem.cs
Go to the documentation of this file.
1using Newtonsoft.Json;
5using System;
6using System.Collections.Generic;
7using System.Net.Http;
8using System.Text.RegularExpressions;
9using System.Threading.Tasks;
10using TinCan;
11using UnityEditor;
12using UnityEngine;
13using UnityEngine.XR;
14using static UnityEngine.Audio.ProcessorInstance;
15
16#if MANAGE_XR
17using MXR.SDK;
18#endif
19
20namespace PixoVR.Apex
21{
22 public delegate void PlatformResponse(ResponseType type, bool wasSuccessful, object responseData);
23
24 [DefaultExecutionOrder(-50)]
25 public class ApexSystem : ApexSingleton<ApexSystem>
26 {
27 private static readonly string TAG = "ApexSystem";
28 private enum VersionParts : int
29 {
30 Major = 0,
31 Minor,
32 Patch,
33 }
34
35 public static string ServerIP
36 {
37 get { return Instance.serverIP; }
38 set { }
39 }
40
41 public static int ModuleID
42 {
43 get { return Instance.moduleID; }
44 set { Instance.moduleID = value; }
45 }
46
47 public static string ModuleName
48 {
49 get { return Instance.moduleName; }
50 set { Instance.moduleName = value; }
51 }
52
53 public static string ModuleVersion
54 {
55 get { return Instance.moduleVersion; }
56 set { Instance.moduleVersion = value; }
57 }
58
59 public static string ScenarioID
60 {
61 get { return Instance.scenarioID; }
62 set { Instance.scenarioID = value; }
63 }
64
66 {
67 get { return Instance.currentActiveLogin; }
68 set { }
69 }
70
71 public static bool RunSetupOnAwake
72 {
73 get { return Instance.runSetupOnAwake; }
74 set { Instance.runSetupOnAwake = value; }
75 }
76
77 public static bool LoginCheckModuleAccess
78 {
79 get { return Instance.loginCheckModuleAccess; }
80 set { }
81 }
82
83 public static string DeviceSerialNumber
84 {
85 get { return Instance.deviceSerialNumber; }
86 set { }
87 }
88
89 public static string PassedLoginToken
90 {
91 get
92 {
93 Debug.unityLogger.Log(LogType.Log, TAG, $"Getting passed login token as {Instance.loginToken} in instance {Instance.gameObject.name}");
94 return Instance.loginToken;
95 }
96
97 protected set
98 {
99 Debug.unityLogger.Log(LogType.Error, TAG, $"Setting passed login token to {value}");
100 Instance.loginToken = value;
101 }
102 }
103
104 public static string OptionalData
105 {
106 get { return Instance.optionalParameter; }
107 set { Instance.optionalParameter = value; }
108 }
109
110 public static string CurrentExitTarget
111 {
112 get { return Instance.currentExitTargetParameter; }
113 set
114 {
115 if (value != null)
116 {
117 Instance.currentExitTargetParameter = value;
118 }
119 else
120 {
121 Instance.currentExitTargetParameter = "";
122 }
123
124 if (Instance.currentExitTargetParameter.Contains("://"))
125 {
126 TargetType = "url";
127 }
128 else
129 {
130 TargetType = "app";
131 }
132 }
133 }
134
135 public static string TargetType
136 {
137 get { return Instance.targetTypeParameter; }
138 private set { Instance.targetTypeParameter = value; }
139 }
140
141 public static string APIEndpoint
142 {
143 get { return ((APIPlatformServer)Instance.PlatformTargetServer).ToUrlString(); }
144 }
145
147 {
148 get { return Instance.apexAPIHandler; }
149 }
150
151 [SerializeField, EndpointDisplay]
153
154 [SerializeField]
155 protected string serverIP = "";
156
157 [SerializeField]
158 protected int moduleID = 0;
159
160 [SerializeField]
161 protected string moduleName = "Generic";
162
163 [SerializeField]
164 protected string moduleVersion = "";
165
166 [SerializeField]
167 protected string scenarioID = "Generic";
168
169 [SerializeField]
170 public bool runSetupOnAwake = true;
171
172 [SerializeField]
173 public bool loginCheckModuleAccess = true;
174
175 [SerializeField]
176 protected float heartbeatTime = 5.0f;
177
178 protected string webSocketUrl;
179 protected string deviceID;
180 protected string deviceModel;
181 protected string platform;
182 protected string clientIP;
183 protected Guid currentSessionID;
184 protected int heartbeatSessionID;
185 protected float heartbeatTimer;
186 protected bool sessionInProgress;
187 protected bool userAccessVerified = false;
188 protected string deviceSerialNumber = "";
189 protected bool hasParsedArguments = false;
190
191 protected string loginToken = "";
192 protected string optionalParameter = "";
193 protected string currentExitTargetParameter = "";
194 protected string targetTypeParameter = "";
195
198 protected ApexWebsocket webSocket;
199 protected Task<bool> socketConnectTask;
200 protected Task socketDisconnectTask;
201
204
207
210
213
216
217 public PlatformResponse OnPlatformResponse = null;
218
220
223
230 void Awake()
232 Debug.unityLogger.Log(LogType.Log, TAG, $"ApexSystem found on {gameObject.name}");
235 Debug.unityLogger.Log(LogType.Log, TAG, "Instance already initialized.");
238 var projectSettings = Resources.Load<Editor.PixoVRProjectSettings>("PixoVRProjectSettings");
239 if (projectSettings != null)
241 if (string.IsNullOrEmpty(moduleVersion))
243 moduleVersion = projectSettings.ModuleVersion;
249#if UNITY_IOS || UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX
251#endif
252 if (runSetupOnAwake)
254 Debug.unityLogger.Log(LogType.Log, TAG, "Running on awake!");
255 SetupAPI();
258 DontDestroyOnLoad(gameObject);
259#if MANAGE_XR && !UNITY_EDITOR
260 Debug.unityLogger.Log(LogType.Log, TAG, "Using ManageXR");
261 InitMXRSDK();
262#endif
264
265#if MANAGE_XR
266 async void InitMXRSDK()
268 Debug.unityLogger.Log(LogType.Log, TAG, "Initializing the ManageXR SDK");
269 await MXRManager.InitAsync();
270 MXRManager.System.OnDeviceStatusChange += OnDeviceStatusChanged;
271 deviceSerialNumber = MXRManager.System.DeviceStatus.serial;
272 Debug.unityLogger.Log(LogType.Log, TAG, $"Device serial set to {deviceSerialNumber}");
274
275 void OnDeviceStatusChanged(DeviceStatus newDeviceStatus)
277 deviceSerialNumber = newDeviceStatus.serial;
278 Debug.unityLogger.Log(LogType.Log, TAG, $"Device serial number changed to {deviceSerialNumber}");
279 }
280#endif
281
282 void SetupDeepLinking()
283 {
284 Application.deepLinkActivated += OnDeepLinkActivated;
285 if (!string.IsNullOrEmpty(Application.absoluteURL))
286 {
287 // Cold start and Application.absoluteURL not null so process Deep Link.
288 OnDeepLinkActivated(Application.absoluteURL);
289 }
290 }
291
292 void OnDeepLinkActivated(string url)
293 {
294 // Update DeepLink Manager global variable, so URL can be accessed from anywhere.
295 var urlArguments = PixoPlatformUtilities.ParseURLArguments(url);
296 _ParsePassedData(urlArguments);
297 }
298
300 {
301 Debug.unityLogger.Log(LogType.Log, TAG, "SetupPlatformConfiguration");
302
303#if UNITY_ANDROID
305 {
306 Debug.unityLogger.Log(LogType.Log, TAG, "Found pixoconfig.cnf");
307
308 string configContent = PixoAndroidUtils.ReadFileFromSharedStorage("pixoconfig.cnf");
309
310 if (configContent.Length > 0)
311 {
312 Debug.unityLogger.Log(LogType.Log, TAG, "Configuration is not empty.");
313 ConfigurationTypes configData = JsonConvert.DeserializeObject<ConfigurationTypes>(configContent);
314 if (configData == null)
315 {
316 Debug.unityLogger.Log(LogType.Log, TAG, "Failed to deserialize the config.");
317 return;
318 }
319
320 // Parse out the platform target to utilize the unity built in config values
321 if (configData.Platform.Contains("NA", StringComparison.CurrentCultureIgnoreCase))
322 {
323 if (configData.Platform.Contains("Production", StringComparison.CurrentCultureIgnoreCase))
324 {
325 Debug.unityLogger.Log(LogType.Log, TAG, "NA Production platform target.");
326 PlatformTargetServer = PlatformServer.NA_PRODUCTION;
327 }
328
329 if (configData.Platform.Contains("Dev", StringComparison.CurrentCultureIgnoreCase))
331 Debug.unityLogger.Log(LogType.Log, TAG, "NA Dev platform target.");
333 }
334
335 if (configData.Platform.Contains("Stage", StringComparison.CurrentCultureIgnoreCase))
336 {
337 Debug.unityLogger.Log(LogType.Log, TAG, "NA Stage platform target.");
339 }
341 else if (configData.Platform.Contains("SA", StringComparison.CurrentCultureIgnoreCase))
342 {
343 Debug.unityLogger.Log(LogType.Log, TAG, "SA Production platform target.");
344 PlatformTargetServer = PlatformServer.SA_PRODUCTION;
345 }
346
347 // TODO (MGruber): Add a custom value, but this requires multiple configuration values to be saved.
348 // Need to save the normal headset api endpoint, web api endpoint and platform api endpoint. 3 VALUES! D:
349 }
350 }
351#endif
352 }
353
354 void SetupAPI()
355 {
356 Debug.unityLogger.Log(LogType.Log, TAG, "Mac Address: " + ApexUtils.GetMacAddress());
357 if (serverIP.Length == 0)
358 {
360 }
361
363
364 if (apexAPIHandler != null)
365 {
366 Debug.unityLogger.Log(LogType.Log, TAG, "Apex API Handler is not null!");
367 }
368
369 // TODO: Move to new plugin
371 apexAPIHandler.OnAPIResponse += OnAPIResponse;
372
373 if (webSocket != null)
374 {
376 {
378 }
379 }
380
381 webSocket = new ApexWebsocket();
383 webSocket.OnConnectFailed.AddListener((reason) => OnWebSocketConnectFailed(reason));
384 webSocket.OnReceive.AddListener((data) => OnWebSocketReceive(data));
385 webSocket.OnClosed.AddListener((reason) => OnWebSocketClosed(reason));
386
388
390 {
391 var applicationArugments = PixoPlatformUtilities.ParseApplicationArguments();
392 _ParsePassedData(applicationArugments);
393 Debug.unityLogger.Log(LogType.Log, TAG, $"Login Token: {(string.IsNullOrEmpty(PassedLoginToken) ? "<Null>" : PassedLoginToken)}");
394 hasParsedArguments = true;
395 }
396 }
397
398 void _ExitApplication(string nextExitApplication)
399 {
400 Debug.unityLogger.Log(LogType.Log, TAG, "ApexSystem::_ExitApplication");
401 if (nextExitApplication == null)
403 nextExitApplication = "";
404 }
405
406 string returnTargetType = "app";
407
408 if (nextExitApplication.Contains("://"))
409 {
410 returnTargetType = "url";
411 }
412
413 Debug.unityLogger.Log(LogType.Log, TAG, "" + nextExitApplication + " " + returnTargetType);
414
415 string parameters = "";
416
417 Debug.unityLogger.Log(LogType.Log, TAG, "Building parameters for url.");
418
419 if (CurrentActiveLogin != null)
420 {
421 parameters += "pixotoken=" + CurrentActiveLogin.Token;
422 }
423 else if (!string.IsNullOrEmpty(PassedLoginToken))
424 {
425 parameters += "pixotoken=" + PassedLoginToken;
426 }
427
428 if (optionalParameter != null)
429 {
430 if (optionalParameter.Length > 0)
431 {
432 if (parameters.Length > 0)
433 parameters += "&";
434 parameters += "optional=" + optionalParameter;
435 }
436 }
437
438 if (nextExitApplication.Length > 0)
439 {
440 if (parameters.Length > 0)
441 parameters += "&";
442 parameters += "returntarget=" + nextExitApplication;
443 }
444
445 if (returnTargetType.Length > 0)
447 if (parameters.Length > 0)
448 parameters += "&";
449 parameters += "targettype=" + returnTargetType;
450 }
451
452 Debug.unityLogger.Log(LogType.Log, TAG, "Checking the return target parameter.");
453
454 if (!string.IsNullOrEmpty(CurrentExitTarget))
455 {
456 Debug.unityLogger.Log(LogType.Log, TAG, "Had a valid return target parameter.");
457 if (targetTypeParameter.Equals("url", StringComparison.OrdinalIgnoreCase))
458 {
459 Debug.unityLogger.Log(LogType.Log, TAG, "Return Target is a URL.");
460
461 string returnURL = CurrentExitTarget;
462 if (!string.IsNullOrEmpty(parameters))
463 {
464 if (!returnURL.Contains('?'))
465 returnURL += "?";
466 else
467 returnURL += "&";
468
469 returnURL += parameters;
470 }
471 Debug.unityLogger.Log(LogType.Log, TAG, "Custom Target: " + returnURL);
474 return;
475 }
476 else
477 {
478 Debug.unityLogger.Log(LogType.Log, TAG, $"Return Target is a package name. {CurrentExitTarget}");
479
480 List<string> keys = new List<string>(),
481 values = new List<string>();
482
483 Debug.unityLogger.Log(LogType.Log, TAG, "Adding pixo token.");
484
485 if (CurrentActiveLogin != null)
486 {
487 keys.Add("pixotoken");
488 values.Add(CurrentActiveLogin.Token);
489 }
490 else if (!string.IsNullOrEmpty(PassedLoginToken))
491 {
492 keys.Add("pixotoken");
493 values.Add(PassedLoginToken);
494 }
495
496 Debug.unityLogger.Log(LogType.Log, TAG, "Adding optional.");
497
498 if (!string.IsNullOrEmpty(optionalParameter))
499 {
500 keys.Add("optional");
501 values.Add(optionalParameter);
502 }
503
504 Debug.unityLogger.Log(LogType.Log, TAG, "Adding return target.");
505
506 if (!string.IsNullOrEmpty(nextExitApplication))
507 {
508 keys.Add("returntarget");
509 values.Add(nextExitApplication);
510 }
511
512 Debug.unityLogger.Log(LogType.Log, TAG, "Adding return target type.");
513
514 if (!string.IsNullOrEmpty(returnTargetType))
515 {
516 keys.Add("targettype");
517 values.Add(returnTargetType);
518 }
519
520 PixoPlatformUtilities.OpenApplication(CurrentExitTarget, keys.ToArray(), values.ToArray());
522 return;
523 }
524 }
525
527 }
528
529 string GetEndpointFromTarget(PlatformServer target)
530 {
531 return target.ToUrlString();
532 }
533
534 string GetPlatformEndpointFromPlatformTarget(PlatformServer target)
535 {
536 int targetValue = (int)target;
537 APIPlatformServer apiTarget = (APIPlatformServer)targetValue;
538
539 return apiTarget.ToUrlString();
540 }
541
543 {
545
546 if (webSocketUrl.Contains("://"))
547 {
548 webSocketUrl = webSocketUrl.Split(new string[] { "://" }, 2, StringSplitOptions.RemoveEmptyEntries)[1];
549 }
550
551 if (webSocketUrl.Contains("/"))
552 {
553 webSocketUrl = webSocketUrl.Split(new string[] { "/" }, 2, StringSplitOptions.RemoveEmptyEntries)[0];
554 }
555
556 webSocketUrl = "wss://" + webSocketUrl + "/ws";
557 }
558
559 void Start()
560 {
562 {
563 Debug.unityLogger.Log(LogType.Warning, TAG, $"{moduleVersion} is an invalid module version.");
564 }
565 deviceID = SystemInfo.deviceUniqueIdentifier;
566 deviceModel = SystemInfo.deviceModel;
567 platform =
568 XRSettings.loadedDeviceName.Length > 0 ? XRSettings.loadedDeviceName : Application.platform.ToString();
569 clientIP = Utils.ApexUtils.GetLocalIP();
570 }
571
572 private void FixedUpdate()
573 {
574 if (webSocket != null)
575 {
578
580 {
581 heartbeatTimer -= Time.fixedDeltaTime;
583 if (heartbeatTimer <= 0.0f)
584 {
587 }
588 }
589 }
591 void ConnectWebsocket()
592 {
593 socketConnectTask = Task.Run(() => webSocket.Connect(new Uri(webSocketUrl)));
594 }
595
597 {
598 socketDisconnectTask = Task.Run(() => webSocket.CloseSocket());
599 }
600
602 {
603 Debug.unityLogger.Log(LogType.Log, TAG, "Websocket connected successfully.");
604 }
605
606 void OnWebSocketConnectFailed(string reason)
608 Debug.unityLogger.Log(LogType.Error, TAG, "Websocket failed to connect with error: " + reason);
609 }
610
611 void OnWebSocketReceive(string data)
612 {
613 Debug.unityLogger.Log(LogType.Log, TAG, "Websocket received: " + data);
614 try
615 {
616 if (data.Contains("auth_code"))
617 {
618 var authCode = JsonConvert.DeserializeObject<AuthorizationCode>(data);
619 OnAuthorizationCodeReceived.Invoke(authCode.Code);
621
622 if (data.Contains("Token", StringComparison.OrdinalIgnoreCase))
623 {
624 object loginResponse = JsonConvert.DeserializeObject<LoginResponseContent>(data);
625 HandleLogin(true, loginResponse);
626 }
627 }
628 catch (Exception ex)
629 {
630 Debug.unityLogger.Log(LogType.Log, TAG, ex.Message);
631 }
632 }
633
634 void OnWebSocketClosed(System.Net.WebSockets.WebSocketCloseStatus reason)
635 {
636 Debug.unityLogger.Log(LogType.Log, TAG, "Websocket closed with reason: " + reason);
637 }
638
640 {
641 if (IsModuleVersionOnlyNumerical() == false)
642 return false;
643
644 string[] moduleVersionParts = moduleVersion.Split('.');
645
646 if (moduleVersionParts.Length != 3)
647 return false;
648
649 if (!IsModuleMajorVersionPartValid(moduleVersionParts[(int)VersionParts.Major]))
650 return false;
651
652 if (!IsModuleNonMajorVersionPartValid(moduleVersionParts[(int)VersionParts.Minor]))
653 return false;
655 if (!IsModuleNonMajorVersionPartValid(moduleVersionParts[(int)VersionParts.Patch]))
656 return false;
657
658 return true;
660
661 static readonly Regex VersionValidator = new Regex(@"^[0123456789.]+$");
662
664 {
665 return VersionValidator.IsMatch(moduleVersion);
666 }
667
668 bool IsModuleNonMajorVersionPartValid(string modulePart)
669 {
670 if (modulePart.Length <= 0)
671 return false;
672
673 if (modulePart.Length > 2)
674 return false;
675
676 return true;
677 }
678
679 bool IsModuleMajorVersionPartValid(string modulePart)
680 {
681 if (modulePart.Length <= 0)
682 return false;
683
684 if (modulePart.StartsWith("0"))
685 return false;
686
687 return true;
688 }
689
690 public static void ExitApplication(string nextExitTarget = "")
691 {
692 Instance._ExitApplication(nextExitTarget);
693 }
694
695 public static bool RequestAuthorizationCode()
696 {
697 return Instance._RequestAuthorizationCode();
698 }
699
700 public static void ChangePlatformServer(PlatformServer newServer)
701 {
702 Instance._ChangePlatformServer(newServer);
703 }
704
705 public static void Ping(Action<HttpResponseMessage, object> success = null, Action<HttpResponseMessage, FailureResponse> failure = null)
706 {
707 ApexAPIHandler.Ping(success, failure);
708 }
710 public static bool LoginWithToken()
712 Debug.unityLogger.Log(LogType.Log, TAG, $"Login with token of token {(string.IsNullOrEmpty(PassedLoginToken) ? "<none>" : PassedLoginToken)}");
714 }
715
716 public static bool LoginWithToken(string token)
717 {
718 Debug.unityLogger.Log(LogType.Log, TAG, $"Calling LoginWithToken ({token})");
719 if (token.Length <= 0)
720 {
721 return false;
722 }
723
724 Debug.unityLogger.Log(LogType.Log, TAG, $"Logging in with token: {token}");
725 ApexAPIHandler.LoginWithToken(token);
726
727 return true;
728 }
729
730 public static bool Login(LoginData login)
731 {
732 Debug.unityLogger.Log(LogType.Log, TAG, "_Login called.");
733 if (ApexAPIHandler == null)
734 {
735 Debug.unityLogger.Log(LogType.Log, TAG, "API Handler is null.");
736 Instance.OnLoginFailed.Invoke(
737 Instance.GenerateFailureResponse(
738 "There was an error reaching the platform, please contact your administrator."
739 )
740 );
741 return false;
742 }
744 if (login.Login.Length <= 0)
745 {
746 Debug.unityLogger.Log(LogType.Log, TAG, "[Login] No user name.");
747 Instance.OnLoginFailed.Invoke(Instance.GenerateFailureResponse("No username or email entered."));
748 return false;
749 }
750
751 if (login.Password.Length <= 0)
752 {
753 Debug.unityLogger.Log(LogType.Log, TAG, "[Login] No password.");
754 login.Password = "<empty>";
755 }
756
757 ApexAPIHandler.Login(login);
759 Debug.unityLogger.Log(LogType.Log, TAG, "Login called.");
760
761 return true;
762 }
763
764 public static bool Login(string username, string password)
765 {
766 return Login(new LoginData(username, password));
767 }
768
769 public static bool CheckModuleAccess(int targetModuleID = -1)
770 {
771 return Instance._CheckModuleAccess(targetModuleID);
772 }
773
774 public static void JoinSession(string scenarioID = null, Extension contextExtension = null, Action<HttpResponseMessage, JoinSessionResponse> success = null, Action<HttpResponseMessage, FailureResponse> failure = null)
775 {
776 Instance._JoinSession(scenarioID, contextExtension, success, failure);
777 }
779 public static void CompleteSession(SessionData currentSessionData, Extension contextExtension = null, Extension resultExtension = null, Action<HttpResponseMessage, object> success = null, Action<HttpResponseMessage, FailureResponse> failure = null)
780 {
781 Instance._CompleteSession(currentSessionData, contextExtension, resultExtension, success, failure);
782 }
783
784 public static void SendSimpleSessionEvent(string action, string targetObject, Extension contextExtension, Action<HttpResponseMessage, object> success = null, Action<HttpResponseMessage, FailureResponse> failure = null)
785 {
786 Instance._SendSimpleSessionEvent(action, targetObject, contextExtension, success, failure);
787 }
788
789 public static void SendSessionEvent(Statement eventStatement, Action<HttpResponseMessage, object> success = null, Action<HttpResponseMessage, FailureResponse> failure = null)
790 {
791 Instance._SendSessionEvent(eventStatement, success, failure);
792 }
793
794 public static bool GetCurrentUser()
795 {
796 return GetUser();
797 }
798
799 public static bool GetUser(int userId = -1)
800 {
801 return Instance._GetUser(userId);
802 }
803
804 public static bool GetCurrentUserModules()
805 {
806 return GetUserModules();
807 }
808
809 public static bool GetUserModules(int userId = -1)
810 {
811 return Instance._GetUserModules(userId);
813
814 public static bool GetModulesList(string platformName)
815 {
816 return Instance._GetModuleList(platformName);
818
819 public static bool GetQuickIDAuthUsers(string serialNumber)
820 {
821 return Instance._GetQuickIDAuthUsers(serialNumber);
823
824 public static bool QuickIDLogin(string serialNumber, string username)
825 {
826 return Instance._QuickIDLogin(serialNumber, username);
828
829 protected void _ChangePlatformServer(PlatformServer newServer)
830 {
831 PlatformTargetServer = newServer;
833 SetupAPI();
834 }
835
836 protected bool _LoginWithToken(string token)
838 Debug.unityLogger.Log(LogType.Log, TAG, $"Calling LoginWithToken ({token})");
839 if (token.Length <= 0)
840 {
841 return false;
843
844 Debug.unityLogger.Log(LogType.Log, TAG, $"Logging in with token: {token}");
846
847 return true;
848 }
849
850 protected FailureResponse GenerateFailureResponse(string message)
851 {
852 FailureResponse failureResponse = new FailureResponse()
853 {
854 Error = "True",
855 HttpCode = "400",
856 Message = message,
857 };
858
859 return failureResponse;
860 }
861
862 protected void _ParsePassedData(Dictionary<string, string> arguments)
863 {
864 Debug.unityLogger.Log(LogType.Log, TAG, "Parsing passed data.");
865 if (arguments == null)
866 {
867 Debug.unityLogger.Log(LogType.Log, TAG, "No arguments found for the application.");
868 return;
869 }
870
871 if (arguments.ContainsKey("optional"))
872 optionalParameter = arguments["optional"];
873
874 if (arguments.ContainsKey("returntarget"))
875 CurrentExitTarget = arguments["returntarget"];
876
877 if (arguments.ContainsKey("targettype"))
878 TargetType = arguments["targettype"];
879
880 Debug.unityLogger.Log(LogType.Log, TAG, "Is the token already set?");
881 if (string.IsNullOrEmpty(PassedLoginToken))
882 {
883 Debug.unityLogger.Log(LogType.Log, TAG, "Token is not set, but does the arguments contain a token?");
884 if (arguments.ContainsKey("pixotoken"))
885 {
886 Debug.unityLogger.Log(LogType.Log, TAG, "Token was found in the arguments.");
887 string token = arguments["pixotoken"];
888 Debug.unityLogger.Log(LogType.Log, TAG, $"Found pixotoken {token}.");
889 if (!string.IsNullOrEmpty(token))
890 {
891 PassedLoginToken = string.Copy(token);
892 }
893 }
894 }
895 }
896
897 protected bool _CheckModuleAccess(int targetModuleID = -1)
899 Debug.unityLogger.Log(LogType.Log, TAG, "_CheckModuleAccess called.");
900
901 if (currentActiveLogin == null)
902 {
903 Debug.unityLogger.Log(LogType.Error, TAG, "Cannot check user's module access with no active login.");
904 return false;
905 }
906
907 if (targetModuleID <= -1)
908 {
909 targetModuleID = moduleID;
911
912 Debug.unityLogger.Log(LogType.Log, TAG, $"Checking module access of module {targetModuleID} from user {currentActiveLogin.ID} and device serial number {(string.IsNullOrEmpty(deviceSerialNumber) == true ? "---" : deviceSerialNumber)}");
914
915 return true;
916 }
917
918 protected void _JoinSession(string newScenarioID, Extension contextExtension, Action<HttpResponseMessage, JoinSessionResponse> success, Action<HttpResponseMessage, FailureResponse> failure)
919 {
920 if (currentActiveLogin == null)
921 {
922 Debug.unityLogger.Log(LogType.Error, TAG, "Cannot join session with no active login.");
923 failure?.Invoke(null, new FailureResponse { Error = "true", Message = "Cannot join session with no active login." });
924 return;
925 }
926
927 if (userAccessVerified == false)
928 {
929 failure?.Invoke(null, new FailureResponse { Error = "true", Message = "User access not verified." });
930 return;
931 }
932
933 if (newScenarioID != null)
934 {
935 scenarioID = newScenarioID;
936 }
937
938 if (sessionInProgress == true)
939 {
940 Debug.unityLogger.Log(LogType.Error, TAG,
941 "Session is already in progress."
942 + " The previous session didn't complete or a new session was started during an active session."
943 );
944 }
946 currentSessionID = Guid.NewGuid();
947
948 Statement sessionStatement = new Statement();
949 Agent sessionActor = new Agent();
950 sessionActor.mbox = currentActiveLogin.Email;
951
952 Verb sessionVerb = new Verb();
953 sessionVerb.id = ApexVerbs.JOINED_SESSION;
954 sessionVerb.display = new LanguageMap();
955 sessionVerb.display.Add("en", "Joined Session");
956
957 Activity sessionActivity = new Activity();
958 sessionActivity.id = string.Format("https://pixovr.com/xapi/objects/{0}/{1}", moduleID, scenarioID);
959
960 Context sessionContext = new Context();
961 sessionContext.registration = currentSessionID;
962 sessionContext.revision = moduleVersion;
963 sessionContext.platform = platform;
964
965 sessionContext.extensions = AppendStandardContextExtension(contextExtension);
967 sessionStatement.actor = sessionActor;
968 sessionStatement.verb = sessionVerb;
969 sessionStatement.target = sessionActivity;
970 sessionStatement.context = sessionContext;
971
972 JoinSessionData sessionData = new JoinSessionData();
973 sessionData.DeviceId = deviceID;
974 sessionData.IpAddress = clientIP;
975 sessionData.ModuleId = moduleID;
976 sessionData.Uuid = currentSessionID.ToString();
977 sessionData.EventType = ApexEventTypes.PIXOVR_SESSION_JOINED;
978 sessionData.JsonData = sessionStatement;
979
980 apexAPIHandler.JoinSession(currentActiveLogin.Token, sessionData, success, failure);
981 }
982
983 protected void _SendSimpleSessionEvent(string verbName, string targetObject, Extension contextExtension, Action<HttpResponseMessage, object> success, Action<HttpResponseMessage, FailureResponse> failure)
984 {
985 if (string.IsNullOrEmpty(verbName))
986 {
987 failure?.Invoke(null, new FailureResponse { Error = "true", Message = "Verb name is invalid." });
988 return;
989 }
990
991 Statement sessionStatement = new Statement();
992
993 Verb sessionVerb = new Verb();
994 sessionVerb.id = new Uri("https://pixovr.com/xapi/verbs/" + verbName.Replace(' ', '_').ToLower());
995 sessionVerb.display = new LanguageMap();
996 sessionVerb.display.Add("en", verbName);
997
998 Activity sessionActivity = new Activity();
999 sessionActivity.id = string.Format(
1000 "https://pixovr.com/xapi/objects/{0}/{1}/{2}",
1001 moduleID,
1002 scenarioID,
1003 targetObject.Replace(' ', '_').ToLower()
1004 );
1005
1006 Context sessionContext = new Context();
1007 sessionContext.registration = currentSessionID;
1008 sessionContext.revision = moduleVersion;
1009 sessionContext.platform = platform;
1010
1011 sessionContext.extensions = AppendStandardContextExtension(contextExtension);
1012
1013 sessionStatement.actor = null;
1014 sessionStatement.verb = sessionVerb;
1015 sessionStatement.target = sessionActivity;
1016 sessionStatement.context = sessionContext;
1017
1018 SessionEventData sessionEvent = new SessionEventData();
1019 sessionEvent.DeviceId = deviceID;
1020 sessionEvent.ModuleId = ModuleID;
1021 sessionEvent.Uuid = currentSessionID.ToString();
1022 sessionEvent.EventType = ApexEventTypes.PIXOVR_SESSION_EVENT;
1023 sessionEvent.JsonData = sessionStatement;
1024
1025 _SendSessionEvent(sessionStatement, success, failure);
1026 }
1027
1028 protected void _SendSessionEvent(Statement eventStatement, Action<HttpResponseMessage, object> success, Action<HttpResponseMessage, FailureResponse> failure)
1029 {
1030 if (userAccessVerified == false)
1032 failure?.Invoke(null, new FailureResponse { Error = "true", Message = "User access not verified." });
1033 return;
1034 }
1035
1036 if (currentActiveLogin == null)
1037 {
1038 Debug.unityLogger.Log(LogType.Error, TAG, "Cannot send a session event with no active login.");
1039 failure?.Invoke(null, new FailureResponse { Error = "true", Message = "Cannot send a session event with no active login." });
1040 return;
1041 }
1042
1043 if (sessionInProgress == false)
1044 {
1045 Debug.unityLogger.Log(LogType.Error, TAG, "No session in progress to send event for.");
1046 failure?.Invoke(null, new FailureResponse { Error = "true", Message = "No session in progress to send event for." });
1047 return;
1048 }
1049
1050 if (eventStatement == null)
1051 {
1052 Debug.unityLogger.Log(LogType.Error, TAG, "No event data to send.");
1053 failure?.Invoke(null, new FailureResponse { Error = "true", Message = "No event data to send." });
1054 return;
1055 }
1056
1057 if (eventStatement.actor != null)
1058 {
1059 Debug.unityLogger.Log(LogType.Warning, TAG, "Actor data should not be filled out.");
1060 }
1061
1062 if (eventStatement.verb == null)
1063 {
1064 Debug.unityLogger.Log(LogType.Error, TAG, "Verb missing from eventStatement.");
1065 failure?.Invoke(null, new FailureResponse { Error = "true", Message = "Verb missing from eventStatement." });
1066 return;
1067 }
1068
1069 if (eventStatement.verb.id == null)
1070 {
1071 Debug.unityLogger.Log(LogType.Error, TAG, "verb.id missing from eventStatement.");
1072 failure?.Invoke(null, new FailureResponse { Error = "true", Message = "verb.id missing from eventStatement." });
1073 return;
1074 }
1075
1076 if (eventStatement.target == null)
1077 {
1078 Debug.unityLogger.Log(LogType.Error, TAG, "Object (target) missing from eventStatement.");
1079 failure?.Invoke(null, new FailureResponse { Error = "true", Message = "Object (target) missing from eventStatement." });
1080 return;
1081 }
1082
1083 eventStatement.actor = new Agent();
1084 eventStatement.actor.mbox = currentActiveLogin.Email;
1085
1086 if (eventStatement.context == null)
1087 {
1088 eventStatement.context = new Context();
1089 }
1090
1091 eventStatement.context.registration = currentSessionID;
1092 eventStatement.context.revision = ModuleVersion;
1093 eventStatement.context.platform = platform;
1094
1095 eventStatement.context.extensions = AppendStandardContextExtension(eventStatement.context.extensions);
1096
1097 SessionEventData sessionEvent = new SessionEventData();
1098 sessionEvent.DeviceId = deviceID;
1099 sessionEvent.ModuleId = ModuleID;
1100 sessionEvent.Uuid = currentSessionID.ToString();
1101 sessionEvent.EventType = ApexEventTypes.PIXOVR_SESSION_EVENT;
1102 sessionEvent.JsonData = eventStatement;
1103
1104 apexAPIHandler.SendSessionEvent(currentActiveLogin.Token, sessionEvent, success, failure);
1105 }
1106
1107 protected void _CompleteSession(SessionData currentSessionData, Extension contextExtension, Extension resultExtension, Action<HttpResponseMessage, object> success = null, Action<HttpResponseMessage, FailureResponse> failure = null)
1108 {
1109 if (userAccessVerified == false)
1110 {
1111 failure?.Invoke(null, new FailureResponse { Error = "true", Message = "User access not verified." });
1112 return;
1113 }
1114
1115 if (currentActiveLogin == null)
1116 {
1117 Debug.unityLogger.Log(LogType.Error, TAG, "Cannot complete session with no active login.");
1118 failure?.Invoke(null, new FailureResponse { Error = "true", Message = "Cannot complete session with no active login." });
1119 return;
1120 }
1121
1122 if (sessionInProgress == false)
1123 {
1124 Debug.unityLogger.Log(LogType.Error, TAG, "No session in progress to complete.");
1125 failure?.Invoke(null, new FailureResponse { Error = "true", Message = "No session in progress to complete." });
1126 return;
1127 }
1128
1129 // Create our actor
1130 Agent sessionActor = new Agent();
1131 sessionActor.mbox = currentActiveLogin.Email;
1132
1133 // Create our verb
1134 Verb sessionVerb = new Verb();
1135 sessionVerb.id = ApexVerbs.COMPLETED_SESSION;
1136 sessionVerb.display = new LanguageMap();
1137 sessionVerb.display.Add("en", "Completed Session");
1138
1139 // Create the session activity
1140 Activity sessionActivity = new Activity();
1141 sessionActivity.id = string.Format("https://pixovr.com/xapi/objects/{0}/{1}", moduleID, scenarioID);
1142
1143 // Create our context
1144 Context sessionContext = new Context();
1145 sessionContext.registration = currentSessionID;
1146 sessionContext.revision = moduleVersion;
1147 sessionContext.platform = platform;
1148
1149 sessionContext.extensions = AppendStandardContextExtension(contextExtension);
1150
1151 // Create our results
1152 Result sessionResult = new Result();
1153 sessionResult.completion = currentSessionData.Complete;
1154 sessionResult.success = currentSessionData.Success;
1155 // Add score to the results
1156 sessionResult.score = new Score();
1157 sessionResult.score.min = currentSessionData.MinimumScore;
1158 sessionResult.score.max = currentSessionData.MaximumScore;
1159 sessionResult.score.raw = currentSessionData.Score;
1160 sessionResult.score.scaled = DetermineScaledScore(
1161 currentSessionData.ScaledScore,
1162 currentSessionData.Score,
1163 currentSessionData.MaximumScore
1164 );
1165 sessionResult.duration = TimeSpan.FromSeconds(currentSessionData.Duration);
1166 if (resultExtension != null)
1167 {
1168 sessionResult.extensions = new Extensions(resultExtension.ToJObject());
1169 }
1170
1171 // Create our statement and add the pieces
1172 Statement sessionStatement = new Statement();
1173 sessionStatement.actor = sessionActor;
1174 sessionStatement.verb = sessionVerb;
1175 sessionStatement.target = sessionActivity;
1176 sessionStatement.context = sessionContext;
1177 sessionStatement.result = sessionResult;
1178
1179 CompleteSessionData sessionData = new CompleteSessionData();
1180 sessionData.DeviceId = deviceID;
1181 sessionData.ModuleId = moduleID;
1182 sessionData.Uuid = currentSessionID.ToString();
1183 sessionData.EventType = ApexEventTypes.PIXOVR_SESSION_COMPLETE;
1184 sessionData.JsonData = sessionStatement;
1185 sessionData.SessionDuration = currentSessionData.Duration;
1186 sessionData.Score = currentSessionData.Score;
1187 sessionData.ScoreMin = currentSessionData.MinimumScore;
1188 sessionData.ScoreMax = currentSessionData.MaximumScore;
1189 sessionData.ScoreScaled = DetermineScaledScore(
1190 currentSessionData.ScaledScore,
1191 currentSessionData.Score,
1192 currentSessionData.MaximumScore
1193 );
1194
1195 apexAPIHandler.CompleteSession(currentActiveLogin.Token, sessionData, success, failure);
1196 }
1197
1198 protected bool _SendHeartbeat()
1199 {
1200 Debug.unityLogger.Log(LogType.Log, TAG, "Sending heartbeat...");
1201 if (!sessionInProgress)
1202 return false;
1203
1204 if (currentActiveLogin == null)
1205 return false;
1206
1208
1209 return true;
1210 }
1211
1212 protected bool _GetUser(int userId = -1)
1213 {
1214 if (currentActiveLogin == null)
1215 return false;
1216
1217 if (userId < 0)
1218 {
1219 userId = currentActiveLogin.ID;
1220 }
1221
1223 return true;
1224 }
1225
1226 protected bool _GetUserModules(int userId = -1)
1227 {
1228 if (currentActiveLogin == null)
1229 return false;
1230
1231 if (userId < 0)
1232 {
1233 userId = currentActiveLogin.ID;
1234 }
1235
1237 return true;
1238 }
1239
1240 protected bool _GetModuleList(string platformName)
1241 {
1242 if (currentActiveLogin == null)
1243 return false;
1244
1246 return true;
1247 }
1248
1249 protected bool _GetQuickIDAuthUsers(string serialNumber)
1250 {
1251 if (String.IsNullOrEmpty(serialNumber)) return false;
1253 return true;
1254 }
1255
1256
1257 protected bool _QuickIDLogin(string serialNumber, string username)
1258 {
1259 if (String.IsNullOrEmpty(serialNumber) || string.IsNullOrEmpty(username)) return false;
1260 var loginData = new QuickIDLoginData(serialNumber, username);
1261 apexAPIHandler.QuickIDLogin(loginData);
1262 return true;
1263 }
1264
1265 private float DetermineScaledScore(float scaledScore, float score, float maxScore)
1266 {
1267 float determinedScaledScore = scaledScore;
1268
1269 if (scaledScore < Mathf.Epsilon && score >= Mathf.Epsilon)
1270 {
1271 determinedScaledScore = (score / maxScore) * 100f;
1272 }
1273
1274 return determinedScaledScore;
1275 }
1276
1277 private Extensions AppendStandardContextExtension(Extensions currentContextExtensions)
1278 {
1279 return AppendStandardContextExtension(new Extension(currentContextExtensions.ToJObject()));
1280 }
1281
1282 private Extensions AppendStandardContextExtension(Extension currentContextExtension)
1283 {
1284 Extension contextExtension;
1285 if (currentContextExtension != null)
1286 {
1287 contextExtension = currentContextExtension;
1289 else
1290 {
1291 contextExtension = new Extension();
1292 }
1293
1294 contextExtension.Add(ApexExtensionStrings.MODULE_ID, moduleID.ToString());
1295 contextExtension.AddSimple("device_id", deviceID);
1296 contextExtension.AddSimple("device_model", deviceModel);
1297 contextExtension.AddSimple("sdk_version", "unity-" + ApexUtils.SDKVersion);
1298
1299 if (string.IsNullOrEmpty(deviceSerialNumber))
1300 {
1301 contextExtension.AddSimple("device_serial", deviceSerialNumber.ToString());
1302 }
1303
1304 return new Extensions(contextExtension.ToJObject());
1306
1307 protected void OnAPIResponse(ResponseType response, HttpResponseMessage message, object responseData)
1308 {
1309 Debug.unityLogger.Log(LogType.Log, TAG, "On API Response");
1310 bool success = message.IsSuccessStatusCode;
1311 if (responseData is FailureResponse)
1312 {
1313 success = success && (responseData is IFailure) && (!(responseData as FailureResponse).HasErrored());
1314 }
1315
1316 switch (response)
1317 {
1318 case ResponseType.RT_LOGIN:
1319 {
1320 Debug.unityLogger.Log(LogType.Log, TAG, "Calling to handle login.");
1321 HandleLogin(success, responseData);
1322 break;
1323 }
1324 case ResponseType.RT_GET_USER:
1326 if (success)
1327 {
1328 OnGetUserSuccess.Invoke(responseData as GetUserResponseContent);
1329 }
1330 else
1331 {
1332 FailureResponse failureData = responseData as FailureResponse;
1333 Debug.unityLogger.Log(LogType.Log, TAG, string.Format("Failed to get user.\nError: {0}", failureData.Message));
1334 OnGetUserFailed.Invoke(responseData as FailureResponse);
1335 }
1336 break;
1337 }
1338 case ResponseType.RT_GET_USER_MODULES:
1339 {
1340 if (success)
1341 {
1342 OnGetUserModulesSuccess.Invoke(responseData as GetUserModulesResponse);
1343 }
1344 else
1345 {
1346 FailureResponse failureData = responseData as FailureResponse;
1347 Debug.unityLogger.Log(LogType.Log, TAG, string.Format("Failed to get user.\nError: {0}", failureData.Message));
1348 OnGetUserFailed.Invoke(responseData as FailureResponse);
1349 }
1350 break;
1351 }
1352 case ResponseType.RT_GET_USER_ACCESS:
1353 {
1354 if (success)
1356 var userAccessResponseContent = responseData as UserAccessResponseContent;
1357 if (userAccessResponseContent.Access)
1358 {
1359 if (userAccessResponseContent.PassingScore.HasValue)
1360 {
1361 currentActiveLogin.MinimumPassingScore = userAccessResponseContent.PassingScore.Value;
1362 }
1363
1364 userAccessVerified = true;
1366 }
1367 else
1368 {
1369 currentActiveLogin = null;
1370 userAccessVerified = false;
1371 OnModuleAccessFailed.Invoke(
1372 new FailureResponse()
1373 {
1374 Error = "True",
1375 HttpCode = "401",
1376 Message = "User does not have access to module",
1377 }
1378 );
1379 }
1380 }
1381 else
1382 {
1383 FailureResponse failureData = responseData as FailureResponse;
1384 Debug.unityLogger.Log(LogType.Log, TAG,
1385 string.Format(
1386 "Failed to get users module access data.\nError: {0}",
1387 failureData.Message
1388 )
1389 );
1390
1391 OnModuleAccessFailed.Invoke(responseData as FailureResponse);
1392 }
1393 break;
1394 }
1395 case ResponseType.RT_GET_MODULES_LIST:
1396 {
1397 if (success)
1398 {
1399 OnGetOrganizationModulesSuccess.Invoke(responseData as List<OrgModule>);
1400 }
1401 else
1402 {
1403 FailureResponse failureData = responseData as FailureResponse;
1404 Debug.unityLogger.Log(LogType.Log, TAG,
1405 string.Format("Failed to get org modules.\nError: {0}", failureData.Message)
1406 );
1407
1408 OnGetOrganizationModulesFailed.Invoke(responseData as FailureResponse);
1409 }
1410
1411 break;
1412 }
1413 case ResponseType.RT_QUICK_ID_AUTH_GET_USERS:
1414 {
1415 if (success)
1416 {
1418 }
1419 else
1420 {
1421 FailureResponse failureData = responseData as FailureResponse;
1422 Debug.unityLogger.Log(LogType.Log, TAG, string.Format("Failed to get Quick ID Authentication users.\nError: {0}", failureData.Message));
1423 OnGetQuickIDAuthGetUsersFailed.Invoke(responseData as FailureResponse);
1424 }
1425 break;
1426 }
1427
1428 case ResponseType.RT_QUICK_ID_AUTH_LOGIN:
1429 {
1430 HandleLogin(success, responseData);
1431 if (success)
1432 {
1433 OnQuickIDAuthLoginSuccess.Invoke(responseData as LoginResponseContent);
1434 }
1435 else
1436 {
1437 FailureResponse failureData = responseData as FailureResponse;
1438 Debug.unityLogger.Log(LogType.Log, TAG, string.Format("Failed to authenticate with Quick ID Authentication.\nError: {0}", failureData.Message));
1439 OnQuickIDAuthLoginFailed.Invoke(responseData as FailureResponse);
1440 }
1441 break;
1442 }
1443 default:
1444 {
1445 break;
1446 }
1447 }
1448
1449 if (OnPlatformResponse != null)
1450 {
1451 OnPlatformResponse.Invoke(response, success, responseData);
1452 }
1453 }
1454
1455 protected void HandleLogin(bool successful, object responseData)
1456 {
1457 Debug.unityLogger.Log(LogType.Log, TAG, "Handling Login");
1458 userAccessVerified = false;
1459
1460 if (successful)
1461 {
1462 currentActiveLogin = responseData as LoginResponseContent;
1463
1464 OnLoginSuccess.Invoke();
1465
1467 {
1469 }
1470 }
1471 else
1472 {
1473 FailureResponse failureData = responseData as FailureResponse;
1474 Debug.unityLogger.Log(LogType.Log, TAG, string.Format("Failed to log in.\nError: {0}", failureData.Message));
1475 OnLoginFailed.Invoke(responseData as FailureResponse);
1476 }
1477 }
1478
1480 {
1481 if (!webSocket.IsConnected())
1482 {
1484 }
1486 }
1487
1488 public static bool GenerateOneTimeLoginForCurrentUser(Action<HttpResponseMessage, object> success, Action<HttpResponseMessage, FailureResponse> failure)
1489 {
1490 if (CurrentActiveLogin == null)
1491 {
1492 Debug.unityLogger.Log(LogType.Error, TAG, "No user logged in to generate code.");
1493 failure?.Invoke(null, new FailureResponse { Error = "true", Message = "No user logged in to generate code." });
1494 return false;
1495 }
1496
1497 ApexAPIHandler.GenerateAssistedLogin(CurrentActiveLogin.Token, -1, success, failure);
1498 return true;
1499 }
1500
1501 public static void GenerateOneTimeLoginForUser(int userId, Action<HttpResponseMessage, object> success, Action<HttpResponseMessage, FailureResponse> failure)
1502 {
1504 {
1505 Debug.unityLogger.Log(LogType.Error, TAG, "No current user logged in.");
1506 failure?.Invoke(null, new FailureResponse { Error = "true", Message = "No current user logged in." });
1507 return;
1508 }
1509
1510 if (userId < 0)
1511 {
1512 Debug.unityLogger.Log(LogType.Error, TAG, "User id is invalid.");
1513 failure?.Invoke(null, new FailureResponse { Error = "true", Message = "User id is invalid." });
1514 return;
1515 }
1516
1517 ApexAPIHandler.GenerateAssistedLogin(CurrentActiveLogin.Token, userId, success, failure);
1518 }
1519
1520 public static void GetUserMetricsForCurrentUsersOrg(int page, FilterParams filterParams, Action<UserMetricsResponse, object> success, Action<HttpResponseMessage, FailureResponse> failure)
1521 {
1522 if (CurrentActiveLogin == null)
1523 {
1524 Debug.LogError("[ApexSystem] No user logged in to get the user metrics for the current user org.");
1525 failure?.Invoke(null, new FailureResponse { Error = "true", Message = "No user logged in to retrieve org devices." });
1526 return;
1528
1529 ApexAPIHandler.GetUserMetricsForOrg(CurrentActiveLogin.Token, CurrentActiveLogin.OrgId, page, filterParams, success, failure);
1530 }
1531
1532 public static void GetDevicesForOrg(int page, FilterParams filterParams, Action<HttpResponseMessage, OrgDevicesResponse> success, Action<HttpResponseMessage, FailureResponse> failure)
1533 {
1534 if (CurrentActiveLogin == null)
1535 {
1536 Debug.LogError("[ApexSystem] No user logged in to retrieve org devices.");
1537 failure?.Invoke(null, new FailureResponse { Error = "true", Message = "No user logged in to retrieve org devices." });
1538 return;
1539 }
1540
1541 ApexAPIHandler.GetDevicesForOrg(CurrentActiveLogin.Token, CurrentActiveLogin.OrgId, page, filterParams, success, failure);
1542 }
1543
1544 public static void GetSesssionHistory(int page, SessionFilters sessionFilters, FilterParams filterParams, Action<HttpResponseMessage, SessionHistoryResponse> success, Action<HttpResponseMessage, FailureResponse> failure)
1545 {
1546 if (CurrentActiveLogin == null)
1547 {
1548 Debug.LogError("[ApexSystem] No user logged in to retrieve session history.");
1549 failure?.Invoke(null, new FailureResponse { Error = "true", Message = "No user logged in to retrieve session history." });
1550 return;
1551 }
1552
1553 ApexAPIHandler.GetSessionHistory(CurrentActiveLogin.Token, page, sessionFilters, filterParams, success, failure);
1554 }
1555 }
1556}
async void GetUserModules(string authToken, int userId)
async void QuickIDLogin(QuickIDLoginData login)
async void CompleteSession(string authToken, CompleteSessionData completionData, Action< HttpResponseMessage, object > success, Action< HttpResponseMessage, FailureResponse > failure)
async void LoginWithToken(string token)
void SetPlatformEndpoint(string endpointUrl)
async void GetQuickIDAuthenticationUsers(string serialNumber)
async void GetUserData(string authToken, int userId)
async void SendHeartbeat(string authToken, int sessionId, Action< HttpResponseMessage, object > success=null, Action< HttpResponseMessage, FailureResponse > failure=null)
async void SendSessionEvent(string authToken, SessionEventData sessionEvent, Action< HttpResponseMessage, object > success, Action< HttpResponseMessage, FailureResponse > failure)
async void JoinSession(string authToken, JoinSessionData joinData, Action< HttpResponseMessage, JoinSessionResponse > success, Action< HttpResponseMessage, FailureResponse > failure)
async void GetModuleAccess(int moduleId, int userId, string serialNumber)
async void GetModuleList(string authToken, string platform)
const string PIXOVR_SESSION_COMPLETE
const string PIXOVR_SESSION_EVENT
const string PIXOVR_SESSION_JOINED
static readonly string MODULE_ID
bool InitializeInstance(T targetInstance)
ApexWebsocket webSocket
Extensions AppendStandardContextExtension(Extensions currentContextExtensions)
OnGeneratedAssistedLoginSuccessEvent OnGeneratedAssistedLoginSuccess
bool runSetupOnAwake
[SerializeField]
static string CurrentExitTarget
static string PassedLoginToken
Definition ApexSystem.cs:90
static bool LoginCheckModuleAccess
Definition ApexSystem.cs:78
void _CompleteSession(SessionData currentSessionData, Extension contextExtension, Extension resultExtension, Action< HttpResponseMessage, object > success=null, Action< HttpResponseMessage, FailureResponse > failure=null)
static bool QuickIDLogin(string serialNumber, string username)
static bool GetCurrentUser()
static bool GenerateOneTimeLoginForCurrentUser(Action< HttpResponseMessage, object > success, Action< HttpResponseMessage, FailureResponse > failure)
static bool RunSetupOnAwake
Definition ApexSystem.cs:72
static void SendSessionEvent(Statement eventStatement, Action< HttpResponseMessage, object > success=null, Action< HttpResponseMessage, FailureResponse > failure=null)
FailureResponse GenerateFailureResponse(string message)
string GetPlatformEndpointFromPlatformTarget(PlatformServer target)
void _ChangePlatformServer(PlatformServer newServer)
int moduleID
[SerializeField]
static bool Login(string username, string password)
OnApexFailureEvent OnGeneratedAssistedLoginFailed
static void SendSimpleSessionEvent(string action, string targetObject, Extension contextExtension, Action< HttpResponseMessage, object > success=null, Action< HttpResponseMessage, FailureResponse > failure=null)
static string APIEndpoint
static string ModuleName
Definition ApexSystem.cs:48
static void Ping(Action< HttpResponseMessage, object > success=null, Action< HttpResponseMessage, FailureResponse > failure=null)
OnGetQuickIDAuthUsersSuccessEvent OnGetQuickIDAuthGetUsersSuccess
void OnAPIResponse(ResponseType response, HttpResponseMessage message, object responseData)
static void ExitApplication(string nextExitTarget="")
OnApexFailureEvent OnGetUserFailed
OnAuthCodeReceived OnAuthorizationCodeReceived
OnGetOrgModulesSuccessEvent OnGetOrganizationModulesSuccess
static bool RequestAuthorizationCode()
void SetupPlatformConfiguration()
PlatformResponse OnPlatformResponse
static bool GetUser(int userId=-1)
static bool GetQuickIDAuthUsers(string serialNumber)
string moduleVersion
[SerializeField]
string GetEndpointFromTarget(PlatformServer target)
OnLoginSuccessEvent OnLoginSuccess
void OnWebSocketConnectFailed(string reason)
static bool CheckModuleAccess(int targetModuleID=-1)
OnQuickIDAuthLoginSuccessEvent OnQuickIDAuthLoginSuccess
void OnWebSocketReceive(string data)
void HandleLogin(bool successful, object responseData)
static void GenerateOneTimeLoginForUser(int userId, Action< HttpResponseMessage, object > success, Action< HttpResponseMessage, FailureResponse > failure)
static bool GetUserModules(int userId=-1)
void _SendSimpleSessionEvent(string verbName, string targetObject, Extension contextExtension, Action< HttpResponseMessage, object > success, Action< HttpResponseMessage, FailureResponse > failure)
static LoginResponseContent CurrentActiveLogin
Definition ApexSystem.cs:66
bool _GetQuickIDAuthUsers(string serialNumber)
string currentExitTargetParameter
static APIHandler ApexAPIHandler
static void GetSesssionHistory(int page, SessionFilters sessionFilters, FilterParams filterParams, Action< HttpResponseMessage, SessionHistoryResponse > success, Action< HttpResponseMessage, FailureResponse > failure)
static string ServerIP
Definition ApexSystem.cs:36
static string TargetType
float DetermineScaledScore(float scaledScore, float score, float maxScore)
APIHandler apexAPIHandler
static bool GetCurrentUserModules()
static bool GetModulesList(string platformName)
static void CompleteSession(SessionData currentSessionData, Extension contextExtension=null, Extension resultExtension=null, Action< HttpResponseMessage, object > success=null, Action< HttpResponseMessage, FailureResponse > failure=null)
Task< bool > socketConnectTask
static void GetUserMetricsForCurrentUsersOrg(int page, FilterParams filterParams, Action< UserMetricsResponse, object > success, Action< HttpResponseMessage, FailureResponse > failure)
OnApexFailureEvent OnGetQuickIDAuthGetUsersFailed
static void ChangePlatformServer(PlatformServer newServer)
static string ModuleVersion
Definition ApexSystem.cs:54
static bool LoginWithToken()
bool loginCheckModuleAccess
[SerializeField]
OnApexFailureEvent OnGetUserModulesFailed
OnApexFailureEvent OnLoginFailed
static bool Login(LoginData login)
static string ScenarioID
Definition ApexSystem.cs:60
void _ParsePassedData(Dictionary< string, string > arguments)
static void JoinSession(string scenarioID=null, Extension contextExtension=null, Action< HttpResponseMessage, JoinSessionResponse > success=null, Action< HttpResponseMessage, FailureResponse > failure=null)
static string DeviceSerialNumber
Definition ApexSystem.cs:84
void _SendSessionEvent(Statement eventStatement, Action< HttpResponseMessage, object > success, Action< HttpResponseMessage, FailureResponse > failure)
LoginResponseContent currentActiveLogin
bool _LoginWithToken(string token)
static readonly Regex VersionValidator
void _JoinSession(string newScenarioID, Extension contextExtension, Action< HttpResponseMessage, JoinSessionResponse > success, Action< HttpResponseMessage, FailureResponse > failure)
OnApexFailureEvent OnGetOrganizationModulesFailed
float heartbeatTime
[SerializeField]
OnApexFailureEvent OnModuleAccessFailed
OnApexFailureEvent OnQuickIDAuthLoginFailed
static string OptionalData
string scenarioID
[SerializeField]
static readonly string TAG
Definition ApexSystem.cs:27
OnModuleAccessSuccessEvent OnModuleAccessSuccess
void _ExitApplication(string nextExitApplication)
bool _GetUser(int userId=-1)
OnGetUserSuccessEvent OnGetUserSuccess
bool _QuickIDLogin(string serialNumber, string username)
bool _CheckModuleAccess(int targetModuleID=-1)
bool IsModuleVersionOnlyNumerical()
string serverIP
[SerializeField]
void OnWebSocketClosed(System.Net.WebSockets.WebSocketCloseStatus reason)
static void GetDevicesForOrg(int page, FilterParams filterParams, Action< HttpResponseMessage, OrgDevicesResponse > success, Action< HttpResponseMessage, FailureResponse > failure)
bool _GetModuleList(string platformName)
static bool LoginWithToken(string token)
PlatformServer PlatformTargetServer
OnGetUserModulesSuccessEvent OnGetUserModulesSuccess
Extensions AppendStandardContextExtension(Extension currentContextExtension)
string moduleName
[SerializeField]
bool IsModuleNonMajorVersionPartValid(string modulePart)
bool _GetUserModules(int userId=-1)
bool IsModuleMajorVersionPartValid(string modulePart)
void OnDeepLinkActivated(string url)
static readonly Uri JOINED_SESSION
static readonly Uri COMPLETED_SESSION
async Task< bool > Connect(Uri endpoint, int attemptTries=3)
OnWebSocketReceive OnReceive
OnWebSocketConnectFailed OnConnectFailed
OnWebSocketClosed OnClosed
OnWebSocketConnectSuccessful OnConnectSuccess
[Serializable]
Definition ApexTypes.cs:164
static bool DoesFileExistInSharedLocation(string fileName)
static string ReadFileFromSharedStorage(string fileName)
static bool OpenApplication(string applicationPath, string[] argumentKeys, string[] argumentValues)
static Dictionary< string, string > ParseURLArguments(string url)
static Dictionary< string, string > ParseApplicationArguments()
static string GetMacAddress()
Definition ApexUtils.cs:20
void Add(Uri key, string value)
void AddSimple(string key, string value)
override JObject ToJObject(TCAPIVersion version)
delegate void PlatformResponse(ResponseType type, bool wasSuccessful, object responseData)