1 /*
2 Copyright (C) 2017-2018 by the Battle for Wesnoth Project https://www.wesnoth.org/
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY.
10
11 See the COPYING file for more details.
12 */
13
14 #include "chat_events.hpp"
15
16 #include "formula/string_utils.hpp"
17 #include "gettext.hpp"
18 #include "log.hpp"
19 #include "map_command_handler.hpp"
20 #include "chat_command_handler.hpp"
21 #include "preferences/credentials.hpp"
22 #include "preferences/general.hpp"
23 #include "preferences/game.hpp"
24
25 #include <boost/range/algorithm/find_if.hpp>
26
27 static lg::log_domain log_engine("engine");
28 #define ERR_NG LOG_STREAM(err, log_engine)
29 #define LOG_NG LOG_STREAM(info, log_engine)
30
31 namespace events {
32
chat_handler()33 chat_handler::chat_handler()
34 {
35 }
36
~chat_handler()37 chat_handler::~chat_handler()
38 {
39 }
40
41 /**
42 * Change the log level of a log domain.
43 *
44 * @param data string of the form: "@<level@> @<domain@>"
45 */
change_logging(const std::string & data)46 void chat_handler::change_logging(const std::string& data) {
47 const std::string::const_iterator j =
48 std::find(data.begin(), data.end(), ' ');
49 if (j == data.end()) return;
50 const std::string level(data.begin(), j);
51 const std::string domain(j + 1, data.end());
52 int severity;
53 if (level == "error") severity = lg::err().get_severity();
54 else if (level == "warning") severity = lg::warn().get_severity();
55 else if (level == "info") severity = lg::info().get_severity();
56 else if (level == "debug") severity = lg::debug().get_severity();
57 else {
58 utils::string_map symbols;
59 symbols["level"] = level;
60 const std::string& msg =
61 VGETTEXT("Unknown debug level: '$level'.", symbols);
62 ERR_NG << msg << std::endl;
63 add_chat_message(time(nullptr), _("error"), 0, msg);
64 return;
65 }
66 if (!lg::set_log_domain_severity(domain, severity)) {
67 utils::string_map symbols;
68 symbols["domain"] = domain;
69 const std::string& msg =
70 VGETTEXT("Unknown debug domain: '$domain'.", symbols);
71 ERR_NG << msg << std::endl;
72 add_chat_message(time(nullptr), _("error"), 0, msg);
73 return;
74 }
75 else {
76 utils::string_map symbols;
77 symbols["level"] = level;
78 symbols["domain"] = domain;
79 const std::string& msg =
80 VGETTEXT("Switched domain: '$domain' to level: '$level'.", symbols);
81 LOG_NG << msg << "\n";
82 add_chat_message(time(nullptr), "log", 0, msg);
83 }
84 }
85
send_command(const std::string & cmd,const std::string & args)86 void chat_handler::send_command(const std::string& cmd, const std::string& args /* = "" */) {
87 config data;
88 if (cmd == "muteall") {
89 data.add_child(cmd);
90 }
91 else if (cmd == "query") {
92 data.add_child(cmd)["type"] = args;
93 }
94 else if (cmd == "ban" || cmd == "unban" || cmd == "kick"
95 || cmd == "mute" || cmd == "unmute") {
96 data.add_child(cmd)["username"] = args;
97 }
98 else if (cmd == "ping") {
99 data[cmd] = std::to_string(time(nullptr));
100 }
101 else if (cmd == "report") {
102 data.add_child("query")["type"] = "report " + args;
103 }
104 else if (cmd == "join") {
105 data.add_child("room_join")["room"] = args;
106 }
107 else if (cmd == "part") {
108 data.add_child("room_part")["room"] = args;
109 }
110 send_to_server(data);
111 }
112
do_speak(const std::string & message,bool allies_only)113 void chat_handler::do_speak(const std::string& message, bool allies_only)
114 {
115 if (message.empty() || message == "/") {
116 return;
117 }
118 bool is_command = (message[0] == '/');
119 bool quoted_command = (is_command && message[1] == ' ');
120
121 if (!is_command) {
122 send_chat_message(message, allies_only);
123 return;
124 }
125 else if (quoted_command) {
126 send_chat_message(std::string(message.begin() + 2, message.end()), allies_only);
127 return;
128 }
129 std::string cmd(message.begin() + 1, message.end());
130 chat_command_handler cch(*this, allies_only);
131 cch.dispatch(cmd);
132 }
133
user_relation_changed(const std::string &)134 void chat_handler::user_relation_changed(const std::string& /*name*/)
135 {
136 }
137
send_whisper(const std::string & receiver,const std::string & message)138 void chat_handler::send_whisper(const std::string& receiver, const std::string& message)
139 {
140 config cwhisper, data;
141 cwhisper["receiver"] = receiver;
142 cwhisper["message"] = message;
143 cwhisper["sender"] = preferences::login();
144 data.add_child("whisper", std::move(cwhisper));
145 send_to_server(data);
146 }
147
add_whisper_sent(const std::string & receiver,const std::string & message)148 void chat_handler::add_whisper_sent(const std::string& receiver, const std::string& message)
149 {
150 utils::string_map symbols;
151 symbols["receiver"] = receiver;
152 add_chat_message(time(nullptr), VGETTEXT("whisper to $receiver", symbols), 0, message);
153 }
154
add_whisper_received(const std::string & sender,const std::string & message)155 void chat_handler::add_whisper_received(const std::string& sender, const std::string& message)
156 {
157 utils::string_map symbols;
158 symbols["sender"] = sender;
159 add_chat_message(time(nullptr), VGETTEXT("whisper: $sender", symbols), 0, message);
160 }
161
send_chat_room_message(const std::string & room,const std::string & message)162 void chat_handler::send_chat_room_message(const std::string& room,
163 const std::string& message)
164 {
165 config cmsg, data;
166 cmsg["room"] = room;
167 cmsg["message"] = message;
168 cmsg["sender"] = preferences::login();
169 data.add_child("message", std::move(cmsg));
170 send_to_server(data);
171 }
172
add_chat_room_message_sent(const std::string & room,const std::string & message)173 void chat_handler::add_chat_room_message_sent(const std::string &room, const std::string &message)
174 {
175 add_chat_room_message_received(room, preferences::login(), message);
176 }
177
add_chat_room_message_received(const std::string & room,const std::string & speaker,const std::string & message)178 void chat_handler::add_chat_room_message_received(const std::string &room,
179 const std::string &speaker, const std::string &message)
180 {
181 add_chat_message(time(nullptr), room + ": " + speaker, 0, message, events::chat_handler::MESSAGE_PRIVATE);
182 }
183
184 }
185