From 2bb9b99c7eeac64d3306a6850260df5dd2e7c133 Mon Sep 17 00:00:00 2001 From: KonTy <9524513+KonTy@users.noreply.github.com> Date: Sun, 14 Jun 2026 12:06:20 -0700 Subject: [PATCH 1/5] StartProcess: pick up boost::process v1 headers on Boost 1.91 Boost 1.86 split boost::process into v1 (the existing API) and v2 (a new one), and started exposing the v1 headers under boost/process/v1/. Boost 1.91 then dropped the unversioned forwarder headers, so on those versions only boost/process/v1/ resolves. Detect both layouts with __has_include and route through a tc_bp namespace alias so the only behavioural difference between old and new Boost is which header path we use. The minimum Boost version (1.74 / 1.78) is unchanged. --- src/common/Utilities/StartProcess.cpp | 37 +++++++++++++++++++-------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/src/common/Utilities/StartProcess.cpp b/src/common/Utilities/StartProcess.cpp index 37c41f73a95ef..bebf92de3f94f 100644 --- a/src/common/Utilities/StartProcess.cpp +++ b/src/common/Utilities/StartProcess.cpp @@ -22,15 +22,32 @@ #include #include -#include -#include -#include -#include -#include -#include -#include - -using namespace boost::process; +// Boost 1.86 split boost::process into v1 (the old API) and v2 (the new one) +// and exposed the v1 headers under boost/process/v1/. Boost 1.91 then removed +// the unversioned forwarder headers, so on those versions only the v1/ path +// resolves. Detect both layouts so older Boost (TC's minimum is 1.74) still +// works. +#if __has_include() +# include +# include +# include +# include +# include +# include +# include +namespace tc_bp = boost::process::v1; +#else +# include +# include +# include +# include +# include +# include +# include +namespace tc_bp = boost::process; +#endif + +using namespace tc_bp; using namespace boost::iostreams; namespace Trinity @@ -133,7 +150,7 @@ static int CreateChildProcess(T waiter, std::string const& executable, exe = boost::filesystem::absolute(executable).string(), args = argsVector, env = environment(boost::this_process::environment()), - std_in = boost::process::close, + std_in = tc_bp::close, std_out = outStream, std_err = errStream }; From 368978604742e7cca38ab9616432f3a634f467dd Mon Sep 17 00:00:00 2001 From: KonTy <9524513+KonTy@users.noreply.github.com> Date: Sun, 14 Jun 2026 12:06:28 -0700 Subject: [PATCH 2/5] dep/boost: stop defining BOOST_ASIO_NO_DEPRECATED src/common/Asio/DeadlineTimer.h inherits from boost::asio::basic_deadline_timer, which is one of the symbols Asio gates behind !defined(BOOST_ASIO_NO_DEPRECATED). On older Boost releases this combination compiled because the gate wasn't applied to that header; on recent releases (observed on 1.91) the template is hidden when the macro is defined and the TC build stops linking. Drop the macro from the boost target. The deprecated APIs TC actually uses are limited to deadline_timer, which is what DeadlineTimer.h is about; everything else that the macro was guarding is already absent from the TC source tree. --- dep/boost/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/dep/boost/CMakeLists.txt b/dep/boost/CMakeLists.txt index aa7315f1e49c2..ebcd96fe72c6e 100644 --- a/dep/boost/CMakeLists.txt +++ b/dep/boost/CMakeLists.txt @@ -54,7 +54,6 @@ target_compile_definitions(boost -DBOOST_CHRONO_NO_LIB -DBOOST_SERIALIZATION_NO_LIB -DBOOST_CONFIG_SUPPRESS_OUTDATED_MESSAGE - -DBOOST_ASIO_NO_DEPRECATED -DBOOST_SYSTEM_USE_UTF8 -DBOOST_BIND_NO_PLACEHOLDERS) From 55a2239a018c08e748de0d11f7e951d611e02f6c Mon Sep 17 00:00:00 2001 From: KonTy <9524513+KonTy@users.noreply.github.com> Date: Sun, 14 Jun 2026 12:06:35 -0700 Subject: [PATCH 3/5] dep/jemalloc: tighten signatures so it builds on gcc 16 Two small, independent fixes to the bundled jemalloc snapshot. safety_check.h declared safety_check_set_abort as taking void(*)(), but the implementation in safety_check.c (and every caller) takes a void(*)(const char*). gcc 16 rejects the incompatible function pointer conversion at call sites instead of warning. Update the header to match the actual signature. jemalloc_cpp.cpp called std::__throw_bad_alloc(), which is a libstdc++ internal helper and has been removed in recent libstdc++ releases. Replace with the standard 'throw std::bad_alloc()' form, which compiles on every supported toolchain. --- dep/jemalloc/include/jemalloc/internal/safety_check.h | 2 +- dep/jemalloc/src/jemalloc_cpp.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dep/jemalloc/include/jemalloc/internal/safety_check.h b/dep/jemalloc/include/jemalloc/internal/safety_check.h index 53339ac12f2de..ec4b33699bdcc 100644 --- a/dep/jemalloc/include/jemalloc/internal/safety_check.h +++ b/dep/jemalloc/include/jemalloc/internal/safety_check.h @@ -3,7 +3,7 @@ void safety_check_fail(const char *format, ...); /* Can set to NULL for a default. */ -void safety_check_set_abort(void (*abort_fn)()); +void safety_check_set_abort(void (*abort_fn)(const char *)); JEMALLOC_ALWAYS_INLINE void safety_check_set_redzone(void *ptr, size_t usize, size_t bumped_usize) { diff --git a/dep/jemalloc/src/jemalloc_cpp.cpp b/dep/jemalloc/src/jemalloc_cpp.cpp index da0441a7c9788..05d5c3a7cec57 100644 --- a/dep/jemalloc/src/jemalloc_cpp.cpp +++ b/dep/jemalloc/src/jemalloc_cpp.cpp @@ -67,7 +67,7 @@ handleOOM(std::size_t size, bool nothrow) { } if (ptr == nullptr && !nothrow) - std::__throw_bad_alloc(); + throw std::bad_alloc(); return ptr; } From 511ec0dc9bfb672ca08d1147fb2b595094f84878 Mon Sep 17 00:00:00 2001 From: KonTy <9524513+KonTy@users.noreply.github.com> Date: Sun, 14 Jun 2026 12:06:43 -0700 Subject: [PATCH 4/5] liblua: expose fetched Lua headers to consumers sol2 is consumed through a precompiled header and resolves via whatever include path is in scope at the point sol2 is parsed. On distros that ship Lua 5.5 in /usr/include (Arch is the obvious one, but not the only one going forward), that header is picked up in preference to the Lua sources fetched into _deps/lua-src/, and sol2 then refuses to compile against the wrong version. Marking liblua's include directory as PUBLIC adds the fetched Lua sources to anything that links against liblua, which is what already happens in the rest of the consumer chain. The change has no effect on Windows (no system Lua) and no effect on distros that don't ship a competing lua.h. --- CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4f22642b94d47..866c2305aa5e2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,6 +34,12 @@ SET(LUA_ROOT ${lua_SOURCE_DIR}) file(GLOB SRC_LUA ${LUA_ROOT}/*.h ${LUA_ROOT}/*.c) LIST(REMOVE_ITEM SRC_LUA ${CMAKE_SOURCE_DIR}/../../misc/client-extensions/lua-5.1/src/lua.c) add_library ( liblua STATIC ${SRC_LUA} ) +# Expose the fetched Lua sources as a public include directory so downstream +# consumers (notably sol2, which is consumed via a precompiled header) pull +# the matching lua.h from this build rather than whatever the system +# happens to provide. Several modern Linux distros ship Lua 5.5 in +# /usr/include and quietly break sol2's expectations otherwise. +target_include_directories(liblua PUBLIC ${LUA_ROOT}) if(NOT WIN32) target_compile_options(liblua PUBLIC -fPIC) endif() From 57e3c6a64639d25bbd70a38173677e6c8b20282c Mon Sep 17 00:00:00 2001 From: KonTy <9524513+KonTy@users.noreply.github.com> Date: Fri, 26 Jun 2026 00:10:33 -0700 Subject: [PATCH 5/5] WIP: save current local SQL changes --- .../2021_09_12_world_smart_scripts_resize.sql | 13 +++++- .../world/2021_10_02_world_trainer_extend.sql | 25 +++++++++-- .../world/2021_10_02_world_vendor_extend.sql | 13 +++++- .../2021_10_31_world_tswow_transmog_npc.sql | 41 +++++++++---------- .../world/3.3.5/2024_08_17_00_world.sql | 15 ++++++- 5 files changed, 76 insertions(+), 31 deletions(-) diff --git a/sql/custom/world/2021_09_12_world_smart_scripts_resize.sql b/sql/custom/world/2021_09_12_world_smart_scripts_resize.sql index 8d5ff35c00555..be1e57d4c775d 100644 --- a/sql/custom/world/2021_09_12_world_smart_scripts_resize.sql +++ b/sql/custom/world/2021_09_12_world_smart_scripts_resize.sql @@ -1,3 +1,12 @@ -- make types larger so we can fit more values -ALTER TABLE `smart_scripts` MODIFY COLUMN `action_type` int unsigned; -ALTER TABLE `smart_scripts` MODIFY COLUMN `event_type` int unsigned; \ No newline at end of file +SET @has_table := (SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name = 'smart_scripts'); + +SET @alter_sql_1 := IF(@has_table > 0, 'ALTER TABLE `smart_scripts` MODIFY COLUMN `action_type` int unsigned', 'SELECT 1'); +PREPARE stmt1 FROM @alter_sql_1; +EXECUTE stmt1; +DEALLOCATE PREPARE stmt1; + +SET @alter_sql_2 := IF(@has_table > 0, 'ALTER TABLE `smart_scripts` MODIFY COLUMN `event_type` int unsigned', 'SELECT 1'); +PREPARE stmt2 FROM @alter_sql_2; +EXECUTE stmt2; +DEALLOCATE PREPARE stmt2; \ No newline at end of file diff --git a/sql/custom/world/2021_10_02_world_trainer_extend.sql b/sql/custom/world/2021_10_02_world_trainer_extend.sql index 49d7f49b73527..1d1b835435b12 100644 --- a/sql/custom/world/2021_10_02_world_trainer_extend.sql +++ b/sql/custom/world/2021_10_02_world_trainer_extend.sql @@ -1,5 +1,22 @@ -ALTER TABLE `trainer` ADD COLUMN `raceMask` INT(10) UNSIGNED NOT NULL DEFAULT '0'; -ALTER TABLE `trainer` ADD COLUMN `classMask` INT(10) UNSIGNED NOT NULL DEFAULT '0'; +SET @trainer_has_table := (SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name = 'trainer'); +SET @trainer_spell_has_table := (SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name = 'trainer_spell'); -ALTER TABLE `trainer_spell` ADD COLUMN `raceMask` INT(10) UNSIGNED NOT NULL DEFAULT '0'; -ALTER TABLE `trainer_spell` ADD COLUMN `classMask` INT(10) UNSIGNED NOT NULL DEFAULT '0'; \ No newline at end of file +SET @alter_trainer_1 := IF(@trainer_has_table > 0, 'ALTER TABLE `trainer` ADD COLUMN `raceMask` INT(10) UNSIGNED NOT NULL DEFAULT "0"', 'SELECT 1'); +PREPARE stmt1 FROM @alter_trainer_1; +EXECUTE stmt1; +DEALLOCATE PREPARE stmt1; + +SET @alter_trainer_2 := IF(@trainer_has_table > 0, 'ALTER TABLE `trainer` ADD COLUMN `classMask` INT(10) UNSIGNED NOT NULL DEFAULT "0"', 'SELECT 1'); +PREPARE stmt2 FROM @alter_trainer_2; +EXECUTE stmt2; +DEALLOCATE PREPARE stmt2; + +SET @alter_trainer_spell_1 := IF(@trainer_spell_has_table > 0, 'ALTER TABLE `trainer_spell` ADD COLUMN `raceMask` INT(10) UNSIGNED NOT NULL DEFAULT "0"', 'SELECT 1'); +PREPARE stmt3 FROM @alter_trainer_spell_1; +EXECUTE stmt3; +DEALLOCATE PREPARE stmt3; + +SET @alter_trainer_spell_2 := IF(@trainer_spell_has_table > 0, 'ALTER TABLE `trainer_spell` ADD COLUMN `classMask` INT(10) UNSIGNED NOT NULL DEFAULT "0"', 'SELECT 1'); +PREPARE stmt4 FROM @alter_trainer_spell_2; +EXECUTE stmt4; +DEALLOCATE PREPARE stmt4; \ No newline at end of file diff --git a/sql/custom/world/2021_10_02_world_vendor_extend.sql b/sql/custom/world/2021_10_02_world_vendor_extend.sql index 8ab5d164f53a1..414ab0a1a3aa4 100644 --- a/sql/custom/world/2021_10_02_world_vendor_extend.sql +++ b/sql/custom/world/2021_10_02_world_vendor_extend.sql @@ -1,2 +1,11 @@ -ALTER TABLE `npc_vendor` ADD COLUMN `raceMask` INT(10) UNSIGNED NOT NULL DEFAULT '0'; -ALTER TABLE `npc_vendor` ADD COLUMN `classMask` INT(10) UNSIGNED NOT NULL DEFAULT '0'; \ No newline at end of file +SET @npc_vendor_has_table := (SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name = 'npc_vendor'); + +SET @alter_vendor_1 := IF(@npc_vendor_has_table > 0, 'ALTER TABLE `npc_vendor` ADD COLUMN `raceMask` INT(10) UNSIGNED NOT NULL DEFAULT "0"', 'SELECT 1'); +PREPARE stmt1 FROM @alter_vendor_1; +EXECUTE stmt1; +DEALLOCATE PREPARE stmt1; + +SET @alter_vendor_2 := IF(@npc_vendor_has_table > 0, 'ALTER TABLE `npc_vendor` ADD COLUMN `classMask` INT(10) UNSIGNED NOT NULL DEFAULT "0"', 'SELECT 1'); +PREPARE stmt2 FROM @alter_vendor_2; +EXECUTE stmt2; +DEALLOCATE PREPARE stmt2; \ No newline at end of file diff --git a/sql/custom/world/2021_10_31_world_tswow_transmog_npc.sql b/sql/custom/world/2021_10_31_world_tswow_transmog_npc.sql index c20272d3b7032..c7f6c65aaf6ce 100644 --- a/sql/custom/world/2021_10_31_world_tswow_transmog_npc.sql +++ b/sql/custom/world/2021_10_31_world_tswow_transmog_npc.sql @@ -1,26 +1,23 @@ +-- Only execute if trinity_string table exists +SET @has_trinity_string := (SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name = 'trinity_string'); + SET @TEXT_ID := 65000; -REPLACE INTO `npc_text` (`ID`, `text0_0`) VALUES -(@TEXT_ID, 'Transmogrification allows you to change how your items look like without changing the stats of the items.\r\nItems used in transmogrification are no longer refundable, tradeable and are bound to you.\r\nUpdating a menu updates the view and prices.\r\n\r\nNot everything can be transmogrified with eachother.\r\nRestrictions include but are not limited to:\r\nOnly armor and weapons can be transmogrified\r\nGuns, bows and crossbows can be transmogrified with eachother\r\nFishing poles can not be transmogrified\r\nYou must be able to equip both items used in the process.\r\n\r\nTransmogrifications stay on your items as long as you own them.\r\nIf you try to put the item in guild bank or mail it to someone else, the transmogrification is stripped.\r\n\r\nYou can also remove transmogrifications for free at the transmogrifier.'), -(@TEXT_ID+1, 'You can save your own transmogrification sets.\r\n\r\nTo save, first you must transmogrify your equipped items.\r\nThen when you go to the set management menu and go to save set menu,\r\nall items you have transmogrified are displayed so you see what you are saving.\r\nIf you think the set is fine, you can click to save the set and name it as you wish.\r\n\r\nTo use a set you can click the saved set in the set management menu and then select use set.\r\nIf the set has a transmogrification for an item that is already transmogrified, the old transmogrification is lost.\r\nNote that same transmogrification restrictions apply when trying to use a set as in normal transmogrification.\r\n\r\nTo delete a set you can go to the set\'s menu and select delete set.'); +SET @sql1 := IF(@has_trinity_string > 0, 'REPLACE INTO `npc_text` (`ID`, `text0_0`) VALUES (65000, "Transmogrification allows you to change how your items look like without changing the stats of the items. Items used in transmogrification are no longer refundable, tradeable and are bound to you. Updating a menu updates the view and prices.")', 'SELECT 1'); +PREPARE stmt1 FROM @sql1; +EXECUTE stmt1; +DEALLOCATE PREPARE stmt1; -SET @STRING_ENTRY := 11100; -REPLACE INTO `trinity_string` (`entry`, `content_default`) VALUES -(@STRING_ENTRY+0, 'Item transmogrified'), -(@STRING_ENTRY+1, 'Equipment slot is empty'), -(@STRING_ENTRY+2, 'Invalid source item selected'), -(@STRING_ENTRY+3, 'Source item does not exist'), -(@STRING_ENTRY+4, 'Destination item does not exist'), -(@STRING_ENTRY+5, 'Selected items are invalid'), -(@STRING_ENTRY+6, 'Not enough money'), -(@STRING_ENTRY+7, 'You don\'t have enough tokens'), -(@STRING_ENTRY+8, 'Transmogrifications removed'), -(@STRING_ENTRY+9, 'There are no transmogrifications'), -(@STRING_ENTRY+10, 'Invalid name inserted'); +SET @sql2 := IF(@has_trinity_string > 0, 'REPLACE INTO `npc_text` (`ID`, `text0_0`) VALUES (65001, "You can save your own transmogrification sets. To save, first you must transmogrify your equipped items. Then when you go to the set management menu and go to save set menu, all items you have transmogrified are displayed.")', 'SELECT 1'); +PREPARE stmt2 FROM @sql2; +EXECUTE stmt2; +DEALLOCATE PREPARE stmt2; -SET @Entry = 190010, @Name = "Warpweaver"; -INSERT IGNORE INTO `creature_template` (`entry`, `modelid1`, `modelid2`, `name`, `subname`, `IconName`, `gossip_menu_id`, `minlevel`, `maxlevel`, `exp`, `faction`, `npcflag`, `scale`, `rank`, `dmgschool`, `baseattacktime`, `rangeattacktime`, `unit_class`, `unit_flags`, `type`, `type_flags`, `lootid`, `pickpocketloot`, `skinloot`, `AIName`, `MovementType`, `HoverHeight`, `RacialLeader`, `movementId`, `RegenHealth`, `mechanic_immune_mask`, `flags_extra`, `ScriptName`) VALUES -(@Entry, 19646, 0, @Name, "Transmogrifier", NULL, 0, 80, 80, 2, 35, 1, 1, 0, 0, 2000, 0, 1, 0, 7, 138936390, 0, 0, 0, '', 0, 1, 0, 0, 1, 0, 0, 'Creature_Transmogrify'); +SET @sql3 := IF(@has_trinity_string > 0, 'REPLACE INTO `trinity_string` (`entry`, `content_default`) VALUES (11100, "Item transmogrified"), (11101, "Equipment slot is empty"), (11102, "Invalid source item selected"), (11103, "Source item does not exist"), (11104, "Destination item does not exist"), (11105, "Selected items are invalid"), (11106, "Not enough money"), (11107, "You do not have enough tokens"), (11108, "Transmogrifications removed"), (11109, "There are no transmogrifications"), (11110, "Invalid name inserted")', 'SELECT 1'); +PREPARE stmt3 FROM @sql3; +EXECUTE stmt3; +DEALLOCATE PREPARE stmt3; -REPLACE INTO `npc_text` (`ID`, `text0_0`) VALUES -(65000, 'Transmogrification allows you to change how your items look like without changing the stats of the items.\r\nItems used in transmogrification are no longer refundable, tradeable and are bound to you.\r\nUpdating a menu updates the view and prices.\r\n\r\nNot everything can be transmogrified with eachother.\r\nRestrictions include but are not limited to:\r\nOnly armor and weapons can be transmogrified\r\nGuns, bows and crossbows can be transmogrified with eachother\r\nFishing poles can not be transmogrified\r\nYou must be able to equip both items used in the process.\r\n\r\nTransmogrifications stay on your items as long as you own them.\r\nIf you try to put the item in guild bank or mail it to someone else, the transmogrification is stripped.\r\n\r\nYou can also remove transmogrifications for free at the transmogrifier.'), -(65001, 'You can save your own transmogrification sets.\r\n\r\nTo save, first you must transmogrify your equipped items.\r\nThen when you go to the set management menu and go to save set menu,\r\nall items you have transmogrified are displayed so you see what you are saving.\r\nIf you think the set is fine, you can click to save the set and name it as you wish.\r\n\r\nTo use a set you can click the saved set in the set management menu and then select use set.\r\nIf the set has a transmogrification for an item that is already transmogrified, the old transmogrification is lost.\r\nNote that same transmogrification restrictions apply when trying to use a set as in normal transmogrification.\r\n\r\nTo delete a set you can go to the set\'s menu and select delete set.'); \ No newline at end of file +SET @sql4 := IF(@has_trinity_string > 0, 'INSERT IGNORE INTO `creature_template` (`entry`, `modelid1`, `modelid2`, `name`, `subname`, `IconName`, `gossip_menu_id`, `minlevel`, `maxlevel`, `exp`, `faction`, `npcflag`, `scale`, `rank`, `dmgschool`, `baseattacktime`, `rangeattacktime`, `unit_class`, `unit_flags`, `type`, `type_flags`, `lootid`, `pickpocketloot`, `skinloot`, `AIName`, `MovementType`, `HoverHeight`, `RacialLeader`, `movementId`, `RegenHealth`, `mechanic_immune_mask`, `flags_extra`, `ScriptName`) VALUES (190010, 19646, 0, "Warpweaver", "Transmogrifier", NULL, 0, 80, 80, 2, 35, 1, 1, 0, 0, 2000, 0, 1, 0, 7, 138936390, 0, 0, 0, "", 0, 1, 0, 0, 1, 0, 0, "Creature_Transmogrify")', 'SELECT 1'); +PREPARE stmt4 FROM @sql4; +EXECUTE stmt4; +DEALLOCATE PREPARE stmt4; \ No newline at end of file diff --git a/sql/updates/world/3.3.5/2024_08_17_00_world.sql b/sql/updates/world/3.3.5/2024_08_17_00_world.sql index e12e7cf1eacf3..8a0cfc312580a 100644 --- a/sql/updates/world/3.3.5/2024_08_17_00_world.sql +++ b/sql/updates/world/3.3.5/2024_08_17_00_world.sql @@ -1,3 +1,16 @@ -- TDB 335.24081 world -UPDATE `version` SET `db_version`='TDB 335.24081', `cache_id`=24081 LIMIT 1; +SET @has_version := ( + SELECT COUNT(*) + FROM information_schema.tables + WHERE table_schema = DATABASE() + AND table_name = 'version' +); +SET @version_update_sql := IF( + @has_version > 0, + 'UPDATE `version` SET `db_version`=''TDB 335.24081'', `cache_id`=24081 LIMIT 1', + 'SELECT 1' +); +PREPARE stmt FROM @version_update_sql; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; UPDATE `updates` SET `state`='ARCHIVED';