From 703ad01c8b4b59c0059eb0b13df12db1c7a626ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Liru=20F=C3=A6rs?= Date: Sun, 9 Feb 2020 19:28:35 -0500 Subject: [PATCH] AntiSpam refactor! Adds SLURLs to antispam notifications Reduces weight of antispam to either global queue, multiple queues, or none Renames variables to make more sense Repositions code, cleans up code, uses modern C++, etc This fixes a bit of a leak or two, especially with antispam turned off! Also fixes the endless leak of queue expansion by cleaning up while idle When changing between global and individual queues, they're now purged. Also made some improvements to previous commit, woops. Also fix wrong logic for is_linden and chat source type for objects --- indra/newview/NACLantispam.cpp | 625 +++++++----------- indra/newview/NACLantispam.h | 103 +-- indra/newview/ascentprefschat.cpp | 5 +- indra/newview/llagent.cpp | 2 +- indra/newview/llappviewer.cpp | 2 + indra/newview/llstartup.cpp | 21 +- indra/newview/llviewermenu.cpp | 31 +- indra/newview/llviewermessage.cpp | 203 +++--- .../skins/default/xui/en-us/notifications.xml | 2 +- 9 files changed, 403 insertions(+), 591 deletions(-) diff --git a/indra/newview/NACLantispam.cpp b/indra/newview/NACLantispam.cpp index dfeb7a5c9..ba51b6515 100644 --- a/indra/newview/NACLantispam.cpp +++ b/indra/newview/NACLantispam.cpp @@ -14,457 +14,300 @@ */ #include "llviewerprecompiledheaders.h" + #include "NACLantispam.h" -#include "llviewercontrol.h" -#include "llnotificationsutil.h" -#include "llviewerobjectlist.h" #include "llagent.h" +#include "llavataractions.h" +#include "llcallbacklist.h" // For idle cleaning +#include "llnotificationsutil.h" #include "lltrans.h" +#include "llviewerobjectlist.h" + #include #include +class NACLAntiSpamQueue +{ + friend class NACLAntiSpamRegistry; +public: + const U32& getAmount() const { return mAmount; } + const U32& getTime() const { return mTime; } +protected: + NACLAntiSpamQueue(const U32& time, const U32& amount) : mTime(time), mAmount(amount) {} + void setAmount(const U32& amount) { mAmount = amount; } + void setTime(const U32& time) { mTime = time; } + void block(const LLUUID& source) { mEntries[source.asString()].block(); } + void reset() { mEntries.clear(); } + // Returns 0 if unblocked/disabled, 1 if check results in a new block, 2 if by an existing block + U8 check(const LLUUID& source, const U32& multiplier) + { + const auto key = source.asString(); + auto it = mEntries.find(key); + if (it != mEntries.end()) + return it->second.blockIfNeeded(mAmount * multiplier, mTime); + mEntries[key]; // Default construct an Entry + return 0U; + } + void idle() + { + // Clean out old unblocked entries + const auto time_limit = mTime + 1; // One second after time has gone up, the next offense would reset anyway + for (auto it = mEntries.begin(); it != mEntries.end();) + { + const auto& entry = it->second; + if (entry.getBlocked() || entry.withinBlockTime(time_limit)) + ++it; + else it = mEntries.erase(it); + } + } + +private: + class Entry + { + friend class NACLAntiSpamQueue; + protected: + void reset() { updateTime(); mAmount = 1; mBlocked = false; } + const U32& getAmount() const { return mAmount; } + const U32& getTime() const { return mTime; } + void updateTime() { mTime = time(nullptr); } + void block() { mBlocked = true; } + bool withinBlockTime(const U32& time_limit) const { return (time(nullptr) - mTime) <= time_limit; } + U8 blockIfNeeded(const U32& amount, const U32& time_limit) + { + if (mBlocked) return 2U; // Already blocked + if (withinBlockTime(time_limit)) + { + if (++mAmount > amount) + { + block(); + return 1U; + } + } + else reset(); // Enough time has passed to forgive or not already in list + return 0U; + } + bool getBlocked() const { return mBlocked; } + private: + U32 mAmount = 1; + std::time_t mTime = time(nullptr); + bool mBlocked = false; + }; + boost::unordered_map mEntries; + U32 mAmount, mTime; +}; + bool can_block(const LLUUID& id) { - if (id.isNull() || gAgent.getID() == id) return false; //Can't block system or self. - if (const LLViewerObject* obj = gObjectList.findObject(id)) //From an object, - return !obj->permYouOwner(); //not own object. + if (id.isNull() || gAgentID == id) return false; // Can't block system or self. + if (const LLViewerObject* obj = gObjectList.findObject(id)) // From an object, + return !obj->permYouOwner(); // not own object. return true; } -U32 NACLAntiSpamRegistry::globalAmount; -U32 NACLAntiSpamRegistry::globalTime; -bool NACLAntiSpamRegistry::bGlobalQueue; -NACLAntiSpamQueue* NACLAntiSpamRegistry::queues[NACLAntiSpamRegistry::QUEUE_MAX] = {0}; -boost::unordered_map NACLAntiSpamRegistry::globalEntries; -boost::unordered_map::iterator NACLAntiSpamRegistry::it2; +bool is_collision_sound(const std::string& sound) +{ + // The following sounds will be ignored for purposes of spam protection. They have been gathered from wiki documentation of frequent official sounds. + const std::array COLLISION_SOUNDS = { + "dce5fdd4-afe4-4ea1-822f-dd52cac46b08", + "51011582-fbca-4580-ae9e-1a5593f094ec", + "68d62208-e257-4d0c-bbe2-20c9ea9760bb", + "75872e8c-bc39-451b-9b0b-042d7ba36cba", + "6a45ba0b-5775-4ea8-8513-26008a17f873", + "992a6d1b-8c77-40e0-9495-4098ce539694", + "2de4da5a-faf8-46be-bac6-c4d74f1e5767", + "6e3fb0f7-6d9c-42ca-b86b-1122ff562d7d", + "14209133-4961-4acc-9649-53fc38ee1667", + "bc4a4348-cfcc-4e5e-908e-8a52a8915fe6", + "9e5c1297-6eed-40c0-825a-d9bcd86e3193", + "e534761c-1894-4b61-b20c-658a6fb68157", + "8761f73f-6cf9-4186-8aaa-0948ed002db1", + "874a26fd-142f-4173-8c5b-890cd846c74d", + "0e24a717-b97e-4b77-9c94-b59a5a88b2da", + "75cf3ade-9a5b-4c4d-bb35-f9799bda7fb2", + "153c8bf7-fb89-4d89-b263-47e58b1b4774", + "55c3e0ce-275a-46fa-82ff-e0465f5e8703", + "24babf58-7156-4841-9a3f-761bdbb8e237", + "aca261d8-e145-4610-9e20-9eff990f2c12", + "0642fba6-5dcf-4d62-8e7b-94dbb529d117", + "25a863e8-dc42-4e8a-a357-e76422ace9b5", + "9538f37c-456e-4047-81be-6435045608d4", + "8c0f84c3-9afd-4396-b5f5-9bca2c911c20", + "be582e5d-b123-41a2-a150-454c39e961c8", + "c70141d4-ba06-41ea-bcbc-35ea81cb8335", + "7d1826f4-24c4-4aac-8c2e-eff45df37783", + "063c97d3-033a-4e9b-98d8-05c8074922cb", + "00000000-0000-0000-0000-000000000120" + }; -// The following sounds will be ignored for purposes of spam protection. They have been gathered from wiki documentation of frequent official sounds. -const std::string COLLISION_SOUNDS[] ={"dce5fdd4-afe4-4ea1-822f-dd52cac46b08","51011582-fbca-4580-ae9e-1a5593f094ec","68d62208-e257-4d0c-bbe2-20c9ea9760bb","75872e8c-bc39-451b-9b0b-042d7ba36cba","6a45ba0b-5775-4ea8-8513-26008a17f873","992a6d1b-8c77-40e0-9495-4098ce539694","2de4da5a-faf8-46be-bac6-c4d74f1e5767","6e3fb0f7-6d9c-42ca-b86b-1122ff562d7d","14209133-4961-4acc-9649-53fc38ee1667","bc4a4348-cfcc-4e5e-908e-8a52a8915fe6","9e5c1297-6eed-40c0-825a-d9bcd86e3193","e534761c-1894-4b61-b20c-658a6fb68157","8761f73f-6cf9-4186-8aaa-0948ed002db1","874a26fd-142f-4173-8c5b-890cd846c74d","0e24a717-b97e-4b77-9c94-b59a5a88b2da","75cf3ade-9a5b-4c4d-bb35-f9799bda7fb2","153c8bf7-fb89-4d89-b263-47e58b1b4774","55c3e0ce-275a-46fa-82ff-e0465f5e8703","24babf58-7156-4841-9a3f-761bdbb8e237","aca261d8-e145-4610-9e20-9eff990f2c12","0642fba6-5dcf-4d62-8e7b-94dbb529d117","25a863e8-dc42-4e8a-a357-e76422ace9b5","9538f37c-456e-4047-81be-6435045608d4","8c0f84c3-9afd-4396-b5f5-9bca2c911c20","be582e5d-b123-41a2-a150-454c39e961c8","c70141d4-ba06-41ea-bcbc-35ea81cb8335","7d1826f4-24c4-4aac-8c2e-eff45df37783","063c97d3-033a-4e9b-98d8-05c8074922cb","00000000-0000-0000-0000-000000000120"}; -const int COLLISION_SOUNDS_SIZE=29; - -// NaClAntiSpamQueueEntry - -NACLAntiSpamQueueEntry::NACLAntiSpamQueueEntry() -{ - entryTime=0; - entryAmount=0; - blocked=false; + for (const auto& collision : COLLISION_SOUNDS) + if (collision == sound) + return true; + return false; } -void NACLAntiSpamQueueEntry::clearEntry() -{ - entryTime=0; - entryAmount=0; - blocked=false; -} -U32 NACLAntiSpamQueueEntry::getEntryAmount() const -{ - return entryAmount; -} -U32 NACLAntiSpamQueueEntry::getEntryTime() const -{ - return entryTime; -} -void NACLAntiSpamQueueEntry::updateEntryAmount() -{ - entryAmount++; -} -void NACLAntiSpamQueueEntry::updateEntryTime() -{ - entryTime=time(0); -} -void NACLAntiSpamQueueEntry::setBlocked() -{ - blocked=true; -} -bool NACLAntiSpamQueueEntry::getBlocked() const -{ - return blocked; -} - -// NaClAntiSpamQueue - -NACLAntiSpamQueue::NACLAntiSpamQueue(U32 time, U32 amount) -{ - queueTime=time; - queueAmount=amount; -} -void NACLAntiSpamQueue::setAmount(U32 amount) -{ - queueAmount=amount; -} -void NACLAntiSpamQueue::setTime(U32 time) -{ - queueTime=time; -} -U32 NACLAntiSpamQueue::getAmount() const -{ - return queueAmount; -} -U32 NACLAntiSpamQueue::getTime() const -{ - return queueTime; -} -void NACLAntiSpamQueue::clearEntries() -{ - for(it = entries.begin(); it != entries.end(); it++) - { - it->second->clearEntry(); - } -} -void NACLAntiSpamQueue::purgeEntries() -{ - for(it = entries.begin(); it != entries.end(); it++) - { - delete it->second; - } - entries.clear(); -} -void NACLAntiSpamQueue::blockEntry(LLUUID& source) -{ - it=entries.find(source.asString()); - if(it == entries.end()) - { - entries[source.asString()]=new NACLAntiSpamQueueEntry(); - } - entries[source.asString()]->setBlocked(); -} -int NACLAntiSpamQueue::checkEntry(LLUUID& name, U32 multiplier) -// Returns 0 if unblocked/disabled, 1 if check results in a new block, 2 if by an existing block -{ - static LLCachedControl enabled(gSavedSettings,"AntiSpamEnabled",false); - if(!enabled) return 0; - it=entries.find(name.asString()); - if(it != entries.end()) - { - if(it->second->getBlocked()) return 2; - U32 eTime=it->second->getEntryTime(); - U32 currentTime=time(0); - if((currentTime-eTime) <= queueTime) - { - it->second->updateEntryAmount(); - U32 eAmount=it->second->getEntryAmount(); - if(eAmount > (queueAmount*multiplier)) - { - it->second->setBlocked(); - return 1; - } - else - return 0; - } - else - { - it->second->clearEntry(); - it->second->updateEntryAmount(); - it->second->updateEntryTime(); - return 0; - } - } - else - { - //LL_DEBUGS() << "[antispam] New queue entry:" << name.asString() << LL_ENDL; - entries[name.asString()]=new NACLAntiSpamQueueEntry(); - entries[name.asString()]->updateEntryAmount(); - entries[name.asString()]->updateEntryTime(); - return 0; - } -} - // NaClAntiSpamRegistry -static const char* QUEUE_NAME[NACLAntiSpamRegistry::QUEUE_MAX] = { -"Chat", -"Inventory", -"Instant Message", -"calling card", -"sound", -"Sound Preload", -"Script Dialog", -"Teleport"}; +constexpr std::array QUEUE_NAME = { + "Chat", + "Inventory", + "Instant Message", + "calling card", + "sound", + "Sound Preload", + "Script Dialog", + "Teleport" +}; -NACLAntiSpamRegistry::NACLAntiSpamRegistry(U32 time, U32 amount) +NACLAntiSpamRegistry::NACLAntiSpamRegistry() { - globalTime=time; - globalAmount=amount; - static LLCachedControl _NACL_AntiSpamGlobalQueue(gSavedSettings,"_NACL_AntiSpamGlobalQueue"); - bGlobalQueue=_NACL_AntiSpamGlobalQueue; - for(int queue = 0; queue < QUEUE_MAX; ++queue) + auto control = gSavedSettings.getControl("_NACL_AntiSpamTime"); + const U32 time = control->get().asInteger(); + mConnections[0] = control->getSignal()->connect(boost::bind(&NACLAntiSpamRegistry::handleNaclAntiSpamTimeChanged, _2)); + + control = gSavedSettings.getControl("_NACL_AntiSpamAmount"); + const U32 amount = control->get().asInteger(); + mConnections[1] = control->getSignal()->connect(boost::bind(&NACLAntiSpamRegistry::handleNaclAntiSpamAmountChanged, _2)); + + control = gSavedSettings.getControl("_NACL_AntiSpamGlobalQueue"); + mConnections[2] = control->getSignal()->connect(boost::bind(&NACLAntiSpamRegistry::handleNaclAntiSpamGlobalQueueChanged, _2)); + initializeQueues(control->get(), time, amount); +} + +void NACLAntiSpamRegistry::initializeQueues(bool global, const U32& time, const U32& amount) +{ + if (global) // If Global, initialize global queue + mGlobalQueue.reset(new NACLAntiSpamQueue(time, amount)); + else { - queues[queue] = new NACLAntiSpamQueue(time,amount); + mQueues.reset(new std::array{ + NACLAntiSpamQueue(time, amount), // QUEUE_CHAT + NACLAntiSpamQueue(time, amount), // QUEUE_INVENTORY + NACLAntiSpamQueue(time, amount), // QUEUE_IM + NACLAntiSpamQueue(time, amount), // QUEUE_CALLING_CARD + NACLAntiSpamQueue(time, amount), // QUEUE_SOUND + NACLAntiSpamQueue(time, amount), // QUEUE_SOUND_PRELOAD + NACLAntiSpamQueue(time, amount), // QUEUE_SCRIPT_DIALOG + NACLAntiSpamQueue(time, amount) // QUEUE_TELEPORT + }); } } -//static -const char* NACLAntiSpamRegistry::getQueueName(U32 queue_id) + +constexpr const char* getQueueName(const NACLAntiSpamRegistry::Type& name) { - if(queue_id >= QUEUE_MAX) - return "Unknown"; - return QUEUE_NAME[queue_id]; + return name >= QUEUE_NAME.size() ? "Unknown" : QUEUE_NAME[name]; } -//static -void NACLAntiSpamRegistry::registerQueues(U32 time, U32 amount) -{ - globalTime=time; - globalAmount=amount; - static LLCachedControl _NACL_AntiSpamGlobalQueue(gSavedSettings,"_NACL_AntiSpamGlobalQueue"); - bGlobalQueue=_NACL_AntiSpamGlobalQueue; - for(int queue = 0; queue < QUEUE_MAX; ++queue) - { - queues[queue] = new NACLAntiSpamQueue(time,amount); - } -} -//static -/*void NACLAntiSpamRegistry::registerQueue(U32 name, U32 time, U32 amount) -{ - it=queues.find(name); - if(it == queues.end()) - { - queues[name]=new NACLAntiSpamQueue(time,amount); - } -}*/ -//static -void NACLAntiSpamRegistry::setRegisteredQueueTime(U32 name, U32 time) -{ - if(name >= QUEUE_MAX || queues[name] == 0) - { - LL_ERRS("AntiSpam") << "CODE BUG: Attempting to set time of antispam queue that was outside of the reasonable range of queues or not created. Queue: " << getQueueName(name) << LL_ENDL; - return; - } - - queues[name]->setTime(time); -} -//static -void NACLAntiSpamRegistry::setRegisteredQueueAmount(U32 name, U32 amount) -{ - if(name >= QUEUE_MAX || queues[name] == 0) - { - LL_ERRS("AntiSpam") << "CODE BUG: Attempting to set amount for antispam queue that was outside of the reasonable range of queues or not created. Queue: " << getQueueName(name) << LL_ENDL; - return; - } - - queues[name]->setAmount(amount); -} -//static + void NACLAntiSpamRegistry::setAllQueueTimes(U32 time) { - globalTime=time; - for(int queue = 0; queue < QUEUE_MAX; ++queue) - if( queues[queue] ) - queues[queue]->setTime(time); + if (mGlobalQueue) mGlobalQueue->setTime(time); + else for(auto& queue : *mQueues) queue.setTime(time); } -//static + void NACLAntiSpamRegistry::setAllQueueAmounts(U32 amount) { - globalAmount=amount; - for(int queue = 0; queue < QUEUE_MAX; ++queue) + if (mGlobalQueue) mGlobalQueue->setAmount(amount); + else for (U8 queue = 0U; queue < QUEUE_MAX; ++queue) { - if(!queues[queue]) continue; - if(queue == QUEUE_SOUND || queue == QUEUE_SOUND_PRELOAD) - queues[queue]->setAmount(amount*5); + auto& q = (*mQueues)[queue]; + if (queue == QUEUE_SOUND || queue == QUEUE_SOUND_PRELOAD) + q.setAmount(amount*5); else - queues[queue]->setAmount(amount); + q.setAmount(amount); } } -//static -void NACLAntiSpamRegistry::clearRegisteredQueue(U32 name) + +void NACLAntiSpamRegistry::blockOnQueue(const Type& name, const LLUUID& source) { - if(name >= QUEUE_MAX || queues[name] == 0) - { - LL_ERRS("AntiSpam") << "CODE BUG: Attempting to clear antispam queue that was outside of the reasonable range of queues or not created. Queue: " << getQueueName(name) << LL_ENDL; - return; - } - - queues[name]->clearEntries(); + if (name >= QUEUE_MAX) + LL_ERRS("AntiSpam") << "CODE BUG: Attempting to use a antispam queue that was outside of the reasonable range of queues. Queue: " << getQueueName(name) << LL_ENDL; + else (mGlobalQueue ? *mGlobalQueue : (*mQueues)[name]).block(source); } -//static -void NACLAntiSpamRegistry::purgeRegisteredQueue(U32 name) -{ - if(name >= QUEUE_MAX || queues[name] == 0) - { - LL_ERRS("AntiSpam") << "CODE BUG: Attempting to purge antispam queue that was outside of the reasonable range of queues or not created. Queue: " << getQueueName(name) << LL_ENDL; - return; - } - - queues[name]->purgeEntries(); -} -//static -void NACLAntiSpamRegistry::blockOnQueue(U32 name, LLUUID& source) -{ - if(bGlobalQueue) - { - NACLAntiSpamRegistry::blockGlobalEntry(source); - } - else - { - if(name >= QUEUE_MAX || queues[name] == 0) - { - LL_ERRS("AntiSpam") << "CODE BUG: Attempting to use a antispam queue that was outside of the reasonable range of queues or not created. Queue: " << getQueueName(name) << LL_ENDL; - return; - } - queues[name]->blockEntry(source); - } -} -//static -void NACLAntiSpamRegistry::blockGlobalEntry(LLUUID& source) -{ - it2=globalEntries.find(source.asString()); - if(it2 == globalEntries.end()) - { - globalEntries[source.asString()]=new NACLAntiSpamQueueEntry(); - } - globalEntries[source.asString()]->setBlocked(); -} -//static -bool NACLAntiSpamRegistry::checkQueue(U32 name, LLUUID& source, U32 multiplier) + +bool NACLAntiSpamRegistry::checkQueue(const Type& name, const LLUUID& source, const LFIDBearer::Type& type, const U32& multiplier) //returns true if blocked { + if (name >= QUEUE_MAX) + { + LL_ERRS("AntiSpam") << "CODE BUG: Attempting to check antispam queue that was outside of the reasonable range of queues. Queue: " << getQueueName(name) << LL_ENDL; + return false; + } + if (!can_block(source)) return false; - int result; - if(bGlobalQueue) + auto& queue = mGlobalQueue ? *mGlobalQueue : (*mQueues)[name]; + const auto result = queue.check(source, multiplier); + if (!result) return false; // Safe + + if (result != 2 // Not previously blocked + && gSavedSettings.getBOOL("AntiSpamNotify")) // and Just blocked! { - result=NACLAntiSpamRegistry::checkGlobalEntry(source,multiplier); - } - else - { - if(name >= QUEUE_MAX || queues[name] == 0) - { - LL_ERRS("AntiSpam") << "CODE BUG: Attempting to check antispam queue that was outside of the reasonable range of queues or not created. Queue: " << getQueueName(name) << LL_ENDL; - return false; - } - result=queues[name]->checkEntry(source,multiplier); - } - if(result == 0) //Safe - return false; - else if(result == 2) //Previously blocked - { - return true; - } - else //Just blocked! - { - if(gSavedSettings.getBOOL("AntiSpamNotify")) - { - LLSD args; - args["SOURCE"] = source.asString().c_str(); - args["TYPE"] = LLTrans::getString(getQueueName(name)); - args["AMOUNT"] = boost::lexical_cast(multiplier * queues[name]->getAmount()); - args["TIME"] = boost::lexical_cast(queues[name]->getTime()); - LLNotificationsUtil::add("AntiSpamBlock", args); - } - return true; + const std::string get_slurl_for(const LLUUID& id, const LFIDBearer::Type& type); + const auto slurl = get_slurl_for(source, type); + LLSD args; + args["SOURCE"] = slurl.empty() ? source.asString() : slurl; + args["TYPE"] = LLTrans::getString(getQueueName(name)); + args["AMOUNT"] = (LLSD::Integer)(multiplier * queue.getAmount()); + args["TIME"] = (LLSD::Integer)queue.getTime(); + LLNotificationsUtil::add("AntiSpamBlock", args); } + return true; } -// Global queue stoof -//static -void NACLAntiSpamRegistry::setGlobalQueue(bool value) +void NACLAntiSpamRegistry::idle() { - NACLAntiSpamRegistry::purgeAllQueues(); - bGlobalQueue=value; + if (mGlobalQueue) mGlobalQueue->idle(); + else for (auto& queue : *mQueues) queue.idle(); } -//static -void NACLAntiSpamRegistry::setGlobalAmount(U32 amount) + +void NACLAntiSpamRegistry::resetQueues() { - globalAmount=amount; + if (mGlobalQueue) mGlobalQueue->reset(); + else for (auto& queue : *mQueues) queue.reset(); + + LL_INFOS() << "AntiSpam Queues Reset" << LL_ENDL; } -//static -void NACLAntiSpamRegistry::setGlobalTime(U32 time) -{ - globalTime=time; -} -//static -void NACLAntiSpamRegistry::clearAllQueues() -{ - if(bGlobalQueue) - NACLAntiSpamRegistry::clearGlobalEntries(); - else - for(int queue = 0; queue < QUEUE_MAX; ++queue) - { - if(queues[queue]) queues[queue]->clearEntries(); - } -} -//static + void NACLAntiSpamRegistry::purgeAllQueues() { - if(bGlobalQueue) - NACLAntiSpamRegistry::purgeGlobalEntries(); + // Note: These resets are upon the unique_ptr, not the Queue itself! + if (mGlobalQueue) + mGlobalQueue.reset(); else - for(int queue = 0; queue < QUEUE_MAX; ++queue) - { - if(queues[queue]) queues[queue]->purgeEntries(); - } - LL_INFOS() << "AntiSpam Queues Purged" << LL_ENDL; -} -//static -int NACLAntiSpamRegistry::checkGlobalEntry(LLUUID& name, U32 multiplier) -{ - static LLCachedControl enabled(gSavedSettings,"AntiSpamEnabled",false); - if(!enabled) return 0; - it2=globalEntries.find(name.asString()); - if(it2 != globalEntries.end()) - { - if(it2->second->getBlocked()) return 2; - U32 eTime=it2->second->getEntryTime(); - U32 currentTime=time(0); - if((currentTime-eTime) <= globalTime) - { - it2->second->updateEntryAmount(); - U32 eAmount=it2->second->getEntryAmount(); - if(eAmount > (globalAmount*multiplier)) - return 1; - else - return 0; - } - else - { - it2->second->clearEntry(); - it2->second->updateEntryAmount(); - it2->second->updateEntryTime(); - return 0; - } - } - else - { - globalEntries[name.asString()]=new NACLAntiSpamQueueEntry(); - globalEntries[name.asString()]->updateEntryAmount(); - globalEntries[name.asString()]->updateEntryTime(); - return 0; - } -} -//static -void NACLAntiSpamRegistry::clearGlobalEntries() -{ - for(it2 = globalEntries.begin(); it2 != globalEntries.end(); it2++) - { - it2->second->clearEntry(); - } -} -//static -void NACLAntiSpamRegistry::purgeGlobalEntries() -{ - for(it2 = globalEntries.begin(); it2 != globalEntries.end(); it2++) - { - delete it2->second; - it2->second = 0; - } - globalEntries.clear(); + mQueues.reset(); } -//Handlers -//static +// Handlers +// static +void NACLAntiSpamRegistry::startup() +{ + auto onAntiSpamToggle = [](const LLControlVariable*, const LLSD& value) { + if (value.asBoolean()) instance(); + else deleteSingleton(); + }; + auto control = gSavedSettings.getControl("AntiSpamEnabled"); + control->getSignal()->connect(onAntiSpamToggle); + onAntiSpamToggle(control, control->get()); +} + +// static bool NACLAntiSpamRegistry::handleNaclAntiSpamGlobalQueueChanged(const LLSD& newvalue) { - setGlobalQueue(newvalue.asBoolean()); + if (instanceExists()) + { + auto& inst = instance(); + inst.purgeAllQueues(); + inst.initializeQueues(newvalue.asBoolean(), gSavedSettings.getU32("_NACL_AntiSpamTime"), gSavedSettings.getU32("_NACL_AntiSpamAmount")); + } return true; } //static bool NACLAntiSpamRegistry::handleNaclAntiSpamTimeChanged(const LLSD& newvalue) { - setAllQueueTimes(newvalue.asInteger()); + if (auto inst = getIfExists()) inst->setAllQueueTimes(newvalue.asInteger()); return true; } //static bool NACLAntiSpamRegistry::handleNaclAntiSpamAmountChanged(const LLSD& newvalue) { - setAllQueueAmounts(newvalue.asInteger()); + if (auto inst = getIfExists()) inst->setAllQueueAmounts(newvalue.asInteger()); return true; -} - +} \ No newline at end of file diff --git a/indra/newview/NACLantispam.h b/indra/newview/NACLantispam.h index 321bbde72..33c6d39d7 100644 --- a/indra/newview/NACLantispam.h +++ b/indra/newview/NACLantispam.h @@ -13,72 +13,22 @@ * 0. You just DO WHAT THE FUCK YOU WANT TO. */ -#ifndef NACLANTISPAM_H -#define NACLANTISPAM_H +#pragma once +#include #include #include "stdtypes.h" +#include "lfidbearer.h" #include "lluuid.h" -class NACLAntiSpamQueueEntry + +class NACLAntiSpamQueue; +class NACLAntiSpamRegistry final : public LLSingleton { - friend class NACLAntiSpamQueue; - friend class NACLAntiSpamRegistry; -protected: - NACLAntiSpamQueueEntry(); - void clearEntry(); - U32 getEntryAmount() const; - U32 getEntryTime() const; - void updateEntryAmount(); - void updateEntryTime(); - bool getBlocked() const; - void setBlocked(); -private: - U32 entryAmount; - U32 entryTime; - bool blocked; -}; -class NACLAntiSpamQueue -{ - friend class NACLAntiSpamRegistry; + friend class LLSingleton; + NACLAntiSpamRegistry(); public: - U32 getAmount() const; - U32 getTime() const; -protected: - NACLAntiSpamQueue(U32 time, U32 amount); - void setAmount(U32 amount); - void setTime(U32 time); - void clearEntries(); - void purgeEntries(); - void blockEntry(LLUUID& source); - int checkEntry(LLUUID& source, U32 multiplier); -private: - boost::unordered_map entries; - boost::unordered_map::iterator it; - U32 queueAmount; - U32 queueTime; -}; -class NACLAntiSpamRegistry -{ -public: - NACLAntiSpamRegistry(U32 time=2, U32 amount=10); - static void registerQueues(U32 time=2, U32 amount=10); -// static void registerQueue(U32 name, U32 time, U32 amount); - static void setRegisteredQueueTime(U32 name, U32 time); - static void setRegisteredQueueAmount(U32 name,U32 amount); - static void setAllQueueTimes(U32 amount); - static void setAllQueueAmounts(U32 time); - static bool checkQueue(U32 name, LLUUID& source, U32 multiplier=1); - static bool handleNaclAntiSpamGlobalQueueChanged(const LLSD& newvalue); - static bool handleNaclAntiSpamTimeChanged(const LLSD& newvalue); - static bool handleNaclAntiSpamAmountChanged(const LLSD& newvalue); - static void clearRegisteredQueue(U32 name); - static void purgeRegisteredQueue(U32 name); - static void clearAllQueues(); - static void purgeAllQueues(); - static void setGlobalQueue(bool value); - static void setGlobalAmount(U32 amount); - static void setGlobalTime(U32 time); - static void blockOnQueue(U32 name,LLUUID& owner_id); - enum { + static void startup(); + + enum Type : U8 { QUEUE_CHAT, QUEUE_INVENTORY, QUEUE_IM, @@ -89,22 +39,19 @@ public: QUEUE_TELEPORT, QUEUE_MAX }; + bool checkQueue(const Type& name, const LLUUID& source, const LFIDBearer::Type& type = LFIDBearer::AVATAR, const U32& multiplier = 1); + void blockOnQueue(const Type& name, const LLUUID& owner_id); + void idle(); + void resetQueues(); private: - static const char* getQueueName(U32 queue_id); - static NACLAntiSpamQueue* queues[QUEUE_MAX]; - static boost::unordered_map globalEntries; - static boost::unordered_map::iterator it2; - static U32 globalTime; - static U32 globalAmount; - static bool bGlobalQueue; - - static int checkGlobalEntry(LLUUID& source, U32 multiplier); - static void clearGlobalEntries(); - static void purgeGlobalEntries(); - static void blockGlobalEntry(LLUUID& source); + void setAllQueueTimes(U32 amount); + void setAllQueueAmounts(U32 time); + void purgeAllQueues(); + void initializeQueues(bool global, const U32& time, const U32& amount); + static bool handleNaclAntiSpamGlobalQueueChanged(const LLSD& newvalue); + static bool handleNaclAntiSpamTimeChanged(const LLSD& newvalue); + static bool handleNaclAntiSpamAmountChanged(const LLSD& newvalue); + std::unique_ptr> mQueues; + std::unique_ptr mGlobalQueue; + std::array mConnections; }; - -extern const std::string COLLISION_SOUNDS[]; -extern const int COLLISION_SOUNDS_SIZE; - -#endif //NACLANTISPAM_H diff --git a/indra/newview/ascentprefschat.cpp b/indra/newview/ascentprefschat.cpp index a32eef090..25d196435 100644 --- a/indra/newview/ascentprefschat.cpp +++ b/indra/newview/ascentprefschat.cpp @@ -70,7 +70,10 @@ LLPrefsAscentChat::LLPrefsAscentChat() } childSetEnabled("reset_antispam", started); - getChild("reset_antispam")->setCommitCallback(boost::bind(NACLAntiSpamRegistry::purgeAllQueues)); + getChild("reset_antispam")->setCommitCallback([](LLUICtrl* ctrl, const LLSD& param) { + if (auto inst = NACLAntiSpamRegistry::getIfExists()) + inst->resetQueues(); + }); getChild("autoreplace")->setCommitCallback(boost::bind(LLFloaterAutoReplaceSettings::showInstance, LLSD())); getChild("KeywordsOn")->setCommitCallback(boost::bind(&LLPrefsAscentChat::onCommitKeywords, this, _1)); diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 2b976907e..99153014d 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -908,7 +908,7 @@ void LLAgent::setRegion(LLViewerRegion *regionp) if (mRegionp) { // NaCl - Antispam Registry - NACLAntiSpamRegistry::purgeAllQueues(); + if (auto antispam = NACLAntiSpamRegistry::getIfExists()) antispam->resetQueues(); // NaCl End // We've changed regions, we're now going to change our agent coordinate frame. diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 89a3b3e9b..6871500f0 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -190,6 +190,7 @@ #include "llviewerthrottle.h" #include "llparcel.h" #include "llviewerassetstats.h" +#include "NACLantispam.h" #include "llmainlooprepeater.h" @@ -4209,6 +4210,7 @@ void LLAppViewer::idle() gIdleCallbacks.callFunctions(); gInventory.idleNotifyObservers(); + if (auto antispam = NACLAntiSpamRegistry::getIfExists()) antispam->idle(); } // Metrics logging (LLViewerAssetStats, etc.) diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index d4d4b1323..750de91bb 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -1088,27 +1088,12 @@ bool idle_startup() } //Get these logs out of my newview root directory, PLEASE. - if (gHippoGridManager->getCurrentGrid()->isSecondLife()) - { - gDirUtilp->setPerAccountChatLogsDir(LLStringUtil::null, - gSavedSettings.getString("FirstName"), gSavedSettings.getString("LastName") ); - } - else - { - gDirUtilp->setPerAccountChatLogsDir(gHippoGridManager->getConnectedGrid()->getGridNick(), - gSavedSettings.getString("FirstName"), gSavedSettings.getString("LastName") ); - } + gDirUtilp->setPerAccountChatLogsDir(gHippoGridManager->getCurrentGrid()->isSecondLife() ? LLStringUtil::null : gHippoGridManager->getConnectedGrid()->getGridNick(), + gSavedSettings.getString("FirstName"), gSavedSettings.getString("LastName")); LLFile::mkdir(gDirUtilp->getChatLogsDir()); LLFile::mkdir(gDirUtilp->getPerAccountChatLogsDir()); - // NaCl - Antispam - U32 antispam_time = gSavedSettings.getU32("_NACL_AntiSpamTime"); - U32 antispam_amount = gSavedSettings.getU32("_NACL_AntiSpamAmount"); - NACLAntiSpamRegistry::registerQueues(antispam_time, antispam_amount); - gSavedSettings.getControl("_NACL_AntiSpamGlobalQueue")->getSignal()->connect(boost::bind(&NACLAntiSpamRegistry::handleNaclAntiSpamGlobalQueueChanged, _2)); - gSavedSettings.getControl("_NACL_AntiSpamTime")->getSignal()->connect(boost::bind(&NACLAntiSpamRegistry::handleNaclAntiSpamTimeChanged, _2)); - gSavedSettings.getControl("_NACL_AntiSpamAmount")->getSignal()->connect(boost::bind(&NACLAntiSpamRegistry::handleNaclAntiSpamAmountChanged, _2)); - // NaCl End + NACLAntiSpamRegistry::startup(); // NaCl - Antispam //good a place as any to create user windlight directories std::string user_windlight_path_name(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight", "")); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 5fba38bc3..affeb8190 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -9083,11 +9083,31 @@ const LLUUID& get_obj_owner(const LLUUID& id, const JCFloaterAreaSearch::ObjectD return LLUUID::null; } -const std::string get_obj_owner_slurl(const LLUUID& obj_id, const std::string& name = LLStringUtil::null) +const std::string get_obj_owner_slurl(const LLUUID& obj_id, const std::string& name = LLStringUtil::null, bool* group_ownedp = nullptr) { - const auto owner = get_obj_owner(obj_id); - if (owner.isNull()) return name; - return LLAvatarActions::getSLURL(obj_id); + bool group_owned; + LLUUID owner; + if (!group_ownedp) + { + if (const auto& obj = gObjectList.findObject(obj_id)) // Viewer Object is more likely to be up to date + { + owner = obj->mOwnerID; + group_owned = obj->flagObjectGroupOwned(); + } + else if (const auto& obj = get_obj_data(obj_id)) // Fall back on Object Data + { + owner = obj->owner_id; + group_owned = owner == obj->group_id; + } + } + else + { + owner = get_obj_owner(obj_id); + group_owned = *group_ownedp; + } + return owner.isNull() ? name + : group_owned ? LLGroupActions::getSLURL(owner) + : LLAvatarActions::getSLURL(owner); } const std::string get_obj_slurl(const LLUUID& id, const std::string& name = LLStringUtil::null) @@ -9100,13 +9120,14 @@ const std::string get_obj_slurl(const LLUUID& id, const std::string& name = LLSt LLSD sdQuery; sdQuery["name"] = !name.empty() ? name : - obj_data ? obj_data->name : LLTrans::getString("unknown_land_type"); + obj_data ? obj_data->name : LLTrans::getString("land_type_unknown"); const auto& owner = get_obj_owner(id, obj_data, obj); if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES) && (owner != gAgentID)) sdQuery["rlv_shownames"] = true; sdQuery["owner"] = owner; + sdQuery["group_owned"] = obj ? obj->flagObjectGroupOwned() : obj_data && obj_data->group_id == owner; if (const auto region = obj ? obj->getRegion() : nullptr) sdQuery["slurl"] = LLSLURL(region->getName(), obj->getPositionAgent()).getLocationString(); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 71d5680d8..b1eeb9653 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -1593,67 +1593,57 @@ bool is_spam_filtered(const EInstantMessage& dialog, bool is_friend, bool is_own case IM_GROUP_NOTICE: case IM_GROUP_NOTICE_REQUESTED: { - static LLCachedControl filter(gSavedSettings, "AntiSpamGroupNotices"); - if (!filter) return false; - break; + static const LLCachedControl filter("AntiSpamGroupNotices"); + return filter; } case IM_GROUP_INVITATION: { - static LLCachedControl filter(gSavedSettings, "AntiSpamGroupInvites"); - if (!filter) return false; - break; + static const LLCachedControl filter("AntiSpamGroupInvites"); + return filter; } case IM_INVENTORY_OFFERED: case IM_TASK_INVENTORY_OFFERED: { - static LLCachedControl filter(gSavedSettings, "AntiSpamItemOffers"); - if (!filter) return false; - break; + static const LLCachedControl filter("AntiSpamItemOffers"); + return filter; } case IM_FROM_TASK_AS_ALERT: { - static LLCachedControl filter(gSavedSettings, "AntiSpamAlerts"); - if (!filter) return false; - break; + static const LLCachedControl filter("AntiSpamAlerts"); + return filter; } case IM_LURE_USER: { - static LLCachedControl filter(gSavedSettings, "AntiSpamTeleports"); - if (!filter) return false; - break; + static const LLCachedControl filter("AntiSpamTeleports"); + return filter; } case IM_TELEPORT_REQUEST: { - static LLCachedControl filter(gSavedSettings, "AntiSpamTeleportRequests"); - if (!filter) return false; - break; + static const LLCachedControl filter("AntiSpamTeleportRequests"); + return filter; } case IM_FRIENDSHIP_OFFERED: { - static LLCachedControl filter(gSavedSettings, "AntiSpamFriendshipOffers"); - if (!filter) return false; - break; + static const LLCachedControl filter("AntiSpamFriendshipOffers"); + return filter; } case IM_COUNT: { // Bit of a hack, we should never get here unless we did this on purpose, though, doesn't matter because we'd do nothing anyway - static LLCachedControl filter(gSavedSettings, "AntiSpamScripts"); - if (!filter) return false; - break; + static const LLCachedControl filter( "AntiSpamScripts"); + return filter; } default: return false; } - - // Last, definitely filter - return true; } void inventory_offer_handler(LLOfferInfo* info, bool is_friend, bool is_owned_by_me) { - static const LLCachedControl no_landmarks(gSavedSettings, "AntiSpamItemOffersLandmarks"); // NaCl - Antispam Registry - if (NACLAntiSpamRegistry::checkQueue((U32)NACLAntiSpamRegistry::QUEUE_INVENTORY,info->mFromID) + static const LLCachedControl no_landmarks("AntiSpamItemOffersLandmarks"); + auto antispam = NACLAntiSpamRegistry::getIfExists(); + if ((antispam && antispam->checkQueue(NACLAntiSpamRegistry::QUEUE_INVENTORY, info->mFromID, info->mFromGroup ? LFIDBearer::GROUP : LFIDBearer::AVATAR)) || (!has_spam_bypass(is_friend, is_owned_by_me) && (no_landmarks && info->mType == LLAssetType::AT_LANDMARK))) { @@ -2125,19 +2115,19 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) msg->getStringFast(_PREHASH_MessageBlock, _PREHASH_FromAgentName, name); msg->getStringFast(_PREHASH_MessageBlock, _PREHASH_Message, message); // NaCl - Newline flood protection - static LLCachedControl AntiSpamEnabled(gSavedSettings,"AntiSpamEnabled",false); - if (AntiSpamEnabled && can_block(from_id)) + auto antispam = NACLAntiSpamRegistry::getIfExists(); + if (antispam && can_block(from_id)) { - static LLCachedControl SpamNewlines(gSavedSettings,"_NACL_AntiSpamNewlines"); + static const LLCachedControl SpamNewlines("_NACL_AntiSpamNewlines"); boost::sregex_iterator iter(message.begin(), message.end(), NEWLINES); if((U32)std::abs(std::distance(iter, boost::sregex_iterator())) > SpamNewlines) { - NACLAntiSpamRegistry::blockOnQueue((U32)NACLAntiSpamRegistry::QUEUE_IM,from_id); + antispam->blockOnQueue(NACLAntiSpamRegistry::QUEUE_IM, from_id); LL_INFOS() << "[antispam] blocked owner due to too many newlines: " << from_id << LL_ENDL; - if(gSavedSettings.getBOOL("AntiSpamNotify")) + if (gSavedSettings.getBOOL("AntiSpamNotify")) { LLSD args; - args["SOURCE"] = from_id.asString(); + args["SOURCE"] = from_id; args["AMOUNT"] = boost::lexical_cast(SpamNewlines); LLNotificationsUtil::add("AntiSpamNewlineFlood", args); } @@ -2153,8 +2143,8 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) EInstantMessage dialog = (EInstantMessage)d; // NaCl - Antispam Registry - if((dialog != IM_TYPING_START && dialog != IM_TYPING_STOP) - && NACLAntiSpamRegistry::checkQueue((U32)NACLAntiSpamRegistry::QUEUE_IM,from_id)) + if (antispam && (dialog != IM_TYPING_START && dialog != IM_TYPING_STOP) + && antispam->checkQueue(NACLAntiSpamRegistry::QUEUE_IM, from_id)) return; // NaCl End @@ -2177,20 +2167,23 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) // bool is_do_not_disturb = gAgent.isDoNotDisturb(); - bool is_muted = LLMuteList::getInstance()->isMuted(from_id, name, LLMute::flagTextChat) - // object IMs contain sender object id in session_id (STORM-1209) - || (dialog == IM_FROM_TASK && LLMuteList::getInstance()->isMuted(session_id)); bool is_owned_by_me = false; bool is_friend = (LLAvatarTracker::instance().getBuddyInfo(from_id) == NULL) ? false : true; bool accept_im_from_only_friend = gSavedSettings.getBOOL("InstantMessagesFriendsOnly"); - bool is_linden = chat.mSourceType != CHAT_SOURCE_OBJECT && - LLMuteList::getInstance()->isLinden(name); - chat.mMuted = is_muted && !is_linden; chat.mFromID = from_id; chat.mFromName = name; - chat.mSourceType = (from_id.isNull() || (name == std::string(SYSTEM_FROM))) ? CHAT_SOURCE_SYSTEM : CHAT_SOURCE_AGENT; - + chat.mSourceType = (from_id.isNull() || (name == std::string(SYSTEM_FROM))) ? CHAT_SOURCE_SYSTEM : + (dialog == IM_FROM_TASK && dialog == IM_FROM_TASK_AS_ALERT) ? CHAT_SOURCE_OBJECT : CHAT_SOURCE_AGENT; + + bool is_muted = LLMuteList::getInstance()->isMuted(from_id, name, LLMute::flagTextChat) + // object IMs contain sender object id in session_id (STORM-1209) + || (chat.mSourceType == CHAT_SOURCE_OBJECT && LLMuteList::getInstance()->isMuted(session_id)); + + bool is_linden = chat.mSourceType != CHAT_SOURCE_OBJECT && + LLMuteList::getInstance()->isLinden(name); + chat.mMuted = is_muted && !is_linden; + if(chat.mSourceType == CHAT_SOURCE_AGENT) { LLSD args; @@ -3454,8 +3447,9 @@ void process_offer_callingcard(LLMessageSystem* msg, void**) msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, source_id); // NaCl - Antispam Registry - if(NACLAntiSpamRegistry::checkQueue((U32)NACLAntiSpamRegistry::QUEUE_CALLING_CARD,source_id)) - return; + if (auto antispam = NACLAntiSpamRegistry::getIfExists()) + if (antispam->checkQueue(NACLAntiSpamRegistry::QUEUE_CALLING_CARD, source_id)) + return; // NaCl End LLUUID tid; @@ -3670,9 +3664,10 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) chat.mChatType = (EChatType)type_temp; // NaCL - Antispam Registry - if((chat.mChatType != CHAT_TYPE_START && chat.mChatType != CHAT_TYPE_STOP) //Chat type isn't typing - &&((owner_id.isNull() && NACLAntiSpamRegistry::checkQueue((U32)NACLAntiSpamRegistry::QUEUE_CHAT,from_id)) //Spam from an object? - ||(NACLAntiSpamRegistry::checkQueue((U32)NACLAntiSpamRegistry::QUEUE_CHAT,owner_id)))) //Spam from a resident? + auto antispam = NACLAntiSpamRegistry::getIfExists(); + if (antispam && chat.mChatType != CHAT_TYPE_START && chat.mChatType != CHAT_TYPE_STOP //Chat type isn't typing + && (antispam->checkQueue(NACLAntiSpamRegistry::QUEUE_CHAT, from_id, owner_id.isNull() ? LFIDBearer::AVATAR : LFIDBearer::OBJECT) // Spam from an object or avatar? + || (owner_id.notNull() && (antispam->checkQueue(NACLAntiSpamRegistry::QUEUE_CHAT, owner_id))))) // Spam from a resident? return; // NaCl End @@ -3876,18 +3871,17 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) if (is_audible) { // NaCl - Newline flood protection - static LLCachedControl AntiSpamEnabled(gSavedSettings,"AntiSpamEnabled",false); - if (AntiSpamEnabled && can_block(from_id)) + if (antispam && can_block(from_id)) { - static LLCachedControl SpamNewlines(gSavedSettings,"_NACL_AntiSpamNewlines"); + static const LLCachedControl SpamNewlines("_NACL_AntiSpamNewlines"); boost::sregex_iterator iter(mesg.begin(), mesg.end(), NEWLINES); if((U32)std::abs(std::distance(iter, boost::sregex_iterator())) > SpamNewlines) { - NACLAntiSpamRegistry::blockOnQueue((U32)NACLAntiSpamRegistry::QUEUE_CHAT,owner_id); + antispam->blockOnQueue(NACLAntiSpamRegistry::QUEUE_CHAT, owner_id); if(gSavedSettings.getBOOL("AntiSpamNotify")) { LLSD args; - args["MESSAGE"] = "Chat: Blocked newline flood from "+owner_id.asString(); + args["MESSAGE"] = "Chat: Blocked newline flood from " + LLAvatarActions::getSLURL(owner_id); LLNotificationsUtil::add("SystemMessageTip", args); } return; @@ -5232,18 +5226,18 @@ void process_sound_trigger(LLMessageSystem *msg, void **) msg->getUUIDFast(_PREHASH_SoundData, _PREHASH_ObjectID, object_id); // NaCl - Antispam Registry - static LLCachedControl _NACL_AntiSpamSoundMulti(gSavedSettings,"_NACL_AntiSpamSoundMulti"); - if(owner_id.isNull()) + if (auto antispam = NACLAntiSpamRegistry::getIfExists()) { - bool bDoSpamCheck=1; - std::string sSound=sound_id.asString(); - for(int i=0;i< COLLISION_SOUNDS_SIZE;i++) - if(COLLISION_SOUNDS[i] == sSound) - bDoSpamCheck=0; - if(bDoSpamCheck) - if(NACLAntiSpamRegistry::checkQueue((U32)NACLAntiSpamRegistry::QUEUE_SOUND,object_id, _NACL_AntiSpamSoundMulti)) return; + static const LLCachedControl _NACL_AntiSpamSoundMulti("_NACL_AntiSpamSoundMulti"); + if (owner_id.isNull()) + { + bool is_collision_sound(const std::string & sound); + if (!is_collision_sound(sound_id.asString()) + && antispam->checkQueue(NACLAntiSpamRegistry::QUEUE_SOUND, object_id, LFIDBearer::OBJECT, _NACL_AntiSpamSoundMulti)) + return; + } + else if (antispam->checkQueue(NACLAntiSpamRegistry::QUEUE_SOUND, owner_id, LFIDBearer::AVATAR, _NACL_AntiSpamSoundMulti)) return; } - else if(NACLAntiSpamRegistry::checkQueue((U32)NACLAntiSpamRegistry::QUEUE_SOUND,owner_id, _NACL_AntiSpamSoundMulti)) return; // NaCl End msg->getUUIDFast(_PREHASH_SoundData, _PREHASH_ParentID, parent_id); @@ -5322,11 +5316,14 @@ void process_preload_sound(LLMessageSystem *msg, void **user_data) msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_OwnerID, owner_id); // NaCl - Antispam Registry - static LLCachedControl _NACL_AntiSpamSoundPreloadMulti(gSavedSettings,"_NACL_AntiSpamSoundPreloadMulti"); - if((owner_id.isNull() - && NACLAntiSpamRegistry::checkQueue((U32)NACLAntiSpamRegistry::QUEUE_SOUND_PRELOAD,object_id,_NACL_AntiSpamSoundPreloadMulti)) - || NACLAntiSpamRegistry::checkQueue((U32)NACLAntiSpamRegistry::QUEUE_SOUND_PRELOAD,owner_id,_NACL_AntiSpamSoundPreloadMulti)) - return; + if (auto antispam = NACLAntiSpamRegistry::getIfExists()) + { + static const LLCachedControl _NACL_AntiSpamSoundPreloadMulti("_NACL_AntiSpamSoundPreloadMulti"); + if ((owner_id.isNull() + && antispam->checkQueue(NACLAntiSpamRegistry::QUEUE_SOUND_PRELOAD, object_id, LFIDBearer::OBJECT, _NACL_AntiSpamSoundPreloadMulti)) + || antispam->checkQueue(NACLAntiSpamRegistry::QUEUE_SOUND_PRELOAD, owner_id, LFIDBearer::AVATAR, _NACL_AntiSpamSoundPreloadMulti)) + return; + } // NaCl End LLViewerObject *objectp = gObjectList.findObject(object_id); @@ -5364,10 +5361,13 @@ void process_attached_sound(LLMessageSystem *msg, void **user_data) msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_OwnerID, owner_id); // NaCl - Antispam Registry - if((owner_id.isNull() - && NACLAntiSpamRegistry::checkQueue((U32)NACLAntiSpamRegistry::QUEUE_SOUND,object_id)) - || NACLAntiSpamRegistry::checkQueue((U32)NACLAntiSpamRegistry::QUEUE_SOUND,owner_id)) - return; + if (auto antispam = NACLAntiSpamRegistry::getIfExists()) + { + if ((owner_id.isNull() + && antispam->checkQueue(NACLAntiSpamRegistry::QUEUE_SOUND, object_id, LFIDBearer::OBJECT)) + || antispam->checkQueue(NACLAntiSpamRegistry::QUEUE_SOUND, owner_id)) + return; + } // NaCl End msg->getF32Fast(_PREHASH_DataBlock, _PREHASH_Gain, gain); @@ -7100,8 +7100,9 @@ void process_economy_data(LLMessageSystem *msg, void** /*user_data*/) void notify_cautioned_script_question(const LLSD& notification, const LLSD& response, S32 orig_questions, BOOL granted) { // NaCl - Antispam Registry - LLUUID task_id = notification["payload"]["task_id"].asUUID(); - if(NACLAntiSpamRegistry::checkQueue((U32)NACLAntiSpamRegistry::QUEUE_SCRIPT_DIALOG,task_id)) return; + if (auto antispam = NACLAntiSpamRegistry::getIfExists()) + if (antispam->checkQueue(NACLAntiSpamRegistry::QUEUE_SCRIPT_DIALOG, notification["payload"]["task_id"].asUUID(), LFIDBearer::OBJECT)) + return; // NaCl End // only continue if at least some permissions were requested if (orig_questions) @@ -7376,10 +7377,13 @@ void process_script_question(LLMessageSystem *msg, void **user_data) msg->getUUIDFast(_PREHASH_Data, _PREHASH_ItemID, itemid ); // NaCl - Antispam Registry - if((taskid.isNull() - && NACLAntiSpamRegistry::checkQueue((U32)NACLAntiSpamRegistry::QUEUE_SCRIPT_DIALOG,itemid)) - || NACLAntiSpamRegistry::checkQueue((U32)NACLAntiSpamRegistry::QUEUE_SCRIPT_DIALOG,taskid)) - return; + if (auto antispam = NACLAntiSpamRegistry::getIfExists()) + { + if ((taskid.isNull() + && antispam->checkQueue(NACLAntiSpamRegistry::QUEUE_SCRIPT_DIALOG, itemid, LFIDBearer::NONE)) + || antispam->checkQueue(NACLAntiSpamRegistry::QUEUE_SCRIPT_DIALOG, taskid, LFIDBearer::OBJECT)) + return; + } // NaCl End msg->getStringFast(_PREHASH_Data, _PREHASH_ObjectName, object_name); @@ -7674,7 +7678,7 @@ void process_teleport_failed(LLMessageSystem *msg, void**) // Get the message ID msg->getStringFast(_PREHASH_AlertInfo, _PREHASH_Message, message_id); big_reason = LLAgent::sTeleportErrorMessages[message_id]; - if ( big_reason.size() > 0 ) + if (!big_reason.empty()) { // Substitute verbose reason from the local map args["REASON"] = big_reason; } @@ -7687,7 +7691,7 @@ void process_teleport_failed(LLMessageSystem *msg, void**) LLSD llsd_block; std::string llsd_raw; msg->getStringFast(_PREHASH_AlertInfo, _PREHASH_ExtraParams, llsd_raw); - if (llsd_raw.length()) + if (!llsd_raw.empty()) { std::istringstream llsd_data(llsd_raw); if (!LLSDSerialize::deserialize(llsd_block, llsd_data, llsd_raw.length())) @@ -8212,10 +8216,15 @@ void process_script_dialog(LLMessageSystem* msg, void**) msg->getUUID("Data", "ObjectID", object_id); // NaCl - Antispam Registry - if(NACLAntiSpamRegistry::checkQueue((U32)NACLAntiSpamRegistry::QUEUE_SCRIPT_DIALOG,object_id)) + auto antispam = NACLAntiSpamRegistry::getIfExists(); + if (antispam && antispam->checkQueue(NACLAntiSpamRegistry::QUEUE_SCRIPT_DIALOG, object_id, LFIDBearer::OBJECT)) return; // NaCl End + std::string first_name; + msg->getString("Data", "FirstName", first_name); + bool const is_group = first_name.empty(); + // For compability with OS grids first check for presence of extended packet before fetching data. LLUUID owner_id; if (gMessageSystem->getNumberOfBlocks("OwnerData") > 0) @@ -8223,13 +8232,14 @@ void process_script_dialog(LLMessageSystem* msg, void**) msg->getUUID("OwnerData", "OwnerID", owner_id); // NaCl - Antispam Registry - if(NACLAntiSpamRegistry::checkQueue((U32)NACLAntiSpamRegistry::QUEUE_SCRIPT_DIALOG,owner_id)) + if (antispam && antispam->checkQueue(NACLAntiSpamRegistry::QUEUE_SCRIPT_DIALOG, owner_id, is_group ? LFIDBearer::GROUP : LFIDBearer::AVATAR)) return; // NaCl End } // NaCl - Antispam - if (owner_id.isNull() ? is_spam_filtered(IM_COUNT, LLAvatarActions::isFriend(object_id), object_id == gAgentID) : is_spam_filtered(IM_COUNT, LLAvatarActions::isFriend(owner_id), owner_id == gAgentID)) return; + if (owner_id.isNull() ? is_spam_filtered(IM_COUNT, LLAvatarActions::isFriend(object_id), object_id == gAgentID) + : is_spam_filtered(IM_COUNT, LLAvatarActions::isFriend(owner_id), owner_id == gAgentID)) return; // NaCl End if (LLMuteList::getInstance()->isMuted(object_id) || LLMuteList::getInstance()->isMuted(owner_id)) @@ -8238,12 +8248,10 @@ void process_script_dialog(LLMessageSystem* msg, void**) } std::string message; - std::string first_name; std::string last_name; std::string object_name; S32 chat_channel; - msg->getString("Data", "FirstName", first_name); msg->getString("Data", "LastName", last_name); msg->getString("Data", "ObjectName", object_name); msg->getString("Data", "Message", message); @@ -8296,7 +8304,6 @@ void process_script_dialog(LLMessageSystem* msg, void**) args["MESSAGE"] = message; args["CHANNEL"] = chat_channel; LLNotificationPtr notification; - bool const is_group = first_name.empty(); char const* name = (is_group && !is_text_box) ? "GROUPNAME" : "NAME"; args[name] = is_group ? last_name : LLCacheName::buildFullName(first_name, last_name); if (is_text_box) @@ -8392,17 +8399,21 @@ void process_load_url(LLMessageSystem* msg, void**) msg->getUUID( "Data", "OwnerID", owner_id); // NaCl - Antispam - if (owner_id.isNull() ? is_spam_filtered(IM_COUNT, LLAvatarActions::isFriend(object_id), object_id == gAgentID) : is_spam_filtered(IM_COUNT, LLAvatarActions::isFriend(owner_id), owner_id == gAgentID)) return; - // NaCl End - - // NaCl - Antispam Registry - if((owner_id.isNull() - && NACLAntiSpamRegistry::checkQueue((U32)NACLAntiSpamRegistry::QUEUE_SCRIPT_DIALOG,object_id)) - || NACLAntiSpamRegistry::checkQueue((U32)NACLAntiSpamRegistry::QUEUE_SCRIPT_DIALOG,owner_id)) - return; + if (owner_id.isNull() ? is_spam_filtered(IM_COUNT, LLAvatarActions::isFriend(object_id), object_id == gAgentID) + : is_spam_filtered(IM_COUNT, LLAvatarActions::isFriend(owner_id), owner_id == gAgentID)) return; // NaCl End msg->getBOOL( "Data", "OwnerIsGroup", owner_is_group); + // NaCl - Antispam Registry + if (auto antispam = NACLAntiSpamRegistry::getIfExists()) + { + if ((owner_id.isNull() + && antispam->checkQueue(NACLAntiSpamRegistry::QUEUE_SCRIPT_DIALOG, object_id, LFIDBearer::OBJECT)) + || antispam->checkQueue(NACLAntiSpamRegistry::QUEUE_SCRIPT_DIALOG, owner_id, owner_is_group ? LFIDBearer::GROUP : LFIDBearer::AVATAR)) + return; + } + // NaCl End + msg->getString("Data", "Message", 256, message); msg->getString("Data", "URL", 256, url); diff --git a/indra/newview/skins/default/xui/en-us/notifications.xml b/indra/newview/skins/default/xui/en-us/notifications.xml index fe4f50391..f8958e8fe 100644 --- a/indra/newview/skins/default/xui/en-us/notifications.xml +++ b/indra/newview/skins/default/xui/en-us/notifications.xml @@ -11407,7 +11407,7 @@ AntiSpam: Blocked [SOURCE] for spamming [TYPE]s [AMOUNT] times in [TIME] seconds icon="notifytip.tga" name="AntiSpamNewlineFlood" type="notifytip"> -AntiSpam: Blocked newline flood from [SOURCE] (over [AMOUNT] newlines). +AntiSpam: Blocked newline flood from secondlife:///app/agent/[SOURCE]/about (over [AMOUNT] newlines).