From b2b075a235f26bd14195833eb6770098a7bf6799 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Wed, 29 Aug 2018 20:30:07 +0300
Subject: [PATCH] MAINT-6291 Fixed Scripted teleports have a higher rate of
 failure than user-initiated teleports.

Sim apparently sends finish and start messages simultaneously in case of
scripted or experience teleports
---
 indra/newview/llagent.cpp         |  1 +
 indra/newview/llagent.h           |  1 +
 indra/newview/llviewermessage.cpp | 26 ++++++++++++++++++++++----
 3 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 901294d6b49..9b8cc62aa81 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -4150,6 +4150,7 @@ void LLAgent::setTeleportState(ETeleportState state)
             " for previously failed teleport.  Ignore!" << LL_ENDL;
         return;
     }
+    LL_DEBUGS("Teleport") << "Setting teleport state to " << state << " Previous state: " << mTeleportState << LL_ENDL;
 	mTeleportState = state;
 	if (mTeleportState > TELEPORT_NONE && gSavedSettings.getBOOL("FreezeTime"))
 	{
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index 4bb4d317e80..b1b39b637e4 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -629,6 +629,7 @@ class LLAgent : public LLOldEvents::LLObservable
 	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			canRestoreCanceledTeleport() { return mTeleportCanceled != NULL; }
 	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
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index a2b4a6a91dd..a8db3846576 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -2709,6 +2709,12 @@ void process_teleport_start(LLMessageSystem *msg, void**)
 	U32 teleport_flags = 0x0;
 	msg->getU32("Info", "TeleportFlags", teleport_flags);
 
+	if (gAgent.getTeleportState() == LLAgent::TELEPORT_MOVING)
+	{
+		// Race condition?
+		LL_WARNS("Messaging") << "Got TeleportStart, but teleport already in progress. TeleportFlags=" << teleport_flags << LL_ENDL;
+	}
+
 	LL_DEBUGS("Messaging") << "Got TeleportStart with TeleportFlags=" << teleport_flags << ". gTeleportDisplay: " << gTeleportDisplay << ", gAgent.mTeleportState: " << gAgent.getTeleportState() << LL_ENDL;
 
 	// *NOTE: The server sends two StartTeleport packets when you are teleporting to a LM
@@ -2766,7 +2772,7 @@ void process_teleport_progress(LLMessageSystem* msg, void**)
 	}
 	std::string buffer;
 	msg->getString("Info", "Message", buffer);
-	LL_DEBUGS("Messaging") << "teleport progress: " << buffer << LL_ENDL;
+	LL_DEBUGS("Messaging") << "teleport progress: " << buffer << " flags: " << teleport_flags << LL_ENDL;
 
 	//Sorta hacky...default to using simulator raw messages
 	//if we don't find the coresponding mapping in our progress mappings
@@ -2889,9 +2895,21 @@ void process_teleport_finish(LLMessageSystem* msg, void**)
 
     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();
+        if (gAgent.canRestoreCanceledTeleport())
+        {
+            // 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();
+        }
+        else
+        {
+            // Race condition? Make sure all variables are set correctly for teleport to work
+            LL_WARNS("Messaging") << "Teleport 'finish' message without 'start'" << LL_ENDL;
+            gTeleportDisplay = TRUE;
+            LLViewerMessage::getInstance()->mTeleportStartedSignal();
+            gAgent.setTeleportState(LLAgent::TELEPORT_REQUESTED);
+            make_ui_sound("UISndTeleportOut");
+        }
     }
 	
 	// Teleport is finished; it can't be cancelled now.
-- 
GitLab