diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index 9e4473655..b75bf2de5 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -1401,6 +1401,9 @@ debug_log_level (Debug log level) enum action ,none,error,warning,action,info,ve # debug.txt is only moved if this setting is positive. debug_log_size_max (Debug log file size threshold) int 50 +# Minimal level of logging to be written to chat. +chat_log_level (Chat log level) enum error ,none,error,warning,action,info,verbose + # Enable IPv6 support (for both client and server). # Required for IPv6 connections to work at all. enable_ipv6 (IPv6) bool true diff --git a/src/client/game.cpp b/src/client/game.cpp index 422e17d4f..e7663a113 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -855,6 +855,7 @@ private: SoundMaker *soundmaker = nullptr; ChatBackend *chat_backend = nullptr; + LogOutputBuffer m_chat_log_buf; EventManager *eventmgr = nullptr; QuicktuneShortcutter *quicktune = nullptr; @@ -926,6 +927,7 @@ private: }; Game::Game() : + m_chat_log_buf(g_logger), m_game_ui(new GameUI()) { g_settings->registerChangedCallback("doubletap_jump", @@ -1192,6 +1194,7 @@ void Game::shutdown() chat_backend->addMessage(L"", L"# Disconnected."); chat_backend->addMessage(L"", L""); + m_chat_log_buf.clear(); if (client) { client->Stop(); @@ -2903,18 +2906,9 @@ void Game::processClientEvents(CameraOrientation *cam) void Game::updateChat(f32 dtime, const v2u32 &screensize) { - // Add chat log output for errors to be shown in chat - static LogOutputBuffer chat_log_error_buf(g_logger, LL_ERROR); - // Get new messages from error log buffer - while (!chat_log_error_buf.empty()) { - std::wstring error_message = utf8_to_wide(chat_log_error_buf.get()); - if (!g_settings->getBool("disable_escape_sequences")) { - error_message.insert(0, L"\x1b(c@red)"); - error_message.append(L"\x1b(c@white)"); - } - chat_backend->addMessage(L"", error_message); - } + while (!m_chat_log_buf.empty()) + chat_backend->addMessage(L"", utf8_to_wide(m_chat_log_buf.get())); // Get new messages from client std::wstring message; diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 33654e213..1d0610c0f 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -400,6 +400,7 @@ void set_default_settings(Settings *settings) settings->setDefault("remote_media", ""); settings->setDefault("debug_log_level", "action"); settings->setDefault("debug_log_size_max", "50"); + settings->setDefault("chat_log_level", "error"); settings->setDefault("emergequeue_limit_total", "512"); settings->setDefault("emergequeue_limit_diskonly", "64"); settings->setDefault("emergequeue_limit_generate", "64"); diff --git a/src/log.cpp b/src/log.cpp index 30344b4df..54442c39b 100644 --- a/src/log.cpp +++ b/src/log.cpp @@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "debug.h" #include "gettime.h" #include "porting.h" +#include "settings.h" #include "config.h" #include "exceptions.h" #include "util/numeric.h" @@ -338,7 +339,80 @@ void FileLogOutput::setFile(const std::string &filename, s64 file_size_max) "-------------\n" << std::endl; } +void StreamLogOutput::logRaw(LogLevel lev, const std::string &line) +{ + bool colored_message = (Logger::color_mode == LOG_COLOR_ALWAYS) || + (Logger::color_mode == LOG_COLOR_AUTO && is_tty); + if (colored_message) { + switch (lev) { + case LL_ERROR: + // error is red + m_stream << "\033[91m"; + break; + case LL_WARNING: + // warning is yellow + m_stream << "\033[93m"; + break; + case LL_INFO: + // info is a bit dark + m_stream << "\033[37m"; + break; + case LL_VERBOSE: + // verbose is darker than info + m_stream << "\033[2m"; + break; + default: + // action is white + colored_message = false; + } + } + m_stream << line << std::endl; + + if (colored_message) { + // reset to white color + m_stream << "\033[0m"; + } +} + +void LogOutputBuffer::updateLogLevel() +{ + const std::string &conf_loglev = g_settings->get("chat_log_level"); + LogLevel log_level = Logger::stringToLevel(conf_loglev); + if (log_level == LL_MAX) { + warningstream << "Supplied unrecognized chat_log_level; " + "showing none." << std::endl; + log_level = LL_NONE; + } + + m_logger.removeOutput(this); + m_logger.addOutputMaxLevel(this, log_level); +} + +void LogOutputBuffer::logRaw(LogLevel lev, const std::string &line) +{ + std::string color; + + if (!g_settings->getBool("disable_escape_sequences")) { + switch (lev) { + case LL_ERROR: // red + color = "\x1b(c@#F00)"; + break; + case LL_WARNING: // yellow + color = "\x1b(c@#EE0)"; + break; + case LL_INFO: // grey + color = "\x1b(c@#BBB)"; + break; + case LL_VERBOSE: // dark grey + color = "\x1b(c@#888)"; + break; + default: break; + } + } + + m_buffer.push(color.append(line)); +} //// //// *Buffer methods diff --git a/src/log.h b/src/log.h index 6350d8a86..856d3479b 100644 --- a/src/log.h +++ b/src/log.h @@ -124,39 +124,7 @@ public: #endif } - void logRaw(LogLevel lev, const std::string &line) - { - bool colored_message = (Logger::color_mode == LOG_COLOR_ALWAYS) || - (Logger::color_mode == LOG_COLOR_AUTO && is_tty); - if (colored_message) - switch (lev) { - case LL_ERROR: - // error is red - m_stream << "\033[91m"; - break; - case LL_WARNING: - // warning is yellow - m_stream << "\033[93m"; - break; - case LL_INFO: - // info is a bit dark - m_stream << "\033[37m"; - break; - case LL_VERBOSE: - // verbose is darker than info - m_stream << "\033[2m"; - break; - default: - // action is white - colored_message = false; - } - - m_stream << line << std::endl; - - if (colored_message) - // reset to white color - m_stream << "\033[0m"; - } + void logRaw(LogLevel lev, const std::string &line); private: std::ostream &m_stream; @@ -178,23 +146,27 @@ private: class LogOutputBuffer : public ICombinedLogOutput { public: - LogOutputBuffer(Logger &logger, LogLevel lev) : + LogOutputBuffer(Logger &logger) : m_logger(logger) { - m_logger.addOutput(this, lev); - } + updateLogLevel(); + }; - ~LogOutputBuffer() + virtual ~LogOutputBuffer() { m_logger.removeOutput(this); } - void logRaw(LogLevel lev, const std::string &line) + void updateLogLevel(); + + void logRaw(LogLevel lev, const std::string &line); + + void clear() { - m_buffer.push(line); + m_buffer = std::queue(); } - bool empty() + bool empty() const { return m_buffer.empty(); }