TrinityCore
Hyperlinks.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 "Hyperlinks.h"
19#include "Common.h"
20#include "DB2Stores.h"
21#include "Errors.h"
22#include "ItemTemplate.h"
23#include "ObjectMgr.h"
24#include "QuestDef.h"
25#include "SharedDefines.h"
26#include "SpellInfo.h"
27#include "SpellMgr.h"
28#include "StringFormat.h"
29#include "World.h"
30
31using namespace Trinity::Hyperlinks;
32
33inline uint8 toHex(char c) { return (c >= '0' && c <= '9') ? c - '0' + 0x10 : (c >= 'a' && c <= 'f') ? c - 'a' + 0x1a : 0x00; }
34// Validates a single hyperlink
36{
37 uint32 color = 0;
38 std::string_view tag;
39 std::string_view data;
40 std::string_view text;
41
42 //color tag
43 if (str.substr(0, 2) != "|c")
44 return {};
45 str.remove_prefix(2);
46
47 if (str.length() < 8)
48 return {};
49
50 for (uint8 i = 0; i < 8; ++i)
51 {
52 if (uint8 hex = toHex(str[i]))
53 color = (color << 4) | (hex & 0xf);
54 else
55 return {};
56 }
57 str.remove_prefix(8);
58
59 if (str.substr(0, 2) != "|H")
60 return {};
61 str.remove_prefix(2);
62
63 // tag+data part follows
64 if (size_t delimPos = str.find('|'); delimPos != std::string_view::npos)
65 {
66 tag = str.substr(0, delimPos);
67 str.remove_prefix(delimPos+1);
68 }
69 else
70 return {};
71
72 // split tag if : is present (data separator)
73 if (size_t dataStart = tag.find(':'); dataStart != std::string_view::npos)
74 {
75 data = tag.substr(dataStart+1);
76 tag = tag.substr(0, dataStart);
77 }
78
79 // ok, next should be link data end tag...
80 if (str.substr(0, 1) != "h")
81 return {};
82 str.remove_prefix(1);
83 // skip to final |
84 if (size_t end = str.find('|'); end != std::string_view::npos)
85 {
86 // check end tag
87 if (str.substr(end, 4) != "|h|r")
88 return {};
89 // check text brackets
90 if ((str[0] != '[') || (str[end - 1] != ']'))
91 return {};
92 text = str.substr(1, end - 2);
93 // tail
94 str = str.substr(end + 4);
95 }
96 else
97 return {};
98
99 // ok, valid hyperlink, return info
100 return { str, color, tag, data, text };
101}
102
103template <typename T>
105{
106 static bool IsTextValid(typename T::value_type, std::string_view) { return true; }
107 static bool IsColorValid(typename T::value_type, HyperlinkColor) { return true; }
108};
109
110static bool IsCreatureNameValid(uint32 creatureId, std::string_view text)
111{
112 if (CreatureTemplate const* creatureTemplate = sObjectMgr->GetCreatureTemplate(creatureId))
113 {
114 CreatureLocale const* locale = sObjectMgr->GetCreatureLocale(creatureId);
115 if (!locale)
116 return creatureTemplate->Name == text;
117
118 for (uint8 i = 0; i < TOTAL_LOCALES; ++i)
119 {
120 std::string const& name = (i == DEFAULT_LOCALE) ? creatureTemplate->Name : locale->Name[i];
121 if (name.empty())
122 continue;
123 if (name == text)
124 return true;
125 }
126 }
127
128 return false;
129}
130
131template <>
132struct LinkValidator<LinkTags::spell>
133{
134 static bool IsTextValid(SpellLinkData const& data, std::string_view text)
135 {
136 return IsTextValid(data.Spell, text);
137 }
138
139 static bool IsTextValid(SpellInfo const* info, std::string_view text)
140 {
141 for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1))
142 if ((*info->SpellName)[i] == text)
143 return true;
144 return false;
145 }
146
148 {
149 return c == CHAT_LINK_COLOR_SPELL;
150 }
151};
152
153template <>
154struct LinkValidator<LinkTags::achievement>
155{
156 static bool IsTextValid(AchievementLinkData const& data, std::string_view text)
157 {
158 if (text.empty())
159 return false;
160 for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1))
161 if (text == data.Achievement->Title[i])
162 return true;
163 return false;
164 }
165
167 {
168 return c == CHAT_LINK_COLOR_ACHIEVEMENT;
169 }
170};
171
172template <>
173struct LinkValidator<LinkTags::apower>
174{
175 static bool IsTextValid(ArtifactPowerLinkData const& data, std::string_view text)
176 {
177 if (SpellInfo const* info = sSpellMgr->GetSpellInfo(data.ArtifactPower->SpellID, DIFFICULTY_NONE))
179 return false;
180 }
181
183 {
185 }
186};
187
188template <>
189struct LinkValidator<LinkTags::azessence>
190{
191 static bool IsTextValid(AzeriteEssenceLinkData const& data, std::string_view text)
192 {
193 for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1))
194 if (data.Essence->Name[i] == text)
195 return true;
196 return false;
197 }
198
200 {
201 return c == ItemQualityColors[data.Rank + 1];
202 }
203};
204
205template <>
206struct LinkValidator<LinkTags::battlepet>
207{
208 static bool IsTextValid(BattlePetLinkData const& data, std::string_view text)
209 {
210 return IsCreatureNameValid(data.Species->CreatureID, text);
211 }
212
214 {
215 return c == ItemQualityColors[data.Quality];
216 }
217};
218
219template <>
220struct LinkValidator<LinkTags::battlePetAbil>
221{
222 static bool IsTextValid(BattlePetAbilLinkData const& data, std::string_view text)
223 {
224 for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1))
225 if (data.Ability->Name[i] == text)
226 return true;
227 return false;
228 }
229
231 {
233 }
234};
235
236template <>
237struct LinkValidator<LinkTags::conduit>
238{
239 static bool IsTextValid(SoulbindConduitRankEntry const* rank, std::string_view text)
240 {
241 if (SpellInfo const* info = sSpellMgr->GetSpellInfo(rank->SpellID, DIFFICULTY_NONE))
243 return false;
244 }
245
247 {
248 return c == CHAT_LINK_COLOR_SPELL;
249 }
250};
251
252template <>
253struct LinkValidator<LinkTags::currency>
254{
255 static bool IsTextValid(CurrencyLinkData const& data, std::string_view text)
256 {
257 LocalizedString const* name = data.Container ? &data.Container->ContainerName : &data.Currency->Name;
258 for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1))
259 if ((*name)[i] == text)
260 return true;
261 return false;
262 }
263
264 static bool IsColorValid(CurrencyLinkData const& data, HyperlinkColor c)
265 {
266 return c == ItemQualityColors[(data.Container ? data.Container->ContainerQuality : data.Currency->Quality)];
267 }
268};
269
270template <>
271struct LinkValidator<LinkTags::enchant>
272{
273 static bool IsTextValid(SpellInfo const* info, std::string_view text)
274 {
276 return true;
277 SkillLineAbilityMapBounds bounds = sSpellMgr->GetSkillLineAbilityMapBounds(info->Id);
278 if (bounds.first == bounds.second)
279 return false;
280
281 for (auto pair = bounds.first; pair != bounds.second; ++pair)
282 {
283 SkillLineEntry const* skill = sSkillLineStore.LookupEntry(pair->second->SkillupSkillLineID
284 ? pair->second->SkillupSkillLineID
285 : pair->second->SkillLine);
286 if (!skill)
287 return false;
288
289 for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1))
290 {
291 std::string_view skillName = skill->DisplayName[i];
292 std::string_view spellName = (*info->SpellName)[i];
293 if ((text.length() == (skillName.length() + 2 + spellName.length())) &&
294 (text.substr(0, skillName.length()) == skillName) &&
295 (text.substr(skillName.length(), 2) == ": ") &&
296 (text.substr(skillName.length() + 2) == spellName))
297 return true;
298 }
299 }
300 return false;
301 }
302
303 static bool IsColorValid(SpellInfo const*, HyperlinkColor c)
304 {
305 return c == CHAT_LINK_COLOR_ENCHANT;
306 }
307};
308
309template <>
310struct LinkValidator<LinkTags::garrfollower>
311{
312 static bool IsTextValid(GarrisonFollowerLinkData const& data, std::string_view text)
313 {
316 }
317
319 {
320 return c == ItemQualityColors[data.Quality];
321 }
322};
323
324template <>
325struct LinkValidator<LinkTags::garrfollowerability>
326{
327 static bool IsTextValid(GarrAbilityEntry const* ability, std::string_view text)
328 {
329 for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1))
330 if (ability->Name[i] == text)
331 return true;
332 return false;
333 }
334
336 {
338 }
339};
340
341template <>
342struct LinkValidator<LinkTags::garrmission>
343{
344 static bool IsTextValid(GarrisonMissionLinkData const& data, std::string_view text)
345 {
346 for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1))
347 if (data.Mission->Name[i] == text)
348 return true;
349 return false;
350 }
351
353 {
354 return c == QuestDifficultyColors[2];
355 }
356};
357
358template <>
359struct LinkValidator<LinkTags::instancelock>
360{
361 static bool IsTextValid(InstanceLockLinkData const& data, std::string_view text)
362 {
363 for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1))
364 if (data.Map->MapName[i] == text)
365 return true;
366 return false;
367 }
368
370 {
372 }
373};
374
375template <>
376struct LinkValidator<LinkTags::item>
377{
378 static bool IsTextValid(ItemLinkData const& data, std::string_view text)
379 {
380 LocalizedString const* suffixStrings = nullptr;
382 suffixStrings = &data.Suffix->Description;
383
384 return IsTextValid(data.Item, suffixStrings, text);
385 }
386
387 static bool IsTextValid(ItemTemplate const* itemTemplate, LocalizedString const* suffixStrings, std::string_view text)
388 {
389 for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1))
390 {
391 std::string_view name = itemTemplate->GetName(i);
392 if (name.empty())
393 continue;
394 if (suffixStrings)
395 {
396 std::string_view suffix = (*suffixStrings)[i];
397 if (
398 (!suffix.empty()) &&
399 (text.length() == (name.length() + 1 + suffix.length())) &&
400 (text.substr(0, name.length()) == name) &&
401 (text[name.length()] == ' ') &&
402 (text.substr(name.length() + 1) == suffix)
403 )
404 return true;
405 }
406 else if (text == name)
407 return true;
408 }
409 return false;
410 }
411
412 static bool IsColorValid(ItemLinkData const& data, HyperlinkColor c)
413 {
414 return c == ItemQualityColors[data.Quality];
415 }
416};
417
418template <>
419struct LinkValidator<LinkTags::journal>
420{
421 static bool IsTextValid(JournalLinkData const& data, std::string_view text)
422 {
423 for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1))
424 if ((*data.ExpectedText)[i] == text)
425 return true;
426 return false;
427 }
428
430 {
431 return c == CHAT_LINK_COLOR_JOURNAL;
432 }
433};
434
435template <>
436struct LinkValidator<LinkTags::keystone>
437{
438 static bool IsTextValid(KeystoneLinkData const& data, std::string_view text)
439 {
440 // Skip "Keystone" prefix - not loading GlobalStrings.db2
441 size_t validateStartPos = text.find(": ");
442 if (validateStartPos == std::string_view::npos)
443 return false;
444
445 text.remove_prefix(validateStartPos);
446 text.remove_prefix(2); // skip ": " too
447
448 for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1))
449 {
450 std::string expectedText = Trinity::StringFormat("{} ({})", data.Map->Name[i], data.Level);
451 if (expectedText == text)
452 return true;
453 }
454 return false;
455 }
456
458 {
460 }
461};
462
463template <>
464struct LinkValidator<LinkTags::quest>
465{
466 static bool IsTextValid(QuestLinkData const& data, std::string_view text)
467 {
468 if (text.empty())
469 return false;
470
471 if (text == data.Quest->GetLogTitle())
472 return true;
473
474 QuestTemplateLocale const* locale = sObjectMgr->GetQuestLocale(data.Quest->GetQuestId());
475 if (!locale)
476 return false;
477
478 for (uint8 i = 0; i < TOTAL_LOCALES; ++i)
479 {
480 if (i == DEFAULT_LOCALE)
481 continue;
482
483 std::string_view name = ObjectMgr::GetLocaleString(locale->LogTitle, LocaleConstant(i));
484 if (!name.empty() && (text == name))
485 return true;
486 }
487
488 return false;
489 }
490
492 {
493 for (uint8 i = 0; i < MAX_QUEST_DIFFICULTY; ++i)
494 if (c == QuestDifficultyColors[i])
495 return true;
496 return false;
497 }
498};
499
500template <>
501struct LinkValidator<LinkTags::mawpower>
502{
503 static bool IsTextValid(MawPowerEntry const* mawPower, std::string_view text)
504 {
505 if (SpellInfo const* info = sSpellMgr->GetSpellInfo(mawPower->SpellID, DIFFICULTY_NONE))
507 return false;
508 }
509
511 {
512 return c == CHAT_LINK_COLOR_SPELL;
513 }
514};
515
516template <>
517struct LinkValidator<LinkTags::mount>
518{
519 static bool IsTextValid(MountLinkData const& data, std::string_view text)
520 {
522 }
523
525 {
526 return c == CHAT_LINK_COLOR_SPELL;
527 }
528};
529
530template <>
531struct LinkValidator<LinkTags::outfit>
532{
533 static bool IsTextValid(std::string_view, std::string_view)
534 {
535 return true;
536 }
537
538 static bool IsColorValid(std::string_view, HyperlinkColor c)
539 {
540 return c == CHAT_LINK_COLOR_TRANSMOG;
541 }
542};
543
544template <>
545struct LinkValidator<LinkTags::pvptal>
546{
547 static bool IsTextValid(PvpTalentEntry const* pvpTalent, std::string_view text)
548 {
549 if (SpellInfo const* info = sSpellMgr->GetSpellInfo(pvpTalent->SpellID, DIFFICULTY_NONE))
551 return false;
552 }
553
555 {
556 return c == CHAT_LINK_COLOR_TALENT;
557 }
558};
559
560template <>
561struct LinkValidator<LinkTags::talent>
562{
563 static bool IsTextValid(TalentEntry const* talent, std::string_view text)
564 {
565 if (SpellInfo const* info = sSpellMgr->GetSpellInfo(talent->SpellID, DIFFICULTY_NONE))
567 return false;
568 }
569
571 {
572 return c == CHAT_LINK_COLOR_TALENT;
573 }
574};
575
576template <>
577struct LinkValidator<LinkTags::trade>
578{
579 static bool IsTextValid(TradeskillLinkData const& data, std::string_view text)
580 {
582 }
583
585 {
586 return c == CHAT_LINK_COLOR_TRADE;
587 }
588};
589
590template <>
591struct LinkValidator<LinkTags::transmogappearance>
592{
593 static bool IsTextValid(ItemModifiedAppearanceEntry const* enchantment, std::string_view text)
594 {
595 if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(enchantment->ItemID))
596 return LinkValidator<LinkTags::item>::IsTextValid(itemTemplate, nullptr, text);
597 return false;
598 }
599
601 {
602 return c == CHAT_LINK_COLOR_TRANSMOG;
603 }
604};
605
606template <>
607struct LinkValidator<LinkTags::transmogillusion>
608{
609 static bool IsTextValid(SpellItemEnchantmentEntry const* enchantment, std::string_view text)
610 {
611 for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1))
612 if (enchantment->Name[i] == text)
613 return true;
614 for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1))
615 if (enchantment->HordeName[i] == text)
616 return true;
617 return false;
618 }
619
621 {
622 return c == CHAT_LINK_COLOR_TRANSMOG;
623 }
624};
625
626template <>
627struct LinkValidator<LinkTags::transmogset>
628{
629 static bool IsTextValid(TransmogSetEntry const* set, std::string_view text)
630 {
631 for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1))
632 {
633 if (ItemNameDescriptionEntry const* itemNameDescription = sItemNameDescriptionStore.LookupEntry(set->ItemNameDescriptionID))
634 {
635 std::string expectedText = Trinity::StringFormat("{} ({})", set->Name[i], itemNameDescription->Description[i]);
636 if (expectedText.c_str() == text)
637 return true;
638 }
639 else if (set->Name[i] == text)
640 return true;
641 }
642 return false;
643 }
644
646 {
647 return c == CHAT_LINK_COLOR_TRANSMOG;
648 }
649};
650
651template <>
652struct LinkValidator<LinkTags::worldmap>
653{
654 static bool IsTextValid(WorldMapLinkData const&, std::string_view)
655 {
656 return true;
657 }
658
660 {
661 return c == CHAT_LINK_COLOR_ACHIEVEMENT;
662 }
663};
664
665template <typename TAG>
666static bool ValidateAs(HyperlinkInfo const& info)
667{
668 std::decay_t<typename TAG::value_type> t;
669 if (!TAG::StoreTo(t, info.data))
670 return false;
671
672 int32 const severity = static_cast<int32>(sWorld->getIntConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_SEVERITY));
673 if (severity >= 0)
674 {
676 return false;
677 if (severity >= 1)
678 {
680 return false;
681 }
682 }
683 return true;
684}
685
686#define TryValidateAs(T) do { if (info.tag == T::tag()) return ValidateAs<T>(info); } while (0)
687
688static bool ValidateLinkInfo(HyperlinkInfo const& info)
689{
690 using namespace LinkTags;
691 TryValidateAs(achievement);
692 TryValidateAs(api);
693 TryValidateAs(apower);
694 TryValidateAs(azessence);
695 TryValidateAs(area);
696 TryValidateAs(areatrigger);
697 TryValidateAs(battlepet);
698 TryValidateAs(battlePetAbil);
699 TryValidateAs(clubFinder);
700 TryValidateAs(clubTicket);
701 TryValidateAs(conduit);
702 TryValidateAs(creature);
703 TryValidateAs(creature_entry);
704 TryValidateAs(currency);
705 TryValidateAs(dungeonScore);
706 TryValidateAs(enchant);
707 TryValidateAs(gameevent);
708 TryValidateAs(gameobject);
709 TryValidateAs(gameobject_entry);
710 TryValidateAs(garrfollower);
711 TryValidateAs(garrfollowerability);
712 TryValidateAs(garrmission);
713 TryValidateAs(instancelock);
714 TryValidateAs(item);
715 TryValidateAs(itemset);
716 TryValidateAs(journal);
717 TryValidateAs(keystone);
718 TryValidateAs(mawpower);
719 TryValidateAs(mount);
720 TryValidateAs(outfit);
721 TryValidateAs(player);
722 TryValidateAs(pvptal);
723 TryValidateAs(quest);
724 TryValidateAs(skill);
725 TryValidateAs(spell);
726 TryValidateAs(talent);
727 TryValidateAs(talentbuild);
728 TryValidateAs(taxinode);
729 TryValidateAs(tele);
730 TryValidateAs(title);
731 TryValidateAs(trade);
732 TryValidateAs(transmogappearance);
733 TryValidateAs(transmogillusion);
734 TryValidateAs(transmogset);
735 TryValidateAs(worldmap);
736 return false;
737}
738
739// Validates all hyperlinks and control sequences contained in str
740bool Trinity::Hyperlinks::CheckAllLinks(std::string_view str)
741{
742 // Step 1: Disallow all control sequences except ||, |H, |h, |c and |r
743 {
744 std::string_view::size_type pos = 0;
745 while ((pos = str.find('|', pos)) != std::string::npos)
746 {
747 ++pos;
748 if (pos == str.length())
749 return false;
750 char next = str[pos];
751 if (next == 'H' || next == 'h' || next == 'c' || next == 'r' || next == '|')
752 ++pos;
753 else
754 return false;
755 }
756 }
757
758 // Step 2: Parse all link sequences
759 // They look like this: |c<color>|H<linktag>:<linkdata>|h[<linktext>]|h|r
760 // - <color> is 8 hex characters AARRGGBB
761 // - <linktag> is arbitrary length [a-z_]
762 // - <linkdata> is arbitrary length, no | contained
763 // - <linktext> is printable
764 {
765 std::string::size_type pos;
766 while ((pos = str.find('|')) != std::string::npos)
767 {
768 if (str[pos + 1] == '|') // this is an escaped pipe character (||)
769 {
770 str = str.substr(pos + 2);
771 continue;
772 }
773
774 HyperlinkInfo info = ParseSingleHyperlink(str.substr(pos));
775 if (!info || !ValidateLinkInfo(info))
776 return false;
777
778 // tag is fine, find the next one
779 str = info.tail;
780 }
781 }
782
783 // all tags are valid
784 return true;
785}
LocaleConstant
Definition: Common.h:48
@ TOTAL_LOCALES
Definition: Common.h:62
@ LOCALE_enUS
Definition: Common.h:49
#define DEFAULT_LOCALE
Definition: Common.h:66
DB2Storage< ItemNameDescriptionEntry > sItemNameDescriptionStore("ItemNameDescription.db2", &ItemNameDescriptionLoadInfo::Instance)
DB2Storage< SkillLineEntry > sSkillLineStore("SkillLine.db2", &SkillLineLoadInfo::Instance)
@ DIFFICULTY_NONE
Definition: DBCEnums.h:874
uint8_t uint8
Definition: Define.h:144
int32_t int32
Definition: Define.h:138
uint32_t uint32
Definition: Define.h:142
@ ITEM_FLAG3_HIDE_NAME_SUFFIX
Definition: ItemTemplate.h:264
#define sObjectMgr
Definition: ObjectMgr.h:1946
if(posix_memalign(&__mallocedMemory, __align, __size)) return NULL
uint32 constexpr ItemQualityColors[MAX_ITEM_QUALITY]
@ CHAT_LINK_COLOR_TRADE
@ CHAT_LINK_COLOR_JOURNAL
@ CHAT_LINK_COLOR_TRANSMOG
@ CHAT_LINK_COLOR_SPELL
@ CHAT_LINK_COLOR_ACHIEVEMENT
@ CHAT_LINK_COLOR_ARTIFACT_POWER
@ CHAT_LINK_COLOR_GARR_ABILITY
@ CHAT_LINK_COLOR_TALENT
@ CHAT_LINK_COLOR_BATTLE_PET_ABIL
@ CHAT_LINK_COLOR_INSTANCE_LOCK
@ CHAT_LINK_COLOR_ENCHANT
uint32 constexpr QuestDifficultyColors[MAX_QUEST_DIFFICULTY]
@ ITEM_QUALITY_EPIC
size_t constexpr MAX_QUEST_DIFFICULTY
#define sSpellMgr
Definition: SpellMgr.h:849
std::pair< SkillLineAbilityMap::const_iterator, SkillLineAbilityMap::const_iterator > SkillLineAbilityMapBounds
Definition: SpellMgr.h:621
static std::string_view GetLocaleString(std::vector< std::string > const &data, LocaleConstant locale)
Definition: ObjectMgr.h:1682
std::string const & GetLogTitle() const
Definition: QuestDef.h:616
uint32 GetQuestId() const
Definition: QuestDef.h:587
uint32 const Id
Definition: SpellInfo.h:325
LocalizedString const * SpellName
Definition: SpellInfo.h:403
#define sWorld
Definition: World.h:931
@ CONFIG_CHAT_STRICT_LINK_CHECKING_SEVERITY
Definition: World.h:319
std::string StringFormat(FormatString< Args... > fmt, Args &&... args)
Default TC string format function.
Definition: StringFormat.h:38
LocalizedString Title
Definition: DB2Structure.h:31
LocalizedString Name
Definition: DB2Structure.h:327
LocalizedString Name
Definition: DB2Structure.h:447
std::vector< std::string > Name
Definition: CreatureData.h:569
LocalizedString ContainerName
LocalizedString Name
LocalizedString Name
LocalizedString Name
LocalizedString Description
bool HasFlag(ItemFlags flag) const
Definition: ItemTemplate.h:871
char const * GetName(LocaleConstant locale) const
static bool IsColorValid(AchievementLinkData const &, HyperlinkColor c)
Definition: Hyperlinks.cpp:166
static bool IsTextValid(AchievementLinkData const &data, std::string_view text)
Definition: Hyperlinks.cpp:156
static bool IsColorValid(ArtifactPowerLinkData const &, HyperlinkColor c)
Definition: Hyperlinks.cpp:182
static bool IsTextValid(ArtifactPowerLinkData const &data, std::string_view text)
Definition: Hyperlinks.cpp:175
static bool IsTextValid(AzeriteEssenceLinkData const &data, std::string_view text)
Definition: Hyperlinks.cpp:191
static bool IsColorValid(AzeriteEssenceLinkData const &data, HyperlinkColor c)
Definition: Hyperlinks.cpp:199
static bool IsColorValid(BattlePetAbilLinkData const &, HyperlinkColor c)
Definition: Hyperlinks.cpp:230
static bool IsTextValid(BattlePetAbilLinkData const &data, std::string_view text)
Definition: Hyperlinks.cpp:222
static bool IsTextValid(BattlePetLinkData const &data, std::string_view text)
Definition: Hyperlinks.cpp:208
static bool IsColorValid(BattlePetLinkData const &data, HyperlinkColor c)
Definition: Hyperlinks.cpp:213
static bool IsTextValid(SoulbindConduitRankEntry const *rank, std::string_view text)
Definition: Hyperlinks.cpp:239
static bool IsColorValid(SoulbindConduitRankEntry const *, HyperlinkColor c)
Definition: Hyperlinks.cpp:246
static bool IsTextValid(CurrencyLinkData const &data, std::string_view text)
Definition: Hyperlinks.cpp:255
static bool IsColorValid(CurrencyLinkData const &data, HyperlinkColor c)
Definition: Hyperlinks.cpp:264
static bool IsTextValid(SpellInfo const *info, std::string_view text)
Definition: Hyperlinks.cpp:273
static bool IsColorValid(SpellInfo const *, HyperlinkColor c)
Definition: Hyperlinks.cpp:303
static bool IsColorValid(GarrisonFollowerLinkData const &data, HyperlinkColor c)
Definition: Hyperlinks.cpp:318
static bool IsTextValid(GarrisonFollowerLinkData const &data, std::string_view text)
Definition: Hyperlinks.cpp:312
static bool IsTextValid(GarrAbilityEntry const *ability, std::string_view text)
Definition: Hyperlinks.cpp:327
static bool IsColorValid(GarrAbilityEntry const *, HyperlinkColor c)
Definition: Hyperlinks.cpp:335
static bool IsColorValid(GarrisonMissionLinkData const &, HyperlinkColor c)
Definition: Hyperlinks.cpp:352
static bool IsTextValid(GarrisonMissionLinkData const &data, std::string_view text)
Definition: Hyperlinks.cpp:344
static bool IsTextValid(InstanceLockLinkData const &data, std::string_view text)
Definition: Hyperlinks.cpp:361
static bool IsColorValid(InstanceLockLinkData const &, HyperlinkColor c)
Definition: Hyperlinks.cpp:369
static bool IsColorValid(ItemLinkData const &data, HyperlinkColor c)
Definition: Hyperlinks.cpp:412
static bool IsTextValid(ItemTemplate const *itemTemplate, LocalizedString const *suffixStrings, std::string_view text)
Definition: Hyperlinks.cpp:387
static bool IsTextValid(ItemLinkData const &data, std::string_view text)
Definition: Hyperlinks.cpp:378
static bool IsTextValid(JournalLinkData const &data, std::string_view text)
Definition: Hyperlinks.cpp:421
static bool IsColorValid(JournalLinkData const &, HyperlinkColor c)
Definition: Hyperlinks.cpp:429
static bool IsTextValid(KeystoneLinkData const &data, std::string_view text)
Definition: Hyperlinks.cpp:438
static bool IsColorValid(KeystoneLinkData const &, HyperlinkColor c)
Definition: Hyperlinks.cpp:457
static bool IsColorValid(MawPowerEntry const *, HyperlinkColor c)
Definition: Hyperlinks.cpp:510
static bool IsTextValid(MawPowerEntry const *mawPower, std::string_view text)
Definition: Hyperlinks.cpp:503
static bool IsColorValid(MountLinkData const &, HyperlinkColor c)
Definition: Hyperlinks.cpp:524
static bool IsTextValid(MountLinkData const &data, std::string_view text)
Definition: Hyperlinks.cpp:519
static bool IsColorValid(std::string_view, HyperlinkColor c)
Definition: Hyperlinks.cpp:538
static bool IsTextValid(std::string_view, std::string_view)
Definition: Hyperlinks.cpp:533
static bool IsTextValid(PvpTalentEntry const *pvpTalent, std::string_view text)
Definition: Hyperlinks.cpp:547
static bool IsColorValid(PvpTalentEntry const *, HyperlinkColor c)
Definition: Hyperlinks.cpp:554
static bool IsColorValid(QuestLinkData const &, HyperlinkColor c)
Definition: Hyperlinks.cpp:491
static bool IsTextValid(QuestLinkData const &data, std::string_view text)
Definition: Hyperlinks.cpp:466
static bool IsTextValid(SpellLinkData const &data, std::string_view text)
Definition: Hyperlinks.cpp:134
static bool IsTextValid(SpellInfo const *info, std::string_view text)
Definition: Hyperlinks.cpp:139
static bool IsColorValid(SpellLinkData const &, HyperlinkColor c)
Definition: Hyperlinks.cpp:147
static bool IsColorValid(TalentEntry const *, HyperlinkColor c)
Definition: Hyperlinks.cpp:570
static bool IsTextValid(TalentEntry const *talent, std::string_view text)
Definition: Hyperlinks.cpp:563
static bool IsColorValid(TradeskillLinkData const &, HyperlinkColor c)
Definition: Hyperlinks.cpp:584
static bool IsTextValid(TradeskillLinkData const &data, std::string_view text)
Definition: Hyperlinks.cpp:579
static bool IsColorValid(ItemModifiedAppearanceEntry const *, HyperlinkColor c)
Definition: Hyperlinks.cpp:600
static bool IsTextValid(ItemModifiedAppearanceEntry const *enchantment, std::string_view text)
Definition: Hyperlinks.cpp:593
static bool IsColorValid(SpellItemEnchantmentEntry const *, HyperlinkColor c)
Definition: Hyperlinks.cpp:620
static bool IsTextValid(SpellItemEnchantmentEntry const *enchantment, std::string_view text)
Definition: Hyperlinks.cpp:609
static bool IsColorValid(TransmogSetEntry const *, HyperlinkColor c)
Definition: Hyperlinks.cpp:645
static bool IsTextValid(TransmogSetEntry const *set, std::string_view text)
Definition: Hyperlinks.cpp:629
static bool IsColorValid(WorldMapLinkData const &, HyperlinkColor c)
Definition: Hyperlinks.cpp:659
static bool IsTextValid(WorldMapLinkData const &, std::string_view)
Definition: Hyperlinks.cpp:654
static bool IsTextValid(typename T::value_type, std::string_view)
Definition: Hyperlinks.cpp:106
static bool IsColorValid(typename T::value_type, HyperlinkColor)
Definition: Hyperlinks.cpp:107
LocalizedString Name
LocalizedString MapName
std::vector< std::string > LogTitle
Definition: QuestDef.h:408
LocalizedString DisplayName
LocalizedString HordeName
uint32 SpellID
int32 ItemNameDescriptionID
LocalizedString Name