mirror of
https://github.com/TriM-Organization/LiteyukiBot-TriM.git
synced 2026-06-14 00:22:26 +00:00
Ⓜ️手动从旧梦 81a191f merge
This commit is contained in:
@@ -0,0 +1,274 @@
|
||||
import asyncio
|
||||
from asyncio import TimerHandle
|
||||
from typing import Any, Dict
|
||||
|
||||
import nonebot
|
||||
from nonebot import on_regex, require, on_command
|
||||
from nonebot.matcher import Matcher
|
||||
from nonebot.params import RegexDict
|
||||
from nonebot.plugin import PluginMetadata, inherit_supported_adapters
|
||||
from nonebot.rule import to_me
|
||||
from nonebot.utils import run_sync
|
||||
from nonebot.permission import SUPERUSER
|
||||
from typing_extensions import Annotated
|
||||
|
||||
require("nonebot_plugin_alconna")
|
||||
require("nonebot_plugin_session")
|
||||
|
||||
from nonebot_plugin_alconna import (
|
||||
Alconna,
|
||||
AlconnaQuery,
|
||||
Image,
|
||||
Option,
|
||||
Query,
|
||||
Text,
|
||||
UniMessage,
|
||||
on_alconna,
|
||||
store_true,
|
||||
Args,
|
||||
Arparma,
|
||||
)
|
||||
from nonebot_plugin_session import SessionId, SessionIdType
|
||||
|
||||
from .config import Config, handle_config
|
||||
from .data_source import GuessResult, Handle
|
||||
from .utils import random_idiom
|
||||
|
||||
__plugin_meta__ = PluginMetadata(
|
||||
name="猜成语",
|
||||
description="猜成语-睿乐特别版",
|
||||
usage=(
|
||||
"@我 + “猜成语”开始游戏;\n"
|
||||
"你有十次的机会猜一个四字词语;\n"
|
||||
"每次猜测后,汉字与拼音的颜色将会标识其与正确答案的区别;\n"
|
||||
"青色 表示其出现在答案中且在正确的位置;\n"
|
||||
"橙色 表示其出现在答案中但不在正确的位置;\n"
|
||||
"每个格子的 汉字、声母、韵母、声调 都会独立进行颜色的指示。\n"
|
||||
"当四个格子都为青色时,你便赢得了游戏!\n"
|
||||
"可发送“结束”结束游戏;可发送“提示”查看提示。\n"
|
||||
"使用 --strict 选项开启非默认的成语检查,即猜测的短语必须是成语,\n"
|
||||
"如:@我 猜成语 --strict"
|
||||
),
|
||||
type="application",
|
||||
homepage="https://github.com/noneplugin/nonebot-plugin-handle",
|
||||
config=Config,
|
||||
supported_adapters=inherit_supported_adapters(
|
||||
"nonebot_plugin_alconna", "nonebot_plugin_session"
|
||||
),
|
||||
extra={
|
||||
"example": "@小Q 猜成语",
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
games: Dict[str, Handle] = {}
|
||||
timers: Dict[str, TimerHandle] = {}
|
||||
|
||||
UserId = Annotated[str, SessionId(SessionIdType.GROUP)]
|
||||
|
||||
|
||||
def game_is_running(user_id: UserId) -> bool:
|
||||
return user_id in games
|
||||
|
||||
|
||||
def game_not_running(user_id: UserId) -> bool:
|
||||
return user_id not in games
|
||||
|
||||
|
||||
handle = on_alconna(
|
||||
Alconna(
|
||||
"handle",
|
||||
Option("-s|--strict", default=False, action=store_true),
|
||||
Option("-d|--hard", default=False, action=store_true),
|
||||
),
|
||||
aliases=("猜成语",),
|
||||
rule=to_me() & game_not_running,
|
||||
use_cmd_start=True,
|
||||
block=True,
|
||||
priority=13,
|
||||
)
|
||||
handle_hint = on_alconna(
|
||||
"提示",
|
||||
rule=game_is_running,
|
||||
use_cmd_start=True,
|
||||
block=True,
|
||||
priority=13,
|
||||
)
|
||||
handle_stop = on_alconna(
|
||||
"结束",
|
||||
aliases=("结束游戏", "结束猜成语"),
|
||||
rule=game_is_running,
|
||||
use_cmd_start=True,
|
||||
block=True,
|
||||
priority=13,
|
||||
)
|
||||
|
||||
handle_answer = on_alconna(
|
||||
Alconna(
|
||||
"答案",
|
||||
Option(
|
||||
"-g|--group",
|
||||
default="Now",
|
||||
args=Args["group", str, "Now"],
|
||||
),
|
||||
Option(
|
||||
"-l|--list",
|
||||
default=False,
|
||||
action=store_true,
|
||||
),
|
||||
),
|
||||
# rule=game_is_running,
|
||||
use_cmd_start=True,
|
||||
permission=SUPERUSER,
|
||||
block=True,
|
||||
priority=13,
|
||||
)
|
||||
|
||||
# handle_update = on_alconna(
|
||||
# "更新词库",
|
||||
# aliases=("刷新词库", "猜成语刷新词库"),
|
||||
# rule=to_me(),
|
||||
# use_cmd_start=True,
|
||||
# block=True,
|
||||
# priority=13,
|
||||
# )
|
||||
|
||||
|
||||
handle_idiom = on_regex(
|
||||
r"^(?P<idiom>[\u4e00-\u9fa5]{4})$",
|
||||
rule=game_is_running,
|
||||
block=True,
|
||||
priority=14,
|
||||
)
|
||||
|
||||
|
||||
def stop_game(user_id: str):
|
||||
if timer := timers.pop(user_id, None):
|
||||
timer.cancel()
|
||||
games.pop(user_id, None)
|
||||
|
||||
|
||||
async def stop_game_timeout(matcher: Matcher, user_id: str):
|
||||
game = games.get(user_id, None)
|
||||
stop_game(user_id)
|
||||
if game:
|
||||
msg = "猜成语超时,游戏结束。"
|
||||
if len(game.guessed_idiom) >= 1:
|
||||
msg += f"\n{game.result}"
|
||||
await matcher.finish(msg)
|
||||
|
||||
|
||||
def set_timeout(matcher: Matcher, user_id: str, timeout: float = 300):
|
||||
if timer := timers.get(user_id, None):
|
||||
timer.cancel()
|
||||
loop = asyncio.get_running_loop()
|
||||
timer = loop.call_later(
|
||||
timeout, lambda: asyncio.ensure_future(stop_game_timeout(matcher, user_id))
|
||||
)
|
||||
timers[user_id] = timer
|
||||
|
||||
|
||||
@handle.handle()
|
||||
async def _(
|
||||
result: Arparma,
|
||||
matcher: Matcher,
|
||||
user_id: UserId,
|
||||
):
|
||||
nonebot.logger.info(result.options)
|
||||
is_strict = handle_config.handle_strict_mode or result.options["strict"].value
|
||||
idiom, explanation = random_idiom(result.options["hard"].value)
|
||||
game = Handle(idiom, explanation, strict=is_strict)
|
||||
|
||||
games[user_id] = game
|
||||
set_timeout(matcher, user_id)
|
||||
|
||||
msg = Text(
|
||||
f"你有{game.times}次机会猜一个四字成语,"
|
||||
+ ("发送有效成语以参与游戏。" if is_strict else "发送任意四字词语以参与游戏。")
|
||||
) + Image(raw=await run_sync(game.draw)())
|
||||
await msg.send()
|
||||
|
||||
|
||||
@handle_hint.handle()
|
||||
async def _(matcher: Matcher, user_id: UserId):
|
||||
game = games[user_id]
|
||||
set_timeout(matcher, user_id)
|
||||
|
||||
await UniMessage.image(raw=await run_sync(game.draw_hint)()).send()
|
||||
|
||||
|
||||
@handle_stop.handle()
|
||||
async def _(matcher: Matcher, user_id: UserId):
|
||||
game = games[user_id]
|
||||
stop_game(user_id)
|
||||
|
||||
msg = "游戏已结束"
|
||||
if len(game.guessed_idiom) >= 1:
|
||||
msg += f"\n{game.result}"
|
||||
await matcher.finish(msg)
|
||||
|
||||
|
||||
# @handle_update.handle()
|
||||
|
||||
|
||||
@handle_idiom.handle()
|
||||
async def _(matcher: Matcher, user_id: UserId, matched: Dict[str, Any] = RegexDict()):
|
||||
game = games[user_id]
|
||||
set_timeout(matcher, user_id)
|
||||
|
||||
idiom = str(matched["idiom"])
|
||||
result = game.guess(idiom)
|
||||
|
||||
if result in [GuessResult.WIN, GuessResult.LOSS]:
|
||||
stop_game(user_id)
|
||||
msg = Text(
|
||||
(
|
||||
"恭喜你猜出了成语!"
|
||||
if result == GuessResult.WIN
|
||||
else "很遗憾,没有人猜出来呢"
|
||||
)
|
||||
+ f"\n{game.result}"
|
||||
) + Image(raw=await run_sync(game.draw)())
|
||||
await msg.send()
|
||||
|
||||
elif result == GuessResult.DUPLICATE:
|
||||
await matcher.finish("你已经猜过这个成语了呢")
|
||||
|
||||
elif result == GuessResult.ILLEGAL:
|
||||
await matcher.finish(f"你确定“{idiom}”是个成语吗?")
|
||||
|
||||
else:
|
||||
await UniMessage.image(raw=await run_sync(game.draw)()).send()
|
||||
|
||||
|
||||
@handle_answer.handle()
|
||||
async def _(
|
||||
result: Arparma,
|
||||
matcher: Matcher,
|
||||
user_id: UserId,
|
||||
):
|
||||
|
||||
if result.options["list"].value:
|
||||
await handle_answer.finish(
|
||||
UniMessage.text(
|
||||
"\n".join("{}-{}".format(i, j.idiom) for i, j in games.items())
|
||||
)
|
||||
)
|
||||
return
|
||||
|
||||
try:
|
||||
if result.options["group"].args["group"] == "Now":
|
||||
session_numstr = user_id
|
||||
else:
|
||||
session_numstr = "qq_OneBot V11_2378756507_{}".format(
|
||||
result.options["group"].args["group"]
|
||||
)
|
||||
except:
|
||||
session_numstr = user_id
|
||||
|
||||
if session_numstr in games.keys():
|
||||
await handle_answer.finish(UniMessage.text(games[session_numstr].idiom))
|
||||
else:
|
||||
await handle_answer.finish(
|
||||
UniMessage.text("{} 不存在开局的游戏".format(session_numstr))
|
||||
)
|
||||
Reference in New Issue
Block a user