From af1c67a252260f306655ece46885f8c9d3ae7881 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 28 Dec 2016 17:23:56 -0800 Subject: [PATCH] Progress! --- assignment-client/src/audio/AudioMixer.cpp | 5 -- assignment-client/src/avatars/AvatarMixer.cpp | 4 -- interface/resources/qml/hifi/Pal.qml | 37 +++------- libraries/networking/src/Node.cpp | 21 +++--- libraries/networking/src/Node.h | 1 - libraries/networking/src/NodeList.cpp | 67 +++++++------------ libraries/networking/src/NodeList.h | 5 +- libraries/networking/src/udt/PacketHeaders.h | 1 - .../src/UsersScriptingInterface.cpp | 10 +-- .../src/UsersScriptingInterface.h | 19 +++++- scripts/system/pal.js | 12 ++++ 11 files changed, 81 insertions(+), 101 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 3589c025f4..c9b00eb874 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -65,7 +65,6 @@ AudioMixer::AudioMixer(ReceivedMessage& message) : packetReceiver.registerListener(PacketType::NegotiateAudioFormat, this, "handleNegotiateAudioFormat"); packetReceiver.registerListener(PacketType::MuteEnvironment, this, "handleMuteEnvironmentPacket"); packetReceiver.registerListener(PacketType::NodeIgnoreRequest, this, "handleNodeIgnoreRequestPacket"); - packetReceiver.registerListener(PacketType::NodeUnignoreRequest, this, "handleNodeUnignoreRequestPacket"); packetReceiver.registerListener(PacketType::NodePersonalMuteRequest, this, "handleNodePersonalMuteRequestPacket"); packetReceiver.registerListener(PacketType::NodePersonalMuteStatusRequest, this, "handleNodePersonalMuteStatusRequestPacket"); packetReceiver.registerListener(PacketType::KillAvatar, this, "handleKillAvatarPacket"); @@ -228,10 +227,6 @@ void AudioMixer::handleNodeIgnoreRequestPacket(QSharedPointer p sendingNode->parseIgnoreRequestMessage(packet); } -void AudioMixer::handleNodeUnignoreRequestPacket(QSharedPointer packet, SharedNodePointer sendingNode) { - sendingNode->parseUnignoreRequestMessage(packet); -} - void AudioMixer::handleNodePersonalMuteRequestPacket(QSharedPointer packet, SharedNodePointer sendingNode) { // parse out the UUID being muted from the packet QUuid ignoredUUID = QUuid::fromRfc4122(packet->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index 1de1f093b7..43ad2cbaff 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -49,7 +49,6 @@ AvatarMixer::AvatarMixer(ReceivedMessage& message) : packetReceiver.registerListener(PacketType::AvatarIdentity, this, "handleAvatarIdentityPacket"); packetReceiver.registerListener(PacketType::KillAvatar, this, "handleKillAvatarPacket"); packetReceiver.registerListener(PacketType::NodeIgnoreRequest, this, "handleNodeIgnoreRequestPacket"); - packetReceiver.registerListener(PacketType::NodeUnignoreRequest, this, "handleNodeUnignoreRequestPacket"); packetReceiver.registerListener(PacketType::RadiusIgnoreRequest, this, "handleRadiusIgnoreRequestPacket"); packetReceiver.registerListener(PacketType::RequestsDomainListData, this, "handleRequestsDomainListDataPacket"); @@ -595,9 +594,6 @@ void AvatarMixer::handleNodeIgnoreRequestPacket(QSharedPointer senderNode->parseIgnoreRequestMessage(message); } -void AvatarMixer::handleNodeUnignoreRequestPacket(QSharedPointer packet, SharedNodePointer sendingNode) { - sendingNode->parseUnignoreRequestMessage(packet); -} void AvatarMixer::handleRadiusIgnoreRequestPacket(QSharedPointer packet, SharedNodePointer sendingNode) { sendingNode->parseIgnoreRadiusRequestMessage(packet); } diff --git a/interface/resources/qml/hifi/Pal.qml b/interface/resources/qml/hifi/Pal.qml index 819da7eea5..07f9386b2a 100644 --- a/interface/resources/qml/hifi/Pal.qml +++ b/interface/resources/qml/hifi/Pal.qml @@ -210,21 +210,8 @@ Item { var newValue = !model[styleData.role] var datum = userData[model.userIndex] datum[styleData.role] = model[styleData.role] = newValue - if (styleData.role === "personalMute") { - Users[styleData.role](model.sessionId, newValue) - } else if (styleData.role === "ignore") { - var key = styleData.role; - if (!newValue) { - key = 'un' + key; - } - if (newValue) { - ignored[datum.sessionId] = datum; - console.log("fixme hrs adding to ignored", JSON.stringify(datum), "at", datum.sessionId); - } else { - delete ignored[datum.sessionId]; - } - console.log('fixme hrs pal action', key, model.sessionId); - Users[key](model.sessionId); + if (styleData.role === "personalMute" || styleData.role === "ignore") { + Users[styleData.role](model.sessionId, newValue) } else { Users[styleData.role](model.sessionId) // Just for now, while we cannot undo things: @@ -354,7 +341,6 @@ Item { property var userData: [] property var myData: ({displayName: "", userName: "", audioLevel: 0.0}) // valid dummy until set property bool iAmAdmin: false - property var ignored: ({}); // FIXME: reset when changing domains function findSessionIndex(sessionId, optionalData) { // no findIndex in .qml var i, data = optionalData || userData, length = data.length; for (var i = 0; i < length; i++) { @@ -373,16 +359,6 @@ Item { myData = data[myIndex]; data.splice(myIndex, 1); userData = data; - var ignoredID, index; - for (ignoredID in ignored) { - index = findSessionIndex(ignoredID); - console.log('fixme hrs adding back ignored', ignoredID, index, JSON.stringify(ignored[ignoredID])); - if (-1 === index) { // Add back any missing ignored, because they sometimes take a moment to show up. - userData.push(ignored[ignoredID]); - } else { // Mark existing ignored. - userData[index].ignored = true; - } - } sortModel(); break; case 'select': @@ -429,13 +405,20 @@ Item { } } break; - case 'updateMuted': + case 'updatePersonalMutedStatus': var userId = message.params[0]; var enabled = message.params[1]; var userIndex = findSessionIndex(userId); userModel.get(userIndex).personalMute.property = enabled; userData[userIndex].personalMute.property = enabled; // Defensive programming break; + case 'updateIgnoredStatus': + var userId = message.params[0]; + var enabled = message.params[1]; + var userIndex = findSessionIndex(userId); + userModel.get(userIndex).ignore.property = enabled; + userData[userIndex].ignore.property = enabled; // Defensive programming + break; default: console.log('Unrecognized message:', JSON.stringify(message)); } diff --git a/libraries/networking/src/Node.cpp b/libraries/networking/src/Node.cpp index 0f3a6ee30d..b2670fd9b0 100644 --- a/libraries/networking/src/Node.cpp +++ b/libraries/networking/src/Node.cpp @@ -81,18 +81,17 @@ void Node::updateClockSkewUsec(qint64 clockSkewSample) { _clockSkewUsec = (quint64)_clockSkewMovingPercentile.getValueAtPercentile(); } -void Node::parseIgnoreRequestMessage(QSharedPointer message) { - while (message->getBytesLeftToRead()) { - // parse out the UUID being ignored from the packet - QUuid ignoredUUID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); - - addIgnoredNode(ignoredUUID); - } -} - -void Node::parseUnignoreRequestMessage(QSharedPointer message) { +void Node::parseIgnoreRequestMessage(QSharedPointer message) { + // parse out the UUID being ignored from the packet QUuid ignoredUUID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); - removeIgnoredNode(ignoredUUID); + bool addToIgnore; + message->readPrimitive(&addToIgnore); + + if (addToIgnore) { + addIgnoredNode(ignoredUUID); + } else { + removeIgnoredNode(ignoredUUID); + } } void Node::addIgnoredNode(const QUuid& otherNodeID) { diff --git a/libraries/networking/src/Node.h b/libraries/networking/src/Node.h index 0a344c9479..28afb8b943 100644 --- a/libraries/networking/src/Node.h +++ b/libraries/networking/src/Node.h @@ -73,7 +73,6 @@ public: bool getCanKick() const { return _permissions.can(NodePermissions::Permission::canKick); } void parseIgnoreRequestMessage(QSharedPointer message); - void parseUnignoreRequestMessage(QSharedPointer message); void addIgnoredNode(const QUuid& otherNodeID); void removeIgnoredNode(const QUuid& otherNodeID); bool isIgnoringNodeWithID(const QUuid& nodeID) const { QReadLocker lock { &_ignoredNodeIDSetLock }; return _ignoredNodeIDSet.find(nodeID) != _ignoredNodeIDSet.cend(); } diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index ab63c81b9a..89b5590025 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -778,7 +778,7 @@ void NodeList::sendIgnoreRadiusStateToNode(const SharedNodePointer& destinationN sendPacket(std::move(ignorePacket), *destinationNode); } -void NodeList::ignoreNodeBySessionID(const QUuid& nodeID) { +void NodeList::ignoreNodeBySessionID(const QUuid& nodeID, bool ignoreEnabled) { // enumerate the nodes to send a reliable ignore packet to each that can leverage it if (!nodeID.isNull() && _sessionUUID != nodeID) { eachMatchingNode([&nodeID](const SharedNodePointer& node)->bool { @@ -787,63 +787,36 @@ void NodeList::ignoreNodeBySessionID(const QUuid& nodeID) { } else { return false; } - }, [&nodeID, this](const SharedNodePointer& destinationNode) { + }, [&nodeID, ignoreEnabled, this](const SharedNodePointer& destinationNode) { // create a reliable NLPacket with space for the ignore UUID - auto ignorePacket = NLPacket::create(PacketType::NodeIgnoreRequest, NUM_BYTES_RFC4122_UUID, true); + auto ignorePacket = NLPacket::create(PacketType::NodeIgnoreRequest, NUM_BYTES_RFC4122_UUID + sizeof(bool), true); // write the node ID to the packet ignorePacket->write(nodeID.toRfc4122()); + ignorePacket->writePrimitive(ignoreEnabled); - qCDebug(networking) << "Sending packet to ignore node" << uuidStringWithoutCurlyBraces(nodeID); + qCDebug(networking) << "Sending packet to" << (ignoreEnabled ? "ignore" : "unignore") << "node" << uuidStringWithoutCurlyBraces(nodeID); // send off this ignore packet reliably to the matching node sendPacket(std::move(ignorePacket), *destinationNode); }); - QReadLocker setLocker { &_ignoredSetLock }; + QReadLocker setLocker { &_ignoredSetLock }; // write lock for insert and unsafe_erase - // add this nodeID to our set of ignored IDs - _ignoredNodeIDs.insert(nodeID); - - emit ignoredNode(nodeID); + if (ignoreEnabled) { + // add this nodeID to our set of ignored IDs + _ignoredNodeIDs.insert(nodeID); + emit ignoredNode(nodeID); + } else { + _ignoredNodeIDs.unsafe_erase(nodeID); + emit unignoredNode(nodeID); + } } else { qWarning() << "NodeList::ignoreNodeBySessionID called with an invalid ID or an ID which matches the current session ID."; } } -void NodeList::unignoreNodeBySessionID(const QUuid& nodeID) { - // enumerate the nodes to send a reliable unignore packet to each that can leverage it - if (!nodeID.isNull() && _sessionUUID != nodeID) { - eachMatchingNode([&nodeID](const SharedNodePointer& node)->bool { - if (node->getType() == NodeType::AudioMixer || node->getType() == NodeType::AvatarMixer) { - return true; - } else { - return false; - } - }, [&nodeID, this](const SharedNodePointer& destinationNode) { - // create a reliable NLPacket with space for the unignore UUID - auto ignorePacket = NLPacket::create(PacketType::NodeUnignoreRequest, NUM_BYTES_RFC4122_UUID, true); - - // write the node ID to the packet - ignorePacket->write(nodeID.toRfc4122()); - - qCDebug(networking) << "Sending packet to unignore node" << uuidStringWithoutCurlyBraces(nodeID); - - // send off this unignore packet reliably to the matching node - sendPacket(std::move(ignorePacket), *destinationNode); - }); - - QWriteLocker setLocker { &_ignoredSetLock }; // write lock for unsafe_erase - _ignoredNodeIDs.unsafe_erase(nodeID); - - emit unignoredNode(nodeID); - - } else { - qWarning() << "NodeList::unignoreNodeBySessionID called with an invalid ID or an ID which matches the current session ID."; - } -} - bool NodeList::isIgnoringNode(const QUuid& nodeID) const { QReadLocker setLocker { &_ignoredSetLock }; return _ignoredNodeIDs.find(nodeID) != _ignoredNodeIDs.cend(); @@ -876,6 +849,18 @@ void NodeList::maybeSendIgnoreSetToNode(SharedNodePointer newNode) { } } +void NodeList::processPersonalMuteStatusReply(QSharedPointer message) { + // read the UUID from the packet + QString nodeUUIDString = (QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID))).toString(); + // read the personal mute status + bool isPersonalMuted; + message->readPrimitive(&isPersonalMuted); + + qCDebug(networking) << "Got personal muted status" << isPersonalMuted << "for node" << nodeUUIDString; + + emit personalMuteStatusReply(nodeUUIDString, isPersonalMuted); +} + void NodeList::personalMuteNodeBySessionID(const QUuid& nodeID, bool muteEnabled) { // cannot personal mute yourself, or nobody if (!nodeID.isNull() && _sessionUUID != nodeID) { diff --git a/libraries/networking/src/NodeList.h b/libraries/networking/src/NodeList.h index b8022c2d72..1e0a7fa8d1 100644 --- a/libraries/networking/src/NodeList.h +++ b/libraries/networking/src/NodeList.h @@ -76,17 +76,16 @@ public: void toggleIgnoreRadius() { ignoreNodesInRadius(!getIgnoreRadiusEnabled()); } void enableIgnoreRadius() { ignoreNodesInRadius(true); } void disableIgnoreRadius() { ignoreNodesInRadius(false); } - void ignoreNodeBySessionID(const QUuid& nodeID); - void unignoreNodeBySessionID(const QUuid& nodeID); + void ignoreNodeBySessionID(const QUuid& nodeID, bool ignoreEnabled); bool isIgnoringNode(const QUuid& nodeID) const; void personalMuteNodeBySessionID(const QUuid& nodeID, bool muteEnabled); + void requestPersonalMuteStatus(const QUuid& nodeID); void kickNodeBySessionID(const QUuid& nodeID); void muteNodeBySessionID(const QUuid& nodeID); void requestUsernameFromSessionID(const QUuid& nodeID); bool getRequestsDomainListData() { return _requestsDomainListData; } void setRequestsDomainListData(bool isRequesting); - void requestPersonalMuteStatus(const QUuid& nodeID); public slots: void reset(); diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index 76c5120823..78ae1e7ff0 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -105,7 +105,6 @@ public: UsernameFromIDReply, ViewFrustum, RequestsDomainListData, - NodeUnignoreRequest, NodePersonalMuteRequest, NodePersonalMuteStatusRequest, NodePersonalMuteStatusReply, diff --git a/libraries/script-engine/src/UsersScriptingInterface.cpp b/libraries/script-engine/src/UsersScriptingInterface.cpp index 0d6983a1e9..b558c2572d 100644 --- a/libraries/script-engine/src/UsersScriptingInterface.cpp +++ b/libraries/script-engine/src/UsersScriptingInterface.cpp @@ -24,14 +24,14 @@ UsersScriptingInterface::UsersScriptingInterface() { connect(nodeList.data(), &NodeList::personalMuteStatusReply, this, &UsersScriptingInterface::personalMuteStatusReply); } -void UsersScriptingInterface::ignore(const QUuid& nodeID) { +void UsersScriptingInterface::ignore(const QUuid& nodeID, bool ignoreEnabled) { // ask the NodeList to ignore this user (based on the session ID of their node) - DependencyManager::get()->ignoreNodeBySessionID(nodeID); + DependencyManager::get()->ignoreNodeBySessionID(nodeID, ignoreEnabled); } -void UsersScriptingInterface::unignore(const QUuid& nodeID) { - // ask the NodeList to ignore this user (based on the session ID of their node) - DependencyManager::get()->unignoreNodeBySessionID(nodeID); +void UsersScriptingInterface::requestIgnoreStatus(const QUuid& nodeID) { + // ask the Audio Mixer via the NodeList for the Personal Mute status associated with the given session ID + DependencyManager::get()->isIgnoringNode(nodeID); } void UsersScriptingInterface::personalMute(const QUuid& nodeID, bool muteEnabled) { diff --git a/libraries/script-engine/src/UsersScriptingInterface.h b/libraries/script-engine/src/UsersScriptingInterface.h index 31024defc6..05082602b8 100644 --- a/libraries/script-engine/src/UsersScriptingInterface.h +++ b/libraries/script-engine/src/UsersScriptingInterface.h @@ -35,9 +35,16 @@ public slots: * Ignore another user. * @function Users.ignore * @param {nodeID} nodeID The node or session ID of the user you want to ignore. + * @param {bool} enable True for ignored; false for un-ignored. */ - void ignore(const QUuid& nodeID); - void unignore(const QUuid& nodeID); + void ignore(const QUuid& nodeID, bool ignoreEnabled); + + /**jsdoc + * Requests a bool containing whether you have ignored the given Avatar UUID. + * @function Users.requestIgnoreStatus + * @param {nodeID} nodeID The node or session ID of the user whose ignore status you want. + */ + void requestIgnoreStatus(const QUuid& nodeID); /**jsdoc * Mute another user for you and you only. @@ -48,7 +55,7 @@ public slots: void personalMute(const QUuid& nodeID, bool muteEnabled); /**jsdoc - * Requests a bool containing whether you have given the given Avatar UUID. + * Requests a bool containing whether you have personally muted the given Avatar UUID. * @function Users.requestPersonalMuteStatus * @param {nodeID} nodeID The node or session ID of the user whose personal mute status you want. */ @@ -131,6 +138,12 @@ signals: */ void personalMuteStatusReply(const QString& nodeID, bool isPersonalMuted); + /**jsdoc + * Notifies scripts of the Ignore status associated with a UUID. + * @function Users.ignoreStatusReply + */ + void ignoreStatusReply(const QString& nodeID, bool isIgnored); + private: bool getRequestsDomainListData(); void setRequestsDomainListData(bool requests); diff --git a/scripts/system/pal.js b/scripts/system/pal.js index f69a4eb369..2e35ff3d6e 100644 --- a/scripts/system/pal.js +++ b/scripts/system/pal.js @@ -133,9 +133,11 @@ function populateUserList() { Users.requestUsernameFromID(id); } // Request personal mute status from AudioMixer + // and ignore status from AudioMixer/AvatarMixer // (as long as we're not requesting it for our own ID) if (id) { Users.requestPersonalMuteStatus(id); + Users.requestIgnoreStatus(id); } data.push(avatarPalDatum); if (id) { // No overlay for ourself. @@ -171,6 +173,14 @@ function personalMuteStatusReply(id, isPersonalMuted) { pal.sendToQml({ method: 'updatePersonalMutedStatus', params: data }); } +// The function that handles the ignored status from the AudioMixer/AvatarMixer +function ignoreStatusReply(id, isIgnored) { + var data = [id, isIgnored]; + print('Ignored Status Data:', JSON.stringify(data)); + // Ship the data off to QML + pal.sendToQml({ method: 'updateIgnoredStatus', params: data }); +} + var pingPong = true; function updateOverlays() { var eye = Camera.position; @@ -342,6 +352,7 @@ pal.visibleChanged.connect(onVisibleChanged); pal.closed.connect(off); Users.usernameFromIDReply.connect(usernameFromIDReply); Users.personalMuteStatusReply.connect(personalMuteStatusReply); +Users.ignoreStatusReply.connect(ignoreStatusReply); function onIgnore(sessionId) { // make it go away in the usual way, since we'll still get data keeping it live // Why doesn't this work from .qml? (crashes) @@ -360,6 +371,7 @@ Script.scriptEnding.connect(function () { Users.usernameFromIDReply.disconnect(usernameFromIDReply); Users.ignoredNode.disconnect(onIgnore); Users.personalMuteStatusReply.disconnect(personalMuteStatusReply); + Users.ignoreStatusReply.disconnect(ignoreStatusReply); off(); });