diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index dc1a693590..02dc552dae 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -34,7 +34,7 @@ EntityServer::EntityServer(ReceivedMessage& message) : DependencyManager::set(); auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver.registerListenerForTypes({ PacketType::EntityAdd, PacketType::EntityEdit, PacketType::EntityErase }, + packetReceiver.registerListenerForTypes({ PacketType::EntityAdd, PacketType::EntityEdit, PacketType::EntityErase, PacketType::EntityPhysics }, this, "handleEntityPacket"); } diff --git a/libraries/entities/src/EntityEditPacketSender.cpp b/libraries/entities/src/EntityEditPacketSender.cpp index e05db07d0d..43de66f4b2 100644 --- a/libraries/entities/src/EntityEditPacketSender.cpp +++ b/libraries/entities/src/EntityEditPacketSender.cpp @@ -29,7 +29,7 @@ void EntityEditPacketSender::processEntityEditNackPacket(QSharedPointernewObject(); + entitiesObject.setProperty("ADD_FILTER_TYPE", FilterType::Add); + entitiesObject.setProperty("EDIT_FILTER_TYPE", FilterType::Edit); + entitiesObject.setProperty("PHYSICS_FILTER_TYPE", FilterType::Physics); + global.setProperty("Entities", entitiesObject); _hasEntityEditFilter = true; } -bool EntityTree::filterProperties(EntityItemProperties& propertiesIn, EntityItemProperties& propertiesOut, bool& wasChanged, bool isAdd) { +bool EntityTree::filterProperties(EntityItemProperties& propertiesIn, EntityItemProperties& propertiesOut, bool& wasChanged, FilterType filterType) { if (!_entityEditFilterEngine) { propertiesOut = propertiesIn; wasChanged = false; // not changed @@ -953,7 +959,7 @@ bool EntityTree::filterProperties(EntityItemProperties& propertiesIn, EntityItem auto in = QJsonValue::fromVariant(inputValues.toVariant()); // grab json copy now, because the inputValues might be side effected by the filter. QScriptValueList args; args << inputValues; - args << isAdd; + args << filterType; QScriptValue result = _entityEditFilterFunction.call(_nullObjectForFilter, args); if (_entityEditFilterHadUncaughtExceptions()) { @@ -1001,6 +1007,7 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c case PacketType::EntityAdd: isAdd = true; // fall through to next case + case PacketType::EntityPhysics: case PacketType::EntityEdit: { quint64 startDecode = 0, endDecode = 0; quint64 startLookup = 0, endLookup = 0; @@ -1010,6 +1017,7 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c quint64 startLogging = 0, endLogging = 0; bool suppressDisallowedScript = false; + bool isPhysics = message.getType() == PacketType::EntityPhysics; _totalEditMessages++; @@ -1021,6 +1029,7 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c entityItemID, properties); endDecode = usecTimestampNow(); + if (validEditPacket && !_entityScriptSourceWhitelist.isEmpty() && !properties.getScript().isEmpty()) { bool passedWhiteList = false; @@ -1053,8 +1062,7 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c } } - if ((isAdd || - (message.getType() == PacketType::EntityEdit && properties.lifetimeChanged())) && + if ((isAdd || properties.lifetimeChanged()) && !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 || @@ -1070,8 +1078,9 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c startFilter = usecTimestampNow(); bool wasChanged = false; - // Having (un)lock rights bypasses the filter. - bool allowed = senderNode->isAllowedEditor() || filterProperties(properties, properties, wasChanged, isAdd); + // Having (un)lock rights bypasses the filter, unless it's a physics result. + FilterType filterType = isPhysics ? FilterType::Physics : (isAdd ? FilterType::Add : FilterType::Edit); + bool allowed = (!isPhysics && senderNode->isAllowedEditor()) || filterProperties(properties, properties, wasChanged, filterType); if (!allowed) { auto timestamp = properties.getLastEdited(); properties = EntityItemProperties(); @@ -1088,7 +1097,7 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c startLookup = usecTimestampNow(); EntityItemPointer existingEntity = findEntityByEntityItemID(entityItemID); endLookup = usecTimestampNow(); - if (existingEntity && message.getType() == PacketType::EntityEdit) { + if (existingEntity && !isAdd) { if (suppressDisallowedScript) { bumpTimestamp(properties); diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 9b30096be5..5dad282d3b 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -60,6 +60,11 @@ public: class EntityTree : public Octree, public SpatialParentTree { Q_OBJECT public: + enum FilterType { + Add, + Edit, + Physics + }; EntityTree(bool shouldReaverage = false); virtual ~EntityTree(); @@ -357,7 +362,7 @@ protected: float _maxTmpEntityLifetime { DEFAULT_MAX_TMP_ENTITY_LIFETIME }; - bool filterProperties(EntityItemProperties& propertiesIn, EntityItemProperties& propertiesOut, bool& wasChanged, bool isAdd); + bool filterProperties(EntityItemProperties& propertiesIn, EntityItemProperties& propertiesOut, bool& wasChanged, FilterType filterType); bool _hasEntityEditFilter{ false }; QScriptEngine* _entityEditFilterEngine{}; QScriptValue _entityEditFilterFunction{}; diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index 7cb02010f8..e2dc8d73e6 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -48,7 +48,8 @@ PacketVersion versionForPacketType(PacketType packetType) { case PacketType::EntityAdd: case PacketType::EntityEdit: case PacketType::EntityData: - return VERSION_ENTITIES_SERVER_SCRIPTS; + case PacketType::EntityPhysics: + return VERSION_ENTITIES_PHYSICS_PACKET; case PacketType::EntityQuery: return static_cast(EntityQueryPacketVersion::JsonFilter); case PacketType::AvatarIdentity: diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index d695bde62a..88b5ec19ad 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -110,7 +110,8 @@ public: EntityScriptGetStatus, EntityScriptGetStatusReply, ReloadEntityServerScript, - LAST_PACKET_TYPE = ReloadEntityServerScript + EntityPhysics, + LAST_PACKET_TYPE = EntityPhysics }; }; @@ -201,6 +202,7 @@ const PacketVersion VERSION_WEB_ENTITIES_SUPPORT_DPI = 63; const PacketVersion VERSION_ENTITIES_ARROW_ACTION = 64; const PacketVersion VERSION_ENTITIES_LAST_EDITED_BY = 65; const PacketVersion VERSION_ENTITIES_SERVER_SCRIPTS = 66; +const PacketVersion VERSION_ENTITIES_PHYSICS_PACKET = 67; enum class EntityQueryPacketVersion: PacketVersion { JsonFilter = 18 diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index e9891020b3..eb75718d92 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -614,7 +614,7 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_ properties.setClientOnly(_entity->getClientOnly()); properties.setOwningAvatarID(_entity->getOwningAvatarID()); - entityPacketSender->queueEditEntityMessage(PacketType::EntityEdit, tree, id, properties); + entityPacketSender->queueEditEntityMessage(PacketType::EntityPhysics, tree, id, properties); _entity->setLastBroadcast(now); // if we've moved an entity with children, check/update the queryAACube of all descendents and tell the server @@ -630,7 +630,7 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_ newQueryCubeProperties.setClientOnly(entityDescendant->getClientOnly()); newQueryCubeProperties.setOwningAvatarID(entityDescendant->getOwningAvatarID()); - entityPacketSender->queueEditEntityMessage(PacketType::EntityEdit, tree, + entityPacketSender->queueEditEntityMessage(PacketType::EntityPhysics, tree, descendant->getID(), newQueryCubeProperties); entityDescendant->setLastBroadcast(now); }