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.
This commit is contained in:
@@ -232,6 +232,75 @@ const BOOL SCRIPT_QUESTION_IS_CAUTION[SCRIPT_PERMISSION_EOF] =
|
||||
FALSE // ControlYourCamera
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
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<const T,U32>::iterator it = mActiveList.insert(std::pair<const T, U32>(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<F32> mDuration;
|
||||
const LLCachedControl<U32> mFrequency;
|
||||
std::map<const T,U32> mActiveList;
|
||||
std::set<const T> mBlockedList;
|
||||
};
|
||||
template<> bool SH_SpamHandler<LLUUID>::isAgent(const LLUUID &owner) const { return gAgent.getID() == owner; }
|
||||
template<> bool SH_SpamHandler<std::string>::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<LLUUID> avatar_spam_check("SGBlockGeneralSpam","SGSpamTime","SGSpamCount");
|
||||
static SH_SpamHandler<LLUUID> 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<LLUUID> 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)
|
||||
// </edit>
|
||||
if (chatter)
|
||||
{
|
||||
LLSD args;
|
||||
args["FULL_NAME"] = from_name;
|
||||
static SH_SpamHandler<LLUUID> avatar_spam_check("SGBlockChatSpam","SGChatSpamTime","SGChatSpamCount");
|
||||
static SH_SpamHandler<LLUUID> 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<std::string> 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;
|
||||
|
||||
Reference in New Issue
Block a user