Skip to content

Instantly share code, notes, and snippets.

@Shauren
Created August 2, 2017 20:24
Show Gist options
  • Save Shauren/c696b7383d2a39eca6d6a732babc02b0 to your computer and use it in GitHub Desktop.
Save Shauren/c696b7383d2a39eca6d6a732babc02b0 to your computer and use it in GitHub Desktop.
TC named command args
diff --git a/src/common/Utilities/StringFormat.h b/src/common/Utilities/StringFormat.h
index 12eeb2a6d1..f44101224f 100644
--- a/src/common/Utilities/StringFormat.h
+++ b/src/common/Utilities/StringFormat.h
@@ -23,11 +23,51 @@
namespace Trinity
{
+ struct FmtArgWrapper
+ {
+ FmtArgWrapper(char const* name) : Name(name) { }
+
+ virtual std::string ToString() const = 0;
+
+ char const* Name;
+ };
+
+ template<typename T>
+ struct FmtArgWrapperImpl : FmtArgWrapper
+ {
+ FmtArgWrapperImpl(char const* name, T const& value) : FmtArgWrapper(name), Value(value) { }
+
+ std::string ToString() const override
+ {
+ return fmt::format("{}", Value);
+ }
+
+ T const& Value;
+ };
+
+ template<typename T>
+ auto UnwrapArg(FmtArgWrapperImpl<T> const& arg)
+ {
+ return fmt::arg(arg.Name, arg.Value);
+ }
+
+ template<typename T>
+ auto UnwrapArg(T&& arg)
+ {
+ return std::forward<T>(arg);
+ }
+
+ template<typename T>
+ auto FormatArg(char const* name, T const& value)
+ {
+ return FmtArgWrapperImpl<T>(name, value);
+ }
+
/// Default TC string format function.
template<typename Format, typename... Args>
inline std::string StringFormat(Format&& fmt, Args&&... args)
{
- return fmt::sprintf(std::forward<Format>(fmt), std::forward<Args>(args)...);
+ return fmt::sprintf(std::forward<Format>(fmt), UnwrapArg(std::forward<Args>(args))...);
}
/// Returns true if the given char pointer is null.
diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp
index 46c6a26760..7555c7ff68 100644
--- a/src/server/game/Chat/Chat.cpp
+++ b/src/server/game/Chat/Chat.cpp
@@ -209,6 +209,11 @@ void ChatHandler::SendSysMessage(const char *str, bool escapeCharacters)
free(buf);
}
+void ChatHandler::AppendArg(std::ostream& str, Trinity::FmtArgWrapper const& arg) const
+{
+ str << '|' << arg.Name << ":\"" << arg.ToString() << '"';
+}
+
void ChatHandler::SendGlobalSysMessage(const char *str)
{
// Chat output
@@ -1404,3 +1409,16 @@ void AddonChannelCommandHandler::SendSysMessage(char const* str, bool escapeChar
msg.append(body, lastpos, pos - lastpos);
Send(msg);
}
+
+void AddonChannelCommandHandler::SendSysMessage(uint32 entry)
+{
+ if (IsHumanReadable())
+ ChatHandler::SendSysMessage(entry);
+ else
+ SendSysMessage(FormatSeparateMessageArgs(entry).c_str(), true);
+}
+
+void AddonChannelCommandHandler::AppendArg(std::ostream& str, Trinity::FmtArgWrapper const& arg) const
+{
+ str << '\t' << arg.Name << '\t' << boost::replace_all_copy(arg.ToString(), "\t", "\t\t");
+}
diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h
index 8bbcf49c7a..e9f9873b23 100644
--- a/src/server/game/Chat/Chat.h
+++ b/src/server/game/Chat/Chat.h
@@ -23,6 +23,7 @@
#include "ObjectGuid.h"
#include "SharedDefines.h"
#include "StringFormat.h"
+#include <sstream>
#include <vector>
class ChatHandler;
@@ -72,8 +73,7 @@ class TC_GAME_API ChatHandler
// function with different implementation for chat/console
virtual char const* GetTrinityString(uint32 entry) const;
virtual void SendSysMessage(char const* str, bool escapeCharacters = false);
-
- void SendSysMessage(uint32 entry);
+ virtual void SendSysMessage(uint32 entry);
template<typename... Args>
void PSendSysMessage(char const* fmt, Args&&... args)
@@ -84,7 +84,10 @@ class TC_GAME_API ChatHandler
template<typename... Args>
void PSendSysMessage(uint32 entry, Args&&... args)
{
- SendSysMessage(PGetParseString(entry, std::forward<Args>(args)...).c_str());
+ std::string message = IsHumanReadable() ?
+ PGetParseString(entry, std::forward<Args>(args)...) :
+ FormatSeparateMessageArgs(entry, std::forward<Args>(args)...);
+ SendSysMessage(message.c_str());
}
template<typename... Args>
@@ -93,6 +96,48 @@ class TC_GAME_API ChatHandler
return Trinity::StringFormat(GetTrinityString(entry), std::forward<Args>(args)...);
}
+ virtual void AppendArg(std::ostream& str, Trinity::FmtArgWrapper const& arg) const;
+
+ template<typename T>
+ struct AnonymousFmtArg : Trinity::FmtArgWrapperImpl<T>
+ {
+ AnonymousFmtArg(uint32 index, T const& value) : FmtArgWrapperImpl(nullptr, value)
+ {
+ TempName = Trinity::StringFormat("arg%u", index);
+ Name = TempName.c_str();
+ }
+
+ std::string TempName;
+ };
+
+ template<typename T>
+ static auto WrapArgIfNeeded(T const& arg, uint32 index)
+ {
+ return AnonymousFmtArg<T>(index, arg);
+ }
+
+ static Trinity::FmtArgWrapper const& WrapArgIfNeeded(Trinity::FmtArgWrapper const& arg, uint32 /*index*/)
+ {
+ return arg;
+ }
+
+ void AppendArgs(std::ostream& str, uint32 /*index*/) const { str << '|'; }
+ template<typename Arg, typename... Args>
+ void AppendArgs(std::ostream& str, uint32 index, Arg&& arg, Args&&... args) const
+ {
+ AppendArg(str, WrapArgIfNeeded(arg, index));
+ AppendArgs(str, index + 1, std::forward<Args>(args)...);
+ }
+
+ template<typename... Args>
+ std::string FormatSeparateMessageArgs(uint32 entry, Args&&... args) const
+ {
+ std::ostringstream str;
+ str << entry;
+ AppendArgs(str, 0, std::forward<Args>(args)...);
+ return str.str();
+ }
+
bool _ParseCommands(char const* text);
virtual bool ParseCommands(char const* text);
@@ -190,7 +235,8 @@ class TC_GAME_API AddonChannelCommandHandler : public ChatHandler
using ChatHandler::ChatHandler;
bool ParseCommands(char const* str) override;
void SendSysMessage(char const* str, bool escapeCharacters) override;
- using ChatHandler::SendSysMessage;
+ void SendSysMessage(uint32 entry) override;
+ void AppendArg(std::ostream& str, Trinity::FmtArgWrapper const& arg) const override;
bool IsHumanReadable() const override { return humanReadable; }
private:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment