From 49fa9b5515e708083c85aaa2b1b522bc266944c4 Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Mon, 21 Dec 2015 19:22:40 +0200
Subject: [PATCH] MAINT-335 FIXED Avatar hangs in space after cancelling
 teleport

---
 indra/newview/llagent.cpp         | 16 +++++++++++++++-
 indra/newview/llagent.h           |  2 ++
 indra/newview/llviewermessage.cpp |  7 +++++++
 3 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 3f32be1d68a..a2211d7356d 100755
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -3849,6 +3849,7 @@ void LLAgent::startTeleportRequest()
     }
 	if (hasPendingTeleportRequest())
 	{
+        mTeleportCanceled.reset();
 		if  (!isMaturityPreferenceSyncedWithServer())
 		{
 			gTeleportDisplay = TRUE;
@@ -3878,6 +3879,7 @@ void LLAgent::startTeleportRequest()
 void LLAgent::handleTeleportFinished()
 {
 	clearTeleportRequest();
+    mTeleportCanceled.reset();
 	if (mIsMaturityRatingChangingDuringTeleport)
 	{
 		// notify user that the maturity preference has been changed
@@ -4021,13 +4023,25 @@ void LLAgent::teleportCancel()
 			msg->addUUIDFast(_PREHASH_AgentID, getID());
 			msg->addUUIDFast(_PREHASH_SessionID, getSessionID());
 			sendReliableMessage();
-		}	
+		}
+		mTeleportCanceled = mTeleportRequest;
 	}
 	clearTeleportRequest();
 	gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
 	gPipeline.resetVertexBuffers();
 }
 
+void LLAgent::restoreCanceledTeleportRequest()
+{
+    if (mTeleportCanceled != NULL)
+    {
+        gAgent.setTeleportState( LLAgent::TELEPORT_REQUESTED );
+        mTeleportRequest = mTeleportCanceled;
+        mTeleportCanceled.reset();
+        gTeleportDisplay = TRUE;
+        gTeleportDisplayTimer.reset();
+    }
+}
 
 void LLAgent::teleportViaLocation(const LLVector3d& pos_global)
 {
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index 4830cb754b6..a8689dd5a67 100755
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -616,6 +616,7 @@ class LLAgent : public LLOldEvents::LLObservable
 	void 			teleportViaLocation(const LLVector3d& pos_global);		// To a global location - this will probably need to be deprecated
 	void			teleportViaLocationLookAt(const LLVector3d& pos_global);// To a global location, preserving camera rotation
 	void 			teleportCancel();										// May or may not be allowed by server
+    void            restoreCanceledTeleportRequest();
 	bool			getTeleportKeepsLookAt() { return mbTeleportKeepsLookAt; } // Whether look-at reset after teleport
 protected:
 	bool 			teleportCore(bool is_local = false); 					// Stuff for all teleports; returns true if the teleport can proceed
@@ -638,6 +639,7 @@ class LLAgent : public LLOldEvents::LLObservable
 	friend class LLTeleportRequestViaLocationLookAt;
 
 	LLTeleportRequestPtr        mTeleportRequest;
+	LLTeleportRequestPtr        mTeleportCanceled;
 	boost::signals2::connection mTeleportFinishedSlot;
 	boost::signals2::connection mTeleportFailedSlot;
 
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 49886b5e4fe..f3d0369da6e 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -3996,6 +3996,13 @@ void process_teleport_finish(LLMessageSystem* msg, void**)
 		LL_WARNS("Messaging") << "Got teleport notification for wrong agent!" << LL_ENDL;
 		return;
 	}
+
+    if (gAgent.getTeleportState() == LLAgent::TELEPORT_NONE)
+    {
+        // Server either ignored teleport cancel message or did not receive it in time.
+        // This message can't be ignored since teleport is complete at server side
+        gAgent.restoreCanceledTeleportRequest();
+    }
 	
 	// Teleport is finished; it can't be cancelled now.
 	gViewerWindow->setProgressCancelButtonVisible(FALSE);
-- 
GitLab