备份CatanBuilding瘦身独立工程

This commit is contained in:
JSD\13999
2026-05-26 16:15:54 +08:00
commit 2d0e6a61b7
12001 changed files with 2431925 additions and 0 deletions

View File

@@ -0,0 +1,60 @@
using System;
using System.Collections.Generic;
using PlayFab.SharedModels;
namespace PlayFab.Internal
{
public enum AuthType
{
None,
PreLoginSession, // Not yet defined
LoginSession, // "X-Authorization"
DevSecretKey, // "X-SecretKey"
EntityToken, // "X-EntityToken"
}
public enum HttpRequestState
{
Sent,
Received,
Idle,
Error
}
public class CallRequestContainer
{
#if !UNITY_WSA && !UNITY_WP8
public HttpRequestState HttpState = HttpRequestState.Idle;
public System.Net.HttpWebRequest HttpRequest = null;
#endif
#if PLAYFAB_REQUEST_TIMING
public PlayFabHttp.RequestTiming Timing;
public System.Diagnostics.Stopwatch Stopwatch;
#endif
// This class stores the state of the request and all associated data
public string ApiEndpoint = null;
public string FullUrl = null;
public byte[] Payload = null;
public string JsonResponse = null;
public PlayFabRequestCommon ApiRequest;
public Dictionary<string, string> RequestHeaders;
public PlayFabResultCommon ApiResult;
public PlayFabError Error;
public Action DeserializeResultJson;
public Action InvokeSuccessCallback;
public Action<PlayFabError> ErrorCallback;
public object CustomData = null;
public PlayFabApiSettings settings;
public PlayFabAuthenticationContext context;
public IPlayFabInstanceApi instanceApi;
public bool CalledGetResponse = false;
public CallRequestContainer()
{
#if PLAYFAB_REQUEST_TIMING
Stopwatch = System.Diagnostics.Stopwatch.StartNew();
#endif
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: aeac58284b4b1cd4ab93ab0e71ba8540
timeCreated: 1462745280
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,500 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using PlayFab.Public;
using PlayFab.SharedModels;
using UnityEngine;
namespace PlayFab.Internal
{
/// <summary>
/// This is a wrapper for Http So we can better separate the functionaity of Http Requests delegated to WWW or HttpWebRequest
/// </summary>
public class PlayFabHttp : SingletonMonoBehaviour<PlayFabHttp>
{
private static List<CallRequestContainer> _apiCallQueue = new List<CallRequestContainer>(); // Starts initialized, and is nulled when it's flushed
public delegate void ApiProcessingEvent<in TEventArgs>(TEventArgs e);
public delegate void ApiProcessErrorEvent(PlayFabRequestCommon request, PlayFabError error);
public static event ApiProcessingEvent<ApiProcessingEventArgs> ApiProcessingEventHandler;
public static event ApiProcessErrorEvent ApiProcessingErrorEventHandler;
public static readonly Dictionary<string, string> GlobalHeaderInjection = new Dictionary<string, string>();
private static IPlayFabLogger _logger;
#if !DISABLE_PLAYFABENTITY_API && !DISABLE_PLAYFABCLIENT_API
private static IScreenTimeTracker screenTimeTracker = new ScreenTimeTracker();
private const float delayBetweenBatches = 5.0f;
#endif
#if PLAYFAB_REQUEST_TIMING
public struct RequestTiming
{
public DateTime StartTimeUtc;
public string ApiEndpoint;
public int WorkerRequestMs;
public int MainThreadRequestMs;
}
public delegate void ApiRequestTimingEvent(RequestTiming time);
public static event ApiRequestTimingEvent ApiRequestTimingEventHandler;
#endif
/// <summary>
/// Return the number of api calls that are waiting for results from the server
/// </summary>
/// <returns></returns>
public static int GetPendingMessages()
{
var transport = PluginManager.GetPlugin<ITransportPlugin>(PluginContract.PlayFab_Transport);
return transport.IsInitialized ? transport.GetPendingMessages() : 0;
}
/// <summary>
/// This initializes the GameObject and ensures it is in the scene.
/// </summary>
public static void InitializeHttp()
{
if (string.IsNullOrEmpty(PlayFabSettings.TitleId))
throw new PlayFabException(PlayFabExceptionCode.TitleNotSet, "You must set PlayFabSettings.TitleId before making API Calls.");
var transport = PluginManager.GetPlugin<ITransportPlugin>(PluginContract.PlayFab_Transport);
if (transport.IsInitialized)
return;
transport.Initialize();
CreateInstance(); // Invoke the SingletonMonoBehaviour
}
/// <summary>
/// This initializes the GameObject and ensures it is in the scene.
/// </summary>
public static void InitializeLogger(IPlayFabLogger setLogger = null)
{
if (_logger != null)
throw new InvalidOperationException("Once initialized, the logger cannot be reset.");
if (setLogger == null)
setLogger = new PlayFabLogger();
_logger = setLogger;
}
#if !DISABLE_PLAYFABENTITY_API && !DISABLE_PLAYFABCLIENT_API
/// <summary>
/// This initializes ScreenTimeTracker object and notifying it to start sending info.
/// </summary>
/// <param name="playFabUserId">Result of the user's login, represent user ID</param>
public static void InitializeScreenTimeTracker(string entityId, string entityType, string playFabUserId)
{
screenTimeTracker.ClientSessionStart(entityId, entityType, playFabUserId);
instance.StartCoroutine(SendScreenTimeEvents(delayBetweenBatches));
}
/// <summary>
/// This function will send Screen Time events on a periodic basis.
/// </summary>
/// <param name="secondsBetweenBatches">Delay between batches, in seconds</param>
private static IEnumerator SendScreenTimeEvents(float secondsBetweenBatches)
{
WaitForSeconds delay = new WaitForSeconds(secondsBetweenBatches);
while (!PlayFabSettings.DisableFocusTimeCollection)
{
screenTimeTracker.Send();
yield return delay;
}
}
#endif
public static void SimpleGetCall(string fullUrl, Action<byte[]> successCallback, Action<string> errorCallback)
{
InitializeHttp();
PluginManager.GetPlugin<ITransportPlugin>(PluginContract.PlayFab_Transport).SimpleGetCall(fullUrl, successCallback, errorCallback);
}
public static void SimplePutCall(string fullUrl, byte[] payload, Action<byte[]> successCallback, Action<string> errorCallback)
{
InitializeHttp();
PluginManager.GetPlugin<ITransportPlugin>(PluginContract.PlayFab_Transport).SimplePutCall(fullUrl, payload, successCallback, errorCallback);
}
public static void SimplePostCall(string fullUrl, byte[] payload, Action<byte[]> successCallback, Action<string> errorCallback)
{
InitializeHttp();
PluginManager.GetPlugin<ITransportPlugin>(PluginContract.PlayFab_Transport).SimplePostCall(fullUrl, payload, successCallback, errorCallback);
}
protected internal static void MakeApiCall<TResult>(string apiEndpoint,
PlayFabRequestCommon request, AuthType authType, Action<TResult> resultCallback,
Action<PlayFabError> errorCallback, object customData = null, Dictionary<string, string> extraHeaders = null, PlayFabAuthenticationContext authenticationContext = null, PlayFabApiSettings apiSettings = null, IPlayFabInstanceApi instanceApi = null)
where TResult : PlayFabResultCommon
{
apiSettings = apiSettings ?? PlayFabSettings.staticSettings;
var fullUrl = apiSettings.GetFullUrl(apiEndpoint, apiSettings.RequestGetParams);
_MakeApiCall(apiEndpoint, fullUrl, request, authType, resultCallback, errorCallback, customData, extraHeaders, false, authenticationContext, apiSettings, instanceApi);
}
protected internal static void MakeApiCallWithFullUri<TResult>(string fullUri,
PlayFabRequestCommon request, AuthType authType, Action<TResult> resultCallback,
Action<PlayFabError> errorCallback, object customData = null, Dictionary<string, string> extraHeaders = null, PlayFabAuthenticationContext authenticationContext = null, PlayFabApiSettings apiSettings = null, IPlayFabInstanceApi instanceApi = null)
where TResult : PlayFabResultCommon
{
apiSettings = apiSettings ?? PlayFabSettings.staticSettings;
// This will not be called if environment file does not exist or does not contain property the debugging URI
_MakeApiCall(null, fullUri, request, authType, resultCallback, errorCallback, customData, extraHeaders, false, authenticationContext, apiSettings, instanceApi);
}
/// <summary>
/// Internal method for Make API Calls
/// </summary>
private static void _MakeApiCall<TResult>(string apiEndpoint, string fullUrl,
PlayFabRequestCommon request, AuthType authType, Action<TResult> resultCallback,
Action<PlayFabError> errorCallback, object customData, Dictionary<string, string> extraHeaders, bool allowQueueing, PlayFabAuthenticationContext authenticationContext, PlayFabApiSettings apiSettings, IPlayFabInstanceApi instanceApi)
where TResult : PlayFabResultCommon
{
InitializeHttp();
SendEvent(apiEndpoint, request, null, ApiProcessingEventType.Pre);
var serializer = PluginManager.GetPlugin<ISerializerPlugin>(PluginContract.PlayFab_Serializer);
var reqContainer = new CallRequestContainer
{
ApiEndpoint = apiEndpoint,
FullUrl = fullUrl,
settings = apiSettings,
context = authenticationContext,
CustomData = customData,
Payload = Encoding.UTF8.GetBytes(serializer.SerializeObject(request)),
ApiRequest = request,
ErrorCallback = errorCallback,
RequestHeaders = extraHeaders ?? new Dictionary<string, string>(), // Use any headers provided by the customer
instanceApi = instanceApi
};
// Append any additional headers
foreach (var pair in GlobalHeaderInjection)
if (!reqContainer.RequestHeaders.ContainsKey(pair.Key))
reqContainer.RequestHeaders[pair.Key] = pair.Value;
#if PLAYFAB_REQUEST_TIMING
reqContainer.Timing.StartTimeUtc = DateTime.UtcNow;
reqContainer.Timing.ApiEndpoint = apiEndpoint;
#endif
// Add PlayFab Headers
var transport = PluginManager.GetPlugin<ITransportPlugin>(PluginContract.PlayFab_Transport);
reqContainer.RequestHeaders["X-ReportErrorAsSuccess"] = "true"; // Makes processing PlayFab errors a little easier
reqContainer.RequestHeaders["X-PlayFabSDK"] = PlayFabSettings.VersionString; // Tell PlayFab which SDK this is
switch (authType)
{
#if ENABLE_PLAYFABSERVER_API || ENABLE_PLAYFABADMIN_API || UNITY_EDITOR || ENABLE_PLAYFAB_SECRETKEY
case AuthType.DevSecretKey:
if (apiSettings.DeveloperSecretKey == null) throw new PlayFabException(PlayFabExceptionCode.DeveloperKeyNotSet, "DeveloperSecretKey is not found in Request, Server Instance or PlayFabSettings");
reqContainer.RequestHeaders["X-SecretKey"] = apiSettings.DeveloperSecretKey; break;
#endif
#if !DISABLE_PLAYFABCLIENT_API
case AuthType.LoginSession:
if (authenticationContext != null)
reqContainer.RequestHeaders["X-Authorization"] = authenticationContext.ClientSessionTicket;
break;
#endif
#if !DISABLE_PLAYFABENTITY_API
case AuthType.EntityToken:
if (authenticationContext != null)
reqContainer.RequestHeaders["X-EntityToken"] = authenticationContext.EntityToken;
break;
#endif
}
// These closures preserve the TResult generic information in a way that's safe for all the devices
reqContainer.DeserializeResultJson = () =>
{
reqContainer.ApiResult = serializer.DeserializeObject<TResult>(reqContainer.JsonResponse);
};
reqContainer.InvokeSuccessCallback = () =>
{
if (resultCallback != null)
{
resultCallback((TResult)reqContainer.ApiResult);
}
};
if (allowQueueing && _apiCallQueue != null)
{
for (var i = _apiCallQueue.Count - 1; i >= 0; i--)
if (_apiCallQueue[i].ApiEndpoint == apiEndpoint)
_apiCallQueue.RemoveAt(i);
_apiCallQueue.Add(reqContainer);
}
else
{
transport.MakeApiCall(reqContainer);
}
}
/// <summary>
/// Internal code shared by IPlayFabHTTP implementations
/// </summary>
internal void OnPlayFabApiResult(CallRequestContainer reqContainer)
{
var result = reqContainer.ApiResult;
#if !DISABLE_PLAYFABENTITY_API
var entRes = result as AuthenticationModels.GetEntityTokenResponse;
if (entRes != null)
{
PlayFabSettings.staticPlayer.EntityToken = entRes.EntityToken;
}
#endif
#if !DISABLE_PLAYFABCLIENT_API
var logRes = result as ClientModels.LoginResult;
var regRes = result as ClientModels.RegisterPlayFabUserResult;
if (logRes != null)
{
logRes.AuthenticationContext = new PlayFabAuthenticationContext(logRes.SessionTicket, logRes.EntityToken.EntityToken, logRes.PlayFabId, logRes.EntityToken.Entity.Id, logRes.EntityToken.Entity.Type);
if (reqContainer.context != null)
reqContainer.context.CopyFrom(logRes.AuthenticationContext);
}
else if (regRes != null)
{
regRes.AuthenticationContext = new PlayFabAuthenticationContext(regRes.SessionTicket, regRes.EntityToken.EntityToken, regRes.PlayFabId, regRes.EntityToken.Entity.Id, regRes.EntityToken.Entity.Type);
if (reqContainer.context != null)
reqContainer.context.CopyFrom(regRes.AuthenticationContext);
}
#endif
}
/// <summary>
/// MonoBehaviour OnEnable Method
/// </summary>
private void OnEnable()
{
if (_logger != null)
{
_logger.OnEnable();
}
#if !DISABLE_PLAYFABENTITY_API && !DISABLE_PLAYFABCLIENT_API
if ((screenTimeTracker != null) && !PlayFabSettings.DisableFocusTimeCollection)
{
screenTimeTracker.OnEnable();
}
#endif
}
/// <summary>
/// MonoBehaviour OnDisable
/// </summary>
private void OnDisable()
{
if (_logger != null)
{
_logger.OnDisable();
}
#if !DISABLE_PLAYFABENTITY_API && !DISABLE_PLAYFABCLIENT_API
if ((screenTimeTracker != null) && !PlayFabSettings.DisableFocusTimeCollection)
{
screenTimeTracker.OnDisable();
}
#endif
}
/// <summary>
/// MonoBehaviour OnDestroy
/// </summary>
private void OnDestroy()
{
var transport = PluginManager.GetPlugin<ITransportPlugin>(PluginContract.PlayFab_Transport);
if (transport.IsInitialized)
{
transport.OnDestroy();
}
if (_logger != null)
{
_logger.OnDestroy();
}
#if !DISABLE_PLAYFABENTITY_API && !DISABLE_PLAYFABCLIENT_API
if ((screenTimeTracker != null) && !PlayFabSettings.DisableFocusTimeCollection)
{
screenTimeTracker.OnDestroy();
}
#endif
}
/// <summary>
/// MonoBehaviour OnApplicationFocus
/// </summary>
public void OnApplicationFocus(bool isFocused)
{
#if !DISABLE_PLAYFABENTITY_API && !DISABLE_PLAYFABCLIENT_API
if ((screenTimeTracker != null) && !PlayFabSettings.DisableFocusTimeCollection)
{
screenTimeTracker.OnApplicationFocus(isFocused);
}
#endif
}
/// <summary>
/// MonoBehaviour OnApplicationQuit
/// </summary>
public void OnApplicationQuit()
{
#if !DISABLE_PLAYFABENTITY_API && !DISABLE_PLAYFABCLIENT_API
if ((screenTimeTracker != null) && !PlayFabSettings.DisableFocusTimeCollection)
{
screenTimeTracker.OnApplicationQuit();
}
#endif
}
/// <summary>
/// MonoBehaviour Update
/// </summary>
private void Update()
{
var transport = PluginManager.GetPlugin<ITransportPlugin>(PluginContract.PlayFab_Transport);
if (transport.IsInitialized)
{
if (_apiCallQueue != null)
{
foreach (var eachRequest in _apiCallQueue)
transport.MakeApiCall(eachRequest); // Flush the queue
_apiCallQueue = null; // null this after it's flushed
}
transport.Update();
}
while (_injectedCoroutines.Count > 0)
StartCoroutine(_injectedCoroutines.Dequeue());
while (_injectedAction.Count > 0)
{
var action = _injectedAction.Dequeue();
if (action != null)
{
action.Invoke();
}
}
}
#region Helpers
protected internal static PlayFabError GeneratePlayFabError(string apiEndpoint, string json, object customData)
{
Dictionary<string, object> errorDict = null;
Dictionary<string, List<string>> errorDetails = null;
var serializer = PluginManager.GetPlugin<ISerializerPlugin>(PluginContract.PlayFab_Serializer);
try
{
// Deserialize the error
errorDict = serializer.DeserializeObject<Dictionary<string, object>>(json);
}
catch (Exception) { /* Unusual, but shouldn't actually matter */ }
try
{
object errorDetailsString;
if (errorDict != null && errorDict.TryGetValue("errorDetails", out errorDetailsString))
errorDetails = serializer.DeserializeObject<Dictionary<string, List<string>>>(errorDetailsString.ToString());
}
catch (Exception) { /* Unusual, but shouldn't actually matter */ }
return new PlayFabError
{
ApiEndpoint = apiEndpoint,
HttpCode = errorDict != null && errorDict.ContainsKey("code") ? Convert.ToInt32(errorDict["code"]) : 400,
HttpStatus = errorDict != null && errorDict.ContainsKey("status") ? (string)errorDict["status"] : "BadRequest",
Error = errorDict != null && errorDict.ContainsKey("errorCode") ? (PlayFabErrorCode)Convert.ToInt32(errorDict["errorCode"]) : PlayFabErrorCode.ServiceUnavailable,
ErrorMessage = errorDict != null && errorDict.ContainsKey("errorMessage") ? (string)errorDict["errorMessage"] : json,
ErrorDetails = errorDetails,
CustomData = customData,
RetryAfterSeconds = errorDict != null && errorDict.ContainsKey("retryAfterSeconds") ? Convert.ToUInt32(errorDict["retryAfterSeconds"]) : (uint?)null,
};
}
protected internal static void SendErrorEvent(PlayFabRequestCommon request, PlayFabError error)
{
if (ApiProcessingErrorEventHandler == null)
return;
try
{
ApiProcessingErrorEventHandler(request, error);
}
catch (Exception e)
{
Debug.LogException(e);
}
}
protected internal static void SendEvent(string apiEndpoint, PlayFabRequestCommon request, PlayFabResultCommon result, ApiProcessingEventType eventType)
{
if (ApiProcessingEventHandler == null)
return;
try
{
ApiProcessingEventHandler(new ApiProcessingEventArgs
{
ApiEndpoint = apiEndpoint,
EventType = eventType,
Request = request,
Result = result
});
}
catch (Exception e)
{
Debug.LogException(e);
}
}
public static void ClearAllEvents()
{
ApiProcessingEventHandler = null;
ApiProcessingErrorEventHandler = null;
}
#if PLAYFAB_REQUEST_TIMING
protected internal static void SendRequestTiming(RequestTiming rt)
{
if (ApiRequestTimingEventHandler != null)
{
ApiRequestTimingEventHandler(rt);
}
}
#endif
#endregion
private readonly Queue<IEnumerator> _injectedCoroutines = new Queue<IEnumerator>();
private readonly Queue<Action> _injectedAction = new Queue<Action>();
public void InjectInUnityThread(IEnumerator x)
{
_injectedCoroutines.Enqueue(x);
}
public void InjectInUnityThread(Action action)
{
_injectedAction.Enqueue(action);
}
}
#region Event Classes
public enum ApiProcessingEventType
{
Pre,
Post
}
public class ApiProcessingEventArgs
{
public string ApiEndpoint;
public ApiProcessingEventType EventType;
public PlayFabRequestCommon Request;
public PlayFabResultCommon Result;
public TRequest GetRequest<TRequest>() where TRequest : PlayFabRequestCommon
{
return Request as TRequest;
}
}
#endregion
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 97a8a3caac8b73541aa8a9a1e330f479
timeCreated: 1462575707
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,244 @@
#if UNITY_2017_2_OR_NEWER
using PlayFab.SharedModels;
using System;
using System.Collections;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
namespace PlayFab.Internal
{
public class PlayFabUnityHttp : ITransportPlugin
{
private bool _isInitialized = false;
private readonly int _pendingWwwMessages = 0;
public bool IsInitialized { get { return _isInitialized; } }
public void Initialize() { _isInitialized = true; }
public void Update() { }
public void OnDestroy() { }
public void SimpleGetCall(string fullUrl, Action<byte[]> successCallback, Action<string> errorCallback)
{
PlayFabHttp.instance.StartCoroutine(SimpleCallCoroutine("get", fullUrl, null, successCallback, errorCallback));
}
public void SimplePutCall(string fullUrl, byte[] payload, Action<byte[]> successCallback, Action<string> errorCallback)
{
PlayFabHttp.instance.StartCoroutine(SimpleCallCoroutine("put", fullUrl, payload, successCallback, errorCallback));
}
public void SimplePostCall(string fullUrl, byte[] payload, Action<byte[]> successCallback, Action<string> errorCallback)
{
PlayFabHttp.instance.StartCoroutine(SimpleCallCoroutine("post", fullUrl, payload, successCallback, errorCallback));
}
private static IEnumerator SimpleCallCoroutine(string method, string fullUrl, byte[] payload, Action<byte[]> successCallback, Action<string> errorCallback)
{
if (payload == null)
{
using (UnityWebRequest www = UnityWebRequest.Get(fullUrl))
{
#if UNITY_2017_2_OR_NEWER
www.timeout = PlayFabSettings.RequestTimeout / 1000;
yield return www.SendWebRequest();
#else
yield return www.Send();
#endif
if (!string.IsNullOrEmpty(www.error))
errorCallback(www.error);
else
successCallback(www.downloadHandler.data);
};
}
else
{
UnityWebRequest request;
if (method == "put")
{
request = UnityWebRequest.Put(fullUrl, payload);
}
else
{
request = new UnityWebRequest(fullUrl, "POST");
request.uploadHandler = (UploadHandler)new UploadHandlerRaw(payload);
request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
request.SetRequestHeader("Content-Type", "application/json");
}
#if UNITY_2017_2_OR_NEWER
#if !UNITY_2019_1_OR_NEWER
request.chunkedTransfer = false; // can be removed after Unity's PUT will be more stable
#endif
yield return request.SendWebRequest();
#else
yield return request.Send();
#endif
#if UNITY_2020_1_OR_NEWER
if (request.result == UnityWebRequest.Result.ConnectionError || request.result == UnityWebRequest.Result.ProtocolError)
#else
if (request.isNetworkError || request.isHttpError)
#endif
{
errorCallback(request.error);
}
else
{
successCallback(request.downloadHandler.data);
}
request.Dispose();
}
}
public void MakeApiCall(object reqContainerObj)
{
CallRequestContainer reqContainer = (CallRequestContainer)reqContainerObj;
reqContainer.RequestHeaders["Content-Type"] = "application/json";
// Start the www corouting to Post, and get a response or error which is then passed to the callbacks.
PlayFabHttp.instance.StartCoroutine(Post(reqContainer));
}
private IEnumerator Post(CallRequestContainer reqContainer)
{
#if PLAYFAB_REQUEST_TIMING
var stopwatch = System.Diagnostics.Stopwatch.StartNew();
var startTime = DateTime.UtcNow;
#endif
using var www = new UnityWebRequest(reqContainer.FullUrl)
{
uploadHandler = new UploadHandlerRaw(reqContainer.Payload),
downloadHandler = new DownloadHandlerBuffer(),
method = "POST"
};
foreach (var headerPair in reqContainer.RequestHeaders)
{
if (!string.IsNullOrEmpty(headerPair.Key) && !string.IsNullOrEmpty(headerPair.Value))
www.SetRequestHeader(headerPair.Key, headerPair.Value);
else
Debug.LogWarning("Null header: " + headerPair.Key + " = " + headerPair.Value);
}
#if UNITY_2017_2_OR_NEWER
yield return www.SendWebRequest();
#else
yield return www.Send();
#endif
#if PLAYFAB_REQUEST_TIMING
stopwatch.Stop();
var timing = new PlayFabHttp.RequestTiming {
StartTimeUtc = startTime,
ApiEndpoint = reqContainer.ApiEndpoint,
WorkerRequestMs = (int)stopwatch.ElapsedMilliseconds,
MainThreadRequestMs = (int)stopwatch.ElapsedMilliseconds
};
PlayFabHttp.SendRequestTiming(timing);
#endif
if (!string.IsNullOrEmpty(www.error))
{
OnError(www.error, reqContainer);
}
else
{
try
{
byte[] responseBytes = www.downloadHandler.data;
string responseText = System.Text.Encoding.UTF8.GetString(responseBytes, 0, responseBytes.Length);
OnResponse(responseText, reqContainer);
}
catch (Exception e)
{
OnError("Unhandled error in PlayFabUnityHttp: " + e, reqContainer);
}
}
www.Dispose();
}
public int GetPendingMessages()
{
return _pendingWwwMessages;
}
public void OnResponse(string response, CallRequestContainer reqContainer)
{
try
{
#if PLAYFAB_REQUEST_TIMING
var startTime = DateTime.UtcNow;
#endif
var serializer = PluginManager.GetPlugin<ISerializerPlugin>(PluginContract.PlayFab_Serializer);
var httpResult = serializer.DeserializeObject<HttpResponseObject>(response);
if (httpResult.code == 200)
{
// We have a good response from the server
reqContainer.JsonResponse = serializer.SerializeObject(httpResult.data);
reqContainer.DeserializeResultJson();
reqContainer.ApiResult.Request = reqContainer.ApiRequest;
reqContainer.ApiResult.CustomData = reqContainer.CustomData;
PlayFabHttp.instance.OnPlayFabApiResult(reqContainer);
#if !DISABLE_PLAYFABCLIENT_API
PlayFabDeviceUtil.OnPlayFabLogin(reqContainer.ApiResult, reqContainer.settings, reqContainer.instanceApi);
#endif
try
{
PlayFabHttp.SendEvent(reqContainer.ApiEndpoint, reqContainer.ApiRequest, reqContainer.ApiResult, ApiProcessingEventType.Post);
}
catch (Exception e)
{
Debug.LogException(e);
}
try
{
reqContainer.InvokeSuccessCallback();
}
catch (Exception e)
{
Debug.LogException(e);
}
}
else
{
if (reqContainer.ErrorCallback != null)
{
reqContainer.Error = PlayFabHttp.GeneratePlayFabError(reqContainer.ApiEndpoint, response, reqContainer.CustomData);
PlayFabHttp.SendErrorEvent(reqContainer.ApiRequest, reqContainer.Error);
reqContainer.ErrorCallback(reqContainer.Error);
}
}
}
catch (Exception e)
{
Debug.LogException(e);
}
}
public void OnError(string error, CallRequestContainer reqContainer)
{
reqContainer.JsonResponse = error;
if (reqContainer.ErrorCallback != null)
{
reqContainer.Error = PlayFabHttp.GeneratePlayFabError(reqContainer.ApiEndpoint, reqContainer.JsonResponse, reqContainer.CustomData);
PlayFabHttp.SendErrorEvent(reqContainer.ApiRequest, reqContainer.Error);
reqContainer.ErrorCallback(reqContainer.Error);
}
}
}
}
#endif

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: fdda21a9c6bb5c74d85422afab113b0f
timeCreated: 1512617003
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,219 @@
#if !UNITY_2018_2_OR_NEWER // Unity has deprecated Www
using System;
using System.Collections;
using System.IO;
using PlayFab.Json;
using PlayFab.SharedModels;
using UnityEngine;
#if UNITY_5_4_OR_NEWER
using UnityEngine.Networking;
#else
using UnityEngine.Experimental.Networking;
#endif
namespace PlayFab.Internal
{
public class PlayFabWww : ITransportPlugin
{
private bool _isInitialized = false;
private int _pendingWwwMessages = 0;
public bool IsInitialized { get { return _isInitialized; } }
public void Initialize()
{
_isInitialized = true;
}
public void Update() { }
public void OnDestroy() { }
public void SimpleGetCall(string fullUrl, Action<byte[]> successCallback, Action<string> errorCallback)
{
PlayFabHttp.instance.StartCoroutine(SimpleCallCoroutine("get", fullUrl, null, successCallback, errorCallback));
}
public void SimplePutCall(string fullUrl, byte[] payload, Action<byte[]> successCallback, Action<string> errorCallback)
{
PlayFabHttp.instance.StartCoroutine(SimpleCallCoroutine("put", fullUrl, payload, successCallback, errorCallback));
}
public void SimplePostCall(string fullUrl, byte[] payload, Action<byte[]> successCallback, Action<string> errorCallback)
{
PlayFabHttp.instance.StartCoroutine(SimpleCallCoroutine("post", fullUrl, payload, successCallback, errorCallback));
}
private static IEnumerator SimpleCallCoroutine(string method, string fullUrl, byte[] payload, Action<byte[]> successCallback, Action<string> errorCallback)
{
if (payload == null)
{
var www = new WWW(fullUrl);
yield return www;
if (!string.IsNullOrEmpty(www.error))
errorCallback(www.error);
else
successCallback(www.bytes);
}
else
{
UnityWebRequest request;
if (method == "put")
{
request = UnityWebRequest.Put(fullUrl, payload);
}
else
{
var strPayload = System.Text.Encoding.UTF8.GetString(payload, 0, payload.Length);
request = UnityWebRequest.Post(fullUrl, strPayload);
}
#if UNITY_2017_2_OR_NEWER
request.chunkedTransfer = false; // can be removed after Unity's PUT will be more stable
request.SendWebRequest();
#else
request.Send();
#endif
#if !UNITY_WEBGL
while (request.uploadProgress < 1 || request.downloadProgress < 1)
{
yield return 1;
}
#else
while (!request.isDone)
{
yield return 1;
}
#endif
if (!string.IsNullOrEmpty(request.error))
errorCallback(request.error);
else
successCallback(request.downloadHandler.data);
}
}
public void MakeApiCall(object reqContainerObj)
{
CallRequestContainer reqContainer = (CallRequestContainer)reqContainerObj;
reqContainer.RequestHeaders["Content-Type"] = "application/json";
//Debug.LogFormat("Posting {0} to Url: {1}", req.Trim(), url);
var www = new WWW(reqContainer.FullUrl, reqContainer.Payload, reqContainer.RequestHeaders);
#if PLAYFAB_REQUEST_TIMING
var stopwatch = System.Diagnostics.Stopwatch.StartNew();
#endif
// Start the www corouting to Post, and get a response or error which is then passed to the callbacks.
Action<string> wwwSuccessCallback = (response) =>
{
try
{
#if PLAYFAB_REQUEST_TIMING
var startTime = DateTime.UtcNow;
#endif
var serializer = PluginManager.GetPlugin<ISerializerPlugin>(PluginContract.PlayFab_Serializer);
var httpResult = serializer.DeserializeObject<HttpResponseObject>(response);
if (httpResult.code == 200)
{
// We have a good response from the server
reqContainer.JsonResponse = serializer.SerializeObject(httpResult.data);
reqContainer.DeserializeResultJson();
reqContainer.ApiResult.Request = reqContainer.ApiRequest;
reqContainer.ApiResult.CustomData = reqContainer.CustomData;
PlayFabHttp.instance.OnPlayFabApiResult(reqContainer);
#if !DISABLE_PLAYFABCLIENT_API
PlayFabDeviceUtil.OnPlayFabLogin(reqContainer.ApiResult, reqContainer.settings, reqContainer.instanceApi);
#endif
try
{
PlayFabHttp.SendEvent(reqContainer.ApiEndpoint, reqContainer.ApiRequest, reqContainer.ApiResult, ApiProcessingEventType.Post);
}
catch (Exception e)
{
Debug.LogException(e);
}
#if PLAYFAB_REQUEST_TIMING
stopwatch.Stop();
var timing = new PlayFabHttp.RequestTiming {
StartTimeUtc = startTime,
ApiEndpoint = reqContainer.ApiEndpoint,
WorkerRequestMs = (int)stopwatch.ElapsedMilliseconds,
MainThreadRequestMs = (int)stopwatch.ElapsedMilliseconds
};
PlayFabHttp.SendRequestTiming(timing);
#endif
try
{
reqContainer.InvokeSuccessCallback();
}
catch (Exception e)
{
Debug.LogException(e);
}
}
else
{
if (reqContainer.ErrorCallback != null)
{
reqContainer.Error = PlayFabHttp.GeneratePlayFabError(reqContainer.ApiEndpoint, response, reqContainer.CustomData);
PlayFabHttp.SendErrorEvent(reqContainer.ApiRequest, reqContainer.Error);
reqContainer.ErrorCallback(reqContainer.Error);
}
}
}
catch (Exception e)
{
Debug.LogException(e);
}
};
Action<string> wwwErrorCallback = (errorCb) =>
{
reqContainer.JsonResponse = errorCb;
if (reqContainer.ErrorCallback != null)
{
reqContainer.Error = PlayFabHttp.GeneratePlayFabError(reqContainer.ApiEndpoint, reqContainer.JsonResponse, reqContainer.CustomData);
PlayFabHttp.SendErrorEvent(reqContainer.ApiRequest, reqContainer.Error);
reqContainer.ErrorCallback(reqContainer.Error);
}
};
PlayFabHttp.instance.StartCoroutine(PostPlayFabApiCall(www, wwwSuccessCallback, wwwErrorCallback));
}
private IEnumerator PostPlayFabApiCall(WWW www, Action<string> wwwSuccessCallback, Action<string> wwwErrorCallback)
{
yield return www;
if (!string.IsNullOrEmpty(www.error))
{
wwwErrorCallback(www.error);
}
else
{
try
{
byte[] responseBytes = www.bytes;
string responseText = System.Text.Encoding.UTF8.GetString(responseBytes, 0, responseBytes.Length);
wwwSuccessCallback(responseText);
}
catch (Exception e)
{
wwwErrorCallback("Unhandled error in PlayFabWWW: " + e);
}
}
www.Dispose();
}
public int GetPendingMessages()
{
return _pendingWwwMessages;
}
}
}
#endif

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 71ae810a641b9644187c8824db5ff1fe
timeCreated: 1462745593
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,544 @@
#if !UNITY_WSA && !UNITY_WP8
using System;
using UnityEngine;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Threading;
using PlayFab.SharedModels;
#if !DISABLE_PLAYFABCLIENT_API
using PlayFab.ClientModels;
#endif
namespace PlayFab.Internal
{
public class PlayFabWebRequest : ITransportPlugin
{
/// <summary>
/// Disable encryption certificate validation within PlayFabWebRequest using this request.
/// This is not generally recommended.
/// As of early 2018:
/// None of the built-in Unity mechanisms validate the certificate, using .Net 3.5 equivalent runtime
/// It is also not currently feasible to provide a single cross platform solution that will correctly validate a certificate.
/// The Risk:
/// All Unity HTTPS mechanisms are vulnerable to Man-In-The-Middle attacks.
/// The only more-secure option is to define a custom CustomCertValidationHook, specifically tailored to the platforms you support,
/// which validate the cert based on a list of trusted certificate providers. This list of providers must be able to update itself, as the
/// base certificates for those providers will also expire and need updating on a regular basis.
/// </summary>
public static void SkipCertificateValidation()
{
var rcvc = new System.Net.Security.RemoteCertificateValidationCallback(AcceptAllCertifications); //(sender, cert, chain, ssl) => true
ServicePointManager.ServerCertificateValidationCallback = rcvc;
certValidationSet = true;
}
/// <summary>
/// Provide PlayFabWebRequest with a custom ServerCertificateValidationCallback which can be used to validate the PlayFab encryption certificate.
/// Please do not:
/// - Hard code the current PlayFab certificate information - The PlayFab certificate updates itself on a regular schedule, and your game will fail and require a republish to fix
/// - Hard code a list of static certificate authorities - Any single exported list of certificate authorities will become out of date, and have the same problem when the CA cert expires
/// Real solution:
/// - A mechanism where a valid certificate authority list can be securely downloaded and updated without republishing the client when existing certificates expire.
/// </summary>
public static System.Net.Security.RemoteCertificateValidationCallback CustomCertValidationHook
{
set
{
ServicePointManager.ServerCertificateValidationCallback = value;
certValidationSet = true;
}
}
private static readonly Queue<Action> ResultQueueTransferThread = new Queue<Action>();
private static readonly Queue<Action> ResultQueueMainThread = new Queue<Action>();
private static readonly List<CallRequestContainer> ActiveRequests = new List<CallRequestContainer>();
private static bool certValidationSet = false;
private static Thread _requestQueueThread;
private static readonly object _ThreadLock = new object();
private static readonly TimeSpan ThreadKillTimeout = TimeSpan.FromSeconds(60);
private static DateTime _threadKillTime = DateTime.UtcNow + ThreadKillTimeout; // Kill the thread after 1 minute of inactivity
private static bool _isApplicationPlaying;
private static int _activeCallCount;
private static string _unityVersion;
private bool _isInitialized = false;
public bool IsInitialized { get { return _isInitialized; } }
public void Initialize()
{
SetupCertificates();
_isApplicationPlaying = true;
_unityVersion = Application.unityVersion;
_isInitialized = true;
}
public void OnDestroy()
{
_isApplicationPlaying = false;
lock (ResultQueueTransferThread)
{
ResultQueueTransferThread.Clear();
}
lock (ActiveRequests)
{
ActiveRequests.Clear();
}
lock (_ThreadLock)
{
_requestQueueThread = null;
}
}
private void SetupCertificates()
{
// These are performance Optimizations for HttpWebRequests.
ServicePointManager.DefaultConnectionLimit = 10;
ServicePointManager.Expect100Continue = false;
if (!certValidationSet)
{
Debug.LogWarning("PlayFab API calls will likely fail because you have not set up a HttpWebRequest certificate validation mechanism");
Debug.LogWarning("Please set a validation callback into PlayFab.Internal.PlayFabWebRequest.CustomCertValidationHook, or set PlayFab.Internal.PlayFabWebRequest.SkipCertificateValidation()");
}
}
/// <summary>
/// This disables certificate validation, if it's been activated by a customer via SkipCertificateValidation()
/// </summary>
private static bool AcceptAllCertifications(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
{
return true;
}
public void SimpleGetCall(string fullUrl, Action<byte[]> successCallback, Action<string> errorCallback)
{
// This needs to be improved to use a decent thread-pool, but it can be improved invisibly later
var newThread = new Thread(() => SimpleHttpsWorker("GET", fullUrl, null, successCallback, errorCallback));
newThread.Start();
}
public void SimplePutCall(string fullUrl, byte[] payload, Action<byte[]> successCallback, Action<string> errorCallback)
{
// This needs to be improved to use a decent thread-pool, but it can be improved invisibly later
var newThread = new Thread(() => SimpleHttpsWorker("PUT", fullUrl, payload, successCallback, errorCallback));
newThread.Start();
}
public void SimplePostCall(string fullUrl, byte[] payload, Action<byte[]> successCallback, Action<string> errorCallback)
{
// This needs to be improved to use a decent thread-pool, but it can be improved invisibly later
var newThread = new Thread(() => SimpleHttpsWorker("POST", fullUrl, payload, successCallback, errorCallback));
newThread.Start();
}
private void SimpleHttpsWorker(string httpMethod, string fullUrl, byte[] payload, Action<byte[]> successCallback, Action<string> errorCallback)
{
// This should also use a pooled HttpWebRequest object, but that too can be improved invisibly later
var httpRequest = (HttpWebRequest)WebRequest.Create(fullUrl);
httpRequest.UserAgent = "UnityEngine-Unity; Version: " + _unityVersion;
httpRequest.Method = httpMethod;
httpRequest.KeepAlive = PlayFabSettings.RequestKeepAlive;
httpRequest.Timeout = PlayFabSettings.RequestTimeout;
httpRequest.AllowWriteStreamBuffering = false;
httpRequest.ReadWriteTimeout = PlayFabSettings.RequestTimeout;
if (payload != null)
{
httpRequest.ContentLength = payload.LongLength;
using (var stream = httpRequest.GetRequestStream())
{
stream.Write(payload, 0, payload.Length);
}
}
try
{
var response = httpRequest.GetResponse();
byte[] output = null;
using (var responseStream = response.GetResponseStream())
{
if (responseStream != null)
{
output = new byte[response.ContentLength];
responseStream.Read(output, 0, output.Length);
}
}
successCallback(output);
}
catch (WebException webException)
{
try
{
using (var responseStream = webException.Response.GetResponseStream())
{
if (responseStream != null)
using (var stream = new StreamReader(responseStream))
errorCallback(stream.ReadToEnd());
}
}
catch (Exception e)
{
Debug.LogException(e);
}
}
catch (Exception e)
{
Debug.LogException(e);
}
}
public void MakeApiCall(object reqContainerObj)
{
CallRequestContainer reqContainer = (CallRequestContainer)reqContainerObj;
reqContainer.HttpState = HttpRequestState.Idle;
lock (ActiveRequests)
{
ActiveRequests.Insert(0, reqContainer);
}
ActivateThreadWorker();
}
private static void ActivateThreadWorker()
{
lock (_ThreadLock)
{
if (_requestQueueThread != null)
{
return;
}
_requestQueueThread = new Thread(WorkerThreadMainLoop);
_requestQueueThread.Start();
}
}
private static void WorkerThreadMainLoop()
{
try
{
bool active;
lock (_ThreadLock)
{
// Kill the thread after 1 minute of inactivity
_threadKillTime = DateTime.UtcNow + ThreadKillTimeout;
}
List<CallRequestContainer> localActiveRequests = new List<CallRequestContainer>();
do
{
//process active requests
lock (ActiveRequests)
{
localActiveRequests.AddRange(ActiveRequests);
ActiveRequests.Clear();
_activeCallCount = localActiveRequests.Count;
}
var activeCalls = localActiveRequests.Count;
for (var i = activeCalls - 1; i >= 0; i--) // We must iterate backwards, because we remove at index i in some cases
{
switch (localActiveRequests[i].HttpState)
{
case HttpRequestState.Error:
localActiveRequests.RemoveAt(i); break;
case HttpRequestState.Idle:
Post(localActiveRequests[i]); break;
case HttpRequestState.Sent:
if (!localActiveRequests[i].CalledGetResponse) { // Else we'll GetResponse try again next tick
localActiveRequests[i].HttpRequest.GetResponseAsync();
localActiveRequests[i].CalledGetResponse = true;
}
else if (localActiveRequests[i].HttpRequest.HaveResponse)
ProcessHttpResponse(localActiveRequests[i]);
break;
case HttpRequestState.Received:
ProcessJsonResponse(localActiveRequests[i]);
localActiveRequests.RemoveAt(i);
break;
}
}
#region Expire Thread.
// Check if we've been inactive
lock (_ThreadLock)
{
var now = DateTime.UtcNow;
if (activeCalls > 0 && _isApplicationPlaying)
{
// Still active, reset the _threadKillTime
_threadKillTime = now + ThreadKillTimeout;
}
// Kill the thread after 1 minute of inactivity
active = now <= _threadKillTime;
if (!active)
{
_requestQueueThread = null;
}
// This thread will be stopped, so null this now, inside lock (_threadLock)
}
#endregion
Thread.Sleep(1);
} while (active);
}
catch (Exception e)
{
Debug.LogException(e);
_requestQueueThread = null;
}
}
private static void Post(CallRequestContainer reqContainer)
{
try
{
reqContainer.HttpRequest = (HttpWebRequest)WebRequest.Create(reqContainer.FullUrl);
reqContainer.HttpRequest.UserAgent = "UnityEngine-Unity; Version: " + _unityVersion;
reqContainer.HttpRequest.SendChunked = false;
// Prevents hitting a proxy if no proxy is available. TODO: Add support for proxy's.
reqContainer.HttpRequest.Proxy = null;
foreach (var pair in reqContainer.RequestHeaders)
reqContainer.HttpRequest.Headers.Add(pair.Key, pair.Value);
reqContainer.HttpRequest.ContentType = "application/json";
reqContainer.HttpRequest.Method = "POST";
reqContainer.HttpRequest.KeepAlive = PlayFabSettings.RequestKeepAlive;
reqContainer.HttpRequest.Timeout = PlayFabSettings.RequestTimeout;
reqContainer.HttpRequest.AllowWriteStreamBuffering = false;
reqContainer.HttpRequest.Proxy = null;
reqContainer.HttpRequest.ContentLength = reqContainer.Payload.LongLength;
reqContainer.HttpRequest.ReadWriteTimeout = PlayFabSettings.RequestTimeout;
//Debug.Log("Get Stream");
// Get Request Stream and send data in the body.
using (var stream = reqContainer.HttpRequest.GetRequestStream())
{
//Debug.Log("Post Stream");
stream.Write(reqContainer.Payload, 0, reqContainer.Payload.Length);
//Debug.Log("After Post stream");
}
reqContainer.HttpState = HttpRequestState.Sent;
}
catch (WebException e)
{
reqContainer.JsonResponse = ResponseToString(e.Response) ?? e.Status + ": WebException making http request to: " + reqContainer.FullUrl;
var enhancedError = new WebException(reqContainer.JsonResponse, e);
Debug.LogException(enhancedError);
QueueRequestError(reqContainer);
}
catch (Exception e)
{
reqContainer.JsonResponse = "Unhandled exception in Post : " + reqContainer.FullUrl;
var enhancedError = new Exception(reqContainer.JsonResponse, e);
Debug.LogException(enhancedError);
QueueRequestError(reqContainer);
}
}
private static void ProcessHttpResponse(CallRequestContainer reqContainer)
{
try
{
#if PLAYFAB_REQUEST_TIMING
reqContainer.Timing.WorkerRequestMs = (int)reqContainer.Stopwatch.ElapsedMilliseconds;
#endif
// Get and check the response
var httpResponse = (HttpWebResponse)reqContainer.HttpRequest.GetResponse();
if (httpResponse.StatusCode == HttpStatusCode.OK)
{
reqContainer.JsonResponse = ResponseToString(httpResponse);
}
if (httpResponse.StatusCode != HttpStatusCode.OK || string.IsNullOrEmpty(reqContainer.JsonResponse))
{
reqContainer.JsonResponse = reqContainer.JsonResponse ?? "No response from server";
QueueRequestError(reqContainer);
return;
}
else
{
// Response Recieved Successfully, now process.
}
reqContainer.HttpState = HttpRequestState.Received;
}
catch (Exception e)
{
var msg = "Unhandled exception in ProcessHttpResponse : " + reqContainer.FullUrl;
reqContainer.JsonResponse = reqContainer.JsonResponse ?? msg;
var enhancedError = new Exception(msg, e);
Debug.LogException(enhancedError);
QueueRequestError(reqContainer);
}
}
/// <summary>
/// Set the reqContainer into an error state, and queue it to invoke the ErrorCallback for that request
/// </summary>
private static void QueueRequestError(CallRequestContainer reqContainer)
{
reqContainer.Error = PlayFabHttp.GeneratePlayFabError(reqContainer.ApiEndpoint, reqContainer.JsonResponse, reqContainer.CustomData); // Decode the server-json error
reqContainer.HttpState = HttpRequestState.Error;
lock (ResultQueueTransferThread)
{
//Queue The result callbacks to run on the main thread.
ResultQueueTransferThread.Enqueue(() =>
{
PlayFabHttp.SendErrorEvent(reqContainer.ApiRequest, reqContainer.Error);
if (reqContainer.ErrorCallback != null)
reqContainer.ErrorCallback(reqContainer.Error);
});
}
}
private static void ProcessJsonResponse(CallRequestContainer reqContainer)
{
try
{
var serializer = PluginManager.GetPlugin<ISerializerPlugin>(PluginContract.PlayFab_Serializer);
var httpResult = serializer.DeserializeObject<HttpResponseObject>(reqContainer.JsonResponse);
#if PLAYFAB_REQUEST_TIMING
reqContainer.Timing.WorkerRequestMs = (int)reqContainer.Stopwatch.ElapsedMilliseconds;
#endif
//This would happen if playfab returned a 500 internal server error or a bad json response.
if (httpResult == null || httpResult.code != 200)
{
QueueRequestError(reqContainer);
return;
}
reqContainer.JsonResponse = serializer.SerializeObject(httpResult.data);
reqContainer.DeserializeResultJson(); // Assigns Result with a properly typed object
reqContainer.ApiResult.Request = reqContainer.ApiRequest;
reqContainer.ApiResult.CustomData = reqContainer.CustomData;
if(_isApplicationPlaying)
{
PlayFabHttp.instance.OnPlayFabApiResult(reqContainer);
}
#if !DISABLE_PLAYFABCLIENT_API
lock (ResultQueueTransferThread)
{
ResultQueueTransferThread.Enqueue(() => { PlayFabDeviceUtil.OnPlayFabLogin(reqContainer.ApiResult, reqContainer.settings, reqContainer.instanceApi); });
}
#endif
lock (ResultQueueTransferThread)
{
//Queue The result callbacks to run on the main thread.
ResultQueueTransferThread.Enqueue(() =>
{
#if PLAYFAB_REQUEST_TIMING
reqContainer.Stopwatch.Stop();
reqContainer.Timing.MainThreadRequestMs = (int)reqContainer.Stopwatch.ElapsedMilliseconds;
PlayFabHttp.SendRequestTiming(reqContainer.Timing);
#endif
try
{
PlayFabHttp.SendEvent(reqContainer.ApiEndpoint, reqContainer.ApiRequest, reqContainer.ApiResult, ApiProcessingEventType.Post);
reqContainer.InvokeSuccessCallback();
}
catch (Exception e)
{
Debug.LogException(e); // Log the user's callback exception back to them without halting PlayFabHttp
}
});
}
}
catch (Exception e)
{
var msg = "Unhandled exception in ProcessJsonResponse : " + reqContainer.FullUrl;
reqContainer.JsonResponse = reqContainer.JsonResponse ?? msg;
var enhancedError = new Exception(msg, e);
Debug.LogException(enhancedError);
QueueRequestError(reqContainer);
}
}
public void Update()
{
lock (ResultQueueTransferThread)
{
while (ResultQueueTransferThread.Count > 0)
{
var actionToQueue = ResultQueueTransferThread.Dequeue();
ResultQueueMainThread.Enqueue(actionToQueue);
}
}
while (ResultQueueMainThread.Count > 0)
{
var finishedRequest = ResultQueueMainThread.Dequeue();
finishedRequest();
}
}
private static string ResponseToString(WebResponse webResponse)
{
if (webResponse == null)
return null;
try
{
using (var responseStream = webResponse.GetResponseStream())
{
if (responseStream == null)
return null;
using (var stream = new StreamReader(responseStream))
{
return stream.ReadToEnd();
}
}
}
catch (WebException webException)
{
try
{
using (var responseStream = webException.Response.GetResponseStream())
{
if (responseStream == null)
return null;
using (var stream = new StreamReader(responseStream))
{
return stream.ReadToEnd();
}
}
}
catch (Exception e)
{
Debug.LogException(e);
return null;
}
}
catch (Exception e)
{
Debug.LogException(e);
return null;
}
}
public int GetPendingMessages()
{
var count = 0;
lock (ActiveRequests)
count += ActiveRequests.Count + _activeCallCount;
lock (ResultQueueTransferThread)
count += ResultQueueTransferThread.Count;
return count;
}
}
}
#endif

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 18fd1a0daadd68d45aebf8c19cac2bda
timeCreated: 1466016486
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: