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({