- hexi core: message handling, rate limiting, cooldown, plugin manager - Custom plugins: BF stats, daily check-in, quotes, persona cards, etc. - Community plugins vendored under hexi/plugins with local fixes - Web admin frontends (learning-chat, persona-admin), unified hexi/web - Tests for rate_limit/cooldown/memes/persona; poetry.lock Co-Authored-By: Claude <noreply@anthropic.com>
50 lines
1.6 KiB
Python
50 lines
1.6 KiB
Python
import random
|
|
|
|
from nonebot import on_message, require
|
|
from nonebot.adapters.onebot.v11 import GroupMessageEvent
|
|
from nonebot.log import logger
|
|
|
|
require("nonebot_plugin_alconna")
|
|
from nonebot_plugin_alconna import UniMessage
|
|
|
|
PROB_A = 1.4
|
|
# group_id: (last_msg, is_repeated, p)
|
|
group_stat: dict[int, tuple[str, bool, float]] = {}
|
|
|
|
"""
|
|
不复读率 随 复读次数 指数级衰减
|
|
从第2条复读,即第3条重复消息开始有几率触发复读
|
|
|
|
a 设为一个略大于1的小数,最好不要超过2,建议1.6
|
|
复读概率计算式:p_n = 1 - 1/a^n
|
|
递推式:p_n+1 = 1 - (1 - p_n) / a
|
|
"""
|
|
|
|
repeater = on_message(block=False)
|
|
|
|
|
|
@repeater.handle()
|
|
async def repeater_handle(ev: GroupMessageEvent):
|
|
group_id = ev.group_id
|
|
msg = str(ev.message)
|
|
|
|
if group_id not in group_stat:
|
|
group_stat[group_id] = (msg, False, 0.0)
|
|
return
|
|
|
|
last_msg, is_repeated, p = group_stat[group_id]
|
|
if last_msg == msg: # 群友正在复读
|
|
if not is_repeated: # 机器人尚未复读过,开始测试复读
|
|
if random.random() < p: # 概率测试通过,复读并设 flag
|
|
try:
|
|
group_stat[group_id] = (msg, True, 0.0)
|
|
await UniMessage.text(ev.message.extract_plain_text()).send()
|
|
except Exception as e:
|
|
logger.error(f"复读失败: {type(e)}")
|
|
logger.exception(e)
|
|
else: # 概率测试失败,蓄力
|
|
p = 1 - (1 - p) / PROB_A
|
|
group_stat[group_id] = (msg, False, p)
|
|
else: # 不是复读,重置
|
|
group_stat[group_id] = (msg, False, 0.0)
|