public static void AddResourceEvent(EGAResourceFlowType flowType, string currency, double amount, string itemType, string itemId) { // Validate event params if (!GAValidator.ValidateResourceEvent(flowType, currency, (long)amount, itemType, itemId)) { GAHTTPApi.Instance.SendSdkErrorEvent(EGASdkErrorType.Rejected); return; } // If flow type is sink reverse amount if (flowType == EGAResourceFlowType.Sink) { amount *= -1; } // Create empty eventData JSONClass eventDict = new JSONClass(); // insert event specific values string flowTypeString = ResourceFlowTypeToString(flowType); eventDict["event_id"] = flowTypeString + ":" + currency + ":" + itemType + ":" + itemId; eventDict["category"] = CategoryResource; eventDict.Add("amount", new JSONData(amount)); // Add custom dimensions AddDimensionsToEvent(eventDict); // Log GALogger.I("Add RESOURCE event: {currency:" + currency + ", amount:" + amount + ", itemType:" + itemType + ", itemId:" + itemId + "}"); // Send to store AddEventToStore(eventDict); }
public static void AddErrorEvent(EGAErrorSeverity severity, string message) { string severityString = ErrorSeverityToString(severity); // Validate if (!GAValidator.ValidateErrorEvent(severity, message)) { GAHTTPApi.Instance.SendSdkErrorEvent(EGASdkErrorType.Rejected); return; } // Create empty eventData JSONClass eventData = new JSONClass(); // Append event specifics eventData["category"] = CategoryError; eventData["severity"] = severityString; eventData["message"] = message; // Log GALogger.I("Add ERROR event: {severity:" + severityString + ", message:" + message + "}"); // Send to store AddEventToStore(eventData); }
public static void AddDesignEvent(string eventId, double value, bool sendValue) { // Validate if (!GAValidator.ValidateDesignEvent(eventId, value)) { GAHTTPApi.Instance.SendSdkErrorEvent(EGASdkErrorType.Rejected); return; } // Create empty eventData JSONClass eventData = new JSONClass(); // Append event specifics eventData["category"] = CategoryDesign; eventData["event_id"] = eventId; if (sendValue) { eventData.Add("value", new JSONData(value)); } // Log GALogger.I("Add DESIGN event: {eventId:" + eventId + ", value:" + value + "}"); // Send to store AddEventToStore(eventData); }
public static void AddSessionStartEvent() { string categorySessionStart = CategorySessionStart; // Event specific data JSONClass eventDict = new JSONClass(); eventDict["category"] = categorySessionStart; // Increment session number and persist GAState.IncrementSessionNum(); GAStore.SetState(GAState.SessionNumKey, GAState.SessionNum.ToString(CultureInfo.InvariantCulture)); // Add custom dimensions AddDimensionsToEvent(eventDict); // Add to store AddEventToStore(eventDict); // Log GALogger.I("Add SESSION START event"); // Send event right away ProcessEvents(categorySessionStart, false); }
public static void AddErrorEvent(EGAErrorSeverity severity, string message, IDictionary <string, object> fields) { string severityString = ErrorSeverityToString(severity); // Validate if (!GAValidator.ValidateErrorEvent(severity, message)) { //GAHTTPApi.Instance.SendSdkErrorEvent(EGASdkErrorType.Rejected); return; } // Create empty eventData JSONObject eventData = new JSONObject(); // Append event specifics eventData["category"] = CategoryError; eventData["severity"] = severityString; eventData["message"] = message; // Add custom dimensions AddDimensionsToEvent(eventData); // Add custom fields AddFieldsToEvent(eventData, GAState.ValidateAndCleanCustomFields(fields)); // Log GALogger.I("Add ERROR event: {severity:" + severityString + ", message:" + message + "}"); // Send to store AddEventToStore(eventData); }
public static void AddDesignEvent(string eventId, double value, bool sendValue, IDictionary <string, object> fields) { // Validate if (!GAValidator.ValidateDesignEvent(eventId, value)) { //GAHTTPApi.Instance.SendSdkErrorEvent(EGASdkErrorType.Rejected); return; } // Create empty eventData JSONObject eventData = new JSONObject(); // Append event specifics eventData["category"] = CategoryDesign; eventData["event_id"] = eventId; if (sendValue) { eventData.Add("value", new JSONNumber(value)); } // Add custom dimensions AddDimensionsToEvent(eventData); // Add custom fields AddFieldsToEvent(eventData, GAState.ValidateAndCleanCustomFields(fields)); // Log GALogger.I("Add DESIGN event: {eventId:" + eventId + ", value:" + value + "}"); // Send to store AddEventToStore(eventData); }
public static void AddSessionStartEvent() { if (!GAState.IsEventSubmissionEnabled) { return; } string categorySessionStart = CategorySessionStart; // Event specific data JSONObject eventDict = new JSONObject(); eventDict["category"] = categorySessionStart; // Increment session number and persist GAState.IncrementSessionNum(); GAStore.SetState(GAState.SessionNumKey, GAState.SessionNum.ToString(CultureInfo.InvariantCulture)); // Add custom dimensions AddDimensionsToEvent(eventDict); IDictionary <string, object> fieldsToUse = GAState.CurrentGlobalCustomEventFields; // Add custom fields AddFieldsToEvent(eventDict, GAState.ValidateAndCleanCustomFields(fieldsToUse)); // Add to store AddEventToStore(eventDict); // Log GALogger.I("Add SESSION START event"); // Send event right away ProcessEvents(categorySessionStart, false); }
private static void FixMissingSessionEndEvents() { if (!GAState.IsEventSubmissionEnabled) { return; } // Get all sessions that are not current Dictionary <string, object> parameters = new Dictionary <string, object>(); parameters.Add("$session_id", GAState.SessionId); string sql = "SELECT timestamp, event FROM ga_session WHERE session_id != $session_id;"; JSONArray sessions = GAStore.ExecuteQuerySync(sql, parameters); if (sessions == null || sessions.Count == 0) { return; } GALogger.I(sessions.Count + " session(s) located with missing session_end event."); // Add missing session_end events for (int i = 0; i < sessions.Count; ++i) { JSONNode session = sessions[i]; JSONNode sessionEndEvent = null; try { sessionEndEvent = JSONNode.LoadFromBinaryBase64(session["event"].Value); } catch (Exception) { //GALogger.E("FixMissingSessionEndEvents: Error decoding json, " + e); } if (sessionEndEvent != null) { long event_ts = sessionEndEvent["client_ts"].AsLong; long start_ts = session["timestamp"].AsLong; long length = event_ts - start_ts; length = Math.Max(0, length); GALogger.D("fixMissingSessionEndEvents length calculated: " + length); sessionEndEvent["category"] = CategorySessionEnd; sessionEndEvent.Add("length", new JSONNumber(length)); // Add to store AddEventToStore(sessionEndEvent.AsObject); } else { GALogger.I("Problem decoding session_end event. Skipping this session_end event."); } } }
public static void AddSessionEndEvent() { long session_start_ts = GAState.SessionStart; long client_ts_adjusted = GAState.GetClientTsAdjusted(); long sessionLength = client_ts_adjusted - session_start_ts; if (sessionLength < 0) { // Should never happen. // Could be because of edge cases regarding time altering on device. GALogger.W("Session length was calculated to be less then 0. Should not be possible. Resetting to 0."); sessionLength = 0; } // Event specific data JSONClass eventDict = new JSONClass(); eventDict["category"] = CategorySessionEnd; eventDict.Add("length", new JSONData(sessionLength)); // Add custom dimensions AddDimensionsToEvent(eventDict); // Add to store AddEventToStore(eventDict); // Log GALogger.I("Add SESSION END event."); // Send all event right away ProcessEvents("", false); }
public static void SetBirthYear(int birthYear) { Instance.BirthYear = birthYear; if (GAStore.IsTableReady) { GAStore.SetState(BirthYearKey, birthYear.ToString()); } GALogger.I("Set birth year: " + birthYear); }
public static bool ValidateBirthyear(long birthYear) { if (birthYear < 0 || birthYear > 9999) { GALogger.I("Validation fail - birthYear: Cannot be (null) or invalid range."); return(false); } return(true); }
public static void SetCustomDimension03(string dimension) { CurrentCustomDimension03 = dimension; if (GAStore.IsTableReady) { GAStore.SetState(Dimension03Key, dimension); } GALogger.I("Set custom03 dimension value: " + dimension); }
public static bool ValidateGender(EGAGender gender) { if (gender == EGAGender.Undefined || !(gender == EGAGender.Male || gender == EGAGender.Female)) { GALogger.I("Validation fail - gender: Has to be 'male' or 'female'."); return(false); } return(true); }
public static bool ValidateFacebookId(string facebookId) { if (!ValidateString(facebookId, false)) { GALogger.I("Validation fail - facebook id: id cannot be (null), empty or above 64 characters."); return(false); } return(true); }
public static void SetFacebookId(string facebookId) { Instance.FacebookId = facebookId; if (GAStore.IsTableReady) { GAStore.SetState(FacebookIdKey, facebookId); } GALogger.I("Set facebook id: " + facebookId); }
public static void SetGender(EGAGender gender) { Instance.Gender = gender.ToString().ToLowerInvariant(); if (GAStore.IsTableReady) { GAStore.SetState(GenderKey, Instance.Gender); } GALogger.I("Set gender: " + gender); }
public static bool ValidateResourceEvent(EGAResourceFlowType flowType, string currency, long amount, string itemType, string itemId) { if (flowType == EGAResourceFlowType.Undefined) { GALogger.I("Validation fail - resource event - flowType: Invalid flow type."); return(false); } if (string.IsNullOrEmpty(currency)) { GALogger.I("Validation fail - resource event - currency: Cannot be (null)"); return(false); } if (!GAState.HasAvailableResourceCurrency(currency)) { GALogger.I("Validation fail - resource event - currency: Not found in list of pre-defined available resource currencies. String: " + currency); return(false); } if (!(amount > 0)) { GALogger.I("Validation fail - resource event - amount: Float amount cannot be 0 or negative. Value: " + amount); return(false); } if (string.IsNullOrEmpty(itemType)) { GALogger.I("Validation fail - resource event - itemType: Cannot be (null)"); return(false); } if (!ValidateEventPartLength(itemType, false)) { GALogger.I("Validation fail - resource event - itemType: Cannot be (null), empty or above 64 characters. String: " + itemType); return(false); } if (!ValidateEventPartCharacters(itemType)) { GALogger.I("Validation fail - resource event - itemType: Cannot contain other characters than A-z, 0-9, -_., ()!?. String: " + itemType); return(false); } if (!GAState.HasAvailableResourceItemType(itemType)) { GALogger.I("Validation fail - resource event - itemType: Not found in list of pre-defined available resource itemTypes. String: " + itemType); return(false); } if (!ValidateEventPartLength(itemId, false)) { GALogger.I("Validation fail - resource event - itemId: Cannot be (null), empty or above 64 characters. String: " + itemId); return(false); } if (!ValidateEventPartCharacters(itemId)) { GALogger.I("Validation fail - resource event - itemId: Cannot contain other characters than A-z, 0-9, -_., ()!?. String: " + itemId); return(false); } return(true); }
public static void AddResourceEvent(EGAResourceFlowType flowType, string currency, double amount, string itemType, string itemId, IDictionary <string, object> fields, bool mergeFields) { if (!GAState.IsEventSubmissionEnabled) { return; } // Validate event params if (!GAValidator.ValidateResourceEvent(flowType, currency, (long)amount, itemType, itemId)) { //GAHTTPApi.Instance.SendSdkErrorEvent(EGASdkErrorType.Rejected); return; } // If flow type is sink reverse amount if (flowType == EGAResourceFlowType.Sink) { amount *= -1; } // Create empty eventData JSONObject eventDict = new JSONObject(); // insert event specific values string flowTypeString = ResourceFlowTypeToString(flowType); eventDict["event_id"] = flowTypeString + ":" + currency + ":" + itemType + ":" + itemId; eventDict["category"] = CategoryResource; eventDict.Add("amount", new JSONNumber(amount)); // Add custom dimensions AddDimensionsToEvent(eventDict); IDictionary <string, object> fieldsToUse = new Dictionary <string, object>(fields != null && fields.Count > 0 ? fields : GAState.CurrentGlobalCustomEventFields); if (mergeFields && fields != null && fields.Count > 0) { foreach (KeyValuePair <string, object> pair in GAState.CurrentGlobalCustomEventFields) { if (!fieldsToUse.ContainsKey(pair.Key)) { fieldsToUse.Add(pair.Key, pair.Value); } } } // Add custom fields AddFieldsToEvent(eventDict, GAState.ValidateAndCleanCustomFields(fieldsToUse)); // Log GALogger.I("Add RESOURCE event: {currency:" + currency + ", amount:" + amount + ", itemType:" + itemType + ", itemId:" + itemId + "}"); // Send to store AddEventToStore(eventDict); }
public static void AddBusinessEvent( string currency, int amount, string itemType, string itemId, string cartType, IDictionary <string, object> fields ) { if (!GAState.IsEventSubmissionEnabled) { return; } // Validate event params if (!GAValidator.ValidateBusinessEvent(currency, amount, cartType, itemType, itemId)) { //GAHTTPApi.Instance.SendSdkErrorEvent(EGASdkErrorType.Rejected); return; } // Create empty eventData JSONObject eventDict = new JSONObject(); // Increment transaction number and persist GAState.IncrementTransactionNum(); GAStore.SetState(GAState.TransactionNumKey, GAState.TransactionNum.ToString(CultureInfo.InvariantCulture)); // Required eventDict["event_id"] = itemType + ":" + itemId; eventDict["category"] = CategoryBusiness; eventDict["currency"] = currency; eventDict.Add("amount", new JSONNumber(amount)); eventDict.Add(GAState.TransactionNumKey, new JSONNumber(GAState.TransactionNum)); // Optional if (!string.IsNullOrEmpty(cartType)) { eventDict.Add("cart_type", cartType); } // Add custom dimensions AddDimensionsToEvent(eventDict); // Add custom fields AddFieldsToEvent(eventDict, GAState.ValidateAndCleanCustomFields(fields)); // Log GALogger.I("Add BUSINESS event: {currency:" + currency + ", amount:" + amount + ", itemType:" + itemType + ", itemId:" + itemId + ", cartType:" + cartType + "}"); // Send to store AddEventToStore(eventDict); }
public static void AddErrorEvent(EGAErrorSeverity severity, string message, IDictionary <string, object> fields, bool mergeFields, bool skipAddingFields) { if (!GAState.IsEventSubmissionEnabled) { return; } string severityString = ErrorSeverityToString(severity); // Validate if (!GAValidator.ValidateErrorEvent(severity, message)) { //GAHTTPApi.Instance.SendSdkErrorEvent(EGASdkErrorType.Rejected); return; } // Create empty eventData JSONObject eventData = new JSONObject(); // Append event specifics eventData["category"] = CategoryError; eventData["severity"] = severityString; eventData["message"] = message; // Add custom dimensions AddDimensionsToEvent(eventData); if (!skipAddingFields) { IDictionary <string, object> fieldsToUse = new Dictionary <string, object>(fields != null && fields.Count > 0 ? fields : GAState.CurrentGlobalCustomEventFields); if (mergeFields && fields != null && fields.Count > 0) { foreach (KeyValuePair <string, object> pair in GAState.CurrentGlobalCustomEventFields) { if (!fieldsToUse.ContainsKey(pair.Key)) { fieldsToUse.Add(pair.Key, pair.Value); } } } // Add custom fields AddFieldsToEvent(eventData, GAState.ValidateAndCleanCustomFields(fieldsToUse)); } // Log GALogger.I("Add ERROR event: {severity:" + severityString + ", message:" + message + "}"); // Send to store AddEventToStore(eventData); }
private static void OnResuming(object sender, object e) { GAThreading.PerformTaskOnGAThread("onResuming", () => { if (!GAState.UseManualSessionHandling) { OnResume(); } else { GALogger.I("OnResuming: Not calling GameAnalytics.OnResume() as using manual session handling"); } }); }
public static bool ValidateErrorEvent(EGAErrorSeverity severity, string message) { if (severity == EGAErrorSeverity.Undefined) { GALogger.I("Validation fail - error event - severity: Severity was unsupported value."); return(false); } if (!ValidateLongString(message, true)) { GALogger.I("Validation fail - error event - message: Message cannot be above 8192 characters."); return(false); } return(true); }
public static bool ValidateSdkErrorEvent(string gameKey, string gameSecret, EGASdkErrorType type) { if (!ValidateKeys(gameKey, gameSecret)) { return(false); } if (type == EGASdkErrorType.Undefined) { GALogger.I("Validation fail - sdk error event - type: Type was unsupported value."); return(false); } return(true); }
public static bool ValidateArrayOfStrings(long maxCount, long maxStringLength, bool allowNoValues, string logTag, params string[] arrayOfStrings) { string arrayTag = logTag; // use arrayTag to annotate warning log if (string.IsNullOrEmpty(arrayTag)) { arrayTag = "Array"; } if (arrayOfStrings == null) { GALogger.I(arrayTag + " validation failed: array cannot be null. "); return(false); } // check if empty if (allowNoValues == false && arrayOfStrings.Length == 0) { GALogger.I(arrayTag + " validation failed: array cannot be empty. "); return(false); } // check if exceeding max count if (maxCount > 0 && arrayOfStrings.Length > maxCount) { GALogger.I(arrayTag + " validation failed: array cannot exceed " + maxCount + " values. It has " + arrayOfStrings.Length + " values."); return(false); } // validate each string foreach (string arrayString in arrayOfStrings) { int stringLength = arrayString == null ? 0 : arrayString.Length; // check if empty (not allowed) if (stringLength == 0) { GALogger.I(arrayTag + " validation failed: contained an empty string."); return(false); } // check if exceeding max length if (maxStringLength > 0 && stringLength > maxStringLength) { GALogger.I(arrayTag + " validation failed: a string exceeded max allowed length (which is: " + maxStringLength + "). String was: " + arrayString); return(false); } } return(true); }
private static void OnSuspending(object sender, SuspendingEventArgs e) { var deferral = e.SuspendingOperation.GetDeferral(); if (!GAState.UseManualSessionHandling) { OnStop(); } else { GALogger.I("OnSuspending: Not calling GameAnalytics.OnStop() as using manual session handling"); } deferral.Complete(); }
public static void AddDesignEvent(string eventId, double value, bool sendValue, IDictionary <string, object> fields, bool mergeFields) { if (!GAState.IsEventSubmissionEnabled) { return; } // Validate if (!GAValidator.ValidateDesignEvent(eventId, value)) { //GAHTTPApi.Instance.SendSdkErrorEvent(EGASdkErrorType.Rejected); return; } // Create empty eventData JSONObject eventData = new JSONObject(); // Append event specifics eventData["category"] = CategoryDesign; eventData["event_id"] = eventId; if (sendValue) { eventData.Add("value", new JSONNumber(value)); } // Add custom dimensions AddDimensionsToEvent(eventData); IDictionary <string, object> fieldsToUse = new Dictionary <string, object>(fields != null && fields.Count > 0 ? fields : GAState.CurrentGlobalCustomEventFields); if (mergeFields && fields != null && fields.Count > 0) { foreach (KeyValuePair <string, object> pair in GAState.CurrentGlobalCustomEventFields) { if (!fieldsToUse.ContainsKey(pair.Key)) { fieldsToUse.Add(pair.Key, pair.Value); } } } // Add custom fields AddFieldsToEvent(eventData, GAState.ValidateAndCleanCustomFields(fieldsToUse)); // Log GALogger.I("Add DESIGN event: {eventId:" + eventId + ", value:" + value + "}"); // Send to store AddEventToStore(eventData); }
public static void EndSessionAndStopQueue() { GAThreading.IgnoreTimer(Instance.SuspendBlockId); if (Initialized) { GALogger.I("Ending session."); GAEvents.StopEventQueue(); if (IsEnabled() && SessionIsStarted()) { GAEvents.AddSessionEndEvent(); SessionStart = 0; } GAThreading.StopThread(); } }
public static bool ValidateDesignEvent(string eventId, double value) { if (!ValidateEventIdLength(eventId)) { GALogger.I("Validation fail - design event - eventId: Cannot be (null) or empty. Only 5 event parts allowed seperated by :. Each part need to be 32 characters or less. String: " + eventId); return(false); } if (!ValidateEventIdCharacters(eventId)) { GALogger.I("Validation fail - design event - eventId: Non valid characters. Only allowed A-z, 0-9, -_., ()!?. String: " + eventId); return(false); } // value: allow 0, negative and nil (not required) return(true); }
public static void ProcessEvents(EGAHTTPApiResponse responseEnum, JSONNode dataDict, string putbackSql, string deleteSql, int eventCount) { if (responseEnum == EGAHTTPApiResponse.Ok) { // Delete events GAStore.ExecuteQuerySync(deleteSql); GALogger.I("Event queue: " + eventCount + " events sent."); } else { // Put events back (Only in case of no response) if (responseEnum == EGAHTTPApiResponse.NoResponse) { GALogger.W("Event queue: Failed to send events to collector - Retrying next time"); GAStore.ExecuteQuerySync(putbackSql); // Delete events (When getting some anwser back always assume events are processed) } else { if (dataDict != null) { JSONNode json = null; IEnumerator <JSONNode> enumerator = dataDict.Childs.GetEnumerator(); if (enumerator.MoveNext()) { json = enumerator.Current; } if (responseEnum == EGAHTTPApiResponse.BadRequest && json is JSONArray) { GALogger.W("Event queue: " + eventCount + " events sent. " + dataDict.Count + " events failed GA server validation."); } else { GALogger.W("Event queue: Failed to send events."); } } else { GALogger.W("Event queue: Failed to send events."); } GAStore.ExecuteQuerySync(deleteSql); } } UpdateSessionTime(); }
private static async Task WaitOnSuspend() { if (!GAState.UseManualSessionHandling) { OnSuspend(); while (!GAThreading.IsThreadFinished()) { await Task.Delay(100); } } else { GALogger.I("OnSuspending: Not calling GameAnalytics.OnStop() as using manual session handling"); } }