From 85edb93710d8d42cf0053a0d88b511964aeed722 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 8 Oct 2013 12:13:45 -0700 Subject: [PATCH] add a Profile class to hold user data from data-server --- interface/src/Application.cpp | 2 +- interface/src/Application.h | 3 ++ interface/src/DataServerClient.cpp | 81 +++++++++++++++++------------- interface/src/DataServerClient.h | 9 ++-- interface/src/Menu.cpp | 5 +- interface/src/avatar/MyAvatar.cpp | 10 ---- interface/src/avatar/MyAvatar.h | 3 -- interface/src/avatar/Profile.cpp | 54 ++++++++++++++++++++ interface/src/avatar/Profile.h | 39 ++++++++++++++ 9 files changed, 150 insertions(+), 56 deletions(-) create mode 100644 interface/src/avatar/Profile.cpp create mode 100644 interface/src/avatar/Profile.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 408724d1a3..ff84b4ee2d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1587,7 +1587,7 @@ void Application::init() { } qDebug("Loaded settings.\n"); - if (!_myAvatar.getUsername().isEmpty()) { + if (!_profile.getUsername().isEmpty()) { // we have a username for this avatar, ask the data-server for the mesh URL for this avatar DataServerClient::getClientValueForKey(DataServerKey::FaceMeshURL); } diff --git a/interface/src/Application.h b/interface/src/Application.h index 620d6d57f5..a4994d7f6c 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -44,6 +44,7 @@ #include "VoxelImporter.h" #include "avatar/Avatar.h" #include "avatar/MyAvatar.h" +#include "avatar/Profile.h" #include "avatar/HandControl.h" #include "devices/Faceshift.h" #include "devices/SerialInterface.h" @@ -110,6 +111,7 @@ public: QGLWidget* getGLWidget() { return _glWidget; } MyAvatar* getAvatar() { return &_myAvatar; } + Profile* getProfile() { return &_profile; } Audio* getAudio() { return &_audio; } Camera* getCamera() { return &_myCamera; } ViewFrustum* getViewFrustum() { return &_viewFrustum; } @@ -275,6 +277,7 @@ private: Oscilloscope _audioScope; MyAvatar _myAvatar; // The rendered avatar of oneself + Profile _profile; // The data-server linked profile for this user Transmitter _myTransmitter; // Gets UDP data from transmitter app used to animate the avatar diff --git a/interface/src/DataServerClient.cpp b/interface/src/DataServerClient.cpp index 529ce9bd83..27fbb44d13 100644 --- a/interface/src/DataServerClient.cpp +++ b/interface/src/DataServerClient.cpp @@ -14,9 +14,11 @@ #include #include "Application.h" +#include "Profile.h" + #include "DataServerClient.h" -QString DataServerClient::_clientUsername; + std::map DataServerClient::_unmatchedPackets; const char DATA_SERVER_HOSTNAME[] = "127.0.0.1"; @@ -24,33 +26,36 @@ const unsigned short DATA_SERVER_PORT = 3282; const sockaddr_in DATA_SERVER_SOCKET = socketForHostnameAndHostOrderPort(DATA_SERVER_HOSTNAME, DATA_SERVER_PORT); void DataServerClient::putValueForKey(const char* key, const char* value) { - if (!_clientUsername.isEmpty()) { - unsigned char* putPacket = new unsigned char[MAX_PACKET_SIZE]; - - // setup the header for this packet - int numPacketBytes = populateTypeAndVersion(putPacket, PACKET_TYPE_DATA_SERVER_PUT); - - // 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); - numPacketBytes += strlen(key); - putPacket[numPacketBytes++] = '\0'; - - // pack the value, null terminated - strcpy((char*) putPacket + numPacketBytes, value); - numPacketBytes += strlen(value); - putPacket[numPacketBytes++] = '\0'; - - // add the putPacket to our vector of unconfirmed packets, will be deleted once put is confirmed - _unmatchedPackets.insert(std::pair(putPacket, numPacketBytes)); - - // send this put request to the data server - NodeList::getInstance()->getNodeSocket()->send((sockaddr*) &DATA_SERVER_SOCKET, putPacket, numPacketBytes); - } + Profile* userProfile = Application::getInstance()->getProfile(); + QString clientString = userProfile->getUUID().isNull() ? userProfile->getUsername() : userProfile->getUUID().toString(); + + Application::getInstance(); + + unsigned char* putPacket = new unsigned char[MAX_PACKET_SIZE]; + + // setup the header for this packet + int numPacketBytes = populateTypeAndVersion(putPacket, PACKET_TYPE_DATA_SERVER_PUT); + + // pack the client UUID, null terminated + memcpy(putPacket + numPacketBytes, clientString.toLocal8Bit().constData(), clientString.toLocal8Bit().size()); + numPacketBytes += clientString.toLocal8Bit().size(); + putPacket[numPacketBytes++] = '\0'; + + // pack the key, null terminated + strcpy((char*) putPacket + numPacketBytes, key); + numPacketBytes += strlen(key); + putPacket[numPacketBytes++] = '\0'; + + // pack the value, null terminated + strcpy((char*) putPacket + numPacketBytes, value); + numPacketBytes += strlen(value); + putPacket[numPacketBytes++] = '\0'; + + // add the putPacket to our vector of unconfirmed packets, will be deleted once put is confirmed + _unmatchedPackets.insert(std::pair(putPacket, numPacketBytes)); + + // send this put request to the data server + NodeList::getInstance()->getNodeSocket()->send((sockaddr*) &DATA_SERVER_SOCKET, putPacket, numPacketBytes); } void DataServerClient::getValueForKeyAndUUID(const char* key, QUuid &uuid) { @@ -83,7 +88,9 @@ void DataServerClient::getValueForKeyAndUserString(const char* key, QString& use NodeList::getInstance()->getNodeSocket()->send((sockaddr*) &DATA_SERVER_SOCKET, getPacket, numPacketBytes); } - +void DataServerClient::getClientValueForKey(const char* key) { + getValueForKeyAndUserString(key, Application::getInstance()->getProfile()->getUsername()); +} void DataServerClient::processConfirmFromDataServer(unsigned char* packetData, int numPacketBytes) { removeMatchedPacketFromMap(packetData, numPacketBytes); @@ -102,18 +109,22 @@ void DataServerClient::processSendFromDataServer(unsigned char* packetData, int // for now assume this means that it is for our avatar char* dataKeyPosition = (char*) packetData + numHeaderBytes + sizeof(userString); + char* dataValuePosition = dataKeyPosition + strlen(dataKeyPosition) + sizeof(char); + + QString dataValueString(QByteArray(dataValuePosition, + numPacketBytes - ((unsigned char*) dataValuePosition - packetData))); 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()); + + qDebug("Changing user's face model URL to %s\n", dataValueString.toLocal8Bit().constData()); QMetaObject::invokeMethod(&Application::getInstance()->getAvatar()->getHead().getBlendFace(), "setModelURL", - Q_ARG(QUrl, faceMeshURL)); + Q_ARG(QUrl, QUrl(dataValueString))); + } else if (strcmp(dataKeyPosition, DataServerKey::UUID) == 0) { + // this is the user's UUID - set it on the profile + Application::getInstance()->getProfile()->setUUID(dataValueString); } } else { // user string was UUID, find matching avatar and associate data diff --git a/interface/src/DataServerClient.h b/interface/src/DataServerClient.h index 072236545d..1a26cdb23d 100644 --- a/interface/src/DataServerClient.h +++ b/interface/src/DataServerClient.h @@ -13,27 +13,26 @@ #include +#include "Application.h" + class DataServerClient { public: static void putValueForKey(const char* key, const char* value); static void getValueForKeyAndUUID(const char* key, QUuid& uuid); static void getValueForKeyAndUserString(const char* key, QString& userString); - static void getClientValueForKey(const char* key) { getValueForKeyAndUserString(key, _clientUsername); } + static void getClientValueForKey(const char* key); static void processConfirmFromDataServer(unsigned char* packetData, int numPacketBytes); static void processSendFromDataServer(unsigned char* packetData, int numPacketBytes); static void processMessageFromDataServer(unsigned char* packetData, int numPacketBytes); static void removeMatchedPacketFromMap(unsigned char* packetData, int numPacketBytes); static void resendUnmatchedPackets(); - - static void setClientUsername(const QString& clientUsername) { _clientUsername = clientUsername; } - static QString& setClientUsername() { return _clientUsername; } private: - static QString _clientUsername; static std::map _unmatchedPackets; }; namespace DataServerKey { const char FaceMeshURL[] = "mesh"; + const char UUID[] = "uuid"; } #endif /* defined(__hifi__DataServerClient__) */ diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 9274674947..74bfc0527a 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -504,6 +504,7 @@ void Menu::loadSettings(QSettings* settings) { settings->endGroup(); scanMenuBar(&loadAction, settings); + Application::getInstance()->getProfile()->loadData(settings); Application::getInstance()->getAvatar()->loadData(settings); Application::getInstance()->getSwatch()->loadData(settings); } @@ -755,7 +756,7 @@ void Menu::editPreferences() { QFormLayout* form = new QFormLayout(); layout->addLayout(form, 1); - QString avatarUsername = applicationInstance->getAvatar()->getUsername(); + QString avatarUsername = applicationInstance->getProfile()->getUsername(); QLineEdit* avatarUsernameEdit = new QLineEdit(avatarUsername); avatarUsernameEdit->setMinimumWidth(QLINE_MINIMUM_WIDTH); form->addRow("Username:", avatarUsernameEdit); @@ -815,7 +816,7 @@ void Menu::editPreferences() { if (avatarUsernameEdit->text() != avatarUsername) { // there has been a username change - set the new UUID on the avatar instance - applicationInstance->getAvatar()->setUsername(avatarUsernameEdit->text()); + applicationInstance->getProfile()->setUsername(avatarUsernameEdit->text()); if (faceModelURL.toString() == faceURLString) { // if there was no change to the face model URL then clear it and ask the data-server for what it is diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index c08843b118..2a4ec30621 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -72,12 +72,6 @@ void MyAvatar::setMoveTarget(const glm::vec3 moveTarget) { _moveTargetStepCounter = 0; } -void MyAvatar::setUsername(const QString& username) { - _username = username; - - DataServerClient::setClientUsername(username); -} - void MyAvatar::simulate(float deltaTime, Transmitter* transmitter) { glm::quat orientation = getOrientation(); @@ -534,8 +528,6 @@ void MyAvatar::renderScreenTint(ScreenTintLayer layer, Camera& whichCamera) { void MyAvatar::saveData(QSettings* settings) { settings->beginGroup("Avatar"); - settings->setValue("Username", _username); - settings->setValue("bodyYaw", _bodyYaw); settings->setValue("bodyPitch", _bodyPitch); settings->setValue("bodyRoll", _bodyRoll); @@ -557,8 +549,6 @@ void MyAvatar::saveData(QSettings* settings) { void MyAvatar::loadData(QSettings* settings) { settings->beginGroup("Avatar"); - setUsername(settings->value("Username").toString()); - // in case settings is corrupt or missing loadSetting() will check for NaN _bodyYaw = loadSetting(settings, "bodyYaw", 0.0f); _bodyPitch = loadSetting(settings, "bodyPitch", 0.0f); diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 4b37e28f55..e6cea94988 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -34,7 +34,6 @@ public: void setNewScale(const float scale); void setWantCollisionsOn(bool wantCollisionsOn) { _isCollisionsOn = wantCollisionsOn; } void setMoveTarget(const glm::vec3 moveTarget); - void setUsername(const QString& username); // getters float getNewScale() const { return _newScale; } @@ -50,7 +49,6 @@ public: glm::vec3 getGravity() const { return _gravity; } glm::vec3 getUprightHeadPosition() const; glm::vec3 getUprightEyeLevelPosition() const; - const QString& getUsername() const { return _username; } // get/set avatar data void saveData(QSettings* settings); @@ -84,7 +82,6 @@ private: float _collisionRadius; glm::vec3 _moveTarget; int _moveTargetStepCounter; - QString _username; // private methods float getBallRenderAlpha(int ball, bool lookingInMirror) const; diff --git a/interface/src/avatar/Profile.cpp b/interface/src/avatar/Profile.cpp new file mode 100644 index 0000000000..fcd4365c82 --- /dev/null +++ b/interface/src/avatar/Profile.cpp @@ -0,0 +1,54 @@ +// +// Profile.cpp +// hifi +// +// Created by Stephen Birarda on 10/8/13. +// Copyright (c) 2013 HighFidelity, Inc. All rights reserved. +// + +#include + +#include "Profile.h" +#include "DataServerClient.h" + +Profile::Profile() : + _username(), + _uuid(), + _faceModelURL() +{ + +} + +void Profile::clear() { + _username.clear(); + _uuid = QUuid(); + _faceModelURL.clear(); +} + +void Profile::setUsername(const QString &username) { + this->clear(); + _username = username; + + // we've been given a new username, ask the data-server for our UUID + DataServerClient::getClientValueForKey(DataServerKey::UUID); +} + +void Profile::saveData(QSettings* settings) { + settings->beginGroup("Profile"); + + settings->setValue("username", _username); + settings->setValue("UUID", _uuid); + settings->setValue("faceModelURL", _faceModelURL); + + settings->endGroup(); +} + +void Profile::loadData(QSettings* settings) { + settings->beginGroup("Profile"); + + _username = settings->value("username").toString(); + _uuid = settings->value("UUID").toUuid(); + _faceModelURL = settings->value("faceModelURL").toUrl(); + + settings->endGroup(); +} \ No newline at end of file diff --git a/interface/src/avatar/Profile.h b/interface/src/avatar/Profile.h new file mode 100644 index 0000000000..02c8b0ad9e --- /dev/null +++ b/interface/src/avatar/Profile.h @@ -0,0 +1,39 @@ +// +// Profile.h +// hifi +// +// Created by Stephen Birarda on 10/8/13. +// Copyright (c) 2013 HighFidelity, Inc. All rights reserved. +// + +#ifndef __hifi__Profile__ +#define __hifi__Profile__ + +#include +#include +#include + +class Profile { +public: + Profile(); + + void setUsername(const QString& username); + QString& getUsername() { return _username; } + + void setUUID(const QUuid& uuid) { _uuid = uuid; } + QUuid& getUUID() { return _uuid; } + + void setFaceModelURL(const QUrl& faceModelURL) { _faceModelURL = faceModelURL; } + QUrl& getFaceModelURL() { return _faceModelURL; } + + void clear(); + + void saveData(QSettings* settings); + void loadData(QSettings* settings); +private: + QString _username; + QUuid _uuid; + QUrl _faceModelURL; +}; + +#endif /* defined(__hifi__Profile__) */