From 28dbbf095b03624936d6cce0134336d8828df4c6 Mon Sep 17 00:00:00 2001 From: James Huston Date: Sun, 14 Dec 2025 22:29:45 -0500 Subject: [PATCH] MCP: Add ChatHandler fallback for GM commands, add code commenting guidelines - ServerTools.cpp: Use ChatHandler::ParseCommands() as fallback for any unhandled GM command - ServerTools.cpp: Add leading dot to commands for ChatHandler compatibility - ServerTools.cpp: Add detailed header comments about GM command implementation pattern - AGENTS.md: Add code commenting guidelines section --- AGENTS.md | 30 +++++++++ src/araxiaonline/mcp/ServerTools.cpp | 99 ++++++++++++++++++++++++++-- 2 files changed, 122 insertions(+), 7 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 544c529718..34d3da1311 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -15,3 +15,33 @@ This project is a fork of Trinity Core, a World of Warcraft server emulator. We are currently in the process of getting the Eluna addon working with the master branch. Documentation with status can be found in [ELUNA_INTEGRATION_COMPLETE.md](ELUNA_INTEGRATION_COMPLETE.md), [GLOBAL_ELUNA_PLAN.md](GLOBAL_ELUNA_PLAN.md), and [VALIDATION_SUMMARY.md](VALIDATION_SUMMARY.md). Please consult them before tacking any new tasks. All tasks should be tracked in these files. + +--- + +## Code Commenting Guidelines + +**ALWAYS add comments when modifying C++ code in this project.** + +### Why? +- Context is lost between sessions +- Future AI assistants (and humans) need to understand design decisions +- Prevents reimplementing the same solutions repeatedly +- Code comments stay close to the implementation + +### What to Comment: +1. **File headers** - Document the purpose and any important patterns used +2. **Non-obvious design decisions** - Why did you choose this approach? +3. **Integration patterns** - How does this code interact with TrinityCore systems? +4. **Gotchas and warnings** - What mistakes should be avoided? + +### Example Pattern (MCP GM Commands): +```cpp +// PREFER ChatHandler::ParseCommands() over reimplementing GM command logic +// This allows ANY existing command to work without custom code +ChatHandler handler(player->GetSession()); +handler.ParseCommands(command); +``` + +### Key Files with Important Comments: +- `src/araxiaonline/mcp/ServerTools.cpp` - GM command implementation pattern +- `src/araxiaonline/mcp/AraxiaMCPServer.cpp` - MCP server architecture diff --git a/src/araxiaonline/mcp/ServerTools.cpp b/src/araxiaonline/mcp/ServerTools.cpp index fef72b74e3..837afdeb93 100644 --- a/src/araxiaonline/mcp/ServerTools.cpp +++ b/src/araxiaonline/mcp/ServerTools.cpp @@ -2,6 +2,33 @@ * Araxia MCP Server - Server Tools * * Basic server information and control tools. + * + * ============================================================================= + * IMPORTANT: GM Command Implementation Pattern + * ============================================================================= + * + * When adding new GM commands to gm_command tool: + * + * 1. PREFER using ChatHandler::ParseCommands() as a fallback rather than + * reimplementing command logic. This allows ANY existing GM command to + * work through MCP without custom code. + * + * 2. Only implement custom handlers when you need: + * - Structured JSON response with specific data (e.g., coordinates from "gps") + * - Custom error handling or validation + * - Modified behavior from the standard command + * + * 3. The fallback pattern at the end of gm_command: + * ```cpp + * ChatHandler handler(player->GetSession()); + * bool success = handler.ParseCommands(command); + * ``` + * This executes the command exactly as if typed in-game with a leading dot. + * + * 4. Available GM commands are defined in src/server/scripts/Commands/cs_*.cpp + * Check there for command names and required permissions. + * + * ============================================================================= */ #include "AraxiaMCPServer.h" @@ -21,6 +48,9 @@ #include "Creature.h" #include "SpellMgr.h" #include "SpellInfo.h" +#include "ObjectMgr.h" +#include "SmartScriptMgr.h" +#include "Chat.h" #include namespace Araxia @@ -446,6 +476,47 @@ void RegisterServerTools() }; } } + // Handle: reload - Reload various data from database + else if (cmd == "reload") + { + std::string reloadType; + iss >> reloadType; + + if (reloadType.empty()) + { + return { + {"success", false}, + {"error", "Usage: reload "}, + {"supported_types", {"smart_scripts", "creature_template", "game_tele"}} + }; + } + + TC_LOG_INFO("araxia.mcp", "[MCP] Reloading: {}", reloadType); + + if (reloadType == "smart_scripts" || reloadType == "smartai" || reloadType == "smart") + { + sSmartScriptMgr->LoadSmartAIFromDB(); + return {{"success", true}, {"command", "reload"}, {"type", "smart_scripts"}, {"message", "SmartAI scripts reloaded from database"}}; + } + else if (reloadType == "creature" || reloadType == "creature_template") + { + sObjectMgr->LoadCreatureTemplates(); + return {{"success", true}, {"command", "reload"}, {"type", "creature_template"}, {"message", "Creature templates reloaded. Note: Existing spawns need server restart."}}; + } + else if (reloadType == "game_tele" || reloadType == "tele") + { + sObjectMgr->LoadGameTele(); + return {{"success", true}, {"command", "reload"}, {"type", "game_tele"}, {"message", "Teleport locations reloaded"}}; + } + else + { + return { + {"success", false}, + {"error", "Unknown reload type: " + reloadType}, + {"supported_types", {"smart_scripts", "creature_template", "game_tele"}} + }; + } + } // Handle: levelup [level] - Level up player to specified level (or +1 if no level given) else if (cmd == "levelup") { @@ -478,13 +549,27 @@ void RegisterServerTools() }; } - // Unknown command - return { - {"success", false}, - {"error", "Unknown or unimplemented command"}, - {"command", cmd}, - {"supported", {"go xyz", "tele", "gps", "additem", "die", "revive", "aura", "unaura", "learn", "unlearn", "respawn", "levelup"}} - }; + // Fallback: Pass any unhandled command to ChatHandler (existing GM command system) + // This allows MCP to execute ANY GM command without reimplementing logic + // NOTE: ChatHandler::ParseCommands expects commands WITH leading dot (e.g., ".npc add") + else + { + ChatHandler handler(player->GetSession()); + std::string dotCommand = "." + command; // Add leading dot for ChatHandler + bool success = handler.ParseCommands(dotCommand); + + TC_LOG_INFO("araxia.mcp", "[MCP] Executed via ChatHandler: {} (success: {})", command, success); + + return { + {"success", success}, + {"command", command}, + {"method", "ChatHandler"}, + {"message", success ? "Command executed via GM command system" : "Command failed or unknown"} + }; + } + + // Unreachable - but satisfies compiler warning about all paths returning + return {{"success", false}, {"error", "Unreachable code path"}}; } );