/// <summary> /// Handles the response bundle and calls registered callbacks. /// </summary> /// <param name="in_jsonData">The received message bundle.</param> private void HandleResponseBundle(string in_jsonData) { m_brainCloudClientRef.Log("INCOMING: " + in_jsonData); JsonResponseBundleV2 bundleObj = JsonReader.Deserialize <JsonResponseBundleV2>(in_jsonData); long receivedPacketId = (long)bundleObj.packetId; if (m_expectedIncomingPacketId == NO_PACKET_EXPECTED || m_expectedIncomingPacketId != receivedPacketId) { m_brainCloudClientRef.Log("Dropping duplicate packet"); return; } m_expectedIncomingPacketId = NO_PACKET_EXPECTED; Dictionary <string, object>[] responseBundle = bundleObj.responses; Dictionary <string, object> response = null; Exception firstThrownException = null; int numExceptionsThrown = 0; for (int j = 0; j < responseBundle.Length; ++j) { response = responseBundle[j]; int statusCode = (int)response["status"]; string data = ""; // // It's important to note here that a user error callback *might* call // ResetCommunications() based on the error being returned. // ResetCommunications will clear the m_serviceCallsInProgress List // effectively removing all registered callbacks for this message bundle. // It's also likely that the developer will want to call authenticate next. // We need to ensure that this is supported as it's the best way to // reset the brainCloud communications after a session invalid or network // error is triggered. // // This is safe to do from the main thread but just in case someone // calls this method from another thread, we lock on m_serviceCallsWaiting // ServerCall sc = null; lock (m_serviceCallsWaiting) { if (m_serviceCallsInProgress.Count > 0) { sc = m_serviceCallsInProgress[0] as ServerCall; m_serviceCallsInProgress.RemoveAt(0); } } // its a success response if (statusCode == 200) { if (response[OperationParam.ServiceMessageData.Value] != null) { Dictionary <string, object> responseData = (Dictionary <string, object>)response[OperationParam.ServiceMessageData.Value]; // send the data back as not formatted data = JsonWriter.Serialize(response); // save the session ID try { if (getJsonString(responseData, OperationParam.ServiceMessageSessionId.Value, null) != null) { m_sessionID = (string)responseData[OperationParam.ServiceMessageSessionId.Value]; m_isAuthenticated = true; // TODO confirm authentication } // save the profile ID if (getJsonString(responseData, OperationParam.ServiceMessageProfileId.Value, null) != null) { m_brainCloudClientRef.AuthenticationService.ProfileId = (string)responseData[OperationParam.ServiceMessageProfileId.Value]; } } catch (Exception e) { m_brainCloudClientRef.Log("SessionId or ProfileId do not exist " + e.ToString()); } } // now try to execute the callback if (sc != null) { if (sc.GetService().Equals(ServiceName.PlayerState.Value) && (sc.GetOperation().Equals(ServiceOperation.FullReset.Value) || sc.GetOperation().Equals(ServiceOperation.Reset.Value) || sc.GetOperation().Equals(ServiceOperation.Logout.Value))) { // we reset the current player or logged out // we are no longer authenticated m_isAuthenticated = false; m_brainCloudClientRef.AuthenticationService.ProfileId = null; } else if (sc.GetService().Equals(ServiceName.Authenticate.Value) && sc.GetOperation().Equals(ServiceOperation.Authenticate.Value)) { ProcessAuthenticate(data); } // // only process callbacks that are real if (sc.GetCallback() != null) { try { sc.GetCallback().OnSuccessCallback(data); } catch (Exception e) { m_brainCloudClientRef.Log(e.StackTrace); ++numExceptionsThrown; if (firstThrownException == null) { firstThrownException = e; } } } } } else if (statusCode >= 400 || statusCode == 202) { object reasonCodeObj = null, statusMessageObj = null; int reasonCode = 0; string statusMessage = ""; if (response.TryGetValue("reason_code", out reasonCodeObj)) { reasonCode = (int)reasonCodeObj; } if (response.TryGetValue("status_message", out statusMessageObj)) { statusMessage = (string)statusMessageObj; } if (reasonCode == ReasonCodes.SESSION_EXPIRED || reasonCode == ReasonCodes.SESSION_NOT_FOUND_ERROR) { m_isAuthenticated = false; m_brainCloudClientRef.Log("Received session expired or not found, need to re-authenticate"); } // now try to execute the callback if (sc != null && sc.GetCallback() != null) { try { sc.GetCallback().OnErrorCallback(statusCode, reasonCode, statusMessage); } catch (Exception e) { m_brainCloudClientRef.Log(e.StackTrace); ++numExceptionsThrown; if (firstThrownException == null) { firstThrownException = e; } } } } } if (firstThrownException != null) { m_activeRequest = null; // to make sure we don't reprocess this message throw new Exception("User callback handlers threw " + numExceptionsThrown + " exception(s)." + " See the Unity log for callstacks or inner exception for first exception thrown.", firstThrownException); } }
/// <summary> /// Handles the response bundle and calls registered callbacks. /// </summary> /// <param name="in_jsonData">The received message bundle.</param> private void HandleResponseBundle(string in_jsonData) { m_brainCloudClientRef.Log("INCOMING: " + in_jsonData); JsonResponseBundleV2 bundleObj = JsonReader.Deserialize <JsonResponseBundleV2>(in_jsonData); long receivedPacketId = (long)bundleObj.packetId; if (m_expectedIncomingPacketId == NO_PACKET_EXPECTED || m_expectedIncomingPacketId != receivedPacketId) { m_brainCloudClientRef.Log("Dropping duplicate packet"); return; } m_expectedIncomingPacketId = NO_PACKET_EXPECTED; Dictionary <string, object>[] responseBundle = bundleObj.responses; Dictionary <string, object> response = null; IList <Exception> exceptions = new List <Exception>(); for (int j = 0; j < responseBundle.Length; ++j) { response = responseBundle[j]; int statusCode = (int)response["status"]; string data = ""; // // It's important to note here that a user error callback *might* call // ResetCommunications() based on the error being returned. // ResetCommunications will clear the m_serviceCallsInProgress List // effectively removing all registered callbacks for this message bundle. // It's also likely that the developer will want to call authenticate next. // We need to ensure that this is supported as it's the best way to // reset the brainCloud communications after a session invalid or network // error is triggered. // // This is safe to do from the main thread but just in case someone // calls this method from another thread, we lock on m_serviceCallsWaiting // ServerCall sc = null; lock (m_serviceCallsWaiting) { if (m_serviceCallsInProgress.Count > 0) { sc = m_serviceCallsInProgress[0] as ServerCall; m_serviceCallsInProgress.RemoveAt(0); } } // its a success response if (statusCode == 200) { Dictionary <string, object> responseData = null; if (response[OperationParam.ServiceMessageData.Value] != null) { responseData = (Dictionary <string, object>)response[OperationParam.ServiceMessageData.Value]; // send the data back as not formatted data = JsonWriter.Serialize(response); // save the session ID try { if (getJsonString(responseData, OperationParam.ServiceMessageSessionId.Value, null) != null) { m_sessionID = (string)responseData[OperationParam.ServiceMessageSessionId.Value]; m_isAuthenticated = true; // TODO confirm authentication } // save the profile ID if (getJsonString(responseData, OperationParam.ServiceMessageProfileId.Value, null) != null) { m_brainCloudClientRef.AuthenticationService.ProfileId = (string)responseData[OperationParam.ServiceMessageProfileId.Value]; } } catch (Exception e) { m_brainCloudClientRef.Log("SessionId or ProfileId do not exist " + e.ToString()); } } // now try to execute the callback if (sc != null) { if (sc.GetService().Equals(ServiceName.PlayerState.Value) && (sc.GetOperation().Equals(ServiceOperation.FullReset.Value) || sc.GetOperation().Equals(ServiceOperation.Logout.Value))) { // we reset the current player or logged out // we are no longer authenticated m_isAuthenticated = false; m_brainCloudClientRef.AuthenticationService.ClearSavedProfileID(); } else if (sc.GetService().Equals(ServiceName.Authenticate.Value) && sc.GetOperation().Equals(ServiceOperation.Authenticate.Value)) { ProcessAuthenticate(data); } // // only process callbacks that are real if (sc.GetCallback() != null) { try { sc.GetCallback().OnSuccessCallback(data); } catch (Exception e) { m_brainCloudClientRef.Log(e.StackTrace); exceptions.Add(e); } } // now deal with rewards if (m_rewardCallback != null && responseData != null) { try { Dictionary <string, object> rewards = null; // it's an operation that return a reward if (sc.GetService().Equals(ServiceName.Authenticate.Value) && sc.GetOperation().Equals(ServiceOperation.Authenticate.Value)) { object objRewards = null; if (responseData.TryGetValue("rewards", out objRewards)) { Dictionary <string, object> outerRewards = (Dictionary <string, object>)objRewards; if (outerRewards.TryGetValue("rewards", out objRewards)) { Dictionary <string, object> innerRewards = (Dictionary <string, object>)objRewards; if (innerRewards.Count > 0) { // we found rewards rewards = outerRewards; } } } } else if ((sc.GetService().Equals(ServiceName.PlayerStatistics.Value) && sc.GetOperation().Equals(ServiceOperation.Update.Value)) || (sc.GetService().Equals(ServiceName.PlayerStatisticsEvent.Value) && (sc.GetOperation().Equals(ServiceOperation.Trigger.Value) || sc.GetOperation().Equals(ServiceOperation.TriggerMultiple.Value)))) { object objRewards = null; if (responseData.TryGetValue("rewards", out objRewards)) { Dictionary <string, object> innerRewards = (Dictionary <string, object>)objRewards; if (innerRewards.Count > 0) { // we found rewards rewards = responseData; } } } if (rewards != null) { Dictionary <string, object> theReward = new Dictionary <string, object>(); theReward["rewards"] = rewards; theReward["service"] = sc.GetService(); theReward["operation"] = sc.GetOperation(); Dictionary <string, object> apiRewards = new Dictionary <string, object>(); List <object> rewardList = new List <object>(); rewardList.Add(theReward); apiRewards["apiRewards"] = rewardList; string rewardsAsJson = JsonWriter.Serialize(apiRewards); m_rewardCallback(rewardsAsJson); } } catch (Exception e) { m_brainCloudClientRef.Log(e.StackTrace); exceptions.Add(e); } } } } else if (statusCode >= 400 || statusCode == 202) { object reasonCodeObj = null, statusMessageObj = null; int reasonCode = 0; string errorJson = ""; if (response.TryGetValue("reason_code", out reasonCodeObj)) { reasonCode = (int)reasonCodeObj; } if (m_oldStyleStatusResponseInErrorCallback) { if (response.TryGetValue("status_message", out statusMessageObj)) { errorJson = (string)statusMessageObj; } } else { errorJson = JsonWriter.Serialize(response); } if (reasonCode == ReasonCodes.PLAYER_SESSION_EXPIRED || reasonCode == ReasonCodes.NO_SESSION) { m_isAuthenticated = false; m_brainCloudClientRef.Log("Received session expired or not found, need to re-authenticate"); } if (sc != null && sc.GetOperation().Equals(ServiceOperation.Logout.Value)) { if (reasonCode == ReasonCodes.CLIENT_NETWORK_ERROR_TIMEOUT) { m_isAuthenticated = false; m_brainCloudClientRef.Log("Could not communicate with the server on logout due to network timeout"); } } // now try to execute the callback if (sc != null && sc.GetCallback() != null) { try { sc.GetCallback().OnErrorCallback(statusCode, reasonCode, errorJson); } catch (Exception e) { m_brainCloudClientRef.Log(e.StackTrace); exceptions.Add(e); } } } } if (bundleObj.events != null && m_eventCallback != null) { Dictionary <string, Dictionary <string, object>[]> eventsJsonObj = new Dictionary <string, Dictionary <string, object>[]>(); eventsJsonObj["events"] = bundleObj.events; string eventsAsJson = JsonWriter.Serialize(eventsJsonObj); try { m_eventCallback(eventsAsJson); } catch (Exception e) { m_brainCloudClientRef.Log(e.StackTrace); exceptions.Add(e); } } if (exceptions.Count > 0) { m_activeRequest = null; // to make sure we don't reprocess this message throw new Exception("User callback handlers threw " + exceptions.Count + " exception(s)." + " See the Unity log for callstacks or inner exception for first exception thrown.", exceptions[0]); } }