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)
|