44048b333a
thinker.go: 移除所有 defer t.muUnlock() 持锁跨阻塞调用的模式,消除8处死锁点 - performThink: defer→立即解锁,LLM调用不再持锁 - lightThinkLoop: defer在for循环内→第2次迭代自死锁 - resetSilenceTimer: defer持锁调performThink - UpdatePresence: defer持锁调time.Sleep+performThink - storeThought: defer+panic→锁泄露; 移除extractProactiveMessage嵌套锁 is_admin三层防御: - synthesizer: 系统提示词注入管理员/非管理员身份标签 - iot_provider: 非管理员直接拒绝IoT操作 - plugin-manager: ToolDefinition.AdminOnly自动拦截,集中管控 群聊优化: - group_ambient: 强化审查指令,【不发送】自审查标签 - 群聊间隔4s→3s,最多2条/轮 - 工具失败也推跟进消息,避免沉默 平台桥接: - 日志文件名使用适配器唯一标识符(ConfigName) - QQ表情映射替换为官方116条目数据 - CQ表情保留名称/ID
208 lines
4.9 KiB
Python
208 lines
4.9 KiB
Python
#!/usr/bin/env python3
|
|
"""Add qqFaceName map and resolveFaceName function to adapter.go using official QQ Bot API data."""
|
|
|
|
# Official QQ Bot API Emoji List
|
|
OFFICIAL_DATA = """1 4 得意
|
|
1 5 流泪
|
|
1 8 睡
|
|
1 9 大哭
|
|
1 10 尴尬
|
|
1 12 调皮
|
|
1 14 微笑
|
|
1 16 酷
|
|
1 21 可爱
|
|
1 23 傲慢
|
|
1 24 饥饿
|
|
1 25 困
|
|
1 26 惊恐
|
|
1 27 流汗
|
|
1 28 憨笑
|
|
1 29 悠闲
|
|
1 30 奋斗
|
|
1 32 疑问
|
|
1 33 嘘
|
|
1 34 晕
|
|
1 38 敲打
|
|
1 39 再见
|
|
1 41 发抖
|
|
1 42 爱情
|
|
1 43 跳跳
|
|
1 49 拥抱
|
|
1 53 蛋糕
|
|
1 60 咖啡
|
|
1 63 玫瑰
|
|
1 66 爱心
|
|
1 74 太阳
|
|
1 75 月亮
|
|
1 76 赞
|
|
1 78 握手
|
|
1 79 胜利
|
|
1 85 飞吻
|
|
1 89 西瓜
|
|
1 96 冷汗
|
|
1 97 擦汗
|
|
1 98 抠鼻
|
|
1 99 鼓掌
|
|
1 100 糗大了
|
|
1 101 坏笑
|
|
1 102 左哼哼
|
|
1 103 右哼哼
|
|
1 104 哈欠
|
|
1 106 委屈
|
|
1 109 左亲亲
|
|
1 111 可怜
|
|
1 116 示爱
|
|
1 118 抱拳
|
|
1 120 拳头
|
|
1 122 爱你
|
|
1 123 NO
|
|
1 124 OK
|
|
1 125 转圈
|
|
1 129 挥手
|
|
1 144 喝彩
|
|
1 147 棒棒糖
|
|
1 171 茶
|
|
1 173 泪奔
|
|
1 174 无奈
|
|
1 175 卖萌
|
|
1 176 小纠结
|
|
1 179 doge
|
|
1 180 惊喜
|
|
1 181 骚扰
|
|
1 182 笑哭
|
|
1 183 我最美
|
|
1 201 点赞
|
|
1 203 托脸
|
|
1 212 托腮
|
|
1 214 啵啵
|
|
1 219 蹭一蹭
|
|
1 222 抱抱
|
|
1 227 拍手
|
|
1 232 佛系
|
|
1 240 喷脸
|
|
1 243 甩头
|
|
1 246 加油抱抱
|
|
1 262 脑阔疼
|
|
1 264 捂脸
|
|
1 265 辣眼睛
|
|
1 266 哦哟
|
|
1 267 头秃
|
|
1 268 问号脸
|
|
1 269 暗中观察
|
|
1 270 emm
|
|
1 271 吃瓜
|
|
1 272 呵呵哒
|
|
1 273 我酸了
|
|
1 277 汪汪
|
|
1 278 汗
|
|
1 281 无眼笑
|
|
1 282 敬礼
|
|
1 284 面无表情
|
|
1 285 摸鱼
|
|
1 287 哦
|
|
1 289 睁眼
|
|
1 290 敲开心
|
|
1 293 摸锦鲤
|
|
1 294 期待
|
|
1 297 拜谢
|
|
1 298 元宝
|
|
1 299 牛啊
|
|
1 305 右亲亲
|
|
1 306 牛气冲天
|
|
1 307 喵喵
|
|
1 314 仔细分析
|
|
1 315 加油
|
|
1 318 崇拜
|
|
1 319 比心
|
|
1 320 庆祝
|
|
1 322 拒绝
|
|
1 324 吃糖
|
|
1 326 生气"""
|
|
|
|
ADAPTER_PATH = "d:/Project/Code/Uni/Cyrene/backend/platform-bridge/internal/adapter/qq/adapter.go"
|
|
|
|
with open(ADAPTER_PATH, "r", encoding="utf-8") as f:
|
|
content = f.read()
|
|
|
|
# Build face map
|
|
entries = []
|
|
for line in OFFICIAL_DATA.strip().split("\n"):
|
|
parts = line.split("\t")
|
|
if len(parts) == 3 and parts[0] == "1":
|
|
entries.append((int(parts[1]), parts[2]))
|
|
entries.sort(key=lambda x: x[0])
|
|
|
|
map_code = []
|
|
map_code.append("")
|
|
map_code.append("// qqFaceName maps QQ face/emoji IDs to their Chinese names.")
|
|
map_code.append("// Source: Official QQ Bot API Emoji List (https://bot.q.qq.com/wiki/develop/api-v2/openapi/emoji/model.html)")
|
|
map_code.append("var qqFaceName = map[string]string{")
|
|
for i, (eid, name) in enumerate(entries):
|
|
comma = "," if i < len(entries) - 1 else ","
|
|
map_code.append(f'\t"{eid}": "{name}"{comma}')
|
|
map_code.append("}")
|
|
map_code.append("")
|
|
map_code.append("// resolveFaceName returns the display name for a face CQ code.")
|
|
map_code.append("// Uses name field if present (NapCat array format), otherwise looks up the face ID in qqFaceName map.")
|
|
map_code.append("func resolveFaceName(match string) string {")
|
|
map_code.append('\tif name := extractCQParam(match, "name"); name != "" {')
|
|
map_code.append('\t\treturn name')
|
|
map_code.append('\t}')
|
|
map_code.append('\tif id := extractCQParam(match, "id"); id != "" {')
|
|
map_code.append('\t\tif name, ok := qqFaceName[id]; ok {')
|
|
map_code.append('\t\t\treturn name')
|
|
map_code.append('\t\t}')
|
|
map_code.append('\t\treturn id')
|
|
map_code.append('\t}')
|
|
map_code.append('\treturn ""')
|
|
map_code.append("}")
|
|
|
|
new_block = "\n".join(map_code)
|
|
|
|
# 1. Update simplifyCQCodes to handle face with name
|
|
# Old: if label, ok := cqSimplifyMap[typ]; ok { return label }
|
|
# New: add face handling before the generic lookup
|
|
old_simplify = '''\t\tif label, ok := cqSimplifyMap[typ]; ok {
|
|
\t\t\treturn label
|
|
\t\t}'''
|
|
new_simplify = '''\t\tif typ == "face" {
|
|
\t\t\tfaceName := resolveFaceName(match)
|
|
\t\t\tif faceName != "" {
|
|
\t\t\t\treturn "[表情 " + faceName + "]"
|
|
\t\t\t}
|
|
\t\t\treturn "[表情]"
|
|
\t\t}
|
|
\t\tif label, ok := cqSimplifyMap[typ]; ok {
|
|
\t\t\treturn label
|
|
\t\t}'''
|
|
content = content.replace(old_simplify, new_simplify)
|
|
|
|
# 2. Update array-format face handler to use qqFaceName
|
|
old_face_array = '''\t\t\tcase "face":
|
|
\t\t\t\ttext += "[表情]"'''
|
|
new_face_array = '''\t\t\tcase "face":
|
|
\t\t\t\tfaceName := ""
|
|
\t\t\t\tif data, ok := s["data"].(map[string]interface{}); ok {
|
|
\t\t\t\t\tif name, ok := data["name"].(string); ok && name != "" {
|
|
\t\t\t\t\t\tfaceName = " " + name
|
|
\t\t\t\t\t} else if id, ok := data["id"].(string); ok && id != "" {
|
|
\t\t\t\t\t\tif mapped, ok2 := qqFaceName[id]; ok2 {
|
|
\t\t\t\t\t\t\tfaceName = " " + mapped
|
|
\t\t\t\t\t\t} else {
|
|
\t\t\t\t\t\t\tfaceName = " " + id
|
|
\t\t\t\t\t\t}
|
|
\t\t\t\t\t}
|
|
\t\t\t\t}
|
|
\t\t\t\ttext += "[表情" + faceName + "]"'''
|
|
content = content.replace(old_face_array, new_face_array)
|
|
|
|
# 3. Insert the face map and resolveFaceName function after cqSimplifyMap
|
|
insert_after = "}\n\n// simplifyCQCodes"
|
|
insert_idx = content.index(insert_after) + 1 # after the closing }
|
|
content = content[:insert_idx] + new_block + content[insert_idx:]
|
|
|
|
with open(ADAPTER_PATH, "w", encoding="utf-8") as f:
|
|
f.write(content)
|
|
|
|
print(f"Updated with {len(entries)} official QQ emoji entries")
|