fix bug,新增深渊使用率查询和一些娱乐功能

This commit is contained in:
CMHopeSunshine 2022-05-03 10:43:50 +08:00
parent 07f337e010
commit b5dee2acfe
10 changed files with 314 additions and 66 deletions

View File

@ -53,7 +53,6 @@ async def gacha(event: Union[MessageEvent, GroupMessageEvent], reGroup: Dict = R
gacha_type = gacha_type_by_name(pool)
if gacha_type == 0:
await sim_gacha.finish('卡池名称出错,请选择角色1|角色2|武器|常驻', at_sender=True)
# TODO 冷却时间
if event.message_type == 'group':
if not lmt_group.check(event.group_id):
await sim_gacha.finish(f'本群模拟抽卡冷却中(剩余{lmt_group.left_time(event.group_id)}秒)')

View File

@ -51,9 +51,9 @@ __usage__ = '''
__help_version__ = '1.1.0'
sy = on_command('sy', aliases={'深渊', '深境螺旋'}, priority=7, block=True)
sy = on_command('sy', aliases={'深渊信息', '深境螺旋信息'}, priority=7, block=True)
ssbq = on_command('ssbq', aliases={'实时便笺', '实时便签', '当前树脂'}, priority=7, block=True)
myzj = on_command('myzj', aliases={'札记', '每月札记'}, priority=7, block=True)
myzj = on_command('myzj', aliases={'札记信息', '每月札记'}, priority=7, block=True)
ys = on_command('ys', aliases={'原神卡片', '个人卡片'}, priority=7, block=True)
ysa = on_command('ysa', aliases={'角色背包'}, priority=7, block=True)
ysc = on_command('ysc', aliases={'角色卡片', '角色详情'}, priority=7, block=True)
@ -242,7 +242,7 @@ async def ysb_handler(event: MessageEvent, msg: Message = CommandArg()):
@add_public_ck.handle()
@exception_handler()
async def add_public_ck_handler(msg: Message = CommandArg()):
async def add_public_ck_handler(event: MessageEvent, msg: Message = CommandArg()):
cookie = str(msg).strip()
if await check_cookie(cookie):
await insert_public_cookie(cookie)

View File

@ -22,7 +22,10 @@ async def get_abyss_data(user_id, uid, schedule_type="1", use_cache=True):
async with ClientSession() as session:
res = await session.get(url=url, headers=headers, params=params)
data = await res.json()
if await check_retcode(data, cookie, uid):
check = await check_retcode(data, cookie, uid)
if check == '私人cookie达到了每日30次查询上限':
return check
elif check:
return data
@ -63,7 +66,10 @@ async def get_player_card_data(user_id, uid, use_cache=True):
async with ClientSession() as session:
res = await session.get(url=url, headers=headers, params=params)
data = await res.json()
if await check_retcode(data, cookie, uid):
check = await check_retcode(data, cookie, uid)
if check == '私人cookie达到了每日30次查询上限':
return check
elif check:
return data
@ -84,7 +90,10 @@ async def get_chara_detail_data(user_id, uid, use_cache=True):
async with ClientSession() as session:
res = await session.post(url=url, headers=headers, json=json_data)
data = await res.json()
if await check_retcode(data, cookie, uid):
check = await check_retcode(data, cookie, uid)
if check == '私人cookie达到了每日30次查询上限':
return check
elif check:
return data
@ -105,7 +114,6 @@ async def get_chara_skill_data(uid, chara_id, use_cache=True):
async with ClientSession() as session:
res = await session.get(url=url, headers=headers, params=params)
data = await res.json()
# TODO:待定未知cookie对技能的影响
return data
@ -176,6 +184,8 @@ async def get_sign_info(uid):
data = await res.json()
if await check_retcode(data, cookie, uid):
return data
else:
return f'你的uid{uid}的cookie已过期,需要重新绑定哦!'
# 执行签到操作

View File

@ -0,0 +1,63 @@
from aiohttp import ClientSession
from urllib.parse import quote
from nonebot import on_command
from nonebot.params import CommandArg
from typing import Union
from nonebot.adapters.onebot.v11 import GroupMessageEvent, MessageEvent, MessageSegment
from ..utils.util import FreqLimiter
import random
duilian = on_command('对联', aliases={'对对联'}, priority=15, block=True)
cat_pic = on_command('猫图', aliases={'来点猫片', '看看猫猫', '来个猫猫'}, priority=15, block=True)
tcy_pic = on_command('二次元图', aliases={'来点二次元', '来点二刺螈'}, priority=15, block=True)
duilian_limit = FreqLimiter(5)
cat_lmt = FreqLimiter(10)
tcy_lmt = FreqLimiter(5)
@duilian.handle()
async def duilian_handler(event: Union[GroupMessageEvent, MessageEvent], msg=CommandArg()):
if not msg:
await duilian.finish('请输入对联内容')
if not duilian_limit.check(event.group_id or event.user_id):
await duilian.finish(f'对联冷却ing(剩余{duilian_limit.left_time(event.group_id or event.user_id)}秒)')
else:
duilian_limit.start_cd(event.group_id or event.user_id, 10)
text = quote(str(msg))
url = f'https://ai-backend.binwang.me/v0.2/couplet/{text}'
async with ClientSession() as session:
res = await session.get(url)
res = await res.json()
result = res['output'][0]
await duilian.finish(f'上联:{msg}\n下联:{result}')
@cat_pic.handle()
async def cat_pic_handler(event: Union[GroupMessageEvent, MessageEvent]):
if not cat_lmt.check(event.group_id or event.user_id):
await cat_pic.finish(f'猫片冷却ing(剩余{cat_lmt.left_time(event.group_id or event.user_id)}秒)')
else:
cat_lmt.start_cd(event.group_id or event.user_id, 10)
url = 'http://edgecats.net/'
async with ClientSession() as session:
res = await session.get(url)
res = await res.read()
await cat_pic.finish(MessageSegment.image(res))
@tcy_pic.handle()
async def tcy_pic_handler(event: Union[GroupMessageEvent, MessageEvent]):
urls = [
'https://www.dmoe.cc/random.php',
'https://acg.toubiec.cn/random.php',
'https://api.ixiaowai.cn/api/api.php'
]
if not tcy_lmt.check(event.group_id or event.user_id):
await tcy_pic.finish(f'二次元图片冷却ing(剩余{tcy_lmt.left_time(event.group_id or event.user_id)}秒)')
else:
tcy_lmt.start_cd(event.group_id or event.user_id, 5)
async with ClientSession() as session:
res = await session.get(random.choice(urls))
res = await res.read()
await cat_pic.finish(MessageSegment.image(res))

View File

@ -1,11 +1,13 @@
import os
from PIL import Image
from pathlib import Path
from nonebot import on_endswith
from nonebot import on_endswith, on_command, on_regex
from nonebot.params import RegexDict
from nonebot.adapters.onebot.v11 import MessageSegment, MessageEvent
from ..utils.character_alias import get_id_by_alias
from ..utils.util import pil2b64, exception_handler
from .blue import get_blue_pic
from ..utils.util import pil2b64
from .abyss_rate_draw import draw_rate_rank, draw_teams_rate
import re
import time
@ -16,6 +18,8 @@ __usage__ = '''
4.[xx收益曲线]查看blue菌hehe出品的收益曲线攻略
*感谢来自大佬们的授权角色支持别名查询
5.[今日/明日/周x材料]查看每日角色天赋材料和武器突破材料表
6.[深渊登场率]查看2.6深渊角色登场率
7.[深渊上半/下半阵容出场率]查看2.6深渊阵容出场率
'''
__help_version__ = '1.0.2'
@ -27,9 +31,12 @@ material = on_endswith('角色材料', priority=6, block=True)
attribute = on_endswith('参考面板', priority=6, block=True)
attribute2 = on_endswith('收益曲线', priority=6, block=True)
daily_material = on_endswith(('材料', '天赋材料', '突破材料'), priority=6, block=True)
abyss_rate = on_command('syrate', aliases={'深渊登场率', '深境螺旋登场率', '深渊登场率排行', '深渊排行'}, priority=6, block=True)
abyss_team = on_regex(r'^(深渊|深境螺旋)(?P<floor>上半|下半)阵容(排行|出场率)?$', priority=5, block=True)
@guide.handle()
@exception_handler()
async def genshin_guide(event: MessageEvent):
name: str = event.message.extract_plain_text().replace('角色攻略', '').strip()
realname = get_id_by_alias(name)
@ -45,6 +52,7 @@ async def genshin_guide(event: MessageEvent):
@material.handle()
@exception_handler()
async def genshin_material(event: MessageEvent):
name: str = event.message.extract_plain_text().replace('角色材料', '').strip()
realname = get_id_by_alias(name)
@ -61,6 +69,7 @@ async def genshin_material(event: MessageEvent):
@attribute.handle()
@exception_handler()
async def genshinAttribute(event: MessageEvent):
name: str = event.message.extract_plain_text().replace('参考面板', '').strip()
if name not in ['风主', '岩主', '雷主']:
@ -79,6 +88,7 @@ async def genshinAttribute(event: MessageEvent):
@attribute2.handle()
@exception_handler()
async def genshinAttribute2(event: MessageEvent):
name: str = event.message.extract_plain_text().replace('收益曲线', '').strip()
if name not in ['风主', '岩主', '雷主']:
@ -94,6 +104,7 @@ async def genshinAttribute2(event: MessageEvent):
@daily_material.handle()
@exception_handler()
async def daily_material_handle(event: MessageEvent):
week: str = event.message.extract_plain_text().replace('材料', '').replace('天赋材料', '').replace('突破材料', '').strip()
if week:
@ -122,3 +133,17 @@ async def daily_material_handle(event: MessageEvent):
else:
path = os.path.join(res_path, "daily_material", "周三周六.jpg")
await daily_material.finish(MessageSegment.image(file=Path(path)), at_sender=True)
@abyss_rate.handle()
@exception_handler()
async def abyss_rate_handler(event: MessageEvent):
abyss_img = await draw_rate_rank()
await abyss_rate.finish(abyss_img)
@abyss_team.handle()
@exception_handler()
async def abyss_team_handler(event: MessageEvent, reGroup=RegexDict()):
abyss_img = await draw_teams_rate(reGroup['floor'])
await abyss_team.finish(abyss_img)

View File

@ -0,0 +1,54 @@
from aiohttp import ClientSession
# 数据源自微信公众号原神创意工坊
headers = {
'Host': 'www.youchuang.fun',
'Referer': 'https://servicewechat.com/wxce4dbe0cb0f764b3/52/page-frame.html',
'User-Agent': 'Mozilla/5.0 (iPad; CPU OS 15_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) '
'Mobile/15E148 MicroMessenger/8.0.20(0x1800142f) NetType/WIFI Language/zh_CN',
'content-type': 'application/json'
}
async def get_rate(type: str = 'role'):
url = f'https://www.youchuang.fun/gamerole/{type}Rate'
json_data = {
"version": "2.6"
}
async with ClientSession() as session:
res = await session.post(url=url, headers=headers, json=json_data)
return await res.json()
async def get_formation_rate(layer: int = 1):
url = 'https://www.youchuang.fun/gamerole/formationRate'
json_data = {
"version": "2.6",
"layer": layer
}
async with ClientSession() as session:
res = await session.post(url=url, headers=headers, json=json_data)
return await res.json()
async def get_teammates_rate(name: str):
url = 'https://www.youchuang.fun/gamerole/teammatesRate'
json_data = {
"name": name,
"version": "2.6"
}
async with ClientSession() as session:
res = await session.post(url=url, headers=headers, json=json_data)
return await res.json()
async def get_weapon_rate(name: str):
url = 'https://www.youchuang.fun/gamerole/getWeaponByName'
json_data = {
"name": name,
"version": "2.6"
}
async with ClientSession() as session:
res = await session.post(url=url, headers=headers, json=json_data)
return await res.json()

View File

@ -0,0 +1,79 @@
from PIL import Image, ImageDraw, ImageFont
import os
from nonebot.adapters.onebot.v11 import MessageSegment
from .abyss_rate_data import get_rate, get_formation_rate
from ..utils.util import pil2b64
from ..utils.character_alias import get_id_by_alias
res_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'res')
def get_font(size, font_type='msyh.ttc'):
return ImageFont.truetype(os.path.join(res_path, font_type), size)
async def draw_rate_rank(type: str = 'role', mode: str = 'used'):
data = await get_rate(type)
if not data or data['code'] != '200':
return '获取工坊数据失败,请稍后再试'
col = int(len(data['result']['rateList']) / 5) if len(data['result']['rateList']) % 5 == 0 else int(len(data['result']['rateList']) / 5) + 1
top_img = Image.open(os.path.join(res_path, 'player_card', '卡片顶部无字.png')).resize((1080, 316))
body_img = Image.open(os.path.join(res_path, 'player_card', '卡片身体.png')).resize((1080, 226))
bottom_img = Image.open(os.path.join(res_path, 'player_card', '卡片底部.png')).resize((1080, 72))
bg_img = Image.new('RGBA', (1080, top_img.height + col * 220 + bottom_img.height + 50))
bg_img.paste(top_img, (0, 0))
bg_draw = ImageDraw.Draw(bg_img)
bg_draw.text((70, 55), '2.6深境螺旋登场率排行榜', fill='black', font=get_font(40, 'msyhbd.ttc'))
bg_draw.text((70, 110), f'当前共{data["result"]["userCount"]}份样本数据', fill='black', font=get_font(35))
for i in range(0, col + 1):
bg_img.paste(body_img, (0, top_img.height + i * body_img.height))
bg_img.paste(bottom_img, (0, top_img.height + col * 220 + 50))
bg_draw.text((130, bg_img.height - 86), 'Created by LittlePaimon | Data from 原神创意工坊', fill='black', font=get_font(35))
n = 0
for role in data['result']['rateList']:
role_img = Image.open(os.path.join(res_path, 'role_card', f'{get_id_by_alias(role["name"])[0]}.png')).resize((160, 200))
role_draw = ImageDraw.Draw(role_img)
role_draw.text((28 if len(role['rate']) == 6 else 38, 158), role['rate'], font=get_font(30), fill='black')
bg_img.alpha_composite(role_img, (50 + 204 * (n % 5), 180 + 240 * int(n / 5)))
n += 1
bg_img = pil2b64(bg_img, 75)
bg_img = MessageSegment.image(bg_img)
return bg_img
async def draw_teams_rate(floor='上半半'):
data = await get_formation_rate(1 if floor == '上半' else 2)
if not data or data['code'] != '200':
return '获取工坊数据失败,请稍后再试'
rateList = data['result']['rateList'][0:10]
top_img = Image.open(os.path.join(res_path, 'player_card', '卡片顶部无字.png')).resize((1080, 316))
body_img = Image.open(os.path.join(res_path, 'player_card', '卡片身体.png')).resize((1080, 240))
bottom_img = Image.open(os.path.join(res_path, 'player_card', '卡片底部.png')).resize((1080, 72))
bg_img = Image.new('RGBA', (1080, top_img.height + 10 * body_img.height + bottom_img.height - 130))
bg_img.paste(top_img, (0, 0))
bg_draw = ImageDraw.Draw(bg_img)
bg_draw.text((70, 55), f'2.6深境螺旋阵容出场率 | {floor}', fill='black', font=get_font(40, 'msyhbd.ttc'))
bg_draw.text((70, 110), f'当前共{data["result"]["userCount"]}份样本数据', fill='black', font=get_font(35))
for i in range(0, 10):
bg_img.paste(body_img, (0, top_img.height + i * body_img.height))
bg_img.paste(bottom_img, (0, top_img.height + 10 * 240 - 130))
bg_draw.text((130, bg_img.height - 86), 'Created by LittlePaimon | Data from 原神创意工坊', fill='black', font=get_font(35))
n = 0
for team in rateList:
bg_draw.text((48, 240 + 240 * n), '排名', fill='grey', font=get_font(30))
bg_draw.text((65 if n != 9 else 55, 275 + 240 * n), str(n + 1), fill='black', font=get_font(35))
bg_draw.text((934, 240 + 240 * n), '出场率', fill='grey', font=get_font(30))
bg_draw.text((930, 275 + 240 * n), team['rate'], fill='black', font=get_font(35))
r = 0
for role in team['formation']:
role_img = Image.open(
os.path.join(res_path, 'role_card', f'{get_id_by_alias(role["name"])[0]}.png')).resize((160, 200))
role_draw = ImageDraw.Draw(role_img)
role_draw.text((80 - 15 * len(role['name']), 158), role['name'], font=get_font(30), fill='black')
bg_img.alpha_composite(role_img, (130 + 204 * r, 180 + 240 * n))
r += 1
n += 1
bg_img = pil2b64(bg_img, 75)
bg_img = MessageSegment.image(bg_img)
return bg_img

View File

@ -6,6 +6,10 @@ nonebot2版本的小派蒙
- Paimon_Wiki 派蒙wiki查询插件
- Paimon_Gacha 派蒙模拟抽卡插件
- Paimon_Gacha_Log 派蒙抽卡记录获取插件
- Paimon_Plugins 派蒙其他娱乐插件
* 对联
* 来点猫片
* 来点二次元
具体插件命令与hoshino版一致<br>
nonebot2刚上手测试时间较短如有bug请及时反馈。
@ -17,11 +21,12 @@ nonebot2刚上手测试时间较短如有bug请及时反馈。
不多说了看wiki的部署教程
### 2. 安装nonebot2
先安装脚手架以及依赖
先安装脚手架以及相关依赖
```
pip install nb-cli
pip install matplotlib
pip install aiohttp
pip install xlsxwriter
```
创建nonebot2项目
`nb create`
@ -48,7 +53,7 @@ pip install aiohttp
编辑`.env`,把`dev`改成`prod`<br>
编辑`.env.prod`,修改以下内容
```
HOST=127.0.0.1 # Nonebot监听的IP
HOST=127.0.0.1 # Nonebot监听的IP如需外网访问改为0.0.0.0
PORT=6789 # Nonebot监听的端口和go-cqhttp的端口一致
LOG_LEVEL=INFO # 日志等级
SUPERUSERS=["123456"] # 超级用户
@ -58,7 +63,17 @@ COMMAND_SEP=[""] # 命令分隔符
```
### 3. 安装go-cqhttp
也不多说了看wiki的部署教程的go-cqhttp部分
也不多说了看wiki的部署教程的go-cqhttp部分<br>
servers部分修改如下
```
servers:
- ws-reverse:
universal: "ws://127.0.0.1:6789/onebot/v11/ws"
reconnect-interval: 3000
middlewares:
<<: *default
access-token: ""
```
### 4. 安装插件
```

View File

@ -129,12 +129,14 @@ short_name={
'波乱月白经津': '波乱'
}
def get_id_by_alias(name):
for c in character_alias.items():
if name in c[1]:
return c
return None
def get_short_name(name):
for n in short_name.items():
if name == n[0]:

View File

@ -167,6 +167,7 @@ async def check_retcode(data, cookie, uid):
await delete_cookie_cache(cookie['cookie'], key='cookie')
elif cookie['type'] == 'private':
logger.info(f'用户{cookie["user_id"]}的uid{cookie["uid"]}私人cookie达到了每日30次查询上限')
return '私人cookie达到了每日30次查询上限'
return False
else:
await update_cookie_cache(cookie['cookie'], uid, 'uid')