diff --git a/.pubnub.yml b/.pubnub.yml index ba38a0dc..d2f13270 100644 --- a/.pubnub.yml +++ b/.pubnub.yml @@ -1,6 +1,13 @@ --- -version: v8.0.1 +version: v8.1.0 changelog: + - date: 2025-02-04 + version: v8.1.0 + changes: + - type: feature + text: "Added new optional parameter IfMatchesEtag for setUUIDMetadata and setChannelMetadata. When provided, the server compares the argument value with the eTag on the server and if they don't match a HTTP 412 error is returned." + - type: bug + text: "Fixes issue of not getting PNSubscriptionChangedCategory status when subscription change happens." - date: 2025-01-20 version: v8.0.1 changes: @@ -748,7 +755,7 @@ sdks: distribution-type: package distribution-repository: git release package-name: PubNub.unitypackage - location: https://github.com/pubnub/unity/releases/download/v8.0.1/PubNub.unitypackage + location: https://github.com/pubnub/unity/releases/download/v8.1.0/PubNub.unitypackage requires: - name: "UnityEditor" @@ -915,7 +922,7 @@ sdks: distribution-type: package distribution-repository: git release package-name: PubNub.unitypackage - location: https://github.com/pubnub/unity/releases/download/v8.0.1/PubNub.unitypackage + location: https://github.com/pubnub/unity/releases/download/v8.1.0/PubNub.unitypackage requires: - name: "UnityEditor" diff --git a/PubNubUnity/Assets/PubNub/Runtime/Plugins/PubnubApiUnity.dll b/PubNubUnity/Assets/PubNub/Runtime/Plugins/PubnubApiUnity.dll index e0a983c7..16a31755 100644 Binary files a/PubNubUnity/Assets/PubNub/Runtime/Plugins/PubnubApiUnity.dll and b/PubNubUnity/Assets/PubNub/Runtime/Plugins/PubnubApiUnity.dll differ diff --git a/PubNubUnity/Assets/PubNub/Runtime/Util/NewtonsoftJsonUnity.cs b/PubNubUnity/Assets/PubNub/Runtime/Util/NewtonsoftJsonUnity.cs index 26ad4ba8..8ade7379 100644 --- a/PubNubUnity/Assets/PubNub/Runtime/Util/NewtonsoftJsonUnity.cs +++ b/PubNubUnity/Assets/PubNub/Runtime/Util/NewtonsoftJsonUnity.cs @@ -8,471 +8,652 @@ using Newtonsoft.Json.Linq; namespace PubnubApi.Unity.PubNub.Runtime.Util { - public class NewtonsoftJsonUnity : IJsonPluggableLibrary { - private readonly PNConfiguration config; - private readonly IPubnubLog pubnubLog; - private readonly JsonSerializerSettings defaultJsonSerializerSettings; - - public NewtonsoftJsonUnity(PNConfiguration pubnubConfig, IPubnubLog log) { - this.config = pubnubConfig; - this.pubnubLog = log; - defaultJsonSerializerSettings = new JsonSerializerSettings { MaxDepth = 64 }; - } - - #region IJsonPlugableLibrary methods implementation - - private static bool IsValidJson(string jsonString, PNOperationType operationType) { - bool ret = false; - try { - if (operationType == PNOperationType.PNPublishOperation - || operationType == PNOperationType.PNHistoryOperation - || operationType == PNOperationType.PNTimeOperation - || operationType == PNOperationType.PNPublishFileMessageOperation) { - JArray.Parse(jsonString); - } else { - JObject.Parse(jsonString); - } - - ret = true; - } catch { - try { - if (operationType == PNOperationType.PNPublishOperation - || operationType == PNOperationType.PNHistoryOperation - || operationType == PNOperationType.PNTimeOperation - || operationType == PNOperationType.PNPublishFileMessageOperation) { - JObject.Parse(jsonString); - ret = true; - } - } catch { - /* igonore */ - } - } - - return ret; - } - - public object BuildJsonObject(string jsonString) { - object ret = null; - - try { - var token = JToken.Parse(jsonString); - ret = token; - } catch { - /* ignore */ - } - - return ret; - } - - public bool IsDictionaryCompatible(string jsonString, PNOperationType operationType) { - bool ret = false; - if (JsonFastCheck(jsonString) && IsValidJson(jsonString, operationType)) { - try { - using (StringReader strReader = new StringReader(jsonString)) { - using (JsonTextReader jsonTxtreader = new JsonTextReader(strReader)) { - while (jsonTxtreader.Read()) { - if (jsonTxtreader.LineNumber == 1 && jsonTxtreader.LinePosition == 1 && - jsonTxtreader.TokenType == JsonToken.StartObject) { - ret = true; - break; - } else { - break; - } - } - - jsonTxtreader.Close(); - } + public class NewtonsoftJsonUnity : IJsonPluggableLibrary + { + private readonly PNConfiguration config; + private readonly IPubnubLog pubnubLog; + private readonly JsonSerializerSettings defaultJsonSerializerSettings; + + public NewtonsoftJsonUnity(PNConfiguration pubnubConfig, IPubnubLog log) + { + this.config = pubnubConfig; + this.pubnubLog = log; + defaultJsonSerializerSettings = new JsonSerializerSettings { MaxDepth = 64 }; + } + + #region IJsonPlugableLibrary methods implementation + + private static bool IsValidJson(string jsonString, PNOperationType operationType) + { + bool ret = false; + try + { + if (operationType == PNOperationType.PNPublishOperation + || operationType == PNOperationType.PNHistoryOperation + || operationType == PNOperationType.PNTimeOperation + || operationType == PNOperationType.PNPublishFileMessageOperation) + { + JArray.Parse(jsonString); + } + else + { + JObject.Parse(jsonString); + } + + ret = true; + } + catch + { + try + { + if (operationType == PNOperationType.PNPublishOperation + || operationType == PNOperationType.PNHistoryOperation + || operationType == PNOperationType.PNTimeOperation + || operationType == PNOperationType.PNPublishFileMessageOperation) + { + JObject.Parse(jsonString); + ret = true; + } + } + catch + { + /* igonore */ + } + } + + return ret; + } + + public object BuildJsonObject(string jsonString) + { + object ret = null; + + try + { + var token = JToken.Parse(jsonString); + ret = token; + } + catch + { + /* ignore */ + } + + return ret; + } + + public bool IsDictionaryCompatible(string jsonString, PNOperationType operationType) + { + bool ret = false; + if (JsonFastCheck(jsonString) && IsValidJson(jsonString, operationType)) + { + try + { + using (StringReader strReader = new StringReader(jsonString)) + { + using (JsonTextReader jsonTxtreader = new JsonTextReader(strReader)) + { + while (jsonTxtreader.Read()) + { + if (jsonTxtreader.LineNumber == 1 && jsonTxtreader.LinePosition == 1 && + jsonTxtreader.TokenType == JsonToken.StartObject) + { + ret = true; + break; + } + else + { + break; + } + } + + jsonTxtreader.Close(); + } #if (NET35 || NET40 || NET45 || NET461 || NET48) strReader.Close(); #endif - } - } catch { - /* ignore */ - } - } - - return ret; - } - - public string SerializeToJsonString(object objectToSerialize) { - return JsonConvert.SerializeObject(objectToSerialize, defaultJsonSerializerSettings); - } - - public List DeserializeToListOfObject(string jsonString) { - List result = - JsonConvert.DeserializeObject>(jsonString, defaultJsonSerializerSettings); - - return result; - } - - public object DeserializeToObject(object rawObject, Type type) { - try { - if (rawObject is JObject jObject) { - return jObject.ToObject(type); - } else { - return rawObject; - } - } catch (Exception e) { - LoggingMethod.WriteToLog(pubnubLog, e.ToString(), config.LogVerbosity); - return rawObject; - } - } - - public object DeserializeToObject(string jsonString) { - object result = JsonConvert.DeserializeObject(jsonString, - new JsonSerializerSettings { DateParseHandling = DateParseHandling.None, MaxDepth = 64 }); - if (result.GetType().ToString() == "Newtonsoft.Json.Linq.JArray") { - JArray jarrayResult = result as JArray; - List objectContainer = jarrayResult.ToObject>(); - if (objectContainer != null && objectContainer.Count > 0) { - for (int index = 0; index < objectContainer.Count; index++) { - if (objectContainer[index].GetType().ToString() == "Newtonsoft.Json.Linq.JArray") { - JArray internalItem = objectContainer[index] as JArray; - objectContainer[index] = internalItem.Select(item => (object)item).ToArray(); - } - } - - result = objectContainer; - } - } - - return result; - } - - public void PopulateObject(string value, object target) { - JsonConvert.PopulateObject(value, target, defaultJsonSerializerSettings); - } - - public virtual T DeserializeToObject(string jsonString) { - T ret = default(T); - - try { - ret = JsonConvert.DeserializeObject(jsonString, - new JsonSerializerSettings { DateParseHandling = DateParseHandling.None, MaxDepth = 64 }); - } catch { - /* ignore */ - } - - return ret; - } - - private bool IsGenericTypeForMessage() { - bool ret = false; - if (typeof(T).GetTypeInfo().IsGenericType && - typeof(T).GetGenericTypeDefinition() == typeof(PNMessageResult<>)) { - ret = true; - } - - LoggingMethod.WriteToLog(pubnubLog, - string.Format(CultureInfo.InvariantCulture, - "DateTime: {0}, typeof(T).GetTypeInfo().IsGenericType = {1}", - DateTime.Now.ToString(CultureInfo.InvariantCulture), - typeof(T).GetTypeInfo().IsGenericType.ToString()), config.LogVerbosity); - if (typeof(T).GetTypeInfo().IsGenericType) { - LoggingMethod.WriteToLog(pubnubLog, - string.Format(CultureInfo.InvariantCulture, - "DateTime: {0}, typeof(T).GetGenericTypeDefinition() = {1}", - DateTime.Now.ToString(CultureInfo.InvariantCulture), - typeof(T).GetGenericTypeDefinition().ToString()), config.LogVerbosity); - } - - LoggingMethod.WriteToLog(pubnubLog, - string.Format(CultureInfo.InvariantCulture, "DateTime: {0}, IsGenericTypeForMessage = {1}", - DateTime.Now.ToString(CultureInfo.InvariantCulture), ret.ToString()), config.LogVerbosity); - return ret; - } - - private T DeserializeMessageToObjectBasedOnPlatform(List listObject) { - T ret = default(T); - Type dataType = typeof(T).GetTypeInfo().GenericTypeArguments[0]; - Type generic = typeof(PNMessageResult<>); - Type specific = generic.MakeGenericType(dataType); - - ConstructorInfo ci = specific.GetTypeInfo().DeclaredConstructors.FirstOrDefault(); - if (ci != null) { - object message = ci.Invoke(new object[] { }); - - //Set data - PropertyInfo dataProp = specific.GetRuntimeProperty("Message"); - - object userMessage = null; - if (listObject[0].GetType() == typeof(JValue)) { - JValue jsonValue = listObject[0] as JValue; - userMessage = jsonValue.Value; - userMessage = ConvertToDataType(dataType, userMessage); - - dataProp.SetValue(message, userMessage, null); - } else if (listObject[0].GetType() == typeof(JObject) || - listObject[0].GetType() == typeof(JArray)) { - JToken token = listObject[0] as JToken; - if (dataProp.PropertyType == typeof(string)) { - userMessage = JsonConvert.SerializeObject(token, defaultJsonSerializerSettings); - } else { - userMessage = token.ToObject(dataProp.PropertyType, JsonSerializer.Create()); - } - - dataProp.SetValue(message, userMessage, null); - } else if (listObject[0].GetType() == typeof(System.String)) { - userMessage = listObject[0] as string; - dataProp.SetValue(message, userMessage, null); - } - - //Set Time - PropertyInfo timeProp = specific.GetRuntimeProperty("Timetoken"); - long timetoken; - Int64.TryParse(listObject[2].ToString(), out timetoken); - timeProp.SetValue(message, timetoken, null); - - //Set Publisher - PropertyInfo publisherProp = specific.GetRuntimeProperty("Publisher"); - string publisherValue = (listObject[3] != null) ? listObject[3].ToString() : ""; - publisherProp.SetValue(message, publisherValue, null); - - // Set ChannelName - PropertyInfo channelNameProp = specific.GetRuntimeProperty("Channel"); - channelNameProp.SetValue(message, listObject[5]?.ToString(), null); - - // Set ChannelGroup - PropertyInfo subsciptionProp = specific.GetRuntimeProperty("Subscription"); - subsciptionProp.SetValue(message, listObject[4]?.ToString(), null); - - PropertyInfo customMessageType = specific.GetRuntimeProperty("CustomMessageType"); - customMessageType.SetValue(message, listObject[6], null); - //Set Metadata list second position, index=1 - if (listObject[1] != null) { - PropertyInfo userMetadataProp = specific.GetRuntimeProperty("UserMetadata"); - userMetadataProp.SetValue(message, listObject[1], null); - } - - - ret = (T)Convert.ChangeType(message, specific, CultureInfo.InvariantCulture); - } - - return ret; - } - - public virtual T DeserializeToObject(List listObject) { - T ret = default(T); - - if (listObject == null) { - return ret; - } - - if (IsGenericTypeForMessage()) { - #region "Subscribe Message<>" - - return DeserializeMessageToObjectBasedOnPlatform(listObject); - - #endregion - } else { - return DeserializeToInternalObjectUtility.DeserializeToInternalObject(this, listObject); - } - } - - public Dictionary DeserializeToDictionaryOfObject(string jsonString) { - Dictionary result = null; - try { - if (JsonFastCheck(jsonString)) { - result = JsonConvert.DeserializeObject>(jsonString, - defaultJsonSerializerSettings); - } - } catch { - //ignore - } - - return result; - } - - public Dictionary ConvertToDictionaryObject(object localContainer) { - Dictionary ret = null; - - try { - if (localContainer != null) { - if (localContainer.GetType().ToString() == "Newtonsoft.Json.Linq.JObject") { - ret = new Dictionary(); - - IDictionary jsonDictionary = localContainer as JObject; - if (jsonDictionary != null) { - foreach (KeyValuePair pair in jsonDictionary) { - JToken token = pair.Value; - ret.Add(pair.Key, ConvertJTokenToObject(token)); - } - } - } else if (localContainer.GetType().ToString() == - "System.Collections.Generic.Dictionary`2[System.String,System.Object]") { - ret = new Dictionary(); - Dictionary dictionary = localContainer as Dictionary; - foreach (string key in dictionary.Keys) { - ret.Add(key, dictionary[key]); - } - } else if (localContainer.GetType().ToString() == "Newtonsoft.Json.Linq.JProperty") { - ret = new Dictionary(); - - JProperty jsonProp = localContainer as JProperty; - if (jsonProp != null) { - string propName = jsonProp.Name; - ret.Add(propName, ConvertJTokenToObject(jsonProp.Value)); - } - } else if (localContainer.GetType().ToString() == - "System.Collections.Generic.List`1[System.Object]") { - List localList = localContainer as List; - if (localList != null && localList.Count > 0) { - if (localList[0].GetType() == typeof(KeyValuePair)) { - ret = new Dictionary(); - foreach (object item in localList) { - if (item is KeyValuePair kvpItem) { - ret.Add(kvpItem.Key, kvpItem.Value); - } else { - ret = null; - break; - } - } - } else if (localList[0].GetType() == typeof(Dictionary)) { - ret = new Dictionary(); - foreach (object item in localList) { - if (item is Dictionary dicItem) { - if (dicItem.Count > 0 && dicItem.ContainsKey("key") && - dicItem.ContainsKey("value")) { - ret.Add(dicItem["key"].ToString(), dicItem["value"]); - } - } else { - ret = null; - break; - } - } - } - } - } - } - } catch { - /* ignore */ - } - - return ret; - } - - public object[] ConvertToObjectArray(object localContainer) { - object[] ret = null; - - try { - if (localContainer.GetType().ToString() == "Newtonsoft.Json.Linq.JArray") { - JArray jarrayResult = localContainer as JArray; - List objectContainer = jarrayResult.ToObject>(); - if (objectContainer != null && objectContainer.Count > 0) { - for (int index = 0; index < objectContainer.Count; index++) { - if (objectContainer[index].GetType().ToString() == "Newtonsoft.Json.Linq.JArray") { - JArray internalItem = objectContainer[index] as JArray; - objectContainer[index] = internalItem.Select(item => (object)item).ToArray(); - } - } - - ret = objectContainer.ToArray(); - } - } else if (localContainer.GetType().ToString() == "System.Collections.Generic.List`1[System.Object]") { - List listResult = localContainer as List; - ret = listResult.ToArray(); - } - } catch { - /* ignore */ - } - - return ret; - } - - public static bool JsonFastCheck(string rawJson) { - var c = rawJson.TrimStart()[0]; - return c == '[' || c == '{'; - } - - private static object ConvertJTokenToObject(JToken token) { - if (token == null) { - return null; - } - - var jsonValue = token as JValue; - if (jsonValue != null) { - return jsonValue.Value; - } - - var jsonContainer = token as JArray; - if (jsonContainer != null) { - List jsonList = new List(); - foreach (JToken arrayItem in jsonContainer) { - jsonList.Add(ConvertJTokenToObject(arrayItem)); - } - - return jsonList; - } - - IDictionary jsonObject = token as JObject; - if (jsonObject != null) { - var jsonDict = new Dictionary(); - List propertyList = (from childToken in token - where childToken is JProperty - select childToken as JProperty).ToList(); - foreach (JProperty property in propertyList) { - jsonDict.Add(property.Name, ConvertJTokenToObject(property.Value)); - } - - return jsonDict; - } - - return null; - } - - private static object ConvertToDataType(Type dataType, object inputValue) { - if (dataType == inputValue.GetType()) { - return inputValue; - } - - object userMessage = inputValue; - switch (dataType.FullName) { - case "System.Int32": - userMessage = Convert.ChangeType(inputValue, typeof(System.Int32), CultureInfo.InvariantCulture); - break; - case "System.Int16": - userMessage = Convert.ChangeType(inputValue, typeof(System.Int16), CultureInfo.InvariantCulture); - break; - case "System.UInt64": - userMessage = Convert.ChangeType(inputValue, typeof(System.UInt64), CultureInfo.InvariantCulture); - break; - case "System.UInt32": - userMessage = Convert.ChangeType(inputValue, typeof(System.UInt32), CultureInfo.InvariantCulture); - break; - case "System.UInt16": - userMessage = Convert.ChangeType(inputValue, typeof(System.UInt16), CultureInfo.InvariantCulture); - break; - case "System.Byte": - userMessage = Convert.ChangeType(inputValue, typeof(System.Byte), CultureInfo.InvariantCulture); - break; - case "System.SByte": - userMessage = Convert.ChangeType(inputValue, typeof(System.SByte), CultureInfo.InvariantCulture); - break; - case "System.Decimal": - userMessage = Convert.ChangeType(inputValue, typeof(System.Decimal), CultureInfo.InvariantCulture); - break; - case "System.Boolean": - userMessage = Convert.ChangeType(inputValue, typeof(System.Boolean), CultureInfo.InvariantCulture); - break; - case "System.Double": - userMessage = Convert.ChangeType(inputValue, typeof(System.Double), CultureInfo.InvariantCulture); - break; - case "System.Char": - userMessage = Convert.ChangeType(inputValue, typeof(System.Char), CultureInfo.InvariantCulture); - break; - case "System.String": - userMessage = Convert.ChangeType(inputValue, typeof(System.String), CultureInfo.InvariantCulture); - break; - case "System.Object": - userMessage = Convert.ChangeType(inputValue, typeof(Object), CultureInfo.InvariantCulture); - break; - default: - break; - } - - return userMessage; - } - - #endregion - } + } + } + catch + { + /* ignore */ + } + } + + return ret; + } + + public string SerializeToJsonString(object objectToSerialize) + { + return JsonConvert.SerializeObject(objectToSerialize, defaultJsonSerializerSettings); + } + + public List DeserializeToListOfObject(string jsonString) + { + List result = + JsonConvert.DeserializeObject>(jsonString, defaultJsonSerializerSettings); + + return result; + } + + public object DeserializeToObject(object rawObject, Type type) + { + try + { + if (rawObject is JObject jObject) + { + return jObject.ToObject(type); + } + else + { + return rawObject; + } + } + catch (Exception e) + { + LoggingMethod.WriteToLog(pubnubLog, $"[{DateTime.Now.ToString(CultureInfo.InvariantCulture)}] Error: DeserializeToObject exception {e}", config.LogVerbosity); + return rawObject; + } + } + + public object DeserializeToObject(string jsonString) + { + object result = JsonConvert.DeserializeObject(jsonString, + new JsonSerializerSettings { DateParseHandling = DateParseHandling.None, MaxDepth = 64 }); + if (result.GetType().ToString() == "Newtonsoft.Json.Linq.JArray") + { + JArray jarrayResult = result as JArray; + List objectContainer = jarrayResult.ToObject>(); + if (objectContainer != null && objectContainer.Count > 0) + { + for (int index = 0; index < objectContainer.Count; index++) + { + if (objectContainer[index].GetType().ToString() == "Newtonsoft.Json.Linq.JArray") + { + JArray internalItem = objectContainer[index] as JArray; + objectContainer[index] = internalItem.Select(item => (object)item).ToArray(); + } + } + + result = objectContainer; + } + } + + return result; + } + + public void PopulateObject(string value, object target) + { + JsonConvert.PopulateObject(value, target, defaultJsonSerializerSettings); + } + + public virtual T DeserializeToObject(string jsonString) + { + T ret = default(T); + + try + { + ret = JsonConvert.DeserializeObject(jsonString, + new JsonSerializerSettings { DateParseHandling = DateParseHandling.None, MaxDepth = 64 }); + } + catch + { + /* ignore */ + } + + return ret; + } + + private bool IsGenericTypeForMessage() + { + bool ret = typeof(T).GetTypeInfo().IsGenericType && + typeof(T).GetGenericTypeDefinition() == typeof(PNMessageResult<>); + + LoggingMethod.WriteToLog(pubnubLog, + $"[{DateTime.Now.ToString(CultureInfo.InvariantCulture)}] typeof(T).GetTypeInfo().IsGenericType = {typeof(T).GetTypeInfo().IsGenericType}", config.LogVerbosity); + if (typeof(T).GetTypeInfo().IsGenericType) + { + LoggingMethod.WriteToLog(pubnubLog, + $"[{DateTime.Now.ToString(CultureInfo.InvariantCulture)}] typeof(T).GetGenericTypeDefinition() = {typeof(T).GetGenericTypeDefinition()}", config.LogVerbosity); + } + LoggingMethod.WriteToLog(pubnubLog, + $"[{DateTime.Now.ToString(CultureInfo.InvariantCulture)}] IsGenericTypeForMessage = {ret}", config.LogVerbosity); + return ret; + } + + private T DeserializeMessageToObjectBasedOnPlatform(List listObject) + { + T ret = default(T); + Type dataType = typeof(T).GetTypeInfo().GenericTypeArguments[0]; + Type generic = typeof(PNMessageResult<>); + Type specific = generic.MakeGenericType(dataType); + + ConstructorInfo ci = specific.GetTypeInfo().DeclaredConstructors.FirstOrDefault(); + if (ci != null) + { + object message = ci.Invoke(new object[] { }); + + //Set data + PropertyInfo dataProp = specific.GetRuntimeProperty("Message"); + + object userMessage = null; + if (listObject[0].GetType() == typeof(JValue)) + { + JValue jsonValue = listObject[0] as JValue; + userMessage = jsonValue.Value; + userMessage = ConvertToDataType(dataType, userMessage); + + dataProp.SetValue(message, userMessage, null); + } + else if (listObject[0].GetType() == typeof(JObject) || + listObject[0].GetType() == typeof(JArray)) + { + JToken token = listObject[0] as JToken; + if (dataProp.PropertyType == typeof(string)) + { + userMessage = JsonConvert.SerializeObject(token, defaultJsonSerializerSettings); + } + else + { + userMessage = token.ToObject(dataProp.PropertyType, JsonSerializer.Create()); + } + + dataProp.SetValue(message, userMessage, null); + } + else if (listObject[0].GetType() == typeof(System.String)) + { + userMessage = listObject[0] as string; + dataProp.SetValue(message, userMessage, null); + } + + //Set Time + PropertyInfo timeProp = specific.GetRuntimeProperty("Timetoken"); + long timetoken; + Int64.TryParse(listObject[2].ToString(), out timetoken); + timeProp.SetValue(message, timetoken, null); + + //Set Publisher + PropertyInfo publisherProp = specific.GetRuntimeProperty("Publisher"); + string publisherValue = (listObject[3] != null) ? listObject[3].ToString() : ""; + publisherProp.SetValue(message, publisherValue, null); + + // Set ChannelName + PropertyInfo channelNameProp = specific.GetRuntimeProperty("Channel"); + channelNameProp.SetValue(message, listObject[5]?.ToString(), null); + + // Set ChannelGroup + PropertyInfo subsciptionProp = specific.GetRuntimeProperty("Subscription"); + subsciptionProp.SetValue(message, listObject[4]?.ToString(), null); + + PropertyInfo customMessageType = specific.GetRuntimeProperty("CustomMessageType"); + customMessageType.SetValue(message, listObject[6], null); + //Set Metadata list second position, index=1 + if (listObject[1] != null) + { + PropertyInfo userMetadataProp = specific.GetRuntimeProperty("UserMetadata"); + userMetadataProp.SetValue(message, listObject[1], null); + } + + + ret = (T)Convert.ChangeType(message, specific, CultureInfo.InvariantCulture); + } + + return ret; + } + + public T DeserializeToObject(IDictionary jsonFields) + { + T response = default(T); + Type dataType = typeof(T).GetTypeInfo().GenericTypeArguments[0]; + Type generic = typeof(PNMessageResult<>); + Type specific = generic.MakeGenericType(dataType); + + var content = jsonFields["payload"]; + ConstructorInfo ci = specific.GetTypeInfo().DeclaredConstructors.FirstOrDefault(); + if (ci != null) + { + object message = ci.Invoke(new object[] { }); + PropertyInfo dataProp = specific.GetRuntimeProperty("Message"); + object userMessage = null; + + if (content.GetType() == typeof(JValue)) + { + JValue jsonValue = content as JValue; + userMessage = jsonValue.Value; + userMessage = ConvertToDataType(dataType, userMessage); + + dataProp.SetValue(message, userMessage, null); + } + else if (content.GetType() == typeof(JObject) || + content.GetType() == typeof(JArray)) + { + JToken token = content as JToken; + if (dataProp.PropertyType == typeof(string)) + { + userMessage = JsonConvert.SerializeObject(token, defaultJsonSerializerSettings); + } + else + { + userMessage = token.ToObject(dataProp.PropertyType, JsonSerializer.Create()); + } + + dataProp.SetValue(message, userMessage, null); + } + else if (content.GetType() == typeof(System.String)) + { + userMessage = content as string; + dataProp.SetValue(message, userMessage, null); + } + + PropertyInfo timeProp = specific.GetRuntimeProperty("Timetoken"); + long timetoken; + Int64.TryParse(jsonFields["publishTimetoken"].ToString(), out timetoken); + timeProp.SetValue(message, timetoken, null); + + PropertyInfo publisherProp = specific.GetRuntimeProperty("Publisher"); + string publisherValue = (jsonFields["userId"] != null) ? jsonFields["userId"].ToString() : ""; + publisherProp.SetValue(message, publisherValue, null); + + PropertyInfo channelNameProp = specific.GetRuntimeProperty("Channel"); + channelNameProp.SetValue(message, jsonFields["channel"]?.ToString(), null); + + PropertyInfo subsciptionProp = specific.GetRuntimeProperty("Subscription"); + subsciptionProp.SetValue(message, jsonFields["channelGroup"]?.ToString(), null); + + if (jsonFields.ContainsKey("customMessageType")) + { + PropertyInfo customMessageType = specific.GetRuntimeProperty("CustomMessageType"); + customMessageType.SetValue(message, jsonFields["customMessageType"], null); + } + + if (jsonFields["userMetadata"] != null) + { + PropertyInfo userMetadataProp = specific.GetRuntimeProperty("UserMetadata"); + userMetadataProp.SetValue(message, jsonFields["userMetadata"], null); + } + + + response = (T)Convert.ChangeType(message, specific, CultureInfo.InvariantCulture); + } + + return response; + } + + public virtual T DeserializeToObject(List listObject) + { + T ret = default(T); + + if (listObject == null) + { + return ret; + } + + if (IsGenericTypeForMessage()) + { + #region "Subscribe Message<>" + + return DeserializeMessageToObjectBasedOnPlatform(listObject); + + #endregion + } + else + { + return DeserializeToInternalObjectUtility.DeserializeToInternalObject(this, listObject); + } + } + + public Dictionary DeserializeToDictionaryOfObject(string jsonString) + { + Dictionary result = null; + try + { + if (JsonFastCheck(jsonString)) + { + result = JsonConvert.DeserializeObject>(jsonString, + defaultJsonSerializerSettings); + } + } + catch + { + //ignore + } + + return result; + } + + public Dictionary ConvertToDictionaryObject(object localContainer) + { + Dictionary ret = null; + + try + { + if (localContainer != null) + { + if (localContainer.GetType().ToString() == "Newtonsoft.Json.Linq.JObject") + { + ret = new Dictionary(); + + IDictionary jsonDictionary = localContainer as JObject; + if (jsonDictionary != null) + { + foreach (KeyValuePair pair in jsonDictionary) + { + JToken token = pair.Value; + ret.Add(pair.Key, ConvertJTokenToObject(token)); + } + } + } + else if (localContainer.GetType().ToString() == + "System.Collections.Generic.Dictionary`2[System.String,System.Object]") + { + ret = new Dictionary(); + Dictionary dictionary = localContainer as Dictionary; + foreach (string key in dictionary.Keys) + { + ret.Add(key, dictionary[key]); + } + } + else if (localContainer.GetType().ToString() == "Newtonsoft.Json.Linq.JProperty") + { + ret = new Dictionary(); + + JProperty jsonProp = localContainer as JProperty; + if (jsonProp != null) + { + string propName = jsonProp.Name; + ret.Add(propName, ConvertJTokenToObject(jsonProp.Value)); + } + } + else if (localContainer.GetType().ToString() == "System.Collections.Generic.List`1[System.Object]") + { + List localList = localContainer as List; + if (localList != null && localList.Count > 0) + { + if (localList[0].GetType() == typeof(KeyValuePair)) + { + ret = new Dictionary(); + foreach (object item in localList) + { + if (item is KeyValuePair kvpItem) + { + ret.Add(kvpItem.Key, kvpItem.Value); + } + else + { + ret = null; + break; + } + } + } + else if (localList[0].GetType() == typeof(Dictionary)) + { + ret = new Dictionary(); + foreach (object item in localList) + { + if (item is Dictionary dicItem) + { + if (dicItem.Count > 0 && dicItem.ContainsKey("key") && + dicItem.ContainsKey("value")) + { + ret.Add(dicItem["key"].ToString(), dicItem["value"]); + } + } + else + { + ret = null; + break; + } + } + } + } + } + } + } + catch + { + /* ignore */ + } + + return ret; + } + + public object[] ConvertToObjectArray(object localContainer) + { + object[] ret = null; + + try + { + if (localContainer.GetType().ToString() == "Newtonsoft.Json.Linq.JArray") + { + JArray jarrayResult = localContainer as JArray; + List objectContainer = jarrayResult.ToObject>(); + if (objectContainer != null && objectContainer.Count > 0) + { + for (int index = 0; index < objectContainer.Count; index++) + { + if (objectContainer[index].GetType().ToString() == "Newtonsoft.Json.Linq.JArray") + { + JArray internalItem = objectContainer[index] as JArray; + objectContainer[index] = internalItem.Select(item => (object)item).ToArray(); + } + } + ret = objectContainer.ToArray(); + } + } + else if (localContainer.GetType().ToString() == "System.Collections.Generic.List`1[System.Object]") + { + List listResult = localContainer as List; + ret = listResult.ToArray(); + } + } + catch { /* ignore */ } + + return ret; + } + + public static bool JsonFastCheck(string rawJson) + { + var c = rawJson.TrimStart()[0]; + return c == '[' || c == '{'; + } + + private static object ConvertJTokenToObject(JToken token) + { + if (token == null) + { + return null; + } + + var jsonValue = token as JValue; + if (jsonValue != null) + { + return jsonValue.Value; + } + + var jsonContainer = token as JArray; + if (jsonContainer != null) + { + List jsonList = new List(); + foreach (JToken arrayItem in jsonContainer) + { + jsonList.Add(ConvertJTokenToObject(arrayItem)); + } + return jsonList; + } + + IDictionary jsonObject = token as JObject; + if (jsonObject != null) + { + var jsonDict = new Dictionary(); + List propertyList = (from childToken in token + where childToken is JProperty + select childToken as JProperty).ToList(); + foreach (JProperty property in propertyList) + { + jsonDict.Add(property.Name, ConvertJTokenToObject(property.Value)); + } + + return jsonDict; + } + + return null; + } + + private static object ConvertToDataType(Type dataType, object inputValue) + { + if (dataType == inputValue.GetType()) + { + return inputValue; + } + + object userMessage = inputValue; + switch (dataType.FullName) + { + case "System.Int32": + userMessage = Convert.ChangeType(inputValue, typeof(System.Int32), CultureInfo.InvariantCulture); + break; + case "System.Int16": + userMessage = Convert.ChangeType(inputValue, typeof(System.Int16), CultureInfo.InvariantCulture); + break; + case "System.UInt64": + userMessage = Convert.ChangeType(inputValue, typeof(System.UInt64), CultureInfo.InvariantCulture); + break; + case "System.UInt32": + userMessage = Convert.ChangeType(inputValue, typeof(System.UInt32), CultureInfo.InvariantCulture); + break; + case "System.UInt16": + userMessage = Convert.ChangeType(inputValue, typeof(System.UInt16), CultureInfo.InvariantCulture); + break; + case "System.Byte": + userMessage = Convert.ChangeType(inputValue, typeof(System.Byte), CultureInfo.InvariantCulture); + break; + case "System.SByte": + userMessage = Convert.ChangeType(inputValue, typeof(System.SByte), CultureInfo.InvariantCulture); + break; + case "System.Decimal": + userMessage = Convert.ChangeType(inputValue, typeof(System.Decimal), CultureInfo.InvariantCulture); + break; + case "System.Boolean": + userMessage = Convert.ChangeType(inputValue, typeof(System.Boolean), CultureInfo.InvariantCulture); + break; + case "System.Double": + userMessage = Convert.ChangeType(inputValue, typeof(System.Double), CultureInfo.InvariantCulture); + break; + case "System.Char": + userMessage = Convert.ChangeType(inputValue, typeof(System.Char), CultureInfo.InvariantCulture); + break; + case "System.String": + userMessage = Convert.ChangeType(inputValue, typeof(System.String), CultureInfo.InvariantCulture); + break; + case "System.Object": + userMessage = Convert.ChangeType(inputValue, typeof(Object), CultureInfo.InvariantCulture); + break; + default: + break; + } + + return userMessage; + } + + #endregion + } } \ No newline at end of file diff --git a/PubNubUnity/Assets/PubNub/Runtime/Util/UnityPNSDKSource.cs b/PubNubUnity/Assets/PubNub/Runtime/Util/UnityPNSDKSource.cs index a56cda1f..9470471a 100644 --- a/PubNubUnity/Assets/PubNub/Runtime/Util/UnityPNSDKSource.cs +++ b/PubNubUnity/Assets/PubNub/Runtime/Util/UnityPNSDKSource.cs @@ -5,7 +5,7 @@ namespace PubnubApi.Unity { public class UnityPNSDKSource : IPNSDKSource { - private const string build = "8.0.1"; + private const string build = "8.1.0"; public string GetPNSDK() { #if(UNITY_IOS) diff --git a/PubNubUnity/Assets/PubNub/package.json b/PubNubUnity/Assets/PubNub/package.json index 5d5e5115..ff7f5b46 100644 --- a/PubNubUnity/Assets/PubNub/package.json +++ b/PubNubUnity/Assets/PubNub/package.json @@ -1,6 +1,6 @@ { "name": "com.pubnub.sdk", - "version": "8.0.1", + "version": "8.1.0", "displayName": "PubNub SDK", "description": "PubNub Real-time Cloud-Hosted Push API and Push Notification Client Frameworks", "unity": "2021.3", diff --git a/VERSION b/VERSION index cd1d2e94..8104cabd 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.0.1 +8.1.0