/// <summary> /// Starts the SDK. Call before sending events or making engagements. /// </summary> /// <param name="envKey">The unique environment key for this game environment.</param> /// <param name="collectURL">The Collect URL for this game.</param> /// <param name="engageURL">The Engage URL for this game.</param> /// <param name="userID">The user id for the player, if set to AUTO_GENERATED_USER_ID we create one for you.</param> public void StartSDK(string envKey, string collectURL, string engageURL, string userID) { lock (_lock) { Logger.LogInfo("Starting DDNA SDK"); if (!PlayerPrefs.HasKey(PF_KEY_USER_ID)) { Logger.LogDebug("No UserID key found in PlayerPrefs, starting from fresh."); } SetUserID(userID); this.EnvironmentKey = envKey; this.CollectURL = collectURL; // TODO: warn if no http is present, prepend it, although we support both this.EngageURL = engageURL; this.Platform = ClientInfo.Platform; this.SessionID = GetSessionID(); this.initialised = true; if (_launchNotificationEventParams != null) { RecordEvent("notificationOpened", _launchNotificationEventParams); _launchNotificationEventParams = null; } TriggerDefaultEvents(); // Setup automated event uploads if (Settings.BackgroundEventUpload && !IsInvoking("Upload")) { InvokeRepeating("Upload", Settings.BackgroundEventUploadStartDelaySeconds, Settings.BackgroundEventUploadRepeatRateSeconds); } } }
internal override void ForgetMe() { if (PlayerPrefs.HasKey(DDNA.PF_KEY_FORGOTTEN)) { Logger.LogDebug("Already forgotten user " + UserID); return; } Logger.LogDebug("Forgetting user " + UserID); PlayerPrefs.SetInt(DDNA.PF_KEY_FORGET_ME, 1); if (IsUploading) { return; } var advertisingId = PlayerPrefs.GetString(DDNA.PF_KEY_ADVERTISING_ID); var dictionary = new Dictionary <string, object>() { { "eventName", "ddnaForgetMe" }, { "eventTimestamp", GetCurrentTimestamp() }, { "eventUUID", Guid.NewGuid().ToString() }, { "sessionID", SessionID }, { "userID", UserID }, { "eventParams", new Dictionary <string, object>() { { "platform", Platform }, { "sdkVersion", Settings.SDK_VERSION }, { "ddnaAdvertisingId", advertisingId } } } }; if (string.IsNullOrEmpty(advertisingId)) { (dictionary["eventParams"] as Dictionary <string, object>) .Remove("ddnaAdvertisingId"); } string json; try { json = MiniJSON.Json.Serialize(dictionary); } catch (Exception e) { Logger.LogWarning("Unable to generate JSON for 'ddnaForgetMe' event. " + e.Message); return; } var url = (HashSecret != null) ? DDNA.FormatURI( Settings.COLLECT_HASH_URL_PATTERN.Replace("/bulk", ""), CollectURL, EnvironmentKey, DDNA.GenerateHash(json, HashSecret)) : DDNA.FormatURI( Settings.COLLECT_URL_PATTERN.Replace("/bulk", ""), CollectURL, EnvironmentKey, null); HttpRequest request = new HttpRequest(url) { HTTPMethod = HttpRequest.HTTPMethodType.POST, HTTPBody = json }; request.setHeader("Content-Type", "application/json"); StartCoroutine(Send( request, () => { Logger.LogDebug("Forgot user " + UserID); PlayerPrefs.SetInt(DDNA.PF_KEY_FORGOTTEN, 1); })); }
private void HandleSessionConfigurationCallback(JSONObject response) { if (response.Count > 0) { var parameters = response["parameters"]; if (parameters != null && parameters is JSONObject) { object dpWhitelist = null; (parameters as JSONObject).TryGetValue("dpWhitelist", out dpWhitelist); if (dpWhitelist != null && dpWhitelist is List <object> ) { whitelistDps = new ReadOnlyCollection <string>( (dpWhitelist as List <object>) .Select(e => e as string) .ToList()); } object eventsWhitelist = null; (parameters as JSONObject).TryGetValue("eventsWhitelist", out eventsWhitelist); if (eventsWhitelist != null && eventsWhitelist is List <object> ) { whitelistEvents = new ReadOnlyCollection <string>( (eventsWhitelist as List <object>) .Select(e => e as string) .ToList()); } object triggers = null; (parameters as JSONObject).TryGetValue("triggers", out triggers); if (triggers != null && triggers is List <object> ) { eventTriggers = (triggers as List <object>) .Select((e, i) => { var t = new EventTrigger(this, i, e as JSONObject); // save persistent actions var p = t.GetResponse().GetOrDefault("parameters", new JSONObject()); if (p.GetOrDefault("ddnaIsPersistent", false)) { actionStore.Put(t, p); } return(t); }) .GroupBy(e => e.GetEventName()) .ToDictionary(e => e.Key, e => { var list = e.ToList(); list.Sort(); return(new ReadOnlyCollection <EventTrigger>(list)); }); } object imageCache = null; (parameters as JSONObject).TryGetValue("imageCache", out imageCache); if (imageCache != null && imageCache is List <object> ) { cacheImages = new ReadOnlyCollection <string>( (imageCache as List <object>) .Select(e => e as string) .ToList()); DownloadImageAssets(); } #if DDNA_SMARTADS SmartAds.Instance.RegisterForAdsInternal(response); #endif Logger.LogDebug("Session configured"); object cached = null; (parameters as JSONObject).TryGetValue("isCachedResponse", out cached); if (cached != null && cached is bool) { ddna.NotifyOnSessionConfigured(cached as bool? ?? false); } else { ddna.NotifyOnSessionConfigured(false); } } } else { Logger.LogWarning("Session configuration failed"); ddna.NotifyOnSessionConfigurationFailed(); } }
private void TriggerDefaultEvents(bool newPlayer) { if (Settings.OnFirstRunSendNewPlayerEvent && newPlayer) { Logger.LogDebug("Sending 'newPlayer' event"); var newPlayerEvent = new GameEvent("newPlayer"); if (ClientInfo.CountryCode != null) { newPlayerEvent.AddParam("userCountry", ClientInfo.CountryCode); } RecordEvent(newPlayerEvent); } if (Settings.OnInitSendGameStartedEvent) { Logger.LogDebug("Sending 'gameStarted' event"); var gameStartedEvent = new GameEvent("gameStarted") .AddParam("clientVersion", this.ClientVersion) .AddParam("userLocale", ClientInfo.Locale); if (!string.IsNullOrEmpty(CrossGameUserID)) { gameStartedEvent.AddParam("ddnaCrossGameUserID", CrossGameUserID); } if (!String.IsNullOrEmpty(this.PushNotificationToken)) { gameStartedEvent.AddParam("pushNotificationToken", this.PushNotificationToken); } if (!String.IsNullOrEmpty(this.AndroidRegistrationID)) { gameStartedEvent.AddParam("androidRegistrationID", this.AndroidRegistrationID); } RecordEvent(gameStartedEvent); } if (Settings.OnInitSendClientDeviceEvent) { Logger.LogDebug("Sending 'clientDevice' event"); var clientDeviceEvent = new GameEvent("clientDevice") .AddParam("deviceName", ClientInfo.DeviceName) .AddParam("deviceType", ClientInfo.DeviceType) .AddParam("hardwareVersion", ClientInfo.DeviceModel) .AddParam("operatingSystem", ClientInfo.OperatingSystem) .AddParam("operatingSystemVersion", ClientInfo.OperatingSystemVersion) .AddParam("timezoneOffset", ClientInfo.TimezoneOffset) .AddParam("userLanguage", ClientInfo.LanguageCode); if (ClientInfo.Manufacturer != null) { clientDeviceEvent.AddParam("manufacturer", ClientInfo.Manufacturer); } RecordEvent(clientDeviceEvent); } }
override internal void RecordPushNotification(Dictionary <string, object> payload) { Logger.LogDebug("Received push notification: " + payload); var notificationEvent = new GameEvent("notificationOpened"); try { if (payload.ContainsKey("_ddId")) { notificationEvent.AddParam("notificationId", Convert.ToInt64(payload["_ddId"])); } if (payload.ContainsKey("_ddName")) { notificationEvent.AddParam("notificationName", payload["_ddName"]); } bool insertCommunicationAttrs = false; if (payload.ContainsKey("_ddCampaign")) { notificationEvent.AddParam("campaignId", Convert.ToInt64(payload["_ddCampaign"])); insertCommunicationAttrs = true; } if (payload.ContainsKey("_ddCohort")) { notificationEvent.AddParam("cohortId", Convert.ToInt64(payload["_ddCohort"])); insertCommunicationAttrs = true; } if (insertCommunicationAttrs && payload.ContainsKey("_ddCommunicationSender")) { // _ddCommunicationSender inserted by respective native notification SDK notificationEvent.AddParam("communicationSender", payload["_ddCommunicationSender"]); notificationEvent.AddParam("communicationState", "OPEN"); } if (payload.ContainsKey("_ddLaunch")) { // _ddLaunch inserted by respective native notification SDK notificationEvent.AddParam("notificationLaunch", Convert.ToBoolean(payload["_ddLaunch"])); } if (payload.ContainsKey("_ddCampaign")) { notificationEvent.AddParam("campaignId", Convert.ToInt64(payload["_ddCampaign"])); } if (payload.ContainsKey("_ddCohort")) { notificationEvent.AddParam("cohortId", Convert.ToInt64(payload["_ddCohort"])); } notificationEvent.AddParam("communicationState", "OPEN"); } catch (Exception ex) { Logger.LogError("Error parsing push notification payload. " + ex.Message); } if (this.started) { this.RecordEvent(notificationEvent); } else { this.launchNotificationEvent = notificationEvent; } }
///<summary> /// When unity quits, it destroys objects in a random order. /// In principle, a Singleton is only destroyed when application quits. /// If any script calls Instance after it have been destroyed, /// it will create a buggy ghost object that will stay on the Editor scene /// even after stopping playing the Application. Really bad! /// So, this was made to be sure we're not creating that buggy ghost object. /// </summary> public virtual void OnDestroy() { Logger.LogDebug("[Singleton] Destroying an instance of " + typeof(T)); applicationIsQuitting = true; }
private IEnumerator EngageCoroutine(string decisionPoint, Dictionary <string, object> engageParams, Action <Dictionary <string, object> > callback) { Logger.LogDebug("Starting engagement for '" + decisionPoint + "'"); Dictionary <string, object> engageRequest = new Dictionary <string, object>() { { "userID", this.UserID }, { "decisionPoint", decisionPoint }, { "sessionID", this.SessionID }, { "version", Settings.ENGAGE_API_VERSION }, { "sdkVersion", Settings.SDK_VERSION }, { "platform", this.Platform }, { "timezoneOffset", Convert.ToInt32(ClientInfo.TimezoneOffset) } }; if (ClientInfo.Locale != null) { engageRequest.Add("locale", ClientInfo.Locale); } if (engageParams != null) { engageRequest.Add("parameters", engageParams); } string engageJSON = null; try { engageJSON = MiniJSON.Json.Serialize(engageRequest); } catch (Exception e) { Logger.LogWarning("Problem serialising engage request data: " + e.Message); yield break; } Action <string> requestCb = (response) => { bool cachedResponse = false; if (response != null) { Logger.LogDebug("Using live engagement: " + response); this.engageArchive[decisionPoint] = response; } else { if (this.engageArchive.Contains(decisionPoint)) { Logger.LogWarning("Engage request failed, using cached response."); cachedResponse = true; response = this.engageArchive[decisionPoint]; } else { Logger.LogWarning("Engage request failed"); } } Dictionary <string, object> result = MiniJSON.Json.Deserialize(response) as Dictionary <string, object>; if (cachedResponse) { result["isCachedResponse"] = cachedResponse; } if (callback != null) { callback(result); } }; yield return(StartCoroutine(EngageRequest(engageJSON, requestCb))); }