diff --git a/indra/newview/app_settings/settings_per_account_alchemy.xml b/indra/newview/app_settings/settings_per_account_alchemy.xml
index a9eb115f0d..f42e37b281 100644
--- a/indra/newview/app_settings/settings_per_account_alchemy.xml
+++ b/indra/newview/app_settings/settings_per_account_alchemy.xml
@@ -253,5 +253,71 @@
Value
0
+ AlchemyAutoresponseChanged
+
+ AlchemyAutoresponseEnable
+
+ AlchemyAutoresponseNotFriendEnable
+
+ AlchemyAutoresponse
+
+ AlchemyAutoresponseNotFriendChanged
+
+ AlchemyAutoresponseNotFriend
+
-
\ No newline at end of file
+
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index b0552fb6e2..147f1de67b 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -444,6 +444,9 @@ LLAgent::LLAgent() :
mShowAvatar(TRUE),
mFrameAgent(),
+ mIsAutoRespond(false),
+ mIsAutoRespondNonFriends(false),
+
mIsDoNotDisturb(false),
mIsRejectTeleportOffers(false),
mIgnorePrejump(FALSE),
@@ -1800,6 +1803,42 @@ BOOL LLAgent::getRejectFriendshipRequests() const
return mIsRejectFriendshipRequests;
}
+//-----------------------------------------------------------------------------
+// setAutoRespond()
+//-----------------------------------------------------------------------------
+void LLAgent::setAutoRespond(bool pIsAutoRespond)
+{
+ LL_INFOS() << "Setting autorespond mode to " << pIsAutoRespond << LL_ENDL;
+ mIsAutoRespond = pIsAutoRespond;
+ gSavedPerAccountSettings.setBOOL("AlchemyAutoresponseEnable", pIsAutoRespond);
+}
+
+//-----------------------------------------------------------------------------
+// getAutoRespond()
+//-----------------------------------------------------------------------------
+bool LLAgent::getAutoRespond() const
+{
+ return mIsAutoRespond;
+}
+
+//-----------------------------------------------------------------------------
+// setAutoRespondNonFriends()
+//-----------------------------------------------------------------------------
+void LLAgent::setAutoRespondNonFriends(bool pIsAutoRespondNonFriends)
+{
+ LL_INFOS() << "Setting AutoRespondingNonFriends mode to " << pIsAutoRespondNonFriends << LL_ENDL;
+ mIsAutoRespondNonFriends = pIsAutoRespondNonFriends;
+ gSavedPerAccountSettings.setBOOL("AlchemyAutoresponseNotFriendEnable", pIsAutoRespondNonFriends);
+}
+
+//-----------------------------------------------------------------------------
+// getAutoRespondNonFriends()
+//-----------------------------------------------------------------------------
+bool LLAgent::getAutoRespondNonFriends() const
+{
+ return mIsAutoRespondNonFriends;
+}
+
//-----------------------------------------------------------------------------
// startAutoPilotGlobal()
//-----------------------------------------------------------------------------
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index 38727207af..8095e34f3f 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -501,6 +501,18 @@ class LLAgent final : public LLOldEvents::LLObservable
private:
BOOL mIsRejectFriendshipRequests;
+public:
+ void setAutoRespond(bool pIsAutoRespond);
+ bool getAutoRespond() const;
+private:
+ BOOL mIsAutoRespond;
+
+public:
+ void setAutoRespondNonFriends(bool pIsAutoRespondNonFriends);
+ bool getAutoRespondNonFriends() const;
+private:
+ BOOL mIsAutoRespondNonFriends;
+
//--------------------------------------------------------------------
// Grab
//--------------------------------------------------------------------
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 8915a159f5..3301018fe8 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -489,6 +489,9 @@ BOOL LLFloaterPreference::postBuild()
gSavedPerAccountSettings.setString("DoNotDisturbModeResponse", LLTrans::getString("DoNotDisturbModeResponseDefault"));
gSavedPerAccountSettings.setString("ALRejectTeleportOffersResponse", LLTrans::getString("RejectTeleportOffersResponseDefault"));
gSavedPerAccountSettings.setString("ALRejectFriendshipRequestsResponse", LLTrans::getString("RejectFriendshipRequestsResponseDefault"));
+
+ gSavedPerAccountSettings.setString("AlchemyAutoresponse", LLTrans::getString("AutoResponseModeDefault"));
+ gSavedPerAccountSettings.setString("AlchemyAutoresponseNotFriend", LLTrans::getString("AutoResponseModeNonFriendsDefault"));
}
// set 'enable' property for 'Clear log...' button
@@ -574,6 +577,24 @@ void LLFloaterPreference::onRejectTeleportOffersResponseChanged()
gSavedPerAccountSettings.setBOOL("ALRejectTeleportOffersResponseChanged", reject_teleport_offers_response_changed_flag);
}
+void LLFloaterPreference::onAutoRespondResponseChanged()
+{
+ bool auto_response_changed_flag =
+ LLTrans::getString("AutoResponseModeDefault")
+ != getChild("autorespond_response")->getValue().asString();
+
+ gSavedPerAccountSettings.setBOOL("AlchemyAutoresponseChanged", auto_response_changed_flag);
+}
+
+void LLFloaterPreference::onAutoRespondNonFriendsResponseChanged()
+{
+ bool auto_response_non_friends_changed_flag =
+ LLTrans::getString("AutoResponseModeNonFriendsDefault")
+ != getChild("AlchemyAutoresponseNotFriend")->getValue().asString();
+
+ gSavedPerAccountSettings.setBOOL("AlchemyAutoresponseNotFriendChanged", auto_response_non_friends_changed_flag);
+}
+
#if !LL_HAVOK
////////////////////////////////////////////////////
// Grid panel
@@ -951,6 +972,8 @@ LLFloaterPreference::~LLFloaterPreference()
mComplexityChangedSignal.disconnect();
mDnDModeConnection.disconnect();
mRejectTeleportConnection.disconnect();
+ mAutoResponseConnection.disconnect();
+ mAutoResponseNonFriendsConnection.disconnect();
}
void LLFloaterPreference::draw()
@@ -1037,6 +1060,15 @@ void LLFloaterPreference::apply()
}
}
+ // Setting this up so we sync the settings with menu.
+ // i.e Checking the checkox form the Preferences will also check it in the menu.
+ // --FLN
+ bool autoresponse_enabled = getChild("AlchemyAutoresponseEnable")->get();
+ bool autoresponse_notfriends_enabled = getChild("AlchemyAutoresponseNotFriendEnable")->get();
+
+ gAgent.setAutoRespond(autoresponse_enabled);
+ gAgent.setAutoRespondNonFriends(autoresponse_notfriends_enabled);
+
saveAvatarProperties();
}
@@ -1113,6 +1145,10 @@ void LLFloaterPreference::onOpen(const LLSD& key)
mRejectTeleportConnection = gSavedPerAccountSettings.getControl("ALRejectTeleportOffersResponse")->getSignal()->connect(boost::bind(&LLFloaterPreference::onRejectTeleportOffersResponseChanged, this));
+ mAutoResponseConnection = gSavedPerAccountSettings.getControl("AlchemyAutoresponse")->getSignal()->connect(boost::bind(&LLFloaterPreference::onAutoRespondResponseChanged, this));
+
+ mAutoResponseNonFriendsConnection = gSavedPerAccountSettings.getControl("AlchemyAutoresponseNotFriend")->getSignal()->connect(boost::bind(&LLFloaterPreference::onAutoRespondNonFriendsResponseChanged, this));
+
}
gAgent.sendAgentUserInfoRequest();
@@ -1227,6 +1263,19 @@ void LLFloaterPreference::initDoNotDisturbResponse()
{
gSavedPerAccountSettings.setString("ALRejectFriendshipRequestsResponse", LLTrans::getString("RejectFriendshipRequestsResponseDefault"));
}
+
+ // This is called on viewer init so we setup defaults
+ // not sure this is necessary anymore ???
+ // -- FLN
+ if (!gSavedPerAccountSettings.getBOOL("AlchemyAutoresponseChanged"))
+ {
+ gSavedPerAccountSettings.setString("AlchemyAutoresponse", LLTrans::getString("AlchemyAutoresponseDefault"));
+ }
+
+ if (!gSavedPerAccountSettings.getBOOL("AlchemyAutoresponseNotFriendChanged"))
+ {
+ gSavedPerAccountSettings.setString("AlchemyAutoresponseNotFriend", LLTrans::getString("AlchemyAutoresponseNotFriendDefault"));
+ }
}
//static
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index 248bc5002c..fa7b92cead 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -125,6 +125,9 @@ class LLFloaterPreference final : public LLFloater, public LLAvatarPropertiesObs
// string differs from default after user changes.
void onDoNotDisturbResponseChanged();
void onRejectTeleportOffersResponseChanged();
+ void onAutoRespondResponseChanged();
+ void onAutoRespondNonFriendsResponseChanged();
+
// if the custom settings box is clicked
void onChangeCustom();
void updateMeterText(LLUICtrl* ctrl);
@@ -267,6 +270,8 @@ class LLFloaterPreference final : public LLFloater, public LLAvatarPropertiesObs
boost::signals2::connection mRejectTeleportConnection;
boost::signals2::connection mChatBubbleOpacityConnection;
boost::signals2::connection mPreferredMaturityConnection;
+ boost::signals2::connection mAutoResponseConnection;
+ boost::signals2::connection mAutoResponseNonFriendsConnection;
bool mDnDInit = false;
diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp
index f76d2fce11..0c2ff1bb32 100644
--- a/indra/newview/llimprocessing.cpp
+++ b/indra/newview/llimprocessing.cpp
@@ -29,6 +29,7 @@
#include "llimprocessing.h"
#include "llagent.h"
+#include "llagentui.h"
#include "llappviewer.h"
#include "llavatarnamecache.h"
#include "llfirstuse.h"
@@ -64,8 +65,28 @@
#include "rlvui.h"
// [/RLVa:KB]
+#include //
+#include
#include "boost/lexical_cast.hpp"
+
+
+// Resurrect the Autorespond from the archive
+// -- FLN
+std::string replace_wildcards(std::string input, const LLUUID& id, const std::string& name)
+{
+ boost::algorithm::replace_all(input, "#n", name);
+ // disable boost::lexical_cast warning
+ LLSLURL slurl;
+ LLAgentUI::buildSLURL(slurl);
+ boost::algorithm::replace_all(input, "#r", slurl.getSLURLString());
+
+ LLAvatarName av_name;
+ boost::algorithm::replace_all(input, "#d", LLAvatarNameCache::get(id, &av_name) ? av_name.getDisplayName() : name);
+ return input;
+}
+
+
extern void on_new_message(const LLSD& msg);
// Strip out "Resident" for display, but only if the message came from a user
@@ -532,6 +553,11 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
BOOL is_linden = chat.mSourceType != CHAT_SOURCE_OBJECT &&
LLMuteList::isLinden(name);
+ // Resurrect AutoResponse from Alchemy Archive
+ // -- FLN
+ static LLCachedControl sAutorespond(gSavedPerAccountSettings, "AlchemyAutoresponseEnable");
+ static LLCachedControl sAutorespondNonFriend(gSavedPerAccountSettings, "AlchemyAutoresponseNotFriendEnable");
+
chat.mMuted = is_muted;
chat.mFromID = from_id;
chat.mFromName = name;
@@ -625,6 +651,49 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
}
}
+ else if (offline == IM_ONLINE
+ && (sAutorespond || (sAutorespondNonFriend && !is_friend))
+ && from_id.notNull() //not a system message
+ && to_id.notNull()) //not global message
+ {
+ buffer = message;
+ LL_DEBUGS("Messaging") << "process_improved_im: session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL;
+ bool send_response = !gIMMgr->hasSession(session_id);
+ gIMMgr->addMessage(session_id,
+ from_id,
+ name,
+ buffer,
+ IM_OFFLINE == offline,
+ LLStringUtil::null,
+ dialog,
+ parent_estate_id,
+ region_id,
+ position,
+ true);
+ if (send_response)
+ {
+ std::string my_name;
+ LLAgentUI::buildFullname(my_name);
+ std::string response = gSavedPerAccountSettings.getString(sAutorespondNonFriend && !is_friend
+ ? "AlchemyAutoresponseNotFriend"
+ : "AlchemyAutoresponse");
+ response = replace_wildcards(response, from_id, name);
+ pack_instant_message(
+ gMessageSystem,
+ gAgent.getID(),
+ FALSE,
+ gAgent.getSessionID(),
+ from_id,
+ my_name,
+ response,
+ IM_ONLINE,
+ IM_DO_NOT_DISTURB_AUTO_RESPONSE,
+ session_id);
+ gAgent.sendReliableMessage();
+ gIMMgr->addMessage(session_id, gAgent.getID(), my_name, LLTrans::getString("AutoresponsePrefix").append(response));
+ }
+ }
+
else if (from_id.isNull())
{
LLSD args;
@@ -733,6 +802,32 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
false,
0
);
+
+ // Resurrect Autorespond from Alchemy archive
+ // -- FLN
+ if (sAutorespond || (sAutorespondNonFriend && !is_friend))
+ {
+ std::string my_name;
+ LLAgentUI::buildFullname(my_name);
+ std::string response = gSavedPerAccountSettings.getString(sAutorespondNonFriend && !is_friend
+ ? "AlchemyAutoresponseNotFriend"
+ : "AlchemyAutoresponse");
+ response = replace_wildcards(response, from_id, name);
+ pack_instant_message(gMessageSystem,
+ gAgent.getID(),
+ FALSE,
+ gAgent.getSessionID(),
+ from_id,
+ my_name,
+ response,
+ IM_ONLINE,
+ IM_DO_NOT_DISTURB_AUTO_RESPONSE,
+ session_id);
+ gAgent.sendReliableMessage();
+
+ gIMMgr->addMessage(session_id, gAgent.getID(), my_name, LLTrans::getString("AutoresponsePrefix").append(response));
+ }
+
}
gIMMgr->processIMTypingStart(from_id, dialog);
diff --git a/indra/newview/llimprocessing.h b/indra/newview/llimprocessing.h
index 4d20b963a4..56c0e1a50c 100644
--- a/indra/newview/llimprocessing.h
+++ b/indra/newview/llimprocessing.h
@@ -59,5 +59,11 @@ class LLIMProcessing
static void requestOfflineMessagesLegacy();
};
+// Resurrect the Autorespond from the archive
+// -- FLN
+// Replace wild cards in message strings
+std::string replace_wildcards(std::string input, const LLUUID& id, const std::string& name);
+
+
#endif // LL_LLLLIMPROCESSING_H
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index d1fb13e784..6634153186 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -6587,6 +6587,56 @@ class LLWorldGetRejectFriendshipRequests : public view_listener_t
}
};
+class LLCommunicateSetAutoRespond : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ if (gAgent.getAutoRespond())
+ {
+ gAgent.setAutoRespond(false);
+ }
+ else
+ {
+ gAgent.setAutoRespond(true);
+ LLNotificationsUtil::add("AutoRespondModeSet");
+ }
+ return true;
+ }
+};
+
+class LLCommunicateCheckAutoRespond : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ return gAgent.getAutoRespond();
+ }
+};
+
+class LLCommunicateSetAutoRespondNonFriends : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ if (gAgent.getAutoRespondNonFriends())
+ {
+ gAgent.setAutoRespondNonFriends(false);
+ }
+ else
+ {
+ gAgent.setAutoRespondNonFriends(true);
+ LLNotificationsUtil::add("AutoRespondNonFriendsModeSet");
+ }
+ return true;
+ }
+};
+
+class LLCommunicateCheckAutoRespondNonFriends : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ return gAgent.getAutoRespondNonFriends();
+ }
+};
+
class LLWorldCreateLandmark : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -10090,6 +10140,13 @@ void initialize_menus()
//Communicate Nearby chat
view_listener_t::addMenu(new LLCommunicateNearbyChat(), "Communicate.NearbyChat");
+ // Communicate > Autorespond
+ view_listener_t::addMenu(new LLCommunicateSetAutoRespond(), "Communicate.SetAutoRespond");
+ view_listener_t::addMenu(new LLCommunicateSetAutoRespondNonFriends(), "Communicate.SetAutoRespondNonFriends");
+ view_listener_t::addMenu(new LLCommunicateCheckAutoRespond(), "Communicate.GetAutoRespond");
+ view_listener_t::addMenu(new LLCommunicateCheckAutoRespondNonFriends(), "Communicate.GetAutoRespondNonFriends");
+
+
// Communicate > Voice morphing > Subscribe...
commit.add("Communicate.VoiceMorphing.Subscribe", boost::bind(&handle_voice_morphing_subscribe));
// Communicate > Voice morphing > Premium perk...
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 4ca62fc792..48d2163d64 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -729,8 +729,24 @@
function="World.GetRejectFriendshipRequests"/>
-
-
+
+
+
+
+
+
+
+
+
+
+
+Autorespond mode is on.
+Incoming instant messages will now be answered with your configured autoresponse.
+
+
+
+
+Autorespond mode for non-friends is on.
+Incoming instant messages from anyone who is not your friend will now be answered with your configured autoresponse.
+
+
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
index d320d57285..90c4362063 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
@@ -31,6 +31,12 @@
filename="panel_preferences_chat_cmd.xml"
layout="topleft"
follows="top|left" />
+
- Automatic response to all avatars when in REJECT FRIENDSHIP REQUESTS mode
+ type="string"
+ length="1"
+ follows="left|top"
+ height="13"
+ layout="topleft"
+ left="15"
+ mouse_opaque="false"
+ name="autorespond_response_label"
+ top_pad="10"
+ width="475">
+ Automatic response to all avatars when in AUTORESPONSE to everyone mode:
- log_in_to_change
+ enabled_control="AlchemyAutoresponseEnable"
+ control_name="AlchemyAutoresponse"
+ use_ellipses="false"
+ commit_on_focus_lost = "true"
+ follows="left|top"
+ height="45"
+ layout="topleft"
+ left="15"
+ top_pad="10"
+ name="AlchemyAutoresponse"
+ width="475"
+ word_wrap="true">
+ log_in_to_change
-
- Automatic response to all avatars when in REJECT TELEPORT OFFERS mode:
+
+ Automatic response to non-friends when in AUTORESPONSE TO NON-FRIENDS mode:
-
- log_in_to_change
+
+ log_in_to_change
-
+
+
+
\ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_chat_rejection.xml b/indra/newview/skins/default/xui/en/panel_preferences_chat_rejection.xml
new file mode 100644
index 0000000000..24f95621a5
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_preferences_chat_rejection.xml
@@ -0,0 +1,73 @@
+
+
+
+ Automatic response to all avatars when in REJECT FRIENDSHIP REQUESTS mode
+
+
+ log_in_to_change
+
+
+
+ Automatic response to all avatars when in REJECT TELEPORT OFFERS mode:
+
+
+ log_in_to_change
+
+
+
\ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 78d3e4d4a8..ef7db37951 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -2858,7 +2858,11 @@ If you continue to receive this message, please contact Second Life support for
This resident has turned on 'Do Not Disturb' and will see your message later.
The Resident you messaged has activated [APP_NAME] viewer's 'reject all friendship requests mode' which means they have requested not to be disturbed with friendship requests. You may still send an IM manually.
+
+
The Resident you messaged has activated [APP_NAME] viewer's 'reject all teleport offers and requests mode' which means they have requested not to be disturbed with teleport offers and requests. You may still send an IM message manually.
+ The Resident you messaged has activated 'autorespond mode' which means they have requested not to be disturbed. Your message will still be shown in their IM panel for later viewing.
+ The Resident you messaged has activated 'autorespond non-friends mode' which means they have requested not to be disturbed. Your message will still be shown in their IM panel for later viewing.
(By name)
@@ -3735,6 +3739,7 @@ Please reinstall viewer from https://alchemyviewer.org/downloads and contact the
Offline
User not online - message will be stored and delivered later.
User not online - inventory has been saved.
+ (Autoresponse)
Your call has been answered