diff options
-rw-r--r-- | src/server/game/Chat/ChatLink.cpp | 234 | ||||
-rw-r--r-- | src/server/game/Chat/ChatLink.h | 16 | ||||
-rw-r--r-- | src/server/game/Miscellaneous/SharedDefines.h | 8 |
3 files changed, 211 insertions, 47 deletions
diff --git a/src/server/game/Chat/ChatLink.cpp b/src/server/game/Chat/ChatLink.cpp index 1abb14a1669..6c26e8ba92e 100644 --- a/src/server/game/Chat/ChatLink.cpp +++ b/src/server/game/Chat/ChatLink.cpp @@ -101,7 +101,7 @@ bool ChatLink::ValidateName(char* buffer, char const* /*context*/) return true; } -// |color|Hitem:item_id:perm_ench_id:gem1:gem2:gem3:0:random_property:property_seed:reporter_level:upgrade_id:context:numBonusListIDs|h[name]|h|r +// |color|Hitem:item_id:perm_ench_id:gem1:gem2:gem3:0:random_property:property_seed:reporter_level:reporter_spec:modifiers_mask:context:numBonusListIDs:bonusListIDs(%d):mods(%d):gem1numBonusListIDs:gem1bonusListIDs(%d):gem2numBonusListIDs:gem2bonusListIDs(%d):gem3numBonusListIDs:gem3bonusListIDs(%d)|h[name]|h|r // |cffa335ee|Hitem:124382:0:0:0:0:0:0:0:0:0:0:0:4:42:562:565:567|h[Edict of Argus]|h|r"); bool ItemChatLink::Initialize(std::istringstream& iss) { @@ -132,12 +132,145 @@ bool ItemChatLink::Initialize(std::istringstream& iss) return false; } - // Number of various item properties after item entry - uint8 const propsCount = 11; - uint8 const randomPropertyPosition = 5; - uint8 const numBonusListIDsPosition = 10; - uint8 const maxBonusListIDs = 100; - for (uint8 index = 0; index < propsCount; ++index) + if (!CheckDelimiter(iss, DELIMITER, "item")) + return false; + + if (HasValue(iss) && !ReadInt32(iss, _enchantId)) + { + TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): sequence finished unexpectedly while reading item enchantId", iss.str().c_str()); + return false; + } + + if (!CheckDelimiter(iss, DELIMITER, "item")) + return false; + + if (HasValue(iss) && !ReadInt32(iss, _gemItemId[0])) + { + TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): sequence finished unexpectedly while reading item gem id 1", iss.str().c_str()); + return false; + } + + if (!CheckDelimiter(iss, DELIMITER, "item")) + return false; + + if (HasValue(iss) && !ReadInt32(iss, _gemItemId[1])) + { + TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): sequence finished unexpectedly while reading item gem id 2", iss.str().c_str()); + return false; + } + + if (!CheckDelimiter(iss, DELIMITER, "item")) + return false; + + if (HasValue(iss) && !ReadInt32(iss, _gemItemId[2])) + { + TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): sequence finished unexpectedly while reading item gem id 3", iss.str().c_str()); + return false; + } + + if (!CheckDelimiter(iss, DELIMITER, "item")) + return false; + + int32 zero = 0; + if (HasValue(iss) && !ReadInt32(iss, zero)) + { + TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): sequence finished unexpectedly while reading zero", iss.str().c_str()); + return false; + } + + if (!CheckDelimiter(iss, DELIMITER, "item")) + return false; + + if (HasValue(iss) && !ReadInt32(iss, _randomPropertyId)) + { + TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): sequence finished unexpectedly while reading item random property id", iss.str().c_str()); + return false; + } + + if (_randomPropertyId > 0) + { + _property = sItemRandomPropertiesStore.LookupEntry(_randomPropertyId); + if (!_property) + { + TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): got invalid item property id %u in |item command", iss.str().c_str(), _randomPropertyId); + return false; + } + } + else if (_randomPropertyId < 0) + { + _suffix = sItemRandomSuffixStore.LookupEntry(-_randomPropertyId); + if (!_suffix) + { + TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): got invalid item suffix id %u in |item command", iss.str().c_str(), -_randomPropertyId); + return false; + } + } + + if (!CheckDelimiter(iss, DELIMITER, "item")) + return false; + + if (HasValue(iss) && !ReadInt32(iss, _randomPropertySeed)) + { + TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): sequence finished unexpectedly while reading item random property seed", iss.str().c_str()); + return false; + } + + if (!CheckDelimiter(iss, DELIMITER, "item")) + return false; + + if (HasValue(iss) && !ReadInt32(iss, _reporterLevel)) + { + TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): sequence finished unexpectedly while reading item owner level", iss.str().c_str()); + return false; + } + + if (!CheckDelimiter(iss, DELIMITER, "item")) + return false; + + if (HasValue(iss) && !ReadInt32(iss, _reporterSpec)) + { + TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): sequence finished unexpectedly while reading item owner spec", iss.str().c_str()); + return false; + } + + if (!CheckDelimiter(iss, DELIMITER, "item")) + return false; + + int32 modifiersMask = 0; + if (HasValue(iss) && !ReadInt32(iss, modifiersMask)) + { + TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): sequence finished unexpectedly while reading item modifiers mask", iss.str().c_str()); + return false; + } + + if (!CheckDelimiter(iss, DELIMITER, "item")) + return false; + + if (HasValue(iss) && !ReadInt32(iss, _context)) + { + TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): sequence finished unexpectedly while reading item context", iss.str().c_str()); + return false; + } + + if (!CheckDelimiter(iss, DELIMITER, "item")) + return false; + + uint32 numBonusListIDs = 0; + if (HasValue(iss) && !ReadUInt32(iss, numBonusListIDs)) + { + TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): sequence finished unexpectedly while reading item bonus lists size", iss.str().c_str()); + return false; + } + + uint32 const maxBonusListIDs = 16; + if (numBonusListIDs > maxBonusListIDs) + { + TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): too many item bonus list IDs %u in |item command", iss.str().c_str(), numBonusListIDs); + return false; + } + + _bonusListIDs.resize(numBonusListIDs); + for (uint32 index = 0; index < numBonusListIDs; ++index) { if (!CheckDelimiter(iss, DELIMITER, "item")) return false; @@ -145,64 +278,76 @@ bool ItemChatLink::Initialize(std::istringstream& iss) int32 id = 0; if (!ReadInt32(iss, id)) { - TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): sequence finished unexpectedly while reading item property (%u)", iss.str().c_str(), index); + TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): sequence finished unexpectedly while reading item bonus list id (index %u)", iss.str().c_str(), index); return false; } - if (id && (index == randomPropertyPosition)) + + if (!sDB2Manager.GetItemBonusList(id)) { - // Validate random property - if (id > 0) - { - _property = sItemRandomPropertiesStore.LookupEntry(id); - if (!_property) - { - TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): got invalid item property id %u in |item command", iss.str().c_str(), id); - return false; - } - } - else if (id < 0) - { - _suffix = sItemRandomSuffixStore.LookupEntry(-id); - if (!_suffix) - { - TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): got invalid item suffix id %u in |item command", iss.str().c_str(), -id); - return false; - } - } + TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): got invalid item bonus list id %d in |item command", iss.str().c_str(), id); + return false; } - if (index == numBonusListIDsPosition) + + _bonusListIDs[index] = id; + } + + for (uint32 i = 0; i < MAX_ITEM_MODIFIERS; ++i) + { + if (modifiersMask & (1 << i)) { - if (id > maxBonusListIDs) + if (!CheckDelimiter(iss, DELIMITER, "item")) + return false; + + int32 id = 0; + if (!ReadInt32(iss, id)) { - TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): too many item bonus list IDs %u in |item command", iss.str().c_str(), id); + TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): sequence finished unexpectedly while reading item modifier id (index %u)", iss.str().c_str(), i); return false; } - _bonusListIDs.resize(id); + _modifiers.push_back(std::make_pair(i, id)); } - - _data[index] = id; } - for (uint32 index = 0; index < _bonusListIDs.size(); ++index) + for (uint32 i = 0; i < MAX_ITEM_PROTO_SOCKETS; ++i) { if (!CheckDelimiter(iss, DELIMITER, "item")) return false; - int32 id = 0; - if (!ReadInt32(iss, id)) + numBonusListIDs = 0; + if (HasValue(iss) && !ReadUInt32(iss, numBonusListIDs)) { - TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): sequence finished unexpectedly while reading item bonus list id (%u)", iss.str().c_str(), index); + TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): sequence finished unexpectedly while reading item bonus lists size for gem %u", iss.str().c_str(), i); return false; } - if (!sDB2Manager.GetItemBonusList(id)) + if (numBonusListIDs > maxBonusListIDs) { - TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): got invalid item bonus list id %d in |item command", iss.str().c_str(), id); + TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): too many item bonus list IDs %u in |item command for gem %u", iss.str().c_str(), numBonusListIDs, i); return false; } - _bonusListIDs[index] = id; + _gemBonusListIDs[i].resize(numBonusListIDs); + for (uint32 index = 0; index < numBonusListIDs; ++index) + { + if (!CheckDelimiter(iss, DELIMITER, "item")) + return false; + + int32 id = 0; + if (!ReadInt32(iss, id)) + { + TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): sequence finished unexpectedly while reading item bonus list id (index %u) for gem %u", iss.str().c_str(), index, i); + return false; + } + + if (!sDB2Manager.GetItemBonusList(id)) + { + TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): got invalid item bonus list id %d in |item command for gem %u", iss.str().c_str(), id, i); + return false; + } + + _gemBonusListIDs[i][index] = id; + } } return true; @@ -218,6 +363,13 @@ std::string ItemChatLink::FormatName(uint8 index, LocalizedString* suffixStrings return ss.str(); } +// item links are compacted to remove all zero values +bool ItemChatLink::HasValue(std::istringstream& iss) const +{ + char next = iss.peek(); + return next != DELIMITER && next != PIPE_CHAR; +} + bool ItemChatLink::ValidateName(char* buffer, char const* context) { ChatLink::ValidateName(buffer, context); diff --git a/src/server/game/Chat/ChatLink.h b/src/server/game/Chat/ChatLink.h index ae6932b5d27..e3d9ed08be2 100644 --- a/src/server/game/Chat/ChatLink.h +++ b/src/server/game/Chat/ChatLink.h @@ -58,19 +58,29 @@ protected: class TC_GAME_API ItemChatLink : public ChatLink { public: - ItemChatLink() : ChatLink(), _item(NULL), _suffix(NULL), _property(NULL) + ItemChatLink() : ChatLink(), _item(nullptr), _enchantId(0), _randomPropertyId(0), _randomPropertySeed(0), _reporterLevel(0), _reporterSpec(0), _context(0), + _suffix(nullptr), _property(nullptr) { - memset(_data, 0, sizeof(_data)); + memset(_gemItemId, 0, sizeof(_gemItemId)); } virtual bool Initialize(std::istringstream& iss) override; virtual bool ValidateName(char* buffer, const char* context) override; protected: std::string FormatName(uint8 index, LocalizedString* suffixStrings) const; + bool HasValue(std::istringstream& iss) const; ItemTemplate const* _item; - int32 _data[11]; + int32 _enchantId; + int32 _gemItemId[3]; + int32 _randomPropertyId; + int32 _randomPropertySeed; + int32 _reporterLevel; + int32 _reporterSpec; + int32 _context; std::vector<int32> _bonusListIDs; + std::vector<std::pair<uint32, int32>> _modifiers; + std::vector<int32> _gemBonusListIDs[3]; ItemRandomSuffixEntry const* _suffix; ItemRandomPropertiesEntry const* _property; }; diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index a626484acc5..b88439cd6c6 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -329,10 +329,11 @@ enum ItemQualities ITEM_QUALITY_EPIC = 4, // PURPLE ITEM_QUALITY_LEGENDARY = 5, // ORANGE ITEM_QUALITY_ARTIFACT = 6, // LIGHT YELLOW - ITEM_QUALITY_HEIRLOOM = 7 + ITEM_QUALITY_HEIRLOOM = 7, // LIGHT BLUE + ITEM_QUALITY_WOW_TOKEN = 8 // LIGHT BLUE }; -#define MAX_ITEM_QUALITY 8 +#define MAX_ITEM_QUALITY 9 enum SpellCategory { @@ -349,7 +350,8 @@ const uint32 ItemQualityColors[MAX_ITEM_QUALITY] = 0xffa335ee, // PURPLE 0xffff8000, // ORANGE 0xffe6cc80, // LIGHT YELLOW - 0xffe6cc80 // LIGHT YELLOW + 0xff00ccff, // LIGHT BLUE + 0xff00ccff // LIGHT BLUE }; // *********************************** |