The Battle for Wesnoth 1.21.0-dev
 
Loading...
Searching...
No Matches
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
18#include "gettext.hpp"
19#include "log.hpp"
22
23static 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
27namespace events {
28
32
36
37/**
38* Change the log level of a log domain.
39*
40* @param data string of the form: "@<level@> @<domain@>"
41*/
42void 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());
48 lg::severity severity;
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
82void chat_handler::send_command(const std::string& cmd, const std::string& args /* = "" */) {
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// Return value of true represents a successful command completion and closure of the text box
109// Return value of false represents an unsuccessful input and leaves the text box open
110bool chat_handler::do_speak(const std::string& message, bool allies_only)
111{
112 if(message.empty()) {
113 return true;
114 }
115 if(message == "/") {
116 return false;
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 true;
124 }
125 else if (quoted_command) {
126 send_chat_message(std::string(message.begin() + 2, message.end()), allies_only);
127 return true;
128 }
129 std::string cmd(message.begin() + 1, message.end());
130 chat_command_handler cch(*this, allies_only);
131 return cch.dispatch(cmd);
132}
133
134void chat_handler::user_relation_changed(const std::string& /*name*/)
135{
136}
137
138void chat_handler::send_whisper(const std::string& receiver, const std::string& message)
139{
140 send_to_server(config{"whisper", config{
141 "receiver", receiver, "message", message, "sender", prefs::get().login()
142 }});
143}
144
145void chat_handler::add_whisper_sent(const std::string& receiver, const std::string& message)
146{
147 utils::string_map symbols;
148 symbols["receiver"] = receiver;
149 add_chat_message(std::chrono::system_clock::now(), VGETTEXT("whisper to $receiver", symbols), 0, message);
150}
151
152void chat_handler::add_whisper_received(const std::string& sender, const std::string& message)
153{
154 utils::string_map symbols;
155 symbols["sender"] = sender;
156 add_chat_message(std::chrono::system_clock::now(), VGETTEXT("whisper: $sender", symbols), 0, message);
157}
158
159void chat_handler::send_chat_room_message(const std::string& room,
160 const std::string& message)
161{
162 send_to_server(config{"message", config{
163 "room", room, "message", message, "sender", prefs::get().login()
164 }});
165}
166
167void chat_handler::add_chat_room_message_sent(const std::string &room, const std::string &message)
168{
169 add_chat_room_message_received(room, prefs::get().login(), message);
170}
171
173 const std::string &speaker, const std::string &message)
174{
175 add_chat_message(std::chrono::system_clock::now(), room + ": " + speaker, 0, message, events::chat_handler::MESSAGE_PRIVATE);
176}
177
178}
#define ERR_NG
#define LOG_NG
static lg::log_domain log_engine("engine")
A config object defines a single node in a WML file, with access to child nodes.
Definition config.hpp:157
config & add_child(std::string_view key)
Definition config.cpp:436
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.
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="")
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:100
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
std::string_view data
Definition picture.cpp:188