From ee6a90dd546d4ca3b454e9f77f7a5dddd4a08bf3 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 10 Sep 2014 15:13:02 -0700 Subject: [PATCH 01/22] allow domain to pass down its ID from config --- domain-server/src/DomainServer.cpp | 6 ++++++ libraries/networking/src/NodeList.cpp | 5 ++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 56570a4b82..d17caf24f0 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -189,6 +189,12 @@ void DomainServer::setupNodeListAndAssignments(const QUuid& sessionUUID) { populateDefaultStaticAssignmentsExcludingTypes(parsedTypes); LimitedNodeList* nodeList = LimitedNodeList::createInstance(domainServerPort, domainServerDTLSPort); + + const QString DOMAIN_CONFIG_ID_KEY = "id"; + + // set our LimitedNodeList UUID to match the UUID from our config + // nodes will currently use this to add resources to data-web that relate to our domain + nodeList->setSessionUUID(_argumentVariantMap.value(DOMAIN_CONFIG_ID_KEY).toString()); connect(nodeList, &LimitedNodeList::nodeAdded, this, &DomainServer::nodeAdded); connect(nodeList, &LimitedNodeList::nodeKilled, this, &DomainServer::nodeKilled); diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index d77ef321a8..79a399c621 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -397,7 +397,10 @@ int NodeList::processDomainServerList(const QByteArray& packet) { _numNoReplyDomainCheckIns = 0; // if this was the first domain-server list from this domain, we've now connected - _domainHandler.setIsConnected(true); + if (!_domainHandler.isConnected()) { + _domainHandler.setUUID(uuidFromPacketHeader(packet)); + _domainHandler.setIsConnected(true); + } int readNodes = 0; From 71f2c0b542d088a3034b49dc4822f07dccf8c3a1 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 11 Sep 2014 10:14:00 -0700 Subject: [PATCH 02/22] initial addition of the AddressManager with location switch hooked up --- interface/src/Application.cpp | 13 +- interface/src/Menu.cpp | 126 ++----------------- interface/src/Menu.h | 12 +- interface/src/avatar/MyAvatar.cpp | 56 ++++----- interface/src/avatar/MyAvatar.h | 3 +- interface/src/location/LocationManager.cpp | 86 ++++++++----- interface/src/location/LocationManager.h | 7 +- interface/src/ui/ChatMessageArea.cpp | 4 +- interface/src/ui/ChatWindow.cpp | 2 +- interface/src/ui/UserLocationsDialog.cpp | 2 +- libraries/networking/src/AddressManager.cpp | 108 ++++++++++++++++ libraries/networking/src/AddressManager.h | 33 +++++ libraries/networking/src/LimitedNodeList.cpp | 2 +- 13 files changed, 249 insertions(+), 205 deletions(-) create mode 100644 libraries/networking/src/AddressManager.cpp create mode 100644 libraries/networking/src/AddressManager.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 05a195c904..5b1110fbad 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -51,6 +51,7 @@ #include #include +#include #include #include #include @@ -421,6 +422,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : MIDIManager& midiManagerInstance = MIDIManager::getInstance(); midiManagerInstance.openDefaultPort(); #endif + + AddressManager::getInstance().handleLookupString("1.5,2.5,0.0/0.0,-161.98,0.02"); } Application::~Application() { @@ -809,7 +812,7 @@ bool Application::event(QEvent* event) { QFileOpenEvent* fileEvent = static_cast(event); bool isHifiSchemeURL = !fileEvent->url().isEmpty() && fileEvent->url().toLocalFile().startsWith(CUSTOM_URL_SCHEME); if (isHifiSchemeURL) { - Menu::getInstance()->goToURL(fileEvent->url().toLocalFile()); +// Menu::getInstance()->goToURL(fileEvent->url().toLocalFile()); } return false; } @@ -1059,7 +1062,7 @@ void Application::keyPressEvent(QKeyEvent* event) { break; case Qt::Key_At: - Menu::getInstance()->goTo(); +// Menu::getInstance()->goTo(); break; default: event->ignore(); @@ -3360,7 +3363,7 @@ void Application::updateWindowTitle(){ #ifndef WIN32 // crashes with vs2013/win32 qDebug("Application title set to: %s", title.toStdString().c_str()); -#endif !WIN32 +#endif _window->setWindowTitle(title); } @@ -4114,11 +4117,11 @@ void Application::urlGoTo(int argc, const char * constArgv[]) { // goto either @user, #place, or x-xx,y-yy,z-zz // style co-ordinate. - Menu::goTo(destination); +// Menu::goTo(destination); if (!orientation.isEmpty()) { // location orientation - Menu::goToOrientation(orientation); +// Menu::goToOrientation(orientation); } } } diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index d7679968ae..48908b12a1 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -183,8 +183,6 @@ Menu::Menu() : Qt::Key_At, this, SLOT(goTo())); - connect(&LocationManager::getInstance(), &LocationManager::multipleDestinationsFound, - this, &Menu::multipleDestinationsDecision); addDisabledActionAndSeparator(fileMenu, "Upload Avatar Model"); addActionToQMenuAndActionHash(fileMenu, MenuOption::UploadHead, 0, Application::getInstance(), SLOT(uploadHead())); @@ -1191,107 +1189,25 @@ void Menu::goToDomainDialog() { sendFakeEnterEvent(); } -void Menu::goToOrientation(QString orientation) { - LocationManager::getInstance().goToOrientation(orientation); -} +void Menu::addressBarDialog() { -bool Menu::goToDestination(QString destination) { - return LocationManager::getInstance().goToDestination(destination); -} - -void Menu::goTo(QString destination) { - LocationManager::getInstance().goTo(destination); -} - -void Menu::goTo() { - - QInputDialog gotoDialog(Application::getInstance()->getWindow()); - gotoDialog.setWindowTitle("Go to"); - gotoDialog.setLabelText("Destination or URL:\n @user, #place, hifi://domain/location/orientation"); + QInputDialog addressBarDialog(Application::getInstance()->getWindow()); + addressBarDialog.setWindowTitle("Address Bar"); + addressBarDialog.setLabelText("place, @user, hifi://domain/path, position/orientation"); QString destination = QString(); - gotoDialog.setTextValue(destination); - gotoDialog.resize(gotoDialog.parentWidget()->size().width() * DIALOG_RATIO_OF_WINDOW, gotoDialog.size().height()); + addressBarDialog.setTextValue(destination); + addressBarDialog.resize(addressBarDialog.parentWidget()->size().width() * DIALOG_RATIO_OF_WINDOW, + addressBarDialog.size().height()); - int dialogReturn = gotoDialog.exec(); - if (dialogReturn == QDialog::Accepted && !gotoDialog.textValue().isEmpty()) { - QString desiredDestination = gotoDialog.textValue(); - if (!goToURL(desiredDestination)) {; - goTo(desiredDestination); - } + int dialogReturn = addressBarDialog.exec(); + if (dialogReturn == QDialog::Accepted && !addressBarDialog.textValue().isEmpty()) { + // let the location manager parse this out and decide what to do with it +// LocationManager::getInstance().handleAddressBarEntry(addressBarDialog.textValue()); } sendFakeEnterEvent(); } -bool Menu::goToURL(QString location) { - if (location.startsWith(CUSTOM_URL_SCHEME + "/")) { - QStringList urlParts = location.remove(0, CUSTOM_URL_SCHEME.length()).split('/', QString::SkipEmptyParts); - - if (urlParts.count() > 1) { - // if url has 2 or more parts, the first one is domain name - QString domain = urlParts[0]; - - // second part is either a destination coordinate or - // a place name - QString destination = urlParts[1]; - - // any third part is an avatar orientation. - QString orientation = urlParts.count() > 2 ? urlParts[2] : QString(); - - goToDomain(domain); - - // goto either @user, #place, or x-xx,y-yy,z-zz - // style co-ordinate. - goTo(destination); - - if (!orientation.isEmpty()) { - // location orientation - goToOrientation(orientation); - } - } else if (urlParts.count() == 1) { - QString destination = urlParts[0]; - - // If this starts with # or @, treat it as a user/location, otherwise treat it as a domain - if (destination[0] == '#' || destination[0] == '@') { - goTo(destination); - } else { - goToDomain(destination); - } - } - return true; - } - return false; -} - -void Menu::goToUser(const QString& user) { - LocationManager::getInstance().goTo(user); -} - -/// Open a url, shortcutting any "hifi" scheme URLs to the local application. -void Menu::openUrl(const QUrl& url) { - if (url.scheme() == "hifi") { - goToURL(url.toString()); - } else { - QDesktopServices::openUrl(url); - } -} - -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()->goToLocationFromAddress(userData["address"].toObject()); - } else if (userResponse == QMessageBox::Open) { - Application::getInstance()->getAvatar()->goToLocationFromAddress(placeData["address"].toObject()); - } -} - void Menu::muteEnvironment() { int headerSize = numBytesForPacketHeaderGivenPacketType(PacketTypeMuteEnvironment); int packetSize = headerSize + sizeof(glm::vec3) + sizeof(float); @@ -1316,26 +1232,6 @@ void Menu::muteEnvironment() { free(packet); } -void Menu::goToLocation() { - MyAvatar* myAvatar = Application::getInstance()->getAvatar(); - glm::vec3 avatarPos = myAvatar->getPosition(); - QString currentLocation = QString("%1, %2, %3").arg(QString::number(avatarPos.x), - QString::number(avatarPos.y), QString::number(avatarPos.z)); - - QInputDialog coordinateDialog(Application::getInstance()->getWindow()); - coordinateDialog.setWindowTitle("Go to Location"); - coordinateDialog.setLabelText("Coordinate as x,y,z:"); - coordinateDialog.setTextValue(currentLocation); - coordinateDialog.resize(coordinateDialog.parentWidget()->size().width() * 0.30, coordinateDialog.size().height()); - - int dialogReturn = coordinateDialog.exec(); - if (dialogReturn == QDialog::Accepted && !coordinateDialog.textValue().isEmpty()) { - goToDestination(coordinateDialog.textValue()); - } - - sendFakeEnterEvent(); -} - void Menu::namedLocationCreated(LocationManager::NamedLocationCreateResponse response) { if (response == LocationManager::Created) { diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 3b263add36..a9068c4b60 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -162,11 +162,8 @@ public: int menuItemLocation = UNSPECIFIED_POSITION); void removeAction(QMenu* menu, const QString& actionName); - - bool static goToDestination(QString destination); - void static goToOrientation(QString orientation); + void static goToDomain(const QString newDomain); - void static goTo(QString destination); const QByteArray& getWalletPrivateKey() const { return _walletPrivateKey; } @@ -185,11 +182,8 @@ public slots: void saveSettings(QSettings* settings = NULL); void importSettings(); void exportSettings(); - void goTo(); - bool goToURL(QString location); - void goToUser(const QString& user); + void addressBarDialog(); void pasteToVoxel(); - void openUrl(const QUrl& url); void toggleLoginMenuItem(); @@ -212,7 +206,6 @@ private slots: void editAnimations(); void changePrivateKey(); void goToDomainDialog(); - void goToLocation(); void nameLocation(); void toggleLocationList(); void bandwidthDetailsClosed(); @@ -227,7 +220,6 @@ private slots: void toggleChat(); void audioMuteToggled(); void namedLocationCreated(LocationManager::NamedLocationCreateResponse response); - void multipleDestinationsDecision(const QJsonObject& userData, const QJsonObject& placeData); void muteEnvironment(); private: diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 6472ba2efa..14120a7e2c 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -91,6 +92,9 @@ MyAvatar::MyAvatar() : Ragdoll* ragdoll = _skeletonModel.buildRagdoll(); _physicsSimulation.setRagdoll(ragdoll); _physicsSimulation.addEntity(&_voxelShapeManager); + + // connect to AddressManager signal for location jumps + connect(&AddressManager::getInstance(), &AddressManager::locationChangeRequired, this, &MyAvatar::goToLocation); } MyAvatar::~MyAvatar() { @@ -1798,45 +1802,29 @@ void MyAvatar::resetSize() { qDebug("Reseted scale to %f", _targetScale); } -void MyAvatar::goToLocationFromResponse(const QJsonObject& jsonObject) { - QJsonObject locationObject = jsonObject["data"].toObject()["address"].toObject(); - bool isOnline = jsonObject["data"].toObject()["online"].toBool(); - if (isOnline ) { - goToLocationFromAddress(locationObject); - } else { - QMessageBox::warning(Application::getInstance()->getWindow(), "", "The user is not online."); - } -} - -void MyAvatar::goToLocationFromAddress(const QJsonObject& locationObject) { +void MyAvatar::goToLocation(const glm::vec3& newPosition, bool hasOrientation, const glm::vec3& newOrientation) { // send a node kill request, indicating to other clients that they should play the "disappeared" effect sendKillAvatar(); - - QString positionString = locationObject["position"].toString(); - QString orientationString = locationObject["orientation"].toString(); - QString domainHostnameString = locationObject["domain"].toString(); - - qDebug() << "Changing domain to" << domainHostnameString << - ", position to" << positionString << - ", and orientation to" << orientationString; - - QStringList coordinateItems = positionString.split(','); - QStringList orientationItems = orientationString.split(','); - - NodeList::getInstance()->getDomainHandler().setHostname(domainHostnameString); - - // orient the user to face the target - glm::quat newOrientation = glm::quat(glm::radians(glm::vec3(orientationItems[0].toFloat(), - orientationItems[1].toFloat(), - orientationItems[2].toFloat()))) - * glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f)); - setOrientation(newOrientation); + + glm::quat quatOrientation = getOrientation(); + + qDebug().nospace() << "MyAvatar goToLocation - moving to " << newPosition.x << ", " + << newPosition.y << ", " << newPosition.z; + + if (hasOrientation) { + qDebug().nospace() << "MyAvatar goToLocation - new orientation is " + << newOrientation.x << ", " << newOrientation.y << ", " << newOrientation.z; + + // orient the user to face the target + glm::quat quatOrientation = glm::quat(glm::radians(newOrientation)) + * glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f)); + setOrientation(quatOrientation); + } // move the user a couple units away const float DISTANCE_TO_USER = 2.0f; - glm::vec3 newPosition = glm::vec3(coordinateItems[0].toFloat(), coordinateItems[1].toFloat(), - coordinateItems[2].toFloat()) - newOrientation * IDENTITY_FRONT * DISTANCE_TO_USER; - slamPosition(newPosition); + glm::vec3 shiftedPosition = newPosition - quatOrientation * IDENTITY_FRONT * DISTANCE_TO_USER; + slamPosition(shiftedPosition); emit transformChanged(); } diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index be828e0c91..86c10fdbb4 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -155,8 +155,7 @@ public slots: void decreaseSize(); void resetSize(); - void goToLocationFromResponse(const QJsonObject& jsonObject); - void goToLocationFromAddress(const QJsonObject& jsonObject); + void goToLocation(const glm::vec3& newPosition, bool hasOrientation, const glm::vec3& newOrientation); // Set/Get update the thrust that will move the avatar around void addThrust(glm::vec3 newThrust) { _thrust += newThrust; }; diff --git a/interface/src/location/LocationManager.cpp b/interface/src/location/LocationManager.cpp index 67e1b899ee..4484c50ebf 100644 --- a/interface/src/location/LocationManager.cpp +++ b/interface/src/location/LocationManager.cpp @@ -16,15 +16,9 @@ #include const QString GET_USER_ADDRESS = "/api/v1/users/%1/address"; -const QString GET_PLACE_ADDRESS = "/api/v1/places/%1"; -const QString GET_ADDRESSES = "/api/v1/addresses/%1"; +const QString GET_PLACE_ADDRESS = "/api/v1/metaverse/search/%1"; const QString POST_PLACE_CREATE = "/api/v1/places/"; - -LocationManager::LocationManager() { - -}; - LocationManager& LocationManager::getInstance() { static LocationManager sharedInstance; return sharedInstance; @@ -63,7 +57,7 @@ void LocationManager::createNamedLocation(NamedLocation* namedLocation) { void LocationManager::goTo(QString destination) { const QString USER_DESTINATION_TYPE = "user"; const QString PLACE_DESTINATION_TYPE = "place"; - const QString OTHER_DESTINATION_TYPE = "coordinate_or_username"; + const QString COORDINATE_DESTINATION_TYPE = "coordinate"; if (destination.startsWith("@")) { // remove '@' and go to user @@ -73,45 +67,37 @@ void LocationManager::goTo(QString destination) { return; } - if (destination.startsWith("#")) { - // remove '#' and go to named place - QString destinationPlace = destination.remove(0, 1); - UserActivityLogger::getInstance().wentTo(PLACE_DESTINATION_TYPE, destinationPlace); - goToPlace(destinationPlace); - return; - } - // go to coordinate destination or to Username if (!goToDestination(destination)) { destination = QString(QUrl::toPercentEncoding(destination)); - UserActivityLogger::getInstance().wentTo(OTHER_DESTINATION_TYPE, destination); + UserActivityLogger::getInstance().wentTo(PLACE_DESTINATION_TYPE, destination); JSONCallbackParameters callbackParams; callbackParams.jsonCallbackReceiver = this; - callbackParams.jsonCallbackMethod = "goToAddressFromResponse"; + callbackParams.jsonCallbackMethod = "goToPlaceFromResponse"; callbackParams.errorCallbackReceiver = this; callbackParams.errorCallbackMethod = "handleAddressLookupError"; - AccountManager::getInstance().authenticatedRequest(GET_ADDRESSES.arg(destination), + AccountManager::getInstance().authenticatedRequest(GET_PLACE_ADDRESS.arg(destination), QNetworkAccessManager::GetOperation, callbackParams); + } else { + UserActivityLogger::getInstance().wentTo(COORDINATE_DESTINATION_TYPE, destination); } } -void LocationManager::goToAddressFromResponse(const QJsonObject& responseData) { +void LocationManager::goToPlaceFromResponse(const QJsonObject& responseData) { QJsonValue status = responseData["status"]; - const QJsonObject& data = responseData["data"].toObject(); - const QJsonValue& userObject = data["user"]; - const QJsonValue& placeObject = data["place"]; + QJsonObject data = responseData["data"].toObject(); + QJsonObject domainObject = data["domain"].toObject(); - if (!placeObject.isUndefined() && !userObject.isUndefined()) { - emit multipleDestinationsFound(userObject.toObject(), placeObject.toObject()); - } else if (placeObject.isUndefined()) { - Application::getInstance()->getAvatar()->goToLocationFromAddress(userObject.toObject()["address"].toObject()); - } else { - Application::getInstance()->getAvatar()->goToLocationFromAddress(placeObject.toObject()["address"].toObject()); - } + const QString DOMAIN_NETWORK_ADDRESS_KEY = "network_address"; + + // get the network address for the domain we need to switch to + NodeList::getInstance()->getDomainHandler().setHostname(domainObject[DOMAIN_NETWORK_ADDRESS_KEY].toString()); + + // check if there is a path inside the domain we need to jump to } void LocationManager::goToUser(QString userName) { @@ -140,6 +126,46 @@ void LocationManager::goToPlace(QString placeName) { callbackParams); } +void LocationManager::goToUrl(const QUrl& url) { +// if (location.startsWith(CUSTOM_URL_SCHEME + "/")) { +// QStringList urlParts = location.remove(0, CUSTOM_URL_SCHEME.length()).split('/', QString::SkipEmptyParts); +// +// if (urlParts.count() > 1) { +// // if url has 2 or more parts, the first one is domain name +// QString domain = urlParts[0]; +// +// // second part is either a destination coordinate or +// // a place name +// QString destination = urlParts[1]; +// +// // any third part is an avatar orientation. +// QString orientation = urlParts.count() > 2 ? urlParts[2] : QString(); +// +// goToDomain(domain); +// +// // goto either @user, #place, or x-xx,y-yy,z-zz +// // style co-ordinate. +// goTo(destination); +// +// if (!orientation.isEmpty()) { +// // location orientation +// goToOrientation(orientation); +// } +// } else if (urlParts.count() == 1) { +// QString destination = urlParts[0]; +// +// // If this starts with # or @, treat it as a user/location, otherwise treat it as a domain +// if (destination[0] == '#' || destination[0] == '@') { +// goTo(destination); +// } else { +// goToDomain(destination); +// } +// } +// return true; +// } +// return false; +} + void LocationManager::goToOrientation(QString orientation) { if (orientation.isEmpty()) { return; diff --git a/interface/src/location/LocationManager.h b/interface/src/location/LocationManager.h index 30b4447ded..bf1c0e67e2 100644 --- a/interface/src/location/LocationManager.h +++ b/interface/src/location/LocationManager.h @@ -29,12 +29,12 @@ public: SystemError }; - LocationManager(); void createNamedLocation(NamedLocation* namedLocation); - + void goTo(QString destination); void goToUser(QString userName); void goToPlace(QString placeName); + void goToUrl(const QUrl& url); void goToOrientation(QString orientation); bool goToDestination(QString destination); @@ -46,12 +46,11 @@ private: signals: void creationCompleted(LocationManager::NamedLocationCreateResponse response); - void multipleDestinationsFound(const QJsonObject& userData, const QJsonObject& placeData); private slots: void namedLocationDataReceived(const QJsonObject& data); void errorDataReceived(QNetworkReply::NetworkError error, const QString& message); - void goToAddressFromResponse(const QJsonObject& jsonObject); + void goToPlaceFromResponse(const QJsonObject& jsonObject); }; diff --git a/interface/src/ui/ChatMessageArea.cpp b/interface/src/ui/ChatMessageArea.cpp index 1e16a8a2db..ab93c7abe9 100644 --- a/interface/src/ui/ChatMessageArea.cpp +++ b/interface/src/ui/ChatMessageArea.cpp @@ -19,8 +19,8 @@ ChatMessageArea::ChatMessageArea(bool useFixedHeight) : QTextBrowser(), _useFixe connect(document()->documentLayout(), &QAbstractTextDocumentLayout::documentSizeChanged, this, &ChatMessageArea::updateLayout); - connect(this, &QTextBrowser::anchorClicked, - Menu::getInstance(), &Menu::openUrl); +// connect(this, &QTextBrowser::anchorClicked, +// Menu::getInstance(), &Menu::openUrl); } void ChatMessageArea::setHtml(const QString& html) { diff --git a/interface/src/ui/ChatWindow.cpp b/interface/src/ui/ChatWindow.cpp index b9b5ed8e19..9961a84e79 100644 --- a/interface/src/ui/ChatWindow.cpp +++ b/interface/src/ui/ChatWindow.cpp @@ -169,7 +169,7 @@ bool ChatWindow::eventFilter(QObject* sender, QEvent* event) { } else if (event->type() == QEvent::MouseButtonRelease) { QVariant userVar = sender->property("user"); if (userVar.isValid()) { - Menu::getInstance()->goToUser("@" + userVar.toString()); +// Menu::getInstance()->goToUser("@" + userVar.toString()); return true; } } diff --git a/interface/src/ui/UserLocationsDialog.cpp b/interface/src/ui/UserLocationsDialog.cpp index f72e66ce77..ca1a9b5ad6 100644 --- a/interface/src/ui/UserLocationsDialog.cpp +++ b/interface/src/ui/UserLocationsDialog.cpp @@ -52,7 +52,7 @@ void UserLocationsDialog::updateEnabled() { void UserLocationsDialog::goToModelIndex(const QModelIndex& index) { QVariant location = _proxyModel.data(index.sibling(index.row(), UserLocationsModel::LocationColumn)); - Menu::getInstance()->goToURL(location.toString()); +// Menu::getInstance()->goToURL(location.toString()); } void UserLocationsDialog::deleteSelection() { diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp new file mode 100644 index 0000000000..6413fe6580 --- /dev/null +++ b/libraries/networking/src/AddressManager.cpp @@ -0,0 +1,108 @@ +// +// AddressManager.cpp +// libraries/networking/src +// +// Created by Stephen Birarda on 2014-09-10. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include +#include +#include + +#include "AddressManager.h" + +AddressManager& AddressManager::getInstance() { + static AddressManager sharedInstance; + return sharedInstance; +} + +void AddressManager::handleLookupString(const QString& lookupString) { + // there are 4 possible lookup strings + + // 1. global place name (name of domain or place) - example: sanfrancisco + // 2. user name (prepended with @) - example: @philip + // 3. location string (posX,posY,posZ/eulerX,eulerY,eulerZ) + // 4. domain network address (IP or dns resolvable hostname) + + // use our regex'ed helpers to figure out what we're supposed to do with this + if (!lookupHandledAsUsername(lookupString) && + !lookupHandledAsNetworkAddress(lookupString) && + !lookupHandledAsLocationString(lookupString)) { + + } + + + +} + +bool AddressManager::lookupHandledAsNetworkAddress(const QString& lookupString) { + const QString IP_ADDRESS_REGEX_STRING = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}" + "([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"; + const QString HOSTNAME_REGEX_STRING = "^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*" + "([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]*[A-Za-z0-9])$"; + + + + return false; +} + +bool AddressManager::lookupHandledAsLocationString(const QString& lookupString) { + const QString FLOAT_REGEX_STRING = "([-+]?[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?)"; + const QString TRIPLE_FLOAT_REGEX_STRING = FLOAT_REGEX_STRING + "\\s*,\\s*" + + FLOAT_REGEX_STRING + "\\s*,\\s*" + FLOAT_REGEX_STRING + "\\s*(?:$|\\/)"; + + QRegExp tripleFloatRegex(TRIPLE_FLOAT_REGEX_STRING); + + if (tripleFloatRegex.indexIn(lookupString) != -1) { + // we have at least a position, so emit our signal to say we need to change position + glm::vec3 newPosition(tripleFloatRegex.cap(1).toFloat(), + tripleFloatRegex.cap(2).toFloat(), + tripleFloatRegex.cap(3).toFloat()); + + if (newPosition.x != NAN && newPosition.y != NAN && newPosition.z != NAN) { + glm::vec3 newOrientation; + // we may also have an orientation + if (lookupString[tripleFloatRegex.matchedLength() - 1] == QChar('/') + && tripleFloatRegex.indexIn(lookupString, tripleFloatRegex.matchedLength() - 1) != -1) { + + glm::vec3 newOrientation(tripleFloatRegex.cap(1).toFloat(), + tripleFloatRegex.cap(2).toFloat(), + tripleFloatRegex.cap(3).toFloat()); + + if (newOrientation.x != NAN && newOrientation.y != NAN && newOrientation.z != NAN) { + emit locationChangeRequired(newPosition, true, newOrientation); + return true; + } else { + qDebug() << "Orientation parsed from lookup string is invalid. Will not use for location change."; + } + } + + emit locationChangeRequired(newPosition, false, newOrientation); + + } else { + qDebug() << "Could not jump to position from lookup string because it has an invalid value."; + } + + return true; + } + + return false; +} + +bool AddressManager::lookupHandledAsUsername(const QString& lookupString) { + const QString USERNAME_REGEX_STRING = "^@(\\S+)$"; + + QRegExp usernameRegex(USERNAME_REGEX_STRING); + + if (usernameRegex.indexIn(lookupString) != -1) { + // this is a username - pull the captured name and lookup that user's address + + return true; + } + + return false; +} diff --git a/libraries/networking/src/AddressManager.h b/libraries/networking/src/AddressManager.h new file mode 100644 index 0000000000..5c1a5c2e89 --- /dev/null +++ b/libraries/networking/src/AddressManager.h @@ -0,0 +1,33 @@ +// +// AddressManager.h +// libraries/networking/src +// +// Created by Stephen Birarda on 2014-09-10. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_AddressManager_h +#define hifi_AddressManager_h + +#include + +#include + +class AddressManager : public QObject { + Q_OBJECT +public: + static AddressManager& getInstance(); + + void handleLookupString(const QString& lookupString); +signals: + void locationChangeRequired(const glm::vec3& newPosition, bool hasOrientationChange, const glm::vec3& newOrientation); +private: + bool lookupHandledAsNetworkAddress(const QString& lookupString); + bool lookupHandledAsLocationString(const QString& lookupString); + bool lookupHandledAsUsername(const QString& lookupString); +}; + +#endif // hifi_AddressManager_h \ No newline at end of file diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index f50f7493fb..604f8c7434 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -33,7 +33,7 @@ const char SOLO_NODE_TYPES[2] = { NodeType::AudioMixer }; -const QUrl DEFAULT_NODE_AUTH_URL = QUrl("https://data.highfidelity.io"); +const QUrl DEFAULT_NODE_AUTH_URL = QUrl("http://localhost:3000"); LimitedNodeList* LimitedNodeList::_sharedInstance = NULL; From dd1b23044f11a139152332a1f578519dde1d3c4a Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 11 Sep 2014 10:24:04 -0700 Subject: [PATCH 03/22] hook meta+enter up to address bar display --- interface/src/Application.cpp | 15 +++++--- interface/src/Menu.cpp | 69 +++++------------------------------ interface/src/Menu.h | 9 +---- 3 files changed, 21 insertions(+), 72 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 5b1110fbad..c123dfa1f4 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -422,8 +422,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : MIDIManager& midiManagerInstance = MIDIManager::getInstance(); midiManagerInstance.openDefaultPort(); #endif - - AddressManager::getInstance().handleLookupString("1.5,2.5,0.0/0.0,-161.98,0.02"); } Application::~Application() { @@ -913,7 +911,12 @@ void Application::keyPressEvent(QKeyEvent* event) { case Qt::Key_Return: case Qt::Key_Enter: - Menu::getInstance()->triggerOption(MenuOption::Chat); + if (isMeta) { + Menu::getInstance()->triggerOption(MenuOption::AddressBar); + } else { + Menu::getInstance()->triggerOption(MenuOption::Chat); + } + break; case Qt::Key_Up: @@ -1317,7 +1320,7 @@ void Application::dropEvent(QDropEvent *event) { SnapshotMetaData* snapshotData = Snapshot::parseSnapshotData(snapshotPath); if (snapshotData) { if (!snapshotData->getDomain().isEmpty()) { - Menu::getInstance()->goToDomain(snapshotData->getDomain()); +// Menu::getInstance()->goToDomain(snapshotData->getDomain()); } _myAvatar->setPosition(snapshotData->getLocation()); @@ -4101,7 +4104,7 @@ void Application::urlGoTo(int argc, const char * constArgv[]) { if (urlParts.count() == 1) { // location coordinates or place name QString domain = urlParts[0]; - Menu::goToDomain(domain); +// Menu::goToDomain(domain); } else if (urlParts.count() > 1) { // if url has 2 or more parts, the first one is domain name QString domain = urlParts[0]; @@ -4113,7 +4116,7 @@ void Application::urlGoTo(int argc, const char * constArgv[]) { // any third part is an avatar orientation. QString orientation = urlParts.count() > 2 ? urlParts[2] : QString(); - Menu::goToDomain(domain); +// Menu::goToDomain(domain); // goto either @user, #place, or x-xx,y-yy,z-zz // style co-ordinate. diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 48908b12a1..b8835407b0 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -158,16 +159,6 @@ Menu::Menu() : Qt::CTRL | Qt::Key_G, appInstance->getAvatar(), SLOT(goHome())); - addActionToQMenuAndActionHash(fileMenu, - MenuOption::GoToDomain, - Qt::CTRL | Qt::Key_D, - this, - SLOT(goToDomainDialog())); - addActionToQMenuAndActionHash(fileMenu, - MenuOption::GoToLocation, - Qt::CTRL | Qt::SHIFT | Qt::Key_L, - this, - SLOT(goToLocation())); addActionToQMenuAndActionHash(fileMenu, MenuOption::NameLocation, Qt::CTRL | Qt::Key_N, @@ -179,10 +170,10 @@ Menu::Menu() : this, SLOT(toggleLocationList())); addActionToQMenuAndActionHash(fileMenu, - MenuOption::GoTo, - Qt::Key_At, + MenuOption::AddressBar, + Qt::CTRL | Qt::Key_Enter, this, - SLOT(goTo())); + SLOT(toggleAddressBar())); addDisabledActionAndSeparator(fileMenu, "Upload Avatar Model"); addActionToQMenuAndActionHash(fileMenu, MenuOption::UploadHead, 0, Application::getInstance(), SLOT(uploadHead())); @@ -1149,62 +1140,22 @@ void Menu::changePrivateKey() { sendFakeEnterEvent(); } -void Menu::goToDomain(const QString newDomain) { - if (NodeList::getInstance()->getDomainHandler().getHostname() != newDomain) { - // send a node kill request, indicating to other clients that they should play the "disappeared" effect - Application::getInstance()->getAvatar()->sendKillAvatar(); - - // give our nodeList the new domain-server hostname - NodeList::getInstance()->getDomainHandler().setHostname(newDomain); - } -} - -void Menu::goToDomainDialog() { - - QString currentDomainHostname = NodeList::getInstance()->getDomainHandler().getHostname(); - - if (NodeList::getInstance()->getDomainHandler().getPort() != DEFAULT_DOMAIN_SERVER_PORT) { - // add the port to the currentDomainHostname string if it is custom - currentDomainHostname.append(QString(":%1").arg(NodeList::getInstance()->getDomainHandler().getPort())); - } - - QInputDialog domainDialog(Application::getInstance()->getWindow()); - domainDialog.setWindowTitle("Go to Domain"); - domainDialog.setLabelText("Domain server:"); - domainDialog.setTextValue(currentDomainHostname); - domainDialog.resize(domainDialog.parentWidget()->size().width() * DIALOG_RATIO_OF_WINDOW, domainDialog.size().height()); - - int dialogReturn = domainDialog.exec(); - if (dialogReturn == QDialog::Accepted) { - QString newHostname(DEFAULT_DOMAIN_HOSTNAME); - - if (domainDialog.textValue().size() > 0) { - // the user input a new hostname, use that - newHostname = domainDialog.textValue(); - } - - goToDomain(newHostname); - } - - sendFakeEnterEvent(); -} - -void Menu::addressBarDialog() { +void Menu::toggleAddressBar() { QInputDialog addressBarDialog(Application::getInstance()->getWindow()); addressBarDialog.setWindowTitle("Address Bar"); - addressBarDialog.setLabelText("place, @user, hifi://domain/path, position/orientation"); - QString destination = QString(); + addressBarDialog.setWindowFlags(Qt::Sheet); + addressBarDialog.setLabelText("place, domain, @user, example.com, position/orientation"); - addressBarDialog.setTextValue(destination); addressBarDialog.resize(addressBarDialog.parentWidget()->size().width() * DIALOG_RATIO_OF_WINDOW, addressBarDialog.size().height()); int dialogReturn = addressBarDialog.exec(); if (dialogReturn == QDialog::Accepted && !addressBarDialog.textValue().isEmpty()) { - // let the location manager parse this out and decide what to do with it -// LocationManager::getInstance().handleAddressBarEntry(addressBarDialog.textValue()); + // let the AddressManger figure out what to do with this + AddressManager::getInstance().handleLookupString(addressBarDialog.textValue()); } + sendFakeEnterEvent(); } diff --git a/interface/src/Menu.h b/interface/src/Menu.h index a9068c4b60..078c2b4255 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -163,8 +163,6 @@ public: void removeAction(QMenu* menu, const QString& actionName); - void static goToDomain(const QString newDomain); - const QByteArray& getWalletPrivateKey() const { return _walletPrivateKey; } signals: @@ -182,7 +180,7 @@ public slots: void saveSettings(QSettings* settings = NULL); void importSettings(); void exportSettings(); - void addressBarDialog(); + void toggleAddressBar(); void pasteToVoxel(); void toggleLoginMenuItem(); @@ -205,7 +203,6 @@ private slots: void editAttachments(); void editAnimations(); void changePrivateKey(); - void goToDomainDialog(); void nameLocation(); void toggleLocationList(); void bandwidthDetailsClosed(); @@ -307,6 +304,7 @@ private: namespace MenuOption { const QString AboutApp = "About Interface"; + const QString AddressBar = "Show Address Bar"; const QString AlignForearmsWithWrists = "Align Forearms with Wrists"; const QString AlternateIK = "Alternate IK"; const QString AmbientOcclusion = "Ambient Occlusion"; @@ -393,9 +391,6 @@ namespace MenuOption { const QString GlowMode = "Cycle Glow Mode"; const QString GlowWhenSpeaking = "Glow When Speaking"; const QString GoHome = "Go Home"; - const QString GoToDomain = "Go To Domain..."; - const QString GoTo = "Go To..."; - const QString GoToLocation = "Go To Location..."; const QString HeadMouse = "Head Mouse"; const QString IncreaseAvatarSize = "Increase Avatar Size"; const QString IncreaseVoxelSize = "Increase Voxel Size"; From aaabe6b1e1a2353a9b12a412de230ff18e6db945 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 11 Sep 2014 10:45:45 -0700 Subject: [PATCH 04/22] handle domain changes via address bar --- interface/src/Application.cpp | 12 ++++++++++++ interface/src/Application.h | 1 + interface/src/avatar/MyAvatar.cpp | 5 +---- libraries/networking/src/AddressManager.cpp | 13 +++++++++++++ libraries/networking/src/AddressManager.h | 1 + libraries/networking/src/DomainHandler.h | 3 ++- 6 files changed, 30 insertions(+), 5 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c123dfa1f4..2fa9701e18 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -407,6 +407,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : connect(_window, &MainWindow::windowGeometryChanged, _runningScriptsWidget, &RunningScriptsWidget::setBoundary); + // connect to the domainChangeRequired signal on AddressManager + connect(&AddressManager::getInstance(), &AddressManager::domainChangeRequired, this, &Application::changeDomainHostname); + //When -url in command line, teleport to location urlGoTo(argc, constArgv); @@ -3391,6 +3394,15 @@ void Application::updateLocationInServer() { } } +void Application::changeDomainHostname(const QString &newDomainHostname) { + // tell the MyAvatar object to send a kill packet so that it dissapears from its old avatar mixer immediately + _myAvatar->sendKillAvatar(); + + // call the domain hostname change as a queued connection on the nodelist + QMetaObject::invokeMethod(&NodeList::getInstance()->getDomainHandler(), "setHostname", + Q_ARG(const QString&, newDomainHostname)); +} + void Application::domainChanged(const QString& domainHostname) { updateWindowTitle(); diff --git a/interface/src/Application.h b/interface/src/Application.h index f48d88d7a4..6f4bc02e94 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -313,6 +313,7 @@ signals: void importDone(); public slots: + void changeDomainHostname(const QString& newDomainHostname); void domainChanged(const QString& domainHostname); void updateWindowTitle(); void updateLocationInServer(); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 14120a7e2c..b4335512ef 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1802,10 +1802,7 @@ void MyAvatar::resetSize() { qDebug("Reseted scale to %f", _targetScale); } -void MyAvatar::goToLocation(const glm::vec3& newPosition, bool hasOrientation, const glm::vec3& newOrientation) { - // send a node kill request, indicating to other clients that they should play the "disappeared" effect - sendKillAvatar(); - +void MyAvatar::goToLocation(const glm::vec3& newPosition, bool hasOrientation, const glm::vec3& newOrientation) { glm::quat quatOrientation = getOrientation(); qDebug().nospace() << "MyAvatar goToLocation - moving to " << newPosition.x << ", " diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index 6413fe6580..5f6e0652c2 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -42,10 +42,23 @@ void AddressManager::handleLookupString(const QString& lookupString) { bool AddressManager::lookupHandledAsNetworkAddress(const QString& lookupString) { const QString IP_ADDRESS_REGEX_STRING = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}" "([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"; + const QString HOSTNAME_REGEX_STRING = "^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*" "([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]*[A-Za-z0-9])$"; + QRegExp hostnameRegex(HOSTNAME_REGEX_STRING); + if (hostnameRegex.indexIn(lookupString) != -1) { + emit domainChangeRequired(hostnameRegex.cap(0)); + return true; + } + + QRegExp ipAddressRegex(IP_ADDRESS_REGEX_STRING); + + if (ipAddressRegex.indexIn(lookupString) != -1) { + emit domainChangeRequired(ipAddressRegex.cap(0)); + return true; + } return false; } diff --git a/libraries/networking/src/AddressManager.h b/libraries/networking/src/AddressManager.h index 5c1a5c2e89..e43102dd42 100644 --- a/libraries/networking/src/AddressManager.h +++ b/libraries/networking/src/AddressManager.h @@ -23,6 +23,7 @@ public: void handleLookupString(const QString& lookupString); signals: + void domainChangeRequired(const QString& newHostname); void locationChangeRequired(const glm::vec3& newPosition, bool hasOrientationChange, const glm::vec3& newOrientation); private: bool lookupHandledAsNetworkAddress(const QString& lookupString); diff --git a/libraries/networking/src/DomainHandler.h b/libraries/networking/src/DomainHandler.h index 91caddca22..c65d687f5f 100644 --- a/libraries/networking/src/DomainHandler.h +++ b/libraries/networking/src/DomainHandler.h @@ -40,7 +40,6 @@ public: void setUUID(const QUuid& uuid) { _uuid = uuid; } const QString& getHostname() const { return _hostname; } - void setHostname(const QString& hostname); const QHostAddress& getIP() const { return _sockAddr.getAddress(); } void setIPToLocalhost() { _sockAddr.setAddress(QHostAddress(QHostAddress::LocalHost)); } @@ -63,6 +62,8 @@ public: void parseDTLSRequirementPacket(const QByteArray& dtlsRequirementPacket); void softReset(); +public slots: + void setHostname(const QString& hostname); private slots: void completedHostnameLookup(const QHostInfo& hostInfo); From 684aa97b98c1db72eb182ab760aa918a92ab47d1 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 11 Sep 2014 11:00:24 -0700 Subject: [PATCH 05/22] add port parsing for domain hostname in address bar --- libraries/networking/src/AddressManager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index 5f6e0652c2..7a1848174e 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -41,10 +41,10 @@ void AddressManager::handleLookupString(const QString& lookupString) { bool AddressManager::lookupHandledAsNetworkAddress(const QString& lookupString) { const QString IP_ADDRESS_REGEX_STRING = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}" - "([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"; + "([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(:\\d{1,5})?$"; - const QString HOSTNAME_REGEX_STRING = "^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*" - "([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]*[A-Za-z0-9])$"; + const QString HOSTNAME_REGEX_STRING = "^(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])" + "(?:\\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9]))+(:{1}\\d{1,5})?$"; QRegExp hostnameRegex(HOSTNAME_REGEX_STRING); From 6d21c4bf0d1ffd7607c4b4a6576a7a965e2a2ee3 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 11 Sep 2014 11:07:42 -0700 Subject: [PATCH 06/22] make lookup for hostnames case insensitive --- libraries/networking/src/AddressManager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index 7a1848174e..40bae46c5a 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -43,10 +43,10 @@ bool AddressManager::lookupHandledAsNetworkAddress(const QString& lookupString) const QString IP_ADDRESS_REGEX_STRING = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}" "([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(:\\d{1,5})?$"; - const QString HOSTNAME_REGEX_STRING = "^(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])" - "(?:\\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9]))+(:{1}\\d{1,5})?$"; + const QString HOSTNAME_REGEX_STRING = "^((?:[A-Z0-9]|[A-Z0-9][A-Z0-9\\-]{0,61}[A-Z0-9])" + "(?:\\.(?:[A-Z0-9]|[A-Z0-9][A-Z0-9\\-]{0,61}[A-Z0-9]))+|localhost)(:{1}\\d{1,5})?$"; - QRegExp hostnameRegex(HOSTNAME_REGEX_STRING); + QRegExp hostnameRegex(HOSTNAME_REGEX_STRING, Qt::CaseInsensitive); if (hostnameRegex.indexIn(lookupString) != -1) { emit domainChangeRequired(hostnameRegex.cap(0)); From 23a0ef2de1f9fcd09600979023e437dcda280aa2 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 11 Sep 2014 12:13:13 -0700 Subject: [PATCH 07/22] remove some spacing in AddressManager --- libraries/networking/src/AddressManager.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index 40bae46c5a..63f1b59f6b 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -34,9 +34,6 @@ void AddressManager::handleLookupString(const QString& lookupString) { !lookupHandledAsLocationString(lookupString)) { } - - - } bool AddressManager::lookupHandledAsNetworkAddress(const QString& lookupString) { From b56ea5c936cdba2ca50040dd9858dde7004bb9c9 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 11 Sep 2014 17:17:47 -0700 Subject: [PATCH 08/22] centralize path creation from position and orientation to AddressManager --- interface/src/Application.cpp | 65 ++++++---- interface/src/Application.h | 1 - interface/src/location/LocationManager.cpp | 79 +----------- interface/src/location/LocationManager.h | 2 - .../scripting/LocationScriptingInterface.cpp | 53 -------- .../scripting/LocationScriptingInterface.h | 48 ------- libraries/networking/src/AddressManager.cpp | 119 ++++++++++++++++-- libraries/networking/src/AddressManager.h | 25 +++- libraries/networking/src/DomainHandler.cpp | 16 +++ libraries/networking/src/DomainHandler.h | 4 +- 10 files changed, 188 insertions(+), 224 deletions(-) delete mode 100644 interface/src/scripting/LocationScriptingInterface.cpp delete mode 100644 interface/src/scripting/LocationScriptingInterface.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 2fa9701e18..39c8f1a82f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -84,7 +84,6 @@ #include "scripting/MenuScriptingInterface.h" #include "scripting/SettingsScriptingInterface.h" #include "scripting/WindowScriptingInterface.h" -#include "scripting/LocationScriptingInterface.h" #include "ui/InfoView.h" #include "ui/OAuthWebViewHandler.h" @@ -408,7 +407,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : _runningScriptsWidget, &RunningScriptsWidget::setBoundary); // connect to the domainChangeRequired signal on AddressManager - connect(&AddressManager::getInstance(), &AddressManager::domainChangeRequired, this, &Application::changeDomainHostname); + connect(&AddressManager::getInstance(), &AddressManager::possibleDomainChangeRequired, + this, &Application::changeDomainHostname); //When -url in command line, teleport to location urlGoTo(argc, constArgv); @@ -811,7 +811,7 @@ bool Application::event(QEvent* event) { // handle custom URL if (event->type() == QEvent::FileOpen) { QFileOpenEvent* fileEvent = static_cast(event); - bool isHifiSchemeURL = !fileEvent->url().isEmpty() && fileEvent->url().toLocalFile().startsWith(CUSTOM_URL_SCHEME); + bool isHifiSchemeURL = !fileEvent->url().isEmpty() && fileEvent->url().toLocalFile().startsWith(HIFI_URL_SCHEME); if (isHifiSchemeURL) { // Menu::getInstance()->goToURL(fileEvent->url().toLocalFile()); } @@ -3376,31 +3376,44 @@ void Application::updateWindowTitle(){ void Application::updateLocationInServer() { AccountManager& accountManager = AccountManager::getInstance(); - - if (accountManager.isLoggedIn()) { + const QUuid& domainUUID = NodeList::getInstance()->getDomainHandler().getUUID(); + + if (accountManager.isLoggedIn() && !domainUUID.isNull()) { // construct a QJsonObject given the user's current address information - QJsonObject updatedLocationObject; + QJsonObject rootObject; - QJsonObject addressObject; - addressObject.insert("position", QString(createByteArray(_myAvatar->getPosition()))); - addressObject.insert("orientation", QString(createByteArray(glm::degrees(safeEulerAngles(_myAvatar->getOrientation()))))); - addressObject.insert("domain", NodeList::getInstance()->getDomainHandler().getHostname()); + QJsonObject locationObject; + + QString pathString = AddressManager::pathForPositionAndOrientation(_myAvatar->getPosition(), + true, + _myAvatar->getOrientation()); + + const QString LOCATION_KEY_IN_ROOT = "location"; + const QString PATH_KEY_IN_LOCATION = "path"; + const QString DOMAIN_ID_KEY_IN_LOCATION = "domain_id"; + + locationObject.insert(PATH_KEY_IN_LOCATION, pathString); + locationObject.insert(DOMAIN_ID_KEY_IN_LOCATION, domainUUID.toString()); - updatedLocationObject.insert("address", addressObject); + rootObject.insert(LOCATION_KEY_IN_ROOT, locationObject); - accountManager.authenticatedRequest("/api/v1/users/address", QNetworkAccessManager::PutOperation, - JSONCallbackParameters(), QJsonDocument(updatedLocationObject).toJson()); + accountManager.authenticatedRequest("/api/v1/users/location", QNetworkAccessManager::PutOperation, + JSONCallbackParameters(), QJsonDocument(rootObject).toJson()); } } void Application::changeDomainHostname(const QString &newDomainHostname) { - // tell the MyAvatar object to send a kill packet so that it dissapears from its old avatar mixer immediately - _myAvatar->sendKillAvatar(); + NodeList* nodeList = NodeList::getInstance(); - // call the domain hostname change as a queued connection on the nodelist - QMetaObject::invokeMethod(&NodeList::getInstance()->getDomainHandler(), "setHostname", - Q_ARG(const QString&, newDomainHostname)); + if (!nodeList->getDomainHandler().isCurrentHostname(newDomainHostname)) { + // tell the MyAvatar object to send a kill packet so that it dissapears from its old avatar mixer immediately + _myAvatar->sendKillAvatar(); + + // call the domain hostname change as a queued connection on the nodelist + QMetaObject::invokeMethod(&NodeList::getInstance()->getDomainHandler(), "setHostname", + Q_ARG(const QString&, newDomainHostname)); + } } void Application::domainChanged(const QString& domainHostname) { @@ -3785,12 +3798,12 @@ ScriptEngine* Application::loadScript(const QString& scriptFilename, bool isUser scriptEngine->registerGlobalObject("Overlays", &_overlays); QScriptValue windowValue = scriptEngine->registerGlobalObject("Window", WindowScriptingInterface::getInstance()); - scriptEngine->registerGetterSetter("location", LocationScriptingInterface::locationGetter, - LocationScriptingInterface::locationSetter, windowValue); - - // register `location` on the global object. - scriptEngine->registerGetterSetter("location", LocationScriptingInterface::locationGetter, - LocationScriptingInterface::locationSetter); +// scriptEngine->registerGetterSetter("location", LocationScriptingInterface::locationGetter, +// LocationScriptingInterface::locationSetter, windowValue); +// +// // register `location` on the global object. +// scriptEngine->registerGetterSetter("location", LocationScriptingInterface::locationGetter, +// LocationScriptingInterface::locationSetter); scriptEngine->registerGlobalObject("Menu", MenuScriptingInterface::getInstance()); scriptEngine->registerGlobalObject("Settings", SettingsScriptingInterface::getInstance()); @@ -4111,8 +4124,8 @@ void Application::takeSnapshot() { void Application::urlGoTo(int argc, const char * constArgv[]) { //Gets the url (hifi://domain/destination/orientation) QString customUrl = getCmdOption(argc, constArgv, "-url"); - if(customUrl.startsWith(CUSTOM_URL_SCHEME + "//")) { - QStringList urlParts = customUrl.remove(0, CUSTOM_URL_SCHEME.length() + 2).split('/', QString::SkipEmptyParts); + if(customUrl.startsWith(HIFI_URL_SCHEME + "//")) { + QStringList urlParts = customUrl.remove(0, HIFI_URL_SCHEME.length() + 2).split('/', QString::SkipEmptyParts); if (urlParts.count() == 1) { // location coordinates or place name QString domain = urlParts[0]; diff --git a/interface/src/Application.h b/interface/src/Application.h index 6f4bc02e94..ef08cf4ec5 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -114,7 +114,6 @@ static const float NODE_KILLED_GREEN = 0.0f; static const float NODE_KILLED_BLUE = 0.0f; static const QString SNAPSHOT_EXTENSION = ".jpg"; -static const QString CUSTOM_URL_SCHEME = "hifi:"; static const float BILLBOARD_FIELD_OF_VIEW = 30.0f; // degrees static const float BILLBOARD_DISTANCE = 5.0f; // meters diff --git a/interface/src/location/LocationManager.cpp b/interface/src/location/LocationManager.cpp index 4484c50ebf..6beb1f5527 100644 --- a/interface/src/location/LocationManager.cpp +++ b/interface/src/location/LocationManager.cpp @@ -15,8 +15,7 @@ #include "LocationManager.h" #include -const QString GET_USER_ADDRESS = "/api/v1/users/%1/address"; -const QString GET_PLACE_ADDRESS = "/api/v1/metaverse/search/%1"; + const QString POST_PLACE_CREATE = "/api/v1/places/"; LocationManager& LocationManager::getInstance() { @@ -36,10 +35,6 @@ void LocationManager::namedLocationDataReceived(const QJsonObject& data) { } } -void LocationManager::errorDataReceived(QNetworkReply::NetworkError error, const QString& message) { - emit creationCompleted(LocationManager::SystemError); -} - void LocationManager::createNamedLocation(NamedLocation* namedLocation) { AccountManager& accountManager = AccountManager::getInstance(); if (accountManager.isLoggedIn()) { @@ -54,78 +49,6 @@ void LocationManager::createNamedLocation(NamedLocation* namedLocation) { } } -void LocationManager::goTo(QString destination) { - const QString USER_DESTINATION_TYPE = "user"; - const QString PLACE_DESTINATION_TYPE = "place"; - const QString COORDINATE_DESTINATION_TYPE = "coordinate"; - - if (destination.startsWith("@")) { - // remove '@' and go to user - QString destinationUser = destination.remove(0, 1); - UserActivityLogger::getInstance().wentTo(USER_DESTINATION_TYPE, destinationUser); - goToUser(destinationUser); - return; - } - - // go to coordinate destination or to Username - if (!goToDestination(destination)) { - destination = QString(QUrl::toPercentEncoding(destination)); - UserActivityLogger::getInstance().wentTo(PLACE_DESTINATION_TYPE, destination); - - JSONCallbackParameters callbackParams; - callbackParams.jsonCallbackReceiver = this; - callbackParams.jsonCallbackMethod = "goToPlaceFromResponse"; - callbackParams.errorCallbackReceiver = this; - callbackParams.errorCallbackMethod = "handleAddressLookupError"; - - AccountManager::getInstance().authenticatedRequest(GET_PLACE_ADDRESS.arg(destination), - QNetworkAccessManager::GetOperation, - callbackParams); - } else { - UserActivityLogger::getInstance().wentTo(COORDINATE_DESTINATION_TYPE, destination); - } -} - -void LocationManager::goToPlaceFromResponse(const QJsonObject& responseData) { - QJsonValue status = responseData["status"]; - - QJsonObject data = responseData["data"].toObject(); - QJsonObject domainObject = data["domain"].toObject(); - - const QString DOMAIN_NETWORK_ADDRESS_KEY = "network_address"; - - // get the network address for the domain we need to switch to - NodeList::getInstance()->getDomainHandler().setHostname(domainObject[DOMAIN_NETWORK_ADDRESS_KEY].toString()); - - // check if there is a path inside the domain we need to jump to -} - -void LocationManager::goToUser(QString userName) { - JSONCallbackParameters callbackParams; - callbackParams.jsonCallbackReceiver = Application::getInstance()->getAvatar(); - callbackParams.jsonCallbackMethod = "goToLocationFromResponse"; - callbackParams.errorCallbackReceiver = this; - callbackParams.errorCallbackMethod = "handleAddressLookupError"; - - userName = QString(QUrl::toPercentEncoding(userName)); - 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"; - callbackParams.errorCallbackReceiver = this; - callbackParams.errorCallbackMethod = "handleAddressLookupError"; - - placeName = QString(QUrl::toPercentEncoding(placeName)); - AccountManager::getInstance().authenticatedRequest(GET_PLACE_ADDRESS.arg(placeName), - QNetworkAccessManager::GetOperation, - callbackParams); -} - void LocationManager::goToUrl(const QUrl& url) { // if (location.startsWith(CUSTOM_URL_SCHEME + "/")) { // QStringList urlParts = location.remove(0, CUSTOM_URL_SCHEME.length()).split('/', QString::SkipEmptyParts); diff --git a/interface/src/location/LocationManager.h b/interface/src/location/LocationManager.h index bf1c0e67e2..ec580dfc7a 100644 --- a/interface/src/location/LocationManager.h +++ b/interface/src/location/LocationManager.h @@ -49,8 +49,6 @@ signals: private slots: void namedLocationDataReceived(const QJsonObject& data); - void errorDataReceived(QNetworkReply::NetworkError error, const QString& message); - void goToPlaceFromResponse(const QJsonObject& jsonObject); }; diff --git a/interface/src/scripting/LocationScriptingInterface.cpp b/interface/src/scripting/LocationScriptingInterface.cpp deleted file mode 100644 index 9e68778942..0000000000 --- a/interface/src/scripting/LocationScriptingInterface.cpp +++ /dev/null @@ -1,53 +0,0 @@ -// -// LocationScriptingInterface.cpp -// interface/src/scripting -// -// Created by Ryan Huffman on 4/29/14. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#include - -#include "NodeList.h" - -#include "LocationScriptingInterface.h" - -LocationScriptingInterface* LocationScriptingInterface::getInstance() { - static LocationScriptingInterface sharedInstance; - return &sharedInstance; -} - -bool LocationScriptingInterface::isConnected() { - return NodeList::getInstance()->getDomainHandler().isConnected(); -} - -QString LocationScriptingInterface::getHref() { - return getProtocol() + "//" + getHostname() + getPathname(); -} - -QString LocationScriptingInterface::getPathname() { - const glm::vec3& position = Application::getInstance()->getAvatar()->getPosition(); - QString path; - path.sprintf("/%.4f,%.4f,%.4f", position.x, position.y, position.z); - return path; -} - -QString LocationScriptingInterface::getHostname() { - return NodeList::getInstance()->getDomainHandler().getHostname(); -} - -void LocationScriptingInterface::assign(const QString& url) { - QMetaObject::invokeMethod(Menu::getInstance(), "goToURL", Q_ARG(const QString&, url)); -} - -QScriptValue LocationScriptingInterface::locationGetter(QScriptContext* context, QScriptEngine* engine) { - return engine->newQObject(getInstance()); -} - -QScriptValue LocationScriptingInterface::locationSetter(QScriptContext* context, QScriptEngine* engine) { - LocationScriptingInterface::getInstance()->assign(context->argument(0).toString()); - return QScriptValue::UndefinedValue; -} diff --git a/interface/src/scripting/LocationScriptingInterface.h b/interface/src/scripting/LocationScriptingInterface.h deleted file mode 100644 index 20f63bceed..0000000000 --- a/interface/src/scripting/LocationScriptingInterface.h +++ /dev/null @@ -1,48 +0,0 @@ -// -// LocationScriptingInterface.h -// interface/src/scripting -// -// Created by Ryan Huffman on 4/29/14. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#ifndef hifi_LocationScriptingInterface_h -#define hifi_LocationScriptingInterface_h - -#include -#include -#include -#include -#include - -#include "Application.h" - -class LocationScriptingInterface : public QObject { - Q_OBJECT - Q_PROPERTY(bool isConnected READ isConnected) - Q_PROPERTY(QString href READ getHref) - Q_PROPERTY(QString protocol READ getProtocol) - Q_PROPERTY(QString hostname READ getHostname) - Q_PROPERTY(QString pathname READ getPathname) - LocationScriptingInterface() { }; -public: - static LocationScriptingInterface* getInstance(); - - bool isConnected(); - QString getHref(); - QString getProtocol() { return CUSTOM_URL_SCHEME; }; - QString getPathname(); - QString getHostname(); - - static QScriptValue locationGetter(QScriptContext* context, QScriptEngine* engine); - static QScriptValue locationSetter(QScriptContext* context, QScriptEngine* engine); - -public slots: - void assign(const QString& url); - -}; - -#endif // hifi_LocationScriptingInterface_h diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index 63f1b59f6b..5e3c7f22be 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -13,6 +13,8 @@ #include #include +#include + #include "AddressManager.h" AddressManager& AddressManager::getInstance() { @@ -20,6 +22,33 @@ AddressManager& AddressManager::getInstance() { return sharedInstance; } +QString AddressManager::pathForPositionAndOrientation(const glm::vec3& position, bool hasOrientation, + const glm::quat& orientation) { + + QString pathString = "/" + createByteArray(position); + + if (hasOrientation) { + QString orientationString = createByteArray(glm::degrees(safeEulerAngles(orientation))); + pathString += "/" + orientationString; + } + + return pathString; +} + +const JSONCallbackParameters& AddressManager::apiCallbackParameters() { + static bool hasSetupParameters = false; + static JSONCallbackParameters callbackParams; + + if (!hasSetupParameters) { + callbackParams.jsonCallbackReceiver = this; + callbackParams.jsonCallbackMethod = "handleAPIResponse"; + callbackParams.errorCallbackReceiver = this; + callbackParams.errorCallbackMethod = "handleAPIError"; + } + + return callbackParams; +} + void AddressManager::handleLookupString(const QString& lookupString) { // there are 4 possible lookup strings @@ -28,15 +57,77 @@ void AddressManager::handleLookupString(const QString& lookupString) { // 3. location string (posX,posY,posZ/eulerX,eulerY,eulerZ) // 4. domain network address (IP or dns resolvable hostname) + QString sanitizedLookupString = lookupString.trimmed().remove(HIFI_URL_SCHEME + "//"); + + // use our regex'ed helpers to figure out what we're supposed to do with this - if (!lookupHandledAsUsername(lookupString) && - !lookupHandledAsNetworkAddress(lookupString) && - !lookupHandledAsLocationString(lookupString)) { - + if (!isLookupHandledAsUsername(sanitizedLookupString) && + !isLookupHandledAsNetworkAddress(sanitizedLookupString) && + !isLookupHandledAsViewpoint(sanitizedLookupString)) { + attemptPlaceNameLookup(sanitizedLookupString); } } -bool AddressManager::lookupHandledAsNetworkAddress(const QString& lookupString) { +void AddressManager::handleAPIResponse(const QJsonObject &jsonObject) { + QJsonObject dataObject = jsonObject["data"].toObject(); + + const QString ADDRESS_API_DOMAIN_KEY = "domain"; + const QString ADDRESS_API_ONLINE_KEY = "online"; + + if (!dataObject.contains(ADDRESS_API_ONLINE_KEY) + || dataObject[ADDRESS_API_ONLINE_KEY].toBool()) { + + if (dataObject.contains(ADDRESS_API_DOMAIN_KEY)) { + QJsonObject domainObject = dataObject[ADDRESS_API_DOMAIN_KEY].toObject(); + + const QString DOMAIN_NETWORK_ADDRESS_KEY = "network_address"; + QString domainHostname = domainObject[DOMAIN_NETWORK_ADDRESS_KEY].toString(); + + emit possibleDomainChangeRequired(domainHostname); + + // take the path that came back + const QString LOCATION_KEY = "location"; + const QString LOCATION_PATH_KEY = "path"; + QString returnedPath; + + if (domainObject.contains(LOCATION_PATH_KEY)) { + returnedPath = domainObject[LOCATION_PATH_KEY].toString(); + } else if (domainObject.contains(LOCATION_KEY)) { + returnedPath = domainObject[LOCATION_KEY].toObject()[LOCATION_PATH_KEY].toString(); + } + + if (!returnedPath.isEmpty()) { + // try to parse this returned path as a viewpoint, that's the only thing it could be for now + if (!isLookupHandledAsViewpoint(returnedPath)) { + qDebug() << "Received a location path that was could not be handled as a viewpoint -" << returnedPath; + } + } + + } else { + qDebug() << "Received an address manager API response with no domain key. Cannot parse."; + qDebug() << jsonObject; + } + } else { + // we've been told that this result exists but is offline, emit our signal so the application can handle + emit lookupResultIsOffline(); + } +} + +void AddressManager::handleAPIError(QNetworkReply::NetworkError error, const QString& message) { + qDebug() << "AddressManager API error -" << error << "-" << message; +} + +const QString GET_PLACE = "/api/v1/places/%1"; + +void AddressManager::attemptPlaceNameLookup(const QString& lookupString) { + // assume this is a place name and see if we can get any info on it + QString placeName = QUrl::toPercentEncoding(lookupString); + AccountManager::getInstance().authenticatedRequest(GET_PLACE.arg(placeName), + QNetworkAccessManager::GetOperation, + apiCallbackParameters()); +} + +bool AddressManager::isLookupHandledAsNetworkAddress(const QString& lookupString) { const QString IP_ADDRESS_REGEX_STRING = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}" "([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(:\\d{1,5})?$"; @@ -46,23 +137,23 @@ bool AddressManager::lookupHandledAsNetworkAddress(const QString& lookupString) QRegExp hostnameRegex(HOSTNAME_REGEX_STRING, Qt::CaseInsensitive); if (hostnameRegex.indexIn(lookupString) != -1) { - emit domainChangeRequired(hostnameRegex.cap(0)); + emit possibleDomainChangeRequired(hostnameRegex.cap(0)); return true; } QRegExp ipAddressRegex(IP_ADDRESS_REGEX_STRING); if (ipAddressRegex.indexIn(lookupString) != -1) { - emit domainChangeRequired(ipAddressRegex.cap(0)); + emit possibleDomainChangeRequired(ipAddressRegex.cap(0)); return true; } return false; } -bool AddressManager::lookupHandledAsLocationString(const QString& lookupString) { +bool AddressManager::isLookupHandledAsViewpoint(const QString& lookupString) { const QString FLOAT_REGEX_STRING = "([-+]?[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?)"; - const QString TRIPLE_FLOAT_REGEX_STRING = FLOAT_REGEX_STRING + "\\s*,\\s*" + + const QString TRIPLE_FLOAT_REGEX_STRING = QString("\\/") + FLOAT_REGEX_STRING + "\\s*,\\s*" + FLOAT_REGEX_STRING + "\\s*,\\s*" + FLOAT_REGEX_STRING + "\\s*(?:$|\\/)"; QRegExp tripleFloatRegex(TRIPLE_FLOAT_REGEX_STRING); @@ -103,13 +194,19 @@ bool AddressManager::lookupHandledAsLocationString(const QString& lookupString) return false; } -bool AddressManager::lookupHandledAsUsername(const QString& lookupString) { +const QString GET_USER_LOCATION = "/api/v1/users/%1/location"; + +bool AddressManager::isLookupHandledAsUsername(const QString& lookupString) { const QString USERNAME_REGEX_STRING = "^@(\\S+)$"; QRegExp usernameRegex(USERNAME_REGEX_STRING); if (usernameRegex.indexIn(lookupString) != -1) { - // this is a username - pull the captured name and lookup that user's address + QString username = QUrl::toPercentEncoding(usernameRegex.cap(1)); + // this is a username - pull the captured name and lookup that user's location + AccountManager::getInstance().authenticatedRequest(GET_USER_LOCATION.arg(username), + QNetworkAccessManager::GetOperation, + apiCallbackParameters()); return true; } diff --git a/libraries/networking/src/AddressManager.h b/libraries/networking/src/AddressManager.h index e43102dd42..f1960b73f7 100644 --- a/libraries/networking/src/AddressManager.h +++ b/libraries/networking/src/AddressManager.h @@ -15,20 +15,37 @@ #include #include +#include + +#include "AccountManager.h" + +static const QString HIFI_URL_SCHEME = "hifi:"; + +const glm::quat EMPTY_QUAT = glm::quat(); class AddressManager : public QObject { Q_OBJECT public: static AddressManager& getInstance(); + static QString pathForPositionAndOrientation(const glm::vec3& position, bool hasOrientation = false, + const glm::quat& orientation = EMPTY_QUAT); + void handleLookupString(const QString& lookupString); + void attemptPlaceNameLookup(const QString& lookupString); +public slots: + void handleAPIResponse(const QJsonObject& jsonObject); + void handleAPIError(QNetworkReply::NetworkError error, const QString& message); signals: - void domainChangeRequired(const QString& newHostname); + void lookupResultIsOffline(); + void possibleDomainChangeRequired(const QString& newHostname); void locationChangeRequired(const glm::vec3& newPosition, bool hasOrientationChange, const glm::vec3& newOrientation); private: - bool lookupHandledAsNetworkAddress(const QString& lookupString); - bool lookupHandledAsLocationString(const QString& lookupString); - bool lookupHandledAsUsername(const QString& lookupString); + const JSONCallbackParameters& apiCallbackParameters(); + + bool isLookupHandledAsNetworkAddress(const QString& lookupString); + bool isLookupHandledAsViewpoint(const QString& lookupString); + bool isLookupHandledAsUsername(const QString& lookupString); }; #endif // hifi_AddressManager_h \ No newline at end of file diff --git a/libraries/networking/src/DomainHandler.cpp b/libraries/networking/src/DomainHandler.cpp index 91166129ad..9c0ae55d7e 100644 --- a/libraries/networking/src/DomainHandler.cpp +++ b/libraries/networking/src/DomainHandler.cpp @@ -73,6 +73,22 @@ void DomainHandler::setSockAddr(const HifiSockAddr& sockAddr, const QString& hos _hostname = hostname; } +void DomainHandler::setUUID(const QUuid& uuid) { + if (uuid != _uuid) { + _uuid = uuid; + qDebug() << "Domain uuid changed to" << uuidStringWithoutCurlyBraces(_uuid); + } +} + +QString DomainHandler::hostnameWithoutPort(const QString& hostname) { + int colonIndex = hostname.indexOf(':'); + return colonIndex > 0 ? hostname.left(colonIndex) : hostname; +} + +bool DomainHandler::isCurrentHostname(const QString& hostname) { + return hostnameWithoutPort(hostname) == _hostname; +} + void DomainHandler::setHostname(const QString& hostname) { if (hostname != _hostname) { diff --git a/libraries/networking/src/DomainHandler.h b/libraries/networking/src/DomainHandler.h index c65d687f5f..bfdb5d7f38 100644 --- a/libraries/networking/src/DomainHandler.h +++ b/libraries/networking/src/DomainHandler.h @@ -37,8 +37,10 @@ public: void clearSettings(); const QUuid& getUUID() const { return _uuid; } - void setUUID(const QUuid& uuid) { _uuid = uuid; } + void setUUID(const QUuid& uuid); + static QString hostnameWithoutPort(const QString& hostname); + bool isCurrentHostname(const QString& hostname); const QString& getHostname() const { return _hostname; } const QHostAddress& getIP() const { return _sockAddr.getAddress(); } From 7964180905adf14968455ec0c10be3fb57f93294 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 11 Sep 2014 17:33:01 -0700 Subject: [PATCH 09/22] handle place creation at new API endpoint --- interface/src/avatar/MyAvatar.h | 2 +- interface/src/location/LocationManager.cpp | 147 +----------------- interface/src/location/LocationManager.h | 14 -- interface/src/location/NamedLocation.cpp | 28 ++-- interface/src/location/NamedLocation.h | 32 ++-- interface/src/ui/ChatWindow.cpp | 3 +- interface/src/ui/OAuthWebViewHandler.cpp | 2 + interface/src/ui/ScriptEditorWidget.cpp | 2 + .../src/ui/overlays/BillboardOverlay.cpp | 4 +- 9 files changed, 43 insertions(+), 191 deletions(-) diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 86c10fdbb4..01dd392465 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -155,7 +155,7 @@ public slots: void decreaseSize(); void resetSize(); - void goToLocation(const glm::vec3& newPosition, bool hasOrientation, const glm::vec3& newOrientation); + void goToLocation(const glm::vec3& newPosition, bool hasOrientation = false, const glm::vec3& newOrientation = glm::vec3()); // Set/Get update the thrust that will move the avatar around void addThrust(glm::vec3 newThrust) { _thrust += newThrust; }; diff --git a/interface/src/location/LocationManager.cpp b/interface/src/location/LocationManager.cpp index 6beb1f5527..1228791c98 100644 --- a/interface/src/location/LocationManager.cpp +++ b/interface/src/location/LocationManager.cpp @@ -9,14 +9,11 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include +#include -#include "Application.h" #include "LocationManager.h" -#include - -const QString POST_PLACE_CREATE = "/api/v1/places/"; +const QString POST_LOCATION_CREATE = "/api/v1/locations/"; LocationManager& LocationManager::getInstance() { static LocationManager sharedInstance; @@ -44,145 +41,7 @@ void LocationManager::createNamedLocation(NamedLocation* namedLocation) { callbackParams.errorCallbackReceiver = this; callbackParams.errorCallbackMethod = "errorDataReceived"; - accountManager.authenticatedRequest(POST_PLACE_CREATE, QNetworkAccessManager::PostOperation, + accountManager.authenticatedRequest(POST_LOCATION_CREATE, QNetworkAccessManager::PostOperation, callbackParams, namedLocation->toJsonString().toUtf8()); } } - -void LocationManager::goToUrl(const QUrl& url) { -// if (location.startsWith(CUSTOM_URL_SCHEME + "/")) { -// QStringList urlParts = location.remove(0, CUSTOM_URL_SCHEME.length()).split('/', QString::SkipEmptyParts); -// -// if (urlParts.count() > 1) { -// // if url has 2 or more parts, the first one is domain name -// QString domain = urlParts[0]; -// -// // second part is either a destination coordinate or -// // a place name -// QString destination = urlParts[1]; -// -// // any third part is an avatar orientation. -// QString orientation = urlParts.count() > 2 ? urlParts[2] : QString(); -// -// goToDomain(domain); -// -// // goto either @user, #place, or x-xx,y-yy,z-zz -// // style co-ordinate. -// goTo(destination); -// -// if (!orientation.isEmpty()) { -// // location orientation -// goToOrientation(orientation); -// } -// } else if (urlParts.count() == 1) { -// QString destination = urlParts[0]; -// -// // If this starts with # or @, treat it as a user/location, otherwise treat it as a domain -// if (destination[0] == '#' || destination[0] == '@') { -// goTo(destination); -// } else { -// goToDomain(destination); -// } -// } -// return true; -// } -// return false; -} - -void LocationManager::goToOrientation(QString orientation) { - if (orientation.isEmpty()) { - return; - } - - QStringList orientationItems = orientation.remove(' ').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) { - - // 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); - - MyAvatar* myAvatar = Application::getInstance()->getAvatar(); - glm::quat avatarOrientation = myAvatar->getOrientation(); - if (newAvatarOrientation != avatarOrientation) { - myAvatar->setOrientation(newAvatarOrientation); - emit myAvatar->transformChanged(); - } - } -} - -bool LocationManager::goToDestination(QString destination) { - - QStringList coordinateItems = destination.remove(' ').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) { - - // 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); - - 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->slamPosition(newAvatarPos); - emit myAvatar->transformChanged(); - } - - return true; - } - - // no coordinates were parsed - return false; -} - -void LocationManager::handleAddressLookupError(QNetworkReply::NetworkError networkError, - const QString& errorString) { - QString messageBoxString; - - if (networkError == QNetworkReply::ContentNotFoundError) { - messageBoxString = "That address could not be found."; - } else { - messageBoxString = errorString; - } - - QMessageBox::warning(Application::getInstance()->getWindow(), "", messageBoxString); -} - -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); - } -} diff --git a/interface/src/location/LocationManager.h b/interface/src/location/LocationManager.h index ec580dfc7a..926d5d752b 100644 --- a/interface/src/location/LocationManager.h +++ b/interface/src/location/LocationManager.h @@ -14,7 +14,6 @@ #include -#include "AccountManager.h" #include "NamedLocation.h" class LocationManager : public QObject { @@ -30,19 +29,6 @@ public: }; void createNamedLocation(NamedLocation* namedLocation); - - void goTo(QString destination); - void goToUser(QString userName); - void goToPlace(QString placeName); - void goToUrl(const QUrl& url); - void goToOrientation(QString orientation); - bool goToDestination(QString destination); - -public slots: - void handleAddressLookupError(QNetworkReply::NetworkError networkError, const QString& errorString); - -private: - void replaceLastOccurrence(const QChar search, const QChar replace, QString& string); signals: void creationCompleted(LocationManager::NamedLocationCreateResponse response); diff --git a/interface/src/location/NamedLocation.cpp b/interface/src/location/NamedLocation.cpp index ed7701a391..997c36efba 100644 --- a/interface/src/location/NamedLocation.cpp +++ b/interface/src/location/NamedLocation.cpp @@ -9,19 +9,25 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include +#include + #include "NamedLocation.h" -const QString JSON_FORMAT = "{\"address\":{\"position\":\"%1,%2,%3\"," - "\"orientation\":\"%4,%5,%6,%7\",\"domain\":\"%8\"},\"name\":\"%9\"}"; +NamedLocation::NamedLocation(const QString& name, + const glm::vec3& position, const glm::quat& orientation, + const QUuid& domainID) : + _name(name), + _position(position), + _orientation(orientation), + _domainID(domainID) +{ + +} + +const QString JSON_FORMAT = "{\"location\":{\"path\":\"%1\",\"domain_id\":\"%2\"},\"name\":\"%3\"}"; 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); + return JSON_FORMAT.arg(AddressManager::pathForPositionAndOrientation(_position, true, _orientation), + uuidStringWithoutCurlyBraces(_domainID), _name); } diff --git a/interface/src/location/NamedLocation.h b/interface/src/location/NamedLocation.h index ffbd157263..fca6852062 100644 --- a/interface/src/location/NamedLocation.h +++ b/interface/src/location/NamedLocation.h @@ -22,39 +22,33 @@ class NamedLocation : public QObject { Q_OBJECT public: - NamedLocation(QString locationName, glm::vec3 location, glm::quat orientation, QString domain) { - _locationName = locationName; - _location = location; - _orientation = orientation; - _domain = domain; - } + NamedLocation(const QString& name, const glm::vec3& position, const glm::quat& orientation, const QUuid& domainID); QString toJsonString(); - bool isEmpty() { return _locationName.isNull() || _locationName.isEmpty(); } + bool isEmpty() { return _name.isNull() || _name.isEmpty(); } - void setLocationName(QString locationName) { _locationName = locationName; } - QString locationName() { return _locationName; } + void setName(QString name) { _name = name; } + const QString& getName() const { return _name; } - void setLocation(glm::vec3 location) { _location = location; } - glm::vec3 location() { return _location; } + void setLocation(glm::vec3 position) { _position = position; } + const glm::vec3& getPosition() const { return _position; } - void setOrientation(glm::quat orentation) { _orientation = orentation; } - glm::quat orientation() { return _orientation; } + void setOrientation(const glm::quat& orentation) { _orientation = orentation; } + const glm::quat& getOrientation() const { return _orientation; } - void setDomain(QString domain) { _domain = domain; } - QString domain() { return _domain; } + void setDomainID(const QUuid& domainID) { _domainID = domainID; } + const QUuid& getDomainID() const { return _domainID; } signals: void dataReceived(bool locationExists); private: - - QString _locationName; + QString _name; QString _createdBy; - glm::vec3 _location; + glm::vec3 _position; glm::quat _orientation; - QString _domain; + QUuid _domainID; }; diff --git a/interface/src/ui/ChatWindow.cpp b/interface/src/ui/ChatWindow.cpp index 9961a84e79..cf62b75215 100644 --- a/interface/src/ui/ChatWindow.cpp +++ b/interface/src/ui/ChatWindow.cpp @@ -17,6 +17,8 @@ #include #include +#include + #include "Application.h" #include "ChatMessageArea.h" #include "FlowLayout.h" @@ -28,7 +30,6 @@ #include "ChatWindow.h" - const int NUM_MESSAGES_TO_TIME_STAMP = 20; const QRegularExpression regexLinks("((?:(?:ftp)|(?:https?)|(?:hifi))://\\S+)"); diff --git a/interface/src/ui/OAuthWebViewHandler.cpp b/interface/src/ui/OAuthWebViewHandler.cpp index 8ec415584d..a1dbfe9e0b 100644 --- a/interface/src/ui/OAuthWebViewHandler.cpp +++ b/interface/src/ui/OAuthWebViewHandler.cpp @@ -11,6 +11,8 @@ #include +#include + #include "Application.h" #include "OAuthWebViewHandler.h" diff --git a/interface/src/ui/ScriptEditorWidget.cpp b/interface/src/ui/ScriptEditorWidget.cpp index f99c9d5ac4..1473e4a6a0 100644 --- a/interface/src/ui/ScriptEditorWidget.cpp +++ b/interface/src/ui/ScriptEditorWidget.cpp @@ -23,6 +23,8 @@ #include #include +#include + #include "Application.h" #include "ScriptHighlighting.h" diff --git a/interface/src/ui/overlays/BillboardOverlay.cpp b/interface/src/ui/overlays/BillboardOverlay.cpp index 7d85d54fef..f29fa6ed8d 100644 --- a/interface/src/ui/overlays/BillboardOverlay.cpp +++ b/interface/src/ui/overlays/BillboardOverlay.cpp @@ -9,7 +9,9 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include "../../Application.h" +#include + +#include "Application.h" #include "BillboardOverlay.h" From 5f6563f4c9e8d3f32688d16af061beb28342c2ec Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 11 Sep 2014 17:42:04 -0700 Subject: [PATCH 10/22] don't allow named location creation with no domain UUID --- interface/src/Menu.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index b8835407b0..49b185fe47 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -1217,23 +1217,34 @@ void Menu::nameLocation() { // check if user is logged in or show login dialog if not AccountManager& accountManager = AccountManager::getInstance(); + 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."); msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); msgBox.button(QMessageBox::Ok)->setText("Login"); + if (msgBox.exec() == QMessageBox::Ok) { loginForCurrentDomain(); } return; } + + DomainHandler& domainHandler = NodeList::getInstance()->getDomainHandler(); + if (domainHandler.getUUID().isNull()) { + const QString UNREGISTERED_DOMAIN_MESSAGE = "This domain is not registered with High Fidelity." + "\n\nYou cannot create a global location in an unregistered domain."; + QMessageBox::critical(this, "Unregistered Domain", UNREGISTERED_DOMAIN_MESSAGE); + + 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" + "When they come here, they'll have the same viewpoint\n" "(wherever you are standing and looking now) as you.\n\n" "Location name:"); @@ -1251,7 +1262,7 @@ void Menu::nameLocation() { connect(manager, &LocationManager::creationCompleted, this, &Menu::namedLocationCreated); NamedLocation* location = new NamedLocation(locationName, myAvatar->getPosition(), myAvatar->getOrientation(), - NodeList::getInstance()->getDomainHandler().getHostname()); + domainHandler.getUUID()); manager->createNamedLocation(location); } } From 745edb8b0a9dc835b900a04c0c84c5e71b906c82 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 12 Sep 2014 09:10:47 -0700 Subject: [PATCH 11/22] fix error handling for location naming --- interface/src/Menu.cpp | 29 ++++--------- interface/src/Menu.h | 3 +- interface/src/UserLocationsModel.cpp | 8 ++-- interface/src/UserLocationsModel.h | 4 +- interface/src/avatar/MyAvatar.cpp | 5 --- interface/src/avatar/MyAvatar.h | 1 - interface/src/location/LocationManager.cpp | 46 ++++++++++++++++++++- interface/src/location/LocationManager.h | 4 +- interface/src/location/NamedLocation.cpp | 2 +- libraries/networking/src/AccountManager.cpp | 3 +- 10 files changed, 63 insertions(+), 42 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 49b185fe47..98f2986b9a 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -154,11 +154,6 @@ Menu::Menu() : appInstance, SLOT(toggleRunningScriptsWidget())); addDisabledActionAndSeparator(fileMenu, "Go"); - addActionToQMenuAndActionHash(fileMenu, - MenuOption::GoHome, - Qt::CTRL | Qt::Key_G, - appInstance->getAvatar(), - SLOT(goHome())); addActionToQMenuAndActionHash(fileMenu, MenuOption::NameLocation, Qt::CTRL | Qt::Key_N, @@ -1183,23 +1178,13 @@ void Menu::muteEnvironment() { free(packet); } -void Menu::namedLocationCreated(LocationManager::NamedLocationCreateResponse response) { +void Menu::displayNameLocationResponse(const QString& errorString) { - 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(); + if (!errorString.isEmpty()) { + QMessageBox msgBox; + msgBox.setText(errorString); + msgBox.exec(); + } } void Menu::toggleLocationList() { @@ -1259,7 +1244,7 @@ void Menu::nameLocation() { MyAvatar* myAvatar = Application::getInstance()->getAvatar(); LocationManager* manager = new LocationManager(); - connect(manager, &LocationManager::creationCompleted, this, &Menu::namedLocationCreated); + connect(manager, &LocationManager::creationCompleted, this, &Menu::displayNameLocationResponse); NamedLocation* location = new NamedLocation(locationName, myAvatar->getPosition(), myAvatar->getOrientation(), domainHandler.getUUID()); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 078c2b4255..d8658f956e 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -216,7 +216,7 @@ private slots: void toggleConsole(); void toggleChat(); void audioMuteToggled(); - void namedLocationCreated(LocationManager::NamedLocationCreateResponse response); + void displayNameLocationResponse(const QString& errorString); void muteEnvironment(); private: @@ -390,7 +390,6 @@ namespace MenuOption { const QString FullscreenMirror = "Fullscreen Mirror"; const QString GlowMode = "Cycle Glow Mode"; const QString GlowWhenSpeaking = "Glow When Speaking"; - const QString GoHome = "Go Home"; const QString HeadMouse = "Head Mouse"; const QString IncreaseAvatarSize = "Increase Avatar Size"; const QString IncreaseVoxelSize = "Increase Voxel Size"; diff --git a/interface/src/UserLocationsModel.cpp b/interface/src/UserLocationsModel.cpp index e84cae8f95..0a035faedd 100644 --- a/interface/src/UserLocationsModel.cpp +++ b/interface/src/UserLocationsModel.cpp @@ -75,10 +75,10 @@ void UserLocation::handleRenameResponse(const QJsonObject& responseData) { emit updated(_name); } -void UserLocation::handleRenameError(QNetworkReply::NetworkError error, const QString& errorString) { +void UserLocation::handleRenameError(QNetworkReply& errorReply) { _updating = false; - QString msg = "There was an error renaming location '" + _name + "': " + errorString; + QString msg = "There was an error renaming location '" + _name + "': " + errorReply.errorString(); qDebug() << msg; QMessageBox::warning(Application::getInstance()->getWindow(), "Error", msg); @@ -109,10 +109,10 @@ void UserLocation::handleDeleteResponse(const QJsonObject& responseData) { } } -void UserLocation::handleDeleteError(QNetworkReply::NetworkError error, const QString& errorString) { +void UserLocation::handleDeleteError(QNetworkReply& errorReply) { _updating = false; - QString msg = "There was an error deleting location '" + _name + "': " + errorString; + QString msg = "There was an error deleting location '" + _name + "': " + errorReply.errorString(); qDebug() << msg; QMessageBox::warning(Application::getInstance()->getWindow(), "Error", msg); } diff --git a/interface/src/UserLocationsModel.h b/interface/src/UserLocationsModel.h index d3f86faa5a..4a1eb9fd0a 100644 --- a/interface/src/UserLocationsModel.h +++ b/interface/src/UserLocationsModel.h @@ -31,9 +31,9 @@ public: public slots: void handleRenameResponse(const QJsonObject& responseData); - void handleRenameError(QNetworkReply::NetworkError error, const QString& errorString); + void handleRenameError(QNetworkReply& errorReply); void handleDeleteResponse(const QJsonObject& responseData); - void handleDeleteError(QNetworkReply::NetworkError error, const QString& errorString); + void handleDeleteError(QNetworkReply& errorReply); signals: void updated(const QString& name); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index b4335512ef..8238969eda 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1778,11 +1778,6 @@ void MyAvatar::maybeUpdateBillboard() { sendBillboardPacket(); } -void MyAvatar::goHome() { - qDebug("Going Home!"); - slamPosition(START_LOCATION); -} - void MyAvatar::increaseSize() { if ((1.0f + SCALING_RATIO) * _targetScale < MAX_AVATAR_SCALE) { _targetScale *= (1.0f + SCALING_RATIO); diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 01dd392465..6195bcc9b7 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -150,7 +150,6 @@ public: const PlayerPointer getPlayer() const { return _player; } public slots: - void goHome(); void increaseSize(); void decreaseSize(); void resetSize(); diff --git a/interface/src/location/LocationManager.cpp b/interface/src/location/LocationManager.cpp index 1228791c98..029657996b 100644 --- a/interface/src/location/LocationManager.cpp +++ b/interface/src/location/LocationManager.cpp @@ -9,6 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include + #include #include "LocationManager.h" @@ -20,15 +22,17 @@ LocationManager& LocationManager::getInstance() { return sharedInstance; } +const QString UNKNOWN_ERROR_MESSAGE = "Unknown error creating named location. Please try again!"; + void LocationManager::namedLocationDataReceived(const QJsonObject& data) { if (data.isEmpty()) { return; } if (data.contains("status") && data["status"].toString() == "success") { - emit creationCompleted(LocationManager::Created); + emit creationCompleted(QString()); } else { - emit creationCompleted(LocationManager::AlreadyExists); + emit creationCompleted(UNKNOWN_ERROR_MESSAGE); } } @@ -45,3 +49,41 @@ void LocationManager::createNamedLocation(NamedLocation* namedLocation) { callbackParams, namedLocation->toJsonString().toUtf8()); } } + +void LocationManager::errorDataReceived(QNetworkReply& errorReply) { + + if (errorReply.header(QNetworkRequest::ContentTypeHeader).toString().startsWith("application/json")) { + // we have some JSON error data we can parse for our error message + QJsonDocument responseJson = QJsonDocument::fromJson(errorReply.readAll()); + + QJsonObject dataObject = responseJson.object()["data"].toObject(); + + qDebug() << dataObject; + + QString errorString = "There was a problem creating that location.\n"; + + // construct the error string from the returned attribute errors + foreach(const QString& key, dataObject.keys()) { + errorString += "\n\u2022 " + key + " - "; + + QJsonValue keyedErrorValue = dataObject[key]; + + if (keyedErrorValue.isArray()) { + foreach(const QJsonValue& attributeErrorValue, keyedErrorValue.toArray()) { + errorString += attributeErrorValue.toString() + ", "; + } + + // remove the trailing comma at end of error list + errorString.remove(errorString.length() - 2, 2); + } else if (keyedErrorValue.isString()) { + errorString += keyedErrorValue.toString(); + } + } + + // emit our creationCompleted signal with the error + emit creationCompleted(errorString); + + } else { + creationCompleted(UNKNOWN_ERROR_MESSAGE); + } +} diff --git a/interface/src/location/LocationManager.h b/interface/src/location/LocationManager.h index 926d5d752b..b6a662e323 100644 --- a/interface/src/location/LocationManager.h +++ b/interface/src/location/LocationManager.h @@ -13,6 +13,7 @@ #define hifi_LocationManager_h #include +#include #include "NamedLocation.h" @@ -31,10 +32,11 @@ public: void createNamedLocation(NamedLocation* namedLocation); signals: - void creationCompleted(LocationManager::NamedLocationCreateResponse response); + void creationCompleted(const QString& errorMessage); private slots: void namedLocationDataReceived(const QJsonObject& data); + void errorDataReceived(QNetworkReply& errorReply); }; diff --git a/interface/src/location/NamedLocation.cpp b/interface/src/location/NamedLocation.cpp index 997c36efba..7785edfea1 100644 --- a/interface/src/location/NamedLocation.cpp +++ b/interface/src/location/NamedLocation.cpp @@ -25,7 +25,7 @@ NamedLocation::NamedLocation(const QString& name, } -const QString JSON_FORMAT = "{\"location\":{\"path\":\"%1\",\"domain_id\":\"%2\"},\"name\":\"%3\"}"; +const QString JSON_FORMAT = "{\"location\":{\"path\":\"%1\",\"domain_id\":\"%2\",\"name\":\"%3\"}}"; QString NamedLocation::toJsonString() { return JSON_FORMAT.arg(AddressManager::pathForPositionAndOrientation(_position, true, _orientation), diff --git a/libraries/networking/src/AccountManager.cpp b/libraries/networking/src/AccountManager.cpp index 7fda9d74c9..1100371ac9 100644 --- a/libraries/networking/src/AccountManager.cpp +++ b/libraries/networking/src/AccountManager.cpp @@ -292,8 +292,7 @@ void AccountManager::passErrorToCallback(QNetworkReply* requestReply) { if (callbackParams.errorCallbackReceiver) { // invoke the right method on the callback receiver QMetaObject::invokeMethod(callbackParams.errorCallbackReceiver, qPrintable(callbackParams.errorCallbackMethod), - Q_ARG(QNetworkReply::NetworkError, requestReply->error()), - Q_ARG(const QString&, requestReply->errorString())); + Q_ARG(QNetworkReply&, *requestReply)); // remove the related reply-callback group from the map _pendingCallbackMap.remove(requestReply); From 74295a3869baff209f6e12db6515819249ce540d Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 12 Sep 2014 09:52:34 -0700 Subject: [PATCH 12/22] repairs for new location lookup --- interface/src/Menu.h | 1 + interface/src/UserLocationsModel.cpp | 41 +++++++++++++----------- interface/src/UserLocationsModel.h | 12 +++---- interface/src/ui/UserLocationsDialog.cpp | 2 +- 4 files changed, 31 insertions(+), 25 deletions(-) diff --git a/interface/src/Menu.h b/interface/src/Menu.h index d8658f956e..fabaa0dce7 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -390,6 +390,7 @@ namespace MenuOption { const QString FullscreenMirror = "Fullscreen Mirror"; const QString GlowMode = "Cycle Glow Mode"; const QString GlowWhenSpeaking = "Glow When Speaking"; + const QString GoToUser = "Go To User"; const QString HeadMouse = "Head Mouse"; const QString IncreaseAvatarSize = "Increase Avatar Size"; const QString IncreaseVoxelSize = "Increase Voxel Size"; diff --git a/interface/src/UserLocationsModel.cpp b/interface/src/UserLocationsModel.cpp index 0a035faedd..0fae0d8800 100644 --- a/interface/src/UserLocationsModel.cpp +++ b/interface/src/UserLocationsModel.cpp @@ -18,14 +18,13 @@ #include "Application.h" #include "UserLocationsModel.h" -static const QString PLACES_GET = "/api/v1/places"; -static const QString PLACES_UPDATE = "/api/v1/places/%1"; -static const QString PLACES_DELETE= "/api/v1/places/%1"; +static const QString LOCATIONS_GET = "/api/v1/locations"; +static const QString LOCATION_UPDATE_OR_DELETE = "/api/v1/locations/%1"; -UserLocation::UserLocation(QString id, QString name, QString location) : +UserLocation::UserLocation(const QString& id, const QString& name, const QString& address) : _id(id), _name(name), - _location(location), + _address(address), _previousName(name), _updating(false) { } @@ -35,10 +34,15 @@ void UserLocation::requestRename(const QString& newName) { _updating = true; JSONCallbackParameters callbackParams(this, "handleRenameResponse", this, "handleRenameError"); + QJsonObject jsonNameObject; - jsonNameObject.insert("name", QJsonValue(newName)); + jsonNameObject.insert("name", newName); + + QJsonObject locationObject; + locationObject.insert("location", jsonNameObject); + QJsonDocument jsonDocument(jsonNameObject); - AccountManager::getInstance().authenticatedRequest(PLACES_UPDATE.arg(_id), + AccountManager::getInstance().authenticatedRequest(LOCATION_UPDATE_OR_DELETE.arg(_id), QNetworkAccessManager::PutOperation, callbackParams, jsonDocument.toJson()); @@ -54,7 +58,9 @@ void UserLocation::handleRenameResponse(const QJsonObject& responseData) { QJsonValue status = responseData["status"]; if (!status.isUndefined() && status.toString() == "success") { - QString updatedName = responseData["data"].toObject()["name"].toString(); + qDebug() << responseData; + QString updatedName = responseData["data"].toObject()["location"].toObject()["name"].toString(); + qDebug() << "The updated name is" << updatedName; _name = updatedName; } else { _name = _previousName; @@ -90,7 +96,7 @@ void UserLocation::requestDelete() { _updating = true; JSONCallbackParameters callbackParams(this, "handleDeleteResponse", this, "handleDeleteError"); - AccountManager::getInstance().authenticatedRequest(PLACES_DELETE.arg(_id), + AccountManager::getInstance().authenticatedRequest(LOCATION_UPDATE_OR_DELETE.arg(_id), QNetworkAccessManager::DeleteOperation, callbackParams); } @@ -153,7 +159,7 @@ void UserLocationsModel::refresh() { endResetModel(); JSONCallbackParameters callbackParams(this, "handleLocationsResponse"); - AccountManager::getInstance().authenticatedRequest(PLACES_GET, + AccountManager::getInstance().authenticatedRequest(LOCATIONS_GET, QNetworkAccessManager::GetOperation, callbackParams); } @@ -165,14 +171,13 @@ void UserLocationsModel::handleLocationsResponse(const QJsonObject& responseData QJsonValue status = responseData["status"]; if (!status.isUndefined() && status.toString() == "success") { beginResetModel(); - QJsonArray locations = responseData["data"].toObject()["places"].toArray(); + QJsonArray locations = responseData["data"].toObject()["locations"].toArray(); for (QJsonArray::const_iterator it = locations.constBegin(); it != locations.constEnd(); it++) { QJsonObject location = (*it).toObject(); - QJsonObject address = location["address"].toObject(); + QString locationAddress = "hifi://" + location["domain"].toObject()["name"].toString() + + location["path"].toString(); UserLocation* userLocation = new UserLocation(location["id"].toString(), location["name"].toString(), - "hifi://" + address["domain"].toString() - + "/" + address["position"].toString() - + "/" + address["orientation"].toString()); + locationAddress); _locations.append(userLocation); connect(userLocation, &UserLocation::deleted, this, &UserLocationsModel::removeLocation); connect(userLocation, &UserLocation::updated, this, &UserLocationsModel::update); @@ -214,8 +219,8 @@ QVariant UserLocationsModel::data(const QModelIndex& index, int role) const { return QVariant(); } else if (index.column() == NameColumn) { return _locations[index.row()]->name(); - } else if (index.column() == LocationColumn) { - return QVariant(_locations[index.row()]->location()); + } else if (index.column() == AddressColumn) { + return QVariant(_locations[index.row()]->address()); } } @@ -226,7 +231,7 @@ QVariant UserLocationsModel::headerData(int section, Qt::Orientation orientation if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { switch (section) { case NameColumn: return "Name"; - case LocationColumn: return "Location"; + case AddressColumn: return "Address"; default: return QVariant(); } } diff --git a/interface/src/UserLocationsModel.h b/interface/src/UserLocationsModel.h index 4a1eb9fd0a..54518d72e1 100644 --- a/interface/src/UserLocationsModel.h +++ b/interface/src/UserLocationsModel.h @@ -20,14 +20,14 @@ class UserLocation : public QObject { Q_OBJECT public: - UserLocation(QString id, QString name, QString location); + UserLocation(const QString& id, const QString& name, const QString& address); bool isUpdating() { return _updating; } void requestRename(const QString& newName); void requestDelete(); - QString id() { return _id; } - QString name() { return _name; } - QString location() { return _location; } + const QString& id() { return _id; } + const QString& name() { return _name; } + const QString& address() { return _address; } public slots: void handleRenameResponse(const QJsonObject& responseData); @@ -42,7 +42,7 @@ signals: private: QString _id; QString _name; - QString _location; + QString _address; QString _previousName; bool _updating; @@ -65,7 +65,7 @@ public: enum Columns { NameColumn = 0, - LocationColumn + AddressColumn }; public slots: diff --git a/interface/src/ui/UserLocationsDialog.cpp b/interface/src/ui/UserLocationsDialog.cpp index ca1a9b5ad6..5aed0c3df4 100644 --- a/interface/src/ui/UserLocationsDialog.cpp +++ b/interface/src/ui/UserLocationsDialog.cpp @@ -51,7 +51,7 @@ void UserLocationsDialog::updateEnabled() { } void UserLocationsDialog::goToModelIndex(const QModelIndex& index) { - QVariant location = _proxyModel.data(index.sibling(index.row(), UserLocationsModel::LocationColumn)); + QVariant location = _proxyModel.data(index.sibling(index.row(), UserLocationsModel::AddressColumn)); // Menu::getInstance()->goToURL(location.toString()); } From 7896119228c6405bace9511f7cfe582bd755cc9c Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 12 Sep 2014 09:56:40 -0700 Subject: [PATCH 13/22] remap two goToUrl calls to AddressManager --- interface/src/Application.cpp | 2 +- interface/src/ui/UserLocationsDialog.cpp | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 39c8f1a82f..350f0fe1b9 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -813,7 +813,7 @@ bool Application::event(QEvent* event) { QFileOpenEvent* fileEvent = static_cast(event); bool isHifiSchemeURL = !fileEvent->url().isEmpty() && fileEvent->url().toLocalFile().startsWith(HIFI_URL_SCHEME); if (isHifiSchemeURL) { -// Menu::getInstance()->goToURL(fileEvent->url().toLocalFile()); + AddressManager::getInstance().handleLookupString(fileEvent->url().toLocalFile()); } return false; } diff --git a/interface/src/ui/UserLocationsDialog.cpp b/interface/src/ui/UserLocationsDialog.cpp index 5aed0c3df4..31f388d045 100644 --- a/interface/src/ui/UserLocationsDialog.cpp +++ b/interface/src/ui/UserLocationsDialog.cpp @@ -13,6 +13,8 @@ #include #include +#include + #include "Menu.h" #include "UserLocationsDialog.h" @@ -51,8 +53,8 @@ void UserLocationsDialog::updateEnabled() { } void UserLocationsDialog::goToModelIndex(const QModelIndex& index) { - QVariant location = _proxyModel.data(index.sibling(index.row(), UserLocationsModel::AddressColumn)); -// Menu::getInstance()->goToURL(location.toString()); + QVariant address = _proxyModel.data(index.sibling(index.row(), UserLocationsModel::AddressColumn)); + AddressManager::getInstance().handleLookupString(address.toString()); } void UserLocationsDialog::deleteSelection() { From 1f2020d1690e3c2691c23adaee147c22ccc1eaa8 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 12 Sep 2014 10:13:33 -0700 Subject: [PATCH 14/22] some url handling repairs, move existing error reply handlers to new format --- interface/src/Application.cpp | 66 ++++--------------- interface/src/Application.h | 3 +- interface/src/ModelUploader.cpp | 4 +- interface/src/ModelUploader.h | 2 +- interface/src/ui/ChatMessageArea.cpp | 4 +- libraries/networking/src/AddressManager.cpp | 14 +++- libraries/networking/src/AddressManager.h | 3 +- .../networking/src/UserActivityLogger.cpp | 4 +- libraries/networking/src/UserActivityLogger.h | 2 +- 9 files changed, 37 insertions(+), 65 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 350f0fe1b9..13a94ebebf 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -358,9 +358,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : Particle::setVoxelEditPacketSender(&_voxelEditSender); Particle::setParticleEditPacketSender(&_particleEditSender); - // when -url in command line, teleport to location - urlGoTo(argc, constArgv); - // For now we're going to set the PPS for outbound packets to be super high, this is // probably not the right long term solution. But for now, we're going to do this to // allow you to move a particle around in your hand @@ -405,13 +402,15 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : connect(_window, &MainWindow::windowGeometryChanged, _runningScriptsWidget, &RunningScriptsWidget::setBoundary); + + AddressManager& addressManager = AddressManager::getInstance(); // connect to the domainChangeRequired signal on AddressManager - connect(&AddressManager::getInstance(), &AddressManager::possibleDomainChangeRequired, + connect(&addressManager, &AddressManager::possibleDomainChangeRequired, this, &Application::changeDomainHostname); - //When -url in command line, teleport to location - urlGoTo(argc, constArgv); + // when -url in command line, teleport to location + addressManager.handleUrl(QUrl(getCmdOption(argc, constArgv, "-url"))); // call the OAuthWebviewHandler static getter so that its instance lives in our thread OAuthWebViewHandler::getInstance(); @@ -1066,10 +1065,6 @@ void Application::keyPressEvent(QKeyEvent* event) { case Qt::Key_Equal: _myAvatar->resetSize(); break; - - case Qt::Key_At: -// Menu::getInstance()->goTo(); - break; default: event->ignore(); break; @@ -1323,7 +1318,7 @@ void Application::dropEvent(QDropEvent *event) { SnapshotMetaData* snapshotData = Snapshot::parseSnapshotData(snapshotPath); if (snapshotData) { if (!snapshotData->getDomain().isEmpty()) { -// Menu::getInstance()->goToDomain(snapshotData->getDomain()); + changeDomainHostname(snapshotData->getDomain()); } _myAvatar->setPosition(snapshotData->getLocation()); @@ -3797,14 +3792,6 @@ ScriptEngine* Application::loadScript(const QString& scriptFilename, bool isUser scriptEngine->registerGlobalObject("Overlays", &_overlays); - QScriptValue windowValue = scriptEngine->registerGlobalObject("Window", WindowScriptingInterface::getInstance()); -// scriptEngine->registerGetterSetter("location", LocationScriptingInterface::locationGetter, -// LocationScriptingInterface::locationSetter, windowValue); -// -// // register `location` on the global object. -// scriptEngine->registerGetterSetter("location", LocationScriptingInterface::locationGetter, -// LocationScriptingInterface::locationSetter); - scriptEngine->registerGlobalObject("Menu", MenuScriptingInterface::getInstance()); scriptEngine->registerGlobalObject("Settings", SettingsScriptingInterface::getInstance()); scriptEngine->registerGlobalObject("AudioDevice", AudioDeviceScriptingInterface::getInstance()); @@ -3932,6 +3919,13 @@ void Application::uploadAttachment() { uploadModel(ATTACHMENT_MODEL); } +void Application::openUrl(const QUrl& url) { + if (!AddressManager::getInstance().handleUrl(url)) { + // address manager did not handle - ask QDesktopServices to handle + QDesktopServices::openUrl(url); + } +} + void Application::domainSettingsReceived(const QJsonObject& domainSettingsObject) { // from the domain-handler, figure out the satoshi cost per voxel and per meter cubed @@ -4120,37 +4114,3 @@ void Application::takeSnapshot() { } _snapshotShareDialog->show(); } - -void Application::urlGoTo(int argc, const char * constArgv[]) { - //Gets the url (hifi://domain/destination/orientation) - QString customUrl = getCmdOption(argc, constArgv, "-url"); - if(customUrl.startsWith(HIFI_URL_SCHEME + "//")) { - QStringList urlParts = customUrl.remove(0, HIFI_URL_SCHEME.length() + 2).split('/', QString::SkipEmptyParts); - if (urlParts.count() == 1) { - // location coordinates or place name - QString domain = urlParts[0]; -// Menu::goToDomain(domain); - } else if (urlParts.count() > 1) { - // if url has 2 or more parts, the first one is domain name - QString domain = urlParts[0]; - - // second part is either a destination coordinate or - // a place name - QString destination = urlParts[1]; - - // any third part is an avatar orientation. - QString orientation = urlParts.count() > 2 ? urlParts[2] : QString(); - -// Menu::goToDomain(domain); - - // goto either @user, #place, or x-xx,y-yy,z-zz - // style co-ordinate. -// Menu::goTo(destination); - - if (!orientation.isEmpty()) { - // location orientation -// Menu::goToOrientation(orientation); - } - } - } -} diff --git a/interface/src/Application.h b/interface/src/Application.h index ef08cf4ec5..0c50aca4b9 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -152,7 +152,6 @@ public: void initializeGL(); void paintGL(); void resizeGL(int width, int height); - void urlGoTo(int argc, const char * constArgv[]); void keyPressEvent(QKeyEvent* event); void keyReleaseEvent(QKeyEvent* event); @@ -352,6 +351,8 @@ public slots: void uploadHead(); void uploadSkeleton(); void uploadAttachment(); + + void openUrl(const QUrl& url); void bumpSettings() { ++_numChangedSettings; } diff --git a/interface/src/ModelUploader.cpp b/interface/src/ModelUploader.cpp index 12a4b145cc..d120f74991 100644 --- a/interface/src/ModelUploader.cpp +++ b/interface/src/ModelUploader.cpp @@ -381,11 +381,11 @@ void ModelUploader::uploadSuccess(const QJsonObject& jsonResponse) { checkS3(); } -void ModelUploader::uploadFailed(QNetworkReply::NetworkError errorCode, const QString& errorString) { +void ModelUploader::uploadFailed(QNetworkReply& errorReply) { if (_progressDialog) { _progressDialog->reject(); } - qDebug() << "Model upload failed (" << errorCode << "): " << errorString; + qDebug() << "Model upload failed (" << errorReply.error() << "): " << errorReply.errorString(); QMessageBox::warning(NULL, QString("ModelUploader::uploadFailed()"), QString("There was a problem with your upload, please try again later."), diff --git a/interface/src/ModelUploader.h b/interface/src/ModelUploader.h index 2596120751..a1c7a27393 100644 --- a/interface/src/ModelUploader.h +++ b/interface/src/ModelUploader.h @@ -43,7 +43,7 @@ private slots: void checkJSON(const QJsonObject& jsonResponse); void uploadUpdate(qint64 bytesSent, qint64 bytesTotal); void uploadSuccess(const QJsonObject& jsonResponse); - void uploadFailed(QNetworkReply::NetworkError errorCode, const QString& errorString); + void uploadFailed(QNetworkReply& errorReply); void checkS3(); void processCheck(); diff --git a/interface/src/ui/ChatMessageArea.cpp b/interface/src/ui/ChatMessageArea.cpp index ab93c7abe9..1dc38e9c94 100644 --- a/interface/src/ui/ChatMessageArea.cpp +++ b/interface/src/ui/ChatMessageArea.cpp @@ -19,8 +19,8 @@ ChatMessageArea::ChatMessageArea(bool useFixedHeight) : QTextBrowser(), _useFixe connect(document()->documentLayout(), &QAbstractTextDocumentLayout::documentSizeChanged, this, &ChatMessageArea::updateLayout); -// connect(this, &QTextBrowser::anchorClicked, -// Menu::getInstance(), &Menu::openUrl); + + connect(this, &QTextBrowser::anchorClicked, Application::getInstance(), &Application::openUrl); } void ChatMessageArea::setHtml(const QString& html) { diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index 5e3c7f22be..591a7a3ef6 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -49,6 +49,16 @@ const JSONCallbackParameters& AddressManager::apiCallbackParameters() { return callbackParams; } +bool AddressManager::handleUrl(const QUrl& lookupUrl) { + if (lookupUrl.scheme() == HIFI_URL_SCHEME) { + // we've verified that this is a valid hifi URL - hand it off to handleLookupString + handleLookupString(lookupUrl.toString()); + return true; + } + + return false; +} + void AddressManager::handleLookupString(const QString& lookupString) { // there are 4 possible lookup strings @@ -113,8 +123,8 @@ void AddressManager::handleAPIResponse(const QJsonObject &jsonObject) { } } -void AddressManager::handleAPIError(QNetworkReply::NetworkError error, const QString& message) { - qDebug() << "AddressManager API error -" << error << "-" << message; +void AddressManager::handleAPIError(QNetworkReply& errorReply) { + qDebug() << "AddressManager API error -" << errorReply.error() << "-" << errorReply.errorString(); } const QString GET_PLACE = "/api/v1/places/%1"; diff --git a/libraries/networking/src/AddressManager.h b/libraries/networking/src/AddressManager.h index f1960b73f7..8ccffe39fa 100644 --- a/libraries/networking/src/AddressManager.h +++ b/libraries/networking/src/AddressManager.h @@ -31,11 +31,12 @@ public: static QString pathForPositionAndOrientation(const glm::vec3& position, bool hasOrientation = false, const glm::quat& orientation = EMPTY_QUAT); + bool handleUrl(const QUrl& lookupUrl); void handleLookupString(const QString& lookupString); void attemptPlaceNameLookup(const QString& lookupString); public slots: void handleAPIResponse(const QJsonObject& jsonObject); - void handleAPIError(QNetworkReply::NetworkError error, const QString& message); + void handleAPIError(QNetworkReply& errorReply); signals: void lookupResultIsOffline(); void possibleDomainChangeRequired(const QString& newHostname); diff --git a/libraries/networking/src/UserActivityLogger.cpp b/libraries/networking/src/UserActivityLogger.cpp index e2d3434867..549f02ae3c 100644 --- a/libraries/networking/src/UserActivityLogger.cpp +++ b/libraries/networking/src/UserActivityLogger.cpp @@ -73,8 +73,8 @@ void UserActivityLogger::requestFinished(const QJsonObject& object) { // qDebug() << object; } -void UserActivityLogger::requestError(QNetworkReply::NetworkError error,const QString& string) { - qDebug() << error << ": " << string; +void UserActivityLogger::requestError(QNetworkReply& errorReply) { + qDebug() << errorReply.error() << "-" << errorReply.errorString(); } void UserActivityLogger::launch(QString applicationVersion) { diff --git a/libraries/networking/src/UserActivityLogger.h b/libraries/networking/src/UserActivityLogger.h index 7e8abe9fb2..1bd966d632 100644 --- a/libraries/networking/src/UserActivityLogger.h +++ b/libraries/networking/src/UserActivityLogger.h @@ -40,7 +40,7 @@ public slots: private slots: void requestFinished(const QJsonObject& object); - void requestError(QNetworkReply::NetworkError error,const QString& string); + void requestError(QNetworkReply& errorReply); private: UserActivityLogger(); From b77a3f4904cd57dd4cb59b3940e86d21a26d75a6 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 12 Sep 2014 10:15:51 -0700 Subject: [PATCH 15/22] cleanup application file event handler --- interface/src/Application.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 13a94ebebf..9963706d97 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -810,10 +810,7 @@ bool Application::event(QEvent* event) { // handle custom URL if (event->type() == QEvent::FileOpen) { QFileOpenEvent* fileEvent = static_cast(event); - bool isHifiSchemeURL = !fileEvent->url().isEmpty() && fileEvent->url().toLocalFile().startsWith(HIFI_URL_SCHEME); - if (isHifiSchemeURL) { - AddressManager::getInstance().handleLookupString(fileEvent->url().toLocalFile()); - } + AddressManager::getInstance().handleLookupString(fileEvent->url().toLocalFile()); return false; } return QApplication::event(event); From ab7df8679dbbbaebf7a2261783b88632e1226b28 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 12 Sep 2014 11:19:22 -0700 Subject: [PATCH 16/22] fix broken hifi linking --- interface/src/Application.cpp | 8 ++- interface/src/Menu.cpp | 2 +- libraries/networking/src/AddressManager.cpp | 75 +++++++++++++-------- libraries/networking/src/AddressManager.h | 9 +-- 4 files changed, 60 insertions(+), 34 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9963706d97..15aacc7f8d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -410,6 +410,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : this, &Application::changeDomainHostname); // when -url in command line, teleport to location + qDebug() << getCmdOption(argc, constArgv, "-url"); addressManager.handleUrl(QUrl(getCmdOption(argc, constArgv, "-url"))); // call the OAuthWebviewHandler static getter so that its instance lives in our thread @@ -810,9 +811,14 @@ bool Application::event(QEvent* event) { // handle custom URL if (event->type() == QEvent::FileOpen) { QFileOpenEvent* fileEvent = static_cast(event); - AddressManager::getInstance().handleLookupString(fileEvent->url().toLocalFile()); + + if (!fileEvent->url().isEmpty()) { + AddressManager::getInstance().handleLookupString(fileEvent->url().toLocalFile()); + } + return false; } + return QApplication::event(event); } diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 98f2986b9a..bd6a82f3df 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -1140,7 +1140,7 @@ void Menu::toggleAddressBar() { QInputDialog addressBarDialog(Application::getInstance()->getWindow()); addressBarDialog.setWindowTitle("Address Bar"); addressBarDialog.setWindowFlags(Qt::Sheet); - addressBarDialog.setLabelText("place, domain, @user, example.com, position/orientation"); + addressBarDialog.setLabelText("place, domain, @user, example.com, /position/orientation"); addressBarDialog.resize(addressBarDialog.parentWidget()->size().width() * DIALOG_RATIO_OF_WINDOW, addressBarDialog.size().height()); diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index 591a7a3ef6..59d00c496b 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -51,8 +51,34 @@ const JSONCallbackParameters& AddressManager::apiCallbackParameters() { bool AddressManager::handleUrl(const QUrl& lookupUrl) { if (lookupUrl.scheme() == HIFI_URL_SCHEME) { - // we've verified that this is a valid hifi URL - hand it off to handleLookupString - handleLookupString(lookupUrl.toString()); + + // there are 4 possible lookup strings + + // 1. global place name (name of domain or place) - example: sanfrancisco + // 2. user name (prepended with @) - example: @philip + // 3. location string (posX,posY,posZ/eulerX,eulerY,eulerZ) + // 4. domain network address (IP or dns resolvable hostname) + + qDebug() << lookupUrl; + + if (lookupUrl.isRelative()) { + // if this is a relative path then handle it as a relative viewpoint + handleRelativeViewpoint(lookupUrl.path()); + } else { + // use our regex'ed helpers to figure out what we're supposed to do with this + if (!handleUsername(lookupUrl.authority())) { + // we're assuming this is either a network address or global place name + // check if it is a network address first + if (!handleNetworkAddress(lookupUrl.host())) { + // wasn't an address - lookup the place name + attemptPlaceNameLookup(lookupUrl.host()); + } + + // we may have a path that defines a relative viewpoint - if so we should jump to that now + handleRelativeViewpoint(lookupUrl.path()); + } + } + return true; } @@ -60,22 +86,12 @@ bool AddressManager::handleUrl(const QUrl& lookupUrl) { } void AddressManager::handleLookupString(const QString& lookupString) { - // there are 4 possible lookup strings + // we've verified that this is a valid hifi URL - hand it off to handleLookupString + QString sanitizedString = lookupString; + const QRegExp HIFI_SCHEME_REGEX = QRegExp(HIFI_URL_SCHEME + ":\\/{1,2}", Qt::CaseInsensitive); + sanitizedString = sanitizedString.remove(HIFI_SCHEME_REGEX); - // 1. global place name (name of domain or place) - example: sanfrancisco - // 2. user name (prepended with @) - example: @philip - // 3. location string (posX,posY,posZ/eulerX,eulerY,eulerZ) - // 4. domain network address (IP or dns resolvable hostname) - - QString sanitizedLookupString = lookupString.trimmed().remove(HIFI_URL_SCHEME + "//"); - - - // use our regex'ed helpers to figure out what we're supposed to do with this - if (!isLookupHandledAsUsername(sanitizedLookupString) && - !isLookupHandledAsNetworkAddress(sanitizedLookupString) && - !isLookupHandledAsViewpoint(sanitizedLookupString)) { - attemptPlaceNameLookup(sanitizedLookupString); - } + handleUrl(QUrl(HIFI_URL_SCHEME + "://" + sanitizedString)); } void AddressManager::handleAPIResponse(const QJsonObject &jsonObject) { @@ -108,7 +124,7 @@ void AddressManager::handleAPIResponse(const QJsonObject &jsonObject) { if (!returnedPath.isEmpty()) { // try to parse this returned path as a viewpoint, that's the only thing it could be for now - if (!isLookupHandledAsViewpoint(returnedPath)) { + if (!handleRelativeViewpoint(returnedPath)) { qDebug() << "Received a location path that was could not be handled as a viewpoint -" << returnedPath; } } @@ -137,7 +153,7 @@ void AddressManager::attemptPlaceNameLookup(const QString& lookupString) { apiCallbackParameters()); } -bool AddressManager::isLookupHandledAsNetworkAddress(const QString& lookupString) { +bool AddressManager::handleNetworkAddress(const QString& lookupString) { const QString IP_ADDRESS_REGEX_STRING = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}" "([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(:\\d{1,5})?$"; @@ -161,7 +177,7 @@ bool AddressManager::isLookupHandledAsNetworkAddress(const QString& lookupString return false; } -bool AddressManager::isLookupHandledAsViewpoint(const QString& lookupString) { +bool AddressManager::handleRelativeViewpoint(const QString& lookupString) { const QString FLOAT_REGEX_STRING = "([-+]?[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?)"; const QString TRIPLE_FLOAT_REGEX_STRING = QString("\\/") + FLOAT_REGEX_STRING + "\\s*,\\s*" + FLOAT_REGEX_STRING + "\\s*,\\s*" + FLOAT_REGEX_STRING + "\\s*(?:$|\\/)"; @@ -206,20 +222,23 @@ bool AddressManager::isLookupHandledAsViewpoint(const QString& lookupString) { const QString GET_USER_LOCATION = "/api/v1/users/%1/location"; -bool AddressManager::isLookupHandledAsUsername(const QString& lookupString) { - const QString USERNAME_REGEX_STRING = "^@(\\S+)$"; +bool AddressManager::handleUsername(const QString& lookupString) { + const QString USERNAME_REGEX_STRING = "^@(\\S+)"; QRegExp usernameRegex(USERNAME_REGEX_STRING); if (usernameRegex.indexIn(lookupString) != -1) { - QString username = QUrl::toPercentEncoding(usernameRegex.cap(1)); - // this is a username - pull the captured name and lookup that user's location - AccountManager::getInstance().authenticatedRequest(GET_USER_LOCATION.arg(username), - QNetworkAccessManager::GetOperation, - apiCallbackParameters()); - + lookupUserViaAPI(usernameRegex.cap(1)); return true; } return false; } + +void AddressManager::lookupUserViaAPI(const QString& username) { + QString formattedUsername = QUrl::toPercentEncoding(username); + // this is a username - pull the captured name and lookup that user's location + AccountManager::getInstance().authenticatedRequest(GET_USER_LOCATION.arg(formattedUsername), + QNetworkAccessManager::GetOperation, + apiCallbackParameters()); +} diff --git a/libraries/networking/src/AddressManager.h b/libraries/networking/src/AddressManager.h index 8ccffe39fa..1afdf00e7d 100644 --- a/libraries/networking/src/AddressManager.h +++ b/libraries/networking/src/AddressManager.h @@ -19,7 +19,7 @@ #include "AccountManager.h" -static const QString HIFI_URL_SCHEME = "hifi:"; +static const QString HIFI_URL_SCHEME = "hifi"; const glm::quat EMPTY_QUAT = glm::quat(); @@ -37,6 +37,7 @@ public: public slots: void handleAPIResponse(const QJsonObject& jsonObject); void handleAPIError(QNetworkReply& errorReply); + void lookupUserViaAPI(const QString& username); signals: void lookupResultIsOffline(); void possibleDomainChangeRequired(const QString& newHostname); @@ -44,9 +45,9 @@ signals: private: const JSONCallbackParameters& apiCallbackParameters(); - bool isLookupHandledAsNetworkAddress(const QString& lookupString); - bool isLookupHandledAsViewpoint(const QString& lookupString); - bool isLookupHandledAsUsername(const QString& lookupString); + bool handleNetworkAddress(const QString& lookupString); + bool handleRelativeViewpoint(const QString& pathSubsection); + bool handleUsername(const QString& lookupString); }; #endif // hifi_AddressManager_h \ No newline at end of file From 93ff34baaa03d1b374f460ab8587071c05b408e2 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 12 Sep 2014 11:21:38 -0700 Subject: [PATCH 17/22] force address bar lookup through handleLookupString --- interface/src/Application.cpp | 7 ++++--- libraries/networking/src/AddressManager.h | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 15aacc7f8d..89c3dcebd5 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -410,8 +410,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : this, &Application::changeDomainHostname); // when -url in command line, teleport to location - qDebug() << getCmdOption(argc, constArgv, "-url"); - addressManager.handleUrl(QUrl(getCmdOption(argc, constArgv, "-url"))); + addressManager.handleLookupString(getCmdOption(argc, constArgv, "-url")); // call the OAuthWebviewHandler static getter so that its instance lives in our thread OAuthWebViewHandler::getInstance(); @@ -3923,7 +3922,9 @@ void Application::uploadAttachment() { } void Application::openUrl(const QUrl& url) { - if (!AddressManager::getInstance().handleUrl(url)) { + if (url.scheme() == HIFI_URL_SCHEME) { + AddressManager::getInstance().handleLookupString(url.toString()); + } else { // address manager did not handle - ask QDesktopServices to handle QDesktopServices::openUrl(url); } diff --git a/libraries/networking/src/AddressManager.h b/libraries/networking/src/AddressManager.h index 1afdf00e7d..dd5e5ad0a3 100644 --- a/libraries/networking/src/AddressManager.h +++ b/libraries/networking/src/AddressManager.h @@ -31,7 +31,6 @@ public: static QString pathForPositionAndOrientation(const glm::vec3& position, bool hasOrientation = false, const glm::quat& orientation = EMPTY_QUAT); - bool handleUrl(const QUrl& lookupUrl); void handleLookupString(const QString& lookupString); void attemptPlaceNameLookup(const QString& lookupString); public slots: @@ -45,6 +44,8 @@ signals: private: const JSONCallbackParameters& apiCallbackParameters(); + bool handleUrl(const QUrl& lookupUrl); + bool handleNetworkAddress(const QString& lookupString); bool handleRelativeViewpoint(const QString& pathSubsection); bool handleUsername(const QString& lookupString); From 1084483dd503270a2ee699093668a7f69fcd4fac Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 12 Sep 2014 11:22:34 -0700 Subject: [PATCH 18/22] fix for default param of default constructed quat --- libraries/networking/src/AddressManager.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libraries/networking/src/AddressManager.h b/libraries/networking/src/AddressManager.h index dd5e5ad0a3..2365f8b4c1 100644 --- a/libraries/networking/src/AddressManager.h +++ b/libraries/networking/src/AddressManager.h @@ -21,15 +21,13 @@ static const QString HIFI_URL_SCHEME = "hifi"; -const glm::quat EMPTY_QUAT = glm::quat(); - class AddressManager : public QObject { Q_OBJECT public: static AddressManager& getInstance(); static QString pathForPositionAndOrientation(const glm::vec3& position, bool hasOrientation = false, - const glm::quat& orientation = EMPTY_QUAT); + const glm::quat& orientation = glm::quat()); void handleLookupString(const QString& lookupString); void attemptPlaceNameLookup(const QString& lookupString); From 88a75a35855e4b65e7c862e3d036630b0b18534c Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 12 Sep 2014 11:27:54 -0700 Subject: [PATCH 19/22] fix for goToUser from ChatWindow --- interface/src/ui/ChatWindow.cpp | 3 ++- libraries/networking/src/AddressManager.cpp | 4 ++-- libraries/networking/src/AddressManager.h | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/interface/src/ui/ChatWindow.cpp b/interface/src/ui/ChatWindow.cpp index cf62b75215..5add09a9a6 100644 --- a/interface/src/ui/ChatWindow.cpp +++ b/interface/src/ui/ChatWindow.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include "Application.h" @@ -170,7 +171,7 @@ bool ChatWindow::eventFilter(QObject* sender, QEvent* event) { } else if (event->type() == QEvent::MouseButtonRelease) { QVariant userVar = sender->property("user"); if (userVar.isValid()) { -// Menu::getInstance()->goToUser("@" + userVar.toString()); + AddressManager::getInstance().goToUser(userVar.toString()); return true; } } diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index 59d00c496b..e41dbe0e3a 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -228,14 +228,14 @@ bool AddressManager::handleUsername(const QString& lookupString) { QRegExp usernameRegex(USERNAME_REGEX_STRING); if (usernameRegex.indexIn(lookupString) != -1) { - lookupUserViaAPI(usernameRegex.cap(1)); + goToUser(usernameRegex.cap(1)); return true; } return false; } -void AddressManager::lookupUserViaAPI(const QString& username) { +void AddressManager::goToUser(const QString& username) { QString formattedUsername = QUrl::toPercentEncoding(username); // this is a username - pull the captured name and lookup that user's location AccountManager::getInstance().authenticatedRequest(GET_USER_LOCATION.arg(formattedUsername), diff --git a/libraries/networking/src/AddressManager.h b/libraries/networking/src/AddressManager.h index 2365f8b4c1..987e435981 100644 --- a/libraries/networking/src/AddressManager.h +++ b/libraries/networking/src/AddressManager.h @@ -34,7 +34,7 @@ public: public slots: void handleAPIResponse(const QJsonObject& jsonObject); void handleAPIError(QNetworkReply& errorReply); - void lookupUserViaAPI(const QString& username); + void goToUser(const QString& username); signals: void lookupResultIsOffline(); void possibleDomainChangeRequired(const QString& newHostname); From 892e0e7cbfcb573140461c641ec7afd216497cb0 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 12 Sep 2014 11:43:50 -0700 Subject: [PATCH 20/22] fix node auth url, NAN break on windows --- libraries/networking/src/AddressManager.cpp | 4 ++-- libraries/networking/src/LimitedNodeList.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index e41dbe0e3a..f2e9ce64ab 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -190,7 +190,7 @@ bool AddressManager::handleRelativeViewpoint(const QString& lookupString) { tripleFloatRegex.cap(2).toFloat(), tripleFloatRegex.cap(3).toFloat()); - if (newPosition.x != NAN && newPosition.y != NAN && newPosition.z != NAN) { + if (!isNaN(newPosition.x) && !isNaN(newPosition.y) && !isNaN(newPosition.z)) { glm::vec3 newOrientation; // we may also have an orientation if (lookupString[tripleFloatRegex.matchedLength() - 1] == QChar('/') @@ -200,7 +200,7 @@ bool AddressManager::handleRelativeViewpoint(const QString& lookupString) { tripleFloatRegex.cap(2).toFloat(), tripleFloatRegex.cap(3).toFloat()); - if (newOrientation.x != NAN && newOrientation.y != NAN && newOrientation.z != NAN) { + if (!isNaN(newOrientation.x) && !isNaN(newOrientation.y) && !isNaN(newOrientation.z)) { emit locationChangeRequired(newPosition, true, newOrientation); return true; } else { diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 604f8c7434..f50f7493fb 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -33,7 +33,7 @@ const char SOLO_NODE_TYPES[2] = { NodeType::AudioMixer }; -const QUrl DEFAULT_NODE_AUTH_URL = QUrl("http://localhost:3000"); +const QUrl DEFAULT_NODE_AUTH_URL = QUrl("https://data.highfidelity.io"); LimitedNodeList* LimitedNodeList::_sharedInstance = NULL; From f0ead98a2a2e62029f806fbf51c0559be8748509 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 12 Sep 2014 13:27:01 -0700 Subject: [PATCH 21/22] put back LocationScriptingInterface so it works prior to replacement --- interface/src/Application.cpp | 8 +++ .../scripting/LocationScriptingInterface.cpp | 52 +++++++++++++++++++ .../scripting/LocationScriptingInterface.h | 50 ++++++++++++++++++ libraries/networking/src/AddressManager.h | 3 +- 4 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 interface/src/scripting/LocationScriptingInterface.cpp create mode 100644 interface/src/scripting/LocationScriptingInterface.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 3208347728..18b39b30ef 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -81,6 +81,7 @@ #include "scripting/AccountScriptingInterface.h" #include "scripting/AudioDeviceScriptingInterface.h" #include "scripting/ClipboardScriptingInterface.h" +#include "scripting/LocationScriptingInterface.h" #include "scripting/MenuScriptingInterface.h" #include "scripting/SettingsScriptingInterface.h" #include "scripting/WindowScriptingInterface.h" @@ -3811,6 +3812,13 @@ ScriptEngine* Application::loadScript(const QString& scriptFilename, bool isUser scriptEngine->registerGlobalObject("Overlays", &_overlays); + QScriptValue windowValue = scriptEngine->registerGlobalObject("Window", WindowScriptingInterface::getInstance()); + scriptEngine->registerGetterSetter("location", LocationScriptingInterface::locationGetter, + LocationScriptingInterface::locationSetter, windowValue); + // register `location` on the global object. + scriptEngine->registerGetterSetter("location", LocationScriptingInterface::locationGetter, + LocationScriptingInterface::locationSetter); + scriptEngine->registerGlobalObject("Menu", MenuScriptingInterface::getInstance()); scriptEngine->registerGlobalObject("Settings", SettingsScriptingInterface::getInstance()); scriptEngine->registerGlobalObject("AudioDevice", AudioDeviceScriptingInterface::getInstance()); diff --git a/interface/src/scripting/LocationScriptingInterface.cpp b/interface/src/scripting/LocationScriptingInterface.cpp new file mode 100644 index 0000000000..bead12117d --- /dev/null +++ b/interface/src/scripting/LocationScriptingInterface.cpp @@ -0,0 +1,52 @@ +// +// LocationScriptingInterface.cpp +// interface/src/scripting +// +// Created by Ryan Huffman on 4/29/14. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include + +#include "NodeList.h" + +#include "LocationScriptingInterface.h" + +LocationScriptingInterface* LocationScriptingInterface::getInstance() { + static LocationScriptingInterface sharedInstance; + return &sharedInstance; +} + +bool LocationScriptingInterface::isConnected() { + return NodeList::getInstance()->getDomainHandler().isConnected(); +} + +QString LocationScriptingInterface::getHref() { + return getProtocol() + "//" + getHostname() + getPathname(); +} + +QString LocationScriptingInterface::getPathname() { + MyAvatar* applicationAvatar = Application::getInstance()->getAvatar(); + return AddressManager::pathForPositionAndOrientation(applicationAvatar->getPosition(), + true, applicationAvatar->getOrientation()); +} + +QString LocationScriptingInterface::getHostname() { + return NodeList::getInstance()->getDomainHandler().getHostname(); +} + +void LocationScriptingInterface::assign(const QString& url) { + QMetaObject::invokeMethod(&AddressManager::getInstance(), "handleLookupString", Q_ARG(const QString&, url)); +} + +QScriptValue LocationScriptingInterface::locationGetter(QScriptContext* context, QScriptEngine* engine) { + return engine->newQObject(getInstance()); +} + +QScriptValue LocationScriptingInterface::locationSetter(QScriptContext* context, QScriptEngine* engine) { + LocationScriptingInterface::getInstance()->assign(context->argument(0).toString()); + return QScriptValue::UndefinedValue; +} diff --git a/interface/src/scripting/LocationScriptingInterface.h b/interface/src/scripting/LocationScriptingInterface.h new file mode 100644 index 0000000000..3d725776fd --- /dev/null +++ b/interface/src/scripting/LocationScriptingInterface.h @@ -0,0 +1,50 @@ +// +// LocationScriptingInterface.h +// interface/src/scripting +// +// Created by Ryan Huffman on 4/29/14. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_LocationScriptingInterface_h +#define hifi_LocationScriptingInterface_h + +#include +#include +#include +#include +#include + +#include + +#include "Application.h" + +class LocationScriptingInterface : public QObject { + Q_OBJECT + Q_PROPERTY(bool isConnected READ isConnected) + Q_PROPERTY(QString href READ getHref) + Q_PROPERTY(QString protocol READ getProtocol) + Q_PROPERTY(QString hostname READ getHostname) + Q_PROPERTY(QString pathname READ getPathname) + LocationScriptingInterface() { }; +public: + static LocationScriptingInterface* getInstance(); + + bool isConnected(); + QString getHref(); + QString getProtocol() { return HIFI_URL_SCHEME; }; + QString getPathname(); + QString getHostname(); + + static QScriptValue locationGetter(QScriptContext* context, QScriptEngine* engine); + static QScriptValue locationSetter(QScriptContext* context, QScriptEngine* engine); + +public slots: + void assign(const QString& url); + +}; + +#endif // hifi_LocationScriptingInterface_h diff --git a/libraries/networking/src/AddressManager.h b/libraries/networking/src/AddressManager.h index 987e435981..f27fb475c2 100644 --- a/libraries/networking/src/AddressManager.h +++ b/libraries/networking/src/AddressManager.h @@ -29,9 +29,10 @@ public: static QString pathForPositionAndOrientation(const glm::vec3& position, bool hasOrientation = false, const glm::quat& orientation = glm::quat()); - void handleLookupString(const QString& lookupString); void attemptPlaceNameLookup(const QString& lookupString); public slots: + void handleLookupString(const QString& lookupString); + void handleAPIResponse(const QJsonObject& jsonObject); void handleAPIError(QNetworkReply& errorReply); void goToUser(const QString& username); From b0593bcdc0f862b49c4d426fc37eb75f6a37007a Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 12 Sep 2014 13:31:27 -0700 Subject: [PATCH 22/22] fix a double space --- interface/src/location/LocationManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/location/LocationManager.cpp b/interface/src/location/LocationManager.cpp index 029657996b..92e8616478 100644 --- a/interface/src/location/LocationManager.cpp +++ b/interface/src/location/LocationManager.cpp @@ -32,7 +32,7 @@ void LocationManager::namedLocationDataReceived(const QJsonObject& data) { if (data.contains("status") && data["status"].toString() == "success") { emit creationCompleted(QString()); } else { - emit creationCompleted(UNKNOWN_ERROR_MESSAGE); + emit creationCompleted(UNKNOWN_ERROR_MESSAGE); } }