diff --git a/Editor/Resources/Builder/BuilderWindow.cs b/Editor/Resources/Builder/BuilderWindow.cs index c5e8c1a8..b00e0cb6 100644 --- a/Editor/Resources/Builder/BuilderWindow.cs +++ b/Editor/Resources/Builder/BuilderWindow.cs @@ -1195,7 +1195,8 @@ public IEnumerator Json(string url, Action callback) yield return uwr.SendWebRequest(); if (uwr.result != UnityWebRequest.Result.Success) { - throw new System.Exception(uwr.error); + string errorMsg = $"HTTP/{uwr.responseCode}: {uwr.error}"; + throw new System.Exception(errorMsg); } else { @@ -1218,7 +1219,8 @@ public IEnumerator Json(string url, T postData, Action callback, Dict if (uwr.result != UnityWebRequest.Result.Success) { Debug.LogError(url + ":" + JsonUtility.ToJson(postData)); - throw new System.Exception(uwr.error); + string errorMsg = $"HTTP/{uwr.responseCode}: {uwr.error}"; + throw new System.Exception(errorMsg); } else { @@ -1323,15 +1325,28 @@ private IEnumerator UploadAvatar(Action callback) { status.AddStatus("Posted avatar successfully."); Debug.Log("Posted avatar successfully."); - callback(); selectedExistingAvatar = av; SetupExistingAvatars(); EditorCoroutineUtility.StartCoroutine(sq.AttachAvatar((slot) => { status.AddStatus("Avatar attached successfully."); - Debug.Log("Avatar attached successfully."); - callback(); - EditorCoroutineUtility.StartCoroutine(sq.SelectAvatar(() => { }, Debug.LogException, slot.UserAvatarId), this); + Debug.Log("Avatar attached successfully."); + if (slot == null) + { + status.AddStatus("Failed to select avatar: attach response was empty."); + Debug.LogError("Failed to select avatar: attach response was empty."); + callback(); + return; + } + EditorCoroutineUtility.StartCoroutine(sq.SelectAvatar(() => + { + callback(); + }, e => + { + status.AddStatus("Failed to select avatar: " + e); + Debug.LogError("Failed to select avatar: " + e); + callback(); + }, slot.UserAvatarId), this); }, e => { status.AddStatus("Failed to attach avatar: " + e); diff --git a/Editor/Resources/Builder/SideQuest/SqEditorAppApi.cs b/Editor/Resources/Builder/SideQuest/SqEditorAppApi.cs index 9d0719c3..c1002252 100644 --- a/Editor/Resources/Builder/SideQuest/SqEditorAppApi.cs +++ b/Editor/Resources/Builder/SideQuest/SqEditorAppApi.cs @@ -1,4 +1,4 @@ -using Newtonsoft.Json; +using Newtonsoft.Json; using System; using System.Collections; using System.Collections.Generic; @@ -95,7 +95,7 @@ public IEnumerator UpdateAvatar(Action OnCompleted, Action($"/v2/avatars/{avatarId}", new SqEditorAvatar() { HighId = highId, LowId = lowId, PreviewImage = screenshotId, Public = ispublic, Version = 2, Name = name}, (av) => { OnCompleted?.Invoke(av); - }, OnError, true, false, "PATCH"); + }, OnError, true, false, "PUT"); } public IEnumerator GetAvatars(Action> OnCompleted, Action OnError) { @@ -126,7 +126,7 @@ public IEnumerator SelectAvatar(Action OnCompleted, Action OnError, l yield return JsonPost($"/v2/users/me/avatars/{userAvatarId}", new SqAvatarSlotSelect() { IsSelected = true}, (u) => { OnCompleted?.Invoke(); - }, OnError, true, false,"PATCH"); + }, OnError, true, false); } /// /// Get a list of the currently logged in sidequest user's achievements @@ -533,6 +533,7 @@ private async Task UploadFileWithRetryAsync(string url, byte[] data, strin using (var request = new HttpRequestMessage(HttpMethod.Put, url)) { request.Content = content; + content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(GetMimeType(name)); // Set timeout for this specific request using (var cts = new CancellationTokenSource(TimeSpan.FromMinutes(5))) @@ -891,6 +892,26 @@ private void LoadData() } } + private string GetMimeType(string fileName) + { + var ext = Path.GetExtension(fileName)?.ToLower(); + switch (ext) + { + case ".html": return "text/html"; + case ".js": return "application/javascript"; + case ".glb": return "model/gltf-binary"; + case ".gltf": return "model/gltf+json"; + case ".png": return "image/png"; + case ".jpg": + case ".jpeg": return "image/jpeg"; + case ".gif": return "image/gif"; + case ".zip": return "application/zip"; + case ".json": return "application/json"; + case ".txt": return "text/plain"; + default: return "application/octet-stream"; + } + } + private void SaveData() { File.WriteAllText(Config.DataFile, JsonConvert.SerializeObject(Data)); diff --git a/Editor/Resources/Builder/SideQuest/SqEditorModels.cs b/Editor/Resources/Builder/SideQuest/SqEditorModels.cs index 84b8944e..49f01037 100644 --- a/Editor/Resources/Builder/SideQuest/SqEditorModels.cs +++ b/Editor/Resources/Builder/SideQuest/SqEditorModels.cs @@ -1,4 +1,4 @@ -using Newtonsoft.Json; +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.IO; @@ -492,6 +492,9 @@ public class SqAvatarSlot [JsonProperty("is_selected")] public bool IsSelected { get; set; } + + [JsonProperty("is_public", NullValueHandling = NullValueHandling.Ignore)] + public bool? IsPublic { get; set; } } public class SqAvatarSlotSelect