TrinityCore
Loading...
Searching...
No Matches
ChatCommandTags.h
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef TRINITY_CHATCOMMANDTAGS_H
19#define TRINITY_CHATCOMMANDTAGS_H
20
21#include "ChatCommandHelpers.h"
22#include "Hyperlinks.h"
23#include "ObjectGuid.h"
24#include "Optional.h"
25#include "Util.h"
26#include <string>
27#include <string_view>
28#include <tuple>
29#include <type_traits>
30#include <utility>
31#include <variant>
32
33class ChatHandler;
34class Player;
35class WorldSession;
36
38{
43
44 template <typename T>
45 struct tag_base<T, std::enable_if_t<std::is_base_of_v<ContainerTag, T>>>
46 {
47 using type = typename T::value_type;
48 };
49
50 template <std::size_t Size>
52 {
53 constexpr string_literal(char const (&str)[Size])
54 {
55 std::ranges::copy_n(str, Size, value.begin());
56 }
57
58 constexpr operator std::string_view() const
59 {
60 return { value.data(), value.size() - 1 };
61 }
62
63 std::array<char, Size> value;
64 };
65
66 TC_GAME_API ChatCommandResult TryConsumExactSequencee(std::string_view sequence, ChatHandler const* handler, std::string_view args);
67}
68
70{
71 /************************** CONTAINER TAGS **********************************************\
72 |* Simple holder classes to differentiate between extraction methods *|
73 |* Must inherit from Trinity::Impl::ChatCommands::ContainerTag *|
74 |* Must implement the following: *|
75 |* - TryConsume: ChatHandler const*, std::string_view -> ChatCommandResult *|
76 |* - on match, returns tail of the provided argument string (as std::string_view) *|
77 |* - on specific error, returns error message (as std::string&& or char const*) *|
78 |* - on generic error, returns std::nullopt (this will print command usage) *|
79 |* *|
80 |* - typedef value_type of type that is contained within the tag *|
81 |* - cast operator to value_type *|
82 |* *|
83 \****************************************************************************************/
84
85 template <Impl::ChatCommands::string_literal Sequence>
87 {
88 using value_type = void;
89
90 ChatCommandResult TryConsume(ChatHandler const* handler, std::string_view args) const
91 {
92 return Trinity::Impl::ChatCommands::TryConsumExactSequencee(Sequence, handler, args);
93 }
94 };
95
96#define EXACT_SEQUENCE(str) Trinity::ChatCommands::ExactSequence<str>
97
99 {
100 using value_type = std::string_view;
101
102 using std::string_view::operator=;
103
104 ChatCommandResult TryConsume(ChatHandler const*,std::string_view args)
105 {
106 std::string_view::operator=(args);
107 return std::string_view();
108 }
109 };
110
112 {
113 using value_type = std::wstring;
114
115 using std::wstring::operator=;
116
117 ChatCommandResult TryConsume(ChatHandler const* handler, std::string_view args)
118 {
119 if (Utf8toWStr(args, *this))
120 return std::string_view();
121 else
123 }
124 };
125
127 {
128 using value_type = std::string;
129
130 TC_GAME_API ChatCommandResult TryConsume(ChatHandler const* handler, std::string_view args);
131 };
132
134 {
136
137 AccountIdentifier() = default;
139
140 operator uint32() const { return _id; }
141 operator std::string const& () const { return _name; }
142 operator std::string_view() const { return _name; }
143
144 uint32 GetID() const { return _id; }
145 std::string const& GetName() const { return _name; }
146 bool IsConnected() const { return _session != nullptr; }
147 WorldSession* GetConnectedSession() { return _session; }
148
149 ChatCommandResult TryConsume(ChatHandler const* handler, std::string_view args);
150
151 static Optional<AccountIdentifier> FromTarget(ChatHandler* handler);
152
153 private:
154 uint32 _id = 0;
155 std::string _name;
156 WorldSession* _session = nullptr;
157 };
158
160 {
162
163 PlayerIdentifier() = default;
164 PlayerIdentifier(Player& player);
165
166 operator ObjectGuid() const { return _guid; }
167 operator std::string const&() const { return _name; }
168 operator std::string_view() const { return _name; }
169
170 std::string const& GetName() const { return _name; }
171 ObjectGuid GetGUID() const { return _guid; }
172 bool IsConnected() const { return (_player != nullptr); }
173 Player* GetConnectedPlayer() const { return _player; }
174
175 ChatCommandResult TryConsume(ChatHandler const* handler, std::string_view args);
176
177 static Optional<PlayerIdentifier> FromTarget(ChatHandler* handler);
178 static Optional<PlayerIdentifier> FromSelf(ChatHandler* handler);
180 {
181 if (Optional<PlayerIdentifier> fromTarget = FromTarget(handler))
182 return fromTarget;
183 else
184 return FromSelf(handler);
185 }
186
187 private:
188 std::string _name;
190 Player* _player = nullptr;
191 };
192
193 template <typename linktag>
195 {
196 using value_type = typename linktag::value_type;
197 using storage_type = std::remove_cvref_t<value_type>;
198
199 operator value_type() const { return val; }
200 value_type operator*() const { return val; }
201 storage_type const* operator->() const { return &val; }
202
203 ChatCommandResult TryConsume(ChatHandler const* handler, std::string_view args)
204 {
206 // invalid hyperlinks cannot be consumed
207 if (!info)
208 return std::nullopt;
209
210 // check if we got the right tag
211 if (info.tag != linktag::tag())
212 return std::nullopt;
213
214 // store value
215 if (!linktag::StoreTo(val, info.data))
217
218 // finally, skip any potential delimiters
219 auto [token, next] = Trinity::Impl::ChatCommands::tokenize(info.tail);
220 if (token.empty()) /* empty token = first character is delimiter, skip past it */
221 return next;
222 else
223 return info.tail;
224 }
225
226 private:
228 };
229
230 // pull in link tags for user convenience
231 using namespace ::Trinity::Hyperlinks::LinkTags;
232}
233
234namespace Trinity::Impl
235{
236 template <typename T>
238 {
239 template <typename U>
240 T operator()(U const& v) const { return v; }
241 };
242}
243
244namespace Trinity::ChatCommands
245{
246 template <typename T1, typename... Ts>
247 concept HasVariantConversionOperators = !std::same_as<Impl::ChatCommands::tag_base_t<T1>, void>
248 && (std::assignable_from<Impl::ChatCommands::tag_base_t<T1>&, Impl::ChatCommands::tag_base_t<Ts>> && ...);
249
250 template <typename T1, typename... Ts>
251 struct Variant : public std::variant<T1, Ts...>
252 {
253 using base = std::variant<T1, Ts...>;
254
256
258 {
260 }
261
262 operator first_type() const requires (HasVariantConversionOperators<T1, Ts...>)
263 {
264 return operator*();
265 }
266
267 bool operator!() const requires (HasVariantConversionOperators<T1, Ts...>)
268 {
269 return !**this;
270 }
271
272 template <typename T>
273 Variant& operator=(T&& arg) { base::operator=(std::forward<T>(arg)); return *this; }
274
275 template <size_t index>
276 constexpr decltype(auto) get() { return std::get<index>(static_cast<base&>(*this)); }
277 template <size_t index>
278 constexpr decltype(auto) get() const { return std::get<index>(static_cast<base const&>(*this)); }
279 template <typename type>
280 constexpr decltype(auto) get() { return std::get<type>(static_cast<base&>(*this)); }
281 template <typename type>
282 constexpr decltype(auto) get() const { return std::get<type>(static_cast<base const&>(*this)); }
283
284 template <typename T>
285 constexpr decltype(auto) visit(T&& arg) { return std::visit(std::forward<T>(arg), static_cast<base&>(*this)); }
286 template <typename T>
287 constexpr decltype(auto) visit(T&& arg) const { return std::visit(std::forward<T>(arg), static_cast<base const&>(*this)); }
288
289 template <typename T>
290 constexpr bool holds_alternative() const { return std::holds_alternative<T>(static_cast<base const&>(*this)); }
291 };
292}
293
294#endif
#define TC_GAME_API
Definition Define.h:129
uint32_t uint32
Definition Define.h:154
@ LANG_CMDPARSER_LINKDATA_INVALID
Definition Language.h:1011
@ LANG_CMDPARSER_INVALID_UTF8
Definition Language.h:1010
std::optional< T > Optional
Optional helper class to wrap optional values within.
Definition Optional.h:25
bool Utf8toWStr(char const *utf8str, size_t csize, wchar_t *wstr, size_t &wsize)
Definition Util.cpp:336
Player session in the World.
TokenizeResult tokenize(std::string_view args) noexcept
typename tag_base< T >::type tag_base_t
TC_GAME_API ChatCommandResult TryConsumExactSequencee(std::string_view sequence, ChatHandler const *handler, std::string_view args)
TC_GAME_API char const * GetTrinityString(ChatHandler const *handler, TrinityStrings which)
STL namespace.
ChatCommandResult TryConsume(ChatHandler const *handler, std::string_view args) const
std::string const & GetName() const
static Optional< PlayerIdentifier > FromTargetOrSelf(ChatHandler *handler)
TC_GAME_API ChatCommandResult TryConsume(ChatHandler const *handler, std::string_view args)
ChatCommandResult TryConsume(ChatHandler const *, std::string_view args)
constexpr bool holds_alternative() const
constexpr decltype(auto) visit(T &&arg)
constexpr decltype(auto) visit(T &&arg) const
constexpr decltype(auto) get()
std::variant< T1, Ts... > base
Impl::ChatCommands::tag_base_t< T1 > first_type
constexpr decltype(auto) get() const
ChatCommandResult TryConsume(ChatHandler const *handler, std::string_view args)
T operator()(U const &v) const
constexpr string_literal(char const (&str)[Size])