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