diff options
author | Bjørn Lindeijer <bjorn@lindeijer.nl> | 2009-03-22 19:45:03 +0100 |
---|---|---|
committer | Bjørn Lindeijer <bjorn@lindeijer.nl> | 2009-03-22 19:45:56 +0100 |
commit | 0c43d04b438d41c277ae80402d4b4888db1a0b64 (patch) | |
tree | 3aaeb75ecd1bcbe85decedab5f1fa426fe0411e3 /src/gui/chat.cpp | |
parent | a7f5eaeb7f643658d356533a608f0f18d85b6d32 (diff) | |
parent | 401802c1d7a1b3d659bdc53a45d9a6292fc1121e (diff) | |
download | mana-0c43d04b438d41c277ae80402d4b4888db1a0b64.tar.gz mana-0c43d04b438d41c277ae80402d4b4888db1a0b64.tar.bz2 mana-0c43d04b438d41c277ae80402d4b4888db1a0b64.tar.xz mana-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.cpp | 290 |
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; +} |