diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 1ce647cb8b..a6a976c1f5 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -88,6 +88,7 @@ set(viewer_SOURCE_FILES ao.cpp aoengine.cpp aoset.cpp + alassetblocklist.cpp alavataractions.cpp alavatargroups.cpp alchatcommand.cpp @@ -832,6 +833,7 @@ set(viewer_HEADER_FILES ao.h aoengine.h aoset.h + alassetblocklist.h alavataractions.h alavatargroups.h alchatcommand.h diff --git a/indra/newview/alassetblocklist.cpp b/indra/newview/alassetblocklist.cpp new file mode 100644 index 0000000000..c665de8d4a --- /dev/null +++ b/indra/newview/alassetblocklist.cpp @@ -0,0 +1,205 @@ +/** + * @file alassetblocklist.h + * @brief + * + * $LicenseInfo:firstyear=2024&license=viewerlgpl$ + * Alchemy Viewer Source Code + * Copyright (C) 2024, Rye Mutt + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "alassetblocklist.h" + +#include "llagent.h" +#include "llsdserialize.h" +#include "llselectmgr.h" +#include "lltrans.h" +#include "llviewerobject.h" +#include "llviewerobjectlist.h" +#include "llviewerregion.h" +#include "llvocache.h" +#include "llvoavatarself.h" +#include "llworld.h" +#include "pipeline.h" +#include "llxorcipher.h" + + // ============================================================================ + // ALAssetBlocklist + // + +LLSD ALBlockedAsset::toLLSD() const +{ + LLSD data; + data["owner_id"] = mOwnerID; + data["location"] = mLocation; + data["type"] = mAssetType; + data["date"] = mDate; + return data; +} + +void ALBlockedAsset::fromLLSD(const LLSD& data) +{ + mOwnerID = data["owner_id"].asUUID(); + mLocation = data["location"].asString(); + mAssetType = (LLAssetType::EType)data["type"].asInteger(); + mDate = data["date"].asDate(); + mPersist = true; +} + +// ============================================================================ +// ALAssetBlocklist +// + +#define BLOCK_FILE "asset_blocklist.llsd" +const LLUUID PERSIST_ID("348da8de-abca-a407-8881-bc6f9b583388"); + +ALAssetBlocklist::ALAssetBlocklist() +{ + load(); +} + +ALAssetBlocklist::~ALAssetBlocklist() +{ +} + +void ALAssetBlocklist::load() +{ + llifstream fileDerender(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, BLOCK_FILE)); + if (!fileDerender.is_open()) + { + LL_WARNS() << "Can't open asset blocklist file \"" << BLOCK_FILE << "\" for reading" << LL_ENDL; + return; + } + + mEntries.clear(); + + LLSD inSD; + S32 ret = LLSDSerialize::fromNotation(inSD, fileDerender, LLSDSerialize::SIZE_UNLIMITED); + fileDerender.close(); + if (ret == LLSDParser::PARSE_FAILURE || !inSD.isMap()) + { + return; + } + + for (const auto& entry : inSD.asMap()) + { + LLUUID shadow_id{ entry.first }; + LLXORCipher cipher(PERSIST_ID.mData, UUID_BYTES); + cipher.decrypt(shadow_id.mData, UUID_BYTES); + mEntries.emplace(shadow_id, entry.second); + } +} + +void ALAssetBlocklist::save() const +{ + llofstream fileDerender(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, BLOCK_FILE)); + if (!fileDerender.is_open()) + { + LL_WARNS() << "Can't open asset blocklist file \"" << BLOCK_FILE << "\" for writing" << LL_ENDL; + return; + } + + LLSD outSD; + for (const auto&[key, value] : mEntries) + { + if (value.mPersist) + { + LLUUID shadow_id{ key }; + LLXORCipher cipher(PERSIST_ID.mData, UUID_BYTES); + cipher.encrypt(shadow_id.mData, UUID_BYTES); + outSD[shadow_id.asString()] = value.toLLSD(); + } + } + + LLSDSerialize::toNotation(outSD, fileDerender); +} + +void ALAssetBlocklist::addEntry(const LLUUID& asset_id, const LLUUID& avatar_id, const std::string& region, LLAssetType::EType type, bool persist/* = true*/) +{ + if (isBlocked(asset_id)) + { + return; + } + + ALBlockedAsset new_entry; + new_entry.mOwnerID = avatar_id; + new_entry.mLocation = region; + new_entry.mAssetType = type; + new_entry.mDate = LLDate(time_corrected()); + new_entry.mPersist = persist; + + mEntries.emplace(asset_id, new_entry); + + if (persist) + save(); + + mChangedSignal(); +} + +void ALAssetBlocklist::removeEntry(const LLUUID& asset_id) +{ + auto it = mEntries.find(asset_id); + if (it != mEntries.end()) + { + bool permanent = it->second.mPersist; + mEntries.erase(it); + + if (permanent) + save(); + + mChangedSignal(); + } +} + +void ALAssetBlocklist::removeEntries(const uuid_vec_t& asset_ids) +{ + bool permanent = false; + bool changed = false; + for(const auto& id : asset_ids) + { + auto it = mEntries.find(id); + if (it != mEntries.end()) + { + if(!permanent) + { + permanent = it->second.mPersist; + } + + mEntries.erase(it); + + if (!changed) + { + changed = true; + } + } + } + if (permanent) + save(); + + if(changed) + mChangedSignal(); +} + +bool ALAssetBlocklist::isBlocked(const LLUUID& asset_id) +{ + return mEntries.contains(asset_id); +} + +// ============================================================================ diff --git a/indra/newview/alassetblocklist.h b/indra/newview/alassetblocklist.h new file mode 100644 index 0000000000..0060344893 --- /dev/null +++ b/indra/newview/alassetblocklist.h @@ -0,0 +1,87 @@ +/** + * @file alassetblocklist.h + * @brief + * + * $LicenseInfo:firstyear=2024&license=viewerlgpl$ + * Alchemy Viewer Source Code + * Copyright (C) 2024, Rye Mutt + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * $/LicenseInfo$ + */ + +#ifndef LL_ASSETBLOCK_H +#define LL_ASSETBLOCK_H + +#include "llsingleton.h" +#include "lluuid.h" +#include "llassettype.h" + +#include "boost/unordered_map.hpp" +#include "boost/signals2.hpp" + + +// ============================================================================ +// ALAssetBlocklist +// + +class ALBlockedAsset +{ +public: + ALBlockedAsset() = default; + ALBlockedAsset(const LLSD& sd) { fromLLSD(sd); } + + LLSD toLLSD() const; + void fromLLSD(const LLSD& sd); + + std::string mLocation; + LLUUID mOwnerID; + LLDate mDate; + LLAssetType::EType mAssetType = LLAssetType::AT_NONE; + bool mPersist = true; +}; + +class ALAssetBlocklist : public LLSingleton +{ + LLSINGLETON(ALAssetBlocklist); +protected: + /*virtual*/ ~ALAssetBlocklist(); + + void load(); + void save() const; + +public: + using entry_list_t = boost::unordered_map; + using change_signal_t = boost::signals2::signal; + + const entry_list_t& getEntries() const { return mEntries; } + + void addEntry(const LLUUID& asset_id, const LLUUID& avatar_id, const std::string& region, LLAssetType::EType type, bool persist = true); + void removeEntry(const LLUUID& asset_id); + void removeEntries(const uuid_vec_t& asset_ids); + + bool isBlocked(const LLUUID& asset_id); + + boost::signals2::connection setChangeCallback(const change_signal_t::slot_type& cb) { return mChangedSignal.connect(cb); } + +protected: + entry_list_t mEntries; + change_signal_t mChangedSignal; +}; + +// ============================================================================ + +#endif // LL_ASSETBLOCK_H diff --git a/indra/newview/alfloaterexploresounds.cpp b/indra/newview/alfloaterexploresounds.cpp index 2b03f2bbb2..d28dcef12e 100644 --- a/indra/newview/alfloaterexploresounds.cpp +++ b/indra/newview/alfloaterexploresounds.cpp @@ -5,6 +5,9 @@ #include "llviewerprecompiledheaders.h" #include "alfloaterexploresounds.h" + +#include "alassetblocklist.h" +#include "llfloaterblocked.h" #include "llcheckboxctrl.h" #include "llscrolllistctrl.h" #include "llagent.h" @@ -73,7 +76,7 @@ BOOL ALFloaterExploreSounds::postBuild() getChild("play_locally_btn")->setClickedCallback(boost::bind(&ALFloaterExploreSounds::handlePlayLocally, this)); getChild("look_at_btn")->setClickedCallback(boost::bind(&ALFloaterExploreSounds::handleLookAt, this)); getChild("stop_btn")->setClickedCallback(boost::bind(&ALFloaterExploreSounds::handleStop, this)); - getChild("bl_btn")->setClickedCallback(boost::bind(&ALFloaterExploreSounds::blacklistSound, this)); + getChild("block_btn")->setClickedCallback(boost::bind(&ALFloaterExploreSounds::blacklistSound, this)); mStopLocalButton = getChild("stop_locally_btn"); mStopLocalButton->setClickedCallback(boost::bind(&ALFloaterExploreSounds::handleStopLocally, this)); @@ -99,7 +102,7 @@ void ALFloaterExploreSounds::handleSelection() childSetEnabled("look_at_btn", (num_selected && !multiple)); childSetEnabled("play_locally_btn", num_selected); childSetEnabled("stop_btn", num_selected); - childSetEnabled("bl_btn", num_selected); + childSetEnabled("block_btn", num_selected); } LLSoundHistoryItem ALFloaterExploreSounds::getItem(const LLUUID& itemID) @@ -497,36 +500,24 @@ void ALFloaterExploreSounds::blacklistSound() continue; } - std::string region_name; + std::string location = "Unknown"; LLViewerRegion* cur_region = gAgent.getRegion(); if (cur_region) { - region_name = cur_region->getName(); + location = cur_region->getName(); + //if(!item.mPosition.isNull()) + //{ + // LLVector3 cur_pos(item.mPosition - cur_region->getOriginGlobal()); + // location = fmt::format(FMT_STRING("{:s} ({:d}, {:d}, {:d})"), cur_region->getName(), ll_round(cur_pos.mV[VX]), ll_round(cur_pos.mV[VY]), ll_round(cur_pos.mV[VZ])); + //} + //else + //{ + // location = cur_region->getName(); + //} } - blacklist_avatar_name_cache_connection_map_t::iterator it = mBlacklistAvatarNameCacheConnections.find(item.mOwnerID); - if (it != mBlacklistAvatarNameCacheConnections.end()) - { - if (it->second.connected()) - { - it->second.disconnect(); - } - mBlacklistAvatarNameCacheConnections.erase(it); - } - LLAvatarNameCache::callback_connection_t cb = LLAvatarNameCache::get(item.mOwnerID, boost::bind(&ALFloaterExploreSounds::onBlacklistAvatarNameCacheCallback, this, _1, _2, item.mAssetID, region_name)); - mBlacklistAvatarNameCacheConnections.insert(std::make_pair(item.mOwnerID, cb)); + ALAssetBlocklist::instance().addEntry(item.mAssetID, item.mOwnerID, location, LLAssetType::AT_SOUND); } -} -void ALFloaterExploreSounds::onBlacklistAvatarNameCacheCallback(const LLUUID& av_id, const LLAvatarName& av_name, const LLUUID& asset_id, const std::string& region_name) -{ - blacklist_avatar_name_cache_connection_map_t::iterator it = mBlacklistAvatarNameCacheConnections.find(av_id); - if (it != mBlacklistAvatarNameCacheConnections.end()) - { - if (it->second.connected()) - { - it->second.disconnect(); - } - mBlacklistAvatarNameCacheConnections.erase(it); - } + handleStop(); } diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index aff409793f..ef68045cf1 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -1212,6 +1212,17 @@ Value 0 + BlockAssetSortOrder + + Comment + Specifies sort order for asset list + Persist + 1 + Type + U32 + Value + 0 + BlockRenderingSortOrder Comment diff --git a/indra/newview/llfloaterblocked.cpp b/indra/newview/llfloaterblocked.cpp index 4b06b38501..dc4190c276 100644 --- a/indra/newview/llfloaterblocked.cpp +++ b/indra/newview/llfloaterblocked.cpp @@ -16,6 +16,7 @@ #include "llviewerprecompiledheaders.h" +#include "alassetblocklist.h" #include "llavatarname.h" #include "llavatarnamecache.h" #include "llcallbacklist.h" @@ -45,9 +46,11 @@ const std::string BLOCKED_PARAM_NAME = "blocked_to_select"; const std::string DERENDER_PARAM_NAME = "derender_to_select"; +const std::string ASSET_PARAM_NAME = "asset_to_select"; const std::string EXCEPTION_PARAM_NAME = "exception_to_select"; const std::string BLOCKED_TAB_NAME = "mute_tab"; const std::string DERENDER_TAB_NAME = "derender_tab"; +const std::string ASSET_TAB_NAME = "asset_tab"; const std::string EXCEPTION_TAB_NAME = "avatar_rendering_tab"; // ============================================================================ @@ -428,13 +431,130 @@ void LLPanelDerenderList::refresh() auto pObjEntry = static_cast(pEntry.get()); sdColumns[1]["value"] = fmt::format(FMT_STRING("{} <{}, {}, {}>"), pObjEntry->strRegionName, ll_round(pObjEntry->posRegion.mV[VX]), ll_round(pObjEntry->posRegion.mV[VY]), ll_round(pObjEntry->posRegion.mV[VZ])); } - sdColumns[2]["value"] = (pEntry->isPersistent()) ? "Permanent" : "Temporary"; + sdColumns[2]["value"] = (pEntry->isPersistent()) ? LLTrans::getString("Permanent") : LLTrans::getString("Temporary"); m_pDerenderList->addElement(sdRow, ADD_BOTTOM); } } } +// ============================================================================ +// LLPanelAssetBlocklist +// + +static LLPanelInjector t_panel_asset_list("panel_asset_block_list"); + +LLPanelAssetBlocklist::LLPanelAssetBlocklist() + : LLPanel() +{ +} + +LLPanelAssetBlocklist::~LLPanelAssetBlocklist() +{ + mAssetBlocklistChangeConn.disconnect(); +} + +BOOL LLPanelAssetBlocklist::postBuild() +{ + mAssetBlocklist = findChild("asset_list"); + mAssetBlocklist->setCommitCallback(boost::bind(&LLPanelAssetBlocklist::onSelectionChange, this)); + mAssetBlocklist->setCommitOnDelete(true); + mAssetBlocklist->setCommitOnSelectionChange(true); + + // Restore last sort order + U32 nSortValue = gSavedSettings.getU32("BlockAssetSortOrder"); + if (nSortValue) + { + mAssetBlocklist->sortByColumnIndex(nSortValue >> 4, nSortValue & 0xF); + } + mAssetBlocklist->setSortChangedCallback(boost::bind(&LLPanelAssetBlocklist::onColumnSortChange, this)); + + mAssetBlocklistChangeConn = ALAssetBlocklist::instance().setChangeCallback(boost::bind(&LLPanelAssetBlocklist::refresh, this)); + findChild("asset_trash_btn")->setCommitCallback(boost::bind(&LLPanelAssetBlocklist::onSelectionRemove, this)); + + return TRUE; +} + +void LLPanelAssetBlocklist::onOpen(const LLSD& sdParam) +{ + refresh(); + + if ((sdParam.has(ASSET_PARAM_NAME)) && (sdParam[ASSET_PARAM_NAME].asUUID().notNull())) + { + mAssetBlocklist->selectByID(sdParam[ASSET_PARAM_NAME].asUUID()); + } +} + +void LLPanelAssetBlocklist::onColumnSortChange() +{ + U32 nSortValue = 0; + + S32 idxColumn = mAssetBlocklist->getSortColumnIndex(); + if (-1 != idxColumn) + { + nSortValue = idxColumn << 4 | ((mAssetBlocklist->getSortAscending()) ? 1 : 0); + } + + gSavedSettings.setU32("BlockAssetSortOrder", nSortValue); +} + +void LLPanelAssetBlocklist::onSelectionChange() +{ + bool hasSelected = (NULL != mAssetBlocklist->getFirstSelected()); + getChildView("asset_trash_btn")->setEnabled(hasSelected); +} + +void LLPanelAssetBlocklist::onSelectionRemove() +{ + uuid_vec_t ids; + std::vector selItems = mAssetBlocklist->getAllSelected(); + for (LLScrollListItem* itemp : selItems) + { + ids.push_back(itemp->getValue().asUUID()); + } + + ALAssetBlocklist::instance().removeEntries(ids); +} + +void LLPanelAssetBlocklist::refresh() +{ + mAssetBlocklist->clearRows(); + if (ALAssetBlocklist::instanceExists()) + { + LLSD sdRow; LLSD& sdColumns = sdRow["columns"]; + sdColumns[0]["column"] = "name"; sdColumns[0]["type"] = "text"; + sdColumns[1]["column"] = "location"; sdColumns[1]["type"] = "text"; + sdColumns[2]["column"] = "asset_type"; sdColumns[2]["type"] = "text"; + sdColumns[3]["column"] = "date"; sdColumns[3]["type"] = "text"; + sdColumns[4]["column"] = "persist"; sdColumns[4]["type"] = "text"; + + for (const auto& [key, data] : ALAssetBlocklist::instance().getEntries()) + { + sdRow["value"] = key; + + std::string owner_name = "Unknown"; + LLAvatarName avName; + if (LLAvatarNameCache::get(data.mOwnerID, &avName)) + { + owner_name = avName.getUserName(); + } + sdColumns[0]["value"] = owner_name; + sdColumns[1]["value"] = data.mLocation; + sdColumns[2]["value"] = LLTrans::getString(LLAssetType::lookupHumanReadable(data.mAssetType)); + + std::string timeStr = getString("blockedDate"); + LLSD substitution; + substitution["datetime"] = (S32)data.mDate.secondsSinceEpoch(); + LLStringUtil::format(timeStr, substitution); + + sdColumns[3]["value"] = timeStr; + sdColumns[4]["value"] = data.mPersist ? LLTrans::getString("Permanent") : LLTrans::getString("Temporary"); + + mAssetBlocklist->addElement(sdRow, ADD_BOTTOM); + } + } +} + // ============================================================================ // LLPanelAvatarRendering - Menu helper class // @@ -745,6 +865,8 @@ void LLFloaterBlocked::onOpen(const LLSD& sdParam) m_pBlockedTabs->selectTabByName(BLOCKED_TAB_NAME); else if (sdParam.has(DERENDER_PARAM_NAME)) m_pBlockedTabs->selectTabByName(DERENDER_TAB_NAME); + else if (sdParam.has(ASSET_PARAM_NAME)) + m_pBlockedTabs->selectTabByName(ASSET_TAB_NAME); if (sdParam.has(EXCEPTION_PARAM_NAME)) m_pBlockedTabs->selectTabByName(EXCEPTION_TAB_NAME); else if ( (sdParam.isString()) && (m_pBlockedTabs->hasChild(sdParam.asString())) ) @@ -783,6 +905,11 @@ void LLFloaterBlocked::showDerenderAndSelect(const LLUUID& idEntry) LLFloaterReg::showInstance("blocked", LLSD().with(DERENDER_PARAM_NAME, idEntry)); } +void LLFloaterBlocked::showAssetAndSelect(const LLUUID& idEntry) +{ + LLFloaterReg::showInstance("blocked", LLSD().with(ASSET_PARAM_NAME, idEntry)); +} + void LLFloaterBlocked::showRenderExceptionAndSelect(const LLUUID& idEntry) { LLFloaterReg::showInstance("blocked", LLSD().with(EXCEPTION_PARAM_NAME, idEntry)); diff --git a/indra/newview/llfloaterblocked.h b/indra/newview/llfloaterblocked.h index dbc1618892..b881457d5a 100644 --- a/indra/newview/llfloaterblocked.h +++ b/indra/newview/llfloaterblocked.h @@ -145,6 +145,45 @@ class LLPanelDerenderList final : public LLPanel boost::signals2::connection m_DerenderChangeConn; }; +// ============================================================================ +// LLPanelAssetBlocklist +// + +class LLPanelAssetBlocklist final : public LLPanel +{ +public: + LLPanelAssetBlocklist(); + ~LLPanelAssetBlocklist(); + + /* + * LLPanel overrides + */ +public: + BOOL postBuild() override; + void onOpen(const LLSD& sdParam) override; + + /* + * Member functions + */ +protected: + void refresh() override; + + /* + * Event handlers + */ +protected: + void onColumnSortChange(); + void onSelectionChange(); + void onSelectionRemove(); + + /* + * Member variables + */ +protected: + LLScrollListCtrl* mAssetBlocklist = nullptr; + boost::signals2::connection mAssetBlocklistChangeConn; +}; + // ============================================================================ // LLPanelAvatarRendering - Configure avatar complexity excpetions // @@ -232,6 +271,7 @@ class LLFloaterBlocked final : public LLFloater public: static void showMuteAndSelect(const LLUUID& idMute); static void showDerenderAndSelect(const LLUUID& idEntry); + static void showAssetAndSelect(const LLUUID& idEntry); static void showRenderExceptionAndSelect(const LLUUID& idEntry); /* diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 706affaf0a..0f4512c7a5 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -51,6 +51,7 @@ #include "llxfermanager.h" #include "mean_collision_data.h" +#include "alassetblocklist.h" #include "llagent.h" #include "llagentbenefits.h" #include "llagentcamera.h" @@ -4253,6 +4254,9 @@ void process_sound_trigger(LLMessageSystem *msg, void **) if (gAudiop && gAudiop->isCorruptSound(sound_id)) return; + if (ALAssetBlocklist::instance().isBlocked(sound_id)) + return; + msg->getUUIDFast(_PREHASH_SoundData, _PREHASH_OwnerID, owner_id); msg->getUUIDFast(_PREHASH_SoundData, _PREHASH_ObjectID, object_id); @@ -4327,6 +4331,9 @@ void process_preload_sound(LLMessageSystem *msg, void **user_data) if (gAudiop->isCorruptSound(sound_id)) return; + if (ALAssetBlocklist::instance().isBlocked(sound_id)) + return; + msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_ObjectID, object_id); msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_OwnerID, owner_id); @@ -4366,6 +4373,9 @@ void process_attached_sound(LLMessageSystem *msg, void **user_data) if (gAudiop && gAudiop->isCorruptSound(sound_id)) return; + if (ALAssetBlocklist::instance().isBlocked(sound_id)) + return; + msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_ObjectID, object_id); msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_OwnerID, owner_id); msg->getF32Fast(_PREHASH_DataBlock, _PREHASH_Gain, gain); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 2d74607625..286c88c277 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -53,6 +53,7 @@ #include "message.h" #include "object_flags.h" +#include "alassetblocklist.h" #include "llaudiosourcevo.h" #include "llagent.h" #include "llagentcamera.h" @@ -6396,6 +6397,10 @@ void LLViewerObject::setAttachedSound(const LLUUID &audio_uuid, const LLUUID& ow } return; } + + if (gAudiop->isCorruptSound(audio_uuid) || ALAssetBlocklist::instance().isBlocked(audio_uuid)) + return; + if (flags & LL_SOUND_FLAG_LOOP && mAudioSourcep && mAudioSourcep->isLoop() && mAudioSourcep->getCurrentData() && mAudioSourcep->getCurrentData()->getID() == audio_uuid) diff --git a/indra/newview/skins/default/xui/en/floater_blocked.xml b/indra/newview/skins/default/xui/en/floater_blocked.xml index 5033927fde..8798ed60ed 100644 --- a/indra/newview/skins/default/xui/en/floater_blocked.xml +++ b/indra/newview/skins/default/xui/en/floater_blocked.xml @@ -14,7 +14,7 @@ save_visibility="false" single_instance="true" title="BLOCKED / DERENDER LIST" - width="350"> + width="500"> + diff --git a/indra/newview/skins/default/xui/en/floater_explore_sounds.xml b/indra/newview/skins/default/xui/en/floater_explore_sounds.xml index 9b3655a4b3..092672a4aa 100644 --- a/indra/newview/skins/default/xui/en/floater_explore_sounds.xml +++ b/indra/newview/skins/default/xui/en/floater_explore_sounds.xml @@ -51,5 +51,5 @@