From bbdf4a12055c154fd2685ff007a6a8565b1803de Mon Sep 17 00:00:00 2001 From: stojce Date: Sat, 8 Feb 2014 01:10:26 +0100 Subject: [PATCH 01/10] Allow logged-in users to name their current location & orientation --- data-server/src/DataServer.cpp | 70 ++++++++++++++++++++ interface/CMakeLists.txt | 2 +- interface/src/DatagramProcessor.cpp | 3 + interface/src/Menu.cpp | 77 +++++++++++++++++++++- interface/src/Menu.h | 4 ++ interface/src/location/LocationManager.cpp | 26 ++++++++ interface/src/location/LocationManager.h | 37 +++++++++++ interface/src/location/NamedLocation.cpp | 46 +++++++++++++ interface/src/location/NamedLocation.h | 63 ++++++++++++++++++ libraries/shared/src/DataServerClient.cpp | 73 ++++++++++++++++++++ libraries/shared/src/DataServerClient.h | 12 +++- libraries/shared/src/PacketHeaders.h | 3 + 12 files changed, 410 insertions(+), 6 deletions(-) create mode 100644 interface/src/location/LocationManager.cpp create mode 100644 interface/src/location/LocationManager.h create mode 100644 interface/src/location/NamedLocation.cpp create mode 100644 interface/src/location/NamedLocation.h diff --git a/data-server/src/DataServer.cpp b/data-server/src/DataServer.cpp index 43fc52fb06..258afb755f 100644 --- a/data-server/src/DataServer.cpp +++ b/data-server/src/DataServer.cpp @@ -20,6 +20,11 @@ const quint16 DATA_SERVER_LISTEN_PORT = 3282; const char REDIS_HOSTNAME[] = "127.0.0.1"; const unsigned short REDIS_PORT = 6379; +const int ARGV_FIXED_INDEX_START = 2; + +const char REDIS_HASH_MULTIPLE_SET[] = "HMSET"; +const char REDIS_HASH_SET[] = "HSET"; +const char REDIS_HASH_GET_ALL[] = "HGETALL"; DataServer::DataServer(int argc, char* argv[]) : QCoreApplication(argc, argv), @@ -65,6 +70,71 @@ void DataServer::readPendingDatagrams() { PacketType requestType = packetTypeForPacket(receivedPacket); + if ((requestType == PacketTypeDataServerHashPut || requestType == PacketTypeDataServerHashGet) && + packetVersionMatch(receivedPacket)) { + + QDataStream packetStream(receivedPacket); + int numReceivedHeaderBytes = numBytesForPacketHeader(receivedPacket); + packetStream.skipRawData(numReceivedHeaderBytes); + + // pull the sequence number used for this packet + quint8 sequenceNumber = 0; + + packetStream >> sequenceNumber; + + // pull the UUID that we will need as part of the key + QString userString; + packetStream >> userString; + + if (requestType == PacketTypeDataServerHashPut) { + QString dataKey, dataValue; + QStringList redisCommandKeys, redisCommandValues; + + while(true) { + packetStream >> dataKey >> dataValue; + if (dataKey.isNull() || dataKey.isEmpty()) { + break; + } + redisAppendCommand(_redis, "%s %s %s %s", + REDIS_HASH_SET, + qPrintable(userString), + qPrintable(dataKey), + qPrintable(dataValue)); + }; + + redisReply* reply = NULL; + redisGetReply(_redis, (void **) &reply); + + if (reply->type == REDIS_REPLY_INTEGER && reply->integer == 0) { + QByteArray replyPacket = byteArrayWithPopluatedHeader(PacketTypeDataServerConfirm, _uuid); + replyPacket.append(sequenceNumber); + _socket.writeDatagram(replyPacket, senderSockAddr.getAddress(), senderSockAddr.getPort()); + } + + freeReplyObject(reply); + reply = NULL; + } else { + + redisReply* reply = (redisReply*) redisCommand(_redis, "%s %s", REDIS_HASH_GET_ALL, qPrintable(userString)); + + QByteArray sendPacket = byteArrayWithPopluatedHeader(PacketTypeDataServerHashSend, _uuid); + QDataStream sendPacketStream(&sendPacket, QIODevice::Append); + + sendPacketStream << sequenceNumber; + sendPacketStream << userString; + + if (reply->type == REDIS_REPLY_ARRAY && reply->elements > 0) { + for (int i = 0; i < reply->elements; i++) { + sendPacketStream << QString(reply->element[i]->str); + } + } + // reply back with the send packet + _socket.writeDatagram(sendPacket, senderSockAddr.getAddress(), senderSockAddr.getPort()); + freeReplyObject(reply); + reply = NULL; + } + } + if ((requestType == PacketTypeDataServerPut || requestType == PacketTypeDataServerGet) && packetVersionMatch(receivedPacket)) { diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 6af6ed478d..4c300f6fda 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -57,7 +57,7 @@ configure_file(InterfaceVersion.h.in ${PROJECT_BINARY_DIR}/includes/InterfaceVer # grab the implementation and header files from src dirs file(GLOB INTERFACE_SRCS src/*.cpp src/*.h) -foreach(SUBDIR avatar devices renderer ui starfield) +foreach(SUBDIR avatar devices renderer ui starfield location) file(GLOB_RECURSE SUBDIR_SRCS src/${SUBDIR}/*.cpp src/${SUBDIR}/*.h) set(INTERFACE_SRCS ${INTERFACE_SRCS} ${SUBDIR_SRCS}) endforeach(SUBDIR) diff --git a/interface/src/DatagramProcessor.cpp b/interface/src/DatagramProcessor.cpp index 24ec956c62..52e8b72ab2 100644 --- a/interface/src/DatagramProcessor.cpp +++ b/interface/src/DatagramProcessor.cpp @@ -116,7 +116,10 @@ void DatagramProcessor::processDatagrams() { } case PacketTypeDataServerGet: case PacketTypeDataServerPut: + case PacketTypeDataServerHashPut: + case PacketTypeDataServerHashGet: case PacketTypeDataServerSend: + case PacketTypeDataServerHashSend: case PacketTypeDataServerConfirm: DataServerClient::processMessageFromDataServer(incomingPacket); break; diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 67eaa8782c..3b2b09fcd7 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include @@ -114,7 +115,12 @@ Menu::Menu() : MenuOption::GoToLocation, Qt::CTRL | Qt::SHIFT | Qt::Key_L, this, - SLOT(goToLocation())); + SLOT(goToLocation())); + addActionToQMenuAndActionHash(fileMenu, + MenuOption::NameLocation, + Qt::CTRL | Qt::Key_N, + this, + SLOT(nameLocation())); addActionToQMenuAndActionHash(fileMenu, MenuOption::GoTo, Qt::Key_At, @@ -152,8 +158,9 @@ Menu::Menu() : addActionToQMenuAndActionHash(editMenu, MenuOption::CutVoxels, Qt::CTRL | Qt::Key_X, appInstance, SLOT(cutVoxels())); addActionToQMenuAndActionHash(editMenu, MenuOption::CopyVoxels, Qt::CTRL | Qt::Key_C, appInstance, SLOT(copyVoxels())); addActionToQMenuAndActionHash(editMenu, MenuOption::PasteVoxels, Qt::CTRL | Qt::Key_V, appInstance, SLOT(pasteVoxels())); - addActionToQMenuAndActionHash(editMenu, MenuOption::NudgeVoxels, Qt::CTRL | Qt::Key_N, appInstance, SLOT(nudgeVoxels())); - + // TODO: add new shortcut + addActionToQMenuAndActionHash(editMenu, MenuOption::NudgeVoxels, 0, appInstance, SLOT(nudgeVoxels())); + #ifdef __APPLE__ addActionToQMenuAndActionHash(editMenu, MenuOption::DeleteVoxels, Qt::Key_Backspace, appInstance, SLOT(deleteVoxels())); #else @@ -964,6 +971,70 @@ void Menu::goTo() { sendFakeEnterEvent(); } +void Menu::namedLocationCreated(LocationManager::LocationCreateResponse response, NamedLocation* location) { + + if (response == LocationManager::AlreadyExists) { + QMessageBox msgBox; + msgBox.setText("That name has been claimed by " + location->getCreatedBy() + ", try something else."); + msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); + msgBox.button(QMessageBox::Ok)->setText("Go to user"); + int ret = msgBox.exec(); + + if (ret == QMessageBox::Ok) { + DataServerClient::getValuesForKeysAndUserString( + QStringList() + << DataServerKey::Domain + << DataServerKey::Position + << DataServerKey::Orientation, + location->getCreatedBy(), + Application::getInstance()->getProfile()); + } + } +} + +void Menu::nameLocation() { + // check if user is logged in or show login dialog if not + Profile* profile = Application::getInstance()->getProfile(); + if (profile->getUsername().isNull()) { + QMessageBox msgBox; + msgBox.setText("We need to tie this location to your username."); + msgBox.setInformativeText("Please login first, then try naming the location again."); + msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); + msgBox.button(QMessageBox::Ok)->setText("Login"); + if (msgBox.exec() == QMessageBox::Ok) { + login(); + } + return; + } + + QInputDialog nameDialog(Application::getInstance()->getWindow()); + nameDialog.setWindowTitle("Name this location"); + nameDialog.setLabelText("Name this location, then share that name with others.\n" + "When they come here, they'll be in the same location and orientation\n" + "(wherever you are standing and looking now) as you.\n\n" + "Location name:"); + + nameDialog.setWindowFlags(Qt::Sheet); + nameDialog.resize((int) (nameDialog.parentWidget()->size().width() * 0.30), nameDialog.size().height()); + + if (nameDialog.exec() == QDialog::Accepted) { + + QString locationName = nameDialog.textValue().trimmed(); + if (locationName.isEmpty()) { + return; + } + + MyAvatar* myAvatar = Application::getInstance()->getAvatar(); + + LocationManager* manager = new LocationManager(); + connect(manager, + SIGNAL(creationCompleted(LocationManager::LocationCreateResponse, NamedLocation*)), + SLOT(namedLocationCreated(LocationManager::LocationCreateResponse, NamedLocation*))); + + manager->createNamedLocation(locationName, profile->getUsername(), myAvatar->getPosition(), myAvatar->getOrientation()); + } +} + void Menu::goToLocation() { MyAvatar* myAvatar = Application::getInstance()->getAvatar(); glm::vec3 avatarPos = myAvatar->getPosition(); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 5e49ca6fd1..08306f8dd0 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -15,6 +15,7 @@ #include #include +#include "location/LocationManager.h" enum FrustumDrawMode { FRUSTUM_DRAW_MODE_ALL, @@ -101,6 +102,7 @@ private slots: void editPreferences(); void goToDomain(); void goToLocation(); + void nameLocation(); void bandwidthDetailsClosed(); void voxelStatsDetailsClosed(); void lodToolsClosed(); @@ -111,6 +113,7 @@ private slots: void resetSwatchColors(); void showMetavoxelEditor(); void audioMuteToggled(); + void namedLocationCreated(LocationManager::LocationCreateResponse response, NamedLocation* location); private: static Menu* _instance; @@ -210,6 +213,7 @@ namespace MenuOption { const QString GlowMode = "Cycle Glow Mode"; const QString GoToDomain = "Go To Domain..."; const QString GoToLocation = "Go To Location..."; + const QString NameLocation = "Name this location"; const QString GoTo = "Go To..."; const QString ImportVoxels = "Import Voxels"; const QString ImportVoxelsClipboard = "Import Voxels to Clipboard"; diff --git a/interface/src/location/LocationManager.cpp b/interface/src/location/LocationManager.cpp new file mode 100644 index 0000000000..11a099ae80 --- /dev/null +++ b/interface/src/location/LocationManager.cpp @@ -0,0 +1,26 @@ +// +// LocationManager.cpp +// hifi +// +// Created by Stojce Slavkovski on 2/7/14. +// +// + +#include "LocationManager.h" + +void LocationManager::createNamedLocation(QString locationName, QString creator, glm::vec3 location, glm::quat orientation) { + _namedLocation = new NamedLocation(locationName, creator, location, orientation); + connect(_namedLocation, SIGNAL(dataReceived(bool)), SLOT(locationDataReceived(bool))); + DataServerClient::getHashFieldsForKey(DataServerKey::NamedLocation, _namedLocation->locationName(), _namedLocation); +} + +void LocationManager::locationDataReceived(bool locationExists) { + disconnect(_namedLocation, SIGNAL(dataReceived(bool)), this, SLOT(locationDataReceived(bool))); + if (locationExists) { + emit creationCompleted(AlreadyExists, _namedLocation); + } else { + DataServerClient::putHashFieldsForKey(DataServerKey::NamedLocation, _namedLocation->locationName(), _namedLocation); + emit creationCompleted(Created, _namedLocation); + } +} + diff --git a/interface/src/location/LocationManager.h b/interface/src/location/LocationManager.h new file mode 100644 index 0000000000..29a29b0496 --- /dev/null +++ b/interface/src/location/LocationManager.h @@ -0,0 +1,37 @@ +// +// LocationManager.h +// hifi +// +// Created by Stojce Slavkovski on 2/7/14. +// +// + +#ifndef __hifi__LocationManager__ +#define __hifi__LocationManager__ + +#include +#include "NamedLocation.h" + +class LocationManager : public QObject { + Q_OBJECT + +public: + enum LocationCreateResponse { + Created, + AlreadyExists + }; + + LocationManager() { }; + void createNamedLocation(QString locationName, QString creator, glm::vec3 location, glm::quat orientation); + +signals: + void creationCompleted(LocationManager::LocationCreateResponse response, NamedLocation* location); + +private: + NamedLocation* _namedLocation; + +private slots: + void locationDataReceived(bool locationExists); +}; + +#endif /* defined(__hifi__LocationManager__) */ diff --git a/interface/src/location/NamedLocation.cpp b/interface/src/location/NamedLocation.cpp new file mode 100644 index 0000000000..977f368091 --- /dev/null +++ b/interface/src/location/NamedLocation.cpp @@ -0,0 +1,46 @@ +// +// LocationManager.cpp +// hifi +// +// Created by Stojce Slavkovski on 2/1/14. +// +// + +#include "NamedLocation.h" + +// deserialize data +void NamedLocation::processDataServerResponse(const QString& userString, + const QStringList& keyList, + const QStringList& valueList) { + for (int i = 0; i < keyList.count(); i++) { + if (keyList[i] == "creator") { + _createdBy = valueList[i]; + } else if (keyList[i] == "location") { + QStringList locationCoords = valueList[i].split(","); + if (locationCoords.length() == 3) { + _location = glm::vec3(locationCoords[0].toLong(), locationCoords[1].toLong(), locationCoords[2].toLong()); + } + } else if (keyList[i] == "orientation") { + + QStringList orientationCoords = valueList[i].split(","); + if (orientationCoords.length() == 4) { + _orientation = glm::quat(orientationCoords[0].toLong(), + orientationCoords[1].toLong(), + orientationCoords[2].toLong(), + orientationCoords[3].toLong()); + } + } + } + + emit dataReceived(keyList.count() > 0); +} + +// serialize data +QHash NamedLocation::getHashData() { + QHash response; + qDebug() << QString::fromStdString(glm::to_string(_location)); + response["location"] = QString::number(_location.x) + "," + QString::number(_location.y) + "," + QString::number(_location.z); + response["creator"] = _createdBy; + response["orientation"] = QString::number(_orientation.x) + "," + QString::number(_orientation.y) + "," + QString::number(_orientation.z) + "," + QString::number(_orientation.w); + return response; +} \ No newline at end of file diff --git a/interface/src/location/NamedLocation.h b/interface/src/location/NamedLocation.h new file mode 100644 index 0000000000..ea315ebf9b --- /dev/null +++ b/interface/src/location/NamedLocation.h @@ -0,0 +1,63 @@ +// +// NamedLocation.h +// hifi +// +// Created by Stojce Slavkovski on 2/1/14. +// +// + +#ifndef __hifi__NamedLocation__ +#define __hifi__NamedLocation__ + +#include +#include +#include + +#include "DataServerClient.h" + +class NamedLocation : public QObject, public DataServerCallbackObject, public DataServerCallerObject { + Q_OBJECT + +public: + + NamedLocation(QString locationName, QString createdBy, glm::vec3 location, glm::quat orientation) { + _locationName = locationName; + _createdBy = createdBy; + _location = location; + _orientation = orientation; + } + + bool isEmpty() { return _locationName.isNull() || _locationName.isEmpty(); } + + // DataServerCallbackObject implementation + void processDataServerResponse(const QString& userString, const QStringList& keyList, const QStringList& valueList); + + // DataServerCallerObject implementation + QHash getHashData(); + + // properties >> + void setLocationName(QString locationName) { _locationName = locationName; } + QString locationName() { return _locationName; } + + void createdBy(QString createdBy) { _createdBy = createdBy; } + QString getCreatedBy() { return _createdBy; } + + void setLocation(glm::vec3 location) { _location = location; } + glm::vec3 location() { return _location; } + + void setOrientation(glm::quat orentation) { _orientation = orentation; } + glm::quat orientation() { return _orientation; } + // properties << + +signals: + void dataReceived(bool locationExists); + +private: + QString _locationName; + QString _createdBy; + glm::vec3 _location; + glm::quat _orientation; + +}; + +#endif /* defined(__hifi__NamedLocation__) */ diff --git a/libraries/shared/src/DataServerClient.cpp b/libraries/shared/src/DataServerClient.cpp index fd003aa3bb..3b6fe2dbf6 100644 --- a/libraries/shared/src/DataServerClient.cpp +++ b/libraries/shared/src/DataServerClient.cpp @@ -88,6 +88,44 @@ void DataServerClient::getValueForKeyAndUserString(const QString& key, const QSt getValuesForKeysAndUserString(QStringList(key), userString, callbackObject); } +void DataServerClient::getHashFieldsForKey(const QString serverKey, QString keyValue, DataServerCallbackObject* callbackObject) { + + QByteArray getPacket = byteArrayWithPopluatedHeader(PacketTypeDataServerHashGet); + QDataStream packetStream(&getPacket, QIODevice::Append); + packetStream << _sequenceNumber << serverKey + ":" + keyValue; + + // add the getPacket to our map of unconfirmed packets, will be deleted once we get a response from the nameserver + _unmatchedPackets.insert(_sequenceNumber, getPacket); + _callbackObjects.insert(_sequenceNumber, callbackObject); + + // send the get to the data server + NodeList::getInstance()->getNodeSocket().writeDatagram(getPacket, dataServerSockAddr().getAddress(), + dataServerSockAddr().getPort()); + _sequenceNumber++; +} + +void DataServerClient::putHashFieldsForKey(const QString serverKey, QString keyValue, DataServerCallerObject* callerObject) { + + QByteArray putPacket = byteArrayWithPopluatedHeader(PacketTypeDataServerHashPut); + QDataStream packetStream(&putPacket, QIODevice::Append); + packetStream << _sequenceNumber << serverKey + ":" + keyValue; + + QHash hashData(callerObject->getHashData()); + QHash::const_iterator i = hashData.constBegin(); + while (i != hashData.constEnd()) { + packetStream << i.key() << i.value(); + ++i; + } + // add the getPacket to our map of unconfirmed packets, will be deleted once we get a response from the nameserver + _unmatchedPackets.insert(_sequenceNumber, putPacket); + + // send this put request to the data server + NodeList::getInstance()->getNodeSocket().writeDatagram(putPacket, dataServerSockAddr().getAddress(), + dataServerSockAddr().getPort()); + + _sequenceNumber++; +} + void DataServerClient::processConfirmFromDataServer(const QByteArray& packet) { removeMatchedPacketFromMap(packet); } @@ -113,12 +151,47 @@ void DataServerClient::processSendFromDataServer(const QByteArray& packet) { valueListString.split(MULTI_KEY_VALUE_SEPARATOR)); } } +void DataServerClient::processHashSendFromDataServer(const QByteArray& packet) { + + // pull the user string from the packet so we know who to associate this with + QDataStream packetStream(packet); + packetStream.skipRawData(numBytesForPacketHeader(packet)); + + quint8 sequenceNumber = 0; + packetStream >> sequenceNumber; + + if (_callbackObjects.find(sequenceNumber) != _callbackObjects.end()) { + // remove the packet from our two maps, it's matched + DataServerCallbackObject* callbackObject = _callbackObjects.take(sequenceNumber); + _unmatchedPackets.remove(sequenceNumber); + + QString userString, keyString, valueString; + QStringList keyList, valueList; + + packetStream >> userString; + + while(true) { + packetStream >> keyString; + packetStream >> valueString; + if (keyString.isNull() || keyString.isEmpty()) { + break; + } + + keyList << keyString; + valueList << valueString; + } + callbackObject->processDataServerResponse(userString, keyList, valueList); + } +} void DataServerClient::processMessageFromDataServer(const QByteArray& packet) { switch (packetTypeForPacket(packet)) { case PacketTypeDataServerSend: processSendFromDataServer(packet); break; + case PacketTypeDataServerHashSend: + processHashSendFromDataServer(packet); + break; case PacketTypeDataServerConfirm: processConfirmFromDataServer(packet); break; diff --git a/libraries/shared/src/DataServerClient.h b/libraries/shared/src/DataServerClient.h index 0360576645..d2f846cc6b 100644 --- a/libraries/shared/src/DataServerClient.h +++ b/libraries/shared/src/DataServerClient.h @@ -18,6 +18,11 @@ #include "HifiSockAddr.h" +class DataServerCallerObject { +public: + virtual QHash getHashData() = 0; +}; + class DataServerCallbackObject { public: virtual void processDataServerResponse(const QString& userString, const QStringList& keyList, const QStringList& valueList) = 0; @@ -35,14 +40,16 @@ public: static void getValueForKeyAndUUID(const QString& key, const QUuid& uuid, DataServerCallbackObject* callbackObject); static void getValuesForKeysAndUUID(const QStringList& keys, const QUuid& uuid, DataServerCallbackObject* callbackObject); static void getValuesForKeysAndUserString(const QStringList& keys, const QString& userString, - DataServerCallbackObject* callbackObject); - + DataServerCallbackObject* callbackObject); + static void getHashFieldsForKey(const QString serverKey, QString keyValue, DataServerCallbackObject* callbackObject); + static void putHashFieldsForKey(const QString serverKey, QString keyValue, DataServerCallerObject* callerObject); static void processMessageFromDataServer(const QByteArray& packet); static void resendUnmatchedPackets(); private: static void processConfirmFromDataServer(const QByteArray& packet); static void processSendFromDataServer(const QByteArray& packet); + static void processHashSendFromDataServer(const QByteArray& packet); static void removeMatchedPacketFromMap(const QByteArray& packet); static QMap _unmatchedPackets; @@ -57,6 +64,7 @@ namespace DataServerKey { const QString Position = "position"; const QString Orientation = "orientation"; const QString UUID = "uuid"; + const QString NamedLocation = "namedlocation"; } #endif /* defined(__hifi__DataServerClient__) */ diff --git a/libraries/shared/src/PacketHeaders.h b/libraries/shared/src/PacketHeaders.h index 543dce0504..84f074b0a7 100644 --- a/libraries/shared/src/PacketHeaders.h +++ b/libraries/shared/src/PacketHeaders.h @@ -36,6 +36,9 @@ enum PacketType { PacketTypeCreateAssignment, PacketTypeDataServerPut, PacketTypeDataServerGet, + PacketTypeDataServerHashPut, + PacketTypeDataServerHashGet, + PacketTypeDataServerHashSend, PacketTypeDataServerSend, PacketTypeDataServerConfirm, PacketTypeVoxelQuery, From d1c8a693876809d3f9b305b04e52d0c883e68991 Mon Sep 17 00:00:00 2001 From: stojce Date: Sat, 8 Feb 2014 09:25:49 +0100 Subject: [PATCH 02/10] New DataServer features --- data-server/src/DataServer.cpp | 6 ++++-- interface/src/Menu.cpp | 2 +- libraries/shared/src/NodeList.cpp | 1 + libraries/shared/src/PacketHeaders.cpp | 3 +++ 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/data-server/src/DataServer.cpp b/data-server/src/DataServer.cpp index 429a2ec331..16a274607d 100644 --- a/data-server/src/DataServer.cpp +++ b/data-server/src/DataServer.cpp @@ -69,9 +69,9 @@ void DataServer::readPendingDatagrams() { senderSockAddr.getAddressPointer(), senderSockAddr.getPortPointer()); PacketType requestType = packetTypeForPacket(receivedPacket); - + if ((requestType == PacketTypeDataServerHashPut || requestType == PacketTypeDataServerHashGet) && - packetVersionMatch(receivedPacket)) { + receivedPacket[numBytesArithmeticCodingFromBuffer(receivedPacket.data())] == versionForPacketType(requestType)) { QDataStream packetStream(receivedPacket); int numReceivedHeaderBytes = numBytesForPacketHeader(receivedPacket); @@ -95,6 +95,7 @@ void DataServer::readPendingDatagrams() { if (dataKey.isNull() || dataKey.isEmpty()) { break; } + redisAppendCommand(_redis, "%s %s %s %s", REDIS_HASH_SET, qPrintable(userString), @@ -127,6 +128,7 @@ void DataServer::readPendingDatagrams() { for (int i = 0; i < reply->elements; i++) { sendPacketStream << QString(reply->element[i]->str); } + qDebug() << "Found data for key" << userString; } // reply back with the send packet _socket.writeDatagram(sendPacket, senderSockAddr.getAddress(), senderSockAddr.getPort()); diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 1d3c1cf589..3f7fe8385b 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -998,7 +998,7 @@ void Menu::namedLocationCreated(LocationManager::LocationCreateResponse response void Menu::nameLocation() { // check if user is logged in or show login dialog if not Profile* profile = Application::getInstance()->getProfile(); - if (profile->getUsername().isNull()) { + if (profile->getUUID().isNull()) { QMessageBox msgBox; msgBox.setText("We need to tie this location to your username."); msgBox.setInformativeText("Please login first, then try naming the location again."); diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index 2672f3b27b..ca378207df 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -97,6 +97,7 @@ bool NodeList::packetVersionAndHashMatch(const QByteArray& packet) { const QSet NON_VERIFIED_PACKETS = QSet() << PacketTypeDomainList << PacketTypeDomainListRequest << PacketTypeStunResponse << PacketTypeDataServerConfirm << PacketTypeDataServerGet << PacketTypeDataServerPut << PacketTypeDataServerSend + << PacketTypeDataServerHashGet << PacketTypeDataServerHashPut << PacketTypeDataServerHashSend << PacketTypeCreateAssignment << PacketTypeRequestAssignment; if (!NON_VERIFIED_PACKETS.contains(packetTypeForPacket(packet))) { diff --git a/libraries/shared/src/PacketHeaders.cpp b/libraries/shared/src/PacketHeaders.cpp index b46a57d4aa..168d6700c1 100644 --- a/libraries/shared/src/PacketHeaders.cpp +++ b/libraries/shared/src/PacketHeaders.cpp @@ -56,6 +56,9 @@ PacketVersion versionForPacketType(PacketType type) { case PacketTypeDataServerPut: case PacketTypeDataServerConfirm: case PacketTypeDataServerSend: + case PacketTypeDataServerHashPut: + case PacketTypeDataServerHashGet: + case PacketTypeDataServerHashSend: return 1; default: return 0; From 95d0128c74bf0436c9e750238b335785e32c2fd7 Mon Sep 17 00:00:00 2001 From: stojce Date: Wed, 12 Mar 2014 18:53:25 +0100 Subject: [PATCH 03/10] Using new API client --- data-server/src/DataServer.cpp | 263 --------------------- interface/src/Menu.cpp | 78 +++++- interface/src/Menu.h | 4 + interface/src/location/LocationManager.cpp | 48 +++- interface/src/location/LocationManager.h | 21 +- interface/src/location/NamedLocation.cpp | 100 +++++--- interface/src/location/NamedLocation.h | 33 ++- libraries/shared/src/AccountManager.h | 3 +- 8 files changed, 213 insertions(+), 337 deletions(-) delete mode 100644 data-server/src/DataServer.cpp diff --git a/data-server/src/DataServer.cpp b/data-server/src/DataServer.cpp deleted file mode 100644 index 16a274607d..0000000000 --- a/data-server/src/DataServer.cpp +++ /dev/null @@ -1,263 +0,0 @@ -// -// DataServer.cpp -// hifi -// -// Created by Stephen Birarda on 1/20/2014. -// Copyright (c) 2014 HighFidelity, Inc. All rights reserved. -// - -#include -#include -#include - -#include -#include -#include - -#include "DataServer.h" - -const quint16 DATA_SERVER_LISTEN_PORT = 3282; - -const char REDIS_HOSTNAME[] = "127.0.0.1"; -const unsigned short REDIS_PORT = 6379; -const int ARGV_FIXED_INDEX_START = 2; - -const char REDIS_HASH_MULTIPLE_SET[] = "HMSET"; -const char REDIS_HASH_SET[] = "HSET"; -const char REDIS_HASH_GET_ALL[] = "HGETALL"; - -DataServer::DataServer(int argc, char* argv[]) : - QCoreApplication(argc, argv), - _socket(), - _redis(NULL), - _uuid(QUuid::createUuid()) -{ - _socket.bind(QHostAddress::Any, DATA_SERVER_LISTEN_PORT); - - connect(&_socket, &QUdpSocket::readyRead, this, &DataServer::readPendingDatagrams); - - _redis = redisConnect(REDIS_HOSTNAME, REDIS_PORT); - - if (_redis && _redis->err) { - if (_redis) { - qDebug() << "Redis connection error:" << _redis->errstr; - } else { - qDebug("Redis connection error - can't allocate redis context."); - } - - // couldn't connect to redis, bail out - QMetaObject::invokeMethod(this, "quit", Qt::QueuedConnection); - } -} - -DataServer::~DataServer() { - // disconnect from redis and free the context - if (_redis) { - redisFree(_redis); - } -} - -const int MAX_PACKET_SIZE = 1500; - -void DataServer::readPendingDatagrams() { - QByteArray receivedPacket; - HifiSockAddr senderSockAddr; - - while (_socket.hasPendingDatagrams()) { - receivedPacket.resize(_socket.pendingDatagramSize()); - _socket.readDatagram(receivedPacket.data(), _socket.pendingDatagramSize(), - senderSockAddr.getAddressPointer(), senderSockAddr.getPortPointer()); - - PacketType requestType = packetTypeForPacket(receivedPacket); - - if ((requestType == PacketTypeDataServerHashPut || requestType == PacketTypeDataServerHashGet) && - receivedPacket[numBytesArithmeticCodingFromBuffer(receivedPacket.data())] == versionForPacketType(requestType)) { - - QDataStream packetStream(receivedPacket); - int numReceivedHeaderBytes = numBytesForPacketHeader(receivedPacket); - packetStream.skipRawData(numReceivedHeaderBytes); - - // pull the sequence number used for this packet - quint8 sequenceNumber = 0; - - packetStream >> sequenceNumber; - - // pull the UUID that we will need as part of the key - QString userString; - packetStream >> userString; - - if (requestType == PacketTypeDataServerHashPut) { - QString dataKey, dataValue; - QStringList redisCommandKeys, redisCommandValues; - - while(true) { - packetStream >> dataKey >> dataValue; - if (dataKey.isNull() || dataKey.isEmpty()) { - break; - } - - redisAppendCommand(_redis, "%s %s %s %s", - REDIS_HASH_SET, - qPrintable(userString), - qPrintable(dataKey), - qPrintable(dataValue)); - }; - - redisReply* reply = NULL; - redisGetReply(_redis, (void **) &reply); - - if (reply->type == REDIS_REPLY_INTEGER && reply->integer == 0) { - QByteArray replyPacket = byteArrayWithPopluatedHeader(PacketTypeDataServerConfirm, _uuid); - replyPacket.append(sequenceNumber); - _socket.writeDatagram(replyPacket, senderSockAddr.getAddress(), senderSockAddr.getPort()); - } - - freeReplyObject(reply); - reply = NULL; - } else { - - redisReply* reply = (redisReply*) redisCommand(_redis, "%s %s", REDIS_HASH_GET_ALL, qPrintable(userString)); - - QByteArray sendPacket = byteArrayWithPopluatedHeader(PacketTypeDataServerHashSend, _uuid); - QDataStream sendPacketStream(&sendPacket, QIODevice::Append); - - sendPacketStream << sequenceNumber; - sendPacketStream << userString; - - if (reply->type == REDIS_REPLY_ARRAY && reply->elements > 0) { - for (int i = 0; i < reply->elements; i++) { - sendPacketStream << QString(reply->element[i]->str); - } - qDebug() << "Found data for key" << userString; - } - // reply back with the send packet - _socket.writeDatagram(sendPacket, senderSockAddr.getAddress(), senderSockAddr.getPort()); - freeReplyObject(reply); - reply = NULL; - } - } - - if ((requestType == PacketTypeDataServerPut || requestType == PacketTypeDataServerGet) && - receivedPacket[numBytesArithmeticCodingFromBuffer(receivedPacket.data())] == versionForPacketType(requestType)) { - - QDataStream packetStream(receivedPacket); - int numReceivedHeaderBytes = numBytesForPacketHeader(receivedPacket); - packetStream.skipRawData(numReceivedHeaderBytes); - - // pull the sequence number used for this packet - quint8 sequenceNumber = 0; - - packetStream >> sequenceNumber; - - // pull the UUID that we will need as part of the key - QString userString; - packetStream >> userString; - QUuid parsedUUID(userString); - - if (parsedUUID.isNull()) { - // we failed to parse a UUID, this means the user has sent us a username - - // ask redis for the UUID for this user - redisReply* reply = (redisReply*) redisCommand(_redis, "GET user:%s", qPrintable(userString)); - - if (reply->type == REDIS_REPLY_STRING) { - parsedUUID = QUuid(QString(reply->str)); - } - - if (!parsedUUID.isNull()) { - qDebug() << "Found UUID" << parsedUUID << "for username" << userString; - } else { - qDebug() << "Failed UUID lookup for username" << userString; - } - - freeReplyObject(reply); - reply = NULL; - } - - if (!parsedUUID.isNull()) { - if (requestType == PacketTypeDataServerPut) { - - // pull the key and value that specifies the data the user is putting/getting - QString dataKey, dataValue; - - packetStream >> dataKey >> dataValue; - - qDebug("Sending command to redis: SET uuid:%s:%s %s", - qPrintable(uuidStringWithoutCurlyBraces(parsedUUID)), - qPrintable(dataKey), qPrintable(dataValue)); - - redisReply* reply = (redisReply*) redisCommand(_redis, "SET uuid:%s:%s %s", - qPrintable(uuidStringWithoutCurlyBraces(parsedUUID)), - qPrintable(dataKey), qPrintable(dataValue)); - - if (reply->type == REDIS_REPLY_STATUS && strcmp("OK", reply->str) == 0) { - // if redis stored the value successfully reply back with a confirm - // which is a reply packet with the sequence number - QByteArray replyPacket = byteArrayWithPopluatedHeader(PacketTypeDataServerConfirm, _uuid); - - replyPacket.append(sequenceNumber); - - _socket.writeDatagram(replyPacket, senderSockAddr.getAddress(), senderSockAddr.getPort()); - } - - freeReplyObject(reply); - } else { - // setup a send packet with the returned data - // leverage the packetData sent by overwriting and appending - QByteArray sendPacket = byteArrayWithPopluatedHeader(PacketTypeDataServerSend, _uuid); - QDataStream sendPacketStream(&sendPacket, QIODevice::Append); - - sendPacketStream << sequenceNumber; - - // pull the key list that specifies the data the user is putting/getting - QString keyListString; - packetStream >> keyListString; - - if (keyListString != "uuid") { - - // copy the parsed UUID - sendPacketStream << uuidStringWithoutCurlyBraces(parsedUUID); - - const char MULTI_KEY_VALUE_SEPARATOR = '|'; - - // append the keyListString back to the sendPacket - sendPacketStream << keyListString; - - QStringList keyList = keyListString.split(MULTI_KEY_VALUE_SEPARATOR); - QStringList valueList; - - foreach (const QString& dataKey, keyList) { - qDebug("Sending command to redis: GET uuid:%s:%s", - qPrintable(uuidStringWithoutCurlyBraces(parsedUUID)), - qPrintable(dataKey)); - redisReply* reply = (redisReply*) redisCommand(_redis, "GET uuid:%s:%s", - qPrintable(uuidStringWithoutCurlyBraces(parsedUUID)), - qPrintable(dataKey)); - - if (reply->len) { - // copy the value that redis returned - valueList << QString(reply->str); - } else { - // didn't find a value - insert a space - valueList << QChar(' '); - } - - freeReplyObject(reply); - } - - // append the value QStringList using the right separator - sendPacketStream << valueList.join(MULTI_KEY_VALUE_SEPARATOR); - } else { - // user was asking for their UUID - sendPacketStream << userString; - sendPacketStream << QString("uuid"); - sendPacketStream << uuidStringWithoutCurlyBraces(parsedUUID); - } - - // reply back with the send packet - _socket.writeDatagram(sendPacket, senderSockAddr.getAddress(), senderSockAddr.getPort()); - } - } - } - } -} diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 0674826342..5224d234fb 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -115,13 +116,18 @@ Menu::Menu() : addActionToQMenuAndActionHash(fileMenu, MenuOption::GoToDomain, Qt::CTRL | Qt::Key_D, - this, - SLOT(goToDomainDialog())); + this, + SLOT(goToDomainDialog())); addActionToQMenuAndActionHash(fileMenu, MenuOption::GoToLocation, Qt::CTRL | Qt::SHIFT | Qt::Key_L, - this, - SLOT(goToLocation())); + this, + SLOT(goToLocation())); + addActionToQMenuAndActionHash(fileMenu, + MenuOption::NameLocation, + Qt::CTRL | Qt::Key_N, + this, + SLOT(nameLocation())); addActionToQMenuAndActionHash(fileMenu, MenuOption::GoTo, Qt::Key_At, @@ -400,6 +406,7 @@ void Menu::saveSettings(QSettings* settings) { scanMenuBar(&saveAction, settings); Application::getInstance()->getAvatar()->saveData(settings); NodeList::getInstance()->saveData(settings); + } void Menu::importSettings() { @@ -959,6 +966,69 @@ void Menu::goToLocation() { sendFakeEnterEvent(); } +void Menu::namedLocationCreated(LocationManager::NamedLocationCreateResponse response, NamedLocation* location) { + + if (response == LocationManager::Created) { + return; + } + + QMessageBox msgBox; + switch (response) { + case LocationManager::AlreadyExists: + msgBox.setText("That name has been already claimed, try something else."); + break; + default: + msgBox.setText("An unexpected error has occurred, please try again later."); + break; + } + + msgBox.exec(); +} + +void Menu::nameLocation() { + // check if user is logged in or show login dialog if not + + AccountManager& accountManager = AccountManager::getInstance(); + if (!accountManager.isLoggedIn() && 1 > 2) { + QMessageBox msgBox; + msgBox.setText("We need to tie this location to your username."); + msgBox.setInformativeText("Please login first, then try naming the location again."); + msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); + msgBox.button(QMessageBox::Ok)->setText("Login"); + if (msgBox.exec() == QMessageBox::Ok) { + loginForCurrentDomain(); + } + + return; + } + + QInputDialog nameDialog(Application::getInstance()->getWindow()); + nameDialog.setWindowTitle("Name this location"); + nameDialog.setLabelText("Name this location, then share that name with others.\n" + "When they come here, they'll be in the same location and orientation\n" + "(wherever you are standing and looking now) as you.\n\n" + "Location name:"); + + nameDialog.setWindowFlags(Qt::Sheet); + nameDialog.resize((int) (nameDialog.parentWidget()->size().width() * 0.30), nameDialog.size().height()); + + if (nameDialog.exec() == QDialog::Accepted) { + + QString locationName = nameDialog.textValue().trimmed(); + if (locationName.isEmpty()) { + return; + } + + MyAvatar* myAvatar = Application::getInstance()->getAvatar(); + LocationManager* manager = new LocationManager(); + connect(manager, &LocationManager::creationCompleted, this, &Menu::namedLocationCreated); + NamedLocation* location = new NamedLocation(locationName, + myAvatar->getPosition(), myAvatar->getOrientation(), + NodeList::getInstance()->getDomainInfo().getHostname()); + manager->createNamedLocation(location); + } +} + void Menu::pasteToVoxel() { QInputDialog pasteToOctalCodeDialog(Application::getInstance()->getWindow()); pasteToOctalCodeDialog.setWindowTitle("Paste to Voxel"); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 204b93dd4a..d701861cf1 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -17,6 +17,7 @@ #include #include #include +#include "location/LocationManager.h" const float ADJUST_LOD_DOWN_FPS = 40.0; const float ADJUST_LOD_UP_FPS = 55.0; @@ -134,6 +135,7 @@ private slots: void editPreferences(); void goToDomainDialog(); void goToLocation(); + void nameLocation(); void bandwidthDetailsClosed(); void voxelStatsDetailsClosed(); void lodToolsClosed(); @@ -141,6 +143,7 @@ private slots: void runTests(); void showMetavoxelEditor(); void audioMuteToggled(); + void namedLocationCreated(LocationManager::NamedLocationCreateResponse response, NamedLocation* location); private: static Menu* _instance; @@ -241,6 +244,7 @@ namespace MenuOption { const QString GlowMode = "Cycle Glow Mode"; const QString GoToDomain = "Go To Domain..."; const QString GoToLocation = "Go To Location..."; + const QString NameLocation = "Name this location"; const QString GoTo = "Go To..."; const QString IncreaseAvatarSize = "Increase Avatar Size"; const QString IncreaseVoxelSize = "Increase Voxel Size"; diff --git a/interface/src/location/LocationManager.cpp b/interface/src/location/LocationManager.cpp index f57ed0f48d..0588c66818 100644 --- a/interface/src/location/LocationManager.cpp +++ b/interface/src/location/LocationManager.cpp @@ -8,19 +8,47 @@ #include "LocationManager.h" -void LocationManager::createNamedLocation(QString locationName, QString creator, glm::vec3 location, glm::quat orientation) { - _namedLocation = new NamedLocation(locationName, creator, location, orientation); - connect(_namedLocation, SIGNAL(dataReceived(bool)), SLOT(locationDataReceived(bool))); - // DataServerClient::getHashFieldsForKey(DataServerKey::NamedLocation, _namedLocation->locationName(), _namedLocation); +const QString GET_USER_ADDRESS = "/api/v1/users/%1/address"; +const QString GET_PLACE_ADDRESS = "/api/v1/places/%1/address"; +const QString GET_ADDRESSES = "/api/v1/addresses/%1/address"; +const QString POST_PLACE_CREATE = "/api/v1/places/"; + +LocationManager& LocationManager::getInstance() { + static LocationManager sharedInstance; + return sharedInstance; } -void LocationManager::locationDataReceived(bool locationExists) { - disconnect(_namedLocation, SIGNAL(dataReceived(bool)), this, SLOT(locationDataReceived(bool))); - if (locationExists) { - emit creationCompleted(AlreadyExists, _namedLocation); +void LocationManager::namedLocationDataReceived(const QJsonObject& data) { + if (data.isEmpty()) { + return; + } + + qDebug() << data; + if (data.contains("status") && data["status"].toString() == "success") { + NamedLocation* location = new NamedLocation(data["data"].toObject()); + emit creationCompleted(LocationManager::Created, location); } else { - // DataServerClient::putHashFieldsForKey(DataServerKey::NamedLocation, _namedLocation->locationName(), _namedLocation); - emit creationCompleted(Created, _namedLocation); + emit creationCompleted(LocationManager::AlreadyExists, NULL); } } +void LocationManager::errorDataReceived(QNetworkReply::NetworkError error, const QString& message) { + emit creationCompleted(LocationManager::SystemError, NULL); +} + +void LocationManager::createNamedLocation(NamedLocation* namedLocation) { + AccountManager& accountManager = AccountManager::getInstance(); + if (accountManager.isLoggedIn()) { + JSONCallbackParameters callbackParams; + callbackParams.jsonCallbackReceiver = this; + callbackParams.jsonCallbackMethod = "namedLocationDataReceived"; + callbackParams.errorCallbackReceiver = this; + callbackParams.errorCallbackMethod = "errorDataReceived"; + + qDebug() << namedLocation->toJsonString(); + accountManager.authenticatedRequest(POST_PLACE_CREATE, QNetworkAccessManager::PostOperation, + callbackParams, namedLocation->toJsonString().toUtf8()); + } +} + + diff --git a/interface/src/location/LocationManager.h b/interface/src/location/LocationManager.h index 29a29b0496..4282d0e795 100644 --- a/interface/src/location/LocationManager.h +++ b/interface/src/location/LocationManager.h @@ -11,27 +11,32 @@ #include #include "NamedLocation.h" +#include "AccountManager.h" class LocationManager : public QObject { Q_OBJECT public: - enum LocationCreateResponse { + static LocationManager& getInstance(); + + enum NamedLocationCreateResponse { Created, - AlreadyExists + AlreadyExists, + SystemError }; LocationManager() { }; - void createNamedLocation(QString locationName, QString creator, glm::vec3 location, glm::quat orientation); + void createNamedLocation(NamedLocation* namedLocation); + + void goTo(QString destination); + void goToUser(QString userName); signals: - void creationCompleted(LocationManager::LocationCreateResponse response, NamedLocation* location); - -private: - NamedLocation* _namedLocation; + void creationCompleted(LocationManager::NamedLocationCreateResponse response, NamedLocation* location); private slots: - void locationDataReceived(bool locationExists); + void namedLocationDataReceived(const QJsonObject& data); + void errorDataReceived(QNetworkReply::NetworkError error, const QString& message); }; #endif /* defined(__hifi__LocationManager__) */ diff --git a/interface/src/location/NamedLocation.cpp b/interface/src/location/NamedLocation.cpp index 977f368091..af96794fd0 100644 --- a/interface/src/location/NamedLocation.cpp +++ b/interface/src/location/NamedLocation.cpp @@ -8,39 +8,73 @@ #include "NamedLocation.h" -// deserialize data -void NamedLocation::processDataServerResponse(const QString& userString, - const QStringList& keyList, - const QStringList& valueList) { - for (int i = 0; i < keyList.count(); i++) { - if (keyList[i] == "creator") { - _createdBy = valueList[i]; - } else if (keyList[i] == "location") { - QStringList locationCoords = valueList[i].split(","); - if (locationCoords.length() == 3) { - _location = glm::vec3(locationCoords[0].toLong(), locationCoords[1].toLong(), locationCoords[2].toLong()); - } - } else if (keyList[i] == "orientation") { - - QStringList orientationCoords = valueList[i].split(","); - if (orientationCoords.length() == 4) { - _orientation = glm::quat(orientationCoords[0].toLong(), - orientationCoords[1].toLong(), - orientationCoords[2].toLong(), - orientationCoords[3].toLong()); - } - } - } - - emit dataReceived(keyList.count() > 0); +const QString JSON_FORMAT = "{\"address\":{\"position\":\"%1,%2,%3\"," + "\"orientation\":\"%4,%5,%6,%7\",\"domain\":\"%8\"},\"name\":\"%9\"}"; + +QString NamedLocation::toJsonString() { + return JSON_FORMAT.arg(QString::number(_location.x), + QString::number(_location.y), + QString::number(_location.z), + QString::number(_orientation.w), + QString::number(_orientation.x), + QString::number(_orientation.y), + QString::number(_orientation.z), + _domain, + _locationName); } -// serialize data -QHash NamedLocation::getHashData() { - QHash response; - qDebug() << QString::fromStdString(glm::to_string(_location)); - response["location"] = QString::number(_location.x) + "," + QString::number(_location.y) + "," + QString::number(_location.z); - response["creator"] = _createdBy; - response["orientation"] = QString::number(_orientation.x) + "," + QString::number(_orientation.y) + "," + QString::number(_orientation.z) + "," + QString::number(_orientation.w); - return response; +NamedLocation::NamedLocation(const QJsonObject jsonData) { + + bool hasProperties; + + if (jsonData.contains("name")) { + hasProperties = true; + _locationName = jsonData["name"].toString(); + } + + if (jsonData.contains("username")) { + hasProperties = true; + _createdBy = jsonData["username"].toString(); + } + + if (jsonData.contains("domain")) { + hasProperties = true; + _domain = jsonData["domain"].toString(); + } + + // parse position + if (jsonData.contains("position")) { + hasProperties = true; + const int NUMBER_OF_POSITION_ITEMS = 3; + const int X_ITEM = 0; + const int Y_ITEM = 1; + const int Z_ITEM = 2; + + QStringList coordinateItems = jsonData["position"].toString().split(",", QString::SkipEmptyParts); + if (coordinateItems.size() == NUMBER_OF_POSITION_ITEMS) { + double x = coordinateItems[X_ITEM].trimmed().toDouble(); + double y = coordinateItems[Y_ITEM].trimmed().toDouble(); + double z = coordinateItems[Z_ITEM].trimmed().toDouble(); + _location = glm::vec3(x, y, z); + } + } + + // parse orientation + if (jsonData.contains("orientation")) { + hasProperties = true; + QStringList orientationItems = jsonData["orientation"] .toString().split(",", QString::SkipEmptyParts); + const int NUMBER_OF_ORIENTATION_ITEMS = 4; + const int W_ITEM = 0; + const int X_ITEM = 1; + const int Y_ITEM = 2; + const int Z_ITEM = 3; + + if (orientationItems.size() == NUMBER_OF_ORIENTATION_ITEMS) { + double w = orientationItems[W_ITEM].trimmed().toDouble(); + double x = orientationItems[X_ITEM].trimmed().toDouble(); + double y = orientationItems[Y_ITEM].trimmed().toDouble(); + double z = orientationItems[Z_ITEM].trimmed().toDouble(); + _orientation = glm::quat(w, x, y, z); + } + } } \ No newline at end of file diff --git a/interface/src/location/NamedLocation.h b/interface/src/location/NamedLocation.h index ba3c532317..4bc8c2e2ad 100644 --- a/interface/src/location/NamedLocation.h +++ b/interface/src/location/NamedLocation.h @@ -13,50 +13,47 @@ #include #include -// #include "DataServerClient.h" +#include -class NamedLocation : public QObject { //, public DataServerCallbackObject, public DataServerCallerObject { +class NamedLocation : public QObject { Q_OBJECT public: - - NamedLocation(QString locationName, QString createdBy, glm::vec3 location, glm::quat orientation) { + NamedLocation(QString locationName, glm::vec3 location, glm::quat orientation, QString domain) { _locationName = locationName; - _createdBy = createdBy; _location = location; _orientation = orientation; + _domain = domain; } + NamedLocation(const QJsonObject jsonData); + + QString toJsonString(); + bool isEmpty() { return _locationName.isNull() || _locationName.isEmpty(); } - // DataServerCallbackObject implementation - void processDataServerResponse(const QString& userString, const QStringList& keyList, const QStringList& valueList); - - // DataServerCallerObject implementation - QHash getHashData(); - - // properties >> void setLocationName(QString locationName) { _locationName = locationName; } QString locationName() { return _locationName; } - - void createdBy(QString createdBy) { _createdBy = createdBy; } - QString getCreatedBy() { return _createdBy; } - + void setLocation(glm::vec3 location) { _location = location; } glm::vec3 location() { return _location; } void setOrientation(glm::quat orentation) { _orientation = orentation; } glm::quat orientation() { return _orientation; } - // properties << - + + void setDomain(QString domain) { _domain = domain; } + QString domain() { return _domain; } + signals: void dataReceived(bool locationExists); private: + QString _locationName; QString _createdBy; glm::vec3 _location; glm::quat _orientation; + QString _domain; }; diff --git a/libraries/shared/src/AccountManager.h b/libraries/shared/src/AccountManager.h index 8b3c6b362c..b0797e78ca 100644 --- a/libraries/shared/src/AccountManager.h +++ b/libraries/shared/src/AccountManager.h @@ -50,8 +50,9 @@ public: Q_INVOKABLE bool checkAndSignalForAccessToken(); void requestAccessToken(const QString& login, const QString& password); - + QString getUsername() const { return _accountInfo.getUsername(); } + QString getAccessToken() const { return _accountInfo.getAccessToken().token; } void destroy() { delete _networkAccessManager; } From fd201c450bb48f79f79f7c0ee24a72907022ba79 Mon Sep 17 00:00:00 2001 From: stojce Date: Wed, 12 Mar 2014 23:02:21 +0100 Subject: [PATCH 04/10] Multiple destinations implementation --- interface/interface_en.ts | 8 +- interface/src/Menu.cpp | 112 ++++---------- interface/src/Menu.h | 1 + interface/src/location/LocationManager.cpp | 169 ++++++++++++++++++++- interface/src/location/LocationManager.h | 17 ++- 5 files changed, 214 insertions(+), 93 deletions(-) diff --git a/interface/interface_en.ts b/interface/interface_en.ts index a8f78cd36e..20d7a74c09 100644 --- a/interface/interface_en.ts +++ b/interface/interface_en.ts @@ -113,18 +113,18 @@ Menu - + Open .ini config file - - + + Text files (*.ini) - + Save .ini config file diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 6845ab2064..a11692ad12 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -37,6 +37,7 @@ #include "InfoView.h" #include "ui/MetavoxelEditor.h" + Menu* Menu::_instance = NULL; Menu* Menu::getInstance() { @@ -79,7 +80,7 @@ Menu::Menu() : _loginAction(NULL) { Application *appInstance = Application::getInstance(); - + QMenu* fileMenu = addMenu("File"); #ifdef Q_OS_MAC @@ -860,67 +861,11 @@ void Menu::goToDomainDialog() { } void Menu::goToOrientation(QString orientation) { - - if (orientation.isEmpty()) { - return; - } - - QStringList orientationItems = orientation.split(QRegExp("_|,"), QString::SkipEmptyParts); - - const int NUMBER_OF_ORIENTATION_ITEMS = 4; - const int W_ITEM = 0; - const int X_ITEM = 1; - const int Y_ITEM = 2; - const int Z_ITEM = 3; - - if (orientationItems.size() == NUMBER_OF_ORIENTATION_ITEMS) { - - double w = replaceLastOccurrence('-', '.', orientationItems[W_ITEM].trimmed()).toDouble(); - double x = replaceLastOccurrence('-', '.', orientationItems[X_ITEM].trimmed()).toDouble(); - double y = replaceLastOccurrence('-', '.', orientationItems[Y_ITEM].trimmed()).toDouble(); - double z = replaceLastOccurrence('-', '.', orientationItems[Z_ITEM].trimmed()).toDouble(); - - glm::quat newAvatarOrientation(w, x, y, z); - - MyAvatar* myAvatar = Application::getInstance()->getAvatar(); - glm::quat avatarOrientation = myAvatar->getOrientation(); - if (newAvatarOrientation != avatarOrientation) { - myAvatar->setOrientation(newAvatarOrientation); - } - } + LocationManager::getInstance().goToDestination(orientation); } bool Menu::goToDestination(QString destination) { - - QStringList coordinateItems = destination.split(QRegExp("_|,"), QString::SkipEmptyParts); - - const int NUMBER_OF_COORDINATE_ITEMS = 3; - const int X_ITEM = 0; - const int Y_ITEM = 1; - const int Z_ITEM = 2; - if (coordinateItems.size() == NUMBER_OF_COORDINATE_ITEMS) { - - double x = replaceLastOccurrence('-', '.', coordinateItems[X_ITEM].trimmed()).toDouble(); - double y = replaceLastOccurrence('-', '.', coordinateItems[Y_ITEM].trimmed()).toDouble(); - double z = replaceLastOccurrence('-', '.', coordinateItems[Z_ITEM].trimmed()).toDouble(); - - glm::vec3 newAvatarPos(x, y, z); - - MyAvatar* myAvatar = Application::getInstance()->getAvatar(); - glm::vec3 avatarPos = myAvatar->getPosition(); - if (newAvatarPos != avatarPos) { - // send a node kill request, indicating to other clients that they should play the "disappeared" effect - MyAvatar::sendKillAvatar(); - - qDebug("Going To Location: %f, %f, %f...", x, y, z); - myAvatar->setPosition(newAvatarPos); - } - - return true; - } - - // no coordinates were parsed - return false; + return LocationManager::getInstance().goToDestination(destination); } void Menu::goTo() { @@ -935,25 +880,33 @@ void Menu::goTo() { int dialogReturn = gotoDialog.exec(); if (dialogReturn == QDialog::Accepted && !gotoDialog.textValue().isEmpty()) { - - destination = gotoDialog.textValue(); - - // go to coordinate destination or to Username - if (!goToDestination(destination)) { - JSONCallbackParameters callbackParams; - callbackParams.jsonCallbackReceiver = Application::getInstance()->getAvatar(); - callbackParams.jsonCallbackMethod = "goToLocationFromResponse"; - - // there's a username entered by the user, make a request to the data-server for the associated location - AccountManager::getInstance().authenticatedRequest("/api/v1/users/" + gotoDialog.textValue() + "/address", - QNetworkAccessManager::GetOperation, - callbackParams); - } + LocationManager* manager = new LocationManager(); + manager->goTo(gotoDialog.textValue()); + connect(manager, &LocationManager::multipleDestinationsFound, this, &Menu::multipleDestinationsDecision); } sendFakeEnterEvent(); } +void Menu::multipleDestinationsDecision(const QJsonObject& userData, const QJsonObject& placeData) { + QMessageBox msgBox; + msgBox.setText("Both user and location exists with same name"); + msgBox.setInformativeText("Where you wanna go?"); + msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Open); + msgBox.button(QMessageBox::Ok)->setText("User"); + msgBox.button(QMessageBox::Open)->setText("Place"); + int userResponse = msgBox.exec(); + + if (userResponse == QMessageBox::Ok) { + Application::getInstance()->getAvatar()->goToLocationFromResponse(userData); + } else if (userResponse == QMessageBox::Open) { + Application::getInstance()->getAvatar()->goToLocationFromResponse(userData); + } + + LocationManager* manager = reinterpret_cast(sender()); + disconnect(manager, &LocationManager::multipleDestinationsFound, this, &Menu::multipleDestinationsDecision); +} + void Menu::goToLocation() { MyAvatar* myAvatar = Application::getInstance()->getAvatar(); glm::vec3 avatarPos = myAvatar->getPosition(); @@ -999,7 +952,7 @@ void Menu::nameLocation() { // check if user is logged in or show login dialog if not AccountManager& accountManager = AccountManager::getInstance(); - if (!accountManager.isLoggedIn() && 1 > 2) { + if (!accountManager.isLoggedIn()) { QMessageBox msgBox; msgBox.setText("We need to tie this location to your username."); msgBox.setInformativeText("Please login first, then try naming the location again."); @@ -1278,17 +1231,6 @@ void Menu::addAvatarCollisionSubMenu(QMenu* overMenu) { 0, true, avatar, SLOT(updateCollisionFlags())); } -QString Menu::replaceLastOccurrence(QChar search, QChar replace, QString string) { - int lastIndex; - lastIndex = string.lastIndexOf(search); - if (lastIndex > 0) { - lastIndex = string.lastIndexOf(search); - string.replace(lastIndex, 1, replace); - } - - return string; -} - QAction* Menu::getActionFromName(const QString& menuName, QMenu* menu) { QList menuActions; if (menu) { diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 6ff0d79662..d47c156aa8 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -149,6 +149,7 @@ private slots: void toggleChat(); void audioMuteToggled(); void namedLocationCreated(LocationManager::NamedLocationCreateResponse response, NamedLocation* location); + void multipleDestinationsDecision(const QJsonObject& userData, const QJsonObject& placeData); private: static Menu* _instance; diff --git a/interface/src/location/LocationManager.cpp b/interface/src/location/LocationManager.cpp index 0588c66818..61ed401766 100644 --- a/interface/src/location/LocationManager.cpp +++ b/interface/src/location/LocationManager.cpp @@ -7,12 +7,17 @@ // #include "LocationManager.h" +#include "Application.h" const QString GET_USER_ADDRESS = "/api/v1/users/%1/address"; const QString GET_PLACE_ADDRESS = "/api/v1/places/%1/address"; -const QString GET_ADDRESSES = "/api/v1/addresses/%1/address"; const QString POST_PLACE_CREATE = "/api/v1/places/"; + +LocationManager::LocationManager() : _userData(), _placeData() { + +}; + LocationManager& LocationManager::getInstance() { static LocationManager sharedInstance; return sharedInstance; @@ -23,7 +28,6 @@ void LocationManager::namedLocationDataReceived(const QJsonObject& data) { return; } - qDebug() << data; if (data.contains("status") && data["status"].toString() == "success") { NamedLocation* location = new NamedLocation(data["data"].toObject()); emit creationCompleted(LocationManager::Created, location); @@ -45,10 +49,169 @@ void LocationManager::createNamedLocation(NamedLocation* namedLocation) { callbackParams.errorCallbackReceiver = this; callbackParams.errorCallbackMethod = "errorDataReceived"; - qDebug() << namedLocation->toJsonString(); accountManager.authenticatedRequest(POST_PLACE_CREATE, QNetworkAccessManager::PostOperation, callbackParams, namedLocation->toJsonString().toUtf8()); } } +void LocationManager::goTo(QString destination) { + + if (destination.startsWith("@")) { + // remove '@' and go to user + goToUser(destination.remove(0, 1)); + return; + } + + if (destination.startsWith("#")) { + // remove '#' and go to named place + goToPlace(destination.remove(0, 1)); + return; + } + + // go to coordinate destination or to Username + if (!goToDestination(destination)) { + // reset data on local variables + _userData = QJsonObject(); + _placeData = QJsonObject(); + + JSONCallbackParameters callbackParams; + callbackParams.jsonCallbackReceiver = this; + callbackParams.jsonCallbackMethod = "goToUserFromResponse"; + AccountManager::getInstance().authenticatedRequest(GET_USER_ADDRESS.arg(destination), + QNetworkAccessManager::GetOperation, + callbackParams); + + callbackParams.jsonCallbackMethod = "goToLocationFromResponse"; + AccountManager::getInstance().authenticatedRequest(GET_PLACE_ADDRESS.arg(destination), + QNetworkAccessManager::GetOperation, + callbackParams); + } +} + +void LocationManager::goToUserFromResponse(const QJsonObject& jsonObject) { + _userData = jsonObject; + checkForMultipleDestinations(); +} + +void LocationManager::goToLocationFromResponse(const QJsonObject& jsonObject) { + _placeData = jsonObject; + checkForMultipleDestinations(); +} + +void LocationManager::checkForMultipleDestinations() { + if (!_userData.isEmpty() && !_placeData.isEmpty()) { + if (_userData.contains("status") && _userData["status"].toString() == "success" && + _placeData.contains("status") && _placeData["status"].toString() == "success") { + emit multipleDestinationsFound(_userData, _placeData); + return; + } + + if (_userData.contains("status") && _userData["status"].toString() == "success") { + Application::getInstance()->getAvatar()->goToLocationFromResponse(_userData); + return; + } + + if (_placeData.contains("status") && _placeData["status"].toString() == "success") { + Application::getInstance()->getAvatar()->goToLocationFromResponse(_placeData); + return; + } + + emit locationChanged(); + } +} + +void LocationManager::goToUser(QString userName) { + + JSONCallbackParameters callbackParams; + callbackParams.jsonCallbackReceiver = Application::getInstance()->getAvatar(); + callbackParams.jsonCallbackMethod = "goToLocationFromResponse"; + + AccountManager::getInstance().authenticatedRequest(GET_USER_ADDRESS.arg(userName), + QNetworkAccessManager::GetOperation, + callbackParams); +} + +void LocationManager::goToPlace(QString placeName) { + JSONCallbackParameters callbackParams; + callbackParams.jsonCallbackReceiver = Application::getInstance()->getAvatar(); + callbackParams.jsonCallbackMethod = "goToLocationFromResponse"; + + AccountManager::getInstance().authenticatedRequest(GET_PLACE_ADDRESS.arg(placeName), + QNetworkAccessManager::GetOperation, + callbackParams); +} + +void LocationManager::goToOrientation(QString orientation) { + if (orientation.isEmpty()) { + return; + } + + QStringList orientationItems = orientation.split(QRegExp("_|,"), QString::SkipEmptyParts); + + const int NUMBER_OF_ORIENTATION_ITEMS = 4; + const int W_ITEM = 0; + const int X_ITEM = 1; + const int Y_ITEM = 2; + const int Z_ITEM = 3; + + if (orientationItems.size() == NUMBER_OF_ORIENTATION_ITEMS) { + + double w = replaceLastOccurrence('-', '.', orientationItems[W_ITEM].trimmed()).toDouble(); + double x = replaceLastOccurrence('-', '.', orientationItems[X_ITEM].trimmed()).toDouble(); + double y = replaceLastOccurrence('-', '.', orientationItems[Y_ITEM].trimmed()).toDouble(); + double z = replaceLastOccurrence('-', '.', orientationItems[Z_ITEM].trimmed()).toDouble(); + + glm::quat newAvatarOrientation(w, x, y, z); + + MyAvatar* myAvatar = Application::getInstance()->getAvatar(); + glm::quat avatarOrientation = myAvatar->getOrientation(); + if (newAvatarOrientation != avatarOrientation) { + myAvatar->setOrientation(newAvatarOrientation); + } + } +} + +bool LocationManager::goToDestination(QString destination) { + + QStringList coordinateItems = destination.split(QRegExp("_|,"), QString::SkipEmptyParts); + + const int NUMBER_OF_COORDINATE_ITEMS = 3; + const int X_ITEM = 0; + const int Y_ITEM = 1; + const int Z_ITEM = 2; + if (coordinateItems.size() == NUMBER_OF_COORDINATE_ITEMS) { + + double x = replaceLastOccurrence('-', '.', coordinateItems[X_ITEM].trimmed()).toDouble(); + double y = replaceLastOccurrence('-', '.', coordinateItems[Y_ITEM].trimmed()).toDouble(); + double z = replaceLastOccurrence('-', '.', coordinateItems[Z_ITEM].trimmed()).toDouble(); + + glm::vec3 newAvatarPos(x, y, z); + + MyAvatar* myAvatar = Application::getInstance()->getAvatar(); + glm::vec3 avatarPos = myAvatar->getPosition(); + if (newAvatarPos != avatarPos) { + // send a node kill request, indicating to other clients that they should play the "disappeared" effect + MyAvatar::sendKillAvatar(); + + qDebug("Going To Location: %f, %f, %f...", x, y, z); + myAvatar->setPosition(newAvatarPos); + } + + return true; + } + + // no coordinates were parsed + return false; +} + +QString LocationManager::replaceLastOccurrence(QChar search, QChar replace, QString string) { + int lastIndex; + lastIndex = string.lastIndexOf(search); + if (lastIndex > 0) { + lastIndex = string.lastIndexOf(search); + string.replace(lastIndex, 1, replace); + } + + return string; +} diff --git a/interface/src/location/LocationManager.h b/interface/src/location/LocationManager.h index 4282d0e795..6d5beacae5 100644 --- a/interface/src/location/LocationManager.h +++ b/interface/src/location/LocationManager.h @@ -25,18 +25,33 @@ public: SystemError }; - LocationManager() { }; + LocationManager(); void createNamedLocation(NamedLocation* namedLocation); void goTo(QString destination); void goToUser(QString userName); + void goToPlace(QString placeName); + void goToOrientation(QString orientation); + bool goToDestination(QString destination); + +private: + QString replaceLastOccurrence(QChar search, QChar replace, QString string); + QJsonObject _userData; + QJsonObject _placeData; + + void checkForMultipleDestinations(); signals: void creationCompleted(LocationManager::NamedLocationCreateResponse response, NamedLocation* location); + void multipleDestinationsFound(const QJsonObject& userData, const QJsonObject& placeData); + void locationChanged(); private slots: void namedLocationDataReceived(const QJsonObject& data); void errorDataReceived(QNetworkReply::NetworkError error, const QString& message); + void goToLocationFromResponse(const QJsonObject& jsonObject); + void goToUserFromResponse(const QJsonObject& jsonObject); + }; #endif /* defined(__hifi__LocationManager__) */ From d92426c37dd6c70216598291fd280cf0e4fc0561 Mon Sep 17 00:00:00 2001 From: stojce Date: Wed, 12 Mar 2014 23:11:44 +0100 Subject: [PATCH 05/10] translation auto corrected --- interface/interface_en.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/interface/interface_en.ts b/interface/interface_en.ts index 20d7a74c09..58796e1aa4 100644 --- a/interface/interface_en.ts +++ b/interface/interface_en.ts @@ -4,22 +4,22 @@ Application - + Export Voxels - + Sparse Voxel Octree Files (*.svo) - + Open Script - + JavaScript Files (*.js) @@ -113,18 +113,18 @@ Menu - + Open .ini config file - - + + Text files (*.ini) - + Save .ini config file From e231c8486b20da47dd4c1ea565ec7e8ea73eb36a Mon Sep 17 00:00:00 2001 From: stojce Date: Thu, 13 Mar 2014 07:47:33 +0100 Subject: [PATCH 06/10] Using singleton for location manager --- interface/interface_en.ts | 8 ++++---- interface/src/Menu.cpp | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/interface/interface_en.ts b/interface/interface_en.ts index e658d15ba7..46d050787a 100644 --- a/interface/interface_en.ts +++ b/interface/interface_en.ts @@ -4,22 +4,22 @@ Application - + Export Voxels - + Sparse Voxel Octree Files (*.svo) - + Open Script - + JavaScript Files (*.js) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 69cbd4a963..eb4386b84c 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -884,7 +884,7 @@ void Menu::goTo() { int dialogReturn = gotoDialog.exec(); if (dialogReturn == QDialog::Accepted && !gotoDialog.textValue().isEmpty()) { - LocationManager* manager = new LocationManager(); + LocationManager* manager = &LocationManager::getInstance(); manager->goTo(gotoDialog.textValue()); connect(manager, &LocationManager::multipleDestinationsFound, this, &Menu::multipleDestinationsDecision); } From e964b846de1e094d40310f8158a1e9c53fa8f4fd Mon Sep 17 00:00:00 2001 From: stojce Date: Thu, 13 Mar 2014 08:03:23 +0100 Subject: [PATCH 07/10] - url encoding for get requests --- interface/src/location/LocationManager.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/interface/src/location/LocationManager.cpp b/interface/src/location/LocationManager.cpp index 61ed401766..f23915506d 100644 --- a/interface/src/location/LocationManager.cpp +++ b/interface/src/location/LocationManager.cpp @@ -74,6 +74,7 @@ void LocationManager::goTo(QString destination) { _userData = QJsonObject(); _placeData = QJsonObject(); + destination = QString::QString(QUrl::toPercentEncoding(destination)); JSONCallbackParameters callbackParams; callbackParams.jsonCallbackReceiver = this; callbackParams.jsonCallbackMethod = "goToUserFromResponse"; @@ -126,6 +127,7 @@ void LocationManager::goToUser(QString userName) { callbackParams.jsonCallbackReceiver = Application::getInstance()->getAvatar(); callbackParams.jsonCallbackMethod = "goToLocationFromResponse"; + userName = QString::QString(QUrl::toPercentEncoding(userName)); AccountManager::getInstance().authenticatedRequest(GET_USER_ADDRESS.arg(userName), QNetworkAccessManager::GetOperation, callbackParams); @@ -136,6 +138,7 @@ void LocationManager::goToPlace(QString placeName) { callbackParams.jsonCallbackReceiver = Application::getInstance()->getAvatar(); callbackParams.jsonCallbackMethod = "goToLocationFromResponse"; + placeName = QString::QString(QUrl::toPercentEncoding(placeName)); AccountManager::getInstance().authenticatedRequest(GET_PLACE_ADDRESS.arg(placeName), QNetworkAccessManager::GetOperation, callbackParams); From be804e0f864ff17ba7ed3c940d67206db8f9dcc8 Mon Sep 17 00:00:00 2001 From: stojce Date: Thu, 13 Mar 2014 09:30:59 +0100 Subject: [PATCH 08/10] Fixes for linux build --- interface/src/location/LocationManager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/src/location/LocationManager.cpp b/interface/src/location/LocationManager.cpp index f23915506d..986371ac88 100644 --- a/interface/src/location/LocationManager.cpp +++ b/interface/src/location/LocationManager.cpp @@ -74,7 +74,7 @@ void LocationManager::goTo(QString destination) { _userData = QJsonObject(); _placeData = QJsonObject(); - destination = QString::QString(QUrl::toPercentEncoding(destination)); + destination = QString(QUrl::toPercentEncoding(destination)); JSONCallbackParameters callbackParams; callbackParams.jsonCallbackReceiver = this; callbackParams.jsonCallbackMethod = "goToUserFromResponse"; @@ -127,7 +127,7 @@ void LocationManager::goToUser(QString userName) { callbackParams.jsonCallbackReceiver = Application::getInstance()->getAvatar(); callbackParams.jsonCallbackMethod = "goToLocationFromResponse"; - userName = QString::QString(QUrl::toPercentEncoding(userName)); + userName = QString(QUrl::toPercentEncoding(userName)); AccountManager::getInstance().authenticatedRequest(GET_USER_ADDRESS.arg(userName), QNetworkAccessManager::GetOperation, callbackParams); @@ -138,7 +138,7 @@ void LocationManager::goToPlace(QString placeName) { callbackParams.jsonCallbackReceiver = Application::getInstance()->getAvatar(); callbackParams.jsonCallbackMethod = "goToLocationFromResponse"; - placeName = QString::QString(QUrl::toPercentEncoding(placeName)); + placeName = QString(QUrl::toPercentEncoding(placeName)); AccountManager::getInstance().authenticatedRequest(GET_PLACE_ADDRESS.arg(placeName), QNetworkAccessManager::GetOperation, callbackParams); From b3cbcc6cd6b841962cc181ffc58d2946a948eac7 Mon Sep 17 00:00:00 2001 From: stojce Date: Thu, 13 Mar 2014 10:20:16 +0100 Subject: [PATCH 09/10] minor cleanup of unused data --- libraries/shared/src/NodeList.cpp | 1 - libraries/shared/src/PacketHeaders.cpp | 3 --- libraries/shared/src/PacketHeaders.h | 3 --- 3 files changed, 7 deletions(-) diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index 523d18929c..263e29bc94 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -97,7 +97,6 @@ bool NodeList::packetVersionAndHashMatch(const QByteArray& packet) { << PacketTypeDomainServerAuthRequest << PacketTypeDomainConnectRequest << PacketTypeStunResponse << PacketTypeDataServerConfirm << PacketTypeDataServerGet << PacketTypeDataServerPut << PacketTypeDataServerSend - << PacketTypeDataServerHashGet << PacketTypeDataServerHashPut << PacketTypeDataServerHashSend << PacketTypeCreateAssignment << PacketTypeRequestAssignment; if (!NON_VERIFIED_PACKETS.contains(checkType)) { diff --git a/libraries/shared/src/PacketHeaders.cpp b/libraries/shared/src/PacketHeaders.cpp index 88996adceb..eccfa4fefa 100644 --- a/libraries/shared/src/PacketHeaders.cpp +++ b/libraries/shared/src/PacketHeaders.cpp @@ -58,9 +58,6 @@ PacketVersion versionForPacketType(PacketType type) { case PacketTypeDataServerPut: case PacketTypeDataServerConfirm: case PacketTypeDataServerSend: - case PacketTypeDataServerHashPut: - case PacketTypeDataServerHashGet: - case PacketTypeDataServerHashSend: return 1; case PacketTypeVoxelSet: case PacketTypeVoxelSetDestructive: diff --git a/libraries/shared/src/PacketHeaders.h b/libraries/shared/src/PacketHeaders.h index 47a4c65409..0122e36a61 100644 --- a/libraries/shared/src/PacketHeaders.h +++ b/libraries/shared/src/PacketHeaders.h @@ -39,9 +39,6 @@ enum PacketType { PacketTypeCreateAssignment, PacketTypeDataServerPut, PacketTypeDataServerGet, - PacketTypeDataServerHashPut, - PacketTypeDataServerHashGet, - PacketTypeDataServerHashSend, PacketTypeDataServerSend, PacketTypeDataServerConfirm, PacketTypeVoxelQuery, From 576b8acef3d253f546fef78ccf5b1e9818307f39 Mon Sep 17 00:00:00 2001 From: stojce Date: Fri, 14 Mar 2014 20:09:03 +0100 Subject: [PATCH 10/10] CR fixes --- interface/interface_en.ts | 8 ++-- interface/src/Menu.cpp | 4 +- interface/src/Menu.h | 6 +-- interface/src/location/LocationManager.cpp | 43 ++++++++++------- interface/src/location/LocationManager.h | 7 +-- interface/src/location/NamedLocation.cpp | 56 ---------------------- interface/src/location/NamedLocation.h | 2 - 7 files changed, 38 insertions(+), 88 deletions(-) diff --git a/interface/interface_en.ts b/interface/interface_en.ts index c52ec91671..786a76530c 100644 --- a/interface/interface_en.ts +++ b/interface/interface_en.ts @@ -113,18 +113,18 @@ Menu - + Open .ini config file - - + + Text files (*.ini) - + Save .ini config file diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index b322e6567c..98a00e05c9 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -19,12 +19,12 @@ #include #include #include +#include #include #include #include #include #include -#include #include #include @@ -940,7 +940,7 @@ void Menu::goToLocation() { sendFakeEnterEvent(); } -void Menu::namedLocationCreated(LocationManager::NamedLocationCreateResponse response, NamedLocation* location) { +void Menu::namedLocationCreated(LocationManager::NamedLocationCreateResponse response) { if (response == LocationManager::Created) { return; diff --git a/interface/src/Menu.h b/interface/src/Menu.h index b124315cbb..df622be6ac 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -17,9 +17,9 @@ #include #include #include -#include "location/LocationManager.h" -#include +#include "location/LocationManager.h" +#include "ui/ChatWindow.h" const float ADJUST_LOD_DOWN_FPS = 40.0; const float ADJUST_LOD_UP_FPS = 55.0; @@ -149,7 +149,7 @@ private slots: void showChat(); void toggleChat(); void audioMuteToggled(); - void namedLocationCreated(LocationManager::NamedLocationCreateResponse response, NamedLocation* location); + void namedLocationCreated(LocationManager::NamedLocationCreateResponse response); void multipleDestinationsDecision(const QJsonObject& userData, const QJsonObject& placeData); private: diff --git a/interface/src/location/LocationManager.cpp b/interface/src/location/LocationManager.cpp index 986371ac88..b83094ba4c 100644 --- a/interface/src/location/LocationManager.cpp +++ b/interface/src/location/LocationManager.cpp @@ -6,8 +6,8 @@ // // -#include "LocationManager.h" #include "Application.h" +#include "LocationManager.h" const QString GET_USER_ADDRESS = "/api/v1/users/%1/address"; const QString GET_PLACE_ADDRESS = "/api/v1/places/%1/address"; @@ -29,15 +29,14 @@ void LocationManager::namedLocationDataReceived(const QJsonObject& data) { } if (data.contains("status") && data["status"].toString() == "success") { - NamedLocation* location = new NamedLocation(data["data"].toObject()); - emit creationCompleted(LocationManager::Created, location); + emit creationCompleted(LocationManager::Created); } else { - emit creationCompleted(LocationManager::AlreadyExists, NULL); + emit creationCompleted(LocationManager::AlreadyExists); } } void LocationManager::errorDataReceived(QNetworkReply::NetworkError error, const QString& message) { - emit creationCompleted(LocationManager::SystemError, NULL); + emit creationCompleted(LocationManager::SystemError); } void LocationManager::createNamedLocation(NamedLocation* namedLocation) { @@ -149,7 +148,7 @@ void LocationManager::goToOrientation(QString orientation) { return; } - QStringList orientationItems = orientation.split(QRegExp("_|,"), QString::SkipEmptyParts); + QStringList orientationItems = orientation.remove(' ').split(QRegExp("_|,"), QString::SkipEmptyParts); const int NUMBER_OF_ORIENTATION_ITEMS = 4; const int W_ITEM = 0; @@ -159,10 +158,16 @@ void LocationManager::goToOrientation(QString orientation) { if (orientationItems.size() == NUMBER_OF_ORIENTATION_ITEMS) { - double w = replaceLastOccurrence('-', '.', orientationItems[W_ITEM].trimmed()).toDouble(); - double x = replaceLastOccurrence('-', '.', orientationItems[X_ITEM].trimmed()).toDouble(); - double y = replaceLastOccurrence('-', '.', orientationItems[Y_ITEM].trimmed()).toDouble(); - double z = replaceLastOccurrence('-', '.', orientationItems[Z_ITEM].trimmed()).toDouble(); + // replace last occurrence of '_' with decimal point + replaceLastOccurrence('-', '.', orientationItems[W_ITEM]); + replaceLastOccurrence('-', '.', orientationItems[X_ITEM]); + replaceLastOccurrence('-', '.', orientationItems[Y_ITEM]); + replaceLastOccurrence('-', '.', orientationItems[Z_ITEM]); + + double w = orientationItems[W_ITEM].toDouble(); + double x = orientationItems[X_ITEM].toDouble(); + double y = orientationItems[Y_ITEM].toDouble(); + double z = orientationItems[Z_ITEM].toDouble(); glm::quat newAvatarOrientation(w, x, y, z); @@ -176,7 +181,7 @@ void LocationManager::goToOrientation(QString orientation) { bool LocationManager::goToDestination(QString destination) { - QStringList coordinateItems = destination.split(QRegExp("_|,"), QString::SkipEmptyParts); + QStringList coordinateItems = destination.remove(' ').split(QRegExp("_|,"), QString::SkipEmptyParts); const int NUMBER_OF_COORDINATE_ITEMS = 3; const int X_ITEM = 0; @@ -184,9 +189,14 @@ bool LocationManager::goToDestination(QString destination) { const int Z_ITEM = 2; if (coordinateItems.size() == NUMBER_OF_COORDINATE_ITEMS) { - double x = replaceLastOccurrence('-', '.', coordinateItems[X_ITEM].trimmed()).toDouble(); - double y = replaceLastOccurrence('-', '.', coordinateItems[Y_ITEM].trimmed()).toDouble(); - double z = replaceLastOccurrence('-', '.', coordinateItems[Z_ITEM].trimmed()).toDouble(); + // replace last occurrence of '_' with decimal point + replaceLastOccurrence('-', '.', coordinateItems[X_ITEM]); + replaceLastOccurrence('-', '.', coordinateItems[Y_ITEM]); + replaceLastOccurrence('-', '.', coordinateItems[Z_ITEM]); + + double x = coordinateItems[X_ITEM].toDouble(); + double y = coordinateItems[Y_ITEM].toDouble(); + double z = coordinateItems[Z_ITEM].toDouble(); glm::vec3 newAvatarPos(x, y, z); @@ -207,14 +217,11 @@ bool LocationManager::goToDestination(QString destination) { return false; } -QString LocationManager::replaceLastOccurrence(QChar search, QChar replace, QString string) { +void LocationManager::replaceLastOccurrence(const QChar search, const QChar replace, QString& string) { int lastIndex; lastIndex = string.lastIndexOf(search); if (lastIndex > 0) { lastIndex = string.lastIndexOf(search); string.replace(lastIndex, 1, replace); } - - return string; } - diff --git a/interface/src/location/LocationManager.h b/interface/src/location/LocationManager.h index 6d5beacae5..a6bdaf66b4 100644 --- a/interface/src/location/LocationManager.h +++ b/interface/src/location/LocationManager.h @@ -10,8 +10,9 @@ #define __hifi__LocationManager__ #include -#include "NamedLocation.h" + #include "AccountManager.h" +#include "NamedLocation.h" class LocationManager : public QObject { Q_OBJECT @@ -35,14 +36,14 @@ public: bool goToDestination(QString destination); private: - QString replaceLastOccurrence(QChar search, QChar replace, QString string); QJsonObject _userData; QJsonObject _placeData; + void replaceLastOccurrence(const QChar search, const QChar replace, QString& string); void checkForMultipleDestinations(); signals: - void creationCompleted(LocationManager::NamedLocationCreateResponse response, NamedLocation* location); + void creationCompleted(LocationManager::NamedLocationCreateResponse response); void multipleDestinationsFound(const QJsonObject& userData, const QJsonObject& placeData); void locationChanged(); diff --git a/interface/src/location/NamedLocation.cpp b/interface/src/location/NamedLocation.cpp index af96794fd0..c6daef4961 100644 --- a/interface/src/location/NamedLocation.cpp +++ b/interface/src/location/NamedLocation.cpp @@ -22,59 +22,3 @@ QString NamedLocation::toJsonString() { _domain, _locationName); } - -NamedLocation::NamedLocation(const QJsonObject jsonData) { - - bool hasProperties; - - if (jsonData.contains("name")) { - hasProperties = true; - _locationName = jsonData["name"].toString(); - } - - if (jsonData.contains("username")) { - hasProperties = true; - _createdBy = jsonData["username"].toString(); - } - - if (jsonData.contains("domain")) { - hasProperties = true; - _domain = jsonData["domain"].toString(); - } - - // parse position - if (jsonData.contains("position")) { - hasProperties = true; - const int NUMBER_OF_POSITION_ITEMS = 3; - const int X_ITEM = 0; - const int Y_ITEM = 1; - const int Z_ITEM = 2; - - QStringList coordinateItems = jsonData["position"].toString().split(",", QString::SkipEmptyParts); - if (coordinateItems.size() == NUMBER_OF_POSITION_ITEMS) { - double x = coordinateItems[X_ITEM].trimmed().toDouble(); - double y = coordinateItems[Y_ITEM].trimmed().toDouble(); - double z = coordinateItems[Z_ITEM].trimmed().toDouble(); - _location = glm::vec3(x, y, z); - } - } - - // parse orientation - if (jsonData.contains("orientation")) { - hasProperties = true; - QStringList orientationItems = jsonData["orientation"] .toString().split(",", QString::SkipEmptyParts); - const int NUMBER_OF_ORIENTATION_ITEMS = 4; - const int W_ITEM = 0; - const int X_ITEM = 1; - const int Y_ITEM = 2; - const int Z_ITEM = 3; - - if (orientationItems.size() == NUMBER_OF_ORIENTATION_ITEMS) { - double w = orientationItems[W_ITEM].trimmed().toDouble(); - double x = orientationItems[X_ITEM].trimmed().toDouble(); - double y = orientationItems[Y_ITEM].trimmed().toDouble(); - double z = orientationItems[Z_ITEM].trimmed().toDouble(); - _orientation = glm::quat(w, x, y, z); - } - } -} \ No newline at end of file diff --git a/interface/src/location/NamedLocation.h b/interface/src/location/NamedLocation.h index 4bc8c2e2ad..81af03b45e 100644 --- a/interface/src/location/NamedLocation.h +++ b/interface/src/location/NamedLocation.h @@ -26,8 +26,6 @@ public: _domain = domain; } - NamedLocation(const QJsonObject jsonData); - QString toJsonString(); bool isEmpty() { return _locationName.isNull() || _locationName.isEmpty(); }