summaryrefslogtreecommitdiff
path: root/src/gui/chat.cpp
diff options
context:
space:
mode:
authorBjørn Lindeijer <bjorn@lindeijer.nl>2009-03-22 19:45:03 +0100
committerBjørn Lindeijer <bjorn@lindeijer.nl>2009-03-22 19:45:56 +0100
commit0c43d04b438d41c277ae80402d4b4888db1a0b64 (patch)
tree3aaeb75ecd1bcbe85decedab5f1fa426fe0411e3 /src/gui/chat.cpp
parenta7f5eaeb7f643658d356533a608f0f18d85b6d32 (diff)
parent401802c1d7a1b3d659bdc53a45d9a6292fc1121e (diff)
downloadmana-client-0c43d04b438d41c277ae80402d4b4888db1a0b64.tar.gz
mana-client-0c43d04b438d41c277ae80402d4b4888db1a0b64.tar.bz2
mana-client-0c43d04b438d41c277ae80402d4b4888db1a0b64.tar.xz
mana-client-0c43d04b438d41c277ae80402d4b4888db1a0b64.zip
Merged the tmwserv client with the eAthena client
This merge involved major changes on both sides, and as such took several weeks. Lots of things are expected to be broken now, however, we now have a single code base to improve and extend, which can be compiled to support either eAthena or tmwserv. In the coming months, the plan is to work towards a client that supports both eAthena and tmwserv, without needing to be recompiled. Conflicts: Everywhere!
Diffstat (limited to 'src/gui/chat.cpp')
-rw-r--r--src/gui/chat.cpp290
1 files changed, 265 insertions, 25 deletions
diff --git a/src/gui/chat.cpp b/src/gui/chat.cpp
index ac13355c..37250091 100644
--- a/src/gui/chat.cpp
+++ b/src/gui/chat.cpp
@@ -31,25 +31,44 @@
#include "windowcontainer.h"
#include "widgets/layout.h"
+#include "widgets/tab.h"
+#include "widgets/tabbedarea.h"
#include "../beingmanager.h"
+#ifdef TMWSERV_SUPPORT
+#include "../commandhandler.h"
+#endif
+#include "../channelmanager.h"
+#include "../channel.h"
#include "../configuration.h"
#include "../game.h"
#include "../localplayer.h"
-#include "../party.h"
+#ifdef TMWSERV_SUPPORT
+#include "../net/chatserver/chatserver.h"
+#include "../net/gameserver/player.h"
+#else
+#include "../party.h"
#include "../net/messageout.h"
-#include "../net/protocol.h"
+#include "../net/ea/protocol.h"
+#endif
#include "../resources/iteminfo.h"
#include "../resources/itemdb.h"
+#include "../utils/dtor.h"
#include "../utils/gettext.h"
#include "../utils/strprintf.h"
#include "../utils/stringutils.h"
+#ifdef TMWSERV_SUPPORT
+ChatWindow::ChatWindow():
+ Window("Chat"),
+#else
ChatWindow::ChatWindow(Network * network):
-Window(""), mNetwork(network), mTmpVisible(false)
+ Window(""), mNetwork(network),
+#endif
+ mTmpVisible(false)
{
setWindowName("Chat");
@@ -64,18 +83,21 @@ Window(""), mNetwork(network), mTmpVisible(false)
mChatInput->setActionEventId("chatinput");
mChatInput->addActionListener(this);
- mTextOutput = new BrowserBox(BrowserBox::AUTO_WRAP);
- mTextOutput->setOpaque(false);
- mTextOutput->setMaxRow((int) config.getValue("ChatLogLength", 0));
- mTextOutput->setLinkHandler(mItemLinkHandler);
+ BrowserBox *textOutput = new BrowserBox(BrowserBox::AUTO_WRAP);
+ textOutput->setOpaque(false);
+ textOutput->setMaxRow((int) config.getValue("ChatLogLength", 0));
+ textOutput->setLinkHandler(mItemLinkHandler);
- mScrollArea = new ScrollArea(mTextOutput);
- mScrollArea->setScrollPolicy(gcn::ScrollArea::SHOW_NEVER,
+ ScrollArea *scrollArea = new ScrollArea(textOutput);
+ scrollArea->setScrollPolicy(gcn::ScrollArea::SHOW_NEVER,
gcn::ScrollArea::SHOW_ALWAYS);
- mScrollArea->setScrollAmount(0, 1);
- mScrollArea->setOpaque(false);
+ scrollArea->setScrollAmount(0, 1);
+ scrollArea->setOpaque(false);
+
+ mChatTabs = new TabbedArea();
+ mChatTabs->addTab("General", scrollArea);
- place(0, 0, mScrollArea, 5, 5).setPadding(0);
+ place(0, 0, mChatTabs, 5, 5).setPadding(0);
place(0, 5, mChatInput, 5).setPadding(1);
Layout &layout = getLayout();
@@ -88,6 +110,7 @@ Window(""), mNetwork(network), mTmpVisible(false)
mChatInput->addKeyListener(this);
mCurHist = mHistory.end();
+#ifdef EATHENA_SUPPORT
// Read the party prefix
std::string partyPrefix = config.getValue("PartyPrefix", "$");
mPartyPrefix = (partyPrefix.empty() ? '$' : partyPrefix.at(0));
@@ -99,19 +122,75 @@ Window(""), mNetwork(network), mTmpVisible(false)
// run the @assert command for the player again. Convenience for GMs.
if (config.getValue(player_node->getName() + "GMassert", 0))
chatSend(player_node->getName(), "@assert");
+#endif
}
ChatWindow::~ChatWindow()
{
+#ifdef EATHENA_SUPPORT
char partyPrefix[2] = ".";
*partyPrefix = mPartyPrefix;
config.setValue("PartyPrefix", partyPrefix);
config.setValue("ReturnToggles", mReturnToggles ? "1" : "0");
delete mRecorder;
+#endif
+}
+
+void ChatWindow::widgetResized(const gcn::Event &event)
+{
+ Window::widgetResized(event);
+
+ const gcn::Rectangle area = getChildrenArea();
+
+ mChatInput->setPosition(mChatInput->getFrameSize(),
+ area.height - mChatInput->getHeight() -
+ mChatInput->getFrameSize());
+ mChatInput->setWidth(area.width - 2 * mChatInput->getFrameSize());
+
+ mChatTabs->setWidth(area.width - 2 * mChatTabs->getFrameSize());
+ mChatTabs->setHeight(area.height - 2 * mChatTabs->getFrameSize());
+
+ const std::string &channelName = getFocused();
+ ChannelMap::const_iterator chan = mChannels.find(channelName);
+ if (chan != mChannels.end()) {
+ ScrollArea *scroll = chan->second.scroll;
+ scroll->setWidth(area.width - 2 * scroll->getFrameSize());
+ scroll->setHeight(area.height - 2 * scroll->getFrameSize() -
+ mChatInput->getHeight() - 5);
+ scroll->logic();
+ }
+}
+
+void ChatWindow::logic()
+{
+ Window::logic();
+
+ const gcn::Rectangle area = getChildrenArea();
+
+ const std::string &channelName = getFocused();
+ ChannelMap::const_iterator chan = mChannels.find(channelName);
+ if (chan != mChannels.end()) {
+ ScrollArea *scroll = chan->second.scroll;
+ scroll->setWidth(area.width - 2 * scroll->getFrameSize());
+ scroll->setHeight(area.height - 2 * scroll->getFrameSize() -
+ mChatInput->getHeight() - 5);
+ scroll->logic();
+ }
}
-void ChatWindow::chatLog(std::string line, int own, bool ignoreRecord)
+void ChatWindow::chatLog(std::string line, int own, std::string channelName,
+ bool ignoreRecord)
{
+ if(channelName.empty())
+ channelName = getFocused();
+
+ ChannelMap::const_iterator chan = mChannels.find(channelName);
+ if (chan == mChannels.end())
+ return;
+
+ BrowserBox * const output = chan->second.browser;
+ ScrollArea * const scroll = chan->second.scroll;
+
// Trim whitespace
trim(line);
@@ -180,10 +259,17 @@ void ChatWindow::chatLog(std::string line, int own, bool ignoreRecord)
tmp.text = line;
lineColor = "##S";
break;
+ case BY_CHANNEL:
+ tmp.nick = "";
+ // TODO: Use a predefined color
+ lineColor = "##2"; // Equiv. to BrowserBox::GREEN
+ break;
+#ifdef EATHENA_SUPPORT
case BY_PARTY:
tmp.nick += CAT_NORMAL;
lineColor = "##P";
break;
+#endif
case ACT_WHISPER:
tmp.nick = strprintf(_("%s whispers:"), tmp.nick.c_str());
tmp.nick += " ";
@@ -206,10 +292,12 @@ void ChatWindow::chatLog(std::string line, int own, bool ignoreRecord)
lineColor = "##S";
}
+#ifdef EATHENA_SUPPORT
if (tmp.nick.empty() && tmp.text.substr(0, 17) == "Visible GM status")
{
player_node->setGM();
}
+#endif
// Get the current system time
time_t t;
@@ -228,25 +316,38 @@ void ChatWindow::chatLog(std::string line, int own, bool ignoreRecord)
// We look if the Vertical Scroll Bar is set at the max before
// adding a row, otherwise the max will always be a row higher
// at comparison.
- if (mScrollArea->getVerticalScrollAmount() ==
- mScrollArea->getVerticalMaxScroll())
+ if (scroll->getVerticalScrollAmount() >= scroll->getVerticalMaxScroll())
{
- mTextOutput->addRow(line);
- mScrollArea->setVerticalScrollAmount(mScrollArea->
- getVerticalMaxScroll());
+ output->addRow(line);
+ scroll->setVerticalScrollAmount(scroll->getVerticalMaxScroll());
}
else
{
- mTextOutput->addRow(line);
+ output->addRow(line);
}
+ scroll->logic();
mRecorder->record(line.substr(3));
}
+#ifdef EATHENA_SUPPORT
void ChatWindow::chatLog(CHATSKILL act)
{
chatLog(const_msg(act), BY_SERVER);
}
+#endif
+
+const std::string &ChatWindow::getFocused() const
+{
+ return mChatTabs->getSelectedTab()->getCaption();
+}
+
+void ChatWindow::clearTab(const std::string &tab)
+{
+ ChannelMap::const_iterator chan = mChannels.find(tab);
+ if (chan != mChannels.end())
+ chan->second.browser->clearRows();
+}
void ChatWindow::action(const gcn::ActionEvent &event)
{
@@ -265,7 +366,11 @@ void ChatWindow::action(const gcn::ActionEvent &event)
mCurHist = mHistory.end();
// Send the message to the server
+#ifdef TMWSERV_SUPPORT
+ chatSend(message);
+#else
chatSend(player_node->getName(), message);
+#endif
// Clear the text from the chat input
mChatInput->setText("");
@@ -343,6 +448,8 @@ void ChatWindow::whisper(const std::string &nick, std::string msg)
if (tempNick.compare(playerName) == 0 || msg.empty())
return;
+ // TODO: Implement whispering on tmwserv
+#ifdef EATHENA_SUPPORT
MessageOut outMsg(mNetwork);
outMsg.writeInt16(CMSG_CHAT_WHISPER);
outMsg.writeInt16(msg.length() + 28);
@@ -352,8 +459,123 @@ void ChatWindow::whisper(const std::string &nick, std::string msg)
chatLog(strprintf(_("Whispering to %s: %s"),
recvnick.c_str(), msg.c_str()),
BY_PLAYER);
+#endif
+}
+
+#ifdef TMWSERV_SUPPORT
+
+void ChatWindow::chatSend(std::string &msg)
+{
+ if (msg.empty()) return;
+
+ // check for item link
+ std::string::size_type start = msg.find('[');
+ if (start != std::string::npos && msg[start+1] != '@')
+ {
+ std::string::size_type end = msg.find(']', start);
+ if (end != std::string::npos)
+ {
+ std::string temp = msg.substr(start+1, end-1);
+ ItemInfo itemInfo = ItemDB::get(temp);
+ msg.insert(end, "@@");
+ msg.insert(start+1, "|");
+ msg.insert(start+1, toString(itemInfo.getId()));
+ msg.insert(start+1, "@@");
+
+ }
+ }
+
+
+ // Prepare ordinary message
+ if (msg[0] != '/')
+ {
+ if (getFocused() == "General")
+ {
+ Net::GameServer::Player::say(msg);
+ }
+ else
+ {
+ Channel *channel = channelManager->findByName(getFocused());
+ if (channel)
+ {
+ Net::ChatServer::chat(channel->getId(), msg);
+ }
+ }
+ }
+ else
+ {
+ commandHandler->handleCommand(std::string(msg, 1));
+ }
+}
+
+void ChatWindow::removeChannel(short channelId)
+{
+ removeChannel(channelManager->findById(channelId));
+}
+
+void ChatWindow::removeChannel(const std::string &channelName)
+{
+ removeChannel(channelManager->findByName(channelName));
+}
+
+void ChatWindow::removeChannel(Channel *channel)
+{
+ if (channel)
+ {
+ Tab *tab = mChatTabs->getTab(channel->getName());
+ if (!tab)
+ return;
+ clearTab(channel->getName());
+ mChatTabs->removeTab(tab);
+ mChannels.erase(channel->getName());
+ channelManager->removeChannel(channel);
+
+ logic();
+ }
+}
+
+void ChatWindow::createNewChannelTab(const std::string &channelName)
+{
+ // Create new channel
+ BrowserBox *textOutput = new BrowserBox(BrowserBox::AUTO_WRAP);
+ textOutput->setOpaque(false);
+ textOutput->disableLinksAndUserColors();
+ textOutput->setMaxRow((int) config.getValue("ChatLogLength", 0));
+ ScrollArea *scrollArea = new ScrollArea(textOutput);
+ scrollArea->setPosition(scrollArea->getFrameSize(), scrollArea->getFrameSize());
+ scrollArea->setScrollPolicy(gcn::ScrollArea::SHOW_NEVER, gcn::ScrollArea::SHOW_ALWAYS);
+ scrollArea->setOpaque(false);
+ scrollArea->setWidth(getChildrenArea().width - 2 * scrollArea->getFrameSize());
+ scrollArea->setHeight(getChildrenArea().height - 2 * scrollArea->getFrameSize() -
+ mChatInput->getHeight() - 5);
+ scrollArea->logic();
+ textOutput->setWidth(scrollArea->getChildrenArea().width);
+ textOutput->setHeight(scrollArea->getChildrenArea().height);
+
+ // Add channel to the tabbed area
+ mChatTabs->addTab(channelName, scrollArea);
+ mChannels.insert(
+ std::make_pair(channelName, ChatArea(textOutput, scrollArea)));
+
+ // Update UI
+ logic();
+}
+
+void ChatWindow::sendToChannel(short channelId,
+ const std::string &user,
+ const std::string &msg)
+{
+ Channel *channel = channelManager->findById(channelId);
+ if (channel)
+ {
+ std::string channelName = channel->getName();
+ chatLog(user + ": " + msg, user == player_node->getName() ? BY_PLAYER : BY_OTHER, channelName);
+ mChatTabs->getTab(channelName)->setHighlighted(true);
+ }
}
+#else
+
void ChatWindow::chatSend(const std::string &nick, std::string msg)
{
/* Some messages are managed client side, while others
@@ -488,7 +710,7 @@ void ChatWindow::chatSend(const std::string &nick, std::string msg)
outMsg.writeInt16(0x00c1);
}
else if (command == "clear")
- mTextOutput->clearRows();
+ clearTab(getFocused());
else if (command == "whisper" || command == "msg" || command == "w")
whisper(nick, msg);
else if (command == "record")
@@ -608,7 +830,7 @@ void ChatWindow::chatSend(const std::string &nick, std::string msg)
mRecorder->record(timeStr.str() + _("Present: ") + response + ".");
- chatLog(_("Attendance written to record log."), BY_SERVER, true);
+ chatLog(_("Attendance written to record log."), BY_SERVER, std::string(), true);
}
else
{
@@ -712,16 +934,25 @@ std::string ChatWindow::const_msg(CHATSKILL act)
return msg;
}
+#endif
+
void ChatWindow::scroll(int amount)
{
if (!isVisible())
return;
- int range = mScrollArea->getHeight() / 8 * amount;
+ ChannelMap::const_iterator chan = mChannels.find(getFocused());
+ if (chan == mChannels.end())
+ return;
+
+ BrowserBox *browser = chan->second.browser;
+ ScrollArea *scroll = chan->second.scroll;
+
+ int range = scroll->getHeight() / 8 * amount;
gcn::Rectangle scr;
- scr.y = mScrollArea->getVerticalScrollAmount() + range;
+ scr.y = scroll->getVerticalScrollAmount() + range;
scr.height = abs(range);
- mTextOutput->showPart(scr);
+ browser->showPart(scr);
}
void ChatWindow::keyPressed(gcn::KeyEvent &event)
@@ -774,10 +1005,10 @@ void ChatWindow::setVisible(bool isVisible)
* For whatever reason, if setVisible is called, the mTmpVisible effect
* should be disabled.
*/
-
mTmpVisible = false;
}
+#ifdef EATHENA_SUPPORT
void ChatWindow::party(const std::string & command, const std::string & rest)
{
if (command == "prefix")
@@ -809,6 +1040,7 @@ void ChatWindow::party(const std::string & command, const std::string & rest)
else
mParty->respond(command, rest);
}
+#endif
void ChatWindow::help(const std::string & msg1, const std::string & msg2)
{
@@ -861,10 +1093,12 @@ void ChatWindow::help(const std::string & msg1, const std::string & msg2)
chatLog(_("This command tell others you are (doing) <msg>."),
BY_SERVER);
}
+#ifdef EATHENA_SUPPORT
else if (msg1 == "party")
{
mParty->help(msg2);
}
+#endif
else if (msg1 == "present")
{
chatLog(_("Command: /present"), BY_SERVER);
@@ -921,3 +1155,9 @@ void ChatWindow::help(const std::string & msg1, const std::string & msg2)
chatLog(_("Type /help for a list of commands."), BY_SERVER);
}
}
+
+bool ChatWindow::tabExists(const std::string &tabName)
+{
+ Tab *tab = mChatTabs->getTab(tabName);
+ return tab != 0;
+}