From f45ba78a72d86fd481a2d2064ac63858d69ad7ee Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Mon, 6 Apr 2020 16:54:12 +0200 Subject: Allow relative directories for `screenshot_path`, tweak default path (#9122) This will likely be more intuitive for users and should play better with sandboxed distributions such as Flatpak. In addition, the screenshot directory will now be created if it doesn't exist already. --- src/defaultsettings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/defaultsettings.cpp') diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 472522bf4..b6b1ce1f2 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -48,7 +48,7 @@ void set_default_settings(Settings *settings) settings->setDefault("pitch_move", "false"); settings->setDefault("fast_move", "false"); settings->setDefault("noclip", "false"); - settings->setDefault("screenshot_path", "."); + settings->setDefault("screenshot_path", "screenshots"); settings->setDefault("screenshot_format", "png"); settings->setDefault("screenshot_quality", "0"); settings->setDefault("client_unload_unused_data_timeout", "600"); -- cgit v1.2.3 From 56bababcdfce097a4e08cc3d1de8d798e7999ce7 Mon Sep 17 00:00:00 2001 From: Loic Blot Date: Mon, 27 Apr 2020 08:31:37 +0200 Subject: Add MetricsBackend with prometheus counter support --- Dockerfile | 22 +++++-- README.md | 1 + builtin/settingtypes.txt | 6 ++ src/CMakeLists.txt | 26 ++++++++ src/cmake_config.h.in | 1 + src/defaultsettings.cpp | 3 + src/map.cpp | 11 +++- src/map.h | 6 +- src/server.cpp | 57 ++++++++++++---- src/server.h | 21 ++++-- src/server/mods.cpp | 1 + src/server/mods.h | 3 + src/util/CMakeLists.txt | 1 + src/util/metricsbackend.cpp | 140 ++++++++++++++++++++++++++++++++++++++++ src/util/metricsbackend.h | 140 ++++++++++++++++++++++++++++++++++++++++ util/ci/build_prometheus_cpp.sh | 13 ++++ 16 files changed, 427 insertions(+), 25 deletions(-) create mode 100644 src/util/metricsbackend.cpp create mode 100644 src/util/metricsbackend.h create mode 100755 util/ci/build_prometheus_cpp.sh (limited to 'src/defaultsettings.cpp') diff --git a/Dockerfile b/Dockerfile index 7c1107288..72343ab9c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -21,15 +21,29 @@ WORKDIR /usr/src/minetest RUN apk add --no-cache git build-base irrlicht-dev cmake bzip2-dev libpng-dev \ jpeg-dev libxxf86vm-dev mesa-dev sqlite-dev libogg-dev \ libvorbis-dev openal-soft-dev curl-dev freetype-dev zlib-dev \ - gmp-dev jsoncpp-dev postgresql-dev && \ + gmp-dev jsoncpp-dev postgresql-dev ca-certificates && \ git clone --depth=1 -b ${MINETEST_GAME_VERSION} https://github.com/minetest/minetest_game.git ./games/minetest_game && \ - rm -fr ./games/minetest_game/.git && \ - mkdir build && \ + rm -fr ./games/minetest_game/.git + +WORKDIR /usr/src/ +RUN git clone --recursive https://github.com/jupp0r/prometheus-cpp/ && \ + mkdir prometheus-cpp/build && \ + cd prometheus-cpp/build && \ + cmake .. \ + -DCMAKE_INSTALL_PREFIX=/usr/local \ + -DCMAKE_BUILD_TYPE=Release \ + -DENABLE_TESTING=0 && \ + make -j2 && \ + make install + +WORKDIR /usr/src/minetest +RUN mkdir build && \ cd build && \ cmake .. \ -DCMAKE_INSTALL_PREFIX=/usr/local \ -DCMAKE_BUILD_TYPE=Release \ -DBUILD_SERVER=TRUE \ + -DENABLE_PROMETHEUS=TRUE \ -DBUILD_UNITTESTS=FALSE \ -DBUILD_CLIENT=FALSE && \ make -j2 && \ @@ -49,6 +63,6 @@ COPY --from=0 /usr/local/share/doc/minetest/minetest.conf.example /etc/minetest/ USER minetest:minetest -EXPOSE 30000/udp +EXPOSE 30000/udp 30000/tcp CMD ["/usr/local/bin/minetestserver", "--config", "/etc/minetest/minetest.conf"] diff --git a/README.md b/README.md index b3b2b863e..024e7b691 100644 --- a/README.md +++ b/README.md @@ -236,6 +236,7 @@ General options and their default values: ENABLE_SPATIAL=ON - Build with LibSpatial; Speeds up AreaStores ENABLE_SOUND=ON - Build with OpenAL, libogg & libvorbis; in-game sounds ENABLE_LUAJIT=ON - Build with LuaJIT (much faster than non-JIT Lua) + ENABLE_PROMETHEUS=OFF - Build with Prometheus metrics exporter (listens on tcp/30000 by default) ENABLE_SYSTEM_GMP=ON - Use GMP from system (much faster than bundled mini-gmp) ENABLE_SYSTEM_JSONCPP=OFF - Use JsonCPP from system OPENGL_GL_PREFERENCE=LEGACY - Linux client build only; See CMake Policy CMP0072 for reference diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index b9228f384..165ed8c06 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -955,6 +955,12 @@ address (Server address) string # Note that the port field in the main menu overrides this setting. remote_port (Remote port) int 30000 1 65535 +# Prometheus listener address. +# If minetest is compiled with ENABLE_PROMETHEUS option enabled, +# enable metrics listener for Prometheus on that address. +# Metrics can be fetch on http://127.0.0.1:30000/metrics +prometheus_listener_address (Prometheus listener address) string 127.0.0.1:30000 + # Save the map received by the client on disk. enable_local_map_saving (Saving map received from server) bool false diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b416faaf3..710d9e13e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -217,6 +217,26 @@ endif(ENABLE_REDIS) find_package(SQLite3 REQUIRED) +OPTION(ENABLE_PROMETHEUS "Enable prometheus client support" FALSE) +set(USE_PROMETHEUS FALSE) + +if(ENABLE_PROMETHEUS) + find_path(PROMETHEUS_CPP_INCLUDE_DIR NAMES prometheus/counter.h) + find_library(PROMETHEUS_PULL_LIBRARY NAMES prometheus-cpp-pull) + find_library(PROMETHEUS_CORE_LIBRARY NAMES prometheus-cpp-core) + if(PROMETHEUS_CPP_INCLUDE_DIR AND PROMETHEUS_PULL_LIBRARY AND PROMETHEUS_CORE_LIBRARY) + set(PROMETHEUS_LIBRARIES ${PROMETHEUS_PULL_LIBRARY} ${PROMETHEUS_CORE_LIBRARY}) + set(USE_PROMETHEUS TRUE) + include_directories(${PROMETHEUS_CPP_INCLUDE_DIR}) + endif(PROMETHEUS_CPP_INCLUDE_DIR AND PROMETHEUS_PULL_LIBRARY AND PROMETHEUS_CORE_LIBRARY) +endif(ENABLE_PROMETHEUS) + +if(USE_PROMETHEUS) + message(STATUS "Prometheus client enabled.") +else(USE_PROMETHEUS) + message(STATUS "Prometheus client disabled.") +endif(USE_PROMETHEUS) + OPTION(ENABLE_SPATIAL "Enable SpatialIndex AreaStore backend" TRUE) set(USE_SPATIAL FALSE) @@ -597,6 +617,9 @@ if(BUILD_CLIENT) if (USE_REDIS) target_link_libraries(${PROJECT_NAME} ${REDIS_LIBRARY}) endif() + if (USE_PROMETHEUS) + target_link_libraries(${PROJECT_NAME} ${PROMETHEUS_LIBRARIES}) + endif() if (USE_SPATIAL) target_link_libraries(${PROJECT_NAME} ${SPATIAL_LIBRARY}) endif() @@ -632,6 +655,9 @@ if(BUILD_SERVER) if (USE_REDIS) target_link_libraries(${PROJECT_NAME}server ${REDIS_LIBRARY}) endif() + if (USE_PROMETHEUS) + target_link_libraries(${PROJECT_NAME}server ${PROMETHEUS_LIBRARIES}) + endif() if (USE_SPATIAL) target_link_libraries(${PROJECT_NAME}server ${SPATIAL_LIBRARY}) endif() diff --git a/src/cmake_config.h.in b/src/cmake_config.h.in index cac6335d4..cfcee4b58 100644 --- a/src/cmake_config.h.in +++ b/src/cmake_config.h.in @@ -23,6 +23,7 @@ #cmakedefine01 USE_LEVELDB #cmakedefine01 USE_LUAJIT #cmakedefine01 USE_POSTGRESQL +#cmakedefine01 USE_PROMETHEUS #cmakedefine01 USE_SPATIAL #cmakedefine01 USE_SYSTEM_GMP #cmakedefine01 USE_REDIS diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index b6b1ce1f2..06daa3b94 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -334,6 +334,9 @@ void set_default_settings(Settings *settings) // Server settings->setDefault("disable_escape_sequences", "false"); settings->setDefault("strip_color_codes", "false"); +#if USE_PROMETHEUS + settings->setDefault("prometheus_listener_address", "127.0.0.1:30000"); +#endif // Network settings->setDefault("enable_ipv6", "true"); diff --git a/src/map.cpp b/src/map.cpp index 12e122124..5f1b984a4 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -144,7 +144,7 @@ bool Map::isNodeUnderground(v3s16 p) { v3s16 blockpos = getNodeBlockPos(p); MapBlock *block = getBlockNoCreateNoEx(blockpos); - return block && block->getIsUnderground(); + return block && block->getIsUnderground(); } bool Map::isValidPosition(v3s16 p) @@ -1187,7 +1187,7 @@ bool Map::isBlockOccluded(MapBlock *block, v3s16 cam_pos_nodes) ServerMap */ ServerMap::ServerMap(const std::string &savedir, IGameDef *gamedef, - EmergeManager *emerge): + EmergeManager *emerge, MetricsBackend *mb): Map(dout_server, gamedef), settings_mgr(g_settings, savedir + DIR_DELIM + "map_meta.txt"), m_emerge(emerge) @@ -1221,6 +1221,8 @@ ServerMap::ServerMap(const std::string &savedir, IGameDef *gamedef, m_savedir = savedir; m_map_saving_enabled = false; + m_save_time_counter = mb->addCounter("minetest_core_map_save_time", "Map save time (in nanoseconds)"); + try { // If directory exists, check contents and load if possible if (fs::PathExists(m_savedir)) { @@ -1777,6 +1779,8 @@ void ServerMap::save(ModifiedState save_level) return; } + u64 start_time = porting::getTimeNs(); + if(save_level == MOD_STATE_CLEAN) infostream<<"ServerMap: Saving whole map, this can take time." <increment(end_time - start_time); } void ServerMap::listAllLoadableBlocks(std::vector &dst) diff --git a/src/map.h b/src/map.h index ff6b20c4f..77ee4da9e 100644 --- a/src/map.h +++ b/src/map.h @@ -31,6 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "voxel.h" #include "modifiedstate.h" #include "util/container.h" +#include "util/metricsbackend.h" #include "nodetimer.h" #include "map_settings_manager.h" #include "debug.h" @@ -45,6 +46,7 @@ class NodeMetadata; class IGameDef; class IRollbackManager; class EmergeManager; +class MetricsBackend; class ServerEnvironment; struct BlockMakeData; @@ -324,7 +326,7 @@ public: /* savedir: directory to which map data should be saved */ - ServerMap(const std::string &savedir, IGameDef *gamedef, EmergeManager *emerge); + ServerMap(const std::string &savedir, IGameDef *gamedef, EmergeManager *emerge, MetricsBackend *mb); ~ServerMap(); s32 mapType() const @@ -449,6 +451,8 @@ private: bool m_map_metadata_changed = true; MapDatabase *dbase = nullptr; MapDatabase *dbase_ro = nullptr; + + MetricCounterPtr m_save_time_counter; }; diff --git a/src/server.cpp b/src/server.cpp index af6d3e40d..a7eb52837 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -229,18 +229,46 @@ Server::Server( m_nodedef(createNodeDefManager()), m_craftdef(createCraftDefManager()), m_thread(new ServerThread(this)), - m_uptime(0), m_clients(m_con), m_admin_chat(iface), m_modchannel_mgr(new ModChannelMgr()) { - m_lag = g_settings->getFloat("dedicated_server_step"); - if (m_path_world.empty()) throw ServerError("Supplied empty world path"); if (!gamespec.isValid()) throw ServerError("Supplied invalid gamespec"); + +#if USE_PROMETHEUS + m_metrics_backend = std::unique_ptr(createPrometheusMetricsBackend()); +#else + m_metrics_backend = std::unique_ptr(new MetricsBackend()); +#endif + + m_uptime_counter = m_metrics_backend->addCounter("minetest_core_server_uptime", "Server uptime (in seconds)"); + m_player_gauge = m_metrics_backend->addGauge("minetest_core_player_number", "Number of connected players"); + + m_timeofday_gauge = m_metrics_backend->addGauge( + "minetest_core_timeofday", + "Time of day value"); + + m_lag_gauge = m_metrics_backend->addGauge( + "minetest_core_latency", + "Latency value (in seconds)"); + + m_aom_buffer_counter = m_metrics_backend->addCounter( + "minetest_core_aom_generated_count", + "Number of active object messages generated"); + + m_packet_recv_counter = m_metrics_backend->addCounter( + "minetest_core_server_packet_recv", + "Processable packets received"); + + m_packet_recv_processed_counter = m_metrics_backend->addCounter( + "minetest_core_server_packet_recv_processed", + "Valid received packets processed"); + + m_lag_gauge->set(g_settings->getFloat("dedicated_server_step")); } Server::~Server() @@ -353,7 +381,7 @@ void Server::init() MutexAutoLock envlock(m_env_mutex); // Create the Map (loads map_meta.txt, overriding configured mapgen params) - ServerMap *servermap = new ServerMap(m_path_world, this, m_emerge); + ServerMap *servermap = new ServerMap(m_path_world, this, m_emerge, m_metrics_backend.get()); // Initialize scripting infostream << "Server: Initializing Lua" << std::endl; @@ -511,9 +539,7 @@ void Server::AsyncRunStep(bool initial_step) /* Update uptime */ - { - m_uptime.set(m_uptime.get() + dtime); - } + m_uptime_counter->increment(dtime); handlePeerChanges(); @@ -527,11 +553,13 @@ void Server::AsyncRunStep(bool initial_step) */ m_time_of_day_send_timer -= dtime; - if(m_time_of_day_send_timer < 0.0) { + if (m_time_of_day_send_timer < 0.0) { m_time_of_day_send_timer = g_settings->getFloat("time_send_interval"); u16 time = m_env->getTimeOfDay(); float time_speed = g_settings->getFloat("time_speed"); SendTimeOfDay(PEER_ID_INEXISTENT, time, time_speed); + + m_timeofday_gauge->set(time); } { @@ -603,7 +631,7 @@ void Server::AsyncRunStep(bool initial_step) } m_clients.step(dtime); - m_lag += (m_lag > dtime ? -1 : 1) * dtime/100; + m_lag_gauge->increment((m_lag_gauge->get() > dtime ? -1 : 1) * dtime/100); #if USE_CURL // send masterserver announce { @@ -614,9 +642,9 @@ void Server::AsyncRunStep(bool initial_step) ServerList::AA_START, m_bind_addr.getPort(), m_clients.getPlayerNames(), - m_uptime.get(), + m_uptime_counter->get(), m_env->getGameTime(), - m_lag, + m_lag_gauge->get(), m_gamespec.id, Mapgen::getMapgenName(m_emerge->mgparams->mgtype), m_modmgr->getMods(), @@ -638,6 +666,7 @@ void Server::AsyncRunStep(bool initial_step) const RemoteClientMap &clients = m_clients.getClientList(); ScopeProfiler sp(g_profiler, "Server: update objects within range"); + m_player_gauge->set(clients.size()); for (const auto &client_it : clients) { RemoteClient *client = client_it.second; @@ -703,6 +732,8 @@ void Server::AsyncRunStep(bool initial_step) message_list->push_back(aom); } + m_aom_buffer_counter->increment(buffered_messages.size()); + m_clients.lock(); const RemoteClientMap &clients = m_clients.getClientList(); // Route data to every client @@ -943,7 +974,9 @@ void Server::Receive() } peer_id = pkt.getPeerId(); + m_packet_recv_counter->increment(); ProcessData(&pkt); + m_packet_recv_processed_counter->increment(); } catch (const con::InvalidIncomingDataException &e) { infostream << "Server::Receive(): InvalidIncomingDataException: what()=" << e.what() << std::endl; @@ -3127,7 +3160,7 @@ std::wstring Server::getStatusString() // Version os << L"version=" << narrow_to_wide(g_version_string); // Uptime - os << L", uptime=" << m_uptime.get(); + os << L", uptime=" << m_uptime_counter->get(); // Max lag estimate os << L", max_lag=" << (m_env ? m_env->getMaxLagEstimate() : 0); diff --git a/src/server.h b/src/server.h index b995aba28..71059dd30 100644 --- a/src/server.h +++ b/src/server.h @@ -33,6 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "util/numeric.h" #include "util/thread.h" #include "util/basic_macros.h" +#include "util/metricsbackend.h" #include "serverenvironment.h" #include "clientiface.h" #include "chatmessage.h" @@ -203,7 +204,7 @@ public: // Connection must be locked when called std::wstring getStatusString(); - inline double getUptime() const { return m_uptime.m_value; } + inline double getUptime() const { return m_uptime_counter->get(); } // read shutdown state inline bool isShutdownRequested() const { return m_shutdown_state.is_requested; } @@ -591,9 +592,6 @@ private: float m_step_dtime = 0.0f; std::mutex m_step_dtime_mutex; - // current server step lag counter - float m_lag; - // The server mainly operates in this thread ServerThread *m_thread = nullptr; @@ -602,8 +600,6 @@ private: */ // Timer for sending time of day over network float m_time_of_day_send_timer = 0.0f; - // Uptime of server in seconds - MutexedVariable m_uptime; /* Client interface @@ -677,6 +673,19 @@ private: // ModChannel manager std::unique_ptr m_modchannel_mgr; + + // Global server metrics backend + std::unique_ptr m_metrics_backend; + + // Server metrics + MetricCounterPtr m_uptime_counter; + MetricGaugePtr m_player_gauge; + MetricGaugePtr m_timeofday_gauge; + // current server step lag + MetricGaugePtr m_lag_gauge; + MetricCounterPtr m_aom_buffer_counter; + MetricCounterPtr m_packet_recv_counter; + MetricCounterPtr m_packet_recv_processed_counter; }; /* diff --git a/src/server/mods.cpp b/src/server/mods.cpp index c8d8a28e2..6ac530739 100644 --- a/src/server/mods.cpp +++ b/src/server/mods.cpp @@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "scripting_server.h" #include "content/subgames.h" #include "porting.h" +#include "util/metricsbackend.h" /** * Manage server mods diff --git a/src/server/mods.h b/src/server/mods.h index 2bc1aa22f..54774bd86 100644 --- a/src/server/mods.h +++ b/src/server/mods.h @@ -20,7 +20,10 @@ with this program; if not, write to the Free Software Foundation, Inc., #pragma once #include "content/mods.h" +#include +class MetricsBackend; +class MetricCounter; class ServerScripting; /** diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index 199d3aeaa..cd2e468d1 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -5,6 +5,7 @@ set(UTIL_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/directiontables.cpp ${CMAKE_CURRENT_SOURCE_DIR}/enriched_string.cpp ${CMAKE_CURRENT_SOURCE_DIR}/ieee_float.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/metricsbackend.cpp ${CMAKE_CURRENT_SOURCE_DIR}/numeric.cpp ${CMAKE_CURRENT_SOURCE_DIR}/pointedthing.cpp ${CMAKE_CURRENT_SOURCE_DIR}/quicktune.cpp diff --git a/src/util/metricsbackend.cpp b/src/util/metricsbackend.cpp new file mode 100644 index 000000000..4454557a3 --- /dev/null +++ b/src/util/metricsbackend.cpp @@ -0,0 +1,140 @@ +/* +Minetest +Copyright (C) 2013-2020 Minetest core developers team + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "metricsbackend.h" +#if USE_PROMETHEUS +#include +#include +#include +#include +#include "log.h" +#include "settings.h" +#endif + +MetricCounterPtr MetricsBackend::addCounter( + const std::string &name, const std::string &help_str) +{ + return std::make_shared(name, help_str); +} + +MetricGaugePtr MetricsBackend::addGauge( + const std::string &name, const std::string &help_str) +{ + return std::make_shared(name, help_str); +} + +#if USE_PROMETHEUS + +class PrometheusMetricCounter : public MetricCounter +{ +public: + PrometheusMetricCounter() = delete; + + PrometheusMetricCounter(const std::string &name, const std::string &help_str, + std::shared_ptr registry) : + MetricCounter(), + m_family(prometheus::BuildCounter() + .Name(name) + .Help(help_str) + .Register(*registry)), + m_counter(m_family.Add({})) + { + } + + virtual ~PrometheusMetricCounter() {} + + virtual void increment(double number) { m_counter.Increment(number); } + virtual double get() const { return m_counter.Value(); } + +private: + prometheus::Family &m_family; + prometheus::Counter &m_counter; +}; + +class PrometheusMetricGauge : public MetricGauge +{ +public: + PrometheusMetricGauge() = delete; + + PrometheusMetricGauge(const std::string &name, const std::string &help_str, + std::shared_ptr registry) : + MetricGauge(), + m_family(prometheus::BuildGauge() + .Name(name) + .Help(help_str) + .Register(*registry)), + m_gauge(m_family.Add({})) + { + } + + virtual ~PrometheusMetricGauge() {} + + virtual void increment(double number) { m_gauge.Increment(number); } + virtual void decrement(double number) { m_gauge.Decrement(number); } + virtual void set(double number) { m_gauge.Set(number); } + virtual double get() const { return m_gauge.Value(); } + +private: + prometheus::Family &m_family; + prometheus::Gauge &m_gauge; +}; + +class PrometheusMetricsBackend : public MetricsBackend +{ +public: + PrometheusMetricsBackend(const std::string &addr) : + MetricsBackend(), m_exposer(std::unique_ptr( + new prometheus::Exposer(addr))), + m_registry(std::make_shared()) + { + m_exposer->RegisterCollectable(m_registry); + } + + virtual ~PrometheusMetricsBackend() {} + + virtual MetricCounterPtr addCounter( + const std::string &name, const std::string &help_str); + virtual MetricGaugePtr addGauge( + const std::string &name, const std::string &help_str); + +private: + std::unique_ptr m_exposer; + std::shared_ptr m_registry; +}; + +MetricCounterPtr PrometheusMetricsBackend::addCounter( + const std::string &name, const std::string &help_str) +{ + return std::make_shared(name, help_str, m_registry); +} + +MetricGaugePtr PrometheusMetricsBackend::addGauge( + const std::string &name, const std::string &help_str) +{ + return std::make_shared(name, help_str, m_registry); +} + +MetricsBackend *createPrometheusMetricsBackend() +{ + std::string addr; + g_settings->getNoEx("prometheus_listener_address", addr); + return new PrometheusMetricsBackend(addr); +} + +#endif diff --git a/src/util/metricsbackend.h b/src/util/metricsbackend.h new file mode 100644 index 000000000..c37306392 --- /dev/null +++ b/src/util/metricsbackend.h @@ -0,0 +1,140 @@ +/* +Minetest +Copyright (C) 2013-2020 Minetest core developers team + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once +#include +#include "config.h" +#include "util/thread.h" + +class MetricCounter +{ +public: + MetricCounter() = default; + + virtual ~MetricCounter() {} + + virtual void increment(double number = 1.0) = 0; + virtual double get() const = 0; +}; + +typedef std::shared_ptr MetricCounterPtr; + +class SimpleMetricCounter : public MetricCounter +{ +public: + SimpleMetricCounter() = delete; + + virtual ~SimpleMetricCounter() {} + + SimpleMetricCounter(const std::string &name, const std::string &help_str) : + MetricCounter(), m_name(name), m_help_str(help_str), + m_counter(0.0) + { + } + + virtual void increment(double number) + { + MutexAutoLock lock(m_mutex); + m_counter += number; + } + virtual double get() const + { + MutexAutoLock lock(m_mutex); + return m_counter; + } + +private: + std::string m_name; + std::string m_help_str; + + mutable std::mutex m_mutex; + double m_counter; +}; + +class MetricGauge +{ +public: + MetricGauge() = default; + virtual ~MetricGauge() {} + + virtual void increment(double number = 1.0) = 0; + virtual void decrement(double number = 1.0) = 0; + virtual void set(double number) = 0; + virtual double get() const = 0; +}; + +typedef std::shared_ptr MetricGaugePtr; + +class SimpleMetricGauge : public MetricGauge +{ +public: + SimpleMetricGauge() = delete; + + SimpleMetricGauge(const std::string &name, const std::string &help_str) : + MetricGauge(), m_name(name), m_help_str(help_str), m_gauge(0.0) + { + } + + virtual ~SimpleMetricGauge() {} + + virtual void increment(double number) + { + MutexAutoLock lock(m_mutex); + m_gauge += number; + } + virtual void decrement(double number) + { + MutexAutoLock lock(m_mutex); + m_gauge -= number; + } + virtual void set(double number) + { + MutexAutoLock lock(m_mutex); + m_gauge = number; + } + virtual double get() const + { + MutexAutoLock lock(m_mutex); + return m_gauge; + } + +private: + std::string m_name; + std::string m_help_str; + + mutable std::mutex m_mutex; + double m_gauge; +}; + +class MetricsBackend +{ +public: + MetricsBackend() = default; + + virtual ~MetricsBackend() {} + + virtual MetricCounterPtr addCounter( + const std::string &name, const std::string &help_str); + virtual MetricGaugePtr addGauge( + const std::string &name, const std::string &help_str); +}; + +#if USE_PROMETHEUS +MetricsBackend *createPrometheusMetricsBackend(); +#endif diff --git a/util/ci/build_prometheus_cpp.sh b/util/ci/build_prometheus_cpp.sh new file mode 100755 index 000000000..edfd574cd --- /dev/null +++ b/util/ci/build_prometheus_cpp.sh @@ -0,0 +1,13 @@ +#! /bin/bash -eu + +cd /tmp +git clone --recursive https://github.com/jupp0r/prometheus-cpp +mkdir prometheus-cpp/build +cd prometheus-cpp/build +cmake .. \ + -DCMAKE_INSTALL_PREFIX=/usr/local \ + -DCMAKE_BUILD_TYPE=Release \ + -DENABLE_TESTING=0 +make -j2 +sudo make install + -- cgit v1.2.3 From 66c182531cf7ef06c98a25b4e12db770314bdc91 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Mon, 4 May 2020 08:45:31 +0200 Subject: Change default keys for cam/minimap to C/V (#9779) --- README.md | 6 +++--- builtin/settingtypes.txt | 4 ++-- src/defaultsettings.cpp | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src/defaultsettings.cpp') diff --git a/README.md b/README.md index 024e7b691..202ba4fe2 100644 --- a/README.md +++ b/README.md @@ -69,15 +69,15 @@ Some can be changed in the key config dialog in the settings tab. | J | Enable/disable fast mode (needs fast privilege) | | H | Enable/disable noclip mode (needs noclip privilege) | | E | Move fast in fast mode | +| C | Cycle through camera modes | +| V | Cycle through minimap modes | +| Shift + V | Change minimap orientation | | F1 | Hide/show HUD | | F2 | Hide/show chat | | F3 | Disable/enable fog | | F4 | Disable/enable camera update (Mapblocks are not updated anymore when disabled, disabled in release builds) | | F5 | Cycle through debug information screens | | F6 | Cycle through profiler info screens | -| F7 | Cycle through camera modes | -| F9 | Cycle through minimap modes | -| Shift + F9 | Change minimap orientation | | F10 | Show/hide console | | F12 | Take screenshot | diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index 165ed8c06..c983fb436 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -252,7 +252,7 @@ keymap_cinematic (Cinematic mode key) key # Key for toggling display of minimap. # See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 -keymap_minimap (Minimap key) key KEY_F9 +keymap_minimap (Minimap key) key KEY_KEY_V # Key for taking screenshots. # See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 @@ -424,7 +424,7 @@ keymap_toggle_profiler (Profiler toggle key) key KEY_F6 # Key for switching between first- and third-person camera. # See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 -keymap_camera_mode (Toggle camera mode key) key KEY_F7 +keymap_camera_mode (Toggle camera mode key) key KEY_KEY_C # Key for increasing the viewing range. # See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 06daa3b94..33654e213 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -80,7 +80,7 @@ void set_default_settings(Settings *settings) settings->setDefault("keymap_chat", "KEY_KEY_T"); settings->setDefault("keymap_cmd", "/"); settings->setDefault("keymap_cmd_local", "."); - settings->setDefault("keymap_minimap", "KEY_F9"); + settings->setDefault("keymap_minimap", "KEY_KEY_V"); settings->setDefault("keymap_console", "KEY_F10"); settings->setDefault("keymap_rangeselect", "KEY_KEY_R"); settings->setDefault("keymap_freemove", "KEY_KEY_K"); @@ -103,7 +103,7 @@ void set_default_settings(Settings *settings) #endif settings->setDefault("keymap_toggle_debug", "KEY_F5"); settings->setDefault("keymap_toggle_profiler", "KEY_F6"); - settings->setDefault("keymap_camera_mode", "KEY_F7"); + settings->setDefault("keymap_camera_mode", "KEY_KEY_C"); settings->setDefault("keymap_screenshot", "KEY_F12"); settings->setDefault("keymap_increase_viewing_range_min", "+"); settings->setDefault("keymap_decrease_viewing_range_min", "-"); -- cgit v1.2.3 From 836dd4a1e4f97411519578cd9e59b6dbe3b2c00d Mon Sep 17 00:00:00 2001 From: SmallJoker Date: Thu, 14 May 2020 19:26:15 +0200 Subject: Add chat_log_level setting (#9223) Log all higher levels in LogOutputBuffer Move StreamLogOutput::logRaw to source file like LogOutputBuffer::logRaw for compiling speed --- builtin/settingtypes.txt | 3 ++ src/client/game.cpp | 16 ++++------- src/defaultsettings.cpp | 1 + src/log.cpp | 74 ++++++++++++++++++++++++++++++++++++++++++++++++ src/log.h | 52 ++++++++-------------------------- 5 files changed, 95 insertions(+), 51 deletions(-) (limited to 'src/defaultsettings.cpp') 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(); } -- cgit v1.2.3 From a9b74f4c3966ad38c2f9a97364d3fdda0e514c93 Mon Sep 17 00:00:00 2001 From: SmallJoker Date: Sun, 24 May 2020 14:24:13 +0200 Subject: Add chat_font_size setting (#9736) Default font sizes are used when the setting value is 0 or below (clamped by Settings). --- builtin/settingtypes.txt | 4 ++++ src/client/gameui.cpp | 23 +++++++++++++---------- src/defaultsettings.cpp | 4 ++++ src/gui/guiChatConsole.cpp | 4 +++- 4 files changed, 24 insertions(+), 11 deletions(-) (limited to 'src/defaultsettings.cpp') diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index e18de3382..c787aea2c 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -903,6 +903,10 @@ fallback_font_shadow_alpha (Fallback font shadow alpha) int 128 0 255 # This font will be used for certain languages or if the default font is unavailable. fallback_font_path (Fallback font path) filepath fonts/DroidSansFallbackFull.ttf +# Font size of the recent chat text and chat prompt in point (pt). +# Value 0 will use the default font size. +chat_font_size (Chat font size) int 0 + # Path to save screenshots at. Can be an absolute or relative path. # The folder will be created if it doesn't already exist. screenshot_path (Screenshot folder) path screenshots diff --git a/src/client/gameui.cpp b/src/client/gameui.cpp index bbe7caeb1..c216f405d 100644 --- a/src/client/gameui.cpp +++ b/src/client/gameui.cpp @@ -76,6 +76,11 @@ void GameUI::init() m_guitext_chat = gui::StaticText::add(guienv, L"", core::rect(0, 0, 0, 0), //false, false); // Disable word wrap as of now false, true, guiroot); + u16 chat_font_size = g_settings->getU16("chat_font_size"); + if (chat_font_size != 0) { + m_guitext_chat->setOverrideFont(g_fontengine->getFont( + chat_font_size, FM_Unspecified)); + } // Profiler text (size is updated when text is updated) m_guitext_profiler = gui::StaticText::add(guienv, L"", @@ -213,7 +218,6 @@ void GameUI::showTranslatedStatusText(const char *str) void GameUI::setChatText(const EnrichedString &chat_text, u32 recent_chat_count) { - setStaticText(m_guitext_chat, chat_text); // Update gui element size and position s32 chat_y = 5; @@ -221,16 +225,15 @@ void GameUI::setChatText(const EnrichedString &chat_text, u32 recent_chat_count) if (m_flags.show_debug) chat_y += 2 * g_fontengine->getLineHeight(); - // first pass to calculate height of text to be set const v2u32 &window_size = RenderingEngine::get_instance()->getWindowSize(); - s32 width = std::min(g_fontengine->getTextWidth(chat_text.c_str()) + 10, - window_size.X - 20); - m_guitext_chat->setRelativePosition(core::rect(10, chat_y, width, - chat_y + window_size.Y)); - - // now use real height of text and adjust rect according to this size - m_guitext_chat->setRelativePosition(core::rect(10, chat_y, width, - chat_y + m_guitext_chat->getTextHeight())); + + core::rect chat_size(10, chat_y, + window_size.X - 20, 0); + chat_size.LowerRightCorner.Y = std::min((s32)window_size.Y, + m_guitext_chat->getTextHeight() + chat_y); + + m_guitext_chat->setRelativePosition(chat_size); + setStaticText(m_guitext_chat, chat_text); m_recent_chat_count = recent_chat_count; } diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 1d0610c0f..5d1795003 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -321,8 +321,12 @@ void set_default_settings(Settings *settings) std::string font_size_str = std::to_string(DEFAULT_FONT_SIZE); #endif + // General font settings settings->setDefault("font_size", font_size_str); settings->setDefault("mono_font_size", font_size_str); + settings->setDefault("chat_font_size", "0"); // Default "font_size" + + // ContentDB settings->setDefault("contentdb_url", "https://content.minetest.net"); #ifdef __ANDROID__ settings->setDefault("contentdb_flag_blacklist", "nonfree, android_default"); diff --git a/src/gui/guiChatConsole.cpp b/src/gui/guiChatConsole.cpp index e67fae3c6..8de00c12f 100644 --- a/src/gui/guiChatConsole.cpp +++ b/src/gui/guiChatConsole.cpp @@ -74,7 +74,9 @@ GUIChatConsole::GUIChatConsole( m_background_color.setBlue(clamp_u8(myround(console_color.Z))); } - m_font = g_fontengine->getFont(FONT_SIZE_UNSPECIFIED, FM_Mono); + u16 chat_font_size = g_settings->getU16("chat_font_size"); + m_font = g_fontengine->getFont(chat_font_size != 0 ? + chat_font_size : FONT_SIZE_UNSPECIFIED, FM_Mono); if (!m_font) { errorstream << "GUIChatConsole: Unable to load mono font" << std::endl; -- cgit v1.2.3 From a2199bf62232707e96ece031a00b320d30e34445 Mon Sep 17 00:00:00 2001 From: Maksim Date: Sat, 20 Jun 2020 12:06:30 +0200 Subject: Android: fix TMPFolder path (#10052) --- src/defaultsettings.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'src/defaultsettings.cpp') diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 5d1795003..abb6593b7 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -451,6 +451,7 @@ void set_default_settings(Settings *settings) settings->setDefault("high_precision_fpu", "true"); settings->setDefault("enable_console", "false"); + settings->setDefault("screen_dpi", "72"); // Altered settings for macOS #if defined(__MACH__) && defined(__APPLE__) @@ -464,7 +465,7 @@ void set_default_settings(Settings *settings) settings->setDefault("screen_h", "0"); settings->setDefault("fullscreen", "true"); settings->setDefault("touchtarget", "true"); - settings->setDefault("TMPFolder", porting::getDataPath("tmp" DIR_DELIM)); + settings->setDefault("TMPFolder", porting::path_cache); settings->setDefault("touchscreen_threshold","20"); settings->setDefault("fixed_virtual_joystick", "false"); settings->setDefault("virtual_joystick_triggers_aux", "false"); @@ -486,8 +487,8 @@ void set_default_settings(Settings *settings) settings->setDefault("curl_verify_cert","false"); // Apply settings according to screen size - float x_inches = ((double) porting::getDisplaySize().X / - (160 * porting::getDisplayDensity())); + float x_inches = (float) porting::getDisplaySize().X / + (160.f * porting::getDisplayDensity()); if (x_inches < 3.7f) { settings->setDefault("hud_scaling", "0.6"); @@ -503,8 +504,5 @@ void set_default_settings(Settings *settings) settings->setDefault("mono_font_size", "14"); } // Tablets >= 6.0 use non-Android defaults for these settings -#else - settings->setDefault("screen_dpi", "72"); #endif } - -- cgit v1.2.3 From 88ffd641243ead70d82623d54822421c72893240 Mon Sep 17 00:00:00 2001 From: LoneWolfHT Date: Tue, 14 Jul 2020 10:12:17 -0700 Subject: Add object crosshair, disable entity selectionboxes by default (#9523) Adds new object crosshair base pack texture --- builtin/settingtypes.txt | 5 ++++- doc/texture_packs.txt | 7 ++++++- minetest.conf.example | 4 ++-- src/client/game.cpp | 3 +++ src/client/hud.cpp | 39 ++++++++++++++++++++++++++++++++++----- src/client/hud.h | 4 ++++ src/client/render/core.cpp | 1 + src/defaultsettings.cpp | 2 +- 8 files changed, 55 insertions(+), 10 deletions(-) (limited to 'src/defaultsettings.cpp') diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index c787aea2c..c0620542d 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -741,9 +741,11 @@ selectionbox_color (Selection box color) string (0,0,0) selectionbox_width (Selection box width) int 2 1 5 # Crosshair color (R,G,B). +# Also controls the object crosshair color crosshair_color (Crosshair color) string (255,255,255) # Crosshair alpha (opaqueness, between 0 and 255). +# Also controls the object crosshair color crosshair_alpha (Crosshair alpha) int 255 0 255 # Maximum number of recent chat messages to show @@ -817,7 +819,8 @@ world_aligned_mode (World-aligned textures mode) enum enable disable,enable,forc autoscale_mode (Autoscaling mode) enum disable disable,enable,force # Show entity selection boxes -show_entity_selectionbox (Show entity selection boxes) bool true +# A restart is required after changing this. +show_entity_selectionbox (Show entity selection boxes) bool false [*Menus] diff --git a/doc/texture_packs.txt b/doc/texture_packs.txt index 94151f1a4..e7a7dfd3c 100644 --- a/doc/texture_packs.txt +++ b/doc/texture_packs.txt @@ -72,7 +72,12 @@ by texture packs. All existing fallback textures can be found in the directory * `crosshair.png` * the crosshair texture in the center of the screen. The settings `crosshair_color` and `crosshair_alpha` are used to create a cross - when no texture was found + when no texture is found. + +* `object_crosshair.png` + * the crosshair seen when pointing at an object. The settings + `crosshair_color` and `crosshair_alpha` are used to create a cross + when no texture is found. * `halo.png`: used for the node highlighting mesh diff --git a/minetest.conf.example b/minetest.conf.example index a5f98ee5e..520125713 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -955,8 +955,9 @@ # autoscale_mode = disable # Show entity selection boxes +# A restart is required after changing this. # type: bool -# show_entity_selectionbox = true +# show_entity_selectionbox = false ## Menus @@ -3374,4 +3375,3 @@ # so see a full list at https://content.minetest.net/help/content_flags/ # type: string # contentdb_flag_blacklist = nonfree, desktop_default - diff --git a/src/client/game.cpp b/src/client/game.cpp index 5f3ff5649..42d60b21c 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -3176,11 +3176,14 @@ PointedThing Game::updatePointedThing( const NodeDefManager *nodedef = map.getNodeDefManager(); runData.selected_object = NULL; + hud->pointing_at_object = false; RaycastState s(shootline, look_for_object, liquids_pointable); PointedThing result; env.continueRaycast(&s, &result); if (result.type == POINTEDTHING_OBJECT) { + hud->pointing_at_object = true; + runData.selected_object = client->getEnv().getActiveObject(result.object_id); aabb3f selection_box; if (show_entity_selectionbox && runData.selected_object->doShowSelectionBox() && diff --git a/src/client/hud.cpp b/src/client/hud.cpp index 31e633bc2..2b347c1e0 100644 --- a/src/client/hud.cpp +++ b/src/client/hud.cpp @@ -41,6 +41,9 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "gui/touchscreengui.h" #endif +#define OBJECT_CROSSHAIR_LINE_SIZE 8 +#define CROSSHAIR_LINE_SIZE 10 + Hud::Hud(gui::IGUIEnvironment *guienv, Client *client, LocalPlayer *player, Inventory *inventory) { @@ -76,6 +79,7 @@ Hud::Hud(gui::IGUIEnvironment *guienv, Client *client, LocalPlayer *player, selectionbox_argb = video::SColor(255, sbox_r, sbox_g, sbox_b); use_crosshair_image = tsrc->isKnownSourceImage("crosshair.png"); + use_object_crosshair_image = tsrc->isKnownSourceImage("object_crosshair.png"); m_selection_boxes.clear(); m_halo_boxes.clear(); @@ -601,6 +605,31 @@ void Hud::drawHotbar(u16 playeritem) { void Hud::drawCrosshair() { + if (pointing_at_object) { + if (use_object_crosshair_image) { + video::ITexture *object_crosshair = tsrc->getTexture("object_crosshair.png"); + v2u32 size = object_crosshair->getOriginalSize(); + v2s32 lsize = v2s32(m_displaycenter.X - (size.X / 2), + m_displaycenter.Y - (size.Y / 2)); + driver->draw2DImage(object_crosshair, lsize, + core::rect(0, 0, size.X, size.Y), + nullptr, crosshair_argb, true); + } else { + driver->draw2DLine( + m_displaycenter - v2s32(OBJECT_CROSSHAIR_LINE_SIZE, + OBJECT_CROSSHAIR_LINE_SIZE), + m_displaycenter + v2s32(OBJECT_CROSSHAIR_LINE_SIZE, + OBJECT_CROSSHAIR_LINE_SIZE), crosshair_argb); + driver->draw2DLine( + m_displaycenter + v2s32(OBJECT_CROSSHAIR_LINE_SIZE, + -OBJECT_CROSSHAIR_LINE_SIZE), + m_displaycenter + v2s32(-OBJECT_CROSSHAIR_LINE_SIZE, + OBJECT_CROSSHAIR_LINE_SIZE), crosshair_argb); + } + + return; + } + if (use_crosshair_image) { video::ITexture *crosshair = tsrc->getTexture("crosshair.png"); v2u32 size = crosshair->getOriginalSize(); @@ -608,12 +637,12 @@ void Hud::drawCrosshair() m_displaycenter.Y - (size.Y / 2)); driver->draw2DImage(crosshair, lsize, core::rect(0, 0, size.X, size.Y), - 0, crosshair_argb, true); + nullptr, crosshair_argb, true); } else { - driver->draw2DLine(m_displaycenter - v2s32(10, 0), - m_displaycenter + v2s32(10, 0), crosshair_argb); - driver->draw2DLine(m_displaycenter - v2s32(0, 10), - m_displaycenter + v2s32(0, 10), crosshair_argb); + driver->draw2DLine(m_displaycenter - v2s32(CROSSHAIR_LINE_SIZE, 0), + m_displaycenter + v2s32(CROSSHAIR_LINE_SIZE, 0), crosshair_argb); + driver->draw2DLine(m_displaycenter - v2s32(0, CROSSHAIR_LINE_SIZE), + m_displaycenter + v2s32(0, CROSSHAIR_LINE_SIZE), crosshair_argb); } } diff --git a/src/client/hud.h b/src/client/hud.h index 6f4c54626..ba34d479d 100644 --- a/src/client/hud.h +++ b/src/client/hud.h @@ -45,12 +45,16 @@ public: video::SColor crosshair_argb; video::SColor selectionbox_argb; + bool use_crosshair_image = false; + bool use_object_crosshair_image = false; std::string hotbar_image = ""; bool use_hotbar_image = false; std::string hotbar_selected_image = ""; bool use_hotbar_selected_image = false; + bool pointing_at_object = false; + Hud(gui::IGUIEnvironment *guienv, Client *client, LocalPlayer *player, Inventory *inventory); ~Hud(); diff --git a/src/client/render/core.cpp b/src/client/render/core.cpp index bf5aa6c2c..92a7137ea 100644 --- a/src/client/render/core.cpp +++ b/src/client/render/core.cpp @@ -86,6 +86,7 @@ void RenderingCore::drawHUD() if (show_hud) { if (draw_crosshair) hud->drawCrosshair(); + hud->drawHotbar(client->getEnv().getLocalPlayer()->getWieldIndex()); hud->drawLuaElements(camera->getOffset()); camera->drawNametags(); diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index abb6593b7..07bf0ebb8 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -225,7 +225,7 @@ void set_default_settings(Settings *settings) settings->setDefault("desynchronize_mapblock_texture_animation", "true"); settings->setDefault("hud_hotbar_max_width", "1.0"); settings->setDefault("enable_local_map_saving", "false"); - settings->setDefault("show_entity_selectionbox", "true"); + settings->setDefault("show_entity_selectionbox", "false"); settings->setDefault("texture_clean_transparent", "false"); settings->setDefault("texture_min_size", "64"); settings->setDefault("ambient_occlusion_gamma", "2.2"); -- cgit v1.2.3