From 092515e19952910a6601be2a2b81f432c0e5b02d Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 22 Nov 2013 15:19:59 -0800 Subject: [PATCH] Send an explicit kill request to the avatar mixer (which will pass it along to the other clients) when we exit. --- assignment-client/src/avatars/AvatarMixer.cpp | 4 ++- interface/src/Application.cpp | 3 ++ libraries/shared/src/NodeList.cpp | 36 +++++++++++++++++++ libraries/shared/src/NodeList.h | 4 +++ libraries/shared/src/PacketHeaders.h | 1 + 5 files changed, 47 insertions(+), 1 deletion(-) diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index 30e1cf2fcf..b13c92e0ed 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -146,6 +146,7 @@ void AvatarMixer::run() { case PACKET_TYPE_INJECT_AUDIO: broadcastAvatarData(nodeList, nodeUUID, &nodeAddress); break; + case PACKET_TYPE_KILL_NODE: case PACKET_TYPE_AVATAR_URLS: case PACKET_TYPE_AVATAR_FACE_VIDEO: nodeUUID = QUuid::fromRfc4122(QByteArray((char*) packetData + numBytesForPacketHeader(packetData), @@ -156,7 +157,8 @@ void AvatarMixer::run() { nodeList->getNodeSocket()->send(node->getActiveSocket(), packetData, receivedBytes); } } - break; + // let node kills fall through to default behavior + default: // hand this off to the NodeList nodeList->processNodeData(&nodeAddress, packetData, receivedBytes); diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index b9e928e295..eae4c6825a 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1394,6 +1394,9 @@ void Application::terminate() { _rearMirrorTools->saveSettings(_settings); _settings->sync(); + // let the avatar mixer know we're out + NodeList::getInstance()->sendKillNode(&NODE_TYPE_AVATAR_MIXER, 1); + if (_enableNetworkThread) { _stopNetworkReceiveThread = true; pthread_join(_networkReceiveThread, NULL); diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index a943d6dde1..daa0d7a4b1 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -162,6 +162,10 @@ void NodeList::processNodeData(sockaddr* senderAddress, unsigned char* packetDat processSTUNResponse(packetData, dataBytes); break; } + case PACKET_TYPE_KILL_NODE: { + processKillNode(packetData, dataBytes); + break; + } } } @@ -449,6 +453,38 @@ void NodeList::processSTUNResponse(unsigned char* packetData, size_t dataBytes) } } +void NodeList::sendKillNode(const char* nodeTypes, int numNodeTypes) { + unsigned char packet[MAX_PACKET_SIZE]; + unsigned char* packetPosition = packet; + + packetPosition += populateTypeAndVersion(packetPosition, PACKET_TYPE_KILL_NODE); + + QByteArray rfcUUID = _ownerUUID.toRfc4122(); + memcpy(packetPosition, rfcUUID.constData(), rfcUUID.size()); + packetPosition += rfcUUID.size(); + + broadcastToNodes(packet, packetPosition - packet, nodeTypes, numNodeTypes); +} + +void NodeList::processKillNode(unsigned char* packetData, size_t dataBytes) { + // skip the header + int numBytesPacketHeader = numBytesForPacketHeader(packetData); + packetData += numBytesPacketHeader; + dataBytes -= numBytesPacketHeader; + + // read the node id + QUuid nodeUUID = QUuid::fromRfc4122(QByteArray((char*)packetData, NUM_BYTES_RFC4122_UUID)); + + packetData += NUM_BYTES_RFC4122_UUID; + dataBytes -= NUM_BYTES_RFC4122_UUID; + + // make sure the node exists + Node* node = nodeWithUUID(nodeUUID); + if (node) { + killNode(node, true); + } +} + void NodeList::sendDomainServerCheckIn() { static bool printedDomainServerIP = false; diff --git a/libraries/shared/src/NodeList.h b/libraries/shared/src/NodeList.h index 47ea2e9e41..1e7b181cb0 100644 --- a/libraries/shared/src/NodeList.h +++ b/libraries/shared/src/NodeList.h @@ -109,6 +109,8 @@ public: void pingPublicAndLocalSocketsForInactiveNode(Node* node) const; + void sendKillNode(const char* nodeTypes, int numNodeTypes); + Node* nodeWithAddress(sockaddr *senderAddress); Node* nodeWithUUID(const QUuid& nodeUUID); @@ -155,6 +157,8 @@ private: void sendSTUNRequest(); void processSTUNResponse(unsigned char* packetData, size_t dataBytes); + void processKillNode(unsigned char* packetData, size_t dataBytes); + QString _domainHostname; QHostAddress _domainIP; unsigned short _domainPort; diff --git a/libraries/shared/src/PacketHeaders.h b/libraries/shared/src/PacketHeaders.h index a9f320bafd..64a6544cfa 100644 --- a/libraries/shared/src/PacketHeaders.h +++ b/libraries/shared/src/PacketHeaders.h @@ -18,6 +18,7 @@ const PACKET_TYPE PACKET_TYPE_STUN_RESPONSE = 1; const PACKET_TYPE PACKET_TYPE_DOMAIN = 'D'; const PACKET_TYPE PACKET_TYPE_PING = 'P'; const PACKET_TYPE PACKET_TYPE_PING_REPLY = 'R'; +const PACKET_TYPE PACKET_TYPE_KILL_NODE = 'K'; const PACKET_TYPE PACKET_TYPE_HEAD_DATA = 'H'; const PACKET_TYPE PACKET_TYPE_Z_COMMAND = 'Z'; const PACKET_TYPE PACKET_TYPE_INJECT_AUDIO = 'I';