681 lines
27 KiB
C#
681 lines
27 KiB
C#
#define COMMUNITY_LABS_SDK
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
using UnityEngine.SceneManagement;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Resources;
|
|
using VRC.Core;
|
|
using System;
|
|
using System.IO;
|
|
#if UNITY_EDITOR
|
|
using UnityEditor;
|
|
#endif
|
|
|
|
namespace VRCSDK2
|
|
{
|
|
#if UNITY_EDITOR
|
|
public class RuntimeWorldCreation : RuntimeAPICreation
|
|
{
|
|
public GameObject waitingPanel;
|
|
public GameObject blueprintPanel;
|
|
public GameObject errorPanel;
|
|
|
|
public Text titleText;
|
|
public InputField blueprintName;
|
|
public InputField blueprintDescription;
|
|
public InputField worldCapacity;
|
|
public RawImage bpImage;
|
|
public Image liveBpImage;
|
|
public Toggle shouldUpdateImageToggle;
|
|
public Toggle releasePublic;
|
|
public Toggle contentNsfw;
|
|
|
|
public Toggle contentSex;
|
|
public Toggle contentViolence;
|
|
public Toggle contentGore;
|
|
public Toggle contentOther;
|
|
|
|
public Toggle contentFeatured;
|
|
public Toggle contentSDKExample;
|
|
|
|
public Image showInWorldsMenuGroup;
|
|
public Toggle showInActiveWorlds;
|
|
public Toggle showInPopularWorlds;
|
|
public Toggle showInNewWorlds;
|
|
|
|
public InputField userTags;
|
|
|
|
public UnityEngine.UI.Button uploadButton;
|
|
|
|
public UnityEngine.UI.Button openCommunityLabsDocsButton;
|
|
|
|
public GameObject publishToCommunityLabsPanel;
|
|
|
|
private Toggle publishToCommLabsToggle;
|
|
|
|
private ApiWorld worldRecord;
|
|
|
|
private const int MAX_USER_TAGS_FOR_WORLD = 5;
|
|
private const int MAX_CHARACTERS_ALLOWED_IN_USER_TAG = 20;
|
|
List<String> customTags;
|
|
|
|
public static bool IsCurrentWorldInCommunityLabs = false;
|
|
public static bool IsCurrentWorldUploaded = false;
|
|
public static bool IsCurrentWorldPubliclyPublished = false;
|
|
public static bool HasExceededPublishLimit = false;
|
|
|
|
new void Start()
|
|
{
|
|
if (!Application.isEditor || !Application.isPlaying)
|
|
return;
|
|
|
|
base.Start();
|
|
|
|
IsCurrentWorldInCommunityLabs = false;
|
|
IsCurrentWorldUploaded = false;
|
|
IsCurrentWorldPubliclyPublished = false;
|
|
|
|
|
|
var desc = pipelineManager.GetComponent<VRC.SDKBase.VRC_SceneDescriptor>();
|
|
desc.PositionPortraitCamera(imageCapture.shotCamera.transform);
|
|
|
|
Application.runInBackground = true;
|
|
UnityEngine.XR.XRSettings.enabled = false;
|
|
|
|
uploadButton.onClick.AddListener(SetupUpload);
|
|
|
|
openCommunityLabsDocsButton.onClick.AddListener(OpenCommunityLabsDocumentation);
|
|
|
|
shouldUpdateImageToggle.onValueChanged.AddListener(ToggleUpdateImage);
|
|
|
|
releasePublic.gameObject.SetActive(false);
|
|
|
|
System.Action<string> onError = (err) => {
|
|
VRC.Core.Logger.LogError("Could not authenticate - " + err, DebugLevel.Always);
|
|
blueprintPanel.SetActive(false);
|
|
errorPanel.SetActive(true);
|
|
};
|
|
|
|
if (!ApiCredentials.Load())
|
|
onError("Not logged in");
|
|
else
|
|
APIUser.InitialFetchCurrentUser(
|
|
delegate (ApiModelContainer<APIUser> c)
|
|
{
|
|
UserLoggedInCallback(c.Model as APIUser);
|
|
},
|
|
delegate (ApiModelContainer<APIUser> c)
|
|
{
|
|
onError(c.Error);
|
|
}
|
|
);
|
|
|
|
#if !COMMUNITY_LABS_SDK
|
|
publishToCommunityLabsPanel.gameObject.SetActive(false);
|
|
#endif
|
|
}
|
|
|
|
void UserLoggedInCallback(APIUser user)
|
|
{
|
|
pipelineManager.user = user;
|
|
|
|
ApiWorld model = new ApiWorld();
|
|
model.id = pipelineManager.blueprintId;
|
|
model.Fetch(null,
|
|
(c) =>
|
|
{
|
|
VRC.Core.Logger.Log("<color=magenta>Updating an existing world.</color>", DebugLevel.All);
|
|
worldRecord = c.Model as ApiWorld;
|
|
pipelineManager.completedSDKPipeline = !string.IsNullOrEmpty(worldRecord.authorId);
|
|
GetUserUploadInformationAndSetupUI(model.id);
|
|
},
|
|
(c) =>
|
|
{
|
|
VRC.Core.Logger.Log("<color=magenta>World record not found, creating a new world.</color>", DebugLevel.All);
|
|
worldRecord = new ApiWorld { capacity = 16 };
|
|
pipelineManager.completedSDKPipeline = false;
|
|
worldRecord.id = pipelineManager.blueprintId;
|
|
GetUserUploadInformationAndSetupUI(model.id);
|
|
});
|
|
}
|
|
|
|
void CheckWorldStatus(string worldId, Action onCheckComplete)
|
|
{
|
|
// check if world has been previously uploaded, and if world is in community labs
|
|
ApiWorld.FetchUploadedWorlds(
|
|
delegate (IEnumerable<ApiWorld> worlds)
|
|
{
|
|
ApiWorld selectedWorld = worlds.FirstOrDefault(w => w.id == worldId);
|
|
if (null!=selectedWorld)
|
|
{
|
|
IsCurrentWorldInCommunityLabs = selectedWorld.IsCommunityLabsWorld;
|
|
IsCurrentWorldPubliclyPublished = selectedWorld.IsPublicPublishedWorld;
|
|
IsCurrentWorldUploaded = true;
|
|
}
|
|
if (onCheckComplete != null) onCheckComplete();
|
|
|
|
},
|
|
delegate (string err)
|
|
{
|
|
IsCurrentWorldInCommunityLabs = false;
|
|
IsCurrentWorldUploaded = false;
|
|
IsCurrentWorldPubliclyPublished = false;
|
|
Debug.Log("CheckWorldStatus error:" + err);
|
|
if (onCheckComplete != null) onCheckComplete();
|
|
}
|
|
);
|
|
}
|
|
|
|
|
|
void GetUserUploadInformationAndSetupUI(string worldId)
|
|
{
|
|
CheckWorldStatus(worldId, delegate()
|
|
{
|
|
bool hasSufficientTrustLevelToPublishToCommunityLabs = APIUser.CurrentUser.hasKnownTrustLevel;
|
|
APIUser.FetchPublishWorldsInformation(
|
|
(c) =>
|
|
{
|
|
try
|
|
{
|
|
if (c["canPublish"].Type == BestHTTP.JSON.Json.TokenType.Boolean)
|
|
{
|
|
HasExceededPublishLimit = !(bool)(c["canPublish"]);
|
|
}
|
|
else
|
|
HasExceededPublishLimit = true;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
HasExceededPublishLimit = true;
|
|
}
|
|
|
|
if(Application.isPlaying)
|
|
{
|
|
SetupUI(hasSufficientTrustLevelToPublishToCommunityLabs, HasExceededPublishLimit);
|
|
}
|
|
},
|
|
(c) =>
|
|
{
|
|
if(Application.isPlaying)
|
|
{
|
|
SetupUI(hasSufficientTrustLevelToPublishToCommunityLabs, HasExceededPublishLimit);
|
|
}
|
|
}
|
|
);
|
|
}
|
|
);
|
|
}
|
|
|
|
void SetupUI(bool hasEnoughTrustToPublishToCL = false, bool hasExceededWeeklyPublishLimit = false)
|
|
{
|
|
#if COMMUNITY_LABS_SDK
|
|
// do not display community labs panel if updating an existing CL world or updating a public world
|
|
publishToCommunityLabsPanel.gameObject.SetActive(!IsCurrentWorldUploaded);
|
|
#endif
|
|
|
|
if (!ValidateAssetBundleBlueprintID(worldRecord.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;
|
|
}
|
|
|
|
contentFeatured.gameObject.SetActive(APIUser.CurrentUser.hasSuperPowers);
|
|
contentSDKExample.gameObject.SetActive(APIUser.CurrentUser.hasSuperPowers);
|
|
|
|
if (APIUser.Exists(pipelineManager.user))
|
|
{
|
|
waitingPanel.SetActive(false);
|
|
blueprintPanel.SetActive(true);
|
|
errorPanel.SetActive(false);
|
|
|
|
if (string.IsNullOrEmpty(worldRecord.authorId) || worldRecord.authorId == pipelineManager.user.id)
|
|
{
|
|
titleText.text = "Configure World";
|
|
blueprintName.text = worldRecord.name;
|
|
worldCapacity.text = worldRecord.capacity.ToString();
|
|
contentSex.isOn = worldRecord.tags.Contains("content_sex");
|
|
contentViolence.isOn = worldRecord.tags.Contains("content_violence");
|
|
contentGore.isOn = worldRecord.tags.Contains("content_gore");
|
|
contentOther.isOn = worldRecord.tags.Contains("content_other");
|
|
shouldUpdateImageToggle.interactable = isUpdate;
|
|
shouldUpdateImageToggle.isOn = !isUpdate;
|
|
liveBpImage.enabled = !isUpdate;
|
|
bpImage.enabled = isUpdate;
|
|
|
|
if (!APIUser.CurrentUser.hasSuperPowers)
|
|
{
|
|
releasePublic.gameObject.SetActive(false);
|
|
releasePublic.isOn = false;
|
|
releasePublic.interactable = false;
|
|
|
|
contentFeatured.isOn = contentSDKExample.isOn = false;
|
|
}
|
|
else
|
|
{
|
|
contentFeatured.isOn = worldRecord.tags.Contains("content_featured");
|
|
contentSDKExample.isOn = worldRecord.tags.Contains("content_sdk_example");
|
|
|
|
releasePublic.isOn = worldRecord.releaseStatus == "public";
|
|
releasePublic.gameObject.SetActive(true);
|
|
}
|
|
|
|
// "show in worlds menu"
|
|
if (APIUser.CurrentUser.hasSuperPowers)
|
|
{
|
|
showInWorldsMenuGroup.gameObject.SetActive(true);
|
|
showInActiveWorlds.isOn = !worldRecord.tags.Contains("admin_hide_active");
|
|
showInPopularWorlds.isOn = !worldRecord.tags.Contains("admin_hide_popular");
|
|
showInNewWorlds.isOn = !worldRecord.tags.Contains("admin_hide_new");
|
|
}
|
|
else
|
|
{
|
|
showInWorldsMenuGroup.gameObject.SetActive(false);
|
|
}
|
|
|
|
blueprintDescription.text = worldRecord.description;
|
|
|
|
userTags.text = "";
|
|
foreach (var tag in worldRecord.publicTags)
|
|
{
|
|
userTags.text = userTags.text + tag.Replace("author_tag_", "");
|
|
userTags.text = userTags.text + " ";
|
|
}
|
|
|
|
ImageDownloader.DownloadImage(worldRecord.imageUrl, 0, obj => bpImage.texture = obj, null);
|
|
}
|
|
else // user does not own world id associated with descriptor
|
|
{
|
|
Debug.LogErrorFormat("{0} is not an owner of {1}", worldRecord.authorId, pipelineManager.user.id);
|
|
blueprintPanel.SetActive(false);
|
|
errorPanel.SetActive(true);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
waitingPanel.SetActive(true);
|
|
blueprintPanel.SetActive(false);
|
|
errorPanel.SetActive(false);
|
|
|
|
if (!APIUser.CurrentUser.hasSuperPowers)
|
|
{
|
|
releasePublic.gameObject.SetActive(false);
|
|
releasePublic.isOn = false;
|
|
releasePublic.interactable = false;
|
|
}
|
|
else
|
|
{
|
|
releasePublic.gameObject.SetActive(true);
|
|
releasePublic.isOn = false;
|
|
}
|
|
}
|
|
|
|
// set up publish to Community Labs checkbox and text
|
|
int worldsPublishedThisWeek = hasExceededWeeklyPublishLimit ? 1 : 0;
|
|
int maximumWorldsAllowedToPublishPerWeek = 1;
|
|
publishToCommLabsToggle = publishToCommunityLabsPanel.GetComponentInChildren<Toggle>();
|
|
|
|
if (null != publishToCommLabsToggle)
|
|
{
|
|
// disable publishing to CL checkbox if not enough trust or exceeded publish limit
|
|
publishToCommLabsToggle.interactable = hasEnoughTrustToPublishToCL && !hasExceededWeeklyPublishLimit;
|
|
|
|
Text publishText = publishToCommLabsToggle.gameObject.GetComponentInChildren<Text>();
|
|
if (null != publishText)
|
|
{
|
|
if (!hasEnoughTrustToPublishToCL)
|
|
{
|
|
publishText.text = "Not enough Trust to Publish to Community Labs";
|
|
}
|
|
else
|
|
{
|
|
if (hasExceededWeeklyPublishLimit)
|
|
{
|
|
publishText.text = "Publish limit for Community Labs Exceeded\n" + "(" + worldsPublishedThisWeek + "/" + maximumWorldsAllowedToPublishPerWeek + " Published this week)";
|
|
}
|
|
else
|
|
{
|
|
publishText.text = "Publish to Community Labs\n" + "(" + worldsPublishedThisWeek + "/" + maximumWorldsAllowedToPublishPerWeek + " Published this week)";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void SetupUpload()
|
|
{
|
|
if (!ParseUserTags())
|
|
return;
|
|
|
|
publishingToCommunityLabs = (publishToCommLabsToggle != null) && (publishToCommLabsToggle.isActiveAndEnabled) && (publishToCommLabsToggle.isOn);
|
|
|
|
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.SetInt("VRCSDK2_capacity", System.Convert.ToInt16(worldCapacity.text));
|
|
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);
|
|
UnityEditor.EditorPrefs.SetBool("VRCSDK2_release_public", releasePublic.isOn);
|
|
UnityEditor.EditorPrefs.SetBool("VRCSDK2_content_featured", contentFeatured.isOn);
|
|
UnityEditor.EditorPrefs.SetBool("VRCSDK2_content_sdk_example", contentSDKExample.isOn);
|
|
|
|
if (string.IsNullOrEmpty(worldRecord.id))
|
|
{
|
|
pipelineManager.AssignId();
|
|
worldRecord.id = pipelineManager.blueprintId;
|
|
}
|
|
|
|
string blueprintId = worldRecord.id;
|
|
int version = Mathf.Max(1, worldRecord.version + 1);
|
|
PrepareVRCPathForS3(abPath, blueprintId, version, ApiWorld.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, blueprintId, version, ApiWorld.VERSION);
|
|
}
|
|
|
|
StartCoroutine(UploadNew());
|
|
}
|
|
|
|
void OnUploadedWorld()
|
|
{
|
|
const string devUrl = "https://dev-api.vrchat.cloud";
|
|
const string releaseUrl = "https://vrchat.com";
|
|
|
|
string uploadedWorldURL = (API.IsDevApi() ? devUrl : releaseUrl) + "/home/world/" + pipelineManager.blueprintId;
|
|
OnSDKPipelineComplete(uploadedWorldURL);
|
|
}
|
|
|
|
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 ? worldRecord.unityPackageUrl : "", GetFriendlyWorldFileName("Unity package"), "Unity package",
|
|
delegate (string fileUrl)
|
|
{
|
|
cloudFrontUnityPackageUrl = fileUrl;
|
|
}
|
|
));
|
|
}
|
|
|
|
// upload asset bundle
|
|
if (!string.IsNullOrEmpty(uploadVrcPath))
|
|
{
|
|
yield return StartCoroutine(UploadFile(uploadVrcPath, isUpdate ? worldRecord.assetUrl : "", GetFriendlyWorldFileName("Asset bundle"), "Asset bundle",
|
|
delegate (string fileUrl)
|
|
{
|
|
cloudFrontAssetUrl = fileUrl;
|
|
}
|
|
));
|
|
}
|
|
|
|
if (isUpdate)
|
|
yield return StartCoroutine(UpdateBlueprint());
|
|
else
|
|
yield return StartCoroutine(CreateBlueprint());
|
|
|
|
if (publishingToCommunityLabs)
|
|
{
|
|
ApiWorld.PublishWorldToCommunityLabs(pipelineManager.blueprintId,
|
|
(world) => OnUploadedWorld(),
|
|
(err) =>
|
|
{
|
|
Debug.LogError("PublishWorldToCommunityLabs error:" + err);
|
|
OnUploadedWorld();
|
|
}
|
|
);
|
|
}
|
|
else
|
|
{
|
|
OnUploadedWorld();
|
|
}
|
|
}
|
|
|
|
private string GetFriendlyWorldFileName(string type)
|
|
{
|
|
return "World - " + 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 (contentFeatured.isOn)
|
|
tags.Add("content_featured");
|
|
if (contentSDKExample.isOn)
|
|
tags.Add("content_sdk_example");
|
|
if(releasePublic.isOn)
|
|
tags.Add("admin_approved");
|
|
}
|
|
|
|
// "show in worlds menu"
|
|
if (APIUser.CurrentUser.hasSuperPowers)
|
|
{
|
|
if (!showInActiveWorlds.isOn)
|
|
tags.Add("admin_hide_active");
|
|
if (!showInPopularWorlds.isOn)
|
|
tags.Add("admin_hide_popular");
|
|
if (!showInNewWorlds.isOn)
|
|
tags.Add("admin_hide_new");
|
|
}
|
|
|
|
// add any author tags
|
|
foreach (var word in customTags)
|
|
{
|
|
// add all custom tags with "author_tag_" prefix
|
|
tags.Add("author_tag_" + word);
|
|
}
|
|
|
|
return tags;
|
|
}
|
|
|
|
bool ParseUserTags()
|
|
{
|
|
bool validTags = true;
|
|
customTags = new List<string>();
|
|
char[] delimiterChars = { ' ', ',', '.', ':', '\t', '\n', '"', '#' };
|
|
|
|
// split user tags into individual words
|
|
string[] words = userTags.text.Split(delimiterChars, StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
foreach (var word in words)
|
|
{
|
|
customTags.Add(word.ToLower());
|
|
}
|
|
|
|
// check that number of tags is within tag limit
|
|
if (words.Count() > MAX_USER_TAGS_FOR_WORLD)
|
|
{
|
|
validTags = false;
|
|
UnityEditor.EditorUtility.DisplayDialog("Tags are limited to a maximum of " + MAX_USER_TAGS_FOR_WORLD + " per world.", "Please remove excess tags before uploading!", "OK");
|
|
}
|
|
else
|
|
{
|
|
// check that no tags exceed maximum tag length
|
|
int maximumTagLength = 0;
|
|
foreach (string item in words)
|
|
{
|
|
if (item.Length > maximumTagLength)
|
|
{
|
|
maximumTagLength = item.Length;
|
|
}
|
|
}
|
|
|
|
if (maximumTagLength > MAX_CHARACTERS_ALLOWED_IN_USER_TAG)
|
|
{
|
|
validTags = false;
|
|
UnityEditor.EditorUtility.DisplayDialog("Tags are limited to a maximum of " + MAX_CHARACTERS_ALLOWED_IN_USER_TAG + " characters per tag.", "One or more of your tags exceeds the maximum " + MAX_CHARACTERS_ALLOWED_IN_USER_TAG + " character limit.\n\n" + "Please shorten tags before uploading!", "OK");
|
|
}
|
|
else
|
|
{
|
|
// make sure tags are all alphanumeric
|
|
foreach (var word in words)
|
|
{
|
|
if (!word.All(char.IsLetterOrDigit))
|
|
{
|
|
validTags = false;
|
|
UnityEditor.EditorUtility.DisplayDialog("Tags should consist of alphanumeric characters only.", "Please remove any non-alphanumeric characters from tags before uploading!", "OK");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return validTags;
|
|
}
|
|
|
|
protected override IEnumerator CreateBlueprint()
|
|
{
|
|
yield return StartCoroutine(UpdateImage(isUpdate ? worldRecord.imageUrl : "", GetFriendlyWorldFileName("Image")));
|
|
|
|
SetUploadProgress("Saving Blueprint to user", "Almost finished!!", 0.0f);
|
|
ApiWorld world = new ApiWorld
|
|
{
|
|
id = worldRecord.id,
|
|
authorName = pipelineManager.user.displayName,
|
|
authorId = pipelineManager.user.id,
|
|
name = blueprintName.text,
|
|
imageUrl = cloudFrontImageUrl,
|
|
assetUrl = cloudFrontAssetUrl,
|
|
unityPackageUrl = cloudFrontUnityPackageUrl,
|
|
description = blueprintDescription.text,
|
|
tags = BuildTags(),
|
|
releaseStatus = (releasePublic.isOn) ? ("public") : ("private"),
|
|
capacity = System.Convert.ToInt16(worldCapacity.text),
|
|
occupants = 0,
|
|
shouldAddToAuthor = true
|
|
};
|
|
|
|
if (APIUser.CurrentUser.hasSuperPowers)
|
|
world.isCurated = contentFeatured.isOn || contentSDKExample.isOn;
|
|
else
|
|
world.isCurated = false;
|
|
|
|
bool doneUploading = false;
|
|
world.Post(
|
|
(c) =>
|
|
{
|
|
ApiWorld savedBP = (ApiWorld)c.Model;
|
|
pipelineManager.blueprintId = savedBP.id;
|
|
UnityEditor.EditorPrefs.SetString("blueprintID-" + pipelineManager.GetInstanceID().ToString(), savedBP.id);
|
|
VRC.Core.Logger.Log("Setting blueprintID on pipeline manager and editor prefs", DebugLevel.All);
|
|
doneUploading = true;
|
|
},
|
|
(c) => { doneUploading = true; Debug.LogError(c.Error); });
|
|
|
|
while (!doneUploading)
|
|
yield return null;
|
|
}
|
|
|
|
protected override IEnumerator UpdateBlueprint()
|
|
{
|
|
bool doneUploading = false;
|
|
|
|
worldRecord.name = blueprintName.text;
|
|
worldRecord.description = blueprintDescription.text;
|
|
worldRecord.capacity = System.Convert.ToInt16(worldCapacity.text);
|
|
worldRecord.assetUrl = cloudFrontAssetUrl;
|
|
worldRecord.tags = BuildTags();
|
|
worldRecord.releaseStatus = (releasePublic.isOn) ? ("public") : ("private");
|
|
worldRecord.unityPackageUrl = cloudFrontUnityPackageUrl;
|
|
worldRecord.isCurated = contentFeatured.isOn || contentSDKExample.isOn;
|
|
|
|
if (shouldUpdateImageToggle.isOn)
|
|
{
|
|
yield return StartCoroutine(UpdateImage(isUpdate ? worldRecord.imageUrl : "", GetFriendlyWorldFileName("Image")));
|
|
|
|
worldRecord.imageUrl = cloudFrontImageUrl;
|
|
}
|
|
|
|
SetUploadProgress("Saving Blueprint", "Almost finished!!", 0.0f);
|
|
worldRecord.Save((c) => doneUploading = true, (c) => { doneUploading = true; Debug.LogError(c.Error); });
|
|
|
|
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(worldRecord.imageUrl, 0, obj => bpImage.texture = obj, null);
|
|
}
|
|
}
|
|
|
|
protected override void DisplayUpdateCompletedDialog(string contentUrl = null)
|
|
{
|
|
#if UNITY_EDITOR
|
|
#if COMMUNITY_LABS_SDK
|
|
if (null != contentUrl)
|
|
{
|
|
CheckWorldStatus(pipelineManager.blueprintId, delegate ()
|
|
{
|
|
ContentUploadedDialog window = (ContentUploadedDialog)EditorWindow.GetWindow(typeof(ContentUploadedDialog), true, "VRCSDK", true);
|
|
window.setContentURL(contentUrl);
|
|
window.Show();
|
|
// refresh UI based on uploaded world
|
|
GetUserUploadInformationAndSetupUI(pipelineManager.blueprintId);
|
|
}
|
|
);
|
|
}
|
|
else
|
|
#endif
|
|
base.DisplayUpdateCompletedDialog(contentUrl);
|
|
#endif
|
|
}
|
|
|
|
private void OpenCommunityLabsDocumentation()
|
|
{
|
|
Application.OpenURL(CommunityLabsConstants.COMMUNITY_LABS_DOCUMENTATION_URL);
|
|
}
|
|
|
|
void OnDestroy()
|
|
{
|
|
UnityEditor.EditorUtility.ClearProgressBar();
|
|
UnityEditor.EditorPrefs.DeleteKey("currentBuildingAssetBundlePath");
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|