From 91a165b4c3d92e958f318057ea67b67207f022a1 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Tue, 26 Mar 2019 11:49:08 -0700 Subject: [PATCH] separate out the certified entity map stuff (no-op refactor) --- .../src/entities/EntityServer.cpp | 58 +-------- libraries/entities/src/EntityTree.cpp | 119 +++++++++++++----- libraries/entities/src/EntityTree.h | 3 + 3 files changed, 95 insertions(+), 85 deletions(-) diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index f2cad1e400..06632dabb0 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -22,7 +22,6 @@ #include #include #include -#include #include #include "../AssignmentDynamicFactory.h" @@ -471,62 +470,7 @@ void EntityServer::startDynamicDomainVerification() { qCDebug(entities) << "Starting Dynamic Domain Verification..."; EntityTreePointer tree = std::static_pointer_cast(_tree); - QHash localMap(tree->getEntityCertificateIDMap()); - - QHashIterator i(localMap); - qCDebug(entities) << localMap.size() << "certificates present."; - while (i.hasNext()) { - i.next(); - const auto& certificateID = i.key(); - const auto& entityID = i.value(); - - // Examine each cert: - 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"] = certificateID; - networkRequest.setUrl(requestURL); - - QNetworkReply* networkReply = networkAccessManager.put(networkRequest, QJsonDocument(request).toJson()); - - connect(networkReply, &QNetworkReply::finished, this, [this, entityID, networkReply] { - EntityTreePointer tree = std::static_pointer_cast(_tree); - - QJsonObject jsonObject = QJsonDocument::fromJson(networkReply->readAll()).object(); - jsonObject = jsonObject["data"].toObject(); - networkReply->deleteLater(); - - if (networkReply->error() != QNetworkReply::NoError) { - qCDebug(entities) << "Call to" << networkReply->url() << "failed with error" << networkReply->error() << "; NOT deleting entity" << entityID - << "More info:" << jsonObject; - return; - } - QString thisDomainID = DependencyManager::get()->getDomainID().remove(QRegExp("\\{|\\}")); - if (jsonObject["domain_id"].toString() == thisDomainID) { - // Entity belongs here. Nothing to do. - return; - } - // Entity does not belong here: - EntityItemPointer entity = tree->findEntityByEntityItemID(entityID); - if (!entity) { - qCDebug(entities) << "Entity undergoing dynamic domain verification is no longer available:" << entityID; - return; - } - if (entity->getAge() <= (_MAXIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS / MSECS_PER_SECOND)) { - qCDebug(entities) << "Entity failed dynamic domain verification, but was created too recently to necessitate deletion:" << entityID; - return; - } - qCDebug(entities) << "Entity's cert's domain ID" << jsonObject["domain_id"].toString() - << "doesn't match the current Domain ID" << thisDomainID << "; deleting entity" << entityID; - tree->withWriteLock([&] { - tree->deleteEntity(entityID, true); - }); - }); - } + tree->startDynamicDomainVerificationOnServer((float) _MAXIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS / MSECS_PER_SECOND); 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"; diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 11e392f590..55a8c42261 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include "EntitySimulation.h" #include "VariantMapToScriptValue.h" @@ -286,27 +287,7 @@ void EntityTree::postAddEntity(EntityItemPointer entity) { assert(entity); 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() && !entity->getCertificateType().contains(DOMAIN_UNLIMITED)) { - qCDebug(entities) << "Certificate ID" << certID << "already exists on entity with ID" - << existingEntityItemID << ". Deleting existing entity."; - deleteEntity(existingEntityItemID, true); - return; - } + addCertifiedEntityOnServer(entity); } // check to see if we need to simulate this entity.. @@ -764,13 +745,7 @@ 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); - } - } + removeCertifiedEntityOnServer(theEntity); // set up the deleted entities ID QWriteLocker recentlyDeletedEntitiesLocker(&_recentlyDeletedEntitiesLock); @@ -1421,6 +1396,94 @@ bool EntityTree::isScriptInWhitelist(const QString& scriptProperty) { return false; } +void EntityTree::addCertifiedEntityOnServer(EntityItemPointer entity) { + 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() && !entity->getCertificateType().contains(DOMAIN_UNLIMITED)) { + qCDebug(entities) << "Certificate ID" << certID << "already exists on entity with ID" + << existingEntityItemID << ". Deleting existing entity."; + deleteEntity(existingEntityItemID, true); + } +} + +void EntityTree::removeCertifiedEntityOnServer(EntityItemPointer entity) { + QWriteLocker entityCertificateIDMapLocker(&_entityCertificateIDMapLock); + QString certID = entity->getCertificateID(); + if (entity->getEntityItemID() == _entityCertificateIDMap.value(certID)) { + _entityCertificateIDMap.remove(certID); + } +} + +void EntityTree::startDynamicDomainVerificationOnServer(float minimumAgeToRemove) { + QHash localMap(getEntityCertificateIDMap()); + QHashIterator i(localMap); + qCDebug(entities) << localMap.size() << "certificates present."; + while (i.hasNext()) { + i.next(); + const auto& certificateID = i.key(); + const auto& entityID = i.value(); + + // Examine each cert: + 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"] = certificateID; + networkRequest.setUrl(requestURL); + + QNetworkReply* networkReply = networkAccessManager.put(networkRequest, QJsonDocument(request).toJson()); + + connect(networkReply, &QNetworkReply::finished, this, [this, entityID, networkReply, minimumAgeToRemove] { + + QJsonObject jsonObject = QJsonDocument::fromJson(networkReply->readAll()).object(); + jsonObject = jsonObject["data"].toObject(); + networkReply->deleteLater(); + + if (networkReply->error() != QNetworkReply::NoError) { + qCDebug(entities) << "Call to" << networkReply->url() << "failed with error" << networkReply->error() << "; NOT deleting entity" << entityID + << "More info:" << jsonObject; + return; + } + QString thisDomainID = DependencyManager::get()->getDomainID().remove(QRegExp("\\{|\\}")); + if (jsonObject["domain_id"].toString() == thisDomainID) { + // Entity belongs here. Nothing to do. + return; + } + // Entity does not belong here: + EntityItemPointer entity = findEntityByEntityItemID(entityID); + if (!entity) { + qCDebug(entities) << "Entity undergoing dynamic domain verification is no longer available:" << entityID; + return; + } + if (entity->getAge() <= minimumAgeToRemove) { + qCDebug(entities) << "Entity failed dynamic domain verification, but was created too recently to necessitate deletion:" << entityID; + return; + } + qCDebug(entities) << "Entity's cert's domain ID" << jsonObject["domain_id"].toString() + << "doesn't match the current Domain ID" << thisDomainID << "; deleting entity" << entityID; + withWriteLock([&] { + deleteEntity(entityID, true); + }); + }); + } +} + void EntityTree::startChallengeOwnershipTimer(const EntityItemID& entityItemID) { QTimer* _challengeOwnershipTimeoutTimer = new QTimer(this); connect(this, &EntityTree::killChallengeOwnershipTimeoutTimer, this, [=](const EntityItemID& id) { diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 63e1197970..10809747b3 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -279,6 +279,7 @@ public: void updateEntityQueryAACube(SpatiallyNestablePointer object, EntityEditPacketSender* packetSender, bool force, bool tellServer); + void startDynamicDomainVerificationOnServer(float minimumAgeToRemove); signals: void deletingEntity(const EntityItemID& entityID); @@ -377,6 +378,8 @@ protected: Q_INVOKABLE void startChallengeOwnershipTimer(const EntityItemID& entityItemID); private: + void addCertifiedEntityOnServer(EntityItemPointer entity); + void removeCertifiedEntityOnServer(EntityItemPointer entity); void sendChallengeOwnershipPacket(const QString& certID, const QString& ownerKey, const EntityItemID& entityItemID, const SharedNodePointer& senderNode); void sendChallengeOwnershipRequestPacket(const QByteArray& certID, const QByteArray& text, const QByteArray& nodeToChallenge, const SharedNodePointer& senderNode); void validatePop(const QString& certID, const EntityItemID& entityItemID, const SharedNodePointer& senderNode);