Feature: Add list_files and get_screenshot MCP tools
Add the two P2c MCP tools on top of the P2b protocol. list_files lists drives (COMMAND_LIST_DRIVE -> TOKEN_DRIVE_LIST) or a directory (follow-up COMMAND_LIST_FILES -> TOKEN_FILE_LIST on the same one-shot sub-link); get_screenshot reuses the screen-preview RPC with a per-host reqId correlation so stale or MFC-preview responses fall through to the MFC path untouched. Both share the P2b single-flight pending registry. Fix file/process name encoding: the client reads process names, paths and file names via the ANSI (A) APIs, so they are GBK on Windows regardless of the CLIENT_CAP_UTF8 capability bit (which governs window titles only). Decode by clientType (LNX/MAC = UTF-8, Windows = 936) rather than GetClientEncoding, and convert the list_files path to the client ANSI code page before sending. Sync Mcp_Phase2_Design.md with the P2c design and the encoding correction. Co-Authored-By: deepseek-v4-pro
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
#pragma comment(lib, "ws2_32.lib")
|
||||
|
||||
class CMy2015RemoteDlg;
|
||||
class context;
|
||||
|
||||
// MCP (Model Context Protocol) 服务端:httplib 封装 + JSON-RPC 2.0 分发 + 静态 token 校验。
|
||||
// 与 CWebService 平级、互不依赖;默认禁用,经「扩展 → MCP设置」开启后监听
|
||||
@@ -62,6 +63,26 @@ public:
|
||||
// 工具线程:清理挂起状态(发送失败等提前退出路径)。
|
||||
void ClearPending(uint64_t device_id);
|
||||
|
||||
// ===== P2c:list_files / get_screenshot 扩展 =====
|
||||
|
||||
// 登记挂起(带目录路径;list_files 专用,path 为空表示只列盘)。
|
||||
bool BeginPending(uint64_t device_id, const std::string& tool, const std::string& path);
|
||||
|
||||
// get_screenshot:工具线程生成 16 位 reqId(跳过 0,0 表示未设置),用于丢弃过期响应。
|
||||
uint16_t NextPreviewReqId();
|
||||
|
||||
// get_screenshot:登记期望的 reqId(必须在发送 COMMAND_SCREEN_PREVIEW_REQ 前调用)。
|
||||
void SetPendingReqId(uint64_t device_id, uint16_t reqId);
|
||||
|
||||
// get_screenshot:MessageHandle(TOKEN_SCREEN_PREVIEW_RSP) 在 IO 线程同步调用;
|
||||
// 挂起命中且 reqId 一致则拷贝响应并返回 true,否则 false(回落到 MFC 预览路径)。
|
||||
bool TakePreviewResponse(uint64_t device_id, uint16_t reqId, const BYTE* data, ULONG len);
|
||||
|
||||
// list_files:MessageHandle(TOKEN_DRIVE_LIST) 调用。
|
||||
// 返回 true = 已取走盘列表(调用方 CancelIO);false = 已转向下发 COMMAND_LIST_FILES、
|
||||
// 等 TOKEN_FILE_LIST(调用方不关子链接)。
|
||||
bool OnDriveList(uint64_t device_id, context* subCtx, const BYTE* buf, ULONG len);
|
||||
|
||||
private:
|
||||
CMcpServer();
|
||||
~CMcpServer();
|
||||
@@ -80,12 +101,17 @@ private:
|
||||
// 挂起请求注册表(受 m_PendingMutex 保护,键 = device_id)。
|
||||
struct PendingRequest {
|
||||
std::string tool;
|
||||
std::string path; // list_files:目录路径;空 = 只列盘
|
||||
uint16_t expectedReqId = 0; // get_screenshot:期望的预览 reqId(0 = 未设置)
|
||||
std::vector<BYTE> data;
|
||||
bool done = false;
|
||||
};
|
||||
std::mutex m_PendingMutex;
|
||||
std::condition_variable m_PendingCv;
|
||||
std::map<uint64_t, PendingRequest> m_Pending;
|
||||
|
||||
// get_screenshot 的 reqId 发生器(16 位,跳过 0)。与 MFC 预览的 m_PreviewReqId 各自独立计数。
|
||||
std::atomic<uint16_t> m_PreviewReqId{1};
|
||||
};
|
||||
|
||||
// 全局访问器(仿 WebService(),见 WebService.h 末尾)
|
||||
|
||||
Reference in New Issue
Block a user