Merge Firestorm LGPL

Tue, 13 Mar 2018 19:51:18 +0100

author
Ansariel
date
Tue, 13 Mar 2018 19:51:18 +0100
changeset 55335
e403dadcae53
parent 55334
d3479b5f7073
parent 54965
b8433c12766f
child 55337
47a0198ea43a

Merge Firestorm LGPL

indra/newview/CMakeLists.txt file | annotate | diff | revisions
indra/newview/llappviewer.cpp file | annotate | diff | revisions
     1.1 --- a/autobuild.xml	Tue Mar 13 19:50:55 2018 +0100
     1.2 +++ b/autobuild.xml	Tue Mar 13 19:51:18 2018 +0100
     1.3 @@ -948,11 +948,11 @@
     1.4              <key>archive</key>
     1.5              <map>
     1.6                <key>hash</key>
     1.7 -              <string>6324120be383af3564f2b46b07f1b765</string>
     1.8 +              <string>9f69c9fa0932d54d17c159fc33faea87</string>
     1.9                <key>hash_algorithm</key>
    1.10                <string>md5</string>
    1.11                <key>url</key>
    1.12 -              <string>file:///opt/firestorm/fmodstudio-1.10.03-darwin-.tar.bz2</string>
    1.13 +              <string>file:///opt/firestorm/fmodstudio-1.10.04-darwin-180681405.tar.bz2</string>
    1.14              </map>
    1.15              <key>name</key>
    1.16              <string>darwin</string>
    1.17 @@ -990,18 +990,32 @@
    1.18              <key>archive</key>
    1.19              <map>
    1.20                <key>hash</key>
    1.21 -              <string>4be36322f3bf16dfbba67c8df574d446</string>
    1.22 +              <string>7cf0785fa38889c9028fe776eda060f6</string>
    1.23                <key>hash_algorithm</key>
    1.24                <string>md5</string>
    1.25                <key>url</key>
    1.26 -              <string>file:///c:/cygwin/opt/firestorm/fmodstudio-1.10.03-windows-180491728.tar.bz2</string>
    1.27 +              <string>file:///c:/cygwin/opt/firestorm/fmodstudio-1.10.04-windows-180672209.tar.bz2</string>
    1.28              </map>
    1.29              <key>name</key>
    1.30              <string>windows</string>
    1.31            </map>
    1.32 +          <key>windows64</key>
    1.33 +          <map>
    1.34 +            <key>archive</key>
    1.35 +            <map>
    1.36 +              <key>hash</key>
    1.37 +              <string>fe0951c7fffbf1cd0154bcdb5bcaa5c9</string>
    1.38 +              <key>hash_algorithm</key>
    1.39 +              <string>md5</string>
    1.40 +              <key>url</key>
    1.41 +              <string>file:///c:/cygwin/opt/firestorm/fmodstudio-1.10.04-windows64-180672211.tar.bz2</string>
    1.42 +            </map>
    1.43 +            <key>name</key>
    1.44 +            <string>windows64</string>
    1.45 +          </map>
    1.46          </map>
    1.47          <key>version</key>
    1.48 -        <string>1.10.03</string>
    1.49 +        <string>1.10.04</string>
    1.50        </map>
    1.51        <key>fmodex</key>
    1.52        <map>
    1.53 @@ -1958,9 +1972,9 @@
    1.54              <key>archive</key>
    1.55              <map>
    1.56                <key>hash</key>
    1.57 -              <string>88ab0fb55e82f8cd3a75ee636def785a</string>
    1.58 -              <key>url</key>
    1.59 -              <string>file:///opt/firestorm/kdu-7.9.0-darwin-201702032052-r58.tar.bz2</string>
    1.60 +              <string>75991f598df209713faf94b4a1cb1a89</string>
    1.61 +              <key>url</key>
    1.62 +              <string>file:///opt/firestorm/du-7.A.3-darwin-180711129.tar.bz2</string>
    1.63              </map>
    1.64              <key>name</key>
    1.65              <string>darwin</string>
    1.66 @@ -1970,9 +1984,9 @@
    1.67              <key>archive</key>
    1.68              <map>
    1.69                <key>hash</key>
    1.70 -              <string>88ab0fb55e82f8cd3a75ee636def785a</string>
    1.71 -              <key>url</key>
    1.72 -              <string>file:///opt/firestorm/kdu-7.9.0-darwin-201702032052-r58.tar.bz2</string>
    1.73 +              <string>75991f598df209713faf94b4a1cb1a89</string>
    1.74 +              <key>url</key>
    1.75 +              <string>file:///opt/firestorm/kdu-7.A.3-darwin-180711129.tar.bz2</string>
    1.76              </map>
    1.77              <key>name</key>
    1.78              <string>darwin64</string>
    1.79 @@ -2006,9 +2020,9 @@
    1.80              <key>archive</key>
    1.81              <map>
    1.82                <key>hash</key>
    1.83 -              <string>adeb9db4d4435a65c44a72f981a18b33</string>
    1.84 -              <key>url</key>
    1.85 -              <string>file:///c:/cygwin/opt/firestorm/kdu-7.9.1-windows-201703182143-r61.tar.bz2</string>
    1.86 +              <string>7da700b9ca0d05aff5e83c79505827b3</string>
    1.87 +              <key>url</key>
    1.88 +              <string>file:///c:/cygwin/opt/firestorm/kdu-7.A.3-windows-180702336.tar.bz2</string>
    1.89              </map>
    1.90              <key>name</key>
    1.91              <string>windows</string>
    1.92 @@ -2018,9 +2032,9 @@
    1.93              <key>archive</key>
    1.94              <map>
    1.95                <key>hash</key>
    1.96 -              <string>adeb9db4d4435a65c44a72f981a18b33</string>
    1.97 -              <key>url</key>
    1.98 -              <string>file:///c:/cygwin/opt/firestorm/kdu-7.9.1-windows-201703182143-r61.tar.bz2</string>
    1.99 +              <string>7da700b9ca0d05aff5e83c79505827b3</string>
   1.100 +              <key>url</key>
   1.101 +              <string>file:///c:/cygwin/opt/firestorm/kdu-7.A.3-windows-180702336.tar.bz2</string>
   1.102              </map>
   1.103              <key>name</key>
   1.104              <string>windows64</string>
   1.105 @@ -4232,7 +4246,7 @@
   1.106                    <string>--package</string>
   1.107                    <string>--platform darwin</string>
   1.108                    <string>--btype RelWithDebInfo</string>
   1.109 -                  <string>--fmodex</string>
   1.110 +                  <string>--fmodstudio</string>
   1.111                    <string>--kdu</string>
   1.112                  </array>
   1.113                </map>
   1.114 @@ -4243,7 +4257,7 @@
   1.115                    <string>--platform darwin</string>
   1.116                    <string>--package</string>
   1.117                    <string>--btype RelWithDebInfo</string>
   1.118 -                  <string>--fmodex</string>
   1.119 +                  <string>--fmodstudio</string>
   1.120                    <string>--kdu</string>
   1.121                  </array>
   1.122                </map>
   1.123 @@ -4288,7 +4302,7 @@
   1.124                  <array>
   1.125                    <string>--build</string>
   1.126                    <string>--platform darwin</string>
   1.127 -                  <string>--fmodex</string>
   1.128 +                  <string>--fmodstudio</string>
   1.129                    <string>--kdu</string>
   1.130                  </array>
   1.131                </map>
   1.132 @@ -4298,7 +4312,7 @@
   1.133                  <array>
   1.134                    <string>--platform darwin</string>
   1.135                    <string>--kdu</string>
   1.136 -                  <string>--fmodex</string>
   1.137 +                  <string>--fmodstudio</string>
   1.138                  </array>
   1.139                </map>
   1.140                <key>name</key>
     2.1 --- a/indra/newview/CMakeLists.txt	Tue Mar 13 19:50:55 2018 +0100
     2.2 +++ b/indra/newview/CMakeLists.txt	Tue Mar 13 19:51:18 2018 +0100
     2.3 @@ -459,6 +459,7 @@
     2.4      llhudview.cpp
     2.5      llimagefiltersmanager.cpp
     2.6      llimhandler.cpp
     2.7 +    llimprocessing.cpp
     2.8      llimview.cpp
     2.9      llinspect.cpp
    2.10      llinspectavatar.cpp
    2.11 @@ -1212,6 +1213,7 @@
    2.12      llhudtext.h
    2.13      llhudview.h
    2.14      llimagefiltersmanager.h
    2.15 +    llimprocessing.h
    2.16      llimview.h
    2.17      llinspect.h
    2.18      llinspectavatar.h
     3.1 --- a/indra/newview/fsfloatersearch.cpp	Tue Mar 13 19:50:55 2018 +0100
     3.2 +++ b/indra/newview/fsfloatersearch.cpp	Tue Mar 13 19:51:18 2018 +0100
     3.3 @@ -301,7 +301,7 @@
     3.4  	if (mPanelProfile)
     3.5  	{
     3.6  		mPanelProfile->setVisible(false);
     3.7 -		mPanelProfile->setEmbedded(TRUE);
     3.8 +		mPanelProfile->setEmbedded(true);
     3.9  		mPanelPeople->childSetAction("people_profile_btn", boost::bind(&FSFloaterSearch::onBtnPeopleProfile, this));
    3.10  	}
    3.11  	
     4.1 --- a/indra/newview/fspanelprofile.cpp	Tue Mar 13 19:50:55 2018 +0100
     4.2 +++ b/indra/newview/fspanelprofile.cpp	Tue Mar 13 19:51:18 2018 +0100
     4.3 @@ -94,10 +94,10 @@
     4.4  FSPanelProfileTab::FSPanelProfileTab()
     4.5  : LLPanel()
     4.6  , mAvatarId(LLUUID::null)
     4.7 -, mLoading(FALSE)
     4.8 -, mLoaded(FALSE)
     4.9 -, mEmbedded(FALSE)
    4.10 -, mSelfProfile(FALSE)
    4.11 +, mLoading(false)
    4.12 +, mLoaded(false)
    4.13 +, mEmbedded(false)
    4.14 +, mSelfProfile(false)
    4.15  {
    4.16  }
    4.17  
    4.18 @@ -136,7 +136,7 @@
    4.19  {
    4.20  	setApplyProgress(false);
    4.21  
    4.22 -	mLoaded = TRUE;
    4.23 +	mLoaded = true;
    4.24  }
    4.25  
    4.26  void FSPanelProfileTab::setApplyProgress(bool started)
    4.27 @@ -316,7 +316,7 @@
    4.28  		mDisplayNameButton->setEnabled(TRUE);
    4.29  	}
    4.30  
    4.31 -	mDescriptionEdit->setParseHTML( !own_profile && !getEmbedded() );
    4.32 +	mDescriptionEdit->setParseHTML(!own_profile && !getEmbedded());
    4.33  
    4.34  	FSDropTarget* drop_target = getChild<FSDropTarget>("drop_target");
    4.35  	drop_target->setVisible(!own_profile);
    4.36 @@ -750,10 +750,10 @@
    4.37  
    4.38  	if (getSelfProfile() && !getEmbedded())
    4.39  	{
    4.40 -		mShowInSearchCheckbox->setVisible( TRUE );
    4.41 -		mShowInSearchCheckbox->setEnabled( TRUE );
    4.42 -		mDescriptionEdit->setEnabled( TRUE );
    4.43 -		mSecondLifePic->setEnabled( TRUE );
    4.44 +		mShowInSearchCheckbox->setVisible(TRUE);
    4.45 +		mShowInSearchCheckbox->setEnabled(TRUE);
    4.46 +		mDescriptionEdit->setEnabled(TRUE);
    4.47 +		mSecondLifePic->setEnabled(TRUE);
    4.48  	}
    4.49  }
    4.50  
    4.51 @@ -1039,7 +1039,7 @@
    4.52  
    4.53  	if (getSelfProfile() && !getEmbedded())
    4.54  	{
    4.55 -		mUrlEdit->setEnabled( TRUE );
    4.56 +		mUrlEdit->setEnabled(TRUE);
    4.57  	}
    4.58  }
    4.59  
    4.60 @@ -1296,10 +1296,6 @@
    4.61  		mPickDescription->setEnabled(TRUE);
    4.62  		mSetCurrentLocationButton->setVisible(TRUE);
    4.63  	}
    4.64 -	/*else
    4.65 -	{
    4.66 -		mSnapshotCtrl->setEnabled(FALSE);
    4.67 -	}*/
    4.68  }
    4.69  
    4.70  BOOL FSPanelPick::postBuild()
    4.71 @@ -1855,7 +1851,8 @@
    4.72  //////////////////////////////////////////////////////////////////////////
    4.73  
    4.74  FSPanelProfileFirstLife::FSPanelProfileFirstLife()
    4.75 - : FSPanelProfileTab()
    4.76 + : FSPanelProfileTab(),
    4.77 + mIsEditing(false)
    4.78  {
    4.79  }
    4.80  
    4.81 @@ -1865,9 +1862,11 @@
    4.82  
    4.83  BOOL FSPanelProfileFirstLife::postBuild()
    4.84  {
    4.85 -	mDescriptionEdit = getChild<LLUICtrl>("fl_description_edit");
    4.86 +	mDescriptionEdit = getChild<LLTextEditor>("fl_description_edit");
    4.87  	mPicture = getChild<LLTextureCtrl>("real_world_pic");
    4.88  
    4.89 +	mDescriptionEdit->setFocusReceivedCallback(boost::bind(&FSPanelProfileFirstLife::onDescriptionFocusReceived, this));
    4.90 +
    4.91  	return TRUE;
    4.92  }
    4.93  
    4.94 @@ -1878,6 +1877,17 @@
    4.95  	resetData();
    4.96  }
    4.97  
    4.98 +
    4.99 +void FSPanelProfileFirstLife::onDescriptionFocusReceived()
   4.100 +{
   4.101 +	if (!mIsEditing && getSelfProfile())
   4.102 +	{
   4.103 +		mIsEditing = true;
   4.104 +		mDescriptionEdit->setParseHTML(false);
   4.105 +		mDescriptionEdit->setText(mCurrentDescription);
   4.106 +	}
   4.107 +}
   4.108 +
   4.109  void FSPanelProfileFirstLife::processProperties(void* data, EAvatarProcessorType type)
   4.110  {
   4.111  	if (APT_PROPERTIES == type)
   4.112 @@ -1885,7 +1895,8 @@
   4.113  		const LLAvatarData* avatar_data = static_cast<const LLAvatarData*>(data);
   4.114  		if (avatar_data && getAvatarId() == avatar_data->avatar_id)
   4.115  		{
   4.116 -			mDescriptionEdit->setValue(avatar_data->fl_about_text);
   4.117 +			mCurrentDescription = avatar_data->fl_about_text;
   4.118 +			mDescriptionEdit->setValue(mCurrentDescription);
   4.119  			mPicture->setValue(avatar_data->fl_image_id);
   4.120  			enableControls();
   4.121  		}
   4.122 @@ -1910,8 +1921,8 @@
   4.123  
   4.124  	if (getSelfProfile() && !getEmbedded())
   4.125  	{
   4.126 -		mDescriptionEdit->setEnabled( TRUE );
   4.127 -		mPicture->setEnabled( TRUE );
   4.128 +		mDescriptionEdit->setEnabled(TRUE);
   4.129 +		mPicture->setEnabled(TRUE);
   4.130  	}
   4.131  }
   4.132  
   4.133 @@ -2135,12 +2146,17 @@
   4.134  //////////////////////////////////////////////////////////////////////////
   4.135  
   4.136  FSPanelProfile::FSPanelProfile()
   4.137 - : FSPanelProfileTab()
   4.138 + : FSPanelProfileTab(),
   4.139 + mAvatarNameCacheConnection()
   4.140  {
   4.141  }
   4.142  
   4.143  FSPanelProfile::~FSPanelProfile()
   4.144  {
   4.145 +	if (mAvatarNameCacheConnection.connected())
   4.146 +	{
   4.147 +		mAvatarNameCacheConnection.disconnect();
   4.148 +	}
   4.149  }
   4.150  
   4.151  BOOL FSPanelProfile::postBuild()
   4.152 @@ -2214,7 +2230,7 @@
   4.153  		getChild<LLUICtrl>("cancel_btn")->setVisible(TRUE);
   4.154  	}
   4.155  
   4.156 -	LLAvatarNameCache::get(getAvatarId(), boost::bind(&FSPanelProfile::onAvatarNameCache, this, _1, _2));
   4.157 +	mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&FSPanelProfile::onAvatarNameCache, this, _1, _2));
   4.158  }
   4.159  
   4.160  void FSPanelProfile::updateData()
   4.161 @@ -2239,8 +2255,6 @@
   4.162  		mPanelWeb->apply(&data);
   4.163  		mPanelSecondlife->apply(&data);
   4.164  
   4.165 -		// panel_classifieds->apply();
   4.166 -
   4.167  		mPanelInterests->apply();
   4.168  		mPanelPicks->apply();
   4.169  		mPanelNotes->apply();
   4.170 @@ -2249,9 +2263,8 @@
   4.171  
   4.172  void FSPanelProfile::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name)
   4.173  {
   4.174 +	mAvatarNameCacheConnection.disconnect();
   4.175 +
   4.176  	mPanelSecondlife->onAvatarNameCache(agent_id, av_name);
   4.177  	mPanelWeb->onAvatarNameCache(agent_id, av_name);
   4.178  }
   4.179 -
   4.180 -
   4.181 -// eof
     5.1 --- a/indra/newview/fspanelprofile.h	Tue Mar 13 19:50:55 2018 +0100
     5.2 +++ b/indra/newview/fspanelprofile.h	Tue Mar 13 19:51:18 2018 +0100
     5.3 @@ -85,7 +85,7 @@
     5.4  
     5.5  	/*virtual*/ ~FSPanelProfileTab();
     5.6  
     5.7 -	void setEmbedded(BOOL embedded) { mEmbedded = embedded; }
     5.8 +	void setEmbedded(bool embedded) { mEmbedded = embedded; }
     5.9  
    5.10  protected:
    5.11  
    5.12 @@ -93,28 +93,28 @@
    5.13  
    5.14  	virtual void enableControls();
    5.15  
    5.16 -	// mLoading: FALSE: Initial state, can request
    5.17 -	//           TRUE:  Data requested, skip duplicate requests (happens due to LLUI's habit of repeated callbacks)
    5.18 -	// mLoaded:  FALSE: Initial state, show loading indicator
    5.19 -	//           TRUE:  Data recieved, which comes in a single message, hide indicator
    5.20 +	// mLoading: false: Initial state, can request
    5.21 +	//           true:  Data requested, skip duplicate requests (happens due to LLUI's habit of repeated callbacks)
    5.22 +	// mLoaded:  false: Initial state, show loading indicator
    5.23 +	//           true:  Data recieved, which comes in a single message, hide indicator
    5.24  	bool getIsLoading() { return mLoading; }
    5.25 -	void setIsLoading() { mLoading = TRUE; }
    5.26 +	void setIsLoading() { mLoading = true; }
    5.27  	bool getIsLoaded() { return mLoaded; }
    5.28 -	void resetLoading() { mLoading = FALSE; mLoaded = FALSE; }
    5.29 +	void resetLoading() { mLoading = false; mLoaded = false; }
    5.30  	
    5.31 -	const BOOL getEmbedded() const { return mEmbedded; }
    5.32 +	const bool getEmbedded() const { return mEmbedded; }
    5.33  	
    5.34 -	const BOOL getSelfProfile() const { return mSelfProfile; }
    5.35 +	const bool getSelfProfile() const { return mSelfProfile; }
    5.36  
    5.37  	void setApplyProgress(bool started);
    5.38  
    5.39  private:
    5.40  
    5.41 -	LLUUID  mAvatarId;
    5.42 -	BOOL    mLoading;
    5.43 -	BOOL    mLoaded;
    5.44 -	BOOL	mEmbedded;
    5.45 -	BOOL	mSelfProfile;
    5.46 +	LLUUID	mAvatarId;
    5.47 +	bool	mLoading;
    5.48 +	bool	mLoaded;
    5.49 +	bool	mEmbedded;
    5.50 +	bool	mSelfProfile;
    5.51  };
    5.52  
    5.53  
    5.54 @@ -248,11 +248,11 @@
    5.55  	void onAvatarNameCacheSetName(const LLUUID& id, const LLAvatarName& av_name);
    5.56  
    5.57  private:
    5.58 -	typedef std::map<std::string,LLUUID>    group_map_t;
    5.59 -	group_map_t             mGroups;
    5.60 -	void                    openGroupProfile();
    5.61 +	typedef std::map<std::string, LLUUID> group_map_t;
    5.62 +	group_map_t			mGroups;
    5.63 +	void				openGroupProfile();
    5.64  
    5.65 -	LLTextBox*          mStatusText;
    5.66 +	LLTextBox*			mStatusText;
    5.67  	LLGroupList*		mGroupList;
    5.68  	LLCheckBoxCtrl*		mShowInSearchCheckbox;
    5.69  	LLTextureCtrl*		mSecondLifePic;
    5.70 @@ -268,7 +268,7 @@
    5.71  	LLButton*			mIMButton;
    5.72  	LLMenuButton*		mOverflowButton;
    5.73  
    5.74 -	bool                mVoiceStatus;
    5.75 +	bool				mVoiceStatus;
    5.76  
    5.77  	boost::signals2::connection mRlvBehaviorCallbackConnection;
    5.78  	void updateRlvRestrictions(ERlvBehaviour behavior);
    5.79 @@ -306,12 +306,6 @@
    5.80  
    5.81  	/*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event);
    5.82  
    5.83 -	// void load(std::string url);
    5.84 -	// static void onURLKeystroke(LLLineEditor* editor, void* data);
    5.85 -	// static void onCommitLoad(LLUICtrl* ctrl, void* data);
    5.86 -	// static void onCommitURL(LLUICtrl* ctrl, void* data);
    5.87 -	// static void onClickWebProfileHelp(void *);
    5.88 -
    5.89  	void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
    5.90  
    5.91  	virtual void enableControls();
    5.92 @@ -359,8 +353,8 @@
    5.93  	virtual void enableControls();
    5.94  
    5.95  private:
    5.96 -	LLCheckBoxCtrl *mWantChecks[8];
    5.97 -	LLCheckBoxCtrl *mSkillChecks[6];
    5.98 +	LLCheckBoxCtrl*	mWantChecks[8];
    5.99 +	LLCheckBoxCtrl*	mSkillChecks[6];
   5.100  	LLLineEditor*	mWantToEditor;
   5.101  	LLLineEditor*	mSkillsEditor;
   5.102  	LLLineEditor*	mLanguagesEditor;
   5.103 @@ -499,14 +493,14 @@
   5.104  	LLButton*			mSetCurrentLocationButton;
   5.105  	LLButton*			mSaveButton;
   5.106  
   5.107 -	LLVector3d mPosGlobal;
   5.108 -	LLUUID mParcelId;
   5.109 -	LLUUID mPickId;
   5.110 -	LLUUID mRequestedId;
   5.111 +	LLVector3d			mPosGlobal;
   5.112 +	LLUUID				mParcelId;
   5.113 +	LLUUID				mPickId;
   5.114 +	LLUUID				mRequestedId;
   5.115  
   5.116 -	bool mLocationChanged;
   5.117 -	bool mNewPick;
   5.118 -	bool mIsEditing;
   5.119 +	bool				mLocationChanged;
   5.120 +	bool				mNewPick;
   5.121 +	bool				mIsEditing;
   5.122  
   5.123  	std::string mCurrentPickDescription;
   5.124  
   5.125 @@ -582,9 +576,13 @@
   5.126  
   5.127  protected:
   5.128  	virtual void enableControls();
   5.129 +	void onDescriptionFocusReceived();
   5.130  
   5.131 -	LLUICtrl*		mDescriptionEdit;
   5.132 +	LLTextEditor*	mDescriptionEdit;
   5.133  	LLTextureCtrl*	mPicture;
   5.134 +
   5.135 +	bool			mIsEditing;
   5.136 +	std::string		mCurrentDescription;
   5.137  };
   5.138  
   5.139  /**
   5.140 @@ -626,8 +624,7 @@
   5.141  	 */
   5.142  	void fillRightsData();
   5.143  
   5.144 -	void rightsConfirmationCallback(const LLSD& notification,
   5.145 -			const LLSD& response, S32 rights);
   5.146 +	void rightsConfirmationCallback(const LLSD& notification, const LLSD& response, S32 rights);
   5.147  	void confirmModifyRights(bool grant, S32 rights);
   5.148  	void onCommitRights();
   5.149  	void onCommitNotes();
   5.150 @@ -676,6 +673,8 @@
   5.151  	FSPanelProfileFirstLife*	mPanelFirstlife;
   5.152  	FSPanelAvatarNotes*			mPanelNotes;
   5.153  	LLTabContainer*				mTabContainer;
   5.154 +
   5.155 +	boost::signals2::connection	mAvatarNameCacheConnection;
   5.156  };
   5.157  
   5.158  #endif // FS_PANELPROFILE_H
     6.1 --- a/indra/newview/llappviewer.cpp	Tue Mar 13 19:50:55 2018 +0100
     6.2 +++ b/indra/newview/llappviewer.cpp	Tue Mar 13 19:51:18 2018 +0100
     6.3 @@ -43,6 +43,7 @@
     6.4  #include "llagentui.h"
     6.5  #include "llagentwearables.h"
     6.6  #include "llfloaterimcontainer.h"
     6.7 +#include "llimprocessing.h"
     6.8  #include "llwindow.h"
     6.9  #include "llviewerstats.h"
    6.10  #include "llviewerstatsrecorder.h"
    6.11 @@ -613,26 +614,6 @@
    6.12  	return true;
    6.13  }
    6.14  
    6.15 -void request_initial_instant_messages()
    6.16 -{
    6.17 -	static BOOL requested = FALSE;
    6.18 -	if (!requested
    6.19 -		&& gMessageSystem
    6.20 -		&& LLMuteList::getInstance()->isLoaded()
    6.21 -		&& isAgentAvatarValid())
    6.22 -	{
    6.23 -		// Auto-accepted inventory items may require the avatar object
    6.24 -		// to build a correct name.  Likewise, inventory offers from
    6.25 -		// muted avatars require the mute list to properly mute.
    6.26 -		LLMessageSystem* msg = gMessageSystem;
    6.27 -		msg->newMessageFast(_PREHASH_RetrieveInstantMessages);
    6.28 -		msg->nextBlockFast(_PREHASH_AgentData);
    6.29 -		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
    6.30 -		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
    6.31 -		gAgent.sendReliableMessage();
    6.32 -		requested = TRUE;
    6.33 -	}
    6.34 -}
    6.35  
    6.36  // Use these strictly for things that are constructed at startup,
    6.37  // or for things that are performance critical.  JC
    6.38 @@ -5489,7 +5470,7 @@
    6.39  
    6.40  	// Must wait until both have avatar object and mute list, so poll
    6.41  	// here.
    6.42 -	request_initial_instant_messages();
    6.43 +	LLIMProcessing::requestOfflineMessages();
    6.44  
    6.45  	///////////////////////////////////
    6.46  	//
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/indra/newview/llimprocessing.cpp	Tue Mar 13 19:51:18 2018 +0100
     7.3 @@ -0,0 +1,2188 @@
     7.4 +/**
     7.5 +* @file LLIMProcessing.cpp
     7.6 +* @brief Container for Instant Messaging
     7.7 +*
     7.8 +* $LicenseInfo:firstyear=2001&license=viewerlgpl$
     7.9 +* Second Life Viewer Source Code
    7.10 +* Copyright (C) 2018, Linden Research, Inc.
    7.11 +*
    7.12 +* This library is free software; you can redistribute it and/or
    7.13 +* modify it under the terms of the GNU Lesser General Public
    7.14 +* License as published by the Free Software Foundation;
    7.15 +* version 2.1 of the License only.
    7.16 +*
    7.17 +* This library is distributed in the hope that it will be useful,
    7.18 +* but WITHOUT ANY WARRANTY; without even the implied warranty of
    7.19 +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    7.20 +* Lesser General Public License for more details.
    7.21 +*
    7.22 +* You should have received a copy of the GNU Lesser General Public
    7.23 +* License along with this library; if not, write to the Free Software
    7.24 +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
    7.25 +*
    7.26 +* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
    7.27 +* $/LicenseInfo$
    7.28 +*/
    7.29 +
    7.30 +#include "llviewerprecompiledheaders.h"
    7.31 +
    7.32 +#include "llimprocessing.h"
    7.33 +
    7.34 +#include "llagent.h"
    7.35 +#include "llavatarnamecache.h"
    7.36 +#include "llfirstuse.h"
    7.37 +#include "llfloaterreg.h"
    7.38 +// <FS:Ansariel> [FS communication UI]
    7.39 +//#include "llfloaterimnearbychat.h"
    7.40 +#include "fsfloaternearbychat.h"
    7.41 +// </FS:Ansariel> [FS communication UI]
    7.42 +#include "llimview.h"
    7.43 +#include "llinventoryobserver.h"
    7.44 +#include "llinventorymodel.h"
    7.45 +#include "llmutelist.h"
    7.46 +#include "llnotifications.h"
    7.47 +#include "llnotificationsutil.h"
    7.48 +#include "llnotificationmanager.h"
    7.49 +#include "llpanelgroup.h"
    7.50 +#include "llregionhandle.h"
    7.51 +#include "llslurl.h"
    7.52 +#include "llstring.h"
    7.53 +#include "lltoastnotifypanel.h"
    7.54 +#include "lltrans.h"
    7.55 +#include "llviewergenericmessage.h"
    7.56 +#include "llviewerobjectlist.h"
    7.57 +#include "llviewermessage.h"
    7.58 +#include "llviewerwindow.h"
    7.59 +#include "llviewerregion.h"
    7.60 +#include "llvoavatarself.h"
    7.61 +
    7.62 +#include <boost/regex.hpp>
    7.63 +#include "boost/lexical_cast.hpp"
    7.64 +
    7.65 +// [RLVa:KB] - Checked: 2010-03-09 (RLVa-1.2.0a)
    7.66 +#include "rlvactions.h"
    7.67 +#include "rlvhandler.h"
    7.68 +#include "rlvinventory.h"
    7.69 +#include "rlvui.h"
    7.70 +// [/RLVa:KB]
    7.71 +
    7.72 +// Firestorm includes
    7.73 +#include "fscommon.h"
    7.74 +#include "fsdata.h"
    7.75 +#include "fskeywords.h"
    7.76 +#include "llagentui.h"
    7.77 +#include "llavataractions.h"
    7.78 +#include "llgiveinventory.h"
    7.79 +#include "lllandmarkactions.h"
    7.80 +#include "llviewernetwork.h"
    7.81 +#include "sound_ids.h"
    7.82 +#include "NACLantispam.h"
    7.83 +
    7.84 +#if LL_MSVC
    7.85 +// disable boost::lexical_cast warning
    7.86 +#pragma warning (disable:4702)
    7.87 +#endif
    7.88 +
    7.89 +// Strip out "Resident" for display, but only if the message came from a user
    7.90 +// (rather than a script)
    7.91 +static std::string clean_name_from_im(const std::string& name, EInstantMessage type)
    7.92 +{
    7.93 +    switch (type)
    7.94 +    {
    7.95 +        case IM_NOTHING_SPECIAL:
    7.96 +        case IM_MESSAGEBOX:
    7.97 +        case IM_GROUP_INVITATION:
    7.98 +        case IM_INVENTORY_OFFERED:
    7.99 +        case IM_INVENTORY_ACCEPTED:
   7.100 +        case IM_INVENTORY_DECLINED:
   7.101 +        case IM_GROUP_VOTE:
   7.102 +        case IM_GROUP_MESSAGE_DEPRECATED:
   7.103 +            //IM_TASK_INVENTORY_OFFERED
   7.104 +            //IM_TASK_INVENTORY_ACCEPTED
   7.105 +            //IM_TASK_INVENTORY_DECLINED
   7.106 +        case IM_NEW_USER_DEFAULT:
   7.107 +        case IM_SESSION_INVITE:
   7.108 +        case IM_SESSION_P2P_INVITE:
   7.109 +        case IM_SESSION_GROUP_START:
   7.110 +        case IM_SESSION_CONFERENCE_START:
   7.111 +        case IM_SESSION_SEND:
   7.112 +        case IM_SESSION_LEAVE:
   7.113 +            //IM_FROM_TASK
   7.114 +        case IM_DO_NOT_DISTURB_AUTO_RESPONSE:
   7.115 +        case IM_CONSOLE_AND_CHAT_HISTORY:
   7.116 +        case IM_LURE_USER:
   7.117 +        case IM_LURE_ACCEPTED:
   7.118 +        case IM_LURE_DECLINED:
   7.119 +        case IM_GODLIKE_LURE_USER:
   7.120 +        case IM_TELEPORT_REQUEST:
   7.121 +        case IM_GROUP_ELECTION_DEPRECATED:
   7.122 +            //IM_GOTO_URL
   7.123 +            //IM_FROM_TASK_AS_ALERT
   7.124 +        case IM_GROUP_NOTICE:
   7.125 +        case IM_GROUP_NOTICE_INVENTORY_ACCEPTED:
   7.126 +        case IM_GROUP_NOTICE_INVENTORY_DECLINED:
   7.127 +        case IM_GROUP_INVITATION_ACCEPT:
   7.128 +        case IM_GROUP_INVITATION_DECLINE:
   7.129 +        case IM_GROUP_NOTICE_REQUESTED:
   7.130 +        case IM_FRIENDSHIP_OFFERED:
   7.131 +        case IM_FRIENDSHIP_ACCEPTED:
   7.132 +        case IM_FRIENDSHIP_DECLINED_DEPRECATED:
   7.133 +            //IM_TYPING_START
   7.134 +            //IM_TYPING_STOP
   7.135 +            return LLCacheName::cleanFullName(name);
   7.136 +        default:
   7.137 +            return name;
   7.138 +    }
   7.139 +}
   7.140 +
   7.141 +static std::string clean_name_from_task_im(const std::string& msg,
   7.142 +    BOOL from_group)
   7.143 +{
   7.144 +    boost::smatch match;
   7.145 +    static const boost::regex returned_exp(
   7.146 +        "(.*been returned to your inventory lost and found folder by )(.+)( (from|near).*)");
   7.147 +    if (boost::regex_match(msg, match, returned_exp))
   7.148 +    {
   7.149 +        // match objects are 1-based for groups
   7.150 +        std::string final = match[1].str();
   7.151 +        std::string name = match[2].str();
   7.152 +        // Don't try to clean up group names
   7.153 +        if (!from_group)
   7.154 +        {
   7.155 +            final += LLCacheName::buildUsername(name);
   7.156 +        }
   7.157 +        final += match[3].str();
   7.158 +        return final;
   7.159 +    }
   7.160 +    return msg;
   7.161 +}
   7.162 +
   7.163 +const std::string NOT_ONLINE_MSG("User not online - message will be stored and delivered later.");
   7.164 +const std::string NOT_ONLINE_INVENTORY("User not online - inventory has been saved.");
   7.165 +void translate_if_needed(std::string& message)
   7.166 +{
   7.167 +    if (message == NOT_ONLINE_MSG)
   7.168 +    {
   7.169 +        message = LLTrans::getString("not_online_msg");
   7.170 +    }
   7.171 +    else if (message == NOT_ONLINE_INVENTORY)
   7.172 +    {
   7.173 +        message = LLTrans::getString("not_online_inventory");
   7.174 +    }
   7.175 +}
   7.176 +
   7.177 +class LLPostponedIMSystemTipNotification : public LLPostponedNotification
   7.178 +{
   7.179 +protected:
   7.180 +    /* virtual */
   7.181 +    void modifyNotificationParams()
   7.182 +    {
   7.183 +        LLSD payload = mParams.payload;
   7.184 +        payload["SESSION_NAME"] = mName;
   7.185 +        mParams.payload = payload;
   7.186 +    }
   7.187 +};
   7.188 +
   7.189 +class LLPostponedOfferNotification : public LLPostponedNotification
   7.190 +{
   7.191 +protected:
   7.192 +    /* virtual */
   7.193 +    void modifyNotificationParams()
   7.194 +    {
   7.195 +        LLSD substitutions = mParams.substitutions;
   7.196 +        substitutions["NAME"] = mName;
   7.197 +        mParams.substitutions = substitutions;
   7.198 +    }
   7.199 +};
   7.200 +
   7.201 +void inventory_offer_handler(LLOfferInfo* info)
   7.202 +{
   7.203 +    // If muted, don't even go through the messaging stuff.  Just curtail the offer here.
   7.204 +    // Passing in a null UUID handles the case of where you have muted one of your own objects by_name.
   7.205 +    // The solution for STORM-1297 seems to handle the cases where the object is owned by someone else.
   7.206 +    if (LLMuteList::getInstance()->isMuted(info->mFromID, info->mFromName) ||
   7.207 +        LLMuteList::getInstance()->isMuted(LLUUID::null, info->mFromName))
   7.208 +    {
   7.209 +        info->forceResponse(IOR_MUTE);
   7.210 +        return;
   7.211 +    }
   7.212 +
   7.213 +
   7.214 +    bool bAutoAccept(false);
   7.215 +    // Avoid the Accept/Discard dialog if the user so desires. JC
   7.216 +    // <FS:Ansariel> Auto-accept any kind of inventory (FIRE-4128)
   7.217 +    //if (gSavedSettings.getBOOL("AutoAcceptNewInventory")
   7.218 +    //  && (info->mType == LLAssetType::AT_NOTECARD
   7.219 +    //      || info->mType == LLAssetType::AT_LANDMARK
   7.220 +    //      || info->mType == LLAssetType::AT_TEXTURE))
   7.221 +//  if (gSavedSettings.getBOOL("AutoAcceptNewInventory"))
   7.222 +    // </FS:Ansariel> Auto-accept any kind of inventory (FIRE-4128)
   7.223 +// [RLVa:KB]
   7.224 +    // Don't auto-accept give-to-RLV inventory offers
   7.225 +    if ( (gSavedSettings.getBOOL("AutoAcceptNewInventory")) &&
   7.226 +         ( (!rlv_handler_t::isEnabled()) || (!RlvInventory::instance().isGiveToRLVOffer(*info)) ) )
   7.227 +// [/RLVa:KB]
   7.228 +    {
   7.229 +        // For certain types, just accept the items into the inventory,
   7.230 +        // and possibly open them on receipt depending upon "ShowNewInventory".
   7.231 +        bAutoAccept = true;
   7.232 +    }
   7.233 +
   7.234 +    // Strip any SLURL from the message display. (DEV-2754)
   7.235 +    std::string msg = info->mDesc;
   7.236 +    int indx = msg.find(" ( http://slurl.com/secondlife/");
   7.237 +    if(indx == std::string::npos)
   7.238 +    {
   7.239 +        // try to find new slurl host
   7.240 +        indx = msg.find(" ( http://maps.secondlife.com/secondlife/");
   7.241 +    }
   7.242 +    if(indx >= 0)
   7.243 +    {
   7.244 +        LLStringUtil::truncate(msg, indx);
   7.245 +    }
   7.246 +
   7.247 +    LLSD args;
   7.248 +    args["[OBJECTNAME]"] = msg;
   7.249 +
   7.250 +    LLSD payload;
   7.251 +
   7.252 +    // must protect against a NULL return from lookupHumanReadable()
   7.253 +    std::string typestr = ll_safe_string(LLAssetType::lookupHumanReadable(info->mType));
   7.254 +    if (!typestr.empty())
   7.255 +    {
   7.256 +        // human readable matches string name from strings.xml
   7.257 +        // lets get asset type localized name
   7.258 +        args["OBJECTTYPE"] = LLTrans::getString(typestr);
   7.259 +    }
   7.260 +    else
   7.261 +    {
   7.262 +        LL_WARNS("Messaging") << "LLAssetType::lookupHumanReadable() returned NULL - probably bad asset type: " << info->mType << LL_ENDL;
   7.263 +        args["OBJECTTYPE"] = "";
   7.264 +
   7.265 +        // This seems safest, rather than propagating bogosity
   7.266 +        LL_WARNS("Messaging") << "Forcing an inventory-decline for probably-bad asset type." << LL_ENDL;
   7.267 +        info->forceResponse(IOR_DECLINE);
   7.268 +        return;
   7.269 +    }
   7.270 +
   7.271 +    // If mObjectID is null then generate the object_id based on msg to prevent
   7.272 +    // multiple creation of chiclets for same object.
   7.273 +    LLUUID object_id = info->mObjectID;
   7.274 +    if (object_id.isNull())
   7.275 +        object_id.generate(msg);
   7.276 +
   7.277 +    payload["from_id"] = info->mFromID;
   7.278 +    // Needed by LLScriptFloaterManager to bind original notification with 
   7.279 +    // faked for toast one.
   7.280 +    payload["object_id"] = object_id;
   7.281 +    // Flag indicating that this notification is faked for toast.
   7.282 +    payload["give_inventory_notification"] = FALSE;
   7.283 +    args["OBJECTFROMNAME"] = info->mFromName;
   7.284 +    args["NAME"] = info->mFromName;
   7.285 +    if (info->mFromGroup)
   7.286 +    {
   7.287 +        args["NAME_SLURL"] = LLSLURL("group", info->mFromID, "about").getSLURLString();
   7.288 +    }
   7.289 +    else
   7.290 +    {
   7.291 +// [SL:KB] - Patch: UI-Notifications | Checked: 2011-04-11 (Catznip-2.5.0a) | Added: Catznip-2.5.0a
   7.292 +        args["NAME_LABEL"] = LLSLURL("agent", info->mFromID, "completename").getSLURLString();
   7.293 +// [/SL:KB]
   7.294 +        args["NAME_SLURL"] = LLSLURL("agent", info->mFromID, "about").getSLURLString();
   7.295 +    }
   7.296 +    std::string verb = "select?name=" + LLURI::escape(msg);
   7.297 +    args["ITEM_SLURL"] = LLSLURL("inventory", info->mObjectID, verb.c_str()).getSLURLString();
   7.298 +
   7.299 +    LLNotification::Params p;
   7.300 +
   7.301 +    // Object -> Agent Inventory Offer
   7.302 +    if (info->mFromObject && !bAutoAccept)
   7.303 +    {
   7.304 +// [RLVa:KB] - Checked: RLVa-1.2.2
   7.305 +        // Only filter if the object owner is a nearby agent
   7.306 +        if ( (RlvActions::isRlvEnabled()) && (!RlvActions::canShowName(RlvActions::SNC_DEFAULT, info->mFromID)) && (RlvUtil::isNearbyAgent(info->mFromID)) )
   7.307 +        {
   7.308 +            payload["rlv_shownames"] = TRUE;
   7.309 +            args["NAME_SLURL"] = LLSLURL("agent", info->mFromID, "rlvanonym").getSLURLString();
   7.310 +        }
   7.311 +// [/RLVa:KB]
   7.312 +
   7.313 +        // Inventory Slurls don't currently work for non agent transfers, so only display the object name.
   7.314 +        args["ITEM_SLURL"] = msg;
   7.315 +        // Note: sets inventory_task_offer_callback as the callback
   7.316 +        p.substitutions(args).payload(payload).functor.responder(LLNotificationResponderPtr(info));
   7.317 +        info->mPersist = true;
   7.318 +
   7.319 +        // Offers from your own objects need a special notification template.
   7.320 +        p.name = info->mFromID == gAgentID ? "OwnObjectGiveItem" : "ObjectGiveItem";
   7.321 +
   7.322 +        // Pop up inv offer chiclet and let the user accept (keep), or reject (and silently delete) the inventory.
   7.323 +        LLPostponedNotification::add<LLPostponedOfferNotification>(p, info->mFromID, info->mFromGroup == TRUE);
   7.324 +    }
   7.325 +    else // Agent -> Agent Inventory Offer
   7.326 +    {
   7.327 +// [RLVa:KB] - Checked: RLVa-2.0.1
   7.328 +        // Only filter if the offer is from a nearby agent and if there's no open IM session (doesn't necessarily have to be focused)
   7.329 +        bool fRlvCanShowName = (!RlvActions::isRlvEnabled()) ||
   7.330 +            (RlvActions::canShowName(RlvActions::SNC_DEFAULT, info->mFromID)) || (!RlvUtil::isNearbyAgent(info->mFromID)) || (RlvUIEnabler::hasOpenIM(info->mFromID)) || (RlvUIEnabler::hasOpenProfile(info->mFromID));
   7.331 +        if (!fRlvCanShowName)
   7.332 +        {
   7.333 +            payload["rlv_shownames"] = TRUE;
   7.334 +            LLAvatarName av_name;
   7.335 +            if (LLAvatarNameCache::get(info->mFromID, &av_name))
   7.336 +            {
   7.337 +                args["NAME"] = RlvStrings::getAnonym(av_name);
   7.338 +            }
   7.339 +            else
   7.340 +            {
   7.341 +                args["NAME"] = RlvStrings::getAnonym(info->mFromName);
   7.342 +            }
   7.343 +            args["NAME_SLURL"] = LLSLURL("agent", info->mFromID, "rlvanonym").getSLURLString();
   7.344 +        }
   7.345 +// [/RLVa:KB]
   7.346 +
   7.347 +        p.responder = info;
   7.348 +        // Note: sets inventory_offer_callback as the callback
   7.349 +        // *TODO fix memory leak
   7.350 +        // inventory_offer_callback() is not invoked if user received notification and 
   7.351 +        // closes viewer(without responding the notification)
   7.352 +        p.substitutions(args).payload(payload).functor.responder(LLNotificationResponderPtr(info));
   7.353 +        info->mPersist = true;
   7.354 +        // <FS:Ansariel> FIRE-3832: Silent accept/decline of inventory offers
   7.355 +        //p.name = "UserGiveItem";
   7.356 +        p.name = (gSavedSettings.getBOOL("FSUseLegacyInventoryAcceptMessages") ? "UserGiveItemLegacy" : "UserGiveItem");
   7.357 +        // </FS:Ansariel>
   7.358 +        p.offer_from_agent = true;
   7.359 +        
   7.360 +        // Prefetch the item into your local inventory.
   7.361 +        LLInventoryFetchItemsObserver* fetch_item = new LLInventoryFetchItemsObserver(info->mObjectID);
   7.362 +        fetch_item->startFetch();
   7.363 +        if(fetch_item->isFinished())
   7.364 +        {
   7.365 +            fetch_item->done();
   7.366 +        }
   7.367 +        else
   7.368 +        {
   7.369 +            gInventory.addObserver(fetch_item);
   7.370 +        }
   7.371 +        
   7.372 +        // In viewer 2 we're now auto receiving inventory offers and messaging as such (not sending reject messages).
   7.373 +        // <FS:Ansariel> Optional V1-like inventory accept messages
   7.374 +        //info->send_auto_receive_response();
   7.375 +        // Also needs to be send on auto-accept so the item gets into the inventory!
   7.376 +        if (bAutoAccept || !gSavedSettings.getBOOL("FSUseLegacyInventoryAcceptMessages"))
   7.377 +        {
   7.378 +            info->send_auto_receive_response();
   7.379 +        }
   7.380 +        // </FS:Ansariel> Optional V1-like inventory accept messages
   7.381 +
   7.382 +        if (gAgent.isDoNotDisturb()) 
   7.383 +        {
   7.384 +            send_do_not_disturb_message(gMessageSystem, info->mFromID);
   7.385 +        }
   7.386 +
   7.387 +        if (!bAutoAccept) // if we auto accept, do not pester the user
   7.388 +        {
   7.389 +            // Inform user that there is a script floater via toast system
   7.390 +            payload["give_inventory_notification"] = TRUE;
   7.391 +            p.payload = payload;
   7.392 +            LLPostponedNotification::add<LLPostponedOfferNotification>(p, info->mFromID, false);
   7.393 +        }
   7.394 +        // <FS:Ansariel> FIRE-19540: Log auto-accepted inventory to nearby chat
   7.395 +        else if (gSavedSettings.getBOOL("FSLogAutoAcceptInventoryToChat"))
   7.396 +        {
   7.397 +            std::string message_type;
   7.398 +            LLStringUtil::format_map_t chat_args;
   7.399 +            
   7.400 +            chat_args["OBJECT_TYPE"] = (!typestr.empty() ? LLTrans::getString(typestr) : "");
   7.401 +            chat_args["DESC"] = msg;
   7.402 +
   7.403 +            if (info->mFromObject)
   7.404 +            {
   7.405 +                std::string str_pos;
   7.406 +                std::string::size_type idx_start = info->mDesc.rfind(" ( http://");
   7.407 +                std::string::size_type idx_end = info->mDesc.find(" )", idx_start);
   7.408 +                if (idx_start != std::string::npos && idx_end != std::string::npos)
   7.409 +                {
   7.410 +                    LLSLURL url_pos(info->mDesc.substr(idx_start + 3, idx_end - (idx_start + 3)));
   7.411 +                    str_pos = "&slurl=" + LLURI::escape(url_pos.getLocationString());
   7.412 +                }
   7.413 +
   7.414 +                chat_args["OBJECT_NAME"] = "[" + LLSLURL("objectim", info->mObjectID, "").getSLURLString() + "?name=" + LLURI::escape(info->mFromName) + "&owner=" + info->mFromID.asString() + (info->mFromGroup ? "&groupowned=true" : "") + str_pos + " " + info->mFromName + "]";
   7.415 +                message_type = "InvOfferAutoAcceptObject";
   7.416 +            }
   7.417 +            else
   7.418 +            {
   7.419 +                bool fRlvCanShowName = (!RlvActions::isRlvEnabled()) ||
   7.420 +                    (RlvActions::canShowName(RlvActions::SNC_DEFAULT, info->mFromID)) || (!RlvUtil::isNearbyAgent(info->mFromID)) || (RlvUIEnabler::hasOpenIM(info->mFromID)) || (RlvUIEnabler::hasOpenProfile(info->mFromID));
   7.421 +                
   7.422 +                std::string name_slurl = LLSLURL("agent", info->mFromID, (fRlvCanShowName ? "inspect" : "rlvanonym")).getSLURLString();
   7.423 +
   7.424 +                chat_args["USER_NAME"] = name_slurl;
   7.425 +                message_type = "InvOfferAutoAcceptUser";
   7.426 +            }
   7.427 +
   7.428 +            report_to_nearby_chat(LLTrans::getString(message_type, chat_args));
   7.429 +        }
   7.430 +        // </FS:Ansariel>
   7.431 +
   7.432 +        // <FS:Ansariel> Show offered inventory also if auto-accept is enabled (FIRE-5101)
   7.433 +        if (bAutoAccept && gSavedSettings.getBOOL("ShowNewInventory"))
   7.434 +        {
   7.435 +            LLViewerInventoryCategory* catp = NULL;
   7.436 +            catp = (LLViewerInventoryCategory*)gInventory.getCategory(info->mObjectID);
   7.437 +            LLViewerInventoryItem* itemp = NULL;
   7.438 +            if(!catp)
   7.439 +            {
   7.440 +                itemp = (LLViewerInventoryItem*)gInventory.getItem(info->mObjectID);
   7.441 +            }
   7.442 +
   7.443 +            LLOpenAgentOffer* open_agent_offer = new LLOpenAgentOffer(info->mObjectID, info->mFromName);
   7.444 +            open_agent_offer->startFetch();
   7.445 +            if(catp || (itemp && itemp->isFinished()))
   7.446 +            {
   7.447 +                open_agent_offer->done();
   7.448 +            }
   7.449 +            else
   7.450 +            {
   7.451 +                gInventory.addObserver(open_agent_offer);
   7.452 +            }
   7.453 +        }
   7.454 +        // </FS:Ansariel> Show offered inventory also if auto-accept is enabled (FIRE-5101)
   7.455 +    }
   7.456 +
   7.457 +    LLFirstUse::newInventory();
   7.458 +}
   7.459 +
   7.460 +// Callback for name resolution of a god/estate message
   7.461 +static void god_message_name_cb(const LLAvatarName& av_name, LLChat chat, std::string message)
   7.462 +{	
   7.463 +    LLSD args;
   7.464 +    args["NAME"] = av_name.getCompleteName();
   7.465 +    args["MESSAGE"] = message;
   7.466 +    LLNotificationsUtil::add("GodMessage", args);
   7.467 +
   7.468 +    // Treat like a system message and put in chat history.
   7.469 +    chat.mSourceType = CHAT_SOURCE_SYSTEM;
   7.470 +    chat.mText = message;
   7.471 +
   7.472 +    // <FS:Ansariel> [FS communication UI]
   7.473 +    //LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
   7.474 +    FSFloaterNearbyChat* nearby_chat = FSFloaterNearbyChat::getInstance();
   7.475 +    // </FS:Ansariel> [FS communication UI]
   7.476 +    if (nearby_chat)
   7.477 +    {
   7.478 +        nearby_chat->addMessage(chat);
   7.479 +    }
   7.480 +}
   7.481 +
   7.482 +// <FS:Ansariel> FIRE-505: Group name not shown in notification well
   7.483 +static void notification_group_name_cb(const std::string& group_name,
   7.484 +                                        const std::string& sender,
   7.485 +                                        const std::string& subject,
   7.486 +                                        const std::string& message,
   7.487 +                                        const LLSD& payload,
   7.488 +                                        U32 timestamp)
   7.489 +{
   7.490 +    LLAvatarName av_name;
   7.491 +    av_name.fromString(sender);
   7.492 +    LLSD args;
   7.493 +    args["SENDER"] = av_name.getUserNameForDisplay();
   7.494 +    args["GROUP"] = group_name;
   7.495 +    args["SUBJECT"] = subject;
   7.496 +    args["MESSAGE"] = message;
   7.497 +    LLDate notice_date = LLDate(timestamp).notNull() ? LLDate(timestamp) : LLDate::now();
   7.498 +    LLNotifications::instance().add(LLNotification::Params("GroupNotice").substitutions(args).payload(payload).time_stamp(notice_date));
   7.499 +    make_ui_sound("UISndGroupNotice"); // <FS:PP> Group notice sound
   7.500 +}
   7.501 +// </FS:Ansariel>
   7.502 +
   7.503 +// <FS:Ansariel> FIRE-6786: Always show teleport location in teleport offer
   7.504 +static void teleport_region_info_cb(const std::string& slurl, LLSD args, const LLSD& payload, const LLUUID& from_id, const LLUUID& session_id, bool can_user_access_dst_region, bool does_user_require_maturity_increase)
   7.505 +{
   7.506 +    if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC))
   7.507 +    {
   7.508 +        args["POS_SLURL"] = RlvStrings::getString(RLV_STRING_HIDDEN);
   7.509 +    }
   7.510 +    else
   7.511 +    {
   7.512 +        args["POS_SLURL"] = slurl;
   7.513 +    }
   7.514 +
   7.515 +    LLNotification::Params params;
   7.516 +
   7.517 +    if (!can_user_access_dst_region)
   7.518 +    {
   7.519 +        params.name = "TeleportOffered_MaturityBlocked_SLUrl";
   7.520 +        send_simple_im(from_id, LLTrans::getString("TeleportMaturityExceeded"), IM_NOTHING_SPECIAL, session_id);
   7.521 +        send_simple_im(from_id, LLStringUtil::null, IM_LURE_DECLINED, session_id);
   7.522 +    }
   7.523 +    else if (does_user_require_maturity_increase)
   7.524 +    {
   7.525 +        params.name = "TeleportOffered_MaturityExceeded_SLUrl";
   7.526 +    }
   7.527 +    else
   7.528 +    {
   7.529 +        params.name = "TeleportOffered_SLUrl";
   7.530 +        params.functor.name = "TeleportOffered";
   7.531 +    }
   7.532 +
   7.533 +    params.substitutions = args;
   7.534 +    params.payload = payload;
   7.535 +    LLPostponedNotification::add<LLPostponedOfferNotification>(params, from_id, false);
   7.536 +
   7.537 +    LLWindow* viewer_window = gViewerWindow->getWindow();
   7.538 +    static LLCachedControl<bool> sFlashIcon(gSavedSettings, "FSFlashOnMessage");
   7.539 +    if (viewer_window && sFlashIcon)
   7.540 +    {
   7.541 +        viewer_window->flashIcon(5.f);
   7.542 +    }
   7.543 +}
   7.544 +// </FS:Ansariel>
   7.545 +
   7.546 +static bool parse_lure_bucket(const std::string& bucket,
   7.547 +    U64& region_handle,
   7.548 +    LLVector3& pos,
   7.549 +    LLVector3& look_at,
   7.550 +    U8& region_access)
   7.551 +{
   7.552 +    // tokenize the bucket
   7.553 +    typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
   7.554 +    boost::char_separator<char> sep("|", "", boost::keep_empty_tokens);
   7.555 +    tokenizer tokens(bucket, sep);
   7.556 +    tokenizer::iterator iter = tokens.begin();
   7.557 +
   7.558 +    S32 gx, gy, rx, ry, rz, lx, ly, lz;
   7.559 +    try
   7.560 +    {
   7.561 +        gx = boost::lexical_cast<S32>((*(iter)).c_str());
   7.562 +        gy = boost::lexical_cast<S32>((*(++iter)).c_str());
   7.563 +        rx = boost::lexical_cast<S32>((*(++iter)).c_str());
   7.564 +        ry = boost::lexical_cast<S32>((*(++iter)).c_str());
   7.565 +        rz = boost::lexical_cast<S32>((*(++iter)).c_str());
   7.566 +        lx = boost::lexical_cast<S32>((*(++iter)).c_str());
   7.567 +        ly = boost::lexical_cast<S32>((*(++iter)).c_str());
   7.568 +        lz = boost::lexical_cast<S32>((*(++iter)).c_str());
   7.569 +    }
   7.570 +    catch (boost::bad_lexical_cast&)
   7.571 +    {
   7.572 +        LL_WARNS("parse_lure_bucket")
   7.573 +            << "Couldn't parse lure bucket."
   7.574 +            << LL_ENDL;
   7.575 +        return false;
   7.576 +    }
   7.577 +    // Grab region access
   7.578 +    region_access = SIM_ACCESS_MIN;
   7.579 +    if (++iter != tokens.end())
   7.580 +    {
   7.581 +        std::string access_str((*iter).c_str());
   7.582 +        LLStringUtil::trim(access_str);
   7.583 +        if (access_str == "A")
   7.584 +        {
   7.585 +            region_access = SIM_ACCESS_ADULT;
   7.586 +        }
   7.587 +        else if (access_str == "M")
   7.588 +        {
   7.589 +            region_access = SIM_ACCESS_MATURE;
   7.590 +        }
   7.591 +        else if (access_str == "PG")
   7.592 +        {
   7.593 +            region_access = SIM_ACCESS_PG;
   7.594 +        }
   7.595 +    }
   7.596 +
   7.597 +    pos.setVec((F32)rx, (F32)ry, (F32)rz);
   7.598 +    look_at.setVec((F32)lx, (F32)ly, (F32)lz);
   7.599 +
   7.600 +    region_handle = to_region_handle(gx, gy);
   7.601 +    return true;
   7.602 +}
   7.603 +
   7.604 +static void notification_display_name_callback(const LLUUID& id,
   7.605 +    const LLAvatarName& av_name,
   7.606 +    const std::string& name,
   7.607 +    LLSD& substitutions,
   7.608 +    const LLSD& payload)
   7.609 +{
   7.610 +    substitutions["NAME"] = av_name.getDisplayName();
   7.611 +    LLNotificationsUtil::add(name, substitutions, payload);
   7.612 +}
   7.613 +
   7.614 +void LLIMProcessing::processNewMessage(LLUUID from_id,
   7.615 +    BOOL from_group,
   7.616 +    LLUUID to_id,
   7.617 +    U8 offline,
   7.618 +    EInstantMessage dialog, // U8
   7.619 +    LLUUID session_id,
   7.620 +    U32 timestamp,
   7.621 +    std::string agentName,
   7.622 +    std::string message,
   7.623 +    U32 parent_estate_id,
   7.624 +    LLUUID region_id,
   7.625 +    LLVector3 position,
   7.626 +    U8 *binary_bucket,
   7.627 +    S32 binary_bucket_size,
   7.628 +    LLHost &sender)
   7.629 +{
   7.630 +    LLChat chat;
   7.631 +    std::string buffer;
   7.632 +    std::string name = agentName;
   7.633 +
   7.634 +    // NaCl - Antispam Registry
   7.635 +    if (dialog != IM_TYPING_START && dialog != IM_TYPING_STOP &&											// Typing notifications
   7.636 +        !(dialog == IM_NOTHING_SPECIAL && offline == IM_OFFLINE && from_id.notNull() && to_id.notNull()) &&	// Saved offline IMs
   7.637 +        !(dialog == IM_FROM_TASK && offline == IM_OFFLINE)													// Saved offline IMs from objects
   7.638 +        )
   7.639 +    {
   7.640 +        if (NACLAntiSpamRegistry::instance().checkQueue(ANTISPAM_QUEUE_IM, from_id, ANTISPAM_SOURCE_AGENT))
   7.641 +        {
   7.642 +            return;
   7.643 +        }
   7.644 +    }
   7.645 +    // NaCl End
   7.646 +
   7.647 +    // make sure that we don't have an empty or all-whitespace name
   7.648 +    LLStringUtil::trim(name);
   7.649 +    if (name.empty())
   7.650 +    {
   7.651 +        name = LLTrans::getString("Unnamed");
   7.652 +    }
   7.653 +
   7.654 +    // Preserve the unaltered name for use in group notice mute checking.
   7.655 +    std::string original_name = name;
   7.656 +
   7.657 +    // IDEVO convert new-style "Resident" names for display
   7.658 +    name = clean_name_from_im(name, dialog);
   7.659 +
   7.660 +    BOOL is_do_not_disturb = gAgent.isDoNotDisturb();
   7.661 +    BOOL is_autorespond = gAgent.getAutorespond();
   7.662 +    BOOL is_autorespond_nonfriends = gAgent.getAutorespondNonFriends();
   7.663 +    // <FS:PP> FIRE-1245: Option to block/reject teleport offers
   7.664 +    BOOL is_rejecting_tp_offers = gAgent.getRejectTeleportOffers();
   7.665 +    static LLCachedControl<bool> FSDontRejectTeleportOffersFromFriends(gSavedPerAccountSettings, "FSDontRejectTeleportOffersFromFriends");
   7.666 +    // </FS:PP>
   7.667 +    BOOL is_rejecting_group_invites = gAgent.getRejectAllGroupInvites(); // <FS:PP> Option to block/reject all group invites
   7.668 +    BOOL is_rejecting_friendship_requests = gAgent.getRejectFriendshipRequests(); // <FS:PP> FIRE-15233: Automatic friendship request refusal
   7.669 +    BOOL is_autorespond_muted = gSavedPerAccountSettings.getBOOL("FSSendMutedAvatarResponse");
   7.670 +    BOOL is_muted = LLMuteList::getInstance()->isMuted(from_id, name, LLMute::flagTextChat)
   7.671 +        // object IMs contain sender object id in session_id (STORM-1209)
   7.672 +        || (dialog == IM_FROM_TASK && LLMuteList::getInstance()->isMuted(session_id));
   7.673 +    BOOL is_owned_by_me = FALSE;
   7.674 +    BOOL is_friend = (LLAvatarTracker::instance().getBuddyInfo(from_id) == NULL) ? false : true;
   7.675 +    static LLCachedControl<bool> accept_im_from_only_friend(gSavedSettings, "VoiceCallsFriendsOnly");
   7.676 +    //BOOL is_linden = chat.mSourceType != CHAT_SOURCE_OBJECT &&
   7.677 +    //		LLMuteList::getInstance()->isLinden(name); <:FS:TM> Bear compie fix - is_linden not referenced
   7.678 +
   7.679 +    // <FS:PP> FIRE-10500: Autoresponse for (Away)
   7.680 +    static LLCachedControl<bool> FSSendAwayAvatarResponse(gSavedPerAccountSettings, "FSSendAwayAvatarResponse");
   7.681 +    BOOL is_afk = gAgent.getAFK();
   7.682 +    // </FS:PP>
   7.683 +
   7.684 +    chat.mMuted = is_muted;
   7.685 +    chat.mFromID = from_id;
   7.686 +    chat.mFromName = name;
   7.687 +    chat.mSourceType = (from_id.isNull() || (name == std::string(SYSTEM_FROM))) ? CHAT_SOURCE_SYSTEM : CHAT_SOURCE_AGENT;
   7.688 +    
   7.689 +    if (chat.mSourceType == CHAT_SOURCE_SYSTEM)
   7.690 +    { // Translate server message if required (MAINT-6109)
   7.691 +        translate_if_needed(message);
   7.692 +    }
   7.693 +
   7.694 +    LLViewerObject *source = gObjectList.findObject(session_id); //Session ID is probably the wrong thing.
   7.695 +    if (source)
   7.696 +    {
   7.697 +        is_owned_by_me = source->permYouOwner();
   7.698 +    }
   7.699 +
   7.700 +    // NaCl - Newline flood protection
   7.701 +    static LLCachedControl<bool> useAntiSpam(gSavedSettings, "UseAntiSpam");
   7.702 +    if (useAntiSpam && dialog != IM_GROUP_INVITATION)
   7.703 +    {
   7.704 +        bool doCheck = true;
   7.705 +        if (from_id.isNull() || gAgentID == from_id)
   7.706 +        {
   7.707 +            doCheck = false;
   7.708 +        }
   7.709 +        if (doCheck && is_owned_by_me)
   7.710 +        {
   7.711 +            doCheck = false;
   7.712 +        }
   7.713 +        if (doCheck && NACLAntiSpamRegistry::instance().checkNewlineFlood(ANTISPAM_QUEUE_IM, from_id, message))
   7.714 +        {
   7.715 +            return;
   7.716 +        }
   7.717 +    }
   7.718 +    // NaCl End
   7.719 +
   7.720 +    std::string separator_string(": ");
   7.721 +
   7.722 +    LLSD args;
   7.723 +    LLSD payload;
   7.724 +    LLNotification::Params params;
   7.725 +
   7.726 +    switch(dialog)
   7.727 +    { 
   7.728 +    case IM_CONSOLE_AND_CHAT_HISTORY:
   7.729 +        args["MESSAGE"] = message;
   7.730 +        payload["from_id"] = from_id;
   7.731 +
   7.732 +        params.name = "IMSystemMessageTip";
   7.733 +        params.substitutions = args;
   7.734 +        params.payload = payload;
   7.735 +        LLPostponedNotification::add<LLPostponedIMSystemTipNotification>(params, from_id, false);
   7.736 +        break;
   7.737 +
   7.738 +    case IM_NOTHING_SPECIAL:	// p2p IM
   7.739 +        // Don't show dialog, just do IM
   7.740 +        if (!gAgent.isGodlike()
   7.741 +                && gAgent.getRegion()->isPrelude() 
   7.742 +                && to_id.isNull() )
   7.743 +        {
   7.744 +            // do nothing -- don't distract newbies in
   7.745 +            // Prelude with global IMs
   7.746 +        }
   7.747 +// [RLVa:KB] - Checked: RLVa-2.1.0
   7.748 +        else if ( (RlvActions::isRlvEnabled()) && (offline == IM_ONLINE) && (!is_muted) && ((!accept_im_from_only_friend) || (is_friend)) &&
   7.749 +                  (message.length() > 3) && (RLV_CMD_PREFIX == message[0]) && (RlvHandler::instance().processIMQuery(from_id, message)) )
   7.750 +        {
   7.751 +            // Eat the message and do nothing
   7.752 +            return;
   7.753 +        }
   7.754 +// [/RLVa:KB]
   7.755 +//      else if (offline == IM_ONLINE 
   7.756 +//                  && is_do_not_disturb
   7.757 +//                  && from_id.notNull() //not a system message
   7.758 +//                  && to_id.notNull()) //not global message
   7.759 +// [RLVa:KB] - Checked: 2010-11-30 (RLVa-1.3.0)
   7.760 +        // <FS:Ansariel> Only send the busy reponse if either the sender is not
   7.761 +        //               muted OR the sender is muted and we explicitely want
   7.762 +        //               to inform him about that fact.
   7.763 +        else if (offline == IM_ONLINE
   7.764 +                    && (!accept_im_from_only_friend || is_friend)                                    // is friend or accept IMs from friend only disabled
   7.765 +                    && ((is_do_not_disturb && (!is_muted || (is_muted && !is_autorespond_muted))) || // do not disturb
   7.766 +                        (is_autorespond && !is_muted) ||                                             // autorespond everyone
   7.767 +                        (is_autorespond_nonfriends && !is_friend && !is_muted) ||                    // autorespond friends only
   7.768 +                        (is_afk && FSSendAwayAvatarResponse && !is_muted))                           // away
   7.769 +                    && from_id.notNull() //not a system message
   7.770 +                    && to_id.notNull() //not global message
   7.771 +                    && RlvActions::canReceiveIM(from_id))
   7.772 +// [/RLVa:KB]
   7.773 +        {
   7.774 +            // <FS:Ansariel> Log autoresponse notification after initial message
   7.775 +            bool has_session = true;
   7.776 +
   7.777 +            // <FS:Ansariel> Old "do not disturb" message behavior: only send once if session not open
   7.778 +            // Session id will be null if avatar answers from offline IM via email
   7.779 +            std::string response;
   7.780 +            if (!gIMMgr->hasSession(session_id) && session_id.notNull())
   7.781 +            {
   7.782 +            // </FS:Ansariel>
   7.783 +                // <FS:Ansariel> Log autoresponse notification after initial message
   7.784 +                has_session = false;
   7.785 +                // <FS:Ansariel> FS autoresponse feature
   7.786 +                std::string my_name;
   7.787 +                LLAgentUI::buildFullname(my_name);
   7.788 +                if (is_do_not_disturb)
   7.789 +                {
   7.790 +                    response = gSavedPerAccountSettings.getString("DoNotDisturbModeResponse");
   7.791 +                }
   7.792 +                else if (is_autorespond_nonfriends && !is_friend)
   7.793 +                {
   7.794 +                    response = gSavedPerAccountSettings.getString("FSAutorespondNonFriendsResponse");
   7.795 +                }
   7.796 +                else if (is_autorespond)
   7.797 +                {
   7.798 +                    response = gSavedPerAccountSettings.getString("FSAutorespondModeResponse");
   7.799 +                }
   7.800 +                // <FS:PP> FIRE-10500: Autoresponse for (Away)
   7.801 +                else if (is_afk && FSSendAwayAvatarResponse)
   7.802 +                {
   7.803 +                    response = gSavedPerAccountSettings.getString("FSAwayAvatarResponse");
   7.804 +                }
   7.805 +                // </FS:PP>
   7.806 +                else
   7.807 +                {
   7.808 +                    LL_WARNS() << "Unknown auto-response mode" << LL_ENDL;
   7.809 +                }
   7.810 +                pack_instant_message(
   7.811 +                    gMessageSystem,
   7.812 +                    gAgent.getID(),
   7.813 +                    FALSE,
   7.814 +                    gAgent.getSessionID(),
   7.815 +                    from_id,
   7.816 +                    my_name,
   7.817 +                    response,
   7.818 +                    IM_ONLINE,
   7.819 +                    IM_DO_NOT_DISTURB_AUTO_RESPONSE,
   7.820 +                    session_id);
   7.821 +                gAgent.sendReliableMessage();
   7.822 +                // </FS:Ansariel> FS autoresponse feature
   7.823 +            // <FS:Ansariel> Old "do not disturb" message behavior: only send once if session not open
   7.824 +            }
   7.825 +            // </FS:Ansariel>
   7.826 +
   7.827 +            // <FS:Ansariel> checkfor and process reqinfo
   7.828 +            if (has_session)
   7.829 +            {
   7.830 +                message = FSData::getInstance()->processRequestForInfo(from_id,message,name,session_id);
   7.831 +            }
   7.832 +            // </FS:Ansariel>
   7.833 +
   7.834 +            // now store incoming IM in chat history
   7.835 +
   7.836 +            buffer = message;
   7.837 +    
   7.838 +            LL_DEBUGS("Messaging") << "session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL;
   7.839 +
   7.840 +            // <FS:PP> FIRE-10178: Keyword Alerts in group IM do not work unless the group is in the foreground (notification on receipt of IM)
   7.841 +            chat.mText = buffer;
   7.842 +            bool keyword_alert_performed = false;
   7.843 +            if (FSKeywords::getInstance()->chatContainsKeyword(chat, false))
   7.844 +            {
   7.845 +                FSKeywords::notify(chat);
   7.846 +                keyword_alert_performed = true;
   7.847 +            }
   7.848 +            // </FS:PP>
   7.849 +
   7.850 +            // add to IM panel, but do not bother the user
   7.851 +            gIMMgr->addMessage(
   7.852 +                session_id,
   7.853 +                from_id,
   7.854 +                name,
   7.855 +                buffer,
   7.856 +                IM_OFFLINE == offline,
   7.857 +                LLStringUtil::null,
   7.858 +                dialog,
   7.859 +                parent_estate_id,
   7.860 +                region_id,
   7.861 +                position,
   7.862 +                true,
   7.863 +                false,
   7.864 +                keyword_alert_performed);
   7.865 +
   7.866 +            // <FS:Ansariel> Old "do not disturb" message behavior: only send once if session not open
   7.867 +            //if (!gIMMgr->isDNDMessageSend(session_id))
   7.868 +            //{
   7.869 +            //	// return a standard "do not disturb" message, but only do it to online IM
   7.870 +            //	// (i.e. not other auto responses and not store-and-forward IM)
   7.871 +            //	send_do_not_disturb_message(msg, from_id, session_id);
   7.872 +            //	gIMMgr->setDNDMessageSent(session_id, true);
   7.873 +            //}
   7.874 +            // </FS:Ansariel>
   7.875 +
   7.876 +            if (!has_session)
   7.877 +            {
   7.878 +                // <FS:LO> Fire-5389 - "Autoresponse Sent" message added to Firestorm as was in Phoenix
   7.879 +                LLStringUtil::format_map_t args;
   7.880 +                args["MESSAGE"] = response;
   7.881 +
   7.882 +                gIMMgr->addMessage(
   7.883 +                    session_id,
   7.884 +                    gAgentID,
   7.885 +                    LLStringUtil::null, // Pass null value so no name gets prepended
   7.886 +                    LLTrans::getString("IM_autoresponse_sent", args),
   7.887 +                    false,
   7.888 +                    name,
   7.889 +                    IM_NOTHING_SPECIAL,
   7.890 +                    parent_estate_id,
   7.891 +                    region_id,
   7.892 +                    position,
   7.893 +                    false,
   7.894 +                    true
   7.895 +                    );
   7.896 +                // </FS:LO>
   7.897 +
   7.898 +                // <FS:Ansariel> Send inventory item on autoresponse
   7.899 +                LLUUID item_id(gSavedPerAccountSettings.getString("FSAutoresponseItemUUID"));
   7.900 +                if (item_id.notNull())
   7.901 +                {
   7.902 +                    LLInventoryItem* item = dynamic_cast<LLInventoryItem*>(gInventory.getItem(item_id));
   7.903 +                    if (item)
   7.904 +                    {
   7.905 +                        gIMMgr->addMessage(
   7.906 +                                session_id,
   7.907 +                                gAgentID,
   7.908 +                                LLStringUtil::null, // Pass null value so no name gets prepended
   7.909 +                                LLTrans::getString("IM_autoresponse_item_sent", LLSD().with("[ITEM_NAME]", item->getName())),
   7.910 +                                false,
   7.911 +                                name,
   7.912 +                                IM_NOTHING_SPECIAL,
   7.913 +                                parent_estate_id,
   7.914 +                                region_id,
   7.915 +                                position,
   7.916 +                                false,
   7.917 +                                true);
   7.918 +                        LLGiveInventory::doGiveInventoryItem(from_id, item, session_id);
   7.919 +                    }
   7.920 +                }
   7.921 +                // </FS:Ansariel>
   7.922 +            }
   7.923 +        }
   7.924 +        else if (from_id.isNull())
   7.925 +        {
   7.926 +            LLSD args;
   7.927 +            args["MESSAGE"] = message;
   7.928 +            LLNotificationsUtil::add("SystemMessage", args);
   7.929 +        }
   7.930 +        else if (to_id.isNull())
   7.931 +        {
   7.932 +            // Message to everyone from GOD, look up the fullname since
   7.933 +            // server always slams name to legacy names
   7.934 +            LLAvatarNameCache::get(from_id, boost::bind(god_message_name_cb, _2, chat, message));
   7.935 +        }
   7.936 +        else
   7.937 +        {
   7.938 +            // standard message, not from system
   7.939 +            std::string saved;
   7.940 +            if(offline == IM_OFFLINE)
   7.941 +            {
   7.942 +                LLStringUtil::format_map_t args;
   7.943 +                args["[LONG_TIMESTAMP]"] = formatted_time(timestamp);
   7.944 +                saved = LLTrans::getString("Saved_message", args);
   7.945 +            }
   7.946 +            buffer = saved + message;
   7.947 +
   7.948 +            LL_DEBUGS("Messaging") << "session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL;
   7.949 +
   7.950 +            bool mute_im = is_muted;
   7.951 +            if (accept_im_from_only_friend && !is_friend)
   7.952 +            {
   7.953 +                if (!gIMMgr->isNonFriendSessionNotified(session_id))
   7.954 +                {
   7.955 +                    // <FS:Ansariel> Disable this - doesn't make sense it will be skipped by LLIMMgr::addMessage() anyway
   7.956 +                    //std::string message = LLTrans::getString("IM_unblock_only_groups_friends");
   7.957 +                    //gIMMgr->addMessage(session_id, from_id, name, message, IM_OFFLINE == offline);
   7.958 +                    // </FS:Ansariel>
   7.959 +                    gIMMgr->addNotifiedNonFriendSessionID(session_id);
   7.960 +                }
   7.961 +
   7.962 +                mute_im = true;
   7.963 +            }
   7.964 +
   7.965 +// [RLVa:KB] - Checked: 2010-11-30 (RLVa-1.3.0)
   7.966 +            // Don't block offline IMs, or IMs from Lindens
   7.967 +            if ( (rlv_handler_t::isEnabled()) && (offline != IM_OFFLINE) && (!RlvActions::canReceiveIM(from_id)) && (!LLMuteList::getInstance()->isLinden(original_name) ))
   7.968 +            {
   7.969 +                if (!mute_im)
   7.970 +                    RlvUtil::sendBusyMessage(from_id, RlvStrings::getString(RLV_STRING_BLOCKED_RECVIM_REMOTE), session_id);
   7.971 +                message = RlvStrings::getString(RLV_STRING_BLOCKED_RECVIM);
   7.972 +            }
   7.973 +// [/RLVa:KB]
   7.974 +
   7.975 +            if (!mute_im) 
   7.976 +            {
   7.977 +                // checkfor and process reqinfo
   7.978 +                message = FSData::getInstance()->processRequestForInfo(from_id, message, name, session_id);
   7.979 +
   7.980 +                // <FS:PP> FIRE-10178: Keyword Alerts in group IM do not work unless the group is in the foreground (notification on receipt of IM)
   7.981 +                chat.mText = message;
   7.982 +                bool keyword_alert_performed = false;
   7.983 +                if (FSKeywords::getInstance()->chatContainsKeyword(chat, false))
   7.984 +                {
   7.985 +                    FSKeywords::notify(chat);
   7.986 +                    keyword_alert_performed = true;
   7.987 +                }
   7.988 +                // </FS:PP>
   7.989 +
   7.990 +                buffer = saved + message;
   7.991 +
   7.992 +                gIMMgr->addMessage(
   7.993 +                    session_id,
   7.994 +                    from_id,
   7.995 +                    name,
   7.996 +                    buffer,
   7.997 +                    IM_OFFLINE == offline,
   7.998 +                    LLStringUtil::null,
   7.999 +                    dialog,
  7.1000 +                    parent_estate_id,
  7.1001 +                    region_id,
  7.1002 +                    position,
  7.1003 +                    true,
  7.1004 +                    false,
  7.1005 +                    keyword_alert_performed);
  7.1006 +            }
  7.1007 +            else
  7.1008 +            {
  7.1009 +                /*
  7.1010 +                EXT-5099
  7.1011 +                currently there is no way to store in history only...
  7.1012 +                using  LLNotificationsUtil::add will add message to Nearby Chat
  7.1013 +
  7.1014 +                // muted user, so don't start an IM session, just record line in chat
  7.1015 +                // history.  Pretend the chat is from a local agent,
  7.1016 +                // so it will go into the history but not be shown on screen.
  7.1017 +
  7.1018 +                LLSD args;
  7.1019 +                args["MESSAGE"] = buffer;
  7.1020 +                LLNotificationsUtil::add("SystemMessageTip", args);
  7.1021 +                */
  7.1022 +                static LLCachedControl<bool> fsSendMutedAvatarResponse(gSavedPerAccountSettings, "FSSendMutedAvatarResponse");
  7.1023 +                if (fsSendMutedAvatarResponse && (!accept_im_from_only_friend || is_friend))
  7.1024 +                {
  7.1025 +                    std::string my_name;
  7.1026 +                    LLAgentUI::buildFullname(my_name);
  7.1027 +                    std::string response = gSavedPerAccountSettings.getString("FSMutedAvatarResponse");
  7.1028 +                    pack_instant_message(
  7.1029 +                        gMessageSystem,
  7.1030 +                        gAgent.getID(),
  7.1031 +                        FALSE,
  7.1032 +                        gAgent.getSessionID(),
  7.1033 +                        from_id,
  7.1034 +                        my_name,
  7.1035 +                        response,
  7.1036 +                        IM_ONLINE,
  7.1037 +                        IM_DO_NOT_DISTURB_AUTO_RESPONSE,
  7.1038 +                        session_id);
  7.1039 +                    gAgent.sendReliableMessage();
  7.1040 +                }
  7.1041 +
  7.1042 +                // <FS:Ansariel> Don't flash for muted IMs
  7.1043 +                return;
  7.1044 +            }
  7.1045 +        }
  7.1046 +        break;
  7.1047 +
  7.1048 +    case IM_TYPING_START:
  7.1049 +        {
  7.1050 +            LLPointer<LLIMInfo> im_info = new LLIMInfo(gMessageSystem);
  7.1051 +            gIMMgr->processIMTypingStart(im_info);
  7.1052 +        }
  7.1053 +        break;
  7.1054 +
  7.1055 +    case IM_TYPING_STOP:
  7.1056 +        {
  7.1057 +            LLPointer<LLIMInfo> im_info = new LLIMInfo(gMessageSystem);
  7.1058 +            gIMMgr->processIMTypingStop(im_info);
  7.1059 +        }
  7.1060 +        break;
  7.1061 +
  7.1062 +    case IM_MESSAGEBOX:
  7.1063 +        {
  7.1064 +            // This is a block, modeless dialog.
  7.1065 +            args["MESSAGE"] = message;
  7.1066 +            LLNotificationsUtil::add("SystemMessageTip", args);
  7.1067 +        }
  7.1068 +        break;
  7.1069 +    case IM_GROUP_NOTICE:
  7.1070 +    case IM_GROUP_NOTICE_REQUESTED:
  7.1071 +        {
  7.1072 +            LL_INFOS("Messaging") << "Received IM_GROUP_NOTICE message." << LL_ENDL;
  7.1073 +            // Read the binary bucket for more information.
  7.1074 +            struct notice_bucket_header_t
  7.1075 +            {
  7.1076 +                U8 has_inventory;
  7.1077 +                U8 asset_type;
  7.1078 +                LLUUID group_id;
  7.1079 +            };
  7.1080 +            struct notice_bucket_full_t
  7.1081 +            {
  7.1082 +                struct notice_bucket_header_t header;
  7.1083 +                U8 item_name[DB_INV_ITEM_NAME_BUF_SIZE];
  7.1084 +            }* notice_bin_bucket;
  7.1085 +
  7.1086 +            // Make sure the binary bucket is big enough to hold the header 
  7.1087 +            // and a null terminated item name.
  7.1088 +            if ( (binary_bucket_size < (S32)((sizeof(notice_bucket_header_t) + sizeof(U8))))
  7.1089 +                || (binary_bucket[binary_bucket_size - 1] != '\0') )
  7.1090 +            {
  7.1091 +                LL_WARNS("Messaging") << "Malformed group notice binary bucket" << LL_ENDL;
  7.1092 +                // <FS:Ansariel> Don't flash task icon
  7.1093 +                //break;
  7.1094 +                return;
  7.1095 +            }
  7.1096 +
  7.1097 +            // The group notice packet does not have an AgentID.  Obtain one from the name cache.
  7.1098 +            // If last name is "Resident" strip it out so the cache name lookup works.
  7.1099 +            std::string::size_type index = original_name.find(" Resident");
  7.1100 +            if (index != std::string::npos)
  7.1101 +            {
  7.1102 +                original_name = original_name.substr(0, index);
  7.1103 +            }
  7.1104 +
  7.1105 +            std::string legacy_name = gCacheName->buildLegacyName(original_name);
  7.1106 +            LLUUID agent_id = LLAvatarNameCache::findIdByName(legacy_name);
  7.1107 +
  7.1108 +            if (agent_id.isNull())
  7.1109 +            {
  7.1110 +                LL_WARNS("Messaging") << "buildLegacyName returned null while processing " << original_name << LL_ENDL;
  7.1111 +            }
  7.1112 +            else if (LLMuteList::getInstance()->isMuted(agent_id))
  7.1113 +            {
  7.1114 +                // <FS:Ansariel> Don't flash task icon
  7.1115 +                //break;
  7.1116 +                return;
  7.1117 +            }
  7.1118 +
  7.1119 +            notice_bin_bucket = (struct notice_bucket_full_t*) &binary_bucket[0];
  7.1120 +            U8 has_inventory = notice_bin_bucket->header.has_inventory;
  7.1121 +            U8 asset_type = notice_bin_bucket->header.asset_type;
  7.1122 +            LLUUID group_id = notice_bin_bucket->header.group_id;
  7.1123 +            std::string item_name = ll_safe_string((const char*) notice_bin_bucket->item_name);
  7.1124 +
  7.1125 +            // If there is inventory, give the user the inventory offer.
  7.1126 +            LLOfferInfo* info = NULL;
  7.1127 +
  7.1128 +            if (has_inventory)
  7.1129 +            {
  7.1130 +                info = new LLOfferInfo();
  7.1131 +                
  7.1132 +                info->mIM = IM_GROUP_NOTICE;
  7.1133 +                info->mFromID = from_id;
  7.1134 +                info->mFromGroup = from_group;
  7.1135 +                info->mTransactionID = session_id;
  7.1136 +                info->mType = (LLAssetType::EType) asset_type;
  7.1137 +                info->mFolderID = gInventory.findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(info->mType));
  7.1138 +                std::string from_name;
  7.1139 +
  7.1140 +                // <FS:Ansariel> FIRE-17714: Make group notice attachment confirmation localizable
  7.1141 +                //from_name += "A group member named ";
  7.1142 +                //from_name += name;
  7.1143 +                LLStringUtil::format_map_t args;
  7.1144 +                args["NAME"] = name;
  7.1145 +                from_name += LLTrans::getString("InvOfferGroupNoticeName", args);
  7.1146 +                // </FS:Ansariel>
  7.1147 +
  7.1148 +                info->mFromName = from_name;
  7.1149 +                info->mDesc = item_name;
  7.1150 +                info->mHost = sender;
  7.1151 +            }
  7.1152 +            
  7.1153 +            std::string str(message);
  7.1154 +
  7.1155 +            // Tokenize the string.
  7.1156 +            // TODO: Support escaped tokens ("||" -> "|")
  7.1157 +            typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
  7.1158 +            boost::char_separator<char> sep("|", "", boost::keep_empty_tokens);
  7.1159 +            tokenizer tokens(str, sep);
  7.1160 +            tokenizer::iterator iter = tokens.begin();
  7.1161 +
  7.1162 +            std::string subj(*iter++);
  7.1163 +            std::string mes(*iter++);
  7.1164 +
  7.1165 +            // Send the notification down the new path.
  7.1166 +            // For requested notices, we don't want to send the popups.
  7.1167 +            if (dialog != IM_GROUP_NOTICE_REQUESTED)
  7.1168 +            {
  7.1169 +                payload["subject"] = subj;
  7.1170 +                payload["message"] = mes;
  7.1171 +                payload["sender_name"] = name;
  7.1172 +                payload["sender_id"] = agent_id;
  7.1173 +                payload["group_id"] = group_id;
  7.1174 +                payload["inventory_name"] = item_name;
  7.1175 +                payload["received_time"] = LLDate::now();
  7.1176 +                if(info && info->asLLSD())
  7.1177 +                {
  7.1178 +                    payload["inventory_offer"] = info->asLLSD();
  7.1179 +                }
  7.1180 +
  7.1181 +                // <FS:Ansariel> FIRE-505: Group name not shown in notification well
  7.1182 +                //LLSD args;
  7.1183 +                //args["SUBJECT"] = subj;
  7.1184 +                //args["MESSAGE"] = mes;
  7.1185 +                //LLDate notice_date = LLDate(timestamp).notNull() ? LLDate(timestamp) : LLDate::now();
  7.1186 +                //LLNotifications::instance().add(LLNotification::Params("GroupNotice").substitutions(args).payload(payload).time_stamp(notice_date));
  7.1187 +                //make_ui_sound("UISndGroupNotice"); // <FS:PP> Group notice sound
  7.1188 +                if (group_id.isNull())
  7.1189 +                {
  7.1190 +                    LL_WARNS() << "Received group notice with null id!" << LL_ENDL;
  7.1191 +                }
  7.1192 +                gCacheName->get(group_id, true, boost::bind(&notification_group_name_cb, _2, name, subj, mes, payload, timestamp));
  7.1193 +                // </FS:Ansariel>
  7.1194 +            }
  7.1195 +
  7.1196 +            // Also send down the old path for now.
  7.1197 +            if (IM_GROUP_NOTICE_REQUESTED == dialog)
  7.1198 +            {
  7.1199 +                
  7.1200 +                LLPanelGroup::showNotice(subj,mes,group_id,has_inventory,item_name,info);
  7.1201 +            }
  7.1202 +            else
  7.1203 +            {
  7.1204 +                delete info;
  7.1205 +            }
  7.1206 +        }
  7.1207 +        break;
  7.1208 +    case IM_GROUP_INVITATION:
  7.1209 +        {
  7.1210 +            // <FS:Ansariel> FIRE-20385: Don't show group invitation for groups agent is already a member of
  7.1211 +            if (gAgent.isInGroup(from_id) && !gSavedSettings.getBOOL("FSShowJoinedGroupInvitations"))
  7.1212 +            {
  7.1213 +                LL_INFOS("Messaging") << "Received group invitation for group " << from_id << " but we are already a member" << LL_ENDL;
  7.1214 +                return;
  7.1215 +            }
  7.1216 +            // </FS:Ansariel>
  7.1217 +
  7.1218 +            if (!is_muted)
  7.1219 +            {
  7.1220 +                // group is not blocked, but we still need to check agent that sent the invitation
  7.1221 +                // and we have no agent's id
  7.1222 +                // Note: server sends username "first.last".
  7.1223 +                is_muted |= LLMuteList::getInstance()->isMuted(name);
  7.1224 +            }
  7.1225 +            if (is_do_not_disturb || is_muted)
  7.1226 +            {
  7.1227 +                send_do_not_disturb_message(gMessageSystem, from_id);
  7.1228 +            }
  7.1229 +            
  7.1230 +            if (!is_muted)
  7.1231 +            {
  7.1232 +                LL_INFOS("Messaging") << "Received IM_GROUP_INVITATION message." << LL_ENDL;
  7.1233 +                // Read the binary bucket for more information.
  7.1234 +                struct invite_bucket_t
  7.1235 +                {
  7.1236 +                    S32 membership_fee;
  7.1237 +                    LLUUID role_id;
  7.1238 +                }* invite_bucket;
  7.1239 +
  7.1240 +                // Make sure the binary bucket is the correct size.
  7.1241 +                if (binary_bucket_size != sizeof(invite_bucket_t))
  7.1242 +                {
  7.1243 +                    LL_WARNS("Messaging") << "Malformed group invite binary bucket" << LL_ENDL;
  7.1244 +                    // <FS:Ansariel> Don't flash task icon
  7.1245 +                    //break;
  7.1246 +                    return;
  7.1247 +                }
  7.1248 +
  7.1249 +                invite_bucket = (struct invite_bucket_t*) &binary_bucket[0];
  7.1250 +                S32 membership_fee = ntohl(invite_bucket->membership_fee);
  7.1251 +
  7.1252 +                LLSD payload;
  7.1253 +                payload["transaction_id"] = session_id;
  7.1254 +                payload["group_id"] = from_id;
  7.1255 +                payload["name"] = name;
  7.1256 +                payload["message"] = message;
  7.1257 +                payload["fee"] = membership_fee;
  7.1258 +
  7.1259 +                LLSD args;
  7.1260 +                args["MESSAGE"] = message;
  7.1261 +                // we shouldn't pass callback functor since it is registered in LLFunctorRegistration
  7.1262 +
  7.1263 +                // <FS:PP> Option to block/reject all group invites
  7.1264 +                // LLNotificationsUtil::add("JoinGroup", args, payload);
  7.1265 +                if (is_rejecting_group_invites)
  7.1266 +                {
  7.1267 +                    LL_INFOS("Messaging") << "Group invite automatically rejected because of the user setting..." << LL_ENDL;
  7.1268 +                    return;
  7.1269 +                }
  7.1270 +                else
  7.1271 +                {
  7.1272 +                    make_ui_sound("UISndGroupInvitation"); // <FS:PP> Group invitation sound
  7.1273 +                    LLNotificationsUtil::add("JoinGroup", args, payload);
  7.1274 +                }
  7.1275 +                // </FS:PP>
  7.1276 +            }
  7.1277 +            // <FS:Ansariel> Don't flash task icon for group messages from muted senders
  7.1278 +            else
  7.1279 +            {
  7.1280 +                return;
  7.1281 +            }
  7.1282 +            // </FS:Ansariel>
  7.1283 +        }
  7.1284 +        break;
  7.1285 +
  7.1286 +    case IM_INVENTORY_OFFERED:
  7.1287 +    case IM_TASK_INVENTORY_OFFERED:
  7.1288 +        // Someone has offered us some inventory.
  7.1289 +        {
  7.1290 +            LLOfferInfo* info = new LLOfferInfo;
  7.1291 +            if (IM_INVENTORY_OFFERED == dialog)
  7.1292 +            {
  7.1293 +                struct offer_agent_bucket_t
  7.1294 +                {
  7.1295 +                    S8		asset_type;
  7.1296 +                    LLUUID	object_id;
  7.1297 +                }* bucketp;
  7.1298 +
  7.1299 +                if (sizeof(offer_agent_bucket_t) != binary_bucket_size)
  7.1300 +                {
  7.1301 +                    LL_WARNS("Messaging") << "Malformed inventory offer from agent" << LL_ENDL;
  7.1302 +                    delete info;
  7.1303 +                    // <FS:Ansariel> Don't flash task icon
  7.1304 +                    //break;
  7.1305 +                    return; 
  7.1306 +                }
  7.1307 +                bucketp = (struct offer_agent_bucket_t*) &binary_bucket[0];
  7.1308 +                info->mType = (LLAssetType::EType) bucketp->asset_type;
  7.1309 +                info->mObjectID = bucketp->object_id;
  7.1310 +                info->mFromObject = FALSE;
  7.1311 +            }
  7.1312 +            else // IM_TASK_INVENTORY_OFFERED
  7.1313 +            {
  7.1314 +                if (sizeof(S8) != binary_bucket_size)
  7.1315 +                {
  7.1316 +                    LL_WARNS("Messaging") << "Malformed inventory offer from object" << LL_ENDL;
  7.1317 +                    delete info;
  7.1318 +                    // <FS:Ansariel> Don't flash task icon
  7.1319 +                    //break;
  7.1320 +                    return; 
  7.1321 +                }
  7.1322 +                info->mType = (LLAssetType::EType) binary_bucket[0];
  7.1323 +                info->mObjectID = LLUUID::null;
  7.1324 +                info->mFromObject = TRUE;
  7.1325 +            }
  7.1326 +
  7.1327 +            info->mIM = dialog;
  7.1328 +            info->mFromID = from_id;
  7.1329 +            info->mFromGroup = from_group;
  7.1330 +            info->mTransactionID = session_id;
  7.1331 +            info->mFolderID = gInventory.findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(info->mType));
  7.1332 +
  7.1333 +            info->mFromName = name;
  7.1334 +            info->mDesc = message;
  7.1335 +            info->mHost = sender;
  7.1336 +            //if (((is_do_not_disturb && !is_owned_by_me) || is_muted))
  7.1337 +            if (is_muted)
  7.1338 +            {
  7.1339 +                // Prefetch the offered item so that it can be discarded by the appropriate observer. (EXT-4331)
  7.1340 +                LLInventoryFetchItemsObserver* fetch_item = new LLInventoryFetchItemsObserver(info->mObjectID);
  7.1341 +                fetch_item->startFetch();
  7.1342 +                delete fetch_item;
  7.1343 +
  7.1344 +                // Same as closing window
  7.1345 +                info->forceResponse(IOR_DECLINE);
  7.1346 +            }
  7.1347 +            // old logic: busy mode must not affect interaction with objects (STORM-565)
  7.1348 +            // new logic: inventory offers from in-world objects should be auto-declined (CHUI-519)
  7.1349 +            else if (is_do_not_disturb && dialog == IM_TASK_INVENTORY_OFFERED)
  7.1350 +            {
  7.1351 +                // Until throttling is implemented, do not disturb mode should reject inventory instead of silently
  7.1352 +                // accepting it.  SEE SL-39554
  7.1353 +                info->forceResponse(IOR_DECLINE);
  7.1354 +            }
  7.1355 +            else
  7.1356 +            {
  7.1357 +                inventory_offer_handler(info);
  7.1358 +            }
  7.1359 +        }
  7.1360 +        break;
  7.1361 +
  7.1362 +    case IM_INVENTORY_ACCEPTED:
  7.1363 +    {
  7.1364 +//      args["NAME"] = LLSLURL("agent", from_id, "completename").getSLURLString();;
  7.1365 +//      args["ORIGINAL_NAME"] = original_name;
  7.1366 +// [RLVa:KB] - Checked: RLVa-1.2.2
  7.1367 +        // Only anonymize the name if the agent is nearby, there isn't an open IM session to them and their profile isn't open
  7.1368 +        LLAvatarName av_name;
  7.1369 +        bool fRlvCanShowName = (!RlvActions::isRlvEnabled()) ||
  7.1370 +            (RlvActions::canShowName(RlvActions::SNC_DEFAULT, from_id)) || (!RlvUtil::isNearbyAgent(from_id)) || (RlvUIEnabler::hasOpenProfile(from_id)) || (RlvUIEnabler::hasOpenIM(from_id));
  7.1371 +        args["NAME"] = LLSLURL("agent", from_id, (fRlvCanShowName) ? "completename" : "rlvanonym").getSLURLString();;
  7.1372 +        args["ORIGINAL_NAME"] = fRlvCanShowName ? original_name : (LLAvatarNameCache::get(from_id, &av_name) ? RlvStrings::getAnonym(av_name) : RlvStrings::getAnonym(original_name));
  7.1373 +// [/RLVa:KB]
  7.1374 +        LLSD payload;
  7.1375 +        payload["from_id"] = from_id;
  7.1376 +        // Passing the "SESSION_NAME" to use it for IM notification logging
  7.1377 +        // in LLTipHandler::processNotification(). See STORM-941.
  7.1378 +        payload["SESSION_NAME"] = name;
  7.1379 +        LLNotificationsUtil::add("InventoryAccepted", args, payload);
  7.1380 +        break;
  7.1381 +    }
  7.1382 +    case IM_INVENTORY_DECLINED:
  7.1383 +    {
  7.1384 +//      args["NAME"] = LLSLURL("agent", from_id, "completename").getSLURLString();;
  7.1385 +// [RLVa:KB] - Checked: RLVa-1.2.2
  7.1386 +        // Only anonymize the name if the agent is nearby, there isn't an open IM session to them and their profile isn't open
  7.1387 +        bool fRlvCanShowName = (!RlvActions::isRlvEnabled()) ||
  7.1388 +            (RlvActions::canShowName(RlvActions::SNC_DEFAULT, from_id)) || (!RlvUtil::isNearbyAgent(from_id)) || (RlvUIEnabler::hasOpenProfile(from_id)) || (RlvUIEnabler::hasOpenIM(from_id));
  7.1389 +        args["NAME"] = LLSLURL("agent", from_id, (fRlvCanShowName) ? "completename" : "rlvanonym").getSLURLString();;
  7.1390 +// [/RLVa:KB]
  7.1391 +        LLSD payload;
  7.1392 +        payload["from_id"] = from_id;
  7.1393 +        LLNotificationsUtil::add("InventoryDeclined", args, payload);
  7.1394 +        break;
  7.1395 +    }
  7.1396 +    // TODO: _DEPRECATED suffix as part of vote removal - DEV-24856
  7.1397 +    case IM_GROUP_VOTE:
  7.1398 +        {
  7.1399 +            LL_WARNS("Messaging") << "Received IM: IM_GROUP_VOTE_DEPRECATED" << LL_ENDL;
  7.1400 +        }
  7.1401 +        break;
  7.1402 +
  7.1403 +    case IM_GROUP_ELECTION_DEPRECATED:
  7.1404 +    {
  7.1405 +        LL_WARNS("Messaging") << "Received IM: IM_GROUP_ELECTION_DEPRECATED" << LL_ENDL;
  7.1406 +    }
  7.1407 +    break;
  7.1408 +    
  7.1409 +    case IM_FROM_TASK:
  7.1410 +        {
  7.1411 +
  7.1412 +            if (is_do_not_disturb && !is_owned_by_me)
  7.1413 +            {
  7.1414 +                return;
  7.1415 +            }
  7.1416 +
  7.1417 +            // <FS:PP> FIRE-6406: Feature to disable Object Return notification
  7.1418 +            static LLCachedControl<bool> FSDisableReturnObjectNotification(gSavedSettings, "FSDisableReturnObjectNotification");
  7.1419 +            if (FSDisableReturnObjectNotification)
  7.1420 +            {
  7.1421 +                if (message.find("been returned to your inventory") != -1)
  7.1422 +                {
  7.1423 +                    return;
  7.1424 +                }
  7.1425 +            }
  7.1426 +            // </FS:PP>
  7.1427 +
  7.1428 +            // Build a link to open the object IM info window.
  7.1429 +            std::string location = ll_safe_string((char*)binary_bucket, binary_bucket_size - 1);
  7.1430 +
  7.1431 +            if (session_id.notNull())
  7.1432 +            {
  7.1433 +                chat.mFromID = session_id;
  7.1434 +            }
  7.1435 +            else
  7.1436 +            {
  7.1437 +                // This message originated on a region without the updated code for task id and slurl information.
  7.1438 +                // We just need a unique ID for this object that isn't the owner ID.
  7.1439 +                // If it is the owner ID it will overwrite the style that contains the link to that owner's profile.
  7.1440 +                // This isn't ideal - it will make 1 style for all objects owned by the the same person/group.
  7.1441 +                // This works because the only thing we can really do in this case is show the owner name and link to their profile.
  7.1442 +                chat.mFromID = from_id ^ gAgent.getSessionID();
  7.1443 +            }
  7.1444 +
  7.1445 +            chat.mSourceType = CHAT_SOURCE_OBJECT;
  7.1446 +            chat.mChatType = CHAT_TYPE_IM;
  7.1447 +
  7.1448 +            // To conclude that the source type of message is CHAT_SOURCE_SYSTEM it's not
  7.1449 +            // enough to check only from name (i.e. fromName = "Second Life"). For example
  7.1450 +            // source type of messages from objects called "Second Life" should not be CHAT_SOURCE_SYSTEM.
  7.1451 +            bool chat_from_system = (SYSTEM_FROM == name) && region_id.isNull() && position.isNull();
  7.1452 +            if(chat_from_system)
  7.1453 +            {
  7.1454 +                // System's UUID is NULL (fixes EXT-4766)
  7.1455 +                chat.mFromID = LLUUID::null;
  7.1456 +                chat.mSourceType = CHAT_SOURCE_SYSTEM;
  7.1457 +            }
  7.1458 +
  7.1459 +            // IDEVO Some messages have embedded resident names
  7.1460 +            message = clean_name_from_task_im(message, from_group);
  7.1461 +
  7.1462 +            LLSD query_string;
  7.1463 +            query_string["owner"] = from_id;
  7.1464 +// [RLVa:KB] - Checked: RLVa-1.2.0
  7.1465 +            if (RlvActions::isRlvEnabled())
  7.1466 +            {
  7.1467 +                // NOTE: the chat message itself will be filtered in LLNearbyChatHandler::processChat()
  7.1468 +                if ( (!RlvActions::canShowName(RlvActions::SNC_DEFAULT)) && (!from_group) && (RlvUtil::isNearbyAgent(from_id)) )
  7.1469 +                {
  7.1470 +                    query_string["rlv_shownames"] = TRUE;
  7.1471 +
  7.1472 +                    RlvUtil::filterNames(name);
  7.1473 +                    chat.mFromName = name;
  7.1474 +                }
  7.1475 +                if (!RlvActions::canShowLocation())
  7.1476 +                {
  7.1477 +                    std::string::size_type idxPos = location.find('/');
  7.1478 +                    if ( (std::string::npos != idxPos) && (RlvUtil::isNearbyRegion(location.substr(0, idxPos))) )
  7.1479 +                        location = RlvStrings::getString(RLV_STRING_HIDDEN_REGION);
  7.1480 +                }
  7.1481 +            }
  7.1482 +// [/RLVa:KB]
  7.1483 +            query_string["slurl"] = location;
  7.1484 +            query_string["name"] = name;
  7.1485 +            if (from_group)
  7.1486 +            {
  7.1487 +                query_string["groupowned"] = "true";
  7.1488 +            }	
  7.1489 +
  7.1490 +//          chat.mURL = LLSLURL("objectim", session_id, "").getSLURLString();
  7.1491 +// [SL:KB] - Checked: 2010-11-02 (RLVa-1.2.2a) | Added: RLVa-1.2.2a
  7.1492 +            chat.mURL = LLSLURL("objectim", session_id, LLURI::mapToQueryString(query_string)).getSLURLString();
  7.1493 +// [/SL:KB]
  7.1494 +            chat.mText = message;
  7.1495 +
  7.1496 +            // <FS:PP> FIRE-10178: Keyword Alerts in group IM do not work unless the group is in the foreground (notification on receipt of Task IM)
  7.1497 +            if (FSKeywords::getInstance()->chatContainsKeyword(chat, true))
  7.1498 +            {
  7.1499 +                FSKeywords::notify(chat);
  7.1500 +            }
  7.1501 +            // </FS:PP>
  7.1502 +
  7.1503 +            // Note: lie to Nearby Chat, pretending that this is NOT an IM, because
  7.1504 +            // IMs from obejcts don't open IM sessions.
  7.1505 +            // <FS:Ansariel> [FS communication UI]
  7.1506 +            //LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
  7.1507 +            FSFloaterNearbyChat* nearby_chat = FSFloaterNearbyChat::getInstance();
  7.1508 +            // </FS:Ansariel> [FS communication UI]
  7.1509 +            if(!chat_from_system && nearby_chat)
  7.1510 +            {
  7.1511 +                chat.mOwnerID = from_id;
  7.1512 +                LLSD args;
  7.1513 +                args["slurl"] = location;
  7.1514 +
  7.1515 +                // Look for IRC-style emotes here so object name formatting is correct
  7.1516 +                // <FS:Ansariel> Consolidate IRC /me prefix checks
  7.1517 +                //std::string prefix = message.substr(0, 4);
  7.1518 +                //if (prefix == "/me " || prefix == "/me'")
  7.1519 +                if (is_irc_me_prefix(message))
  7.1520 +                // </FS:Ansariel>
  7.1521 +                {
  7.1522 +                    chat.mChatStyle = CHAT_STYLE_IRC;
  7.1523 +                }
  7.1524 +
  7.1525 +                LLNotificationsUI::LLNotificationManager::instance().onChat(chat, args);
  7.1526 +            }
  7.1527 +
  7.1528 +
  7.1529 +            //Object IMs send with from name: 'Second Life' need to be displayed also in notification toasts (EXT-1590)
  7.1530 +            if (!chat_from_system) break;
  7.1531 +            
  7.1532 +            LLSD substitutions;
  7.1533 +            substitutions["NAME"] = name;
  7.1534 +            substitutions["MSG"] = message;
  7.1535 +
  7.1536 +            LLSD payload;
  7.1537 +            payload["object_id"] = session_id;
  7.1538 +            payload["owner_id"] = from_id;
  7.1539 +            payload["from_id"] = from_id;
  7.1540 +            payload["slurl"] = location;
  7.1541 +            payload["name"] = name;
  7.1542 +
  7.1543 +            if (from_group)
  7.1544 +            {
  7.1545 +                payload["group_owned"] = "true";
  7.1546 +            }
  7.1547 +
  7.1548 +            LLNotificationsUtil::add("ServerObjectMessage", substitutions, payload);
  7.1549 +        }
  7.1550 +        break;
  7.1551 +
  7.1552 +    case IM_SESSION_SEND:		// ad-hoc or group IMs
  7.1553 +
  7.1554 +        // Only show messages if we have a session open (which
  7.1555 +        // should happen after you get an "invitation"
  7.1556 +// [SL:KB] - Patch: Chat-GroupSnooze | Checked: 2012-06-16 (Catznip-3.3)
  7.1557 +        //if ( !gIMMgr->hasSession(session_id) )
  7.1558 +        if ( (!gIMMgr->hasSession(session_id)) &&
  7.1559 +             ( (!gAgent.isInGroup(session_id)) || (!gIMMgr->checkSnoozeExpiration(session_id)) || LLAvatarActions::isBlocked(from_id) || (!gIMMgr->restoreSnoozedSession(session_id)) ) )
  7.1560 +// [/SL:KB]
  7.1561 +        {
  7.1562 +            return;
  7.1563 +        }
  7.1564 +
  7.1565 +        else if (offline == IM_ONLINE && is_do_not_disturb)
  7.1566 +        {
  7.1567 +
  7.1568 +            // return a standard "do not disturb" message, but only do it to online IM 
  7.1569 +            // (i.e. not other auto responses and not store-and-forward IM)
  7.1570 +            if (!gIMMgr->hasSession(session_id))
  7.1571 +            {
  7.1572 +                // if there is not a panel for this conversation (i.e. it is a new IM conversation
  7.1573 +                // initiated by the other party) then...
  7.1574 +                send_do_not_disturb_message(gMessageSystem, from_id, session_id);
  7.1575 +            }
  7.1576 +
  7.1577 +            // now store incoming IM in chat history
  7.1578 +
  7.1579 +            buffer = message;
  7.1580 +    
  7.1581 +            LL_DEBUGS("Messaging") << "message in dnd; session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL;
  7.1582 +
  7.1583 +            // add to IM panel, but do not bother the user
  7.1584 +            gIMMgr->addMessage(
  7.1585 +                session_id,
  7.1586 +                from_id,
  7.1587 +                name,
  7.1588 +                buffer,
  7.1589 +                IM_OFFLINE == offline,
  7.1590 +                ll_safe_string((char*)binary_bucket),
  7.1591 +                IM_SESSION_INVITE,
  7.1592 +                parent_estate_id,
  7.1593 +                region_id,
  7.1594 +                position,
  7.1595 +                true);
  7.1596 +        }
  7.1597 +        else
  7.1598 +        {
  7.1599 +
  7.1600 +            // <FS:PP> FIRE-10178: Keyword Alerts in group IM do not work unless the group is in the foreground (notification on receipt of IM)
  7.1601 +            chat.mText = message;
  7.1602 +            bool keyword_alert_performed = false;
  7.1603 +            if (FSKeywords::getInstance()->chatContainsKeyword(chat, false))
  7.1604 +            {
  7.1605 +                FSKeywords::notify(chat);
  7.1606 +                keyword_alert_performed = true;
  7.1607 +            }
  7.1608 +            // </FS:PP>
  7.1609 +
  7.1610 +            // standard message, not from system
  7.1611 +            std::string saved;
  7.1612 +            if(offline == IM_OFFLINE)
  7.1613 +            {
  7.1614 +                saved = llformat("(Saved %s) ", formatted_time(timestamp).c_str());
  7.1615 +            }
  7.1616 +
  7.1617 +            buffer = saved + message;
  7.1618 +
  7.1619 +            LL_DEBUGS("Messaging") << "standard message session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL;
  7.1620 +
  7.1621 +            gIMMgr->addMessage(
  7.1622 +                session_id,
  7.1623 +                from_id,
  7.1624 +                name,
  7.1625 +                buffer,
  7.1626 +                IM_OFFLINE == offline,
  7.1627 +                ll_safe_string((char*)binary_bucket),
  7.1628 +                IM_SESSION_INVITE,
  7.1629 +                parent_estate_id,
  7.1630 +                region_id,
  7.1631 +                position,
  7.1632 +                true,
  7.1633 +                false,
  7.1634 +                keyword_alert_performed);
  7.1635 +        }
  7.1636 +        break;
  7.1637 +
  7.1638 +    case IM_FROM_TASK_AS_ALERT:
  7.1639 +        if (is_do_not_disturb && !is_owned_by_me)
  7.1640 +        {
  7.1641 +            return;
  7.1642 +        }
  7.1643 +        {
  7.1644 +            // Construct a viewer alert for this message.
  7.1645 +            args["NAME"] = name;
  7.1646 +            args["MESSAGE"] = message;
  7.1647 +            LLNotificationsUtil::add("ObjectMessage", args);
  7.1648 +        }
  7.1649 +        break;
  7.1650 +    case IM_DO_NOT_DISTURB_AUTO_RESPONSE:
  7.1651 +        if (is_muted)
  7.1652 +        {
  7.1653 +            LL_DEBUGS("Messaging") << "Ignoring do-not-disturb response from " << from_id << LL_ENDL;
  7.1654 +            return;
  7.1655 +        }
  7.1656 +        else
  7.1657 +        {
  7.1658 +            // <FS:Ansariel> FIRE-12908: Add busy response indicator back to busy messages
  7.1659 +            //gIMMgr->addMessage(session_id, from_id, name, message);
  7.1660 +            buffer = llformat("(%s): %s", LLTrans::getString("BusyResponse").c_str(), message.c_str());
  7.1661 +            gIMMgr->addMessage(session_id, from_id, name, buffer);
  7.1662 +            // </FS:Ansariel>
  7.1663 +        }
  7.1664 +        break;
  7.1665 +        
  7.1666 +    case IM_LURE_USER:
  7.1667 +    case IM_TELEPORT_REQUEST:
  7.1668 +        {
  7.1669 +// [RLVa:KB] - Checked: RLVa-1.4.9
  7.1670 +            // If we auto-accept the offer/request then this will override DnD status (but we'll still let the other party know later)
  7.1671 +            bool fRlvAutoAccept = (rlv_handler_t::isEnabled()) &&
  7.1672 +                ( ((IM_LURE_USER == dialog) && (RlvActions::autoAcceptTeleportOffer(from_id))) ||
  7.1673 +                  ((IM_TELEPORT_REQUEST == dialog) && (RlvActions::autoAcceptTeleportRequest(from_id))) );
  7.1674 +// [/RLVa:KB]
  7.1675 +
  7.1676 +            if (is_muted)
  7.1677 +            { 
  7.1678 +                return;
  7.1679 +            }
  7.1680 +
  7.1681 +            // <FS:PP> FIRE-1245: Option to block/reject teleport offers
  7.1682 +            //else if (gSavedSettings.getBOOL("VoiceCallsFriendsOnly") && (LLAvatarTracker::instance().getBuddyInfo(from_id) == NULL))
  7.1683 +            //{
  7.1684 +            //	return;
  7.1685 +            //}
  7.1686 +            else if ( (is_rejecting_tp_offers && (!FSDontRejectTeleportOffersFromFriends || (FSDontRejectTeleportOffersFromFriends && !is_friend))) && (!fRlvAutoAccept) )
  7.1687 +            {
  7.1688 +                send_rejecting_tp_offers_message(gMessageSystem, from_id);
  7.1689 +            }
  7.1690 +            // </FS:PP>
  7.1691 +            else
  7.1692 +            {
  7.1693 +//              if (is_do_not_disturb)
  7.1694 +// [RLVa:KB] - Checked: RLVa-1.4.9
  7.1695 +                if ( (is_do_not_disturb) && (!fRlvAutoAccept) )
  7.1696 +// [/RLVa:KB]
  7.1697 +                {
  7.1698 +                    send_do_not_disturb_message(gMessageSystem, from_id);
  7.1699 +                }
  7.1700 +
  7.1701 +                LLVector3 pos, look_at;
  7.1702 +                U64 region_handle(0);
  7.1703 +                U8 region_access(SIM_ACCESS_MIN);
  7.1704 +                std::string region_info = ll_safe_string((char*)binary_bucket, binary_bucket_size);
  7.1705 +                std::string region_access_str = LLStringUtil::null;
  7.1706 +                std::string region_access_icn = LLStringUtil::null;
  7.1707 +                std::string region_access_lc  = LLStringUtil::null;
  7.1708 +
  7.1709 +                bool canUserAccessDstRegion = true;
  7.1710 +                bool doesUserRequireMaturityIncrease = false;
  7.1711 +
  7.1712 +                // Do not parse the (empty) lure bucket for TELEPORT_REQUEST
  7.1713 +                if (IM_TELEPORT_REQUEST != dialog && parse_lure_bucket(region_info, region_handle, pos, look_at, region_access))
  7.1714 +                {
  7.1715 +                    region_access_str = LLViewerRegion::accessToString(region_access);
  7.1716 +                    region_access_icn = LLViewerRegion::getAccessIcon(region_access);
  7.1717 +                    region_access_lc  = region_access_str;
  7.1718 +                    LLStringUtil::toLower(region_access_lc);
  7.1719 +
  7.1720 +                    if (!gAgent.isGodlike())
  7.1721 +                    {
  7.1722 +                        switch (region_access)
  7.1723 +                        {
  7.1724 +                        case SIM_ACCESS_MIN :
  7.1725 +                        case SIM_ACCESS_PG :
  7.1726 +                            break;
  7.1727 +                        case SIM_ACCESS_MATURE :
  7.1728 +                            if (gAgent.isTeen())
  7.1729 +                            {
  7.1730 +                                canUserAccessDstRegion = false;
  7.1731 +                            }
  7.1732 +                            else if (gAgent.prefersPG())
  7.1733 +                            {
  7.1734 +                                doesUserRequireMaturityIncrease = true;
  7.1735 +                            }
  7.1736 +                            break;
  7.1737 +                        case SIM_ACCESS_ADULT :
  7.1738 +                            if (!gAgent.isAdult())
  7.1739 +                            {
  7.1740 +                                canUserAccessDstRegion = false;
  7.1741 +                            }
  7.1742 +                            else if (!gAgent.prefersAdult())
  7.1743 +                            {
  7.1744 +                                doesUserRequireMaturityIncrease = true;
  7.1745 +                            }
  7.1746 +                            break;
  7.1747 +                        default :
  7.1748 +                            llassert(0);
  7.1749 +                            break;
  7.1750 +                        }
  7.1751 +                    }
  7.1752 +                }
  7.1753 +
  7.1754 +// [RLVa:KB] - Checked: RLVa-1.4.9
  7.1755 +                if (rlv_handler_t::isEnabled())
  7.1756 +                {
  7.1757 +                    if ( ((IM_LURE_USER == dialog) && (!RlvActions::canAcceptTpOffer(from_id))) ||
  7.1758 +                         ((IM_TELEPORT_REQUEST == dialog) && (!RlvActions::canAcceptTpRequest(from_id))) )
  7.1759 +                    {
  7.1760 +                        RlvUtil::sendBusyMessage(from_id, RlvStrings::getString(RLV_STRING_BLOCKED_TPLUREREQ_REMOTE));
  7.1761 +                        if (is_do_not_disturb)
  7.1762 +                            send_do_not_disturb_message(gMessageSystem, from_id);
  7.1763 +                        return;
  7.1764 +                    }
  7.1765 +
  7.1766 +                    // Censor message if: 1) restricted from receiving IMs from the sender, or 2) teleport offer/request and @showloc=n restricted
  7.1767 +                    if ( (!RlvActions::canReceiveIM(from_id)) || 
  7.1768 +                         ((gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) && (IM_LURE_USER == dialog || IM_TELEPORT_REQUEST == dialog)) )
  7.1769 +                    {
  7.1770 +                        message = RlvStrings::getString(RLV_STRING_HIDDEN);
  7.1771 +                    }
  7.1772 +                }
  7.1773 +// [/RLVa:KB]
  7.1774 +
  7.1775 +                LLSD args;
  7.1776 +                // *TODO: Translate -> [FIRST] [LAST] (maybe)
  7.1777 +// [SL:KB] - Patch: UI-Notifications | Checked: 2011-04-11 (Catznip-2.5.0a) | Added: Catznip-2.5.0a
  7.1778 +                args["NAME_LABEL"] = LLSLURL("agent", from_id, "completename").getSLURLString();
  7.1779 +// [/SL:KB]
  7.1780 +                args["NAME_SLURL"] = LLSLURL("agent", from_id, "about").getSLURLString();
  7.1781 +                args["MESSAGE"] = message;
  7.1782 +                args["MATURITY_STR"] = region_access_str;
  7.1783 +                args["MATURITY_ICON"] = region_access_icn;
  7.1784 +                args["REGION_CONTENT_MATURITY"] = region_access_lc;
  7.1785 +                LLSD payload;
  7.1786 +                payload["from_id"] = from_id;
  7.1787 +                payload["lure_id"] = session_id;
  7.1788 +                payload["godlike"] = FALSE;
  7.1789 +                payload["region_maturity"] = region_access;
  7.1790 +
  7.1791 +                // <FS:Ansariel> FIRE-6786: Always show teleport location in teleport offer
  7.1792 +                if (dialog == IM_LURE_USER && (!rlv_handler_t::isEnabled() || !fRlvAutoAccept) && LLGridManager::instance().isInSecondLife())
  7.1793 +                {
  7.1794 +                    LLVector3d pos_global = from_region_handle(region_handle);
  7.1795 +                    pos_global += LLVector3d(pos);
  7.1796 +                    LLLandmarkActions::getSLURLfromPosGlobal(pos_global, boost::bind(&teleport_region_info_cb, _1, args, payload, from_id, session_id, canUserAccessDstRegion, doesUserRequireMaturityIncrease));
  7.1797 +                    return;
  7.1798 +                }
  7.1799 +                // </FS:Ansariel>
  7.1800 +
  7.1801 +                if (!canUserAccessDstRegion)
  7.1802 +                {
  7.1803 +                    LLNotification::Params params("TeleportOffered_MaturityBlocked");
  7.1804 +                    params.substitutions = args;
  7.1805 +                    params.payload = payload;
  7.1806 +                    LLPostponedNotification::add<LLPostponedOfferNotification>(	params, from_id, false);
  7.1807 +                    send_simple_im(from_id, LLTrans::getString("TeleportMaturityExceeded"), IM_NOTHING_SPECIAL, session_id);
  7.1808 +                    send_simple_im(from_id, LLStringUtil::null, IM_LURE_DECLINED, session_id);
  7.1809 +                }
  7.1810 +                else if (doesUserRequireMaturityIncrease)
  7.1811 +                {
  7.1812 +                    LLNotification::Params params("TeleportOffered_MaturityExceeded");
  7.1813 +                    params.substitutions = args;
  7.1814 +                    params.payload = payload;
  7.1815 +                    LLPostponedNotification::add<LLPostponedOfferNotification>(	params, from_id, false);
  7.1816 +                }
  7.1817 +                else
  7.1818 +                {
  7.1819 +                    LLNotification::Params params;
  7.1820 +                    if (IM_LURE_USER == dialog)
  7.1821 +                    {
  7.1822 +                        params.name = "TeleportOffered";
  7.1823 +                        params.functor.name = "TeleportOffered";
  7.1824 +                    }
  7.1825 +                    else if (IM_TELEPORT_REQUEST == dialog)
  7.1826 +                    {
  7.1827 +                        params.name = "TeleportRequest";
  7.1828 +                        params.functor.name = "TeleportRequest";
  7.1829 +                    }
  7.1830 +
  7.1831 +                    params.substitutions = args;
  7.1832 +                    params.payload = payload;
  7.1833 +
  7.1834 +// [RLVa:KB] - Checked: RLVa-1.4.9
  7.1835 +                    if (fRlvAutoAccept)
  7.1836 +                    {
  7.1837 +                        if (IM_LURE_USER == dialog)
  7.1838 +                            gRlvHandler.setCanCancelTp(false);
  7.1839 +                        if (is_do_not_disturb)
  7.1840 +                            send_do_not_disturb_message(gMessageSystem, from_id);
  7.1841 +                        LLNotifications::instance().forceResponse(LLNotification::Params(params.name).payload(payload), 0);
  7.1842 +                    }
  7.1843 +                    else
  7.1844 +                    {
  7.1845 +                        LLPostponedNotification::add<LLPostponedOfferNotification>(params, from_id, false);
  7.1846 +                    }
  7.1847 +// [/RLVa:KB]
  7.1848 +//                  LLPostponedNotification::add<LLPostponedOfferNotification>(params, from_id, false);
  7.1849 +                }
  7.1850 +            }
  7.1851 +        }
  7.1852 +        break;
  7.1853 +
  7.1854 +    case IM_GODLIKE_LURE_USER:
  7.1855 +        {
  7.1856 +            LLVector3 pos, look_at;
  7.1857 +            U64 region_handle(0);
  7.1858 +            U8 region_access(SIM_ACCESS_MIN);
  7.1859 +            std::string region_info = ll_safe_string((char*)binary_bucket, binary_bucket_size);
  7.1860 +            std::string region_access_str = LLStringUtil::null;
  7.1861 +            std::string region_access_icn = LLStringUtil::null;
  7.1862 +            std::string region_access_lc  = LLStringUtil::null;
  7.1863 +
  7.1864 +            bool canUserAccessDstRegion = true;
  7.1865 +            bool doesUserRequireMaturityIncrease = false;
  7.1866 +
  7.1867 +            if (parse_lure_bucket(region_info, region_handle, pos, look_at, region_access))
  7.1868 +            {
  7.1869 +                region_access_str = LLViewerRegion::accessToString(region_access);
  7.1870 +                region_access_icn = LLViewerRegion::getAccessIcon(region_access);
  7.1871 +                region_access_lc  = region_access_str;
  7.1872 +                LLStringUtil::toLower(region_access_lc);
  7.1873 +
  7.1874 +                if (!gAgent.isGodlike())
  7.1875 +                {
  7.1876 +                    switch (region_access)
  7.1877 +                    {
  7.1878 +                    case SIM_ACCESS_MIN :
  7.1879 +                    case SIM_ACCESS_PG :
  7.1880 +                        break;
  7.1881 +                    case SIM_ACCESS_MATURE :
  7.1882 +                        if (gAgent.isTeen())
  7.1883 +                        {
  7.1884 +                            canUserAccessDstRegion = false;
  7.1885 +                        }
  7.1886 +                        else if (gAgent.prefersPG())
  7.1887 +                        {
  7.1888 +                            doesUserRequireMaturityIncrease = true;
  7.1889 +                        }
  7.1890 +                        break;
  7.1891 +                    case SIM_ACCESS_ADULT :
  7.1892 +                        if (!gAgent.isAdult())
  7.1893 +                        {
  7.1894 +                            canUserAccessDstRegion = false;
  7.1895 +                        }
  7.1896 +                        else if (!gAgent.prefersAdult())
  7.1897 +                        {
  7.1898 +                            doesUserRequireMaturityIncrease = true;
  7.1899 +                        }
  7.1900 +                        break;
  7.1901 +                    default :
  7.1902 +                        llassert(0);
  7.1903 +                        break;
  7.1904 +                    }
  7.1905 +                }
  7.1906 +            }
  7.1907 +
  7.1908 +            LLSD args;
  7.1909 +            // *TODO: Translate -> [FIRST] [LAST] (maybe)
  7.1910 +            args["NAME_SLURL"] = LLSLURL("agent", from_id, "about").getSLURLString();
  7.1911 +            args["MESSAGE"] = message;
  7.1912 +            args["MATURITY_STR"] = region_access_str;
  7.1913 +            args["MATURITY_ICON"] = region_access_icn;
  7.1914 +            args["REGION_CONTENT_MATURITY"] = region_access_lc;
  7.1915 +            LLSD payload;
  7.1916 +            payload["from_id"] = from_id;
  7.1917 +            payload["lure_id"] = session_id;
  7.1918 +            payload["godlike"] = TRUE;
  7.1919 +            payload["region_maturity"] = region_access;
  7.1920 +
  7.1921 +            if (!canUserAccessDstRegion)
  7.1922 +            {
  7.1923 +                LLNotification::Params params("TeleportOffered_MaturityBlocked");
  7.1924 +                params.substitutions = args;
  7.1925 +                params.payload = payload;
  7.1926 +                LLPostponedNotification::add<LLPostponedOfferNotification>(	params, from_id, false);
  7.1927 +                send_simple_im(from_id, LLTrans::getString("TeleportMaturityExceeded"), IM_NOTHING_SPECIAL, session_id);
  7.1928 +                send_simple_im(from_id, LLStringUtil::null, IM_LURE_DECLINED, session_id);
  7.1929 +            }
  7.1930 +            else if (doesUserRequireMaturityIncrease)
  7.1931 +            {
  7.1932 +                LLNotification::Params params("TeleportOffered_MaturityExceeded");
  7.1933 +                params.substitutions = args;
  7.1934 +                params.payload = payload;
  7.1935 +                LLPostponedNotification::add<LLPostponedOfferNotification>(	params, from_id, false);
  7.1936 +            }
  7.1937 +            else
  7.1938 +            {
  7.1939 +            // do not show a message box, because you're about to be
  7.1940 +            // teleported.
  7.1941 +            LLNotifications::instance().forceResponse(LLNotification::Params("TeleportOffered").payload(payload), 0);
  7.1942 +        }
  7.1943 +        }
  7.1944 +        break;
  7.1945 +
  7.1946 +    case IM_GOTO_URL:
  7.1947 +        {
  7.1948 +            LLSD args;
  7.1949 +            // n.b. this is for URLs sent by the system, not for
  7.1950 +            // URLs sent by scripts (i.e. llLoadURL)
  7.1951 +            if (binary_bucket_size <= 0)
  7.1952 +            {
  7.1953 +                LL_WARNS("Messaging") << "bad binary_bucket_size: "
  7.1954 +                    << binary_bucket_size
  7.1955 +                    << " - aborting function." << LL_ENDL;
  7.1956 +                return;
  7.1957 +            }
  7.1958 +
  7.1959 +            std::string url;
  7.1960 +
  7.1961 +            url.assign((char*)binary_bucket, binary_bucket_size - 1);
  7.1962 +            args["MESSAGE"] = message;
  7.1963 +            args["URL"] = url;
  7.1964 +            LLSD payload;
  7.1965 +            payload["url"] = url;
  7.1966 +            LLNotificationsUtil::add("GotoURL", args, payload );
  7.1967 +        }
  7.1968 +        break;
  7.1969 +
  7.1970 +    case IM_FRIENDSHIP_OFFERED:
  7.1971 +        {
  7.1972 +
  7.1973 +            // <FS:PP> FIRE-15233: Automatic friendship request refusal
  7.1974 +            if (is_rejecting_friendship_requests)
  7.1975 +            {
  7.1976 +                send_rejecting_friendship_requests_message(gMessageSystem, from_id);
  7.1977 +                return;
  7.1978 +            }
  7.1979 +            // </FS:PP>
  7.1980 +
  7.1981 +            LLSD payload;
  7.1982 +            payload["from_id"] = from_id;
  7.1983 +            payload["session_id"] = session_id;
  7.1984 +            payload["online"] = (offline == IM_ONLINE);
  7.1985 +            payload["sender"] = sender.getIPandPort();
  7.1986 +
  7.1987 +            bool add_notification = true;
  7.1988 +            for (LLToastNotifyPanel::instance_iter ti(LLToastNotifyPanel::beginInstances())
  7.1989 +                , tend(LLToastNotifyPanel::endInstances()); ti != tend; ++ti)
  7.1990 +            {
  7.1991 +                LLToastNotifyPanel& panel = *ti;
  7.1992 +                const std::string& notification_name = panel.getNotificationName();
  7.1993 +                if (notification_name == "OfferFriendship" && panel.isControlPanelEnabled())
  7.1994 +                {
  7.1995 +                    add_notification = false;
  7.1996 +                    break;
  7.1997 +                }
  7.1998 +            }
  7.1999 +
  7.2000 +            if (is_muted && add_notification)
  7.2001 +            {
  7.2002 +                LLNotifications::instance().forceResponse(LLNotification::Params("OfferFriendship").payload(payload), 1);
  7.2003 +            }
  7.2004 +            else
  7.2005 +            {
  7.2006 +                if (is_do_not_disturb)
  7.2007 +                {
  7.2008 +                    send_do_not_disturb_message(gMessageSystem, from_id);
  7.2009 +                }
  7.2010 +// [SL:KB] - Patch: UI-Notifications | Checked: 2011-04-11 (Catznip-2.5.0a) | Added: Catznip-2.5.0a
  7.2011 +                args["NAME_LABEL"] = LLSLURL("agent", from_id, "completename").getSLURLString();
  7.2012 +// [/SL:KB]
  7.2013 +                args["NAME_SLURL"] = LLSLURL("agent", from_id, "about").getSLURLString();
  7.2014 +
  7.2015 +                if (add_notification)
  7.2016 +                {
  7.2017 +                if(message.empty())
  7.2018 +                {
  7.2019 +                    //support for frienship offers from clients before July 2008
  7.2020 +                        LLNotificationsUtil::add("OfferFriendshipNoMessage", args, payload);
  7.2021 +                        make_ui_sound("UISndFriendshipOffer"); // <FS:PP> Friendship offer sound
  7.2022 +                }
  7.2023 +                else
  7.2024 +                {
  7.2025 +                    args["[MESSAGE]"] = message;
  7.2026 +                    LLNotification::Params params("OfferFriendship");
  7.2027 +                    params.substitutions = args;
  7.2028 +                    params.payload = payload;
  7.2029 +                    LLPostponedNotification::add<LLPostponedOfferNotification>(	params, from_id, false);
  7.2030 +                    make_ui_sound("UISndFriendshipOffer"); // <FS:PP> Friendship offer sound
  7.2031 +                }
  7.2032 +            }
  7.2033 +        }
  7.2034 +        }
  7.2035 +        break;
  7.2036 +
  7.2037 +    case IM_FRIENDSHIP_ACCEPTED:
  7.2038 +        {
  7.2039 +            // In the case of an offline IM, the formFriendship() may be extraneous
  7.2040 +            // as the database should already include the relationship.  But it
  7.2041 +            // doesn't hurt for dupes.
  7.2042 +            LLAvatarTracker::formFriendship(from_id);
  7.2043 +            
  7.2044 +            std::vector<std::string> strings;
  7.2045 +            strings.push_back(from_id.asString());
  7.2046 +            send_generic_message("requestonlinenotification", strings);
  7.2047 +            
  7.2048 +            args["NAME"] = name;
  7.2049 +            LLSD payload;
  7.2050 +            payload["from_id"] = from_id;
  7.2051 +            LLAvatarNameCache::get(from_id, boost::bind(&notification_display_name_callback, _1, _2, "FriendshipAccepted", args, payload));
  7.2052 +        }
  7.2053 +        break;
  7.2054 +
  7.2055 +    case IM_FRIENDSHIP_DECLINED_DEPRECATED:
  7.2056 +    default:
  7.2057 +        LL_WARNS("Messaging") << "Instant message calling for unknown dialog "
  7.2058 +                << (S32)dialog << LL_ENDL;
  7.2059 +        break;
  7.2060 +    }
  7.2061 +
  7.2062 +    LLWindow* viewer_window = gViewerWindow->getWindow();
  7.2063 +    // <FS:CR> Make osx dashboard icon bounce when window isn't in focus
  7.2064 +    //if (viewer_window && viewer_window->getMinimized())
  7.2065 +    static LLCachedControl<bool> sFlashIcon(gSavedSettings, "FSFlashOnMessage");
  7.2066 +    static LLCachedControl<bool> sFSFlashOnObjectIM(gSavedSettings, "FSFlashOnObjectIM");
  7.2067 +    if (viewer_window && dialog != IM_TYPING_START && dialog != IM_TYPING_STOP && sFlashIcon && (sFSFlashOnObjectIM || (chat.mChatType != CHAT_TYPE_IM)) && !is_muted)
  7.2068 +    {
  7.2069 +        viewer_window->flashIcon(5.f);
  7.2070 +    }
  7.2071 +}
  7.2072 +
  7.2073 +void LLIMProcessing::requestOfflineMessages()
  7.2074 +{
  7.2075 +    static BOOL requested = FALSE;
  7.2076 +    if (!requested
  7.2077 +        && gMessageSystem
  7.2078 +        && LLMuteList::getInstance()->isLoaded()
  7.2079 +        && isAgentAvatarValid()
  7.2080 +        && gAgent.getRegion()
  7.2081 +        && gAgent.getRegion()->capabilitiesReceived())
  7.2082 +    {
  7.2083 +        std::string cap_url = gAgent.getRegionCapability("ReadOfflineMsgs");
  7.2084 +
  7.2085 +        // Auto-accepted inventory items may require the avatar object
  7.2086 +        // to build a correct name.  Likewise, inventory offers from
  7.2087 +        // muted avatars require the mute list to properly mute.
  7.2088 +        if (cap_url.empty())
  7.2089 +        {
  7.2090 +            requestOfflineMessagesLegacy();
  7.2091 +        }
  7.2092 +        else
  7.2093 +        {
  7.2094 +            LLCoros::instance().launch("LLIMProcessing::requestOfflineMessagesCoro",
  7.2095 +                boost::bind(&LLIMProcessing::requestOfflineMessagesCoro, cap_url));
  7.2096 +        }
  7.2097 +        requested = TRUE;
  7.2098 +    }
  7.2099 +}
  7.2100 +
  7.2101 +void LLIMProcessing::requestOfflineMessagesCoro(std::string url)
  7.2102 +{
  7.2103 +    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
  7.2104 +    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
  7.2105 +        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("requestOfflineMessagesCoro", httpPolicy));
  7.2106 +    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
  7.2107 +
  7.2108 +    LLSD result = httpAdapter->getAndSuspend(httpRequest, url);
  7.2109 +
  7.2110 +    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
  7.2111 +    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
  7.2112 +
  7.2113 +    if (!status) // success = httpResults["success"].asBoolean();
  7.2114 +    {
  7.2115 +        LL_WARNS() << "Error requesting offline messages via capability " << url << ", Status: " << status.toString() << "\nFalling back to legacy method." << LL_ENDL;
  7.2116 +
  7.2117 +        requestOfflineMessagesLegacy();
  7.2118 +        return;
  7.2119 +    }
  7.2120 +
  7.2121 +    LLSD contents = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_CONTENT];
  7.2122 +
  7.2123 +    if (!contents.size())
  7.2124 +    {
  7.2125 +        LL_WARNS() << "No contents received for offline messages via capability " << url << LL_ENDL;
  7.2126 +        return;
  7.2127 +    }
  7.2128 +
  7.2129 +    LLSD messages;
  7.2130 +    if (contents.isArray())
  7.2131 +    {
  7.2132 +        messages = *contents.beginArray();
  7.2133 +    }
  7.2134 +    else if (contents.has("messages"))
  7.2135 +    {
  7.2136 +        messages = contents["messages"];
  7.2137 +    }
  7.2138 +    else
  7.2139 +    {
  7.2140 +        LL_WARNS() << "Invalid offline message content received via capability " << url << LL_ENDL;
  7.2141 +        return;
  7.2142 +    }
  7.2143 +
  7.2144 +    if (!messages.isArray())
  7.2145 +    {
  7.2146 +        LL_WARNS() << "Invalid offline message content received via capability " << url << LL_ENDL;
  7.2147 +        return;
  7.2148 +    }
  7.2149 +
  7.2150 +    std::vector<U8> data;
  7.2151 +    S32 binary_bucket_size = 0;
  7.2152 +    LLHost sender = gAgent.getRegion()->getHost();
  7.2153 +
  7.2154 +    LLSD::array_iterator i = messages.beginArray();
  7.2155 +    LLSD::array_iterator iEnd = messages.endArray();
  7.2156 +    for (; i != iEnd; ++i)
  7.2157 +    {
  7.2158 +        const LLSD &message_data(*i);
  7.2159 +        LLVector3 position(message_data["local_x"].asReal(), message_data["local_y"].asReal(), message_data["local_z"].asReal());
  7.2160 +        data = message_data["binary_bucket"].asBinary();
  7.2161 +        binary_bucket_size = data.size(); // message_data["count"] == data.size() - 1 due to ('\0')
  7.2162 +        U32 parent_estate_id = message_data.has("parent_estate_id") ? message_data["ParentEstateID"].asInteger() : 1; // 1 - IMMainland
  7.2163 +
  7.2164 +        LLIMProcessing::processNewMessage(message_data["from_agent_id"].asUUID(),
  7.2165 +            message_data["from_group"].asInteger(), // BOOL
  7.2166 +            message_data["to_agent_id"].asUUID(),
  7.2167 +            IM_OFFLINE,
  7.2168 +            (EInstantMessage)message_data["dialog"].asInteger(),
  7.2169 +            message_data["session_id"].asUUID(),
  7.2170 +            message_data["timestamp"].asInteger(),
  7.2171 +            message_data["from_agent_name"].asString(),
  7.2172 +            message_data["message"].asString(),
  7.2173 +            parent_estate_id,
  7.2174 +            message_data["region_id"].asUUID(),
  7.2175 +            position,
  7.2176 +            &data[0],
  7.2177 +            binary_bucket_size,
  7.2178 +            sender);
  7.2179 +    }
  7.2180 +}
  7.2181 +
  7.2182 +void LLIMProcessing::requestOfflineMessagesLegacy()
  7.2183 +{
  7.2184 +    LLMessageSystem* msg = gMessageSystem;
  7.2185 +    msg->newMessageFast(_PREHASH_RetrieveInstantMessages);
  7.2186 +    msg->nextBlockFast(_PREHASH_AgentData);
  7.2187 +    msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
  7.2188 +    msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
  7.2189 +    gAgent.sendReliableMessage();
  7.2190 +}
  7.2191 +
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/indra/newview/llimprocessing.h	Tue Mar 13 19:51:18 2018 +0100
     8.3 @@ -0,0 +1,62 @@
     8.4 +/**
     8.5 +* @file LLIMMgr.h
     8.6 +* @brief Container for Instant Messaging
     8.7 +*
     8.8 +* $LicenseInfo:firstyear=2001&license=viewerlgpl$
     8.9 +* Second Life Viewer Source Code
    8.10 +* Copyright (C) 2010, Linden Research, Inc.
    8.11 +*
    8.12 +* This library is free software; you can redistribute it and/or
    8.13 +* modify it under the terms of the GNU Lesser General Public
    8.14 +* License as published by the Free Software Foundation;
    8.15 +* version 2.1 of the License only.
    8.16 +*
    8.17 +* This library is distributed in the hope that it will be useful,
    8.18 +* but WITHOUT ANY WARRANTY; without even the implied warranty of
    8.19 +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    8.20 +* Lesser General Public License for more details.
    8.21 +*
    8.22 +* You should have received a copy of the GNU Lesser General Public
    8.23 +* License along with this library; if not, write to the Free Software
    8.24 +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
    8.25 +*
    8.26 +* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
    8.27 +* $/LicenseInfo$
    8.28 +*/
    8.29 +
    8.30 +#ifndef LL_LLIMPROCESSING_H
    8.31 +#define LL_LLIMPROCESSING_H
    8.32 +
    8.33 +#include "llinstantmessage.h"
    8.34 +
    8.35 +class LLIMProcessing
    8.36 +{
    8.37 +public:
    8.38 +    // Pre-process message for IM manager
    8.39 +    static void processNewMessage(LLUUID from_id,
    8.40 +        BOOL from_group,
    8.41 +        LLUUID to_id,
    8.42 +        U8 offline,
    8.43 +        EInstantMessage dialog, // U8
    8.44 +        LLUUID session_id,
    8.45 +        U32 timestamp,
    8.46 +        std::string agentName,
    8.47 +        std::string message,
    8.48 +        U32 parent_estate_id,
    8.49 +        LLUUID region_id,
    8.50 +        LLVector3 position,
    8.51 +        U8 *binary_bucket,
    8.52 +        S32 binary_bucket_size,
    8.53 +        LLHost &sender);
    8.54 +
    8.55 +    // Either receives list of offline messages from 'ReadOfflineMsgs' capability
    8.56 +    // or uses legacy method
    8.57 +    static void requestOfflineMessages();
    8.58 +
    8.59 +private:
    8.60 +    static void requestOfflineMessagesCoro(std::string url);
    8.61 +    static void requestOfflineMessagesLegacy();
    8.62 +};
    8.63 +
    8.64 +
    8.65 +#endif  // LL_LLLLIMPROCESSING_H
     9.1 --- a/indra/newview/llviewermessage.cpp	Tue Mar 13 19:50:55 2018 +0100
     9.2 +++ b/indra/newview/llviewermessage.cpp	Tue Mar 13 19:51:18 2018 +0100
     9.3 @@ -26,7 +26,6 @@
     9.4  
     9.5  #include "llviewerprecompiledheaders.h"
     9.6  #include "llviewermessage.h"
     9.7 -#include "boost/lexical_cast.hpp"
     9.8  
     9.9  // Linden libraries
    9.10  #include "llanimationstates.h"
    9.11 @@ -66,7 +65,7 @@
    9.12  #include "llfloatersnapshot.h"
    9.13  #include "llhudeffecttrail.h"
    9.14  #include "llhudmanager.h"
    9.15 -#include "llimview.h"
    9.16 +#include "llimprocessing.h"
    9.17  #include "llinventoryfunctions.h"
    9.18  #include "llinventoryobserver.h"
    9.19  #include "llinventorypanel.h"
    9.20 @@ -127,7 +126,6 @@
    9.21  // [/RLVa:KB]
    9.22  
    9.23  #include <boost/algorithm/string/split.hpp> //
    9.24 -#include <boost/regex.hpp>
    9.25  #include <boost/foreach.hpp>
    9.26  
    9.27  #include "llnotificationmanager.h" //
    9.28 @@ -135,12 +133,12 @@
    9.29  
    9.30  #include "llexperiencecache.h"
    9.31  
    9.32 -// Firestorm inclues
    9.33 +// Firestorm includes
    9.34 +#include <boost/regex.hpp>
    9.35  #include "animationexplorer.h"		// <FS:Zi> Animation Explorer
    9.36  #include "fsareasearch.h"
    9.37  #include "fsassetblacklist.h"
    9.38  #include "fscommon.h"
    9.39 -#include "fsdata.h"
    9.40  #include "fsfloaterplacedetails.h"
    9.41  #include "fsradar.h"
    9.42  #include "fskeywords.h" // <FS:PP> FIRE-10178: Keyword Alerts in group IM do not work unless the group is in the foreground
    9.43 @@ -150,19 +148,10 @@
    9.44  #include "llfloaterbump.h"
    9.45  #include "llfloaterreg.h"
    9.46  #include "llfriendcard.h"
    9.47 -#include "llgiveinventory.h"
    9.48 -#include "lllandmarkactions.h"
    9.49 -#include "lltexturefetch.h"
    9.50 -#include "sound_ids.h"
    9.51  #include "tea.h" // <FS:AW opensim currency support>
    9.52  #include "NACLantispam.h"
    9.53  #include "chatbar_as_cmdline.h"
    9.54  
    9.55 -#if LL_MSVC
    9.56 -// disable boost::lexical_cast warning
    9.57 -#pragma warning (disable:4702)
    9.58 -#endif
    9.59 -
    9.60  extern void on_new_message(const LLSD& msg);
    9.61  
    9.62  //
    9.63 @@ -839,38 +828,36 @@
    9.64  //-----------------------------------------------------------------------------
    9.65  // Instant Message
    9.66  //-----------------------------------------------------------------------------
    9.67 -class LLOpenAgentOffer : public LLInventoryFetchItemsObserver
    9.68 -{
    9.69 -public:
    9.70 -	LLOpenAgentOffer(const LLUUID& object_id,
    9.71 -					 const std::string& from_name) : 
    9.72 -		LLInventoryFetchItemsObserver(object_id),
    9.73 -		mFromName(from_name) {}
    9.74 -	/*virtual*/ void startFetch()
    9.75 -	{
    9.76 -		for (uuid_vec_t::const_iterator it = mIDs.begin(); it < mIDs.end(); ++it)
    9.77 -		{
    9.78 -			LLViewerInventoryCategory* cat = gInventory.getCategory(*it);
    9.79 -			if (cat)
    9.80 -			{
    9.81 -				mComplete.push_back((*it));
    9.82 -			}
    9.83 -		}
    9.84 -		LLInventoryFetchItemsObserver::startFetch();
    9.85 -	}
    9.86 -	/*virtual*/ void done()
    9.87 -	{
    9.88 -		// <FS:Ansariel> FIRE-3234: Don't need a check for ShowNewInventory here;
    9.89 -		// This only gets called if the user explicity clicks "Show" or
    9.90 -		// AutoAcceptNewInventory and ShowNewInventory are TRUE.
    9.91 -		//open_inventory_offer(mComplete, mFromName);
    9.92 -		open_inventory_offer(mComplete, mFromName, true);
    9.93 -		gInventory.removeObserver(this);
    9.94 -		delete this;
    9.95 -	}
    9.96 -private:
    9.97 -	std::string mFromName;
    9.98 -};
    9.99 +// <FS:Ansariel> Moved to header; needed in llimprocessing.cpp
   9.100 +//class LLOpenAgentOffer : public LLInventoryFetchItemsObserver
   9.101 +//{
   9.102 +//public:
   9.103 +//	LLOpenAgentOffer(const LLUUID& object_id,
   9.104 +//					 const std::string& from_name) : 
   9.105 +//		LLInventoryFetchItemsObserver(object_id),
   9.106 +//		mFromName(from_name) {}
   9.107 +//	/*virtual*/ void startFetch()
   9.108 +//	{
   9.109 +//		for (uuid_vec_t::const_iterator it = mIDs.begin(); it < mIDs.end(); ++it)
   9.110 +//		{
   9.111 +//			LLViewerInventoryCategory* cat = gInventory.getCategory(*it);
   9.112 +//			if (cat)
   9.113 +//			{
   9.114 +//				mComplete.push_back((*it));
   9.115 +//			}
   9.116 +//		}
   9.117 +//		LLInventoryFetchItemsObserver::startFetch();
   9.118 +//	}
   9.119 +//	/*virtual*/ void done()
   9.120 +//	{
   9.121 +//		open_inventory_offer(mComplete, mFromName);
   9.122 +//		gInventory.removeObserver(this);
   9.123 +//		delete this;
   9.124 +//	}
   9.125 +//private:
   9.126 +//	std::string mFromName;
   9.127 +//};
   9.128 +// </FS:Ansariel>
   9.129  
   9.130  /**
   9.131   * Class to observe adding of new items moved from the world to user's inventory to select them in inventory.
   9.132 @@ -2174,18 +2161,6 @@
   9.133  	return false;
   9.134  }
   9.135  
   9.136 -class LLPostponedOfferNotification: public LLPostponedNotification
   9.137 -{
   9.138 -protected:
   9.139 -	/* virtual */
   9.140 -	void modifyNotificationParams()
   9.141 -	{
   9.142 -		LLSD substitutions = mParams.substitutions;
   9.143 -		substitutions["NAME"] = mName;
   9.144 -		mParams.substitutions = substitutions;
   9.145 -	}
   9.146 -};
   9.147 -
   9.148  void LLOfferInfo::initRespondFunctionMap()
   9.149  {
   9.150  	if(mRespondFunctions.empty())
   9.151 @@ -2198,265 +2173,6 @@
   9.152  	}
   9.153  }
   9.154  
   9.155 -void inventory_offer_handler(LLOfferInfo* info)
   9.156 -{
   9.157 -	// If muted, don't even go through the messaging stuff.  Just curtail the offer here.
   9.158 -	// Passing in a null UUID handles the case of where you have muted one of your own objects by_name.
   9.159 -	// The solution for STORM-1297 seems to handle the cases where the object is owned by someone else.
   9.160 -	if (LLMuteList::getInstance()->isMuted(info->mFromID, info->mFromName) ||
   9.161 -		LLMuteList::getInstance()->isMuted(LLUUID::null, info->mFromName))
   9.162 -	{
   9.163 -		info->forceResponse(IOR_MUTE);
   9.164 -		return;
   9.165 -	}
   9.166 -
   9.167 -
   9.168 -	bool bAutoAccept(false);
   9.169 -	// Avoid the Accept/Discard dialog if the user so desires. JC
   9.170 -	// <FS:Ansariel> Auto-accept any kind of inventory (FIRE-4128)
   9.171 -	//if (gSavedSettings.getBOOL("AutoAcceptNewInventory")
   9.172 -	//	&& (info->mType == LLAssetType::AT_NOTECARD
   9.173 -	//		|| info->mType == LLAssetType::AT_LANDMARK
   9.174 -	//		|| info->mType == LLAssetType::AT_TEXTURE))
   9.175 -//	if (gSavedSettings.getBOOL("AutoAcceptNewInventory"))
   9.176 -	// </FS:Ansariel> Auto-accept any kind of inventory (FIRE-4128)
   9.177 -// [RLVa:KB]
   9.178 -	// Don't auto-accept give-to-RLV inventory offers
   9.179 -	if ( (gSavedSettings.getBOOL("AutoAcceptNewInventory")) &&
   9.180 -		 ( (!rlv_handler_t::isEnabled()) || (!RlvInventory::instance().isGiveToRLVOffer(*info)) ) )
   9.181 -// [/RLVa:KB]
   9.182 -	{
   9.183 -		// For certain types, just accept the items into the inventory,
   9.184 -		// and possibly open them on receipt depending upon "ShowNewInventory".
   9.185 -		bAutoAccept = true;
   9.186 -	}
   9.187 -
   9.188 -	// Strip any SLURL from the message display. (DEV-2754)
   9.189 -	std::string msg = info->mDesc;
   9.190 -	int indx = msg.find(" ( http://slurl.com/secondlife/");
   9.191 -	if(indx == std::string::npos)
   9.192 -	{
   9.193 -		// try to find new slurl host
   9.194 -		indx = msg.find(" ( http://maps.secondlife.com/secondlife/");
   9.195 -	}
   9.196 -	if(indx >= 0)
   9.197 -	{
   9.198 -		LLStringUtil::truncate(msg, indx);
   9.199 -	}
   9.200 -
   9.201 -	LLSD args;
   9.202 -	args["[OBJECTNAME]"] = msg;
   9.203 -
   9.204 -	LLSD payload;
   9.205 -
   9.206 -	// must protect against a NULL return from lookupHumanReadable()
   9.207 -	std::string typestr = ll_safe_string(LLAssetType::lookupHumanReadable(info->mType));
   9.208 -	if (!typestr.empty())
   9.209 -	{
   9.210 -		// human readable matches string name from strings.xml
   9.211 -		// lets get asset type localized name
   9.212 -		args["OBJECTTYPE"] = LLTrans::getString(typestr);
   9.213 -	}
   9.214 -	else
   9.215 -	{
   9.216 -		LL_WARNS("Messaging") << "LLAssetType::lookupHumanReadable() returned NULL - probably bad asset type: " << info->mType << LL_ENDL;
   9.217 -		args["OBJECTTYPE"] = "";
   9.218 -
   9.219 -		// This seems safest, rather than propagating bogosity
   9.220 -		LL_WARNS("Messaging") << "Forcing an inventory-decline for probably-bad asset type." << LL_ENDL;
   9.221 -		info->forceResponse(IOR_DECLINE);
   9.222 -		return;
   9.223 -	}
   9.224 -
   9.225 -	// If mObjectID is null then generate the object_id based on msg to prevent
   9.226 -	// multiple creation of chiclets for same object.
   9.227 -	LLUUID object_id = info->mObjectID;
   9.228 -	if (object_id.isNull())
   9.229 -		object_id.generate(msg);
   9.230 -
   9.231 -	payload["from_id"] = info->mFromID;
   9.232 -	// Needed by LLScriptFloaterManager to bind original notification with 
   9.233 -	// faked for toast one.
   9.234 -	payload["object_id"] = object_id;
   9.235 -	// Flag indicating that this notification is faked for toast.
   9.236 -	payload["give_inventory_notification"] = FALSE;
   9.237 -	args["OBJECTFROMNAME"] = info->mFromName;
   9.238 -	args["NAME"] = info->mFromName;
   9.239 -	if (info->mFromGroup)
   9.240 -	{
   9.241 -		args["NAME_SLURL"] = LLSLURL("group", info->mFromID, "about").getSLURLString();
   9.242 -	}
   9.243 -	else
   9.244 -	{
   9.245 -// [SL:KB] - Patch: UI-Notifications | Checked: 2011-04-11 (Catznip-2.5.0a) | Added: Catznip-2.5.0a
   9.246 -		args["NAME_LABEL"] = LLSLURL("agent", info->mFromID, "completename").getSLURLString();
   9.247 -// [/SL:KB]
   9.248 -		args["NAME_SLURL"] = LLSLURL("agent", info->mFromID, "about").getSLURLString();
   9.249 -	}
   9.250 -	std::string verb = "select?name=" + LLURI::escape(msg);
   9.251 -	args["ITEM_SLURL"] = LLSLURL("inventory", info->mObjectID, verb.c_str()).getSLURLString();
   9.252 -
   9.253 -	LLNotification::Params p;
   9.254 -
   9.255 -	// Object -> Agent Inventory Offer
   9.256 -	if (info->mFromObject && !bAutoAccept)
   9.257 -	{
   9.258 -// [RLVa:KB] - Checked: RLVa-1.2.2
   9.259 -		// Only filter if the object owner is a nearby agent
   9.260 -		if ( (RlvActions::isRlvEnabled()) && (!RlvActions::canShowName(RlvActions::SNC_DEFAULT, info->mFromID)) && (RlvUtil::isNearbyAgent(info->mFromID)) )
   9.261 -		{
   9.262 -			payload["rlv_shownames"] = TRUE;
   9.263 -			args["NAME_SLURL"] = LLSLURL("agent", info->mFromID, "rlvanonym").getSLURLString();
   9.264 -		}
   9.265 -// [/RLVa:KB]
   9.266 -
   9.267 -		// Inventory Slurls don't currently work for non agent transfers, so only display the object name.
   9.268 -		args["ITEM_SLURL"] = msg;
   9.269 -		// Note: sets inventory_task_offer_callback as the callback
   9.270 -		p.substitutions(args).payload(payload).functor.responder(LLNotificationResponderPtr(info));
   9.271 -		info->mPersist = true;
   9.272 -
   9.273 -		// Offers from your own objects need a special notification template.
   9.274 -		p.name = info->mFromID == gAgentID ? "OwnObjectGiveItem" : "ObjectGiveItem";
   9.275 -
   9.276 -		// Pop up inv offer chiclet and let the user accept (keep), or reject (and silently delete) the inventory.
   9.277 -	    LLPostponedNotification::add<LLPostponedOfferNotification>(p, info->mFromID, info->mFromGroup == TRUE);
   9.278 -	}
   9.279 -	else // Agent -> Agent Inventory Offer
   9.280 -	{
   9.281 -// [RLVa:KB] - Checked: RLVa-2.0.1
   9.282 -		// Only filter if the offer is from a nearby agent and if there's no open IM session (doesn't necessarily have to be focused)
   9.283 -		bool fRlvCanShowName = (!RlvActions::isRlvEnabled()) ||
   9.284 -			(RlvActions::canShowName(RlvActions::SNC_DEFAULT, info->mFromID)) || (!RlvUtil::isNearbyAgent(info->mFromID)) || (RlvUIEnabler::hasOpenIM(info->mFromID)) || (RlvUIEnabler::hasOpenProfile(info->mFromID));
   9.285 -		if (!fRlvCanShowName)
   9.286 -		{
   9.287 -			payload["rlv_shownames"] = TRUE;
   9.288 -			LLAvatarName av_name;
   9.289 -			if (LLAvatarNameCache::get(info->mFromID, &av_name))
   9.290 -			{
   9.291 -				args["NAME"] = RlvStrings::getAnonym(av_name);
   9.292 -			}
   9.293 -			else
   9.294 -			{
   9.295 -				args["NAME"] = RlvStrings::getAnonym(info->mFromName);
   9.296 -			}
   9.297 -			args["NAME_SLURL"] = LLSLURL("agent", info->mFromID, "rlvanonym").getSLURLString();
   9.298 -		}
   9.299 -// [/RLVa:KB]
   9.300 -
   9.301 -		p.responder = info;
   9.302 -		// Note: sets inventory_offer_callback as the callback
   9.303 -		// *TODO fix memory leak
   9.304 -		// inventory_offer_callback() is not invoked if user received notification and 
   9.305 -		// closes viewer(without responding the notification)
   9.306 -		p.substitutions(args).payload(payload).functor.responder(LLNotificationResponderPtr(info));
   9.307 -		info->mPersist = true;
   9.308 -		// <FS:Ansariel> FIRE-3832: Silent accept/decline of inventory offers
   9.309 -		//p.name = "UserGiveItem";
   9.310 -		p.name = (gSavedSettings.getBOOL("FSUseLegacyInventoryAcceptMessages") ? "UserGiveItemLegacy" : "UserGiveItem");
   9.311 -		// </FS:Ansariel>
   9.312 -		p.offer_from_agent = true;
   9.313 -		
   9.314 -		// Prefetch the item into your local inventory.
   9.315 -		LLInventoryFetchItemsObserver* fetch_item = new LLInventoryFetchItemsObserver(info->mObjectID);
   9.316 -		fetch_item->startFetch();
   9.317 -		if(fetch_item->isFinished())
   9.318 -		{
   9.319 -			fetch_item->done();
   9.320 -		}
   9.321 -		else
   9.322 -		{
   9.323 -			gInventory.addObserver(fetch_item);
   9.324 -		}
   9.325 -		
   9.326 -		// In viewer 2 we're now auto receiving inventory offers and messaging as such (not sending reject messages).
   9.327 -		// <FS:Ansariel> Optional V1-like inventory accept messages
   9.328 -		//info->send_auto_receive_response();
   9.329 -		// Also needs to be send on auto-accept so the item gets into the inventory!
   9.330 -		if (bAutoAccept || !gSavedSettings.getBOOL("FSUseLegacyInventoryAcceptMessages"))
   9.331 -		{
   9.332 -			info->send_auto_receive_response();
   9.333 -		}
   9.334 -		// </FS:Ansariel> Optional V1-like inventory accept messages
   9.335 -
   9.336 -        if (gAgent.isDoNotDisturb()) 
   9.337 -        {
   9.338 -            send_do_not_disturb_message(gMessageSystem, info->mFromID);
   9.339 -        }
   9.340 -        
   9.341 -		if( !bAutoAccept ) // if we auto accept, do not pester the user
   9.342 -		{
   9.343 -			// Inform user that there is a script floater via toast system
   9.344 -			payload["give_inventory_notification"] = TRUE;
   9.345 -			p.payload = payload;
   9.346 -			LLPostponedNotification::add<LLPostponedOfferNotification>(p, info->mFromID, false);
   9.347 -		}
   9.348 -		// <FS:Ansariel> FIRE-19540: Log auto-accepted inventory to nearby chat
   9.349 -		else if (gSavedSettings.getBOOL("FSLogAutoAcceptInventoryToChat"))
   9.350 -		{
   9.351 -			std::string message_type;
   9.352 -			LLStringUtil::format_map_t chat_args;
   9.353 -			
   9.354 -			chat_args["OBJECT_TYPE"] = (!typestr.empty() ? LLTrans::getString(typestr) : "");
   9.355 -			chat_args["DESC"] = msg;
   9.356 -
   9.357 -			if (info->mFromObject)
   9.358 -			{
   9.359 -				std::string str_pos;
   9.360 -				std::string::size_type idx_start = info->mDesc.rfind(" ( http://");
   9.361 -				std::string::size_type idx_end = info->mDesc.find(" )", idx_start);
   9.362 -				if (idx_start != std::string::npos && idx_end != std::string::npos)
   9.363 -				{
   9.364 -					LLSLURL url_pos(info->mDesc.substr(idx_start + 3, idx_end - (idx_start + 3)));
   9.365 -					str_pos = "&slurl=" + LLURI::escape(url_pos.getLocationString());
   9.366 -				}
   9.367 -
   9.368 -				chat_args["OBJECT_NAME"] = "[" + LLSLURL("objectim", info->mObjectID, "").getSLURLString() + "?name=" + LLURI::escape(info->mFromName) + "&owner=" + info->mFromID.asString() + (info->mFromGroup ? "&groupowned=true" : "") + str_pos + " " + info->mFromName + "]";
   9.369 -				message_type = "InvOfferAutoAcceptObject";
   9.370 -			}
   9.371 -			else
   9.372 -			{
   9.373 -				bool fRlvCanShowName = (!RlvActions::isRlvEnabled()) ||
   9.374 -					(RlvActions::canShowName(RlvActions::SNC_DEFAULT, info->mFromID)) || (!RlvUtil::isNearbyAgent(info->mFromID)) || (RlvUIEnabler::hasOpenIM(info->mFromID)) || (RlvUIEnabler::hasOpenProfile(info->mFromID));
   9.375 -				
   9.376 -				std::string name_slurl = LLSLURL("agent", info->mFromID, (fRlvCanShowName ? "inspect" : "rlvanonym")).getSLURLString();
   9.377 -
   9.378 -				chat_args["USER_NAME"] = name_slurl;
   9.379 -				message_type = "InvOfferAutoAcceptUser";
   9.380 -			}
   9.381 -
   9.382 -			report_to_nearby_chat(LLTrans::getString(message_type, chat_args));
   9.383 -		}
   9.384 -		// </FS:Ansariel>
   9.385 -
   9.386 -		// <FS:Ansariel> Show offered inventory also if auto-accept is enabled (FIRE-5101)
   9.387 -		if (bAutoAccept && gSavedSettings.getBOOL("ShowNewInventory"))
   9.388 -		{
   9.389 -			LLViewerInventoryCategory* catp = NULL;
   9.390 -			catp = (LLViewerInventoryCategory*)gInventory.getCategory(info->mObjectID);
   9.391 -			LLViewerInventoryItem* itemp = NULL;
   9.392 -			if(!catp)
   9.393 -			{
   9.394 -				itemp = (LLViewerInventoryItem*)gInventory.getItem(info->mObjectID);
   9.395 -			}
   9.396 -
   9.397 -			LLOpenAgentOffer* open_agent_offer = new LLOpenAgentOffer(info->mObjectID, info->mFromName);
   9.398 -			open_agent_offer->startFetch();
   9.399 -			if(catp || (itemp && itemp->isFinished()))
   9.400 -			{
   9.401 -				open_agent_offer->done();
   9.402 -			}
   9.403 -			else
   9.404 -			{
   9.405 -				gInventory.addObserver(open_agent_offer);
   9.406 -			}
   9.407 -		}
   9.408 -		// </FS:Ansariel> Show offered inventory also if auto-accept is enabled (FIRE-5101)
   9.409 -	}
   9.410 -
   9.411 -	LLFirstUse::newInventory();
   9.412 -}
   9.413 -
   9.414  bool lure_callback(const LLSD& notification, const LLSD& response)
   9.415  {
   9.416  	S32 option = 0;
   9.417 @@ -2592,1735 +2308,57 @@
   9.418  	}
   9.419  };
   9.420  
   9.421 -static bool parse_lure_bucket(const std::string& bucket,
   9.422 -							  U64& region_handle,
   9.423 -							  LLVector3& pos,
   9.424 -							  LLVector3& look_at,
   9.425 -							  U8& region_access)
   9.426 -{
   9.427 -	// tokenize the bucket
   9.428 -	typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
   9.429 -	boost::char_separator<char> sep("|", "", boost::keep_empty_tokens);
   9.430 -	tokenizer tokens(bucket, sep);
   9.431 -	tokenizer::iterator iter = tokens.begin();
   9.432 -
   9.433 -	S32 gx,gy,rx,ry,rz,lx,ly,lz;
   9.434 -	try
   9.435 -	{
   9.436 -		gx = boost::lexical_cast<S32>((*(iter)).c_str());
   9.437 -		gy = boost::lexical_cast<S32>((*(++iter)).c_str());
   9.438 -		rx = boost::lexical_cast<S32>((*(++iter)).c_str());
   9.439 -		ry = boost::lexical_cast<S32>((*(++iter)).c_str());
   9.440 -		rz = boost::lexical_cast<S32>((*(++iter)).c_str());
   9.441 -		lx = boost::lexical_cast<S32>((*(++iter)).c_str());
   9.442 -		ly = boost::lexical_cast<S32>((*(++iter)).c_str());
   9.443 -		lz = boost::lexical_cast<S32>((*(++iter)).c_str());
   9.444 -	}
   9.445 -	catch( boost::bad_lexical_cast& )
   9.446 -	{
   9.447 -		LL_WARNS("parse_lure_bucket")
   9.448 -			<< "Couldn't parse lure bucket."
   9.449 -			<< LL_ENDL;
   9.450 -		return false;
   9.451 -	}
   9.452 -	// Grab region access
   9.453 -	region_access = SIM_ACCESS_MIN;
   9.454 -	if (++iter != tokens.end())
   9.455 -	{
   9.456 -		std::string access_str((*iter).c_str());
   9.457 -		LLStringUtil::trim(access_str);
   9.458 -		if ( access_str == "A" )
   9.459 -		{
   9.460 -			region_access = SIM_ACCESS_ADULT;
   9.461 -		}
   9.462 -		else if ( access_str == "M" )
   9.463 -		{
   9.464 -			region_access = SIM_ACCESS_MATURE;
   9.465 -		}
   9.466 -		else if ( access_str == "PG" )
   9.467 -		{
   9.468 -			region_access = SIM_ACCESS_PG;
   9.469 -		}
   9.470 -	}
   9.471 -
   9.472 -	pos.setVec((F32)rx, (F32)ry, (F32)rz);
   9.473 -	look_at.setVec((F32)lx, (F32)ly, (F32)lz);
   9.474 -
   9.475 -	region_handle = to_region_handle(gx, gy);
   9.476 -	return true;
   9.477 -}
   9.478 -
   9.479 -// Strip out "Resident" for display, but only if the message came from a user
   9.480 -// (rather than a script)
   9.481 -static std::string clean_name_from_im(const std::string& name, EInstantMessage type)
   9.482 -{
   9.483 -	switch(type)
   9.484 -	{
   9.485 -	case IM_NOTHING_SPECIAL:
   9.486 -	case IM_MESSAGEBOX:
   9.487 -	case IM_GROUP_INVITATION:
   9.488 -	case IM_INVENTORY_OFFERED:
   9.489 -	case IM_INVENTORY_ACCEPTED:
   9.490 -	case IM_INVENTORY_DECLINED:
   9.491 -	case IM_GROUP_VOTE:
   9.492 -	case IM_GROUP_MESSAGE_DEPRECATED:
   9.493 -	//IM_TASK_INVENTORY_OFFERED
   9.494 -	//IM_TASK_INVENTORY_ACCEPTED
   9.495 -	//IM_TASK_INVENTORY_DECLINED
   9.496 -	case IM_NEW_USER_DEFAULT:
   9.497 -	case IM_SESSION_INVITE:
   9.498 -	case IM_SESSION_P2P_INVITE:
   9.499 -	case IM_SESSION_GROUP_START:
   9.500 -	case IM_SESSION_CONFERENCE_START:
   9.501 -	case IM_SESSION_SEND:
   9.502 -	case IM_SESSION_LEAVE:
   9.503 -	//IM_FROM_TASK
   9.504 -	case IM_DO_NOT_DISTURB_AUTO_RESPONSE:
   9.505 -	case IM_CONSOLE_AND_CHAT_HISTORY:
   9.506 -	case IM_LURE_USER:
   9.507 -	case IM_LURE_ACCEPTED:
   9.508 -	case IM_LURE_DECLINED:
   9.509 -	case IM_GODLIKE_LURE_USER:
   9.510 -	case IM_TELEPORT_REQUEST:
   9.511 -	case IM_GROUP_ELECTION_DEPRECATED:
   9.512 -	//IM_GOTO_URL
   9.513 -	//IM_FROM_TASK_AS_ALERT
   9.514 -	case IM_GROUP_NOTICE:
   9.515 -	case IM_GROUP_NOTICE_INVENTORY_ACCEPTED:
   9.516 -	case IM_GROUP_NOTICE_INVENTORY_DECLINED:
   9.517 -	case IM_GROUP_INVITATION_ACCEPT:
   9.518 -	case IM_GROUP_INVITATION_DECLINE:
   9.519 -	case IM_GROUP_NOTICE_REQUESTED:
   9.520 -	case IM_FRIENDSHIP_OFFERED:
   9.521 -	case IM_FRIENDSHIP_ACCEPTED:
   9.522 -	case IM_FRIENDSHIP_DECLINED_DEPRECATED:
   9.523 -	//IM_TYPING_START
   9.524 -	//IM_TYPING_STOP
   9.525 -		return LLCacheName::cleanFullName(name);
   9.526 -	default:
   9.527 -		return name;
   9.528 -	}
   9.529 -}
   9.530 -
   9.531 -static std::string clean_name_from_task_im(const std::string& msg,
   9.532 -										   BOOL from_group)
   9.533 -{
   9.534 -	boost::smatch match;
   9.535 -	static const boost::regex returned_exp(
   9.536 -		"(.*been returned to your inventory lost and found folder by )(.+)( (from|near).*)");
   9.537 -	if (boost::regex_match(msg, match, returned_exp))
   9.538 -	{
   9.539 -		// match objects are 1-based for groups
   9.540 -		std::string final = match[1].str();
   9.541 -		std::string name = match[2].str();
   9.542 -		// Don't try to clean up group names
   9.543 -		if (!from_group)
   9.544 -		{
   9.545 -			final += LLCacheName::buildUsername(name);
   9.546 -		}
   9.547 -		final += match[3].str();
   9.548 -		return final;
   9.549 -	}
   9.550 -	return msg;
   9.551 -}
   9.552 -
   9.553 -static void notification_display_name_callback(const LLUUID& id,
   9.554 -					  const LLAvatarName& av_name,
   9.555 -					  const std::string& name, 
   9.556 -					  LLSD& substitutions, 
   9.557 -					  const LLSD& payload)
   9.558 -{
   9.559 -	substitutions["NAME"] = av_name.getDisplayName();
   9.560 -	LLNotificationsUtil::add(name, substitutions, payload);
   9.561 -}
   9.562 -
   9.563 -class LLPostponedIMSystemTipNotification: public LLPostponedNotification
   9.564 -{
   9.565 -protected:
   9.566 -	/* virtual */
   9.567 -	void modifyNotificationParams()
   9.568 -	{
   9.569 -		LLSD payload = mParams.payload;
   9.570 -		payload["SESSION_NAME"] = mName;
   9.571 -		mParams.payload = payload;
   9.572 -	}
   9.573 -
   9.574 -};
   9.575 -
   9.576 -// Callback for name resolution of a god/estate message
   9.577 -static void god_message_name_cb(const LLAvatarName& av_name, LLChat chat, std::string message)
   9.578 -{	
   9.579 -	LLSD args;
   9.580 -	args["NAME"] = av_name.getCompleteName();
   9.581 -	args["MESSAGE"] = message;
   9.582 -	LLNotificationsUtil::add("GodMessage", args);
   9.583 -
   9.584 -	// Treat like a system message and put in chat history.
   9.585 -	chat.mSourceType = CHAT_SOURCE_SYSTEM;
   9.586 -	chat.mText = message;
   9.587 -
   9.588 -	// <FS:Ansariel> [FS communication UI]
   9.589 -	//LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
   9.590 -	FSFloaterNearbyChat* nearby_chat = FSFloaterNearbyChat::getInstance();
   9.591 -	// </FS:Ansariel> [FS communication UI]
   9.592 -	if (nearby_chat)
   9.593 -	{
   9.594 -		nearby_chat->addMessage(chat);
   9.595 -	}
   9.596 -}
   9.597 -
   9.598 -const std::string NOT_ONLINE_MSG("User not online - message will be stored and delivered later.");
   9.599 -const std::string NOT_ONLINE_INVENTORY("User not online - inventory has been saved.");
   9.600 -void translate_if_needed(std::string& message)
   9.601 -{
   9.602 -	if (message == NOT_ONLINE_MSG)
   9.603 -	{
   9.604 -		message = LLTrans::getString("not_online_msg");
   9.605 -	}
   9.606 -	else if (message == NOT_ONLINE_INVENTORY)
   9.607 -	{
   9.608 -		message = LLTrans::getString("not_online_inventory");
   9.609 -	}
   9.610 -}
   9.611 -
   9.612 -// <FS:Ansariel> FIRE-505: Group name not shown in notification well
   9.613 -static void notification_group_name_cb(const std::string& group_name,
   9.614 -										const std::string& sender,
   9.615 -										const std::string& subject,
   9.616 -										const std::string& message,
   9.617 -										const LLSD& payload,
   9.618 -										U32 timestamp)
   9.619 -{
   9.620 -	LLAvatarName av_name;
   9.621 -	av_name.fromString(sender);
   9.622 -	LLSD args;
   9.623 -	args["SENDER"] = av_name.getUserNameForDisplay();
   9.624 -	args["GROUP"] = group_name;
   9.625 -	args["SUBJECT"] = subject;
   9.626 -	args["MESSAGE"] = message;
   9.627 -	LLDate notice_date = LLDate(timestamp).notNull() ? LLDate(timestamp) : LLDate::now();
   9.628 -	LLNotifications::instance().add(LLNotification::Params("GroupNotice").substitutions(args).payload(payload).time_stamp(notice_date));
   9.629 -	make_ui_sound("UISndGroupNotice"); // <FS:PP> Group notice sound
   9.630 -}
   9.631 -// </FS:Ansariel>
   9.632 -
   9.633 -// <FS:Ansariel> FIRE-6786: Always show teleport location in teleport offer
   9.634 -static void teleport_region_info_cb(const std::string& slurl, LLSD args, const LLSD& payload, const LLUUID& from_id, const LLUUID& session_id, bool can_user_access_dst_region, bool does_user_require_maturity_increase)
   9.635 -{
   9.636 -	if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC))
   9.637 -	{
   9.638 -		args["POS_SLURL"] = RlvStrings::getString(RLV_STRING_HIDDEN);
   9.639 -	}
   9.640 -	else
   9.641 -	{
   9.642 -		args["POS_SLURL"] = slurl;
   9.643 -	}
   9.644 -
   9.645 -	LLNotification::Params params;
   9.646 -
   9.647 -	if (!can_user_access_dst_region)
   9.648 -	{
   9.649 -		params.name = "TeleportOffered_MaturityBlocked_SLUrl";
   9.650 -		send_simple_im(from_id, LLTrans::getString("TeleportMaturityExceeded"), IM_NOTHING_SPECIAL, session_id);
   9.651 -		send_simple_im(from_id, LLStringUtil::null, IM_LURE_DECLINED, session_id);
   9.652 -	}
   9.653 -	else if (does_user_require_maturity_increase)
   9.654 -	{
   9.655 -		params.name = "TeleportOffered_MaturityExceeded_SLUrl";
   9.656 -	}
   9.657 -	else
   9.658 -	{
   9.659 -		params.name = "TeleportOffered_SLUrl";
   9.660 -		params.functor.name = "TeleportOffered";
   9.661 -	}
   9.662 -
   9.663 -	params.substitutions = args;
   9.664 -	params.payload = payload;
   9.665 -	LLPostponedNotification::add<LLPostponedOfferNotification>(params, from_id, false);
   9.666 -
   9.667 -	LLWindow* viewer_window = gViewerWindow->getWindow();
   9.668 -	static LLCachedControl<bool> sFlashIcon(gSavedSettings, "FSFlashOnMessage");
   9.669 -	if (viewer_window && sFlashIcon)
   9.670 -	{
   9.671 -		viewer_window->flashIcon(5.f);
   9.672 -	}
   9.673 -}
   9.674 -// </FS:Ansariel>
   9.675 -
   9.676  void process_improved_im(LLMessageSystem *msg, void **user_data)
   9.677  {
   9.678 -	LLUUID from_id;
   9.679 -	BOOL from_group;
   9.680 -	LLUUID to_id;
   9.681 -	U8 offline;
   9.682 -	U8 d = 0;
   9.683 -	LLUUID session_id;
   9.684 -	U32 timestamp;
   9.685 -	std::string name;
   9.686 -	std::string message;
   9.687 -	U32 parent_estate_id = 0;
   9.688 -	LLUUID region_id;
   9.689 -	LLVector3 position;
   9.690 -	U8 binary_bucket[MTUBYTES];
   9.691 -	S32 binary_bucket_size;
   9.692 -	LLChat chat;
   9.693 -	std::string buffer;
   9.694 -	
   9.695 -	// *TODO: Translate - need to fix the full name to first/last (maybe)
   9.696 -	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, from_id);
   9.697 -	msg->getBOOLFast(_PREHASH_MessageBlock, _PREHASH_FromGroup, from_group);
   9.698 -	msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_ToAgentID, to_id);
   9.699 -	msg->getU8Fast(  _PREHASH_MessageBlock, _PREHASH_Offline, offline);
   9.700 -	msg->getU8Fast(  _PREHASH_MessageBlock, _PREHASH_Dialog, d);
   9.701 -	msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_ID, session_id);
   9.702 -	msg->getU32Fast( _PREHASH_MessageBlock, _PREHASH_Timestamp, timestamp);
   9.703 -	//msg->getData("MessageBlock", "Count",		&count);
   9.704 -	msg->getStringFast(_PREHASH_MessageBlock, _PREHASH_FromAgentName, name);
   9.705 -	msg->getStringFast(_PREHASH_MessageBlock, _PREHASH_Message,		message);
   9.706 -	msg->getU32Fast(_PREHASH_MessageBlock, _PREHASH_ParentEstateID, parent_estate_id);
   9.707 -	msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_RegionID, region_id);
   9.708 -	msg->getVector3Fast(_PREHASH_MessageBlock, _PREHASH_Position, position);
   9.709 -	msg->getBinaryDataFast(  _PREHASH_MessageBlock, _PREHASH_BinaryBucket, binary_bucket, 0, 0, MTUBYTES);
   9.710 -	binary_bucket_size = msg->getSizeFast(_PREHASH_MessageBlock, _PREHASH_BinaryBucket);
   9.711 -	EInstantMessage dialog = (EInstantMessage)d;
   9.712 -
   9.713 -	// NaCl - Antispam Registry
   9.714 -	if (dialog != IM_TYPING_START && dialog != IM_TYPING_STOP &&											// Typing notifications
   9.715 -		!(dialog == IM_NOTHING_SPECIAL && offline == IM_OFFLINE && from_id.notNull() && to_id.notNull()) &&	// Saved offline IMs
   9.716 -		!(dialog == IM_FROM_TASK && offline == IM_OFFLINE)													// Saved offline IMs from objects
   9.717 -		)
   9.718 -	{
   9.719 -		if (NACLAntiSpamRegistry::instance().checkQueue(ANTISPAM_QUEUE_IM, from_id, ANTISPAM_SOURCE_AGENT))
   9.720 -		{
   9.721 -			return;
   9.722 -		}
   9.723 -	}
   9.724 -	// NaCl End
   9.725 -
   9.726 -    // make sure that we don't have an empty or all-whitespace name
   9.727 -	LLStringUtil::trim(name);
   9.728 -	if (name.empty())
   9.729 -	{
   9.730 -        name = LLTrans::getString("Unnamed");
   9.731 -	}
   9.732 -
   9.733 -	// Preserve the unaltered name for use in group notice mute checking.
   9.734 -	std::string original_name = name;
   9.735 -
   9.736 -	// IDEVO convert new-style "Resident" names for display
   9.737 -	name = clean_name_from_im(name, dialog);
   9.738 -
   9.739 -	BOOL is_do_not_disturb = gAgent.isDoNotDisturb();
   9.740 -	BOOL is_autorespond = gAgent.getAutorespond();
   9.741 -	BOOL is_autorespond_nonfriends = gAgent.getAutorespondNonFriends();
   9.742 -	// <FS:PP> FIRE-1245: Option to block/reject teleport offers
   9.743 -	BOOL is_rejecting_tp_offers = gAgent.getRejectTeleportOffers();
   9.744 -	static LLCachedControl<bool> FSDontRejectTeleportOffersFromFriends(gSavedPerAccountSettings, "FSDontRejectTeleportOffersFromFriends");
   9.745 -	// </FS:PP>
   9.746 -	BOOL is_rejecting_group_invites = gAgent.getRejectAllGroupInvites(); // <FS:PP> Option to block/reject all group invites
   9.747 -	BOOL is_rejecting_friendship_requests = gAgent.getRejectFriendshipRequests(); // <FS:PP> FIRE-15233: Automatic friendship request refusal
   9.748 -	BOOL is_autorespond_muted = gSavedPerAccountSettings.getBOOL("FSSendMutedAvatarResponse");
   9.749 -	BOOL is_muted = LLMuteList::getInstance()->isMuted(from_id, name, LLMute::flagTextChat)
   9.750 -		// object IMs contain sender object id in session_id (STORM-1209)
   9.751 -		|| (dialog == IM_FROM_TASK && LLMuteList::getInstance()->isMuted(session_id));
   9.752 -	BOOL is_owned_by_me = FALSE;
   9.753 -	BOOL is_friend = (LLAvatarTracker::instance().getBuddyInfo(from_id) == NULL) ? false : true;
   9.754 -	static LLCachedControl<bool> accept_im_from_only_friend(gSavedSettings, "VoiceCallsFriendsOnly");
   9.755 -	//BOOL is_linden = chat.mSourceType != CHAT_SOURCE_OBJECT &&
   9.756 -	//		LLMuteList::getInstance()->isLinden(name); <:FS:TM> Bear compie fix - is_linden not referenced
   9.757 -
   9.758 -	// <FS:PP> FIRE-10500: Autoresponse for (Away)
   9.759 -	static LLCachedControl<bool> FSSendAwayAvatarResponse(gSavedPerAccountSettings, "FSSendAwayAvatarResponse");
   9.760 -	BOOL is_afk = gAgent.getAFK();
   9.761 -	// </FS:PP>
   9.762 -
   9.763 -	chat.mMuted = is_muted;
   9.764 -	chat.mFromID = from_id;
   9.765 -	chat.mFromName = name;
   9.766 -	chat.mSourceType = (from_id.isNull() || (name == std::string(SYSTEM_FROM))) ? CHAT_SOURCE_SYSTEM : CHAT_SOURCE_AGENT;
   9.767 -	
   9.768 -	if (chat.mSourceType == CHAT_SOURCE_SYSTEM)
   9.769 -	{ // Translate server message if required (MAINT-6109)
   9.770 -		translate_if_needed(message);
   9.771 -	}
   9.772 -
   9.773 -	LLViewerObject *source = gObjectList.findObject(session_id); //Session ID is probably the wrong thing.
   9.774 -	if (source)
   9.775 -	{
   9.776 -		is_owned_by_me = source->permYouOwner();
   9.777 -	}
   9.778 -
   9.779 -	// NaCl - Newline flood protection
   9.780 -	static LLCachedControl<bool> useAntiSpam(gSavedSettings, "UseAntiSpam");
   9.781 -	if (useAntiSpam && dialog != IM_GROUP_INVITATION)
   9.782 -	{
   9.783 -		bool doCheck = true;
   9.784 -		if (from_id.isNull() || gAgentID == from_id)
   9.785 -		{
   9.786 -			doCheck = false;
   9.787 -		}
   9.788 -		if (doCheck && is_owned_by_me)
   9.789 -		{
   9.790 -			doCheck = false;
   9.791 -		}
   9.792 -		if (doCheck && NACLAntiSpamRegistry::instance().checkNewlineFlood(ANTISPAM_QUEUE_IM, from_id, message))
   9.793 -		{
   9.794 -			return;
   9.795 -		}
   9.796 -	}
   9.797 -	// NaCl End
   9.798 -
   9.799 -	std::string separator_string(": ");
   9.800 -
   9.801 -	LLSD args;
   9.802 -	LLSD payload;
   9.803 -	LLNotification::Params params;
   9.804 -
   9.805 -	switch(dialog)
   9.806 -	{ 
   9.807 -	case IM_CONSOLE_AND_CHAT_HISTORY:
   9.808 -		args["MESSAGE"] = message;
   9.809 -		payload["from_id"] = from_id;
   9.810 -
   9.811 -		params.name = "IMSystemMessageTip";
   9.812 -		params.substitutions = args;
   9.813 -		params.payload = payload;
   9.814 -	    LLPostponedNotification::add<LLPostponedIMSystemTipNotification>(params, from_id, false);
   9.815 -		break;
   9.816 -
   9.817 -	case IM_NOTHING_SPECIAL:	// p2p IM
   9.818 -		// Don't show dialog, just do IM
   9.819 -		if (!gAgent.isGodlike()
   9.820 -				&& gAgent.getRegion()->isPrelude() 
   9.821 -				&& to_id.isNull() )
   9.822 -		{
   9.823 -			// do nothing -- don't distract newbies in
   9.824 -			// Prelude with global IMs
   9.825 -		}
   9.826 -// [RLVa:KB] - Checked: RLVa-2.1.0
   9.827 -		else if ( (RlvActions::isRlvEnabled()) && (offline == IM_ONLINE) && (!is_muted) && ((!accept_im_from_only_friend) || (is_friend)) &&
   9.828 -		          (message.length() > 3) && (RLV_CMD_PREFIX == message[0]) && (RlvHandler::instance().processIMQuery(from_id, message)) )
   9.829 -		{
   9.830 -			// Eat the message and do nothing
   9.831 -			return;
   9.832 -		}
   9.833 -// [/RLVa:KB]
   9.834 -//		else if (offline == IM_ONLINE 
   9.835 -//					&& is_do_not_disturb
   9.836 -//					&& from_id.notNull() //not a system message
   9.837 -//					&& to_id.notNull()) //not global message
   9.838 -// [RLVa:KB] - Checked: 2010-11-30 (RLVa-1.3.0)
   9.839 -		// <FS:Ansariel> Only send the busy reponse if either the sender is not
   9.840 -		//               muted OR the sender is muted and we explicitely want
   9.841 -		//               to inform him about that fact.
   9.842 -		else if (offline == IM_ONLINE
   9.843 -					&& (!accept_im_from_only_friend || is_friend)                                    // is friend or accept IMs from friend only disabled
   9.844 -					&& ((is_do_not_disturb && (!is_muted || (is_muted && !is_autorespond_muted))) || // do not disturb
   9.845 -						(is_autorespond && !is_muted) ||                                             // autorespond everyone
   9.846 -						(is_autorespond_nonfriends && !is_friend && !is_muted) ||                    // autorespond friends only
   9.847 -						(is_afk && FSSendAwayAvatarResponse && !is_muted))                           // away
   9.848 -					&& from_id.notNull() //not a system message
   9.849 -					&& to_id.notNull() //not global message
   9.850 -					&& RlvActions::canReceiveIM(from_id))
   9.851 -// [/RLVa:KB]
   9.852 -		{
   9.853 -			// <FS:Ansariel> Log autoresponse notification after initial message
   9.854 -			bool has_session = true;
   9.855 -
   9.856 -			// <FS:Ansariel> Old "do not disturb" message behavior: only send once if session not open
   9.857 -			// Session id will be null if avatar answers from offline IM via email
   9.858 -			std::string response;
   9.859 -			if (!gIMMgr->hasSession(session_id) && session_id.notNull())
   9.860 -			{
   9.861 -			// </FS:Ansariel>
   9.862 -				// <FS:Ansariel> Log autoresponse notification after initial message
   9.863 -				has_session = false;
   9.864 -				// <FS:Ansariel> FS autoresponse feature
   9.865 -				std::string my_name;
   9.866 -				LLAgentUI::buildFullname(my_name);
   9.867 -				if (is_do_not_disturb)
   9.868 -				{
   9.869 -					response = gSavedPerAccountSettings.getString("DoNotDisturbModeResponse");
   9.870 -				}
   9.871 -				else if (is_autorespond_nonfriends && !is_friend)
   9.872 -				{
   9.873 -					response = gSavedPerAccountSettings.getString("FSAutorespondNonFriendsResponse");
   9.874 -				}
   9.875 -				else if (is_autorespond)
   9.876 -				{
   9.877 -					response = gSavedPerAccountSettings.getString("FSAutorespondModeResponse");
   9.878 -				}
   9.879 -				// <FS:PP> FIRE-10500: Autoresponse for (Away)
   9.880 -				else if (is_afk && FSSendAwayAvatarResponse)
   9.881 -				{
   9.882 -					response = gSavedPerAccountSettings.getString("FSAwayAvatarResponse");
   9.883 -				}
   9.884 -				// </FS:PP>
   9.885 -				else
   9.886 -				{
   9.887 -					LL_WARNS() << "Unknown auto-response mode" << LL_ENDL;
   9.888 -				}
   9.889 -				pack_instant_message(
   9.890 -					gMessageSystem,
   9.891 -					gAgent.getID(),
   9.892 -					FALSE,
   9.893 -					gAgent.getSessionID(),
   9.894 -					from_id,
   9.895 -					my_name,
   9.896 -					response,
   9.897 -					IM_ONLINE,
   9.898 -					IM_DO_NOT_DISTURB_AUTO_RESPONSE,
   9.899 -					session_id);
   9.900 -				gAgent.sendReliableMessage();
   9.901 -				// </FS:Ansariel> FS autoresponse feature
   9.902 -			// <FS:Ansariel> Old "do not disturb" message behavior: only send once if session not open
   9.903 -			}
   9.904 -			// </FS:Ansariel>
   9.905 -
   9.906 -			// <FS:Ansariel> checkfor and process reqinfo
   9.907 -			if (has_session)
   9.908 -			{
   9.909 -				message = FSData::getInstance()->processRequestForInfo(from_id,message,name,session_id);
   9.910 -			}
   9.911 -			// </FS:Ansariel>
   9.912 -
   9.913 -			// now store incoming IM in chat history
   9.914 -
   9.915 -			buffer = message;
   9.916 -	
   9.917 -			LL_DEBUGS("Messaging") << "session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL;
   9.918 -
   9.919 -			// <FS:PP> FIRE-10178: Keyword Alerts in group IM do not work unless the group is in the foreground (notification on receipt of IM)
   9.920 -			chat.mText = buffer;
   9.921 -			bool keyword_alert_performed = false;
   9.922 -			if (FSKeywords::getInstance()->chatContainsKeyword(chat, false))
   9.923 -			{
   9.924 -				FSKeywords::notify(chat);
   9.925 -				keyword_alert_performed = true;
   9.926 -			}
   9.927 -			// </FS:PP>
   9.928 -
   9.929 -			// add to IM panel, but do not bother the user
   9.930 -			gIMMgr->addMessage(
   9.931 -				session_id,
   9.932 -				from_id,
   9.933 -				name,
   9.934 -				buffer,
   9.935 -				IM_OFFLINE == offline,
   9.936 -				LLStringUtil::null,
   9.937 -				dialog,
   9.938 -				parent_estate_id,
   9.939 -				region_id,
   9.940 -				position,
   9.941 -				true,
   9.942 -				false,
   9.943 -				keyword_alert_performed);
   9.944 -
   9.945 -			// <FS:Ansariel> Old "do not disturb" message behavior: only send once if session not open
   9.946 -			//if (!gIMMgr->isDNDMessageSend(session_id))
   9.947 -			//{
   9.948 -			//	// return a standard "do not disturb" message, but only do it to online IM
   9.949 -			//	// (i.e. not other auto responses and not store-and-forward IM)
   9.950 -			//	send_do_not_disturb_message(msg, from_id, session_id);
   9.951 -			//	gIMMgr->setDNDMessageSent(session_id, true);
   9.952 -			//}
   9.953 -			// </FS:Ansariel>
   9.954 -
   9.955 -			if (!has_session)
   9.956 -			{
   9.957 -				// <FS:LO> Fire-5389 - "Autoresponse Sent" message added to Firestorm as was in Phoenix
   9.958 -				LLStringUtil::format_map_t args;
   9.959 -				args["MESSAGE"] = response;
   9.960 -
   9.961 -				gIMMgr->addMessage(
   9.962 -					session_id,
   9.963 -					gAgentID,
   9.964 -					LLStringUtil::null, // Pass null value so no name gets prepended
   9.965 -					LLTrans::getString("IM_autoresponse_sent", args),
   9.966 -					false,
   9.967 -					name,
   9.968 -					IM_NOTHING_SPECIAL,
   9.969 -					parent_estate_id,
   9.970 -					region_id,
   9.971 -					position,
   9.972 -					false,
   9.973 -					true
   9.974 -					);
   9.975 -				// </FS:LO>
   9.976 -
   9.977 -				// <FS:Ansariel> Send inventory item on autoresponse
   9.978 -				LLUUID item_id(gSavedPerAccountSettings.getString("FSAutoresponseItemUUID"));
   9.979 -				if (item_id.notNull())
   9.980 -				{
   9.981 -					LLInventoryItem* item = dynamic_cast<LLInventoryItem*>(gInventory.getItem(item_id));
   9.982 -					if (item)
   9.983 -					{
   9.984 -						gIMMgr->addMessage(
   9.985 -								session_id,
   9.986 -								gAgentID,
   9.987 -								LLStringUtil::null, // Pass null value so no name gets prepended
   9.988 -								LLTrans::getString("IM_autoresponse_item_sent", LLSD().with("[ITEM_NAME]", item->getName())),
   9.989 -								false,
   9.990 -								name,
   9.991 -								IM_NOTHING_SPECIAL,
   9.992 -								parent_estate_id,
   9.993 -								region_id,
   9.994 -								position,
   9.995 -								false,
   9.996 -								true);
   9.997 -						LLGiveInventory::doGiveInventoryItem(from_id, item, session_id);
   9.998 -					}
   9.999 -				}
  9.1000 -				// </FS:Ansariel>
  9.1001 -			}
  9.1002 -		}
  9.1003 -		else if (from_id.isNull())
  9.1004 -		{
  9.1005 -			LLSD args;
  9.1006 -			args["MESSAGE"] = message;
  9.1007 -			LLNotificationsUtil::add("SystemMessage", args);
  9.1008 -		}
  9.1009 -		else if (to_id.isNull())
  9.1010 -		{
  9.1011 -			// Message to everyone from GOD, look up the fullname since
  9.1012 -			// server always slams name to legacy names
  9.1013 -			LLAvatarNameCache::get(from_id, boost::bind(god_message_name_cb, _2, chat, message));
  9.1014 -		}
  9.1015 -		else
  9.1016 -		{
  9.1017 -			// standard message, not from system
  9.1018 -			std::string saved;
  9.1019 -			if(offline == IM_OFFLINE)
  9.1020 -			{
  9.1021 -				LLStringUtil::format_map_t args;
  9.1022 -				args["[LONG_TIMESTAMP]"] = formatted_time(timestamp);
  9.1023 -				saved = LLTrans::getString("Saved_message", args);
  9.1024 -			}
  9.1025 -			buffer = saved + message;
  9.1026 -
  9.1027 -			LL_DEBUGS("Messaging") << "session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL;
  9.1028 -
  9.1029 -			bool mute_im = is_muted;
  9.1030 -			if(accept_im_from_only_friend&&!is_friend)
  9.1031 -			{
  9.1032 -				if (!gIMMgr->isNonFriendSessionNotified(session_id))
  9.1033 -				{
  9.1034 -					// <FS:Ansariel> Disable this - doesn't make sense it will be skipped by LLIMMgr::addMessage() anyway
  9.1035 -					//std::string message = LLTrans::getString("IM_unblock_only_groups_friends");
  9.1036 -					//gIMMgr->addMessage(session_id, from_id, name, message, IM_OFFLINE == offline);
  9.1037 -					// </FS:Ansariel>
  9.1038 -					gIMMgr->addNotifiedNonFriendSessionID(session_id);
  9.1039 -				}
  9.1040 -
  9.1041 -				mute_im = true;
  9.1042 -			}
  9.1043 -
  9.1044 -// [RLVa:KB] - Checked: 2010-11-30 (RLVa-1.3.0)
  9.1045 -			// Don't block offline IMs, or IMs from Lindens
  9.1046 -			if ( (rlv_handler_t::isEnabled()) && (offline != IM_OFFLINE) && (!RlvActions::canReceiveIM(from_id)) && (!LLMuteList::getInstance()->isLinden(original_name) ))
  9.1047 -			{
  9.1048 -				if (!mute_im)
  9.1049 -					RlvUtil::sendBusyMessage(from_id, RlvStrings::getString(RLV_STRING_BLOCKED_RECVIM_REMOTE), session_id);
  9.1050 -				message = RlvStrings::getString(RLV_STRING_BLOCKED_RECVIM);
  9.1051 -			}
  9.1052 -// [/RLVa:KB]
  9.1053 -
  9.1054 -			if (!mute_im) 
  9.1055 -			{
  9.1056 -				// checkfor and process reqinfo
  9.1057 -				message = FSData::getInstance()->processRequestForInfo(from_id, message, name, session_id);
  9.1058 -
  9.1059 -				// <FS:PP> FIRE-10178: Keyword Alerts in group IM do not work unless the group is in the foreground (notification on receipt of IM)
  9.1060 -				chat.mText = message;
  9.1061 -				bool keyword_alert_performed = false;
  9.1062 -				if (FSKeywords::getInstance()->chatContainsKeyword(chat, false))
  9.1063 -				{
  9.1064 -					FSKeywords::notify(chat);
  9.1065 -					keyword_alert_performed = true;
  9.1066 -				}
  9.1067 -				// </FS:PP>
  9.1068 -
  9.1069 -				buffer = saved + message;
  9.1070 -
  9.1071 -				gIMMgr->addMessage(
  9.1072 -					session_id,
  9.1073 -					from_id,
  9.1074 -					name,
  9.1075 -					buffer,
  9.1076 -					IM_OFFLINE == offline,
  9.1077 -					LLStringUtil::null,
  9.1078 -					dialog,
  9.1079 -					parent_estate_id,
  9.1080 -					region_id,
  9.1081 -					position,
  9.1082 -					true,
  9.1083 -					false,
  9.1084 -					keyword_alert_performed);
  9.1085 -			}
  9.1086 -			else
  9.1087 -			{
  9.1088 -				/*
  9.1089 -				EXT-5099
  9.1090 -				currently there is no way to store in history only...
  9.1091 -				using  LLNotificationsUtil::add will add message to Nearby Chat
  9.1092 -
  9.1093 -				// muted user, so don't start an IM session, just record line in chat
  9.1094 -				// history.  Pretend the chat is from a local agent,
  9.1095 -				// so it will go into the history but not be shown on screen.
  9.1096 -
  9.1097 -				LLSD args;
  9.1098 -				args["MESSAGE"] = buffer;
  9.1099 -				LLNotificationsUtil::add("SystemMessageTip", args);
  9.1100 -				*/
  9.1101 -				static LLCachedControl<bool> fsSendMutedAvatarResponse(gSavedPerAccountSettings, "FSSendMutedAvatarResponse");
  9.1102 -				if (fsSendMutedAvatarResponse && (!accept_im_from_only_friend || is_friend))
  9.1103 -				{
  9.1104 -					std::string my_name;
  9.1105 -					LLAgentUI::buildFullname(my_name);
  9.1106 -					std::string response = gSavedPerAccountSettings.getString("FSMutedAvatarResponse");
  9.1107 -					pack_instant_message(
  9.1108 -						gMessageSystem,
  9.1109 -						gAgent.getID(),
  9.1110 -						FALSE,
  9.1111 -						gAgent.getSessionID(),
  9.1112 -						from_id,
  9.1113 -						my_name,
  9.1114 -						response,
  9.1115 -						IM_ONLINE,
  9.1116 -						IM_DO_NOT_DISTURB_AUTO_RESPONSE,
  9.1117 -						session_id);
  9.1118 -					gAgent.sendReliableMessage();
  9.1119 -				}
  9.1120 -
  9.1121 -				// <FS:Ansariel> Don't flash for muted IMs
  9.1122 -				return;
  9.1123 -			}
  9.1124 -		}
  9.1125 -		break;
  9.1126 -
  9.1127 -	case IM_TYPING_START:
  9.1128 -		{
  9.1129 -			LLPointer<LLIMInfo> im_info = new LLIMInfo(gMessageSystem);
  9.1130 -			gIMMgr->processIMTypingStart(im_info);
  9.1131 -		}
  9.1132 -		break;
  9.1133 -
  9.1134 -	case IM_TYPING_STOP:
  9.1135 -		{
  9.1136 -			LLPointer<LLIMInfo> im_info = new LLIMInfo(gMessageSystem);
  9.1137 -			gIMMgr->processIMTypingStop(im_info);
  9.1138 -		}
  9.1139 -		break;
  9.1140 -
  9.1141 -	case IM_MESSAGEBOX:
  9.1142 -		{
  9.1143 -			// This is a block, modeless dialog.
  9.1144 -			//*TODO: Translate
  9.1145 -			args["MESSAGE"] = message;
  9.1146 -			LLNotificationsUtil::add("SystemMessageTip", args);
  9.1147 -		}
  9.1148 -		break;
  9.1149 -	case IM_GROUP_NOTICE:
  9.1150 -	case IM_GROUP_NOTICE_REQUESTED:
  9.1151 -		{
  9.1152 -			LL_INFOS("Messaging") << "Received IM_GROUP_NOTICE message." << LL_ENDL;
  9.1153 -			// Read the binary bucket for more information.
  9.1154 -			struct notice_bucket_header_t
  9.1155 -			{
  9.1156 -				U8 has_inventory;
  9.1157 -				U8 asset_type;
  9.1158 -				LLUUID group_id;
  9.1159 -			};
  9.1160 -			struct notice_bucket_full_t
  9.1161 -			{
  9.1162 -				struct notice_bucket_header_t header;
  9.1163 -				U8 item_name[DB_INV_ITEM_NAME_BUF_SIZE];
  9.1164 -			}* notice_bin_bucket;
  9.1165 -
  9.1166 -			// Make sure the binary bucket is big enough to hold the header 
  9.1167 -			// and a null terminated item name.
  9.1168 -			if ( (binary_bucket_size < (S32)((sizeof(notice_bucket_header_t) + sizeof(U8))))
  9.1169 -				|| (binary_bucket[binary_bucket_size - 1] != '\0') )
  9.1170 -			{
  9.1171 -				LL_WARNS("Messaging") << "Malformed group notice binary bucket" << LL_ENDL;
  9.1172 -				// <FS:Ansariel> Don't flash task icon
  9.1173 -				//break;
  9.1174 -				return;
  9.1175 -			}
  9.1176 -
  9.1177 -			// The group notice packet does not have an AgentID.  Obtain one from the name cache.
  9.1178 -			// If last name is "Resident" strip it out so the cache name lookup works.
  9.1179 -			std::string::size_type index = original_name.find(" Resident");
  9.1180 -			if (index != std::string::npos)
  9.1181 -			{
  9.1182 -				original_name = original_name.substr(0, index);
  9.1183 -			}
  9.1184 -
  9.1185 -			std::string legacy_name = gCacheName->buildLegacyName(original_name);
  9.1186 -			LLUUID agent_id = LLAvatarNameCache::findIdByName(legacy_name);
  9.1187 -
  9.1188 -			if (agent_id.isNull())
  9.1189 -			{
  9.1190 -				LL_WARNS("Messaging") << "buildLegacyName returned null while processing " << original_name << LL_ENDL;
  9.1191 -			}
  9.1192 -			else if (LLMuteList::getInstance()->isMuted(agent_id))
  9.1193 -			{
  9.1194 -				// <FS:Ansariel> Don't flash task icon
  9.1195 -				//break;
  9.1196 -				return;
  9.1197 -			}
  9.1198 -
  9.1199 -			notice_bin_bucket = (struct notice_bucket_full_t*) &binary_bucket[0];
  9.1200 -			U8 has_inventory = notice_bin_bucket->header.has_inventory;
  9.1201 -			U8 asset_type = notice_bin_bucket->header.asset_type;
  9.1202 -			LLUUID group_id = notice_bin_bucket->header.group_id;
  9.1203 -			std::string item_name = ll_safe_string((const char*) notice_bin_bucket->item_name);
  9.1204 -
  9.1205 -			// If there is inventory, give the user the inventory offer.
  9.1206 -			LLOfferInfo* info = NULL;
  9.1207 -
  9.1208 -			if (has_inventory)
  9.1209 -			{
  9.1210 -				info = new LLOfferInfo();
  9.1211 -				
  9.1212 -				info->mIM = IM_GROUP_NOTICE;
  9.1213 -				info->mFromID = from_id;
  9.1214 -				info->mFromGroup = from_group;
  9.1215 -				info->mTransactionID = session_id;
  9.1216 -				info->mType = (LLAssetType::EType) asset_type;
  9.1217 -				info->mFolderID = gInventory.findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(info->mType));
  9.1218 -				std::string from_name;
  9.1219 -
  9.1220 -				// <FS:Ansariel> FIRE-17714: Make group notice attachment confirmation localizable
  9.1221 -				//from_name += "A group member named ";
  9.1222 -				//from_name += name;
  9.1223 -				LLStringUtil::format_map_t args;
  9.1224 -				args["NAME"] = name;
  9.1225 -				from_name += LLTrans::getString("InvOfferGroupNoticeName", args);
  9.1226 -				// </FS:Ansariel>
  9.1227 -
  9.1228 -				info->mFromName = from_name;
  9.1229 -				info->mDesc = item_name;
  9.1230 -				info->mHost = msg->getSender();
  9.1231 -			}
  9.1232 -			
  9.1233 -			std::string str(message);
  9.1234 -
  9.1235 -			// Tokenize the string.
  9.1236 -			// TODO: Support escaped tokens ("||" -> "|")
  9.1237 -			typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
  9.1238 -			boost::char_separator<char> sep("|","",boost::keep_empty_tokens);
  9.1239 -			tokenizer tokens(str, sep);
  9.1240 -			tokenizer::iterator iter = tokens.begin();
  9.1241 -
  9.1242 -			std::string subj(*iter++);
  9.1243 -			std::string mes(*iter++);
  9.1244 -
  9.1245 -			// Send the notification down the new path.
  9.1246 -			// For requested notices, we don't want to send the popups.
  9.1247 -			if (dialog != IM_GROUP_NOTICE_REQUESTED)
  9.1248 -			{
  9.1249 -				payload["subject"] = subj;
  9.1250 -				payload["message"] = mes;
  9.1251 -				payload["sender_name"] = name;
  9.1252 -				payload["sender_id"] = agent_id;
  9.1253 -				payload["group_id"] = group_id;
  9.1254 -				payload["inventory_name"] = item_name;
  9.1255 - 				payload["received_time"] = LLDate::now();
  9.1256 -				if(info && info->asLLSD())
  9.1257 -				{
  9.1258 -					payload["inventory_offer"] = info->asLLSD();
  9.1259 -				}
  9.1260 -
  9.1261 -				// <FS:Ansariel> FIRE-505: Group name not shown in notification well
  9.1262 -				//LLSD args;
  9.1263 -				//args["SUBJECT"] = subj;
  9.1264 -				//LLDate notice_date = LLDate(timestamp).notNull() ? LLDate(timestamp) : LLDate::now();
  9.1265 -				//LLNotifications::instance().add(LLNotification::Params("GroupNotice").substitutions(args).payload(payload).time_stamp(notice_date));
  9.1266 -				//make_ui_sound("UISndGroupNotice"); // <FS:PP> Group notice sound
  9.1267 -				if (group_id.isNull())
  9.1268 -				{
  9.1269 -					LL_WARNS() << "Received group notice with null id!" << LL_ENDL;
  9.1270 -				}
  9.1271 -				gCacheName->get(group_id, true, boost::bind(&notification_group_name_cb, _2, name, subj, mes, payload, timestamp));
  9.1272 -				// </FS:Ansariel>
  9.1273 -			}
  9.1274 -
  9.1275 -			// Also send down the old path for now.
  9.1276 -			if (IM_GROUP_NOTICE_REQUESTED == dialog)
  9.1277 -			{
  9.1278 -				
  9.1279 -				LLPanelGroup::showNotice(subj,mes,group_id,has_inventory,item_name,info);
  9.1280 -			}
  9.1281 -			else
  9.1282 -			{
  9.1283 -				delete info;
  9.1284 -			}
  9.1285 -		}
  9.1286 -		break;
  9.1287 -	case IM_GROUP_INVITATION:
  9.1288 -		{
  9.1289 -			// <FS:Ansariel> FIRE-20385: Don't show group invitation for groups agent is already a member of
  9.1290 -			if (gAgent.isInGroup(from_id) && !gSavedSettings.getBOOL("FSShowJoinedGroupInvitations"))
  9.1291 -			{
  9.1292 -				LL_INFOS("Messaging") << "Received group invitation for group " << from_id << " but we are already a member" << LL_ENDL;
  9.1293 -				return;
  9.1294 -			}
  9.1295 -			// </FS:Ansariel>
  9.1296 -
  9.1297 -			if (!is_muted)
  9.1298 -			{
  9.1299 -				// group is not blocked, but we still need to check agent that sent the invitation
  9.1300 -				// and we have no agent's id
  9.1301 -				// Note: server sends username "first.last".
  9.1302 -				is_muted |= LLMuteList::getInstance()->isMuted(name);
  9.1303 -			}
  9.1304 -			if (is_do_not_disturb || is_muted)
  9.1305 -			{
  9.1306 -				send_do_not_disturb_message(msg, from_id);
  9.1307 -			}
  9.1308 -			
  9.1309 -			if (!is_muted)
  9.1310 -			{
  9.1311 -				LL_INFOS("Messaging") << "Received IM_GROUP_INVITATION message." << LL_ENDL;
  9.1312 -				// Read the binary bucket for more information.
  9.1313 -				struct invite_bucket_t
  9.1314 -				{
  9.1315 -					S32 membership_fee;
  9.1316 -					LLUUID role_id;
  9.1317 -				}* invite_bucket;
  9.1318 -
  9.1319 -				// Make sure the binary bucket is the correct size.
  9.1320 -				if (binary_bucket_size != sizeof(invite_bucket_t))
  9.1321 -				{
  9.1322 -					LL_WARNS("Messaging") << "Malformed group invite binary bucket" << LL_ENDL;
  9.1323 -					// <FS:Ansariel> Don't flash task icon
  9.1324 -					//break;
  9.1325 -					return;
  9.1326 -				}
  9.1327 -
  9.1328 -				invite_bucket = (struct invite_bucket_t*) &binary_bucket[0];
  9.1329 -				S32 membership_fee = ntohl(invite_bucket->membership_fee);
  9.1330 -
  9.1331 -				LLSD payload;
  9.1332 -				payload["transaction_id"] = session_id;
  9.1333 -				payload["group_id"] = from_id;
  9.1334 -				payload["name"] = name;
  9.1335 -				payload["message"] = message;
  9.1336 -				payload["fee"] = membership_fee;
  9.1337 -
  9.1338 -				LLSD args;
  9.1339 -				args["MESSAGE"] = message;
  9.1340 -				// we shouldn't pass callback functor since it is registered in LLFunctorRegistration
  9.1341 -
  9.1342 -				// <FS:PP> Option to block/reject all group invites
  9.1343 -				// LLNotificationsUtil::add("JoinGroup", args, payload);
  9.1344 -				if (is_rejecting_group_invites)
  9.1345 -				{
  9.1346 -					LL_INFOS("Messaging") << "Group invite automatically rejected because of the user setting..." << LL_ENDL;
  9.1347 -					return;
  9.1348 -				}
  9.1349 -				else
  9.1350 -				{
  9.1351 -					make_ui_sound("UISndGroupInvitation"); // <FS:PP> Group invitation sound
  9.1352 -					LLNotificationsUtil::add("JoinGroup", args, payload);
  9.1353 -				}
  9.1354 -				// </FS:PP>
  9.1355 -			}
  9.1356 -			// <FS:Ansariel> Don't flash task icon for group messages from muted senders
  9.1357 -			else
  9.1358 -			{
  9.1359 -				return;
  9.1360 -			}
  9.1361 -			// </FS:Ansariel>
  9.1362 -		}
  9.1363 -		break;
  9.1364 -
  9.1365 -	case IM_INVENTORY_OFFERED:
  9.1366 -	case IM_TASK_INVENTORY_OFFERED:
  9.1367 -		// Someone has offered us some inventory.
  9.1368 -		{
  9.1369 -			LLOfferInfo* info = new LLOfferInfo;
  9.1370 -			if (IM_INVENTORY_OFFERED == dialog)
  9.1371 -			{
  9.1372 -				struct offer_agent_bucket_t
  9.1373 -				{
  9.1374 -					S8		asset_type;
  9.1375 -					LLUUID	object_id;
  9.1376 -				}* bucketp;
  9.1377 -
  9.1378 -				if (sizeof(offer_agent_bucket_t) != binary_bucket_size)
  9.1379 -				{
  9.1380 -					LL_WARNS("Messaging") << "Malformed inventory offer from agent" << LL_ENDL;
  9.1381 -					delete info;
  9.1382 -					// <FS:Ansariel> Don't flash task icon
  9.1383 -					//break;
  9.1384 -					return; 
  9.1385 -				}
  9.1386 -				bucketp = (struct offer_agent_bucket_t*) &binary_bucket[0];
  9.1387 -				info->mType = (LLAssetType::EType) bucketp->asset_type;
  9.1388 -				info->mObjectID = bucketp->object_id;
  9.1389 -				info->mFromObject = FALSE;
  9.1390 -			}
  9.1391 -			else // IM_TASK_INVENTORY_OFFERED
  9.1392 -			{
  9.1393 -				if (sizeof(S8) != binary_bucket_size)
  9.1394 -				{
  9.1395 -					LL_WARNS("Messaging") << "Malformed inventory offer from object" << LL_ENDL;
  9.1396 -					delete info;
  9.1397 -					// <FS:Ansariel> Don't flash task icon
  9.1398 -					//break;
  9.1399 -					return; 
  9.1400 -				}
  9.1401 -				info->mType = (LLAssetType::EType) binary_bucket[0];
  9.1402 -				info->mObjectID = LLUUID::null;
  9.1403 -				info->mFromObject = TRUE;
  9.1404 -			}
  9.1405 -
  9.1406 -			info->mIM = dialog;
  9.1407 -			info->mFromID = from_id;
  9.1408 -			info->mFromGroup = from_group;
  9.1409 -			info->mTransactionID = session_id;
  9.1410 -			info->mFolderID = gInventory.findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(info->mType));
  9.1411 -
  9.1412 -			info->mFromName = name;
  9.1413 -			info->mDesc = message;
  9.1414 -			info->mHost = msg->getSender();
  9.1415 -			//if (((is_do_not_disturb && !is_owned_by_me) || is_muted))
  9.1416 -			if (is_muted)
  9.1417 -			{
  9.1418 -				// Prefetch the offered item so that it can be discarded by the appropriate observer. (EXT-4331)
  9.1419 -				LLInventoryFetchItemsObserver* fetch_item = new LLInventoryFetchItemsObserver(info->mObjectID);
  9.1420 -				fetch_item->startFetch();
  9.1421 -				delete fetch_item;
  9.1422 -
  9.1423 -				// Same as closing window
  9.1424 -				info->forceResponse(IOR_DECLINE);
  9.1425 -			}
  9.1426 -			// old logic: busy mode must not affect interaction with objects (STORM-565)
  9.1427 -			// new logic: inventory offers from in-world objects should be auto-declined (CHUI-519)
  9.1428 -			else if (is_do_not_disturb && dialog == IM_TASK_INVENTORY_OFFERED)
  9.1429 -			{
  9.1430 -				// Until throttling is implemented, do not disturb mode should reject inventory instead of silently
  9.1431 -				// accepting it.  SEE SL-39554
  9.1432 -				info->forceResponse(IOR_DECLINE);
  9.1433 -			}
  9.1434 -			else
  9.1435 -			{
  9.1436 -				inventory_offer_handler(info);
  9.1437 -			}
  9.1438 -		}
  9.1439 -		break;
  9.1440 -
  9.1441 -	case IM_INVENTORY_ACCEPTED:
  9.1442 -	{
  9.1443 -//		args["NAME"] = LLSLURL("agent", from_id, "completename").getSLURLString();;
  9.1444 -//		args["ORIGINAL_NAME"] = original_name;
  9.1445 -// [RLVa:KB] - Checked: RLVa-1.2.2
  9.1446 -		// Only anonymize the name if the agent is nearby, there isn't an open IM session to them and their profile isn't open
  9.1447 -		LLAvatarName av_name;
  9.1448 -		bool fRlvCanShowName = (!RlvActions::isRlvEnabled()) ||
  9.1449 -			(RlvActions::canShowName(RlvActions::SNC_DEFAULT, from_id)) || (!RlvUtil::isNearbyAgent(from_id)) || (RlvUIEnabler::hasOpenProfile(from_id)) || (RlvUIEnabler::hasOpenIM(from_id));
  9.1450 -		args["NAME"] = LLSLURL("agent", from_id, (fRlvCanShowName) ? "completename" : "rlvanonym").getSLURLString();;
  9.1451 -		args["ORIGINAL_NAME"] = fRlvCanShowName ? original_name : (LLAvatarNameCache::get(from_id, &av_name) ? RlvStrings::getAnonym(av_name) : RlvStrings::getAnonym(original_name));
  9.1452 -// [/RLVa:KB]
  9.1453 -		LLSD payload;
  9.1454 -		payload["from_id"] = from_id;
  9.1455 -		// Passing the "SESSION_NAME" to use it for IM notification logging
  9.1456 -		// in LLTipHandler::processNotification(). See STORM-941.
  9.1457 -		payload["SESSION_NAME"] = name;
  9.1458 -		LLNotificationsUtil::add("InventoryAccepted", args, payload);
  9.1459 -		break;
  9.1460 -	}
  9.1461 -	case IM_INVENTORY_DECLINED:
  9.1462 -	{
  9.1463 -//		args["NAME"] = LLSLURL("agent", from_id, "completename").getSLURLString();;
  9.1464 -// [RLVa:KB] - Checked: RLVa-1.2.2
  9.1465 -		// Only anonymize the name if the agent is nearby, there isn't an open IM session to them and their profile isn't open
  9.1466 -		bool fRlvCanShowName = (!RlvActions::isRlvEnabled()) ||
  9.1467 -			(RlvActions::canShowName(RlvActions::SNC_DEFAULT, from_id)) || (!RlvUtil::isNearbyAgent(from_id)) || (RlvUIEnabler::hasOpenProfile(from_id)) || (RlvUIEnabler::hasOpenIM(from_id));
  9.1468 -		args["NAME"] = LLSLURL("agent", from_id, (fRlvCanShowName) ? "completename" : "rlvanonym").getSLURLString();;
  9.1469 -// [/RLVa:KB]
  9.1470 -		LLSD payload;
  9.1471 -		payload["from_id"] = from_id;
  9.1472 -		LLNotificationsUtil::add("InventoryDeclined", args, payload);
  9.1473 -		break;
  9.1474 -	}
  9.1475 -	// TODO: _DEPRECATED suffix as part of vote removal - DEV-24856
  9.1476 -	case IM_GROUP_VOTE:
  9.1477 -		{
  9.1478 -			LL_WARNS("Messaging") << "Received IM: IM_GROUP_VOTE_DEPRECATED" << LL_ENDL;
  9.1479 -		}
  9.1480 -		break;
  9.1481 -
  9.1482 -	case IM_GROUP_ELECTION_DEPRECATED:
  9.1483 -	{
  9.1484 -		LL_WARNS("Messaging") << "Received IM: IM_GROUP_ELECTION_DEPRECATED" << LL_ENDL;
  9.1485 -	}
  9.1486 -	break;
  9.1487 -	
  9.1488 -	case IM_FROM_TASK:
  9.1489 -		{
  9.1490 -
  9.1491 -			if (is_do_not_disturb && !is_owned_by_me)
  9.1492 -			{
  9.1493 -				return;
  9.1494 -			}
  9.1495 -
  9.1496 -			// <FS:PP> FIRE-6406: Feature to disable Object Return notification
  9.1497 -			static LLCachedControl<bool> FSDisableReturnObjectNotification(gSavedSettings, "FSDisableReturnObjectNotification");
  9.1498 -			if (FSDisableReturnObjectNotification)
  9.1499 -			{
  9.1500 -				if (message.find("been returned to your inventory") != -1)
  9.1501 -				{
  9.1502 -					return;
  9.1503 -				}
  9.1504 -			}
  9.1505 -			// </FS:PP>
  9.1506 -
  9.1507 -			// Build a link to open the object IM info window.
  9.1508 -			std::string location = ll_safe_string((char*)binary_bucket, binary_bucket_size-1);
  9.1509 -
  9.1510 -			if (session_id.notNull())
  9.1511 -			{
  9.1512 -				chat.mFromID = session_id;
  9.1513 -			}
  9.1514 -			else
  9.1515 -			{
  9.1516 -				// This message originated on a region without the updated code for task id and slurl information.
  9.1517 -				// We just need a unique ID for this object that isn't the owner ID.
  9.1518 -				// If it is the owner ID it will overwrite the style that contains the link to that owner's profile.
  9.1519 -				// This isn't ideal - it will make 1 style for all objects owned by the the same person/group.
  9.1520 -				// This works because the only thing we can really do in this case is show the owner name and link to their profile.
  9.1521 -				chat.mFromID = from_id ^ gAgent.getSessionID();
  9.1522 -			}
  9.1523 -
  9.1524 -			chat.mSourceType = CHAT_SOURCE_OBJECT;
  9.1525 -			chat.mChatType = CHAT_TYPE_IM;
  9.1526 -
  9.1527 -			// To conclude that the source type of message is CHAT_SOURCE_SYSTEM it's not
  9.1528 -			// enough to check only from name (i.e. fromName = "Second Life"). For example
  9.1529 -			// source type of messages from objects called "Second Life" should not be CHAT_SOURCE_SYSTEM.
  9.1530 -			bool chat_from_system = (SYSTEM_FROM == name) && region_id.isNull() && position.isNull();
  9.1531 -			if(chat_from_system)
  9.1532 -			{
  9.1533 -				// System's UUID is NULL (fixes EXT-4766)
  9.1534 -				chat.mFromID = LLUUID::null;
  9.1535 -				chat.mSourceType = CHAT_SOURCE_SYSTEM;
  9.1536 -			}
  9.1537 -
  9.1538 -			// IDEVO Some messages have embedded resident names
  9.1539 -			message = clean_name_from_task_im(message, from_group);
  9.1540 -
  9.1541 -			LLSD query_string;
  9.1542 -			query_string["owner"] = from_id;
  9.1543 -// [RLVa:KB] - Checked: RLVa-1.2.0
  9.1544 -			if (RlvActions::isRlvEnabled())
  9.1545 -			{
  9.1546 -				// NOTE: the chat message itself will be filtered in LLNearbyChatHandler::processChat()
  9.1547 -				if ( (!RlvActions::canShowName(RlvActions::SNC_DEFAULT)) && (!from_group) && (RlvUtil::isNearbyAgent(from_id)) )
  9.1548 -				{
  9.1549 -					query_string["rlv_shownames"] = TRUE;
  9.1550 -
  9.1551 -					RlvUtil::filterNames(name);
  9.1552 -					chat.mFromName = name;
  9.1553 -				}
  9.1554 -				if (!RlvActions::canShowLocation())
  9.1555 -				{
  9.1556 -					std::string::size_type idxPos = location.find('/');
  9.1557 -					if ( (std::string::npos != idxPos) && (RlvUtil::isNearbyRegion(location.substr(0, idxPos))) )
  9.1558 -						location = RlvStrings::getString(RLV_STRING_HIDDEN_REGION);
  9.1559 -				}
  9.1560 -			}
  9.1561 -// [/RLVa:KB]
  9.1562 -			query_string["slurl"] = location;
  9.1563 -			query_string["name"] = name;
  9.1564 -			if (from_group)
  9.1565 -			{
  9.1566 -				query_string["groupowned"] = "true";
  9.1567 -			}	
  9.1568 -
  9.1569 -//			chat.mURL = LLSLURL("objectim", session_id, "").getSLURLString();
  9.1570 -// [SL:KB] - Checked: 2010-11-02 (RLVa-1.2.2a) | Added: RLVa-1.2.2a
  9.1571 -			chat.mURL = LLSLURL("objectim", session_id, LLURI::mapToQueryString(query_string)).getSLURLString();
  9.1572 -// [/SL:KB]
  9.1573 -			chat.mText = message;
  9.1574 -
  9.1575 -			// <FS:PP> FIRE-10178: Keyword Alerts in group IM do not work unless the group is in the foreground (notification on receipt of Task IM)
  9.1576 -			if (FSKeywords::getInstance()->chatContainsKeyword(chat, true))
  9.1577 -			{
  9.1578 -				FSKeywords::notify(chat);
  9.1579 -			}
  9.1580 -			// </FS:PP>
  9.1581 -
  9.1582 -			// Note: lie to Nearby Chat, pretending that this is NOT an IM, because
  9.1583 -			// IMs from obejcts don't open IM sessions.
  9.1584 -			// <FS:Ansariel> [FS communication UI]
  9.1585 -			//LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
  9.1586 -			FSFloaterNearbyChat* nearby_chat = FSFloaterNearbyChat::getInstance();
  9.1587 -			// </FS:Ansariel> [FS communication UI]
  9.1588 -			if(!chat_from_system && nearby_chat)
  9.1589 -			{
  9.1590 -				chat.mOwnerID = from_id;
  9.1591 -				LLSD args;
  9.1592 -				args["slurl"] = location;
  9.1593 -
  9.1594 -				// Look for IRC-style emotes here so object name formatting is correct
  9.1595 -				// <FS:Ansariel> Consolidate IRC /me prefix checks
  9.1596 -				//std::string prefix = message.substr(0, 4);
  9.1597 -				//if (prefix == "/me " || prefix == "/me'")
  9.1598 -				if (is_irc_me_prefix(message))
  9.1599 -				// </FS:Ansariel>
  9.1600 -				{
  9.1601 -					chat.mChatStyle = CHAT_STYLE_IRC;
  9.1602 -				}
  9.1603 -
  9.1604 -				LLNotificationsUI::LLNotificationManager::instance().onChat(chat, args);
  9.1605 -			}
  9.1606 -
  9.1607 -
  9.1608 -			//Object IMs send with from name: 'Second Life' need to be displayed also in notification toasts (EXT-1590)
  9.1609 -			if (!chat_from_system) break;
  9.1610 -			
  9.1611 -			LLSD substitutions;
  9.1612 -			substitutions["NAME"] = name;
  9.1613 -			substitutions["MSG"] = message;
  9.1614 -
  9.1615 -			LLSD payload;
  9.1616 -			payload["object_id"] = session_id;
  9.1617 -			payload["owner_id"] = from_id;
  9.1618 -			payload["from_id"] = from_id;
  9.1619 -			payload["slurl"] = location;
  9.1620 -			payload["name"] = name;
  9.1621 -
  9.1622 -			if (from_group)
  9.1623 -			{
  9.1624 -				payload["group_owned"] = "true";
  9.1625 -			}
  9.1626 -
  9.1627 -			LLNotificationsUtil::add("ServerObjectMessage", substitutions, payload);
  9.1628 -		}
  9.1629 -		break;
  9.1630 -
  9.1631 -	case IM_SESSION_SEND:		// ad-hoc or group IMs
  9.1632 -
  9.1633 -		// Only show messages if we have a session open (which
  9.1634 -		// should happen after you get an "invitation"
  9.1635 -// [SL:KB] - Patch: Chat-GroupSnooze | Checked: 2012-06-16 (Catznip-3.3)
  9.1636 -		//if ( !gIMMgr->hasSession(session_id) )
  9.1637 -		if ( (!gIMMgr->hasSession(session_id)) &&
  9.1638 -			 ( (!gAgent.isInGroup(session_id)) || (!gIMMgr->checkSnoozeExpiration(session_id)) || LLAvatarActions::isBlocked(from_id) || (!gIMMgr->restoreSnoozedSession(session_id)) ) )
  9.1639 -// [/SL:KB]
  9.1640 -		{
  9.1641 -			return;
  9.1642 -		}
  9.1643 -
  9.1644 -		else if (offline == IM_ONLINE && is_do_not_disturb)
  9.1645 -		{
  9.1646 -
  9.1647 -			// return a standard "do not disturb" message, but only do it to online IM 
  9.1648 -			// (i.e. not other auto responses and not store-and-forward IM)
  9.1649 -			if (!gIMMgr->hasSession(session_id))
  9.1650 -			{
  9.1651 -				// if there is not a panel for this conversation (i.e. it is a new IM conversation
  9.1652 -				// initiated by the other party) then...
  9.1653 -				send_do_not_disturb_message(msg, from_id, session_id);
  9.1654 -			}
  9.1655 -
  9.1656 -			// now store incoming IM in chat history
  9.1657 -
  9.1658 -			buffer = message;
  9.1659 -	
  9.1660 -			LL_DEBUGS("Messaging") << "message in dnd; session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL;
  9.1661 -
  9.1662 -			// add to IM panel, but do not bother the user
  9.1663 -			gIMMgr->addMessage(
  9.1664 -				session_id,
  9.1665 -				from_id,
  9.1666 -				name,
  9.1667 -				buffer,
  9.1668 -				IM_OFFLINE == offline,
  9.1669 -				ll_safe_string((char*)binary_bucket),
  9.1670 -				IM_SESSION_INVITE,
  9.1671 -				parent_estate_id,
  9.1672 -				region_id,
  9.1673 -				position,
  9.1674 -				true);
  9.1675 -		}
  9.1676 -		else
  9.1677 -		{
  9.1678 -
  9.1679 -			// <FS:PP> FIRE-10178: Keyword Alerts in group IM do not work unless the group is in the foreground (notification on receipt of IM)
  9.1680 -			chat.mText = message;
  9.1681 -			bool keyword_alert_performed = false;
  9.1682 -			if (FSKeywords::getInstance()->chatContainsKeyword(chat, false))
  9.1683 -			{
  9.1684 -				FSKeywords::notify(chat);
  9.1685 -				keyword_alert_performed = true;
  9.1686 -			}
  9.1687 -			// </FS:PP>
  9.1688 -
  9.1689 -			// standard message, not from system
  9.1690 -			std::string saved;
  9.1691 -			if(offline == IM_OFFLINE)
  9.1692 -			{
  9.1693 -				saved = llformat("(Saved %s) ", formatted_time(timestamp).c_str());
  9.1694 -			}
  9.1695 -
  9.1696 -			buffer = saved + message;
  9.1697 -
  9.1698 -			LL_DEBUGS("Messaging") << "standard message session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL;
  9.1699 -
  9.1700 -			gIMMgr->addMessage(
  9.1701 -				session_id,
  9.1702 -				from_id,
  9.1703 -				name,
  9.1704 -				buffer,
  9.1705 -				IM_OFFLINE == offline,
  9.1706 -				ll_safe_string((char*)binary_bucket),
  9.1707 -				IM_SESSION_INVITE,
  9.1708 -				parent_estate_id,
  9.1709 -				region_id,
  9.1710 -				position,
  9.1711 -				true,
  9.1712 -				false,
  9.1713 -				keyword_alert_performed);
  9.1714 -		}
  9.1715 -		break;
  9.1716 -
  9.1717 -	case IM_FROM_TASK_AS_ALERT:
  9.1718 -		if (is_do_not_disturb && !is_owned_by_me)
  9.1719 -		{
  9.1720 -			return;
  9.1721 -		}
  9.1722 -		{
  9.1723 -			// Construct a viewer alert for this message.
  9.1724 -			args["NAME"] = name;
  9.1725 -			args["MESSAGE"] = message;
  9.1726 -			LLNotificationsUtil::add("ObjectMessage", args);
  9.1727 -		}
  9.1728 -		break;
  9.1729 -	case IM_DO_NOT_DISTURB_AUTO_RESPONSE:
  9.1730 -		if (is_muted)
  9.1731 -		{
  9.1732 -			LL_DEBUGS("Messaging") << "Ignoring do-not-disturb response from " << from_id << LL_ENDL;
  9.1733 -			return;
  9.1734 -		}
  9.1735 -		else
  9.1736 -		{
  9.1737 -			// <FS:Ansariel> FIRE-12908: Add busy response indicator back to busy messages
  9.1738 -			//gIMMgr->addMessage(session_id, from_id, name, message);
  9.1739 -			buffer = llformat("(%s): %s", LLTrans::getString("BusyResponse").c_str(), message.c_str());
  9.1740 -			gIMMgr->addMessage(session_id, from_id, name, buffer);
  9.1741 -			// </FS:Ansariel>
  9.1742 -		}
  9.1743 -		break;
  9.1744 -		
  9.1745 -	case IM_LURE_USER:
  9.1746 -	case IM_TELEPORT_REQUEST:
  9.1747 -		{
  9.1748 -// [RLVa:KB] - Checked: RLVa-1.4.9
  9.1749 -			// If we auto-accept the offer/request then this will override DnD status (but we'll still let the other party know later)
  9.1750 -			bool fRlvAutoAccept = (rlv_handler_t::isEnabled()) &&
  9.1751 -				( ((IM_LURE_USER == dialog) && (RlvActions::autoAcceptTeleportOffer(from_id))) ||
  9.1752 -				  ((IM_TELEPORT_REQUEST == dialog) && (RlvActions::autoAcceptTeleportRequest(from_id))) );
  9.1753 -// [/RLVa:KB]
  9.1754 -
  9.1755 -			if (is_muted)
  9.1756 -			{ 
  9.1757 -				return;
  9.1758 -			}
  9.1759 -
  9.1760 -			// <FS:PP> FIRE-1245: Option to block/reject teleport offers
  9.1761 -			//else if (gSavedSettings.getBOOL("VoiceCallsFriendsOnly") && (LLAvatarTracker::instance().getBuddyInfo(from_id) == NULL))
  9.1762 -			//{
  9.1763 -			//	return;
  9.1764 -			//}
  9.1765 -			else if ( (is_rejecting_tp_offers && (!FSDontRejectTeleportOffersFromFriends || (FSDontRejectTeleportOffersFromFriends && !is_friend))) && (!fRlvAutoAccept) )
  9.1766 -			{
  9.1767 -				send_rejecting_tp_offers_message(msg, from_id);
  9.1768 -			}
  9.1769 -			// </FS:PP>
  9.1770 -			else
  9.1771 -			{
  9.1772 -//				if (is_do_not_disturb)
  9.1773 -// [RLVa:KB] - Checked: RLVa-1.4.9
  9.1774 -				if ( (is_do_not_disturb) && (!fRlvAutoAccept) )
  9.1775 -// [/RLVa:KB]
  9.1776 -				{
  9.1777 -					send_do_not_disturb_message(msg, from_id);
  9.1778 -				}
  9.1779 -
  9.1780 -				LLVector3 pos, look_at;
  9.1781 -				U64 region_handle(0);
  9.1782 -				U8 region_access(SIM_ACCESS_MIN);
  9.1783 -				std::string region_info = ll_safe_string((char*)binary_bucket, binary_bucket_size);
  9.1784 -				std::string region_access_str = LLStringUtil::null;
  9.1785 -				std::string region_access_icn = LLStringUtil::null;
  9.1786 -				std::string region_access_lc  = LLStringUtil::null;
  9.1787 -
  9.1788 -				bool canUserAccessDstRegion = true;
  9.1789 -				bool doesUserRequireMaturityIncrease = false;
  9.1790 -
  9.1791 -				// Do not parse the (empty) lure bucket for TELEPORT_REQUEST
  9.1792 -				if (IM_TELEPORT_REQUEST != dialog && parse_lure_bucket(region_info, region_handle, pos, look_at, region_access))
  9.1793 -				{
  9.1794 -					region_access_str = LLViewerRegion::accessToString(region_access);
  9.1795 -					region_access_icn = LLViewerRegion::getAccessIcon(region_access);
  9.1796 -					region_access_lc  = region_access_str;
  9.1797 -					LLStringUtil::toLower(region_access_lc);
  9.1798 -
  9.1799 -					if (!gAgent.isGodlike())
  9.1800 -					{
  9.1801 -						switch (region_access)
  9.1802 -						{
  9.1803 -						case SIM_ACCESS_MIN :
  9.1804 -						case SIM_ACCESS_PG :
  9.1805 -							break;
  9.1806 -						case SIM_ACCESS_MATURE :
  9.1807 -							if (gAgent.isTeen())
  9.1808 -							{
  9.1809 -								canUserAccessDstRegion = false;
  9.1810 -							}
  9.1811 -							else if (gAgent.prefersPG())
  9.1812 -							{
  9.1813 -								doesUserRequireMaturityIncrease = true;
  9.1814 -							}
  9.1815 -							break;
  9.1816 -						case SIM_ACCESS_ADULT :
  9.1817 -							if (!gAgent.isAdult())
  9.1818 -							{
  9.1819 -								canUserAccessDstRegion = false;
  9.1820 -							}
  9.1821 -							else if (!gAgent.prefersAdult())
  9.1822 -							{
  9.1823 -								doesUserRequireMaturityIncrease = true;
  9.1824 -							}
  9.1825 -							break;
  9.1826 -						default :
  9.1827 -							llassert(0);
  9.1828 -							break;
  9.1829 -						}
  9.1830 -					}
  9.1831 -				}
  9.1832 -
  9.1833 -// [RLVa:KB] - Checked: RLVa-1.4.9
  9.1834 -				if (rlv_handler_t::isEnabled())
  9.1835 -				{
  9.1836 -					if ( ((IM_LURE_USER == dialog) && (!RlvActions::canAcceptTpOffer(from_id))) ||
  9.1837 -					     ((IM_TELEPORT_REQUEST == dialog) && (!RlvActions::canAcceptTpRequest(from_id))) )
  9.1838 -					{
  9.1839 -						RlvUtil::sendBusyMessage(from_id, RlvStrings::getString(RLV_STRING_BLOCKED_TPLUREREQ_REMOTE));
  9.1840 -						if (is_do_not_disturb)
  9.1841 -							send_do_not_disturb_message(msg, from_id);
  9.1842 -						return;
  9.1843 -					}
  9.1844 -
  9.1845 -					// Censor message if: 1) restricted from receiving IMs from the sender, or 2) teleport offer/request and @showloc=n restricted
  9.1846 -					if ( (!RlvActions::canReceiveIM(from_id)) || 
  9.1847 -						 ((gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) && (IM_LURE_USER == dialog || IM_TELEPORT_REQUEST == dialog)) )
  9.1848 -					{
  9.1849 -						message = RlvStrings::getString(RLV_STRING_HIDDEN);
  9.1850 -					}
  9.1851 -				}
  9.1852 -// [/RLVa:KB]
  9.1853 -
  9.1854 -				LLSD args;
  9.1855 -				// *TODO: Translate -> [FIRST] [LAST] (maybe)
  9.1856 -// [SL:KB] - Patch: UI-Notifications | Checked: 2011-04-11 (Catznip-2.5.0a) | Added: Catznip-2.5.0a
  9.1857 -				args["NAME_LABEL"] = LLSLURL("agent", from_id, "completename").getSLURLString();
  9.1858 -// [/SL:KB]
  9.1859 -				args["NAME_SLURL"] = LLSLURL("agent", from_id, "about").getSLURLString();
  9.1860 -				args["MESSAGE"] = message;
  9.1861 -				args["MATURITY_STR"] = region_access_str;
  9.1862 -				args["MATURITY_ICON"] = region_access_icn;
  9.1863 -				args["REGION_CONTENT_MATURITY"] = region_access_lc;
  9.1864 -				LLSD payload;
  9.1865 -				payload["from_id"] = from_id;
  9.1866 -				payload["lure_id"] = session_id;
  9.1867 -				payload["godlike"] = FALSE;
  9.1868 -				payload["region_maturity"] = region_access;
  9.1869 -
  9.1870 -				// <FS:Ansariel> FIRE-6786: Always show teleport location in teleport offer
  9.1871 -				if (dialog == IM_LURE_USER && (!rlv_handler_t::isEnabled() || !fRlvAutoAccept) && LLGridManager::instance().isInSecondLife())
  9.1872 -				{
  9.1873 -					LLVector3d pos_global = from_region_handle(region_handle);
  9.1874 -					pos_global += LLVector3d(pos);
  9.1875 -					LLLandmarkActions::getSLURLfromPosGlobal(pos_global, boost::bind(&teleport_region_info_cb, _1, args, payload, from_id, session_id, canUserAccessDstRegion, doesUserRequireMaturityIncrease));
  9.1876 -					return;
  9.1877 -				}
  9.1878 -				// </FS:Ansariel>
  9.1879 -
  9.1880 -				if (!canUserAccessDstRegion)
  9.1881 -				{
  9.1882 -					LLNotification::Params params("TeleportOffered_MaturityBlocked");
  9.1883 -					params.substitutions = args;
  9.1884 -					params.payload = payload;
  9.1885 -					LLPostponedNotification::add<LLPostponedOfferNotification>(	params, from_id, false);
  9.1886 -					send_simple_im(from_id, LLTrans::getString("TeleportMaturityExceeded"), IM_NOTHING_SPECIAL, session_id);
  9.1887 -					send_simple_im(from_id, LLStringUtil::null, IM_LURE_DECLINED, session_id);
  9.1888 -				}
  9.1889 -				else if (doesUserRequireMaturityIncrease)
  9.1890 -				{
  9.1891 -					LLNotification::Params params("TeleportOffered_MaturityExceeded");
  9.1892 -					params.substitutions = args;
  9.1893 -					params.payload = payload;
  9.1894 -					LLPostponedNotification::add<LLPostponedOfferNotification>(	params, from_id, false);
  9.1895 -				}
  9.1896 -				else
  9.1897 -				{
  9.1898 -					LLNotification::Params params;
  9.1899 -					if (IM_LURE_USER == dialog)
  9.1900 -					{
  9.1901 -						params.name = "TeleportOffered";
  9.1902 -						params.functor.name = "TeleportOffered";
  9.1903 -					}
  9.1904 -					else if (IM_TELEPORT_REQUEST == dialog)
  9.1905 -					{
  9.1906 -						params.name = "TeleportRequest";
  9.1907 -						params.functor.name = "TeleportRequest";
  9.1908 -					}
  9.1909 -
  9.1910 -					params.substitutions = args;
  9.1911 -					params.payload = payload;
  9.1912 -
  9.1913 -// [RLVa:KB] - Checked: RLVa-1.4.9
  9.1914 -					if (fRlvAutoAccept)
  9.1915 -					{
  9.1916 -						if (IM_LURE_USER == dialog)
  9.1917 -							gRlvHandler.setCanCancelTp(false);
  9.1918 -						if (is_do_not_disturb)
  9.1919 -							send_do_not_disturb_message(msg, from_id);
  9.1920 -						LLNotifications::instance().forceResponse(LLNotification::Params(params.name).payload(payload), 0);
  9.1921 -					}
  9.1922 -					else
  9.1923 -					{
  9.1924 -						LLPostponedNotification::add<LLPostponedOfferNotification>(params, from_id, false);
  9.1925 -					}
  9.1926 -// [/RLVa:KB]
  9.1927 -//					LLPostponedNotification::add<LLPostponedOfferNotification>(	params, from_id, false);
  9.1928 -				}
  9.1929 -			}
  9.1930 -		}
  9.1931 -		break;
  9.1932 -
  9.1933 -	case IM_GODLIKE_LURE_USER:
  9.1934 -		{
  9.1935 -			LLVector3 pos, look_at;
  9.1936 -			U64 region_handle(0);
  9.1937 -			U8 region_access(SIM_ACCESS_MIN);
  9.1938 -			std::string region_info = ll_safe_string((char*)binary_bucket, binary_bucket_size);
  9.1939 -			std::string region_access_str = LLStringUtil::null;
  9.1940 -			std::string region_access_icn = LLStringUtil::null;
  9.1941 -			std::string region_access_lc  = LLStringUtil::null;
  9.1942 -
  9.1943 -			bool canUserAccessDstRegion = true;
  9.1944 -			bool doesUserRequireMaturityIncrease = false;
  9.1945 -
  9.1946 -			if (parse_lure_bucket(region_info, region_handle, pos, look_at, region_access))
  9.1947 -			{
  9.1948 -				region_access_str = LLViewerRegion::accessToString(region_access);
  9.1949 -				region_access_icn = LLViewerRegion::getAccessIcon(region_access);
  9.1950 -				region_access_lc  = region_access_str;
  9.1951 -				LLStringUtil::toLower(region_access_lc);
  9.1952 -
  9.1953 -				if (!gAgent.isGodlike())
  9.1954 -				{
  9.1955 -					switch (region_access)
  9.1956 -					{
  9.1957 -					case SIM_ACCESS_MIN :
  9.1958 -					case SIM_ACCESS_PG :
  9.1959 -						break;
  9.1960 -					case SIM_ACCESS_MATURE :
  9.1961 -						if (gAgent.isTeen())
  9.1962 -						{
  9.1963 -							canUserAccessDstRegion = false;
  9.1964 -						}
  9.1965 -						else if (gAgent.prefersPG())
  9.1966 -						{
  9.1967 -							doesUserRequireMaturityIncrease = true;
  9.1968 -						}
  9.1969 -						break;
  9.1970 -					case SIM_ACCESS_ADULT :
  9.1971 -						if (!gAgent.isAdult())
  9.1972 -						{
  9.1973 -							canUserAccessDstRegion = false;
  9.1974 -						}
  9.1975 -						else if (!gAgent.prefersAdult())
  9.1976 -						{
  9.1977 -							doesUserRequireMaturityIncrease = true;
  9.1978 -						}
  9.1979 -						break;
  9.1980 -					default :
  9.1981 -						llassert(0);
  9.1982 -						break;
  9.1983 -					}
  9.1984 -				}
  9.1985 -			}
  9.1986 -
  9.1987 -			LLSD args;
  9.1988 -			// *TODO: Translate -> [FIRST] [LAST] (maybe)
  9.1989 -			args["NAME_SLURL"] = LLSLURL("agent", from_id, "about").getSLURLString();
  9.1990 -			args["MESSAGE"] = message;
  9.1991 -			args["MATURITY_STR"] = region_access_str;
  9.1992 -			args["MATURITY_ICON"] = region_access_icn;
  9.1993 -			args["REGION_CONTENT_MATURITY"] = region_access_lc;
  9.1994 -			LLSD payload;
  9.1995 -			payload["from_id"] = from_id;
  9.1996 -			payload["lure_id"] = session_id;
  9.1997 -			payload["godlike"] = TRUE;
  9.1998 -			payload["region_maturity"] = region_access;
  9.1999 -
  9.2000 -			if (!canUserAccessDstRegion)
  9.2001 -			{
  9.2002 -				LLNotification::Params params("TeleportOffered_MaturityBlocked");
  9.2003 -				params.substitutions = args;
  9.2004 -				params.payload = payload;
  9.2005 -				LLPostponedNotification::add<LLPostponedOfferNotification>(	params, from_id, false);
  9.2006 -				send_simple_im(from_id, LLTrans::getString("TeleportMaturityExceeded"), IM_NOTHING_SPECIAL, session_id);
  9.2007 -				send_simple_im(from_id, LLStringUtil::null, IM_LURE_DECLINED, session_id);
  9.2008 -			}
  9.2009 -			else if (doesUserRequireMaturityIncrease)
  9.2010 -			{
  9.2011 -				LLNotification::Params params("TeleportOffered_MaturityExceeded");
  9.2012 -				params.substitutions = args;
  9.2013 -				params.payload = payload;
  9.2014 -				LLPostponedNotification::add<LLPostponedOfferNotification>(	params, from_id, false);
  9.2015 -			}
  9.2016 -			else
  9.2017 -			{
  9.2018 -			// do not show a message box, because you're about to be
  9.2019 -			// teleported.
  9.2020 -			LLNotifications::instance().forceResponse(LLNotification::Params("TeleportOffered").payload(payload), 0);
  9.2021 -		}
  9.2022 -		}
  9.2023 -		break;
  9.2024 -
  9.2025 -	case IM_GOTO_URL:
  9.2026 -		{
  9.2027 -			LLSD args;
  9.2028 -			// n.b. this is for URLs sent by the system, not for
  9.2029 -			// URLs sent by scripts (i.e. llLoadURL)
  9.2030 -			if (binary_bucket_size <= 0)
  9.2031 -			{
  9.2032 -				LL_WARNS("Messaging") << "bad binary_bucket_size: "
  9.2033 -					<< binary_bucket_size
  9.2034 -					<< " - aborting function." << LL_ENDL;
  9.2035 -				return;
  9.2036 -			}
  9.2037 -
  9.2038 -			std::string url;
  9.2039 -			
  9.2040 -			url.assign((char*)binary_bucket, binary_bucket_size-1);
  9.2041 -			args["MESSAGE"] = message;
  9.2042 -			args["URL"] = url;
  9.2043 -			LLSD payload;
  9.2044 -			payload["url"] = url;
  9.2045 -			LLNotificationsUtil::add("GotoURL", args, payload );
  9.2046 -		}
  9.2047 -		break;
  9.2048 -
  9.2049 -	case IM_FRIENDSHIP_OFFERED:
  9.2050 -		{
  9.2051 -
  9.2052 -			// <FS:PP> FIRE-15233: Automatic friendship request refusal
  9.2053 -			if (is_rejecting_friendship_requests)
  9.2054 -			{
  9.2055 -				send_rejecting_friendship_requests_message(msg, from_id);
  9.2056 -				return;
  9.2057 -			}
  9.2058 -			// </FS:PP>
  9.2059 -
  9.2060 -			LLSD payload;
  9.2061 -			payload["from_id"] = from_id;
  9.2062 -			payload["session_id"] = session_id;
  9.2063 -			payload["online"] = (offline == IM_ONLINE);
  9.2064 -			payload["sender"] = msg->getSender().getIPandPort();
  9.2065 -
  9.2066 -			bool add_notification = true;
  9.2067 -			for (LLToastNotifyPanel::instance_iter ti(LLToastNotifyPanel::beginInstances())
  9.2068 -				, tend(LLToastNotifyPanel::endInstances()); ti != tend; ++ti)
  9.2069 -			{
  9.2070 -				LLToastNotifyPanel& panel = *ti;
  9.2071 -				const std::string& notification_name = panel.getNotificationName();
  9.2072 -				if (notification_name == "OfferFriendship" && panel.isControlPanelEnabled())
  9.2073 -				{
  9.2074 -					add_notification = false;
  9.2075 -					break;
  9.2076 -				}
  9.2077 -			}
  9.2078 -
  9.2079 -			if (is_muted && add_notification)
  9.2080 -			{
  9.2081 -				LLNotifications::instance().forceResponse(LLNotification::Params("OfferFriendship").payload(payload), 1);
  9.2082 -			}
  9.2083 -			else
  9.2084 -			{
  9.2085 -				if (is_do_not_disturb)
  9.2086 -				{
  9.2087 -					send_do_not_disturb_message(msg, from_id);
  9.2088 -				}
  9.2089 -// [SL:KB] - Patch: UI-Notifications | Checked: 2011-04-11 (Catznip-2.5.0a) | Added: Catznip-2.5.0a
  9.2090 -				args["NAME_LABEL"] = LLSLURL("agent", from_id, "completename").getSLURLString();
  9.2091 -// [/SL:KB]
  9.2092 -				args["NAME_SLURL"] = LLSLURL("agent", from_id, "about").getSLURLString();
  9.2093 -
  9.2094 -				if (add_notification)
  9.2095 -				{
  9.2096 -				if(message.empty())
  9.2097 -				{
  9.2098 -					//support for frienship offers from clients before July 2008
  9.2099 -				        LLNotificationsUtil::add("OfferFriendshipNoMessage", args, payload);
  9.2100 -				        make_ui_sound("UISndFriendshipOffer"); // <FS:PP> Friendship offer sound
  9.2101 -				}
  9.2102 -				else
  9.2103 -				{
  9.2104 -					args["[MESSAGE]"] = message;
  9.2105 -				    LLNotification::Params params("OfferFriendship");
  9.2106 -				    params.substitutions = args;
  9.2107 -				    params.payload = payload;
  9.2108 -				    LLPostponedNotification::add<LLPostponedOfferNotification>(	params, from_id, false);
  9.2109 -				    make_ui_sound("UISndFriendshipOffer"); // <FS:PP> Friendship offer sound
  9.2110 -				}
  9.2111 -			}
  9.2112 -		}
  9.2113 -		}
  9.2114 -		break;
  9.2115 -
  9.2116 -	case IM_FRIENDSHIP_ACCEPTED:
  9.2117 -		{
  9.2118 -			// In the case of an offline IM, the formFriendship() may be extraneous
  9.2119 -			// as the database should already include the relationship.  But it
  9.2120 -			// doesn't hurt for dupes.
  9.2121 -			LLAvatarTracker::formFriendship(from_id);
  9.2122 -			
  9.2123 -			std::vector<std::string> strings;
  9.2124 -			strings.push_back(from_id.asString());
  9.2125 -			send_generic_message("requestonlinenotification", strings);
  9.2126 -			
  9.2127 -			args["NAME"] = name;
  9.2128 -			LLSD payload;
  9.2129 -			payload["from_id"] = from_id;
  9.2130 -			LLAvatarNameCache::get(from_id, boost::bind(&notification_display_name_callback,_1,_2,"FriendshipAccepted",args,payload));
  9.2131 -		}
  9.2132 -		break;
  9.2133 -
  9.2134 -	case IM_FRIENDSHIP_DECLINED_DEPRECATED:
  9.2135 -	default:
  9.2136 -		LL_WARNS("Messaging") << "Instant message calling for unknown dialog "
  9.2137 -				<< (S32)dialog << LL_ENDL;
  9.2138 -		break;
  9.2139 -	}
  9.2140 -
  9.2141 -	LLWindow* viewer_window = gViewerWindow->getWindow();
  9.2142 -	// <FS:CR> Make osx dashboard icon bounce when window isn't in focus
  9.2143 -	//if (viewer_window && viewer_window->getMinimized())
  9.2144 -	static LLCachedControl<bool> sFlashIcon(gSavedSettings, "FSFlashOnMessage");
  9.2145 -	static LLCachedControl<bool> sFSFlashOnObjectIM(gSavedSettings, "FSFlashOnObjectIM");
  9.2146 -	if (viewer_window && dialog != IM_TYPING_START && dialog != IM_TYPING_STOP && sFlashIcon && (sFSFlashOnObjectIM || (chat.mChatType != CHAT_TYPE_IM)) && !is_muted)
  9.2147 -	{
  9.2148 -		viewer_window->flashIcon(5.f);
  9.2149 -	}
  9.2150 +    LLUUID from_id;
  9.2151 +    BOOL from_group;
  9.2152 +    LLUUID to_id;
  9.2153 +    U8 offline;
  9.2154 +    U8 d = 0;
  9.2155 +    LLUUID session_id;
  9.2156 +    U32 timestamp;
  9.2157 +    std::string agentName;
  9.2158 +    std::string message;
  9.2159 +    U32 parent_estate_id = 0;
  9.2160 +    LLUUID region_id;
  9.2161 +    LLVector3 position;
  9.2162 +    U8 binary_bucket[MTUBYTES];
  9.2163 +    S32 binary_bucket_size;
  9.2164 +
  9.2165 +    // *TODO: Translate - need to fix the full name to first/last (maybe)
  9.2166 +    msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, from_id);
  9.2167 +    msg->getBOOLFast(_PREHASH_MessageBlock, _PREHASH_FromGroup, from_group);
  9.2168 +    msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_ToAgentID, to_id);
  9.2169 +    msg->getU8Fast(_PREHASH_MessageBlock, _PREHASH_Offline, offline);
  9.2170 +    msg->getU8Fast(_PREHASH_MessageBlock, _PREHASH_Dialog, d);
  9.2171 +    msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_ID, session_id);
  9.2172 +    msg->getU32Fast(_PREHASH_MessageBlock, _PREHASH_Timestamp, timestamp);
  9.2173 +    //msg->getData("MessageBlock", "Count",		&count);
  9.2174 +    msg->getStringFast(_PREHASH_MessageBlock, _PREHASH_FromAgentName, agentName);
  9.2175 +    msg->getStringFast(_PREHASH_MessageBlock, _PREHASH_Message, message);
  9.2176 +    msg->getU32Fast(_PREHASH_MessageBlock, _PREHASH_ParentEstateID, parent_estate_id);
  9.2177 +    msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_RegionID, region_id);
  9.2178 +    msg->getVector3Fast(_PREHASH_MessageBlock, _PREHASH_Position, position);
  9.2179 +    msg->getBinaryDataFast(_PREHASH_MessageBlock, _PREHASH_BinaryBucket, binary_bucket, 0, 0, MTUBYTES);
  9.2180 +    binary_bucket_size = msg->getSizeFast(_PREHASH_MessageBlock, _PREHASH_BinaryBucket);
  9.2181 +    EInstantMessage dialog = (EInstantMessage)d;
  9.2182 +    LLHost sender = msg->getSender();
  9.2183 +
  9.2184 +    LLIMProcessing::processNewMessage(from_id,
  9.2185 +        from_group,
  9.2186 +        to_id,
  9.2187 +        offline,
  9.2188 +        dialog,
  9.2189 +        session_id,
  9.2190 +        timestamp,
  9.2191 +        agentName,
  9.2192 +        message,
  9.2193 +        parent_estate_id,
  9.2194 +        region_id,
  9.2195 +        position,
  9.2196 +        binary_bucket,
  9.2197 +        binary_bucket_size,
  9.2198 +        sender);
  9.2199  }
  9.2200  
  9.2201  void send_do_not_disturb_message (LLMessageSystem* msg, const LLUUID& from_id, const LLUUID& session_id)
    10.1 --- a/indra/newview/llviewermessage.h	Tue Mar 13 19:50:55 2018 +0100
    10.2 +++ b/indra/newview/llviewermessage.h	Tue Mar 13 19:51:18 2018 +0100
    10.3 @@ -39,6 +39,9 @@
    10.4  #include <boost/function.hpp>
    10.5  #include <boost/signals2.hpp>
    10.6  
    10.7 +#include "llinventorymodel.h" // <FS:Ansariel> For LLOpenAgentOffer
    10.8 +#include "llinventoryobserver.h" // <FS:Ansariel> For LLOpenAgentOffer
    10.9 +
   10.10  //
   10.11  // Forward declarations
   10.12  //
   10.13 @@ -282,6 +285,41 @@
   10.14  	respond_function_map_t mRespondFunctions;
   10.15  };
   10.16  
   10.17 +// <FS:Ansariel> Moved from source; needed in llimprocessing.cpp
   10.18 +class LLOpenAgentOffer : public LLInventoryFetchItemsObserver
   10.19 +{
   10.20 +public:
   10.21 +	LLOpenAgentOffer(const LLUUID& object_id,
   10.22 +					 const std::string& from_name) : 
   10.23 +		LLInventoryFetchItemsObserver(object_id),
   10.24 +		mFromName(from_name) {}
   10.25 +	/*virtual*/ void startFetch()
   10.26 +	{
   10.27 +		for (uuid_vec_t::const_iterator it = mIDs.begin(); it < mIDs.end(); ++it)
   10.28 +		{
   10.29 +			LLViewerInventoryCategory* cat = gInventory.getCategory(*it);
   10.30 +			if (cat)
   10.31 +			{
   10.32 +				mComplete.push_back((*it));
   10.33 +			}
   10.34 +		}
   10.35 +		LLInventoryFetchItemsObserver::startFetch();
   10.36 +	}
   10.37 +	/*virtual*/ void done()
   10.38 +	{
   10.39 +		// <FS:Ansariel> FIRE-3234: Don't need a check for ShowNewInventory here;
   10.40 +		// This only gets called if the user explicity clicks "Show" or
   10.41 +		// AutoAcceptNewInventory and ShowNewInventory are TRUE.
   10.42 +		//open_inventory_offer(mComplete, mFromName);
   10.43 +		open_inventory_offer(mComplete, mFromName, true);
   10.44 +		gInventory.removeObserver(this);
   10.45 +		delete this;
   10.46 +	}
   10.47 +private:
   10.48 +	std::string mFromName;
   10.49 +};
   10.50 +// </FS:Ansariel>
   10.51 +
   10.52  void process_feature_disabled_message(LLMessageSystem* msg, void**);
   10.53  
   10.54  #endif
    11.1 --- a/indra/newview/llviewerregion.cpp	Tue Mar 13 19:50:55 2018 +0100
    11.2 +++ b/indra/newview/llviewerregion.cpp	Tue Mar 13 19:51:18 2018 +0100
    11.3 @@ -3067,6 +3067,7 @@
    11.4  	capabilityNames.append("ParcelVoiceInfoRequest");
    11.5  	capabilityNames.append("ProductInfoRequest");
    11.6  	capabilityNames.append("ProvisionVoiceAccountRequest");
    11.7 +	capabilityNames.append("ReadOfflineMsgs");
    11.8  	capabilityNames.append("RemoteParcelRequest");
    11.9  	capabilityNames.append("RenderMaterials");
   11.10  	capabilityNames.append("RequestTextureDownload");
    12.1 --- a/indra/newview/llworldmapview.cpp	Tue Mar 13 19:50:55 2018 +0100
    12.2 +++ b/indra/newview/llworldmapview.cpp	Tue Mar 13 19:51:18 2018 +0100
    12.3 @@ -1926,10 +1926,14 @@
    12.4  		case MAP_ITEM_LAND_FOR_SALE:
    12.5  		case MAP_ITEM_LAND_FOR_SALE_ADULT:
    12.6  			{
    12.7 -				LLVector3d pos_global = viewPosToGlobal(x, y);
    12.8 -				LLSimInfo* info = LLWorldMap::getInstance()->simInfoFromPosGlobal(pos_global);
    12.9 +				// <FS:Ansariel> Show parcel details instead of search with possible useless result
   12.10 +				//LLVector3d pos_global = viewPosToGlobal(x, y);
   12.11 +				//LLSimInfo* info = LLWorldMap::getInstance()->simInfoFromPosGlobal(pos_global);
   12.12 +				//LLFloaterReg::hideInstance("world_map");
   12.13 +				//LLFloaterReg::showInstance("search", LLSD().with("category", "land").with("query", info->getName()));
   12.14  				LLFloaterReg::hideInstance("world_map");
   12.15 -				LLFloaterReg::showInstance("search", LLSD().with("category", "land").with("query", info->getName()));
   12.16 +				LLUrlAction::executeSLURL(LLSLURL("parcel", id, "about").getSLURLString());
   12.17 +				// </FS:Ansariel>
   12.18  				break;
   12.19  			}
   12.20  		case MAP_ITEM_CLASSIFIED:
    13.1 --- a/indra/newview/qtoolalign.cpp	Tue Mar 13 19:50:55 2018 +0100
    13.2 +++ b/indra/newview/qtoolalign.cpp	Tue Mar 13 19:51:18 2018 +0100
    13.3 @@ -18,6 +18,7 @@
    13.4  #include "llfloatertools.h"
    13.5  #include "llselectmgr.h"
    13.6  #include "llviewercamera.h"
    13.7 +#include "llviewercontrol.h"
    13.8  #include "llviewerobject.h"
    13.9  #include "llviewerwindow.h"
   13.10  
   13.11 @@ -350,8 +351,10 @@
   13.12  
   13.13  BOOL QToolAlign::canAffectSelection()
   13.14  {
   13.15 -	// An selection is scalable if you are allowed to both edit and move
   13.16 -	// everything in it, and it does not have any sitting agents
   13.17 +	// An selection is scalable if you are allowed to move the objects
   13.18 +	// and it does not have any sitting agents. In case of editing linked parts,
   13.19 +	// the object itself has to be modifiable.
   13.20 +	static LLCachedControl<bool> edit_linked_parts(gSavedSettings, "EditLinkedParts");
   13.21  	BOOL can_scale = LLSelectMgr::getInstance()->getSelection()->getObjectCount() != 0;
   13.22  	if (can_scale)
   13.23  	{
   13.24 @@ -359,7 +362,7 @@
   13.25  		{
   13.26  			virtual bool apply(LLViewerObject* objectp)
   13.27  			{
   13.28 -				return objectp->permModify() && objectp->permMove() && !objectp->isSeat();
   13.29 +				return (!edit_linked_parts || objectp->permModify()) && objectp->permMove() && !objectp->isSeat();
   13.30  			}
   13.31  		} func;
   13.32  		can_scale = LLSelectMgr::getInstance()->getSelection()->applyToObjects(&func);
    14.1 --- a/indra/newview/skins/default/xui/de/panel_preferences_colors.xml	Tue Mar 13 19:50:55 2018 +0100
    14.2 +++ b/indra/newview/skins/default/xui/de/panel_preferences_colors.xml	Tue Mar 13 19:51:18 2018 +0100
    14.3 @@ -53,7 +53,7 @@
    14.4  			<text name="object_name_header_label">
    14.5  				Objekte
    14.6  			</text>
    14.7 -			<slider label="Abschwächungsfaktor außerhalb Chat-Reichweite:" label_width="275" name="FSBeyondNearbyChatColorDiminishFactor" tool_tip="Faktor, der dafür verwendet wird, die normale Chatfarbe abzuschwächen, wenn sich der Sender außerhalb der normalen Chatreichweite befindet."/>
    14.8 +			<slider label="Abschwächungsfaktor außerhalb Chat-Reichweite:" label_width="275" name="FSBeyondNearbyChatColorDiminishFactor" tool_tip="Faktor, der dafür verwendet wird, die normale Chatfarbe abzuschwächen, wenn sich der Sender außerhalb der normalen Chatreichweite befindet (0 = dunkel, 1 = hell)."/>
    14.9  			<check_box name="FSColorIMsDistinctly" label="IM/Gruppenchat in Konsole unterschiedlich einfärben:"/>
   14.10  			<panel name="im_color_panel">
   14.11  				<text name="console_im_label">
    15.1 --- a/indra/newview/skins/default/xui/en/panel_preferences_colors.xml	Tue Mar 13 19:50:55 2018 +0100
    15.2 +++ b/indra/newview/skins/default/xui/en/panel_preferences_colors.xml	Tue Mar 13 19:51:18 2018 +0100
    15.3 @@ -538,7 +538,7 @@
    15.4        min_val="0"
    15.5        max_val="1"
    15.6        name="FSBeyondNearbyChatColorDiminishFactor"
    15.7 -      tool_tip="The factor used to diminish the actual chat color if the sender is beyond normal chat range."
    15.8 +      tool_tip="The factor used to diminish the actual chat color if the sender is beyond normal chat range (0 = dim, 1 = bright)"
    15.9        top_pad="20"
   15.10        width="450" />
   15.11       <check_box
    16.1 --- a/indra/newview/skins/default/xui/pl/panel_preferences_colors.xml	Tue Mar 13 19:50:55 2018 +0100
    16.2 +++ b/indra/newview/skins/default/xui/pl/panel_preferences_colors.xml	Tue Mar 13 19:51:18 2018 +0100
    16.3 @@ -50,7 +50,7 @@
    16.4  			<text name="object_name_header_label">
    16.5  				Obiekty
    16.6  			</text>
    16.7 -			<slider label="Współczynnik zanikania koloru poza zasięgiem czatu:" label_width="295" name="FSBeyondNearbyChatColorDiminishFactor" tool_tip="Współczynnik zanikania koloru czcionki czatu dla osób przebywających poza normalnym zasięgiem pisania." />
    16.8 +			<slider label="Współczynnik zanikania koloru poza zasięgiem czatu:" label_width="295" name="FSBeyondNearbyChatColorDiminishFactor" tool_tip="Współczynnik zanikania koloru czcionki czatu dla osób przebywających poza normalnym zasięgiem pisania (0 = ciemny, 1 = jasny)." />
    16.9  			<check_box name="FSColorIMsDistinctly" label="Koloruj czat IM/Grup oddzielnie w konsoli:" />
   16.10  			<panel name="im_color_panel">
   16.11  				<text name="console_im_label">

mercurial