aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Entities/Object/ObjectGuid.cpp80
-rw-r--r--src/server/game/Entities/Object/ObjectGuid.h34
-rw-r--r--src/server/game/Server/WorldSession.cpp12
-rw-r--r--src/server/scripts/Commands/cs_npc.cpp2
4 files changed, 108 insertions, 20 deletions
diff --git a/src/server/game/Entities/Object/ObjectGuid.cpp b/src/server/game/Entities/Object/ObjectGuid.cpp
index 9a8bd07fe76..959be366409 100644
--- a/src/server/game/Entities/Object/ObjectGuid.cpp
+++ b/src/server/game/Entities/Object/ObjectGuid.cpp
@@ -17,14 +17,76 @@
#include "ObjectGuid.h"
#include "ByteBuffer.h"
+#include "Errors.h"
#include "Log.h"
+#include "Util.h"
#include "World.h"
-#include <sstream>
-#include <iomanip>
+#include <charconv>
ObjectGuid const ObjectGuid::Empty = ObjectGuid();
-char const* ObjectGuid::GetTypeName(HighGuid high)
+namespace
+{
+struct ObjectGuidInfo
+{
+ struct FormatPadding { std::ptrdiff_t Value; constexpr operator std::ptrdiff_t() const { return Value; } };
+
+ template <std::ptrdiff_t Width>
+ static constexpr inline FormatPadding padding{ .Value = Width };
+ static constexpr inline FormatPadding no_padding{ .Value = 0 };
+
+ struct FormatBase { int32 Value; constexpr operator int32() const { return Value; } };
+
+ static constexpr inline FormatBase dec{ 10 };
+ static constexpr inline FormatBase hex{ 16 };
+
+ static fmt::appender AppendTypeName(fmt::format_context& ctx, std::string_view type)
+ {
+ return std::copy(type.begin(), type.end(), ctx.out());
+ }
+
+ template <FormatPadding Width, FormatBase Base>
+ static fmt::appender AppendComponent(fmt::format_context& ctx, uint64 component)
+ {
+ std::array<char, 20> buf;
+ auto [end, err] = std::to_chars(buf.data(), buf.data() + buf.size(), component, Base);
+
+ ASSERT(err == std::errc(), "Failed to convert guid part to string");
+
+ if constexpr (Width != 0)
+ {
+ if (std::distance(buf.data(), end) < Width)
+ std::fill_n(ctx.out(), Width - std::distance(buf.data(), end), '0');
+ }
+
+ if constexpr (Base > 10)
+ return std::transform(buf.data(), end, ctx.out(), charToUpper);
+ else
+ return std::copy(buf.data(), end, ctx.out());
+ }
+};
+}
+
+template <typename FormatContext>
+auto fmt::formatter<ObjectGuid>::format(ObjectGuid const& guid, FormatContext& ctx) const -> decltype(ctx.out())
+{
+ ctx.advance_to(ObjectGuidInfo::AppendTypeName(ctx, "GUID Full: 0x"));
+ ctx.advance_to(ObjectGuidInfo::AppendComponent<ObjectGuidInfo::padding<16>, ObjectGuidInfo::hex>(ctx, guid.GetRawValue()));
+ ctx.advance_to(ObjectGuidInfo::AppendTypeName(ctx, " Type: "));
+ ctx.advance_to(ObjectGuidInfo::AppendTypeName(ctx, guid.GetTypeName()));
+ if (uint32 entry = guid.GetEntry())
+ {
+ ctx.advance_to(ObjectGuidInfo::AppendTypeName(ctx, guid.IsPet() ? " Pet number: " : " Entry: "));
+ ctx.advance_to(ObjectGuidInfo::AppendComponent<ObjectGuidInfo::no_padding, ObjectGuidInfo::dec>(ctx, entry));
+ }
+ ctx.advance_to(ObjectGuidInfo::AppendTypeName(ctx, " Low: "));
+ ctx.advance_to(ObjectGuidInfo::AppendComponent<ObjectGuidInfo::no_padding, ObjectGuidInfo::dec>(ctx, guid.GetCounter()));
+ return ctx.out();
+}
+
+template TC_GAME_API fmt::appender fmt::formatter<ObjectGuid>::format<fmt::format_context>(ObjectGuid const&, format_context&) const;
+
+std::string_view ObjectGuid::GetTypeName(HighGuid high)
{
switch (high)
{
@@ -47,14 +109,12 @@ char const* ObjectGuid::GetTypeName(HighGuid high)
std::string ObjectGuid::ToString() const
{
- std::ostringstream str;
- str << "GUID Full: 0x" << std::hex << std::setw(16) << std::setfill('0') << _guid << std::dec;
- str << " Type: " << GetTypeName();
- if (HasEntry())
- str << (IsPet() ? " Pet number: " : " Entry: ") << GetEntry() << " ";
+ return Trinity::StringFormat("{}", *this);
+}
- str << " Low: " << GetCounter();
- return str.str();
+std::string ObjectGuid::ToHexString() const
+{
+ return Trinity::StringFormat("0x{:016X}", _guid);
}
ObjectGuid ObjectGuid::Global(HighGuid type, LowType counter)
diff --git a/src/server/game/Entities/Object/ObjectGuid.h b/src/server/game/Entities/Object/ObjectGuid.h
index 9c09e75c56e..18fc2590554 100644
--- a/src/server/game/Entities/Object/ObjectGuid.h
+++ b/src/server/game/Entities/Object/ObjectGuid.h
@@ -24,6 +24,7 @@
#include <list>
#include <memory>
#include <set>
+#include <stdexcept>
#include <string>
#include <type_traits>
#include <unordered_set>
@@ -216,9 +217,10 @@ class TC_GAME_API ObjectGuid
bool operator==(ObjectGuid const& right) const = default;
std::strong_ordering operator<=>(ObjectGuid const& right) const = default;
- static char const* GetTypeName(HighGuid high);
- char const* GetTypeName() const { return !IsEmpty() ? GetTypeName(GetHigh()) : "None"; }
+ static std::string_view GetTypeName(HighGuid high);
+ std::string_view GetTypeName() const { return !IsEmpty() ? GetTypeName(GetHigh()) : "None"; }
std::string ToString() const;
+ std::string ToHexString() const;
private:
static bool HasEntry(HighGuid high)
@@ -318,4 +320,32 @@ namespace std
};
}
+namespace fmt
+{
+inline namespace v9
+{
+template <typename T, typename Char, typename Enable>
+struct formatter;
+
+template <>
+struct formatter<ObjectGuid, char, void>
+{
+ template <typename ParseContext>
+ constexpr auto parse(ParseContext& ctx) -> decltype(ctx.begin())
+ {
+ auto begin = ctx.begin(), end = ctx.end();
+ if (begin == end)
+ return begin;
+
+ if (*begin != '}')
+ throw std::invalid_argument("invalid type specifier");
+
+ return begin;
+ }
+
+ template <typename FormatContext>
+ auto format(ObjectGuid const& guid, FormatContext& ctx) const -> decltype(ctx.out());
+};
+}
+}
#endif // ObjectGuid_h__
diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp
index 2950b72ce8e..15cb8e3830d 100644
--- a/src/server/game/Server/WorldSession.cpp
+++ b/src/server/game/Server/WorldSession.cpp
@@ -189,15 +189,13 @@ std::string const & WorldSession::GetPlayerName() const
std::string WorldSession::GetPlayerInfo() const
{
- std::ostringstream ss;
-
- ss << "[Player: ";
- if (!m_playerLoading && _player)
- ss << _player->GetName() << ' ' << _player->GetGUID().ToString() << ", ";
+ if (_player)
+ return Trinity::StringFormat("[Player: {} {}, Account: {}]", _player->GetName(), _player->GetGUID(), GetAccountId());
- ss << "Account: " << GetAccountId() << "]";
+ if (m_playerLoading)
+ return Trinity::StringFormat("[Player: Logging in, Account: {}]", GetAccountId());
- return ss.str();
+ return Trinity::StringFormat("[Player: Account: {}]", GetAccountId());
}
/// Get player guid if available. Use for logging purposes only
diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp
index e85636f282d..9e8529f1cb8 100644
--- a/src/server/scripts/Commands/cs_npc.cpp
+++ b/src/server/scripts/Commands/cs_npc.cpp
@@ -1122,7 +1122,7 @@ public:
continue;
ObjectGuid guid = ObjectGuid::Create<HighGuid::Player>(pair.first);
Player const* player = ObjectAccessor::FindConnectedPlayer(guid);
- handler->PSendSysMessage(LANG_COMMAND_NPC_SHOWLOOT_SUBLABEL, player ? player->GetName() : Trinity::StringFormat("Offline player (GuidLow 0x{:08X})", pair.first), pair.second->size());
+ handler->PSendSysMessage(LANG_COMMAND_NPC_SHOWLOOT_SUBLABEL, player ? player->GetName() : Trinity::StringFormat("Offline player ({})", pair.first.ToString()), pair.second->size());
for (auto it = pair.second->cbegin(); it != pair.second->cend(); ++it)
{