forked from mttu-developers/konabot
添加中间答案功能
This commit is contained in:
@ -7,3 +7,5 @@
|
|||||||
- 例如:/^commit$/ 会匹配 commit,不会匹配 acommit、Commit 等。
|
- 例如:/^commit$/ 会匹配 commit,不会匹配 acommit、Commit 等。
|
||||||
- 而如果是 /commit/,则会匹配 commit、acommit,而不会匹配 Commit。
|
- 而如果是 /commit/,则会匹配 commit、acommit,而不会匹配 Commit。
|
||||||
- 无法使用 Javascript 的字符串声明模式,例如,/case_insensitive/i 就不会被视作一个正则表达式。
|
- 无法使用 Javascript 的字符串声明模式,例如,/case_insensitive/i 就不会被视作一个正则表达式。
|
||||||
|
|
||||||
|
一个提示是提示,还是中间答案,取决于它是否有 checkpoint 标记。如果有 checkpoint 标记,则会提示用户「你回答了一个中间答案」,并且这个中间答案的回答会在排行榜中显示。
|
||||||
|
|||||||
@ -63,7 +63,7 @@ def get_submission_message(
|
|||||||
hint_msg = "✨ 恭喜!这是本题的中间答案,加油!"
|
hint_msg = "✨ 恭喜!这是本题的中间答案,加油!"
|
||||||
else:
|
else:
|
||||||
hint_msg = "🤔 答错啦!请检查你的答案。"
|
hint_msg = "🤔 答错啦!请检查你的答案。"
|
||||||
return f"{hint_msg}\n\n提示:{hint.hint}"
|
return f"{hint_msg}\n\n提示:{hint.message}"
|
||||||
return "❌ 答错啦!请检查你的答案。"
|
return "❌ 答错啦!请检查你的答案。"
|
||||||
|
|
||||||
|
|
||||||
@ -162,3 +162,15 @@ def get_puzzle_info_message(manager: PuzzleManager, puzzle: Puzzle) -> UniMessag
|
|||||||
msg = msg.text(f"\n---------\n使用 `konaph ready {puzzle.raw_id}` 完成编辑")
|
msg = msg.text(f"\n---------\n使用 `konaph ready {puzzle.raw_id}` 完成编辑")
|
||||||
|
|
||||||
return msg
|
return msg
|
||||||
|
|
||||||
|
|
||||||
|
def get_puzzle_hint_list(puzzle: Puzzle) -> str:
|
||||||
|
msg = f"==== {puzzle.title} 提示与中间答案 ====\n"
|
||||||
|
if len(puzzle.hints) == 0:
|
||||||
|
msg += "\n你没有添加任何中间答案。"
|
||||||
|
return msg
|
||||||
|
for hint_id, hint in puzzle.hints.items():
|
||||||
|
n = {False: "[提示]", True: "[中间答案]"}[hint.is_checkpoint]
|
||||||
|
msg += f"\n{n}[{hint_id}] {hint.pattern}"
|
||||||
|
msg += f"\n {hint.message}"
|
||||||
|
return msg
|
||||||
|
|||||||
@ -12,7 +12,7 @@ from konabot.plugins.kona_ph.core.path import KONAPH_DATA_JSON
|
|||||||
|
|
||||||
class PuzzleHint(BaseModel):
|
class PuzzleHint(BaseModel):
|
||||||
pattern: str
|
pattern: str
|
||||||
hint: str
|
message: str
|
||||||
is_checkpoint: bool
|
is_checkpoint: bool
|
||||||
|
|
||||||
|
|
||||||
@ -59,13 +59,22 @@ class Puzzle(BaseModel):
|
|||||||
time=time,
|
time=time,
|
||||||
)
|
)
|
||||||
for hint_id, hint in self.hints.items():
|
for hint_id, hint in self.hints.items():
|
||||||
if re.match(hint.pattern, submission):
|
if hint.pattern.startswith('/') and hint.pattern.endswith('/'):
|
||||||
return PuzzleSubmission(
|
if re.match(hint.pattern.strip('/'), submission):
|
||||||
success=False,
|
return PuzzleSubmission(
|
||||||
flag=submission,
|
success=False,
|
||||||
time=time,
|
flag=submission,
|
||||||
hint_id=hint_id,
|
time=time,
|
||||||
)
|
hint_id=hint_id,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
if hint.pattern == submission:
|
||||||
|
return PuzzleSubmission(
|
||||||
|
success=False,
|
||||||
|
flag=submission,
|
||||||
|
time=time,
|
||||||
|
hint_id=hint_id,
|
||||||
|
)
|
||||||
return PuzzleSubmission(
|
return PuzzleSubmission(
|
||||||
success=False,
|
success=False,
|
||||||
flag=submission,
|
flag=submission,
|
||||||
|
|||||||
@ -3,18 +3,22 @@ from math import ceil
|
|||||||
|
|
||||||
from nonebot import get_plugin_config
|
from nonebot import get_plugin_config
|
||||||
from nonebot_plugin_alconna import (Alconna, Args, Image, Option, Query,
|
from nonebot_plugin_alconna import (Alconna, Args, Image, Option, Query,
|
||||||
Subcommand, SubcommandResult, UniMessage, on_alconna)
|
Subcommand, SubcommandResult, UniMessage,
|
||||||
|
on_alconna)
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
from konabot.common.longtask import DepLongTaskTarget
|
from konabot.common.longtask import DepLongTaskTarget
|
||||||
|
from konabot.common.nb.exc import BotExceptionMessage
|
||||||
from konabot.common.nb.extract_image import download_image_bytes
|
from konabot.common.nb.extract_image import download_image_bytes
|
||||||
from konabot.common.nb.qq_broadcast import qq_broadcast
|
from konabot.common.nb.qq_broadcast import qq_broadcast
|
||||||
from konabot.common.username import get_username
|
from konabot.common.username import get_username
|
||||||
from konabot.plugins.kona_ph.core.image import get_image_manager
|
from konabot.plugins.kona_ph.core.image import get_image_manager
|
||||||
from konabot.plugins.kona_ph.core.message import (get_puzzle_description,
|
from konabot.plugins.kona_ph.core.message import (get_puzzle_description, get_puzzle_hint_list,
|
||||||
get_puzzle_info_message,
|
get_puzzle_info_message,
|
||||||
get_submission_message)
|
get_submission_message)
|
||||||
from konabot.plugins.kona_ph.core.storage import get_today_date, puzzle_manager
|
from konabot.plugins.kona_ph.core.storage import (Puzzle, PuzzleHint, PuzzleManager,
|
||||||
|
get_today_date,
|
||||||
|
puzzle_manager)
|
||||||
|
|
||||||
PUZZLE_PAGE_SIZE = 10
|
PUZZLE_PAGE_SIZE = 10
|
||||||
|
|
||||||
@ -36,6 +40,17 @@ def is_puzzle_admin(target: DepLongTaskTarget):
|
|||||||
return target.target_id in config.plugin_puzzle_admin
|
return target.target_id in config.plugin_puzzle_admin
|
||||||
|
|
||||||
|
|
||||||
|
def check_puzzle(manager: PuzzleManager, target: DepLongTaskTarget, raw_id: str) -> Puzzle:
|
||||||
|
if raw_id not in manager.puzzle_data:
|
||||||
|
raise BotExceptionMessage("没有这个谜题")
|
||||||
|
puzzle = manager.puzzle_data[raw_id]
|
||||||
|
if is_puzzle_admin(target):
|
||||||
|
return puzzle
|
||||||
|
if target.target_id != puzzle.author_id:
|
||||||
|
raise BotExceptionMessage("你没有权限查看或编辑这个谜题")
|
||||||
|
return puzzle
|
||||||
|
|
||||||
|
|
||||||
def create_admin_commands():
|
def create_admin_commands():
|
||||||
cmd_admin = on_alconna(
|
cmd_admin = on_alconna(
|
||||||
Alconna(
|
Alconna(
|
||||||
@ -73,21 +88,21 @@ def create_admin_commands():
|
|||||||
"add",
|
"add",
|
||||||
Args["raw_id", str],
|
Args["raw_id", str],
|
||||||
Args["pattern", str],
|
Args["pattern", str],
|
||||||
Args["hint", str],
|
Args["message", str],
|
||||||
dest="add",
|
dest="add",
|
||||||
),
|
),
|
||||||
Subcommand(
|
Subcommand(
|
||||||
"list",
|
"list",
|
||||||
Args["raw_id", str],
|
Args["raw_id", str],
|
||||||
Args["page?", int],
|
Args["page?", int],
|
||||||
dest="get",
|
dest="list",
|
||||||
),
|
),
|
||||||
Subcommand(
|
Subcommand(
|
||||||
"modify",
|
"modify",
|
||||||
Args["raw_id", str],
|
Args["raw_id", str],
|
||||||
Args["hint_id", int],
|
Args["hint_id", int],
|
||||||
Option("--pattern", Args["pattern", str], alias=["-p"]),
|
Option("--pattern", Args["pattern", str], alias=["-p"]),
|
||||||
Option("--hint", Args["hint", str], alias=["-h"]),
|
Option("--message", Args["message", str], alias=["-m"]),
|
||||||
Option("--checkpoint", Args["is_checkpoint", bool], alias=["-c"]),
|
Option("--checkpoint", Args["is_checkpoint", bool], alias=["-c"]),
|
||||||
dest="modify",
|
dest="modify",
|
||||||
),
|
),
|
||||||
@ -140,15 +155,7 @@ def create_admin_commands():
|
|||||||
@cmd_admin.assign("ready")
|
@cmd_admin.assign("ready")
|
||||||
async def _(raw_id: str, target: DepLongTaskTarget):
|
async def _(raw_id: str, target: DepLongTaskTarget):
|
||||||
async with puzzle_manager() as manager:
|
async with puzzle_manager() as manager:
|
||||||
if raw_id not in manager.puzzle_data:
|
p = check_puzzle(manager, target, raw_id)
|
||||||
return await target.send_message(UniMessage.text(
|
|
||||||
"你输入的谜题不存在!输入 `konaph my` 查看你创建的谜题"
|
|
||||||
))
|
|
||||||
p = manager.puzzle_data[raw_id]
|
|
||||||
if p.author_id != target.target_id and not is_puzzle_admin(target):
|
|
||||||
return await target.send_message(UniMessage.text(
|
|
||||||
"这不是你的题,你没有权限编辑!输入 `konaph my` 查看你创建的谜题"
|
|
||||||
))
|
|
||||||
if p.ready:
|
if p.ready:
|
||||||
return await target.send_message(UniMessage.text(
|
return await target.send_message(UniMessage.text(
|
||||||
"题目早就准备好啦!"
|
"题目早就准备好啦!"
|
||||||
@ -161,15 +168,7 @@ def create_admin_commands():
|
|||||||
@cmd_admin.assign("unready")
|
@cmd_admin.assign("unready")
|
||||||
async def _(raw_id: str, target: DepLongTaskTarget):
|
async def _(raw_id: str, target: DepLongTaskTarget):
|
||||||
async with puzzle_manager() as manager:
|
async with puzzle_manager() as manager:
|
||||||
if raw_id not in manager.puzzle_data:
|
p = check_puzzle(manager, target, raw_id)
|
||||||
return await target.send_message(UniMessage.text(
|
|
||||||
"你输入的谜题不存在!输入 `konaph my` 查看你创建的谜题"
|
|
||||||
))
|
|
||||||
p = manager.puzzle_data[raw_id]
|
|
||||||
if p.author_id != target.target_id and not is_puzzle_admin(target):
|
|
||||||
return await target.send_message(UniMessage.text(
|
|
||||||
"这不是你的题,你没有权限编辑!输入 `konaph my` 查看你创建的谜题"
|
|
||||||
))
|
|
||||||
if not p.ready:
|
if not p.ready:
|
||||||
return await target.send_message(UniMessage.text(
|
return await target.send_message(UniMessage.text(
|
||||||
f"谜题「{p.title}」已经是未取消状态了!"
|
f"谜题「{p.title}」已经是未取消状态了!"
|
||||||
@ -187,16 +186,7 @@ def create_admin_commands():
|
|||||||
@cmd_admin.assign("info")
|
@cmd_admin.assign("info")
|
||||||
async def _(raw_id: str, target: DepLongTaskTarget):
|
async def _(raw_id: str, target: DepLongTaskTarget):
|
||||||
async with puzzle_manager() as manager:
|
async with puzzle_manager() as manager:
|
||||||
if raw_id not in manager.puzzle_data:
|
p = check_puzzle(manager, target, raw_id)
|
||||||
return await target.send_message(UniMessage.text(
|
|
||||||
"你输入的谜题不存在!输入 `konaph my` 查看你创建的谜题"
|
|
||||||
))
|
|
||||||
p = manager.puzzle_data[raw_id]
|
|
||||||
if p.author_id != target.target_id and not is_puzzle_admin(target):
|
|
||||||
return await target.send_message(UniMessage.text(
|
|
||||||
"这不是你的题,你没有权限查看详细信息!"
|
|
||||||
))
|
|
||||||
|
|
||||||
await target.send_message(get_puzzle_info_message(manager, p))
|
await target.send_message(get_puzzle_info_message(manager, p))
|
||||||
|
|
||||||
@cmd_admin.assign("my")
|
@cmd_admin.assign("my")
|
||||||
@ -232,7 +222,9 @@ def create_admin_commands():
|
|||||||
@cmd_admin.assign("all")
|
@cmd_admin.assign("all")
|
||||||
async def _(target: DepLongTaskTarget, ready: Query[bool] = Query("all.ready"), page: int = 1):
|
async def _(target: DepLongTaskTarget, ready: Query[bool] = Query("all.ready"), page: int = 1):
|
||||||
if not is_puzzle_admin(target):
|
if not is_puzzle_admin(target):
|
||||||
return await target.send_message(UniMessage.text("你没有权限查看所有的哦"))
|
return await target.send_message(UniMessage.text(
|
||||||
|
"你没有权限使用该指令"
|
||||||
|
))
|
||||||
async with puzzle_manager() as manager:
|
async with puzzle_manager() as manager:
|
||||||
puzzles = [*manager.puzzle_data.values()]
|
puzzles = [*manager.puzzle_data.values()]
|
||||||
if ready.available:
|
if ready.available:
|
||||||
@ -314,11 +306,7 @@ def create_admin_commands():
|
|||||||
image_manager = get_image_manager()
|
image_manager = get_image_manager()
|
||||||
|
|
||||||
async with puzzle_manager() as manager:
|
async with puzzle_manager() as manager:
|
||||||
if raw_id not in manager.puzzle_data:
|
p = check_puzzle(manager, target, raw_id)
|
||||||
return await target.send_message("没有这个谜题")
|
|
||||||
p = manager.puzzle_data[raw_id]
|
|
||||||
if not is_puzzle_admin(target) and target.target_id != p.author_id:
|
|
||||||
return await target.send_message("你没有权限编辑这个谜题")
|
|
||||||
if title is not None:
|
if title is not None:
|
||||||
p.title = title
|
p.title = title
|
||||||
if description is not None:
|
if description is not None:
|
||||||
@ -342,6 +330,10 @@ def create_admin_commands():
|
|||||||
|
|
||||||
@cmd_admin.assign("publish")
|
@cmd_admin.assign("publish")
|
||||||
async def _(target: DepLongTaskTarget, raw_id: str | None = None):
|
async def _(target: DepLongTaskTarget, raw_id: str | None = None):
|
||||||
|
if not is_puzzle_admin(target):
|
||||||
|
return await target.send_message(UniMessage.text(
|
||||||
|
"你没有权限使用该指令"
|
||||||
|
))
|
||||||
today = get_today_date()
|
today = get_today_date()
|
||||||
async with puzzle_manager() as manager:
|
async with puzzle_manager() as manager:
|
||||||
if today in manager.daily_puzzle_of_date:
|
if today in manager.daily_puzzle_of_date:
|
||||||
@ -358,12 +350,8 @@ def create_admin_commands():
|
|||||||
@cmd_admin.assign("preview")
|
@cmd_admin.assign("preview")
|
||||||
async def _(target: DepLongTaskTarget, raw_id: str):
|
async def _(target: DepLongTaskTarget, raw_id: str):
|
||||||
async with puzzle_manager() as manager:
|
async with puzzle_manager() as manager:
|
||||||
puzzle = manager.puzzle_data.get(raw_id)
|
p = check_puzzle(manager, target, raw_id)
|
||||||
if puzzle is None:
|
return await target.send_message(get_puzzle_description(p))
|
||||||
return await target.send_message("没有这个谜题")
|
|
||||||
if not is_puzzle_admin(target) and target.target_id != puzzle.author_id:
|
|
||||||
return await target.send_message("你没有权限预览这个谜题")
|
|
||||||
return await target.send_message(get_puzzle_description(puzzle))
|
|
||||||
|
|
||||||
@cmd_admin.assign("get-submits")
|
@cmd_admin.assign("get-submits")
|
||||||
async def _(target: DepLongTaskTarget, raw_id: str):
|
async def _(target: DepLongTaskTarget, raw_id: str):
|
||||||
@ -387,17 +375,10 @@ def create_admin_commands():
|
|||||||
测试一道谜题的回答,并给出结果
|
测试一道谜题的回答,并给出结果
|
||||||
"""
|
"""
|
||||||
async with puzzle_manager() as manager:
|
async with puzzle_manager() as manager:
|
||||||
puzzle = manager.puzzle_data.get(raw_id)
|
p = check_puzzle(manager, target, raw_id)
|
||||||
if puzzle is None:
|
result = p.check_submission(submission)
|
||||||
return await target.send_message("没有这个谜题")
|
msg = get_submission_message(p, result)
|
||||||
if not is_puzzle_admin(target) and target.target_id != puzzle.author_id:
|
return await target.send_message("[测试提交] " + msg)
|
||||||
return await target.send_message("你没有权限预览这个谜题")
|
|
||||||
|
|
||||||
result = puzzle.check_submission(submission)
|
|
||||||
msg = get_submission_message(puzzle, result)
|
|
||||||
return await target.send_message(
|
|
||||||
UniMessage.text("[测试提交] ") + msg
|
|
||||||
)
|
|
||||||
|
|
||||||
@cmd_admin.assign("subcommands.hint")
|
@cmd_admin.assign("subcommands.hint")
|
||||||
async def _(target: DepLongTaskTarget, subcommands: Query[SubcommandResult] = Query("subcommands.hint")):
|
async def _(target: DepLongTaskTarget, subcommands: Query[SubcommandResult] = Query("subcommands.hint")):
|
||||||
@ -409,15 +390,75 @@ def create_admin_commands():
|
|||||||
.text("- konaph hint add <id> <pattern> <hint>\n - 添加一个提示 / 中间答案\n")
|
.text("- konaph hint add <id> <pattern> <hint>\n - 添加一个提示 / 中间答案\n")
|
||||||
.text("- konaph hint modify <id> <hint_id>\n")
|
.text("- konaph hint modify <id> <hint_id>\n")
|
||||||
.text(" - --pattern <pattern>\n - 更改匹配规则\n")
|
.text(" - --pattern <pattern>\n - 更改匹配规则\n")
|
||||||
.text(" - --hint <hint>\n - 更改提示文本\n")
|
.text(" - --message <message>\n - 更改提示文本\n")
|
||||||
.text(" - --checkpoint [True|False]\n - 更改是否为中间答案\n")
|
.text(" - --checkpoint [True|False]\n - 更改是否为中间答案\n")
|
||||||
.text("- konaph hint delete <id> <hint_id>\n - 删除一个提示 / 中间答案\n")
|
.text("- konaph hint delete <id> <hint_id>\n - 删除一个提示 / 中间答案\n")
|
||||||
.text("\n更多关于 pattern 和中间答案的信息,请见 man:中间答案(7)")
|
.text("\n更多关于 pattern 和中间答案的信息,请见 man:中间答案(7)")
|
||||||
)
|
)
|
||||||
|
|
||||||
@cmd_admin.assign("hint.add")
|
@cmd_admin.assign("subcommands.hint.add")
|
||||||
async def _(target: DepLongTaskTarget):
|
async def _(
|
||||||
await target.send_message("114514")
|
target: DepLongTaskTarget,
|
||||||
|
raw_id: str,
|
||||||
|
pattern: str,
|
||||||
|
message: str,
|
||||||
|
):
|
||||||
|
async with puzzle_manager() as manager:
|
||||||
|
p = check_puzzle(manager, target, raw_id)
|
||||||
|
p.hints[p.hint_id_max + 1] = PuzzleHint(
|
||||||
|
pattern=pattern,
|
||||||
|
message=message,
|
||||||
|
is_checkpoint=False,
|
||||||
|
)
|
||||||
|
await target.send_message("创建成功!\n\n" + get_puzzle_hint_list(p))
|
||||||
|
|
||||||
|
@cmd_admin.assign("subcommands.hint.list")
|
||||||
|
async def _(
|
||||||
|
target: DepLongTaskTarget,
|
||||||
|
raw_id: str,
|
||||||
|
):
|
||||||
|
async with puzzle_manager() as manager:
|
||||||
|
p = check_puzzle(manager, target, raw_id)
|
||||||
|
await target.send_message(get_puzzle_hint_list(p))
|
||||||
|
|
||||||
|
@cmd_admin.assign("subcommands.hint.modify")
|
||||||
|
async def _(
|
||||||
|
target: DepLongTaskTarget,
|
||||||
|
raw_id: str,
|
||||||
|
hint_id: int,
|
||||||
|
pattern: str | None = None,
|
||||||
|
message: str | None = None,
|
||||||
|
is_checkpoint: bool | None = None,
|
||||||
|
):
|
||||||
|
async with puzzle_manager() as manager:
|
||||||
|
p = check_puzzle(manager, target, raw_id)
|
||||||
|
if hint_id not in p.hints:
|
||||||
|
raise BotExceptionMessage(
|
||||||
|
f"没有这个 hint_id。请使用 konaph hint list {raw_id} 了解 hint 清单"
|
||||||
|
)
|
||||||
|
hint = p.hints[hint_id]
|
||||||
|
if pattern is not None:
|
||||||
|
hint.pattern = pattern
|
||||||
|
if message is not None:
|
||||||
|
hint.message = message
|
||||||
|
if is_checkpoint is not None:
|
||||||
|
hint.is_checkpoint = is_checkpoint
|
||||||
|
await target.send_message("更改成功!\n\n" + get_puzzle_hint_list(p))
|
||||||
|
|
||||||
|
@cmd_admin.assign("subcommands.hint.delete")
|
||||||
|
async def _(
|
||||||
|
target: DepLongTaskTarget,
|
||||||
|
raw_id: str,
|
||||||
|
hint_id: int,
|
||||||
|
):
|
||||||
|
async with puzzle_manager() as manager:
|
||||||
|
p = check_puzzle(manager, target, raw_id)
|
||||||
|
if hint_id not in p.hints:
|
||||||
|
raise BotExceptionMessage(
|
||||||
|
f"没有这个 hint_id。请使用 konaph hint list {raw_id} 了解 hint 清单"
|
||||||
|
)
|
||||||
|
del p.hints[hint_id]
|
||||||
|
await target.send_message("删除成功!\n\n" + get_puzzle_hint_list(p))
|
||||||
|
|
||||||
|
|
||||||
return cmd_admin
|
return cmd_admin
|
||||||
|
|||||||
Reference in New Issue
Block a user