From 2b5d8622637f1b27d6b6d3b4718d07f08476ecd9 Mon Sep 17 00:00:00 2001
From: Stephen Birarda <commit@birarda.com>
Date: Mon, 22 Aug 2016 17:06:43 -0700
Subject: [PATCH 1/5] request shareable name in AddressManager once connected

---
 libraries/networking/src/AddressManager.cpp | 56 +++++++++++++++++++++
 libraries/networking/src/AddressManager.h   |  6 +++
 libraries/networking/src/NodeList.cpp       |  4 ++
 3 files changed, 66 insertions(+)

diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp
index 6760d44244..c436858c68 100644
--- a/libraries/networking/src/AddressManager.cpp
+++ b/libraries/networking/src/AddressManager.cpp
@@ -651,6 +651,9 @@ bool AddressManager::setHost(const QString& host, LookupTrigger trigger, quint16
 
         _port = port;
 
+        // any host change should clear the shareable place name
+        _shareablePlaceName.clear();
+
         if (host != _host) {
             _host = host;
             emit hostChanged(_host);
@@ -708,6 +711,59 @@ void AddressManager::copyPath() {
     QApplication::clipboard()->setText(currentPath());
 }
 
+void AddressManager::handleShareableNameAPIResponse(QNetworkReply& requestReply) {
+    // make sure that this response is for the domain we're currently connected to
+    auto domainID = DependencyManager::get<NodeList>()->getDomainHandler().getUUID();
+
+    if (requestReply.url().toString().contains(uuidStringWithoutCurlyBraces(domainID))) {
+        // check for a name or default name in the API response
+
+        QJsonObject responseObject = QJsonDocument::fromJson(requestReply.readAll()).object();
+        QJsonObject domainObject = responseObject["domain"].toObject();
+
+        const QString DOMAIN_NAME_KEY = "name";
+        const QString DOMAIN_DEFAULT_PLACE_NAME_KEY = "default_place_name";
+
+        bool shareableNameChanged { false };
+
+        if (domainObject[DOMAIN_NAME_KEY].isString()) {
+            _shareablePlaceName = domainObject[DOMAIN_NAME_KEY].toString();
+            shareableNameChanged = true;
+        } else if (domainObject[DOMAIN_DEFAULT_PLACE_NAME_KEY].isString()) {
+            _shareablePlaceName = domainObject[DOMAIN_DEFAULT_PLACE_NAME_KEY].toString();
+            shareableNameChanged = true;
+        }
+
+        if (shareableNameChanged) {
+            qDebug() << "AddressManager shareable name changed to" << _shareablePlaceName;
+        }
+    }
+}
+
+void AddressManager::lookupShareableNameForDomainID(const QUuid& domainID) {
+
+    // if we get to a domain via IP/hostname, often the address is only reachable by this client
+    // and not by other clients on the LAN or Internet
+
+    // to work around this we use the ID to lookup the default place name, and if it exists we
+    // then use that for Steam join/invite or copiable address
+
+    // it only makes sense to lookup a shareable default name if we don't have a place name
+    if (_placeName.isEmpty()) {
+        JSONCallbackParameters callbackParams;
+
+        // no error callback handling
+        // in the case of an error we simply assume there is no default place name
+        callbackParams.jsonCallbackReceiver = this;
+        callbackParams.jsonCallbackMethod = "handleShareableNameAPIResponse";
+
+        DependencyManager::get<AccountManager>()->sendRequest(GET_DOMAIN_ID.arg(uuidStringWithoutCurlyBraces(domainID)),
+                                                              AccountManagerAuth::None,
+                                                              QNetworkAccessManager::GetOperation,
+                                                              callbackParams);
+    }
+}
+
 void AddressManager::addCurrentAddressToHistory(LookupTrigger trigger) {
 
     // if we're cold starting and this is called for the first address (from settings) we don't do anything
diff --git a/libraries/networking/src/AddressManager.h b/libraries/networking/src/AddressManager.h
index 8ccddc5975..74cc431448 100644
--- a/libraries/networking/src/AddressManager.h
+++ b/libraries/networking/src/AddressManager.h
@@ -101,6 +101,8 @@ public slots:
     void copyAddress();
     void copyPath();
 
+    void lookupShareableNameForDomainID(const QUuid& domainID);
+
 signals:
     void lookupResultsFinished();
     void lookupResultIsOffline();
@@ -124,6 +126,8 @@ private slots:
     void handleAPIResponse(QNetworkReply& requestReply);
     void handleAPIError(QNetworkReply& errorReply);
 
+    void handleShareableNameAPIResponse(QNetworkReply& requestReply);
+
 private:
     void goToAddressFromObject(const QVariantMap& addressMap, const QNetworkReply& reply);
 
@@ -154,6 +158,8 @@ private:
     PositionGetter _positionGetter;
     OrientationGetter _orientationGetter;
 
+    QString _shareablePlaceName;
+
     QStack<QUrl> _backStack;
     QStack<QUrl> _forwardStack;
     quint64 _lastBackPush = 0;
diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp
index 781cc00c1c..3a07ea8b54 100644
--- a/libraries/networking/src/NodeList.cpp
+++ b/libraries/networking/src/NodeList.cpp
@@ -539,6 +539,10 @@ void NodeList::processDomainServerList(QSharedPointer<ReceivedMessage> message)
     if (!_domainHandler.isConnected()) {
         _domainHandler.setUUID(domainUUID);
         _domainHandler.setIsConnected(true);
+
+        // in case we didn't use a place name to get to this domain,
+        // give the address manager a chance to lookup a default one now
+        DependencyManager::get<AddressManager>()->lookupShareableNameForDomainID(domainUUID);
     } else if (_domainHandler.getUUID() != domainUUID) {
         // Recieved packet from different domain.
         qWarning() << "IGNORING DomainList packet from" << domainUUID << "while connected to" << _domainHandler.getUUID();

From edd4f5853e81fb25cdc94303559545102012cddd Mon Sep 17 00:00:00 2001
From: Stephen Birarda <commit@birarda.com>
Date: Mon, 22 Aug 2016 17:17:13 -0700
Subject: [PATCH 2/5] use temporary domain name as place name on ID lookup

---
 libraries/networking/src/AddressManager.cpp | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp
index c436858c68..b2f1fc39b5 100644
--- a/libraries/networking/src/AddressManager.cpp
+++ b/libraries/networking/src/AddressManager.cpp
@@ -360,6 +360,7 @@ void AddressManager::goToAddressFromObject(const QVariantMap& dataObject, const
 
                 LookupTrigger trigger = (LookupTrigger) reply.property(LOOKUP_TRIGGER_KEY).toInt();
 
+
                 // set our current root place id to the ID that came back
                 const QString PLACE_ID_KEY = "id";
                 _rootPlaceID = rootMap[PLACE_ID_KEY].toUuid();
@@ -368,6 +369,15 @@ void AddressManager::goToAddressFromObject(const QVariantMap& dataObject, const
                 const QString PLACE_NAME_KEY = "name";
                 QString placeName = rootMap[PLACE_NAME_KEY].toString();
 
+                if (placeName.isEmpty()) {
+                    // we didn't get a set place name, check if there is a default or temporary domain name to use
+                    const QString TEMPORARY_DOMAIN_NAME_KEY = "name";
+
+                    if (domainObject.contains(TEMPORARY_DOMAIN_NAME_KEY)) {
+                        placeName = domainObject[TEMPORARY_DOMAIN_NAME_KEY].toString();
+                    }
+                }
+
                 if (!placeName.isEmpty()) {
                     if (setHost(placeName, trigger)) {
                         trigger = LookupTrigger::Internal;

From fbe784155eaf07a73da222584bee9371d19a7c78 Mon Sep 17 00:00:00 2001
From: Stephen Birarda <commit@birarda.com>
Date: Tue, 23 Aug 2016 11:18:42 -0700
Subject: [PATCH 3/5] add a shareable address return to address manager

---
 interface/src/DiscoverabilityManager.cpp    |  2 +-
 libraries/networking/src/AddressManager.cpp | 32 +++++++++++++++++----
 libraries/networking/src/AddressManager.h   |  2 ++
 3 files changed, 29 insertions(+), 7 deletions(-)

diff --git a/interface/src/DiscoverabilityManager.cpp b/interface/src/DiscoverabilityManager.cpp
index dd80dadca7..9b61770a3e 100644
--- a/interface/src/DiscoverabilityManager.cpp
+++ b/interface/src/DiscoverabilityManager.cpp
@@ -111,7 +111,7 @@ void DiscoverabilityManager::updateLocation() {
     }
 
     // Update Steam
-    SteamClient::updateLocation(domainHandler.getHostname(), addressManager->currentFacingAddress());
+    SteamClient::updateLocation(domainHandler.getHostname(), addressManager->currentShareableAddress());
 }
 
 void DiscoverabilityManager::handleHeartbeatResponse(QNetworkReply& requestReply) {
diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp
index b2f1fc39b5..c9c9d73394 100644
--- a/libraries/networking/src/AddressManager.cpp
+++ b/libraries/networking/src/AddressManager.cpp
@@ -63,15 +63,31 @@ QUrl AddressManager::currentAddress() const {
 }
 
 QUrl AddressManager::currentFacingAddress() const {
-    QUrl hifiURL;
+    auto hifiURL = currentAddress();
+    hifiURL.setPath(currentFacingPath());
 
-    hifiURL.setScheme(HIFI_URL_SCHEME);
-    hifiURL.setHost(_host);
+    return hifiURL;
+}
 
-    if (_port != 0 && _port != DEFAULT_DOMAIN_SERVER_PORT) {
-        hifiURL.setPort(_port);
+
+QUrl AddressManager::currentShareableAddress() const {
+    if (!_shareablePlaceName.isEmpty()) {
+        // if we have a shareable place name use that instead of whatever the current host is
+        QUrl hifiURL;
+
+        hifiURL.setScheme(HIFI_URL_SCHEME);
+        hifiURL.setHost(_shareablePlaceName);
+
+        hifiURL.setPath(currentPath());
+
+        return hifiURL;
+    } else {
+        return currentAddress();
     }
+}
 
+QUrl AddressManager::currentFacingShareableAddress() const {
+    auto hifiURL = currentShareableAddress();
     hifiURL.setPath(currentFacingPath());
 
     return hifiURL;
@@ -372,9 +388,12 @@ void AddressManager::goToAddressFromObject(const QVariantMap& dataObject, const
                 if (placeName.isEmpty()) {
                     // we didn't get a set place name, check if there is a default or temporary domain name to use
                     const QString TEMPORARY_DOMAIN_NAME_KEY = "name";
+                    const QString DEFAULT_DOMAIN_NAME_KEY = "default_place_name";
 
                     if (domainObject.contains(TEMPORARY_DOMAIN_NAME_KEY)) {
                         placeName = domainObject[TEMPORARY_DOMAIN_NAME_KEY].toString();
+                    } else if (domainObject.contains(DEFAULT_DOMAIN_NAME_KEY)) {
+                        placeName = domainObject[DEFAULT_DOMAIN_NAME_KEY].toString();
                     }
                 }
 
@@ -714,7 +733,8 @@ void AddressManager::refreshPreviousLookup() {
 }
 
 void AddressManager::copyAddress() {
-    QApplication::clipboard()->setText(currentAddress().toString());
+    // assume that the address is being copied because the user wants a shareable address
+    QApplication::clipboard()->setText(currentShareableAddress().toString());
 }
 
 void AddressManager::copyPath() {
diff --git a/libraries/networking/src/AddressManager.h b/libraries/networking/src/AddressManager.h
index 74cc431448..296abbb36c 100644
--- a/libraries/networking/src/AddressManager.h
+++ b/libraries/networking/src/AddressManager.h
@@ -59,6 +59,8 @@ public:
 
     QUrl currentAddress() const;
     QUrl currentFacingAddress() const;
+    QUrl currentShareableAddress() const;
+    QUrl currentFacingShareableAddress() const;
     QString currentPath(bool withOrientation = true) const;
     QString currentFacingPath() const;
 

From 43b8e01d46636651a9984b2dcca35bf4eb7954a4 Mon Sep 17 00:00:00 2001
From: Stephen Birarda <commit@birarda.com>
Date: Tue, 23 Aug 2016 11:21:15 -0700
Subject: [PATCH 4/5] don't force auto networking on non metaverse domains

---
 domain-server/src/DomainServer.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp
index cbf533bf64..b61fef8525 100644
--- a/domain-server/src/DomainServer.cpp
+++ b/domain-server/src/DomainServer.cpp
@@ -121,9 +121,9 @@ DomainServer::DomainServer(int argc, char* argv[]) :
     if (_type != NonMetaverse) {
         // if we have a metaverse domain, we'll use an access token for API calls
         resetAccountManagerAccessToken();
-    }
 
-    setupAutomaticNetworking();
+        setupAutomaticNetworking();
+    }
 
     if (!getID().isNull() && _type != NonMetaverse) {
         // setup periodic heartbeats to metaverse API

From 9461ca0cfca81d4abd088e6b72544ba86300a44b Mon Sep 17 00:00:00 2001
From: Stephen Birarda <commit@birarda.com>
Date: Tue, 23 Aug 2016 11:56:18 -0700
Subject: [PATCH 5/5] use the facing shareable address for steam location

---
 interface/src/DiscoverabilityManager.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/interface/src/DiscoverabilityManager.cpp b/interface/src/DiscoverabilityManager.cpp
index 9b61770a3e..eb9a7c7f6d 100644
--- a/interface/src/DiscoverabilityManager.cpp
+++ b/interface/src/DiscoverabilityManager.cpp
@@ -111,7 +111,7 @@ void DiscoverabilityManager::updateLocation() {
     }
 
     // Update Steam
-    SteamClient::updateLocation(domainHandler.getHostname(), addressManager->currentShareableAddress());
+    SteamClient::updateLocation(domainHandler.getHostname(), addressManager->currentFacingShareableAddress());
 }
 
 void DiscoverabilityManager::handleHeartbeatResponse(QNetworkReply& requestReply) {