forked from LichKing255/AshamaneCoreLegacy
-
Notifications
You must be signed in to change notification settings - Fork 3
Closed
Description
Description:
The project currently fails to compile on Windows using Visual Studio 2017 (MSVC v141) due to multiple C++20 features being used in a codebase configured for C++17. Below is a detailed list of all the changes required to make the project compile successfully on Windows.
See Fork with fixes: #13
- dep/g3dlite/source/debugAssert.cpp — Line 106
The assignment to LPTSTR from a string literal fails because the project uses Unicode character set.
// Before:
realLastErr = _T("Last error code does not exist.");
// After:
realLastErr = (LPTSTR)_T("Last error code does not exist.");
- src/common/Debugging/WheatyExceptionReport.cpp and WheatyExceptionReport.h
The function GetExceptionString is declared and defined as returning LPTSTR but actually returns const char* literals, causing C2440 errors.
// Before (in both .cpp and .h):
LPTSTR GetExceptionString(DWORD dwCode)
LPTSTR WheatyExceptionReport::GetExceptionString(DWORD dwCode)
// After:
LPCTSTR GetExceptionString(DWORD dwCode)
LPCTSTR WheatyExceptionReport::GetExceptionString(DWORD dwCode)
Additionally, calls to DumpTypeIndex passing "" as the 7th argument need a cast:
// Before:
DumpTypeIndex(..., "");
// After:
DumpTypeIndex(..., (char*)"");
- src/common/Utilities/Types.h
std::type_identity is a C++20 feature not available in C++17. A custom implementation needs to be added.
// Before:
struct find_type_if<Check, T1, Ts...> : std::conditional_t<Check<T1>::value, std::type_identity<T1>, find_type_if<Check, Ts...>>
// After — add custom type_identity before the struct:
template<typename T>
struct type_identity { using type = T; };
template<template<typename...> typename Check, typename T1, typename... Ts>
struct find_type_if<Check, T1, Ts...> : std::conditional_t<Check<T1>::value, type_identity<T1>, find_type_if<Check, Ts...>>
- src/server/database/Database/FieldValueConverters.h
std::type_identity_t is C++20. Replace with the custom Trinity::type_identity.
// Before:
class PrimitiveResultValueConverter<char const*, std::type_identity_t>
using StringResultValueConverter = PrimitiveResultValueConverter<char const*, std::type_identity_t>;
// After:
class PrimitiveResultValueConverter<char const*, Trinity::type_identity>
using StringResultValueConverter = PrimitiveResultValueConverter<char const*, Trinity::type_identity>;
- src/server/database/Database/QueryCallback.cpp
Template lambdas ([&](...)) are C++20. Replace with a struct Visitor, and the lambda passed as std::function<bool()>& must be stored in a named variable first.
// Before:
return std::visit([&]<typename Result>(std::future<Result>&& future)
{
...
}, std::move(_query));
// After:
struct Visitor
{
QueryCallback& self;
std::function<bool()>& checkStateAndReturnCompletion;
bool operator()(std::future<QueryResult>&& future) { ... }
bool operator()(std::future<PreparedQueryResult>&& future) { ... }
};
std::function<bool()> checkFn = checkStateAndReturnCompletion;
Visitor v{*this, checkFn};
return std::visit(v, std::move(_query));
- src/server/database/Database/MySQLPreparedStatement.cpp
std::chrono::year_month_day, hh_mm_ss, and sys_days are C++20. Replace with C++17 compatible code using gmtime.
// Before:
std::chrono::year_month_day ymd(time_point_cast<std::chrono::days>(value));
std::chrono::hh_mm_ss hms(duration_cast<std::chrono::microseconds>(value - std::chrono::sys_days(ymd)));
MYSQL_TIME* time = reinterpret_cast<MYSQL_TIME*>(static_cast<char*>(param->buffer));
time->year = static_cast<int32>(ymd.year());
time->month = static_cast<uint32>(ymd.month());
time->day = static_cast<uint32>(ymd.day());
time->hour = hms.hours().count();
time->minute = hms.minutes().count();
time->second = hms.seconds().count();
time->second_part = hms.subseconds().count();
// After:
time_t tt = std::chrono::system_clock::to_time_t(value);
tm* t = gmtime(&tt);
MYSQL_TIME* time = reinterpret_cast<MYSQL_TIME*>(static_cast<char*>(param->buffer));
time->year = t->tm_year + 1900;
time->month = t->tm_mon + 1;
time->day = t->tm_mday;
time->hour = t->tm_hour;
time->minute = t->tm_min;
time->second = t->tm_sec;
time->second_part = 0;
- src/server/database/Database/QueryResult.cpp
Same C++20 date functions (year, month, day, sys_days). Replace with std::tm and mktime.
// Before:
case MYSQL_TIMESTAMP_DATE:
return sys_days(year(source.year) / month(source.month) / day(source.day));
case MYSQL_TIMESTAMP_DATETIME:
return sys_days(year(source.year) / month(source.month) / day(source.day))
+ hours(source.hour) + minutes(source.minute)
+ seconds(source.second) + microseconds(source.second_part);
// After:
case MYSQL_TIMESTAMP_DATE:
{
std::tm t = {};
t.tm_year = source.year - 1900;
t.tm_mon = source.month - 1;
t.tm_mday = source.day;
time_t tt = mktime(&t);
return std::chrono::system_clock::from_time_t(tt);
}
case MYSQL_TIMESTAMP_DATETIME:
{
std::tm t = {};
t.tm_year = source.year - 1900;
t.tm_mon = source.month - 1;
t.tm_mday = source.day;
t.tm_hour = source.hour;
t.tm_min = source.minute;
t.tm_sec = source.second;
time_t tt = mktime(&t);
return std::chrono::system_clock::from_time_t(tt)
+ std::chrono::microseconds(source.second_part);
}
- src/server/database/Database/MySQLConnection.cpp
Designated initializers ({ .field = value }) are C++20. Replace with direct member assignment. Also, executor_work_guard has a deleted copy assignment operator, so it must be moved using aggregate initialization.
// Before:
m_workerThread = std::make_unique<WorkerThread>(WorkerThread{
.ThreadHandle = std::thread([context] { context->run(); }),
.WorkGuard = std::move(executorWorkGuard)
});
// After:
m_workerThread = std::make_unique<WorkerThread>(WorkerThread{
std::thread([context] { context->run(); }),
std::move(executorWorkGuard)
});
- src/server/game/Entities/Player/Player.cpp — Line 28732
std::to_address is C++20. The field BuildingInfo.PacketInfo is a std::optional, so use has_value() and operator* instead.
// Before:
garrisonInfo.Buildings.push_back(std::to_address(plot->BuildingInfo.PacketInfo));
// After:
garrisonInfo.Buildings.push_back(plot->BuildingInfo.PacketInfo.has_value() ? &(*plot->BuildingInfo.PacketInfo) : nullptr);
- src/server/game/Handlers/PetHandler.cpp — Line 523
Same std::to_address issue with std::optional.
// Before:
DeclinedName const* declinedname = std::to_address(packet.RenameData.DeclinedNames);
// After:
DeclinedName const* declinedname = packet.RenameData.DeclinedNames.has_value() ? &(*packet.RenameData.DeclinedNames) : nullptr;
- src/server/game/Spells/SpellEffects.cpp — Lines 4473 and 4476
Same std::to_address issue with OptionalMovement::SpellEffectExtraData.
// Before (line 4473):
m_caster->GetMotionMaster()->MoveCharge(..., std::to_address(spellEffectExtraData));
// After:
m_caster->GetMotionMaster()->MoveCharge(..., spellEffectExtraData ? &(*spellEffectExtraData) : nullptr);
- src/server/scripts/Draenor/Highmaul/boss_the_butcher.cpp — Line 403
std::random_shuffle was removed in C++17. Replace with std::shuffle and add #include .
// Before:
std::random_shuffle(l_Indexes.begin(), l_Indexes.end());
// After:
#include <random> // add at top of file
std::shuffle(l_Indexes.begin(), l_Indexes.end(), std::mt19937{std::random_device{}()});
- src/server/scripts/Northrend/Nexus/Oculus/boss_urom.cpp — Line 105
Same std::random_shuffle removal. Add #include .
// Before:
std::random_shuffle(group, group + 3);
// After:
#include <random> // add at top of file
std::shuffle(group, group + 3, std::mt19937{std::random_device{}()});
Environment:
- OS: Windows 10/11
- Compiler: MSVC v141 (Visual Studio 2017)
- C++ Standard: /std:c++17 (though some code requires C++20 features)
- Boost: 1.78.0
- MySQL: 8.0
- OpenSSL: 3.x
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels