diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index 7fbbefa596..425bea2c38 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -302,22 +302,16 @@ void EntityServer::readAdditionalConfiguration(const QJsonObject& settingsSectio // connect the filterAdded signal, and block edits until you hear back connect(entityEditFilters.data(), &EntityEditFilters::filterAdded, this, &EntityServer::entityFilterAdded); - entityEditFilters->rejectAll(true); entityEditFilters->addFilter(EntityItemID(), filterURL); } } void EntityServer::entityFilterAdded(EntityItemID id, bool success) { if (id.isInvalidID()) { - // this is the domain-wide entity filter, which we want to stop - // the world for - auto entityEditFilters = qobject_cast(sender()); if (success) { qDebug() << "entity edit filter for " << id << "added successfully"; - entityEditFilters->rejectAll(false); } else { - qDebug() << "entity edit filter unsuccessfully added, stopping..."; - stop(); + qDebug() << "entity edit filter unsuccessfully added, all edits will be rejected for those without lock rights."; } } } diff --git a/libraries/entities/src/EntityEditFilters.cpp b/libraries/entities/src/EntityEditFilters.cpp index ddd9ea006a..cda7f1bc59 100644 --- a/libraries/entities/src/EntityEditFilters.cpp +++ b/libraries/entities/src/EntityEditFilters.cpp @@ -42,20 +42,18 @@ QList EntityEditFilters::getZonesByPosition(glm::vec3& position) { return zones; } -bool EntityEditFilters::filter(glm::vec3& position, EntityItemProperties& propertiesIn, EntityItemProperties& propertiesOut, bool& wasChanged, EntityTree::FilterType filterType) { +bool EntityEditFilters::filter(glm::vec3& position, EntityItemProperties& propertiesIn, EntityItemProperties& propertiesOut, bool& wasChanged, + EntityTree::FilterType filterType, EntityItemID& itemID) { qCDebug(entities) << "in EntityEditFilters"; - // allows us to start entity server and reject all edits until filter is setup - if (_rejectAll) { - qCDebug(entities) << "rejecting all edits"; - return false; - } - // get the ids of all the zones (plus the global entity edit filter) that the position // lies within auto zoneIDs = getZonesByPosition(position); - for (auto id : zoneIDs) { + if (id == itemID) { + qCDebug(entities) << "zone filter not applied to its own edit"; + continue; + } qCDebug(entities) << "applying filter for zone" << id; // get the filter pair, etc... @@ -64,7 +62,10 @@ bool EntityEditFilters::filter(glm::vec3& position, EntityItemProperties& proper _lock.unlock(); if (filterData.valid()) { - + if (filterData.rejectAll) { + qCDebug(entities) << "rejecting all edits"; + return false; + } auto oldProperties = propertiesIn.getDesiredProperties(); auto specifiedProperties = propertiesIn.getChangedProperties(); propertiesIn.setDesiredProperties(specifiedProperties); @@ -81,7 +82,6 @@ bool EntityEditFilters::filter(glm::vec3& position, EntityItemProperties& proper result = QScriptValue(); } - if (result.isObject()){ qCDebug(entities) << "filter result accepted"; // make propertiesIn reflect the changes, for next filter... @@ -131,7 +131,15 @@ void EntityEditFilters::addFilter(EntityItemID entityID, QString filterURL) { // first remove any existing info for this entity removeFilter(entityID); + + // reject all edits until we load the script + FilterData filterData; + filterData.rejectAll = true; + _lock.lockForWrite(); + _filterDataMap.insert(entityID, filterData); + _lock.unlock(); + auto scriptRequest = ResourceManager::createResourceRequest(this, scriptURL); if (!scriptRequest) { qWarning() << "Could not create ResourceRequest for Entity Edit filter script at" << scriptURL.toString(); @@ -195,6 +203,7 @@ void EntityEditFilters::scriptRequestFinished(EntityItemID entityID) { // put the engine in the engine map (so we don't leak them, etc...) FilterData filterData; filterData.engine = engine; + filterData.rejectAll = false; // define the uncaughtException function QScriptEngine& engineRef = *engine; @@ -209,10 +218,11 @@ void EntityEditFilters::scriptRequestFinished(EntityItemID entityID) { global.setProperty("Entities", entitiesObject); filterData.filterFn = global.property("filter"); if (!filterData.filterFn.isFunction()) { - qDebug() << "Filter function specified but not found. Ignoring filter"; + qDebug() << "Filter function specified but not found. Will reject all edits for those without lock rights."; delete engine; - return; + filterData.rejectAll=true; } + _lock.lockForWrite(); _filterDataMap.insert(entityID, filterData); diff --git a/libraries/entities/src/EntityEditFilters.h b/libraries/entities/src/EntityEditFilters.h index 8ad82621dd..6aeb347603 100644 --- a/libraries/entities/src/EntityEditFilters.h +++ b/libraries/entities/src/EntityEditFilters.h @@ -30,8 +30,10 @@ public: QScriptValue filterFn; std::function uncaughtExceptions; QScriptEngine* engine; - - bool valid() { return (engine != nullptr && filterFn.isFunction() && uncaughtExceptions); } + bool rejectAll; + + FilterData(): engine(nullptr), rejectAll(false) {}; + bool valid() { return (rejectAll || (engine != nullptr && filterFn.isFunction() && uncaughtExceptions)); } }; EntityEditFilters() {}; @@ -40,8 +42,8 @@ public: void addFilter(EntityItemID entityID, QString filterURL); void removeFilter(EntityItemID entityID); - bool filter(glm::vec3& position, EntityItemProperties& propertiesIn, EntityItemProperties& propertiesOut, bool& wasChanged, EntityTree::FilterType filterType); - void rejectAll(bool state) {_rejectAll = state; } + bool filter(glm::vec3& position, EntityItemProperties& propertiesIn, EntityItemProperties& propertiesOut, bool& wasChanged, + EntityTree::FilterType filterType, EntityItemID& entityID); signals: void filterAdded(EntityItemID id, bool success); diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index e1edc6bb20..cd12b703f8 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -928,9 +928,9 @@ void EntityTree::fixupTerseEditLogging(EntityItemProperties& properties, QList(); - if (entityEditFilters) { + if (entityEditFilters && existingEntity) { auto position = existingEntity->getPosition(); - accepted = entityEditFilters->filter(position, propertiesIn, propertiesOut, wasChanged, filterType); + accepted = entityEditFilters->filter(position, propertiesIn, propertiesOut, wasChanged, filterType, existingEntity->getEntityItemID()); } return accepted;