✨ 完成 arkmr
84
ArknightsUID/arknightsuid_ap/__init__.py
Normal file
@ -0,0 +1,84 @@
|
||||
import asyncio
|
||||
|
||||
from gsuid_core.aps import scheduler
|
||||
from gsuid_core.bot import Bot
|
||||
from gsuid_core.gss import gss
|
||||
from gsuid_core.logger import logger
|
||||
from gsuid_core.models import Event
|
||||
from gsuid_core.segment import MessageSegment
|
||||
from gsuid_core.sv import SV
|
||||
from gsuid_core.utils.database.api import get_uid
|
||||
from gsuid_core.utils.error_reply import UID_HINT
|
||||
|
||||
from ..utils.ark_prefix import PREFIX
|
||||
from ..utils.database.models import ArknightsBind
|
||||
|
||||
# from .ap_text import get_ap_text
|
||||
from .draw_ap_card import get_ap_img
|
||||
|
||||
# from .notice import get_notice_list
|
||||
|
||||
sv_get_ap = SV('ark查询体力')
|
||||
sv_get_ap_admin = SV('ark强制推送', pm=1)
|
||||
|
||||
|
||||
# @sv_get_ap.on_fullmatch((f'{PREFIX}当前状态'))
|
||||
# async def send_daily_info(bot: Bot, ev: Event):
|
||||
# await bot.logger.info('开始执行[ark每日信息文字版]')
|
||||
# uid = await get_uid(bot, ev, ArknightsBind)
|
||||
# if uid is None:
|
||||
# return await bot.send(UID_HINT)
|
||||
# await bot.logger.info(f'[ark每日信息文字版]UID: {uid}')
|
||||
|
||||
# im = await get_ap_text(uid)
|
||||
# await bot.send(im)
|
||||
|
||||
|
||||
# @sv_get_ap_admin.on_fullmatch((f'{PREFIX}强制推送体力提醒'))
|
||||
# async def force_notice_job(bot: Bot, ev: Event):
|
||||
# await bot.logger.info('开始执行[ark强制推送体力信息]')
|
||||
# await ark_notice_job()
|
||||
|
||||
|
||||
# @scheduler.scheduled_job('cron', minute='*/30')
|
||||
# async def ark_notice_job():
|
||||
# result = await get_notice_list()
|
||||
# logger.info('[ark推送检查]完成!等待消息推送中...')
|
||||
# logger.debug(result)
|
||||
|
||||
# # 执行私聊推送
|
||||
# for bot_id in result:
|
||||
# for BOT_ID in gss.active_bot:
|
||||
# bot = gss.active_bot[BOT_ID]
|
||||
# for user_id in result[bot_id]['direct']:
|
||||
# msg = result[bot_id]['direct'][user_id]
|
||||
# await bot.target_send(msg, 'direct', user_id, bot_id, '', '')
|
||||
# await asyncio.sleep(0.5)
|
||||
# logger.info('[ark推送检查] 私聊推送完成')
|
||||
# for gid in result[bot_id]['group']:
|
||||
# msg_list = []
|
||||
# for user_id in result[bot_id]['group'][gid]:
|
||||
# msg_list.append(MessageSegment.at(user_id))
|
||||
# msg = result[bot_id]['group'][gid][user_id]
|
||||
# msg_list.append(MessageSegment.text(msg))
|
||||
# await bot.target_send(msg_list, 'group', gid, bot_id, '', '')
|
||||
# await asyncio.sleep(0.5)
|
||||
# logger.info('[ark推送检查] 群聊推送完成')
|
||||
|
||||
|
||||
@sv_get_ap.on_fullmatch(
|
||||
(
|
||||
f'{PREFIX}每日',
|
||||
f'{PREFIX}mr',
|
||||
f'{PREFIX}实时便笺',
|
||||
f'{PREFIX}便笺',
|
||||
f'{PREFIX}便签',
|
||||
)
|
||||
)
|
||||
async def send_daily_info_pic(bot: Bot, ev: Event):
|
||||
await bot.logger.info('开始执行[ark每日信息]')
|
||||
user_id = ev.at if ev.at else ev.user_id
|
||||
await bot.logger.info(f'[ark每日信息]QQ号: {user_id}')
|
||||
|
||||
im = await get_ap_img(bot.bot_id, user_id)
|
||||
await bot.send(im)
|
99
ArknightsUID/arknightsuid_ap/ap_text.py
Normal file
@ -0,0 +1,99 @@
|
||||
# import math
|
||||
# from datetime import datetime
|
||||
|
||||
# from gsuid_core.data_store import get_res_path
|
||||
# from gsuid_core.logger import logger
|
||||
# from gsuid_core.utils.error_reply import get_error
|
||||
# from msgspec import json as msgjson
|
||||
|
||||
# # from ..arknightsuid_resource.constants import Excel
|
||||
# from ..utils.ark_api import ark_skd_api
|
||||
# from ..utils.models.skland.models import PlayerStatusAp
|
||||
|
||||
# daily_im = """*数据刷新可能存在一定延迟,请以当前游戏实际数据为准
|
||||
# ==============
|
||||
# 理智:{}/{}
|
||||
# 公开招募:{}/{}
|
||||
# 公招刷新:{}
|
||||
# 训练室:{}
|
||||
# 每周报酬合成玉:{}/{}
|
||||
# 每日任务:{}/{}
|
||||
# 每周任务:{}/{}
|
||||
# 数据增补仪:{}/{}
|
||||
# 数据增补条:{}/{}
|
||||
# =============="""
|
||||
|
||||
|
||||
# def seconds2hours(seconds: int) -> str:
|
||||
# m, s = divmod(int(seconds), 60)
|
||||
# h, m = divmod(m, 60)
|
||||
# return '%02d:%02d:%02d' % (h, m, s)
|
||||
|
||||
# def now_ap(ap: PlayerStatusAp) -> int:
|
||||
# _ap = ap.current + math.floor((datetime.now().timestamp() - ap.lastApAddTime) / 360)
|
||||
# return _ap if _ap <= ap.max else ap.max
|
||||
|
||||
|
||||
# async def get_ap_text(uid: str) -> str:
|
||||
# try:
|
||||
# player_info = await ark_skd_api.get_game_player_info(uid)
|
||||
# if isinstance(player_info, int):
|
||||
# return get_error(player_info)
|
||||
|
||||
# player_save_path = get_res_path(['ArknightsUID', 'players'])
|
||||
|
||||
# with open(player_save_path / f'{player_info.status.uid}.json', 'wb') as file:
|
||||
# file.write(msgjson.format(msgjson.encode(player_info), indent=4))
|
||||
|
||||
# ap = player_info.status.ap
|
||||
# current_ap = now_ap(ap)
|
||||
# max_ap = ap.max
|
||||
# rec_time = ''
|
||||
# if current_ap < max_ap:
|
||||
# ap_recover_time = seconds2hours(
|
||||
# ap.completeRecoveryTime
|
||||
# )
|
||||
# next_ap_rec_time = seconds2hours(
|
||||
# 8 * 60
|
||||
# - (
|
||||
# (max_ap - current_ap)
|
||||
# * 8
|
||||
# * 60
|
||||
# - int(ap.completeRecoveryTime)
|
||||
# )
|
||||
# )
|
||||
# rec_time = f' ({next_ap_rec_time}/{ap_recover_time})'
|
||||
|
||||
# accepted_epedition_num = dailydata['accepted_epedition_num']
|
||||
# total_expedition_num = dailydata['total_expedition_num']
|
||||
# finished_expedition_num = 0
|
||||
# expedition_info: list[str] = []
|
||||
# for expedition in dailydata['expeditions']:
|
||||
# expedition_name = expedition['name']
|
||||
|
||||
# if expedition['status'] == 'Finished':
|
||||
# expedition_info.append(f'{expedition_name} 探索完成')
|
||||
# finished_expedition_num += 1
|
||||
# else:
|
||||
# remaining_time: str = seconds2hours(
|
||||
# expedition['remaining_time']
|
||||
# )
|
||||
# expedition_info.append(
|
||||
# f'{expedition_name} 剩余时间{remaining_time}'
|
||||
# )
|
||||
|
||||
# expedition_data = '\n'.join(expedition_info)
|
||||
# print(expedition_data)
|
||||
# send_mes = daily_im.format(
|
||||
# current_ap,
|
||||
# max_ap,
|
||||
# rec_time,
|
||||
# accepted_epedition_num,
|
||||
# finished_expedition_num,
|
||||
# total_expedition_num,
|
||||
# expedition_data,
|
||||
# )
|
||||
# return send_mes
|
||||
# except TypeError:
|
||||
# logger.exception('[查询当前状态]查询失败!')
|
||||
# return '你绑定过的UID中可能存在过期CK~请重新绑定一下噢~'
|
528
ArknightsUID/arknightsuid_ap/draw_ap_card.py
Normal file
@ -0,0 +1,528 @@
|
||||
import asyncio
|
||||
import math
|
||||
from datetime import datetime, timedelta
|
||||
from io import BytesIO
|
||||
from pathlib import Path
|
||||
|
||||
import aiohttp
|
||||
from gsuid_core.logger import logger
|
||||
from gsuid_core.utils.image.convert import convert_img
|
||||
from PIL import Image, ImageDraw
|
||||
|
||||
from ..arknightsuid_resource.constants import Excel
|
||||
from ..utils.ark_api import ark_skd_api
|
||||
from ..utils.database.models import ArknightsBind
|
||||
from ..utils.fonts.source_han_sans import (
|
||||
sans_font_18,
|
||||
sans_font_26,
|
||||
sans_font_34,
|
||||
)
|
||||
from ..utils.models.skland.models import PlayerStatusAp
|
||||
|
||||
TEXT_PATH = Path(__file__).parent / 'texture2D'
|
||||
|
||||
white_bg = Image.open(TEXT_PATH / 'white_bg.png')
|
||||
up_bar = Image.open(TEXT_PATH / 'up_bar.png')
|
||||
brain_pic = Image.open(TEXT_PATH / 'brain.png')
|
||||
warn_pic = Image.open(TEXT_PATH / 'warn.png')
|
||||
mask_pic = Image.open(TEXT_PATH / 'mask.png').convert('RGBA')
|
||||
logo_white = Image.open(TEXT_PATH / 'logo_white.png')
|
||||
|
||||
blue_bar_bg1 = Image.open(TEXT_PATH / 'blue_bar_bg1.png')
|
||||
grey_bar_bg1 = Image.open(TEXT_PATH / 'grey_bar_bg1.png')
|
||||
|
||||
based_w = 850
|
||||
based_h = 1750
|
||||
|
||||
first_color = (29, 29, 29)
|
||||
white_color = (255, 255, 255)
|
||||
red_color = (235, 61, 75)
|
||||
|
||||
|
||||
def seconds2hours(seconds: int) -> str:
|
||||
m, s = divmod(int(seconds), 60)
|
||||
h, m = divmod(m, 60)
|
||||
return '%02d:%02d:%02d' % (h, m, s)
|
||||
|
||||
def now_ap(ap: PlayerStatusAp) -> int:
|
||||
_ap = ap.current + math.floor((datetime.now().timestamp() - ap.lastApAddTime) / 360)
|
||||
return _ap if _ap <= ap.max else ap.max
|
||||
|
||||
|
||||
async def download_image(url: str) -> Image.Image:
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.get(url) as response:
|
||||
img_data = await response.read()
|
||||
img = Image.open(BytesIO(img_data))
|
||||
return img
|
||||
|
||||
|
||||
async def get_ap_img(bot_id: str, user_id: str):
|
||||
try:
|
||||
uid_list = await ArknightsBind.get_uid_list_by_game(user_id, bot_id)
|
||||
logger.info(f'[每日信息]UID: {uid_list}')
|
||||
# 进行校验UID是否绑定CK
|
||||
useable_uid_list = []
|
||||
if uid_list is None:
|
||||
return '请先绑定一个可用CRED & UID再来查询哦~'
|
||||
for uid in uid_list:
|
||||
status = await ark_skd_api.check_cred_valid(uid)
|
||||
if status is not bool:
|
||||
useable_uid_list.append(uid)
|
||||
logger.info(f'[每日信息]可用UID: {useable_uid_list}')
|
||||
if len(useable_uid_list) == 0:
|
||||
return '请先绑定一个可用CRED & UID再来查询哦~'
|
||||
# 开始绘图任务
|
||||
task = []
|
||||
img = Image.new(
|
||||
'RGBA', (based_w * len(useable_uid_list), based_h), (0, 0, 0, 0)
|
||||
)
|
||||
for uid_index, uid in enumerate(useable_uid_list):
|
||||
task.append(_draw_all_ap_img(img, uid, uid_index))
|
||||
await asyncio.gather(*task)
|
||||
res = await convert_img(img)
|
||||
logger.info('[查询每日信息]绘图已完成,等待发送!')
|
||||
except TypeError:
|
||||
logger.exception('[查询每日信息]绘图失败!')
|
||||
res = '你绑定过的UID中可能存在过期CRED~请重新绑定一下噢~'
|
||||
|
||||
return res
|
||||
|
||||
|
||||
async def _draw_all_ap_img(img: Image.Image, uid: str, index: int):
|
||||
ap_img = await draw_ap_img(uid)
|
||||
img.paste(ap_img, (850 * index, 0), ap_img)
|
||||
|
||||
|
||||
def get_error(img: Image.Image, uid: str, daily_data: int):
|
||||
img_draw = ImageDraw.Draw(img)
|
||||
img.paste(warn_pic, (0, 0), warn_pic)
|
||||
# 写UID
|
||||
img_draw.text(
|
||||
(350, 680),
|
||||
f'UID{uid}',
|
||||
font=sans_font_26,
|
||||
fill=first_color,
|
||||
anchor='mm',
|
||||
)
|
||||
img_draw.text(
|
||||
(350, 650),
|
||||
f'错误码 {daily_data}',
|
||||
font=sans_font_26,
|
||||
fill=red_color,
|
||||
anchor='mm',
|
||||
)
|
||||
return img
|
||||
|
||||
|
||||
async def seconds2hours_zhcn(seconds: int) -> str:
|
||||
m, s = divmod(int(seconds), 60)
|
||||
h, m = divmod(m, 60)
|
||||
return '%02d小时%02d分钟' % (h, m)
|
||||
|
||||
|
||||
async def draw_ap_img(uid: str) -> Image.Image:
|
||||
# char
|
||||
char_pic = Image.open(TEXT_PATH / 'char_1028_texas2_1b.png').resize((1700, 1700)).convert('RGBA')
|
||||
|
||||
tmp_img = Image.new('RGBA', (based_w, based_h))
|
||||
tmp_img.paste(char_pic, (-250, 50), char_pic)
|
||||
tmp_img2 = Image.new('RGBA', (based_w, based_h))
|
||||
tmp_img2.paste(tmp_img, (0, 0), mask_pic)
|
||||
|
||||
img = Image.alpha_composite(white_bg, tmp_img2)
|
||||
|
||||
# 获取数据
|
||||
player_info = await ark_skd_api.get_game_player_info(uid)
|
||||
if isinstance(player_info, int):
|
||||
return get_error(img, uid, player_info)
|
||||
|
||||
# nickname
|
||||
nickname = player_info.status.name
|
||||
up_bar_img = up_bar.copy()
|
||||
up_bar_draw = ImageDraw.Draw(up_bar_img)
|
||||
up_bar_draw.text(
|
||||
(40, 130),
|
||||
f'Dr.{nickname}',
|
||||
font=sans_font_34,
|
||||
fill=white_color,
|
||||
anchor='lm',
|
||||
)
|
||||
img.paste(up_bar_img, (0, 0), up_bar_img)
|
||||
|
||||
# ap
|
||||
current_ap = now_ap(player_info.status.ap)
|
||||
max_ap = player_info.status.ap.max
|
||||
brain_pic_img = brain_pic.copy()
|
||||
brain_pic_draw = ImageDraw.Draw(brain_pic_img)
|
||||
brain_pic_draw.text(
|
||||
(135, 255),
|
||||
f'{current_ap}/{max_ap}',
|
||||
font=sans_font_34,
|
||||
fill=white_color,
|
||||
anchor='lm',
|
||||
)
|
||||
img.paste(brain_pic_img, (50, 500), brain_pic_img)
|
||||
|
||||
# logo
|
||||
logo_white_img = logo_white.copy().resize((400, 225), Image.LANCZOS)
|
||||
img.paste(logo_white_img, (400, 590), logo_white_img)
|
||||
|
||||
# 详细信息
|
||||
|
||||
# recruit check
|
||||
recruit = player_info.recruit
|
||||
recruit_task = [recruit[i].state for i in range(len(recruit))]
|
||||
recruit_task_finish_count = recruit_task.count(2)
|
||||
finishTs = -1
|
||||
|
||||
if recruit_task_finish_count == 0:
|
||||
blue_bar_bg1_img = blue_bar_bg1.copy()
|
||||
else:
|
||||
blue_bar_bg1_img = grey_bar_bg1.copy()
|
||||
|
||||
for i in range(len(recruit)):
|
||||
if finishTs < recruit[i].finishTs:
|
||||
finishTs = recruit[i].finishTs
|
||||
# 获取当前时间与 finishTs 的时间差,转换为几小时几分钟
|
||||
now = datetime.now()
|
||||
finishTs = datetime.fromtimestamp(finishTs)
|
||||
delta = finishTs - now
|
||||
delta_hour = delta.seconds // 3600
|
||||
delta_minute = (delta.seconds - delta_hour * 3600) // 60
|
||||
blue_bar_bg1_draw = ImageDraw.Draw(blue_bar_bg1_img)
|
||||
blue_bar_bg1_draw.text(
|
||||
(170, 60),
|
||||
'公开招募',
|
||||
font=sans_font_34,
|
||||
fill=first_color,
|
||||
anchor='lm',
|
||||
)
|
||||
|
||||
blue_bar_bg1_draw.text(
|
||||
(540, 70),
|
||||
'招募已全部完成' if recruit_task_finish_count == len(recruit) else f'{delta_hour}小时{delta_minute}分钟后全部完成',
|
||||
font=sans_font_18,
|
||||
fill=first_color,
|
||||
anchor='rm',
|
||||
)
|
||||
|
||||
blue_bar_bg1_draw.text(
|
||||
xy=(777, 58),
|
||||
text=f'{len(recruit) - recruit_task_finish_count}/{len(recruit)}',
|
||||
font=sans_font_34,
|
||||
fill=white_color,
|
||||
anchor='rm',
|
||||
)
|
||||
|
||||
img.paste(blue_bar_bg1_img, (-20, 800), blue_bar_bg1_img)
|
||||
|
||||
# recruit refresh check
|
||||
recruit_refresh = player_info.building.hire.refreshCount
|
||||
if recruit_refresh == 0:
|
||||
grey_bar_bg1_img = grey_bar_bg1.copy()
|
||||
grey_bar_bg1_draw = ImageDraw.Draw(grey_bar_bg1_img)
|
||||
complete_work_time = player_info.building.hire.completeWorkTime
|
||||
# 获取当前时间与 completeWorkTime 的时间差,转换为几小时几分钟
|
||||
now = datetime.now()
|
||||
complete_work_time = datetime.fromtimestamp(complete_work_time)
|
||||
delta = complete_work_time - now
|
||||
delta_hour = delta.seconds // 3600
|
||||
delta_minute = (delta.seconds - delta_hour * 3600) // 60
|
||||
grey_bar_bg1_draw.text(
|
||||
(170, 60),
|
||||
'公开刷新',
|
||||
font=sans_font_34,
|
||||
fill=first_color,
|
||||
anchor='lm',
|
||||
)
|
||||
grey_bar_bg1_draw.text(
|
||||
(540, 70),
|
||||
f'{delta_hour}小时{delta_minute}分钟后获取刷新次数',
|
||||
font=sans_font_18,
|
||||
fill=first_color,
|
||||
anchor='rm',
|
||||
)
|
||||
grey_bar_bg1_draw.text(
|
||||
xy=(777, 58),
|
||||
text='联络中',
|
||||
font=sans_font_34,
|
||||
fill=white_color,
|
||||
anchor='rm',
|
||||
)
|
||||
img.paste(grey_bar_bg1_img, (-20, 910), grey_bar_bg1_img)
|
||||
else:
|
||||
blue_bar_bg1_img = blue_bar_bg1.copy()
|
||||
blue_bar_bg1_draw = ImageDraw.Draw(blue_bar_bg1_img)
|
||||
blue_bar_bg1_draw.text(
|
||||
(170, 60),
|
||||
'公开招募刷新',
|
||||
font=sans_font_34,
|
||||
fill=first_color,
|
||||
anchor='lm',
|
||||
)
|
||||
blue_bar_bg1_draw.text(
|
||||
(540, 70),
|
||||
'可进行公开招募刷新',
|
||||
font=sans_font_18,
|
||||
fill=first_color,
|
||||
anchor='rm',
|
||||
)
|
||||
blue_bar_bg1_draw.text(
|
||||
xy=(777, 58),
|
||||
text='可刷新',
|
||||
font=sans_font_34,
|
||||
fill=white_color,
|
||||
anchor='rm',
|
||||
)
|
||||
img.paste(blue_bar_bg1_img, (-20, 910), blue_bar_bg1_img)
|
||||
|
||||
# training char check
|
||||
if player_info.building.training:
|
||||
training_char = player_info.building.training.trainee.charId
|
||||
remain_secs = player_info.building.training.remainSecs
|
||||
# 将remainSecs(剩余秒数) ,转换为几小时几分钟
|
||||
remain_time = await seconds2hours_zhcn(remain_secs)
|
||||
|
||||
char_cn_name = Excel.CHARATER_TABLE[training_char].name
|
||||
blue_bar_bg1_img = blue_bar_bg1.copy()
|
||||
blue_bar_bg1_draw = ImageDraw.Draw(blue_bar_bg1_img)
|
||||
blue_bar_bg1_draw.text(
|
||||
(170, 60),
|
||||
'训练室',
|
||||
font=sans_font_34,
|
||||
fill=first_color,
|
||||
anchor='lm',
|
||||
)
|
||||
blue_bar_bg1_draw.text(
|
||||
(540, 70),
|
||||
f'{remain_time}后完成专精',
|
||||
font=sans_font_18,
|
||||
fill=first_color,
|
||||
anchor='rm',
|
||||
)
|
||||
blue_bar_bg1_draw.text(
|
||||
xy=(777, 58),
|
||||
text=f'{char_cn_name}',
|
||||
font=sans_font_34,
|
||||
fill=white_color,
|
||||
anchor='rm',
|
||||
)
|
||||
img.paste(blue_bar_bg1_img, (-20, 1020), blue_bar_bg1_img)
|
||||
else:
|
||||
grey_bar_bg1_img = grey_bar_bg1.copy()
|
||||
grey_bar_bg1_draw = ImageDraw.Draw(grey_bar_bg1_img)
|
||||
grey_bar_bg1_draw.text(
|
||||
(170, 60),
|
||||
'训练室',
|
||||
font=sans_font_34,
|
||||
fill=first_color,
|
||||
anchor='lm',
|
||||
)
|
||||
grey_bar_bg1_draw.text(
|
||||
(540, 70),
|
||||
'设备空闲中',
|
||||
font=sans_font_18,
|
||||
fill=first_color,
|
||||
anchor='rm',
|
||||
)
|
||||
grey_bar_bg1_draw.text(
|
||||
xy=(777, 58),
|
||||
text='无干员',
|
||||
font=sans_font_34,
|
||||
fill=white_color,
|
||||
anchor='rm',
|
||||
)
|
||||
img.paste(grey_bar_bg1_img, (-20, 1020), grey_bar_bg1_img)
|
||||
|
||||
# campaign reward check
|
||||
campaign_reward = player_info.campaign.reward
|
||||
if campaign_reward.current == campaign_reward.total:
|
||||
blue_bar_bg1_img = blue_bar_bg1.copy()
|
||||
else:
|
||||
blue_bar_bg1_img = grey_bar_bg1.copy()
|
||||
blue_bar_bg1_draw = ImageDraw.Draw(blue_bar_bg1_img)
|
||||
blue_bar_bg1_draw.text(
|
||||
(170, 60),
|
||||
'每周报酬合成玉',
|
||||
font=sans_font_34,
|
||||
fill=first_color,
|
||||
anchor='lm',
|
||||
)
|
||||
|
||||
# 获取当前时间与下一周周一早上4点的时间差,转换为几天几小时
|
||||
now = datetime.now()
|
||||
next_monday = now + timedelta(days=-now.weekday(), weeks=1)
|
||||
next_monday = next_monday.replace(hour=4, minute=0, second=0, microsecond=0)
|
||||
delta = next_monday - now
|
||||
delta_day = delta.days
|
||||
delta_hour = delta.seconds // 3600
|
||||
blue_bar_bg1_draw.text(
|
||||
(540, 70),
|
||||
f'{delta_day}天{delta_hour}小时后刷新',
|
||||
font=sans_font_18,
|
||||
fill=first_color,
|
||||
anchor='rm',
|
||||
)
|
||||
|
||||
blue_bar_bg1_draw.text(
|
||||
xy=(777, 58),
|
||||
text=f'{campaign_reward.current}/{campaign_reward.total}',
|
||||
font=sans_font_34,
|
||||
fill=white_color,
|
||||
anchor='rm',
|
||||
)
|
||||
img.paste(blue_bar_bg1_img, (-20, 1130), blue_bar_bg1_img)
|
||||
|
||||
# routine daily check
|
||||
routine_daily = player_info.routine.daily
|
||||
# 获取当前时间与下一天早上4点的时间差,转换为几小时几分钟
|
||||
now = datetime.now()
|
||||
next_day = now + timedelta(days=1)
|
||||
next_day = next_day.replace(hour=4, minute=0, second=0, microsecond=0)
|
||||
delta = next_day - now
|
||||
delta_hour = delta.seconds // 3600
|
||||
delta_minute = (delta.seconds - delta_hour * 3600) // 60
|
||||
if routine_daily.total == routine_daily.current:
|
||||
blue_bar_bg1_img = blue_bar_bg1.copy()
|
||||
else:
|
||||
blue_bar_bg1_img = grey_bar_bg1.copy()
|
||||
blue_bar_bg1_draw = ImageDraw.Draw(blue_bar_bg1_img)
|
||||
blue_bar_bg1_draw.text(
|
||||
(170, 60),
|
||||
'每日任务',
|
||||
font=sans_font_34,
|
||||
fill=first_color,
|
||||
anchor='lm',
|
||||
)
|
||||
blue_bar_bg1_draw.text(
|
||||
(540, 70),
|
||||
f'{delta_hour}小时{delta_minute}分钟后刷新',
|
||||
font=sans_font_18,
|
||||
fill=first_color,
|
||||
anchor='rm',
|
||||
)
|
||||
blue_bar_bg1_draw.text(
|
||||
xy=(777, 58),
|
||||
text=f'{routine_daily.current}/{routine_daily.total}',
|
||||
font=sans_font_34,
|
||||
fill=white_color,
|
||||
anchor='rm',
|
||||
)
|
||||
img.paste(blue_bar_bg1_img, (-20, 1240), blue_bar_bg1_img)
|
||||
|
||||
# routine weekly check
|
||||
routine_weekly = player_info.routine.weekly
|
||||
# 获取当前时间与下一周周一早上4点的时间差,转换为几天几小时
|
||||
now = datetime.now()
|
||||
next_monday = now + timedelta(days=-now.weekday(), weeks=1)
|
||||
next_monday = next_monday.replace(hour=4, minute=0, second=0, microsecond=0)
|
||||
delta = next_monday - now
|
||||
delta_day = delta.days
|
||||
delta_hour = delta.seconds // 3600
|
||||
if routine_weekly.total == routine_weekly.current:
|
||||
blue_bar_bg1_img = blue_bar_bg1.copy()
|
||||
else:
|
||||
blue_bar_bg1_img = grey_bar_bg1.copy()
|
||||
blue_bar_bg1_draw = ImageDraw.Draw(blue_bar_bg1_img)
|
||||
blue_bar_bg1_draw.text(
|
||||
(170, 60),
|
||||
'每周任务',
|
||||
font=sans_font_34,
|
||||
fill=first_color,
|
||||
anchor='lm',
|
||||
)
|
||||
blue_bar_bg1_draw.text(
|
||||
(540, 70),
|
||||
f'{delta_day}天{delta_hour}小时后刷新',
|
||||
font=sans_font_18,
|
||||
fill=first_color,
|
||||
anchor='rm',
|
||||
)
|
||||
blue_bar_bg1_draw.text(
|
||||
xy=(777, 58),
|
||||
text=f'{routine_weekly.current}/{routine_weekly.total}',
|
||||
font=sans_font_34,
|
||||
fill=white_color,
|
||||
anchor='rm',
|
||||
)
|
||||
img.paste(blue_bar_bg1_img, (-20, 1350), blue_bar_bg1_img)
|
||||
|
||||
# tower reward check
|
||||
tower_reward = player_info.tower.reward
|
||||
higher_item = tower_reward.higherItem
|
||||
term_ts = tower_reward.termTs
|
||||
# 获取当前时间与 termTs 的时间差,转换为几天几小时
|
||||
now = datetime.now()
|
||||
term_ts = datetime.fromtimestamp(term_ts)
|
||||
delta = term_ts - now
|
||||
delta_day = delta.days
|
||||
delta_hour = delta.seconds // 3600
|
||||
if higher_item.current == higher_item.total:
|
||||
blue_bar_bg1_img = blue_bar_bg1.copy()
|
||||
else:
|
||||
blue_bar_bg1_img = grey_bar_bg1.copy()
|
||||
blue_bar_bg1_draw = ImageDraw.Draw(blue_bar_bg1_img)
|
||||
blue_bar_bg1_draw.text(
|
||||
(170, 60),
|
||||
'数据增补仪',
|
||||
font=sans_font_34,
|
||||
fill=first_color,
|
||||
anchor='lm',
|
||||
)
|
||||
blue_bar_bg1_draw.text(
|
||||
(540, 70),
|
||||
f'{delta_day}天{delta_hour}小时后刷新',
|
||||
font=sans_font_18,
|
||||
fill=first_color,
|
||||
anchor='rm',
|
||||
)
|
||||
blue_bar_bg1_draw.text(
|
||||
xy=(777, 58),
|
||||
text=f'{higher_item.current}/{higher_item.total}',
|
||||
font=sans_font_34,
|
||||
fill=white_color,
|
||||
anchor='rm',
|
||||
)
|
||||
img.paste(blue_bar_bg1_img, (-20, 1460), blue_bar_bg1_img)
|
||||
|
||||
lower_item = tower_reward.lowerItem
|
||||
if lower_item.current == lower_item.total:
|
||||
blue_bar_bg1_img = blue_bar_bg1.copy()
|
||||
else:
|
||||
blue_bar_bg1_img = grey_bar_bg1.copy()
|
||||
blue_bar_bg1_draw = ImageDraw.Draw(blue_bar_bg1_img)
|
||||
blue_bar_bg1_draw.text(
|
||||
(170, 60),
|
||||
'数据增补条',
|
||||
font=sans_font_34,
|
||||
fill=first_color,
|
||||
anchor='lm',
|
||||
)
|
||||
blue_bar_bg1_draw.text(
|
||||
(540, 70),
|
||||
f'{delta_day}天{delta_hour}小时后刷新',
|
||||
font=sans_font_18,
|
||||
fill=first_color,
|
||||
anchor='rm',
|
||||
)
|
||||
blue_bar_bg1_draw.text(
|
||||
xy=(777, 58),
|
||||
text=f'{lower_item.current}/{lower_item.total}',
|
||||
font=sans_font_34,
|
||||
fill=white_color,
|
||||
anchor='rm',
|
||||
)
|
||||
img.paste(blue_bar_bg1_img, (-20, 1570), blue_bar_bg1_img)
|
||||
|
||||
|
||||
img_draw = ImageDraw.Draw(img)
|
||||
img_draw.text(
|
||||
(425, 1710),
|
||||
'Powerd By ArknightsUID | GsCore',
|
||||
font=sans_font_26,
|
||||
fill=first_color,
|
||||
anchor='mm',
|
||||
)
|
||||
|
||||
return img
|
105
ArknightsUID/arknightsuid_ap/notice.py
Normal file
@ -0,0 +1,105 @@
|
||||
# from gsuid_core.gss import gss
|
||||
# from gsuid_core.logger import logger
|
||||
|
||||
# from ..sruid_utils.api.mys.models import DailyNoteData
|
||||
# from ..starrailuid_config.sr_config import srconfig
|
||||
# from ..utils.api import get_sqla
|
||||
# from ..utils.mys_api import mys_api
|
||||
|
||||
# MR_NOTICE = '\n可发送[srmr]或者[sr每日]来查看更多信息!\n'
|
||||
|
||||
# NOTICE = {
|
||||
# 'stamina': f'你的开拓力快满啦!{MR_NOTICE}',
|
||||
# 'go': f'你有派遣信息即将可收取!{MR_NOTICE}',
|
||||
# }
|
||||
|
||||
|
||||
# async def get_notice_list() -> dict[str, dict[str, dict]]:
|
||||
# msg_dict: dict[str, dict[str, dict]] = {}
|
||||
# for bot_id in gss.active_bot:
|
||||
# sqla = get_sqla(bot_id)
|
||||
# user_list = await sqla.get_all_push_user_list()
|
||||
# for user in user_list:
|
||||
# if user.sr_uid is not None:
|
||||
# raw_data = await mys_api.get_daily_data(user.sr_uid)
|
||||
# if isinstance(raw_data, int):
|
||||
# logger.error(f'[sr推送提醒]获取{user.sr_uid}的数据失败!')
|
||||
# continue
|
||||
# push_data = await sqla.select_push_data(user.sr_uid)
|
||||
# msg_dict = await all_check(
|
||||
# user.bot_id,
|
||||
# raw_data,
|
||||
# push_data.__dict__,
|
||||
# msg_dict,
|
||||
# user.user_id,
|
||||
# user.sr_uid,
|
||||
# )
|
||||
# return msg_dict
|
||||
|
||||
|
||||
# async def all_check(
|
||||
# bot_id: str,
|
||||
# raw_data: DailyNoteData,
|
||||
# push_data: dict,
|
||||
# msg_dict: dict[str, dict[str, dict]],
|
||||
# user_id: str,
|
||||
# uid: str,
|
||||
# ) -> dict[str, dict[str, dict]]:
|
||||
# sqla = get_sqla(bot_id)
|
||||
# for mode in NOTICE.keys():
|
||||
# # 检查条件
|
||||
# if push_data[f'{mode}_is_push'] == 'on':
|
||||
# if srconfig.get_config('CrazyNotice').data:
|
||||
# if not await check(mode, raw_data, push_data[f'{mode}_value']):
|
||||
# await sqla.update_push_data(
|
||||
# uid, {f'{mode}_is_push': 'off'}
|
||||
# )
|
||||
# continue
|
||||
# # 准备推送
|
||||
# if await check(mode, raw_data, push_data[f'{mode}_value']):
|
||||
# if push_data[f'{mode}_push'] == 'off':
|
||||
# pass
|
||||
# # on 推送到私聊
|
||||
# else:
|
||||
# # 初始化
|
||||
# if bot_id not in msg_dict:
|
||||
# msg_dict[bot_id] = {'direct': {}, 'group': {}}
|
||||
|
||||
# if push_data[f'{mode}_push'] == 'on':
|
||||
# # 添加私聊信息
|
||||
# if user_id not in msg_dict[bot_id]['direct']:
|
||||
# msg_dict[bot_id]['direct'][user_id] = NOTICE[mode]
|
||||
# else:
|
||||
# msg_dict[bot_id]['direct'][user_id] += NOTICE[mode]
|
||||
# await sqla.update_push_data(uid, {f'{mode}_is_push': 'on'})
|
||||
# # 群号推送到群聊
|
||||
# else:
|
||||
# # 初始化
|
||||
# gid = push_data[f'{mode}_push']
|
||||
# if gid not in msg_dict[bot_id]['group']:
|
||||
# msg_dict[bot_id]['group'][gid] = {}
|
||||
|
||||
# if user_id not in msg_dict[bot_id]['group'][gid]:
|
||||
# msg_dict[bot_id]['group'][gid][user_id] = NOTICE[mode]
|
||||
# else:
|
||||
# msg_dict[bot_id]['group'][gid][user_id] += NOTICE[mode]
|
||||
# await sqla.update_push_data(uid, {f'{mode}_is_push': 'on'})
|
||||
# return msg_dict
|
||||
|
||||
|
||||
# async def check(mode: str, data: DailyNoteData, limit: int) -> bool:
|
||||
# if mode == 'resin':
|
||||
# if data['current_stamina'] >= limit:
|
||||
# return True
|
||||
# elif data['current_stamina'] >= data['max_stamina']:
|
||||
# return True
|
||||
# else:
|
||||
# return False
|
||||
# if mode == 'go':
|
||||
# for i in data['expeditions']:
|
||||
# if i['status'] == 'Ongoing':
|
||||
# if int(i['remaining_time']) <= limit * 60:
|
||||
# return True
|
||||
# else:
|
||||
# return True
|
||||
# return False
|
13
ArknightsUID/arknightsuid_ap/test.py
Normal file
@ -0,0 +1,13 @@
|
||||
from pathlib import Path
|
||||
|
||||
from PIL import Image
|
||||
|
||||
path = Path(__file__).parent / 'texture2D'
|
||||
|
||||
char = Image.open(path / 'char_1028_texas2_1b.png')
|
||||
mask = Image.open(path / 'mask.png')
|
||||
img = Image.new('RGB',(850,1750))
|
||||
temp_img = Image.new('RGB',(850,1750))
|
||||
temp_img.paste(char, (-500,0), char )
|
||||
img.paste(temp_img, (0,0), mask)
|
||||
img.show()
|
After Width: | Height: | Size: 1.7 MiB |
BIN
ArknightsUID/arknightsuid_ap/texture2D/black_bg.png
Normal file
After Width: | Height: | Size: 362 KiB |
BIN
ArknightsUID/arknightsuid_ap/texture2D/blue_bar_bg1.png
Normal file
After Width: | Height: | Size: 63 KiB |
BIN
ArknightsUID/arknightsuid_ap/texture2D/blue_bar_bg2.png
Normal file
After Width: | Height: | Size: 78 KiB |
BIN
ArknightsUID/arknightsuid_ap/texture2D/brain.png
Normal file
After Width: | Height: | Size: 41 KiB |
BIN
ArknightsUID/arknightsuid_ap/texture2D/char_1028_texas2_1b.png
Normal file
After Width: | Height: | Size: 406 KiB |
BIN
ArknightsUID/arknightsuid_ap/texture2D/grey_bar_bg1.png
Normal file
After Width: | Height: | Size: 40 KiB |
BIN
ArknightsUID/arknightsuid_ap/texture2D/grey_bar_bg2.png
Normal file
After Width: | Height: | Size: 63 KiB |
BIN
ArknightsUID/arknightsuid_ap/texture2D/logo_black.png
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
ArknightsUID/arknightsuid_ap/texture2D/logo_white.png
Normal file
After Width: | Height: | Size: 28 KiB |
BIN
ArknightsUID/arknightsuid_ap/texture2D/mask.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
ArknightsUID/arknightsuid_ap/texture2D/up_bar.png
Normal file
After Width: | Height: | Size: 6.5 KiB |
BIN
ArknightsUID/arknightsuid_ap/texture2D/warn.png
Normal file
After Width: | Height: | Size: 130 KiB |
BIN
ArknightsUID/arknightsuid_ap/texture2D/white_bg.png
Normal file
After Width: | Height: | Size: 1.1 MiB |
@ -1,5 +1,3 @@
|
||||
import re
|
||||
|
||||
from gsuid_core.bot import Bot
|
||||
from gsuid_core.models import Event
|
||||
from gsuid_core.sv import SV
|
||||
@ -7,20 +5,18 @@ from gsuid_core.utils.database.api import get_uid
|
||||
|
||||
from ..utils.ark_prefix import PREFIX
|
||||
from ..utils.database.models import ArknightsBind
|
||||
|
||||
# from ..utils.convert import get_uid
|
||||
from .draw_roleinfo_card import get_role_img
|
||||
|
||||
sv_get_info = SV('ark查询信息')
|
||||
|
||||
|
||||
@sv_get_info.on_command((f'{PREFIX}uid'))
|
||||
@sv_get_info.on_command((f'{PREFIX}uid')) # noqa: UP034
|
||||
async def send_role_info(bot: Bot, ev: Event):
|
||||
uid = await get_uid(bot, ev, bind_model=ArknightsBind)
|
||||
if uid is None:
|
||||
return '你还没有绑定UID噢,请使用[ark绑定uid123]完成绑定!'
|
||||
|
||||
await bot.logger.info('开始执行[ark查询信息]')
|
||||
await get_role_img(uid)
|
||||
await bot.send('WIP')
|
||||
# await bot.send(await get_role_img(uid))
|
||||
# await get_role_img(uid)
|
||||
# await bot.send('WIP')
|
||||
await bot.send(await get_role_img(uid))
|
||||
|
@ -1,20 +1,63 @@
|
||||
from pathlib import Path
|
||||
|
||||
from gsuid_core.data_store import get_res_path
|
||||
from gsuid_core.utils.error_reply import get_error
|
||||
from gsuid_core.utils.image.convert import convert_img
|
||||
from msgspec import json as msgjson
|
||||
from PIL import Image, ImageDraw
|
||||
|
||||
from ..utils.ark_api import ark_skd_api
|
||||
from ..utils.fonts.source_han_serif import sans_font_28
|
||||
from ..utils.resource.RESOURCE_PATH import SKIN_PATH
|
||||
|
||||
TEXT_PATH = Path(__file__).parent / 'texture2D'
|
||||
bg_img = Image.open(TEXT_PATH / 'bg.png')
|
||||
base_info_img = Image.open(TEXT_PATH / 'base_info.png')
|
||||
|
||||
|
||||
async def get_role_img(sr_uid: str):
|
||||
player_info = await ark_skd_api.get_game_player_info(sr_uid)
|
||||
async def get_role_img(uid: str):
|
||||
player_info = await ark_skd_api.get_game_player_info(uid)
|
||||
if isinstance(player_info, int):
|
||||
return get_error(player_info)
|
||||
|
||||
current_ts = player_info.currentTs
|
||||
status = player_info.status
|
||||
uid = status.uid
|
||||
|
||||
player_save_path = get_res_path(['ArknightsUID', 'players'])
|
||||
|
||||
with open(player_save_path / f'{uid}.json', 'wb') as file:
|
||||
with open(player_save_path / f'{player_info.status.uid}.json', 'wb') as file:
|
||||
file.write(msgjson.format(msgjson.encode(player_info), indent=4))
|
||||
|
||||
# 放 background
|
||||
char_info = bg_img.copy()
|
||||
|
||||
# 放干员主立绘
|
||||
secretary = player_info.status.secretary
|
||||
# secretary_charId = secretary.charId
|
||||
secretary_skinId = secretary.skinId.replace('@', '_')
|
||||
|
||||
secretary_char_img = (
|
||||
Image.open(SKIN_PATH / f'{secretary_skinId}b.png')
|
||||
.resize((768, 768))
|
||||
.convert('RGBA')
|
||||
)
|
||||
char_info.paste(secretary_char_img, (0, -20), secretary_char_img)
|
||||
|
||||
# 放基础信息
|
||||
base_info = base_info_img.copy()
|
||||
base_info_draw = ImageDraw.Draw(base_info)
|
||||
base_info_draw.text(
|
||||
(400, 163),
|
||||
player_info.status.name,
|
||||
(255, 255, 255),
|
||||
sans_font_28,
|
||||
'lm'
|
||||
)
|
||||
|
||||
# 放入职信息
|
||||
|
||||
|
||||
base_info.resize((475, 400)).convert('RGBA')
|
||||
char_info.paste(base_info, (200, 0), base_info)
|
||||
|
||||
char_info.show()
|
||||
|
||||
res = await convert_img(char_info)
|
||||
return res
|
||||
|
After Width: | Height: | Size: 2.2 MiB |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 7.0 KiB After Width: | Height: | Size: 7.0 KiB |
Before Width: | Height: | Size: 8.3 KiB After Width: | Height: | Size: 8.3 KiB |
Before Width: | Height: | Size: 137 KiB After Width: | Height: | Size: 137 KiB |
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 8.8 KiB |
Before Width: | Height: | Size: 86 KiB After Width: | Height: | Size: 86 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 5.9 KiB |
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 8.8 KiB |
Before Width: | Height: | Size: 9.7 KiB After Width: | Height: | Size: 9.7 KiB |
Before Width: | Height: | Size: 9.8 KiB After Width: | Height: | Size: 9.8 KiB |
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 6.4 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 942 B After Width: | Height: | Size: 942 B |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.3 KiB |
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 6.9 KiB |
Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 9.2 KiB |
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 783 B After Width: | Height: | Size: 783 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
@ -8,6 +8,7 @@ from ..arknightsuid_resource import startup
|
||||
|
||||
async def all_start():
|
||||
try:
|
||||
pass
|
||||
await startup()
|
||||
except Exception as e:
|
||||
logger.exception(e)
|
||||
|
@ -36,6 +36,9 @@ class BaseArkApi:
|
||||
if isinstance(unpack_data, int):
|
||||
return unpack_data
|
||||
else:
|
||||
import json
|
||||
with open('test.json', 'w', encoding='utf-8') as f:
|
||||
json.dump(unpack_data, f, ensure_ascii=False, indent=4)
|
||||
return msgspec.convert(unpack_data, type=ArknightsPlayerInfoModel)
|
||||
|
||||
async def check_cred_valid(self, Cred: str) -> bool | ArknightsUserMeModel:
|
||||
@ -73,7 +76,7 @@ class BaseArkApi:
|
||||
)
|
||||
if Cred is None:
|
||||
return -61
|
||||
arkUser = await ArknightsUser.base_select_data(ArknightsUser, Cred=Cred)
|
||||
arkUser = await ArknightsUser.base_select_data(Cred=Cred)
|
||||
if arkUser is None:
|
||||
return -61
|
||||
header['Cred'] = Cred
|
||||
|
BIN
ArknightsUID/utils/fonts/SourceHanSansCN-Medium.ttf
Normal file
BIN
ArknightsUID/utils/fonts/SourceHanSerifCN-Medium.ttf
Normal file
22
ArknightsUID/utils/fonts/source_han_sans.py
Normal file
@ -0,0 +1,22 @@
|
||||
from pathlib import Path
|
||||
|
||||
from PIL import ImageFont
|
||||
|
||||
FONT_ORIGIN_PATH = Path(__file__).parent / 'SourceHanSansCN-Medium.ttf'
|
||||
|
||||
|
||||
def source_han_sans_cn_origin(size: int) -> ImageFont.FreeTypeFont:
|
||||
return ImageFont.truetype(str(FONT_ORIGIN_PATH), size=size)
|
||||
|
||||
|
||||
sans_font_12 = source_han_sans_cn_origin(12)
|
||||
sans_font_18 = source_han_sans_cn_origin(18)
|
||||
sans_font_22 = source_han_sans_cn_origin(22)
|
||||
sans_font_24 = source_han_sans_cn_origin(24)
|
||||
sans_font_26 = source_han_sans_cn_origin(26)
|
||||
sans_font_36 = source_han_sans_cn_origin(36)
|
||||
sans_font_34 = source_han_sans_cn_origin(34)
|
||||
sans_font_38 = source_han_sans_cn_origin(38)
|
||||
sans_font_28 = source_han_sans_cn_origin(28)
|
||||
sans_font_50 = source_han_sans_cn_origin(50)
|
||||
sans_font_120 = source_han_sans_cn_origin(34)
|
14
ArknightsUID/utils/fonts/source_han_serif.py
Normal file
@ -0,0 +1,14 @@
|
||||
from pathlib import Path
|
||||
|
||||
from PIL import ImageFont
|
||||
|
||||
FONT_ORIGIN_PATH = Path(__file__).parent / 'SourceHanSerifCN-Medium.ttf'
|
||||
|
||||
|
||||
def source_han_serif_origin(size: int) -> ImageFont.FreeTypeFont:
|
||||
return ImageFont.truetype(str(FONT_ORIGIN_PATH), size=size)
|
||||
|
||||
|
||||
sans_font_12 = source_han_serif_origin(12)
|
||||
sans_font_28 = source_han_serif_origin(28)
|
||||
sans_font_120 = source_han_serif_origin(34)
|
15
ArknightsUID/utils/image/image_tools.py
Normal file
@ -0,0 +1,15 @@
|
||||
from pathlib import Path
|
||||
|
||||
from gsuid_core.utils.image.image_tools import CustomizeImage
|
||||
from PIL import Image
|
||||
|
||||
BG_PATH = Path(__file__).parent / 'bg'
|
||||
NM_BG_PATH = BG_PATH / 'nm_bg'
|
||||
SP_BG_PATH = BG_PATH / 'sp_bg'
|
||||
|
||||
|
||||
async def get_simple_bg(
|
||||
based_w: int, based_h: int, image: str | None | Image.Image = None
|
||||
) -> Image.Image:
|
||||
CIL = CustomizeImage(NM_BG_PATH)
|
||||
return CIL.get_image(image, based_w, based_h)
|
@ -173,3 +173,6 @@ class CharacterTable(BaseModel):
|
||||
|
||||
def __init__(self, data: dict) -> None:
|
||||
super().__init__(chars=data)
|
||||
|
||||
def __getitem__(self, key: str) -> CharacterData:
|
||||
return self.chars[key]
|
||||
|
@ -109,17 +109,17 @@ class PlayerManufactureFormulaInfo(Struct):
|
||||
itemId: str
|
||||
count: int
|
||||
weight: int
|
||||
costs: list[str]
|
||||
costPoint: int
|
||||
costs: list[str] | None = None
|
||||
|
||||
|
||||
class PlayerEquipmentInfo(Struct):
|
||||
id_: str = field(name='id')
|
||||
name: str
|
||||
desc: str
|
||||
typeIcon: str
|
||||
typeName1: str
|
||||
shiningColor: str
|
||||
desc: str | None = None
|
||||
typeName1: str | None = None
|
||||
|
||||
|
||||
class PlayerCampaignZoneInfo(Struct):
|
||||
@ -147,8 +147,8 @@ class PlayerTowerInfo(Struct):
|
||||
id_: str = field(name='id')
|
||||
name: str
|
||||
subName: str
|
||||
hasHard: bool
|
||||
stageNum: int
|
||||
hasHard: bool | None = None
|
||||
stageNum: int | None = None
|
||||
|
||||
|
||||
class PlayerZoneInfo(Struct):
|
||||
@ -174,17 +174,17 @@ class PlayerStageInfo(Struct):
|
||||
|
||||
class PlayerSkinInfo(Struct):
|
||||
id_: str = field(name='id')
|
||||
name: str
|
||||
brandId: str
|
||||
brandName: str
|
||||
brandCapitalName: str
|
||||
illustId: str
|
||||
dynIllustId: str
|
||||
avatarId: str
|
||||
portraitId: str
|
||||
sortId: int
|
||||
displayTagId: str
|
||||
skinGroupId: str
|
||||
name: str | None = None
|
||||
brandName: str | None = None
|
||||
brandCapitalName: str | None = None
|
||||
illustId: str | None = None
|
||||
dynIllustId: str | None = None
|
||||
avatarId: str | None = None
|
||||
portraitId: str | None = None
|
||||
skinGroupId: str | None = None
|
||||
|
||||
|
||||
class PlayerCharInfo(Struct):
|
||||
@ -208,14 +208,14 @@ class ActivityZone(Struct):
|
||||
zoneReplicaId: str
|
||||
clearedStage: int
|
||||
totalStage: int
|
||||
stageStatus: list[ActivityZoneStageStatus]
|
||||
stageStatus: list[ActivityZoneStageStatus] | None = None
|
||||
|
||||
|
||||
class PlayerActivity(Struct):
|
||||
actId: str
|
||||
actReplicaId: str
|
||||
type_: str = field(name='type')
|
||||
zones: list[ActivityZone]
|
||||
type_: str | None = field(name='type', default=None)
|
||||
|
||||
|
||||
class RewoardItem(Struct):
|
||||
@ -235,10 +235,10 @@ class BankItem(Struct):
|
||||
|
||||
class RogueRecord(Struct):
|
||||
rogueId: str
|
||||
clearTime: int
|
||||
relicCnt: int
|
||||
bank: BankItem
|
||||
mission: RewoardItem
|
||||
mission: RewoardItem | None = None
|
||||
clearTime: int | None = None
|
||||
|
||||
|
||||
class PlayerRogue(Struct):
|
||||
@ -254,10 +254,10 @@ class TowerReward(Struct):
|
||||
class TowerRecord(Struct):
|
||||
towerId: str
|
||||
best: int
|
||||
hasHard: bool
|
||||
stageNum: int
|
||||
unlockHard: bool
|
||||
hardBest: int
|
||||
hasHard: bool | None = None
|
||||
stageNum: int | None = None
|
||||
unlockHard: bool | None = None
|
||||
hardBest: int | None = None
|
||||
|
||||
|
||||
class PlayerTower(Struct):
|
||||
@ -288,9 +288,9 @@ class RecruitTag(Struct):
|
||||
class PlayerRecruit(Struct):
|
||||
startTs: int
|
||||
finishTs: int
|
||||
duration: int
|
||||
selectTags: list[RecruitTag | None]
|
||||
state: int
|
||||
duration: int | None = None
|
||||
selectTags: list[RecruitTag] | None = None
|
||||
|
||||
|
||||
class BuildingTrainingTrainee(Struct):
|
||||
@ -448,8 +448,18 @@ class BuildingPower(Struct):
|
||||
chars: list[BuildingChar]
|
||||
|
||||
|
||||
class BuildingTiredChar(Struct):
|
||||
charId: str
|
||||
ap: int
|
||||
lastApAddTime: int
|
||||
roomSlotId: str
|
||||
index: int
|
||||
bubble: BuildingCharBubble
|
||||
workTime: int
|
||||
|
||||
|
||||
class PlayerBuilding(Struct):
|
||||
tiredChars: list[str]
|
||||
tiredChars: list[BuildingTiredChar]
|
||||
powers: list[BuildingPower]
|
||||
manufactures: list[BuildingManufactures]
|
||||
tradings: list[BuildingTradings]
|
||||
@ -572,7 +582,6 @@ class ArknightsPlayerInfoModel(Struct, omit_defaults=True, gc=False):
|
||||
currentTs: int
|
||||
showConfig: DisplayShowConfig
|
||||
status: PlayerStatus
|
||||
medal: PlayerMedal
|
||||
assistChars: list[PlayerAssistChar]
|
||||
chars: list[PlayerInfoChar]
|
||||
skins: list[PlayerInfoSkin]
|
||||
@ -587,17 +596,18 @@ class ArknightsPlayerInfoModel(Struct, omit_defaults=True, gc=False):
|
||||
skinInfoMap: dict[str, PlayerSkinInfo]
|
||||
stageInfoMap: dict[str, PlayerStageInfo]
|
||||
activityInfoMap: dict[str, PlayerActivityInfo]
|
||||
zoneInfoMap: dict[str, PlayerZoneInfo]
|
||||
towerInfoMap: dict[str, PlayerTowerInfo]
|
||||
rogueInfoMap: dict[str, PlayerRogueInfo]
|
||||
campaignInfoMap: dict[str, PlayerCampaignInfo]
|
||||
medalInfoMap: dict[str, PlayerMedalInfo]
|
||||
campaignZoneInfoMap: dict[str, PlayerCampaignZoneInfo]
|
||||
equipmentInfoMap: dict[str, PlayerEquipmentInfo]
|
||||
manufactureFormulaInfoMap: dict[str, PlayerManufactureFormulaInfo]
|
||||
charAssets: list[PlayerCharAsset]
|
||||
skinAssets: list[PlayerSkinAsset]
|
||||
activityBannerList: dict[str, list[PlayerActivityBannerList]]
|
||||
medal: PlayerMedal | None = None
|
||||
zoneInfoMap: dict[str, PlayerZoneInfo] | None = None
|
||||
medalInfoMap: dict[str, PlayerMedalInfo] | None = None
|
||||
|
||||
|
||||
################
|
||||
|
@ -10,6 +10,7 @@ CONFIG_PATH = MAIN_PATH / 'config.json'
|
||||
PLAYER_PATH = MAIN_PATH / 'players'
|
||||
RESOURCE_PATH = MAIN_PATH / 'resource'
|
||||
GAMEDATA_PATH = RESOURCE_PATH / 'gamedata'
|
||||
SKIN_PATH = RESOURCE_PATH / 'skin'
|
||||
|
||||
def init_dir():
|
||||
for i in [
|
||||
@ -17,7 +18,8 @@ def init_dir():
|
||||
CU_BG_PATH,
|
||||
PLAYER_PATH,
|
||||
RESOURCE_PATH,
|
||||
GAMEDATA_PATH
|
||||
GAMEDATA_PATH,
|
||||
SKIN_PATH
|
||||
]:
|
||||
i.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
|