From 178591b6d55cb87b3f5bd8ea748ad9bea0d90622 Mon Sep 17 00:00:00 2001 From: grorp Date: Thu, 9 May 2024 19:15:50 +0200 Subject: [PATCH 01/67] Android CI: Additionally make an AAB for uploading to the Play Store (#14584) --- .github/workflows/android.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index c59dd6732..040c19935 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -34,8 +34,17 @@ jobs: run: | sudo apt-get update sudo apt-get install -y --no-install-recommends gettext openjdk-11-jdk-headless - - name: Build with Gradle + - name: Build AAB with Gradle + # We build an AAB as well for uploading to the the Play Store. + run: cd android; ./gradlew bundlerelease + - name: Build APKs with Gradle + # "assemblerelease" is very fast after "bundlerelease". run: cd android; ./gradlew assemblerelease + - name: Save AAB artifact + uses: actions/upload-artifact@v4 + with: + name: Minetest-release.aab + path: android/app/build/outputs/bundle/release/app-release.aab - name: Save armeabi artifact uses: actions/upload-artifact@v4 with: From e0e1d0855d38701cfb8c4ff130e65db40b9a2d86 Mon Sep 17 00:00:00 2001 From: grorp Date: Thu, 9 May 2024 19:16:08 +0200 Subject: [PATCH 02/67] Close formspecs with a single tap outside (#14605) --- src/gui/guiFormSpecMenu.cpp | 9 +++ src/gui/modalMenu.cpp | 108 +++++++++++++++++++++--------------- src/gui/modalMenu.h | 28 ++++++---- 3 files changed, 90 insertions(+), 55 deletions(-) diff --git a/src/gui/guiFormSpecMenu.cpp b/src/gui/guiFormSpecMenu.cpp index 7ac391c83..577e2ee68 100644 --- a/src/gui/guiFormSpecMenu.cpp +++ b/src/gui/guiFormSpecMenu.cpp @@ -4740,6 +4740,8 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) list_selected->changeItem(m_selected_item->i, stack_from); } + bool absorb_event = false; + // Possibly send inventory action to server if (move_amount > 0) { // Send IAction::Move @@ -4882,6 +4884,10 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) a->from_i = m_selected_item->i; m_invmgr->inventoryAction(a); + // Formspecs usually close when you click outside them, we absorb + // the event to prevent that. See GUIModalMenu::remapClickOutside. + absorb_event = true; + } else if (craft_amount > 0) { assert(s.isValid()); @@ -4911,6 +4917,9 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) m_selected_dragging = false; } m_old_pointer = m_pointer; + + if (absorb_event) + return true; } if (event.EventType == EET_GUI_EVENT) { diff --git a/src/gui/modalMenu.cpp b/src/gui/modalMenu.cpp index bb287ecd1..d95311035 100644 --- a/src/gui/modalMenu.cpp +++ b/src/gui/modalMenu.cpp @@ -25,19 +25,39 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "client/renderingengine.h" #include "modalMenu.h" #include "gettext.h" +#include "gui/guiInventoryList.h" #include "porting.h" #include "settings.h" #include "touchscreengui.h" +PointerAction PointerAction::fromEvent(const SEvent &event) { + switch (event.EventType) { + case EET_MOUSE_INPUT_EVENT: + return {v2s32(event.MouseInput.X, event.MouseInput.Y), porting::getTimeMs()}; + case EET_TOUCH_INPUT_EVENT: + return {v2s32(event.TouchInput.X, event.TouchInput.Y), porting::getTimeMs()}; + default: + FATAL_ERROR("SEvent given to PointerAction::fromEvent has wrong EventType"); + } +} + +bool PointerAction::isRelated(PointerAction previous) { + u64 time_delta = porting::getDeltaMs(previous.time, time); + v2s32 pos_delta = pos - previous.pos; + f32 distance_sq = (f32)pos_delta.X * pos_delta.X + (f32)pos_delta.Y * pos_delta.Y; + + return time_delta < 400 && distance_sq < (30.0f * 30.0f); +} + GUIModalMenu::GUIModalMenu(gui::IGUIEnvironment* env, gui::IGUIElement* parent, - s32 id, IMenuManager *menumgr, bool remap_dbl_click) : + s32 id, IMenuManager *menumgr, bool remap_click_outside) : IGUIElement(gui::EGUIET_ELEMENT, env, parent, id, core::rect(0, 0, 100, 100)), #ifdef __ANDROID__ m_jni_field_name(""), #endif m_menumgr(menumgr), - m_remap_dbl_click(remap_dbl_click) + m_remap_click_outside(remap_click_outside) { m_gui_scale = std::max(g_settings->getFloat("gui_scaling"), 0.5f); const float screen_dpi_scale = RenderingEngine::getDisplayDensity(); @@ -50,9 +70,6 @@ GUIModalMenu::GUIModalMenu(gui::IGUIEnvironment* env, gui::IGUIElement* parent, setVisible(true); m_menumgr->createdMenu(this); - - m_last_touch.time = 0; - m_last_touch.pos = v2s32(0, 0); } GUIModalMenu::~GUIModalMenu() @@ -115,42 +132,53 @@ static bool isChild(gui::IGUIElement *tocheck, gui::IGUIElement *parent) return false; } -bool GUIModalMenu::remapDoubleClick(const SEvent &event) +bool GUIModalMenu::remapClickOutside(const SEvent &event) { - /* The following code is for capturing double-clicks of the mouse button - * and translating the double-click into an EET_KEY_INPUT_EVENT event - * -- which closes the form -- under some circumstances. - * - * There have been many github issues reporting this as a bug even though it - * was an intended feature. For this reason, remapping the double-click as - * an ESC must be explicitly set when creating this class via the - * /p remap_dbl_click parameter of the constructor. - */ - - if (!m_remap_dbl_click) + if (!m_remap_click_outside || event.EventType != EET_MOUSE_INPUT_EVENT || + (event.MouseInput.Event != EMIE_LMOUSE_PRESSED_DOWN && + event.MouseInput.Event != EMIE_LMOUSE_LEFT_UP)) return false; - if (event.EventType != EET_MOUSE_INPUT_EVENT || - event.MouseInput.Event != EMIE_LMOUSE_DOUBLE_CLICK) - return false; + // The formspec must only be closed if both the EMIE_LMOUSE_PRESSED_DOWN and + // the EMIE_LMOUSE_LEFT_UP event haven't been absorbed by something else. + + PointerAction last = m_last_click_outside; + m_last_click_outside = {}; // always reset + PointerAction current = PointerAction::fromEvent(event); - // Only exit if the double-click happened outside the menu. gui::IGUIElement *hovered = - Environment->getRootGUIElement()->getElementFromPoint(m_pointer); + Environment->getRootGUIElement()->getElementFromPoint(current.pos); if (isChild(hovered, this)) return false; - // Translate double-click to escape. - SEvent translated{}; - translated.EventType = EET_KEY_INPUT_EVENT; - translated.KeyInput.Key = KEY_ESCAPE; - translated.KeyInput.Control = false; - translated.KeyInput.Shift = false; - translated.KeyInput.PressedDown = true; - translated.KeyInput.Char = 0; - OnEvent(translated); + // Dropping items is also done by tapping outside the formspec. If an item + // is selected, make sure it is dropped without closing the formspec. + // We have to explicitly restrict this to GUIInventoryList because other + // GUI elements like text fields like to absorb events for no reason. + GUIInventoryList *focused = dynamic_cast(Environment->getFocus()); + if (focused && focused->OnEvent(event)) + // Return true since the event was handled, even if it wasn't handled by us. + return true; - return true; + if (event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN) { + m_last_click_outside = current; + return true; + } + + if (event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP && + current.isRelated(last)) { + SEvent translated{}; + translated.EventType = EET_KEY_INPUT_EVENT; + translated.KeyInput.Key = KEY_ESCAPE; + translated.KeyInput.Control = false; + translated.KeyInput.Shift = false; + translated.KeyInput.PressedDown = true; + translated.KeyInput.Char = 0; + OnEvent(translated); + return true; + } + + return false; } bool GUIModalMenu::simulateMouseEvent(ETOUCH_INPUT_EVENT touch_event, bool second_try) @@ -319,20 +347,12 @@ bool GUIModalMenu::preprocessEvent(const SEvent &event) // Detect double-taps and convert them into double-click events. if (event.TouchInput.Event == ETIE_PRESSED_DOWN) { - u64 time_now = porting::getTimeMs(); - u64 time_delta = porting::getDeltaMs(m_last_touch.time, time_now); - - v2s32 pos_delta = m_pointer - m_last_touch.pos; - f32 distance_sq = (f32)pos_delta.X * pos_delta.X + - (f32)pos_delta.Y * pos_delta.Y; - - if (time_delta < 400 && distance_sq < (30 * 30)) { + PointerAction current = PointerAction::fromEvent(event); + if (current.isRelated(m_last_touch)) { // ETIE_COUNT is used for double-tap events. simulateMouseEvent(ETIE_COUNT); } - - m_last_touch.time = time_now; - m_last_touch.pos = m_pointer; + m_last_touch = current; } return ret; @@ -361,7 +381,7 @@ bool GUIModalMenu::preprocessEvent(const SEvent &event) m_touch_hovered.reset(); } - if (remapDoubleClick(event)) + if (remapClickOutside(event)) return true; } diff --git a/src/gui/modalMenu.h b/src/gui/modalMenu.h index 9bb55ffec..7ee8531d0 100644 --- a/src/gui/modalMenu.h +++ b/src/gui/modalMenu.h @@ -31,6 +31,14 @@ enum class PointerType { Touch, }; +struct PointerAction { + v2s32 pos; + u64 time; // ms + + static PointerAction fromEvent(const SEvent &event); + bool isRelated(PointerAction other); +}; + class GUIModalMenu; class IMenuManager @@ -94,14 +102,14 @@ protected: private: IMenuManager *m_menumgr; - /* If true, remap a double-click (or double-tap) action to ESC. This is so - * that, for example, Android users can double-tap to close a formspec. - * - * This value can (currently) only be set by the class constructor - * and the default value for the setting is true. + /* If true, remap a click outside the formspec to ESC. This is so that, for + * example, touchscreen users can close formspecs. + * The default for this setting is true. Currently, it's set to false for + * the mainmenu to prevent Minetest from closing unexpectedly. */ - bool m_remap_dbl_click; - bool remapDoubleClick(const SEvent &event); + bool m_remap_click_outside; + bool remapClickOutside(const SEvent &event); + PointerAction m_last_click_outside{}; // This might be necessary to expose to the implementation if it // wants to launch other menus @@ -111,13 +119,11 @@ private: irr_ptr m_touch_hovered; + // Converts touches into clicks. bool simulateMouseEvent(ETOUCH_INPUT_EVENT touch_event, bool second_try=false); void enter(gui::IGUIElement *element); void leave(); // Used to detect double-taps and convert them into double-click events. - struct { - v2s32 pos; - s64 time; - } m_last_touch; + PointerAction m_last_touch{}; }; From 07fe8d4481cd8fd14ac34afefcbf642df73e4b83 Mon Sep 17 00:00:00 2001 From: Benjamin Wheeler <34549440+benjamin051000@users.noreply.github.com> Date: Fri, 10 May 2024 06:00:15 -0400 Subject: [PATCH 03/67] Dockerfile: Use the default branch when cloning libspatialindex repository (#14621) --- Dockerfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 701c0492a..39974a1c3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,6 @@ ARG DOCKER_IMAGE=alpine:3.19 FROM $DOCKER_IMAGE AS dev -ENV SPATIALINDEX_VERSION master ENV LUAJIT_VERSION v2.1 RUN apk add --no-cache git build-base cmake curl-dev zlib-dev zstd-dev \ @@ -19,7 +18,7 @@ RUN git clone --recursive https://github.com/jupp0r/prometheus-cpp && \ cmake --build build && \ cmake --install build && \ cd /usr/src/ && \ - git clone --recursive https://github.com/libspatialindex/libspatialindex -b ${SPATIALINDEX_VERSION} && \ + git clone --recursive https://github.com/libspatialindex/libspatialindex && \ cd libspatialindex && \ cmake -B build \ -DCMAKE_INSTALL_PREFIX=/usr/local && \ From a8af0c0ca47c91eea09cbc77b104411f5e22a513 Mon Sep 17 00:00:00 2001 From: grorp Date: Fri, 10 May 2024 18:54:22 +0200 Subject: [PATCH 04/67] Close buttonbars when hiding TouchScreenGUI (#14630) To open the inventory or the pause menu, you first need to open the buttonbar containing the respective button. Before this commit, the buttonbar is still open after closing the menu, so you have to tap twice before you can continue playing. After this commit, the buttonbar is already closed after closing the menu, so you only have to tap once before you can continue playing. --- src/gui/touchscreengui.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gui/touchscreengui.cpp b/src/gui/touchscreengui.cpp index 2a2fa36ed..2504c4eb5 100644 --- a/src/gui/touchscreengui.cpp +++ b/src/gui/touchscreengui.cpp @@ -857,8 +857,10 @@ void TouchScreenGUI::setVisible(bool visible) if (!visible) { while (!m_pointer_pos.empty()) handleReleaseEvent(m_pointer_pos.begin()->first); - for (AutoHideButtonBar &bar : m_buttonbars) + for (AutoHideButtonBar &bar : m_buttonbars) { + bar.deactivate(); bar.hide(); + } } else { for (AutoHideButtonBar &bar : m_buttonbars) bar.show(); From 57b6e74abb5a24cbe31e6770eb55551b74a28694 Mon Sep 17 00:00:00 2001 From: grorp Date: Sun, 12 May 2024 11:46:39 +0200 Subject: [PATCH 05/67] Fix crash if zip file cannot be opened (#14636) Helped-by: savilli <78875209+savilli@users.noreply.github.com> --- builtin/mainmenu/content/contentdb.lua | 4 +++- src/filesys.cpp | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/builtin/mainmenu/content/contentdb.lua b/builtin/mainmenu/content/contentdb.lua index eb06c8b61..849f7152d 100644 --- a/builtin/mainmenu/content/contentdb.lua +++ b/builtin/mainmenu/content/contentdb.lua @@ -71,7 +71,9 @@ local function download_and_extract(param) os.remove(filename) if tempfolder == "" then return { - msg = fgettext_ne("Failed to extract \"$1\" (unsupported file type or broken archive)", package.title), + msg = fgettext_ne("Failed to extract \"$1\" " .. + "(insufficient disk space, unsupported file type or broken archive)", + package.title), } end diff --git a/src/filesys.cpp b/src/filesys.cpp index 1ae7f57aa..f7a03617b 100644 --- a/src/filesys.cpp +++ b/src/filesys.cpp @@ -932,6 +932,8 @@ bool extractZipFile(io::IFileSystem *fs, const char *filename, const std::string } irr_ptr opened_zip(zip_loader->createArchive(filename, false, false)); + if (!opened_zip) + return false; const io::IFileList* files_in_zip = opened_zip->getFileList(); for (u32 i = 0; i < files_in_zip->getFileCount(); i++) { From 0889048cb5241856189f54bc20015065857129f9 Mon Sep 17 00:00:00 2001 From: chmodsayshello Date: Sun, 12 May 2024 14:20:18 +0200 Subject: [PATCH 06/67] Add option for random mod load order (#14637) --- builtin/settingtypes.txt | 3 +++ src/content/mod_configuration.cpp | 10 ++++++++++ src/defaultsettings.cpp | 5 +++++ 3 files changed, 18 insertions(+) diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index 11dfbf128..9c2199676 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -1761,6 +1761,9 @@ deprecated_lua_api_handling (Deprecated Lua API handling) enum log none,log,erro # Enable random user input (only used for testing). random_input (Random input) bool false +# Enable random mod loading (mainly used for testing). +random_mod_load_order (Random mod load order) bool false + # Enable mod channels support. enable_mod_channels (Mod channels) bool false diff --git a/src/content/mod_configuration.cpp b/src/content/mod_configuration.cpp index 9e0461f56..47ad3e0dc 100644 --- a/src/content/mod_configuration.cpp +++ b/src/content/mod_configuration.cpp @@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "filesys.h" #include "gettext.h" #include "exceptions.h" +#include "util/numeric.h" std::string ModConfiguration::getUnsatisfiedModsError() const @@ -226,6 +227,15 @@ void ModConfiguration::resolveDependencies() modnames.insert(mod.name); } + // Step 1.5 (optional): shuffle unsatisfied mods so non declared depends get found by their devs + if (g_settings->getBool("random_mod_load_order")) { + MyRandGenerator rg; + std::shuffle(m_unsatisfied_mods.begin(), + m_unsatisfied_mods.end(), + rg + ); + } + // Step 2: get dependencies (including optional dependencies) // of each mod, split mods into satisfied and unsatisfied std::vector satisfied; diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 3e62a79e5..0ea4051b4 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -419,6 +419,11 @@ void set_default_settings() // Server settings->setDefault("disable_escape_sequences", "false"); settings->setDefault("strip_color_codes", "false"); +#ifndef NDEBUG + settings->setDefault("random_mod_load_order", "true"); +#else + settings->setDefault("random_mod_load_order", "false"); +#endif #if USE_PROMETHEUS settings->setDefault("prometheus_listener_address", "127.0.0.1:30000"); #endif From 472742266bb61ff989b72695b52b2761adb8d877 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Sat, 11 May 2024 11:36:47 +0200 Subject: [PATCH 07/67] Fix invalid glDrawBuffer call on GLES closes #14445 --- irr/src/OpenGL/ExtensionHandler.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/irr/src/OpenGL/ExtensionHandler.h b/irr/src/OpenGL/ExtensionHandler.h index 8f96f0d4a..74c3e0b8a 100644 --- a/irr/src/OpenGL/ExtensionHandler.h +++ b/irr/src/OpenGL/ExtensionHandler.h @@ -138,7 +138,8 @@ public: inline void irrGlDrawBuffer(GLenum mode) { - GL.DrawBuffer(mode); + // GLES only has DrawBuffers, so use that + GL.DrawBuffers(1, &mode); } inline void irrGlDrawBuffers(GLsizei n, const GLenum *bufs) From 6303334cc2f39732697a1278532cbe66ed481da8 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Sat, 11 May 2024 11:37:23 +0200 Subject: [PATCH 08/67] Deduplicate GL extension detection --- irr/src/OpenGL/ExtensionHandler.cpp | 37 ++--------------------------- irr/src/OpenGL/ExtensionHandler.h | 14 ++++------- irr/src/OpenGL3/Driver.cpp | 2 +- irr/src/OpenGLES2/Driver.cpp | 5 +--- 4 files changed, 9 insertions(+), 49 deletions(-) diff --git a/irr/src/OpenGL/ExtensionHandler.cpp b/irr/src/OpenGL/ExtensionHandler.cpp index 3ac212987..3c248ba0a 100644 --- a/irr/src/OpenGL/ExtensionHandler.cpp +++ b/irr/src/OpenGL/ExtensionHandler.cpp @@ -12,47 +12,14 @@ #include "os.h" #include -// FIXME: this basically duplicates what mt_opengl.h already does - namespace irr { namespace video { -void COpenGL3ExtensionHandler::initExtensionsOld() -{ - auto extensions_string = reinterpret_cast(GL.GetString(GL_EXTENSIONS)); - const char *pos = extensions_string; - while (const char *next = strchr(pos, ' ')) { - addExtension(std::string{pos, next}); - pos = next + 1; - } - addExtension(pos); - extensionsLoaded(); -} -void COpenGL3ExtensionHandler::initExtensionsNew() +void COpenGL3ExtensionHandler::initExtensions() { - int ext_count = GetInteger(GL_NUM_EXTENSIONS); - for (int k = 0; k < ext_count; k++) - addExtension(reinterpret_cast(GL.GetStringi(GL_EXTENSIONS, k))); - extensionsLoaded(); -} - -void COpenGL3ExtensionHandler::addExtension(std::string &&name) -{ - Extensions.emplace(std::move(name)); -} - -bool COpenGL3ExtensionHandler::queryExtension(const std::string &name) const noexcept -{ - return Extensions.find(name) != Extensions.end(); -} - -void COpenGL3ExtensionHandler::extensionsLoaded() -{ - os::Printer::log((std::string("Loaded ") + std::to_string(Extensions.size()) + " extensions:").c_str(), ELL_DEBUG); - for (const auto &it : Extensions) - os::Printer::log((std::string(" ") + it).c_str(), ELL_DEBUG); + // reading extensions happens in mt_opengl.cpp for (size_t j = 0; j < IRR_OGLES_Feature_Count; ++j) FeatureAvailable[j] = queryExtension(getFeatureString(j)); } diff --git a/irr/src/OpenGL/ExtensionHandler.h b/irr/src/OpenGL/ExtensionHandler.h index 74c3e0b8a..8f76c0eea 100644 --- a/irr/src/OpenGL/ExtensionHandler.h +++ b/irr/src/OpenGL/ExtensionHandler.h @@ -28,11 +28,13 @@ public: COpenGL3ExtensionHandler() : COGLESCoreExtensionHandler() {} - void initExtensionsOld(); - void initExtensionsNew(); + void initExtensions(); /// Checks whether a named extension is present - bool queryExtension(const std::string &name) const noexcept; + inline bool queryExtension(const std::string &name) const noexcept + { + return GL.IsExtensionPresent(name); + } bool queryFeature(video::E_VIDEO_DRIVER_FEATURE feature) const { @@ -159,12 +161,6 @@ public: bool AnisotropicFilterSupported = false; bool BlendMinMaxSupported = false; - -private: - void addExtension(std::string &&name); - void extensionsLoaded(); - - std::unordered_set Extensions; }; } diff --git a/irr/src/OpenGL3/Driver.cpp b/irr/src/OpenGL3/Driver.cpp index 8196a8117..fd018b91d 100644 --- a/irr/src/OpenGL3/Driver.cpp +++ b/irr/src/OpenGL3/Driver.cpp @@ -36,7 +36,7 @@ void COpenGL3Driver::initFeatures() { assert(Version.Spec == OpenGLSpec::Compat); assert(isVersionAtLeast(3, 2)); - initExtensionsNew(); + initExtensions(); TextureFormats[ECF_A1R5G5B5] = {GL_RGB5_A1, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV}; // WARNING: may not be renderable TextureFormats[ECF_R5G6B5] = {GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5}; // GL_RGB565 is an extension until 4.1 diff --git a/irr/src/OpenGLES2/Driver.cpp b/irr/src/OpenGLES2/Driver.cpp index 6278ee9c3..249b6caef 100644 --- a/irr/src/OpenGLES2/Driver.cpp +++ b/irr/src/OpenGLES2/Driver.cpp @@ -31,10 +31,7 @@ void COpenGLES2Driver::initFeatures() { assert(Version.Spec == OpenGLSpec::ES); assert(Version.Major >= 2); - if (Version.Major >= 3) - initExtensionsNew(); - else - initExtensionsOld(); + initExtensions(); static const GLenum BGRA8_EXT = 0x93A1; From 5a4d7fb0d6304279ce45b50b7764beaec76ffe8e Mon Sep 17 00:00:00 2001 From: Josiah VanderZee Date: Tue, 14 May 2024 09:03:11 -0500 Subject: [PATCH 09/67] Do not bother to assert that a u8 is >= 0 This fixes a warning seen in GCC 7 on CI about a comparison in mapblock.h that is always true. --- src/mapblock.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mapblock.h b/src/mapblock.h index a32f9b312..843daf6ef 100644 --- a/src/mapblock.h +++ b/src/mapblock.h @@ -167,7 +167,7 @@ public: inline void setLightingComplete(LightBank bank, u8 direction, bool is_complete) { - assert(direction >= 0 && direction <= 5); + assert(direction <= 5); if (bank == LIGHTBANK_NIGHT) { direction += 6; } @@ -182,7 +182,7 @@ public: inline bool isLightingComplete(LightBank bank, u8 direction) { - assert(direction >= 0 && direction <= 5); + assert(direction <= 5); if (bank == LIGHTBANK_NIGHT) { direction += 6; } From c38e0d05bf43a9aee86aec4e7ccb149fd41015b9 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Tue, 14 May 2024 18:31:51 +0200 Subject: [PATCH 10/67] Reenable fog toggle unless server restricts fog distance (#14634) see comments in #14539 --- builtin/settingtypes.txt | 5 ++--- doc/lua_api.md | 9 ++++----- src/client/game.cpp | 28 ++++++++++++++++------------ src/defaultsettings.cpp | 3 +-- 4 files changed, 23 insertions(+), 22 deletions(-) diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index 9c2199676..b43c938ae 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -381,8 +381,7 @@ crosshair_alpha (Crosshair alpha) int 255 0 255 [**Fog] -# Whether to fog out the end of the visible area. This option only works -# with the 'debug' privilege. +# Whether to fog out the end of the visible area. enable_fog (Fog) bool true # Make fog and sky colors depend on daytime (dawn/sunset) and view direction. @@ -2511,7 +2510,7 @@ keymap_toggle_chat (Chat toggle key) key KEY_F2 # Key for toggling the display of the large chat console. keymap_console (Large chat console key) key KEY_F10 -# Key for toggling the display of fog. Only usable with 'debug' privilege. +# Key for toggling the display of fog. keymap_toggle_fog (Fog toggle key) key KEY_F3 # Key for toggling the camera update. Only usable with 'debug' privilege. diff --git a/doc/lua_api.md b/doc/lua_api.md index b08f7356d..d338d23b2 100644 --- a/doc/lua_api.md +++ b/doc/lua_api.md @@ -8257,14 +8257,13 @@ child will follow movement and rotation of that bone. `"default"` uses the classic Minetest sun and moon tinting. Will use tonemaps, if set to `"default"`. (default: `"default"`) * `fog`: A table with following optional fields: - * `fog_distance`: integer, set an upper bound the client's viewing_range (inluding range_all). - By default, fog_distance is controlled by the client's viewing_range, and this field is not set. - Any value >= 0 sets the desired upper bound for the client's viewing_range and disables range_all. - Any value < 0, resets the behavior to being client-controlled. + * `fog_distance`: integer, set an upper bound for the client's viewing_range. + Any value >= 0 sets the desired upper bound for viewing_range, + disables range_all and prevents disabling fog (F3 key by default). + Any value < 0 resets the behavior to being client-controlled. (default: -1) * `fog_start`: float, override the client's fog_start. Fraction of the visible distance at which fog starts to be rendered. - By default, fog_start is controlled by the client's `fog_start` setting, and this field is not set. Any value between [0.0, 0.99] set the fog_start as a fraction of the viewing_range. Any value < 0, resets the behavior to being client-controlled. (default: -1) diff --git a/src/client/game.cpp b/src/client/game.cpp index 01739ff25..0b907ee5b 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -792,6 +792,14 @@ protected: void showOverlayMessage(const char *msg, float dtime, int percent, bool draw_clouds = true); + inline bool fogEnabled() + { + // Client setting only takes effect if fog distance unlimited or debug priv + if (sky->getFogDistance() < 0 || client->checkPrivilege("debug")) + return m_cache_enable_fog; + return true; + } + static void settingChangedCallback(const std::string &setting_name, void *data); void readSettings(); @@ -2467,15 +2475,12 @@ void Game::toggleMinimap(bool shift_pressed) void Game::toggleFog() { - bool flag; - // do not modify setting if no privilege - if (!client->checkPrivilege("debug")) { - flag = true; - } else { - flag = !g_settings->getBool("enable_fog"); - g_settings->setBool("enable_fog", flag); - } - if (flag) + bool flag = !g_settings->getBool("enable_fog"); + g_settings->setBool("enable_fog", flag); + bool allowed = sky->getFogDistance() < 0 || client->checkPrivilege("debug"); + if (!allowed) + m_game_ui->showTranslatedStatusText("Fog enabled by game or mod"); + else if (flag) m_game_ui->showTranslatedStatusText("Fog enabled"); else m_game_ui->showTranslatedStatusText("Fog disabled"); @@ -4230,8 +4235,7 @@ void Game::updateClouds(float dtime) camera_node_position.Y = camera_node_position.Y + camera_offset.Y * BS; camera_node_position.Z = camera_node_position.Z + camera_offset.Z * BS; this->clouds->update(camera_node_position, this->sky->getCloudColor()); - bool enable_fog = this->m_cache_enable_fog || !client->checkPrivilege("debug"); - if (this->clouds->isCameraInsideCloud() && enable_fog) { + if (this->clouds->isCameraInsideCloud() && this->fogEnabled()) { // If camera is inside cloud and fog is enabled, use cloud's colors as sky colors. video::SColor clouds_dark = this->clouds->getColor().getInterpolated( video::SColor(255, 0, 0, 0), 0.9); @@ -4291,7 +4295,7 @@ void Game::drawScene(ProfilerGraph *graph, RunStats *stats) /* Fog */ - if (this->m_cache_enable_fog || !client->checkPrivilege("debug")) { + if (this->fogEnabled()) { this->driver->setFog( fog_color, video::EFT_FOG_LINEAR, diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 0ea4051b4..6c0d4b4cc 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -172,11 +172,10 @@ void set_default_settings() settings->setDefault("keymap_toggle_block_bounds", ""); settings->setDefault("keymap_toggle_hud", "KEY_F1"); settings->setDefault("keymap_toggle_chat", "KEY_F2"); -#ifndef NDEBUG settings->setDefault("keymap_toggle_fog", "KEY_F3"); +#ifndef NDEBUG settings->setDefault("keymap_toggle_update_camera", "KEY_F4"); #else - settings->setDefault("keymap_toggle_fog", ""); settings->setDefault("keymap_toggle_update_camera", ""); #endif settings->setDefault("keymap_toggle_debug", "KEY_F5"); From 39fd9b93c3647b9d7b01777ca9bf6ba0720b0c65 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Wed, 8 May 2024 20:37:10 +0200 Subject: [PATCH 11/67] Introduce proper error handling for file streams --- src/client/client.cpp | 7 +- src/client/filecache.cpp | 20 ++--- src/client/shader.cpp | 4 +- src/client/shadows/dynamicshadowsrender.cpp | 3 +- src/content/content.cpp | 38 +++------ src/database/database-files.cpp | 17 ++-- src/filesys.cpp | 89 ++++++++++++++------- src/filesys.h | 63 ++++++++++++++- src/gettext.cpp | 19 ++--- src/gui/guiEngine.cpp | 5 +- src/log.cpp | 23 +++--- src/map_settings_manager.cpp | 8 +- src/mapgen/mg_schematic.cpp | 7 +- src/porting.cpp | 17 +++- src/porting.h | 3 + src/script/lua_api/l_areastore.cpp | 2 +- src/server.cpp | 12 +-- src/server/ban.cpp | 3 +- src/settings.cpp | 5 +- src/texture_override.cpp | 3 +- src/unittest/test.cpp | 6 +- src/unittest/test_ban.cpp | 4 +- src/unittest/test_filesys.cpp | 26 ++++++ 23 files changed, 235 insertions(+), 149 deletions(-) diff --git a/src/client/client.cpp b/src/client/client.cpp index ca3f91e78..61140d87a 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -278,9 +278,7 @@ void Client::scanModSubfolder(const std::string &mod_name, const std::string &mo << "\" as \"" << vfs_path << "\"." << std::endl; std::string contents; - if (!fs::ReadFile(real_path, contents)) { - errorstream << "Client::scanModSubfolder(): Can't read file \"" - << real_path << "\"." << std::endl; + if (!fs::ReadFile(real_path, contents, true)) { continue; } @@ -1945,8 +1943,7 @@ void Client::makeScreenshot() while (serial < SCREENSHOT_MAX_SERIAL_TRIES) { filename = filename_base + (serial > 0 ? ("_" + itos(serial)) : "") + filename_ext; - std::ifstream tmp(filename.c_str()); - if (!tmp.good()) + if (!fs::PathExists(filename)) break; // File did not apparently exist, we'll go with it serial++; } diff --git a/src/client/filecache.cpp b/src/client/filecache.cpp index cb9f5440b..ffd011866 100644 --- a/src/client/filecache.cpp +++ b/src/client/filecache.cpp @@ -38,13 +38,9 @@ void FileCache::createDir() bool FileCache::loadByPath(const std::string &path, std::ostream &os) { - std::ifstream fis(path.c_str(), std::ios_base::binary); - - if(!fis.good()){ - verbosestream<<"FileCache: File not found in cache: " - <(is)), - std::istreambuf_iterator()); + fs::ReadFile(spec.path + DIR_DELIM + "description.txt", spec.desc); } } diff --git a/src/database/database-files.cpp b/src/database/database-files.cpp index 518c776ea..27f42fc97 100644 --- a/src/database/database-files.cpp +++ b/src/database/database-files.cpp @@ -165,11 +165,9 @@ void PlayerDatabaseFiles::savePlayer(RemotePlayer *player) } // Open and deserialize file to check player name - std::ifstream is(path.c_str(), std::ios_base::binary); - if (!is.good()) { - errorstream << "Failed to open " << path << std::endl; + auto is = open_ifstream(path.c_str(), true); + if (!is.good()) return; - } deSerialize(&testplayer, is, path, NULL); is.close(); @@ -205,7 +203,7 @@ bool PlayerDatabaseFiles::removePlayer(const std::string &name) RemotePlayer temp_player("", NULL); for (u32 i = 0; i < PLAYER_FILE_ALTERNATE_TRIES; i++) { // Open file and deserialize - std::ifstream is(path.c_str(), std::ios_base::binary); + auto is = open_ifstream(path.c_str(), false); if (!is.good()) continue; @@ -231,7 +229,7 @@ bool PlayerDatabaseFiles::loadPlayer(RemotePlayer *player, PlayerSAO *sao) const std::string player_to_load = player->getName(); for (u32 i = 0; i < PLAYER_FILE_ALTERNATE_TRIES; i++) { // Open file and deserialize - std::ifstream is(path.c_str(), std::ios_base::binary); + auto is = open_ifstream(path.c_str(), false); if (!is.good()) continue; @@ -260,7 +258,7 @@ void PlayerDatabaseFiles::listPlayers(std::vector &res) const std::string &filename = it->name; std::string full_path = m_savedir + DIR_DELIM + filename; - std::ifstream is(full_path.c_str(), std::ios_base::binary); + auto is = open_ifstream(full_path.c_str(), true); if (!is.good()) continue; @@ -332,7 +330,7 @@ void AuthDatabaseFiles::reload() bool AuthDatabaseFiles::readAuthFile() { std::string path = m_savedir + DIR_DELIM + "auth.txt"; - std::ifstream file(path, std::ios::binary); + auto file = open_ifstream(path.c_str(), false); if (!file.good()) { return false; } @@ -528,8 +526,7 @@ Json::Value *ModStorageDatabaseFiles::getOrCreateJson(const std::string &modname std::string path = m_storage_dir + DIR_DELIM + modname; if (fs::PathExists(path)) { - std::ifstream is(path.c_str(), std::ios_base::binary); - + auto is = open_ifstream(path.c_str(), true); Json::CharReaderBuilder builder; builder.settings_["collectComments"] = false; std::string errs; diff --git a/src/filesys.cpp b/src/filesys.cpp index f7a03617b..a61f7f0aa 100644 --- a/src/filesys.cpp +++ b/src/filesys.cpp @@ -41,6 +41,13 @@ with this program; if not, write to the Free Software Foundation, Inc., #endif #endif +// Error from last OS call as string +#ifdef _WIN32 +#define LAST_OS_ERROR() porting::ConvertError(GetLastError()) +#else +#define LAST_OS_ERROR() strerror(errno) +#endif + namespace fs { @@ -849,40 +856,44 @@ const char *GetFilenameFromPath(const char *path) bool safeWriteToFile(const std::string &path, std::string_view content) { - std::string tmp_file = path + ".~mt"; + // Note: this is not safe if two MT processes try this at the same time (FIXME?) + const std::string tmp_file = path + ".~mt"; - // Write to a tmp file - bool tmp_success = false; + // Write data to a temporary file + std::string write_error; #ifdef _WIN32 // We've observed behavior suggesting that the MSVC implementation of std::ofstream::flush doesn't // actually flush, so we use win32 APIs. - HANDLE tmp_handle = CreateFile( - tmp_file.c_str(), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); - if (tmp_handle == INVALID_HANDLE_VALUE) { + HANDLE handle = CreateFile(tmp_file.c_str(), GENERIC_WRITE, 0, nullptr, + CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); + if (handle == INVALID_HANDLE_VALUE) { + errorstream << "Failed to open file: " << LAST_OS_ERROR() << std::endl; return false; } DWORD bytes_written; - tmp_success = (WriteFile(tmp_handle, content.data(), content.size(), &bytes_written, nullptr) && - FlushFileBuffers(tmp_handle)); - CloseHandle(tmp_handle); + if (!WriteFile(handle, content.data(), content.size(), &bytes_written, nullptr)) + write_error = LAST_OS_ERROR(); + else if (!FlushFileBuffers(handle)) + write_error = LAST_OS_ERROR(); + CloseHandle(handle); #else - std::ofstream os(tmp_file.c_str(), std::ios::binary); - if (!os.good()) { + auto os = open_ofstream(tmp_file.c_str(), true); + if (!os.good()) return false; - } - os << content; - os.flush(); + os << content << std::flush; os.close(); - tmp_success = !os.fail(); + if (os.fail()) + write_error = "iostream fail"; #endif - if (!tmp_success) { + if (!write_error.empty()) { + errorstream << "Failed to write file: " << write_error << std::endl; remove(tmp_file.c_str()); return false; } - bool rename_success = false; + std::string rename_error; // Move the finished temporary file over the real file #ifdef _WIN32 @@ -890,22 +901,25 @@ bool safeWriteToFile(const std::string &path, std::string_view content) // to query the file. This can make the move file call below fail. // We retry up to 5 times, with a 1ms sleep between, before we consider the whole operation failed for (int attempt = 0; attempt < 5; attempt++) { - rename_success = MoveFileEx(tmp_file.c_str(), path.c_str(), + auto ok = MoveFileEx(tmp_file.c_str(), path.c_str(), MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH); - if (rename_success) + if (ok) { + rename_error.clear(); break; + } + rename_error = LAST_OS_ERROR(); sleep_ms(1); } #else // On POSIX compliant systems rename() is specified to be able to swap the // file in place of the destination file, making this a truly error-proof // transaction. - rename_success = rename(tmp_file.c_str(), path.c_str()) == 0; + if (rename(tmp_file.c_str(), path.c_str()) != 0) + rename_error = LAST_OS_ERROR(); #endif - if (!rename_success) { - warningstream << "Failed to write to file: " << path.c_str() << std::endl; - // Remove the temporary file because moving it over the target file - // failed. + + if (!rename_error.empty()) { + errorstream << "Failed to overwrite \"" << path << "\": " << rename_error << std::endl; remove(tmp_file.c_str()); return false; } @@ -949,7 +963,7 @@ bool extractZipFile(io::IFileSystem *fs, const char *filename, const std::string irr_ptr toread(opened_zip->createAndOpenFile(i)); - std::ofstream os(fullpath.c_str(), std::ios::binary); + auto os = open_ofstream(fullpath.c_str(), true); if (!os.good()) return false; @@ -976,12 +990,11 @@ bool extractZipFile(io::IFileSystem *fs, const char *filename, const std::string } #endif -bool ReadFile(const std::string &path, std::string &out) +bool ReadFile(const std::string &path, std::string &out, bool log_error) { - std::ifstream is(path, std::ios::binary | std::ios::ate); - if (!is.good()) { + auto is = open_ifstream(path.c_str(), log_error, std::ios::ate); + if (!is.good()) return false; - } auto size = is.tellg(); out.resize(size); @@ -996,4 +1009,22 @@ bool Rename(const std::string &from, const std::string &to) return rename(from.c_str(), to.c_str()) == 0; } +bool OpenStream(std::filebuf &stream, const char *filename, + std::ios::openmode mode, bool log_error, bool log_warn) +{ + assert((mode & std::ios::in) || (mode & std::ios::out)); + assert(!stream.is_open()); + // C++ dropped the ball hard for file opening error handling, there's not even + // an implementation-defined mechanism for returning any kind of error code or message. + if (!stream.open(filename, mode)) { + if (log_warn || log_error) { + std::string msg = LAST_OS_ERROR(); + (log_error ? errorstream : warningstream) + << "Failed to open \"" << filename << "\": " << msg << std::endl; + } + return false; + } + return true; +} + } // namespace fs diff --git a/src/filesys.h b/src/filesys.h index 3edc3eef6..bb71f22e5 100644 --- a/src/filesys.h +++ b/src/filesys.h @@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include #include +#include #ifdef _WIN32 #define DIR_DELIM "\\" @@ -148,14 +149,74 @@ std::string AbsolutePath(const std::string &path); // delimiter is found. const char *GetFilenameFromPath(const char *path); +// Replace the content of a file on disk in a way that is safe from +// corruption/truncation on a crash. +// logs and returns false on error bool safeWriteToFile(const std::string &path, std::string_view content); #ifndef SERVER bool extractZipFile(irr::io::IFileSystem *fs, const char *filename, const std::string &destination); #endif -bool ReadFile(const std::string &path, std::string &out); +bool ReadFile(const std::string &path, std::string &out, bool log_error = false); bool Rename(const std::string &from, const std::string &to); +/** + * Open a file buffer with error handling, commonly used with `std::fstream.rdbuf()`. + * + * @param stream stream references, must not already be open + * @param filename filename to open + * @param mode mode bits (used as-is) + * @param log_error log failure to errorstream? + * @param log_warn log failure to warningstream? + * @return true if success +*/ +bool OpenStream(std::filebuf &stream, const char *filename, + std::ios::openmode mode, bool log_error, bool log_warn); + } // namespace fs + +// outside of namespace for convenience: + +/** + * Helper function to open an output file stream (= writing). + * + * For compatibility with fopen() binary mode and truncate are always set. + * Use `fs::OpenStream` for more control. + * @param name file name + * @param log if true, failure to open the file will be logged to errorstream + * @param mode additional mode bits (e.g. std::ios::app) + * @return file stream, will be !good in case of error +*/ +inline std::ofstream open_ofstream(const char *name, bool log, + std::ios::openmode mode = std::ios::openmode()) +{ + mode |= std::ios::out | std::ios::binary; + if (!(mode & std::ios::app)) + mode |= std::ios::trunc; + std::ofstream ofs; + if (!fs::OpenStream(*ofs.rdbuf(), name, mode, log, false)) + ofs.setstate(std::ios::failbit); + return ofs; +} + +/** + * Helper function to open an input file stream (= reading). + * + * For compatibility with fopen() binary mode is always set. + * Use `fs::OpenStream` for more control. + * @param name file name + * @param log if true, failure to open the file will be logged to errorstream + * @param mode additional mode bits (e.g. std::ios::ate) + * @return file stream, will be !good in case of error +*/ +inline std::ifstream open_ifstream(const char *name, bool log, + std::ios::openmode mode = std::ios::openmode()) +{ + mode |= std::ios::in | std::ios::binary; + std::ifstream ifs; + if (!fs::OpenStream(*ifs.rdbuf(), name, mode, log, false)) + ifs.setstate(std::ios::failbit); + return ifs; +} diff --git a/src/gettext.cpp b/src/gettext.cpp index 68b6f728a..58efebb7c 100644 --- a/src/gettext.cpp +++ b/src/gettext.cpp @@ -147,18 +147,15 @@ static void MSVC_LocaleWorkaround(int argc, char* argv[]) exit(0); // NOTREACHED } else { - char buffer[1024]; + auto e = GetLastError(); - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), - MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), buffer, - sizeof(buffer) - 1, NULL); - - errorstream << "*******************************************************" << std::endl; - errorstream << "CMD: " << app_name << std::endl; - errorstream << "Failed to restart with current locale: " << std::endl; - errorstream << buffer; - errorstream << "Expect language to be broken!" << std::endl; - errorstream << "*******************************************************" << std::endl; + errorstream + << "*******************************************************" << '\n' + << "CMD: " << app_name << '\n'; + << "Failed to restart with current locale: "; + << porting::ConvertError(e) << '\n'; + << "Expect language to be broken!" << '\n'; + << "*******************************************************" << std::endl; } } diff --git a/src/gui/guiEngine.cpp b/src/gui/guiEngine.cpp index 4d35f38ab..66f9f9864 100644 --- a/src/gui/guiEngine.cpp +++ b/src/gui/guiEngine.cpp @@ -620,10 +620,9 @@ bool GUIEngine::setTexture(texture_layer layer, const std::string &texturepath, bool GUIEngine::downloadFile(const std::string &url, const std::string &target) { #if USE_CURL - std::ofstream target_file(target.c_str(), std::ios::out | std::ios::binary); - if (!target_file.good()) { + auto target_file = open_ofstream(target.c_str(), true); + if (!target_file.good()) return false; - } HTTPFetchRequest fetch_request; HTTPFetchResult fetch_result; diff --git a/src/log.cpp b/src/log.cpp index 8ab0ca4ba..5ee66c070 100644 --- a/src/log.cpp +++ b/src/log.cpp @@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "exceptions.h" #include "util/numeric.h" #include "log.h" +#include "filesys.h" #ifdef __ANDROID__ #include @@ -36,7 +37,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include #include -#include #include class LevelTarget : public LogTarget { @@ -299,25 +299,24 @@ void FileLogOutput::setFile(const std::string &filename, s64 file_size_max) bool is_too_large = false; if (file_size_max > 0) { std::ifstream ifile(filename, std::ios::binary | std::ios::ate); - is_too_large = ifile.tellg() > file_size_max; - ifile.close(); + if (ifile.good()) + is_too_large = ifile.tellg() > file_size_max; } - if (is_too_large) { std::string filename_secondary = filename + ".1"; actionstream << "The log file grew too big; it is moved to " << filename_secondary << std::endl; - remove(filename_secondary.c_str()); - rename(filename.c_str(), filename_secondary.c_str()); + fs::DeleteSingleFileOrEmptyDirectory(filename_secondary); + fs::Rename(filename, filename_secondary); } - m_stream.open(filename, std::ios::app | std::ios::ate); - if (!m_stream.good()) - throw FileNotGoodException("Failed to open log file " + - filename + ": " + strerror(errno)); + // Intentionally not using open_ofstream() to keep the text mode + if (!fs::OpenStream(*m_stream.rdbuf(), filename.c_str(), std::ios::out | std::ios::app, true, false)) + throw FileNotGoodException("Failed to open log file"); + m_stream << "\n\n" - "-------------" << std::endl << - " Separator" << std::endl << + "-------------\n" << + " Separator\n" << "-------------\n" << std::endl; } diff --git a/src/map_settings_manager.cpp b/src/map_settings_manager.cpp index 264a941c2..bef7ad1c6 100644 --- a/src/map_settings_manager.cpp +++ b/src/map_settings_manager.cpp @@ -96,13 +96,9 @@ bool MapSettingsManager::setMapSettingNoiseParams( bool MapSettingsManager::loadMapMeta() { - std::ifstream is(m_map_meta_path.c_str(), std::ios_base::binary); - - if (!is.good()) { - errorstream << "loadMapMeta: could not open " - << m_map_meta_path << std::endl; + auto is = open_ifstream(m_map_meta_path.c_str(), true); + if (!is.good()) return false; - } if (!m_map_settings->parseConfigLines(is)) { errorstream << "loadMapMeta: Format error. '[end_of_params]' missing?" << std::endl; diff --git a/src/mapgen/mg_schematic.cpp b/src/mapgen/mg_schematic.cpp index b6b78f9e9..5ce0b8844 100644 --- a/src/mapgen/mg_schematic.cpp +++ b/src/mapgen/mg_schematic.cpp @@ -485,12 +485,9 @@ bool Schematic::serializeToLua(std::ostream *os, bool use_comments, bool Schematic::loadSchematicFromFile(const std::string &filename, const NodeDefManager *ndef, StringMap *replace_names) { - std::ifstream is(filename.c_str(), std::ios_base::binary); - if (!is.good()) { - errorstream << __FUNCTION__ << ": unable to open file '" - << filename << "'" << std::endl; + auto is = open_ifstream(filename.c_str(), true); + if (!is.good()) return false; - } if (!m_ndef) m_ndef = ndef; diff --git a/src/porting.cpp b/src/porting.cpp index db769d901..2b2405d38 100644 --- a/src/porting.cpp +++ b/src/porting.cpp @@ -582,7 +582,7 @@ static void createCacheDirTag() if (fs::PathExists(path)) return; fs::CreateAllDirs(path_cache); - std::ofstream ofs(path, std::ios::out | std::ios::binary); + auto ofs = open_ofstream(path.c_str(), false); if (!ofs.good()) return; ofs << "Signature: 8a477f597d28d172789f06886806bc55\n" @@ -800,6 +800,21 @@ std::string QuoteArgv(const std::string &arg) ret.push_back('"'); return ret; } + +std::string ConvertError(DWORD error_code) +{ + wchar_t buffer[320]; + + auto r = FormatMessageW( + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + nullptr, error_code, 0, buffer, ARRLEN(buffer) - 1, nullptr); + if (!r) + return std::to_string(error_code); + + if (!buffer[0]) // should not happen normally + return "?"; + return wide_to_utf8(buffer); +} #endif int mt_snprintf(char *buf, const size_t buf_size, const char *fmt, ...) diff --git a/src/porting.h b/src/porting.h index 0f97a1ca3..a98e66bcf 100644 --- a/src/porting.h +++ b/src/porting.h @@ -293,6 +293,9 @@ void attachOrCreateConsole(); #ifdef _WIN32 // Quotes an argument for use in a CreateProcess() commandline (not cmd.exe!!) std::string QuoteArgv(const std::string &arg); + +// Convert an error code (e.g. from GetLastError()) into a string. +std::string ConvertError(DWORD error_code); #endif int mt_snprintf(char *buf, const size_t buf_size, const char *fmt, ...); diff --git a/src/script/lua_api/l_areastore.cpp b/src/script/lua_api/l_areastore.cpp index 82fb945ae..c261338a4 100644 --- a/src/script/lua_api/l_areastore.cpp +++ b/src/script/lua_api/l_areastore.cpp @@ -298,7 +298,7 @@ int LuaAreaStore::l_from_file(lua_State *L) const char *filename = luaL_checkstring(L, 2); CHECK_SECURE_PATH(L, filename, false); - std::ifstream is(filename, std::ios::binary); + auto is = open_ifstream(filename, true); return deserialization_helper(L, o->as, is); } diff --git a/src/server.cpp b/src/server.cpp index 6e12017bc..316f349b2 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -2545,9 +2545,7 @@ bool Server::addMediaFile(const std::string &filename, // Read data std::string filedata; - if (!fs::ReadFile(filepath, filedata)) { - errorstream << "Server::addMediaFile(): Failed to open \"" - << filename << "\" for reading" << std::endl; + if (!fs::ReadFile(filepath, filedata, true)) { return false; } @@ -2715,9 +2713,7 @@ void Server::sendRequestedMedia(session_t peer_id, // Read data std::string data; - if (!fs::ReadFile(m.path, data)) { - errorstream << "Server::sendRequestedMedia(): Failed to read \"" - << name << "\"" << std::endl; + if (!fs::ReadFile(m.path, data, true)) { continue; } file_size_bunch_total += data.size(); @@ -3618,7 +3614,7 @@ namespace { auto filepath = fs::CreateTempFile(); if (filepath.empty()) return ""; - std::ofstream os(filepath, std::ios::binary); + auto os = open_ofstream(filepath.c_str(), true); if (!os.good()) return ""; os << content; @@ -4200,7 +4196,7 @@ Translations *Server::getTranslationLanguage(const std::string &lang_code) for (const auto &i : m_media) { if (str_ends_with(i.first, suffix)) { std::string data; - if (fs::ReadFile(i.second.path, data)) { + if (fs::ReadFile(i.second.path, data, true)) { translations->loadTranslation(data); } } diff --git a/src/server/ban.cpp b/src/server/ban.cpp index 47a6ccd5e..4af108795 100644 --- a/src/server/ban.cpp +++ b/src/server/ban.cpp @@ -48,9 +48,8 @@ void BanManager::load() { MutexAutoLock lock(m_mutex); infostream<<"BanManager: loading from "< #include @@ -48,7 +49,7 @@ static const std::map override_LUT = { TextureOverrideSource::TextureOverrideSource(const std::string &filepath) { - std::ifstream infile(filepath.c_str()); + auto infile = open_ifstream(filepath.c_str(), false); std::string line; int line_index = 0; while (std::getline(infile, line)) { diff --git a/src/unittest/test.cpp b/src/unittest/test.cpp index e2d19b3e1..7141ee0c6 100644 --- a/src/unittest/test.cpp +++ b/src/unittest/test.cpp @@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "modchannels.h" #include "util/numeric.h" #include "porting.h" +#include "debug.h" content_t t_CONTENT_STONE; content_t t_CONTENT_GRASS; @@ -348,11 +349,14 @@ void TestBase::runTest(const char *name, std::function &&test) rawstream << " at " << e.file << ":" << e.line << std::endl; rawstream << "[FAIL] "; num_tests_failed++; - } catch (std::exception &e) { + } +#if CATCH_UNHANDLED_EXCEPTIONS == 1 + catch (std::exception &e) { rawstream << "Caught unhandled exception: " << e.what() << std::endl; rawstream << "[FAIL] "; num_tests_failed++; } +#endif num_tests_run++; u64 tdiff = porting::getTimeMs() - t1; rawstream << name << " - " << tdiff << "ms" << std::endl; diff --git a/src/unittest/test_ban.cpp b/src/unittest/test_ban.cpp index 6b36211ab..58132e20a 100644 --- a/src/unittest/test_ban.cpp +++ b/src/unittest/test_ban.cpp @@ -80,13 +80,13 @@ void TestBan::testCreate() BanManager bm(m_testbm); } - UASSERT(std::ifstream(m_testbm, std::ios::binary).is_open()); + UASSERT(fs::IsFile(m_testbm)); // test manual save { BanManager bm(m_testbm2); bm.save(); - UASSERT(std::ifstream(m_testbm2, std::ios::binary).is_open()); + UASSERT(fs::IsFile(m_testbm2)); } } diff --git a/src/unittest/test_filesys.cpp b/src/unittest/test_filesys.cpp index 302371361..8fc9db3d8 100644 --- a/src/unittest/test_filesys.cpp +++ b/src/unittest/test_filesys.cpp @@ -41,6 +41,7 @@ public: void testRemoveRelativePathComponent(); void testSafeWriteToFile(); void testCopyFileContents(); + void testNonExist(); }; static TestFileSys g_test_instance; @@ -54,6 +55,7 @@ void TestFileSys::runTests(IGameDef *gamedef) TEST(testRemoveRelativePathComponent); TEST(testSafeWriteToFile); TEST(testCopyFileContents); + TEST(testNonExist); } //////////////////////////////////////////////////////////////////////////////// @@ -311,3 +313,27 @@ void TestFileSys::testCopyFileContents() UASSERT(fs::ReadFile(file2, contents_actual)); UASSERTEQ(auto, contents_actual, test_data); } + +void TestFileSys::testNonExist() +{ + const auto path = getTestTempFile(); + fs::DeleteSingleFileOrEmptyDirectory(path); + + UASSERT(!fs::IsFile(path)); + UASSERT(!fs::IsDir(path)); + UASSERT(!fs::IsExecutable(path)); + + std::string s; + UASSERT(!fs::ReadFile(path, s)); + UASSERT(s.empty()); + + UASSERT(!fs::Rename(path, getTestTempFile())); + + std::filebuf buf; + // with logging enabled to test that code path + UASSERT(!fs::OpenStream(buf, path.c_str(), std::ios::in, false, true)); + UASSERT(!buf.is_open()); + + auto ifs = open_ifstream(path.c_str(), false); + UASSERT(!ifs.good()); +} From 93f4844c9c42a01ef7d0dc33451b2d98c8f7438f Mon Sep 17 00:00:00 2001 From: sfan5 Date: Tue, 14 May 2024 23:12:49 +0200 Subject: [PATCH 12/67] Fix unintentional error message with dynamic media --- src/client/filecache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/filecache.cpp b/src/client/filecache.cpp index ffd011866..1f7e605d1 100644 --- a/src/client/filecache.cpp +++ b/src/client/filecache.cpp @@ -38,7 +38,7 @@ void FileCache::createDir() bool FileCache::loadByPath(const std::string &path, std::ostream &os) { - auto fis = open_ifstream(path.c_str(), true); + auto fis = open_ifstream(path.c_str(), false); if (!fis.good()) return false; From 5c187363b2bfe9f50a793129102092b036846475 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20M=C3=BCller?= <34514239+appgurueu@users.noreply.github.com> Date: Wed, 15 May 2024 19:56:25 +0200 Subject: [PATCH 13/67] Fix some clang compiler warnings (#14654) * Fix some clang compiler warnings * Get rid of sdl_supports_primary_selection * Fix draw2DImage hiding overloaded virtual function --- irr/src/COSOperator.cpp | 23 ++++------------------- irr/src/OpenGL/Driver.cpp | 6 ------ irr/src/OpenGL/Driver.h | 2 ++ irr/src/OpenGL/MaterialRenderer.h | 10 +++++----- src/client/mapblock_mesh.cpp | 27 --------------------------- src/client/shadows/dynamicshadows.cpp | 1 - src/collision.cpp | 8 -------- src/gui/guiTable.cpp | 1 - src/irrlicht_changes/static_text.cpp | 1 - src/network/connection_internal.h | 2 +- 10 files changed, 12 insertions(+), 69 deletions(-) diff --git a/irr/src/COSOperator.cpp b/irr/src/COSOperator.cpp index b26463799..d53223916 100644 --- a/irr/src/COSOperator.cpp +++ b/irr/src/COSOperator.cpp @@ -29,18 +29,6 @@ #include "fast_atof.h" -#if defined(_IRR_COMPILE_WITH_SDL_DEVICE_) -static const bool sdl_supports_primary_selection = [] { -#if SDL_VERSION_ATLEAST(2, 25, 0) - SDL_version linked_version; - SDL_GetVersion(&linked_version); - return (linked_version.major == 2 && linked_version.minor >= 25) || linked_version.major > 2; -#else - return false; -#endif -}(); -#endif - namespace irr { @@ -131,8 +119,7 @@ void COSOperator::copyToPrimarySelection(const c8 *text) const #if defined(_IRR_COMPILE_WITH_SDL_DEVICE_) #if SDL_VERSION_ATLEAST(2, 25, 0) - if (sdl_supports_primary_selection) - SDL_SetPrimarySelectionText(text); + SDL_SetPrimarySelectionText(text); #endif #elif defined(_IRR_COMPILE_WITH_X11_DEVICE_) @@ -195,11 +182,9 @@ const c8 *COSOperator::getTextFromPrimarySelection() const { #if defined(_IRR_COMPILE_WITH_SDL_DEVICE_) #if SDL_VERSION_ATLEAST(2, 25, 0) - if (sdl_supports_primary_selection) { - SDL_free(PrimarySelectionText); - PrimarySelectionText = SDL_GetPrimarySelectionText(); - return PrimarySelectionText; - } + SDL_free(PrimarySelectionText); + PrimarySelectionText = SDL_GetPrimarySelectionText(); + return PrimarySelectionText; #endif return 0; diff --git a/irr/src/OpenGL/Driver.cpp b/irr/src/OpenGL/Driver.cpp index bf9334e15..0dd6ea1bb 100644 --- a/irr/src/OpenGL/Driver.cpp +++ b/irr/src/OpenGL/Driver.cpp @@ -704,12 +704,6 @@ IRenderTarget *COpenGL3DriverBase::addRenderTarget() return renderTarget; } -// small helper function to create vertex buffer object adress offsets -static inline u8 *buffer_offset(const long offset) -{ - return ((u8 *)0 + offset); -} - //! draws a vertex primitive list void COpenGL3DriverBase::drawVertexPrimitiveList(const void *vertices, u32 vertexCount, const void *indexList, u32 primitiveCount, diff --git a/irr/src/OpenGL/Driver.h b/irr/src/OpenGL/Driver.h index 80eeaf0da..51554334b 100644 --- a/irr/src/OpenGL/Driver.h +++ b/irr/src/OpenGL/Driver.h @@ -102,6 +102,8 @@ public: // internally used virtual void draw2DImage(const video::ITexture *texture, u32 layer, bool flip); + using CNullDriver::draw2DImage; + void draw2DImageBatch(const video::ITexture *texture, const core::array> &positions, const core::array> &sourceRects, diff --git a/irr/src/OpenGL/MaterialRenderer.h b/irr/src/OpenGL/MaterialRenderer.h index be74461e3..fa37cfff3 100644 --- a/irr/src/OpenGL/MaterialRenderer.h +++ b/irr/src/OpenGL/MaterialRenderer.h @@ -37,15 +37,15 @@ public: GLuint getProgram() const; virtual void OnSetMaterial(const SMaterial &material, const SMaterial &lastMaterial, - bool resetAllRenderstates, IMaterialRendererServices *services); + bool resetAllRenderstates, IMaterialRendererServices *services) override; - virtual bool OnRender(IMaterialRendererServices *service, E_VERTEX_TYPE vtxtype); + virtual bool OnRender(IMaterialRendererServices *service, E_VERTEX_TYPE vtxtype) override; - virtual void OnUnsetMaterial(); + virtual void OnUnsetMaterial() override; - virtual bool isTransparent() const; + virtual bool isTransparent() const override; - virtual s32 getRenderCapability() const; + virtual s32 getRenderCapability() const override; void setBasicRenderStates(const SMaterial &material, const SMaterial &lastMaterial, bool resetAllRenderstates) override; diff --git a/src/client/mapblock_mesh.cpp b/src/client/mapblock_mesh.cpp index 1d74b70cb..f06dcfa58 100644 --- a/src/client/mapblock_mesh.cpp +++ b/src/client/mapblock_mesh.cpp @@ -329,32 +329,6 @@ void final_color_blend(video::SColor *result, Mesh generation helpers */ -// This table is moved outside getNodeVertexDirs to avoid the compiler using -// a mutex to initialize this table at runtime right in the hot path. -// For details search the internet for "cxa_guard_acquire". -static const v3s16 vertex_dirs_table[] = { - // ( 1, 0, 0) - v3s16( 1,-1, 1), v3s16( 1,-1,-1), - v3s16( 1, 1,-1), v3s16( 1, 1, 1), - // ( 0, 1, 0) - v3s16( 1, 1,-1), v3s16(-1, 1,-1), - v3s16(-1, 1, 1), v3s16( 1, 1, 1), - // ( 0, 0, 1) - v3s16(-1,-1, 1), v3s16( 1,-1, 1), - v3s16( 1, 1, 1), v3s16(-1, 1, 1), - // invalid - v3s16(), v3s16(), v3s16(), v3s16(), - // ( 0, 0,-1) - v3s16( 1,-1,-1), v3s16(-1,-1,-1), - v3s16(-1, 1,-1), v3s16( 1, 1,-1), - // ( 0,-1, 0) - v3s16( 1,-1, 1), v3s16(-1,-1, 1), - v3s16(-1,-1,-1), v3s16( 1,-1,-1), - // (-1, 0, 0) - v3s16(-1,-1,-1), v3s16(-1,-1, 1), - v3s16(-1, 1, 1), v3s16(-1, 1,-1) -}; - /* Gets nth node tile (0 <= n <= 5). */ @@ -1006,7 +980,6 @@ video::SColor encode_light(u16 light, u8 emissive_light) u8 get_solid_sides(MeshMakeData *data) { std::unordered_map results; - v3s16 ofs; v3s16 blockpos_nodes = data->m_blockpos * MAP_BLOCKSIZE; const NodeDefManager *ndef = data->nodedef; diff --git a/src/client/shadows/dynamicshadows.cpp b/src/client/shadows/dynamicshadows.cpp index f717cc8b0..11db9bea7 100644 --- a/src/client/shadows/dynamicshadows.cpp +++ b/src/client/shadows/dynamicshadows.cpp @@ -42,7 +42,6 @@ static v3f quantizeDirection(v3f direction, float step) void DirectionalLight::createSplitMatrices(const Camera *cam) { static const float COS_15_DEG = 0.965926f; - v3f newCenter; v3f look = cam->getDirection().normalize(); // if current look direction is < 15 degrees away from the captured diff --git a/src/collision.cpp b/src/collision.cpp index 01daaf309..2db0e127d 100644 --- a/src/collision.cpp +++ b/src/collision.cpp @@ -218,14 +218,6 @@ bool wouldCollideWithCeiling( return false; } -static inline void getNeighborConnectingFace(const v3s16 &p, - const NodeDefManager *nodedef, Map *map, MapNode n, int v, int *neighbors) -{ - MapNode n2 = map->getNode(p); - if (nodedef->nodeboxConnects(n, n2, v)) - *neighbors |= v; -} - collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef, f32 pos_max_d, const aabb3f &box_0, f32 stepheight, f32 dtime, diff --git a/src/gui/guiTable.cpp b/src/gui/guiTable.cpp index 530580124..498090413 100644 --- a/src/gui/guiTable.cpp +++ b/src/gui/guiTable.cpp @@ -183,7 +183,6 @@ void GUITable::setTable(const TableOptions &options, } // Handle table options - video::SColor default_color(255, 255, 255, 255); s32 opendepth = 0; for (const Option &option : options) { const std::string &name = option.name; diff --git a/src/irrlicht_changes/static_text.cpp b/src/irrlicht_changes/static_text.cpp index 61f4da5e1..eba397963 100644 --- a/src/irrlicht_changes/static_text.cpp +++ b/src/irrlicht_changes/static_text.cpp @@ -94,7 +94,6 @@ void StaticText::draw() getTextWidth(); } - irr::video::SColor previous_color(255, 255, 255, 255); for (const EnrichedString &str : BrokenText) { if (HAlign == EGUIA_LOWERRIGHT) { diff --git a/src/network/connection_internal.h b/src/network/connection_internal.h index 95f523be2..a528f3fef 100644 --- a/src/network/connection_internal.h +++ b/src/network/connection_internal.h @@ -455,7 +455,7 @@ public: void PutReliableSendCommand(ConnectionCommandPtr &c, unsigned int max_packet_size) override; - virtual const Address &getAddress() const { + virtual const Address &getAddress() const override { return address; } From 5625be70fa748b6176010a81569239cbf392fb87 Mon Sep 17 00:00:00 2001 From: ROllerozxa Date: Wed, 15 May 2024 19:56:41 +0200 Subject: [PATCH 14/67] Don't bundle Development Test on macOS --- .github/workflows/macos.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 24c2b9f51..a7c670ed7 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -55,6 +55,7 @@ jobs: - name: CPack run: | cd build + cmake .. -DINSTALL_DEVTEST=FALSE cpack -G ZIP -B macos - uses: actions/upload-artifact@v4 From b23042839b849562afecf83f337197764a9485bc Mon Sep 17 00:00:00 2001 From: AFCMS Date: Wed, 15 May 2024 19:56:50 +0200 Subject: [PATCH 15/67] Fixes to Docker GitHub Actions workflow --- .github/workflows/docker_image.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/docker_image.yml b/.github/workflows/docker_image.yml index eaac7bf1b..421d2edf4 100644 --- a/.github/workflows/docker_image.yml +++ b/.github/workflows/docker_image.yml @@ -9,7 +9,7 @@ on: push: branches: [ "master" ] # Publish semver tags as releases. - tags: [ "*.*.*" ] + tags: [ "*" ] pull_request: # Build docker image on pull requests. (but do not publish) paths: @@ -25,6 +25,12 @@ on: - '.dockerignore' - '.github/workflows/docker_image.yml' workflow_dispatch: + inputs: + use_cache: + description: "Use build cache" + required: true + type: boolean + default: true env: REGISTRY: ghcr.io @@ -82,6 +88,7 @@ jobs: labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha cache-to: type=gha,mode=max + no-cache: ${{ (github.event_name == 'workflow_dispatch' && !inputs.use_cache) || startsWith(github.ref, 'refs/tags/') }} - name: Test Docker Image run: | From bceef8f5293fb935a78d143976fe1a0eecfdf5de Mon Sep 17 00:00:00 2001 From: Muhammad Rifqi Priyo Susanto Date: Thu, 16 May 2024 21:00:00 +0700 Subject: [PATCH 16/67] Trivial fix (forget to remove semicolon) in gettext.cpp --- src/gettext.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gettext.cpp b/src/gettext.cpp index 58efebb7c..bb99e39bc 100644 --- a/src/gettext.cpp +++ b/src/gettext.cpp @@ -151,10 +151,10 @@ static void MSVC_LocaleWorkaround(int argc, char* argv[]) errorstream << "*******************************************************" << '\n' - << "CMD: " << app_name << '\n'; - << "Failed to restart with current locale: "; - << porting::ConvertError(e) << '\n'; - << "Expect language to be broken!" << '\n'; + << "CMD: " << app_name << '\n' + << "Failed to restart with current locale: " + << porting::ConvertError(e) << '\n' + << "Expect language to be broken!" << '\n' << "*******************************************************" << std::endl; } } From f6cfe6b873cf2741fc9430e48e6c91db18054c42 Mon Sep 17 00:00:00 2001 From: grorp Date: Fri, 17 May 2024 13:27:31 +0200 Subject: [PATCH 17/67] Enable RTTI for Irrlicht on MSVC (#14677) --- irr/src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/irr/src/CMakeLists.txt b/irr/src/CMakeLists.txt index 10a841669..daff63bc2 100644 --- a/irr/src/CMakeLists.txt +++ b/irr/src/CMakeLists.txt @@ -31,7 +31,7 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "^(GNU|Clang|AppleClang)$") elseif(MSVC) string(APPEND CMAKE_CXX_STANDARD_LIBRARIES " msvcrt.lib") # ???? fuck off - add_compile_options(/GR- /Zl) + add_compile_options(/Zl) # Enable SSE for floating point math on 32-bit x86 by default # reasoning see minetest issue #11810 and https://gcc.gnu.org/wiki/FloatingPointMath From c4703a7f19441b2262630a34d64f9f1c210a9375 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Fri, 17 May 2024 13:00:41 +0200 Subject: [PATCH 18/67] Fix wrong collision axis in Lua moveresult introduced by c24a04d246221e13a626f4a4dd34037a5332a935 --- builtin/game/misc_s.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builtin/game/misc_s.lua b/builtin/game/misc_s.lua index 19708983a..ab15b230e 100644 --- a/builtin/game/misc_s.lua +++ b/builtin/game/misc_s.lua @@ -110,7 +110,7 @@ if core.set_push_moveresult1 then standing_on_object = b2, collisions = {{ type = "node", - axis = AXES[axis], + axis = AXES[axis + 1], node_pos = vector.new(npx, npy, npz), new_pos = vector.new(v0x, v0y, v0z), old_velocity = vector.new(v1x, v1y, v1z), From 8972e829f2a30fa38916db7c0690ecabb51be120 Mon Sep 17 00:00:00 2001 From: OgelGames Date: Tue, 21 May 2024 04:36:44 +1000 Subject: [PATCH 19/67] Restore vector type check (#14663) --- src/script/common/c_converter.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/script/common/c_converter.cpp b/src/script/common/c_converter.cpp index 446f88f3d..f0511d586 100644 --- a/src/script/common/c_converter.cpp +++ b/src/script/common/c_converter.cpp @@ -58,6 +58,7 @@ extern "C" { */ static void read_v3_aux(lua_State *L, int index) { + CHECK_POS_TAB(index); lua_pushvalue(L, index); lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_READ_VECTOR); lua_insert(L, -2); From 408faa11a170ab3ac7352f1ec802b0171349fd0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20M=C3=BCller?= <34514239+appgurueu@users.noreply.github.com> Date: Mon, 20 May 2024 20:37:40 +0200 Subject: [PATCH 20/67] Allow removal of item definition fields (#14675) --- builtin/game/register.lua | 5 ++++- doc/lua_api.md | 10 ++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/builtin/game/register.lua b/builtin/game/register.lua index 4ecf6ec71..76cb72f87 100644 --- a/builtin/game/register.lua +++ b/builtin/game/register.lua @@ -404,7 +404,7 @@ core.register_item(":", { }) -function core.override_item(name, redefinition) +function core.override_item(name, redefinition, del_fields) if redefinition.name ~= nil then error("Attempt to redefine name of "..name.." to "..dump(redefinition.name), 2) end @@ -418,6 +418,9 @@ function core.override_item(name, redefinition) for k, v in pairs(redefinition) do rawset(item, k, v) end + for _, field in ipairs(del_fields or {}) do + rawset(item, field, nil) + end register_item_raw(item) end diff --git a/doc/lua_api.md b/doc/lua_api.md index d338d23b2..dca31e4b6 100644 --- a/doc/lua_api.md +++ b/doc/lua_api.md @@ -5613,11 +5613,17 @@ Call these functions only at load time! * `minetest.register_node(name, node definition)` * `minetest.register_craftitem(name, item definition)` * `minetest.register_tool(name, item definition)` -* `minetest.override_item(name, redefinition)` +* `minetest.override_item(name, redefinition, del_fields)` + * `redefinition` is a table of fields `[name] = new_value`, + overwriting fields of or adding fields to the existing definition. + * `del_fields` is a list of field names to be set + to `nil` ("deleted from") the original definition. * Overrides fields of an item registered with register_node/tool/craftitem. * Note: Item must already be defined, (opt)depend on the mod defining it. * Example: `minetest.override_item("default:mese", - {light_source=minetest.LIGHT_MAX})` + {light_source=minetest.LIGHT_MAX}, {"sounds"})`: + Overwrites the `light_source` field, + removes the sounds from the definition of the mese block. * `minetest.unregister_item(name)` * Unregisters the item from the engine, and deletes the entry with key `name` from `minetest.registered_items` and from the associated item table From 36d236c5e063a4f20df52b31f9dd40e246f34672 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Mon, 20 May 2024 20:37:52 +0200 Subject: [PATCH 21/67] Update SDL for mingw builds (#14678) --- util/buildbot/common.sh | 2 +- util/buildbot/sha256sums.txt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/util/buildbot/common.sh b/util/buildbot/common.sh index 0887f7875..a7fa3b5d3 100644 --- a/util/buildbot/common.sh +++ b/util/buildbot/common.sh @@ -15,7 +15,7 @@ zlib_version=1.3.1 zstd_version=1.5.5 libjpeg_version=3.0.1 libpng_version=1.6.40 -sdl2_version=2.28.5 +sdl2_version=2.30.3 download () { local url=$1 diff --git a/util/buildbot/sha256sums.txt b/util/buildbot/sha256sums.txt index fce73a0a9..0587e6ea1 100644 --- a/util/buildbot/sha256sums.txt +++ b/util/buildbot/sha256sums.txt @@ -19,8 +19,8 @@ da6ad10632cf172992158e9ea0977a87914b5d5de93a972c3430b6a412237556 luajit-2024012 2b1dabe83d478b398cf9226d96de7fa62c973365c4aea70d27ba5782fb49d2d0 luajit-20240125-win64.zip e2443451fe5c2066eb564c64b8a1762738a88b7fd749c8b5907fed45c785497b openal-soft-1.23.1-win32.zip cb041445a118469caefbad2647470cb8571c8337bce2adc07634011ab5625417 openal-soft-1.23.1-win64.zip -f9f890af960e92fd3f532f2e9ac00681c33bc67a722e000dfdaeb41b0064f1a0 sdl2-2.28.5-win32.zip -8dde2c6963544b7d8a2e87c128ebbdf51ad0e70c7e2df986ff4e963ce9996d9b sdl2-2.28.5-win64.zip +574e0847e622ff09ab23e2b22b77685a2ab6ee43de3e2932f3e8a14a4d7b9338 sdl2-2.30.3-win32.zip +6127afdfc7b6a4ade8caf9a7267748ffea974f729866dd5be96c7a69d2f0fee7 sdl2-2.30.3-win64.zip 326701086a0ed66e09a9f3ec4d971654c13b6bd79cfdd079c947ecdcd6409525 sqlite3-3.44.2-win32.zip b2d474e3625f8f426b6cc5c0ecac831a1de46f7d1027bf4a9f6267b0b0411d42 sqlite3-3.44.2-win64.zip 8af10515d57dbfee5d2106cd66cafa2adeb4270d4c6047ccbf7e8b5d2d50681c zlib-1.3.1-win32.zip From ab783b9bb2355a38de7e001f114dacfb03a312f3 Mon Sep 17 00:00:00 2001 From: chmodsayshello Date: Tue, 21 May 2024 15:37:35 +0200 Subject: [PATCH 22/67] Display background & moving progress bar on shutdown screen (#14597) Co-authored-by: Gregor Parzefall --- src/client/game.cpp | 16 ++++++++++------ src/client/renderingengine.cpp | 32 ++++++++++++++++++-------------- src/client/renderingengine.h | 4 +++- 3 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/client/game.cpp b/src/client/game.cpp index 0b907ee5b..d35bf8e08 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -790,7 +790,7 @@ protected: // Misc void showOverlayMessage(const char *msg, float dtime, int percent, - bool draw_clouds = true); + float *indef_pos = nullptr); inline bool fogEnabled() { @@ -966,6 +966,8 @@ private: #ifdef __ANDROID__ bool m_android_chat_open; #endif + + float m_shutdown_progress = 0.0f; }; Game::Game() : @@ -1245,7 +1247,9 @@ void Game::shutdown() if (g_touchscreengui) g_touchscreengui->hide(); - showOverlayMessage(N_("Shutting down..."), 0, 0, false); + // only if the shutdown progress bar isn't shown yet + if (m_shutdown_progress == 0.0f) + showOverlayMessage(N_("Shutting down..."), 0, 0); if (clouds) clouds->drop(); @@ -1297,7 +1301,7 @@ void Game::shutdown() m_rendering_engine->run(); f32 dtime; fps_control.limit(device, &dtime); - showOverlayMessage(N_("Shutting down..."), dtime, 0, false); + showOverlayMessage(N_("Shutting down..."), dtime, 0, &m_shutdown_progress); } stop_thread->rethrow(); @@ -1429,7 +1433,7 @@ bool Game::createSingleplayerServer(const std::string &map_dir, if (success) showOverlayMessage(N_("Creating server..."), dtime, 5); else - showOverlayMessage(N_("Shutting down..."), dtime, 0, false); + showOverlayMessage(N_("Shutting down..."), dtime, 0, &m_shutdown_progress); } start_thread->rethrow(); @@ -4366,10 +4370,10 @@ void Game::drawScene(ProfilerGraph *graph, RunStats *stats) Misc ****************************************************************************/ -void Game::showOverlayMessage(const char *msg, float dtime, int percent, bool draw_sky) +void Game::showOverlayMessage(const char *msg, float dtime, int percent, float *indef_pos) { m_rendering_engine->draw_load_screen(wstrgettext(msg), guienv, texture_src, - dtime, percent, draw_sky); + dtime, percent, indef_pos); } void Game::settingChangedCallback(const std::string &setting_name, void *data) diff --git a/src/client/renderingengine.cpp b/src/client/renderingengine.cpp index 3dbb39f86..27ea2b76f 100644 --- a/src/client/renderingengine.cpp +++ b/src/client/renderingengine.cpp @@ -308,7 +308,7 @@ bool RenderingEngine::setWindowIcon() */ void RenderingEngine::draw_load_screen(const std::wstring &text, gui::IGUIEnvironment *guienv, ITextureSource *tsrc, float dtime, - int percent, bool sky) + int percent, float *indef_pos) { v2u32 screensize = getWindowSize(); @@ -322,18 +322,22 @@ void RenderingEngine::draw_load_screen(const std::wstring &text, auto *driver = get_video_driver(); - if (sky) { - driver->beginScene(true, true, RenderingEngine::MENU_SKY_COLOR); - if (g_settings->getBool("menu_clouds")) { - g_menuclouds->step(dtime * 3); - g_menucloudsmgr->drawAll(); - } - } else { - driver->beginScene(true, true, video::SColor(255, 0, 0, 0)); + driver->setFog(RenderingEngine::MENU_SKY_COLOR); + driver->beginScene(true, true, RenderingEngine::MENU_SKY_COLOR); + if (g_settings->getBool("menu_clouds")) { + g_menuclouds->step(dtime * 3); + g_menucloudsmgr->drawAll(); } + int percent_min = 0; + int percent_max = percent; + if (indef_pos) { + *indef_pos = fmodf(*indef_pos + (dtime * 50.0f), 140.0f); + percent_max = std::min((int) *indef_pos, 100); + percent_min = std::max((int) *indef_pos - 40, 0); + } // draw progress bar - if ((percent >= 0) && (percent <= 100)) { + if ((percent_min >= 0) && (percent_max <= 100)) { video::ITexture *progress_img = tsrc->getTexture("progress_bar.png"); video::ITexture *progress_img_bg = tsrc->getTexture("progress_bar_bg.png"); @@ -364,11 +368,11 @@ void RenderingEngine::draw_load_screen(const std::wstring &text, 0, 0, true); draw2DImageFilterScaled(get_video_driver(), progress_img, - core::rect(img_pos.X, img_pos.Y, - img_pos.X + (percent * imgW) / 100, + core::rect(img_pos.X + (percent_min * imgW) / 100, img_pos.Y, + img_pos.X + (percent_max * imgW) / 100, img_pos.Y + imgH), - core::rect(0, 0, - (percent * img_size.Width) / 100, + core::rect(percent_min * img_size.Width / 100, 0, + percent_max * img_size.Width / 100, img_size.Height), 0, 0, true); } diff --git a/src/client/renderingengine.h b/src/client/renderingengine.h index b8ae62fc4..684df1237 100644 --- a/src/client/renderingengine.h +++ b/src/client/renderingengine.h @@ -137,9 +137,11 @@ public: return m_device->getGUIEnvironment(); } + // If "indef_pos" is given, the value of "percent" is ignored and an indefinite + // progress bar is drawn. void draw_load_screen(const std::wstring &text, gui::IGUIEnvironment *guienv, ITextureSource *tsrc, - float dtime = 0, int percent = 0, bool sky = true); + float dtime = 0, int percent = 0, float *indef_pos = nullptr); void draw_scene(video::SColor skycolor, bool show_hud, bool draw_wield_tool, bool draw_crosshair); From b21a97434278eaeb8dfef806ab563f9f2b56842a Mon Sep 17 00:00:00 2001 From: sfence Date: Tue, 21 May 2024 15:38:12 +0200 Subject: [PATCH 23/67] Fix inventory: Quickly picking up item and placing it again no longer works (#14657) --- src/gui/guiFormSpecMenu.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/gui/guiFormSpecMenu.cpp b/src/gui/guiFormSpecMenu.cpp index 577e2ee68..2e54b32dc 100644 --- a/src/gui/guiFormSpecMenu.cpp +++ b/src/gui/guiFormSpecMenu.cpp @@ -4625,11 +4625,6 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) if (!m_left_dragging) break; - // Abort left-dragging - m_left_dragging = false; - m_client->inhibit_inventory_revert = false; - m_left_drag_stacks.clear(); - // Both the selected item and the hovered item need to be checked // because we don't know exactly when the double-click happened ItemStack slct; @@ -4658,6 +4653,12 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) } if (amount > 0) { + if (m_left_dragging) { + // Abort left-dragging + m_left_dragging = false; + m_client->inhibit_inventory_revert = false; + m_left_drag_stacks.clear(); + } IMoveAction *a = new IMoveAction(); a->count = amount; a->from_inv = s.inventoryloc; From 50092594732dbdfc519a12e48ec837ec88c6e031 Mon Sep 17 00:00:00 2001 From: Lars Mueller Date: Tue, 21 May 2024 15:22:29 +0200 Subject: [PATCH 24/67] Add unit test and feature flag for override_item --- builtin/game/features.lua | 1 + doc/lua_api.md | 2 ++ games/devtest/mods/unittests/misc.lua | 12 ++++++++++++ 3 files changed, 15 insertions(+) diff --git a/builtin/game/features.lua b/builtin/game/features.lua index 051d2aa2a..22bf1859d 100644 --- a/builtin/game/features.lua +++ b/builtin/game/features.lua @@ -41,6 +41,7 @@ core.features = { item_meta_range = true, node_interaction_actor = true, moveresult_new_pos = true, + override_item_remove_fields = true, } function core.has_feature(arg) diff --git a/doc/lua_api.md b/doc/lua_api.md index dca31e4b6..4eea2f7f3 100644 --- a/doc/lua_api.md +++ b/doc/lua_api.md @@ -5444,6 +5444,8 @@ Utilities node_interaction_actor = true, -- "new_pos" field in entity moveresult (5.9.0) moveresult_new_pos = true, + -- Allow removing definition fields in `minetest.override_item` + override_item_remove_fields = true, } ``` diff --git a/games/devtest/mods/unittests/misc.lua b/games/devtest/mods/unittests/misc.lua index 6ff5c7e84..4bd8002b9 100644 --- a/games/devtest/mods/unittests/misc.lua +++ b/games/devtest/mods/unittests/misc.lua @@ -254,3 +254,15 @@ local function test_gennotify_api() assert(#custom == 0, "custom ids not empty") end unittests.register("test_gennotify_api", test_gennotify_api) + +unittests.register("test_item_registration", function() + local itemname = "unittests:test_override_item" + minetest.register_item(itemname, {description = "foo"}) + assert(assert(minetest.registered_items[itemname]).description == "foo") + minetest.override_item(itemname, {description = "bar"}) + assert(assert(minetest.registered_items[itemname]).description == "bar") + minetest.override_item(itemname, {}, {"description"}) + assert(assert(minetest.registered_items[itemname]).description == nil) + minetest.unregister_item("unittests:test_override_item") + assert(minetest.registered_items["unittests:test_override_item"] == nil) +end) From 567f85752de80d89559ca6dcedf58d684dc71710 Mon Sep 17 00:00:00 2001 From: Lars Mueller Date: Tue, 21 May 2024 16:27:38 +0200 Subject: [PATCH 25/67] Fix broken unit test Also makes devtest unit test results a bit more prominent --- games/devtest/mods/unittests/init.lua | 28 ++++++++++++++++++---- games/devtest/mods/unittests/load_time.lua | 13 ++++++++++ games/devtest/mods/unittests/misc.lua | 12 ---------- 3 files changed, 37 insertions(+), 16 deletions(-) create mode 100644 games/devtest/mods/unittests/load_time.lua diff --git a/games/devtest/mods/unittests/init.lua b/games/devtest/mods/unittests/init.lua index 6b2cd7a79..1499ccacb 100644 --- a/games/devtest/mods/unittests/init.lua +++ b/games/devtest/mods/unittests/init.lua @@ -160,7 +160,7 @@ function unittests.run_all() -- Print stats assert(#unittests.list == counters.total) print(string.rep("+", 80)) - print(string.format("Unit Test Results: %s", + print(string.format("Devtest Unit Test Results: %s", counters.total == counters.passed and "PASSED" or "FAILED")) print(string.format(" %d / %d failed tests.", counters.total - counters.passed, counters.total)) @@ -185,22 +185,42 @@ dofile(modpath .. "/content_ids.lua") dofile(modpath .. "/metadata.lua") dofile(modpath .. "/raycast.lua") dofile(modpath .. "/inventory.lua") +dofile(modpath .. "/load_time.lua") -------------- +local function send_results(name, ok) + core.chat_send_player(name, + minetest.colorize(ok and "green" or "red", + (ok and "All devtest unit tests passed." or + "There were devtest unit test failures.") .. + " Check the console for detailed output.")) +end + if core.settings:get_bool("devtest_unittests_autostart", false) then + local test_results = nil core.after(0, function() + unittests.on_finished = function(ok) + for _, player in ipairs(minetest.get_connected_players()) do + send_results(player:get_player_name(), ok) + end + test_results = ok + end coroutine.wrap(unittests.run_all)() end) + minetest.register_on_joinplayer(function(player) + if test_results == nil then + return -- tests haven't completed yet + end + send_results(player:get_player_name(), test_results) + end) else core.register_chatcommand("unittests", { privs = {basic_privs=true}, description = "Runs devtest unittests (may modify player or map state)", func = function(name, param) unittests.on_finished = function(ok) - core.chat_send_player(name, - (ok and "All tests passed." or "There were test failures.") .. - " Check the console for detailed output.") + send_results(name, ok) end coroutine.wrap(unittests.run_all)() return true, "" diff --git a/games/devtest/mods/unittests/load_time.lua b/games/devtest/mods/unittests/load_time.lua new file mode 100644 index 000000000..d437fba06 --- /dev/null +++ b/games/devtest/mods/unittests/load_time.lua @@ -0,0 +1,13 @@ +-- Test item (un)registration and overriding +do + local itemname = "unittests:test_override_item" + minetest.register_craftitem(":" .. itemname, {description = "foo"}) + assert(assert(minetest.registered_items[itemname]).description == "foo") + minetest.override_item(itemname, {description = "bar"}) + assert(assert(minetest.registered_items[itemname]).description == "bar") + minetest.override_item(itemname, {}, {"description"}) + -- description has the empty string as a default + assert(assert(minetest.registered_items[itemname]).description == "") + minetest.unregister_item("unittests:test_override_item") + assert(minetest.registered_items["unittests:test_override_item"] == nil) +end diff --git a/games/devtest/mods/unittests/misc.lua b/games/devtest/mods/unittests/misc.lua index 4bd8002b9..6ff5c7e84 100644 --- a/games/devtest/mods/unittests/misc.lua +++ b/games/devtest/mods/unittests/misc.lua @@ -254,15 +254,3 @@ local function test_gennotify_api() assert(#custom == 0, "custom ids not empty") end unittests.register("test_gennotify_api", test_gennotify_api) - -unittests.register("test_item_registration", function() - local itemname = "unittests:test_override_item" - minetest.register_item(itemname, {description = "foo"}) - assert(assert(minetest.registered_items[itemname]).description == "foo") - minetest.override_item(itemname, {description = "bar"}) - assert(assert(minetest.registered_items[itemname]).description == "bar") - minetest.override_item(itemname, {}, {"description"}) - assert(assert(minetest.registered_items[itemname]).description == nil) - minetest.unregister_item("unittests:test_override_item") - assert(minetest.registered_items["unittests:test_override_item"] == nil) -end) From df8a600b228c93e0a2ab1ef40dfa250b0c994718 Mon Sep 17 00:00:00 2001 From: sfence Date: Tue, 21 May 2024 17:52:54 +0200 Subject: [PATCH 26/67] Fix glitch through ceiling with Sneak Glitch (#14332) --- src/client/localplayer.cpp | 15 +- src/collision.cpp | 305 ++++++++++++++++++++++--------------- src/collision.h | 7 +- 3 files changed, 196 insertions(+), 131 deletions(-) diff --git a/src/client/localplayer.cpp b/src/client/localplayer.cpp index 796c89306..da87e9b17 100644 --- a/src/client/localplayer.cpp +++ b/src/client/localplayer.cpp @@ -437,15 +437,18 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d, m_speed.Z = 0.0f; } - if (y_diff > 0 && m_speed.Y <= 0.0f && - (physics_override.sneak_glitch || y_diff < BS * 0.6f)) { + if (y_diff > 0 && m_speed.Y <= 0.0f) { // Move player to the maximal height when falling or when // the ledge is climbed on the next step. - // Smoothen the movement (based on 'position.Y = bmax.Y') - position.Y += y_diff * dtime * 22.0f + BS * 0.01f; - position.Y = std::min(position.Y, bmax.Y); - m_speed.Y = 0.0f; + v3f check_pos = position; + check_pos.Y += y_diff * dtime * 22.0f + BS * 0.01f; + if (y_diff < BS * 0.6f || (physics_override.sneak_glitch + && !collision_check_intersection(env, m_client, m_collisionbox, check_pos))) { + // Smoothen the movement (based on 'position.Y = bmax.Y') + position.Y = std::min(check_pos.Y, bmax.Y); + m_speed.Y = 0.0f; + } } // Allow jumping on node edges while sneaking diff --git a/src/collision.cpp b/src/collision.cpp index 2db0e127d..d804f7f0d 100644 --- a/src/collision.cpp +++ b/src/collision.cpp @@ -218,17 +218,131 @@ bool wouldCollideWithCeiling( return false; } +static bool add_area_node_boxes(const v3s16 min, const v3s16 max, IGameDef *gamedef, + Environment *env, std::vector &cinfo) +{ + const auto *nodedef = gamedef->getNodeDefManager(); + bool any_position_valid = false; + + thread_local std::vector nodeboxes; + Map *map = &env->getMap(); + + v3s16 p; + for (p.Z = min.Z; p.Z <= max.Z; p.Z++) + for (p.Y = min.Y; p.Y <= max.Y; p.Y++) + for (p.X = min.X; p.X <= max.X; p.X++) { + bool is_position_valid; + MapNode n = map->getNode(p, &is_position_valid); + + if (is_position_valid && n.getContent() != CONTENT_IGNORE) { + // Object collides into walkable nodes + + any_position_valid = true; + const ContentFeatures &f = nodedef->get(n); + + if (!f.walkable) + continue; + + // Negative bouncy may have a meaning, but we need +value here. + int n_bouncy_value = abs(itemgroup_get(f.groups, "bouncy")); + + u8 neighbors = n.getNeighbors(p, map); + + nodeboxes.clear(); + n.getCollisionBoxes(nodedef, &nodeboxes, neighbors); + + // Calculate float position only once + v3f posf = intToFloat(p, BS); + for (auto box : nodeboxes) { + box.MinEdge += posf; + box.MaxEdge += posf; + cinfo.emplace_back(false, n_bouncy_value, p, box); + } + } else { + // Collide with unloaded nodes (position invalid) and loaded + // CONTENT_IGNORE nodes (position valid) + aabb3f box = getNodeBox(p, BS); + cinfo.emplace_back(true, 0, p, box); + } + } + return any_position_valid; +} + +static void add_object_boxes(Environment *env, + const aabb3f &box_0, f32 dtime, + const v3f pos_f, const v3f speed_f, ActiveObject *self, + std::vector &cinfo) +{ + auto process_object = [&] (ActiveObject *object) { + if (object && object->collideWithObjects()) { + aabb3f box; + if (object->getCollisionBox(&box)) + cinfo.emplace_back(object, 0, box); + } + }; + + // Calculate distance by speed, add own extent and 1.5m of tolerance + const f32 distance = speed_f.getLength() * dtime + + box_0.getExtent().getLength() + 1.5f * BS; + +#ifndef SERVER + ClientEnvironment *c_env = dynamic_cast(env); + if (c_env) { + std::vector clientobjects; + c_env->getActiveObjects(pos_f, distance, clientobjects); + + for (auto &clientobject : clientobjects) { + // Do collide with everything but itself and the parent CAO + if (!self || (self != clientobject.obj && + self != clientobject.obj->getParent())) { + process_object(clientobject.obj); + } + } + + // add collision with local player + LocalPlayer *lplayer = c_env->getLocalPlayer(); + if (lplayer->getParent() == nullptr) { + aabb3f lplayer_collisionbox = lplayer->getCollisionbox(); + v3f lplayer_pos = lplayer->getPosition(); + lplayer_collisionbox.MinEdge += lplayer_pos; + lplayer_collisionbox.MaxEdge += lplayer_pos; + auto *obj = (ActiveObject*) lplayer->getCAO(); + cinfo.emplace_back(obj, 0, lplayer_collisionbox); + } + } + else +#endif + { + ServerEnvironment *s_env = dynamic_cast(env); + if (s_env) { + // search for objects which are not us, or we are not its parent. + // we directly process the object in this callback to avoid useless + // looping afterwards. + auto include_obj_cb = [self, &process_object] (ServerActiveObject *obj) { + if (!obj->isGone() && + (!self || (self != obj && self != obj->getParent()))) { + process_object(obj); + } + return false; + }; + + // nothing is put into this vector + std::vector s_objects; + s_env->getObjectsInsideRadius(s_objects, pos_f, distance, include_obj_cb); + } + } +} + +#define PROFILER_NAME(text) (dynamic_cast(env) ? ("Server: " text) : ("Client: " text)) + collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef, f32 pos_max_d, const aabb3f &box_0, f32 stepheight, f32 dtime, v3f *pos_f, v3f *speed_f, v3f accel_f, ActiveObject *self, - bool collideWithObjects) + bool collide_with_objects) { - #define PROFILER_NAME(text) (s_env ? ("Server: " text) : ("Client: " text)) static bool time_notification_done = false; - Map *map = &env->getMap(); - ServerEnvironment *s_env = dynamic_cast(env); ScopeProfiler sp(g_profiler, PROFILER_NAME("collisionMoveSimple()"), SPT_AVG, PRECISION_MICRO); @@ -272,134 +386,36 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef, cinfo.clear(); { - v3f minpos_f( - MYMIN(pos_f->X, newpos_f.X), - MYMIN(pos_f->Y, newpos_f.Y) + 0.01f * BS, // bias rounding, player often at +/-n.5 - MYMIN(pos_f->Z, newpos_f.Z) - ); - v3f maxpos_f( - MYMAX(pos_f->X, newpos_f.X), - MYMAX(pos_f->Y, newpos_f.Y), - MYMAX(pos_f->Z, newpos_f.Z) - ); - v3s16 min = floatToInt(minpos_f + box_0.MinEdge, BS) - v3s16(1, 1, 1); - v3s16 max = floatToInt(maxpos_f + box_0.MaxEdge, BS) + v3s16(1, 1, 1); + v3f minpos_f( + MYMIN(pos_f->X, newpos_f.X), + MYMIN(pos_f->Y, newpos_f.Y) + 0.01f * BS, // bias rounding, player often at +/-n.5 + MYMIN(pos_f->Z, newpos_f.Z) + ); + v3f maxpos_f( + MYMAX(pos_f->X, newpos_f.X), + MYMAX(pos_f->Y, newpos_f.Y), + MYMAX(pos_f->Z, newpos_f.Z) + ); + v3s16 min = floatToInt(minpos_f + box_0.MinEdge, BS) - v3s16(1, 1, 1); + v3s16 max = floatToInt(maxpos_f + box_0.MaxEdge, BS) + v3s16(1, 1, 1); - const auto *nodedef = gamedef->getNodeDefManager(); - bool any_position_valid = false; + bool any_position_valid = add_area_node_boxes(min, max, gamedef, env, cinfo); - thread_local std::vector nodeboxes; - - v3s16 p; - for (p.Z = min.Z; p.Z <= max.Z; p.Z++) - for (p.Y = min.Y; p.Y <= max.Y; p.Y++) - for (p.X = min.X; p.X <= max.X; p.X++) { - bool is_position_valid; - MapNode n = map->getNode(p, &is_position_valid); - - if (is_position_valid && n.getContent() != CONTENT_IGNORE) { - // Object collides into walkable nodes - - any_position_valid = true; - const ContentFeatures &f = nodedef->get(n); - - if (!f.walkable) - continue; - - // Negative bouncy may have a meaning, but we need +value here. - int n_bouncy_value = abs(itemgroup_get(f.groups, "bouncy")); - - u8 neighbors = n.getNeighbors(p, map); - - nodeboxes.clear(); - n.getCollisionBoxes(nodedef, &nodeboxes, neighbors); - - // Calculate float position only once - v3f posf = intToFloat(p, BS); - for (auto box : nodeboxes) { - box.MinEdge += posf; - box.MaxEdge += posf; - cinfo.emplace_back(false, n_bouncy_value, p, box); - } - } else { - // Collide with unloaded nodes (position invalid) and loaded - // CONTENT_IGNORE nodes (position valid) - aabb3f box = getNodeBox(p, BS); - cinfo.emplace_back(true, 0, p, box); + // Do not move if world has not loaded yet, since custom node boxes + // are not available for collision detection. + // This also intentionally occurs in the case of the object being positioned + // solely on loaded CONTENT_IGNORE nodes, no matter where they come from. + if (!any_position_valid) { + *speed_f = v3f(0, 0, 0); + return result; } } - // Do not move if world has not loaded yet, since custom node boxes - // are not available for collision detection. - // This also intentionally occurs in the case of the object being positioned - // solely on loaded CONTENT_IGNORE nodes, no matter where they come from. - if (!any_position_valid) { - *speed_f = v3f(0, 0, 0); - return result; - } - - } - /* Collect object boxes in movement range */ - - auto process_object = [] (ActiveObject *object) { - if (object && object->collideWithObjects()) { - aabb3f box; - if (object->getCollisionBox(&box)) - cinfo.emplace_back(object, 0, box); - } - }; - - if (collideWithObjects) { - // Calculate distance by speed, add own extent and 1.5m of tolerance - const f32 distance = speed_f->getLength() * dtime + - box_0.getExtent().getLength() + 1.5f * BS; - -#ifndef SERVER - ClientEnvironment *c_env = dynamic_cast(env); - if (c_env) { - std::vector clientobjects; - c_env->getActiveObjects(*pos_f, distance, clientobjects); - - for (auto &clientobject : clientobjects) { - // Do collide with everything but itself and the parent CAO - if (!self || (self != clientobject.obj && - self != clientobject.obj->getParent())) { - process_object(clientobject.obj); - } - } - - // add collision with local player - LocalPlayer *lplayer = c_env->getLocalPlayer(); - if (lplayer->getParent() == nullptr) { - aabb3f lplayer_collisionbox = lplayer->getCollisionbox(); - v3f lplayer_pos = lplayer->getPosition(); - lplayer_collisionbox.MinEdge += lplayer_pos; - lplayer_collisionbox.MaxEdge += lplayer_pos; - auto *obj = (ActiveObject*) lplayer->getCAO(); - cinfo.emplace_back(obj, 0, lplayer_collisionbox); - } - } - else -#endif - if (s_env) { - // search for objects which are not us, or we are not its parent. - // we directly process the object in this callback to avoid useless - // looping afterwards. - auto include_obj_cb = [self, &process_object] (ServerActiveObject *obj) { - if (!obj->isGone() && - (!self || (self != obj && self != obj->getParent()))) { - process_object(obj); - } - return false; - }; - - // nothing is put into this vector - std::vector s_objects; - s_env->getObjectsInsideRadius(s_objects, *pos_f, distance, include_obj_cb); - } + if (collide_with_objects) { + add_object_boxes(env, box_0, dtime, *pos_f, *speed_f, self, cinfo); } /* @@ -579,3 +595,44 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef, return result; } + +bool collision_check_intersection(Environment *env, IGameDef *gamedef, + const aabb3f &box_0, const v3f &pos_f, ActiveObject *self, + bool collide_with_objects) +{ + ScopeProfiler sp(g_profiler, PROFILER_NAME("collision_check_intersection()"), SPT_AVG, PRECISION_MICRO); + + std::vector cinfo; + { + v3s16 min = floatToInt(pos_f + box_0.MinEdge, BS) - v3s16(1, 1, 1); + v3s16 max = floatToInt(pos_f + box_0.MaxEdge, BS) + v3s16(1, 1, 1); + + bool any_position_valid = add_area_node_boxes(min, max, gamedef, env, cinfo); + + if (!any_position_valid) { + return true; + } + } + + if (collide_with_objects) { + v3f speed; + add_object_boxes(env, box_0, 0, pos_f, speed, self, cinfo); + } + + /* + Collision detection + */ + aabb3f checkbox = box_0; + checkbox.MinEdge += pos_f; + checkbox.MaxEdge += pos_f; + + /* + Go through every node and object box + */ + for (const NearbyCollisionInfo &box_info : cinfo) { + if (box_info.box.intersectsWithBox(checkbox)) + return true; + } + + return false; +} diff --git a/src/collision.h b/src/collision.h index 042970f32..b29a222c3 100644 --- a/src/collision.h +++ b/src/collision.h @@ -71,7 +71,12 @@ collisionMoveResult collisionMoveSimple(Environment *env,IGameDef *gamedef, f32 stepheight, f32 dtime, v3f *pos_f, v3f *speed_f, v3f accel_f, ActiveObject *self=NULL, - bool collideWithObjects=true); + bool collide_with_objects=true); + +// check if box is in collision on actual position +bool collision_check_intersection(Environment *env, IGameDef *gamedef, + const aabb3f &box_0, const v3f &pos_f, ActiveObject *self = nullptr, + bool collide_with_objects = true); // Helper function: // Checks for collision of a moving aabbox with a static aabbox From bd4572cfd129aa17b79f50f8c08719781d288e5e Mon Sep 17 00:00:00 2001 From: Lars Mueller Date: Tue, 21 May 2024 17:32:58 +0200 Subject: [PATCH 27/67] Fix broken CI --- games/devtest/mods/unittests/init.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/games/devtest/mods/unittests/init.lua b/games/devtest/mods/unittests/init.lua index 1499ccacb..47568d9fc 100644 --- a/games/devtest/mods/unittests/init.lua +++ b/games/devtest/mods/unittests/init.lua @@ -200,11 +200,15 @@ end if core.settings:get_bool("devtest_unittests_autostart", false) then local test_results = nil core.after(0, function() + -- CI adds a mod which sets `unittests.on_finished` + -- to write status information to the filesystem + local old_on_finished = unittests.on_finished unittests.on_finished = function(ok) for _, player in ipairs(minetest.get_connected_players()) do send_results(player:get_player_name(), ok) end test_results = ok + old_on_finished(ok) end coroutine.wrap(unittests.run_all)() end) From a078cfee3ec3800c692f5a1a8800d3668d7ee3a1 Mon Sep 17 00:00:00 2001 From: Xeno333 <149852758+Xeno333@users.noreply.github.com> Date: Wed, 22 May 2024 09:46:05 -0500 Subject: [PATCH 28/67] Rename "opaque_water" setting to "translucent_liquids" with inverted meaning (#14660) The old setting will be migrated properly. --------- Co-authored-by: grorp --- builtin/settingtypes.txt | 4 ++-- src/defaultsettings.cpp | 2 +- src/main.cpp | 3 +++ src/migratesettings.h | 14 ++++++++++++++ src/nodedef.cpp | 8 ++++---- src/nodedef.h | 2 +- 6 files changed, 25 insertions(+), 8 deletions(-) create mode 100644 src/migratesettings.h diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index b43c938ae..8dc37c3e7 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -265,8 +265,8 @@ undersampling (Undersampling) int 1 1 8 [**Graphics Effects] -# Makes all liquids opaque -opaque_water (Opaque liquids) bool false +# Allows liquids to be translucent. +translucent_liquids (Translucent liquids) bool true # Leaves style: # - Fancy: all faces visible diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 6c0d4b4cc..378d09759 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -282,7 +282,7 @@ void set_default_settings() settings->setDefault("enable_3d_clouds", "true"); settings->setDefault("cloud_radius", "12"); settings->setDefault("menu_clouds", "true"); - settings->setDefault("opaque_water", "false"); + settings->setDefault("translucent_liquids", "true"); settings->setDefault("console_height", "0.6"); settings->setDefault("console_color", "(0,0,0)"); settings->setDefault("console_alpha", "200"); diff --git a/src/main.cpp b/src/main.cpp index d693a6b5c..7f078d9b2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "filesys.h" #include "version.h" #include "defaultsettings.h" +#include "migratesettings.h" #include "gettext.h" #include "log.h" #include "util/quicktune.h" @@ -687,6 +688,8 @@ static bool init_common(const Settings &cmd_args, int argc, char *argv[]) if (!read_config_file(cmd_args)) return false; + migrate_settings(); + init_log_streams(cmd_args); // Initialize random seed diff --git a/src/migratesettings.h b/src/migratesettings.h new file mode 100644 index 000000000..60435f18a --- /dev/null +++ b/src/migratesettings.h @@ -0,0 +1,14 @@ +// Minetest +// SPDX-License-Identifier: LGPL-2.1-or-later + +#include "settings.h" + +void migrate_settings() +{ + // Converts opaque_water to translucent_liquids + if (g_settings->existsLocal("opaque_water")) { + g_settings->set("translucent_liquids", + g_settings->getBool("opaque_water") ? "false" : "true"); + g_settings->remove("opaque_water"); + } +} diff --git a/src/nodedef.cpp b/src/nodedef.cpp index 1ce0a5c74..2914cc3aa 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -283,7 +283,7 @@ void TileDef::deSerialize(std::istream &is, NodeDrawType drawtype, u16 protocol_ void TextureSettings::readSettings() { connected_glass = g_settings->getBool("connected_glass"); - opaque_water = g_settings->getBool("opaque_water"); + translucent_liquids = g_settings->getBool("translucent_liquids"); bool smooth_lighting = g_settings->getBool("smooth_lighting"); enable_mesh_cache = g_settings->getBool("enable_mesh_cache"); enable_minimap = g_settings->getBool("enable_minimap"); @@ -683,7 +683,7 @@ void ContentFeatures::deSerialize(std::istream &is, u16 protocol_version) if (is.eof()) throw SerializationError(""); post_effect_color_shaded = tmp; - } catch(SerializationError &e) {}; + } catch (SerializationError &e) {}; } #ifndef SERVER @@ -825,14 +825,14 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc solidness = 0; break; case NDT_LIQUID: - if (tsettings.opaque_water) + if (!tsettings.translucent_liquids) alpha = ALPHAMODE_OPAQUE; solidness = 1; is_liquid = true; break; case NDT_FLOWINGLIQUID: solidness = 0; - if (tsettings.opaque_water) + if (!tsettings.translucent_liquids) alpha = ALPHAMODE_OPAQUE; is_liquid = true; break; diff --git a/src/nodedef.h b/src/nodedef.h index f493d48c4..de713a1ad 100644 --- a/src/nodedef.h +++ b/src/nodedef.h @@ -184,7 +184,7 @@ public: WorldAlignMode world_aligned_mode; AutoScale autoscale_mode; int node_texture_size; - bool opaque_water; + bool translucent_liquids; bool connected_glass; bool enable_mesh_cache; bool enable_minimap; From 12983748187c46a37a12e37f72c75b84bf33ca8b Mon Sep 17 00:00:00 2001 From: JosiahWI <41302989+JosiahWI@users.noreply.github.com> Date: Wed, 22 May 2024 11:39:53 -0500 Subject: [PATCH 29/67] Upgrade client active object mgr tests to Catch2 (#14565) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Upgrade client active object mgr tests to Catch2 In addition to invoking Catch2's test runner after Minetest's homemade runner, this refactors the tests to follow the DRY principle, and gives them expressive names and clear assertions. Catch2 is already bundled with Minetest, so there are no added dependencies. * Increment failed modules count for Catch2 tests * Respect --test-module option for Catch2 tests * Improve Catch2 --test-module behavior This switches infostream to rawstream so that test runner output is displayed, and returns the correct boolean depending on the results. The tests are now found by setting the configuration instead of invoking the command line parser. * Test uniqueness of all IDS instead of just one Co-Authored-By: Lars Müller * Include Catch2 test run in timing and logging * Flush std::cout after printing Catch results * Increment total tests run instead of hardcoding to 1 * Flush stderr before printing to stdout It's necessary to flush stderr before printing to stdout in adition to flushing stdout before printing to stderr, to make sure all output is ordered correctly. * Make Catch write to rawstream --------- Co-authored-by: Lars Müller --- CMakeLists.txt | 2 +- lib/catch2/CMakeLists.txt | 3 +- src/CMakeLists.txt | 8 +- src/activeobjectmgr.h | 1 - src/unittest/test.cpp | 37 +++++- src/unittest/test_clientactiveobjectmgr.cpp | 119 ++++++++++---------- 6 files changed, 101 insertions(+), 69 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b8254db7f..4c6c60ba9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -278,7 +278,7 @@ if(NOT USE_LUAJIT) add_subdirectory(lib/bitop) endif() -if(BUILD_BENCHMARKS) +if(BUILD_UNITTESTS OR BUILD_BENCHMARKS) add_subdirectory(lib/catch2) endif() diff --git a/lib/catch2/CMakeLists.txt b/lib/catch2/CMakeLists.txt index 3c471d49d..077272571 100644 --- a/lib/catch2/CMakeLists.txt +++ b/lib/catch2/CMakeLists.txt @@ -13,4 +13,5 @@ # + return os << std::fixed << duration.value() << ' ' << duration.unitsAsString(); add_library(catch2 INTERFACE) -target_include_directories(catch2 INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) +add_library(Catch2::Catch2 ALIAS catch2) +target_include_directories(catch2 INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bad7e2afb..6ea544980 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -615,8 +615,8 @@ if(BUILD_CLIENT) if (USE_SPATIAL) target_link_libraries(${PROJECT_NAME} ${SPATIAL_LIBRARY}) endif() - if(BUILD_BENCHMARKS) - target_link_libraries(${PROJECT_NAME} catch2) + if(BUILD_UNITTESTS OR BUILD_BENCHMARKS) + target_link_libraries(${PROJECT_NAME} Catch2::Catch2) endif() endif(BUILD_CLIENT) @@ -677,8 +677,8 @@ if(BUILD_SERVER) ${CURL_LIBRARY} ) endif() - if(BUILD_BENCHMARKS) - target_link_libraries(${PROJECT_NAME}server catch2) + if(BUILD_UNITTESTS OR BUILD_BENCHMARKS) + target_link_libraries(${PROJECT_NAME}server Catch2::Catch2) endif() endif(BUILD_SERVER) diff --git a/src/activeobjectmgr.h b/src/activeobjectmgr.h index 0205aee85..369e8acf5 100644 --- a/src/activeobjectmgr.h +++ b/src/activeobjectmgr.h @@ -31,7 +31,6 @@ class TestServerActiveObjectMgr; template class ActiveObjectMgr { - friend class ::TestClientActiveObjectMgr; friend class ::TestServerActiveObjectMgr; public: diff --git a/src/unittest/test.cpp b/src/unittest/test.cpp index 7141ee0c6..2fbba5e4a 100644 --- a/src/unittest/test.cpp +++ b/src/unittest/test.cpp @@ -17,6 +17,11 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#define CATCH_CONFIG_RUNNER +// we want to have catch write to rawstream (stderr) instead of stdout +#define CATCH_CONFIG_NOSTDOUT +#include + #include "test.h" #include "nodedef.h" @@ -27,6 +32,21 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "porting.h" #include "debug.h" +#include + +// make catch write everything to rawstream +namespace Catch { + std::ostream& cout() { + return rawstream; + } + std::ostream& clog() { + return rawstream; + } + std::ostream& cerr() { + return rawstream; + } +} + content_t t_CONTENT_STONE; content_t t_CONTENT_GRASS; content_t t_CONTENT_TORCH; @@ -234,6 +254,16 @@ bool run_tests() num_total_tests_run += testmod->num_tests_run; } + rawstream << "Catch test results: " << std::endl; + auto num_catch_tests_failed = Catch::Session().run(); + // We count the all the Catch tests as one test for Minetest's own logging + // because we don't have a way to tell how many individual tests Catch ran. + ++num_total_tests_run; + if (num_catch_tests_failed > 0) { + ++num_modules_failed; + ++num_total_tests_failed; + } + u64 tdiff = porting::getTimeMs() - t1; g_logger.setLevelSilenced(LL_ERROR, false); @@ -269,8 +299,11 @@ bool run_tests(const std::string &module_name) auto testmod = findTestModule(module_name); if (!testmod) { - errorstream << "Test module not found: " << module_name << std::endl; - return 1; + rawstream << "Did not find module, searching Catch tests: " << module_name << std::endl; + Catch::Session session; + session.configData().testsOrTags.push_back(module_name); + auto catch_test_failures = session.run(); + return catch_test_failures == 0; } g_logger.setLevelSilenced(LL_ERROR, true); diff --git a/src/unittest/test_clientactiveobjectmgr.cpp b/src/unittest/test_clientactiveobjectmgr.cpp index d3cd83dc9..2df099fb1 100644 --- a/src/unittest/test_clientactiveobjectmgr.cpp +++ b/src/unittest/test_clientactiveobjectmgr.cpp @@ -17,11 +17,14 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "client/activeobjectmgr.h" -#include #include "test.h" -#include "profiler.h" +#include "client/activeobjectmgr.h" + +#include + +#include +#include class TestClientActiveObject : public ClientActiveObject { @@ -58,9 +61,6 @@ public: void runTests(IGameDef *gamedef); - void testFreeID(); - void testRegisterObject(); - void testRemoveObject(); void testGetActiveSelectableObjects(); }; @@ -68,75 +68,74 @@ static TestClientActiveObjectMgr g_test_instance; void TestClientActiveObjectMgr::runTests(IGameDef *gamedef) { - TEST(testFreeID); - TEST(testRegisterObject) - TEST(testRemoveObject) TEST(testGetActiveSelectableObjects) } //////////////////////////////////////////////////////////////////////////////// -void TestClientActiveObjectMgr::testFreeID() +static TestClientActiveObject* register_default_test_object( + client::ActiveObjectMgr &caomgr) { + auto test_obj = std::make_unique(); + auto result = test_obj.get(); + REQUIRE(caomgr.registerObject(std::move(test_obj))); + return result; +} + +TEST_CASE("test client active object manager") { client::ActiveObjectMgr caomgr; - std::vector aoids; + auto tcao1 = register_default_test_object(caomgr); - u16 aoid = caomgr.getFreeId(); - // Ensure it's not the same id - UASSERT(caomgr.getFreeId() != aoid); - - aoids.push_back(aoid); - - // Register basic objects, ensure we never found - for (u8 i = 0; i < UINT8_MAX; i++) { - // Register an object - auto tcao_u = std::make_unique(); - auto tcao = tcao_u.get(); - caomgr.registerObject(std::move(tcao_u)); - aoids.push_back(tcao->getId()); - - // Ensure next id is not in registered list - UASSERT(std::find(aoids.begin(), aoids.end(), caomgr.getFreeId()) == - aoids.end()); + SECTION("When we register many client objects, " + "then all the assigned IDs should be unique.") + { + // This should be enough rounds to be pretty confident + // there are no duplicates. + u16 n = 255; + std::unordered_set ids; + ids.insert(tcao1->getId()); + for (u16 i = 0; i < n; ++i) { + auto other_tcao = register_default_test_object(caomgr); + ids.insert(other_tcao->getId()); + } + // n added objects & tcao1 + CHECK(n + 1 == static_cast(ids.size())); } - caomgr.clear(); -} + SECTION("two registered objects") + { + auto tcao2 = register_default_test_object(caomgr); + auto tcao2_id = tcao2->getId(); -void TestClientActiveObjectMgr::testRegisterObject() -{ - client::ActiveObjectMgr caomgr; - auto tcao_u = std::make_unique(); - auto tcao = tcao_u.get(); - UASSERT(caomgr.registerObject(std::move(tcao_u))); + auto obj1 = caomgr.getActiveObject(tcao1->getId()); + REQUIRE(obj1 != nullptr); - u16 id = tcao->getId(); + auto obj2 = caomgr.getActiveObject(tcao2_id); + REQUIRE(obj2 != nullptr); - auto tcaoToCompare = caomgr.getActiveObject(id); - UASSERT(tcaoToCompare->getId() == id); - UASSERT(tcaoToCompare == tcao); + SECTION("When we query an object by its ID, " + "then we should get back an object with that ID.") + { + CHECK(obj1->getId() == tcao1->getId()); + CHECK(obj2->getId() == tcao2->getId()); + } - tcao_u = std::make_unique(); - tcao = tcao_u.get(); - UASSERT(caomgr.registerObject(std::move(tcao_u))); - UASSERT(caomgr.getActiveObject(tcao->getId()) == tcao); - UASSERT(caomgr.getActiveObject(tcao->getId()) != tcaoToCompare); + SECTION("When we register and query for an object, " + "its memory location should not have changed.") + { + CHECK(obj1 == tcao1); + CHECK(obj2 == tcao2); + } + } - caomgr.clear(); -} - -void TestClientActiveObjectMgr::testRemoveObject() -{ - client::ActiveObjectMgr caomgr; - auto tcao_u = std::make_unique(); - auto tcao = tcao_u.get(); - UASSERT(caomgr.registerObject(std::move(tcao_u))); - - u16 id = tcao->getId(); - UASSERT(caomgr.getActiveObject(id) != nullptr) - - caomgr.removeObject(tcao->getId()); - UASSERT(caomgr.getActiveObject(id) == nullptr) + SECTION("Given an object has been removed, " + "when we query for it, " + "then we should get nullptr.") + { + auto id = tcao1->getId(); + caomgr.removeObject(tcao1->getId()); // may invalidate tcao1 + CHECK(caomgr.getActiveObject(id) == nullptr); + } caomgr.clear(); } From bc60693a5d55bcf25bedda8d33d6e4e5c0e0d111 Mon Sep 17 00:00:00 2001 From: grorp Date: Thu, 23 May 2024 20:36:01 +0200 Subject: [PATCH 30/67] Enable "FULL" debug info for Android build (#14684) --- android/native/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/native/build.gradle b/android/native/build.gradle index 705d14f82..96a7739c0 100644 --- a/android/native/build.gradle +++ b/android/native/build.gradle @@ -36,7 +36,7 @@ android { buildTypes { release { ndk { - debugSymbolLevel 'SYMBOL_TABLE' + debugSymbolLevel 'FULL' } } } From 6c0b8229ecc8da7109ca471db8480a345abdf426 Mon Sep 17 00:00:00 2001 From: grorp Date: Thu, 23 May 2024 20:36:13 +0200 Subject: [PATCH 31/67] Fix artifacts with bloom + tonemapping on ogles2 (#14688) --- client/shaders/second_stage/opengl_fragment.glsl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/shaders/second_stage/opengl_fragment.glsl b/client/shaders/second_stage/opengl_fragment.glsl index 3b0d4c844..0a73aa393 100644 --- a/client/shaders/second_stage/opengl_fragment.glsl +++ b/client/shaders/second_stage/opengl_fragment.glsl @@ -61,7 +61,8 @@ vec4 applyBloom(vec4 color, vec2 uv) equation used: ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F */ -vec3 uncharted2Tonemap(vec3 x) +// see https://github.com/minetest/minetest/pull/14688 +highp vec3 uncharted2Tonemap(highp vec3 x) { return ((x * (0.22 * x + 0.03) + 0.002) / (x * (0.22 * x + 0.3) + 0.06)) - 0.03333; } From d5fc040d2df2d31acb454c000b38b95860b039cf Mon Sep 17 00:00:00 2001 From: grorp Date: Fri, 24 May 2024 12:10:19 +0200 Subject: [PATCH 32/67] Consistent width for internal scrollbars of formspec elements (#14689) also: Make sure that very short, wide scrollbars are still usable --- src/client/clientlauncher.cpp | 2 +- src/gui/guiScrollBar.cpp | 4 ++-- src/gui/guiTable.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/client/clientlauncher.cpp b/src/client/clientlauncher.cpp index 52fadb192..da8118a7e 100644 --- a/src/client/clientlauncher.cpp +++ b/src/client/clientlauncher.cpp @@ -343,7 +343,7 @@ void ClientLauncher::init_guienv(gui::IGUIEnvironment *guienv) float density = rangelim(g_settings->getFloat("gui_scaling"), 0.5f, 20) * RenderingEngine::getDisplayDensity(); skin->setSize(gui::EGDS_CHECK_BOX_WIDTH, (s32)(17.0f * density)); - skin->setSize(gui::EGDS_SCROLLBAR_SIZE, (s32)(14.0f * density)); + skin->setSize(gui::EGDS_SCROLLBAR_SIZE, (s32)(21.0f * density)); skin->setSize(gui::EGDS_WINDOW_BUTTON_WIDTH, (s32)(15.0f * density)); if (density > 1.5f) { std::string sprite_path = porting::path_share + "/textures/base/pack/"; diff --git a/src/gui/guiScrollBar.cpp b/src/gui/guiScrollBar.cpp index 88f101a2b..8e8935b2d 100644 --- a/src/gui/guiScrollBar.cpp +++ b/src/gui/guiScrollBar.cpp @@ -274,10 +274,10 @@ void GUIScrollBar::setPosRaw(const s32 &pos) s32 thumb_min = 0; if (is_horizontal) { - thumb_min = RelativeRect.getHeight(); + thumb_min = std::min(RelativeRect.getHeight(), RelativeRect.getWidth() / 2); thumb_area = RelativeRect.getWidth() - border_size * 2; } else { - thumb_min = RelativeRect.getWidth(); + thumb_min = std::min(RelativeRect.getWidth(), RelativeRect.getHeight() / 2); thumb_area = RelativeRect.getHeight() - border_size * 2; } diff --git a/src/gui/guiTable.cpp b/src/gui/guiTable.cpp index 498090413..93a56ed3c 100644 --- a/src/gui/guiTable.cpp +++ b/src/gui/guiTable.cpp @@ -60,7 +60,7 @@ GUITable::GUITable(gui::IGUIEnvironment *env, m_rowheight = MYMAX(m_rowheight, 1); } - const s32 s = skin->getSize(gui::EGDS_SCROLLBAR_SIZE) * 1.5f; + const s32 s = skin->getSize(gui::EGDS_SCROLLBAR_SIZE); m_scrollbar = new GUIScrollBar(Environment, this, -1, core::rect(RelativeRect.getWidth() - s, 0, From 728f643ea76278dcf89f9ac066062e7b895e46c8 Mon Sep 17 00:00:00 2001 From: grorp Date: Fri, 24 May 2024 12:10:46 +0200 Subject: [PATCH 33/67] Scale C++ menus down to fit the window (#14690) --- src/gui/guiKeyChangeMenu.cpp | 10 +++------- src/gui/guiOpenURL.cpp | 10 +++------- src/gui/guiPasswordChange.cpp | 11 +++-------- src/gui/guiVolumeChange.cpp | 10 +++------- src/gui/modalMenu.cpp | 14 ++++++++++++++ src/gui/modalMenu.h | 6 ++++++ 6 files changed, 32 insertions(+), 29 deletions(-) diff --git a/src/gui/guiKeyChangeMenu.cpp b/src/gui/guiKeyChangeMenu.cpp index 3d8c13e5e..b8c1143f2 100644 --- a/src/gui/guiKeyChangeMenu.cpp +++ b/src/gui/guiKeyChangeMenu.cpp @@ -107,13 +107,9 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize) removeAllChildren(); key_used_text = nullptr; - const float s = m_gui_scale; - DesiredRect = core::rect( - screensize.X / 2 - 835 * s / 2, - screensize.Y / 2 - 430 * s / 2, - screensize.X / 2 + 835 * s / 2, - screensize.Y / 2 + 430 * s / 2 - ); + ScalingInfo info = getScalingInfo(screensize, v2u32(835, 430)); + const float s = info.scale; + DesiredRect = info.rect; recalculateAbsolutePosition(false); v2s32 size = DesiredRect.getSize(); diff --git a/src/gui/guiOpenURL.cpp b/src/gui/guiOpenURL.cpp index 33be88162..f20d8ba7b 100644 --- a/src/gui/guiOpenURL.cpp +++ b/src/gui/guiOpenURL.cpp @@ -66,13 +66,9 @@ void GUIOpenURLMenu::regenerateGui(v2u32 screensize) /* Calculate new sizes and positions */ - const float s = m_gui_scale; - DesiredRect = core::rect( - screensize.X / 2 - 580 * s / 2, - screensize.Y / 2 - 250 * s / 2, - screensize.X / 2 + 580 * s / 2, - screensize.Y / 2 + 250 * s / 2 - ); + ScalingInfo info = getScalingInfo(screensize, v2u32(580, 250)); + const float s = info.scale; + DesiredRect = info.rect; recalculateAbsolutePosition(false); v2s32 size = DesiredRect.getSize(); diff --git a/src/gui/guiPasswordChange.cpp b/src/gui/guiPasswordChange.cpp index 6b0c0063d..d3c1867a8 100644 --- a/src/gui/guiPasswordChange.cpp +++ b/src/gui/guiPasswordChange.cpp @@ -62,14 +62,9 @@ void GUIPasswordChange::regenerateGui(v2u32 screensize) /* Calculate new sizes and positions */ - const float s = m_gui_scale; - - DesiredRect = core::rect( - screensize.X / 2 - 580 * s / 2, - screensize.Y / 2 - 300 * s / 2, - screensize.X / 2 + 580 * s / 2, - screensize.Y / 2 + 300 * s / 2 - ); + ScalingInfo info = getScalingInfo(screensize, v2u32(580, 300)); + const float s = info.scale; + DesiredRect = info.rect; recalculateAbsolutePosition(false); v2s32 size = DesiredRect.getSize(); diff --git a/src/gui/guiVolumeChange.cpp b/src/gui/guiVolumeChange.cpp index 3043a27a8..a6608dd18 100644 --- a/src/gui/guiVolumeChange.cpp +++ b/src/gui/guiVolumeChange.cpp @@ -54,13 +54,9 @@ void GUIVolumeChange::regenerateGui(v2u32 screensize) /* Calculate new sizes and positions */ - const float s = m_gui_scale; - DesiredRect = core::rect( - screensize.X / 2 - 380 * s / 2, - screensize.Y / 2 - 200 * s / 2, - screensize.X / 2 + 380 * s / 2, - screensize.Y / 2 + 200 * s / 2 - ); + ScalingInfo info = getScalingInfo(screensize, v2u32(380, 200)); + const float s = info.scale; + DesiredRect = info.rect; recalculateAbsolutePosition(false); v2s32 size = DesiredRect.getSize(); diff --git a/src/gui/modalMenu.cpp b/src/gui/modalMenu.cpp index d95311035..00bc143bb 100644 --- a/src/gui/modalMenu.cpp +++ b/src/gui/modalMenu.cpp @@ -398,3 +398,17 @@ porting::AndroidDialogState GUIModalMenu::getAndroidUIInputState() return porting::getInputDialogState(); } #endif + +GUIModalMenu::ScalingInfo GUIModalMenu::getScalingInfo(v2u32 screensize, v2u32 base_size) +{ + f32 scale = m_gui_scale; + scale = std::min(scale, (f32)screensize.X / (f32)base_size.X); + scale = std::min(scale, (f32)screensize.Y / (f32)base_size.Y); + s32 w = base_size.X * scale, h = base_size.Y * scale; + return {scale, core::rect( + screensize.X / 2 - w / 2, + screensize.Y / 2 - h / 2, + screensize.X / 2 + w / 2, + screensize.Y / 2 + h / 2 + )}; +} diff --git a/src/gui/modalMenu.h b/src/gui/modalMenu.h index 7ee8531d0..071024120 100644 --- a/src/gui/modalMenu.h +++ b/src/gui/modalMenu.h @@ -94,6 +94,12 @@ protected: std::string m_jni_field_name; #endif + struct ScalingInfo { + f32 scale; + core::rect rect; + }; + ScalingInfo getScalingInfo(v2u32 screensize, v2u32 base_size); + // This is set to true if the menu is currently processing a second-touch event. bool m_second_touch = false; // This is set to true if the menu is currently processing a mouse event From 82790b15567d4dd550c3a9ec27a26f7cb9c94f61 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Sun, 26 May 2024 14:28:12 +0200 Subject: [PATCH 34/67] Add documentation for IDE developer setup (#13935) --- .gitignore | 9 +- .vscode/extensions.json | 5 ++ CMakePresets.json | 41 +++++++++ doc/ides/images/jetbrains_cmake_profiles.png | Bin 0 -> 109456 bytes doc/ides/images/jetbrains_ide.png | Bin 0 -> 78742 bytes .../jetbrains_notification_profiles.png | Bin 0 -> 4977 bytes ...jetbrains_open_project_wizard_profiles.png | Bin 0 -> 67392 bytes ...ains_open_project_wizard_windows_cmake.png | Bin 0 -> 64227 bytes ...s_open_project_wizard_windows_compiler.png | Bin 0 -> 46877 bytes doc/ides/images/jetbrains_vcpkg.png | Bin 0 -> 15893 bytes .../images/vscode_cmake_preset_selection.png | Bin 0 -> 12993 bytes doc/ides/images/vscode_toolbar.png | Bin 0 -> 24121 bytes doc/ides/jetbrains.md | 81 ++++++++++++++++++ doc/ides/visual_studio.md | 7 ++ doc/ides/vscode.md | 51 +++++++++++ 15 files changed, 193 insertions(+), 1 deletion(-) create mode 100644 .vscode/extensions.json create mode 100644 CMakePresets.json create mode 100644 doc/ides/images/jetbrains_cmake_profiles.png create mode 100644 doc/ides/images/jetbrains_ide.png create mode 100644 doc/ides/images/jetbrains_notification_profiles.png create mode 100644 doc/ides/images/jetbrains_open_project_wizard_profiles.png create mode 100644 doc/ides/images/jetbrains_open_project_wizard_windows_cmake.png create mode 100644 doc/ides/images/jetbrains_open_project_wizard_windows_compiler.png create mode 100644 doc/ides/images/jetbrains_vcpkg.png create mode 100644 doc/ides/images/vscode_cmake_preset_selection.png create mode 100644 doc/ides/images/vscode_toolbar.png create mode 100644 doc/ides/jetbrains.md create mode 100644 doc/ides/visual_studio.md create mode 100644 doc/ides/vscode.md diff --git a/.gitignore b/.gitignore index 37e27bfed..047a24c70 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,8 @@ ## Editors and development environments *~ +.cmake +CMakeUserPresets.json +Testing/* *.swp *.bak* *.orig @@ -26,7 +29,8 @@ gtags.files # Codelite *.project # Visual Studio Code & plugins -.vscode/ +.vscode/* +!.vscode/extensions.json build/.cmake/ # Fleet .fleet @@ -107,7 +111,10 @@ src/cmake_config_githash.h *.iml test_config.h cmake-build-debug/ +cmake-build-minsizerel/ cmake-build-release/ +cmake-build-relwithdebinfo/ +cmake-build-default/ cmake_config.h cmake_config_githash.h CMakeDoxy* diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 000000000..fd9b2c09b --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,5 @@ +{ + "recommendations": [ + "ms-vscode.cpptools-extension-pack" + ] +} \ No newline at end of file diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 000000000..d1e6a4037 --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,41 @@ +{ + "version": 3, + "cmakeMinimumRequired": { + "major": 3, + "minor": 12 + }, + "configurePresets": [ + { + "name": "Debug", + "displayName": "Debug", + "description": "Debug preset with debug symbols and no optimizations", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug" + } + }, + { + "name": "Release", + "displayName": "Release", + "description": "Release preset with optimizations and no debug symbols", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release" + } + }, + { + "name": "RelWithDebInfo", + "displayName": "RelWithDebInfo", + "description": "Release with debug symbols", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "RelWithDebInfo" + } + }, + { + "name": "MinSizeRel", + "displayName": "MinSizeRel", + "description": "Release with minimal code size", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "MinSizeRel" + } + } + ] +} diff --git a/doc/ides/images/jetbrains_cmake_profiles.png b/doc/ides/images/jetbrains_cmake_profiles.png new file mode 100644 index 0000000000000000000000000000000000000000..f0e969a6bc0e52a077ec87282ae2422adce0d12c GIT binary patch literal 109456 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 z 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

FN{8h=bq9;B*VoEf?P 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 literal 0 HcmV?d00001 diff --git a/doc/ides/images/jetbrains_notification_profiles.png b/doc/ides/images/jetbrains_notification_profiles.png new file mode 100644 index 0000000000000000000000000000000000000000..8aeb1307385ff5f7f27d3d220da2054e2756a884 GIT binary patch literal 4977 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 literal 0 HcmV?d00001 diff --git a/doc/ides/images/jetbrains_open_project_wizard_profiles.png b/doc/ides/images/jetbrains_open_project_wizard_profiles.png new file mode 100644 index 0000000000000000000000000000000000000000..dafc2c0c43be6d3e4e7fcd5095acb7647a97481a GIT binary patch literal 67392 zcmagF1yo(Vw=YU@DefD0cXx*tcX!>myA`K6rC6b8vEuITzA5hR?hX(7egAXbJNMpq zGZZsG9UUOjbBjne>H{n4nDpH`o^%urD=BT;FIqRy0dSH}z{A z0dle?RYr5%d&}D?EWbmev}(@veJ~7qt33#Xz~2bH4?X!KnKrvUxE4~>y8HH$luT|} za+`*@V<;Cq0GU63{(N?EbUa_Qs`c`8b-kXwzUFvqRk8aJowW-8Fq(DPgq`)V>rF!KT`U;??{V> zhy>qzJhQ(}2IPGo-!vM@{rWlTfG%3EoUP9h&2}jkxvA{2Q3&&0_H&YTAqLVkr~S{s zP4d2GT}%8Df<9(SmPkgzeyZnKPY<6rB14_s-QD&iWx<&KiC%h2mZ)x9nCJ&y6M!v$ zIMw;6Q=`xR`CDgSY_AtZX|@kN(2#SYEq(JUhqD|p&J3!jC!oEzxSbcjVDIqU+sQNiwLQN6IxlRD5A(Gg4)vsSye&5 z5R74oc?JH5wh`JkIs_}?9J=PL{Eswg_$L(qaLFD~_Cgj~t23+^3#pK=`Jd}R8w?r7 z7D?+z9axW@M=V-m;~F<0DEt#VDHF|qzG&o`2tHxf19-zv35=6oP#D>(KNx6cy=cE~a*NEeS$kwq zWh)jQJe{BKR!7Cgszq6_E-KTn3_d;S_TFu61vd&M{(x7sW*#*CGsVou*WC;b)^RFq zB79xUIGwG1Bv0iE1yB!5u)|aiI!Kp;0b9G3dhQgN@u^u^!7{a=BAcDn*lALwl_rh9 z!w%@1naNk8UP?Kvu1*&xjn5K^@w~BdTZJb%sBddCx56VN{LPyw&y;fC+w0Q%(%#yd za;|&wYvUz4di+{aN=k5!Z+3?hG|R@|;0)+b#NQpzQNf`s1EENQu~5mO zwj!av>TcOJtVS%+&cecqLz18>!Y%|Z+0e@6VSH>i(!C@UdoLJg)CO zo*}?yX@2THqs`}Bg2o<fG!v^}s$_edRzn4h>xm zl!(Mq-o4tNq?)UH=nlJ0 zt+_L`>WyGR5iUU_M4HT3lYH!7Sz4M}Klk<+E7jo=L&oa)TBK6Yl(N3&8t>cg?O49J znE6X0he3xEW<2wiz-GBAWD|@24$@m|UU5h&)(@Ra9a(Cyt1Q`~(Rnu}tFkiSa=Fzz zYbVkDLAPk%a(^ABC@>+7%}2$&m~ z@r>FqbXZEx3Bi*k%bF$BU4bR=?CjjY&}f*&t`LqDs^>XR+{H3IJ~2N3Qi4Xh7$Tt` zg0sIqZ=VNBUfi`R^xzM(iLRnk%625I?~EE0F1C7WR9H<9%^mW1-+Z*Clu!RO{~*Z? z;JeW~qKq=+G755%lao8r93CDPiwAc*n#;%_m(Sp**;}l)KU?c;U0Z5A4HOGQ3T@xF zK3?F!Pdm)`$$QOUd)&4tz=svV^w;`YO0qh=DRUWD1EE)9DKDA}*Lh0sJXlNz;$B5T zdo&_qZ}vC9#%As_fUu19Sb2T9DJO>HSKXFwy5U8NKc2SY?`-!M84B%xB&(UD0r8&0}N91w@?@}nOK^FAb@OuGB-76gMF zLty<~E{*fgOmK7w@9j;+C2_i8WV?l%P}szHt9SdO0D^$SU+)p9N&)~ESh)* z-@S=EFf;`aJZx|qvf@$4LKW@3&pGQB)cVFg8jXh>IyXlrpQlhodG~@S zr3^e4H2LuQS88l$O0?$G%k}eKao;#4fO1@cijLwvk`(OkmV&$-J9EBtH17EF;pe_e zVCb7SpTm=|cS6FoO{GbRnF}m_U63JCh~XB=^?!ZAw_j{guKSgIvfeTK0vk@mf?z4i z#7hcH=XOlzq%2!wh_3-<3V3t&YuUlqH%dX4< zu)KJUjIQ$oB!+B%*<@Y9?w%SU)D2I(}+(YCuj?MP#(kn>ga^E(22frE}5BLWlHps6MCRK%06Khkz0p3jD=82e5 zIHZyP-A2TX0zf~5eBc3&TY8`dzh`aL4zR~#p4@*{-w-%`1bV~cJoy)B8SQ-o7R|F5 zJTAs2*qb=SZ*p~Yb<8XgHJ!yBdOR9sx~NCX%~ae@zXad>$pc)znXqqh=0;<$=nIV4 zQ{~`hyT^H0MFwOR)>t6Q);fD_ZDyWCmh0h66Lnl~I?oni!1l0E?96=`DJ&i%esA=2 zi!g9A10RpGB&^X{h}5WXeo)OgC-gRz9N3X3vwujoU$o2y2M~o-(j=tvLie(?@Bs=@S*icegq0i0MX z0odUb<3rV10sRnsF-z_KTtLhF1Qft!)qtbT#@%Omt4798vQ|1dtb)k5%;ktJ?6RK> zWfoFE=%4bWeHMA048;%WwWx3CH2g+9f665JNH@za>6nlHV6wC(#Wbl(Cm=v&hgGPo z(+ygN=(3>~mwe|i9Gils$Xo*_*Xi$8V-Lo{!wye0tQU|R6q2`h5C6Ud|D6emNG|i4 zp3K1^^5NgFIo1e(xc_K(td(H$RR$GjF>>qi4>7wCoON1-DAD$adr%x z`IC^q7IoW;0GW9@S1n*+V$b;{OXTm!@AG_<*?S=d{{8uv@i!?2WxWdv>`kD>#yQJQ zx62xr*;P43_9An&Zhd1;#D6P^fx&p}HgQ0~79d%#)tpw&Kb=8FI|PM3CxsxQ$3sYP z)WsBa62Nzr)v~$GtU!mo=QLnofs!5~-LI*iO%5A4$yXQJgDR|#qh2r3k={brw*nb` z78puI4Oq&?BGXw3mr~ED@TF zpBjlC2JAb%JVrKM*raHRPI4gtqMN5@)L+`651;TC9vw}UADfrA3CUKtOPX44&UtT{ zMw0w~ru>|(PL{y@W^48P6c@=sE~MerV4Q6B&0Zj*U9s2~CS_>-pGiJ*+LYk4bKdM9 zT`FidxT|3^Z70$#{aNaQNzBj(bk+snj zny*coq0FIv3SvziF=a)zK)VEP)IixP725TDi8z7e(q6q2hQ!of`ZZ-NLQN{VFAe{J zqckd7LMC5zGNNqRbzQX6k2Nn~-RYR-=Qmad>{auzR*N?0ad%`3BH+avC+Ey%`3?jB8>nh*6w^U?HXlGZ{WEVZD?4Ng$NTALmt z$uxOl$!aWAw8h@ez+VqrlL3-p@P+x$$vbYg)5WtI@xsJO_i2Y6=}}#iS;8ned9UwT zk~chL%~Y?QCfCs8FTx|zvjg2e95_>fb# z#4GDASg^LpVC3LVvrkz3OG|bQadAnxTAXta#`I@odHvMWTvp~D>0bVzq5Lfn(Y^qn zZu(tFG~(LsgTZ(El2gB|_>r}#J61q!D5nr>4Veb>yk@6zHC%aZVEuTxQHNq9Vg;uI zW`eW98WZPvr+v4#E0LI6LD8ReeUH$2h2gW6(aq;?vGWtv4qF}hUEFR6Dl4?wL}_PO zyUZ_!;McE+>{pj}{VR!n9Pwu7LId=wv?3TadP?ddSRWSMj8t`TZOxoND7_{4Jy1$O zCFoz4kP^_Qa5AD_;+BK;Y`x9LQd5zgYb^3(oz1Uie+CO{6%0f}@`njtuit)HQEqo% z_2s%<(KuBLQ45Q#d|HbVad6_iKGQB%2)6nYTi$ti!8;`xcLlMgxt1iRFDhBa9EmeLv zcq{l_|LQjZS0tfW?riS(1^7({>o31f6fe0m?I*XG3bvO86wErz+mR6|4ThKy+J>dC zuJjmZ)!{TpVJ8df0~Tp%THE=*j>euAWWAm;FT9x_A210%p^}P+qmYQo0_jaf$*4CG zt-MxAj*}kCqAH&1?{?dT)}CPuUu|b!chW&|^oudpzPW{;U%}BN(8_@Hg@RacA=T-K z{S(@FUhwE7yD*|QXz;ae{JfY5Gg^H%J)N}ZSMImOiaR!VVI@N_+yvMkzgj0dGM#)x zT$9F+q!=n!WWB?$O;s{Xw@ploo8*r8oZvuA6Ui97pc`QO@jSw}oKQn0b}gWhpn#J) zpP+$(LJWj)+VKKoq7oz6Y44RzAL#x)N97e~enJHf_D#i|n?1204T4^6D*t(>9*mmK z-)&KaU<&u-+KiMWAoO&Us_hYo-hMUxLdTJ-Udc6&R)PZ=$GCF>Z$h6P)^oJdfxsLGYQ z?#Kqn{5@geo-sbwBgqMN!N8SuNY{H)YhCG-h-ZzY);;BkYIG6%lUhU1m*yKr3xTK( zrg9vpBg$wy`02qPJQcRkCr`D>NE+3}1CFxMc2|vJ|KT%saF)-L4|hf-0|* zEc?!pq{SL55iCdpE7CUiyw|xn#<0>KpAl;g(;P@C2UIe@#XFpFbA}J6X|2fHAdgAX z=DWjG^H`L_%{%P|Y;DpKwS+LhBT=QIU4Vtc6Z`J6E__wVX6qE4l3)n6JHL`p%JX9jC+DE4M@=qfjH6w^Z=aQ6dnEI54GEf zAdX$K5i*6>>-hSNoj+kH$Rq+56|@DIF+aK$<1R(cw6EO8ihrKZhAJMWYxlc|1_^Nm zFTo1FM9;PdLkrkHUDNT#{NpddDWE%DDS6uIQ!p@p|4TwJ=8NQ46VIJA1qC3m59DwT zrtDr|q@YjmaYp;dptE5pwFVFsB@mXc5oU)p6}?+Qvt~jSF|PyREkiit3JZq8||C990_C`@I5=@|v<5gl@ zFNUaqYK$!{G>H_z&}yI$n-z0*;h`>rex1KIjoC1z?d?h1d3 zQk5Ew%S-AvhI+(a3+Wk)bl-^>Rv70sR%fG?MmwBgH@NH1=M=8px53b((esD#i1x`o z6Nl>s_&i1^7@0xePC1yPEH3 zQD=f+$Gn1){hg`U{9aCB$aP-^RXA_SsH&m|YyeWH(-_Q?%}x~ICXk*J&5BBF&59RH zr-lQH(Gb?EljFP-tS3&e+n>26%G;w&-SQdIyok(C#<;OB6Zu36q-^(3mxsovX@Z?-B8ci>W4zWVZ0CC}l zZAQKnf0d4L_C`spBixdr4o-%`Yp zV#woBd0%J~dZl8Mot;6zuP#bbF4hfwkYLO ztYbq_ZZrm{2qi_bO-73F(RQ!H+s`aV7a>Kr3#r z7wY(cgow8=*5Al8-u!O!g2=qtBKsVj))Vh5ILgHhTee8~=9ke15L-Z9mo2QhSOv*7 z9)DF!SBDK8qNv?3Ka@?qj$mjOd;OX6yFrcr+Kqj7%F{9e1JM>*l;1qCAPLXb>JEJLG%?=lA3&9oW`2oq<}Dt^h_yVM^Y>_V`ibvUtL} z(rE9V+~xot9~R-N%2{S0X*P7DThd~4(cpfu)O_zacdv9vl zMk75vwn9l+c?Ny3;DyL7$w=BK;9KBy`4%|IKOlJDPA-U}ggHLtT_KV;pV-yS%gJ)d z6$0VJdu6Prw5h470sLR*s-Y^W)muC<;zPA%-co9QUR=#v2P!%S z;OOz>JPPHyFxrJs>rqxr4o~?blPj%AtDNU0E7jNUgk#7TKxpy9TFct1+}5|Sen+KN z-7r zwz?a?!r$Ew-z$lZP3Csj+XxG+{O4CKmS#tu@x3c^xYc{J-=?9|b?B;B|8&3Ih5B}? z8|_bwZ!;W>wlX^Y!*YphwFxK8()uB#&HN*$#Qf3i7+*1YvdiIo#*L7`tQn)^@|{5G zDIxG`BOr?h7`?@&*Y6^lj0e2U^|w{V+5J|X%sjfa215)ko!@Dl(e;4k(2 zsoHz_B5XpcpO2t1%ieHapvF)a*nU$CU48M4wu}2y#lNV$CoLZtCOcgl@;8(IY~rPy zn$tMcvcZv_rSrlN+Or7s*ZAPMQCc_V=6Te}xz4#kxs%81T|I=YJ(>}IMKxv2)q4j) zS(e-r!DYE39X4g`Wh?kDGs3S)O2=c&KkS+DZ{lNN)@#e-3FFHYnA2^u4^^fjKYwc1 zyj9eaq99S(ZHRpq;xV7U@gkMmvnHUqA0I_js6q4Md6J~gH{gsq8yQ@eZX_Hf`7xB;T6_36=M8}E5&pACSI2= zL9H&@I4#NgBshZti>+vNqvTCXLjD|g98VNad6t2m~ku&u@Q;5ILy8Uet_^c_X{ zI-sTAsxG2xG+5=5e+a}Bo)AT-ongBegazM+W<|wCW+$WJMrwbymW#Q zYf&)g)NKIsBQo!|962gAF~(#EjGs1w^g_S0@gt%MGk%+iV}uc1CK2U+(v~1fgaE(Z znJZY^;iig1F?>ug zK27wgyR+B|eQa?YQek*idX_P;7zDa0F`8zDf5*w$6CGso()B3f1etQb?gDuyedJ?p zS3qn3DTvYjI%1n5QMp$56SCAED8|&IvA_aw;&}Yu)%GAA336i+j}T(zXEO63ELLsQ zkP{@CXE?ugpCCcO79-vR(#&BJ9513w=KcC?vk2-dq&ZpZoh6uWk|w@gg-RlP4!Rdy_G|Z2L;ZU~G!~IzPArbc zeVd!T?DNv3=OgmF5$8>5zhqij8>hR0*SMJflN^tCw0d&?8b`mJ^78EY6JOlRVGyy@ zC5gqFl$_T%{5Jw!ds$BinIu7zqA9m)_WsBfk3gNLSkQk87rWqYe8Q<_IdV!lBlAP} z<5)XFC8K#C+qXQZomTvC6Yp9z@=+`XNE?O0;YczoB`2C+7N5`;N1unmaf_MHw%z}?=bL?@h--lh&okOx~Hz+Q{kb^OZx!k?d+VVJs1ePNv zWtwO`yAS7*I)owf=M$TAx9tk|_I&3}xyf?v(!jp`o;gM{BE25YeJ`)m##R(fcRqrO zh1*BH|6%9jO=2dI((JIGE7$4;j8suh+cq3@g;mP1d5qm+p3k9FOl||V&-uK59MN;z znn)QPQ|-7Wni5>UfSYW7>D@ta8^!{U3Jpz3GhrL(^d6q{u5MV&#y1``KBV5kn!A$o zbYmPb4(RO;LJ@9h?0j$t6a-|I2y{s?9nf5ALA6*j9$jj-EZGI2NIKpabFz%=^gT!^ z?XVz}W2vss+^J?${sxZdv)Jd6tSo}&V$Xn)xFTsrd;>vSJM2QN+zoU$mYmC|-hRKJ zshnrUE84__h$MfvOKmENlsI=)pcopA^HN^c@SUchCKQ&|t3#||`STu|ZL`sFE$tv~ z7UC|p2b%o6OK67+yl$O-s@SP=aooZVqH>E`0W#@WAb0O>T+i(wA|m};RzP=CQu2F? zn;KLj8ccgu0mWRWqT2oD$|0mhXTBZCB3H|kAm&U_yfhl8bJ+0M^h{I0QE2GwcfHWl zGSUp1$Wjxlz-WD_`#5xAb*_46Hjj#ZaZy+bI^f7^mPXE*;*)6Fsagi}!h8g`viK+H>!$4$K z@)3`gL5mDwf&?|>2@m8*OT>td7?#-PQ0Tv+%FTYWtToMD*N4TWQOB-dXmwodI8EFa z!@gphlHT*Y2p=;MG)&Tnc-H@4OQ@chnB*_dj+}%5rl}57HW6jPRZStmb|dAs78^yz zoO-=%oTTx?Pw;tmFtHcDh=?L-KcFBQ2au-S=BnL*npL+ts<}gX9>qBpA5m^ABRuly zZy3>N!p3gG-8i9%&c&voQ(99N8|V3hX@T_-af}j<6?NUe69Q&sh<~$CfBWg*=QC*_ z#lGR^A&$8o5imMPzqagTlsvo^l08}5pge?QbDLsYS4Z|iXr>fffL!&yq~N=-pG#Lx zV(6J55@$A%4L`hJ@Nc@3wD@(|cy?77wwhl3wZok^ zJJj7lEPfZR^G_O+dJ&486q9moNqg(Qc3(y@Y;`{#4`VKNyPD)8w&C5H|6z(Hr=UB$ z$4w0zWUQ65lKb^&H|AwcizABQ13sK(dY_$Uj)fHbHY2v*!dS4sRIxWl@uIeo`c8tC z1RyqA%d^kdB6ABfE3|F1m~L@yu$c?_*y&N?#9_!(Zaxez6EZM-M0VBySHaSesurfs zWts1s!)LZiR>ILVK*_p1BbJOOz^~M`XJL`o1c?1obzW`z05HpPdBQ+#{aVze|R*ak*g@Cdp!Ff57D9P#o1 zwEgfib#m}Nn)LDZKGK>^@$K(g*d`TM)b;7Fv0D7xIWrslovXq>m5fZqIBG|spp}** zQ>$^E)n3zc{NhdYWL)Y}C2o8*RZ1QNtb0ur7l+!qig*C7g<(+YwzHSbWqJC4M`ods zp?wyi#9~*dbCEJ4NF7vY4eg8pg~7zA`!B9l@FI8DRgj-+1$uAD*j^&+B-;XDz?tBL zznLvsu&V%Vum*;9QUq3!ltPKouyq?YLrN38c>=e>lJg6QI}3ud6-_Je9Q?qi>6A8< znT%#?&T_D>~=7gPh{W zCu7<^WNiw~->NkUL1MMxImAe`I8v?{OPD<(^ntl+jUUY*)_PFkNb#ghf;1w-Kz!n%>4QmU+~CYqGD|$EclwgKcv>`t~8~d7_($A zV;3mfP<>Xw#YTz1`Z&TAx5}Qm*{IuB`j8>1--R^qN z_FFn3LH@D%${?}$#O3k(`*TaiI(hSKZFx(_voHd0Z%fvgP3{+%#>r|6ot%A}7OdenG76RFkRWkgcIf(&GOVkxil?N&3+=x7ioI>cq}H&eK3adQPs4 z%|skdsuT2rqDw+LIPCm-B>To<)BM~esYPJm^qFgmnpz4HjG4DHK1@(wwiX8_A-&Yn zq_O&DadE+)<0;aJ@V|u`h>yx%!pJD+L-oS?MSzHC2R4?es;#!Opv`%%1ZgA*Mz+uY zo4&!OwO88o?Q@Mf&UdZl8bk>#`DfBJeG5w#(X(HdhCSRE>?1pmvVE*JrKOb*3}P+^ zByaankIq1I1SEBhgIzx9;!Yv;dWdtiQKbJAcmRb+_k`@JPfYBxAN`4Zel?Fd47i6) z^Xe#Aw#N@-0SgxQjA$=AS=+djy}9T9Em>g5_IhOR+1YN^`o}Z=BvZ<{U^b!VfW>%> z2}SFdlDrM1cp?P;-%Ly6z?R_wAhus~lF~mS+!8_tXzfrwcrGpWC%obP@IXlt;Fe}O?q+YXk!UuGK>fn~=*sddr&_Ng{%g>TzPEOh ztF_E*6El{|C}*&=F>4(dz)TRa`U57$8I7r97P^JF?37mOAewQ$5t=z&IMR~XA$KjUJU07ZT`muwt&p1F*?(vDE9w5p%Uzz2)H^|Vwae#`d}?06G@@Ry;RCP3j5CB7a<75Q{2?L zsD+$$xuR=XYsn&US&^_zoe8(RKgSWlK+$)qw|V^ic>`Jg3uZ9{{c{QBzdrmQaTgRI z%D*>Qz!Aa!1K|AASor@0A&!?@&WKJA7_FTtO!Af?uIN4ivKu3_z-Q2iCK@P&iK z-$lIq+LeybO{LrO_~vzG{|TR+8&n*8KB2uC)H*Zlee^77f12=cO7h4(yPtV)CX}&@ z03Iy~+ghj~bIY!Ar=0ooS=3~6)$+HCMkE_iQNhVqT=o8QA=Q`TC?~z25mM3MUj==c zS@IzWB;_VVo+~bjLzVk%k6m5sj3J;iA2l^zeuDI?=WDwU05m|>RWiB;%iA~0kGKR3 z+ZONQGd>J(sz(ztoqA7t$_sJ+I92gEv>~s1Is1a`9N#`Y_9#&Da>;2b$L;;%t@oq2 z&?h&md%QnA#<9}v(f8EF59z`4Bqqs1s+P+9sbc2Nu>AV`GXAn*ZiWflcjJce!PnQ- zzx9S?)3dwa)qgIQN|qP|oXgjk(ePEEPl;cCFg+>D4`qedRN|o8U{%+ga8dtRl;j$z zKt5fhYV&N27h!gFvHQAr`ZY+JA|WDJ)XGb@-*RKts5!F<$W#P%E$s&UG%2n0u(TGo2m=%u zF$ydSY+Q;kv5V#7;xk{ybLZ5z6FhGGes-U=?#FbfsNf2imO2W4g z)8dBMhOm!3j08nAaB&pUNgk!&QbKBeaToT`i^&fNA9$IJPZk>a z$faH-h=Ope>91OT$X!zDAp?E37#gMo!s@=U@4?y(cw`;@Nw2rgn?d6g@9Af+^Ku3^ z4%(aoO6ck;>Pk<9$HZbEvos(oU1>lxK zv{UW&L5V3uYqE^*KE@;(JRQ!$01hFdg?zJ6&AMQ2eQ*kg!u(i1+ZGo4LM40Sk2BgD zkVBYV;LSo*i0Vab)!F0CBG{*a7psqZJCWSkkn`-b-A4hJ zmgr5RZGt)71PAWt6o7Y3Botm2!aNS`oH7rj)HUIB49HR3sJD81R8Zx(klsHkz!4jN zv-<3YD~p=XoTmkH8SY*@3bk@{$g=I&cnrosq2EqbnndUjL%(aFnr$cgB+Q2B)$NvVE7}ZJBY@K9n}KTpVf+L z8s@lpH|Y66o-`9zS8Ohi#D4ZuDTPh=msm^r??wU>(Bsw0{hL(Q!dEh?oUc;;+ zL`hNNb@0B(>WxGQ%~+_+8K2$Z<85cxZ5IS-5&@rzAP~DLb@zUV={VB5Abdto5$o5u z4^Q&rE8EI->WHM;trOL{(;4fS=yT*gB~Thi1*Bp|bUspazBj3nY)-bM(~keba^D)t0nO4#wmO>es^T>trT4@#Mx3UE=5 zD9e0{<42@33DZj}Zl0~*NOTx^aN=3k4Vo_{eg3LO%k@3BY?pcIjj#|9sM zMB-}QAZf+MV$Q?41~;ApsoA<04U!J6jl-?3L|H(Tqo^RRiK)#b&vE}|)$?4fH`7!t z%>37(0~>5-eO(uRl4o72bOs6!g_ZCGh6E2cPMANt{4@}@h@DMC@I1ko4;NTjf?jIs67NrmI1_6CTW{w7aZBAk7lt)Fbxwlq?2d+A=-f z;y$v@IgCXZrR6#fHb$SQDK@J)k<(2G`MJ@W?<6>%MUnf6utZUzMU312)EX1kSwn?u zReT=n*;U9lDqn#5dMbAI$eUCe>~q1r-mP{)6o8uzQBZ(#Wn|bpp~9y=b+7F!wUeCm z?;=xy#13Au+}v`N`?GJiISc#Z(=lB2j^-OS1w_~W90_%Y z?z6@odsuFe6zwhTgp3-WL^a`%jhT#bI&7wh5r1`mG>65K(I5OwvA}1eI2&8Y3k->=d)qV|OBwCA8K@8O z#V()Kxfh1xY3@W+UO<8ymm@~(iUmR^ zAtKJsMWs*-nosg0a6au0`Z*(3(A!;!2;tb)Wsty`MajC)`^~UWOap5Dwoxf5(ZLRq-_4w z@4LTa(YdQgZ`2wBfC&6QZVRuG@tV_R`yT~{_%_}T?LyKC+Fj&6>q18b6Z~kKkuZx``{IabGfxk*1A$#D-fBeW-XM2Y+dV+;tJ+vhpWI$)yllkzW?KCp$?2!Ve z(U+iGo%dvLGZ^{vOD;>U>(&)Upy0<6O)snd2yTPw)551ePR|d*CcatOwv~7UESBL0 z^-i@~>TAOLXi01?R4=50ASoo3Hczn-~?kv1Fu$km(L7!}rgh0fmECUHOdYS%s zVq<)BrS!h}_zzgD2Q`^+SvAt~N#ok2TG8O8c&djZ{#|bT%<{n@bgxc>?L4?3$PfaUYhL|ER9;`p~(-oo(KA zv@T+58E42*;Z{?bE+7TsO|^mv&46SUiQWTnt9Dyr$ zT-HIpO|j_gm2)}<9^c;WO7ET`0le{6Z%-^kVc&2^`#l7rC{_@^_o}PlvI&RDex7?G3zQ?BUlXZW)7QCoN&(gUe z0H}Cqw-M|}j5sMS9rQ+C=!(O6px&Y2z*b5Oc^BvkuMJ%pG}uyHM|&WeOwkw_*tMa# zu7ou~OoacTWA6Dy{AhT;5h>|yeM2Tm>M%RDd_V@|6nZ%M*%cGzVl%=dvMfX7BN`;r zhd7w&B9O(SvZ59AQY4?g0wk|6azHdn4sFpRt4#{O9k@@K8LmLrfH7accFQ4`AW*ky z75rGf8e32>nT75tyv9_et_XoxhJ63-WzvGa=|Ujb_o!O|=0!NDkM^UN6#)=jh|B6Bcs^t7-ei|A^iAJzH5_E_<2`HOenHYp}+qY|ICBRkSHTKw-oEP+5E4r z!`^glmQtVITOag6wvlT6$6o*OWjzS>fuR$UkbO*vrr*)s5Xrgvm|9-{f@|{hN;r2l zV9{*)Zelygne+>d1>M-G*QJEAD(&u20cX|7>pc-UBN#noz-f)7QutD&H}Rr@a$#%Y4AC z@{T9JbMfo-7Qr_1HW}r(ro%5s=(>=6XC7~^pM61XmLALK4qnfD_Vf}lpXb85!nVlX z;vxQ`p9s{tJTD0K?@3j;Q4}x5(eS9o#_WRu%j>W|%j=~-Gj>Wqbphsd!38Sa1WWPH zX0?0XL%Z}cZ=}TzYW>>jjXNo|jrQ~0&Cnf%CPGj;4aIt{{~hzq8JQ+I>wkqvsoFAg zC_Hc8om#P(kHEH^9G|Tr#CB8^#0Cnf#@hxxXTN7$SLyFDIec!9_s2wMHNHvXf1d&ddj_q zH}65Ilo*&CfPyTuS?;!_%d`Jwjnj{f3Q`Mt-;yk1LX;lb7c-`@`_DH+4UoHHqi>dW zcWt+yN?J~}>fZA7$FKFp|7cE#NlXd9 zf8AZwxZux>VQw}_kw08eA1I~7n03$Y8!YEOrNl25)#i$?9}r1e(lf8M0o`&njpJuW zT&vFG4ubbM*jSK=#1zj&pX&y?a53FCo+?pmX__hBu3LXmX?*qC6NB#D^Cmajh>Ad{Y*UK)+)U~I){d4-C-Ql680dPE>+4NG zb$v{Yc?A9s4*x&U{J((OKPW%RUtsJnSpPqW{x8P>|3UL#VWQ(F-mhR8-oXNBF>w=H zU{2nULS__7r~7skcK(gO|HlSR2c%~xzb1P-T=?7Y{ixu5&@Wjez`x_Zois>Fi)@xX zGG7S|$QI#akEVI}J%_I>&N4Bzjsx{;jqUs<%+TIYz%N8MCz-WhnUU7+@T^R9;E>d9 z9(Dm?#&XgjxuE}tvA2MVqiMH=A$V{LFt`LK*o5FPIKf?m2L=fQ2=49>+}$O(d(hwm z1b2tv?(h$JzxUj8&%Jl8zt@^sJ=4`y)m8PB?7g4rZ0^S33GX*z457KkAI7EsP_)BL zzGLwXj;(1?`SMfAd2@!r!WXGcvEmVpym9gTA_jF2)Xp!B1ss)v1b=umyX)mtPL;am zy`H>Eb;>7mGIe|x=Q`}@#<1n0CpPS0``2|3Bnm0YasT|@!RZ>Rx(%&L;&e5nQn!dB z;-q5qpS@CGd@0kH2eMsCZ>ycvCIgZgvlsq85BIjso%(n_Vo6ya1bAOA|K1nX=LLRz z3A*JcaoSI2|B-KOFL`dmTZy=Z5SzNk@gS_qFwJ-|NR8s9v|e}^Ga$GpF}3dyYe5tR zpfw%teQE{{_F$*|hqm#R2m$3@qkAbKcs}OU-WPYiju6QP{o~^ZkIn>?uN4u6{^BS2 zr|4Cm`GA5RPs+&Q0RF{c5$Zx2QGyh4G^(d<#exZls!CFs zI}h`Y-f_X=d~u(Aal3TAaOcl;J&T|Ey|ffXKdBJjn})lh(9(vdlpUO;Sfb}!E#5AOj zwkYz6=^sPp7lYcaS9VNGqqMGM6*H_*QtPGJN)&^P?KbE=9+@!oOoPOsotx7YJ1fAzil&NDv@R+q#IsGIK< zv5dBovlX4-Vsq|LLY_IY%XAiH_$S?f-@DNQ$JZW6K>$_*Ln)mTXV@FzdJfFX%mNDS zA7b7W$keass2K$CCqGlo+@6upzA!t8=!oc4h!M{w5N@SAT$t65OG3I0*Vv?gsx0kT z$A3-|c>2I%xr9=jX^7CG`xf;>*l}|60RD(KhGLkY?rw$GP43KM86F7eCR9USsT5}$9m z$i47BXaF<-^y?85aL(D$?}yYmbA2RQzrM_gh(5D>!cd=|CRvsL>T{%JQClMsdoCaA zACK&`8qB6CdCky|O6odMi$5l@R_A!?N$-^%DQDFEI4p4iC8Nf2R>%?;SiqjZ{9laL zVqZSLWp;?5=f5Ef_sm(|nfeOLAWf%e)Q~;wiGL}sm6S`m#c`~gSBT%KZrR^dXX^a= z*ibjHEQa>?0;7_W7k+}uKK34KYY;1K!JC|6TU?e)E?oxhz<}4}Gd#^a`sK?Me@ivO zhXfeBOXSzL>vX&>H6E2zb>31x^C!>kX1fKc@fk*HcB*~kF>Bl(x0IHe(bOmi1zF|B zNiry5{|3nOx?LoX&|GAqxAd1*zE4o4K1pP+7E&b@f7am*_S5OFqFMu$#zv2W7#(nH zlJ7}93nN2N0bpq zUHQg%v03-`wvGRCi@g_<9hX>lg}quZH-O>oC3o8*eAS6|p2#|gudJoeiG;eZG0raT z%L|925#1=H?@57!4L$r2HNaT50TN>%(W*1DqZOnhk7t;aJR3vvCps7dub)v}PfrLD zF~mjh+Wk>^nn>TRcPiuZ^Re!xo>l6OH=PNiJqF^a9;KZ93TPo*H+Wym9u{qG4pMKm z>7Qlcjv<72q$Q&4zfPOwoI1`HUd6A2`>ai@p34US%Cj1ghzh7ACP6-5O9@+AL8)!V>4lbs?#{e9SCGLE9$viul4UEMO zzHl9qR)30u@vb;pMuGt@-x53!I2<1Du+SX|Hcle_snal!iSpCX$@*?Q*r)QVfzOcT zo$%E-HMiLp@oBV`$g0w+FReqf8K5Nl5(K(!BxC=f*&HHC$gFPAdJc!KZFFYa8;Rp( zn*c4Ez1MHbkFRH25pr&*i^jANiVKIhbGO%uzUo#M9cQgwxx0Ac{!^@eh}eD-6(DMZ z(@(n3)dHpuCzEhuRuAg4Pr81AGyZ6*>ZE;TiYt)@*7nKpI2( zTE7INU|rpVnoejKzudEZzMwWn9c!R>T~^lx24oQ1e-K>hZtX}|RFm!HUt(6>p-CB*xHH!c@Mz{O0~F`E}#GJ+UDzHaTY zNCoUD12s0^KmNG_-7 z>wjl4^P#)FYbk@!Gj>as*01BH;!gj01JoQd_^hfp=Cvi(LFjgtUQ}9@+gdOb(&;@}r(KBX4c43?q#d~D zpVwMD3-s5oVheA*I(G*6Q8P7}S5m`Kj0u5%*>OUk-eT7H^&hl+B2F_dN;P&A-sBX5 zxrZpmy&k@$47KV8vIU&=F~Js9T1Pf?t0rhwYavT`V=%S~t?SX~LXNfEnBD z(Q$7~L(Lx3(9HH?Z~t|>kZ+)_xx_cw_v`E0m0gVh7at$CUrU<#*|MD&Lk@AK$C7tP z%m>R}fSr%2tF;-uDcrGN!`+PIW+{BXEq!lVyzL#vDnpm&@7OL&Cb#n;k~=ZN8Ifi z#{3eyPi6QU6?SuNBb+@J+wiw&2?yB}zV$Cloc1K|gqt(d;_RrMNvsd#ToY+Ke!^`eTT&j=TAs z;>_}oqM@aPvBSH18i~3f%%zWM7R}-BO}}UmCa0)}gf1Nmk6&q{dOW;ID{e+Kb9i53 zQO2F-isf=8nv`!!V*vR(#y|~&@H)dQC_Cbcq2vXD_)llt#SB7?%D)8t61!l8`1I|c)lJ6CjY+>wkjSVBM2YGXoRt5br~x8+hZ6BB9|xw7 zkN9`#F%jCRK)nKMopdGE*lexhPV1>j=;jj4JofmBTynmywp=OYTv@Hdp*RG+nO5Ry z)%IveSHsgz&#hEAP?WN_X)5~rB{onsta@#D!52JZX4R9QUG%@D*ohEfw$P7HhK zecC5{6s?*1?O@6N1V^4YA)4cV;4(*%nB5CQf73Ev027o6Pts#$t0Ac4GQ z*p6+N5A~~Mre(Ro>Sr0DpR0j!HJtJ{<#J5mv$gL22F5=uWyNvarlND;QvC$lc#{%( zWt1Qt{6->N;g0YsWh2RK*S!AeGH-~*Nub#ZO9jbrm{)F zv;LRd&iUBrebk2KRkR}w~R|4Aj( z(p-e8Tci`~@OHOw4yG&5?;$epBPw~c$4!PngTtfv#M*>ACacPiUvxWcaj(*VG{+Tx zJn47GObX_lpM~F@u{h%GkaV8CC2H*IuSy=*tQOIZvH3>J@t;uxhmXCNi^bXuM@zo9SQfJm{sy&h~(1^^domjnjydX_+ya z{%xMbZ~1=WJk@Zi0S54ri0c}W>|gEF?}!y_A|N4<>}@n7(m_Bal?Ckdu|N>2OK)SG zJy~+s;+kfx?=$C;m1q6AkbHd08E-J5m4V zVp?GXAx?29!Pv9uN~B&&=sLIev#4u>{Zd=Y!qQ^-LSwyV991kEo@ux?{Wp!ud@XAV zEh`4}8nQpxWO+duH13v!A5B7XE)?4?qTKg8S2;fFDmCw2ufc7kt!#B2>vHdS&gDB& zXUg2Vb3j%LUKRvBHP~YkXh1?R35i9LA*%ZDb{Md(*Npbe#mb)u4cKV@GG98ix`29y zV>9_!jsDD2u?i@QpQ(IC14hz7R%J-A;n1z;Uuv75_)-08-T_|cIZtPL&{AHPRc)m6 zWS2W_56AR~RqCvPB-Z{VB`gPntZYrGo#WNPTbSmQZTN6XqySl*rGw)t>-i(zcsBb6 zH1j)kSg6}N+mw*5WubRif~(T6 zN?z^Np0Sq&jEcRQE}$cHS&*14Tl#OR)qy^UP!0+M71%18yZ(V_$V+fxA3X3qNsv-ZOsThEJ}Y>&4b)6m8sEo6zuV1rlFGU!1yH#!9IQZ`Wt>8 z=kEorI(lmcNvy}zPcKH^IZhuLDh3kH!|QqKi3?KA(+<kg8Jem_(F)&iX0r zS2X!5!se#7Eh>U8(U3j}0U&r|EPavOd>@4&?nlN!iRY8COoKB{5hr2C()AduL(AW> zs3We>BLOVR4cnj5&Z=q;+G5Y-D@Y=wuP`*r4Xkz4v`K}Fuoeguqk5g)cz(p&Y#jO~ zFnh?2Yli5QCZ})AHj3Pn69#i85}I>)nJh{PrG>j-NorUpS<;?^KW@yQU&;9degIQr zM~Pel|7Z(pltRkz4t`-?jXpAjGNE>QeP7t3@1@?1y6H5sH%F&tY*jQ-xG5n^qFp$gm>vrva?ILYKb?II6 zn7jSaA!J2WNT-Zz%HuS2IC!ZtU@?ayG9f;;nJ-qj<|rP(s1bpkO(`OZl@Ja2Dyw+? za|KLDSny;(16zR)P+vc*7#BSFIkzOUvI~DWg;bf^`sNNcv2_0HMH69~YhQPXdo|O- z-kzK9Bxl&U1nfBK2Rn};TL5Wnc=Hl>Ki%G4bNCNRR74$_tj0Y-2bWX$LDBm|5mD^8 zPP$LAK+^@Z?P<42%5pW`Y>%)0f-`suNJqA`EWX~IGmj}*H9vAP+y7i37-nOqd`sD; zs|m+!bm90d^Vr11|8*w1VBk560@;@WnMoXMV)xm^d#L45rnk#TZtCaOpp9*#?nUH7 zkC+B&@-kqkvfR3`{0iGISJd5!3ndm5an1GniI4~>lDV(`L`snVk^Q5I)kmpLjFgbNE0YA|6b>EbSk9lN$zVx2}H`=kh3w?Kc-#aM{4bK=19 zC8Y{dd9;;d8EzBGm0is3%=DH;Wf&s_f&~x4f;S9c;bCa?v+NpKnz!FPS`J(~^AZuA z>LQpxR*MnQ8LMiEQ53pi#ek`toNF(TObwd)+idBxJl&~hCc zufH3iRt}&R5%mwGVE&MeJ@$?-L+9T6L?S zfe}6I=i(@81W}6pLHp_UVVc`!wjgJZA~rGmXUg_G7`_ZSJ{R63g_5 z_Dh;;O(F)Oz+!2yJ(7a2XUD@|?{~Fdq4@_UObv@InCIv(8ym|Yq{C4GUuq5H>=h8m&TEM? z*tm9eGPU+KVOkYnD891MlpJ+r_UQ*(dFCSlAcgGXXqEC6=^!=4>K}_;#>~!!sFduI zeA!SI9m|2R9XE%%Wra{Hsk_IlCwGV#|74r_POtCnMUah6sPb`0jKGXb2WoKF1#vp$ zWp52mHE}X|_;r`ayBGx$E9m&>KNYe#dgVPD`+M31^+j5c_@N(EwO7Wm| z=79|eRjl`z?!7qAJarC`=u=yKbjS-BJ+3g6DJ?MGUhzbYP;+I(k7Tz_w5FQ{u26p0 zwvC#$F9vsPO2p`@%8zoj9AsB*^12i)5Qt=H(a{4_BJPLG50ckyNA&6hCk?FIL^gP0 zF)e4!HD(z78@s&L$y)o`rfB22E*^?u`D+DqHJ#S{w`Y{%=;&g-rtd5|6MgprAl~hq|t;zH>7bMRLoo zXOVA|Q^dd@@^G1{f$@tAvdwXKok=etIEfuW`_}s#&*DJ~GRDV0;dH7%$SU&ouBuu#~ zxzz>HzI1easeeml>cJA?XXzYRSpG)vBZ~faNkDyghrQPYg3!pw+Ecyng!WEX4DK+meYM)Fg zfDgr`5tjVV`U@qq88M^LzBo3_6<_ePDUpX1z&BBWruveqd8Fsit-5MhLW3)(Wc0@@ z>aplC4}}b@J>WIFkfWTt9e`TnKh$68eHgXqHhS$^hfw{D!zTuQ>7sp4=zc_0+eMZ{ z`a6wkG+Bh(mLte$GVdE1Bac5NHP1KpangF)zj|xN-RL{n|Cv_y*$IVxo#`EJAm;fT8fzdGr}!+ zxYO~jFM4cbW_XInwCIIG{7WSnfZ z!k_%5pZ>2`JbV6SWB$*({)y;?7WvCo{Z~ZLm|y-nCC7``27VZ#=UbYcpF@E0gr20u z^Kc$w{1cLmDdh(Tm-Zn&W7sI1x65~IqxIva*6Iw-$y?vQ5&SHp=ljGC2Lm#0P2O{V zA#8*p27w8JJ22jJrl$Xd@yW-8ZpnCKay*=x%6%sI#0!X&N77)oGS zXx@TjLyVE5pe%H%Nwb`V?-FE=>#pfkagjonP9yX~=Rzd@>fKpGqce8S+a4t`^DEIr z*U(Asl01`9;riQibKwx#b)joBiWnFx8$|K)5%Cj-N|@oPfXMK#umRBjk)Q3dK~uRN zGknhboh>e&*DW8|A^QOdbGk0k??SIf(}cUIdNKL}c8Rqb8_|!Z;J=gZfds_+O7Dcs z>iYLa9^IltYelF%2C9~u2!6T-@>{<0fhO^iTrlJ%x!G+I(e-Z051Gam>k2m;(Hq?E z>&&zTo?R0f$2lQO{t$@7*OT9d7pa5?tJOFA8>O@P`d(ekj_%$zI|`JI<;>AJw#V@A zTK5pepY}?5kd4S2IK|qX8w+?41U;HeD*caSok{)sE~wMOfB6Hs{1r?? z&GC?$)Zqeg1{KpVKDwNGQhL=v=y#ap90}t%6xI9@S!{%FW=X6w!$B2Hza{N?i{ckQ z`gB=jsWVWN2Q!Up8kWy^zo}sTsM&^(SVxj`$O4>>#Lf4)U$UtL+LIjW9tvu_Mz2~# zu9;KhDX;5uU1DDXF=auDgkx7gFIltF$^Pj*&O5$&4B}1^mXyTeYQtHdan&U(O2ckM zJ17_mCgK6#Z5fAba@9IwQoRR;s&Zg7XrZ%bmS1GK8DQQm$TnFbD!U2cz_nnr)riP? zAfK)&iRoGdGpeW6({g|(*m^BV(>(aFD}S9o6VJI_8yV~f`m9kl?kA;`YU;%H+BG>3 zhzV(jmx##DBP%c>6qaZreF0o!AROsfL0~xF7V6achQ+uhi3f*K)+pdX?V97e+j3vP!q~~l5x+I-VoxD? zM&I@RYjh(1pmM|QpRCSTU|1pf3<+JP0FL)Q`2(11^d01-$SJtGR+3vLRR# zOHEa-;Wf5uQ-Y`ti`_fMbhaLb*qrtXCzDI8r}Bzp9hH_*bxA&5ZZHH#{9{pj>23`t zbJ?+t3FIngd{R*3@jqk$CIw<#m@1#}ltC;mAX@IoZ;{qM5YW|Dyj9+X+pBK$W02R9zS=BsO(TrE45RWRwZ*d}^T^9aQ7Crl? z{`sX0^U3Fluf_T9{DN(P5Ue|j9DGGSH|(hU>~emgFHI$OEoPwNX zVm@vQvn^qkrZMzePM=-NP%3eC5ibN}sa2hFQZoUehKp4n1#$M3Iqt>Y+Y@!NqQh_( z3>i4TH%RQmWe?gt|Ogm(o>c16tA zK$nNFTqzVx`J9)P+$@TFBwt-UiZm*k6F5b*D#*(vs5P6ZBFo6OO@$Vhxn}=NWeqx{ zP-T3@OuLG z(OfHpe##uABT-cITI7C0nmdkZqw31Dr$zU>G8*0p!^QnbmURVxVdVEd$POq;g-}2_@ilm+Q{cE}ghinj1pRL;!w|h8NSV&r5SC?r3 zV$`cOm9T&T*Q1m}LBCsa!9W$|@cRo4LAx3eQeBe5#DbGZmDkOW+@{tMxkF&F^lV|# zZGI@B2n#5kJwBudwg&Ck?tjIaDDij~amlGGW$AzRjS1tiGJGuOEX7z3so&P@YIczQ z@D2?X^<{v9e`RR7zBW1b94clCcHqtI+iA1Qrc}O%;9iT${fL!h-wLT?2YN48Vw%># zMLgl%x$)oP!%~$Kr6(JH3wo^7`k`2&{;B385WZ#?#l?_g0rfNW$m)%AILeVG;-Nh8 zMIWv6JtD+(Gt>bitAz=zB_De`f&MOLiOqJHcAg`++~D0~!S?(PdA z)3q`9j&NmVsTHys4d2Jk`6yY-#`rB$uWJS=4J&a&uRFulR89YA11yyg^?b7@D!Y>O zGYVf;&xK$lW=0we{@!{5udz}K(k>nAI>#PV;YE8mBzlK215!0EOC}U5KvIv`BcwgX zc^Tu8{eOfY#TQ_hje00CyuZo31qvR=qoP+)hC4fP=BeWEWt&R^)lYd~@_pZPpmj*A ze@C7pBTRN*p0|`Ec6Du2RLrl|=5|AkwU6$KC^w-)n^D z8>Cyx0@ubS9p-{V{E*yL7p!mF<&~ghElHYU!4lw^M#hZcT$o!Dnx!A%AvB zrU)vw&trxv1u%Myz9=eN2|D)V`xF^Hha5oYIl3R7umeS!ogW`5sy*^O-j-CBj9PJp zm6TE_sM-iecW0cU`8&xmX%v8vO&+k-{R;_QQ_YfLCR3KYc)r z`+247pT{i}eGRw1OEC^c`@iDBdmL<;G8`3_t!Wu2wU3wB>t zu>s58Oz$4snx7(A&&-SZ9d@qGeb#juLQn8AXK?2}Sy4DWSnlhupT}J4^b4ad(up4H zy8Q{33q!I8ON3m(KQzTfYky@1nQTzO5T_Uk&z zBZMjF0YOKO2*PEDwfAPEeoj=BknRmm0Cr@CAGg~%iYGt7$G2pBry6pD5Y-_RD*S}N z800YHW#qYL|BdPP0bo2*yLz~5d@n=fYIx=g?O-tskh`90`PJDcI}ESU!#YzE=<8Et71qKVc>nj4pRcD9sBa} zh6l@_+S^eh~_p!vQ)tb zL?f9nF@V*9$Fx0vy=q5HbhmFGn$uENpl4Mi3FS*CsWl^^IqRJl#|Z z)4sCUtg<#_tQF>qGcR`d;M$P(}wU=i2coR91{Kb@-`m>c+C^oce;J(#79Ay0Q; z?GwA(o$y;T3wAzq?>Mu$0E#7Cnn?Bmy=JjP&W+BPHDL->CnMZd0On2nD-t*y4-ZTxT~640f!4(k;c7M)d^KD^e)Rz1!JmnCEcCB83yS?8DU_R5&*v%g z{T+MeWwV^K*@3>5qNuj*XdNp*+2-YRFY8sY0emL%@RKOq?*kkaEijuAC0(+s4EcIW zGgLm^vo)t#1eXZKqAT!3t7X`AO<@6)`F!W{*nSqe6tj81A+5QJi@jqrDwf|RGPFA? zO$5ox$h2-U&@t!nVs<4nr<_lSp~#pJG%ukWfZuS)z&|n=B18la_8OFdhw|1YDzPTf z#NtJ$P2ffva^ZVb`L;Iose#jioOXjKFH`t>EI?||dZ*puo2SOA)j#2i)x)$Kzd9M? znP~ie*}-TWr;Ao7OO?ja8OcZSE=lb4a%QQaLo8{?Q zS=LqKSBMA%?bkkdz5Qn)x^OY8?m6XM{x6d98JC75U+4msbn?XxrszX|4M}r0;gtS2s&yy++6IqyQk-zC~1;jZ2H7rT-tzcYX`gcJmrAl|ijTn1&3 z+u0-9j_aB0xX7U?a>i|{y$jrjKS+~>AJd>K!!lUwFD1_x=n;EK?6Q->l%zgR^}5Yz zUDn;ch7nm#DZj*gYxeUf*6YT}_xF<>55D>a?lGr6I4wkqkKWNLWY+@JXt)lzzrlix zZ@G-2Odti+;H#cC*{Tn*Gu-cdY!t#2^E(jH^)Av0-Uf7UWOBO-ikZ{-soHv*>3go- z?*rhYKvY!PlUZwul=lzcH@6h*>8W6(pT?fwfSmCi)|{l#yXfHgC*1LrC~wo)3poh1 zI+-3E6~872-8=V|HV+#+NUsS1-6l0ONv;*;f>zh~zqoJtL!}0w4b_lWWUVei1X0?- zAx)p#amd;|!q4y#BhK^0EC@SXqoVrtZ7*)&^vI^M@%f*EgTZRPeRuZ0h}Wbk-B~}g zKs{L?sH*TqT*xG|BnE6kptN71{73VMzAjGwSI_dV8VoWgeY}}nl-S4u<)lCxoA$H~ ztS@pGs2&UPN9ds#psL5l@!<1YAGYv~6Lf^nN{VF2d^_Rpj)Wm^uvr*+A?4yC@JddQ zdKr%mKQLvCKRnggx)uY+ug?1&jbH#&$8zs(iaIY6r|FQD-LzF@76@{W*=0Y`xozG zX>Mzeehss+m1@rSPu^azHDAPk;4ml#2Zhmm|G~~)6zDIH_wo^X6Pilc+S+%H>{p6c zC!P62y{~swaBvHy{X?JbIn}bD(7LOeZM~lab?@z@j_&2WXl5PtQhWb~%ZKSF4`J(G z$73KyWC!V0?(VmosfUf@+E6JoCtH_$EV|xpld<2kVUM}FvtXiY82y7J8B1IxJnv^k zvzP&6obB-eS-Rv}^D>~h_I+@%fko;~PwlG2SGro|01*Z%`U^}veVGr#1X!;H8%#^8TMmMiz5Q=R6ywKC*kc)(?!hVvWptk-#R&x&TyJ+ho|>x z?S7X=`|d=N{Q2Vy*_t*=lMOcD1yA?y8wbZ)S}iUZ)eK!N6AQL`4qp9ymME04gVf}+ zR^30L%#cR>JkKGj1}x4u$xO~X*<`c3M~-ONxKyrBG7-(UkUQHJM&33cNm-^9$3wk- z!(_*}l9GiKjGIJT>UzYM_iG}OV8vNM)mM~fk97CNj0W_7S< zksuom$6G-jl^6c+g>@3iwE>n*^|vmx`23I%3YDho94HXkA3p^vVUMz`YZ1i-w>Dyb zzqY3_Qu0tXk?1>-ecah7D;Q_Nl@oaQkxc~q6dX~IA)9U3_*q`f0|h4+4kti&S`oa}PE{`j{lo}E9YX(__SMU{QP}o~k>Cxjt({;2{<5)~xLvjY+4Oa* zB09O->>)M)yYBNURFsaDJ)Q`eHFLSgjYr`mQITX=d{~S)lthjIvggVw&tU%8>-k13 zKCU>Cn}>$<78oRUjGl}8p`}W-WI;$q_Jg9U>AUxQ5*$Cs85ra8#-RJqT>dC#TG{Y| z_zUB_OF@kh_D1%hfE8)n7QuOESL{olpIh{UJ||~-yk1=ggO{L;G|G4?V>*<|s4dGI z?{k4;q)Oq{#kcLW>rClc?CQc|;=-{F&iTvrd;Yom`vuF2hh>u=3Z9lMDw7`WEF)lQ z59McjVy;@=xkkC4iGHtLtjL;we=hRGDvUofV9QO|0r3R=$=^}Q9}qSh6wSrQ5`#g9 z1^WBLLllPuJ{b~7vW~F1JOVW6%!r6R{gm4z2BJ`b-w=qoc{#cd$NGuVlh)2oXXs^J zaGWwe+zXkQxTg&@Y$rV&V6`J)#fZocVUI4Q86B)|oz%pp5f^o5CA3lB-BMp&r5l+X zFy=PwByle&+{TjYjWF^C$=et4B>E@50h_2?4dLo$B&~MQY23IQrCsw5u}N%jF6s~h z($}so_rn!NzwX_rFD7rBAp*|sUE+Q>sF;tXb#Q5ZQVrYyr0P-ro{-O)7FTbEr?XpP z@lWA1w{{5-rk64-(0auj;Q3IxfHKt(_~`g>LJ$XkMu;cd6-v8TVy z0&rPCUu9`FSmM!y$_qjAges%m%^B%Q!r&Z)HURL>sd%MPbk>DPe)z`S#;Z<}tWS;=9{E z!tdn#J`j5G372S(Cw3!#;dV5!U{_C+yg#AIym*rv*|T(yyW`j>ts*&JHSW3oj{5O) z(T;K09{-(S1wOH2K!w^Jh0P~oW67$cAmNQ=^4p?@@Hi>H0r88p^sV8(c$`itMw5{i zy4i*A5r5ty0PfPP1CRAq9SY$ICWc(OoxyMzD%@P%W1U+lo|A{B0hD%!Ir}}N5{RvY zUaui+Ndv{YGM({3%O-`jhUin`Tqu=Eb_^#Ht?n16-aYQJWRWSn>QJ%nLa3T5uudt( z*b^~}^1LSomy(h)n?N{dg-?EA9{t%}$c}YgKr+iVv&;7~?x+vU-QF#NvQnNGHg6M^x7u z31wW!&`!@ow!54jB307Ue#kU9NLsYBP#s(ML|F&=aM};#O+e`AT+nRUrBhRa+`r$N z8U+)(XwH+b+E`L44J5*$7YnsT85yBgI(o>-eIhEk<$oZb@<{==+-mASA}SOqGhkLb z(Qk9+qt3MN&&m!ct9|UFC6ObgDeYYp{?~?)nX0UWayL4<@*@}whmW^57W{5v;@ycL z-;FBBvSf*M29srtl<~xd9|)G_QUab#tZssfjYq&+LZiDAUpC{N?3@qCB>foJkAr6- zG4AVSboq8EPj{*}dnN{38m#S&bWroTZewtAcfR!XVc;?{Q;oeV&e~{LY^_YinN)xS zs9!U|FFB$$)xi_S(ZPW_TMmRFw;@L0W(Vl@v>yrE=F+QKPBQw zT72X16hI8!l`2i`TEU?Kt!c%7!CHx=-o-WUSMB&ojsPe*pmuJ+G@8&Ef0vkNpOIs| z4^#Xn9~ND0RH>B@iJfMkRM7%a&?G=&AQ2Xwq5k;sYni)l;`gG6SR|I_L3ZEt!y^1M ztaFSlcMD>zy8E$43t}lbIehz9ut0bS77mWECE9_!E^Mw{1w!?E9|Z;Df>$3xBT*)kWCjNCU>zMcvI?GOl4`YqpEDJ&EiknmN=U#(_EMN>g{Cw5 zrBM z$3t2zx3Ayi)>obdo_?79s#$SJ*gtfAfhqo<}V`YlB0bcirUKJ)?=a{LuJ+N}P!e@4*=#z!${Urw*oJp;O9LfdPc_=<-5>)pA09uN(5;j~Yu)1>gF>0A7KS zQBbn56Q+A3qZ#C_nG=v(t>3bUerUQ=CoK;3Y!v_&+*bBW54u|k?h7VuT1BP9zs*v@ zM+9hKtjUMnXeYEFaeEy{jbQ+P6U8}RKsMQ0o!!8M!?P{Vo#`P$C(UC%40f!!$oeZh z)=MaGs4ehBXrn9-M~m2iFB5f57DAb$Y1vG#C^`NR5~gqZjZ7s);AEYkyZ3lqO;xQY zdj}%4jq`hzNSS7&mIPwF!Vgf++`fir%E+C53?Elfw9`d*{&+~3fd~Y&ZRW|e52*Wf z{NQ{A%pr~}@7C9oYGy#S_k3SBk}mWb$ehmtbRE((#KVRE+pVKn{4(r2M*>U;J&o4< zzVr&{u)*@9We|kSvimF1MM%e39V>dQ9uEqO?#+qO)sI9Ke{n-^8<6-oDiPYiPt{l% zB!Pdm9Ms5|KF%0~Pv}cvdtV}TQ)R5<;e>4E{AF#E+nhX7ve8l(_5Q0#xtn)IU9=d2 z&=VQJE5BpB2AGf}+Us5-o64{N6muiM7|KYe~==9HY) z$m7-3*ZUKFlaBTCfHVfWO_ZJ687;MO1EIhz)AH?&eh~yRRee0qOx~dve%A{Fup>e} zxyUdvxr43YtdU)Lj#;4Ywz}HP)emOKS?erZOlt1lorQNg(p`Hz`h#E)y*A(DmMO={ zV;feATeEm`!}cR`*sKVmsW6m+er{pCpCzaoWf@PZBAfP8TSB}jy>I)ye@ZtyET+pF z``=L=n=~EG@qG#J;fcG?+=`Gt;sdZ(YO4V@_BU-6-;|Fla*C>1mSbYUb-}Trfeyfi z_v@9xD8A7C=R0@3!+@}8^K_tQ-Trg&X(Dr)1(m*?QTHO3sKGHDzlT@ff`HU%!dq1^ zy#Vo*TJh9ot!`ekQ{;SQV$&arsj9*>6RW(NOG)@^_YkMCh8s7;0XC_}NV@oTzxCx~ zbMCLnR&9>i=sUzK{tGuYf37^j%pT=0CWE^LG?^ zGSw%D1^YX$DKifBv1d60YFcSt8^7Yd>&Wff5xKmutP+C`S}#Vg_bn@%86D7u;1Q}m zpl_s;oRsi3*L7NuuuPK!jpixOCoI9Az-Aysw~v|Q@a?8n%?%QtQ{}uE9)iJ5K+Nnw zZ8T7NlI9DY+<~(n8!Q8|FIABn=xcN$j(%6+*DVXMC?(8Pa1wlCCnT^HO#U(_6tOn~9!nr~XH0^LH&@RiXX(LCO6F!1`fj<7%iu zs$yB((?n3@FGTR-01krt2TN%5`cNGD6Ktx8;O*5Y9X|&PbtZ;`N52xUl492{APg@E zRD+o{aKMvLZyM*Vz z;E{h(k$*gS|Azzm|NEXmax^GfVT)YdO3+Iso?Jq&VF?4{%wJq$HqLyE@)x>zNW6pP z&@a$Gm>rXewS|Fhph&MZ`cQRcW$jkqRJ`C`a4)_#tscj{)a%EB%~VSos#%L6jz>nr zyh}mamE|w2j^nHq_dHB@2ixrerj^aVUUQhczI~dtzZGo#+$fj+p%v;>E-absV;CU8 z?28D3qX4gd%~AgtxG?tlHPrFh7`IOO<%O+K;nZ5sy7@aLXmFBJO@28Dw1!^fQ7^Yc z&!HzTcSC>u=lrii>hCLE)0VTw1&YQW(yUd;QLX)$aT`K;*?G_7&41h;p%|ncM zCn?de0=&4K)Dfsqb2uJv=5o5euyv3J-Ag}?2>{+z?DwuWT0QGPzG@A!E{>}%S`l%6 z9#I8mMh(pQgpCrlm)z!SiGTVcNKU`IJ&*L|`1fTk(5{vfL+|&&nZxIY=Vl2-(Nok= zv|G&ZrfvqU=#%4f7nZlxF5(aE9Tj^KOv!C|O0iKC|2~a320VHYM;+;*HM8Zgp^XH_ zSX{>M>)I-|vhsxQUq^9cX68DcopdtqJ_Q~?<&mS`UwJkh)NecApS%6u31i$OQnZ(^ zKzyL)h}cf6c`Tr{%vAGomm|9#b3wX3;dXT>h!Bwf1R-QDYF>iW>v{O%K_mYLi?(YV+Cd*XjM(+_Z3N zXUf_9rj>65TJzYs9*~V!9gcWL0T`zw4c8Gcv?kDcRyu8elGAg6c@hx;yqYqlF7f)|10HsMG5qWV2OxQ+-w9$=<%-@(HeLtTt&U-wps zvEuXkUO#PUx>&>C7$^Ttl>|l7hJ$;jmxtGw`69LSStr! z;qO9&-}@^#07ef$_I!5QFOl4g&_BF`cFaZfIDprrA0uFU3oOOmUul2(y4bH%mF>!y zjw078&rgE#q6VRWmJl*JB@o_sMFlKY$i)tv0Yw5utimH$`?jmd6;O~dv~V&#_t(r- zXk#?04G!tZxJ{|c>^z(MY5t5JfEOJUL-)OjnRG8k7k>}eTNMN$yyUo>Y z`1k2mk6y8@IdXCU2RIwTbS|~%{Z3O3WM)a3oJ~!?vXrxVHuxN{G^m5ecew1v>PFXx znai7`c{`4bdRT!}Q=H0oBk-dEiDfQ3grtXS755HLr;nG88N;k=0H^f}XO{_WKk3`R zO602<`^w&cnmW8KVv%lP`N<8%!{~PwxOEG700)!8eEXt5gh(TOCnBQp^44;1i&G$V zhr$T?@pW;e#f8Kyq8=&vCn9;|1n-P?3 zO8-FNlQmRyX$e&0Q6>{9KjU%6vyQur`<3haJ!`%|(3z#~G(HLLkIlWyqW7@hrW{Q( zb!nAw;t-e=xN9^3Wh~w9E@^wEw^BLv$sPQ^^wFLk5Kv|4cCgDrcjnLejWy~-t9eU!~aLwTZYBabbo_H@t{ElclW_%g1ZwWSn$E!E!f}?AOr{w!7T)L z65QS0-CYKDNbdW2pWS``D_^*V?w+3N>gulg$vLMQRri%fUekGsAYRB6(W=OjFaOPZIDk|%e(n(t*z{nZ6N{vCd9EKc+FvIi%s$z9$? z&Afk}Sp*@k%xu^BJPA=`5^VyB{fEiZ&%k zLAT=>x3}CHfllD991PQ0q|ahajy`aqG50O59KgK}PA<8l1%3g$k})kDJ+PGQ(GMQG zH_*;Apv#oQl!gWq>XeaLdS+(PN@rtmTAyT(oR=eV2zv`rUPZu9HRPU6xI2Y;Bb#+g zb~W28H5}*VZx&m2USP)NtZ?3z;Sfz0f2ZMW`9bocV}Tmoy=lvcBbYz>3^no1gi2bv zuvhzAz{LKPt!7p1dr^0V*}3vCr3e)xk@UolU%hdJ?BOLef1W~wMKlRjq}0p9NR>9% z1A?=EM$L~GgTtRS!FYO^4TH7jed2^)S!hn2-eX*O1c@W7o7eJT1a&rS-8sC`HM&ho zmC@Dt$T-`+8?Gc^LTY`&CWT*Q5W-02BVAidz0EAAp|*C*ZXv62(eE7JiY zW@WGGuQdA7d{n>Vd->e+!1FD@&(oP+>upz0MdGk66HsI-^MGz82*U0srj6e*;rvB| zkPOrkcwZQ|j*v5YlhQQV+JJ+ z17lS1@>&g|TdEQ6wXU-wR!$!+!%7OG7he;MN{Os3oI#}=O4$TwBra_VS{7+$2JUMw zRh7W)pT}9lwiXe`Mz>g5_OHfP@uF>#;II$s*YJpK#ftx(KFkfkw@ap zWRt(po%e$QhTR}sK;fu%fB)i|TOr%^9Y-BcEe<+h*5j}g#c?DHb(4U${?K4I8Ux_- zC08IUTFrs9X7dpTaQgjuZ;`B&yEl3fqHHKS;O{ti5GcU-g1@Sy^z=?nB?F4I8_-(j zdOAd2r285iNedob)00=uDsz3DrULSpvMe z7BWJl)I~K8K$V-0>!narea$t!s3izK5W*K-);Z-qucF{jjc+;emblip^Q}5~yW8s9 z$CU@(*onuA;o~W`=_nQNeeCxw!Nd8Cq{2iYs#KfGYT7KY_w194+aDxragDCeivgSc zr`<&;#2Cxz1;ZA~t%xYZPeY^JHi)yx$M3vPbEMu%I00V8+MSJ*cVF(4c{oPt1Pd^m zCePUzhTO7Nrvxe;QnZvOl;`Mc>S~#oL#firZJ0OnNPUTnGFOugOq-B-QfzQ=sO!9` zud03wPY*io?O=uZ|gEJrz}Qbh;X-5}0_Y|VySHYgpMj6EY|3&izEoMkBD z)qidNlVA#lZJrkTf5FlZ3#bFO^g!h+I5=j-7Q(*(CPltMwbP|0;=8H4B5b=}MHSY8 z0^Og82|F&!J%S2&Ddngvy!q#FpTbq6Opmf)+x|2OhNA2a{smS~NbCP0$Jak;zy5>S z{{7m2@Yw&f=iX$>NB>*MAGgPr%hJHY{N^{u`aZC6tc{JUv?w(q+8w&meXZ&quHw`W`h;1V|69Y(RhFR|D@6;${On_wTF zgy<(=_2;8-K*qB_s0o(L>JRvVAt8MoYwx@-si#gSUJ4ZOI!Pp3vAe_r=8Y^&MWfRn z8(z~m0BoYwTB3Wv%ljehnX@U93_=+N$r_v~Z;thz3JyH|lv1B?n?pU2ttGdnNVcAH zZ|8TvprB7(>6Ystt#z}$k*me+46b!?e<6nw-y*HUedZ(=XivFXT)pZpNW$rAAxi=) z_w^=IM)m%Sfz-XvwwBC*yZDAf^B*05e&ZfPGDb9fmso(__vC00(L_O!exF6Cv{AA` zo2K$^J=Vj4rP6o5depjfw|el-b3Ka5a%ge#v?-6JB-f~Kc53duiT;OMlt(>XR=O7J z(=PR1)uVI&*eJ3;(6O@&xoA#%q9{nZiaSwcJ>+t)ckJrhQ2ozSVIx%%q2`fDijkk< zMqUQGdj#q9FC#sIR2#+#9gU$tFkTXbTD&dOI$V==rI79eo`&$uMJVJp)(pAFJfi2? zYKBdtq-VNXeBubWx7=T-UW!VGF{G~n+;n|d>K4eHE%M0(JRICL z+DpiU{Y??1kw%7B{I0M2iwE;S!3eVuGm)*a+2P)gt6Kt3v&(U{v{%cZ{J7+KD|B@# z1jO#tN%F-uvN#cmJm04 z3D2;1m7Q>Z*zlF`W5)`JR!=vA{avaL=Y2XGdfj2Vac+=X^@M4}CU89K&s6^oArj=* z9I>|c0!Y1g+>#h*YMWdAJIq4@JP%kk-g+z1z=ckIleiH`?Ez7A+`s=4Jv@x1?d;Ex zjaKKm$Ms?jONUoUE`OZ`X#D#?a+?U2>7||2Rp{W9$>~y_T?p8|03SCmP#5_y(yILFl|X*B4j_FCfcV{YfAjFoAm{Ss@(kUcY2|2CT$f0X0~OIp0Q8^ zn{(nkM!CxpTl*UtmXXaysig%^l-e{lpSq-dcQ#{EpE0dl3CX(2v7zN@BECXK;sWwK zCC6Q}sNyJ5x)BC+-3v5yrFrCgQvw z;$3H|*aoCUZtPbph`>u2BtG^G(FQ%t;@r4-12lXsgxNm0Uv!T*b?`~Ud zzoaDf<(2`wVG}59b+$Z)1sHXpY0B>ENdRGP;Q#_Er>9O2w%=EGS!}WZlB`9~t8i2v z4zS9GhjUfNZkYI0L>K15KC48%Sun9JoRq`^BQjZS%`PuZHwu6!H_ggxY$H_nu!d{T zH1mb_R&zOCOx*2`ny&1pFW(*XfEQv(qk7{gP>30RvC=4}J@hX3SjchQ(FA?8uKn$H zM2xwB`-(|@i|F;6^(>E?0OOdObjJd^u`{Q4333Y?boG`@v)$_3zWK-M zeDS%EqNd@M_ij&$s1Py0mz@ITeiUWM{Q_8>j4+zh1J$tTeb>z563EWqw9HcFZiysl zdzkR?H&J|;pEOsu+9PMSelZeNgw5L!%D($q{ypXRgM!bE1i4{9ZBy0DLHFfX?t3kr zUw+2aI>&wSs+&_ysD5cVMrqDa7%EjrQMW=@AdNwCU!wB!H0Uq=Q5giGZ;EVAn!)o6 zdOd)jxlRl?L4qu^^Fhka-g~ijG>aG!GtDA!oXl_%w%mOgRDl+=Zs+<8Oz99ccB@A-f>CjmRn6-2Bb6~yzbj;q(q*C8&dniOknTfE)R*La zx#5?XfbhP@Yrve*`VCaxYTsS8{9`w&0NY5ZLu5zkSqd5zz zPc+`5-IN;0fQs3QY&V$=itTU;{Eh!C zJ1soiXy%gpdtRXXdK>qeiw~YIfvO~?e8#S zPMt20aWo0X?X}&cq!@dW$p>4+xyv$5a%<5bGx|D9Mr};J>1Zr!?F6he!#9VKyq|sXN$xy;BV3`aI(i?B~J{C>ypTSRDWf zF0b!0x;QoPDC0mx>Xg9wr%~)qkJxXOZ{3R;t2}!dfW-QFlbF9x>x&|;h{(HW@0`Gu zG4#Ga7F&q`p$|lWEAyV=8-!39K3(pDaJ1=63|ilhnJeLZD2^M5wp#5-KOsm;sUt z(QiD*h~JQamj&yuL`3ngG^{**$vRU4i$^?G3A_S3{e%n?-hZ_Al9s4w^F6=Jy#1V)aY)*5@7DTT%6_Cco39qQNF-g~;z=+7&m4Tjz;5uP$%qR1 z9UrbBjn5gvqPtOoD2E2d|L}Z%%c`(y>k%W9zgopW!9^ShQ$4hm%HJnaRxh&&_A7V2 z`GNB%WJUFOO`uMw=YesGin5!zTG4uq*pP0-Nq}?n73;;XOEyA&MRa_e^&ZP^ zDwi{4B!+z{WImt(CRO$2+n~s@?w(W(OynTQmr?nXNuut0cgW!OIWoIE( zpn-VAw?~?BqwBSue8i}$YlI*2fz!F%4KnJ`D|)wAOx!d(i}8oVjRo?>nb}ulXq^(Z z9G8JBeFtB}_JlMWHm&bZ2;u|?NzB$qux^JADFs%$7(&IRSme@ zO6tuyCGYZ*(r%OFm4DiL`<=oc4u8&~wKyz^1bXC0zO}z<*r%IY3nPd|yT! z^FQ2c|Wpk{pcI1C)7C%a32K8Q;^>k-}fBEF!(Gu7fQ6w zr>|PsC$8Lw>>wlad8wjbqMDGr>*lrg8g|rIdzI0W#mwvh4XF=;a>`>ARwZRUOxnC4 z60xuw63?r$WHr3kcGqD%@PjL)zQu(3nmPdMEX}q_puIC&f%F8Jb+RO&qDW)yaFx>y zzRW<0KK`A#sLUzKkjV1Ji#Lcj8^}uuczi+OtHXT?I+Y4b&8M77 zRgJFXjbLP%)D|`3F08WZfrd#DEX;g(3`NsY3wwAp`(7edaofw0(3hpM6j?m-;nGtN zCRZ-2zd~IKN~+6P0WrYAP3PY%U?2&{n zo_|wN!!%VmxLRig1yFm}(3WqL5C2nJV0%B_ZIp9(;Iq8BA}?>=D;c^lfC@b_@VYth zRFzMSHGm?xk3jO-f6dqB_*LC~P`B$0f{7}#@oZi9W{c^ZEnx0*{?it zV!p!!&ki^vjI+i_&~Roo~=M^o>V@-0lf_pZkb zRy7vQ%1P&i7T*}`JPO{d;IC;E1D$SU*hL@BF#tH32BB0qnVHC25v!$HncO#iD{f&D zY^Y^+t7rFAhZ`h#sJ*q7wlCsnvNQD?AqUGsETwx45tR$xk3q)<0)?QAD)!IUEC5`g zPikB6ooDHILz8$YuW7$$qc2{uK~td z-WJ9NA9)jqAa$H5Mi@hdj2>mbl;(IZ$vOTsi%lGrz)nNiG)& zGxo)$6l!lq*yq-?6#@Kl2vV%gN`|kl#F$3+0RZzEk!{8Gx0)fIhrI9&lFj=y#`Em0 zvXfimD0R-@3`)Y%#|g6A+gs4LjIRxTeF|Oh_1*vyz|v6YXRxS=<-pY~TFKJR?>h`8 zl;L!na^eEc!jH=*&oB!iq>zAc7Z+ zQRhxx2$@g^oA}%EAS}Ba)aWa>AU9UgkR_&P++n`5t<<-bJ*G%JFv{2sjYss7pEeW9 ztiE51zV5=`mK@Mub6&(3$zl)q&=AmV3tcJXku3WL(Qx_=^N^}*Wx4FZOLoHl{L}km zL04omI$250a97X=(Y-6gm3!XGF7{aBtvN!BW?fMAW%x352&~W?GMsV8ZM%fupUy%G z+`ey(K)+eRU6x!&TT%cI8^6BGg@}VS10hsj@6)jWUg+i~p&}9S%QG*yrNmf1^2ZNv z4=ORbkS5qJv!Vk!vF??x5D(F45*fzz^pvbDw=Fm-8KRF7;osxK@7Jj-5N~%%+kdyb zMO^!qO3L@p35m4co=Ej>Bq_MW+z1R`aZQrodkgXQeLmB<5a7S7i$3B&k~D`|50BXJ zsrBro!y!(=B!dj%Rm{VyS{qNiZeF*8RA=5tQXl^G5TqSrjeQd{$-G^GbAEVo9EjPhf?@)YI+soUntFabFe2|9rTQZ zIm3cN?I$A7jp$>(fM6!+P^LW2wi?OG(jB~@5Z4lsLn?3O4yH^|gq%s(qAUtm9|(c> z1vKR5u3@j*?yYx;zwF)7r0=ul{g4|F21&@Jv=`V*5qIz|a8vUJHM3IWf;Tw!=kzUF zI12ukHx%F~FCIT!qbKK8h;oFtuf4%h^X zKgl$eeWHg&2`G-HPaZk#qXs^YWGMkfqAh@|Nql2wic11cP80e^3O4L^zHg!xEUkEG zGLY-;WKX1L=K*6-cut~wZbY#FPIn?d!&mONVvyL#L8SW>Cv5Q~Dr=Ifl3Qqx*@2yV zxB7fZ2G9g7*rV2t89vN|E)*EN$Z)EBvMuNo)Ja&khka@RZ{H&Y{-KIZHsW_V_o)h^ zQa|%rNfP}kRTL+6E?tLjWhjbu8Vj)hvRu2?ZylYhXDqu>go23ld0Y}IXzZ6Av>TEi za4n8gRqg+Q2JP`Ze(zmiDw<894iX!#S2V@BEaGv?o_?c*4Qre17i)xveTWp?QPf&F zzp&8ZFVK<*nAK|l3s9_cms|A?%3NDA*e%{la-i?ORf_z+h-^LMm=n`R4l;r5HY&vB zyJ3i_(C{J!PolnJI_)#Z<8;dBJF%66+t?MksAxUjia;H?UmNHj9d#)f%Blk)8zg}# zem>*(oO)YLwY|}qoFt?tkc%ZAA7d}l*}UV-lN_iei~r(fF1y%AU-+|hc(+&2xagva ze;S^MU$vYP%53IOBnZEdj)iB40+9W>bU*Mh_IBi? z4~IUp$X2Y2A;Q!Woc(HCfApxiaR7vvxrzey!13v+EBGWcfva@NcKrPz(8m-J6;oft z7m1|M7t>b)uJWhG+{3<4`zgC#tdHIJedhUGSr-;cJSKC8b;_xr1;L};>E_PCC^b3PKNs)l)i4jlPM2~oFgmkx!b*fc~AFRR`lW0dV8Vc8YmocBJ zMr8qL3TL-LwJSHO+zro}9aPUx+aZy#a&uAZ$8O;wp4k zPqKQSP)dAyaEeuvvn2YPSMT-|x6Qr|XB_98)0|}9mMNbHcUE8qsL2j_F`1%IZ4G08K)1>$LXOpm`S9K9LOlrhABH(D$;fc z**^W1uAIp^nobF9KQLFhLo|pTCY7C>Iit)Zdl&XrSvgnfb&FVP7D%t+lbOiFI^1McA22>L0|$_fRuXPwm{IYbWrB6z$;rt z50|AuR!X_}FC_kBFNB={X*9>2g1+S4Zzl1;xAWdu)_y*`ukK>DE|6$T9E`pW|F{qM z%rP9D*aF!r#Uu7C+rOj6&J^zWcWMfZ9v>!9LpM%#qHkt>R5f#JHoR;YrLUZ2+NUIY zcg>PXg5MINq0o&atKusHst9}?#FF#RTh1zta?}KWU=d~43H7}>`3ly~jp&Z#CP(hy zVU88}I*CN-65~2?5UuAV`y?ANvb(0m0W*r~VoDCyZ?MiQZzl&TJVIU@9ar5F5yCp| zVWsRi10{w9wK-}SU6nSf)9p>euLHb$LZjoBJA!9UznRH&d^*7Ozdtt4ciUaQkZ+tnWJU^ zqO7$cga=?1yB)lBu-87dyyN!Nn2X~<4}3%)ubdz!2B5#CLLm3gcpHe-CY$+6c}V|J z2ZyIq^pN=5EoPigA`7LJnVDIAg`#WP44;_2x&vk>e4H(AOXK%`9`o$HH??B{Y%9Yb z?_Ln4PX|xCLSwOz%{~2H=%|DSu5d$J;JATO_n6S`hYq;NR&HR3kMJ{8Q~g{}1)6X3 z-Xkp@r~Cvlc93Cu>kXMcsQKX@ z(z*2%zWK8?xQNQ|O{JK)pC=_c)MA_Tb7ZQll(3&zjNkGvA5CARLMw zX`*c5zFmh^8H5dtK;x=8!fqiP{>;qK)WL+Y<6yXj!666!x~dt&Ok?az3ZonCT0_G5 zGUiGH#!{)0N1)<7#D`^$AqCen0_aijNC=;=scui8;V%Hcg_Tq6l@g^>fW(2K0o#h_ zSZwUHS7{@bX}>;HFv$CxtVIB4e8&=a~Mz;f$Lwa`)=<=v4}N8U#leNHu`G%v~Ei7WAT92_qwLi z9l>7A8DvbF`T_U`J<>?N z!y4*s-%;o}kfF@U$hAl9f%%5;+_2`kExYxbu23WE9>TtqEJ;>{ zGQUs%oIwrzRFi|1S^>O>!5EdZ*|CJlkwPS9;pu$ zX!7`+v*RboqkUn3*X5k*u_9IL{*CT*PQR}c$LIWrk%I4S*Q9$_sOM)dz}=|f^NnL+ zmozIHCxV*ou1&GffyJiEN{paqcn_k#+C@Y6GG-;#7umI-dEe-IgUv!s}=>z{U06NmUdG z@p;b$EHLE``pq*T4y|NwPrJA|$?SgSdRBOi{M#cZxDwUq;>>2BXo%PcR{WWpz}Ls; z^lB*D_V}S|;SF`3Not7sexz^LEtoeQ)N_5BaRNLut1N%(n`|yO$h?*@6Md9ySq?nf z(|}e@&kKdMRZL(=cE0(-(hGc+dC4OqrY5D)r>HoC={O8yIzwIFd&;K;yE|U*EbHy4Ss2J z;FQUh>XHCeW}dyL?{Jepjqvp*Zks7^;3;mcy1{`p=uekD3J+i7Dz^#dcrH|z9`sR` zY9YPhblT_-8Ku)$nc-z>yesA|!<{(v85KDTe15j2V>U!32xi)AQ;|G4{E3quVOd7- zxZg6mKadBSZm7x2Ev1cG^ZopJ-7Xd(KndAxWwk_Dc--aFhomqQnJRKUKE3Vy?@>%u zkxJ+iuf|bZ1Gy9=qkv_xpe`S3m+e|cQkXRX)hV5-E=#}O$nN~$|YUfjNIpcQk zlPhA25Y4Sp+H~JFDUpQs@|Z~i-?rs9Sp#OCM$mYLZs5FY_Y#Wueu`btu^>;7;c)h1 z7kXr=vgy{An@>ry~{GPP_BS{sBV`VXtrK|qzd@E3hLqZeSK>9*yt^<=?w_s z&ov+dDPbb&^GK#wfX!@FH!n1v!dHOM{QRW4b&|5ojvA3Ue1gp^csG5hoU%;6BQ=9* zUuWOLDT2loeX=S}gQY&^&b^4|%9KT(j#q4|{HBfWWZj!h37a^}C|`li^)^x?SE3K3 zSzm?7SwATHb^PcWK#Y{-m1)c-hg5lFl#7^|@Ffo=MJsUwGVA7v8x&Td(+XpFC?n2L z)l>F;%AUt}f7&UP0qbmZhxPS^s1(W#ueNY0ZZlQXG>)Upa~qb!Is~5~T5m-@_e1@h zlHU-O5oxz&zM0&|vtM#Sy811or{9q{XR;se63V z3iEF7C4iV$T6T%)&tMQE#{|Qg+0J!On}37OJ>PepvUFA!`ix(ENpa0N-Uu`!_Axi0 zLW>K^J?6uVb}y{m(HRJ7iNWNgrc_ob*P0OXgXr;3d=i}zY3XGT^EoF@p zde;}WV8)ZVND-?ℜ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℞ERJfkVFF9%yLCElWaJ3;gEc=Nw-POan` zpY4HVZ?A&Cdyfk6utK|-`}d*a>=^gMIss5!;^Z@d#zYoJEtLOl${FG1{GlC&hbkqO z)`Lk;tOfyE4tKP;a&&4Vd7>mMI?L!c^bm%;8Ae&ck&DgRay)ihS#8lSE0hgl=c22c z?eKTk>(3+(xx!zJif*3Sq%R*zK<=K&JfwFOzn^SbcdqX5$*ENP$8b<*_j%)p#jctJ zBJe|}aAz;gN?=$_}c~WANRh0Tmb+1Ctqsy z(R1=CG9fQ_5Q1Cu>5au-scB*`M-o=A!Q`g!+P)NM(QYp5KyH{s`+hdG;MZsT21jj znFl>@jo{V)V4i1oruc&`HFPZ4ltGdIqb9Gl!E4G*KkQA>VI~OjvS|1cDktKCM3b9a z#^#NWzu@de@>=ovW_J+I{6C)Ta8 z7pZ!#n{ABw2uu$865~I%z*y&-=;||L1`EH`GfI%^SmnB7!$G0)K?m|oV$zSiHFdFa zliVxN;-IVZV)XM>9reeX0@hoHqCMTLi)XVEE?!i;dd2oRqk0-C`YOfAqRBHh6qW}N z4o=%zHp;WOKTAcqNh35?)$YZNxoMa5m!l1#6VWKl#}bbL-q`h^+#>9+6CZ1|yo6HyVq$KsC>>bid-0i037u4Z4%4MjKIBBVpO3j}5t zH4{2m2n4?3R9P(@YY+*ieQ>i*@f1{p?K}Sc7GJ2NpaJ^u0C;XPXMrHI)8J6ZPZd>9 zWJ6f3W1xrbsbKM!tc0;OtxaQfdjIL;D~_0G`SFo;jq`yNVCDj_5_E9R=Dwj@t-$3& zIl)zHdR;tO#2(bWf&w_%ncx`e^rxL(94*Xu6C-zTHgWhA>pz#gMFx8~o53TCz}e7& z%@1&P$m7gI*$pVLiZ*>@lkI1IvMX9j9J87UgIyk2Lc)I8T~ zgnCl0C>U?|kshmC-ViK*y$gS)kOzYlvYfPdPp6yQSx;a8>^U)lrcj*rPf(7?s$csG zW<}}_LA8HoEyI{g_5DteX?JW-X5!7LyVv&TuMgyw8_!REK8+u^B4Mz3O}J}^Y?N8X z7BzfW?x~jb}fCO-SPHP z3P(S+hVyeNv#w!ifx{G&*7~`3nN!$f5GFX|7;20ijsBF9sgejo`?^i97=>z?B-88y zAh{(Da*RGE^Wni=v;cyz2n#Y(`;3kPRC~HMt#g%w>GAFWK1xvZ;680k$hY480;LR$ z!tJs6>u&Zp(>0}j2WmqZmsutmY+I3F(PwY!?pRl3NOcTYZoGr- zhrvQEvdV`9WtJ3*r za`EzV*?n$E`DigKA?)aMR_a!WqU++~W&{^ROb${l8jHIAysID|2}?}SwVKZK+)O@p zY{z3B#z6sN_@Gy3$sOPp&R9?JPXV+!=_&+R>$`g zOg$&@uvR(h!`z;7t6Yo7+;!(Y4f*1b43`mFfu`$`{Q?4c#dmWkEjm zhz>8>4Z@HJ1wLIWmTxcYz?qCwju<}=a&D3 z`DcKr%suJAx7^#0SDSwFyhe&ycZ$;fDgaI+$8l?M%vL6NoQalu{=jVfk_Uy)0yFDFYeEE^#I}euz0%Ru`62fVx5B2{;JP7daP3jGPY9y zPuLcn6oMZkH=+3>7+32 zT*{-k{;Dro<5pG-F+Qjwm=v$3(yV(Y7$sf-o-w3=MxKaod_+?1shHIVl%0a?NK&E@ z=Ij8`nxDbl!nyJR2$9U$(YSc5Ki>ZJEJbxyJn2LgX*^`4qFA!&_q~1+efjs%d;Hgp{&?oL-`Yl&_e357JIs-0@%ivzhDan>f8wdRl80e~7 literal 0 HcmV?d00001 diff --git a/doc/ides/images/jetbrains_open_project_wizard_windows_cmake.png b/doc/ides/images/jetbrains_open_project_wizard_windows_cmake.png new file mode 100644 index 0000000000000000000000000000000000000000..2366908ec8cf313a2cfde3e99e5a07be27e3ba0a GIT binary patch literal 64227 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 Iq-p5?0uQJ6QUCw| literal 0 HcmV?d00001 diff --git a/doc/ides/images/vscode_cmake_preset_selection.png b/doc/ides/images/vscode_cmake_preset_selection.png new file mode 100644 index 0000000000000000000000000000000000000000..f73ede5be02143c3737181b5c970d91b1656dae2 GIT binary patch literal 12993 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 literal 0 HcmV?d00001 diff --git a/doc/ides/jetbrains.md b/doc/ides/jetbrains.md new file mode 100644 index 000000000..09a95b92f --- /dev/null +++ b/doc/ides/jetbrains.md @@ -0,0 +1,81 @@ +# [Jetbrains IntellIJ CLion](https://www.jetbrains.com/clion) + +## Linux + +When opening the folder for the first time, select `Open as CMake project` if the IDE ask you between Make and CMake. + +The IDE will open the folder and display the open project wizard: + +![Open Project Wizard](images/jetbrains_open_project_wizard_profiles.png) + +CLion try to determine a base configuration, but Minetest define it's own presets for easier setup. So you need to +delete the `Debug` profile with the `-` sign and close the dialog. + +You should notice a notification telling you 4 presets have been loaded in the bottom right corner. + +![Notification Popup](images/jetbrains_notification_profiles.png) + +Clicking on the `View` link or going to `Settings > Build, Execution, Deployment > CMake` you should get a window +similar to the Open Project Wizard, but with the readonly presets listed. + +![CMake Profiles](images/jetbrains_cmake_profiles.png) + +By default, none of the presets are enabled. You can select them and enable the ones you want. Keep in mind that +triggering the CMake project reload (VCS updates, config changes, etc) will reload all the enabled profiles, so unless +you need the other ones you can enable just `Debug` and `Release`. + +If none of the availlable profiles fit your needs, you can create a `CMakeUserPresets.json` file, edit it by hand and +CLion will load the presets in this window. But the easiest solution is to create an editable copy of one of the availlable +presets with the `Copy` button icon. + +After these steps you should get an IDE like this. + +On the main toolbar at the top right, you have a dropdown for selecting the CMake profile to use for the build. You have another dropdown next to it to select the build target; by default the `minetest` executable will be selected, but you may also have to use `IrrlichtMt` for building just the library . + +![Jetbrains IDE](images/jetbrains_ide.png) + +You can rightclick the topbar to change the project icon and color, for fancier looking IDE. + +## Windows + +Under Windows, the recommended compiler is the [Visual Studio](https://visualstudio.microsoft.com) compiler. + +From the Visual Studio installer, you need to install the `Desktop development with C++` Workload. CMake is already +bundled in CLion. + +By default, CLion have a MinGW compiler bundled, so if you want to use Visual Studio, you need to configure it as the default compiler. + +CLion may ask you in the open project wisard for your compilers, with MinGW and Visual Studio if you have installed it predefined. You can use the arrows to make `Visual Studio` the default. + +If not you can go to `Settings > Build, Execution, Deployment > Toolchains` to change it. + +![Jetbrains Open Project Wizard](images/jetbrains_open_project_wizard_windows_compiler.png) + + + + +Then, the process is roughly similar to Linux, you just need to pick `Visual Studio` as toolchain. + +![Jetbrains Open Project Wizard](images/jetbrains_open_project_wizard_windows_cmake.png) + + + + +[Vcpkg](https://vcpkg.io) is the recommended way of installing Minetest dependencies. + +You need to let CLion know about a `vcpkg` installation to let the bundled CMake use the dependencies seamlessly and get +IDE integration. (Require CLion 2023 or later) + +Go to `View > Tool Windows > Vcpkg` and click the add button. I will open a popup allowing you to add a Vcpkg +installation. By default it will download a new one that you can use to install your dependencies, but if you already +have one installed or you do not plan on using CLion only then install Vcpkg by hand and select your installation +directory. Don't forget to check `Add vcpkg installation to existing CMake profiles`. If you haven't already installed +Minetest dependencies in your vcpkg installation, you can do it right from CLion's Vcpkg tool window. + +![Jetbrains Vcpkg](images/jetbrains_vcpkg.png) + +Reloading the CMake project (should happen automatically, or display a notification for outdated CMake project) will now +load the dependencies. + +[More infos on Vcpkg integration in CLion](https://blog.jetbrains.com/clion/2023/01/support-for-vcpkg-in-clion) + diff --git a/doc/ides/visual_studio.md b/doc/ides/visual_studio.md new file mode 100644 index 000000000..a08a58ea2 --- /dev/null +++ b/doc/ides/visual_studio.md @@ -0,0 +1,7 @@ +# [Visual Studio](https://visualstudio.microsoft.com) + +From the Visual Studio installer, you need to install the `Desktop development with C++` Workload. You need to make sure the `C++ CMake tools for Windows` component is included in the installation details panel. + +You need to install [Vcpkg](https://vcpkg.io) and install Minetest dependencies as stated in the compilation documentation. + +For the packages to be discoverable and used by Visual Studio, you need to run `vcpkg integrate install`. diff --git a/doc/ides/vscode.md b/doc/ides/vscode.md new file mode 100644 index 000000000..6814a7a88 --- /dev/null +++ b/doc/ides/vscode.md @@ -0,0 +1,51 @@ +# [Visual Studio Code](https://code.visualstudio.com) + +VSCode suppport for C/C++ and CMake is provided by +the [Microsoft C/C++ extension pack](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools-extension-pack). +You can install it from the VSCode extensions tab. + +If you use a unofficial VSCode distribution like [VSCodium](https://vscodium.com), you will need to install the +extension pack manually by downloading the VSIX files and going to `Extensions > ... > Install from VSIX`. + +CMake support for VSCode uses CMake presets provided by the project by default. + +When you open the Minetest folder with VSCode, you should get a quick pick asking you for the default preset. + +![VSCode CMake Preset Selection](images/vscode_cmake_preset_selection.png) + +You can use the bottom bar to change the CMake profile, change the build target, build, run and debug (running/debugging doesn't build first). + +![VSCode Toolbar](images/vscode_toolbar.png) + +Like most of the VSCode experience, it may be faster to use commands directly (most of the VSCode UI just trigger commands). + +| Command Name | Usecase | +|----------------------------------|----------------------------------| +| `CMake: Select Configure Preset` | Change the current CMake profile | +| `CMake: Set Build Target` | Change the current build target | +| `CMake: Build` | Build current target | +| `CMake: Clean` | Clean build files | +| `CMake: Run Without Debugging` | Run selected run target | +| `CMake: Debug` | Debug selected run target | + +## Windows + +Under Windows, the recommended compiler is the [Visual Studio](https://visualstudio.microsoft.com) compiler. + +From the Visual Studio installer, you need to install the `Desktop development with C++` Workload. + +[Vcpkg](https://vcpkg.io) is the recommended way of installing Minetest dependencies. + +Follow the official documentation to install it and install Minetest dependencies as explained in [Windows compilation process](../compiling/windows.md). + +You need to let CMake know about the `vcpkg` installation in VSCode. + +Modify your `.vscode/settings.json`: + +```json +{ + "cmake.configureSettings": { + "CMAKE_TOOLCHAIN_FILE": "C:/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake" + } +} +``` From a86baefda72293c57e3e984bf01407be38d2a722 Mon Sep 17 00:00:00 2001 From: Muhammad Rifqi Priyo Susanto Date: Sun, 26 May 2024 19:28:24 +0700 Subject: [PATCH 35/67] Translation updater: Add support for function call without parantheses (#14574) Co-authored-by: Lars Mueller --- util/mod_translation_updater.py | 62 +++++++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 14 deletions(-) diff --git a/util/mod_translation_updater.py b/util/mod_translation_updater.py index 8d537841a..d23b96e59 100755 --- a/util/mod_translation_updater.py +++ b/util/mod_translation_updater.py @@ -118,21 +118,47 @@ def main(): else: update_folder(os.path.abspath("./")) -# Group 2 will be the string, groups 1 and 3 will be the delimiters (" or ') +# Compile pattern for matching lua function call +def compile_func_call_pattern(argument_pattern): + return re.compile( + # Look for beginning of file or anything that isn't a function identifier + r'(?:^|[\.=,{\(\s])' + + # Matches S, FS, NS, or NFS function call + r'N?F?S\s*' + + # The pattern to match argument + argument_pattern, + re.DOTALL) + +# Add parentheses around a pattern +def parenthesize_pattern(pattern): + return ( + # Start of argument: open parentheses and space (optional) + r'\(\s*' + + # The pattern to be parenthesized + pattern + + # End of argument or function call: space, comma, or close parentheses + r'[\s,\)]') + +# Quoted string +# Group 2 will be the string, group 1 and group 3 will be the delimiters (" or ') # See https://stackoverflow.com/questions/46967465/regex-match-text-in-either-single-or-double-quote -pattern_lua_quoted = re.compile( - r'(?:^|[\.=,{\(\s])' # Look for beginning of file or anything that isn't a function identifier - r'N?F?S\s*\(\s*' # Matches S, FS, NS or NFS function call - r'(["\'])((?:\\\1|(?:(?!\1)).)*)(\1)' # Quoted string - r'[\s,\)]', # End of call or argument - re.DOTALL) +pattern_lua_quoted_string = r'(["\'])((?:\\\1|(?:(?!\1)).)*)(\1)' + +# Double square bracket string (multiline) +pattern_lua_square_bracket_string = r'\[\[(.*?)\]\]' + +# Handles the " ... " or ' ... ' string delimiters +pattern_lua_quoted = compile_func_call_pattern(parenthesize_pattern(pattern_lua_quoted_string)) + # Handles the [[ ... ]] string delimiters -pattern_lua_bracketed = re.compile( - r'(?:^|[\.=,{\(\s])' # Same as for pattern_lua_quoted - r'N?F?S\s*\(\s*' # Same as for pattern_lua_quoted - r'\[\[(.*?)\]\]' # [[ ... ]] string delimiters - r'[\s,\)]', # Same as for pattern_lua_quoted - re.DOTALL) +pattern_lua_bracketed = compile_func_call_pattern(parenthesize_pattern(pattern_lua_square_bracket_string)) + +# Handles like pattern_lua_quoted, but for single parameter (without parentheses) +# See https://www.lua.org/pil/5.html for informations about single argument call +pattern_lua_quoted_single = compile_func_call_pattern(pattern_lua_quoted_string) + +# Same as pattern_lua_quoted_single, but for [[ ... ]] string delimiters +pattern_lua_bracketed_single = compile_func_call_pattern(pattern_lua_square_bracket_string) # Handles "concatenation" .. " of strings" pattern_concat = re.compile(r'["\'][\s]*\.\.[\s]*["\']', re.DOTALL) @@ -281,9 +307,17 @@ def read_lua_file_strings(lua_file): with open(lua_file, encoding='utf-8') as text_file: text = text_file.read() + strings = [] + + for s in pattern_lua_quoted_single.findall(text): + strings.append(s[1]) + for s in pattern_lua_bracketed_single.findall(text): + strings.append(s) + + # Only concatenate strings after matching + # single parameter call (without parantheses) text = re.sub(pattern_concat, "", text) - strings = [] for s in pattern_lua_quoted.findall(text): strings.append(s[1]) for s in pattern_lua_bracketed.findall(text): From 83bc362dacfdef2bdf18cae5e2c52f526e8431c5 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Sun, 26 May 2024 14:28:30 +0200 Subject: [PATCH 36/67] Mark Redis database backend as deprecated (#14679) --- src/database/database-redis.cpp | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/database/database-redis.cpp b/src/database/database-redis.cpp index a9e549c33..a9a4a37f1 100644 --- a/src/database/database-redis.cpp +++ b/src/database/database-redis.cpp @@ -32,6 +32,9 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include +#if VERSION_MAJOR > 5 || VERSION_MINOR > 9 +#define DEPRECATION_PERIOD_OVER +#endif Database_Redis::Database_Redis(Settings &conf) { @@ -66,6 +69,14 @@ Database_Redis::Database_Redis(Settings &conf) } freeReplyObject(reply); } + + warningstream << "/!\\ You are using the deprecated redis backend. " +#ifdef DEPRECATION_PERIOD_OVER + << "This backend is only still supported for migrations. /!\\\n" +#else + << "This backend will become read-only in the next release. /!\\\n" +#endif + << "Please migrate to SQLite3 or PostgreSQL instead." << std::endl; } Database_Redis::~Database_Redis() @@ -73,16 +84,22 @@ Database_Redis::~Database_Redis() redisFree(ctx); } -void Database_Redis::beginSave() { +void Database_Redis::beginSave() +{ +#ifdef DEPRECATION_PERIOD_OVER + throw DatabaseException("Redis backend is read-only, see deprecation notice."); +#else redisReply *reply = static_cast(redisCommand(ctx, "MULTI")); if (!reply) { throw DatabaseException(std::string( "Redis command 'MULTI' failed: ") + ctx->errstr); } freeReplyObject(reply); +#endif } -void Database_Redis::endSave() { +void Database_Redis::endSave() +{ redisReply *reply = static_cast(redisCommand(ctx, "EXEC")); if (!reply) { throw DatabaseException(std::string( From b1fa430dad8675b3c0efd6b912bf93019a8699d3 Mon Sep 17 00:00:00 2001 From: grorp Date: Sun, 26 May 2024 19:49:32 +0200 Subject: [PATCH 37/67] Android: Don't crash if there is no web browser installed (#14683) --- .../src/main/java/net/minetest/minetest/GameActivity.java | 8 +++++++- android/app/src/main/res/values/strings.xml | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/android/app/src/main/java/net/minetest/minetest/GameActivity.java b/android/app/src/main/java/net/minetest/minetest/GameActivity.java index 2646721d1..b0e301c53 100644 --- a/android/app/src/main/java/net/minetest/minetest/GameActivity.java +++ b/android/app/src/main/java/net/minetest/minetest/GameActivity.java @@ -23,6 +23,7 @@ package net.minetest.minetest; import org.libsdl.app.SDLActivity; import android.content.Intent; +import android.content.ActivityNotFoundException; import android.net.Uri; import android.os.Bundle; import android.text.InputType; @@ -33,6 +34,7 @@ import android.view.WindowManager; import android.view.inputmethod.InputMethodManager; import android.widget.Button; import android.widget.LinearLayout; +import android.widget.Toast; import android.content.res.Configuration; import androidx.annotation.Keep; @@ -201,7 +203,11 @@ public class GameActivity extends SDLActivity { public void openURI(String uri) { Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri)); - startActivity(browserIntent); + try { + startActivity(browserIntent); + } catch (ActivityNotFoundException e) { + runOnUiThread(() -> Toast.makeText(this, R.string.no_web_browser, Toast.LENGTH_SHORT).show()); + } } public String getUserDataPath() { diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index 9eb1d3ca1..5885a7b7a 100644 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -7,4 +7,5 @@ Loading Minetest Less than 1 minute… Done + No web browser found From f3c91e4f9659b9a3377dc7bf539d1d256ce8a5aa Mon Sep 17 00:00:00 2001 From: Gregor Parzefall Date: Fri, 24 May 2024 17:34:32 +0200 Subject: [PATCH 38/67] Immediately apply gui_scaling changes to IGUISkin --- src/client/clientlauncher.cpp | 52 ++++++++++++++++++++++++----------- src/client/clientlauncher.h | 4 ++- 2 files changed, 39 insertions(+), 17 deletions(-) diff --git a/src/client/clientlauncher.cpp b/src/client/clientlauncher.cpp index da8118a7e..6379fc141 100644 --- a/src/client/clientlauncher.cpp +++ b/src/client/clientlauncher.cpp @@ -36,6 +36,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "network/networkexceptions.h" #include #include +#include #if USE_SOUND #include "sound/sound_openal.h" @@ -68,6 +69,7 @@ static void dump_start_data(const GameStartData &data) ClientLauncher::~ClientLauncher() { delete input; + g_settings->deregisterChangedCallback("gui_scaling", setting_changed_callback, this); delete g_fontengine; g_fontengine = nullptr; @@ -126,7 +128,8 @@ bool ClientLauncher::run(GameStartData &start_data, const Settings &cmd_args) setAttribute(scene::ALLOW_ZWRITE_ON_TRANSPARENT, true); guienv = m_rendering_engine->get_gui_env(); - init_guienv(guienv); + config_guienv(); + g_settings->registerChangedCallback("gui_scaling", setting_changed_callback, this); g_fontengine = new FontEngine(guienv); @@ -326,7 +329,12 @@ void ClientLauncher::init_input() } } -void ClientLauncher::init_guienv(gui::IGUIEnvironment *guienv) +void ClientLauncher::setting_changed_callback(const std::string &name, void *data) +{ + static_cast(data)->config_guienv(); +} + +void ClientLauncher::config_guienv() { gui::IGUISkin *skin = guienv->getSkin(); @@ -345,23 +353,35 @@ void ClientLauncher::init_guienv(gui::IGUIEnvironment *guienv) skin->setSize(gui::EGDS_CHECK_BOX_WIDTH, (s32)(17.0f * density)); skin->setSize(gui::EGDS_SCROLLBAR_SIZE, (s32)(21.0f * density)); skin->setSize(gui::EGDS_WINDOW_BUTTON_WIDTH, (s32)(15.0f * density)); + + static u32 orig_sprite_id = skin->getIcon(gui::EGDI_CHECK_BOX_CHECKED); + static std::unordered_map sprite_ids; + if (density > 1.5f) { - std::string sprite_path = porting::path_share + "/textures/base/pack/"; - if (density > 3.5f) - sprite_path.append("checkbox_64.png"); - else if (density > 2.0f) - sprite_path.append("checkbox_32.png"); - else - sprite_path.append("checkbox_16.png"); // Texture dimensions should be a power of 2 - gui::IGUISpriteBank *sprites = skin->getSpriteBank(); - video::IVideoDriver *driver = m_rendering_engine->get_video_driver(); - video::ITexture *sprite_texture = driver->getTexture(sprite_path.c_str()); - if (sprite_texture) { - s32 sprite_id = sprites->addTextureAsSprite(sprite_texture); - if (sprite_id != -1) - skin->setIcon(gui::EGDI_CHECK_BOX_CHECKED, sprite_id); + std::string path = porting::path_share + "/textures/base/pack/"; + if (density > 3.5f) + path.append("checkbox_64.png"); + else if (density > 2.0f) + path.append("checkbox_32.png"); + else + path.append("checkbox_16.png"); + + auto cached_id = sprite_ids.find(path); + if (cached_id != sprite_ids.end()) { + skin->setIcon(gui::EGDI_CHECK_BOX_CHECKED, cached_id->second); + } else { + gui::IGUISpriteBank *sprites = skin->getSpriteBank(); + video::IVideoDriver *driver = m_rendering_engine->get_video_driver(); + video::ITexture *texture = driver->getTexture(path.c_str()); + s32 id = sprites->addTextureAsSprite(texture); + if (id != -1) { + skin->setIcon(gui::EGDI_CHECK_BOX_CHECKED, id); + sprite_ids.emplace(path, id); + } } + } else { + skin->setIcon(gui::EGDI_CHECK_BOX_CHECKED, orig_sprite_id); } } diff --git a/src/client/clientlauncher.h b/src/client/clientlauncher.h index dc0794c88..7b070451a 100644 --- a/src/client/clientlauncher.h +++ b/src/client/clientlauncher.h @@ -38,7 +38,9 @@ private: void init_args(GameStartData &start_data, const Settings &cmd_args); bool init_engine(); void init_input(); - void init_guienv(gui::IGUIEnvironment *guienv); + + static void setting_changed_callback(const std::string &name, void *data); + void config_guienv(); bool launch_game(std::string &error_message, bool reconnect_requested, GameStartData &start_data, const Settings &cmd_args); From 3120558dd17112097800175fc011eefa1d41af0e Mon Sep 17 00:00:00 2001 From: Gregor Parzefall Date: Fri, 24 May 2024 18:19:12 +0200 Subject: [PATCH 39/67] Make the CDB dependency dialog use more space --- builtin/mainmenu/content/dlg_install.lua | 38 +++++++++++++++--------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/builtin/mainmenu/content/dlg_install.lua b/builtin/mainmenu/content/dlg_install.lua index 8c2a43b09..11cb0674b 100644 --- a/builtin/mainmenu/content/dlg_install.lua +++ b/builtin/mainmenu/content/dlg_install.lua @@ -66,35 +66,45 @@ local function get_formspec(data) message_bg = mt_color_orange end + local ENABLE_TOUCH = core.settings:get_bool("enable_touch") + + local w = ENABLE_TOUCH and 14 or 7 + local padded_w = w - 2*0.375 + local dropdown_w = ENABLE_TOUCH and 10.2 or 4.25 + local button_w = (padded_w - 0.25) / 3 + local button_pad = button_w / 2 + local formspec = { "formspec_version[3]", - "size[7,7.85]", + "size[", w, ",9.05]", + ENABLE_TOUCH and "padding[0.01,0.01]" or "position[0.5,0.55]", "style[title;border=false]", - "box[0,0;7,0.5;#3333]", - "button[0,0;7,0.5;title;", fgettext("Install $1", package.title) , "]", + "box[0,0;", w, ",0.8;#3333]", + "button[0,0;", w, ",0.8;title;", fgettext("Install $1", package.title) , "]", - "container[0.375,0.70]", + "container[0.375,1]", - "label[0,0.25;", fgettext("Base Game:"), "]", - "dropdown[2,0;4.25,0.5;selected_game;", table.concat(game_list, ","), ";", selected_game_idx, "]", + "label[0,0.4;", fgettext("Base Game:"), "]", + "dropdown[", padded_w - dropdown_w, ",0;", dropdown_w, ",0.8;selected_game;", + table.concat(game_list, ","), ";", selected_game_idx, "]", - "label[0,0.8;", fgettext("Dependencies:"), "]", + "label[0,1.1;", fgettext("Dependencies:"), "]", "tablecolumns[color;text;color;text]", - "table[0,1.1;6.25,3;packages;", table.concat(formatted_deps, ","), "]", + "table[0,1.4;", padded_w, ",3;packages;", table.concat(formatted_deps, ","), "]", "container_end[]", - "checkbox[0.375,5.1;will_install_deps;", + "checkbox[0.375,5.7;will_install_deps;", fgettext("Install missing dependencies"), ";", will_install_deps and "true" or "false", "]", - "box[0,5.4;7,1.2;", message_bg, "]", - "textarea[0.375,5.5;6.25,1;;;", message, "]", + "box[0,6;", w, ",1.8;", message_bg, "]", + "textarea[0.375,6.1;", padded_w, ",1.6;;;", message, "]", - "container[1.375,6.85]", - "button[0,0;2,0.8;install_all;", fgettext("Install"), "]", - "button[2.25,0;2,0.8;cancel;", fgettext("Cancel"), "]", + "container[", 0.375 + button_pad, ",8.05]", + "button[0,0;", button_w, ",0.8;install_all;", fgettext("Install"), "]", + "button[", 0.25 + button_w, ",0;", button_w, ",0.8;cancel;", fgettext("Cancel"), "]", "container_end[]", } From cdbbac5b6d63a986d2da3be475197446238fb375 Mon Sep 17 00:00:00 2001 From: Desour Date: Sat, 25 Mar 2023 21:40:17 +0100 Subject: [PATCH 40/67] Move sha256.c to lib/ Precompiled headers don't work if we're not a pure C++ project. --- CMakeLists.txt | 1 + lib/sha256/CMakeLists.txt | 14 ++++++++++++++ lib/sha256/cmake_config.h.in | 5 +++++ {src/util => lib/sha256}/sha256.c | 8 ++------ {src/util => lib/sha256/sha256}/sha256.h | 0 src/CMakeLists.txt | 2 ++ src/script/lua_api/l_util.cpp | 4 ++-- src/util/CMakeLists.txt | 1 - src/util/srp.cpp | 2 +- 9 files changed, 27 insertions(+), 10 deletions(-) create mode 100644 lib/sha256/CMakeLists.txt create mode 100644 lib/sha256/cmake_config.h.in rename {src/util => lib/sha256}/sha256.c (99%) rename {src/util => lib/sha256/sha256}/sha256.h (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4c6c60ba9..2cd2e7336 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -277,6 +277,7 @@ find_package(Lua REQUIRED) if(NOT USE_LUAJIT) add_subdirectory(lib/bitop) endif() +add_subdirectory(lib/sha256) if(BUILD_UNITTESTS OR BUILD_BENCHMARKS) add_subdirectory(lib/catch2) diff --git a/lib/sha256/CMakeLists.txt b/lib/sha256/CMakeLists.txt new file mode 100644 index 000000000..555cb8ba9 --- /dev/null +++ b/lib/sha256/CMakeLists.txt @@ -0,0 +1,14 @@ +project(sha256 C) + +add_library(sha256 STATIC sha256.c) + +target_include_directories(sha256 INTERFACE .) + +INCLUDE(CheckIncludeFiles) +check_include_files(endian.h HAVE_ENDIAN_H) + +configure_file( + "${PROJECT_SOURCE_DIR}/cmake_config.h.in" + "${PROJECT_BINARY_DIR}/cmake_config.h" +) +target_include_directories(sha256 PRIVATE "${PROJECT_BINARY_DIR}") diff --git a/lib/sha256/cmake_config.h.in b/lib/sha256/cmake_config.h.in new file mode 100644 index 000000000..1ce07a107 --- /dev/null +++ b/lib/sha256/cmake_config.h.in @@ -0,0 +1,5 @@ +// Filled in by the build system + +#pragma once + +#cmakedefine HAVE_ENDIAN_H diff --git a/src/util/sha256.c b/lib/sha256/sha256.c similarity index 99% rename from src/util/sha256.c rename to lib/sha256/sha256.c index 2c1c6303f..56bdec098 100644 --- a/src/util/sha256.c +++ b/lib/sha256/sha256.c @@ -56,17 +56,13 @@ #include #include -#include "util/sha256.h" +#include "sha256/sha256.h" #if defined(_MSC_VER) && !defined(__clang__) && !defined(__attribute__) #define __attribute__(a) #endif -/* pull HAVE_ENDIAN_H from Minetest */ -#include "config.h" -#if !HAVE_ENDIAN_H -#undef HAVE_ENDIAN_H -#endif +#include "cmake_config.h" /* HAVE_ENDIAN_H */ /** endian.h **/ /* diff --git a/src/util/sha256.h b/lib/sha256/sha256/sha256.h similarity index 100% rename from src/util/sha256.h rename to lib/sha256/sha256/sha256.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6ea544980..a37b02f87 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -565,6 +565,7 @@ if(BUILD_CLIENT) ${GMP_LIBRARY} ${JSON_LIBRARY} ${LUA_BIT_LIBRARY} + sha256 ${FREETYPE_LIBRARY} ${PLATFORM_LIBS} # on Android, Minetest depends on SDL2 directly @@ -637,6 +638,7 @@ if(BUILD_SERVER) ${JSON_LIBRARY} ${LUA_LIBRARY} ${LUA_BIT_LIBRARY} + sha256 ${GMP_LIBRARY} ${PLATFORM_LIBS} ) diff --git a/src/script/lua_api/l_util.cpp b/src/script/lua_api/l_util.cpp index f98eb0288..c868f949c 100644 --- a/src/script/lua_api/l_util.cpp +++ b/src/script/lua_api/l_util.cpp @@ -42,7 +42,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "version.h" #include "util/hex.h" #include "util/sha1.h" -#include "util/sha256.h" +#include #include "util/png.h" #include @@ -573,7 +573,7 @@ int ModApiUtil::l_sha256(lua_State *L) auto data = readParam(L, 1); bool hex = !lua_isboolean(L, 2) || !readParam(L, 2); - + std::string data_sha256; data_sha256.resize(SHA256_DIGEST_LENGTH); SHA256(reinterpret_cast(data.data()), data.size(), diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index 68e9eae5f..01b932c72 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -13,7 +13,6 @@ set(UTIL_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/quicktune.cpp ${CMAKE_CURRENT_SOURCE_DIR}/serialize.cpp ${CMAKE_CURRENT_SOURCE_DIR}/sha1.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/sha256.c ${CMAKE_CURRENT_SOURCE_DIR}/string.cpp ${CMAKE_CURRENT_SOURCE_DIR}/srp.cpp ${CMAKE_CURRENT_SOURCE_DIR}/timetaker.cpp diff --git a/src/util/srp.cpp b/src/util/srp.cpp index a290c9995..ea64efca6 100644 --- a/src/util/srp.cpp +++ b/src/util/srp.cpp @@ -50,7 +50,7 @@ #include #endif -#include "util/sha256.h" +#include #include "srp.h" //#define CSRP_USE_SHA1 From 9da5c5e2d0f71a62cb52e59a4ea3b9c2a89d8722 Mon Sep 17 00:00:00 2001 From: Desour Date: Sat, 25 Mar 2023 23:19:05 +0100 Subject: [PATCH 41/67] Add precompiled header support Note: the header is not included in the default precompiled_headers.txt, because we don't use it yet, and it might be big --- doc/compiling/README.md | 2 + src/CMakeLists.txt | 27 ++++++++++ src/precompiled_headers.txt | 103 ++++++++++++++++++++++++++++++++++++ 3 files changed, 132 insertions(+) create mode 100644 src/precompiled_headers.txt diff --git a/doc/compiling/README.md b/doc/compiling/README.md index 3652c2d74..a1ab1ebbd 100644 --- a/doc/compiling/README.md +++ b/doc/compiling/README.md @@ -20,6 +20,8 @@ General options and their default values: SemiDebug - Partially optimized debug build RelWithDebInfo - Release build with debug information MinSizeRel - Release build with -Os passed to compiler to make executable as small as possible + PRECOMPILE_HEADERS=FALSE - Precompile some headers (experimental; requires CMake 3.16 or later) + PRECOMPILED_HEADERS_PATH= - Path to a file listing all headers to precompile (default points to src/precompiled_headers.txt) ENABLE_CURL=ON - Build with cURL; Enables use of online mod repo, public serverlist and remote media fetching via http ENABLE_CURSES=ON - Build with (n)curses; Enables a server side terminal (command line option: --terminal) ENABLE_GETTEXT=ON - Build with Gettext; Allows using translations diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a37b02f87..bcbe6d7f5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -48,6 +48,25 @@ if(NOT (BUILD_CLIENT OR BUILD_SERVER)) endif() +option(PRECOMPILE_HEADERS "Precompile some headers (experimental; requires CMake 3.16 or later)" FALSE) +set(PRECOMPILED_HEADERS_PATH "" CACHE FILEPATH "Path to a file listing all headers to precompile") + +if(PRECOMPILE_HEADERS) + if(${CMAKE_VERSION} VERSION_LESS 3.16) + message(FATAL_ERROR "PRECOMPILE_HEADERS is on, but precompiled headers require at least CMake 3.16.") + endif() + if(PRECOMPILED_HEADERS_PATH) + set(PRECOMPILED_HEADERS ${PRECOMPILED_HEADERS_PATH}) + else() + set(PRECOMPILED_HEADERS "${CMAKE_SOURCE_DIR}/src/precompiled_headers.txt") + endif() + message(STATUS "Reading headers to precompile from: ${PRECOMPILED_HEADERS}") + # ignore lines that begin with # and empty lines + file(STRINGS ${PRECOMPILED_HEADERS} PRECOMPILED_HEADERS_LIST REGEX "^[^#].*$") + set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${PRECOMPILED_HEADERS}) +endif() + + option(ENABLE_CURL "Enable cURL support for fetching media" TRUE) set(USE_CURL FALSE) @@ -619,6 +638,10 @@ if(BUILD_CLIENT) if(BUILD_UNITTESTS OR BUILD_BENCHMARKS) target_link_libraries(${PROJECT_NAME} Catch2::Catch2) endif() + + if(PRECOMPILE_HEADERS) + target_precompile_headers(${PROJECT_NAME} PRIVATE ${PRECOMPILED_HEADERS_LIST}) + endif() endif(BUILD_CLIENT) @@ -682,6 +705,10 @@ if(BUILD_SERVER) if(BUILD_UNITTESTS OR BUILD_BENCHMARKS) target_link_libraries(${PROJECT_NAME}server Catch2::Catch2) endif() + + if(PRECOMPILE_HEADERS) + target_precompile_headers(${PROJECT_NAME}server PRIVATE ${PRECOMPILED_HEADERS_LIST}) + endif() endif(BUILD_SERVER) # See issue #4638 diff --git a/src/precompiled_headers.txt b/src/precompiled_headers.txt new file mode 100644 index 000000000..24c92b783 --- /dev/null +++ b/src/precompiled_headers.txt @@ -0,0 +1,103 @@ + +# stdlib +# ------ + +# C stuff: + + + + + + + + + + + + + + + + + + + + + + + + + +# Containers: + + + + + + + + + + + + +# Input/Output: + + + + + + + + + + +# Multi-threading: + + + + + + + +# Other: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# libs +# ---- + +# jsoncpp + From 43df39c4f76c75af4f6d54101c9abac26398cb70 Mon Sep 17 00:00:00 2001 From: Desour Date: Tue, 9 Apr 2024 15:35:32 +0200 Subject: [PATCH 42/67] Sound loading: Improve error handling --- src/client/sound/ogg_file.cpp | 85 +++++++++++++++++++++++++++++------ 1 file changed, 72 insertions(+), 13 deletions(-) diff --git a/src/client/sound/ogg_file.cpp b/src/client/sound/ogg_file.cpp index 62cc71327..17bc7be20 100644 --- a/src/client/sound/ogg_file.cpp +++ b/src/client/sound/ogg_file.cpp @@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "ogg_file.h" +#include #include // memcpy namespace sound { @@ -98,18 +99,31 @@ const ov_callbacks OggVorbisBufferSource::s_ov_callbacks = { std::optional RAIIOggFile::getDecodeInfo(const std::string &filename_for_logging) { OggFileDecodeInfo ret; - - vorbis_info *pInfo = ov_info(&m_file, -1); - if (!pInfo) - return std::nullopt; - ret.name_for_logging = filename_for_logging; - if (pInfo->channels == 1) { + long num_logical_bitstreams = ov_streams(&m_file); + if (num_logical_bitstreams < 1) { + warningstream << "Audio: Can't decode. Has not even one logical bitstream (but " + << num_logical_bitstreams << "): " + << ret.name_for_logging << std::endl; + return std::nullopt; + } + + // We only support sounds where the sample rate and channel count doesn't + // change. + // Read the info for the first logical bitstream: + vorbis_info *info0 = ov_info(&m_file, 0); + if (!info0) { + warningstream << "Audio: Can't decode. ov_info failed for: " + << ret.name_for_logging << std::endl; + return std::nullopt; + } + + if (info0->channels == 1) { ret.is_stereo = false; ret.format = AL_FORMAT_MONO16; ret.bytes_per_sample = 2; - } else if (pInfo->channels == 2) { + } else if (info0->channels == 2) { ret.is_stereo = true; ret.format = AL_FORMAT_STEREO16; ret.bytes_per_sample = 4; @@ -119,10 +133,42 @@ std::optional RAIIOggFile::getDecodeInfo(const std::string &f return std::nullopt; } - ret.freq = pInfo->rate; + ret.freq = info0->rate; - ret.length_samples = static_cast(ov_pcm_total(&m_file, -1)); - ret.length_seconds = static_cast(ov_time_total(&m_file, -1)); + if (!ov_seekable(&m_file)) { + warningstream << "Audio: Can't decode. Sound is not seekable, can't get length: " + << ret.name_for_logging << std::endl; + return std::nullopt; + } + + auto pcm_total = ov_pcm_total(&m_file, -1); + assert(pcm_total >= 0); + auto time_total = ov_time_total(&m_file, -1); + assert(time_total >= 0); + ret.length_samples = static_cast(pcm_total); + ret.length_seconds = static_cast(time_total); + + // Check that channel count and sample rate do indeed not change + for (int strm = 1; strm < num_logical_bitstreams; ++strm) { + vorbis_info *info = ov_info(&m_file, strm); + if (!info) { + warningstream << "Audio: Can't decode. ov_info failed for: " + << ret.name_for_logging << std::endl; + return std::nullopt; + } + if (info->channels != info0->channels) { + warningstream << "Audio: Can't decode. Channel count changes from " + << info0->channels << " to " << info->channels << ": " + << ret.name_for_logging << std::endl; + return std::nullopt; + } + if (info->rate != info0->rate) { + warningstream << "Audio: Can't decode. Sample rate changes from " + << info0->rate << " to " << info->rate << ": " + << ret.name_for_logging << std::endl; + return std::nullopt; + } + } return ret; } @@ -134,6 +180,9 @@ RAIIALSoundBuffer RAIIOggFile::loadBuffer(const OggFileDecodeInfo &decode_info, constexpr int word_size = 2; // we use s16 samples constexpr int word_signed = 1; // ^ + assert(pcm_end <= decode_info.length_samples); + assert(pcm_start <= decode_info.length_samples); + // seek if (ov_pcm_tell(&m_file) != pcm_start) { if (ov_pcm_seek(&m_file, pcm_start) != 0) { @@ -141,6 +190,7 @@ RAIIALSoundBuffer RAIIOggFile::loadBuffer(const OggFileDecodeInfo &decode_info, << decode_info.name_for_logging << std::endl; return RAIIALSoundBuffer(); } + assert(ov_pcm_tell(&m_file) == pcm_start); } const size_t size = static_cast(pcm_end - pcm_start) @@ -150,14 +200,23 @@ RAIIALSoundBuffer RAIIOggFile::loadBuffer(const OggFileDecodeInfo &decode_info, // read size bytes size_t read_count = 0; - int bitStream; + int bitstream; while (read_count < size) { // Read up to a buffer's worth of decoded sound data long num_bytes = ov_read(&m_file, &snd_buffer[read_count], size - read_count, - endian, word_size, word_signed, &bitStream); + endian, word_size, word_signed, &bitstream); if (num_bytes <= 0) { - warningstream << "Audio: Error decoding " + std::string_view errstr = [&]{ + switch (num_bytes) { + case 0: return "EOF"; + case OV_HOLE: return "OV_HOLE"; + case OV_EBADLINK: return "OV_EBADLINK"; + case OV_EINVAL: return "OV_EINVAL"; + default: return "unknown error"; + } + }(); + warningstream << "Audio: Error decoding (" << errstr << "): " << decode_info.name_for_logging << std::endl; return RAIIALSoundBuffer(); } From f836a47bc1a9dd021b18dca2f45c08c085adb71c Mon Sep 17 00:00:00 2001 From: Desour Date: Tue, 9 Apr 2024 15:54:03 +0200 Subject: [PATCH 43/67] Sound loading: Fix issues where ov_read skips samples --- src/client/sound/ogg_file.cpp | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/client/sound/ogg_file.cpp b/src/client/sound/ogg_file.cpp index 17bc7be20..11659c706 100644 --- a/src/client/sound/ogg_file.cpp +++ b/src/client/sound/ogg_file.cpp @@ -184,13 +184,15 @@ RAIIALSoundBuffer RAIIOggFile::loadBuffer(const OggFileDecodeInfo &decode_info, assert(pcm_start <= decode_info.length_samples); // seek - if (ov_pcm_tell(&m_file) != pcm_start) { + s64 current_pcm = ov_pcm_tell(&m_file); + if (current_pcm != pcm_start) { if (ov_pcm_seek(&m_file, pcm_start) != 0) { - warningstream << "Audio: Error decoding (could not seek) " + warningstream << "Audio: Error decoding (could not seek): " << decode_info.name_for_logging << std::endl; return RAIIALSoundBuffer(); } assert(ov_pcm_tell(&m_file) == pcm_start); + current_pcm = pcm_start; } const size_t size = static_cast(pcm_end - pcm_start) @@ -199,6 +201,7 @@ RAIIALSoundBuffer RAIIOggFile::loadBuffer(const OggFileDecodeInfo &decode_info, std::unique_ptr snd_buffer(new char[size]); // read size bytes + s64 last_byte_offset = current_pcm * decode_info.bytes_per_sample; size_t read_count = 0; int bitstream; while (read_count < size) { @@ -221,6 +224,25 @@ RAIIALSoundBuffer RAIIOggFile::loadBuffer(const OggFileDecodeInfo &decode_info, return RAIIALSoundBuffer(); } + // This usually doesn't happen, but for some sounds ov_read seems to skip + // some samples, see #14453. + s64 current_byte_offset = ov_pcm_tell(&m_file) * decode_info.bytes_per_sample; + if (current_byte_offset != last_byte_offset + num_bytes) { + infostream << "Audio: ov_read skipped " + << current_byte_offset - (last_byte_offset + num_bytes) + << " bytes, re-seeking: " + << decode_info.name_for_logging << std::endl; + s64 expected_offset = (last_byte_offset + num_bytes) / decode_info.bytes_per_sample; + if (ov_pcm_seek(&m_file, expected_offset) != 0) { + warningstream << "Audio: Error decoding (could not seek): " + << decode_info.name_for_logging << std::endl; + return RAIIALSoundBuffer(); + } + assert(ov_pcm_tell(&m_file) == expected_offset); + current_byte_offset = last_byte_offset + num_bytes; + } + last_byte_offset = current_byte_offset; + read_count += num_bytes; } From 670bb32b2cbeaea41e37853822017371d8b4ced1 Mon Sep 17 00:00:00 2001 From: SmallJoker Date: Wed, 29 May 2024 19:46:24 +0200 Subject: [PATCH 44/67] Particles: fix crash caused by absent texture Introduced in commit f8bff34. The related code does already expect that 'texture.ref' may be nullptr. --- src/client/particles.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/client/particles.cpp b/src/client/particles.cpp index 638505846..c19282424 100644 --- a/src/client/particles.cpp +++ b/src/client/particles.cpp @@ -1008,7 +1008,6 @@ video::SMaterial ParticleManager::getMaterialForParticle(const ClientParticleTex video::EMFN_MODULATE_1X, video::EAS_TEXTURE | video::EAS_VERTEX_COLOR); material.BlendOperation = blendop; - assert(texture.ref); material.setTexture(0, texture.ref); return material; From abf353c178935df7b7149c1020a4ef67264e53cb Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Wed, 29 May 2024 19:10:22 +0100 Subject: [PATCH 45/67] Update no games message to give more context (#14695) --- builtin/mainmenu/tab_local.lua | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/builtin/mainmenu/tab_local.lua b/builtin/mainmenu/tab_local.lua index 98ba17299..1ed08d825 100644 --- a/builtin/mainmenu/tab_local.lua +++ b/builtin/mainmenu/tab_local.lua @@ -156,10 +156,18 @@ local function get_formspec(tabview, name, tabdata) -- Point the player to ContentDB when no games are found if #pkgmgr.games == 0 then + local W = tabview.width + local H = tabview.height + + local hypertext = "" .. + fgettext_ne("Minetest is a game-creation platform that allows you to play many different games.") .. "\n" .. + fgettext_ne("Minetest doesn't come with a game by default.") .. " " .. + fgettext_ne("You need to install a game before you can create a world.") + + local button_y = H * 2/3 - 0.6 return table.concat({ - "style[label_button;border=false]", - "button[2.75,1.5;10,1;label_button;", fgettext("You have no games installed."), "]", - "button[5.25,3.5;5,1.2;game_open_cdb;", fgettext("Install a game"), "]"}) + "hypertext[0.375,0;", W - 2*0.375, ",", button_y, ";ht;", core.formspec_escape(hypertext), "]", + "button[5.25,", button_y, ";5,1.2;game_open_cdb;", fgettext("Install a game"), "]"}) end local retval = "" From a4768d163804d6e0ca5616dd4639fd510c53933f Mon Sep 17 00:00:00 2001 From: Lars Mueller Date: Fri, 31 May 2024 21:35:15 +0200 Subject: [PATCH 46/67] Fix fog moon tint not working --- src/client/sky.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/client/sky.cpp b/src/client/sky.cpp index 705161100..92e5df218 100644 --- a/src/client/sky.cpp +++ b/src/client/sky.cpp @@ -490,9 +490,9 @@ void Sky::update(float time_of_day, float time_brightness, ); } else { pointcolor_moon_f = video::SColorf( - (m_sky_params.fog_moon_tint.getRed() / 255) * pointcolor_light, - (m_sky_params.fog_moon_tint.getGreen() / 255) * pointcolor_light, - (m_sky_params.fog_moon_tint.getBlue() / 255) * pointcolor_light, + (m_sky_params.fog_moon_tint.getRed() / 255.0f) * pointcolor_light, + (m_sky_params.fog_moon_tint.getGreen() / 255.0f) * pointcolor_light, + (m_sky_params.fog_moon_tint.getBlue() / 255.0f) * pointcolor_light, 1 ); } From 140b9e5a5a40476659cad689621fc01e8b1182b1 Mon Sep 17 00:00:00 2001 From: sfence Date: Sat, 1 Jun 2024 16:36:20 +0200 Subject: [PATCH 47/67] Allow game to specify first and last mod in mod loading order (#14177) Co-authored-by: Lars Mueller Co-authored-by: sfan5 --- doc/lua_api.md | 2 + games/devtest/game.conf | 2 + games/devtest/mods/first_mod/init.lua | 1 + games/devtest/mods/first_mod/mod.conf | 2 + games/devtest/mods/last_mod/init.lua | 1 + games/devtest/mods/last_mod/mod.conf | 5 ++ games/devtest/mods/unittests/mod.conf | 3 +- src/content/mod_configuration.cpp | 70 ++++++++++++++++--- src/content/mod_configuration.h | 3 + src/content/subgames.cpp | 96 +++++++++++++------------- src/content/subgames.h | 14 +++- src/unittest/test_servermodmanager.cpp | 6 +- 12 files changed, 141 insertions(+), 64 deletions(-) create mode 100644 games/devtest/mods/first_mod/init.lua create mode 100644 games/devtest/mods/first_mod/mod.conf create mode 100644 games/devtest/mods/last_mod/init.lua create mode 100644 games/devtest/mods/last_mod/mod.conf diff --git a/doc/lua_api.md b/doc/lua_api.md index 4eea2f7f3..3bdf48c01 100644 --- a/doc/lua_api.md +++ b/doc/lua_api.md @@ -63,6 +63,8 @@ The game directory can contain the following files: * `name`: (Deprecated) same as title. * `description`: Short description to be shown in the content tab. See [Translating content meta](#translating-content-meta). + * `first_mod`: Use this to specify the mod that must be loaded before any other mod. + * `last_mod`: Use this to specify the mod that must be loaded after all other mods * `allowed_mapgens = ` e.g. `allowed_mapgens = v5,v6,flat` Mapgens not in this list are removed from the list of mapgens for the diff --git a/games/devtest/game.conf b/games/devtest/game.conf index 0f5656c99..8184881a2 100644 --- a/games/devtest/game.conf +++ b/games/devtest/game.conf @@ -1,2 +1,4 @@ title = Development Test description = Testing environment to help with testing the engine features of Minetest. It can also be helpful in mod development. +first_mod = first_mod +last_mod = last_mod diff --git a/games/devtest/mods/first_mod/init.lua b/games/devtest/mods/first_mod/init.lua new file mode 100644 index 000000000..3909a39cc --- /dev/null +++ b/games/devtest/mods/first_mod/init.lua @@ -0,0 +1 @@ +-- Nothing to do here, loading order is tested in C++ unittests. diff --git a/games/devtest/mods/first_mod/mod.conf b/games/devtest/mods/first_mod/mod.conf new file mode 100644 index 000000000..d35fa8d28 --- /dev/null +++ b/games/devtest/mods/first_mod/mod.conf @@ -0,0 +1,2 @@ +name = first_mod +description = Mod which should be loaded before every other mod. diff --git a/games/devtest/mods/last_mod/init.lua b/games/devtest/mods/last_mod/init.lua new file mode 100644 index 000000000..3909a39cc --- /dev/null +++ b/games/devtest/mods/last_mod/init.lua @@ -0,0 +1 @@ +-- Nothing to do here, loading order is tested in C++ unittests. diff --git a/games/devtest/mods/last_mod/mod.conf b/games/devtest/mods/last_mod/mod.conf new file mode 100644 index 000000000..734bf4c0c --- /dev/null +++ b/games/devtest/mods/last_mod/mod.conf @@ -0,0 +1,5 @@ +name = last_mod +description = Mod which should be loaded as last mod. +# Test dependencies +optional_depends = unittests +depends = first_mod diff --git a/games/devtest/mods/unittests/mod.conf b/games/devtest/mods/unittests/mod.conf index fa94e01a6..ccff73701 100644 --- a/games/devtest/mods/unittests/mod.conf +++ b/games/devtest/mods/unittests/mod.conf @@ -1,3 +1,4 @@ name = unittests description = Adds automated unit tests for the engine -depends = basenodes +# Also test that it is possible to depend on first_mod +depends = first_mod, basenodes diff --git a/src/content/mod_configuration.cpp b/src/content/mod_configuration.cpp index 47ad3e0dc..d814c1b68 100644 --- a/src/content/mod_configuration.cpp +++ b/src/content/mod_configuration.cpp @@ -24,7 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "gettext.h" #include "exceptions.h" #include "util/numeric.h" - +#include std::string ModConfiguration::getUnsatisfiedModsError() const { @@ -116,6 +116,9 @@ void ModConfiguration::addGameMods(const SubgameSpec &gamespec) std::string game_virtual_path; game_virtual_path.append("games/").append(gamespec.id).append("/mods"); addModsInPath(gamespec.gamemods_path, game_virtual_path); + + m_first_mod = gamespec.first_mod; + m_last_mod = gamespec.last_mod; } void ModConfiguration::addModsFromConfig( @@ -221,13 +224,20 @@ void ModConfiguration::checkConflictsAndDeps() void ModConfiguration::resolveDependencies() { - // Step 1: Compile a list of the mod names we're working with + // Compile a list of the mod names we're working with std::set modnames; - for (const ModSpec &mod : m_unsatisfied_mods) { - modnames.insert(mod.name); + std::optional first_mod_spec, last_mod_spec; + for (ModSpec &mod : m_unsatisfied_mods) { + if (mod.name == m_first_mod) { + first_mod_spec = mod; + } else if (mod.name == m_last_mod) { + last_mod_spec = mod; + } else { + modnames.insert(mod.name); + } } - // Step 1.5 (optional): shuffle unsatisfied mods so non declared depends get found by their devs + // Optionally shuffle unsatisfied mods so non declared depends get found by their devs if (g_settings->getBool("random_mod_load_order")) { MyRandGenerator rg; std::shuffle(m_unsatisfied_mods.begin(), @@ -236,25 +246,55 @@ void ModConfiguration::resolveDependencies() ); } - // Step 2: get dependencies (including optional dependencies) + // Check for presence of first and last mod + if (!m_first_mod.empty() && !first_mod_spec.has_value()) + throw ModError("The mod specified as first by the game was not found."); + if (!m_last_mod.empty() && !last_mod_spec.has_value()) + throw ModError("The mod specified as last by the game was not found."); + + // Check and add first mod + if (first_mod_spec.has_value()) { + // Dependencies are not allowed for first mod + if (!first_mod_spec->depends.empty() || !first_mod_spec->optdepends.empty()) + throw ModError("Mod specified by first_mod cannot have dependencies"); + + m_sorted_mods.push_back(*first_mod_spec); + } + + // Get dependencies (including optional dependencies) // of each mod, split mods into satisfied and unsatisfied std::vector satisfied; std::list unsatisfied; for (ModSpec mod : m_unsatisfied_mods) { + if (mod.name == m_first_mod || mod.name == m_last_mod) + continue; // skip, handled separately + mod.unsatisfied_depends = mod.depends; // check which optional dependencies actually exist for (const std::string &optdep : mod.optdepends) { if (modnames.count(optdep) != 0) mod.unsatisfied_depends.insert(optdep); } + mod.unsatisfied_depends.erase(m_first_mod); // first is already satisfied + + if (last_mod_spec.has_value() && mod.unsatisfied_depends.count(last_mod_spec->name) != 0) { + throw ModError("Impossible to depend on the mod specified by last_mod"); + } // if a mod has no depends it is initially satisfied - if (mod.unsatisfied_depends.empty()) + if (mod.unsatisfied_depends.empty()) { satisfied.push_back(mod); - else + } else { unsatisfied.push_back(mod); + } } - // Step 3: mods without unmet dependencies can be appended to + // All dependencies of the last mod are initially unsatisfied + if (last_mod_spec.has_value()) { + last_mod_spec->unsatisfied_depends = last_mod_spec->depends; + last_mod_spec->unsatisfied_depends.erase(m_first_mod); + } + + // Mods without unmet dependencies can be appended to // the sorted list. while (!satisfied.empty()) { ModSpec mod = satisfied.back(); @@ -270,8 +310,18 @@ void ModConfiguration::resolveDependencies() ++it; } } + if (last_mod_spec.has_value()) + last_mod_spec->unsatisfied_depends.erase(mod.name); } - // Step 4: write back list of unsatisfied mods + // Write back list of unsatisfied mods m_unsatisfied_mods.assign(unsatisfied.begin(), unsatisfied.end()); + + // Check and add last mod + if (last_mod_spec.has_value()) { + if (last_mod_spec->unsatisfied_depends.empty()) + m_sorted_mods.push_back(*last_mod_spec); + else + m_unsatisfied_mods.push_back(*last_mod_spec); + } } diff --git a/src/content/mod_configuration.h b/src/content/mod_configuration.h index e945a785a..200694652 100644 --- a/src/content/mod_configuration.h +++ b/src/content/mod_configuration.h @@ -87,6 +87,9 @@ public: void checkConflictsAndDeps(); private: + std::string m_first_mod; // "" <=> no mod + std::string m_last_mod; // "" <=> no mod + std::vector m_sorted_mods; /** diff --git a/src/content/subgames.cpp b/src/content/subgames.cpp index 611b09308..9d5d528a8 100644 --- a/src/content/subgames.cpp +++ b/src/content/subgames.cpp @@ -94,6 +94,50 @@ std::string getSubgamePathEnv() return ""; } +static SubgameSpec getSubgameSpec(const std::string &game_id, + const std::string &game_path, + const std::unordered_map &mods_paths, + const std::string &menuicon_path) +{ + const auto gamemods_path = game_path + DIR_DELIM + "mods"; + // Get meta + const std::string conf_path = game_path + DIR_DELIM + "game.conf"; + Settings conf; + conf.readConfigFile(conf_path.c_str()); + + std::string game_title; + if (conf.exists("title")) + game_title = conf.get("title"); + else if (conf.exists("name")) + game_title = conf.get("name"); + else + game_title = game_id; + + std::string game_author; + if (conf.exists("author")) + game_author = conf.get("author"); + + int game_release = 0; + if (conf.exists("release")) + game_release = conf.getS32("release"); + + std::string first_mod; + if (conf.exists("first_mod")) + first_mod = conf.get("first_mod"); + + std::string last_mod; + if (conf.exists("last_mod")) + last_mod = conf.get("last_mod"); + + SubgameSpec spec(game_id, game_path, gamemods_path, mods_paths, game_title, + menuicon_path, game_author, game_release, first_mod, last_mod); + + if (conf.exists("name") && !conf.exists("title")) + spec.deprecation_msgs.push_back("\"name\" setting in game.conf is deprecated, please use \"title\" instead"); + + return spec; +} + SubgameSpec findSubgame(const std::string &id) { if (id.empty()) @@ -137,8 +181,6 @@ SubgameSpec findSubgame(const std::string &id) if (game_path.empty()) return SubgameSpec(); - std::string gamemod_path = game_path + DIR_DELIM + "mods"; - // Find mod directories std::unordered_map mods_paths; mods_paths["mods"] = user + DIR_DELIM + "mods"; @@ -149,40 +191,13 @@ SubgameSpec findSubgame(const std::string &id) mods_paths[fs::AbsolutePath(mod_path)] = mod_path; } - // Get meta - std::string conf_path = game_path + DIR_DELIM + "game.conf"; - Settings conf; - conf.readConfigFile(conf_path.c_str()); - - std::string game_title; - if (conf.exists("title")) - game_title = conf.get("title"); - else if (conf.exists("name")) - game_title = conf.get("name"); - else - game_title = id; - - std::string game_author; - if (conf.exists("author")) - game_author = conf.get("author"); - - int game_release = 0; - if (conf.exists("release")) - game_release = conf.getS32("release"); - std::string menuicon_path; #ifndef SERVER menuicon_path = getImagePath( game_path + DIR_DELIM + "menu" + DIR_DELIM + "icon.png"); #endif - SubgameSpec spec(id, game_path, gamemod_path, mods_paths, game_title, - menuicon_path, game_author, game_release); - - if (conf.exists("name") && !conf.exists("title")) - spec.deprecation_msgs.push_back("\"name\" setting in game.conf is deprecated, please use \"title\" instead"); - - return spec; + return getSubgameSpec(id, game_path, mods_paths, menuicon_path); } SubgameSpec findWorldSubgame(const std::string &world_path) @@ -190,25 +205,8 @@ SubgameSpec findWorldSubgame(const std::string &world_path) std::string world_gameid = getWorldGameId(world_path, true); // See if world contains an embedded game; if so, use it. std::string world_gamepath = world_path + DIR_DELIM + "game"; - if (fs::PathExists(world_gamepath)) { - SubgameSpec gamespec; - gamespec.id = world_gameid; - gamespec.path = world_gamepath; - gamespec.gamemods_path = world_gamepath + DIR_DELIM + "mods"; - - Settings conf; - std::string conf_path = world_gamepath + DIR_DELIM + "game.conf"; - conf.readConfigFile(conf_path.c_str()); - - if (conf.exists("title")) - gamespec.title = conf.get("title"); - else if (conf.exists("name")) - gamespec.title = conf.get("name"); - else - gamespec.title = world_gameid; - - return gamespec; - } + if (fs::PathExists(world_gamepath)) + return getSubgameSpec(world_gameid, world_gamepath, {}, ""); return findSubgame(world_gameid); } diff --git a/src/content/subgames.h b/src/content/subgames.h index d5d168243..17a219669 100644 --- a/src/content/subgames.h +++ b/src/content/subgames.h @@ -32,6 +32,8 @@ struct SubgameSpec std::string title; std::string author; int release; + std::string first_mod; // "" <=> no mod + std::string last_mod; // "" <=> no mod std::string path; std::string gamemods_path; @@ -49,10 +51,16 @@ struct SubgameSpec const std::unordered_map &addon_mods_paths = {}, const std::string &title = "", const std::string &menuicon_path = "", - const std::string &author = "", int release = 0) : + const std::string &author = "", int release = 0, + const std::string &first_mod = "", + const std::string &last_mod = "") : id(id), - title(title), author(author), release(release), path(path), - gamemods_path(gamemods_path), addon_mods_paths(addon_mods_paths), + title(title), author(author), release(release), + first_mod(first_mod), + last_mod(last_mod), + path(path), + gamemods_path(gamemods_path), + addon_mods_paths(addon_mods_paths), menuicon_path(menuicon_path) { } diff --git a/src/unittest/test_servermodmanager.cpp b/src/unittest/test_servermodmanager.cpp index f023e3a3b..90c29e125 100644 --- a/src/unittest/test_servermodmanager.cpp +++ b/src/unittest/test_servermodmanager.cpp @@ -121,7 +121,8 @@ void TestServerModManager::testGetMods() { ServerModManager sm(m_worlddir); const auto &mods = sm.getMods(); - UASSERTEQ(bool, mods.empty(), false); + // `ls ./games/devtest/mods | wc -l` + 1 (test mod) + UASSERTEQ(std::size_t, mods.size(), 31 + 1); // Ensure we found basenodes mod (part of devtest) // and test_mod (for testing MINETEST_MOD_PATH). @@ -139,6 +140,9 @@ void TestServerModManager::testGetMods() UASSERTEQ(bool, default_found, true); UASSERTEQ(bool, test_mod_found, true); + + UASSERT(mods.front().name == "first_mod"); + UASSERT(mods.back().name == "last_mod"); } void TestServerModManager::testGetModspec() From 981d67324b5f8a63c4187195494910d4a21f9de4 Mon Sep 17 00:00:00 2001 From: grorp Date: Sat, 1 Jun 2024 17:03:06 +0200 Subject: [PATCH 48/67] Mainmenu: Unify gamedata.errormessage and messagebox formspecs (#14716) --- builtin/fstk/dialog.lua | 9 +++----- builtin/fstk/ui.lua | 27 ++++++++++++++-------- builtin/mainmenu/content/dlg_contentdb.lua | 2 +- 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/builtin/fstk/dialog.lua b/builtin/fstk/dialog.lua index c50d23855..991ec20ab 100644 --- a/builtin/fstk/dialog.lua +++ b/builtin/fstk/dialog.lua @@ -78,15 +78,12 @@ function dialog_create(name,get_formspec,buttonhandler,eventhandler) return self end +-- "message" must already be formspec-escaped, e.g. via fgettext or +-- core.formspec_escape. function messagebox(name, message) return dialog_create(name, function() - return ([[ - formspec_version[3] - size[8,3] - textarea[0.375,0.375;7.25,1.2;;;%s] - button[3,1.825;2,0.8;ok;%s] - ]]):format(message, fgettext("OK")) + return ui.get_message_formspec("", message, "ok") end, function(this, fields) if fields.ok then diff --git a/builtin/fstk/ui.lua b/builtin/fstk/ui.lua index a63cb2cd0..a3a8fed77 100644 --- a/builtin/fstk/ui.lua +++ b/builtin/fstk/ui.lua @@ -50,6 +50,20 @@ function ui.find_by_name(name) return ui.childlist[name] end +-------------------------------------------------------------------------------- +-- "title" and "message" must already be formspec-escaped, e.g. via fgettext or +-- core.formspec_escape. +function ui.get_message_formspec(title, message, btn_id) + return table.concat({ + "size[14,8]", + "real_coordinates[true]", + "set_focus[", btn_id, ";true]", + "box[0.5,1.2;13,5;#000]", + ("textarea[0.5,1.2;13,5;;%s;%s]"):format(title, message), + "button[5,6.6;4,1;", btn_id, ";" .. fgettext("OK") .. "]", + }) +end + -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Internal functions not to be called from user @@ -76,6 +90,9 @@ function ui.update() } ui.overridden = true elseif gamedata ~= nil and gamedata.errormessage ~= nil then + -- Note to API users: + -- "gamedata.errormessage" must not be formspec-escaped yet. + -- For translations, fgettext_ne should be used. local error_message = core.formspec_escape(gamedata.errormessage) local error_title @@ -84,15 +101,7 @@ function ui.update() else error_title = fgettext("An error occurred:") end - formspec = { - "size[14,8]", - "real_coordinates[true]", - "set_focus[btn_error_confirm;true]", - "box[0.5,1.2;13,5;#000]", - ("textarea[0.5,1.2;13,5;;%s;%s]"):format( - error_title, error_message), - "button[5,6.6;4,1;btn_error_confirm;" .. fgettext("OK") .. "]" - } + formspec = {ui.get_message_formspec(error_title, error_message, "btn_error_confirm")} ui.overridden = true else local active_toplevel_ui_elements = 0 diff --git a/builtin/mainmenu/content/dlg_contentdb.lua b/builtin/mainmenu/content/dlg_contentdb.lua index 4dafafc45..a975e1326 100644 --- a/builtin/mainmenu/content/dlg_contentdb.lua +++ b/builtin/mainmenu/content/dlg_contentdb.lua @@ -117,7 +117,7 @@ local function resolve_auto_install_spec() end if not resolved then - gamedata.errormessage = fgettext("The package $1 was not found.", auto_install_spec) + gamedata.errormessage = fgettext_ne("The package $1 was not found.", auto_install_spec) ui.update() auto_install_spec = nil From 833bb542fce78e2f94ca1b568c0b988234155621 Mon Sep 17 00:00:00 2001 From: grorp Date: Sun, 2 Jun 2024 21:05:16 +0200 Subject: [PATCH 49/67] Allow toggling fullscreen without restart and add keybind (#14714) --- builtin/mainmenu/settings/dlg_settings.lua | 5 +++ builtin/settingtypes.txt | 3 ++ doc/menu_lua_api.md | 3 +- irr/include/IrrlichtDevice.h | 5 +++ irr/src/CIrrDeviceSDL.cpp | 47 +++++++++++++++++----- irr/src/CIrrDeviceSDL.h | 6 +++ src/client/game.cpp | 3 +- src/client/inputhandler.cpp | 14 +++++++ src/client/inputhandler.h | 3 ++ src/client/renderingengine.cpp | 29 ++++++++++++- src/client/renderingengine.h | 1 + src/defaultsettings.cpp | 1 + src/gui/guiEngine.cpp | 13 +++++- src/gui/guiEngine.h | 2 + 14 files changed, 120 insertions(+), 15 deletions(-) diff --git a/builtin/mainmenu/settings/dlg_settings.lua b/builtin/mainmenu/settings/dlg_settings.lua index d6bbf2570..fe1e1924f 100644 --- a/builtin/mainmenu/settings/dlg_settings.lua +++ b/builtin/mainmenu/settings/dlg_settings.lua @@ -723,6 +723,11 @@ local function eventhandler(event) mm_game_theme.set_engine(true) return true end + if event == "FullscreenChange" then + -- Refresh the formspec to keep the fullscreen checkbox up to date. + ui.update() + return true + end return false end diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index 8dc37c3e7..613e54f6d 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -2399,6 +2399,9 @@ keymap_minimap (Minimap key) key KEY_KEY_V # Key for taking screenshots. keymap_screenshot (Screenshot) key KEY_F12 +# Key for toggling fullscreen mode. +keymap_fullscreen (Fullscreen key) key KEY_F11 + # Key for dropping the currently selected item. keymap_drop (Drop item key) key KEY_KEY_Q diff --git a/doc/menu_lua_api.md b/doc/menu_lua_api.md index cb1f07a90..19540a607 100644 --- a/doc/menu_lua_api.md +++ b/doc/menu_lua_api.md @@ -14,7 +14,8 @@ Callbacks * `core.button_handler(fields)`: called when a button is pressed. * `fields` = `{name1 = value1, name2 = value2, ...}` * `core.event_handler(event)` - * `event`: `"MenuQuit"`, `"KeyEnter"`, `"ExitButton"` or `"EditBoxEnter"` + * `event`: `"MenuQuit"`, `"KeyEnter"`, `"ExitButton"`, `"EditBoxEnter"` or + `"FullscreenChange"` Gamedata diff --git a/irr/include/IrrlichtDevice.h b/irr/include/IrrlichtDevice.h index 38ba8c63d..11619010c 100644 --- a/irr/include/IrrlichtDevice.h +++ b/irr/include/IrrlichtDevice.h @@ -179,6 +179,11 @@ public: /** \return True if window is fullscreen. */ virtual bool isFullscreen() const = 0; + //! Enables or disables fullscreen mode. + /** Only works on SDL. + \return True on success. */ + virtual bool setFullscreen(bool fullscreen) { return false; } + //! Checks if the window could possibly be visible. /** If this returns false, you should not do any rendering. */ virtual bool isWindowVisible() const { return true; }; diff --git a/irr/src/CIrrDeviceSDL.cpp b/irr/src/CIrrDeviceSDL.cpp index b50fd4b4a..6f2772aa6 100644 --- a/irr/src/CIrrDeviceSDL.cpp +++ b/irr/src/CIrrDeviceSDL.cpp @@ -463,13 +463,7 @@ bool CIrrDeviceSDL::createWindowWithContext() { u32 SDL_Flags = 0; - if (CreationParams.Fullscreen) { -#ifdef _IRR_EMSCRIPTEN_PLATFORM_ - SDL_Flags |= SDL_WINDOW_FULLSCREEN; -#else - SDL_Flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; -#endif - } + SDL_Flags |= getFullscreenFlag(CreationParams.Fullscreen); if (Resizable) SDL_Flags |= SDL_WINDOW_RESIZABLE; if (CreationParams.WindowMaximized) @@ -889,6 +883,14 @@ bool CIrrDeviceSDL::run() IsInBackground = false; break; + case SDL_RENDER_TARGETS_RESET: + os::Printer::log("Received SDL_RENDER_TARGETS_RESET. Rendering is probably broken.", ELL_ERROR); + break; + + case SDL_RENDER_DEVICE_RESET: + os::Printer::log("Received SDL_RENDER_DEVICE_RESET. Rendering is probably broken.", ELL_ERROR); + break; + default: break; } // end switch @@ -1157,14 +1159,37 @@ bool CIrrDeviceSDL::isWindowMaximized() const bool CIrrDeviceSDL::isFullscreen() const { -#ifdef _IRR_EMSCRIPTEN_PLATFORM_ - return SDL_GetWindowFlags(0) == SDL_WINDOW_FULLSCREEN; -#else + if (!Window) + return false; + u32 flags = SDL_GetWindowFlags(Window); + return (flags & SDL_WINDOW_FULLSCREEN) != 0 || + (flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0; +} - return CIrrDeviceStub::isFullscreen(); +u32 CIrrDeviceSDL::getFullscreenFlag(bool fullscreen) +{ + if (!fullscreen) + return 0; +#ifdef _IRR_EMSCRIPTEN_PLATFORM_ + return SDL_WINDOW_FULLSCREEN; +#else + return SDL_WINDOW_FULLSCREEN_DESKTOP; #endif } +bool CIrrDeviceSDL::setFullscreen(bool fullscreen) +{ + if (!Window) + return false; + // The SDL wiki says that this may trigger SDL_RENDER_TARGETS_RESET, but + // looking at the SDL source, this only happens with D3D, so it's not + // relevant to us. + bool success = SDL_SetWindowFullscreen(Window, getFullscreenFlag(fullscreen)) == 0; + if (!success) + os::Printer::log("SDL_SetWindowFullscreen failed", SDL_GetError(), ELL_ERROR); + return success; +} + bool CIrrDeviceSDL::isWindowVisible() const { return !IsInBackground; diff --git a/irr/src/CIrrDeviceSDL.h b/irr/src/CIrrDeviceSDL.h index a83e8cf5e..c536a8149 100644 --- a/irr/src/CIrrDeviceSDL.h +++ b/irr/src/CIrrDeviceSDL.h @@ -86,6 +86,10 @@ public: /** \return True if window is fullscreen. */ bool isFullscreen() const override; + //! Enables or disables fullscreen mode. + /** \return True on success. */ + bool setFullscreen(bool fullscreen) override; + //! Checks if the window could possibly be visible. bool isWindowVisible() const override; @@ -299,6 +303,8 @@ private: bool Resizable; + static u32 getFullscreenFlag(bool fullscreen); + core::rect lastElemPos; struct SKeyMap diff --git a/src/client/game.cpp b/src/client/game.cpp index d35bf8e08..e6e478b04 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -1164,7 +1164,8 @@ void Game::run() g_settings->getU16("screen_w"), g_settings->getU16("screen_h") ); - const bool initial_window_maximized = g_settings->getBool("window_maximized"); + const bool initial_window_maximized = !g_settings->getBool("fullscreen") && + g_settings->getBool("window_maximized"); while (m_rendering_engine->run() && !(*kill || g_gamecallback->shutdown_requested diff --git a/src/client/inputhandler.cpp b/src/client/inputhandler.cpp index 6dfd2ad35..665d77dc5 100644 --- a/src/client/inputhandler.cpp +++ b/src/client/inputhandler.cpp @@ -18,6 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include "settings.h" #include "util/numeric.h" #include "inputhandler.h" #include "gui/mainmenumanager.h" @@ -113,6 +114,19 @@ bool MyEventReceiver::OnEvent(const SEvent &event) return true; } + // This is separate from other keyboard handling so that it also works in menus. + if (event.EventType == EET_KEY_INPUT_EVENT) { + const KeyPress keyCode(event.KeyInput); + if (keyCode == getKeySetting("keymap_fullscreen")) { + if (event.KeyInput.PressedDown && !fullscreen_is_down) { + bool fullscreen = RenderingEngine::get_raw_device()->isFullscreen(); + g_settings->setBool("fullscreen", !fullscreen); + } + fullscreen_is_down = event.KeyInput.PressedDown; + return true; + } + } + // Let the menu handle events, if one is active. if (isMenuActive()) { if (g_touchscreengui) diff --git a/src/client/inputhandler.h b/src/client/inputhandler.h index f4fae2b0b..4c6db3618 100644 --- a/src/client/inputhandler.h +++ b/src/client/inputhandler.h @@ -220,6 +220,9 @@ private: // often changing keys, and keysListenedFor is expected // to change seldomly but contain lots of keys. KeyList keysListenedFor; + + // Intentionally not reset by clearInput/releaseAllKeys. + bool fullscreen_is_down = false; }; class InputHandler diff --git a/src/client/renderingengine.cpp b/src/client/renderingengine.cpp index 27ea2b76f..b0033c0e2 100644 --- a/src/client/renderingengine.cpp +++ b/src/client/renderingengine.cpp @@ -207,7 +207,12 @@ RenderingEngine::RenderingEngine(IEventReceiver *receiver) #else u16 screen_w = std::max(g_settings->getU16("screen_w"), 1); u16 screen_h = std::max(g_settings->getU16("screen_h"), 1); - bool window_maximized = g_settings->getBool("window_maximized"); + // If I… + // 1. … set fullscreen = true and window_maximized = true on startup + // 2. … set fullscreen = false later + // on Linux with SDL, everything breaks. + // => Don't do it. + bool window_maximized = !fullscreen && g_settings->getBool("window_maximized"); #endif // bpp, fsaa, vsync @@ -249,18 +254,40 @@ RenderingEngine::RenderingEngine(IEventReceiver *receiver) gui::EGST_WINDOWS_METALLIC, driver); m_device->getGUIEnvironment()->setSkin(skin); skin->drop(); + + g_settings->registerChangedCallback("fullscreen", settingChangedCallback, this); + g_settings->registerChangedCallback("window_maximized", settingChangedCallback, this); } RenderingEngine::~RenderingEngine() { sanity_check(s_singleton == this); + g_settings->deregisterChangedCallback("fullscreen", settingChangedCallback, this); + g_settings->deregisterChangedCallback("window_maximized", settingChangedCallback, this); + core.reset(); m_device->closeDevice(); m_device->drop(); s_singleton = nullptr; } +void RenderingEngine::settingChangedCallback(const std::string &name, void *data) +{ + IrrlichtDevice *device = static_cast(data)->m_device; + if (name == "fullscreen") { + device->setFullscreen(g_settings->getBool("fullscreen")); + + } else if (name == "window_maximized") { + if (!device->isFullscreen()) { + if (g_settings->getBool("window_maximized")) + device->maximizeWindow(); + else + device->restoreWindow(); + } + } +} + v2u32 RenderingEngine::_getWindowSize() const { if (core) diff --git a/src/client/renderingengine.h b/src/client/renderingengine.h index 684df1237..1a2a63513 100644 --- a/src/client/renderingengine.h +++ b/src/client/renderingengine.h @@ -168,6 +168,7 @@ public: const bool initial_window_maximized); private: + static void settingChangedCallback(const std::string &name, void *data); v2u32 _getWindowSize() const; std::unique_ptr core; diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 378d09759..f16c56db4 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -182,6 +182,7 @@ void set_default_settings() settings->setDefault("keymap_toggle_profiler", "KEY_F6"); settings->setDefault("keymap_camera_mode", "KEY_KEY_C"); settings->setDefault("keymap_screenshot", "KEY_F12"); + settings->setDefault("keymap_fullscreen", "KEY_F11"); settings->setDefault("keymap_increase_viewing_range_min", "+"); settings->setDefault("keymap_decrease_viewing_range_min", "-"); settings->setDefault("keymap_slot1", "KEY_KEY_1"); diff --git a/src/gui/guiEngine.cpp b/src/gui/guiEngine.cpp index 66f9f9864..fdc13fa14 100644 --- a/src/gui/guiEngine.cpp +++ b/src/gui/guiEngine.cpp @@ -193,6 +193,8 @@ GUIEngine::GUIEngine(JoystickController *joystick, m_script = std::make_unique(this); + g_settings->registerChangedCallback("fullscreen", fullscreenChangedCallback, this); + try { m_script->setMainMenuData(&m_data->script_data); m_data->script_data.errormessage.clear(); @@ -319,7 +321,8 @@ void GUIEngine::run() g_settings->getU16("screen_w"), g_settings->getU16("screen_h") ); - const bool initial_window_maximized = g_settings->getBool("window_maximized"); + const bool initial_window_maximized = !g_settings->getBool("fullscreen") && + g_settings->getBool("window_maximized"); FpsControl fps_control; f32 dtime = 0.0f; @@ -377,6 +380,8 @@ void GUIEngine::run() /******************************************************************************/ GUIEngine::~GUIEngine() { + g_settings->deregisterChangedCallback("fullscreen", fullscreenChangedCallback, this); + // deinitialize script first. gc destructors might depend on other stuff infostream << "GUIEngine: Deinitializing scripting" << std::endl; m_script.reset(); @@ -666,3 +671,9 @@ void GUIEngine::updateTopLeftTextSize() m_irr_toplefttext = gui::StaticText::add(m_rendering_engine->get_gui_env(), m_toplefttext, rect, false, true, 0, -1); } + +/******************************************************************************/ +void GUIEngine::fullscreenChangedCallback(const std::string &name, void *data) +{ + static_cast(data)->getScriptIface()->handleMainMenuEvent("FullscreenChange"); +} diff --git a/src/gui/guiEngine.h b/src/gui/guiEngine.h index b2b396537..fa4e1ebd3 100644 --- a/src/gui/guiEngine.h +++ b/src/gui/guiEngine.h @@ -296,4 +296,6 @@ private: bool m_clouds_enabled = true; /** data used to draw clouds */ clouddata m_cloud; + + static void fullscreenChangedCallback(const std::string &name, void *data); }; From 508b5ccc6386de700d39ff6e885d3dc553fd7d28 Mon Sep 17 00:00:00 2001 From: grorp Date: Sun, 2 Jun 2024 21:05:35 +0200 Subject: [PATCH 50/67] Document keymap_toggle_block_bounds, remove unimplemented BLOCK_BOUNDS_MAX (#14722) --- builtin/settingtypes.txt | 3 +++ src/client/game.cpp | 3 --- src/client/hud.cpp | 2 +- src/client/hud.h | 1 - 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index 613e54f6d..aca960590 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -2525,6 +2525,9 @@ keymap_toggle_debug (Debug info toggle key) key KEY_F5 # Key for toggling the display of the profiler. Used for development. keymap_toggle_profiler (Profiler toggle key) key KEY_F6 +# Key for toggling the display of mapblock boundaries. +keymap_toggle_block_bounds (Block bounds toggle key) key + # Key for switching between first- and third-person camera. keymap_camera_mode (Toggle camera mode key) key KEY_KEY_C diff --git a/src/client/game.cpp b/src/client/game.cpp index e6e478b04..2e27d6b0d 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -2427,9 +2427,6 @@ void Game::toggleBlockBounds() case Hud::BLOCK_BOUNDS_NEAR: m_game_ui->showTranslatedStatusText("Block bounds shown for nearby blocks"); break; - case Hud::BLOCK_BOUNDS_MAX: - m_game_ui->showTranslatedStatusText("Block bounds shown for all blocks"); - break; default: break; } diff --git a/src/client/hud.cpp b/src/client/hud.cpp index 6bb9c234b..637a2f500 100644 --- a/src/client/hud.cpp +++ b/src/client/hud.cpp @@ -913,7 +913,7 @@ enum Hud::BlockBoundsMode Hud::toggleBlockBounds() { m_block_bounds_mode = static_cast(m_block_bounds_mode + 1); - if (m_block_bounds_mode >= BLOCK_BOUNDS_MAX) { + if (m_block_bounds_mode > BLOCK_BOUNDS_NEAR) { m_block_bounds_mode = BLOCK_BOUNDS_OFF; } return m_block_bounds_mode; diff --git a/src/client/hud.h b/src/client/hud.h index 746a1b33e..b2b5dd09c 100644 --- a/src/client/hud.h +++ b/src/client/hud.h @@ -40,7 +40,6 @@ public: BLOCK_BOUNDS_OFF, BLOCK_BOUNDS_CURRENT, BLOCK_BOUNDS_NEAR, - BLOCK_BOUNDS_MAX } m_block_bounds_mode = BLOCK_BOUNDS_OFF; video::SColor crosshair_argb; From 445e485fc59ff6c5e434ec5b6d3e96010377bc1f Mon Sep 17 00:00:00 2001 From: Lars Mueller Date: Mon, 3 Jun 2024 01:14:15 +0200 Subject: [PATCH 51/67] Fix CI not running on Irrlicht-only PRs --- .github/workflows/android.yml | 2 ++ .github/workflows/cpp_lint.yml | 2 ++ .github/workflows/docker_image.yml | 2 ++ .github/workflows/linux.yml | 2 ++ .github/workflows/macos.yml | 3 +++ .github/workflows/windows.yml | 2 ++ 6 files changed, 13 insertions(+) diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index 040c19935..dcc991080 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -20,6 +20,8 @@ on: - 'lib/**.cpp' - 'src/**.[ch]' - 'src/**.cpp' + - 'irr/**.[ch]' + - 'irr/**.cpp' - '**/CMakeLists.txt' - 'cmake/Modules/**' - 'android/**' diff --git a/.github/workflows/cpp_lint.yml b/.github/workflows/cpp_lint.yml index 79b8ffc4e..0ec8ebf1d 100644 --- a/.github/workflows/cpp_lint.yml +++ b/.github/workflows/cpp_lint.yml @@ -20,6 +20,8 @@ on: - 'lib/**.cpp' - 'src/**.[ch]' - 'src/**.cpp' + - 'irr/**.[ch]' + - 'irr/**.cpp' - '**/CMakeLists.txt' - 'cmake/Modules/**' - 'util/ci/**' diff --git a/.github/workflows/docker_image.yml b/.github/workflows/docker_image.yml index 421d2edf4..1a2805e22 100644 --- a/.github/workflows/docker_image.yml +++ b/.github/workflows/docker_image.yml @@ -17,6 +17,8 @@ on: - 'lib/**.cpp' - 'src/**.[ch]' - 'src/**.cpp' + - 'irr/**.[ch]' + - 'irr/**.cpp' - '**/CMakeLists.txt' - 'cmake/Modules/**' - 'util/ci/**' diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index eb2b032da..95f0f004a 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -22,6 +22,8 @@ on: - 'lib/**.cpp' - 'src/**.[ch]' - 'src/**.cpp' + - 'irr/**.[ch]' + - 'irr/**.cpp' - '**/CMakeLists.txt' - 'cmake/Modules/**' - 'util/ci/**' diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index a7c670ed7..ad9982f66 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -19,6 +19,9 @@ on: - 'lib/**.cpp' - 'src/**.[ch]' - 'src/**.cpp' + - 'irr/**.[ch]' + - 'irr/**.cpp' + - 'irr/**.mm' # Objective-C(++) - '**/CMakeLists.txt' - 'cmake/Modules/**' - '.github/workflows/macos.yml' diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 9a036a24f..5765f67fa 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -21,6 +21,8 @@ on: - 'lib/**.cpp' - 'src/**.[ch]' - 'src/**.cpp' + - 'irr/**.[ch]' + - 'irr/**.cpp' - '**/CMakeLists.txt' - 'cmake/Modules/**' - 'util/buildbot/**' From 75f3a2183f439fca445c089c1eb1580a60fe4575 Mon Sep 17 00:00:00 2001 From: Alex <24834740+GreenXenith@users.noreply.github.com> Date: Mon, 3 Jun 2024 03:40:34 -0700 Subject: [PATCH 52/67] Fix and clarify skybox texture order documentation (#14680) --- doc/lua_api.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/doc/lua_api.md b/doc/lua_api.md index 3bdf48c01..fde2e726f 100644 --- a/doc/lua_api.md +++ b/doc/lua_api.md @@ -8232,7 +8232,11 @@ child will follow movement and rotation of that bone. * `"plain"`: Uses 0 textures, `base_color` used as both fog and sky. (default: `"regular"`) * `textures`: A table containing up to six textures in the following - order: Y+ (top), Y- (bottom), X- (west), X+ (east), Z+ (north), Z- (south). + order: Y+ (top), Y- (bottom), X+ (east), X- (west), Z- (south), Z+ (north). + The top and bottom textures are oriented in-line with the east (X+) face (the top edge of the + bottom texture and the bottom edge of the top texture touch the east face). + Some top and bottom textures expect to be aligned with the north face and will need to be rotated + by -90 and 90 degrees, respectively, to fit the eastward orientation. * `clouds`: Boolean for whether clouds appear. (default: `true`) * `sky_color`: A table used in `"regular"` type only, containing the following values (alpha is ignored): From ec9c000be945b8d0500fc7b751fee081aa23c13e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20M=C3=BCller?= <34514239+appgurueu@users.noreply.github.com> Date: Mon, 3 Jun 2024 20:38:09 +0200 Subject: [PATCH 53/67] Fix scrolling in scroll containers (#14702) --- irr/include/IEventReceiver.h | 1 - irr/src/CIrrDeviceOSX.mm | 2 ++ irr/src/CIrrDeviceSDL.cpp | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/irr/include/IEventReceiver.h b/irr/include/IEventReceiver.h index e0660a6f1..cf7dee3ab 100644 --- a/irr/include/IEventReceiver.h +++ b/irr/include/IEventReceiver.h @@ -331,7 +331,6 @@ struct SEvent //! A bitmap of button states. You can use isButtonPressed() to determine //! if a button is pressed or not. - //! Currently only valid if the event was EMIE_MOUSE_MOVED u32 ButtonStates; //! Is the left button pressed down? diff --git a/irr/src/CIrrDeviceOSX.mm b/irr/src/CIrrDeviceOSX.mm index 8e4843441..67c0ce05c 100644 --- a/irr/src/CIrrDeviceOSX.mm +++ b/irr/src/CIrrDeviceOSX.mm @@ -852,6 +852,7 @@ bool CIrrDeviceMacOSX::run() ievent.MouseInput.Wheel *= 10.0f; else ievent.MouseInput.Wheel *= 5.0f; + ievent.MouseInput.ButtonStates = MouseButtonStates; postMouseEvent(event, ievent); break; @@ -1048,6 +1049,7 @@ void CIrrDeviceMacOSX::storeMouseLocation() ievent.MouseInput.Event = irr::EMIE_MOUSE_MOVED; ievent.MouseInput.X = x; ievent.MouseInput.Y = y; + ievent.MouseInput.ButtonStates = MouseButtonStates; postEventFromUser(ievent); } } diff --git a/irr/src/CIrrDeviceSDL.cpp b/irr/src/CIrrDeviceSDL.cpp index 6f2772aa6..c01e6900e 100644 --- a/irr/src/CIrrDeviceSDL.cpp +++ b/irr/src/CIrrDeviceSDL.cpp @@ -667,6 +667,7 @@ bool CIrrDeviceSDL::run() #else irrevent.MouseInput.Wheel = SDL_event.wheel.y; #endif + irrevent.MouseInput.ButtonStates = MouseButtonStates; irrevent.MouseInput.Shift = (keymod & KMOD_SHIFT) != 0; irrevent.MouseInput.Control = (keymod & KMOD_CTRL) != 0; irrevent.MouseInput.X = MouseX; From 87232358d39fbff09f2b9051bd25edebbb231f8a Mon Sep 17 00:00:00 2001 From: sfan5 Date: Mon, 3 Jun 2024 20:39:02 +0200 Subject: [PATCH 54/67] Update some workflows to newer Ubuntu versions (#14668) --- .github/workflows/android.yml | 4 ++-- .github/workflows/linux.yml | 37 +++++++++++++++---------------- .github/workflows/lua.yml | 10 +++------ src/content/mod_configuration.cpp | 1 + src/mapgen/mg_biome.cpp | 1 + util/ci/build_luajit.sh | 6 +++++ util/ci/build_prometheus_cpp.sh | 6 ++--- util/ci/common.sh | 17 +++++++++----- util/ci/docker.sh | 15 ------------- 9 files changed, 45 insertions(+), 52 deletions(-) create mode 100755 util/ci/build_luajit.sh delete mode 100755 util/ci/docker.sh diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index dcc991080..0896d9abc 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -29,13 +29,13 @@ on: jobs: build: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 - name: Install deps run: | sudo apt-get update - sudo apt-get install -y --no-install-recommends gettext openjdk-11-jdk-headless + sudo apt-get install -y --no-install-recommends gettext openjdk-17-jdk-headless - name: Build AAB with Gradle # We build an AAB as well for uploading to the the Play Store. run: cd android; ./gradlew bundlerelease diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 95f0f004a..2d0c72907 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -57,21 +57,21 @@ jobs: ./bin/minetest --run-unittests # Current gcc version - gcc_12: - runs-on: ubuntu-22.04 + gcc_14: + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 - name: Install deps run: | source ./util/ci/common.sh - install_linux_deps g++-12 libluajit-5.1-dev + install_linux_deps g++-14 libluajit-5.1-dev - name: Build run: | ./util/ci/build.sh env: - CC: gcc-12 - CXX: g++-12 + CC: gcc-14 + CXX: g++-14 - name: Test run: | @@ -103,21 +103,21 @@ jobs: ./bin/minetest --run-unittests # Current clang version - clang_14: - runs-on: ubuntu-22.04 + clang_18: + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 - name: Install deps run: | source ./util/ci/common.sh - install_linux_deps clang-14 lldb + install_linux_deps clang-18 lldb - name: Build run: | ./util/ci/build.sh env: - CC: clang-14 - CXX: clang++-14 + CC: clang-18 + CXX: clang++-18 - name: Test run: | @@ -128,27 +128,26 @@ jobs: ./util/test_multiplayer.sh # Build with prometheus-cpp (server-only) - clang_9_prometheus: - name: "clang_9 (PROMETHEUS=1)" - runs-on: ubuntu-20.04 + clang_11_prometheus: + name: "clang_11 (PROMETHEUS=1)" + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 - name: Install deps run: | source ./util/ci/common.sh - install_linux_deps clang-9 + install_linux_deps clang-11 - name: Build prometheus-cpp - run: | - ./util/ci/build_prometheus_cpp.sh + run: ./util/ci/build_prometheus_cpp.sh - name: Build run: | ./util/ci/build.sh env: - CC: clang-9 - CXX: clang++-9 - CMAKE_FLAGS: "-DENABLE_PROMETHEUS=1 -DBUILD_CLIENT=0" + CC: clang-11 + CXX: clang++-11 + CMAKE_FLAGS: "-DENABLE_PROMETHEUS=1 -DBUILD_CLIENT=0 -DENABLE_CURSES=0" - name: Test run: | diff --git a/.github/workflows/lua.yml b/.github/workflows/lua.yml index 6f803d133..0073eca2e 100644 --- a/.github/workflows/lua.yml +++ b/.github/workflows/lua.yml @@ -17,7 +17,7 @@ jobs: # Note that the integration tests are also run in build.yml, but only when C++ code is changed. integration_tests: name: "Compile and run multiplayer tests" - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 - name: Install deps @@ -39,7 +39,7 @@ jobs: luacheck: name: "Builtin Luacheck and Unit Tests" - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: @@ -50,11 +50,7 @@ jobs: - uses: leafo/gh-actions-luarocks@v4.3.0 - name: Install LuaJIT - run: | - cd $HOME - git clone https://github.com/LuaJIT/LuaJIT/ - cd LuaJIT - make -j$(nproc) + run: ./util/ci/build_luajit.sh - name: Install luarocks tools run: | diff --git a/src/content/mod_configuration.cpp b/src/content/mod_configuration.cpp index d814c1b68..1dba67ef1 100644 --- a/src/content/mod_configuration.cpp +++ b/src/content/mod_configuration.cpp @@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "exceptions.h" #include "util/numeric.h" #include +#include std::string ModConfiguration::getUnsatisfiedModsError() const { diff --git a/src/mapgen/mg_biome.cpp b/src/mapgen/mg_biome.cpp index beb457c0f..83ecbd691 100644 --- a/src/mapgen/mg_biome.cpp +++ b/src/mapgen/mg_biome.cpp @@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "porting.h" #include "settings.h" +#include /////////////////////////////////////////////////////////////////////////////// diff --git a/util/ci/build_luajit.sh b/util/ci/build_luajit.sh new file mode 100755 index 000000000..6307b2780 --- /dev/null +++ b/util/ci/build_luajit.sh @@ -0,0 +1,6 @@ +#!/bin/bash -eu +cd $HOME +git clone --depth 1 https://github.com/LuaJIT/LuaJIT +pushd LuaJIT +make -j$(nproc) +popd diff --git a/util/ci/build_prometheus_cpp.sh b/util/ci/build_prometheus_cpp.sh index f3e4a5559..d2956aa5e 100755 --- a/util/ci/build_prometheus_cpp.sh +++ b/util/ci/build_prometheus_cpp.sh @@ -1,7 +1,7 @@ -#! /bin/bash -eu - +#!/bin/bash -eu cd /tmp -git clone --recursive https://github.com/jupp0r/prometheus-cpp +git clone --recursive --depth 1 --shallow-submodules \ + https://github.com/jupp0r/prometheus-cpp mkdir prometheus-cpp/build cd prometheus-cpp/build cmake .. \ diff --git a/util/ci/common.sh b/util/ci/common.sh index ac80029f0..201b182f2 100644 --- a/util/ci/common.sh +++ b/util/ci/common.sh @@ -4,7 +4,7 @@ install_linux_deps() { local pkgs=( cmake gettext postgresql - libpng-dev libjpeg-dev libgl1-mesa-dev libsdl2-dev + libpng-dev libjpeg-dev libgl1-mesa-dev libsdl2-dev libfreetype-dev libsqlite3-dev libhiredis-dev libogg-dev libgmp-dev libvorbis-dev libopenal-dev libpq-dev libleveldb-dev libcurl4-openssl-dev libzstd-dev ) @@ -12,11 +12,16 @@ install_linux_deps() { sudo apt-get update sudo apt-get install -y --no-install-recommends "${pkgs[@]}" "$@" - sudo systemctl start postgresql.service - sudo -u postgres psql <<<" - CREATE USER minetest WITH PASSWORD 'minetest'; - CREATE DATABASE minetest; - " + # set up Postgres for unit tests + if [ -n "$MINETEST_POSTGRESQL_CONNECT_STRING" ]; then + sudo systemctl start postgresql.service + sudo -u postgres psql <<<" + CREATE USER minetest WITH PASSWORD 'minetest'; + CREATE DATABASE minetest; + \c minetest + GRANT ALL ON SCHEMA public TO minetest; + " + fi } # macOS build only diff --git a/util/ci/docker.sh b/util/ci/docker.sh deleted file mode 100755 index dd671a007..000000000 --- a/util/ci/docker.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh -e -name=${CONTAINER_IMAGE}/server - -# build and publish Docker image (gitlab-ci) - -docker build . \ - -t ${name}:${CI_COMMIT_SHA} \ - -t ${name}:${CI_COMMIT_REF_NAME} \ - -t ${name}:latest - -docker push ${name}:${CI_COMMIT_SHA} -docker push ${name}:${CI_COMMIT_REF_NAME} -[ "$CI_COMMIT_BRANCH" = master ] && docker push ${name}:latest - -exit 0 From 08485f67812974c3ff2eb8daa08508de1188f72b Mon Sep 17 00:00:00 2001 From: SmallJoker Date: Wed, 5 Jun 2024 20:11:47 +0200 Subject: [PATCH 55/67] Chat: Remove tailing punctuation from clickable links --- src/chat.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/chat.cpp b/src/chat.cpp index 5331a87bd..ec84d125f 100644 --- a/src/chat.cpp +++ b/src/chat.cpp @@ -376,6 +376,13 @@ u32 ChatBuffer::formatChatLine(const ChatLine &line, u32 cols, tempchar = linestring[in_pos+frag_length]; } + // Remove tailing punctuation characters + static const std::wstring tailing_chars = L",."; + tempchar = linestring[in_pos+frag_length - 1]; + if (tailing_chars.find(tempchar) != std::wstring::npos) { + frag_length--; + } + space_pos = frag_length - 1; // This frag may need to be force-split. That's ok, urls aren't "words" if (frag_length >= remaining_in_output) { From 71893807b37c07bd428d71c47fd7cbd12bc82760 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Fri, 7 Jun 2024 16:57:30 +0200 Subject: [PATCH 56/67] Call malloc_trim() regularly to improve deallocation behavior (#14707) --- irr/include/IMeshBuffer.h | 26 +++++++++++++++++++++++ src/CMakeLists.txt | 6 ++++++ src/client/mapblock_mesh.cpp | 5 +++++ src/cmake_config.h.in | 1 + src/mapblock.cpp | 1 + src/mapgen/mg_schematic.cpp | 4 +++- src/porting.cpp | 40 +++++++++++++++++++++++++++++++++++- src/porting.h | 12 +++++++++++ src/voxel.cpp | 8 ++++++-- 9 files changed, 99 insertions(+), 4 deletions(-) diff --git a/irr/include/IMeshBuffer.h b/irr/include/IMeshBuffer.h index 3e2e3d74e..c69a12d1d 100644 --- a/irr/include/IMeshBuffer.h +++ b/irr/include/IMeshBuffer.h @@ -176,6 +176,32 @@ public: } return 0; } + + //! Calculate size of vertices and indices in memory + virtual size_t getSize() const + { + size_t ret = 0; + switch (getVertexType()) { + case video::EVT_STANDARD: + ret += sizeof(video::S3DVertex) * getVertexCount(); + break; + case video::EVT_2TCOORDS: + ret += sizeof(video::S3DVertex2TCoords) * getVertexCount(); + break; + case video::EVT_TANGENTS: + ret += sizeof(video::S3DVertexTangents) * getVertexCount(); + break; + } + switch (getIndexType()) { + case video::EIT_16BIT: + ret += sizeof(u16) * getIndexCount(); + break; + case video::EIT_32BIT: + ret += sizeof(u32) * getIndexCount(); + break; + } + return ret; + } }; } // end namespace scene diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bcbe6d7f5..2ea416a4d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -351,6 +351,12 @@ endif() include(CheckSymbolExists) check_symbol_exists(strlcpy "string.h" HAVE_STRLCPY) +if(UNIX) + check_symbol_exists(malloc_trim "malloc.h" HAVE_MALLOC_TRIM) +else() + set(HAVE_MALLOC_TRIM FALSE) +endif() + check_include_files(endian.h HAVE_ENDIAN_H) configure_file( diff --git a/src/client/mapblock_mesh.cpp b/src/client/mapblock_mesh.cpp index f06dcfa58..429464e04 100644 --- a/src/client/mapblock_mesh.cpp +++ b/src/client/mapblock_mesh.cpp @@ -800,11 +800,16 @@ MapBlockMesh::MapBlockMesh(Client *client, MeshMakeData *data, v3s16 camera_offs MapBlockMesh::~MapBlockMesh() { + size_t sz = 0; for (scene::IMesh *m : m_mesh) { + for (u32 i = 0; i < m->getMeshBufferCount(); i++) + sz += m->getMeshBuffer(i)->getSize(); m->drop(); } for (MinimapMapblock *block : m_minimap_mapblocks) delete block; + + porting::TrackFreedMemory(sz); } bool MapBlockMesh::animate(bool faraway, float time, int crack, diff --git a/src/cmake_config.h.in b/src/cmake_config.h.in index 33ce41943..2185600af 100644 --- a/src/cmake_config.h.in +++ b/src/cmake_config.h.in @@ -31,6 +31,7 @@ #cmakedefine01 USE_REDIS #cmakedefine01 HAVE_ENDIAN_H #cmakedefine01 HAVE_STRLCPY +#cmakedefine01 HAVE_MALLOC_TRIM #cmakedefine01 CURSES_HAVE_CURSES_H #cmakedefine01 CURSES_HAVE_NCURSES_H #cmakedefine01 CURSES_HAVE_NCURSES_NCURSES_H diff --git a/src/mapblock.cpp b/src/mapblock.cpp index b3e951b1f..9a27a9f3d 100644 --- a/src/mapblock.cpp +++ b/src/mapblock.cpp @@ -85,6 +85,7 @@ MapBlock::~MapBlock() #endif delete[] data; + porting::TrackFreedMemory(sizeof(MapNode) * nodecount); } bool MapBlock::onObjectsActivation() diff --git a/src/mapgen/mg_schematic.cpp b/src/mapgen/mg_schematic.cpp index 5ce0b8844..bc1b35ab4 100644 --- a/src/mapgen/mg_schematic.cpp +++ b/src/mapgen/mg_schematic.cpp @@ -19,7 +19,6 @@ with this program; if not, write to the Free Software Foundation, Inc., */ #include -#include #include "mg_schematic.h" #include "server.h" #include "mapgen.h" @@ -32,6 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "serialization.h" #include "filesys.h" #include "voxelalgorithms.h" +#include "porting.h" /////////////////////////////////////////////////////////////////////////////// @@ -80,6 +80,8 @@ Schematic::~Schematic() { delete []schemdata; delete []slice_probs; + u32 nodecount = size.X * size.Y * size.Z; + porting::TrackFreedMemory(nodecount * sizeof(MapNode)); } ObjDef *Schematic::clone() const diff --git a/src/porting.cpp b/src/porting.cpp index 2b2405d38..0763e92e1 100644 --- a/src/porting.cpp +++ b/src/porting.cpp @@ -63,7 +63,11 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #endif -#include "config.h" +#if HAVE_MALLOC_TRIM + // glibc-only pretty much + #include +#endif + #include "debug.h" #include "filesys.h" #include "log.h" @@ -72,6 +76,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include #include +#include #if !defined(SERVER) && defined(_WIN32) // On Windows export some driver-specific variables to encourage Minetest to be @@ -903,4 +908,37 @@ double perf_freq = get_perf_freq(); #endif +#if HAVE_MALLOC_TRIM + +/* + * On Linux/glibc we found that after deallocating bigger chunks of data (esp. MapBlocks) + * the memory would not be given back to the OS and would stay at peak usage. + * This appears to be a combination of unfortunate allocation order/fragmentation + * and the fact that glibc does not call madvise(MADV_DONTNEED) on its own. + * Some other allocators were also affected, jemalloc and musl libc were not. + * read more: + * + * As a workaround we track freed memory coarsely and call malloc_trim() once a + * certain amount is reached. + */ + +static std::atomic memory_freed; + +constexpr size_t MEMORY_TRIM_THRESHOLD = 128 * 1024 * 1024; + +void TrackFreedMemory(size_t amount) +{ + constexpr auto MO = std::memory_order_relaxed; + memory_freed.fetch_add(amount, MO); + if (memory_freed.load(MO) >= MEMORY_TRIM_THRESHOLD) { + // Synchronize call + if (memory_freed.exchange(0, MO) < MEMORY_TRIM_THRESHOLD) + return; + // Leave some headroom for future allocations + malloc_trim(1 * 1024 * 1024); + } +} + +#endif + } //namespace porting diff --git a/src/porting.h b/src/porting.h index a98e66bcf..27fabe7cd 100644 --- a/src/porting.h +++ b/src/porting.h @@ -290,6 +290,17 @@ void osSpecificInit(); // This attaches to the parents process console, or creates a new one if it doesnt exist. void attachOrCreateConsole(); +/** + * Call this after freeing bigger blocks of memory. Used on some platforms to + * properly give memory back to the OS. + * @param amount Number of bytes freed +*/ +#if HAVE_MALLOC_TRIM +void TrackFreedMemory(size_t amount); +#else +inline void TrackFreedMemory(size_t amount) { (void)amount; } +#endif + #ifdef _WIN32 // Quotes an argument for use in a CreateProcess() commandline (not cmd.exe!!) std::string QuoteArgv(const std::string &arg); @@ -298,6 +309,7 @@ std::string QuoteArgv(const std::string &arg); std::string ConvertError(DWORD error_code); #endif +// snprintf wrapper int mt_snprintf(char *buf, const size_t buf_size, const char *fmt, ...); /** diff --git a/src/voxel.cpp b/src/voxel.cpp index bb270f53b..0f87cf282 100644 --- a/src/voxel.cpp +++ b/src/voxel.cpp @@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "nodedef.h" #include "util/directiontables.h" #include "util/timetaker.h" +#include "porting.h" #include // memcpy, memset /* @@ -40,12 +41,15 @@ VoxelManipulator::~VoxelManipulator() void VoxelManipulator::clear() { - // Reset area to volume=0 - m_area = VoxelArea(); + // Reset area to empty volume + VoxelArea old; + std::swap(m_area, old); delete[] m_data; m_data = nullptr; delete[] m_flags; m_flags = nullptr; + + porting::TrackFreedMemory((sizeof(*m_data) + sizeof(*m_flags)) * old.getVolume()); } void VoxelManipulator::print(std::ostream &o, const NodeDefManager *ndef, From 4c9be808a7222e82e04c24d927150664773ad5be Mon Sep 17 00:00:00 2001 From: cx384 Date: Sat, 8 Jun 2024 12:37:22 +0200 Subject: [PATCH 57/67] Improve register_on_leaveplayer documentation --- doc/lua_api.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/lua_api.md b/doc/lua_api.md index fde2e726f..b1412ca85 100644 --- a/doc/lua_api.md +++ b/doc/lua_api.md @@ -5796,6 +5796,7 @@ Call these functions only at load time! * `last_login`: The timestamp of the previous login, or nil if player is new * `minetest.register_on_leaveplayer(function(ObjectRef, timed_out))` * Called when a player leaves the game + * Does not get executed for connected players on shutdown. * `timed_out`: True for timeout, false for other reasons. * `minetest.register_on_authplayer(function(name, ip, is_success))` * Called when a client attempts to log into an account. From 27cb54c1dbce437a2d2acb20aba3fa6ffa80576c Mon Sep 17 00:00:00 2001 From: sfan5 Date: Tue, 14 May 2024 19:26:22 +0200 Subject: [PATCH 58/67] Stop misusing volatile keyword --- src/log.cpp | 4 ++-- src/log.h | 10 +++++----- src/network/connection.cpp | 4 ++-- src/unittest/test_threading.cpp | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/log.cpp b/src/log.cpp index 5ee66c070..6dbc43372 100644 --- a/src/log.cpp +++ b/src/log.cpp @@ -253,7 +253,7 @@ const std::string Logger::getThreadName() void Logger::log(LogLevel lev, const std::string &text) { - if (m_silenced_levels[lev]) + if (isLevelSilenced(lev)) return; const std::string thread_name = getThreadName(); @@ -267,7 +267,7 @@ void Logger::log(LogLevel lev, const std::string &text) void Logger::logRaw(LogLevel lev, const std::string &text) { - if (m_silenced_levels[lev]) + if (isLevelSilenced(lev)) return; logToOutputsRaw(lev, text); diff --git a/src/log.h b/src/log.h index 4255e55bc..f92d17737 100644 --- a/src/log.h +++ b/src/log.h @@ -79,6 +79,10 @@ public: return m_has_outputs[level].load(std::memory_order_relaxed); } + bool isLevelSilenced(LogLevel level) { + return m_silenced_levels[level].load(std::memory_order_relaxed); + } + static LogColor color_mode; private: @@ -91,11 +95,7 @@ private: std::vector m_outputs[LL_MAX]; std::atomic m_has_outputs[LL_MAX]; - - // Should implement atomic loads and stores (even though it's only - // written to when one thread has access currently). - // Works on all known architectures (x86, ARM, MIPS). - volatile bool m_silenced_levels[LL_MAX]; + std::atomic m_silenced_levels[LL_MAX]; std::map m_thread_names; mutable std::mutex m_mutex; }; diff --git a/src/network/connection.cpp b/src/network/connection.cpp index 84a6c53c5..00b4fe4b0 100644 --- a/src/network/connection.cpp +++ b/src/network/connection.cpp @@ -1078,7 +1078,7 @@ bool UDPPeer::processReliableSendCommand( bool have_sequence_number = false; bool have_initial_sequence_number = false; std::queue toadd; - volatile u16 initial_sequence_number = 0; + u16 initial_sequence_number = 0; for (SharedBuffer &original : originals) { u16 seqnum = chan.getOutgoingSequenceNumber(have_sequence_number); @@ -1118,7 +1118,7 @@ bool UDPPeer::processReliableSendCommand( return true; } - volatile u16 packets_available = toadd.size(); + u16 packets_available = toadd.size(); /* we didn't get a single sequence number no need to fill queue */ if (!have_initial_sequence_number) { LOG(derr_con << m_connection->getDesc() << "Ran out of sequence numbers!" << std::endl); diff --git a/src/unittest/test_threading.cpp b/src/unittest/test_threading.cpp index 9d7b7c808..a91e1b532 100644 --- a/src/unittest/test_threading.cpp +++ b/src/unittest/test_threading.cpp @@ -161,7 +161,7 @@ void TestThreading::testAtomicSemaphoreThread() -static volatile bool g_tls_broken; +static std::atomic g_tls_broken; class TLSTestThread : public Thread { public: @@ -226,7 +226,7 @@ private: */ void TestThreading::testTLS() { - static const int num_threads = 10; + constexpr int num_threads = 10; for (int j = 0; j < num_threads; j++) { g_tls_broken = false; From 558d749d544c7cc0e7b5f0adb5feff30dac9f994 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Tue, 14 May 2024 19:56:31 +0200 Subject: [PATCH 59/67] A few clean ups in log.cpp --- src/log.cpp | 68 +++++++++++++++++++++-------------- src/log.h | 18 ++-------- src/terminal_chat_console.cpp | 2 +- 3 files changed, 45 insertions(+), 43 deletions(-) diff --git a/src/log.cpp b/src/log.cpp index 6dbc43372..98939c9bf 100644 --- a/src/log.cpp +++ b/src/log.cpp @@ -34,6 +34,10 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #endif +#if !defined(_WIN32) +#include // isatty +#endif + #include #include #include @@ -104,21 +108,19 @@ thread_local LogStream dout_con(trace_target); static unsigned int g_level_to_android[] = { ANDROID_LOG_INFO, // LL_NONE - //ANDROID_LOG_FATAL, ANDROID_LOG_ERROR, // LL_ERROR ANDROID_LOG_WARN, // LL_WARNING - ANDROID_LOG_WARN, // LL_ACTION - //ANDROID_LOG_INFO, + ANDROID_LOG_INFO, // LL_ACTION ANDROID_LOG_DEBUG, // LL_INFO ANDROID_LOG_VERBOSE, // LL_VERBOSE ANDROID_LOG_VERBOSE, // LL_TRACE }; -void AndroidLogOutput::logRaw(LogLevel lev, const std::string &line) { +void AndroidLogOutput::logRaw(LogLevel lev, const std::string &line) +{ static_assert(ARRLEN(g_level_to_android) == LL_MAX, "mismatch between android and internal loglevels"); - __android_log_print(g_level_to_android[lev], - PROJECT_NAME_C, "%s", line.c_str()); + __android_log_write(g_level_to_android[lev], PROJECT_NAME_C, line.c_str()); } #endif @@ -156,9 +158,7 @@ void Logger::addOutput(ILogOutput *out) void Logger::addOutput(ILogOutput *out, LogLevel lev) { - MutexAutoLock lock(m_mutex); - m_outputs[lev].push_back(out); - m_has_outputs[lev] = true; + addOutputMasked(out, LOGLEVEL_TO_MASKLEVEL(lev)); } void Logger::addOutputMasked(ILogOutput *out, LogLevelMask mask) @@ -187,9 +187,7 @@ LogLevelMask Logger::removeOutput(ILogOutput *out) MutexAutoLock lock(m_mutex); LogLevelMask ret_mask = 0; for (size_t i = 0; i < LL_MAX; i++) { - std::vector::iterator it; - - it = std::find(m_outputs[i].begin(), m_outputs[i].end(), out); + auto it = std::find(m_outputs[i].begin(), m_outputs[i].end(), out); if (it != m_outputs[i].end()) { ret_mask |= LOGLEVEL_TO_MASKLEVEL(i); m_outputs[i].erase(it); @@ -218,9 +216,9 @@ void Logger::deregisterThread() m_thread_names.erase(id); } -const std::string Logger::getLevelLabel(LogLevel lev) +const char *Logger::getLevelLabel(LogLevel lev) { - static const std::string names[] = { + static const char *names[] = { "", "ERROR", "WARNING", @@ -229,26 +227,29 @@ const std::string Logger::getLevelLabel(LogLevel lev) "VERBOSE", "TRACE", }; - assert(lev < LL_MAX && lev >= 0); static_assert(ARRLEN(names) == LL_MAX, "mismatch between loglevel names and enum"); + assert(lev < LL_MAX && lev >= 0); return names[lev]; } LogColor Logger::color_mode = LOG_COLOR_AUTO; -const std::string Logger::getThreadName() +const std::string &Logger::getThreadName() { - std::map::const_iterator it; - std::thread::id id = std::this_thread::get_id(); - it = m_thread_names.find(id); + + auto it = m_thread_names.find(id); if (it != m_thread_names.end()) return it->second; - std::ostringstream os; - os << "#0x" << std::hex << id; - return os.str(); + thread_local std::string fallback_name; + if (fallback_name.empty()) { + std::ostringstream os; + os << "#0x" << std::hex << id; + fallback_name = os.str(); + } + return fallback_name; } void Logger::log(LogLevel lev, const std::string &text) @@ -256,13 +257,15 @@ void Logger::log(LogLevel lev, const std::string &text) if (isLevelSilenced(lev)) return; - const std::string thread_name = getThreadName(); - const std::string label = getLevelLabel(lev); + const std::string &thread_name = getThreadName(); + const char *label = getLevelLabel(lev); const std::string timestamp = getTimestamp(); - std::ostringstream os(std::ios_base::binary); - os << timestamp << ": " << label << "[" << thread_name << "]: " << text; - logToOutputs(lev, os.str(), timestamp, thread_name, text); + std::string line = timestamp; + line.append(": ").append(label).append("[").append(thread_name) + .append("]: ").append(text); + + logToOutputs(lev, line, timestamp, thread_name, text); } void Logger::logRaw(LogLevel lev, const std::string &text) @@ -320,6 +323,17 @@ void FileLogOutput::setFile(const std::string &filename, s64 file_size_max) "-------------\n" << std::endl; } +StreamLogOutput::StreamLogOutput(std::ostream &stream) : + m_stream(stream) +{ +#if !defined(_WIN32) + if (&stream == &std::cout) + is_tty = isatty(STDOUT_FILENO); + else if (&stream == &std::cerr) + is_tty = isatty(STDERR_FILENO); +#endif +} + void StreamLogOutput::logRaw(LogLevel lev, const std::string &line) { bool colored_message = (Logger::color_mode == LOG_COLOR_ALWAYS) || diff --git a/src/log.h b/src/log.h index f92d17737..9ac4e5767 100644 --- a/src/log.h +++ b/src/log.h @@ -26,9 +26,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include #include -#if !defined(_WIN32) // POSIX - #include -#endif #include "threading/mutex_auto_lock.h" #include "util/basic_macros.h" #include "util/stream.h" @@ -73,7 +70,7 @@ public: void logRaw(LogLevel lev, const std::string &text); static LogLevel stringToLevel(const std::string &name); - static const std::string getLevelLabel(LogLevel lev); + static const char *getLevelLabel(LogLevel lev); bool hasOutput(LogLevel level) { return m_has_outputs[level].load(std::memory_order_relaxed); @@ -91,7 +88,7 @@ private: const std::string &time, const std::string &thread_name, const std::string &payload_text); - const std::string getThreadName(); + const std::string &getThreadName(); std::vector m_outputs[LL_MAX]; std::atomic m_has_outputs[LL_MAX]; @@ -120,16 +117,7 @@ public: class StreamLogOutput : public ICombinedLogOutput { public: - StreamLogOutput(std::ostream &stream) : - m_stream(stream) - { -#if !defined(_WIN32) - if (&stream == &std::cout) - is_tty = isatty(STDOUT_FILENO); - else if (&stream == &std::cerr) - is_tty = isatty(STDERR_FILENO); -#endif - } + StreamLogOutput(std::ostream &stream); void logRaw(LogLevel lev, const std::string &line); diff --git a/src/terminal_chat_console.cpp b/src/terminal_chat_console.cpp index b1512d8f3..752d7c7b8 100644 --- a/src/terminal_chat_console.cpp +++ b/src/terminal_chat_console.cpp @@ -426,7 +426,7 @@ void TerminalChatConsole::step(int ch) printw("[ESC] Toggle ESC mode |" " [CTRL+C] Shut down |" " (L) in-, (l) decrease loglevel %s", - Logger::getLevelLabel((LogLevel) m_log_level).c_str()); + Logger::getLevelLabel((LogLevel) m_log_level)); } refresh(); From fee6e8e11b37f940ba674d53790f36a349c1a343 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Wed, 5 Jun 2024 22:43:06 +0200 Subject: [PATCH 60/67] Identify when compiled with openresty LuaJIT Debian testing ships it --- src/main.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 7f078d9b2..7474ae84c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -427,7 +427,11 @@ static void print_version(std::ostream &os) os << PROJECT_NAME_C " " << g_version_hash << " (" << porting::getPlatformName() << ")" << std::endl; #if USE_LUAJIT - os << "Using " << LUAJIT_VERSION << std::endl; + os << "Using " << LUAJIT_VERSION +#ifdef OPENRESTY_LUAJIT + << " (OpenResty)" +#endif + << std::endl; #else os << "Using " << LUA_RELEASE << std::endl; #endif From 8268c61b9f841c7e7e900a90223a43b2126fadbb Mon Sep 17 00:00:00 2001 From: sfan5 Date: Wed, 5 Jun 2024 22:58:33 +0200 Subject: [PATCH 61/67] Make safeWriteToFile safe for thread-concurrent use --- src/filesys.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/filesys.cpp b/src/filesys.cpp index a61f7f0aa..26cdaba07 100644 --- a/src/filesys.cpp +++ b/src/filesys.cpp @@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include #include +#include #include "log.h" #include "config.h" #include "porting.h" @@ -854,10 +855,12 @@ const char *GetFilenameFromPath(const char *path) return filename ? filename + 1 : path; } +// Note: this is not safe if two MT processes try this at the same time (FIXME?) bool safeWriteToFile(const std::string &path, std::string_view content) { - // Note: this is not safe if two MT processes try this at the same time (FIXME?) - const std::string tmp_file = path + ".~mt"; + // Prevent two threads from writing to the same temporary file + static std::atomic g_file_counter; + const std::string tmp_file = path + ".~mt" + itos(g_file_counter.fetch_add(1)); // Write data to a temporary file std::string write_error; From b7e886a7403d5e7106328506c7a990637d77f0b2 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Wed, 5 Jun 2024 23:04:09 +0200 Subject: [PATCH 62/67] Rename sha256 header fixes #14710 --- lib/sha256/{sha256/sha256.h => my_sha256.h} | 0 lib/sha256/sha256.c | 2 +- src/script/lua_api/l_util.cpp | 2 +- src/util/srp.cpp | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) rename lib/sha256/{sha256/sha256.h => my_sha256.h} (100%) diff --git a/lib/sha256/sha256/sha256.h b/lib/sha256/my_sha256.h similarity index 100% rename from lib/sha256/sha256/sha256.h rename to lib/sha256/my_sha256.h diff --git a/lib/sha256/sha256.c b/lib/sha256/sha256.c index 56bdec098..cd78e24f6 100644 --- a/lib/sha256/sha256.c +++ b/lib/sha256/sha256.c @@ -56,7 +56,7 @@ #include #include -#include "sha256/sha256.h" +#include "my_sha256.h" #if defined(_MSC_VER) && !defined(__clang__) && !defined(__attribute__) #define __attribute__(a) diff --git a/src/script/lua_api/l_util.cpp b/src/script/lua_api/l_util.cpp index c868f949c..883b9480c 100644 --- a/src/script/lua_api/l_util.cpp +++ b/src/script/lua_api/l_util.cpp @@ -42,7 +42,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "version.h" #include "util/hex.h" #include "util/sha1.h" -#include +#include "my_sha256.h" #include "util/png.h" #include diff --git a/src/util/srp.cpp b/src/util/srp.cpp index ea64efca6..56b2aa763 100644 --- a/src/util/srp.cpp +++ b/src/util/srp.cpp @@ -50,7 +50,7 @@ #include #endif -#include +#include "my_sha256.h" #include "srp.h" //#define CSRP_USE_SHA1 From c03894321a4259bae85acce634d014aa0ed7759f Mon Sep 17 00:00:00 2001 From: sfan5 Date: Wed, 5 Jun 2024 23:07:40 +0200 Subject: [PATCH 63/67] Fix file write warning in devtest closes #14721 --- games/devtest/mods/testnodes/textures.lua | 8 -------- 1 file changed, 8 deletions(-) diff --git a/games/devtest/mods/testnodes/textures.lua b/games/devtest/mods/testnodes/textures.lua index 0caaaed9d..86bc3e343 100644 --- a/games/devtest/mods/testnodes/textures.lua +++ b/games/devtest/mods/testnodes/textures.lua @@ -181,14 +181,6 @@ fractal = nil frac_emb = nil checker = nil -do - -- we used to write the textures to our mod folder. in order to avoid - -- duplication errors delete them if they still exist. - local path = core.get_modpath(core.get_current_modname()) .. "/textures/" - os.remove(path .. "testnodes_generated_mb.png") - os.remove(path .. "testnodes_generated_ck.png") -end - local textures_path = core.get_worldpath() .. "/" core.safe_file_write( textures_path .. "testnodes1.png", From 3539af7d776f2e89a3d9c16ef03c1add7081501d Mon Sep 17 00:00:00 2001 From: sfan5 Date: Fri, 7 Jun 2024 16:52:31 +0200 Subject: [PATCH 64/67] Set some useful SDL hints fixes #14596 --- irr/src/CIrrDeviceSDL.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/irr/src/CIrrDeviceSDL.cpp b/irr/src/CIrrDeviceSDL.cpp index c01e6900e..81ff37511 100644 --- a/irr/src/CIrrDeviceSDL.cpp +++ b/irr/src/CIrrDeviceSDL.cpp @@ -272,6 +272,19 @@ CIrrDeviceSDL::CIrrDeviceSDL(const SIrrlichtCreationParameters ¶m) : SDL_SetHint(SDL_HINT_ENABLE_SCREEN_KEYBOARD, "0"); #endif + // Minetest has its own signal handler + SDL_SetHint(SDL_HINT_NO_SIGNAL_HANDLERS, "1"); + + // Disabling the compositor is not a good idea in windowed mode. + // See https://github.com/minetest/minetest/issues/14596 + SDL_SetHint(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0"); + +#if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) + // These are not interesting for our use + SDL_SetHint(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, "0"); + SDL_SetHint(SDL_HINT_TV_REMOTE_AS_JOYSTICK, "0"); +#endif + // Minetest has its own code to synthesize mouse events from touch events, // so we prevent SDL from doing it. SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0"); From 5133ae52dfab4a662d671df434a8d37e2a2f7431 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Fri, 7 Jun 2024 17:00:36 +0200 Subject: [PATCH 65/67] Update vcpkg used in CI --- .github/workflows/windows.yml | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 5765f67fa..367933148 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -69,8 +69,8 @@ jobs: name: VS 2019 ${{ matrix.config.arch }}-${{ matrix.type }} runs-on: windows-2019 env: - VCPKG_VERSION: 8eb57355a4ffb410a2e94c07b4dca2dffbee8e50 - # 2023.10.19 + VCPKG_VERSION: 01f602195983451bc83e72f4214af2cbc495aa94 + # 2024.05.24 vcpkg_packages: zlib zstd curl[winssl] openal-soft libvorbis libogg libjpeg-turbo sqlite3 freetype luajit gmp jsoncpp sdl2 strategy: fail-fast: false @@ -94,12 +94,6 @@ jobs: steps: - uses: actions/checkout@v4 - # Workaround for regression, see https://github.com/minetest/minetest/pull/14536 - - name: Pin CMake to 3.28 - uses: lukka/get-cmake@latest - with: - cmakeVersion: "~3.28.0" - - name: Restore from cache and run vcpkg uses: lukka/run-vcpkg@v7 with: From 781c7a800f145e77c7c7581e06a9302e7011e97a Mon Sep 17 00:00:00 2001 From: minetest Date: Fri, 7 Jun 2024 18:44:58 +0200 Subject: [PATCH 66/67] Replace Catch2 with v3 amalgamation --- lib/catch2/catch.hpp | 17976 ----------------------------- lib/catch2/catch_amalgamated.cpp | 11638 +++++++++++++++++++ lib/catch2/catch_amalgamated.hpp | 14057 ++++++++++++++++++++++ 3 files changed, 25695 insertions(+), 17976 deletions(-) delete mode 100644 lib/catch2/catch.hpp create mode 100644 lib/catch2/catch_amalgamated.cpp create mode 100644 lib/catch2/catch_amalgamated.hpp diff --git a/lib/catch2/catch.hpp b/lib/catch2/catch.hpp deleted file mode 100644 index 9b309bddc..000000000 --- a/lib/catch2/catch.hpp +++ /dev/null @@ -1,17976 +0,0 @@ -/* - * Catch v2.13.10 - * Generated: 2022-10-16 11:01:23.452308 - * ---------------------------------------------------------- - * This file has been merged from multiple headers. Please don't edit it directly - * Copyright (c) 2022 Two Blue Cubes Ltd. All rights reserved. - * - * Distributed under the Boost Software License, Version 1.0. (See accompanying - * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - */ -#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED -#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED -// start catch.hpp - - -#define CATCH_VERSION_MAJOR 2 -#define CATCH_VERSION_MINOR 13 -#define CATCH_VERSION_PATCH 10 - -#ifdef __clang__ -# pragma clang system_header -#elif defined __GNUC__ -# pragma GCC system_header -#endif - -// start catch_suppress_warnings.h - -#ifdef __clang__ -# ifdef __ICC // icpc defines the __clang__ macro -# pragma warning(push) -# pragma warning(disable: 161 1682) -# else // __ICC -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wpadded" -# pragma clang diagnostic ignored "-Wswitch-enum" -# pragma clang diagnostic ignored "-Wcovered-switch-default" -# endif -#elif defined __GNUC__ - // Because REQUIREs trigger GCC's -Wparentheses, and because still - // supported version of g++ have only buggy support for _Pragmas, - // Wparentheses have to be suppressed globally. -# pragma GCC diagnostic ignored "-Wparentheses" // See #674 for details - -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wunused-variable" -# pragma GCC diagnostic ignored "-Wpadded" -#endif -// end catch_suppress_warnings.h -#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER) -# define CATCH_IMPL -# define CATCH_CONFIG_ALL_PARTS -#endif - -// In the impl file, we want to have access to all parts of the headers -// Can also be used to sanely support PCHs -#if defined(CATCH_CONFIG_ALL_PARTS) -# define CATCH_CONFIG_EXTERNAL_INTERFACES -# if defined(CATCH_CONFIG_DISABLE_MATCHERS) -# undef CATCH_CONFIG_DISABLE_MATCHERS -# endif -# if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER) -# define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER -# endif -#endif - -#if !defined(CATCH_CONFIG_IMPL_ONLY) -// start catch_platform.h - -// See e.g.: -// https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/TargetConditionals.h.auto.html -#ifdef __APPLE__ -# include -# if (defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1) || \ - (defined(TARGET_OS_MAC) && TARGET_OS_MAC == 1) -# define CATCH_PLATFORM_MAC -# elif (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE == 1) -# define CATCH_PLATFORM_IPHONE -# endif - -#elif defined(linux) || defined(__linux) || defined(__linux__) -# define CATCH_PLATFORM_LINUX - -#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__) -# define CATCH_PLATFORM_WINDOWS -#endif - -// end catch_platform.h - -#ifdef CATCH_IMPL -# ifndef CLARA_CONFIG_MAIN -# define CLARA_CONFIG_MAIN_NOT_DEFINED -# define CLARA_CONFIG_MAIN -# endif -#endif - -// start catch_user_interfaces.h - -namespace Catch { - unsigned int rngSeed(); -} - -// end catch_user_interfaces.h -// start catch_tag_alias_autoregistrar.h - -// start catch_common.h - -// start catch_compiler_capabilities.h - -// Detect a number of compiler features - by compiler -// The following features are defined: -// -// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported? -// CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported? -// CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported? -// CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled? -// **************** -// Note to maintainers: if new toggles are added please document them -// in configuration.md, too -// **************** - -// In general each macro has a _NO_ form -// (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature. -// Many features, at point of detection, define an _INTERNAL_ macro, so they -// can be combined, en-mass, with the _NO_ forms later. - -#ifdef __cplusplus - -# if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L) -# define CATCH_CPP14_OR_GREATER -# endif - -# if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) -# define CATCH_CPP17_OR_GREATER -# endif - -#endif - -// Only GCC compiler should be used in this block, so other compilers trying to -// mask themselves as GCC should be ignored. -#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__) && !defined(__LCC__) -# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" ) -# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic pop" ) - -# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) - -#endif - -#if defined(__clang__) - -# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" ) -# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic pop" ) - -// As of this writing, IBM XL's implementation of __builtin_constant_p has a bug -// which results in calls to destructors being emitted for each temporary, -// without a matching initialization. In practice, this can result in something -// like `std::string::~string` being called on an uninitialized value. -// -// For example, this code will likely segfault under IBM XL: -// ``` -// REQUIRE(std::string("12") + "34" == "1234") -// ``` -// -// Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented. -# if !defined(__ibmxl__) && !defined(__CUDACC__) -# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, hicpp-vararg) */ -# endif - -# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ - _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \ - _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"") - -# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ - _Pragma( "clang diagnostic ignored \"-Wparentheses\"" ) - -# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \ - _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" ) - -# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \ - _Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" ) - -# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \ - _Pragma( "clang diagnostic ignored \"-Wunused-template\"" ) - -#endif // __clang__ - -//////////////////////////////////////////////////////////////////////////////// -// Assume that non-Windows platforms support posix signals by default -#if !defined(CATCH_PLATFORM_WINDOWS) - #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS -#endif - -//////////////////////////////////////////////////////////////////////////////// -// We know some environments not to support full POSIX signals -#if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__) - #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS -#endif - -#ifdef __OS400__ -# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS -# define CATCH_CONFIG_COLOUR_NONE -#endif - -//////////////////////////////////////////////////////////////////////////////// -// Android somehow still does not support std::to_string -#if defined(__ANDROID__) -# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING -# define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE -#endif - -//////////////////////////////////////////////////////////////////////////////// -// Not all Windows environments support SEH properly -#if defined(__MINGW32__) -# define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH -#endif - -//////////////////////////////////////////////////////////////////////////////// -// PS4 -#if defined(__ORBIS__) -# define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE -#endif - -//////////////////////////////////////////////////////////////////////////////// -// Cygwin -#ifdef __CYGWIN__ - -// Required for some versions of Cygwin to declare gettimeofday -// see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin -# define _BSD_SOURCE -// some versions of cygwin (most) do not support std::to_string. Use the libstd check. -// https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813 -# if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \ - && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF)) - -# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING - -# endif -#endif // __CYGWIN__ - -//////////////////////////////////////////////////////////////////////////////// -// Visual C++ -#if defined(_MSC_VER) - -// Universal Windows platform does not support SEH -// Or console colours (or console at all...) -# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) -# define CATCH_CONFIG_COLOUR_NONE -# else -# define CATCH_INTERNAL_CONFIG_WINDOWS_SEH -# endif - -# if !defined(__clang__) // Handle Clang masquerading for msvc - -// MSVC traditional preprocessor needs some workaround for __VA_ARGS__ -// _MSVC_TRADITIONAL == 0 means new conformant preprocessor -// _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor -# if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL) -# define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR -# endif // MSVC_TRADITIONAL - -// Only do this if we're not using clang on Windows, which uses `diagnostic push` & `diagnostic pop` -# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) ) -# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) ) -# endif // __clang__ - -#endif // _MSC_VER - -#if defined(_REENTRANT) || defined(_MSC_VER) -// Enable async processing, as -pthread is specified or no additional linking is required -# define CATCH_INTERNAL_CONFIG_USE_ASYNC -#endif // _MSC_VER - -//////////////////////////////////////////////////////////////////////////////// -// Check if we are compiled with -fno-exceptions or equivalent -#if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND) -# define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED -#endif - -//////////////////////////////////////////////////////////////////////////////// -// DJGPP -#ifdef __DJGPP__ -# define CATCH_INTERNAL_CONFIG_NO_WCHAR -#endif // __DJGPP__ - -//////////////////////////////////////////////////////////////////////////////// -// Embarcadero C++Build -#if defined(__BORLANDC__) - #define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN -#endif - -//////////////////////////////////////////////////////////////////////////////// - -// Use of __COUNTER__ is suppressed during code analysis in -// CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly -// handled by it. -// Otherwise all supported compilers support COUNTER macro, -// but user still might want to turn it off -#if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L ) - #define CATCH_INTERNAL_CONFIG_COUNTER -#endif - -//////////////////////////////////////////////////////////////////////////////// - -// RTX is a special version of Windows that is real time. -// This means that it is detected as Windows, but does not provide -// the same set of capabilities as real Windows does. -#if defined(UNDER_RTSS) || defined(RTX64_BUILD) - #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH - #define CATCH_INTERNAL_CONFIG_NO_ASYNC - #define CATCH_CONFIG_COLOUR_NONE -#endif - -#if !defined(_GLIBCXX_USE_C99_MATH_TR1) -#define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER -#endif - -// Various stdlib support checks that require __has_include -#if defined(__has_include) - // Check if string_view is available and usable - #if __has_include() && defined(CATCH_CPP17_OR_GREATER) - # define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW - #endif - - // Check if optional is available and usable - # if __has_include() && defined(CATCH_CPP17_OR_GREATER) - # define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL - # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) - - // Check if byte is available and usable - # if __has_include() && defined(CATCH_CPP17_OR_GREATER) - # include - # if defined(__cpp_lib_byte) && (__cpp_lib_byte > 0) - # define CATCH_INTERNAL_CONFIG_CPP17_BYTE - # endif - # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) - - // Check if variant is available and usable - # if __has_include() && defined(CATCH_CPP17_OR_GREATER) - # if defined(__clang__) && (__clang_major__ < 8) - // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852 - // fix should be in clang 8, workaround in libstdc++ 8.2 - # include - # if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) - # define CATCH_CONFIG_NO_CPP17_VARIANT - # else - # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT - # endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) - # else - # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT - # endif // defined(__clang__) && (__clang_major__ < 8) - # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) -#endif // defined(__has_include) - -#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) -# define CATCH_CONFIG_COUNTER -#endif -#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) && !defined(CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH) -# define CATCH_CONFIG_WINDOWS_SEH -#endif -// This is set by default, because we assume that unix compilers are posix-signal-compatible by default. -#if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS) -# define CATCH_CONFIG_POSIX_SIGNALS -#endif -// This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions. -#if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR) -# define CATCH_CONFIG_WCHAR -#endif - -#if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING) -# define CATCH_CONFIG_CPP11_TO_STRING -#endif - -#if defined(CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_NO_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_CPP17_OPTIONAL) -# define CATCH_CONFIG_CPP17_OPTIONAL -#endif - -#if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW) -# define CATCH_CONFIG_CPP17_STRING_VIEW -#endif - -#if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT) -# define CATCH_CONFIG_CPP17_VARIANT -#endif - -#if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && !defined(CATCH_CONFIG_NO_CPP17_BYTE) && !defined(CATCH_CONFIG_CPP17_BYTE) -# define CATCH_CONFIG_CPP17_BYTE -#endif - -#if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT) -# define CATCH_INTERNAL_CONFIG_NEW_CAPTURE -#endif - -#if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NEW_CAPTURE) -# define CATCH_CONFIG_NEW_CAPTURE -#endif - -#if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) -# define CATCH_CONFIG_DISABLE_EXCEPTIONS -#endif - -#if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_POLYFILL_ISNAN) -# define CATCH_CONFIG_POLYFILL_ISNAN -#endif - -#if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC) && !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) && !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC) -# define CATCH_CONFIG_USE_ASYNC -#endif - -#if defined(CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_NO_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_ANDROID_LOGWRITE) -# define CATCH_CONFIG_ANDROID_LOGWRITE -#endif - -#if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER) -# define CATCH_CONFIG_GLOBAL_NEXTAFTER -#endif - -// Even if we do not think the compiler has that warning, we still have -// to provide a macro that can be used by the code. -#if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION) -# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION -#endif -#if !defined(CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION) -# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION -#endif -#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) -# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS -#endif -#if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS) -# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS -#endif -#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS) -# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS -#endif -#if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS) -# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS -#endif - -// The goal of this macro is to avoid evaluation of the arguments, but -// still have the compiler warn on problems inside... -#if !defined(CATCH_INTERNAL_IGNORE_BUT_WARN) -# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) -#endif - -#if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10) -# undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS -#elif defined(__clang__) && (__clang_major__ < 5) -# undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS -#endif - -#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS) -# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS -#endif - -#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) -#define CATCH_TRY if ((true)) -#define CATCH_CATCH_ALL if ((false)) -#define CATCH_CATCH_ANON(type) if ((false)) -#else -#define CATCH_TRY try -#define CATCH_CATCH_ALL catch (...) -#define CATCH_CATCH_ANON(type) catch (type) -#endif - -#if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) -#define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR -#endif - -// end catch_compiler_capabilities.h -#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line -#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) -#ifdef CATCH_CONFIG_COUNTER -# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ ) -#else -# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ ) -#endif - -#include -#include -#include - -// We need a dummy global operator<< so we can bring it into Catch namespace later -struct Catch_global_namespace_dummy {}; -std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy); - -namespace Catch { - - struct CaseSensitive { enum Choice { - Yes, - No - }; }; - - class NonCopyable { - NonCopyable( NonCopyable const& ) = delete; - NonCopyable( NonCopyable && ) = delete; - NonCopyable& operator = ( NonCopyable const& ) = delete; - NonCopyable& operator = ( NonCopyable && ) = delete; - - protected: - NonCopyable(); - virtual ~NonCopyable(); - }; - - struct SourceLineInfo { - - SourceLineInfo() = delete; - SourceLineInfo( char const* _file, std::size_t _line ) noexcept - : file( _file ), - line( _line ) - {} - - SourceLineInfo( SourceLineInfo const& other ) = default; - SourceLineInfo& operator = ( SourceLineInfo const& ) = default; - SourceLineInfo( SourceLineInfo&& ) noexcept = default; - SourceLineInfo& operator = ( SourceLineInfo&& ) noexcept = default; - - bool empty() const noexcept { return file[0] == '\0'; } - bool operator == ( SourceLineInfo const& other ) const noexcept; - bool operator < ( SourceLineInfo const& other ) const noexcept; - - char const* file; - std::size_t line; - }; - - std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ); - - // Bring in operator<< from global namespace into Catch namespace - // This is necessary because the overload of operator<< above makes - // lookup stop at namespace Catch - using ::operator<<; - - // Use this in variadic streaming macros to allow - // >> +StreamEndStop - // as well as - // >> stuff +StreamEndStop - struct StreamEndStop { - std::string operator+() const; - }; - template - T const& operator + ( T const& value, StreamEndStop ) { - return value; - } -} - -#define CATCH_INTERNAL_LINEINFO \ - ::Catch::SourceLineInfo( __FILE__, static_cast( __LINE__ ) ) - -// end catch_common.h -namespace Catch { - - struct RegistrarForTagAliases { - RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ); - }; - -} // end namespace Catch - -#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \ - CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ - CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ - namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \ - CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION - -// end catch_tag_alias_autoregistrar.h -// start catch_test_registry.h - -// start catch_interfaces_testcase.h - -#include - -namespace Catch { - - class TestSpec; - - struct ITestInvoker { - virtual void invoke () const = 0; - virtual ~ITestInvoker(); - }; - - class TestCase; - struct IConfig; - - struct ITestCaseRegistry { - virtual ~ITestCaseRegistry(); - virtual std::vector const& getAllTests() const = 0; - virtual std::vector const& getAllTestsSorted( IConfig const& config ) const = 0; - }; - - bool isThrowSafe( TestCase const& testCase, IConfig const& config ); - bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ); - std::vector filterTests( std::vector const& testCases, TestSpec const& testSpec, IConfig const& config ); - std::vector const& getAllTestCasesSorted( IConfig const& config ); - -} - -// end catch_interfaces_testcase.h -// start catch_stringref.h - -#include -#include -#include -#include - -namespace Catch { - - /// A non-owning string class (similar to the forthcoming std::string_view) - /// Note that, because a StringRef may be a substring of another string, - /// it may not be null terminated. - class StringRef { - public: - using size_type = std::size_t; - using const_iterator = const char*; - - private: - static constexpr char const* const s_empty = ""; - - char const* m_start = s_empty; - size_type m_size = 0; - - public: // construction - constexpr StringRef() noexcept = default; - - StringRef( char const* rawChars ) noexcept; - - constexpr StringRef( char const* rawChars, size_type size ) noexcept - : m_start( rawChars ), - m_size( size ) - {} - - StringRef( std::string const& stdString ) noexcept - : m_start( stdString.c_str() ), - m_size( stdString.size() ) - {} - - explicit operator std::string() const { - return std::string(m_start, m_size); - } - - public: // operators - auto operator == ( StringRef const& other ) const noexcept -> bool; - auto operator != (StringRef const& other) const noexcept -> bool { - return !(*this == other); - } - - auto operator[] ( size_type index ) const noexcept -> char { - assert(index < m_size); - return m_start[index]; - } - - public: // named queries - constexpr auto empty() const noexcept -> bool { - return m_size == 0; - } - constexpr auto size() const noexcept -> size_type { - return m_size; - } - - // Returns the current start pointer. If the StringRef is not - // null-terminated, throws std::domain_exception - auto c_str() const -> char const*; - - public: // substrings and searches - // Returns a substring of [start, start + length). - // If start + length > size(), then the substring is [start, size()). - // If start > size(), then the substring is empty. - auto substr( size_type start, size_type length ) const noexcept -> StringRef; - - // Returns the current start pointer. May not be null-terminated. - auto data() const noexcept -> char const*; - - constexpr auto isNullTerminated() const noexcept -> bool { - return m_start[m_size] == '\0'; - } - - public: // iterators - constexpr const_iterator begin() const { return m_start; } - constexpr const_iterator end() const { return m_start + m_size; } - }; - - auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&; - auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&; - - constexpr auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef { - return StringRef( rawChars, size ); - } -} // namespace Catch - -constexpr auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef { - return Catch::StringRef( rawChars, size ); -} - -// end catch_stringref.h -// start catch_preprocessor.hpp - - -#define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__ -#define CATCH_RECURSION_LEVEL1(...) CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__))) -#define CATCH_RECURSION_LEVEL2(...) CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__))) -#define CATCH_RECURSION_LEVEL3(...) CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(__VA_ARGS__))) -#define CATCH_RECURSION_LEVEL4(...) CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(__VA_ARGS__))) -#define CATCH_RECURSION_LEVEL5(...) CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(__VA_ARGS__))) - -#ifdef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR -#define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__ -// MSVC needs more evaluations -#define CATCH_RECURSION_LEVEL6(...) CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__))) -#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__)) -#else -#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL5(__VA_ARGS__) -#endif - -#define CATCH_REC_END(...) -#define CATCH_REC_OUT - -#define CATCH_EMPTY() -#define CATCH_DEFER(id) id CATCH_EMPTY() - -#define CATCH_REC_GET_END2() 0, CATCH_REC_END -#define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2 -#define CATCH_REC_GET_END(...) CATCH_REC_GET_END1 -#define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT -#define CATCH_REC_NEXT1(test, next) CATCH_DEFER ( CATCH_REC_NEXT0 ) ( test, next, 0) -#define CATCH_REC_NEXT(test, next) CATCH_REC_NEXT1(CATCH_REC_GET_END test, next) - -#define CATCH_REC_LIST0(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ ) -#define CATCH_REC_LIST1(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0) ) ( f, peek, __VA_ARGS__ ) -#define CATCH_REC_LIST2(f, x, peek, ...) f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ ) - -#define CATCH_REC_LIST0_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ ) -#define CATCH_REC_LIST1_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0_UD) ) ( f, userdata, peek, __VA_ARGS__ ) -#define CATCH_REC_LIST2_UD(f, userdata, x, peek, ...) f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ ) - -// Applies the function macro `f` to each of the remaining parameters, inserts commas between the results, -// and passes userdata as the first parameter to each invocation, -// e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a), f(x, b), f(x, c) -#define CATCH_REC_LIST_UD(f, userdata, ...) CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) - -#define CATCH_REC_LIST(f, ...) CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) - -#define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param) -#define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__ -#define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__ -#define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF -#define INTERNAL_CATCH_STRINGIZE(...) INTERNAL_CATCH_STRINGIZE2(__VA_ARGS__) -#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR -#define INTERNAL_CATCH_STRINGIZE2(...) #__VA_ARGS__ -#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) -#else -// MSVC is adding extra space and needs another indirection to expand INTERNAL_CATCH_NOINTERNAL_CATCH_DEF -#define INTERNAL_CATCH_STRINGIZE2(...) INTERNAL_CATCH_STRINGIZE3(__VA_ARGS__) -#define INTERNAL_CATCH_STRINGIZE3(...) #__VA_ARGS__ -#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) (INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1) -#endif - -#define INTERNAL_CATCH_MAKE_NAMESPACE2(...) ns_##__VA_ARGS__ -#define INTERNAL_CATCH_MAKE_NAMESPACE(name) INTERNAL_CATCH_MAKE_NAMESPACE2(name) - -#define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__) - -#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR -#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) decltype(get_wrapper()) -#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)) -#else -#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) INTERNAL_CATCH_EXPAND_VARGS(decltype(get_wrapper())) -#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))) -#endif - -#define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(...)\ - CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST,__VA_ARGS__) - -#define INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_0) INTERNAL_CATCH_REMOVE_PARENS(_0) -#define INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_0, _1) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_1) -#define INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_0, _1, _2) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_1, _2) -#define INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_0, _1, _2, _3) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_1, _2, _3) -#define INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_0, _1, _2, _3, _4) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_1, _2, _3, _4) -#define INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_0, _1, _2, _3, _4, _5) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_1, _2, _3, _4, _5) -#define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _3, _4, _5, _6) -#define INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_0, _1, _2, _3, _4, _5, _6, _7) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_1, _2, _3, _4, _5, _6, _7) -#define INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_1, _2, _3, _4, _5, _6, _7, _8) -#define INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9) -#define INTERNAL_CATCH_REMOVE_PARENS_11_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10) - -#define INTERNAL_CATCH_VA_NARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N - -#define INTERNAL_CATCH_TYPE_GEN\ - template struct TypeList {};\ - template\ - constexpr auto get_wrapper() noexcept -> TypeList { return {}; }\ - template class...> struct TemplateTypeList{};\ - template class...Cs>\ - constexpr auto get_wrapper() noexcept -> TemplateTypeList { return {}; }\ - template\ - struct append;\ - template\ - struct rewrap;\ - template class, typename...>\ - struct create;\ - template class, typename>\ - struct convert;\ - \ - template \ - struct append { using type = T; };\ - template< template class L1, typename...E1, template class L2, typename...E2, typename...Rest>\ - struct append, L2, Rest...> { using type = typename append, Rest...>::type; };\ - template< template class L1, typename...E1, typename...Rest>\ - struct append, TypeList, Rest...> { using type = L1; };\ - \ - template< template class Container, template class List, typename...elems>\ - struct rewrap, List> { using type = TypeList>; };\ - template< template class Container, template class List, class...Elems, typename...Elements>\ - struct rewrap, List, Elements...> { using type = typename append>, typename rewrap, Elements...>::type>::type; };\ - \ - template