diff --git a/README.md b/README.md index e4656bc..8b1c5c2 100644 --- a/README.md +++ b/README.md @@ -16,8 +16,8 @@ To start tracking, you need to know your `projectToken`. To initialize the track var infinario = Infinario.Infinario.GetInstance(); infinario.Initialize("projectToken"); -//or if you want to track app version as well -infinario.Initilize("projectToken", "1.0.0"); +//or if you want to track app version as well, third parameter is instance +infinario.Initilize("projectToken", "1.0.0", "https://api.infinario.com"); ``` Now you can track events by calling the ```Track``` method: @@ -110,7 +110,36 @@ infinario.Track("my_player_action", ); infinario.Track("my_player_action", , ); ``` - +### Get Segment for player +To obtain player's segment information form segmentations you can use method GetCurrentSegment. +You have to specify projectSecret (this is different than projectToken - you can find it in project overview). +The second parameter is segmentationId (obtained from last part of url, when creating or viewing segments). +The last one is your callback method with 3 parameters: +- `boolean` type specifing if retrieving of segment was successfull +- `InfinarioSegment` type with the our desired information about players segment +- `string` information about errors that occured +``` + infinario.GetCurrentSegment(projectSecret, segmentationId, OnSegmentReceiveCallback); + + private void OnSegmentReceiveCallback(bool success, InfinarioSegment infinarioSegment, string error) + { + if (success) + { + Debug.Log(infinarioSegment); + // Do stuff according to segment type + } + else + { + Debug.LogError(error); + } + } +``` +InfinarioSegment class object returned in OnSegmentReceiveCallback contains public methods: +- `GetName()` returning string name of the segment where player belongs +- `GetSegmentationName()` returning string name of segmentation +- `GetSegmentIndex()` returns integer identifying the order of current segment in segmentation (starting with 0) + + ### Offline Behavior Once instantized, the SDK collects and sends all tracked events continuously to the Infinario servers. @@ -119,4 +148,4 @@ However, if your application goes offline, the SDK guarantees you to re-send the ## Final Remarks - Make sure you create at most one instance of ```Infinario``` during your application lifetime. -- If you wish to override some of the capabilities (e.g. session management), please note that we will not be able to give you any guarantees. \ No newline at end of file +- If you wish to override some of the capabilities (e.g. session management), please note that we will not be able to give you any guarantees. diff --git a/source/Assets/Scripts/InfinarioSDK/Constants.cs b/source/Assets/Scripts/InfinarioSDK/Constants.cs index 196b17e..461d333 100644 --- a/source/Assets/Scripts/InfinarioSDK/Constants.cs +++ b/source/Assets/Scripts/InfinarioSDK/Constants.cs @@ -6,15 +6,16 @@ internal class Constants * SDK */ public static string SDK = "Unity SDK"; - public static string VERSION = "2.0.2"; + public static string VERSION = "2.0.3"; /** * Tracking ids, events and properties */ public static string ID_REGISTERED = "registered"; public static string ID_COOKIE = "cookie"; - - public static string EVENT_SESSION_START = "session_start"; + public static string ID_USER = "user_id"; + + public static string EVENT_SESSION_START = "session_start"; public static string EVENT_SESSION_END = "session_end"; public static string EVENT_IDENTIFICATION = "identification"; public static string EVENT_VIRTUAL_PAYMENT = "virtual_payment"; @@ -42,10 +43,13 @@ internal class Constants public static long BULK_MAX = 60 * 20; public static double SESSION_TIMEOUT = 60; - - public static string DEFAULT_TARGET = "https://api.infinario.com"; + + public static string DEFAULT_SECRET = "X-Infinario-Secret"; + public static string DEFAULT_TARGET = "https://api.infinario.com"; public static string BULK_URL = "/bulk"; + public static string GET_SEGMENT_URL = "/analytics/segmentation-for"; + public static string ENDPOINT_UPDATE = "crm/customers"; public static string ENDPOINT_TRACK = "crm/events"; } diff --git a/source/Assets/Scripts/InfinarioSDK/Device.cs b/source/Assets/Scripts/InfinarioSDK/Device.cs index 983dfac..83db5d1 100644 --- a/source/Assets/Scripts/InfinarioSDK/Device.cs +++ b/source/Assets/Scripts/InfinarioSDK/Device.cs @@ -22,6 +22,7 @@ public static Dictionary GetProperties() private static string GetPlatform() { var platform = Application.platform; + var dict = new Dictionary { {RuntimePlatform.Android, "Android"}, {RuntimePlatform.IPhonePlayer, "iOS"}, @@ -29,14 +30,11 @@ private static string GetPlatform() {RuntimePlatform.WSAPlayerARM, "Windows Phone"}, {RuntimePlatform.WSAPlayerX64, "Windows Store"}, {RuntimePlatform.WSAPlayerX86, "Windows Store"}, - {RuntimePlatform.OSXDashboardPlayer, "Mac OS X"}, - {RuntimePlatform.OSXEditor, "Mac OS X"}, {RuntimePlatform.OSXPlayer, "Mac OS X"}, - {RuntimePlatform.OSXWebPlayer, "Mac OS X"}, + {RuntimePlatform.OSXEditor, "Mac OS X"}, {RuntimePlatform.WindowsEditor, "Unity Editor"}, {RuntimePlatform.WindowsPlayer, "Windows Standalone"}, - {RuntimePlatform.WP8Player, "Windows Phone"}, - {RuntimePlatform.WindowsWebPlayer, "Web Player"} + {RuntimePlatform.WebGLPlayer, "Web Player"} }; return (dict.ContainsKey (platform) ? dict [platform] : "Other"); } diff --git a/source/Assets/Scripts/InfinarioSDK/Infinario.cs b/source/Assets/Scripts/InfinarioSDK/Infinario.cs index 2a62c6d..62ea51a 100644 --- a/source/Assets/Scripts/InfinarioSDK/Infinario.cs +++ b/source/Assets/Scripts/InfinarioSDK/Infinario.cs @@ -1,3 +1,4 @@ +using System; using System.Collections; using System.Collections.Generic; using Infinario.Interface; @@ -32,8 +33,8 @@ public void Initialize(string projectToken) { Initialize (projectToken, null, null); } - - public void Initialize(string projectToken, string appVersion) + + public void Initialize(string projectToken, string appVersion) { Initialize (projectToken, appVersion, null); } @@ -125,5 +126,10 @@ public void SessionStatus(bool paused, Dictionary properties) } } + public void GetCurrentSegment(string projectSecret, string segmentationId, Action onSegmentReceiveCallback) + { + implementation.GetCurrentSegment(projectSecret, segmentationId, onSegmentReceiveCallback); + } + } } diff --git a/source/Assets/Scripts/InfinarioSDK/InfinarioInterface.cs b/source/Assets/Scripts/InfinarioSDK/InfinarioInterface.cs index 02747f8..8dff0f5 100644 --- a/source/Assets/Scripts/InfinarioSDK/InfinarioInterface.cs +++ b/source/Assets/Scripts/InfinarioSDK/InfinarioInterface.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; namespace Infinario.Interface { @@ -11,5 +12,6 @@ abstract class IInfinario public abstract void TrackSessionStart (Dictionary properties); public abstract void TrackSessionEnd (Dictionary properties); public abstract void TrackVirtualPayment (string currency, long amount, string itemName, string itemType); + public abstract void GetCurrentSegment (string projectSecret, string segmentaionId, Action onSegmentReceiveCallback); } } \ No newline at end of file diff --git a/source/Assets/Scripts/InfinarioSDK/InfinarioSegment.cs b/source/Assets/Scripts/InfinarioSDK/InfinarioSegment.cs new file mode 100644 index 0000000..a923986 --- /dev/null +++ b/source/Assets/Scripts/InfinarioSDK/InfinarioSegment.cs @@ -0,0 +1,39 @@ +using UnityEngine; +using System.Collections; +using System.Collections.Generic; +using System; + +namespace Infinario +{ + class InfinarioSegment + { + private string _name; + private string _analysis_name; + private int _index; + + public InfinarioSegment(string name, string analysisName, int index){ + this._name = name; + this._analysis_name = analysisName; + this._index = index; + } + + public string GetName(){ + return this._name; + } + + public string GetSegmentationName() + { + return this._analysis_name; + } + + public int? GetSegmentIndex() + { + return this._index; + } + + public override string ToString() + { + return "Segment: " + _name + ", Segment Index: " + _index + ", Segmentation name: " + _analysis_name; + } + } +} diff --git a/source/Assets/Scripts/InfinarioSDK/InfinarioUnitySDK.cs b/source/Assets/Scripts/InfinarioSDK/InfinarioUnitySDK.cs index 6fe12e0..f665d45 100644 --- a/source/Assets/Scripts/InfinarioSDK/InfinarioUnitySDK.cs +++ b/source/Assets/Scripts/InfinarioSDK/InfinarioUnitySDK.cs @@ -1,4 +1,5 @@ +using System; using System.Text; using System.Collections; using System.Collections.Generic; @@ -16,6 +17,7 @@ class Unity : IInfinario private string appVersion = null; private Dictionary deviceProperties = null; Dictionary customerIds = null; + private Sender.Sender sender; private static object initializeFinalizeLock = new object(); private static object sessionLock = new object(); @@ -33,23 +35,63 @@ public override void Initialize(string projectToken, string appVersion, string t commandQueue = new PersistentBulkCommandQueue ("events", Constants.BULK_LIMIT); - new Sender.Sender ((target != null) ? target : Constants.DEFAULT_TARGET, commandQueue); + sender = new Sender.Sender ((target != null) ? target : Constants.DEFAULT_TARGET, commandQueue); } public override void Identify(Dictionary customer, Dictionary properties) { - if (customer.ContainsKey (Constants.ID_REGISTERED) && customer[Constants.ID_REGISTERED] != null) - { - customerIds[Constants.ID_REGISTERED] = customer[Constants.ID_REGISTERED]; - - if (!customer[Constants.ID_REGISTERED].Equals(storage.GetRegisteredId())) + if ((customer.ContainsKey (Constants.ID_REGISTERED) && customer[Constants.ID_REGISTERED] != null) || + (customer.ContainsKey(Constants.ID_USER) && customer[Constants.ID_USER] != null)) + { + if (customer.ContainsKey(Constants.ID_REGISTERED)) + { + customerIds[Constants.ID_REGISTERED] = customer[Constants.ID_REGISTERED]; + } + else + { + if (customerIds.ContainsKey(Constants.ID_REGISTERED)) + { + customerIds.Remove(Constants.ID_REGISTERED); + } + } + if (customer.ContainsKey(Constants.ID_USER)) { - storage.SaveRegisteredId(customer[Constants.ID_REGISTERED].ToString()); - Dictionary mergedProperties = MergeAutomaticProperties(customer); + customerIds[Constants.ID_USER] = customer[Constants.ID_USER]; + } + else + { + if (customerIds.ContainsKey(Constants.ID_USER)) + { + customerIds.Remove(Constants.ID_USER); + } + } + + if ((customer.ContainsKey(Constants.ID_REGISTERED) && !customer[Constants.ID_REGISTERED].Equals(storage.GetRegisteredId())) || + (customer.ContainsKey(Constants.ID_USER) && !customer[Constants.ID_USER].Equals(storage.GetUserId()))) + { + if (customer.ContainsKey(Constants.ID_REGISTERED)) + { + storage.SaveRegisteredId(customer[Constants.ID_REGISTERED].ToString()); + } + else + { + storage.SaveRegisteredId(null); + } + if (customer.ContainsKey(Constants.ID_USER)) + { + storage.SaveUserId(customer[Constants.ID_USER].ToString()); + } + else + { + storage.SaveUserId(null); + } + Dictionary mergedProperties = MergeAutomaticProperties(customer); Track (Constants.EVENT_IDENTIFICATION, mergedProperties, double.NaN); - if (properties != null) + if (properties != null) + { Update(properties); + } } } } @@ -128,7 +170,12 @@ public override void TrackVirtualPayment(string currency, long amount, string it this.Track(Constants.EVENT_VIRTUAL_PAYMENT, properties, double.NaN); } - private Dictionary MergeAutomaticProperties(Dictionary properties) + public override void GetCurrentSegment(string projectSecret, string segmentaionId, Action onSegmentReceiveCallback) + { + sender.GetCurrentSegment(customerIds, projectSecret, segmentaionId, onSegmentReceiveCallback); + } + + private Dictionary MergeAutomaticProperties(Dictionary properties) { lock (initializeFinalizeLock) { @@ -151,5 +198,7 @@ private void ScheduleCommand(Command command) lst.Add (command.Execute()); commandQueue.MultiEnqueue(lst); } + + } } diff --git a/source/Assets/Scripts/InfinarioSDK/PersistentStorage.cs b/source/Assets/Scripts/InfinarioSDK/PersistentStorage.cs index 9194ee6..8b726e3 100644 --- a/source/Assets/Scripts/InfinarioSDK/PersistentStorage.cs +++ b/source/Assets/Scripts/InfinarioSDK/PersistentStorage.cs @@ -4,6 +4,7 @@ using Infinario.MiniJSON; using System; using System.Linq; +using System.Globalization; namespace Infinario.Storage { @@ -57,11 +58,28 @@ public string GetRegisteredId() } } - public void SaveSessionStart(double timestamp, Dictionary properties) + public void SaveUserId(string userId) + { + lock (lockAccess) + { + PlayerPrefs.SetString(Constants.ID_USER, userId); + } + } + + public string GetUserId() + { + lock (lockAccess) + { + var userId = PlayerPrefs.GetString(Constants.ID_USER); + return (String.IsNullOrEmpty(userId) ? null : userId); + } + } + + public void SaveSessionStart(double timestamp, Dictionary properties) { lock (lockAccess) { - PlayerPrefs.SetString (Constants.PROPERTY_SESSION_START_TIMESTAMP, timestamp.ToString()); + PlayerPrefs.SetString (Constants.PROPERTY_SESSION_START_TIMESTAMP, timestamp.ToString("R", CultureInfo.InvariantCulture)); PlayerPrefs.SetString (Constants.PROPERTY_SESSION_START_PROPERTIES, Json.Serialize(properties)); } } @@ -87,7 +105,7 @@ public void SaveSessionEnd(double timestamp, Dictionary properti { lock (lockAccess) { - PlayerPrefs.SetString (Constants.PROPERTY_SESSION_END_TIMESTAMP, timestamp.ToString()); + PlayerPrefs.SetString (Constants.PROPERTY_SESSION_END_TIMESTAMP, timestamp.ToString("R", CultureInfo.InvariantCulture)); PlayerPrefs.SetString (Constants.PROPERTY_SESSION_END_PROPERTIES, Json.Serialize(properties)); } } @@ -129,7 +147,11 @@ public Dictionary GetIds() var registered = GetRegisteredId (); if (!string.IsNullOrEmpty (registered)) ids.Add(Constants.ID_REGISTERED, registered); - return ids; + + var userid = GetUserId(); + if (!string.IsNullOrEmpty(userid)) + ids.Add(Constants.ID_USER, userid); + return ids; } } } diff --git a/source/Assets/Scripts/InfinarioSDK/Sender.cs b/source/Assets/Scripts/InfinarioSDK/Sender.cs index da26433..5869126 100644 --- a/source/Assets/Scripts/InfinarioSDK/Sender.cs +++ b/source/Assets/Scripts/InfinarioSDK/Sender.cs @@ -4,124 +4,211 @@ using Infinario.Storage; using Infinario.MiniJSON; using System.Text; +using System; +using UnityEngine.Networking; -namespace Infinario.Sender +namespace Infinario.Sender { - class Sender - { - public Sender(string target, PersistentBulkCommandQueue commandQueue) - { - this.StartCoroutine (APISendLoop(target, commandQueue)); - } - - protected MonoBehaviour _coroutineObject; - - protected void StartCoroutine(IEnumerator coroutine) - { - if (_coroutineObject == null) - { - var go = new GameObject("Infinario Coroutines"); - UnityEngine.Object.DontDestroyOnLoad(go); - _coroutineObject = go.AddComponent(); - } - _coroutineObject.StartCoroutine (coroutine); - } - - /// - /// Periodically performs the following steps: - /// 0. keep alive the session - // 1. collect the freshest command bulk - // 2. try-send bulk - // 3. validate response - // 4. parse response and enqueue for retry if needed - // 5. wait for N seconds (N grows with the number of consecutive connection failures) - /// - /// The send loop enumerator. - private IEnumerator APISendLoop(string target, PersistentBulkCommandQueue commandQueue) - { - const int WAIT_FOR_DEFAULT = 3; - var httpTarget = target + Constants.BULK_URL; - int consecutiveFailedRequests = 0; - - while (true) - { - // Decide if we process retry commands or new commands in this round - List commands = commandQueue.BulkDequeue(true); - - if (commands.Count > 0) - { - // 1B: Prepare the http components - var httpBody = Json.Serialize(new Dictionary {{"commands", commands}}); - byte[] httpBodyBytes = Encoding.UTF8.GetBytes(httpBody); - Dictionary httpHeaders = new Dictionary{ {"Content-type", "application/json"} }; - - // 2. Send the bulk API request - WWW req = new WWW(httpTarget, httpBodyBytes, httpHeaders); //TODO: we could add a timeout functionality - yield return req; - - // 3A: Check response for errors - if (!string.IsNullOrEmpty(req.error)) - { - consecutiveFailedRequests++; - } - else - { - // 3B. Parse the API response - var responseBody = req.text; - Dictionary apiResponse = (Dictionary) Json.Deserialize(responseBody); - bool success = (bool) apiResponse["success"]; - if(success) - { - consecutiveFailedRequests = 0; - - // 4A: extract retry-commands and queue them back (if any) - var retryCommands = ExtractRetryCommands(apiResponse,commands); - commandQueue.MultiDequeue(commands.Count); //remove every command from this request - commandQueue.MultiPush(retryCommands); //re-add failed commands with the highest priority - } - else - { - consecutiveFailedRequests++; - } - } - - } - - // 5. Detemine wait time and go idle. - float waitSeconds = (float)System.Math.Pow(WAIT_FOR_DEFAULT, System.Math.Sqrt(consecutiveFailedRequests+1)); - if(consecutiveFailedRequests == 0 && commandQueue.ElementCount > 0) - { - waitSeconds = 0f; - } - waitSeconds = System.Math.Min (waitSeconds, Constants.BULK_MAX - 3f); - - yield return new WaitForSeconds(waitSeconds); - } - } - - /// - /// Walks through the API response and returns all commands that should be retried. - /// - /// A list of retry command objects. - /// API response dictionary object. - /// Request dictionary object. - private List ExtractRetryCommands(Dictionary response,List sentCommands) - { - List commandResponses = response ["results"] as List; - - List retryCommands = new List (); - int idx = 0; - foreach (var cmdResponse in commandResponses) - { - var cmdResponseDict = (Dictionary)cmdResponse; - string status = (cmdResponseDict ["status"] as string).ToLower (); - if (status.Equals ("retry")) - { - retryCommands.Add (sentCommands[idx]); - } - idx++; - } - return retryCommands; - } + class InfinarioMonoBehaviour : MonoBehaviour + { + } + + class Sender + { + private string _target; + + public Sender(string target, PersistentBulkCommandQueue commandQueue) + { + this.StartCoroutine(APISendLoop(target, commandQueue)); + _target = target; + } + + protected MonoBehaviour _coroutineObject; + + protected void StartCoroutine(IEnumerator coroutine) + { + if (_coroutineObject == null) + { + var go = new GameObject("Infinario Coroutines"); + UnityEngine.Object.DontDestroyOnLoad(go); + _coroutineObject = go.AddComponent(); + } + _coroutineObject.StartCoroutine(coroutine); + } + + /// + /// Periodically performs the following steps: + /// 0. keep alive the session + // 1. collect the freshest command bulk + // 2. try-send bulk + // 3. validate response + // 4. parse response and enqueue for retry if needed + // 5. wait for N seconds (N grows with the number of consecutive connection failures) + /// + /// The send loop enumerator. + private IEnumerator APISendLoop(string target, PersistentBulkCommandQueue commandQueue) + { + const int WAIT_FOR_DEFAULT = 3; + var httpTarget = target + Constants.BULK_URL; + int consecutiveFailedRequests = 0; + + while (true) + { + // Decide if we process retry commands or new commands in this round + List commands = commandQueue.BulkDequeue(true); + + if (commands.Count > 0) + { + + // 1B: Prepare the http components + var httpBody = Json.Serialize(new Dictionary {{"commands", commands}}); + byte[] httpBodyBytes = Encoding.UTF8.GetBytes(httpBody); + + // 2. Send the bulk API request + UnityWebRequest req = new UnityWebRequest(httpTarget, "POST"); + req.uploadHandler = (UploadHandler) new UploadHandlerRaw(httpBodyBytes); + req.downloadHandler = (DownloadHandler) new DownloadHandlerBuffer(); + req.SetRequestHeader("Content-Type", "application/json"); + + yield return req.SendWebRequest(); + + + // 3A: Check response for errors + if (!string.IsNullOrEmpty(req.error)) + { + consecutiveFailedRequests++; + } + else + { + // 3B. Parse the API response + var responseBody = req.downloadHandler.text; + Dictionary apiResponse = + (Dictionary) Json.Deserialize(responseBody); + bool success = (bool) apiResponse["success"]; + if (success) + { + consecutiveFailedRequests = 0; + + // 4A: extract retry-commands and queue them back (if any) + var retryCommands = ExtractRetryCommands(apiResponse, commands); + commandQueue.MultiDequeue(commands.Count); //remove every command from this request + commandQueue.MultiPush(retryCommands); //re-add failed commands with the highest priority + } + else + { + consecutiveFailedRequests++; + } + } + + } + + // 5. Detemine wait time and go idle. + float waitSeconds = + (float) System.Math.Pow(WAIT_FOR_DEFAULT, System.Math.Sqrt(consecutiveFailedRequests + 1)); + if (consecutiveFailedRequests == 0 && commandQueue.ElementCount > 0) + { + waitSeconds = 0f; + } + waitSeconds = System.Math.Min(waitSeconds, Constants.BULK_MAX - 3f); + + yield return new WaitForSeconds(waitSeconds); + } + } + + /// + /// Walks through the API response and returns all commands that should be retried. + /// + /// A list of retry command objects. + /// API response dictionary object. + /// Request dictionary object. + private List ExtractRetryCommands(Dictionary response, List sentCommands) + { + List commandResponses = response["results"] as List; + + List retryCommands = new List(); + int idx = 0; + foreach (var cmdResponse in commandResponses) + { + var cmdResponseDict = (Dictionary) cmdResponse; + string status = (cmdResponseDict["status"] as string).ToLower(); + if (status.Equals("retry")) + { + retryCommands.Add(sentCommands[idx]); + } + idx++; + } + return retryCommands; + } + + + private IEnumerator GetCurrentSegmentCoroutine(Dictionary customerIds, string projectSecret, + string segmentationId, Action onSegmentReceiveCallback) + { + + + var httpTarget = (_target ?? Constants.DEFAULT_TARGET) + Constants.GET_SEGMENT_URL; + + // var httpBody = Json.Serialize(new Dictionary {{"commands", commands}}); + + + var body = new Dictionary() + { + {"customer_ids", customerIds}, + {"analysis_id", segmentationId} + }; + + var httpBody = Json.Serialize(body); + byte[] httpBodyBytes = Encoding.UTF8.GetBytes(httpBody); + + // 2. Send the bulk API request + UnityWebRequest req = new UnityWebRequest(httpTarget, "POST"); + req.uploadHandler = (UploadHandler) new UploadHandlerRaw(httpBodyBytes); + req.downloadHandler = (DownloadHandler) new DownloadHandlerBuffer(); + req.SetRequestHeader("Accept", "application/json"); + req.SetRequestHeader("Content-Type", "application/json"); + req.SetRequestHeader(Constants.DEFAULT_SECRET, projectSecret); + + yield return req.SendWebRequest(); + + + // Check response for errors + if (!string.IsNullOrEmpty(req.error)) + { + onSegmentReceiveCallback(false, null, req.error + "\n " + req.downloadHandler.text); + } + else + { + // Parse the API response + var responseBody = req.downloadHandler.text; + Dictionary apiResponse = (Dictionary) Json.Deserialize(responseBody); + bool success = (bool) apiResponse["success"]; + if (success) + { + var segmentName = apiResponse["segment"] as string; + var segmentationName = apiResponse["analysis_name"] as string; + var c = apiResponse["segment_index"]; + string error = ""; + int segmentIndex = -1; + try + { + segmentIndex = Convert.ToInt32(c); + } + catch (Exception exception) + { + error += exception.Message; + } + onSegmentReceiveCallback(true, new InfinarioSegment(segmentName, segmentationName, segmentIndex), error); + } + else + { + onSegmentReceiveCallback(false, null, "Unsuccessful segmentation request. Response text:\n"+req.downloadHandler.text); + } + } + } + + public void GetCurrentSegment(Dictionary customerIds, string projectSecret, string segmentaionId, Action onSegmentReceiveCallback) + { + StartCoroutine(GetCurrentSegmentCoroutine(customerIds,projectSecret,segmentaionId,onSegmentReceiveCallback)); + } } } diff --git a/source/Assets/Scripts/InfinarioSDK/Utils.cs b/source/Assets/Scripts/InfinarioSDK/Utils.cs index 111310d..f0668bd 100644 --- a/source/Assets/Scripts/InfinarioSDK/Utils.cs +++ b/source/Assets/Scripts/InfinarioSDK/Utils.cs @@ -10,8 +10,18 @@ public class Utils public static double GetCurrentTimestamp() { var t0 = DateTime.UtcNow; - var tEpoch = new DateTime(1970, 1, 1, 0, 0, 0); - return t0.Subtract(tEpoch).TotalMilliseconds / 1000.0; + + var tEpoch = new DateTime(1970, 1, 1, 0, 0, 0); + var tTime = t0.Subtract(tEpoch).TotalMilliseconds / 1000.0; + + var tSanityDateTime = new DateTime(2020, 1, 1, 0, 0, 0); + var tSanity = (tSanityDateTime.Subtract(tEpoch)).TotalMilliseconds / 1000.0; + while(tTime > tSanity) + { + tTime = tTime / 10.0; + } + + return tTime; } public static string GenerateCookieId()