From 3cd4031bd746e40dd88967b6726c6392ddf00955 Mon Sep 17 00:00:00 2001 From: Marco Date: Thu, 10 Oct 2024 14:30:51 -0300 Subject: [PATCH 01/13] fix: resolve nil method error in battlemart.lua callback (#2961) Replaced the method npc:getFormattedCategoryNames(itemsTable) with the function GetFormattedShopCategoryNames(SupplyShopConfigTable), which correctly formats the shop category names. This fixes the error and allows the NPC to properly display the selection of item categories. --- data-otservbr-global/npc/battlemart.lua | 153 +----------------------- 1 file changed, 4 insertions(+), 149 deletions(-) diff --git a/data-otservbr-global/npc/battlemart.lua b/data-otservbr-global/npc/battlemart.lua index e19ba50b6e5..b9f6f90683c 100644 --- a/data-otservbr-global/npc/battlemart.lua +++ b/data-otservbr-global/npc/battlemart.lua @@ -50,157 +50,12 @@ npcType.onCloseChannel = function(npc, creature) npcHandler:onCloseChannel(npc, creature) end -local itemsTable = { - ["foods"] = { - { itemName = "brown mushroom", clientId = 3725, buy = 10 }, - { itemName = "fire mushroom", clientId = 3731, buy = 300 }, - }, - ["exercise weapons"] = { - { itemName = "enhanced exercise axe", clientId = 35280, buy = 2340000 }, - { itemName = "enhanced exercise bow", clientId = 35282, buy = 2340000 }, - { itemName = "enhanced exercise club", clientId = 35281, buy = 2340000 }, - { itemName = "enhanced exercise rod", clientId = 35283, buy = 2340000 }, - { itemName = "enhanced exercise shield", clientId = 44066, buy = 2340000 }, - { itemName = "enhanced exercise sword", clientId = 35279, buy = 2340000 }, - { itemName = "enhanced exercise wand", clientId = 35284, buy = 2340000 }, - { itemName = "exercise axe", clientId = 28553, buy = 1800000 }, - { itemName = "exercise bow", clientId = 28555, buy = 1800000 }, - { itemName = "exercise club", clientId = 28554, buy = 1800000 }, - { itemName = "exercise rod", clientId = 28556, buy = 1800000 }, - { itemName = "exercise sword", clientId = 28552, buy = 1800000 }, - { itemName = "exercise wand", clientId = 28557, buy = 1800000 }, - { itemName = "masterful exercise axe", clientId = 35286, buy = 2700000 }, - { itemName = "masterful exercise bow", clientId = 35288, buy = 2700000 }, - { itemName = "masterful exercise club", clientId = 35287, buy = 2700000 }, - { itemName = "masterful exercise rod", clientId = 35289, buy = 2700000 }, - { itemName = "masterful exercise shield", clientId = 44067, buy = 2700000 }, - { itemName = "masterful exercise sword", clientId = 35285, buy = 2700000 }, - { itemName = "masterful exercise wand", clientId = 35290, buy = 2700000 }, - }, - ["distance equipments"] = { - { itemName = "envenomed arrow", clientId = 16143, buy = 12 }, - { itemName = "diamond arrow", clientId = 35901, buy = 100 }, - { itemName = "drill bolt", clientId = 16142, buy = 12 }, - { itemName = "crystalline arrow", clientId = 15793, buy = 20 }, - { itemName = "blue quiver", clientId = 35848, buy = 400 }, - { itemName = "bolt", clientId = 3446, buy = 4 }, - { itemName = "bow", clientId = 3350, buy = 400 }, - { itemName = "arrow", clientId = 3447, buy = 3 }, - { itemName = "assassin star", clientId = 7368, buy = 100 }, - { itemName = "earth arrow", clientId = 774, buy = 5 }, - { itemName = "enchanted spear", clientId = 7367, buy = 30 }, - { itemName = "flaming arrow", clientId = 763, buy = 5 }, - { itemName = "flash arrow", clientId = 761, buy = 5 }, - { itemName = "royal star", clientId = 25759, buy = 110 }, - { itemName = "quiver", clientId = 35562, buy = 400 }, - { itemName = "red quiver", clientId = 35849, buy = 400 }, - { itemName = "power bolt", clientId = 3450, buy = 7 }, - { itemName = "piercing bolt", clientId = 7363, buy = 5 }, - { itemName = "onyx arrow", clientId = 7365, buy = 7 }, - { itemName = "prismatic bolt", clientId = 16141, buy = 20 }, - { itemName = "shiver arrow", clientId = 762, buy = 5 }, - { itemName = "sniper arrow", clientId = 7364, buy = 5 }, - { itemName = "spear", clientId = 3277, buy = 5 }, - { itemName = "spectral bolt", clientId = 35902, buy = 70 }, - { itemName = "throwing star", clientId = 3287, buy = 42 }, - { itemName = "tarsal arrow", clientId = 14251, buy = 6 }, - { itemName = "vortex bolt", clientId = 14252, buy = 6 }, - { itemName = "hunting spear", clientId = 3347, buy = 25 }, - }, - ["runes"] = { - { itemName = "avalanche rune", clientId = 3161, buy = 57 }, - { itemName = "blank rune", clientId = 3147, buy = 10 }, - { itemName = "chameleon rune", clientId = 3178, buy = 210 }, - { itemName = "animate dead rune", clientId = 3203, buy = 375 }, - { itemName = "convince creature rune", clientId = 3177, buy = 80 }, - { itemName = "cure poison rune", clientId = 3153, buy = 65 }, - { itemName = "desintegrate rune", clientId = 3197, buy = 26 }, - { itemName = "destroy field rune", clientId = 3148, buy = 15 }, - { itemName = "energy wall rune", clientId = 3166, buy = 85 }, - { itemName = "energy bomb rune", clientId = 3149, buy = 203 }, - { itemName = "energy field rune", clientId = 3164, buy = 38 }, - { itemName = "explosion rune", clientId = 3200, buy = 31 }, - { itemName = "fire bomb rune", clientId = 3192, buy = 147 }, - { itemName = "fire field rune", clientId = 3188, buy = 28 }, - { itemName = "fire wall rune", clientId = 3190, buy = 61 }, - { itemName = "fireball rune", clientId = 3189, buy = 30 }, - { itemName = "great fireball rune", clientId = 3191, buy = 57 }, - { itemName = "heavy magic missile rune", clientId = 3198, buy = 12 }, - { itemName = "holy missile rune", clientId = 3182, buy = 16 }, - { itemName = "icicle rune", clientId = 3158, buy = 30 }, - { itemName = "intense healing rune", clientId = 3152, buy = 95 }, - { itemName = "light magic missile rune", clientId = 3174, buy = 4 }, - { itemName = "magic wall rune", clientId = 3180, buy = 116 }, - { itemName = "paralyze rune", clientId = 3165, buy = 700 }, - { itemName = "poison bomb rune", clientId = 3173, buy = 85 }, - { itemName = "poison field rune", clientId = 3172, buy = 21 }, - { itemName = "poison wall rune", clientId = 3176, buy = 52 }, - { itemName = "stone shower rune", clientId = 3175, buy = 37 }, - { itemName = "stalagmite rune", clientId = 3179, buy = 12 }, - { itemName = "sudden death rune", clientId = 3155, buy = 135 }, - { itemName = "soulfire rune", clientId = 3195, buy = 46 }, - { itemName = "thunderstorm rune", clientId = 3202, buy = 47 }, - { itemName = "ultimate healing rune", clientId = 3160, buy = 175 }, - { itemName = "wild growth rune", clientId = 3156, buy = 160 }, - }, - ["tools"] = { - { itemName = "fishing rod", clientId = 3483, buy = 150 }, - { itemName = "flask of rust remover", clientId = 9016, buy = 50 }, - { itemName = "torch", clientId = 2920, buy = 2 }, - { itemName = "worm", clientId = 3492, buy = 1 }, - { itemName = "crowbar", clientId = 3304, buy = 260 }, - { itemName = "backpack", clientId = 2854, buy = 20 }, - }, - ["amulets"] = { - { itemName = "gill necklace", clientId = 16108, buy = 20000 }, - { itemName = "glacier amulet", clientId = 815, buy = 15000 }, - { itemName = "leviathan's amulet", clientId = 9303, buy = 30000 }, - { itemName = "magma amulet", clientId = 817, buy = 15000 }, - { itemName = "lightning pendant", clientId = 816, buy = 15000 }, - { itemName = "prismatic necklace", clientId = 16113, buy = 20000 }, - { itemName = "sacred tree amulet", clientId = 9302, buy = 30000 }, - { itemName = "shockwave amulet", clientId = 9304, buy = 30000 }, - { itemName = "stone skin amulet", clientId = 3081, buy = 5000 }, - { itemName = "collar of blue plasma", clientId = 23542, buy = 60000 }, - { itemName = "collar of green plasma", clientId = 23543, buy = 60000 }, - { itemName = "collar of red plasma", clientId = 23544, buy = 60000 }, - { itemName = "terra amulet", clientId = 814, buy = 15000 }, - }, - ["rings"] = { - { itemName = "life ring", clientId = 3052, buy = 900 }, - { itemName = "might ring", clientId = 3048, buy = 5000 }, - { itemName = "ring of blue plasma", clientId = 23529, buy = 80000 }, - { itemName = "ring of green plasma", clientId = 23531, buy = 80000 }, - { itemName = "ring of healing", clientId = 3098, buy = 2000 }, - { itemName = "prismatic ring", clientId = 16114, buy = 100000 }, - { itemName = "ring of red plasma", clientId = 23533, buy = 80000 }, - { itemName = "stealth ring", clientId = 3049, buy = 5000 }, - { itemName = "time ring", clientId = 3053, buy = 2000 }, - { itemName = "dwarven ring", clientId = 3097, buy = 2000 }, - { itemName = "energy ring", clientId = 3051, buy = 2000 }, - }, - ["potions"] = { - { itemName = "great health potion", clientId = 239, buy = 225 }, - { itemName = "great mana potion", clientId = 238, buy = 144 }, - { itemName = "great spirit potion", clientId = 7642, buy = 228 }, - { itemName = "health potion", clientId = 266, buy = 50 }, - { itemName = "mana potion", clientId = 268, buy = 56 }, - { itemName = "mana shield potion", clientId = 35563, buy = 200000 }, - { itemName = "ultimate health potion", clientId = 7643, buy = 379 }, - { itemName = "ultimate mana potion", clientId = 23373, buy = 438 }, - { itemName = "ultimate spirit potion", clientId = 23374, buy = 438 }, - { itemName = "supreme health potion", clientId = 23375, buy = 625 }, - { itemName = "strong health potion", clientId = 236, buy = 115 }, - { itemName = "strong mana potion", clientId = 237, buy = 93 }, - }, -} - local function creatureSayCallback(npc, player, type, message) - local categoryTable = itemsTable[message:lower()] + local categoryTable = SupplyShopConfigTable[message:lower()] if MsgContains(message, "shop options") then - npcHandler:say("I sell a selection of " .. npc:getFormattedCategoryNames(itemsTable), npc, player) + npcHandler:say("I sell a selection of " .. GetFormattedShopCategoryNames(SupplyShopConfigTable), npc, player) elseif categoryTable then - local remainingCategories = npc:getRemainingShopCategories(message:lower(), itemsTable) + local remainingCategories = npc:getRemainingShopCategories(message:lower(), SupplyShopConfigTable) npcHandler:say("Of course, just browse through my wares. You can also look at " .. remainingCategories .. ".", npc, player) npc:openShopWindowTable(player, categoryTable) end @@ -209,7 +64,7 @@ end npcHandler:setMessage(MESSAGE_GREET, "It is good to see you. I'm always at your {shop options}") npcHandler:setMessage(MESSAGE_FAREWELL, "Farewell, |PLAYERNAME|, I'll be here if you need me again.") npcHandler:setMessage(MESSAGE_WALKAWAY, "Come back soon!") -npcHandler:setMessage(MESSAGE_SENDTRADE, "Of course, just browse through my wares. Or do you want to look only at " .. GetFormattedShopCategoryNames(itemsTable) .. ".") +npcHandler:setMessage(MESSAGE_SENDTRADE, "Of course, just browse through my wares. Or do you want to look only at " .. GetFormattedShopCategoryNames(SupplyShopConfigTable) .. ".") npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) npcHandler:addModule(FocusModule:new(), npcConfig.name, true, true, true) From e71a259f6cfd5e5a34fc7190feef506294f6c089 Mon Sep 17 00:00:00 2001 From: Leonardo <130802152+PetryNotak@users.noreply.github.com> Date: Fri, 11 Oct 2024 10:44:02 -0300 Subject: [PATCH 02/13] fix: handle nil value for soul war to prevent errors with custom data (#2964) --- data/libs/functions/monstertype.lua | 2 +- data/scripts/lib/quests.lua | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/data/libs/functions/monstertype.lua b/data/libs/functions/monstertype.lua index a9f6fff59f7..042fda08276 100644 --- a/data/libs/functions/monstertype.lua +++ b/data/libs/functions/monstertype.lua @@ -28,7 +28,7 @@ function MonsterType:generateLootRoll(config, resultTable, player) end local chance = item.chance - if iType:getId() == SoulWarQuest.bagYouDesireItemId then + if SoulWarQuest and iType:getId() == SoulWarQuest.bagYouDesireItemId then result[item.itemId].chance = self:calculateBagYouDesireChance(player, chance) logger.debug("Final chance for bag you desire: {}, original chance: {}", result[item.itemId].chance, chance) end diff --git a/data/scripts/lib/quests.lua b/data/scripts/lib/quests.lua index 08005e34ae2..90d03462b12 100644 --- a/data/scripts/lib/quests.lua +++ b/data/scripts/lib/quests.lua @@ -1,2 +1,4 @@ -- We need to register the variables beforehand to avoid accessing null values. -RegisterSoulWarBossesLevers() +if RegisterSoulWarBossesLevers then + RegisterSoulWarBossesLevers() +end From 35550d10e55616098d64473f08a84ef41d355673 Mon Sep 17 00:00:00 2001 From: Eduardo Dantas Date: Fri, 11 Oct 2024 11:01:51 -0300 Subject: [PATCH 03/13] fix: eventcallback from std::forward to args (#2962) Using std::forward inside a loop can cause rvalue arguments to be moved and invalidated after the first iteration. This happens because std::forward preserves the value category, allowing rvalues to be moved. To ensure arguments remain valid across all iterations when invoking callbacks, avoid using std::forward inside the loop and pass arguments directly as args.... Resolves #2959 --- src/lua/callbacks/events_callbacks.hpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/lua/callbacks/events_callbacks.hpp b/src/lua/callbacks/events_callbacks.hpp index 9b80dabd93a..032b6bef28f 100644 --- a/src/lua/callbacks/events_callbacks.hpp +++ b/src/lua/callbacks/events_callbacks.hpp @@ -90,8 +90,7 @@ class EventsCallbacks { void executeCallback(EventCallback_t eventType, CallbackFunc callbackFunc, Args &&... args) { for (const auto &[name, callback] : getCallbacksByType(eventType)) { if (callback && callback->isLoadedCallback()) { - std::invoke(callbackFunc, *callback, std::forward(args)...); - // g_logger().trace("Executed callback: {}", name); + std::invoke(callbackFunc, *callback, args...); } } } @@ -107,7 +106,7 @@ class EventsCallbacks { ReturnValue checkCallbackWithReturnValue(EventCallback_t eventType, CallbackFunc callbackFunc, Args &&... args) { for (const auto &[name, callback] : getCallbacksByType(eventType)) { if (callback && callback->isLoadedCallback()) { - ReturnValue callbackResult = std::invoke(callbackFunc, *callback, std::forward(args)...); + ReturnValue callbackResult = std::invoke(callbackFunc, *callback, args...); if (callbackResult != RETURNVALUE_NOERROR) { return callbackResult; } @@ -128,7 +127,7 @@ class EventsCallbacks { bool allCallbacksSucceeded = true; for (const auto &[name, callback] : getCallbacksByType(eventType)) { if (callback && callback->isLoadedCallback()) { - bool callbackResult = std::invoke(callbackFunc, *callback, std::forward(args)...); + bool callbackResult = std::invoke(callbackFunc, *callback, args...); allCallbacksSucceeded &= callbackResult; } } From 34baa0af0286c2b2070a79edd6a344499071242a Mon Sep 17 00:00:00 2001 From: "Leilani A." <168607226+kaleohanopahala@users.noreply.github.com> Date: Fri, 11 Oct 2024 11:02:33 -0300 Subject: [PATCH 04/13] fix: player wheel string conversion (#2967) Now checks to ensure that strings are numeric before converting them to numbers with std::stoull. If the strings are not numeric, it falls back to a lexicographical comparison, preventing crashes caused by invalid conversions. Resolves #2966 --- src/creatures/players/wheel/player_wheel.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/creatures/players/wheel/player_wheel.cpp b/src/creatures/players/wheel/player_wheel.cpp index 3d0a3619bd0..7a317106074 100644 --- a/src/creatures/players/wheel/player_wheel.cpp +++ b/src/creatures/players/wheel/player_wheel.cpp @@ -771,12 +771,18 @@ std::vector PlayerWheel::getRevealedGems() const { if (unlockedGemUUIDs.empty()) { return unlockedGems; } + std::vector sortedUnlockedGemGUIDs; for (const auto &uuid : unlockedGemUUIDs) { sortedUnlockedGemGUIDs.push_back(uuid); } + std::sort(sortedUnlockedGemGUIDs.begin(), sortedUnlockedGemGUIDs.end(), [](const std::string &a, const std::string &b) { - return std::stoull(a) < std::stoull(b); + if (std::ranges::all_of(a, ::isdigit) && std::ranges::all_of(b, ::isdigit)) { + return std::stoull(a) < std::stoull(b); + } else { + return a < b; + } }); for (const auto &uuid : sortedUnlockedGemGUIDs) { From c4786c42e412bf884c5683a96d17a78fe157fc5f Mon Sep 17 00:00:00 2001 From: Beats Date: Sat, 12 Oct 2024 19:29:22 -0300 Subject: [PATCH 05/13] perf: build cmake (#2972) --- CMakeLists.txt | 63 +++++++-------------------- cmake/modules/BaseConfig.cmake | 79 ++++++++++++++++++++-------------- cmake/modules/CanaryLib.cmake | 57 ++++++++++-------------- src/CMakeLists.txt | 29 +++++-------- src/kv/value_wrapper.hpp | 4 +- tests/CMakeLists.txt | 9 ++++ 6 files changed, 108 insertions(+), 133 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5bee518ecd6..3d143fec490 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,33 +7,31 @@ cmake_minimum_required(VERSION 3.22 FATAL_ERROR) # VCPKG # cmake -DCMAKE_TOOLCHAIN_FILE=/opt/workspace/vcpkg/scripts/buildsystems/vcpkg.cmake .. -# Needed libs is in file vcpkg.json +# Needed libs are in file vcpkg.json # Windows required libs: .\vcpkg install --triplet x64-windows asio pugixml spdlog curl protobuf parallel-hashmap magic-enum mio luajit libmariadb mpir abseil bshoshany-thread-pool + if(DEFINED ENV{VCPKG_ROOT} AND NOT DEFINED CMAKE_TOOLCHAIN_FILE) - set(CMAKE_TOOLCHAIN_FILE "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" - CACHE STRING "") + set(CMAKE_TOOLCHAIN_FILE "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" + CACHE STRING "") endif() if(DEFINED ENV{VCPKG_DEFAULT_TRIPLET} AND NOT DEFINED VCPKG_TARGET_TRIPLET) - set(VCPKG_TARGET_TRIPLET "$ENV{VCPKG_DEFAULT_TRIPLET}" CACHE STRING "") + set(VCPKG_TARGET_TRIPLET "$ENV{VCPKG_DEFAULT_TRIPLET}" CACHE STRING "") endif() set(VCPKG_FEATURE_FLAGS "versions") set(VCPKG_BUILD_TYPE "release") set(CMAKE_EXPORT_COMPILE_COMMANDS ON) - - # ***************************************************************************** # Project canary # ***************************************************************************** if(CMAKE_BUILD_TYPE STREQUAL "Debug") - project(canary-debug) + project(canary-debug LANGUAGES CXX) else() - project(canary) + project(canary LANGUAGES CXX) endif() - # ***************************************************************************** # Append cmake search path # ***************************************************************************** @@ -57,7 +55,7 @@ option(FEATURE_METRICS "Enable metrics feature" OFF) # Options Code # ***************************************************************************** -if(FEATURE_METRIC) +if(FEATURE_METRICS) log_option_enabled("metrics") else () log_option_disabled("metrics") @@ -69,52 +67,21 @@ if(OPTIONS_ENABLE_CCACHE) if(CCACHE) log_option_enabled("ccache") set(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE}) - else() + else() log_option_disabled("ccache") endif() endif() - # === SCCACHE === if(OPTIONS_ENABLE_SCCACHE) - find_program(SCCACHE_PATH sccache) - if(SCCACHE_PATH) - log_option_enabled("sccache") - set(CMAKE_C_COMPILER_LAUNCHER ${SCCACHE_PATH}) - set(CMAKE_CXX_COMPILER_LAUNCHER ${SCCACHE_PATH}) - else() - log_option_disabled("sccache") - endif() -endif() - - -# === IPO === -if(OPTIONS_ENABLE_IPO) - if(MSVC) - log_option_enabled("IPO/LTO") - set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /GL") - set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO} /LTCG") - set(CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO} /LTCG") - set(CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO} /LTCG") - set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} /LTCG") + find_program(SCCACHE_PATH sccache) + if(SCCACHE_PATH) + log_option_enabled("sccache") + set(CMAKE_C_COMPILER_LAUNCHER ${SCCACHE_PATH}) + set(CMAKE_CXX_COMPILER_LAUNCHER ${SCCACHE_PATH}) else() - if(CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo" OR CMAKE_BUILD_TYPE STREQUAL "Release") - log_option_enabled("IPO/LTO") - include(CheckIPOSupported) - check_ipo_supported(RESULT result OUTPUT output) - if(result) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto=auto") - message(STATUS "IPO/LTO enabled with -flto=auto for non-MSVC compiler.") - set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) - else() - log_war("IPO/LTO not supported: ${output}") - endif() - else() - log_option_disabled("IPO/LTO") - endif () + log_option_disabled("sccache") endif() -else() - log_option_disabled("IPO/LTO") endif() option(BUILD_TESTS "Build tests" OFF) # By default, tests will not be built diff --git a/cmake/modules/BaseConfig.cmake b/cmake/modules/BaseConfig.cmake index f61ee9e809c..f987020db26 100644 --- a/cmake/modules/BaseConfig.cmake +++ b/cmake/modules/BaseConfig.cmake @@ -3,9 +3,7 @@ cmake_minimum_required(VERSION 3.22 FATAL_ERROR) # ***************************************************************************** # CMake Features # ***************************************************************************** -set(CMAKE_CXX_STANDARD 20) -set(GNUCXX_MINIMUM_VERSION 11) -set(MSVC_MINIMUM_VERSION "19.32") +set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_POSITION_INDEPENDENT_CODE ON) set(CMAKE_DISABLE_SOURCE_CHANGES ON) @@ -15,9 +13,6 @@ set(Boost_NO_WARN_NEW_VERSIONS ON) # Make will print more details set(CMAKE_VERBOSE_MAKEFILE OFF) -# Generate compile_commands.json -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) - # ***************************************************************************** # Packages / Libs # ***************************************************************************** @@ -50,21 +45,21 @@ find_path(BOOST_DI_INCLUDE_DIRS "boost/di.hpp") # === GCC Minimum Version === if (CMAKE_COMPILER_IS_GNUCXX) message("-- Compiler: GCC - Version: ${CMAKE_CXX_COMPILER_VERSION}") - if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS GNUCXX_MINIMUM_VERSION) - message(FATAL_ERROR "GCC version must be at least ${GNUCXX_MINIMUM_VERSION}!") + if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 11) + message(FATAL_ERROR "GCC version must be at least 11!") endif() endif() # === Minimum required version for visual studio === if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") message("-- Compiler: Visual Studio - Version: ${CMAKE_CXX_COMPILER_VERSION}") - if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS MSVC_MINIMUM_VERSION) - message(FATAL_ERROR "Visual Studio version must be at least ${MSVC_MINIMUM_VERSION}") + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "19.32") + message(FATAL_ERROR "Visual Studio version must be at least 19.32") endif() endif() # ***************************************************************************** -# Sanity Checks +# Options # ***************************************************************************** option(TOGGLE_BIN_FOLDER "Use build/bin folder for generate compilation files" ON) option(OPTIONS_ENABLE_OPENMP "Enable Open Multi-Processing support." ON) @@ -79,14 +74,14 @@ if(TOGGLE_BIN_FOLDER) log_option_enabled("TOGGLE_BIN_FOLDER") else() log_option_disabled("TOGGLE_BIN_FOLDER") -endif(TOGGLE_BIN_FOLDER) +endif() -# === TOGGLE_BIN_FOLDER === +# === OPTIONS_ENABLE_OPENMP === if(OPTIONS_ENABLE_OPENMP) log_option_enabled("OPTIONS_ENABLE_OPENMP") else() log_option_disabled("OPTIONS_ENABLE_OPENMP") -endif(OPTIONS_ENABLE_OPENMP) +endif() # === DEBUG LOG === # cmake -DDEBUG_LOG=ON .. @@ -95,7 +90,7 @@ if(DEBUG_LOG) log_option_enabled("DEBUG LOG") else() log_option_disabled("DEBUG LOG") -endif(DEBUG_LOG) +endif() # === ASAN === if(ASAN_ENABLED) @@ -113,7 +108,6 @@ endif() # === BUILD_STATIC_LIBRARY === if(BUILD_STATIC_LIBRARY) log_option_enabled("STATIC_LIBRARY") - if(MSVC) set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib") elseif(UNIX AND NOT APPLE) @@ -130,14 +124,36 @@ if(SPEED_UP_BUILD_UNITY) log_option_enabled("SPEED_UP_BUILD_UNITY") else() log_option_disabled("SPEED_UP_BUILD_UNITY") -endif(SPEED_UP_BUILD_UNITY) +endif() # === USE_PRECOMPILED_HEADER === if(USE_PRECOMPILED_HEADER) log_option_enabled("USE_PRECOMPILED_HEADER") else() log_option_disabled("USE_PRECOMPILED_HEADER") -endif(USE_PRECOMPILED_HEADER) +endif() + +# === IPO Configuration === +function(configure_linking target_name) + if(OPTIONS_ENABLE_IPO) + include(CheckIPOSupported) + check_ipo_supported(RESULT ipo_supported OUTPUT ipo_output LANGUAGES CXX) + if(ipo_supported) + set_property(TARGET ${target_name} PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE) + message(STATUS "IPO/LTO enabled for target ${target_name}.") + + if(MSVC) + target_compile_options(${target_name} PRIVATE /GL) + target_link_options(${target_name} PRIVATE /LTCG) + elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") + target_compile_options(${target_name} PRIVATE -flto) + target_link_options(${target_name} PRIVATE -flto) + endif() + else() + message(WARNING "IPO/LTO is not supported for target ${target_name}: ${ipo_output}") + endif() + endif() +endfunction() # ***************************************************************************** # Compiler Options @@ -147,39 +163,38 @@ if (MSVC) string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_${type} "${CMAKE_CXX_FLAGS_${type}}") string(REPLACE "/Zi" "/Z7" CMAKE_C_FLAGS_${type} "${CMAKE_C_FLAGS_${type}}") endforeach(type) - add_compile_options(/MP /FS /Zf /EHsc) else() add_compile_options(-Wno-unused-parameter -Wno-sign-compare -Wno-switch -Wno-implicit-fallthrough -Wno-extra) endif() -## Link compilation files to build/bin folder, else link to the main dir +# === Compiler Features === +add_library(project_options INTERFACE) +target_compile_features(project_options INTERFACE cxx_std_23) + +# ***************************************************************************** +# Output Directory Function +# ***************************************************************************** function(set_output_directory target_name) if (TOGGLE_BIN_FOLDER) set_target_properties(${target_name} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" - ) + ) else() set_target_properties(${target_name} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/" - ) + ) endif() endfunction() -## Setup shared target basic configurations +# ***************************************************************************** +# Setup Target Function +# ***************************************************************************** function(setup_target TARGET_NAME) if (MSVC AND BUILD_STATIC_LIBRARY) set_property(TARGET ${TARGET_NAME} PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") endif() + target_link_libraries(${TARGET_NAME} PUBLIC project_options) endfunction() - -# ***************************************************************************** -# DEBUG: Print cmake variables -# ***************************************************************************** -#get_cmake_property(_variableNames VARIABLES) -#list (SORT _variableNames) -#foreach (_variableName ${_variableNames}) -# message(STATUS "${_variableName}=${${_variableName}}") -#endforeach() diff --git a/cmake/modules/CanaryLib.cmake b/cmake/modules/CanaryLib.cmake index 84d1c96c214..fbb7aad27c0 100644 --- a/cmake/modules/CanaryLib.cmake +++ b/cmake/modules/CanaryLib.cmake @@ -22,11 +22,10 @@ add_subdirectory(utils) # Add more global sources - please add preferably in the sub_directory CMakeLists. target_sources(${PROJECT_NAME}_lib PRIVATE canary_server.cpp) -# Add public pre compiler header to lib, to pass down to related targets -target_precompile_headers(${PROJECT_NAME}_lib PUBLIC pch.hpp) - -if(NOT SPEED_UP_BUILD_UNITY AND USE_PRECOMPILED_HEADERS) - target_compile_definitions(${PROJECT_NAME}_lib PUBLIC -DUSE_PRECOMPILED_HEADERS) +# Conditional Precompiled Headers +if(USE_PRECOMPILED_HEADER) + target_precompile_headers(${PROJECT_NAME}_lib PUBLIC pch.hpp) + target_compile_definitions(${PROJECT_NAME}_lib PUBLIC USE_PRECOMPILED_HEADERS) endif() # ***************************************************************************** @@ -36,38 +35,21 @@ if (CMAKE_COMPILER_IS_GNUCXX) target_compile_options(${PROJECT_NAME}_lib PRIVATE -Wno-deprecated-declarations) endif() -# Sets the NDEBUG macro for RelWithDebInfo and Release configurations. -# This disables assertions in these configurations, optimizing the code for performance -# and reducing debugging overhead, while keeping debug information available for diagnostics. +# Sets the NDEBUG macro for Release and RelWithDebInfo configurations. target_compile_definitions(${PROJECT_NAME}_lib PUBLIC - $<$:NDEBUG> - $<$:NDEBUG> + $<$:NDEBUG> + $<$:NDEBUG> ) -# === IPO === -if(MSVC) - target_compile_options(${PROJECT_NAME}_lib PRIVATE "/GL") - set_target_properties(${PROJECT_NAME}_lib PROPERTIES - STATIC_LINKER_FLAGS "/LTCG" - SHARED_LINKER_FLAGS "/LTCG" - MODULE_LINKER_FLAGS "/LTCG" - EXE_LINKER_FLAGS "/LTCG") -else() - include(CheckIPOSupported) - check_ipo_supported(RESULT result) - if(result) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto=auto") - message(STATUS "IPO/LTO enabled with -flto=auto for non-MSVC compiler.") - set_property(TARGET ${PROJECT_NAME}_lib PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE) - else() - message(WARNING "IPO/LTO is not supported: ${output}") - endif() -endif() +# Configurar IPO e Linkagem Incremental +configure_linking(${PROJECT_NAME}_lib) # === UNITY BUILD (compile time reducer) === if(SPEED_UP_BUILD_UNITY) set_target_properties(${PROJECT_NAME}_lib PROPERTIES UNITY_BUILD ON) log_option_enabled("Build unity for speed up compilation") +else() + log_option_disabled("Build unity") endif() # ***************************************************************************** @@ -80,13 +62,13 @@ target_include_directories(${PROJECT_NAME}_lib ${GMP_INCLUDE_DIRS} ${LUAJIT_INCLUDE_DIRS} ${PARALLEL_HASHMAP_INCLUDE_DIRS} - ) +) # ***************************************************************************** # Target links to external dependencies # ***************************************************************************** target_link_libraries(${PROJECT_NAME}_lib - PUBLIC + PUBLIC ${GMP_LIBRARIES} ${LUAJIT_LIBRARIES} CURL::libcurl @@ -108,7 +90,6 @@ target_link_libraries(${PROJECT_NAME}_lib if(FEATURE_METRICS) add_definitions(-DFEATURE_METRICS) - target_link_libraries(${PROJECT_NAME}_lib PUBLIC opentelemetry-cpp::common @@ -134,11 +115,10 @@ if (MSVC) else() set(VCPKG_TARGET_TRIPLET "x64-windows" CACHE STRING "") endif() - target_link_libraries(${PROJECT_NAME}_lib PUBLIC ${CMAKE_THREAD_LIBS_INIT} ${MYSQL_CLIENT_LIBS}) else() target_link_libraries(${PROJECT_NAME}_lib PUBLIC Threads::Threads) -endif (MSVC) +endif() # === OpenMP === if(OPTIONS_ENABLE_OPENMP) @@ -150,3 +130,12 @@ if(OPTIONS_ENABLE_OPENMP) else() log_option_disabled("openmp") endif() + +# === Optimization Flags === +if(CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo" OR CMAKE_BUILD_TYPE STREQUAL "Release") + if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") + target_compile_options(${PROJECT_NAME}_lib PRIVATE -O3 -march=native) + elseif(MSVC) + target_compile_options(${PROJECT_NAME}_lib PRIVATE /O2) + endif() +endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2abd46f06c2..50bea4189ff 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -15,24 +15,17 @@ if(MSVC) target_sources(${PROJECT_NAME} PRIVATE ../cmake/canary.rc) endif() -if (UNIX) - - if(CMAKE_BUILD_TYPE STREQUAL "Debug") - target_compile_options(${PROJECT_NAME}_lib - PRIVATE - -Wall -Wextra -Wpedantic - ) - endif() - - if(CMAKE_BUILD_TYPE STREQUAL "Debug") - target_compile_options(${PROJECT_NAME} - PRIVATE - -Wall -Wextra -Wpedantic - ) - endif() - -endif (UNIX) - setup_target(${PROJECT_NAME}) set_output_directory(${PROJECT_NAME}) target_link_libraries(${PROJECT_NAME} PRIVATE ${PROJECT_NAME}_lib) + +# Configurar IPO e Linkagem Incremental para o executável +configure_linking(${PROJECT_NAME}) + +# Compiler warnings and options +if (UNIX) + if(CMAKE_BUILD_TYPE STREQUAL "Debug") + target_compile_options(${PROJECT_NAME}_lib PRIVATE -Wall -Wextra -Wpedantic) + target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wextra -Wpedantic) + endif() +endif() diff --git a/src/kv/value_wrapper.hpp b/src/kv/value_wrapper.hpp index 889b1776de2..df1ad85e8df 100644 --- a/src/kv/value_wrapper.hpp +++ b/src/kv/value_wrapper.hpp @@ -169,7 +169,7 @@ inline bool ValueWrapper::operator==(const ValueWrapper &rhs) const { inline bool operator==(const ValueVariant &lhs, const ValueVariant &rhs) { return std::visit( - [](const auto &a, const auto &b) { + [](const auto &a, const auto &b) -> bool { using A = std::decay_t; using B = std::decay_t; @@ -190,6 +190,8 @@ inline bool operator==(const ValueVariant &lhs, const ValueVariant &rhs) { if constexpr (std::is_same_v) { return a == b; } + + return false; }, lhs, rhs ); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 5cf5c5d80ee..3838528bd23 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -9,6 +9,15 @@ function(setup_test TARGET_NAME DIR) target_link_libraries(${TARGET_NAME} PRIVATE Boost::ut ${PROJECT_NAME}_lib) target_include_directories(${TARGET_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/tests/fixture PRIVATE ${CMAKE_SOURCE_DIR}/tests/${DIR}) + if(SPEED_UP_BUILD_UNITY AND (CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo" OR CMAKE_BUILD_TYPE STREQUAL "Release")) + set_target_properties(${TARGET_NAME} PROPERTIES UNITY_BUILD ON) + log_option_enabled("Build unity for speed up compilation") + else() + log_option_disabled("Build unity") + endif() + + configure_linking(${TARGET_NAME}) + add_test(NAME ${DIR} COMMAND ${TARGET_NAME}) if(RUN_TESTS_AFTER_BUILD) add_custom_command( From ff268331172ac8c59ae1c94377436e670bc4ceae Mon Sep 17 00:00:00 2001 From: Beats Date: Sun, 13 Oct 2024 00:54:20 -0300 Subject: [PATCH 06/13] update: gha build (#2641) --- .github/workflows/build-ubuntu.yml | 27 ++++++++++++++------ cmake/modules/BaseConfig.cmake | 30 ++++++++++++++++++++--- cmake/modules/CanaryLib.cmake | 3 +-- cmake/modules/FindMySQL.cmake | 2 +- src/lua/functions/core/game/lua_enums.cpp | 15 +++++++++++- src/lua/functions/core/game/lua_enums.hpp | 3 +++ src/main.cpp | 19 ++++++++++++++ src/pch.hpp | 7 +++--- tests/CMakeLists.txt | 2 +- vcpkg.json | 9 ++----- 10 files changed, 90 insertions(+), 27 deletions(-) diff --git a/.github/workflows/build-ubuntu.yml b/.github/workflows/build-ubuntu.yml index 2b369e34875..6a252630f48 100644 --- a/.github/workflows/build-ubuntu.yml +++ b/.github/workflows/build-ubuntu.yml @@ -36,11 +36,13 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-22.04] + os: [ubuntu-22.04, ubuntu-24.04] buildtype: [linux-release, linux-debug] include: - os: ubuntu-22.04 triplet: x64-linux + - os: ubuntu-24.04 + triplet: x64-linux steps: - name: Checkout repository @@ -48,14 +50,23 @@ jobs: - name: Install Linux Dependencies run: > - sudo apt-get update && sudo apt-get install ccache linux-headers-$(uname -r) + sudo apt-get update && sudo apt-get install ccache linux-headers-"$(uname -r)" + + - name: Switch to gcc-12 on Ubuntu 22.04 + if: matrix.os == 'ubuntu-22.04' + run: | + sudo apt install gcc-12 g++-12 + sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-12 100 --slave /usr/bin/g++ g++ /usr/bin/g++-12 --slave /usr/bin/gcov gcov /usr/bin/gcov-12 + sudo update-alternatives --set gcc /usr/bin/gcc-12 - - name: Switch to gcc-11 - if: matrix.os == 'ubuntu-20.04' + - name: Switch to gcc-14 on Ubuntu 24.04 + if: matrix.os == 'ubuntu-24.04' run: | - sudo apt install gcc-11 g++-11 - sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-11 100 --slave /usr/bin/g++ g++ /usr/bin/g++-11 --slave /usr/bin/gcov gcov /usr/bin/gcov-11 - sudo update-alternatives --set gcc /usr/bin/gcc-11 + sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y + sudo apt-get update + sudo apt-get install gcc-14 g++-14 -y + sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-14 100 --slave /usr/bin/g++ g++ /usr/bin/g++-14 --slave /usr/bin/gcov gcov /usr/bin/gcov-14 + sudo update-alternatives --set gcc /usr/bin/gcc-14 - name: CCache uses: hendrikmuhs/ccache-action@main @@ -70,7 +81,7 @@ jobs: run: | vcpkgCommitId=$(grep '.builtin-baseline' vcpkg.json | awk -F: '{print $2}' | tr -d '," ') echo "vcpkg commit ID: $vcpkgCommitId" - echo "VCPKG_GIT_COMMIT_ID=$vcpkgCommitId" >> $GITHUB_ENV + echo "VCPKG_GIT_COMMIT_ID=$vcpkgCommitId" >> "$GITHUB_ENV" - name: Get vcpkg commit id from vcpkg.json uses: lukka/run-vcpkg@main diff --git a/cmake/modules/BaseConfig.cmake b/cmake/modules/BaseConfig.cmake index f987020db26..e772f78b3a1 100644 --- a/cmake/modules/BaseConfig.cmake +++ b/cmake/modules/BaseConfig.cmake @@ -136,21 +136,43 @@ endif() # === IPO Configuration === function(configure_linking target_name) if(OPTIONS_ENABLE_IPO) + # Check if IPO/LTO is supported include(CheckIPOSupported) check_ipo_supported(RESULT ipo_supported OUTPUT ipo_output LANGUAGES CXX) + + # Get the GCC compiler version, if applicable + if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + execute_process( + COMMAND ${CMAKE_CXX_COMPILER} -dumpversion + OUTPUT_VARIABLE GCC_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + endif() + if(ipo_supported) set_property(TARGET ${target_name} PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE) - message(STATUS "IPO/LTO enabled for target ${target_name}.") + log_option_enabled("IPO/LTO enabled for target ${target_name}.") if(MSVC) target_compile_options(${target_name} PRIVATE /GL) target_link_options(${target_name} PRIVATE /LTCG) elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") - target_compile_options(${target_name} PRIVATE -flto) - target_link_options(${target_name} PRIVATE -flto) + # Check if it's running on Linux, using GCC 14, and in Debug mode + if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND + CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND + GCC_VERSION VERSION_EQUAL "14" AND + CMAKE_BUILD_TYPE STREQUAL "Debug") + log_option_disabled("LTO disabled for GCC 14 in Debug mode on Linux for target ${target_name}.") + # Disable LTO for Debug builds with GCC 14 + target_compile_options(${target_name} PRIVATE -fno-lto) + target_link_options(${target_name} PRIVATE -fno-lto) + else() + target_compile_options(${target_name} PRIVATE -flto=auto) + target_link_options(${target_name} PRIVATE -flto=auto) + endif() endif() else() - message(WARNING "IPO/LTO is not supported for target ${target_name}: ${ipo_output}") + log_option_disabled("IPO/LTO is not supported for target ${target_name}: ${ipo_output}") endif() endif() endfunction() diff --git a/cmake/modules/CanaryLib.cmake b/cmake/modules/CanaryLib.cmake index fbb7aad27c0..3e168d0569b 100644 --- a/cmake/modules/CanaryLib.cmake +++ b/cmake/modules/CanaryLib.cmake @@ -47,7 +47,7 @@ configure_linking(${PROJECT_NAME}_lib) # === UNITY BUILD (compile time reducer) === if(SPEED_UP_BUILD_UNITY) set_target_properties(${PROJECT_NAME}_lib PROPERTIES UNITY_BUILD ON) - log_option_enabled("Build unity for speed up compilation") + log_option_enabled("Build unity for speed up compilation for taget ${PROJECT_NAME}_lib") else() log_option_disabled("Build unity") endif() @@ -84,7 +84,6 @@ target_link_libraries(${PROJECT_NAME}_lib spdlog::spdlog unofficial::argon2::libargon2 unofficial::libmariadb - unofficial::mariadbclient protobuf ) diff --git a/cmake/modules/FindMySQL.cmake b/cmake/modules/FindMySQL.cmake index e96b1e27d53..9e3b4587301 100644 --- a/cmake/modules/FindMySQL.cmake +++ b/cmake/modules/FindMySQL.cmake @@ -58,7 +58,7 @@ IF (WIN32) ADD_DEFINITIONS(-DDBUG_OFF) ENDIF (CMAKE_BUILD_TYPE STREQUAL Debug) - FIND_LIBRARY(MYSQL_LIB NAMES mysqlclient libmariadb + FIND_LIBRARY(MYSQL_LIB NAMES mariadbclient libmariadb PATHS $ENV{MYSQL_DIR}/lib/${libsuffixDist} $ENV{MYSQL_DIR}/libmysql diff --git a/src/lua/functions/core/game/lua_enums.cpp b/src/lua/functions/core/game/lua_enums.cpp index 22b93351911..a0870052f87 100644 --- a/src/lua/functions/core/game/lua_enums.cpp +++ b/src/lua/functions/core/game/lua_enums.cpp @@ -19,6 +19,8 @@ #include "enums/account_type.hpp" #include "enums/account_group_type.hpp" +constexpr const char* soundNamespace = "SOUND_EFFECT_TYPE_"; + #define registerMagicEnum(luaState, enumClassType) \ { \ auto number = magic_enum::enum_integer(enumClassType); \ @@ -107,6 +109,9 @@ void LuaEnums::init(lua_State* L) { initWebhookEnums(L); initBosstiaryEnums(L); initSoundEnums(L); + spelltSoundEnums(L); + monsterSoundEnums(L); + effectsSoundEnums(L); initWheelEnums(L); initAttributeConditionSubIdEnums(L); initConcoctionsEnum(L); @@ -1242,7 +1247,6 @@ void LuaEnums::initBosstiaryEnums(lua_State* L) { // "SOUND_EFFECT_TYPE_" is the sound lua namespace void LuaEnums::initSoundEnums(lua_State* L) { - std::string soundNamespace = "SOUND_EFFECT_TYPE_"; registerEnumNamespace(L, soundNamespace, SoundEffect_t::SILENCE); registerEnumNamespace(L, soundNamespace, SoundEffect_t::HUMAN_CLOSE_ATK_FIST); registerEnumNamespace(L, soundNamespace, SoundEffect_t::MONSTER_CLOSE_ATK_FIST); @@ -1272,6 +1276,9 @@ void LuaEnums::initSoundEnums(lua_State* L) { registerEnumNamespace(L, soundNamespace, SoundEffect_t::MONSTER_MELEE_ATK_MAGIC); registerEnumNamespace(L, soundNamespace, SoundEffect_t::MONSTER_MELEE_ATK_ETHEREAL); registerEnumNamespace(L, soundNamespace, SoundEffect_t::MONSTER_MELEE_ATK_CONSTRUCT); +} + +void LuaEnums::spelltSoundEnums(lua_State* L) { registerEnumNamespace(L, soundNamespace, SoundEffect_t::SPELL_LIGHT_HEALING); registerEnumNamespace(L, soundNamespace, SoundEffect_t::SPELL_INTENSE_HEALING); registerEnumNamespace(L, soundNamespace, SoundEffect_t::SPELL_ULTIMATE_HEALING); @@ -1423,6 +1430,9 @@ void LuaEnums::initSoundEnums(lua_State* L) { registerEnumNamespace(L, soundNamespace, SoundEffect_t::SPELL_EXPOSE_WEAKNESS); registerEnumNamespace(L, soundNamespace, SoundEffect_t::SPELL_SAP_STRENGTH); registerEnumNamespace(L, soundNamespace, SoundEffect_t::SPELL_CANCEL_MAGIC_SHIELD); +} + +void LuaEnums::monsterSoundEnums(lua_State* L) { registerEnumNamespace(L, soundNamespace, SoundEffect_t::MONSTER_SPELL_SINGLE_TARGET_FIRE); registerEnumNamespace(L, soundNamespace, SoundEffect_t::MONSTER_SPELL_SINGLE_TARGET_ENERGY); registerEnumNamespace(L, soundNamespace, SoundEffect_t::MONSTER_SPELL_SINGLE_TARGET_EARTH); @@ -1487,6 +1497,9 @@ void LuaEnums::initSoundEnums(lua_State* L) { registerEnumNamespace(L, soundNamespace, SoundEffect_t::MONSTER_SPELL_HIGHRISK_TELEPORT); registerEnumNamespace(L, soundNamespace, SoundEffect_t::MONSTER_SPELL_MINION); registerEnumNamespace(L, soundNamespace, SoundEffect_t::MONSTER_SPELL_AGONY); +} + +void LuaEnums::effectsSoundEnums(lua_State* L) { registerEnumNamespace(L, soundNamespace, SoundEffect_t::AMPHIBIC_BARK); registerEnumNamespace(L, soundNamespace, SoundEffect_t::AQUATIC_BEAST_BARK); registerEnumNamespace(L, soundNamespace, SoundEffect_t::AQUATIC_CRITTER_BARK); diff --git a/src/lua/functions/core/game/lua_enums.hpp b/src/lua/functions/core/game/lua_enums.hpp index 8beabbbacee..d14ca0ceb54 100644 --- a/src/lua/functions/core/game/lua_enums.hpp +++ b/src/lua/functions/core/game/lua_enums.hpp @@ -66,5 +66,8 @@ class LuaEnums final : LuaScriptInterface { static void initWebhookEnums(lua_State* L); static void initBosstiaryEnums(lua_State* L); static void initSoundEnums(lua_State* L); + static void spelltSoundEnums(lua_State* L); + static void monsterSoundEnums(lua_State* L); + static void effectsSoundEnums(lua_State* L); static void initWheelEnums(lua_State* L); }; diff --git a/src/main.cpp b/src/main.cpp index 8534bbb6911..a2a77bd636c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -9,7 +9,26 @@ #include "canary_server.hpp" #include "lib/di/container.hpp" +// Define um conceito para garantir que a função só aceite contêineres de números +template +concept NumberContainer = requires(T a) { + typename T::value_type; + requires std::integral || std::floating_point; +}; + +// Função que calcula a média de um contêiner de números +auto calculateAverage(const NumberContainer auto &container) { + // Utiliza ranges e std::views para processar o contêiner + return std::accumulate(container.begin(), container.end(), 0.0) / std::ranges::distance(container); +} int main() { + std::vector numbers = { 1, 2, 3, 4, 5 }; + + // Calcula a média usando a função com suporte a C++23 + double average = calculateAverage(numbers); + + std::cout << "Average: " << average << std::endl; + return inject().run(); } diff --git a/src/pch.hpp b/src/pch.hpp index ea3c9cd2e73..b89830b9fdb 100644 --- a/src/pch.hpp +++ b/src/pch.hpp @@ -83,13 +83,14 @@ #include #include #include +#include // FMT Custom Formatter for Enums template -struct fmt::formatter, char>> : formatter> { +struct fmt::formatter, char>> : fmt::formatter> { template - auto format(E e, FormatContext &ctx) { - return formatter>::format( + auto format(E e, FormatContext &ctx) const { + return fmt::formatter>::format( static_cast>(e), ctx ); } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 3838528bd23..d35631ff2fa 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -11,7 +11,7 @@ function(setup_test TARGET_NAME DIR) if(SPEED_UP_BUILD_UNITY AND (CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo" OR CMAKE_BUILD_TYPE STREQUAL "Release")) set_target_properties(${TARGET_NAME} PROPERTIES UNITY_BUILD ON) - log_option_enabled("Build unity for speed up compilation") + log_option_enabled("Build unity for speed up compilation for target ${TARGET_NAME}") else() log_option_disabled("Build unity") endif() diff --git a/vcpkg.json b/vcpkg.json index eed7e776ee0..1549bf6a851 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -9,6 +9,7 @@ "bext-ut", "curl", "eventpp", + "libmariadb", "luajit", "magic-enum", "mio", @@ -23,12 +24,6 @@ "default-features": true, "features": ["otlp-http", "prometheus"] }, - { - "name": "libmariadb", - "features": [ - "mariadbclient" - ] - }, { "name": "gmp", "platform": "linux" @@ -38,5 +33,5 @@ "platform": "windows" } ], - "builtin-baseline": "095ee06e7f60dceef7d713e3f8b1c2eb10d650d7" + "builtin-baseline": "9558037875497b9db8cf38fcd7db68ec661bffe7" } From 25912138314ceaaa88c50132857cdc507ae15b8c Mon Sep 17 00:00:00 2001 From: Felipe Paluco <87909998+FelipePaluco@users.noreply.github.com> Date: Mon, 14 Oct 2024 10:28:49 -0300 Subject: [PATCH 07/13] fix: wrong positions on scourge of oblivion boss lever (#2970) Not all users are being teleported to the Scourge of Oblivion Boss Room. The current positions is +1 SQM to the right --- .../actions/bosses_levers/the_scourge_of_oblivion.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/data-otservbr-global/scripts/actions/bosses_levers/the_scourge_of_oblivion.lua b/data-otservbr-global/scripts/actions/bosses_levers/the_scourge_of_oblivion.lua index 7824ea47878..f7373fbe49b 100644 --- a/data-otservbr-global/scripts/actions/bosses_levers/the_scourge_of_oblivion.lua +++ b/data-otservbr-global/scripts/actions/bosses_levers/the_scourge_of_oblivion.lua @@ -10,11 +10,11 @@ local config = { { pos = Position(32676, 32745, 11), teleport = Position(32726, 32733, 11), effect = CONST_ME_TELEPORT }, { pos = Position(32676, 32741, 11), teleport = Position(32726, 32733, 11), effect = CONST_ME_TELEPORT }, { pos = Position(32676, 32742, 11), teleport = Position(32726, 32733, 11), effect = CONST_ME_TELEPORT }, - { pos = Position(32678, 32741, 11), teleport = Position(32726, 32733, 11), effect = CONST_ME_TELEPORT }, - { pos = Position(32678, 32742, 11), teleport = Position(32726, 32733, 11), effect = CONST_ME_TELEPORT }, - { pos = Position(32678, 32743, 11), teleport = Position(32726, 32733, 11), effect = CONST_ME_TELEPORT }, - { pos = Position(32678, 32744, 11), teleport = Position(32726, 32733, 11), effect = CONST_ME_TELEPORT }, - { pos = Position(32678, 32745, 11), teleport = Position(32726, 32733, 11), effect = CONST_ME_TELEPORT }, + { pos = Position(32677, 32741, 11), teleport = Position(32726, 32733, 11), effect = CONST_ME_TELEPORT }, + { pos = Position(32677, 32742, 11), teleport = Position(32726, 32733, 11), effect = CONST_ME_TELEPORT }, + { pos = Position(32677, 32743, 11), teleport = Position(32726, 32733, 11), effect = CONST_ME_TELEPORT }, + { pos = Position(32677, 32744, 11), teleport = Position(32726, 32733, 11), effect = CONST_ME_TELEPORT }, + { pos = Position(32677, 32745, 11), teleport = Position(32726, 32733, 11), effect = CONST_ME_TELEPORT }, }, specPos = { from = Position(32712, 32723, 11), From 26820658cfe502818225ce69189d858bb172928a Mon Sep 17 00:00:00 2001 From: Felipe Paluco <87909998+FelipePaluco@users.noreply.github.com> Date: Mon, 14 Oct 2024 10:29:26 -0300 Subject: [PATCH 08/13] fix: npc zoltan giving free ferumbras hat (#2945) Change the NPC Zoltan to prevent exploits and having Ferumbras Hat for free. --- data-otservbr-global/npc/zoltan.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/data-otservbr-global/npc/zoltan.lua b/data-otservbr-global/npc/zoltan.lua index 9d783dd0441..c9c23cfe803 100644 --- a/data-otservbr-global/npc/zoltan.lua +++ b/data-otservbr-global/npc/zoltan.lua @@ -76,13 +76,13 @@ local function creatureSayCallback(npc, creature, type, message) if player:getSex() == PLAYERSEX_MALE and not player:hasOutfit(130, 2) then if MsgContains(message, "yes") then if player:getItemCount(5903) == 1 then - npcHandler:say("Sorry you don't have the Ferumbras' hat.", npc, creature) - else npcHandler:say("I bow to you, player, and hereby grant you the right to wear Ferumbras' hat as accessory. Congratulations!", npc, creature) player:removeItem(5903, 1) player:addOutfitAddon(130, 2) -- male mage addon - player:addOutfitAddon(133, 2) -- male summoner addon + player:addOutfitAddon(141, 2) -- female summoner addon player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) + else + npcHandler:say("Sorry you don't have the Ferumbras' hat.", npc, creature) end else npcHandler:say("This task is only available for male players who don't already have the addon.", npc, creature) From a60f27f89a76b49d0aa1b7476cbeb96413053706 Mon Sep 17 00:00:00 2001 From: pudimtibia Date: Mon, 14 Oct 2024 10:30:05 -0300 Subject: [PATCH 09/13] fix: remove poff effect when killing monsters (#2942) Remove POFF when killing a creature, I'm not sure why it was included but it differs from global tibia. --- src/game/game.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/game/game.cpp b/src/game/game.cpp index 5692e4d9c3d..258b0f117e1 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -1163,7 +1163,6 @@ bool Game::removeCreature(std::shared_ptr creature, bool isLogout /* = size_t i = 0; for (const auto &spectator : playersSpectators) { if (const auto &player = spectator->getPlayer()) { - player->sendMagicEffect(tilePosition, CONST_ME_POFF); player->sendRemoveTileThing(tilePosition, oldStackPosVector[i++]); } } From 90eff7979934da0696494caf5e08336902401501 Mon Sep 17 00:00:00 2001 From: Karin Date: Mon, 14 Oct 2024 10:36:51 -0300 Subject: [PATCH 10/13] fix: prevent sell items with duration to the npc (#2898) This fix prevents players from selling items with used duration in NPC trades. --- data-otservbr-global/npc/perod.lua | 2 +- src/creatures/npcs/npc.cpp | 8 ++++++++ src/creatures/players/player.cpp | 4 ++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/data-otservbr-global/npc/perod.lua b/data-otservbr-global/npc/perod.lua index b0bc5e7a57d..7d3f32d6ad3 100644 --- a/data-otservbr-global/npc/perod.lua +++ b/data-otservbr-global/npc/perod.lua @@ -143,7 +143,7 @@ npcConfig.shop = { { itemName = "shiver arrow", clientId = 762, buy = 5 }, { itemName = "shovel", clientId = 3457, buy = 50, sell = 8 }, { itemName = "sniper arrow", clientId = 7364, buy = 5 }, - { itemName = "spear", clientId = 3277, buy = 10, sell = 10 }, + { itemName = "spear", clientId = 3277, buy = 9, sell = 3 }, { itemName = "spectral bolt", clientId = 35902, buy = 70 }, { itemName = "tarsal arrow", clientId = 14251, buy = 6 }, { itemName = "throwing star", clientId = 3287, buy = 42 }, diff --git a/src/creatures/npcs/npc.cpp b/src/creatures/npcs/npc.cpp index 519afaf92f2..fbf08461c00 100644 --- a/src/creatures/npcs/npc.cpp +++ b/src/creatures/npcs/npc.cpp @@ -396,6 +396,10 @@ void Npc::onPlayerSellItem(std::shared_ptr player, uint16_t itemId, uint continue; } + if (!item->hasMarketAttributes()) { + continue; + } + auto removeCount = std::min(toRemove, item->getItemCount()); if (g_game().internalRemoveItem(item, removeCount) != RETURNVALUE_NOERROR) { @@ -410,6 +414,10 @@ void Npc::onPlayerSellItem(std::shared_ptr player, uint16_t itemId, uint } auto totalRemoved = amount - toRemove; + if (totalRemoved == 0) { + return; + } + auto totalCost = static_cast(sellPrice * totalRemoved); g_logger().debug("[Npc::onPlayerSellItem] - Removing items from player {} amount {} of items with id {} on shop for npc {}", player->getName(), toRemove, itemId, getName()); if (totalRemoved > 0 && totalCost > 0) { diff --git a/src/creatures/players/player.cpp b/src/creatures/players/player.cpp index ee96b5bba24..4470d7431ad 100644 --- a/src/creatures/players/player.cpp +++ b/src/creatures/players/player.cpp @@ -4118,6 +4118,10 @@ std::map &Player::getAllItemTypeCount(std::map &Player::getAllSaleItemIdAndCount(std::map &countMap) const { for (const auto &item : getAllInventoryItems(false, true)) { + if (!item->hasMarketAttributes()) { + continue; + } + if (const auto &container = item->getContainer()) { if (container->size() > 0) { continue; From 3d483fc40b48d046b5c9f3b1fc735d7867010f33 Mon Sep 17 00:00:00 2001 From: "Leilani A." <168607226+kaleohanopahala@users.noreply.github.com> Date: Mon, 14 Oct 2024 10:38:27 -0300 Subject: [PATCH 11/13] perf: optimize spawn cleanup removing redundant iteration (#2913) This improves efficiency by avoiding an intermediate list for removal, saving time and memory. The map is traversed only once, with iterators updated after each removal, making the process more efficient. Additionally, it eliminates redundant lookups by directly modifying the map during iteration. --- .../monsters/spawns/spawn_monster.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/creatures/monsters/spawns/spawn_monster.cpp b/src/creatures/monsters/spawns/spawn_monster.cpp index 13321bd3914..922f0210000 100644 --- a/src/creatures/monsters/spawns/spawn_monster.cpp +++ b/src/creatures/monsters/spawns/spawn_monster.cpp @@ -282,16 +282,17 @@ void SpawnMonster::scheduleSpawn(uint32_t spawnMonsterId, spawnBlock_t &sb, cons } void SpawnMonster::cleanup() { - std::vector removeList; - for (const auto &[spawnMonsterId, monster] : spawnedMonsterMap) { - if (monster == nullptr || monster->isRemoved()) { - removeList.push_back(spawnMonsterId); + std::erase_if(spawnedMonsterMap, [this](const auto &entry) { + const auto &monster = entry.second; + if (!monster || monster->isRemoved()) { + auto spawnIt = spawnMonsterMap.find(entry.first); + if (spawnIt != spawnMonsterMap.end()) { + spawnIt->second.lastSpawn = OTSYS_TIME(); + } + return true; } - } - for (const auto &spawnMonsterId : removeList) { - spawnMonsterMap[spawnMonsterId].lastSpawn = OTSYS_TIME(); - spawnedMonsterMap.erase(spawnMonsterId); - } + return false; + }); } bool SpawnMonster::addMonster(const std::string &name, const Position &pos, Direction dir, uint32_t scheduleInterval, uint32_t weight /*= 1*/) { From 72917d4cb35fd3a1bc571950af3a1af853343545 Mon Sep 17 00:00:00 2001 From: LeoTK <41605307+LeoTKBR@users.noreply.github.com> Date: Mon, 14 Oct 2024 10:40:56 -0300 Subject: [PATCH 12/13] fix: onLook nil value (#2856) Showing nil on look monsters and npcs. --- data/scripts/eventcallbacks/player/on_look.lua | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/data/scripts/eventcallbacks/player/on_look.lua b/data/scripts/eventcallbacks/player/on_look.lua index 6b4be92553a..851cd9b707f 100644 --- a/data/scripts/eventcallbacks/player/on_look.lua +++ b/data/scripts/eventcallbacks/player/on_look.lua @@ -60,12 +60,16 @@ function callback.playerOnLook(player, thing, position, distance) description = string.format("%s\nDecays to: %d", description, decayId) end elseif thing:isCreature() then - local str, pId = "%s\n%s\nHealth: %d / %d" + local str, id = "%s\n%s\nHealth: %d / %d" if thing:isPlayer() and thing:getMaxMana() > 0 then - pId = string.format("Player ID: %i", thing:getGuid()) + id = string.format("Player ID: %i", thing:getGuid()) str = string.format("%s, Mana: %d / %d", str, thing:getMana(), thing:getMaxMana()) + elseif thing:isMonster() then + id = string.format("Monster ID: %i", thing:getId()) + elseif thing:isNpc() then + id = string.format("NPC ID: %i", thing:getId()) end - description = string.format(str, description, pId, thing:getHealth(), thing:getMaxHealth()) + description = string.format(str, description, id, thing:getHealth(), thing:getMaxHealth()) end description = string.format("%s\nPosition: (%d, %d, %d)", description, position.x, position.y, position.z) From 92c07cf160d4871848578e1eedd9d47db376a6bd Mon Sep 17 00:00:00 2001 From: Karin Date: Mon, 14 Oct 2024 10:41:44 -0300 Subject: [PATCH 13/13] fix: code error when adding text attribute (#2975) Fix code error when adding text attribute --- .../scripts/actions/system/quest_reward_common.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/data-otservbr-global/scripts/actions/system/quest_reward_common.lua b/data-otservbr-global/scripts/actions/system/quest_reward_common.lua index a991cdbbcf1..f6ca1c6271a 100644 --- a/data-otservbr-global/scripts/actions/system/quest_reward_common.lua +++ b/data-otservbr-global/scripts/actions/system/quest_reward_common.lua @@ -111,10 +111,10 @@ local function playerAddContainerItem(params, item) keyItem:setActionId(params.action) end else - reward:addItem(params.itemid, params.count) + local rewardItem = reward:addItem(params.itemid, params.count) local attribute = AttributeTable[item.uid] - if attribute then - addItem:setAttribute(ITEM_ATTRIBUTE_TEXT, attribute.text) + if attribute and rewardItem then + rewardItem:setAttribute(ITEM_ATTRIBUTE_TEXT, attribute.text) end end