mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-16 07:30:42 +01:00
Core/Chat: Implement hyperlink validation for new link types
This commit is contained in:
@@ -36,6 +36,20 @@ char const* Trinity::ChatCommands::ArgInfo<AchievementEntry const*>::TryConsume(
|
||||
return args;
|
||||
}
|
||||
|
||||
struct CurrencyTypesVisitor
|
||||
{
|
||||
using value_type = CurrencyTypesEntry const*;
|
||||
value_type operator()(Hyperlink<currency> currency) const { return currency->Currency; }
|
||||
value_type operator()(uint32 currencyId) const { return sCurrencyTypesStore.LookupEntry(currencyId); }
|
||||
};
|
||||
char const* Trinity::ChatCommands::ArgInfo<CurrencyTypesEntry const*>::TryConsume(CurrencyTypesEntry const*& data, char const* args)
|
||||
{
|
||||
Variant <Hyperlink<currency>, uint32> val;
|
||||
if ((args = CommandArgsConsumerSingle<decltype(val)>::TryConsumeTo(val, args)))
|
||||
data = boost::apply_visitor(CurrencyTypesVisitor(), val);
|
||||
return args;
|
||||
}
|
||||
|
||||
struct GameTeleVisitor
|
||||
{
|
||||
using value_type = GameTele const*;
|
||||
|
||||
@@ -116,6 +116,13 @@ struct TC_GAME_API ArgInfo<AchievementEntry const*>
|
||||
static char const* TryConsume(AchievementEntry const*&, char const*);
|
||||
};
|
||||
|
||||
// CurrencyTypesEntry* from numeric id or link
|
||||
template <>
|
||||
struct TC_GAME_API ArgInfo<CurrencyTypesEntry const*>
|
||||
{
|
||||
static char const* TryConsume(CurrencyTypesEntry const*&, char const*);
|
||||
};
|
||||
|
||||
// GameTele* from string name or link
|
||||
template <>
|
||||
struct TC_GAME_API ArgInfo<GameTele const*>
|
||||
|
||||
@@ -74,13 +74,130 @@ bool Trinity::Hyperlinks::LinkTags::achievement::StoreTo(AchievementLinkData& va
|
||||
t.TryConsumeTo(val.Criteria[1]) && t.TryConsumeTo(val.Criteria[2]) && t.TryConsumeTo(val.Criteria[3]) && t.IsEmpty();
|
||||
}
|
||||
|
||||
bool Trinity::Hyperlinks::LinkTags::apower::StoreTo(ArtifactPowerLinkData& val, char const* pos, size_t len)
|
||||
{
|
||||
HyperlinkDataTokenizer t(pos, len);
|
||||
uint32 artifactPowerId;
|
||||
if (!(t.TryConsumeTo(artifactPowerId) && t.TryConsumeTo(val.PurchasedRank) && t.TryConsumeTo(val.CurrentRankWithBonus) && t.IsEmpty()))
|
||||
return false;
|
||||
if (!sArtifactPowerStore.LookupEntry(artifactPowerId))
|
||||
return false;
|
||||
val.ArtifactPower = sDB2Manager.GetArtifactPowerRank(artifactPowerId, std::max<uint8>(val.CurrentRankWithBonus, 1));
|
||||
if (val.ArtifactPower)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Trinity::Hyperlinks::LinkTags::azessence::StoreTo(AzeriteEssenceLinkData& val, char const* pos, size_t len)
|
||||
{
|
||||
HyperlinkDataTokenizer t(pos, len);
|
||||
uint32 azeriteEssenceId;
|
||||
if (!t.TryConsumeTo(azeriteEssenceId))
|
||||
return false;
|
||||
return (val.Essence = sAzeriteEssenceStore.LookupEntry(azeriteEssenceId)) && t.TryConsumeTo(val.Rank)
|
||||
&& sDB2Manager.GetAzeriteEssencePower(azeriteEssenceId, val.Rank) && t.IsEmpty();
|
||||
}
|
||||
|
||||
bool Trinity::Hyperlinks::LinkTags::battlepet::StoreTo(BattlePetLinkData& val, char const* pos, size_t len)
|
||||
{
|
||||
HyperlinkDataTokenizer t(pos, len);
|
||||
uint32 battlePetSpeciesId;
|
||||
if (!t.TryConsumeTo(battlePetSpeciesId))
|
||||
return false;
|
||||
return (val.Species = sBattlePetSpeciesStore.LookupEntry(battlePetSpeciesId)) && t.TryConsumeTo(val.Level)
|
||||
&& t.TryConsumeTo(val.Quality) && val.Quality < MAX_ITEM_QUALITY
|
||||
&& t.TryConsumeTo(val.MaxHealth) && t.TryConsumeTo(val.Power) && t.TryConsumeTo(val.Speed)
|
||||
&& t.TryConsumeTo(val.PetGuid) && val.PetGuid.GetHigh() == HighGuid::BattlePet && t.TryConsumeTo(val.DisplayId);
|
||||
}
|
||||
|
||||
bool Trinity::Hyperlinks::LinkTags::conduit::StoreTo(SoulbindConduitRankEntry const*& val, char const* pos, size_t len)
|
||||
{
|
||||
HyperlinkDataTokenizer t(pos, len);
|
||||
uint32 soulbindConduitId, rank;
|
||||
if (!(t.TryConsumeTo(soulbindConduitId) && t.TryConsumeTo(rank) && t.IsEmpty()))
|
||||
return false;
|
||||
return !!(val = sDB2Manager.GetSoulbindConduitRank(soulbindConduitId, rank));
|
||||
}
|
||||
|
||||
bool Trinity::Hyperlinks::LinkTags::currency::StoreTo(CurrencyLinkData& val, char const* pos, size_t len)
|
||||
{
|
||||
HyperlinkDataTokenizer t(pos, len);
|
||||
uint32 currencyId;
|
||||
if (!t.TryConsumeTo(currencyId))
|
||||
return false;
|
||||
val.Currency = sCurrencyTypesStore.LookupEntry(currencyId);
|
||||
if (!val.Currency || !t.TryConsumeTo(val.Quantity) || !t.IsEmpty())
|
||||
return false;
|
||||
val.Container = sDB2Manager.GetCurrencyContainerForCurrencyQuantity(currencyId, val.Quantity);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Trinity::Hyperlinks::LinkTags::enchant::StoreTo(SpellInfo const*& val, char const* pos, size_t len)
|
||||
{
|
||||
HyperlinkDataTokenizer t(pos, len);
|
||||
uint32 spellId;
|
||||
if (!(t.TryConsumeTo(spellId) && t.IsEmpty()))
|
||||
return false;
|
||||
return (val = sSpellMgr->GetSpellInfo(spellId, DIFFICULTY_NONE)) && val->HasAttribute(SPELL_ATTR0_TRADESPELL);
|
||||
return !!(val = sSpellMgr->GetSpellInfo(spellId, DIFFICULTY_NONE)) && val->HasAttribute(SPELL_ATTR0_TRADESPELL);
|
||||
}
|
||||
|
||||
bool Trinity::Hyperlinks::LinkTags::garrfollower::StoreTo(GarrisonFollowerLinkData& val, char const* pos, size_t len)
|
||||
{
|
||||
HyperlinkDataTokenizer t(pos, len);
|
||||
uint32 garrFollowerId;
|
||||
if (!t.TryConsumeTo(garrFollowerId))
|
||||
return false;
|
||||
|
||||
val.Follower = sGarrFollowerStore.LookupEntry(garrFollowerId);
|
||||
if (!val.Follower || !t.TryConsumeTo(val.Quality) || val.Quality >= MAX_ITEM_QUALITY || !t.TryConsumeTo(val.Level) || !t.TryConsumeTo(val.ItemLevel)
|
||||
|| !t.TryConsumeTo(val.Abilities[0]) || !t.TryConsumeTo(val.Abilities[1]) || !t.TryConsumeTo(val.Abilities[2]) || !t.TryConsumeTo(val.Abilities[3])
|
||||
|| !t.TryConsumeTo(val.Traits[0]) || !t.TryConsumeTo(val.Traits[1]) || !t.TryConsumeTo(val.Traits[2]) || !t.TryConsumeTo(val.Traits[3])
|
||||
|| !t.TryConsumeTo(val.Specialization))
|
||||
return false;
|
||||
|
||||
for (uint32 ability : val.Abilities)
|
||||
if (ability && !sGarrAbilityStore.LookupEntry(ability))
|
||||
return false;
|
||||
|
||||
for (uint32 trait : val.Traits)
|
||||
if (trait && !sGarrAbilityStore.LookupEntry(trait))
|
||||
return false;
|
||||
|
||||
if (val.Specialization && !sGarrAbilityStore.LookupEntry(val.Specialization))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Trinity::Hyperlinks::LinkTags::garrfollowerability::StoreTo(GarrAbilityEntry const*& val, char const* pos, size_t len)
|
||||
{
|
||||
HyperlinkDataTokenizer t(pos, len);
|
||||
uint32 garrAbilityId;
|
||||
if (!t.TryConsumeTo(garrAbilityId))
|
||||
return false;
|
||||
return !!(val = sGarrAbilityStore.LookupEntry(garrAbilityId)) && t.IsEmpty();
|
||||
}
|
||||
|
||||
bool Trinity::Hyperlinks::LinkTags::garrmission::StoreTo(GarrisonMissionLinkData& val, char const* pos, size_t len)
|
||||
{
|
||||
HyperlinkDataTokenizer t(pos, len);
|
||||
uint32 garrMissionId;
|
||||
if (!t.TryConsumeTo(garrMissionId))
|
||||
return false;
|
||||
return !!(val.Mission = sGarrMissionStore.LookupEntry(garrMissionId)) && t.TryConsumeTo(val.DbID) && t.IsEmpty();
|
||||
}
|
||||
|
||||
bool Trinity::Hyperlinks::LinkTags::instancelock::StoreTo(InstanceLockLinkData& val, char const* pos, size_t len)
|
||||
{
|
||||
HyperlinkDataTokenizer t(pos, len);
|
||||
if (!t.TryConsumeTo(val.Owner))
|
||||
return false;
|
||||
uint32 mapId;
|
||||
if (!t.TryConsumeTo(mapId))
|
||||
return false;
|
||||
return !!(val.Map = sMapStore.LookupEntry(mapId))
|
||||
&& t.TryConsumeTo(val.Difficulty) && sDB2Manager.GetMapDifficultyData(mapId, Difficulty(val.Difficulty))
|
||||
&& t.TryConsumeTo(val.CompletedEncountersMask) && t.IsEmpty();
|
||||
}
|
||||
|
||||
bool Trinity::Hyperlinks::LinkTags::item::StoreTo(ItemLinkData& val, char const* pos, size_t len)
|
||||
@@ -143,6 +260,92 @@ bool Trinity::Hyperlinks::LinkTags::item::StoreTo(ItemLinkData& val, char const*
|
||||
return t.TryConsumeTo(val.Creator) && t.TryConsumeTo(val.UseEnchantId) && t.IsEmpty();
|
||||
}
|
||||
|
||||
bool Trinity::Hyperlinks::LinkTags::journal::StoreTo(JournalLinkData& val, char const* pos, size_t len)
|
||||
{
|
||||
HyperlinkDataTokenizer t(pos, len);
|
||||
uint32 id;
|
||||
if (!t.TryConsumeTo(val.Type) || !t.TryConsumeTo(id) || !t.TryConsumeTo(val.Difficulty) || !t.IsEmpty())
|
||||
return false;
|
||||
switch (JournalLinkData::Types(val.Type))
|
||||
{
|
||||
case JournalLinkData::Types::Instance:
|
||||
{
|
||||
JournalInstanceEntry const* instance = sJournalInstanceStore.LookupEntry(id);
|
||||
if (!instance)
|
||||
return false;
|
||||
val.ExpectedText = &instance->Name;
|
||||
break;
|
||||
}
|
||||
case JournalLinkData::Types::Encounter:
|
||||
{
|
||||
JournalEncounterEntry const* encounter = sJournalEncounterStore.LookupEntry(id);
|
||||
if (!encounter)
|
||||
return false;
|
||||
val.ExpectedText = &encounter->Name;
|
||||
break;
|
||||
}
|
||||
case JournalLinkData::Types::EncounterSection:
|
||||
{
|
||||
JournalEncounterSectionEntry const* encounterSection = sJournalEncounterSectionStore.LookupEntry(id);
|
||||
if (!encounterSection)
|
||||
return false;
|
||||
val.ExpectedText = &encounterSection->Title;
|
||||
break;
|
||||
}
|
||||
case JournalLinkData::Types::Tier:
|
||||
{
|
||||
JournalTierEntry const* tier = sDB2Manager.GetJournalTier(id);
|
||||
if (!tier)
|
||||
return false;
|
||||
val.ExpectedText = &tier->Name;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Trinity::Hyperlinks::LinkTags::keystone::StoreTo(KeystoneLinkData& val, char const* pos, size_t len)
|
||||
{
|
||||
HyperlinkDataTokenizer t(pos, len);
|
||||
uint32 mapChallengeModeId;
|
||||
if (!t.TryConsumeTo(val.ItemId) || !t.TryConsumeTo(mapChallengeModeId) || !t.TryConsumeTo(val.Level)
|
||||
|| !t.TryConsumeTo(val.Affix[0]) || !t.TryConsumeTo(val.Affix[1]) || !t.TryConsumeTo(val.Affix[2]) || !t.TryConsumeTo(val.Affix[3])
|
||||
|| !t.IsEmpty())
|
||||
return false;
|
||||
val.Map = sMapChallengeModeStore.LookupEntry(mapChallengeModeId);
|
||||
if (!val.Map)
|
||||
return false;
|
||||
ItemTemplate const* item = sObjectMgr->GetItemTemplate(val.ItemId);
|
||||
if (!item || item->GetClass() != ITEM_CLASS_REAGENT || item->GetSubClass() != ITEM_SUBCLASS_KEYSTONE)
|
||||
return false;
|
||||
for (uint32 keystoneAffix : val.Affix)
|
||||
if (keystoneAffix && !sKeystoneAffixStore.LookupEntry(keystoneAffix))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Trinity::Hyperlinks::LinkTags::mawpower::StoreTo(MawPowerEntry const*& val, char const* pos, size_t len)
|
||||
{
|
||||
HyperlinkDataTokenizer t(pos, len);
|
||||
uint32 mawPowerId;
|
||||
if (!t.TryConsumeTo(mawPowerId))
|
||||
return false;
|
||||
return !!(val = sMawPowerStore.LookupEntry(mawPowerId)) && t.IsEmpty();
|
||||
}
|
||||
|
||||
bool Trinity::Hyperlinks::LinkTags::pvptal::StoreTo(PvpTalentEntry const*& val, char const* pos, size_t len)
|
||||
{
|
||||
HyperlinkDataTokenizer t(pos, len);
|
||||
uint32 pvpTalentId;
|
||||
if (!(t.TryConsumeTo(pvpTalentId) && t.IsEmpty()))
|
||||
return false;
|
||||
if (!(val = sPvpTalentStore.LookupEntry(pvpTalentId)))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Trinity::Hyperlinks::LinkTags::quest::StoreTo(QuestLinkData& val, char const* pos, size_t len)
|
||||
{
|
||||
HyperlinkDataTokenizer t(pos, len);
|
||||
@@ -185,3 +388,48 @@ bool Trinity::Hyperlinks::LinkTags::trade::StoreTo(TradeskillLinkData& val, char
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Trinity::Hyperlinks::LinkTags::transmogappearance::StoreTo(ItemModifiedAppearanceEntry const*& val, char const* pos, size_t len)
|
||||
{
|
||||
HyperlinkDataTokenizer t(pos, len);
|
||||
uint32 itemModifiedAppearanceId;
|
||||
if (!t.TryConsumeTo(itemModifiedAppearanceId))
|
||||
return false;
|
||||
return !!(val = sItemModifiedAppearanceStore.LookupEntry(itemModifiedAppearanceId)) && t.IsEmpty();
|
||||
}
|
||||
|
||||
bool Trinity::Hyperlinks::LinkTags::transmogillusion::StoreTo(SpellItemEnchantmentEntry const*& val, char const* pos, size_t len)
|
||||
{
|
||||
HyperlinkDataTokenizer t(pos, len);
|
||||
uint32 spellItemEnchantmentId;
|
||||
if (!t.TryConsumeTo(spellItemEnchantmentId))
|
||||
return false;
|
||||
return !!(val = sSpellItemEnchantmentStore.LookupEntry(spellItemEnchantmentId))
|
||||
&& sDB2Manager.GetTransmogIllusionForEnchantment(spellItemEnchantmentId) && t.IsEmpty();
|
||||
}
|
||||
|
||||
bool Trinity::Hyperlinks::LinkTags::transmogset::StoreTo(TransmogSetEntry const*& val, char const* pos, size_t len)
|
||||
{
|
||||
HyperlinkDataTokenizer t(pos, len);
|
||||
uint32 transmogSetId;
|
||||
if (!t.TryConsumeTo(transmogSetId))
|
||||
return false;
|
||||
return !!(val = sTransmogSetStore.LookupEntry(transmogSetId)) && t.IsEmpty();
|
||||
}
|
||||
|
||||
bool Trinity::Hyperlinks::LinkTags::worldmap::StoreTo(WorldMapLinkData& val, char const* pos, size_t len)
|
||||
{
|
||||
HyperlinkDataTokenizer t(pos, len);
|
||||
uint32 uiMapId;
|
||||
if (!t.TryConsumeTo(uiMapId))
|
||||
return false;
|
||||
val.UiMap = sUiMapStore.LookupEntry(uiMapId);
|
||||
if (!val.UiMap || !t.TryConsumeTo(val.X) || !t.TryConsumeTo(val.Y))
|
||||
return false;
|
||||
if (t.IsEmpty())
|
||||
return true;
|
||||
val.Z.emplace();
|
||||
if (!t.TryConsumeTo(*val.Z))
|
||||
return false;
|
||||
return t.IsEmpty();
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "SharedDefines.h"
|
||||
#include "SpellInfo.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "StringFormat.h"
|
||||
#include "World.h"
|
||||
#include "advstd.h"
|
||||
|
||||
@@ -99,88 +100,26 @@ static bool equal_with_len(char const* str1, char const* str2, size_t len)
|
||||
return !len && !*str1;
|
||||
}
|
||||
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::achievement>
|
||||
static bool IsCreatureNameValid(uint32 creatureId, char const* pos, size_t len)
|
||||
{
|
||||
static bool IsTextValid(AchievementLinkData const& data, char const* pos, size_t len)
|
||||
if (CreatureTemplate const* creatureTemplate = sObjectMgr->GetCreatureTemplate(creatureId))
|
||||
{
|
||||
if (!len)
|
||||
return false;
|
||||
for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1))
|
||||
if (equal_with_len(data.Achievement->Title[i], pos, len))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool IsColorValid(AchievementLinkData const&, HyperlinkColor c)
|
||||
{
|
||||
return c == CHAT_LINK_COLOR_ACHIEVEMENT;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::item>
|
||||
{
|
||||
static bool IsTextValid(ItemLinkData const& data, char const* pos, size_t len)
|
||||
{
|
||||
LocalizedString const* suffixStrings = nullptr;
|
||||
if (!(data.Item->GetFlags3() & ITEM_FLAG3_HIDE_NAME_SUFFIX) && data.Suffix)
|
||||
suffixStrings = &data.Suffix->Description;
|
||||
|
||||
for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1))
|
||||
{
|
||||
std::string name = data.Item->GetName(i);
|
||||
if (name.empty())
|
||||
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))
|
||||
return true;
|
||||
}
|
||||
else if (equal_with_len(name.c_str(), pos, len))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool IsColorValid(ItemLinkData const& data, HyperlinkColor c)
|
||||
{
|
||||
return c == ItemQualityColors[data.Quality];
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::quest>
|
||||
{
|
||||
static bool IsTextValid(QuestLinkData const& data, char const* pos, size_t len)
|
||||
{
|
||||
QuestTemplateLocale const* locale = sObjectMgr->GetQuestLocale(data.Quest->GetQuestId());
|
||||
CreatureLocale const* locale = sObjectMgr->GetCreatureLocale(creatureId);
|
||||
if (!locale)
|
||||
return equal_with_len(data.Quest->GetLogTitle().c_str(), pos, len);
|
||||
return equal_with_len(creatureTemplate->Name.c_str(), pos, len);
|
||||
|
||||
for (uint8 i = 0; i < TOTAL_LOCALES; ++i)
|
||||
{
|
||||
std::string const& name = (i == DEFAULT_LOCALE) ? data.Quest->GetLogTitle() : locale->LogTitle[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))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool IsColorValid(QuestLinkData const&, HyperlinkColor c)
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_QUEST_DIFFICULTY; ++i)
|
||||
if (c == QuestDifficultyColors[i])
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
return false;
|
||||
}
|
||||
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::spell>
|
||||
@@ -204,6 +143,106 @@ struct LinkValidator<LinkTags::spell>
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::achievement>
|
||||
{
|
||||
static bool IsTextValid(AchievementLinkData const& data, char const* pos, size_t len)
|
||||
{
|
||||
if (!len)
|
||||
return false;
|
||||
for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1))
|
||||
if (equal_with_len(data.Achievement->Title[i], pos, len))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool IsColorValid(AchievementLinkData const&, HyperlinkColor c)
|
||||
{
|
||||
return c == CHAT_LINK_COLOR_ACHIEVEMENT;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::apower>
|
||||
{
|
||||
static bool IsTextValid(ArtifactPowerLinkData const& data, char const* pos, size_t len)
|
||||
{
|
||||
if (SpellInfo const* info = sSpellMgr->GetSpellInfo(data.ArtifactPower->SpellID, DIFFICULTY_NONE))
|
||||
return LinkValidator<LinkTags::spell>::IsTextValid(info, pos, len);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool IsColorValid(ArtifactPowerLinkData const&, HyperlinkColor c)
|
||||
{
|
||||
return c == CHAT_LINK_COLOR_ARTIFACT_POWER;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::azessence>
|
||||
{
|
||||
static bool IsTextValid(AzeriteEssenceLinkData const& data, char const* pos, size_t len)
|
||||
{
|
||||
for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1))
|
||||
if (equal_with_len(data.Essence->Name[i], pos, len))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool IsColorValid(AzeriteEssenceLinkData const& data, HyperlinkColor c)
|
||||
{
|
||||
return c == ItemQualityColors[data.Rank + 1];
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::battlepet>
|
||||
{
|
||||
static bool IsTextValid(BattlePetLinkData const& data, char const* pos, size_t len)
|
||||
{
|
||||
return IsCreatureNameValid(data.Species->CreatureID, pos, len);
|
||||
}
|
||||
|
||||
static bool IsColorValid(BattlePetLinkData const& data, HyperlinkColor c)
|
||||
{
|
||||
return c == ItemQualityColors[data.Quality];
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::conduit>
|
||||
{
|
||||
static bool IsTextValid(SoulbindConduitRankEntry const* rank, char const* pos, size_t len)
|
||||
{
|
||||
if (SpellInfo const* info = sSpellMgr->GetSpellInfo(rank->SpellID, DIFFICULTY_NONE))
|
||||
return LinkValidator<LinkTags::spell>::IsTextValid(info, pos, len);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool IsColorValid(SoulbindConduitRankEntry const*, HyperlinkColor c)
|
||||
{
|
||||
return c == CHAT_LINK_COLOR_SPELL;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::currency>
|
||||
{
|
||||
static bool IsTextValid(CurrencyLinkData const& data, char const* pos, size_t len)
|
||||
{
|
||||
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))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool IsColorValid(CurrencyLinkData const& data, HyperlinkColor c)
|
||||
{
|
||||
return c == ItemQualityColors[(data.Container ? data.Container->ContainerQuality : data.Currency->Quality)];
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::enchant>
|
||||
{
|
||||
@@ -237,12 +276,239 @@ struct LinkValidator<LinkTags::enchant>
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::garrfollower>
|
||||
{
|
||||
static bool IsTextValid(GarrisonFollowerLinkData const& data, char const* pos, size_t len)
|
||||
{
|
||||
return IsCreatureNameValid(data.Follower->HordeCreatureID, pos, len)
|
||||
|| IsCreatureNameValid(data.Follower->AllianceCreatureID, pos, len);
|
||||
}
|
||||
|
||||
static bool IsColorValid(GarrisonFollowerLinkData const& data, HyperlinkColor c)
|
||||
{
|
||||
return c == ItemQualityColors[data.Quality];
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::garrfollowerability>
|
||||
{
|
||||
static bool IsTextValid(GarrAbilityEntry const* ability, char const* pos, size_t len)
|
||||
{
|
||||
for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1))
|
||||
if (equal_with_len(ability->Name[i], pos, len))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool IsColorValid(GarrAbilityEntry const*, HyperlinkColor c)
|
||||
{
|
||||
return c == CHAT_LINK_COLOR_GARR_ABILITY;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::garrmission>
|
||||
{
|
||||
static bool IsTextValid(GarrisonMissionLinkData const& data, char const* pos, size_t len)
|
||||
{
|
||||
for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1))
|
||||
if (equal_with_len(data.Mission->Name[i], pos, len))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool IsColorValid(GarrisonMissionLinkData const&, HyperlinkColor c)
|
||||
{
|
||||
return c == QuestDifficultyColors[2];
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::instancelock>
|
||||
{
|
||||
static bool IsTextValid(InstanceLockLinkData const& data, char const* pos, size_t len)
|
||||
{
|
||||
for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1))
|
||||
if (equal_with_len(data.Map->MapName[i], pos, len))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool IsColorValid(InstanceLockLinkData const&, HyperlinkColor c)
|
||||
{
|
||||
return c == CHAT_LINK_COLOR_INSTANCE_LOCK;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::item>
|
||||
{
|
||||
static bool IsTextValid(ItemLinkData const& data, char const* pos, size_t len)
|
||||
{
|
||||
LocalizedString const* suffixStrings = nullptr;
|
||||
if (!(data.Item->GetFlags3() & ITEM_FLAG3_HIDE_NAME_SUFFIX) && data.Suffix)
|
||||
suffixStrings = &data.Suffix->Description;
|
||||
|
||||
return IsTextValid(data.Item, suffixStrings, pos, len);
|
||||
}
|
||||
|
||||
static bool IsTextValid(ItemTemplate const* itemTemplate, LocalizedString const* suffixStrings, char const* pos, size_t len)
|
||||
{
|
||||
for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1))
|
||||
{
|
||||
std::string name = itemTemplate->GetName(i);
|
||||
if (name.empty())
|
||||
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))
|
||||
return true;
|
||||
}
|
||||
else if (equal_with_len(name.c_str(), pos, len))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool IsColorValid(ItemLinkData const& data, HyperlinkColor c)
|
||||
{
|
||||
return c == ItemQualityColors[data.Quality];
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::journal>
|
||||
{
|
||||
static bool IsTextValid(JournalLinkData const& data, char const* pos, size_t len)
|
||||
{
|
||||
for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1))
|
||||
if (equal_with_len((*data.ExpectedText)[i], pos, len))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool IsColorValid(JournalLinkData const&, HyperlinkColor c)
|
||||
{
|
||||
return c == CHAT_LINK_COLOR_JOURNAL;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::keystone>
|
||||
{
|
||||
static bool IsTextValid(KeystoneLinkData const& data, char const* pos, size_t len)
|
||||
{
|
||||
// Skip "Keystone" prefix - not loading GlobalStrings.db2
|
||||
char const* validateStartPos = strstr(pos, ": ");
|
||||
if (!validateStartPos)
|
||||
return false;
|
||||
|
||||
// skip ": " too
|
||||
validateStartPos += 2;
|
||||
size_t validateLen = len - (validateStartPos - pos);
|
||||
|
||||
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))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool IsColorValid(KeystoneLinkData const&, HyperlinkColor c)
|
||||
{
|
||||
return c == ItemQualityColors[ITEM_QUALITY_EPIC];
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::quest>
|
||||
{
|
||||
static bool IsTextValid(QuestLinkData const& data, char const* pos, size_t len)
|
||||
{
|
||||
QuestTemplateLocale const* locale = sObjectMgr->GetQuestLocale(data.Quest->GetQuestId());
|
||||
if (!locale)
|
||||
return equal_with_len(data.Quest->GetLogTitle().c_str(), pos, len);
|
||||
|
||||
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))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool IsColorValid(QuestLinkData const&, HyperlinkColor c)
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_QUEST_DIFFICULTY; ++i)
|
||||
if (c == QuestDifficultyColors[i])
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::mawpower>
|
||||
{
|
||||
static bool IsTextValid(MawPowerEntry const* mawPower, char const* pos, size_t len)
|
||||
{
|
||||
if (SpellInfo const* info = sSpellMgr->GetSpellInfo(mawPower->SpellID, DIFFICULTY_NONE))
|
||||
return LinkValidator<LinkTags::spell>::IsTextValid(info, pos, len);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool IsColorValid(MawPowerEntry const*, HyperlinkColor c)
|
||||
{
|
||||
return c == CHAT_LINK_COLOR_SPELL;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::outfit>
|
||||
{
|
||||
static bool IsTextValid(std::string const&, char const*, size_t)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool IsColorValid(std::string const&, HyperlinkColor c)
|
||||
{
|
||||
return c == CHAT_LINK_COLOR_TRANSMOG;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::pvptal>
|
||||
{
|
||||
static bool IsTextValid(PvpTalentEntry const* mawPower, char const* pos, size_t len)
|
||||
{
|
||||
if (SpellInfo const* info = sSpellMgr->GetSpellInfo(mawPower->SpellID, DIFFICULTY_NONE))
|
||||
return LinkValidator<LinkTags::spell>::IsTextValid(info, pos, len);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool IsColorValid(PvpTalentEntry const*, HyperlinkColor c)
|
||||
{
|
||||
return c == CHAT_LINK_COLOR_TALENT;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::talent>
|
||||
{
|
||||
static bool IsTextValid(TalentEntry const* talent, char const* pos, size_t len)
|
||||
static bool IsTextValid(TalentEntry const* mawPower, char const* pos, size_t len)
|
||||
{
|
||||
if (SpellInfo const* info = sSpellMgr->GetSpellInfo(talent->SpellID, DIFFICULTY_NONE))
|
||||
if (SpellInfo const* info = sSpellMgr->GetSpellInfo(mawPower->SpellID, DIFFICULTY_NONE))
|
||||
return LinkValidator<LinkTags::spell>::IsTextValid(info, pos, len);
|
||||
return false;
|
||||
}
|
||||
@@ -267,6 +533,81 @@ struct LinkValidator<LinkTags::trade>
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::transmogappearance>
|
||||
{
|
||||
static bool IsTextValid(ItemModifiedAppearanceEntry const* enchantment, char const* pos, size_t len)
|
||||
{
|
||||
if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(enchantment->ItemID))
|
||||
return LinkValidator<LinkTags::item>::IsTextValid(itemTemplate, nullptr, pos, len);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool IsColorValid(ItemModifiedAppearanceEntry const*, HyperlinkColor c)
|
||||
{
|
||||
return c == CHAT_LINK_COLOR_TRANSMOG;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::transmogillusion>
|
||||
{
|
||||
static bool IsTextValid(SpellItemEnchantmentEntry const* enchantment, char const* pos, size_t len)
|
||||
{
|
||||
for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1))
|
||||
if (equal_with_len(enchantment->Name[i], pos, len))
|
||||
return true;
|
||||
for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1))
|
||||
if (equal_with_len(enchantment->HordeName[i], pos, len))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool IsColorValid(SpellItemEnchantmentEntry const*, HyperlinkColor c)
|
||||
{
|
||||
return c == CHAT_LINK_COLOR_TRANSMOG;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::transmogset>
|
||||
{
|
||||
static bool IsTextValid(TransmogSetEntry const* set, char const* pos, size_t len)
|
||||
{
|
||||
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))
|
||||
return true;
|
||||
}
|
||||
else if (equal_with_len(set->Name[i], pos, len))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool IsColorValid(TransmogSetEntry const*, HyperlinkColor c)
|
||||
{
|
||||
return c == CHAT_LINK_COLOR_TRANSMOG;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct LinkValidator<LinkTags::worldmap>
|
||||
{
|
||||
static bool IsTextValid(WorldMapLinkData const&, char const*, size_t)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool IsColorValid(WorldMapLinkData const&, HyperlinkColor c)
|
||||
{
|
||||
return c == CHAT_LINK_COLOR_ACHIEVEMENT;
|
||||
}
|
||||
};
|
||||
|
||||
#define TryValidateAs(tagname) \
|
||||
{ \
|
||||
ASSERT(!strcmp(LinkTags::tagname::tag(), #tagname)); \
|
||||
@@ -288,17 +629,31 @@ struct LinkValidator<LinkTags::trade>
|
||||
static bool ValidateLinkInfo(HyperlinkInfo const& info)
|
||||
{
|
||||
TryValidateAs(achievement);
|
||||
TryValidateAs(apower);
|
||||
TryValidateAs(azessence);
|
||||
TryValidateAs(area);
|
||||
TryValidateAs(areatrigger);
|
||||
TryValidateAs(battlepet);
|
||||
TryValidateAs(conduit);
|
||||
TryValidateAs(creature);
|
||||
TryValidateAs(creature_entry);
|
||||
TryValidateAs(currency);
|
||||
TryValidateAs(enchant);
|
||||
TryValidateAs(gameevent);
|
||||
TryValidateAs(gameobject);
|
||||
TryValidateAs(gameobject_entry);
|
||||
TryValidateAs(garrfollower);
|
||||
TryValidateAs(garrfollowerability);
|
||||
TryValidateAs(garrmission);
|
||||
TryValidateAs(instancelock);
|
||||
TryValidateAs(item);
|
||||
TryValidateAs(itemset);
|
||||
TryValidateAs(journal);
|
||||
TryValidateAs(keystone);
|
||||
TryValidateAs(mawpower);
|
||||
TryValidateAs(outfit);
|
||||
TryValidateAs(player);
|
||||
TryValidateAs(pvptal);
|
||||
TryValidateAs(quest);
|
||||
TryValidateAs(skill);
|
||||
TryValidateAs(spell);
|
||||
@@ -307,6 +662,10 @@ static bool ValidateLinkInfo(HyperlinkInfo const& info)
|
||||
TryValidateAs(tele);
|
||||
TryValidateAs(title);
|
||||
TryValidateAs(trade);
|
||||
TryValidateAs(transmogappearance);
|
||||
TryValidateAs(transmogillusion);
|
||||
TryValidateAs(transmogset);
|
||||
TryValidateAs(worldmap);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,17 +20,36 @@
|
||||
|
||||
#include "advstd.h"
|
||||
#include "ObjectGuid.h"
|
||||
#include "Optional.h"
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
struct AchievementEntry;
|
||||
struct ArtifactPowerRankEntry;
|
||||
struct AzeriteEssenceEntry;
|
||||
struct BattlePetSpeciesEntry;
|
||||
struct CurrencyContainerEntry;
|
||||
struct CurrencyTypesEntry;
|
||||
struct GarrAbilityEntry;
|
||||
struct GarrFollowerEntry;
|
||||
struct GarrMissionEntry;
|
||||
struct GlyphPropertiesEntry;
|
||||
struct ItemModifiedAppearanceEntry;
|
||||
struct ItemNameDescriptionEntry;
|
||||
struct ItemTemplate;
|
||||
struct LocalizedString;
|
||||
struct MapEntry;
|
||||
struct MapChallengeModeEntry;
|
||||
struct MawPowerEntry;
|
||||
struct PvpTalentEntry;
|
||||
class Quest;
|
||||
struct SkillLineEntry;
|
||||
struct SoulbindConduitRankEntry;
|
||||
class SpellInfo;
|
||||
struct SpellItemEnchantmentEntry;
|
||||
struct TalentEntry;
|
||||
struct TransmogSetEntry;
|
||||
struct UiMapEntry;
|
||||
|
||||
namespace Trinity
|
||||
{
|
||||
@@ -48,6 +67,64 @@ struct AchievementLinkData
|
||||
uint32 Criteria[4];
|
||||
};
|
||||
|
||||
struct ArtifactPowerLinkData
|
||||
{
|
||||
ArtifactPowerRankEntry const* ArtifactPower;
|
||||
uint8 PurchasedRank;
|
||||
uint8 CurrentRankWithBonus;
|
||||
};
|
||||
|
||||
struct AzeriteEssenceLinkData
|
||||
{
|
||||
AzeriteEssenceEntry const* Essence;
|
||||
uint8 Rank;
|
||||
};
|
||||
|
||||
struct BattlePetLinkData
|
||||
{
|
||||
BattlePetSpeciesEntry const* Species;
|
||||
uint8 Level;
|
||||
uint8 Quality;
|
||||
uint32 MaxHealth;
|
||||
uint32 Power;
|
||||
uint32 Speed;
|
||||
ObjectGuid PetGuid;
|
||||
uint32 DisplayId;
|
||||
};
|
||||
|
||||
struct CurrencyLinkData
|
||||
{
|
||||
CurrencyTypesEntry const* Currency;
|
||||
int32 Quantity;
|
||||
|
||||
CurrencyContainerEntry const* Container;
|
||||
};
|
||||
|
||||
struct GarrisonFollowerLinkData
|
||||
{
|
||||
GarrFollowerEntry const* Follower;
|
||||
uint32 Quality;
|
||||
uint32 Level;
|
||||
uint32 ItemLevel;
|
||||
uint32 Abilities[4];
|
||||
uint32 Traits[4];
|
||||
uint32 Specialization;
|
||||
};
|
||||
|
||||
struct GarrisonMissionLinkData
|
||||
{
|
||||
GarrMissionEntry const* Mission;
|
||||
uint64 DbID;
|
||||
};
|
||||
|
||||
struct InstanceLockLinkData
|
||||
{
|
||||
ObjectGuid Owner;
|
||||
MapEntry const* Map;
|
||||
uint32 Difficulty;
|
||||
uint32 CompletedEncountersMask;
|
||||
};
|
||||
|
||||
struct ItemLinkData
|
||||
{
|
||||
ItemTemplate const* Item;
|
||||
@@ -73,6 +150,29 @@ struct ItemLinkData
|
||||
ItemNameDescriptionEntry const* Suffix;
|
||||
};
|
||||
|
||||
struct JournalLinkData
|
||||
{
|
||||
enum class Types : uint8
|
||||
{
|
||||
Instance = 0,
|
||||
Encounter = 1,
|
||||
EncounterSection = 2,
|
||||
Tier = 3
|
||||
};
|
||||
|
||||
uint8 Type;
|
||||
LocalizedString const* ExpectedText;
|
||||
uint32 Difficulty;
|
||||
};
|
||||
|
||||
struct KeystoneLinkData
|
||||
{
|
||||
uint32 ItemId;
|
||||
MapChallengeModeEntry const* Map;
|
||||
uint32 Level;
|
||||
uint32 Affix[4];
|
||||
};
|
||||
|
||||
struct QuestLinkData
|
||||
{
|
||||
::Quest const* Quest;
|
||||
@@ -92,6 +192,14 @@ struct TradeskillLinkData
|
||||
SkillLineEntry const* Skill;
|
||||
};
|
||||
|
||||
struct WorldMapLinkData
|
||||
{
|
||||
UiMapEntry const* UiMap;
|
||||
uint32 X;
|
||||
uint32 Y;
|
||||
Optional<uint32> Z;
|
||||
};
|
||||
|
||||
namespace LinkTags {
|
||||
|
||||
/************************** LINK TAGS ***************************************************\
|
||||
@@ -138,6 +246,7 @@ namespace LinkTags {
|
||||
};
|
||||
|
||||
#define make_base_tag(ltag, type) struct ltag : public base_tag { using value_type = type; static constexpr char const* tag() { return #ltag; } }
|
||||
// custom formats
|
||||
make_base_tag(area, uint32);
|
||||
make_base_tag(areatrigger, uint32);
|
||||
make_base_tag(creature, ObjectGuid::LowType);
|
||||
@@ -151,6 +260,9 @@ namespace LinkTags {
|
||||
make_base_tag(taxinode, uint32);
|
||||
make_base_tag(tele, uint32);
|
||||
make_base_tag(title, uint32);
|
||||
|
||||
// client format
|
||||
make_base_tag(outfit, std::string const&); // some sort of weird base91 derived encoding
|
||||
#undef make_base_tag
|
||||
|
||||
struct TC_GAME_API achievement
|
||||
@@ -160,6 +272,41 @@ namespace LinkTags {
|
||||
static bool StoreTo(AchievementLinkData& val, char const* pos, size_t len);
|
||||
};
|
||||
|
||||
struct TC_GAME_API apower
|
||||
{
|
||||
using value_type = ArtifactPowerLinkData const&;
|
||||
static constexpr char const* tag() { return "apower"; }
|
||||
static bool StoreTo(ArtifactPowerLinkData& val, char const* pos, size_t len);
|
||||
};
|
||||
|
||||
struct TC_GAME_API azessence
|
||||
{
|
||||
using value_type = AzeriteEssenceLinkData const&;
|
||||
static constexpr char const* tag() { return "azessence"; }
|
||||
static bool StoreTo(AzeriteEssenceLinkData& val, char const* pos, size_t len);
|
||||
};
|
||||
|
||||
struct TC_GAME_API battlepet
|
||||
{
|
||||
using value_type = BattlePetLinkData const&;
|
||||
static constexpr char const* tag() { return "battlepet"; }
|
||||
static bool StoreTo(BattlePetLinkData& val, char const* pos, size_t len);
|
||||
};
|
||||
|
||||
struct TC_GAME_API conduit
|
||||
{
|
||||
using value_type = SoulbindConduitRankEntry const*&;
|
||||
static constexpr char const* tag() { return "conduit"; }
|
||||
static bool StoreTo(SoulbindConduitRankEntry const*& val, char const* pos, size_t len);
|
||||
};
|
||||
|
||||
struct TC_GAME_API currency
|
||||
{
|
||||
using value_type = CurrencyLinkData const&;
|
||||
static constexpr char const* tag() { return "currency"; }
|
||||
static bool StoreTo(CurrencyLinkData& val, char const* pos, size_t len);
|
||||
};
|
||||
|
||||
struct TC_GAME_API enchant
|
||||
{
|
||||
using value_type = SpellInfo const*;
|
||||
@@ -167,6 +314,34 @@ namespace LinkTags {
|
||||
static bool StoreTo(SpellInfo const*& val, char const* pos, size_t len);
|
||||
};
|
||||
|
||||
struct TC_GAME_API garrfollower
|
||||
{
|
||||
using value_type = GarrisonFollowerLinkData const&;
|
||||
static constexpr char const* tag() { return "garrfollower"; }
|
||||
static bool StoreTo(GarrisonFollowerLinkData& val, char const* pos, size_t len);
|
||||
};
|
||||
|
||||
struct TC_GAME_API garrfollowerability
|
||||
{
|
||||
using value_type = GarrAbilityEntry const*&;
|
||||
static constexpr char const* tag() { return "garrfollowerability"; }
|
||||
static bool StoreTo(GarrAbilityEntry const*& val, char const* pos, size_t len);
|
||||
};
|
||||
|
||||
struct TC_GAME_API garrmission
|
||||
{
|
||||
using value_type = GarrisonMissionLinkData const&;
|
||||
static constexpr char const* tag() { return "garrmission"; }
|
||||
static bool StoreTo(GarrisonMissionLinkData& val, char const* pos, size_t len);
|
||||
};
|
||||
|
||||
struct TC_GAME_API instancelock
|
||||
{
|
||||
using value_type = InstanceLockLinkData const&;
|
||||
static constexpr char const* tag() { return "instancelock"; }
|
||||
static bool StoreTo(InstanceLockLinkData& val, char const* pos, size_t len);
|
||||
};
|
||||
|
||||
struct TC_GAME_API item
|
||||
{
|
||||
using value_type = ItemLinkData const&;
|
||||
@@ -174,6 +349,34 @@ namespace LinkTags {
|
||||
static bool StoreTo(ItemLinkData& val, char const* pos, size_t len);
|
||||
};
|
||||
|
||||
struct TC_GAME_API journal
|
||||
{
|
||||
using value_type = JournalLinkData const&;
|
||||
static constexpr char const* tag() { return "journal"; }
|
||||
static bool StoreTo(JournalLinkData& val, char const* pos, size_t len);
|
||||
};
|
||||
|
||||
struct TC_GAME_API keystone
|
||||
{
|
||||
using value_type = KeystoneLinkData const&;
|
||||
static constexpr char const* tag() { return "keystone"; }
|
||||
static bool StoreTo(KeystoneLinkData& val, char const* pos, size_t len);
|
||||
};
|
||||
|
||||
struct TC_GAME_API mawpower
|
||||
{
|
||||
using value_type = MawPowerEntry const*&;
|
||||
static constexpr char const* tag() { return "mawpower"; }
|
||||
static bool StoreTo(MawPowerEntry const*& val, char const* pos, size_t len);
|
||||
};
|
||||
|
||||
struct TC_GAME_API pvptal
|
||||
{
|
||||
using value_type = PvpTalentEntry const*&;
|
||||
static constexpr char const* tag() { return "pvptal"; }
|
||||
static bool StoreTo(PvpTalentEntry const*& val, char const* pos, size_t len);
|
||||
};
|
||||
|
||||
struct TC_GAME_API quest
|
||||
{
|
||||
using value_type = QuestLinkData const&;
|
||||
@@ -201,6 +404,34 @@ namespace LinkTags {
|
||||
static constexpr char const* tag() { return "trade"; }
|
||||
static bool StoreTo(TradeskillLinkData& val, char const* pos, size_t len);
|
||||
};
|
||||
|
||||
struct TC_GAME_API transmogappearance
|
||||
{
|
||||
using value_type = ItemModifiedAppearanceEntry const*&;
|
||||
static constexpr char const* tag() { return "transmogappearance"; }
|
||||
static bool StoreTo(ItemModifiedAppearanceEntry const*& val, char const* pos, size_t len);
|
||||
};
|
||||
|
||||
struct TC_GAME_API transmogillusion
|
||||
{
|
||||
using value_type = SpellItemEnchantmentEntry const*&;
|
||||
static constexpr char const* tag() { return "transmogillusion"; }
|
||||
static bool StoreTo(SpellItemEnchantmentEntry const*& val, char const* pos, size_t len);
|
||||
};
|
||||
|
||||
struct TC_GAME_API transmogset
|
||||
{
|
||||
using value_type = TransmogSetEntry const*&;
|
||||
static constexpr char const* tag() { return "transmogset"; }
|
||||
static bool StoreTo(TransmogSetEntry const*& val, char const* pos, size_t len);
|
||||
};
|
||||
|
||||
struct TC_GAME_API worldmap
|
||||
{
|
||||
using value_type = WorldMapLinkData const&;
|
||||
static constexpr char const* tag() { return "worldmap"; }
|
||||
static bool StoreTo(WorldMapLinkData& val, char const* pos, size_t len);
|
||||
};
|
||||
}
|
||||
|
||||
struct HyperlinkColor
|
||||
|
||||
@@ -5649,6 +5649,11 @@ enum ChatLinkColors : uint32
|
||||
CHAT_LINK_COLOR_SPELL = 0xff71d5ff, // bright blue
|
||||
CHAT_LINK_COLOR_ENCHANT = 0xffffd000, // orange
|
||||
CHAT_LINK_COLOR_ACHIEVEMENT = 0xffffff00,
|
||||
CHAT_LINK_COLOR_ARTIFACT_POWER = 0xff71d5ff,
|
||||
CHAT_LINK_COLOR_GARR_ABILITY = 0xff4e96f7,
|
||||
CHAT_LINK_COLOR_INSTANCE_LOCK = 0xffff8000,
|
||||
CHAT_LINK_COLOR_JOURNAL = 0xff66bbff,
|
||||
CHAT_LINK_COLOR_TRANSMOG = 0xffff80ff,
|
||||
};
|
||||
|
||||
// Values from ItemPetFood (power of (value-1) used for compare with CreatureFamilyEntry.petDietMask
|
||||
|
||||
Reference in New Issue
Block a user