AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
Acore::Hyperlinks Namespace Reference

Namespaces

namespace  LinkTags
 

Classes

struct  AchievementLinkData
 
struct  GlyphLinkData
 
struct  HyperlinkColor
 
struct  HyperlinkInfo
 
struct  ItemLinkData
 
struct  QuestLinkData
 
struct  TalentLinkData
 
struct  TradeskillLinkData
 

Functions

HyperlinkInfo AC_GAME_API ParseSingleHyperlink (std::string_view str)
 
bool AC_GAME_API CheckAllLinks (std::string_view str)
 

Function Documentation

◆ CheckAllLinks()

bool Acore::Hyperlinks::CheckAllLinks ( std::string_view  str)
378{
379 // Step 1: Disallow all control sequences except ||, |H, |h, |c and |r
380 {
381 std::string_view::size_type pos = 0;
382 while ((pos = str.find('|', pos)) != std::string::npos)
383 {
384 ++pos;
385 if (pos == str.length())
386 return false;
387 char next = str[pos];
388 if (next == 'H' || next == 'h' || next == 'c' || next == 'r' || next == '|')
389 ++pos;
390 else
391 return false;
392 }
393 }
394
395 // Step 2: Parse all link sequences
396 // They look like this: |c<color>|H<linktag>:<linkdata>|h[<linktext>]|h|r
397 // - <color> is 8 hex characters AARRGGBB
398 // - <linktag> is arbitrary length [a-z_]
399 // - <linkdata> is arbitrary length, no | contained
400 // - <linktext> is printable
401 {
402 std::string::size_type pos;
403 while ((pos = str.find('|')) != std::string::npos)
404 {
405 if (str[pos + 1] == '|') // this is an escaped pipe character (||)
406 {
407 str = str.substr(pos + 2);
408 continue;
409 }
410
411 HyperlinkInfo info = ParseSingleHyperlink(str.substr(pos));
412 if (!info || !ValidateLinkInfo(info))
413 return false;
414
415 // tag is fine, find the next one
416 str = info.tail;
417 }
418 }
419
420 // all tags are valid
421 return true;
422}
static bool ValidateLinkInfo(HyperlinkInfo const &info)
Definition: Hyperlinks.cpp:349
HyperlinkInfo AC_GAME_API ParseSingleHyperlink(std::string_view str)
Definition: Hyperlinks.cpp:32
Definition: Hyperlinks.h:237
std::string_view const tail
Definition: Hyperlinks.h:244

References ParseSingleHyperlink(), Acore::Hyperlinks::HyperlinkInfo::tail, and ValidateLinkInfo().

Referenced by WorldPackets::Strings::Hyperlinks::Validate(), and WorldSession::ValidateHyperlinksAndMaybeKick().

◆ ParseSingleHyperlink()

HyperlinkInfo Acore::Hyperlinks::ParseSingleHyperlink ( std::string_view  str)
33{
34 uint32 color = 0;
35 std::string_view tag;
36 std::string_view data;
37 std::string_view text;
38
39 //color tag
40 if (str.substr(0, 2) != "|c")
41 return {};
42
43 str.remove_prefix(2);
44
45 if (str.length() < 8)
46 return {};
47
48 for (uint8 i = 0; i < 8; ++i)
49 {
50 if (uint8 hex = toHex(str[i]))
51 color = (color << 4) | (hex & 0xf);
52 else
53 return {};
54 }
55
56 str.remove_prefix(8);
57
58 if (str.substr(0, 2) != "|H")
59 return {};
60
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}
std::uint8_t uint8
Definition: Define.h:110
std::uint32_t uint32
Definition: Define.h:108
uint8 toHex(char c)
Definition: Hyperlinks.cpp:29

References toHex().

Referenced by CheckAllLinks(), and Acore::ChatCommands::Hyperlink< linktag >::TryConsume().