TrinityCore
Loading...
Searching...
No Matches
ChatCommandArgs.cpp
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#include "ChatCommandArgs.h"
19#include "ChatCommand.h"
20#include "DB2Stores.h"
21#include "MapUtils.h"
22#include "ObjectMgr.h"
23#include "SpellMgr.h"
24
25using namespace Trinity::ChatCommands;
27
28void Trinity::Impl::ChatCommands::InvalidStringValueFormatError(ChatCommandResult& result, ChatHandler const* handler, std::string_view arg, std::type_info const& type) noexcept
29{
31}
32
34{
35 std::string_view title(text.Title);
36 std::string_view constant(text.Constant);
37
39
40 auto constantIt = std::ranges::lower_bound(map, constant, compare, Containers::MapKey);
41 if (constantIt == map.end() || compare(constant, constantIt->first))
42 map.emplace(constantIt, constant, val); // not unique
43 else
44 constantIt->second = std::nullopt;
45
46 if (title != constant)
47 {
48 auto titleIt = std::ranges::lower_bound(map, title, compare, Containers::MapKey);
49 if (titleIt == map.end() || compare(title, titleIt->first))
50 map.emplace(titleIt, title, val); // not unique
51 else
52 titleIt->second = std::nullopt;
53 }
54}
55
56int64 const* Trinity::Impl::ChatCommands::EnumArgInfoBase::Match(SearchMap const& map, std::string_view s) noexcept
57{
58 auto it = std::ranges::lower_bound(map, s, StringCompareLessI_T(), Containers::MapKey);
59 auto end = map.end();
60 if (it == end || !StringStartsWithI(it->first, s)) // not a match
61 return nullptr;
62
63 if (!StringEqualI(it->first, s)) // we don't have an exact match - check if it is unique
64 {
65 auto it2 = it;
66 ++it2;
67 if (it2 != end && StringStartsWithI(it2->first, s)) // not unique
68 return nullptr;
69 }
70
71 if (it->second)
72 return &*it->second;
73 else
74 return nullptr;
75}
76
78{
79 if (!current.IsSuccessful())
80 {
81 if (current.HasErrorMessage())
82 {
83 if (combined.HasErrorMessage())
84 {
85 std::string mergedError = std::move(combined).GetErrorMessage();
86 mergedError.append(1, '\n');
87 mergedError.append(GetTrinityString(handler, LANG_CMDPARSER_OR));
88 mergedError.append(1, ' ');
89 mergedError.append(current.GetErrorMessage());
90 combined = std::move(mergedError);
91 }
92 else
93 combined = std::move(current).GetErrorMessage();
94 }
95
96 return false;
97 }
98
99 combined = *current;
100 return true;
101}
102
104{
105 if (combined.HasErrorMessage() && combined.GetErrorMessage().find('\n') != std::string::npos)
106 {
107 std::string error = std::string(GetTrinityString(handler, LANG_CMDPARSER_EITHER))
108 .append(1, ' ')
109 .append(combined.GetErrorMessage());
110 combined = std::move(error);
111 }
112}
113
115{
117 value_type operator()(Hyperlink<achievement> const& achData) const { return achData->Achievement; }
118 value_type operator()(uint32 achId) const { return sAchievementStore.LookupEntry(achId); }
119};
121{
123 ChatCommandResult result = ArgInfo<decltype(val)>::TryConsume(val, handler, args);
124 if (!result || (data = val.visit(AchievementVisitor())))
125 return result;
126 if (uint32* id = std::get_if<uint32>(&val))
128 else
129 result = std::nullopt;
130 return result;
131}
132
134{
136 value_type operator()(Hyperlink<currency> currency) const { return currency->Currency; }
137 value_type operator()(uint32 currencyId) const { return sCurrencyTypesStore.LookupEntry(currencyId); }
138};
140{
142 ChatCommandResult result = ArgInfo<decltype(val)>::TryConsume(val, handler, args);
143 if (!result || (data = val.visit(CurrencyTypesVisitor())))
144 return result;
145 if (uint32* id = std::get_if<uint32>(&val))
147 else
148 result = std::nullopt;
149 return result;
150}
151
153{
154 using value_type = GameTele const*;
155 value_type operator()(Hyperlink<tele> tele) const { return sObjectMgr->GetGameTele(tele); }
156 value_type operator()(std::string_view tele) const { return sObjectMgr->GetGameTele(tele); }
157};
158ChatCommandResult Trinity::Impl::ChatCommands::ArgInfo<GameTele const*>::TryConsume(GameTele const*& data, ChatHandler const* handler, std::string_view args) noexcept
159{
160 Variant<Hyperlink<tele>, std::string_view> val;
161 ChatCommandResult result = ArgInfo<decltype(val)>::TryConsume(val, handler, args);
162 if (!result || (data = val.visit(GameTeleVisitor())))
163 return result;
165 result = FormatTrinityString(handler, LANG_CMDPARSER_GAME_TELE_ID_NO_EXIST, static_cast<uint32>(std::get<Hyperlink<tele>>(val)));
166 else
167 result = FormatTrinityString(handler, LANG_CMDPARSER_GAME_TELE_NO_EXIST, STRING_VIEW_FMT_ARG(std::get<std::string_view>(val)));
168 return result;
169}
170
172{
173 using value_type = ItemTemplate const*;
174 value_type operator()(Hyperlink<item> const& item) const { return item->Item; }
175 value_type operator()(uint32 item) const { return sObjectMgr->GetItemTemplate(item); }
176};
178{
180 ChatCommandResult result = ArgInfo<decltype(val)>::TryConsume(val, handler, args);
181 if (!result || (data = val.visit(ItemTemplateVisitor())))
182 return result;
183 if (uint32* id = std::get_if<uint32>(&val))
185 else
186 result = std::nullopt;
187 return result;
188}
189
191{
192 using value_type = Quest const*;
193 value_type operator()(Hyperlink<quest> quest) const { return quest->Quest; }
194 value_type operator()(uint32 questId) const { return sObjectMgr->GetQuestTemplate(questId); }
195};
196ChatCommandResult Trinity::Impl::ChatCommands::ArgInfo<Quest const*>::TryConsume(Quest const*& data, ChatHandler const* handler, std::string_view args) noexcept
197{
199 ChatCommandResult result = ArgInfo<decltype(val)>::TryConsume(val, handler, args);
200 if (!result || (data = val.visit(QuestVisitor())))
201 return result;
202 if (uint32* id = std::get_if<uint32>(&val))
204 else
205 result = std::nullopt;
206 return result;
207}
208
210{
211 using value_type = SpellInfo const*;
212
213 value_type operator()(Hyperlink<apower> artifactPower) const { return operator()(artifactPower->ArtifactPower->SpellID); }
214 value_type operator()(Hyperlink<conduit> soulbindConduit) const { return operator()((*soulbindConduit)->SpellID); }
215 value_type operator()(Hyperlink<enchant> enchant) const { return enchant; }
216 value_type operator()(Hyperlink<mawpower> mawPower) const { return operator()((*mawPower)->SpellID); }
217 value_type operator()(Hyperlink<mount> const& mount) const { return mount->Spell; }
218 value_type operator()(Hyperlink<pvptal> pvpTalent) const { return operator()((*pvpTalent)->SpellID); }
219 value_type operator()(Hyperlink<spell> spell) const { return spell->Spell; }
220 value_type operator()(Hyperlink<talent> talent) const { return operator()((*talent)->SpellID); }
221 value_type operator()(Hyperlink<trade> const& trade) const { return trade->Spell; }
222
223 value_type operator()(uint32 spellId) const { return sSpellMgr->GetSpellInfo(spellId, DIFFICULTY_NONE); }
224};
225ChatCommandResult Trinity::Impl::ChatCommands::ArgInfo<SpellInfo const*>::TryConsume(SpellInfo const*& data, ChatHandler const* handler, std::string_view args) noexcept
226{
228 ChatCommandResult result = ArgInfo<decltype(val)>::TryConsume(val, handler, args);
229 if (!result || (data = val.visit(SpellInfoVisitor())))
230 return result;
231 if (uint32* id = std::get_if<uint32>(&val))
233 else
234 result = std::nullopt;
235 return result;
236}
DB2Storage< AchievementEntry > sAchievementStore("Achievement.db2", &AchievementLoadInfo::Instance)
DB2Storage< CurrencyTypesEntry > sCurrencyTypesStore("CurrencyTypes.db2", &CurrencyTypesLoadInfo::Instance)
@ DIFFICULTY_NONE
Definition DBCEnums.h:933
#define STRING_VIEW_FMT_ARG(str)
Definition Define.h:147
int64_t int64
Definition Define.h:149
uint32_t uint32
Definition Define.h:154
@ LANG_CMDPARSER_ITEM_NO_EXIST
Definition Language.h:1020
@ LANG_CMDPARSER_GAME_TELE_ID_NO_EXIST
Definition Language.h:1018
@ LANG_CMDPARSER_STRING_VALUE_INVALID
Definition Language.h:1009
@ LANG_CMDPARSER_EITHER
Definition Language.h:1007
@ LANG_CMDPARSER_OR
Definition Language.h:1008
@ LANG_CMDPARSER_ACHIEVEMENT_NO_EXIST
Definition Language.h:1017
@ LANG_CMDPARSER_GAME_TELE_NO_EXIST
Definition Language.h:1019
@ LANG_CMDPARSER_QUEST_NO_EXIST
Definition Language.h:1024
@ LANG_CMDPARSER_CURRENCY_NO_EXIST
Definition Language.h:1023
@ LANG_CMDPARSER_SPELL_NO_EXIST
Definition Language.h:1021
#define sObjectMgr
Definition ObjectMgr.h:1885
#define sSpellMgr
Definition SpellMgr.h:812
TC_COMMON_API bool StringEqualI(std::string_view str1, std::string_view str2)
Definition Util.cpp:849
bool StringStartsWithI(std::string_view haystack, std::string_view needle)
Definition Util.h:462
TC_GAME_API bool HandleVariantChatCommandConsumeResults(ChatCommandResult &combined, ChatCommandResult &&current, ChatHandler const *handler) noexcept
TC_GAME_API char const * GetTrinityString(ChatHandler const *handler, TrinityStrings which)
TC_GAME_API void PrefixVariantChatCommandError(ChatCommandResult &combined, ChatHandler const *handler) noexcept
TC_GAME_API std::string FormatTrinityString(std::string_view messageFormat, fmt::printf_args messageFormatArgs)
TC_GAME_API void InvalidStringValueFormatError(ChatCommandResult &result, ChatHandler const *handler, std::string_view arg, std::type_info const &type) noexcept
std::string GetTypeName()
Definition Util.h:588
value_type operator()(Hyperlink< achievement > const &achData) const
value_type operator()(uint32 achId) const
AchievementEntry const * value_type
value_type operator()(Hyperlink< currency > currency) const
value_type operator()(uint32 currencyId) const
CurrencyTypesEntry const * value_type
value_type operator()(std::string_view tele) const
value_type operator()(Hyperlink< tele > tele) const
GameTele const * value_type
value_type operator()(uint32 item) const
ItemTemplate const * value_type
value_type operator()(Hyperlink< item > const &item) const
value_type operator()(Hyperlink< quest > quest) const
value_type operator()(uint32 questId) const
Quest const * value_type
value_type operator()(Hyperlink< pvptal > pvpTalent) const
value_type operator()(uint32 spellId) const
value_type operator()(Hyperlink< enchant > enchant) const
value_type operator()(Hyperlink< trade > const &trade) const
value_type operator()(Hyperlink< mawpower > mawPower) const
SpellInfo const * value_type
value_type operator()(Hyperlink< conduit > soulbindConduit) const
value_type operator()(Hyperlink< spell > spell) const
value_type operator()(Hyperlink< apower > artifactPower) const
value_type operator()(Hyperlink< mount > const &mount) const
value_type operator()(Hyperlink< talent > talent) const
constexpr bool holds_alternative() const
constexpr decltype(auto) visit(T &&arg)
static void AddSearchMapEntry(SearchMap &map, int64 val, EnumText const &text) noexcept
static int64 const * Match(SearchMap const &map, std::string_view s) noexcept
std::vector< std::pair< std::string_view, Optional< int64 > > > SearchMap