mirror of
https://github.com/xuthus83/LittlePaimon.git
synced 2025-04-12 23:29:37 +08:00
✨ 每日材料
更新
This commit is contained in:
parent
e164a64cb7
commit
53b699fca8
@ -1,3 +1,4 @@
|
|||||||
|
import datetime
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import git
|
import git
|
||||||
from nonebot.utils import run_sync
|
from nonebot.utils import run_sync
|
||||||
@ -25,7 +26,8 @@ async def check_update():
|
|||||||
return f'当前已是最新版本:{__version__}'
|
return f'当前已是最新版本:{__version__}'
|
||||||
result = '检查到更新,日志如下:\n'
|
result = '检查到更新,日志如下:\n'
|
||||||
for i, commit in enumerate(remote_commit, start=1):
|
for i, commit in enumerate(remote_commit, start=1):
|
||||||
result += f'{i}.{commit["commit"]["committer"]["date"].replace("T", " ").replace("Z", "")}\n' + commit['commit']['message'].replace(':bug:', '🐛').replace(
|
time_str = (datetime.datetime.strptime(commit['commit']['committer']['date'], '%Y-%m-%dT%H:%M:%SZ') + datetime.timedelta(hours=8)).strftime('%Y-%m-%d %H:%M:%S')
|
||||||
|
result += f'{i}.{time_str}\n' + commit['commit']['message'].replace(':bug:', '🐛').replace(
|
||||||
':sparkles:', '✨').replace(':memo:', '📝') + '\n'
|
':sparkles:', '✨').replace(':memo:', '📝') + '\n'
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ from LittlePaimon.utils.message import MessageBuild
|
|||||||
from LittlePaimon.database.models import PlayerAlias
|
from LittlePaimon.database.models import PlayerAlias
|
||||||
from LittlePaimon.config import RESOURCE_BASE_PATH
|
from LittlePaimon.config import RESOURCE_BASE_PATH
|
||||||
from .draw_map import init_map, draw_map, get_full_map
|
from .draw_map import init_map, draw_map, get_full_map
|
||||||
|
from .draw_daily_material import draw_material
|
||||||
|
|
||||||
# from .abyss_rate_draw import draw_rate_rank, draw_teams_rate
|
# from .abyss_rate_draw import draw_rate_rank, draw_teams_rate
|
||||||
|
|
||||||
@ -86,31 +87,28 @@ generate_map = on_command('生成地图', priority=1, block=True, permission=SUP
|
|||||||
|
|
||||||
@daily_material.handle()
|
@daily_material.handle()
|
||||||
async def _(event: MessageEvent, regex_dict: dict = RegexDict()):
|
async def _(event: MessageEvent, regex_dict: dict = RegexDict()):
|
||||||
|
await daily_material.send('开始获取每日材料,请稍候...')
|
||||||
if regex_dict['day'] in ['今日', '今天', '现在']:
|
if regex_dict['day'] in ['今日', '今天', '现在']:
|
||||||
day = time.strftime("%w")
|
day = time.strftime("%w")
|
||||||
elif regex_dict['day'] in ['明日', '明天']:
|
elif regex_dict['day'] in ['明日', '明天']:
|
||||||
day = str(int(time.strftime("%w")) + 1)
|
day = str(int(time.strftime("%w")) + 1)
|
||||||
elif regex_dict['day'] in ['后日', '后天']:
|
elif regex_dict['day'] in ['后日', '后天']:
|
||||||
day = str(int(time.strftime("%w")) + 2)
|
day = str(int(time.strftime("%w")) + 2)
|
||||||
elif regex_dict['day'] in ['周一', '周四']:
|
elif regex_dict['day'] == '周日':
|
||||||
day = '1'
|
await daily_material.finish('周日所有材料都可以刷哦!', at_sender=True)
|
||||||
elif regex_dict['day'] in ['周二', '周五']:
|
elif regex_dict['day'].startswith('周'):
|
||||||
day = '2'
|
await daily_material.finish(await draw_material(regex_dict['day']))
|
||||||
elif regex_dict['day'] in ['周三', '周六']:
|
if day == '0':
|
||||||
day = '3'
|
|
||||||
else:
|
|
||||||
day = '0'
|
|
||||||
if day == "0":
|
|
||||||
await daily_material.finish('周日所有材料都可以刷哦!', at_sender=True)
|
await daily_material.finish('周日所有材料都可以刷哦!', at_sender=True)
|
||||||
elif day in ['1', '4']:
|
|
||||||
await daily_material.finish(
|
|
||||||
MessageSegment.image(file='https://static.cherishmoon.fun/LittlePaimon/DailyMaterials/周一周四.jpg'))
|
|
||||||
elif day in ['2', '5']:
|
|
||||||
await daily_material.finish(
|
|
||||||
MessageSegment.image(file='https://static.cherishmoon.fun/LittlePaimon/DailyMaterials/周二周五.jpg'))
|
|
||||||
else:
|
else:
|
||||||
await daily_material.finish(
|
await daily_material.finish(await draw_material({
|
||||||
MessageSegment.image(file='https://static.cherishmoon.fun/LittlePaimon/DailyMaterials/周三周六.jpg'))
|
'1': '周一',
|
||||||
|
'2': '周二',
|
||||||
|
'3': '周三',
|
||||||
|
'4': '周四',
|
||||||
|
'5': '周五',
|
||||||
|
'6': '周六',
|
||||||
|
}[day]), at_sender=True)
|
||||||
|
|
||||||
|
|
||||||
@material_map.handle()
|
@material_map.handle()
|
||||||
@ -164,7 +162,9 @@ async def _(event: MessageEvent, map_: str = Arg('map'), names=Arg('names')):
|
|||||||
if isinstance(names, Message):
|
if isinstance(names, Message):
|
||||||
names = names.extract_plain_text().split(' ')
|
names = names.extract_plain_text().split(' ')
|
||||||
if not freq_limiter.check(f'材料地图_{event.group_id if isinstance(event, GroupMessageEvent) else event.user_id}'):
|
if not freq_limiter.check(f'材料地图_{event.group_id if isinstance(event, GroupMessageEvent) else event.user_id}'):
|
||||||
await material_map_full.finish(f'材料地图查询冷却中,剩余{freq_limiter.left(f"材料地图_{event.group_id if isinstance(event, GroupMessageEvent) else event.user_id}")}秒', at_sender=True)
|
await material_map_full.finish(
|
||||||
|
f'材料地图查询冷却中,剩余{freq_limiter.left(f"材料地图_{event.group_id if isinstance(event, GroupMessageEvent) else event.user_id}")}秒',
|
||||||
|
at_sender=True)
|
||||||
freq_limiter.start(f'材料地图_{event.group_id if isinstance(event, GroupMessageEvent) else event.user_id}', 15)
|
freq_limiter.start(f'材料地图_{event.group_id if isinstance(event, GroupMessageEvent) else event.user_id}', 15)
|
||||||
if len(names) > 3:
|
if len(names) > 3:
|
||||||
names = names[:3]
|
names = names[:3]
|
||||||
|
116
LittlePaimon/plugins/Paimon_Wiki/draw_daily_material.py
Normal file
116
LittlePaimon/plugins/Paimon_Wiki/draw_daily_material.py
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
import math
|
||||||
|
from pathlib import Path
|
||||||
|
from LittlePaimon.config import RESOURCE_BASE_PATH
|
||||||
|
from LittlePaimon.utils import aiorequests, scheduler
|
||||||
|
from LittlePaimon.utils.files import save_json, load_json, load_image
|
||||||
|
from LittlePaimon.utils.image import PMImage, font_manager as fm
|
||||||
|
from LittlePaimon.utils.message import MessageBuild
|
||||||
|
|
||||||
|
week_cn = {
|
||||||
|
'monday': '周一',
|
||||||
|
'tuesday': '周二',
|
||||||
|
'wednesday': '周三',
|
||||||
|
'thursday': '周四',
|
||||||
|
'friday': '周五',
|
||||||
|
'saturday': '周六',
|
||||||
|
}
|
||||||
|
|
||||||
|
MATERIAL_URL = 'https://api.ambr.top/v2/chs/material'
|
||||||
|
CHARACTER_URL = 'https://api.ambr.top/v2/chs/avatar'
|
||||||
|
WEAPON_URL = 'https://api.ambr.top/v2/chs/weapon'
|
||||||
|
DAILY_URL = 'https://api.ambr.top/v2/chs/dailyDungeon'
|
||||||
|
UPGRADE_URL = 'https://api.ambr.top/v2/static/upgrade'
|
||||||
|
|
||||||
|
|
||||||
|
async def get_daily_material():
|
||||||
|
daily_info = {
|
||||||
|
'天赋': {},
|
||||||
|
'武器': {}
|
||||||
|
}
|
||||||
|
daily_data = (await aiorequests.get(DAILY_URL)).json()['data']
|
||||||
|
material_data = (await aiorequests.get(MATERIAL_URL)).json()['data']
|
||||||
|
upgrade_data = (await aiorequests.get(UPGRADE_URL)).json()['data']
|
||||||
|
for week in daily_data:
|
||||||
|
if week == 'sunday':
|
||||||
|
continue
|
||||||
|
daily_info['天赋'][week_cn[week]], daily_info['武器'][week_cn[week]] = {}, {}
|
||||||
|
domain_data = daily_data[week]
|
||||||
|
domain_data_sort = sorted(domain_data, key=lambda x: domain_data[x]['city'])
|
||||||
|
for domain_key in domain_data_sort:
|
||||||
|
item_type = 'avatar' if domain_data[domain_key]['name'].startswith('精通秘境') else 'weapon'
|
||||||
|
material = material_data['items'][str(domain_data[domain_key]['reward'][-1])]
|
||||||
|
used = [upgrade_data[item_type][id] for id in upgrade_data[item_type] if
|
||||||
|
str(material['id']) in upgrade_data[item_type][id]['items'] and 'Player' not in
|
||||||
|
upgrade_data[item_type][id]['icon']]
|
||||||
|
daily_info['天赋' if item_type == 'avatar' else '武器'][week_cn[week]][
|
||||||
|
f'{material["name"]}-{material["icon"]}'] = [f'{u["rank"]}{u["icon"]}' for u in used]
|
||||||
|
save_json(daily_info, Path() / 'data' / 'LittlePaimon' / 'daily_material.json')
|
||||||
|
|
||||||
|
|
||||||
|
async def draw_material(week: str = '周一'):
|
||||||
|
if not (Path() / 'data' / 'LittlePaimon' / 'daily_material.json').exists():
|
||||||
|
await get_daily_material()
|
||||||
|
if week in {'周一', '周四'}:
|
||||||
|
week_str = '周一/周四'
|
||||||
|
elif week in {'周二', '周五'}:
|
||||||
|
week_str = '周二/周五'
|
||||||
|
else:
|
||||||
|
week_str = '周三/周六'
|
||||||
|
daily_info = load_json(Path() / 'data' / 'LittlePaimon' / 'daily_material.json')
|
||||||
|
avatar = daily_info['天赋'][week]
|
||||||
|
weapon = daily_info['武器'][week]
|
||||||
|
total_height = max(70 * len(avatar) + sum(math.ceil(len(items) / 5) * 140 for items in avatar.values()),
|
||||||
|
70 * len(weapon) + sum(math.ceil(len(items) / 5) * 140 for items in weapon.values())) + 165
|
||||||
|
img = PMImage(RESOURCE_BASE_PATH / 'general' / 'bg.png')
|
||||||
|
await img.stretch((50, img.width - 50), 1520, 'width')
|
||||||
|
await img.stretch((50, img.height - 50), total_height - 100, 'height')
|
||||||
|
frame = await load_image(RESOURCE_BASE_PATH / 'general' / 'frame.png')
|
||||||
|
await img.paste(frame, (190, 62))
|
||||||
|
await img.paste(frame, (1000, 62))
|
||||||
|
await img.text(f'{week_str}角色天赋材料', 223, 69, fm.get('SourceHanSerifCN-Bold.otf', 35), 'black')
|
||||||
|
await img.text(f'{week_str}武器突破材料', 1033, 69, fm.get('SourceHanSerifCN-Bold.otf', 35), 'black')
|
||||||
|
star_bg = {
|
||||||
|
'3': await load_image(RESOURCE_BASE_PATH / 'icon' / 'star3.png', size=(110, 110)),
|
||||||
|
'4': await load_image(RESOURCE_BASE_PATH / 'icon' / 'star4.png', size=(110, 110)),
|
||||||
|
'5': await load_image(RESOURCE_BASE_PATH / 'icon' / 'star5.png', size=(110, 110))
|
||||||
|
}
|
||||||
|
now_height = 165
|
||||||
|
for name, items in avatar.items():
|
||||||
|
name, icon = name.split('-')
|
||||||
|
await img.paste(await load_image(RESOURCE_BASE_PATH / 'icon' / 'star5.png', size=(60, 60)), (90, now_height))
|
||||||
|
await img.paste(await load_image(RESOURCE_BASE_PATH / 'material' / f'{icon}.png', size=(60, 60)),
|
||||||
|
(90, now_height))
|
||||||
|
await img.text(name, 165, now_height + 5, fm.get('SourceHanSerifCN-Bold.otf', 30), 'black')
|
||||||
|
now_height += 70
|
||||||
|
items.sort(key=lambda x: int(x[0]), reverse=True)
|
||||||
|
for i in range(len(items)):
|
||||||
|
star = items[i][0]
|
||||||
|
icon = items[i][1:]
|
||||||
|
await img.paste(star_bg[star], (90 + 128 * (i % 5), now_height + 125 * int(i / 5)))
|
||||||
|
await img.paste(await load_image(RESOURCE_BASE_PATH / 'avatar' / f'{icon}.png', size=(110, 110)),
|
||||||
|
(90 + 128 * (i % 5), now_height + 125 * int(i / 5)))
|
||||||
|
now_height += math.ceil(len(items) / 5) * 125 + 15
|
||||||
|
now_height = 165
|
||||||
|
for name, items in weapon.items():
|
||||||
|
name, icon = name.split('-')
|
||||||
|
await img.paste(await load_image(RESOURCE_BASE_PATH / 'icon' / 'star5.png', size=(60, 60)), (908, now_height))
|
||||||
|
await img.paste(await load_image(RESOURCE_BASE_PATH / 'material' / f'{icon}.png', size=(60, 60)),
|
||||||
|
(908, now_height))
|
||||||
|
await img.text(name, 983, now_height + 5, fm.get('SourceHanSerifCN-Bold.otf', 30), 'black')
|
||||||
|
now_height += 70
|
||||||
|
items.sort(key=lambda x: int(x[0]), reverse=True)
|
||||||
|
for i in range(len(items)):
|
||||||
|
star = items[i][0]
|
||||||
|
icon = items[i][1:]
|
||||||
|
await img.paste(star_bg[star], (908 + 128 * (i % 5), now_height + 125 * int(i / 5)))
|
||||||
|
await img.paste(await load_image(RESOURCE_BASE_PATH / 'weapon' / f'{icon}.png', size=(110, 110)),
|
||||||
|
(908 + 128 * (i % 5), now_height + 125 * int(i / 5)))
|
||||||
|
now_height += math.ceil(len(items) / 5) * 125 + 15
|
||||||
|
await img.text('CREATED BY LITTLEPAIMON', (0, img.width), img.height - 83,
|
||||||
|
fm.get('bahnschrift_bold', 44, 'Bold'), '#3c3c3c', align='center')
|
||||||
|
|
||||||
|
return MessageBuild.Image(img, mode='RGB', quality=80)
|
||||||
|
|
||||||
|
@scheduler.scheduled_job('cron', hour=7, misfire_grace_time=10)
|
||||||
|
async def update_daily_material():
|
||||||
|
await get_daily_material()
|
@ -39,13 +39,7 @@ async def load_image(
|
|||||||
if path.exists():
|
if path.exists():
|
||||||
img = Image.open(path)
|
img = Image.open(path)
|
||||||
elif path.name.startswith(('UI_', 'Skill_')):
|
elif path.name.startswith(('UI_', 'Skill_')):
|
||||||
try:
|
img = await aiorequests.download_icon(path.name, headers=headers, save_path=path, follow_redirects=True)
|
||||||
img = await aiorequests.get_img(f'https://enka.network/ui/{path.name}', headers=headers, save_path=path, follow_redirects=True)
|
|
||||||
except Exception:
|
|
||||||
try:
|
|
||||||
img = await aiorequests.get_img(f'https://file.minigg.icu/genshin/ui/{path.name}', headers=headers, save_path=path, follow_redirects=True)
|
|
||||||
except Exception as e:
|
|
||||||
raise FileNotFoundError(f'{path} not found') from e
|
|
||||||
else:
|
else:
|
||||||
raise FileNotFoundError(f'{path} not found')
|
raise FileNotFoundError(f'{path} not found')
|
||||||
cache_image[str(path)] = img
|
cache_image[str(path)] = img
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import contextlib
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from ssl import SSLCertVerificationError
|
from ssl import SSLCertVerificationError
|
||||||
@ -145,3 +146,24 @@ class aiorequests:
|
|||||||
colour='green'):
|
colour='green'):
|
||||||
f.write(chunk)
|
f.write(chunk)
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
async def download_icon(name: str,
|
||||||
|
headers: Optional[Dict[str, str]] = None,
|
||||||
|
save_path: Optional[Union[str, Path]] = None,
|
||||||
|
**kwargs):
|
||||||
|
"""
|
||||||
|
下载icon
|
||||||
|
:param name: url
|
||||||
|
:param headers: 请求头
|
||||||
|
:param save_path: 保存路径
|
||||||
|
"""
|
||||||
|
urls = [
|
||||||
|
f'https://file.minigg.icu/genshin/ui/{name}',
|
||||||
|
f'https://api.ambr.top/assets/UI/{name}',
|
||||||
|
f'https://enka.network/ui/{name}'
|
||||||
|
]
|
||||||
|
for url in urls:
|
||||||
|
with contextlib.suppress(Exception):
|
||||||
|
return await aiorequests.get_img(url=url, headers=headers, save_path=save_path, **kwargs)
|
||||||
|
raise FileNotFoundError(f'{name}下载失败,请检查网络')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user