diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 88db77b314..4e6ed35d2c 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3295,7 +3295,6 @@ void Application::initializeUi() { qmlRegisterType("Hifi", 1, 0, "ResourceImageItem"); qmlRegisterType("Hifi", 1, 0, "Preference"); qmlRegisterType("HifiWeb", 1, 0, "WebBrowserSuggestionsEngine"); - // qmlRegisterType("ExternalResource", 1, 0, "ExternalResource"); { auto tabletScriptingInterface = DependencyManager::get(); @@ -5574,6 +5573,9 @@ void Application::saveSettings() const { getMyAvatar()->saveData(); PluginManager::getInstance()->saveSettings(); + // Don't save external resource paths until such time as there's UI to select or set alternatives. Otherwise new default + // values won't be used unless Interface.json entries are manually remove or Interface.json is deleted. + /* auto bucketEnum = QMetaEnum::fromType(); auto externalResource = ExternalResource::getInstance(); @@ -5585,6 +5587,7 @@ void Application::saveSettings() const { Setting::Handle url(setting, externalResource->getBase(bucket)); url.set(externalResource->getBase(bucket)); } + */ } bool Application::importEntities(const QString& urlOrFilename, const bool isObservable, const qint64 callerId) { @@ -7565,10 +7568,6 @@ void Application::registerScriptEngineWithApplicationServices(const ScriptEngine scriptEngine->registerGlobalObject("HifiAbout", AboutUtil::getInstance()); // Deprecated. scriptEngine->registerGlobalObject("ResourceRequestObserver", DependencyManager::get().data()); - - //scriptEngine->registerGlobalObject("ExternalResource", ExternalResource::getInstance()); - // scriptEngine->registerEnum("Script.ExternalPaths", QMetaEnum::fromType()); - registerInteractiveWindowMetaType(scriptEngine.data()); auto pickScriptingInterface = DependencyManager::get(); diff --git a/interface/src/scripting/TestScriptingInterface.cpp b/interface/src/scripting/TestScriptingInterface.cpp index fc17d4c978..53630b3eed 100644 --- a/interface/src/scripting/TestScriptingInterface.cpp +++ b/interface/src/scripting/TestScriptingInterface.cpp @@ -68,7 +68,7 @@ bool TestScriptingInterface::loadTestScene(QString scene) { } static const QString TEST_ROOT = "https://raw.githubusercontent.com/hifi-archive/hifi_tests/master/"; - static const QString TEST_BINARY_ROOT = NetworkingConstants::HF_CONTENT_CDN_URL + "/test_scene_data/"; + static const QString TEST_BINARY_ROOT = NetworkingConstants::HF_CONTENT_CDN_URL + "test_scene_data/"; static const QString TEST_SCRIPTS_ROOT = TEST_ROOT + "scripts/"; static const QString TEST_SCENES_ROOT = TEST_ROOT + "scenes/"; diff --git a/libraries/networking/src/ExternalResource.cpp b/libraries/networking/src/ExternalResource.cpp index d3aef1171b..e2b6a40682 100644 --- a/libraries/networking/src/ExternalResource.cpp +++ b/libraries/networking/src/ExternalResource.cpp @@ -4,7 +4,7 @@ // Created by Dale Glass on 6 Sep 2020 // Copyright 2020 Vircadia contributors. // -// Flexible management for external resources (eg, on S3) +// Flexible management for external resources (e.g., on S3). // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html @@ -23,25 +23,24 @@ ExternalResource* ExternalResource::getInstance() { return &instance; } -QUrl ExternalResource::getQUrl(Bucket bucket, const QUrl& relative_path) { - qCDebug(external_resource) << "Requested URL for bucket " << bucket << ", path " << relative_path; +QUrl ExternalResource::getQUrl(Bucket bucket, const QUrl& path) { + qCDebug(external_resource) << "Requested URL for bucket " << bucket << ", path " << path; if (!_bucketBases.contains(bucket)) { - qCCritical(external_resource) << "External resource " << relative_path << " was requested from unrecognized bucket " - << bucket; + qCCritical(external_resource) << "External resource " << path << " was requested from unrecognized bucket " << bucket; return QUrl(); } - if (!relative_path.isValid()) { - qCCritical(external_resource) << "External resource " << relative_path << " was requested from bucket " << bucket - << " with an invalid path. Error: " << relative_path.errorString(); + if (!path.isValid()) { + qCCritical(external_resource) << "External resource " << path << " was requested from bucket " << bucket + << " with an invalid path. Error: " << path.errorString(); return QUrl(); } - if (!relative_path.isRelative()) { - qCWarning(external_resource) << "External resource " << relative_path << " was requested from bucket " << bucket + if (!path.isRelative()) { + qCWarning(external_resource) << "External resource " << path << " was requested from bucket " << bucket << " without using a relative path, returning as-is."; - return relative_path; + return path; } QUrl base; @@ -50,13 +49,13 @@ QUrl ExternalResource::getQUrl(Bucket bucket, const QUrl& relative_path) { base = _bucketBases[bucket]; } - QUrl merged = base.resolved(relative_path).adjusted(QUrl::NormalizePathSegments); + QUrl merged = base.resolved(path).adjusted(QUrl::NormalizePathSegments); if ( merged.isValid() ) { qCDebug(external_resource) << "External resource resolved to " << merged; } else { - qCCritical(external_resource) << "External resource resolved to invalid URL " << merged << "; Error " << merged.errorString() - << "; base = " << base << "; relative_path = " << relative_path; + qCCritical(external_resource) << "External resource resolved to invalid URL " << merged << "; Error " + << merged.errorString() << "; base = " << base << "; path = " << path; } return merged; @@ -68,9 +67,9 @@ QString ExternalResource::getBase(Bucket bucket) { }; bool ExternalResource::setBase(Bucket bucket, const QString& url) { - QUrl new_url(url); + QUrl newURL(url); - if (!new_url.isValid() || new_url.isRelative()) { + if (!newURL.isValid() || newURL.isRelative()) { qCCritical(external_resource) << "Attempted to set bucket " << bucket << " to invalid URL " << url; return false; } @@ -80,9 +79,9 @@ bool ExternalResource::setBase(Bucket bucket, const QString& url) { return false; } - qCDebug(external_resource) << "Setting base URL for " << bucket << " to " << new_url; + qCDebug(external_resource) << "Setting base URL for " << bucket << " to " << newURL; std::lock_guard guard(_bucketMutex); - _bucketBases[bucket] = new_url; + _bucketBases[bucket] = newURL; return true; } diff --git a/libraries/networking/src/ExternalResource.h b/libraries/networking/src/ExternalResource.h index c58e153c56..2c1e83da29 100644 --- a/libraries/networking/src/ExternalResource.h +++ b/libraries/networking/src/ExternalResource.h @@ -4,7 +4,7 @@ // Created by Dale Glass on 6 Sep 2020 // Copyright 2020 Vircadia contributors. // -// Flexible management for external resources (eg, on S3) +// Flexible management for external resources (e.g., on S3). // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html @@ -25,11 +25,11 @@ * * With the death of the original High Fidelity and the transition of the project to a community-managed * one, it became necessary to deal with that the various assets that used to be located under the - * highfidelity.com domain will disappear, and there won't be a fixed place for them afterwards. Data + * highfidelity.com domain, and there won't be a fixed place for them afterwards. Data * hosted by community members may not remain forever, reorganization may be necessary, people may want - * to run mirrors, and some might want to run without external internet access at all. + * to run mirrors, and some might want to run without external Internet access at all. * - * This class makes it possible to deal with this in a more flexible manner: rather than hardcoding URLs + * This class makes it possible to deal with this in a more flexible manner: rather than hard-coding URLs * all over the codebase, now it's possible to easily change where all those things are downloaded from. * * The term 'bucket' refers to the buckets used on Amazon S3, but there's no requirement for S3 or anything @@ -42,25 +42,42 @@ public: static ExternalResource* getInstance(); ~ExternalResource(){}; - /** - * Bucket from which to retrieve the resource - * - * The original High Fidelity used the Public, Content and MPAssets buckets. The intention is that the - * community-run versions of these will keep the original data and structure, and any new additions - * will be done to the Assets bucket instead. This should ease the transition and ensure a clean - * separation. + /**jsdoc + *

An external resource bucket.

+ *

The original High Fidelity used "Public", "Content", and "MPAssets" Amazon S3 buckets. The intention is that the + * community-run versions of these will keep the original data and structure, and any new additions will be made to + * Vircadia's "Assets" bucket. This should ease the transition from High Fidelity and ensure a clean separation.

+ * @typedef {object} Script.ResourceBuckets + * @property {Script.ResourceBucket} Assets - Vircadia assets. + * @property {Script.ResourceBucket} HF_Public - Assets that used to be in High Fidelity's hifi-public Amazon + * S3 bucket. + * @property {Script.ResourceBucket} HF_Content - Assets that used to be in High Fidelity's hifi-content Amazon + * S3 bucket. + * @property {Script.ResourceBucket} HF_Marketplace - Assets that used to be in the High Fidelity's mpassets + * Amazon S3 bucket. (High Fidelity marketplace.) + */ + /**jsdoc + *

An external resource bucket.

+ * + * + * + * + * + * + * + * + * + * + *
ValueNameDescription
0HF_PublicAssets that used to be in High Fidelity's hifi-public + * Amazon S3 bucket.
1HF_ContentAssets that used to be in High Fidelity's hifi-content + * Amazon S3 bucket.
2HF_MarketplaceAssets that used to be in the High Fidelity's + * mpassets Amazon S3 bucket. (High Fidelity marketplace.)
3AssetsVircadia assets.
+ * @typedef {number} Script.ResourceBucket */ enum class Bucket { - /** Assets that used to be in the hifi-public S3 bucket */ HF_Public, - - /** Assets that used to be in the hifi-content S3 bucket */ HF_Content, - - /** Assets that used to be in the mpassets S3 bucket (hifi marketplace) */ HF_Marketplace, - - /** Vircadia assets */ Assets }; Q_ENUM(Bucket) @@ -77,52 +94,10 @@ public: * @param relative_path The path of the resource within the bucket * @returns The resulting URL as a QUrl */ - QUrl getQUrl(Bucket bucket, const QUrl& relative_path); + QUrl getQUrl(Bucket bucket, const QUrl& path); - /** - * Returns the location of a resource as a QUrl - * - * Returns the location of the resource \p relative_path in bucket \p bucket - * - * @note The resulting path will be sanitized by condensing multiple instances of '/' to one. - * This is done for easier usage with Amazon S3 and compatible systems. - * - * @param bucket The bucket in which the resource is found - * @param relative_path The path of the resource within the bucket - * @returns The resulting URL as a QUrl - */ - QUrl getQUrl(Bucket bucket, QString path) { return getQUrl(bucket, QUrl(path)); } - - /** - * Returns the location of a resource as a QString - * - * Returns the location of the resource \p relative_path in bucket \p bucket - * - * @note The resulting path will be sanitized by condensing multiple instances of '/' to one. - * This is done for easier usage with Amazon S3 and compatible systems. - * - * @param bucket The bucket in which the resource is found - * @param relative_path The path of the resource within the bucket - * @returns The resulting URL as a QString - */ - QString getUrl(Bucket bucket, const QUrl& relative_path) { - return ExternalResource::getQUrl(bucket, relative_path).toString(); - }; - - /** - * Returns the location of a resource as a QString - * - * Returns the location of the resource \p relative_path in bucket \p bucket - * - * @note The resulting path will be sanitized by condensing multiple instances of '/' to one. - * This is done for easier usage with Amazon S3 and compatible systems. - * - * @param bucket The bucket in which the resource is found - * @param relative_path The path of the resource within the bucket - * @returns The resulting URL as a QString - */ - Q_INVOKABLE QString getUrl(Bucket bucket, const QString& relative_path) { - return ExternalResource::getQUrl(bucket, QUrl(relative_path)).toString(); + QString getUrl(Bucket bucket, const QString& path) { + return ExternalResource::getQUrl(bucket, QUrl(path)).toString(); }; /** diff --git a/libraries/networking/src/NetworkingConstants.h b/libraries/networking/src/NetworkingConstants.h index 533b5ccca4..0766965a44 100644 --- a/libraries/networking/src/NetworkingConstants.h +++ b/libraries/networking/src/NetworkingConstants.h @@ -45,11 +45,11 @@ namespace NetworkingConstants { const QUrl MASTER_BUILDS_XML_URL("https://highfidelity.com/dev-builds.xml"); // CDN URLs - const QString HF_CONTENT_CDN_URL = "https://cdn-1.vircadia.com/eu-c-1/vircadia-content"; - const QString HF_MPASSETS_CDN_URL = "https://cdn-1.vircadia.com/eu-c-1/vircadia-mpassets"; - const QString HF_PUBLIC_CDN_URL = "https://cdn-1.vircadia.com/eu-c-1/vircadia-public"; + const QString HF_CONTENT_CDN_URL = "https://cdn-1.vircadia.com/eu-c-1/vircadia-content/"; + const QString HF_MPASSETS_CDN_URL = "https://cdn-1.vircadia.com/eu-c-1/vircadia-mpassets/"; + const QString HF_PUBLIC_CDN_URL = "https://cdn-1.vircadia.com/eu-c-1/vircadia-public/"; const QString HF_MARKETPLACE_CDN_HOSTNAME = "mpassets.highfidelity.com"; - const QString VIRCADIA_CONTENT_CDN_URL = "https://cdn-1.vircadia.com/us-e-1"; + const QString VIRCADIA_CONTENT_CDN_URL = "https://cdn-1.vircadia.com/us-e-1/"; #if USE_STABLE_GLOBAL_SERVICES const QString ICE_SERVER_DEFAULT_HOSTNAME = "ice.vircadia.com"; diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index fe3bccd543..184d0bebd2 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -2883,6 +2883,6 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS } } -QString ScriptEngine::getExternalPath(ExternalResource::Bucket bucket, const QString& relativePath) { - return ExternalResource::getInstance()->getUrl(bucket, relativePath); +QString ScriptEngine::getExternalPath(ExternalResource::Bucket bucket, const QString& path) { + return ExternalResource::getInstance()->getUrl(bucket, path); } diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index abb232a0f5..8eeb72e658 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -121,6 +121,7 @@ public: *
  • "agent": An assignment client script.
  • * * Read-only. + * @property {Script.ResourceBuckets} ExternalPaths - External resource buckets. */ class ScriptEngine : public BaseScriptEngine, public EntitiesScriptEngineProvider { Q_OBJECT @@ -235,12 +236,12 @@ public: /**jsdoc * @function Script.registerEnum - * @param {string} enumName - Name. - * @param {object} newEnum - Enumeration to be added - * @warning This function must be called after a registerGlobalObject that creates the namespace this enum is located in, - * or the globalObject won't function. Eg, if you have a Foo object and a Foo.FooType enum, Foo must be registered first. + * @param {string} name - Name. + * @param {object} enum - Enum. * @deprecated This function is deprecated and will be removed. */ + // WARNING: This function must be called after a registerGlobalObject that creates the namespace this enum is located in, or\ + // the globalObject won't function. E.g., if you have a Foo object and a Foo.FooType enum, Foo must be registered first. /// registers a global enum Q_INVOKABLE void registerEnum(const QString& enumName, QMetaEnum newEnum); @@ -684,7 +685,23 @@ public: void setScriptEngines(QSharedPointer& scriptEngines) { _scriptEngines = scriptEngines; } - Q_INVOKABLE QString getExternalPath(ExternalResource::Bucket bucket, const QString& relativePath); + /**jsdoc + * Gets the URL for an asset in an external resource bucket. (The location where the bucket is hosted may change over time + * but this method will return the asset's current URL.) + * @function Script.getExternalPath + * @param {Script.ResourceBucket} bucket - The external resource bucket that the asset is in. + * @param {string} path - The path within the external resource bucket where the asset is located. + *

    Normally, this should start with a path or filename to be appended to the bucket URL. + * Alternatively, it can be a relative path starting with ./ or ../, to navigate within the + * resource bucket's URL. Or it can be an absolute path starting with /, in which case the bucket's path + * is discarded when calculating the asset's URL.

    + * @Returns {string} The URL of an external asset. + * @example Report the URL of a default particle. + * print(Script.getExternalPath(Script.ExternalPaths.Assets, "Bazaar/Assets/Textures/Defaults/Interface/default_particle.png")); + * @example Report the root directory where the Vircadia assets are located. + * print(Script.getExternalPath(Script.ExternalPaths.Assets, ".")); + */ + Q_INVOKABLE QString getExternalPath(ExternalResource::Bucket bucket, const QString& path); public slots: