private static void OnImageDownloadCompleted(UnityWebRequestAsyncOperation operation, ImageRequest request) { UnityWebRequest webRequest = operation.webRequest; request.isDone = true; if (webRequest.isNetworkError || webRequest.isHttpError) { request.error = WebRequestError.GenerateFromWebRequest(webRequest); request.NotifyFailed(); } else { #if DEBUG if (PluginSettings.data.logAllRequests) { var responseTimeStamp = ServerTimeStamp.Now; Debug.Log("IMAGE DOWNLOAD SUCEEDED" + "\nDownload completed at: " + ServerTimeStamp.ToLocalDateTime(responseTimeStamp) + "\nURL: " + webRequest.url); } #endif request.imageTexture = (webRequest.downloadHandler as DownloadHandlerTexture).texture; request.NotifySucceeded(); } }
private static void OnImageDownloadCompleted(UnityWebRequestAsyncOperation operation, ImageRequest request) { UnityWebRequest webRequest = operation.webRequest; request.isDone = true; if (webRequest.isNetworkError || webRequest.isHttpError) { request.error = WebRequestError.GenerateFromWebRequest(webRequest); request.NotifyFailed(); } else { #if DEBUG if (DownloadClient.logAllRequests) { var responseTimeStamp = ServerTimeStamp.Now; Debug.Log(String.Format("{0} REQUEST SUCEEDED\nResponse received at: {1} [{2}]\nURL: {3}\nResponse: {4}\n", webRequest.method.ToUpper(), ServerTimeStamp.ToLocalDateTime(responseTimeStamp), responseTimeStamp, webRequest.url, webRequest.downloadHandler.text)); } #endif request.imageTexture = (webRequest.downloadHandler as DownloadHandlerTexture).texture; request.NotifySucceeded(); } }
// ---------[ INITIALIZATION ]--------- public static WebRequestError GenerateFromWebRequest(UnityEngine.Networking.UnityWebRequest webRequest) { UnityEngine.Debug.Assert(webRequest.isNetworkError || webRequest.isHttpError); WebRequestError error; WebRequestError.APIWrapper errorWrapper = JsonConvert.DeserializeObject <APIWrapper>(webRequest.downloadHandler.text); if (errorWrapper != null && errorWrapper.error != null) { error = errorWrapper.error; } else { error = new WebRequestError(); error.message = webRequest.error; } error.responseCode = (int)webRequest.responseCode; error.method = webRequest.method.ToUpper(); error.url = webRequest.url; error.timeStamp = ServerTimeStamp.Now; return(error); }
// ---------[ Internal Callbacks ]--------- private void SubmissionError_Local(string errorMessage) { if (this != null && this.onError != null) { WebRequestError error = WebRequestError.GenerateLocal(errorMessage); this.onError.Invoke(error); } }
private static void OnModBinaryRequestCompleted(UnityWebRequestAsyncOperation operation, ModBinaryRequest request) { UnityWebRequest webRequest = operation.webRequest; request.isDone = true; if (webRequest.isNetworkError || webRequest.isHttpError) { request.error = WebRequestError.GenerateFromWebRequest(webRequest); request.NotifyFailed(); } else { #if DEBUG if (GlobalSettings.LOG_ALL_WEBREQUESTS) { var responseTimeStamp = ServerTimeStamp.Now; Debug.Log("DOWNLOAD SUCEEDED" + "\nDownload completed at: " + ServerTimeStamp.ToLocalDateTime(responseTimeStamp) + "\nURL: " + webRequest.url + "\nFilePath: " + request.binaryFilePath); } #endif try { if (File.Exists(request.binaryFilePath)) { File.Delete(request.binaryFilePath); } File.Move(request.binaryFilePath + ".download", request.binaryFilePath); } catch (Exception e) { string warningInfo = ("[mod.io] Failed to save mod binary." + "\nFile: " + request.binaryFilePath + "\n\n"); Debug.LogWarning(warningInfo + Utility.GenerateExceptionDebugString(e)); request.NotifyFailed(); } request.NotifySucceeded(); } }
internal void NotifyFailed() { #if DEBUG if (GlobalSettings.LOG_ALL_WEBREQUESTS && error != null) { WebRequestError.LogAsWarning(error); } #endif if (failed != null) { failed(this); } }
// ---------[ INITIALIZATION ]--------- public static WebRequestError GenerateFromWebRequest(UnityWebRequest webRequest) { UnityEngine.Debug.Assert(webRequest != null); UnityEngine.Debug.Assert(webRequest.isNetworkError || webRequest.isHttpError); WebRequestError error = new WebRequestError(); error.webRequest = webRequest; error.timeStamp = ParseDateHeaderAsTimeStamp(webRequest); error.ApplyAPIErrorValues(); error.ApplyInterpretedValues(); return(error); }
private static void DownloadModBinary_Internal(ModfileIdPair idPair, string downloadURL) { FileDownloadInfo downloadInfo = modfileDownloadMap[idPair]; downloadInfo.request = UnityWebRequest.Get(downloadURL); string tempFilePath = downloadInfo.target + ".download"; DataStorage.WriteFile(tempFilePath, new byte[0], (p, success) => { if (success) { downloadInfo.request.downloadHandler = new DownloadHandlerFile(tempFilePath); #if PLATFORM_PS4 // NOTE(@jackson): This workaround addresses an issue in UnityWebRequests on the // PS4 whereby redirects fail in specific cases. Special thanks to @Eamon of // Spiderling Studios (http://spiderlinggames.co.uk/) downloadInfo.request.redirectLimit = 0; #endif var operation = downloadInfo.request.SendWebRequest(); #if DEBUG DebugUtilities.DebugDownload(operation, LocalUser.instance, tempFilePath); #endif operation.completed += (o) => DownloadClient.OnModBinaryRequestCompleted(idPair); DownloadClient.StartMonitoringSpeed(); // notify download started if (DownloadClient.modfileDownloadStarted != null) { DownloadClient.modfileDownloadStarted(idPair, downloadInfo); } } else if (DownloadClient.modfileDownloadFailed != null) { string warningInfo = ("Failed to create download file on disk." + "\nSource: " + downloadURL + "\nDestination: " + tempFilePath + "\n\n"); modfileDownloadFailed(idPair, WebRequestError.GenerateLocal(warningInfo)); } }); }
public static WebRequestError GenerateLocal(string errorMessage) { WebRequestError error = new WebRequestError() { webRequest = null, timeStamp = ServerTimeStamp.Now, errorMessage = errorMessage, displayMessage = errorMessage, isAuthenticationInvalid = false, isServerUnreachable = false, isRequestUnresolvable = false, limitedUntilTimeStamp = -1, }; return(error); }
private static void OnImageDownloadCompleted(UnityWebRequestAsyncOperation operation, ImageRequest request) { UnityWebRequest webRequest = operation.webRequest; request.isDone = true; if (webRequest.isNetworkError || webRequest.isHttpError) { request.error = WebRequestError.GenerateFromWebRequest(webRequest); request.NotifyFailed(); } else { request.imageTexture = (webRequest.downloadHandler as DownloadHandlerTexture).texture; request.NotifySucceeded(); } }
public static void UploadModBinary_Unzipped(int modId, EditableModfile modfileValues, string unzippedBinaryLocation, bool setPrimary, Action <Modfile> onSuccess, Action <WebRequestError> onError) { string binaryZipLocation = Application.temporaryCachePath + "/modio/" + System.IO.Path.GetFileNameWithoutExtension(unzippedBinaryLocation) + DateTime.Now.ToFileTime() + ".zip"; bool zipSucceeded = false; try { Directory.CreateDirectory(Path.GetDirectoryName(binaryZipLocation)); using (var zip = new Ionic.Zip.ZipFile()) { zip.AddFile(unzippedBinaryLocation); zip.Save(binaryZipLocation); } zipSucceeded = true; } catch (Exception e) { Debug.LogError("[mod.io] Unable to zip mod binary prior to uploading.\n\n" + Utility.GenerateExceptionDebugString(e)); WebRequestError error = new WebRequestError() { message = "Unable to zip mod binary prior to uploading", url = binaryZipLocation, timeStamp = ServerTimeStamp.Now, responseCode = 0, }; onError(error); } if (zipSucceeded) { UploadModBinary_Zipped(modId, modfileValues, binaryZipLocation, setPrimary, onSuccess, onError); } }
private string ConvertErrorToHelpString(WebRequestError error) { if (error.fieldValidationMessages != null && error.fieldValidationMessages.Count > 0) { var helpString = new System.Text.StringBuilder(); foreach (string message in error.fieldValidationMessages.Values) { helpString.Append(message + "\n"); } helpString.Length -= 1; return(helpString.ToString()); } else { return(error.message); } }
private static void DownloadModBinary_Internal(ModfileIdPair idPair, string downloadURL) { FileDownloadInfo downloadInfo = modfileDownloadMap[idPair]; downloadInfo.request = UnityWebRequest.Get(downloadURL); string tempFilePath = downloadInfo.target + ".download"; try { Directory.CreateDirectory(Path.GetDirectoryName(tempFilePath)); downloadInfo.request.downloadHandler = new DownloadHandlerFile(tempFilePath); #if PLATFORM_PS4 // NOTE(@jackson): This workaround addresses an issue in UnityWebRequests on the // PS4 whereby redirects fail in specific cases. Special thanks to @Eamon of // Spiderling Studios (http://spiderlinggames.co.uk/) downloadInfo.request.redirectLimit = 0; #endif } catch (Exception e) { string warningInfo = ("Failed to create download file on disk." + "\nFile: " + tempFilePath + "\n\n"); Debug.LogWarning("[mod.io] " + warningInfo + Utility.GenerateExceptionDebugString(e)); if (modfileDownloadFailed != null) { modfileDownloadFailed(idPair, WebRequestError.GenerateLocal(warningInfo)); } return; } var operation = downloadInfo.request.SendWebRequest(); #if DEBUG if (PluginSettings.data.logAllRequests) { string requestHeaders = ""; List <string> requestKeys = new List <string>(APIClient.UNITY_REQUEST_HEADER_KEYS); requestKeys.AddRange(APIClient.MODIO_REQUEST_HEADER_KEYS); foreach (string headerKey in requestKeys) { string headerValue = downloadInfo.request.GetRequestHeader(headerKey); if (headerValue != null) { requestHeaders += "\n" + headerKey + ": " + headerValue; } } int timeStamp = ServerTimeStamp.Now; Debug.Log("DOWNLOAD REQUEST SENT" + "\nTimeStamp: [" + timeStamp.ToString() + "] " + ServerTimeStamp.ToLocalDateTime(timeStamp).ToString() + "\nURL: " + downloadInfo.request.url + "\nHeaders: " + requestHeaders); } #endif operation.completed += (o) => DownloadClient.OnModBinaryRequestCompleted(idPair); DownloadClient.StartMonitoringSpeed(); // notify download started if (DownloadClient.modfileDownloadStarted != null) { DownloadClient.modfileDownloadStarted(idPair, downloadInfo); } }
/// <summary>Generates a debug-friendly string of a web request response.</summary> public static string GetResponseInfo(UnityWebRequest webRequest) { if (webRequest == null) { return("NULL_WEB_REQUEST"); } // get info var responseString = new System.Text.StringBuilder(); responseString.Append("URL: "); responseString.Append(webRequest.url); responseString.Append(" ("); responseString.Append(webRequest.method.ToUpper()); responseString.AppendLine(")"); responseString.Append("Response Code: "); responseString.AppendLine(webRequest.responseCode.ToString()); responseString.Append("Response Error: "); if (string.IsNullOrEmpty(webRequest.error)) { responseString.AppendLine("NO_ERROR"); } else { responseString.AppendLine(webRequest.error); } // add request headers responseString.AppendLine("Headers:"); var responseHeaders = webRequest.GetResponseHeaders(); if (responseHeaders == null || responseHeaders.Count == 0) { responseString.AppendLine(" NONE"); } else { foreach (var kvp in responseHeaders) { responseString.Append(" "); responseString.Append(kvp.Key); responseString.Append('='); responseString.Append(kvp.Value); responseString.AppendLine(); } } // add error information if (webRequest.isNetworkError || webRequest.isHttpError) { var error = WebRequestError.GenerateFromWebRequest(webRequest); responseString.AppendLine("mod.io Error Details:"); // add flags responseString.Append(" flags="); if (error.isAuthenticationInvalid) { responseString.Append("[AuthenticationInvalid]"); } if (error.isServerUnreachable) { responseString.Append("[ServerUnreachable]"); } if (error.isRequestUnresolvable) { responseString.Append("[RequestUnresolvable]"); } if (!error.isAuthenticationInvalid && !error.isServerUnreachable && !error.isRequestUnresolvable) { responseString.Append("[NONE]"); } responseString.AppendLine(); // add rate limiting responseString.Append(" limitedUntilTimeStamp="); responseString.AppendLine(error.limitedUntilTimeStamp.ToString()); // add messages responseString.Append(" errorReference="); responseString.AppendLine(error.errorReference.ToString()); responseString.Append(" errorMessage="); responseString.AppendLine(error.errorMessage); if (error.fieldValidationMessages != null && error.fieldValidationMessages.Count > 0) { responseString.AppendLine(" fieldValidation:"); foreach (var kvp in error.fieldValidationMessages) { responseString.Append(" ["); responseString.Append(kvp.Key); responseString.Append("]="); responseString.Append(kvp.Value); responseString.AppendLine(); } } responseString.Append(" displayMessage="); responseString.AppendLine(error.displayMessage); } // body responseString.AppendLine("Body:"); string bodyText = null; try { if (webRequest.downloadHandler == null) { bodyText = " NULL_DOWNLOAD_HANDLER"; } else { bodyText = webRequest.downloadHandler.text; } } catch { bodyText = " TEXT_ACCESS_NOT_SUPPORTED"; } responseString.AppendLine(bodyText); return(responseString.ToString()); }
/// <summary>Attempts to reauthenticate using the stored external auth ticket.</summary> public static void ReauthenticateWithStoredExternalAuthData(bool hasUserAcceptedTerms, Action <UserProfile> onSuccess, Action <WebRequestError> onError) { ExternalAuthenticationData authData = LocalUser.ExternalAuthentication; Debug.Assert(!string.IsNullOrEmpty(authData.ticket)); Debug.Assert(authData.provider != ExternalAuthenticationProvider.None); Action <string> onSuccessWrapper = (t) => { LocalUser.OAuthToken = t; LocalUser.WasTokenRejected = false; LocalUser.Save(); if (onSuccess != null) { UserAccountManagement.UpdateUserProfile(onSuccess, onError); } }; switch (LocalUser.ExternalAuthentication.provider) { case ExternalAuthenticationProvider.Steam: { APIClient.RequestSteamAuthentication(authData.ticket, hasUserAcceptedTerms, onSuccessWrapper, onError); } break; case ExternalAuthenticationProvider.GOG: { APIClient.RequestGOGAuthentication(authData.ticket, hasUserAcceptedTerms, onSuccessWrapper, onError); } break; case ExternalAuthenticationProvider.ItchIO: { APIClient.RequestItchIOAuthentication(authData.ticket, hasUserAcceptedTerms, onSuccessWrapper, onError); } break; case ExternalAuthenticationProvider.OculusRift: { string token = authData.ticket; string nonce = null; string userIdString = null; int userId = -1; string errorMessage = null; if (authData.additionalData == null) { errorMessage = "The user id and nonce are missing."; } else if (!authData.additionalData.TryGetValue(ExternalAuthenticationData.OculusRiftKeys.NONCE, out nonce) || string.IsNullOrEmpty(nonce)) { errorMessage = "The nonce is missing."; } else if (!authData.additionalData.TryGetValue(ExternalAuthenticationData.OculusRiftKeys.USER_ID, out userIdString) || string.IsNullOrEmpty(userIdString)) { errorMessage = "The user id is missing."; } else if (!int.TryParse(userIdString, out userId)) { errorMessage = "The user id is not parseable as an integer."; } if (errorMessage != null) { Debug.LogWarning("[mod.io] Unable to authenticate using stored Oculus Rift user data.\n" + errorMessage); if (onError != null) { var error = WebRequestError.GenerateLocal(errorMessage); onError(error); } return; } else { APIClient.RequestOculusRiftAuthentication(nonce, userId, token, hasUserAcceptedTerms, onSuccessWrapper, onError); } } break; case ExternalAuthenticationProvider.XboxLive: { APIClient.RequestXboxLiveAuthentication(authData.ticket, hasUserAcceptedTerms, onSuccessWrapper, onError); } break; default: { throw new System.NotImplementedException(); } } }
private static void OnModBinaryRequestCompleted(ModfileIdPair idPair) { FileDownloadInfo downloadInfo = DownloadClient.modfileDownloadMap[idPair]; UnityWebRequest request = downloadInfo.request; downloadInfo.bytesPerSecond = 0; if (request.isNetworkError || request.isHttpError) { if (request.error.ToUpper() == "USER ABORTED" || request.error.ToUpper() == "REQUEST ABORTED") { downloadInfo.wasAborted = true; DownloadClient.FinalizeDownload(idPair, downloadInfo); } // NOTE(@jackson): This workaround addresses an issue in UnityWebRequests on the // PS4 whereby redirects fail in specific cases. Special thanks to @Eamon of // Spiderling Studios (http://spiderlinggames.co.uk/) #if UNITY_PS4 || MODIO_DEV else if (downloadInfo.error.webRequest.responseCode == 302) // Redirect limit exceeded { string headerLocation = string.Empty; if (downloadInfo.error.webRequest.GetResponseHeaders().TryGetValue("location", out headerLocation) && !request.url.Equals(headerLocation)) { if (PluginSettings.REQUEST_LOGGING.logAllResponses) { Debug.LogFormat("[mod.io] Caught PS4 redirection error. Reattempting.\nURL: {0}", headerLocation); } downloadInfo.error = null; downloadInfo.isDone = false; DownloadModBinary_Internal(idPair, headerLocation); return; } } #endif // UNITY_PS4 else { downloadInfo.error = WebRequestError.GenerateFromWebRequest(request); DownloadClient.FinalizeDownload(idPair, downloadInfo); } } else { DataStorage.MoveFile(downloadInfo.target + ".download", downloadInfo.target, (src, dst, success) => { if (!success) { string errorMessage = ("Download succeeded but failed to rename from" + " temporary file name." + "\nTemporary file name: " + downloadInfo.target + ".download"); downloadInfo.error = WebRequestError.GenerateLocal(errorMessage); } DownloadClient.FinalizeDownload(idPair, downloadInfo); }); } }
// ------[ INITIALIZATION ]------ protected virtual void OnEnable() { // Grab Serialized Properties serializedObject.Update(); modIdProperty = serializedObject.FindProperty("modId"); editableModProfileProperty = serializedObject.FindProperty("editableModProfile"); isModListLoading = false; profileViewParts = new IModProfileViewPart[] { new LoadingProfileViewPart() }; // Profile Initialization if (modIdProperty.intValue == ScriptableModProfile.UNINITIALIZED_MOD_ID) { this.profile = null; string userAuthToken = CacheClient.LoadAuthenticatedUserToken(); if (!String.IsNullOrEmpty(userAuthToken)) { APIClient.userAuthorizationToken = userAuthToken; this.isModListLoading = true; this.modOptions = new string[] { "Loading..." }; Action <WebRequestError> onError = (e) => { WebRequestError.LogAsWarning(e); isModListLoading = false; }; ModManager.GetAuthenticatedUserProfile((userProfile) => { this.user = userProfile; // - Find User Mods - Action <List <ModProfile> > onGetUserMods = (profiles) => { modInitializationOptionIndex = 0; modList = profiles.ToArray(); modOptions = new string[modList.Length]; for (int i = 0; i < modList.Length; ++i) { ModProfile mod = modList[i]; modOptions[i] = mod.name; } isModListLoading = false; }; ModManager.GetAuthenticatedUserMods(onGetUserMods, onError); }, onError); } else { this.modOptions = new string[0]; } modInitializationOptionIndex = 0; } else { // Initialize View profile = null; System.Action <ModProfile> onGetProfile = (p) => { profile = p; profileViewParts = CreateProfileViewParts(); foreach (IModProfileViewPart viewPart in profileViewParts) { viewPart.OnEnable(editableModProfileProperty, p, this.user); } ; profileGetErrorMessage = string.Empty; }; System.Action <WebRequestError> onGetProfileError = (e) => { profile = null; profileViewParts = CreateProfileViewParts(); foreach (IModProfileViewPart viewPart in profileViewParts) { viewPart.OnEnable(editableModProfileProperty, null, this.user); } ; profileGetErrorMessage = ("Unable to fetch the mod profile data on the server.\n" + e.message); }; ModManager.GetModProfile(modIdProperty.intValue, onGetProfile, onGetProfileError); } scrollPos = Vector2.zero; isProfileSyncing = false; // Events EditorApplication.update += OnUpdate; LoginWindow.userLoggedIn += OnUserLogin; }
public static void LogAsWarning(WebRequestError error) { Debug.LogWarning("[mod.io] Web Request Failed\n" + error.ToUnityDebugString()); }
public static void LogAsWarning(WebRequestError error) { Debug.LogWarning(error.ToUnityDebugString()); }
private static void OnModBinaryRequestCompleted(ModfileIdPair idPair) { FileDownloadInfo downloadInfo = DownloadClient.modfileDownloadMap[idPair]; UnityWebRequest request = downloadInfo.request; bool succeeded = false; downloadInfo.isDone = true; downloadInfo.bytesPerSecond = 0; if (request.isNetworkError || request.isHttpError) { if (request.error.ToUpper() == "USER ABORTED" || request.error.ToUpper() == "REQUEST ABORTED") { #if DEBUG if (PluginSettings.data.logAllRequests) { Debug.Log("DOWNLOAD ABORTED" + "\nDownload aborted at: " + ServerTimeStamp.Now + "\nURL: " + request.url); } #endif downloadInfo.wasAborted = true; } // NOTE(@jackson): This workaround addresses an issue in UnityWebRequests on the // PS4 whereby redirects fail in specific cases. Special thanks to @Eamon of // Spiderling Studios (http://spiderlinggames.co.uk/) #if UNITY_PS4 else if (downloadInfo.error.responseCode == 302) // Redirect limit exceeded { string headerLocation = string.Empty; if (downloadInfo.error.responseHeaders.TryGetValue("location", out headerLocation) && !request.url.Equals(headerLocation)) { if (PluginSettings.data.logAllRequests) { Debug.LogFormat("CAUGHT DOWNLOAD REDIRECTION\nURL: {0}", headerLocation); } downloadInfo.error = null; downloadInfo.isDone = false; DownloadModBinary_Internal(idPair, headerLocation); return; } } #endif else { downloadInfo.error = WebRequestError.GenerateFromWebRequest(request); if (PluginSettings.data.logAllRequests) { WebRequestError.LogAsWarning(downloadInfo.error); } if (modfileDownloadFailed != null) { modfileDownloadFailed(idPair, downloadInfo.error); } } } else { try { if (File.Exists(downloadInfo.target)) { File.Delete(downloadInfo.target); } File.Move(downloadInfo.target + ".download", downloadInfo.target); succeeded = true; } catch (Exception e) { string warningInfo = ("Failed to save mod binary." + "\nFile: " + downloadInfo.target + "\n\n"); Debug.LogWarning("[mod.io] " + warningInfo + Utility.GenerateExceptionDebugString(e)); downloadInfo.error = WebRequestError.GenerateLocal(warningInfo); if (modfileDownloadFailed != null) { modfileDownloadFailed(idPair, downloadInfo.error); } } } if (succeeded) { #if DEBUG if (PluginSettings.data.logAllRequests) { var responseTimeStamp = ServerTimeStamp.Now; Debug.Log("DOWNLOAD SUCEEDED" + "\nDownload completed at: " + ServerTimeStamp.ToLocalDateTime(responseTimeStamp) + "\nURL: " + request.url + "\nFilePath: " + downloadInfo.target); } #endif if (modfileDownloadSucceeded != null) { modfileDownloadSucceeded(idPair, downloadInfo); } } modfileDownloadMap.Remove(idPair); DownloadClient.modfileProgressMarkers.Remove(idPair); }