From f323955099eb19f5ff3969d09db05f58a842b95b Mon Sep 17 00:00:00 2001
From: Howaner <franzi.moos@googlemail.com>
Date: Sat, 13 Sep 2014 20:27:10 +0200
Subject: [PATCH] Moved chat json creating to the CompositeChat class.

---
 src/CompositeChat.cpp        | 178 +++++++++++++++++++++++++++++++++++
 src/CompositeChat.h          |   6 ++
 src/Protocol/Protocol17x.cpp | 173 +---------------------------------
 src/Protocol/Protocol17x.h   |   4 +-
 src/Protocol/Protocol18x.cpp | 173 +---------------------------------
 src/Protocol/Protocol18x.h   |   4 +-
 6 files changed, 192 insertions(+), 346 deletions(-)

diff --git a/src/CompositeChat.cpp b/src/CompositeChat.cpp
index 0d339021e..d1eb0b852 100644
--- a/src/CompositeChat.cpp
+++ b/src/CompositeChat.cpp
@@ -5,6 +5,7 @@
 
 #include "Globals.h"
 #include "CompositeChat.h"
+#include "ClientHandle.h"
 
 
 
@@ -399,6 +400,183 @@ void cCompositeChat::AddStyle(AString & a_Style, const AString & a_AddStyle)
 
 
 
+AString cCompositeChat::CreateJsonString(bool a_ShouldUseChatPrefixes) const
+{
+	Json::Value msg;
+	msg["text"] = cClientHandle::FormatMessageType(a_ShouldUseChatPrefixes, GetMessageType(), GetAdditionalMessageTypeData());  // The client crashes without this field being present
+	const cCompositeChat::cParts & Parts = GetParts();
+	for (cCompositeChat::cParts::const_iterator itr = Parts.begin(), end = Parts.end(); itr != end; ++itr)
+	{
+		Json::Value Part;
+		switch ((*itr)->m_PartType)
+		{
+			case cCompositeChat::ptText:
+			{
+				Part["text"] = (*itr)->m_Text;
+				AddChatPartStyle(Part, (*itr)->m_Style);
+				break;
+			}
+			
+			case cCompositeChat::ptClientTranslated:
+			{
+				const cCompositeChat::cClientTranslatedPart & p = (const cCompositeChat::cClientTranslatedPart &)**itr;
+				Part["translate"] = p.m_Text;
+				Json::Value With;
+				for (AStringVector::const_iterator itrW = p.m_Parameters.begin(), endW = p.m_Parameters.end(); itrW != endW; ++itr)
+				{
+					With.append(*itrW);
+				}
+				if (!p.m_Parameters.empty())
+				{
+					Part["with"] = With;
+				}
+				AddChatPartStyle(Part, p.m_Style);
+				break;
+			}
+			
+			case cCompositeChat::ptUrl:
+			{
+				const cCompositeChat::cUrlPart & p = (const cCompositeChat::cUrlPart &)**itr;
+				Part["text"] = p.m_Text;
+				Json::Value Url;
+				Url["action"] = "open_url";
+				Url["value"] = p.m_Url;
+				Part["clickEvent"] = Url;
+				AddChatPartStyle(Part, p.m_Style);
+				break;
+			}
+			
+			case cCompositeChat::ptSuggestCommand:
+			case cCompositeChat::ptRunCommand:
+			{
+				const cCompositeChat::cCommandPart & p = (const cCompositeChat::cCommandPart &)**itr;
+				Part["text"] = p.m_Text;
+				Json::Value Cmd;
+				Cmd["action"] = (p.m_PartType == cCompositeChat::ptRunCommand) ? "run_command" : "suggest_command";
+				Cmd["value"] = p.m_Command;
+				Part["clickEvent"] = Cmd;
+				AddChatPartStyle(Part, p.m_Style);
+				break;
+			}
+
+			case cCompositeChat::ptShowAchievement:
+			{
+				const cCompositeChat::cShowAchievementPart & p = (const cCompositeChat::cShowAchievementPart &)**itr;
+				Part["translate"] = "chat.type.achievement";
+
+				Json::Value Ach;
+				Ach["action"] = "show_achievement";
+				Ach["value"] = p.m_Text;
+				
+				Json::Value AchColourAndName;
+				AchColourAndName["color"] = "green";
+				AchColourAndName["translate"] = p.m_Text;
+				AchColourAndName["hoverEvent"] = Ach;
+
+				Json::Value Extra;
+				Extra.append(AchColourAndName);
+
+				Json::Value Name;
+				Name["text"] = p.m_PlayerName;
+
+				Json::Value With;
+				With.append(Name);
+				With.append(Extra);
+
+				Part["with"] = With;
+				AddChatPartStyle(Part, p.m_Style);
+				break;
+			}
+		}
+		msg["extra"].append(Part);
+	}  // for itr - Parts[]
+
+	return msg.toStyledString();
+}
+
+
+
+
+
+void cCompositeChat::AddChatPartStyle(Json::Value & a_Value, const AString & a_PartStyle) const
+{
+	size_t len = a_PartStyle.length();
+	for (size_t i = 0; i < len; i++)
+	{
+		switch (a_PartStyle[i])
+		{
+			case 'b':
+			{
+				// bold
+				a_Value["bold"] = Json::Value(true);
+				break;
+			}
+			
+			case 'i':
+			{
+				// italic
+				a_Value["italic"] = Json::Value(true);
+				break;
+			}
+			
+			case 'u':
+			{
+				// Underlined
+				a_Value["underlined"] = Json::Value(true);
+				break;
+			}
+			
+			case 's':
+			{
+				// strikethrough
+				a_Value["strikethrough"] = Json::Value(true);
+				break;
+			}
+			
+			case 'o':
+			{
+				// obfuscated
+				a_Value["obfuscated"] = Json::Value(true);
+				break;
+			}
+			
+			case '@':
+			{
+				// Color, specified by the next char:
+				i++;
+				if (i >= len)
+				{
+					// String too short, didn't contain a color
+					break;
+				}
+				switch (a_PartStyle[i])
+				{
+					case '0': a_Value["color"] = Json::Value("black");        break;
+					case '1': a_Value["color"] = Json::Value("dark_blue");    break;
+					case '2': a_Value["color"] = Json::Value("dark_green");   break;
+					case '3': a_Value["color"] = Json::Value("dark_aqua");    break;
+					case '4': a_Value["color"] = Json::Value("dark_red");     break;
+					case '5': a_Value["color"] = Json::Value("dark_purple");  break;
+					case '6': a_Value["color"] = Json::Value("gold");         break;
+					case '7': a_Value["color"] = Json::Value("gray");         break;
+					case '8': a_Value["color"] = Json::Value("dark_gray");    break;
+					case '9': a_Value["color"] = Json::Value("blue");         break;
+					case 'a': a_Value["color"] = Json::Value("green");        break;
+					case 'b': a_Value["color"] = Json::Value("aqua");         break;
+					case 'c': a_Value["color"] = Json::Value("red");          break;
+					case 'd': a_Value["color"] = Json::Value("light_purple"); break;
+					case 'e': a_Value["color"] = Json::Value("yellow");       break;
+					case 'f': a_Value["color"] = Json::Value("white");        break;
+				}  // switch (color)
+			}  // case '@'
+		}  // switch (Style[i])
+	}  // for i - a_PartStyle[]
+}
+
+
+
+
+
 ////////////////////////////////////////////////////////////////////////////////
 // cCompositeChat::cBasePart:
 
diff --git a/src/CompositeChat.h b/src/CompositeChat.h
index 2dc21b98f..369eed196 100644
--- a/src/CompositeChat.h
+++ b/src/CompositeChat.h
@@ -4,6 +4,7 @@
 // Declares the cCompositeChat class used to wrap a chat message with multiple parts (text, url, cmd)
 
 #include "Defines.h"
+#include "json/json.h"
 
 
 
@@ -189,6 +190,8 @@ public:
 	Used for older protocols that don't support composite chat
 	and for console-logging. */
 	AString ExtractText(void) const;
+
+	AString CreateJsonString(bool a_ShouldUseChatPrefixes = true) const;
 	
 	// tolua_end
 	
@@ -197,6 +200,9 @@ public:
 	/** Converts the MessageType to a LogLevel value.
 	Used by the logging bindings when logging a cCompositeChat object. */
 	static cLogger::eLogLevel MessageTypeToLogLevel(eMessageType a_MessageType);
+
+	/** Adds the chat part's style (represented by the part's stylestring) into the Json object. */
+	void AddChatPartStyle(Json::Value & a_Value, const AString & a_PartStyle) const;
 	
 protected:
 	/** All the parts that */
diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp
index f36ec5b49..f51f15ec2 100644
--- a/src/Protocol/Protocol17x.cpp
+++ b/src/Protocol/Protocol17x.cpp
@@ -239,101 +239,13 @@ void cProtocol172::SendChat(const AString & a_Message)
 void cProtocol172::SendChat(const cCompositeChat & a_Message)
 {
 	ASSERT(m_State == 3);  // In game mode?
-	
-	// Compose the complete Json string to send:
-	Json::Value msg;
+
 	cWorld * World = m_Client->GetPlayer()->GetWorld();
-	msg["text"] = cClientHandle::FormatMessageType((World == NULL) ? false : World->ShouldUseChatPrefixes(), a_Message.GetMessageType(), a_Message.GetAdditionalMessageTypeData());  // The client crashes without this field being present
-	const cCompositeChat::cParts & Parts = a_Message.GetParts();
-	for (cCompositeChat::cParts::const_iterator itr = Parts.begin(), end = Parts.end(); itr != end; ++itr)
-	{
-		Json::Value Part;
-		switch ((*itr)->m_PartType)
-		{
-			case cCompositeChat::ptText:
-			{
-				Part["text"] = (*itr)->m_Text;
-				AddChatPartStyle(Part, (*itr)->m_Style);
-				break;
-			}
-			
-			case cCompositeChat::ptClientTranslated:
-			{
-				const cCompositeChat::cClientTranslatedPart & p = (const cCompositeChat::cClientTranslatedPart &)**itr;
-				Part["translate"] = p.m_Text;
-				Json::Value With;
-				for (AStringVector::const_iterator itrW = p.m_Parameters.begin(), endW = p.m_Parameters.end(); itrW != endW; ++itr)
-				{
-					With.append(*itrW);
-				}
-				if (!p.m_Parameters.empty())
-				{
-					Part["with"] = With;
-				}
-				AddChatPartStyle(Part, p.m_Style);
-				break;
-			}
-			
-			case cCompositeChat::ptUrl:
-			{
-				const cCompositeChat::cUrlPart & p = (const cCompositeChat::cUrlPart &)**itr;
-				Part["text"] = p.m_Text;
-				Json::Value Url;
-				Url["action"] = "open_url";
-				Url["value"] = p.m_Url;
-				Part["clickEvent"] = Url;
-				AddChatPartStyle(Part, p.m_Style);
-				break;
-			}
-			
-			case cCompositeChat::ptSuggestCommand:
-			case cCompositeChat::ptRunCommand:
-			{
-				const cCompositeChat::cCommandPart & p = (const cCompositeChat::cCommandPart &)**itr;
-				Part["text"] = p.m_Text;
-				Json::Value Cmd;
-				Cmd["action"] = (p.m_PartType == cCompositeChat::ptRunCommand) ? "run_command" : "suggest_command";
-				Cmd["value"] = p.m_Command;
-				Part["clickEvent"] = Cmd;
-				AddChatPartStyle(Part, p.m_Style);
-				break;
-			}
+	bool ShouldUseChatPrefixes = (World == NULL) ? false : World->ShouldUseChatPrefixes();
 
-			case cCompositeChat::ptShowAchievement:
-			{
-				const cCompositeChat::cShowAchievementPart & p = (const cCompositeChat::cShowAchievementPart &)**itr;
-				Part["translate"] = "chat.type.achievement";
-
-				Json::Value Ach;
-				Ach["action"] = "show_achievement";
-				Ach["value"] = p.m_Text;
-				
-				Json::Value AchColourAndName;
-				AchColourAndName["color"] = "green";
-				AchColourAndName["translate"] = p.m_Text;
-				AchColourAndName["hoverEvent"] = Ach;
-
-				Json::Value Extra;
-				Extra.append(AchColourAndName);
-
-				Json::Value Name;
-				Name["text"] = p.m_PlayerName;
-
-				Json::Value With;
-				With.append(Name);
-				With.append(Extra);
-
-				Part["with"] = With;
-				AddChatPartStyle(Part, p.m_Style);
-				break;
-			}
-		}
-		msg["extra"].append(Part);
-	}  // for itr - Parts[]
-	
 	// Send the message to the client:
 	cPacketizer Pkt(*this, 0x02);
-	Pkt.WriteString(msg.toStyledString());
+	Pkt.WriteString(a_Message.CreateJsonString(ShouldUseChatPrefixes));
 }
 
 
@@ -2427,85 +2339,6 @@ void cProtocol172::StartEncryption(const Byte * a_Key)
 
 
 
-void cProtocol172::AddChatPartStyle(Json::Value & a_Value, const AString & a_PartStyle)
-{
-	size_t len = a_PartStyle.length();
-	for (size_t i = 0; i < len; i++)
-	{
-		switch (a_PartStyle[i])
-		{
-			case 'b':
-			{
-				// bold
-				a_Value["bold"] = Json::Value(true);
-				break;
-			}
-			
-			case 'i':
-			{
-				// italic
-				a_Value["italic"] = Json::Value(true);
-				break;
-			}
-			
-			case 'u':
-			{
-				// Underlined
-				a_Value["underlined"] = Json::Value(true);
-				break;
-			}
-			
-			case 's':
-			{
-				// strikethrough
-				a_Value["strikethrough"] = Json::Value(true);
-				break;
-			}
-			
-			case 'o':
-			{
-				// obfuscated
-				a_Value["obfuscated"] = Json::Value(true);
-				break;
-			}
-			
-			case '@':
-			{
-				// Color, specified by the next char:
-				i++;
-				if (i >= len)
-				{
-					// String too short, didn't contain a color
-					break;
-				}
-				switch (a_PartStyle[i])
-				{
-					case '0': a_Value["color"] = Json::Value("black");        break;
-					case '1': a_Value["color"] = Json::Value("dark_blue");    break;
-					case '2': a_Value["color"] = Json::Value("dark_green");   break;
-					case '3': a_Value["color"] = Json::Value("dark_aqua");    break;
-					case '4': a_Value["color"] = Json::Value("dark_red");     break;
-					case '5': a_Value["color"] = Json::Value("dark_purple");  break;
-					case '6': a_Value["color"] = Json::Value("gold");         break;
-					case '7': a_Value["color"] = Json::Value("gray");         break;
-					case '8': a_Value["color"] = Json::Value("dark_gray");    break;
-					case '9': a_Value["color"] = Json::Value("blue");         break;
-					case 'a': a_Value["color"] = Json::Value("green");        break;
-					case 'b': a_Value["color"] = Json::Value("aqua");         break;
-					case 'c': a_Value["color"] = Json::Value("red");          break;
-					case 'd': a_Value["color"] = Json::Value("light_purple"); break;
-					case 'e': a_Value["color"] = Json::Value("yellow");       break;
-					case 'f': a_Value["color"] = Json::Value("white");        break;
-				}  // switch (color)
-			}  // case '@'
-		}  // switch (Style[i])
-	}  // for i - a_PartStyle[]
-}
-
-
-
-
-
 ////////////////////////////////////////////////////////////////////////////////
 // cProtocol172::cPacketizer:
 
diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h
index b37de1527..6668d0a87 100644
--- a/src/Protocol/Protocol17x.h
+++ b/src/Protocol/Protocol17x.h
@@ -307,9 +307,7 @@ protected:
 	void ParseItemMetadata(cItem & a_Item, const AString & a_Metadata);
 	
 	void StartEncryption(const Byte * a_Key);
-	
-	/** Adds the chat part's style (represented by the part's stylestring) into the Json object. */
-	void AddChatPartStyle(Json::Value & a_Value, const AString & a_PartStyle);
+
 } ;
 
 
diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp
index b3cdcc7bc..5023acf2d 100644
--- a/src/Protocol/Protocol18x.cpp
+++ b/src/Protocol/Protocol18x.cpp
@@ -231,101 +231,13 @@ void cProtocol180::SendChat(const AString & a_Message)
 void cProtocol180::SendChat(const cCompositeChat & a_Message)
 {
 	ASSERT(m_State == 3);  // In game mode?
-	
-	// Compose the complete Json string to send:
-	Json::Value msg;
+
 	cWorld * World = m_Client->GetPlayer()->GetWorld();
-	msg["text"] = cClientHandle::FormatMessageType((World == NULL) ? false : World->ShouldUseChatPrefixes(), a_Message.GetMessageType(), a_Message.GetAdditionalMessageTypeData());  // The client crashes without this field being present
-	const cCompositeChat::cParts & Parts = a_Message.GetParts();
-	for (cCompositeChat::cParts::const_iterator itr = Parts.begin(), end = Parts.end(); itr != end; ++itr)
-	{
-		Json::Value Part;
-		switch ((*itr)->m_PartType)
-		{
-			case cCompositeChat::ptText:
-			{
-				Part["text"] = (*itr)->m_Text;
-				AddChatPartStyle(Part, (*itr)->m_Style);
-				break;
-			}
-			
-			case cCompositeChat::ptClientTranslated:
-			{
-				const cCompositeChat::cClientTranslatedPart & p = (const cCompositeChat::cClientTranslatedPart &)**itr;
-				Part["translate"] = p.m_Text;
-				Json::Value With;
-				for (AStringVector::const_iterator itrW = p.m_Parameters.begin(), endW = p.m_Parameters.end(); itrW != endW; ++itr)
-				{
-					With.append(*itrW);
-				}
-				if (!p.m_Parameters.empty())
-				{
-					Part["with"] = With;
-				}
-				AddChatPartStyle(Part, p.m_Style);
-				break;
-			}
-			
-			case cCompositeChat::ptUrl:
-			{
-				const cCompositeChat::cUrlPart & p = (const cCompositeChat::cUrlPart &)**itr;
-				Part["text"] = p.m_Text;
-				Json::Value Url;
-				Url["action"] = "open_url";
-				Url["value"] = p.m_Url;
-				Part["clickEvent"] = Url;
-				AddChatPartStyle(Part, p.m_Style);
-				break;
-			}
-			
-			case cCompositeChat::ptSuggestCommand:
-			case cCompositeChat::ptRunCommand:
-			{
-				const cCompositeChat::cCommandPart & p = (const cCompositeChat::cCommandPart &)**itr;
-				Part["text"] = p.m_Text;
-				Json::Value Cmd;
-				Cmd["action"] = (p.m_PartType == cCompositeChat::ptRunCommand) ? "run_command" : "suggest_command";
-				Cmd["value"] = p.m_Command;
-				Part["clickEvent"] = Cmd;
-				AddChatPartStyle(Part, p.m_Style);
-				break;
-			}
+	bool ShouldUseChatPrefixes = (World == NULL) ? false : World->ShouldUseChatPrefixes();
 
-			case cCompositeChat::ptShowAchievement:
-			{
-				const cCompositeChat::cShowAchievementPart & p = (const cCompositeChat::cShowAchievementPart &)**itr;
-				Part["translate"] = "chat.type.achievement";
-
-				Json::Value Ach;
-				Ach["action"] = "show_achievement";
-				Ach["value"] = p.m_Text;
-				
-				Json::Value AchColourAndName;
-				AchColourAndName["color"] = "green";
-				AchColourAndName["translate"] = p.m_Text;
-				AchColourAndName["hoverEvent"] = Ach;
-
-				Json::Value Extra;
-				Extra.append(AchColourAndName);
-
-				Json::Value Name;
-				Name["text"] = p.m_PlayerName;
-
-				Json::Value With;
-				With.append(Name);
-				With.append(Extra);
-
-				Part["with"] = With;
-				AddChatPartStyle(Part, p.m_Style);
-				break;
-			}
-		}
-		msg["extra"].append(Part);
-	}  // for itr - Parts[]
-	
 	// Send the message to the client:
 	cPacketizer Pkt(*this, 0x02);
-	Pkt.WriteString(msg.toStyledString());
+	Pkt.WriteString(a_Message.CreateJsonString(ShouldUseChatPrefixes));
 	Pkt.WriteChar(0);
 }
 
@@ -2693,85 +2605,6 @@ void cProtocol180::StartEncryption(const Byte * a_Key)
 
 
 
-void cProtocol180::AddChatPartStyle(Json::Value & a_Value, const AString & a_PartStyle)
-{
-	size_t len = a_PartStyle.length();
-	for (size_t i = 0; i < len; i++)
-	{
-		switch (a_PartStyle[i])
-		{
-			case 'b':
-			{
-				// bold
-				a_Value["bold"] = Json::Value(true);
-				break;
-			}
-			
-			case 'i':
-			{
-				// italic
-				a_Value["italic"] = Json::Value(true);
-				break;
-			}
-			
-			case 'u':
-			{
-				// Underlined
-				a_Value["underlined"] = Json::Value(true);
-				break;
-			}
-			
-			case 's':
-			{
-				// strikethrough
-				a_Value["strikethrough"] = Json::Value(true);
-				break;
-			}
-			
-			case 'o':
-			{
-				// obfuscated
-				a_Value["obfuscated"] = Json::Value(true);
-				break;
-			}
-			
-			case '@':
-			{
-				// Color, specified by the next char:
-				i++;
-				if (i >= len)
-				{
-					// String too short, didn't contain a color
-					break;
-				}
-				switch (a_PartStyle[i])
-				{
-					case '0': a_Value["color"] = Json::Value("black");        break;
-					case '1': a_Value["color"] = Json::Value("dark_blue");    break;
-					case '2': a_Value["color"] = Json::Value("dark_green");   break;
-					case '3': a_Value["color"] = Json::Value("dark_aqua");    break;
-					case '4': a_Value["color"] = Json::Value("dark_red");     break;
-					case '5': a_Value["color"] = Json::Value("dark_purple");  break;
-					case '6': a_Value["color"] = Json::Value("gold");         break;
-					case '7': a_Value["color"] = Json::Value("gray");         break;
-					case '8': a_Value["color"] = Json::Value("dark_gray");    break;
-					case '9': a_Value["color"] = Json::Value("blue");         break;
-					case 'a': a_Value["color"] = Json::Value("green");        break;
-					case 'b': a_Value["color"] = Json::Value("aqua");         break;
-					case 'c': a_Value["color"] = Json::Value("red");          break;
-					case 'd': a_Value["color"] = Json::Value("light_purple"); break;
-					case 'e': a_Value["color"] = Json::Value("yellow");       break;
-					case 'f': a_Value["color"] = Json::Value("white");        break;
-				}  // switch (color)
-			}  // case '@'
-		}  // switch (Style[i])
-	}  // for i - a_PartStyle[]
-}
-
-
-
-
-
 ////////////////////////////////////////////////////////////////////////////////
 // cProtocol180::cPacketizer:
 
diff --git a/src/Protocol/Protocol18x.h b/src/Protocol/Protocol18x.h
index 70696d32d..7ba2b92cd 100644
--- a/src/Protocol/Protocol18x.h
+++ b/src/Protocol/Protocol18x.h
@@ -324,9 +324,7 @@ protected:
 	void ParseItemMetadata(cItem & a_Item, const AString & a_Metadata);
 	
 	void StartEncryption(const Byte * a_Key);
-	
-	/** Adds the chat part's style (represented by the part's stylestring) into the Json object. */
-	void AddChatPartStyle(Json::Value & a_Value, const AString & a_PartStyle);
+
 } ;