diff --git a/assignment-client/src/octree/OctreeInboundPacketProcessor.cpp b/assignment-client/src/octree/OctreeInboundPacketProcessor.cpp index d1b84ec63c..8a560984a6 100644 --- a/assignment-client/src/octree/OctreeInboundPacketProcessor.cpp +++ b/assignment-client/src/octree/OctreeInboundPacketProcessor.cpp @@ -92,11 +92,6 @@ void OctreeInboundPacketProcessor::processPacket(const SharedNodePointer& sendin if (_myServer->getOctree()->handlesEditPacketType(packetType)) { PerformanceWarning warn(debugProcessPacket, "processPacket KNOWN TYPE",debugProcessPacket); _receivedPacketCount++; - - if (! sendingNode.data()->getCanEdit()) { - qDebug("node %s attempted unpermitted edit", sendingNode->getUUID().toString().toUtf8().constData()); - return; - } const unsigned char* packetData = reinterpret_cast(packet.data()); diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 578ee5202d..046df5189d 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -644,15 +644,15 @@ void DomainServer::handleConnectRequest(const QByteArray& packet, const HifiSock nodeUUID = QUuid::createUuid(); } - // if this user is in the editors list (or if the editors list is empty) set the user's node's canEdit to true + // if this user is in the editors list (or if the editors list is empty) set the user's node's canAdjustLocks to true const QVariant* allowedEditorsVariant = valueForKeyPath(_settingsManager.getSettingsMap(), ALLOWED_EDITORS_SETTINGS_KEYPATH); QStringList allowedEditors = allowedEditorsVariant ? allowedEditorsVariant->toStringList() : QStringList(); - bool canEdit = allowedEditors.isEmpty() || allowedEditors.contains(username); + bool canAdjustLocks = allowedEditors.isEmpty() || allowedEditors.contains(username); SharedNodePointer newNode = DependencyManager::get()->addOrUpdateNode(nodeUUID, nodeType, - publicSockAddr, localSockAddr, canEdit); + publicSockAddr, localSockAddr, canAdjustLocks); // when the newNode is created the linked data is also created // if this was a static assignment set the UUID, set the sendingSockAddr DomainServerNodeData* nodeData = reinterpret_cast(newNode->getLinkedData()); @@ -852,7 +852,7 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif // always send the node their own UUID back QDataStream broadcastDataStream(&broadcastPacket, QIODevice::Append); broadcastDataStream << node->getUUID(); - broadcastDataStream << node->getCanEdit(); + broadcastDataStream << node->getCanAdjustLocks(); int numBroadcastPacketLeadBytes = broadcastDataStream.device()->pos(); diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index d2f0c4edb7..5d949912a7 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -27,9 +27,9 @@ void EntityScriptingInterface::queueEntityMessage(PacketType packetType, } -bool EntityScriptingInterface::canEdit() { +bool EntityScriptingInterface::canAdjustLocks() { auto nodeList = DependencyManager::get(); - return nodeList->getThisNodeCanEdit(); + return nodeList->getThisNodeCanAdjustLocks(); } @@ -40,18 +40,16 @@ EntityItemID EntityScriptingInterface::addEntity(const EntityItemProperties& pro EntityItemID id(NEW_ENTITY, creatorTokenID, false ); - if (canEdit()) { - // If we have a local entity tree set, then also update it. - if (_entityTree) { - _entityTree->lockForWrite(); - _entityTree->addEntity(id, properties); - _entityTree->unlock(); - } - - // queue the packet - queueEntityMessage(PacketTypeEntityAddOrEdit, id, properties); + // If we have a local entity tree set, then also update it. + if (_entityTree) { + _entityTree->lockForWrite(); + _entityTree->addEntity(id, properties); + _entityTree->unlock(); } + // queue the packet + queueEntityMessage(PacketTypeEntityAddOrEdit, id, properties); + return id; } @@ -74,32 +72,30 @@ EntityItemID EntityScriptingInterface::identifyEntity(EntityItemID entityID) { EntityItemProperties EntityScriptingInterface::getEntityProperties(EntityItemID entityID) { EntityItemProperties results; - if (canEdit()) { - EntityItemID identity = identifyEntity(entityID); - if (_entityTree) { - _entityTree->lockForRead(); - EntityItem* entity = const_cast(_entityTree->findEntityByEntityItemID(identity)); + EntityItemID identity = identifyEntity(entityID); + if (_entityTree) { + _entityTree->lockForRead(); + EntityItem* entity = const_cast(_entityTree->findEntityByEntityItemID(identity)); - if (entity) { - results = entity->getProperties(); + if (entity) { + results = entity->getProperties(); - // TODO: improve sitting points and naturalDimensions in the future, - // for now we've included the old sitting points model behavior for entity types that are models - // we've also added this hack for setting natural dimensions of models - if (entity->getType() == EntityTypes::Model) { - const FBXGeometry* geometry = _entityTree->getGeometryForEntity(entity); - if (geometry) { - results.setSittingPoints(geometry->sittingPoints); - Extents meshExtents = geometry->getUnscaledMeshExtents(); - results.setNaturalDimensions(meshExtents.maximum - meshExtents.minimum); - } + // TODO: improve sitting points and naturalDimensions in the future, + // for now we've included the old sitting points model behavior for entity types that are models + // we've also added this hack for setting natural dimensions of models + if (entity->getType() == EntityTypes::Model) { + const FBXGeometry* geometry = _entityTree->getGeometryForEntity(entity); + if (geometry) { + results.setSittingPoints(geometry->sittingPoints); + Extents meshExtents = geometry->getUnscaledMeshExtents(); + results.setNaturalDimensions(meshExtents.maximum - meshExtents.minimum); } - - } else { - results.setIsUnknownID(); } - _entityTree->unlock(); + + } else { + results.setIsUnknownID(); } + _entityTree->unlock(); } return results; @@ -107,10 +103,6 @@ EntityItemProperties EntityScriptingInterface::getEntityProperties(EntityItemID EntityItemID EntityScriptingInterface::editEntity(EntityItemID entityID, const EntityItemProperties& properties) { - if (!canEdit()) { - return entityID; - } - EntityItemID actualID = entityID; // if the entity is unknown, attempt to look it up if (!entityID.isKnownID) { @@ -125,7 +117,7 @@ EntityItemID EntityScriptingInterface::editEntity(EntityItemID entityID, const E // the actual id, because we can edit out local entities just with creatorTokenID if (_entityTree) { _entityTree->lockForWrite(); - _entityTree->updateEntity(entityID, properties); + _entityTree->updateEntity(entityID, properties, canAdjustLocks()); _entityTree->unlock(); } @@ -151,10 +143,6 @@ EntityItemID EntityScriptingInterface::editEntity(EntityItemID entityID, const E void EntityScriptingInterface::deleteEntity(EntityItemID entityID) { - if (!canEdit()) { - return; - } - EntityItemID actualID = entityID; // if the entity is unknown, attempt to look it up diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index 19003c3349..6b02d6db0a 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -59,12 +59,11 @@ public: void setEntityTree(EntityTree* modelTree) { _entityTree = modelTree; } EntityTree* getEntityTree(EntityTree*) { return _entityTree; } - public slots: // returns true if the DomainServer will allow this Node/Avatar to make changes - Q_INVOKABLE bool canEdit(); + Q_INVOKABLE bool canAdjustLocks(); /// adds a model with the specific properties Q_INVOKABLE EntityItemID addEntity(const EntityItemProperties& properties); diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index fa64540c4e..95617b4944 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -93,7 +93,7 @@ void EntityTree::postAddEntity(EntityItem* entity) { emit addingEntity(entity->getEntityItemID()); } -bool EntityTree::updateEntity(const EntityItemID& entityID, const EntityItemProperties& properties) { +bool EntityTree::updateEntity(const EntityItemID& entityID, const EntityItemProperties& properties, bool allowLockChange) { EntityTreeElement* containingElement = getContainingElement(entityID); if (!containingElement) { qDebug() << "UNEXPECTED!!!! EntityTree::updateEntity() entityID doesn't exist!!! entityID=" << entityID; @@ -106,21 +106,27 @@ bool EntityTree::updateEntity(const EntityItemID& entityID, const EntityItemProp return false; } - return updateEntityWithElement(existingEntity, properties, containingElement); + return updateEntityWithElement(existingEntity, properties, containingElement, allowLockChange); } -bool EntityTree::updateEntity(EntityItem* entity, const EntityItemProperties& properties) { +bool EntityTree::updateEntity(EntityItem* entity, const EntityItemProperties& properties, bool allowLockChange) { EntityTreeElement* containingElement = getContainingElement(entity->getEntityItemID()); if (!containingElement) { qDebug() << "UNEXPECTED!!!! EntityTree::updateEntity() entity-->element lookup failed!!! entityID=" << entity->getEntityItemID(); return false; } - return updateEntityWithElement(entity, properties, containingElement); + return updateEntityWithElement(entity, properties, containingElement, allowLockChange); } bool EntityTree::updateEntityWithElement(EntityItem* entity, const EntityItemProperties& properties, - EntityTreeElement* containingElement) { + EntityTreeElement* containingElement, bool allowLockChange) { + + if (!allowLockChange && (entity->getLocked() != properties.getLocked())) { + qDebug() << "Refusing disallowed lock adjustment."; + return false; + } + // enforce support for locked entities. If an entity is currently locked, then the only // property we allow you to change is the locked property. if (entity->getLocked()) { @@ -586,7 +592,7 @@ int EntityTree::processEditPacketData(PacketType packetType, const unsigned char // if the EntityItem exists, then update it if (existingEntity) { - updateEntity(entityItemID, properties); + updateEntity(entityItemID, properties, senderNode->getCanAdjustLocks()); existingEntity->markAsChangedOnServer(); } else { qDebug() << "User attempted to edit an unknown entity. ID:" << entityItemID; diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index b4621f1a10..62d6db0a10 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -86,10 +86,10 @@ public: EntityItem* addEntity(const EntityItemID& entityID, const EntityItemProperties& properties); // use this method if you only know the entityID - bool updateEntity(const EntityItemID& entityID, const EntityItemProperties& properties); + bool updateEntity(const EntityItemID& entityID, const EntityItemProperties& properties, bool allowLockChange); // use this method if you have a pointer to the entity (avoid an extra entity lookup) - bool updateEntity(EntityItem* entity, const EntityItemProperties& properties); + bool updateEntity(EntityItem* entity, const EntityItemProperties& properties, bool allowLockChange); void deleteEntity(const EntityItemID& entityID, bool force = false); void deleteEntities(QSet entityIDs, bool force = false); @@ -162,7 +162,7 @@ private: void processRemovedEntities(const DeleteEntityOperator& theOperator); bool updateEntityWithElement(EntityItem* entity, const EntityItemProperties& properties, - EntityTreeElement* containingElement); + EntityTreeElement* containingElement, bool AllowLockChange); static bool findNearPointOperation(OctreeElement* element, void* extraData); static bool findInSphereOperation(OctreeElement* element, void* extraData); static bool findInCubeOperation(OctreeElement* element, void* extraData); diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index b90551dcd0..54c746fcb6 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -412,7 +412,7 @@ void LimitedNodeList::handleNodeKill(const SharedNodePointer& node) { SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t nodeType, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket, - bool canEdit) { + bool canAdjustLocks) { NodeHash::const_iterator it = _nodeHash.find(uuid); if (it != _nodeHash.end()) { @@ -420,12 +420,12 @@ SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t matchingNode->setPublicSocket(publicSocket); matchingNode->setLocalSocket(localSocket); - matchingNode->setCanEdit(canEdit); + matchingNode->setCanAdjustLocks(canAdjustLocks); return matchingNode; } else { // we didn't have this node, so add them - Node* newNode = new Node(uuid, nodeType, publicSocket, localSocket, canEdit); + Node* newNode = new Node(uuid, nodeType, publicSocket, localSocket, canAdjustLocks); SharedNodePointer newNodePointer(newNode); _nodeHash.insert(UUIDNodePair(newNode->getUUID(), newNodePointer)); diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index 378fa89786..72aefdb2b3 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -77,8 +77,8 @@ public: const QUuid& getSessionUUID() const { return _sessionUUID; } void setSessionUUID(const QUuid& sessionUUID); - bool getThisNodeCanEdit() { return _thisNodeCanEdit; } - void setThisNodeCanEdit(bool canEdit) { _thisNodeCanEdit = canEdit; } + bool getThisNodeCanAdjustLocks() { return _thisNodeCanAdjustLocks; } + void setThisNodeCanAdjustLocks(bool canAdjustLocks) { _thisNodeCanAdjustLocks = canAdjustLocks; } void rebindNodeSocket(); QUdpSocket& getNodeSocket() { return _nodeSocket; } @@ -109,7 +109,7 @@ public: SharedNodePointer sendingNodeForPacket(const QByteArray& packet); SharedNodePointer addOrUpdateNode(const QUuid& uuid, NodeType_t nodeType, - const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket, bool canEdit); + const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket, bool canAdjustLocks); const HifiSockAddr& getLocalSockAddr() const { return _localSockAddr; } const HifiSockAddr& getSTUNSockAddr() const { return _stunSockAddr; } @@ -204,7 +204,7 @@ protected: void handleNodeKill(const SharedNodePointer& node); QUuid _sessionUUID; - bool _thisNodeCanEdit; + bool _thisNodeCanAdjustLocks; NodeHash _nodeHash; QReadWriteLock _nodeMutex; QUdpSocket _nodeSocket; diff --git a/libraries/networking/src/Node.cpp b/libraries/networking/src/Node.cpp index ccefc4d1d0..2bf792c6ee 100644 --- a/libraries/networking/src/Node.cpp +++ b/libraries/networking/src/Node.cpp @@ -42,7 +42,7 @@ const QString& NodeType::getNodeTypeName(NodeType_t nodeType) { } Node::Node(const QUuid& uuid, NodeType_t type, const HifiSockAddr& publicSocket, - const HifiSockAddr& localSocket, bool canEdit) : + const HifiSockAddr& localSocket, bool canAdjustLocks) : NetworkPeer(uuid, publicSocket, localSocket), _type(type), _activeSocket(NULL), @@ -54,7 +54,7 @@ Node::Node(const QUuid& uuid, NodeType_t type, const HifiSockAddr& publicSocket, _clockSkewUsec(0), _mutex(), _clockSkewMovingPercentile(30, 0.8f), // moving 80th percentile of 30 samples - _canEdit(canEdit) + _canAdjustLocks(canAdjustLocks) { } @@ -133,7 +133,7 @@ QDataStream& operator<<(QDataStream& out, const Node& node) { out << node._uuid; out << node._publicSocket; out << node._localSocket; - out << node._canEdit; + out << node._canAdjustLocks; return out; } @@ -143,7 +143,7 @@ QDataStream& operator>>(QDataStream& in, Node& node) { in >> node._uuid; in >> node._publicSocket; in >> node._localSocket; - in >> node._canEdit; + in >> node._canAdjustLocks; return in; } diff --git a/libraries/networking/src/Node.h b/libraries/networking/src/Node.h index dbdca9bbc0..ddda947ff4 100644 --- a/libraries/networking/src/Node.h +++ b/libraries/networking/src/Node.h @@ -45,7 +45,8 @@ namespace NodeType { class Node : public NetworkPeer { Q_OBJECT public: - Node(const QUuid& uuid, NodeType_t type, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket, bool canEdit); + Node(const QUuid& uuid, NodeType_t type, + const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket, bool canAdjustLocks); ~Node(); bool operator==(const Node& otherNode) const { return _uuid == otherNode._uuid; } @@ -77,8 +78,8 @@ public: const HifiSockAddr* getActiveSocket() const { return _activeSocket; } - void setCanEdit(bool canEdit) { _canEdit = canEdit; } - bool getCanEdit() { return _canEdit; } + void setCanAdjustLocks(bool canAdjustLocks) { _canAdjustLocks = canAdjustLocks; } + bool getCanAdjustLocks() { return _canAdjustLocks; } void activatePublicSocket(); void activateLocalSocket(); @@ -104,7 +105,7 @@ private: int _clockSkewUsec; QMutex _mutex; MovingPercentile _clockSkewMovingPercentile; - bool _canEdit; + bool _canAdjustLocks; }; QDebug operator<<(QDebug debug, const Node &message); diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index 972efda79e..d35e11a1c3 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -379,9 +379,9 @@ int NodeList::processDomainServerList(const QByteArray& packet) { packetStream >> newUUID; setSessionUUID(newUUID); - bool thisNodeCanEdit; - packetStream >> thisNodeCanEdit; - setThisNodeCanEdit(thisNodeCanEdit); + bool thisNodeCanAdjustLocks; + packetStream >> thisNodeCanAdjustLocks; + setThisNodeCanAdjustLocks(thisNodeCanAdjustLocks); // pull each node in the packet while(packetStream.device()->pos() < packet.size()) { @@ -389,9 +389,9 @@ int NodeList::processDomainServerList(const QByteArray& packet) { qint8 nodeType; QUuid nodeUUID, connectionUUID; HifiSockAddr nodePublicSocket, nodeLocalSocket; - bool canEdit; + bool canAdjustLocks; - packetStream >> nodeType >> nodeUUID >> nodePublicSocket >> nodeLocalSocket >> canEdit; + packetStream >> nodeType >> nodeUUID >> nodePublicSocket >> nodeLocalSocket >> canAdjustLocks; // if the public socket address is 0 then it's reachable at the same IP // as the domain server @@ -399,7 +399,7 @@ int NodeList::processDomainServerList(const QByteArray& packet) { nodePublicSocket.setAddress(_domainHandler.getIP()); } - SharedNodePointer node = addOrUpdateNode(nodeUUID, nodeType, nodePublicSocket, nodeLocalSocket, canEdit); + SharedNodePointer node = addOrUpdateNode(nodeUUID, nodeType, nodePublicSocket, nodeLocalSocket, canAdjustLocks); packetStream >> connectionUUID; node->setConnectionSecret(connectionUUID); diff --git a/tests/octree/src/ModelTests.cpp b/tests/octree/src/ModelTests.cpp index 3666759de4..00cb3901e5 100644 --- a/tests/octree/src/ModelTests.cpp +++ b/tests/octree/src/ModelTests.cpp @@ -107,7 +107,7 @@ void EntityTests::entityTreeTests(bool verbose) { properties.setPosition(newPosition); - tree.updateEntity(entityID, properties); + tree.updateEntity(entityID, properties, true); float targetRadius = oneMeter * 2.0 / (float)TREE_SCALE; // in tree units const EntityItem* foundEntityByRadius = tree.findClosestEntity(positionNearOriginInTreeUnits, targetRadius); @@ -147,7 +147,7 @@ void EntityTests::entityTreeTests(bool verbose) { properties.setPosition(newPosition); - tree.updateEntity(entityID, properties); + tree.updateEntity(entityID, properties, true); float targetRadius = oneMeter * 2.0 / (float)TREE_SCALE; // in tree units const EntityItem* foundEntityByRadius = tree.findClosestEntity(positionAtCenterInTreeUnits, targetRadius);