Files
SimpleRemoter/server/2015Remote/McpInternal.h
T
yuanyuanxianganddeepseek-flash c99a1c375e Feature: Add MCP tools for remote chat with the client user
Add chat_open, chat_send, chat_wait and chat_close to the MCP tool set,
behind a new McpChat switch that defaults to off and is independent of
the read-only switch. The tools reuse the existing client chat link: the
main connection sends COMMAND_CHAT, the client opens a sub-connection
with TOKEN_CONN_AUTH and TOKEN_CHAT_START, the server answers with
COMMAND_NEXT_CHAT, and both directions then carry raw CP936 text.

Sessions are per host and held in shared pointers under their own mutex,
so a waiting chat_wait survives a close or a dropped sub-connection, and
chat_send is serialised per session. Text is converted strictly between
UTF-8 and CP936: invalid UTF-8, characters GBK cannot represent (emoji,
accented letters) and messages over the client's 4000-byte buffer are
rejected with -32602 instead of being mangled. A one-second settle delay
after the sub-connection binds keeps the first message from reaching the
client before its chat window exists.

The routing hooks run before the host-management hooks in MessageHandle
and clear the route in OfflineProc before the context leaves the list. A
five-second tombstone absorbs a late TOKEN_CHAT_START after a timeout, so
a failed chat_open does not pop the MFC chat dialog. Idle sessions are
swept on every tool call, and audit entries record the session id and
byte counts only, never message bodies.

The settings dialog gains the chat checkbox and the translated labels
for all three languages, and the strict UTF-8 to CP936 helpers move from
McpMachine.cpp to McpInternal so both tool families can share them.

Co-Authored-By: deepseek-flash
2026-10-23 11:19:21 +02:00

72 lines
3.1 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#pragma once
// MCP 工具实现共享的内部辅助函数。
//
// 这些函数原先都定义在 McpServer.cpp 的匿名命名空间里;主机管理 / 连接管理
// 工具族(McpMachine.cpp)需要复用同一套 JSON、host id 解析与编码转换逻辑,
// 故抽出到独立编译单元,由 McpServer.cpp 与 McpMachine.cpp 共同引用。
//
// 约定:函数语义与实现与抽取前完全一致(McpServer.cpp 通过 using-directive
// 引入,调用点不变),不做行为改动。
#include <Windows.h>
#include "jsoncpp/json.h"
#include <string>
#include <cstdint>
class CMy2015RemoteDlg;
class context;
namespace McpInternal {
// Json::Value → 紧凑 JSON 字符串
std::string JsonToString(const Json::Value& v);
// JSON-RPC 2.0 成功 / 错误响应
std::string BuildResult(const Json::Value& id, const Json::Value& result);
std::string BuildError(const Json::Value& id, int code, const std::string& msg);
// 仅 ASCII 小写化;不区分大小写的子串匹配
std::string ToLowerAscii(const std::string& s);
bool ContainsCI(const std::string& haystack, const std::string& needle);
// 入参读取
std::string JsonStrField(const Json::Value& v, const char* key);
bool IsDigits(const std::string& s);
std::string GetStringArg(const Json::Value& args, const char* key);
bool GetIntArg(const Json::Value& args, const char* key, int& out);
bool ReadUInt64(const Json::Value& v, uint64_t& out);
bool ReadUInt64Arg(const Json::Value& args, const char* key, uint64_t& out);
// 解析 id 入参(必填、纯数字)为 uint64;非法返回 false 并写 err。
bool ParseHostIdArg(const Json::Value& args, uint64_t& out, std::string& err);
// 在 m_HostList 中按 clientID 找在线主 context(锁内遍历 m_cs)。
context* FindMainContext(CMy2015RemoteDlg* parent, uint64_t id);
// 有界 strlen:p 最多可读 avail 字节,返回 n < avail 表示遇到 '\0'。
size_t BoundedStrlen(const char* p, size_t avail);
// 编码转换:任意代码页 → UTF-8(输出 JSON 用);UTF-8 → 目标代码页(下发客户端用)。
std::string ToUtf8(const char* s, UINT cp);
std::string ToAnsi(const std::string& utf8, UINT cp);
// 严格 UTF-8 → 目标代码页:任一字符无法表示即失败(不用 '?' 顶替)。
// UTF-8 本身非法也失败。聊天消息用它拒绝 GBK 不可表示的字符(emoji 等)。
bool Utf8ToCpExact(const std::string& utf8, UINT cp, std::string& out);
// 校验字节串是否为合法 UTF-8(n=0 视为合法)。
bool IsValidUtf8(const char* s, size_t n);
// 写操作审计:PostMessageA(WM_SHOWERRORMSG) 落到服务端消息/审计日志(不可关闭)。
void AuditManageAction(CMy2015RemoteDlg* parent, uint64_t devId,
const std::string& tool, const std::string& detail);
// 远程交谈审计:与 AuditManageAction 同落地方式,标题区分(MCP远程交谈)。
// 只记录会话 id / 字节数,绝不记录消息正文。
void AuditChatAction(CMy2015RemoteDlg* parent, uint64_t devId,
const std::string& tool, const std::string& detail);
} // namespace McpInternal