diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index 59fa9c4f3d..7375a0f650 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -384,7 +384,7 @@ "name": "standard_permissions", "type": "table", "label": "Domain-Wide User Permissions", - "help": "Indicate which users or groups can have which domain-wide permissions.", + "help": "Indicate which users or groups can have which domain-wide permissions.", "caption": "Standard Permissions", "can_add_new_rows": false, @@ -394,7 +394,7 @@ "span": 1 }, { - "label": "Permissions ?", + "label": "Permissions ?", "span": 6 } ], @@ -463,7 +463,7 @@ "span": 1 }, { - "label": "Permissions ?", + "label": "Permissions ?", "span": 6 } ], diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index e0863041a1..55d93d5b5b 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -179,6 +179,7 @@ QUuid EntityScriptingInterface::addEntity(const EntityItemProperties& properties } entity->setLastBroadcast(usecTimestampNow()); + propertiesWithSimID.setLastEdited(entity->getLastEdited()); } else { qCDebug(entities) << "script failed to add new Entity to local Octree"; success = false; @@ -376,6 +377,7 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties& properties.setQueryAACube(entity->getQueryAACube()); } entity->setLastBroadcast(usecTimestampNow()); + properties.setLastEdited(entity->getLastEdited()); // if we've moved an entity with children, check/update the queryAACube of all descendents and tell the server // if they've changed. diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index ec1f8a50bc..7ebfecbe8e 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -130,16 +130,13 @@ bool EntityTree::updateEntityWithElement(EntityItemPointer entity, const EntityI EntityItemProperties properties = origProperties; bool allowLockChange; - bool canRezPermanentEntities; QUuid senderID; if (senderNode.isNull()) { auto nodeList = DependencyManager::get(); allowLockChange = nodeList->isAllowedEditor(); - canRezPermanentEntities = nodeList->getThisNodeCanRez(); senderID = nodeList->getSessionUUID(); } else { allowLockChange = senderNode->isAllowedEditor(); - canRezPermanentEntities = senderNode->getCanRez(); senderID = senderNode->getUUID(); } @@ -148,14 +145,6 @@ bool EntityTree::updateEntityWithElement(EntityItemPointer entity, const EntityI return false; } - if (!canRezPermanentEntities && (entity->getLifetime() != properties.getLifetime())) { - // we don't allow a Node that can't create permanent entities to adjust lifetimes on existing ones - if (properties.lifetimeChanged()) { - qCDebug(entities) << "Refusing disallowed entity lifetime 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()) { @@ -321,26 +310,9 @@ bool EntityTree::updateEntityWithElement(EntityItemPointer entity, const EntityI return true; } -bool EntityTree::permissionsAllowRez(const EntityItemProperties& properties, bool canRez, bool canRezTmp) { - float lifeTime = properties.getLifetime(); - - if (lifeTime == ENTITY_ITEM_IMMORTAL_LIFETIME || lifeTime > _maxTmpEntityLifetime) { - // this is an attempt to rez a permanent or non-temporary entity. - if (!canRez) { - return false; - } - } else { - // this is an attempt to rez a temporary entity. - if (!canRezTmp) { - return false; - } - } - - return true; -} - EntityItemPointer EntityTree::addEntity(const EntityItemID& entityID, const EntityItemProperties& properties) { EntityItemPointer result = NULL; + EntityItemProperties props = properties; auto nodeList = DependencyManager::get(); if (!nodeList) { @@ -348,16 +320,8 @@ EntityItemPointer EntityTree::addEntity(const EntityItemID& entityID, const Enti return nullptr; } - bool clientOnly = properties.getClientOnly(); - - if (!clientOnly && getIsClient() && - !permissionsAllowRez(properties, nodeList->getThisNodeCanRez(), nodeList->getThisNodeCanRezTmp())) { - // if our Node isn't allowed to create entities in this domain, don't try. - return nullptr; - } - bool recordCreationTime = false; - if (properties.getCreated() == UNKNOWN_CREATED_TIME) { + if (props.getCreated() == UNKNOWN_CREATED_TIME) { // the entity's creation time was not specified in properties, which means this is a NEW entity // and we must record its creation time recordCreationTime = true; @@ -372,8 +336,8 @@ EntityItemPointer EntityTree::addEntity(const EntityItemID& entityID, const Enti } // construct the instance of the entity - EntityTypes::EntityType type = properties.getType(); - result = EntityTypes::constructEntityItem(type, entityID, properties); + EntityTypes::EntityType type = props.getType(); + result = EntityTypes::constructEntityItem(type, entityID, props); if (result) { if (recordCreationTime) { @@ -890,6 +854,13 @@ void EntityTree::fixupTerseEditLogging(EntityItemProperties& properties, QList= 0) { + float value = properties.getLifetime(); + changedProperties[index] = QString("lifetime:") + QString::number((int)value); + } + } } int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned char* editData, int maxLength, @@ -922,11 +893,23 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c EntityItemID entityItemID; EntityItemProperties properties; startDecode = usecTimestampNow(); - + bool validEditPacket = EntityItemProperties::decodeEntityEditPacket(editData, maxLength, processedBytes, entityItemID, properties); endDecode = usecTimestampNow(); + const quint64 LAST_EDITED_SERVERSIDE_BUMP = 1; // usec + if (!senderNode->getCanRez() && senderNode->getCanRezTmp()) { + // this node is only allowed to rez temporary entities. if need be, cap the lifetime. + if (properties.getLifetime() == ENTITY_ITEM_IMMORTAL_LIFETIME || + properties.getLifetime() > _maxTmpEntityLifetime) { + properties.setLifetime(_maxTmpEntityLifetime); + // also bump up the lastEdited time of the properties so that the interface that created this edit + // will accept our adjustment to lifetime back into its own entity-tree. + properties.setLastEdited(properties.getLastEdited() + LAST_EDITED_SERVERSIDE_BUMP); + } + } + // If we got a valid edit packet, then it could be a new entity or it could be an update to // an existing entity... handle appropriately if (validEditPacket) { @@ -955,7 +938,7 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c endUpdate = usecTimestampNow(); _totalUpdates++; } else if (message.getType() == PacketType::EntityAdd) { - if (permissionsAllowRez(properties, senderNode->getCanRez(), senderNode->getCanRezTmp())) { + if (senderNode->getCanRez() || senderNode->getCanRezTmp()) { // this is a new entity... assign a new entityID properties.setCreated(properties.getLastEdited()); startCreate = usecTimestampNow(); diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 8afb8d878f..15daf3bf3c 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -64,7 +64,6 @@ public: void setEntityMaxTmpLifetime(float maxTmpEntityLifetime) { _maxTmpEntityLifetime = maxTmpEntityLifetime; } - bool permissionsAllowRez(const EntityItemProperties& properties, bool canRez, bool canRezTmp); /// Implements our type specific root element factory virtual OctreeElementPointer createNewElement(unsigned char* octalCode = NULL) override; diff --git a/scripts/system/edit.js b/scripts/system/edit.js index d1ac32e6f4..9d5585e353 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -334,7 +334,7 @@ var toolBar = (function() { that.setActive = function(active) { if (active != isActive) { - if (active && !Entities.canAdjustLocks()) { + if (active && !Entities.canRez() && !Entities.canRezTmp()) { Window.alert(INSUFFICIENT_PERMISSIONS_ERROR_MSG); } else { Messages.sendLocalMessage("edit-events", JSON.stringify({