mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-26 03:42:37 +01:00
Core/ChatCommands: C++17 cleanup (again) (PR #25323)
(cherry picked from commit 2f7d2ef3e9)
This commit is contained in:
@@ -33,87 +33,95 @@ using namespace Trinity::Hyperlinks;
|
||||
|
||||
inline uint8 toHex(char c) { return (c >= '0' && c <= '9') ? c - '0' + 0x10 : (c >= 'a' && c <= 'f') ? c - 'a' + 0x1a : 0x00; }
|
||||
// Validates a single hyperlink
|
||||
HyperlinkInfo Trinity::Hyperlinks::ParseHyperlink(char const* pos)
|
||||
HyperlinkInfo Trinity::Hyperlinks::ParseSingleHyperlink(std::string_view str)
|
||||
{
|
||||
//color tag
|
||||
if (*(pos++) != '|' || *(pos++) != 'c')
|
||||
return nullptr;
|
||||
uint32 color = 0;
|
||||
std::string_view tag;
|
||||
std::string_view data;
|
||||
std::string_view text;
|
||||
|
||||
//color tag
|
||||
if (str.substr(0, 2) != "|c")
|
||||
return {};
|
||||
str.remove_prefix(2);
|
||||
|
||||
if (str.length() < 8)
|
||||
return {};
|
||||
|
||||
for (uint8 i = 0; i < 8; ++i)
|
||||
{
|
||||
if (uint8 hex = toHex(*(pos++)))
|
||||
if (uint8 hex = toHex(str[i]))
|
||||
color = (color << 4) | (hex & 0xf);
|
||||
else
|
||||
return nullptr;
|
||||
return {};
|
||||
}
|
||||
// link data start tag
|
||||
if (*(pos++) != '|' || *(pos++) != 'H')
|
||||
return nullptr;
|
||||
// link tag, find next : or |
|
||||
char const* tagStart = pos;
|
||||
size_t tagLength = 0;
|
||||
while (*pos && *pos != '|' && *(pos++) != ':') // we only advance pointer to one past if the last thing is : (not for |), this is intentional!
|
||||
++tagLength;
|
||||
// ok, link data, skip to next |
|
||||
char const* dataStart = pos;
|
||||
size_t dataLength = 0;
|
||||
while (*pos && *(pos++) != '|')
|
||||
++dataLength;
|
||||
// ok, next should be link data end tag...
|
||||
if (*(pos++) != 'h')
|
||||
return nullptr;
|
||||
// then visible link text, starts with [
|
||||
if (*(pos++) != '[')
|
||||
return nullptr;
|
||||
// skip until we hit the next ], abort on unexpected |
|
||||
char const* textStart = pos;
|
||||
size_t textLength = 0;
|
||||
while (*pos)
|
||||
str.remove_prefix(8);
|
||||
|
||||
if (str.substr(0, 2) != "|H")
|
||||
return {};
|
||||
str.remove_prefix(2);
|
||||
|
||||
// tag+data part follows
|
||||
if (size_t delimPos = str.find('|'); delimPos != std::string_view::npos)
|
||||
{
|
||||
if (*pos == '|')
|
||||
return nullptr;
|
||||
if (*(pos++) == ']')
|
||||
break;
|
||||
++textLength;
|
||||
tag = str.substr(0, delimPos);
|
||||
str.remove_prefix(delimPos+1);
|
||||
}
|
||||
// link end tag
|
||||
if (*(pos++) != '|' || *(pos++) != 'h' || *(pos++) != '|' || *(pos++) != 'r')
|
||||
return nullptr;
|
||||
else
|
||||
return {};
|
||||
|
||||
// split tag if : is present (data separator)
|
||||
if (size_t dataStart = tag.find(':'); dataStart != std::string_view::npos)
|
||||
{
|
||||
data = tag.substr(dataStart+1);
|
||||
tag = tag.substr(0, dataStart);
|
||||
}
|
||||
|
||||
// ok, next should be link data end tag...
|
||||
if (str.substr(0, 1) != "h")
|
||||
return {};
|
||||
str.remove_prefix(1);
|
||||
// skip to final |
|
||||
if (size_t end = str.find('|'); end != std::string_view::npos)
|
||||
{
|
||||
// check end tag
|
||||
if (str.substr(end, 4) != "|h|r")
|
||||
return {};
|
||||
// check text brackets
|
||||
if ((str[0] != '[') || (str[end - 1] != ']'))
|
||||
return {};
|
||||
text = str.substr(1, end - 2);
|
||||
// tail
|
||||
str = str.substr(end + 4);
|
||||
}
|
||||
else
|
||||
return {};
|
||||
|
||||
// ok, valid hyperlink, return info
|
||||
return { pos, color, tagStart, tagLength, dataStart, dataLength, textStart, textLength };
|
||||
return { str, color, tag, data, text };
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct LinkValidator
|
||||
{
|
||||
static bool IsTextValid(typename T::value_type, char const*, size_t) { return true; }
|
||||
static bool IsTextValid(typename T::value_type, std::string_view) { return true; }
|
||||
static bool IsColorValid(typename T::value_type, HyperlinkColor) { return true; }
|
||||
};
|
||||
|
||||
// str1 is null-terminated, str2 is length-terminated, check if they are exactly equal
|
||||
static bool equal_with_len(char const* str1, char const* str2, size_t len)
|
||||
{
|
||||
if (!*str1)
|
||||
return false;
|
||||
while (len && *str1 && *(str1++) == *(str2++))
|
||||
--len;
|
||||
return !len && !*str1;
|
||||
}
|
||||
|
||||
static bool IsCreatureNameValid(uint32 creatureId, char const* pos, size_t len)
|
||||
static bool IsCreatureNameValid(uint32 creatureId, std::string_view text)
|
||||
{
|
||||
if (CreatureTemplate const* creatureTemplate = sObjectMgr->GetCreatureTemplate(creatureId))
|
||||
{
|
||||
CreatureLocale const* locale = sObjectMgr->GetCreatureLocale(creatureId);
|
||||
if (!locale)
|
||||
return equal_with_len(creatureTemplate->Name.c_str(), pos, len);
|
||||
return creatureTemplate->Name == text;
|
||||
|
||||
for (uint8 i = 0; i < TOTAL_LOCALES; ++i)
|
||||
{
|
||||
std::string const& name = (i == DEFAULT_LOCALE) ? creatureTemplate->Name : locale->Name[i];
|
||||
if (name.empty())
|
||||
continue;
|
||||
if (equal_with_len(name.c_str(), pos, len))
|
||||
if (name == text)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -124,15 +132,15 @@ static bool IsCreatureNameValid(uint32 creatureId, char const* pos, size_t len)
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::spell>
|
||||
{
|
||||
static bool IsTextValid(SpellLinkData const& data, char const* pos, size_t len)
|
||||
static bool IsTextValid(SpellLinkData const& data, std::string_view text)
|
||||
{
|
||||
return IsTextValid(data.Spell, pos, len);
|
||||
return IsTextValid(data.Spell, text);
|
||||
}
|
||||
|
||||
static bool IsTextValid(SpellInfo const* info, char const* pos, size_t len)
|
||||
static bool IsTextValid(SpellInfo const* info, std::string_view text)
|
||||
{
|
||||
for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1))
|
||||
if (equal_with_len((*info->SpellName)[i], pos, len))
|
||||
if ((*info->SpellName)[i] == text)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@@ -146,12 +154,12 @@ struct LinkValidator<LinkTags::spell>
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::achievement>
|
||||
{
|
||||
static bool IsTextValid(AchievementLinkData const& data, char const* pos, size_t len)
|
||||
static bool IsTextValid(AchievementLinkData const& data, std::string_view text)
|
||||
{
|
||||
if (!len)
|
||||
if (text.empty())
|
||||
return false;
|
||||
for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1))
|
||||
if (equal_with_len(data.Achievement->Title[i], pos, len))
|
||||
if (text == data.Achievement->Title[i])
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@@ -165,10 +173,10 @@ struct LinkValidator<LinkTags::achievement>
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::apower>
|
||||
{
|
||||
static bool IsTextValid(ArtifactPowerLinkData const& data, char const* pos, size_t len)
|
||||
static bool IsTextValid(ArtifactPowerLinkData const& data, std::string_view text)
|
||||
{
|
||||
if (SpellInfo const* info = sSpellMgr->GetSpellInfo(data.ArtifactPower->SpellID, DIFFICULTY_NONE))
|
||||
return LinkValidator<LinkTags::spell>::IsTextValid(info, pos, len);
|
||||
return LinkValidator<LinkTags::spell>::IsTextValid(info, text);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -181,10 +189,10 @@ struct LinkValidator<LinkTags::apower>
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::azessence>
|
||||
{
|
||||
static bool IsTextValid(AzeriteEssenceLinkData const& data, char const* pos, size_t len)
|
||||
static bool IsTextValid(AzeriteEssenceLinkData const& data, std::string_view text)
|
||||
{
|
||||
for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1))
|
||||
if (equal_with_len(data.Essence->Name[i], pos, len))
|
||||
if (data.Essence->Name[i] == text)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@@ -198,9 +206,9 @@ struct LinkValidator<LinkTags::azessence>
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::battlepet>
|
||||
{
|
||||
static bool IsTextValid(BattlePetLinkData const& data, char const* pos, size_t len)
|
||||
static bool IsTextValid(BattlePetLinkData const& data, std::string_view text)
|
||||
{
|
||||
return IsCreatureNameValid(data.Species->CreatureID, pos, len);
|
||||
return IsCreatureNameValid(data.Species->CreatureID, text);
|
||||
}
|
||||
|
||||
static bool IsColorValid(BattlePetLinkData const& data, HyperlinkColor c)
|
||||
@@ -212,10 +220,10 @@ struct LinkValidator<LinkTags::battlepet>
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::conduit>
|
||||
{
|
||||
static bool IsTextValid(SoulbindConduitRankEntry const* rank, char const* pos, size_t len)
|
||||
static bool IsTextValid(SoulbindConduitRankEntry const* rank, std::string_view text)
|
||||
{
|
||||
if (SpellInfo const* info = sSpellMgr->GetSpellInfo(rank->SpellID, DIFFICULTY_NONE))
|
||||
return LinkValidator<LinkTags::spell>::IsTextValid(info, pos, len);
|
||||
return LinkValidator<LinkTags::spell>::IsTextValid(info, text);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -228,11 +236,11 @@ struct LinkValidator<LinkTags::conduit>
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::currency>
|
||||
{
|
||||
static bool IsTextValid(CurrencyLinkData const& data, char const* pos, size_t len)
|
||||
static bool IsTextValid(CurrencyLinkData const& data, std::string_view text)
|
||||
{
|
||||
LocalizedString const* name = data.Container ? &data.Container->ContainerName : &data.Currency->Name;
|
||||
for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1))
|
||||
if (equal_with_len((*name)[i], pos, len))
|
||||
if ((*name)[i] == text)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@@ -246,9 +254,9 @@ struct LinkValidator<LinkTags::currency>
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::enchant>
|
||||
{
|
||||
static bool IsTextValid(SpellInfo const* info, char const* pos, size_t len)
|
||||
static bool IsTextValid(SpellInfo const* info, std::string_view text)
|
||||
{
|
||||
if (LinkValidator<LinkTags::spell>::IsTextValid(info, pos, len))
|
||||
if (LinkValidator<LinkTags::spell>::IsTextValid(info, text))
|
||||
return true;
|
||||
SkillLineAbilityMapBounds bounds = sSpellMgr->GetSkillLineAbilityMapBounds(info->Id);
|
||||
if (bounds.first == bounds.second)
|
||||
@@ -264,11 +272,12 @@ struct LinkValidator<LinkTags::enchant>
|
||||
|
||||
for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1))
|
||||
{
|
||||
char const* skillName = skill->DisplayName[i];
|
||||
size_t skillLen = strlen(skillName);
|
||||
if (len > skillLen + 2 && // or of form [Skill Name: Spell Name]
|
||||
!strncmp(pos, skillName, skillLen) && !strncmp(pos + skillLen, ": ", 2) &&
|
||||
equal_with_len((*info->SpellName)[i], pos + (skillLen + 2), len - (skillLen + 2)))
|
||||
std::string_view skillName = skill->DisplayName[i];
|
||||
std::string_view spellName = (*info->SpellName)[i];
|
||||
if ((text.length() == (skillName.length() + 2 + spellName.length())) &&
|
||||
(text.substr(0, skillName.length()) == skillName) &&
|
||||
(text.substr(skillName.length(), 2) == ": ") &&
|
||||
(text.substr(skillName.length() + 2) == spellName))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -284,10 +293,10 @@ struct LinkValidator<LinkTags::enchant>
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::garrfollower>
|
||||
{
|
||||
static bool IsTextValid(GarrisonFollowerLinkData const& data, char const* pos, size_t len)
|
||||
static bool IsTextValid(GarrisonFollowerLinkData const& data, std::string_view text)
|
||||
{
|
||||
return IsCreatureNameValid(data.Follower->HordeCreatureID, pos, len)
|
||||
|| IsCreatureNameValid(data.Follower->AllianceCreatureID, pos, len);
|
||||
return IsCreatureNameValid(data.Follower->HordeCreatureID, text)
|
||||
|| IsCreatureNameValid(data.Follower->AllianceCreatureID, text);
|
||||
}
|
||||
|
||||
static bool IsColorValid(GarrisonFollowerLinkData const& data, HyperlinkColor c)
|
||||
@@ -299,10 +308,10 @@ struct LinkValidator<LinkTags::garrfollower>
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::garrfollowerability>
|
||||
{
|
||||
static bool IsTextValid(GarrAbilityEntry const* ability, char const* pos, size_t len)
|
||||
static bool IsTextValid(GarrAbilityEntry const* ability, std::string_view text)
|
||||
{
|
||||
for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1))
|
||||
if (equal_with_len(ability->Name[i], pos, len))
|
||||
if (ability->Name[i] == text)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@@ -316,10 +325,10 @@ struct LinkValidator<LinkTags::garrfollowerability>
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::garrmission>
|
||||
{
|
||||
static bool IsTextValid(GarrisonMissionLinkData const& data, char const* pos, size_t len)
|
||||
static bool IsTextValid(GarrisonMissionLinkData const& data, std::string_view text)
|
||||
{
|
||||
for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1))
|
||||
if (equal_with_len(data.Mission->Name[i], pos, len))
|
||||
if (data.Mission->Name[i] == text)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@@ -333,10 +342,10 @@ struct LinkValidator<LinkTags::garrmission>
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::instancelock>
|
||||
{
|
||||
static bool IsTextValid(InstanceLockLinkData const& data, char const* pos, size_t len)
|
||||
static bool IsTextValid(InstanceLockLinkData const& data, std::string_view text)
|
||||
{
|
||||
for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1))
|
||||
if (equal_with_len(data.Map->MapName[i], pos, len))
|
||||
if (data.Map->MapName[i] == text)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@@ -350,16 +359,16 @@ struct LinkValidator<LinkTags::instancelock>
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::item>
|
||||
{
|
||||
static bool IsTextValid(ItemLinkData const& data, char const* pos, size_t len)
|
||||
static bool IsTextValid(ItemLinkData const& data, std::string_view text)
|
||||
{
|
||||
LocalizedString const* suffixStrings = nullptr;
|
||||
if (!data.Item->HasFlag(ITEM_FLAG3_HIDE_NAME_SUFFIX) && data.Suffix)
|
||||
suffixStrings = &data.Suffix->Description;
|
||||
|
||||
return IsTextValid(data.Item, suffixStrings, pos, len);
|
||||
return IsTextValid(data.Item, suffixStrings, text);
|
||||
}
|
||||
|
||||
static bool IsTextValid(ItemTemplate const* itemTemplate, LocalizedString const* suffixStrings, char const* pos, size_t len)
|
||||
static bool IsTextValid(ItemTemplate const* itemTemplate, LocalizedString const* suffixStrings, std::string_view text)
|
||||
{
|
||||
for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1))
|
||||
{
|
||||
@@ -368,13 +377,17 @@ struct LinkValidator<LinkTags::item>
|
||||
continue;
|
||||
if (suffixStrings)
|
||||
{
|
||||
if (len > name.length() + 1 &&
|
||||
(strncmp(name.c_str(), pos, name.length()) == 0) &&
|
||||
(*(pos + name.length()) == ' ') &&
|
||||
equal_with_len((*suffixStrings)[i], pos + name.length() + 1, len - name.length() - 1))
|
||||
std::string_view suffix = (*suffixStrings)[i];
|
||||
if (
|
||||
(!suffix.empty()) &&
|
||||
(text.length() == (name.length() + 1 + suffix.length())) &&
|
||||
(text.substr(0, name.length()) == name) &&
|
||||
(text[name.length()] == ' ') &&
|
||||
(text.substr(name.length() + 1) == suffix)
|
||||
)
|
||||
return true;
|
||||
}
|
||||
else if (equal_with_len(name.c_str(), pos, len))
|
||||
else if (text == name)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -389,10 +402,10 @@ struct LinkValidator<LinkTags::item>
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::journal>
|
||||
{
|
||||
static bool IsTextValid(JournalLinkData const& data, char const* pos, size_t len)
|
||||
static bool IsTextValid(JournalLinkData const& data, std::string_view text)
|
||||
{
|
||||
for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1))
|
||||
if (equal_with_len((*data.ExpectedText)[i], pos, len))
|
||||
if ((*data.ExpectedText)[i] == text)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@@ -406,21 +419,20 @@ struct LinkValidator<LinkTags::journal>
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::keystone>
|
||||
{
|
||||
static bool IsTextValid(KeystoneLinkData const& data, char const* pos, size_t len)
|
||||
static bool IsTextValid(KeystoneLinkData const& data, std::string_view text)
|
||||
{
|
||||
// Skip "Keystone" prefix - not loading GlobalStrings.db2
|
||||
char const* validateStartPos = strstr(pos, ": ");
|
||||
if (!validateStartPos)
|
||||
size_t validateStartPos = text.find(": ");
|
||||
if (validateStartPos == std::string_view::npos)
|
||||
return false;
|
||||
|
||||
// skip ": " too
|
||||
validateStartPos += 2;
|
||||
size_t validateLen = len - (validateStartPos - pos);
|
||||
text.remove_prefix(validateStartPos);
|
||||
text.remove_prefix(2); // skip ": " too
|
||||
|
||||
for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1))
|
||||
{
|
||||
std::string expectedText = Trinity::StringFormat("%s (%u)", data.Map->Name[i], data.Level);
|
||||
if (equal_with_len(expectedText.c_str(), validateStartPos, validateLen))
|
||||
if (expectedText == text)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -435,18 +447,18 @@ struct LinkValidator<LinkTags::keystone>
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::quest>
|
||||
{
|
||||
static bool IsTextValid(QuestLinkData const& data, char const* pos, size_t len)
|
||||
static bool IsTextValid(QuestLinkData const& data, std::string_view text)
|
||||
{
|
||||
QuestTemplateLocale const* locale = sObjectMgr->GetQuestLocale(data.Quest->GetQuestId());
|
||||
if (!locale)
|
||||
return equal_with_len(data.Quest->GetLogTitle().c_str(), pos, len);
|
||||
return data.Quest->GetLogTitle().c_str() == text;
|
||||
|
||||
for (uint8 i = 0; i < TOTAL_LOCALES; ++i)
|
||||
{
|
||||
std::string const& name = (i == DEFAULT_LOCALE) ? data.Quest->GetLogTitle() : locale->LogTitle[i];
|
||||
if (name.empty())
|
||||
continue;
|
||||
if (equal_with_len(name.c_str(), pos, len))
|
||||
if (text == name)
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -465,10 +477,10 @@ struct LinkValidator<LinkTags::quest>
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::mawpower>
|
||||
{
|
||||
static bool IsTextValid(MawPowerEntry const* mawPower, char const* pos, size_t len)
|
||||
static bool IsTextValid(MawPowerEntry const* mawPower, std::string_view text)
|
||||
{
|
||||
if (SpellInfo const* info = sSpellMgr->GetSpellInfo(mawPower->SpellID, DIFFICULTY_NONE))
|
||||
return LinkValidator<LinkTags::spell>::IsTextValid(info, pos, len);
|
||||
return LinkValidator<LinkTags::spell>::IsTextValid(info, text);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -481,7 +493,7 @@ struct LinkValidator<LinkTags::mawpower>
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::outfit>
|
||||
{
|
||||
static bool IsTextValid(std::string const&, char const*, size_t)
|
||||
static bool IsTextValid(std::string const&, std::string_view)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -495,10 +507,10 @@ struct LinkValidator<LinkTags::outfit>
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::pvptal>
|
||||
{
|
||||
static bool IsTextValid(PvpTalentEntry const* pvpTalent, char const* pos, size_t len)
|
||||
static bool IsTextValid(PvpTalentEntry const* pvpTalent, std::string_view text)
|
||||
{
|
||||
if (SpellInfo const* info = sSpellMgr->GetSpellInfo(pvpTalent->SpellID, DIFFICULTY_NONE))
|
||||
return LinkValidator<LinkTags::spell>::IsTextValid(info, pos, len);
|
||||
return LinkValidator<LinkTags::spell>::IsTextValid(info, text);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -511,10 +523,10 @@ struct LinkValidator<LinkTags::pvptal>
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::talent>
|
||||
{
|
||||
static bool IsTextValid(TalentEntry const* talent, char const* pos, size_t len)
|
||||
static bool IsTextValid(TalentEntry const* talent, std::string_view text)
|
||||
{
|
||||
if (SpellInfo const* info = sSpellMgr->GetSpellInfo(talent->SpellID, DIFFICULTY_NONE))
|
||||
return LinkValidator<LinkTags::spell>::IsTextValid(info, pos, len);
|
||||
return LinkValidator<LinkTags::spell>::IsTextValid(info, text);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -527,9 +539,9 @@ struct LinkValidator<LinkTags::talent>
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::trade>
|
||||
{
|
||||
static bool IsTextValid(TradeskillLinkData const& data, char const* pos, size_t len)
|
||||
static bool IsTextValid(TradeskillLinkData const& data, std::string_view text)
|
||||
{
|
||||
return LinkValidator<LinkTags::spell>::IsTextValid(data.Spell, pos, len);
|
||||
return LinkValidator<LinkTags::spell>::IsTextValid(data.Spell, text);
|
||||
}
|
||||
|
||||
static bool IsColorValid(TradeskillLinkData const&, HyperlinkColor c)
|
||||
@@ -541,10 +553,10 @@ struct LinkValidator<LinkTags::trade>
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::transmogappearance>
|
||||
{
|
||||
static bool IsTextValid(ItemModifiedAppearanceEntry const* enchantment, char const* pos, size_t len)
|
||||
static bool IsTextValid(ItemModifiedAppearanceEntry const* enchantment, std::string_view text)
|
||||
{
|
||||
if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(enchantment->ItemID))
|
||||
return LinkValidator<LinkTags::item>::IsTextValid(itemTemplate, nullptr, pos, len);
|
||||
return LinkValidator<LinkTags::item>::IsTextValid(itemTemplate, nullptr, text);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -557,13 +569,13 @@ struct LinkValidator<LinkTags::transmogappearance>
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::transmogillusion>
|
||||
{
|
||||
static bool IsTextValid(SpellItemEnchantmentEntry const* enchantment, char const* pos, size_t len)
|
||||
static bool IsTextValid(SpellItemEnchantmentEntry const* enchantment, std::string_view text)
|
||||
{
|
||||
for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1))
|
||||
if (equal_with_len(enchantment->Name[i], pos, len))
|
||||
if (enchantment->Name[i] == text)
|
||||
return true;
|
||||
for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1))
|
||||
if (equal_with_len(enchantment->HordeName[i], pos, len))
|
||||
if (enchantment->HordeName[i] == text)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@@ -577,17 +589,17 @@ struct LinkValidator<LinkTags::transmogillusion>
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::transmogset>
|
||||
{
|
||||
static bool IsTextValid(TransmogSetEntry const* set, char const* pos, size_t len)
|
||||
static bool IsTextValid(TransmogSetEntry const* set, std::string_view text)
|
||||
{
|
||||
for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1))
|
||||
{
|
||||
if (ItemNameDescriptionEntry const* itemNameDescription = sItemNameDescriptionStore.LookupEntry(set->ItemNameDescriptionID))
|
||||
{
|
||||
std::string expectedText = Trinity::StringFormat("%s (%s)", set->Name[i], itemNameDescription->Description[i]);
|
||||
if (equal_with_len(expectedText.c_str(), pos, len))
|
||||
if (expectedText.c_str() == text)
|
||||
return true;
|
||||
}
|
||||
else if (equal_with_len(set->Name[i], pos, len))
|
||||
else if (set->Name[i] == text)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -602,7 +614,7 @@ struct LinkValidator<LinkTags::transmogset>
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::worldmap>
|
||||
{
|
||||
static bool IsTextValid(WorldMapLinkData const&, char const*, size_t)
|
||||
static bool IsTextValid(WorldMapLinkData const&, std::string_view)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -615,17 +627,16 @@ struct LinkValidator<LinkTags::worldmap>
|
||||
|
||||
#define TryValidateAs(tagname) \
|
||||
{ \
|
||||
ASSERT(!strcmp(LinkTags::tagname::tag(), #tagname)); \
|
||||
if (info.tag.second == strlen(LinkTags::tagname::tag()) && \
|
||||
!strncmp(info.tag.first, LinkTags::tagname::tag(), strlen(LinkTags::tagname::tag()))) \
|
||||
static_assert(LinkTags::tagname::tag() == #tagname); \
|
||||
if (info.tag == LinkTags::tagname::tag()) \
|
||||
{ \
|
||||
advstd::remove_cvref_t<typename LinkTags::tagname::value_type> t; \
|
||||
if (!LinkTags::tagname::StoreTo(t, info.data.first, info.data.second)) \
|
||||
if (!LinkTags::tagname::StoreTo(t, info.data)) \
|
||||
return false; \
|
||||
if (!LinkValidator<LinkTags::tagname>::IsColorValid(t, info.color)) \
|
||||
return false; \
|
||||
if (sWorld->getIntConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_SEVERITY)) \
|
||||
if (!LinkValidator<LinkTags::tagname>::IsTextValid(t, info.text.first, info.text.second)) \
|
||||
if (!LinkValidator<LinkTags::tagname>::IsTextValid(t, info.text)) \
|
||||
return false; \
|
||||
return true; \
|
||||
} \
|
||||
@@ -675,16 +686,19 @@ static bool ValidateLinkInfo(HyperlinkInfo const& info)
|
||||
}
|
||||
|
||||
// Validates all hyperlinks and control sequences contained in str
|
||||
bool Trinity::Hyperlinks::CheckAllLinks(std::string const& str)
|
||||
bool Trinity::Hyperlinks::CheckAllLinks(std::string_view str)
|
||||
{
|
||||
// Step 1: Disallow all control sequences except ||, |H, |h, |c and |r
|
||||
{
|
||||
std::string::size_type pos = 0;
|
||||
std::string_view::size_type pos = 0;
|
||||
while ((pos = str.find('|', pos)) != std::string::npos)
|
||||
{
|
||||
char next = str[pos + 1];
|
||||
++pos;
|
||||
if (pos == str.length())
|
||||
return false;
|
||||
char next = str[pos];
|
||||
if (next == 'H' || next == 'h' || next == 'c' || next == 'r' || next == '|')
|
||||
pos += 2;
|
||||
++pos;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
@@ -697,21 +711,21 @@ bool Trinity::Hyperlinks::CheckAllLinks(std::string const& str)
|
||||
// - <linkdata> is arbitrary length, no | contained
|
||||
// - <linktext> is printable
|
||||
{
|
||||
std::string::size_type pos = 0;
|
||||
while ((pos = str.find('|', pos)) != std::string::npos)
|
||||
std::string::size_type pos;
|
||||
while ((pos = str.find('|')) != std::string::npos)
|
||||
{
|
||||
if (str[pos + 1] == '|') // this is an escaped pipe character (||)
|
||||
{
|
||||
pos += 2;
|
||||
str = str.substr(pos + 2);
|
||||
continue;
|
||||
}
|
||||
|
||||
HyperlinkInfo info = ParseHyperlink(str.c_str() + pos);
|
||||
HyperlinkInfo info = ParseSingleHyperlink(str.substr(pos));
|
||||
if (!info || !ValidateLinkInfo(info))
|
||||
return false;
|
||||
|
||||
// tag is fine, find the next one
|
||||
pos = info.next - str.c_str();
|
||||
str = info.tail;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user