Skip to content

Commit

Permalink
Add asset blocklist for sounds
Browse files Browse the repository at this point in the history
  • Loading branch information
RyeMutt committed May 11, 2024
1 parent 4c9252a commit 66100c4
Show file tree
Hide file tree
Showing 13 changed files with 603 additions and 33 deletions.
2 changes: 2 additions & 0 deletions indra/newview/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ set(viewer_SOURCE_FILES
ao.cpp
aoengine.cpp
aoset.cpp
alassetblocklist.cpp
alavataractions.cpp
alavatargroups.cpp
alchatcommand.cpp
Expand Down Expand Up @@ -832,6 +833,7 @@ set(viewer_HEADER_FILES
ao.h
aoengine.h
aoset.h
alassetblocklist.h
alavataractions.h
alavatargroups.h
alchatcommand.h
Expand Down
205 changes: 205 additions & 0 deletions indra/newview/alassetblocklist.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
/**
* @file alassetblocklist.h
* @brief
*
* $LicenseInfo:firstyear=2024&license=viewerlgpl$
* Alchemy Viewer Source Code
* Copyright (C) 2024, Rye Mutt <[email protected]>
*
* 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);
}

// ============================================================================
87 changes: 87 additions & 0 deletions indra/newview/alassetblocklist.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/**
* @file alassetblocklist.h
* @brief
*
* $LicenseInfo:firstyear=2024&license=viewerlgpl$
* Alchemy Viewer Source Code
* Copyright (C) 2024, Rye Mutt <[email protected]>
*
* 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<ALAssetBlocklist>
{
LLSINGLETON(ALAssetBlocklist);
protected:
/*virtual*/ ~ALAssetBlocklist();

void load();
void save() const;

public:
using entry_list_t = boost::unordered_map<LLUUID, ALBlockedAsset>;
using change_signal_t = boost::signals2::signal<void()>;

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
45 changes: 18 additions & 27 deletions indra/newview/alfloaterexploresounds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -73,7 +76,7 @@ BOOL ALFloaterExploreSounds::postBuild()
getChild<LLButton>("play_locally_btn")->setClickedCallback(boost::bind(&ALFloaterExploreSounds::handlePlayLocally, this));
getChild<LLButton>("look_at_btn")->setClickedCallback(boost::bind(&ALFloaterExploreSounds::handleLookAt, this));
getChild<LLButton>("stop_btn")->setClickedCallback(boost::bind(&ALFloaterExploreSounds::handleStop, this));
getChild<LLButton>("bl_btn")->setClickedCallback(boost::bind(&ALFloaterExploreSounds::blacklistSound, this));
getChild<LLButton>("block_btn")->setClickedCallback(boost::bind(&ALFloaterExploreSounds::blacklistSound, this));

mStopLocalButton = getChild<LLButton>("stop_locally_btn");
mStopLocalButton->setClickedCallback(boost::bind(&ALFloaterExploreSounds::handleStopLocally, this));
Expand All @@ -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)
Expand Down Expand Up @@ -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();
}
Loading

0 comments on commit 66100c4

Please sign in to comment.