mirror of
https://github.com/TriM-Organization/LiteyukiBot-TriM.git
synced 2024-11-28 16:24:51 +08:00
🎈新增接龙插件,修改部分图形结构
This commit is contained in:
parent
cc5c0e1dee
commit
dd03dd6d3e
@ -32,7 +32,7 @@
|
|||||||
- 感谢[nonebot-plugin-alconna](https://github.com/ArcletProject/nonebot-plugin-alconna)提供的命令解析功能
|
- 感谢[nonebot-plugin-alconna](https://github.com/ArcletProject/nonebot-plugin-alconna)提供的命令解析功能
|
||||||
- 十分感谢[神羽SnowyKami](https://github.com/snowykami)提供的技术指导和服务器资源
|
- 十分感谢[神羽SnowyKami](https://github.com/snowykami)提供的技术指导和服务器资源
|
||||||
- 特别感谢[云裳工作室](https://doc.ysmcc.cn/doc/1/)提供的服务器挂载
|
- 特别感谢[云裳工作室](https://doc.ysmcc.cn/doc/1/)提供的服务器挂载
|
||||||
- 由衷的感谢我在学习生活中遇到的所有朋友们,你们身为我生命中的一处景色,不断地推进我此生的进程。
|
- 由衷感谢我在学习生活中遇到的所有朋友们,你们身为我生命中的一处景色,不断地推进我此生的进程。
|
||||||
|
|
||||||
### 许可证
|
### 许可证
|
||||||
|
|
||||||
|
@ -28,5 +28,7 @@ jieba~=0.42.1
|
|||||||
pip~=23.2.1
|
pip~=23.2.1
|
||||||
fastapi~=0.110.0
|
fastapi~=0.110.0
|
||||||
python-dotenv~=1.0.1
|
python-dotenv~=1.0.1
|
||||||
|
nonebot_plugin_session
|
||||||
pypinyin
|
pypinyin
|
||||||
zhDateTime>=1.0.3
|
zhDateTime>=1.0.3
|
||||||
|
Musicreater>=2.2.0
|
305
src/plugins/liteyuki_plugin_dockdragon/__init__.py
Normal file
305
src/plugins/liteyuki_plugin_dockdragon/__init__.py
Normal file
@ -0,0 +1,305 @@
|
|||||||
|
'''
|
||||||
|
接龙
|
||||||
|
'''
|
||||||
|
|
||||||
|
import asyncio
|
||||||
|
from asyncio import TimerHandle
|
||||||
|
|
||||||
|
from typing import List, Dict, Any
|
||||||
|
|
||||||
|
import re
|
||||||
|
import random
|
||||||
|
import pypinyin
|
||||||
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
from nonebot.matcher import Matcher
|
||||||
|
from nonebot import on_regex, require
|
||||||
|
from nonebot.params import RegexDict
|
||||||
|
from nonebot.plugin import PluginMetadata, inherit_supported_adapters
|
||||||
|
|
||||||
|
from typing_extensions import Annotated
|
||||||
|
|
||||||
|
require("nonebot_plugin_alconna")
|
||||||
|
require("nonebot_plugin_session")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
from nonebot_plugin_alconna import (
|
||||||
|
Alconna,
|
||||||
|
AlconnaQuery,
|
||||||
|
Option,
|
||||||
|
Query,
|
||||||
|
Text,
|
||||||
|
UniMessage,
|
||||||
|
on_alconna,
|
||||||
|
store_true,
|
||||||
|
)
|
||||||
|
from nonebot.rule import to_me
|
||||||
|
from nonebot_plugin_session import SessionId, SessionIdType
|
||||||
|
|
||||||
|
from .utils import random_idiom, legal_idiom, legal_patted_idiom, get_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": "@小羿 接龙",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# games: Dict[str, Dragle] = {}
|
||||||
|
games = {}
|
||||||
|
auto_echo = {}
|
||||||
|
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("dockdragon", Option("-s|--strict", 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_update = on_alconna(
|
||||||
|
# "更新词库",
|
||||||
|
# aliases=("刷新词库", "猜成语刷新词库"),
|
||||||
|
# rule=to_me(),
|
||||||
|
# use_cmd_start=True,
|
||||||
|
# block=True,
|
||||||
|
# priority=13,
|
||||||
|
# )
|
||||||
|
|
||||||
|
def is_auto_echo(user_id: UserId) -> bool:
|
||||||
|
return auto_echo.get(user_id, True)
|
||||||
|
|
||||||
|
|
||||||
|
handle_idiom = on_regex(
|
||||||
|
r"^(?P<idiom>[\u4e00-\u9fa5]{4})$",
|
||||||
|
rule=is_auto_echo,
|
||||||
|
block=True,
|
||||||
|
priority=14,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
停止自动回复 = on_alconna(
|
||||||
|
"自动接龙",
|
||||||
|
aliases=("自动成语接龙",),
|
||||||
|
rule=None,
|
||||||
|
use_cmd_start=True,
|
||||||
|
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 _(
|
||||||
|
# matcher: Matcher,
|
||||||
|
# user_id: UserId,
|
||||||
|
# strict: Query[bool] = AlconnaQuery("strict.value", False),
|
||||||
|
# ):
|
||||||
|
# # is_strict = handle_config.handle_strict_mode or strict.result
|
||||||
|
# idiom, explanation = random_idiom()
|
||||||
|
# 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()
|
||||||
|
async def _(matcher: Matcher, user_id: UserId):
|
||||||
|
if auto_echo.get(user_id, True):
|
||||||
|
auto_echo[user_id] = False
|
||||||
|
await matcher.finish("已关闭自动接龙回复")
|
||||||
|
else:
|
||||||
|
auto_echo[user_id] = True
|
||||||
|
await matcher.finish("已开启自动接龙回复")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@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 legal_idiom(idiom):
|
||||||
|
# stop_game(user_id)
|
||||||
|
print(matcher.get_target())
|
||||||
|
await matcher.finish(get_idiom(idiom,True,True))
|
||||||
|
|
||||||
|
# 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()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# zh = re.compile(r"[\u4e00-\u9fff]+")
|
||||||
|
|
||||||
|
|
||||||
|
# @cat.on_text(states=["", "idle"])
|
||||||
|
# async def handled():
|
||||||
|
# '''自动接龙'''
|
||||||
|
# text = cat.arg
|
||||||
|
# r = zh.search(text)
|
||||||
|
# if not r:
|
||||||
|
# return
|
||||||
|
|
||||||
|
# word = r.group()
|
||||||
|
|
||||||
|
# for dragon in dragon_list:
|
||||||
|
# # 跳过不启用的接龙
|
||||||
|
# if not dragon.use:
|
||||||
|
# continue
|
||||||
|
|
||||||
|
# # 当前词语符合接龙词库
|
||||||
|
# if dragon.check(word):
|
||||||
|
|
||||||
|
# # 上次接龙
|
||||||
|
# last = cat.cache.get("dragon", {}).get(dragon.name, "")
|
||||||
|
|
||||||
|
# # 成功接龙
|
||||||
|
# if last and word:
|
||||||
|
# p1 = lazy_pinyin(last)[-1]
|
||||||
|
# p2 = lazy_pinyin(word)[0]
|
||||||
|
# if p1 == p2:
|
||||||
|
# await cat.send(f"[{cat.user.name}] 接龙成功!")
|
||||||
|
|
||||||
|
|
||||||
|
# # 无论是否成功接龙都发送下一个词
|
||||||
|
# word = dragon.next(word)
|
||||||
|
# cat.cache.setdefault("dragon", {})
|
||||||
|
# cat.cache["dragon"][dragon.name] = word
|
||||||
|
# if not word:
|
||||||
|
# word = choice(["%$#*-_", "你赢了", "接不上来..."])
|
||||||
|
# await cat.send(word)
|
||||||
|
# break
|
||||||
|
|
||||||
|
|
||||||
|
# cat.set_wakeup_cmds(cmds="接龙管理")
|
||||||
|
# cat.set_rest_cmds(cmds=["exit", "退出"])
|
||||||
|
|
||||||
|
|
||||||
|
# @cat.on_cmd(cmds="list", states="idle")
|
||||||
|
# async def list_all():
|
||||||
|
# '''列出所有词库'''
|
||||||
|
# items = ["所有词库:"]
|
||||||
|
# for dragon in dragon_list:
|
||||||
|
# if dragon.use:
|
||||||
|
# items.append(f"[{dragon.name}] 正在使用")
|
||||||
|
# else:
|
||||||
|
# items.append(f"[{dragon.name}]")
|
||||||
|
# await cat.send("\n".join(items))
|
||||||
|
|
||||||
|
|
||||||
|
# @cat.on_cmd(cmds="data", states="idle")
|
||||||
|
# async def show_data():
|
||||||
|
# '''展示你的答题数据'''
|
||||||
|
# gid = cat.group.id
|
||||||
|
# uid = cat.user.id
|
||||||
|
|
||||||
|
# stmt = select(DragonUserData).filter_by(group_id=gid, user_id=uid)
|
||||||
|
# cursor = cat.db_session.exec(stmt)
|
||||||
|
# user_datas = cursor.all()
|
||||||
|
|
||||||
|
# if user_datas:
|
||||||
|
# info = "\n".join(
|
||||||
|
# f"[{u.dragon_name}] 接龙次数 {u.cnt}"
|
||||||
|
# for u in user_datas
|
||||||
|
# )
|
||||||
|
# else:
|
||||||
|
# info = "你还没有用过我...T_T"
|
||||||
|
|
||||||
|
# await cat.send(info)
|
||||||
|
|
97
src/plugins/liteyuki_plugin_dockdragon/debug.py
Normal file
97
src/plugins/liteyuki_plugin_dockdragon/debug.py
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
|
||||||
|
import random
|
||||||
|
|
||||||
|
from pypinyin import Style, pinyin
|
||||||
|
|
||||||
|
from typing import Dict, List, Tuple
|
||||||
|
|
||||||
|
# fmt: off
|
||||||
|
# 声母
|
||||||
|
INITIALS = [
|
||||||
|
"zh", "z", "y", "x", "w", "t", "sh", "s", "r", "q", "p",
|
||||||
|
"n", "m", "l", "k", "j", "h", "g", "f", "d", "ch", "c", "b"
|
||||||
|
]
|
||||||
|
# 韵母
|
||||||
|
FINALS = [
|
||||||
|
"ün", "üe", "üan", "ü", "uo", "un", "ui", "ue", "uang",
|
||||||
|
"uan", "uai","ua", "ou", "iu", "iong", "ong", "io", "ing",
|
||||||
|
"in", "ie", "iao", "iang", "ian", "ia", "er", "eng", "en",
|
||||||
|
"ei", "ao", "ang", "an", "ai", "u", "o", "i", "e", "a"
|
||||||
|
]
|
||||||
|
# fmt: on
|
||||||
|
|
||||||
|
|
||||||
|
def get_pinyin_of_n(word: str, which: int) -> List[Tuple[str, str, str]]:
|
||||||
|
pys = pinyin(word, style=Style.TONE3, v_to_u=True,heteronym=True)[which]
|
||||||
|
# py = p[0]
|
||||||
|
results = []
|
||||||
|
for py in pys:
|
||||||
|
if py[-1].isdigit():
|
||||||
|
tone = py[-1]
|
||||||
|
py = py[:-1]
|
||||||
|
else:
|
||||||
|
tone = ""
|
||||||
|
initial = ""
|
||||||
|
for i in INITIALS:
|
||||||
|
if py.startswith(i):
|
||||||
|
initial = i
|
||||||
|
break
|
||||||
|
final = ""
|
||||||
|
for f in FINALS:
|
||||||
|
if py.endswith(f):
|
||||||
|
final = f
|
||||||
|
break
|
||||||
|
results.append((initial, final, tone)) # 声母,韵母,声调
|
||||||
|
return results
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
LEGAL_PHRASES = [
|
||||||
|
idiom.strip() for idiom in open("./resources/idioms_p.txt","r", encoding="utf-8").readlines()
|
||||||
|
]
|
||||||
|
sorted_phrases = dict([i for j in [[(py[0]+py[1],{"":[],"1":[],"2":[],"3":[],"4":[]}) for py in get_pinyin_of_n(idiom[0],0)] for idiom in LEGAL_PHRASES] for i in j])
|
||||||
|
|
||||||
|
for idiom in LEGAL_PHRASES:
|
||||||
|
for py in get_pinyin_of_n(idiom[0],0):
|
||||||
|
sorted_phrases[py[0]+py[1]][py[2]].append(idiom)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def legal_idiom(word: str) -> bool:
|
||||||
|
return word in LEGAL_PHRASES
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def legal_patted_idiom(former:str, laster: str, diff_word: bool,homophonic: bool) -> bool:
|
||||||
|
"""
|
||||||
|
判断成语是否符合接龙条件
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
==========
|
||||||
|
former: str
|
||||||
|
前一个成语
|
||||||
|
laster: str
|
||||||
|
后一个成语
|
||||||
|
diff_word: bool
|
||||||
|
异字模式:接龙之字无须一致
|
||||||
|
homophonic: bool
|
||||||
|
谐音模式:接龙之字可不同音调
|
||||||
|
|
||||||
|
"""
|
||||||
|
return legal_idiom(laster) and legal_idiom(former) and ((((len({i[:2] for i in get_pinyin_of_n(laster[0],0)}.intersection({i[:2] for i in get_pinyin_of_n(former[-1],0)})))>0) if homophonic else (get_pinyin_of_n(laster,0)[0] == get_pinyin_of_n(former,-1)[0])) if diff_word else (former[-1] == laster[0] if homophonic else ((former[-1] == laster[0])and(get_pinyin_of_n(laster,0)[0] == get_pinyin_of_n(former,-1)[0]))))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def get_idiom(idiom: str,diff_word: bool,homophonic: bool) -> str:
|
||||||
|
return random.choice(([k for o in [[i for j in sorted_phrases[py[0]+py[1]].values() for i in j] for py in get_pinyin_of_n(idiom[-1],0)] for k in o] if homophonic else sorted_phrases[(py:=get_pinyin_of_n(idiom,-1)[0])[0]+py[1]][py[2]])if diff_word else ([k for o in [[i for j in sorted_phrases[py[0]+py[1]].values() for i in j if i[0] == idiom[-1]] for py in get_pinyin_of_n(idiom[-1],0)] for k in o] if homophonic else (lambda py:[i for i in sorted_phrases[py[0]+py[1]][py[2]] if i[0] == idiom[-1]])(get_pinyin_of_n(idiom,-1)[0])))
|
||||||
|
|
||||||
|
|
||||||
|
while True:
|
||||||
|
dw, homo = (bool(int(i)) for i in input("异字 异音:").split(" "))
|
||||||
|
print(legal_patted_idiom((phra:=input("成语A:")),(phrb:=input("成语B:")),dw,homo),legal_idiom(phra),legal_idiom(phrb),"\n",get_idiom(phra,dw,homo),get_pinyin_of_n(phra,-1),get_pinyin_of_n(phrb,0))
|
||||||
|
|
||||||
|
|
30126
src/plugins/liteyuki_plugin_dockdragon/resources/idioms_p.txt
Normal file
30126
src/plugins/liteyuki_plugin_dockdragon/resources/idioms_p.txt
Normal file
File diff suppressed because it is too large
Load Diff
141
src/plugins/liteyuki_plugin_dockdragon/utils.py
Normal file
141
src/plugins/liteyuki_plugin_dockdragon/utils.py
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
import random
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
from typing import Dict, List, Tuple
|
||||||
|
from PIL import ImageFont
|
||||||
|
|
||||||
|
from PIL.ImageFont import FreeTypeFont
|
||||||
|
|
||||||
|
# from watchdog.observers import Observer
|
||||||
|
# from watchdog.events import FileSystemEventHandler, FileModifiedEvent
|
||||||
|
|
||||||
|
from pypinyin import Style, pinyin
|
||||||
|
|
||||||
|
resource_dir = Path(__file__).parent / "resources"
|
||||||
|
fonts_dir = resource_dir / "fonts"
|
||||||
|
data_dir = resource_dir / "data"
|
||||||
|
idiom_path = resource_dir / "idioms_p.txt"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# fmt: off
|
||||||
|
# 声母
|
||||||
|
INITIALS = [
|
||||||
|
"zh", "z", "y", "x", "w", "t", "sh", "s", "r", "q", "p",
|
||||||
|
"n", "m", "l", "k", "j", "h", "g", "f", "d", "ch", "c", "b"
|
||||||
|
]
|
||||||
|
# 韵母
|
||||||
|
FINALS = [
|
||||||
|
"ün", "üe", "üan", "ü", "uo", "un", "ui", "ue", "uang",
|
||||||
|
"uan", "uai","ua", "ou", "iu", "iong", "ong", "io", "ing",
|
||||||
|
"in", "ie", "iao", "iang", "ian", "ia", "er", "eng", "en",
|
||||||
|
"ei", "ao", "ang", "an", "ai", "u", "o", "i", "e", "a"
|
||||||
|
]
|
||||||
|
# fmt: on
|
||||||
|
|
||||||
|
|
||||||
|
def get_pinyin_of_n(word: str, which: int) -> List[Tuple[str, str, str]]:
|
||||||
|
pys = pinyin(word, style=Style.TONE3, v_to_u=True,heteronym=True)[which]
|
||||||
|
# py = p[0]
|
||||||
|
results = []
|
||||||
|
for py in pys:
|
||||||
|
if py[-1].isdigit():
|
||||||
|
tone = py[-1]
|
||||||
|
py = py[:-1]
|
||||||
|
else:
|
||||||
|
tone = ""
|
||||||
|
initial = ""
|
||||||
|
for i in INITIALS:
|
||||||
|
if py.startswith(i):
|
||||||
|
initial = i
|
||||||
|
break
|
||||||
|
final = ""
|
||||||
|
for f in FINALS:
|
||||||
|
if py.endswith(f):
|
||||||
|
final = f
|
||||||
|
break
|
||||||
|
results.append((initial, final, tone)) # 声母,韵母,声调
|
||||||
|
return results
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
LEGAL_PHRASES = [
|
||||||
|
idiom.strip() for idiom in idiom_path.open("r", encoding="utf-8").readlines()
|
||||||
|
]
|
||||||
|
sorted_phrases = dict([i for j in [[(py[0]+py[1],{"":[],"1":[],"2":[],"3":[],"4":[]}) for py in get_pinyin_of_n(idiom[0],0)] for idiom in LEGAL_PHRASES] for i in j])
|
||||||
|
|
||||||
|
for idiom in LEGAL_PHRASES:
|
||||||
|
for py in get_pinyin_of_n(idiom[0],0):
|
||||||
|
sorted_phrases[py[0]+py[1]][py[2]].append(idiom)
|
||||||
|
|
||||||
|
|
||||||
|
# class LegalPhrasesModifiedHandler(FileSystemEventHandler):
|
||||||
|
# """
|
||||||
|
# Handler for resource file changes
|
||||||
|
# """
|
||||||
|
|
||||||
|
# def on_modified(self, event):
|
||||||
|
# print(f"{event.src_path} modified, reloading resource...")
|
||||||
|
# if "idioms.txt" in event.src_path:
|
||||||
|
# global LEGAL_PHRASES
|
||||||
|
# LEGAL_PHRASES = [
|
||||||
|
# idiom.strip()
|
||||||
|
# for idiom in idiom_path.open("r", encoding="utf-8").readlines()
|
||||||
|
# ]
|
||||||
|
# sorted_phrases = dict([i for j in [[(py[0]+py[1],{"":[],"1":[],"2":[],"3":[],"4":[]}) for py in get_pinyin_of_n(idiom[0],0)] for idiom in LEGAL_PHRASES] for i in j])
|
||||||
|
|
||||||
|
# for idiom in LEGAL_PHRASES:
|
||||||
|
# for py in get_pinyin_of_n(idiom[0],0):
|
||||||
|
# sorted_phrases[py[0]+py[1]][py[2]].append(idiom)
|
||||||
|
|
||||||
|
|
||||||
|
# Observer().schedule(
|
||||||
|
# LegalPhrasesModifiedHandler(),
|
||||||
|
# data_dir,
|
||||||
|
# recursive=False,
|
||||||
|
# event_filter=FileModifiedEvent,
|
||||||
|
# )
|
||||||
|
|
||||||
|
|
||||||
|
def legal_idiom(word: str) -> bool:
|
||||||
|
return word in LEGAL_PHRASES
|
||||||
|
|
||||||
|
|
||||||
|
def random_idiom() -> str:
|
||||||
|
return random.choice(LEGAL_PHRASES)
|
||||||
|
|
||||||
|
def legal_patted_idiom(former:str, laster: str, diff_word: bool,homophonic: bool) -> bool:
|
||||||
|
"""
|
||||||
|
判断成语是否符合接龙条件
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
==========
|
||||||
|
former: str
|
||||||
|
前一个成语
|
||||||
|
laster: str
|
||||||
|
后一个成语
|
||||||
|
diff_word: bool
|
||||||
|
异字模式:接龙之字无须一致
|
||||||
|
homophonic: bool
|
||||||
|
谐音模式:接龙之字可不同音调
|
||||||
|
|
||||||
|
"""
|
||||||
|
return legal_idiom(laster) and legal_idiom(former) and ((((len({i[:2] for i in get_pinyin_of_n(laster[0],0)}.intersection({i[:2] for i in get_pinyin_of_n(former[-1],0)})))>0) if homophonic else (get_pinyin_of_n(laster,0)[0] == get_pinyin_of_n(former,-1)[0])) if diff_word else (former[-1] == laster[0] if homophonic else ((former[-1] == laster[0])and(get_pinyin_of_n(laster,0)[0] == get_pinyin_of_n(former,-1)[0]))))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def get_idiom(idiom: str,diff_word: bool,homophonic: bool) -> str:
|
||||||
|
return random.choice(([k for o in [[i for j in sorted_phrases[py[0]+py[1]].values() for i in j] for py in get_pinyin_of_n(idiom[-1],0)] for k in o] if homophonic else sorted_phrases[(py:=get_pinyin_of_n(idiom,-1)[0])[0]+py[1]][py[2]])if diff_word else ([k for o in [[i for j in sorted_phrases[py[0]+py[1]].values() for i in j if i[0] == idiom[-1]] for py in get_pinyin_of_n(idiom[-1],0)] for k in o] if homophonic else (lambda py:[i for i in sorted_phrases[py[0]+py[1]][py[2]] if i[0] == idiom[-1]])(get_pinyin_of_n(idiom,-1)[0])))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def load_font(name: str, fontsize: int) -> FreeTypeFont:
|
||||||
|
return ImageFont.truetype(str(fonts_dir / name), fontsize, encoding="utf-8")
|
@ -1,7 +1,7 @@
|
|||||||
from nonebot.plugin import PluginMetadata
|
from nonebot.plugin import PluginMetadata
|
||||||
from .status import *
|
from .status import *
|
||||||
|
|
||||||
__author__ = "snowykami"
|
__author__ = "snowykami & 金羿Eilles"
|
||||||
__plugin_meta__ = PluginMetadata(
|
__plugin_meta__ = PluginMetadata(
|
||||||
name="状态查看器",
|
name="状态查看器",
|
||||||
description="",
|
description="",
|
||||||
|
@ -15,8 +15,8 @@ from nonebot_plugin_alconna import (
|
|||||||
UniMessage,
|
UniMessage,
|
||||||
Option,
|
Option,
|
||||||
store_true,
|
store_true,
|
||||||
AlconnaQuery,
|
# AlconnaQuery,
|
||||||
Query,
|
# Query,
|
||||||
Arparma,
|
Arparma,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
27
src/plugins/trim_plugin_msctconverter/__init__.py
Normal file
27
src/plugins/trim_plugin_msctconverter/__init__.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
|
||||||
|
|
||||||
|
from nonebot.plugin import PluginMetadata
|
||||||
|
from .msctexec import *
|
||||||
|
|
||||||
|
__author__ = "金羿Eilles"
|
||||||
|
__plugin_meta__ = PluginMetadata(
|
||||||
|
name="伶伦转换器",
|
||||||
|
description="",
|
||||||
|
usage=(
|
||||||
|
"MARKDOWN## 伶伦转换器\n"
|
||||||
|
"《我的世界》音乐转换,结构生成与转换\n"
|
||||||
|
"### 用法\n"
|
||||||
|
"- `/msctcvt` 转换MIDI音乐\n"
|
||||||
|
# "- `/stctcvt` 各类结构互转\n"
|
||||||
|
# "- `/stctbld` 文本指令转结构\n"
|
||||||
|
# "- `/stctbld` 文本指令转结构\n"
|
||||||
|
),
|
||||||
|
type="application",
|
||||||
|
homepage="https://gitee.com/TriM-Organization/Musicreater",
|
||||||
|
extra={
|
||||||
|
"liteyuki": True,
|
||||||
|
"toggleable" : False,
|
||||||
|
"default_enable" : True,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
42
src/plugins/trim_plugin_msctconverter/msctexec.py
Normal file
42
src/plugins/trim_plugin_msctconverter/msctexec.py
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
|
||||||
|
|
||||||
|
import nonebot
|
||||||
|
from nonebot import require
|
||||||
|
|
||||||
|
require("nonebot_plugin_alconna")
|
||||||
|
from nonebot_plugin_alconna import (
|
||||||
|
on_alconna,
|
||||||
|
Alconna,
|
||||||
|
Subcommand,
|
||||||
|
UniMessage,
|
||||||
|
Option,
|
||||||
|
store_true,
|
||||||
|
Arparma,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
musicreater_convert = on_alconna(
|
||||||
|
aliases={"musicreater_convert","音乐转换","midi转换"},
|
||||||
|
command=Alconna(
|
||||||
|
"msctcvt",
|
||||||
|
Option(
|
||||||
|
"-r|--refresh",
|
||||||
|
default=False,
|
||||||
|
alias={"refr", "r", "刷新"},
|
||||||
|
action=store_true,
|
||||||
|
),
|
||||||
|
Subcommand(
|
||||||
|
"memory",
|
||||||
|
alias={"mem", "m", "内存"},
|
||||||
|
),
|
||||||
|
Subcommand(
|
||||||
|
"process",
|
||||||
|
alias={"proc", "p", "进程"},
|
||||||
|
),
|
||||||
|
# Subcommand(
|
||||||
|
# "refresh",
|
||||||
|
# alias={"refr", "r", "刷新"},
|
||||||
|
# ),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
2
src/resources/liteyuki_statistics/lang/zh-WY.lang
Normal file
2
src/resources/liteyuki_statistics/lang/zh-WY.lang
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
stat.message=计言
|
||||||
|
stat.rank=言榜
|
@ -19,7 +19,7 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.info-box {
|
.info-box {
|
||||||
border-radius: 60px;
|
/* border-radius: 60px; */
|
||||||
padding: 40px;
|
padding: 40px;
|
||||||
backdrop-filter: blur(10px);
|
backdrop-filter: blur(10px);
|
||||||
background-color: rgba(0, 0, 0, 0.5);
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
.bot-icon-img {
|
.bot-icon-img {
|
||||||
height: 220px;
|
height: 220px;
|
||||||
width: 220px;
|
width: 220px;
|
||||||
border-radius: 50%;
|
/* border-radius: 50%; */
|
||||||
}
|
}
|
||||||
|
|
||||||
.bot-name {
|
.bot-name {
|
||||||
@ -88,14 +88,14 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 60px;
|
height: 60px;
|
||||||
background-color: #ffffff44;
|
background-color: #ffffff44;
|
||||||
border-radius: 30px;
|
/* border-radius: 30px; */
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.disk-usage {
|
.disk-usage {
|
||||||
background-color: #a2d8f4;
|
background-color: #a2d8f4;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
border-radius: 30px;
|
/* border-radius: 30px; */
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.bot-icon {
|
.bot-icon {
|
||||||
border-radius: 50%;
|
/* border-radius: 50%; */
|
||||||
height: 200px;
|
height: 200px;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
}
|
}
|
||||||
@ -102,6 +102,6 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.addition-info {
|
.addition-info {
|
||||||
font-size: 36px;
|
font-size: 32px;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user