From 3b0eb30280129766d5c5ea2fe464d8158034c54d Mon Sep 17 00:00:00 2001 From: Alex Dcnh <140754794+Wishmaster117@users.noreply.github.com> Date: Wed, 29 Apr 2026 11:09:30 +0200 Subject: [PATCH 1/2] Add Disperse UI through bridge --- Core/MultiBotComm.lua | 75 +++ Locales/MultiBotAceLocale-deDE.lua | 7 + Locales/MultiBotAceLocale-enGB.lua | 7 + Locales/MultiBotAceLocale-enUS.lua | 7 + Locales/MultiBotAceLocale-esES.lua | 7 + Locales/MultiBotAceLocale-frFR.lua | 7 + Locales/MultiBotAceLocale-koKR.lua | 7 + Locales/MultiBotAceLocale-ruRU.lua | 7 + Locales/MultiBotAceLocale-zhCN.lua | 7 + MultiBot.toc | 1 + README.md | 568 +++------------------- UI/MultiBotDisperseUI.lua | 175 +++++++ UI/MultiBotLeftCoreUI.lua | 5 + UI/MultiBotMainUI.lua | 2 +- docs/multibot_missing_commands_roadmap.md | 88 +++- 15 files changed, 439 insertions(+), 531 deletions(-) create mode 100644 UI/MultiBotDisperseUI.lua diff --git a/Core/MultiBotComm.lua b/Core/MultiBotComm.lua index 0e558e9..9d2c0ee 100644 --- a/Core/MultiBotComm.lua +++ b/Core/MultiBotComm.lua @@ -119,6 +119,7 @@ local function ensureBridgeState() state.glyphActive = state.glyphActive or nil state.rtiSeq = state.rtiSeq or 0 state.combatSeq = state.combatSeq or 0 + state.positionSeq = state.positionSeq or 0 return state end @@ -128,6 +129,27 @@ local function debugPrint(...) end end +local function L(key, fallback) + if MultiBot and type(MultiBot.L) == "function" then + return MultiBot.L(key, fallback) + end + + return fallback or key +end + +local function systemMessage(message) + message = trim(message) + if message == "" then + return + end + + if DEFAULT_CHAT_FRAME and DEFAULT_CHAT_FRAME.AddMessage then + DEFAULT_CHAT_FRAME:AddMessage(message) + elseif type(print) == "function" then + print(message) + end +end + local function buildMessage(opcode, payload) local message = trim(opcode) if payload ~= nil and payload ~= "" then @@ -295,6 +317,31 @@ function Comm.RunCombatCommand(scope, target, command) return Comm.Send("RUN", "COMBAT~" .. scope .. "~" .. urlEncodeField(target) .. "~" .. token .. "~" .. urlEncodeField(command)) end +function Comm.RunPositionCommand(scope, target, command) + local state = ensureBridgeState() + + if not state.connected then + return false + end + + command = trim(command or "") + if command == "" then + return false + end + + scope = string.upper(trim(scope or "ALL")) + target = trim(target or "") + + if scope ~= "ALL" and scope ~= "GROUP" and scope ~= "BOT" then + return false + end + + state.positionSeq = (tonumber(state.positionSeq) or 0) + 1 + local token = tostring(math.floor(safeNow() * 1000)) .. "-position-" .. tostring(state.positionSeq) + + return Comm.Send("RUN", "POSITION~" .. scope .. "~" .. urlEncodeField(target) .. "~" .. token .. "~" .. urlEncodeField(command)) +end + function Comm.RequestOutfits(name) local state = ensureBridgeState() name = trim(name) @@ -1648,6 +1695,34 @@ function Comm.HandleAddonMessage(prefix, message, distribution, sender) return true end + if opcode == "POSITION_ACK" then + state.connected = true + state.lastError = nil + debugPrint("ADDON:RX", "POSITION_ACK", payload or "") + + local scope, rest = splitOnce(payload or "", "~") + local encodedTarget, rest2 = splitOnce(rest, "~") + local token, rest3 = splitOnce(rest2, "~") + local executedText, encodedCommand = splitOnce(rest3, "~") + local executed = tonumber(executedText) or 0 + local command = trim(urlDecodeField(encodedCommand)) + + if executed > 0 then + local distance = string.match(command, "^disperse set%s+(.+)$") + + if distance then + systemMessage(string.format( + L("disperse.confirm.set", "Disperse set to %s yards."), + distance + )) + elseif command == "disperse disable" then + systemMessage(L("disperse.confirm.disable", "Disperse disabled.")) + end + end + + return true + end + if opcode == "ERR" then state.lastError = payload debugPrint("ADDON:RX", "ERR", payload or "") diff --git a/Locales/MultiBotAceLocale-deDE.lua b/Locales/MultiBotAceLocale-deDE.lua index e11cbae..7ccbf0b 100644 --- a/Locales/MultiBotAceLocale-deDE.lua +++ b/Locales/MultiBotAceLocale-deDE.lua @@ -5,6 +5,13 @@ end local deDEValues = { ["tips.units.rti"] = "RTI", + ["tips.disperse.main"] = "Disperse", + ["tips.disperse.set"] = "Disperse-Distanz setzen", + ["tips.disperse.disable"] = "Disperse deaktivieren", + ["disperse.bridge.required"] = "Position-Bridge ist nicht verbunden.", + ["disperse.invalid_distance"] = "Gib eine Distanz zwischen 1 und 100 Yards ein.", + ["disperse.confirm.set"] = "Disperse auf %s Yards gesetzt.", + ["disperse.confirm.disable"] = "Disperse deaktiviert.", ["rti.bridge.required"] = "Die RTI-Bridge ist nicht verbunden.", ["info.rti.no_bot_selection"] = "Kein botspezifisches RTI-Symbol ausgewählt.", ["rti.icon.star"] = "Stern", diff --git a/Locales/MultiBotAceLocale-enGB.lua b/Locales/MultiBotAceLocale-enGB.lua index b56a3a9..b38db3d 100644 --- a/Locales/MultiBotAceLocale-enGB.lua +++ b/Locales/MultiBotAceLocale-enGB.lua @@ -5,6 +5,13 @@ end local enGBValues = { ["tips.units.rti"] = "RTI", + ["tips.disperse.main"] = "Disperse", + ["tips.disperse.set"] = "Set disperse distance", + ["tips.disperse.disable"] = "Disable disperse", + ["disperse.bridge.required"] = "Position bridge is not connected.", + ["disperse.invalid_distance"] = "Enter a distance between 1 and 100 yards.", + ["disperse.confirm.set"] = "Disperse set to %s yards.", + ["disperse.confirm.disable"] = "Disperse disabled.", ["rti.bridge.required"] = "RTI bridge is not connected.", ["info.rti.no_bot_selection"] = "No bot-specific RTI icon selected.", ["rti.icon.star"] = "Star", diff --git a/Locales/MultiBotAceLocale-enUS.lua b/Locales/MultiBotAceLocale-enUS.lua index f595d59..a3ae60e 100644 --- a/Locales/MultiBotAceLocale-enUS.lua +++ b/Locales/MultiBotAceLocale-enUS.lua @@ -5,6 +5,13 @@ end local enUSValues = { ["tips.units.rti"] = "RTI", + ["tips.disperse.main"] = "Disperse", + ["tips.disperse.set"] = "Set disperse distance", + ["tips.disperse.disable"] = "Disable disperse", + ["disperse.bridge.required"] = "Position bridge is not connected.", + ["disperse.invalid_distance"] = "Enter a distance between 1 and 100 yards.", + ["disperse.confirm.set"] = "Disperse set to %s yards.", + ["disperse.confirm.disable"] = "Disperse disabled.", ["rti.bridge.required"] = "RTI bridge is not connected.", ["info.rti.no_bot_selection"] = "No bot-specific RTI icon selected.", ["rti.icon.star"] = "Star", diff --git a/Locales/MultiBotAceLocale-esES.lua b/Locales/MultiBotAceLocale-esES.lua index 9a894a4..8261914 100644 --- a/Locales/MultiBotAceLocale-esES.lua +++ b/Locales/MultiBotAceLocale-esES.lua @@ -5,6 +5,13 @@ end local esESValues = { ["tips.units.rti"] = "RTI", + ["tips.disperse.main"] = "Dispersar", + ["tips.disperse.set"] = "Definir distancia de dispersión", + ["tips.disperse.disable"] = "Desactivar dispersión", + ["disperse.bridge.required"] = "El puente de posición no está conectado.", + ["disperse.invalid_distance"] = "Introduce una distancia entre 1 y 100 yardas.", + ["disperse.confirm.set"] = "Dispersión establecida a %s yardas.", + ["disperse.confirm.disable"] = "Dispersión desactivada.", ["rti.bridge.required"] = "El puente RTI no está conectado.", ["info.rti.no_bot_selection"] = "No hay ningún icono RTI específico de bot seleccionado.", ["rti.icon.star"] = "Estrella", diff --git a/Locales/MultiBotAceLocale-frFR.lua b/Locales/MultiBotAceLocale-frFR.lua index 21e576e..bb72b5d 100644 --- a/Locales/MultiBotAceLocale-frFR.lua +++ b/Locales/MultiBotAceLocale-frFR.lua @@ -5,6 +5,13 @@ end local frFRValues = { ["tips.units.rti"] = "RTI", + ["tips.disperse.main"] = "Disperse", + ["tips.disperse.set"] = "Définir la distance de disperse", + ["tips.disperse.disable"] = "Désactiver disperse", + ["disperse.bridge.required"] = "Le bridge de position n’est pas connecté.", + ["disperse.invalid_distance"] = "Entre une distance entre 1 et 100 yards.", + ["disperse.confirm.set"] = "Disperse défini à %s yards.", + ["disperse.confirm.disable"] = "Disperse désactivé.", ["rti.bridge.required"] = "Le bridge RTI n'est pas connecté.", ["info.rti.no_bot_selection"] = "Aucun bot avec une icône RTI personnelle sélectionnée.", ["rti.icon.star"] = "Étoile", diff --git a/Locales/MultiBotAceLocale-koKR.lua b/Locales/MultiBotAceLocale-koKR.lua index ea7db72..248a6c2 100644 --- a/Locales/MultiBotAceLocale-koKR.lua +++ b/Locales/MultiBotAceLocale-koKR.lua @@ -5,6 +5,13 @@ end local koKRValues = { ["tips.units.rti"] = "RTI", + ["tips.disperse.main"] = "분산", + ["tips.disperse.set"] = "분산 거리 설정", + ["tips.disperse.disable"] = "분산 비활성화", + ["disperse.bridge.required"] = "위치 브리지가 연결되어 있지 않습니다.", + ["disperse.invalid_distance"] = "1에서 100 야드 사이의 거리를 입력하세요.", + ["disperse.confirm.set"] = "분산 거리가 %s 야드로 설정되었습니다.", + ["disperse.confirm.disable"] = "분산이 비활성화되었습니다.", ["rti.bridge.required"] = "RTI 브리지가 연결되어 있지 않습니다.", ["info.rti.no_bot_selection"] = "봇 전용 RTI 아이콘이 선택되지 않았습니다.", ["rti.icon.star"] = "별", diff --git a/Locales/MultiBotAceLocale-ruRU.lua b/Locales/MultiBotAceLocale-ruRU.lua index a3f9b41..732c01e 100644 --- a/Locales/MultiBotAceLocale-ruRU.lua +++ b/Locales/MultiBotAceLocale-ruRU.lua @@ -5,6 +5,13 @@ end local ruRUValues = { ["tips.units.rti"] = "RTI", + ["tips.disperse.main"] = "Рассредоточение", + ["tips.disperse.set"] = "Задать дистанцию рассредоточения", + ["tips.disperse.disable"] = "Отключить рассредоточение", + ["disperse.bridge.required"] = "Мост позиционирования не подключен.", + ["disperse.invalid_distance"] = "Введите дистанцию от 1 до 100 ярдов.", + ["disperse.confirm.set"] = "Рассредоточение установлено на %s ярдов.", + ["disperse.confirm.disable"] = "Рассредоточение отключено.", ["rti.bridge.required"] = "RTI-мост не подключен.", ["info.rti.no_bot_selection"] = "Не выбрана RTI-иконка для отдельного бота.", ["rti.icon.star"] = "Звезда", diff --git a/Locales/MultiBotAceLocale-zhCN.lua b/Locales/MultiBotAceLocale-zhCN.lua index 4fb7fed..0781101 100644 --- a/Locales/MultiBotAceLocale-zhCN.lua +++ b/Locales/MultiBotAceLocale-zhCN.lua @@ -5,6 +5,13 @@ end local zhCNValues = { ["tips.units.rti"] = "RTI", + ["tips.disperse.main"] = "分散", + ["tips.disperse.set"] = "设置分散距离", + ["tips.disperse.disable"] = "禁用分散", + ["disperse.bridge.required"] = "位置桥接未连接。", + ["disperse.invalid_distance"] = "请输入 1 到 100 码之间的距离。", + ["disperse.confirm.set"] = "分散距离已设置为 %s 码。", + ["disperse.confirm.disable"] = "分散已禁用。", ["rti.bridge.required"] = "RTI 桥接未连接。", ["info.rti.no_bot_selection"] = "未选择任何机器人专用 RTI 图标。", ["rti.icon.star"] = "星星", diff --git a/MultiBot.toc b/MultiBot.toc index 5e73fb0..814c5c8 100644 --- a/MultiBot.toc +++ b/MultiBot.toc @@ -100,6 +100,7 @@ UI\MultiBotMainUI.lua UI\MultiBotGmUI.lua UI\MultiBotRTSCUI.lua UI\MultiBotRTIUI.lua +UI\MultiBotDisperseUI.lua Core\MultiBotInit.lua Data\MultiBotIconos.lua Data\MultiBotItemus.lua diff --git a/README.md b/README.md index cd796c3..aacad26 100644 --- a/README.md +++ b/README.md @@ -1,235 +1,42 @@ -

- Gemini_Generated_Image_s1mnq6s1mnq6s1mn -

- -
- -# MultiBot Chatless - -### Bridge-first client addon for AzerothCore `mod-playerbots` - -MultiBot-Chatless is the client-side World of Warcraft 3.3.5a addon for controlling and inspecting Playerbots through a cleaner, mostly chatless UI workflow. - -
- - - Repository - - - Bridge Module - -WoW Version -Architecture - -

- - - - - - - - - - - - - - - - - -
ComponentRepositoryInstall Location
Client Addon - - MultiBot-Chatless - - - World of Warcraft/Interface/AddOns/MultiBot -
Server Bridge Module - - mod-multibot-bridge - - - azerothcore/modules/mod-multibot-bridge -
- -
+image ---- - -## Important Notice - -`MultiBot-Chatless` is the **addon-side repository only**. - -To get the new bridge-first / mostly chatless behavior, you also need the server-side AzerothCore module: - -
+# Breaking News +MultiBot has been converted to a bridge-first, mostly chatless architecture. -### 👉 mod-multibot-bridge - -
- -Without the bridge module, the addon cannot use the new structured `MBOT GET~...` data flow. - ---- +The addon now uses `mod-multibot-bridge` to request structured data from the server instead of relying on automatic legacy chat parsing for the main UI refresh paths. Roster, states, details, stats, inventory, spellbook, glyphs, outfits and related UI data are now refreshed through `MBOT GET~...` bridge requests when the bridge is available. -# What is MultiBot Chatless? +Manual playerbot commands are still intentionally preserved for diagnostics and gameplay actions. Commands such as `who`, `co ?`, `nc ?`, `ss ?` and similar manual whispers still work so players can request information about a bot state when they explicitly want it. -MultiBot is a user interface addon for the AzerothCore [`mod-playerbots`](https://github.com/mod-playerbots/mod-playerbots) module. +Outfits have also been moved to the bridge-first path. Listing, creating/updating, resetting, equipping and replacing outfit sets no longer require automatic chat parsing, and the bridge suppresses the old detailed `Equipping [item] ...` spam while keeping a single readable equip/replace confirmation. -This fork focuses on removing automatic bot chat spam from the main UI refresh paths by using a dedicated AzerothCore bridge module instead of relying on legacy chat parsing. +RTI, Pull Control, Combat Strategies and Disperse have been added through whitelisted bridge commands. Target icon assignment, RTI attack/pull actions, pull timing, focus/assist/AoE pull presets, selected combat strategy toggles and collective disperse positioning can now be triggered from the UI without automatic chat parsing. -The addon now requests structured data from the server through `mod-multibot-bridge`. +Legacy automatic chat fallback is disabled by default: -Examples of bridge requests: - -```text -MBOT HELLO -MBOT PING -GET~ROSTER -GET~STATES -GET~DETAILS -GET~STATS -GET~INVENTORY -GET~SPELLBOOK -GET~GLYPHS -GET~OUTFITS -RUN~RTI -RUN~COMBAT -``` - -Manual playerbot commands are still intentionally preserved for diagnostics and gameplay actions. - -Commands such as: - -```text -who -co ? -nc ? -ss ? +```lua +MultiBot.allowLegacyChatFallback = false ``` -still work when the player explicitly wants to inspect a bot state. - -The goal is not to remove useful manual commands. -The goal is to remove automatic UI-refresh spam. - ---- - -# Features - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
AreaStatus
Bridge handshakeImplementedHELLO, HELLO_ACK, PING, PONG
Roster refreshBridge-first
Bot statesBridge-first
Bot detailsBridge-first
StatsBridge-first
InventoryBridge-first with icons and item tooltips
SpellbookBridge-first
GlyphsBridge-first with glyph icons and tooltips
OutfitsBridge-first listing, create/update, reset, equip and replace
RTI controlsBridge-first icon assignment and RTI target actions
Pull ControlBridge-first wait, focus, DPS assist, AoE and RTI pull/attack controls
Combat strategy fine tuningBridge-first avoid AoE, save mana, threat and behind controls
Units / EveryBarsImproved login, reload and AddClass refresh behavior
Legacy automatic chat fallbackDisabled by default
- ---- - -# Requirements - -## Client - -- World of Warcraft 3.3.5a / Wrath of the Lich King client. -- Tested with: - - English / US client - - German client - - French client - - Spanish client - -## Server +Set it to `true` only for temporary debugging if you need to test the old chat-based fallback behavior. -- [`AzerothCore WotLK`](https://github.com/mod-playerbots/azerothcore-wotlk/tree/Playerbot). -- [`mod-playerbots`](https://github.com/mod-playerbots/mod-playerbots). -- [`mod-multibot-bridge`](https://github.com/Wishmaster117/mod-multibot-bridge). +# MultiBot +MultiBot is a user interface addon for the AzerothCore `mod-playerbots` module by the Playerbots team: https://github.com/mod-playerbots/mod-playerbots.
+Tested with American, German, French and Spanish 3.3.5 WotLK clients. ---- +This version also expects the companion server module `mod-multibot-bridge` to be installed if you want the new bridge-first/chatless UI behavior. # Installation -## 1. Install the server-side bridge module - -Clone the bridge module inside your AzerothCore `modules` directory: - -```bash -cd /path/to/azerothcore/modules -git clone https://github.com/Wishmaster117/mod-multibot-bridge.git mod-multibot-bridge -``` - -Expected structure: +## 1. Server-side bridge module +1. Copy the `mod-multibot-bridge` folder into your AzerothCore modules directory, next to `mod-playerbots`: ```text -azerothcore/ -└── modules/ - └── mod-multibot-bridge/ - ├── conf/ - └── src/ +azerothcore-wotlk/modules/mod-multibot-bridge ``` -Then: - -1. Re-run CMake if required by your build workflow. -2. Rebuild AzerothCore. -3. Copy/install the generated configuration file if required. -4. Start the server. -5. Check that `mod-multibot-bridge` is loaded. +2. Re-run CMake for your AzerothCore build if your workflow requires it. +3. Rebuild the server. +4. Start the server and check that `mod-multibot-bridge` is loaded. When the addon connects successfully, the server console should show messages similar to: @@ -243,149 +50,59 @@ GET~STATES GET~DETAILS ``` ---- - -## 2. Install the client addon - -Clone this repository into your World of Warcraft AddOns directory. - -```bash -cd "World of Warcraft/Interface/AddOns" -git clone https://github.com/Wishmaster117/MultiBot-Chatless.git MultiBot -``` - -Expected structure: +For UI actions that execute safe gameplay commands, the console may also show bridge requests such as: ```text -World of Warcraft/ -└── Interface/ - └── AddOns/ - └── MultiBot/ - ├── MultiBot.toc - ├── Core/ - ├── Data/ - ├── Features/ - ├── Icons/ - ├── Libs/ - ├── Locales/ - ├── Strategies/ - ├── Textures/ - └── UI/ +RUN~RTI~BOT~Sahkaal~~rti skull +RUN~RTI~GROUP~1~~attack rti target +RUN~COMBAT~BOT~Sahkaal~~co +focus +RUN~COMBAT~ALL~~~co +avoid aoe +RUN~POSITION~ALL~~~disperse set 10 +RUN~POSITION~ALL~~~disperse disable ``` -> The GitHub repository is named `MultiBot-Chatless`, but the local addon folder must be named `MultiBot`. +These commands are validated by the bridge whitelist before being routed to bots. -Do not install it like this: +## 2. Client-side addon +1. Copy the addon files into a folder named `MultiBot` inside your World of Warcraft AddOns directory: ```text -Interface/AddOns/MultiBot/MultiBot/MultiBot.toc +World of Warcraft/Interface/AddOns/MultiBot ``` -The `.toc` file must be directly here: +Example on Windows: ```text -Interface/AddOns/MultiBot/MultiBot.toc +DRIVE:\WowClientFolder\Interface\AddOns\MultiBot ``` ---- - -# Updating - -## Update the addon - -```bash -cd "World of Warcraft/Interface/AddOns/MultiBot" -git pull -``` - -## Update the bridge module - -```bash -cd /path/to/azerothcore/modules/mod-multibot-bridge -git pull -``` - -Then rebuild your AzerothCore server if the module code changed. - ---- - -# Recommended Configuration +2. Make sure the `.toc` file is directly inside the `MultiBot` folder. The addon should not be nested inside an extra directory such as `MultiBot/MultiBot/...`. +3. Start World of Warcraft. +4. Enable the addon on the character selection screen if needed. +5. Log in and use `/multibot`, `/mbot`, `/mb`, or the minimap button. +## 3. Recommended configuration For normal bridge-first usage, keep legacy automatic chat fallback disabled: ```lua MultiBot.allowLegacyChatFallback = false ``` -Only enable it temporarily for debugging or compatibility testing: +Only enable it temporarily for debugging: ```lua MultiBot.allowLegacyChatFallback = true ``` ---- - -# Usage - -Start World of Warcraft and use one of the following commands: - -```text -/multibot -/mbot -/mb -``` - -You can also use the minimap button. +# Use +Start World of Warcraft and enter `/multibot`, `/mbot`, or `/mb` in the chat, or use the minimap button. -When the bridge is available, the addon automatically uses structured bridge messages for the main UI refresh paths instead of legacy chat replies. +The addon will automatically try to connect to `mod-multibot-bridge`. If the bridge is connected, the main UI refresh paths use structured bridge messages instead of legacy chat replies. -Manual commands are still available when you intentionally want them. - -Examples: - -```text -/w BotName who -/w BotName co ? -/w BotName nc ? -/w BotName ss ? -``` - ---- - -# Bridge-First Architecture - -
- - - - - - - - - - - - - - - - - - - - - - -
Old behaviorNew behavior
Addon triggers bot commandsAddon sends structured MBOT GET~... requests
Bots answer with chat textBridge returns structured addon messages
Addon parses localized chat linesAddon consumes stable protocol payloads
Automatic UI refresh creates chat spamMain UI refresh paths are mostly chatless
- -
- ---- +Manual bot information commands remain available. You can still whisper/use commands such as `who`, `co ?`, `nc ?`, `ss ?` and similar playerbot diagnostics when you explicitly want to inspect a bot state. The chatless conversion only removes the automatic UI-refresh spam; it does not remove voluntary status commands. # Current Status - -Implemented bridge-first / chatless areas: +Implemented bridge-first/chatless areas: - Bridge handshake: `HELLO`, `HELLO_ACK`, `PING`, `PONG`. - Roster refresh. @@ -397,200 +114,35 @@ Implemented bridge-first / chatless areas: - Glyph refresh with icons and glyph tooltips. - Outfits refresh and actions through the bridge. - Outfit equip/replace without detailed `Equipping [item] ...` chat spam. -- RTI controls through the bridge. -- Pull Control frame through the bridge. -- Combat strategy fine tuning through the bridge. -- Custom glyph socket mapping and apply order. +- RTI / Target Icons through `RUN~RTI` with `BOT`, `GROUP` and `ALL` scopes. +- Pull Control through `RUN~COMBAT`, including wait time, focus, DPS assist, DPS AoE, presets and RTI pull/attack actions. +- Combat Strategies through `RUN~COMBAT`, including individual EveryBar toggles and Party/Raid strategy toggles for `avoid aoe`, `save mana`, `threat` and `behind`. +- Disperse through `RUN~POSITION`, including distance set, disable action, 1-100 yards validation and bridge ACK confirmation without automatic chat parsing. +- Custom Glyphs socket mapping and apply order. - Talent tab navigation stability after switching between tabs. - Automatic bot reconnect on login/reload for bots already present in the group or raid. - Units bar refresh after adding a bot through AddClass. Kept intentionally: -- Manual whisper/playerbot commands for diagnostics. -- Commands such as `who`, `co ?`, `nc ?`, `ss ?`. -- Gameplay write actions that still rely on existing playerbot commands. +- Manual whisper/playerbot commands for diagnostics, including `who`, `co ?`, `nc ?`, `ss ?` and similar state-inspection commands. +- Manual gameplay commands for players who still want to control bots directly through whispers or party/raid chat. +- Whitelisted bridge gameplay actions for UI buttons that do not need structured chat parsing. - Optional legacy fallback behavior only for debugging or compatibility. ---- - # Remaining Work - -The Outfits, RTI, Pull Control and Combat Strategy migrations are implemented. The next step is Disperse, followed by final stabilization and cleanup. +The RTI, Pull Control, Combat Strategies and Disperse passes are now implemented. The next step is final stabilization, followed by the next missing command block. Planned follow-up work: -- Start the Disperse command migration. -- Regression test login, `/reload`, large raid groups, Units, EveryBars, Stats, Inventory, Spellbook, Talents, Glyphs, Outfits, RTI, Pull Control and Combat Strategies. +- Regression test login, `/reload`, large raid groups, Units, EveryBars, Stats, Inventory, Spellbook, Talents, Glyphs, Outfits, RTI, Pull Control, Combat Strategies and Disperse. - Verify that `MultiBot.allowLegacyChatFallback = false` prevents automatic legacy refresh spam on all migrated UI paths. -- Keep manual diagnostic commands documented and functional. -- Remove obsolete debug prints. -- Remove dead legacy parser paths once bridge-first behavior is fully stable. +- Keep manual diagnostic commands documented and functional, especially `who`, `co ?`, `nc ?` and `ss ?`. +- Keep `RUN~COMBAT`, `RUN~RTI` and `RUN~POSITION` strictly whitelisted in the bridge; they must not become generic unrestricted command executors. +- Remove obsolete debug prints and dead legacy parser paths once the bridge-first behavior is fully stable. - Update screenshots and user documentation after wider testing. +- Next command block to evaluate: Loot Rules / Loot List, including `nc +loot`, `nc -loot` and selected `ll` profiles. --- -# Troubleshooting - -
-The addon does not load - -Check that the folder is named exactly: - -```text -Interface/AddOns/MultiBot -``` - -and that the `.toc` file is here: - -```text -Interface/AddOns/MultiBot/MultiBot.toc -``` - -If the `.toc` file is inside another nested `MultiBot` folder, the addon is installed incorrectly. - -
- -
-The addon loads but the bridge does not connect - -Check that: - -- `mod-multibot-bridge` is installed in the AzerothCore `modules` directory. -- AzerothCore was rebuilt after installing the module. -- The server was restarted after rebuilding. -- The bridge module is visible in server logs. -- Your client is logged into a character connected to the server. - -
- -
-I still see some chat messages - -This project removes automatic UI-refresh spam where the bridge path has been implemented. - -Manual commands and gameplay actions may still produce intentional messages. - -Make sure this value is disabled unless you are debugging: - -```lua -MultiBot.allowLegacyChatFallback = false -``` - -
- -
-Inventory, spellbook, glyphs or outfits do not update - -Check the server console for bridge requests such as: - -```text -GET~INVENTORY -GET~SPELLBOOK -GET~GLYPHS -GET~OUTFITS -``` - -If these requests do not appear, the addon may not be connected to the bridge. - -
- ---- - -# Repository Layout - -```text -MultiBot-Chatless/ -├── Core/ -├── Data/ -├── Features/ -├── Icons/ -├── Libs/ -├── Locales/ -├── Strategies/ -├── Textures/ -├── UI/ -├── docs/ -└── MultiBot.toc -``` - ---- - -# Related Repositories - - - - - - - - - - - - - - - - - - - - - - -
RepositoryDescription
- - MultiBot-Chatless - - - Client-side World of Warcraft addon. -
- - mod-multibot-bridge - - - AzerothCore server-side bridge module. -
- - MultiBot-Standalone - - - Deprecated combined repository kept for history. -
- - mod-playerbots - - - Original AzerothCore Playerbots module. -
- ---- - -# Credits - -MultiBot is built for use with AzerothCore `mod-playerbots`. - -Thanks to Macx-Lio for the original MultiBot Module. - -Thanks to the Playerbots team and the AzerothCore community. - ---- - -
- -## MultiBot Chatless - -Less automatic chat spam. Cleaner UI refreshes. Bridge-first bot data. - -

- - - Client Addon - - •  - - Bridge Module - - -
+# Detailed Notice diff --git a/UI/MultiBotDisperseUI.lua b/UI/MultiBotDisperseUI.lua new file mode 100644 index 0000000..7b1ddba --- /dev/null +++ b/UI/MultiBotDisperseUI.lua @@ -0,0 +1,175 @@ +local function L(key, fallback) + if MultiBot and MultiBot.L then + return MultiBot.L(key, fallback) + end + + return fallback or key +end + +local function TrimText(value) + if type(value) ~= "string" then + return "" + end + + return (value:gsub("^%s+", ""):gsub("%s+$", "")) +end + +local function NormalizeDistance(value) + local distance = tonumber(TrimText(value)) + if not distance or distance <= 0 then + return nil + end + + if distance > 100 then + return nil + end + + distance = math.floor(distance * 10 + 0.5) / 10 + if distance == math.floor(distance) then + return tostring(math.floor(distance)) + end + + return tostring(distance) +end + +local function RunDisperseCommand(command) + if not MultiBot or not MultiBot.Comm or not MultiBot.Comm.RunPositionCommand then + DEFAULT_CHAT_FRAME:AddMessage(L("disperse.bridge.required", "Position bridge is not connected.")) + return false + end + + local ok = MultiBot.Comm.RunPositionCommand("ALL", "", command) + if not ok then + DEFAULT_CHAT_FRAME:AddMessage(L("disperse.bridge.required", "Position bridge is not connected.")) + end + + return ok +end + +function MultiBot.BuildDisperseUI(tLeft) + if not tLeft or MultiBot.frames.disperse then + return MultiBot.frames.disperse + end + + local lastDistance = "10" + local button + local menu = tLeft.addFrame("DisperseMenu", -238, 34, 24, 56, 96).doHide() + local menuOpen = false + menu._mbDropdownManaged = true + menu:SetWidth(56) + menu:SetHeight(96) + + local input = CreateFrame("EditBox", "MultiBotDisperseDistanceEditBox", menu, "InputBoxTemplate") + input:SetAutoFocus(false) + input:SetMaxLetters(3) + input:SetWidth(25) + input:SetHeight(20) + input:SetPoint("TOPLEFT", menu, "TOPLEFT", 30, -23) + input:SetText(lastDistance) + input:SetFrameLevel(menu:GetFrameLevel() + 3) + input:SetScript("OnEscapePressed", function(self) + self:ClearFocus() + end) + + local function setDistance() + local distance = NormalizeDistance(input:GetText()) + if not distance then + DEFAULT_CHAT_FRAME:AddMessage(L("disperse.invalid_distance", "Enter a distance between 1 and 100 yards.")) + return + end + + lastDistance = distance + input:SetText(distance) + input:ClearFocus() + RunDisperseCommand("disperse set " .. distance) + end + + input:SetScript("OnEnterPressed", function() + setDistance() + end) + + local setButton = menu.addButton("Set", -3.5, 1, "spell_nature_wispsplode", L("tips.disperse.set", "Set disperse distance")) + setButton.doLeft = setDistance + + local disableButton = menu.addButton("Disable", -3.5, 27, "spell_nature_sleep", L("tips.disperse.disable", "Disable disperse")) + disableButton.doLeft = function() + input:ClearFocus() + RunDisperseCommand("disperse disable") + end + + local function updateClickBlocker() + if MultiBot.RequestClickBlockerUpdate then + MultiBot.RequestClickBlockerUpdate(menu) + end + end + + local function setDisperseMenuChildrenShown(shown) + if shown then + input:Show() + setButton:doShow() + disableButton:doShow() + + if button then + button.setEnable() + end + else + input:Hide() + setButton:doHide() + disableButton:doHide() + + if button then + button.setDisable() + end + end + + updateClickBlocker() + end + + local function hideDisperseMenu() + input:ClearFocus() + menuOpen = false + menu:Hide() + setDisperseMenuChildrenShown(false) + end + + local function showDisperseMenu() + menuOpen = true + input:SetText(lastDistance) + menu:Show() + setDisperseMenuChildrenShown(true) + end + + menu:HookScript("OnHide", function() + menuOpen = false + setDisperseMenuChildrenShown(false) + end) + + MultiBot.frames.disperseMenu = menu + + button = tLeft.addButton("Disperse", -238, 0, "spell_nature_wispsplode", L("tips.disperse.main", "Disperse")).setDisable() + button.doLeft = function() + if menuOpen then + hideDisperseMenu() + else + showDisperseMenu() + end + end + + button.doRight = function() + hideDisperseMenu() + RunDisperseCommand("disperse disable") + end + + hideDisperseMenu() + + MultiBot.frames.disperse = button + return button +end + +function MultiBot.InitializeDisperseUI() + if not MultiBot.frames or not MultiBot.frames.tLeft then + return nil + end + + return MultiBot.BuildDisperseUI(MultiBot.frames.tLeft) +end \ No newline at end of file diff --git a/UI/MultiBotLeftCoreUI.lua b/UI/MultiBotLeftCoreUI.lua index f84a45f..139f402 100644 --- a/UI/MultiBotLeftCoreUI.lua +++ b/UI/MultiBotLeftCoreUI.lua @@ -88,6 +88,10 @@ function MultiBot.InitializeLeftCoreUI(tLeft) MultiBot.BuildBotRTIActionUI(tLeft, -238, 0) end + if MultiBot.BuildDisperseUI then + MultiBot.BuildDisperseUI(tLeft) + end + tLeft.addButton("Tanker", -170, 0, "ability_warrior_shieldbash", MultiBot.L("tips.tanker.master")).doLeft = function() if MultiBot.isTarget() then MultiBot.ActionToGroup("@tank do attack my target") @@ -100,6 +104,7 @@ function MultiBot.InitializeLeftCoreUI(tLeft) if MultiBot.BindShiftRightSwapButtons then MultiBot.BindShiftRightSwapButtons(tLeft, "LeftRoot", { { name = "BotRTI", id = "BotRTIActionButton", frameName = "BotRTIAction" }, + { name = "Disperse", frameName = "DisperseMenu" }, { name = "Tanker" }, { name = "Mode", frameName = "Mode" }, { name = "Stay" }, diff --git a/UI/MultiBotMainUI.lua b/UI/MultiBotMainUI.lua index d06c3a8..ef41651 100644 --- a/UI/MultiBotMainUI.lua +++ b/UI/MultiBotMainUI.lua @@ -1393,7 +1393,7 @@ function MultiBot.InitializeMainUI(tMultiBar) local rewardButton = createRewardButton(mainFrame) wireShiftRightSwap(rewardButton, "Reward") - + local combatStrategiesButton = createCombatStrategiesButton(mainFrame) wireShiftRightSwap(combatStrategiesButton, "CombatStrategies") diff --git a/docs/multibot_missing_commands_roadmap.md b/docs/multibot_missing_commands_roadmap.md index 79ae027..508bd60 100644 --- a/docs/multibot_missing_commands_roadmap.md +++ b/docs/multibot_missing_commands_roadmap.md @@ -9,7 +9,7 @@ Ce document suit les commandes `mod-playerbots` encore intéressantes à intégr - les commandes serveur/admin à ne pas intégrer dans l'addon ; - les priorités d'intégration bridge-first/chatless. -Le principe reste le même que pour Inventory, Spellbook, Glyphs, Talents, Stats, Quests, Outfits, RTI, Pull Control et Combat Strategies : +Le principe reste le même que pour Inventory, Spellbook, Glyphs, Talents, Stats, Quests, Outfits, RTI, Pull Control, Combat Strategies et Disperse : **éviter le spam chat automatique**, utiliser le bridge quand c'est possible, et conserver les commandes manuelles utiles comme `who`, `co ?`, `nc ?`, `ss ?`. --- @@ -32,10 +32,11 @@ Le principe reste le même que pour Inventory, Spellbook, Glyphs, Talents, Stats | RTI / Target Icons | Fait | UI complète + bridge `RUN~RTI`, scopes `ALL`, `GROUP`, `BOT`. | | Pull Control | Fait / à fignoler | Mini-frame MainBar + bridge `RUN~COMBAT`, séquences de commandes, scopes et presets. | | Combat Strategies | Fait / à tester large | Toggles individuels dans les EveryBars + mini-frame Party/Raid, via `RUN~COMBAT`. | +| Disperse | Fait / à tester large | Mini-frame MainBar + bridge `RUN~POSITION`, distance 1-100 yards et disable. | --- -## Derniers lots terminés : Pull Control + Combat Strategies +## Derniers lots terminés : Pull Control + Combat Strategies + Disperse ### Pull Control @@ -104,6 +105,34 @@ Notes fonctionnelles importantes : - `wait for attack time X` n'est pas une stratégie `co`, donc il ne faut pas attendre qu'elle apparaisse forcément dans `co ?`. - Pour les nouvelles stratégies, le test principal est le comportement réel du bot et la présence d'un `COMBAT_ACK` côté bridge, pas uniquement l'affichage dans `co ?`. +### Disperse + +Le bloc `Disperse` a été ajouté pour contrôler rapidement l'espacement collectif des bots sans repasser par le chat. + +Fonctionnalités terminées : + +- bouton `Disperse` ajouté dans la MainBar ; +- mini-frame compacte ouverte depuis le bouton `Disperse` ; +- input distance configurable ; +- validation addon des distances autorisées entre `1` et `100` yards ; +- refus des valeurs invalides ou supérieures à `100`, sans clamp silencieux ; +- bouton `Set` envoyant `disperse set ` ; +- bouton `Disable` envoyant `disperse disable` ; +- clic droit sur le bouton principal pour désactiver rapidement `Disperse` ; +- endpoint bridge `RUN~POSITION~~~~` ; +- whitelist serveur limitée aux commandes `disperse set ` et `disperse disable` ; +- application native côté serveur via les valeurs playerbots de dispersion, sans parser une réponse chat ; +- ACK bridge `POSITION_ACK` ; +- confirmation en message système après ACK : distance définie ou dispersion désactivée ; +- état visuel normal au login : bouton principal grisé, input et boutons secondaires cachés ; +- ouverture du menu dès le premier clic après login. + +À tester plus largement : + +- comportement en groupe complet et raid ; +- interaction avec les mécaniques de déplacement existantes des bots ; +- lisibilité/position exacte de la mini-frame selon les résolutions et skins UI. + --- ## Priorité 1 - RTI / Target Icons @@ -315,31 +344,45 @@ Recommandation UX conservée : ### Statut -**Prochaine étape logique.** +**Terminé côté MultiBot + bridge, à tester en conditions réelles.** ### Pourquoi Très utile pour les mécaniques AoE ou les combats où les bots doivent s'espacer. -### Commandes à couvrir +### Commandes couvertes -| Commande playerbots | Statut MultiBot | Priorité | Proposition UI | +| Commande playerbots | Statut MultiBot | Priorité | UI actuelle | |---|---:|---:|---| -| `disperse set ` | Manquant | Moyenne | Champ distance + bouton Apply | -| `disperse disable` | Manquant | Moyenne | Bouton Disable | +| `disperse set ` | Fait | Moyenne | Input distance + bouton Set | +| `disperse disable` | Fait | Moyenne | Bouton Disable + clic droit sur le bouton principal | -### Proposition UI +### UX actuelle -Section simple : +```text +MainBar +└─ Disperse + ├─ Distance: [ 10 ] + ├─ Set + └─ Disable +``` + +### Flux bridge final ```text -Disperse distance: [ 8 ] yards -[Apply] [Disable] +RUN~POSITION~ALL~~~disperse set 10 +RUN~POSITION~ALL~~~disperse disable +POSITION_ACK~ALL~~~~disperse set 10 +POSITION_ACK~ALL~~~~disperse disable ``` -### Note +### Notes -À faire après stabilisation RTI/Pull Control/Combat Strategies, sauf si un autre besoin gameplay devient prioritaire. +- `Disperse` utilise un endpoint séparé `RUN~POSITION` pour éviter de mélanger le positionnement collectif avec les stratégies combat `RUN~COMBAT`. +- La distance est validée entre `1` et `100` yards côté addon et côté bridge. +- Les valeurs invalides ou supérieures à `100` sont refusées avec un message d'erreur localisé. +- La confirmation utilisateur est affichée seulement après réception du `POSITION_ACK`. +- Aucun parsing automatique de réponse chat n'est nécessaire. --- @@ -497,7 +540,7 @@ Ces commandes sont plutôt serveur/admin/debug ou trop dangereuses pour une UI u | 1 | RTI bridge-first | UI + bridge command | Haute | Fait | | 2 | Pull Control avancé | Nouvelle UI + séquences commandes | Haute | Fait / à fignoler | | 3 | Advanced Combat Strategies | EveryBars + mini-frame Party/Raid via `RUN~COMBAT` | Haute/Moyenne | Fait / à tester | -| 4 | Disperse | Petite UI + commande combat/mouvement | Moyenne | Prochaine étape | +| 4 | Disperse | Petite UI + commande positionnement via `RUN~POSITION` | Moyenne | Fait / à tester | | 5 | Loot Rules | Petite UI profils | Moyenne | À faire | | 6 | Trainer / Maintenance extras | UI maintenance | Moyenne/Basse | À faire | | 7 | Items avancés | Extensions inventaire | Basse/Moyenne | À faire | @@ -509,25 +552,26 @@ Ces commandes sont plutôt serveur/admin/debug ou trop dangereuses pour une UI u - Toute nouvelle commande utilisée automatiquement par l'addon devrait passer par le bridge quand possible. - Les commandes manuelles informatives doivent rester fonctionnelles en whisper/party/raid. - Ne pas réintroduire de parsing chat automatique pour peupler l'UI. -- Pour les commandes qui ne nécessitent aucun retour structuré, un endpoint générique de type `RUN~COMMAND` ou un endpoint spécialisé comme `RUN~RTI` / `RUN~COMBAT` peut suffire. +- Pour les commandes qui ne nécessitent aucun retour structuré, un endpoint générique de type `RUN~COMMAND` ou un endpoint spécialisé comme `RUN~RTI` / `RUN~COMBAT` / `RUN~POSITION` peut suffire. - Pour les commandes qui doivent alimenter une frame, préférer un endpoint structuré dédié. - Les commandes serveur/admin ne doivent pas être exposées dans l'addon utilisateur. - Les boutons ajoutés dans les barres doivent conserver une position cohérente avec `MultiBotLeftCoreUI.lua` et la position par défaut de `MultiBar` dans `MultiBotInit.lua` / reset dans `MultiBotMainUI.lua`. - Les tooltips nouvellement ajoutés doivent passer par AceLocale, comme les tooltips RTI, Pull Control et Combat Strategies. -- `RUN~COMBAT` doit rester whitelisté côté bridge : ne pas en faire un exécuteur libre de n'importe quelle commande chat. +- `RUN~COMBAT` et `RUN~POSITION` doivent rester whitelistés côté bridge : ne pas en faire des exécuteurs libres de n'importe quelle commande chat. - Éviter les doublons UI : si une stratégie dispose déjà d'un bouton EveryBar dédié, ne pas la rajouter dans une nouvelle frame sauf besoin UX clairement identifié. --- ## Point logique suivant -Le prochain bloc logique est **Disperse**. +Le prochain bloc logique est **Loot Rules / Loot List**. -Raison : les blocs RTI, Pull Control et Combat Strategies couvrent maintenant le ciblage, le pull et les stratégies combat de base. `Disperse` complète naturellement ce trio en ajoutant un contrôle de positionnement collectif très utile contre les AoE et les mécaniques de donjon/raid. +Raison : les blocs RTI, Pull Control, Combat Strategies et Disperse couvrent maintenant le ciblage, le pull, les stratégies combat et le positionnement collectif. Le prochain manque gameplay utile est donc le contrôle du loot, idéalement via une petite UI de profils et des commandes bridge-first whitelistées. Proposition de prochaine itération : -- vérifier d'abord la syntaxe exacte supportée par playerbots : `disperse set ` et `disperse disable` ; -- décider si l'action doit passer par `RUN~COMBAT` ou par un endpoint plus neutre, par exemple `RUN~MOVE` / `RUN~POSITION` si on veut garder `RUN~COMBAT` réservé aux stratégies combat ; -- ajouter une mini-frame simple avec distance configurable et bouton disable ; -- garder le fonctionnement chatless, sans parsing automatique de réponse. +- vérifier la syntaxe exacte réellement supportée par playerbots pour `nc +loot`, `nc -loot` et les variantes `ll` ; +- décider si le loot doit passer par un endpoint dédié, par exemple `RUN~LOOT`, ou par un endpoint générique whitelisté ; +- ajouter une mini-frame simple avec profils `All`, `Normal`, `Gray`, `Quest`, `Skill` ; +- garder les ajouts/retraits item par item pour une itération ultérieure depuis l'inventaire bridge ; +- conserver le fonctionnement chatless, sans parsing automatique de réponse. From eb87dd7afdbc9e2ec48a7c648bcb05e88f4cc31d Mon Sep 17 00:00:00 2001 From: Alex Dcnh <140754794+Wishmaster117@users.noreply.github.com> Date: Wed, 29 Apr 2026 11:18:32 +0200 Subject: [PATCH 2/2] Update README.md --- README.md | 571 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 512 insertions(+), 59 deletions(-) diff --git a/README.md b/README.md index aacad26..efca98b 100644 --- a/README.md +++ b/README.md @@ -1,42 +1,240 @@ -image +

+ Gemini_Generated_Image_s1mnq6s1mnq6s1mn +

+ +
+ +# MultiBot Chatless + +### Bridge-first client addon for AzerothCore `mod-playerbots` + +MultiBot-Chatless is the client-side World of Warcraft 3.3.5a addon for controlling and inspecting Playerbots through a cleaner, mostly chatless UI workflow. + +
+ + + Repository + + + Bridge Module + +WoW Version +Architecture + +

+ + + + + + + + + + + + + + + + + +
ComponentRepositoryInstall Location
Client Addon + + MultiBot-Chatless + + + World of Warcraft/Interface/AddOns/MultiBot +
Server Bridge Module + + mod-multibot-bridge + + + azerothcore/modules/mod-multibot-bridge +
+ +
-# Breaking News -MultiBot has been converted to a bridge-first, mostly chatless architecture. +--- -The addon now uses `mod-multibot-bridge` to request structured data from the server instead of relying on automatic legacy chat parsing for the main UI refresh paths. Roster, states, details, stats, inventory, spellbook, glyphs, outfits and related UI data are now refreshed through `MBOT GET~...` bridge requests when the bridge is available. +## Important Notice -Manual playerbot commands are still intentionally preserved for diagnostics and gameplay actions. Commands such as `who`, `co ?`, `nc ?`, `ss ?` and similar manual whispers still work so players can request information about a bot state when they explicitly want it. +`MultiBot-Chatless` is the **addon-side repository only**. -Outfits have also been moved to the bridge-first path. Listing, creating/updating, resetting, equipping and replacing outfit sets no longer require automatic chat parsing, and the bridge suppresses the old detailed `Equipping [item] ...` spam while keeping a single readable equip/replace confirmation. +To get the new bridge-first / mostly chatless behavior, you also need the server-side AzerothCore module: -RTI, Pull Control, Combat Strategies and Disperse have been added through whitelisted bridge commands. Target icon assignment, RTI attack/pull actions, pull timing, focus/assist/AoE pull presets, selected combat strategy toggles and collective disperse positioning can now be triggered from the UI without automatic chat parsing. +
-Legacy automatic chat fallback is disabled by default: +### 👉 mod-multibot-bridge -```lua -MultiBot.allowLegacyChatFallback = false +
+ +Without the bridge module, the addon cannot use the new structured `MBOT GET~...` data flow. + +--- + +# What is MultiBot Chatless? + +MultiBot is a user interface addon for the AzerothCore [`mod-playerbots`](https://github.com/mod-playerbots/mod-playerbots) module. + +This fork focuses on removing automatic bot chat spam from the main UI refresh paths by using a dedicated AzerothCore bridge module instead of relying on legacy chat parsing. + +The addon now requests structured data from the server through `mod-multibot-bridge`. + +Examples of bridge requests: + +```text +MBOT HELLO +MBOT PING +GET~ROSTER +GET~STATES +GET~DETAILS +GET~STATS +GET~INVENTORY +GET~SPELLBOOK +GET~GLYPHS +GET~OUTFITS +RUN~RTI +RUN~COMBAT +RUN~POSITION +``` + +Manual playerbot commands are still intentionally preserved for diagnostics and gameplay actions. + +Commands such as: + +```text +who +co ? +nc ? +ss ? ``` -Set it to `true` only for temporary debugging if you need to test the old chat-based fallback behavior. +still work when the player explicitly wants to inspect a bot state. + +The goal is not to remove useful manual commands. +The goal is to remove automatic UI-refresh spam. + +--- + +# Features + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AreaStatus
Bridge handshakeImplementedHELLO, HELLO_ACK, PING, PONG
Roster refreshBridge-first
Bot statesBridge-first
Bot detailsBridge-first
StatsBridge-first
InventoryBridge-first with icons and item tooltips
SpellbookBridge-first
GlyphsBridge-first with glyph icons and tooltips
OutfitsBridge-first listing, create/update, reset, equip and replace
RTI controlsBridge-first icon assignment and RTI target actions
Pull ControlBridge-first wait, focus, DPS assist, AoE and RTI pull/attack controls
Combat strategy fine tuningBridge-first avoid AoE, save mana, threat and behind controls
Disperse controlsBridge-first distance set and disable actions through RUN~POSITION
Units / EveryBarsImproved login, reload and AddClass refresh behavior
Legacy automatic chat fallbackDisabled by default
+ +--- + +# Requirements + +## Client + +- World of Warcraft 3.3.5a / Wrath of the Lich King client. +- Tested with: + - English / US client + - German client + - French client + - Spanish client + +## Server -# MultiBot -MultiBot is a user interface addon for the AzerothCore `mod-playerbots` module by the Playerbots team: https://github.com/mod-playerbots/mod-playerbots.
-Tested with American, German, French and Spanish 3.3.5 WotLK clients. +- [`AzerothCore WotLK`](https://github.com/mod-playerbots/azerothcore-wotlk/tree/Playerbot). +- [`mod-playerbots`](https://github.com/mod-playerbots/mod-playerbots). +- [`mod-multibot-bridge`](https://github.com/Wishmaster117/mod-multibot-bridge). -This version also expects the companion server module `mod-multibot-bridge` to be installed if you want the new bridge-first/chatless UI behavior. +--- # Installation -## 1. Server-side bridge module -1. Copy the `mod-multibot-bridge` folder into your AzerothCore modules directory, next to `mod-playerbots`: +## 1. Install the server-side bridge module + +Clone the bridge module inside your AzerothCore `modules` directory: + +```bash +cd /path/to/azerothcore/modules +git clone https://github.com/Wishmaster117/mod-multibot-bridge.git mod-multibot-bridge +``` + +Expected structure: ```text -azerothcore-wotlk/modules/mod-multibot-bridge +azerothcore/ +└── modules/ + └── mod-multibot-bridge/ + ├── conf/ + └── src/ ``` -2. Re-run CMake for your AzerothCore build if your workflow requires it. -3. Rebuild the server. -4. Start the server and check that `mod-multibot-bridge` is loaded. +Then: + +1. Re-run CMake if required by your build workflow. +2. Rebuild AzerothCore. +3. Copy/install the generated configuration file if required. +4. Start the server. +5. Check that `mod-multibot-bridge` is loaded. When the addon connects successfully, the server console should show messages similar to: @@ -50,59 +248,149 @@ GET~STATES GET~DETAILS ``` -For UI actions that execute safe gameplay commands, the console may also show bridge requests such as: +--- + +## 2. Install the client addon + +Clone this repository into your World of Warcraft AddOns directory. + +```bash +cd "World of Warcraft/Interface/AddOns" +git clone https://github.com/Wishmaster117/MultiBot-Chatless.git MultiBot +``` + +Expected structure: ```text -RUN~RTI~BOT~Sahkaal~~rti skull -RUN~RTI~GROUP~1~~attack rti target -RUN~COMBAT~BOT~Sahkaal~~co +focus -RUN~COMBAT~ALL~~~co +avoid aoe -RUN~POSITION~ALL~~~disperse set 10 -RUN~POSITION~ALL~~~disperse disable +World of Warcraft/ +└── Interface/ + └── AddOns/ + └── MultiBot/ + ├── MultiBot.toc + ├── Core/ + ├── Data/ + ├── Features/ + ├── Icons/ + ├── Libs/ + ├── Locales/ + ├── Strategies/ + ├── Textures/ + └── UI/ ``` -These commands are validated by the bridge whitelist before being routed to bots. +> The GitHub repository is named `MultiBot-Chatless`, but the local addon folder must be named `MultiBot`. -## 2. Client-side addon -1. Copy the addon files into a folder named `MultiBot` inside your World of Warcraft AddOns directory: +Do not install it like this: ```text -World of Warcraft/Interface/AddOns/MultiBot +Interface/AddOns/MultiBot/MultiBot/MultiBot.toc ``` -Example on Windows: +The `.toc` file must be directly here: ```text -DRIVE:\WowClientFolder\Interface\AddOns\MultiBot +Interface/AddOns/MultiBot/MultiBot.toc ``` -2. Make sure the `.toc` file is directly inside the `MultiBot` folder. The addon should not be nested inside an extra directory such as `MultiBot/MultiBot/...`. -3. Start World of Warcraft. -4. Enable the addon on the character selection screen if needed. -5. Log in and use `/multibot`, `/mbot`, `/mb`, or the minimap button. +--- + +# Updating + +## Update the addon + +```bash +cd "World of Warcraft/Interface/AddOns/MultiBot" +git pull +``` + +## Update the bridge module + +```bash +cd /path/to/azerothcore/modules/mod-multibot-bridge +git pull +``` + +Then rebuild your AzerothCore server if the module code changed. + +--- + +# Recommended Configuration -## 3. Recommended configuration For normal bridge-first usage, keep legacy automatic chat fallback disabled: ```lua MultiBot.allowLegacyChatFallback = false ``` -Only enable it temporarily for debugging: +Only enable it temporarily for debugging or compatibility testing: ```lua MultiBot.allowLegacyChatFallback = true ``` -# Use -Start World of Warcraft and enter `/multibot`, `/mbot`, or `/mb` in the chat, or use the minimap button. +--- + +# Usage + +Start World of Warcraft and use one of the following commands: + +```text +/multibot +/mbot +/mb +``` + +You can also use the minimap button. -The addon will automatically try to connect to `mod-multibot-bridge`. If the bridge is connected, the main UI refresh paths use structured bridge messages instead of legacy chat replies. +When the bridge is available, the addon automatically uses structured bridge messages for the main UI refresh paths instead of legacy chat replies. -Manual bot information commands remain available. You can still whisper/use commands such as `who`, `co ?`, `nc ?`, `ss ?` and similar playerbot diagnostics when you explicitly want to inspect a bot state. The chatless conversion only removes the automatic UI-refresh spam; it does not remove voluntary status commands. +Manual commands are still available when you intentionally want them. + +Examples: + +```text +/w BotName who +/w BotName co ? +/w BotName nc ? +/w BotName ss ? +``` + +--- + +# Bridge-First Architecture + +
+ + + + + + + + + + + + + + + + + + + + + + +
Old behaviorNew behavior
Addon triggers bot commandsAddon sends structured MBOT GET~... requests
Bots answer with chat textBridge returns structured addon messages
Addon parses localized chat linesAddon consumes stable protocol payloads
Automatic UI refresh creates chat spamMain UI refresh paths are mostly chatless
+ +
+ +--- # Current Status -Implemented bridge-first/chatless areas: + +Implemented bridge-first / chatless areas: - Bridge handshake: `HELLO`, `HELLO_ACK`, `PING`, `PONG`. - Roster refresh. @@ -114,35 +402,200 @@ Implemented bridge-first/chatless areas: - Glyph refresh with icons and glyph tooltips. - Outfits refresh and actions through the bridge. - Outfit equip/replace without detailed `Equipping [item] ...` chat spam. -- RTI / Target Icons through `RUN~RTI` with `BOT`, `GROUP` and `ALL` scopes. -- Pull Control through `RUN~COMBAT`, including wait time, focus, DPS assist, DPS AoE, presets and RTI pull/attack actions. -- Combat Strategies through `RUN~COMBAT`, including individual EveryBar toggles and Party/Raid strategy toggles for `avoid aoe`, `save mana`, `threat` and `behind`. -- Disperse through `RUN~POSITION`, including distance set, disable action, 1-100 yards validation and bridge ACK confirmation without automatic chat parsing. -- Custom Glyphs socket mapping and apply order. +- RTI controls through the bridge. +- Pull Control frame through the bridge. +- Combat strategy fine tuning through the bridge. +- Disperse controls through the bridge with `disperse set ` and `disperse disable`. +- Custom glyph socket mapping and apply order. - Talent tab navigation stability after switching between tabs. - Automatic bot reconnect on login/reload for bots already present in the group or raid. - Units bar refresh after adding a bot through AddClass. Kept intentionally: -- Manual whisper/playerbot commands for diagnostics, including `who`, `co ?`, `nc ?`, `ss ?` and similar state-inspection commands. -- Manual gameplay commands for players who still want to control bots directly through whispers or party/raid chat. -- Whitelisted bridge gameplay actions for UI buttons that do not need structured chat parsing. +- Manual whisper/playerbot commands for diagnostics. +- Commands such as `who`, `co ?`, `nc ?`, `ss ?`. +- Gameplay write actions that still rely on existing playerbot commands. - Optional legacy fallback behavior only for debugging or compatibility. +--- + # Remaining Work -The RTI, Pull Control, Combat Strategies and Disperse passes are now implemented. The next step is final stabilization, followed by the next missing command block. + +The Outfits, RTI, Pull Control, Combat Strategy and Disperse migrations are implemented. The next step is final stabilization and cleanup. Planned follow-up work: - Regression test login, `/reload`, large raid groups, Units, EveryBars, Stats, Inventory, Spellbook, Talents, Glyphs, Outfits, RTI, Pull Control, Combat Strategies and Disperse. - Verify that `MultiBot.allowLegacyChatFallback = false` prevents automatic legacy refresh spam on all migrated UI paths. -- Keep manual diagnostic commands documented and functional, especially `who`, `co ?`, `nc ?` and `ss ?`. -- Keep `RUN~COMBAT`, `RUN~RTI` and `RUN~POSITION` strictly whitelisted in the bridge; they must not become generic unrestricted command executors. -- Remove obsolete debug prints and dead legacy parser paths once the bridge-first behavior is fully stable. +- Keep manual diagnostic commands documented and functional. +- Remove obsolete debug prints. +- Remove dead legacy parser paths once bridge-first behavior is fully stable. - Update screenshots and user documentation after wider testing. -- Next command block to evaluate: Loot Rules / Loot List, including `nc +loot`, `nc -loot` and selected `ll` profiles. --- -# Detailed Notice +# Troubleshooting + +
+The addon does not load + +Check that the folder is named exactly: + +```text +Interface/AddOns/MultiBot +``` + +and that the `.toc` file is here: + +```text +Interface/AddOns/MultiBot/MultiBot.toc +``` + +If the `.toc` file is inside another nested `MultiBot` folder, the addon is installed incorrectly. + +
+ +
+The addon loads but the bridge does not connect + +Check that: + +- `mod-multibot-bridge` is installed in the AzerothCore `modules` directory. +- AzerothCore was rebuilt after installing the module. +- The server was restarted after rebuilding. +- The bridge module is visible in server logs. +- Your client is logged into a character connected to the server. + +
+ +
+I still see some chat messages + +This project removes automatic UI-refresh spam where the bridge path has been implemented. + +Manual commands and gameplay actions may still produce intentional messages. + +Make sure this value is disabled unless you are debugging: + +```lua +MultiBot.allowLegacyChatFallback = false +``` + +
+ +
+Inventory, spellbook, glyphs or outfits do not update + +Check the server console for bridge requests such as: + +```text +GET~INVENTORY +GET~SPELLBOOK +GET~GLYPHS +GET~OUTFITS +``` + +If these requests do not appear, the addon may not be connected to the bridge. + +
+ +--- + +# Repository Layout + +```text +MultiBot-Chatless/ +├── Core/ +├── Data/ +├── Features/ +├── Icons/ +├── Libs/ +├── Locales/ +├── Strategies/ +├── Textures/ +├── UI/ +├── docs/ +└── MultiBot.toc +``` + +--- + +# Related Repositories + + + + + + + + + + + + + + + + + + + + + + +
RepositoryDescription
+ + MultiBot-Chatless + + + Client-side World of Warcraft addon. +
+ + mod-multibot-bridge + + + AzerothCore server-side bridge module. +
+ + MultiBot-Standalone + + + Deprecated combined repository kept for history. +
+ + mod-playerbots + + + Original AzerothCore Playerbots module. +
+ +--- + +# Credits + +MultiBot is built for use with AzerothCore `mod-playerbots`. + +Thanks to Macx-Lio for the original MultiBot Module. + +Thanks to the Playerbots team and the AzerothCore community. + +--- + +
+ +## MultiBot Chatless + +Less automatic chat spam. Cleaner UI refreshes. Bridge-first bot data. + +

+ + + Client Addon + + •  + + Bridge Module + + +