Merge commit 'bba8555a29ea5cde018a73f92f1e6aa1a61351de' into 4.3.4
Conflicts: dep/cppformat/CMakeLists.txt dep/cppformat/ChangeLog.rst dep/cppformat/format.cc dep/cppformat/format.h dep/cppformat/posix.cc dep/cppformat/posix.h sql/updates/world/2015_03_16_02_world.sql sql/updates/world/2015_03_16_03_world.sql sql/updates/world/2015_03_16_04_world.sql sql/updates/world/2015_03_16_05_world.sql sql/updates/world/2015_03_16_06_world.sql sql/updates/world/2015_03_17_00_world.sql src/server/game/Conditions/ConditionMgr.cpp src/server/game/Conditions/ConditionMgr.h src/server/worldserver/CMakeLists.txt
This commit is contained in:
commit
b82a072b25
41 files changed
+813
-1193
No files matched your search
@@ -35,6 +35,7 @@ if(SERVERS OR TOOLS)
|
||||
endif()
|
||||
|
||||
if(SERVERS)
|
||||
add_subdirectory(cppformat)
|
||||
add_subdirectory(gsoap)
|
||||
add_subdirectory(zmqpp)
|
||||
endif()
|
||||
|
||||
@@ -8,6 +8,10 @@ bzip2 (a freely available, patent free, high-quality data compressor)
|
||||
http://www.bzip.org/
|
||||
Version: 1.0.6
|
||||
|
||||
cppformat (type safe format library)
|
||||
https://github.com/cppformat/cppformat
|
||||
Version: 1.1.0 da547f5533f338cc0c65877b44ca40adf31754f7
|
||||
|
||||
G3D (a commercial-grade C++ 3D engine available as Open Source (BSD License)
|
||||
http://g3d.sourceforge.net/
|
||||
Version: 9.0-Release r4036
|
||||
|
||||
@@ -6,7 +6,12 @@ set(FMT_SOURCES format.cc format.h)
|
||||
# Use variadic templates
|
||||
add_definitions(-DFMT_VARIADIC_TEMPLATES=1)
|
||||
|
||||
# Use deleted functions
|
||||
# Check if initializer lists are supported.
|
||||
check_cxx_source_compiles("
|
||||
#include <initilizer_list>
|
||||
int main() {}" FMT_INITIALIZER_LIST)
|
||||
|
||||
# Use delete
|
||||
add_definitions(-DFMT_USE_DELETED_FUNCTIONS=1)
|
||||
|
||||
# Use static assert
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
`#96 <https://github.com/cppformat/cppformat/issues/96>`_ and
|
||||
`#114 <https://github.com/cppformat/cppformat/pull/114>`_).
|
||||
|
||||
* Added `changelog <https://github.com/cppformat/cppformat/blob/master/ChangeLog.rst>`_
|
||||
* Added `changelog <https://github.com/cppformat/cppformat/edit/master/ChangeLog.rst>`_
|
||||
(`#103 <https://github.com/cppformat/cppformat/issues/103>`_).
|
||||
|
||||
1.0.0 - 2015-02-05
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
Copyright (c) 2014 - 2015, Victor Zverovich
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
+259
-401
@@ -35,18 +35,11 @@
|
||||
#include <cmath>
|
||||
#include <cstdarg>
|
||||
|
||||
#if defined(_WIN32) && defined(__MINGW32__)
|
||||
# include <cstring>
|
||||
#endif
|
||||
|
||||
#if FMT_USE_WINDOWS_H
|
||||
# if defined(NOMINMAX) || defined(FMT_WIN_MINMAX)
|
||||
# include <windows.h>
|
||||
# else
|
||||
# define NOMINMAX
|
||||
# include <windows.h>
|
||||
# undef NOMINMAX
|
||||
#ifdef _WIN32
|
||||
# ifdef __MINGW32__
|
||||
# include <cstring>
|
||||
# endif
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
using fmt::internal::Arg;
|
||||
@@ -73,8 +66,10 @@ using fmt::internal::Arg;
|
||||
#ifndef FMT_THROW
|
||||
# if FMT_EXCEPTIONS
|
||||
# define FMT_THROW(x) throw x
|
||||
# define FMT_RETURN_AFTER_THROW(x)
|
||||
# else
|
||||
# define FMT_THROW(x) assert(false)
|
||||
# define FMT_RETURN_AFTER_THROW(x) return x
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@@ -88,21 +83,8 @@ using fmt::internal::Arg;
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4127) // conditional expression is constant
|
||||
# pragma warning(disable: 4702) // unreachable code
|
||||
// Disable deprecation warning for strerror. The latter is not called but
|
||||
// MSVC fails to detect it.
|
||||
# pragma warning(disable: 4996)
|
||||
#endif
|
||||
|
||||
// Dummy implementations of strerror_r and strerror_s called if corresponding
|
||||
// system functions are not available.
|
||||
static inline fmt::internal::None<> strerror_r(int, char *, ...) {
|
||||
return fmt::internal::None<>();
|
||||
}
|
||||
static inline fmt::internal::None<> strerror_s(char *, std::size_t, ...) {
|
||||
return fmt::internal::None<>();
|
||||
}
|
||||
|
||||
namespace fmt {
|
||||
namespace {
|
||||
|
||||
#ifndef _MSC_VER
|
||||
@@ -158,61 +140,36 @@ typedef void (*FormatFunc)(fmt::Writer &, int, fmt::StringRef);
|
||||
// Buffer should be at least of size 1.
|
||||
int safe_strerror(
|
||||
int error_code, char *&buffer, std::size_t buffer_size) FMT_NOEXCEPT {
|
||||
FMT_ASSERT(buffer != 0 && buffer_size != 0, "invalid buffer");
|
||||
|
||||
class StrError {
|
||||
private:
|
||||
int error_code_;
|
||||
char *&buffer_;
|
||||
std::size_t buffer_size_;
|
||||
|
||||
// A noop assignment operator to avoid bogus warnings.
|
||||
void operator=(const StrError &) {}
|
||||
|
||||
// Handle the result of XSI-compliant version of strerror_r.
|
||||
int handle(int result) {
|
||||
// glibc versions before 2.13 return result in errno.
|
||||
return result == -1 ? errno : result;
|
||||
}
|
||||
|
||||
// Handle the result of GNU-specific version of strerror_r.
|
||||
int handle(char *message) {
|
||||
// If the buffer is full then the message is probably truncated.
|
||||
if (message == buffer_ && strlen(buffer_) == buffer_size_ - 1)
|
||||
return ERANGE;
|
||||
buffer_ = message;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Handle the case when strerror_r is not available.
|
||||
int handle(fmt::internal::None<>) {
|
||||
return fallback(strerror_s(buffer_, buffer_size_, error_code_));
|
||||
}
|
||||
|
||||
// Fallback to strerror_s when strerror_r is not available.
|
||||
int fallback(int result) {
|
||||
// If the buffer is full then the message is probably truncated.
|
||||
return result == 0 && strlen(buffer_) == buffer_size_ - 1 ?
|
||||
ERANGE : result;
|
||||
}
|
||||
|
||||
// Fallback to strerror if strerror_r and strerror_s are not available.
|
||||
int fallback(fmt::internal::None<>) {
|
||||
errno = 0;
|
||||
buffer_ = strerror(error_code_);
|
||||
return errno;
|
||||
}
|
||||
|
||||
public:
|
||||
StrError(int error_code, char *&buffer, std::size_t buffer_size)
|
||||
: error_code_(error_code), buffer_(buffer), buffer_size_(buffer_size) {}
|
||||
|
||||
int run() {
|
||||
strerror_r(0, 0, ""); // Suppress a warning about unused strerror_r.
|
||||
return handle(strerror_r(error_code_, buffer_, buffer_size_));
|
||||
}
|
||||
};
|
||||
return StrError(error_code, buffer, buffer_size).run();
|
||||
assert(buffer != 0 && buffer_size != 0);
|
||||
int result = 0;
|
||||
#if ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE) || __ANDROID__
|
||||
// XSI-compliant version of strerror_r.
|
||||
result = strerror_r(error_code, buffer, buffer_size);
|
||||
if (result != 0)
|
||||
result = errno;
|
||||
#elif _GNU_SOURCE
|
||||
// GNU-specific version of strerror_r.
|
||||
char *message = strerror_r(error_code, buffer, buffer_size);
|
||||
// If the buffer is full then the message is probably truncated.
|
||||
if (message == buffer && strlen(buffer) == buffer_size - 1)
|
||||
result = ERANGE;
|
||||
buffer = message;
|
||||
#elif __MINGW32__
|
||||
errno = 0;
|
||||
(void)buffer_size;
|
||||
buffer = strerror(error_code);
|
||||
result = errno;
|
||||
#elif _WIN32
|
||||
result = strerror_s(buffer, buffer_size, error_code);
|
||||
// If the buffer is full then the message is probably truncated.
|
||||
if (result == 0 && std::strlen(buffer) == buffer_size - 1)
|
||||
result = ERANGE;
|
||||
#else
|
||||
result = strerror_r(error_code, buffer, buffer_size);
|
||||
if (result == -1)
|
||||
result = errno; // glibc versions before 2.13 return result in errno.
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
void format_error_code(fmt::Writer &out, int error_code,
|
||||
@@ -222,14 +179,14 @@ void format_error_code(fmt::Writer &out, int error_code,
|
||||
// bad_alloc.
|
||||
out.clear();
|
||||
static const char SEP[] = ": ";
|
||||
static const char ERROR_STR[] = "error ";
|
||||
static const char ERR[] = "error ";
|
||||
fmt::internal::IntTraits<int>::MainType ec_value = error_code;
|
||||
// Subtract 2 to account for terminating null characters in SEP and ERROR_STR.
|
||||
std::size_t error_code_size = sizeof(SEP) + sizeof(ERROR_STR) - 2;
|
||||
error_code_size += fmt::internal::count_digits(ec_value);
|
||||
// Subtract 2 to account for terminating null characters in SEP and ERR.
|
||||
std::size_t error_code_size =
|
||||
sizeof(SEP) + sizeof(ERR) + fmt::internal::count_digits(ec_value) - 2;
|
||||
if (message.size() <= fmt::internal::INLINE_BUFFER_SIZE - error_code_size)
|
||||
out << message << SEP;
|
||||
out << ERROR_STR << error_code;
|
||||
out << ERR << error_code;
|
||||
assert(out.size() <= fmt::internal::INLINE_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
@@ -270,11 +227,6 @@ int parse_nonnegative_int(const Char *&s) {
|
||||
return value;
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
inline bool is_name_start(Char c) {
|
||||
return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || '_' == c;
|
||||
}
|
||||
|
||||
inline void require_numeric_argument(const Arg &arg, char spec) {
|
||||
if (arg.type > Arg::LAST_NUMERIC_TYPE) {
|
||||
std::string message =
|
||||
@@ -305,8 +257,9 @@ class WidthHandler : public fmt::internal::ArgVisitor<WidthHandler, unsigned> {
|
||||
public:
|
||||
explicit WidthHandler(fmt::FormatSpec &spec) : spec_(spec) {}
|
||||
|
||||
void report_unhandled_arg() {
|
||||
unsigned visit_unhandled_arg() {
|
||||
FMT_THROW(fmt::FormatError("width is not integer"));
|
||||
FMT_RETURN_AFTER_THROW(0);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@@ -326,8 +279,9 @@ class WidthHandler : public fmt::internal::ArgVisitor<WidthHandler, unsigned> {
|
||||
class PrecisionHandler :
|
||||
public fmt::internal::ArgVisitor<PrecisionHandler, int> {
|
||||
public:
|
||||
void report_unhandled_arg() {
|
||||
unsigned visit_unhandled_arg() {
|
||||
FMT_THROW(fmt::FormatError("precision is not integer"));
|
||||
FMT_RETURN_AFTER_THROW(0);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@@ -395,139 +349,24 @@ class CharConverter : public fmt::internal::ArgVisitor<CharConverter, void> {
|
||||
arg_.int_value = static_cast<char>(value);
|
||||
}
|
||||
};
|
||||
|
||||
// This function template is used to prevent compile errors when handling
|
||||
// incompatible string arguments, e.g. handling a wide string in a narrow
|
||||
// string formatter.
|
||||
template <typename Char>
|
||||
Arg::StringValue<Char> ignore_incompatible_str(Arg::StringValue<wchar_t>);
|
||||
|
||||
template <>
|
||||
inline Arg::StringValue<char> ignore_incompatible_str(
|
||||
Arg::StringValue<wchar_t>) { return Arg::StringValue<char>(); }
|
||||
|
||||
template <>
|
||||
inline Arg::StringValue<wchar_t> ignore_incompatible_str(
|
||||
Arg::StringValue<wchar_t> s) { return s; }
|
||||
} // namespace
|
||||
|
||||
namespace internal {
|
||||
|
||||
template <typename Impl, typename Char>
|
||||
class BasicArgFormatter : public ArgVisitor<Impl, void> {
|
||||
private:
|
||||
BasicWriter<Char> &writer_;
|
||||
FormatSpec &spec_;
|
||||
|
||||
FMT_DISALLOW_COPY_AND_ASSIGN(BasicArgFormatter);
|
||||
|
||||
protected:
|
||||
BasicWriter<Char> &writer() { return writer_; }
|
||||
const FormatSpec &spec() const { return spec_; }
|
||||
|
||||
public:
|
||||
BasicArgFormatter(BasicWriter<Char> &w, FormatSpec &s)
|
||||
: writer_(w), spec_(s) {}
|
||||
|
||||
template <typename T>
|
||||
void visit_any_int(T value) { writer_.write_int(value, spec_); }
|
||||
|
||||
template <typename T>
|
||||
void visit_any_double(T value) { writer_.write_double(value, spec_); }
|
||||
|
||||
void visit_bool(bool value) {
|
||||
if (spec_.type_) {
|
||||
writer_.write_int(value, spec_);
|
||||
return;
|
||||
}
|
||||
const char *str_value = value ? "true" : "false";
|
||||
Arg::StringValue<char> str = { str_value, strlen(str_value) };
|
||||
writer_.write_str(str, spec_);
|
||||
}
|
||||
|
||||
void visit_char(int value) {
|
||||
if (spec_.type_ && spec_.type_ != 'c') {
|
||||
spec_.flags_ |= CHAR_FLAG;
|
||||
writer_.write_int(value, spec_);
|
||||
return;
|
||||
}
|
||||
if (spec_.align_ == ALIGN_NUMERIC || spec_.flags_ != 0)
|
||||
FMT_THROW(FormatError("invalid format specifier for char"));
|
||||
typedef typename BasicWriter<Char>::CharPtr CharPtr;
|
||||
Char fill = internal::CharTraits<Char>::cast(spec_.fill());
|
||||
CharPtr out = CharPtr();
|
||||
if (spec_.width_ > 1) {
|
||||
out = writer_.grow_buffer(spec_.width_);
|
||||
if (spec_.align_ == ALIGN_RIGHT) {
|
||||
std::fill_n(out, spec_.width_ - 1, fill);
|
||||
out += spec_.width_ - 1;
|
||||
} else if (spec_.align_ == ALIGN_CENTER) {
|
||||
out = writer_.fill_padding(out, spec_.width_, 1, fill);
|
||||
} else {
|
||||
std::fill_n(out + 1, spec_.width_ - 1, fill);
|
||||
}
|
||||
} else {
|
||||
out = writer_.grow_buffer(1);
|
||||
}
|
||||
*out = internal::CharTraits<Char>::cast(value);
|
||||
}
|
||||
|
||||
void visit_string(Arg::StringValue<char> value) {
|
||||
writer_.write_str(value, spec_);
|
||||
}
|
||||
|
||||
using ArgVisitor<Impl, void>::visit_wstring;
|
||||
|
||||
void visit_wstring(Arg::StringValue<Char> value) {
|
||||
writer_.write_str(value, spec_);
|
||||
}
|
||||
|
||||
void visit_pointer(const void *value) {
|
||||
if (spec_.type_ && spec_.type_ != 'p')
|
||||
report_unknown_type(spec_.type_, "pointer");
|
||||
spec_.flags_ = HASH_FLAG;
|
||||
spec_.type_ = 'x';
|
||||
writer_.write_int(reinterpret_cast<uintptr_t>(value), spec_);
|
||||
}
|
||||
};
|
||||
|
||||
// An argument formatter.
|
||||
template <typename Char>
|
||||
class ArgFormatter : public BasicArgFormatter<ArgFormatter<Char>, Char> {
|
||||
private:
|
||||
BasicFormatter<Char> &formatter_;
|
||||
const Char *format_;
|
||||
|
||||
public:
|
||||
ArgFormatter(BasicFormatter<Char> &f, FormatSpec &s, const Char *fmt)
|
||||
: BasicArgFormatter<ArgFormatter<Char>, Char>(f.writer(), s),
|
||||
formatter_(f), format_(fmt) {}
|
||||
|
||||
void visit_custom(Arg::CustomValue c) {
|
||||
c.format(&formatter_, c.value, &format_);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char>
|
||||
class PrintfArgFormatter :
|
||||
public BasicArgFormatter<PrintfArgFormatter<Char>, Char> {
|
||||
public:
|
||||
PrintfArgFormatter(BasicWriter<Char> &w, FormatSpec &s)
|
||||
: BasicArgFormatter<PrintfArgFormatter<Char>, Char>(w, s) {}
|
||||
|
||||
void visit_char(int value) {
|
||||
const FormatSpec &spec = this->spec();
|
||||
BasicWriter<Char> &writer = this->writer();
|
||||
if (spec.type_ && spec.type_ != 'c')
|
||||
writer.write_int(value, spec);
|
||||
typedef typename BasicWriter<Char>::CharPtr CharPtr;
|
||||
CharPtr out = CharPtr();
|
||||
if (spec.width_ > 1) {
|
||||
Char fill = ' ';
|
||||
out = writer.grow_buffer(spec.width_);
|
||||
if (spec.align_ != ALIGN_LEFT) {
|
||||
std::fill_n(out, spec.width_ - 1, fill);
|
||||
out += spec.width_ - 1;
|
||||
} else {
|
||||
std::fill_n(out + 1, spec.width_ - 1, fill);
|
||||
}
|
||||
} else {
|
||||
out = writer.grow_buffer(1);
|
||||
}
|
||||
*out = static_cast<Char>(value);
|
||||
}
|
||||
};
|
||||
} // namespace internal
|
||||
} // namespace fmt
|
||||
|
||||
FMT_FUNC void fmt::SystemError::init(
|
||||
int err_code, CStringRef format_str, ArgList args) {
|
||||
int err_code, StringRef format_str, ArgList args) {
|
||||
error_code_ = err_code;
|
||||
MemoryWriter w;
|
||||
internal::format_system_error(w, err_code, format(format_str, args));
|
||||
@@ -598,7 +437,6 @@ const uint64_t fmt::internal::BasicData<T>::POWERS_OF_10_64[] = {
|
||||
};
|
||||
|
||||
FMT_FUNC void fmt::internal::report_unknown_type(char code, const char *type) {
|
||||
(void)type;
|
||||
if (std::isprint(static_cast<unsigned char>(code))) {
|
||||
FMT_THROW(fmt::FormatError(
|
||||
fmt::format("unknown format code '{}' for {}", code, type)));
|
||||
@@ -608,20 +446,19 @@ FMT_FUNC void fmt::internal::report_unknown_type(char code, const char *type) {
|
||||
static_cast<unsigned>(code), type)));
|
||||
}
|
||||
|
||||
#if FMT_USE_WINDOWS_H
|
||||
#ifdef _WIN32
|
||||
|
||||
FMT_FUNC fmt::internal::UTF8ToUTF16::UTF8ToUTF16(fmt::StringRef s) {
|
||||
int length = MultiByteToWideChar(
|
||||
CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s.size(), 0, 0);
|
||||
CP_UTF8, MB_ERR_INVALID_CHARS, s.c_str(), -1, 0, 0);
|
||||
static const char ERROR_MSG[] = "cannot convert string from UTF-8 to UTF-16";
|
||||
if (length == 0)
|
||||
FMT_THROW(WindowsError(GetLastError(), ERROR_MSG));
|
||||
buffer_.resize(length + 1);
|
||||
buffer_.resize(length);
|
||||
length = MultiByteToWideChar(
|
||||
CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s.size(), &buffer_[0], length);
|
||||
CP_UTF8, MB_ERR_INVALID_CHARS, s.c_str(), -1, &buffer_[0], length);
|
||||
if (length == 0)
|
||||
FMT_THROW(WindowsError(GetLastError(), ERROR_MSG));
|
||||
buffer_[length] = 0;
|
||||
}
|
||||
|
||||
FMT_FUNC fmt::internal::UTF16ToUTF8::UTF16ToUTF8(fmt::WStringRef s) {
|
||||
@@ -632,20 +469,19 @@ FMT_FUNC fmt::internal::UTF16ToUTF8::UTF16ToUTF8(fmt::WStringRef s) {
|
||||
}
|
||||
|
||||
FMT_FUNC int fmt::internal::UTF16ToUTF8::convert(fmt::WStringRef s) {
|
||||
int length = WideCharToMultiByte(CP_UTF8, 0, s.data(), s.size(), 0, 0, 0, 0);
|
||||
int length = WideCharToMultiByte(CP_UTF8, 0, s.c_str(), -1, 0, 0, 0, 0);
|
||||
if (length == 0)
|
||||
return GetLastError();
|
||||
buffer_.resize(length + 1);
|
||||
buffer_.resize(length);
|
||||
length = WideCharToMultiByte(
|
||||
CP_UTF8, 0, s.data(), s.size(), &buffer_[0], length, 0, 0);
|
||||
CP_UTF8, 0, s.c_str(), -1, &buffer_[0], length, 0, 0);
|
||||
if (length == 0)
|
||||
return GetLastError();
|
||||
buffer_[length] = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
FMT_FUNC void fmt::WindowsError::init(
|
||||
int err_code, CStringRef format_str, ArgList args) {
|
||||
int err_code, StringRef format_str, ArgList args) {
|
||||
error_code_ = err_code;
|
||||
MemoryWriter w;
|
||||
internal::format_windows_error(w, err_code, format(format_str, args));
|
||||
@@ -653,6 +489,30 @@ FMT_FUNC void fmt::WindowsError::init(
|
||||
base = std::runtime_error(w.str());
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
FMT_FUNC void fmt::internal::format_system_error(
|
||||
fmt::Writer &out, int error_code,
|
||||
fmt::StringRef message) FMT_NOEXCEPT {
|
||||
FMT_TRY {
|
||||
MemoryBuffer<char, INLINE_BUFFER_SIZE> buffer;
|
||||
buffer.resize(INLINE_BUFFER_SIZE);
|
||||
for (;;) {
|
||||
char *system_message = &buffer[0];
|
||||
int result = safe_strerror(error_code, system_message, buffer.size());
|
||||
if (result == 0) {
|
||||
out << message << ": " << system_message;
|
||||
return;
|
||||
}
|
||||
if (result != ERANGE)
|
||||
break; // Can't get error message, report error code instead.
|
||||
buffer.resize(buffer.size() * 2);
|
||||
}
|
||||
} FMT_CATCH(...) {}
|
||||
format_error_code(out, error_code, message);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
FMT_FUNC void fmt::internal::format_windows_error(
|
||||
fmt::Writer &out, int error_code,
|
||||
fmt::StringRef message) FMT_NOEXCEPT {
|
||||
@@ -681,74 +541,81 @@ FMT_FUNC void fmt::internal::format_windows_error(
|
||||
} FMT_CATCH(...) {}
|
||||
format_error_code(out, error_code, message);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // FMT_USE_WINDOWS_H
|
||||
|
||||
FMT_FUNC void fmt::internal::format_system_error(
|
||||
fmt::Writer &out, int error_code,
|
||||
fmt::StringRef message) FMT_NOEXCEPT {
|
||||
FMT_TRY {
|
||||
MemoryBuffer<char, INLINE_BUFFER_SIZE> buffer;
|
||||
buffer.resize(INLINE_BUFFER_SIZE);
|
||||
for (;;) {
|
||||
char *system_message = &buffer[0];
|
||||
int result = safe_strerror(error_code, system_message, buffer.size());
|
||||
if (result == 0) {
|
||||
out << message << ": " << system_message;
|
||||
return;
|
||||
}
|
||||
if (result != ERANGE)
|
||||
break; // Can't get error message, report error code instead.
|
||||
buffer.resize(buffer.size() * 2);
|
||||
}
|
||||
} FMT_CATCH(...) {}
|
||||
format_error_code(out, error_code, message);
|
||||
}
|
||||
|
||||
// An argument formatter.
|
||||
template <typename Char>
|
||||
void fmt::internal::ArgMap<Char>::init(const ArgList &args) {
|
||||
if (!map_.empty())
|
||||
return;
|
||||
typedef internal::NamedArg<Char> NamedArg;
|
||||
const NamedArg *named_arg = 0;
|
||||
bool use_values =
|
||||
args.type(ArgList::MAX_PACKED_ARGS - 1) == internal::Arg::NONE;
|
||||
if (use_values) {
|
||||
for (unsigned i = 0;/*nothing*/; ++i) {
|
||||
internal::Arg::Type arg_type = args.type(i);
|
||||
switch (arg_type) {
|
||||
case internal::Arg::NONE:
|
||||
return;
|
||||
case internal::Arg::NAMED_ARG:
|
||||
named_arg = static_cast<const NamedArg*>(args.values_[i].pointer);
|
||||
map_.insert(Pair(named_arg->name, *named_arg));
|
||||
break;
|
||||
default:
|
||||
/*nothing*/;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
for (unsigned i = 0; i != ArgList::MAX_PACKED_ARGS; ++i) {
|
||||
internal::Arg::Type arg_type = args.type(i);
|
||||
if (arg_type == internal::Arg::NAMED_ARG) {
|
||||
named_arg = static_cast<const NamedArg*>(args.args_[i].pointer);
|
||||
map_.insert(Pair(named_arg->name, *named_arg));
|
||||
}
|
||||
}
|
||||
for (unsigned i = ArgList::MAX_PACKED_ARGS;/*nothing*/; ++i) {
|
||||
switch (args.args_[i].type) {
|
||||
case internal::Arg::NONE:
|
||||
class fmt::internal::ArgFormatter :
|
||||
public fmt::internal::ArgVisitor<fmt::internal::ArgFormatter<Char>, void> {
|
||||
private:
|
||||
fmt::BasicFormatter<Char> &formatter_;
|
||||
fmt::BasicWriter<Char> &writer_;
|
||||
fmt::FormatSpec &spec_;
|
||||
const Char *format_;
|
||||
|
||||
FMT_DISALLOW_COPY_AND_ASSIGN(ArgFormatter);
|
||||
|
||||
public:
|
||||
ArgFormatter(
|
||||
fmt::BasicFormatter<Char> &f,fmt::FormatSpec &s, const Char *fmt)
|
||||
: formatter_(f), writer_(f.writer()), spec_(s), format_(fmt) {}
|
||||
|
||||
template <typename T>
|
||||
void visit_any_int(T value) { writer_.write_int(value, spec_); }
|
||||
|
||||
template <typename T>
|
||||
void visit_any_double(T value) { writer_.write_double(value, spec_); }
|
||||
|
||||
void visit_char(int value) {
|
||||
if (spec_.type_ && spec_.type_ != 'c') {
|
||||
spec_.flags_ |= CHAR_FLAG;
|
||||
writer_.write_int(value, spec_);
|
||||
return;
|
||||
case internal::Arg::NAMED_ARG:
|
||||
named_arg = static_cast<const NamedArg*>(args.args_[i].pointer);
|
||||
map_.insert(Pair(named_arg->name, *named_arg));
|
||||
break;
|
||||
default:
|
||||
/*nothing*/;
|
||||
}
|
||||
if (spec_.align_ == ALIGN_NUMERIC || spec_.flags_ != 0)
|
||||
FMT_THROW(FormatError("invalid format specifier for char"));
|
||||
typedef typename fmt::BasicWriter<Char>::CharPtr CharPtr;
|
||||
Char fill = static_cast<Char>(spec_.fill());
|
||||
if (spec_.precision_ == 0) {
|
||||
std::fill_n(writer_.grow_buffer(spec_.width_), spec_.width_, fill);
|
||||
return;
|
||||
}
|
||||
CharPtr out = CharPtr();
|
||||
if (spec_.width_ > 1) {
|
||||
out = writer_.grow_buffer(spec_.width_);
|
||||
if (spec_.align_ == fmt::ALIGN_RIGHT) {
|
||||
std::fill_n(out, spec_.width_ - 1, fill);
|
||||
out += spec_.width_ - 1;
|
||||
} else if (spec_.align_ == fmt::ALIGN_CENTER) {
|
||||
out = writer_.fill_padding(out, spec_.width_, 1, fill);
|
||||
} else {
|
||||
std::fill_n(out + 1, spec_.width_ - 1, fill);
|
||||
}
|
||||
} else {
|
||||
out = writer_.grow_buffer(1);
|
||||
}
|
||||
*out = static_cast<Char>(value);
|
||||
}
|
||||
}
|
||||
|
||||
void visit_string(Arg::StringValue<char> value) {
|
||||
writer_.write_str(value, spec_);
|
||||
}
|
||||
void visit_wstring(Arg::StringValue<wchar_t> value) {
|
||||
writer_.write_str(ignore_incompatible_str<Char>(value), spec_);
|
||||
}
|
||||
|
||||
void visit_pointer(const void *value) {
|
||||
if (spec_.type_ && spec_.type_ != 'p')
|
||||
fmt::internal::report_unknown_type(spec_.type_, "pointer");
|
||||
spec_.flags_ = fmt::HASH_FLAG;
|
||||
spec_.type_ = 'x';
|
||||
writer_.write_int(reinterpret_cast<uintptr_t>(value), spec_);
|
||||
}
|
||||
|
||||
void visit_custom(Arg::CustomValue c) {
|
||||
c.format(&formatter_, c.value, &format_);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char>
|
||||
void fmt::internal::FixedBuffer<Char>::grow(std::size_t) {
|
||||
@@ -777,19 +644,6 @@ void fmt::BasicWriter<Char>::write_str(
|
||||
write_str(str_value, str_size, spec);
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
inline Arg fmt::BasicFormatter<Char>::get_arg(
|
||||
BasicStringRef<Char> arg_name, const char *&error) {
|
||||
if (check_no_auto_index(error)) {
|
||||
map_.init(args());
|
||||
const Arg *arg = map_.find(arg_name);
|
||||
if (arg)
|
||||
return *arg;
|
||||
error = "argument not found";
|
||||
}
|
||||
return Arg();
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
inline Arg fmt::BasicFormatter<Char>::parse_arg_index(const Char *&s) {
|
||||
const char *error = 0;
|
||||
@@ -802,33 +656,11 @@ inline Arg fmt::BasicFormatter<Char>::parse_arg_index(const Char *&s) {
|
||||
return arg;
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
inline Arg fmt::BasicFormatter<Char>::parse_arg_name(const Char *&s) {
|
||||
assert(is_name_start(*s));
|
||||
const Char *start = s;
|
||||
Char c;
|
||||
do {
|
||||
c = *++s;
|
||||
} while (is_name_start(c) || ('0' <= c && c <= '9'));
|
||||
const char *error = 0;
|
||||
Arg arg = get_arg(fmt::BasicStringRef<Char>(start, s - start), error);
|
||||
if (error)
|
||||
FMT_THROW(fmt::FormatError(error));
|
||||
return arg;
|
||||
}
|
||||
|
||||
FMT_FUNC Arg fmt::internal::FormatterBase::do_get_arg(
|
||||
unsigned arg_index, const char *&error) {
|
||||
Arg arg = args_[arg_index];
|
||||
switch (arg.type) {
|
||||
case Arg::NONE:
|
||||
if (arg.type == Arg::NONE)
|
||||
error = "argument index out of range";
|
||||
break;
|
||||
case Arg::NAMED_ARG:
|
||||
arg = *static_cast<const internal::Arg*>(arg.pointer);
|
||||
default:
|
||||
/*nothing*/;
|
||||
}
|
||||
return arg;
|
||||
}
|
||||
|
||||
@@ -839,19 +671,14 @@ inline Arg fmt::internal::FormatterBase::next_arg(const char *&error) {
|
||||
return Arg();
|
||||
}
|
||||
|
||||
inline bool fmt::internal::FormatterBase::check_no_auto_index(
|
||||
const char *&error) {
|
||||
if (next_arg_index_ > 0) {
|
||||
error = "cannot switch from automatic to manual argument indexing";
|
||||
return false;
|
||||
}
|
||||
next_arg_index_ = -1;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline Arg fmt::internal::FormatterBase::get_arg(
|
||||
unsigned arg_index, const char *&error) {
|
||||
return check_no_auto_index(error) ? do_get_arg(arg_index, error) : Arg();
|
||||
if (next_arg_index_ <= 0) {
|
||||
next_arg_index_ = -1;
|
||||
return do_get_arg(arg_index, error);
|
||||
}
|
||||
error = "cannot switch from automatic to manual argument indexing";
|
||||
return Arg();
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
@@ -884,7 +711,6 @@ void fmt::internal::PrintfFormatter<Char>::parse_flags(
|
||||
template <typename Char>
|
||||
Arg fmt::internal::PrintfFormatter<Char>::get_arg(
|
||||
const Char *s, unsigned arg_index) {
|
||||
(void)s;
|
||||
const char *error = 0;
|
||||
Arg arg = arg_index == UINT_MAX ?
|
||||
next_arg(error) : FormatterBase::get_arg(arg_index - 1, error);
|
||||
@@ -929,7 +755,7 @@ unsigned fmt::internal::PrintfFormatter<Char>::parse_header(
|
||||
|
||||
template <typename Char>
|
||||
void fmt::internal::PrintfFormatter<Char>::format(
|
||||
BasicWriter<Char> &writer, BasicCStringRef<Char> format_str,
|
||||
BasicWriter<Char> &writer, BasicStringRef<Char> format_str,
|
||||
const ArgList &args) {
|
||||
const Char *start = format_str.c_str();
|
||||
set_args(args);
|
||||
@@ -1023,7 +849,73 @@ void fmt::internal::PrintfFormatter<Char>::format(
|
||||
start = s;
|
||||
|
||||
// Format argument.
|
||||
internal::PrintfArgFormatter<Char>(writer, spec).visit(arg);
|
||||
switch (arg.type) {
|
||||
case Arg::INT:
|
||||
writer.write_int(arg.int_value, spec);
|
||||
break;
|
||||
case Arg::UINT:
|
||||
writer.write_int(arg.uint_value, spec);
|
||||
break;
|
||||
case Arg::LONG_LONG:
|
||||
writer.write_int(arg.long_long_value, spec);
|
||||
break;
|
||||
case Arg::ULONG_LONG:
|
||||
writer.write_int(arg.ulong_long_value, spec);
|
||||
break;
|
||||
case Arg::CHAR: {
|
||||
if (spec.type_ && spec.type_ != 'c')
|
||||
writer.write_int(arg.int_value, spec);
|
||||
typedef typename BasicWriter<Char>::CharPtr CharPtr;
|
||||
CharPtr out = CharPtr();
|
||||
if (spec.width_ > 1) {
|
||||
Char fill = ' ';
|
||||
out = writer.grow_buffer(spec.width_);
|
||||
if (spec.align_ != ALIGN_LEFT) {
|
||||
std::fill_n(out, spec.width_ - 1, fill);
|
||||
out += spec.width_ - 1;
|
||||
} else {
|
||||
std::fill_n(out + 1, spec.width_ - 1, fill);
|
||||
}
|
||||
} else {
|
||||
out = writer.grow_buffer(1);
|
||||
}
|
||||
*out = static_cast<Char>(arg.int_value);
|
||||
break;
|
||||
}
|
||||
case Arg::DOUBLE:
|
||||
writer.write_double(arg.double_value, spec);
|
||||
break;
|
||||
case Arg::LONG_DOUBLE:
|
||||
writer.write_double(arg.long_double_value, spec);
|
||||
break;
|
||||
case Arg::CSTRING:
|
||||
arg.string.size = 0;
|
||||
writer.write_str(arg.string, spec);
|
||||
break;
|
||||
case Arg::STRING:
|
||||
writer.write_str(arg.string, spec);
|
||||
break;
|
||||
case Arg::WSTRING:
|
||||
writer.write_str(ignore_incompatible_str<Char>(arg.wstring), spec);
|
||||
break;
|
||||
case Arg::POINTER:
|
||||
if (spec.type_ && spec.type_ != 'p')
|
||||
internal::report_unknown_type(spec.type_, "pointer");
|
||||
spec.flags_= HASH_FLAG;
|
||||
spec.type_ = 'x';
|
||||
writer.write_int(reinterpret_cast<uintptr_t>(arg.pointer), spec);
|
||||
break;
|
||||
case Arg::CUSTOM: {
|
||||
if (spec.type_)
|
||||
internal::report_unknown_type(spec.type_, "object");
|
||||
const void *str_format = "s";
|
||||
arg.custom.format(&writer, arg.custom.value, &str_format);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
write(writer, start, s);
|
||||
}
|
||||
@@ -1095,47 +987,16 @@ const Char *fmt::BasicFormatter<Char>::format(
|
||||
++s;
|
||||
}
|
||||
|
||||
// Parse zero flag.
|
||||
if (*s == '0') {
|
||||
require_numeric_argument(arg, '0');
|
||||
spec.align_ = ALIGN_NUMERIC;
|
||||
spec.fill_ = '0';
|
||||
++s;
|
||||
}
|
||||
|
||||
// Parse width.
|
||||
// Parse width and zero flag.
|
||||
if ('0' <= *s && *s <= '9') {
|
||||
spec.width_ = parse_nonnegative_int(s);
|
||||
} else if (*s == '{') {
|
||||
++s;
|
||||
Arg width_arg = is_name_start(*s) ?
|
||||
parse_arg_name(s) : parse_arg_index(s);
|
||||
if (*s++ != '}')
|
||||
FMT_THROW(FormatError("invalid format string"));
|
||||
ULongLong value = 0;
|
||||
switch (width_arg.type) {
|
||||
case Arg::INT:
|
||||
if (width_arg.int_value < 0)
|
||||
FMT_THROW(FormatError("negative width"));
|
||||
value = width_arg.int_value;
|
||||
break;
|
||||
case Arg::UINT:
|
||||
value = width_arg.uint_value;
|
||||
break;
|
||||
case Arg::LONG_LONG:
|
||||
if (width_arg.long_long_value < 0)
|
||||
FMT_THROW(FormatError("negative width"));
|
||||
value = width_arg.long_long_value;
|
||||
break;
|
||||
case Arg::ULONG_LONG:
|
||||
value = width_arg.ulong_long_value;
|
||||
break;
|
||||
default:
|
||||
FMT_THROW(FormatError("width is not integer"));
|
||||
if (*s == '0') {
|
||||
require_numeric_argument(arg, '0');
|
||||
spec.align_ = ALIGN_NUMERIC;
|
||||
spec.fill_ = '0';
|
||||
}
|
||||
if (value > INT_MAX)
|
||||
FMT_THROW(FormatError("number is too big"));
|
||||
spec.width_ = static_cast<int>(value);
|
||||
// Zero may be parsed again as a part of the width, but it is simpler
|
||||
// and more efficient than checking if the next char is a digit.
|
||||
spec.width_ = parse_nonnegative_int(s);
|
||||
}
|
||||
|
||||
// Parse precision.
|
||||
@@ -1146,8 +1007,7 @@ const Char *fmt::BasicFormatter<Char>::format(
|
||||
spec.precision_ = parse_nonnegative_int(s);
|
||||
} else if (*s == '{') {
|
||||
++s;
|
||||
Arg precision_arg =
|
||||
is_name_start(*s) ? parse_arg_name(s) : parse_arg_index(s);
|
||||
const Arg &precision_arg = parse_arg_index(s);
|
||||
if (*s++ != '}')
|
||||
FMT_THROW(FormatError("invalid format string"));
|
||||
ULongLong value = 0;
|
||||
@@ -1177,7 +1037,7 @@ const Char *fmt::BasicFormatter<Char>::format(
|
||||
} else {
|
||||
FMT_THROW(FormatError("missing precision specifier"));
|
||||
}
|
||||
if (arg.type <= Arg::LAST_INTEGER_TYPE || arg.type == Arg::POINTER) {
|
||||
if (arg.type < Arg::LAST_INTEGER_TYPE || arg.type == Arg::POINTER) {
|
||||
FMT_THROW(FormatError(
|
||||
fmt::format("precision not allowed in {} format specifier",
|
||||
arg.type == Arg::POINTER ? "pointer" : "integer")));
|
||||
@@ -1200,7 +1060,7 @@ const Char *fmt::BasicFormatter<Char>::format(
|
||||
|
||||
template <typename Char>
|
||||
void fmt::BasicFormatter<Char>::format(
|
||||
BasicCStringRef<Char> format_str, const ArgList &args) {
|
||||
BasicStringRef<Char> format_str, const ArgList &args) {
|
||||
const Char *s = start_ = format_str.c_str();
|
||||
set_args(args);
|
||||
while (*s) {
|
||||
@@ -1214,7 +1074,7 @@ void fmt::BasicFormatter<Char>::format(
|
||||
if (c == '}')
|
||||
FMT_THROW(FormatError("unmatched '}' in format string"));
|
||||
write(writer_, start_, s - 1);
|
||||
Arg arg = is_name_start(*s) ? parse_arg_name(s) : parse_arg_index(s);
|
||||
Arg arg = parse_arg_index(s);
|
||||
s = format(s, arg);
|
||||
}
|
||||
write(writer_, start_, s);
|
||||
@@ -1225,30 +1085,30 @@ FMT_FUNC void fmt::report_system_error(
|
||||
report_error(internal::format_system_error, error_code, message);
|
||||
}
|
||||
|
||||
#if FMT_USE_WINDOWS_H
|
||||
#ifdef _WIN32
|
||||
FMT_FUNC void fmt::report_windows_error(
|
||||
int error_code, fmt::StringRef message) FMT_NOEXCEPT {
|
||||
report_error(internal::format_windows_error, error_code, message);
|
||||
}
|
||||
#endif
|
||||
|
||||
FMT_FUNC void fmt::print(std::FILE *f, CStringRef format_str, ArgList args) {
|
||||
FMT_FUNC void fmt::print(std::FILE *f, StringRef format_str, ArgList args) {
|
||||
MemoryWriter w;
|
||||
w.write(format_str, args);
|
||||
std::fwrite(w.data(), 1, w.size(), f);
|
||||
}
|
||||
|
||||
FMT_FUNC void fmt::print(CStringRef format_str, ArgList args) {
|
||||
FMT_FUNC void fmt::print(StringRef format_str, ArgList args) {
|
||||
print(stdout, format_str, args);
|
||||
}
|
||||
|
||||
FMT_FUNC void fmt::print(std::ostream &os, CStringRef format_str, ArgList args) {
|
||||
FMT_FUNC void fmt::print(std::ostream &os, StringRef format_str, ArgList args) {
|
||||
MemoryWriter w;
|
||||
w.write(format_str, args);
|
||||
os.write(w.data(), w.size());
|
||||
}
|
||||
|
||||
FMT_FUNC void fmt::print_colored(Color c, CStringRef format, ArgList args) {
|
||||
FMT_FUNC void fmt::print_colored(Color c, StringRef format, ArgList args) {
|
||||
char escape[] = "\x1b[30m";
|
||||
escape[3] = '0' + static_cast<char>(c);
|
||||
std::fputs(escape, stdout);
|
||||
@@ -1256,7 +1116,7 @@ FMT_FUNC void fmt::print_colored(Color c, CStringRef format, ArgList args) {
|
||||
std::fputs(RESET_COLOR, stdout);
|
||||
}
|
||||
|
||||
FMT_FUNC int fmt::fprintf(std::FILE *f, CStringRef format, ArgList args) {
|
||||
FMT_FUNC int fmt::fprintf(std::FILE *f, StringRef format, ArgList args) {
|
||||
MemoryWriter w;
|
||||
printf(w, format, args);
|
||||
std::size_t size = w.size();
|
||||
@@ -1265,8 +1125,6 @@ FMT_FUNC int fmt::fprintf(std::FILE *f, CStringRef format, ArgList args) {
|
||||
|
||||
#ifndef FMT_HEADER_ONLY
|
||||
|
||||
template struct fmt::internal::BasicData<void>;
|
||||
|
||||
// Explicit instantiations for char.
|
||||
|
||||
template void fmt::internal::FixedBuffer<char>::grow(std::size_t);
|
||||
@@ -1275,10 +1133,10 @@ template const char *fmt::BasicFormatter<char>::format(
|
||||
const char *&format_str, const fmt::internal::Arg &arg);
|
||||
|
||||
template void fmt::BasicFormatter<char>::format(
|
||||
CStringRef format, const ArgList &args);
|
||||
BasicStringRef<char> format, const ArgList &args);
|
||||
|
||||
template void fmt::internal::PrintfFormatter<char>::format(
|
||||
BasicWriter<char> &writer, CStringRef format, const ArgList &args);
|
||||
BasicWriter<char> &writer, BasicStringRef<char> format, const ArgList &args);
|
||||
|
||||
template int fmt::internal::CharTraits<char>::format_float(
|
||||
char *buffer, std::size_t size, const char *format,
|
||||
@@ -1296,10 +1154,10 @@ template const wchar_t *fmt::BasicFormatter<wchar_t>::format(
|
||||
const wchar_t *&format_str, const fmt::internal::Arg &arg);
|
||||
|
||||
template void fmt::BasicFormatter<wchar_t>::format(
|
||||
BasicCStringRef<wchar_t> format, const ArgList &args);
|
||||
BasicStringRef<wchar_t> format, const ArgList &args);
|
||||
|
||||
template void fmt::internal::PrintfFormatter<wchar_t>::format(
|
||||
BasicWriter<wchar_t> &writer, WCStringRef format,
|
||||
BasicWriter<wchar_t> &writer, BasicStringRef<wchar_t> format,
|
||||
const ArgList &args);
|
||||
|
||||
template int fmt::internal::CharTraits<wchar_t>::format_float(
|
||||
|
||||
+173
-486
File diff suppressed because it is too large.
Load diff
+16
-27
@@ -45,17 +45,16 @@
|
||||
# define O_CREAT _O_CREAT
|
||||
# define O_TRUNC _O_TRUNC
|
||||
|
||||
# ifndef S_IRUSR
|
||||
# define S_IRUSR _S_IREAD
|
||||
# endif
|
||||
#ifndef S_IRUSR
|
||||
# define S_IRUSR _S_IREAD
|
||||
#endif
|
||||
|
||||
# ifndef S_IWUSR
|
||||
# define S_IWUSR _S_IWRITE
|
||||
# endif
|
||||
#ifndef S_IWUSR
|
||||
# define S_IWUSR _S_IWRITE
|
||||
#endif
|
||||
|
||||
# ifdef __MINGW32__
|
||||
# define _SH_DENYNO 0x40
|
||||
# undef fileno
|
||||
# endif
|
||||
|
||||
#endif // _WIN32
|
||||
@@ -83,8 +82,7 @@ fmt::BufferedFile::~BufferedFile() FMT_NOEXCEPT {
|
||||
fmt::report_system_error(errno, "cannot close file");
|
||||
}
|
||||
|
||||
fmt::BufferedFile::BufferedFile(
|
||||
fmt::CStringRef filename, fmt::CStringRef mode) {
|
||||
fmt::BufferedFile::BufferedFile(fmt::StringRef filename, fmt::StringRef mode) {
|
||||
FMT_RETRY_VAL(file_, FMT_SYSTEM(fopen(filename.c_str(), mode.c_str())), 0);
|
||||
if (!file_)
|
||||
throw SystemError(errno, "cannot open file {}", filename);
|
||||
@@ -99,19 +97,16 @@ void fmt::BufferedFile::close() {
|
||||
throw SystemError(errno, "cannot close file");
|
||||
}
|
||||
|
||||
// A macro used to prevent expansion of fileno on broken versions of MinGW.
|
||||
#define FMT_ARGS
|
||||
|
||||
int fmt::BufferedFile::fileno() const {
|
||||
int fd = FMT_POSIX_CALL(fileno FMT_ARGS(file_));
|
||||
int fd = FMT_POSIX_CALL(fileno(file_));
|
||||
if (fd == -1)
|
||||
throw SystemError(errno, "cannot get file descriptor");
|
||||
return fd;
|
||||
}
|
||||
|
||||
fmt::File::File(fmt::CStringRef path, int oflag) {
|
||||
fmt::File::File(fmt::StringRef path, int oflag) {
|
||||
int mode = S_IRUSR | S_IWUSR;
|
||||
#if defined(_WIN32) && !defined(__MINGW32__)
|
||||
#ifdef _WIN32
|
||||
fd_ = -1;
|
||||
FMT_POSIX_CALL(sopen_s(&fd_, path.c_str(), oflag, _SH_DENYNO, mode));
|
||||
#else
|
||||
@@ -141,19 +136,13 @@ void fmt::File::close() {
|
||||
|
||||
fmt::LongLong fmt::File::size() const {
|
||||
#ifdef _WIN32
|
||||
// Use GetFileSize instead of GetFileSizeEx for the case when _WIN32_WINNT
|
||||
// is less than 0x0500 as is the case with some default MinGW builds.
|
||||
// Both functions support large file sizes.
|
||||
DWORD size_upper = 0;
|
||||
LARGE_INTEGER filesize = {};
|
||||
HANDLE handle = reinterpret_cast<HANDLE>(_get_osfhandle(fd_));
|
||||
DWORD size_lower = FMT_SYSTEM(GetFileSize(handle, &size_upper));
|
||||
if (size_lower == INVALID_FILE_SIZE) {
|
||||
DWORD error = GetLastError();
|
||||
if (error != NO_ERROR)
|
||||
throw WindowsError(GetLastError(), "cannot get file size");
|
||||
}
|
||||
fmt::ULongLong long_size = size_upper;
|
||||
return (long_size << sizeof(DWORD) * CHAR_BIT) | size_lower;
|
||||
if (!FMT_SYSTEM(GetFileSizeEx(handle, &filesize)))
|
||||
throw WindowsError(GetLastError(), "cannot get file size");
|
||||
FMT_STATIC_ASSERT(sizeof(fmt::LongLong) >= sizeof(filesize.QuadPart),
|
||||
"return type of File::size is not large enough");
|
||||
return filesize.QuadPart;
|
||||
#else
|
||||
typedef struct stat Stat;
|
||||
Stat file_stat = Stat();
|
||||
|
||||
+11
-14
@@ -28,11 +28,6 @@
|
||||
#ifndef FMT_POSIX_H_
|
||||
#define FMT_POSIX_H_
|
||||
|
||||
#ifdef __MINGW32__
|
||||
// Workaround MinGW bug https://sourceforge.net/p/mingw/bugs/2024/.
|
||||
# undef __STRICT_ANSI__
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h> // for O_RDONLY
|
||||
#include <stdio.h>
|
||||
@@ -41,8 +36,12 @@
|
||||
|
||||
#include "format.h"
|
||||
|
||||
#ifdef FMT_INCLUDE_POSIX_TEST
|
||||
# include "test/posix-test.h"
|
||||
#endif
|
||||
|
||||
#ifndef FMT_POSIX
|
||||
# if defined(_WIN32) && !defined(__MINGW32__)
|
||||
# ifdef _WIN32
|
||||
// Fix warnings about deprecated symbols.
|
||||
# define FMT_POSIX(call) _##call
|
||||
# else
|
||||
@@ -181,7 +180,7 @@ public:
|
||||
#endif
|
||||
|
||||
// Opens a file.
|
||||
BufferedFile(CStringRef filename, CStringRef mode);
|
||||
BufferedFile(fmt::StringRef filename, fmt::StringRef mode);
|
||||
|
||||
// Closes the file.
|
||||
void close();
|
||||
@@ -189,14 +188,12 @@ public:
|
||||
// Returns the pointer to a FILE object representing this file.
|
||||
FILE *get() const FMT_NOEXCEPT { return file_; }
|
||||
|
||||
// We place parentheses around fileno to workaround a bug in some versions
|
||||
// of MinGW that define fileno as a macro.
|
||||
int (fileno)() const;
|
||||
int fileno() const;
|
||||
|
||||
void print(CStringRef format_str, const ArgList &args) {
|
||||
void print(fmt::StringRef format_str, const ArgList &args) {
|
||||
fmt::print(file_, format_str, args);
|
||||
}
|
||||
FMT_VARIADIC(void, print, CStringRef)
|
||||
FMT_VARIADIC(void, print, fmt::StringRef)
|
||||
};
|
||||
|
||||
// A file. Closed file is represented by a File object with descriptor -1.
|
||||
@@ -224,7 +221,7 @@ class File {
|
||||
File() FMT_NOEXCEPT : fd_(-1) {}
|
||||
|
||||
// Opens a file and constructs a File object representing this file.
|
||||
File(CStringRef path, int oflag);
|
||||
File(fmt::StringRef path, int oflag);
|
||||
|
||||
#if !FMT_USE_RVALUE_REFERENCES
|
||||
// Emulate a move constructor and a move assignment operator if rvalue
|
||||
@@ -296,7 +293,7 @@ class File {
|
||||
void close();
|
||||
|
||||
// Returns the file size.
|
||||
LongLong size() const;
|
||||
fmt::LongLong size() const;
|
||||
|
||||
// Attempts to read count bytes from the file into the specified buffer.
|
||||
std::size_t read(void *buffer, std::size_t count);
|
||||
|
||||
@@ -43,6 +43,7 @@ endif()
|
||||
|
||||
include_directories(
|
||||
${CMAKE_BINARY_DIR}
|
||||
${CMAKE_SOURCE_DIR}/dep/cppformat
|
||||
${CMAKE_SOURCE_DIR}/src/server/shared
|
||||
${CMAKE_SOURCE_DIR}/src/server/shared/Configuration
|
||||
${CMAKE_SOURCE_DIR}/src/server/shared/Database
|
||||
@@ -78,6 +79,7 @@ endif()
|
||||
|
||||
target_link_libraries(authserver
|
||||
shared
|
||||
format
|
||||
${MYSQL_LIBRARY}
|
||||
${OPENSSL_LIBRARIES}
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
|
||||
@@ -35,6 +35,7 @@ include_directories(
|
||||
${CMAKE_SOURCE_DIR}/dep/g3dlite/include
|
||||
${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour
|
||||
${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour/Include
|
||||
${CMAKE_SOURCE_DIR}/dep/cppformat
|
||||
${CMAKE_SOURCE_DIR}/src/server/shared
|
||||
${CMAKE_SOURCE_DIR}/src/server/shared/Configuration
|
||||
${CMAKE_SOURCE_DIR}/src/server/shared/Debugging
|
||||
|
||||
@@ -3184,7 +3184,7 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui
|
||||
std::list<Creature*> list;
|
||||
me->GetCreatureListWithEntryInGrid(list, e.event.distance.entry, (float)e.event.distance.dist);
|
||||
|
||||
if (list.size() > 0)
|
||||
if (!list.empty())
|
||||
creature = list.front();
|
||||
}
|
||||
|
||||
@@ -3215,7 +3215,7 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui
|
||||
std::list<GameObject*> list;
|
||||
me->GetGameObjectListWithEntryInGrid(list, e.event.distance.entry, (float)e.event.distance.dist);
|
||||
|
||||
if (list.size() > 0)
|
||||
if (!list.empty())
|
||||
gameobject = list.front();
|
||||
}
|
||||
|
||||
|
||||
@@ -110,6 +110,7 @@ include_directories(
|
||||
${CMAKE_SOURCE_DIR}/dep/recastnavigation/Recast/Include
|
||||
${CMAKE_SOURCE_DIR}/dep/g3dlite/include
|
||||
${CMAKE_SOURCE_DIR}/dep/SFMT
|
||||
${CMAKE_SOURCE_DIR}/dep/cppformat
|
||||
${CMAKE_SOURCE_DIR}/dep/zlib
|
||||
${CMAKE_SOURCE_DIR}/dep/zmqpp
|
||||
${CMAKE_SOURCE_DIR}/src/server/collision
|
||||
|
||||
@@ -104,17 +104,6 @@ ChatCommand* ChatHandler::getCommandTable()
|
||||
return commandTableCache;
|
||||
}
|
||||
|
||||
std::string ChatHandler::PGetParseString(uint32 entry, ...) const
|
||||
{
|
||||
const char *format = GetTrinityString(entry);
|
||||
char str[1024];
|
||||
va_list ap;
|
||||
va_start(ap, entry);
|
||||
vsnprintf(str, 1024, format, ap);
|
||||
va_end(ap);
|
||||
return std::string(str);
|
||||
}
|
||||
|
||||
char const* ChatHandler::GetTrinityString(uint32 entry) const
|
||||
{
|
||||
return m_session->GetTrinityString(entry);
|
||||
@@ -258,27 +247,6 @@ void ChatHandler::SendSysMessage(uint32 entry)
|
||||
SendSysMessage(GetTrinityString(entry));
|
||||
}
|
||||
|
||||
void ChatHandler::PSendSysMessage(uint32 entry, ...)
|
||||
{
|
||||
const char *format = GetTrinityString(entry);
|
||||
va_list ap;
|
||||
char str [2048];
|
||||
va_start(ap, entry);
|
||||
vsnprintf(str, 2048, format, ap);
|
||||
va_end(ap);
|
||||
SendSysMessage(str);
|
||||
}
|
||||
|
||||
void ChatHandler::PSendSysMessage(const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char str [2048];
|
||||
va_start(ap, format);
|
||||
vsnprintf(str, 2048, format, ap);
|
||||
va_end(ap);
|
||||
SendSysMessage(str);
|
||||
}
|
||||
|
||||
bool ChatHandler::ExecuteCommandInTable(ChatCommand* table, const char* text, std::string const& fullcmd)
|
||||
{
|
||||
char const* oldtext = text;
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#define TRINITYCORE_CHAT_H
|
||||
|
||||
#include "SharedDefines.h"
|
||||
#include "StringFormat.h"
|
||||
#include "WorldSession.h"
|
||||
#include "RBAC.h"
|
||||
|
||||
@@ -69,9 +70,24 @@ class ChatHandler
|
||||
virtual void SendSysMessage(char const* str);
|
||||
|
||||
void SendSysMessage(uint32 entry);
|
||||
void PSendSysMessage(char const* format, ...) ATTR_PRINTF(2, 3);
|
||||
void PSendSysMessage(uint32 entry, ...);
|
||||
std::string PGetParseString(uint32 entry, ...) const;
|
||||
|
||||
template<typename... Args>
|
||||
void PSendSysMessage(const char* fmt, Args const&... args)
|
||||
{
|
||||
SendSysMessage(Trinity::StringFormat(fmt, args...).c_str());
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void PSendSysMessage(uint32 entry, Args const&... args)
|
||||
{
|
||||
SendSysMessage(PGetParseString(entry, args...).c_str());
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
std::string PGetParseString(uint32 entry, Args const&... args) const
|
||||
{
|
||||
return Trinity::StringFormat(GetTrinityString(entry), args...);
|
||||
}
|
||||
|
||||
bool ParseCommands(const char* text);
|
||||
|
||||
|
||||
@@ -99,7 +99,8 @@ ConditionMgr::ConditionTypeInfo const ConditionMgr::StaticConditionTypeData[COND
|
||||
{ "Distance", true, true, true },
|
||||
{ "Alive", false, false, false },
|
||||
{ "Health Value", true, true, false },
|
||||
{ "Health Pct", true, true, false }
|
||||
{ "Health Pct", true, true, false },
|
||||
{ "Realm Achievement", true, false, false }
|
||||
};
|
||||
|
||||
// Checks if object meets the condition
|
||||
|
||||
@@ -3825,6 +3825,8 @@ void ObjectMgr::BuildPlayerLevelInfo(uint8 race, uint8 _class, uint8 level, Play
|
||||
}
|
||||
}
|
||||
|
||||
int32 const ReputationMgr::Reputation_Cap;
|
||||
|
||||
void ObjectMgr::LoadQuests()
|
||||
{
|
||||
uint32 oldMSTime = getMSTime();
|
||||
|
||||
@@ -182,9 +182,8 @@ struct TSpellSummary
|
||||
uint8 Effects; // set of enum SelectEffect
|
||||
} *SpellSummary;
|
||||
|
||||
ScriptMgr::ScriptMgr() : _scriptCount(0)
|
||||
ScriptMgr::ScriptMgr() : _scriptCount(0), _scheduledScripts(0)
|
||||
{
|
||||
_scheduledScripts = 0;
|
||||
}
|
||||
|
||||
ScriptMgr::~ScriptMgr() { }
|
||||
|
||||
@@ -1141,7 +1141,7 @@ class ScriptMgr
|
||||
uint32 _scriptCount;
|
||||
|
||||
//atomic op counter for active scripts amount
|
||||
std::atomic_long _scheduledScripts;
|
||||
std::atomic<uint32> _scheduledScripts;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -46,6 +46,8 @@ WorldSocketMgr::WorldSocketMgr() : BaseSocketMgr(), _socketSendBufferSize(-1), m
|
||||
{
|
||||
}
|
||||
|
||||
int const boost::asio::socket_base::max_connections;
|
||||
|
||||
bool WorldSocketMgr::StartNetwork(boost::asio::io_service& service, std::string const& bindIp, uint16 port)
|
||||
{
|
||||
_tcpNoDelay = sConfigMgr->GetBoolDefault("Network.TcpNodelay", true);
|
||||
|
||||
@@ -7193,7 +7193,7 @@ void Spell::CallScriptDestinationTargetSelectHandlers(SpellDestination& target,
|
||||
bool Spell::CheckScriptEffectImplicitTargets(uint32 effIndex, uint32 effIndexToCheck)
|
||||
{
|
||||
// Skip if there are not any script
|
||||
if (!m_loadedScripts.size())
|
||||
if (m_loadedScripts.empty())
|
||||
return true;
|
||||
|
||||
for (std::list<SpellScript*>::iterator itr = m_loadedScripts.begin(); itr != m_loadedScripts.end(); ++itr)
|
||||
|
||||
@@ -51,6 +51,7 @@ include_directories(
|
||||
${CMAKE_SOURCE_DIR}/dep/recastnavigation/Recast/Include
|
||||
${CMAKE_SOURCE_DIR}/dep/g3dlite/include
|
||||
${CMAKE_SOURCE_DIR}/dep/SFMT
|
||||
${CMAKE_SOURCE_DIR}/dep/cppformat
|
||||
${CMAKE_SOURCE_DIR}/dep/zlib
|
||||
${CMAKE_SOURCE_DIR}/src/server/shared
|
||||
${CMAKE_SOURCE_DIR}/src/server/shared/Configuration
|
||||
|
||||
@@ -40,25 +40,44 @@ EndContentData */
|
||||
|
||||
enum Sylvanas
|
||||
{
|
||||
QUEST_JOURNEY_TO_UNDERCITY = 9180,
|
||||
EMOTE_LAMENT_END = 0,
|
||||
SAY_LAMENT_END = 1,
|
||||
QUEST_JOURNEY_TO_UNDERCITY = 9180,
|
||||
|
||||
SOUND_CREDIT = 10896,
|
||||
ENTRY_HIGHBORNE_LAMENTER = 21628,
|
||||
ENTRY_HIGHBORNE_BUNNY = 21641,
|
||||
EMOTE_LAMENT_END = 0,
|
||||
SAY_LAMENT_END = 1,
|
||||
EMOTE_LAMENT = 2,
|
||||
|
||||
SPELL_HIGHBORNE_AURA = 37090,
|
||||
SPELL_SYLVANAS_CAST = 36568,
|
||||
SPELL_RIBBON_OF_SOULS = 34432, // the real one to use might be 37099
|
||||
// Ambassador Sunsorrow
|
||||
SAY_SUNSORROW_WHISPER = 0,
|
||||
|
||||
SOUND_CREDIT = 10896,
|
||||
|
||||
NPC_HIGHBORNE_LAMENTER = 21628,
|
||||
NPC_HIGHBORNE_BUNNY = 21641,
|
||||
NPC_AMBASSADOR_SUNSORROW = 16287,
|
||||
|
||||
SPELL_HIGHBORNE_AURA = 37090,
|
||||
SPELL_SYLVANAS_CAST = 36568,
|
||||
//SPELL_RIBBON_OF_SOULS = 34432, the real one to use might be 37099
|
||||
SPELL_RIBBON_OF_SOULS = 37099,
|
||||
|
||||
// Combat spells
|
||||
SPELL_BLACK_ARROW = 59712,
|
||||
SPELL_FADE = 20672,
|
||||
SPELL_FADE_BLINK = 29211,
|
||||
SPELL_MULTI_SHOT = 59713,
|
||||
SPELL_SHOT = 59710,
|
||||
SPELL_SUMMON_SKELETON = 59711
|
||||
SPELL_BLACK_ARROW = 59712,
|
||||
SPELL_FADE = 20672,
|
||||
SPELL_FADE_BLINK = 29211,
|
||||
SPELL_MULTI_SHOT = 59713,
|
||||
SPELL_SHOT = 59710,
|
||||
SPELL_SUMMON_SKELETON = 59711,
|
||||
|
||||
// Events
|
||||
EVENT_FADE = 1,
|
||||
EVENT_SUMMON_SKELETON = 2,
|
||||
EVENT_BLACK_ARROW = 3,
|
||||
EVENT_SHOOT = 4,
|
||||
EVENT_MULTI_SHOT = 5,
|
||||
EVENT_LAMENT_OF_THE_HIGHBORN = 6,
|
||||
EVENT_SUNSORROW_WHISPER = 7,
|
||||
|
||||
GUID_EVENT_INVOKER = 1,
|
||||
};
|
||||
|
||||
float HighborneLoc[4][3]=
|
||||
@@ -77,26 +96,14 @@ class npc_lady_sylvanas_windrunner : public CreatureScript
|
||||
public:
|
||||
npc_lady_sylvanas_windrunner() : CreatureScript("npc_lady_sylvanas_windrunner") { }
|
||||
|
||||
bool OnQuestReward(Player* /*player*/, Creature* creature, const Quest *_Quest, uint32 /*slot*/) override
|
||||
bool OnQuestReward(Player* player, Creature* creature, const Quest *_Quest, uint32 /*slot*/) override
|
||||
{
|
||||
if (_Quest->GetQuestId() == QUEST_JOURNEY_TO_UNDERCITY)
|
||||
{
|
||||
ENSURE_AI(npc_lady_sylvanas_windrunner::npc_lady_sylvanas_windrunnerAI, creature->AI())->LamentEvent = true;
|
||||
ENSURE_AI(npc_lady_sylvanas_windrunner::npc_lady_sylvanas_windrunnerAI, creature->AI())->DoPlaySoundToSet(creature, SOUND_CREDIT);
|
||||
creature->CastSpell(creature, SPELL_SYLVANAS_CAST, false);
|
||||
|
||||
for (uint8 i = 0; i < 4; ++i)
|
||||
creature->SummonCreature(ENTRY_HIGHBORNE_LAMENTER, HighborneLoc[i][0], HighborneLoc[i][1], HIGHBORNE_LOC_Y, HighborneLoc[i][2], TEMPSUMMON_TIMED_DESPAWN, 160000);
|
||||
}
|
||||
creature->AI()->SetGUID(player->GetGUID(), GUID_EVENT_INVOKER);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return new npc_lady_sylvanas_windrunnerAI(creature);
|
||||
}
|
||||
|
||||
struct npc_lady_sylvanas_windrunnerAI : public ScriptedAI
|
||||
{
|
||||
npc_lady_sylvanas_windrunnerAI(Creature* creature) : ScriptedAI(creature)
|
||||
@@ -106,41 +113,51 @@ public:
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
LamentEventTimer = 5000;
|
||||
LamentEvent = false;
|
||||
targetGUID.Clear();
|
||||
|
||||
FadeTimer = 30000;
|
||||
SummonSkeletonTimer = 20000;
|
||||
BlackArrowTimer = 15000;
|
||||
ShotTimer = 8000;
|
||||
MultiShotTimer = 10000;
|
||||
playerGUID.Clear();
|
||||
}
|
||||
|
||||
uint32 LamentEventTimer;
|
||||
bool LamentEvent;
|
||||
ObjectGuid targetGUID;
|
||||
|
||||
uint32 FadeTimer;
|
||||
uint32 SummonSkeletonTimer;
|
||||
uint32 BlackArrowTimer;
|
||||
uint32 ShotTimer;
|
||||
uint32 MultiShotTimer;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
Initialize();
|
||||
_events.Reset();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override { }
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
{
|
||||
_events.ScheduleEvent(EVENT_FADE, 30000);
|
||||
_events.ScheduleEvent(EVENT_SUMMON_SKELETON, 20000);
|
||||
_events.ScheduleEvent(EVENT_BLACK_ARROW, 15000);
|
||||
_events.ScheduleEvent(EVENT_SHOOT, 8000);
|
||||
_events.ScheduleEvent(EVENT_MULTI_SHOT, 10000);
|
||||
}
|
||||
|
||||
void SetGUID(ObjectGuid guid, int32 type) override
|
||||
{
|
||||
if (type == GUID_EVENT_INVOKER)
|
||||
{
|
||||
Talk(EMOTE_LAMENT);
|
||||
DoPlaySoundToSet(me, SOUND_CREDIT);
|
||||
DoCast(me, SPELL_SYLVANAS_CAST, false);
|
||||
playerGUID = guid;
|
||||
LamentEvent = true;
|
||||
|
||||
for (uint8 i = 0; i < 4; ++i)
|
||||
me->SummonCreature(NPC_HIGHBORNE_LAMENTER, HighborneLoc[i][0], HighborneLoc[i][1], HIGHBORNE_LOC_Y, HighborneLoc[i][2], TEMPSUMMON_TIMED_DESPAWN, 160000);
|
||||
|
||||
_events.ScheduleEvent(EVENT_LAMENT_OF_THE_HIGHBORN, 2000);
|
||||
_events.ScheduleEvent(EVENT_SUNSORROW_WHISPER, 10000);
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summoned) override
|
||||
{
|
||||
if (summoned->GetEntry() == ENTRY_HIGHBORNE_BUNNY)
|
||||
if (summoned->GetEntry() == NPC_HIGHBORNE_BUNNY)
|
||||
{
|
||||
if (Creature* target = ObjectAccessor::GetCreature(*summoned, targetGUID))
|
||||
{
|
||||
target->MonsterMoveWithSpeed(target->GetPositionX(), target->GetPositionY(), me->GetPositionZ()+15.0f, 0);
|
||||
target->GetMotionMaster()->MoveJump(target->GetPositionX(), target->GetPositionY(), me->GetPositionZ() + 15.0f, 0);
|
||||
target->SetPosition(target->GetPositionX(), target->GetPositionY(), me->GetPositionZ()+15.0f, 0.0f);
|
||||
summoned->CastSpell(target, SPELL_RIBBON_OF_SOULS, false);
|
||||
}
|
||||
@@ -152,75 +169,86 @@ public:
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (LamentEvent)
|
||||
{
|
||||
if (LamentEventTimer <= diff)
|
||||
{
|
||||
DoSummon(ENTRY_HIGHBORNE_BUNNY, me, 10.0f, 3000, TEMPSUMMON_TIMED_DESPAWN);
|
||||
|
||||
LamentEventTimer = 2000;
|
||||
if (!me->HasAura(SPELL_SYLVANAS_CAST))
|
||||
{
|
||||
Talk(SAY_LAMENT_END);
|
||||
Talk(EMOTE_LAMENT_END);
|
||||
LamentEvent = false;
|
||||
}
|
||||
} else LamentEventTimer -= diff;
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
if (!UpdateVictim() && !LamentEvent)
|
||||
return;
|
||||
|
||||
// Combat spells
|
||||
_events.Update(diff);
|
||||
|
||||
if (FadeTimer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_FADE);
|
||||
// add a blink to simulate a stealthed movement and reappearing elsewhere
|
||||
DoCast(me, SPELL_FADE_BLINK);
|
||||
FadeTimer = 30000 + rand32() % 5000;
|
||||
// if the victim is out of melee range she cast multi shot
|
||||
if (Unit* victim = me->GetVictim())
|
||||
if (me->GetDistance(victim) > 10.0f)
|
||||
DoCast(victim, SPELL_MULTI_SHOT);
|
||||
} else FadeTimer -= diff;
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
if (SummonSkeletonTimer <= diff)
|
||||
while (uint32 eventId = _events.ExecuteEvent())
|
||||
{
|
||||
DoCast(me, SPELL_SUMMON_SKELETON);
|
||||
SummonSkeletonTimer = 20000 + rand32() % 10000;
|
||||
} else SummonSkeletonTimer -= diff;
|
||||
|
||||
if (BlackArrowTimer <= diff)
|
||||
{
|
||||
if (Unit* victim = me->GetVictim())
|
||||
switch (eventId)
|
||||
{
|
||||
DoCast(victim, SPELL_BLACK_ARROW);
|
||||
BlackArrowTimer = 15000 + rand32() % 5000;
|
||||
case EVENT_FADE:
|
||||
DoCast(me, SPELL_FADE);
|
||||
// add a blink to simulate a stealthed movement and reappearing elsewhere
|
||||
DoCast(me, SPELL_FADE_BLINK);
|
||||
// if the victim is out of melee range she cast multi shot
|
||||
if (Unit* victim = me->GetVictim())
|
||||
if (me->GetDistance(victim) > 10.0f)
|
||||
DoCast(victim, SPELL_MULTI_SHOT);
|
||||
_events.ScheduleEvent(EVENT_FADE, urand(30000, 35000));
|
||||
break;
|
||||
case EVENT_SUMMON_SKELETON:
|
||||
DoCast(me, SPELL_SUMMON_SKELETON);
|
||||
_events.ScheduleEvent(EVENT_SUMMON_SKELETON, urand(20000, 30000));
|
||||
break;
|
||||
case EVENT_BLACK_ARROW:
|
||||
if (Unit* victim = me->GetVictim())
|
||||
DoCast(victim, SPELL_BLACK_ARROW);
|
||||
_events.ScheduleEvent(EVENT_BLACK_ARROW, urand(15000, 20000));
|
||||
break;
|
||||
case EVENT_SHOOT:
|
||||
if (Unit* victim = me->GetVictim())
|
||||
DoCast(victim, SPELL_SHOT);
|
||||
_events.ScheduleEvent(EVENT_SHOOT, urand(8000, 10000));
|
||||
break;
|
||||
case EVENT_MULTI_SHOT:
|
||||
if (Unit* victim = me->GetVictim())
|
||||
DoCast(victim, SPELL_MULTI_SHOT);
|
||||
_events.ScheduleEvent(EVENT_MULTI_SHOT, urand(10000, 13000));
|
||||
break;
|
||||
case EVENT_LAMENT_OF_THE_HIGHBORN:
|
||||
if (!me->HasAura(SPELL_SYLVANAS_CAST))
|
||||
{
|
||||
Talk(SAY_LAMENT_END);
|
||||
Talk(EMOTE_LAMENT_END);
|
||||
LamentEvent = false;
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_KNEEL);
|
||||
Reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
DoSummon(NPC_HIGHBORNE_BUNNY, me, 10.0f, 3000, TEMPSUMMON_TIMED_DESPAWN);
|
||||
_events.ScheduleEvent(EVENT_LAMENT_OF_THE_HIGHBORN, 2000);
|
||||
}
|
||||
break;
|
||||
case EVENT_SUNSORROW_WHISPER:
|
||||
if (Creature* ambassador = me->FindNearestCreature(NPC_AMBASSADOR_SUNSORROW, 20.0f))
|
||||
if (Player* player = ObjectAccessor::GetPlayer(*me, playerGUID))
|
||||
ambassador->AI()->Talk(SAY_SUNSORROW_WHISPER, player);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else BlackArrowTimer -= diff;
|
||||
|
||||
if (ShotTimer <= diff)
|
||||
{
|
||||
if (Unit* victim = me->GetVictim())
|
||||
{
|
||||
DoCast(victim, SPELL_SHOT);
|
||||
ShotTimer = 8000 + rand32() % 2000;
|
||||
}
|
||||
} else ShotTimer -= diff;
|
||||
|
||||
if (MultiShotTimer <= diff)
|
||||
{
|
||||
if (Unit* victim = me->GetVictim())
|
||||
{
|
||||
DoCast(victim, SPELL_MULTI_SHOT);
|
||||
MultiShotTimer = 10000 + rand32() % 3000;
|
||||
}
|
||||
} else MultiShotTimer -= diff;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
EventMap _events;
|
||||
bool LamentEvent;
|
||||
ObjectGuid targetGUID;
|
||||
ObjectGuid playerGUID;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return new npc_lady_sylvanas_windrunnerAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
/*######
|
||||
|
||||
@@ -395,6 +395,9 @@ enum NesingwaryTrapper
|
||||
GO_CARIBOU_TRAP_15 = 188008,
|
||||
|
||||
SPELL_TRAPPED = 46104,
|
||||
|
||||
// Texts
|
||||
SAY_NESINGWARY_1 = 0
|
||||
};
|
||||
|
||||
#define CaribouTrapsNum 15
|
||||
@@ -471,7 +474,7 @@ public:
|
||||
phase = 3;
|
||||
break;
|
||||
case 3:
|
||||
//Talk(SAY_NESINGWARY_1);
|
||||
Talk(SAY_NESINGWARY_1);
|
||||
phaseTimer = 2000;
|
||||
phase = 4;
|
||||
break;
|
||||
|
||||
@@ -59,6 +59,7 @@ include_directories(
|
||||
${CMAKE_BINARY_DIR}
|
||||
${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour
|
||||
${CMAKE_SOURCE_DIR}/dep/SFMT
|
||||
${CMAKE_SOURCE_DIR}/dep/cppformat
|
||||
${CMAKE_SOURCE_DIR}/dep/utf8cpp
|
||||
${CMAKE_SOURCE_DIR}/src/server
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
#include "Appender.h"
|
||||
#include "Common.h"
|
||||
#include "Util.h"
|
||||
#include "StringFormat.h"
|
||||
|
||||
#include <utility>
|
||||
#include <sstream>
|
||||
|
||||
std::string LogMessage::getTimeStr(time_t time)
|
||||
{
|
||||
@@ -68,38 +72,36 @@ void Appender::setLogLevel(LogLevel _level)
|
||||
level = _level;
|
||||
}
|
||||
|
||||
void Appender::write(LogMessage& message)
|
||||
void Appender::write(LogMessage* message)
|
||||
{
|
||||
if (!level || level > message.level)
|
||||
if (!level || level > message->level)
|
||||
return;
|
||||
|
||||
message.prefix.clear();
|
||||
std::ostringstream ss;
|
||||
|
||||
if (flags & APPENDER_FLAGS_PREFIX_TIMESTAMP)
|
||||
message.prefix.append(message.getTimeStr());
|
||||
ss << message->getTimeStr();
|
||||
|
||||
if (flags & APPENDER_FLAGS_PREFIX_LOGLEVEL)
|
||||
{
|
||||
if (!message.prefix.empty())
|
||||
message.prefix.push_back(' ');
|
||||
if (ss.rdbuf()->in_avail() == 0)
|
||||
ss << ' ';
|
||||
|
||||
char text[MAX_QUERY_LEN];
|
||||
snprintf(text, MAX_QUERY_LEN, "%-5s", Appender::getLogLevelString(message.level));
|
||||
message.prefix.append(text);
|
||||
ss << Trinity::StringFormat("%-5s", Appender::getLogLevelString(message->level));
|
||||
}
|
||||
|
||||
if (flags & APPENDER_FLAGS_PREFIX_LOGFILTERTYPE)
|
||||
{
|
||||
if (!message.prefix.empty())
|
||||
message.prefix.push_back(' ');
|
||||
if (ss.rdbuf()->in_avail() == 0)
|
||||
ss << ' ';
|
||||
|
||||
message.prefix.push_back('[');
|
||||
message.prefix.append(message.type);
|
||||
message.prefix.push_back(']');
|
||||
ss << '[' << message->type << ']';
|
||||
}
|
||||
|
||||
if (!message.prefix.empty())
|
||||
message.prefix.push_back(' ');
|
||||
if (ss.rdbuf()->in_avail() == 0)
|
||||
ss << ' ';
|
||||
|
||||
message->prefix = std::move(ss.str());
|
||||
_write(message);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include <time.h>
|
||||
#include <type_traits>
|
||||
#include "Define.h"
|
||||
|
||||
// Values assigned have their equivalent in enum ACE_Log_Priority
|
||||
@@ -57,16 +58,16 @@ enum AppenderFlags
|
||||
|
||||
struct LogMessage
|
||||
{
|
||||
LogMessage(LogLevel _level, std::string const& _type, std::string const& _text)
|
||||
: level(_level), type(_type), text(_text), mtime(time(NULL))
|
||||
LogMessage(LogLevel _level, std::string const& _type, std::string&& _text)
|
||||
: level(_level), type(_type), text(std::forward<std::string>(_text)), mtime(time(NULL))
|
||||
{ }
|
||||
|
||||
static std::string getTimeStr(time_t time);
|
||||
std::string getTimeStr();
|
||||
|
||||
LogLevel level;
|
||||
std::string type;
|
||||
std::string text;
|
||||
LogLevel const level;
|
||||
std::string const type;
|
||||
std::string const text;
|
||||
std::string prefix;
|
||||
std::string param1;
|
||||
time_t mtime;
|
||||
@@ -91,11 +92,11 @@ class Appender
|
||||
AppenderFlags getFlags() const;
|
||||
|
||||
void setLogLevel(LogLevel);
|
||||
void write(LogMessage& message);
|
||||
void write(LogMessage* message);
|
||||
static const char* getLogLevelString(LogLevel level);
|
||||
|
||||
private:
|
||||
virtual void _write(LogMessage const& /*message*/) = 0;
|
||||
virtual void _write(LogMessage const* /*message*/) = 0;
|
||||
|
||||
uint8 id;
|
||||
std::string name;
|
||||
|
||||
@@ -158,14 +158,14 @@ void AppenderConsole::ResetColor(bool stdout_stream)
|
||||
#endif
|
||||
}
|
||||
|
||||
void AppenderConsole::_write(LogMessage const& message)
|
||||
void AppenderConsole::_write(LogMessage const* message)
|
||||
{
|
||||
bool stdout_stream = !(message.level == LOG_LEVEL_ERROR || message.level == LOG_LEVEL_FATAL);
|
||||
bool stdout_stream = !(message->level == LOG_LEVEL_ERROR || message->level == LOG_LEVEL_FATAL);
|
||||
|
||||
if (_colored)
|
||||
{
|
||||
uint8 index;
|
||||
switch (message.level)
|
||||
switch (message->level)
|
||||
{
|
||||
case LOG_LEVEL_TRACE:
|
||||
index = 5;
|
||||
@@ -189,9 +189,9 @@ void AppenderConsole::_write(LogMessage const& message)
|
||||
}
|
||||
|
||||
SetColor(stdout_stream, _colors[index]);
|
||||
utf8printf(stdout_stream ? stdout : stderr, "%s%s", message.prefix.c_str(), message.text.c_str());
|
||||
utf8printf(stdout_stream ? stdout : stderr, "%s%s\n", message->prefix.c_str(), message->text.c_str());
|
||||
ResetColor(stdout_stream);
|
||||
}
|
||||
else
|
||||
utf8printf(stdout_stream ? stdout : stderr, "%s%s", message.prefix.c_str(), message.text.c_str());
|
||||
utf8printf(stdout_stream ? stdout : stderr, "%s%s\n", message->prefix.c_str(), message->text.c_str());
|
||||
}
|
||||
@@ -51,7 +51,7 @@ class AppenderConsole: public Appender
|
||||
private:
|
||||
void SetColor(bool stdout_stream, ColorTypes color);
|
||||
void ResetColor(bool stdout_stream);
|
||||
void _write(LogMessage const& message) override;
|
||||
void _write(LogMessage const* message) override;
|
||||
bool _colored;
|
||||
ColorTypes _colors[MaxLogLevels];
|
||||
};
|
||||
|
||||
@@ -23,18 +23,18 @@ AppenderDB::AppenderDB(uint8 id, std::string const& name, LogLevel level)
|
||||
|
||||
AppenderDB::~AppenderDB() { }
|
||||
|
||||
void AppenderDB::_write(LogMessage const& message)
|
||||
void AppenderDB::_write(LogMessage const* message)
|
||||
{
|
||||
// Avoid infinite loop, PExecute triggers Logging with "sql.sql" type
|
||||
if (!enabled || !message.type.find("sql"))
|
||||
if (!enabled || (message->type.find("sql") != std::string::npos))
|
||||
return;
|
||||
|
||||
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_LOG);
|
||||
stmt->setUInt64(0, message.mtime);
|
||||
stmt->setUInt64(0, message->mtime);
|
||||
stmt->setUInt32(1, realmId);
|
||||
stmt->setString(2, message.type);
|
||||
stmt->setUInt8(3, uint8(message.level));
|
||||
stmt->setString(4, message.text);
|
||||
stmt->setString(2, message->type);
|
||||
stmt->setUInt8(3, uint8(message->level));
|
||||
stmt->setString(4, message->text);
|
||||
LoginDatabase.Execute(stmt);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ class AppenderDB: public Appender
|
||||
private:
|
||||
uint32 realmId;
|
||||
bool enabled;
|
||||
void _write(LogMessage const& message) override;
|
||||
void _write(LogMessage const* message) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -43,21 +43,21 @@ AppenderFile::~AppenderFile()
|
||||
CloseFile();
|
||||
}
|
||||
|
||||
void AppenderFile::_write(LogMessage const& message)
|
||||
void AppenderFile::_write(LogMessage const* message)
|
||||
{
|
||||
bool exceedMaxSize = maxFileSize > 0 && (fileSize.load() + message.Size()) > maxFileSize;
|
||||
bool exceedMaxSize = maxFileSize > 0 && (fileSize.load() + message->Size()) > maxFileSize;
|
||||
|
||||
if (dynamicName)
|
||||
{
|
||||
char namebuf[TRINITY_PATH_MAX];
|
||||
snprintf(namebuf, TRINITY_PATH_MAX, filename.c_str(), message.param1.c_str());
|
||||
snprintf(namebuf, TRINITY_PATH_MAX, filename.c_str(), message->param1.c_str());
|
||||
// always use "a" with dynamic name otherwise it could delete the log we wrote in last _write() call
|
||||
FILE* file = OpenFile(namebuf, "a", backup || exceedMaxSize);
|
||||
if (!file)
|
||||
return;
|
||||
fprintf(file, "%s%s", message.prefix.c_str(), message.text.c_str());
|
||||
fprintf(file, "%s%s", message->prefix.c_str(), message->text.c_str());
|
||||
fflush(file);
|
||||
fileSize += uint64(message.Size());
|
||||
fileSize += uint64(message->Size());
|
||||
fclose(file);
|
||||
return;
|
||||
}
|
||||
@@ -67,9 +67,9 @@ void AppenderFile::_write(LogMessage const& message)
|
||||
if (!logfile)
|
||||
return;
|
||||
|
||||
fprintf(logfile, "%s%s", message.prefix.c_str(), message.text.c_str());
|
||||
fprintf(logfile, "%s%s\n", message->prefix.c_str(), message->text.c_str());
|
||||
fflush(logfile);
|
||||
fileSize += uint64(message.Size());
|
||||
fileSize += uint64(message->Size());
|
||||
}
|
||||
|
||||
FILE* AppenderFile::OpenFile(std::string const &filename, std::string const &mode, bool backup)
|
||||
|
||||
@@ -30,7 +30,7 @@ class AppenderFile: public Appender
|
||||
|
||||
private:
|
||||
void CloseFile();
|
||||
void _write(LogMessage const& message) override;
|
||||
void _write(LogMessage const* message) override;
|
||||
FILE* logfile;
|
||||
std::string filename;
|
||||
std::string logDir;
|
||||
|
||||
@@ -264,30 +264,18 @@ void Log::ReadLoggersFromConfig()
|
||||
}
|
||||
}
|
||||
|
||||
void Log::vlog(std::string const& filter, LogLevel level, char const* str, va_list argptr)
|
||||
{
|
||||
char text[MAX_QUERY_LEN];
|
||||
vsnprintf(text, MAX_QUERY_LEN, str, argptr);
|
||||
write(new LogMessage(level, filter, text));
|
||||
}
|
||||
|
||||
void Log::write(LogMessage* msg) const
|
||||
void Log::write(std::unique_ptr<LogMessage>&& msg) const
|
||||
{
|
||||
Logger const* logger = GetLoggerByType(msg->type);
|
||||
msg->text.append("\n");
|
||||
|
||||
if (_ioService)
|
||||
{
|
||||
auto logOperation = std::shared_ptr<LogOperation>(new LogOperation(logger, msg));
|
||||
auto logOperation = std::shared_ptr<LogOperation>(new LogOperation(logger, std::forward<std::unique_ptr<LogMessage>>(msg)));
|
||||
|
||||
_ioService->post(_strand->wrap([logOperation](){ logOperation->call(); }));
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
logger->write(*msg);
|
||||
delete msg;
|
||||
}
|
||||
logger->write(msg.get());
|
||||
}
|
||||
|
||||
std::string Log::GetTimestampStr()
|
||||
@@ -349,40 +337,20 @@ void Log::outCharDump(char const* str, uint32 accountId, uint64 guid, char const
|
||||
ss << "== START DUMP == (account: " << accountId << " guid: " << guid << " name: " << name
|
||||
<< ")\n" << str << "\n== END DUMP ==\n";
|
||||
|
||||
LogMessage* msg = new LogMessage(LOG_LEVEL_INFO, "entities.player.dump", ss.str());
|
||||
std::unique_ptr<LogMessage> msg(new LogMessage(LOG_LEVEL_INFO, "entities.player.dump", ss.str()));
|
||||
std::ostringstream param;
|
||||
param << guid << '_' << name;
|
||||
|
||||
msg->param1 = param.str();
|
||||
|
||||
write(msg);
|
||||
}
|
||||
|
||||
void Log::outCommand(uint32 account, const char * str, ...)
|
||||
{
|
||||
if (!str || !ShouldLog("commands.gm", LOG_LEVEL_INFO))
|
||||
return;
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, str);
|
||||
char text[MAX_QUERY_LEN];
|
||||
vsnprintf(text, MAX_QUERY_LEN, str, ap);
|
||||
va_end(ap);
|
||||
|
||||
LogMessage* msg = new LogMessage(LOG_LEVEL_INFO, "commands.gm", text);
|
||||
|
||||
std::ostringstream ss;
|
||||
ss << account;
|
||||
msg->param1 = ss.str();
|
||||
|
||||
write(msg);
|
||||
write(std::move(msg));
|
||||
}
|
||||
|
||||
void Log::SetRealmId(uint32 id)
|
||||
{
|
||||
for (AppenderMap::iterator it = appenders.begin(); it != appenders.end(); ++it)
|
||||
if (it->second && it->second->getType() == APPENDER_DB)
|
||||
((AppenderDB *)it->second)->setRealmId(id);
|
||||
static_cast<AppenderDB*>(it->second)->setRealmId(id);
|
||||
}
|
||||
|
||||
void Log::Close()
|
||||
|
||||
@@ -22,12 +22,13 @@
|
||||
#include "Define.h"
|
||||
#include "Appender.h"
|
||||
#include "Logger.h"
|
||||
#include <stdarg.h>
|
||||
#include "StringFormat.h"
|
||||
#include <boost/asio/io_service.hpp>
|
||||
#include <boost/asio/strand.hpp>
|
||||
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
#define LOGGER_ROOT "root"
|
||||
|
||||
@@ -59,17 +60,34 @@ class Log
|
||||
bool ShouldLog(std::string const& type, LogLevel level) const;
|
||||
bool SetLogLevel(std::string const& name, char const* level, bool isLogger = true);
|
||||
|
||||
void outMessage(std::string const& f, LogLevel level, char const* str, ...) ATTR_PRINTF(4, 5);
|
||||
template<typename... Args>
|
||||
inline void outMessage(std::string const& filter, LogLevel const level, const char* fmt, Args const&... args)
|
||||
{
|
||||
write(std::move(std::unique_ptr<LogMessage>(new LogMessage(level, filter, std::move(Trinity::StringFormat(fmt, args...))))));
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void outCommand(uint32 account, const char* fmt, Args const&... args)
|
||||
{
|
||||
if (!ShouldLog("commands.gm", LOG_LEVEL_INFO))
|
||||
return;
|
||||
|
||||
std::unique_ptr<LogMessage> msg(new LogMessage(LOG_LEVEL_INFO, "commands.gm", std::move(Trinity::StringFormat(fmt, args...))));
|
||||
|
||||
std::ostringstream ss;
|
||||
ss << account;
|
||||
msg->param1 = ss.str();
|
||||
|
||||
write(std::move(msg));
|
||||
}
|
||||
|
||||
void outCommand(uint32 account, const char * str, ...) ATTR_PRINTF(3, 4);
|
||||
void outCharDump(char const* str, uint32 account_id, uint64 guid, char const* name);
|
||||
|
||||
void SetRealmId(uint32 id);
|
||||
|
||||
private:
|
||||
static std::string GetTimestampStr();
|
||||
void vlog(std::string const& f, LogLevel level, char const* str, va_list argptr);
|
||||
void write(LogMessage* msg) const;
|
||||
void write(std::unique_ptr<LogMessage>&& msg) const;
|
||||
|
||||
Logger const* GetLoggerByType(std::string const& type) const;
|
||||
Appender* GetAppenderByName(std::string const& name);
|
||||
@@ -126,23 +144,34 @@ inline bool Log::ShouldLog(std::string const& type, LogLevel level) const
|
||||
return logLevel != LOG_LEVEL_DISABLED && logLevel <= level;
|
||||
}
|
||||
|
||||
inline void Log::outMessage(std::string const& filter, LogLevel level, const char * str, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, str);
|
||||
|
||||
vlog(filter, level, str, ap);
|
||||
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
#define sLog Log::instance()
|
||||
|
||||
#define LOG_EXCEPTION_FREE(filterType__, level__, ...) \
|
||||
{ \
|
||||
try \
|
||||
{ \
|
||||
sLog->outMessage(filterType__, level__, __VA_ARGS__); \
|
||||
} \
|
||||
catch (std::exception& e) \
|
||||
{ \
|
||||
sLog->outMessage("server", LOG_LEVEL_ERROR, "Wrong format occurred (%s) at %s:%u.", \
|
||||
e.what(), __FILE__, __LINE__); \
|
||||
} \
|
||||
}
|
||||
|
||||
#if PLATFORM != PLATFORM_WINDOWS
|
||||
void check_args(const char* format, ...) ATTR_PRINTF(1, 2);
|
||||
|
||||
// This will catch format errors on build time
|
||||
#define TC_LOG_MESSAGE_BODY(filterType__, level__, ...) \
|
||||
do { \
|
||||
if (sLog->ShouldLog(filterType__, level__)) \
|
||||
sLog->outMessage(filterType__, level__, __VA_ARGS__); \
|
||||
{ \
|
||||
if (false) \
|
||||
check_args(__VA_ARGS__); \
|
||||
\
|
||||
LOG_EXCEPTION_FREE(filterType__, level__, __VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
#define TC_LOG_MESSAGE_BODY(filterType__, level__, ...) \
|
||||
@@ -150,7 +179,7 @@ inline void Log::outMessage(std::string const& filter, LogLevel level, const cha
|
||||
__pragma(warning(disable:4127)) \
|
||||
do { \
|
||||
if (sLog->ShouldLog(filterType__, level__)) \
|
||||
sLog->outMessage(filterType__, level__, __VA_ARGS__); \
|
||||
LOG_EXCEPTION_FREE(filterType__, level__, __VA_ARGS__); \
|
||||
} while (0) \
|
||||
__pragma(warning(pop))
|
||||
#endif
|
||||
|
||||
@@ -18,14 +18,8 @@
|
||||
#include "LogOperation.h"
|
||||
#include "Logger.h"
|
||||
|
||||
LogOperation::~LogOperation()
|
||||
{
|
||||
delete msg;
|
||||
}
|
||||
|
||||
int LogOperation::call()
|
||||
{
|
||||
if (logger && msg)
|
||||
logger->write(*msg);
|
||||
logger->write(msg.get());
|
||||
return 0;
|
||||
}
|
||||
@@ -18,23 +18,25 @@
|
||||
#ifndef LOGOPERATION_H
|
||||
#define LOGOPERATION_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
class Logger;
|
||||
struct LogMessage;
|
||||
|
||||
class LogOperation
|
||||
{
|
||||
public:
|
||||
LogOperation(Logger const* _logger, LogMessage* _msg)
|
||||
: logger(_logger), msg(_msg)
|
||||
LogOperation(Logger const* _logger, std::unique_ptr<LogMessage>&& _msg)
|
||||
: logger(_logger), msg(std::forward<std::unique_ptr<LogMessage>>(_msg))
|
||||
{ }
|
||||
|
||||
~LogOperation();
|
||||
~LogOperation() { }
|
||||
|
||||
int call();
|
||||
|
||||
protected:
|
||||
Logger const* logger;
|
||||
LogMessage* msg;
|
||||
std::unique_ptr<LogMessage> msg;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -50,9 +50,9 @@ void Logger::setLogLevel(LogLevel _level)
|
||||
level = _level;
|
||||
}
|
||||
|
||||
void Logger::write(LogMessage& message) const
|
||||
void Logger::write(LogMessage* message) const
|
||||
{
|
||||
if (!level || level > message.level || message.text.empty())
|
||||
if (!level || level > message->level || message->text.empty())
|
||||
{
|
||||
//fprintf(stderr, "Logger::write: Logger %s, Level %u. Msg %s Level %u WRONG LEVEL MASK OR EMPTY MSG\n", getName().c_str(), getLogLevel(), message.text.c_str(), message.level);
|
||||
return;
|
||||
|
||||
@@ -32,7 +32,7 @@ class Logger
|
||||
std::string const& getName() const;
|
||||
LogLevel getLogLevel() const;
|
||||
void setLogLevel(LogLevel level);
|
||||
void write(LogMessage& message) const;
|
||||
void write(LogMessage* message) const;
|
||||
|
||||
private:
|
||||
std::string name;
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TRINITYCORE_STRING_FORMAT_H
|
||||
#define TRINITYCORE_STRING_FORMAT_H
|
||||
|
||||
#include <format.h>
|
||||
|
||||
namespace Trinity
|
||||
{
|
||||
//! Default TC string format function
|
||||
template<typename... Args>
|
||||
inline std::string StringFormat(const char* fmt, Args const&... args)
|
||||
{
|
||||
return fmt::sprintf(fmt, args...);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -48,6 +48,7 @@ include_directories(
|
||||
${CMAKE_SOURCE_DIR}/dep/sockets/include
|
||||
${CMAKE_SOURCE_DIR}/dep/SFMT
|
||||
${CMAKE_SOURCE_DIR}/dep/zmqpp
|
||||
${CMAKE_SOURCE_DIR}/dep/cppformat
|
||||
${CMAKE_SOURCE_DIR}/src/server/collision
|
||||
${CMAKE_SOURCE_DIR}/src/server/collision/Management
|
||||
${CMAKE_SOURCE_DIR}/src/server/collision/Models
|
||||
@@ -175,6 +176,7 @@ target_link_libraries(worldserver
|
||||
gsoap
|
||||
Detour
|
||||
zmqpp
|
||||
format
|
||||
${JEMALLOC_LIBRARY}
|
||||
${READLINE_LIBRARY}
|
||||
${TERMCAP_LIBRARY}
|
||||
|
||||
Reference in new issue
Block a user