2025-03-05 18:15:05 +08:00

533 lines
17 KiB
Python

import asyncio
from datetime import datetime, timedelta
from pathlib import Path
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 import now_ap, seconds2hours_zhcn
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)
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=uid)
# if status is not bool:
# skd_uid = await ArknightsUser.get_user_attr_by_uid(
# uid=uid,
# attr="skd_uid",
# )
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 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
if finishTs != -1:
# 获取当前时间与 finishTs 的时间差, 转换为几小时几分钟
now = datetime.now()
finishTs = datetime.fromtimestamp(finishTs)
delta = finishTs - now
delta_hour = delta.seconds // 3600
delta_minute = (delta.seconds - delta_hour * 3600) // 60
else:
delta_hour = 0
delta_minute = 0
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",
)
if recruit_task_finish_count == len(recruit):
blue_bar_bg1_draw.text(
(540, 70),
"招募已全部完成",
font=sans_font_18,
fill=first_color,
anchor="rm",
)
else:
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"{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
if player_info.building.hire:
if player_info.building.hire.refreshCount == 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)
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",
)
img.paste(grey_bar_bg1_img, (-20, 910), grey_bar_bg1_img)
# training char check
if player_info.building.training and player_info.building.training.trainee:
training_char = player_info.building.training.trainee.charId
remain_secs = player_info.building.training.remainSecs
remain_time = 0
if remain_secs != -1:
# 将remainSecs(剩余秒数) , 转换为几小时几分钟
remain_time = seconds2hours_zhcn(remain_secs)
char_cn_name = EXCEL.CHARATER_TABLE.chars[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}后完成专精" if remain_secs != -1 else "设备空闲中",
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