Mana
Loading...
Searching...
No Matches
chathandler.cpp
Go to the documentation of this file.
1/*
2 * The Mana Client
3 * Copyright (C) 2004-2009 The Mana World Development Team
4 * Copyright (C) 2009-2012 The Mana Developers
5 *
6 * This file is part of The Mana Client.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
23
24#include "actorspritemanager.h"
25#include "being.h"
26#include "client.h"
27#include "channel.h"
28#include "channelmanager.h"
29#include "event.h"
30#include "log.h"
31#include "playerrelations.h"
32
34
39
40#include "utils/gettext.h"
41#include "utils/stringutils.h"
42
43#include <string>
44#include <iostream>
45
46extern Being *local_player;
47
49
50namespace ManaServ {
51
52extern Connection *chatServerConnection;
53extern Connection *gameServerConnection;
54extern std::string netToken;
56
76
78{
79 switch (msg.getId())
80 {
81 case GPMSG_SAY:
83 break;
84
87 break;
88
91 break;
92
93 case CPMSG_PRIVMSG:
95 break;
96
99 break;
100
101 case CPMSG_PUBMSG:
103 break;
104
107 break;
108
111 break;
112
115 break;
116
119 break;
121 {
122 int errMsg = msg.readInt8();
123 // Successful logout
124 if (errMsg == ERRMSG_OK)
125 {
126 // TODO: Handle logout
127 }
128 else
129 {
130 switch (errMsg)
131 {
132 case ERRMSG_NO_LOGIN:
133 errorMessage = "Chatserver: Not logged in";
134 break;
135 default:
136 errorMessage = "Chatserver: Unknown error";
137 break;
138 }
140 }
141 }
142 break;
143 }
144}
145
147{
148 short id = msg.readInt16();
149 std::string chatMsg = msg.readString();
150
151 if (id == 0)
152 {
153 serverNotice(chatMsg);
154 return;
155 }
156
157 Being *being = actorSpriteManager->findBeing(id);
158
159 if (!being)
160 {
161 Log::warn("Received GPMSG_SAY for unknown being with id %i."
162 " (Message is: %s)", id, chatMsg.c_str());
163 return;
164 }
165
166 std::string mes = being->getName() + " : " + chatMsg;
167
168 Event event(being == local_player ? Event::Player
169 : Event::Being);
170 event.setString("message", mes);
171 event.setString("text", chatMsg);
172 event.setString("nick", being->getName());
173 event.setInt("beingId", id);
174 event.setInt("permissions", player_relations
175 .checkPermissionSilently(being->getName(),
177 event.trigger(Event::ChatChannel);
178}
179
181{
182 if (msg.readInt8() == ERRMSG_OK)
183 {
184 short channelId = msg.readInt16();
185 std::string channelName = msg.readString();
186 std::string announcement = msg.readString();
187 auto *channel = new Channel(channelId, channelName, announcement);
188 channelManager->addChannel(channel);
189 ChatTab *tab = channel->getTab();
190 tab->chatLog(strprintf(_("Topic: %s"), announcement.c_str()), BY_CHANNEL);
191
192 std::string user;
193 std::string userModes;
194 tab->chatLog(_("Players in this channel:"), BY_CHANNEL);
195 while (msg.getUnreadLength())
196 {
197 user = msg.readString();
198 if (user.empty())
199 return;
200 userModes = msg.readString();
201 if (userModes.find('o') != std::string::npos)
202 {
203 user = "@" + user;
204 }
205 tab->chatLog(user, BY_CHANNEL);
206 }
207
208 }
209 else
210 {
211 serverNotice(_("Error joining channel."));
212 }
213}
214
216{
217 serverNotice(_("Listing channels."));
218 while (msg.getUnreadLength())
219 {
220 std::string channelName = msg.readString();
221 if (channelName.empty())
222 return;
223 std::ostringstream numUsers;
224 numUsers << msg.readInt16();
225 channelName += " - ";
226 channelName += numUsers.str();
227 serverNotice(channelName);
228 }
229 serverNotice(_("End of channel list."));
230}
231
233{
234 std::string userNick = msg.readString();
235 std::string chatMsg = msg.readString();
236
237 Event event(Event::Whisper);
238 event.setString("nick", userNick);
239 event.setString("message", chatMsg);
240 event.trigger(Event::ChatChannel);
241}
242
244{
245 std::string chatMsg = msg.readString();
246 std::string sender = msg.readString();
248 event.setString("message", sender + " : " + chatMsg);
249 event.trigger(Event::ChatChannel);
250}
251
253{
254 short channelId = msg.readInt16();
255 std::string userNick = msg.readString();
256 std::string chatMsg = msg.readString();
257
258 if (Channel *channel = channelManager->findById(channelId))
259 {
260 channel->getTab()->chatLog(userNick, chatMsg);
261 }
262 else
263 {
264 // Can't find channel
265 Log::info("Couldn't find chat channel id: %hi", channelId);
266 }
267}
268
270{
271 if (msg.readInt8() == ERRMSG_OK)
272 {
273 short channelId = msg.readInt16();
274 Channel *channel = channelManager->findById(channelId);
276 }
277}
278
280{
281 std::string channelName = msg.readString();
282 std::string userNick;
283 std::string userModes;
284 Channel *channel = channelManager->findByName(channelName);
285 channel->getTab()->chatLog(_("Players in this channel:"), BY_CHANNEL);
286 while (msg.getUnreadLength())
287 {
288 userNick = msg.readString();
289 if (userNick.empty())
290 {
291 break;
292 }
293 userModes = msg.readString();
294 if (userModes.find('o') != std::string::npos)
295 {
296 userNick = "@" + userNick;
297 }
298 localChatTab->chatLog(userNick, BY_CHANNEL, channel);
299 }
300}
301
303{
304 short channelId = msg.readInt16();
305 char eventId = msg.readInt8();
306 std::string line = msg.readString();
307 Channel *channel = channelManager->findById(channelId);
308
309 if (channel)
310 {
311 switch(eventId)
312 {
314 channel->getTab()->chatLog(strprintf(_("%s entered the "
315 "channel."), line.c_str()), BY_CHANNEL);
316 break;
317
319 channel->getTab()->chatLog(strprintf(_("%s left the channel."),
320 line.c_str()), BY_CHANNEL);
321 break;
322
324 channel->getTab()->chatLog(strprintf(_("Topic: %s"),
325 line.c_str()), BY_CHANNEL);
326 break;
327
329 {
330 int first = line.find(":");
331 int second = line.find(":", first+1);
332 std::string user1 = line.substr(0, first);
333 std::string user2 = line.substr(first+1, second);
334 std::string mode = line.substr(second+1, line.length());
335 channel->getTab()->chatLog(strprintf(_("%s has set mode %s "
336 "on user %s."), user1.c_str(), mode.c_str(),
337 user2.c_str()), BY_CHANNEL);
338 } break;
339
341 {
342 int first = line.find(":");
343 std::string user1 = line.substr(0, first);
344 std::string user2 = line.substr(first+1, line.length());
345 channel->getTab()->chatLog(strprintf(_("%s has kicked %s."),
346 user1.c_str(), user2.c_str()), BY_CHANNEL);
347 } break;
348
349 default:
350 channel->getTab()->chatLog(_("Unknown channel event."),
351 BY_CHANNEL);
352 }
353 }
354}
355
357{
358 while (msg.getUnreadLength())
359 {
360 std::string userNick = msg.readString();
361 if (userNick.empty())
362 break;
363
364 serverNotice(userNick);
365 }
366}
367
374
379
384
385void ChatHandler::talk(const std::string &text)
386{
388 msg.writeString(text);
390}
391
392void ChatHandler::me(const std::string &text)
393{
394 // TODO
395}
396
397void ChatHandler::privateMessage(const std::string &recipient,
398 const std::string &text)
399{
401 msg.writeString(recipient);
402 msg.writeString(text);
404}
405
411
412void ChatHandler::enterChannel(const std::string &channel,
413 const std::string &password)
414{
416 msg.writeString(channel);
417 msg.writeString(password);
419}
420
421void ChatHandler::quitChannel(int channelId)
422{
424 msg.writeInt16(channelId);
426}
427
428void ChatHandler::sendToChannel(int channelId, const std::string &text)
429{
431 msg.writeString(text);
432 msg.writeInt16(channelId);
434}
435
436void ChatHandler::userList(const std::string &channel)
437{
439 msg.writeString(channel);
441}
442
443void ChatHandler::setChannelTopic(int channelId, const std::string &text)
444{
446 msg.writeInt16(channelId);
447 msg.writeString(text);
449}
450
451void ChatHandler::setUserMode(int channelId, const std::string &name, int mode)
452{
454 msg.writeInt16(channelId);
455 msg.writeString(name);
456 msg.writeInt8(mode);
458}
459
460void ChatHandler::kickUser(int channelId, const std::string &name)
461{
463 msg.writeInt16(channelId);
464 msg.writeString(name);
466}
467
469{
472}
473
474} // namespace ManaServ
ActorSpriteManager * actorSpriteManager
Definition game.cpp:110
ChannelManager * channelManager
Definition game.cpp:111
@ BY_CHANNEL
Definition chatwindow.h:51
Being * findBeing(int id) const
Returns a specific Being, by id;.
Definition being.h:65
const std::string & getName() const
Returns the name of the being.
Definition being.h:190
Channel * findByName(const std::string &name) const
void addChannel(Channel *channel)
void removeChannel(Channel *channel)
Channel * findById(int id) const
ChannelTab * getTab()
Definition channel.h:73
A tab for the chat window.
Definition chattab.h:36
void chatLog(std::string line, Own own=BY_SERVER, bool ignoreRecord=false)
Adds a line of text to our message list.
Definition chattab.cpp:111
static void setState(State state)
Definition client.h:169
Definition event.h:42
@ Announcement
Definition event.h:62
@ Being
Definition event.h:63
@ Whisper
Definition event.h:102
@ Player
Definition event.h:92
void setString(const std::string &key, const std::string &value)
Sets the given variable to the given string, if it isn't already set.
Definition event.cpp:58
@ ChatChannel
Definition event.h:49
void handleWhoResponse(MessageIn &msg)
Handle who responses.
void handleListChannelsResponse(MessageIn &msg)
Handle list channels responses.
void userList(const std::string &channel) override
void handlePrivateMessage(MessageIn &msg)
Handle private messages.
void enterChannel(const std::string &channel, const std::string &password) override
void handleAnnouncement(MessageIn &msg)
Handle announcements.
void me(const std::string &text) override
void handleQuitChannelResponse(MessageIn &msg)
Handle quit channel responses.
void handleListChannelUsersResponse(MessageIn &msg)
Handle list channel users responses.
void privateMessage(const std::string &recipient, const std::string &text) override
void sendToChannel(int channelId, const std::string &text) override
void handleMessage(MessageIn &msg) override
Handle the given message appropriately.
void who() override
void kickUser(int channelId, const std::string &name) override
void handleEnterChannelResponse(MessageIn &msg)
Handle channel entry responses.
void channelList() override
void setChannelTopic(int channelId, const std::string &text) override
void setUserMode(int channelId, const std::string &name, int mode) override
void handleChannelEvent(MessageIn &msg)
Handle channel events.
void quitChannel(int channelId) override
void handleGameChatMessage(MessageIn &msg)
Handle chat messages sent from the game server.
void talk(const std::string &text) override
void handleChatMessage(MessageIn &msg)
Handle chat messages.
bool isConnected()
Returns whether the server is connected.
void send(const ManaServ::MessageOut &msg)
Sends a message.
void disconnect()
Disconnects from the given server.
Used for parsing an incoming message from manaserv.
Definition messagein.h:37
uint16_t readInt16()
Reads an unsigned 16-bit integer from the message.
Definition messagein.cpp:58
unsigned int getUnreadLength() const
Returns the length of unread data.
Definition messagein.h:54
std::string readString(int length=-1)
Reads a string.
Definition messagein.cpp:92
uint16_t getId() const
Returns the message ID.
Definition messagein.h:44
uint8_t readInt8()
Reads an unsigned 8-bit integer from the message.
Definition messagein.cpp:43
Used for building an outgoing message to manaserv.
Definition messageout.h:37
void writeInt16(uint16_t value)
Writes an unsigned 16-bit integer to the message.
void writeInt8(uint8_t value)
Writes an unsigned 8-bit integer to the message.
void writeString(const std::string &string, int length=-1)
Writes a string.
const uint16_t * handledMessages
std::string errorMessage
Definition client.cpp:94
@ STATE_ERROR
Definition client.h:60
ChatTab * localChatTab
Definition game.cpp:117
void serverNotice(const std::string &message)
Definition event.h:319
#define _(s)
Definition gettext.h:38
LocalPlayer * local_player
Being * local_player
Net::ChatHandler * chatHandler
Definition net.cpp:48
void warn(const char *log_text,...) LOG_PRINTF_ATTR
void info(const char *log_text,...) LOG_PRINTF_ATTR
Connection * gameServerConnection
std::string netToken
Connection * chatServerConnection
ServerInfo chatServer
@ CPMSG_ENTER_CHANNEL_RESPONSE
@ CPMSG_QUIT_CHANNEL_RESPONSE
@ CPMSG_LIST_CHANNELUSERS_RESPONSE
@ CPMSG_LIST_CHANNELS_RESPONSE
PlayerRelationsManager player_relations
std::string strprintf(char const *format,...)
A safe version of sprintf that returns a std::string of the result.