diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 3f32be1d68aae289a89fbcf4cbc57b1282db551c..a2211d7356ddc77fb747d82ba7bd51ea4570ae6a 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 4830cb754b6654dd89f6db6d366d1f3eb7e289cb..a8689dd5a6779ef99889a0ffaad2bcfca28d17c3 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 49886b5e4fe7f72e08295ad35d5ac5ea0d9d1515..f3d0369da6ef57eeadc08909f98967569932a953 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);