新增全部重签、优化原神猜语音、更改异步请求库

This commit is contained in:
CMHopeSunshine 2022-05-19 18:15:56 +08:00
parent 77ae9e9f8d
commit 238ba221b3
22 changed files with 387 additions and 460 deletions

View File

@ -14,11 +14,10 @@ from ..utils.config import config
setting_time = config.paimon_guess_voice # 游戏持续时间
dir_name = Path() / 'LittlePaimon' / 'LittlePaimon' / 'Guess_voice' / 'voice'
dir_name = Path() / 'data' / 'LittlePaimon' / 'guess_voice' / 'voice'
guess_game = on_command('原神猜语音', priority=12, block=True)
running_guess_game = on_command('我猜', aliases={'guess', 'ig'}, priority=12, permission=permission.GROUP, block=True)
ys_voice = on_command('原神语音', priority=12, block=True)
update_ys_voice = on_command('更新原神语音资源', priority=12, permission=SUPERUSER, block=True)
@ -72,14 +71,6 @@ async def guess_genshin_voice(bot: Bot, event: GroupMessageEvent, msg=CommandArg
await guess_game.finish(str(e))
@running_guess_game.handle()
async def on_input_chara_name(event: GroupMessageEvent, msg=CommandArg()):
msg = str(msg).strip()
guess = Guess(event.group_id, time=setting_time)
if guess.is_start():
await guess.add_answer(event.user_id, msg)
@ys_voice.handle()
async def get_genshin_voice(bot: Bot, event: Union[PrivateMessageEvent, GroupMessageEvent], msg=CommandArg()):
name = str(msg).strip()

View File

@ -7,10 +7,10 @@ import json
import os
from pathlib import Path
from bs4 import BeautifulSoup
from aiohttp import ClientSession
from sqlitedict import SqliteDict # TODO 加入requirements
from .util import get_path
from nonebot import logger
from ..utils.http_util import aiorequests
# OUT_PUT = Path(__file__).parent / 'voice'
@ -49,55 +49,52 @@ db = init_db('data', 'voice.sqlite')
# 获取角色列表
async def get_character_list():
async with ClientSession() as session:
html = await session.get(BASE_URL + API['character_list'])
soup = BeautifulSoup(await html.text(), 'lxml')
char_list = soup.find(attrs={
'class': 'resp-tab-content',
'style': 'display:block;'
})
char_list1 = char_list.find_all(attrs={'class': 'g C5星'})
res = list(set(map(lambda x: x.find('div', class_='L').text, char_list1)))
char_list2 = char_list.find_all(attrs={'class': 'g C5'})
res.extend(list(set(map(lambda x: x.find('div', class_='L').text, char_list2))))
char_list3 = char_list.find_all(attrs={'class': 'g C4星'})
res.extend(list(set(map(lambda x: x.find('div', class_='L').text, char_list3))))
res.sort()
return res
html = await aiorequests.get(url=(BASE_URL + API['character_list']))
soup = BeautifulSoup(html.text, 'lxml')
char_list = soup.find(attrs={
'class': 'resp-tab-content',
'style': 'display:block;'
})
char_list1 = char_list.find_all(attrs={'class': 'g C5星'})
res = list(set(map(lambda x: x.find('div', class_='L').text, char_list1)))
char_list2 = char_list.find_all(attrs={'class': 'g C5'})
res.extend(list(set(map(lambda x: x.find('div', class_='L').text, char_list2))))
char_list3 = char_list.find_all(attrs={'class': 'g C4星'})
res.extend(list(set(map(lambda x: x.find('div', class_='L').text, char_list3))))
res.sort()
return res
# 获取角色语音
async def get_voice_info(character_name: str):
logger.info('获取数据: %s' % character_name)
async with ClientSession() as session:
html = await session.get(BASE_URL + API['voice'] % character_name)
soup = BeautifulSoup(await html.text(), 'lxml')
if soup.find(text='本页面目前没有内容。您可以在其他页面中'):
return None
voice_list = soup.find_all(attrs={'class': 'visible-md'})[2:]
info_list = []
for item in voice_list:
item_tab = item.find_all(attrs={'class': ''})[1:]
if isinstance(item_tab[1].next, str):
return info_list
info_list.append({
'title': item_tab[0].text,
'text': item_tab[5].text,
'': item_tab[1].next.attrs.get('data-src', ''),
'': item_tab[2].next.attrs.get('data-src', ''),
'': item_tab[3].next.attrs.get('data-src', ''),
'': item_tab[4].next.attrs.get('data-src', ''),
})
return info_list
html = await aiorequests.get(url=(BASE_URL + API['voice'] % character_name))
soup = BeautifulSoup(html.text, 'lxml')
if soup.find(text='本页面目前没有内容。您可以在其他页面中'):
return None
voice_list = soup.find_all(attrs={'class': 'visible-md'})[2:]
info_list = []
for item in voice_list:
item_tab = item.find_all(attrs={'class': ''})[1:]
if isinstance(item_tab[1].next, str):
return info_list
info_list.append({
'title': item_tab[0].text,
'text': item_tab[5].text,
'': item_tab[1].next.attrs.get('data-src', ''),
'': item_tab[2].next.attrs.get('data-src', ''),
'': item_tab[3].next.attrs.get('data-src', ''),
'': item_tab[4].next.attrs.get('data-src', ''),
})
return info_list
# 下载音频文件到本地
async def download(url, path):
async with ClientSession() as session:
res = await session.get(url, timeout=30)
os.makedirs(os.path.dirname(path), exist_ok=True)
with open(path, "wb") as f:
f.write(await res.read())
res = await aiorequests.get(url=url, timeout=30)
os.makedirs(os.path.dirname(path), exist_ok=True)
with open(path, "wb") as f:
f.write(res.read())
async def update_voice_data():
@ -148,27 +145,25 @@ async def update_voice_data():
async def voice_list_by_mys():
url = 'https://api-static.mihoyo.com/common/blackboard/ys_obc/v1/home/content/list?app_sn=ys_obc&channel_id=84'
async with ClientSession() as session:
res = await session.get(url, timeout=30)
json_data = await res.json()
if json_data['retcode']:
raise Exception(json_data['message'])
try:
data_list = json_data['data']['list'][0]['list']
except KeyError as e:
raise Exception('获取语音列表失败, 请联系作者修复')
resp = await aiorequests.get(url=url, timeout=30)
json_data = resp.json()
if json_data['retcode']:
raise Exception(json_data['message'])
try:
data_list = json_data['data']['list'][0]['list']
except KeyError as e:
raise Exception('获取语音列表失败, 请联系作者修复')
return {x['title'].split()[0]: x for x in data_list}
return {x['title'].split()[0]: x for x in data_list}
async def voice_detail_by_mys(content_id):
url = 'https://bbs.mihoyo.com/ys/obc/content/%s/detail?bbs_presentation_style=no_header' % content_id
async with ClientSession() as session:
res = await session.get(url, timeout=30)
soup = BeautifulSoup(await res.text(), 'lxml')
paragraph_box = soup.select('.obc-tmpl__paragraph-box')
res = await aiorequests.get(url=url, timeout=30)
soup = BeautifulSoup(res.text, 'lxml')
paragraph_box = soup.select('.obc-tmpl__paragraph-box')
return [{
'text': x.get_text(),
'chn': x.find('source').attrs['src']
} for x in paragraph_box]
return [{
'text': x.get_text(),
'chn': x.find('source').attrs['src']
} for x in paragraph_box]

View File

@ -9,6 +9,9 @@ from nonebot import get_bot, require, logger
from nonebot.adapters.onebot.v11 import MessageSegment, escape
from sqlitedict import SqliteDict
from .util import get_path, require_file
from nonebot.rule import Rule
from nonebot import on_regex
from nonebot.adapters.onebot.v11 import GroupMessageEvent
from .download_data import voice_list_by_mys, voice_detail_by_mys
@ -52,6 +55,23 @@ with open(os.path.join(os.path.dirname(__file__), 'character.json'), 'r', encodi
character_json: dict = json.loads(f.read())
def create_guess_matcher(role_name, second, group_id):
def check_group(event: GroupMessageEvent):
if event.group_id == group_id:
return True
return False
alias_list = character_json[role_name]
re_str = role_name + '|' + '|'.join(alias_list)
guess_matcher = on_regex(re_str, temp=True, rule=Rule(check_group))
@guess_matcher.handle()
async def _(event: GroupMessageEvent):
guess = Guess(event.group_id, time=second)
if guess.is_start():
await guess.add_answer(event.user_id, event.message.extract_plain_text())
def get_voice_by_language(data, language_name):
if language_name == '':
return data['chn']
@ -200,7 +220,7 @@ class Guess:
coalesce=True,
jobstore='default',
max_instances=1)
create_guess_matcher(answer, self.time, self.group_id)
return MessageSegment.record(file=Path(path))
async def start2(self):
@ -282,7 +302,7 @@ class Guess:
# 只添加正确的答案
async def add_answer(self, qq: int, msg: str):
if self.group.get('answer') and char_name_by_name(msg) == self.group['answer']:
if self.group.get('answer'):
process[self.group_id]['ok'].add(qq)
job_id = str(self.group_id) + '_guess_voice'
if scheduler.get_job(job_id, 'default'):

View File

@ -1,11 +1,9 @@
import os
from aiohttp import ClientSession
from pathlib import Path
import aiofiles
from ..utils.http_util import aiorequests
# def get_path(*paths):
# return os.path.join(os.path.dirname(__file__), *paths)
def get_path(dirname, filename):
return Path() / 'data' / 'LittlePaimon' / 'guess_voice' / dirname / filename
@ -32,13 +30,12 @@ async def require_file(file=None,
if not url:
raise ValueError('url not null')
async with ClientSession() as session:
res = await session.get(url, timeout=timeout)
content = await res.read()
res = await aiorequests.get(url, timeout=timeout)
content = res.read()
if file:
os.makedirs(os.path.dirname(file), exist_ok=True)
async with aiofiles.open(file, w_mode, encoding=encoding) as fp:
await fp.write(content)
return content
return await read()
if file:
os.makedirs(os.path.dirname(file), exist_ok=True)
async with aiofiles.open(file, w_mode, encoding=encoding) as fp:
await fp.write(content)
return content
return await read()

View File

@ -1,9 +1,9 @@
from aiohttp import ClientSession
import re
from .gacha_info import *
from .gacha_res import more_ten
from ..utils.config import config
from ..utils.util import FreqLimiter
from ..utils.http_util import aiorequests
from typing import Dict, Union
from nonebot import on_command, on_regex
from nonebot.params import RegexDict
@ -80,10 +80,10 @@ async def gacha(event: Union[MessageEvent, GroupMessageEvent], reGroup: Dict = R
async def show_log_handler(event: MessageEvent):
uid = str(event.user_id)
init_user_info(uid)
gacha_list = user_info[uid]['gacha_list']
# gacha_list = user_info[uid]['gacha_list']
if user_info[uid]['gacha_list']['wish_total'] == 0:
await show_log.finish('你此前并没有抽过卡哦', at_sender=True)
msg = event.message.extract_plain_text().replace('模拟抽卡记录').strip()
msg = event.message.extract_plain_text().replace('模拟抽卡记录', '').strip()
if msg == '角色' or msg == '武器':
res = get_rw_record(msg, uid)
else:
@ -247,13 +247,11 @@ BASE_URL = 'https://webstatic.mihoyo.com/hk4e/gacha_info/cn_gf01/%s'
async def gacha_info_list():
async with ClientSession() as session:
res = await session.get(BASE_URL % 'gacha/list.json')
json_data = await res.json()
return json_data['data']['list']
res = await aiorequests.get(url=BASE_URL % 'gacha/list.json')
json_data = res.json()
return json_data['data']['list']
async def gacha_info(gacha_id):
async with ClientSession() as session:
res = await session.get(BASE_URL % gacha_id + '/zh-cn.json')
return await res.json()
res = await aiorequests.get(url=BASE_URL % gacha_id + '/zh-cn.json')
return res.json()

View File

@ -14,8 +14,7 @@ def id_generator():
def convertUIGF(gachaLog, uid):
UIGF_data = {}
UIGF_data["info"] = {}
UIGF_data = {"info": {}}
UIGF_data["info"]["uid"] = uid
UIGF_data["info"]["lang"] = "zh-cn"
UIGF_data["info"]["export_time"] = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())

View File

@ -1,6 +1,5 @@
import json
from urllib import parse
from aiohttp import ClientSession
from ..utils.http_util import aiorequests
def toApi(url):
@ -30,9 +29,8 @@ def getApi(url, gachaType, size, page, end_id=""):
async def checkApi(url):
try:
async with ClientSession() as session:
r = await session.get(url)
j = await r.json()
j = await aiorequests.get(url=url)
j = j.json()
except Exception as e:
return f'API请求解析出错{e}'
@ -59,8 +57,6 @@ async def getGachaInfo(url):
region = getQueryVariable(url, "region")
lang = getQueryVariable(url, "lang")
gachaInfoUrl = "https://webstatic.mihoyo.com/hk4e/gacha_info/{}/items/{}.json".format(region, lang)
async with ClientSession() as session:
r = await session.get(gachaInfoUrl)
s = (await r.read()).decode("utf-8")
gachaInfo = json.loads(s)
return gachaInfo
resp = await aiorequests.get(url=gachaInfoUrl)
gachaInfo = resp.json()
return gachaInfo

View File

@ -1,10 +1,10 @@
import os
import json
from asyncio import sleep
from aiohttp import ClientSession
from .api import getApi
from .meta_data import gachaQueryTypeIds, gachaQueryTypeDict
from .UIGF_and_XLSX import convertUIGF, writeXLSX
from ..utils.http_util import aiorequests
data_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'user_data', 'gacha_log_data')
@ -16,15 +16,14 @@ async def getGachaLogs(url, gachaTypeId):
end_id = "0"
for page in range(1, 9999):
api = getApi(url, gachaTypeId, size, page, end_id)
async with ClientSession() as session:
r = await session.get(api)
j = await r.json()
gacha = j["data"]["list"]
if not len(gacha):
break
for i in gacha:
gachaList.append(i)
end_id = j["data"]["list"][-1]["id"]
resp = await aiorequests.get(url=api)
j = resp.json()
gacha = j["data"]["list"]
if not len(gacha):
break
for i in gacha:
gachaList.append(i)
end_id = j["data"]["list"][-1]["id"]
await sleep(0.5)
return gachaList

View File

@ -5,6 +5,7 @@ from collections import defaultdict
from asyncio import sleep
from nonebot import on_command, require, logger, get_bot
from nonebot.params import CommandArg
from nonebot.rule import to_me
from nonebot.permission import SUPERUSER
from nonebot.adapters.onebot.v11 import MessageEvent, Message, Bot
from .get_data import get_bind_game, get_sign_info, sign, get_sign_list, get_abyss_data, get_daily_note_data
@ -59,6 +60,7 @@ ysc = on_command('ysc', aliases={'角色卡片', '角色详情'}, priority=7, bl
ysb = on_command('ysb', aliases={'原神绑定', '绑定cookie'}, priority=7, block=True)
mys_sign = on_command('mys_sign', aliases={'mys签到', '米游社签到'}, priority=7, block=True)
mys_sign_auto = on_command('mys_sign_auto', aliases={'mys自动签到', '米游社自动签到'}, priority=7, block=True)
mys_sign_all = on_command('mys_sign_all', aliases={'全部重签'}, priority=7, permission=SUPERUSER, rule=to_me(), block=True)
add_public_ck = on_command('add_ck', aliases={'添加公共cookie', '添加公共ck'}, permission=SUPERUSER, priority=7, block=True)
delete_ck = on_command('delete_ck', aliases={'删除ck', '删除cookie'}, priority=7, block=True)
@ -308,6 +310,11 @@ async def mys_sign_auto_handler(event: MessageEvent, msg: Message = CommandArg()
await mys_sign_auto.finish('开启米游社自动签到成功,派蒙会在每日0点帮你签到', at_sender=True)
@mys_sign_all.handle()
async def sign_all():
await auto_sign()
@scheduler.scheduled_job('cron', hour=config.paimon_sign_hour, minute=config.paimon_sign_minute)
async def auto_sign():
data = await get_auto_sign()

View File

@ -1,10 +1,9 @@
import datetime
# from io import BytesIO
import os
from PIL import Image, ImageDraw, ImageFont
# from aiohttp import ClientSession
from nonebot.adapters.onebot.v11 import MessageSegment
from ..utils.util import pil2b64, get_pic
from ..utils.util import pil2b64
from ..utils.http_util import aiorequests
res_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'res')
@ -120,7 +119,7 @@ async def draw_abyss_card(data, uid, floor_num):
# defeat_rank_img.save(os.path.join(res_path, 'role_side_card', f"{defeat_rank['avatar_id']}.png"))
# else:
# defeat_rank_img = Image.open(os.path.join(res_path, 'role_side_card', f"{defeat_rank['avatar_id']}.png"))
defeat_rank_img = await get_pic(defeat_rank['avatar_icon'], (60, 60), 'RGBA')
defeat_rank_img = await aiorequests.get_img(url=defeat_rank['avatar_icon'], size=(60, 60), mode='RGBA')
top_draw.text((160, 343), str(defeat_rank['value']), font=get_font(21), fill='white')
top_img.alpha_composite(defeat_rank_img, (280, 320))
@ -132,7 +131,7 @@ async def draw_abyss_card(data, uid, floor_num):
# damage_rank_img.save(os.path.join(res_path, 'role_side_card', f"{damage_rank['avatar_id']}.png"))
# else:
# damage_rank_img = Image.open(os.path.join(res_path, 'role_side_card', f"{damage_rank['avatar_id']}.png"))
damage_rank_img = await get_pic(damage_rank['avatar_icon'], (60, 60), 'RGBA')
damage_rank_img = await aiorequests.get_img(url=damage_rank['avatar_icon'], size=(60, 60), mode='RGBA')
top_draw.text((495, 343), str(damage_rank['value']), font=get_font(21), fill='white')
top_img.alpha_composite(damage_rank_img, (590, 320))
@ -145,7 +144,7 @@ async def draw_abyss_card(data, uid, floor_num):
# else:
# take_damage_rank_img = Image.open(
# os.path.join(res_path, 'role_side_card', f"{take_damage_rank['avatar_id']}.png"))
take_damage_rank_img = await get_pic(take_damage_rank['avatar_icon'], (60, 60), 'RGBA')
take_damage_rank_img = await aiorequests.get_img(url=take_damage_rank['avatar_icon'], size=(60, 60), mode='RGBA')
top_draw.text((180, 389), str(take_damage_rank['value']), font=get_font(21), fill='white')
top_img.alpha_composite(take_damage_rank_img, (280, 365))
@ -158,7 +157,7 @@ async def draw_abyss_card(data, uid, floor_num):
# else:
# energy_skill_rank_img = Image.open(
# os.path.join(res_path, 'role_side_card', f"{energy_skill_rank['avatar_id']}.png"))
energy_skill_rank_img = await get_pic(energy_skill_rank['avatar_icon'], (60, 60), 'RGBA')
energy_skill_rank_img = await aiorequests.get_img(url=energy_skill_rank['avatar_icon'], size=(60, 60), mode='RGBA')
top_draw.text((530, 389), str(energy_skill_rank['value']), font=get_font(21), fill='white')
top_img.alpha_composite(energy_skill_rank_img, (590, 365))
@ -171,7 +170,7 @@ async def draw_abyss_card(data, uid, floor_num):
# else:
# normal_skill_rank_img = Image.open(
# os.path.join(res_path, 'role_side_card', f"{normal_skill_rank['avatar_id']}.png"))
normal_skill_rank_img = await get_pic(normal_skill_rank['avatar_icon'], (60, 60), 'RGBA')
normal_skill_rank_img = await aiorequests.get_img(url=normal_skill_rank['avatar_icon'], size=(60, 60), mode='RGBA')
top_draw.text((195, 435), str(normal_skill_rank['value']), font=get_font(21), fill='white')
top_img.alpha_composite(normal_skill_rank_img, (280, 410))

View File

@ -1,158 +1,15 @@
import random
import datetime
# from io import BytesIO
import os
from PIL import Image, ImageDraw, ImageFont
import matplotlib.pyplot as plt
# from aiohttp import ClientSession
from nonebot.adapters.onebot.v11 import MessageSegment
from ..utils.util import pil2b64, get_pic
from ..utils.util import pil2b64
from ..utils.http_util import aiorequests
res_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'res')
# def get_font(size):
# return ImageFont.truetype(os.path.join(res_path, 'msyhbd.ttc'), size)
#
#
# def get_odd_time(seconds):
# m, s = divmod(int(seconds), 60)
# h, m = divmod(m, 60)
# return "剩余%02d时%02d分%02d秒" % (h, m, s)
#
#
# async def get_avater_pic(avater_url):
# async with ClientSession() as session:
# res = await session.get(avater_url)
# res = await res.read()
# avater = Image.open(BytesIO(res)).convert("RGBA").resize((60, 60))
# return avater
#
#
# bg_card_color = {'1': '#C3B8A4', '2': '#C3B8A4', '3': '#4C74A7', '4': '#D7B599'}
#
#
# async def draw_daily_note_card(data, uid):
# if not data:
# return '数据出错'
# if data['retcode'] == 10102:
# return '这uid没有在米游社公开信息哦,请到 个人主页-管理 中打开'
# elif data['retcode'] == 10104:
# return 'uid有误哦检查一下或再手动输入一次uid吧'
# elif data['retcode'] != 0:
# return f'派蒙获取数据失败了,获取状态:\n{data["message"]},{data["retcode"]}'
# data = data['data']
# # 载入所需素材图标
# bg_color = random.choice(list(bg_card_color.items()))
# bg_img = Image.open(os.path.join(res_path, 'daily_note', f'便签背景{bg_color[0]}.png')).convert("RGBA")
# enemy = Image.open(os.path.join(res_path, 'daily_note', '周本.png')).convert("RGBA")
# task = Image.open(os.path.join(res_path, 'daily_note', '委托.png')).convert("RGBA")
# power = Image.open(os.path.join(res_path, 'daily_note', '树脂.png')).convert("RGBA")
# money = Image.open(os.path.join(res_path, 'daily_note', '洞天宝钱.png')).convert("RGBA")
# send_icon = Image.open(os.path.join(res_path, 'daily_note', '派遣背景.png')).convert("RGBA").resize((110, 55))
# send_finish_icon = Image.open(os.path.join(res_path, 'daily_note', '派遣完成.png')).convert("RGBA").resize((55, 55))
# abyss = Image.open(os.path.join(res_path, 'daily_note', '深渊.png')).convert('RGBA').resize((160, 160))
# tran = Image.open(os.path.join(res_path, 'daily_note', '参量.png')).convert('RGBA').resize((40, 40))
# bg_draw = ImageDraw.Draw(bg_img)
#
# bg_draw.text((23, 20), '实时便笺', font=get_font(30), fill='white')
# bg_draw.text((255, 20), 'UID' + uid, font=get_font(30), fill='white')
# # 树脂
# bg_img.alpha_composite(power, (120, 150))
# bg_draw.text((170, 145), f'{data["current_resin"]}/160', font=get_font(30), fill=bg_color[1])
# if data["current_resin"] == 160:
# bg_draw.text((310, 144), '已回满', font=get_font(30), fill=bg_color[1])
# else:
# recover_time = datetime.datetime.now() + datetime.timedelta(seconds=int(data['resin_recovery_time']))
# # recover_time_day = recover_time.day > datetime.datetime.now().day and '明天' or '今天'
# recover_time_day = '今天' if recover_time.day == datetime.datetime.now().day else '明天'
# recover_time_str = f'将于{recover_time_day}{recover_time.strftime("%H:%M")}回满'
# bg_draw.text((320, 147), recover_time_str, font=get_font(25), fill=bg_color[1])
# # 洞天宝钱
# bg_img.alpha_composite(money, (120, 220))
# bg_draw.text((170, 220), f'{data["current_home_coin"]}/2400', font=get_font(30), fill=bg_color[1])
# if data["current_home_coin"] == 2400:
# bg_draw.text((350, 219), '已存满', font=get_font(30), fill=bg_color[1])
# else:
# recover_time = datetime.datetime.now() + datetime.timedelta(seconds=int(data['home_coin_recovery_time']))
# recover_time_day = recover_time.day - datetime.datetime.now().day
# if recover_time_day == 1:
# recover_time_day_str = '明天'
# elif recover_time_day == 0:
# recover_time_day_str = '今天'
# else:
# recover_time_day_str = str(recover_time.day) + '日'
# recover_time_str = f'将于{recover_time_day_str}{recover_time.strftime("%H:%M")}攒满'
# # recover_time_str = f'将于{recover_time.strftime("%d日%H:%M")}攒满'
# bg_draw.text((360, 222), recover_time_str, font=get_font(25), fill=bg_color[1])
# # 委托
# bg_img.alpha_composite(task, (120, 295))
# bg_draw.text((170, 297), f'{data["finished_task_num"]}/4', font=get_font(30), fill=bg_color[1])
# if data["finished_task_num"] == 4:
# bg_draw.text((247, 297), '已完成', font=get_font(30), fill=bg_color[1])
# else:
# bg_draw.text((245, 298), '未完成', font=get_font(25), fill=bg_color[1])
# # 周本
# bg_img.alpha_composite(enemy, (120, 370))
# bg_draw.text((170, 370), f'{data["remain_resin_discount_num"]}/3', font=get_font(30), fill=bg_color[1])
# if data["remain_resin_discount_num"] == 0:
# bg_draw.text((247, 369), '已完成', font=get_font(30), fill=bg_color[1])
# else:
# bg_draw.text((245, 372), '未完成', font=get_font(25), fill=bg_color[1])
# # 参量质变仪
# bg_img.alpha_composite(tran, (360, 297))
# if not data['transformer']['obtained']:
# bg_draw.text((413, 298), '未获得', font=get_font(25), fill=bg_color[1])
# else:
# if data['transformer']['recovery_time']['reached']:
# bg_draw.text((415, 297), '已可用', font=get_font(30), fill=bg_color[1])
# else:
# bg_draw.text((413, 298), f"{data['transformer']['recovery_time']['Day']}天后", font=get_font(25),
# fill=bg_color[1])
# # 深渊
# abyss_new_month = datetime.datetime.now().month if datetime.datetime.now().day < 16 else datetime.datetime.now().month + 1
# abyss_new_day = 16 if datetime.datetime.now().day < 16 else 1
# abyss_new = datetime.datetime.strptime('2022.' + str(abyss_new_month) + '.' + str(abyss_new_day) + '.04:00',
# '%Y.%m.%d.%H:%M') - datetime.datetime.now()
# abyss_new_str = f'{abyss_new.days + 1}天后刷新' if abyss_new.days <= 8 else '已刷新'
# bg_img.alpha_composite(abyss, (520, 264))
# bg_draw.text((568, 300), '深渊', font=get_font(30), fill=bg_color[1])
# if abyss_new_str == '已刷新':
# bg_draw.text((561, 350), abyss_new_str, font=get_font(25), fill=bg_color[1])
# else:
# bg_draw.text((540, 350), abyss_new_str, font=get_font(25), fill=bg_color[1])
# # 派遣
# h = 430
# if not data['expeditions']:
# bg_draw.text((300, h + 140), '没有派遣信息', font=get_font(30), fill=bg_color[1])
# else:
# for send in data['expeditions']:
# send_avatar = await get_avater_pic(send['avatar_side_icon'])
# send_status = '派遣已完成!' if send['status'] == 'Finished' else get_odd_time(send['remained_time'])
# bg_draw.rectangle((145, h, 645, h + 55), fill=None, outline=bg_color[1], width=3)
# if send['status'] == 'Finished':
# bg_img.alpha_composite(send_finish_icon, (590, h))
# bg_img.alpha_composite(send_icon, (150, h))
# bg_img.alpha_composite(send_avatar, (150, h - 10))
# if send_status == '派遣已完成!':
# bg_draw.text((329, h + 10), send_status, font=get_font(25), fill=bg_color[1])
# else:
# bg_draw.text((300, h + 10), send_status, font=get_font(25), fill=bg_color[1])
# h += 57
# last_finish_second = int(max([s['remained_time'] for s in data['expeditions']]))
# if last_finish_second != 0:
# last_finish_time = datetime.datetime.now() + datetime.timedelta(seconds=last_finish_second)
# last_finish_day = last_finish_time.day > datetime.datetime.now().day and '明天' or '今天'
# last_finish_str = f'将于{last_finish_day}{last_finish_time.strftime("%H:%M")}完成全部派遣'
# bg_draw.text((211, h + 3.5), last_finish_str, font=get_font(30), fill=bg_color[1])
# else:
# bg_draw.text((290, h + 3.5), '派遣已全部完成', font=get_font(30), fill=bg_color[1])
# bg_draw.text((274, 797), 'Created by 惜月の小派蒙', font=get_font(20), fill=bg_color[1])
#
# bg_img = pil2b64(bg_img, 70)
# bg_img = MessageSegment.image(bg_img)
# return bg_img
def get_font(size, font='msyhbd.ttc'):
return ImageFont.truetype(os.path.join(res_path, font), size)
@ -259,7 +116,7 @@ async def draw_daily_note_card(data, uid):
exp = data['expeditions']
i = 0
for role in exp:
role_avatar = await get_pic(role['avatar_side_icon'], (135, 135), 'RGBA')
role_avatar = await aiorequests.get_img(url=role['avatar_side_icon'], size=(135, 135), mode='RGBA')
bg_img.alpha_composite(role_avatar, (i * 200 + 168, 1537))
bg_img.alpha_composite(await draw_ring(1 - int(role['remained_time']) / 72000), (i * 201 + 101, 1490))
if role['status'] == 'Ongoing':

View File

@ -2,7 +2,6 @@ import random
from PIL import Image, ImageDraw, ImageFont
import os
import matplotlib.pyplot as plt
# from io import BytesIO
from ..utils.util import pil2b64
from nonebot.adapters.onebot.v11 import MessageSegment

View File

@ -1,10 +1,9 @@
import os, random, re
from PIL import Image, ImageDraw, ImageFont
from ..utils.util import pil2b64, get_pic
from ..utils.util import pil2b64
from nonebot.adapters.onebot.v11 import MessageSegment
# from aiohttp import ClientSession
# from io import BytesIO
import copy
from ..utils.http_util import aiorequests
res_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'res')
@ -50,7 +49,7 @@ async def get_chara_card(data):
# weapon_icon = Image.open(BytesIO(weapon_icon)).convert("RGBA")
# weapon_icon.save(os.path.join(res_path, 'weapon', weapon_name))
# weapon_icon = Image.open(os.path.join(res_path, 'weapon', weapon_name)).resize((63, 63))
weapon_icon = await get_pic(data['weapon']['icon'], (63, 63), 'RGBA')
weapon_icon = await aiorequests.get_img(url=data['weapon']['icon'], size=(63, 63), mode='RGBA')
chara_card.alpha_composite(weapon_icon, (0, 230))
# 等级信息
chara_draw = ImageDraw.Draw(chara_card)
@ -281,7 +280,7 @@ async def get_chara_card_long(data):
# weapon_icon = Image.open(BytesIO(weapon_icon)).convert("RGBA")
# weapon_icon.save(os.path.join(res_path, 'weapon', weapon_name))
# weapon_icon = Image.open(os.path.join(res_path, 'weapon', weapon_name)).resize((62, 62))
weapon_icon = await get_pic(data['weapon']['icon'], (62, 62), 'RGBA')
weapon_icon = await aiorequests.get_img(url=data['weapon']['icon'], size=(62, 62), mode='RGBA')
chara_card.alpha_composite(weapon_icon, (3, 291))
# 等级信息
chara_draw = ImageDraw.Draw(chara_card)
@ -354,7 +353,7 @@ async def draw_reli_icon(data):
# icon.save(os.path.join(res_path, 'reliquaries', f'{data["id"]}.png'))
# else:
# icon = Image.open(os.path.join(res_path, 'reliquaries', f'{data["id"]}.png')).resize((80, 80))
icon = await get_pic(data["icon"], (80, 80), 'RGBA')
icon = await aiorequests.get_img(url=data["icon"], size=(80, 80), mode='RGBA')
base_icon.alpha_composite(icon, (0, 0))
base_icon.alpha_composite(shadow, (40, 60))
base_icon_draw = ImageDraw.Draw(base_icon)
@ -371,7 +370,7 @@ async def draw_const_skill_icon(data, name):
# icon.save(os.path.join(res_path, 'reliquaries', f'{name}{data["id"]}.png'))
# else:
# icon = Image.open(os.path.join(res_path, 'reliquaries', f'{name}{data["id"]}.png')).resize((65, 65))
icon = await get_pic(data["icon"], (65, 65), 'RGBA')
icon = await aiorequests.get_img(url=data["icon"], size=(65, 65), mode='RGBA')
base_icon.alpha_composite(icon, (0, 0))
if 'is_actived' in data and not data['is_actived']:
unlock_icon = Image.open(os.path.join(res_path, 'other', '命座未解锁.png')).resize((65, 65))

View File

@ -1,6 +1,6 @@
from aiohttp import ClientSession
from ..utils.util import get_headers, get_sign_headers, cache, get_use_cookie, get_own_cookie, check_retcode
from ..utils.db_util import update_cookie_cache
from ..utils.http_util import aiorequests
import datetime
import re
@ -11,22 +11,22 @@ async def get_abyss_data(user_id, uid, schedule_type="1", use_cache=True):
url = "https://api-takumi-record.mihoyo.com/game_record/app/genshin/api/spiralAbyss"
params = {
"schedule_type": schedule_type,
"role_id": uid,
"server": server_id}
"role_id": uid,
"server": server_id}
while True:
cookie = await get_use_cookie(user_id, uid=uid, action='查询深渊')
if not cookie:
return '现在派蒙没有可以用的cookie哦可能是:\n1.公共cookie全都达到了每日30次上限\n2.公共池全都失效了或没有cookie\n让管理员使用 添加公共ck 吧!'
headers = get_headers(q=f'role_id={uid}&schedule_type={schedule_type}&server={server_id}',
cookie=cookie['cookie'])
async with ClientSession() as session:
res = await session.get(url=url, headers=headers, params=params)
data = await res.json()
check = await check_retcode(data, cookie, uid)
if check == '私人cookie达到了每日30次查询上限':
return check
elif check:
return data
resp = await aiorequests.get(url=url, headers=headers, params=params)
data = resp.json()
check = await check_retcode(data, cookie, uid)
if check == '私人cookie达到了每日30次查询上限':
return check
elif check:
return data
async def get_daily_note_data(uid):
@ -38,16 +38,15 @@ async def get_daily_note_data(uid):
await update_cookie_cache(cookie['cookie'], uid, 'uid')
headers = get_headers(q=f'role_id={uid}&server={server_id}', cookie=cookie['cookie'])
params = {
"server": server_id,
"server": server_id,
"role_id": uid
}
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):
return data
else:
return f'你的uid{uid}的cookie已过期,需要重新绑定哦!'
resp = await aiorequests.get(url=url, headers=headers, params=params)
data = resp.json()
if await check_retcode(data, cookie, uid):
return data
else:
return f'你的uid{uid}的cookie已过期,需要重新绑定哦!'
@cache(ttl=datetime.timedelta(hours=1))
@ -55,7 +54,7 @@ async def get_player_card_data(user_id, uid, use_cache=True):
server_id = "cn_qd01" if uid[0] == '5' else "cn_gf01"
url = "https://api-takumi-record.mihoyo.com/game_record/app/genshin/api/index"
params = {
"server": server_id,
"server": server_id,
"role_id": uid
}
while True:
@ -63,22 +62,21 @@ async def get_player_card_data(user_id, uid, use_cache=True):
if not cookie:
return '现在派蒙没有可以用的cookie哦可能是:\n1.公共cookie全都达到了每日30次上限\n2.公共池全都失效了或没有cookie\n让管理员使用 添加公共ck 吧!'
headers = get_headers(q=f'role_id={uid}&server={server_id}', cookie=cookie['cookie'])
async with ClientSession() as session:
res = await session.get(url=url, headers=headers, params=params)
data = await res.json()
check = await check_retcode(data, cookie, uid)
if check == '私人cookie达到了每日30次查询上限':
return check
elif check:
return data
resp = await aiorequests.get(url=url, headers=headers, params=params)
data = resp.json()
check = await check_retcode(data, cookie, uid)
if check == '私人cookie达到了每日30次查询上限':
return check
elif check:
return data
@cache(ttl=datetime.timedelta(hours=1))
async def get_chara_detail_data(user_id, uid, use_cache=True):
server_id = "cn_qd01" if uid[0] == '5' else "cn_gf01"
json_data = {
"server": server_id,
"role_id": uid,
"server": server_id,
"role_id": uid,
"character_ids": []
}
url = 'https://api-takumi-record.mihoyo.com/game_record/app/genshin/api/character'
@ -87,14 +85,13 @@ async def get_chara_detail_data(user_id, uid, use_cache=True):
if not cookie:
return '现在派蒙没有可以用的cookie哦可能是:\n1.公共cookie全都达到了每日30次上限\n2.公共池全都失效了或没有cookie\n让管理员使用 添加公共ck 吧!'
headers = get_headers(b=json_data, cookie=cookie['cookie'])
async with ClientSession() as session:
res = await session.post(url=url, headers=headers, json=json_data)
data = await res.json()
check = await check_retcode(data, cookie, uid)
if check == '私人cookie达到了每日30次查询上限':
return check
elif check:
return data
resp = await aiorequests.post(url=url, headers=headers, json=json_data)
data = resp.json()
check = await check_retcode(data, cookie, uid)
if check == '私人cookie达到了每日30次查询上限':
return check
elif check:
return data
@cache(ttl=datetime.timedelta(hours=1))
@ -107,14 +104,13 @@ async def get_chara_skill_data(uid, chara_id, use_cache=True):
await update_cookie_cache(cookie['cookie'], uid, 'uid')
headers = get_headers(q=f'uid={uid}&region={server_id}&avatar_id={chara_id}', cookie=cookie['cookie'])
params = {
"region": server_id,
"uid": uid,
"region": server_id,
"uid": uid,
"avatar_id": chara_id
}
async with ClientSession() as session:
res = await session.get(url=url, headers=headers, params=params)
data = await res.json()
return data
resp = await aiorequests.get(url=url, headers=headers, params=params)
data = resp.json()
return data
@cache(ttl=datetime.timedelta(hours=1))
@ -127,17 +123,16 @@ async def get_monthinfo_data(uid, month, use_cache=True):
await update_cookie_cache(cookie['cookie'], uid, 'uid')
headers = get_headers(q=f'month={month}&bind_uid={uid}&bind_region={server_id}', cookie=cookie['cookie'])
params = {
"month": int(month),
"bind_uid": uid,
"month": int(month),
"bind_uid": uid,
"bind_region": server_id
}
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):
return data
else:
return f'你的uid{uid}的cookie已过期,需要重新绑定哦!'
resp = await aiorequests.get(url=url, headers=headers, params=params)
data = resp.json()
if await check_retcode(data, cookie, uid):
return data
else:
return f'你的uid{uid}的cookie已过期,需要重新绑定哦!'
async def get_bind_game(cookie):
@ -152,9 +147,9 @@ async def get_bind_game(cookie):
params = {
"uid": uid
}
async with ClientSession() as session:
res = await session.get(url=url, headers=headers, params=params)
return (await res.json()), uid
resp = await aiorequests.get(url=url, headers=headers, params=params)
data = resp.json()
return data, uid
# 获取今日签到信息
@ -167,25 +162,24 @@ async def get_sign_info(uid):
headers = {
'x-rpc-app_version': '2.11.1',
'x-rpc-client_type': '5',
'Origin': 'https://webstatic.mihoyo.com',
'Referer': 'https://webstatic.mihoyo.com/',
'Cookie': cookie['cookie'],
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS '
'X) AppleWebKit/605.1.15 (KHTML, like Gecko) miHoYoBBS/2.11.1',
'Origin': 'https://webstatic.mihoyo.com',
'Referer': 'https://webstatic.mihoyo.com/',
'Cookie': cookie['cookie'],
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS '
'X) AppleWebKit/605.1.15 (KHTML, like Gecko) miHoYoBBS/2.11.1',
}
params = {
'act_id': 'e202009291139501',
'region': server_id,
'uid': uid
'uid': uid
}
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):
return data
else:
return f'你的uid{uid}的cookie已过期,需要重新绑定哦!'
resp = await aiorequests.get(url=url, headers=headers, params=params)
data = resp.json()
if await check_retcode(data, cookie, uid):
return data
else:
return f'你的uid{uid}的cookie已过期,需要重新绑定哦!'
# 执行签到操作
@ -198,19 +192,18 @@ async def sign(uid):
headers = get_sign_headers(cookie['cookie'])
json_data = {
'act_id': 'e202009291139501',
'uid': uid,
'uid': uid,
'region': server_id
}
async with ClientSession() as session:
res = await session.post(url=url, headers=headers, json=json_data)
try:
data = await res.json()
except:
return await res.read()
if await check_retcode(data, cookie, uid):
return data
else:
return f'你的uid{uid}的cookie已过期,需要重新绑定哦!'
resp = await aiorequests.post(url=url, headers=headers, json=json_data)
try:
data = resp.json()
except:
return resp.read()
if await check_retcode(data, cookie, uid):
return data
else:
return f'你的uid{uid}的cookie已过期,需要重新绑定哦!'
# 获取签到奖励列表
@ -218,14 +211,14 @@ async def get_sign_list():
url = 'https://api-takumi.mihoyo.com/event/bbs_sign_reward/home'
headers = {
'x-rpc-app_version': '2.11.1',
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 ('
'KHTML, like Gecko) miHoYoBBS/2.11.1',
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 ('
'KHTML, like Gecko) miHoYoBBS/2.11.1',
'x-rpc-client_type': '5',
'Referer': 'https://webstatic.mihoyo.com/'
'Referer': 'https://webstatic.mihoyo.com/'
}
params = {
'act_id': 'e202009291139501'
}
async with ClientSession() as session:
res = await session.get(url=url, headers=headers, params=params)
return await res.json()
resp = await aiorequests.get(url=url, headers=headers, params=params)
data = resp.json()
return data

View File

@ -1,10 +1,10 @@
from aiohttp import ClientSession
from urllib.parse import quote
from nonebot import on_command
from nonebot.params import CommandArg
from nonebot.adapters.onebot.v11 import MessageEvent
from ..utils.util import FreqLimiter, get_id
from ..utils.config import config
from ..utils.http_util import aiorequests
couplets = on_command('对联', aliases={'对对联'}, priority=13, block=True)
@ -28,10 +28,9 @@ async def couplets_handler(event: MessageEvent, msg=CommandArg()):
couplets_limit.start_cd(get_id(event), config.paimon_couplets_cd)
text = quote(str(word))
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 = ''
for n in range(0, num):
result += res['output'][n] + '\n'
await couplets.finish(f'上联:{word}\n下联:{result}')
res = await aiorequests.get(url=url)
res = res.json()
result = ''
for n in range(0, num):
result += res['output'][n] + '\n'
await couplets.finish(f'上联:{word}\n下联:{result}')

View File

@ -1,9 +1,9 @@
import re
from aiohttp import ClientSession
from nonebot import on_command, require, get_bot, logger
from nonebot.params import CommandArg
from nonebot.adapters.onebot.v11 import MessageEvent, MessageSegment
from ..utils.util import load_data, save_data, get_id
from ..utils.http_util import aiorequests
news60s_pic = on_command('早报', aliases={'今日早报', '今日新闻', '60s读世界'}, priority=13, block=True)
@ -15,13 +15,12 @@ async def news60s_pic_handler(event: MessageEvent, msg=CommandArg()):
msg = str(msg).strip()
if not msg:
url = 'https://api.iyk0.com/60s/'
async with ClientSession() as session:
res = await session.get(url)
res = await res.json()
await news60s_pic.finish(MessageSegment.image(file=res['imageUrl']))
res = await aiorequests.get(url=url)
res = res.json()
await news60s_pic.finish(MessageSegment.image(file=res['imageUrl']))
elif msg.startswith('开启推送'):
# 匹配msg中的xx:xx时间
time_str = re.search(r'(\d{2}):(\d{2})', msg)
time_str = re.search(r'(\d{1,2}):(\d{2})', msg)
if time_str:
push_data = load_data('news60s_push.json')
push_id = str(get_id(event))
@ -32,12 +31,14 @@ async def news60s_pic_handler(event: MessageEvent, msg=CommandArg()):
}
if event.message_type == 'guild':
push_data[push_id]['guild_id'] = event.guild_id
if scheduler.get_job('60sNews' + str(get_id(event))):
scheduler.remove_job('60sNews' + str(get_id(event)))
scheduler.add_job(
func=news60s_push_task,
trigger='cron',
hour=int(time_str.group(1)),
minute=int(time_str.group(2)),
id=str(get_id(event)),
id='60sNews' + str(get_id(event)),
args=(str(get_id(event)),
push_data[str(get_id(event))])
)
@ -47,8 +48,8 @@ async def news60s_pic_handler(event: MessageEvent, msg=CommandArg()):
await news60s_pic.finish('请给出正确的时间格式为12:00', at_sender=True)
elif msg.startswith('关闭推送'):
push_data = load_data('news60s_push.json')
del push_data[str(event.group_id or event.channel_id or event.user_id)]
scheduler.remove_job(str(get_id(event)))
del push_data[str(get_id(event))]
scheduler.remove_job('60sNews' + str(get_id(event)))
save_data(push_data, 'news60s_push.json')
await news60s_pic.finish('关闭60s读世界推送成功', at_sender=True)
@ -56,17 +57,16 @@ async def news60s_pic_handler(event: MessageEvent, msg=CommandArg()):
async def news60s_push_task(push_id, push_data: dict):
try:
url = 'https://api.iyk0.com/60s/'
async with ClientSession() as session:
res = await session.get(url)
res = await res.json()
if push_data['type'] == 'group':
await get_bot().send_group_msg(group_id=push_id, message=MessageSegment.image(file=res['imageUrl']))
elif push_data['type'] == 'private':
await get_bot().send_private_msg(user_id=push_id, message=MessageSegment.image(file=res['imageUrl']))
elif push_data['type'] == 'guild':
await get_bot().send_guild_channel_msg(guild_id=push_data['guild_id'], channel_id=push_id,
message=MessageSegment.image(file=res['imageUrl']))
logger.info(f'{push_data["type"]}{push_id}的60秒读世界推送成功')
res = await aiorequests.get(url=url)
res = res.json()
if push_data['type'] == 'group':
await get_bot().send_group_msg(group_id=push_id, message=MessageSegment.image(file=res['imageUrl']))
elif push_data['type'] == 'private':
await get_bot().send_private_msg(user_id=push_id, message=MessageSegment.image(file=res['imageUrl']))
elif push_data['type'] == 'guild':
await get_bot().send_guild_channel_msg(guild_id=push_data['guild_id'], channel_id=push_id,
message=MessageSegment.image(file=res['imageUrl']))
logger.info(f'{push_data["type"]}{push_id}的60秒读世界推送成功')
except Exception as e:
logger.exception(f'{push_data["type"]}{push_id}的60秒读世界推送失败{e}')
@ -77,7 +77,7 @@ for push_id, push_data in load_data('news60s_push.json').items():
trigger='cron',
hour=push_data['hour'],
minute=push_data['minute'],
id=push_id,
id='60sNews' + push_id,
args=(push_id,
push_data)
)
)

View File

@ -1,9 +1,9 @@
import random
from aiohttp import ClientSession
from nonebot import on_command
from nonebot.params import CommandArg
from nonebot.adapters.onebot.v11 import Message, MessageEvent, MessageSegment
from ..utils.util import FreqLimiter
from ..utils.http_util import aiorequests
order_pic = on_command('点菜', aliases={'点餐', '食谱', '我想吃'}, priority=13, block=True)
order_lmt = FreqLimiter(10)
@ -18,19 +18,18 @@ async def order_pic_handler(event: MessageEvent, msg=CommandArg()):
await order_pic.finish(f'点餐冷却ing(剩余{order_lmt.left_time(event.user_id)}秒)')
else:
url = 'https://api.iyk0.com/shipu/?key=' + msg
async with ClientSession() as session:
res = await session.get(url)
res = await res.json()
if res['code'] == 202:
await order_pic.finish('没有找到这种食品哦~')
order_lmt.start_cd(event.user_id, 10)
number = random.randint(1, 3)
recipe_list = []
for i in range(0, number):
recipe = random.choice(res['data'])
if recipe not in recipe_list:
recipe_list.append(recipe)
mes = Message()
for recipe in recipe_list:
mes += MessageSegment.text(recipe['name'] + '\n') + MessageSegment.image(recipe['img']) + '\n'
await order_pic.finish(mes, at_sender=True)
res = await aiorequests.get(url=url)
res = res.json()
if res['code'] == 202:
await order_pic.finish('没有找到这种食品哦~')
order_lmt.start_cd(event.user_id, 10)
number = random.randint(1, 3)
recipe_list = []
for i in range(0, number):
recipe = random.choice(res['data'])
if recipe not in recipe_list:
recipe_list.append(recipe)
mes = Message()
for recipe in recipe_list:
mes += MessageSegment.text(recipe['name'] + '\n') + MessageSegment.image(recipe['img']) + '\n'
await order_pic.finish(mes, at_sender=True)

View File

@ -1,5 +1,4 @@
from aiohttp import ClientSession
from ..utils.http_util import aiorequests
# 数据源自微信公众号原神创意工坊
headers = {
@ -16,9 +15,8 @@ async def get_rate(type: str = 'role'):
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()
res = await aiorequests.post(url=url, headers=headers, json=json_data)
return res.json()
async def get_formation_rate(layer: int = 1):
@ -27,9 +25,8 @@ async def get_formation_rate(layer: int = 1):
"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()
res = await aiorequests.post(url=url, headers=headers, json=json_data)
return res.json()
async def get_teammates_rate(name: str):
@ -38,9 +35,8 @@ async def get_teammates_rate(name: str):
"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()
res = await aiorequests.post(url=url, headers=headers, json=json_data)
return res.json()
async def get_weapon_rate(name: str):
@ -49,6 +45,5 @@ async def get_weapon_rate(name: str):
"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()
res = await aiorequests.post(url=url, headers=headers, json=json_data)
return res.json()

View File

@ -1,4 +1,5 @@
from ..utils.util import get_pic, pil2b64
from ..utils.util import pil2b64
from ..utils.http_util import aiorequests
blue = {
'胡桃': ['', (0, 1886)],
@ -59,8 +60,8 @@ blue = {
async def get_blue_pic(name):
for c in blue.items():
if c[0] == name:
img = await get_pic(f'https://static.cherishmoon.fun/LittlePaimon/blue/{c[1][0]}.jpg')
img = img.crop((0, c[1][1][0], 1080, c[1][1][1]))
img = await aiorequests.get_img(url=f'https://static.cherishmoon.fun/LittlePaimon/blue/{c[1][0]}.jpg')
img = img.crop((0, int(c[1][1][0]), 1080, int(c[1][1][1])))
img = pil2b64(img, 100)
return img
return None

View File

@ -1,5 +1,5 @@
<p align="center" >
<a href="https://github.com/CMHopeSunshine/LittlePaimon/tree/nonebot2"><img src="https://cherishmoon.oss-cn-shenzhen.aliyuncs.com/LittlePaimon/readme/logo.png" width="256" height="256" alt="LittlePaimon"></a>
<a href="https://github.com/CMHopeSunshine/LittlePaimon/tree/nonebot2"><img src="https://static.cherishmoon.fun/LittlePaimon/readme/logo.png" width="256" height="256" alt="LittlePaimon"></a>
</p>
<h1 align="center">小派蒙|LittlePaimon</h1>
<h4 align="center">✨基于<a href="https://github.com/Ice-Cirno/HoshinoBot" target="_blank">HoshinoBot</a>|<a href="https://github.com/nonebot/nonebot2" target="_blank">NoneBot2</a><a href="https://github.com/Mrs4s/go-cqhttp" target="_blank">go-cqhttp</a>的原神Q群机器人✨</h4>
@ -21,48 +21,55 @@
## 功能示例
<img src="https://cherishmoon.oss-cn-shenzhen.aliyuncs.com/LittlePaimon/readme/ys.jpg" alt="ys">
<img src="https://static.cherishmoon.fun/LittlePaimon/readme/ys.jpg" alt="ys">
<details>
<summary>角色背包</summary>
<img src="https://cherishmoon.oss-cn-shenzhen.aliyuncs.com/LittlePaimon/readme/ysa.jpg" alt="ysa">
<img src="https://static.cherishmoon.fun/LittlePaimon/readme/ysa.jpg" alt="ysa">
</details>
<details>
<summary>角色详情</summary>
<img src="https://cherishmoon.oss-cn-shenzhen.aliyuncs.com/LittlePaimon/readme/ysc.jpg" alt="ysc">
<img src="https://static.cherishmoon.fun/LittlePaimon/readme/ysc.jpg" alt="ysc">
</details>
<details>
<summary>深渊信息</summary>
<img src="https://cherishmoon.oss-cn-shenzhen.aliyuncs.com/LittlePaimon/readme/sy12.jpg" alt="sy">
<img src="https://static.cherishmoon.fun/LittlePaimon/readme/sy12.jpg" alt="sy">
</details>
<details>
<summary>模拟抽卡</summary>
<img src="https://cherishmoon.oss-cn-shenzhen.aliyuncs.com/LittlePaimon/readme/十连.jpg" alt="十连">
<img src="https://static.cherishmoon.fun/LittlePaimon/readme/十连.jpg" alt="十连">
</details>
<details>
<summary>实时便签</summary>
<img src="https://cherishmoon.oss-cn-shenzhen.aliyuncs.com/LittlePaimon/readme/ssbq.jpg" alt="ssbq">
<img src="https://static.cherishmoon.fun/LittlePaimon/readme/ssbq.jpg" alt="ssbq">
</details>
<details>
<summary>每月札记</summary>
<img src="https://cherishmoon.oss-cn-shenzhen.aliyuncs.com/LittlePaimon/readme/myzj.jpg" alt="myzj">
<img src="https://static.cherishmoon.fun/LittlePaimon/readme/myzj.jpg" alt="myzj">
</details>
<details>
<summary>角色材料</summary>
<img src="https://cherishmoon.oss-cn-shenzhen.aliyuncs.com/LittlePaimon/readme/material.png" alt="material">
<img src="https://static.cherishmoon.fun/LittlePaimon/readme/material.png" alt="material">
</details>
<details>
<summary>抽卡记录</summary>
<img src="https://cherishmoon.oss-cn-shenzhen.aliyuncs.com/LittlePaimon/readme/gachalog.jpg" alt="gachalog">
<img src="https://static.cherishmoon.fun/LittlePaimon/readme/gachalog.jpg" alt="gachalog">
</details>
## 更新日志
+ 5.19
- 米游社签到新增`全部重签`,仅限超级管理员使用,需@机器人
- `原神猜语音`不再需要`我猜`,直接回答角色别名即可参与猜猜看
- 异步请求库从`aiohttp`改用`httpx`,需安装依赖库`pip install httpx`
- 修复`60秒读世界`在频道无法关闭推送的BUG
## 功能列表
详见[功能列表](https://blog.cherishmoon.fun/bot/NoneBot2FuncList.html)
@ -113,8 +120,8 @@ javascript:(function(){prompt(document.domain,document.cookie)})();
- [NoneBot2](https://github.com/nonebot/nonebot2) - 跨平台异步机器人框架
- [go-cqhttp](https://github.com/Mrs4s/go-cqhttp) - Onebot标准的框架实现
- [Nwflower](https://github.com/Nwflower) - 部分图片的美工大大和武器攻略图提供
- [egenshin](https://github.com/pcrbot/erinilis-modules/tree/master/egenshin) - 参考了它的抽卡代码和资源
- [西北一枝花](https://github.com/Nwflower) - 部分图片的美工大大和武器攻略图提供
- [egenshin](https://github.com/pcrbot/erinilis-modules/tree/master/egenshin) - 参考了它的代码和资源
- [bluemushoom](https://bbs.nga.cn/nuke.php?func=ucp&uid=62861898) - 全角色收益曲线和参考面板攻略图来源
- [genshin-gacha-export](https://github.com/sunfkny/genshin-gacha-export) - 抽卡记录导出参考
- [西风驿站](https://bbs.mihoyo.com/ys/collection/307224) - 角色攻略一图流来源

79
utils/http_util.py Normal file
View File

@ -0,0 +1,79 @@
import base64
from typing import Dict, Optional, Any, Union, Tuple
from pathlib import Path
from io import BytesIO
from PIL import Image
from retrying import retry
import httpx
class aiorequests:
@classmethod
async def get(cls,
url: str,
*,
headers: Optional[Dict[str, str]] = None,
params: Optional[Dict[str, Any]] = None,
timeout: Optional[int] = 20,
**kwargs) -> httpx.Response:
async with httpx.AsyncClient() as client:
return await client.get(url,
headers=headers,
params=params,
timeout=timeout,
**kwargs)
@classmethod
async def post(cls,
url: str,
*,
headers: Optional[Dict[str, str]] = None,
params: Optional[Dict[str, Any]] = None,
data: Optional[Dict[str, Any]] = None,
json: Optional[Dict[str, Union[Any, str]]] = None,
timeout: Optional[int] = 20,
**kwargs) -> httpx.Response:
async with httpx.AsyncClient() as client:
return await client.post(url,
headers=headers,
params=params,
data=data,
json=json,
timeout=timeout,
**kwargs)
@classmethod
@retry(stop_max_attempt_number=3, wait_fixed=300)
async def get_img(cls,
url: str,
*,
headers: Optional[Dict[str, str]] = None,
params: Optional[Dict[str, Any]] = None,
timeout: Optional[int] = 20,
save_path: Optional[Union[str, Path]] = None,
size: Optional[Tuple[int, int]] = None,
mode: Optional[str] = None,
to_b64: bool = False,
**kwargs) -> Union[str, Image.Image]:
async with httpx.AsyncClient() as client:
resp = await client.get(url,
headers=headers,
params=params,
timeout=timeout,
**kwargs)
if to_b64:
return 'base64://' + base64.b64encode(resp.read()).decode()
else:
img = Image.open(BytesIO(resp.read()))
if size:
img = img.resize(size, Image.ANTIALIAS)
if mode:
img = img.convert(mode)
if save_path:
if isinstance(save_path, str):
save_path = Path(save_path)
save_path.parent.mkdir(parents=True, exist_ok=True)
img.save(save_path)
return img

View File

@ -7,15 +7,12 @@ import base64
import datetime
from time import time
import re
import os
import string
import functools
import inspect
import json
import asyncio
from PIL import Image
from json import JSONDecodeError
from aiohttp import ClientSession
from nonebot import get_bot
from nonebot import logger
from nonebot.exception import FinishedException
@ -25,6 +22,7 @@ from .db_util import get_private_cookie, delete_cookie
from .db_util import get_public_cookie, limit_public_cookie
from .db_util import get_cookie_cache, update_cookie_cache, delete_cookie_cache
from .db_util import get_last_query, update_last_query
from .http_util import aiorequests
def auto_withdraw(seconds: int = -1):
@ -140,17 +138,17 @@ class FreqLimiter2:
return int(self.next_time[key1][key2] - time()) + 1
# 从网络url中获取图片
async def get_pic(url: str, size: tuple = None, mode: str = None):
async with ClientSession() as session:
res = await session.get(url)
res = await res.read()
img = Image.open(BytesIO(res))
if size:
img = img.resize(size)
if mode:
img = img.convert(mode)
return img
# # 从网络url中获取图片
# async def get_pic(url: str, size: tuple = None, mode: str = None):
# async with ClientSession() as session:
# res = await session.get(url)
# res = await res.read()
# img = Image.open(BytesIO(res))
# if size:
# img = img.resize(size)
# if mode:
# img = img.convert(mode)
# return img
# 获取可用的cookie
@ -342,13 +340,12 @@ async def check_cookie(cookie):
'x-rpc-client_type': '5',
'Referer': 'https://webstatic.mihoyo.com/'
}
async with ClientSession() as session:
res = await session.get(url=url, headers=headers)
res = await res.json()
if res['retcode'] != 0:
return False
else:
return True
res = await aiorequests.get(url=url, headers=headers)
res = res.json()
if res['retcode'] != 0:
return False
else:
return True
# 向超级用户私聊发送cookie删除信息
@ -390,3 +387,4 @@ def get_id(event):
return event.group_id
elif event.message_type == 'guild':
return event.channel_id