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/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..e772f78b3a1 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,58 @@ 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) + # 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) + 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") + # 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() + log_option_disabled("IPO/LTO is not supported for target ${target_name}: ${ipo_output}") + endif() + endif() +endfunction() # ***************************************************************************** # Compiler Options @@ -147,39 +185,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..3e168d0569b 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") + log_option_enabled("Build unity for speed up compilation for taget ${PROJECT_NAME}_lib") +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 @@ -102,13 +84,11 @@ target_link_libraries(${PROJECT_NAME}_lib spdlog::spdlog unofficial::argon2::libargon2 unofficial::libmariadb - unofficial::mariadbclient protobuf ) if(FEATURE_METRICS) add_definitions(-DFEATURE_METRICS) - target_link_libraries(${PROJECT_NAME}_lib PUBLIC opentelemetry-cpp::common @@ -134,11 +114,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 +129,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/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/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) 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 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/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) { 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/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; } } 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 5cf5c5d80ee..d35631ff2fa 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 for target ${TARGET_NAME}") + 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( 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" }