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).