From ab35a07f0e084e5fe4ecfcb7fc759347b6b8e1cb Mon Sep 17 00:00:00 2001 From: Shyotl Date: Wed, 27 Apr 2011 16:39:20 -0500 Subject: [PATCH] Added anti-spam features. ScriptsCanShowUI:false disables LLMapDestination (from V2) SH_SpamHandler, derived from Cryogenic's spam blocking: If flooded by an object, all objects of same owner get blocked. If flooded by an avatar, avatar will be blocked. Dialog flood prevention. (Objects only) Calling card flood prevention (Avatar only) Chat flood prevention. (Avatar and objects) IM/Inventory offer flood prevention (Avatar and objects) See additions to settings_sh.xml for details on new settings pertaining to anti-spam. --- indra/newview/app_settings/settings.xml | 11 ++ indra/newview/app_settings/settings_sh.xml | 90 +++++++++++++- indra/newview/llviewermessage.cpp | 112 +++++++++++++++++- .../skins/default/xui/en-us/notifications.xml | 6 + 4 files changed, 215 insertions(+), 4 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 577cbed16..537a22a41 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -9,6 +9,17 @@ settings_rlv.xml + ScriptsCanShowUI + + Comment + Allow LSL calls (such as LLMapDestination) to spawn viewer UI + Persist + 1 + Type + Boolean + Value + 1 + FloaterObjectBackuptRect Comment diff --git a/indra/newview/app_settings/settings_sh.xml b/indra/newview/app_settings/settings_sh.xml index a796d5a38..c355ee478 100644 --- a/indra/newview/app_settings/settings_sh.xml +++ b/indra/newview/app_settings/settings_sh.xml @@ -80,5 +80,93 @@ 1.0 - + SGBlockGeneralSpam + + Comment + Enable automatic general spam blocking + Persist + 1 + Type + Boolean + Value + 1 + + SGBlockCardSpam + + Comment + Enable automatic calling card spam blocking + Persist + 1 + Type + Boolean + Value + 1 + + SGBlockChatSpam + + Comment + Enable automatic chat spam blocking + Persist + 1 + Type + Boolean + Value + 1 + + SGBlockDialogSpam + + Comment + Enable automatic dialog spam blocking + Persist + 1 + Type + Boolean + Value + 1 + + SGSpamTime + + Comment + Time of Evalulating spam. (Default: 1.000) + Persist + 1 + Type + F32 + Value + 1.0 + + SGSpamCount + + Comment + Number of items spammed per time period in SGSpamTime. (Default: 4) + Persist + 1 + Type + U32 + Value + 4 + + SGChatSpamTime + + Comment + Time of Evalulating spam. (Default: 1.000) + Persist + 1 + Type + F32 + Value + 1.0 + + SGChatSpamCount + + Comment + Number of items spammed per time set in SGSpamTime. (Default: 10) + Persist + 1 + Type + U32 + Value + 10.0 + + diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index a9fc5c5f8..aedd47d40 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -232,6 +232,75 @@ const BOOL SCRIPT_QUESTION_IS_CAUTION[SCRIPT_PERMISSION_EOF] = FALSE // ControlYourCamera }; +template +class SH_SpamHandler +{ +public: + SH_SpamHandler(const char *pToggleCtrl, const char *pDurCtrl, const char *pFreqCtrl) : + mDuration(pDurCtrl, 1.f), + mFrequency(pFreqCtrl, 5), + mEnabled(false) + { + gSavedSettings.getControl(pToggleCtrl)->getSignal()->connect(boost::bind(&SH_SpamHandler::CtrlToggle, this, _1)); + CtrlToggle(gSavedSettings.getBOOL(pToggleCtrl)); + } + bool CtrlToggle(const LLSD& newvalue) + { + bool on = newvalue.asBoolean(); + if(on == mEnabled) + return true; + mEnabled = on; + mTimer.stop(); + mActiveList.clear(); + mBlockedList.clear(); + return true; + } + bool isBlocked(const T &owner, const LLUUID &source_id, const char *pNotification, LLSD &args=LLSD()) + { + if(!mEnabled || isAgent(owner)) + return false; + if(mBlockedList.find(owner) != mBlockedList.end()) + return true; + if(mTimer.getStarted() && mTimer.getElapsedTimeF32() < mDuration) + { + std::map::iterator it = mActiveList.insert(std::pair(owner,0)).first; + if(++(it->second)>=mFrequency) + { + mBlockedList.insert(owner); + if(pNotification) + { + args["OWNER"] = owner; + args["SOURCE"] = source_id; + LLNotifications::getInstance()->add(pNotification,args); + } + return true; + } + } + else + { + mActiveList.clear(); + mTimer.start(); + } + return false; + } +private: + //Owner is either a key, or a name. Do not look up perms since object may be unknown. + bool isAgent(const T &owner) const; + bool mEnabled; + LLFrameTimer mTimer; + const LLCachedControl mDuration; + const LLCachedControl mFrequency; + std::map mActiveList; + std::set mBlockedList; +}; +template<> bool SH_SpamHandler::isAgent(const LLUUID &owner) const { return gAgent.getID() == owner; } +template<> bool SH_SpamHandler::isAgent(const std::string &owner) const +{ + std::string str; + gAgent.getName(str); + return str == owner; +} + bool friendship_offer_callback(const LLSD& notification, const LLSD& response) { S32 option = LLNotification::getSelectedOption(notification, response); @@ -1631,6 +1700,21 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) chat.mFromID = from_id; chat.mFromName = name; chat.mSourceType = (from_id.isNull() || (name == std::string(SYSTEM_FROM))) ? CHAT_SOURCE_SYSTEM : CHAT_SOURCE_AGENT; + + if(chat.mSourceType == CHAT_SOURCE_AGENT) + { + LLSD args; + args["FULL_NAME"] = name; + static SH_SpamHandler avatar_spam_check("SGBlockGeneralSpam","SGSpamTime","SGSpamCount"); + static SH_SpamHandler object_spam_check("SGBlockGeneralSpam","SGSpamTime","SGSpamCount"); + if(d==IM_FROM_TASK||d==IM_GOTO_URL||d==IM_FROM_TASK_AS_ALERT||d==IM_TASK_INVENTORY_OFFERED||d==IM_TASK_INVENTORY_ACCEPTED||d==IM_TASK_INVENTORY_DECLINED) + { + if(object_spam_check.isBlocked(from_id,session_id,"BlockedGeneralObjects"),args) + return; + } + else if(avatar_spam_check.isBlocked(from_id,from_id,"BlockedGeneralAvatar"),args) + return; + } LLViewerObject *source = gObjectList.findObject(session_id); //Session ID is probably the wrong thing. if (source) @@ -2812,6 +2896,9 @@ void process_offer_callingcard(LLMessageSystem* msg, void**) } else { + static SH_SpamHandler spam_check("SGBlockCardSpam","SHSpamTime","SGSpamCount"); + if(spam_check.isBlocked(source_id,source_id,"BlockedCards",args)) + return; LLNotifications::instance().add("OfferCallingCard", args, payload); } } @@ -2985,6 +3072,14 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) // if (chatter) { + LLSD args; + args["FULL_NAME"] = from_name; + static SH_SpamHandler avatar_spam_check("SGBlockChatSpam","SGChatSpamTime","SGChatSpamCount"); + static SH_SpamHandler object_spam_check("SGBlockChatSpam","SGChatSpamTime","SGChatSpamCount"); + if( (chatter->isAvatar() && avatar_spam_check.isBlocked(from_id,from_id,"BlockedChatterAvatar",args)) || + (!chatter->isAvatar() && object_spam_check.isBlocked(owner_id,from_id,"BlockedChatterObjects",args)) ) + return; + chat.mPosAgent = chatter->getPositionAgent(); // Make swirly things only for talking objects. (not script debug messages, though) @@ -6366,17 +6461,22 @@ static LLNotificationFunctorRegistration callback_script_dialog_reg_2("ScriptDia void process_script_dialog(LLMessageSystem* msg, void**) { S32 i; - LLSD payload; + LLUUID object_id; + msg->getUUID("Data", "ObjectID", object_id); + + if (LLMuteList::getInstance()->isMuted(object_id)) + { + return; + } + std::string message; std::string first_name; std::string last_name; std::string title; - LLUUID object_id; S32 chat_channel; - msg->getUUID("Data", "ObjectID", object_id); msg->getString("Data", "FirstName", first_name); msg->getString("Data", "LastName", last_name); msg->getString("Data", "ObjectName", title); @@ -6437,6 +6537,10 @@ void process_script_dialog(LLMessageSystem* msg, void**) args["FIRST"] = first_name; args["LAST"] = last_name; + static SH_SpamHandler spam_check("SGBlockDialogSpam","SGSpamTime","SGSpamCount"); + if(spam_check.isBlocked(first_name + " " + last_name,object_id,"BlockedDialogs",args)) + return; + if (is_text_box) { args["DEFAULT"] = default_text; @@ -6601,6 +6705,8 @@ void process_initiate_download(LLMessageSystem* msg, void**) void process_script_teleport_request(LLMessageSystem* msg, void**) { + if (!gSavedSettings.getBOOL("ScriptsCanShowUI")) return; + std::string object_name; std::string sim_name; LLVector3 pos; diff --git a/indra/newview/skins/default/xui/en-us/notifications.xml b/indra/newview/skins/default/xui/en-us/notifications.xml index ab432afd1..a89b0b0c0 100644 --- a/indra/newview/skins/default/xui/en-us/notifications.xml +++ b/indra/newview/skins/default/xui/en-us/notifications.xml @@ -6933,6 +6933,12 @@ No For instructions, make a new template in the AO. Use the toolbar to toggle the AO on/off. + Blocked calling cards from [FIRST] [LAST] ([SOURCE]) + Blocking all dialogs from [FIRST] [LAST]'s objects. (Origin: [SOURCE]) + Blocked spam from avatar [FULL_NAME] ([SOURCE]) + Blocked spam from objects owned by [OWNER] ([SOURCE]) + Blocked chat-spam from avatar [FULL_NAME] ([SOURCE]) + Blocked chat-spam from objects owned by [OWNER] ([SOURCE])