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

Namespaces

 

Classes

struct  AchievementLinkData
 
struct  FoundLinkData
 
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)
406{
407 // Step 1: Disallow all control sequences except ||, |H, |h, |c and |r
408 {
409 std::string_view::size_type pos = 0;
410 while ((pos = str.find('|', pos)) != std::string::npos)
411 {
412 ++pos;
413 if (pos == str.length())
414 return false;
415 char next = str[pos];
416 if (next == 'H' || next == 'h' || next == 'c' || next == 'r' || next == '|')
417 ++pos;
418 else
419 return false;
420 }
421 }
422
423 // Step 2: Parse all link sequences
424 // They look like this: |c<color>|H<linktag>:<linkdata>|h[<linktext>]|h|r
425 // - <color> is 8 hex characters AARRGGBB
426 // - <linktag> is arbitrary length [a-z_]
427 // - <linkdata> is arbitrary length, no | contained
428 // - <linktext> is printable
429 {
430 std::string::size_type pos;
431 while ((pos = str.find('|')) != std::string::npos)
432 {
433 if (str[pos + 1] == '|') // this is an escaped pipe character (||)
434 {
435 str = str.substr(pos + 2);
436 continue;
437 }
438
439 HyperlinkInfo info = ParseSingleHyperlink(str.substr(pos));
440 if (!info || !ValidateLinkInfo(info))
441 return false;
442
443 // tag is fine, find the next one
444 str = info.tail;
445 }
446 }
447
448 // all tags are valid
449 return true;
450}

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)
46{
47 uint32 color = 0;
48 std::string_view tag;
49 std::string_view data;
50 std::string_view text;
51
52 //color tag
53 if (str.substr(0, 2) != "|c")
54 return {};
55
56 str.remove_prefix(2);
57
58 if (str.length() < 8)
59 return {};
60
61 for (uint8 i = 0; i < 8; ++i)
62 {
63 if (uint8 hex = toHex(str[i]))
64 color = (color << 4) | (hex & 0xf);
65 else
66 return {};
67 }
68
69 str.remove_prefix(8);
70
71 if (str.substr(0, 2) != "|H")
72 return {};
73
74 str.remove_prefix(2);
75
76 // tag+data part follows
77 if (std::size_t delimPos = str.find('|'); delimPos != std::string_view::npos)
78 {
79 tag = str.substr(0, delimPos);
80 str.remove_prefix(delimPos+1);
81 }
82 else
83 return {};
84
85 // split tag if : is present (data separator)
86 if (std::size_t dataStart = tag.find(':'); dataStart != std::string_view::npos)
87 {
88 data = tag.substr(dataStart+1);
89 tag = tag.substr(0, dataStart);
90 }
91
92 // ok, next should be link data end tag...
93 if (str.substr(0, 1) != "h")
94 return {};
95 str.remove_prefix(1);
96 // skip to final |
97 if (std::size_t end = str.find('|'); end != std::string_view::npos)
98 {
99 // check end tag
100 if (str.substr(end, 4) != "|h|r")
101 return {};
102 // check text brackets
103 if ((str[0] != '[') || (str[end - 1] != ']'))
104 return {};
105 text = str.substr(1, end - 2);
106 // tail
107 str = str.substr(end + 4);
108 }
109 else
110 return {};
111
112 // ok, valid hyperlink, return info
113 return { str, color, tag, data, text };
114}
std::uint8_t uint8
Definition Define.h:109
std::uint32_t uint32
Definition Define.h:107

References toHex().

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