32#include <boost/core/demangle.hpp>
36#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS
37 auto isWindowsBuildGreaterOrEqual = [](DWORD build)
39 OSVERSIONINFOEX osvi = {
sizeof(osvi), 0, 0, build, 0, {0}, 0, 0, 0, 0 };
40 ULONGLONG conditionMask = 0;
41 VER_SET_CONDITION(conditionMask, VER_BUILDNUMBER, VER_GREATER_EQUAL);
43 return VerifyVersionInfo(&osvi, VER_BUILDNUMBER, conditionMask);
46 if (!isWindowsBuildGreaterOrEqual(TRINITY_REQUIRED_WINDOWS_BUILD))
48 OSVERSIONINFOEX osvi = {
sizeof(osvi), 0, 0, 0, 0, {0}, 0, 0, 0, 0 };
49 GetVersionEx((LPOSVERSIONINFO)&osvi);
50 ABORT_MSG(
"TrinityCore requires Windows 10 19H1 (1903) or Windows Server 2019 (1903) - require build number 10.0.%d but found %d.%d.%d",
51 TRINITY_REQUIRED_WINDOWS_BUILD, osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber);
56std::vector<std::string_view>
Trinity::Tokenize(std::string_view str,
char sep,
bool keepEmpty)
58 std::vector<std::string_view> tokens;
61 for (
size_t end = str.find(sep); end != std::string_view::npos; end = str.find(sep, start))
63 if (keepEmpty || (start < end))
64 tokens.push_back(str.substr(start, end - start));
68 if (keepEmpty || (start < str.length()))
69 tokens.push_back(str.substr(start));
74#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__))
75struct tm* localtime_r(time_t
const* time,
struct tm *result)
77 if (localtime_s(result, time) != 0)
81struct tm* gmtime_r(time_t
const* time,
struct tm* result)
83 if (gmtime_s(result, time) != 0)
87time_t timegm(
struct tm* tm)
96 localtime_r(&time, &timeLocal);
103 timeLocal.tm_hour = 0;
104 timeLocal.tm_min = 0;
105 timeLocal.tm_sec = 0;
106 time_t midnightLocal = mktime(&timeLocal);
107 time_t hourLocal = midnightLocal + hour *
HOUR;
109 if (onlyAfterTime && hourLocal <= time)
134 std::ostringstream ss;
150 return "<Unknown time format>";
154 if (hours || hoursOnly)
169 return "<Unknown time format>";
189 return "<Unknown time format>";
193 if (secs || (!days && !hours && !minutes))
208 return "<Unknown time format>";
227 switch (token[token.length() - 1])
230 if (hadG)
return std::nullopt;
235 if (hadS)
return std::nullopt;
240 if (hadC)
return std::nullopt;
248 Optional<uint32> amount = Trinity::StringTo<uint32>(token.substr(0, token.length() - 1));
250 money += (unit * *amount);
264 for (
char itr : timestring)
275 case 'd': multiplier =
DAY;
break;
276 case 'h': multiplier =
HOUR;
break;
277 case 'm': multiplier =
MINUTE;
break;
278 case 's': multiplier = 1;
break;
281 buffer *= multiplier;
293 localtime_r(&t, &aTm);
300 return Trinity::StringFormat(
"{:04}-{:02}-{:02}_{:02}-{:02}-{:02}", aTm.tm_year + 1900, aTm.tm_mon + 1, aTm.tm_mday, aTm.tm_hour, aTm.tm_min, aTm.tm_sec);
306 localtime_r(&t, &time);
308 strftime(buf, 30,
"%c", &time);
309 return std::string(buf);
318 boost::system::error_code error;
319 Trinity::Net::make_address(ipaddress, error);
326 FILE* pid_file = fopen(filename.c_str(),
"w");
327 if (pid_file ==
nullptr)
332 fprintf(pid_file,
"%u", pid);
341 DWORD pid = GetCurrentProcessId();
343 pid_t pid = getpid();
353 return utf8::distance(utf8str.c_str(), utf8str.c_str()+utf8str.size());
355 catch(std::exception
const&)
366 size_t wlen = utf8::distance(utf8str.c_str(), utf8str.c_str()+utf8str.size());
372 utf8::utf8to16(utf8str.c_str(), utf8str.c_str()+utf8str.size(), &wstr[0]);
374 char* oend = utf8::utf16to8(wstr.c_str(), wstr.c_str()+wstr.size(), &utf8str[0]);
375 utf8str.resize(oend-(&utf8str[0]));
377 catch(std::exception
const&)
383bool Utf8toWStr(
char const* utf8str,
size_t csize,
wchar_t* wstr,
size_t& wsize)
388 out = utf8::utf8to16(utf8str, utf8str+csize, out);
392 catch(std::exception
const&)
396 wchar_t const* errorMessage = L
"An error occurred converting string from UTF-8 to WStr";
397 size_t errorMessageLength = wcslen(errorMessage);
398 if (wsize >= errorMessageLength)
400 wcscpy(wstr, errorMessage);
401 wsize = wcslen(wstr);
422 utf8::utf8to16(utf8str.begin(), utf8str.end(), std::back_inserter(wstr));
424 catch(std::exception
const&)
433bool WStrToUtf8(
wchar_t const* wstr,
size_t size, std::string& utf8str)
437 std::string utf8str2;
438 utf8str2.resize(size*4);
442 char* oend = utf8::utf16to8(wstr, wstr+size, &utf8str2[0]);
443 utf8str2.resize(oend-(&utf8str2[0]));
447 catch(std::exception
const&)
460 std::string utf8str2;
461 utf8str2.resize(wstr.size()*4);
465 char* oend = utf8::utf16to8(wstr.begin(), wstr.end(), &utf8str2[0]);
466 utf8str2.resize(oend-(&utf8str2[0]));
470 catch(std::exception
const&)
491 static std::wstring
const a_End = { wchar_t(0x0430) };
492 static std::wstring
const o_End = { wchar_t(0x043E) };
493 static std::wstring
const ya_End = { wchar_t(0x044F) };
494 static std::wstring
const ie_End = { wchar_t(0x0435) };
495 static std::wstring
const i_End = { wchar_t(0x0438) };
496 static std::wstring
const yeru_End = { wchar_t(0x044B) };
497 static std::wstring
const u_End = { wchar_t(0x0443) };
498 static std::wstring
const yu_End = { wchar_t(0x044E) };
499 static std::wstring
const oj_End = { wchar_t(0x043E), wchar_t(0x0439) };
500 static std::wstring
const ie_j_End = { wchar_t(0x0435), wchar_t(0x0439) };
501 static std::wstring
const io_j_End = { wchar_t(0x0451), wchar_t(0x0439) };
502 static std::wstring
const o_m_End = { wchar_t(0x043E), wchar_t(0x043C) };
503 static std::wstring
const io_m_End = { wchar_t(0x0451), wchar_t(0x043C) };
504 static std::wstring
const ie_m_End = { wchar_t(0x0435), wchar_t(0x043C) };
505 static std::wstring
const soft_End = { wchar_t(0x044C) };
506 static std::wstring
const j_End = { wchar_t(0x0439) };
508 static std::array<std::array<std::wstring const*, 7>, 6>
const dropEnds = {{
509 { &a_End, &o_End, &ya_End, &ie_End, &soft_End, &j_End,
nullptr },
510 { &a_End, &ya_End, &yeru_End, &i_End,
nullptr,
nullptr,
nullptr },
511 { &ie_End, &u_End, &yu_End, &i_End,
nullptr,
nullptr,
nullptr },
512 { &u_End, &yu_End, &o_End, &ie_End, &soft_End, &ya_End, &a_End },
513 { &oj_End, &io_j_End, &ie_j_End, &o_m_End, &io_m_End, &ie_m_End, &yu_End },
514 { &ie_End, &i_End,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr }
517 std::size_t
const thisLen = wname.length();
518 std::array<std::wstring const*, 7>
const& endings = dropEnds[declension];
519 for (
auto itr = endings.begin(), end = endings.end(); (itr != end) && *itr; ++itr)
521 std::wstring
const& ending = **itr;
522 std::size_t
const endLen = ending.length();
523 if (!(endLen <= thisLen))
526 if (wname.substr(thisLen-endLen, thisLen) == ending)
527 return wname.substr(0, thisLen-endLen);
535#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS
540 conStr.resize(wstr.size());
541 CharToOemBuffW(&wstr[0], &conStr[0],
uint32(wstr.size()));
552#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS
554 wstr.resize(conStr.size());
555 OemToCharBuffW(&conStr[0], &wstr[0],
uint32(conStr.size()));
565bool Utf8FitTo(std::string_view str, std::wstring_view search)
575 if (temp.find(search) == std::wstring::npos)
591#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS
592 char temp_buf[32 * 1024];
593 wchar_t wtemp_buf[32 * 1024];
595 size_t temp_len = vsnprintf(temp_buf, 32 * 1024, str, *ap);
597 if (temp_len ==
size_t(-1))
598 temp_len = 32*1024-1;
600 size_t wtemp_len = 32*1024-1;
601 Utf8toWStr(temp_buf, temp_len, wtemp_buf, wtemp_len);
603 CharToOemBuffW(&wtemp_buf[0], &temp_buf[0],
uint32(wtemp_len + 1));
604 fprintf(out,
"%s", temp_buf);
606 vfprintf(out, str, *ap);
621#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS
624 wchar_t* commandbuf =
new wchar_t[size + 1];
625 HANDLE hConsole = GetStdHandle(STD_INPUT_HANDLE);
628 if (!ReadConsoleW(hConsole, commandbuf, size, &read,
nullptr) || read == 0)
634 commandbuf[read] = 0;
636 bool ok =
WStrToUtf8(commandbuf, wcslen(commandbuf), str);
647 HANDLE hConsole = GetStdHandle(error ? STD_ERROR_HANDLE : STD_OUTPUT_HANDLE);
650 return WriteConsoleW(hConsole, wstr.c_str(), wstr.size(), &write,
nullptr);
656 std::size_t nextLineIndex = str.find_first_of(
"\r\n");
657 if (nextLineIndex == std::string::npos)
660 str.erase(nextLineIndex);
661 return nextLineIndex;
667 int32 end = arrayLen;
678 result.reserve(arrayLen * 2);
679 auto inserter = std::back_inserter(result);
680 for (
int32 i = init; i != end; i += op)
688 ASSERT(str.size() == (2 * outlen));
696 init =
int32(str.length() - 2);
702 for (
int32 i = init; i != end; i += 2 * op)
703 out[j++] = Trinity::StringTo<uint8>(str.substr(i, 2), 16).value_or(0);
708 return std::equal(a.begin(), a.end(), b.begin(), b.end(), [](
char c1,
char c2) { return std::tolower(c1) == std::tolower(c2); });
713 return haystack.end() !=
714 std::search(haystack.begin(), haystack.end(), needle.begin(), needle.end(), [](
char c1,
char c2) { return std::tolower(c1) == std::tolower(c2); });
719 return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end(), [](
char c1,
char c2) { return std::tolower(c1) < std::tolower(c2); });
724 return boost::core::demangle(info.name());
std::optional< T > Optional
Optional helper class to wrap optional values within.
bool consoleToUtf8(std::string_view conStr, std::string &utf8str)
std::wstring GetMainPartOfName(std::wstring const &wname, uint32 declension)
bool StringEqualI(std::string_view a, std::string_view b)
bool WriteWinConsole(std::string_view str, bool error)
bool WStrToUtf8(wchar_t const *wstr, size_t size, std::string &utf8str)
bool Utf8ToUpperOnlyLatin(std::string &utf8String)
void wstrToLower(std::wstring &str)
bool IsIPAddress(char const *ipaddress)
Check if the string is a valid ip address representation.
std::string TimeToTimestampStr(time_t t)
Optional< int32 > MoneyStringToMoney(std::string const &moneyString)
bool StringContainsStringI(std::string_view haystack, std::string_view needle)
time_t GetLocalHourTimestamp(time_t time, uint8 hour, bool onlyAfterTime)
void utf8printf(FILE *out, const char *str,...)
void strToLower(std::string &str)
TC_COMMON_API Optional< std::size_t > RemoveCRLF(std::string &str)
uint32 CreatePIDFile(std::string const &filename)
create PID file
bool utf8ToConsole(std::string_view utf8str, std::string &conStr)
tm TimeBreakdown(time_t time)
std::string TimeToHumanReadable(time_t t)
bool StringCompareLessI(std::string_view a, std::string_view b)
bool Utf8FitTo(std::string_view str, std::wstring_view search)
std::string secsToTimeString(uint64 timeInSecs, TimeFormat timeFormat, bool hoursOnly)
bool Utf8toWStr(char const *utf8str, size_t csize, wchar_t *wstr, size_t &wsize)
bool ReadWinConsole(std::string &str, size_t size)
size_t utf8length(std::string &utf8str)
void utf8truncate(std::string &utf8str, size_t len)
uint32 TimeStringToSecs(std::string const ×tring)
void wstrToUpper(std::wstring &str)
void strToUpper(std::string &str)
void vutf8printf(FILE *out, const char *str, va_list *ap)
struct WcharToUpperOnlyLatin wcharToUpperOnlyLatin
struct WcharToLower wcharToLower
struct CharToUpper charToUpper
bool isCyrillicCharacter(wchar_t wchar)
struct CharToLower charToLower
struct WcharToUpper wcharToUpper
TC_COMMON_API void HexStrToByteArray(std::string_view str, uint8 *out, size_t outlen, bool reverse=false)
TC_COMMON_API std::string ByteArrayToHexStr(uint8 const *bytes, size_t length, bool reverse=false)
TC_COMMON_API std::string GetTypeName(std::type_info const &)
TC_COMMON_API void VerifyOsVersion()
TC_COMMON_API std::vector< std::string_view > Tokenize(std::string_view str, char sep, bool keepEmpty)
OutputIt StringFormatTo(OutputIt out, FormatString< Args... > fmt, Args &&... args)
std::string StringFormat(FormatString< Args... > fmt, Args &&... args)
Default TC string format function.