From b7e50c5b73a4235f00331195becf57f77048addb Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 3 Oct 2017 13:52:35 -0700 Subject: [PATCH 001/116] First steps --- .../resources/describe-settings.json | 140 +++++++++++++++--- .../qml/hifi/commerce/checkout/Checkout.qml | 4 +- libraries/entities/src/EntityTree.cpp | 56 ++++++- libraries/entities/src/EntityTree.h | 3 + 4 files changed, 179 insertions(+), 24 deletions(-) diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index 8d0e949ff3..f1180e00c2 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -1,5 +1,5 @@ { - "version": 1.8, + "version": 1.9, "settings": [ { "name": "metaverse", @@ -207,7 +207,7 @@ "name": "standard_permissions", "type": "table", "label": "Domain-Wide User Permissions", - "help": "Indicate which types of users can have which domain-wide permissions.", + "help": "Indicate which types of users can have which domain-wide permissions.", "caption": "Standard Permissions", "can_add_new_rows": false, "groups": [ @@ -216,7 +216,7 @@ "span": 1 }, { - "label": "Permissions ?", + "label": "Permissions ?", "span": 8 } ], @@ -253,6 +253,20 @@ "editable": true, "default": false }, + { + "name": "id_can_rez_certified", + "label": "Rez Certified", + "type": "checkbox", + "editable": true, + "default": false + }, + { + "name": "id_can_rez_tmp_certified", + "label": "Rez Temporary Certified", + "type": "checkbox", + "editable": true, + "default": false + }, { "name": "id_can_write_to_asset_server", "label": "Write Assets", @@ -283,7 +297,7 @@ } ], "non-deletable-row-key": "permissions_id", - "non-deletable-row-values": ["localhost", "anonymous", "logged-in"] + "non-deletable-row-values": [ "localhost", "anonymous", "logged-in" ] }, { "name": "group_permissions", @@ -300,7 +314,7 @@ "span": 1 }, { - "label": "Permissions ?", + "label": "Permissions ?", "span": 8 } ], @@ -362,6 +376,20 @@ "editable": true, "default": false }, + { + "name": "id_can_rez_certified", + "label": "Rez Certified", + "type": "checkbox", + "editable": true, + "default": false + }, + { + "name": "id_can_rez_tmp_certified", + "label": "Rez Temporary Certified", + "type": "checkbox", + "editable": true, + "default": false + }, { "name": "id_can_write_to_asset_server", "label": "Write Assets", @@ -383,7 +411,7 @@ "editable": true, "default": false }, - { + { "name": "id_can_replace_content", "label": "Replace Content", "type": "checkbox", @@ -407,7 +435,7 @@ "span": 1 }, { - "label": "Permissions ?", + "label": "Permissions ?", "span": 8 } ], @@ -466,6 +494,20 @@ "editable": true, "default": false }, + { + "name": "id_can_rez_certified", + "label": "Rez Certified", + "type": "checkbox", + "editable": true, + "default": false + }, + { + "name": "id_can_rez_tmp_certified", + "label": "Rez Temporary Certified", + "type": "checkbox", + "editable": true, + "default": false + }, { "name": "id_can_write_to_asset_server", "label": "Write Assets", @@ -487,7 +529,7 @@ "editable": true, "default": false }, - { + { "name": "id_can_replace_content", "label": "Replace Content", "type": "checkbox", @@ -507,7 +549,7 @@ "span": 1 }, { - "label": "Permissions ?", + "label": "Permissions ?", "span": 8 } ], @@ -544,6 +586,20 @@ "editable": true, "default": false }, + { + "name": "id_can_rez_certified", + "label": "Rez Certified", + "type": "checkbox", + "editable": true, + "default": false + }, + { + "name": "id_can_rez_tmp_certified", + "label": "Rez Temporary Certified", + "type": "checkbox", + "editable": true, + "default": false + }, { "name": "id_can_write_to_asset_server", "label": "Write Assets", @@ -565,7 +621,7 @@ "editable": true, "default": false }, - { + { "name": "id_can_replace_content", "label": "Replace Content", "type": "checkbox", @@ -585,7 +641,7 @@ "span": 1 }, { - "label": "Permissions ?", + "label": "Permissions ?", "span": 8 } ], @@ -622,6 +678,20 @@ "editable": true, "default": false }, + { + "name": "id_can_rez_certified", + "label": "Rez Certified", + "type": "checkbox", + "editable": true, + "default": false + }, + { + "name": "id_can_rez_tmp_certified", + "label": "Rez Temporary Certified", + "type": "checkbox", + "editable": true, + "default": false + }, { "name": "id_can_write_to_asset_server", "label": "Write Assets", @@ -643,7 +713,7 @@ "editable": true, "default": false }, - { + { "name": "id_can_replace_content", "label": "Replace Content", "type": "checkbox", @@ -663,7 +733,7 @@ "span": 1 }, { - "label": "Permissions ?", + "label": "Permissions ?", "span": 8 } ], @@ -700,6 +770,20 @@ "editable": true, "default": false }, + { + "name": "id_can_rez_certified", + "label": "Rez Certified", + "type": "checkbox", + "editable": true, + "default": false + }, + { + "name": "id_can_rez_tmp_certified", + "label": "Rez Temporary Certified", + "type": "checkbox", + "editable": true, + "default": false + }, { "name": "id_can_write_to_asset_server", "label": "Write Assets", @@ -721,7 +805,7 @@ "editable": true, "default": false }, - { + { "name": "id_can_replace_content", "label": "Replace Content", "type": "checkbox", @@ -741,7 +825,7 @@ "span": 1 }, { - "label": "Permissions ?", + "label": "Permissions ?", "span": 8 } ], @@ -778,6 +862,20 @@ "editable": true, "default": false }, + { + "name": "id_can_rez_certified", + "label": "Rez Certified", + "type": "checkbox", + "editable": true, + "default": false + }, + { + "name": "id_can_rez_tmp_certified", + "label": "Rez Temporary Certified", + "type": "checkbox", + "editable": true, + "default": false + }, { "name": "id_can_write_to_asset_server", "label": "Write Assets", @@ -799,7 +897,7 @@ "editable": true, "default": false }, - { + { "name": "id_can_replace_content", "label": "Replace Content", "type": "checkbox", @@ -841,7 +939,7 @@ { "name": "asset_server", "label": "Asset Server (ATP)", - "assignment-types": [3], + "assignment-types": [ 3 ], "settings": [ { "name": "enabled", @@ -864,7 +962,7 @@ { "name": "entity_script_server", "label": "Entity Script Server (ESS)", - "assignment-types": [5], + "assignment-types": [ 5 ], "settings": [ { "name": "entity_pps_per_script", @@ -887,7 +985,7 @@ { "name": "avatars", "label": "Avatars", - "assignment-types": [1, 2], + "assignment-types": [ 1, 2 ], "settings": [ { "name": "min_avatar_scale", @@ -926,7 +1024,7 @@ { "name": "audio_threading", "label": "Audio Threading", - "assignment-types": [0], + "assignment-types": [ 0 ], "settings": [ { "name": "auto_threads", @@ -949,7 +1047,7 @@ { "name": "audio_env", "label": "Audio Environment", - "assignment-types": [0], + "assignment-types": [ 0 ], "settings": [ { "name": "attenuation_per_doubling_in_distance", diff --git a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml index 77180f7bab..32f324aea9 100644 --- a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml +++ b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml @@ -35,7 +35,7 @@ Rectangle { property string itemHref; property double balanceAfterPurchase; property bool alreadyOwned: false; - property int itemPrice; + property int itemPrice: -1; property bool itemIsJson: true; property bool shouldBuyWithControlledFailure: false; property bool debugCheckoutSuccess: false; @@ -339,7 +339,7 @@ Rectangle { } FiraSansSemiBold { id: itemPriceText; - text: root.itemPrice; + text: (root.itemPrice === -1) ? "--" : root.itemPrice; // Text size size: 26; // Anchors diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index bf37a08386..b01c9b2d26 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -359,6 +359,18 @@ bool EntityTree::updateEntity(EntityItemPointer entity, const EntityItemProperti qCDebug(entities) << (senderNode ? senderNode->getUUID() : "null") << "physical edits suppressed"; } } + + // Clear Certificate ID if any static certificate property is changed + if (properties.itemNameChanged() || properties.itemDescriptionChanged() || properties.itemCategoriesChanged() || + properties.itemArtistChanged() || properties.itemLicenseChanged() || properties.limitedRunChanged() || + properties.editionNumberChanged() || properties.entityInstanceNumberChanged() || properties.certificateIDChanged()) { + qCDebug(entities) << "A static certificate property on Entity" << entity->getID() << "has changed." + << "Clearing Certificate ID."; + QWriteLocker locker(&_entityCertificateIDMapLock); + _entityCertificateIDMap.remove(entity->getCertificateID()); + properties.setCertificateID(""); + properties.setCertificateIDChanged(true); + } } // else client accepts what the server says @@ -653,6 +665,9 @@ void EntityTree::processRemovedEntities(const DeleteEntityOperator& theOperator) if (_simulation) { _simulation->prepareEntityForDelete(theEntity); } + + QWriteLocker locker(&_entityCertificateIDMapLock); + _entityCertificateIDMap.remove(theEntity->getProperties(PROP_CERTIFICATE_ID).getCertificateID()); } } @@ -1257,13 +1272,17 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c _totalUpdates++; } else if (isAdd) { bool failedAdd = !allowed; + bool isCertified = !properties.getCertificateID().isEmpty(); if (!allowed) { qCDebug(entities) << "Filtered entity add. ID:" << entityItemID; } else if (!senderNode->getCanRez() && !senderNode->getCanRezTmp()) { failedAdd = true; qCDebug(entities) << "User without 'rez rights' [" << senderNode->getUUID() << "] attempted to add an entity ID:" << entityItemID; - + } else if (isCertified && !senderNode->getCanRezCertified() && !senderNode->getCanRezTmpCertified()) { + failedAdd = true; + qCDebug(entities) << "User without 'certified rez rights' [" << senderNode->getUUID() + << "] attempted to add a certified entity with ID:" << entityItemID; } else { // this is a new entity... assign a new entityID properties.setCreated(properties.getLastEdited()); @@ -1272,6 +1291,41 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c EntityItemPointer newEntity = addEntity(entityItemID, properties); endCreate = usecTimestampNow(); _totalCreates++; + + if (newEntity && isCertified) { + if (!newEntity->verifyStaticCertificateProperties()) { + qCDebug(entities) << "User" << senderNode->getUUID() + << "attempted to add a certified entity with ID" << entityItemID << "which failed" + << "static certificate verification."; + // Delete the entity we just added if it doesn't pass static certificate verification + deleteEntity(entityItemID, true); + } else { + QString certID = properties.getCertificateID(); + EntityItemID existingEntityItemID; + + { + QReadLocker locker(&_entityCertificateIDMapLock); + existingEntityItemID = _entityCertificateIDMap.value(certID); + } + + // Delete an already-existing entity from the tree if it has the same + // CertificateID as the entity we're trying to add. + if (!existingEntityItemID.isNull()) { + qCDebug(entities) << "Certificate ID" << certID << "already exists on entity with ID" + << existingEntityItemID << ". Deleting existing entity."; + deleteEntity(existingEntityItemID, true); + } + + { + QWriteLocker locker(&_entityCertificateIDMapLock); + _entityCertificateIDMap.insert(certID, entityItemID); + qCDebug(entities) << "Certificate ID" << certID << "belongs to" << entityItemID; + } + + // Start owner verification + } + } + if (newEntity) { newEntity->markAsChangedOnServer(); notifyNewlyCreatedEntity(*newEntity, senderNode); diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index d0448f438a..4168dc3b66 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -316,6 +316,9 @@ protected: mutable QReadWriteLock _entityMapLock; QHash _entityMap; + mutable QReadWriteLock _entityCertificateIDMapLock; + QHash _entityCertificateIDMap; + EntitySimulationPointer _simulation; bool _wantEditLogging = false; From ed40e41b94a5bf1f0a4379ae9e4c99b8a82a8d8b Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 3 Oct 2017 16:18:29 -0700 Subject: [PATCH 002/116] Potential progress? Not totally sure --- libraries/entities/src/EntityTree.cpp | 40 ++++++++++++++++++++++++++- libraries/entities/src/EntityTree.h | 9 ++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index b01c9b2d26..0f5059d688 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1097,6 +1097,29 @@ bool EntityTree::isScriptInWhitelist(const QString& scriptProperty) { return false; } +void EntityTree::popStatusSuccess(QNetworkReply& reply) { + QJsonObject jsonObject = QJsonDocument::fromJson(reply.readAll()).object(); + qCDebug(entities) << "ZRF FIXME" << jsonObject; + //if (!jsonObject["invalid_reason"].toString().isEmpty()) { + // qCDebug(entities) << "invalid_reason not empty, deleting entity" << entityItemID; + // deleteEntity(entityItemID, true); + //} else if (jsonObject["transfer_status"].toString() == "failed") { + // qCDebug(entities) << "'transfer_status' is 'failed', deleting entity" << entityItemID; + // deleteEntity(entityItemID, true); + //} else { + // //auto challengeOwnershipPacket = NLPacket::create(PacketType::ChallengeOwnership, NUM_BYTES_RFC4122_UUID + sizeof(encryptedText)); + // //challengeOwnershipPacket->write(senderNode->getUUID()); + // //challengeOwnershipPacket->writePrimitive(KillAvatarReason::TheirAvatarEnteredYourBubble); + //} +} + +void EntityTree::popStatusFailure(QNetworkReply& reply) { + QJsonObject jsonObject = QJsonDocument::fromJson(reply.readAll()).object(); + qCDebug(entities) << "ZRF FIXME" << jsonObject; + //qCDebug(entities) << "Call to proof_of_purchase_status endpoint failed; deleting entity" << entityItemID; + //deleteEntity(entityItemID, true); +} + int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned char* editData, int maxLength, const SharedNodePointer& senderNode) { @@ -1322,7 +1345,22 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c qCDebug(entities) << "Certificate ID" << certID << "belongs to" << entityItemID; } - // Start owner verification + // Start owner verification. + // First, asynchronously hit "proof_of_purchase_status?transaction_type=transfer" endpoint. + const QString endpoint("proof_of_purchase_status?transaction_type=transfer"); + QJsonObject request; + request["certificate_id"] = certID; + request["domain_id"] = DependencyManager::get()->getDomainHandler().getUUID().toString(); + + auto accountManager = DependencyManager::get(); + const QString URL = "/api/v1/commerce/"; + JSONCallbackParameters callbackParams(this, "popStatusSuccess", this, "popStatusFailure"); + qCDebug(entities) << "Sending" << endpoint << QJsonDocument(request).toJson(QJsonDocument::Compact); + accountManager->sendRequest(URL + endpoint, + AccountManagerAuth::None, + QNetworkAccessManager::PostOperation, + callbackParams, + QJsonDocument(request).toJson()); } } diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 4168dc3b66..8c26cd0791 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -15,6 +15,11 @@ #include #include +#include "AccountManager.h" +#include +#include +#include + #include #include @@ -277,6 +282,10 @@ signals: void newCollisionSoundURL(const QUrl& url, const EntityItemID& entityID); void clearingEntities(); +private slots: + void popStatusSuccess(QNetworkReply& reply); + void popStatusFailure(QNetworkReply& reply); + protected: void processRemovedEntities(const DeleteEntityOperator& theOperator); From 2cdd5c29f315d9269ed8150b13499bb7fcec5aaf Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 4 Oct 2017 09:58:29 -0700 Subject: [PATCH 003/116] Uncertified rez rights --- libraries/entities/src/EntityTree.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 0f5059d688..e067637db8 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1298,10 +1298,10 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c bool isCertified = !properties.getCertificateID().isEmpty(); if (!allowed) { qCDebug(entities) << "Filtered entity add. ID:" << entityItemID; - } else if (!senderNode->getCanRez() && !senderNode->getCanRezTmp()) { + } else if (!isCertified && !senderNode->getCanRez() && !senderNode->getCanRezTmp()) { failedAdd = true; - qCDebug(entities) << "User without 'rez rights' [" << senderNode->getUUID() - << "] attempted to add an entity ID:" << entityItemID; + qCDebug(entities) << "User without 'uncertified rez rights' [" << senderNode->getUUID() + << "] attempted to add an uncertified entity with ID:" << entityItemID; } else if (isCertified && !senderNode->getCanRezCertified() && !senderNode->getCanRezTmpCertified()) { failedAdd = true; qCDebug(entities) << "User without 'certified rez rights' [" << senderNode->getUUID() From 23245e2fb9c82cb6f5a58636609318a6170a4ee8 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 4 Oct 2017 10:39:23 -0700 Subject: [PATCH 004/116] Modify context overlay filter --- interface/src/ui/overlays/ContextOverlayInterface.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/interface/src/ui/overlays/ContextOverlayInterface.cpp b/interface/src/ui/overlays/ContextOverlayInterface.cpp index 39fd4f9377..8cbb214857 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.cpp +++ b/interface/src/ui/overlays/ContextOverlayInterface.cpp @@ -41,6 +41,7 @@ ContextOverlayInterface::ContextOverlayInterface() { _entityPropertyFlags += PROP_MARKETPLACE_ID; _entityPropertyFlags += PROP_DIMENSIONS; _entityPropertyFlags += PROP_REGISTRATION_POINT; + _entityPropertyFlags += PROP_CERTIFICATE_ID; auto entityTreeRenderer = DependencyManager::get().data(); connect(entityTreeRenderer, SIGNAL(mousePressOnEntity(const EntityItemID&, const PointerEvent&)), this, SLOT(createOrDestroyContextOverlay(const EntityItemID&, const PointerEvent&))); @@ -176,7 +177,12 @@ bool ContextOverlayInterface::createOrDestroyContextOverlay(const EntityItemID& bool ContextOverlayInterface::contextOverlayFilterPassed(const EntityItemID& entityItemID) { EntityItemProperties entityProperties = _entityScriptingInterface->getEntityProperties(entityItemID, _entityPropertyFlags); - return (entityProperties.getMarketplaceID().length() != 0); + Setting::Handle _settingSwitch{ "commerce", false }; + if (_settingSwitch.get()) { + return (entityProperties.getCertificateID().length() != 0); + } else { + return (entityProperties.getMarketplaceID().length() != 0); + } } bool ContextOverlayInterface::destroyContextOverlay(const EntityItemID& entityItemID, const PointerEvent& event) { From ab08dc6bd6abee1ba54c2bcc0ee3b15af42e3d16 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 4 Oct 2017 12:33:58 -0700 Subject: [PATCH 005/116] Progress? --- .../resources/qml/hifi/commerce/checkout/Checkout.qml | 1 + .../qml/hifi/commerce/purchases/PurchasedItem.qml | 1 + interface/src/commerce/Ledger.cpp | 4 ++-- interface/src/commerce/QmlCommerce.cpp | 6 ++++++ interface/src/commerce/QmlCommerce.h | 2 ++ libraries/entities/src/EntityTree.cpp | 11 +++++++---- libraries/entities/src/EntityTree.h | 1 - 7 files changed, 19 insertions(+), 7 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml index 32f324aea9..80c9a3ec0f 100644 --- a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml +++ b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml @@ -579,6 +579,7 @@ Rectangle { } rezzedNotifContainer.visible = true; rezzedNotifContainerTimer.start(); + commerce.updatePopLocation(root.itemId); } } RalewaySemiBold { diff --git a/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml b/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml index a026a818c0..361a89d047 100644 --- a/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml +++ b/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml @@ -343,6 +343,7 @@ Item { if (urlHandler.canHandleUrl(root.itemHref)) { urlHandler.handleUrl(root.itemHref); } + commerce.updatePopLocation(root.itemId); rezzedNotifContainer.visible = true; rezzedNotifContainerTimer.start(); } diff --git a/interface/src/commerce/Ledger.cpp b/interface/src/commerce/Ledger.cpp index a68a6fe929..e926d8918e 100644 --- a/interface/src/commerce/Ledger.cpp +++ b/interface/src/commerce/Ledger.cpp @@ -221,8 +221,8 @@ void Ledger::account() { } // The api/failResponse is called just for the side effect of logging. -void Ledger::updateLocationSuccess(QNetworkReply& reply) { apiResponse("reset", reply); } -void Ledger::updateLocationFailure(QNetworkReply& reply) { failResponse("reset", reply); } +void Ledger::updateLocationSuccess(QNetworkReply& reply) { apiResponse("updateLocation", reply); } +void Ledger::updateLocationFailure(QNetworkReply& reply) { failResponse("updateLocation", reply); } void Ledger::updateLocation(const QString& asset_id, const QString location, const bool controlledFailure) { auto wallet = DependencyManager::get(); QStringList keys = wallet->listPublicKeys(); diff --git a/interface/src/commerce/QmlCommerce.cpp b/interface/src/commerce/QmlCommerce.cpp index dbd84594bc..8c22542d94 100644 --- a/interface/src/commerce/QmlCommerce.cpp +++ b/interface/src/commerce/QmlCommerce.cpp @@ -149,3 +149,9 @@ void QmlCommerce::account() { auto ledger = DependencyManager::get(); ledger->account(); } + +void QmlCommerce::updatePopLocation(const QString& popId, const bool controlledFailure) { + auto ledger = DependencyManager::get(); + auto nodeList = DependencyManager::get(); + ledger->updateLocation(popId, nodeList->getDomainHandler().getUUID().toString(), controlledFailure); +} diff --git a/interface/src/commerce/QmlCommerce.h b/interface/src/commerce/QmlCommerce.h index 8e6af6da65..b1d179aae8 100644 --- a/interface/src/commerce/QmlCommerce.h +++ b/interface/src/commerce/QmlCommerce.h @@ -70,6 +70,8 @@ protected: Q_INVOKABLE void generateKeyPair(); Q_INVOKABLE void reset(); Q_INVOKABLE void account(); + + Q_INVOKABLE void updatePopLocation(const QString& popId, const bool controlledFailure = false); }; #endif // hifi_QmlCommerce_h diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index e067637db8..112066a2f8 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1107,9 +1107,6 @@ void EntityTree::popStatusSuccess(QNetworkReply& reply) { // qCDebug(entities) << "'transfer_status' is 'failed', deleting entity" << entityItemID; // deleteEntity(entityItemID, true); //} else { - // //auto challengeOwnershipPacket = NLPacket::create(PacketType::ChallengeOwnership, NUM_BYTES_RFC4122_UUID + sizeof(encryptedText)); - // //challengeOwnershipPacket->write(senderNode->getUUID()); - // //challengeOwnershipPacket->writePrimitive(KillAvatarReason::TheirAvatarEnteredYourBubble); //} } @@ -1358,9 +1355,15 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c qCDebug(entities) << "Sending" << endpoint << QJsonDocument(request).toJson(QJsonDocument::Compact); accountManager->sendRequest(URL + endpoint, AccountManagerAuth::None, - QNetworkAccessManager::PostOperation, + QNetworkAccessManager::GetOperation, callbackParams, QJsonDocument(request).toJson()); + + // Second, challenge ownership of the PoP cert + //auto challengeOwnershipPacket = NLPacket::create(PacketType::ChallengeOwnership, NUM_BYTES_RFC4122_UUID + sizeof(encryptedText)); + //challengeOwnershipPacket->write(senderNode->getUUID()); + //challengeOwnershipPacket->writePrimitive(KillAvatarReason::TheirAvatarEnteredYourBubble); + //// Kickoff a 10-second timeout timer that deletes the entity if we don't get an ownership response in time } } diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 8c26cd0791..3ea48c113a 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -18,7 +18,6 @@ #include "AccountManager.h" #include #include -#include #include #include From cf7c1934f875d682473c0e5de7b17b1a4da2d28e Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 4 Oct 2017 13:12:21 -0700 Subject: [PATCH 006/116] Progress? --- libraries/entities/src/EntityTree.cpp | 75 ++++++++++++++------------- libraries/entities/src/EntityTree.h | 5 +- 2 files changed, 41 insertions(+), 39 deletions(-) diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 112066a2f8..a31c5a139e 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1097,26 +1097,6 @@ bool EntityTree::isScriptInWhitelist(const QString& scriptProperty) { return false; } -void EntityTree::popStatusSuccess(QNetworkReply& reply) { - QJsonObject jsonObject = QJsonDocument::fromJson(reply.readAll()).object(); - qCDebug(entities) << "ZRF FIXME" << jsonObject; - //if (!jsonObject["invalid_reason"].toString().isEmpty()) { - // qCDebug(entities) << "invalid_reason not empty, deleting entity" << entityItemID; - // deleteEntity(entityItemID, true); - //} else if (jsonObject["transfer_status"].toString() == "failed") { - // qCDebug(entities) << "'transfer_status' is 'failed', deleting entity" << entityItemID; - // deleteEntity(entityItemID, true); - //} else { - //} -} - -void EntityTree::popStatusFailure(QNetworkReply& reply) { - QJsonObject jsonObject = QJsonDocument::fromJson(reply.readAll()).object(); - qCDebug(entities) << "ZRF FIXME" << jsonObject; - //qCDebug(entities) << "Call to proof_of_purchase_status endpoint failed; deleting entity" << entityItemID; - //deleteEntity(entityItemID, true); -} - int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned char* editData, int maxLength, const SharedNodePointer& senderNode) { @@ -1344,26 +1324,51 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c // Start owner verification. // First, asynchronously hit "proof_of_purchase_status?transaction_type=transfer" endpoint. - const QString endpoint("proof_of_purchase_status?transaction_type=transfer"); + QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); + QNetworkRequest networkRequest; + networkRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); + QUrl requestURL = NetworkingConstants::METAVERSE_SERVER_URL; + requestURL.setPath("/api/v1/commerce/proof_of_purchase_status?transaction_type=transfer"); QJsonObject request; request["certificate_id"] = certID; request["domain_id"] = DependencyManager::get()->getDomainHandler().getUUID().toString(); + networkRequest.setUrl(requestURL); - auto accountManager = DependencyManager::get(); - const QString URL = "/api/v1/commerce/"; - JSONCallbackParameters callbackParams(this, "popStatusSuccess", this, "popStatusFailure"); - qCDebug(entities) << "Sending" << endpoint << QJsonDocument(request).toJson(QJsonDocument::Compact); - accountManager->sendRequest(URL + endpoint, - AccountManagerAuth::None, - QNetworkAccessManager::GetOperation, - callbackParams, - QJsonDocument(request).toJson()); + QNetworkReply* networkReply = NULL; + networkReply = networkAccessManager.get(networkRequest); - // Second, challenge ownership of the PoP cert - //auto challengeOwnershipPacket = NLPacket::create(PacketType::ChallengeOwnership, NUM_BYTES_RFC4122_UUID + sizeof(encryptedText)); - //challengeOwnershipPacket->write(senderNode->getUUID()); - //challengeOwnershipPacket->writePrimitive(KillAvatarReason::TheirAvatarEnteredYourBubble); - //// Kickoff a 10-second timeout timer that deletes the entity if we don't get an ownership response in time + connect(networkReply, &QNetworkReply::finished, [=]() { + QJsonObject jsonObject = QJsonDocument::fromJson(networkReply->readAll()).object(); + QJsonDocument doc(jsonObject); + qCDebug(entities) << "ZRF FIXME" << networkReply->error(); + qCDebug(entities) << "ZRF FIXME" << doc.toJson(QJsonDocument::Compact); + + if (networkReply->error() == QNetworkReply::NoError) { + //QJsonObject jsonObject = QJsonDocument::fromJson(reply.readAll()).object(); + //qCDebug(entities) << "ZRF FIXME" << jsonObject; + //if (!jsonObject["invalid_reason"].toString().isEmpty()) { + // qCDebug(entities) << "invalid_reason not empty, deleting entity" << entityItemID; + // deleteEntity(entityItemID, true); + //} else if (jsonObject["transfer_status"].toString() == "failed") { + // qCDebug(entities) << "'transfer_status' is 'failed', deleting entity" << entityItemID; + // deleteEntity(entityItemID, true); + //} else { + // // Second, challenge ownership of the PoP cert + // // 1. Encrypt a nonce with the owner's public key + // QString ownerKey(jsonObject["owner_public_key"].toString()); + // QString encryptedText(""); + + // // 2. Send the encrypted text to the rezzing avatar's node + // auto challengeOwnershipPacket = NLPacket::create(PacketType::ChallengeOwnership, NUM_BYTES_RFC4122_UUID + sizeof(encryptedText)); + // challengeOwnershipPacket->write(senderNode->getUUID()); + // challengeOwnershipPacket->writePrimitive(encryptedText); + // // 3. Kickoff a 10-second timeout timer that deletes the entity if we don't get an ownership response in time + //} + } else { + //qCDebug(entities) << "Call to proof_of_purchase_status endpoint failed; deleting entity" << entityItemID; + //deleteEntity(entityItemID, true); + } + }); } } diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 3ea48c113a..da202c0df9 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -18,6 +18,7 @@ #include "AccountManager.h" #include #include +#include #include #include @@ -281,10 +282,6 @@ signals: void newCollisionSoundURL(const QUrl& url, const EntityItemID& entityID); void clearingEntities(); -private slots: - void popStatusSuccess(QNetworkReply& reply); - void popStatusFailure(QNetworkReply& reply); - protected: void processRemovedEntities(const DeleteEntityOperator& theOperator); From f7ea50ef3bb5787bfdcb21841e3209bf1fc7f266 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 4 Oct 2017 14:02:28 -0700 Subject: [PATCH 007/116] Free memory --- libraries/entities/src/EntityTree.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index a31c5a139e..bb320317c6 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1365,9 +1365,11 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c // // 3. Kickoff a 10-second timeout timer that deletes the entity if we don't get an ownership response in time //} } else { - //qCDebug(entities) << "Call to proof_of_purchase_status endpoint failed; deleting entity" << entityItemID; - //deleteEntity(entityItemID, true); + qCDebug(entities) << "Call to proof_of_purchase_status endpoint failed; deleting entity" << entityItemID; + deleteEntity(entityItemID, true); } + + networkReply->deleteLater(); }); } } From b35eaf2cc80db190487c5072a76d15bb01f9ff66 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 4 Oct 2017 15:06:55 -0700 Subject: [PATCH 008/116] Throw a bunch of code at the wall and hope some sticks --- .../octree/OctreeInboundPacketProcessor.cpp | 4 +- interface/src/commerce/Wallet.cpp | 29 +++-- libraries/entities/src/EntityTree.cpp | 106 ++++++++++++++---- libraries/entities/src/EntityTree.h | 2 + libraries/octree/src/Octree.h | 1 + 5 files changed, 112 insertions(+), 30 deletions(-) diff --git a/assignment-client/src/octree/OctreeInboundPacketProcessor.cpp b/assignment-client/src/octree/OctreeInboundPacketProcessor.cpp index 04409b3b21..2723e8acd5 100644 --- a/assignment-client/src/octree/OctreeInboundPacketProcessor.cpp +++ b/assignment-client/src/octree/OctreeInboundPacketProcessor.cpp @@ -92,7 +92,9 @@ void OctreeInboundPacketProcessor::processPacket(QSharedPointer // Ask our tree subclass if it can handle the incoming packet... PacketType packetType = message->getType(); - if (_myServer->getOctree()->handlesEditPacketType(packetType)) { + if (packetType == PacketType::ChallengeOwnership) { + _myServer->getOctree()->processChallengeOwnershipPacket(*message, sendingNode); + } else if (_myServer->getOctree()->handlesEditPacketType(packetType)) { PerformanceWarning warn(debugProcessPacket, "processPacket KNOWN TYPE", debugProcessPacket); _receivedPacketCount++; diff --git a/interface/src/commerce/Wallet.cpp b/interface/src/commerce/Wallet.cpp index cc2039da48..93e3f7acda 100644 --- a/interface/src/commerce/Wallet.cpp +++ b/interface/src/commerce/Wallet.cpp @@ -656,16 +656,29 @@ bool Wallet::changePassphrase(const QString& newPassphrase) { void Wallet::handleChallengeOwnershipPacket(QSharedPointer packet, SharedNodePointer sendingNode) { QString decryptedText; - quint64 encryptedTextSize; - quint64 publicKeySize; + int certIDByteArraySize; + int encryptedTextByteArraySize; + int ownerKeyByteArraySize; - if (verifyOwnerChallenge(packet->read(packet->readPrimitive(&encryptedTextSize)), packet->read(packet->readPrimitive(&publicKeySize)), decryptedText)) { + packet->readPrimitive(&certIDByteArraySize); + packet->readPrimitive(&encryptedTextByteArraySize); + packet->readPrimitive(&ownerKeyByteArraySize); + + QByteArray certID = packet->read(certIDByteArraySize); + + if (verifyOwnerChallenge(packet->read(encryptedTextByteArraySize), packet->read(ownerKeyByteArraySize), decryptedText)) { auto nodeList = DependencyManager::get(); - // setup the packet - auto decryptedTextPacket = NLPacket::create(PacketType::ChallengeOwnership, NUM_BYTES_RFC4122_UUID + decryptedText.size(), true); - // write the decrypted text to the packet - decryptedTextPacket->write(decryptedText.toUtf8()); + QByteArray decryptedTextByteArray = decryptedText.toUtf8(); + int decryptedTextByteArraySize = decryptedTextByteArray.size(); + int certIDSize = certID.size(); + // setup the packet + auto decryptedTextPacket = NLPacket::create(PacketType::ChallengeOwnership, certIDSize + decryptedTextByteArraySize + 2*sizeof(int), true); + + decryptedTextPacket->writePrimitive(certIDSize); + decryptedTextPacket->writePrimitive(decryptedTextByteArraySize); + decryptedTextPacket->write(certID); + decryptedTextPacket->write(decryptedTextByteArray); qCDebug(commerce) << "Sending ChallengeOwnership Packet containing decrypted text"; @@ -677,6 +690,6 @@ void Wallet::handleChallengeOwnershipPacket(QSharedPointer pack bool Wallet::verifyOwnerChallenge(const QByteArray& encryptedText, const QString& publicKey, QString& decryptedText) { // I have no idea how to do this yet, so here's some dummy code that may not even work. - decryptedText = QString("hello"); + decryptedText = QString("fail"); return true; } diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index bb320317c6..29d0e0cc84 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1097,6 +1097,30 @@ bool EntityTree::isScriptInWhitelist(const QString& scriptProperty) { return false; } +void EntityTree::processChallengeOwnershipPacket(ReceivedMessage& message, const SharedNodePointer& sourceNode) { + int certIDByteArraySize; + int decryptedTextByteArraySize; + + message.readPrimitive(&certIDByteArraySize); + message.readPrimitive(&decryptedTextByteArraySize); + + QString certID(message.read(certIDByteArraySize)); + QString decryptedText(message.read(decryptedTextByteArraySize)); + + emit killChallengeOwnershipTimeoutTimer(certID); + + if (decryptedText == "fail") { + QReadLocker certIdMapLocker(&_entityCertificateIDMapLock); + EntityItemID id = _entityCertificateIDMap.value(certID); + + qCDebug(entities) << "Ownership challenge failed, deleting entity" << id; + deleteEntity(id, true); + QWriteLocker recentlyDeletedLocker(&_recentlyDeletedEntitiesLock); + _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), id); + } else { + } +} + int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned char* editData, int maxLength, const SharedNodePointer& senderNode) { @@ -1299,6 +1323,8 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c << "static certificate verification."; // Delete the entity we just added if it doesn't pass static certificate verification deleteEntity(entityItemID, true); + QWriteLocker locker(&_recentlyDeletedEntitiesLock); + _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID); } else { QString certID = properties.getCertificateID(); EntityItemID existingEntityItemID; @@ -1314,6 +1340,8 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c qCDebug(entities) << "Certificate ID" << certID << "already exists on entity with ID" << existingEntityItemID << ". Deleting existing entity."; deleteEntity(existingEntityItemID, true); + QWriteLocker locker(&_recentlyDeletedEntitiesLock); + _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), existingEntityItemID); } { @@ -1323,6 +1351,7 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c } // Start owner verification. + auto nodeList = DependencyManager::get(); // First, asynchronously hit "proof_of_purchase_status?transaction_type=transfer" endpoint. QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); QNetworkRequest networkRequest; @@ -1331,7 +1360,7 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c requestURL.setPath("/api/v1/commerce/proof_of_purchase_status?transaction_type=transfer"); QJsonObject request; request["certificate_id"] = certID; - request["domain_id"] = DependencyManager::get()->getDomainHandler().getUUID().toString(); + request["domain_id"] = nodeList->getDomainHandler().getUUID().toString(); networkRequest.setUrl(requestURL); QNetworkReply* networkReply = NULL; @@ -1340,33 +1369,68 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c connect(networkReply, &QNetworkReply::finished, [=]() { QJsonObject jsonObject = QJsonDocument::fromJson(networkReply->readAll()).object(); QJsonDocument doc(jsonObject); - qCDebug(entities) << "ZRF FIXME" << networkReply->error(); qCDebug(entities) << "ZRF FIXME" << doc.toJson(QJsonDocument::Compact); if (networkReply->error() == QNetworkReply::NoError) { - //QJsonObject jsonObject = QJsonDocument::fromJson(reply.readAll()).object(); - //qCDebug(entities) << "ZRF FIXME" << jsonObject; - //if (!jsonObject["invalid_reason"].toString().isEmpty()) { - // qCDebug(entities) << "invalid_reason not empty, deleting entity" << entityItemID; - // deleteEntity(entityItemID, true); - //} else if (jsonObject["transfer_status"].toString() == "failed") { - // qCDebug(entities) << "'transfer_status' is 'failed', deleting entity" << entityItemID; - // deleteEntity(entityItemID, true); - //} else { - // // Second, challenge ownership of the PoP cert - // // 1. Encrypt a nonce with the owner's public key - // QString ownerKey(jsonObject["owner_public_key"].toString()); - // QString encryptedText(""); + if (!jsonObject["invalid_reason"].toString().isEmpty()) { + qCDebug(entities) << "invalid_reason not empty, deleting entity" << entityItemID; + deleteEntity(entityItemID, true); + QWriteLocker locker(&_recentlyDeletedEntitiesLock); + _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID); + } else if (jsonObject["transfer_status"].toString() == "failed") { + qCDebug(entities) << "'transfer_status' is 'failed', deleting entity" << entityItemID; + deleteEntity(entityItemID, true); + QWriteLocker locker(&_recentlyDeletedEntitiesLock); + _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID); + } else { + // Second, challenge ownership of the PoP cert + // 1. Encrypt a nonce with the owner's public key + QString ownerKey(jsonObject["owner_public_key"].toString()); + QString encryptedText("test"); - // // 2. Send the encrypted text to the rezzing avatar's node - // auto challengeOwnershipPacket = NLPacket::create(PacketType::ChallengeOwnership, NUM_BYTES_RFC4122_UUID + sizeof(encryptedText)); - // challengeOwnershipPacket->write(senderNode->getUUID()); - // challengeOwnershipPacket->writePrimitive(encryptedText); - // // 3. Kickoff a 10-second timeout timer that deletes the entity if we don't get an ownership response in time - //} + // 2. Send the encrypted text to the rezzing avatar's node + QByteArray certIDByteArray = certID.toUtf8(); + int certIDByteArraySize = certIDByteArray.size(); + QByteArray encryptedTextByteArray = encryptedText.toUtf8(); + int encryptedTextByteArraySize = encryptedTextByteArray.size(); + QByteArray ownerKeyByteArray = ownerKey.toUtf8(); + int ownerKeyByteArraySize = ownerKeyByteArray.size(); + auto challengeOwnershipPacket = NLPacket::create(PacketType::ChallengeOwnership, + certIDByteArraySize + encryptedTextByteArraySize + ownerKeyByteArraySize + 3*sizeof(int), + true); + challengeOwnershipPacket->writePrimitive(certIDByteArraySize); + challengeOwnershipPacket->writePrimitive(encryptedTextByteArraySize); + challengeOwnershipPacket->writePrimitive(ownerKeyByteArraySize); + challengeOwnershipPacket->write(certIDByteArray); + challengeOwnershipPacket->write(encryptedTextByteArray); + challengeOwnershipPacket->write(ownerKeyByteArray); + nodeList->sendPacket(std::move(challengeOwnershipPacket), *senderNode); + + // 3. Kickoff a 10-second timeout timer that deletes the entity if we don't get an ownership response in time + QTimer* challengeOwnershipTimeoutTimer = new QTimer(this); + connect(this, &EntityTree::killChallengeOwnershipTimeoutTimer, this, [&](const QString& certID) { + QReadLocker locker(&_entityCertificateIDMapLock); + EntityItemID id = _entityCertificateIDMap.value(certID); + if (entityItemID == id) { + challengeOwnershipTimeoutTimer->stop(); + challengeOwnershipTimeoutTimer->deleteLater(); + } + }); + connect(challengeOwnershipTimeoutTimer, &QTimer::timeout, this, [=]() { + qCDebug(entities) << "Ownership challenge timed out, deleting entity" << entityItemID; + deleteEntity(entityItemID, true); + QWriteLocker locker(&_recentlyDeletedEntitiesLock); + _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID); + }); + challengeOwnershipTimeoutTimer->setSingleShot(false); + challengeOwnershipTimeoutTimer->setInterval(10000); + challengeOwnershipTimeoutTimer->start(); + } } else { qCDebug(entities) << "Call to proof_of_purchase_status endpoint failed; deleting entity" << entityItemID; deleteEntity(entityItemID, true); + QWriteLocker locker(&_recentlyDeletedEntitiesLock); + _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID); } networkReply->deleteLater(); diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index da202c0df9..68f2c605af 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -100,6 +100,7 @@ public: void fixupTerseEditLogging(EntityItemProperties& properties, QList& changedProperties); virtual int processEditPacketData(ReceivedMessage& message, const unsigned char* editData, int maxLength, const SharedNodePointer& senderNode) override; + virtual void processChallengeOwnershipPacket(ReceivedMessage& message, const SharedNodePointer& sourceNode) override; virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, QVector entityIdsToInclude, QVector entityIdsToDiscard, @@ -281,6 +282,7 @@ signals: void entityServerScriptChanging(const EntityItemID& entityItemID, const bool reload); void newCollisionSoundURL(const QUrl& url, const EntityItemID& entityID); void clearingEntities(); + void killChallengeOwnershipTimeoutTimer(const QString& certID); protected: diff --git a/libraries/octree/src/Octree.h b/libraries/octree/src/Octree.h index a2df5f44e5..250577f351 100644 --- a/libraries/octree/src/Octree.h +++ b/libraries/octree/src/Octree.h @@ -214,6 +214,7 @@ public: virtual bool handlesEditPacketType(PacketType packetType) const { return false; } virtual int processEditPacketData(ReceivedMessage& message, const unsigned char* editData, int maxLength, const SharedNodePointer& sourceNode) { return 0; } + virtual void processChallengeOwnershipPacket(ReceivedMessage& message, const SharedNodePointer& sourceNode) { return; } virtual bool recurseChildrenWithData() const { return true; } virtual bool rootElementHasData() const { return false; } From f974672e7b31171b8cbe913eb7d675187278b0d2 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 4 Oct 2017 15:19:06 -0700 Subject: [PATCH 009/116] Working way better than I expected --- assignment-client/src/entities/EntityServer.cpp | 2 +- libraries/entities/src/EntityTree.cpp | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index 2c8f8a9e37..1c1e02316a 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -36,7 +36,7 @@ EntityServer::EntityServer(ReceivedMessage& message) : DependencyManager::set(); auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver.registerListenerForTypes({ PacketType::EntityAdd, PacketType::EntityEdit, PacketType::EntityErase, PacketType::EntityPhysics }, + packetReceiver.registerListenerForTypes({ PacketType::EntityAdd, PacketType::EntityEdit, PacketType::EntityErase, PacketType::EntityPhysics, PacketType::ChallengeOwnership }, this, "handleEntityPacket"); } diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 29d0e0cc84..64b9c7b1ca 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1107,6 +1107,8 @@ void EntityTree::processChallengeOwnershipPacket(ReceivedMessage& message, const QString certID(message.read(certIDByteArraySize)); QString decryptedText(message.read(decryptedTextByteArraySize)); + qCDebug(entities) << "ZRF FIXME" << decryptedText << certID; + emit killChallengeOwnershipTimeoutTimer(certID); if (decryptedText == "fail") { @@ -1371,17 +1373,24 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c QJsonDocument doc(jsonObject); qCDebug(entities) << "ZRF FIXME" << doc.toJson(QJsonDocument::Compact); - if (networkReply->error() == QNetworkReply::NoError) { - if (!jsonObject["invalid_reason"].toString().isEmpty()) { + // ZRF FIXME!!! + //if (networkReply->error() == QNetworkReply::NoError) { + if (true) { + // ZRF FIXME!!! + //if (!jsonObject["invalid_reason"].toString().isEmpty()) { + if (false) { qCDebug(entities) << "invalid_reason not empty, deleting entity" << entityItemID; deleteEntity(entityItemID, true); QWriteLocker locker(&_recentlyDeletedEntitiesLock); _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID); - } else if (jsonObject["transfer_status"].toString() == "failed") { + // ZRF FIXME!!! + //} else if (jsonObject["transfer_status"].toString() == "failed") { + } else if (false) { qCDebug(entities) << "'transfer_status' is 'failed', deleting entity" << entityItemID; deleteEntity(entityItemID, true); QWriteLocker locker(&_recentlyDeletedEntitiesLock); _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID); + // ZRF FIXME!!! } else { // Second, challenge ownership of the PoP cert // 1. Encrypt a nonce with the owner's public key @@ -1422,7 +1431,6 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c QWriteLocker locker(&_recentlyDeletedEntitiesLock); _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID); }); - challengeOwnershipTimeoutTimer->setSingleShot(false); challengeOwnershipTimeoutTimer->setInterval(10000); challengeOwnershipTimeoutTimer->start(); } From 4cfb860e23ea75dbfa083b44587993e16ed51842 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 4 Oct 2017 15:45:12 -0700 Subject: [PATCH 010/116] Wow, this actually seems to be working --- libraries/entities/src/EntityTree.cpp | 45 +++++++++++++++++---------- libraries/entities/src/EntityTree.h | 2 ++ 2 files changed, 30 insertions(+), 17 deletions(-) diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 64b9c7b1ca..7322378b5f 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1097,6 +1097,28 @@ bool EntityTree::isScriptInWhitelist(const QString& scriptProperty) { return false; } +void EntityTree::startChallengeOwnershipTimer(const EntityItemID& entityItemID) { + QTimer* _challengeOwnershipTimeoutTimer = new QTimer(this); + connect(this, &EntityTree::killChallengeOwnershipTimeoutTimer, this, [&](const QString& certID) { + QReadLocker locker(&_entityCertificateIDMapLock); + EntityItemID id = _entityCertificateIDMap.value(certID); + if (entityItemID == id) { + _challengeOwnershipTimeoutTimer->stop(); + _challengeOwnershipTimeoutTimer->deleteLater(); + } + }); + connect(_challengeOwnershipTimeoutTimer, &QTimer::timeout, this, [=]() { + qCDebug(entities) << "Ownership challenge timed out, deleting entity" << entityItemID; + deleteEntity(entityItemID, true); + QWriteLocker locker(&_recentlyDeletedEntitiesLock); + _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID); + _challengeOwnershipTimeoutTimer->stop(); + _challengeOwnershipTimeoutTimer->deleteLater(); + }); + _challengeOwnershipTimeoutTimer->setInterval(5000); + _challengeOwnershipTimeoutTimer->start(); +} + void EntityTree::processChallengeOwnershipPacket(ReceivedMessage& message, const SharedNodePointer& sourceNode) { int certIDByteArraySize; int decryptedTextByteArraySize; @@ -1416,23 +1438,12 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c nodeList->sendPacket(std::move(challengeOwnershipPacket), *senderNode); // 3. Kickoff a 10-second timeout timer that deletes the entity if we don't get an ownership response in time - QTimer* challengeOwnershipTimeoutTimer = new QTimer(this); - connect(this, &EntityTree::killChallengeOwnershipTimeoutTimer, this, [&](const QString& certID) { - QReadLocker locker(&_entityCertificateIDMapLock); - EntityItemID id = _entityCertificateIDMap.value(certID); - if (entityItemID == id) { - challengeOwnershipTimeoutTimer->stop(); - challengeOwnershipTimeoutTimer->deleteLater(); - } - }); - connect(challengeOwnershipTimeoutTimer, &QTimer::timeout, this, [=]() { - qCDebug(entities) << "Ownership challenge timed out, deleting entity" << entityItemID; - deleteEntity(entityItemID, true); - QWriteLocker locker(&_recentlyDeletedEntitiesLock); - _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID); - }); - challengeOwnershipTimeoutTimer->setInterval(10000); - challengeOwnershipTimeoutTimer->start(); + if (thread() != QThread::currentThread()) { + QMetaObject::invokeMethod(this, "startChallengeOwnershipTimer", Q_ARG(const EntityItemID&, entityItemID)); + return; + } else { + startChallengeOwnershipTimer(entityItemID); + } } } else { qCDebug(entities) << "Call to proof_of_purchase_status endpoint failed; deleting entity" << entityItemID; diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 68f2c605af..210a35d407 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -367,6 +367,8 @@ protected: MovingEntitiesOperator _entityMover; QHash _entitiesToAdd; + + Q_INVOKABLE void startChallengeOwnershipTimer(const EntityItemID& entityItemID); }; #endif // hifi_EntityTree_h From 1fa9bd8fc6c169454296e97aceb956a76deb5e1d Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Fri, 6 Oct 2017 10:47:06 -0700 Subject: [PATCH 011/116] Better implementation of location change and bugfixes --- .../qml/hifi/commerce/checkout/Checkout.qml | 1 - .../hifi/commerce/purchases/PurchasedItem.qml | 1 - .../qml/hifi/commerce/wallet/Wallet.qml | 2 +- interface/src/Application.cpp | 6 +++ interface/src/Application.h | 1 + interface/src/commerce/Ledger.cpp | 24 ++++++++---- interface/src/commerce/QmlCommerce.cpp | 38 ++----------------- interface/src/commerce/QmlCommerce.h | 9 ----- interface/src/commerce/Wallet.cpp | 38 +++++++++++++++++++ interface/src/commerce/Wallet.h | 13 +++++++ .../scripting/WalletScriptingInterface.cpp | 5 +++ .../src/scripting/WalletScriptingInterface.h | 3 ++ .../entities/src/EntityEditPacketSender.cpp | 5 ++- .../entities/src/EntityEditPacketSender.h | 3 ++ libraries/entities/src/EntityTree.cpp | 33 ++++++++++------ libraries/entities/src/EntityTree.h | 1 + scripts/system/marketplaces/marketplaces.js | 11 ++++-- scripts/system/notifications.js | 9 ++++- 18 files changed, 131 insertions(+), 72 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml index e7bbaec755..09c2f6fa76 100644 --- a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml +++ b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml @@ -579,7 +579,6 @@ Rectangle { } rezzedNotifContainer.visible = true; rezzedNotifContainerTimer.start(); - commerce.updatePopLocation(root.itemId); } } RalewaySemiBold { diff --git a/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml b/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml index e343b93117..5eb5516519 100644 --- a/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml +++ b/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml @@ -347,7 +347,6 @@ Item { if (urlHandler.canHandleUrl(root.itemHref)) { urlHandler.handleUrl(root.itemHref); } - commerce.updatePopLocation(root.itemId); rezzedNotifContainer.visible = true; rezzedNotifContainerTimer.start(); } diff --git a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml index 9056d5bed3..0bc444efb5 100644 --- a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml +++ b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml @@ -283,7 +283,7 @@ Rectangle { Connections { onSendSignalToParent: { if (msg.method === "authSuccess") { - root.activeView = "walletHome"; + commerce.getWalletStatus(); } else { sendToScript(msg); } diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 0fc8c46cdc..6608cfe5fc 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1006,6 +1006,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo // connect to the packet sent signal of the _entityEditSender connect(&_entityEditSender, &EntityEditPacketSender::packetSent, this, &Application::packetSent); + connect(&_entityEditSender, &EntityEditPacketSender::addingEntityWithCertificate, this, &Application::addingEntityWithCertificate); const char** constArgv = const_cast(argv); QString concurrentDownloadsStr = getCmdOption(argc, constArgv, "--concurrent-downloads"); @@ -5735,6 +5736,11 @@ int Application::processOctreeStats(ReceivedMessage& message, SharedNodePointer void Application::packetSent(quint64 length) { } +void Application::addingEntityWithCertificate(const QString& certificateID, const QString& domainID) { + auto ledger = DependencyManager::get(); + ledger->updateLocation(certificateID, domainID); +} + void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointer scriptEngine) { scriptEngine->setEmitScriptUpdatesFunction([this]() { diff --git a/interface/src/Application.h b/interface/src/Application.h index 478642e2da..061fae5bcd 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -440,6 +440,7 @@ private slots: void nodeActivated(SharedNodePointer node); void nodeKilled(SharedNodePointer node); static void packetSent(quint64 length); + static void addingEntityWithCertificate(const QString& certificateID, const QString& domainID); void updateDisplayMode(); void domainConnectionRefused(const QString& reasonMessage, int reason, const QString& extraInfo); diff --git a/interface/src/commerce/Ledger.cpp b/interface/src/commerce/Ledger.cpp index e926d8918e..2f5e79f28b 100644 --- a/interface/src/commerce/Ledger.cpp +++ b/interface/src/commerce/Ledger.cpp @@ -225,12 +225,20 @@ void Ledger::updateLocationSuccess(QNetworkReply& reply) { apiResponse("updateLo void Ledger::updateLocationFailure(QNetworkReply& reply) { failResponse("updateLocation", reply); } void Ledger::updateLocation(const QString& asset_id, const QString location, const bool controlledFailure) { auto wallet = DependencyManager::get(); - QStringList keys = wallet->listPublicKeys(); - QString key = keys[0]; - QJsonObject transaction; - transaction["asset_id"] = asset_id; - transaction["location"] = location; - QJsonDocument transactionDoc{ transaction }; - auto transactionString = transactionDoc.toJson(QJsonDocument::Compact); - signedSend("transaction", transactionString, key, "location", "updateLocationSuccess", "updateLocationFailure", controlledFailure); + auto walletScriptingInterface = DependencyManager::get(); + uint walletStatus = walletScriptingInterface->getWalletStatus(); + + if (walletStatus != wallet->WALLET_STATUS_READY) { + emit walletScriptingInterface->walletNotSetup(); + qDebug(commerce) << "User attempted to update the location of a certificate, but their wallet wasn't ready. Status:" << walletStatus; + } else { + QStringList keys = wallet->listPublicKeys(); + QString key = keys[0]; + QJsonObject transaction; + transaction["asset_id"] = asset_id; + transaction["location"] = location; + QJsonDocument transactionDoc{ transaction }; + auto transactionString = transactionDoc.toJson(QJsonDocument::Compact); + signedSend("transaction", transactionString, key, "location", "updateLocationSuccess", "updateLocationFailure", controlledFailure); + } } diff --git a/interface/src/commerce/QmlCommerce.cpp b/interface/src/commerce/QmlCommerce.cpp index 46c73708de..ee75bc59e3 100644 --- a/interface/src/commerce/QmlCommerce.cpp +++ b/interface/src/commerce/QmlCommerce.cpp @@ -15,7 +15,6 @@ #include "Ledger.h" #include "Wallet.h" #include -#include "scripting/WalletScriptingInterface.h" HIFI_QML_DEF(QmlCommerce) @@ -29,37 +28,12 @@ QmlCommerce::QmlCommerce(QQuickItem* parent) : OffscreenQmlDialog(parent) { connect(ledger.data(), &Ledger::historyResult, this, &QmlCommerce::historyResult); connect(wallet.data(), &Wallet::keyFilePathIfExistsResult, this, &QmlCommerce::keyFilePathIfExistsResult); connect(ledger.data(), &Ledger::accountResult, this, &QmlCommerce::accountResult); - connect(ledger.data(), &Ledger::accountResult, this, [&]() { - auto wallet = DependencyManager::get(); - auto walletScriptingInterface = DependencyManager::get(); - uint status; - - if (wallet->getKeyFilePath() == "" || !wallet->getSecurityImage()) { - status = (uint)WalletStatus::WALLET_STATUS_NOT_SET_UP; - } else if (!wallet->walletIsAuthenticatedWithPassphrase()) { - status = (uint)WalletStatus::WALLET_STATUS_NOT_AUTHENTICATED; - } else { - status = (uint)WalletStatus::WALLET_STATUS_READY; - } - - walletScriptingInterface->setWalletStatus(status); - emit walletStatusResult(status); - }); + connect(wallet.data(), &Wallet::walletStatusResult, this, &QmlCommerce::walletStatusResult); } void QmlCommerce::getWalletStatus() { - auto walletScriptingInterface = DependencyManager::get(); - uint status; - - if (DependencyManager::get()->isLoggedIn()) { - // This will set account info for the wallet, allowing us to decrypt and display the security image. - account(); - } else { - status = (uint)WalletStatus::WALLET_STATUS_NOT_LOGGED_IN; - emit walletStatusResult(status); - walletScriptingInterface->setWalletStatus(status); - return; - } + auto wallet = DependencyManager::get(); + wallet->getWalletStatus(); } void QmlCommerce::getLoginStatus() { @@ -151,9 +125,3 @@ void QmlCommerce::account() { auto ledger = DependencyManager::get(); ledger->account(); } - -void QmlCommerce::updatePopLocation(const QString& popId, const bool controlledFailure) { - auto ledger = DependencyManager::get(); - auto nodeList = DependencyManager::get(); - ledger->updateLocation(popId, nodeList->getDomainHandler().getUUID().toString(), controlledFailure); -} diff --git a/interface/src/commerce/QmlCommerce.h b/interface/src/commerce/QmlCommerce.h index b1d179aae8..45a5360680 100644 --- a/interface/src/commerce/QmlCommerce.h +++ b/interface/src/commerce/QmlCommerce.h @@ -27,13 +27,6 @@ class QmlCommerce : public OffscreenQmlDialog { public: QmlCommerce(QQuickItem* parent = nullptr); - enum WalletStatus { - WALLET_STATUS_NOT_LOGGED_IN = 0, - WALLET_STATUS_NOT_SET_UP, - WALLET_STATUS_NOT_AUTHENTICATED, - WALLET_STATUS_READY - }; - signals: void walletStatusResult(uint walletStatus); @@ -70,8 +63,6 @@ protected: Q_INVOKABLE void generateKeyPair(); Q_INVOKABLE void reset(); Q_INVOKABLE void account(); - - Q_INVOKABLE void updatePopLocation(const QString& popId, const bool controlledFailure = false); }; #endif // hifi_QmlCommerce_h diff --git a/interface/src/commerce/Wallet.cpp b/interface/src/commerce/Wallet.cpp index 8b6f2785f1..34e266b32c 100644 --- a/interface/src/commerce/Wallet.cpp +++ b/interface/src/commerce/Wallet.cpp @@ -282,9 +282,27 @@ void initializeAESKeys(unsigned char* ivec, unsigned char* ckey, const QByteArra Wallet::Wallet() { auto nodeList = DependencyManager::get(); + auto ledger = DependencyManager::get(); auto& packetReceiver = nodeList->getPacketReceiver(); packetReceiver.registerListener(PacketType::ChallengeOwnership, this, "handleChallengeOwnershipPacket"); + + connect(ledger.data(), &Ledger::accountResult, this, [&]() { + auto wallet = DependencyManager::get(); + auto walletScriptingInterface = DependencyManager::get(); + uint status; + + if (wallet->getKeyFilePath() == "" || !wallet->getSecurityImage()) { + status = (uint)WalletStatus::WALLET_STATUS_NOT_SET_UP; + } else if (!wallet->walletIsAuthenticatedWithPassphrase()) { + status = (uint)WalletStatus::WALLET_STATUS_NOT_AUTHENTICATED; + } else { + status = (uint)WalletStatus::WALLET_STATUS_READY; + } + + walletScriptingInterface->setWalletStatus(status); + emit walletStatusResult(status); + }); } Wallet::~Wallet() { @@ -695,3 +713,23 @@ bool Wallet::verifyOwnerChallenge(const QByteArray& encryptedText, const QString decryptedText = QString("fail"); return true; } + +void Wallet::account() { + auto ledger = DependencyManager::get(); + ledger->account(); +} + +void Wallet::getWalletStatus() { + auto walletScriptingInterface = DependencyManager::get(); + uint status; + + if (DependencyManager::get()->isLoggedIn()) { + // This will set account info for the wallet, allowing us to decrypt and display the security image. + account(); + } else { + status = (uint)WalletStatus::WALLET_STATUS_NOT_LOGGED_IN; + emit walletStatusResult(status); + walletScriptingInterface->setWalletStatus(status); + return; + } +} diff --git a/interface/src/commerce/Wallet.h b/interface/src/commerce/Wallet.h index acf9f8e45e..38c5299810 100644 --- a/interface/src/commerce/Wallet.h +++ b/interface/src/commerce/Wallet.h @@ -17,6 +17,7 @@ #include #include #include +#include "scripting/WalletScriptingInterface.h" #include @@ -50,10 +51,20 @@ public: void reset(); + void getWalletStatus(); + enum WalletStatus { + WALLET_STATUS_NOT_LOGGED_IN = 0, + WALLET_STATUS_NOT_SET_UP, + WALLET_STATUS_NOT_AUTHENTICATED, + WALLET_STATUS_READY + }; + signals: void securityImageResult(bool exists); void keyFilePathIfExistsResult(const QString& path); + void walletStatusResult(uint walletStatus); + private slots: void handleChallengeOwnershipPacket(QSharedPointer packet, SharedNodePointer sendingNode); @@ -71,6 +82,8 @@ private: bool readSecurityImage(const QString& inputFilePath, unsigned char** outputBufferPtr, int* outputBufferLen); bool verifyOwnerChallenge(const QByteArray& encryptedText, const QString& publicKey, QString& decryptedText); + + void account(); }; #endif // hifi_Wallet_h diff --git a/interface/src/scripting/WalletScriptingInterface.cpp b/interface/src/scripting/WalletScriptingInterface.cpp index 555e9477b0..99fdd5fbde 100644 --- a/interface/src/scripting/WalletScriptingInterface.cpp +++ b/interface/src/scripting/WalletScriptingInterface.cpp @@ -18,6 +18,11 @@ CheckoutProxy::CheckoutProxy(QObject* qmlObject, QObject* parent) : QmlWrapper(q WalletScriptingInterface::WalletScriptingInterface() { } +void WalletScriptingInterface::refreshWalletStatus() { + auto wallet = DependencyManager::get(); + wallet->getWalletStatus(); +} + static const QString CHECKOUT_QML_PATH = qApp->applicationDirPath() + "../../../qml/hifi/commerce/checkout/Checkout.qml"; void WalletScriptingInterface::buy(const QString& name, const QString& id, const int& price, const QString& href) { if (QThread::currentThread() != thread()) { diff --git a/interface/src/scripting/WalletScriptingInterface.h b/interface/src/scripting/WalletScriptingInterface.h index 31b42094cf..038c580197 100644 --- a/interface/src/scripting/WalletScriptingInterface.h +++ b/interface/src/scripting/WalletScriptingInterface.h @@ -20,6 +20,7 @@ #include #include #include "Application.h" +#include "commerce/Wallet.h" class CheckoutProxy : public QmlWrapper { Q_OBJECT @@ -36,6 +37,7 @@ class WalletScriptingInterface : public QObject, public Dependency { public: WalletScriptingInterface(); + Q_INVOKABLE void refreshWalletStatus(); Q_INVOKABLE uint getWalletStatus() { return _walletStatus; } void setWalletStatus(const uint& status) { _walletStatus = status; } @@ -43,6 +45,7 @@ public: signals: void walletStatusChanged(); + void walletNotSetup(); private: uint _walletStatus; diff --git a/libraries/entities/src/EntityEditPacketSender.cpp b/libraries/entities/src/EntityEditPacketSender.cpp index ee0fcf8218..2f8b796c93 100644 --- a/libraries/entities/src/EntityEditPacketSender.cpp +++ b/libraries/entities/src/EntityEditPacketSender.cpp @@ -93,9 +93,9 @@ void EntityEditPacketSender::queueEditEntityMessage(PacketType type, QByteArray bufferOut(NLPacket::maxPayloadSize(type), 0); bool success; + auto nodeList = DependencyManager::get(); if (properties.parentIDChanged() && properties.getParentID() == AVATAR_SELF_ID) { EntityItemProperties propertiesCopy = properties; - auto nodeList = DependencyManager::get(); const QUuid myNodeID = nodeList->getSessionUUID(); propertiesCopy.setParentID(myNodeID); success = EntityItemProperties::encodeEntityEditPacket(type, entityItemID, propertiesCopy, bufferOut); @@ -110,6 +110,9 @@ void EntityEditPacketSender::queueEditEntityMessage(PacketType type, qCDebug(entities) << " properties:" << properties; #endif queueOctreeEditMessage(type, bufferOut); + if (type == PacketType::EntityAdd && !properties.getCertificateID().isEmpty()) { + emit addingEntityWithCertificate(properties.getCertificateID(), nodeList->getDomainHandler().getUUID().toString()); + } } } diff --git a/libraries/entities/src/EntityEditPacketSender.h b/libraries/entities/src/EntityEditPacketSender.h index 81efaa865c..4e5b62e206 100644 --- a/libraries/entities/src/EntityEditPacketSender.h +++ b/libraries/entities/src/EntityEditPacketSender.h @@ -43,6 +43,9 @@ public: virtual char getMyNodeType() const override { return NodeType::EntityServer; } virtual void adjustEditPacketForClockSkew(PacketType type, QByteArray& buffer, qint64 clockSkew) override; +signals: + void addingEntityWithCertificate(const QString& certificateID, const QString& domainID); + public slots: void processEntityEditNackPacket(QSharedPointer message, SharedNodePointer sendingNode); diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 7322378b5f..35c47e48c9 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1099,10 +1099,10 @@ bool EntityTree::isScriptInWhitelist(const QString& scriptProperty) { void EntityTree::startChallengeOwnershipTimer(const EntityItemID& entityItemID) { QTimer* _challengeOwnershipTimeoutTimer = new QTimer(this); - connect(this, &EntityTree::killChallengeOwnershipTimeoutTimer, this, [&](const QString& certID) { + connect(this, &EntityTree::killChallengeOwnershipTimeoutTimer, this, [=](const QString& certID) { QReadLocker locker(&_entityCertificateIDMapLock); EntityItemID id = _entityCertificateIDMap.value(certID); - if (entityItemID == id) { + if (entityItemID == id && _challengeOwnershipTimeoutTimer) { _challengeOwnershipTimeoutTimer->stop(); _challengeOwnershipTimeoutTimer->deleteLater(); } @@ -1112,8 +1112,10 @@ void EntityTree::startChallengeOwnershipTimer(const EntityItemID& entityItemID) deleteEntity(entityItemID, true); QWriteLocker locker(&_recentlyDeletedEntitiesLock); _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID); - _challengeOwnershipTimeoutTimer->stop(); - _challengeOwnershipTimeoutTimer->deleteLater(); + if (_challengeOwnershipTimeoutTimer) { + _challengeOwnershipTimeoutTimer->stop(); + _challengeOwnershipTimeoutTimer->deleteLater(); + } }); _challengeOwnershipTimeoutTimer->setInterval(5000); _challengeOwnershipTimeoutTimer->start(); @@ -1134,14 +1136,18 @@ void EntityTree::processChallengeOwnershipPacket(ReceivedMessage& message, const emit killChallengeOwnershipTimeoutTimer(certID); if (decryptedText == "fail") { - QReadLocker certIdMapLocker(&_entityCertificateIDMapLock); - EntityItemID id = _entityCertificateIDMap.value(certID); - - qCDebug(entities) << "Ownership challenge failed, deleting entity" << id; - deleteEntity(id, true); - QWriteLocker recentlyDeletedLocker(&_recentlyDeletedEntitiesLock); - _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), id); - } else { + EntityItemID id; + { + QReadLocker certIdMapLocker(&_entityCertificateIDMapLock); + id = _entityCertificateIDMap.value(certID); + } + + if (!id.isNull()) { + qCDebug(entities) << "Ownership challenge failed, deleting entity" << id; + deleteEntity(id, true); + QWriteLocker recentlyDeletedLocker(&_recentlyDeletedEntitiesLock); + _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), id); + } } } @@ -2173,3 +2179,6 @@ QStringList EntityTree::getJointNames(const QUuid& entityID) const { return entity->getJointNames(); } +void EntityTree::startDynamicDomainVerification() { + +} diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 210a35d407..85ce6a2ed5 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -369,6 +369,7 @@ protected: QHash _entitiesToAdd; Q_INVOKABLE void startChallengeOwnershipTimer(const EntityItemID& entityItemID); + void startDynamicDomainVerification(); }; #endif // hifi_EntityTree_h diff --git a/scripts/system/marketplaces/marketplaces.js b/scripts/system/marketplaces/marketplaces.js index e94b227a4a..0bee540a9d 100644 --- a/scripts/system/marketplaces/marketplaces.js +++ b/scripts/system/marketplaces/marketplaces.js @@ -129,6 +129,10 @@ } } + function openWallet() { + tablet.pushOntoStack(MARKETPLACE_WALLET_QML_PATH); + } + function setCertificateInfo(currentEntityWithContextOverlay, itemMarketplaceId) { wireEventBridge(true); tablet.sendToQml({ @@ -158,6 +162,7 @@ Entities.canWriteAssetsChanged.connect(onCanWriteAssetsChanged); ContextOverlay.contextOverlayClicked.connect(setCertificateInfo); GlobalServices.myUsernameChanged.connect(onUsernameChanged); + Wallet.refreshWalletStatus(); function onMessage(message) { @@ -214,7 +219,7 @@ } else if (parsedJsonMessage.type === "LOGIN") { openLoginWindow(); } else if (parsedJsonMessage.type === "WALLET_SETUP") { - tablet.pushOntoStack(MARKETPLACE_WALLET_QML_PATH); + openWallet(); } else if (parsedJsonMessage.type === "MY_ITEMS") { referrerURL = MARKETPLACE_URL_INITIAL; filterText = ""; @@ -281,7 +286,7 @@ case 'purchases_openWallet': case 'checkout_openWallet': case 'checkout_setUpClicked': - tablet.pushOntoStack(MARKETPLACE_WALLET_QML_PATH); + openWallet(); break; case 'purchases_walletNotSetUp': case 'checkout_walletNotSetUp': @@ -290,7 +295,7 @@ method: 'updateWalletReferrer', referrer: "purchases" }); - tablet.pushOntoStack(MARKETPLACE_WALLET_QML_PATH); + openWallet(); break; case 'checkout_cancelClicked': tablet.gotoWebScreen(MARKETPLACE_URL + '/items/' + message.params, MARKETPLACES_INJECT_SCRIPT_URL); diff --git a/scripts/system/notifications.js b/scripts/system/notifications.js index ffe93d13e8..a23a390e9b 100644 --- a/scripts/system/notifications.js +++ b/scripts/system/notifications.js @@ -94,13 +94,15 @@ EDIT_ERROR: 4, TABLET: 5, CONNECTION: 6, + WALLET: 7, properties: [ { text: "Snapshot" }, { text: "Level of Detail" }, { text: "Connection Refused" }, { text: "Edit error" }, { text: "Tablet" }, - { text: "Connection" } + { text: "Connection" }, + { text: "Wallet" } ], getTypeFromMenuItem: function (menuItemName) { var type; @@ -574,6 +576,10 @@ createNotification(wordWrap("Error trying to make connection: " + error), NotificationType.CONNECTION); } + function walletNotSetup() { + createNotification("The action you performed requires you to set up your Wallet. Open the Wallet app.", NotificationType.SNAPSHOT); + } + // handles mouse clicks on buttons function mousePressEvent(event) { var pickRay, @@ -682,6 +688,7 @@ Window.notifyEditError = onEditError; Window.notify = onNotify; Tablet.tabletNotification.connect(tabletNotification); + Wallet.walletNotSetup.connect(walletNotSetup); setup(); }()); // END LOCAL_SCOPE From 59a6726af6a0153f7cb93e58aa3f4588fb6c06ce Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Fri, 6 Oct 2017 15:18:39 -0700 Subject: [PATCH 012/116] Checkpoint; lotsa changes... --- .../src/entities/EntityServer.cpp | 62 +++++- assignment-client/src/entities/EntityServer.h | 7 + .../qml/hifi/commerce/checkout/Checkout.qml | 2 +- .../qml/hifi/commerce/purchases/Purchases.qml | 10 +- .../qml/hifi/commerce/wallet/Wallet.qml | 2 + interface/src/commerce/Wallet.cpp | 2 +- libraries/entities/src/EntityTree.cpp | 182 +++++++++--------- libraries/entities/src/EntityTree.h | 6 +- scripts/system/commerce/wallet.js | 5 + scripts/system/html/js/marketplacesInject.js | 1 - scripts/system/marketplaces/marketplaces.js | 8 +- 11 files changed, 186 insertions(+), 101 deletions(-) diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index 1c1e02316a..445af3ac34 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -29,7 +29,8 @@ const char* LOCAL_MODELS_PERSIST_FILE = "resources/models.svo"; EntityServer::EntityServer(ReceivedMessage& message) : OctreeServer(message), - _entitySimulation(NULL) + _entitySimulation(NULL), + _dynamicDomainVerificationTimer(this) { DependencyManager::set(); DependencyManager::set(); @@ -38,6 +39,9 @@ EntityServer::EntityServer(ReceivedMessage& message) : auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); packetReceiver.registerListenerForTypes({ PacketType::EntityAdd, PacketType::EntityEdit, PacketType::EntityErase, PacketType::EntityPhysics, PacketType::ChallengeOwnership }, this, "handleEntityPacket"); + + connect(&_dynamicDomainVerificationTimer, &QTimer::timeout, this, &EntityServer::startDynamicDomainVerification); + _dynamicDomainVerificationTimer.setSingleShot(true); } EntityServer::~EntityServer() { @@ -93,6 +97,8 @@ void EntityServer::beforeRun() { connect(_pruneDeletedEntitiesTimer, SIGNAL(timeout()), this, SLOT(pruneDeletedEntities())); const int PRUNE_DELETED_MODELS_INTERVAL_MSECS = 1 * 1000; // once every second _pruneDeletedEntitiesTimer->start(PRUNE_DELETED_MODELS_INTERVAL_MSECS); + + startDynamicDomainVerification(); } void EntityServer::entityCreated(const EntityItem& newEntity, const SharedNodePointer& senderNode) { @@ -410,3 +416,57 @@ QString EntityServer::serverSubclassStats() { return statsString; } + +void EntityServer::startDynamicDomainVerification() { + qCDebug(entities) << "Starting Dynamic Domain Verification..."; + + auto nodeList = DependencyManager::get(); + QString thisDomainID = nodeList->getDomainHandler().getUUID().toString(); + + EntityTreePointer tree = std::static_pointer_cast(_tree); + QHash localMap(tree->getEntityCertificateIDMap()); + + QHashIterator i(localMap); + qCDebug(entities) << localMap.size() << "entities in _entityCertificateIDMap"; + while (i.hasNext()) { + i.next(); + + QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); + QNetworkRequest networkRequest; + networkRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); + QUrl requestURL = NetworkingConstants::METAVERSE_SERVER_URL; + requestURL.setPath("/api/v1/commerce/proof_of_purchase_status"); + QJsonObject request; + request["certificate_id"] = i.key(); + networkRequest.setUrl(requestURL); + + QNetworkReply* networkReply = NULL; + networkReply = networkAccessManager.get(networkRequest); + + connect(networkReply, &QNetworkReply::finished, [=]() { + QJsonObject jsonObject = QJsonDocument::fromJson(networkReply->readAll()).object(); + QJsonDocument doc(jsonObject); + qCDebug(entities) << "ZRF FIXME" << doc.toJson(QJsonDocument::Compact); + + // ZRF FIXME!!! + //if (networkReply->error() == QNetworkReply::NoError) { + if (true) { + // ZRF FIXME!!! + //if (jsonObject["location"].toString() != thisDomainID) { + if (false) { + qCDebug(entities) << "invalid_reason not empty, deleting entity" << i.value(); + tree->deleteEntity(i.value(), true); + } + } else { + qCDebug(entities) << "Call to proof_of_purchase_status endpoint failed; deleting entity" << i.value(); + tree->deleteEntity(i.value(), true); + } + + networkReply->deleteLater(); + }); + } + + int nextInterval = qrand() % ((MAXIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS + 1) - MINIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS) + MINIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS; + qCDebug(entities) << "Restarting Dynamic Domain Verification timer for" << nextInterval / 1000 << "seconds"; + _dynamicDomainVerificationTimer.start(nextInterval); +} diff --git a/assignment-client/src/entities/EntityServer.h b/assignment-client/src/entities/EntityServer.h index 26c2f149aa..39d15f726e 100644 --- a/assignment-client/src/entities/EntityServer.h +++ b/assignment-client/src/entities/EntityServer.h @@ -80,6 +80,13 @@ private: QReadWriteLock _viewerSendingStatsLock; QMap> _viewerSendingStats; + + //static const int MINIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS = 45 * 60 * 1000; // 45m + //static const int MAXIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS = 75 * 60 * 1000; // 1h15m + static const int MINIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS = 5 * 1000; // 5s + static const int MAXIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS = 10 * 1000; // 10s + QTimer _dynamicDomainVerificationTimer; + void startDynamicDomainVerification(); }; #endif // hifi_EntityServer_h diff --git a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml index 09c2f6fa76..2ab8e90e9d 100644 --- a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml +++ b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml @@ -125,7 +125,7 @@ Rectangle { id: notSetUpTimer; interval: 200; onTriggered: { - sendToScript({method: 'checkout_walletNotSetUp'}); + sendToScript({method: 'checkout_walletNotSetUp', itemId: itemId}); } } diff --git a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml index 990fd348c6..42708a80c5 100644 --- a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml +++ b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml @@ -78,6 +78,10 @@ Rectangle { onInventoryResult: { purchasesReceived = true; + if (root.pendingInventoryReply) { + inventoryTimer.start(); + } + if (result.status !== 'success') { console.log("Failed to get purchases", result.message); } else { @@ -98,10 +102,6 @@ Rectangle { previousPurchasesModel.append(inventoryResult); buildFilteredPurchasesModel(); - - if (root.pendingInventoryReply) { - inventoryTimer.start(); - } } root.pendingInventoryReply = false; @@ -112,7 +112,7 @@ Rectangle { id: notSetUpTimer; interval: 200; onTriggered: { - sendToScript({method: 'checkout_walletNotSetUp'}); + sendToScript({method: 'purchases_walletNotSetUp'}); } } diff --git a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml index 0bc444efb5..9beadd3361 100644 --- a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml +++ b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml @@ -176,6 +176,8 @@ Rectangle { commerce.getWalletStatus(); } else if (msg.referrer === 'purchases') { sendToScript({method: 'goToPurchases'}); + } else { + sendToScript({method: 'goToMarketplaceItemPage', itemId: msg.referrer}); } } else if (msg.method === 'walletSetup_raiseKeyboard') { root.keyboardRaised = true; diff --git a/interface/src/commerce/Wallet.cpp b/interface/src/commerce/Wallet.cpp index 34e266b32c..e80475f2cc 100644 --- a/interface/src/commerce/Wallet.cpp +++ b/interface/src/commerce/Wallet.cpp @@ -710,7 +710,7 @@ void Wallet::handleChallengeOwnershipPacket(QSharedPointer pack bool Wallet::verifyOwnerChallenge(const QByteArray& encryptedText, const QString& publicKey, QString& decryptedText) { // I have no idea how to do this yet, so here's some dummy code that may not even work. - decryptedText = QString("fail"); + decryptedText = QString("success"); return true; } diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 35c47e48c9..8f75a4bdf1 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -147,63 +147,63 @@ int EntityTree::readEntityDataFromBuffer(const unsigned char* data, int bytesLef if (bytesLeftToRead >= (int)(numberOfEntities * expectedBytesPerEntity)) { for (uint16_t i = 0; i < numberOfEntities; i++) { int bytesForThisEntity = 0; - EntityItemID entityItemID = EntityItemID::readEntityItemIDFromBuffer(dataAt, bytesLeftToRead); - EntityItemPointer entity = findEntityByEntityItemID(entityItemID); +EntityItemID entityItemID = EntityItemID::readEntityItemIDFromBuffer(dataAt, bytesLeftToRead); +EntityItemPointer entity = findEntityByEntityItemID(entityItemID); - if (entity) { - QString entityScriptBefore = entity->getScript(); - QUuid parentIDBefore = entity->getParentID(); - QString entityServerScriptsBefore = entity->getServerScripts(); - quint64 entityScriptTimestampBefore = entity->getScriptTimestamp(); +if (entity) { + QString entityScriptBefore = entity->getScript(); + QUuid parentIDBefore = entity->getParentID(); + QString entityServerScriptsBefore = entity->getServerScripts(); + quint64 entityScriptTimestampBefore = entity->getScriptTimestamp(); - bytesForThisEntity = entity->readEntityDataFromBuffer(dataAt, bytesLeftToRead, args); - if (entity->getDirtyFlags()) { - entityChanged(entity); - } - _entityMover.addEntityToMoveList(entity, entity->getQueryAACube()); + bytesForThisEntity = entity->readEntityDataFromBuffer(dataAt, bytesLeftToRead, args); + if (entity->getDirtyFlags()) { + entityChanged(entity); + } + _entityMover.addEntityToMoveList(entity, entity->getQueryAACube()); - QString entityScriptAfter = entity->getScript(); - QString entityServerScriptsAfter = entity->getServerScripts(); - quint64 entityScriptTimestampAfter = entity->getScriptTimestamp(); - bool reload = entityScriptTimestampBefore != entityScriptTimestampAfter; + QString entityScriptAfter = entity->getScript(); + QString entityServerScriptsAfter = entity->getServerScripts(); + quint64 entityScriptTimestampAfter = entity->getScriptTimestamp(); + bool reload = entityScriptTimestampBefore != entityScriptTimestampAfter; - // If the script value has changed on us, or it's timestamp has changed to force - // a reload then we want to send out a script changing signal... - if (reload || entityScriptBefore != entityScriptAfter) { - emitEntityScriptChanging(entityItemID, reload); // the entity script has changed - } - if (reload || entityServerScriptsBefore != entityServerScriptsAfter) { - emitEntityServerScriptChanging(entityItemID, reload); // the entity server script has changed - } + // If the script value has changed on us, or it's timestamp has changed to force + // a reload then we want to send out a script changing signal... + if (reload || entityScriptBefore != entityScriptAfter) { + emitEntityScriptChanging(entityItemID, reload); // the entity script has changed + } + if (reload || entityServerScriptsBefore != entityServerScriptsAfter) { + emitEntityServerScriptChanging(entityItemID, reload); // the entity server script has changed + } - QUuid parentIDAfter = entity->getParentID(); - if (parentIDBefore != parentIDAfter) { - addToNeedsParentFixupList(entity); - } - } else { - entity = EntityTypes::constructEntityItem(dataAt, bytesLeftToRead, args); - if (entity) { - bytesForThisEntity = entity->readEntityDataFromBuffer(dataAt, bytesLeftToRead, args); + QUuid parentIDAfter = entity->getParentID(); + if (parentIDBefore != parentIDAfter) { + addToNeedsParentFixupList(entity); + } +} else { + entity = EntityTypes::constructEntityItem(dataAt, bytesLeftToRead, args); + if (entity) { + bytesForThisEntity = entity->readEntityDataFromBuffer(dataAt, bytesLeftToRead, args); - // don't add if we've recently deleted.... - if (!isDeletedEntity(entityItemID)) { - _entitiesToAdd.insert(entityItemID, entity); + // don't add if we've recently deleted.... + if (!isDeletedEntity(entityItemID)) { + _entitiesToAdd.insert(entityItemID, entity); - if (entity->getCreated() == UNKNOWN_CREATED_TIME) { - entity->recordCreationTime(); - } - #ifdef WANT_DEBUG - } else { - qCDebug(entities) << "Received packet for previously deleted entity [" << - entityItemID << "] ignoring. (inside " << __FUNCTION__ << ")"; - #endif - } - } - } - // Move the buffer forward to read more entities - dataAt += bytesForThisEntity; - bytesLeftToRead -= bytesForThisEntity; - bytesRead += bytesForThisEntity; + if (entity->getCreated() == UNKNOWN_CREATED_TIME) { + entity->recordCreationTime(); + } +#ifdef WANT_DEBUG + } else { + qCDebug(entities) << "Received packet for previously deleted entity [" << + entityItemID << "] ignoring. (inside " << __FUNCTION__ << ")"; +#endif + } + } +} +// Move the buffer forward to read more entities +dataAt += bytesForThisEntity; +bytesLeftToRead -= bytesForThisEntity; +bytesRead += bytesForThisEntity; } } } @@ -214,13 +214,13 @@ int EntityTree::readEntityDataFromBuffer(const unsigned char* data, int bytesLef bool EntityTree::handlesEditPacketType(PacketType packetType) const { // we handle these types of "edit" packets switch (packetType) { - case PacketType::EntityAdd: - case PacketType::EntityEdit: - case PacketType::EntityErase: - case PacketType::EntityPhysics: - return true; - default: - return false; + case PacketType::EntityAdd: + case PacketType::EntityEdit: + case PacketType::EntityErase: + case PacketType::EntityPhysics: + return true; + default: + return false; } } @@ -241,6 +241,29 @@ void EntityTree::postAddEntity(EntityItemPointer entity) { // find and hook up any entities with this entity as a (previously) missing parent fixupNeedsParentFixups(); + + if (getIsServer()) { + QString certID(entity->getCertificateID()); + EntityItemID entityItemID = entity->getEntityItemID(); + EntityItemID existingEntityItemID; + + { + QWriteLocker locker(&_entityCertificateIDMapLock); + existingEntityItemID = _entityCertificateIDMap.value(certID); + if (!certID.isEmpty()) { + _entityCertificateIDMap.insert(certID, entityItemID); + qCDebug(entities) << "Certificate ID" << certID << "belongs to" << entityItemID; + } + } + + // Delete an already-existing entity from the tree if it has the same + // CertificateID as the entity we're trying to add. + if (!existingEntityItemID.isNull()) { + qCDebug(entities) << "Certificate ID" << certID << "already exists on entity with ID" + << existingEntityItemID << ". Deleting existing entity."; + deleteEntity(existingEntityItemID, true); + } + } } bool EntityTree::updateEntity(const EntityItemID& entityID, const EntityItemProperties& properties, const SharedNodePointer& senderNode) { @@ -654,8 +677,16 @@ void EntityTree::processRemovedEntities(const DeleteEntityOperator& theOperator) theEntity->die(); if (getIsServer()) { + { + QWriteLocker entityCertificateIDMapLocker(&_entityCertificateIDMapLock); + QString certID = theEntity->getCertificateID(); + if (theEntity->getEntityItemID() == _entityCertificateIDMap.value(certID)) { + _entityCertificateIDMap.remove(certID); + } + } + // set up the deleted entities ID - QWriteLocker locker(&_recentlyDeletedEntitiesLock); + QWriteLocker recentlyDeletedEntitiesLocker(&_recentlyDeletedEntitiesLock); _recentlyDeletedEntityItemIDs.insert(deletedAt, theEntity->getEntityItemID()); } else { // on the client side, we also remember that we deleted this entity, we don't care about the time @@ -665,9 +696,6 @@ void EntityTree::processRemovedEntities(const DeleteEntityOperator& theOperator) if (_simulation) { _simulation->prepareEntityForDelete(theEntity); } - - QWriteLocker locker(&_entityCertificateIDMapLock); - _entityCertificateIDMap.remove(theEntity->getProperties(PROP_CERTIFICATE_ID).getCertificateID()); } } @@ -1117,8 +1145,8 @@ void EntityTree::startChallengeOwnershipTimer(const EntityItemID& entityItemID) _challengeOwnershipTimeoutTimer->deleteLater(); } }); - _challengeOwnershipTimeoutTimer->setInterval(5000); - _challengeOwnershipTimeoutTimer->start(); + _challengeOwnershipTimeoutTimer->setSingleShot(true); + _challengeOwnershipTimeoutTimer->start(5000); } void EntityTree::processChallengeOwnershipPacket(ReceivedMessage& message, const SharedNodePointer& sourceNode) { @@ -1346,7 +1374,7 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c endCreate = usecTimestampNow(); _totalCreates++; - if (newEntity && isCertified) { + if (newEntity && isCertified && getIsServer()) { if (!newEntity->verifyStaticCertificateProperties()) { qCDebug(entities) << "User" << senderNode->getUUID() << "attempted to add a certified entity with ID" << entityItemID << "which failed" @@ -1357,28 +1385,6 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID); } else { QString certID = properties.getCertificateID(); - EntityItemID existingEntityItemID; - - { - QReadLocker locker(&_entityCertificateIDMapLock); - existingEntityItemID = _entityCertificateIDMap.value(certID); - } - - // Delete an already-existing entity from the tree if it has the same - // CertificateID as the entity we're trying to add. - if (!existingEntityItemID.isNull()) { - qCDebug(entities) << "Certificate ID" << certID << "already exists on entity with ID" - << existingEntityItemID << ". Deleting existing entity."; - deleteEntity(existingEntityItemID, true); - QWriteLocker locker(&_recentlyDeletedEntitiesLock); - _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), existingEntityItemID); - } - - { - QWriteLocker locker(&_entityCertificateIDMapLock); - _entityCertificateIDMap.insert(certID, entityItemID); - qCDebug(entities) << "Certificate ID" << certID << "belongs to" << entityItemID; - } // Start owner verification. auto nodeList = DependencyManager::get(); @@ -2178,7 +2184,3 @@ QStringList EntityTree::getJointNames(const QUuid& entityID) const { } return entity->getJointNames(); } - -void EntityTree::startDynamicDomainVerification() { - -} diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 85ce6a2ed5..d6a35ca2aa 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -187,6 +187,11 @@ public: return _recentlyDeletedEntityItemIDs; } + QHash getEntityCertificateIDMap() const { + QReadLocker locker(&_entityCertificateIDMapLock); + return _entityCertificateIDMap; + } + void forgetEntitiesDeletedBefore(quint64 sinceTime); int processEraseMessage(ReceivedMessage& message, const SharedNodePointer& sourceNode); @@ -369,7 +374,6 @@ protected: QHash _entitiesToAdd; Q_INVOKABLE void startChallengeOwnershipTimer(const EntityItemID& entityItemID); - void startDynamicDomainVerification(); }; #endif // hifi_EntityTree_h diff --git a/scripts/system/commerce/wallet.js b/scripts/system/commerce/wallet.js index 7553ca4eeb..04b67ec14f 100644 --- a/scripts/system/commerce/wallet.js +++ b/scripts/system/commerce/wallet.js @@ -16,6 +16,8 @@ (function () { // BEGIN LOCAL_SCOPE Script.include("/~/system/libraries/accountUtils.js"); + var MARKETPLACE_URL = "https://metaverse.highfidelity.com/marketplace"; + // Function Name: onButtonClicked() // // Description: @@ -88,6 +90,9 @@ case 'goToPurchases': tablet.pushOntoStack(MARKETPLACE_PURCHASES_QML_PATH); break; + case 'goToMarketplaceItemPage': + tablet.gotoWebScreen(MARKETPLACE_URL + '/items/' + message.itemId, MARKETPLACES_INJECT_SCRIPT_URL); + break; default: print('Unrecognized message from QML:', JSON.stringify(message)); } diff --git a/scripts/system/html/js/marketplacesInject.js b/scripts/system/html/js/marketplacesInject.js index ded4542c51..41db724c3f 100644 --- a/scripts/system/html/js/marketplacesInject.js +++ b/scripts/system/html/js/marketplacesInject.js @@ -334,7 +334,6 @@ $('body').addClass("code-injected"); maybeAddLogInButton(); - maybeAddSetupWalletButton(); changeDropdownMenu(); var purchaseButton = $('#side-info').find('.btn').first(); diff --git a/scripts/system/marketplaces/marketplaces.js b/scripts/system/marketplaces/marketplaces.js index 0bee540a9d..deeae0d299 100644 --- a/scripts/system/marketplaces/marketplaces.js +++ b/scripts/system/marketplaces/marketplaces.js @@ -289,13 +289,19 @@ openWallet(); break; case 'purchases_walletNotSetUp': - case 'checkout_walletNotSetUp': wireEventBridge(true); tablet.sendToQml({ method: 'updateWalletReferrer', referrer: "purchases" }); openWallet(); + case 'checkout_walletNotSetUp': + wireEventBridge(true); + tablet.sendToQml({ + method: 'updateWalletReferrer', + referrer: message.itemId + }); + openWallet(); break; case 'checkout_cancelClicked': tablet.gotoWebScreen(MARKETPLACE_URL + '/items/' + message.params, MARKETPLACES_INJECT_SCRIPT_URL); From c70ee6055ffc5de2b4f7d711c5f200ffeecfbbdf Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Fri, 6 Oct 2017 17:12:40 -0700 Subject: [PATCH 013/116] Don't clear cert ID if static properties change; updates to DDV --- .../src/entities/EntityServer.cpp | 60 +++++++++++-------- libraries/entities/src/EntityTree.cpp | 12 ---- 2 files changed, 34 insertions(+), 38 deletions(-) diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index 445af3ac34..0342f4acda 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -431,39 +431,47 @@ void EntityServer::startDynamicDomainVerification() { while (i.hasNext()) { i.next(); - QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); - QNetworkRequest networkRequest; - networkRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); - QUrl requestURL = NetworkingConstants::METAVERSE_SERVER_URL; - requestURL.setPath("/api/v1/commerce/proof_of_purchase_status"); - QJsonObject request; - request["certificate_id"] = i.key(); - networkRequest.setUrl(requestURL); + if (!tree->findEntityByEntityItemID(i.value())->verifyStaticCertificateProperties()) { + qCDebug(entities) << "During Dynamic Domain Verification, a certified entity with ID" << i.value() << "failed" + << "static certificate verification."; + // Delete the entity if it doesn't pass static certificate verification + tree->deleteEntity(i.value(), true); + } else { - QNetworkReply* networkReply = NULL; - networkReply = networkAccessManager.get(networkRequest); + QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); + QNetworkRequest networkRequest; + networkRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); + QUrl requestURL = NetworkingConstants::METAVERSE_SERVER_URL; + requestURL.setPath("/api/v1/commerce/proof_of_purchase_status"); + QJsonObject request; + request["certificate_id"] = i.key(); + networkRequest.setUrl(requestURL); - connect(networkReply, &QNetworkReply::finished, [=]() { - QJsonObject jsonObject = QJsonDocument::fromJson(networkReply->readAll()).object(); - QJsonDocument doc(jsonObject); - qCDebug(entities) << "ZRF FIXME" << doc.toJson(QJsonDocument::Compact); + QNetworkReply* networkReply = NULL; + networkReply = networkAccessManager.get(networkRequest); + + connect(networkReply, &QNetworkReply::finished, [=]() { + QJsonObject jsonObject = QJsonDocument::fromJson(networkReply->readAll()).object(); + QJsonDocument doc(jsonObject); + qCDebug(entities) << "ZRF FIXME" << doc.toJson(QJsonDocument::Compact); - // ZRF FIXME!!! - //if (networkReply->error() == QNetworkReply::NoError) { - if (true) { // ZRF FIXME!!! - //if (jsonObject["location"].toString() != thisDomainID) { - if (false) { - qCDebug(entities) << "invalid_reason not empty, deleting entity" << i.value(); + //if (networkReply->error() == QNetworkReply::NoError) { + if (true) { + // ZRF FIXME!!! + //if (jsonObject["location"].toString() != thisDomainID) { + if (false) { + qCDebug(entities) << "invalid_reason not empty, deleting entity" << i.value(); + tree->deleteEntity(i.value(), true); + } + } else { + qCDebug(entities) << "Call to proof_of_purchase_status endpoint failed; deleting entity" << i.value(); tree->deleteEntity(i.value(), true); } - } else { - qCDebug(entities) << "Call to proof_of_purchase_status endpoint failed; deleting entity" << i.value(); - tree->deleteEntity(i.value(), true); - } - networkReply->deleteLater(); - }); + networkReply->deleteLater(); + }); + } } int nextInterval = qrand() % ((MAXIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS + 1) - MINIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS) + MINIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS; diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 8f75a4bdf1..56a92fb20c 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -382,18 +382,6 @@ bool EntityTree::updateEntity(EntityItemPointer entity, const EntityItemProperti qCDebug(entities) << (senderNode ? senderNode->getUUID() : "null") << "physical edits suppressed"; } } - - // Clear Certificate ID if any static certificate property is changed - if (properties.itemNameChanged() || properties.itemDescriptionChanged() || properties.itemCategoriesChanged() || - properties.itemArtistChanged() || properties.itemLicenseChanged() || properties.limitedRunChanged() || - properties.editionNumberChanged() || properties.entityInstanceNumberChanged() || properties.certificateIDChanged()) { - qCDebug(entities) << "A static certificate property on Entity" << entity->getID() << "has changed." - << "Clearing Certificate ID."; - QWriteLocker locker(&_entityCertificateIDMapLock); - _entityCertificateIDMap.remove(entity->getCertificateID()); - properties.setCertificateID(""); - properties.setCertificateIDChanged(true); - } } // else client accepts what the server says From 988d8a1a62811a48652ce1eaa137dba69e2f15c8 Mon Sep 17 00:00:00 2001 From: samcake Date: Fri, 6 Oct 2017 18:17:48 -0700 Subject: [PATCH 014/116] TRying to debug the overlay notifications to show ?) --- interface/src/ui/overlays/Billboard3DOverlay.cpp | 8 ++++++++ interface/src/ui/overlays/Billboard3DOverlay.h | 2 ++ 2 files changed, 10 insertions(+) diff --git a/interface/src/ui/overlays/Billboard3DOverlay.cpp b/interface/src/ui/overlays/Billboard3DOverlay.cpp index 960f0de095..f19426b054 100644 --- a/interface/src/ui/overlays/Billboard3DOverlay.cpp +++ b/interface/src/ui/overlays/Billboard3DOverlay.cpp @@ -37,6 +37,14 @@ QVariant Billboard3DOverlay::getProperty(const QString &property) { return Planar3DOverlay::getProperty(property); } +void Billboard3DOverlay::update(float duration) { + // Billboard's transform needs to constantly be adjusted if it faces the avatar + // if (isFacingAvatar()) { + notifyRenderTransformChange(); + // } + Base3DOverlay::update(duration); +} + bool Billboard3DOverlay::applyTransformTo(Transform& transform, bool force) { bool transformChanged = false; if (force || usecTimestampNow() > _transformExpiry) { diff --git a/interface/src/ui/overlays/Billboard3DOverlay.h b/interface/src/ui/overlays/Billboard3DOverlay.h index 6b3aa40451..6f590dd6ec 100644 --- a/interface/src/ui/overlays/Billboard3DOverlay.h +++ b/interface/src/ui/overlays/Billboard3DOverlay.h @@ -26,6 +26,8 @@ public: void setProperties(const QVariantMap& properties) override; QVariant getProperty(const QString& property) override; + void update(float deltatime) override; + protected: virtual bool applyTransformTo(Transform& transform, bool force = false) override; From 8d887caa5d00bab566d60a521366b6fe3715a456 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Mon, 9 Oct 2017 11:37:02 -0700 Subject: [PATCH 015/116] Make min and max dynamic verification times server settings --- .../src/entities/EntityServer.cpp | 26 +++++++++++++++++-- assignment-client/src/entities/EntityServer.h | 9 ++++--- .../resources/describe-settings.json | 16 ++++++++++++ 3 files changed, 45 insertions(+), 6 deletions(-) diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index 0342f4acda..f275c5c44a 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -98,7 +98,8 @@ void EntityServer::beforeRun() { const int PRUNE_DELETED_MODELS_INTERVAL_MSECS = 1 * 1000; // once every second _pruneDeletedEntitiesTimer->start(PRUNE_DELETED_MODELS_INTERVAL_MSECS); - startDynamicDomainVerification(); + DomainHandler& domainHandler = DependencyManager::get()->getDomainHandler(); + connect(&domainHandler, &DomainHandler::settingsReceiveFail, this, &EntityServer::domainSettingsRequestFailed); } void EntityServer::entityCreated(const EntityItem& newEntity, const SharedNodePointer& senderNode) { @@ -302,6 +303,18 @@ void EntityServer::readAdditionalConfiguration(const QJsonObject& settingsSectio tree->setEntityMaxTmpLifetime(EntityTree::DEFAULT_MAX_TMP_ENTITY_LIFETIME); } + int minTime; + if (readOptionInt("dynamicDomainVerificationTimeMin", settingsSectionObject, minTime)) { + _MINIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS = minTime * 1000; + } + + int maxTime; + if (readOptionInt("dynamicDomainVerificationTimeMax", settingsSectionObject, maxTime)) { + _MAXIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS = maxTime * 1000; + } + + startDynamicDomainVerification(); + tree->setWantEditLogging(wantEditLogging); tree->setWantTerseEditLogging(wantTerseEditLogging); @@ -417,6 +430,15 @@ QString EntityServer::serverSubclassStats() { return statsString; } +void EntityServer::domainSettingsRequestFailed() { + auto nodeList = DependencyManager::get(); + qCDebug(entities) << "The EntityServer couldn't get the Domain Settings. Starting dynamic domain verification with default values..."; + + _MINIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS = DEFAULT_MINIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS; + _MAXIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS = DEFAULT_MAXIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS; + startDynamicDomainVerification(); +} + void EntityServer::startDynamicDomainVerification() { qCDebug(entities) << "Starting Dynamic Domain Verification..."; @@ -474,7 +496,7 @@ void EntityServer::startDynamicDomainVerification() { } } - int nextInterval = qrand() % ((MAXIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS + 1) - MINIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS) + MINIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS; + int nextInterval = qrand() % ((_MAXIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS + 1) - _MINIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS) + _MINIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS; qCDebug(entities) << "Restarting Dynamic Domain Verification timer for" << nextInterval / 1000 << "seconds"; _dynamicDomainVerificationTimer.start(nextInterval); } diff --git a/assignment-client/src/entities/EntityServer.h b/assignment-client/src/entities/EntityServer.h index 39d15f726e..5cebd9b751 100644 --- a/assignment-client/src/entities/EntityServer.h +++ b/assignment-client/src/entities/EntityServer.h @@ -73,6 +73,7 @@ protected: private slots: void handleEntityPacket(QSharedPointer message, SharedNodePointer senderNode); + void domainSettingsRequestFailed(); private: SimpleEntitySimulationPointer _entitySimulation; @@ -81,10 +82,10 @@ private: QReadWriteLock _viewerSendingStatsLock; QMap> _viewerSendingStats; - //static const int MINIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS = 45 * 60 * 1000; // 45m - //static const int MAXIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS = 75 * 60 * 1000; // 1h15m - static const int MINIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS = 5 * 1000; // 5s - static const int MAXIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS = 10 * 1000; // 10s + static const int DEFAULT_MINIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS = 45 * 60 * 1000; // 45m + static const int DEFAULT_MAXIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS = 75 * 60 * 1000; // 1h15m + int _MINIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS = DEFAULT_MINIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS; // 45m + int _MAXIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS = DEFAULT_MAXIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS; // 1h15m QTimer _dynamicDomainVerificationTimer; void startDynamicDomainVerification(); }; diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index f1180e00c2..2b0d032e3c 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -1254,6 +1254,22 @@ "default": "3600", "advanced": true }, + { + "name": "dynamicDomainVerificationTimeMin", + "label": "Dynamic Domain Verification Time (seconds) - Minimum", + "help": "The lower limit on the amount of time that passes before Dynamic Domain Verification on entities occurs. Units are seconds.", + "placeholder": "2700", + "default": "2700", + "advanced": true + }, + { + "name": "dynamicDomainVerificationTimeMax", + "label": "Dynamic Domain Verification Time (seconds) - Maximum", + "help": "The upper limit on the amount of time that passes before Dynamic Domain Verification on entities occurs. Units are seconds.", + "placeholder": "4500", + "default": "4500", + "advanced": true + }, { "name": "entityScriptSourceWhitelist", "label": "Entity Scripts Allowed from:", From 1f8b68c952790b6b4f38ffee167d055a0f91e1b6 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 11 Oct 2017 11:46:35 -0700 Subject: [PATCH 016/116] Updates now that endpoint exists; add pending timer --- libraries/entities/src/EntityTree.cpp | 186 ++++++++++++++------------ libraries/entities/src/EntityTree.h | 4 + 2 files changed, 108 insertions(+), 82 deletions(-) diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index b8293a117d..7960322383 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1143,6 +1143,109 @@ void EntityTree::startChallengeOwnershipTimer(const EntityItemID& entityItemID) _challengeOwnershipTimeoutTimer->start(5000); } +void EntityTree::startPendingTransferStatusTimer(const QString& certID, const EntityItemID& entityItemID, const SharedNodePointer& senderNode) { + qCDebug(entities) << "'transfer_status' is 'pending', checking again in 10 seconds..." << entityItemID; + QTimer* transferStatusRetryTimer = new QTimer(this); + connect(transferStatusRetryTimer, &QTimer::timeout, this, [=]() { + validatePop(certID, entityItemID, senderNode, true); + }); + transferStatusRetryTimer->setSingleShot(true); + transferStatusRetryTimer->start(10000); +} + +void EntityTree::validatePop(const QString& certID, const EntityItemID& entityItemID, const SharedNodePointer& senderNode, bool isRetryingValidation) { + // Start owner verification. + auto nodeList = DependencyManager::get(); + // First, asynchronously hit "proof_of_purchase_status?transaction_type=transfer" endpoint. + QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); + QNetworkRequest networkRequest; + networkRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); + networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); + QUrl requestURL = NetworkingConstants::METAVERSE_SERVER_URL; + requestURL.setPath("/api/v1/commerce/proof_of_purchase_status/transfer"); + QJsonObject request; + request["certificate_id"] = certID; + networkRequest.setUrl(requestURL); + + QNetworkReply* networkReply = NULL; + networkReply = networkAccessManager.put(networkRequest, QJsonDocument(request).toJson()); + + connect(networkReply, &QNetworkReply::finished, [=]() { + QJsonObject jsonObject = QJsonDocument::fromJson(networkReply->readAll()).object(); + QJsonDocument doc(jsonObject); + qCDebug(entities) << "ZRF FIXME" << doc.toJson(QJsonDocument::Compact); + + if (networkReply->error() == QNetworkReply::NoError) { + if (!jsonObject["invalid_reason"].toString().isEmpty()) { + qCDebug(entities) << "invalid_reason not empty, deleting entity" << entityItemID; + deleteEntity(entityItemID, true); + QWriteLocker locker(&_recentlyDeletedEntitiesLock); + _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID); + } else if (jsonObject["transfer_status"].toString() == "failed") { + qCDebug(entities) << "'transfer_status' is 'failed', deleting entity" << entityItemID; + deleteEntity(entityItemID, true); + QWriteLocker locker(&_recentlyDeletedEntitiesLock); + _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID); + } else if (jsonObject["transfer_status"].toString() == "pending") { + if (isRetryingValidation) { + qCDebug(entities) << "'transfer_status' is 'pending' after retry, deleting entity" << entityItemID; + deleteEntity(entityItemID, true); + QWriteLocker locker(&_recentlyDeletedEntitiesLock); + _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID); + } else { + if (thread() != QThread::currentThread()) { + QMetaObject::invokeMethod(this, "startPendingTransferStatusTimer", + Q_ARG(const QString&, certID), + Q_ARG(const EntityItemID&, entityItemID), + Q_ARG(const SharedNodePointer&, senderNode)); + return; + } else { + startPendingTransferStatusTimer(certID, entityItemID, senderNode); + } + } + } else { + // Second, challenge ownership of the PoP cert + // 1. Encrypt a nonce with the owner's public key + QString ownerKey(jsonObject["owner_public_key"].toString()); + QString encryptedText("test"); + + // 2. Send the encrypted text to the rezzing avatar's node + QByteArray certIDByteArray = certID.toUtf8(); + int certIDByteArraySize = certIDByteArray.size(); + QByteArray encryptedTextByteArray = encryptedText.toUtf8(); + int encryptedTextByteArraySize = encryptedTextByteArray.size(); + QByteArray ownerKeyByteArray = ownerKey.toUtf8(); + int ownerKeyByteArraySize = ownerKeyByteArray.size(); + auto challengeOwnershipPacket = NLPacket::create(PacketType::ChallengeOwnership, + certIDByteArraySize + encryptedTextByteArraySize + ownerKeyByteArraySize + 3 * sizeof(int), + true); + challengeOwnershipPacket->writePrimitive(certIDByteArraySize); + challengeOwnershipPacket->writePrimitive(encryptedTextByteArraySize); + challengeOwnershipPacket->writePrimitive(ownerKeyByteArraySize); + challengeOwnershipPacket->write(certIDByteArray); + challengeOwnershipPacket->write(encryptedTextByteArray); + challengeOwnershipPacket->write(ownerKeyByteArray); + nodeList->sendPacket(std::move(challengeOwnershipPacket), *senderNode); + + // 3. Kickoff a 10-second timeout timer that deletes the entity if we don't get an ownership response in time + if (thread() != QThread::currentThread()) { + QMetaObject::invokeMethod(this, "startChallengeOwnershipTimer", Q_ARG(const EntityItemID&, entityItemID)); + return; + } else { + startChallengeOwnershipTimer(entityItemID); + } + } + } else { + qCDebug(entities) << "Call to proof_of_purchase_status endpoint failed; deleting entity" << entityItemID; + deleteEntity(entityItemID, true); + QWriteLocker locker(&_recentlyDeletedEntitiesLock); + _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID); + } + + networkReply->deleteLater(); + }); +} + void EntityTree::processChallengeOwnershipPacket(ReceivedMessage& message, const SharedNodePointer& sourceNode) { int certIDByteArraySize; int decryptedTextByteArraySize; @@ -1378,88 +1481,7 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c QWriteLocker locker(&_recentlyDeletedEntitiesLock); _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID); } else { - QString certID = properties.getCertificateID(); - - // Start owner verification. - auto nodeList = DependencyManager::get(); - // First, asynchronously hit "proof_of_purchase_status?transaction_type=transfer" endpoint. - QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); - QNetworkRequest networkRequest; - networkRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); - QUrl requestURL = NetworkingConstants::METAVERSE_SERVER_URL; - requestURL.setPath("/api/v1/commerce/proof_of_purchase_status?transaction_type=transfer"); - QJsonObject request; - request["certificate_id"] = certID; - request["domain_id"] = nodeList->getDomainHandler().getUUID().toString(); - networkRequest.setUrl(requestURL); - - QNetworkReply* networkReply = NULL; - networkReply = networkAccessManager.get(networkRequest); - - connect(networkReply, &QNetworkReply::finished, [=]() { - QJsonObject jsonObject = QJsonDocument::fromJson(networkReply->readAll()).object(); - QJsonDocument doc(jsonObject); - qCDebug(entities) << "ZRF FIXME" << doc.toJson(QJsonDocument::Compact); - - // ZRF FIXME!!! - //if (networkReply->error() == QNetworkReply::NoError) { - if (true) { - // ZRF FIXME!!! - //if (!jsonObject["invalid_reason"].toString().isEmpty()) { - if (false) { - qCDebug(entities) << "invalid_reason not empty, deleting entity" << entityItemID; - deleteEntity(entityItemID, true); - QWriteLocker locker(&_recentlyDeletedEntitiesLock); - _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID); - // ZRF FIXME!!! - //} else if (jsonObject["transfer_status"].toString() == "failed") { - } else if (false) { - qCDebug(entities) << "'transfer_status' is 'failed', deleting entity" << entityItemID; - deleteEntity(entityItemID, true); - QWriteLocker locker(&_recentlyDeletedEntitiesLock); - _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID); - // ZRF FIXME!!! - } else { - // Second, challenge ownership of the PoP cert - // 1. Encrypt a nonce with the owner's public key - QString ownerKey(jsonObject["owner_public_key"].toString()); - QString encryptedText("test"); - - // 2. Send the encrypted text to the rezzing avatar's node - QByteArray certIDByteArray = certID.toUtf8(); - int certIDByteArraySize = certIDByteArray.size(); - QByteArray encryptedTextByteArray = encryptedText.toUtf8(); - int encryptedTextByteArraySize = encryptedTextByteArray.size(); - QByteArray ownerKeyByteArray = ownerKey.toUtf8(); - int ownerKeyByteArraySize = ownerKeyByteArray.size(); - auto challengeOwnershipPacket = NLPacket::create(PacketType::ChallengeOwnership, - certIDByteArraySize + encryptedTextByteArraySize + ownerKeyByteArraySize + 3*sizeof(int), - true); - challengeOwnershipPacket->writePrimitive(certIDByteArraySize); - challengeOwnershipPacket->writePrimitive(encryptedTextByteArraySize); - challengeOwnershipPacket->writePrimitive(ownerKeyByteArraySize); - challengeOwnershipPacket->write(certIDByteArray); - challengeOwnershipPacket->write(encryptedTextByteArray); - challengeOwnershipPacket->write(ownerKeyByteArray); - nodeList->sendPacket(std::move(challengeOwnershipPacket), *senderNode); - - // 3. Kickoff a 10-second timeout timer that deletes the entity if we don't get an ownership response in time - if (thread() != QThread::currentThread()) { - QMetaObject::invokeMethod(this, "startChallengeOwnershipTimer", Q_ARG(const EntityItemID&, entityItemID)); - return; - } else { - startChallengeOwnershipTimer(entityItemID); - } - } - } else { - qCDebug(entities) << "Call to proof_of_purchase_status endpoint failed; deleting entity" << entityItemID; - deleteEntity(entityItemID, true); - QWriteLocker locker(&_recentlyDeletedEntitiesLock); - _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID); - } - - networkReply->deleteLater(); - }); + validatePop(properties.getCertificateID(), entityItemID, senderNode, false); } } diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 693c8c5b56..4a773f7a15 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -379,6 +379,10 @@ protected: QHash _entitiesToAdd; Q_INVOKABLE void startChallengeOwnershipTimer(const EntityItemID& entityItemID); + Q_INVOKABLE void startPendingTransferStatusTimer(const QString& certID, const EntityItemID& entityItemID, const SharedNodePointer& senderNode); + +private: + void validatePop(const QString& certID, const EntityItemID& entityItemID, const SharedNodePointer& senderNode, bool isRetryingValidation); }; #endif // hifi_EntityTree_h From f05c70969333e577c5b2dc3502e54d869ac8a766 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 11 Oct 2017 12:06:11 -0700 Subject: [PATCH 017/116] Remove static certificate verification for now --- assignment-client/src/entities/EntityServer.cpp | 4 +++- libraries/entities/src/EntityTree.cpp | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index f275c5c44a..539a082911 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -453,7 +453,9 @@ void EntityServer::startDynamicDomainVerification() { while (i.hasNext()) { i.next(); - if (!tree->findEntityByEntityItemID(i.value())->verifyStaticCertificateProperties()) { + // ZRF FIXME!!! + //if (!tree->findEntityByEntityItemID(i.value())->verifyStaticCertificateProperties()) { + if (false) { qCDebug(entities) << "During Dynamic Domain Verification, a certified entity with ID" << i.value() << "failed" << "static certificate verification."; // Delete the entity if it doesn't pass static certificate verification diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 7960322383..a479c04459 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1472,7 +1472,9 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c _totalCreates++; if (newEntity && isCertified && getIsServer()) { - if (!newEntity->verifyStaticCertificateProperties()) { + // ZRF FIXME!!! + //if (!newEntity->verifyStaticCertificateProperties()) { + if (false) { qCDebug(entities) << "User" << senderNode->getUUID() << "attempted to add a certified entity with ID" << entityItemID << "which failed" << "static certificate verification."; From 9e570fdba3c76b0eda6ff91758afed890d47e648 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 11 Oct 2017 13:05:46 -0700 Subject: [PATCH 018/116] First pass at encryption/decryption. Exciting! --- interface/src/commerce/Wallet.cpp | 21 +++--- interface/src/commerce/Wallet.h | 2 - libraries/entities/src/EntityTree.cpp | 102 +++++++++++++++++++------- libraries/entities/src/EntityTree.h | 5 ++ 4 files changed, 91 insertions(+), 39 deletions(-) diff --git a/interface/src/commerce/Wallet.cpp b/interface/src/commerce/Wallet.cpp index dd926d00d4..702a94625a 100644 --- a/interface/src/commerce/Wallet.cpp +++ b/interface/src/commerce/Wallet.cpp @@ -718,15 +718,22 @@ void Wallet::handleChallengeOwnershipPacket(QSharedPointer pack QString decryptedText; int certIDByteArraySize; int encryptedTextByteArraySize; - int ownerKeyByteArraySize; packet->readPrimitive(&certIDByteArraySize); packet->readPrimitive(&encryptedTextByteArraySize); - packet->readPrimitive(&ownerKeyByteArraySize); QByteArray certID = packet->read(certIDByteArraySize); + QByteArray encryptedText = packet->read(encryptedTextByteArraySize); - if (verifyOwnerChallenge(packet->read(encryptedTextByteArraySize), packet->read(ownerKeyByteArraySize), decryptedText)) { + const auto text = reinterpret_cast(encryptedText.constData()); + const unsigned int textLength = encryptedText.length(); + + RSA* rsa = readKeys(keyFilePath().toStdString().c_str()); + + const int decryptionStatus = RSA_private_decrypt(textLength, text, reinterpret_cast(encryptedText.data()), rsa, RSA_PKCS1_OAEP_PADDING); + RSA_free(rsa); + + if (decryptionStatus != -1) { auto nodeList = DependencyManager::get(); QByteArray decryptedTextByteArray = decryptedText.toUtf8(); @@ -744,16 +751,10 @@ void Wallet::handleChallengeOwnershipPacket(QSharedPointer pack nodeList->sendPacket(std::move(decryptedTextPacket), *sendingNode); } else { - qCDebug(commerce) << "verifyOwnerChallenge() returned false"; + qCDebug(commerce) << "During entity ownership challenge, decrypting the encrypted text failed."; } } -bool Wallet::verifyOwnerChallenge(const QByteArray& encryptedText, const QString& publicKey, QString& decryptedText) { - // I have no idea how to do this yet, so here's some dummy code that may not even work. - decryptedText = QString("success"); - return true; -} - void Wallet::account() { auto ledger = DependencyManager::get(); ledger->account(); diff --git a/interface/src/commerce/Wallet.h b/interface/src/commerce/Wallet.h index 38c5299810..16d23c1e5b 100644 --- a/interface/src/commerce/Wallet.h +++ b/interface/src/commerce/Wallet.h @@ -81,8 +81,6 @@ private: bool writeSecurityImage(const QPixmap* pixmap, const QString& outputFilePath); bool readSecurityImage(const QString& inputFilePath, unsigned char** outputBufferPtr, int* outputBufferLen); - bool verifyOwnerChallenge(const QByteArray& encryptedText, const QString& publicKey, QString& decryptedText); - void account(); }; diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index a479c04459..2a8e3e575a 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -13,6 +13,10 @@ #include #include +#include +#include +#include + #include #include @@ -1144,13 +1148,49 @@ void EntityTree::startChallengeOwnershipTimer(const EntityItemID& entityItemID) } void EntityTree::startPendingTransferStatusTimer(const QString& certID, const EntityItemID& entityItemID, const SharedNodePointer& senderNode) { - qCDebug(entities) << "'transfer_status' is 'pending', checking again in 10 seconds..." << entityItemID; + qCDebug(entities) << "'transfer_status' is 'pending', checking again in 90 seconds..." << entityItemID; QTimer* transferStatusRetryTimer = new QTimer(this); connect(transferStatusRetryTimer, &QTimer::timeout, this, [=]() { validatePop(certID, entityItemID, senderNode, true); }); transferStatusRetryTimer->setSingleShot(true); - transferStatusRetryTimer->start(10000); + transferStatusRetryTimer->start(90000); +} + +QString EntityTree::computeEncryptedNonce(const QString& certID, const QString& ownerKey) { + QUuid nonce = QUuid::createUuid(); + const auto text = reinterpret_cast(qPrintable(nonce.toString())); + const unsigned int textLength = nonce.toString().length(); + + const auto publicKey = reinterpret_cast(ownerKey.toUtf8().toBase64().constData()); + BIO* bio = BIO_new_mem_buf((void*)publicKey, sizeof(publicKey)); + RSA* rsa = PEM_read_bio_RSAPublicKey(bio, NULL, NULL, NULL); + + QByteArray encryptedText(RSA_size(rsa), 0); + const int encryptStatus = RSA_public_encrypt(textLength, text, reinterpret_cast(encryptedText.data()), rsa, RSA_PKCS1_OAEP_PADDING); + BIO_free(bio); + RSA_free(rsa); + if (encryptStatus == -1) { + qCWarning(entities) << "Unable to compute encrypted nonce for" << certID; + return ""; + } + + { + QWriteLocker locker(&_certNonceMapLock); + _certNonceMap.insert(certID, nonce); + } + + return encryptedText.toBase64(); +} + +bool EntityTree::verifyDecryptedNonce(const QString& certID, const QString& decryptedNonce) { + QString actualNonce; + { + QWriteLocker locker(&_certNonceMapLock); + actualNonce = _certNonceMap.take(certID).toString(); + } + + return actualNonce == decryptedNonce; } void EntityTree::validatePop(const QString& certID, const EntityItemID& entityItemID, const SharedNodePointer& senderNode, bool isRetryingValidation) { @@ -1172,6 +1212,9 @@ void EntityTree::validatePop(const QString& certID, const EntityItemID& entityIt connect(networkReply, &QNetworkReply::finished, [=]() { QJsonObject jsonObject = QJsonDocument::fromJson(networkReply->readAll()).object(); + jsonObject = jsonObject["data"].toObject(); + + // ZRF FIXME Remove these two lines QJsonDocument doc(jsonObject); qCDebug(entities) << "ZRF FIXME" << doc.toJson(QJsonDocument::Compact); @@ -1207,32 +1250,37 @@ void EntityTree::validatePop(const QString& certID, const EntityItemID& entityIt // Second, challenge ownership of the PoP cert // 1. Encrypt a nonce with the owner's public key QString ownerKey(jsonObject["owner_public_key"].toString()); - QString encryptedText("test"); + QString encryptedText = computeEncryptedNonce(certID, ownerKey); - // 2. Send the encrypted text to the rezzing avatar's node - QByteArray certIDByteArray = certID.toUtf8(); - int certIDByteArraySize = certIDByteArray.size(); - QByteArray encryptedTextByteArray = encryptedText.toUtf8(); - int encryptedTextByteArraySize = encryptedTextByteArray.size(); - QByteArray ownerKeyByteArray = ownerKey.toUtf8(); - int ownerKeyByteArraySize = ownerKeyByteArray.size(); - auto challengeOwnershipPacket = NLPacket::create(PacketType::ChallengeOwnership, - certIDByteArraySize + encryptedTextByteArraySize + ownerKeyByteArraySize + 3 * sizeof(int), - true); - challengeOwnershipPacket->writePrimitive(certIDByteArraySize); - challengeOwnershipPacket->writePrimitive(encryptedTextByteArraySize); - challengeOwnershipPacket->writePrimitive(ownerKeyByteArraySize); - challengeOwnershipPacket->write(certIDByteArray); - challengeOwnershipPacket->write(encryptedTextByteArray); - challengeOwnershipPacket->write(ownerKeyByteArray); - nodeList->sendPacket(std::move(challengeOwnershipPacket), *senderNode); - - // 3. Kickoff a 10-second timeout timer that deletes the entity if we don't get an ownership response in time - if (thread() != QThread::currentThread()) { - QMetaObject::invokeMethod(this, "startChallengeOwnershipTimer", Q_ARG(const EntityItemID&, entityItemID)); - return; + if (encryptedText == "") { + qCDebug(entities) << "CRITICAL ERROR: Couldn't compute encrypted nonce. Deleting entity..."; + deleteEntity(entityItemID, true); + QWriteLocker locker(&_recentlyDeletedEntitiesLock); + _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID); } else { - startChallengeOwnershipTimer(entityItemID); + // 2. Send the encrypted text to the rezzing avatar's node + QByteArray certIDByteArray = certID.toUtf8(); + int certIDByteArraySize = certIDByteArray.size(); + QByteArray encryptedTextByteArray = encryptedText.toUtf8(); + int encryptedTextByteArraySize = encryptedTextByteArray.size(); + QByteArray ownerKeyByteArray = ownerKey.toUtf8(); + int ownerKeyByteArraySize = ownerKeyByteArray.size(); + auto challengeOwnershipPacket = NLPacket::create(PacketType::ChallengeOwnership, + certIDByteArraySize + encryptedTextByteArraySize + 2 * sizeof(int), + true); + challengeOwnershipPacket->writePrimitive(certIDByteArraySize); + challengeOwnershipPacket->writePrimitive(encryptedTextByteArraySize); + challengeOwnershipPacket->write(certIDByteArray); + challengeOwnershipPacket->write(encryptedTextByteArray); + nodeList->sendPacket(std::move(challengeOwnershipPacket), *senderNode); + + // 3. Kickoff a 10-second timeout timer that deletes the entity if we don't get an ownership response in time + if (thread() != QThread::currentThread()) { + QMetaObject::invokeMethod(this, "startChallengeOwnershipTimer", Q_ARG(const EntityItemID&, entityItemID)); + return; + } else { + startChallengeOwnershipTimer(entityItemID); + } } } } else { @@ -1260,7 +1308,7 @@ void EntityTree::processChallengeOwnershipPacket(ReceivedMessage& message, const emit killChallengeOwnershipTimeoutTimer(certID); - if (decryptedText == "fail") { + if (!verifyDecryptedNonce(certID, decryptedText)) { EntityItemID id; { QReadLocker certIdMapLocker(&_entityCertificateIDMapLock); diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 4a773f7a15..fc6a913ffe 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -336,6 +336,9 @@ protected: mutable QReadWriteLock _entityCertificateIDMapLock; QHash _entityCertificateIDMap; + mutable QReadWriteLock _certNonceMapLock; + QHash _certNonceMap; + EntitySimulationPointer _simulation; bool _wantEditLogging = false; @@ -382,6 +385,8 @@ protected: Q_INVOKABLE void startPendingTransferStatusTimer(const QString& certID, const EntityItemID& entityItemID, const SharedNodePointer& senderNode); private: + QString computeEncryptedNonce(const QString& certID, const QString& ownerKey); + bool verifyDecryptedNonce(const QString& certID, const QString& decryptedNonce); void validatePop(const QString& certID, const EntityItemID& entityItemID, const SharedNodePointer& senderNode, bool isRetryingValidation); }; From 1aaf1a19cdba36c972746c6ab2756cf4004193df Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 11 Oct 2017 13:20:17 -0700 Subject: [PATCH 019/116] Quick fix for printing --- assignment-client/src/entities/EntityServer.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index 539a082911..4a4315dd34 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -465,17 +465,21 @@ void EntityServer::startDynamicDomainVerification() { QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); QNetworkRequest networkRequest; networkRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); + networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); QUrl requestURL = NetworkingConstants::METAVERSE_SERVER_URL; - requestURL.setPath("/api/v1/commerce/proof_of_purchase_status"); + requestURL.setPath("/api/v1/commerce/proof_of_purchase_status/transfer"); QJsonObject request; request["certificate_id"] = i.key(); networkRequest.setUrl(requestURL); QNetworkReply* networkReply = NULL; - networkReply = networkAccessManager.get(networkRequest); + networkReply = networkAccessManager.put(networkRequest, QJsonDocument(request).toJson()); connect(networkReply, &QNetworkReply::finished, [=]() { QJsonObject jsonObject = QJsonDocument::fromJson(networkReply->readAll()).object(); + jsonObject = jsonObject["data"].toObject(); + + // ZRF FIXME Remove these two lines QJsonDocument doc(jsonObject); qCDebug(entities) << "ZRF FIXME" << doc.toJson(QJsonDocument::Compact); From d8b84e687533150f6d1f6e5af93e57ebbfca725c Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 11 Oct 2017 13:26:32 -0700 Subject: [PATCH 020/116] Minor cleanup --- assignment-client/src/entities/EntityServer.cpp | 4 +--- libraries/entities/src/EntityTree.cpp | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index 4a4315dd34..1dc1eef593 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -483,9 +483,7 @@ void EntityServer::startDynamicDomainVerification() { QJsonDocument doc(jsonObject); qCDebug(entities) << "ZRF FIXME" << doc.toJson(QJsonDocument::Compact); - // ZRF FIXME!!! - //if (networkReply->error() == QNetworkReply::NoError) { - if (true) { + if (networkReply->error() == QNetworkReply::NoError) { // ZRF FIXME!!! //if (jsonObject["location"].toString() != thisDomainID) { if (false) { diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 2a8e3e575a..b4eef7ebcc 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1249,7 +1249,7 @@ void EntityTree::validatePop(const QString& certID, const EntityItemID& entityIt } else { // Second, challenge ownership of the PoP cert // 1. Encrypt a nonce with the owner's public key - QString ownerKey(jsonObject["owner_public_key"].toString()); + QString ownerKey(jsonObject["transfer_recipient_key"].toString()); QString encryptedText = computeEncryptedNonce(certID, ownerKey); if (encryptedText == "") { From fa1bfe0d19597de88392cdcb02d11059772a109e Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 11 Oct 2017 14:10:33 -0700 Subject: [PATCH 021/116] Maybe fixes? --- libraries/entities/src/EntityTree.cpp | 145 +++++++++++++------------- 1 file changed, 74 insertions(+), 71 deletions(-) diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index b4eef7ebcc..a68e36b7ed 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -151,63 +151,63 @@ int EntityTree::readEntityDataFromBuffer(const unsigned char* data, int bytesLef if (bytesLeftToRead >= (int)(numberOfEntities * expectedBytesPerEntity)) { for (uint16_t i = 0; i < numberOfEntities; i++) { int bytesForThisEntity = 0; -EntityItemID entityItemID = EntityItemID::readEntityItemIDFromBuffer(dataAt, bytesLeftToRead); -EntityItemPointer entity = findEntityByEntityItemID(entityItemID); + EntityItemID entityItemID = EntityItemID::readEntityItemIDFromBuffer(dataAt, bytesLeftToRead); + EntityItemPointer entity = findEntityByEntityItemID(entityItemID); -if (entity) { - QString entityScriptBefore = entity->getScript(); - QUuid parentIDBefore = entity->getParentID(); - QString entityServerScriptsBefore = entity->getServerScripts(); - quint64 entityScriptTimestampBefore = entity->getScriptTimestamp(); + if (entity) { + QString entityScriptBefore = entity->getScript(); + QUuid parentIDBefore = entity->getParentID(); + QString entityServerScriptsBefore = entity->getServerScripts(); + quint64 entityScriptTimestampBefore = entity->getScriptTimestamp(); - bytesForThisEntity = entity->readEntityDataFromBuffer(dataAt, bytesLeftToRead, args); - if (entity->getDirtyFlags()) { - entityChanged(entity); - } - _entityMover.addEntityToMoveList(entity, entity->getQueryAACube()); + bytesForThisEntity = entity->readEntityDataFromBuffer(dataAt, bytesLeftToRead, args); + if (entity->getDirtyFlags()) { + entityChanged(entity); + } + _entityMover.addEntityToMoveList(entity, entity->getQueryAACube()); - QString entityScriptAfter = entity->getScript(); - QString entityServerScriptsAfter = entity->getServerScripts(); - quint64 entityScriptTimestampAfter = entity->getScriptTimestamp(); - bool reload = entityScriptTimestampBefore != entityScriptTimestampAfter; + QString entityScriptAfter = entity->getScript(); + QString entityServerScriptsAfter = entity->getServerScripts(); + quint64 entityScriptTimestampAfter = entity->getScriptTimestamp(); + bool reload = entityScriptTimestampBefore != entityScriptTimestampAfter; - // If the script value has changed on us, or it's timestamp has changed to force - // a reload then we want to send out a script changing signal... - if (reload || entityScriptBefore != entityScriptAfter) { - emitEntityScriptChanging(entityItemID, reload); // the entity script has changed - } - if (reload || entityServerScriptsBefore != entityServerScriptsAfter) { - emitEntityServerScriptChanging(entityItemID, reload); // the entity server script has changed - } + // If the script value has changed on us, or it's timestamp has changed to force + // a reload then we want to send out a script changing signal... + if (reload || entityScriptBefore != entityScriptAfter) { + emitEntityScriptChanging(entityItemID, reload); // the entity script has changed + } + if (reload || entityServerScriptsBefore != entityServerScriptsAfter) { + emitEntityServerScriptChanging(entityItemID, reload); // the entity server script has changed + } - QUuid parentIDAfter = entity->getParentID(); - if (parentIDBefore != parentIDAfter) { - addToNeedsParentFixupList(entity); - } -} else { - entity = EntityTypes::constructEntityItem(dataAt, bytesLeftToRead, args); - if (entity) { - bytesForThisEntity = entity->readEntityDataFromBuffer(dataAt, bytesLeftToRead, args); + QUuid parentIDAfter = entity->getParentID(); + if (parentIDBefore != parentIDAfter) { + addToNeedsParentFixupList(entity); + } + } else { + entity = EntityTypes::constructEntityItem(dataAt, bytesLeftToRead, args); + if (entity) { + bytesForThisEntity = entity->readEntityDataFromBuffer(dataAt, bytesLeftToRead, args); - // don't add if we've recently deleted.... - if (!isDeletedEntity(entityItemID)) { - _entitiesToAdd.insert(entityItemID, entity); + // don't add if we've recently deleted.... + if (!isDeletedEntity(entityItemID)) { + _entitiesToAdd.insert(entityItemID, entity); - if (entity->getCreated() == UNKNOWN_CREATED_TIME) { - entity->recordCreationTime(); - } -#ifdef WANT_DEBUG - } else { - qCDebug(entities) << "Received packet for previously deleted entity [" << - entityItemID << "] ignoring. (inside " << __FUNCTION__ << ")"; -#endif - } - } -} -// Move the buffer forward to read more entities -dataAt += bytesForThisEntity; -bytesLeftToRead -= bytesForThisEntity; -bytesRead += bytesForThisEntity; + if (entity->getCreated() == UNKNOWN_CREATED_TIME) { + entity->recordCreationTime(); + } + #ifdef WANT_DEBUG + } else { + qCDebug(entities) << "Received packet for previously deleted entity [" << + entityItemID << "] ignoring. (inside " << __FUNCTION__ << ")"; + #endif + } + } + } + // Move the buffer forward to read more entities + dataAt += bytesForThisEntity; + bytesLeftToRead -= bytesForThisEntity; + bytesRead += bytesForThisEntity; } } } @@ -218,33 +218,19 @@ bytesRead += bytesForThisEntity; bool EntityTree::handlesEditPacketType(PacketType packetType) const { // we handle these types of "edit" packets switch (packetType) { - case PacketType::EntityAdd: - case PacketType::EntityEdit: - case PacketType::EntityErase: - case PacketType::EntityPhysics: - return true; - default: - return false; + case PacketType::EntityAdd: + case PacketType::EntityEdit: + case PacketType::EntityErase: + case PacketType::EntityPhysics: + return true; + default: + return false; } } /// Adds a new entity item to the tree void EntityTree::postAddEntity(EntityItemPointer entity) { assert(entity); - // check to see if we need to simulate this entity.. - if (_simulation) { - _simulation->addEntity(entity); - } - - if (!entity->getParentID().isNull()) { - addToNeedsParentFixupList(entity); - } - - _isDirty = true; - emit addingEntity(entity->getEntityItemID()); - - // find and hook up any entities with this entity as a (previously) missing parent - fixupNeedsParentFixups(); if (getIsServer()) { QString certID(entity->getCertificateID()); @@ -266,8 +252,24 @@ void EntityTree::postAddEntity(EntityItemPointer entity) { qCDebug(entities) << "Certificate ID" << certID << "already exists on entity with ID" << existingEntityItemID << ". Deleting existing entity."; deleteEntity(existingEntityItemID, true); + return; } } + + // check to see if we need to simulate this entity.. + if (_simulation) { + _simulation->addEntity(entity); + } + + if (!entity->getParentID().isNull()) { + addToNeedsParentFixupList(entity); + } + + _isDirty = true; + emit addingEntity(entity->getEntityItemID()); + + // find and hook up any entities with this entity as a (previously) missing parent + fixupNeedsParentFixups(); } bool EntityTree::updateEntity(const EntityItemID& entityID, const EntityItemProperties& properties, const SharedNodePointer& senderNode) { @@ -2250,3 +2252,4 @@ QStringList EntityTree::getJointNames(const QUuid& entityID) const { } return entity->getJointNames(); } + From 5a3a3c493785dc18ff4a0668c7ff517aa5eb3483 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 11 Oct 2017 15:05:45 -0700 Subject: [PATCH 022/116] What is going on --- libraries/entities/src/EntityTree.cpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index a68e36b7ed..48c148906e 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1177,20 +1177,15 @@ QString EntityTree::computeEncryptedNonce(const QString& certID, const QString& return ""; } - { - QWriteLocker locker(&_certNonceMapLock); - _certNonceMap.insert(certID, nonce); - } + QWriteLocker locker(&_certNonceMapLock); + _certNonceMap.insert(certID, nonce); return encryptedText.toBase64(); } bool EntityTree::verifyDecryptedNonce(const QString& certID, const QString& decryptedNonce) { - QString actualNonce; - { - QWriteLocker locker(&_certNonceMapLock); - actualNonce = _certNonceMap.take(certID).toString(); - } + QWriteLocker locker(&_certNonceMapLock); + QString actualNonce = _certNonceMap.take(certID).toString(); return actualNonce == decryptedNonce; } From c3e66c95814b9ed08fbf273fdd4273c9381e5817 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 11 Oct 2017 16:38:48 -0700 Subject: [PATCH 023/116] Fixes --- interface/src/commerce/Wallet.cpp | 36 ++++++++++++++------------ libraries/entities/src/EntityTree.cpp | 37 ++++++++++++++------------- libraries/entities/src/EntityTree.h | 2 +- 3 files changed, 40 insertions(+), 35 deletions(-) diff --git a/interface/src/commerce/Wallet.cpp b/interface/src/commerce/Wallet.cpp index 702a94625a..16800c6ad3 100644 --- a/interface/src/commerce/Wallet.cpp +++ b/interface/src/commerce/Wallet.cpp @@ -730,28 +730,32 @@ void Wallet::handleChallengeOwnershipPacket(QSharedPointer pack RSA* rsa = readKeys(keyFilePath().toStdString().c_str()); - const int decryptionStatus = RSA_private_decrypt(textLength, text, reinterpret_cast(encryptedText.data()), rsa, RSA_PKCS1_OAEP_PADDING); - RSA_free(rsa); + if (rsa) { + const int decryptionStatus = RSA_private_decrypt(textLength, text, reinterpret_cast(encryptedText.data()), rsa, RSA_PKCS1_OAEP_PADDING); + RSA_free(rsa); - if (decryptionStatus != -1) { - auto nodeList = DependencyManager::get(); + if (decryptionStatus != -1) { + auto nodeList = DependencyManager::get(); - QByteArray decryptedTextByteArray = decryptedText.toUtf8(); - int decryptedTextByteArraySize = decryptedTextByteArray.size(); - int certIDSize = certID.size(); - // setup the packet - auto decryptedTextPacket = NLPacket::create(PacketType::ChallengeOwnership, certIDSize + decryptedTextByteArraySize + 2*sizeof(int), true); + QByteArray decryptedTextByteArray = decryptedText.toUtf8(); + int decryptedTextByteArraySize = decryptedTextByteArray.size(); + int certIDSize = certID.size(); + // setup the packet + auto decryptedTextPacket = NLPacket::create(PacketType::ChallengeOwnership, certIDSize + decryptedTextByteArraySize + 2 * sizeof(int), true); - decryptedTextPacket->writePrimitive(certIDSize); - decryptedTextPacket->writePrimitive(decryptedTextByteArraySize); - decryptedTextPacket->write(certID); - decryptedTextPacket->write(decryptedTextByteArray); + decryptedTextPacket->writePrimitive(certIDSize); + decryptedTextPacket->writePrimitive(decryptedTextByteArraySize); + decryptedTextPacket->write(certID); + decryptedTextPacket->write(decryptedTextByteArray); - qCDebug(commerce) << "Sending ChallengeOwnership Packet containing decrypted text"; + qCDebug(commerce) << "Sending ChallengeOwnership Packet containing decrypted text"; - nodeList->sendPacket(std::move(decryptedTextPacket), *sendingNode); + nodeList->sendPacket(std::move(decryptedTextPacket), *sendingNode); + } else { + qCDebug(commerce) << "During entity ownership challenge, decrypting the encrypted text failed."; + } } else { - qCDebug(commerce) << "During entity ownership challenge, decrypting the encrypted text failed."; + qCDebug(commerce) << "During entity ownership challenge, creating the RSA object failed."; } } diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 48c148906e..7995a7894e 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1159,28 +1159,32 @@ void EntityTree::startPendingTransferStatusTimer(const QString& certID, const En transferStatusRetryTimer->start(90000); } -QString EntityTree::computeEncryptedNonce(const QString& certID, const QString& ownerKey) { +QString EntityTree::computeEncryptedNonce(const QString& certID, const QString ownerKey) { QUuid nonce = QUuid::createUuid(); const auto text = reinterpret_cast(qPrintable(nonce.toString())); const unsigned int textLength = nonce.toString().length(); - const auto publicKey = reinterpret_cast(ownerKey.toUtf8().toBase64().constData()); - BIO* bio = BIO_new_mem_buf((void*)publicKey, sizeof(publicKey)); + BIO* bio = BIO_new_mem_buf((void*)ownerKey.toUtf8().constData(), -1); + BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); // NO NEWLINE RSA* rsa = PEM_read_bio_RSAPublicKey(bio, NULL, NULL, NULL); - QByteArray encryptedText(RSA_size(rsa), 0); - const int encryptStatus = RSA_public_encrypt(textLength, text, reinterpret_cast(encryptedText.data()), rsa, RSA_PKCS1_OAEP_PADDING); - BIO_free(bio); - RSA_free(rsa); - if (encryptStatus == -1) { - qCWarning(entities) << "Unable to compute encrypted nonce for" << certID; - return ""; - } + //if (rsa) { + QByteArray encryptedText(RSA_size(rsa), 0); + const int encryptStatus = RSA_public_encrypt(textLength, text, reinterpret_cast(encryptedText.data()), rsa, RSA_PKCS1_OAEP_PADDING); + BIO_free(bio); + RSA_free(rsa); + if (encryptStatus == -1) { + qCWarning(entities) << "Unable to compute encrypted nonce for" << certID; + return ""; + } - QWriteLocker locker(&_certNonceMapLock); - _certNonceMap.insert(certID, nonce); + QWriteLocker locker(&_certNonceMapLock); + _certNonceMap.insert(certID, nonce); - return encryptedText.toBase64(); + return encryptedText.toBase64(); + //} else { + // return ""; + //} } bool EntityTree::verifyDecryptedNonce(const QString& certID, const QString& decryptedNonce) { @@ -1246,8 +1250,7 @@ void EntityTree::validatePop(const QString& certID, const EntityItemID& entityIt } else { // Second, challenge ownership of the PoP cert // 1. Encrypt a nonce with the owner's public key - QString ownerKey(jsonObject["transfer_recipient_key"].toString()); - QString encryptedText = computeEncryptedNonce(certID, ownerKey); + QString encryptedText = computeEncryptedNonce(certID, jsonObject["transfer_recipient_key"].toString()); if (encryptedText == "") { qCDebug(entities) << "CRITICAL ERROR: Couldn't compute encrypted nonce. Deleting entity..."; @@ -1260,8 +1263,6 @@ void EntityTree::validatePop(const QString& certID, const EntityItemID& entityIt int certIDByteArraySize = certIDByteArray.size(); QByteArray encryptedTextByteArray = encryptedText.toUtf8(); int encryptedTextByteArraySize = encryptedTextByteArray.size(); - QByteArray ownerKeyByteArray = ownerKey.toUtf8(); - int ownerKeyByteArraySize = ownerKeyByteArray.size(); auto challengeOwnershipPacket = NLPacket::create(PacketType::ChallengeOwnership, certIDByteArraySize + encryptedTextByteArraySize + 2 * sizeof(int), true); diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index fc6a913ffe..cffe0f6bb1 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -385,7 +385,7 @@ protected: Q_INVOKABLE void startPendingTransferStatusTimer(const QString& certID, const EntityItemID& entityItemID, const SharedNodePointer& senderNode); private: - QString computeEncryptedNonce(const QString& certID, const QString& ownerKey); + QString computeEncryptedNonce(const QString& certID, const QString ownerKey); bool verifyDecryptedNonce(const QString& certID, const QString& decryptedNonce); void validatePop(const QString& certID, const EntityItemID& entityItemID, const SharedNodePointer& senderNode, bool isRetryingValidation); }; From 480047548d5e76a0ccd6e9fe3142b36322b5011a Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 11 Oct 2017 18:04:29 -0700 Subject: [PATCH 024/116] exposing the Render interface to the overlay web3d --- interface/src/ui/overlays/Web3DOverlay.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index 526890b9c1..8f9f84642f 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -245,6 +245,7 @@ void Web3DOverlay::setupQmlSurface() { _webSurface->getSurfaceContext()->setContextProperty("SoundCache", DependencyManager::get().data()); _webSurface->getSurfaceContext()->setContextProperty("MenuInterface", MenuScriptingInterface::getInstance()); _webSurface->getSurfaceContext()->setContextProperty("Settings", SettingsScriptingInterface::getInstance()); + _webSurface->getSurfaceContext()->setContextProperty("Render", AbstractViewStateInterface::instance()->getRenderEngine()->getConfiguration().get()); _webSurface->getSurfaceContext()->setContextProperty("pathToFonts", "../../"); From 5efa9207120562acf07bdb68d2b58df9fe1d556f Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 12 Oct 2017 11:13:23 -0700 Subject: [PATCH 025/116] Getting closer --- interface/src/Application.cpp | 4 ++-- interface/src/Application.h | 2 +- interface/src/commerce/Ledger.cpp | 4 ++-- interface/src/commerce/Wallet.cpp | 15 ++++++++++----- .../entities/src/EntityEditPacketSender.cpp | 2 +- libraries/entities/src/EntityEditPacketSender.h | 4 +++- libraries/entities/src/EntityTree.cpp | 17 +++++++++-------- 7 files changed, 28 insertions(+), 20 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ed43c04d04..7589b85fd3 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5758,9 +5758,9 @@ int Application::processOctreeStats(ReceivedMessage& message, SharedNodePointer void Application::packetSent(quint64 length) { } -void Application::addingEntityWithCertificate(const QString& certificateID, const QString& domainID) { +void Application::addingEntityWithCertificate(const QString& certificateID, const QString& placeName) { auto ledger = DependencyManager::get(); - ledger->updateLocation(certificateID, domainID); + ledger->updateLocation(certificateID, placeName); } void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointer scriptEngine) { diff --git a/interface/src/Application.h b/interface/src/Application.h index 84d9eb9feb..bd1de68d71 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -440,7 +440,7 @@ private slots: void nodeActivated(SharedNodePointer node); void nodeKilled(SharedNodePointer node); static void packetSent(quint64 length); - static void addingEntityWithCertificate(const QString& certificateID, const QString& domainID); + static void addingEntityWithCertificate(const QString& certificateID, const QString& placeName); void updateDisplayMode(); void domainConnectionRefused(const QString& reasonMessage, int reason, const QString& extraInfo); diff --git a/interface/src/commerce/Ledger.cpp b/interface/src/commerce/Ledger.cpp index a1a709da98..7b48c98e54 100644 --- a/interface/src/commerce/Ledger.cpp +++ b/interface/src/commerce/Ledger.cpp @@ -234,8 +234,8 @@ void Ledger::updateLocation(const QString& asset_id, const QString location, con QStringList keys = wallet->listPublicKeys(); QString key = keys[0]; QJsonObject transaction; - transaction["asset_id"] = asset_id; - transaction["location"] = location; + transaction["certificate_id"] = asset_id; + transaction["place_name"] = location; QJsonDocument transactionDoc{ transaction }; auto transactionString = transactionDoc.toJson(QJsonDocument::Compact); signedSend("transaction", transactionString, key, "location", "updateLocationSuccess", "updateLocationFailure", controlledFailure); diff --git a/interface/src/commerce/Wallet.cpp b/interface/src/commerce/Wallet.cpp index 16800c6ad3..6952f3b327 100644 --- a/interface/src/commerce/Wallet.cpp +++ b/interface/src/commerce/Wallet.cpp @@ -715,7 +715,7 @@ bool Wallet::changePassphrase(const QString& newPassphrase) { } void Wallet::handleChallengeOwnershipPacket(QSharedPointer packet, SharedNodePointer sendingNode) { - QString decryptedText; + unsigned char decryptedText[64]; int certIDByteArraySize; int encryptedTextByteArraySize; @@ -725,19 +725,24 @@ void Wallet::handleChallengeOwnershipPacket(QSharedPointer pack QByteArray certID = packet->read(certIDByteArraySize); QByteArray encryptedText = packet->read(encryptedTextByteArraySize); - const auto text = reinterpret_cast(encryptedText.constData()); - const unsigned int textLength = encryptedText.length(); + const auto encryptedTextBuf = reinterpret_cast(encryptedText.constData()); + const unsigned int textLength = (int)strlen((char*)encryptedTextBuf); RSA* rsa = readKeys(keyFilePath().toStdString().c_str()); if (rsa) { - const int decryptionStatus = RSA_private_decrypt(textLength, text, reinterpret_cast(encryptedText.data()), rsa, RSA_PKCS1_OAEP_PADDING); + const int decryptionStatus = RSA_private_decrypt(textLength, encryptedTextBuf, decryptedText, rsa, RSA_PKCS1_OAEP_PADDING); + + long error = ERR_get_error(); + const char* error_str = ERR_error_string(error, NULL); + qDebug() << "ZRF HERE\n\nEncrypted Text:" << encryptedTextBuf << "\nEncrypted Text Length:" << textLength << "\nDecrypted Text:" << decryptedText << "\nError:" << error_str; + RSA_free(rsa); if (decryptionStatus != -1) { auto nodeList = DependencyManager::get(); - QByteArray decryptedTextByteArray = decryptedText.toUtf8(); + QByteArray decryptedTextByteArray = QByteArray(reinterpret_cast(decryptedText), (int)strlen((char*)decryptedText)); int decryptedTextByteArraySize = decryptedTextByteArray.size(); int certIDSize = certID.size(); // setup the packet diff --git a/libraries/entities/src/EntityEditPacketSender.cpp b/libraries/entities/src/EntityEditPacketSender.cpp index 2f8b796c93..aa045acbcc 100644 --- a/libraries/entities/src/EntityEditPacketSender.cpp +++ b/libraries/entities/src/EntityEditPacketSender.cpp @@ -111,7 +111,7 @@ void EntityEditPacketSender::queueEditEntityMessage(PacketType type, #endif queueOctreeEditMessage(type, bufferOut); if (type == PacketType::EntityAdd && !properties.getCertificateID().isEmpty()) { - emit addingEntityWithCertificate(properties.getCertificateID(), nodeList->getDomainHandler().getUUID().toString()); + emit addingEntityWithCertificate(properties.getCertificateID(), DependencyManager::get()->currentAddress().authority()); } } } diff --git a/libraries/entities/src/EntityEditPacketSender.h b/libraries/entities/src/EntityEditPacketSender.h index 4e5b62e206..4e8a4be13d 100644 --- a/libraries/entities/src/EntityEditPacketSender.h +++ b/libraries/entities/src/EntityEditPacketSender.h @@ -19,6 +19,8 @@ #include "EntityItem.h" #include "AvatarData.h" +#include + /// Utility for processing, packing, queueing and sending of outbound edit voxel messages. class EntityEditPacketSender : public OctreeEditPacketSender { Q_OBJECT @@ -44,7 +46,7 @@ public: virtual void adjustEditPacketForClockSkew(PacketType type, QByteArray& buffer, qint64 clockSkew) override; signals: - void addingEntityWithCertificate(const QString& certificateID, const QString& domainID); + void addingEntityWithCertificate(const QString& certificateID, const QString& placeName); public slots: void processEntityEditNackPacket(QSharedPointer message, SharedNodePointer sendingNode); diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 7995a7894e..d96cdaaa3e 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -1164,14 +1165,14 @@ QString EntityTree::computeEncryptedNonce(const QString& certID, const QString o const auto text = reinterpret_cast(qPrintable(nonce.toString())); const unsigned int textLength = nonce.toString().length(); - BIO* bio = BIO_new_mem_buf((void*)ownerKey.toUtf8().constData(), -1); + QString ownerKeyWithHeaders = ("-----BEGIN RSA PUBLIC KEY-----\n" + ownerKey + "\n-----END RSA PUBLIC KEY-----"); + BIO* bio = BIO_new_mem_buf((void*)ownerKeyWithHeaders.toUtf8().constData(), -1); BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); // NO NEWLINE RSA* rsa = PEM_read_bio_RSAPublicKey(bio, NULL, NULL, NULL); - //if (rsa) { + if (rsa) { QByteArray encryptedText(RSA_size(rsa), 0); const int encryptStatus = RSA_public_encrypt(textLength, text, reinterpret_cast(encryptedText.data()), rsa, RSA_PKCS1_OAEP_PADDING); - BIO_free(bio); RSA_free(rsa); if (encryptStatus == -1) { qCWarning(entities) << "Unable to compute encrypted nonce for" << certID; @@ -1181,10 +1182,10 @@ QString EntityTree::computeEncryptedNonce(const QString& certID, const QString o QWriteLocker locker(&_certNonceMapLock); _certNonceMap.insert(certID, nonce); - return encryptedText.toBase64(); - //} else { - // return ""; - //} + return encryptedText; + } else { + return ""; + } } bool EntityTree::verifyDecryptedNonce(const QString& certID, const QString& decryptedNonce) { @@ -1302,7 +1303,7 @@ void EntityTree::processChallengeOwnershipPacket(ReceivedMessage& message, const QString certID(message.read(certIDByteArraySize)); QString decryptedText(message.read(decryptedTextByteArraySize)); - qCDebug(entities) << "ZRF FIXME" << decryptedText << certID; + qCDebug(entities) << "ZRF FIXME FJAOPISEJFPAOISEJFOA" << decryptedText << certID; emit killChallengeOwnershipTimeoutTimer(certID); From 0e96fc5caba3ce1b3291cbf7d27f5c82ba7f7bee Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 12 Oct 2017 11:37:26 -0700 Subject: [PATCH 026/116] It's working! --- interface/src/commerce/Wallet.cpp | 11 ++++++----- libraries/entities/src/EntityTree.cpp | 16 +++++++--------- libraries/entities/src/EntityTree.h | 2 +- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/interface/src/commerce/Wallet.cpp b/interface/src/commerce/Wallet.cpp index 6952f3b327..fcb287c2d6 100644 --- a/interface/src/commerce/Wallet.cpp +++ b/interface/src/commerce/Wallet.cpp @@ -725,17 +725,18 @@ void Wallet::handleChallengeOwnershipPacket(QSharedPointer pack QByteArray certID = packet->read(certIDByteArraySize); QByteArray encryptedText = packet->read(encryptedTextByteArraySize); - const auto encryptedTextBuf = reinterpret_cast(encryptedText.constData()); - const unsigned int textLength = (int)strlen((char*)encryptedTextBuf); - RSA* rsa = readKeys(keyFilePath().toStdString().c_str()); if (rsa) { - const int decryptionStatus = RSA_private_decrypt(textLength, encryptedTextBuf, decryptedText, rsa, RSA_PKCS1_OAEP_PADDING); + const int decryptionStatus = RSA_private_decrypt(encryptedTextByteArraySize, + reinterpret_cast(encryptedText.constData()), + decryptedText, + rsa, + RSA_PKCS1_OAEP_PADDING); long error = ERR_get_error(); const char* error_str = ERR_error_string(error, NULL); - qDebug() << "ZRF HERE\n\nEncrypted Text:" << encryptedTextBuf << "\nEncrypted Text Length:" << textLength << "\nDecrypted Text:" << decryptedText << "\nError:" << error_str; + qDebug() << "ZRF HERE\n\nEncrypted Text:" << encryptedText << "\nEncrypted Text ByteArray Size:" << encryptedTextByteArraySize << "\nEncrypted Text Length:" << encryptedText.length() << "\nDecrypted Text:" << decryptedText << "\nError:" << error_str; RSA_free(rsa); diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index d96cdaaa3e..9a2048211f 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1160,7 +1160,7 @@ void EntityTree::startPendingTransferStatusTimer(const QString& certID, const En transferStatusRetryTimer->start(90000); } -QString EntityTree::computeEncryptedNonce(const QString& certID, const QString ownerKey) { +QByteArray EntityTree::computeEncryptedNonce(const QString& certID, const QString ownerKey) { QUuid nonce = QUuid::createUuid(); const auto text = reinterpret_cast(qPrintable(nonce.toString())); const unsigned int textLength = nonce.toString().length(); @@ -1182,6 +1182,8 @@ QString EntityTree::computeEncryptedNonce(const QString& certID, const QString o QWriteLocker locker(&_certNonceMapLock); _certNonceMap.insert(certID, nonce); + qDebug() << "ZRF HERE\n\nEncrypted Text:" << encryptedText << "\nEncrypted Text Length:" << encryptedText.length(); + return encryptedText; } else { return ""; @@ -1251,26 +1253,22 @@ void EntityTree::validatePop(const QString& certID, const EntityItemID& entityIt } else { // Second, challenge ownership of the PoP cert // 1. Encrypt a nonce with the owner's public key - QString encryptedText = computeEncryptedNonce(certID, jsonObject["transfer_recipient_key"].toString()); + QByteArray encryptedText = computeEncryptedNonce(certID, jsonObject["transfer_recipient_key"].toString()); if (encryptedText == "") { qCDebug(entities) << "CRITICAL ERROR: Couldn't compute encrypted nonce. Deleting entity..."; deleteEntity(entityItemID, true); - QWriteLocker locker(&_recentlyDeletedEntitiesLock); - _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID); } else { // 2. Send the encrypted text to the rezzing avatar's node QByteArray certIDByteArray = certID.toUtf8(); int certIDByteArraySize = certIDByteArray.size(); - QByteArray encryptedTextByteArray = encryptedText.toUtf8(); - int encryptedTextByteArraySize = encryptedTextByteArray.size(); auto challengeOwnershipPacket = NLPacket::create(PacketType::ChallengeOwnership, - certIDByteArraySize + encryptedTextByteArraySize + 2 * sizeof(int), + certIDByteArraySize + encryptedText.length() + 2 * sizeof(int), true); challengeOwnershipPacket->writePrimitive(certIDByteArraySize); - challengeOwnershipPacket->writePrimitive(encryptedTextByteArraySize); + challengeOwnershipPacket->writePrimitive(encryptedText.length()); challengeOwnershipPacket->write(certIDByteArray); - challengeOwnershipPacket->write(encryptedTextByteArray); + challengeOwnershipPacket->write(encryptedText); nodeList->sendPacket(std::move(challengeOwnershipPacket), *senderNode); // 3. Kickoff a 10-second timeout timer that deletes the entity if we don't get an ownership response in time diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index cffe0f6bb1..00a601d684 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -385,7 +385,7 @@ protected: Q_INVOKABLE void startPendingTransferStatusTimer(const QString& certID, const EntityItemID& entityItemID, const SharedNodePointer& senderNode); private: - QString computeEncryptedNonce(const QString& certID, const QString ownerKey); + QByteArray computeEncryptedNonce(const QString& certID, const QString ownerKey); bool verifyDecryptedNonce(const QString& certID, const QString& decryptedNonce); void validatePop(const QString& certID, const EntityItemID& entityItemID, const SharedNodePointer& senderNode, bool isRetryingValidation); }; From abe1cd1b51bba38d6a5e5ed7a5015b15dc77c0b9 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 12 Oct 2017 11:40:47 -0700 Subject: [PATCH 027/116] Minor cleanup --- assignment-client/src/entities/EntityServer.cpp | 7 +++---- interface/src/commerce/Wallet.cpp | 4 ---- libraries/entities/src/EntityTree.cpp | 4 ---- 3 files changed, 3 insertions(+), 12 deletions(-) diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index 1dc1eef593..0b27cfa408 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -442,8 +442,7 @@ void EntityServer::domainSettingsRequestFailed() { void EntityServer::startDynamicDomainVerification() { qCDebug(entities) << "Starting Dynamic Domain Verification..."; - auto nodeList = DependencyManager::get(); - QString thisDomainID = nodeList->getDomainHandler().getUUID().toString(); + QString thisPlaceName = DependencyManager::get()->currentAddress().authority(); EntityTreePointer tree = std::static_pointer_cast(_tree); QHash localMap(tree->getEntityCertificateIDMap()); @@ -485,9 +484,9 @@ void EntityServer::startDynamicDomainVerification() { if (networkReply->error() == QNetworkReply::NoError) { // ZRF FIXME!!! - //if (jsonObject["location"].toString() != thisDomainID) { + //if (jsonObject["place_name"].toString() != thisPlaceName) { if (false) { - qCDebug(entities) << "invalid_reason not empty, deleting entity" << i.value(); + qCDebug(entities) << "Entity's cert's place name isn't the current place name; deleting entity" << i.value(); tree->deleteEntity(i.value(), true); } } else { diff --git a/interface/src/commerce/Wallet.cpp b/interface/src/commerce/Wallet.cpp index fcb287c2d6..74f5e700f6 100644 --- a/interface/src/commerce/Wallet.cpp +++ b/interface/src/commerce/Wallet.cpp @@ -734,10 +734,6 @@ void Wallet::handleChallengeOwnershipPacket(QSharedPointer pack rsa, RSA_PKCS1_OAEP_PADDING); - long error = ERR_get_error(); - const char* error_str = ERR_error_string(error, NULL); - qDebug() << "ZRF HERE\n\nEncrypted Text:" << encryptedText << "\nEncrypted Text ByteArray Size:" << encryptedTextByteArraySize << "\nEncrypted Text Length:" << encryptedText.length() << "\nDecrypted Text:" << decryptedText << "\nError:" << error_str; - RSA_free(rsa); if (decryptionStatus != -1) { diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 9a2048211f..c4a22569d7 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1182,8 +1182,6 @@ QByteArray EntityTree::computeEncryptedNonce(const QString& certID, const QStrin QWriteLocker locker(&_certNonceMapLock); _certNonceMap.insert(certID, nonce); - qDebug() << "ZRF HERE\n\nEncrypted Text:" << encryptedText << "\nEncrypted Text Length:" << encryptedText.length(); - return encryptedText; } else { return ""; @@ -1301,8 +1299,6 @@ void EntityTree::processChallengeOwnershipPacket(ReceivedMessage& message, const QString certID(message.read(certIDByteArraySize)); QString decryptedText(message.read(decryptedTextByteArraySize)); - qCDebug(entities) << "ZRF FIXME FJAOPISEJFPAOISEJFOA" << decryptedText << certID; - emit killChallengeOwnershipTimeoutTimer(certID); if (!verifyDecryptedNonce(certID, decryptedText)) { From 50446619f5b5d39ed2551b0ea6f272a754decb1c Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 12 Oct 2017 11:59:46 -0700 Subject: [PATCH 028/116] Remove unnecessary (?) references to _recentlyDeletedEntityItemIDs --- libraries/entities/src/EntityTree.cpp | 30 ++++++++------------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index c4a22569d7..202d9f74b7 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1139,8 +1139,6 @@ void EntityTree::startChallengeOwnershipTimer(const EntityItemID& entityItemID) connect(_challengeOwnershipTimeoutTimer, &QTimer::timeout, this, [=]() { qCDebug(entities) << "Ownership challenge timed out, deleting entity" << entityItemID; deleteEntity(entityItemID, true); - QWriteLocker locker(&_recentlyDeletedEntitiesLock); - _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID); if (_challengeOwnershipTimeoutTimer) { _challengeOwnershipTimeoutTimer->stop(); _challengeOwnershipTimeoutTimer->deleteLater(); @@ -1224,19 +1222,13 @@ void EntityTree::validatePop(const QString& certID, const EntityItemID& entityIt if (!jsonObject["invalid_reason"].toString().isEmpty()) { qCDebug(entities) << "invalid_reason not empty, deleting entity" << entityItemID; deleteEntity(entityItemID, true); - QWriteLocker locker(&_recentlyDeletedEntitiesLock); - _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID); } else if (jsonObject["transfer_status"].toString() == "failed") { qCDebug(entities) << "'transfer_status' is 'failed', deleting entity" << entityItemID; deleteEntity(entityItemID, true); - QWriteLocker locker(&_recentlyDeletedEntitiesLock); - _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID); } else if (jsonObject["transfer_status"].toString() == "pending") { if (isRetryingValidation) { qCDebug(entities) << "'transfer_status' is 'pending' after retry, deleting entity" << entityItemID; deleteEntity(entityItemID, true); - QWriteLocker locker(&_recentlyDeletedEntitiesLock); - _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID); } else { if (thread() != QThread::currentThread()) { QMetaObject::invokeMethod(this, "startPendingTransferStatusTimer", @@ -1281,8 +1273,6 @@ void EntityTree::validatePop(const QString& certID, const EntityItemID& entityIt } else { qCDebug(entities) << "Call to proof_of_purchase_status endpoint failed; deleting entity" << entityItemID; deleteEntity(entityItemID, true); - QWriteLocker locker(&_recentlyDeletedEntitiesLock); - _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID); } networkReply->deleteLater(); @@ -1299,21 +1289,21 @@ void EntityTree::processChallengeOwnershipPacket(ReceivedMessage& message, const QString certID(message.read(certIDByteArraySize)); QString decryptedText(message.read(decryptedTextByteArraySize)); + EntityItemID id; + { + QReadLocker certIdMapLocker(&_entityCertificateIDMapLock); + id = _entityCertificateIDMap.value(certID); + } + emit killChallengeOwnershipTimeoutTimer(certID); if (!verifyDecryptedNonce(certID, decryptedText)) { - EntityItemID id; - { - QReadLocker certIdMapLocker(&_entityCertificateIDMapLock); - id = _entityCertificateIDMap.value(certID); - } - if (!id.isNull()) { - qCDebug(entities) << "Ownership challenge failed, deleting entity" << id; + qCDebug(entities) << "Ownership challenge for Cert ID" << certID << "failed; deleting entity" << id; deleteEntity(id, true); - QWriteLocker recentlyDeletedLocker(&_recentlyDeletedEntitiesLock); - _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), id); } + } else { + qCDebug(entities) << "Ownership challenge for Cert ID" << certID << "succeeded; keeping entity" << id; } } @@ -1521,8 +1511,6 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c << "static certificate verification."; // Delete the entity we just added if it doesn't pass static certificate verification deleteEntity(entityItemID, true); - QWriteLocker locker(&_recentlyDeletedEntitiesLock); - _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID); } else { validatePop(properties.getCertificateID(), entityItemID, senderNode, false); } From 6a47884fcf1b3dc9a2ee4be7fdee3479cae5465b Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 12 Oct 2017 13:41:19 -0700 Subject: [PATCH 029/116] Cleanup and fix --- .../src/entities/EntityServer.cpp | 9 ++++-- interface/src/commerce/Wallet.cpp | 2 +- .../entities/src/EntityEditPacketSender.cpp | 2 +- libraries/entities/src/EntityTree.cpp | 32 ++++++++++--------- 4 files changed, 25 insertions(+), 20 deletions(-) diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index 0b27cfa408..475c911bb8 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -442,7 +442,7 @@ void EntityServer::domainSettingsRequestFailed() { void EntityServer::startDynamicDomainVerification() { qCDebug(entities) << "Starting Dynamic Domain Verification..."; - QString thisPlaceName = DependencyManager::get()->currentAddress().authority(); + QString thisPlaceName = DependencyManager::get()->getPlaceName(); EntityTreePointer tree = std::static_pointer_cast(_tree); QHash localMap(tree->getEntityCertificateIDMap()); @@ -466,7 +466,7 @@ void EntityServer::startDynamicDomainVerification() { networkRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); QUrl requestURL = NetworkingConstants::METAVERSE_SERVER_URL; - requestURL.setPath("/api/v1/commerce/proof_of_purchase_status/transfer"); + requestURL.setPath("/api/v1/commerce/proof_of_purchase_status/location"); QJsonObject request; request["certificate_id"] = i.key(); networkRequest.setUrl(requestURL); @@ -486,8 +486,11 @@ void EntityServer::startDynamicDomainVerification() { // ZRF FIXME!!! //if (jsonObject["place_name"].toString() != thisPlaceName) { if (false) { - qCDebug(entities) << "Entity's cert's place name isn't the current place name; deleting entity" << i.value(); + qCDebug(entities) << "Entity's cert's place name" << jsonObject["place_name"].toString() + << "isn't the current place name" << thisPlaceName << "; deleting entity" << i.value(); tree->deleteEntity(i.value(), true); + } else { + qCDebug(entities) << "Entity passed dynamic domain verification:" << i.value(); } } else { qCDebug(entities) << "Call to proof_of_purchase_status endpoint failed; deleting entity" << i.value(); diff --git a/interface/src/commerce/Wallet.cpp b/interface/src/commerce/Wallet.cpp index 74f5e700f6..0bdb3c03ec 100644 --- a/interface/src/commerce/Wallet.cpp +++ b/interface/src/commerce/Wallet.cpp @@ -750,7 +750,7 @@ void Wallet::handleChallengeOwnershipPacket(QSharedPointer pack decryptedTextPacket->write(certID); decryptedTextPacket->write(decryptedTextByteArray); - qCDebug(commerce) << "Sending ChallengeOwnership Packet containing decrypted text"; + qCDebug(commerce) << "Sending ChallengeOwnership Packet containing decrypted text" << decryptedTextByteArray << "for CertID" << certID; nodeList->sendPacket(std::move(decryptedTextPacket), *sendingNode); } else { diff --git a/libraries/entities/src/EntityEditPacketSender.cpp b/libraries/entities/src/EntityEditPacketSender.cpp index aa045acbcc..5527cbc5ba 100644 --- a/libraries/entities/src/EntityEditPacketSender.cpp +++ b/libraries/entities/src/EntityEditPacketSender.cpp @@ -111,7 +111,7 @@ void EntityEditPacketSender::queueEditEntityMessage(PacketType type, #endif queueOctreeEditMessage(type, bufferOut); if (type == PacketType::EntityAdd && !properties.getCertificateID().isEmpty()) { - emit addingEntityWithCertificate(properties.getCertificateID(), DependencyManager::get()->currentAddress().authority()); + emit addingEntityWithCertificate(properties.getCertificateID(), DependencyManager::get()->getPlaceName()); } } } diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 202d9f74b7..69b7e5ab33 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1187,10 +1187,25 @@ QByteArray EntityTree::computeEncryptedNonce(const QString& certID, const QStrin } bool EntityTree::verifyDecryptedNonce(const QString& certID, const QString& decryptedNonce) { + + QReadLocker certIdMapLocker(&_entityCertificateIDMapLock); + EntityItemID id = _entityCertificateIDMap.value(certID); + QWriteLocker locker(&_certNonceMapLock); QString actualNonce = _certNonceMap.take(certID).toString(); - return actualNonce == decryptedNonce; + bool verificationSuccess = (actualNonce == decryptedNonce); + if (!verificationSuccess) { + if (!id.isNull()) { + qCDebug(entities) << "Ownership challenge for Cert ID" << certID << "failed; deleting entity" << id + << "\nActual nonce:" << actualNonce << "\nDecrypted nonce:" << decryptedNonce; + deleteEntity(id, true); + } + } else { + qCDebug(entities) << "Ownership challenge for Cert ID" << certID << "succeeded; keeping entity" << id; + } + + return verificationSuccess; } void EntityTree::validatePop(const QString& certID, const EntityItemID& entityItemID, const SharedNodePointer& senderNode, bool isRetryingValidation) { @@ -1289,22 +1304,9 @@ void EntityTree::processChallengeOwnershipPacket(ReceivedMessage& message, const QString certID(message.read(certIDByteArraySize)); QString decryptedText(message.read(decryptedTextByteArraySize)); - EntityItemID id; - { - QReadLocker certIdMapLocker(&_entityCertificateIDMapLock); - id = _entityCertificateIDMap.value(certID); - } - emit killChallengeOwnershipTimeoutTimer(certID); - if (!verifyDecryptedNonce(certID, decryptedText)) { - if (!id.isNull()) { - qCDebug(entities) << "Ownership challenge for Cert ID" << certID << "failed; deleting entity" << id; - deleteEntity(id, true); - } - } else { - qCDebug(entities) << "Ownership challenge for Cert ID" << certID << "succeeded; keeping entity" << id; - } + verifyDecryptedNonce(certID, decryptedText); } int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned char* editData, int maxLength, From d75c0a00bb97bfee9cad7f9c4f3af6a601ceba29 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 12 Oct 2017 16:29:05 -0700 Subject: [PATCH 030/116] Closer than ever --- assignment-client/src/entities/EntityServer.cpp | 8 +------- assignment-client/src/entities/EntityServer.h | 1 + interface/src/commerce/Wallet.cpp | 2 +- libraries/entities/src/EntityTree.cpp | 8 ++------ libraries/entities/src/EntityTree.h | 1 + 5 files changed, 6 insertions(+), 14 deletions(-) diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index 475c911bb8..47d51e8d77 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -478,14 +478,8 @@ void EntityServer::startDynamicDomainVerification() { QJsonObject jsonObject = QJsonDocument::fromJson(networkReply->readAll()).object(); jsonObject = jsonObject["data"].toObject(); - // ZRF FIXME Remove these two lines - QJsonDocument doc(jsonObject); - qCDebug(entities) << "ZRF FIXME" << doc.toJson(QJsonDocument::Compact); - if (networkReply->error() == QNetworkReply::NoError) { - // ZRF FIXME!!! - //if (jsonObject["place_name"].toString() != thisPlaceName) { - if (false) { + if (jsonObject["location"].toArray().first().toString() != thisPlaceName) { qCDebug(entities) << "Entity's cert's place name" << jsonObject["place_name"].toString() << "isn't the current place name" << thisPlaceName << "; deleting entity" << i.value(); tree->deleteEntity(i.value(), true); diff --git a/assignment-client/src/entities/EntityServer.h b/assignment-client/src/entities/EntityServer.h index 5cebd9b751..408fad4494 100644 --- a/assignment-client/src/entities/EntityServer.h +++ b/assignment-client/src/entities/EntityServer.h @@ -19,6 +19,7 @@ #include "EntityItem.h" #include "EntityServerConsts.h" #include "EntityTree.h" +#include /// Handles assignments of type EntityServer - sending entities to various clients. diff --git a/interface/src/commerce/Wallet.cpp b/interface/src/commerce/Wallet.cpp index 0bdb3c03ec..64b9922022 100644 --- a/interface/src/commerce/Wallet.cpp +++ b/interface/src/commerce/Wallet.cpp @@ -739,7 +739,7 @@ void Wallet::handleChallengeOwnershipPacket(QSharedPointer pack if (decryptionStatus != -1) { auto nodeList = DependencyManager::get(); - QByteArray decryptedTextByteArray = QByteArray(reinterpret_cast(decryptedText), (int)strlen((char*)decryptedText)); + QByteArray decryptedTextByteArray = QByteArray(reinterpret_cast(decryptedText), decryptionStatus); int decryptedTextByteArraySize = decryptedTextByteArray.size(); int certIDSize = certID.size(); // setup the packet diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 69b7e5ab33..341637606f 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1229,18 +1229,14 @@ void EntityTree::validatePop(const QString& certID, const EntityItemID& entityIt QJsonObject jsonObject = QJsonDocument::fromJson(networkReply->readAll()).object(); jsonObject = jsonObject["data"].toObject(); - // ZRF FIXME Remove these two lines - QJsonDocument doc(jsonObject); - qCDebug(entities) << "ZRF FIXME" << doc.toJson(QJsonDocument::Compact); - if (networkReply->error() == QNetworkReply::NoError) { if (!jsonObject["invalid_reason"].toString().isEmpty()) { qCDebug(entities) << "invalid_reason not empty, deleting entity" << entityItemID; deleteEntity(entityItemID, true); - } else if (jsonObject["transfer_status"].toString() == "failed") { + } else if (jsonObject["transfer_status"].toArray().first().toString() == "failed") { qCDebug(entities) << "'transfer_status' is 'failed', deleting entity" << entityItemID; deleteEntity(entityItemID, true); - } else if (jsonObject["transfer_status"].toString() == "pending") { + } else if (jsonObject["transfer_status"].toArray().first().toString() == "pending") { if (isRetryingValidation) { qCDebug(entities) << "'transfer_status' is 'pending' after retry, deleting entity" << entityItemID; deleteEntity(entityItemID, true); diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 00a601d684..8d939159ce 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -18,6 +18,7 @@ #include "AccountManager.h" #include #include +#include #include #include From b56a38ca15aa109ee96047fa8907d91631b4197c Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 12 Oct 2017 16:32:09 -0700 Subject: [PATCH 031/116] Re-add references to recentlyDeletedEntityItemIDs --- libraries/entities/src/EntityTree.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 341637606f..f36b6ef168 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1139,6 +1139,8 @@ void EntityTree::startChallengeOwnershipTimer(const EntityItemID& entityItemID) connect(_challengeOwnershipTimeoutTimer, &QTimer::timeout, this, [=]() { qCDebug(entities) << "Ownership challenge timed out, deleting entity" << entityItemID; deleteEntity(entityItemID, true); + QWriteLocker locker(&_recentlyDeletedEntitiesLock); + _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID); if (_challengeOwnershipTimeoutTimer) { _challengeOwnershipTimeoutTimer->stop(); _challengeOwnershipTimeoutTimer->deleteLater(); @@ -1200,6 +1202,8 @@ bool EntityTree::verifyDecryptedNonce(const QString& certID, const QString& decr qCDebug(entities) << "Ownership challenge for Cert ID" << certID << "failed; deleting entity" << id << "\nActual nonce:" << actualNonce << "\nDecrypted nonce:" << decryptedNonce; deleteEntity(id, true); + QWriteLocker locker(&_recentlyDeletedEntitiesLock); + _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), id); } } else { qCDebug(entities) << "Ownership challenge for Cert ID" << certID << "succeeded; keeping entity" << id; @@ -1233,13 +1237,19 @@ void EntityTree::validatePop(const QString& certID, const EntityItemID& entityIt if (!jsonObject["invalid_reason"].toString().isEmpty()) { qCDebug(entities) << "invalid_reason not empty, deleting entity" << entityItemID; deleteEntity(entityItemID, true); + QWriteLocker locker(&_recentlyDeletedEntitiesLock); + _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID); } else if (jsonObject["transfer_status"].toArray().first().toString() == "failed") { qCDebug(entities) << "'transfer_status' is 'failed', deleting entity" << entityItemID; deleteEntity(entityItemID, true); + QWriteLocker locker(&_recentlyDeletedEntitiesLock); + _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID); } else if (jsonObject["transfer_status"].toArray().first().toString() == "pending") { if (isRetryingValidation) { qCDebug(entities) << "'transfer_status' is 'pending' after retry, deleting entity" << entityItemID; deleteEntity(entityItemID, true); + QWriteLocker locker(&_recentlyDeletedEntitiesLock); + _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID); } else { if (thread() != QThread::currentThread()) { QMetaObject::invokeMethod(this, "startPendingTransferStatusTimer", @@ -1284,6 +1294,8 @@ void EntityTree::validatePop(const QString& certID, const EntityItemID& entityIt } else { qCDebug(entities) << "Call to proof_of_purchase_status endpoint failed; deleting entity" << entityItemID; deleteEntity(entityItemID, true); + QWriteLocker locker(&_recentlyDeletedEntitiesLock); + _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID); } networkReply->deleteLater(); @@ -1509,6 +1521,8 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c << "static certificate verification."; // Delete the entity we just added if it doesn't pass static certificate verification deleteEntity(entityItemID, true); + QWriteLocker locker(&_recentlyDeletedEntitiesLock); + _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID); } else { validatePop(properties.getCertificateID(), entityItemID, senderNode, false); } From 1400c66506d70c5341d58cbcc0f7fa3d9154a76d Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 12 Oct 2017 16:58:48 -0700 Subject: [PATCH 032/116] Be a bit more thorough --- .../src/entities/EntityServer.cpp | 3 +++ libraries/entities/src/EntityTree.cpp | 22 +++++++------------ libraries/entities/src/EntityTree.h | 5 +++++ 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index 47d51e8d77..ba76bf7f53 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -459,6 +459,7 @@ void EntityServer::startDynamicDomainVerification() { << "static certificate verification."; // Delete the entity if it doesn't pass static certificate verification tree->deleteEntity(i.value(), true); + tree->insertRecentlyDeletedEntityIDs(i.value()); } else { QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); @@ -483,12 +484,14 @@ void EntityServer::startDynamicDomainVerification() { qCDebug(entities) << "Entity's cert's place name" << jsonObject["place_name"].toString() << "isn't the current place name" << thisPlaceName << "; deleting entity" << i.value(); tree->deleteEntity(i.value(), true); + tree->insertRecentlyDeletedEntityIDs(i.value()); } else { qCDebug(entities) << "Entity passed dynamic domain verification:" << i.value(); } } else { qCDebug(entities) << "Call to proof_of_purchase_status endpoint failed; deleting entity" << i.value(); tree->deleteEntity(i.value(), true); + tree->insertRecentlyDeletedEntityIDs(i.value()); } networkReply->deleteLater(); diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index f36b6ef168..d0ec1ffda7 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1139,8 +1139,7 @@ void EntityTree::startChallengeOwnershipTimer(const EntityItemID& entityItemID) connect(_challengeOwnershipTimeoutTimer, &QTimer::timeout, this, [=]() { qCDebug(entities) << "Ownership challenge timed out, deleting entity" << entityItemID; deleteEntity(entityItemID, true); - QWriteLocker locker(&_recentlyDeletedEntitiesLock); - _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID); + insertRecentlyDeletedEntityIDs(entityItemID); if (_challengeOwnershipTimeoutTimer) { _challengeOwnershipTimeoutTimer->stop(); _challengeOwnershipTimeoutTimer->deleteLater(); @@ -1202,8 +1201,7 @@ bool EntityTree::verifyDecryptedNonce(const QString& certID, const QString& decr qCDebug(entities) << "Ownership challenge for Cert ID" << certID << "failed; deleting entity" << id << "\nActual nonce:" << actualNonce << "\nDecrypted nonce:" << decryptedNonce; deleteEntity(id, true); - QWriteLocker locker(&_recentlyDeletedEntitiesLock); - _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), id); + insertRecentlyDeletedEntityIDs(id); } } else { qCDebug(entities) << "Ownership challenge for Cert ID" << certID << "succeeded; keeping entity" << id; @@ -1237,19 +1235,16 @@ void EntityTree::validatePop(const QString& certID, const EntityItemID& entityIt if (!jsonObject["invalid_reason"].toString().isEmpty()) { qCDebug(entities) << "invalid_reason not empty, deleting entity" << entityItemID; deleteEntity(entityItemID, true); - QWriteLocker locker(&_recentlyDeletedEntitiesLock); - _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID); + insertRecentlyDeletedEntityIDs(entityItemID); } else if (jsonObject["transfer_status"].toArray().first().toString() == "failed") { qCDebug(entities) << "'transfer_status' is 'failed', deleting entity" << entityItemID; deleteEntity(entityItemID, true); - QWriteLocker locker(&_recentlyDeletedEntitiesLock); - _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID); + insertRecentlyDeletedEntityIDs(entityItemID); } else if (jsonObject["transfer_status"].toArray().first().toString() == "pending") { if (isRetryingValidation) { qCDebug(entities) << "'transfer_status' is 'pending' after retry, deleting entity" << entityItemID; deleteEntity(entityItemID, true); - QWriteLocker locker(&_recentlyDeletedEntitiesLock); - _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID); + insertRecentlyDeletedEntityIDs(entityItemID); } else { if (thread() != QThread::currentThread()) { QMetaObject::invokeMethod(this, "startPendingTransferStatusTimer", @@ -1269,6 +1264,7 @@ void EntityTree::validatePop(const QString& certID, const EntityItemID& entityIt if (encryptedText == "") { qCDebug(entities) << "CRITICAL ERROR: Couldn't compute encrypted nonce. Deleting entity..."; deleteEntity(entityItemID, true); + insertRecentlyDeletedEntityIDs(entityItemID); } else { // 2. Send the encrypted text to the rezzing avatar's node QByteArray certIDByteArray = certID.toUtf8(); @@ -1294,8 +1290,7 @@ void EntityTree::validatePop(const QString& certID, const EntityItemID& entityIt } else { qCDebug(entities) << "Call to proof_of_purchase_status endpoint failed; deleting entity" << entityItemID; deleteEntity(entityItemID, true); - QWriteLocker locker(&_recentlyDeletedEntitiesLock); - _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID); + insertRecentlyDeletedEntityIDs(entityItemID); } networkReply->deleteLater(); @@ -1521,8 +1516,7 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c << "static certificate verification."; // Delete the entity we just added if it doesn't pass static certificate verification deleteEntity(entityItemID, true); - QWriteLocker locker(&_recentlyDeletedEntitiesLock); - _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID); + insertRecentlyDeletedEntityIDs(entityItemID); } else { validatePop(properties.getCertificateID(), entityItemID, senderNode, false); } diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 8d939159ce..b939ff51c1 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -193,6 +193,11 @@ public: return _recentlyDeletedEntityItemIDs; } + void insertRecentlyDeletedEntityIDs(const EntityItemID& id) { + QWriteLocker locker(&_recentlyDeletedEntitiesLock); + _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), id); + } + QHash getEntityCertificateIDMap() const { QReadLocker locker(&_entityCertificateIDMapLock); return _entityCertificateIDMap; From 8994200d0115fb471de62e9d3c68b6958a2b48a4 Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 12 Oct 2017 17:57:30 -0700 Subject: [PATCH 033/116] Trying to integrate the tool scripts as an app --- .../src/EntityTreeRenderer.cpp | 6 +- .../utilities/lib/configprop/ConfigSlider.qml | 72 ++++ .../lib/hifi-qml/controls-uit/Button.qml | 73 ++++ .../lib/hifi-qml/controls-uit/CheckBox.qml | 101 +++++ .../lib/hifi-qml/controls-uit/ComboBox.qml | 249 +++++++++++ .../hifi-qml/controls-uit/ConfigSlider.qml | 72 ++++ .../hifi-qml/controls-uit/ContentSection.qml | 138 ++++++ .../lib/hifi-qml/controls-uit/GlyphButton.qml | 78 ++++ .../hifi-qml/controls-uit/HorizontalRule.qml | 20 + .../controls-uit/HorizontalSpacer.qml | 21 + .../lib/hifi-qml/controls-uit/Label.qml | 22 + .../hifi-qml/controls-uit/QueuedButton.qml | 43 ++ .../lib/hifi-qml/controls-uit/RadioButton.qml | 71 +++ .../lib/hifi-qml/controls-uit/Separator.qml | 38 ++ .../lib/hifi-qml/controls-uit/Slider.qml | 98 +++++ .../lib/hifi-qml/controls-uit/SpinBox.qml | 117 +++++ .../lib/hifi-qml/controls-uit/Switch.qml | 156 +++++++ .../lib/hifi-qml/controls-uit/Table.qml | 179 ++++++++ .../hifi-qml/controls-uit/VerticalSpacer.qml | 21 + .../styles-uit/AnonymousProRegular.qml | 23 + .../lib/hifi-qml/styles-uit/ButtonLabel.qml | 18 + .../hifi-qml/styles-uit/FiraSansRegular.qml | 23 + .../hifi-qml/styles-uit/FiraSansSemiBold.qml | 23 + .../hifi-qml/styles-uit/FiraSansSemiBold.qmlc | Bin 0 -> 4097 bytes .../lib/hifi-qml/styles-uit/HiFiGlyphs.qml | 25 ++ .../lib/hifi-qml/styles-uit/HiFiGlyphs.qmlc | Bin 0 -> 4897 bytes .../lib/hifi-qml/styles-uit/HifiConstants.qml | 342 +++++++++++++++ .../hifi-qml/styles-uit/HifiConstants.qmlc | Bin 0 -> 51320 bytes .../lib/hifi-qml/styles-uit/IconButton.qml | 20 + .../lib/hifi-qml/styles-uit/InfoItem.qml | 19 + .../lib/hifi-qml/styles-uit/InputLabel.qml | 18 + .../lib/hifi-qml/styles-uit/ListItem.qml | 18 + .../lib/hifi-qml/styles-uit/Logs.qml | 18 + .../lib/hifi-qml/styles-uit/OverlayTitle.qml | 18 + .../lib/hifi-qml/styles-uit/RalewayBold.qml | 24 ++ .../lib/hifi-qml/styles-uit/RalewayLight.qml | 23 + .../hifi-qml/styles-uit/RalewayRegular.qml | 23 + .../hifi-qml/styles-uit/RalewaySemiBold.qml | 23 + .../hifi-qml/styles-uit/RalewaySemiBold.qmlc | Bin 0 -> 4081 bytes .../lib/hifi-qml/styles-uit/SectionName.qml | 19 + .../lib/hifi-qml/styles-uit/Separator.qml | 41 ++ .../lib/hifi-qml/styles-uit/Separator.qmlc | Bin 0 -> 6855 bytes .../lib/hifi-qml/styles-uit/ShortcutText.qml | 18 + .../lib/hifi-qml/styles-uit/TabName.qml | 19 + .../hifi-qml/styles-uit/TextFieldInput.qml | 18 + .../utilities/render/deferredLighting.qml | 405 ++++++++++-------- scripts/developer/utilities/render/luci.js | 98 +++++ 47 files changed, 2663 insertions(+), 188 deletions(-) create mode 100644 scripts/developer/utilities/lib/configprop/ConfigSlider.qml create mode 100644 scripts/developer/utilities/lib/hifi-qml/controls-uit/Button.qml create mode 100644 scripts/developer/utilities/lib/hifi-qml/controls-uit/CheckBox.qml create mode 100644 scripts/developer/utilities/lib/hifi-qml/controls-uit/ComboBox.qml create mode 100644 scripts/developer/utilities/lib/hifi-qml/controls-uit/ConfigSlider.qml create mode 100644 scripts/developer/utilities/lib/hifi-qml/controls-uit/ContentSection.qml create mode 100644 scripts/developer/utilities/lib/hifi-qml/controls-uit/GlyphButton.qml create mode 100644 scripts/developer/utilities/lib/hifi-qml/controls-uit/HorizontalRule.qml create mode 100644 scripts/developer/utilities/lib/hifi-qml/controls-uit/HorizontalSpacer.qml create mode 100644 scripts/developer/utilities/lib/hifi-qml/controls-uit/Label.qml create mode 100644 scripts/developer/utilities/lib/hifi-qml/controls-uit/QueuedButton.qml create mode 100644 scripts/developer/utilities/lib/hifi-qml/controls-uit/RadioButton.qml create mode 100644 scripts/developer/utilities/lib/hifi-qml/controls-uit/Separator.qml create mode 100644 scripts/developer/utilities/lib/hifi-qml/controls-uit/Slider.qml create mode 100644 scripts/developer/utilities/lib/hifi-qml/controls-uit/SpinBox.qml create mode 100644 scripts/developer/utilities/lib/hifi-qml/controls-uit/Switch.qml create mode 100644 scripts/developer/utilities/lib/hifi-qml/controls-uit/Table.qml create mode 100644 scripts/developer/utilities/lib/hifi-qml/controls-uit/VerticalSpacer.qml create mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/AnonymousProRegular.qml create mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/ButtonLabel.qml create mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/FiraSansRegular.qml create mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/FiraSansSemiBold.qml create mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/FiraSansSemiBold.qmlc create mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/HiFiGlyphs.qml create mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/HiFiGlyphs.qmlc create mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/HifiConstants.qml create mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/HifiConstants.qmlc create mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/IconButton.qml create mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/InfoItem.qml create mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/InputLabel.qml create mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/ListItem.qml create mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/Logs.qml create mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/OverlayTitle.qml create mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/RalewayBold.qml create mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/RalewayLight.qml create mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/RalewayRegular.qml create mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/RalewaySemiBold.qml create mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/RalewaySemiBold.qmlc create mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/SectionName.qml create mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/Separator.qml create mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/Separator.qmlc create mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/ShortcutText.qml create mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/TabName.qml create mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/TextFieldInput.qml create mode 100644 scripts/developer/utilities/render/luci.js diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 9e700b0efe..92a82908e2 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -72,7 +72,11 @@ EntityRendererPointer EntityTreeRenderer::renderableForEntityId(const EntityItem render::ItemID EntityTreeRenderer::renderableIdForEntityId(const EntityItemID& id) const { auto renderable = renderableForEntityId(id); - return renderable ? renderable->getRenderItemID() : render::Item::INVALID_ITEM_ID; + if (renderable) { + return renderable->getRenderItemID(); + } else { + return render::Item::INVALID_ITEM_ID; + } } int EntityTreeRenderer::_entitiesScriptEngineCount = 0; diff --git a/scripts/developer/utilities/lib/configprop/ConfigSlider.qml b/scripts/developer/utilities/lib/configprop/ConfigSlider.qml new file mode 100644 index 0000000000..516193b81c --- /dev/null +++ b/scripts/developer/utilities/lib/configprop/ConfigSlider.qml @@ -0,0 +1,72 @@ +// +// ConfigSlider.qml +// +// Created by Zach Pomerantz on 2/8/2016 +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html +// + +import QtQuick 2.7 +import QtQuick.Controls 1.4 +import QtQuick.Layouts 1.3 + +import "../hifi-qml/styles-uit" +import "../hifi-qml/controls-uit" as HifiControls + + +Item { + id: root + width: 400 + height: 24 + property bool integral: false + property var config + property string property + property alias label: labelControl.text + property alias min: sliderControl.minimumValue + property alias max: sliderControl.maximumValue + + Component.onCompleted: { + // Binding favors qml value, so set it first + sliderControl.value = root.config[root.property]; + bindingControl.when = true; + } + + HifiControls.Label { + id: labelControl + text: root.label + anchors.left: root.left + anchors.leftMargin: 8 + anchors.top: root.top + anchors.topMargin: 7 + } + + HifiControls.Label { + id: labelValue + text: sliderControl.value.toFixed(root.integral ? 0 : 2) + anchors.right: root.right + anchors.rightMargin: 8 + anchors.top: root.top + anchors.topMargin: 15 + } + + Binding { + id: bindingControl + target: root.config + property: root.property + value: sliderControl.value + when: false + } + + HifiControls.Slider { + id: sliderControl + stepSize: root.integral ? 1.0 : 0.0 + width: root.width-130 + height: 20 + anchors.right: root.right + anchors.rightMargin: 8 + anchors.top: root.top + anchors.topMargin: 3 + } +} diff --git a/scripts/developer/utilities/lib/hifi-qml/controls-uit/Button.qml b/scripts/developer/utilities/lib/hifi-qml/controls-uit/Button.qml new file mode 100644 index 0000000000..59f8a63238 --- /dev/null +++ b/scripts/developer/utilities/lib/hifi-qml/controls-uit/Button.qml @@ -0,0 +1,73 @@ +// +// Button.qml +// +// Created by David Rowe on 16 Feb 2016 +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +import QtQuick 2.5 +import QtQuick.Controls 1.4 as Original +import QtQuick.Controls.Styles 1.4 + +import "../styles-uit" + +Original.Button { + property int color: 0 + property int colorScheme: hifi.colorSchemes.light + + width: 120 + height: hifi.dimensions.controlLineHeight + + HifiConstants { id: hifi } + + style: ButtonStyle { + + background: Rectangle { + radius: hifi.buttons.radius + + gradient: Gradient { + GradientStop { + position: 0.2 + color: { + if (!control.enabled) { + hifi.buttons.disabledColorStart[control.colorScheme] + } else if (control.pressed) { + hifi.buttons.pressedColor[control.color] + } else if (control.hovered) { + hifi.buttons.hoveredColor[control.color] + } else { + hifi.buttons.colorStart[control.color] + } + } + } + GradientStop { + position: 1.0 + color: { + if (!control.enabled) { + hifi.buttons.disabledColorFinish[control.colorScheme] + } else if (control.pressed) { + hifi.buttons.pressedColor[control.color] + } else if (control.hovered) { + hifi.buttons.hoveredColor[control.color] + } else { + hifi.buttons.colorFinish[control.color] + } + } + } + } + } + + label: RalewayBold { + font.capitalization: Font.AllUppercase + color: enabled ? hifi.buttons.textColor[control.color] + : hifi.buttons.disabledTextColor[control.colorScheme] + size: hifi.fontSizes.buttonLabel + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + text: control.text + } + } +} diff --git a/scripts/developer/utilities/lib/hifi-qml/controls-uit/CheckBox.qml b/scripts/developer/utilities/lib/hifi-qml/controls-uit/CheckBox.qml new file mode 100644 index 0000000000..b279b7ca8d --- /dev/null +++ b/scripts/developer/utilities/lib/hifi-qml/controls-uit/CheckBox.qml @@ -0,0 +1,101 @@ +// +// CheckBox.qml +// +// Created by David Rowe on 26 Feb 2016 +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +import QtQuick 2.5 +import QtQuick.Controls 1.4 as Original +import QtQuick.Controls.Styles 1.4 + +import "../styles-uit" + +Original.CheckBox { + id: checkBox + + property int colorScheme: hifi.colorSchemes.light + property string color: hifi.colors.lightGrayText + readonly property bool isLightColorScheme: colorScheme == hifi.colorSchemes.light + property bool isRedCheck: false + property int boxSize: 14 + property int boxRadius: 3 + property bool wrap: true; + readonly property int checkSize: Math.max(boxSize - 8, 10) + readonly property int checkRadius: 2 + activeFocusOnPress: true + + style: CheckBoxStyle { + indicator: Rectangle { + id: box + width: boxSize + height: boxSize + radius: boxRadius + border.width: 1 + border.color: pressed || hovered + ? hifi.colors.checkboxCheckedBorder + : (checkBox.isLightColorScheme ? hifi.colors.checkboxLightFinish : hifi.colors.checkboxDarkFinish) + + gradient: Gradient { + GradientStop { + position: 0.2 + color: pressed || hovered + ? (checkBox.isLightColorScheme ? hifi.colors.checkboxChecked : hifi.colors.checkboxLightStart) + : (checkBox.isLightColorScheme ? hifi.colors.checkboxLightStart : hifi.colors.checkboxDarkStart) + } + GradientStop { + position: 1.0 + color: pressed || hovered + ? (checkBox.isLightColorScheme ? hifi.colors.checkboxChecked : hifi.colors.checkboxLightFinish) + : (checkBox.isLightColorScheme ? hifi.colors.checkboxLightFinish : hifi.colors.checkboxDarkFinish) + } + } + + Rectangle { + visible: pressed || hovered + anchors.centerIn: parent + id: innerBox + width: checkSize - 4 + height: width + radius: checkRadius + color: hifi.colors.checkboxCheckedBorder + } + + Rectangle { + id: check + width: checkSize + height: checkSize + radius: checkRadius + anchors.centerIn: parent + color: isRedCheck ? hifi.colors.checkboxCheckedRed : hifi.colors.checkboxChecked + border.width: 2 + border.color: isRedCheck? hifi.colors.checkboxCheckedBorderRed : hifi.colors.checkboxCheckedBorder + visible: checked && !pressed || !checked && pressed + } + + Rectangle { + id: disabledOverlay + visible: !enabled + width: boxSize + height: boxSize + radius: boxRadius + border.width: 1 + border.color: hifi.colors.baseGrayHighlight + color: hifi.colors.baseGrayHighlight + opacity: 0.5 + } + } + + label: Label { + text: control.text + color: control.color + x: 2 + wrapMode: checkBox.wrap ? Text.Wrap : Text.NoWrap + elide: checkBox.wrap ? Text.ElideNone : Text.ElideRight + enabled: checkBox.enabled + } + } +} diff --git a/scripts/developer/utilities/lib/hifi-qml/controls-uit/ComboBox.qml b/scripts/developer/utilities/lib/hifi-qml/controls-uit/ComboBox.qml new file mode 100644 index 0000000000..d672fa6387 --- /dev/null +++ b/scripts/developer/utilities/lib/hifi-qml/controls-uit/ComboBox.qml @@ -0,0 +1,249 @@ +// +// ComboBox.qml +// +// Created by Bradley Austin David on 27 Jan 2016 +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +import QtQuick 2.5 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 + +import "../styles-uit" +import "../controls-uit" as HifiControls + +FocusScope { + id: root + HifiConstants { id: hifi } + + property alias model: comboBox.model; + property alias editable: comboBox.editable + property alias comboBox: comboBox + readonly property alias currentText: comboBox.currentText; + property alias currentIndex: comboBox.currentIndex; + + property int dropdownHeight: 480 + property int colorScheme: hifi.colorSchemes.light + readonly property bool isLightColorScheme: colorScheme == hifi.colorSchemes.light + property string label: "" + property real controlHeight: height + (comboBoxLabel.visible ? comboBoxLabel.height + comboBoxLabel.anchors.bottomMargin : 0) + + readonly property ComboBox control: comboBox + + property bool isDesktop: true + + signal accepted(); + + implicitHeight: comboBox.height; + focus: true + + Rectangle { + id: background + gradient: Gradient { + GradientStop { + position: 0.2 + color: popup.visible + ? (isLightColorScheme ? hifi.colors.dropDownPressedLight : hifi.colors.dropDownPressedDark) + : (isLightColorScheme ? hifi.colors.dropDownLightStart : hifi.colors.dropDownDarkStart) + } + GradientStop { + position: 1.0 + color: popup.visible + ? (isLightColorScheme ? hifi.colors.dropDownPressedLight : hifi.colors.dropDownPressedDark) + : (isLightColorScheme ? hifi.colors.dropDownLightFinish : hifi.colors.dropDownDarkFinish) + } + } + anchors.fill: parent + } + + SystemPalette { id: palette } + + ComboBox { + id: comboBox + anchors.fill: parent + visible: false + height: hifi.fontSizes.textFieldInput + 13 // Match height of TextField control. + } + + FiraSansSemiBold { + id: textField + anchors { + left: parent.left + leftMargin: hifi.dimensions.textPadding + right: dropIcon.left + verticalCenter: parent.verticalCenter + } + size: hifi.fontSizes.textFieldInput + text: comboBox.currentText + elide: Text.ElideRight + color: controlHover.containsMouse || popup.visible ? hifi.colors.baseGray : (isLightColorScheme ? hifi.colors.lightGray : hifi.colors.lightGrayText ) + } + + Item { + id: dropIcon + anchors { right: parent.right; verticalCenter: parent.verticalCenter } + height: background.height + width: height + Rectangle { + width: 1 + height: parent.height + anchors.top: parent.top + anchors.left: parent.left + color: isLightColorScheme ? hifi.colors.faintGray : hifi.colors.baseGray + } + HiFiGlyphs { + anchors { + top: parent.top + topMargin: -11 + horizontalCenter: parent.horizontalCenter + } + size: hifi.dimensions.spinnerSize + text: hifi.glyphs.caratDn + color: controlHover.containsMouse || popup.visible ? hifi.colors.baseGray : (isLightColorScheme ? hifi.colors.lightGray : hifi.colors.lightGrayText) + } + } + + MouseArea { + id: controlHover + hoverEnabled: true + anchors.fill: parent + onClicked: toggleList(); + } + + function toggleList() { + if (popup.visible) { + hideList(); + } else { + showList(); + } + } + + function showList() { + var r; + if (isDesktop) { + r = desktop.mapFromItem(root, 0, 0, root.width, root.height); + } else { + r = mapFromItem(root, 0, 0, root.width, root.height); + } + var y = r.y + r.height; + var bottom = y + scrollView.height; + var height = isDesktop ? desktop.height : tabletRoot.height; + if (bottom > height) { + y -= bottom - height + 8; + } + scrollView.x = r.x; + scrollView.y = y; + popup.visible = true; + popup.forceActiveFocus(); + listView.currentIndex = root.currentIndex; + scrollView.hoverEnabled = true; + } + + function hideList() { + popup.visible = false; + scrollView.hoverEnabled = false; + root.accepted(); + } + + FocusScope { + id: popup + parent: isDesktop ? desktop : root + anchors.fill: parent + z: isDesktop ? desktop.zLevels.menu : 12 + visible: false + focus: true + + MouseArea { + anchors.fill: parent + onClicked: hideList(); + } + + function previousItem() { listView.currentIndex = (listView.currentIndex + listView.count - 1) % listView.count; } + function nextItem() { listView.currentIndex = (listView.currentIndex + listView.count + 1) % listView.count; } + function selectCurrentItem() { root.currentIndex = listView.currentIndex; hideList(); } + function selectSpecificItem(index) { root.currentIndex = index; hideList(); } + + Keys.onUpPressed: previousItem(); + Keys.onDownPressed: nextItem(); + Keys.onSpacePressed: selectCurrentItem(); + Keys.onRightPressed: selectCurrentItem(); + Keys.onReturnPressed: selectCurrentItem(); + Keys.onEscapePressed: hideList(); + + ScrollView { + id: scrollView + height: root.dropdownHeight + width: root.width + 4 + property bool hoverEnabled: false; + + style: ScrollViewStyle { + decrementControl: Item { + visible: false + } + incrementControl: Item { + visible: false + } + scrollBarBackground: Rectangle{ + implicitWidth: 20 + color: hifi.colors.baseGray + } + + handle: + Rectangle { + implicitWidth: 16 + anchors.left: parent.left + anchors.leftMargin: 3 + anchors.top: parent.top + anchors.bottom: parent.bottom + radius: 6 + color: hifi.colors.lightGrayText + } + } + + ListView { + id: listView + height: textField.height * count * 1.4 + model: root.model + delegate: Rectangle { + width: root.width + 4 + height: popupText.implicitHeight * 1.4 + color: (listView.currentIndex === index) ? hifi.colors.primaryHighlight : + (isLightColorScheme ? hifi.colors.dropDownPressedLight : hifi.colors.dropDownPressedDark) + FiraSansSemiBold { + anchors.left: parent.left + anchors.leftMargin: hifi.dimensions.textPadding + anchors.verticalCenter: parent.verticalCenter + id: popupText + text: listView.model[index] ? listView.model[index] : (listView.model.get && listView.model.get(index).text ? listView.model.get(index).text : "") + size: hifi.fontSizes.textFieldInput + color: hifi.colors.baseGray + } + MouseArea { + id: popupHover + anchors.fill: parent; + hoverEnabled: scrollView.hoverEnabled; + onEntered: listView.currentIndex = index; + onClicked: popup.selectSpecificItem(index); + } + } + } + } + } + + HifiControls.Label { + id: comboBoxLabel + text: root.label + colorScheme: root.colorScheme + anchors.left: parent.left + anchors.bottom: parent.top + anchors.bottomMargin: 4 + visible: label != "" + } + + Component.onCompleted: { + isDesktop = (typeof desktop !== "undefined"); + } +} diff --git a/scripts/developer/utilities/lib/hifi-qml/controls-uit/ConfigSlider.qml b/scripts/developer/utilities/lib/hifi-qml/controls-uit/ConfigSlider.qml new file mode 100644 index 0000000000..9c38b66ed8 --- /dev/null +++ b/scripts/developer/utilities/lib/hifi-qml/controls-uit/ConfigSlider.qml @@ -0,0 +1,72 @@ +// +// ConfigSlider.qml +// examples/utilities/tools/render +// +// Created by Zach Pomerantz on 2/8/2016 +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html +// + +import QtQuick 2.5 +import QtQuick.Controls 1.4 as Original +import QtQuick.Controls.Styles 1.4 + +import "../styles-uit" +import "../controls-uit" as HifiControls + +Item { + id: root + width: 400 + height: 24 + property bool integral: false + property var config + property string property + property alias label: labelControl.text + property alias min: sliderControl.minimumValue + property alias max: sliderControl.maximumValue + + Component.onCompleted: { + // Binding favors qml value, so set it first + sliderControl.value = root.config[root.property]; + bindingControl.when = true; + } + + HifiControls.Label { + id: labelControl + text: root.label + anchors.left: root.left + anchors.leftMargin: 8 + anchors.top: root.top + anchors.topMargin: 7 + } + + HifiControls.Label { + id: labelValue + text: sliderControl.value.toFixed(root.integral ? 0 : 2) + anchors.right: root.right + anchors.rightMargin: 8 + anchors.top: root.top + anchors.topMargin: 15 + } + + Binding { + id: bindingControl + target: root.config + property: root.property + value: sliderControl.value + when: false + } + + HifiControls.Slider { + id: sliderControl + stepSize: root.integral ? 1.0 : 0.0 + width: root.width-130 + height: 20 + anchors.right: root.right + anchors.rightMargin: 8 + anchors.top: root.top + anchors.topMargin: 3 + } +} diff --git a/scripts/developer/utilities/lib/hifi-qml/controls-uit/ContentSection.qml b/scripts/developer/utilities/lib/hifi-qml/controls-uit/ContentSection.qml new file mode 100644 index 0000000000..47a13e9262 --- /dev/null +++ b/scripts/developer/utilities/lib/hifi-qml/controls-uit/ContentSection.qml @@ -0,0 +1,138 @@ +// +// ContentSection.qml +// +// Created by David Rowe on 16 Feb 2016 +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +import QtQuick 2.5 +import QtGraphicalEffects 1.0 + +import "../styles-uit" + +Column { + property string name: "Content Section" + property bool isFirst: false + property bool isCollapsible: false // Set at creation. + property bool isCollapsed: false + + spacing: 0 // Defer spacing decisions to individual controls. + + anchors { + left: parent.left + leftMargin: hifi.dimensions.contentMargin.x + right: parent.right + rightMargin: hifi.dimensions.contentMargin.x + } + + function toggleCollapsed() { + if (isCollapsible) { + isCollapsed = !isCollapsed; + for (var i = 1; i < children.length; i++) { + children[i].visible = !isCollapsed; + } + } + } + + Item { + id: sectionName + anchors.left: parent.left + anchors.right: parent.right + height: leadingSpace.height + topBar.height + heading.height + bottomBar.height + + Item { + id: leadingSpace + width: 1 + height: isFirst ? 7 : 0 + anchors.top: parent.top + } + + Item { + id: topBar + visible: !isFirst + height: visible ? 2 : 0 + anchors.top: leadingSpace.bottom + + Rectangle { + id: shadow + width: frame.width + height: 1 + color: hifi.colors.baseGrayShadow + x: -hifi.dimensions.contentMargin.x + } + + Rectangle { + width: frame.width + height: 1 + color: hifi.colors.baseGrayHighlight + x: -hifi.dimensions.contentMargin.x + anchors.top: shadow.bottom + } + } + + Item { + id: heading + anchors { + left: parent.left + right: parent.right + top: topBar.bottom + } + height: isCollapsible ? 36 : 28 + + RalewayRegular { + id: title + anchors { + left: parent.left + top: parent.top + topMargin: 12 + } + size: hifi.fontSizes.sectionName + font.capitalization: Font.AllUppercase + text: name + color: hifi.colors.lightGrayText + } + + HiFiGlyphs { + anchors { + top: title.top + topMargin: -9 + right: parent.right + rightMargin: -4 + } + size: hifi.fontSizes.disclosureButton + text: isCollapsed ? hifi.glyphs.disclosureButtonExpand : hifi.glyphs.disclosureButtonCollapse + color: hifi.colors.lightGrayText + visible: isCollapsible + } + + MouseArea { + // Events are propogated so that any active control is defocused. + anchors.fill: parent + propagateComposedEvents: true + onPressed: { + toggleCollapsed(); + mouse.accepted = false; + } + } + } + + LinearGradient { + id: bottomBar + visible: desktop.gradientsSupported && isCollapsible + width: frame.width + height: visible ? 4 : 0 + x: -hifi.dimensions.contentMargin.x + anchors.top: heading.bottom + start: Qt.point(0, 0) + end: Qt.point(0, 4) + gradient: Gradient { + GradientStop { position: 0.0; color: hifi.colors.darkGray } + GradientStop { position: 1.0; color: hifi.colors.baseGray } // Equivalent of darkGray0 over baseGray background. + } + cached: true + } + } +} diff --git a/scripts/developer/utilities/lib/hifi-qml/controls-uit/GlyphButton.qml b/scripts/developer/utilities/lib/hifi-qml/controls-uit/GlyphButton.qml new file mode 100644 index 0000000000..ac353b5a52 --- /dev/null +++ b/scripts/developer/utilities/lib/hifi-qml/controls-uit/GlyphButton.qml @@ -0,0 +1,78 @@ +// +// GlyphButton.qml +// +// Created by Clement on 3/7/16 +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + + +import QtQuick 2.5 +import QtQuick.Controls 1.4 as Original +import QtQuick.Controls.Styles 1.4 + +import "../styles-uit" + +Original.Button { + property int color: 0 + property int colorScheme: hifi.colorSchemes.light + property string glyph: "" + property int size: 32 + + width: 120 + height: 28 + + style: ButtonStyle { + + background: Rectangle { + radius: hifi.buttons.radius + + gradient: Gradient { + GradientStop { + position: 0.2 + color: { + if (!control.enabled) { + hifi.buttons.disabledColorStart[control.colorScheme] + } else if (control.pressed) { + hifi.buttons.pressedColor[control.color] + } else if (control.hovered) { + hifi.buttons.hoveredColor[control.color] + } else { + hifi.buttons.colorStart[control.color] + } + } + } + GradientStop { + position: 1.0 + color: { + if (!control.enabled) { + hifi.buttons.disabledColorFinish[control.colorScheme] + } else if (control.pressed) { + hifi.buttons.pressedColor[control.color] + } else if (control.hovered) { + hifi.buttons.hoveredColor[control.color] + } else { + hifi.buttons.colorFinish[control.color] + } + } + } + } + } + + label: HiFiGlyphs { + color: enabled ? hifi.buttons.textColor[control.color] + : hifi.buttons.disabledTextColor[control.colorScheme] + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + anchors { + // Tweak horizontal alignment so that it looks right. + left: parent.left + leftMargin: -0.5 + } + text: control.glyph + size: control.size + } + } +} diff --git a/scripts/developer/utilities/lib/hifi-qml/controls-uit/HorizontalRule.qml b/scripts/developer/utilities/lib/hifi-qml/controls-uit/HorizontalRule.qml new file mode 100644 index 0000000000..425500f1d4 --- /dev/null +++ b/scripts/developer/utilities/lib/hifi-qml/controls-uit/HorizontalRule.qml @@ -0,0 +1,20 @@ +// +// HorizontalRule.qml +// +// Created by Clement on 7/18/16 +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +import QtQuick 2.5 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 + +Rectangle { + anchors.left: parent.left + anchors.right: parent.right + height: 1 + color: hifi.colors.lightGray +} diff --git a/scripts/developer/utilities/lib/hifi-qml/controls-uit/HorizontalSpacer.qml b/scripts/developer/utilities/lib/hifi-qml/controls-uit/HorizontalSpacer.qml new file mode 100644 index 0000000000..545154ab44 --- /dev/null +++ b/scripts/developer/utilities/lib/hifi-qml/controls-uit/HorizontalSpacer.qml @@ -0,0 +1,21 @@ +// +// HorizontalSpacer.qml +// +// Created by Clement on 7/18/16 +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +import QtQuick 2.5 + +import "../styles-uit" + +Item { + id: root + property alias size: root.width + + width: hifi.dimensions.controlInterlineHeight + height: 1 // Must be non-zero +} diff --git a/scripts/developer/utilities/lib/hifi-qml/controls-uit/Label.qml b/scripts/developer/utilities/lib/hifi-qml/controls-uit/Label.qml new file mode 100644 index 0000000000..330d74fa14 --- /dev/null +++ b/scripts/developer/utilities/lib/hifi-qml/controls-uit/Label.qml @@ -0,0 +1,22 @@ +// +// Label.qml +// +// Created by David Rowe on 26 Feb 2016 +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +import QtQuick 2.5 + +import "../styles-uit" + +RalewaySemiBold { + HifiConstants { id: hifi } + property int colorScheme: hifi.colorSchemes.light + + size: hifi.fontSizes.inputLabel + color: enabled ? (colorScheme == hifi.colorSchemes.light ? hifi.colors.lightGray : hifi.colors.lightGrayText) + : (colorScheme == hifi.colorSchemes.light ? hifi.colors.lightGrayText : hifi.colors.baseGrayHighlight); +} diff --git a/scripts/developer/utilities/lib/hifi-qml/controls-uit/QueuedButton.qml b/scripts/developer/utilities/lib/hifi-qml/controls-uit/QueuedButton.qml new file mode 100644 index 0000000000..36ffbe582f --- /dev/null +++ b/scripts/developer/utilities/lib/hifi-qml/controls-uit/QueuedButton.qml @@ -0,0 +1,43 @@ +// +// QueuedButton.qml +// -- original Button.qml + signal timer workaround --ht +// Created by David Rowe on 16 Feb 2016 +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +import QtQuick 2.5 +import QtQuick.Controls 1.4 as Original +import QtQuick.Controls.Styles 1.4 + +import "../styles-uit" +import "." as HifiControls + +HifiControls.Button { + // FIXME: THIS WORKAROUND MIGRATED/CONSOLIDATED FROM RUNNINGSCRIPTS.QML + + // For some reason trigginer an API that enters + // an internal event loop directly from the button clicked + // trigger below causes the appliction to behave oddly. + // Most likely because the button onClicked handling is never + // completed until the function returns. + // FIXME find a better way of handling the input dialogs that + // doesn't trigger this. + + // NOTE: dialogs that need to use this workaround can connect via + // onQueuedClicked: ... + // instead of: + // onClicked: ... + + signal clickedQueued() + Timer { + id: fromTimer + interval: 5 + repeat: false + running: false + onTriggered: clickedQueued() + } + onClicked: fromTimer.running = true +} diff --git a/scripts/developer/utilities/lib/hifi-qml/controls-uit/RadioButton.qml b/scripts/developer/utilities/lib/hifi-qml/controls-uit/RadioButton.qml new file mode 100644 index 0000000000..ab11ec68b1 --- /dev/null +++ b/scripts/developer/utilities/lib/hifi-qml/controls-uit/RadioButton.qml @@ -0,0 +1,71 @@ +// +// RadioButton.qml +// +// Created by Cain Kilgore on 20th July 2017 +// Copyright 2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +import QtQuick 2.5 +import QtQuick.Controls 1.4 as Original +import QtQuick.Controls.Styles 1.4 + +import "../styles-uit" +import "../controls-uit" as HifiControls + +Original.RadioButton { + id: radioButton + HifiConstants { id: hifi } + + property int colorScheme: hifi.colorSchemes.light + readonly property bool isLightColorScheme: colorScheme == hifi.colorSchemes.light + + readonly property int boxSize: 14 + readonly property int boxRadius: 3 + readonly property int checkSize: 10 + readonly property int checkRadius: 2 + + style: RadioButtonStyle { + indicator: Rectangle { + id: box + width: boxSize + height: boxSize + radius: 7 + gradient: Gradient { + GradientStop { + position: 0.2 + color: pressed || hovered + ? (radioButton.isLightColorScheme ? hifi.colors.checkboxDarkStart : hifi.colors.checkboxLightStart) + : (radioButton.isLightColorScheme ? hifi.colors.checkboxLightStart : hifi.colors.checkboxDarkStart) + } + GradientStop { + position: 1.0 + color: pressed || hovered + ? (radioButton.isLightColorScheme ? hifi.colors.checkboxDarkFinish : hifi.colors.checkboxLightFinish) + : (radioButton.isLightColorScheme ? hifi.colors.checkboxLightFinish : hifi.colors.checkboxDarkFinish) + } + } + + Rectangle { + id: check + width: checkSize + height: checkSize + radius: 7 + anchors.centerIn: parent + color: "#00B4EF" + border.width: 1 + border.color: "#36CDFF" + visible: checked && !pressed || !checked && pressed + } + } + + label: RalewaySemiBold { + text: control.text + size: hifi.fontSizes.inputLabel + color: isLightColorScheme ? hifi.colors.lightGray : hifi.colors.lightGrayText + x: radioButton.boxSize / 2 + } + } +} diff --git a/scripts/developer/utilities/lib/hifi-qml/controls-uit/Separator.qml b/scripts/developer/utilities/lib/hifi-qml/controls-uit/Separator.qml new file mode 100644 index 0000000000..5a775221f6 --- /dev/null +++ b/scripts/developer/utilities/lib/hifi-qml/controls-uit/Separator.qml @@ -0,0 +1,38 @@ +// +// Separator.qml +// +// Created by Zach Fox on 2017-06-06 +// Copyright 2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +import QtQuick 2.5 +import "../styles-uit" + +Item { + // Size + height: 2; + Rectangle { + // Size + width: parent.width; + height: 1; + // Anchors + anchors.left: parent.left; + anchors.bottom: parent.bottom; + anchors.bottomMargin: height; + // Style + color: hifi.colors.baseGrayShadow; + } + Rectangle { + // Size + width: parent.width; + height: 1; + // Anchors + anchors.left: parent.left; + anchors.bottom: parent.bottom; + // Style + color: hifi.colors.baseGrayHighlight; + } +} diff --git a/scripts/developer/utilities/lib/hifi-qml/controls-uit/Slider.qml b/scripts/developer/utilities/lib/hifi-qml/controls-uit/Slider.qml new file mode 100644 index 0000000000..89bae9bcde --- /dev/null +++ b/scripts/developer/utilities/lib/hifi-qml/controls-uit/Slider.qml @@ -0,0 +1,98 @@ +// +// Slider.qml +// +// Created by David Rowe on 27 Feb 2016 +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +import QtQuick 2.5 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 + +import "../styles-uit" +import "../controls-uit" as HifiControls + +Slider { + id: slider + + property int colorScheme: hifi.colorSchemes.light + readonly property bool isLightColorScheme: colorScheme == hifi.colorSchemes.light + property string label: "" + property real controlHeight: height + (sliderLabel.visible ? sliderLabel.height + sliderLabel.anchors.bottomMargin : 0) + + height: hifi.fontSizes.textFieldInput + 14 // Match height of TextField control. + y: sliderLabel.visible ? sliderLabel.height + sliderLabel.anchors.bottomMargin : 0 + + style: SliderStyle { + + groove: Rectangle { + implicitWidth: 50 + implicitHeight: hifi.dimensions.sliderGrooveHeight + radius: height / 2 + color: isLightColorScheme ? hifi.colors.sliderGutterLight : hifi.colors.sliderGutterDark + + Rectangle { + width: parent.height - 2 + height: slider.width * (slider.value - slider.minimumValue) / (slider.maximumValue - slider.minimumValue) - 1 + radius: height / 2 + anchors { + top: parent.top + topMargin: width + 1 + left: parent.left + leftMargin: 1 + } + transformOrigin: Item.TopLeft + rotation: -90 + gradient: Gradient { + GradientStop { position: 0.0; color: hifi.colors.blueAccent } + GradientStop { position: 1.0; color: hifi.colors.primaryHighlight } + } + } + } + + handle: Rectangle { + implicitWidth: hifi.dimensions.sliderHandleSize + implicitHeight: hifi.dimensions.sliderHandleSize + radius: height / 2 + border.width: 1 + border.color: isLightColorScheme ? hifi.colors.sliderBorderLight : hifi.colors.sliderBorderDark + gradient: Gradient { + GradientStop { + position: 0.0 + color: pressed || hovered + ? (isLightColorScheme ? hifi.colors.sliderDarkStart : hifi.colors.sliderLightStart ) + : (isLightColorScheme ? hifi.colors.sliderLightStart : hifi.colors.sliderDarkStart ) + } + GradientStop { + position: 1.0 + color: pressed || hovered + ? (isLightColorScheme ? hifi.colors.sliderDarkFinish : hifi.colors.sliderLightFinish ) + : (isLightColorScheme ? hifi.colors.sliderLightFinish : hifi.colors.sliderDarkFinish ) + } + } + + Rectangle { + height: parent.height - 2 + width: height + radius: height / 2 + anchors.centerIn: parent + color: hifi.colors.transparent + border.width: 1 + border.color: hifi.colors.black + } + } + } + + HifiControls.Label { + id: sliderLabel + text: slider.label + colorScheme: slider.colorScheme + anchors.left: parent.left + anchors.bottom: parent.top + anchors.bottomMargin: 2 + visible: label != "" + } +} diff --git a/scripts/developer/utilities/lib/hifi-qml/controls-uit/SpinBox.qml b/scripts/developer/utilities/lib/hifi-qml/controls-uit/SpinBox.qml new file mode 100644 index 0000000000..a1237d4bc7 --- /dev/null +++ b/scripts/developer/utilities/lib/hifi-qml/controls-uit/SpinBox.qml @@ -0,0 +1,117 @@ +// +// SpinBox.qml +// +// Created by David Rowe on 26 Feb 2016 +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +import QtQuick 2.5 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 + +import "../styles-uit" +import "../controls-uit" as HifiControls + +SpinBox { + id: spinBox + + property int colorScheme: hifi.colorSchemes.light + readonly property bool isLightColorScheme: colorScheme == hifi.colorSchemes.light + property string label: "" + property string labelInside: "" + property color colorLabelInside: hifi.colors.white + property real controlHeight: height + (spinBoxLabel.visible ? spinBoxLabel.height + spinBoxLabel.anchors.bottomMargin : 0) + + FontLoader { id: firaSansSemiBold; source: "../../fonts/FiraSans-SemiBold.ttf"; } + font.family: firaSansSemiBold.name + font.pixelSize: hifi.fontSizes.textFieldInput + height: hifi.fontSizes.textFieldInput + 13 // Match height of TextField control. + + y: spinBoxLabel.visible ? spinBoxLabel.height + spinBoxLabel.anchors.bottomMargin : 0 + + style: SpinBoxStyle { + id: spinStyle + background: Rectangle { + color: isLightColorScheme + ? (spinBox.activeFocus ? hifi.colors.white : hifi.colors.lightGray) + : (spinBox.activeFocus ? hifi.colors.black : hifi.colors.baseGrayShadow) + border.color: spinBoxLabelInside.visible ? spinBoxLabelInside.color : hifi.colors.primaryHighlight + border.width: spinBox.activeFocus ? spinBoxLabelInside.visible ? 2 : 1 : 0 + } + + textColor: isLightColorScheme + ? (spinBox.activeFocus ? hifi.colors.black : hifi.colors.lightGray) + : (spinBox.activeFocus ? hifi.colors.white : hifi.colors.lightGrayText) + selectedTextColor: hifi.colors.black + selectionColor: hifi.colors.primaryHighlight + + horizontalAlignment: Qt.AlignLeft + padding.left: spinBoxLabelInside.visible ? 30 : hifi.dimensions.textPadding + padding.right: hifi.dimensions.spinnerSize + padding.top: 0 + + incrementControl: HiFiGlyphs { + id: incrementButton + text: hifi.glyphs.caratUp + x: 10 + y: 1 + size: hifi.dimensions.spinnerSize + color: styleData.upPressed ? (isLightColorScheme ? hifi.colors.black : hifi.colors.white) : hifi.colors.gray + } + + decrementControl: HiFiGlyphs { + text: hifi.glyphs.caratDn + x: 10 + y: -1 + size: hifi.dimensions.spinnerSize + color: styleData.downPressed ? (isLightColorScheme ? hifi.colors.black : hifi.colors.white) : hifi.colors.gray + } + } + + HifiControls.Label { + id: spinBoxLabel + text: spinBox.label + colorScheme: spinBox.colorScheme + anchors.left: parent.left + anchors.bottom: parent.top + anchors.bottomMargin: 4 + visible: label != "" + } + + HifiControls.Label { + id: spinBoxLabelInside + text: spinBox.labelInside + anchors.left: parent.left + anchors.leftMargin: 10 + font.bold: true + anchors.verticalCenter: parent.verticalCenter + color: spinBox.colorLabelInside + visible: spinBox.labelInside != "" + } + + MouseArea { + anchors.fill: parent + propagateComposedEvents: true + onWheel: { + if(spinBox.activeFocus) + wheel.accepted = false + else + wheel.accepted = true + } + onPressed: { + mouse.accepted = false + } + onReleased: { + mouse.accepted = false + } + onClicked: { + mouse.accepted = false + } + onDoubleClicked: { + mouse.accepted = false + } + } +} diff --git a/scripts/developer/utilities/lib/hifi-qml/controls-uit/Switch.qml b/scripts/developer/utilities/lib/hifi-qml/controls-uit/Switch.qml new file mode 100644 index 0000000000..d54f986717 --- /dev/null +++ b/scripts/developer/utilities/lib/hifi-qml/controls-uit/Switch.qml @@ -0,0 +1,156 @@ +// +// Switch.qml +// +// Created by Zach Fox on 2017-06-06 +// Copyright 2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +import QtQuick 2.5 +import QtQuick.Controls 1.4 as Original +import QtQuick.Controls.Styles 1.4 + +import "../styles-uit" + +Item { + id: rootSwitch; + + property int colorScheme: hifi.colorSchemes.light; + readonly property bool isLightColorScheme: colorScheme == hifi.colorSchemes.light; + property int switchWidth: 70; + readonly property int switchRadius: height/2; + property string labelTextOff: ""; + property string labelGlyphOffText: ""; + property int labelGlyphOffSize: 32; + property string labelTextOn: ""; + property string labelGlyphOnText: ""; + property int labelGlyphOnSize: 32; + property alias checked: originalSwitch.checked; + signal onCheckedChanged; + signal clicked; + + Original.Switch { + id: originalSwitch; + activeFocusOnPress: true; + anchors.top: rootSwitch.top; + anchors.left: rootSwitch.left; + anchors.leftMargin: rootSwitch.width/2 - rootSwitch.switchWidth/2; + onCheckedChanged: rootSwitch.onCheckedChanged(); + onClicked: rootSwitch.clicked(); + + style: SwitchStyle { + + padding { + top: 3; + left: 3; + right: 3; + bottom: 3; + } + + groove: Rectangle { + color: "#252525"; + implicitWidth: rootSwitch.switchWidth; + implicitHeight: rootSwitch.height; + radius: rootSwitch.switchRadius; + } + + handle: Rectangle { + id: switchHandle; + implicitWidth: rootSwitch.height - padding.top - padding.bottom; + implicitHeight: implicitWidth; + radius: implicitWidth/2; + border.color: hifi.colors.lightGrayText; + color: hifi.colors.lightGray; + + MouseArea { + anchors.fill: parent; + hoverEnabled: true; + onEntered: parent.color = hifi.colors.blueHighlight; + onExited: parent.color = hifi.colors.lightGray; + } + } + } + } + + // OFF Label + Item { + anchors.right: originalSwitch.left; + anchors.rightMargin: 10; + anchors.top: rootSwitch.top; + height: rootSwitch.height; + + RalewaySemiBold { + id: labelOff; + text: labelTextOff; + size: hifi.fontSizes.inputLabel; + color: originalSwitch.checked ? hifi.colors.lightGrayText : "#FFFFFF"; + anchors.top: parent.top; + anchors.right: parent.right; + width: paintedWidth; + height: parent.height; + verticalAlignment: Text.AlignVCenter; + } + + HiFiGlyphs { + id: labelGlyphOff; + text: labelGlyphOffText; + size: labelGlyphOffSize; + color: labelOff.color; + anchors.top: parent.top; + anchors.topMargin: 2; + anchors.right: labelOff.left; + anchors.rightMargin: 4; + } + + MouseArea { + anchors.top: parent.top; + anchors.bottom: parent.bottom; + anchors.left: labelGlyphOff.left; + anchors.right: labelOff.right; + onClicked: { + originalSwitch.checked = false; + } + } + } + + // ON Label + Item { + anchors.left: originalSwitch.right; + anchors.leftMargin: 10; + anchors.top: rootSwitch.top; + height: rootSwitch.height; + + RalewaySemiBold { + id: labelOn; + text: labelTextOn; + size: hifi.fontSizes.inputLabel; + color: originalSwitch.checked ? "#FFFFFF" : hifi.colors.lightGrayText; + anchors.top: parent.top; + anchors.left: parent.left; + width: paintedWidth; + height: parent.height; + verticalAlignment: Text.AlignVCenter; + } + + HiFiGlyphs { + id: labelGlyphOn; + text: labelGlyphOnText; + size: labelGlyphOnSize; + color: labelOn.color; + anchors.top: parent.top; + anchors.left: labelOn.right; + } + + MouseArea { + anchors.top: parent.top; + anchors.bottom: parent.bottom; + anchors.left: labelOn.left; + anchors.right: labelGlyphOn.right; + onClicked: { + originalSwitch.checked = true; + } + } + } +} diff --git a/scripts/developer/utilities/lib/hifi-qml/controls-uit/Table.qml b/scripts/developer/utilities/lib/hifi-qml/controls-uit/Table.qml new file mode 100644 index 0000000000..11d1920f95 --- /dev/null +++ b/scripts/developer/utilities/lib/hifi-qml/controls-uit/Table.qml @@ -0,0 +1,179 @@ +// +// Table.qml +// +// Created by David Rowe on 18 Feb 2016 +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +import QtQuick 2.5 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 + +import "../styles-uit" + +TableView { + id: tableView + + property int colorScheme: hifi.colorSchemes.light + readonly property bool isLightColorScheme: colorScheme == hifi.colorSchemes.light + property bool expandSelectedRow: false + property bool centerHeaderText: false + + model: ListModel { } + + headerVisible: false + headerDelegate: Rectangle { + height: hifi.dimensions.tableHeaderHeight + color: isLightColorScheme ? hifi.colors.tableBackgroundLight : hifi.colors.tableBackgroundDark + + RalewayRegular { + id: titleText + text: styleData.value + size: hifi.fontSizes.tableHeading + font.capitalization: Font.AllUppercase + color: hifi.colors.baseGrayHighlight + horizontalAlignment: (centerHeaderText ? Text.AlignHCenter : Text.AlignLeft) + anchors { + left: parent.left + leftMargin: hifi.dimensions.tablePadding + right: parent.right + rightMargin: hifi.dimensions.tablePadding + verticalCenter: parent.verticalCenter + } + } + + HiFiGlyphs { + id: titleSort + text: sortIndicatorOrder == Qt.AscendingOrder ? hifi.glyphs.caratUp : hifi.glyphs.caratDn + color: hifi.colors.darkGray + opacity: 0.6; + size: hifi.fontSizes.tableHeadingIcon + anchors { + left: titleText.right + leftMargin: -hifi.fontSizes.tableHeadingIcon / 3 - (centerHeaderText ? 5 : 0) + right: parent.right + rightMargin: hifi.dimensions.tablePadding + verticalCenter: titleText.verticalCenter + } + visible: sortIndicatorVisible && sortIndicatorColumn === styleData.column + } + + Rectangle { + width: 1 + anchors { + left: parent.left + top: parent.top + topMargin: 1 + bottom: parent.bottom + bottomMargin: 2 + } + color: isLightColorScheme ? hifi.colors.lightGrayText : hifi.colors.baseGrayHighlight + visible: styleData.column > 0 + } + + Rectangle { + height: 1 + anchors { + left: parent.left + right: parent.right + bottom: parent.bottom + } + color: isLightColorScheme ? hifi.colors.lightGrayText : hifi.colors.baseGrayHighlight + } + } + + // Use rectangle to draw border with rounded corners. + frameVisible: false + Rectangle { + color: "#00000000" + anchors { fill: parent; margins: -2 } + border.color: isLightColorScheme ? hifi.colors.lightGrayText : hifi.colors.baseGrayHighlight + border.width: 2 + } + anchors.margins: 2 // Shrink TableView to lie within border. + + backgroundVisible: true + + horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff + verticalScrollBarPolicy: Qt.ScrollBarAsNeeded + + style: TableViewStyle { + // Needed in order for rows to keep displaying rows after end of table entries. + backgroundColor: tableView.isLightColorScheme ? hifi.colors.tableBackgroundLight : hifi.colors.tableBackgroundDark + alternateBackgroundColor: tableView.isLightColorScheme ? hifi.colors.tableRowLightOdd : hifi.colors.tableRowDarkOdd + + padding.top: headerVisible ? hifi.dimensions.tableHeaderHeight: 0 + + handle: Item { + id: scrollbarHandle + implicitWidth: hifi.dimensions.scrollbarHandleWidth + Rectangle { + anchors { + fill: parent + topMargin: 3 + bottomMargin: 3 // "" + leftMargin: 1 // Move it right + rightMargin: -1 // "" + } + radius: hifi.dimensions.scrollbarHandleWidth/2 + color: isLightColorScheme ? hifi.colors.tableScrollHandleLight : hifi.colors.tableScrollHandleDark + } + } + + scrollBarBackground: Item { + implicitWidth: hifi.dimensions.scrollbarBackgroundWidth + Rectangle { + anchors { + fill: parent + margins: -1 // Expand + topMargin: -1 + } + color: isLightColorScheme ? hifi.colors.tableScrollBackgroundLight : hifi.colors.tableScrollBackgroundDark + + // Extend header color above scrollbar background + Rectangle { + anchors { + top: parent.top + topMargin: -hifi.dimensions.tableHeaderHeight + left: parent.left + right: parent.right + } + height: hifi.dimensions.tableHeaderHeight + color: tableView.isLightColorScheme ? hifi.colors.tableBackgroundLight : hifi.colors.tableBackgroundDark + visible: headerVisible + } + Rectangle { + // Extend header bottom border + anchors { + top: parent.top + left: parent.left + right: parent.right + } + height: 1 + color: isLightColorScheme ? hifi.colors.lightGrayText : hifi.colors.baseGrayHighlight + visible: headerVisible + } + } + } + + incrementControl: Item { + visible: false + } + + decrementControl: Item { + visible: false + } + } + + rowDelegate: Rectangle { + height: (styleData.selected && expandSelectedRow ? 1.8 : 1) * hifi.dimensions.tableRowHeight + color: styleData.selected + ? hifi.colors.primaryHighlight + : tableView.isLightColorScheme + ? (styleData.alternate ? hifi.colors.tableRowLightEven : hifi.colors.tableRowLightOdd) + : (styleData.alternate ? hifi.colors.tableRowDarkEven : hifi.colors.tableRowDarkOdd) + } +} diff --git a/scripts/developer/utilities/lib/hifi-qml/controls-uit/VerticalSpacer.qml b/scripts/developer/utilities/lib/hifi-qml/controls-uit/VerticalSpacer.qml new file mode 100644 index 0000000000..2df65f1002 --- /dev/null +++ b/scripts/developer/utilities/lib/hifi-qml/controls-uit/VerticalSpacer.qml @@ -0,0 +1,21 @@ +// +// VerticalSpacer.qml +// +// Created by David Rowe on 16 Feb 2016 +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +import QtQuick 2.5 + +import "../styles-uit" + +Item { + id: root + property alias size: root.height + + width: 1 // Must be non-zero + height: hifi.dimensions.controlInterlineHeight +} diff --git a/scripts/developer/utilities/lib/hifi-qml/styles-uit/AnonymousProRegular.qml b/scripts/developer/utilities/lib/hifi-qml/styles-uit/AnonymousProRegular.qml new file mode 100644 index 0000000000..789689973b --- /dev/null +++ b/scripts/developer/utilities/lib/hifi-qml/styles-uit/AnonymousProRegular.qml @@ -0,0 +1,23 @@ +// +// AnonymousProRegular.qml +// +// Created by David Rowe on 12 Feb 2016 +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +import QtQuick 2.5 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 + +Text { + id: root + FontLoader { id: anonymousProRegular; source: "../../fonts/AnonymousPro-Regular.ttf"; } + property real size: 32 + font.pixelSize: size + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignLeft + font.family: anonymousProRegular.name +} diff --git a/scripts/developer/utilities/lib/hifi-qml/styles-uit/ButtonLabel.qml b/scripts/developer/utilities/lib/hifi-qml/styles-uit/ButtonLabel.qml new file mode 100644 index 0000000000..aade5fb439 --- /dev/null +++ b/scripts/developer/utilities/lib/hifi-qml/styles-uit/ButtonLabel.qml @@ -0,0 +1,18 @@ +// +// ButtonLabel.qml +// +// Created by Clement on 7/18/16 +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +import QtQuick 2.5 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 +import "." + +RalewayBold { + font.pixelSize: hifi.fontSizes.buttonLabel +} diff --git a/scripts/developer/utilities/lib/hifi-qml/styles-uit/FiraSansRegular.qml b/scripts/developer/utilities/lib/hifi-qml/styles-uit/FiraSansRegular.qml new file mode 100644 index 0000000000..4ae0826772 --- /dev/null +++ b/scripts/developer/utilities/lib/hifi-qml/styles-uit/FiraSansRegular.qml @@ -0,0 +1,23 @@ +// +// FiraSansRegular.qml +// +// Created by David Rowe on 12 May 2016 +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +import QtQuick 2.5 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 + +Text { + id: root + FontLoader { id: firaSansRegular; source: "../../fonts/FiraSans-Regular.ttf"; } + property real size: 32 + font.pixelSize: size + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignLeft + font.family: firaSansRegular.name +} diff --git a/scripts/developer/utilities/lib/hifi-qml/styles-uit/FiraSansSemiBold.qml b/scripts/developer/utilities/lib/hifi-qml/styles-uit/FiraSansSemiBold.qml new file mode 100644 index 0000000000..b3f3324090 --- /dev/null +++ b/scripts/developer/utilities/lib/hifi-qml/styles-uit/FiraSansSemiBold.qml @@ -0,0 +1,23 @@ +// +// FiraSansSemiBold.qml +// +// Created by David Rowe on 12 Feb 2016 +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +import QtQuick 2.5 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 + +Text { + id: root + FontLoader { id: firaSansSemiBold; source: pathToFonts + "fonts/FiraSans-SemiBold.ttf"; } + property real size: 32 + font.pixelSize: size + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignLeft + font.family: firaSansSemiBold.name +} diff --git a/scripts/developer/utilities/lib/hifi-qml/styles-uit/FiraSansSemiBold.qmlc b/scripts/developer/utilities/lib/hifi-qml/styles-uit/FiraSansSemiBold.qmlc new file mode 100644 index 0000000000000000000000000000000000000000..62898a891eb53784c3db5fba53a950848e4ef57a GIT binary patch literal 4097 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 literal 0 HcmV?d00001 diff --git a/scripts/developer/utilities/lib/hifi-qml/styles-uit/HifiConstants.qml b/scripts/developer/utilities/lib/hifi-qml/styles-uit/HifiConstants.qml new file mode 100644 index 0000000000..4a26d11128 --- /dev/null +++ b/scripts/developer/utilities/lib/hifi-qml/styles-uit/HifiConstants.qml @@ -0,0 +1,342 @@ +// +// HiFiConstants.qml +// +// Created by Bradley Austin Davis on 28 Apr 2015 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +import QtQuick 2.5 +import QtQuick.Window 2.2 + +Item { + readonly property alias colors: colors + readonly property alias colorSchemes: colorSchemes + readonly property alias dimensions: dimensions + readonly property alias fontSizes: fontSizes + readonly property alias glyphs: glyphs + readonly property alias icons: icons + readonly property alias buttons: buttons + readonly property alias effects: effects + + function glyphForIcon(icon) { + // Translates icon enum to glyph char. + var glyph; + switch (icon) { + case hifi.icons.information: + glyph = hifi.glyphs.info; + break; + case hifi.icons.question: + glyph = hifi.glyphs.question; + break; + case hifi.icons.warning: + glyph = hifi.glyphs.alert; + break; + case hifi.icons.critical: + glyph = hifi.glyphs.error; + break; + case hifi.icons.placemark: + glyph = hifi.glyphs.placemark; + break; + default: + glyph = hifi.glyphs.noIcon; + } + return glyph; + } + + Item { + id: colors + + // Base colors + readonly property color baseGray: "#393939" + readonly property color darkGray: "#121212" + readonly property color baseGrayShadow: "#252525" + readonly property color baseGrayHighlight: "#575757" + readonly property color lightGray: "#6a6a6a" + readonly property color lightGrayText: "#afafaf" + readonly property color faintGray: "#e3e3e3" + readonly property color primaryHighlight: "#00b4ef" + readonly property color blueHighlight: "#00b4ef" + readonly property color blueAccent: "#0093C5" + readonly property color redHighlight: "#EA4C5F" + readonly property color redAccent: "#C62147" + readonly property color greenHighlight: "#1ac567" + readonly property color greenShadow: "#359D85" + readonly property color orangeHighlight: "#FFC49C" + readonly property color orangeAccent: "#FF6309" + readonly property color indigoHighlight: "#C0D2FF" + readonly property color indigoAccent: "#9495FF" + readonly property color magentaHighlight: "#EF93D1" + readonly property color magentaAccent: "#A2277C" + readonly property color checkboxCheckedRed: "#FF0000" + readonly property color checkboxCheckedBorderRed: "#D00000" + readonly property color lightBlueHighlight: "#d6f6ff" + + // Semitransparent + readonly property color darkGray30: "#4d121212" + readonly property color darkGray0: "#00121212" + readonly property color baseGrayShadow60: "#99252525" + readonly property color baseGrayShadow50: "#80252525" + readonly property color baseGrayShadow25: "#40252525" + readonly property color baseGrayHighlight40: "#66575757" + readonly property color baseGrayHighlight15: "#26575757" + readonly property color lightGray50: "#806a6a6a" + readonly property color lightGrayText80: "#ccafafaf" + readonly property color faintGray80: "#cce3e3e3" + readonly property color faintGray50: "#80e3e3e3" + + // Other colors + readonly property color white: "#ffffff" + readonly property color gray: "#808080" + readonly property color black: "#000000" + readonly property color locked: "#252525" + // Semitransparent + readonly property color white50: "#80ffffff" + readonly property color white30: "#4dffffff" + readonly property color white25: "#40ffffff" + readonly property color transparent: "#00ffffff" + + // Control specific colors + readonly property color tableRowLightOdd: "#fafafa" + readonly property color tableRowLightEven: "#eeeeee" // Equivavlent to "#1a575757" over #e3e3e3 background + readonly property color tableRowDarkOdd: "#2e2e2e" // Equivalent to "#80393939" over #404040 background + readonly property color tableRowDarkEven: "#1c1c1c" // Equivalent to "#a6181818" over #404040 background + readonly property color tableBackgroundLight: tableRowLightEven + readonly property color tableBackgroundDark: tableRowDarkEven + readonly property color tableScrollHandleLight: "#DDDDDD" + readonly property color tableScrollHandleDark: "#707070" + readonly property color tableScrollBackgroundLight: tableRowLightOdd + readonly property color tableScrollBackgroundDark: "#323232" + readonly property color checkboxLightStart: "#ffffff" + readonly property color checkboxLightFinish: "#afafaf" + readonly property color checkboxDarkStart: "#7d7d7d" + readonly property color checkboxDarkFinish: "#6b6a6b" + readonly property color checkboxChecked: primaryHighlight + readonly property color checkboxCheckedBorder: "#36cdff" + readonly property color sliderGutterLight: "#d4d4d4" + readonly property color sliderGutterDark: "#252525" + readonly property color sliderBorderLight: "#afafaf" + readonly property color sliderBorderDark: "#7d7d7d" + readonly property color sliderLightStart: "#ffffff" + readonly property color sliderLightFinish: "#afafaf" + readonly property color sliderDarkStart: "#7d7d7d" + readonly property color sliderDarkFinish: "#6b6a6b" + readonly property color dropDownPressedLight: "#d4d4d4" + readonly property color dropDownPressedDark: "#afafaf" + readonly property color dropDownLightStart: "#ffffff" + readonly property color dropDownLightFinish: "#afafaf" + readonly property color dropDownDarkStart: "#7d7d7d" + readonly property color dropDownDarkFinish: "#6b6a6b" + readonly property color textFieldLightBackground: "#d4d4d4" + readonly property color tabBackgroundDark: "#252525" + readonly property color tabBackgroundLight: "#d4d4d4" + } + + Item { + id: colorSchemes + readonly property int light: 0 + readonly property int dark: 1 + } + + Item { + id: dimensions + readonly property bool largeScreen: Screen.width >= 1920 && Screen.height >= 1080 + readonly property real borderRadius: largeScreen ? 7.5 : 5.0 + readonly property real borderWidth: largeScreen ? 2 : 1 + readonly property vector2d contentMargin: Qt.vector2d(21, 21) + readonly property vector2d contentSpacing: Qt.vector2d(11, 14) + readonly property real labelPadding: 40 + readonly property real textPadding: 8 + readonly property real sliderHandleSize: 18 + readonly property real sliderGrooveHeight: 8 + readonly property real frameIconSize: 22 + readonly property real spinnerSize: 50 + readonly property real tablePadding: 12 + readonly property real tableRowHeight: largeScreen ? 26 : 23 + readonly property real tableHeaderHeight: 29 + readonly property vector2d modalDialogMargin: Qt.vector2d(50, 30) + readonly property real modalDialogTitleHeight: 40 + readonly property real controlLineHeight: 28 // Height of spinbox control on 1920 x 1080 monitor + readonly property real controlInterlineHeight: 21 // 75% of controlLineHeight + readonly property vector2d menuPadding: Qt.vector2d(14, 102) + readonly property real scrollbarBackgroundWidth: 18 + readonly property real scrollbarHandleWidth: scrollbarBackgroundWidth - 2 + readonly property real tabletMenuHeader: 90 + } + + Item { + id: fontSizes // In pixels + readonly property real overlayTitle: dimensions.largeScreen ? 18 : 14 + readonly property real tabName: dimensions.largeScreen ? 12 : 10 + readonly property real sectionName: dimensions.largeScreen ? 12 : 10 + readonly property real inputLabel: dimensions.largeScreen ? 14 : 10 + readonly property real textFieldInput: dimensions.largeScreen ? 15 : 12 + readonly property real textFieldInputLabel: dimensions.largeScreen ? 13 : 9 + readonly property real textFieldSearchIcon: dimensions.largeScreen ? 30 : 24 + readonly property real tableHeading: dimensions.largeScreen ? 12 : 10 + readonly property real tableHeadingIcon: dimensions.largeScreen ? 60 : 33 + readonly property real tableText: dimensions.largeScreen ? 15 : 12 + readonly property real buttonLabel: dimensions.largeScreen ? 13 : 9 + readonly property real iconButton: dimensions.largeScreen ? 13 : 9 + readonly property real listItem: dimensions.largeScreen ? 15 : 11 + readonly property real tabularData: dimensions.largeScreen ? 15 : 11 + readonly property real logs: dimensions.largeScreen ? 16 : 12 + readonly property real code: dimensions.largeScreen ? 16 : 12 + readonly property real rootMenu: dimensions.largeScreen ? 15 : 11 + readonly property real rootMenuDisclosure: dimensions.largeScreen ? 20 : 16 + readonly property real menuItem: dimensions.largeScreen ? 15 : 11 + readonly property real shortcutText: dimensions.largeScreen ? 13 : 9 + readonly property real carat: dimensions.largeScreen ? 38 : 30 + readonly property real disclosureButton: dimensions.largeScreen ? 30 : 22 + } + + Item { + id: icons + // Values per OffscreenUi::Icon + readonly property int none: 0 + readonly property int question: 1 + readonly property int information: 2 + readonly property int warning: 3 + readonly property int critical: 4 + readonly property int placemark: 5 + } + + Item { + id: buttons + readonly property int white: 0 + readonly property int blue: 1 + readonly property int red: 2 + readonly property int black: 3 + readonly property var textColor: [ colors.darkGray, colors.white, colors.white, colors.white ] + readonly property var colorStart: [ colors.white, colors.primaryHighlight, "#d42043", "#343434" ] + readonly property var colorFinish: [ colors.lightGrayText, colors.blueAccent, "#94132e", colors.black ] + readonly property var hoveredColor: [ colorStart[white], colorStart[blue], colorStart[red], colorFinish[black] ] + readonly property var pressedColor: [ colorFinish[white], colorFinish[blue], colorFinish[red], colorStart[black] ] + readonly property var disabledColorStart: [ colorStart[white], colors.baseGrayHighlight] + readonly property var disabledColorFinish: [ colorFinish[white], colors.baseGrayShadow] + readonly property var disabledTextColor: [ colors.lightGrayText, colors.baseGrayShadow] + readonly property int radius: 5 + } + + QtObject { + id: effects + readonly property int fadeInDuration: 300 + } + Item { + id: glyphs + readonly property string noIcon: "" + readonly property string hmd: "b" + readonly property string screen: "c" + readonly property string keyboard: "d" + readonly property string handControllers: "e" + readonly property string headphonesMic: "f" + readonly property string gamepad: "g" + readonly property string headphones: "h" + readonly property string mic: "i" + readonly property string upload: "j" + readonly property string script: "k" + readonly property string text: "l" + readonly property string cube: "m" + readonly property string sphere: "n" + readonly property string zone: "o" + readonly property string light: "p" + readonly property string web: "q" + readonly property string web2: "r" + readonly property string edit: "s" + readonly property string market: "t" + readonly property string directory: "u" + readonly property string menu: "v" + readonly property string close: "w" + readonly property string closeInverted: "x" + readonly property string pin: "y" + readonly property string pinInverted: "z" + readonly property string resizeHandle: "A" + readonly property string disclosureExpand: "B" + readonly property string reloadSmall: "a" + readonly property string closeSmall: "C" + readonly property string forward: "D" + readonly property string backward: "E" + readonly property string reload: "F" + readonly property string unmuted: "G" + readonly property string muted: "H" + readonly property string minimize: "I" + readonly property string maximize: "J" + readonly property string maximizeInverted: "K" + readonly property string disclosureButtonExpand: "L" + readonly property string disclosureButtonCollapse: "M" + readonly property string scriptStop: "N" + readonly property string scriptReload: "O" + readonly property string scriptRun: "P" + readonly property string scriptNew: "Q" + readonly property string hifiForum: "2" + readonly property string hifiLogoSmall: "S" + readonly property string avatar1: "T" + readonly property string placemark: "U" + readonly property string box: "V" + readonly property string community: "0" + readonly property string grabHandle: "X" + readonly property string search: "Y" + readonly property string disclosureCollapse: "Z" + readonly property string scriptUpload: "R" + readonly property string code: "W" + readonly property string avatar: "<" + readonly property string arrowsH: ":" + readonly property string arrowsV: ";" + readonly property string arrows: "`" + readonly property string compress: "!" + readonly property string expand: "\"" + readonly property string placemark1: "#" + readonly property string circle: "$" + readonly property string handPointer: "9" + readonly property string plusSquareO: "%" + readonly property string sliders: "&" + readonly property string square: "'" + readonly property string alignCenter: "8" + readonly property string alignJustify: ")" + readonly property string alignLeft: "*" + readonly property string alignRight: "^" + readonly property string bars: "7" + readonly property string circleSlash: "," + readonly property string sync: "()" + readonly property string key: "-" + readonly property string link: "." + readonly property string location: "/" + readonly property string caratR: "3" + readonly property string caratL: "4" + readonly property string caratDn: "5" + readonly property string caratUp: "6" + readonly property string folderLg: ">" + readonly property string folderSm: "?" + readonly property string levelUp: "1" + readonly property string info: "[" + readonly property string question: "]" + readonly property string alert: "+" + readonly property string home: "_" + readonly property string error: "=" + readonly property string settings: "@" + readonly property string trash: "{" + readonly property string objectGroup: "\ue000" + readonly property string cm: "}" + readonly property string msvg79: "~" + readonly property string deg: "\\" + readonly property string px: "|" + readonly property string editPencil: "\ue00d" + readonly property string vol_0: "\ue00e" + readonly property string vol_1: "\ue00f" + readonly property string vol_2: "\ue010" + readonly property string vol_3: "\ue011" + readonly property string vol_4: "\ue012" + readonly property string vol_x_0: "\ue013" + readonly property string vol_x_1: "\ue014" + readonly property string vol_x_2: "\ue015" + readonly property string vol_x_3: "\ue016" + readonly property string vol_x_4: "\ue017" + readonly property string source: "\ue01c" + readonly property string playback_play: "\ue01d" + readonly property string stop_square: "\ue01e" + readonly property string avatarTPose: "\ue01f" + readonly property string lock: "\ue006" + } +} diff --git a/scripts/developer/utilities/lib/hifi-qml/styles-uit/HifiConstants.qmlc b/scripts/developer/utilities/lib/hifi-qml/styles-uit/HifiConstants.qmlc new file mode 100644 index 0000000000000000000000000000000000000000..686f84ad173d629beb11885bdba32232ee46d480 GIT binary patch literal 51320 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 literal 0 HcmV?d00001 diff --git a/scripts/developer/utilities/lib/hifi-qml/styles-uit/ShortcutText.qml b/scripts/developer/utilities/lib/hifi-qml/styles-uit/ShortcutText.qml new file mode 100644 index 0000000000..a3ab351870 --- /dev/null +++ b/scripts/developer/utilities/lib/hifi-qml/styles-uit/ShortcutText.qml @@ -0,0 +1,18 @@ +// +// ShortcutText.qml +// +// Created by Clement on 7/18/16 +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +import QtQuick 2.5 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 +import "." + +RalewayLight { + font.pixelSize: hifi.fontSizes.shortcutText +} diff --git a/scripts/developer/utilities/lib/hifi-qml/styles-uit/TabName.qml b/scripts/developer/utilities/lib/hifi-qml/styles-uit/TabName.qml new file mode 100644 index 0000000000..eb4e790e7e --- /dev/null +++ b/scripts/developer/utilities/lib/hifi-qml/styles-uit/TabName.qml @@ -0,0 +1,19 @@ +// +// TabName.qml +// +// Created by Clement on 7/18/16 +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +import QtQuick 2.5 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 +import "." + +RalewayRegular { + font.pixelSize: hifi.fontSizes.tabName + font.capitalization: Font.AllUppercase +} diff --git a/scripts/developer/utilities/lib/hifi-qml/styles-uit/TextFieldInput.qml b/scripts/developer/utilities/lib/hifi-qml/styles-uit/TextFieldInput.qml new file mode 100644 index 0000000000..010b4d03ad --- /dev/null +++ b/scripts/developer/utilities/lib/hifi-qml/styles-uit/TextFieldInput.qml @@ -0,0 +1,18 @@ +// +// TextFieldInput.qml +// +// Created by Clement on 7/18/16 +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +import QtQuick 2.5 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 +import "." + +FiraSansSemiBold { + font.pixelSize: hifi.fontSizes.textFieldInput +} diff --git a/scripts/developer/utilities/render/deferredLighting.qml b/scripts/developer/utilities/render/deferredLighting.qml index 60929d75c0..1cf88ec5ac 100644 --- a/scripts/developer/utilities/render/deferredLighting.qml +++ b/scripts/developer/utilities/render/deferredLighting.qml @@ -7,215 +7,246 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html // -import QtQuick 2.5 +import QtQuick 2.7 import QtQuick.Controls 1.4 -import "configSlider" +import QtQuick.Layouts 1.3 -Column { - spacing: 8 - property var mainViewTask: Render.getConfig("RenderMainView") - - Row { - spacing: 8 - Column { - spacing: 10 - Repeater { - model: [ - "Unlit:LightingModel:enableUnlit", - "Emissive:LightingModel:enableEmissive", - "Lightmap:LightingModel:enableLightmap", - "Background:LightingModel:enableBackground", - "ssao:AmbientOcclusion:enabled", - "Textures:LightingModel:enableMaterialTexturing" - ] - CheckBox { - text: modelData.split(":")[0] - checked: mainViewTask.getConfig(modelData.split(":")[1])[modelData.split(":")[2]] - onCheckedChanged: { mainViewTask.getConfig(modelData.split(":")[1])[modelData.split(":")[2]] = checked } - } - } - } +import "../lib/hifi-qml/styles-uit" +import "../lib/hifi-qml/controls-uit" as HifiControls +import "../lib/configprop" +Rectangle { + id: render; + HifiConstants { id: hifi;} + color: hifi.colors.baseGray; + property var mainViewTask: Render.getConfig("RenderMainView") - Column { - spacing: 10 - Repeater { - model: [ - "Obscurance:LightingModel:enableObscurance", - "Scattering:LightingModel:enableScattering", - "Diffuse:LightingModel:enableDiffuse", - "Specular:LightingModel:enableSpecular", - "Albedo:LightingModel:enableAlbedo", - "Wireframe:LightingModel:enableWireframe" - ] - CheckBox { - text: modelData.split(":")[0] - checked: mainViewTask.getConfig(modelData.split(":")[1])[modelData.split(":")[2]] - onCheckedChanged: { mainViewTask.getConfig(modelData.split(":")[1])[modelData.split(":")[2]] = checked } - } - } - } - - Column { - spacing: 10 - Repeater { - model: [ - "Ambient:LightingModel:enableAmbientLight", - "Directional:LightingModel:enableDirectionalLight", - "Point:LightingModel:enablePointLight", - "Spot:LightingModel:enableSpotLight", - "Light Contour:LightingModel:showLightContour", - "Zone Stack:DrawZoneStack:enabled", - "Shadow:RenderShadowTask:enabled" - ] - CheckBox { - text: modelData.split(":")[0] - checked: mainViewTask.getConfig(modelData.split(":")[1])[modelData.split(":")[2]] - onCheckedChanged: { mainViewTask.getConfig(modelData.split(":")[1])[modelData.split(":")[2]] = checked } - } - } - } - } Column { - spacing: 10 - Repeater { - model: [ "Tone Mapping Exposure:ToneMapping:exposure:5.0:-5.0" - ] - ConfigSlider { - label: qsTr(modelData.split(":")[0]) - integral: false - config: mainViewTask.getConfig(modelData.split(":")[1]) - property: modelData.split(":")[2] - max: modelData.split(":")[3] - min: modelData.split(":")[4] + spacing: 10 + + Row { + + spacing: 20 + padding: 10 + Column { + spacing: 10 + Repeater { + model: [ + "Unlit:LightingModel:enableUnlit", + "Emissive:LightingModel:enableEmissive", + "Lightmap:LightingModel:enableLightmap", + "Background:LightingModel:enableBackground", + "ssao:AmbientOcclusion:enabled", + "Textures:LightingModel:enableMaterialTexturing" + ] + HifiControls.CheckBox { + boxSize: 20 + text: modelData.split(":")[0] + checked: render.mainViewTask.getConfig(modelData.split(":")[1])[modelData.split(":")[2]] + onCheckedChanged: { render.mainViewTask.getConfig(modelData.split(":")[1])[modelData.split(":")[2]] = checked } + } + } + } + + + Column { + spacing: 10 + Repeater { + model: [ + "Obscurance:LightingModel:enableObscurance", + "Scattering:LightingModel:enableScattering", + "Diffuse:LightingModel:enableDiffuse", + "Specular:LightingModel:enableSpecular", + "Albedo:LightingModel:enableAlbedo", + "Wireframe:LightingModel:enableWireframe" + ] + HifiControls.CheckBox { + boxSize: 20 + text: modelData.split(":")[0] + checked: render.mainViewTask.getConfig(modelData.split(":")[1])[modelData.split(":")[2]] + onCheckedChanged: { render.mainViewTask.getConfig(modelData.split(":")[1])[modelData.split(":")[2]] = checked } + } + } + } + + Column { + spacing: 10 + Repeater { + model: [ + "Ambient:LightingModel:enableAmbientLight", + "Directional:LightingModel:enableDirectionalLight", + "Point:LightingModel:enablePointLight", + "Spot:LightingModel:enableSpotLight", + "Light Contour:LightingModel:showLightContour", + "Zone Stack:DrawZoneStack:enabled", + "Shadow:RenderShadowTask:enabled" + ] + HifiControls.CheckBox { + boxSize: 20 + text: modelData.split(":")[0] + checked: render.mainViewTask.getConfig(modelData.split(":")[1])[modelData.split(":")[2]] + onCheckedChanged: { render.mainViewTask.getConfig(modelData.split(":")[1])[modelData.split(":")[2]] = checked } + } + } } } + Separator {} + Column { + spacing: 10 + Repeater { + model: [ "Tone Mapping Exposure:ToneMapping:exposure:5.0:-5.0" + ] + ConfigSlider { + label: qsTr(modelData.split(":")[0]) + integral: false + config: render.mainViewTask.getConfig(modelData.split(":")[1]) + property: modelData.split(":")[2] + max: modelData.split(":")[3] + min: modelData.split(":")[4] + } + } + Row { + HifiControls.Label { + text: "Tone Mapping Curve" + anchors.left: root.left + } + + HifiControls.ComboBox { + anchors.right: root.right + currentIndex: 1 + model: ListModel { + id: cbItems + ListElement { text: "RGB"; color: "Yellow" } + ListElement { text: "SRGB"; color: "Green" } + ListElement { text: "Reinhard"; color: "Yellow" } + ListElement { text: "Filmic"; color: "White" } + } + width: 200 + onCurrentIndexChanged: { render.mainViewTask.getConfig("ToneMapping")["curve"] = currentIndex } + } + } + } Row { - Label { - text: "Tone Mapping Curve" + id: framebuffer + spacing: 10 + height: 24 + + HifiControls.Label { + text: "Debug Framebuffer" + height: 24 anchors.left: root.left } + + property var config: render.mainViewTask.getConfig("DebugDeferredBuffer") - ComboBox { + function setDebugMode(mode) { + framebuffer.config.enabled = (mode != 0); + framebuffer.config.mode = mode; + } + + HifiControls.ComboBox { + height: 24 anchors.right: root.right - currentIndex: 1 + currentIndex: 0 model: ListModel { - id: cbItems - ListElement { text: "RGB"; color: "Yellow" } - ListElement { text: "SRGB"; color: "Green" } - ListElement { text: "Reinhard"; color: "Yellow" } - ListElement { text: "Filmic"; color: "White" } + id: cbItemsFramebuffer + ListElement { text: "Off"; color: "Yellow" } + ListElement { text: "Depth"; color: "Green" } + ListElement { text: "Albedo"; color: "Yellow" } + ListElement { text: "Normal"; color: "White" } + ListElement { text: "Roughness"; color: "White" } + ListElement { text: "Metallic"; color: "White" } + ListElement { text: "Emissive"; color: "White" } + ListElement { text: "Unlit"; color: "White" } + ListElement { text: "Occlusion"; color: "White" } + ListElement { text: "Lightmap"; color: "White" } + ListElement { text: "Scattering"; color: "White" } + ListElement { text: "Lighting"; color: "White" } + ListElement { text: "Shadow"; color: "White" } + ListElement { text: "Linear Depth"; color: "White" } + ListElement { text: "Half Linear Depth"; color: "White" } + ListElement { text: "Half Normal"; color: "White" } + ListElement { text: "Mid Curvature"; color: "White" } + ListElement { text: "Mid Normal"; color: "White" } + ListElement { text: "Low Curvature"; color: "White" } + ListElement { text: "Low Normal"; color: "White" } + ListElement { text: "Curvature Occlusion"; color: "White" } + ListElement { text: "Debug Scattering"; color: "White" } + ListElement { text: "Ambient Occlusion"; color: "White" } + ListElement { text: "Ambient Occlusion Blurred"; color: "White" } + ListElement { text: "Custom"; color: "White" } } width: 200 - onCurrentIndexChanged: { mainViewTask.getConfig("ToneMapping")["curve"] = currentIndex } + onCurrentIndexChanged: { framebuffer.setDebugMode(currentIndex) } } } - } - Row { - id: framebuffer - spacing: 10 - Label { - text: "Debug Framebuffer" - anchors.left: root.left - } - - property var config: mainViewTask.getConfig("DebugDeferredBuffer") + Separator {} + Row { + spacing: 10 + Column { + spacing: 10 - function setDebugMode(mode) { - framebuffer.config.enabled = (mode != 0); - framebuffer.config.mode = mode; - } + HifiControls.CheckBox { + boxSize: 20 + text: "Opaques" + checked: render.mainViewTask.getConfig("DrawOpaqueBounds")["enabled"] + onCheckedChanged: { render.mainViewTask.getConfig("DrawOpaqueBounds")["enabled"] = checked } + } + HifiControls.CheckBox { + boxSize: 20 + text: "Transparents" + checked: render.mainViewTask.getConfig("DrawTransparentBounds")["enabled"] + onCheckedChanged: { render.mainViewTask.getConfig("DrawTransparentBounds")["enabled"] = checked } + } + HifiControls.CheckBox { + boxSize: 20 + text: "Opaques in Front" + checked: render.mainViewTask.getConfig("DrawOverlayInFrontOpaqueBounds")["enabled"] + onCheckedChanged: { render.mainViewTask.getConfig("DrawOverlayInFrontOpaqueBounds")["enabled"] = checked } + } + HifiControls.CheckBox { + boxSize: 20 + text: "Transparents in Front" + checked: render.mainViewTask.getConfig("DrawOverlayInFrontTransparentBounds")["enabled"] + onCheckedChanged: { render.mainViewTask.getConfig("DrawOverlayInFrontTransparentBounds")["enabled"] = checked } + } + HifiControls.CheckBox { + boxSize: 20 + text: "Opaques in HUD" + checked: render.mainViewTask.getConfig("DrawOverlayHUDOpaqueBounds")["enabled"] + onCheckedChanged: { render.mainViewTask.getConfig("DrawOverlayHUDOpaqueBounds")["enabled"] = checked } + } + HifiControls.CheckBox { + boxSize: 20 + text: "Transparents in HUD" + checked: render.mainViewTask.getConfig("DrawOverlayHUDTransparentBounds")["enabled"] + onCheckedChanged: { render.mainViewTask.getConfig("DrawOverlayHUDTransparentBounds")["enabled"] = checked } + } - ComboBox { - anchors.right: root.right - currentIndex: 0 - model: ListModel { - id: cbItemsFramebuffer - ListElement { text: "Off"; color: "Yellow" } - ListElement { text: "Depth"; color: "Green" } - ListElement { text: "Albedo"; color: "Yellow" } - ListElement { text: "Normal"; color: "White" } - ListElement { text: "Roughness"; color: "White" } - ListElement { text: "Metallic"; color: "White" } - ListElement { text: "Emissive"; color: "White" } - ListElement { text: "Unlit"; color: "White" } - ListElement { text: "Occlusion"; color: "White" } - ListElement { text: "Lightmap"; color: "White" } - ListElement { text: "Scattering"; color: "White" } - ListElement { text: "Lighting"; color: "White" } - ListElement { text: "Shadow"; color: "White" } - ListElement { text: "Linear Depth"; color: "White" } - ListElement { text: "Half Linear Depth"; color: "White" } - ListElement { text: "Half Normal"; color: "White" } - ListElement { text: "Mid Curvature"; color: "White" } - ListElement { text: "Mid Normal"; color: "White" } - ListElement { text: "Low Curvature"; color: "White" } - ListElement { text: "Low Normal"; color: "White" } - ListElement { text: "Curvature Occlusion"; color: "White" } - ListElement { text: "Debug Scattering"; color: "White" } - ListElement { text: "Ambient Occlusion"; color: "White" } - ListElement { text: "Ambient Occlusion Blurred"; color: "White" } - ListElement { text: "Custom"; color: "White" } } - width: 200 - onCurrentIndexChanged: { framebuffer.setDebugMode(currentIndex) } + Column { + spacing: 10 + HifiControls.CheckBox { + boxSize: 20 + text: "Metas" + checked: render.mainViewTask.getConfig("DrawMetaBounds")["enabled"] + onCheckedChanged: { render.mainViewTask.getConfig("DrawMetaBounds")["enabled"] = checked } + } + HifiControls.CheckBox { + boxSize: 20 + text: "Lights" + checked: render.mainViewTask.getConfig("DrawLightBounds")["enabled"] + onCheckedChanged: { render.mainViewTask.getConfig("DrawLightBounds")["enabled"] = checked; } + } + HifiControls.CheckBox { + boxSize: 20 + text: "Zones" + checked: render.mainViewTask.getConfig("DrawZones")["enabled"] + onCheckedChanged: { render.mainViewTask.getConfig("ZoneRenderer")["enabled"] = checked; render.mainViewTask.getConfig("DrawZones")["enabled"] = checked; } + } + } } } - - Row { - Column { - - CheckBox { - text: "Opaques" - checked: mainViewTask.getConfig("DrawOpaqueBounds")["enabled"] - onCheckedChanged: { mainViewTask.getConfig("DrawOpaqueBounds")["enabled"] = checked } - } - CheckBox { - text: "Transparents" - checked: mainViewTask.getConfig("DrawTransparentBounds")["enabled"] - onCheckedChanged: { mainViewTask.getConfig("DrawTransparentBounds")["enabled"] = checked } - } - CheckBox { - text: "Opaques in Front" - checked: mainViewTask.getConfig("DrawOverlayInFrontOpaqueBounds")["enabled"] - onCheckedChanged: { mainViewTask.getConfig("DrawOverlayInFrontOpaqueBounds")["enabled"] = checked } - } - CheckBox { - text: "Transparents in Front" - checked: mainViewTask.getConfig("DrawOverlayInFrontTransparentBounds")["enabled"] - onCheckedChanged: { mainViewTask.getConfig("DrawOverlayInFrontTransparentBounds")["enabled"] = checked } - } - CheckBox { - text: "Opaques in HUD" - checked: mainViewTask.getConfig("DrawOverlayHUDOpaqueBounds")["enabled"] - onCheckedChanged: { mainViewTask.getConfig("DrawOverlayHUDOpaqueBounds")["enabled"] = checked } - } - CheckBox { - text: "Transparents in HUD" - checked: mainViewTask.getConfig("DrawOverlayHUDTransparentBounds")["enabled"] - onCheckedChanged: { mainViewTask.getConfig("DrawOverlayHUDTransparentBounds")["enabled"] = checked } - } - - } - Column { - CheckBox { - text: "Metas" - checked: mainViewTask.getConfig("DrawMetaBounds")["enabled"] - onCheckedChanged: { mainViewTask.getConfig("DrawMetaBounds")["enabled"] = checked } - } - CheckBox { - text: "Lights" - checked: mainViewTask.getConfig("DrawLightBounds")["enabled"] - onCheckedChanged: { mainViewTask.getConfig("DrawLightBounds")["enabled"] = checked; } - } - CheckBox { - text: "Zones" - checked: mainViewTask.getConfig("DrawZones")["enabled"] - onCheckedChanged: { mainViewTask.getConfig("ZoneRenderer")["enabled"] = checked; mainViewTask.getConfig("DrawZones")["enabled"] = checked; } - } - } - } } - diff --git a/scripts/developer/utilities/render/luci.js b/scripts/developer/utilities/render/luci.js new file mode 100644 index 0000000000..3e0beb2181 --- /dev/null +++ b/scripts/developer/utilities/render/luci.js @@ -0,0 +1,98 @@ +"use strict"; + +// +// Luci.js +// tablet-engine app +// +// Copyright 2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +(function() { + var TABLET_BUTTON_NAME = "LUCI"; + var QMLAPP_URL = Script.resolvePath("./deferredLighting.qml"); + + + var onLuciScreen = false; + + function onClicked() { + if (onLuciScreen) { + tablet.gotoHomeScreen(); + } else { + tablet.loadQMLSource(QMLAPP_URL); + } + } + + var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); + var button = tablet.addButton({ + text: TABLET_BUTTON_NAME, + sortOrder: 1 + }); + + var hasEventBridge = false; + + function wireEventBridge(on) { + if (!tablet) { + print("Warning in wireEventBridge(): 'tablet' undefined!"); + return; + } + if (on) { + if (!hasEventBridge) { + tablet.fromQml.connect(fromQml); + hasEventBridge = true; + } + } else { + if (hasEventBridge) { + tablet.fromQml.disconnect(fromQml); + hasEventBridge = false; + } + } + } + + function onScreenChanged(type, url) { + if (url === QMLAPP_URL) { + onLuciScreen = true; + } else { + onLuciScreen = false; + } + + button.editProperties({isActive: onLuciScreen}); + wireEventBridge(onLuciScreen); + } + + function fromQml(message) { + } + + button.clicked.connect(onClicked); + tablet.screenChanged.connect(onScreenChanged); + + var moveDebugCursor = false; + Controller.mousePressEvent.connect(function (e) { + if (e.isMiddleButton) { + moveDebugCursor = true; + setDebugCursor(e.x, e.y); + } + }); + Controller.mouseReleaseEvent.connect(function() { moveDebugCursor = false; }); + Controller.mouseMoveEvent.connect(function (e) { if (moveDebugCursor) setDebugCursor(e.x, e.y); }); + + + Script.scriptEnding.connect(function () { + if (onLuciScreen) { + tablet.gotoHomeScreen(); + } + button.clicked.disconnect(onClicked); + tablet.screenChanged.disconnect(onScreenChanged); + tablet.removeButton(button); + }); + + function setDebugCursor(x, y) { + nx = (x / Window.innerWidth); + ny = 1.0 - ((y) / (Window.innerHeight - 32)); + + Render.getConfig("RenderMainView").getConfig("Antialiasing").debugCursorTexcoord = { x: nx, y: ny }; + } + +}()); \ No newline at end of file From 18287ed45bfa47d68c70412861b752212511d7d1 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 13 Oct 2017 01:06:40 -0700 Subject: [PATCH 034/116] Banging my head against qml... --- .../utilities/lib/configprop/ConfigSlider.qml | 29 ++++++++------- .../hifi-qml/styles-uit/FiraSansSemiBold.qmlc | Bin 4097 -> 0 bytes .../lib/hifi-qml/styles-uit/HiFiGlyphs.qmlc | Bin 4897 -> 0 bytes .../hifi-qml/styles-uit/HifiConstants.qmlc | Bin 51320 -> 0 bytes .../hifi-qml/styles-uit/RalewaySemiBold.qmlc | Bin 4081 -> 0 bytes .../lib/hifi-qml/styles-uit/Separator.qmlc | Bin 6855 -> 0 bytes .../utilities/render/deferredLighting.qml | 35 +++++++++++++++--- 7 files changed, 46 insertions(+), 18 deletions(-) delete mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/FiraSansSemiBold.qmlc delete mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/HiFiGlyphs.qmlc delete mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/HifiConstants.qmlc delete mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/RalewaySemiBold.qmlc delete mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/Separator.qmlc diff --git a/scripts/developer/utilities/lib/configprop/ConfigSlider.qml b/scripts/developer/utilities/lib/configprop/ConfigSlider.qml index 516193b81c..f82b381a2d 100644 --- a/scripts/developer/utilities/lib/configprop/ConfigSlider.qml +++ b/scripts/developer/utilities/lib/configprop/ConfigSlider.qml @@ -9,16 +9,19 @@ // import QtQuick 2.7 -import QtQuick.Controls 1.4 -import QtQuick.Layouts 1.3 +import QtQuick.Controls 1.4 as Original +import QtQuick.Controls.Styles 1.4 import "../hifi-qml/styles-uit" import "../hifi-qml/controls-uit" as HifiControls Item { + HifiConstants { id: luci } id: root - width: 400 + + anchors.left: parent.left + anchors.right: parent.right height: 24 property bool integral: false property var config @@ -36,19 +39,19 @@ Item { HifiControls.Label { id: labelControl text: root.label + enabled: true anchors.left: root.left - anchors.leftMargin: 8 - anchors.top: root.top - anchors.topMargin: 7 + anchors.right: root.horizontalCenter + anchors.verticalCenter: root.verticalCenter + //anchors.topMargin: 7 } HifiControls.Label { id: labelValue text: sliderControl.value.toFixed(root.integral ? 0 : 2) anchors.right: root.right - anchors.rightMargin: 8 - anchors.top: root.top - anchors.topMargin: 15 + anchors.bottom: root.bottom + anchors.bottomMargin: 0 } Binding { @@ -62,11 +65,11 @@ Item { HifiControls.Slider { id: sliderControl stepSize: root.integral ? 1.0 : 0.0 - width: root.width-130 - height: 20 + //height: 20 + anchors.left: root.horizontalCenter anchors.right: root.right - anchors.rightMargin: 8 + anchors.rightMargin: 0 anchors.top: root.top - anchors.topMargin: 3 + anchors.topMargin: 0 } } diff --git a/scripts/developer/utilities/lib/hifi-qml/styles-uit/FiraSansSemiBold.qmlc b/scripts/developer/utilities/lib/hifi-qml/styles-uit/FiraSansSemiBold.qmlc deleted file mode 100644 index 62898a891eb53784c3db5fba53a950848e4ef57a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4097 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 diff --git a/scripts/developer/utilities/lib/hifi-qml/styles-uit/HifiConstants.qmlc b/scripts/developer/utilities/lib/hifi-qml/styles-uit/HifiConstants.qmlc deleted file mode 100644 index 686f84ad173d629beb11885bdba32232ee46d480..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51320 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 diff --git a/scripts/developer/utilities/render/deferredLighting.qml b/scripts/developer/utilities/render/deferredLighting.qml index 1cf88ec5ac..7ab7342605 100644 --- a/scripts/developer/utilities/render/deferredLighting.qml +++ b/scripts/developer/utilities/render/deferredLighting.qml @@ -16,19 +16,43 @@ import "../lib/hifi-qml/controls-uit" as HifiControls import "../lib/configprop" Rectangle { - id: render; HifiConstants { id: hifi;} + id: render; + anchors.margins: hifi.dimensions.contentMargin.x + color: hifi.colors.baseGray; property var mainViewTask: Render.getConfig("RenderMainView") - + + Row { + anchors.left: parent.left + anchors.right: parent.right + anchors.margins: 10 Column { - spacing: 10 - + padding: 10 + spacing: 5 + + // width: parent.width + anchors.left: parent.left + anchors.right: parent.right + // padding: hifi.dimensions.contentMargin.x + + ConfigSlider { + label: qsTr("ToneMapping") + integral: false + config: render.mainViewTask.getConfig("ToneMapping") + property: "exposure" + max: 2 + min: 0 + + anchors.left: parent.left + anchors.right: parent.right + } + Row { spacing: 20 padding: 10 - Column { + Column { spacing: 10 Repeater { model: [ @@ -249,4 +273,5 @@ Rectangle { } } } + } } From bcbddb7106f83bf9f4176af584b4b6b93a6ebc1e Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Sat, 14 Oct 2017 12:26:21 -0700 Subject: [PATCH 035/116] Fix unix warnings --- interface/src/commerce/Ledger.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/commerce/Ledger.cpp b/interface/src/commerce/Ledger.cpp index 7b48c98e54..904847cb5f 100644 --- a/interface/src/commerce/Ledger.cpp +++ b/interface/src/commerce/Ledger.cpp @@ -227,7 +227,7 @@ void Ledger::updateLocation(const QString& asset_id, const QString location, con auto walletScriptingInterface = DependencyManager::get(); uint walletStatus = walletScriptingInterface->getWalletStatus(); - if (walletStatus != wallet->WALLET_STATUS_READY) { + if (walletStatus != (uint)wallet->WALLET_STATUS_READY) { emit walletScriptingInterface->walletNotSetup(); qDebug(commerce) << "User attempted to update the location of a certificate, but their wallet wasn't ready. Status:" << walletStatus; } else { From 552defb418febefe887f12d65f75b9a1e4394f8c Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Mon, 16 Oct 2017 11:23:34 -0700 Subject: [PATCH 036/116] Change protocol version --- libraries/networking/src/udt/PacketHeaders.cpp | 2 +- libraries/networking/src/udt/PacketHeaders.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index 2f3f65c90b..1a9f93d255 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -30,7 +30,7 @@ PacketVersion versionForPacketType(PacketType packetType) { case PacketType::EntityEdit: case PacketType::EntityData: case PacketType::EntityPhysics: - return VERSION_ENTITIES_HAS_CERTIFICATE_PROPERTIES; + return VERSION_ENTITIES_HAS_DYNAMIC_OWNERSHIP_TESTS; case PacketType::EntityQuery: return static_cast(EntityQueryPacketVersion::JSONFilterWithFamilyTree); case PacketType::AvatarIdentity: diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index 122be60870..da29372a40 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -268,6 +268,7 @@ const PacketVersion VERSION_ENTITIES_HAS_SHOULD_HIGHLIGHT = 71; const PacketVersion VERSION_ENTITIES_HAS_HIGHLIGHT_SCRIPTING_INTERFACE = 72; const PacketVersion VERSION_ENTITIES_ANIMATION_ALLOW_TRANSLATION_PROPERTIES = 73; const PacketVersion VERSION_ENTITIES_HAS_CERTIFICATE_PROPERTIES = 74; +const PacketVersion VERSION_ENTITIES_HAS_DYNAMIC_OWNERSHIP_TESTS = 75; enum class EntityQueryPacketVersion: PacketVersion { JSONFilter = 18, From 960f1fbfe49bbef2f562ed1cd7cf6d6910360f7a Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Mon, 16 Oct 2017 13:28:14 -0700 Subject: [PATCH 037/116] Still broken, but safer --- .../src/entities/EntityServer.cpp | 77 ++++++++++--------- .../octree/OctreeInboundPacketProcessor.cpp | 4 +- libraries/entities/src/EntityTree.cpp | 13 +--- libraries/entities/src/EntityTree.h | 5 -- 4 files changed, 47 insertions(+), 52 deletions(-) diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index ba76bf7f53..d2585aae49 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -452,50 +452,53 @@ void EntityServer::startDynamicDomainVerification() { while (i.hasNext()) { i.next(); - // ZRF FIXME!!! - //if (!tree->findEntityByEntityItemID(i.value())->verifyStaticCertificateProperties()) { - if (false) { - qCDebug(entities) << "During Dynamic Domain Verification, a certified entity with ID" << i.value() << "failed" - << "static certificate verification."; - // Delete the entity if it doesn't pass static certificate verification - tree->deleteEntity(i.value(), true); - tree->insertRecentlyDeletedEntityIDs(i.value()); - } else { + EntityItemPointer entity = tree->findEntityByEntityItemID(i.value()); - QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); - QNetworkRequest networkRequest; - networkRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); - networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); - QUrl requestURL = NetworkingConstants::METAVERSE_SERVER_URL; - requestURL.setPath("/api/v1/commerce/proof_of_purchase_status/location"); - QJsonObject request; - request["certificate_id"] = i.key(); - networkRequest.setUrl(requestURL); + if (entity) { + // ZRF FIXME!!! + //if (!entity->verifyStaticCertificateProperties()) { + if (false) { + qCDebug(entities) << "During Dynamic Domain Verification, a certified entity with ID" << i.value() << "failed" + << "static certificate verification."; + // Delete the entity if it doesn't pass static certificate verification + tree->deleteEntity(i.value(), true); + } else { - QNetworkReply* networkReply = NULL; - networkReply = networkAccessManager.put(networkRequest, QJsonDocument(request).toJson()); + QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); + QNetworkRequest networkRequest; + networkRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); + networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); + QUrl requestURL = NetworkingConstants::METAVERSE_SERVER_URL; + requestURL.setPath("/api/v1/commerce/proof_of_purchase_status/location"); + QJsonObject request; + request["certificate_id"] = i.key(); + networkRequest.setUrl(requestURL); - connect(networkReply, &QNetworkReply::finished, [=]() { - QJsonObject jsonObject = QJsonDocument::fromJson(networkReply->readAll()).object(); - jsonObject = jsonObject["data"].toObject(); + QNetworkReply* networkReply = NULL; + networkReply = networkAccessManager.put(networkRequest, QJsonDocument(request).toJson()); - if (networkReply->error() == QNetworkReply::NoError) { - if (jsonObject["location"].toArray().first().toString() != thisPlaceName) { - qCDebug(entities) << "Entity's cert's place name" << jsonObject["place_name"].toString() - << "isn't the current place name" << thisPlaceName << "; deleting entity" << i.value(); - tree->deleteEntity(i.value(), true); - tree->insertRecentlyDeletedEntityIDs(i.value()); + connect(networkReply, &QNetworkReply::finished, [=]() { + QJsonObject jsonObject = QJsonDocument::fromJson(networkReply->readAll()).object(); + jsonObject = jsonObject["data"].toObject(); + + if (networkReply->error() == QNetworkReply::NoError) { + if (jsonObject["location"].toArray().first().toString() != thisPlaceName) { + qCDebug(entities) << "Entity's cert's place name" << jsonObject["place_name"].toString() + << "isn't the current place name" << thisPlaceName << "; deleting entity" << i.value(); + tree->deleteEntity(i.value(), true); + } else { + qCDebug(entities) << "Entity passed dynamic domain verification:" << i.value(); + } } else { - qCDebug(entities) << "Entity passed dynamic domain verification:" << i.value(); + qCDebug(entities) << "Call to proof_of_purchase_status endpoint failed; deleting entity" << i.value(); + tree->deleteEntity(i.value(), true); } - } else { - qCDebug(entities) << "Call to proof_of_purchase_status endpoint failed; deleting entity" << i.value(); - tree->deleteEntity(i.value(), true); - tree->insertRecentlyDeletedEntityIDs(i.value()); - } - networkReply->deleteLater(); - }); + networkReply->deleteLater(); + }); + } + } else { + qCWarning(entities) << "During DDV, an entity with ID" << i.value() << "was NOT found in the Entity Tree!"; } } diff --git a/assignment-client/src/octree/OctreeInboundPacketProcessor.cpp b/assignment-client/src/octree/OctreeInboundPacketProcessor.cpp index 2723e8acd5..3f835678ac 100644 --- a/assignment-client/src/octree/OctreeInboundPacketProcessor.cpp +++ b/assignment-client/src/octree/OctreeInboundPacketProcessor.cpp @@ -93,7 +93,9 @@ void OctreeInboundPacketProcessor::processPacket(QSharedPointer PacketType packetType = message->getType(); if (packetType == PacketType::ChallengeOwnership) { - _myServer->getOctree()->processChallengeOwnershipPacket(*message, sendingNode); + _myServer->getOctree()->withWriteLock([&] { + _myServer->getOctree()->processChallengeOwnershipPacket(*message, sendingNode); + }); } else if (_myServer->getOctree()->handlesEditPacketType(packetType)) { PerformanceWarning warn(debugProcessPacket, "processPacket KNOWN TYPE", debugProcessPacket); _receivedPacketCount++; diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 3e63c94c87..5bd56eba50 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1139,7 +1139,6 @@ void EntityTree::startChallengeOwnershipTimer(const EntityItemID& entityItemID) connect(_challengeOwnershipTimeoutTimer, &QTimer::timeout, this, [=]() { qCDebug(entities) << "Ownership challenge timed out, deleting entity" << entityItemID; deleteEntity(entityItemID, true); - insertRecentlyDeletedEntityIDs(entityItemID); if (_challengeOwnershipTimeoutTimer) { _challengeOwnershipTimeoutTimer->stop(); _challengeOwnershipTimeoutTimer->deleteLater(); @@ -1174,13 +1173,16 @@ QByteArray EntityTree::computeEncryptedNonce(const QString& certID, const QStrin const int encryptStatus = RSA_public_encrypt(textLength, text, reinterpret_cast(encryptedText.data()), rsa, RSA_PKCS1_OAEP_PADDING); RSA_free(rsa); if (encryptStatus == -1) { - qCWarning(entities) << "Unable to compute encrypted nonce for" << certID; + long error = ERR_get_error(); + const char* error_str = ERR_error_string(error, NULL); + qCWarning(entities) << "Unable to compute encrypted nonce for" << certID << "\nRSA error:" << error_str; return ""; } QWriteLocker locker(&_certNonceMapLock); _certNonceMap.insert(certID, nonce); + qCDebug(entities) << "Challenging ownership of Cert ID" << certID << "by encrypting and sending nonce" << nonce << "to owner."; return encryptedText; } else { return ""; @@ -1201,7 +1203,6 @@ bool EntityTree::verifyDecryptedNonce(const QString& certID, const QString& decr qCDebug(entities) << "Ownership challenge for Cert ID" << certID << "failed; deleting entity" << id << "\nActual nonce:" << actualNonce << "\nDecrypted nonce:" << decryptedNonce; deleteEntity(id, true); - insertRecentlyDeletedEntityIDs(id); } } else { qCDebug(entities) << "Ownership challenge for Cert ID" << certID << "succeeded; keeping entity" << id; @@ -1235,16 +1236,13 @@ void EntityTree::validatePop(const QString& certID, const EntityItemID& entityIt if (!jsonObject["invalid_reason"].toString().isEmpty()) { qCDebug(entities) << "invalid_reason not empty, deleting entity" << entityItemID; deleteEntity(entityItemID, true); - insertRecentlyDeletedEntityIDs(entityItemID); } else if (jsonObject["transfer_status"].toArray().first().toString() == "failed") { qCDebug(entities) << "'transfer_status' is 'failed', deleting entity" << entityItemID; deleteEntity(entityItemID, true); - insertRecentlyDeletedEntityIDs(entityItemID); } else if (jsonObject["transfer_status"].toArray().first().toString() == "pending") { if (isRetryingValidation) { qCDebug(entities) << "'transfer_status' is 'pending' after retry, deleting entity" << entityItemID; deleteEntity(entityItemID, true); - insertRecentlyDeletedEntityIDs(entityItemID); } else { if (thread() != QThread::currentThread()) { QMetaObject::invokeMethod(this, "startPendingTransferStatusTimer", @@ -1264,7 +1262,6 @@ void EntityTree::validatePop(const QString& certID, const EntityItemID& entityIt if (encryptedText == "") { qCDebug(entities) << "CRITICAL ERROR: Couldn't compute encrypted nonce. Deleting entity..."; deleteEntity(entityItemID, true); - insertRecentlyDeletedEntityIDs(entityItemID); } else { // 2. Send the encrypted text to the rezzing avatar's node QByteArray certIDByteArray = certID.toUtf8(); @@ -1290,7 +1287,6 @@ void EntityTree::validatePop(const QString& certID, const EntityItemID& entityIt } else { qCDebug(entities) << "Call to proof_of_purchase_status endpoint failed; deleting entity" << entityItemID; deleteEntity(entityItemID, true); - insertRecentlyDeletedEntityIDs(entityItemID); } networkReply->deleteLater(); @@ -1516,7 +1512,6 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c << "static certificate verification."; // Delete the entity we just added if it doesn't pass static certificate verification deleteEntity(entityItemID, true); - insertRecentlyDeletedEntityIDs(entityItemID); } else { validatePop(properties.getCertificateID(), entityItemID, senderNode, false); } diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index b939ff51c1..8d939159ce 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -193,11 +193,6 @@ public: return _recentlyDeletedEntityItemIDs; } - void insertRecentlyDeletedEntityIDs(const EntityItemID& id) { - QWriteLocker locker(&_recentlyDeletedEntitiesLock); - _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), id); - } - QHash getEntityCertificateIDMap() const { QReadLocker locker(&_entityCertificateIDMapLock); return _entityCertificateIDMap; From 3c572b0f7a1d5eeda5654ed9a2a7aef0e644c2ca Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Mon, 16 Oct 2017 13:41:39 -0700 Subject: [PATCH 038/116] Fix deadlock --- libraries/entities/src/EntityTree.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 5bd56eba50..6ccff83fb4 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1191,11 +1191,17 @@ QByteArray EntityTree::computeEncryptedNonce(const QString& certID, const QStrin bool EntityTree::verifyDecryptedNonce(const QString& certID, const QString& decryptedNonce) { - QReadLocker certIdMapLocker(&_entityCertificateIDMapLock); - EntityItemID id = _entityCertificateIDMap.value(certID); + EntityItemID id; + { + QReadLocker certIdMapLocker(&_entityCertificateIDMapLock); + id = _entityCertificateIDMap.value(certID); + } - QWriteLocker locker(&_certNonceMapLock); - QString actualNonce = _certNonceMap.take(certID).toString(); + QString actualNonce; + { + QWriteLocker locker(&_certNonceMapLock); + actualNonce = _certNonceMap.take(certID).toString(); + } bool verificationSuccess = (actualNonce == decryptedNonce); if (!verificationSuccess) { From a4b8bf0be60b52ce8ae85d3d4fa2cf5e67e1a8f8 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Mon, 16 Oct 2017 15:33:10 -0700 Subject: [PATCH 039/116] Bugfixes and CR --- .../src/entities/EntityServer.cpp | 1 + assignment-client/src/entities/EntityServer.h | 4 ++-- .../resources/describe-settings.json | 4 ++-- interface/src/commerce/Wallet.cpp | 2 +- libraries/entities/src/EntityTree.cpp | 21 +++++++++++++------ libraries/entities/src/EntityTree.h | 1 - 6 files changed, 21 insertions(+), 12 deletions(-) diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index d2585aae49..d99187adee 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include "AssignmentParentFinder.h" #include "EntityNodeData.h" diff --git a/assignment-client/src/entities/EntityServer.h b/assignment-client/src/entities/EntityServer.h index 408fad4494..bcfeb3485d 100644 --- a/assignment-client/src/entities/EntityServer.h +++ b/assignment-client/src/entities/EntityServer.h @@ -84,9 +84,9 @@ private: QMap> _viewerSendingStats; static const int DEFAULT_MINIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS = 45 * 60 * 1000; // 45m - static const int DEFAULT_MAXIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS = 75 * 60 * 1000; // 1h15m + static const int DEFAULT_MAXIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS = 60 * 60 * 1000; // 1h int _MINIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS = DEFAULT_MINIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS; // 45m - int _MAXIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS = DEFAULT_MAXIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS; // 1h15m + int _MAXIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS = DEFAULT_MAXIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS; // 1h QTimer _dynamicDomainVerificationTimer; void startDynamicDomainVerification(); }; diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index 2b0d032e3c..d8c91f4ce3 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -1266,8 +1266,8 @@ "name": "dynamicDomainVerificationTimeMax", "label": "Dynamic Domain Verification Time (seconds) - Maximum", "help": "The upper limit on the amount of time that passes before Dynamic Domain Verification on entities occurs. Units are seconds.", - "placeholder": "4500", - "default": "4500", + "placeholder": "3600", + "default": "3600", "advanced": true }, { diff --git a/interface/src/commerce/Wallet.cpp b/interface/src/commerce/Wallet.cpp index f7cd0e5919..c7c09d8b03 100644 --- a/interface/src/commerce/Wallet.cpp +++ b/interface/src/commerce/Wallet.cpp @@ -741,7 +741,7 @@ void Wallet::handleChallengeOwnershipPacket(QSharedPointer pack if (decryptionStatus != -1) { auto nodeList = DependencyManager::get(); - QByteArray decryptedTextByteArray = QByteArray(reinterpret_cast(decryptedText), decryptionStatus); + QByteArray decryptedTextByteArray = QByteArray(reinterpret_cast(decryptedText), decryptionStatus); int decryptedTextByteArraySize = decryptedTextByteArray.size(); int certIDSize = certID.size(); // setup the packet diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 6ccff83fb4..57b4c9acc1 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include @@ -1159,18 +1160,23 @@ void EntityTree::startPendingTransferStatusTimer(const QString& certID, const En } QByteArray EntityTree::computeEncryptedNonce(const QString& certID, const QString ownerKey) { - QUuid nonce = QUuid::createUuid(); - const auto text = reinterpret_cast(qPrintable(nonce.toString())); - const unsigned int textLength = nonce.toString().length(); - QString ownerKeyWithHeaders = ("-----BEGIN RSA PUBLIC KEY-----\n" + ownerKey + "\n-----END RSA PUBLIC KEY-----"); BIO* bio = BIO_new_mem_buf((void*)ownerKeyWithHeaders.toUtf8().constData(), -1); BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); // NO NEWLINE RSA* rsa = PEM_read_bio_RSAPublicKey(bio, NULL, NULL, NULL); if (rsa) { + QUuid nonce = QUuid::createUuid(); + const unsigned int textLength = nonce.toString().length(); QByteArray encryptedText(RSA_size(rsa), 0); - const int encryptStatus = RSA_public_encrypt(textLength, text, reinterpret_cast(encryptedText.data()), rsa, RSA_PKCS1_OAEP_PADDING); + const int encryptStatus = RSA_public_encrypt(textLength, + reinterpret_cast(qPrintable(nonce.toString())), + reinterpret_cast(encryptedText.data()), + rsa, + RSA_PKCS1_OAEP_PADDING); + if (bio) { + BIO_free(bio); + } RSA_free(rsa); if (encryptStatus == -1) { long error = ERR_get_error(); @@ -1181,10 +1187,13 @@ QByteArray EntityTree::computeEncryptedNonce(const QString& certID, const QStrin QWriteLocker locker(&_certNonceMapLock); _certNonceMap.insert(certID, nonce); - qCDebug(entities) << "Challenging ownership of Cert ID" << certID << "by encrypting and sending nonce" << nonce << "to owner."; + return encryptedText; } else { + if (bio) { + BIO_free(bio); + } return ""; } } diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 8d939159ce..d6539babe7 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -19,7 +19,6 @@ #include #include #include -#include #include #include From e1b0e5a2dd2a8ec10d005cc23198f7f437c3c825 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Mon, 16 Oct 2017 16:00:32 -0700 Subject: [PATCH 040/116] Move some include files around --- assignment-client/src/entities/EntityServer.cpp | 3 +++ assignment-client/src/entities/EntityServer.h | 1 - libraries/entities/src/EntityEditPacketSender.cpp | 1 + libraries/entities/src/EntityEditPacketSender.h | 2 -- libraries/entities/src/EntityTree.cpp | 4 ++++ libraries/entities/src/EntityTree.h | 5 ----- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index d99187adee..d23cdd593e 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -17,6 +17,9 @@ #include #include #include +#include +#include +#include #include "AssignmentParentFinder.h" #include "EntityNodeData.h" diff --git a/assignment-client/src/entities/EntityServer.h b/assignment-client/src/entities/EntityServer.h index bcfeb3485d..05404b28c8 100644 --- a/assignment-client/src/entities/EntityServer.h +++ b/assignment-client/src/entities/EntityServer.h @@ -19,7 +19,6 @@ #include "EntityItem.h" #include "EntityServerConsts.h" #include "EntityTree.h" -#include /// Handles assignments of type EntityServer - sending entities to various clients. diff --git a/libraries/entities/src/EntityEditPacketSender.cpp b/libraries/entities/src/EntityEditPacketSender.cpp index a629e7908a..e82ed82093 100644 --- a/libraries/entities/src/EntityEditPacketSender.cpp +++ b/libraries/entities/src/EntityEditPacketSender.cpp @@ -18,6 +18,7 @@ #include "EntitiesLogging.h" #include "EntityItem.h" #include "EntityItemProperties.h" +#include EntityEditPacketSender::EntityEditPacketSender() { auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); diff --git a/libraries/entities/src/EntityEditPacketSender.h b/libraries/entities/src/EntityEditPacketSender.h index 4e8a4be13d..bf79bb9203 100644 --- a/libraries/entities/src/EntityEditPacketSender.h +++ b/libraries/entities/src/EntityEditPacketSender.h @@ -19,8 +19,6 @@ #include "EntityItem.h" #include "AvatarData.h" -#include - /// Utility for processing, packing, queueing and sending of outbound edit voxel messages. class EntityEditPacketSender : public OctreeEditPacketSender { Q_OBJECT diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 57b4c9acc1..ba92947a2e 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -18,6 +18,10 @@ #include #include #include +#include "AccountManager.h" +#include +#include +#include #include diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index d6539babe7..922d60f132 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -15,11 +15,6 @@ #include #include -#include "AccountManager.h" -#include -#include -#include - #include #include From eceb0dcc950c4a80783beb42cf472bd5b4de94aa Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 17 Oct 2017 11:29:43 -0700 Subject: [PATCH 041/116] Fix appearance of domain settings page --- domain-server/resources/describe-settings.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index d8c91f4ce3..9dadc6df03 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -217,7 +217,7 @@ }, { "label": "Permissions ?", - "span": 8 + "span": 10 } ], "columns": [ @@ -315,7 +315,7 @@ }, { "label": "Permissions ?", - "span": 8 + "span": 10 } ], "columns": [ @@ -436,7 +436,7 @@ }, { "label": "Permissions ?", - "span": 8 + "span": 10 } ], "columns": [ @@ -550,7 +550,7 @@ }, { "label": "Permissions ?", - "span": 8 + "span": 10 } ], "columns": [ @@ -642,7 +642,7 @@ }, { "label": "Permissions ?", - "span": 8 + "span": 10 } ], "columns": [ @@ -734,7 +734,7 @@ }, { "label": "Permissions ?", - "span": 8 + "span": 10 } ], "columns": [ @@ -826,7 +826,7 @@ }, { "label": "Permissions ?", - "span": 8 + "span": 10 } ], "columns": [ From f3b641a8335a6bf1b9fe8c2fce56a63c64c7476e Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 17 Oct 2017 11:07:40 -0700 Subject: [PATCH 042/116] Edit.js caused a testing fail :( --- scripts/system/edit.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/system/edit.js b/scripts/system/edit.js index d6d4de2a4b..c8e93b229b 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -1561,7 +1561,8 @@ function getPositionToCreateEntity(extra) { } function importSVO(importURL) { - if (!Entities.canRez() && !Entities.canRezTmp()) { + if (!Entities.canRez() && !Entities.canRezTmp() && + !Entities.canRezCertified() && !Entities.canRezTmpCertified()) { Window.notifyEditError(INSUFFICIENT_PERMISSIONS_IMPORT_ERROR_MSG); return; } From 952160874c576ada782bf25c826ea75537e38836 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 18 Oct 2017 11:21:03 -0700 Subject: [PATCH 043/116] Stringmatch Domain ID instead of placename for DVV --- assignment-client/src/entities/EntityServer.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index d23cdd593e..75bdb469a4 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -446,7 +446,7 @@ void EntityServer::domainSettingsRequestFailed() { void EntityServer::startDynamicDomainVerification() { qCDebug(entities) << "Starting Dynamic Domain Verification..."; - QString thisPlaceName = DependencyManager::get()->getPlaceName(); + QString thisDomainID = DependencyManager::get()->getDomainId(); EntityTreePointer tree = std::static_pointer_cast(_tree); QHash localMap(tree->getEntityCertificateIDMap()); @@ -486,9 +486,9 @@ void EntityServer::startDynamicDomainVerification() { jsonObject = jsonObject["data"].toObject(); if (networkReply->error() == QNetworkReply::NoError) { - if (jsonObject["location"].toArray().first().toString() != thisPlaceName) { - qCDebug(entities) << "Entity's cert's place name" << jsonObject["place_name"].toString() - << "isn't the current place name" << thisPlaceName << "; deleting entity" << i.value(); + if (jsonObject["domain_id"].toString() != thisDomainID) { + qCDebug(entities) << "Entity's cert's domain ID" << jsonObject["domain_id"].toString() + << "doesn't match the current Domain ID" << thisDomainID << "; deleting entity" << i.value(); tree->deleteEntity(i.value(), true); } else { qCDebug(entities) << "Entity passed dynamic domain verification:" << i.value(); From 74180bc4cd3026eb331c751014578e1ba2a29f3c Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 19 Oct 2017 15:30:49 -0700 Subject: [PATCH 044/116] Implement static cert verification correctly --- .../src/entities/EntityServer.cpp | 4 +- libraries/entities/src/EntityItem.cpp | 86 +++++++++---------- libraries/entities/src/EntityItem.h | 10 +-- .../entities/src/EntityScriptingInterface.cpp | 15 ---- .../entities/src/EntityScriptingInterface.h | 3 - libraries/entities/src/EntityTree.cpp | 6 +- 6 files changed, 49 insertions(+), 75 deletions(-) diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index 75bdb469a4..1351220714 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -459,9 +459,7 @@ void EntityServer::startDynamicDomainVerification() { EntityItemPointer entity = tree->findEntityByEntityItemID(i.value()); if (entity) { - // ZRF FIXME!!! - //if (!entity->verifyStaticCertificateProperties()) { - if (false) { + if (!entity->verifyStaticCertificateProperties()) { qCDebug(entities) << "During Dynamic Domain Verification, a certified entity with ID" << i.value() << "failed" << "static certificate verification."; // Delete the entity if it doesn't pass static certificate verification diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 58b8dd22bf..3074bd275b 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -14,9 +14,13 @@ #include #include #include -#include // see comments for DEBUG_CERT +#include #include #include +#include +#include +#include +#include #include @@ -41,6 +45,7 @@ int entityItemPointernMetaTypeId = qRegisterMetaType(); int EntityItem::_maxActionsDataSize = 800; quint64 EntityItem::_rememberDeletedActionTime = 20 * USECS_PER_SECOND; +QString EntityItem::_marketplacePublicKey; EntityItem::EntityItem(const EntityItemID& entityItemID) : SpatiallyNestable(NestableType::Entity, entityItemID) @@ -1588,16 +1593,16 @@ QByteArray EntityItem::getStaticCertificateJSON() const { // It is important that this be reproducible in the same order each time. Since we also generate these on the server, we do it alphabetically // to help maintainence in two different code bases. if (!propertySet.getAnimation().getURL().isEmpty()) { - json["animation.url"] = propertySet.getAnimation().getURL(); + json["animationURL"] = propertySet.getAnimation().getURL(); } ADD_STRING_PROPERTY(collisionSoundURL, CollisionSoundURL); ADD_STRING_PROPERTY(compoundShapeURL, CompoundShapeURL); ADD_INT_PROPERTY(editionNumber, EditionNumber); - ADD_INT_PROPERTY(entityInstanceNumber, EntityInstanceNumber); + ADD_INT_PROPERTY(instanceNumber, EntityInstanceNumber); ADD_STRING_PROPERTY(itemArtist, ItemArtist); ADD_STRING_PROPERTY(itemCategories, ItemCategories); ADD_STRING_PROPERTY(itemDescription, ItemDescription); - ADD_STRING_PROPERTY(itemLicense, ItemLicense); + ADD_STRING_PROPERTY(itemLicenseUrl, ItemLicense); ADD_STRING_PROPERTY(itemName, ItemName); ADD_INT_PROPERTY(limitedRun, LimitedRun); ADD_STRING_PROPERTY(marketplaceID, MarketplaceID); @@ -1612,39 +1617,6 @@ QByteArray EntityItem::getStaticCertificateHash() const { return QCryptographicHash::hash(getStaticCertificateJSON(), QCryptographicHash::Sha256); } -#ifdef DEBUG_CERT -QString EntityItem::computeCertificateID() { - // Until the marketplace generates it, compute and answer the certificateID here. - // Does not set it, as that will have to be done from script engine in order to update server, etc. - const auto hash = getStaticCertificateHash(); - const auto text = reinterpret_cast(hash.constData()); - const unsigned int textLength = hash.length(); - - const char privateKey[] = "-----BEGIN RSA PRIVATE KEY-----\n\ -MIIBOQIBAAJBALCoBiDAZOClO26tC5pd7JikBL61WIgpAqbcNnrV/TcG6LPI7Zbi\n\ -MjdUixmTNvYMRZH3Wlqtl2IKG1W68y3stKECAwEAAQJABvOlwhYwIhL+gr12jm2R\n\ -yPPzZ9nVEQ6kFxLlZfIT09119fd6OU1X5d4sHWfMfSIEgjwQIDS3ZU1kY3XKo87X\n\ -zQIhAOPHlYa1OC7BLhaTouy68qIU2vCKLP8mt4S31/TT0UOnAiEAxor6gU6yupTQ\n\ -yuyV3yHvr5LkZKBGqhjmOTmDfgtX7ncCIChGbgX3nQuHVOLhD/nTxHssPNozVGl5\n\ -KxHof+LmYSYZAiB4U+yEh9SsXdq40W/3fpLMPuNq1PRezJ5jGidGMcvF+wIgUNec\n\ -3Kg2U+CVZr8/bDT/vXRrsKj1zfobYuvbfVH02QY=\n\ ------END RSA PRIVATE KEY-----"; - BIO* bio = BIO_new_mem_buf((void*)privateKey, sizeof(privateKey)); - RSA* rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL); - - QByteArray signature(RSA_size(rsa), 0); - unsigned int signatureLength = 0; - const int signOK = RSA_sign(NID_sha256, text, textLength, reinterpret_cast(signature.data()), &signatureLength, rsa); - BIO_free(bio); - RSA_free(rsa); - if (!signOK) { - qCWarning(entities) << "Unable to compute signature for" << getName() << getEntityItemID(); - return ""; - } - return signature.toBase64(); -#endif -} - bool EntityItem::verifyStaticCertificateProperties() { // True IIF a non-empty certificateID matches the static certificate json. // I.e., if we can verify that the certificateID was produced by High Fidelity signing the static certificate hash. @@ -1659,13 +1631,8 @@ bool EntityItem::verifyStaticCertificateProperties() { const auto hash = getStaticCertificateHash(); const auto text = reinterpret_cast(hash.constData()); const unsigned int textLength = hash.length(); - - // After DEBUG_CERT ends, we will get/cache this once from the marketplace when needed, and it likely won't be RSA. - const char publicKey[] = "-----BEGIN PUBLIC KEY-----\n\ -MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALCoBiDAZOClO26tC5pd7JikBL61WIgp\n\ -AqbcNnrV/TcG6LPI7ZbiMjdUixmTNvYMRZH3Wlqtl2IKG1W68y3stKECAwEAAQ==\n\ ------END PUBLIC KEY-----"; - BIO *bio = BIO_new_mem_buf((void*)publicKey, sizeof(publicKey)); + + BIO *bio = BIO_new_mem_buf((void*)qPrintable(EntityItem::_marketplacePublicKey), -1); EVP_PKEY* evp_key = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL); RSA* rsa = EVP_PKEY_get1_RSA(evp_key); bool answer = RSA_verify(NID_sha256, text, textLength, signature, signatureLength, rsa); @@ -3006,3 +2973,34 @@ void EntityItem::somethingChangedNotification() { } }); } + +void EntityItem::retrieveMarketplacePublicKey() { + QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); + QNetworkRequest networkRequest; + networkRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); + QUrl requestURL = NetworkingConstants::METAVERSE_SERVER_URL; + requestURL.setPath("/api/v1/commerce/marketplace_key"); + QJsonObject request; + networkRequest.setUrl(requestURL); + + QNetworkReply* networkReply = NULL; + networkReply = networkAccessManager.get(networkRequest); + + connect(networkReply, &QNetworkReply::finished, [=]() { + QJsonObject jsonObject = QJsonDocument::fromJson(networkReply->readAll()).object(); + jsonObject = jsonObject["data"].toObject(); + + if (networkReply->error() == QNetworkReply::NoError) { + if (!jsonObject["public_key"].toString().isEmpty()) { + EntityItem::_marketplacePublicKey = jsonObject["public_key"].toString(); + qCWarning(entities) << "Marketplace public key has been set to" << _marketplacePublicKey; + } else { + qCWarning(entities) << "Marketplace public key is empty!"; + } + } else { + qCWarning(entities) << "Call to" << networkRequest.url() << "failed! Error:" << networkReply->error(); + } + + networkReply->deleteLater(); + }); +} diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index c26f1694a9..ce39bbce8e 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -36,9 +36,6 @@ #include "SimulationFlags.h" #include "EntityDynamicInterface.h" -// FIXME: The server-side marketplace will soon create the certificateID. At that point, all of the DEBUG_CERT stuff will go away. -#define DEBUG_CERT 1 - class EntitySimulation; class EntityTreeElement; class EntityTreeElementExtraEncodeData; @@ -331,9 +328,6 @@ public: QByteArray getStaticCertificateJSON() const; QByteArray getStaticCertificateHash() const; bool verifyStaticCertificateProperties(); -#ifdef DEBUG_CERT - QString computeCertificateID(); -#endif // TODO: get rid of users of getRadius()... float getRadius() const; @@ -484,6 +478,9 @@ public: ChangeHandlerId registerChangeHandler(const ChangeHandlerCallback& handler); void deregisterChangeHandler(const ChangeHandlerId& changeHandlerId); + static QString _marketplacePublicKey; + static void retrieveMarketplacePublicKey(); + protected: QHash _changeHandlers; @@ -635,7 +632,6 @@ protected: quint64 _lastUpdatedVelocityTimestamp { 0 }; quint64 _lastUpdatedAngularVelocityTimestamp { 0 }; quint64 _lastUpdatedAccelerationTimestamp { 0 }; - }; #endif // hifi_EntityItem_h diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index f5117dddc0..66a64db15e 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -1778,18 +1778,3 @@ bool EntityScriptingInterface::verifyStaticCertificateProperties(const QUuid& en } return result; } - -#ifdef DEBUG_CERT -QString EntityScriptingInterface::computeCertificateID(const QUuid& entityID) { - QString result { "" }; - if (_entityTree) { - _entityTree->withReadLock([&] { - EntityItemPointer entity = _entityTree->findEntityByEntityItemID(EntityItemID(entityID)); - if (entity) { - result = entity->computeCertificateID(); - } - }); - } - return result; -} -#endif \ No newline at end of file diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index 989d3dd89d..2dc31dbe7d 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -387,9 +387,6 @@ public slots: Q_INVOKABLE glm::mat4 getEntityLocalTransform(const QUuid& entityID); Q_INVOKABLE bool verifyStaticCertificateProperties(const QUuid& entityID); -#ifdef DEBUG_CERT - Q_INVOKABLE QString computeCertificateID(const QUuid& entityID); -#endif signals: void collisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision); diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index ba92947a2e..f8db876728 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -71,6 +71,8 @@ EntityTree::EntityTree(bool shouldReaverage) : Octree(shouldReaverage) { resetClientEditStats(); + + EntityItem::retrieveMarketplacePublicKey(); } EntityTree::~EntityTree() { @@ -1523,9 +1525,7 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c _totalCreates++; if (newEntity && isCertified && getIsServer()) { - // ZRF FIXME!!! - //if (!newEntity->verifyStaticCertificateProperties()) { - if (false) { + if (!newEntity->verifyStaticCertificateProperties()) { qCDebug(entities) << "User" << senderNode->getUUID() << "attempted to add a certified entity with ID" << entityItemID << "which failed" << "static certificate verification."; From 8976961bfb68b7c57e91b7b48ecd158253d9ac10 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 19 Oct 2017 16:27:39 -0700 Subject: [PATCH 045/116] add build config to draco install dir --- cmake/externals/draco/CMakeLists.txt | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/cmake/externals/draco/CMakeLists.txt b/cmake/externals/draco/CMakeLists.txt index 44ddd6d3de..6a894e76b6 100644 --- a/cmake/externals/draco/CMakeLists.txt +++ b/cmake/externals/draco/CMakeLists.txt @@ -13,7 +13,7 @@ ExternalProject_Add( ${EXTERNAL_NAME} URL http://hifi-public.s3.amazonaws.com/dependencies/draco-1.1.0.zip URL_MD5 208f8b04c91d5f1c73d731a3ea37c5bb - CONFIGURE_COMMAND CMAKE_ARGS ${ANDROID_CMAKE_ARGS} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH= ${EXTRA_CMAKE_FLAGS} + CONFIGURE_COMMAND CMAKE_ARGS ${ANDROID_CMAKE_ARGS} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH=-$ ${EXTRA_CMAKE_FLAGS} LOG_DOWNLOAD 1 LOG_CONFIGURE 1 LOG_BUILD 1 @@ -23,10 +23,11 @@ ExternalProject_Add( set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals") ExternalProject_Get_Property(${EXTERNAL_NAME} INSTALL_DIR) +set(SUFFIXED_INSTALL_DIR "${INSTALL_DIR}-$") string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) -set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${INSTALL_DIR}/include CACHE PATH "List of Draco include directories") +set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${SUFFIXED_INSTALL_DIR}/include CACHE PATH "List of Draco include directories") if (UNIX) set(LIB_PREFIX "lib") @@ -35,6 +36,6 @@ elseif (WIN32) set(LIB_EXT "lib") endif () -set(${EXTERNAL_NAME_UPPER}_LIBRARY ${INSTALL_DIR}/lib/${LIB_PREFIX}draco.${LIB_EXT} CACHE FILEPATH "Path to Draco release library") -set(${EXTERNAL_NAME_UPPER}_ENCODER_LIBRARY ${INSTALL_DIR}/lib/${LIB_PREFIX}dracoenc.${LIB_EXT} CACHE FILEPATH "Path to Draco encoder release library") -set(${EXTERNAL_NAME_UPPER}_DECODER_LIBRARY ${INSTALL_DIR}/lib/${LIB_PREFIX}dracodec.${LIB_EXT} CACHE FILEPATH "Path to Draco decoder release library") +set(${EXTERNAL_NAME_UPPER}_LIBRARY ${SUFFIXED_INSTALL_DIR}/lib/${LIB_PREFIX}draco.${LIB_EXT} CACHE FILEPATH "Path to Draco release library") +set(${EXTERNAL_NAME_UPPER}_ENCODER_LIBRARY ${SUFFIXED_INSTALL_DIR}/lib/${LIB_PREFIX}dracoenc.${LIB_EXT} CACHE FILEPATH "Path to Draco encoder release library") +set(${EXTERNAL_NAME_UPPER}_DECODER_LIBRARY ${SUFFIXED_INSTALL_DIR}/lib/${LIB_PREFIX}dracodec.${LIB_EXT} CACHE FILEPATH "Path to Draco decoder release library") From c99e803ab707020d0f2fb74cbc7b581405a9bc1b Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 19 Oct 2017 17:17:54 -0700 Subject: [PATCH 046/116] Error handling --- libraries/entities/src/EntityItem.cpp | 100 ++++++++++++++++++-------- 1 file changed, 69 insertions(+), 31 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 3074bd275b..94d9a08252 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -1624,6 +1625,7 @@ bool EntityItem::verifyStaticCertificateProperties() { if (getCertificateID().isEmpty()) { return false; } + const auto signatureBytes = QByteArray::fromBase64(getCertificateID().toLatin1()); const auto signature = reinterpret_cast(signatureBytes.constData()); const unsigned int signatureLength = signatureBytes.length(); @@ -1632,14 +1634,41 @@ bool EntityItem::verifyStaticCertificateProperties() { const auto text = reinterpret_cast(hash.constData()); const unsigned int textLength = hash.length(); - BIO *bio = BIO_new_mem_buf((void*)qPrintable(EntityItem::_marketplacePublicKey), -1); + BIO *bio = BIO_new_mem_buf((void*)EntityItem::_marketplacePublicKey.toUtf8().constData(), -1); EVP_PKEY* evp_key = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL); - RSA* rsa = EVP_PKEY_get1_RSA(evp_key); - bool answer = RSA_verify(NID_sha256, text, textLength, signature, signatureLength, rsa); - BIO_free(bio); - RSA_free(rsa); - EVP_PKEY_free(evp_key); - return answer; + if (evp_key) { + RSA* rsa = EVP_PKEY_get1_RSA(evp_key); + if (rsa) { + bool answer = RSA_verify(NID_sha256, text, textLength, signature, signatureLength, rsa); + RSA_free(rsa); + if (bio) { + BIO_free(bio); + } + if (evp_key) { + EVP_PKEY_free(evp_key); + } + return answer; + } else { + if (bio) { + BIO_free(bio); + } + if (evp_key) { + EVP_PKEY_free(evp_key); + } + long error = ERR_get_error(); + const char* error_str = ERR_error_string(error, NULL); + qCWarning(entities) << "Failed to verify static certificate properties! RSA error:" << error_str; + return false; + } + } else { + if (bio) { + BIO_free(bio); + } + long error = ERR_get_error(); + const char* error_str = ERR_error_string(error, NULL); + qCWarning(entities) << "Failed to verify static certificate properties! RSA error:" << error_str; + return false; + } } void EntityItem::adjustShapeInfoByRegistration(ShapeInfo& info) const { @@ -2975,32 +3004,41 @@ void EntityItem::somethingChangedNotification() { } void EntityItem::retrieveMarketplacePublicKey() { - QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); - QNetworkRequest networkRequest; - networkRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); - QUrl requestURL = NetworkingConstants::METAVERSE_SERVER_URL; - requestURL.setPath("/api/v1/commerce/marketplace_key"); - QJsonObject request; - networkRequest.setUrl(requestURL); + EntityItem::_marketplacePublicKey = "-----BEGIN PUBLIC KEY-----\n" + "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyNNpKuspPe9D8jbzrX5k\n" + "dyl7HvEGHzbXS2ydi0qUApyVZoPsmdx4vtpx6XgwxY8+9X/CDBIIWT2DnfOSzeOQ\n" + "D3zdcK2ro0HRiWuCzGKp9BM2GppkoiCZaJjpCiM7XOrBuI5OHp+5csb21nJs/Djo\n" + "a6eCj3NlkJEjR2SQepPU89dKbS13g6B5uxH7IgerPmJmsCTEmst87AMGJU0SWyiA\n" + "0DSzom/QDODGYAwmC9+++l+xD7pm/zT2NHRom0tbr6Il51PSAcnmxHOcdxuJeRN7\n" + "9ep9dg0aTpKBvVbef9WGWj2QgdQ8qR+b9zoiWDq5vlgeLH2WH/AcDAIyyTr/ydeo\n" + "CQIDAQAB\n" + "-----END PUBLIC KEY-----\n"; + //QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); + //QNetworkRequest networkRequest; + //networkRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); + //QUrl requestURL = NetworkingConstants::METAVERSE_SERVER_URL; + //requestURL.setPath("/api/v1/commerce/marketplace_key"); + //QJsonObject request; + //networkRequest.setUrl(requestURL); - QNetworkReply* networkReply = NULL; - networkReply = networkAccessManager.get(networkRequest); + //QNetworkReply* networkReply = NULL; + //networkReply = networkAccessManager.get(networkRequest); - connect(networkReply, &QNetworkReply::finished, [=]() { - QJsonObject jsonObject = QJsonDocument::fromJson(networkReply->readAll()).object(); - jsonObject = jsonObject["data"].toObject(); + //connect(networkReply, &QNetworkReply::finished, [=]() { + // QJsonObject jsonObject = QJsonDocument::fromJson(networkReply->readAll()).object(); + // jsonObject = jsonObject["data"].toObject(); - if (networkReply->error() == QNetworkReply::NoError) { - if (!jsonObject["public_key"].toString().isEmpty()) { - EntityItem::_marketplacePublicKey = jsonObject["public_key"].toString(); - qCWarning(entities) << "Marketplace public key has been set to" << _marketplacePublicKey; - } else { - qCWarning(entities) << "Marketplace public key is empty!"; - } - } else { - qCWarning(entities) << "Call to" << networkRequest.url() << "failed! Error:" << networkReply->error(); - } + // if (networkReply->error() == QNetworkReply::NoError) { + // if (!jsonObject["public_key"].toString().isEmpty()) { + // EntityItem::_marketplacePublicKey = jsonObject["public_key"].toString(); + // qCWarning(entities) << "Marketplace public key has been set to" << _marketplacePublicKey; + // } else { + // qCWarning(entities) << "Marketplace public key is empty!"; + // } + // } else { + // qCWarning(entities) << "Call to" << networkRequest.url() << "failed! Error:" << networkReply->error(); + // } - networkReply->deleteLater(); - }); + // networkReply->deleteLater(); + //}); } From 9e68e805a0401d744563e4f48c319b677bd7e9a2 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Fri, 20 Oct 2017 10:38:59 -0700 Subject: [PATCH 047/116] Get marketplace public key from backend --- libraries/entities/src/EntityItem.cpp | 57 +++++++++++---------------- 1 file changed, 24 insertions(+), 33 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 94d9a08252..15ef5295e0 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -3004,41 +3004,32 @@ void EntityItem::somethingChangedNotification() { } void EntityItem::retrieveMarketplacePublicKey() { - EntityItem::_marketplacePublicKey = "-----BEGIN PUBLIC KEY-----\n" - "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyNNpKuspPe9D8jbzrX5k\n" - "dyl7HvEGHzbXS2ydi0qUApyVZoPsmdx4vtpx6XgwxY8+9X/CDBIIWT2DnfOSzeOQ\n" - "D3zdcK2ro0HRiWuCzGKp9BM2GppkoiCZaJjpCiM7XOrBuI5OHp+5csb21nJs/Djo\n" - "a6eCj3NlkJEjR2SQepPU89dKbS13g6B5uxH7IgerPmJmsCTEmst87AMGJU0SWyiA\n" - "0DSzom/QDODGYAwmC9+++l+xD7pm/zT2NHRom0tbr6Il51PSAcnmxHOcdxuJeRN7\n" - "9ep9dg0aTpKBvVbef9WGWj2QgdQ8qR+b9zoiWDq5vlgeLH2WH/AcDAIyyTr/ydeo\n" - "CQIDAQAB\n" - "-----END PUBLIC KEY-----\n"; - //QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); - //QNetworkRequest networkRequest; - //networkRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); - //QUrl requestURL = NetworkingConstants::METAVERSE_SERVER_URL; - //requestURL.setPath("/api/v1/commerce/marketplace_key"); - //QJsonObject request; - //networkRequest.setUrl(requestURL); + QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); + QNetworkRequest networkRequest; + networkRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); + QUrl requestURL = NetworkingConstants::METAVERSE_SERVER_URL; + requestURL.setPath("/api/v1/commerce/marketplace_key"); + QJsonObject request; + networkRequest.setUrl(requestURL); - //QNetworkReply* networkReply = NULL; - //networkReply = networkAccessManager.get(networkRequest); + QNetworkReply* networkReply = NULL; + networkReply = networkAccessManager.get(networkRequest); - //connect(networkReply, &QNetworkReply::finished, [=]() { - // QJsonObject jsonObject = QJsonDocument::fromJson(networkReply->readAll()).object(); - // jsonObject = jsonObject["data"].toObject(); + connect(networkReply, &QNetworkReply::finished, [=]() { + QJsonObject jsonObject = QJsonDocument::fromJson(networkReply->readAll()).object(); + jsonObject = jsonObject["data"].toObject(); - // if (networkReply->error() == QNetworkReply::NoError) { - // if (!jsonObject["public_key"].toString().isEmpty()) { - // EntityItem::_marketplacePublicKey = jsonObject["public_key"].toString(); - // qCWarning(entities) << "Marketplace public key has been set to" << _marketplacePublicKey; - // } else { - // qCWarning(entities) << "Marketplace public key is empty!"; - // } - // } else { - // qCWarning(entities) << "Call to" << networkRequest.url() << "failed! Error:" << networkReply->error(); - // } + if (networkReply->error() == QNetworkReply::NoError) { + if (!jsonObject["public_key"].toString().isEmpty()) { + EntityItem::_marketplacePublicKey = jsonObject["public_key"].toString(); + qCWarning(entities) << "Marketplace public key has been set to" << _marketplacePublicKey; + } else { + qCWarning(entities) << "Marketplace public key is empty!"; + } + } else { + qCWarning(entities) << "Call to" << networkRequest.url() << "failed! Error:" << networkReply->error(); + } - // networkReply->deleteLater(); - //}); + networkReply->deleteLater(); + }); } From fbd393d918072cfeefe66330a83591225b146232 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Fri, 20 Oct 2017 15:10:24 -0700 Subject: [PATCH 048/116] Add newline to cert ID when updating location --- interface/src/commerce/Ledger.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/commerce/Ledger.cpp b/interface/src/commerce/Ledger.cpp index 904847cb5f..856ba68a2f 100644 --- a/interface/src/commerce/Ledger.cpp +++ b/interface/src/commerce/Ledger.cpp @@ -234,7 +234,7 @@ void Ledger::updateLocation(const QString& asset_id, const QString location, con QStringList keys = wallet->listPublicKeys(); QString key = keys[0]; QJsonObject transaction; - transaction["certificate_id"] = asset_id; + transaction["certificate_id"] = asset_id + "\n"; transaction["place_name"] = location; QJsonDocument transactionDoc{ transaction }; auto transactionString = transactionDoc.toJson(QJsonDocument::Compact); From b5f1793863506ed6b9518c7af325fd0530b6bf2d Mon Sep 17 00:00:00 2001 From: David Back Date: Mon, 23 Oct 2017 14:21:18 -0700 Subject: [PATCH 049/116] add a tablet contextual mode flag to HMDScriptingInterface used to keep tablet in place --- interface/resources/qml/hifi/tablet/TabletRoot.qml | 2 +- interface/src/scripting/HMDScriptingInterface.cpp | 4 +++- interface/src/scripting/HMDScriptingInterface.h | 5 ++++- scripts/system/tablet-ui/tabletUI.js | 8 +++++++- 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/interface/resources/qml/hifi/tablet/TabletRoot.qml b/interface/resources/qml/hifi/tablet/TabletRoot.qml index ba9d06eee3..a161741049 100644 --- a/interface/resources/qml/hifi/tablet/TabletRoot.qml +++ b/interface/resources/qml/hifi/tablet/TabletRoot.qml @@ -219,7 +219,7 @@ Item { function setShown(value) { if (value === true) { - HMD.openTablet() + HMD.openTablet(HMD.tabletContextualMode) // pass in current contextual mode flag to maintain flag (otherwise uses default false argument) } else { HMD.closeTablet() } diff --git a/interface/src/scripting/HMDScriptingInterface.cpp b/interface/src/scripting/HMDScriptingInterface.cpp index 39d3164f1f..0b6800395f 100644 --- a/interface/src/scripting/HMDScriptingInterface.cpp +++ b/interface/src/scripting/HMDScriptingInterface.cpp @@ -100,10 +100,12 @@ void HMDScriptingInterface::deactivateHMDHandMouse() { void HMDScriptingInterface::closeTablet() { _showTablet = false; + _tabletContextualMode = false; } -void HMDScriptingInterface::openTablet() { +void HMDScriptingInterface::openTablet(bool contextualMode) { _showTablet = true; + _tabletContextualMode = contextualMode; } QScriptValue HMDScriptingInterface::getHUDLookAtPosition2D(QScriptContext* context, QScriptEngine* engine) { diff --git a/interface/src/scripting/HMDScriptingInterface.h b/interface/src/scripting/HMDScriptingInterface.h index e5040b1f90..76bab77cbb 100644 --- a/interface/src/scripting/HMDScriptingInterface.h +++ b/interface/src/scripting/HMDScriptingInterface.h @@ -30,6 +30,7 @@ class HMDScriptingInterface : public AbstractHMDScriptingInterface, public Depen Q_PROPERTY(glm::quat orientation READ getOrientation) Q_PROPERTY(bool mounted READ isMounted NOTIFY mountedChanged) Q_PROPERTY(bool showTablet READ getShouldShowTablet) + Q_PROPERTY(bool tabletContextualMode READ getTabletContextualMode) Q_PROPERTY(QUuid tabletID READ getCurrentTabletFrameID WRITE setCurrentTabletFrameID) Q_PROPERTY(QUuid homeButtonID READ getCurrentHomeButtonID WRITE setCurrentHomeButtonID) Q_PROPERTY(QUuid homeButtonHighlightID READ getCurrentHomeButtonHightlightID WRITE setCurrentHomeButtonHightlightID) @@ -75,7 +76,7 @@ public: Q_INVOKABLE void closeTablet(); - Q_INVOKABLE void openTablet(); + Q_INVOKABLE void openTablet(bool contextualMode = false); signals: bool shouldShowHandControllersChanged(); @@ -91,6 +92,7 @@ public: void toggleShouldShowTablet() { _showTablet = !_showTablet; } void setShouldShowTablet(bool value) { _showTablet = value; } bool getShouldShowTablet() const { return _showTablet; } + bool getTabletContextualMode() const { return _tabletContextualMode; } void setCurrentTabletFrameID(QUuid tabletID) { _tabletUIID = tabletID; } QUuid getCurrentTabletFrameID() const { return _tabletUIID; } @@ -106,6 +108,7 @@ public: private: bool _showTablet { false }; + bool _tabletContextualMode { false }; QUuid _tabletUIID; // this is the entityID of the tablet frame QUuid _tabletScreenID; // this is the overlayID which is part of (a child of) the tablet-ui. QUuid _homeButtonID; diff --git a/scripts/system/tablet-ui/tabletUI.js b/scripts/system/tablet-ui/tabletUI.js index 554729f61e..c10ded5774 100644 --- a/scripts/system/tablet-ui/tabletUI.js +++ b/scripts/system/tablet-ui/tabletUI.js @@ -124,7 +124,13 @@ print("TABLET in showTabletUI, already rezzed"); } var tabletProperties = {}; - UIWebTablet.calculateTabletAttachmentProperties(activeHand, true, tabletProperties); + if (HMD.tabletContextualMode) + print("DBACK tabletContextualMode"); + else + print("DBACK NOT tabletContextualMode"); + if (!HMD.tabletContextualMode) { // contextual mode forces tablet in place -> don't update attachment + UIWebTablet.calculateTabletAttachmentProperties(activeHand, true, tabletProperties); + } tabletProperties.visible = true; Overlays.editOverlay(HMD.tabletID, tabletProperties); Overlays.editOverlay(HMD.homeButtonID, { visible: true }); From 80dc98b2c2403c71f1011fed6134292dd5dcae28 Mon Sep 17 00:00:00 2001 From: David Back Date: Mon, 23 Oct 2017 14:23:45 -0700 Subject: [PATCH 050/116] remove prints --- scripts/system/tablet-ui/tabletUI.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/scripts/system/tablet-ui/tabletUI.js b/scripts/system/tablet-ui/tabletUI.js index c10ded5774..17821c737e 100644 --- a/scripts/system/tablet-ui/tabletUI.js +++ b/scripts/system/tablet-ui/tabletUI.js @@ -124,10 +124,6 @@ print("TABLET in showTabletUI, already rezzed"); } var tabletProperties = {}; - if (HMD.tabletContextualMode) - print("DBACK tabletContextualMode"); - else - print("DBACK NOT tabletContextualMode"); if (!HMD.tabletContextualMode) { // contextual mode forces tablet in place -> don't update attachment UIWebTablet.calculateTabletAttachmentProperties(activeHand, true, tabletProperties); } From 53081b51a6b0e530a57e73f7ec477a9368759885 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Mon, 23 Oct 2017 13:42:25 -0700 Subject: [PATCH 051/116] Clean up as much as possible --- .../src/entities/EntityServer.cpp | 2 +- libraries/entities/src/EntityItem.cpp | 37 ++++++++++++++----- libraries/entities/src/EntityTree.cpp | 2 +- 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index 1351220714..129c3600c7 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -492,7 +492,7 @@ void EntityServer::startDynamicDomainVerification() { qCDebug(entities) << "Entity passed dynamic domain verification:" << i.value(); } } else { - qCDebug(entities) << "Call to proof_of_purchase_status endpoint failed; deleting entity" << i.value(); + qCDebug(entities) << "Call to" << networkReply->url() << "failed with error" << networkReply->error() << "; deleting entity" << i.value(); tree->deleteEntity(i.value(), true); } diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 15ef5295e0..2239ee03b6 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1626,20 +1626,39 @@ bool EntityItem::verifyStaticCertificateProperties() { return false; } - const auto signatureBytes = QByteArray::fromBase64(getCertificateID().toLatin1()); - const auto signature = reinterpret_cast(signatureBytes.constData()); - const unsigned int signatureLength = signatureBytes.length(); + const QByteArray marketplacePublicKeyByteArray = EntityItem::_marketplacePublicKey.toUtf8(); + const unsigned char* marketplacePublicKey = reinterpret_cast(marketplacePublicKeyByteArray.constData()); + int marketplacePublicKeyLength = marketplacePublicKeyByteArray.length(); - const auto hash = getStaticCertificateHash(); - const auto text = reinterpret_cast(hash.constData()); - const unsigned int textLength = hash.length(); - - BIO *bio = BIO_new_mem_buf((void*)EntityItem::_marketplacePublicKey.toUtf8().constData(), -1); + BIO *bio = BIO_new_mem_buf((void*)marketplacePublicKey, marketplacePublicKeyLength); EVP_PKEY* evp_key = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL); if (evp_key) { RSA* rsa = EVP_PKEY_get1_RSA(evp_key); if (rsa) { - bool answer = RSA_verify(NID_sha256, text, textLength, signature, signatureLength, rsa); + const QByteArray digestByteArray = getStaticCertificateHash(); + const unsigned char* digest = reinterpret_cast(digestByteArray.constData()); + int digestLength = digestByteArray.length(); + + const QByteArray signatureByteArray = QByteArray::fromBase64(getCertificateID().toUtf8()); + const unsigned char* signature = reinterpret_cast(signatureByteArray.constData()); + int signatureLength = signatureByteArray.length(); + + ERR_clear_error(); + bool answer = RSA_verify(NID_sha256, + digest, + digestLength, + signature, + signatureLength, + rsa); + long error = ERR_get_error(); + if (error != 0) { + const char* error_str = ERR_error_string(error, NULL); + qCWarning(entities) << "ERROR while verifying static certificate properties! RSA error:" << error_str + << "\nStatic Cert JSON:" << getStaticCertificateJSON() + << "\nKey:" << EntityItem::_marketplacePublicKey << "\nKey Length:" << marketplacePublicKeyLength + << "\nDigest:" << digest << "\nDigest Length:" << digestLength + << "\nSignature:" << signature << "\nSignature Length:" << signatureLength; + } RSA_free(rsa); if (bio) { BIO_free(bio); diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index bca921fe0f..463eae7fd0 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1307,7 +1307,7 @@ void EntityTree::validatePop(const QString& certID, const EntityItemID& entityIt } } } else { - qCDebug(entities) << "Call to proof_of_purchase_status endpoint failed; deleting entity" << entityItemID; + qCDebug(entities) << "Call to" << networkReply->url() << "failed with error" << networkReply->error() << "; deleting entity" << entityItemID; deleteEntity(entityItemID, true); } From 97d44e62c87747e173786a98e429f242e2ee3255 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Mon, 23 Oct 2017 16:52:32 -0700 Subject: [PATCH 052/116] Fix bugs --- assignment-client/src/entities/EntityServer.cpp | 7 ++++--- libraries/entities/src/EntityTree.cpp | 5 +++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index 129c3600c7..7032668d05 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -446,7 +446,7 @@ void EntityServer::domainSettingsRequestFailed() { void EntityServer::startDynamicDomainVerification() { qCDebug(entities) << "Starting Dynamic Domain Verification..."; - QString thisDomainID = DependencyManager::get()->getDomainId(); + QString thisDomainID = DependencyManager::get()->getDomainId().remove(QRegExp("\\{|\\}")); EntityTreePointer tree = std::static_pointer_cast(_tree); QHash localMap(tree->getEntityCertificateIDMap()); @@ -473,7 +473,7 @@ void EntityServer::startDynamicDomainVerification() { QUrl requestURL = NetworkingConstants::METAVERSE_SERVER_URL; requestURL.setPath("/api/v1/commerce/proof_of_purchase_status/location"); QJsonObject request; - request["certificate_id"] = i.key(); + request["certificate_id"] = i.key() + "\n"; networkRequest.setUrl(requestURL); QNetworkReply* networkReply = NULL; @@ -492,7 +492,8 @@ void EntityServer::startDynamicDomainVerification() { qCDebug(entities) << "Entity passed dynamic domain verification:" << i.value(); } } else { - qCDebug(entities) << "Call to" << networkReply->url() << "failed with error" << networkReply->error() << "; deleting entity" << i.value(); + qCDebug(entities) << "Call to" << networkReply->url() << "failed with error" << networkReply->error() << "; deleting entity" << i.value() + << "More info:" << jsonObject; tree->deleteEntity(i.value(), true); } diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 463eae7fd0..510512b72c 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1244,7 +1244,7 @@ void EntityTree::validatePop(const QString& certID, const EntityItemID& entityIt QUrl requestURL = NetworkingConstants::METAVERSE_SERVER_URL; requestURL.setPath("/api/v1/commerce/proof_of_purchase_status/transfer"); QJsonObject request; - request["certificate_id"] = certID; + request["certificate_id"] = certID + "\n"; networkRequest.setUrl(requestURL); QNetworkReply* networkReply = NULL; @@ -1307,7 +1307,8 @@ void EntityTree::validatePop(const QString& certID, const EntityItemID& entityIt } } } else { - qCDebug(entities) << "Call to" << networkReply->url() << "failed with error" << networkReply->error() << "; deleting entity" << entityItemID; + qCDebug(entities) << "Call to" << networkReply->url() << "failed with error" << networkReply->error() << "; deleting entity" << entityItemID + << "More info:" << jsonObject; deleteEntity(entityItemID, true); } From 3e139283ba03247fbd5d2a11e83fa60b070b20dc Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Mon, 23 Oct 2017 17:31:21 -0700 Subject: [PATCH 053/116] Remove unnecessary newlines --- assignment-client/src/entities/EntityServer.cpp | 2 +- interface/src/commerce/Ledger.cpp | 2 +- libraries/entities/src/EntityTree.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index 7032668d05..fa9c73b12d 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -473,7 +473,7 @@ void EntityServer::startDynamicDomainVerification() { QUrl requestURL = NetworkingConstants::METAVERSE_SERVER_URL; requestURL.setPath("/api/v1/commerce/proof_of_purchase_status/location"); QJsonObject request; - request["certificate_id"] = i.key() + "\n"; + request["certificate_id"] = i.key(); networkRequest.setUrl(requestURL); QNetworkReply* networkReply = NULL; diff --git a/interface/src/commerce/Ledger.cpp b/interface/src/commerce/Ledger.cpp index 856ba68a2f..904847cb5f 100644 --- a/interface/src/commerce/Ledger.cpp +++ b/interface/src/commerce/Ledger.cpp @@ -234,7 +234,7 @@ void Ledger::updateLocation(const QString& asset_id, const QString location, con QStringList keys = wallet->listPublicKeys(); QString key = keys[0]; QJsonObject transaction; - transaction["certificate_id"] = asset_id + "\n"; + transaction["certificate_id"] = asset_id; transaction["place_name"] = location; QJsonDocument transactionDoc{ transaction }; auto transactionString = transactionDoc.toJson(QJsonDocument::Compact); diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 510512b72c..483e2bfc46 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1244,7 +1244,7 @@ void EntityTree::validatePop(const QString& certID, const EntityItemID& entityIt QUrl requestURL = NetworkingConstants::METAVERSE_SERVER_URL; requestURL.setPath("/api/v1/commerce/proof_of_purchase_status/transfer"); QJsonObject request; - request["certificate_id"] = certID + "\n"; + request["certificate_id"] = certID; networkRequest.setUrl(requestURL); QNetworkReply* networkReply = NULL; From c64c2e17c8daf636027bafd07eb13f55f1a16505 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 24 Oct 2017 10:52:27 -0700 Subject: [PATCH 054/116] First pass at consolidation --- assignment-client/src/octree/OctreeServer.cpp | 1 - domain-server/src/DomainServer.cpp | 5 ++--- ice-server/src/IceServer.cpp | 4 ++-- interface/resources/qml/AddressBarDialog.qml | 2 +- interface/resources/qml/hifi/NameCard.qml | 4 ++-- .../qml/hifi/tablet/TabletAddressDialog.qml | 2 +- interface/src/Application.cpp | 3 +-- interface/src/commerce/Ledger.cpp | 4 +--- interface/src/networking/CloseEventSender.cpp | 5 ++--- interface/src/ui/AddressBarDialog.cpp | 2 +- interface/src/ui/AddressBarDialog.h | 8 +++---- interface/src/ui/LoginDialog.cpp | 1 - interface/src/ui/PreferencesDialog.cpp | 1 - .../ui/overlays/ContextOverlayInterface.cpp | 6 ++---- libraries/fbx/src/FSTReader.cpp | 1 - libraries/networking/src/AccountManager.cpp | 3 +-- libraries/networking/src/AccountManager.h | 5 +++++ libraries/networking/src/AddressManager.cpp | 5 ----- libraries/networking/src/AddressManager.h | 4 ---- .../networking/src/NetworkingConstants.h | 21 ------------------- .../src/OAuthNetworkAccessManager.cpp | 3 +-- .../script-engine/src/XMLHttpRequestClass.cpp | 7 +++---- libraries/ui/src/ui/types/RequestFilters.cpp | 4 ++-- scripts/system/makeUserConnection.js | 4 ++-- scripts/system/pal.js | 2 +- scripts/system/snapshot.js | 2 +- scripts/system/tablet-goto.js | 4 ++-- tools/ac-client/src/ACClientApp.cpp | 3 +-- tools/atp-client/src/ATPClientApp.cpp | 3 +-- 29 files changed, 39 insertions(+), 80 deletions(-) delete mode 100644 libraries/networking/src/NetworkingConstants.h diff --git a/assignment-client/src/octree/OctreeServer.cpp b/assignment-client/src/octree/OctreeServer.cpp index 4a1aade59d..c535c48dda 100644 --- a/assignment-client/src/octree/OctreeServer.cpp +++ b/assignment-client/src/octree/OctreeServer.cpp @@ -22,7 +22,6 @@ #include #include #include -#include #include #include diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 436f49c7ca..28100efd2d 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -340,12 +339,12 @@ bool DomainServer::optionallySetupOAuth() { const QVariantMap& settingsMap = _settingsManager.getSettingsMap(); _oauthProviderURL = QUrl(settingsMap.value(OAUTH_PROVIDER_URL_OPTION).toString()); + auto accountManager = DependencyManager::get(); // if we don't have an oauth provider URL then we default to the default node auth url if (_oauthProviderURL.isEmpty()) { - _oauthProviderURL = NetworkingConstants::METAVERSE_SERVER_URL; + _oauthProviderURL = accountManager->getMetaverseServerURL(); } - auto accountManager = DependencyManager::get(); accountManager->setAuthURL(_oauthProviderURL); _oauthClientID = settingsMap.value(OAUTH_CLIENT_ID_OPTION).toString(); diff --git a/ice-server/src/IceServer.cpp b/ice-server/src/IceServer.cpp index f8bf1f62ae..a2e900e8d2 100644 --- a/ice-server/src/IceServer.cpp +++ b/ice-server/src/IceServer.cpp @@ -18,9 +18,9 @@ #include #include +#include #include #include -#include #include #include @@ -208,7 +208,7 @@ void IceServer::requestDomainPublicKey(const QUuid& domainID) { // send a request to the metaverse API for the public key for this domain auto& networkAccessManager = NetworkAccessManager::getInstance(); - QUrl publicKeyURL { NetworkingConstants::METAVERSE_SERVER_URL }; + QUrl publicKeyURL { DependencyManager::get()->getMetaverseServerURL() }; QString publicKeyPath = QString("/api/v1/domains/%1/public_key").arg(uuidStringWithoutCurlyBraces(domainID)); publicKeyURL.setPath(publicKeyPath); diff --git a/interface/resources/qml/AddressBarDialog.qml b/interface/resources/qml/AddressBarDialog.qml index c19e16cd36..60d2bacc62 100644 --- a/interface/resources/qml/AddressBarDialog.qml +++ b/interface/resources/qml/AddressBarDialog.qml @@ -87,7 +87,7 @@ Window { onReceivedHifiSchemeURL: resetAfterTeleport(); // Update location after using back and forward buttons. - onMetaverseServerUrlChanged: updateLocationTextTimer.start(); + onHostChanged: updateLocationTextTimer.start(); ListModel { id: suggestions } diff --git a/interface/resources/qml/hifi/NameCard.qml b/interface/resources/qml/hifi/NameCard.qml index 65517f5a73..fa73bc5135 100644 --- a/interface/resources/qml/hifi/NameCard.qml +++ b/interface/resources/qml/hifi/NameCard.qml @@ -17,7 +17,7 @@ import "../styles-uit" import "../controls-uit" as HifiControls import "toolbars" -// references Users, UserActivityLogger, MyAvatar, Vec3, Quat, AddressManager from root context +// references Users, UserActivityLogger, MyAvatar, Vec3, Quat, AddressManager, Account from root context Item { id: thisNameCard @@ -30,7 +30,7 @@ Item { // Properties property string profileUrl: ""; - property string defaultBaseUrl: AddressManager.metaverseServerUrl; + property string defaultBaseUrl: Account.metaverseServerURL; property string connectionStatus : "" property string uuid: "" property string displayName: "" diff --git a/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml b/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml index e8752b01e7..4d9a83817a 100644 --- a/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml +++ b/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml @@ -134,7 +134,7 @@ StackView { bottom: parent.bottom } - onMetaverseServerUrlChanged: updateLocationTextTimer.start(); + onHostChanged: updateLocationTextTimer.start(); Rectangle { id: navBar width: parent.width diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 6e7a405181..b3f31c6c81 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -94,7 +94,6 @@ #include #include #include -#include #include #include #include @@ -960,7 +959,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo // set the account manager's root URL and trigger a login request if we don't have the access token accountManager->setIsAgent(true); - accountManager->setAuthURL(NetworkingConstants::METAVERSE_SERVER_URL); + accountManager->setAuthURL(accountManager->getMetaverseServerURL()); auto addressManager = DependencyManager::get(); diff --git a/interface/src/commerce/Ledger.cpp b/interface/src/commerce/Ledger.cpp index 80e599fb24..bd7668cf32 100644 --- a/interface/src/commerce/Ledger.cpp +++ b/interface/src/commerce/Ledger.cpp @@ -16,7 +16,6 @@ #include "Wallet.h" #include "Ledger.h" #include "CommerceLogging.h" -#include // inventory answers {status: 'success', data: {assets: [{id: "guid", title: "name", preview: "url"}....]}} // balance answers {status: 'success', data: {balance: integer}} @@ -121,7 +120,6 @@ QString nameFromKey(const QString& key, const QStringList& publicKeys) { return "Someone"; } -static const QString MARKETPLACE_ITEMS_BASE_URL = NetworkingConstants::METAVERSE_SERVER_URL.toString() + "/marketplace/items/"; void Ledger::historySuccess(QNetworkReply& reply) { // here we send a historyResult with some extra stuff in it // Namely, the styled text we'd like to show. The issue is the @@ -154,7 +152,7 @@ void Ledger::historySuccess(QNetworkReply& reply) { } } else { coloredQuantityAndAssetTitle = QString("\"") + coloredQuantityAndAssetTitle + diff --git a/interface/src/networking/CloseEventSender.cpp b/interface/src/networking/CloseEventSender.cpp index de8bd897b2..41e1fb8bef 100644 --- a/interface/src/networking/CloseEventSender.cpp +++ b/interface/src/networking/CloseEventSender.cpp @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -27,13 +26,13 @@ QNetworkRequest createNetworkRequest() { QNetworkRequest request; + auto accountManager = DependencyManager::get(); - QUrl requestURL = NetworkingConstants::METAVERSE_SERVER_URL; + QUrl requestURL = accountManager->getMetaverseServerURL(); requestURL.setPath(USER_ACTIVITY_URL); request.setUrl(requestURL); - auto accountManager = DependencyManager::get(); if (accountManager->hasValidAccessToken()) { request.setRawHeader(ACCESS_TOKEN_AUTHORIZATION_HEADER, diff --git a/interface/src/ui/AddressBarDialog.cpp b/interface/src/ui/AddressBarDialog.cpp index d7b59ba912..8b5e255b06 100644 --- a/interface/src/ui/AddressBarDialog.cpp +++ b/interface/src/ui/AddressBarDialog.cpp @@ -39,7 +39,7 @@ AddressBarDialog::AddressBarDialog(QQuickItem* parent) : OffscreenQmlDialog(pare }); _backEnabled = !(DependencyManager::get()->getBackStack().isEmpty()); _forwardEnabled = !(DependencyManager::get()->getForwardStack().isEmpty()); - connect(addressManager.data(), &AddressManager::hostChanged, this, &AddressBarDialog::metaverseServerUrlChanged); + connect(addressManager.data(), &AddressManager::hostChanged, this, &AddressBarDialog::hostChanged); connect(DependencyManager::get().data(), &DialogsManager::setUseFeed, this, &AddressBarDialog::setUseFeed); connect(qApp, &Application::receivedHifiSchemeURL, this, &AddressBarDialog::receivedHifiSchemeURL); } diff --git a/interface/src/ui/AddressBarDialog.h b/interface/src/ui/AddressBarDialog.h index 921e808abb..48e702f5bf 100644 --- a/interface/src/ui/AddressBarDialog.h +++ b/interface/src/ui/AddressBarDialog.h @@ -13,8 +13,8 @@ #ifndef hifi_AddressBarDialog_h #define hifi_AddressBarDialog_h +#include #include -#include class AddressBarDialog : public OffscreenQmlDialog { Q_OBJECT @@ -22,7 +22,7 @@ class AddressBarDialog : public OffscreenQmlDialog { Q_PROPERTY(bool backEnabled READ backEnabled NOTIFY backEnabledChanged) Q_PROPERTY(bool forwardEnabled READ forwardEnabled NOTIFY forwardEnabledChanged) Q_PROPERTY(bool useFeed READ useFeed WRITE setUseFeed NOTIFY useFeedChanged) - Q_PROPERTY(QString metaverseServerUrl READ metaverseServerUrl NOTIFY metaverseServerUrlChanged) + Q_PROPERTY(QString metaverseServerUrl READ metaverseServerUrl) public: AddressBarDialog(QQuickItem* parent = nullptr); @@ -30,14 +30,14 @@ public: bool forwardEnabled() { return _forwardEnabled; } bool useFeed() { return _useFeed; } void setUseFeed(bool useFeed) { if (_useFeed != useFeed) { _useFeed = useFeed; emit useFeedChanged(); } } - QString metaverseServerUrl() { return NetworkingConstants::METAVERSE_SERVER_URL.toString(); } + QString metaverseServerUrl() { return DependencyManager::get()->getMetaverseServerURL().toString(); } signals: void backEnabledChanged(); void forwardEnabledChanged(); void useFeedChanged(); void receivedHifiSchemeURL(const QString& url); - void metaverseServerUrlChanged(); + void hostChanged(); protected: void displayAddressOfflineMessage(); diff --git a/interface/src/ui/LoginDialog.cpp b/interface/src/ui/LoginDialog.cpp index 515215a8d3..7ce2a0146d 100644 --- a/interface/src/ui/LoginDialog.cpp +++ b/interface/src/ui/LoginDialog.cpp @@ -16,7 +16,6 @@ #include #include -#include #include #include #include diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index b3bd6fbd34..023d3e6e17 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include diff --git a/interface/src/ui/overlays/ContextOverlayInterface.cpp b/interface/src/ui/overlays/ContextOverlayInterface.cpp index 8cbb214857..969b5e47c5 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.cpp +++ b/interface/src/ui/overlays/ContextOverlayInterface.cpp @@ -12,8 +12,8 @@ #include "ContextOverlayInterface.h" #include "Application.h" +#include #include -#include #ifndef MIN #define MIN(a,b) ((a) < (b) ? (a) : (b)) @@ -260,8 +260,6 @@ void ContextOverlayInterface::openInspectionCertificate() { } } -static const QString MARKETPLACE_BASE_URL = NetworkingConstants::METAVERSE_SERVER_URL.toString() + "/marketplace/items/"; - void ContextOverlayInterface::openMarketplace() { // lets open the tablet and go to the current item in // the marketplace (if the current entity has a @@ -269,7 +267,7 @@ void ContextOverlayInterface::openMarketplace() { if (!_currentEntityWithContextOverlay.isNull() && _entityMarketplaceID.length() > 0) { auto tablet = dynamic_cast(_tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system")); // construct the url to the marketplace item - QString url = MARKETPLACE_BASE_URL + _entityMarketplaceID; + QString url = DependencyManager::get()->getMetaverseServerURL().toString() + "/marketplace/items/" + _entityMarketplaceID; QString MARKETPLACES_INJECT_SCRIPT_PATH = "file:///" + qApp->applicationDirPath() + "/scripts/system/html/js/marketplacesInject.js"; tablet->gotoWebScreen(url, MARKETPLACES_INJECT_SCRIPT_PATH); _hmdScriptingInterface->openTablet(); diff --git a/libraries/fbx/src/FSTReader.cpp b/libraries/fbx/src/FSTReader.cpp index 3f0a629c8c..cc4a919445 100644 --- a/libraries/fbx/src/FSTReader.cpp +++ b/libraries/fbx/src/FSTReader.cpp @@ -15,7 +15,6 @@ #include #include -#include #include #include "FSTReader.h" diff --git a/libraries/networking/src/AccountManager.cpp b/libraries/networking/src/AccountManager.cpp index fa6b49597d..f6264a19c4 100644 --- a/libraries/networking/src/AccountManager.cpp +++ b/libraries/networking/src/AccountManager.cpp @@ -28,7 +28,6 @@ #include -#include "NetworkingConstants.h" #include "NetworkLogging.h" #include "NodeList.h" #include "udt/PacketHeaders.h" @@ -240,7 +239,7 @@ void AccountManager::sendRequest(const QString& path, QUrl requestURL = _authURL; if (requestURL.isEmpty()) { // Assignment client doesn't set _authURL. - requestURL = NetworkingConstants::METAVERSE_SERVER_URL; + requestURL = getMetaverseServerURL(); } if (path.startsWith("/")) { diff --git a/libraries/networking/src/AccountManager.h b/libraries/networking/src/AccountManager.h index b37846ec1b..aec75a9084 100644 --- a/libraries/networking/src/AccountManager.h +++ b/libraries/networking/src/AccountManager.h @@ -58,6 +58,8 @@ using UserAgentGetter = std::function; const auto DEFAULT_USER_AGENT_GETTER = []() -> QString { return HIGH_FIDELITY_USER_AGENT; }; +const QUrl METAVERSE_SERVER_URL = "https://metaverse.highfidelity.com"; + class AccountManager : public QObject, public Dependency { Q_OBJECT public: @@ -96,6 +98,9 @@ public: void setTemporaryDomain(const QUuid& domainID, const QString& key); const QString& getTemporaryDomainKey(const QUuid& domainID) { return _accountInfo.getTemporaryDomainKey(domainID); } + Q_PROPERTY(QUrl metaverseServerURL READ getMetaverseServerURL) + QUrl getMetaverseServerURL() { return METAVERSE_SERVER_URL; } + public slots: void requestAccessToken(const QString& login, const QString& password); void requestAccessTokenWithSteam(QByteArray authSessionTicket); diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index 2376a3b2b6..1a51440e91 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -24,7 +24,6 @@ #include "AddressManager.h" #include "NodeList.h" -#include "NetworkingConstants.h" #include "NetworkLogging.h" #include "UserActivityLogger.h" #include "udt/PacketHeaders.h" @@ -770,10 +769,6 @@ QString AddressManager::getDomainId() const { return DependencyManager::get()->getDomainHandler().getUUID().toString(); } -const QUrl AddressManager::getMetaverseServerUrl() const { - return NetworkingConstants::METAVERSE_SERVER_URL; -} - void AddressManager::handleShareableNameAPIResponse(QNetworkReply& requestReply) { // make sure that this response is for the domain we're currently connected to auto domainID = DependencyManager::get()->getDomainHandler().getUUID(); diff --git a/libraries/networking/src/AddressManager.h b/libraries/networking/src/AddressManager.h index 83eedfc82f..366fc5dfab 100644 --- a/libraries/networking/src/AddressManager.h +++ b/libraries/networking/src/AddressManager.h @@ -41,7 +41,6 @@ class AddressManager : public QObject, public Dependency { Q_PROPERTY(QString pathname READ currentPath) Q_PROPERTY(QString placename READ getPlaceName) Q_PROPERTY(QString domainId READ getDomainId) - Q_PROPERTY(QUrl metaverseServerUrl READ getMetaverseServerUrl NOTIFY metaverseServerUrlChanged) public: Q_INVOKABLE QString protocolVersion(); using PositionGetter = std::function; @@ -71,7 +70,6 @@ public: const QUuid& getRootPlaceID() const { return _rootPlaceID; } const QString& getPlaceName() const { return _shareablePlaceName.isEmpty() ? _placeName : _shareablePlaceName; } QString getDomainId() const; - const QUrl getMetaverseServerUrl() const; const QString& getHost() const { return _host; } @@ -123,8 +121,6 @@ signals: void goBackPossible(bool isPossible); void goForwardPossible(bool isPossible); - void metaverseServerUrlChanged(); - protected: AddressManager(); private slots: diff --git a/libraries/networking/src/NetworkingConstants.h b/libraries/networking/src/NetworkingConstants.h deleted file mode 100644 index a512ae8887..0000000000 --- a/libraries/networking/src/NetworkingConstants.h +++ /dev/null @@ -1,21 +0,0 @@ -// -// NetworkingConstants.h -// libraries/networking/src -// -// Created by Stephen Birarda on 2015-03-31. -// Copyright 2015 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#ifndef hifi_NetworkingConstants_h -#define hifi_NetworkingConstants_h - -#include - -namespace NetworkingConstants { - const QUrl METAVERSE_SERVER_URL = QUrl("https://metaverse.highfidelity.com"); -} - -#endif // hifi_NetworkingConstants_h diff --git a/libraries/networking/src/OAuthNetworkAccessManager.cpp b/libraries/networking/src/OAuthNetworkAccessManager.cpp index 15d5acbc67..42b8f16575 100644 --- a/libraries/networking/src/OAuthNetworkAccessManager.cpp +++ b/libraries/networking/src/OAuthNetworkAccessManager.cpp @@ -15,7 +15,6 @@ #include "AccountManager.h" #include "LimitedNodeList.h" -#include "NetworkingConstants.h" #include "SharedUtil.h" #include "OAuthNetworkAccessManager.h" @@ -35,7 +34,7 @@ QNetworkReply* OAuthNetworkAccessManager::createRequest(QNetworkAccessManager::O auto accountManager = DependencyManager::get(); if (accountManager->hasValidAccessToken() - && req.url().host() == NetworkingConstants::METAVERSE_SERVER_URL.host()) { + && req.url().host() == accountManager->getMetaverseServerURL().host()) { QNetworkRequest authenticatedRequest(req); authenticatedRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); authenticatedRequest.setHeader(QNetworkRequest::UserAgentHeader, HIGH_FIDELITY_USER_AGENT); diff --git a/libraries/script-engine/src/XMLHttpRequestClass.cpp b/libraries/script-engine/src/XMLHttpRequestClass.cpp index 1d3c8fda32..c8d518e6c9 100644 --- a/libraries/script-engine/src/XMLHttpRequestClass.cpp +++ b/libraries/script-engine/src/XMLHttpRequestClass.cpp @@ -17,13 +17,10 @@ #include #include -#include #include "ScriptEngine.h" #include "XMLHttpRequestClass.h" -const QString METAVERSE_API_URL = NetworkingConstants::METAVERSE_SERVER_URL.toString() + "/api/"; - Q_DECLARE_METATYPE(QByteArray*) XMLHttpRequestClass::XMLHttpRequestClass(QScriptEngine* engine) : @@ -140,7 +137,9 @@ void XMLHttpRequestClass::open(const QString& method, const QString& url, bool a _url.setUrl(url); _async = async; - if (url.toLower().left(METAVERSE_API_URL.length()) == METAVERSE_API_URL) { + auto metaverseApiUrl = DependencyManager::get()->getMetaverseServerURL().toString() + "/api/"; + + if (url.toLower().left(metaverseApiUrl.length()) == metaverseApiUrl) { auto accountManager = DependencyManager::get(); if (accountManager->hasValidAccessToken()) { diff --git a/libraries/ui/src/ui/types/RequestFilters.cpp b/libraries/ui/src/ui/types/RequestFilters.cpp index f9686d2311..1823921545 100644 --- a/libraries/ui/src/ui/types/RequestFilters.cpp +++ b/libraries/ui/src/ui/types/RequestFilters.cpp @@ -10,7 +10,6 @@ // #include "RequestFilters.h" -#include "NetworkingConstants.h" #include #include @@ -26,9 +25,10 @@ namespace { }; const auto& scheme = url.scheme(); const auto& host = url.host(); + auto metaverseServerURL = DependencyManager::get()->getMetaverseServerURL(); return (scheme == "https" && HF_HOSTS.contains(host)) || - ((scheme == NetworkingConstants::METAVERSE_SERVER_URL.scheme()) && (host == NetworkingConstants::METAVERSE_SERVER_URL.host())); + ((scheme == metaverseServerURL.scheme()) && (host == metaverseServerURL.host())); } bool isScript(const QString filename) { diff --git a/scripts/system/makeUserConnection.js b/scripts/system/makeUserConnection.js index bfad959ffc..7dddd46562 100644 --- a/scripts/system/makeUserConnection.js +++ b/scripts/system/makeUserConnection.js @@ -444,7 +444,7 @@ }, WAITING_INTERVAL); } - var pollCount = 0, requestUrl = location.metaverseServerUrl + '/api/v1/user/connection_request'; + var pollCount = 0, requestUrl = Account.metaverseServerURL + '/api/v1/user/connection_request'; // As currently implemented, we select the closest waiting avatar (if close enough) and send // them a connectionRequest. If nobody is close enough we send a waiting message, and wait for a // connectionRequest. If the 2 people who want to connect are both somewhat out of range when they @@ -569,7 +569,7 @@ // IWBNI we also did some fail sound/visual effect. Window.makeConnection(false, result.connection); if (Account.isLoggedIn()) { // Give extra failure info - request(location.metaverseServerUrl + '/api/v1/users/' + Account.username + '/location', function (error, response) { + request(Account.metaverseServerURL + '/api/v1/users/' + Account.username + '/location', function (error, response) { var message = ''; if (error || response.status !== 'success') { message = 'Unable to get location.'; diff --git a/scripts/system/pal.js b/scripts/system/pal.js index 2a8a89ae7d..44ff7c2acd 100644 --- a/scripts/system/pal.js +++ b/scripts/system/pal.js @@ -334,7 +334,7 @@ function updateUser(data) { // User management services // // These are prototype versions that will be changed when the back end changes. -var METAVERSE_BASE = location.metaverseServerUrl; +var METAVERSE_BASE = Account.metaverseServerURL; function requestJSON(url, callback) { // callback(data) if successfull. Logs otherwise. request({ diff --git a/scripts/system/snapshot.js b/scripts/system/snapshot.js index 8f08b29cff..9afdb4ec53 100644 --- a/scripts/system/snapshot.js +++ b/scripts/system/snapshot.js @@ -35,7 +35,7 @@ var imageData = []; var storyIDsToMaybeDelete = []; var shareAfterLogin = false; var snapshotToShareAfterLogin = []; -var METAVERSE_BASE = location.metaverseServerUrl; +var METAVERSE_BASE = Account.metaverseServerURL; var isLoggedIn; var numGifSnapshotUploadsPending = 0; var numStillSnapshotUploadsPending = 0; diff --git a/scripts/system/tablet-goto.js b/scripts/system/tablet-goto.js index 96ed3e3f59..929c6e0e5c 100644 --- a/scripts/system/tablet-goto.js +++ b/scripts/system/tablet-goto.js @@ -115,7 +115,7 @@ var stories = {}, pingPong = false; function expire(id) { var options = { - uri: location.metaverseServerUrl + '/api/v1/user_stories/' + id, + uri: Account.metaverseServerURL + '/api/v1/user_stories/' + id, method: 'PUT', json: true, body: {expire: "true"} @@ -139,7 +139,7 @@ 'protocol=' + encodeURIComponent(location.protocolVersion()), 'per_page=' + count ]; - var url = location.metaverseServerUrl + '/api/v1/user_stories?' + options.join('&'); + var url = Account.metaverseServerURL + '/api/v1/user_stories?' + options.join('&'); request({ uri: url }, function (error, data) { diff --git a/tools/ac-client/src/ACClientApp.cpp b/tools/ac-client/src/ACClientApp.cpp index e00560158f..f3ea9b7348 100644 --- a/tools/ac-client/src/ACClientApp.cpp +++ b/tools/ac-client/src/ACClientApp.cpp @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -106,7 +105,7 @@ ACClientApp::ACClientApp(int argc, char* argv[]) : auto accountManager = DependencyManager::get(); accountManager->setIsAgent(true); - accountManager->setAuthURL(NetworkingConstants::METAVERSE_SERVER_URL); + accountManager->setAuthURL(accountManager->getMetaverseServerURL()); auto nodeList = DependencyManager::get(); diff --git a/tools/atp-client/src/ATPClientApp.cpp b/tools/atp-client/src/ATPClientApp.cpp index c5edf27b67..85aee10d76 100644 --- a/tools/atp-client/src/ATPClientApp.cpp +++ b/tools/atp-client/src/ATPClientApp.cpp @@ -17,7 +17,6 @@ #include #include -#include #include #include #include @@ -145,7 +144,7 @@ ATPClientApp::ATPClientApp(int argc, char* argv[]) : auto accountManager = DependencyManager::get(); accountManager->setIsAgent(true); - accountManager->setAuthURL(NetworkingConstants::METAVERSE_SERVER_URL); + accountManager->setAuthURL(accountManager->getMetaverseServerURL()); auto nodeList = DependencyManager::get(); From 48c8d52c09db48e617e356f0a360497b44484260 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 24 Oct 2017 13:21:03 -0700 Subject: [PATCH 055/116] Cleanup --- interface/resources/qml/hifi/NameCard.qml | 7 +++---- interface/resources/qml/hifi/Pal.qml | 3 --- interface/src/scripting/AccountScriptingInterface.h | 5 +++++ libraries/networking/src/AccountManager.h | 5 +++-- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/interface/resources/qml/hifi/NameCard.qml b/interface/resources/qml/hifi/NameCard.qml index fa73bc5135..fcfff02b72 100644 --- a/interface/resources/qml/hifi/NameCard.qml +++ b/interface/resources/qml/hifi/NameCard.qml @@ -30,7 +30,6 @@ Item { // Properties property string profileUrl: ""; - property string defaultBaseUrl: Account.metaverseServerURL; property string connectionStatus : "" property string uuid: "" property string displayName: "" @@ -59,7 +58,7 @@ Item { clip: true Image { id: userImage - source: profileUrl !== "" ? ((0 === profileUrl.indexOf("http")) ? profileUrl : (defaultBaseUrl + profileUrl)) : ""; + source: profileUrl !== "" ? ((0 === profileUrl.indexOf("http")) ? profileUrl : (Account.metaverseServerURL + profileUrl)) : ""; mipmap: true; // Anchors anchors.fill: parent @@ -95,7 +94,7 @@ Item { enabled: (selected && activeTab == "nearbyTab") || isMyCard; hoverEnabled: enabled onClicked: { - userInfoViewer.url = defaultBaseUrl + "/users/" + userName; + userInfoViewer.url = Account.metaverseServerURL + "/users/" + userName; userInfoViewer.visible = true; } onEntered: infoHoverImage.visible = true; @@ -366,7 +365,7 @@ Item { enabled: selected hoverEnabled: true onClicked: { - userInfoViewer.url = defaultBaseUrl + "/users/" + userName; + userInfoViewer.url = Account.metaverseServerURL + "/users/" + userName; userInfoViewer.visible = true; } onEntered: { diff --git a/interface/resources/qml/hifi/Pal.qml b/interface/resources/qml/hifi/Pal.qml index c98cfba1ba..89f18e5ce2 100644 --- a/interface/resources/qml/hifi/Pal.qml +++ b/interface/resources/qml/hifi/Pal.qml @@ -23,9 +23,6 @@ import "../controls" as HifiControls Rectangle { id: pal; - // Size - width: parent.width; - height: parent.height; // Style color: "#E3E3E3"; // Properties diff --git a/interface/src/scripting/AccountScriptingInterface.h b/interface/src/scripting/AccountScriptingInterface.h index 4f87e02dce..4ff250e926 100644 --- a/interface/src/scripting/AccountScriptingInterface.h +++ b/interface/src/scripting/AccountScriptingInterface.h @@ -25,6 +25,11 @@ class AccountScriptingInterface : public QObject { * @property username {String} username if user is logged in, otherwise it returns "Unknown user" */ +public: + + Q_PROPERTY(QUrl metaverseServerURL READ getMetaverseServerURL) + QUrl getMetaverseServerURL() { return DependencyManager::get()->getMetaverseServerURL(); } + signals: /**jsdoc diff --git a/libraries/networking/src/AccountManager.h b/libraries/networking/src/AccountManager.h index aec75a9084..09c38e2d3e 100644 --- a/libraries/networking/src/AccountManager.h +++ b/libraries/networking/src/AccountManager.h @@ -58,7 +58,9 @@ using UserAgentGetter = std::function; const auto DEFAULT_USER_AGENT_GETTER = []() -> QString { return HIGH_FIDELITY_USER_AGENT; }; -const QUrl METAVERSE_SERVER_URL = "https://metaverse.highfidelity.com"; +const QUrl METAVERSE_SERVER_URL_STAGING = "https://staging.highfidelity.com"; +const QUrl METAVERSE_SERVER_URL_STABLE = "https://metaverse.highfidelity.com"; +const QUrl METAVERSE_SERVER_URL = METAVERSE_SERVER_URL_STABLE; class AccountManager : public QObject, public Dependency { Q_OBJECT @@ -98,7 +100,6 @@ public: void setTemporaryDomain(const QUuid& domainID, const QString& key); const QString& getTemporaryDomainKey(const QUuid& domainID) { return _accountInfo.getTemporaryDomainKey(domainID); } - Q_PROPERTY(QUrl metaverseServerURL READ getMetaverseServerURL) QUrl getMetaverseServerURL() { return METAVERSE_SERVER_URL; } public slots: From 4b50454104ca527d046e75043ba9408456eda04d Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 24 Oct 2017 14:13:14 -0700 Subject: [PATCH 056/116] Missed a spot --- scripts/system/marketplaces/marketplace.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/marketplaces/marketplace.js b/scripts/system/marketplaces/marketplace.js index f365ca5d4c..d90695c767 100644 --- a/scripts/system/marketplaces/marketplace.js +++ b/scripts/system/marketplaces/marketplace.js @@ -15,7 +15,7 @@ Script.include("../libraries/WebTablet.js"); var toolIconUrl = Script.resolvePath("../assets/images/tools/"); -var MARKETPLACE_URL = "https://metaverse.highfidelity.com/marketplace"; +var MARKETPLACE_URL = Account.metaverseServerURL + "/marketplace"; var marketplaceWindow = new OverlayWebWindow({ title: "Marketplace", source: "about:blank", From b092862b03db8c5fc468ba41755175b066d75039 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 24 Oct 2017 14:22:38 -0700 Subject: [PATCH 057/116] Missed another spot --- domain-server/resources/web/settings/js/settings.js | 4 +++- libraries/networking/src/AccountManager.h | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/domain-server/resources/web/settings/js/settings.js b/domain-server/resources/web/settings/js/settings.js index 14347b6be1..ecd67e30eb 100644 --- a/domain-server/resources/web/settings/js/settings.js +++ b/domain-server/resources/web/settings/js/settings.js @@ -1,6 +1,8 @@ var Settings = { showAdvanced: false, - METAVERSE_URL: 'https://metaverse.highfidelity.com', + METAVERSE_URL_STABLE: 'https://metaverse.highfidelity.com', + METAVERSE_URL_STAGING: 'https://staging.highfidelity.com', + METAVERSE_URL: METAVERSE_URL_STABLE, ADVANCED_CLASS: 'advanced-setting', DEPRECATED_CLASS: 'deprecated-setting', TRIGGER_CHANGE_CLASS: 'trigger-change', diff --git a/libraries/networking/src/AccountManager.h b/libraries/networking/src/AccountManager.h index 09c38e2d3e..3dae03200e 100644 --- a/libraries/networking/src/AccountManager.h +++ b/libraries/networking/src/AccountManager.h @@ -58,6 +58,9 @@ using UserAgentGetter = std::function; const auto DEFAULT_USER_AGENT_GETTER = []() -> QString { return HIGH_FIDELITY_USER_AGENT; }; +// If you want to use STAGING instead of STABLE, +// don't forget to ALSO change the Domain Server Metaverse Server URL, which is at the top of: +// \domain-server\resources\web\settings\js\settings.js const QUrl METAVERSE_SERVER_URL_STAGING = "https://staging.highfidelity.com"; const QUrl METAVERSE_SERVER_URL_STABLE = "https://metaverse.highfidelity.com"; const QUrl METAVERSE_SERVER_URL = METAVERSE_SERVER_URL_STABLE; From 7998984d8e7e337978d77134193549eda4da28cf Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 24 Oct 2017 14:30:47 -0700 Subject: [PATCH 058/116] Missed tons of spots! --- .../resources/qml/dialogs/preferences/AvatarBrowser.qml | 2 +- .../qml/hifi/commerce/common/EmulatedMarketplaceHeader.qml | 2 +- .../tabletWindows/preferences/TabletAvatarBrowser.qml | 2 +- libraries/ui/src/ui/types/RequestFilters.cpp | 4 ++-- scripts/system/commerce/wallet.js | 2 +- scripts/system/directory.js | 2 +- scripts/system/edit.js | 2 +- scripts/system/html/js/marketplacesInject.js | 6 ++++-- scripts/system/marketplaces/marketplaces.js | 6 ++++-- scripts/system/tablet-users.js | 2 +- scripts/tutorials/getDomainMetadata.js | 2 +- 11 files changed, 18 insertions(+), 14 deletions(-) diff --git a/interface/resources/qml/dialogs/preferences/AvatarBrowser.qml b/interface/resources/qml/dialogs/preferences/AvatarBrowser.qml index e2a012ad46..5949adffca 100644 --- a/interface/resources/qml/dialogs/preferences/AvatarBrowser.qml +++ b/interface/resources/qml/dialogs/preferences/AvatarBrowser.qml @@ -33,7 +33,7 @@ Window { BaseWebView { id: webview - url: "https://metaverse.highfidelity.com/marketplace?category=avatars" + url: Account.metaverseServerURL + "/marketplace?category=avatars" focus: true anchors { diff --git a/interface/resources/qml/hifi/commerce/common/EmulatedMarketplaceHeader.qml b/interface/resources/qml/hifi/commerce/common/EmulatedMarketplaceHeader.qml index cc316a70e9..8b3f017fd2 100644 --- a/interface/resources/qml/hifi/commerce/common/EmulatedMarketplaceHeader.qml +++ b/interface/resources/qml/hifi/commerce/common/EmulatedMarketplaceHeader.qml @@ -25,7 +25,7 @@ Item { HifiConstants { id: hifi; } id: root; - property string referrerURL: "https://metaverse.highfidelity.com/marketplace?"; + property string referrerURL: (Account.metaverseServerURL + "/marketplace?"); readonly property int additionalDropdownHeight: usernameDropdown.height - myUsernameButton.anchors.bottomMargin; property alias usernameDropdownVisible: usernameDropdown.visible; diff --git a/interface/resources/qml/hifi/tablet/tabletWindows/preferences/TabletAvatarBrowser.qml b/interface/resources/qml/hifi/tablet/tabletWindows/preferences/TabletAvatarBrowser.qml index cab76bf818..34d587a3f5 100644 --- a/interface/resources/qml/hifi/tablet/tabletWindows/preferences/TabletAvatarBrowser.qml +++ b/interface/resources/qml/hifi/tablet/tabletWindows/preferences/TabletAvatarBrowser.qml @@ -31,7 +31,7 @@ Item { BaseWebView { id: webview - url: "https://metaverse.highfidelity.com/marketplace?category=avatars" + url: (Account.metaverseServerURL + "/marketplace?category=avatars)" focus: true anchors { diff --git a/libraries/ui/src/ui/types/RequestFilters.cpp b/libraries/ui/src/ui/types/RequestFilters.cpp index 1823921545..10c0eef58d 100644 --- a/libraries/ui/src/ui/types/RequestFilters.cpp +++ b/libraries/ui/src/ui/types/RequestFilters.cpp @@ -19,13 +19,13 @@ namespace { bool isAuthableHighFidelityURL(const QUrl& url) { + auto metaverseServerURL = DependencyManager::get()->getMetaverseServerURL(); static const QStringList HF_HOSTS = { "highfidelity.com", "highfidelity.io", - "metaverse.highfidelity.com", "metaverse.highfidelity.io" + metaverseServerURL.toString(), "metaverse.highfidelity.io" }; const auto& scheme = url.scheme(); const auto& host = url.host(); - auto metaverseServerURL = DependencyManager::get()->getMetaverseServerURL(); return (scheme == "https" && HF_HOSTS.contains(host)) || ((scheme == metaverseServerURL.scheme()) && (host == metaverseServerURL.host())); diff --git a/scripts/system/commerce/wallet.js b/scripts/system/commerce/wallet.js index 04b67ec14f..8e4a3215fd 100644 --- a/scripts/system/commerce/wallet.js +++ b/scripts/system/commerce/wallet.js @@ -16,7 +16,7 @@ (function () { // BEGIN LOCAL_SCOPE Script.include("/~/system/libraries/accountUtils.js"); - var MARKETPLACE_URL = "https://metaverse.highfidelity.com/marketplace"; + var MARKETPLACE_URL = Account.metaverseServerURL + "/marketplace"; // Function Name: onButtonClicked() // diff --git a/scripts/system/directory.js b/scripts/system/directory.js index ac65615a68..8b9ec17f05 100644 --- a/scripts/system/directory.js +++ b/scripts/system/directory.js @@ -15,7 +15,7 @@ Script.include([ var toolIconUrl = Script.resolvePath("assets/images/tools/"); -var DIRECTORY_WINDOW_URL = "https://metaverse.highfidelity.com/directory"; +var DIRECTORY_WINDOW_URL = Account.metaverseServerURL + "/directory"; var directoryWindow = new OverlayWebWindow({ title: 'Directory', source: "about:blank", diff --git a/scripts/system/edit.js b/scripts/system/edit.js index 2ae1e142a0..7b8ec90b7b 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -163,7 +163,7 @@ var importingSVOTextOverlay = Overlays.addOverlay("text", { visible: false }); -var MARKETPLACE_URL = "https://metaverse.highfidelity.com/marketplace"; +var MARKETPLACE_URL = Account.metaverseServerURL + "/marketplace"; var marketplaceWindow = new OverlayWebWindow({ title: 'Marketplace', source: "about:blank", diff --git a/scripts/system/html/js/marketplacesInject.js b/scripts/system/html/js/marketplacesInject.js index 29bbb4576e..8deb5c0bbd 100644 --- a/scripts/system/html/js/marketplacesInject.js +++ b/scripts/system/html/js/marketplacesInject.js @@ -29,6 +29,7 @@ var commerceMode = false; var userIsLoggedIn = false; var walletNeedsSetup = false; + var metaverseServerURL = "https://metaverse.highfidelity.com"; function injectCommonCode(isDirectoryPage) { @@ -57,7 +58,7 @@ ); // Footer. - var isInitialHiFiPage = location.href === "https://metaverse.highfidelity.com/marketplace?"; + var isInitialHiFiPage = location.href === metaverseServerURL + "/marketplace?"; $("body").append( '
' + (!isInitialHiFiPage ? '' : '') + @@ -69,7 +70,7 @@ // Footer actions. $("#back-button").on("click", function () { - (document.referrer !== "") ? window.history.back() : window.location = "https://metaverse.highfidelity.com/marketplace?"; + (document.referrer !== "") ? window.history.back() : window.location = (metaverseServerURL + "/marketplace?"); }); $("#all-markets").on("click", function () { EventBridge.emitWebEvent(GOTO_DIRECTORY); @@ -641,6 +642,7 @@ commerceMode = !!parsedJsonMessage.data.commerceMode; userIsLoggedIn = !!parsedJsonMessage.data.userIsLoggedIn; walletNeedsSetup = !!parsedJsonMessage.data.walletNeedsSetup; + metaverseServerURL = parsedJsonMessage.data.metaverseServerURL; injectCode(); } } diff --git a/scripts/system/marketplaces/marketplaces.js b/scripts/system/marketplaces/marketplaces.js index 6880d10c18..10b52d0f6a 100644 --- a/scripts/system/marketplaces/marketplaces.js +++ b/scripts/system/marketplaces/marketplaces.js @@ -15,7 +15,8 @@ Script.include("../libraries/WebTablet.js"); - var MARKETPLACE_URL = "https://metaverse.highfidelity.com/marketplace"; + var METAVERSE_SERVER_URL = Account.metaverseServerURL; + var MARKETPLACE_URL = METAVERSE_SERVER_URL + "/marketplace"; var MARKETPLACE_URL_INITIAL = MARKETPLACE_URL + "?"; // Append "?" to signal injected script that it's the initial page. var MARKETPLACES_URL = Script.resolvePath("../html/marketplaces.html"); var MARKETPLACES_INJECT_SCRIPT_URL = Script.resolvePath("../html/js/marketplacesInject.js"); @@ -155,7 +156,8 @@ data: { commerceMode: Settings.getValue("commerce", false), userIsLoggedIn: Account.loggedIn, - walletNeedsSetup: Wallet.walletStatus === 1 + walletNeedsSetup: Wallet.walletStatus === 1, + metaverseServerURL: Account.metaverseServerURL } })); } diff --git a/scripts/system/tablet-users.js b/scripts/system/tablet-users.js index 591537f9bc..6f37cd55eb 100644 --- a/scripts/system/tablet-users.js +++ b/scripts/system/tablet-users.js @@ -14,7 +14,7 @@ var USERS_URL = "https://hifi-content.s3.amazonaws.com/faye/tablet-dev/users.html"; var HOME_BUTTON_TEXTURE = Script.resourcesPath() + "meshes/tablet-with-home-button.fbx/tablet-with-home-button.fbm/button-root.png"; - var FRIENDS_WINDOW_URL = "https://metaverse.highfidelity.com/user/friends"; + var FRIENDS_WINDOW_URL = Account.metaverseServerURL + "/user/friends"; var FRIENDS_WINDOW_WIDTH = 290; var FRIENDS_WINDOW_HEIGHT = 500; var FRIENDS_WINDOW_TITLE = "Add/Remove Friends"; diff --git a/scripts/tutorials/getDomainMetadata.js b/scripts/tutorials/getDomainMetadata.js index 54c356ae7b..1af801f2d6 100644 --- a/scripts/tutorials/getDomainMetadata.js +++ b/scripts/tutorials/getDomainMetadata.js @@ -6,7 +6,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -var SERVER = 'https://metaverse.highfidelity.com/api/v1'; +var SERVER = Account.metaverseServerURL + '/api/v1'; var OVERLAY = null; From 08a6eb4dd399ef4f5cdeca95ae4ab8fb50efe97f Mon Sep 17 00:00:00 2001 From: David Back Date: Tue, 24 Oct 2017 15:50:09 -0700 Subject: [PATCH 059/116] reset tablet contextual mode back to false when toggling tablet show/hide --- interface/src/scripting/HMDScriptingInterface.cpp | 9 +++++++++ interface/src/scripting/HMDScriptingInterface.h | 4 ++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/interface/src/scripting/HMDScriptingInterface.cpp b/interface/src/scripting/HMDScriptingInterface.cpp index 0b6800395f..31b8f74e9e 100644 --- a/interface/src/scripting/HMDScriptingInterface.cpp +++ b/interface/src/scripting/HMDScriptingInterface.cpp @@ -108,6 +108,15 @@ void HMDScriptingInterface::openTablet(bool contextualMode) { _tabletContextualMode = contextualMode; } +void HMDScriptingInterface::toggleShouldShowTablet() { + setShouldShowTablet(!getShouldShowTablet()); +} + +void HMDScriptingInterface::setShouldShowTablet(bool value) { + _showTablet = value; + _tabletContextualMode = false; +} + QScriptValue HMDScriptingInterface::getHUDLookAtPosition2D(QScriptContext* context, QScriptEngine* engine) { glm::vec3 hudIntersection; auto instance = DependencyManager::get(); diff --git a/interface/src/scripting/HMDScriptingInterface.h b/interface/src/scripting/HMDScriptingInterface.h index 76bab77cbb..ef8ea95704 100644 --- a/interface/src/scripting/HMDScriptingInterface.h +++ b/interface/src/scripting/HMDScriptingInterface.h @@ -89,8 +89,8 @@ public: bool isMounted() const; - void toggleShouldShowTablet() { _showTablet = !_showTablet; } - void setShouldShowTablet(bool value) { _showTablet = value; } + void toggleShouldShowTablet(); + void setShouldShowTablet(bool value); bool getShouldShowTablet() const { return _showTablet; } bool getTabletContextualMode() const { return _tabletContextualMode; } From d7bdbfb37bae8b95652eea01411c43bfa459d2ef Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 25 Oct 2017 09:53:59 -0700 Subject: [PATCH 060/116] Fix unix build errors --- libraries/networking/src/AccountManager.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/networking/src/AccountManager.h b/libraries/networking/src/AccountManager.h index 3dae03200e..a0abde26c9 100644 --- a/libraries/networking/src/AccountManager.h +++ b/libraries/networking/src/AccountManager.h @@ -61,8 +61,8 @@ const auto DEFAULT_USER_AGENT_GETTER = []() -> QString { return HIGH_FIDELITY_US // If you want to use STAGING instead of STABLE, // don't forget to ALSO change the Domain Server Metaverse Server URL, which is at the top of: // \domain-server\resources\web\settings\js\settings.js -const QUrl METAVERSE_SERVER_URL_STAGING = "https://staging.highfidelity.com"; -const QUrl METAVERSE_SERVER_URL_STABLE = "https://metaverse.highfidelity.com"; +const QUrl METAVERSE_SERVER_URL_STAGING("https://staging.highfidelity.com"); +const QUrl METAVERSE_SERVER_URL_STABLE("https://metaverse.highfidelity.com"); const QUrl METAVERSE_SERVER_URL = METAVERSE_SERVER_URL_STABLE; class AccountManager : public QObject, public Dependency { From 3f0108528d17632921f42cd448e8ca3e1f773d3b Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 25 Oct 2017 15:19:56 -0700 Subject: [PATCH 061/116] Remove unnecessary newline --- scripts/system/marketplaces/marketplaces.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/marketplaces/marketplaces.js b/scripts/system/marketplaces/marketplaces.js index 8fc50059ab..f0044084f6 100644 --- a/scripts/system/marketplaces/marketplaces.js +++ b/scripts/system/marketplaces/marketplaces.js @@ -136,7 +136,7 @@ function setCertificateInfo(currentEntityWithContextOverlay, itemCertificateId) { wireEventBridge(true); - var certificateId = itemCertificateId || (Entities.getEntityProperties(currentEntityWithContextOverlay, ['certificateID']).certificateID + "\n"); + var certificateId = itemCertificateId || (Entities.getEntityProperties(currentEntityWithContextOverlay, ['certificateID']).certificateID); tablet.sendToQml({ method: 'inspectionCertificate_setCertificateId', certificateId: certificateId From 2f28cf1443cceef77cac4178514871f6fd57622a Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 25 Oct 2017 15:20:31 -0700 Subject: [PATCH 062/116] Remove unnecessary newline --- scripts/system/marketplaces/marketplaces.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/marketplaces/marketplaces.js b/scripts/system/marketplaces/marketplaces.js index 3bf6435a25..7dc41abcd3 100644 --- a/scripts/system/marketplaces/marketplaces.js +++ b/scripts/system/marketplaces/marketplaces.js @@ -135,7 +135,7 @@ function setCertificateInfo(currentEntityWithContextOverlay, itemCertificateId) { wireEventBridge(true); - var certificateId = itemCertificateId || (Entities.getEntityProperties(currentEntityWithContextOverlay, ['certificateID']).certificateID + "\n"); + var certificateId = itemCertificateId || (Entities.getEntityProperties(currentEntityWithContextOverlay, ['certificateID']).certificateID); tablet.sendToQml({ method: 'inspectionCertificate_setCertificateId', certificateId: certificateId From b820f397fcba7488cb316d9f6d7ef9a1c6ba8cf7 Mon Sep 17 00:00:00 2001 From: Nissim Hadar Date: Thu, 26 Oct 2017 08:39:22 -0700 Subject: [PATCH 063/116] Fix zero-divide. --- libraries/model/src/model/Haze.h | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/libraries/model/src/model/Haze.h b/libraries/model/src/model/Haze.h index fe606bf083..29eedcd372 100644 --- a/libraries/model/src/model/Haze.h +++ b/libraries/model/src/model/Haze.h @@ -30,10 +30,25 @@ namespace model { -LOG_P_005 / hazeRange_m.z); } - inline float convertHazeRangeToHazeRangeFactor(const float hazeRange_m) { return (-LOG_P_005 / hazeRange_m); } + + inline float convertHazeRangeToHazeRangeFactor(const float hazeRange_m) { + // limit range to no less than 1.0 metres + if (hazeRange_m < 1.0f) { + return -LOG_P_005; + } + else { + return -LOG_P_005 / hazeRange_m; + } + } inline float convertHazeAltitudeToHazeAltitudeFactor(const float hazeAltitude_m) { - return -LOG_P_005 / hazeAltitude_m; + // limit altitude to no less than 1.0 metres + if (hazeAltitude_m < 1.0) { + return -LOG_P_005; + } + else { + return -LOG_P_005 / hazeAltitude_m; + } } // Derivation (s is the proportion of sun blend, a is the angle at which the blend is 50%, solve for m = 0.5 From c5c996f18677dc598e3b4c94d56ff0bf7c9b9446 Mon Sep 17 00:00:00 2001 From: Nissim Hadar Date: Thu, 26 Oct 2017 09:21:38 -0700 Subject: [PATCH 064/116] Cleanup. --- libraries/model/src/model/Haze.h | 28 ++++++---------------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/libraries/model/src/model/Haze.h b/libraries/model/src/model/Haze.h index 29eedcd372..2ffdd2333b 100644 --- a/libraries/model/src/model/Haze.h +++ b/libraries/model/src/model/Haze.h @@ -16,8 +16,8 @@ #include "NumericalConstants.h" namespace model { - const float LOG_P_005 = (float)log(0.05); - const float LOG_P_05 = (float)log(0.5); + const float LOG_P_005 = logf(0.05f); + const float LOG_P_05 = logf(0.5f); // Derivation (d is distance, b is haze coefficient, f is attenuation, solve for f = 0.05 // f = exp(-d * b) @@ -30,26 +30,10 @@ namespace model { -LOG_P_005 / hazeRange_m.z); } + // limit range and altitude to no less than 1.0 metres + inline float convertHazeRangeToHazeRangeFactor(const float hazeRange_m) { return -LOG_P_005 / glm::max(hazeRange_m, 1.0f); } - inline float convertHazeRangeToHazeRangeFactor(const float hazeRange_m) { - // limit range to no less than 1.0 metres - if (hazeRange_m < 1.0f) { - return -LOG_P_005; - } - else { - return -LOG_P_005 / hazeRange_m; - } - } - - inline float convertHazeAltitudeToHazeAltitudeFactor(const float hazeAltitude_m) { - // limit altitude to no less than 1.0 metres - if (hazeAltitude_m < 1.0) { - return -LOG_P_005; - } - else { - return -LOG_P_005 / hazeAltitude_m; - } - } + inline float convertHazeAltitudeToHazeAltitudeFactor(const float hazeAltitude_m) { return -LOG_P_005 / glm::max(hazeAltitude_m, 1.0f); } // Derivation (s is the proportion of sun blend, a is the angle at which the blend is 50%, solve for m = 0.5 // s = dot(lookAngle, sunAngle) = cos(a) @@ -57,7 +41,7 @@ namespace model { // log(m) = p * log(s) // p = log(m) / log(s) inline float convertDirectionalLightAngleToPower(const float directionalLightAngle) { - return LOG_P_05 / (float)log(cos(RADIANS_PER_DEGREE * directionalLightAngle)); + return LOG_P_05 / logf(cosf(RADIANS_PER_DEGREE * directionalLightAngle)); } const glm::vec3 initialHazeColor{ 0.5f, 0.6f, 0.7f }; From ddd25da430a52d87c0e9d4fb2798205668b1dc07 Mon Sep 17 00:00:00 2001 From: beholder Date: Thu, 26 Oct 2017 17:35:28 +0300 Subject: [PATCH 065/116] 8315 Stylus appears in wrong place on hand --- .../controllerModules/tabletStylusInput.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/scripts/system/controllers/controllerModules/tabletStylusInput.js b/scripts/system/controllers/controllerModules/tabletStylusInput.js index beb86d0ef4..46b630d023 100644 --- a/scripts/system/controllers/controllerModules/tabletStylusInput.js +++ b/scripts/system/controllers/controllerModules/tabletStylusInput.js @@ -154,6 +154,25 @@ Script.include("/~/system/libraries/controllers.js"); this.showStylus = function() { if (this.stylus) { + var X_ROT_NEG_90 = { x: -0.70710678, y: 0, z: 0, w: 0.70710678 }; + var modelOrientation = Quat.multiply(this.stylusTip.orientation, X_ROT_NEG_90); + var modelOrientationAngles = Quat.safeEulerAngles(modelOrientation); + + var rotation = Overlays.getProperty(this.stylus, "rotation"); + var rotationAngles = Quat.safeEulerAngles(rotation); + + if(!Vec3.withinEpsilon(modelOrientationAngles, rotationAngles, 1)) { + var modelPositionOffset = Vec3.multiplyQbyV(modelOrientation, { x: 0, y: 0, z: MyAvatar.sensorToWorldScale * -WEB_STYLUS_LENGTH / 2 }); + + var updatedStylusProperties = { + position: Vec3.sum(this.stylusTip.position, modelPositionOffset), + rotation: modelOrientation, + dimensions: Vec3.multiply(MyAvatar.sensorToWorldScale, { x: 0.01, y: 0.01, z: WEB_STYLUS_LENGTH }), + }; + + Overlays.editOverlay(this.stylus, updatedStylusProperties); + } + return; } From f0eab58ebd6ab0891a6612f284f4a43e7f2b83f3 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Thu, 26 Oct 2017 09:41:24 -0700 Subject: [PATCH 066/116] Bug 6719 fixed --- .../dialogs/content/AttachmentsContent.qml | 18 +++++++++++++++--- interface/src/avatar/MyAvatar.cpp | 1 + interface/src/avatar/MyAvatar.h | 1 + 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/interface/resources/qml/hifi/dialogs/content/AttachmentsContent.qml b/interface/resources/qml/hifi/dialogs/content/AttachmentsContent.qml index 62cd581e3b..5c9d6822c8 100644 --- a/interface/resources/qml/hifi/dialogs/content/AttachmentsContent.qml +++ b/interface/resources/qml/hifi/dialogs/content/AttachmentsContent.qml @@ -14,13 +14,25 @@ Item { readonly property var originalAttachments: MyAvatar.getAttachmentsVariant(); property var attachments: []; - Component.onCompleted: { - for (var i = 0; i < originalAttachments.length; ++i) { - var attachment = originalAttachments[i]; + function reload(){ + content.attachments = []; + var currentAttachments = MyAvatar.getAttachmentsVariant(); + listView.model.clear(); + for (var i = 0; i < currentAttachments.length; ++i) { + var attachment = currentAttachments[i]; content.attachments.push(attachment); listView.model.append({}); } } + + Connections { + target: MyAvatar + onAttachmentsChanged: reload() + } + + Component.onCompleted: { + reload() + } Column { width: pane.width diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 3189ad3c77..0fceba82f0 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1452,6 +1452,7 @@ void MyAvatar::setAttachmentData(const QVector& attachmentData) return; } Avatar::setAttachmentData(attachmentData); + emit attachmentsChanged(); } glm::vec3 MyAvatar::getSkeletonPosition() const { diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 16ed9ea5b4..303a395a47 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -619,6 +619,7 @@ signals: void skeletonChanged(); void dominantHandChanged(const QString& hand); void sensorToWorldScaleChanged(float sensorToWorldScale); + void attachmentsChanged(); private: From 5969e0b1185eac25391eb9b1cf07c2295d936907 Mon Sep 17 00:00:00 2001 From: beholder Date: Thu, 26 Oct 2017 20:42:08 +0300 Subject: [PATCH 067/116] 8211 Add very short haptic feedback when highlighting letters on keyboard --- interface/resources/qml/controls-uit/Key.qml | 13 +++++++++++++ interface/src/ui/overlays/Web3DOverlay.cpp | 14 ++++++++++++++ interface/src/ui/overlays/Web3DOverlay.h | 2 ++ 3 files changed, 29 insertions(+) diff --git a/interface/resources/qml/controls-uit/Key.qml b/interface/resources/qml/controls-uit/Key.qml index eda9c03fa2..d66c03f179 100644 --- a/interface/resources/qml/controls-uit/Key.qml +++ b/interface/resources/qml/controls-uit/Key.qml @@ -55,8 +55,21 @@ Item { mouse.accepted = true; } + property var _HAPTIC_STRENGTH: 0.1; + property var _HAPTIC_DURATION: 3.0; + property var leftHand: 0; + property var rightHand: 1; + onEntered: { keyItem.state = "mouseOver"; + + var globalPosition = keyItem.mapToGlobal(mouseArea1.mouseX, mouseArea1.mouseY); + var deviceId = Web3DOverlay.deviceIdByTouchPoint(globalPosition.x, globalPosition.y); + var hand = deviceId - 1; + + if(hand == leftHand || hand == rightHand) { + Controller.triggerHapticPulse(_HAPTIC_STRENGTH, _HAPTIC_DURATION, hand); + } } onExited: { diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index 363c85b395..7be518e100 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -244,6 +244,8 @@ void Web3DOverlay::setupQmlSurface() { _webSurface->getSurfaceContext()->setContextProperty("SoundCache", DependencyManager::get().data()); _webSurface->getSurfaceContext()->setContextProperty("MenuInterface", MenuScriptingInterface::getInstance()); _webSurface->getSurfaceContext()->setContextProperty("Settings", SettingsScriptingInterface::getInstance()); + _webSurface->getSurfaceContext()->setContextProperty("Controller", DependencyManager::get().data()); + _webSurface->getSurfaceContext()->setContextProperty("Web3DOverlay", this); _webSurface->getSurfaceContext()->setContextProperty("pathToFonts", "../../"); @@ -272,6 +274,18 @@ void Web3DOverlay::onResizeWebSurface() { _webSurface->resize(QSize(_resolution.x, _resolution.y)); } +Q_INVOKABLE int Web3DOverlay::deviceIdByTouchPoint(qreal x, qreal y) +{ + auto mapped = _webSurface->getRootItem()->mapFromGlobal(QPoint(x, y)); + + for (auto pair : _activeTouchPoints) { + if (mapped.x() == (int) pair.second.pos().x() && mapped.y() == (int) pair.second.pos().y()) + return pair.first; + } + + return -1; +} + void Web3DOverlay::render(RenderArgs* args) { if (!_visible || !getParentVisible()) { return; diff --git a/interface/src/ui/overlays/Web3DOverlay.h b/interface/src/ui/overlays/Web3DOverlay.h index de74b95b3e..19ffe5c989 100644 --- a/interface/src/ui/overlays/Web3DOverlay.h +++ b/interface/src/ui/overlays/Web3DOverlay.h @@ -66,6 +66,8 @@ public: void destroyWebSurface(); void onResizeWebSurface(); + Q_INVOKABLE int deviceIdByTouchPoint(qreal x, qreal y); + public slots: void emitScriptEvent(const QVariant& scriptMessage); From d24f241b8896a253a31795259e0c8b57fcc0333f Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 26 Oct 2017 13:31:15 -0700 Subject: [PATCH 068/116] Fix silly javascript error --- domain-server/resources/web/settings/js/settings.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/domain-server/resources/web/settings/js/settings.js b/domain-server/resources/web/settings/js/settings.js index ecd67e30eb..c4da828bb1 100644 --- a/domain-server/resources/web/settings/js/settings.js +++ b/domain-server/resources/web/settings/js/settings.js @@ -1,8 +1,8 @@ var Settings = { showAdvanced: false, - METAVERSE_URL_STABLE: 'https://metaverse.highfidelity.com', - METAVERSE_URL_STAGING: 'https://staging.highfidelity.com', - METAVERSE_URL: METAVERSE_URL_STABLE, + // STABLE METAVERSE_URL: https://metaverse.highfidelity.com + // STAGING METAVERSE_URL: https://staging.highfidelity.com + METAVERSE_URL: 'https://metaverse.highfidelity.com', ADVANCED_CLASS: 'advanced-setting', DEPRECATED_CLASS: 'deprecated-setting', TRIGGER_CHANGE_CLASS: 'trigger-change', From 002141724bc14ef9615c4d21195cd2b27f107eda Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 26 Oct 2017 14:12:36 -0700 Subject: [PATCH 069/116] Return to using NetworkingConstants --- domain-server/src/DomainServer.cpp | 5 ++-- ice-server/src/IceServer.cpp | 4 +-- interface/src/Application.cpp | 3 ++- interface/src/commerce/Ledger.cpp | 4 ++- interface/src/networking/CloseEventSender.cpp | 5 ++-- interface/src/ui/AddressBarDialog.h | 4 +-- .../ui/overlays/ContextOverlayInterface.cpp | 6 +++-- libraries/networking/src/AccountManager.h | 10 ++----- .../networking/src/NetworkingConstants.h | 26 +++++++++++++++++++ .../src/OAuthNetworkAccessManager.cpp | 3 ++- .../script-engine/src/XMLHttpRequestClass.cpp | 7 ++--- libraries/ui/src/ui/types/RequestFilters.cpp | 3 ++- tools/ac-client/src/ACClientApp.cpp | 3 ++- tools/atp-client/src/ATPClientApp.cpp | 3 ++- 14 files changed, 59 insertions(+), 27 deletions(-) create mode 100644 libraries/networking/src/NetworkingConstants.h diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 28100efd2d..436f49c7ca 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -339,12 +340,12 @@ bool DomainServer::optionallySetupOAuth() { const QVariantMap& settingsMap = _settingsManager.getSettingsMap(); _oauthProviderURL = QUrl(settingsMap.value(OAUTH_PROVIDER_URL_OPTION).toString()); - auto accountManager = DependencyManager::get(); // if we don't have an oauth provider URL then we default to the default node auth url if (_oauthProviderURL.isEmpty()) { - _oauthProviderURL = accountManager->getMetaverseServerURL(); + _oauthProviderURL = NetworkingConstants::METAVERSE_SERVER_URL; } + auto accountManager = DependencyManager::get(); accountManager->setAuthURL(_oauthProviderURL); _oauthClientID = settingsMap.value(OAUTH_CLIENT_ID_OPTION).toString(); diff --git a/ice-server/src/IceServer.cpp b/ice-server/src/IceServer.cpp index a2e900e8d2..f8bf1f62ae 100644 --- a/ice-server/src/IceServer.cpp +++ b/ice-server/src/IceServer.cpp @@ -18,9 +18,9 @@ #include #include -#include #include #include +#include #include #include @@ -208,7 +208,7 @@ void IceServer::requestDomainPublicKey(const QUuid& domainID) { // send a request to the metaverse API for the public key for this domain auto& networkAccessManager = NetworkAccessManager::getInstance(); - QUrl publicKeyURL { DependencyManager::get()->getMetaverseServerURL() }; + QUrl publicKeyURL { NetworkingConstants::METAVERSE_SERVER_URL }; QString publicKeyPath = QString("/api/v1/domains/%1/public_key").arg(uuidStringWithoutCurlyBraces(domainID)); publicKeyURL.setPath(publicKeyPath); diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 5e41886905..f2bb52ea47 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -94,6 +94,7 @@ #include #include #include +#include #include #include #include @@ -960,7 +961,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo // set the account manager's root URL and trigger a login request if we don't have the access token accountManager->setIsAgent(true); - accountManager->setAuthURL(accountManager->getMetaverseServerURL()); + accountManager->setAuthURL(NetworkingConstants::METAVERSE_SERVER_URL); auto addressManager = DependencyManager::get(); diff --git a/interface/src/commerce/Ledger.cpp b/interface/src/commerce/Ledger.cpp index bd7668cf32..80e599fb24 100644 --- a/interface/src/commerce/Ledger.cpp +++ b/interface/src/commerce/Ledger.cpp @@ -16,6 +16,7 @@ #include "Wallet.h" #include "Ledger.h" #include "CommerceLogging.h" +#include // inventory answers {status: 'success', data: {assets: [{id: "guid", title: "name", preview: "url"}....]}} // balance answers {status: 'success', data: {balance: integer}} @@ -120,6 +121,7 @@ QString nameFromKey(const QString& key, const QStringList& publicKeys) { return "Someone"; } +static const QString MARKETPLACE_ITEMS_BASE_URL = NetworkingConstants::METAVERSE_SERVER_URL.toString() + "/marketplace/items/"; void Ledger::historySuccess(QNetworkReply& reply) { // here we send a historyResult with some extra stuff in it // Namely, the styled text we'd like to show. The issue is the @@ -152,7 +154,7 @@ void Ledger::historySuccess(QNetworkReply& reply) { } } else { coloredQuantityAndAssetTitle = QString("\"") + coloredQuantityAndAssetTitle + diff --git a/interface/src/networking/CloseEventSender.cpp b/interface/src/networking/CloseEventSender.cpp index 41e1fb8bef..de8bd897b2 100644 --- a/interface/src/networking/CloseEventSender.cpp +++ b/interface/src/networking/CloseEventSender.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -26,13 +27,13 @@ QNetworkRequest createNetworkRequest() { QNetworkRequest request; - auto accountManager = DependencyManager::get(); - QUrl requestURL = accountManager->getMetaverseServerURL(); + QUrl requestURL = NetworkingConstants::METAVERSE_SERVER_URL; requestURL.setPath(USER_ACTIVITY_URL); request.setUrl(requestURL); + auto accountManager = DependencyManager::get(); if (accountManager->hasValidAccessToken()) { request.setRawHeader(ACCESS_TOKEN_AUTHORIZATION_HEADER, diff --git a/interface/src/ui/AddressBarDialog.h b/interface/src/ui/AddressBarDialog.h index 48e702f5bf..cab533cce3 100644 --- a/interface/src/ui/AddressBarDialog.h +++ b/interface/src/ui/AddressBarDialog.h @@ -13,8 +13,8 @@ #ifndef hifi_AddressBarDialog_h #define hifi_AddressBarDialog_h -#include #include +#include class AddressBarDialog : public OffscreenQmlDialog { Q_OBJECT @@ -30,7 +30,7 @@ public: bool forwardEnabled() { return _forwardEnabled; } bool useFeed() { return _useFeed; } void setUseFeed(bool useFeed) { if (_useFeed != useFeed) { _useFeed = useFeed; emit useFeedChanged(); } } - QString metaverseServerUrl() { return DependencyManager::get()->getMetaverseServerURL().toString(); } + QString metaverseServerUrl() { return NetworkingConstants::METAVERSE_SERVER_URL.toString(); } signals: void backEnabledChanged(); diff --git a/interface/src/ui/overlays/ContextOverlayInterface.cpp b/interface/src/ui/overlays/ContextOverlayInterface.cpp index 08e8e734c0..70b75a0b17 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.cpp +++ b/interface/src/ui/overlays/ContextOverlayInterface.cpp @@ -12,8 +12,8 @@ #include "ContextOverlayInterface.h" #include "Application.h" -#include #include +#include #ifndef MIN #define MIN(a,b) ((a) < (b) ? (a) : (b)) @@ -263,6 +263,8 @@ void ContextOverlayInterface::openInspectionCertificate() { } } +static const QString MARKETPLACE_BASE_URL = NetworkingConstants::METAVERSE_SERVER_URL.toString() + "/marketplace/items/"; + void ContextOverlayInterface::openMarketplace() { // lets open the tablet and go to the current item in // the marketplace (if the current entity has a @@ -270,7 +272,7 @@ void ContextOverlayInterface::openMarketplace() { if (!_currentEntityWithContextOverlay.isNull() && _entityMarketplaceID.length() > 0) { auto tablet = dynamic_cast(_tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system")); // construct the url to the marketplace item - QString url = DependencyManager::get()->getMetaverseServerURL().toString() + "/marketplace/items/" + _entityMarketplaceID; + QString url = MARKETPLACE_BASE_URL + _entityMarketplaceID; QString MARKETPLACES_INJECT_SCRIPT_PATH = "file:///" + qApp->applicationDirPath() + "/scripts/system/html/js/marketplacesInject.js"; tablet->gotoWebScreen(url, MARKETPLACES_INJECT_SCRIPT_PATH); _hmdScriptingInterface->openTablet(); diff --git a/libraries/networking/src/AccountManager.h b/libraries/networking/src/AccountManager.h index a0abde26c9..7d97687d0b 100644 --- a/libraries/networking/src/AccountManager.h +++ b/libraries/networking/src/AccountManager.h @@ -18,6 +18,7 @@ #include #include +#include "NetworkingConstants.h" #include "NetworkAccessManager.h" #include "DataServerAccountInfo.h" @@ -58,13 +59,6 @@ using UserAgentGetter = std::function; const auto DEFAULT_USER_AGENT_GETTER = []() -> QString { return HIGH_FIDELITY_USER_AGENT; }; -// If you want to use STAGING instead of STABLE, -// don't forget to ALSO change the Domain Server Metaverse Server URL, which is at the top of: -// \domain-server\resources\web\settings\js\settings.js -const QUrl METAVERSE_SERVER_URL_STAGING("https://staging.highfidelity.com"); -const QUrl METAVERSE_SERVER_URL_STABLE("https://metaverse.highfidelity.com"); -const QUrl METAVERSE_SERVER_URL = METAVERSE_SERVER_URL_STABLE; - class AccountManager : public QObject, public Dependency { Q_OBJECT public: @@ -103,7 +97,7 @@ public: void setTemporaryDomain(const QUuid& domainID, const QString& key); const QString& getTemporaryDomainKey(const QUuid& domainID) { return _accountInfo.getTemporaryDomainKey(domainID); } - QUrl getMetaverseServerURL() { return METAVERSE_SERVER_URL; } + QUrl getMetaverseServerURL() { return NetworkingConstants::METAVERSE_SERVER_URL; } public slots: void requestAccessToken(const QString& login, const QString& password); diff --git a/libraries/networking/src/NetworkingConstants.h b/libraries/networking/src/NetworkingConstants.h new file mode 100644 index 0000000000..0bb0cee5d2 --- /dev/null +++ b/libraries/networking/src/NetworkingConstants.h @@ -0,0 +1,26 @@ +// +// NetworkingConstants.h +// libraries/networking/src +// +// Created by Stephen Birarda on 2015-03-31. +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_NetworkingConstants_h +#define hifi_NetworkingConstants_h + +#include + +namespace NetworkingConstants { + // If you want to use STAGING instead of STABLE, + // don't forget to ALSO change the Domain Server Metaverse Server URL, which is at the top of: + // \domain-server\resources\web\settings\js\settings.js + const QUrl METAVERSE_SERVER_URL_STABLE("https://metaverse.highfidelity.com"); + const QUrl METAVERSE_SERVER_URL_STAGING("https://staging.highfidelity.com"); + const QUrl METAVERSE_SERVER_URL = METAVERSE_SERVER_URL_STABLE; +} + +#endif // hifi_NetworkingConstants_h diff --git a/libraries/networking/src/OAuthNetworkAccessManager.cpp b/libraries/networking/src/OAuthNetworkAccessManager.cpp index 42b8f16575..15d5acbc67 100644 --- a/libraries/networking/src/OAuthNetworkAccessManager.cpp +++ b/libraries/networking/src/OAuthNetworkAccessManager.cpp @@ -15,6 +15,7 @@ #include "AccountManager.h" #include "LimitedNodeList.h" +#include "NetworkingConstants.h" #include "SharedUtil.h" #include "OAuthNetworkAccessManager.h" @@ -34,7 +35,7 @@ QNetworkReply* OAuthNetworkAccessManager::createRequest(QNetworkAccessManager::O auto accountManager = DependencyManager::get(); if (accountManager->hasValidAccessToken() - && req.url().host() == accountManager->getMetaverseServerURL().host()) { + && req.url().host() == NetworkingConstants::METAVERSE_SERVER_URL.host()) { QNetworkRequest authenticatedRequest(req); authenticatedRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); authenticatedRequest.setHeader(QNetworkRequest::UserAgentHeader, HIGH_FIDELITY_USER_AGENT); diff --git a/libraries/script-engine/src/XMLHttpRequestClass.cpp b/libraries/script-engine/src/XMLHttpRequestClass.cpp index c8d518e6c9..1d3c8fda32 100644 --- a/libraries/script-engine/src/XMLHttpRequestClass.cpp +++ b/libraries/script-engine/src/XMLHttpRequestClass.cpp @@ -17,10 +17,13 @@ #include #include +#include #include "ScriptEngine.h" #include "XMLHttpRequestClass.h" +const QString METAVERSE_API_URL = NetworkingConstants::METAVERSE_SERVER_URL.toString() + "/api/"; + Q_DECLARE_METATYPE(QByteArray*) XMLHttpRequestClass::XMLHttpRequestClass(QScriptEngine* engine) : @@ -137,9 +140,7 @@ void XMLHttpRequestClass::open(const QString& method, const QString& url, bool a _url.setUrl(url); _async = async; - auto metaverseApiUrl = DependencyManager::get()->getMetaverseServerURL().toString() + "/api/"; - - if (url.toLower().left(metaverseApiUrl.length()) == metaverseApiUrl) { + if (url.toLower().left(METAVERSE_API_URL.length()) == METAVERSE_API_URL) { auto accountManager = DependencyManager::get(); if (accountManager->hasValidAccessToken()) { diff --git a/libraries/ui/src/ui/types/RequestFilters.cpp b/libraries/ui/src/ui/types/RequestFilters.cpp index 10c0eef58d..b1deec47c8 100644 --- a/libraries/ui/src/ui/types/RequestFilters.cpp +++ b/libraries/ui/src/ui/types/RequestFilters.cpp @@ -10,6 +10,7 @@ // #include "RequestFilters.h" +#include "NetworkingConstants.h" #include #include @@ -19,7 +20,7 @@ namespace { bool isAuthableHighFidelityURL(const QUrl& url) { - auto metaverseServerURL = DependencyManager::get()->getMetaverseServerURL(); + auto metaverseServerURL = NetworkingConstants::METAVERSE_SERVER_URL; static const QStringList HF_HOSTS = { "highfidelity.com", "highfidelity.io", metaverseServerURL.toString(), "metaverse.highfidelity.io" diff --git a/tools/ac-client/src/ACClientApp.cpp b/tools/ac-client/src/ACClientApp.cpp index f3ea9b7348..e00560158f 100644 --- a/tools/ac-client/src/ACClientApp.cpp +++ b/tools/ac-client/src/ACClientApp.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -105,7 +106,7 @@ ACClientApp::ACClientApp(int argc, char* argv[]) : auto accountManager = DependencyManager::get(); accountManager->setIsAgent(true); - accountManager->setAuthURL(accountManager->getMetaverseServerURL()); + accountManager->setAuthURL(NetworkingConstants::METAVERSE_SERVER_URL); auto nodeList = DependencyManager::get(); diff --git a/tools/atp-client/src/ATPClientApp.cpp b/tools/atp-client/src/ATPClientApp.cpp index 85aee10d76..c5edf27b67 100644 --- a/tools/atp-client/src/ATPClientApp.cpp +++ b/tools/atp-client/src/ATPClientApp.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -144,7 +145,7 @@ ATPClientApp::ATPClientApp(int argc, char* argv[]) : auto accountManager = DependencyManager::get(); accountManager->setIsAgent(true); - accountManager->setAuthURL(accountManager->getMetaverseServerURL()); + accountManager->setAuthURL(NetworkingConstants::METAVERSE_SERVER_URL); auto nodeList = DependencyManager::get(); From f6fa85fed21b96963c23b213a7e1ee37754ef3e1 Mon Sep 17 00:00:00 2001 From: beholder Date: Fri, 27 Oct 2017 01:08:01 +0300 Subject: [PATCH 070/116] adjust to coding standards --- interface/resources/qml/controls-uit/Key.qml | 2 +- interface/src/ui/overlays/Web3DOverlay.cpp | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/interface/resources/qml/controls-uit/Key.qml b/interface/resources/qml/controls-uit/Key.qml index d66c03f179..973f4df346 100644 --- a/interface/resources/qml/controls-uit/Key.qml +++ b/interface/resources/qml/controls-uit/Key.qml @@ -67,7 +67,7 @@ Item { var deviceId = Web3DOverlay.deviceIdByTouchPoint(globalPosition.x, globalPosition.y); var hand = deviceId - 1; - if(hand == leftHand || hand == rightHand) { + if (hand == leftHand || hand == rightHand) { Controller.triggerHapticPulse(_HAPTIC_STRENGTH, _HAPTIC_DURATION, hand); } } diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index 7be518e100..afa38608ff 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -274,16 +274,18 @@ void Web3DOverlay::onResizeWebSurface() { _webSurface->resize(QSize(_resolution.x, _resolution.y)); } -Q_INVOKABLE int Web3DOverlay::deviceIdByTouchPoint(qreal x, qreal y) -{ +const int INVALID_DEVICE_ID = -1; + +Q_INVOKABLE int Web3DOverlay::deviceIdByTouchPoint(qreal x, qreal y) { auto mapped = _webSurface->getRootItem()->mapFromGlobal(QPoint(x, y)); for (auto pair : _activeTouchPoints) { - if (mapped.x() == (int) pair.second.pos().x() && mapped.y() == (int) pair.second.pos().y()) + if (mapped.x() == (int)pair.second.pos().x() && mapped.y() == (int)pair.second.pos().y()) { return pair.first; + } } - return -1; + return INVALID_DEVICE_ID; } void Web3DOverlay::render(RenderArgs* args) { From 6093cef6f00a987e168336f5f67403917ef9c44a Mon Sep 17 00:00:00 2001 From: beholder Date: Fri, 27 Oct 2017 01:14:07 +0300 Subject: [PATCH 071/116] add comments to explain '-1' --- interface/resources/qml/controls-uit/Key.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/qml/controls-uit/Key.qml b/interface/resources/qml/controls-uit/Key.qml index 973f4df346..e54250c872 100644 --- a/interface/resources/qml/controls-uit/Key.qml +++ b/interface/resources/qml/controls-uit/Key.qml @@ -65,7 +65,7 @@ Item { var globalPosition = keyItem.mapToGlobal(mouseArea1.mouseX, mouseArea1.mouseY); var deviceId = Web3DOverlay.deviceIdByTouchPoint(globalPosition.x, globalPosition.y); - var hand = deviceId - 1; + var hand = deviceId - 1; // based on touchEventUtils.js, deviceId is 'hand + 1', so 'hand' is 'deviceId' - 1 if (hand == leftHand || hand == rightHand) { Controller.triggerHapticPulse(_HAPTIC_STRENGTH, _HAPTIC_DURATION, hand); From 10d05ba6c9ae41e62e67f5780e09a75b3bc64f16 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 26 Oct 2017 16:34:49 -0700 Subject: [PATCH 072/116] only respond to expected ICE peers in DS --- domain-server/src/DomainGatekeeper.cpp | 10 ++++++++-- libraries/networking/src/NodeList.cpp | 4 ++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/domain-server/src/DomainGatekeeper.cpp b/domain-server/src/DomainGatekeeper.cpp index 09bebf806a..188c420a5d 100644 --- a/domain-server/src/DomainGatekeeper.cpp +++ b/domain-server/src/DomainGatekeeper.cpp @@ -814,9 +814,15 @@ void DomainGatekeeper::processICEPeerInformationPacket(QSharedPointer message) { auto limitedNodeList = DependencyManager::get(); - auto pingReplyPacket = limitedNodeList->constructICEPingReplyPacket(*message, limitedNodeList->getSessionUUID()); - limitedNodeList->sendPacket(std::move(pingReplyPacket), message->getSenderSockAddr()); + // before we respond to this ICE ping packet, make sure we have a peer in the list that matches + QUuid icePeerID = QUuid::fromRfc4122({ message->getRawMessage(), NUM_BYTES_RFC4122_UUID }); + + if (_icePeers.contains(icePeerID)) { + auto pingReplyPacket = limitedNodeList->constructICEPingReplyPacket(*message, limitedNodeList->getSessionUUID()); + + limitedNodeList->sendPacket(std::move(pingReplyPacket), message->getSenderSockAddr()); + } } void DomainGatekeeper::processICEPingReplyPacket(QSharedPointer message) { diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index fcf369f786..71128c5ff0 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -557,10 +557,10 @@ void NodeList::pingPunchForDomainServer() { flagTimeForConnectionStep(LimitedNodeList::ConnectionStep::SendPingsToDS); // send the ping packet to the local and public sockets for this node - auto localPingPacket = constructICEPingPacket(PingType::Local, _sessionUUID); + auto localPingPacket = constructICEPingPacket(PingType::Local, _domainHandler.getICEClientID()); sendPacket(std::move(localPingPacket), _domainHandler.getICEPeer().getLocalSocket()); - auto publicPingPacket = constructICEPingPacket(PingType::Public, _sessionUUID); + auto publicPingPacket = constructICEPingPacket(PingType::Public, _domainHandler.getICEClientID()); sendPacket(std::move(publicPingPacket), _domainHandler.getICEPeer().getPublicSocket()); _domainHandler.getICEPeer().incrementConnectionAttempts(); From 8cb60fc62c259b3605446c9ae0ec47f2ab6b58c5 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 26 Oct 2017 16:44:21 -0700 Subject: [PATCH 073/116] Small edit.js changes --- scripts/system/edit.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/system/edit.js b/scripts/system/edit.js index ef1f2049bb..a3ca1bc5dc 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -415,7 +415,7 @@ var toolBar = (function () { } }); - var hasRezPermissions = (Entities.canRez() || Entities.canRezTmp()); + var hasRezPermissions = (Entities.canRez() || Entities.canRezTmp() || Entities.canRezCertified() || Entities.canRezTmpCertified()); var createButtonIconRsrc = (hasRezPermissions ? CREATE_ENABLED_ICON : CREATE_DISABLED_ICON); tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); activeButton = tablet.addButton({ @@ -434,7 +434,7 @@ var toolBar = (function () { tablet.fromQml.connect(fromQml); createButton.clicked.connect(function() { - if ( ! (Entities.canRez() || Entities.canRezTmp()) ) { + if ( ! (Entities.canRez() || Entities.canRezTmp() || Entities.canRezCertified() || Entities.canRezTmpCertified()) ) { Window.notifyEditError(INSUFFICIENT_PERMISSIONS_ERROR_MSG); return; } @@ -634,7 +634,7 @@ var toolBar = (function () { if (active === isActive) { return; } - if (active && !Entities.canRez() && !Entities.canRezTmp()) { + if (active && !Entities.canRez() && !Entities.canRezTmp() && !Entities.canRezCertified() && !Entities.canRezTmpCertified()) { Window.notifyEditError(INSUFFICIENT_PERMISSIONS_ERROR_MSG); return; } @@ -789,7 +789,7 @@ function handleDomainChange() { return; } - var hasRezPermissions = (Entities.canRez() || Entities.canRezTmp()); + var hasRezPermissions = (Entities.canRez() || Entities.canRezTmp() || Entities.canRezCertified() || Entities.canRezTmpCertified()); createButton.editProperties({ icon: (hasRezPermissions ? CREATE_ENABLED_ICON : CREATE_DISABLED_ICON), captionColorOverride: (hasRezPermissions ? "" : "#888888"), @@ -1491,7 +1491,7 @@ function onFileOpenChanged(filename) { } } if (importURL) { - if (!isActive && (Entities.canRez() && Entities.canRezTmp())) { + if (!isActive && (Entities.canRez() && Entities.canRezTmp() && Entities.canRezCertified() && Entities.canRezTmpCertified())) { toolBar.toggle(); } importSVO(importURL); @@ -1501,7 +1501,7 @@ function onFileOpenChanged(filename) { function onPromptTextChanged(prompt) { Window.promptTextChanged.disconnect(onPromptTextChanged); if (prompt !== "") { - if (!isActive && (Entities.canRez() && Entities.canRezTmp())) { + if (!isActive && (Entities.canRez() && Entities.canRezTmp() && Entities.canRezCertified() && Entities.canRezTmpCertified())) { toolBar.toggle(); } importSVO(prompt); From 9481824d0ab11cd35b8f9da991e99af367730e0e Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 26 Oct 2017 17:02:09 -0700 Subject: [PATCH 074/116] Fix enabled status of wear button --- interface/resources/qml/hifi/commerce/checkout/Checkout.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml index 8ea9ce494c..dfe0c319e5 100644 --- a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml +++ b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml @@ -585,7 +585,7 @@ Rectangle { // "Rez" button HifiControlsUit.Button { id: rezNowButton; - enabled: root.canRezCertifiedItems; + enabled: root.canRezCertifiedItems || root.isWearable; buttonGlyph: hifi.glyphs.lightning; color: hifi.buttons.red; colorScheme: hifi.colorSchemes.light; @@ -634,7 +634,7 @@ Rectangle { } RalewaySemiBold { id: explainRezText; - //visible: !root.isWearable; + visible: !root.isWearable; text: 'What does "Rez" mean?' // Text size size: 16; From 79338f43162963839d5891567d721ddf19360515 Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 26 Oct 2017 17:12:49 -0700 Subject: [PATCH 075/116] removing the the unecessary files and trying using qrc:///qml --- .../utilities/lib/configprop/ConfigSlider.qml | 4 +- .../lib/hifi-qml/controls-uit/Button.qml | 73 ---- .../lib/hifi-qml/controls-uit/CheckBox.qml | 101 ------ .../lib/hifi-qml/controls-uit/ComboBox.qml | 249 ------------- .../hifi-qml/controls-uit/ConfigSlider.qml | 72 ---- .../hifi-qml/controls-uit/ContentSection.qml | 138 ------- .../lib/hifi-qml/controls-uit/GlyphButton.qml | 78 ---- .../hifi-qml/controls-uit/HorizontalRule.qml | 20 - .../controls-uit/HorizontalSpacer.qml | 21 -- .../lib/hifi-qml/controls-uit/Label.qml | 22 -- .../hifi-qml/controls-uit/QueuedButton.qml | 43 --- .../lib/hifi-qml/controls-uit/RadioButton.qml | 71 ---- .../lib/hifi-qml/controls-uit/Separator.qml | 38 -- .../lib/hifi-qml/controls-uit/Slider.qml | 98 ----- .../lib/hifi-qml/controls-uit/SpinBox.qml | 117 ------ .../lib/hifi-qml/controls-uit/Switch.qml | 156 -------- .../lib/hifi-qml/controls-uit/Table.qml | 179 --------- .../hifi-qml/controls-uit/VerticalSpacer.qml | 21 -- .../styles-uit/AnonymousProRegular.qml | 23 -- .../lib/hifi-qml/styles-uit/ButtonLabel.qml | 18 - .../hifi-qml/styles-uit/FiraSansRegular.qml | 23 -- .../hifi-qml/styles-uit/FiraSansSemiBold.qml | 23 -- .../lib/hifi-qml/styles-uit/HiFiGlyphs.qml | 25 -- .../lib/hifi-qml/styles-uit/HifiConstants.qml | 342 ------------------ .../lib/hifi-qml/styles-uit/IconButton.qml | 20 - .../lib/hifi-qml/styles-uit/InfoItem.qml | 19 - .../lib/hifi-qml/styles-uit/InputLabel.qml | 18 - .../lib/hifi-qml/styles-uit/ListItem.qml | 18 - .../lib/hifi-qml/styles-uit/Logs.qml | 18 - .../lib/hifi-qml/styles-uit/OverlayTitle.qml | 18 - .../lib/hifi-qml/styles-uit/RalewayBold.qml | 24 -- .../lib/hifi-qml/styles-uit/RalewayLight.qml | 23 -- .../hifi-qml/styles-uit/RalewayRegular.qml | 23 -- .../hifi-qml/styles-uit/RalewaySemiBold.qml | 23 -- .../lib/hifi-qml/styles-uit/SectionName.qml | 19 - .../lib/hifi-qml/styles-uit/Separator.qml | 41 --- .../lib/hifi-qml/styles-uit/ShortcutText.qml | 18 - .../lib/hifi-qml/styles-uit/TabName.qml | 19 - .../hifi-qml/styles-uit/TextFieldInput.qml | 18 - .../utilities/render/deferredLighting.qml | 4 +- 40 files changed, 4 insertions(+), 2274 deletions(-) delete mode 100644 scripts/developer/utilities/lib/hifi-qml/controls-uit/Button.qml delete mode 100644 scripts/developer/utilities/lib/hifi-qml/controls-uit/CheckBox.qml delete mode 100644 scripts/developer/utilities/lib/hifi-qml/controls-uit/ComboBox.qml delete mode 100644 scripts/developer/utilities/lib/hifi-qml/controls-uit/ConfigSlider.qml delete mode 100644 scripts/developer/utilities/lib/hifi-qml/controls-uit/ContentSection.qml delete mode 100644 scripts/developer/utilities/lib/hifi-qml/controls-uit/GlyphButton.qml delete mode 100644 scripts/developer/utilities/lib/hifi-qml/controls-uit/HorizontalRule.qml delete mode 100644 scripts/developer/utilities/lib/hifi-qml/controls-uit/HorizontalSpacer.qml delete mode 100644 scripts/developer/utilities/lib/hifi-qml/controls-uit/Label.qml delete mode 100644 scripts/developer/utilities/lib/hifi-qml/controls-uit/QueuedButton.qml delete mode 100644 scripts/developer/utilities/lib/hifi-qml/controls-uit/RadioButton.qml delete mode 100644 scripts/developer/utilities/lib/hifi-qml/controls-uit/Separator.qml delete mode 100644 scripts/developer/utilities/lib/hifi-qml/controls-uit/Slider.qml delete mode 100644 scripts/developer/utilities/lib/hifi-qml/controls-uit/SpinBox.qml delete mode 100644 scripts/developer/utilities/lib/hifi-qml/controls-uit/Switch.qml delete mode 100644 scripts/developer/utilities/lib/hifi-qml/controls-uit/Table.qml delete mode 100644 scripts/developer/utilities/lib/hifi-qml/controls-uit/VerticalSpacer.qml delete mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/AnonymousProRegular.qml delete mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/ButtonLabel.qml delete mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/FiraSansRegular.qml delete mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/FiraSansSemiBold.qml delete mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/HiFiGlyphs.qml delete mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/HifiConstants.qml delete mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/IconButton.qml delete mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/InfoItem.qml delete mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/InputLabel.qml delete mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/ListItem.qml delete mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/Logs.qml delete mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/OverlayTitle.qml delete mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/RalewayBold.qml delete mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/RalewayLight.qml delete mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/RalewayRegular.qml delete mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/RalewaySemiBold.qml delete mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/SectionName.qml delete mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/Separator.qml delete mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/ShortcutText.qml delete mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/TabName.qml delete mode 100644 scripts/developer/utilities/lib/hifi-qml/styles-uit/TextFieldInput.qml diff --git a/scripts/developer/utilities/lib/configprop/ConfigSlider.qml b/scripts/developer/utilities/lib/configprop/ConfigSlider.qml index f82b381a2d..bb46536fdc 100644 --- a/scripts/developer/utilities/lib/configprop/ConfigSlider.qml +++ b/scripts/developer/utilities/lib/configprop/ConfigSlider.qml @@ -12,8 +12,8 @@ import QtQuick 2.7 import QtQuick.Controls 1.4 as Original import QtQuick.Controls.Styles 1.4 -import "../hifi-qml/styles-uit" -import "../hifi-qml/controls-uit" as HifiControls +import "qrc:///qml/styles-uit" +import "qrc:///qml/controls-uit" as HifiControls Item { diff --git a/scripts/developer/utilities/lib/hifi-qml/controls-uit/Button.qml b/scripts/developer/utilities/lib/hifi-qml/controls-uit/Button.qml deleted file mode 100644 index 59f8a63238..0000000000 --- a/scripts/developer/utilities/lib/hifi-qml/controls-uit/Button.qml +++ /dev/null @@ -1,73 +0,0 @@ -// -// Button.qml -// -// Created by David Rowe on 16 Feb 2016 -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -import QtQuick 2.5 -import QtQuick.Controls 1.4 as Original -import QtQuick.Controls.Styles 1.4 - -import "../styles-uit" - -Original.Button { - property int color: 0 - property int colorScheme: hifi.colorSchemes.light - - width: 120 - height: hifi.dimensions.controlLineHeight - - HifiConstants { id: hifi } - - style: ButtonStyle { - - background: Rectangle { - radius: hifi.buttons.radius - - gradient: Gradient { - GradientStop { - position: 0.2 - color: { - if (!control.enabled) { - hifi.buttons.disabledColorStart[control.colorScheme] - } else if (control.pressed) { - hifi.buttons.pressedColor[control.color] - } else if (control.hovered) { - hifi.buttons.hoveredColor[control.color] - } else { - hifi.buttons.colorStart[control.color] - } - } - } - GradientStop { - position: 1.0 - color: { - if (!control.enabled) { - hifi.buttons.disabledColorFinish[control.colorScheme] - } else if (control.pressed) { - hifi.buttons.pressedColor[control.color] - } else if (control.hovered) { - hifi.buttons.hoveredColor[control.color] - } else { - hifi.buttons.colorFinish[control.color] - } - } - } - } - } - - label: RalewayBold { - font.capitalization: Font.AllUppercase - color: enabled ? hifi.buttons.textColor[control.color] - : hifi.buttons.disabledTextColor[control.colorScheme] - size: hifi.fontSizes.buttonLabel - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - text: control.text - } - } -} diff --git a/scripts/developer/utilities/lib/hifi-qml/controls-uit/CheckBox.qml b/scripts/developer/utilities/lib/hifi-qml/controls-uit/CheckBox.qml deleted file mode 100644 index b279b7ca8d..0000000000 --- a/scripts/developer/utilities/lib/hifi-qml/controls-uit/CheckBox.qml +++ /dev/null @@ -1,101 +0,0 @@ -// -// CheckBox.qml -// -// Created by David Rowe on 26 Feb 2016 -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -import QtQuick 2.5 -import QtQuick.Controls 1.4 as Original -import QtQuick.Controls.Styles 1.4 - -import "../styles-uit" - -Original.CheckBox { - id: checkBox - - property int colorScheme: hifi.colorSchemes.light - property string color: hifi.colors.lightGrayText - readonly property bool isLightColorScheme: colorScheme == hifi.colorSchemes.light - property bool isRedCheck: false - property int boxSize: 14 - property int boxRadius: 3 - property bool wrap: true; - readonly property int checkSize: Math.max(boxSize - 8, 10) - readonly property int checkRadius: 2 - activeFocusOnPress: true - - style: CheckBoxStyle { - indicator: Rectangle { - id: box - width: boxSize - height: boxSize - radius: boxRadius - border.width: 1 - border.color: pressed || hovered - ? hifi.colors.checkboxCheckedBorder - : (checkBox.isLightColorScheme ? hifi.colors.checkboxLightFinish : hifi.colors.checkboxDarkFinish) - - gradient: Gradient { - GradientStop { - position: 0.2 - color: pressed || hovered - ? (checkBox.isLightColorScheme ? hifi.colors.checkboxChecked : hifi.colors.checkboxLightStart) - : (checkBox.isLightColorScheme ? hifi.colors.checkboxLightStart : hifi.colors.checkboxDarkStart) - } - GradientStop { - position: 1.0 - color: pressed || hovered - ? (checkBox.isLightColorScheme ? hifi.colors.checkboxChecked : hifi.colors.checkboxLightFinish) - : (checkBox.isLightColorScheme ? hifi.colors.checkboxLightFinish : hifi.colors.checkboxDarkFinish) - } - } - - Rectangle { - visible: pressed || hovered - anchors.centerIn: parent - id: innerBox - width: checkSize - 4 - height: width - radius: checkRadius - color: hifi.colors.checkboxCheckedBorder - } - - Rectangle { - id: check - width: checkSize - height: checkSize - radius: checkRadius - anchors.centerIn: parent - color: isRedCheck ? hifi.colors.checkboxCheckedRed : hifi.colors.checkboxChecked - border.width: 2 - border.color: isRedCheck? hifi.colors.checkboxCheckedBorderRed : hifi.colors.checkboxCheckedBorder - visible: checked && !pressed || !checked && pressed - } - - Rectangle { - id: disabledOverlay - visible: !enabled - width: boxSize - height: boxSize - radius: boxRadius - border.width: 1 - border.color: hifi.colors.baseGrayHighlight - color: hifi.colors.baseGrayHighlight - opacity: 0.5 - } - } - - label: Label { - text: control.text - color: control.color - x: 2 - wrapMode: checkBox.wrap ? Text.Wrap : Text.NoWrap - elide: checkBox.wrap ? Text.ElideNone : Text.ElideRight - enabled: checkBox.enabled - } - } -} diff --git a/scripts/developer/utilities/lib/hifi-qml/controls-uit/ComboBox.qml b/scripts/developer/utilities/lib/hifi-qml/controls-uit/ComboBox.qml deleted file mode 100644 index d672fa6387..0000000000 --- a/scripts/developer/utilities/lib/hifi-qml/controls-uit/ComboBox.qml +++ /dev/null @@ -1,249 +0,0 @@ -// -// ComboBox.qml -// -// Created by Bradley Austin David on 27 Jan 2016 -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 - -import "../styles-uit" -import "../controls-uit" as HifiControls - -FocusScope { - id: root - HifiConstants { id: hifi } - - property alias model: comboBox.model; - property alias editable: comboBox.editable - property alias comboBox: comboBox - readonly property alias currentText: comboBox.currentText; - property alias currentIndex: comboBox.currentIndex; - - property int dropdownHeight: 480 - property int colorScheme: hifi.colorSchemes.light - readonly property bool isLightColorScheme: colorScheme == hifi.colorSchemes.light - property string label: "" - property real controlHeight: height + (comboBoxLabel.visible ? comboBoxLabel.height + comboBoxLabel.anchors.bottomMargin : 0) - - readonly property ComboBox control: comboBox - - property bool isDesktop: true - - signal accepted(); - - implicitHeight: comboBox.height; - focus: true - - Rectangle { - id: background - gradient: Gradient { - GradientStop { - position: 0.2 - color: popup.visible - ? (isLightColorScheme ? hifi.colors.dropDownPressedLight : hifi.colors.dropDownPressedDark) - : (isLightColorScheme ? hifi.colors.dropDownLightStart : hifi.colors.dropDownDarkStart) - } - GradientStop { - position: 1.0 - color: popup.visible - ? (isLightColorScheme ? hifi.colors.dropDownPressedLight : hifi.colors.dropDownPressedDark) - : (isLightColorScheme ? hifi.colors.dropDownLightFinish : hifi.colors.dropDownDarkFinish) - } - } - anchors.fill: parent - } - - SystemPalette { id: palette } - - ComboBox { - id: comboBox - anchors.fill: parent - visible: false - height: hifi.fontSizes.textFieldInput + 13 // Match height of TextField control. - } - - FiraSansSemiBold { - id: textField - anchors { - left: parent.left - leftMargin: hifi.dimensions.textPadding - right: dropIcon.left - verticalCenter: parent.verticalCenter - } - size: hifi.fontSizes.textFieldInput - text: comboBox.currentText - elide: Text.ElideRight - color: controlHover.containsMouse || popup.visible ? hifi.colors.baseGray : (isLightColorScheme ? hifi.colors.lightGray : hifi.colors.lightGrayText ) - } - - Item { - id: dropIcon - anchors { right: parent.right; verticalCenter: parent.verticalCenter } - height: background.height - width: height - Rectangle { - width: 1 - height: parent.height - anchors.top: parent.top - anchors.left: parent.left - color: isLightColorScheme ? hifi.colors.faintGray : hifi.colors.baseGray - } - HiFiGlyphs { - anchors { - top: parent.top - topMargin: -11 - horizontalCenter: parent.horizontalCenter - } - size: hifi.dimensions.spinnerSize - text: hifi.glyphs.caratDn - color: controlHover.containsMouse || popup.visible ? hifi.colors.baseGray : (isLightColorScheme ? hifi.colors.lightGray : hifi.colors.lightGrayText) - } - } - - MouseArea { - id: controlHover - hoverEnabled: true - anchors.fill: parent - onClicked: toggleList(); - } - - function toggleList() { - if (popup.visible) { - hideList(); - } else { - showList(); - } - } - - function showList() { - var r; - if (isDesktop) { - r = desktop.mapFromItem(root, 0, 0, root.width, root.height); - } else { - r = mapFromItem(root, 0, 0, root.width, root.height); - } - var y = r.y + r.height; - var bottom = y + scrollView.height; - var height = isDesktop ? desktop.height : tabletRoot.height; - if (bottom > height) { - y -= bottom - height + 8; - } - scrollView.x = r.x; - scrollView.y = y; - popup.visible = true; - popup.forceActiveFocus(); - listView.currentIndex = root.currentIndex; - scrollView.hoverEnabled = true; - } - - function hideList() { - popup.visible = false; - scrollView.hoverEnabled = false; - root.accepted(); - } - - FocusScope { - id: popup - parent: isDesktop ? desktop : root - anchors.fill: parent - z: isDesktop ? desktop.zLevels.menu : 12 - visible: false - focus: true - - MouseArea { - anchors.fill: parent - onClicked: hideList(); - } - - function previousItem() { listView.currentIndex = (listView.currentIndex + listView.count - 1) % listView.count; } - function nextItem() { listView.currentIndex = (listView.currentIndex + listView.count + 1) % listView.count; } - function selectCurrentItem() { root.currentIndex = listView.currentIndex; hideList(); } - function selectSpecificItem(index) { root.currentIndex = index; hideList(); } - - Keys.onUpPressed: previousItem(); - Keys.onDownPressed: nextItem(); - Keys.onSpacePressed: selectCurrentItem(); - Keys.onRightPressed: selectCurrentItem(); - Keys.onReturnPressed: selectCurrentItem(); - Keys.onEscapePressed: hideList(); - - ScrollView { - id: scrollView - height: root.dropdownHeight - width: root.width + 4 - property bool hoverEnabled: false; - - style: ScrollViewStyle { - decrementControl: Item { - visible: false - } - incrementControl: Item { - visible: false - } - scrollBarBackground: Rectangle{ - implicitWidth: 20 - color: hifi.colors.baseGray - } - - handle: - Rectangle { - implicitWidth: 16 - anchors.left: parent.left - anchors.leftMargin: 3 - anchors.top: parent.top - anchors.bottom: parent.bottom - radius: 6 - color: hifi.colors.lightGrayText - } - } - - ListView { - id: listView - height: textField.height * count * 1.4 - model: root.model - delegate: Rectangle { - width: root.width + 4 - height: popupText.implicitHeight * 1.4 - color: (listView.currentIndex === index) ? hifi.colors.primaryHighlight : - (isLightColorScheme ? hifi.colors.dropDownPressedLight : hifi.colors.dropDownPressedDark) - FiraSansSemiBold { - anchors.left: parent.left - anchors.leftMargin: hifi.dimensions.textPadding - anchors.verticalCenter: parent.verticalCenter - id: popupText - text: listView.model[index] ? listView.model[index] : (listView.model.get && listView.model.get(index).text ? listView.model.get(index).text : "") - size: hifi.fontSizes.textFieldInput - color: hifi.colors.baseGray - } - MouseArea { - id: popupHover - anchors.fill: parent; - hoverEnabled: scrollView.hoverEnabled; - onEntered: listView.currentIndex = index; - onClicked: popup.selectSpecificItem(index); - } - } - } - } - } - - HifiControls.Label { - id: comboBoxLabel - text: root.label - colorScheme: root.colorScheme - anchors.left: parent.left - anchors.bottom: parent.top - anchors.bottomMargin: 4 - visible: label != "" - } - - Component.onCompleted: { - isDesktop = (typeof desktop !== "undefined"); - } -} diff --git a/scripts/developer/utilities/lib/hifi-qml/controls-uit/ConfigSlider.qml b/scripts/developer/utilities/lib/hifi-qml/controls-uit/ConfigSlider.qml deleted file mode 100644 index 9c38b66ed8..0000000000 --- a/scripts/developer/utilities/lib/hifi-qml/controls-uit/ConfigSlider.qml +++ /dev/null @@ -1,72 +0,0 @@ -// -// ConfigSlider.qml -// examples/utilities/tools/render -// -// Created by Zach Pomerantz on 2/8/2016 -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html -// - -import QtQuick 2.5 -import QtQuick.Controls 1.4 as Original -import QtQuick.Controls.Styles 1.4 - -import "../styles-uit" -import "../controls-uit" as HifiControls - -Item { - id: root - width: 400 - height: 24 - property bool integral: false - property var config - property string property - property alias label: labelControl.text - property alias min: sliderControl.minimumValue - property alias max: sliderControl.maximumValue - - Component.onCompleted: { - // Binding favors qml value, so set it first - sliderControl.value = root.config[root.property]; - bindingControl.when = true; - } - - HifiControls.Label { - id: labelControl - text: root.label - anchors.left: root.left - anchors.leftMargin: 8 - anchors.top: root.top - anchors.topMargin: 7 - } - - HifiControls.Label { - id: labelValue - text: sliderControl.value.toFixed(root.integral ? 0 : 2) - anchors.right: root.right - anchors.rightMargin: 8 - anchors.top: root.top - anchors.topMargin: 15 - } - - Binding { - id: bindingControl - target: root.config - property: root.property - value: sliderControl.value - when: false - } - - HifiControls.Slider { - id: sliderControl - stepSize: root.integral ? 1.0 : 0.0 - width: root.width-130 - height: 20 - anchors.right: root.right - anchors.rightMargin: 8 - anchors.top: root.top - anchors.topMargin: 3 - } -} diff --git a/scripts/developer/utilities/lib/hifi-qml/controls-uit/ContentSection.qml b/scripts/developer/utilities/lib/hifi-qml/controls-uit/ContentSection.qml deleted file mode 100644 index 47a13e9262..0000000000 --- a/scripts/developer/utilities/lib/hifi-qml/controls-uit/ContentSection.qml +++ /dev/null @@ -1,138 +0,0 @@ -// -// ContentSection.qml -// -// Created by David Rowe on 16 Feb 2016 -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -import QtQuick 2.5 -import QtGraphicalEffects 1.0 - -import "../styles-uit" - -Column { - property string name: "Content Section" - property bool isFirst: false - property bool isCollapsible: false // Set at creation. - property bool isCollapsed: false - - spacing: 0 // Defer spacing decisions to individual controls. - - anchors { - left: parent.left - leftMargin: hifi.dimensions.contentMargin.x - right: parent.right - rightMargin: hifi.dimensions.contentMargin.x - } - - function toggleCollapsed() { - if (isCollapsible) { - isCollapsed = !isCollapsed; - for (var i = 1; i < children.length; i++) { - children[i].visible = !isCollapsed; - } - } - } - - Item { - id: sectionName - anchors.left: parent.left - anchors.right: parent.right - height: leadingSpace.height + topBar.height + heading.height + bottomBar.height - - Item { - id: leadingSpace - width: 1 - height: isFirst ? 7 : 0 - anchors.top: parent.top - } - - Item { - id: topBar - visible: !isFirst - height: visible ? 2 : 0 - anchors.top: leadingSpace.bottom - - Rectangle { - id: shadow - width: frame.width - height: 1 - color: hifi.colors.baseGrayShadow - x: -hifi.dimensions.contentMargin.x - } - - Rectangle { - width: frame.width - height: 1 - color: hifi.colors.baseGrayHighlight - x: -hifi.dimensions.contentMargin.x - anchors.top: shadow.bottom - } - } - - Item { - id: heading - anchors { - left: parent.left - right: parent.right - top: topBar.bottom - } - height: isCollapsible ? 36 : 28 - - RalewayRegular { - id: title - anchors { - left: parent.left - top: parent.top - topMargin: 12 - } - size: hifi.fontSizes.sectionName - font.capitalization: Font.AllUppercase - text: name - color: hifi.colors.lightGrayText - } - - HiFiGlyphs { - anchors { - top: title.top - topMargin: -9 - right: parent.right - rightMargin: -4 - } - size: hifi.fontSizes.disclosureButton - text: isCollapsed ? hifi.glyphs.disclosureButtonExpand : hifi.glyphs.disclosureButtonCollapse - color: hifi.colors.lightGrayText - visible: isCollapsible - } - - MouseArea { - // Events are propogated so that any active control is defocused. - anchors.fill: parent - propagateComposedEvents: true - onPressed: { - toggleCollapsed(); - mouse.accepted = false; - } - } - } - - LinearGradient { - id: bottomBar - visible: desktop.gradientsSupported && isCollapsible - width: frame.width - height: visible ? 4 : 0 - x: -hifi.dimensions.contentMargin.x - anchors.top: heading.bottom - start: Qt.point(0, 0) - end: Qt.point(0, 4) - gradient: Gradient { - GradientStop { position: 0.0; color: hifi.colors.darkGray } - GradientStop { position: 1.0; color: hifi.colors.baseGray } // Equivalent of darkGray0 over baseGray background. - } - cached: true - } - } -} diff --git a/scripts/developer/utilities/lib/hifi-qml/controls-uit/GlyphButton.qml b/scripts/developer/utilities/lib/hifi-qml/controls-uit/GlyphButton.qml deleted file mode 100644 index ac353b5a52..0000000000 --- a/scripts/developer/utilities/lib/hifi-qml/controls-uit/GlyphButton.qml +++ /dev/null @@ -1,78 +0,0 @@ -// -// GlyphButton.qml -// -// Created by Clement on 3/7/16 -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - - -import QtQuick 2.5 -import QtQuick.Controls 1.4 as Original -import QtQuick.Controls.Styles 1.4 - -import "../styles-uit" - -Original.Button { - property int color: 0 - property int colorScheme: hifi.colorSchemes.light - property string glyph: "" - property int size: 32 - - width: 120 - height: 28 - - style: ButtonStyle { - - background: Rectangle { - radius: hifi.buttons.radius - - gradient: Gradient { - GradientStop { - position: 0.2 - color: { - if (!control.enabled) { - hifi.buttons.disabledColorStart[control.colorScheme] - } else if (control.pressed) { - hifi.buttons.pressedColor[control.color] - } else if (control.hovered) { - hifi.buttons.hoveredColor[control.color] - } else { - hifi.buttons.colorStart[control.color] - } - } - } - GradientStop { - position: 1.0 - color: { - if (!control.enabled) { - hifi.buttons.disabledColorFinish[control.colorScheme] - } else if (control.pressed) { - hifi.buttons.pressedColor[control.color] - } else if (control.hovered) { - hifi.buttons.hoveredColor[control.color] - } else { - hifi.buttons.colorFinish[control.color] - } - } - } - } - } - - label: HiFiGlyphs { - color: enabled ? hifi.buttons.textColor[control.color] - : hifi.buttons.disabledTextColor[control.colorScheme] - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - anchors { - // Tweak horizontal alignment so that it looks right. - left: parent.left - leftMargin: -0.5 - } - text: control.glyph - size: control.size - } - } -} diff --git a/scripts/developer/utilities/lib/hifi-qml/controls-uit/HorizontalRule.qml b/scripts/developer/utilities/lib/hifi-qml/controls-uit/HorizontalRule.qml deleted file mode 100644 index 425500f1d4..0000000000 --- a/scripts/developer/utilities/lib/hifi-qml/controls-uit/HorizontalRule.qml +++ /dev/null @@ -1,20 +0,0 @@ -// -// HorizontalRule.qml -// -// Created by Clement on 7/18/16 -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 - -Rectangle { - anchors.left: parent.left - anchors.right: parent.right - height: 1 - color: hifi.colors.lightGray -} diff --git a/scripts/developer/utilities/lib/hifi-qml/controls-uit/HorizontalSpacer.qml b/scripts/developer/utilities/lib/hifi-qml/controls-uit/HorizontalSpacer.qml deleted file mode 100644 index 545154ab44..0000000000 --- a/scripts/developer/utilities/lib/hifi-qml/controls-uit/HorizontalSpacer.qml +++ /dev/null @@ -1,21 +0,0 @@ -// -// HorizontalSpacer.qml -// -// Created by Clement on 7/18/16 -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -import QtQuick 2.5 - -import "../styles-uit" - -Item { - id: root - property alias size: root.width - - width: hifi.dimensions.controlInterlineHeight - height: 1 // Must be non-zero -} diff --git a/scripts/developer/utilities/lib/hifi-qml/controls-uit/Label.qml b/scripts/developer/utilities/lib/hifi-qml/controls-uit/Label.qml deleted file mode 100644 index 330d74fa14..0000000000 --- a/scripts/developer/utilities/lib/hifi-qml/controls-uit/Label.qml +++ /dev/null @@ -1,22 +0,0 @@ -// -// Label.qml -// -// Created by David Rowe on 26 Feb 2016 -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -import QtQuick 2.5 - -import "../styles-uit" - -RalewaySemiBold { - HifiConstants { id: hifi } - property int colorScheme: hifi.colorSchemes.light - - size: hifi.fontSizes.inputLabel - color: enabled ? (colorScheme == hifi.colorSchemes.light ? hifi.colors.lightGray : hifi.colors.lightGrayText) - : (colorScheme == hifi.colorSchemes.light ? hifi.colors.lightGrayText : hifi.colors.baseGrayHighlight); -} diff --git a/scripts/developer/utilities/lib/hifi-qml/controls-uit/QueuedButton.qml b/scripts/developer/utilities/lib/hifi-qml/controls-uit/QueuedButton.qml deleted file mode 100644 index 36ffbe582f..0000000000 --- a/scripts/developer/utilities/lib/hifi-qml/controls-uit/QueuedButton.qml +++ /dev/null @@ -1,43 +0,0 @@ -// -// QueuedButton.qml -// -- original Button.qml + signal timer workaround --ht -// Created by David Rowe on 16 Feb 2016 -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -import QtQuick 2.5 -import QtQuick.Controls 1.4 as Original -import QtQuick.Controls.Styles 1.4 - -import "../styles-uit" -import "." as HifiControls - -HifiControls.Button { - // FIXME: THIS WORKAROUND MIGRATED/CONSOLIDATED FROM RUNNINGSCRIPTS.QML - - // For some reason trigginer an API that enters - // an internal event loop directly from the button clicked - // trigger below causes the appliction to behave oddly. - // Most likely because the button onClicked handling is never - // completed until the function returns. - // FIXME find a better way of handling the input dialogs that - // doesn't trigger this. - - // NOTE: dialogs that need to use this workaround can connect via - // onQueuedClicked: ... - // instead of: - // onClicked: ... - - signal clickedQueued() - Timer { - id: fromTimer - interval: 5 - repeat: false - running: false - onTriggered: clickedQueued() - } - onClicked: fromTimer.running = true -} diff --git a/scripts/developer/utilities/lib/hifi-qml/controls-uit/RadioButton.qml b/scripts/developer/utilities/lib/hifi-qml/controls-uit/RadioButton.qml deleted file mode 100644 index ab11ec68b1..0000000000 --- a/scripts/developer/utilities/lib/hifi-qml/controls-uit/RadioButton.qml +++ /dev/null @@ -1,71 +0,0 @@ -// -// RadioButton.qml -// -// Created by Cain Kilgore on 20th July 2017 -// Copyright 2017 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -import QtQuick 2.5 -import QtQuick.Controls 1.4 as Original -import QtQuick.Controls.Styles 1.4 - -import "../styles-uit" -import "../controls-uit" as HifiControls - -Original.RadioButton { - id: radioButton - HifiConstants { id: hifi } - - property int colorScheme: hifi.colorSchemes.light - readonly property bool isLightColorScheme: colorScheme == hifi.colorSchemes.light - - readonly property int boxSize: 14 - readonly property int boxRadius: 3 - readonly property int checkSize: 10 - readonly property int checkRadius: 2 - - style: RadioButtonStyle { - indicator: Rectangle { - id: box - width: boxSize - height: boxSize - radius: 7 - gradient: Gradient { - GradientStop { - position: 0.2 - color: pressed || hovered - ? (radioButton.isLightColorScheme ? hifi.colors.checkboxDarkStart : hifi.colors.checkboxLightStart) - : (radioButton.isLightColorScheme ? hifi.colors.checkboxLightStart : hifi.colors.checkboxDarkStart) - } - GradientStop { - position: 1.0 - color: pressed || hovered - ? (radioButton.isLightColorScheme ? hifi.colors.checkboxDarkFinish : hifi.colors.checkboxLightFinish) - : (radioButton.isLightColorScheme ? hifi.colors.checkboxLightFinish : hifi.colors.checkboxDarkFinish) - } - } - - Rectangle { - id: check - width: checkSize - height: checkSize - radius: 7 - anchors.centerIn: parent - color: "#00B4EF" - border.width: 1 - border.color: "#36CDFF" - visible: checked && !pressed || !checked && pressed - } - } - - label: RalewaySemiBold { - text: control.text - size: hifi.fontSizes.inputLabel - color: isLightColorScheme ? hifi.colors.lightGray : hifi.colors.lightGrayText - x: radioButton.boxSize / 2 - } - } -} diff --git a/scripts/developer/utilities/lib/hifi-qml/controls-uit/Separator.qml b/scripts/developer/utilities/lib/hifi-qml/controls-uit/Separator.qml deleted file mode 100644 index 5a775221f6..0000000000 --- a/scripts/developer/utilities/lib/hifi-qml/controls-uit/Separator.qml +++ /dev/null @@ -1,38 +0,0 @@ -// -// Separator.qml -// -// Created by Zach Fox on 2017-06-06 -// Copyright 2017 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -import QtQuick 2.5 -import "../styles-uit" - -Item { - // Size - height: 2; - Rectangle { - // Size - width: parent.width; - height: 1; - // Anchors - anchors.left: parent.left; - anchors.bottom: parent.bottom; - anchors.bottomMargin: height; - // Style - color: hifi.colors.baseGrayShadow; - } - Rectangle { - // Size - width: parent.width; - height: 1; - // Anchors - anchors.left: parent.left; - anchors.bottom: parent.bottom; - // Style - color: hifi.colors.baseGrayHighlight; - } -} diff --git a/scripts/developer/utilities/lib/hifi-qml/controls-uit/Slider.qml b/scripts/developer/utilities/lib/hifi-qml/controls-uit/Slider.qml deleted file mode 100644 index 89bae9bcde..0000000000 --- a/scripts/developer/utilities/lib/hifi-qml/controls-uit/Slider.qml +++ /dev/null @@ -1,98 +0,0 @@ -// -// Slider.qml -// -// Created by David Rowe on 27 Feb 2016 -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 - -import "../styles-uit" -import "../controls-uit" as HifiControls - -Slider { - id: slider - - property int colorScheme: hifi.colorSchemes.light - readonly property bool isLightColorScheme: colorScheme == hifi.colorSchemes.light - property string label: "" - property real controlHeight: height + (sliderLabel.visible ? sliderLabel.height + sliderLabel.anchors.bottomMargin : 0) - - height: hifi.fontSizes.textFieldInput + 14 // Match height of TextField control. - y: sliderLabel.visible ? sliderLabel.height + sliderLabel.anchors.bottomMargin : 0 - - style: SliderStyle { - - groove: Rectangle { - implicitWidth: 50 - implicitHeight: hifi.dimensions.sliderGrooveHeight - radius: height / 2 - color: isLightColorScheme ? hifi.colors.sliderGutterLight : hifi.colors.sliderGutterDark - - Rectangle { - width: parent.height - 2 - height: slider.width * (slider.value - slider.minimumValue) / (slider.maximumValue - slider.minimumValue) - 1 - radius: height / 2 - anchors { - top: parent.top - topMargin: width + 1 - left: parent.left - leftMargin: 1 - } - transformOrigin: Item.TopLeft - rotation: -90 - gradient: Gradient { - GradientStop { position: 0.0; color: hifi.colors.blueAccent } - GradientStop { position: 1.0; color: hifi.colors.primaryHighlight } - } - } - } - - handle: Rectangle { - implicitWidth: hifi.dimensions.sliderHandleSize - implicitHeight: hifi.dimensions.sliderHandleSize - radius: height / 2 - border.width: 1 - border.color: isLightColorScheme ? hifi.colors.sliderBorderLight : hifi.colors.sliderBorderDark - gradient: Gradient { - GradientStop { - position: 0.0 - color: pressed || hovered - ? (isLightColorScheme ? hifi.colors.sliderDarkStart : hifi.colors.sliderLightStart ) - : (isLightColorScheme ? hifi.colors.sliderLightStart : hifi.colors.sliderDarkStart ) - } - GradientStop { - position: 1.0 - color: pressed || hovered - ? (isLightColorScheme ? hifi.colors.sliderDarkFinish : hifi.colors.sliderLightFinish ) - : (isLightColorScheme ? hifi.colors.sliderLightFinish : hifi.colors.sliderDarkFinish ) - } - } - - Rectangle { - height: parent.height - 2 - width: height - radius: height / 2 - anchors.centerIn: parent - color: hifi.colors.transparent - border.width: 1 - border.color: hifi.colors.black - } - } - } - - HifiControls.Label { - id: sliderLabel - text: slider.label - colorScheme: slider.colorScheme - anchors.left: parent.left - anchors.bottom: parent.top - anchors.bottomMargin: 2 - visible: label != "" - } -} diff --git a/scripts/developer/utilities/lib/hifi-qml/controls-uit/SpinBox.qml b/scripts/developer/utilities/lib/hifi-qml/controls-uit/SpinBox.qml deleted file mode 100644 index a1237d4bc7..0000000000 --- a/scripts/developer/utilities/lib/hifi-qml/controls-uit/SpinBox.qml +++ /dev/null @@ -1,117 +0,0 @@ -// -// SpinBox.qml -// -// Created by David Rowe on 26 Feb 2016 -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 - -import "../styles-uit" -import "../controls-uit" as HifiControls - -SpinBox { - id: spinBox - - property int colorScheme: hifi.colorSchemes.light - readonly property bool isLightColorScheme: colorScheme == hifi.colorSchemes.light - property string label: "" - property string labelInside: "" - property color colorLabelInside: hifi.colors.white - property real controlHeight: height + (spinBoxLabel.visible ? spinBoxLabel.height + spinBoxLabel.anchors.bottomMargin : 0) - - FontLoader { id: firaSansSemiBold; source: "../../fonts/FiraSans-SemiBold.ttf"; } - font.family: firaSansSemiBold.name - font.pixelSize: hifi.fontSizes.textFieldInput - height: hifi.fontSizes.textFieldInput + 13 // Match height of TextField control. - - y: spinBoxLabel.visible ? spinBoxLabel.height + spinBoxLabel.anchors.bottomMargin : 0 - - style: SpinBoxStyle { - id: spinStyle - background: Rectangle { - color: isLightColorScheme - ? (spinBox.activeFocus ? hifi.colors.white : hifi.colors.lightGray) - : (spinBox.activeFocus ? hifi.colors.black : hifi.colors.baseGrayShadow) - border.color: spinBoxLabelInside.visible ? spinBoxLabelInside.color : hifi.colors.primaryHighlight - border.width: spinBox.activeFocus ? spinBoxLabelInside.visible ? 2 : 1 : 0 - } - - textColor: isLightColorScheme - ? (spinBox.activeFocus ? hifi.colors.black : hifi.colors.lightGray) - : (spinBox.activeFocus ? hifi.colors.white : hifi.colors.lightGrayText) - selectedTextColor: hifi.colors.black - selectionColor: hifi.colors.primaryHighlight - - horizontalAlignment: Qt.AlignLeft - padding.left: spinBoxLabelInside.visible ? 30 : hifi.dimensions.textPadding - padding.right: hifi.dimensions.spinnerSize - padding.top: 0 - - incrementControl: HiFiGlyphs { - id: incrementButton - text: hifi.glyphs.caratUp - x: 10 - y: 1 - size: hifi.dimensions.spinnerSize - color: styleData.upPressed ? (isLightColorScheme ? hifi.colors.black : hifi.colors.white) : hifi.colors.gray - } - - decrementControl: HiFiGlyphs { - text: hifi.glyphs.caratDn - x: 10 - y: -1 - size: hifi.dimensions.spinnerSize - color: styleData.downPressed ? (isLightColorScheme ? hifi.colors.black : hifi.colors.white) : hifi.colors.gray - } - } - - HifiControls.Label { - id: spinBoxLabel - text: spinBox.label - colorScheme: spinBox.colorScheme - anchors.left: parent.left - anchors.bottom: parent.top - anchors.bottomMargin: 4 - visible: label != "" - } - - HifiControls.Label { - id: spinBoxLabelInside - text: spinBox.labelInside - anchors.left: parent.left - anchors.leftMargin: 10 - font.bold: true - anchors.verticalCenter: parent.verticalCenter - color: spinBox.colorLabelInside - visible: spinBox.labelInside != "" - } - - MouseArea { - anchors.fill: parent - propagateComposedEvents: true - onWheel: { - if(spinBox.activeFocus) - wheel.accepted = false - else - wheel.accepted = true - } - onPressed: { - mouse.accepted = false - } - onReleased: { - mouse.accepted = false - } - onClicked: { - mouse.accepted = false - } - onDoubleClicked: { - mouse.accepted = false - } - } -} diff --git a/scripts/developer/utilities/lib/hifi-qml/controls-uit/Switch.qml b/scripts/developer/utilities/lib/hifi-qml/controls-uit/Switch.qml deleted file mode 100644 index d54f986717..0000000000 --- a/scripts/developer/utilities/lib/hifi-qml/controls-uit/Switch.qml +++ /dev/null @@ -1,156 +0,0 @@ -// -// Switch.qml -// -// Created by Zach Fox on 2017-06-06 -// Copyright 2017 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -import QtQuick 2.5 -import QtQuick.Controls 1.4 as Original -import QtQuick.Controls.Styles 1.4 - -import "../styles-uit" - -Item { - id: rootSwitch; - - property int colorScheme: hifi.colorSchemes.light; - readonly property bool isLightColorScheme: colorScheme == hifi.colorSchemes.light; - property int switchWidth: 70; - readonly property int switchRadius: height/2; - property string labelTextOff: ""; - property string labelGlyphOffText: ""; - property int labelGlyphOffSize: 32; - property string labelTextOn: ""; - property string labelGlyphOnText: ""; - property int labelGlyphOnSize: 32; - property alias checked: originalSwitch.checked; - signal onCheckedChanged; - signal clicked; - - Original.Switch { - id: originalSwitch; - activeFocusOnPress: true; - anchors.top: rootSwitch.top; - anchors.left: rootSwitch.left; - anchors.leftMargin: rootSwitch.width/2 - rootSwitch.switchWidth/2; - onCheckedChanged: rootSwitch.onCheckedChanged(); - onClicked: rootSwitch.clicked(); - - style: SwitchStyle { - - padding { - top: 3; - left: 3; - right: 3; - bottom: 3; - } - - groove: Rectangle { - color: "#252525"; - implicitWidth: rootSwitch.switchWidth; - implicitHeight: rootSwitch.height; - radius: rootSwitch.switchRadius; - } - - handle: Rectangle { - id: switchHandle; - implicitWidth: rootSwitch.height - padding.top - padding.bottom; - implicitHeight: implicitWidth; - radius: implicitWidth/2; - border.color: hifi.colors.lightGrayText; - color: hifi.colors.lightGray; - - MouseArea { - anchors.fill: parent; - hoverEnabled: true; - onEntered: parent.color = hifi.colors.blueHighlight; - onExited: parent.color = hifi.colors.lightGray; - } - } - } - } - - // OFF Label - Item { - anchors.right: originalSwitch.left; - anchors.rightMargin: 10; - anchors.top: rootSwitch.top; - height: rootSwitch.height; - - RalewaySemiBold { - id: labelOff; - text: labelTextOff; - size: hifi.fontSizes.inputLabel; - color: originalSwitch.checked ? hifi.colors.lightGrayText : "#FFFFFF"; - anchors.top: parent.top; - anchors.right: parent.right; - width: paintedWidth; - height: parent.height; - verticalAlignment: Text.AlignVCenter; - } - - HiFiGlyphs { - id: labelGlyphOff; - text: labelGlyphOffText; - size: labelGlyphOffSize; - color: labelOff.color; - anchors.top: parent.top; - anchors.topMargin: 2; - anchors.right: labelOff.left; - anchors.rightMargin: 4; - } - - MouseArea { - anchors.top: parent.top; - anchors.bottom: parent.bottom; - anchors.left: labelGlyphOff.left; - anchors.right: labelOff.right; - onClicked: { - originalSwitch.checked = false; - } - } - } - - // ON Label - Item { - anchors.left: originalSwitch.right; - anchors.leftMargin: 10; - anchors.top: rootSwitch.top; - height: rootSwitch.height; - - RalewaySemiBold { - id: labelOn; - text: labelTextOn; - size: hifi.fontSizes.inputLabel; - color: originalSwitch.checked ? "#FFFFFF" : hifi.colors.lightGrayText; - anchors.top: parent.top; - anchors.left: parent.left; - width: paintedWidth; - height: parent.height; - verticalAlignment: Text.AlignVCenter; - } - - HiFiGlyphs { - id: labelGlyphOn; - text: labelGlyphOnText; - size: labelGlyphOnSize; - color: labelOn.color; - anchors.top: parent.top; - anchors.left: labelOn.right; - } - - MouseArea { - anchors.top: parent.top; - anchors.bottom: parent.bottom; - anchors.left: labelOn.left; - anchors.right: labelGlyphOn.right; - onClicked: { - originalSwitch.checked = true; - } - } - } -} diff --git a/scripts/developer/utilities/lib/hifi-qml/controls-uit/Table.qml b/scripts/developer/utilities/lib/hifi-qml/controls-uit/Table.qml deleted file mode 100644 index 11d1920f95..0000000000 --- a/scripts/developer/utilities/lib/hifi-qml/controls-uit/Table.qml +++ /dev/null @@ -1,179 +0,0 @@ -// -// Table.qml -// -// Created by David Rowe on 18 Feb 2016 -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 - -import "../styles-uit" - -TableView { - id: tableView - - property int colorScheme: hifi.colorSchemes.light - readonly property bool isLightColorScheme: colorScheme == hifi.colorSchemes.light - property bool expandSelectedRow: false - property bool centerHeaderText: false - - model: ListModel { } - - headerVisible: false - headerDelegate: Rectangle { - height: hifi.dimensions.tableHeaderHeight - color: isLightColorScheme ? hifi.colors.tableBackgroundLight : hifi.colors.tableBackgroundDark - - RalewayRegular { - id: titleText - text: styleData.value - size: hifi.fontSizes.tableHeading - font.capitalization: Font.AllUppercase - color: hifi.colors.baseGrayHighlight - horizontalAlignment: (centerHeaderText ? Text.AlignHCenter : Text.AlignLeft) - anchors { - left: parent.left - leftMargin: hifi.dimensions.tablePadding - right: parent.right - rightMargin: hifi.dimensions.tablePadding - verticalCenter: parent.verticalCenter - } - } - - HiFiGlyphs { - id: titleSort - text: sortIndicatorOrder == Qt.AscendingOrder ? hifi.glyphs.caratUp : hifi.glyphs.caratDn - color: hifi.colors.darkGray - opacity: 0.6; - size: hifi.fontSizes.tableHeadingIcon - anchors { - left: titleText.right - leftMargin: -hifi.fontSizes.tableHeadingIcon / 3 - (centerHeaderText ? 5 : 0) - right: parent.right - rightMargin: hifi.dimensions.tablePadding - verticalCenter: titleText.verticalCenter - } - visible: sortIndicatorVisible && sortIndicatorColumn === styleData.column - } - - Rectangle { - width: 1 - anchors { - left: parent.left - top: parent.top - topMargin: 1 - bottom: parent.bottom - bottomMargin: 2 - } - color: isLightColorScheme ? hifi.colors.lightGrayText : hifi.colors.baseGrayHighlight - visible: styleData.column > 0 - } - - Rectangle { - height: 1 - anchors { - left: parent.left - right: parent.right - bottom: parent.bottom - } - color: isLightColorScheme ? hifi.colors.lightGrayText : hifi.colors.baseGrayHighlight - } - } - - // Use rectangle to draw border with rounded corners. - frameVisible: false - Rectangle { - color: "#00000000" - anchors { fill: parent; margins: -2 } - border.color: isLightColorScheme ? hifi.colors.lightGrayText : hifi.colors.baseGrayHighlight - border.width: 2 - } - anchors.margins: 2 // Shrink TableView to lie within border. - - backgroundVisible: true - - horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff - verticalScrollBarPolicy: Qt.ScrollBarAsNeeded - - style: TableViewStyle { - // Needed in order for rows to keep displaying rows after end of table entries. - backgroundColor: tableView.isLightColorScheme ? hifi.colors.tableBackgroundLight : hifi.colors.tableBackgroundDark - alternateBackgroundColor: tableView.isLightColorScheme ? hifi.colors.tableRowLightOdd : hifi.colors.tableRowDarkOdd - - padding.top: headerVisible ? hifi.dimensions.tableHeaderHeight: 0 - - handle: Item { - id: scrollbarHandle - implicitWidth: hifi.dimensions.scrollbarHandleWidth - Rectangle { - anchors { - fill: parent - topMargin: 3 - bottomMargin: 3 // "" - leftMargin: 1 // Move it right - rightMargin: -1 // "" - } - radius: hifi.dimensions.scrollbarHandleWidth/2 - color: isLightColorScheme ? hifi.colors.tableScrollHandleLight : hifi.colors.tableScrollHandleDark - } - } - - scrollBarBackground: Item { - implicitWidth: hifi.dimensions.scrollbarBackgroundWidth - Rectangle { - anchors { - fill: parent - margins: -1 // Expand - topMargin: -1 - } - color: isLightColorScheme ? hifi.colors.tableScrollBackgroundLight : hifi.colors.tableScrollBackgroundDark - - // Extend header color above scrollbar background - Rectangle { - anchors { - top: parent.top - topMargin: -hifi.dimensions.tableHeaderHeight - left: parent.left - right: parent.right - } - height: hifi.dimensions.tableHeaderHeight - color: tableView.isLightColorScheme ? hifi.colors.tableBackgroundLight : hifi.colors.tableBackgroundDark - visible: headerVisible - } - Rectangle { - // Extend header bottom border - anchors { - top: parent.top - left: parent.left - right: parent.right - } - height: 1 - color: isLightColorScheme ? hifi.colors.lightGrayText : hifi.colors.baseGrayHighlight - visible: headerVisible - } - } - } - - incrementControl: Item { - visible: false - } - - decrementControl: Item { - visible: false - } - } - - rowDelegate: Rectangle { - height: (styleData.selected && expandSelectedRow ? 1.8 : 1) * hifi.dimensions.tableRowHeight - color: styleData.selected - ? hifi.colors.primaryHighlight - : tableView.isLightColorScheme - ? (styleData.alternate ? hifi.colors.tableRowLightEven : hifi.colors.tableRowLightOdd) - : (styleData.alternate ? hifi.colors.tableRowDarkEven : hifi.colors.tableRowDarkOdd) - } -} diff --git a/scripts/developer/utilities/lib/hifi-qml/controls-uit/VerticalSpacer.qml b/scripts/developer/utilities/lib/hifi-qml/controls-uit/VerticalSpacer.qml deleted file mode 100644 index 2df65f1002..0000000000 --- a/scripts/developer/utilities/lib/hifi-qml/controls-uit/VerticalSpacer.qml +++ /dev/null @@ -1,21 +0,0 @@ -// -// VerticalSpacer.qml -// -// Created by David Rowe on 16 Feb 2016 -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -import QtQuick 2.5 - -import "../styles-uit" - -Item { - id: root - property alias size: root.height - - width: 1 // Must be non-zero - height: hifi.dimensions.controlInterlineHeight -} diff --git a/scripts/developer/utilities/lib/hifi-qml/styles-uit/AnonymousProRegular.qml b/scripts/developer/utilities/lib/hifi-qml/styles-uit/AnonymousProRegular.qml deleted file mode 100644 index 789689973b..0000000000 --- a/scripts/developer/utilities/lib/hifi-qml/styles-uit/AnonymousProRegular.qml +++ /dev/null @@ -1,23 +0,0 @@ -// -// AnonymousProRegular.qml -// -// Created by David Rowe on 12 Feb 2016 -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 - -Text { - id: root - FontLoader { id: anonymousProRegular; source: "../../fonts/AnonymousPro-Regular.ttf"; } - property real size: 32 - font.pixelSize: size - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignLeft - font.family: anonymousProRegular.name -} diff --git a/scripts/developer/utilities/lib/hifi-qml/styles-uit/ButtonLabel.qml b/scripts/developer/utilities/lib/hifi-qml/styles-uit/ButtonLabel.qml deleted file mode 100644 index aade5fb439..0000000000 --- a/scripts/developer/utilities/lib/hifi-qml/styles-uit/ButtonLabel.qml +++ /dev/null @@ -1,18 +0,0 @@ -// -// ButtonLabel.qml -// -// Created by Clement on 7/18/16 -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 -import "." - -RalewayBold { - font.pixelSize: hifi.fontSizes.buttonLabel -} diff --git a/scripts/developer/utilities/lib/hifi-qml/styles-uit/FiraSansRegular.qml b/scripts/developer/utilities/lib/hifi-qml/styles-uit/FiraSansRegular.qml deleted file mode 100644 index 4ae0826772..0000000000 --- a/scripts/developer/utilities/lib/hifi-qml/styles-uit/FiraSansRegular.qml +++ /dev/null @@ -1,23 +0,0 @@ -// -// FiraSansRegular.qml -// -// Created by David Rowe on 12 May 2016 -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 - -Text { - id: root - FontLoader { id: firaSansRegular; source: "../../fonts/FiraSans-Regular.ttf"; } - property real size: 32 - font.pixelSize: size - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignLeft - font.family: firaSansRegular.name -} diff --git a/scripts/developer/utilities/lib/hifi-qml/styles-uit/FiraSansSemiBold.qml b/scripts/developer/utilities/lib/hifi-qml/styles-uit/FiraSansSemiBold.qml deleted file mode 100644 index b3f3324090..0000000000 --- a/scripts/developer/utilities/lib/hifi-qml/styles-uit/FiraSansSemiBold.qml +++ /dev/null @@ -1,23 +0,0 @@ -// -// FiraSansSemiBold.qml -// -// Created by David Rowe on 12 Feb 2016 -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 - -Text { - id: root - FontLoader { id: firaSansSemiBold; source: pathToFonts + "fonts/FiraSans-SemiBold.ttf"; } - property real size: 32 - font.pixelSize: size - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignLeft - font.family: firaSansSemiBold.name -} diff --git a/scripts/developer/utilities/lib/hifi-qml/styles-uit/HiFiGlyphs.qml b/scripts/developer/utilities/lib/hifi-qml/styles-uit/HiFiGlyphs.qml deleted file mode 100644 index cbd6fa1d68..0000000000 --- a/scripts/developer/utilities/lib/hifi-qml/styles-uit/HiFiGlyphs.qml +++ /dev/null @@ -1,25 +0,0 @@ -// -// HiFiGlyphs.qml -// -// Created by David Rowe on 12 Feb 2016 -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 - -Text { - id: root - FontLoader { id: hiFiGlyphs; source: pathToFonts + "fonts/hifi-glyphs.ttf"; } - property int size: 32 - font.pixelSize: size - width: size - height: size - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignLeft - font.family: hiFiGlyphs.name -} diff --git a/scripts/developer/utilities/lib/hifi-qml/styles-uit/HifiConstants.qml b/scripts/developer/utilities/lib/hifi-qml/styles-uit/HifiConstants.qml deleted file mode 100644 index 4a26d11128..0000000000 --- a/scripts/developer/utilities/lib/hifi-qml/styles-uit/HifiConstants.qml +++ /dev/null @@ -1,342 +0,0 @@ -// -// HiFiConstants.qml -// -// Created by Bradley Austin Davis on 28 Apr 2015 -// Copyright 2015 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -import QtQuick 2.5 -import QtQuick.Window 2.2 - -Item { - readonly property alias colors: colors - readonly property alias colorSchemes: colorSchemes - readonly property alias dimensions: dimensions - readonly property alias fontSizes: fontSizes - readonly property alias glyphs: glyphs - readonly property alias icons: icons - readonly property alias buttons: buttons - readonly property alias effects: effects - - function glyphForIcon(icon) { - // Translates icon enum to glyph char. - var glyph; - switch (icon) { - case hifi.icons.information: - glyph = hifi.glyphs.info; - break; - case hifi.icons.question: - glyph = hifi.glyphs.question; - break; - case hifi.icons.warning: - glyph = hifi.glyphs.alert; - break; - case hifi.icons.critical: - glyph = hifi.glyphs.error; - break; - case hifi.icons.placemark: - glyph = hifi.glyphs.placemark; - break; - default: - glyph = hifi.glyphs.noIcon; - } - return glyph; - } - - Item { - id: colors - - // Base colors - readonly property color baseGray: "#393939" - readonly property color darkGray: "#121212" - readonly property color baseGrayShadow: "#252525" - readonly property color baseGrayHighlight: "#575757" - readonly property color lightGray: "#6a6a6a" - readonly property color lightGrayText: "#afafaf" - readonly property color faintGray: "#e3e3e3" - readonly property color primaryHighlight: "#00b4ef" - readonly property color blueHighlight: "#00b4ef" - readonly property color blueAccent: "#0093C5" - readonly property color redHighlight: "#EA4C5F" - readonly property color redAccent: "#C62147" - readonly property color greenHighlight: "#1ac567" - readonly property color greenShadow: "#359D85" - readonly property color orangeHighlight: "#FFC49C" - readonly property color orangeAccent: "#FF6309" - readonly property color indigoHighlight: "#C0D2FF" - readonly property color indigoAccent: "#9495FF" - readonly property color magentaHighlight: "#EF93D1" - readonly property color magentaAccent: "#A2277C" - readonly property color checkboxCheckedRed: "#FF0000" - readonly property color checkboxCheckedBorderRed: "#D00000" - readonly property color lightBlueHighlight: "#d6f6ff" - - // Semitransparent - readonly property color darkGray30: "#4d121212" - readonly property color darkGray0: "#00121212" - readonly property color baseGrayShadow60: "#99252525" - readonly property color baseGrayShadow50: "#80252525" - readonly property color baseGrayShadow25: "#40252525" - readonly property color baseGrayHighlight40: "#66575757" - readonly property color baseGrayHighlight15: "#26575757" - readonly property color lightGray50: "#806a6a6a" - readonly property color lightGrayText80: "#ccafafaf" - readonly property color faintGray80: "#cce3e3e3" - readonly property color faintGray50: "#80e3e3e3" - - // Other colors - readonly property color white: "#ffffff" - readonly property color gray: "#808080" - readonly property color black: "#000000" - readonly property color locked: "#252525" - // Semitransparent - readonly property color white50: "#80ffffff" - readonly property color white30: "#4dffffff" - readonly property color white25: "#40ffffff" - readonly property color transparent: "#00ffffff" - - // Control specific colors - readonly property color tableRowLightOdd: "#fafafa" - readonly property color tableRowLightEven: "#eeeeee" // Equivavlent to "#1a575757" over #e3e3e3 background - readonly property color tableRowDarkOdd: "#2e2e2e" // Equivalent to "#80393939" over #404040 background - readonly property color tableRowDarkEven: "#1c1c1c" // Equivalent to "#a6181818" over #404040 background - readonly property color tableBackgroundLight: tableRowLightEven - readonly property color tableBackgroundDark: tableRowDarkEven - readonly property color tableScrollHandleLight: "#DDDDDD" - readonly property color tableScrollHandleDark: "#707070" - readonly property color tableScrollBackgroundLight: tableRowLightOdd - readonly property color tableScrollBackgroundDark: "#323232" - readonly property color checkboxLightStart: "#ffffff" - readonly property color checkboxLightFinish: "#afafaf" - readonly property color checkboxDarkStart: "#7d7d7d" - readonly property color checkboxDarkFinish: "#6b6a6b" - readonly property color checkboxChecked: primaryHighlight - readonly property color checkboxCheckedBorder: "#36cdff" - readonly property color sliderGutterLight: "#d4d4d4" - readonly property color sliderGutterDark: "#252525" - readonly property color sliderBorderLight: "#afafaf" - readonly property color sliderBorderDark: "#7d7d7d" - readonly property color sliderLightStart: "#ffffff" - readonly property color sliderLightFinish: "#afafaf" - readonly property color sliderDarkStart: "#7d7d7d" - readonly property color sliderDarkFinish: "#6b6a6b" - readonly property color dropDownPressedLight: "#d4d4d4" - readonly property color dropDownPressedDark: "#afafaf" - readonly property color dropDownLightStart: "#ffffff" - readonly property color dropDownLightFinish: "#afafaf" - readonly property color dropDownDarkStart: "#7d7d7d" - readonly property color dropDownDarkFinish: "#6b6a6b" - readonly property color textFieldLightBackground: "#d4d4d4" - readonly property color tabBackgroundDark: "#252525" - readonly property color tabBackgroundLight: "#d4d4d4" - } - - Item { - id: colorSchemes - readonly property int light: 0 - readonly property int dark: 1 - } - - Item { - id: dimensions - readonly property bool largeScreen: Screen.width >= 1920 && Screen.height >= 1080 - readonly property real borderRadius: largeScreen ? 7.5 : 5.0 - readonly property real borderWidth: largeScreen ? 2 : 1 - readonly property vector2d contentMargin: Qt.vector2d(21, 21) - readonly property vector2d contentSpacing: Qt.vector2d(11, 14) - readonly property real labelPadding: 40 - readonly property real textPadding: 8 - readonly property real sliderHandleSize: 18 - readonly property real sliderGrooveHeight: 8 - readonly property real frameIconSize: 22 - readonly property real spinnerSize: 50 - readonly property real tablePadding: 12 - readonly property real tableRowHeight: largeScreen ? 26 : 23 - readonly property real tableHeaderHeight: 29 - readonly property vector2d modalDialogMargin: Qt.vector2d(50, 30) - readonly property real modalDialogTitleHeight: 40 - readonly property real controlLineHeight: 28 // Height of spinbox control on 1920 x 1080 monitor - readonly property real controlInterlineHeight: 21 // 75% of controlLineHeight - readonly property vector2d menuPadding: Qt.vector2d(14, 102) - readonly property real scrollbarBackgroundWidth: 18 - readonly property real scrollbarHandleWidth: scrollbarBackgroundWidth - 2 - readonly property real tabletMenuHeader: 90 - } - - Item { - id: fontSizes // In pixels - readonly property real overlayTitle: dimensions.largeScreen ? 18 : 14 - readonly property real tabName: dimensions.largeScreen ? 12 : 10 - readonly property real sectionName: dimensions.largeScreen ? 12 : 10 - readonly property real inputLabel: dimensions.largeScreen ? 14 : 10 - readonly property real textFieldInput: dimensions.largeScreen ? 15 : 12 - readonly property real textFieldInputLabel: dimensions.largeScreen ? 13 : 9 - readonly property real textFieldSearchIcon: dimensions.largeScreen ? 30 : 24 - readonly property real tableHeading: dimensions.largeScreen ? 12 : 10 - readonly property real tableHeadingIcon: dimensions.largeScreen ? 60 : 33 - readonly property real tableText: dimensions.largeScreen ? 15 : 12 - readonly property real buttonLabel: dimensions.largeScreen ? 13 : 9 - readonly property real iconButton: dimensions.largeScreen ? 13 : 9 - readonly property real listItem: dimensions.largeScreen ? 15 : 11 - readonly property real tabularData: dimensions.largeScreen ? 15 : 11 - readonly property real logs: dimensions.largeScreen ? 16 : 12 - readonly property real code: dimensions.largeScreen ? 16 : 12 - readonly property real rootMenu: dimensions.largeScreen ? 15 : 11 - readonly property real rootMenuDisclosure: dimensions.largeScreen ? 20 : 16 - readonly property real menuItem: dimensions.largeScreen ? 15 : 11 - readonly property real shortcutText: dimensions.largeScreen ? 13 : 9 - readonly property real carat: dimensions.largeScreen ? 38 : 30 - readonly property real disclosureButton: dimensions.largeScreen ? 30 : 22 - } - - Item { - id: icons - // Values per OffscreenUi::Icon - readonly property int none: 0 - readonly property int question: 1 - readonly property int information: 2 - readonly property int warning: 3 - readonly property int critical: 4 - readonly property int placemark: 5 - } - - Item { - id: buttons - readonly property int white: 0 - readonly property int blue: 1 - readonly property int red: 2 - readonly property int black: 3 - readonly property var textColor: [ colors.darkGray, colors.white, colors.white, colors.white ] - readonly property var colorStart: [ colors.white, colors.primaryHighlight, "#d42043", "#343434" ] - readonly property var colorFinish: [ colors.lightGrayText, colors.blueAccent, "#94132e", colors.black ] - readonly property var hoveredColor: [ colorStart[white], colorStart[blue], colorStart[red], colorFinish[black] ] - readonly property var pressedColor: [ colorFinish[white], colorFinish[blue], colorFinish[red], colorStart[black] ] - readonly property var disabledColorStart: [ colorStart[white], colors.baseGrayHighlight] - readonly property var disabledColorFinish: [ colorFinish[white], colors.baseGrayShadow] - readonly property var disabledTextColor: [ colors.lightGrayText, colors.baseGrayShadow] - readonly property int radius: 5 - } - - QtObject { - id: effects - readonly property int fadeInDuration: 300 - } - Item { - id: glyphs - readonly property string noIcon: "" - readonly property string hmd: "b" - readonly property string screen: "c" - readonly property string keyboard: "d" - readonly property string handControllers: "e" - readonly property string headphonesMic: "f" - readonly property string gamepad: "g" - readonly property string headphones: "h" - readonly property string mic: "i" - readonly property string upload: "j" - readonly property string script: "k" - readonly property string text: "l" - readonly property string cube: "m" - readonly property string sphere: "n" - readonly property string zone: "o" - readonly property string light: "p" - readonly property string web: "q" - readonly property string web2: "r" - readonly property string edit: "s" - readonly property string market: "t" - readonly property string directory: "u" - readonly property string menu: "v" - readonly property string close: "w" - readonly property string closeInverted: "x" - readonly property string pin: "y" - readonly property string pinInverted: "z" - readonly property string resizeHandle: "A" - readonly property string disclosureExpand: "B" - readonly property string reloadSmall: "a" - readonly property string closeSmall: "C" - readonly property string forward: "D" - readonly property string backward: "E" - readonly property string reload: "F" - readonly property string unmuted: "G" - readonly property string muted: "H" - readonly property string minimize: "I" - readonly property string maximize: "J" - readonly property string maximizeInverted: "K" - readonly property string disclosureButtonExpand: "L" - readonly property string disclosureButtonCollapse: "M" - readonly property string scriptStop: "N" - readonly property string scriptReload: "O" - readonly property string scriptRun: "P" - readonly property string scriptNew: "Q" - readonly property string hifiForum: "2" - readonly property string hifiLogoSmall: "S" - readonly property string avatar1: "T" - readonly property string placemark: "U" - readonly property string box: "V" - readonly property string community: "0" - readonly property string grabHandle: "X" - readonly property string search: "Y" - readonly property string disclosureCollapse: "Z" - readonly property string scriptUpload: "R" - readonly property string code: "W" - readonly property string avatar: "<" - readonly property string arrowsH: ":" - readonly property string arrowsV: ";" - readonly property string arrows: "`" - readonly property string compress: "!" - readonly property string expand: "\"" - readonly property string placemark1: "#" - readonly property string circle: "$" - readonly property string handPointer: "9" - readonly property string plusSquareO: "%" - readonly property string sliders: "&" - readonly property string square: "'" - readonly property string alignCenter: "8" - readonly property string alignJustify: ")" - readonly property string alignLeft: "*" - readonly property string alignRight: "^" - readonly property string bars: "7" - readonly property string circleSlash: "," - readonly property string sync: "()" - readonly property string key: "-" - readonly property string link: "." - readonly property string location: "/" - readonly property string caratR: "3" - readonly property string caratL: "4" - readonly property string caratDn: "5" - readonly property string caratUp: "6" - readonly property string folderLg: ">" - readonly property string folderSm: "?" - readonly property string levelUp: "1" - readonly property string info: "[" - readonly property string question: "]" - readonly property string alert: "+" - readonly property string home: "_" - readonly property string error: "=" - readonly property string settings: "@" - readonly property string trash: "{" - readonly property string objectGroup: "\ue000" - readonly property string cm: "}" - readonly property string msvg79: "~" - readonly property string deg: "\\" - readonly property string px: "|" - readonly property string editPencil: "\ue00d" - readonly property string vol_0: "\ue00e" - readonly property string vol_1: "\ue00f" - readonly property string vol_2: "\ue010" - readonly property string vol_3: "\ue011" - readonly property string vol_4: "\ue012" - readonly property string vol_x_0: "\ue013" - readonly property string vol_x_1: "\ue014" - readonly property string vol_x_2: "\ue015" - readonly property string vol_x_3: "\ue016" - readonly property string vol_x_4: "\ue017" - readonly property string source: "\ue01c" - readonly property string playback_play: "\ue01d" - readonly property string stop_square: "\ue01e" - readonly property string avatarTPose: "\ue01f" - readonly property string lock: "\ue006" - } -} diff --git a/scripts/developer/utilities/lib/hifi-qml/styles-uit/IconButton.qml b/scripts/developer/utilities/lib/hifi-qml/styles-uit/IconButton.qml deleted file mode 100644 index 84c1ef14c1..0000000000 --- a/scripts/developer/utilities/lib/hifi-qml/styles-uit/IconButton.qml +++ /dev/null @@ -1,20 +0,0 @@ -// -// IconButton.qml -// -// Created by Clement on 7/18/16 -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 -import "." - -RalewayRegular { - font.pixelSize: hifi.fontSizes.iconButton - font.capitalization: Font.AllUppercase - font.letterSpacing: 1.5 -} diff --git a/scripts/developer/utilities/lib/hifi-qml/styles-uit/InfoItem.qml b/scripts/developer/utilities/lib/hifi-qml/styles-uit/InfoItem.qml deleted file mode 100644 index 83781a4ef5..0000000000 --- a/scripts/developer/utilities/lib/hifi-qml/styles-uit/InfoItem.qml +++ /dev/null @@ -1,19 +0,0 @@ -// -// InfoItem.qml -// -// Created by Clement on 7/18/16 -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 -import "." - -RalewaySemiBold { - lineHeight: 2 - font.pixelSize: hifi.fontSizes.menuItem -} diff --git a/scripts/developer/utilities/lib/hifi-qml/styles-uit/InputLabel.qml b/scripts/developer/utilities/lib/hifi-qml/styles-uit/InputLabel.qml deleted file mode 100644 index 59657a554d..0000000000 --- a/scripts/developer/utilities/lib/hifi-qml/styles-uit/InputLabel.qml +++ /dev/null @@ -1,18 +0,0 @@ -// -// InputLabel.qml -// -// Created by Clement on 7/18/16 -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 -import "." - -RalewaySemiBold { - font.pixelSize: hifi.fontSizes.inputLabel -} diff --git a/scripts/developer/utilities/lib/hifi-qml/styles-uit/ListItem.qml b/scripts/developer/utilities/lib/hifi-qml/styles-uit/ListItem.qml deleted file mode 100644 index f707686edc..0000000000 --- a/scripts/developer/utilities/lib/hifi-qml/styles-uit/ListItem.qml +++ /dev/null @@ -1,18 +0,0 @@ -// -// ListItem.qml -// -// Created by Clement on 7/18/16 -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 -import "." - -RalewayRegular { - font.pixelSize: hifi.fontSizes.listItem -} diff --git a/scripts/developer/utilities/lib/hifi-qml/styles-uit/Logs.qml b/scripts/developer/utilities/lib/hifi-qml/styles-uit/Logs.qml deleted file mode 100644 index 577fe2f8d8..0000000000 --- a/scripts/developer/utilities/lib/hifi-qml/styles-uit/Logs.qml +++ /dev/null @@ -1,18 +0,0 @@ -// -// Logs.qml -// -// Created by Clement on 7/18/16 -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 -import "." - -AnonymousProRegular { - font.pixelSize: hifi.fontSizes.logs -} diff --git a/scripts/developer/utilities/lib/hifi-qml/styles-uit/OverlayTitle.qml b/scripts/developer/utilities/lib/hifi-qml/styles-uit/OverlayTitle.qml deleted file mode 100644 index e23b9eca14..0000000000 --- a/scripts/developer/utilities/lib/hifi-qml/styles-uit/OverlayTitle.qml +++ /dev/null @@ -1,18 +0,0 @@ -// -// OverlayTitle.qml -// -// Created by Clement on 7/18/16 -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 -import "." - -RalewayRegular { - font.pixelSize: hifi.fontSizes.overlayTitle -} diff --git a/scripts/developer/utilities/lib/hifi-qml/styles-uit/RalewayBold.qml b/scripts/developer/utilities/lib/hifi-qml/styles-uit/RalewayBold.qml deleted file mode 100644 index 433fdb7ae6..0000000000 --- a/scripts/developer/utilities/lib/hifi-qml/styles-uit/RalewayBold.qml +++ /dev/null @@ -1,24 +0,0 @@ -// -// RalewayBold.qml -// -// Created by David Rowe on 12 Feb 2016 -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 - -Text { - id: root - FontLoader { id: ralewayBold; source: pathToFonts + "fonts/Raleway-Bold.ttf"; } - property real size: 32 - font.pixelSize: size - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignLeft - font.family: ralewayBold.name - font.bold: true // Font seems to need this in order to display bold. -} diff --git a/scripts/developer/utilities/lib/hifi-qml/styles-uit/RalewayLight.qml b/scripts/developer/utilities/lib/hifi-qml/styles-uit/RalewayLight.qml deleted file mode 100644 index 913918afd7..0000000000 --- a/scripts/developer/utilities/lib/hifi-qml/styles-uit/RalewayLight.qml +++ /dev/null @@ -1,23 +0,0 @@ -// -// RalewayLight.qml -// -// Created by David Rowe on 12 Feb 2016 -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 - -Text { - id: root - FontLoader { id: ralewayLight; source: "../../fonts/Raleway-Light.ttf"; } - property real size: 32 - font.pixelSize: size - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignLeft - font.family: ralewayLight.name -} diff --git a/scripts/developer/utilities/lib/hifi-qml/styles-uit/RalewayRegular.qml b/scripts/developer/utilities/lib/hifi-qml/styles-uit/RalewayRegular.qml deleted file mode 100644 index 2cffeeb59d..0000000000 --- a/scripts/developer/utilities/lib/hifi-qml/styles-uit/RalewayRegular.qml +++ /dev/null @@ -1,23 +0,0 @@ -// -// RalewayRegular.qml -// -// Created by David Rowe on 12 Feb 2016 -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 - -Text { - id: root - FontLoader { id: ralewayRegular; source: pathToFonts + "fonts/Raleway-Regular.ttf"; } - property real size: 32 - font.pixelSize: size - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignLeft - font.family: ralewayRegular.name -} diff --git a/scripts/developer/utilities/lib/hifi-qml/styles-uit/RalewaySemiBold.qml b/scripts/developer/utilities/lib/hifi-qml/styles-uit/RalewaySemiBold.qml deleted file mode 100644 index b6c79e02a4..0000000000 --- a/scripts/developer/utilities/lib/hifi-qml/styles-uit/RalewaySemiBold.qml +++ /dev/null @@ -1,23 +0,0 @@ -// -// RalewaySemiBold.qml -// -// Created by David Rowe on 12 Feb 2016 -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 - -Text { - id: root - FontLoader { id: ralewaySemiBold; source: pathToFonts + "fonts/Raleway-SemiBold.ttf"; } - property real size: 32 - font.pixelSize: size - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignLeft - font.family: ralewaySemiBold.name -} diff --git a/scripts/developer/utilities/lib/hifi-qml/styles-uit/SectionName.qml b/scripts/developer/utilities/lib/hifi-qml/styles-uit/SectionName.qml deleted file mode 100644 index 5438fec7bc..0000000000 --- a/scripts/developer/utilities/lib/hifi-qml/styles-uit/SectionName.qml +++ /dev/null @@ -1,19 +0,0 @@ -// -// SectionName.qml -// -// Created by Clement on 7/18/16 -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 -import "." - -RalewayRegular { - font.pixelSize: hifi.fontSizes.sectionName - font.capitalization: Font.AllUppercase -} diff --git a/scripts/developer/utilities/lib/hifi-qml/styles-uit/Separator.qml b/scripts/developer/utilities/lib/hifi-qml/styles-uit/Separator.qml deleted file mode 100644 index 4134b928a7..0000000000 --- a/scripts/developer/utilities/lib/hifi-qml/styles-uit/Separator.qml +++ /dev/null @@ -1,41 +0,0 @@ -// -// Separator.qml -// -// Created by Zach Fox on 2017-06-06 -// Copyright 2017 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -import QtQuick 2.5 -import "../styles-uit" - -Item { - // Size - height: 2; - width: parent.width; - - Rectangle { - // Size - width: parent.width; - height: 1; - // Anchors - anchors.left: parent.left; - anchors.bottom: parent.bottom; - anchors.bottomMargin: height; - // Style - color: hifi.colors.baseGrayShadow; - } - - Rectangle { - // Size - width: parent.width; - height: 1; - // Anchors - anchors.left: parent.left; - anchors.bottom: parent.bottom; - // Style - color: hifi.colors.baseGrayHighlight; - } -} diff --git a/scripts/developer/utilities/lib/hifi-qml/styles-uit/ShortcutText.qml b/scripts/developer/utilities/lib/hifi-qml/styles-uit/ShortcutText.qml deleted file mode 100644 index a3ab351870..0000000000 --- a/scripts/developer/utilities/lib/hifi-qml/styles-uit/ShortcutText.qml +++ /dev/null @@ -1,18 +0,0 @@ -// -// ShortcutText.qml -// -// Created by Clement on 7/18/16 -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 -import "." - -RalewayLight { - font.pixelSize: hifi.fontSizes.shortcutText -} diff --git a/scripts/developer/utilities/lib/hifi-qml/styles-uit/TabName.qml b/scripts/developer/utilities/lib/hifi-qml/styles-uit/TabName.qml deleted file mode 100644 index eb4e790e7e..0000000000 --- a/scripts/developer/utilities/lib/hifi-qml/styles-uit/TabName.qml +++ /dev/null @@ -1,19 +0,0 @@ -// -// TabName.qml -// -// Created by Clement on 7/18/16 -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 -import "." - -RalewayRegular { - font.pixelSize: hifi.fontSizes.tabName - font.capitalization: Font.AllUppercase -} diff --git a/scripts/developer/utilities/lib/hifi-qml/styles-uit/TextFieldInput.qml b/scripts/developer/utilities/lib/hifi-qml/styles-uit/TextFieldInput.qml deleted file mode 100644 index 010b4d03ad..0000000000 --- a/scripts/developer/utilities/lib/hifi-qml/styles-uit/TextFieldInput.qml +++ /dev/null @@ -1,18 +0,0 @@ -// -// TextFieldInput.qml -// -// Created by Clement on 7/18/16 -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 -import "." - -FiraSansSemiBold { - font.pixelSize: hifi.fontSizes.textFieldInput -} diff --git a/scripts/developer/utilities/render/deferredLighting.qml b/scripts/developer/utilities/render/deferredLighting.qml index 7ab7342605..d2f778c3a6 100644 --- a/scripts/developer/utilities/render/deferredLighting.qml +++ b/scripts/developer/utilities/render/deferredLighting.qml @@ -11,8 +11,8 @@ import QtQuick 2.7 import QtQuick.Controls 1.4 import QtQuick.Layouts 1.3 -import "../lib/hifi-qml/styles-uit" -import "../lib/hifi-qml/controls-uit" as HifiControls +import "qrc:///qml/styles-uit" +import "qrc:///qml/controls-uit" as HifiControls import "../lib/configprop" Rectangle { From 0ab06d624ae61ff871fc51e34b61377fdd62462e Mon Sep 17 00:00:00 2001 From: MissLiviRose Date: Thu, 26 Oct 2017 17:35:51 -0700 Subject: [PATCH 076/116] remove href property for non-owned avatar entities --- libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index f674a2206e..258a7f37c5 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -286,6 +286,13 @@ void Avatar::updateAvatarEntities() { properties.setScript(noScript); } + auto specifiedHref = properties.getHref(); + if (!isMyAvatar() && !specifiedHref.isEmpty()) { + qCDebug(avatars_renderer) << "removing entity href from avatar attached entity:" << entityID << "old href:" << specifiedHref; + QString noHref; + properties.setScript(noHref); + } + // When grabbing avatar entities, they are parented to the joint moving them, then when un-grabbed // they go back to the default parent (null uuid). When un-gripped, others saw the entity disappear. // The thinking here is the local position was noticed as changing, but not the parentID (since it is now From c7857d4fc310a9e4cef99c74d14c431d90e17685 Mon Sep 17 00:00:00 2001 From: MissLiviRose Date: Thu, 26 Oct 2017 17:47:04 -0700 Subject: [PATCH 077/116] actually remove href not script --- libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index 258a7f37c5..142e57c9e5 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -290,7 +290,7 @@ void Avatar::updateAvatarEntities() { if (!isMyAvatar() && !specifiedHref.isEmpty()) { qCDebug(avatars_renderer) << "removing entity href from avatar attached entity:" << entityID << "old href:" << specifiedHref; QString noHref; - properties.setScript(noHref); + properties.setHref(noHref); } // When grabbing avatar entities, they are parented to the joint moving them, then when un-grabbed From 0636a2db06cca814697d8322e8b026cd2f1c43a4 Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 26 Oct 2017 19:19:52 -0700 Subject: [PATCH 078/116] removing historic changes --- interface/src/ui/overlays/Billboard3DOverlay.cpp | 8 -------- interface/src/ui/overlays/Billboard3DOverlay.h | 2 -- 2 files changed, 10 deletions(-) diff --git a/interface/src/ui/overlays/Billboard3DOverlay.cpp b/interface/src/ui/overlays/Billboard3DOverlay.cpp index f19426b054..960f0de095 100644 --- a/interface/src/ui/overlays/Billboard3DOverlay.cpp +++ b/interface/src/ui/overlays/Billboard3DOverlay.cpp @@ -37,14 +37,6 @@ QVariant Billboard3DOverlay::getProperty(const QString &property) { return Planar3DOverlay::getProperty(property); } -void Billboard3DOverlay::update(float duration) { - // Billboard's transform needs to constantly be adjusted if it faces the avatar - // if (isFacingAvatar()) { - notifyRenderTransformChange(); - // } - Base3DOverlay::update(duration); -} - bool Billboard3DOverlay::applyTransformTo(Transform& transform, bool force) { bool transformChanged = false; if (force || usecTimestampNow() > _transformExpiry) { diff --git a/interface/src/ui/overlays/Billboard3DOverlay.h b/interface/src/ui/overlays/Billboard3DOverlay.h index 6f590dd6ec..6b3aa40451 100644 --- a/interface/src/ui/overlays/Billboard3DOverlay.h +++ b/interface/src/ui/overlays/Billboard3DOverlay.h @@ -26,8 +26,6 @@ public: void setProperties(const QVariantMap& properties) override; QVariant getProperty(const QString& property) override; - void update(float deltatime) override; - protected: virtual bool applyTransformTo(Transform& transform, bool force = false) override; From 1dbeac7b882433a01bc553f53fc4315bee057bf1 Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 26 Oct 2017 19:55:59 -0700 Subject: [PATCH 079/116] Adding the idons for Luci and cleaning up the scripts --- .../utilities/lib/configprop/ConfigSlider.qml | 75 ------------------- .../render/configSlider/ConfigSlider.qml | 44 ++++++----- .../utilities/render/debugDeferredLighting.js | 49 ------------ .../utilities/render/deferredLighting.qml | 4 +- scripts/developer/utilities/render/luci.js | 6 +- scripts/system/assets/images/luci-a.svg | 10 +++ scripts/system/assets/images/luci-i.svg | 13 ++++ 7 files changed, 56 insertions(+), 145 deletions(-) delete mode 100644 scripts/developer/utilities/lib/configprop/ConfigSlider.qml delete mode 100644 scripts/developer/utilities/render/debugDeferredLighting.js create mode 100644 scripts/system/assets/images/luci-a.svg create mode 100644 scripts/system/assets/images/luci-i.svg diff --git a/scripts/developer/utilities/lib/configprop/ConfigSlider.qml b/scripts/developer/utilities/lib/configprop/ConfigSlider.qml deleted file mode 100644 index bb46536fdc..0000000000 --- a/scripts/developer/utilities/lib/configprop/ConfigSlider.qml +++ /dev/null @@ -1,75 +0,0 @@ -// -// ConfigSlider.qml -// -// Created by Zach Pomerantz on 2/8/2016 -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html -// - -import QtQuick 2.7 -import QtQuick.Controls 1.4 as Original -import QtQuick.Controls.Styles 1.4 - -import "qrc:///qml/styles-uit" -import "qrc:///qml/controls-uit" as HifiControls - - -Item { - HifiConstants { id: luci } - id: root - - anchors.left: parent.left - anchors.right: parent.right - height: 24 - property bool integral: false - property var config - property string property - property alias label: labelControl.text - property alias min: sliderControl.minimumValue - property alias max: sliderControl.maximumValue - - Component.onCompleted: { - // Binding favors qml value, so set it first - sliderControl.value = root.config[root.property]; - bindingControl.when = true; - } - - HifiControls.Label { - id: labelControl - text: root.label - enabled: true - anchors.left: root.left - anchors.right: root.horizontalCenter - anchors.verticalCenter: root.verticalCenter - //anchors.topMargin: 7 - } - - HifiControls.Label { - id: labelValue - text: sliderControl.value.toFixed(root.integral ? 0 : 2) - anchors.right: root.right - anchors.bottom: root.bottom - anchors.bottomMargin: 0 - } - - Binding { - id: bindingControl - target: root.config - property: root.property - value: sliderControl.value - when: false - } - - HifiControls.Slider { - id: sliderControl - stepSize: root.integral ? 1.0 : 0.0 - //height: 20 - anchors.left: root.horizontalCenter - anchors.right: root.right - anchors.rightMargin: 0 - anchors.top: root.top - anchors.topMargin: 0 - } -} diff --git a/scripts/developer/utilities/render/configSlider/ConfigSlider.qml b/scripts/developer/utilities/render/configSlider/ConfigSlider.qml index 021365686a..bb46536fdc 100644 --- a/scripts/developer/utilities/render/configSlider/ConfigSlider.qml +++ b/scripts/developer/utilities/render/configSlider/ConfigSlider.qml @@ -1,6 +1,5 @@ // // ConfigSlider.qml -// examples/utilities/tools/render // // Created by Zach Pomerantz on 2/8/2016 // Copyright 2016 High Fidelity, Inc. @@ -8,12 +7,21 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html // -import QtQuick 2.5 -import QtQuick.Controls 1.4 + +import QtQuick 2.7 +import QtQuick.Controls 1.4 as Original +import QtQuick.Controls.Styles 1.4 + +import "qrc:///qml/styles-uit" +import "qrc:///qml/controls-uit" as HifiControls + Item { + HifiConstants { id: luci } id: root - width: 400 + + anchors.left: parent.left + anchors.right: parent.right height: 24 property bool integral: false property var config @@ -28,22 +36,22 @@ Item { bindingControl.when = true; } - Label { + HifiControls.Label { id: labelControl text: root.label + enabled: true anchors.left: root.left - anchors.leftMargin: 8 - anchors.top: root.top - anchors.topMargin: 7 + anchors.right: root.horizontalCenter + anchors.verticalCenter: root.verticalCenter + //anchors.topMargin: 7 } - Label { + HifiControls.Label { id: labelValue text: sliderControl.value.toFixed(root.integral ? 0 : 2) - anchors.left: root.left - anchors.leftMargin: 200 - anchors.top: root.top - anchors.topMargin: 15 + anchors.right: root.right + anchors.bottom: root.bottom + anchors.bottomMargin: 0 } Binding { @@ -54,14 +62,14 @@ Item { when: false } - Slider { + HifiControls.Slider { id: sliderControl stepSize: root.integral ? 1.0 : 0.0 - width: root.width-130 - height: 20 + //height: 20 + anchors.left: root.horizontalCenter anchors.right: root.right - anchors.rightMargin: 8 + anchors.rightMargin: 0 anchors.top: root.top - anchors.topMargin: 3 + anchors.topMargin: 0 } } diff --git a/scripts/developer/utilities/render/debugDeferredLighting.js b/scripts/developer/utilities/render/debugDeferredLighting.js deleted file mode 100644 index 2a9b1a1067..0000000000 --- a/scripts/developer/utilities/render/debugDeferredLighting.js +++ /dev/null @@ -1,49 +0,0 @@ -// -// debugDeferredLighting.js -// -// Created by Sam Gateau on 6/6/2016 -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html -// - -// Set up the qml ui -var qml = Script.resolvePath('deferredLighting.qml'); -var window = new OverlayWindow({ - title: 'Lighting', - source: qml, - width: 400, height:400, -}); -window.setPosition(Window.innerWidth - 420, 50); -window.closed.connect(function() { Script.stop(); }); - - -var DDB = Render.RenderDeferredTask.DebugDeferredBuffer; -DDB.enabled = true; -DDB.mode = 0; - -// Debug buffer sizing -var resizing = false; -Controller.mousePressEvent.connect(function (e) { - if (shouldStartResizing(e.x)) { - resizing = true; - } -}); -Controller.mouseReleaseEvent.connect(function() { resizing = false; }); -Controller.mouseMoveEvent.connect(function (e) { resizing && setDebugBufferSize(e.x); }); -Script.scriptEnding.connect(function () { DDB.enabled = false; }); - -function shouldStartResizing(eventX) { - var x = Math.abs(eventX - Window.innerWidth * (1.0 + DDB.size.x) / 2.0); - var mode = DDB.mode; - return mode !== 0 && x < 20; -} - -function setDebugBufferSize(x) { - x = (2.0 * (x / Window.innerWidth) - 1.0); // scale - x = Math.min(Math.max(-1, x), 1); // clamp - DDB.size = { x: x, y: -1, z: 1, w: 1 }; -} - - diff --git a/scripts/developer/utilities/render/deferredLighting.qml b/scripts/developer/utilities/render/deferredLighting.qml index d2f778c3a6..afb1f24baf 100644 --- a/scripts/developer/utilities/render/deferredLighting.qml +++ b/scripts/developer/utilities/render/deferredLighting.qml @@ -13,7 +13,7 @@ import QtQuick.Layouts 1.3 import "qrc:///qml/styles-uit" import "qrc:///qml/controls-uit" as HifiControls -import "../lib/configprop" +import "configSlider" Rectangle { HifiConstants { id: hifi;} @@ -36,7 +36,7 @@ Rectangle { anchors.right: parent.right // padding: hifi.dimensions.contentMargin.x - ConfigSlider { + ConfigSlider { label: qsTr("ToneMapping") integral: false config: render.mainViewTask.getConfig("ToneMapping") diff --git a/scripts/developer/utilities/render/luci.js b/scripts/developer/utilities/render/luci.js index 3e0beb2181..1e2ac1261f 100644 --- a/scripts/developer/utilities/render/luci.js +++ b/scripts/developer/utilities/render/luci.js @@ -13,6 +13,8 @@ (function() { var TABLET_BUTTON_NAME = "LUCI"; var QMLAPP_URL = Script.resolvePath("./deferredLighting.qml"); + var ICON_URL = Script.resolvePath("../../../system/assets/images/luci-i.svg"); + var ACTIVE_ICON_URL = Script.resolvePath("../../../system/assets/images/luci-a.svg"); var onLuciScreen = false; @@ -27,7 +29,9 @@ var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); var button = tablet.addButton({ - text: TABLET_BUTTON_NAME, + text: TABLET_BUTTON_NAME, + icon: ICON_URL, + activeIcon: ACTIVE_ICON_URL, sortOrder: 1 }); diff --git a/scripts/system/assets/images/luci-a.svg b/scripts/system/assets/images/luci-a.svg new file mode 100644 index 0000000000..40e1481eba --- /dev/null +++ b/scripts/system/assets/images/luci-a.svg @@ -0,0 +1,10 @@ + + + + + + + diff --git a/scripts/system/assets/images/luci-i.svg b/scripts/system/assets/images/luci-i.svg new file mode 100644 index 0000000000..2d73339908 --- /dev/null +++ b/scripts/system/assets/images/luci-i.svg @@ -0,0 +1,13 @@ + + + + + + + + From 901e14571211dd2a769aa4cdf96996838603ad26 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 26 Oct 2017 22:57:33 -0700 Subject: [PATCH 080/116] remove redundant dimensionsChanged() --- libraries/entities/src/EntityItem.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 008ec9769f..059e6bf151 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1754,7 +1754,6 @@ void EntityItem::updateDimensions(const glm::vec3& value) { setDimensions(value); markDirtyFlags(Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS); _queryAACubeSet = false; - dimensionsChanged(); } } From 474609dabf1cab9d65c886281dfa49e56b14f9f6 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 26 Oct 2017 22:58:24 -0700 Subject: [PATCH 081/116] enforce dimensions of Circles and Quads --- libraries/entities/src/ShapeEntityItem.cpp | 44 ++++++++++++---------- libraries/entities/src/ShapeEntityItem.h | 2 + 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/libraries/entities/src/ShapeEntityItem.cpp b/libraries/entities/src/ShapeEntityItem.cpp index 9a1a500a54..8c7d1576e1 100644 --- a/libraries/entities/src/ShapeEntityItem.cpp +++ b/libraries/entities/src/ShapeEntityItem.cpp @@ -104,6 +104,14 @@ void ShapeEntityItem::setShape(const entity::Shape& shape) { case entity::Shape::Sphere: _type = EntityTypes::Sphere; break; + case entity::Shape::Circle: + // Circle is implicitly flat so we enforce flat dimensions + setDimensions(getDimensions()); + break; + case entity::Shape::Quad: + // Quad is implicitly flat so we enforce flat dimensions + setDimensions(getDimensions()); + break; default: _type = EntityTypes::Shape; break; @@ -196,6 +204,18 @@ void ShapeEntityItem::setColor(const QColor& value) { setAlpha(value.alpha()); } +void ShapeEntityItem::setDimensions(const glm::vec3& value) { + const float MAX_FLAT_DIMENSION = 0.0001f; + if ((_shape == entity::Shape::Circle || _shape == entity::Shape::Quad) && value.y > MAX_FLAT_DIMENSION) { + // enforce flatness in Y + glm::vec3 newDimensions = value; + newDimensions.y = MAX_FLAT_DIMENSION; + EntityItem::setDimensions(newDimensions); + } else { + EntityItem::setDimensions(value); + } +} + bool ShapeEntityItem::supportsDetailedRayIntersection() const { return _shape == entity::Sphere; } @@ -249,13 +269,8 @@ void ShapeEntityItem::computeShapeInfo(ShapeInfo& info) { const glm::vec3 entityDimensions = getDimensions(); switch (_shape){ - case entity::Shape::Quad: { - // Not in GeometryCache::buildShapes, unsupported. - _collisionShapeType = SHAPE_TYPE_ELLIPSOID; - //TODO WL21389: Add a SHAPE_TYPE_QUAD ShapeType and treat - // as a special box (later if desired support) - } - break; + case entity::Shape::Quad: + // Quads collide like flat Cubes case entity::Shape::Cube: { _collisionShapeType = SHAPE_TYPE_BOX; } @@ -275,19 +290,10 @@ void ShapeEntityItem::computeShapeInfo(ShapeInfo& info) { } } break; - case entity::Shape::Circle: { - _collisionShapeType = SHAPE_TYPE_CIRCLE; - } - break; + case entity::Shape::Circle: + // Circles collide like flat Cylinders case entity::Shape::Cylinder: { _collisionShapeType = SHAPE_TYPE_CYLINDER_Y; - // TODO WL21389: determine if rotation is axis-aligned - //const Transform::Quat & rot = _transform.getRotation(); - - // TODO WL21389: some way to tell apart SHAPE_TYPE_CYLINDER_Y, _X, _Z based on rotation and - // hull ( or dimensions, need circular cross section) - // Should allow for minor variance along axes? - } break; case entity::Shape::Cone: { @@ -330,7 +336,7 @@ void ShapeEntityItem::computeShapeInfo(ShapeInfo& info) { case entity::Shape::Torus: { // Not in GeometryCache::buildShapes, unsupported. _collisionShapeType = SHAPE_TYPE_ELLIPSOID; - //TODO WL21389: SHAPE_TYPE_SIMPLE_HULL and pointCollection (later if desired support) + //TODO handle this shape more correctly } break; default: { diff --git a/libraries/entities/src/ShapeEntityItem.h b/libraries/entities/src/ShapeEntityItem.h index a88a2098e9..20e36c88e6 100644 --- a/libraries/entities/src/ShapeEntityItem.h +++ b/libraries/entities/src/ShapeEntityItem.h @@ -80,6 +80,8 @@ public: const rgbColor& getColor() const { return _color; } void setColor(const rgbColor& value); + void setDimensions(const glm::vec3& value) override; + xColor getXColor() const; void setColor(const xColor& value); From 2710dca37c70fa331f10ee80ad1232155d113961 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 26 Oct 2017 22:58:50 -0700 Subject: [PATCH 082/116] fix rendering of Circles and Quads --- libraries/render-utils/src/GeometryCache.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index f35fb9f830..fa00737e3c 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -482,8 +482,10 @@ void GeometryCache::buildShapes() { using namespace geometry; auto vertexBuffer = std::make_shared(); auto indexBuffer = std::make_shared(); - // Cube + // Cube setupFlatShape(_shapes[Cube], geometry::cube(), _shapeVertices, _shapeIndices); + //Quad renders as flat Cube + setupFlatShape(_shapes[Quad], geometry::cube(), _shapeVertices, _shapeIndices); // Tetrahedron setupFlatShape(_shapes[Tetrahedron], geometry::tetrahedron(), _shapeVertices, _shapeIndices); // Icosahedron @@ -524,12 +526,10 @@ void GeometryCache::buildShapes() { extrudePolygon<64>(_shapes[Cylinder], _shapeVertices, _shapeIndices); //Cone, extrudePolygon<64>(_shapes[Cone], _shapeVertices, _shapeIndices, true); - //Circle - drawCircle(_shapes[Circle], _shapeVertices, _shapeIndices); + // Circle renders as flat Cylinder + extrudePolygon<64>(_shapes[Circle], _shapeVertices, _shapeIndices); // Not implemented yet: - //Quad, - //Torus, - + //Torus, } const GeometryCache::ShapeData * GeometryCache::getShapeData(const Shape shape) const { From 5ed58d5e5dc6012ed054f72ba3b60f6d0c3a7900 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 26 Oct 2017 22:59:25 -0700 Subject: [PATCH 083/116] enable Quad in ShapeEntityItem properties --- scripts/system/html/entityProperties.html | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/system/html/entityProperties.html b/scripts/system/html/entityProperties.html index 2d5dd35e66..d2c33984ff 100644 --- a/scripts/system/html/entityProperties.html +++ b/scripts/system/html/entityProperties.html @@ -59,6 +59,7 @@ +
From a2765cffbd565ea5489abdbd91028c126571bb4b Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 26 Oct 2017 23:22:06 -0700 Subject: [PATCH 084/116] adjusting the qml again ? i just hate the layout / anchor system --- .../utilities/render/deferredLighting.qml | 53 +++++++++---------- 1 file changed, 25 insertions(+), 28 deletions(-) diff --git a/scripts/developer/utilities/render/deferredLighting.qml b/scripts/developer/utilities/render/deferredLighting.qml index afb1f24baf..6837b4d37f 100644 --- a/scripts/developer/utilities/render/deferredLighting.qml +++ b/scripts/developer/utilities/render/deferredLighting.qml @@ -21,39 +21,25 @@ Rectangle { anchors.margins: hifi.dimensions.contentMargin.x color: hifi.colors.baseGray; - property var mainViewTask: Render.getConfig("RenderMainView") + property var mainViewTask: Render.getConfig("RenderMainView") - Row { - anchors.left: parent.left - anchors.right: parent.right - anchors.margins: 10 Column { - padding: 10 spacing: 5 - - // width: parent.width anchors.left: parent.left anchors.right: parent.right - // padding: hifi.dimensions.contentMargin.x - - ConfigSlider { - label: qsTr("ToneMapping") - integral: false - config: render.mainViewTask.getConfig("ToneMapping") - property: "exposure" - max: 2 - min: 0 - - anchors.left: parent.left - anchors.right: parent.right + anchors.margins: hifi.dimensions.contentMargin.x + //padding: hifi.dimensions.contentMargin.x + HifiControls.Label { + text: "Shading" } - Row { - + anchors.left: parent.left + anchors.right: parent.right + spacing: 20 - padding: 10 Column { spacing: 10 + // padding: 10 Repeater { model: [ "Unlit:LightingModel:enableUnlit", @@ -116,6 +102,8 @@ Rectangle { } Separator {} Column { + anchors.left: parent.left + anchors.right: parent.right spacing: 10 Repeater { model: [ "Tone Mapping Exposure:ToneMapping:exposure:5.0:-5.0" @@ -127,17 +115,22 @@ Rectangle { property: modelData.split(":")[2] max: modelData.split(":")[3] min: modelData.split(":")[4] + + anchors.left: parent.left + anchors.right: parent.right } } Row { + anchors.left: parent.left + anchors.right: parent.right HifiControls.Label { text: "Tone Mapping Curve" - anchors.left: root.left + // anchors.left: parent.left } HifiControls.ComboBox { - anchors.right: root.right + // anchors.right: parent.right currentIndex: 1 model: ListModel { id: cbItems @@ -151,7 +144,11 @@ Rectangle { } } } + Separator {} + Row { + anchors.left: parent.left + anchors.right: parent.right id: framebuffer spacing: 10 height: 24 @@ -159,7 +156,7 @@ Rectangle { HifiControls.Label { text: "Debug Framebuffer" height: 24 - anchors.left: root.left + // anchors.left: parent.left } property var config: render.mainViewTask.getConfig("DebugDeferredBuffer") @@ -171,7 +168,7 @@ Rectangle { HifiControls.ComboBox { height: 24 - anchors.right: root.right + // anchors.right: parent.right currentIndex: 0 model: ListModel { id: cbItemsFramebuffer @@ -273,5 +270,5 @@ Rectangle { } } } - } + //} } From 66c31caf4b17a970a6b47419a4d7abf1318126bb Mon Sep 17 00:00:00 2001 From: Nissim Hadar Date: Fri, 27 Oct 2017 09:08:58 -0700 Subject: [PATCH 085/116] Refactoring of the haze --- .../src/RenderableZoneEntityItem.cpp | 6 +- libraries/entities/CMakeLists.txt | 2 +- libraries/entities/src/HazePropertyGroup.cpp | 13 ---- libraries/entities/src/HazePropertyGroup.h | 33 +++------ libraries/entities/src/ZoneEntityItem.h | 19 ++--- libraries/model/src/model/Haze.cpp | 42 +++++------ libraries/model/src/model/Haze.h | 65 +++-------------- libraries/model/src/model/HazeInit.h | 69 +++++++++++++++++++ .../render-utils/src/DeferredGlobalLight.slh | 10 +-- .../src/DeferredLightingEffect.cpp | 4 +- libraries/render-utils/src/DrawHaze.cpp | 34 ++++----- libraries/render-utils/src/DrawHaze.h | 68 +++++++++--------- libraries/render-utils/src/Haze.slf | 20 +++--- libraries/render-utils/src/Haze.slh | 14 ++-- libraries/render-utils/src/HazeStage.cpp | 10 +-- libraries/render-utils/src/HazeStage.h | 44 ++++++------ scripts/system/html/entityProperties.html | 16 ++--- scripts/system/html/js/entityProperties.js | 28 ++++---- 18 files changed, 249 insertions(+), 248 deletions(-) create mode 100644 libraries/model/src/model/HazeInit.h diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp index 0235f1b7a3..877e245006 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp @@ -346,15 +346,15 @@ void ZoneEntityRenderer::updateHazeFromEntity(const TypedEntityPointer& entity) xColor hazeColor = _hazeProperties.getHazeColor(); haze->setHazeColor(glm::vec3(hazeColor.red / 255.0, hazeColor.green / 255.0, hazeColor.blue / 255.0)); xColor hazeGlareColor = _hazeProperties.getHazeGlareColor(); - haze->setDirectionalLightColor(glm::vec3(hazeGlareColor.red / 255.0, hazeGlareColor.green / 255.0, hazeGlareColor.blue / 255.0)); + haze->setHazeGlareColor(glm::vec3(hazeGlareColor.red / 255.0, hazeGlareColor.green / 255.0, hazeGlareColor.blue / 255.0)); haze->setHazeEnableGlare(_hazeProperties.getHazeEnableGlare()); - haze->setDirectionalLightBlend(model::convertDirectionalLightAngleToPower(_hazeProperties.getHazeGlareAngle())); + haze->setHazeGlareBlend(model::convertGlareAngleToPower(_hazeProperties.getHazeGlareAngle())); float hazeAltitude = _hazeProperties.getHazeCeiling() - _hazeProperties.getHazeBaseRef(); haze->setHazeAltitudeFactor(model::convertHazeAltitudeToHazeAltitudeFactor(hazeAltitude)); haze->setHazeBaseReference(_hazeProperties.getHazeBaseRef()); - haze->setHazeBackgroundBlendValue(_hazeProperties.getHazeBackgroundBlend()); + haze->setHazeBackgroundBlend(_hazeProperties.getHazeBackgroundBlend()); haze->setHazeAttenuateKeyLight(_hazeProperties.getHazeAttenuateKeyLight()); haze->setHazeKeyLightRangeFactor(model::convertHazeRangeToHazeRangeFactor(_hazeProperties.getHazeKeyLightRange())); diff --git a/libraries/entities/CMakeLists.txt b/libraries/entities/CMakeLists.txt index 322d69da16..c23740654e 100644 --- a/libraries/entities/CMakeLists.txt +++ b/libraries/entities/CMakeLists.txt @@ -1,4 +1,4 @@ set(TARGET_NAME entities) setup_hifi_library(Network Script) include_directories(SYSTEM "${OPENSSL_INCLUDE_DIR}") -link_hifi_libraries(shared networking octree avatars) +link_hifi_libraries(shared networking octree avatars model) diff --git a/libraries/entities/src/HazePropertyGroup.cpp b/libraries/entities/src/HazePropertyGroup.cpp index 996d2e0cd3..3cc3e69960 100644 --- a/libraries/entities/src/HazePropertyGroup.cpp +++ b/libraries/entities/src/HazePropertyGroup.cpp @@ -15,19 +15,6 @@ #include "EntityItemProperties.h" #include "EntityItemPropertiesMacros.h" -const float HazePropertyGroup::DEFAULT_HAZE_RANGE{ 1000.0f }; -const xColor HazePropertyGroup::DEFAULT_HAZE_COLOR{ 128, 154, 179 }; // Bluish -const xColor HazePropertyGroup::DEFAULT_HAZE_GLARE_COLOR{ 255, 229, 179 }; // Yellowish -const float HazePropertyGroup::DEFAULT_HAZE_GLARE_ANGLE{ 20.0 }; - -const float HazePropertyGroup::DEFAULT_HAZE_CEILING{ 200.0f }; -const float HazePropertyGroup::DEFAULT_HAZE_BASE_REF{ 0.0f }; - -const float HazePropertyGroup::DEFAULT_HAZE_BACKGROUND_BLEND{ 0.0f }; - -const float HazePropertyGroup::DEFAULT_HAZE_KEYLIGHT_RANGE{ 1000.0 }; -const float HazePropertyGroup::DEFAULT_HAZE_KEYLIGHT_ALTITUDE{ 200.0f }; - void HazePropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const { COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_HAZE_RANGE, Haze, haze, HazeRange, hazeRange); COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_HAZE_COLOR, Haze, haze, HazeColor, hazeColor); diff --git a/libraries/entities/src/HazePropertyGroup.h b/libraries/entities/src/HazePropertyGroup.h index cdd36ff7ef..1cbaa24f2a 100644 --- a/libraries/entities/src/HazePropertyGroup.h +++ b/libraries/entities/src/HazePropertyGroup.h @@ -21,6 +21,8 @@ #include "PropertyGroup.h" #include "EntityItemPropertiesMacros.h" +#include + class EntityItemProperties; class EncodeBitstreamParams; class OctreePacketData; @@ -74,38 +76,25 @@ public: EntityPropertyFlags& propertyFlags, bool overwriteLocalData, bool& somethingChanged) override; - static const float DEFAULT_HAZE_RANGE; - static const xColor DEFAULT_HAZE_COLOR; - static const xColor DEFAULT_HAZE_GLARE_COLOR; - static const float DEFAULT_HAZE_GLARE_ANGLE; - - static const float DEFAULT_HAZE_CEILING; - static const float DEFAULT_HAZE_BASE_REF; - - static const float DEFAULT_HAZE_BACKGROUND_BLEND; - - static const float DEFAULT_HAZE_KEYLIGHT_RANGE; - static const float DEFAULT_HAZE_KEYLIGHT_ALTITUDE; - // Range only parameters - DEFINE_PROPERTY(PROP_HAZE_RANGE, HazeRange, hazeRange, float, DEFAULT_HAZE_RANGE); - DEFINE_PROPERTY_REF(PROP_HAZE_COLOR, HazeColor, hazeColor, xColor, DEFAULT_HAZE_COLOR); - DEFINE_PROPERTY_REF(PROP_HAZE_GLARE_COLOR, HazeGlareColor, hazeGlareColor, xColor, DEFAULT_HAZE_GLARE_COLOR); + DEFINE_PROPERTY(PROP_HAZE_RANGE, HazeRange, hazeRange, float, model::initialHazeRange_m); + DEFINE_PROPERTY_REF(PROP_HAZE_COLOR, HazeColor, hazeColor, xColor, model::initialHazeColorXcolor); + DEFINE_PROPERTY_REF(PROP_HAZE_GLARE_COLOR, HazeGlareColor, hazeGlareColor, xColor, model::initialHazeGlareColorXcolor); DEFINE_PROPERTY(PROP_HAZE_ENABLE_GLARE, HazeEnableGlare, hazeEnableGlare, bool, false); - DEFINE_PROPERTY_REF(PROP_HAZE_GLARE_ANGLE, HazeGlareAngle, hazeGlareAngle, float, DEFAULT_HAZE_GLARE_ANGLE); + DEFINE_PROPERTY_REF(PROP_HAZE_GLARE_ANGLE, HazeGlareAngle, hazeGlareAngle, float, model::initialGlareAngle_degs); // Altitude parameters DEFINE_PROPERTY(PROP_HAZE_ALTITUDE_EFFECT, HazeAltitudeEffect, hazeAltitudeEffect, bool, false); - DEFINE_PROPERTY_REF(PROP_HAZE_CEILING, HazeCeiling, hazeCeiling, float, DEFAULT_HAZE_CEILING); - DEFINE_PROPERTY_REF(PROP_HAZE_BASE_REF, HazeBaseRef, hazeBaseRef, float, DEFAULT_HAZE_BASE_REF); + DEFINE_PROPERTY_REF(PROP_HAZE_CEILING, HazeCeiling, hazeCeiling, float, model::initialHazeBaseReference_m + model::initialHazeHeight_m); + DEFINE_PROPERTY_REF(PROP_HAZE_BASE_REF, HazeBaseRef, hazeBaseRef, float, model::initialHazeBaseReference_m); // Background (skybox) blend value - DEFINE_PROPERTY_REF(PROP_HAZE_BACKGROUND_BLEND, HazeBackgroundBlend, hazeBackgroundBlend, float, DEFAULT_HAZE_BACKGROUND_BLEND); + DEFINE_PROPERTY_REF(PROP_HAZE_BACKGROUND_BLEND, HazeBackgroundBlend, hazeBackgroundBlend, float, model::initialHazeBackgroundBlend); // hazeDirectional light attenuation DEFINE_PROPERTY(PROP_HAZE_ATTENUATE_KEYLIGHT, HazeAttenuateKeyLight, hazeAttenuateKeyLight, bool, false); - DEFINE_PROPERTY_REF(PROP_HAZE_KEYLIGHT_RANGE, HazeKeyLightRange, hazeKeyLightRange, float, DEFAULT_HAZE_KEYLIGHT_RANGE); - DEFINE_PROPERTY_REF(PROP_HAZE_KEYLIGHT_ALTITUDE, HazeKeyLightAltitude, hazeKeyLightAltitude, float, DEFAULT_HAZE_KEYLIGHT_ALTITUDE); + DEFINE_PROPERTY_REF(PROP_HAZE_KEYLIGHT_RANGE, HazeKeyLightRange, hazeKeyLightRange, float, model::initialHazeKeyLightRange_m); + DEFINE_PROPERTY_REF(PROP_HAZE_KEYLIGHT_ALTITUDE, HazeKeyLightAltitude, hazeKeyLightAltitude, float, model::initialHazeKeyLightAltitude_m); }; #endif // hifi_HazePropertyGroup_h diff --git a/libraries/entities/src/ZoneEntityItem.h b/libraries/entities/src/ZoneEntityItem.h index ddbb2ed914..628c228af6 100644 --- a/libraries/entities/src/ZoneEntityItem.h +++ b/libraries/entities/src/ZoneEntityItem.h @@ -19,6 +19,7 @@ #include "HazePropertyGroup.h" #include "StagePropertyGroup.h" #include +#include class ZoneEntityItem : public EntityItem { public: @@ -150,20 +151,20 @@ protected: uint32_t _hazeMode{ DEFAULT_HAZE_MODE }; - float _hazeRange{ HazePropertyGroup::DEFAULT_HAZE_RANGE }; - xColor _hazeColor{ HazePropertyGroup::DEFAULT_HAZE_COLOR }; - xColor _hazeGlareColor{ HazePropertyGroup::DEFAULT_HAZE_GLARE_COLOR }; + float _hazeRange{ model::initialHazeRange_m }; + xColor _hazeColor{ model::initialHazeColorXcolor }; + xColor _hazeGlareColor{ model::initialHazeGlareColorXcolor }; bool _hazeEnableGlare{ false }; - float _hazeGlareAngle{ HazePropertyGroup::DEFAULT_HAZE_GLARE_ANGLE }; + float _hazeGlareAngle{ model::initialGlareAngle_degs }; - float _hazeCeiling{ HazePropertyGroup::DEFAULT_HAZE_CEILING }; - float _hazeBaseRef{ HazePropertyGroup::DEFAULT_HAZE_BASE_REF }; + float _hazeCeiling{ model::initialHazeBaseReference_m + model::initialHazeHeight_m }; + float _hazeBaseRef{ model::initialHazeBaseReference_m }; - float _hazeBackgroundBlend{ HazePropertyGroup::DEFAULT_HAZE_BACKGROUND_BLEND }; + float _hazeBackgroundBlend{ model::initialHazeBackgroundBlend }; bool _hazeAttenuateKeyLight{ false }; - float _hazeKeyLightRange{ HazePropertyGroup::DEFAULT_HAZE_KEYLIGHT_RANGE }; - float _hazeKeyLightAltitude{ HazePropertyGroup::DEFAULT_HAZE_KEYLIGHT_ALTITUDE }; + float _hazeKeyLightRange{ model::initialHazeKeyLightRange_m }; + float _hazeKeyLightAltitude{ model::initialHazeKeyLightAltitude_m }; SkyboxPropertyGroup _skyboxProperties; HazePropertyGroup _hazeProperties; diff --git a/libraries/model/src/model/Haze.cpp b/libraries/model/src/model/Haze.cpp index 679d4ad3d1..1c9b989fd1 100644 --- a/libraries/model/src/model/Haze.cpp +++ b/libraries/model/src/model/Haze.cpp @@ -23,7 +23,7 @@ Haze::Haze() { enum HazeModes { HAZE_MODE_IS_ACTIVE = 1 << 0, HAZE_MODE_IS_ALTITUDE_BASED = 1 << 1, - HAZE_MODE_IS_DIRECTIONAL_LIGHT_ATTENUATED = 1 << 2, + HAZE_MODE_IS_KEYLIGHT_ATTENUATED = 1 << 2, HAZE_MODE_IS_MODULATE_COLOR = 1 << 3, HAZE_MODE_IS_ENABLE_LIGHT_BLEND = 1 << 4 }; @@ -55,25 +55,25 @@ void Haze::setHazeEnableGlare(const bool isHazeEnableGlare) { } } -void Haze::setDirectionalLightBlend(const float hazeDirectionalLightBlend) { +void Haze::setHazeGlareBlend(const float hazeGlareBlend) { auto& params = _hazeParametersBuffer.get(); - if (params.directionalLightBlend != hazeDirectionalLightBlend) { - _hazeParametersBuffer.edit().directionalLightBlend = hazeDirectionalLightBlend; + if (params.hazeGlareBlend != hazeGlareBlend) { + _hazeParametersBuffer.edit().hazeGlareBlend = hazeGlareBlend; } } -void Haze::setDirectionalLightColor(const glm::vec3 hazeDirectionalLightColor) { +void Haze::setHazeGlareColor(const glm::vec3 hazeGlareColor) { auto& params = _hazeParametersBuffer.get(); - if (params.directionalLightColor.r != hazeDirectionalLightColor.r) { - _hazeParametersBuffer.edit().directionalLightColor.r = hazeDirectionalLightColor.r; + if (params.hazeGlareColor.r != hazeGlareColor.r) { + _hazeParametersBuffer.edit().hazeGlareColor.r = hazeGlareColor.r; } - if (params.directionalLightColor.g != hazeDirectionalLightColor.g) { - _hazeParametersBuffer.edit().directionalLightColor.g = hazeDirectionalLightColor.g; + if (params.hazeGlareColor.g != hazeGlareColor.g) { + _hazeParametersBuffer.edit().hazeGlareColor.g = hazeGlareColor.g; } - if (params.directionalLightColor.b != hazeDirectionalLightColor.b) { - _hazeParametersBuffer.edit().directionalLightColor.b = hazeDirectionalLightColor.b; + if (params.hazeGlareColor.b != hazeGlareColor.b) { + _hazeParametersBuffer.edit().hazeGlareColor.b = hazeGlareColor.b; } } void Haze::setHazeActive(const bool isHazeActive) { @@ -99,10 +99,10 @@ void Haze::setAltitudeBased(const bool isAltitudeBased) { void Haze::setHazeAttenuateKeyLight(const bool isHazeAttenuateKeyLight) { auto& params = _hazeParametersBuffer.get(); - if (((params.hazeMode & HAZE_MODE_IS_DIRECTIONAL_LIGHT_ATTENUATED) == HAZE_MODE_IS_DIRECTIONAL_LIGHT_ATTENUATED ) && !isHazeAttenuateKeyLight) { - _hazeParametersBuffer.edit().hazeMode &= ~HAZE_MODE_IS_DIRECTIONAL_LIGHT_ATTENUATED; - } else if (((params.hazeMode & HAZE_MODE_IS_DIRECTIONAL_LIGHT_ATTENUATED) != HAZE_MODE_IS_DIRECTIONAL_LIGHT_ATTENUATED) && isHazeAttenuateKeyLight) { - _hazeParametersBuffer.edit().hazeMode |= HAZE_MODE_IS_DIRECTIONAL_LIGHT_ATTENUATED; + if (((params.hazeMode & HAZE_MODE_IS_KEYLIGHT_ATTENUATED) == HAZE_MODE_IS_KEYLIGHT_ATTENUATED) && !isHazeAttenuateKeyLight) { + _hazeParametersBuffer.edit().hazeMode &= ~HAZE_MODE_IS_KEYLIGHT_ATTENUATED; + } else if (((params.hazeMode & HAZE_MODE_IS_KEYLIGHT_ATTENUATED) != HAZE_MODE_IS_KEYLIGHT_ATTENUATED) && isHazeAttenuateKeyLight) { + _hazeParametersBuffer.edit().hazeMode |= HAZE_MODE_IS_KEYLIGHT_ATTENUATED; } } @@ -124,11 +124,11 @@ void Haze::setHazeRangeFactor(const float hazeRangeFactor) { } } -void Haze::setHazeAltitudeFactor(const float hazeAltitudeFactor) { +void Haze::setHazeAltitudeFactor(const float hazeHeightFactor) { auto& params = _hazeParametersBuffer.get(); - if (params.hazeAltitudeFactor != hazeAltitudeFactor) { - _hazeParametersBuffer.edit().hazeAltitudeFactor = hazeAltitudeFactor; + if (params.hazeHeightFactor != hazeHeightFactor) { + _hazeParametersBuffer.edit().hazeHeightFactor = hazeHeightFactor; } } @@ -156,11 +156,11 @@ void Haze::setHazeBaseReference(const float hazeBaseReference) { } } -void Haze::setHazeBackgroundBlendValue(const float hazeBackgroundBlendValue) { +void Haze::setHazeBackgroundBlend(const float hazeBackgroundBlend) { auto& params = _hazeParametersBuffer.get(); - if (params.hazeBackgroundBlendValue != hazeBackgroundBlendValue) { - _hazeParametersBuffer.edit().hazeBackgroundBlendValue = hazeBackgroundBlendValue; + if (params.hazeBackgroundBlend != hazeBackgroundBlend) { + _hazeParametersBuffer.edit().hazeBackgroundBlend = hazeBackgroundBlend; } } diff --git a/libraries/model/src/model/Haze.h b/libraries/model/src/model/Haze.h index 2ffdd2333b..bed82c80f9 100644 --- a/libraries/model/src/model/Haze.h +++ b/libraries/model/src/model/Haze.h @@ -15,56 +15,11 @@ #include "Transform.h" #include "NumericalConstants.h" +#include "HazeInit.h" + namespace model { - const float LOG_P_005 = logf(0.05f); - const float LOG_P_05 = logf(0.5f); - - // Derivation (d is distance, b is haze coefficient, f is attenuation, solve for f = 0.05 - // f = exp(-d * b) - // ln(f) = -d * b - // b = -ln(f)/d - inline glm::vec3 convertHazeRangeToHazeRangeFactor(const glm::vec3 hazeRange_m) { - return glm::vec3( - -LOG_P_005 / hazeRange_m.x, - -LOG_P_005 / hazeRange_m.y, - -LOG_P_005 / hazeRange_m.z); - } - - // limit range and altitude to no less than 1.0 metres - inline float convertHazeRangeToHazeRangeFactor(const float hazeRange_m) { return -LOG_P_005 / glm::max(hazeRange_m, 1.0f); } - - inline float convertHazeAltitudeToHazeAltitudeFactor(const float hazeAltitude_m) { return -LOG_P_005 / glm::max(hazeAltitude_m, 1.0f); } - - // Derivation (s is the proportion of sun blend, a is the angle at which the blend is 50%, solve for m = 0.5 - // s = dot(lookAngle, sunAngle) = cos(a) - // m = pow(s, p) - // log(m) = p * log(s) - // p = log(m) / log(s) - inline float convertDirectionalLightAngleToPower(const float directionalLightAngle) { - return LOG_P_05 / logf(cosf(RADIANS_PER_DEGREE * directionalLightAngle)); - } - - const glm::vec3 initialHazeColor{ 0.5f, 0.6f, 0.7f }; - const float initialDirectionalLightAngle_degs{ 30.0f }; - - const glm::vec3 initialDirectionalLightColor{ 1.0f, 0.9f, 0.7f }; - const float initialHazeBaseReference{ 0.0f }; - // Haze range is defined here as the range the visibility is reduced by 95% // Haze altitude is defined here as the altitude (above 0) that the haze is reduced by 95% - const float initialHazeRange_m{ 150.0f }; - const float initialHazeAltitude_m{ 150.0f }; - - const float initialHazeKeyLightRange_m{ 150.0f }; - const float initialHazeKeyLightAltitude_m{ 150.0f }; - - const float initialHazeBackgroundBlendValue{ 0.0f }; - - const glm::vec3 initialColorModulationFactor{ - convertHazeRangeToHazeRangeFactor(initialHazeRange_m), - convertHazeRangeToHazeRangeFactor(initialHazeRange_m), - convertHazeRangeToHazeRangeFactor(initialHazeRange_m) - }; class Haze { public: @@ -73,9 +28,9 @@ namespace model { Haze(); void setHazeColor(const glm::vec3 hazeColor); - void setDirectionalLightBlend(const float directionalLightBlend); + void setHazeGlareBlend(const float hazeGlareBlend); - void setDirectionalLightColor(const glm::vec3 directionalLightColor); + void setHazeGlareColor(const glm::vec3 hazeGlareColor); void setHazeBaseReference(const float hazeBaseReference); void setHazeActive(const bool isHazeActive); @@ -90,7 +45,7 @@ namespace model { void setHazeKeyLightRangeFactor(const float hazeKeyLightRange); void setHazeKeyLightAltitudeFactor(const float hazeKeyLightAltitude); - void setHazeBackgroundBlendValue(const float hazeBackgroundBlendValue); + void setHazeBackgroundBlend(const float hazeBackgroundBlend); void setZoneTransform(const glm::mat4& zoneTransform); @@ -101,10 +56,10 @@ namespace model { public: // DO NOT CHANGE ORDER HERE WITHOUT UNDERSTANDING THE std140 LAYOUT glm::vec3 hazeColor{ initialHazeColor }; - float directionalLightBlend{ convertDirectionalLightAngleToPower(initialDirectionalLightAngle_degs) }; + float hazeGlareBlend{ convertGlareAngleToPower(initialGlareAngle_degs) }; - glm::vec3 directionalLightColor{ initialDirectionalLightColor }; - float hazeBaseReference{ initialHazeBaseReference }; + glm::vec3 hazeGlareColor{ initialHazeGlareColor }; + float hazeBaseReference{ initialHazeBaseReference_m }; glm::vec3 colorModulationFactor{ initialColorModulationFactor }; int hazeMode{ 0 }; // bit 0 - set to activate haze attenuation of fragment color @@ -115,11 +70,11 @@ namespace model { glm::mat4 zoneTransform; // Amount of background (skybox) to display, overriding the haze effect for the background - float hazeBackgroundBlendValue{ initialHazeBackgroundBlendValue }; + float hazeBackgroundBlend{ initialHazeBackgroundBlend }; // The haze attenuation exponents used by both fragment and directional light attenuation float hazeRangeFactor{ convertHazeRangeToHazeRangeFactor(initialHazeRange_m) }; - float hazeAltitudeFactor{ convertHazeAltitudeToHazeAltitudeFactor(initialHazeAltitude_m) }; + float hazeHeightFactor{ convertHazeAltitudeToHazeAltitudeFactor(initialHazeHeight_m) }; float hazeKeyLightRangeFactor{ convertHazeRangeToHazeRangeFactor(initialHazeKeyLightRange_m) }; float hazeKeyLightAltitudeFactor{ convertHazeAltitudeToHazeAltitudeFactor(initialHazeKeyLightAltitude_m) }; diff --git a/libraries/model/src/model/HazeInit.h b/libraries/model/src/model/HazeInit.h new file mode 100644 index 0000000000..218a79fc1d --- /dev/null +++ b/libraries/model/src/model/HazeInit.h @@ -0,0 +1,69 @@ +// +// MakeHaze.h +// libraries/model/src/model +// +// Created by Nissim Hadar on 10/26/2017. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +#ifndef hifi_model_HazeInit_h +#define hifi_model_HazeInit_h + +namespace model { + const float LOG_P_005 = logf(0.05f); + const float LOG_P_05 = logf(0.5f); + + // Derivation (d is distance, b is haze coefficient, f is attenuation, solve for f = 0.05 + // f = exp(-d * b) + // ln(f) = -d * b + // b = -ln(f)/d + inline glm::vec3 convertHazeRangeToHazeRangeFactor(const glm::vec3 hazeRange_m) { + return glm::vec3( + -LOG_P_005 / hazeRange_m.x, + -LOG_P_005 / hazeRange_m.y, + -LOG_P_005 / hazeRange_m.z); + } + + // limit range and altitude to no less than 1.0 metres + inline float convertHazeRangeToHazeRangeFactor(const float hazeRange_m) { return -LOG_P_005 / glm::max(hazeRange_m, 1.0f); } + + inline float convertHazeAltitudeToHazeAltitudeFactor(const float hazeHeight_m) { return -LOG_P_005 / glm::max(hazeHeight_m, 1.0f); } + + // Derivation (s is the proportion of sun blend, a is the angle at which the blend is 50%, solve for m = 0.5 + // s = dot(lookAngle, sunAngle) = cos(a) + // m = pow(s, p) + // log(m) = p * log(s) + // p = log(m) / log(s) + // limit to 0.1 degrees + inline float convertGlareAngleToPower(const float hazeGlareAngle) { + const float GLARE_ANGLE_LIMIT = 0.1f; + return LOG_P_05 / logf(cosf(RADIANS_PER_DEGREE * glm::max(GLARE_ANGLE_LIMIT, hazeGlareAngle))); + } + + const float initialHazeRange_m{ 1000.0f }; + const float initialHazeHeight_m{ 200.0f }; + + const float initialHazeKeyLightRange_m{ 1000.0f }; + const float initialHazeKeyLightAltitude_m{ 200.0f }; + + const float initialHazeBackgroundBlend{ 0.0f }; + + const glm::vec3 initialColorModulationFactor{ + convertHazeRangeToHazeRangeFactor(initialHazeRange_m), + convertHazeRangeToHazeRangeFactor(initialHazeRange_m), + convertHazeRangeToHazeRangeFactor(initialHazeRange_m) + }; + + const glm::vec3 initialHazeColor{ 0.5f, 0.6f, 0.7f }; // Bluish + const xColor initialHazeColorXcolor{ 128, 154, 179 }; + + const float initialGlareAngle_degs{ 20.0f }; + + const glm::vec3 initialHazeGlareColor{ 1.0f, 0.9f, 0.7f }; + const xColor initialHazeGlareColorXcolor{ 255, 229, 179 }; + + const float initialHazeBaseReference_m{ 0.0f }; +} +#endif // hifi_model_HazeInit_h diff --git a/libraries/render-utils/src/DeferredGlobalLight.slh b/libraries/render-utils/src/DeferredGlobalLight.slh index cc20f6335e..f70daf1e77 100644 --- a/libraries/render-utils/src/DeferredGlobalLight.slh +++ b/libraries/render-utils/src/DeferredGlobalLight.slh @@ -134,7 +134,7 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu color += directionalSpecular; // Attenuate the light if haze effect selected - if ((hazeParams.hazeMode & HAZE_MODE_IS_DIRECTIONAL_LIGHT_ATTENUATED) == HAZE_MODE_IS_DIRECTIONAL_LIGHT_ATTENUATED) { + if ((hazeParams.hazeMode & HAZE_MODE_IS_KEYLIGHT_ATTENUATED) == HAZE_MODE_IS_KEYLIGHT_ATTENUATED) { // Directional light attenuation is simulated by assuming the light source is at a fixed height above the // fragment. This height is where the haze density is reduced by 95% from the haze at the fragment's height // @@ -147,8 +147,8 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu // Height at which haze density is reduced by 95% (default set to 2000.0 for safety ,this should never happen) float height_95p = 2000.0; - if (hazeParams.hazeAltitudeFactorKeyLight > 0.0f) { - height_95p = -log(0.05) / hazeParams.hazeAltitudeFactorKeyLight; + if (hazeParams.hazeKeyLightAltitudeFactor > 0.0f) { + height_95p = -log(0.05) / hazeParams.hazeKeyLightAltitudeFactor; } // Note that the sine will always be positive @@ -168,8 +168,8 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu // Integration is from the fragment towards the light source // Note that the haze base reference affects only the haze density as function of altitude float hazeDensityDistribution = - hazeParams.hazeRangeFactorKeyLight * - exp(-hazeParams.hazeAltitudeFactorKeyLight * (worldFragPos.y - hazeParams.hazeBaseReference)); + hazeParams.hazeKeyLightRangeFactor * + exp(-hazeParams.hazeKeyLightAltitudeFactor * (worldFragPos.y - hazeParams.hazeBaseReference)); float hazeIntegral = hazeDensityDistribution * distance; diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index b6a91888a1..e6a33a9911 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -498,7 +498,7 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext, auto lightStage = renderContext->_scene->getStage(); assert(lightStage); assert(lightStage->getNumLights() > 0); - auto lightAndShadow = lightStage->getCurrentKeyLightAndShadow(); + auto lightAndShadow = lightStage->getLightAndShadow(0); const auto& globalShadow = lightAndShadow.second; // Bind the shadow buffer @@ -509,7 +509,7 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext, auto& program = deferredLightingEffect->_directionalSkyboxLight; LightLocationsPtr locations = deferredLightingEffect->_directionalSkyboxLightLocations; - auto keyLight = lightAndShadow.first; + auto keyLight = lightStage->getLight(0); // Setup the global directional pass pipeline { diff --git a/libraries/render-utils/src/DrawHaze.cpp b/libraries/render-utils/src/DrawHaze.cpp index bf254ce80e..071db8cf25 100644 --- a/libraries/render-utils/src/DrawHaze.cpp +++ b/libraries/render-utils/src/DrawHaze.cpp @@ -33,24 +33,24 @@ void HazeConfig::setHazeColorB(const float value) { hazeColorB = value; } -void HazeConfig::setDirectionalLightAngle_degs(const float value) { - hazeDirectionalLightAngle_degs = value; +void HazeConfig::setHazeGlareAngle_degs(const float value) { + hazeGlareAngle_degs = value; } -void HazeConfig::setDirectionalLightColorR(const float value) { - hazeDirectionalLightColorR = value; +void HazeConfig::setHazeGlareColorR(const float value) { + hazeGlareColorR = value; } -void HazeConfig::setDirectionalLightColorG(const float value) { - hazeDirectionalLightColorG = value; +void HazeConfig::setHazeGlareColorG(const float value) { + hazeGlareColorG = value; } -void HazeConfig::setDirectionalLightColorB(const float value) { - hazeDirectionalLightColorB = value; +void HazeConfig::setHazeGlareColorB(const float value) { + hazeGlareColorB = value; } void HazeConfig::setHazeBaseReference(const float value) { - hazeBaseReference = value; + hazeBaseReference_m = value; } void HazeConfig::setHazeActive(const bool active) { @@ -78,7 +78,7 @@ void HazeConfig::setHazeRange_m(const float value) { } void HazeConfig::setHazeAltitude_m(const float value) { - hazeAltitude_m = value; + hazeHeight_m = value; } void HazeConfig::setHazeKeyLightRange_m(const float value) { @@ -89,8 +89,8 @@ void HazeConfig::setHazeKeyLightAltitude_m(const float value) { hazeKeyLightAltitude_m = value; } -void HazeConfig::setHazeBackgroundBlendValue(const float value) { - hazeBackgroundBlendValue = value; +void HazeConfig::setHazeBackgroundBlend(const float value) { + hazeBackgroundBlend = value; } MakeHaze::MakeHaze() { @@ -99,10 +99,10 @@ MakeHaze::MakeHaze() { void MakeHaze::configure(const Config& config) { _haze->setHazeColor(glm::vec3(config.hazeColorR, config.hazeColorG, config.hazeColorB)); - _haze->setDirectionalLightBlend(model::convertDirectionalLightAngleToPower(config.hazeDirectionalLightAngle_degs)); + _haze->setHazeGlareBlend(model::convertGlareAngleToPower(config.hazeGlareAngle_degs)); - _haze->setDirectionalLightColor(glm::vec3(config.hazeDirectionalLightColorR, config.hazeDirectionalLightColorG, config.hazeDirectionalLightColorB)); - _haze->setHazeBaseReference(config.hazeBaseReference); + _haze->setHazeGlareColor(glm::vec3(config.hazeGlareColorR, config.hazeGlareColorG, config.hazeGlareColorB)); + _haze->setHazeBaseReference(config.hazeBaseReference_m); _haze->setHazeActive(config.isHazeActive); _haze->setAltitudeBased(config.isAltitudeBased); @@ -111,12 +111,12 @@ void MakeHaze::configure(const Config& config) { _haze->setHazeEnableGlare(config.isHazeEnableGlare); _haze->setHazeRangeFactor(model::convertHazeRangeToHazeRangeFactor(config.hazeRange_m)); - _haze->setHazeAltitudeFactor(model::convertHazeAltitudeToHazeAltitudeFactor(config.hazeAltitude_m)); + _haze->setHazeAltitudeFactor(model::convertHazeAltitudeToHazeAltitudeFactor(config.hazeHeight_m)); _haze->setHazeKeyLightRangeFactor(model::convertHazeRangeToHazeRangeFactor(config.hazeKeyLightRange_m)); _haze->setHazeKeyLightAltitudeFactor(model::convertHazeAltitudeToHazeAltitudeFactor(config.hazeKeyLightAltitude_m)); - _haze->setHazeBackgroundBlendValue(config.hazeBackgroundBlendValue); + _haze->setHazeBackgroundBlend(config.hazeBackgroundBlend); } void MakeHaze::run(const render::RenderContextPointer& renderContext, model::HazePointer& haze) { diff --git a/libraries/render-utils/src/DrawHaze.h b/libraries/render-utils/src/DrawHaze.h index 4a7b2135bd..e7a3f2c636 100644 --- a/libraries/render-utils/src/DrawHaze.h +++ b/libraries/render-utils/src/DrawHaze.h @@ -22,7 +22,7 @@ #include "SurfaceGeometryPass.h" -#include "model/Haze.h" +#include using LinearDepthFramebufferPointer = std::shared_ptr; @@ -32,12 +32,12 @@ class MakeHazeConfig : public render::Job::Config { Q_PROPERTY(float hazeColorR MEMBER hazeColorR WRITE setHazeColorR NOTIFY dirty); Q_PROPERTY(float hazeColorG MEMBER hazeColorG WRITE setHazeColorG NOTIFY dirty); Q_PROPERTY(float hazeColorB MEMBER hazeColorB WRITE setHazeColorB NOTIFY dirty); - Q_PROPERTY(float hazeDirectionalLightAngle_degs MEMBER hazeDirectionalLightAngle_degs WRITE setDirectionalLightAngle_degs NOTIFY dirty); + Q_PROPERTY(float hazeGlareAngle_degs MEMBER hazeGlareAngle_degs WRITE setHazeGlareAngle_degs NOTIFY dirty); - Q_PROPERTY(float hazeDirectionalLightColorR MEMBER hazeDirectionalLightColorR WRITE setDirectionalLightColorR NOTIFY dirty); - Q_PROPERTY(float hazeDirectionalLightColorG MEMBER hazeDirectionalLightColorG WRITE setDirectionalLightColorG NOTIFY dirty); - Q_PROPERTY(float hazeDirectionalLightColorB MEMBER hazeDirectionalLightColorB WRITE setDirectionalLightColorB NOTIFY dirty); - Q_PROPERTY(float hazeBaseReference MEMBER hazeBaseReference WRITE setHazeBaseReference NOTIFY dirty); + Q_PROPERTY(float hazeGlareColorR MEMBER hazeGlareColorR WRITE setHazeGlareColorR NOTIFY dirty); + Q_PROPERTY(float hazeGlareColorG MEMBER hazeGlareColorG WRITE setHazeGlareColorG NOTIFY dirty); + Q_PROPERTY(float hazeGlareColorB MEMBER hazeGlareColorB WRITE setHazeGlareColorB NOTIFY dirty); + Q_PROPERTY(float hazeBaseReference_m MEMBER hazeBaseReference_m WRITE setHazeBaseReference NOTIFY dirty); Q_PROPERTY(bool isHazeActive MEMBER isHazeActive WRITE setHazeActive NOTIFY dirty); Q_PROPERTY(bool isAltitudeBased MEMBER isAltitudeBased WRITE setAltitudeBased NOTIFY dirty); @@ -46,12 +46,12 @@ class MakeHazeConfig : public render::Job::Config { Q_PROPERTY(bool isHazeEnableGlare MEMBER isHazeEnableGlare WRITE setHazeEnableGlare NOTIFY dirty); Q_PROPERTY(float hazeRange_m MEMBER hazeRange_m WRITE setHazeRange_m NOTIFY dirty); - Q_PROPERTY(float hazeAltitude_m MEMBER hazeAltitude_m WRITE setHazeAltitude_m NOTIFY dirty); + Q_PROPERTY(float hazeHeight_m MEMBER hazeHeight_m WRITE setHazeAltitude_m NOTIFY dirty); Q_PROPERTY(float hazeKeyLightRange_m MEMBER hazeKeyLightRange_m WRITE setHazeKeyLightRange_m NOTIFY dirty); Q_PROPERTY(float hazeKeyLightAltitude_m MEMBER hazeKeyLightAltitude_m WRITE setHazeKeyLightAltitude_m NOTIFY dirty); - Q_PROPERTY(float hazeBackgroundBlendValue MEMBER hazeBackgroundBlendValue WRITE setHazeBackgroundBlendValue NOTIFY dirty); + Q_PROPERTY(float hazeBackgroundBlend MEMBER hazeBackgroundBlend WRITE setHazeBackgroundBlend NOTIFY dirty); public: MakeHazeConfig() : render::Job::Config() {} @@ -59,12 +59,12 @@ public: float hazeColorR{ model::initialHazeColor.r }; float hazeColorG{ model::initialHazeColor.g }; float hazeColorB{ model::initialHazeColor.b }; - float hazeDirectionalLightAngle_degs{ model::initialDirectionalLightAngle_degs }; + float hazeGlareAngle_degs{ model::initialGlareAngle_degs }; - float hazeDirectionalLightColorR{ model::initialDirectionalLightColor.r }; - float hazeDirectionalLightColorG{ model::initialDirectionalLightColor.g }; - float hazeDirectionalLightColorB{ model::initialDirectionalLightColor.b }; - float hazeBaseReference{ model::initialHazeBaseReference }; + float hazeGlareColorR{ model::initialHazeGlareColor.r }; + float hazeGlareColorG{ model::initialHazeGlareColor.g }; + float hazeGlareColorB{ model::initialHazeGlareColor.b }; + float hazeBaseReference_m{ model::initialHazeBaseReference_m }; bool isHazeActive{ false }; bool isAltitudeBased{ false }; @@ -73,23 +73,23 @@ public: bool isHazeEnableGlare{ false }; float hazeRange_m{ model::initialHazeRange_m }; - float hazeAltitude_m{ model::initialHazeAltitude_m }; + float hazeHeight_m{ model::initialHazeHeight_m }; float hazeKeyLightRange_m{ model::initialHazeKeyLightRange_m }; float hazeKeyLightAltitude_m{ model::initialHazeKeyLightAltitude_m }; - float hazeBackgroundBlendValue{ model::initialHazeBackgroundBlendValue }; + float hazeBackgroundBlend{ model::initialHazeBackgroundBlend }; public slots: void setHazeColorR(const float value) { hazeColorR = value; emit dirty(); } void setHazeColorG(const float value) { hazeColorG = value; emit dirty(); } void setHazeColorB(const float value) { hazeColorB = value; emit dirty(); } - void setDirectionalLightAngle_degs(const float value) { hazeDirectionalLightAngle_degs = value; emit dirty(); } + void setHazeGlareAngle_degs(const float value) { hazeGlareAngle_degs = value; emit dirty(); } - void setDirectionalLightColorR(const float value) { hazeDirectionalLightColorR = value; emit dirty(); } - void setDirectionalLightColorG(const float value) { hazeDirectionalLightColorG = value; emit dirty(); } - void setDirectionalLightColorB(const float value) { hazeDirectionalLightColorB = value; emit dirty(); } - void setHazeBaseReference(const float value) { hazeBaseReference = value; ; emit dirty(); } + void setHazeGlareColorR(const float value) { hazeGlareColorR = value; emit dirty(); } + void setHazeGlareColorG(const float value) { hazeGlareColorG = value; emit dirty(); } + void setHazeGlareColorB(const float value) { hazeGlareColorB = value; emit dirty(); } + void setHazeBaseReference(const float value) { hazeBaseReference_m = value; ; emit dirty(); } void setHazeActive(const bool active) { isHazeActive = active; emit dirty(); } void setAltitudeBased(const bool active) { isAltitudeBased = active; emit dirty(); } @@ -98,12 +98,12 @@ public slots: void setHazeEnableGlare(const bool active) { isHazeEnableGlare = active; emit dirty(); } void setHazeRange_m(const float value) { hazeRange_m = value; emit dirty(); } - void setHazeAltitude_m(const float value) { hazeAltitude_m = value; emit dirty(); } + void setHazeAltitude_m(const float value) { hazeHeight_m = value; emit dirty(); } void setHazeKeyLightRange_m(const float value) { hazeKeyLightRange_m = value; emit dirty(); } void setHazeKeyLightAltitude_m(const float value) { hazeKeyLightAltitude_m = value; emit dirty(); } - void setHazeBackgroundBlendValue(const float value) { hazeBackgroundBlendValue = value; ; emit dirty(); } + void setHazeBackgroundBlend(const float value) { hazeBackgroundBlend = value; ; emit dirty(); } signals: void dirty(); @@ -131,12 +131,12 @@ public: float hazeColorR{ model::initialHazeColor.r }; float hazeColorG{ model::initialHazeColor.g }; float hazeColorB{ model::initialHazeColor.b }; - float hazeDirectionalLightAngle_degs{ model::initialDirectionalLightAngle_degs }; + float hazeGlareAngle_degs{ model::initialGlareAngle_degs }; - float hazeDirectionalLightColorR{ model::initialDirectionalLightColor.r }; - float hazeDirectionalLightColorG{ model::initialDirectionalLightColor.g }; - float hazeDirectionalLightColorB{ model::initialDirectionalLightColor.b }; - float hazeBaseReference{ model::initialHazeBaseReference }; + float hazeGlareColorR{ model::initialHazeGlareColor.r }; + float hazeGlareColorG{ model::initialHazeGlareColor.g }; + float hazeGlareColorB{ model::initialHazeGlareColor.b }; + float hazeBaseReference_m{ model::initialHazeBaseReference_m }; bool isHazeActive{ false }; // Setting this to true will set haze to on bool isAltitudeBased{ false }; @@ -145,22 +145,22 @@ public: bool isHazeEnableGlare{ false }; float hazeRange_m{ model::initialHazeRange_m }; - float hazeAltitude_m{ model::initialHazeAltitude_m }; + float hazeHeight_m{ model::initialHazeHeight_m }; float hazeKeyLightRange_m{ model::initialHazeKeyLightRange_m }; float hazeKeyLightAltitude_m{ model::initialHazeKeyLightAltitude_m }; - float hazeBackgroundBlendValue{ model::initialHazeBackgroundBlendValue }; + float hazeBackgroundBlend{ model::initialHazeBackgroundBlend }; // methods void setHazeColorR(const float value); void setHazeColorG(const float value); void setHazeColorB(const float value); - void setDirectionalLightAngle_degs(const float value); + void setHazeGlareAngle_degs(const float value); - void setDirectionalLightColorR(const float value); - void setDirectionalLightColorG(const float value); - void setDirectionalLightColorB(const float value); + void setHazeGlareColorR(const float value); + void setHazeGlareColorG(const float value); + void setHazeGlareColorB(const float value); void setHazeBaseReference(const float value); void setHazeActive(const bool active); @@ -175,7 +175,7 @@ public: void setHazeKeyLightRange_m(const float value); void setHazeKeyLightAltitude_m(const float value); - void setHazeBackgroundBlendValue(const float value); + void setHazeBackgroundBlend(const float value); }; class DrawHaze { diff --git a/libraries/render-utils/src/Haze.slf b/libraries/render-utils/src/Haze.slf index 77c820e093..b366e6d639 100644 --- a/libraries/render-utils/src/Haze.slf +++ b/libraries/render-utils/src/Haze.slf @@ -60,15 +60,15 @@ void main(void) { Light light = getLight(); vec3 lightDirection = getLightDirection(light); - float directionalLightComponent = max(0.0, dot(eyeFragDir, -lightDirection)); - float power = min(1.0, pow(directionalLightComponent, hazeParams.directionalLightBlend)); + float glareComponent = max(0.0, dot(eyeFragDir, -lightDirection)); + float power = min(1.0, pow(glareComponent, hazeParams.hazeGlareBlend)); - vec4 directionalLightColor = vec4(hazeParams.directionalLightColor, 1.0); + vec4 glareColor = vec4(hazeParams.hazeGlareColor, 1.0); - // Use the haze colour for the belnd-out colour, if blend is not enabled + // Use the haze colour for the glare colour, if blend is not enabled vec4 blendedHazeColor; if ((hazeParams.hazeMode & HAZE_MODE_IS_ENABLE_LIGHT_BLEND) == HAZE_MODE_IS_ENABLE_LIGHT_BLEND) { - blendedHazeColor = mix(hazeColor, directionalLightColor, power); + blendedHazeColor = mix(hazeColor, glareColor, power); } else { blendedHazeColor = hazeColor; } @@ -86,14 +86,14 @@ void main(void) { // Note that the haze base reference affects only the haze density as function of altitude vec3 hazeDensityDistribution = hazeParams.colorModulationFactor * - exp(-hazeParams.hazeAltitudeFactor * (worldEyePos.y - hazeParams.hazeBaseReference)); + exp(-hazeParams.hazeHeightFactor * (worldEyePos.y - hazeParams.hazeBaseReference)); vec3 hazeIntegral = hazeDensityDistribution * distance; const float slopeThreshold = 0.01; float deltaHeight = worldFragPos.y - worldEyePos.y; if (abs(deltaHeight) > slopeThreshold) { - float t = hazeParams.hazeAltitudeFactor * deltaHeight; + float t = hazeParams.hazeHeightFactor * deltaHeight; hazeIntegral *= (1.0 - exp (-t)) / t; } @@ -117,14 +117,14 @@ void main(void) { // Note that the haze base reference affects only the haze density as function of altitude float hazeDensityDistribution = hazeParams.hazeRangeFactor * - exp(-hazeParams.hazeAltitudeFactor * (worldEyePos.y - hazeParams.hazeBaseReference)); + exp(-hazeParams.hazeHeightFactor * (worldEyePos.y - hazeParams.hazeBaseReference)); float hazeIntegral = hazeDensityDistribution * distance; const float slopeThreshold = 0.01; float deltaHeight = worldFragPos.y - worldEyePos.y; if (abs(deltaHeight) > slopeThreshold) { - float t = hazeParams.hazeAltitudeFactor * deltaHeight; + float t = hazeParams.hazeHeightFactor * deltaHeight; // Protect from wild values if (abs(t) > 0.0000001) { hazeIntegral *= (1.0 - exp (-t)) / t; @@ -140,7 +140,7 @@ void main(void) { // Mix with background at far range const float BLEND_DISTANCE = 27000.0; if (distance > BLEND_DISTANCE) { - outFragColor = mix(potentialFragColor, fragColor, hazeParams.backgroundBlendValue); + outFragColor = mix(potentialFragColor, fragColor, hazeParams.backgroundBlend); } else { outFragColor = potentialFragColor; } diff --git a/libraries/render-utils/src/Haze.slh b/libraries/render-utils/src/Haze.slh index 614431dce7..de7f0ac246 100644 --- a/libraries/render-utils/src/Haze.slh +++ b/libraries/render-utils/src/Haze.slh @@ -12,28 +12,28 @@ const int HAZE_MODE_IS_ACTIVE = 1 << 0; const int HAZE_MODE_IS_ALTITUDE_BASED = 1 << 1; -const int HAZE_MODE_IS_DIRECTIONAL_LIGHT_ATTENUATED = 1 << 2; +const int HAZE_MODE_IS_KEYLIGHT_ATTENUATED = 1 << 2; const int HAZE_MODE_IS_MODULATE_COLOR = 1 << 3; const int HAZE_MODE_IS_ENABLE_LIGHT_BLEND = 1 << 4; struct HazeParams { vec3 hazeColor; - float directionalLightBlend; + float hazeGlareBlend; - vec3 directionalLightColor; + vec3 hazeGlareColor; float hazeBaseReference; vec3 colorModulationFactor; int hazeMode; mat4 zoneTransform; - float backgroundBlendValue; + float backgroundBlend; float hazeRangeFactor; - float hazeAltitudeFactor; + float hazeHeightFactor; - float hazeRangeFactorKeyLight; - float hazeAltitudeFactorKeyLight; + float hazeKeyLightRangeFactor; + float hazeKeyLightAltitudeFactor; }; layout(std140) uniform hazeBuffer { diff --git a/libraries/render-utils/src/HazeStage.cpp b/libraries/render-utils/src/HazeStage.cpp index aa7a7f554c..6a6104a1df 100644 --- a/libraries/render-utils/src/HazeStage.cpp +++ b/libraries/render-utils/src/HazeStage.cpp @@ -21,10 +21,10 @@ FetchHazeStage::FetchHazeStage() { void FetchHazeStage::configure(const Config& config) { _haze->setHazeColor(glm::vec3(config.hazeColorR, config.hazeColorG, config.hazeColorB)); - _haze->setDirectionalLightBlend(model::convertDirectionalLightAngleToPower(config.hazeDirectionalLightAngle_degs)); + _haze->setHazeGlareBlend(model::convertGlareAngleToPower(config.hazeGlareAngle_degs)); - _haze->setDirectionalLightColor(glm::vec3(config.hazeDirectionalLightColorR, config.hazeDirectionalLightColorG, config.hazeDirectionalLightColorB)); - _haze->setHazeBaseReference(config.hazeBaseReference); + _haze->setHazeGlareColor(glm::vec3(config.hazeGlareColorR, config.hazeGlareColorG, config.hazeGlareColorB)); + _haze->setHazeBaseReference(config.hazeBaseReference_m); _haze->setHazeActive(config.isHazeActive); _haze->setAltitudeBased(config.isAltitudeBased); @@ -33,12 +33,12 @@ void FetchHazeStage::configure(const Config& config) { _haze->setHazeEnableGlare(config.isHazeEnableGlare); _haze->setHazeRangeFactor(model::convertHazeRangeToHazeRangeFactor(config.hazeRange_m)); - _haze->setHazeAltitudeFactor(model::convertHazeAltitudeToHazeAltitudeFactor(config.hazeAltitude_m)); + _haze->setHazeAltitudeFactor(model::convertHazeAltitudeToHazeAltitudeFactor(config.hazeHeight_m)); _haze->setHazeKeyLightRangeFactor(model::convertHazeRangeToHazeRangeFactor(config.hazeKeyLightRange_m)); _haze->setHazeKeyLightAltitudeFactor(model::convertHazeAltitudeToHazeAltitudeFactor(config.hazeKeyLightAltitude_m)); - _haze->setHazeBackgroundBlendValue(config.hazeBackgroundBlendValue); + _haze->setHazeBackgroundBlend(config.hazeBackgroundBlend); } HazeStage::Index HazeStage::findHaze(const HazePointer& haze) const { diff --git a/libraries/render-utils/src/HazeStage.h b/libraries/render-utils/src/HazeStage.h index 7cc0c659b0..e2d09f3011 100644 --- a/libraries/render-utils/src/HazeStage.h +++ b/libraries/render-utils/src/HazeStage.h @@ -19,7 +19,7 @@ #include #include -#include "model/Haze.h" +#include // Haze stage to set up haze-related rendering tasks class HazeStage : public render::Stage { @@ -86,12 +86,12 @@ class FetchHazeConfig : public render::Job::Config { Q_PROPERTY(float hazeColorR MEMBER hazeColorR WRITE setHazeColorR NOTIFY dirty); Q_PROPERTY(float hazeColorG MEMBER hazeColorG WRITE setHazeColorG NOTIFY dirty); Q_PROPERTY(float hazeColorB MEMBER hazeColorB WRITE setHazeColorB NOTIFY dirty); - Q_PROPERTY(float hazeDirectionalLightAngle_degs MEMBER hazeDirectionalLightAngle_degs WRITE setDirectionalLightAngle_degs NOTIFY dirty); + Q_PROPERTY(float hazeGlareAngle_degs MEMBER hazeGlareAngle_degs WRITE setHazeGlareAngle_degs NOTIFY dirty); - Q_PROPERTY(float hazeDirectionalLightColorR MEMBER hazeDirectionalLightColorR WRITE setDirectionalLightColorR NOTIFY dirty); - Q_PROPERTY(float hazeDirectionalLightColorG MEMBER hazeDirectionalLightColorG WRITE setDirectionalLightColorG NOTIFY dirty); - Q_PROPERTY(float hazeDirectionalLightColorB MEMBER hazeDirectionalLightColorB WRITE setDirectionalLightColorB NOTIFY dirty); - Q_PROPERTY(float hazeBaseReference MEMBER hazeBaseReference WRITE setHazeBaseReference NOTIFY dirty); + Q_PROPERTY(float hazeGlareColorR MEMBER hazeGlareColorR WRITE setHazeGlareColorR NOTIFY dirty); + Q_PROPERTY(float hazeGlareColorG MEMBER hazeGlareColorG WRITE setHazeGlareColorG NOTIFY dirty); + Q_PROPERTY(float hazeGlareColorB MEMBER hazeGlareColorB WRITE setHazeGlareColorB NOTIFY dirty); + Q_PROPERTY(float hazeBaseReference_m MEMBER hazeBaseReference_m WRITE setHazeBaseReference NOTIFY dirty); Q_PROPERTY(bool isHazeActive MEMBER isHazeActive WRITE setHazeActive NOTIFY dirty); Q_PROPERTY(bool isAltitudeBased MEMBER isAltitudeBased WRITE setAltitudeBased NOTIFY dirty); @@ -100,12 +100,12 @@ class FetchHazeConfig : public render::Job::Config { Q_PROPERTY(bool isHazeEnableGlare MEMBER isHazeEnableGlare WRITE setHazeEnableGlare NOTIFY dirty); Q_PROPERTY(float hazeRange_m MEMBER hazeRange_m WRITE setHazeRange_m NOTIFY dirty); - Q_PROPERTY(float hazeAltitude_m MEMBER hazeAltitude_m WRITE setHazeAltitude_m NOTIFY dirty); + Q_PROPERTY(float hazeHeight_m MEMBER hazeHeight_m WRITE setHazeAltitude_m NOTIFY dirty); Q_PROPERTY(float hazeKeyLightRange_m MEMBER hazeKeyLightRange_m WRITE setHazeKeyLightRange_m NOTIFY dirty); Q_PROPERTY(float hazeKeyLightAltitude_m MEMBER hazeKeyLightAltitude_m WRITE setHazeKeyLightAltitude_m NOTIFY dirty); - Q_PROPERTY(float hazeBackgroundBlendValue MEMBER hazeBackgroundBlendValue WRITE setHazeBackgroundBlendValue NOTIFY dirty); + Q_PROPERTY(float hazeBackgroundBlend MEMBER hazeBackgroundBlend WRITE setHazeBackgroundBlend NOTIFY dirty); public: FetchHazeConfig() : render::Job::Config() {} @@ -113,12 +113,12 @@ public: float hazeColorR{ model::initialHazeColor.r }; float hazeColorG{ model::initialHazeColor.g }; float hazeColorB{ model::initialHazeColor.b }; - float hazeDirectionalLightAngle_degs{ model::initialDirectionalLightAngle_degs }; + float hazeGlareAngle_degs{ model::initialGlareAngle_degs }; - float hazeDirectionalLightColorR{ model::initialDirectionalLightColor.r }; - float hazeDirectionalLightColorG{ model::initialDirectionalLightColor.g }; - float hazeDirectionalLightColorB{ model::initialDirectionalLightColor.b }; - float hazeBaseReference{ model::initialHazeBaseReference }; + float hazeGlareColorR{ model::initialHazeGlareColor.r }; + float hazeGlareColorG{ model::initialHazeGlareColor.g }; + float hazeGlareColorB{ model::initialHazeGlareColor.b }; + float hazeBaseReference_m{ model::initialHazeBaseReference_m }; bool isHazeActive{ false }; bool isAltitudeBased{ false }; @@ -127,23 +127,23 @@ public: bool isHazeEnableGlare{ false }; float hazeRange_m{ model::initialHazeRange_m }; - float hazeAltitude_m{ model::initialHazeAltitude_m }; + float hazeHeight_m{ model::initialHazeHeight_m }; float hazeKeyLightRange_m{ model::initialHazeKeyLightRange_m }; float hazeKeyLightAltitude_m{ model::initialHazeKeyLightAltitude_m }; - float hazeBackgroundBlendValue{ model::initialHazeBackgroundBlendValue }; + float hazeBackgroundBlend{ model::initialHazeBackgroundBlend }; public slots: void setHazeColorR(const float value) { hazeColorR = value; emit dirty(); } void setHazeColorG(const float value) { hazeColorG = value; emit dirty(); } void setHazeColorB(const float value) { hazeColorB = value; emit dirty(); } - void setDirectionalLightAngle_degs(const float value) { hazeDirectionalLightAngle_degs = value; emit dirty(); } + void setHazeGlareAngle_degs(const float value) { hazeGlareAngle_degs = value; emit dirty(); } - void setDirectionalLightColorR(const float value) { hazeDirectionalLightColorR = value; emit dirty(); } - void setDirectionalLightColorG(const float value) { hazeDirectionalLightColorG = value; emit dirty(); } - void setDirectionalLightColorB(const float value) { hazeDirectionalLightColorB = value; emit dirty(); } - void setHazeBaseReference(const float value) { hazeBaseReference = value; ; emit dirty(); } + void setHazeGlareColorR(const float value) { hazeGlareColorR = value; emit dirty(); } + void setHazeGlareColorG(const float value) { hazeGlareColorG = value; emit dirty(); } + void setHazeGlareColorB(const float value) { hazeGlareColorB = value; emit dirty(); } + void setHazeBaseReference(const float value) { hazeBaseReference_m = value; ; emit dirty(); } void setHazeActive(const bool active) { isHazeActive = active; emit dirty(); } void setAltitudeBased(const bool active) { isAltitudeBased = active; emit dirty(); } @@ -152,12 +152,12 @@ public slots: void setHazeEnableGlare(const bool active) { isHazeEnableGlare = active; emit dirty(); } void setHazeRange_m(const float value) { hazeRange_m = value; emit dirty(); } - void setHazeAltitude_m(const float value) { hazeAltitude_m = value; emit dirty(); } + void setHazeAltitude_m(const float value) { hazeHeight_m = value; emit dirty(); } void setHazeKeyLightRange_m(const float value) { hazeKeyLightRange_m = value; emit dirty(); } void setHazeKeyLightAltitude_m(const float value) { hazeKeyLightAltitude_m = value; emit dirty(); } - void setHazeBackgroundBlendValue(const float value) { hazeBackgroundBlendValue = value; ; emit dirty(); } + void setHazeBackgroundBlend(const float value) { hazeBackgroundBlend = value; ; emit dirty(); } signals: void dirty(); diff --git a/scripts/system/html/entityProperties.html b/scripts/system/html/entityProperties.html index 2d5dd35e66..f898eb3b9a 100644 --- a/scripts/system/html/entityProperties.html +++ b/scripts/system/html/entityProperties.html @@ -570,14 +570,14 @@
-
+
Haze Color
-
+
-
+
-
+
@@ -586,14 +586,14 @@
-
+
Glare Color
-
+
-
+
-
+
diff --git a/scripts/system/html/js/entityProperties.js b/scripts/system/html/js/entityProperties.js index a015eed714..0463ac4172 100644 --- a/scripts/system/html/js/entityProperties.js +++ b/scripts/system/html/js/entityProperties.js @@ -678,14 +678,14 @@ function loaded() { var elZoneHazeModeEnabled = document.getElementById("property-zone-haze-mode-enabled"); var elZoneHazeRange = document.getElementById("property-zone-haze-range"); - var elZoneHazeColor = document.getElementById("property-zone-haze-blend-in-color"); - var elZoneHazeColorRed = document.getElementById("property-zone-haze-blend-in-color-red"); - var elZoneHazeColorGreen = document.getElementById("property-zone-haze-blend-in-color-green"); - var elZoneHazeColorBlue = document.getElementById("property-zone-haze-blend-in-color-blue"); - var elZoneHazeGlareColor = document.getElementById("property-zone-haze-blend-out-color"); - var elZoneHazeGlareColorRed = document.getElementById("property-zone-haze-blend-out-color-red"); - var elZoneHazeGlareColorGreen = document.getElementById("property-zone-haze-blend-out-color-green"); - var elZoneHazeGlareColorBlue = document.getElementById("property-zone-haze-blend-out-color-blue"); + var elZoneHazeColor = document.getElementById("property-zone-haze-color"); + var elZoneHazeColorRed = document.getElementById("property-zone-haze-color-red"); + var elZoneHazeColorGreen = document.getElementById("property-zone-haze-color-green"); + var elZoneHazeColorBlue = document.getElementById("property-zone-haze-color-blue"); + var elZoneHazeGlareColor = document.getElementById("property-zone-haze-glare-color"); + var elZoneHazeGlareColorRed = document.getElementById("property-zone-haze-glare-color-red"); + var elZoneHazeGlareColorGreen = document.getElementById("property-zone-haze-glare-color-green"); + var elZoneHazeGlareColorBlue = document.getElementById("property-zone-haze-glare-color-blue"); var elZoneHazeEnableGlare = document.getElementById("property-zone-haze-enable-light-blend"); var elZonehazeGlareAngle = document.getElementById("property-zone-haze-blend-angle"); @@ -1474,15 +1474,15 @@ function loaded() { elZoneHazeRange.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('haze', 'hazeRange')); - colorPickers.push($('#property-zone-haze-blend-in-color').colpick({ + colorPickers.push($('#property-zone-haze-color').colpick({ colorScheme: 'dark', layout: 'hex', color: '000000', onShow: function(colpick) { - $('#property-zone-haze-blend-in-color').attr('active', 'true'); + $('#property-zone-haze-color').attr('active', 'true'); }, onHide: function(colpick) { - $('#property-zone-haze-blend-in-color').attr('active', 'false'); + $('#property-zone-haze-color').attr('active', 'false'); }, onSubmit: function(hsb, hex, rgb, el) { $(el).css('background-color', '#' + hex); @@ -1499,15 +1499,15 @@ function loaded() { elZoneHazeColorGreen.addEventListener('change', zoneHazeColorChangeFunction); elZoneHazeColorBlue.addEventListener('change', zoneHazeColorChangeFunction); - colorPickers.push($('#property-zone-haze-blend-out-color').colpick({ + colorPickers.push($('#property-zone-haze-glare-color').colpick({ colorScheme: 'dark', layout: 'hex', color: '000000', onShow: function(colpick) { - $('#property-zone-haze-blend-out-color').attr('active', 'true'); + $('#property-zone-haze-glare-color').attr('active', 'true'); }, onHide: function(colpick) { - $('#property-zone-haze-blend-out-color').attr('active', 'false'); + $('#property-zone-haze-glare-color').attr('active', 'false'); }, onSubmit: function(hsb, hex, rgb, el) { $(el).css('background-color', '#' + hex); From 689828e3facd7cd6a0401f34771808eac17f2915 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 27 Oct 2017 10:00:49 -0700 Subject: [PATCH 086/116] add packet version change for ICE ping change --- libraries/networking/src/udt/PacketHeaders.cpp | 2 ++ libraries/networking/src/udt/PacketHeaders.h | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index ef2768b0af..0852b27293 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -72,6 +72,8 @@ PacketVersion versionForPacketType(PacketType packetType) { case PacketType::MicrophoneAudioWithEcho: case PacketType::AudioStreamStats: return static_cast(AudioVersion::HighDynamicRangeVolume); + case PacketType::ICEPing: + return static_cast(IcePingVersion::SendICEPeerID); default: return 17; } diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index 9443ee570d..9644769566 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -277,4 +277,8 @@ enum class MessageDataVersion : PacketVersion { TextOrBinaryData = 18 }; +enum class IcePingVersion : PacketVersion { + SendICEPeerID = 18 +}; + #endif // hifi_PacketHeaders_h From 2c4d4373dc87d4a76030c3690180c712d266936d Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 27 Oct 2017 10:41:16 -0700 Subject: [PATCH 087/116] support asymmetrical cross section Cylinder --- libraries/entities/src/ShapeEntityItem.cpp | 37 ++++++++++++++-------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/libraries/entities/src/ShapeEntityItem.cpp b/libraries/entities/src/ShapeEntityItem.cpp index 8c7d1576e1..4115a606df 100644 --- a/libraries/entities/src/ShapeEntityItem.cpp +++ b/libraries/entities/src/ShapeEntityItem.cpp @@ -51,12 +51,12 @@ namespace entity { } } -// shapeCalculator is a hook for external code that knows how to configure a ShapeInfo +// hullShapeCalculator is a hook for external code that knows how to configure a ShapeInfo // for given entity::Shape and dimensions -ShapeEntityItem::ShapeInfoCalculator shapeCalculator = nullptr; +ShapeEntityItem::ShapeInfoCalculator hullShapeCalculator = nullptr; void ShapeEntityItem::setShapeInfoCalulator(ShapeEntityItem::ShapeInfoCalculator callback) { - shapeCalculator = callback; + hullShapeCalculator = callback; } ShapeEntityItem::Pointer ShapeEntityItem::baseFactory(const EntityItemID& entityID, const EntityItemProperties& properties) { @@ -276,7 +276,6 @@ void ShapeEntityItem::computeShapeInfo(ShapeInfo& info) { } break; case entity::Shape::Sphere: { - float diameter = entityDimensions.x; const float MIN_DIAMETER = 0.001f; const float MIN_RELATIVE_SPHERICAL_ERROR = 0.001f; @@ -293,13 +292,25 @@ void ShapeEntityItem::computeShapeInfo(ShapeInfo& info) { case entity::Shape::Circle: // Circles collide like flat Cylinders case entity::Shape::Cylinder: { - _collisionShapeType = SHAPE_TYPE_CYLINDER_Y; + float diameter = entityDimensions.x; + const float MIN_DIAMETER = 0.001f; + const float MIN_RELATIVE_SPHERICAL_ERROR = 0.001f; + if (diameter > MIN_DIAMETER + && fabsf(diameter - entityDimensions.z) / diameter < MIN_RELATIVE_SPHERICAL_ERROR) { + _collisionShapeType = SHAPE_TYPE_SPHERE; + } else if (hullShapeCalculator) { + hullShapeCalculator(this, info); + _collisionShapeType = SHAPE_TYPE_SIMPLE_HULL; + } else { + // woops, someone forgot to hook up the hullShapeCalculator()! + // final fallback is ellipsoid + _collisionShapeType = SHAPE_TYPE_ELLIPSOID; + } } break; case entity::Shape::Cone: { - if (shapeCalculator) { - shapeCalculator(this, info); - // shapeCalculator only supports convex shapes (e.g. SHAPE_TYPE_HULL) + if (hullShapeCalculator) { + hullShapeCalculator(this, info); _collisionShapeType = SHAPE_TYPE_SIMPLE_HULL; } else { _collisionShapeType = SHAPE_TYPE_ELLIPSOID; @@ -310,9 +321,8 @@ void ShapeEntityItem::computeShapeInfo(ShapeInfo& info) { case entity::Shape::Triangle: case entity::Shape::Hexagon: case entity::Shape::Octagon: { - if (shapeCalculator) { - shapeCalculator(this, info); - // shapeCalculator only supports convex shapes (e.g. SHAPE_TYPE_HULL) + if (hullShapeCalculator) { + hullShapeCalculator(this, info); _collisionShapeType = SHAPE_TYPE_SIMPLE_HULL; } else { _collisionShapeType = SHAPE_TYPE_ELLIPSOID; @@ -324,9 +334,8 @@ void ShapeEntityItem::computeShapeInfo(ShapeInfo& info) { case entity::Shape::Octahedron: case entity::Shape::Dodecahedron: case entity::Shape::Icosahedron: { - if ( shapeCalculator ) { - shapeCalculator(this, info); - // shapeCalculator only supports convex shapes (e.g. SHAPE_TYPE_HULL) + if ( hullShapeCalculator ) { + hullShapeCalculator(this, info); _collisionShapeType = SHAPE_TYPE_SIMPLE_HULL; } else { _collisionShapeType = SHAPE_TYPE_ELLIPSOID; From 7dc475c695b9a931132bbb6ea1180f0665709b32 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 5 Oct 2017 13:24:51 -0700 Subject: [PATCH 088/116] Update domain server settings Move requests that require access token to go through DS Update various styling and ease of use on DS settings page Update domain server settings CP CP --- .../resources/describe-settings.json | 5 +- domain-server/resources/web/css/style.css | 26 +- domain-server/resources/web/header.html | 4 +- .../resources/web/js/domain-server.js | 3 +- .../resources/web/settings/index.shtml | 5 +- .../resources/web/settings/js/settings.js | 360 +++++++++++++++--- domain-server/src/DomainServer.cpp | 199 ++++++++++ .../embedded-webserver/src/HTTPConnection.cpp | 24 +- .../embedded-webserver/src/HTTPConnection.h | 2 + 9 files changed, 567 insertions(+), 61 deletions(-) diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index 19f1718370..44713accdb 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -14,7 +14,8 @@ { "name": "id", "label": "Domain ID", - "help": "This is your High Fidelity domain ID. If you do not want your domain to be registered in the High Fidelity metaverse you can leave this blank." + "help": "This is your High Fidelity domain ID. If you do not want your domain to be registered in the High Fidelity metaverse you can leave this blank.", + "advanced": true }, { "name": "automatic_networking", @@ -1513,4 +1514,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/domain-server/resources/web/css/style.css b/domain-server/resources/web/css/style.css index 553f408e15..e157e17b8e 100644 --- a/domain-server/resources/web/css/style.css +++ b/domain-server/resources/web/css/style.css @@ -1,6 +1,7 @@ body { position: relative; padding-bottom: 30px; + margin-top: 70px; } [hidden] { @@ -81,7 +82,7 @@ span.port { #setup-sidebar.affix { position: fixed; - top: 15px; + top: 70px; } #setup-sidebar button { @@ -255,3 +256,26 @@ table .headers + .headers td { -webkit-transform: scale(1.0); } } + +/* From https://gist.github.com/alexandrevicenzi/680147013e902a4eaa5d */ +.glyphicon-refresh-animate { + -animation: spin .7s infinite linear; + -ms-animation: spin .7s infinite linear; + -webkit-animation: spinw .7s infinite linear; + -moz-animation: spinm .7s infinite linear; +} + +@keyframes spin { + from { transform: scale(1) rotate(0deg);} + to { transform: scale(1) rotate(360deg);} +} + +@-webkit-keyframes spinw { + from { -webkit-transform: rotate(0deg);} + to { -webkit-transform: rotate(360deg);} +} + +@-moz-keyframes spinm { + from { -moz-transform: rotate(0deg);} + to { -moz-transform: rotate(360deg);} +} diff --git a/domain-server/resources/web/header.html b/domain-server/resources/web/header.html index a37e9a6ff0..803b36d121 100644 --- a/domain-server/resources/web/header.html +++ b/domain-server/resources/web/header.html @@ -13,7 +13,7 @@ -