-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
89bb56c
commit 53066cb
Showing
7 changed files
with
308 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
from pathlib import Path | ||
from loguru import logger | ||
from yaml import safe_load | ||
|
||
origin = """\ | ||
adapters: | ||
- http | ||
- ws | ||
## 是否开启认证流程, 若为 true 则建立连接时需要验证 verifyKey | ||
## 建议公网连接时开启 | ||
enableVerify: true | ||
verifyKey: {key} | ||
## 开启一些调式信息 | ||
debug: false | ||
## 是否开启单 session 模式, 若为 true,则自动创建 session 绑定 console 中登录的 bot | ||
## 开启后,接口中任何 sessionKey 不需要传递参数 | ||
## 若 console 中有多个 bot 登录,则行为未定义 | ||
## 确保 console 中只有一个 bot 登陆时启用 | ||
singleMode: false | ||
## 历史消息的缓存大小 | ||
## 同时,也是 http adapter 的消息队列容量 | ||
cacheSize: 4096 | ||
## adapter 的单独配置,键名与 adapters 项配置相同 | ||
adapterSettings: | ||
## 详情看 http adapter 使用说明 配置 | ||
http: | ||
host: {host} | ||
port: {port} | ||
cors: [*] | ||
## 详情看 websocket adapter 使用说明 配置 | ||
ws: | ||
host: {host} | ||
port: {port} | ||
reservedSyncId: -1 | ||
""" | ||
|
||
mcl_dir_root = Path(input("输入 mcl 的目录: >>>")) | ||
if not mcl_dir_root.exists(): | ||
logger.warning("未知的目录") | ||
exit(1) | ||
bot_config_dir_root = Path(input("输入 bot 的配置目录,默认为 config: >>>") or "config") | ||
if not bot_config_dir_root.exists(): | ||
logger.warning("未知的目录") | ||
exit(1) | ||
setting_file = mcl_dir_root / "config" / "net.mamoe.mirai-api-http" / "setting.yml" | ||
setting_file.parent.mkdir(parents=True, exist_ok=True) | ||
config_file = bot_config_dir_root / "config.yml" | ||
|
||
with config_file.open("r", encoding='utf-8') as f: | ||
config_data = safe_load(f) | ||
|
||
with setting_file.open("w+", encoding='utf-8') as f: | ||
f.write( | ||
origin.format( | ||
host=config_data['mirai']['host'], | ||
port=config_data['mirai']['port'], | ||
key=config_data['mirai']['verify_key'] | ||
) | ||
) | ||
|
||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
import re | ||
import time | ||
import aiohttp | ||
import asyncio | ||
|
||
import contextlib | ||
import pypinyin | ||
from playwright.async_api import TimeoutError, Page | ||
from app import Sender, exclusive, accessable, record | ||
from arclet.alconna import Alconna, Args, CommandMeta | ||
from arclet.alconna.graia import alcommand, Match | ||
from graia.ariadne.app import Ariadne | ||
from graiax.playwright import PlaywrightBrowser | ||
from graia.ariadne.event.lifecycle import AccountLaunch | ||
from graia.ariadne.message.chain import MessageChain | ||
from graia.ariadne.message.element import Source, Image | ||
from graia.ariadne.util.cooldown import CoolDown | ||
from graiax.shortcut.saya import dispatch, listen | ||
|
||
|
||
characters = {} | ||
sem = asyncio.Semaphore(1) | ||
running = asyncio.Event() | ||
cmd = Alconna( | ||
"原神角色卡", | ||
Args["uid;/", "[12][0-9]{8}"]["name", str], | ||
meta=CommandMeta("原神角色卡查询") | ||
) | ||
|
||
@listen(AccountLaunch) | ||
async def init(): | ||
global characters | ||
if not characters: | ||
characters = await init_chara_list() | ||
print(characters) | ||
|
||
@alcommand(cmd, send_error=True) | ||
@record("原神角色卡查询") | ||
@dispatch(CoolDown(5)) | ||
@exclusive | ||
@accessable | ||
async def genshin_chara_card(app: Ariadne, sender: Sender, source: Source, uid: Match[str], name: Match[str]): | ||
global characters | ||
if running.is_set(): | ||
return await app.send_message(sender, "请耐心排队~") | ||
running.set() | ||
start_time = time.time() | ||
uid = uid.result | ||
chara = name.result.strip() | ||
chara_pinyin = "".join(pypinyin.lazy_pinyin(chara)) | ||
if not characters: | ||
characters = await init_chara_list() | ||
if chara_pinyin not in characters: | ||
return await app.send_message(sender, MessageChain(f"角色列表中未找到角色:{chara},请检查拼写")) | ||
url = f"https://enka.shinshin.moe/u/{uid}" | ||
browser = app.launch_manager.get_interface(PlaywrightBrowser) | ||
try: | ||
async with browser.page() as page: | ||
page: Page | ||
await page.goto(url, wait_until="networkidle", timeout=100000) | ||
await page.set_viewport_size({"width": 2560, "height": 1080}) | ||
await page.evaluate( | ||
"document.getElementsByClassName('Dropdown-list')[0].children[13].dispatchEvent(new Event('click'));" | ||
) | ||
clen = await page.locator(".chara").count() | ||
styles = [(await page.locator(".chara").nth(i).get_attribute("style")) for i in range(clen)] | ||
if all(characters[chara_pinyin] not in style.lower() for style in styles): | ||
return await app.send_message( | ||
sender, | ||
MessageChain( | ||
f"未找到角色{chara} | {chara_pinyin}!只查询到这几个呢(只能查到展柜里有的呢):" | ||
f"{'、'.join([k for k, v in characters.items() if any(v in style.lower() for style in styles)])}" | ||
), | ||
quote=source, | ||
) | ||
index = -1 | ||
chara_src = "" | ||
for i, style in enumerate(styles): | ||
if characters[chara_pinyin] in style.lower(): | ||
index = i | ||
chara_src = style | ||
break | ||
if index == -1 or not chara_src: | ||
return await app.send_message(sender, MessageChain("获取角色头像div失败!")) | ||
|
||
await page.locator(f"div.avatar.svelte-jlfv30 >> nth={index}").click() | ||
await asyncio.sleep(1) | ||
await page.get_by_role("button", name=re.compile("Export image", re.IGNORECASE)).click() | ||
async with page.expect_download() as download_info: | ||
for _ in range(3): | ||
with contextlib.suppress(TimeoutError): | ||
await page.get_by_role("button", name=re.compile("Download", re.IGNORECASE)).click(timeout=10000) | ||
path = await (await download_info.value).path() | ||
await app.send_message( | ||
sender, | ||
MessageChain( | ||
f"use: {round(time.time() - start_time, 2)}s\n", | ||
Image(path=path) | ||
), | ||
quote=source, | ||
) | ||
finally: | ||
running.clear() | ||
|
||
async def init_chara_list(): | ||
res = {} | ||
url = "https://genshin.honeyhunterworld.com/fam_chars/?lang=CHS" | ||
async with aiohttp.ClientSession() as session: | ||
async with session.get(url) as resp: | ||
html = await resp.text() | ||
datas = re.findall(r"sortable_data.push\(\[(.*?)]\)", html, re.S) | ||
data = datas[0].replace(r"\"", '"').replace(r"\\", "\\").replace(r"\/", "/") | ||
cs = data[1:-1].split("],[") | ||
for c in cs: | ||
chn_name = re.findall(r'<img loading="lazy" alt="(.+?)"', c, re.S)[0] | ||
chn_name = chn_name.encode().decode("unicode_escape") | ||
en_name = re.findall(r'<a href="/(.+?)_.+/?lang=CHS"', c, re.S)[0] | ||
res["".join(pypinyin.lazy_pinyin(chn_name))] = en_name.lower() | ||
return res |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.