kexue-z / nonebot-plugin-heweather

MIT License
63 stars 11 forks source link

【Bug】bot收到表情、图片、字符消息过长会导致nonebot2项目卡死 #46

Closed KaMmySuma closed 1 year ago

KaMmySuma commented 1 year ago

事情的起因是这样的:https://github.com/Todysheep/nonebot_plugin_bottle/issues/33 不止我一人遇到该问题:https://github.com/kexue-z/nonebot-plugin-heweather/issues/41 后来我单独进行测试,发现只要表情过长都会导致bot卡死。

仅安装heweather,向bot发送以下消息: image

随后bot卡死,gocq可以正常收到消息,但是powershell不再响应新消息: image

卸除heweather后,问题不再复现,nonebot可以正常接收长消息

KaMmySuma commented 1 year ago

似乎是触发命令的正则匹配规则导致的。我仅修改命令的触发方式后,问题不再复现: 以下是我尝试修改的片段: ——原代码:——

weather = on_regex(r".*?(.*)天气(.*).*?", priority=1)

@weather.handle()
async def _(matcher: Matcher, args: Tuple[str, ...] = RegexGroup()):
    city = args[0].strip() or args[1].strip()
    if not city:
        await weather.finish("地点是...空气吗?? >_<")

    # 判断指令前后是否都有内容,如果是则结束,否则跳过。
    if ((args[0].strip() == '') == (args[1].strip() == '')):
        await weather.finish()

    w_data = Weather(city_name=city, api_key=api_key, api_type=api_type)

——修改为:——

weather = on_command("天气", priority=1)

@weather.handle()
async def _(matcher: Matcher, city: Message = CommandArg()):
    if not city:
        await weather.finish("地点是...空气吗?? >_<")
    w_data = Weather(city_name=city, api_key=api_key, api_type=api_type)

但是这样必须以命令开头才能查询,不大顺口,不知道还有没更好的方式实现

Well2333 commented 1 year ago

可以尝试 on_keyword抓取到消息,然后在采用正则表达式提取地名,例如

weather = on_keyword({"天气",}, priority=1)

@weather.handle()
async def _(matcher: Matcher, event: V11_GME):
    if args := re.search(
        r".*?(.*)天气(.*).*?", event.get_plaintext()  # type: ignore
    ):
        city = args[0].strip() or args[1].strip()
        if not city:
            await weather.finish("地点是...空气吗?? >_<")

        # 判断指令前后是否都有内容,如果是则结束,否则跳过。
        if ((args[0].strip() == '') == (args[1].strip() == '')):
            await weather.finish()

        w_data = Weather(city_name=city, api_key=api_key, api_type=api_type)
kexue-z commented 1 year ago

@Well2333 立即pr

ElainaFanBoy commented 1 year ago

可以尝试 on_keyword抓取到消息,然后在采用正则表达式提取地名,例如

weather = on_keyword({"天气",}, priority=1)

@weather.handle()
async def _(matcher: Matcher, event: V11_GME):
    if args := re.search(
        r".*?(.*)天气(.*).*?", event.get_plaintext()  # type: ignore
    ):
        city = args[0].strip() or args[1].strip()
        if not city:
            await weather.finish("地点是...空气吗?? >_<")

        # 判断指令前后是否都有内容,如果是则结束,否则跳过。
        if ((args[0].strip() == '') == (args[1].strip() == '')):
            await weather.finish()

        w_data = Weather(city_name=city, api_key=api_key, api_type=api_type)

问题已解决,感谢