summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSalad Dais <SaladDais@users.noreply.github.com>2023-11-09 15:41:08 +0000
committerAndrey Lihatskiy <alihatskiy@productengine.com>2024-04-10 17:59:25 +0300
commit00e09ddcad8ec2c33ecbcdd0da09bd7819bc3509 (patch)
tree39014462c8205c5e5a0c7835d1b88ef8c06b397c
parent5b88d4d3253820e7b0c317b078ce9f27e59ac6f3 (diff)
Fix BUG-225288: Detaching stops unrelated animations
This is to do with misunderstandings related to how .find() works with multimaps. .find() will, in fact, return an iterator to the first iterator it finds, and will iterate through all elements in the multimap when incremented, not just items with the same key. Change code working with animation sources to be aware of this fact, so unrelated animation sources do not have their animations stopped.
-rw-r--r--indra/newview/llviewermessage.cpp6
-rw-r--r--indra/newview/llvoavatarself.cpp6
2 files changed, 11 insertions, 1 deletions
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 0ee5b8f454..b41d1d9712 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -4166,6 +4166,12 @@ void process_avatar_animation(LLMessageSystem *mesgsys, void **user_data)
LLVOAvatar::AnimSourceIterator anim_it = avatarp->mAnimationSources.find(object_id);
for (;anim_it != avatarp->mAnimationSources.end(); ++anim_it)
{
+ if (anim_it->first != object_id)
+ {
+ // elements with the same key are always contiguous, bail if we went past the
+ // end of this object's animations
+ break;
+ }
if (anim_it->second == animation_id)
{
anim_found = TRUE;
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index 7b24b9ee02..f12fc3babc 100644
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -834,7 +834,11 @@ void LLVOAvatarSelf::stopMotionFromSource(const LLUUID& source_id)
for (AnimSourceIterator motion_it = mAnimationSources.find(source_id); motion_it != mAnimationSources.end(); )
{
gAgent.sendAnimationRequest(motion_it->second, ANIM_REQUEST_STOP);
- mAnimationSources.erase(motion_it++);
+ mAnimationSources.erase(motion_it);
+ // Must find() after each erase() to deal with potential iterator invalidation
+ // This also ensures that we don't go past the end of this source's animations
+ // into those of another source.
+ motion_it = mAnimationSources.find(source_id);
}