From d2f9e34598621f1dabad15025417efd6b81dddf0 Mon Sep 17 00:00:00 2001
From: James Cook <james@lindenlab.com>
Date: Tue, 23 Mar 2010 11:41:33 -0700
Subject: [PATCH] Part DEV-47695 route display name changes via sim for
 rebroadcast to nearby avatars for name tag updates and to update cached
 display name for LSL nonblocking functions

---
 etc/message.xml                       |  16 +++
 indra/llmessage/llavatarnamecache.h   |   3 +
 indra/newview/CMakeLists.txt          |   2 +
 indra/newview/llpanelme.cpp           |   3 +-
 indra/newview/llviewerdisplayname.cpp | 140 ++++++++++++++++++++++++++
 indra/newview/llviewerdisplayname.h   |  53 ++++++++++
 indra/newview/llviewerregion.cpp      |   1 +
 indra/newview/llvoavatar.cpp          |  12 +++
 indra/newview/llvoavatar.h            |   1 +
 9 files changed, 230 insertions(+), 1 deletion(-)
 create mode 100644 indra/newview/llviewerdisplayname.cpp
 create mode 100644 indra/newview/llviewerdisplayname.h

diff --git a/etc/message.xml b/etc/message.xml
index c17ae3656d0..ebbb4e57a96 100644
--- a/etc/message.xml
+++ b/etc/message.xml
@@ -370,6 +370,14 @@
 				</map>
 
 				<!-- Server to client -->
+				<key>DisplayNameUpdate</key>
+				<map>
+					<key>flavor</key>
+					<string>llsd</string>
+					<key>trusted-sender</key>
+					<boolean>true</boolean>
+				</map>
+                
 				<key>ParcelVoiceInfo</key>
 				<map>
 					<key>flavor</key>
@@ -426,6 +434,14 @@
           <boolean>true</boolean>
         </map>
 
+        <key>SetDisplayNameReply</key>
+        <map>
+          <key>flavor</key>
+          <string>llsd</string>
+          <key>trusted-sender</key>
+          <boolean>true</boolean>
+        </map>
+
         <key>DirLandReply</key>
         <map>
           <key>flavor</key>
diff --git a/indra/llmessage/llavatarnamecache.h b/indra/llmessage/llavatarnamecache.h
index 8fc43860da1..17990ecab9c 100644
--- a/indra/llmessage/llavatarnamecache.h
+++ b/indra/llmessage/llavatarnamecache.h
@@ -66,6 +66,9 @@ namespace LLAvatarNameCache
 	// If name information is in cache, callback will be called immediately.
 	void get(const LLUUID& agent_id, callback_slot_t slot);
 
+	// JAMESDEBUG TODO: remove code to set display name, handle in 
+	// application layer because it's different for client and server
+
 	// Callback types for setDisplayName() below
 	typedef boost::signals2::signal<
 		void (bool success, const std::string& reason, const LLSD& content)>
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 7b306d03ab9..3f2e12abef8 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -456,6 +456,7 @@ set(viewer_SOURCE_FILES
     llviewercontrol.cpp
     llviewercontrollistener.cpp
     llviewerdisplay.cpp
+    llviewerdisplayname.cpp
     llviewerfloaterreg.cpp
     llviewerfoldertype.cpp
     llviewergenericmessage.cpp
@@ -957,6 +958,7 @@ set(viewer_HEADER_FILES
     llviewercontrol.h
     llviewercontrollistener.h
     llviewerdisplay.h
+    llviewerdisplayname.h
     llviewerfloaterreg.h
     llviewerfoldertype.h
     llviewergenericmessage.h
diff --git a/indra/newview/llpanelme.cpp b/indra/newview/llpanelme.cpp
index d6c7d7ea8dc..aa199523173 100644
--- a/indra/newview/llpanelme.cpp
+++ b/indra/newview/llpanelme.cpp
@@ -41,6 +41,7 @@
 #include "llagentwearables.h"
 #include "llsidetray.h"
 #include "llviewercontrol.h"
+#include "llviewerdisplayname.h"
 
 // Linden libraries
 #include "llavatarnamecache.h"		// IDEVO
@@ -332,7 +333,7 @@ void LLPanelMyProfileEdit::onDialogSetName(const LLSD& notification, const LLSD&
 		if (agent_id.isNull()) return;
 
 		std::string display_name = response["display_name"].asString();
-		LLAvatarNameCache::setDisplayName(agent_id, display_name,
+		LLViewerDisplayName::set(display_name,
 			boost::bind(&LLPanelMyProfileEdit::onCacheSetName, this,
 				_1, _2, _3));
 	}
diff --git a/indra/newview/llviewerdisplayname.cpp b/indra/newview/llviewerdisplayname.cpp
new file mode 100644
index 00000000000..587d745e517
--- /dev/null
+++ b/indra/newview/llviewerdisplayname.cpp
@@ -0,0 +1,140 @@
+/** 
+ * @file llviewerdisplayname.cpp
+ * @brief Wrapper for display name functionality
+ *
+ * $LicenseInfo:firstyear=2010&license=viewergpl$
+ * 
+ * Copyright (c) 2010, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+#include "llviewerprecompiledheaders.h"
+
+#include "llviewerdisplayname.h"
+
+// viewer includes
+#include "llagent.h"
+#include "llviewerregion.h"
+#include "llvoavatar.h"
+
+// library includes
+#include "llavatarnamecache.h"
+#include "llhttpclient.h"
+#include "llhttpnode.h"
+
+namespace LLViewerDisplayName
+{
+	// Fired when viewer receives server response to display name change
+	set_name_signal_t sSetDisplayNameSignal;
+}
+
+class LLSetDisplayNameResponder : public LLHTTPClient::Responder
+{
+public:
+	// only care about errors
+	/*virtual*/ void error(U32 status, const std::string& reason)
+	{
+		LLViewerDisplayName::sSetDisplayNameSignal(false, "", LLSD());
+		LLViewerDisplayName::sSetDisplayNameSignal.disconnect_all_slots();
+	}
+};
+
+void LLViewerDisplayName::set(const std::string& display_name, const set_name_slot_t& slot)
+{
+	// TODO: simple validation here
+
+	LLViewerRegion* region = gAgent.getRegion();
+	llassert(region);
+	std::string cap_url = region->getCapability("SetDisplayName");
+	if (cap_url.empty())
+	{
+		// this server does not support display names, report error
+		slot(false, "unsupported", LLSD());
+		return;
+	}
+
+	llinfos << "JAMESDEBUG POST to " << cap_url << llendl;
+
+	// Record our caller for when the server sends back a reply
+	sSetDisplayNameSignal.connect(slot);
+
+	// POST the requested change.  The sim will not send a response back to
+	// this request directly, rather it will send a separate message after it
+	// communicates with the back-end.
+	LLSD body;
+	body["display_name"] = display_name;
+	LLHTTPClient::post(cap_url, body, new LLSetDisplayNameResponder);
+}
+
+class LLSetDisplayNameReply : public LLHTTPNode
+{
+	/*virtual*/ void post(
+		LLHTTPNode::ResponsePtr response,
+		const LLSD& context,
+		const LLSD& input) const
+	{
+		LLSD body = input["body"];
+
+		S32 status = body["status"].asInteger();
+		bool success = (status == 200);
+		std::string reason = body["reason"].asString();
+		LLSD content = body["content"];
+
+		llinfos << "JAMESDEBUG LLSetDisplayNameReply status " << status
+			<< " reason " << reason << llendl;
+
+		// inform caller of result
+		LLViewerDisplayName::sSetDisplayNameSignal(success, reason, content);
+		LLViewerDisplayName::sSetDisplayNameSignal.disconnect_all_slots();
+	}
+};
+
+class LLDisplayNameUpdate : public LLHTTPNode
+{
+	/*virtual*/ void post(
+		LLHTTPNode::ResponsePtr response,
+		const LLSD& context,
+		const LLSD& input) const
+	{
+		LLSD body = input["body"];
+		LLUUID agent_id = body["agent_id"];
+
+		llinfos << "JAMESDEBUG LLDisplayNameUpdate agent_id "
+			<< agent_id << llendl;
+
+		// force re-request of this agent's name data
+		LLAvatarNameCache::erase(agent_id);
+
+		// force name tag to update
+		LLVOAvatar::invalidateNameTag(agent_id);
+	}
+};
+
+LLHTTPRegistration<LLSetDisplayNameReply>
+    gHTTPRegistrationMessageSetDisplayNameReply(
+		"/message/SetDisplayNameReply");
+
+LLHTTPRegistration<LLDisplayNameUpdate>
+    gHTTPRegistrationMessageDisplayNameUpdate(
+		"/message/DisplayNameUpdate");
diff --git a/indra/newview/llviewerdisplayname.h b/indra/newview/llviewerdisplayname.h
new file mode 100644
index 00000000000..c77388531bc
--- /dev/null
+++ b/indra/newview/llviewerdisplayname.h
@@ -0,0 +1,53 @@
+/** 
+ * @file llviewerdisplayname.h
+ * @brief Wrapper for display name functionality
+ *
+ * $LicenseInfo:firstyear=2010&license=viewergpl$
+ * 
+ * Copyright (c) 2010, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+#ifndef LLVIEWERDISPLAYNAME_H
+#define LLVIEWERDISPLAYNAME_H
+
+#include <boost/signals2.hpp>
+
+class LLSD;
+class LLUUID;
+
+namespace LLViewerDisplayName
+{
+	typedef boost::signals2::signal<
+		void (bool success, const std::string& reason, const LLSD& content)>
+			set_name_signal_t;
+	typedef set_name_signal_t::slot_type set_name_slot_t;
+
+	// Sends an update to the server to change a display name
+	// and call back when done.  May not succeed due to service
+	// unavailable or name not available.
+	void set(const std::string& display_name, const set_name_slot_t& slot);
+}
+
+#endif // LLVIEWERDISPLAYNAME_H
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index ce627494c8f..8f43b6bcf73 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -1495,6 +1495,7 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
 	capabilityNames.append("SendUserReport");
 	capabilityNames.append("SendUserReportWithScreenshot");
 	capabilityNames.append("ServerReleaseNotes");
+	capabilityNames.append("SetDisplayName");
 	capabilityNames.append("StartGroupProposal");
 	capabilityNames.append("TextureStats");
 	capabilityNames.append("UntrustedSimulatorMessage");
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 4c8bb0ac138..f3850d58a13 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -3004,6 +3004,18 @@ void LLVOAvatar::clearNameTag()
 	}
 }
 
+//static
+void LLVOAvatar::invalidateNameTag(const LLUUID& agent_id)
+{
+	LLViewerObject* obj = gObjectList.findObject(agent_id);
+	if (!obj) return;
+
+	LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(obj);
+	if (!avatar) return;
+
+	avatar->clearNameTag();
+}
+
 // Compute name tag position during idle update
 LLVector3 LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last)
 {
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index c31369358ca..65343c9058d 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -215,6 +215,7 @@ class LLVOAvatar :
 	void			idleUpdateNameTagAlpha(BOOL new_name, F32 alpha);
 	LLColor4		getNameTagColor(bool is_friend);
 	void			clearNameTag();
+	static void		invalidateNameTag(const LLUUID& agent_id);
 	void			addNameTagLine(const std::string& line, const LLColor4& color, S32 style, const LLFontGL* font);
 	void 			idleUpdateRenderCost();
 	void 			idleUpdateTractorBeam();
-- 
GitLab