summaryrefslogtreecommitdiff
path: root/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Scripts/RuntimeBlueprintCreation.cs
diff options
context:
space:
mode:
Diffstat (limited to 'VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Scripts/RuntimeBlueprintCreation.cs')
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Scripts/RuntimeBlueprintCreation.cs421
1 files changed, 421 insertions, 0 deletions
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Scripts/RuntimeBlueprintCreation.cs b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Scripts/RuntimeBlueprintCreation.cs
new file mode 100644
index 00000000..7017dbae
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Scripts/RuntimeBlueprintCreation.cs
@@ -0,0 +1,421 @@
+using UnityEngine;
+using UnityEngine.UI;
+using System.Collections;
+using System.Collections.Generic;
+using VRC.Core;
+using VRC.SDKBase;
+
+namespace VRCSDK2
+{
+#if UNITY_EDITOR
+ public class RuntimeBlueprintCreation : RuntimeAPICreation
+ {
+ public GameObject waitingPanel;
+ public GameObject blueprintPanel;
+ public GameObject errorPanel;
+
+ public Text titleText;
+ public InputField blueprintName;
+ public InputField blueprintDescription;
+ public RawImage bpImage;
+ public Image liveBpImage;
+ public Toggle shouldUpdateImageToggle;
+ public Toggle contentSex;
+ public Toggle contentViolence;
+ public Toggle contentGore;
+ public Toggle contentOther;
+ public Toggle developerAvatar;
+ public Toggle sharePrivate;
+ public Toggle sharePublic;
+ public Toggle tagFallback;
+
+ public UnityEngine.UI.Button uploadButton;
+
+ private ApiAvatar apiAvatar;
+
+ new void Start()
+ {
+ if (!Application.isEditor || !Application.isPlaying)
+ return;
+
+ base.Start();
+
+ var desc = pipelineManager.GetComponent<VRC.SDKBase.VRC_AvatarDescriptor>();
+ desc.PositionPortraitCamera(imageCapture.shotCamera.transform);
+
+ Application.runInBackground = true;
+ UnityEngine.XR.XRSettings.enabled = false;
+
+ uploadButton.onClick.AddListener(SetupUpload);
+
+ shouldUpdateImageToggle.onValueChanged.AddListener(ToggleUpdateImage);
+
+ Login();
+ }
+
+ void LoginErrorCallback(string obj)
+ {
+ VRC.Core.Logger.LogError("Could not log in - " + obj, DebugLevel.Always);
+ blueprintPanel.SetActive(false);
+ errorPanel.SetActive(true);
+ }
+
+ void Login()
+ {
+ if (!ApiCredentials.Load())
+ LoginErrorCallback("Not logged in");
+ else
+ APIUser.InitialFetchCurrentUser(
+ delegate (ApiModelContainer<APIUser> c)
+ {
+ pipelineManager.user = c.Model as APIUser;
+
+ ApiAvatar av = new ApiAvatar() { id = pipelineManager.blueprintId };
+ av.Get(false,
+ (c2) =>
+ {
+ VRC.Core.Logger.Log("<color=magenta>Updating an existing avatar.</color>", DebugLevel.API);
+ apiAvatar = c2.Model as ApiAvatar;
+ pipelineManager.completedSDKPipeline = !string.IsNullOrEmpty(apiAvatar.authorId);
+ SetupUI();
+ },
+ (c2) =>
+ {
+ VRC.Core.Logger.Log("<color=magenta>Creating a new avatar.</color>", DebugLevel.API);
+ apiAvatar = new ApiAvatar();
+ apiAvatar.id = pipelineManager.blueprintId;
+ pipelineManager.completedSDKPipeline = !string.IsNullOrEmpty(apiAvatar.authorId);
+ SetupUI();
+ });
+ }, (c) => {
+ LoginErrorCallback(c.Error);
+ });
+ }
+
+ void SetupUI()
+ {
+ if (!ValidateAssetBundleBlueprintID(apiAvatar.id))
+ {
+ blueprintPanel.SetActive(false);
+ errorPanel.SetActive(true);
+ OnSDKPipelineError("The asset bundle is out of date. Please rebuild the scene using 'New Build'.", "The blueprint ID in the scene does not match the id in the asset bundle.");
+ return;
+ }
+
+ if (APIUser.Exists(pipelineManager.user))
+ {
+ waitingPanel.SetActive(false);
+ blueprintPanel.SetActive(true);
+ errorPanel.SetActive(false);
+
+ if (isUpdate)
+ {
+ // bp update
+ if (apiAvatar.authorId == pipelineManager.user.id)
+ {
+ titleText.text = "Update Avatar";
+ // apiAvatar = pipelineManager.user.GetBlueprint(pipelineManager.blueprintId) as ApiAvatar;
+ blueprintName.text = apiAvatar.name;
+ contentSex.isOn = apiAvatar.tags.Contains("content_sex");
+ contentViolence.isOn = apiAvatar.tags.Contains("content_violence");
+ contentGore.isOn = apiAvatar.tags.Contains("content_gore");
+ contentOther.isOn = apiAvatar.tags.Contains("content_other");
+ developerAvatar.isOn = apiAvatar.tags.Contains("developer");
+ sharePrivate.isOn = apiAvatar.releaseStatus.Contains("private");
+ sharePublic.isOn = apiAvatar.releaseStatus.Contains("public");
+
+ tagFallback.isOn = apiAvatar.tags.Contains("author_quest_fallback");
+ tagFallback.transform.parent.gameObject.SetActive(true);
+
+ switch (pipelineManager.fallbackStatus)
+ {
+ case PipelineManager.FallbackStatus.Valid:
+#if UNITY_ANDROID
+ tagFallback.interactable = true;
+ tagFallback.GetComponentInChildren<Text>().text = "Use for Fallback";
+#else
+ tagFallback.interactable = false;
+ tagFallback.GetComponentInChildren<Text>().text = "Use for Fallback (change only with Android upload)";
+#endif
+ break;
+ case PipelineManager.FallbackStatus.InvalidPerformance:
+ case PipelineManager.FallbackStatus.InvalidRig:
+ tagFallback.isOn = false; // need to remove tag on this upload, the updated version is not up-to-spec
+ tagFallback.interactable = false;
+ tagFallback.GetComponentInChildren<Text>().text = "Use for Fallback (avatar not valid, tag will be cleared)";
+ break;
+ }
+
+ blueprintDescription.text = apiAvatar.description;
+ shouldUpdateImageToggle.interactable = true;
+ shouldUpdateImageToggle.isOn = false;
+ liveBpImage.enabled = false;
+ bpImage.enabled = true;
+
+ ImageDownloader.DownloadImage(apiAvatar.imageUrl, 0, (Texture2D obj) => bpImage.texture = obj, null);
+ }
+ else // user does not own apiAvatar id associated with descriptor
+ {
+ Debug.LogErrorFormat("{0} is not an owner of {1}", apiAvatar.authorId, pipelineManager.user.id);
+ blueprintPanel.SetActive(false);
+ errorPanel.SetActive(true);
+ }
+ }
+ else
+ {
+ titleText.text = "New Avatar";
+ shouldUpdateImageToggle.interactable = false;
+ shouldUpdateImageToggle.isOn = true;
+ liveBpImage.enabled = true;
+ bpImage.enabled = false;
+ tagFallback.isOn = false;
+
+ // Janky fix for an avatar's blueprint image not showing up the very first time you press publish in a project until you resize the window
+ // can remove if we fix the underlying issue or move publishing out of Play Mode
+ string firstTimeResize = $"{Application.identifier}-firstTimeResize";
+ if (!PlayerPrefs.HasKey(firstTimeResize))
+ {
+ GameViewMethods.ResizeGameView();
+ PlayerPrefs.SetInt(firstTimeResize, 1);
+ }
+
+ tagFallback.transform.parent.gameObject.SetActive(true);
+ switch (pipelineManager.fallbackStatus)
+ {
+ case PipelineManager.FallbackStatus.Valid:
+#if UNITY_ANDROID
+ tagFallback.interactable = true;
+ tagFallback.GetComponentInChildren<Text>().text = "Use for Fallback";
+#else
+ tagFallback.interactable = false;
+ tagFallback.GetComponentInChildren<Text>().text = "Use for Fallback (change only with Android upload)";
+#endif
+ break;
+ case PipelineManager.FallbackStatus.InvalidPerformance:
+ case PipelineManager.FallbackStatus.InvalidRig:
+ tagFallback.transform.parent.gameObject.SetActive(true);
+ tagFallback.interactable = false;
+ tagFallback.GetComponentInChildren<Text>().text = "Use for Fallback (avatar not valid, tag will be cleared)";
+ break;
+ }
+ }
+ }
+ else
+ {
+ waitingPanel.SetActive(true);
+ blueprintPanel.SetActive(false);
+ errorPanel.SetActive(false);
+ }
+
+ if (APIUser.CurrentUser != null && APIUser.CurrentUser.hasSuperPowers)
+ developerAvatar.gameObject.SetActive(true);
+ else
+ developerAvatar.gameObject.SetActive(false);
+ }
+
+ public void SetupUpload()
+ {
+ uploadTitle = "Preparing For Upload";
+ isUploading = true;
+
+ string abPath = UnityEditor.EditorPrefs.GetString("currentBuildingAssetBundlePath");
+
+ string unityPackagePath = UnityEditor.EditorPrefs.GetString("VRC_exportedUnityPackagePath");
+
+ UnityEditor.EditorPrefs.SetBool("VRCSDK2_scene_changed", true);
+ UnityEditor.EditorPrefs.SetBool("VRCSDK2_content_sex", contentSex.isOn);
+ UnityEditor.EditorPrefs.SetBool("VRCSDK2_content_violence", contentViolence.isOn);
+ UnityEditor.EditorPrefs.SetBool("VRCSDK2_content_gore", contentGore.isOn);
+ UnityEditor.EditorPrefs.SetBool("VRCSDK2_content_other", contentOther.isOn);
+
+ if (string.IsNullOrEmpty(apiAvatar.id))
+ {
+ pipelineManager.AssignId();
+ apiAvatar.id = pipelineManager.blueprintId;
+ }
+
+ string avatarId = apiAvatar.id;
+ int version = isUpdate ? apiAvatar.version + 1 : 1;
+ PrepareVRCPathForS3(abPath, avatarId, version, ApiAvatar.VERSION);
+
+ if (!string.IsNullOrEmpty(unityPackagePath) && System.IO.File.Exists(unityPackagePath))
+ {
+ VRC.Core.Logger.Log("Found unity package path. Preparing to upload!", DebugLevel.All);
+ PrepareUnityPackageForS3(unityPackagePath, avatarId, version, ApiAvatar.VERSION);
+ }
+
+ StartCoroutine(UploadNew());
+ }
+
+ IEnumerator UploadNew()
+ {
+ bool caughtInvalidInput = false;
+ if (!ValidateNameInput(blueprintName))
+ caughtInvalidInput = true;
+
+ if (caughtInvalidInput)
+ yield break;
+
+ VRC.Core.Logger.Log("Starting upload", DebugLevel.Always);
+
+ // upload unity package
+ if (!string.IsNullOrEmpty(uploadUnityPackagePath))
+ {
+ yield return StartCoroutine(UploadFile(uploadUnityPackagePath, isUpdate ? apiAvatar.unityPackageUrl : "", GetFriendlyAvatarFileName("Unity package"), "Unity package",
+ delegate (string fileUrl)
+ {
+ cloudFrontUnityPackageUrl = fileUrl;
+ }
+ ));
+ }
+
+ // upload asset bundle
+ if (!string.IsNullOrEmpty(uploadVrcPath))
+ {
+ yield return StartCoroutine(UploadFile(uploadVrcPath, isUpdate ? apiAvatar.assetUrl : "", GetFriendlyAvatarFileName("Asset bundle"), "Asset bundle",
+ delegate (string fileUrl)
+ {
+ cloudFrontAssetUrl = fileUrl;
+ }
+ ));
+ }
+
+ if (isUpdate)
+ yield return StartCoroutine(UpdateBlueprint());
+ else
+ yield return StartCoroutine(CreateBlueprint());
+
+ OnSDKPipelineComplete();
+ }
+
+ private string GetFriendlyAvatarFileName(string type)
+ {
+ return "Avatar - " + blueprintName.text + " - " + type + " - " + Application.unityVersion + "_" + ApiWorld.VERSION.ApiVersion +
+ "_" + VRC.Tools.Platform + "_" + API.GetServerEnvironmentForApiUrl();
+ }
+
+ List<string> BuildTags()
+ {
+ var tags = new List<string>();
+ if (contentSex.isOn)
+ tags.Add("content_sex");
+ if (contentViolence.isOn)
+ tags.Add("content_violence");
+ if (contentGore.isOn)
+ tags.Add("content_gore");
+ if (contentOther.isOn)
+ tags.Add("content_other");
+
+ if (APIUser.CurrentUser.hasSuperPowers)
+ {
+ if (developerAvatar.isOn)
+ tags.Add("developer");
+ }
+
+ if (tagFallback.isOn)
+ tags.Add("author_quest_fallback");
+
+ return tags;
+ }
+
+ protected override IEnumerator CreateBlueprint()
+ {
+ yield return StartCoroutine(UpdateImage(isUpdate ? apiAvatar.imageUrl : "", GetFriendlyAvatarFileName("Image")));
+
+ ApiAvatar avatar = new ApiAvatar
+ {
+ id = pipelineManager.blueprintId,
+ authorName = pipelineManager.user.displayName,
+ authorId = pipelineManager.user.id,
+ name = blueprintName.text,
+ imageUrl = cloudFrontImageUrl,
+ assetUrl = cloudFrontAssetUrl,
+ description = blueprintDescription.text,
+ tags = BuildTags(),
+ unityPackageUrl = cloudFrontUnityPackageUrl,
+ releaseStatus = sharePublic.isOn ? "public" : "private"
+ };
+
+ bool doneUploading = false;
+ bool wasError = false;
+
+ avatar.Post(
+ (c) =>
+ {
+ ApiAvatar savedBP = (ApiAvatar)c.Model;
+ pipelineManager.blueprintId = savedBP.id;
+ UnityEditor.EditorPrefs.SetString("blueprintID-" + pipelineManager.GetInstanceID().ToString(), savedBP.id);
+
+ AnalyticsSDK.AvatarUploaded(savedBP, false);
+ doneUploading = true;
+ },
+ (c) =>
+ {
+ Debug.LogError(c.Error);
+ SetUploadProgress("Saving Avatar", "Error saving blueprint.", 0.0f);
+ doneUploading = true;
+ wasError = true;
+ });
+
+ while (!doneUploading)
+ yield return null;
+
+ if (wasError)
+ yield return new WaitUntil(() => UnityEditor.EditorUtility.DisplayDialog("VRChat SDK", "Error saving blueprint.", "Okay"));
+ }
+
+ protected override IEnumerator UpdateBlueprint()
+ {
+ bool doneUploading = false;
+
+ apiAvatar.name = blueprintName.text;
+ apiAvatar.description = blueprintDescription.text;
+ apiAvatar.assetUrl = cloudFrontAssetUrl;
+ apiAvatar.releaseStatus = sharePublic.isOn ? "public" : "private";
+ apiAvatar.tags = BuildTags();
+ apiAvatar.unityPackageUrl = cloudFrontUnityPackageUrl;
+
+ if (shouldUpdateImageToggle.isOn)
+ {
+ yield return StartCoroutine(UpdateImage(isUpdate ? apiAvatar.imageUrl : "", GetFriendlyAvatarFileName("Image")));
+ apiAvatar.imageUrl = cloudFrontImageUrl;
+ }
+
+ SetUploadProgress("Saving Avatar", "Almost finished!!", 0.8f);
+ apiAvatar.Save(
+ (c) => { AnalyticsSDK.AvatarUploaded(apiAvatar, true); doneUploading = true; },
+ (c) => {
+ Debug.LogError(c.Error);
+ SetUploadProgress("Saving Avatar", "Error saving blueprint.", 0.0f);
+ doneUploading = true;
+ });
+
+ while (!doneUploading)
+ yield return null;
+ }
+
+ void ToggleUpdateImage(bool isOn)
+ {
+ if (isOn)
+ {
+ bpImage.enabled = false;
+ liveBpImage.enabled = true;
+ }
+ else
+ {
+ bpImage.enabled = true;
+ liveBpImage.enabled = false;
+ ImageDownloader.DownloadImage(apiAvatar.imageUrl, 0, obj => bpImage.texture = obj, null);
+ }
+ }
+
+ void OnDestroy()
+ {
+ UnityEditor.EditorUtility.ClearProgressBar();
+ UnityEditor.EditorPrefs.DeleteKey("currentBuildingAssetBundlePath");
+ }
+ }
+#endif
+}
+
+