From 84e2c79004f42656660a32f4b54277954f7ec631 Mon Sep 17 00:00:00 2001
From: Andrei Karas <akaras@inbox.ru>
Date: Mon, 13 Oct 2014 16:50:23 +0300
Subject: eathena: show channel messages in channel tab.

---
 src/gui/widgets/tabs/chat/chattab.cpp |  4 +++-
 src/gui/windows/chatwindow.cpp        | 31 +++++++++++++++++++++++++++++++
 src/gui/windows/chatwindow.h          |  6 ++++++
 src/net/eathena/chathandler.cpp       | 24 ++++++++++++++++++++----
 src/net/eathena/chathandler.h         |  2 ++
 5 files changed, 62 insertions(+), 5 deletions(-)

diff --git a/src/gui/widgets/tabs/chat/chattab.cpp b/src/gui/widgets/tabs/chat/chattab.cpp
index 5dc18b329..3ba1ee00a 100644
--- a/src/gui/widgets/tabs/chat/chattab.cpp
+++ b/src/gui/widgets/tabs/chat/chattab.cpp
@@ -43,6 +43,7 @@
 #include "input/inputmanager.h"
 
 #include "net/chathandler.h"
+#include "net/serverfeatures.h"
 
 #include "resources/iteminfo.h"
 
@@ -217,7 +218,8 @@ void ChatTab::chatLog(std::string line, ChatMsgType::Type own,
     }
 
     // if configured, move magic messages log to debug chat tab
-    if (localChatTab && this == localChatTab
+    if (!serverFeatures->haveChatChannels()
+        && localChatTab && this == localChatTab
         && ((config.getBoolValue("showMagicInDebug")
         && own == ChatMsgType::BY_PLAYER
         && tmp.text.length() > 1
diff --git a/src/gui/windows/chatwindow.cpp b/src/gui/windows/chatwindow.cpp
index 4abc70561..5cf727d92 100644
--- a/src/gui/windows/chatwindow.cpp
+++ b/src/gui/windows/chatwindow.cpp
@@ -1559,6 +1559,10 @@ bool ChatWindow::resortChatLog(std::string line, ChatMsgType::Type own,
                     ignoreRecord, tryRemoveColors);
             }
         }
+        else if (serverFeatures->haveChatChannels())
+        {
+            channelChatLog(channel, line, own, ignoreRecord, tryRemoveColors);
+        }
         else if (mShowAllLang)
         {
             localChatTab->chatLog(prefix + line, own,
@@ -1584,6 +1588,33 @@ void ChatWindow::battleChatLog(const std::string &line, ChatMsgType::Type own,
         debugChatTab->chatLog(line, own, ignoreRecord, tryRemoveColors);
 }
 
+void ChatWindow::channelChatLog(const std::string &channel,
+                                const std::string &line,
+                                ChatMsgType::Type own,
+                                const bool ignoreRecord,
+                                const bool tryRemoveColors)
+{
+    std::string tempChannel = channel;
+    toLower(tempChannel);
+
+    ChannelTab *tab = nullptr;
+    const ChannelMap::const_iterator i = mChannels.find(tempChannel);
+
+    if (i != mChannels.end())
+    {
+        tab = i->second;
+    }
+    else
+    {
+        tab = addChannelTab(channel, false);
+        if (tab)
+            saveState();
+    }
+
+    if (tab)
+        tab->chatLog(line, own, ignoreRecord, tryRemoveColors);
+}
+
 void ChatWindow::localPetSay(const std::string &nick, const std::string &text)
 {
     Being *const being = actorManager->findBeingByName(
diff --git a/src/gui/windows/chatwindow.h b/src/gui/windows/chatwindow.h
index 068ec4111..b21930bd0 100644
--- a/src/gui/windows/chatwindow.h
+++ b/src/gui/windows/chatwindow.h
@@ -223,6 +223,12 @@ class ChatWindow final : public Window,
                                   const bool ignoreRecord = false,
                                   const bool tryRemoveColors = true);
 
+        void channelChatLog(const std::string &channel,
+                            const std::string &line,
+                            ChatMsgType::Type own,
+                            const bool ignoreRecord,
+                            const bool tryRemoveColors);
+
         void updateOnline(const std::set<std::string> &onlinePlayers) const;
 
         void loadState();
diff --git a/src/net/eathena/chathandler.cpp b/src/net/eathena/chathandler.cpp
index ac626fd71..b3f81e20a 100644
--- a/src/net/eathena/chathandler.cpp
+++ b/src/net/eathena/chathandler.cpp
@@ -380,19 +380,35 @@ void ChatHandler::processColorChat(Net::MessageIn &msg)
     processChatContinue(msg.readRawString(chatMsgLength, "message"));
 }
 
+std::string ChatHandler::extractChannelFromMessage(std::string &chatMsg)
+{
+    std::string msg = chatMsg;
+    std::string channel(GENERAL_CHANNEL);
+    if (findCutFirst(msg, "[ #"))
+    {   // found channel message
+        const size_t idx = msg.find(" ] ");
+        if (idx != std::string::npos)
+        {
+            channel = std::string("#").append(msg.substr(0, idx));
+            chatMsg = msg.substr(idx + 3);
+        }
+    }
+    return channel;
+}
+
 void ChatHandler::processChatContinue(std::string chatMsg)
 {
-    const size_t pos = chatMsg.find(" : ", 0);
-
+    const std::string channel = extractChannelFromMessage(chatMsg);
     bool allow(true);
     if (chatWindow)
     {
         allow = chatWindow->resortChatLog(chatMsg,
             ChatMsgType::BY_PLAYER,
-            GENERAL_CHANNEL,
+            channel,
             false, true);
     }
 
+    const size_t pos = chatMsg.find(" : ", 0);
     if (pos != std::string::npos)
         chatMsg.erase(0, pos + 3);
 
@@ -521,7 +537,7 @@ void ChatHandler::joinChannel(const std::string &channel)
 {
     // to join channel need use gm commands or send something.
     // here we sending invisible message.
-    channelMessage(channel, "\302\202G");
+    channelMessage(channel, "\302\202\302");
 }
 
 }  // namespace EAthena
diff --git a/src/net/eathena/chathandler.h b/src/net/eathena/chathandler.h
index 418250eb1..86eeb1386 100644
--- a/src/net/eathena/chathandler.h
+++ b/src/net/eathena/chathandler.h
@@ -81,6 +81,8 @@ class ChatHandler final : public MessageHandler, public Ea::ChatHandler
                       const std::string &password) const override final;
 
     protected:
+        static std::string extractChannelFromMessage(std::string &chatMsg);
+
         void processChat(Net::MessageIn &msg);
 
         void processColorChat(Net::MessageIn &msg);
-- 
cgit v1.2.3-70-g09d2