From 6c16f7ab106331d3a24ab9f00ab4f72d836a38c3 Mon Sep 17 00:00:00 2001 From: Ansariel Date: Wed, 15 Nov 2023 17:40:16 +0100 Subject: [PATCH 1/8] Add some of the headers being worst offenders slowing down build time to the PCH --- indra/newview/llviewerprecompiledheaders.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/indra/newview/llviewerprecompiledheaders.h b/indra/newview/llviewerprecompiledheaders.h index 3bed65e1c4..b6e0a3c606 100644 --- a/indra/newview/llviewerprecompiledheaders.h +++ b/indra/newview/llviewerprecompiledheaders.h @@ -110,9 +110,13 @@ #include "llavatarname.h" #include "llavatarnamecache.h" #include "llcorehttputil.h" +#include "llfloater.h" #include "llformat.h" #include "llmatrix4a.h" +#include "llpanel.h" +#include "lluictrl.h" #include "llvector4a.h" +#include "llview.h" #include #include #include @@ -131,6 +135,6 @@ #include #include #include - +#include #endif From ce37208c359ffc523cd9946e20f690d320969759 Mon Sep 17 00:00:00 2001 From: Ansariel Date: Wed, 15 Nov 2023 17:58:35 +0100 Subject: [PATCH 2/8] We don't need those when creating an executable --- indra/newview/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index a4cacf136f..54af0079df 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -2144,9 +2144,9 @@ if (WINDOWS) set_target_properties(${VIEWER_BINARY_NAME} PROPERTIES # *TODO -reenable this once we get server usage sorted out - LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS /LARGEADDRESSAWARE /LTCG" - LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\" /INCREMENTAL:NO /LARGEADDRESSAWARE /LTCG" - LINK_FLAGS_RELEASE "/FORCE:MULTIPLE /MAP\"secondlife-bin.MAP\" /OPT:REF /LARGEADDRESSAWARE /LTCG" + LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS /LARGEADDRESSAWARE /LTCG /NOEXP /NOIMPLIB" + LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\" /INCREMENTAL:NO /LARGEADDRESSAWARE /LTCG /NOEXP /NOIMPLIB" + LINK_FLAGS_RELEASE "/FORCE:MULTIPLE /MAP\"secondlife-bin.MAP\" /OPT:REF /LARGEADDRESSAWARE /LTCG /NOEXP /NOIMPLIB" ) if(USE_PRECOMPILED_HEADERS) From 1ba1e68e25cb6a181ec2b631014bdb9aabbf0f12 Mon Sep 17 00:00:00 2001 From: Beq Date: Wed, 15 Nov 2023 16:20:44 +0000 Subject: [PATCH 3/8] Attempt to work around Mac issue with missing package llsd --- .github/workflows/build_viewer.yml | 44 ++++++++++++++++-------------- indra/newview/viewer_manifest.py | 9 ++++-- 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/.github/workflows/build_viewer.yml b/.github/workflows/build_viewer.yml index 760c99af92..03a49af97b 100644 --- a/.github/workflows/build_viewer.yml +++ b/.github/workflows/build_viewer.yml @@ -14,8 +14,6 @@ env: EXTRA_ARGS: -DUSE_FMODSTUDIO=ON -DUSE_KDU=ON --crashreporting build_secrets_checkout: ${{github.workspace}}/signing XZ_DEFAULTS: -T0 - - jobs: build_matrix: strategy: @@ -25,21 +23,28 @@ jobs: addrsize: [64] runs-on: ${{ matrix.os }} steps: + - name: Install Bash 4 and GNU sed on Mac + if: runner.os == 'macOS' + run: | + /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" + brew update + brew install bash + brew install gnu-sed + + echo "/usr/local/bin" >> $GITHUB_PATH + echo "$(brew --prefix)/opt/gnu-sed/libexec/gnubin" >> $GITHUB_PATH + - uses: actions/checkout@v3 - uses: actions/setup-python@v4 - id: py311 + id: py312 with: - python-version: '3.11' + python-version: '3.11.6' cache: 'pip' - - if: runner.os == 'Windows' - run: | - python3 -m pip install -r requirements.txt --user - echo "$HOME/.local/bin" >> $GITHUB_PATH - - - if: runner.os != 'Windows' + - name: Install python requirements run: | python3 -m pip install -r requirements.txt + python -m pip install -r requirements.txt - name: Check python version run: python -V @@ -54,6 +59,14 @@ jobs: EOF shell: bash + - name: Test python3 llsd + run: | + python3 - <> $GITHUB_ENV echo "CXX=g++-10" >> $GITHUB_ENV - - name: Install Bash 4 and GNU sed on Mac - if: runner.os == 'macOS' - run: | - /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" - brew update - - brew install bash - brew install gnu-sed - - echo "/usr/local/bin" >> $GITHUB_PATH - echo "$(brew --prefix)/opt/gnu-sed/libexec/gnubin" >> $GITHUB_PATH - name: Setup rclone and download the folder uses: beqjanus/setup-rclone@main diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index fe44b5a62f..94636371fc 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -53,8 +53,13 @@ viewer_dir = os.path.dirname(__file__) # indra.util.llmanifest under their system Python! sys.path.insert(0, os.path.join(viewer_dir, os.pardir, "lib", "python")) from indra.util.llmanifest import LLManifest, main, path_ancestors, CHANNEL_VENDOR_BASE, RELEASE_CHANNEL, ManifestError, MissingError -import llsd - +# try to work around weird Mac build issue that seems to find the wrong python +#import llsd +try: + import llsd +except ImportError: + from llbase import llsd +# class ViewerManifest(LLManifest,FSViewerManifest): def is_packaging_viewer(self): # Some commands, files will only be included From b3276e50b1ec4c02e27748a153b4efae31ce3096 Mon Sep 17 00:00:00 2001 From: Beq Date: Sat, 18 Nov 2023 02:23:58 +0000 Subject: [PATCH 4/8] Update KDU to 8.4.1 for all platforms. --- autobuild.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index eae531cafe..b60650a4cc 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -1479,9 +1479,9 @@ archive hash - 3142fccbcc0e2c5a019e3177ef364290 + 47af788cc447a64e311e3a65b74a9cf9 url - file:///opt/firestorm/kdu-8.3-darwin64-232392239.tar.bz2 + file:///opt/firestorm/kdu-8.4.1-darwin64-233220201.tar.bz2 name darwin64 @@ -1491,9 +1491,9 @@ archive hash - e13d6fe708613bb3a5d630c4cdd97a3b + b464a547d5bedcc72e9173d860f40656 url - file:///opt/firestorm/kdu-8.3-linux64-232392238.tar.bz2 + file:///opt/firestorm/kdu-8.4.1-linux64-233220158.tar.bz2 name linux64 @@ -1503,9 +1503,9 @@ archive hash - 4aa7df19125708580055b42190d2511e + 526965ad83ad9ee355b6596f489d82d9 url - file:///c:/cygwin/opt/firestorm/kdu-8.3-windows-232392239.tar.bz2 + file:///c:/cygwin/opt/firestorm/kdu-8.4.1-windows-233220159.tar.bz2 name windows64 From f4fb4cdb75f8cea23b8666a55f4b3d3c3d9aa670 Mon Sep 17 00:00:00 2001 From: Zi Ree Date: Thu, 23 Nov 2023 00:25:06 +0100 Subject: [PATCH 5/8] FIRE-33384 - Fix notecard import for animation overrider --- indra/newview/ao.cpp | 2 +- indra/newview/aoengine.cpp | 201 +++++++++--------- indra/newview/aoengine.h | 3 +- .../skins/default/xui/en/notifications.xml | 7 + 4 files changed, 106 insertions(+), 107 deletions(-) diff --git a/indra/newview/ao.cpp b/indra/newview/ao.cpp index 45502fd1d5..c684781fc2 100644 --- a/indra/newview/ao.cpp +++ b/indra/newview/ao.cpp @@ -534,7 +534,7 @@ bool FloaterAO::newSetCallback(const LLSD& notification, const LLSD& response) if (option == 0) { - return AOEngine::instance().addSet(newSetName, [this](const LLUUID& new_cat_id) + AOEngine::instance().addSet(newSetName, [this](const LLUUID& new_cat_id) { reloading(true); }); diff --git a/indra/newview/aoengine.cpp b/indra/newview/aoengine.cpp index 4ca498bb58..ac306310af 100644 --- a/indra/newview/aoengine.cpp +++ b/indra/newview/aoengine.cpp @@ -55,7 +55,6 @@ AOEngine::AOEngine() : mInMouselook(false), mUnderWater(false), mImportSet(nullptr), - mImportCategory(LLUUID::null), mAOFolder(LLUUID::null), mLastMotion(ANIM_AGENT_STAND), mLastOverriddenMotion(ANIM_AGENT_STAND) @@ -976,13 +975,13 @@ void AOEngine::updateSortOrder(AOSet::AOState* state) } } -bool AOEngine::addSet(const std::string& name, inventory_func_type callback, bool reload) +void AOEngine::addSet(const std::string& name, inventory_func_type callback, bool reload) { if (mAOFolder.isNull()) { LL_WARNS("AOEngine") << ROOT_AO_FOLDER << " folder not there yet. Requesting recreation." << LL_ENDL; tick(); - return false; + return; } BOOL wasProtected = gSavedPerAccountSettings.getBOOL("LockAOFolders"); @@ -992,45 +991,19 @@ bool AOEngine::addSet(const std::string& name, inventory_func_type callback, boo { gSavedPerAccountSettings.setBOOL("LockAOFolders", wasProtected); - if (reload) - { - mTimerCollection.enableReloadTimer(true); - } - callback(new_cat_id); }); - return true; + + if (reload) + { + mTimerCollection.enableReloadTimer(true); + } } bool AOEngine::createAnimationLink(const AOSet* set, AOSet::AOState* state, const LLInventoryItem* item) { LL_DEBUGS("AOEngine") << "Asset ID " << item->getAssetUUID() << " inventory id " << item->getUUID() << " category id " << state->mInventoryUUID << LL_ENDL; - if (state->mInventoryUUID.isNull()) - { - LL_DEBUGS("AOEngine") << "no " << state->mName << " folder yet. Creating ..." << LL_ENDL; - gInventory.createNewCategory(set->getInventoryUUID(), LLFolderType::FT_NONE, state->mName); - - LL_DEBUGS("AOEngine") << "looking for folder to get UUID ..." << LL_ENDL; - LLUUID newStateFolderUUID; - - LLInventoryModel::item_array_t* items; - LLInventoryModel::cat_array_t* cats; - gInventory.getDirectDescendentsOf(set->getInventoryUUID(), cats, items); - - if (cats) - { - for (const auto& cat : *cats) - { - if (cat->getName().compare(state->mName) == 0) - { - LL_DEBUGS("AOEngine") << "UUID found!" << LL_ENDL; - newStateFolderUUID = cat->getUUID(); - state->mInventoryUUID = newStateFolderUUID; - break; - } - } - } - } + LL_DEBUGS("AOEngine") << "state " << state->mName << " item " << item->getName() << LL_ENDL; if (state->mInventoryUUID.isNull()) { @@ -1965,6 +1938,8 @@ bool AOEngine::importNotecard(const LLInventoryItem* item) if (item->getAssetUUID().notNull()) { + // create the new set with the folder UUID where the notecard is in, so we can reference it + // in the notecard reader, this will later be cleared to make room for the real #AO subfolder mImportSet = new AOSet(item->getParentUUID()); mImportSet->setName(item->getName()); @@ -2033,7 +2008,7 @@ void AOEngine::parseNotecard(const char* buffer) LL_WARNS("AOEngine") << "buffer==NULL - aborting import" << LL_ENDL; // NOTE: cleanup is always the same, needs streamlining delete mImportSet; - mImportSet = 0; + mImportSet = nullptr; mUpdatedSignal(); return; } @@ -2044,31 +2019,34 @@ void AOEngine::parseNotecard(const char* buffer) std::vector lines; LLStringUtil::getTokens(text, lines, "\n"); - bool found{ false }; + S32 found = 0; + std::size_t index = 0; for (const auto& line : lines) { if (line.find("Text length ") == 0) { - found = true; + found = index + 1; break; } + index++; } if (!found) { LLNotificationsUtil::add("AOImportNoText", LLSD()); delete mImportSet; - mImportSet = 0; + mImportSet = nullptr; mUpdatedSignal(); return; } + // mImportSet->getInventoryUUID() right now contains the folder UUID where the notecard is in LLViewerInventoryCategory* importCategory = gInventory.getCategory(mImportSet->getInventoryUUID()); if (!importCategory) { LLNotificationsUtil::add("AOImportNoFolder", LLSD()); delete mImportSet; - mImportSet = 0; + mImportSet = nullptr; mUpdatedSignal(); return; } @@ -2078,7 +2056,7 @@ void AOEngine::parseNotecard(const char* buffer) LLInventoryModel::item_array_t* items; gInventory.getDirectDescendentsOf(mImportSet->getInventoryUUID(), dummy, items); - for (auto index = 0; index < items->size(); ++index) + for (index = 0; index < items->size(); ++index) { animationMap[items->at(index)->getName()] = items->at(index)->getUUID(); LL_DEBUGS("AOEngine") << "animation " << items->at(index)->getName() << @@ -2086,7 +2064,7 @@ void AOEngine::parseNotecard(const char* buffer) } // [ State ]Anim1|Anim2|Anim3 - for (auto index = found + 1; index < lines.size(); ++index) + for (index = found; index < lines.size(); ++index) { std::string line = lines[index]; @@ -2169,6 +2147,8 @@ void AOEngine::parseNotecard(const char* buffer) return; } + // clear out set UUID so processImport() knows we need to create a new folder for it + mImportSet->setInventoryUUID(LLUUID::null); mTimerCollection.enableImportTimer(true); mImportRetryCount = 0; processImport(false); @@ -2176,74 +2156,87 @@ void AOEngine::parseNotecard(const char* buffer) void AOEngine::processImport(bool from_timer) { - if (mImportCategory.isNull()) + if (mImportSet->getInventoryUUID().isNull()) { - bool success = addSet(mImportSet->getName(), [this, from_timer](const LLUUID& new_cat_id) + // create new inventory folder for this AO set, the next timer tick should pick it up + addSet(mImportSet->getName(), [this, from_timer](const LLUUID& new_cat_id) { - mImportCategory = new_cat_id; - mImportSet->setInventoryUUID(mImportCategory); - - bool allComplete = true; - for (S32 index = 0; index < AOSet::AOSTATES_MAX; ++index) - { - AOSet::AOState* state = mImportSet->getState(index); - if (!state->mAnimations.empty()) - { - allComplete = false; - LL_DEBUGS("AOEngine") << "state " << state->mName << " still has animations to link." << LL_ENDL; - - for (auto animationIndex = state->mAnimations.size() - 1; animationIndex >= 0; --animationIndex) - { - LL_DEBUGS("AOEngine") << "linking animation " << state->mAnimations[animationIndex].mName << LL_ENDL; - if (createAnimationLink(mImportSet, state, gInventory.getItem(state->mAnimations[animationIndex].mInventoryUUID))) - { - LL_DEBUGS("AOEngine") << "link success, size " << state->mAnimations.size() << ", removing animation " - << (*(state->mAnimations.begin() + animationIndex)).mName << " from import state" << LL_ENDL; - state->mAnimations.erase(state->mAnimations.begin() + animationIndex); - LL_DEBUGS("AOEngine") << "deleted, size now: " << state->mAnimations.size() << LL_ENDL; - } - else - { - LLSD args; - args["NAME"] = state->mAnimations[animationIndex].mName; - LLNotificationsUtil::add("AOImportLinkFailed", args); - } - } - } - } - - if (allComplete) - { - mTimerCollection.enableImportTimer(false); - mOldImportSets.push_back(mImportSet); // FIRE-3801; Cannot delete here, or LLInstanceTracker gets upset. Just remember and delete mOldImportSets once we can. - mImportSet = nullptr; - mImportCategory.setNull(); - reload(from_timer); - } + mImportSet->setInventoryUUID(new_cat_id); }, false); - if (!success) + mImportRetryCount++; + + // if it takes this long to create a new inventoey category, there might be something wrong, + // so give some user feedback at first + if (mImportRetryCount == 2) { - mImportRetryCount++; - if (mImportRetryCount == 5) - { - // NOTE: cleanup is the same as at the end of this function. Needs streamlining. - mTimerCollection.enableImportTimer(false); - delete mImportSet; - mImportSet = nullptr; - mImportCategory.setNull(); - mUpdatedSignal(); - LLSD args; - args["NAME"] = mImportSet->getName(); - LLNotificationsUtil::add("AOImportAbortCreateSet", args); - } - else - { - LLSD args; - args["NAME"] = mImportSet->getName(); - LLNotificationsUtil::add("AOImportRetryCreateSet", args); - } + LLSD args; + args["NAME"] = mImportSet->getName(); + LLNotificationsUtil::add("AOImportRetryCreateSet", args); + return; } + // by now there clearly is something wrong, so stop trying + else if (mImportRetryCount == 5) + { + // NOTE: cleanup is the same as at the end of this function. Needs streamlining. + mTimerCollection.enableImportTimer(false); + delete mImportSet; + mImportSet = nullptr; + mUpdatedSignal(); + LLSD args; + args["NAME"] = mImportSet->getName(); + LLNotificationsUtil::add("AOImportAbortCreateSet", args); + } + + return; + } + + bool allComplete = true; + for (S32 index = 0; index < AOSet::AOSTATES_MAX; ++index) + { + AOSet::AOState* state = mImportSet->getState(index); + if (!state->mAnimations.empty()) + { + allComplete = false; + LL_DEBUGS("AOEngine") << "state " << state->mName << " still has animations to link." << LL_ENDL; + + gInventory.createNewCategory(mImportSet->getInventoryUUID(), LLFolderType::FT_NONE, state->mName, [this, state](const LLUUID& new_cat_id) + { + LL_DEBUGS("AOEngine") << "new_cat_id: " << new_cat_id << LL_ENDL; + state->mInventoryUUID = new_cat_id; + + S32 animationIndex = state->mAnimations.size() - 1; + while (!state->mAnimations.empty()) + { + LL_DEBUGS("AOEngine") << "linking animation " << state->mAnimations[animationIndex].mName << LL_ENDL; + if (createAnimationLink(mImportSet, state, gInventory.getItem(state->mAnimations[animationIndex].mInventoryUUID))) + { + LL_DEBUGS("AOEngine") << "link success, size " << state->mAnimations.size() << ", removing animation " + << state->mAnimations[animationIndex].mName << " from import state" << LL_ENDL; + state->mAnimations.pop_back(); + LL_DEBUGS("AOEngine") << "deleted, size now: " << state->mAnimations.size() << LL_ENDL; + } + else + { + LLSD args; + args["NAME"] = state->mAnimations[animationIndex].mName; + LLNotificationsUtil::add("AOImportLinkFailed", args); + } + animationIndex--; + } + + LL_DEBUGS("AOEngine") << "exiting lambda" << LL_ENDL; + }); + } + } + + if (allComplete) + { + mTimerCollection.enableImportTimer(false); + mOldImportSets.push_back(mImportSet); // FIRE-3801; Cannot delete here, or LLInstanceTracker gets upset. Just remember and delete mOldImportSets once we can. + mImportSet = nullptr; + reload(from_timer); + LLNotificationsUtil::add("AOImportComplete"); } } diff --git a/indra/newview/aoengine.h b/indra/newview/aoengine.h index 062786b689..fdbbd7acfe 100644 --- a/indra/newview/aoengine.h +++ b/indra/newview/aoengine.h @@ -106,7 +106,7 @@ class AOEngine const LLUUID& getAOFolder() const; - bool addSet(const std::string& name, inventory_func_type callback, bool reload = true); + void addSet(const std::string& name, inventory_func_type callback, bool reload = true); bool removeSet(AOSet* set); bool addAnimation(const AOSet* set, AOSet::AOState* state, const LLInventoryItem* item, bool reload = true); @@ -217,7 +217,6 @@ class AOEngine AOSet* mImportSet; std::vector mOldImportSets; - LLUUID mImportCategory; S32 mImportRetryCount; boost::signals2::connection mRegionChangeConnection; diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index a855dd1398..259338784f 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -10674,6 +10674,13 @@ Remove AO set "[AO_SET_NAME]" from the list? The animation overrider found at least one item that did not belong in the configuration. Please check your "Lost and Found" folder for items that were moved out of the animation overrider configuration. + +Animation Overrider notecard import complete! + + Date: Thu, 23 Nov 2023 18:50:49 +0000 Subject: [PATCH 6/8] FIRE-33384 - AO updates. Make pernickety compilers happy. --- indra/newview/aoengine.cpp | 40 ++++++++++++++++---------------------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/indra/newview/aoengine.cpp b/indra/newview/aoengine.cpp index ac306310af..569f5d3662 100644 --- a/indra/newview/aoengine.cpp +++ b/indra/newview/aoengine.cpp @@ -987,7 +987,7 @@ void AOEngine::addSet(const std::string& name, inventory_func_type callback, boo BOOL wasProtected = gSavedPerAccountSettings.getBOOL("LockAOFolders"); gSavedPerAccountSettings.setBOOL("LockAOFolders", FALSE); LL_DEBUGS("AOEngine") << "adding set folder " << name << LL_ENDL; - gInventory.createNewCategory(mAOFolder, LLFolderType::FT_NONE, name, [callback, wasProtected, reload, this](const LLUUID &new_cat_id) + gInventory.createNewCategory(mAOFolder, LLFolderType::FT_NONE, name, [callback, wasProtected](const LLUUID &new_cat_id) { gSavedPerAccountSettings.setBOOL("LockAOFolders", wasProtected); @@ -2019,20 +2019,12 @@ void AOEngine::parseNotecard(const char* buffer) std::vector lines; LLStringUtil::getTokens(text, lines, "\n"); - S32 found = 0; - std::size_t index = 0; - for (const auto& line : lines) - { - if (line.find("Text length ") == 0) - { - found = index + 1; - break; - } - index++; - } + auto it = std::find_if(lines.begin(), lines.end(), [](const std::string& line) { + return line.find("Text length ") == 0; + }); - if (!found) - { + if (it == lines.end()) { + // Line not found LLNotificationsUtil::add("AOImportNoText", LLSD()); delete mImportSet; mImportSet = nullptr; @@ -2040,6 +2032,9 @@ void AOEngine::parseNotecard(const char* buffer) return; } + // Line found, 'it' points to the found element + std::size_t found = std::distance(lines.begin(), it) + 1; + // mImportSet->getInventoryUUID() right now contains the folder UUID where the notecard is in LLViewerInventoryCategory* importCategory = gInventory.getCategory(mImportSet->getInventoryUUID()); if (!importCategory) @@ -2055,16 +2050,15 @@ void AOEngine::parseNotecard(const char* buffer) LLInventoryModel::cat_array_t* dummy; LLInventoryModel::item_array_t* items; - gInventory.getDirectDescendentsOf(mImportSet->getInventoryUUID(), dummy, items); - for (index = 0; index < items->size(); ++index) - { - animationMap[items->at(index)->getName()] = items->at(index)->getUUID(); - LL_DEBUGS("AOEngine") << "animation " << items->at(index)->getName() << - " has inventory UUID " << animationMap[items->at(index)->getName()] << LL_ENDL; - } + gInventory.getDirectDescendentsOf(mImportSet->getInventoryUUID(), dummy, items); + for (auto& item : *items) + { + animationMap[item->getName()] = item->getUUID(); + LL_DEBUGS("AOEngine") << "animation " << item->getName() << " has inventory UUID " << animationMap[item->getName()] << LL_ENDL; + } // [ State ]Anim1|Anim2|Anim3 - for (index = found; index < lines.size(); ++index) + for (auto index = found; index < lines.size(); ++index) { std::string line = lines[index]; @@ -2159,7 +2153,7 @@ void AOEngine::processImport(bool from_timer) if (mImportSet->getInventoryUUID().isNull()) { // create new inventory folder for this AO set, the next timer tick should pick it up - addSet(mImportSet->getName(), [this, from_timer](const LLUUID& new_cat_id) + addSet(mImportSet->getName(), [this](const LLUUID& new_cat_id) { mImportSet->setInventoryUUID(new_cat_id); }, false); From 3f1ee69ed6d23f8eec51c9b5b78c3b388ff556fb Mon Sep 17 00:00:00 2001 From: PanteraPolnocy Date: Sat, 25 Nov 2023 13:44:44 +0100 Subject: [PATCH 7/8] FIRE-33393 French translation update, by Laurent Bechir (+ Polish, too) --- indra/newview/skins/default/xui/fr/notifications.xml | 3 +++ indra/newview/skins/default/xui/pl/notifications.xml | 3 +++ 2 files changed, 6 insertions(+) diff --git a/indra/newview/skins/default/xui/fr/notifications.xml b/indra/newview/skins/default/xui/fr/notifications.xml index 47d36c3573..2aa2ff5620 100644 --- a/indra/newview/skins/default/xui/fr/notifications.xml +++ b/indra/newview/skins/default/xui/fr/notifications.xml @@ -4176,6 +4176,9 @@ Le nom ne peut contenir que des caractères ASCII, sauf ":" et "|". L'AO a trouvé au moins un élément qui n'avait pas sa place dans la configuration. Veuillez vérifier dans votre dossier "Objets trouvés" les éléments qui ont été déplacés hors de la configuration de l'AO. + + L'importation de la notice d'AO est terminée ! + Un ensemble d'animations portant ce nom existe déjà. diff --git a/indra/newview/skins/default/xui/pl/notifications.xml b/indra/newview/skins/default/xui/pl/notifications.xml index 1d65164471..090c00d93d 100644 --- a/indra/newview/skins/default/xui/pl/notifications.xml +++ b/indra/newview/skins/default/xui/pl/notifications.xml @@ -3967,6 +3967,9 @@ Nazwa może zawierać tylko znaki ASCII, za wyjątkiem ":" oraz "|". Usunąć zestaw AO "[AO_SET_NAME]" z listy? + + Importowanie notki dla Animatora zakończone! + Zestaw animacji o tej nazwie już istnieje. From c801eb7678e18020951c839e81ace148e0a973bb Mon Sep 17 00:00:00 2001 From: Zi Ree Date: Wed, 29 Nov 2023 22:42:56 +0100 Subject: [PATCH 8/8] FIRE-33414 - fix animation overrider not being able to add animations to empty states --- indra/newview/ao.cpp | 12 ++++------ indra/newview/aoengine.cpp | 47 ++++++++++++++++++++++++++++++++------ indra/newview/aoengine.h | 4 ++-- indra/newview/aoset.h | 3 +++ 4 files changed, 50 insertions(+), 16 deletions(-) diff --git a/indra/newview/ao.cpp b/indra/newview/ao.cpp index c684781fc2..e9029c8037 100644 --- a/indra/newview/ao.cpp +++ b/indra/newview/ao.cpp @@ -891,14 +891,12 @@ BOOL FloaterAO::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDr *accept = ACCEPT_YES_MULTI; if (item && drop) { - if (AOEngine::instance().addAnimation(mSelectedSet, mSelectedState, item)) - { - addAnimation(item->getName()); + AOEngine::instance().addAnimation(mSelectedSet, mSelectedState, item); + addAnimation(item->getName()); - // TODO: this would be the right thing to do, but it blocks multi drop - // before final release this must be resolved - reloading(true); - } + // TODO: this would be the right thing to do, but it blocks multi drop + // before final release this must be resolved + reloading(true); } } else diff --git a/indra/newview/aoengine.cpp b/indra/newview/aoengine.cpp index 569f5d3662..9373ed525a 100644 --- a/indra/newview/aoengine.cpp +++ b/indra/newview/aoengine.cpp @@ -1000,7 +1000,7 @@ void AOEngine::addSet(const std::string& name, inventory_func_type callback, boo } } -bool AOEngine::createAnimationLink(const AOSet* set, AOSet::AOState* state, const LLInventoryItem* item) +bool AOEngine::createAnimationLink(AOSet::AOState* state, const LLInventoryItem* item) { LL_DEBUGS("AOEngine") << "Asset ID " << item->getAssetUUID() << " inventory id " << item->getUUID() << " category id " << state->mInventoryUUID << LL_ENDL; LL_DEBUGS("AOEngine") << "state " << state->mName << " item " << item->getName() << LL_ENDL; @@ -1019,7 +1019,7 @@ bool AOEngine::createAnimationLink(const AOSet* set, AOSet::AOState* state, cons return true; } -bool AOEngine::addAnimation(const AOSet* set, AOSet::AOState* state, const LLInventoryItem* item, bool reload) +void AOEngine::addAnimation(const AOSet* set, AOSet::AOState* state, const LLInventoryItem* item, bool reload) { AOSet::AOAnimation anim; anim.mAssetUUID = item->getAssetUUID(); @@ -1030,14 +1030,47 @@ bool AOEngine::addAnimation(const AOSet* set, AOSet::AOState* state, const LLInv BOOL wasProtected = gSavedPerAccountSettings.getBOOL("LockAOFolders"); gSavedPerAccountSettings.setBOOL("LockAOFolders", FALSE); - createAnimationLink(set, state, item); + bool success = createAnimationLink(state, item); gSavedPerAccountSettings.setBOOL("LockAOFolders", wasProtected); - if (reload) + if(success) { - mTimerCollection.enableReloadTimer(true); + if (reload) + { + mTimerCollection.enableReloadTimer(true); + } + return; + } + + // creating the animation link failed, so we need to create a new folder for this state - + // add the animation asset to the queue of animations to insert into the state - this takes + // care of multi animation drag & drop that come in faster than the viewer can create a new + // inventory folder + state->mAddQueue.push_back(item); + + // if this is the first queued animation for this state, create the folder asyncronously + if(state->mAddQueue.size() == 1) + { + gInventory.createNewCategory(set->getInventoryUUID(), LLFolderType::FT_NONE, state->mName, [this, state, reload, wasProtected](const LLUUID &new_cat_id) + { + state->mInventoryUUID = new_cat_id; + gSavedPerAccountSettings.setBOOL("LockAOFolders", FALSE); + + // add all queued animations to this state's folder and then clear the queue + for (const auto item : state->mAddQueue) + { + createAnimationLink(state, item); + } + state->mAddQueue.clear(); + + gSavedPerAccountSettings.setBOOL("LockAOFolders", wasProtected); + + if (reload) + { + mTimerCollection.enableReloadTimer(true); + } + }); } - return true; } bool AOEngine::findForeignItems(const LLUUID& uuid) const @@ -2203,7 +2236,7 @@ void AOEngine::processImport(bool from_timer) while (!state->mAnimations.empty()) { LL_DEBUGS("AOEngine") << "linking animation " << state->mAnimations[animationIndex].mName << LL_ENDL; - if (createAnimationLink(mImportSet, state, gInventory.getItem(state->mAnimations[animationIndex].mInventoryUUID))) + if (createAnimationLink(state, gInventory.getItem(state->mAnimations[animationIndex].mInventoryUUID))) { LL_DEBUGS("AOEngine") << "link success, size " << state->mAnimations.size() << ", removing animation " << state->mAnimations[animationIndex].mName << " from import state" << LL_ENDL; diff --git a/indra/newview/aoengine.h b/indra/newview/aoengine.h index fdbbd7acfe..baa01381d3 100644 --- a/indra/newview/aoengine.h +++ b/indra/newview/aoengine.h @@ -109,7 +109,7 @@ class AOEngine void addSet(const std::string& name, inventory_func_type callback, bool reload = true); bool removeSet(AOSet* set); - bool addAnimation(const AOSet* set, AOSet::AOState* state, const LLInventoryItem* item, bool reload = true); + void addAnimation(const AOSet* set, AOSet::AOState* state, const LLInventoryItem* item, bool reload = true); bool removeAnimation(const AOSet* set, AOSet::AOState* state, S32 index); void checkSitCancel(); void checkBelowWater(bool check_underwater); @@ -176,7 +176,7 @@ class AOEngine void saveSet(const AOSet* set); void saveState(const AOSet::AOState* state); - bool createAnimationLink(const AOSet* set, AOSet::AOState* state, const LLInventoryItem* item); + bool createAnimationLink(AOSet::AOState* state, const LLInventoryItem* item); bool findForeignItems(const LLUUID& uuid) const; void purgeFolder(const LLUUID& uuid) const; diff --git a/indra/newview/aoset.h b/indra/newview/aoset.h index 0e7d229bac..e40890cf55 100644 --- a/indra/newview/aoset.h +++ b/indra/newview/aoset.h @@ -27,6 +27,8 @@ #include "lleventtimer.h" +class LLInventoryItem; + class AOSet : public LLEventTimer { @@ -78,6 +80,7 @@ class AOSet { std::string mName; std::vector mAlternateNames; + std::vector mAddQueue; LLUUID mRemapID; bool mCycle; bool mRandom;