feat:初版
This commit is contained in:
137
docs/MemoryBank/02-开发日志.md
Normal file
137
docs/MemoryBank/02-开发日志.md
Normal file
@@ -0,0 +1,137 @@
|
||||
# 开发日志
|
||||
|
||||
## 2025-11-12
|
||||
|
||||
### 项目初始化
|
||||
- ✅ 创建 WechatHookBot 项目结构
|
||||
- ✅ 从 XYBot 复制 utils 和 database 模块
|
||||
- ✅ 设计技术架构文档
|
||||
|
||||
### Hook API 集成
|
||||
- ✅ 封装 NoveLoader (Loader.dll)
|
||||
- ✅ 封装 WechatHookClient (API 客户端)
|
||||
- ✅ 实现消息类型映射和格式转换
|
||||
- ✅ 实现回调处理机制
|
||||
|
||||
### 启动调试
|
||||
**问题**: 回调未触发,无法接收消息
|
||||
- ❌ 尝试1: 调整回调注册顺序 - 失败
|
||||
- ❌ 尝试2: 修改事件循环处理 - 失败
|
||||
- ✅ 解决: 添加共享内存创建 (`create_shared_memory`)
|
||||
- 关键发现: DLL 需要共享内存进行通信
|
||||
- 参考官方 Demo 第 357-365 行
|
||||
|
||||
**问题**: Socket 客户端 ID 混淆
|
||||
- ❌ 使用进程 ID 发送消息 - 失败
|
||||
- ✅ 解决: 区分进程 ID 和 Socket 客户端 ID
|
||||
- `InjectWeChat` 返回进程 ID
|
||||
- 回调中的 `client_id` 是 Socket ID (通常为 1)
|
||||
|
||||
**问题**: 登录信息获取失败
|
||||
- ❌ 使用 type=11028 - 错误
|
||||
- ✅ 解决: 实际类型是 type=11025
|
||||
- 登录信息在注入后自动推送
|
||||
- 包含 wxid, nickname, account, avatar 等字段
|
||||
|
||||
**问题**: 消息类型映射错误
|
||||
- ❌ 使用 10001-10013 - 错误
|
||||
- ✅ 解决: 实际类型是 11046-11061
|
||||
- 文本消息: 11046
|
||||
- 图片消息: 11047
|
||||
- 其他类型依次递增
|
||||
|
||||
**问题**: 群聊消息处理失败
|
||||
- ❌ 使用 `from_wxid` 判断群聊 - 错误
|
||||
- ✅ 解决: 使用 `room_wxid` 字段判断
|
||||
- 群聊消息: `room_wxid` 不为空
|
||||
- 私聊消息: `room_wxid` 为空
|
||||
- 消息内容字段: `msg` (不是 `content`)
|
||||
|
||||
### 插件开发
|
||||
|
||||
#### AIChat 插件
|
||||
- ✅ 支持自定义 API 配置
|
||||
- ✅ 支持人设切换 (txt 文件)
|
||||
- ✅ 三种触发模式: all/mention/keyword
|
||||
- ✅ 群聊/私聊分别控制
|
||||
|
||||
**问题**: 插件配置未加载
|
||||
- ❌ 使用 `on_load` 方法 - 失败
|
||||
- ✅ 解决: 使用 `async_init` 方法
|
||||
- 插件基类只支持 `async_init`
|
||||
- `on_enable` 用于定时任务注册
|
||||
|
||||
#### ManagePlugin 插件
|
||||
- ✅ 插件列表查看
|
||||
- ✅ 热重载功能
|
||||
- ✅ 启用/禁用插件
|
||||
- ✅ 权限控制(管理员)
|
||||
|
||||
**命令列表**:
|
||||
- `/插件列表` - 查看所有插件状态
|
||||
- `/重载插件 <名称>` - 热重载指定插件
|
||||
- `/启用插件 <名称>` - 启用插件
|
||||
- `/禁用插件 <名称>` - 禁用插件
|
||||
|
||||
### 依赖管理
|
||||
**最终依赖**:
|
||||
```
|
||||
loguru==0.7.3
|
||||
APScheduler==3.11.0
|
||||
aiohttp==3.9.1
|
||||
```
|
||||
|
||||
**移除的依赖**:
|
||||
- SQLAlchemy (需要 C++ 编译)
|
||||
- eventlet (msgspec 不支持 32 位)
|
||||
- Flask (不需要 WebUI)
|
||||
|
||||
### 关键技术点
|
||||
|
||||
1. **共享内存创建**
|
||||
```python
|
||||
def create_shared_memory():
|
||||
kernel32 = ctypes.WinDLL('kernel32')
|
||||
file_handle = kernel32.CreateFileMappingA(-1, None, 4, 0, 33,
|
||||
"windows_shell_global__".encode('utf-8'))
|
||||
data_address = kernel32.MapViewOfFile(file_handle, 983071, 0, 0, 0)
|
||||
key = "3101b223dca7715b0154924f0eeeee20".encode('utf-8')
|
||||
kernel32.RtlMoveMemory(data_address, key, len(key))
|
||||
```
|
||||
|
||||
2. **异步回调处理**
|
||||
```python
|
||||
# 在回调线程中使用事件循环
|
||||
asyncio.run_coroutine_threadsafe(
|
||||
self.hookbot.process_message(msg_type, data),
|
||||
self.event_loop
|
||||
)
|
||||
```
|
||||
|
||||
3. **消息格式转换**
|
||||
```python
|
||||
# 群聊判断
|
||||
room_wxid = data.get("room_wxid", "")
|
||||
if room_wxid:
|
||||
message["IsGroup"] = True
|
||||
message["FromWxid"] = room_wxid
|
||||
message["SenderWxid"] = data.get("from_wxid", "")
|
||||
```
|
||||
|
||||
### 测试结果
|
||||
|
||||
✅ **成功测试**:
|
||||
- 机器人启动和注入
|
||||
- 登录信息获取
|
||||
- 私聊消息接收
|
||||
- 群聊消息接收
|
||||
- ping-pong 测试
|
||||
- 插件管理命令
|
||||
- AI 聊天功能
|
||||
|
||||
### 下一步计划
|
||||
|
||||
1. 完善插件功能
|
||||
2. 添加更多消息类型支持
|
||||
3. 优化错误处理
|
||||
4. 编写使用文档
|
||||
Reference in New Issue
Block a user