From 788c7b025b75a49c89e196f5c67ed4978c453927 Mon Sep 17 00:00:00 2001 From: Hokken Date: Fri, 6 Mar 2026 17:41:40 +0000 Subject: [PATCH] Fix quest links triggering trade window (#2155) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary `ChatHelper::parseable()` matched any hyperlink containing `|H`, including quest links (`|Hquest:`), achievement links, spell links, etc. This caused bots to interpret quest links shared in party chat as item trade requests, opening the trade window instead of ignoring them. Narrowed the check from `"|H"` to `"|Hitem:"` so only actual item links trigger the parseable/trade logic. **One-line change** in `src/Bot/Cmd/ChatHelper.cpp:603` ## Root Cause The WoW client uses `|H:|h[Name]|h` hyperlinks for many object types: - `|Hitem:12345|h[Item Name]|h` — items - `|Hquest:678|h[Quest Name]|h` — quests - `|Hspell:890|h[Spell Name]|h` — spells - `|Hachievement:...|h` — achievements The old check `text.find("|H")` matched ALL of these, so sharing a quest link in party chat would cause the bot to enter the item parsing/trade flow. ## Test Scenarios | Scenario | Before | After | |----------|--------|-------| | Share `[Quest Name]` in party chat | Trade window opens | No reaction (correct) | | Share `[Item Name]` in party chat | Trade window opens | Trade window opens (unchanged) | | Say "questitem" in chat | Parsed correctly | Parsed correctly (unchanged) | | Share `[Spell Name]` in party chat | Trade window opens | No reaction (correct) | Tested on AzerothCore 3.3.5a with mod-playerbots, confirmed fix resolves the issue. --------- Co-authored-by: Keleborn <22352763+Celandriel@users.noreply.github.com> Co-authored-by: bash Co-authored-by: Hokken Co-authored-by: Claude Opus 4.6 --- src/Bot/Cmd/ChatHelper.cpp | 4 ++-- src/Bot/Cmd/ChatHelper.h | 2 +- src/Bot/Engine/ExternalEventHelper.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Bot/Cmd/ChatHelper.cpp b/src/Bot/Cmd/ChatHelper.cpp index bf288747..fb6002a1 100644 --- a/src/Bot/Cmd/ChatHelper.cpp +++ b/src/Bot/Cmd/ChatHelper.cpp @@ -598,9 +598,9 @@ uint32 ChatHelper::parseSlot(std::string const text) return EQUIPMENT_SLOT_END; } -bool ChatHelper::parseable(std::string const text) +bool ChatHelper::parseableItem(std::string const text) { - return text.find("|H") != std::string::npos || text == "questitem" || text == "ammo" || + return text.find("|Hitem:") != std::string::npos || text == "questitem" || text == "ammo" || substrContainsInMap(text, consumableSubClasses) || substrContainsInMap(text, tradeSubClasses) || substrContainsInMap(text, itemQualities) || substrContainsInMap(text, slots) || substrContainsInMap(text, chats) || diff --git a/src/Bot/Cmd/ChatHelper.h b/src/Bot/Cmd/ChatHelper.h index 562f2307..5069fcb5 100644 --- a/src/Bot/Cmd/ChatHelper.h +++ b/src/Bot/Cmd/ChatHelper.h @@ -66,7 +66,7 @@ public: static uint32 parseSlot(std::string const text); uint32 parseSkill(std::string const text); - static bool parseable(std::string const text); + static bool parseableItem(std::string const text); void eraseAllSubStr(std::string& mainStr, std::string const toErase); diff --git a/src/Bot/Engine/ExternalEventHelper.cpp b/src/Bot/Engine/ExternalEventHelper.cpp index 2f42eee9..3a62fbda 100644 --- a/src/Bot/Engine/ExternalEventHelper.cpp +++ b/src/Bot/Engine/ExternalEventHelper.cpp @@ -30,7 +30,7 @@ bool ExternalEventHelper::ParseChatCommand(std::string const command, Player* ow return true; } - if (!ChatHelper::parseable(command)) + if (!ChatHelper::parseableItem(command)) return false; HandleCommand("c", command, owner);