using System.IO; using System.Text; using UnityEngine.Networking; #if NETFX_CORE using UnityEngine.Windows; #endif namespace SRDebugger.Internal { using System; using System.Collections; using System.Collections.Generic; using Services; using SRF; using UnityEngine; public class BugReportApi { private readonly string _apiKey; private readonly BugReport _bugReport; private bool _isBusy; private UnityWebRequest _webRequest; public BugReportApi(BugReport report, string apiKey) { _bugReport = report; _apiKey = apiKey; } public bool IsComplete { get; private set; } public bool WasSuccessful { get; private set; } public string ErrorMessage { get; private set; } public float Progress { get { if (_webRequest == null) { return 0; } return Mathf.Clamp01(_webRequest.uploadProgress); } } public IEnumerator Submit() { //Debug.Log("[BugReportApi] Submit()"); if (_isBusy) { throw new InvalidOperationException("BugReportApi is already sending a bug report"); } // Reset state _isBusy = true; ErrorMessage = ""; IsComplete = false; WasSuccessful = false; _webRequest = null; string json; byte[] jsonBytes; try { json = BuildJsonRequest(_bugReport); jsonBytes = Encoding.UTF8.GetBytes(json); } catch (Exception e) { ErrorMessage = "Error building bug report."; Debug.LogError(e); SetCompletionState(false); yield break; } try { const string jsonContentType = "application/json"; _webRequest = new UnityWebRequest(SRDebugApi.BugReportEndPoint, UnityWebRequest.kHttpVerbPOST, new DownloadHandlerBuffer(), new UploadHandlerRaw(jsonBytes) { contentType = jsonContentType }); _webRequest.SetRequestHeader("Accept", jsonContentType); _webRequest.SetRequestHeader("X-ApiKey", _apiKey); } catch (Exception e) { ErrorMessage = "Error building bug report request."; Debug.LogError(e); if (_webRequest != null) { _webRequest.Dispose(); } SetCompletionState(false); } if (_webRequest == null) { SetCompletionState(false); yield break; } #if !UNITY_2017_2_OR_NEWER yield return _webRequest.Send(); #else yield return _webRequest.SendWebRequest(); #endif #if !UNITY_2017_1_OR_NEWER if(_webRequest.isError) #else if (_webRequest.isNetworkError) #endif { ErrorMessage = "Request Error: " + _webRequest.error; SetCompletionState(false); _webRequest.Dispose(); yield break; } long responseCode = _webRequest.responseCode; var responseJson = _webRequest.downloadHandler.text; _webRequest.Dispose(); if (responseCode != 200) { ErrorMessage = "Server: " + SRDebugApiUtil.ParseErrorResponse(responseJson, "Unknown response from server"); SetCompletionState(false); yield break; } SetCompletionState(true); } private void SetCompletionState(bool wasSuccessful) { _bugReport.ScreenshotData = null; WasSuccessful = wasSuccessful; IsComplete = true; _isBusy = false; if (!wasSuccessful) { Debug.LogError("Bug Reporter Error: " + ErrorMessage); } } private static string BuildJsonRequest(BugReport report) { var ht = new Hashtable(); ht.Add("userEmail", report.Email); ht.Add("userDescription", report.UserDescription); ht.Add("console", CreateConsoleDump()); ht.Add("systemInformation", report.SystemInformation); if (report.ScreenshotData != null) { ht.Add("screenshot", Convert.ToBase64String(report.ScreenshotData)); } var json = Json.Serialize(ht); return json; } private static IList> CreateConsoleDump() { var list = new List>(); var consoleLog = Service.Console.AllEntries; foreach (var consoleEntry in consoleLog) { var entry = new List(); entry.Add(consoleEntry.LogType.ToString()); entry.Add(consoleEntry.Message); entry.Add(consoleEntry.StackTrace); if (consoleEntry.Count > 1) { entry.Add(consoleEntry.Count.ToString()); } list.Add(entry); } return list; } } }