The Battle for Wesnoth  1.19.13+dev
chat_events.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2017 - 2025
3  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #include "chat_events.hpp"
16 
17 #include "formula/string_utils.hpp"
18 #include "gettext.hpp"
19 #include "log.hpp"
20 #include "chat_command_handler.hpp"
22 
23 static lg::log_domain log_engine("engine");
24 #define ERR_NG LOG_STREAM(err, log_engine)
25 #define LOG_NG LOG_STREAM(info, log_engine)
26 
27 namespace events {
28 
30 {
31 }
32 
34 {
35 }
36 
37 /**
38 * Change the log level of a log domain.
39 *
40 * @param data string of the form: "@<level@> @<domain@>"
41 */
42 void chat_handler::change_logging(const std::string& data) {
43  const std::string::const_iterator j =
44  std::find(data.begin(), data.end(), ' ');
45  if (j == data.end()) return;
46  const std::string level(data.begin(), j);
47  const std::string domain(j + 1, data.end());
49  if (level == "error") severity = lg::err().get_severity();
50  else if (level == "warning") severity = lg::warn().get_severity();
51  else if (level == "info") severity = lg::info().get_severity();
52  else if (level == "debug") severity = lg::debug().get_severity();
53  else {
54  utils::string_map symbols;
55  symbols["level"] = level;
56  const std::string& msg =
57  VGETTEXT("Unknown debug level: '$level'.", symbols);
58  ERR_NG << msg;
59  add_chat_message(std::chrono::system_clock::now(), _("error"), 0, msg);
60  return;
61  }
62  if (!lg::set_log_domain_severity(domain, severity)) {
63  utils::string_map symbols;
64  symbols["domain"] = domain;
65  const std::string& msg =
66  VGETTEXT("Unknown debug domain: '$domain'.", symbols);
67  ERR_NG << msg;
68  add_chat_message(std::chrono::system_clock::now(), _("error"), 0, msg);
69  return;
70  }
71  else {
72  utils::string_map symbols;
73  symbols["level"] = level;
74  symbols["domain"] = domain;
75  const std::string& msg =
76  VGETTEXT("Switched domain: '$domain' to level: '$level'.", symbols);
77  LOG_NG << msg;
78  add_chat_message(std::chrono::system_clock::now(), "log", 0, msg);
79  }
80 }
81 
82 void chat_handler::send_command(const std::string& cmd, const std::string& args /* = "" */) {
83  config data;
84  if (cmd == "muteall") {
85  data.add_child(cmd);
86  }
87  else if (cmd == "query") {
88  data.add_child(cmd)["type"] = args;
89  }
90  else if (cmd == "ban" || cmd == "unban" || cmd == "kick"
91  || cmd == "mute" || cmd == "unmute") {
92  data.add_child(cmd)["username"] = args;
93  }
94  else if (cmd == "ping") {
95  // Not using serialize_timestamp here since we need the steady clock
96  auto now = std::chrono::steady_clock::now();
97  data.add_child("ping")["requested_at"] = now.time_since_epoch();
98  }
99  else if (cmd == "report") {
100  data.add_child("query")["type"] = "report " + args;
101  }
102  else if (cmd == "roll") {
103  data.add_child("query")["type"] = "roll " + args;
104  }
106 }
107 
108 bool chat_handler::do_speak(const std::string& message, bool allies_only)
109 {
110  if (message.empty() || message == "/") {
111  return false;
112  }
113  bool is_command = (message[0] == '/');
114  bool quoted_command = (is_command && message[1] == ' ');
115 
116  if (!is_command) {
117  send_chat_message(message, allies_only);
118  return true;
119  }
120  else if (quoted_command) {
121  send_chat_message(std::string(message.begin() + 2, message.end()), allies_only);
122  return true;
123  }
124  std::string cmd(message.begin() + 1, message.end());
125  chat_command_handler cch(*this, allies_only);
126  return cch.dispatch(cmd);
127 }
128 
129 void chat_handler::user_relation_changed(const std::string& /*name*/)
130 {
131 }
132 
133 void chat_handler::send_whisper(const std::string& receiver, const std::string& message)
134 {
135  config cwhisper, data;
136  cwhisper["receiver"] = receiver;
137  cwhisper["message"] = message;
138  cwhisper["sender"] = prefs::get().login();
139  data.add_child("whisper", std::move(cwhisper));
141 }
142 
143 void chat_handler::add_whisper_sent(const std::string& receiver, const std::string& message)
144 {
145  utils::string_map symbols;
146  symbols["receiver"] = receiver;
147  add_chat_message(std::chrono::system_clock::now(), VGETTEXT("whisper to $receiver", symbols), 0, message);
148 }
149 
150 void chat_handler::add_whisper_received(const std::string& sender, const std::string& message)
151 {
152  utils::string_map symbols;
153  symbols["sender"] = sender;
154  add_chat_message(std::chrono::system_clock::now(), VGETTEXT("whisper: $sender", symbols), 0, message);
155 }
156 
157 void chat_handler::send_chat_room_message(const std::string& room,
158  const std::string& message)
159 {
160  config cmsg, data;
161  cmsg["room"] = room;
162  cmsg["message"] = message;
163  cmsg["sender"] = prefs::get().login();
164  data.add_child("message", std::move(cmsg));
166 }
167 
168 void chat_handler::add_chat_room_message_sent(const std::string &room, const std::string &message)
169 {
170  add_chat_room_message_received(room, prefs::get().login(), message);
171 }
172 
173 void chat_handler::add_chat_room_message_received(const std::string &room,
174  const std::string &speaker, const std::string &message)
175 {
176  add_chat_message(std::chrono::system_clock::now(), room + ": " + speaker, 0, message, events::chat_handler::MESSAGE_PRIVATE);
177 }
178 
179 }
static lg::log_domain log_engine("engine")
#define ERR_NG
Definition: chat_events.cpp:24
#define LOG_NG
Definition: chat_events.cpp:25
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:158
virtual void add_chat_room_message_received(const std::string &room, const std::string &speaker, const std::string &message)
virtual void add_chat_message(const std::chrono::system_clock::time_point &time, const std::string &speaker, int side, const std::string &message, MESSAGE_TYPE type=MESSAGE_PRIVATE)=0
virtual void send_chat_room_message(const std::string &room, const std::string &message)
virtual void add_chat_room_message_sent(const std::string &room, const std::string &message)
virtual void user_relation_changed(const std::string &name)
Called when a processed command results in a relation (friend/ignore) change for a user whose name is...
virtual void add_whisper_received(const std::string &sender, const std::string &message)
bool do_speak(const std::string &message, bool allies_only=false)
virtual void add_whisper_sent(const std::string &receiver, const std::string &message)
void change_logging(const std::string &data)
Change the log level of a log domain.
Definition: chat_events.cpp:42
virtual void send_chat_message(const std::string &message, bool allies_only=false)=0
virtual void send_whisper(const std::string &receiver, const std::string &message)
virtual void send_to_server(const config &cfg)=0
void send_command(const std::string &cmd, const std::string &args="")
Definition: chat_events.cpp:82
severity get_severity() const
Definition: log.hpp:219
static prefs & get()
std::string login()
#define VGETTEXT(msgid,...)
Handy wrappers around interpolate_variables_into_string and gettext.
static std::string _(const char *str)
Definition: gettext.hpp:97
Standard logging facilities (interface).
Handling of system events.
logger & err()
Definition: log.cpp:339
severity
Definition: log.hpp:82
logger & debug()
Definition: log.cpp:357
logger & warn()
Definition: log.cpp:345
logger & info()
Definition: log.cpp:351
bool set_log_domain_severity(const std::string &name, severity severity)
Definition: log.cpp:379
std::map< std::string, t_string > string_map
auto * find(Container &container, const Value &value)
Convenience wrapper for using find on a container without needing to comare to end()
Definition: general.hpp:140
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
Definition: debugger.cpp:109
std::string_view data
Definition: picture.cpp:188