diff --git a/.github/workflows/core_windows_build.yml b/.github/workflows/core_windows_build.yml index 222fc45f6..d28d1be15 100644 --- a/.github/workflows/core_windows_build.yml +++ b/.github/workflows/core_windows_build.yml @@ -87,9 +87,6 @@ jobs: echo "OPENSSL_INCLUDE_DIR=$root/include" >> "$GITHUB_ENV" echo "OPENSSL_CRYPTO_LIBRARY=$root/lib/VC/libcrypto64MT.lib" >> "$GITHUB_ENV" echo "OPENSSL_SSL_LIBRARY=$root/lib/VC/libssl64MT.lib" >> "$GITHUB_ENV" - # SlProWeb installs provider DLLs beside openssl.exe, while its - # compiled MODULESDIR still names the default installation path. - echo "OPENSSL_MODULES=$root/bin" >> "$GITHUB_ENV" echo "$root/bin" >> "$GITHUB_PATH" else echo "::error::OpenSSL developer libraries not found" diff --git a/.gitignore b/.gitignore index 71177226c..de474249a 100644 --- a/.gitignore +++ b/.gitignore @@ -103,5 +103,3 @@ docs/superpowers/ .ccache/ .sccache/ -# Generated by GenRevision; 02 writes it to the build tree instead. -src/shared/revision_data.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 1ea7e48c2..757285f0a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,7 +23,8 @@ cmake_minimum_required(VERSION 3.18 FATAL_ERROR) # ============================================================================= # Project setup # ============================================================================= -project(MaNGOS VERSION 0.22.0 LANGUAGES C CXX) +# The version is not given here: cmake/Revision.cmake is its only home. +project(MaNGOS LANGUAGES C CXX) # Build artefacts never land in the source tree. This is a test, not hygiene: # sources here still carry relative includes like "../../dep/foo.h", and an @@ -233,9 +234,7 @@ if(NOT WIN32 AND SCRIPT_LIB_ELUNA) find_package(Readline REQUIRED) endif() -include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/GenRevision.cmake) -include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/EnsureVersion.cmake) -include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/MangosParams.cmake) +include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/Revision.cmake) include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/SetDefinitions.cmake) if(PCH) diff --git a/cmake/BuildRevision.h.in b/cmake/BuildRevision.h.in new file mode 100644 index 000000000..9a28e430a --- /dev/null +++ b/cmake/BuildRevision.h.in @@ -0,0 +1,64 @@ +/** + * SPDX-License-Identifier: GPL-3.0-or-later + * + * MaNGOS is a full featured server for World of Warcraft, supporting + * the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8 + * + * Copyright (C) 2005-2026 MaNGOS + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * World of Warcraft, and all World of Warcraft or Warcraft art, images, + * and lore are copyrighted by Blizzard Entertainment, Inc. + */ + +// Template for BuildRevision.h, written into the BUILD tree by +// cmake/Revision.cmake, which sets every value. Included by one file only: +// src/shared/Common/Revision.cpp. Everything else uses Revision.h. + +#ifndef MANGOS_BUILD_REVISION_H +#define MANGOS_BUILD_REVISION_H + +#define REVISION_STR R"(@MANGOS_REVISION@)" +#define REVISION_HASH R"(@MANGOS_REVISION_hash@)" +#define REVISION_DATE R"(@MANGOS_REVISION_date@)" +#define REVISION_ELUNA_STR R"(@MANGOS_ELUNA_REVISION@)" +#define REVISION_SD3_STR R"(@MANGOS_SD3_REVISION@)" + +#define REVISION_PACKAGE_NAME "@MANGOS_PKG@" +#define REVISION_PROJECT_NR "@MANGOS_REVISION_NR@" +#define REVISION_BUILD_HOST R"(@MANGOS_BUILD_HOST@)" + +#define REVISION_WORLD_DB_VERSION "@MANGOS_WORLD_DB_VERSION@" +#define REVISION_WORLD_DB_STRUCTURE "@MANGOS_WORLD_DB_STRUCTURE@" +#define REVISION_WORLD_DB_CONTENT "@MANGOS_WORLD_DB_CONTENT@" +#define REVISION_WORLD_DB_UPDATE "@MANGOS_WORLD_DB_UPDATE@" + +#define REVISION_REALMD_DB_VERSION "@MANGOS_REALMD_DB_VERSION@" +#define REVISION_REALMD_DB_STRUCTURE "@MANGOS_REALMD_DB_STRUCTURE@" +#define REVISION_REALMD_DB_CONTENT "@MANGOS_REALMD_DB_CONTENT@" +#define REVISION_REALMD_DB_UPDATE "@MANGOS_REALMD_DB_UPDATE@" + +#define REVISION_CHAR_DB_VERSION "@MANGOS_CHAR_DB_VERSION@" +#define REVISION_CHAR_DB_STRUCTURE "@MANGOS_CHAR_DB_STRUCTURE@" +#define REVISION_CHAR_DB_CONTENT "@MANGOS_CHAR_DB_CONTENT@" +#define REVISION_CHAR_DB_UPDATE "@MANGOS_CHAR_DB_UPDATE@" + +#define REVISION_CONFIG_DIR R"(@CONF_INSTALL_DIR@/)" +#define REVISION_MANGOSD_CONF_VERSION @MANGOS_WORLD_VER@ +#define REVISION_REALMD_CONF_VERSION @MANGOS_REALM_VER@ +#define REVISION_AHBOT_CONF_VERSION @MANGOS_AHBOT_VER@ +#define REVISION_PLAYERBOT_CONF_VERSION @MANGOS_PLAYERBOT_VER@ + +#endif diff --git a/cmake/EnsureVersion.cmake b/cmake/EnsureVersion.cmake deleted file mode 100644 index 9e0cc679c..000000000 --- a/cmake/EnsureVersion.cmake +++ /dev/null @@ -1,74 +0,0 @@ -# SPDX-License-Identifier: GPL-3.0-or-later -# -# MaNGOS is a full featured server for World of Warcraft, supporting -# the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8 -# -# Copyright (C) 2005-2026 MaNGOS -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -MACRO(NORMALIZE_VERSION _requested_version _normalized_version) - STRING(REGEX MATCH "[^0-9]*[0-9]+\\.[0-9]+\\.[0-9]+.*" _threePartMatch "${_requested_version}") - if(_threePartMatch) - # parse the parts of the version string - STRING(REGEX REPLACE "[^0-9]*([0-9]+)\\.[0-9]+\\.[0-9]+.*" "\\1" _major_vers "${_requested_version}") - STRING(REGEX REPLACE "[^0-9]*[0-9]+\\.([0-9]+)\\.[0-9]+.*" "\\1" _minor_vers "${_requested_version}") - STRING(REGEX REPLACE "[^0-9]*[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" _patch_vers "${_requested_version}") - else(_threePartMatch) - STRING(REGEX REPLACE "([0-9]+)\\.[0-9]+" "\\1" _major_vers "${_requested_version}") - STRING(REGEX REPLACE "[0-9]+\\.([0-9]+)" "\\1" _minor_vers "${_requested_version}") - set(_patch_vers "0") - endif(_threePartMatch) - - # compute an overall version number which can be compared at once - MATH(EXPR ${_normalized_version} "${_major_vers}*10000 + ${_minor_vers}*100 + ${_patch_vers}") -ENDMACRO(NORMALIZE_VERSION) - -MACRO(CHECK_RANGE_INCLUSIVE_LOWER _lower_limit _value _upper_limit _ok) - if(${_value} LESS ${_lower_limit}) - set(${_ok} FALSE) - elseif(${_value} EQUAL ${_lower_limit}) - set(${_ok} TRUE) - elseif(${_value} EQUAL ${_upper_limit}) - set(${_ok} FALSE) - elseif(${_value} GREATER ${_upper_limit}) - set(${_ok} FALSE) - else(${_value} LESS ${_lower_limit}) - set(${_ok} TRUE) - endif(${_value} LESS ${_lower_limit}) -ENDMACRO(CHECK_RANGE_INCLUSIVE_LOWER) - -MACRO(ENSURE_VERSION requested_version found_version var_too_old) - NORMALIZE_VERSION(${requested_version} req_vers_num) - NORMALIZE_VERSION(${found_version} found_vers_num) - - if(found_vers_num LESS req_vers_num) - set(${var_too_old} FALSE) - else(found_vers_num LESS req_vers_num) - set(${var_too_old} TRUE) - endif(found_vers_num LESS req_vers_num) - -ENDMACRO(ENSURE_VERSION) - -MACRO(ENSURE_VERSION2 requested_version2 found_version2 var_too_old2) - ENSURE_VERSION(${requested_version2} ${found_version2} ${var_too_old2}) -ENDMACRO(ENSURE_VERSION2) - -MACRO(ENSURE_VERSION_RANGE min_version found_version max_version var_ok) - NORMALIZE_VERSION(${min_version} req_vers_num) - NORMALIZE_VERSION(${found_version} found_vers_num) - NORMALIZE_VERSION(${max_version} max_vers_num) - - CHECK_RANGE_INCLUSIVE_LOWER(${req_vers_num} ${found_vers_num} ${max_vers_num} ${var_ok}) -ENDMACRO(ENSURE_VERSION_RANGE) diff --git a/cmake/GenRevision.cmake b/cmake/GenRevision.cmake deleted file mode 100644 index c2313c04b..000000000 --- a/cmake/GenRevision.cmake +++ /dev/null @@ -1,231 +0,0 @@ - -if(NOT BUILDDIR) - # Workaround for funny MSVC behaviour - this segment is only used when using cmake gui - set(BUILDDIR ${CMAKE_BINARY_DIR}) -endif() - -if(WITHOUT_GIT) - set(rev_date "1970-01-01 00:00:00 +0000" ) - set(rev_hash "unknown" ) - set(rev_branch "Archived" ) - - if(SCRIPT_LIB_ELUNA) - set(dep_eluna_rev_date "1970-01-01 00:00:00 +0000" ) - set(dep_eluna_rev_hash "unknown" ) - set(dep_eluna_rev_branch "Archived" ) - endif() - if(SCRIPT_LIB_SD3) - set(dep_sd3_rev_date "1970-01-01 00:00:00 +0000" ) - set(dep_sd3_rev_hash "unknown" ) - set(dep_sd3_rev_branch "Archived" ) - endif() - - # No valid git commit date, use compiled date - string(TIMESTAMP rev_date_fallback "%Y-%m-%d %H:%M:%S" UTC) - - if(SCRIPT_LIB_ELUNA) - string(TIMESTAMP dep_eluna_rev_date_fallback "%Y-%m-%d %H:%M:%S" UTC) - endif() - if(SCRIPT_LIB_SD3) - string(TIMESTAMP dep_sd3_rev_date_fallback "%Y-%m-%d %H:%M:%S" UTC) - endif() -else() - if(GIT_EXECUTABLE) - # Create a revision-string that we can use - execute_process( - COMMAND "${GIT_EXECUTABLE}" describe --long --match init --dirty=+ --abbrev=12 --always - WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" - OUTPUT_VARIABLE rev_info - OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_QUIET - ) - # And grab the commits timestamp - execute_process( - COMMAND "${GIT_EXECUTABLE}" show -s --format=%ci - WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" - OUTPUT_VARIABLE rev_date - OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_QUIET - ) - # Also retrieve branch name - execute_process( - COMMAND "${GIT_EXECUTABLE}" rev-parse --abbrev-ref HEAD - WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" - OUTPUT_VARIABLE rev_branch - OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_QUIET - ) - - if(SCRIPT_LIB_ELUNA) - # Create a revision-string that we can use - execute_process( - COMMAND "${GIT_EXECUTABLE}" describe --long --match init --dirty=+ --abbrev=12 --always - WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/src/modules/Eluna" - OUTPUT_VARIABLE dep_eluna_rev_info - OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_QUIET - ) - # And grab the commits timestamp - execute_process( - COMMAND "${GIT_EXECUTABLE}" show -s --format=%ci - WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/src/modules/Eluna" - OUTPUT_VARIABLE dep_eluna_rev_date - OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_QUIET - ) - # Also retrieve branch name - execute_process( - COMMAND "${GIT_EXECUTABLE}" rev-parse --abbrev-ref HEAD - WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/src/modules/Eluna" - OUTPUT_VARIABLE dep_eluna_rev_branch - OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_QUIET - ) - endif() - if(SCRIPT_LIB_SD3) - # Create a revision-string that we can use - execute_process( - COMMAND "${GIT_EXECUTABLE}" describe --long --match init --dirty=+ --abbrev=12 --always - WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/src/modules/SD3" - OUTPUT_VARIABLE dep_sd3_rev_info - OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_QUIET - ) - # And grab the commits timestamp - execute_process( - COMMAND "${GIT_EXECUTABLE}" show -s --format=%ci - WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/src/modules/SD3" - OUTPUT_VARIABLE dep_sd3_rev_date - OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_QUIET - ) - # Also retrieve branch name - execute_process( - COMMAND "${GIT_EXECUTABLE}" rev-parse --abbrev-ref HEAD - WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/src/modules/SD3" - OUTPUT_VARIABLE dep_sd3_rev_branch - OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_QUIET - ) - endif() - endif() - - # Last minute check - ensure that we have a proper revision - # If everything above fails (means the user has erased the git revision control directory or removed the origin/HEAD tag) - if(NOT rev_info) - # No valid ways available to find/set the revision/hash, so let's force some defaults - message(STATUS " - Could not find a proper repository signature (hash) - you may need to pull tags with git fetch -t - Continuing anyway - note that the versionstring will be set to \"unknown 1970-01-01 00:00:00 (Archived)\"") - set(rev_date "1970-01-01 00:00:00 +0000" ) - set(rev_hash "unknown" ) - set(rev_branch "Archived" ) - - if(SCRIPT_LIB_ELUNA) - set(dep_eluna_rev_date "1970-01-01 00:00:00 +0000" ) - set(dep_eluna_rev_hash "unknown" ) - set(dep_eluna_rev_branch "Archived" ) - endif() - if(SCRIPT_LIB_SD3) - set(dep_sd3_rev_date "1970-01-01 00:00:00 +0000" ) - set(dep_sd3_rev_hash "unknown" ) - set(dep_sd3_rev_branch "Archived" ) - endif() - - # No valid git commit date, use compiled date - string(TIMESTAMP rev_date_fallback "%Y-%m-%d %H:%M:%S" UTC) - if(SCRIPT_LIB_ELUNA) - string(TIMESTAMP dep_eluna_rev_date_fallback "%Y-%m-%d %H:%M:%S" UTC) - endif() - if(SCRIPT_LIB_SD3) - string(TIMESTAMP dep_sd3_rev_date_fallback "%Y-%m-%d %H:%M:%S" UTC) - endif() - else() - # We have valid date from git commit, use it - set(rev_date_fallback ${rev_date} ) - if(SCRIPT_LIB_ELUNA) - set(dep_eluna_rev_date_fallback ${dep_eluna_rev_date} ) - endif() - if(SCRIPT_LIB_SD3) - set(dep_sd3_rev_date_fallback ${dep_sd3_rev_date} ) - endif() - - # Extract information required to build a proper versionstring - string(REGEX REPLACE init-|[0-9]+-g "" rev_hash ${rev_info} ) - if(SCRIPT_LIB_ELUNA) - string(REGEX REPLACE init-|[0-9]+-g "" dep_eluna_rev_hash ${dep_eluna_rev_info} ) - endif() - if(SCRIPT_LIB_SD3) - string(REGEX REPLACE init-|[0-9]+-g "" dep_sd3_rev_hash ${dep_sd3_rev_info} ) - endif() - endif() -endif() - -# revision_data.h.in unconditionally references @dep_eluna_rev_hash@ / -# @dep_sd3_rev_hash@ (and _date@/_branch@), but the blocks above only ever -# set those variables when SCRIPT_LIB_ELUNA/SCRIPT_LIB_SD3 is enabled. When a -# module is skipped, give its revision variables clear placeholder values -# instead of leaving them undefined: configure_file() silently substitutes -# an unset @VAR@ with an empty string, which produced a garbled banner like -# "Eluna submodule revision: ( branch)" instead of saying it wasn't built. -if(NOT SCRIPT_LIB_ELUNA) - set(dep_eluna_rev_hash "not built") - set(dep_eluna_rev_date "n/a") - set(dep_eluna_rev_branch "disabled") -endif() -if(NOT SCRIPT_LIB_SD3) - set(dep_sd3_rev_hash "not built") - set(dep_sd3_rev_date "n/a") - set(dep_sd3_rev_branch "disabled") -endif() - -# For package / copyright information we always need proper date -string(REGEX MATCH "([0-9]+)-([0-9]+)-([0-9]+)" rev_date_fallback_match ${rev_date_fallback}) -set(rev_year ${CMAKE_MATCH_1}) -set(rev_month ${CMAKE_MATCH_2}) -set(rev_day ${CMAKE_MATCH_3}) - -# message("rev_hash_cached : ${rev_hash_cached}" ) -# message("rev_hash : ${rev_hash}" ) -# message("rev_branch_cached : ${rev_branch_cached}" ) -# message("rev_branch : ${rev_branch}" ) -# message("dep_eluna_rev_hash_cached : ${dep_eluna_rev_hash_cached}" ) -# message("dep_eluna_rev_hash : ${dep_eluna_rev_hash}" ) -# message("dep_eluna_rev_branch_cached: ${dep_eluna_rev_branch_cached}" ) -# message("dep_eluna_rev_branch : ${dep_eluna_rev_branch}" ) -# message("dep_sd3_rev_hash_cached : ${dep_sd3_rev_hash_cached}" ) -# message("dep_sd3_rev_hash : ${dep_sd3_rev_hash}" ) -# message("dep_sd3_rev_branch_cached : ${dep_sd3_rev_branch_cached}" ) -# message("dep_sd3_rev_branch : ${dep_sd3_rev_branch}" ) -# message("CMAKE_CURRENT_BINARY_DIR : ${CMAKE_CURRENT_BINARY_DIR}" ) -# if(EXISTS "${CMAKE_CURRENT_BINARY_DIR}/src/shared/revision_data.h") -# message("revision_data.h exists.") -# else() -# message("revision_data.h does not exist.") -# endif() -# Create the actual revision_data.h file from the above params -if( - NOT "${rev_hash_cached}" MATCHES "${rev_hash}" - OR NOT "${rev_branch_cached}" MATCHES "${rev_branch}" - OR NOT "${dep_eluna_rev_hash_cached}" MATCHES "${dep_eluna_rev_hash}" - OR NOT "${dep_eluna_rev_branch_cached}" MATCHES "${dep_eluna_rev_branch}" - OR NOT "${dep_sd3_rev_hash_cached}" MATCHES "${dep_sd3_rev_hash}" - OR NOT "${dep_sd3_rev_branch_cached}" MATCHES "${dep_sd3_rev_branch}" - OR NOT EXISTS "${BUILDDIR}/src/shared/revision_data.h" -) - configure_file( - "${CMAKE_SOURCE_DIR}/src/shared/revision_data.h.in" - "${BUILDDIR}/src/shared/revision_data.h" - @ONLY - ) - set(rev_hash_cached "${rev_hash}" CACHE INTERNAL "Cached commit-hash" ) - set(rev_branch_cached "${rev_branch}" CACHE INTERNAL "Cached branch name" ) - # Cached unconditionally (not just when the module is enabled), so the - # "not built"/"disabled" placeholders set above are remembered too - - # otherwise every reconfigure with the module off would see a permanent - # cache mismatch and needlessly regenerate revision_data.h every time. - set(dep_eluna_rev_hash_cached "${dep_eluna_rev_hash}" CACHE INTERNAL "Cached Eluna commit-hash" ) - set(dep_eluna_rev_branch_cached "${dep_eluna_rev_branch}" CACHE INTERNAL "Cached Eluna branch name" ) - set(dep_sd3_rev_hash_cached "${dep_sd3_rev_hash}" CACHE INTERNAL "Cached SD3 commit-hash" ) - set(dep_sd3_rev_branch_cached "${dep_sd3_rev_branch}" CACHE INTERNAL "Cached SD3 branch name" ) -endif() diff --git a/cmake/MangosParams.cmake b/cmake/MangosParams.cmake deleted file mode 100644 index 8eb3566b1..000000000 --- a/cmake/MangosParams.cmake +++ /dev/null @@ -1,5 +0,0 @@ -set(MANGOS_EXP "CLASSIC") -set(MANGOS_PKG "Mangos Zero") -set(MANGOS_WORLD_VER 2026082000) -set(MANGOS_REALM_VER 2026060300) -set(MANGOS_AHBOT_VER 2026071400) diff --git a/cmake/Revision.cmake b/cmake/Revision.cmake new file mode 100644 index 000000000..dfdeda301 --- /dev/null +++ b/cmake/Revision.cmake @@ -0,0 +1,315 @@ +# SPDX-License-Identifier: GPL-3.0-or-later +# +# MaNGOS is a full featured server for World of Warcraft, supporting +# the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8 +# +# Copyright (C) 2005-2026 MaNGOS +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# ============================================================================= +# Revision -- the single point of versioning of this core. +# +# Every version, schema level and ConfVersion is set in the block right below +# and nowhere else. The flow: +# +# this file + cmake/BuildRevision.h.in +# -> /revision/BuildRevision.h (never in the source tree) +# -> included by src/shared/Common/Revision.cpp only +# -> which implements src/shared/Common/Revision.h, used by everything else +# +# So a new commit or a version bump recompiles Revision.cpp and nothing else. +# +# The same values also fill every *.conf.dist.in (mangos_install_conf) and the +# Windows version resource (cmake/win/VersionInfo.h.in). +# +# Runs in two modes, same code: +# configure included from CMakeLists.txt; also creates the `revision` target. +# build `cmake -P` of this file, run by `revision` when the HEAD or index +# of the core or of a built submodule moved. Script mode has no +# cache, so the target passes in what it needs. +# ============================================================================= + +# `cmake -P` starts with every policy unset (CMake 3.x would reject IN_LIST); +# give script mode the policy level of the project so both modes run alike. +if(CMAKE_SCRIPT_MODE_FILE) + cmake_minimum_required(VERSION 3.18) +endif() + +# ----------------------------------------------------------------------------- +# Edit here. +# ----------------------------------------------------------------------------- + +# MANGOS_EXP is also the compile definition that selects the client. +set(MANGOS_EXP "CLASSIC") +set(MANGOS_PKG "Mangos Zero") +set(MANGOS_VERSION "0.22.0") +set(MANGOS_REVISION_NR "2201075") +set(MANGOS_COMPANY "MaNGOS Developers") +set(MANGOS_COPYRIGHT_FIRST_YEAR 2005) + +# Database schema this core requires. Bump together with the matching +# Rel##_##_###_*.sql migration in the mangoszero/database repository. +set(MANGOS_REALMD_DB_VERSION 22) +set(MANGOS_REALMD_DB_STRUCTURE 5) +set(MANGOS_REALMD_DB_CONTENT 1) +set(MANGOS_REALMD_DB_UPDATE "Cata Warden identity") + +set(MANGOS_CHAR_DB_VERSION 22) +set(MANGOS_CHAR_DB_STRUCTURE 5) +set(MANGOS_CHAR_DB_CONTENT 4) +set(MANGOS_CHAR_DB_UPDATE "Remove_Warden_Action") + +set(MANGOS_WORLD_DB_VERSION 22) +set(MANGOS_WORLD_DB_STRUCTURE 6) +set(MANGOS_WORLD_DB_CONTENT 4) +set(MANGOS_WORLD_DB_UPDATE "Warden_Locale_Hardening") + +# ConfVersion of each shipped .conf.dist, YYYYMMDDRR (RR = revision of the day). +set(MANGOS_WORLD_VER 2026092400) # mangosd.conf +set(MANGOS_REALM_VER 2026060300) # realmd.conf +set(MANGOS_AHBOT_VER 2026071400) # ahbot.conf, ah-service.conf +set(MANGOS_PLAYERBOT_VER 2026080700) # aiplayerbot.conf + +# ----------------------------------------------------------------------------- +# Derived and checked. Nothing below needs editing for a version bump. +# ----------------------------------------------------------------------------- + +set(MANGOS_KNOWN_EXPANSIONS CLASSIC TBC WOTLK CATA MISTS) +if(NOT MANGOS_EXP IN_LIST MANGOS_KNOWN_EXPANSIONS) + message(FATAL_ERROR "MANGOS_EXP '${MANGOS_EXP}' is not one of: ${MANGOS_KNOWN_EXPANSIONS}") +endif() + +if(NOT MANGOS_VERSION MATCHES "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$") + message(FATAL_ERROR "MANGOS_VERSION '${MANGOS_VERSION}' must be MAJOR.MINOR.PATCH") +endif() +set(MANGOS_VERSION_MAJOR ${CMAKE_MATCH_1}) +set(MANGOS_VERSION_MINOR ${CMAKE_MATCH_2}) +set(MANGOS_VERSION_PATCH ${CMAKE_MATCH_3}) + +foreach(_conf_ver MANGOS_WORLD_VER MANGOS_REALM_VER MANGOS_AHBOT_VER MANGOS_PLAYERBOT_VER) + if(NOT ${_conf_ver} MATCHES "^20[0-9][0-9][01][0-9][0-3][0-9][0-9][0-9]$") + message(FATAL_ERROR "${_conf_ver} '${${_conf_ver}}' is not a YYYYMMDDRR ConfVersion") + endif() +endforeach() + +if(MANGOS_EXP STREQUAL "CLASSIC") + set(MANGOS_CLIENT_NAME "World of Warcraft 1.12.x") +elseif(MANGOS_EXP STREQUAL "TBC") + set(MANGOS_CLIENT_NAME "The Burning Crusade 2.4.3") +elseif(MANGOS_EXP STREQUAL "WOTLK") + set(MANGOS_CLIENT_NAME "Wrath of the Lich King 3.3.5a") +elseif(MANGOS_EXP STREQUAL "CATA") + set(MANGOS_CLIENT_NAME "Cataclysm 4.3.4") +else() + set(MANGOS_CLIENT_NAME "Mists of Pandaria 5.4.8") +endif() + +# ----------------------------------------------------------------------------- +# mangos_configure( ) +# +# configure_file(@ONLY) that refuses a template naming an unset variable, which +# plain configure_file would silently turn into an empty string. +# ----------------------------------------------------------------------------- +function(mangos_configure input output) + if(NOT IS_ABSOLUTE "${input}") + set(input "${CMAKE_CURRENT_SOURCE_DIR}/${input}") + endif() + + file(STRINGS "${input}" _lines REGEX "@[A-Za-z_][A-Za-z0-9_]*@") + string(REGEX MATCHALL "@[A-Za-z_][A-Za-z0-9_]*@" _refs "${_lines}") + if(_refs) + list(REMOVE_DUPLICATES _refs) + endif() + foreach(_ref IN LISTS _refs) + string(REGEX REPLACE "^@(.*)@$" "\\1" _var "${_ref}") + if(NOT DEFINED ${_var}) + message(FATAL_ERROR "${input} references @${_var}@, which is not set.") + endif() + endforeach() + + configure_file("${input}" "${output}" @ONLY) +endfunction() + +# ----------------------------------------------------------------------------- +# mangos_install_conf( [DESTINATION ]) +# +# The one way a .conf.dist leaves the tree: generated into the current binary +# directory and installed (default: CONF_INSTALL_DIR). +# ----------------------------------------------------------------------------- +function(mangos_install_conf template) + cmake_parse_arguments(ARG "" "DESTINATION" "" ${ARGN}) + if(NOT ARG_DESTINATION) + set(ARG_DESTINATION "${CONF_INSTALL_DIR}") + endif() + + get_filename_component(_name "${template}" NAME) + string(REGEX REPLACE "\\.in$" "" _name "${_name}") + set(_out "${CMAKE_CURRENT_BINARY_DIR}/${_name}") + + mangos_configure("${template}" "${_out}") + install(FILES "${_out}" DESTINATION "${ARG_DESTINATION}") +endfunction() + +# ----------------------------------------------------------------------------- +# git +# ----------------------------------------------------------------------------- + +get_filename_component(MANGOS_SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/.." ABSOLUTE) + +if(CMAKE_SCRIPT_MODE_FILE) + foreach(_required MANGOS_BINARY_DIR MANGOS_BUILD_HOST CONF_INSTALL_DIR) + if(NOT DEFINED ${_required}) + message(FATAL_ERROR "Revision.cmake: -D${_required}= is required in script mode") + endif() + endforeach() +else() + set(MANGOS_BINARY_DIR "${CMAKE_BINARY_DIR}") + # Taken here: `cmake -P` leaves CMAKE_HOST_SYSTEM_VERSION empty. + set(MANGOS_BUILD_HOST "${CMAKE_HOST_SYSTEM_NAME} ${CMAKE_HOST_SYSTEM_VERSION}") +endif() + +# mangos_git_revision( ) +# +# Sets to " ( branch)", _hash, +# _date, and _state_files (the HEAD/index whose change makes the +# values stale). A module that is not built says so instead. +function(mangos_git_revision prefix dir enabled) + set(_hash "unknown") + set(_date "1970-01-01 00:00:00 +0000") + set(_branch "Archived") + set(_state) + + if(NOT enabled) + set(_hash "not built") + set(_date "n/a") + set(_branch "disabled") + elseif(GIT_EXECUTABLE AND NOT WITHOUT_GIT AND EXISTS "${dir}/.git") + execute_process( + COMMAND "${GIT_EXECUTABLE}" describe --long --match init --dirty=+ --abbrev=12 --always + WORKING_DIRECTORY "${dir}" + RESULT_VARIABLE _rc + OUTPUT_VARIABLE _info + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET) + + if(_rc EQUAL 0 AND _info) + string(REGEX REPLACE "init-|[0-9]+-g" "" _hash "${_info}") + + execute_process( + COMMAND "${GIT_EXECUTABLE}" show -s --format=%ci + WORKING_DIRECTORY "${dir}" + OUTPUT_VARIABLE _out + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET) + if(_out) + set(_date "${_out}") + endif() + + execute_process( + COMMAND "${GIT_EXECUTABLE}" rev-parse --abbrev-ref HEAD + WORKING_DIRECTORY "${dir}" + OUTPUT_VARIABLE _out + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET) + if(_out) + set(_branch "${_out}") + endif() + + # .git/modules/ for a submodule, the worktree's own dir for a + # linked worktree. + execute_process( + COMMAND "${GIT_EXECUTABLE}" rev-parse --absolute-git-dir + WORKING_DIRECTORY "${dir}" + OUTPUT_VARIABLE _gitdir + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET) + foreach(_file HEAD index) + if(_gitdir AND EXISTS "${_gitdir}/${_file}") + list(APPEND _state "${_gitdir}/${_file}") + endif() + endforeach() + endif() + endif() + + set(${prefix} "${_hash} ${_date} (${_branch} branch)" PARENT_SCOPE) + set(${prefix}_hash "${_hash}" PARENT_SCOPE) + set(${prefix}_date "${_date}" PARENT_SCOPE) + set(${prefix}_state_files "${_state}" PARENT_SCOPE) +endfunction() + +mangos_git_revision(MANGOS_REVISION "${MANGOS_SOURCE_DIR}" ON) +mangos_git_revision(MANGOS_ELUNA_REVISION "${MANGOS_SOURCE_DIR}/src/modules/Eluna" "${SCRIPT_LIB_ELUNA}") +mangos_git_revision(MANGOS_SD3_REVISION "${MANGOS_SOURCE_DIR}/src/modules/SD3" "${SCRIPT_LIB_SD3}") + +if(MANGOS_REVISION_hash STREQUAL "unknown" AND NOT WITHOUT_GIT AND NOT CMAKE_SCRIPT_MODE_FILE) + message(STATUS "Could not read the git revision; it will read \"${MANGOS_REVISION}\".") +endif() + +# The copyright runs to the year of the commit being built; without git, the +# build year stands in. +if(NOT MANGOS_REVISION_hash STREQUAL "unknown" AND MANGOS_REVISION_date MATCHES "^([0-9][0-9][0-9][0-9])-") + set(_year "${CMAKE_MATCH_1}") +else() + string(TIMESTAMP _year "%Y" UTC) +endif() +set(MANGOS_COPYRIGHT "Copyright (C) ${MANGOS_COPYRIGHT_FIRST_YEAR}-${_year} MaNGOS") + +set(MANGOS_REVISION_INCLUDE_DIR "${MANGOS_BINARY_DIR}/revision") +set(MANGOS_REVISION_HEADER "${MANGOS_REVISION_INCLUDE_DIR}/BuildRevision.h") +mangos_configure("${CMAKE_CURRENT_LIST_DIR}/BuildRevision.h.in" "${MANGOS_REVISION_HEADER}") + +if(CMAKE_SCRIPT_MODE_FILE) + return() +endif() + +# ----------------------------------------------------------------------------- +# `revision`: re-runs this file at build time when git state moved. configure_file +# leaves BuildRevision.h untouched when nothing changed, so that alone recompiles +# nothing; the stamp records that the check ran. Always defined, so `shared` can +# depend on it unconditionally. +# ----------------------------------------------------------------------------- +set(_revision_state_files + ${MANGOS_REVISION_state_files} + ${MANGOS_ELUNA_REVISION_state_files} + ${MANGOS_SD3_REVISION_state_files}) + +if(_revision_state_files) + set(_revision_stamp "${CMAKE_BINARY_DIR}/revision.stamp") + + add_custom_command( + OUTPUT "${_revision_stamp}" + BYPRODUCTS "${MANGOS_REVISION_HEADER}" + COMMAND "${CMAKE_COMMAND}" + "-DMANGOS_BINARY_DIR=${CMAKE_BINARY_DIR}" + "-DMANGOS_BUILD_HOST=${MANGOS_BUILD_HOST}" + "-DCONF_INSTALL_DIR=${CONF_INSTALL_DIR}" + "-DGIT_EXECUTABLE=${GIT_EXECUTABLE}" + "-DSCRIPT_LIB_ELUNA=${SCRIPT_LIB_ELUNA}" + "-DSCRIPT_LIB_SD3=${SCRIPT_LIB_SD3}" + -P "${CMAKE_CURRENT_LIST_FILE}" + COMMAND "${CMAKE_COMMAND}" -E touch "${_revision_stamp}" + DEPENDS ${_revision_state_files} + "${CMAKE_CURRENT_LIST_DIR}/BuildRevision.h.in" + "${CMAKE_CURRENT_LIST_FILE}" + COMMENT "Checking git revision" + VERBATIM) + + # BuildRevision.h was just written above; the first build need not repeat it. + file(TOUCH "${_revision_stamp}") + + add_custom_target(revision DEPENDS "${_revision_stamp}") +else() + add_custom_target(revision) +endif() diff --git a/cmake/StatusInfo.cmake b/cmake/StatusInfo.cmake index 653a6d4cc..90b505315 100644 --- a/cmake/StatusInfo.cmake +++ b/cmake/StatusInfo.cmake @@ -1,5 +1,9 @@ message("===================================================") -message("Mangos revision : ${rev_hash} ${rev_date} (${rev_branch} branch)") +message("Mangos version : ${MANGOS_PKG} ${MANGOS_VERSION} (${MANGOS_CLIENT_NAME})") +message("Mangos revision : ${MANGOS_REVISION}") +message("Database required : realmd Rel${MANGOS_REALMD_DB_VERSION}.${MANGOS_REALMD_DB_STRUCTURE}.${MANGOS_REALMD_DB_CONTENT}, " + "characters Rel${MANGOS_CHAR_DB_VERSION}.${MANGOS_CHAR_DB_STRUCTURE}.${MANGOS_CHAR_DB_CONTENT}, " + "world Rel${MANGOS_WORLD_DB_VERSION}.${MANGOS_WORLD_DB_STRUCTURE}.${MANGOS_WORLD_DB_CONTENT}") message("Build type : ${CMAKE_BUILD_TYPE}") message("Install server(s) to : ${BIN_DIR}") message("Install configs to : ${CONF_INSTALL_DIR}") @@ -28,11 +32,11 @@ if(BUILD_MANGOSD) message("Build main server : Yes (default)") if(SCRIPT_LIB_ELUNA) message("+-- with Eluna script engine") - message(" +-- revision : ${dep_eluna_rev_hash} ${dep_eluna_rev_date} (${dep_eluna_rev_branch} branch)") + message(" +-- revision : ${MANGOS_ELUNA_REVISION}") endif() if(SCRIPT_LIB_SD3) message("+-- with SD3 script engine") - message(" +-- revision : ${dep_sd3_rev_hash} ${dep_sd3_rev_date} (${dep_sd3_rev_branch} branch)") + message(" +-- revision : ${MANGOS_SD3_REVISION}") endif() if(PLAYERBOTS) message("+-- with PlayerBots") diff --git a/cmake/win/VersionInfo.h.in b/cmake/win/VersionInfo.h.in index 057d8ef27..70ec830df 100644 --- a/cmake/win/VersionInfo.h.in +++ b/cmake/win/VersionInfo.h.in @@ -1,15 +1,15 @@ #pragma once #ifndef PRODUCT_VERSION_MAJOR -#define PRODUCT_VERSION_MAJOR @PROJECT_VERSION_MAJOR@ +#define PRODUCT_VERSION_MAJOR @MANGOS_VERSION_MAJOR@ #endif #ifndef PRODUCT_VERSION_MINOR -#define PRODUCT_VERSION_MINOR @PROJECT_VERSION_MINOR@ +#define PRODUCT_VERSION_MINOR @MANGOS_VERSION_MINOR@ #endif #ifndef PRODUCT_VERSION_PATCH -#define PRODUCT_VERSION_PATCH @PROJECT_VERSION_PATCH@ +#define PRODUCT_VERSION_PATCH @MANGOS_VERSION_PATCH@ #endif @@ -52,4 +52,12 @@ #ifndef PRODUCT_BUNDLE #define PRODUCT_BUNDLE "@PRODUCT_NAME@\0" -#endif \ No newline at end of file +#endif + +#ifndef PRODUCT_COMPANY +#define PRODUCT_COMPANY "@MANGOS_COMPANY@\0" +#endif + +#ifndef PRODUCT_COPYRIGHT +#define PRODUCT_COPYRIGHT "@MANGOS_COPYRIGHT@\0" +#endif diff --git a/cmake/win/VersionInfo.rc b/cmake/win/VersionInfo.rc index c04be3868..e5a59d722 100644 --- a/cmake/win/VersionInfo.rc +++ b/cmake/win/VersionInfo.rc @@ -22,10 +22,12 @@ BEGIN BEGIN BLOCK "040904b0" BEGIN + VALUE "CompanyName", PRODUCT_COMPANY VALUE "ProductName", PRODUCT_BUNDLE VALUE "ProductVersion", PRODUCT_VERSION_RESOURCE_STR + VALUE "FileVersion", FILE_VERSION_RESOURCE_STR VALUE "FileDescription", PRODUCT_FILE_DESCRIPTION - VALUE "LegalCopyright", "Copyright (C) 2005-2026 MaNGOS" + VALUE "LegalCopyright", PRODUCT_COPYRIGHT END END BLOCK "VarFileInfo" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e0e51ff85..59798f7e6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -31,8 +31,6 @@ add_subdirectory(proto) # IPC substrate (always built; ah-service and mangosd both link it) add_subdirectory(ipc) -add_subdirectory(genrev) - # Needs to link against mangos_world.lib if(BUILD_MANGOSD) # Build the mangos game library @@ -56,6 +54,8 @@ endif() # Build the mangos realm authentication server if(BUILD_REALMD) add_subdirectory(realmd) + # realmd still includes GitRevision.h / SystemConfig.h by those names. + mangos_submodule_compat(realmd "${CMAKE_SOURCE_DIR}/src/shared/Compat/revision") # realmd is a SUBMODULE and is never edited here. Its own test executables # compile Auth/PatchArtifact.cpp, which includes Auth/Md5.h -- a header this diff --git a/src/game/AuctionHouseBot/AuctionHouseBot.cpp b/src/game/AuctionHouseBot/AuctionHouseBot.cpp index c637b4e26..f26fdb7e9 100755 --- a/src/game/AuctionHouseBot/AuctionHouseBot.cpp +++ b/src/game/AuctionHouseBot/AuctionHouseBot.cpp @@ -33,7 +33,7 @@ #include "Log.h" #include "ObjectMgr.h" #include "AuctionHouseMgr.h" -#include "SystemConfig.h" +#include "Revision.h" #include "SQLStorages.h" #include "World.h" @@ -591,7 +591,7 @@ class AuctionBotSeller : public AuctionBotAgent * @brief Constructor - initializes AuctionBotConfig with default values */ AuctionBotConfig::AuctionBotConfig() - : m_configFileName(AUCTIONHOUSEBOT_CONFIG_LOCATION), + : m_configFileName(Revision::GetConfigPath(Revision::ConfigFile::AhBot)), m_BotId(0), // Initialize m_BotId m_ItemsPerCycleBoost(0), // Initialize m_ItemsPerCycleBoost m_ItemsPerCycleNormal(0) // Initialize m_ItemsPerCycleNormal @@ -612,7 +612,7 @@ bool AuctionBotConfig::Initialize() if (!m_AhBotCfg.SetSource(m_configFileName.c_str())) { // Try current folder as fallback - if (!m_AhBotCfg.SetSource(AUCTIONHOUSEBOT_CONFIG_NAME)) + if (!m_AhBotCfg.SetSource(Revision::GetConfigName(Revision::ConfigFile::AhBot))) { sLog.outString("AHBOT is Disabled. Unable to open configuration file %s. ", m_configFileName.c_str()); setConfig(CONFIG_UINT32_AHBOT_ALLIANCE_ITEM_AMOUNT_RATIO, 0); @@ -620,7 +620,7 @@ bool AuctionBotConfig::Initialize() setConfig(CONFIG_UINT32_AHBOT_NEUTRAL_ITEM_AMOUNT_RATIO, 0); return false; } - m_configFileName = AUCTIONHOUSEBOT_CONFIG_NAME; + m_configFileName = Revision::GetConfigName(Revision::ConfigFile::AhBot); } else { @@ -750,7 +750,7 @@ void AuctionBotConfig::setConfig(AuctionBotConfigBoolValues index, char const* f void AuctionBotConfig::GetConfigFromFile() { // Check config file version - if (m_AhBotCfg.GetIntDefault("ConfVersion", 0) != AHBOT_CONFIG_VERSION) + if (uint32(m_AhBotCfg.GetIntDefault("ConfVersion", 0)) != Revision::GetConfigVersion(Revision::ConfigFile::AhBot)) { sLog.outError("AHBot: Configuration file version doesn't match expected version. Some config variables may be wrong or missing."); } diff --git a/src/game/CMakeLists.txt b/src/game/CMakeLists.txt index 684355321..8a5155bf5 100644 --- a/src/game/CMakeLists.txt +++ b/src/game/CMakeLists.txt @@ -96,6 +96,9 @@ if(SCRIPT_LIB_ELUNA) # open with #include "Common.h". mangos_submodule_compat_sources("${SRC_GRP_ELUNA}" "${CMAKE_SOURCE_DIR}/src/shared/Compat/eluna") + # ElunaIncludes.h still includes GitRevision.h / revision_data.h by those names. + set_property(SOURCE ${SRC_GRP_ELUNA} APPEND PROPERTY + INCLUDE_DIRECTORIES "${CMAKE_SOURCE_DIR}/src/shared/Compat/revision") endif() if(PLAYERBOTS) @@ -182,11 +185,11 @@ file(GLOB Playerbot_Warrior ${CMAKE_SOURCE_DIR}/src/modules/Bots/playerbot/strat source_group("Player Bot\\Strategies\\Warrior" FILES ${Playerbot_Warrior}) LIST(APPEND SRC_GRP_BOTS ${Playerbot_Warrior}) -configure_file(${CMAKE_SOURCE_DIR}/src/modules/Bots/playerbot/aiplayerbot.conf.dist.in ${CMAKE_CURRENT_BINARY_DIR}/aiplayerbot.conf.dist) +mangos_install_conf(${CMAKE_SOURCE_DIR}/src/modules/Bots/playerbot/aiplayerbot.conf.dist.in) endif() -configure_file(AuctionHouseBot/ahbot.conf.dist.in ${CMAKE_CURRENT_BINARY_DIR}/AuctionHouseBot/ahbot.conf.dist) +mangos_install_conf(AuctionHouseBot/ahbot.conf.dist.in) add_library(game STATIC ${SRC_GRP_AHBOT} @@ -275,19 +278,9 @@ if(PCH) add_cxx_pch(game pchdef.h pchdef.cpp) endif() -install( - FILES ${CMAKE_CURRENT_BINARY_DIR}/AuctionHouseBot/ahbot.conf.dist - DESTINATION ${CONF_INSTALL_DIR} -) - if(SCRIPT_LIB_ELUNA) install( DIRECTORY ${CMAKE_SOURCE_DIR}/src/modules/Eluna/extensions DESTINATION ${BIN_DIR}/lua_scripts ) endif() - -if(PLAYERBOTS) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/aiplayerbot.conf.dist - DESTINATION ${CONF_INSTALL_DIR}) -endif() diff --git a/src/game/ChatCommands/ServerCommands.cpp b/src/game/ChatCommands/ServerCommands.cpp index 46336a8c6..167ac44ea 100644 --- a/src/game/ChatCommands/ServerCommands.cpp +++ b/src/game/ChatCommands/ServerCommands.cpp @@ -39,10 +39,8 @@ #include "ObjectMgr.h" #include "World.h" #include "Config.h" -#include "GitRevision.h" -#include "SystemConfig.h" +#include "Revision.h" #include "UpdateTime.h" -#include "revision_data.h" #include "CorpseManager.h" /** @@ -61,7 +59,7 @@ bool ChatHandler::HandleServerInfoCommand(char* /*args*/) uint32 updateTime = sWorldUpdateTime.GetLastUpdateTime(); char const* full; - full = GitRevision::GetProjectRevision(); + full = Revision::GetProjectRevision(); SendSysMessage(full); if (sScriptMgr.IsScriptLibraryLoaded()) @@ -81,10 +79,10 @@ bool ChatHandler::HandleServerInfoCommand(char* /*args*/) SendSysMessage(LANG_USING_SCRIPT_LIB_NONE); } - PSendSysMessage("%s", GitRevision::GetFullRevision()); - PSendSysMessage("%s", GitRevision::GetDepElunaFullRevisionStr()); - PSendSysMessage("%s", GitRevision::GetDepSD3FullRevisionStr()); - PSendSysMessage("%s", GitRevision::GetRunningSystem()); + PSendSysMessage("%s", Revision::GetFullRevision()); + PSendSysMessage("Eluna submodule revision: %s", Revision::GetElunaRevisionStr()); + PSendSysMessage("SD3 submodule revision: %s", Revision::GetSD3RevisionStr()); + PSendSysMessage("Compiled on: %s", Revision::GetBuildHost()); PSendSysMessage(LANG_USING_WORLD_DB, sWorld.GetDBVersion()); PSendSysMessage(LANG_CONNECTED_USERS, activeClientsNum, maxActiveClientsNum, queuedClientsNum, maxQueuedClientsNum); diff --git a/src/game/Object/Player.cpp b/src/game/Object/Player.cpp index a7fd7c8ff..a0e4d178e 100644 --- a/src/game/Object/Player.cpp +++ b/src/game/Object/Player.cpp @@ -71,7 +71,6 @@ #include "BattleGround/BattleGroundAV.h" #include "OutdoorPvP/OutdoorPvP.h" #include "Chat.h" -#include "revision_data.h" #include "Spell.h" #include "ScriptMgr.h" #include "SocialMgr.h" diff --git a/src/game/Object/PlayerActionButton.cpp b/src/game/Object/PlayerActionButton.cpp index e36a59c28..567e073ba 100644 --- a/src/game/Object/PlayerActionButton.cpp +++ b/src/game/Object/PlayerActionButton.cpp @@ -61,7 +61,6 @@ #include "BattleGround/BattleGroundAV.h" #include "OutdoorPvP/OutdoorPvP.h" #include "Chat.h" -#include "revision_data.h" #include "Spell.h" #include "ScriptMgr.h" #include "SocialMgr.h" diff --git a/src/game/Object/PlayerAreaTrigger.cpp b/src/game/Object/PlayerAreaTrigger.cpp index 772b30a49..707e5b143 100644 --- a/src/game/Object/PlayerAreaTrigger.cpp +++ b/src/game/Object/PlayerAreaTrigger.cpp @@ -63,7 +63,6 @@ #include "BattleGround/BattleGroundAV.h" #include "OutdoorPvP/OutdoorPvP.h" #include "Chat.h" -#include "revision_data.h" #include "Spell.h" #include "ScriptMgr.h" #include "SocialMgr.h" diff --git a/src/game/Object/PlayerBattleGround.cpp b/src/game/Object/PlayerBattleGround.cpp index d11f7a877..3370eba89 100644 --- a/src/game/Object/PlayerBattleGround.cpp +++ b/src/game/Object/PlayerBattleGround.cpp @@ -61,7 +61,6 @@ #include "BattleGround/BattleGroundAV.h" #include "OutdoorPvP/OutdoorPvP.h" #include "Chat.h" -#include "revision_data.h" #include "Spell.h" #include "ScriptMgr.h" #include "SocialMgr.h" diff --git a/src/game/Object/PlayerChannel.cpp b/src/game/Object/PlayerChannel.cpp index e5b455cad..03512b653 100644 --- a/src/game/Object/PlayerChannel.cpp +++ b/src/game/Object/PlayerChannel.cpp @@ -62,7 +62,6 @@ #include "BattleGround/BattleGroundAV.h" #include "OutdoorPvP/OutdoorPvP.h" #include "Chat.h" -#include "revision_data.h" #include "Spell.h" #include "ScriptMgr.h" #include "SocialMgr.h" diff --git a/src/game/Object/PlayerCombo.cpp b/src/game/Object/PlayerCombo.cpp index 1c762d27a..221dae8d1 100644 --- a/src/game/Object/PlayerCombo.cpp +++ b/src/game/Object/PlayerCombo.cpp @@ -62,7 +62,6 @@ #include "BattleGround/BattleGroundAV.h" #include "OutdoorPvP/OutdoorPvP.h" #include "Chat.h" -#include "revision_data.h" #include "Spell.h" #include "ScriptMgr.h" #include "SocialMgr.h" diff --git a/src/game/Object/PlayerDbLookup.cpp b/src/game/Object/PlayerDbLookup.cpp index ecca1d350..0c9ba07d1 100644 --- a/src/game/Object/PlayerDbLookup.cpp +++ b/src/game/Object/PlayerDbLookup.cpp @@ -61,7 +61,6 @@ #include "BattleGround/BattleGroundAV.h" #include "OutdoorPvP/OutdoorPvP.h" #include "Chat.h" -#include "revision_data.h" #include "Spell.h" #include "ScriptMgr.h" #include "SocialMgr.h" diff --git a/src/game/Object/PlayerDeath.cpp b/src/game/Object/PlayerDeath.cpp index 8df599dd0..e06811e1f 100644 --- a/src/game/Object/PlayerDeath.cpp +++ b/src/game/Object/PlayerDeath.cpp @@ -64,7 +64,6 @@ #include "BattleGround/BattleGroundAV.h" #include "OutdoorPvP/OutdoorPvP.h" #include "Chat.h" -#include "revision_data.h" #include "Spell.h" #include "ScriptMgr.h" #include "SocialMgr.h" diff --git a/src/game/Object/PlayerDuel.cpp b/src/game/Object/PlayerDuel.cpp index f39f88a63..3993392ff 100644 --- a/src/game/Object/PlayerDuel.cpp +++ b/src/game/Object/PlayerDuel.cpp @@ -62,7 +62,6 @@ #include "BattleGround/BattleGroundAV.h" #include "OutdoorPvP/OutdoorPvP.h" #include "Chat.h" -#include "revision_data.h" #include "Spell.h" #include "ScriptMgr.h" #include "SocialMgr.h" diff --git a/src/game/Object/PlayerDurability.cpp b/src/game/Object/PlayerDurability.cpp index afad1fbb5..dd8cff86f 100644 --- a/src/game/Object/PlayerDurability.cpp +++ b/src/game/Object/PlayerDurability.cpp @@ -61,7 +61,6 @@ #include "BattleGround/BattleGroundAV.h" #include "OutdoorPvP/OutdoorPvP.h" #include "Chat.h" -#include "revision_data.h" #include "Spell.h" #include "ScriptMgr.h" #include "SocialMgr.h" diff --git a/src/game/Object/PlayerGossip.cpp b/src/game/Object/PlayerGossip.cpp index bca344a1a..91bd0d0b5 100644 --- a/src/game/Object/PlayerGossip.cpp +++ b/src/game/Object/PlayerGossip.cpp @@ -63,7 +63,6 @@ #include "BattleGround/BattleGroundAV.h" #include "OutdoorPvP/OutdoorPvP.h" #include "Chat.h" -#include "revision_data.h" #include "Spell.h" #include "ScriptMgr.h" #include "SocialMgr.h" diff --git a/src/game/Object/PlayerGroup.cpp b/src/game/Object/PlayerGroup.cpp index d844074d7..9d08fa62f 100644 --- a/src/game/Object/PlayerGroup.cpp +++ b/src/game/Object/PlayerGroup.cpp @@ -63,7 +63,6 @@ #include "BattleGround/BattleGroundAV.h" #include "OutdoorPvP/OutdoorPvP.h" #include "Chat.h" -#include "revision_data.h" #include "Spell.h" #include "ScriptMgr.h" #include "SocialMgr.h" diff --git a/src/game/Object/PlayerInstance.cpp b/src/game/Object/PlayerInstance.cpp index ef24ed705..12ba5e7a9 100644 --- a/src/game/Object/PlayerInstance.cpp +++ b/src/game/Object/PlayerInstance.cpp @@ -61,7 +61,6 @@ #include "BattleGround/BattleGroundAV.h" #include "OutdoorPvP/OutdoorPvP.h" #include "Chat.h" -#include "revision_data.h" #include "Spell.h" #include "ScriptMgr.h" #include "SocialMgr.h" diff --git a/src/game/Object/PlayerItem.cpp b/src/game/Object/PlayerItem.cpp index 1d9ec99e5..1f1aace2d 100644 --- a/src/game/Object/PlayerItem.cpp +++ b/src/game/Object/PlayerItem.cpp @@ -61,7 +61,6 @@ #include "BattleGround/BattleGroundAV.h" #include "OutdoorPvP/OutdoorPvP.h" #include "Chat.h" -#include "revision_data.h" #include "Spell.h" #include "ScriptMgr.h" #include "SocialMgr.h" diff --git a/src/game/Object/PlayerItemApply.cpp b/src/game/Object/PlayerItemApply.cpp index 5115e1ddb..f7efc7a42 100644 --- a/src/game/Object/PlayerItemApply.cpp +++ b/src/game/Object/PlayerItemApply.cpp @@ -61,7 +61,6 @@ #include "BattleGround/BattleGroundAV.h" #include "OutdoorPvP/OutdoorPvP.h" #include "Chat.h" -#include "revision_data.h" #include "Spell.h" #include "ScriptMgr.h" #include "SocialMgr.h" diff --git a/src/game/Object/PlayerItemEnchant.cpp b/src/game/Object/PlayerItemEnchant.cpp index 1ba7b142c..4673ee331 100644 --- a/src/game/Object/PlayerItemEnchant.cpp +++ b/src/game/Object/PlayerItemEnchant.cpp @@ -63,7 +63,6 @@ #include "BattleGround/BattleGroundAV.h" #include "OutdoorPvP/OutdoorPvP.h" #include "Chat.h" -#include "revision_data.h" #include "Spell.h" #include "ScriptMgr.h" #include "SocialMgr.h" diff --git a/src/game/Object/PlayerItemQuery.cpp b/src/game/Object/PlayerItemQuery.cpp index 22fce0e06..8d276b609 100644 --- a/src/game/Object/PlayerItemQuery.cpp +++ b/src/game/Object/PlayerItemQuery.cpp @@ -62,7 +62,6 @@ #include "BattleGround/BattleGroundAV.h" #include "OutdoorPvP/OutdoorPvP.h" #include "Chat.h" -#include "revision_data.h" #include "Spell.h" #include "ScriptMgr.h" #include "SocialMgr.h" diff --git a/src/game/Object/PlayerItemStorage.cpp b/src/game/Object/PlayerItemStorage.cpp index 93dbccb2e..32ad64e9c 100644 --- a/src/game/Object/PlayerItemStorage.cpp +++ b/src/game/Object/PlayerItemStorage.cpp @@ -62,7 +62,6 @@ #include "BattleGround/BattleGroundAV.h" #include "OutdoorPvP/OutdoorPvP.h" #include "Chat.h" -#include "revision_data.h" #include "Spell.h" #include "ScriptMgr.h" #include "SocialMgr.h" diff --git a/src/game/Object/PlayerItemValidation.cpp b/src/game/Object/PlayerItemValidation.cpp index 77f00ec96..756312c87 100644 --- a/src/game/Object/PlayerItemValidation.cpp +++ b/src/game/Object/PlayerItemValidation.cpp @@ -62,7 +62,6 @@ #include "BattleGround/BattleGroundAV.h" #include "OutdoorPvP/OutdoorPvP.h" #include "Chat.h" -#include "revision_data.h" #include "Spell.h" #include "ScriptMgr.h" #include "SocialMgr.h" diff --git a/src/game/Object/PlayerLearn.cpp b/src/game/Object/PlayerLearn.cpp index ba0989e43..28ee78d2c 100644 --- a/src/game/Object/PlayerLearn.cpp +++ b/src/game/Object/PlayerLearn.cpp @@ -61,7 +61,6 @@ #include "BattleGround/BattleGroundAV.h" #include "OutdoorPvP/OutdoorPvP.h" #include "Chat.h" -#include "revision_data.h" #include "Spell.h" #include "ScriptMgr.h" #include "SocialMgr.h" diff --git a/src/game/Object/PlayerLoad.cpp b/src/game/Object/PlayerLoad.cpp index bfc31442e..418cb8625 100644 --- a/src/game/Object/PlayerLoad.cpp +++ b/src/game/Object/PlayerLoad.cpp @@ -71,7 +71,6 @@ #include "BattleGround/BattleGroundAV.h" #include "OutdoorPvP/OutdoorPvP.h" #include "Chat.h" -#include "revision_data.h" #include "Spell.h" #include "ScriptMgr.h" #include "SocialMgr.h" diff --git a/src/game/Object/PlayerLoot.cpp b/src/game/Object/PlayerLoot.cpp index 42de27fcc..33bf14129 100644 --- a/src/game/Object/PlayerLoot.cpp +++ b/src/game/Object/PlayerLoot.cpp @@ -62,7 +62,6 @@ #include "BattleGround/BattleGroundAV.h" #include "OutdoorPvP/OutdoorPvP.h" #include "Chat.h" -#include "revision_data.h" #include "Spell.h" #include "ScriptMgr.h" #include "SocialMgr.h" diff --git a/src/game/Object/PlayerMail.cpp b/src/game/Object/PlayerMail.cpp index 09aafc1ed..76170ff44 100644 --- a/src/game/Object/PlayerMail.cpp +++ b/src/game/Object/PlayerMail.cpp @@ -61,7 +61,6 @@ #include "BattleGround/BattleGroundAV.h" #include "OutdoorPvP/OutdoorPvP.h" #include "Chat.h" -#include "revision_data.h" #include "Spell.h" #include "ScriptMgr.h" #include "SocialMgr.h" diff --git a/src/game/Object/PlayerMirror.cpp b/src/game/Object/PlayerMirror.cpp index d866978d6..f4fb0d694 100644 --- a/src/game/Object/PlayerMirror.cpp +++ b/src/game/Object/PlayerMirror.cpp @@ -61,7 +61,6 @@ #include "BattleGround/BattleGroundAV.h" #include "OutdoorPvP/OutdoorPvP.h" #include "Chat.h" -#include "revision_data.h" #include "Spell.h" #include "ScriptMgr.h" #include "SocialMgr.h" diff --git a/src/game/Object/PlayerMovement.cpp b/src/game/Object/PlayerMovement.cpp index d3b2b5eec..dc9283595 100644 --- a/src/game/Object/PlayerMovement.cpp +++ b/src/game/Object/PlayerMovement.cpp @@ -61,7 +61,6 @@ #include "BattleGround/BattleGroundAV.h" #include "OutdoorPvP/OutdoorPvP.h" #include "Chat.h" -#include "revision_data.h" #include "Spell.h" #include "ScriptMgr.h" #include "SocialMgr.h" diff --git a/src/game/Object/PlayerPvP.cpp b/src/game/Object/PlayerPvP.cpp index 0ce9255ec..cc26a951f 100644 --- a/src/game/Object/PlayerPvP.cpp +++ b/src/game/Object/PlayerPvP.cpp @@ -61,7 +61,6 @@ #include "BattleGround/BattleGroundAV.h" #include "OutdoorPvP/OutdoorPvP.h" #include "Chat.h" -#include "revision_data.h" #include "Spell.h" #include "ScriptMgr.h" #include "SocialMgr.h" diff --git a/src/game/Object/PlayerQuest.cpp b/src/game/Object/PlayerQuest.cpp index 71b98eb1c..b5ecb2e25 100644 --- a/src/game/Object/PlayerQuest.cpp +++ b/src/game/Object/PlayerQuest.cpp @@ -65,7 +65,7 @@ #include "BattleGround/BattleGroundAV.h" #include "OutdoorPvP/OutdoorPvP.h" #include "Chat.h" -#include "revision_data.h" +#include "Revision.h" #include "Spell.h" #include "ScriptMgr.h" #include "SocialMgr.h" @@ -838,8 +838,8 @@ void Player::AddQuest(Quest const* pQuest, Object* questGiver) SqlStatement stmt = CharacterDatabase.CreateStatement(CHAR_INS_QUEST_TRACK, "INSERT INTO `quest_tracker` (`id`, `character_guid`, `quest_accept_time`, `core_hash`, `core_revision`) VALUES (?, ?, NOW(), ?, ?)"); stmt.addUInt32(quest_id); stmt.addUInt32(GetGUIDLow()); - stmt.addString(REVISION_HASH); - stmt.addString(REVISION_DATE); + stmt.addString(Revision::GetHash()); + stmt.addString(Revision::GetDate()); // add to Quest Tracker stmt.Execute(); diff --git a/src/game/Object/PlayerRegen.cpp b/src/game/Object/PlayerRegen.cpp index 3454ef57a..831873dd0 100644 --- a/src/game/Object/PlayerRegen.cpp +++ b/src/game/Object/PlayerRegen.cpp @@ -61,7 +61,6 @@ #include "BattleGround/BattleGroundAV.h" #include "OutdoorPvP/OutdoorPvP.h" #include "Chat.h" -#include "revision_data.h" #include "Spell.h" #include "ScriptMgr.h" #include "SocialMgr.h" diff --git a/src/game/Object/PlayerReputation.cpp b/src/game/Object/PlayerReputation.cpp index dc6ffbdf3..0f5892551 100644 --- a/src/game/Object/PlayerReputation.cpp +++ b/src/game/Object/PlayerReputation.cpp @@ -61,7 +61,6 @@ #include "BattleGround/BattleGroundAV.h" #include "OutdoorPvP/OutdoorPvP.h" #include "Chat.h" -#include "revision_data.h" #include "Spell.h" #include "ScriptMgr.h" #include "SocialMgr.h" diff --git a/src/game/Object/PlayerRest.cpp b/src/game/Object/PlayerRest.cpp index 4af7411c4..833e51299 100644 --- a/src/game/Object/PlayerRest.cpp +++ b/src/game/Object/PlayerRest.cpp @@ -61,7 +61,6 @@ #include "BattleGround/BattleGroundAV.h" #include "OutdoorPvP/OutdoorPvP.h" #include "Chat.h" -#include "revision_data.h" #include "Spell.h" #include "ScriptMgr.h" #include "SocialMgr.h" diff --git a/src/game/Object/PlayerReward.cpp b/src/game/Object/PlayerReward.cpp index 9bd857b9f..e645bd3a1 100644 --- a/src/game/Object/PlayerReward.cpp +++ b/src/game/Object/PlayerReward.cpp @@ -62,7 +62,6 @@ #include "BattleGround/BattleGroundAV.h" #include "OutdoorPvP/OutdoorPvP.h" #include "Chat.h" -#include "revision_data.h" #include "Spell.h" #include "ScriptMgr.h" #include "SocialMgr.h" diff --git a/src/game/Object/PlayerSave.cpp b/src/game/Object/PlayerSave.cpp index 73c5907b2..7c4c96d30 100644 --- a/src/game/Object/PlayerSave.cpp +++ b/src/game/Object/PlayerSave.cpp @@ -70,7 +70,6 @@ #include "BattleGround/BattleGroundAV.h" #include "OutdoorPvP/OutdoorPvP.h" #include "Chat.h" -#include "revision_data.h" #include "Spell.h" #include "ScriptMgr.h" #include "SocialMgr.h" diff --git a/src/game/Object/PlayerSpell.cpp b/src/game/Object/PlayerSpell.cpp index a883585d1..9e5b73097 100644 --- a/src/game/Object/PlayerSpell.cpp +++ b/src/game/Object/PlayerSpell.cpp @@ -62,7 +62,6 @@ #include "BattleGround/BattleGroundAV.h" #include "OutdoorPvP/OutdoorPvP.h" #include "Chat.h" -#include "revision_data.h" #include "Spell.h" #include "ScriptMgr.h" #include "SocialMgr.h" diff --git a/src/game/Object/PlayerStats.cpp b/src/game/Object/PlayerStats.cpp index c19c10f06..92572349f 100644 --- a/src/game/Object/PlayerStats.cpp +++ b/src/game/Object/PlayerStats.cpp @@ -63,7 +63,6 @@ #include "BattleGround/BattleGroundAV.h" #include "OutdoorPvP/OutdoorPvP.h" #include "Chat.h" -#include "revision_data.h" #include "Spell.h" #include "ScriptMgr.h" #include "SocialMgr.h" diff --git a/src/game/Object/PlayerTalent.cpp b/src/game/Object/PlayerTalent.cpp index 5cdc547d4..0f1237341 100644 --- a/src/game/Object/PlayerTalent.cpp +++ b/src/game/Object/PlayerTalent.cpp @@ -61,7 +61,6 @@ #include "BattleGround/BattleGroundAV.h" #include "OutdoorPvP/OutdoorPvP.h" #include "Chat.h" -#include "revision_data.h" #include "Spell.h" #include "ScriptMgr.h" #include "SocialMgr.h" diff --git a/src/game/Object/PlayerTaxi.cpp b/src/game/Object/PlayerTaxi.cpp index 2193750c3..d1e56637e 100644 --- a/src/game/Object/PlayerTaxi.cpp +++ b/src/game/Object/PlayerTaxi.cpp @@ -64,7 +64,6 @@ #include "BattleGround/BattleGroundAV.h" #include "OutdoorPvP/OutdoorPvP.h" #include "Chat.h" -#include "revision_data.h" #include "Spell.h" #include "ScriptMgr.h" #include "SocialMgr.h" diff --git a/src/game/Object/PlayerVisibility.cpp b/src/game/Object/PlayerVisibility.cpp index 57260b243..b4107162a 100644 --- a/src/game/Object/PlayerVisibility.cpp +++ b/src/game/Object/PlayerVisibility.cpp @@ -62,7 +62,6 @@ #include "BattleGround/BattleGroundAV.h" #include "OutdoorPvP/OutdoorPvP.h" #include "Chat.h" -#include "revision_data.h" #include "Spell.h" #include "ScriptMgr.h" #include "SocialMgr.h" diff --git a/src/game/Object/PlayerZone.cpp b/src/game/Object/PlayerZone.cpp index 60243a2e0..d6a4e9579 100644 --- a/src/game/Object/PlayerZone.cpp +++ b/src/game/Object/PlayerZone.cpp @@ -63,7 +63,6 @@ #include "BattleGround/BattleGroundAV.h" #include "OutdoorPvP/OutdoorPvP.h" #include "Chat.h" -#include "revision_data.h" #include "Spell.h" #include "ScriptMgr.h" #include "SocialMgr.h" diff --git a/src/game/Server/WorldSession.cpp b/src/game/Server/WorldSession.cpp index c04f54542..6f4ee3017 100644 --- a/src/game/Server/WorldSession.cpp +++ b/src/game/Server/WorldSession.cpp @@ -375,7 +375,12 @@ void WorldSession::OnAuthenticatedAdmission() return; m_wardenAdmissionHandled = true; - if (!m_pendingWardenAdmission || !m_pendingWardenAdmission->available) + // Warden.Enabled = 0 takes the same exit as a client that supplied no + // admission data: no WardenServer is provisioned, and every Warden seam + // already treats a missing one as "nothing to do". reset() cleanses the + // session key (~AdmissionData). + if (!m_pendingWardenAdmission || !m_pendingWardenAdmission->available || + !sWorld.getConfig(CONFIG_BOOL_WARDEN_ENABLED)) { m_pendingWardenAdmission.reset(); return; diff --git a/src/game/WorldHandlers/World.cpp b/src/game/WorldHandlers/World.cpp index db169933c..bab54fe91 100644 --- a/src/game/WorldHandlers/World.cpp +++ b/src/game/WorldHandlers/World.cpp @@ -52,7 +52,6 @@ #include "Database/DatabaseEnv.h" #include "Config/Config.h" #include "Platform/Define.h" -#include "SystemConfig.h" #include "Log.h" #include "OpcodeTable.h" #include "WorldSession.h" @@ -98,7 +97,7 @@ #include "DisableMgr.h" #include "Language.h" #include "CommandMgr.h" -#include "GitRevision.h" +#include "Revision.h" #include "UpdateTime.h" #include "GameTime.h" #include "ScheduledExit.h" @@ -1070,8 +1069,9 @@ void World::showFooter(uint32 startupMs) #endif char database[128]; - snprintf(database, sizeof(database), "Rel%s.%s.%s", GitRevision::GetWorldDBVersion(), - GitRevision::GetWorldDBStructure(), GitRevision::GetWorldDBContent()); + Revision::DbVersion const& worldDb = Revision::GetWorldDb(); + snprintf(database, sizeof(database), "Rel%s.%s.%s", worldDb.version, + worldDb.structure, worldDb.content); char ready[64]; if (startupMs >= 60000) @@ -1087,9 +1087,9 @@ void World::showFooter(uint32 startupMs) // layout now, so the same facts go out as ordinary log lines -- which is also // what survives a redirected stdout. sLog.outString("World initialization complete (%s)", ready); - sLog.outString(" server : %s", GitRevision::GetProductVersionStr()); - sLog.outString(" eluna : %s", GitRevision::GetDepElunaFullRevision()); - sLog.outString(" sd3 : %s", GitRevision::GetDepSD3FullRevision()); + sLog.outString(" server : %s", Revision::GetRevisionStr()); + sLog.outString(" eluna : %s", Revision::GetElunaRevisionStr()); + sLog.outString(" sd3 : %s", Revision::GetSD3RevisionStr()); sLog.outString(" database : %s", database); sLog.outString(" clients : %s", EXPECTED_MANGOSD_CLIENT_VERSION); sLog.outString(" builds : %s", AcceptableClientBuildsListStr().c_str()); diff --git a/src/game/WorldHandlers/World.h b/src/game/WorldHandlers/World.h index 264b154ba..422ec6280 100644 --- a/src/game/WorldHandlers/World.h +++ b/src/game/WorldHandlers/World.h @@ -66,6 +66,9 @@ class QueryResult; class WorkerSupervisor; class IpcMessage; +/// PlayerLimit when mangosd.conf does not set it. +constexpr int32 DEFAULT_PLAYER_LIMIT = 100; + // ServerMessages.dbc enum ServerMessageType { @@ -398,6 +401,7 @@ enum eConfigBoolValues CONFIG_BOOL_AH_CUSTODY, // AH Service worker write-authority (SP-2, boot-latched) CONFIG_BOOL_AH_WRITE_AUTHORITY, + CONFIG_BOOL_WARDEN_ENABLED, CONFIG_BOOL_WARDEN_REQUIRE_EXACT_PROFILE, CONFIG_BOOL_VALUE_COUNT }; diff --git a/src/game/WorldHandlers/WorldConfig.cpp b/src/game/WorldHandlers/WorldConfig.cpp index 91c877786..5060654fe 100644 --- a/src/game/WorldHandlers/WorldConfig.cpp +++ b/src/game/WorldHandlers/WorldConfig.cpp @@ -95,10 +95,9 @@ #include "DisableMgr.h" #include "Language.h" #include "CommandMgr.h" -#include "GitRevision.h" +#include "Revision.h" #include "UpdateTime.h" #include "GameTime.h" -#include "SystemConfig.h" #include "AuctionHouseBot/AuctionIntentExecutor.h" #include "AuctionHouseBot/CustodyLedger.h" #include "AuctionHouseBot/CustodyService.h" @@ -152,7 +151,7 @@ void World::LoadConfigSettings(bool reload) } else { - if (confVersion < MANGOSD_CONFIG_VERSION) + if (confVersion < Revision::GetConfigVersion(Revision::ConfigFile::Mangosd)) { sLog.outError("*****************************************************************************"); sLog.outError(" WARNING: Your mangosd.conf version indicates your conf file is out of date!"); @@ -253,6 +252,9 @@ void World::LoadConfigSettings(bool reload) setConfig(CONFIG_UINT32_MAX_WHOLIST_RETURNS, "MaxWhoListReturns", 49); setConfig(CONFIG_UINT32_AUTOBROADCAST_INTERVAL, "AutoBroadcast", 600); + // Read when a session is admitted, so a reload affects new sessions only. + setConfig(CONFIG_BOOL_WARDEN_ENABLED, "Warden.Enabled", true); + // Warden takes one immutable policy snapshot when a session is admitted. // Normalize here so no downstream component can observe unsafe ranges. setConfig(CONFIG_UINT32_WARDEN_ENFORCEMENT_MODE, @@ -339,6 +341,11 @@ void World::LoadConfigSettings(bool reload) { sLog.outError("Warden incident window is invalid; using 900 seconds."); } + if (!getConfig(CONFIG_BOOL_WARDEN_ENABLED)) + { + sLog.outError("Warden is DISABLED (Warden.Enabled = 0): new sessions " + "are admitted without any Warden checks."); + } if (getConfig(CONFIG_UINT32_AUTOBROADCAST_INTERVAL) > 0) { @@ -385,9 +392,9 @@ void World::LoadConfigSettings(bool reload) setConfig(CONFIG_UINT32_INTERVAL_CHANGEWEATHER, "ChangeWeatherInterval", 10 * MINUTE * IN_MILLISECONDS); - if (configNoReload(reload, CONFIG_UINT32_PORT_WORLD, "WorldServerPort", DEFAULT_WORLDSERVER_PORT)) + if (configNoReload(reload, CONFIG_UINT32_PORT_WORLD, "WorldServerPort", 8085)) { - setConfig(CONFIG_UINT32_PORT_WORLD, "WorldServerPort", DEFAULT_WORLDSERVER_PORT); + setConfig(CONFIG_UINT32_PORT_WORLD, "WorldServerPort", 8085); } if (configNoReload(reload, CONFIG_UINT32_GAME_TYPE, "GameType", 0)) diff --git a/src/game/WorldHandlers/WorldSessionMgr.cpp b/src/game/WorldHandlers/WorldSessionMgr.cpp index de8bd55ce..dfc9cdb29 100644 --- a/src/game/WorldHandlers/WorldSessionMgr.cpp +++ b/src/game/WorldHandlers/WorldSessionMgr.cpp @@ -90,10 +90,8 @@ #include "DisableMgr.h" #include "Language.h" #include "CommandMgr.h" -#include "GitRevision.h" #include "UpdateTime.h" #include "GameTime.h" -#include "SystemConfig.h" #include "AuctionHouseBot/AuctionIntentExecutor.h" #include "AuctionHouseBot/CustodyLedger.h" #include "AuctionHouseBot/CustodyService.h" diff --git a/src/genrev/CMakeLists.txt b/src/genrev/CMakeLists.txt deleted file mode 100644 index eb85fed8a..000000000 --- a/src/genrev/CMakeLists.txt +++ /dev/null @@ -1,82 +0,0 @@ -# SPDX-License-Identifier: GPL-3.0-or-later -# -# MaNGOS is a full featured server for World of Warcraft, supporting -# the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8 -# -# Copyright (C) 2005-2026 MaNGOS -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# ============================================================================= -# revision_data.h -- the git revision baked into the binaries. -# -# The header is produced at configure time by cmake/GenRevision.cmake, which the -# top-level CMakeLists.txt includes. This target exists only to refresh it when -# the repository moves underneath an already-configured build tree. -# -# What it replaces: -# -# add_custom_target(revision_data.h ALL COMMAND cmake -P GenRevision.cmake) -# -# That ran on *every* build -- forking a second CMake process and half a dozen -# git processes each time -- to recompute a value that changes only when someone -# commits. Two further consequences, both silent: -# -# - In `cmake -P` script mode there is no cache, so the guards inside -# GenRevision.cmake (which compare against CACHE INTERNAL variables) were -# never satisfied and the whole body ran every time. -# - In script mode CMAKE_CURRENT_BINARY_DIR is the working directory, which -# that target pointed at the SOURCE tree, so every build wrote a generated -# header into the checkout. The .gitignore entry for it was the symptom -# being managed instead of the cause being fixed. -# -# DEPENDS on .git/HEAD and .git/index is what makes this cheap: HEAD moves on -# checkout and commit, index moves on staging, so the regeneration fires exactly -# when the revision can have changed and never otherwise. -# ============================================================================= - -if(WITHOUT_GIT OR NOT IS_DIRECTORY "${CMAKE_SOURCE_DIR}/.git") - return() -endif() - -set(REVISION_HEADER "${CMAKE_BINARY_DIR}/src/shared/revision_data.h") - -set(GIT_STATE_FILES) -foreach(state HEAD index) - if(EXISTS "${CMAKE_SOURCE_DIR}/.git/${state}") - list(APPEND GIT_STATE_FILES "${CMAKE_SOURCE_DIR}/.git/${state}") - endif() -endforeach() - -if(NOT GIT_STATE_FILES) - return() -endif() - -add_custom_command( - OUTPUT "${REVISION_HEADER}" - COMMAND "${CMAKE_COMMAND}" - -DBUILDDIR=${CMAKE_BINARY_DIR} - -DCMAKE_SOURCE_DIR=${CMAKE_SOURCE_DIR} - -DSCRIPT_LIB_ELUNA=${SCRIPT_LIB_ELUNA} - -DSCRIPT_LIB_SD3=${SCRIPT_LIB_SD3} - -DGIT_EXECUTABLE=${GIT_EXECUTABLE} - -P "${CMAKE_SOURCE_DIR}/cmake/GenRevision.cmake" - DEPENDS ${GIT_STATE_FILES} - "${CMAKE_SOURCE_DIR}/src/shared/revision_data.h.in" - WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" - COMMENT "Refreshing revision_data.h (repository HEAD moved)" - VERBATIM -) - -add_custom_target(revision_data ALL DEPENDS "${REVISION_HEADER}") diff --git a/src/mangosd/CMakeLists.txt b/src/mangosd/CMakeLists.txt index 8c06850bf..eeaea6b41 100644 --- a/src/mangosd/CMakeLists.txt +++ b/src/mangosd/CMakeLists.txt @@ -53,7 +53,7 @@ if(WIN32) set(PRODUCT_NAME "mangosd.exe") set(PRODUCT_ICON ${CMAKE_CURRENT_SOURCE_DIR}/mangosd.ico) set(PRODUCT_DESCRIPTION "${MANGOS_PKG} World Server") - configure_file(${CMAKE_SOURCE_DIR}/cmake/win/VersionInfo.h.in ${CMAKE_CURRENT_BINARY_DIR}/VersionInfo.h) + mangos_configure(${CMAKE_SOURCE_DIR}/cmake/win/VersionInfo.h.in ${CMAKE_CURRENT_BINARY_DIR}/VersionInfo.h) endif() @@ -93,11 +93,7 @@ install( DESTINATION ${BIN_DIR} ) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/mangosd.conf.dist.in ${CMAKE_CURRENT_BINARY_DIR}/mangosd.conf.dist) -install( - FILES ${CMAKE_CURRENT_BINARY_DIR}/mangosd.conf.dist - DESTINATION ${CONF_INSTALL_DIR} -) +mangos_install_conf(mangosd.conf.dist.in) if(WIN32 AND MSVC) install( diff --git a/src/mangosd/Master.cpp b/src/mangosd/Master.cpp index bb1051341..2f8556179 100644 --- a/src/mangosd/Master.cpp +++ b/src/mangosd/Master.cpp @@ -39,7 +39,7 @@ #include "MangosdTest.h" #include "MapManager.h" #include "Server/WorldNetwork.h" -#include "SystemConfig.h" +#include "Revision.h" #include "Timer.h" #include "World.h" #include "Server/WardenCheckCatalogLoader.h" @@ -122,7 +122,7 @@ namespace char title[128]; snprintf(title, sizeof(title), "%s (%u Players - %u Connections)", - MANGOS_PACKAGENAME, players, connections); + Revision::GetPackageName(), players, connections); std::string newTitle(title); if (s_lastTitle != newTitle) diff --git a/src/mangosd/mangosd.conf.dist.in b/src/mangosd/mangosd.conf.dist.in index f3aba5df4..15bd6ca9c 100644 --- a/src/mangosd/mangosd.conf.dist.in +++ b/src/mangosd/mangosd.conf.dist.in @@ -240,6 +240,14 @@ MaxWhoListReturns = 49 ################################################################################ # WARDEN # +# Warden.Enabled +# Master switch for the Warden anti-cheat. +# 0 = disabled: sessions are admitted with no Warden module, no checks, +# no audit rows and no enforcement; every Warden.* key below is +# ignored. Applies to sessions admitted after the change. +# 1 = enabled +# Default: 1 +# # Warden.EnforcementMode # Response to confirmed Warden violations and protocol failures. # 0 = observe and log only @@ -280,6 +288,7 @@ MaxWhoListReturns = 49 # ################################################################################ +Warden.Enabled = 1 Warden.EnforcementMode = 2 Warden.RequireExactProfile = 1 Warden.CheckIntervalMin = 30 diff --git a/src/mangosd/mangosd.cpp b/src/mangosd/mangosd.cpp index d33d7a745..78e362dc7 100644 --- a/src/mangosd/mangosd.cpp +++ b/src/mangosd/mangosd.cpp @@ -47,10 +47,6 @@ #include "Common/ServerDefines.h" #include #include -#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3) -# include -# include "Auth/OpenSSLProvider.h" -#endif #include "Platform/Define.h" #include @@ -58,11 +54,10 @@ #include #include "Database/DatabaseEnv.h" #include "Config/Config.h" -#include "GitRevision.h" +#include "Revision.h" #include "ProgressBar.h" #include "Console/ConsoleUI.h" #include "Log.h" -#include "SystemConfig.h" #include "AuctionHouseBot.h" #include "Master.h" #include "World.h" @@ -203,7 +198,7 @@ int main(int argc, char** argv) #endif ///- Command line parsing - char const* cfg_file = MANGOSD_CONFIG_LOCATION; + char const* cfg_file = Revision::GetConfigPath(Revision::ConfigFile::Mangosd); char serviceDaemonMode = '\0'; std::string testMode; @@ -218,7 +213,7 @@ int main(int argc, char** argv) if (arg == "-v" || arg == "--version") { - printf("%s\n", GitRevision::GetProjectRevision()); + printf("%s\n", Revision::GetProjectRevision()); return 0; } else if ((arg == "-c") && hasValue) @@ -294,14 +289,14 @@ int main(int argc, char** argv) #endif if (!sConfig.SetSource(cfg_file)) { - // Try current folder as fallback if SYSCONFDIR path fails - if (!sConfig.SetSource(MANGOSD_CONFIG_NAME)) + // Try current folder as fallback if the configured path fails + if (!sConfig.SetSource(Revision::GetConfigName(Revision::ConfigFile::Mangosd))) { sLog.outError("Could not find configuration file %s.", cfg_file); Log::WaitBeforeContinueIfNeed(); return 1; } - cfg_file = MANGOSD_CONFIG_NAME; + cfg_file = Revision::GetConfigName(Revision::ConfigFile::Mangosd); } #ifndef _WIN32 @@ -316,29 +311,15 @@ int main(int argc, char** argv) } #endif - sLog.outString("%s [world-daemon]", GitRevision::GetProjectRevision()); - sLog.outString("%s", GitRevision::GetFullRevision()); - sLog.outString("%s", GitRevision::GetDepElunaFullRevisionStr()); - sLog.outString("%s", GitRevision::GetDepSD3FullRevisionStr()); + sLog.outString("%s [world-daemon]", Revision::GetProjectRevision()); + sLog.outString("%s", Revision::GetFullRevision()); + sLog.outString("Eluna submodule revision: %s", Revision::GetElunaRevisionStr()); + sLog.outString("SD3 submodule revision: %s", Revision::GetSD3RevisionStr()); print_banner(); sLog.outString("Using configuration file %s.", cfg_file); DETAIL_LOG("Using SSL version: %s (Library: %s)", OPENSSL_VERSION_TEXT, OpenSSL_version(OPENSSL_VERSION)); -#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3) - if (!OpenSSLProviderManager::Instance().IsInitialized()) - { - Log::WaitBeforeContinueIfNeed(); - return 1; - } -#else - if (SSLeay() < 0x10100000L || SSLeay() > 0x10200000L) - { - DETAIL_LOG("WARNING: OpenSSL version may be out of date or unsupported. Logins to server may not work!"); - DETAIL_LOG("WARNING: Minimal required version [OpenSSL 1.1.x] and Maximum supported version [OpenSSL 1.2]"); - } -#endif - ///- Set progress bars show mode BarGoLink::SetOutputState(sConfig.GetBoolDefault("ShowProgressBars", true)); diff --git a/src/modules/AhWorker/CMakeLists.txt b/src/modules/AhWorker/CMakeLists.txt index fa314178a..b12dc0325 100644 --- a/src/modules/AhWorker/CMakeLists.txt +++ b/src/modules/AhWorker/CMakeLists.txt @@ -26,10 +26,7 @@ target_link_libraries(ah_usability PUBLIC ah_ipc) # BrowseMessages.h / Common. add_executable(ah-service ${ah_service_SRC} ${ah_service_platform_SRC}) target_link_libraries(ah-service PRIVATE ah_usability ah_ipc shared Threads::Threads) install(TARGETS ah-service DESTINATION ${BIN_DIR}/service-workers/ah-service) -# Substitute @MANGOS_AHBOT_VER@ (the ConfVersion) like mangosd.conf, then -# install the generated file (a raw copy would leave the placeholder literal). -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ah-service.conf.dist.in ${CMAKE_CURRENT_BINARY_DIR}/ah-service.conf.dist) -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/ah-service.conf.dist DESTINATION ${CONF_INSTALL_DIR}) +mangos_install_conf(ah-service.conf.dist.in) # The CanUseItem differential drift test needs BOTH ah_usability (this worker) # and the game-side AhUsabilityRef source, so it builds only when mangosd is in diff --git a/src/modules/AhWorker/ServiceConfig.cpp b/src/modules/AhWorker/ServiceConfig.cpp index 428af3502..4dfd1fc47 100644 --- a/src/modules/AhWorker/ServiceConfig.cpp +++ b/src/modules/AhWorker/ServiceConfig.cpp @@ -23,7 +23,7 @@ #include #include "ServiceConfig.h" #include "Log/Log.h" -#include "SystemConfig.h" +#include "Revision.h" #include @@ -40,13 +40,13 @@ bool ServiceConfig::Initialize() { // The ahbot.conf path comes from the already-loaded ah-service.conf. std::string cfgPath = sConfig.GetStringDefault( - "AhBot.ConfigPath", AUCTIONHOUSEBOT_CONFIG_NAME); + "AhBot.ConfigPath", Revision::GetConfigName(Revision::ConfigFile::AhBot)); if (!m_botCfg.SetSource(cfgPath.c_str())) { // Try a bare "ahbot.conf" in the current folder as a fallback, // mirroring AuctionBotConfig::Initialize(). - if (!m_botCfg.SetSource(AUCTIONHOUSEBOT_CONFIG_NAME)) + if (!m_botCfg.SetSource(Revision::GetConfigName(Revision::ConfigFile::AhBot))) { sLog.outError("ah-service: unable to open AH bot configuration" " file '%s'", cfgPath.c_str()); @@ -67,11 +67,11 @@ bool ServiceConfig::Reload() { // Re-open the same path that Initialize() used. std::string cfgPath = sConfig.GetStringDefault( - "AhBot.ConfigPath", AUCTIONHOUSEBOT_CONFIG_NAME); + "AhBot.ConfigPath", Revision::GetConfigName(Revision::ConfigFile::AhBot)); if (!m_botCfg.SetSource(cfgPath.c_str())) { - if (!m_botCfg.SetSource(AUCTIONHOUSEBOT_CONFIG_NAME)) + if (!m_botCfg.SetSource(Revision::GetConfigName(Revision::ConfigFile::AhBot))) { sLog.outError("ah-service: Reload: unable to re-open AH bot" " configuration file '%s'", cfgPath.c_str()); @@ -141,7 +141,7 @@ void ServiceConfig::setConfig(AhBotConfigBoolValues index, void ServiceConfig::GetConfigFromFile() { // Check config file version. - if (m_botCfg.GetIntDefault("ConfVersion", 0) != AHBOT_CONFIG_VERSION) + if (uint32(m_botCfg.GetIntDefault("ConfVersion", 0)) != Revision::GetConfigVersion(Revision::ConfigFile::AhBot)) { sLog.outError("AHBot: Configuration file version doesn't match" " expected version. Some config variables may be wrong" @@ -150,7 +150,7 @@ void ServiceConfig::GetConfigFromFile() // The ah-service infra config (sConfig / ah-service.conf) shares the // AHBot conf version; warn if it is stale too. - if (sConfig.GetIntDefault("ConfVersion", 0) != AHBOT_CONFIG_VERSION) + if (uint32(sConfig.GetIntDefault("ConfVersion", 0)) != Revision::GetConfigVersion(Revision::ConfigFile::AhBot)) { sLog.outError("AH-service: ah-service.conf version doesn't match the" " expected version. Some config variables may be wrong" diff --git a/src/modules/Bots/ahbot/AhBotConfig.cpp b/src/modules/Bots/ahbot/AhBotConfig.cpp index a6ccd2849..9c4b2a946 100644 --- a/src/modules/Bots/ahbot/AhBotConfig.cpp +++ b/src/modules/Bots/ahbot/AhBotConfig.cpp @@ -2,7 +2,7 @@ #include #include "../botpch.h" #include "AhBotConfig.h" -#include "SystemConfig.h" +#include "Revision.h" std::vector split(const std::string &s, char delim); using namespace std; @@ -31,7 +31,7 @@ template bool AhBotConfig::Initialize() { - if (!config.SetSource(AUCTIONHOUSEBOT_CONFIG_NAME)) + if (!config.SetSource(Revision::GetConfigName(Revision::ConfigFile::AhBot))) { // Try current folder as fallback if (!config.SetSource("ahbot.conf")) diff --git a/src/modules/Bots/playerbot/PlayerbotAIConfig.cpp b/src/modules/Bots/playerbot/PlayerbotAIConfig.cpp index 91aa3a4a3..f440c02ad 100644 --- a/src/modules/Bots/playerbot/PlayerbotAIConfig.cpp +++ b/src/modules/Bots/playerbot/PlayerbotAIConfig.cpp @@ -7,7 +7,7 @@ #include "RandomPlayerbotFactory.h" #include "RandomBotClassPolicy.h" #include "AccountMgr.h" -#include "SystemConfig.h" +#include "Revision.h" using namespace std; @@ -117,10 +117,10 @@ bool PlayerbotAIConfig::Initialize() { sLog.outString("Initializing AI Playerbot by ike3, based on the original Playerbot by blueboy"); - if (!config.SetSource(SYSCONFDIR"aiplayerbot.conf")) + if (!config.SetSource(Revision::GetConfigPath(Revision::ConfigFile::Playerbot))) { // Try current folder as fallback - if (!config.SetSource("aiplayerbot.conf")) + if (!config.SetSource(Revision::GetConfigName(Revision::ConfigFile::Playerbot))) { sLog.outString("AI Playerbot is Disabled. Unable to open configuration file aiplayerbot.conf"); return false; diff --git a/src/modules/Bots/playerbot/RandomPlayerbotFactory.cpp b/src/modules/Bots/playerbot/RandomPlayerbotFactory.cpp index 9a093e7d8..58d3246cd 100644 --- a/src/modules/Bots/playerbot/RandomPlayerbotFactory.cpp +++ b/src/modules/Bots/playerbot/RandomPlayerbotFactory.cpp @@ -11,7 +11,6 @@ #include "Player.h" #include "RandomBotClassPolicy.h" #include "RandomPlayerbotFactory.h" -#include "SystemConfig.h" /** * A static map that stores the available races for each class. diff --git a/src/modules/Bots/playerbot/aiplayerbot.conf.dist.in b/src/modules/Bots/playerbot/aiplayerbot.conf.dist.in index ff0049024..604855257 100644 --- a/src/modules/Bots/playerbot/aiplayerbot.conf.dist.in +++ b/src/modules/Bots/playerbot/aiplayerbot.conf.dist.in @@ -3,7 +3,7 @@ ########################################## [AiPlayerbotConf] -ConfVersion=2026080700 +ConfVersion=@MANGOS_PLAYERBOT_VER@ # Enable or disable AI Playerbot AiPlayerbot.Enabled = 1 diff --git a/src/modules/CMakeLists.txt b/src/modules/CMakeLists.txt index 4561cadfc..dc115f98b 100644 --- a/src/modules/CMakeLists.txt +++ b/src/modules/CMakeLists.txt @@ -25,6 +25,9 @@ if(BUILD_MANGOSD AND SCRIPT_LIB_SD3) add_subdirectory(SD3) mangos_submodule_compat(mangosscript "${CMAKE_SOURCE_DIR}/src/shared/Compat/sd3") + # SD3 still includes SystemConfig.h by that name. + mangos_submodule_compat(mangosscript + "${CMAKE_SOURCE_DIR}/src/shared/Compat/revision") endif() if(BUILD_MANGOSD AND SCRIPT_LIB_ELUNA) diff --git a/src/shared/.gitignore b/src/shared/.gitignore index 1c62b5c23..d00871c4f 100644 --- a/src/shared/.gitignore +++ b/src/shared/.gitignore @@ -10,4 +10,3 @@ # MaNGOS generated files # -SystemConfig.h diff --git a/src/shared/Auth/ARC4.cpp b/src/shared/Auth/ARC4.cpp deleted file mode 100644 index 59b077594..000000000 --- a/src/shared/Auth/ARC4.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/** - * SPDX-License-Identifier: GPL-3.0-or-later - * - * MaNGOS is a full featured server for World of Warcraft, supporting - * the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8 - * - * Copyright (C) 2005-2026 MaNGOS - * Copyright (C) 2008-2015 TrinityCore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * World of Warcraft, and all World of Warcraft or Warcraft art, images, - * and lore are copyrighted by Blizzard Entertainment, Inc. - */ - -/** - * @file ARC4.cpp - * @brief Implementation of ARC4 encryption algorithm using OpenSSL - * - * This file implements the ARC4 (Alleged RC4) stream cipher for use - * in the MaNGOS authentication and session encryption system. ARC4 - * is used to encrypt/decrypt game traffic between the server and clients. - * - * The implementation uses OpenSSL's EVP interface for the cipher operations - * and includes proper provider management for OpenSSL 3.x compatibility. - */ - -#include "ARC4.h" -#include "OpenSSLProvider.h" -#include "Log/Log.h" -#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3) -#include -#endif - -/** - * @brief Construct ARC4 cipher with specified key length - * @param len Key length in bytes - * - * Creates an ARC4 cipher context with the specified key length. - * The key itself is not set in this constructor - use Init() to set it. - * - * @note On OpenSSL 3.x, this automatically initializes the legacy provider - * required for ARC4 support. - */ -ARC4::ARC4(uint8 len) : m_cipherContext() -{ -#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3) - // RC4 lives in the legacy provider, so it has to be loaded before EVP_rc4(). - if (!OpenSSLProviderManager::Instance().IsInitialized()) - { - sLog.outError("ARC4: Failed to initialize OpenSSL providers"); - return; - } -#endif - - if (!m_cipherContext.IsValid()) - { - sLog.outError("ARC4: Failed to create cipher context"); - return; - } - - // Checked, not assumed: a loaded provider does not mean the cipher was fetched. - if (EVP_EncryptInit_ex(m_cipherContext.Get(), EVP_rc4(), NULL, NULL, NULL) != 1) - { - sLog.outError("ARC4: Failed to initialize RC4 - is the OpenSSL legacy provider loaded?"); - return; - } - - if (EVP_CIPHER_CTX_set_key_length(m_cipherContext.Get(), len) != 1) - { - sLog.outError("ARC4: Failed to set the RC4 key length"); - return; - } -} - -/** - * @brief Construct ARC4 cipher with initial key - * @param seed Pointer to the key bytes - * @param len Length of the key in bytes - * - * Creates an ARC4 cipher context and initializes it with the provided key. - * The cipher is ready to use for encryption/decryption immediately after - * construction. - * - * @note On OpenSSL 3.x, this automatically initializes the legacy provider - * required for ARC4 support. - */ -ARC4::ARC4(uint8 *seed, uint8 len) : m_cipherContext() -{ -#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3) - // RC4 lives in the legacy provider, so it has to be loaded before EVP_rc4(). - if (!OpenSSLProviderManager::Instance().IsInitialized()) - { - sLog.outError("ARC4: Failed to initialize OpenSSL providers"); - return; - } -#endif - - if (!m_cipherContext.IsValid()) - { - sLog.outError("ARC4: Failed to create cipher context"); - return; - } - - // Checked, not assumed: a loaded provider does not mean the cipher was fetched. - if (EVP_EncryptInit_ex(m_cipherContext.Get(), EVP_rc4(), NULL, NULL, NULL) != 1) - { - sLog.outError("ARC4: Failed to initialize RC4 - is the OpenSSL legacy provider loaded?"); - return; - } - - if (EVP_CIPHER_CTX_set_key_length(m_cipherContext.Get(), len) != 1) - { - sLog.outError("ARC4: Failed to set the RC4 key length"); - return; - } - - if (EVP_EncryptInit_ex(m_cipherContext.Get(), NULL, NULL, seed, NULL) != 1) - { - sLog.outError("ARC4: Failed to seed RC4"); - } -} - -/** - * @brief Destructor for ARC4 cipher - * - * All cleanup is handled automatically by the RAII wrappers - * (OpenSSLProviderManager and OpenSSLCipherContext). - */ -ARC4::~ARC4() -{ - // Cleanup is now handled automatically by RAII wrappers -} - -/** - * @brief Initialize or re-initialize the cipher with a new key - * @param seed Pointer to the key bytes - * - * Sets or changes the encryption key for the ARC4 cipher. - * This can be called multiple times to re-key the cipher. - * - * @note The key length must match the length specified in the constructor. - */ -void ARC4::Init(uint8 *seed) -{ - if (m_cipherContext.IsValid()) - { - EVP_EncryptInit_ex(m_cipherContext.Get(), NULL, NULL, seed, NULL); - } -} - -/** - * @brief Encrypt or decrypt data in-place - * @param len Length of data to process in bytes - * @param data Pointer to the data buffer (modified in-place) - * - * Processes data using the ARC4 stream cipher. Since ARC4 is a symmetric - * stream cipher, the same operation is used for both encryption and - * decryption. The data is modified in-place for efficiency. - * - * @warning The cipher must be initialized with a key before calling this. - * @note The output length will always equal the input length for ARC4. - */ -void ARC4::UpdateData(int len, uint8 *data) -{ - if (!m_cipherContext.IsValid()) - { - sLog.outError("ARC4: Invalid cipher context, cannot update data"); - return; - } - - int outlen = 0; - EVP_EncryptUpdate(m_cipherContext.Get(), data, &outlen, data, len); - EVP_EncryptFinal_ex(m_cipherContext.Get(), data, &outlen); -} diff --git a/src/shared/Auth/ARC4.h b/src/shared/Auth/ARC4.h deleted file mode 100644 index 87a8bc02e..000000000 --- a/src/shared/Auth/ARC4.h +++ /dev/null @@ -1,73 +0,0 @@ -/** - * SPDX-License-Identifier: GPL-3.0-or-later - * - * MaNGOS is a full featured server for World of Warcraft, supporting - * the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8 - * - * Copyright (C) 2005-2026 MaNGOS - * Copyright (C) 2008-2015 TrinityCore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * World of Warcraft, and all World of Warcraft or Warcraft art, images, - * and lore are copyrighted by Blizzard Entertainment, Inc. - */ - -#ifndef _AUTH_SARC4_H -#define _AUTH_SARC4_H - -#include -#include "Platform/Define.h" -#include "OpenSSLProvider.h" - -/** - * @brief ARC4 encryption/decryption cipher implementation - * - * ARC4 is a stream cipher that uses a key to generate a keystream. - * This class provides ARC4 encryption and decryption functionality using OpenSSL. - */ -class ARC4 -{ - public: - /** - * @brief Constructor with key length specification - * @param len Length of the key in bytes - */ - ARC4(uint8 len); - /** - * @brief Constructor with seed data - * @param seed Pointer to the seed/key data - * @param len Length of the seed data in bytes - */ - ARC4(uint8 *seed, uint8 len); - /** - * @brief Destructor - */ - ~ARC4(); - /** - * @brief Initialize the cipher with seed data - * @param seed Pointer to the seed/key data - */ - void Init(uint8 *seed); - /** - * @brief Update/encrypt data using the cipher - * @param len Length of the data to process - * @param data Pointer to the data to encrypt/decrypt - */ - void UpdateData(int len, uint8 *data); - private: - OpenSSLCipherContext m_cipherContext; /**< RAII cipher context */ -}; - -#endif diff --git a/src/shared/Auth/OpenSSLProvider.cpp b/src/shared/Auth/OpenSSLProvider.cpp deleted file mode 100644 index babe88fda..000000000 --- a/src/shared/Auth/OpenSSLProvider.cpp +++ /dev/null @@ -1,453 +0,0 @@ -/** - * SPDX-License-Identifier: GPL-3.0-or-later - * - * MaNGOS is a full featured server for World of Warcraft, supporting - * the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8 - * - * Copyright (C) 2005-2026 MaNGOS - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * World of Warcraft, and all World of Warcraft or Warcraft art, images, - * and lore are copyrighted by Blizzard Entertainment, Inc. - */ - -/** - * @file OpenSSLProvider.cpp - * @brief Implementation of RAII wrappers for OpenSSL providers - */ - -#include -#include "OpenSSLProvider.h" -#include "Log/Log.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef WIN32 -#include -#endif - -/** - * Creates a new OpenSSL cipher context wrapper. - */ -OpenSSLCipherContext::OpenSSLCipherContext() - : m_ctx(nullptr) -{ - m_ctx = EVP_CIPHER_CTX_new(); - if (!m_ctx) - { - sLog.outError("OpenSSLCipherContext: Failed to create cipher context"); - } -} - -/** - * Releases the owned OpenSSL cipher context. - */ -OpenSSLCipherContext::~OpenSSLCipherContext() -{ - if (m_ctx) - { - EVP_CIPHER_CTX_free(m_ctx); - m_ctx = nullptr; - } -} - -OpenSSLCipherContext::OpenSSLCipherContext(OpenSSLCipherContext&& other) noexcept - : m_ctx(other.m_ctx) -{ - other.m_ctx = nullptr; -} - -OpenSSLCipherContext& OpenSSLCipherContext::operator=(OpenSSLCipherContext&& other) noexcept -{ - if (this != &other) - { - // Clean up current context - if (m_ctx) - { - EVP_CIPHER_CTX_free(m_ctx); - } - - // Move from other - m_ctx = other.m_ctx; - other.m_ctx = nullptr; - } - return *this; -} - -#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3) - -namespace -{ -bool ParseProviderMajor(const std::string& version, unsigned& major) -{ - std::size_t separator = version.find('.'); - if (separator == std::string::npos || separator == 0) - return false; - - const char* begin = version.data(); - const char* end = begin + separator; - std::from_chars_result parsed = - std::from_chars(begin, end, major); - return parsed.ec == std::errc{} && parsed.ptr == end; -} - -#ifdef WIN32 -std::wstring ReadWindowsEnvironment(const wchar_t* name) -{ - DWORD required = GetEnvironmentVariableW(name, nullptr, 0); - if (required == 0) - return {}; - - std::vector buffer(required); - while (true) - { - DWORD written = GetEnvironmentVariableW( - name, buffer.data(), static_cast(buffer.size())); - if (written == 0) - return {}; - if (written < buffer.size()) - return std::wstring(buffer.data(), written); - buffer.resize(static_cast(written) + 1); - } -} - -std::filesystem::path GetExecutableDirectory() -{ - constexpr std::size_t MAX_WINDOWS_PATH = 32768; - std::vector buffer(MAX_PATH); - - while (buffer.size() <= MAX_WINDOWS_PATH) - { - DWORD written = GetModuleFileNameW( - nullptr, buffer.data(), static_cast(buffer.size())); - if (written == 0) - return {}; - if (written < buffer.size()) - { - return std::filesystem::path( - std::wstring(buffer.data(), written)).parent_path(); - } - - if (buffer.size() == MAX_WINDOWS_PATH) - break; - buffer.resize((std::min)(buffer.size() * 2, MAX_WINDOWS_PATH)); - } - - return {}; -} - -bool ConvertWideToAnsi(const std::wstring& value, std::string& converted) -{ - converted.clear(); - if (value.empty()) - return false; - - constexpr UINT GB18030_CODE_PAGE = 54936; - UINT const codePage = GetACP(); - bool const restrictedCodePage = - codePage == CP_UTF8 || codePage == GB18030_CODE_PAGE; - DWORD const flags = restrictedCodePage ? - WC_ERR_INVALID_CHARS : WC_NO_BEST_FIT_CHARS; - BOOL usedDefault = FALSE; - BOOL* usedDefaultPointer = restrictedCodePage ? nullptr : &usedDefault; - int required = WideCharToMultiByte( - codePage, flags, value.c_str(), -1, - nullptr, 0, nullptr, usedDefaultPointer); - if (required <= 0 || usedDefault) - return false; - - std::vector buffer(static_cast(required)); - usedDefault = FALSE; - int written = WideCharToMultiByte( - codePage, flags, value.c_str(), -1, - buffer.data(), required, nullptr, usedDefaultPointer); - if (written <= 0 || usedDefault) - return false; - - converted.assign(buffer.data(), static_cast(written - 1)); - return true; -} - -bool IsUsableOpenSSLPath(const std::wstring& path, std::string& converted) -{ - if (!ConvertWideToAnsi(path, converted)) - return false; - - constexpr std::size_t LEGACY_SUFFIX_LENGTH = sizeof("\\legacy.dll") - 1; - return converted.size() + LEGACY_SUFFIX_LENGTH < MAX_PATH; -} - -bool ConvertForOpenSSL( - const std::filesystem::path& directory, std::string& converted) -{ - const std::wstring& nativePath = directory.native(); - if (IsUsableOpenSSLPath(nativePath, converted)) - return true; - - DWORD required = GetShortPathNameW(nativePath.c_str(), nullptr, 0); - if (required == 0) - return false; - - std::vector shortPath(required); - DWORD written = GetShortPathNameW( - nativePath.c_str(), shortPath.data(), required); - if (written == 0 || written >= shortPath.size()) - return false; - - return IsUsableOpenSSLPath( - std::wstring(shortPath.data(), written), converted); -} - -void ConfigureBundledProviderSearchPath() -{ - if (!ReadWindowsEnvironment(L"OPENSSL_MODULES").empty()) - return; - - try - { - std::filesystem::path executableDirectory = GetExecutableDirectory(); - if (executableDirectory.empty()) - { - sLog.outError( - "OpenSSLProvider: Failed to resolve the executable directory"); - return; - } - - std::filesystem::path providerDirectory = - executableDirectory / L"ossl-modules"; - std::filesystem::path legacyProvider = - providerDirectory / L"legacy.dll"; - std::error_code fileError; - if (!std::filesystem::is_regular_file(legacyProvider, fileError)) - return; - - std::string providerPath; - if (!ConvertForOpenSSL(providerDirectory, providerPath)) - { - sLog.outError( - "OpenSSLProvider: Bundled provider path cannot be represented " - "for the OpenSSL Windows loader"); - return; - } - - if (OSSL_PROVIDER_set_default_search_path( - nullptr, providerPath.c_str()) != 1) - { - sLog.outError( - "OpenSSLProvider: Failed to configure bundled provider path '%s'", - providerPath.c_str()); - } - } - catch (const std::filesystem::filesystem_error& error) - { - sLog.outError( - "OpenSSLProvider: Failed to inspect bundled provider path: %s", - error.what()); - } -} -#endif - -OpenSSLProvider LoadLegacyProvider() -{ -#ifdef WIN32 - ConfigureBundledProviderSearchPath(); -#endif - return OpenSSLProvider("legacy"); -} - -std::string OpenSSLModulesForDiagnostic() -{ -#ifdef WIN32 - std::wstring modules = ReadWindowsEnvironment(L"OPENSSL_MODULES"); - if (modules.empty()) - return ""; - - std::string converted; - return ConvertWideToAnsi(modules, converted) - ? converted : ""; -#else - const char* modules = std::getenv("OPENSSL_MODULES"); - return modules ? std::string(modules) : std::string(""); -#endif -} -} - -/** - * Loads the named OpenSSL provider into the specified library context. - */ -OpenSSLProvider::OpenSSLProvider(const char* name, OSSL_LIB_CTX* libraryContext) - : m_provider(nullptr), m_providerName(name ? name : "") -{ - if (!name) - { - sLog.outError("OpenSSLProvider: Provider name cannot be null"); - return; - } - - m_provider = OSSL_PROVIDER_load(libraryContext, name); - if (!m_provider) - { - sLog.outError("OpenSSLProvider: Failed to load provider '%s'", name); - } -} - -/** - * Unloads the owned OpenSSL provider instance. - */ -OpenSSLProvider::~OpenSSLProvider() -{ - if (m_provider) - { - OSSL_PROVIDER_unload(m_provider); - m_provider = nullptr; - } -} - -std::string OpenSSLProvider::Version() const -{ - if (!m_provider) - return {}; - - char* version = nullptr; - OSSL_PARAM params[] = { - OSSL_PARAM_construct_utf8_ptr( - OSSL_PROV_PARAM_VERSION, &version, 0), - OSSL_PARAM_construct_end() - }; - if (OSSL_PROVIDER_get_params(m_provider, params) != 1 || !version) - return {}; - return version; -} - -OpenSSLProvider::OpenSSLProvider(OpenSSLProvider&& other) noexcept - : m_provider(other.m_provider), m_providerName(std::move(other.m_providerName)) -{ - other.m_provider = nullptr; -} - -OpenSSLProvider& OpenSSLProvider::operator=(OpenSSLProvider&& other) noexcept -{ - if (this != &other) - { - // Clean up current provider - if (m_provider) - { - OSSL_PROVIDER_unload(m_provider); - } - - // Move from other - m_provider = other.m_provider; - m_providerName = std::move(other.m_providerName); - other.m_provider = nullptr; - } - return *this; -} - -/** - * Initializes the OpenSSL provider manager and loads required providers. - */ -OpenSSLProviderManager::OpenSSLProviderManager() - : m_legacyProvider(LoadLegacyProvider()), - m_defaultProvider("default"), - m_initialized(false) -{ - if (!m_legacyProvider.IsLoaded() || !m_defaultProvider.IsLoaded()) - { - sLog.outError("Failed to load OpenSSL 3.x providers"); - - if (!m_legacyProvider.IsLoaded()) - { - sLog.outError(" - Legacy provider failed to load"); -#ifdef WIN32 - sLog.outError(" Use a complete release with ossl-modules\\legacy.dll"); - sLog.outError(" beside the daemon, or set OPENSSL_MODULES to the"); - sLog.outError(" directory containing a matching legacy.dll."); -#endif - } - - if (!m_defaultProvider.IsLoaded()) - { - sLog.outError(" - Default provider failed to load"); - } - return; - } - - std::string legacyVersion = m_legacyProvider.Version(); - std::string defaultVersion = m_defaultProvider.Version(); - unsigned legacyMajor = 0; - unsigned defaultMajor = 0; - bool parsedLegacy = - ParseProviderMajor(legacyVersion, legacyMajor); - bool parsedDefault = - ParseProviderMajor(defaultVersion, defaultMajor); - - unsigned runtimeMajor = - unsigned((OpenSSL_version_num() >> 28) & 0x0f); - if (runtimeMajor != 3 - || !parsedLegacy || legacyMajor != runtimeMajor - || !parsedDefault || defaultMajor != runtimeMajor) - { - std::string modules = OpenSSLModulesForDiagnostic(); - sLog.outError( - "OpenSSL 3.x provider/runtime validation failed: " - "runtime='%s', legacy provider='%s', default provider='%s', " - "OPENSSL_MODULES='%s'", - OpenSSL_version(OPENSSL_VERSION), - legacyVersion.empty() ? "" : legacyVersion.c_str(), - defaultVersion.empty() ? "" : defaultVersion.c_str(), - modules.c_str()); - return; - } - - EVP_CIPHER* rc4 = EVP_CIPHER_fetch(nullptr, "RC4", nullptr); - if (!rc4) - { - sLog.outError( - "OpenSSL legacy provider is loaded but RC4 is unavailable"); - return; - } - EVP_CIPHER_free(rc4); - - m_initialized = true; - sLog.outString( - "OpenSSL 3.x providers loaded successfully: legacy %s, default %s", - legacyVersion.c_str(), defaultVersion.c_str()); -} - -OpenSSLProviderManager& OpenSSLProviderManager::Instance() -{ - static OpenSSLProviderManager instance; - return instance; -} - -/** - * Logs provider shutdown when the OpenSSL provider manager is destroyed. - */ -OpenSSLProviderManager::~OpenSSLProviderManager() -{ - if (m_initialized) - { - sLog.outString("OpenSSL 3.x providers unloaded"); - } -} - -#endif // OPENSSL_VERSION_MAJOR >= 3 diff --git a/src/shared/Auth/OpenSSLProvider.h b/src/shared/Auth/OpenSSLProvider.h deleted file mode 100644 index bc4ad7e70..000000000 --- a/src/shared/Auth/OpenSSLProvider.h +++ /dev/null @@ -1,206 +0,0 @@ -/** - * SPDX-License-Identifier: GPL-3.0-or-later - * - * MaNGOS is a full featured server for World of Warcraft, supporting - * the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8 - * - * Copyright (C) 2005-2026 MaNGOS - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * World of Warcraft, and all World of Warcraft or Warcraft art, images, - * and lore are copyrighted by Blizzard Entertainment, Inc. - */ - -/** - * @file OpenSSLProvider.h - * @brief RAII wrapper for OpenSSL 3.x providers - * - * This file provides RAII wrappers for OpenSSL provider management, - * ensuring proper cleanup and exception safety for OpenSSL 3.x - * provider loading and unloading. - */ - -#ifndef _AUTH_OPENSSL_PROVIDER_H -#define _AUTH_OPENSSL_PROVIDER_H - -#include -#include - -/** - * @brief RAII wrapper for EVP_CIPHER_CTX - * - * This class manages EVP_CIPHER_CTX lifecycle with proper - * initialization and cleanup, preventing memory leaks. - */ -class OpenSSLCipherContext -{ -public: - /** - * @brief Constructor - creates new cipher context - */ - OpenSSLCipherContext(); - - /** - * @brief Destructor - automatically frees context - */ - ~OpenSSLCipherContext(); - - /** - * @brief Get the underlying cipher context - * @return EVP_CIPHER_CTX pointer - */ - EVP_CIPHER_CTX* Get() const { return m_ctx; } - - /** - * @brief Check if context is valid - * @return true if context is valid, false otherwise - */ - bool IsValid() const { return m_ctx != nullptr; } - - /** - * @brief Move constructor - */ - OpenSSLCipherContext(OpenSSLCipherContext&& other) noexcept; - - /** - * @brief Move assignment operator - */ - OpenSSLCipherContext& operator=(OpenSSLCipherContext&& other) noexcept; - - // Delete copy operations - OpenSSLCipherContext(const OpenSSLCipherContext&) = delete; - OpenSSLCipherContext& operator=(const OpenSSLCipherContext&) = delete; - -private: - EVP_CIPHER_CTX* m_ctx; /**< OpenSSL cipher context */ -}; - -#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3) -#include - -/** - * @brief RAII wrapper for OpenSSL 3.x OSSL_PROVIDER - * - * This class automatically loads and unloads OpenSSL providers, - * ensuring proper cleanup when the wrapper goes out of scope. - * It provides exception safety and prevents resource leaks. - */ -class OpenSSLProvider -{ -public: - /** - * @brief Constructor - loads specified provider - * @param name Provider name (e.g., "legacy", "default") - * @param libraryContext Library context (NULL for default) - */ - OpenSSLProvider(const char* name, OSSL_LIB_CTX* libraryContext = nullptr); - - /** - * @brief Destructor - automatically unloads provider - */ - ~OpenSSLProvider(); - - /** - * @brief Check if provider is successfully loaded - * @return true if provider is loaded, false otherwise - */ - bool IsLoaded() const { return m_provider != nullptr; } - - /** - * @brief Get the version reported by the loaded provider - * @return Provider version, or an empty string if unavailable - */ - std::string Version() const; - - /** - * @brief Get the underlying provider handle - * @return OSSL_PROVIDER pointer or nullptr if not loaded - */ - OSSL_PROVIDER* Get() const { return m_provider; } - - /** - * @brief Move constructor - */ - OpenSSLProvider(OpenSSLProvider&& other) noexcept; - - /** - * @brief Move assignment operator - */ - OpenSSLProvider& operator=(OpenSSLProvider&& other) noexcept; - - // Delete copy operations to prevent double-free - OpenSSLProvider(const OpenSSLProvider&) = delete; - OpenSSLProvider& operator=(const OpenSSLProvider&) = delete; - -private: - OSSL_PROVIDER* m_provider; /**< OpenSSL provider handle */ - std::string m_providerName; /**< Provider name for logging */ -}; - -/** - * @brief RAII wrapper for OpenSSL 3.x provider management - * - * This class manages both legacy and default providers for OpenSSL 3.x, - * ensuring they are loaded and unloaded properly. It's designed to be - * used at application startup to handle provider initialization. - */ -class OpenSSLProviderManager -{ -public: - /** - * @brief Constructor - loads legacy and default providers - */ - OpenSSLProviderManager(); - - /** - * @brief Destructor - automatically unloads providers - */ - ~OpenSSLProviderManager(); - - /** - * @brief The one manager for the process - * - * Providers are global to the library, so loading them per object costs an - * OpenSSL-wide lock on every construction and buys nothing. - */ - static OpenSSLProviderManager& Instance(); - - /** - * @brief Check if providers are successfully loaded - * @return true if both providers loaded successfully - */ - bool IsInitialized() const { return m_initialized; } - - /** - * @brief Get legacy provider - * @return Reference to legacy provider - */ - const OpenSSLProvider& GetLegacyProvider() const { return m_legacyProvider; } - - /** - * @brief Get default provider - * @return Reference to default provider - */ - const OpenSSLProvider& GetDefaultProvider() const { return m_defaultProvider; } - -private: - OpenSSLProvider m_legacyProvider; /**< Legacy provider for compatibility */ - OpenSSLProvider m_defaultProvider; /**< Default provider */ - bool m_initialized; /**< Initialization status */ -}; - -#endif // OPENSSL_VERSION_MAJOR >= 3 - -#endif // _AUTH_OPENSSL_PROVIDER_H diff --git a/src/shared/CMakeLists.txt b/src/shared/CMakeLists.txt index a0c375846..af3b2e538 100644 --- a/src/shared/CMakeLists.txt +++ b/src/shared/CMakeLists.txt @@ -21,8 +21,6 @@ include(TestBigEndian) set(SRC_GRP_AUTH - Auth/ARC4.cpp - Auth/ARC4.h Auth/AuthCrypt.cpp Auth/AuthCrypt.h Auth/BigNumber.cpp @@ -30,8 +28,6 @@ set(SRC_GRP_AUTH Auth/HMACSHA1.cpp Auth/HMACSHA1.h Auth/Md5.h - Auth/OpenSSLProvider.cpp - Auth/OpenSSLProvider.h Auth/Sha1.cpp Auth/Sha1.h ) @@ -42,8 +38,8 @@ set(SRC_GRP_COMMON Common/Locales.h Common/TimeConstants.h Common/ServerDefines.h - Common/GitRevision.cpp - Common/GitRevision.h + Common/Revision.cpp + Common/Revision.h ) source_group("Common" FILES ${SRC_GRP_COMMON}) @@ -231,9 +227,6 @@ set(TGT_INCL Policies ) -configure_file(revision_data.h.in ${CMAKE_CURRENT_BINARY_DIR}/revision_data.h) -configure_file(SystemConfig.h.in ${CMAKE_CURRENT_BINARY_DIR}/SystemConfig.h) - TEST_BIG_ENDIAN(ENDIAN_VALUE) add_library(shared STATIC @@ -253,14 +246,19 @@ add_library(shared STATIC ${SRC_GRP_POLICIES} ${SRC_GRP_SVC} ${SRC_GRP_UTILITIES} - ${CMAKE_CURRENT_BINARY_DIR/revision_data.h} - ${CMAKE_CURRENT_BINARY_DIR/SystemConfig.h} ) +# BuildRevision.h (generated out of source by cmake/Revision.cmake) is visible to +# Revision.cpp alone, so a commit or a version bump recompiles that one file. +# Never add MANGOS_REVISION_INCLUDE_DIR to a target's include path. +set_source_files_properties(Common/Revision.cpp PROPERTIES + INCLUDE_DIRECTORIES "${MANGOS_REVISION_INCLUDE_DIR}" + OBJECT_DEPENDS "${MANGOS_REVISION_HEADER}") +add_dependencies(shared revision) + target_include_directories(shared PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_BINARY_DIR} ${TGT_INCL} ) diff --git a/src/shared/Common/GitRevision.cpp b/src/shared/Common/GitRevision.cpp deleted file mode 100644 index ebd19e970..000000000 --- a/src/shared/Common/GitRevision.cpp +++ /dev/null @@ -1,215 +0,0 @@ -/** - * SPDX-License-Identifier: GPL-3.0-or-later - * - * MaNGOS is a full featured server for World of Warcraft, supporting - * the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8 - * - * Copyright (C) 2005-2026 MaNGOS - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * World of Warcraft, and all World of Warcraft or Warcraft art, images, - * and lore are copyrighted by Blizzard Entertainment, Inc. - */ - -#include "GitRevision.h" - -char const* GitRevision::GetHash() -{ - return REVISION_HASH; -} - -char const* GitRevision::GetDate() -{ - return REVISION_DATE; -} - -char const* GitRevision::GetBranch() -{ - return REVISION_BRANCH; -} - -char const* GitRevision::GetDepElunaHash() -{ - return DEP_ELUNA_REVISION_HASH; -} - -char const* GitRevision::GetDepElunaDate() -{ - return DEP_ELUNA_REVISION_DATE; -} - -char const* GitRevision::GetDepElunaBranch() -{ - return DEP_ELUNA_REVISION_BRANCH; -} - -char const* GitRevision::GetDepSD3Hash() -{ - return DEP_SD3_REVISION_HASH; -} - -char const* GitRevision::GetDepSD3Date() -{ - return DEP_SD3_REVISION_DATE; -} - -char const* GitRevision::GetDepSD3Branch() -{ - return DEP_SD3_REVISION_BRANCH; -} - - -char const* GitRevision::GetCMakeVersion() -{ - return CMAKE_VERSION; -} - -char const* GitRevision::GetHostOSVersion() -{ - return "Compiled on: " CMAKE_HOST_SYSTEM; -} - -// Platform Define -#if PLATFORM == PLATFORM_WINDOWS - #ifdef _WIN64 - #define MANGOS_PLATFORM_STR "Win64" - #else - #define MANGOS_PLATFORM_STR "Win32" - #endif -#elif PLATFORM == PLATFORM_APPLE - #define MANGOS_PLATFORM_STR "MacOSX" -#elif PLATFORM == PLATFORM_INTEL - #define MANGOS_PLATFORM_STR "Intel" -#elif PLATFORM == PLATFORM_UNIX - #define MANGOS_PLATFORM_STR "Linux" -#else - #define MANGOS_PLATFORM_STR "Unknown System" -#endif - -// Database Revision -char const* GitRevision::GetProjectRevision() -{ - return PROJECT_REVISION_NR; -} - -char const* GitRevision::GetRealmDBVersion() -{ - return REALMD_DB_VERSION_NR; -} - -char const* GitRevision::GetRealmDBStructure() -{ - return REALMD_DB_STRUCTURE_NR; -} - -char const* GitRevision::GetRealmDBContent() -{ - return REALMD_DB_CONTENT_NR; -} - -char const* GitRevision::GetRealmDBUpdateDescription() -{ - return REALMD_DB_UPDATE_DESCRIPT; -} - -char const* GitRevision::GetCharDBVersion() -{ - return CHAR_DB_VERSION_NR; -} - -char const* GitRevision::GetCharDBStructure() -{ - return CHAR_DB_STRUCTURE_NR; -} - -char const* GitRevision::GetCharDBContent() -{ - return CHAR_DB_CONTENT_NR; -} - -char const* GitRevision::GetCharDBUpdateDescription() -{ - return CHAR_DB_UPDATE_DESCRIPT; -} - -char const* GitRevision::GetWorldDBVersion() -{ - return WORLD_DB_VERSION_NR; -} - -char const* GitRevision::GetWorldDBStructure() -{ - return WORLD_DB_STRUCTURE_NR; -} - -char const* GitRevision::GetWorldDBContent() -{ - return WORLD_DB_CONTENT_NR; -} - -char const* GitRevision::GetWorldDBUpdateDescription() -{ - return WORLD_DB_UPDATE_DESCRIPT; -} - -char const* GitRevision::GetFullRevision() -{ - return "Mangos revision: " VER_PRODUCTVERSION_STR; -} - -char const* GitRevision::GetDepElunaFullRevision() -{ - return DEP_ELUNA_REVISION_STR; -} - -char const* GitRevision::GetDepElunaFullRevisionStr() -{ - return "Eluna submodule revision: " DEP_ELUNA_REVISION_STR; -} - -char const* GitRevision::GetDepSD3FullRevision() -{ - return DEP_SD3_REVISION_STR; -} - -char const* GitRevision::GetDepSD3FullRevisionStr() -{ - return "SD3 submodule revision: " DEP_SD3_REVISION_STR; -} - -char const* GitRevision::GetRunningSystem() -{ - return "Running on: " CMAKE_HOST_SYSTEM; -} - -char const* GitRevision::GetCompanyNameStr() -{ - return VER_COMPANY_NAME_STR; -} - -char const* GitRevision::GetLegalCopyrightStr() -{ - return VER_LEGALCOPYRIGHT_STR; -} - -char const* GitRevision::GetFileVersionStr() -{ - return VER_FILEVERSION_STR; -} - -char const* GitRevision::GetProductVersionStr() -{ - return VER_PRODUCTVERSION_STR; -} diff --git a/src/shared/Common/GitRevision.h b/src/shared/Common/GitRevision.h deleted file mode 100644 index e7b41cb9e..000000000 --- a/src/shared/Common/GitRevision.h +++ /dev/null @@ -1,84 +0,0 @@ -/** - * SPDX-License-Identifier: GPL-3.0-or-later - * - * MaNGOS is a full featured server for World of Warcraft, supporting - * the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8 - * - * Copyright (C) 2005-2026 MaNGOS - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * World of Warcraft, and all World of Warcraft or Warcraft art, images, - * and lore are copyrighted by Blizzard Entertainment, Inc. - */ - -#ifndef GITREVISION_H -#define GITREVISION_H - -#include "Define.h" - -// Included here rather than in GitRevision.cpp on purpose: this header is the -// one place the generated revision_data.h is meant to be reached through, so -// that the ~40 translation units that merely want a version string do not each -// take a dependency on a file the build regenerates. -#include "revision_data.h" - -namespace GitRevision -{ - // github data - char const* GetHash(); - char const* GetDate(); - char const* GetBranch(); - char const* GetDepElunaHash(); - char const* GetDepElunaDate(); - char const* GetDepElunaBranch(); - char const* GetDepSD3Hash(); - char const* GetDepSD3Date(); - char const* GetDepSD3Branch(); - - // system data - char const* GetCMakeVersion(); - char const* GetHostOSVersion(); - char const* GetRunningSystem(); - - // database data - char const* GetProjectRevision(); - char const* GetRealmDBVersion(); - char const* GetRealmDBStructure(); - char const* GetRealmDBContent(); - char const* GetRealmDBUpdateDescription(); - - char const* GetCharDBVersion(); - char const* GetCharDBStructure(); - char const* GetCharDBContent(); - char const* GetCharDBUpdateDescription(); - - char const* GetWorldDBVersion(); - char const* GetWorldDBStructure(); - char const* GetWorldDBContent(); - char const* GetWorldDBUpdateDescription(); - - // application data - char const* GetFullRevision(); - char const* GetDepElunaFullRevisionStr(); - char const* GetDepElunaFullRevision(); - char const* GetDepSD3FullRevisionStr(); - char const* GetDepSD3FullRevision(); - char const* GetCompanyNameStr(); - char const* GetLegalCopyrightStr(); - char const* GetFileVersionStr(); - char const* GetProductVersionStr(); -} - -#endif diff --git a/src/shared/Common/Revision.cpp b/src/shared/Common/Revision.cpp new file mode 100644 index 000000000..090fcea1b --- /dev/null +++ b/src/shared/Common/Revision.cpp @@ -0,0 +1,147 @@ +/** + * SPDX-License-Identifier: GPL-3.0-or-later + * + * MaNGOS is a full featured server for World of Warcraft, supporting + * the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8 + * + * Copyright (C) 2005-2026 MaNGOS + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * World of Warcraft, and all World of Warcraft or Warcraft art, images, + * and lore are copyrighted by Blizzard Entertainment, Inc. + */ + +#include "Revision.h" + +// Generated by cmake/Revision.cmake into the build tree. Only this file has its +// directory on the include path (src/shared/CMakeLists.txt). +#include "BuildRevision.h" + +#include + +namespace +{ + Revision::DbVersion const s_worldDb = + { + "World", REVISION_WORLD_DB_VERSION, REVISION_WORLD_DB_STRUCTURE, + REVISION_WORLD_DB_CONTENT, REVISION_WORLD_DB_UPDATE + }; + + Revision::DbVersion const s_realmDb = + { + "Realmd", REVISION_REALMD_DB_VERSION, REVISION_REALMD_DB_STRUCTURE, + REVISION_REALMD_DB_CONTENT, REVISION_REALMD_DB_UPDATE + }; + + Revision::DbVersion const s_charDb = + { + "Character", REVISION_CHAR_DB_VERSION, REVISION_CHAR_DB_STRUCTURE, + REVISION_CHAR_DB_CONTENT, REVISION_CHAR_DB_UPDATE + }; + + struct ConfigEntry + { + char const* name; + char const* path; + uint32 version; + }; + + // Indexed by Revision::ConfigFile. + ConfigEntry const s_configs[] = + { + { "mangosd.conf", REVISION_CONFIG_DIR "mangosd.conf", REVISION_MANGOSD_CONF_VERSION }, + { "realmd.conf", REVISION_CONFIG_DIR "realmd.conf", REVISION_REALMD_CONF_VERSION }, + { "ahbot.conf", REVISION_CONFIG_DIR "ahbot.conf", REVISION_AHBOT_CONF_VERSION }, + { "aiplayerbot.conf", REVISION_CONFIG_DIR "aiplayerbot.conf", REVISION_PLAYERBOT_CONF_VERSION }, + }; + + static_assert(sizeof(s_configs) / sizeof(s_configs[0]) == std::size_t(Revision::ConfigFile::Playerbot) + 1, + "s_configs must list every Revision::ConfigFile, in order"); +} + +char const* Revision::GetRevisionStr() +{ + return REVISION_STR; +} + +char const* Revision::GetElunaRevisionStr() +{ + return REVISION_ELUNA_STR; +} + +char const* Revision::GetSD3RevisionStr() +{ + return REVISION_SD3_STR; +} + +char const* Revision::GetFullRevision() +{ + return "Mangos revision: " REVISION_STR; +} + +char const* Revision::GetHash() +{ + return REVISION_HASH; +} + +char const* Revision::GetDate() +{ + return REVISION_DATE; +} + +char const* Revision::GetPackageName() +{ + return REVISION_PACKAGE_NAME; +} + +char const* Revision::GetProjectRevision() +{ + return REVISION_PROJECT_NR; +} + +char const* Revision::GetBuildHost() +{ + return REVISION_BUILD_HOST; +} + +Revision::DbVersion const& Revision::GetWorldDb() +{ + return s_worldDb; +} + +Revision::DbVersion const& Revision::GetRealmDb() +{ + return s_realmDb; +} + +Revision::DbVersion const& Revision::GetCharDb() +{ + return s_charDb; +} + +char const* Revision::GetConfigName(ConfigFile file) +{ + return s_configs[std::size_t(file)].name; +} + +char const* Revision::GetConfigPath(ConfigFile file) +{ + return s_configs[std::size_t(file)].path; +} + +uint32 Revision::GetConfigVersion(ConfigFile file) +{ + return s_configs[std::size_t(file)].version; +} diff --git a/src/shared/Common/Revision.h b/src/shared/Common/Revision.h new file mode 100644 index 000000000..ecb1c2349 --- /dev/null +++ b/src/shared/Common/Revision.h @@ -0,0 +1,79 @@ +/** + * SPDX-License-Identifier: GPL-3.0-or-later + * + * MaNGOS is a full featured server for World of Warcraft, supporting + * the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8 + * + * Copyright (C) 2005-2026 MaNGOS + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * World of Warcraft, and all World of Warcraft or Warcraft art, images, + * and lore are copyrighted by Blizzard Entertainment, Inc. + */ + +#ifndef MANGOS_REVISION_H +#define MANGOS_REVISION_H + +#include "Define.h" + +/** + * What this build is: revision, versions, required database schema and the + * configuration files it reads. All values are set in cmake/Revision.cmake, + * generated into BuildRevision.h in the build tree, and read by Revision.cpp + * alone. This header only declares them, so nothing that includes it is + * rebuilt when the revision or a version changes. + */ +namespace Revision +{ + /// " ( branch)" of the core, Eluna and SD3; a module + /// that is not built reads "not built n/a (disabled branch)". + char const* GetRevisionStr(); + char const* GetElunaRevisionStr(); + char const* GetSD3RevisionStr(); + char const* GetFullRevision(); ///< "Mangos revision: " GetRevisionStr() + char const* GetHash(); + char const* GetDate(); + + char const* GetPackageName(); + char const* GetProjectRevision(); + char const* GetBuildHost(); ///< OS the binary was compiled on + + /// The `db_version` row the core requires of each database. + struct DbVersion + { + char const* name; + char const* version; + char const* structure; + char const* content; + char const* description; + }; + DbVersion const& GetWorldDb(); + DbVersion const& GetRealmDb(); + DbVersion const& GetCharDb(); + + /// The configuration files this build ships a .conf.dist for. + enum class ConfigFile + { + Mangosd, + Realmd, + AhBot, + Playerbot, + }; + char const* GetConfigName(ConfigFile file); ///< "mangosd.conf" + char const* GetConfigPath(ConfigFile file); ///< install config dir + name + uint32 GetConfigVersion(ConfigFile file); ///< ConfVersion it requires +} + +#endif diff --git a/src/shared/Compat/revision/GitRevision.h b/src/shared/Compat/revision/GitRevision.h new file mode 100644 index 000000000..9ef5c77bb --- /dev/null +++ b/src/shared/Compat/revision/GitRevision.h @@ -0,0 +1,36 @@ +/** + * SPDX-License-Identifier: GPL-3.0-or-later + * + * MaNGOS is a full featured server for World of Warcraft, supporting + * the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8 + * + * Copyright (C) 2005-2026 MaNGOS + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * World of Warcraft, and all World of Warcraft or Warcraft art, images, + * and lore are copyrighted by Blizzard Entertainment, Inc. + */ + +// Legacy name for Revision.h, for the realmd and Eluna submodules, which may not +// be edited here (see cmake/SubmoduleCompat.cmake). Delete with the upstream fix. + +#ifndef MANGOS_COMPAT_GITREVISION_H +#define MANGOS_COMPAT_GITREVISION_H + +#include "Revision.h" + +namespace GitRevision = Revision; + +#endif diff --git a/src/shared/Compat/revision/SystemConfig.h b/src/shared/Compat/revision/SystemConfig.h new file mode 100644 index 000000000..fb3531336 --- /dev/null +++ b/src/shared/Compat/revision/SystemConfig.h @@ -0,0 +1,41 @@ +/** + * SPDX-License-Identifier: GPL-3.0-or-later + * + * MaNGOS is a full featured server for World of Warcraft, supporting + * the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8 + * + * Copyright (C) 2005-2026 MaNGOS + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * World of Warcraft, and all World of Warcraft or Warcraft art, images, + * and lore are copyrighted by Blizzard Entertainment, Inc. + */ + +// Legacy name, for the realmd and SD3 submodules, which may not be edited here +// (see cmake/SubmoduleCompat.cmake). Only what realmd's Main.cpp reads; the core +// itself uses Revision.h. Delete with the upstream fix. + +#ifndef MANGOS_COMPAT_SYSTEMCONFIG_H +#define MANGOS_COMPAT_SYSTEMCONFIG_H + +#include "Platform/Define.h" +#include "Revision.h" + +#define REALMD_CONFIG_NAME Revision::GetConfigName(Revision::ConfigFile::Realmd) +#define REALMD_CONFIG_LOCATION Revision::GetConfigPath(Revision::ConfigFile::Realmd) +#define REALMD_CONFIG_VERSION Revision::GetConfigVersion(Revision::ConfigFile::Realmd) +#define DEFAULT_REALMSERVER_PORT 3724 + +#endif diff --git a/src/shared/Compat/revision/revision_data.h b/src/shared/Compat/revision/revision_data.h new file mode 100644 index 000000000..71bb99980 --- /dev/null +++ b/src/shared/Compat/revision/revision_data.h @@ -0,0 +1,34 @@ +/** + * SPDX-License-Identifier: GPL-3.0-or-later + * + * MaNGOS is a full featured server for World of Warcraft, supporting + * the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8 + * + * Copyright (C) 2005-2026 MaNGOS + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * World of Warcraft, and all World of Warcraft or Warcraft art, images, + * and lore are copyrighted by Blizzard Entertainment, Inc. + */ + +// Legacy name, for Eluna's ElunaIncludes.h, which includes it on MaNGOS but +// reads the revision through GitRevision::. Delete with the upstream fix. + +#ifndef MANGOS_COMPAT_REVISION_DATA_H +#define MANGOS_COMPAT_REVISION_DATA_H + +#include "GitRevision.h" + +#endif diff --git a/src/shared/Database/Database.cpp b/src/shared/Database/Database.cpp index cd17ffae0..09f0a6db0 100644 --- a/src/shared/Database/Database.cpp +++ b/src/shared/Database/Database.cpp @@ -34,7 +34,7 @@ #include "DatabaseEnv.h" #include "Config/Config.h" #include "Database/SqlOperations.h" -#include "GitRevision.h" +#include "Revision.h" #include "Utilities/Util.h" #include #include @@ -53,10 +53,15 @@ struct DBVersion std::string description; }; +static DBVersion ToDBVersion(Revision::DbVersion const& db) +{ + return { db.name, db.version, db.structure, db.content, db.description }; +} + const DBVersion databaseVersions[COUNT_DATABASES] = { - { "World", GitRevision::GetWorldDBVersion(), GitRevision::GetWorldDBStructure(), GitRevision::GetWorldDBContent(), GitRevision::GetWorldDBUpdateDescription() }, // DATABASE_WORLD - { "Realmd", GitRevision::GetRealmDBVersion(), GitRevision::GetRealmDBStructure(), GitRevision::GetRealmDBContent(), GitRevision::GetRealmDBUpdateDescription() }, // DATABASE_REALMD - { "Character", GitRevision::GetCharDBVersion(), GitRevision::GetCharDBStructure(), GitRevision::GetCharDBContent(), GitRevision::GetCharDBUpdateDescription() }, // DATABASE_CHARACTER + ToDBVersion(Revision::GetWorldDb()), // DATABASE_WORLD + ToDBVersion(Revision::GetRealmDb()), // DATABASE_REALMD + ToDBVersion(Revision::GetCharDb()), // DATABASE_CHARACTER }; ////////////////////////////////////////////////////////////////////////// diff --git a/src/shared/SystemConfig.h.in b/src/shared/SystemConfig.h.in deleted file mode 100644 index 7acbe5ea6..000000000 --- a/src/shared/SystemConfig.h.in +++ /dev/null @@ -1,72 +0,0 @@ -/** - * SPDX-License-Identifier: GPL-3.0-or-later - * - * MaNGOS is a full featured server for World of Warcraft, supporting - * the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8 - * - * Copyright (C) 2005-2026 MaNGOS - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * World of Warcraft, and all World of Warcraft or Warcraft art, images, - * and lore are copyrighted by Blizzard Entertainment, Inc. - */ - -#ifndef MANGOS_SYSTEMCONFIG_H -#define MANGOS_SYSTEMCONFIG_H - -#include "Platform/Define.h" - -#ifndef MANGOS_PACKAGENAME -#define MANGOS_PACKAGENAME "@MANGOS_PKG@" -#endif - -#ifndef MANGOS_VERSION -# define MANGOS_VERSION(REVD,REVT,REVN,REVH) "@PROJECT_VERSION@" " (" REVD " " REVT " Revision " REVN " - " REVH ")" -#endif - -// Format is YYYYMMDDRR where RR is the change in the conf file -// for that day. -#ifndef MANGOSD_CONFIG_VERSION -# define MANGOSD_CONFIG_VERSION @MANGOS_WORLD_VER@ -#endif - -#ifndef REALMD_CONFIG_VERSION -# define REALMD_CONFIG_VERSION @MANGOS_REALM_VER@ -#endif - -#ifndef AHBOT_CONFIG_VERSION -# define AHBOT_CONFIG_VERSION @MANGOS_AHBOT_VER@ -#endif - -#if MANGOS_ENDIAN == MANGOS_BIGENDIAN -# define MANGOS_ENDIAN_STRING "big-endian" -#else -# define MANGOS_ENDIAN_STRING "little-endian" -#endif - -#define SYSCONFDIR "@CONF_INSTALL_DIR@/" - -#define REALMD_CONFIG_NAME "realmd.conf" -#define MANGOSD_CONFIG_NAME "mangosd.conf" -#define AUCTIONHOUSEBOT_CONFIG_NAME "ahbot.conf" - -#define MANGOSD_CONFIG_LOCATION SYSCONFDIR MANGOSD_CONFIG_NAME -#define REALMD_CONFIG_LOCATION SYSCONFDIR REALMD_CONFIG_NAME -#define AUCTIONHOUSEBOT_CONFIG_LOCATION SYSCONFDIR AUCTIONHOUSEBOT_CONFIG_NAME - -#define DEFAULT_PLAYER_LIMIT 100 -#define DEFAULT_WORLDSERVER_PORT 8085 //8129 -#define DEFAULT_REALMSERVER_PORT 3724 -#endif \ No newline at end of file diff --git a/src/shared/Win/WheatyExceptionReport.cpp b/src/shared/Win/WheatyExceptionReport.cpp index 03315e253..ee3cedb07 100644 --- a/src/shared/Win/WheatyExceptionReport.cpp +++ b/src/shared/Win/WheatyExceptionReport.cpp @@ -17,7 +17,7 @@ #define _NO_CVCONST_H #include #include "WheatyExceptionReport.h" -#include "GitRevision.h" +#include "Revision.h" #include #define CrashFolder _T("Crashes") #pragma comment(linker, "/defaultlib:dbghelp.lib") @@ -352,7 +352,7 @@ void WheatyExceptionReport::GenerateExceptionReport( GetLocalTime(&systime); // Start out with a banner - _tprintf(_T("Revision: %s\r\n"), GitRevision::GetProjectRevision()); + _tprintf(_T("Revision: %s\r\n"), Revision::GetProjectRevision()); _tprintf(_T("Date %u:%u:%u. Time %u:%u \r\n"), systime.wDay, systime.wMonth, systime.wYear, systime.wHour, systime.wMinute); PEXCEPTION_RECORD pExceptionRecord = pExceptionInfo->ExceptionRecord; diff --git a/src/shared/revision_data.h.in b/src/shared/revision_data.h.in deleted file mode 100644 index 0647869d3..000000000 --- a/src/shared/revision_data.h.in +++ /dev/null @@ -1,68 +0,0 @@ -/** - * SPDX-License-Identifier: GPL-3.0-or-later - * - * MaNGOS is a full featured server for World of Warcraft, supporting - * the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8 - * - * Copyright (C) 2005-2026 MaNGOS - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * World of Warcraft, and all World of Warcraft or Warcraft art, images, - * and lore are copyrighted by Blizzard Entertainment, Inc. - */ - -#ifndef REVISION_DATA_H -#define REVISION_DATA_H - #define REVISION_HASH "@rev_hash@" - #define REVISION_DATE "@rev_date@" - #define REVISION_BRANCH "@rev_branch@" - - #define DEP_ELUNA_REVISION_HASH "@dep_eluna_rev_hash@" - #define DEP_ELUNA_REVISION_DATE "@dep_eluna_rev_date@" - #define DEP_ELUNA_REVISION_BRANCH "@dep_eluna_rev_branch@" - #define DEP_ELUNA_REVISION_STR "@dep_eluna_rev_hash@ @dep_eluna_rev_date@ (@dep_eluna_rev_branch@ branch)" - - #define DEP_SD3_REVISION_HASH "@dep_sd3_rev_hash@" - #define DEP_SD3_REVISION_DATE "@dep_sd3_rev_date@" - #define DEP_SD3_REVISION_BRANCH "@dep_sd3_rev_branch@" - #define DEP_SD3_REVISION_STR "@dep_sd3_rev_hash@ @dep_sd3_rev_date@ (@dep_sd3_rev_branch@ branch)" - - #define CMAKE_VERSION R"(@CMAKE_VERSION@)" - #define CMAKE_HOST_SYSTEM R"(@CMAKE_HOST_SYSTEM_NAME@ @CMAKE_HOST_SYSTEM_VERSION@)" - - #define PROJECT_REVISION_NR "2201075" - - #define REALMD_DB_VERSION_NR "22" - #define REALMD_DB_STRUCTURE_NR "5" - #define REALMD_DB_CONTENT_NR "1" - #define REALMD_DB_UPDATE_DESCRIPT "Cata Warden identity" - - #define CHAR_DB_VERSION_NR "22" - #define CHAR_DB_STRUCTURE_NR "5" - #define CHAR_DB_CONTENT_NR "4" - #define CHAR_DB_UPDATE_DESCRIPT "Remove_Warden_Action" - - #define WORLD_DB_VERSION_NR "22" - #define WORLD_DB_STRUCTURE_NR "6" - #define WORLD_DB_CONTENT_NR "4" - #define WORLD_DB_UPDATE_DESCRIPT "Warden_Locale_Hardening" - - #define VER_COMPANY_NAME_STR "MaNGOS Developers" - #define VER_LEGALCOPYRIGHT_STR "(c)2005-@rev_year@ MaNGOS" - #define VER_FILEVERSION 0,0,0 - #define VER_FILEVERSION_STR "@rev_hash@ @rev_date@ (@rev_branch@ branch)" - #define VER_PRODUCTVERSION VER_FILEVERSION - #define VER_PRODUCTVERSION_STR VER_FILEVERSION_STR -#endif diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 48725c549..4309846fd 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -54,8 +54,6 @@ set(SRC_GRP_TESTS WardenIncidentStoreTest.cpp WardenServerTest.cpp DatabaseConcurrencyTest.cpp - DatabaseVersionTest.cpp - OpenSSLProviderTest.cpp ClientParserTest.cpp TerrainModelTest.cpp TileSerializerTest.cpp @@ -195,26 +193,7 @@ if(WIN32) "${MANGOS_TEST_MYSQL_DLL_DIR}/${MANGOS_TEST_MYSQL_DLL_NAME}" "$") endif() - set_tests_properties(mangos_tests PROPERTIES - ENVIRONMENT "OPENSSL_MODULES=") - - # Match the release layout and leave OPENSSL_MODULES empty: provider discovery - # must work from ossl-modules beside the executable, not from the build host. - find_file(MANGOS_TEST_OPENSSL_LEGACY_DLL - NAMES legacy.dll - HINTS "${MANGOS_SSL_ROOT}" "${OPENSSL_ROOT_DIR}" - PATH_SUFFIXES bin/ossl-modules bin ossl-modules lib/ossl-modules "" - NO_DEFAULT_PATH) - - if(MANGOS_TEST_OPENSSL_LEGACY_DLL) - add_custom_command(TARGET mangos_tests POST_BUILD - COMMAND ${CMAKE_COMMAND} -E make_directory - "$/ossl-modules" - COMMAND ${CMAKE_COMMAND} -E copy_if_different - "${MANGOS_TEST_OPENSSL_LEGACY_DLL}" - "$/ossl-modules/legacy.dll") - else() - message(WARNING - "OpenSSL legacy provider (legacy.dll) not found; mangos_tests may fail its RC4 cases.") - endif() + # No ossl-modules here, and no OPENSSL_MODULES to point at one. RC4 was the only + # thing this tree ever asked the legacy provider for, and it is in the tree now, so + # the tests need libcrypto and nothing beside it. endif() diff --git a/src/tests/CheckBuildPolicy.cmake b/src/tests/CheckBuildPolicy.cmake index 870b1faae..8c3d58c34 100644 --- a/src/tests/CheckBuildPolicy.cmake +++ b/src/tests/CheckBuildPolicy.cmake @@ -31,15 +31,24 @@ foreach(REQUIRED_TEXT endif() endforeach() -# The provider manager is a Meyers singleton in mangos_two and an RAII local in -# the other three cores. Either spelling is accepted; what is not negotiable is -# that a failed crypto init leaves through `return 1`. Returning 0 tells a -# supervisor the process exited cleanly, so nothing restarts it. -string(REGEX MATCH - "if \\(![A-Za-z_:.()]*IsInitialized\\(\\)\\)[^\n]*[\r\n]+[^\n]*\\{[\r\n]+[^\n]*Log::WaitBeforeContinueIfNeed\\(\\);[\r\n]+[^\n]*return 1;" - PROVIDER_FAILURE "${MANGOSD_SOURCE}") -if(NOT PROVIDER_FAILURE) - message(FATAL_ERROR "mangosd provider failure must return 1") +# The provider clause is gone, with the provider it guarded. +# +# It required mangosd to leave through `return 1` when the OpenSSL provider manager +# failed to initialise -- a good rule, because returning 0 tells a supervisor the +# process exited cleanly and nothing restarts it. There is no longer anything for it to +# describe: RC4 was the only algorithm this tree fetched from the legacy provider, it is +# implemented in the tree now, and mangosd performs no fallible crypto init at start-up +# at all. SHA-1, SHA-256 and the bignum work come from the default provider, which is +# inside libcrypto and cannot be absent while libcrypto is present. +# +# Deleted rather than loosened. A policy that matches nothing is worse than no policy: +# it passes for the right reason today and for the wrong reason the moment someone +# reintroduces a start-up check and forgets its exit code. +string(FIND "${MANGOSD_SOURCE}" "OpenSSLProvider" POSITION) +if(NOT POSITION EQUAL -1) + message(FATAL_ERROR + "mangosd reaches for OpenSSLProvider again; if a fallible crypto init is back, so " + "must be the rule that it exits with 1") endif() string(FIND "${SRC_CMAKE}" "Upstream realmd passes the *file*" POSITION) diff --git a/src/tests/CheckWardenBoundary.cmake b/src/tests/CheckWardenBoundary.cmake index 9dd604b3f..61bed86c9 100644 --- a/src/tests/CheckWardenBoundary.cmake +++ b/src/tests/CheckWardenBoundary.cmake @@ -147,6 +147,15 @@ if(SESSION_CPP MATCHES "m_wardenClientLocale\\.c_str[ \\t]*\\(") message(FATAL_ERROR "Warden boundary: raw authenticated locale bytes must not reach logs") endif() +require_count("${WORLD_CONFIG}" + "Warden\\.Enabled\"[ \\t]*,[ \\t]*true" 1 + "Warden must default on in world configuration") +file(STRINGS "${SOURCE_ROOT}/src/mangosd/mangosd.conf.dist.in" + MANGOSD_ACTIVE_WARDEN_ENABLED + REGEX "^[ \\t]*Warden\\.Enabled[ \\t]*=") +require_count("${MANGOSD_ACTIVE_WARDEN_ENABLED}" + "Warden\\.Enabled[ \\t]*=[ \\t]*1" 1 + "distributed config must carry one active default-on Warden.Enabled") require_count("${WORLD_CONFIG}" "Warden\\.RequireExactProfile\"[ \\t]*,[ \\t]*true" 1 "strict exact-profile admission must default on in world configuration") diff --git a/src/tests/CryptoStressTest.cpp b/src/tests/CryptoStressTest.cpp index 4a2a8f8c8..7bde0ef44 100644 --- a/src/tests/CryptoStressTest.cpp +++ b/src/tests/CryptoStressTest.cpp @@ -26,7 +26,6 @@ #include #include "TestHarness.h" -#include "Auth/ARC4.h" #include "Auth/BigNumber.h" #include "Auth/HMACSHA1.h" #include "Auth/Md5.h" @@ -269,17 +268,3 @@ TEST(Crypto_bignumber_fixed_width_output_is_always_that_width) CHECK_EQ(wrong, 0); } - -TEST(Crypto_arc4_matches_the_published_vector) -{ - // The provider test next door asserts that RC4 can be FETCHED. That is not the same - // as producing the right keystream: a cipher that initialises and encrypts to - // something else still fetches perfectly, and the symptom is a client that connects - // and then fails to decode a single packet. - uint8 key[] = {'K', 'e', 'y'}; - uint8 data[] = {'P', 'l', 'a', 'i', 'n', 't', 'e', 'x', 't'}; - - ARC4 rc4(key, static_cast(sizeof(key))); - rc4.UpdateData(sizeof(data), data); - CHECK_HEX(data, sizeof(data), "bbf316e8d940af0ad3"); -} diff --git a/src/tests/DatabaseVersionTest.cpp b/src/tests/DatabaseVersionTest.cpp deleted file mode 100644 index 89068fd13..000000000 --- a/src/tests/DatabaseVersionTest.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/** - * SPDX-License-Identifier: GPL-3.0-or-later - * - * MaNGOS is a full featured server for World of Warcraft, supporting - * the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8 - * - * Copyright (C) 2005-2026 MaNGOS - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "TestHarness.h" - -#include "Common/GitRevision.h" - -TEST(CoreDatabaseVersion_requires_database_backed_warden_catalogue) -{ - CHECK_STR(GitRevision::GetRealmDBVersion(), "22"); - CHECK_STR(GitRevision::GetRealmDBStructure(), "5"); - CHECK_STR(GitRevision::GetRealmDBContent(), "1"); - CHECK_STR(GitRevision::GetRealmDBUpdateDescription(), - "Cata Warden identity"); - - CHECK_STR(GitRevision::GetCharDBVersion(), "22"); - CHECK_STR(GitRevision::GetCharDBStructure(), "5"); - CHECK_STR(GitRevision::GetCharDBContent(), "4"); - CHECK_STR(GitRevision::GetCharDBUpdateDescription(), - "Remove_Warden_Action"); - - CHECK_STR(GitRevision::GetWorldDBVersion(), "22"); - CHECK_STR(GitRevision::GetWorldDBStructure(), "6"); - CHECK_STR(GitRevision::GetWorldDBContent(), "4"); - CHECK_STR(GitRevision::GetWorldDBUpdateDescription(), - "Warden_Locale_Hardening"); -} diff --git a/src/tests/OpenSSLProviderTest.cpp b/src/tests/OpenSSLProviderTest.cpp deleted file mode 100644 index 6ba96fea4..000000000 --- a/src/tests/OpenSSLProviderTest.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/** - * SPDX-License-Identifier: GPL-3.0-or-later - * - * MaNGOS is a full featured server for World of Warcraft, supporting - * the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8 - * - * Copyright (C) 2005-2026 MaNGOS - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * World of Warcraft, and all World of Warcraft or Warcraft art, images, - * and lore are copyrighted by Blizzard Entertainment, Inc. - */ - -#include -#include "TestHarness.h" -#include "Auth/OpenSSLProvider.h" - -#include -#include -#include -#include - -TEST(OpenSSL_runtime_and_providers_are_major_three) -{ - const char* modules = std::getenv("OPENSSL_MODULES"); - std::string modulesBefore = modules ? modules : ""; - - OpenSSLProviderManager& manager = - OpenSSLProviderManager::Instance(); - - const char* modulesAfter = std::getenv("OPENSSL_MODULES"); - CHECK_STR(std::string(modulesAfter ? modulesAfter : ""), modulesBefore); - REQUIRE(manager.IsInitialized()); - - unsigned runtimeMajor = - unsigned((OpenSSL_version_num() >> 28) & 0x0f); - CHECK_EQ(runtimeMajor, 3); - - auto checkProvider = [runtimeMajor]( - const OpenSSLProvider& provider) - { - std::string version = provider.Version(); - REQUIRE(!version.empty()); - std::size_t separator = version.find('.'); - REQUIRE(separator != std::string::npos); - unsigned major = 0; - std::from_chars_result result = std::from_chars( - version.data(), version.data() + separator, major); - CHECK(result.ec == std::errc{}); - CHECK(result.ptr == version.data() + separator); - CHECK_EQ(major, runtimeMajor); - }; - - checkProvider(manager.GetLegacyProvider()); - checkProvider(manager.GetDefaultProvider()); -} - -TEST(OpenSSL_legacy_provider_supplies_rc4) -{ - REQUIRE(OpenSSLProviderManager::Instance().IsInitialized()); - EVP_CIPHER* rc4 = EVP_CIPHER_fetch(nullptr, "RC4", nullptr); - CHECK(rc4 != nullptr); - EVP_CIPHER_free(rc4); -} diff --git a/src/tools/extractor/CMakeLists.txt b/src/tools/extractor/CMakeLists.txt index 45cb2c1dd..2a92cbe00 100644 --- a/src/tools/extractor/CMakeLists.txt +++ b/src/tools/extractor/CMakeLists.txt @@ -31,22 +31,9 @@ # extractor_mpq the StormLib container reader. # ============================================================================= -# ============================================================================= -# WHICH CLIENT THIS BAKER IS FOR. MANGOS_EXP (cmake/MangosParams.cmake) is the one -# place the expansion is named; this maps it to something a person reads, so the -# window and the --help banner cannot drift from what the tool actually parses. -# ============================================================================= -if("${MANGOS_EXP}" STREQUAL "CLASSIC") - set(MANGOS_CLIENT_NAME "World of Warcraft 1.12.x") -elseif("${MANGOS_EXP}" STREQUAL "TBC") - set(MANGOS_CLIENT_NAME "The Burning Crusade 2.4.3") -elseif("${MANGOS_EXP}" STREQUAL "WOTLK") - set(MANGOS_CLIENT_NAME "Wrath of the Lich King 3.3.5a") -elseif("${MANGOS_EXP}" STREQUAL "CATA") - set(MANGOS_CLIENT_NAME "Cataclysm 4.3.4") -else() - set(MANGOS_CLIENT_NAME "unknown client") -endif() +# WHICH CLIENT THIS BAKER IS FOR: MANGOS_CLIENT_NAME is derived from MANGOS_EXP in +# cmake/Revision.cmake, so the window and the --help banner cannot drift from +# what the tool actually parses. set(SRC_GRP_CLIENT client/AdtParser.cpp @@ -158,13 +145,16 @@ target_link_libraries(mangos-extractor $<$:ole32> ) -# The icon and version block are compiled from revision_data.h, which genrev writes -# into the build tree. +# The version block comes from the shared Windows template, configured once for +# both executables here: cmake/win/VersionInfo.h.in, fed by cmake/Revision.cmake. +# The .rc files carry their own icon and description, so PRODUCT_* only fill it. if(WIN32) - target_include_directories(mangos-extractor PRIVATE ${CMAKE_BINARY_DIR}/src/shared) - if(TARGET revision_data.h) - add_dependencies(mangos-extractor revision_data.h) - endif() + set(PRODUCT_NAME "MaNGOS") + set(PRODUCT_ICON "${CMAKE_CURRENT_SOURCE_DIR}/mangos-extractor.ico") + set(PRODUCT_DESCRIPTION "MaNGOS client data extractor") + mangos_configure(${CMAKE_SOURCE_DIR}/cmake/win/VersionInfo.h.in + ${CMAKE_CURRENT_BINARY_DIR}/VersionInfo.h) + target_include_directories(mangos-extractor PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) endif() set_target_properties(mangos-extractor PROPERTIES FOLDER "tools") @@ -193,11 +183,7 @@ if(WIN32) ExtractorGui.cpp ${CMAKE_CURRENT_SOURCE_DIR}/mangos-extractor-gui.rc) target_link_libraries(mangos-extractor-gui PRIVATE shell32 ole32 oleaut32 comctl32 comdlg32) - # The .rc includes revision_data.h, which genrev writes into the build tree. - target_include_directories(mangos-extractor-gui PRIVATE ${CMAKE_BINARY_DIR}/src/shared) - if(TARGET revision_data.h) - add_dependencies(mangos-extractor-gui revision_data.h) - endif() + target_include_directories(mangos-extractor-gui PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) target_compile_definitions(mangos-extractor-gui PRIVATE MANGOS_CLIENT_NAME="${MANGOS_CLIENT_NAME}") set_target_properties(mangos-extractor-gui PROPERTIES FOLDER "tools") diff --git a/src/tools/extractor/mangos-extractor-gui.rc b/src/tools/extractor/mangos-extractor-gui.rc index 02a0517c7..41ab75106 100644 --- a/src/tools/extractor/mangos-extractor-gui.rc +++ b/src/tools/extractor/mangos-extractor-gui.rc @@ -24,7 +24,7 @@ */ #include -#include "revision_data.h" +#include "VersionInfo.h" /* Numeric 1, not a named resource: the shell shows the LOWEST-numbered icon, and a string name sorts after every number. This is the one Explorer draws. */ @@ -35,8 +35,8 @@ MANGOSLOGO RCDATA DISCARDABLE "mangos-tools.jpg" VS_VERSION_INFO VERSIONINFO - FILEVERSION VER_FILEVERSION - PRODUCTVERSION VER_PRODUCTVERSION + FILEVERSION FILE_VERSION_RESOURCE + PRODUCTVERSION PRODUCT_VERSION_RESOURCE FILEFLAGSMASK VS_FFI_FILEFLAGSMASK #ifdef _DEBUG FILEFLAGS VS_FF_DEBUG @@ -51,14 +51,14 @@ BEGIN BEGIN BLOCK "040904E4" BEGIN - VALUE "CompanyName", VER_COMPANY_NAME_STR + VALUE "CompanyName", PRODUCT_COMPANY VALUE "FileDescription", "MaNGOS client baker" - VALUE "FileVersion", VER_FILEVERSION_STR + VALUE "FileVersion", FILE_VERSION_RESOURCE_STR VALUE "InternalName", "mangos-extractor-gui" - VALUE "LegalCopyright", VER_LEGALCOPYRIGHT_STR + VALUE "LegalCopyright", PRODUCT_COPYRIGHT VALUE "OriginalFilename", "mangos-extractor-gui.exe" VALUE "ProductName", "MaNGOS" - VALUE "ProductVersion", VER_PRODUCTVERSION_STR + VALUE "ProductVersion", PRODUCT_VERSION_RESOURCE_STR END END BLOCK "VarFileInfo" diff --git a/src/tools/extractor/mangos-extractor.rc b/src/tools/extractor/mangos-extractor.rc index 16f093bd4..faf5f435b 100644 --- a/src/tools/extractor/mangos-extractor.rc +++ b/src/tools/extractor/mangos-extractor.rc @@ -24,13 +24,13 @@ */ #include -#include "revision_data.h" +#include "VersionInfo.h" IDI_APPICON ICON DISCARDABLE "mangos-extractor.ico" VS_VERSION_INFO VERSIONINFO - FILEVERSION VER_FILEVERSION - PRODUCTVERSION VER_PRODUCTVERSION + FILEVERSION FILE_VERSION_RESOURCE + PRODUCTVERSION PRODUCT_VERSION_RESOURCE FILEFLAGSMASK VS_FFI_FILEFLAGSMASK #ifdef _DEBUG FILEFLAGS VS_FF_DEBUG @@ -45,14 +45,14 @@ BEGIN BEGIN BLOCK "040904E4" BEGIN - VALUE "CompanyName", VER_COMPANY_NAME_STR + VALUE "CompanyName", PRODUCT_COMPANY VALUE "FileDescription", "MaNGOS client data extractor" - VALUE "FileVersion", VER_FILEVERSION_STR + VALUE "FileVersion", FILE_VERSION_RESOURCE_STR VALUE "InternalName", "mangos-extractor" - VALUE "LegalCopyright", VER_LEGALCOPYRIGHT_STR + VALUE "LegalCopyright", PRODUCT_COPYRIGHT VALUE "OriginalFilename", "mangos-extractor.exe" VALUE "ProductName", "MaNGOS" - VALUE "ProductVersion", VER_PRODUCTVERSION_STR + VALUE "ProductVersion", PRODUCT_VERSION_RESOURCE_STR END END BLOCK "VarFileInfo"