private HttpWebRequest CreateRequest(string url, byte[] payloadData, bool gzip) { HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest; request.Method = "POST"; #if WINDOWS_UWP request.Headers[HttpRequestHeader.ContentLength] = payloadData.Length.ToString(); #elif WINDOWS_WSA //request.Headers[HttpRequestHeader.ContentLength] = payloadData.Length.ToString(); // Bug setting Content Length on WSA #else request.ContentLength = payloadData.Length; #endif if (gzip) { request.Headers[HttpRequestHeader.ContentEncoding] = "gzip"; } // create authorization hash String key = GAState.GameSecret; request.Headers[HttpRequestHeader.Authorization] = GAUtilities.HmacWithKey(key, payloadData); request.ContentType = "application/json"; return(request); }
public void TestValidateClientTs() { Assert.True(GAValidator.ValidateClientTs(GAUtilities.TimeIntervalSince1970())); Assert.False(GAValidator.ValidateClientTs(long.MinValue)); Assert.False(GAValidator.ValidateClientTs(long.MaxValue)); }
public static bool ValidateSdkWrapperVersion(string wrapperVersion) { if (!GAUtilities.StringMatch(wrapperVersion, "^(unity) [0-9]{0,5}(\\.[0-9]{0,5}){0,2}$")) { return(false); } return(true); }
public static bool ValidateEngineVersion(string engineVersion) { if (engineVersion == null || !GAUtilities.StringMatch(engineVersion, "^(unity) [0-9]{0,5}(\\.[0-9]{0,5}){0,2}$")) { return(false); } return(true); }
public static bool ValidateEventPartCharacters(string eventPart) { if (!GAUtilities.StringMatch(eventPart, "^[A-Za-z0-9\\s\\-_\\.\\(\\)\\!\\?]{1,64}$")) { return(false); } return(true); }
public static bool ValidateKeys(string gameKey, string gameSecret) { if (GAUtilities.StringMatch(gameKey, "^[A-z0-9]{32}$")) { if (GAUtilities.StringMatch(gameSecret, "^[A-z0-9]{40}$")) { return(true); } } return(false); }
public static bool ValidateCurrency(string currency) { if (string.IsNullOrEmpty(currency)) { return(false); } if (!GAUtilities.StringMatch(currency, "^[A-Z]{3}$")) { return(false); } return(true); }
public static bool ValidateEventIdCharacters(string eventId) { if (string.IsNullOrEmpty(eventId)) { return(false); } if (!GAUtilities.StringMatch(eventId, "^[A-Za-z0-9\\s\\-_\\.\\(\\)\\!\\?]{1,64}(:[A-Za-z0-9\\s\\-_\\.\\(\\)\\!\\?]{1,64}){0,4}$")) { return(false); } return(true); }
public static bool ValidateEventIdLength(string eventId) { if (string.IsNullOrEmpty(eventId)) { return(false); } if (!GAUtilities.StringMatch(eventId, "^[^:]{1,64}(?::[^:]{1,64}){0,4}$")) { return(false); } return(true); }
public static long GetClientTsAdjusted() { long clientTs = GAUtilities.TimeIntervalSince1970(); long clientTsAdjustedInteger = clientTs + Instance.ClientServerTimeOffset; if (GAValidator.ValidateClientTs(clientTsAdjustedInteger)) { return(clientTsAdjustedInteger); } else { return(clientTs); } }
private byte[] CreatePayloadData(string payload, bool gzip) { byte[] payloadData; if (gzip) { payloadData = GAUtilities.GzipCompress(payload); GALogger.D("Gzip stats. Size: " + Encoding.UTF8.GetBytes(payload).Length + ", Compressed: " + payloadData.Length + ", Content: " + payload); } else { payloadData = Encoding.UTF8.GetBytes(payload); } return(payloadData); }
public void SendSdkErrorEvent(EGASdkErrorType type) { if (!GAState.IsEventSubmissionEnabled) { return; } string gameKey = GAState.GameKey; string secretKey = GAState.GameSecret; // Validate if (!GAValidator.ValidateSdkErrorEvent(gameKey, secretKey, type)) { return; } // Generate URL string url = baseUrl + "/" + gameKey + "/" + eventsUrlPath; GALogger.D("Sending 'events' URL: " + url); string payloadJSONString = ""; JSONObject json = GAState.GetSdkErrorEventAnnotations(); string typeString = SdkErrorTypeToString(type); json.Add("type", typeString); List <JSONNode> eventArray = new List <JSONNode>(); eventArray.Add(json); payloadJSONString = GAUtilities.ArrayOfObjectsToJsonString(eventArray); if (string.IsNullOrEmpty(payloadJSONString)) { GALogger.W("sendSdkErrorEvent: JSON encoding failed."); return; } GALogger.D("sendSdkErrorEvent json: " + payloadJSONString); byte[] payloadData = Encoding.UTF8.GetBytes(payloadJSONString); SdkErrorTask sdkErrorTask = new SdkErrorTask(type, payloadData, secretKey); sdkErrorTask.Execute(url); }
public static bool ValidateResourceCurrencies(params string[] resourceCurrencies) { if (!ValidateArrayOfStrings(20, 64, false, "resource currencies", resourceCurrencies)) { return(false); } // validate each string for regex foreach (string resourceCurrency in resourceCurrencies) { if (!GAUtilities.StringMatch(resourceCurrency, "^[A-Za-z]+$")) { GALogger.I("resource currencies validation failed: a resource currency can only be A-Z, a-z. String was: " + resourceCurrency); return(false); } } return(true); }
public static JSONObject ValidateAndCleanCustomFields(IDictionary <string, object> fields) { JSONObject result = new JSONObject(); if (fields != null) { int count = 0; foreach (KeyValuePair <string, object> entry in fields) { if (entry.Key == null || entry.Value == null) { GALogger.W("ValidateAndCleanCustomFields: entry with key=" + entry.Key + ", value=" + entry.Value + " has been omitted because its key or value is null"); } else if (count < MaxCustomFieldsCount) { if (GAUtilities.StringMatch(entry.Key, "^[a-zA-Z0-9_]{1," + MaxCustomFieldsKeyLength + "}$")) { if (entry.Value is string || entry.Value is char) { string value = Convert.ToString(entry.Value); if (value.Length <= MaxCustomFieldsValueStringLength && value.Length > 0) { result[entry.Key] = value; ++count; } else { GALogger.W("ValidateAndCleanCustomFields: entry with key=" + entry.Key + ", value=" + entry.Value + " has been omitted because its value is an empty string or exceeds the max number of characters (" + MaxCustomFieldsValueStringLength + ")"); } } else if (entry.Value is double) { result[entry.Key] = new JSONNumber((double)entry.Value); ++count; } else if (entry.Value is float) { result[entry.Key] = new JSONNumber((float)entry.Value); ++count; } else if (entry.Value is long || entry.Value is ulong) { result[entry.Key] = new JSONNumber(Convert.ToInt64(entry.Value)); ++count; } else if (entry.Value is int || entry.Value is byte || entry.Value is sbyte || entry.Value is byte || entry.Value is uint || entry.Value is short || entry.Value is ushort) { result[entry.Key] = new JSONNumber(Convert.ToInt32(entry.Value)); ++count; } else { GALogger.W("ValidateAndCleanCustomFields: entry with key=" + entry.Key + ", value=" + entry.Value + " has been omitted because its value is not a string or number"); } } else { GALogger.W("ValidateAndCleanCustomFields: entry with key=" + entry.Key + ", value=" + entry.Value + " has been omitted because its key illegal characters, an empty or exceeds the max number of characters (" + MaxCustomFieldsKeyLength + ")"); } } else { GALogger.W("ValidateAndCleanCustomFields: entry with key=" + entry.Key + ", value=" + entry.Value + " has been omitted because it exceeds the max number of custom fields (" + MaxCustomFieldsCount + ")"); } } } return(result); }
public static bool ValidateConnectionType(string connectionType) { return(GAUtilities.StringMatch(connectionType, "^(wwan|wifi|lan|offline)$")); }
private static void AddEventToStore(JSONClass eventData) #endif { // Check if datastore is available if (!GAStore.IsTableReady) { GALogger.W("Could not add event: SDK datastore error"); return; } // Check if we are initialized if (!GAState.Initialized) { GALogger.W("Could not add event: SDK is not initialized"); return; } try { // Check db size limits (10mb) // If database is too large block all except user, session and business if (GAStore.IsDbTooLargeForEvents && !GAUtilities.StringMatch(eventData["category"].AsString, "^(user|session_end|business)$")) { GALogger.W("Database too large. Event has been blocked."); return; } // Get default annotations JSONClass ev = GAState.GetEventAnnotations(); // Create json with only default annotations string jsonDefaults = ev.SaveToBase64(); // Merge with eventData foreach (KeyValuePair <string, JSONNode> pair in eventData) { ev.Add(pair.Key, pair.Value); } // Create json string representation string json = ev.ToString(); // output if VERBOSE LOG enabled GALogger.II("Event added to queue: " + json); // Add to store Dictionary <string, object> parameters = new Dictionary <string, object>(); parameters.Add("$status", "new"); parameters.Add("$category", ev["category"].Value); parameters.Add("$session_id", ev["session_id"].Value); parameters.Add("$client_ts", ev["client_ts"].Value); parameters.Add("$event", ev.SaveToBase64()); string sql = "INSERT INTO ga_events (status, category, session_id, client_ts, event) VALUES($status, $category, $session_id, $client_ts, $event);"; GAStore.ExecuteQuerySync(sql, parameters); // Add to session store if not last if (eventData["category"].AsString.Equals(CategorySessionEnd)) { parameters.Clear(); parameters.Add("$session_id", ev["session_id"].Value); sql = "DELETE FROM ga_session WHERE session_id = $session_id;"; GAStore.ExecuteQuerySync(sql, parameters); } else { sql = "INSERT OR REPLACE INTO ga_session(session_id, timestamp, event) VALUES($session_id, $timestamp, $event);"; parameters.Clear(); parameters.Add("$session_id", ev["session_id"].Value); parameters.Add("$timestamp", GAState.SessionStart); parameters.Add("$event", jsonDefaults); GAStore.ExecuteQuerySync(sql, parameters); } } catch (Exception e) { GALogger.E("addEventToStoreWithEventData: error using json"); GALogger.E(e.ToString()); } }
public static bool HasAvailableResourceItemType(string itemType) { return(GAUtilities.StringArrayContainsString(AvailableResourceItemTypes, itemType)); }
public static bool HasAvailableResourceCurrency(string currency) { return(GAUtilities.StringArrayContainsString(AvailableResourceCurrencies, currency)); }
public static bool HasAvailableCustomDimensions03(string dimension3) { return(GAUtilities.StringArrayContainsString(AvailableCustomDimensions03, dimension3)); }
public static JSONArray ExecuteQuerySync(string sql, Dictionary <string, object> parameters, bool useTransaction) { // Force transaction if it is an update, insert or delete. if (GAUtilities.StringMatch(sql.ToUpperInvariant(), "^(UPDATE|INSERT|DELETE)")) { useTransaction = true; } // Get database connection from singelton sharedInstance SqliteConnection sqlDatabasePtr = Instance.SqlDatabase; // Create mutable array for results JSONArray results = new JSONArray(); SqliteTransaction transaction = null; SqliteCommand command = null; try { if (useTransaction) { transaction = sqlDatabasePtr.BeginTransaction(); } command = sqlDatabasePtr.CreateCommand(); if (useTransaction) { command.Transaction = transaction; } command.CommandText = sql; command.Prepare(); // Bind parameters if (parameters.Count != 0) { foreach (KeyValuePair <string, object> pair in parameters) { command.Parameters.AddWithValue(pair.Key, pair.Value); } } using (SqliteDataReader reader = command.ExecuteReader()) { // Loop through results while (reader.Read()) { // get columns count int columnCount = reader.FieldCount; JSONObject row = new JSONObject(); for (int i = 0; i < columnCount; i++) { string column = reader.GetName(i); if (string.IsNullOrEmpty(column)) { continue; } row[column] = reader.GetValue(i).ToString(); } results.Add(row); } } if (useTransaction) { transaction.Commit(); } } catch (SqliteException e) { // TODO(nikolaj): Should we do a db validation to see if the db is corrupt here? GALogger.E("SQLITE3 ERROR: " + e); results = null; if (useTransaction) { if (transaction != null) { try { transaction.Rollback(); } catch (SqliteException ex) { GALogger.E("SQLITE3 ROLLBACK ERROR: " + ex); } finally { transaction.Dispose(); } } } } finally { if (command != null) { command.Dispose(); } if (transaction != null) { transaction.Dispose(); } } // Return results return(results); }
public KeyValuePair <EGAHTTPApiResponse, JSONNode> SendEventsInArray(List <JSONNode> eventArray) #endif { JSONNode json; if (eventArray.Count == 0) { GALogger.D("sendEventsInArray called with missing eventArray"); } EGAHTTPApiResponse result = EGAHTTPApiResponse.NoResponse; string gameKey = GAState.GameKey; // Generate URL string url = baseUrl + "/" + gameKey + "/" + eventsUrlPath; GALogger.D("Sending 'events' URL: " + url); // make JSON string from data string JSONstring = GAUtilities.ArrayOfObjectsToJsonString(eventArray); if (JSONstring.Length == 0) { GALogger.D("sendEventsInArray JSON encoding failed of eventArray"); json = null; result = EGAHTTPApiResponse.JsonEncodeFailed; return(new KeyValuePair <EGAHTTPApiResponse, JSONNode>(result, json)); } string body = ""; HttpStatusCode responseCode = (HttpStatusCode)0; string responseDescription = ""; string authorization = ""; try { byte[] payloadData = CreatePayloadData(JSONstring, useGzip); HttpWebRequest request = CreateRequest(url, payloadData, useGzip); authorization = request.Headers[HttpRequestHeader.Authorization]; #if WINDOWS_UWP || WINDOWS_WSA using (Stream dataStream = await request.GetRequestStreamAsync()) #else using (Stream dataStream = request.GetRequestStream()) #endif { dataStream.Write(payloadData, 0, payloadData.Length); } #if WINDOWS_UWP || WINDOWS_WSA using (HttpWebResponse response = await request.GetResponseAsync() as HttpWebResponse) #else using (HttpWebResponse response = request.GetResponse() as HttpWebResponse) #endif { using (Stream dataStream = response.GetResponseStream()) { using (StreamReader reader = new StreamReader(dataStream)) { string responseString = reader.ReadToEnd(); responseCode = response.StatusCode; responseDescription = response.StatusDescription; // print result body = responseString; } } } } catch (WebException e) { if (e.Response != null) { using (HttpWebResponse response = (HttpWebResponse)e.Response) { using (Stream streamResponse = response.GetResponseStream()) { using (StreamReader streamRead = new StreamReader(streamResponse)) { string responseString = streamRead.ReadToEnd(); responseCode = response.StatusCode; responseDescription = response.StatusDescription; body = responseString; } } } } } catch (Exception e) { GALogger.E(e.ToString()); } GALogger.D("events request content: " + body); EGAHTTPApiResponse requestResponseEnum = ProcessRequestResponse(responseCode, responseDescription, body, "Events"); // if not 200 result if (requestResponseEnum != EGAHTTPApiResponse.Ok && requestResponseEnum != EGAHTTPApiResponse.BadRequest) { GALogger.D("Failed events Call. URL: " + url + ", Authorization: " + authorization + ", JSONString: " + JSONstring); json = null; result = requestResponseEnum; return(new KeyValuePair <EGAHTTPApiResponse, JSONNode>(result, json)); } // decode JSON JSONNode requestJsonDict = JSON.Parse(body); if (requestJsonDict == null) { json = null; result = EGAHTTPApiResponse.JsonDecodeFailed; return(new KeyValuePair <EGAHTTPApiResponse, JSONNode>(result, json)); } // print reason if bad request if (requestResponseEnum == EGAHTTPApiResponse.BadRequest) { GALogger.D("Failed Events Call. Bad request. Response: " + requestJsonDict.ToString()); } // return response json = requestJsonDict; result = requestResponseEnum; return(new KeyValuePair <EGAHTTPApiResponse, JSONNode>(result, json)); }
public static JSONArray ExecuteQuerySync(string sql, Dictionary <string, object> parameters, bool useTransaction) { #if !UNITY_EDITOR // Force transaction if it is an update, insert or delete. if (GAUtilities.StringMatch(sql.ToUpperInvariant(), "^(UPDATE|INSERT|DELETE)")) { useTransaction = true; } // Get database connection from singelton sharedInstance SqliteConnection sqlDatabasePtr = Instance.SqlDatabase; // Create mutable array for results JSONArray results = new JSONArray(); SqliteCommand command = null; try { if (useTransaction) { sqlDatabasePtr.BeginTransaction(); } command = sqlDatabasePtr.CreateCommand(); command.CommandText = sql; // Bind parameters if (parameters.Count != 0) { foreach (KeyValuePair <string, object> pair in parameters) { command.Bind(pair.Key, pair.Value); } } // Loop through results foreach (List <Tuple <string, string> > reader in command.ExecuteQueryMY()) { // get columns count int columnCount = reader.Count; JSONClass row = new JSONClass(); for (int i = 0; i < columnCount; i++) { string column = reader[i].Item1; if (string.IsNullOrEmpty(column)) { continue; } row[column] = reader[i].Item2.ToString(); } results.Add(row); } if (useTransaction) { //transaction.Commit(); sqlDatabasePtr.Commit(); } } catch (SqliteException e) { // TODO(nikolaj): Should we do a db validation to see if the db is corrupt here? GALogger.E("SQLITE3 ERROR: " + e); results = null; } finally { } // Return results return(results); #else return(null); #endif }
private static long CalculateServerTimeOffset(long serverTs) { long clientTs = GAUtilities.TimeIntervalSince1970(); return(serverTs - clientTs); }
public SdkErrorTask(EGASdkErrorType type, byte[] payloadData, string secretKey) { this.type = type; this.payloadData = payloadData; this.hashHmac = GAUtilities.HmacWithKey(secretKey, payloadData); }