From 4d2517d163cf34c9b7b8fc387e45da2ea0848213 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood Date: Sun, 29 Dec 2013 21:49:05 +0100 Subject: [PATCH] Freeze also synchronized avatars when editing an attachment. On the removal of permYouOwner(): Calling permYouOwner() to determine if an attachment is yours is not correct: grid gods (and that includes BEFORE requesting admin status) are marked as owner of everything in their sim. The reason for that is that otherwise, if they only had it when actually godding u, the viewer would have to have an option to either show the proper menus (it doesn't) or allow the sim to refresh the object flags without full object updates (it hasn't). gods often have to act fast, for instance with griefers. Having transition to god mode take as long as a full rez just isn't an option, apart from the sim load caused by resending all objects. Then i tried resending only the object that was selected but there the arriving object update would close the pie menu. So you right-click a prim and the pie menu would close again. The result has always been that if you are on your own sim, in opensim, and select an attachment on another avatar, then YOU would freeze, not the selected avatar. This patch fixes that "opensim related" bug as well. --- indra/llcharacter/llcharacter.cpp | 14 +++++++++ indra/llcharacter/llcharacter.h | 2 ++ indra/llcharacter/llmotioncontroller.cpp | 38 ++++++++++++++++++++++++ indra/llcharacter/llmotioncontroller.h | 6 ++++ indra/newview/llselectmgr.cpp | 25 +++++----------- indra/newview/llselectmgr.h | 2 +- 6 files changed, 69 insertions(+), 18 deletions(-) diff --git a/indra/llcharacter/llcharacter.cpp b/indra/llcharacter/llcharacter.cpp index 65d37f8e0..12960ac01 100644 --- a/indra/llcharacter/llcharacter.cpp +++ b/indra/llcharacter/llcharacter.cpp @@ -543,3 +543,17 @@ LLAnimPauseRequest LLCharacter::requestPause() return mPauseRequest; } +void LLCharacter::requestPause(std::vector& avatar_pause_handles) +{ + mMotionController.pauseAllMotions(); + avatar_pause_handles.push_back(mPauseRequest); +} + +void LLCharacter::pauseAllSyncedCharacters(std::vector& avatar_pause_handles) +{ + // Pause this avatar. + requestPause(avatar_pause_handles); + // Also pause all avatars with synchronized motions. + mMotionController.pauseAllSyncedCharacters(avatar_pause_handles); +} + diff --git a/indra/llcharacter/llcharacter.h b/indra/llcharacter/llcharacter.h index 74cc35187..f618b446f 100644 --- a/indra/llcharacter/llcharacter.h +++ b/indra/llcharacter/llcharacter.h @@ -159,6 +159,8 @@ public: void updateMotions(e_update_t update_type); LLAnimPauseRequest requestPause(); + void requestPause(std::vector& avatar_pause_handles); + void pauseAllSyncedCharacters(std::vector& avatar_pause_handles); BOOL areAnimationsPaused() const { return mMotionController.isPaused(); } void setAnimTimeFactor(F32 factor) { mMotionController.setTimeFactor(factor); } void setTimeStep(F32 time_step) { mMotionController.setTimeStep(time_step); } diff --git a/indra/llcharacter/llmotioncontroller.cpp b/indra/llcharacter/llmotioncontroller.cpp index 7c7192be0..f5380957f 100644 --- a/indra/llcharacter/llmotioncontroller.cpp +++ b/indra/llcharacter/llmotioncontroller.cpp @@ -1257,6 +1257,44 @@ void LLMotionController::refresh_hidden(void) } } } + +void LLMotionController::pauseAllSyncedCharacters(std::vector& avatar_pause_handles) +{ + // Run over all motions. + for (motion_list_t::iterator iter = mActiveMotions.begin(); iter != mActiveMotions.end(); ++iter) + { + LLMotion* motionp = *iter; + AISyncServer* server = motionp->server(); + if (server && !server->never_synced() && motionp->isActive()) // Skip motions that aren't synchronized at all or that are not active. + { + // Run over all clients of the found servers. + AISyncServer::client_list_t const& clients = server->getClients(); + for (AISyncServer::client_list_t::const_iterator client = clients.begin(); client != clients.end(); ++client) + { + LLMotion* motion = dynamic_cast(client->mClientPtr); + if (!motion) + { + continue; + } + LLMotionController* controller = motion->getController(); + if (controller == this) + { + continue; + } + controller->requestPause(avatar_pause_handles); + } + } + } +} + +void LLMotionController::requestPause(std::vector& avatar_pause_handles) +{ + if (mCharacter) + { + mCharacter->requestPause(avatar_pause_handles); + } +} + // //----------------------------------------------------------------------------- diff --git a/indra/llcharacter/llmotioncontroller.h b/indra/llcharacter/llmotioncontroller.h index ac3d6d1f2..054f1c2f9 100644 --- a/indra/llcharacter/llmotioncontroller.h +++ b/indra/llcharacter/llmotioncontroller.h @@ -52,6 +52,8 @@ //----------------------------------------------------------------------------- class LLCharacter; class LLMotionController; +class LLPauseRequestHandle; +typedef LLPointer LLAnimPauseRequest; //----------------------------------------------------------------------------- // LLMotionRegistry @@ -160,6 +162,10 @@ public: void pauseAllMotions(); void unpauseAllMotions(); BOOL isPaused() const { return mPaused; } + // + void requestPause(std::vector& avatar_pause_handles); + void pauseAllSyncedCharacters(std::vector& avatar_pause_handles); + // void setTimeStep(F32 step); diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 4881139df..976397931 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -6506,7 +6506,7 @@ void LLSelectMgr::updateSelectionCenter() mSelectionCenterGlobal.clearVec(); mShowSelection = FALSE; mSelectionBBox = LLBBox(); - mPauseRequest = NULL; + mPauseRequests.clear(); resetAgentHUDZoom(); } @@ -6516,27 +6516,18 @@ void LLSelectMgr::updateSelectionCenter() if (mSelectedObjects->mSelectType == SELECT_TYPE_ATTACHMENT && isAgentAvatarValid()) { - // Singu Note: Chalice Yao's pause agent on attachment selection - if (object->permYouOwner()) + // Freeze avatars with a selected attachment, and all avatars with synchronized motions, if any. + LLVOAvatar* avatar = object->getAvatar(); + // It is possible that 'avatar' is NULL despite this being an attachment because of some race condition. + // In that case just don't freeze the avatar. + if (avatar) { - mPauseRequest = gAgentAvatarp->requestPause(); - } - else if (LLViewerObject* objectp = mSelectedObjects->getPrimaryObject()) - { - while (objectp && !objectp->isAvatar()) - { - objectp = (LLViewerObject*)objectp->getParent(); - } - - if (objectp) - { - mPauseRequest = objectp->asAvatar()->requestPause(); - } + avatar->pauseAllSyncedCharacters(mPauseRequests); } } else { - mPauseRequest = NULL; + mPauseRequests.clear(); } if (mSelectedObjects->mSelectType != SELECT_TYPE_HUD && isAgentAvatarValid()) diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index 16c960ba8..145c25005 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -793,7 +793,7 @@ private: LLFrameTimer mEffectsTimer; BOOL mForceSelection; - LLAnimPauseRequest mPauseRequest; + std::vector mPauseRequests; // Selected avatar and all synchronized avatars. friend class LLObjectBackup; };