summaryrefslogtreecommitdiff
path: root/src/net/chathandler.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/net/chathandler.cpp
parenta7f5eaeb7f643658d356533a608f0f18d85b6d32 (diff)
parent401802c1d7a1b3d659bdc53a45d9a6292fc1121e (diff)
downloadmana-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/net/chathandler.cpp')
-rw-r--r--src/net/chathandler.cpp318
1 files changed, 214 insertions, 104 deletions
diff --git a/src/net/chathandler.cpp b/src/net/chathandler.cpp
index a3ccc4fb..90af899a 100644
--- a/src/net/chathandler.cpp
+++ b/src/net/chathandler.cpp
@@ -1,175 +1,285 @@
/*
* The Mana World
- * Copyright (C) 2004 The Mana World Development Team
+ * Copyright 2004 The Mana World Development Team
*
* This file is part of The Mana World.
*
- * This program is free software; you can redistribute it and/or modify
+ * The Mana World 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,
+ * The Mana World 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, write to the Free Software
+ * along with The Mana World; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include "chathandler.h"
+
#include <SDL_types.h>
#include <string>
+#include <iostream>
-#include "chathandler.h"
#include "messagein.h"
#include "protocol.h"
#include "../being.h"
#include "../beingmanager.h"
#include "../game.h"
-#include "../player_relations.h"
+#include "../channel.h"
+#include "../channelmanager.h"
#include "../gui/chat.h"
-
-#include "../utils/gettext.h"
-#include "../utils/stringutils.h"
+#include "../gui/guildwindow.h"
extern Being *player_node;
-#define SERVER_NAME "Server"
-
ChatHandler::ChatHandler()
{
static const Uint16 _messages[] = {
- SMSG_BEING_CHAT,
- SMSG_PLAYER_CHAT,
- SMSG_WHISPER,
- SMSG_WHISPER_RESPONSE,
- SMSG_GM_CHAT,
- SMSG_WHO_ANSWER,
- 0x10c, // MVP
+ GPMSG_SAY,
+ CPMSG_ENTER_CHANNEL_RESPONSE,
+ CPMSG_LIST_CHANNELS_RESPONSE,
+ CPMSG_PUBMSG,
+ CPMSG_ANNOUNCEMENT,
+ CPMSG_PRIVMSG,
+ CPMSG_QUIT_CHANNEL_RESPONSE,
+ CPMSG_LIST_CHANNELUSERS_RESPONSE,
+ CPMSG_CHANNEL_EVENT,
0
};
handledMessages = _messages;
}
-void ChatHandler::handleMessage(MessageIn *msg)
+void ChatHandler::handleMessage(MessageIn &msg)
{
- Being *being;
- std::string chatMsg;
- std::string nick;
- Sint16 chatMsgLength;
-
- switch (msg->getId())
+ switch (msg.getId())
{
- case SMSG_WHISPER_RESPONSE:
- switch (msg->readInt8())
- {
- case 0x00:
- // comment out since we'll local echo in chat.cpp instead, then only report failures
- //chatWindow->chatLog("Whisper sent", BY_SERVER);
- break;
- case 0x01:
- chatWindow->chatLog(_("Whisper could not be sent, user is offline"), BY_SERVER);
- break;
- case 0x02:
- chatWindow->chatLog(_("Whisper could not be sent, ignored by user"), BY_SERVER);
- break;
- }
+ case GPMSG_SAY:
+ handleGameChatMessage(msg);
break;
- // Received whisper
- case SMSG_WHISPER:
- chatMsgLength = msg->readInt16() - 28;
- nick = msg->readString(24);
+ case CPMSG_ENTER_CHANNEL_RESPONSE:
+ handleEnterChannelResponse(msg);
+ break;
- if (chatMsgLength <= 0)
- break;
+ case CPMSG_LIST_CHANNELS_RESPONSE:
+ handleListChannelsResponse(msg);
+ break;
- chatMsg = msg->readString(chatMsgLength);
- if (nick != SERVER_NAME)
- chatMsg = nick + " : " + chatMsg;
+ case CPMSG_PRIVMSG:
+ handlePrivateMessage(msg);
+ break;
- if (nick == SERVER_NAME)
- chatWindow->chatLog(chatMsg, BY_SERVER);
- else {
- if (player_relations.hasPermission(nick, PlayerRelation::WHISPER))
- chatWindow->chatLog(chatMsg, ACT_WHISPER);
- }
+ case CPMSG_ANNOUNCEMENT:
+ handleAnnouncement(msg);
+ break;
+
+ case CPMSG_PUBMSG:
+ handleChatMessage(msg);
+ break;
+ case CPMSG_QUIT_CHANNEL_RESPONSE:
+ handleQuitChannelResponse(msg);
break;
- // Received speech from being
- case SMSG_BEING_CHAT: {
- chatMsgLength = msg->readInt16() - 8;
- being = beingManager->findBeing(msg->readInt32());
+ case CPMSG_LIST_CHANNELUSERS_RESPONSE:
+ handleListChannelUsersResponse(msg);
+ break;
+
+ case CPMSG_CHANNEL_EVENT:
+ handleChannelEvent(msg);
+ }
+}
+
+void ChatHandler::handleGameChatMessage(MessageIn &msg)
+{
+ short id = msg.readInt16();
+ std::string chatMsg = msg.readString();
+
+ if (id == 0)
+ {
+ chatWindow->chatLog(chatMsg, BY_SERVER);
+ return;
+ }
+
+ Being *being = beingManager->findBeing(id);
+
+ if (being)
+ {
+ chatWindow->chatLog(being->getName() + " : " + chatMsg,
+ being == player_node ? BY_PLAYER : BY_OTHER, "General");
+ being->setSpeech(chatMsg, SPEECH_TIME);
+ }
+ else
+ {
+ chatWindow->chatLog("Unknown : " + chatMsg, BY_OTHER, "General");
+ }
+}
- if (!being || chatMsgLength <= 0)
+void ChatHandler::handleEnterChannelResponse(MessageIn &msg)
+{
+ if(msg.readInt8() == ERRMSG_OK)
+ {
+ short channelId = msg.readInt16();
+ std::string channelName = msg.readString();
+ std::string announcement = msg.readString();
+ Channel *channel = new Channel(channelId, channelName, announcement);
+ channelManager->addChannel(channel);
+ chatWindow->createNewChannelTab(channelName);
+ chatWindow->chatLog("Topic: " + announcement, BY_CHANNEL, channelName);
+
+ std::string user;
+ std::string userModes;
+ chatWindow->chatLog("Players in this channel:", BY_CHANNEL, channelName);
+ while(msg.getUnreadLength())
+ {
+ user = msg.readString();
+ if (user == "")
+ return;
+ userModes = msg.readString();
+ if (userModes.find('o') != std::string::npos)
{
- break;
+ user = "@" + user;
}
+ chatWindow->chatLog(user, BY_CHANNEL, channelName);
+ }
+
+ }
+ else
+ {
+ chatWindow->chatLog("Error joining channel", BY_SERVER);
+ }
+}
- chatMsg = msg->readString(chatMsgLength);
+void ChatHandler::handleListChannelsResponse(MessageIn &msg)
+{
+ chatWindow->chatLog("Listing Channels", BY_SERVER);
+ while(msg.getUnreadLength())
+ {
+ std::string channelName = msg.readString();
+ if (channelName == "")
+ return;
+ std::ostringstream numUsers;
+ numUsers << msg.readInt16();
+ channelName += " - ";
+ channelName += numUsers.str();
+ chatWindow->chatLog(channelName, BY_SERVER);
+ }
+ chatWindow->chatLog("End of channel list", BY_SERVER);
+}
- std::string::size_type pos = chatMsg.find(" : ", 0);
- std::string sender_name = ((pos == std::string::npos)
- ? ""
- : chatMsg.substr(0, pos));
+void ChatHandler::handlePrivateMessage(MessageIn &msg)
+{
+ std::string userNick = msg.readString();
+ std::string chatMsg = msg.readString();
- // 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->chatLog(chatMsg, BY_OTHER);
+ if (!chatWindow->tabExists(userNick))
+ {
+ chatWindow->createNewChannelTab(userNick);
- chatMsg.erase(0, pos + 3);
- trim(chatMsg);
+ }
+ chatWindow->chatLog(userNick + ": " + chatMsg, BY_OTHER, userNick);
+}
+
+void ChatHandler::handleAnnouncement(MessageIn &msg)
+{
+ std::string chatMsg = msg.readString();
+ chatWindow->chatLog(chatMsg, BY_GM);
+}
- if (player_relations.hasPermission(sender_name, PlayerRelation::SPEECH_FLOAT))
- being->setSpeech(chatMsg, SPEECH_TIME);
+void ChatHandler::handleChatMessage(MessageIn &msg)
+{
+ short channelId = msg.readInt16();
+ std::string userNick = msg.readString();
+ std::string chatMsg = msg.readString();
+
+ chatWindow->sendToChannel(channelId, userNick, chatMsg);
+}
+
+void ChatHandler::handleQuitChannelResponse(MessageIn &msg)
+{
+ if(msg.readInt8() == ERRMSG_OK)
+ {
+ short channelId = msg.readInt16();
+ // remove the chat tab
+ chatWindow->removeChannel(channelId);
+ }
+}
+
+void ChatHandler::handleListChannelUsersResponse(MessageIn &msg)
+{
+ std::string channel = msg.readString();
+ std::string userNick;
+ std::string userModes;
+ chatWindow->chatLog("Players in this channel:", BY_CHANNEL, channel);
+ while(msg.getUnreadLength())
+ {
+ userNick = msg.readString();
+ if (userNick == "")
+ {
break;
}
+ userModes = msg.readString();
+ if (userModes.find('o') != std::string::npos)
+ {
+ userNick = "@" + userNick;
+ }
+ chatWindow->chatLog(userNick, BY_CHANNEL, channel);
+ }
+}
- case SMSG_PLAYER_CHAT:
- case SMSG_GM_CHAT: {
- chatMsgLength = msg->readInt16() - 4;
+void ChatHandler::handleChannelEvent(MessageIn &msg)
+{
+ short channelId = msg.readInt16();
+ char eventId = msg.readInt8();
+ std::string line = msg.readString();
+ Channel *channel = channelManager->findById(channelId);
- if (chatMsgLength <= 0)
- {
+ if(channel)
+ {
+ switch(eventId)
+ {
+ case CHAT_EVENT_NEW_PLAYER:
+ line += " entered the channel.";
break;
- }
-
- chatMsg = msg->readString(chatMsgLength);
- std::string::size_type pos = chatMsg.find(" : ", 0);
- if (msg->getId() == SMSG_PLAYER_CHAT)
- {
- chatWindow->chatLog(chatMsg, BY_PLAYER);
+ case CHAT_EVENT_LEAVING_PLAYER:
+ line += " left the channel.";
+ break;
- if (pos != std::string::npos)
- chatMsg.erase(0, pos + 3);
+ case CHAT_EVENT_TOPIC_CHANGE:
+ line = "Topic: " + line;
+ break;
- trim(chatMsg);
+ case CHAT_EVENT_MODE_CHANGE:
+ {
+ int first = line.find(":");
+ int second = line.find(":", first+1);
+ std::string user1 = line.substr(0, first);
+ std::string user2 = line.substr(first+1, second);
+ std::string mode = line.substr(second+1, line.length());
+ line = user1 + " has set mode " + mode + " on user " + user2;
+ } break;
- player_node->setSpeech(chatMsg, SPEECH_TIME);
- }
- else
+ case CHAT_EVENT_KICKED_PLAYER:
{
- chatWindow->chatLog(chatMsg, BY_GM);
- }
- break;
- }
+ int first = line.find(":");
+ std::string user1 = line.substr(0, first);
+ std::string user2 = line.substr(first+1, line.length());
+ line = user1 + " has kicked " + user2;
+ } break;
- case SMSG_WHO_ANSWER:
- chatWindow->chatLog("Online users: " + toString(msg->readInt32()),
- BY_SERVER);
- break;
+ default:
+ line = "Unknown channel event.";
+ }
- case 0x010c:
- // Display MVP player
- msg->readInt32(); // id
- chatWindow->chatLog("MVP player", BY_SERVER);
- break;
+ chatWindow->chatLog(line, BY_CHANNEL, channel->getName());
}
}
+