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

Namespaces

 

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

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