diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a078820e3d..06070094d2 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3613,6 +3613,12 @@ void* Application::networkReceive(void* args) { case PACKET_TYPE_AVATAR_FACE_VIDEO: processAvatarFaceVideoMessage(app->_incomingPacket, bytesReceived); break; + case PACKET_TYPE_DATA_SERVER_GET: + case PACKET_TYPE_DATA_SERVER_PUT: + case PACKET_TYPE_DATA_SERVER_SEND: + case PACKET_TYPE_DATA_SERVER_CONFIRM: + DataServerClient::processMessageFromDataServer(app->_incomingPacket, bytesReceived); + break; default: NodeList::getInstance()->processNodeData(&senderAddress, app->_incomingPacket, bytesReceived); break; diff --git a/interface/src/DataServerClient.cpp b/interface/src/DataServerClient.cpp index 2eefef8ce4..ba748b401b 100644 --- a/interface/src/DataServerClient.cpp +++ b/interface/src/DataServerClient.cpp @@ -6,15 +6,18 @@ // Copyright (c) 2013 HighFidelity, Inc. All rights reserved. // +#include + #include #include #include #include +#include "Application.h" #include "DataServerClient.h" QString DataServerClient::_clientUsername; -std::vector DataServerClient::_unconfirmedPackets; +std::vector DataServerClient::_unmatchedPackets; const char DATA_SERVER_HOSTNAME[] = "127.0.0.1"; const unsigned short DATA_SERVER_PORT = 3282; @@ -27,9 +30,10 @@ void DataServerClient::putValueForKey(const char* key, const char* value) { // setup the header for this packet int numPacketBytes = populateTypeAndVersion(putPacket, PACKET_TYPE_DATA_SERVER_PUT); - // pack the client UUID + // pack the client UUID, null terminated memcpy(putPacket + numPacketBytes, _clientUsername.toLocal8Bit().constData(), _clientUsername.toLocal8Bit().size()); numPacketBytes += _clientUsername.toLocal8Bit().size(); + putPacket[numPacketBytes++] = '\0'; // pack the key, null terminated strcpy((char*) putPacket + numPacketBytes, key); @@ -42,7 +46,7 @@ void DataServerClient::putValueForKey(const char* key, const char* value) { putPacket[numPacketBytes++] = '\0'; // add the putPacket to our vector of unconfirmed packets, will be deleted once put is confirmed - _unconfirmedPackets.push_back(putPacket); + _unmatchedPackets.push_back(putPacket); // send this put request to the data server NodeList::getInstance()->getNodeSocket()->send((sockaddr*) &DATA_SERVER_SOCKET, putPacket, numPacketBytes); @@ -62,9 +66,10 @@ void DataServerClient::getValueForKeyAndUserString(const char* key, QString& use // setup the header for this packet int numPacketBytes = populateTypeAndVersion(getPacket, PACKET_TYPE_DATA_SERVER_GET); - // pack the user string (could be username or UUID string) + // pack the user string (could be username or UUID string), null-terminate memcpy(getPacket + numPacketBytes, userString.toLocal8Bit().constData(), userString.toLocal8Bit().size()); numPacketBytes += userString.toLocal8Bit().size(); + getPacket[numPacketBytes++] = '\0'; // pack the key, null terminated strcpy((char*) getPacket + numPacketBytes, key); @@ -77,14 +82,14 @@ void DataServerClient::getValueForKeyAndUserString(const char* key, QString& use void DataServerClient::processConfirmFromDataServer(unsigned char* packetData, int numPacketBytes) { - for (std::vector::iterator unconfirmedPacket = _unconfirmedPackets.begin(); - unconfirmedPacket != _unconfirmedPackets.end(); + for (std::vector::iterator unconfirmedPacket = _unmatchedPackets.begin(); + unconfirmedPacket != _unmatchedPackets.end(); ++unconfirmedPacket) { if (memcmp(*unconfirmedPacket + sizeof(PACKET_TYPE), packetData + sizeof(PACKET_TYPE), numPacketBytes - sizeof(PACKET_TYPE)) == 0) { // this is a match - remove the confirmed packet from the vector so it isn't sent back out - _unconfirmedPackets.erase(unconfirmedPacket); + _unmatchedPackets.erase(unconfirmedPacket); // we've matched the packet - bail out break; @@ -95,6 +100,46 @@ void DataServerClient::processConfirmFromDataServer(unsigned char* packetData, i } } -void DataServerClient::processGetFromDataServer(unsigned char* packetData, int numPacketBytes) { +void DataServerClient::processSendFromDataServer(unsigned char* packetData, int numPacketBytes) { + // pull the user string from the packet so we know who to associate this with + int numHeaderBytes = numBytesForPacketHeader(packetData); + + QString userString(QByteArray((char*) packetData + numHeaderBytes, strlen((char*) packetData + numHeaderBytes))); + QUuid userUUID(userString); + + if (userUUID.isNull()) { + // the user string was a username + // for now assume this means that it is for our avatar + + char* dataKeyPosition = (char*) packetData + numHeaderBytes + sizeof(userString); + + if (strcmp(dataKeyPosition, DataServerKey::FaceMeshURL) == 0) { + // pull the user's face mesh and set it on the Avatar instance + char* faceMeshPosition = dataKeyPosition + strlen(dataKeyPosition) + sizeof(char); + + QUrl faceMeshURL(QByteArray(faceMeshPosition, + numPacketBytes - ((unsigned char*) faceMeshPosition - packetData))); + + qDebug("Changing user's face model URL to %s\n", faceMeshURL.toString().toLocal8Bit().constData()); + QMetaObject::invokeMethod(&Application::getInstance()->getAvatar()->getHead().getBlendFace(), + "setModelURL", + Q_ARG(QUrl, faceMeshURL)); + } + } else { + // user string was UUID, find matching avatar and associate data + } +} + +void DataServerClient::processMessageFromDataServer(unsigned char* packetData, int numPacketBytes) { + switch (packetData[0]) { + case PACKET_TYPE_DATA_SERVER_SEND: + processSendFromDataServer(packetData, numPacketBytes); + break; + case PACKET_TYPE_DATA_SERVER_CONFIRM: + processConfirmFromDataServer(packetData, numPacketBytes); + break; + default: + break; + } } diff --git a/interface/src/DataServerClient.h b/interface/src/DataServerClient.h index 993608ef81..594f4b5692 100644 --- a/interface/src/DataServerClient.h +++ b/interface/src/DataServerClient.h @@ -20,13 +20,14 @@ public: static void getValueForKeyAndUserString(const char* key, QString& userString); static void getClientValueForKey(const char* key) { getValueForKeyAndUserString(key, _clientUsername); } static void processConfirmFromDataServer(unsigned char* packetData, int numPacketBytes); - static void processGetFromDataServer(unsigned char* packetData, int numPacketBytes); + static void processSendFromDataServer(unsigned char* packetData, int numPacketBytes); + static void processMessageFromDataServer(unsigned char* packetData, int numPacketBytes); static void setClientUsername(const QString& clientUsername) { _clientUsername = clientUsername; } static QString& setClientUsername() { return _clientUsername; } private: static QString _clientUsername; - static std::vector _unconfirmedPackets; + static std::vector _unmatchedPackets; }; namespace DataServerKey {