diff --git a/indra/newview/llteleporthistory.cpp b/indra/newview/llteleporthistory.cpp
index 3d90734d96..3c20615a24 100644
--- a/indra/newview/llteleporthistory.cpp
+++ b/indra/newview/llteleporthistory.cpp
@@ -44,6 +44,10 @@
#include "llavatarname.h"
#include "llavatarnamecache.h"
+#include "llviewernetwork.h" // Access to GridManager
+#include "lfsimfeaturehandler.h" // Access to hyperGridURL
+#include "llworldmapmessage.h" // Access to sendNamedRegionRequest
+
// [RLVa:KB] - Checked: 2010-09-03 (RLVa-1.2.1b)
#include "rlvhandler.h"
// [/RLVa:KB]
@@ -98,6 +102,46 @@ void LLTeleportHistory::goToItem(int idx)
return;
}
+ // [FIRE-35355] OpenSim global position is dependent on the Grid you are on
+ #ifdef OPENSIM
+ if (LLGridManager::getInstance()->isInOpenSim())
+ {
+ if (mItems[mCurrentItem].mRegionID != mItems[idx].mRegionID)
+ {
+ LLSLURL slurl = mItems[idx].mSLURL;
+ std::string grid = slurl.getGrid();
+ std::string current_grid = LFSimFeatureHandler::instance().hyperGridURL();
+ std::string gatekeeper = LLGridManager::getInstance()->getGatekeeper(grid);
+
+ // Requesting region information from the server is only required when changing grid
+ if (slurl.isValid() && grid != current_grid)
+ {
+ if (!gatekeeper.empty())
+ {
+ slurl = LLSLURL(gatekeeper + ":" + slurl.getRegion(), slurl.getPosition(), true);
+ }
+
+ if (mRequestedItem != -1)
+ {
+ return; // We already have a request in progress and don't want to spam the server
+ }
+
+ mRequestedItem = idx;
+
+ LLWorldMapMessage::getInstance()->sendNamedRegionRequest(
+ slurl.getRegion(),
+ boost::bind(&LLTeleportHistory::regionNameCallback, this, idx, _1, _2, _3, _4),
+ slurl.getSLURLString(),
+ true
+ );
+
+ return; // The teleport will occur in the callback with the correct global position
+ }
+ }
+ }
+ #endif
+ //
+
// Attempt to teleport to the requested item.
gAgent.teleportViaLocation(mItems[idx].mGlobalPos);
mRequestedItem = idx;
@@ -210,6 +254,22 @@ void LLTeleportHistory::updateCurrentLocation(const LLVector3d& new_pos)
mItems[mCurrentItem] = LLTeleportHistoryItem(RlvStrings::getString(RlvStringKeys::Hidden::Parcel), LLVector3d::zero);
}
// [/RLVa:KB]
+
+ // [FIRE-35355] OpenSim global position is dependent on the Grid you are on,
+ // so we need to store the slurl so we can request the global position later
+ #ifdef OPENSIM
+ if (LLGridManager::getInstance()->isInOpenSim())
+ {
+ auto regionp = gAgent.getRegion();
+ if (regionp)
+ {
+ LLVector3 new_pos_local = gAgent.getPosAgentFromGlobal(new_pos);
+ LLSLURL slurl = LLSLURL(LFSimFeatureHandler::instance().hyperGridURL(), regionp->getName(), new_pos_local);
+ mItems[mCurrentItem].mSLURL = slurl;
+ }
+ }
+ #endif
+ //
}
//dump(); // LO - removing the dump from happening every time we TP.
@@ -287,3 +347,35 @@ void LLTeleportHistory::dump() const
LL_INFOS() << line.str() << LL_ENDL;
}
}
+
+// [FIRE-35355] Callback for OpenSim so we can teleport to the correct global position on another grid
+void LLTeleportHistory::regionNameCallback(int idx, U64 region_handle, const LLSLURL& slurl, const LLUUID& snapshot_id, bool teleport)
+{
+ if (region_handle)
+ {
+ // Sanity checks again just in case since time has passed since the request was made
+ if (idx < 0 || idx >= (int)mItems.size())
+ {
+ LL_WARNS() << "Invalid teleport history index (" << idx << ") specified" << LL_ENDL;
+ return;
+ }
+
+ if (idx == mCurrentItem)
+ {
+ LL_WARNS() << "Will not teleport to the same location." << LL_ENDL;
+ return;
+ }
+
+ LLVector3d origin_pos = from_region_handle(region_handle);
+ LLVector3d global_pos(origin_pos + LLVector3d(slurl.getPosition()));
+
+ // Attempt to teleport to the target grids region
+ gAgent.teleportViaLocation(global_pos);
+ }
+ else
+ {
+ LL_WARNS() << "Invalid teleport history region handle" << LL_ENDL;
+ onTeleportFailed();
+ }
+}
+//
diff --git a/indra/newview/llteleporthistory.h b/indra/newview/llteleporthistory.h
index 6962f4afe3..5d705fe90d 100644
--- a/indra/newview/llteleporthistory.h
+++ b/indra/newview/llteleporthistory.h
@@ -35,6 +35,8 @@
#include
#include "llteleporthistorystorage.h"
+#include "llslurl.h" // Access to LLSLURL
+
/**
* An item of the teleport history.
@@ -47,8 +49,11 @@ public:
LLTeleportHistoryItem()
{}
- LLTeleportHistoryItem(std::string title, LLVector3d global_pos)
- : mTitle(title), mGlobalPos(global_pos)
+ // [FIRE-35355] OpenSim requires knowing the grid to teleport correctly if changing grids
+ //LLTeleportHistoryItem(std::string title, LLVector3d global_pos)
+ // : mTitle(title), mGlobalPos(global_pos)
+ LLTeleportHistoryItem(std::string title, LLVector3d global_pos, const LLSLURL& slurl = LLSLURL())
+ : mTitle(title), mGlobalPos(global_pos), mSLURL(slurl)
{}
/**
@@ -61,6 +66,7 @@ public:
std::string mFullTitle; // human-readable location title including coordinates
LLVector3d mGlobalPos; // global position
LLUUID mRegionID; // region ID for getting the region info
+ LLSLURL mSLURL; // [FIRE-35355] slurl for the location required for OpenSim
};
/**
@@ -180,6 +186,10 @@ private:
*/
static std::string getCurrentLocationTitle(bool full, const LLVector3& local_pos_override);
+ // [FIRE-35355] Callback for OpenSim so we can teleport to the correct global position on another grid
+ void regionNameCallback(int idx, U64 handle, const LLSLURL& slurl, const LLUUID& snapshot_id, bool teleport);
+ //
+
/**
* Actually, the teleport history.
*/