From c8b18b47abbb325b6cc4b34abbad52b03825e4f9 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Thu, 28 Jul 2011 23:30:51 +0300 Subject: Extract shared logic from chathandler and gamehandler netcode to ea namespace. --- src/net/ea/charserverhandler.cpp | 8 - src/net/ea/chathandler.cpp | 359 +++++++++++++++++++++++++++++++++++++++ src/net/ea/chathandler.h | 94 ++++++++++ src/net/ea/gamehandler.cpp | 101 +++++++++++ src/net/ea/gamehandler.h | 76 +++++++++ src/net/ea/loginhandler.cpp | 4 - src/net/ea/loginhandler.h | 2 +- 7 files changed, 631 insertions(+), 13 deletions(-) create mode 100644 src/net/ea/chathandler.cpp create mode 100644 src/net/ea/chathandler.h create mode 100644 src/net/ea/gamehandler.cpp create mode 100644 src/net/ea/gamehandler.h (limited to 'src/net/ea') diff --git a/src/net/ea/charserverhandler.cpp b/src/net/ea/charserverhandler.cpp index e1fcfda66..c69d8a5be 100644 --- a/src/net/ea/charserverhandler.cpp +++ b/src/net/ea/charserverhandler.cpp @@ -23,25 +23,17 @@ #include "net/ea/charserverhandler.h" #include "client.h" -#include "configuration.h" -#include "game.h" #include "log.h" #include "gui/charcreatedialog.h" #include "gui/okdialog.h" -#include "net/logindata.h" -#include "net/messageout.h" #include "net/net.h" #include "net/ea/loginhandler.h" #include "net/ea/eaprotocol.h" -#include "resources/colordb.h" - -#include "utils/dtor.h" #include "utils/gettext.h" -#include "utils/stringutils.h" #include "debug.h" diff --git a/src/net/ea/chathandler.cpp b/src/net/ea/chathandler.cpp new file mode 100644 index 000000000..658ed9a5d --- /dev/null +++ b/src/net/ea/chathandler.cpp @@ -0,0 +1,359 @@ +/* + * The ManaPlus Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "net/ea/chathandler.h" + +#include "actorspritemanager.h" +#include "being.h" +#include "configuration.h" +#include "localplayer.h" +#include "playerrelations.h" +#include "log.h" + +#include "gui/chatwindow.h" +#include "gui/shopwindow.h" + +#include "gui/widgets/chattab.h" + +#include "utils/gettext.h" +#include "utils/stringutils.h" + +#include + +#include "debug.h" + +namespace Ea +{ + +ChatHandler::ChatHandler() +{ +} + +void ChatHandler::me(const std::string &text) +{ + std::string action = strprintf("*%s*", text.c_str()); + + talk(action); +} + +void ChatHandler::channelList() +{ + SERVER_NOTICE(_("Channels are not supported!")) +} + +void ChatHandler::enterChannel(const std::string &channel A_UNUSED, + const std::string &password A_UNUSED) +{ + SERVER_NOTICE(_("Channels are not supported!")) +} + +void ChatHandler::quitChannel(int channelId A_UNUSED) +{ + SERVER_NOTICE(_("Channels are not supported!")) +} + +void ChatHandler::sendToChannel(int channelId A_UNUSED, + const std::string &text A_UNUSED) +{ + SERVER_NOTICE(_("Channels are not supported!")) +} + +void ChatHandler::userList(const std::string &channel A_UNUSED) +{ + SERVER_NOTICE(_("Channels are not supported!")) +} + +void ChatHandler::setChannelTopic(int channelId A_UNUSED, + const std::string &text A_UNUSED) +{ + SERVER_NOTICE(_("Channels are not supported!")) +} + +void ChatHandler::setUserMode(int channelId A_UNUSED, + const std::string &name A_UNUSED, + int mode A_UNUSED) +{ + SERVER_NOTICE(_("Channels are not supported!")) +} + +void ChatHandler::kickUser(int channelId A_UNUSED, + const std::string &name A_UNUSED) +{ + SERVER_NOTICE(_("Channels are not supported!")) +} + +void ChatHandler::processWhisperResponse(Net::MessageIn &msg) +{ + std::string nick; + + if (mSentWhispers.empty()) + { + nick = "user"; + } + else + { + nick = mSentWhispers.front(); + mSentWhispers.pop(); + } + + int type = msg.readInt8(); + switch (type) + { + case 0x00: + // Success (don't need to report) + break; + case 0x01: + if (chatWindow) + { + chatWindow->whisper(nick, + strprintf(_("Whisper could not be " + "sent, %s is offline."), nick.c_str()), BY_SERVER); + } + break; + case 0x02: + if (chatWindow) + { + chatWindow->whisper(nick, + strprintf(_("Whisper could not " + "be sent, ignored by %s."), nick.c_str()), + BY_SERVER); + } + break; + default: + if (logger) + { + logger->log("QQQ SMSG_WHISPER_RESPONSE:" + + toString(type)); + } + } +} + +void ChatHandler::processWhisper(Net::MessageIn &msg) +{ + int chatMsgLength = msg.readInt16() - 28; + std::string nick = msg.readString(24); + + if (chatMsgLength <= 0) + return; + + std::string chatMsg = msg.readString(chatMsgLength); + if (chatMsg.find("\302\202!") == 0) + chatMsg = chatMsg.substr(2); + + if (nick != "Server") + { + if (player_relations.hasPermission( + nick, PlayerRelation::WHISPER)) + { + bool tradeBot = config.getBoolValue("tradebot"); + bool showMsg = !config.getBoolValue("hideShopMessages"); + if (player_relations.hasPermission( + nick, PlayerRelation::TRADE)) + { + if (shopWindow) + { //commands to shop from player + if (chatMsg.find("!selllist ") == 0) + { + if (tradeBot) + { + if (showMsg && chatWindow) + chatWindow->whisper(nick, chatMsg); + shopWindow->giveList(nick, + ShopWindow::SELL); + } + } + else if (chatMsg.find("!buylist ") == 0) + { + if (tradeBot) + { + if (showMsg && chatWindow) + chatWindow->whisper(nick, chatMsg); + shopWindow->giveList(nick, + ShopWindow::BUY); + } + } + else if (chatMsg.find("!buyitem ") == 0) + { + if (showMsg && chatWindow) + chatWindow->whisper(nick, chatMsg); + if (tradeBot) + { + shopWindow->processRequest(nick, chatMsg, + ShopWindow::BUY); + } + } + else if (chatMsg.find("!sellitem ") == 0) + { + if (showMsg && chatWindow) + chatWindow->whisper(nick, chatMsg); + if (tradeBot) + { + shopWindow->processRequest(nick, chatMsg, + ShopWindow::SELL); + } + } + else if (chatMsg.length() > 3 + && chatMsg.find("\302\202") == 0) + { + chatMsg = chatMsg.erase(0, 2); + if (showMsg && chatWindow) + chatWindow->whisper(nick, chatMsg); + if (chatMsg.find("B1") == 0 + || chatMsg.find("S1") == 0) + { + shopWindow->showList(nick, chatMsg); + } + } + else if (chatWindow) + { + chatWindow->whisper(nick, chatMsg); + } + } + else if (chatWindow) + { + chatWindow->whisper(nick, chatMsg); + } + } + else + { + if (chatWindow && (showMsg + || (chatMsg.find("!selllist") + != 0 && chatMsg.find("!buylist") != 0))) + { + chatWindow->whisper(nick, chatMsg); + } + } + } + } + else if (localChatTab) + { + localChatTab->chatLog(chatMsg, BY_SERVER); + } +} + +void ChatHandler::processBeingChat(Net::MessageIn &msg) +{ + if (!actorSpriteManager) + return; + + int chatMsgLength = msg.readInt16() - 8; + Being *being = actorSpriteManager->findBeing(msg.readInt32()); + + if (!being || chatMsgLength <= 0) + return; + + std::string chatMsg = msg.readRawString(chatMsgLength); + + if (being->getType() == Being::PLAYER) + being->setTalkTime(); + + std::string::size_type pos = chatMsg.find(" : ", 0); + std::string sender_name = ((pos == std::string::npos) + ? "" : chatMsg.substr(0, pos)); + + if (sender_name != being->getName() + && being->getType() == Being::PLAYER) + { + if (!being->getName().empty()) + sender_name = being->getName(); + } + else + { + chatMsg.erase(0, pos + 3); + } + + trim(chatMsg); + + // We use getIgnorePlayer instead of ignoringPlayer here + // because ignorePlayer' side effects are triggered + // right below for Being::IGNORE_SPEECH_FLOAT. + if (player_relations.checkPermissionSilently(sender_name, + PlayerRelation::SPEECH_LOG) && chatWindow) + { + chatWindow->resortChatLog(removeColors(sender_name) + " : " + + chatMsg, BY_OTHER); + } + + if (player_relations.hasPermission(sender_name, + PlayerRelation::SPEECH_FLOAT)) + { + being->setSpeech(chatMsg); + } +} + +void ChatHandler::processChat(Net::MessageIn &msg, bool normalChat) +{ + int chatMsgLength = msg.readInt16() - 4; + + if (chatMsgLength <= 0) + return; + + std::string chatMsg = msg.readRawString(chatMsgLength); + std::string::size_type pos = chatMsg.find(" : ", 0); + + if (normalChat) + { + if (chatWindow) + chatWindow->resortChatLog(chatMsg, BY_PLAYER); + + const std::string senseStr = "You sense the following: "; + if (actorSpriteManager && !chatMsg.find(senseStr)) + { + actorSpriteManager->parseLevels( + chatMsg.substr(senseStr.size())); + } + + if (pos != std::string::npos) + chatMsg.erase(0, pos + 3); + + trim(chatMsg); + + if (player_node) + player_node->setSpeech(chatMsg); + } + else if (localChatTab) + { + localChatTab->chatLog(chatMsg, BY_GM); + } +} + +void ChatHandler::processMVP(Net::MessageIn &msg) +{ + // Display MVP player + int id = msg.readInt32(); // id + if (localChatTab && actorSpriteManager) + { + Being *being = actorSpriteManager->findBeing(id); + if (!being) + { + localChatTab->chatLog(_("MVP player."), BY_SERVER); + } + else + { + localChatTab->chatLog(_("MVP player: ") + + being->getName(), BY_SERVER); + } + } +} + +} // namespace Ea + diff --git a/src/net/ea/chathandler.h b/src/net/ea/chathandler.h new file mode 100644 index 000000000..d000b673d --- /dev/null +++ b/src/net/ea/chathandler.h @@ -0,0 +1,94 @@ +/* + * The ManaPlus Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef NET_EA_CHATHANDLER_H +#define NET_EA_CHATHANDLER_H + +#include "net/chathandler.h" +#include "net/messagein.h" +#include "net/messageout.h" +#include "net/net.h" + +#include + +#ifdef __GNUC__ +#define A_UNUSED __attribute__ ((unused)) +#else +#define A_UNUSED +#endif + +namespace Ea +{ + +class ChatHandler : public Net::ChatHandler +{ + public: + ChatHandler(); + + virtual void talk(const std::string &text) = 0; + + virtual void talkRaw(const std::string &text) = 0; + + void me(const std::string &text); + + virtual void privateMessage(const std::string &recipient, + const std::string &text) = 0; + + void channelList(); + + void enterChannel(const std::string &channel, + const std::string &password); + + void quitChannel(int channelId); + + void sendToChannel(int channelId, const std::string &text); + + void userList(const std::string &channel); + + void setChannelTopic(int channelId, const std::string &text); + + void setUserMode(int channelId, const std::string &name, int mode); + + void kickUser(int channelId, const std::string &name); + + virtual void who() = 0; + + virtual void sendRaw(const std::string &args) = 0; + + virtual void processWhisperResponse(Net::MessageIn &msg); + + virtual void processWhisper(Net::MessageIn &msg); + + virtual void processBeingChat(Net::MessageIn &msg); + + virtual void processChat(Net::MessageIn &msg, bool normalChat); + + virtual void processMVP(Net::MessageIn &msg); + + protected: + typedef std::queue WhisperQueue; + WhisperQueue mSentWhispers; +}; + +} // namespace Ea + +#endif // NET_EA_CHATHANDLER_H diff --git a/src/net/ea/gamehandler.cpp b/src/net/ea/gamehandler.cpp new file mode 100644 index 000000000..694600322 --- /dev/null +++ b/src/net/ea/gamehandler.cpp @@ -0,0 +1,101 @@ +/* + * The ManaPlus Client + * Copyright (C) 2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "net/ea/gamehandler.h" + +#include "client.h" +#include "event.h" +#include "game.h" +#include "localplayer.h" +#include "log.h" + +#include "gui/okdialog.h" + +#include "net/messagein.h" + +#include "utils/gettext.h" + +#include "debug.h" + +namespace Ea +{ + +GameHandler::GameHandler() +{ + mCharID = 0; + + listen(Mana::CHANNEL_GAME); +} + +void GameHandler::event(Mana::Channels channel, const Mana::Event &event) +{ + if (channel == Mana::CHANNEL_GAME) + { + if (event.getName() == Mana::EVENT_ENGINESINITALIZED) + Game::instance()->changeMap(mMap); + else if (event.getName() == Mana::EVENT_MAPLOADED) + mapLoadedEvent(); + } +} + +void GameHandler::who() +{ +} + +void GameHandler::setMap(const std::string map) +{ + mMap = map.substr(0, map.rfind(".")); +} + +void GameHandler::processMapLogin(Net::MessageIn &msg) +{ + unsigned char direction; + Uint16 x, y; + msg.readInt32(); // server tick + msg.readCoordinates(x, y, direction); + msg.skip(2); // unknown + logger->log("Protocol: Player start position: (%d, %d)," + " Direction: %d", x, y, direction); + // Switch now or we'll have problems + Client::setState(STATE_GAME); + if (player_node) + player_node->setTileCoords(x, y); +} + +void GameHandler::processWhoAnswer(Net::MessageIn &msg) +{ + SERVER_NOTICE(strprintf(_("Online users: %d"), msg.readInt32())) +} + +void GameHandler::processCharSwitchResponse(Net::MessageIn &msg) +{ + if (msg.readInt8()) + Client::setState(STATE_SWITCH_CHARACTER); +} + +void GameHandler::processMapQuitResponse(Net::MessageIn &msg) +{ + if (msg.readInt8()) + new OkDialog(_("Game"), _("Request to quit denied!"), NULL); +} + +} // namespace TmwAthena diff --git a/src/net/ea/gamehandler.h b/src/net/ea/gamehandler.h new file mode 100644 index 000000000..16168636b --- /dev/null +++ b/src/net/ea/gamehandler.h @@ -0,0 +1,76 @@ +/* + * The ManaPlus Client + * Copyright (C) 2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef NET_EA_GAMEHANDLER_H +#define NET_EA_GAMEHANDLER_H + +#include "listener.h" + +#include "net/gamehandler.h" +#include "net/messagein.h" +#include "net/net.h" + +#ifdef __GNUC__ +#define A_UNUSED __attribute__ ((unused)) +#else +#define A_UNUSED +#endif + +namespace Ea +{ + +class GameHandler : public Net::GameHandler, public Mana::Listener +{ + public: + GameHandler(); + + virtual void event(Mana::Channels channel, const Mana::Event &event); + + virtual void who(); + + virtual bool removeDeadBeings() const + { return true; } + + virtual void setMap(const std::string map); + + /** The tmwAthena protocol is making use of the MP status bar. */ + virtual bool canUseMagicBar() const + { return true; } + + virtual void mapLoadedEvent() = 0; + + virtual void processMapLogin(Net::MessageIn &msg); + + virtual void processWhoAnswer(Net::MessageIn &msg); + + virtual void processCharSwitchResponse(Net::MessageIn &msg); + + virtual void processMapQuitResponse(Net::MessageIn &msg); + + protected: + std::string mMap; + int mCharID; /// < Saved for map-server switching +}; + +} // namespace Ea + +#endif // NET_EA_GAMEHANDLER_H diff --git a/src/net/ea/loginhandler.cpp b/src/net/ea/loginhandler.cpp index f6d8e5cf7..2bce6c251 100644 --- a/src/net/ea/loginhandler.cpp +++ b/src/net/ea/loginhandler.cpp @@ -26,12 +26,8 @@ #include "log.h" #include "configuration.h" -#include "net/logindata.h" -#include "net/messageout.h" - #include "utils/dtor.h" #include "utils/gettext.h" -#include "utils/stringutils.h" #include "debug.h" diff --git a/src/net/ea/loginhandler.h b/src/net/ea/loginhandler.h index 3b035b530..06c47ad5d 100644 --- a/src/net/ea/loginhandler.h +++ b/src/net/ea/loginhandler.h @@ -102,6 +102,6 @@ class LoginHandler : public Net::LoginHandler Token mToken; }; -} // namespace TmwAthena +} // namespace Ea #endif // NET_TA_LOGINHANDLER_H -- cgit v1.2.3-70-g09d2