From a2105d170261608cf515e1698b9b473d6e73558b Mon Sep 17 00:00:00 2001
From: Igor Borovkov <iborovkov@productengine.com>
Date: Fri, 22 Jan 2010 18:10:07 +0200
Subject: [PATCH] implemented EXT-4523 Log for all Ad-Hoc conferences is stored
 in one file

* for outgoing ad-hoc sessions chat history is saved into new file for every distinct set of initial participants
format: ["Ad-hoc Conference" "hash"<md5 hash of sorted participants' UUIDs>.txt]
ex: Ad-hoc Conference hash77a0ff26-614d-0dbd-ce19-5da9108f141a.txt

* for incoming ad-hoc sessions, chat history of each session is saved into a separate file:
format: [<ad-hoc session name> <timestamp> <4 first symbols of session id>.txt]
ex: Igor ProductEngine Conference 2010_01_22 07_41 2752.txt

--HG--
branch : product-engine
---
 indra/newview/llimview.cpp  | 69 ++++++++++++++++++++++++++++++-------
 indra/newview/llimview.h    | 14 +++++++-
 indra/newview/lllogchat.cpp |  6 ++--
 indra/newview/lllogchat.h   |  2 +-
 4 files changed, 74 insertions(+), 17 deletions(-)

diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index ff20a55358c..c2a7969c0d0 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -55,6 +55,7 @@
 #include "llfloaterchatterbox.h"
 #include "llimfloater.h"
 #include "llgroupiconctrl.h"
+#include "llmd5.h"
 #include "llmutelist.h"
 #include "llrecentpeople.h"
 #include "llviewermessage.h"
@@ -215,12 +216,14 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string&
 		mTextIMPossible = LLVoiceClient::getInstance()->isSessionTextIMPossible(mSessionID);
 	}
 
+	buildHistoryFileName();
+
 	if ( gSavedPerAccountSettings.getBOOL("LogShowHistory") )
 	{
 		std::list<LLSD> chat_history;
 
 		//involves parsing of a chat history
-		LLLogChat::loadAllHistory(mName, chat_history);
+		LLLogChat::loadAllHistory(mHistoryFileName, chat_history);
 		addMessagesFromHistory(chat_history);
 	}
 }
@@ -467,6 +470,44 @@ bool LLIMModel::LLIMSession::isOtherParticipantAvaline()
 	return !mOtherParticipantIsAvatar;
 }
 
+void LLIMModel::LLIMSession::buildHistoryFileName()
+{
+	mHistoryFileName = mName;
+	
+	//ad-hoc requires sophisticated chat history saving schemes
+	if (isAdHoc())
+	{
+		//in case of outgoing ad-hoc sessions
+		if (mInitialTargetIDs.size())
+		{
+			std::set<LLUUID> sorted_uuids(mInitialTargetIDs.begin(), mInitialTargetIDs.end());
+			mHistoryFileName = mName + " hash" + generateHash(sorted_uuids);
+			return;
+		}
+		
+		//in case of incoming ad-hoc sessions
+		mHistoryFileName = mName + " " + LLLogChat::timestamp(true) + " " + mSessionID.asString().substr(0, 4);
+	}
+}
+
+//static
+std::string LLIMModel::LLIMSession::generateHash(const std::set<LLUUID>& sorted_uuids)
+{
+	LLMD5 md5_uuid;
+	
+	std::set<LLUUID>::const_iterator it = sorted_uuids.begin();
+	while (it != sorted_uuids.end())
+	{
+		md5_uuid.update((unsigned char*)(*it).mData, 16);
+		it++;
+	}
+	md5_uuid.finalize();
+
+	LLUUID participants_md5_hash;
+	md5_uuid.raw_digest((unsigned char*) participants_md5_hash.mData);
+	return participants_md5_hash.asString();
+}
+
 
 void LLIMModel::processSessionInitializedReply(const LLUUID& old_session_id, const LLUUID& new_session_id)
 {
@@ -614,11 +655,11 @@ bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from,
 	return true;
 }
 
-bool LLIMModel::logToFile(const std::string& session_name, const std::string& from, const LLUUID& from_id, const std::string& utf8_text)
+bool LLIMModel::logToFile(const std::string& file_name, const std::string& from, const LLUUID& from_id, const std::string& utf8_text)
 {
 	if (gSavedPerAccountSettings.getBOOL("LogInstantMessages"))
 	{
-		LLLogChat::saveHistory(session_name, from, from_id, utf8_text);
+		LLLogChat::saveHistory(file_name, from, from_id, utf8_text);
 		return true;
 	}
 	else
@@ -629,15 +670,7 @@ bool LLIMModel::logToFile(const std::string& session_name, const std::string& fr
 
 bool LLIMModel::logToFile(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text)
 {
-	if (gSavedPerAccountSettings.getBOOL("LogInstantMessages"))
-	{
-		LLLogChat::saveHistory(LLIMModel::getInstance()->getName(session_id), from, from_id, utf8_text);
-		return true;
-	}
-	else
-	{
-		return false;
-	}
+	return logToFile(LLIMModel::getInstance()->getHistoryFileName(session_id), from, from_id, utf8_text);
 }
 
 bool LLIMModel::proccessOnlineOfflineNotification(
@@ -782,6 +815,18 @@ LLIMSpeakerMgr* LLIMModel::getSpeakerManager( const LLUUID& session_id ) const
 	return session->mSpeakers;
 }
 
+const std::string& LLIMModel::getHistoryFileName(const LLUUID& session_id) const
+{
+	LLIMSession* session = findIMSession(session_id);
+	if (!session)
+	{
+		llwarns << "session " << session_id << " does not exist " << llendl;
+		return LLStringUtil::null;
+	}
+
+	return session->mHistoryFileName;
+}
+
 
 // TODO get rid of other participant ID
 void LLIMModel::sendTypingState(LLUUID session_id, LLUUID other_participant_id, BOOL typing) 
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index a226d66b12e..a3b4f78af0c 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -69,6 +69,8 @@ class LLIMModel :  public LLSingleton<LLIMModel>
 		void addMessagesFromHistory(const std::list<LLSD>& history);
 		void addMessage(const std::string& from, const LLUUID& from_id, const std::string& utf8_text, const std::string& time);
 		void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state, const LLVoiceChannel::EDirection& direction);
+		
+		/** @deprecated */
 		static void chatFromLogFile(LLLogChat::ELogLineType type, const LLSD& msg, void* userdata);
 
 		bool isAdHoc();
@@ -80,12 +82,20 @@ class LLIMModel :  public LLSingleton<LLIMModel>
 		bool isGroupSessionType() const { return mSessionType == GROUP_SESSION;}
 		bool isAvalineSessionType() const { return mSessionType == AVALINE_SESSION;}
 
+		//*TODO make private
+		/** ad-hoc sessions involve sophisticated chat history file naming schemes */
+		void buildHistoryFileName();
+
+		//*TODO make private
+		static std::string generateHash(const std::set<LLUUID>& sorted_uuids);
+
 		LLUUID mSessionID;
 		std::string mName;
 		EInstantMessage mType;
 		SType mSessionType;
 		LLUUID mOtherParticipantID;
 		std::vector<LLUUID> mInitialTargetIDs;
+		std::string mHistoryFileName;
 
 		// connection to voice channel state change signal
 		boost::signals2::connection mVoiceChannelStateChangeConnection;
@@ -231,6 +241,8 @@ class LLIMModel :  public LLSingleton<LLIMModel>
 	*/
 	LLIMSpeakerMgr* getSpeakerManager(const LLUUID& session_id) const;
 
+	const std::string& getHistoryFileName(const LLUUID& session_id) const;
+
 	static void sendLeaveSession(const LLUUID& session_id, const LLUUID& other_participant_id);
 	static bool sendStartSession(const LLUUID& temp_session_id, const LLUUID& other_participant_id,
 						  const std::vector<LLUUID>& ids, EInstantMessage dialog);
@@ -243,7 +255,7 @@ class LLIMModel :  public LLSingleton<LLIMModel>
 	/**
 	 * Saves an IM message into a file
 	 */
-	bool logToFile(const std::string& session_name, const std::string& from, const LLUUID& from_id, const std::string& utf8_text);
+	bool logToFile(const std::string& file_name, const std::string& from, const LLUUID& from_id, const std::string& utf8_text);
 
 private:
 	
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index 4e5aaeb66ad..dc187bf36cc 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -237,15 +237,15 @@ void append_to_last_message(std::list<LLSD>& messages, const std::string& line)
 	messages.back()[IM_TEXT] = im_text;
 }
 
-void LLLogChat::loadAllHistory(const std::string& session_name, std::list<LLSD>& messages)
+void LLLogChat::loadAllHistory(const std::string& file_name, std::list<LLSD>& messages)
 {
-	if (session_name.empty())
+	if (file_name.empty())
 	{
 		llwarns << "Session name is Empty!" << llendl;
 		return ;
 	}
 
-	LLFILE* fptr = LLFile::fopen(makeLogFileName(session_name), "r");		/*Flawfinder: ignore*/
+	LLFILE* fptr = LLFile::fopen(makeLogFileName(file_name), "r");		/*Flawfinder: ignore*/
 	if (!fptr) return;	//No previous conversation with this name.
 
 	char buffer[LOG_RECALL_SIZE];		/*Flawfinder: ignore*/
diff --git a/indra/newview/lllogchat.h b/indra/newview/lllogchat.h
index 3d3f5c44587..4290e4bbc08 100644
--- a/indra/newview/lllogchat.h
+++ b/indra/newview/lllogchat.h
@@ -56,7 +56,7 @@ class LLLogChat
 		                    void (*callback)(ELogLineType, const LLSD&, void*), 
 							void* userdata);
 
-	static void loadAllHistory(const std::string& session_name, std::list<LLSD>& messages);
+	static void loadAllHistory(const std::string& file_name, std::list<LLSD>& messages);
 private:
 	static std::string cleanFileName(std::string filename);
 };
-- 
GitLab