24#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<uint64> 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&)
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&)
487 result.reserve(wstr.length() * 2);
492 for (
wchar_t wchar : wstr)
547 for (
wchar_t wchar : wstr)
562 for (
wchar_t wchar : wstr)
593 for (
wchar_t wchar : wstr)
599 result += wchar_t(0x435);
611 for (
wchar_t wchar : wstr)
676 static std::wstring
const a_End = { wchar_t(0x0430) };
677 static std::wstring
const o_End = { wchar_t(0x043E) };
678 static std::wstring
const ya_End = { wchar_t(0x044F) };
679 static std::wstring
const ie_End = { wchar_t(0x0435) };
680 static std::wstring
const i_End = { wchar_t(0x0438) };
681 static std::wstring
const yeru_End = { wchar_t(0x044B) };
682 static std::wstring
const u_End = { wchar_t(0x0443) };
683 static std::wstring
const yu_End = { wchar_t(0x044E) };
684 static std::wstring
const oj_End = { wchar_t(0x043E), wchar_t(0x0439) };
685 static std::wstring
const ie_j_End = { wchar_t(0x0435), wchar_t(0x0439) };
686 static std::wstring
const io_j_End = { wchar_t(0x0451), wchar_t(0x0439) };
687 static std::wstring
const o_m_End = { wchar_t(0x043E), wchar_t(0x043C) };
688 static std::wstring
const io_m_End = { wchar_t(0x0451), wchar_t(0x043C) };
689 static std::wstring
const ie_m_End = { wchar_t(0x0435), wchar_t(0x043C) };
690 static std::wstring
const soft_End = { wchar_t(0x044C) };
691 static std::wstring
const j_End = { wchar_t(0x0439) };
693 static std::array<std::array<std::wstring const*, 7>, 6>
const dropEnds = {{
694 { &a_End, &o_End, &ya_End, &ie_End, &soft_End, &j_End,
nullptr },
695 { &a_End, &ya_End, &yeru_End, &i_End,
nullptr,
nullptr,
nullptr },
696 { &ie_End, &u_End, &yu_End, &i_End,
nullptr,
nullptr,
nullptr },
697 { &u_End, &yu_End, &o_End, &ie_End, &soft_End, &ya_End, &a_End },
698 { &oj_End, &io_j_End, &ie_j_End, &o_m_End, &io_m_End, &ie_m_End, &yu_End },
699 { &ie_End, &i_End,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr }
702 std::size_t
const thisLen = wname.length();
703 std::array<std::wstring const*, 7>
const& endings = dropEnds[declension];
704 for (
auto itr = endings.begin(), end = endings.end(); (itr != end) && *itr; ++itr)
706 std::wstring
const& ending = **itr;
707 std::size_t
const endLen = ending.length();
708 if (!(endLen <= thisLen))
711 if (wname.substr(thisLen-endLen, thisLen) == ending)
712 return wname.substr(0, thisLen-endLen);
720#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS
725 conStr.resize(wstr.size());
726 CharToOemBuffW(&wstr[0], &conStr[0],
uint32(wstr.size()));
737#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS
739 wstr.resize(conStr.size());
740 OemToCharBuffW(&conStr[0], &wstr[0],
uint32(conStr.size()));
750bool Utf8FitTo(std::string_view str, std::wstring_view search)
760 if (temp.find(search) == std::wstring::npos)
776#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS
777 char temp_buf[32 * 1024];
778 wchar_t wtemp_buf[32 * 1024];
780 size_t temp_len = vsnprintf(temp_buf, 32 * 1024, str, *ap);
782 if (temp_len ==
size_t(-1))
783 temp_len = 32*1024-1;
785 size_t wtemp_len = 32*1024-1;
786 Utf8toWStr(temp_buf, temp_len, wtemp_buf, wtemp_len);
788 CharToOemBuffW(&wtemp_buf[0], &temp_buf[0],
uint32(wtemp_len + 1));
789 fprintf(out,
"%s", temp_buf);
791 vfprintf(out, str, *ap);
806#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS
809 wchar_t* commandbuf =
new wchar_t[
size + 1];
810 HANDLE hConsole = GetStdHandle(STD_INPUT_HANDLE);
813 if (!ReadConsoleW(hConsole, commandbuf,
size, &read,
nullptr) || read == 0)
819 commandbuf[read] = 0;
821 bool ok =
WStrToUtf8(commandbuf, wcslen(commandbuf), str);
829 wstr.reserve(str.length());
833 HANDLE hConsole = GetStdHandle(error ? STD_ERROR_HANDLE : STD_OUTPUT_HANDLE);
836 return WriteConsoleW(hConsole, wstr.c_str(), wstr.size(), &write,
nullptr);
842 std::size_t nextLineIndex = str.find_first_of(
"\r\n");
843 if (nextLineIndex == std::string::npos)
846 str.erase(nextLineIndex);
847 return nextLineIndex;
853 int32 end = arrayLen;
864 result.reserve(arrayLen * 2);
865 auto inserter = std::back_inserter(result);
866 for (
int32 i = init; i != end; i += op)
874 ASSERT(str.size() == (2 * outlen));
882 init =
int32(str.length() - 2);
888 for (
int32 i = init; i != end; i += 2 * op)
889 out[j++] = Trinity::StringTo<uint8>(str.substr(i, 2), 16).value_or(0);
894 return std::equal(a.begin(), a.end(), b.begin(), b.end(), [](
char c1,
char c2) { return std::tolower(c1) == std::tolower(c2); });
899 return haystack.end() !=
900 std::search(haystack.begin(), haystack.end(), needle.begin(), needle.end(), [](
char c1,
char c2) { return std::tolower(c1) == std::tolower(c2); });
905 return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end(), [](
char c1,
char c2) { return std::tolower(c1) < std::tolower(c2); });
910 return boost::core::demangle(info.name());
915 return degrees * (2.f * float(
M_PI) / 360.f);
std::optional< T > Optional
Optional helper class to wrap optional values within.
float DegToRad(float degrees)
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)
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::wstring wstrCaseAccentInsensitiveParse(std::wstring_view wstr, LocaleConstant locale)
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)
Optional< int64 > MoneyStringToMoney(std::string const &moneyString)
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.
constexpr std::size_t size()