This commit is contained in:
Wuyi无疑 2022-03-29 23:13:03 +08:00
parent a2b1f47256
commit d26849207a
4 changed files with 283 additions and 228 deletions

3
.gitignore vendored
View File

@ -1 +1,2 @@
/.idea/ /.idea/
mihoyo_libs/mihoyo_bbs/bg/**

View File

@ -16,7 +16,7 @@ from nonebot import logger
mhyVersion = "2.11.1" mhyVersion = "2.11.1"
BASE_PATH = os.path.dirname(__file__) BASE_PATH = os.path.dirname(__file__)
BASE2_PATH = os.path.join(BASE_PATH, 'mihoyo_bbs') BASE2_PATH = os.path.join(BASE_PATH, 'mihoyo_libs/mihoyo_bbs')
INDEX_PATH = os.path.join(BASE2_PATH, 'index') INDEX_PATH = os.path.join(BASE2_PATH, 'index')
@ -725,6 +725,7 @@ def get_character(uid, character_ids, ck, server_id="cn_gf01"):
logger.info("深渊信息读取老Api失败") logger.info("深渊信息读取老Api失败")
logger.info(e.with_traceback) logger.info(e.with_traceback)
async def get_calculate_info(uid, char_id, ck, server_id="cn_gf01"): async def get_calculate_info(uid, char_id, ck, server_id="cn_gf01"):
if uid[0] == '5': if uid[0] == '5':
server_id = "cn_qd01" server_id = "cn_qd01"
@ -732,23 +733,24 @@ async def get_calculate_info(uid, char_id, ck, server_id="cn_gf01"):
async with AsyncClient() as client: async with AsyncClient() as client:
req = await client.get( req = await client.get(
url=url, url=url,
headers = { headers={
'DS': get_ds_token("uid={}&avatar_id={}&region={}".format(uid, char_id, server_id)), 'DS' : get_ds_token("uid={}&avatar_id={}&region={}".format(uid, char_id, server_id)),
'x-rpc-app_version': mhyVersion, 'x-rpc-app_version': mhyVersion,
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (' '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', 'KHTML, like Gecko) miHoYoBBS/2.11.1',
'x-rpc-client_type': '5', 'x-rpc-client_type': '5',
'Referer': 'https://webstatic.mihoyo.com/', 'Referer' : 'https://webstatic.mihoyo.com/',
"Cookie": ck}, "Cookie" : ck},
params = { params={
"avatar_id": char_id, "avatar_id": char_id,
"uid": uid, "uid" : uid,
"region": server_id "region" : server_id
} }
) )
data = json.loads(req.text) data = json.loads(req.text)
return data return data
async def get_mihoyo_bbs_info(mysid, ck): async def get_mihoyo_bbs_info(mysid, ck):
try: try:
async with AsyncClient() as client: async with AsyncClient() as client:
@ -927,4 +929,4 @@ async def get_genshin_events(mode="List"):
params=params params=params
) )
data = json.loads(req.text) data = json.loads(req.text)
return data return data

View File

@ -1,12 +1,10 @@
import json
import asyncio import asyncio
from typing import Optional, Union, Any
import os,time
import math import math
import threading import threading
from base64 import b64encode from base64 import b64encode
from io import BytesIO from io import BytesIO
from re import findall from re import Match, findall
from typing import Optional
import numpy as np import numpy as np
from PIL import Image, ImageDraw, ImageFilter, ImageFont from PIL import Image, ImageDraw, ImageFilter, ImageFont
@ -17,7 +15,7 @@ from wordcloud import WordCloud
from .get_data import * from .get_data import *
FILE_PATH = os.path.dirname(__file__) FILE_PATH = os.path.dirname(__file__)
FILE2_PATH = os.path.join(FILE_PATH, 'mihoyo_bbs') FILE2_PATH = os.path.join(FILE_PATH, 'mihoyo_libs/mihoyo_bbs')
CHAR_PATH = os.path.join(FILE2_PATH, 'chars') CHAR_PATH = os.path.join(FILE2_PATH, 'chars')
CHAR_DONE_PATH = os.path.join(FILE2_PATH, 'char_done') CHAR_DONE_PATH = os.path.join(FILE2_PATH, 'char_done')
CHAR_IMG_PATH = os.path.join(FILE2_PATH, 'char_img') CHAR_IMG_PATH = os.path.join(FILE2_PATH, 'char_img')
@ -28,10 +26,11 @@ TEXT_PATH = os.path.join(FILE2_PATH, 'texture2d')
WEAPON_PATH = os.path.join(FILE2_PATH, 'weapon') WEAPON_PATH = os.path.join(FILE2_PATH, 'weapon')
BG_PATH = os.path.join(FILE2_PATH, 'bg') BG_PATH = os.path.join(FILE2_PATH, 'bg')
class customize_image: class customize_image:
def __init__(self,image: str,based_w: int,based_h: int) -> None: def __init__(self, image: Match, based_w: int, based_h: int) -> None:
self.bg_img = self.get_image(image,based_w,based_h) self.bg_img = self.get_image(image, based_w, based_h)
self.bg_color = self.get_bg_color(self.bg_img) self.bg_color = self.get_bg_color(self.bg_img)
self.text_color = self.get_text_color(self.bg_color) self.text_color = self.get_text_color(self.bg_color)
self.highlight_color = self.get_highlight_color(self.bg_color) self.highlight_color = self.get_highlight_color(self.bg_color)
@ -39,7 +38,8 @@ class customize_image:
self.bg_detail_color = self.get_bg_detail_color(self.bg_color) self.bg_detail_color = self.get_bg_detail_color(self.bg_color)
self.char_high_color = self.get_char_high_color(self.bg_color) self.char_high_color = self.get_char_high_color(self.bg_color)
def get_image(self,image: str,based_w: int,based_h: int) -> Image: @staticmethod
def get_image(image: Match, based_w: int, based_h: int) -> Image:
# 获取背景图片 # 获取背景图片
bg2_path = os.path.join(BG_PATH, random.choice([x for x in os.listdir(BG_PATH) bg2_path = os.path.join(BG_PATH, random.choice([x for x in os.listdir(BG_PATH)
if os.path.isfile(os.path.join(BG_PATH, x))])) if os.path.isfile(os.path.join(BG_PATH, x))]))
@ -65,7 +65,8 @@ class customize_image:
return bg_img return bg_img
def get_bg_color(self,edit_bg:Image) -> tuple[int, int, int]: @staticmethod
def get_bg_color(edit_bg: Image) -> tuple[int, int, int]:
# 获取背景主色 # 获取背景主色
color = 8 color = 8
q = edit_bg.quantize(colors=color, method=2) q = edit_bg.quantize(colors=color, method=2)
@ -78,64 +79,69 @@ class customize_image:
if abs(light_value - based_light) < temp: if abs(light_value - based_light) < temp:
bg_color = bg bg_color = bg
temp = abs(light_value - based_light) temp = abs(light_value - based_light)
#if max(*bg) < 240 and min(*bg) > 20: # if max(*bg) < 240 and min(*bg) > 20:
# bg_color = bg # bg_color = bg
return bg_color return bg_color
def get_text_color(self,bg_color: tuple[int, int, int]) -> tuple[int, int, int]: @staticmethod
def get_text_color(bg_color: tuple[int, int, int]) -> tuple[int, int, int]:
# 通过背景主色bg_color确定文字主色 # 通过背景主色bg_color确定文字主色
r = 125 r = 125
if max(*bg_color) > 255 - r: if max(*bg_color) > 255 - r:
r *= -1 r *= -1
text_color = (math.floor(bg_color[0] + r if bg_color[0] + r <= 255 else 255), text_color = (math.floor(bg_color[0] + r if bg_color[0] + r <= 255 else 255),
math.floor(bg_color[1] + r if bg_color[1] + r <= 255 else 255), math.floor(bg_color[1] + r if bg_color[1] + r <= 255 else 255),
math.floor(bg_color[2] + r if bg_color[2] + r <= 255 else 255)) math.floor(bg_color[2] + r if bg_color[2] + r <= 255 else 255))
return text_color return text_color
def get_char_color(self,bg_color: tuple[int, int, int]) -> tuple[int, int, int]: @staticmethod
def get_char_color(bg_color: tuple[int, int, int]) -> tuple[int, int, int]:
r = 140 r = 140
if max(*bg_color) > 255 - r: if max(*bg_color) > 255 - r:
r *= -1 r *= -1
char_color = (math.floor(bg_color[0] + 5 if bg_color[0] + r <= 255 else 255), char_color = (math.floor(bg_color[0] + 5 if bg_color[0] + r <= 255 else 255),
math.floor(bg_color[1] + 5 if bg_color[1] + r <= 255 else 255), math.floor(bg_color[1] + 5 if bg_color[1] + r <= 255 else 255),
math.floor(bg_color[2] + 5 if bg_color[2] + r <= 255 else 255)) math.floor(bg_color[2] + 5 if bg_color[2] + r <= 255 else 255))
return char_color return char_color
def get_char_high_color(self,bg_color: tuple[int, int, int]) -> tuple[int, int, int]: @staticmethod
def get_char_high_color(bg_color: tuple[int, int, int]) -> tuple[int, int, int]:
r = 140 r = 140
d = 20 d = 20
if max(*bg_color) > 255 - r: if max(*bg_color) > 255 - r:
r *= -1 r *= -1
char_color = (math.floor(bg_color[0] + d if bg_color[0] + r <= 255 else 255), char_color = (math.floor(bg_color[0] + d if bg_color[0] + r <= 255 else 255),
math.floor(bg_color[1] + d if bg_color[1] + r <= 255 else 255), math.floor(bg_color[1] + d if bg_color[1] + r <= 255 else 255),
math.floor(bg_color[2] + d if bg_color[2] + r <= 255 else 255)) math.floor(bg_color[2] + d if bg_color[2] + r <= 255 else 255))
return char_color return char_color
def get_bg_detail_color(self,bg_color: tuple[int, int, int]) -> tuple[int, int, int]: @staticmethod
def get_bg_detail_color(bg_color: tuple[int, int, int]) -> tuple[int, int, int]:
r = 140 r = 140
if max(*bg_color) > 255 - r: if max(*bg_color) > 255 - r:
r *= -1 r *= -1
bg_detail_color = (math.floor(bg_color[0] - 20 if bg_color[0] + r <= 255 else 255), bg_detail_color = (math.floor(bg_color[0] - 20 if bg_color[0] + r <= 255 else 255),
math.floor(bg_color[1] - 20 if bg_color[1] + r <= 255 else 255), math.floor(bg_color[1] - 20 if bg_color[1] + r <= 255 else 255),
math.floor(bg_color[2] - 20 if bg_color[2] + r <= 255 else 255)) math.floor(bg_color[2] - 20 if bg_color[2] + r <= 255 else 255))
return bg_detail_color return bg_detail_color
def get_highlight_color(self,color: tuple[int, int, int]) -> tuple[int, int, int]: @staticmethod
def get_highlight_color(color: tuple[int, int, int]) -> tuple[int, int, int]:
red_color = color[0] red_color = color[0]
green_color = color[1] green_color = color[1]
blue_color = color[2] blue_color = color[2]
highlight_color = {} highlight_color = {"red" : red_color - 127 if red_color > 127 else 127,
highlight_color["red"] = red_color - 127 if red_color > 127 else 127 "green": green_color - 127 if green_color > 127 else 127,
highlight_color["green"] = green_color - 127 if green_color > 127 else 127 "blue" : blue_color - 127 if blue_color > 127 else 127}
highlight_color["blue"] = blue_color - 127 if blue_color > 127 else 127
max_color = max(highlight_color.values()) max_color = max(highlight_color.values())
name = ''
for _highlight_color in highlight_color: for _highlight_color in highlight_color:
if highlight_color[_highlight_color] == max_color: if highlight_color[_highlight_color] == max_color:
name = str(_highlight_color) name = str(_highlight_color)
if name == "red": if name == "red":
return red_color, highlight_color["green"], highlight_color["blue"] return red_color, highlight_color["green"], highlight_color["blue"]
elif name == "green": elif name == "green":
@ -145,6 +151,7 @@ class customize_image:
else: else:
return 0, 0, 0 # Error return 0, 0, 0 # Error
def genshin_font(size: int): def genshin_font(size: int):
return ImageFont.truetype(os.path.join(FILE2_PATH, "yuanshen.ttf"), size=size) return ImageFont.truetype(os.path.join(FILE2_PATH, "yuanshen.ttf"), size=size)
@ -184,17 +191,18 @@ def get_rel_pic(url: str):
with open(os.path.join(REL_PATH, url.split('/')[-1]), 'wb') as f: with open(os.path.join(REL_PATH, url.split('/')[-1]), 'wb') as f:
f.write(get(url).content) f.write(get(url).content)
class get_cookies: class get_cookies:
def __init__(self) -> None: def __init__(self) -> None:
self.useable_cookies: Optional[str] = None self.useable_cookies: Optional[str] = None
self.uid: Optional[str] = None self.uid: Optional[str] = None
self.mode: Optional[int] = None self.mode: Optional[int] = None
self.raw_abyss_data: Optional[json] = None self.raw_abyss_data: Optional[dict] = None
self.raw_data: Optional[json] = None self.raw_data: Optional[dict] = None
self.nickname: Optional[int] = None self.nickname: Optional[int] = None
self.schedule_type: Optional[str] = None self.schedule_type: Optional[str] = None
async def get_useable_cookies(self, uid: str, mode: int = 2,schedule_type: str = "1"): async def get_useable_cookies(self, uid: str, mode: int = 2, schedule_type: str = "1"):
self.uid = uid self.uid = uid
self.schedule_type = schedule_type self.schedule_type = schedule_type
while True: while True:
@ -224,11 +232,11 @@ class get_cookies:
self.nickname = mys_data['data']['list'][0]['nickname'] self.nickname = mys_data['data']['list'][0]['nickname']
self.raw_data = await get_info(self.uid, self.useable_cookies) self.raw_data = await get_info(self.uid, self.useable_cookies)
self.raw_abyss_data = await get_spiral_abyss_info(self.uid, self.useable_cookies, self.schedule_type) self.raw_abyss_data = await get_spiral_abyss_info(self.uid, self.useable_cookies, self.schedule_type)
async def get_uid_data(self): async def get_uid_data(self):
self.raw_abyss_data = await get_spiral_abyss_info(self.uid, self.useable_cookies, self.schedule_type) self.raw_abyss_data = await get_spiral_abyss_info(self.uid, self.useable_cookies, self.schedule_type)
self.raw_data = await get_info(self.uid, self.useable_cookies) self.raw_data = await get_info(self.uid, self.useable_cookies)
async def check_cookies_useable(self): async def check_cookies_useable(self):
if self.raw_data: if self.raw_data:
if self.raw_data["retcode"] != 0: if self.raw_data["retcode"] != 0:
@ -250,27 +258,28 @@ class get_cookies:
else: else:
return "没有可以使用的Cookies" return "没有可以使用的Cookies"
async def draw_word_cloud(uid: str, image: Optional[str] = None, mode: int = 2):
def create_rounded_rectangle_mask(rectangle, radius):
solid_fill = (50, 50, 50, 255)
i = Image.new("RGBA", rectangle.size, (0, 0, 0, 0))
corner = Image.new('RGBA', (radius, radius), (0, 0, 0, 0)) async def draw_word_cloud(uid: str, image: Optional[Match] = None, mode: int = 2):
def create_rounded_rectangle_mask(rectangle, _radius):
solid_fill = (50, 50, 50, 255)
img = Image.new("RGBA", rectangle.size, (0, 0, 0, 0))
corner = Image.new('RGBA', (_radius, _radius), (0, 0, 0, 0))
draw = ImageDraw.Draw(corner) draw = ImageDraw.Draw(corner)
draw.pieslice(((0, 0), (radius * 2, radius * 2)), 180, 270, fill=solid_fill) draw.pieslice(((0, 0), (_radius * 2, _radius * 2)), 180, 270, fill=solid_fill)
mx, my = rectangle.size mx, my = rectangle.size
i.paste(corner, (0, 0), corner) img.paste(corner, (0, 0), corner)
i.paste(corner.rotate(90), (0, my - radius), corner.rotate(90)) img.paste(corner.rotate(90), (0, my - _radius), corner.rotate(90))
i.paste(corner.rotate(180), (mx - radius, my - radius), corner.rotate(180)) img.paste(corner.rotate(180), (mx - _radius, my - _radius), corner.rotate(180))
i.paste(corner.rotate(270), (mx - radius, 0), corner.rotate(270)) img.paste(corner.rotate(270), (mx - _radius, 0), corner.rotate(270))
draw = ImageDraw.Draw(i) draw = ImageDraw.Draw(img)
draw.rectangle(((radius, 0), (mx - radius, my)), fill=solid_fill) draw.rectangle(((_radius, 0), (mx - _radius, my)), fill=solid_fill)
draw.rectangle(((0, radius), (mx, my - radius)), fill=solid_fill) draw.rectangle(((0, _radius), (mx, my - _radius)), fill=solid_fill)
return i return img
nickname = '' nickname = ''
while True: while True:
@ -533,11 +542,12 @@ async def draw_word_cloud(uid: str, image: Optional[str] = None, mode: int = 2):
resultmes = imgmes resultmes = imgmes
return resultmes return resultmes
async def draw_abyss0_pic(uid, nickname, image=None, mode=2, date="1"): async def draw_abyss0_pic(uid, nickname, image=None, mode=2, date="1"):
# 获取Cookies # 获取Cookies
data_def = get_cookies() data_def = get_cookies()
retcode = await data_def.get_useable_cookies(uid, mode, date) retcode = await data_def.get_useable_cookies(uid, mode, date)
if retcode != True: if not retcode:
return retcode return retcode
raw_char_data = data_def.raw_data raw_char_data = data_def.raw_data
raw_data = data_def.raw_abyss_data raw_data = data_def.raw_abyss_data
@ -551,15 +561,15 @@ async def draw_abyss0_pic(uid, nickname, image=None, mode=2, date="1"):
# 获取查询者数据 # 获取查询者数据
floors_data = raw_data['floors'][-1] floors_data = raw_data['floors'][-1]
levels_num = len(floors_data['levels']) levels_num = len(floors_data['levels'])
# 获取背景图片各项参数 # 获取背景图片各项参数
based_w = 900 based_w = 900
based_h = 660 + levels_num * 315 based_h = 660 + levels_num * 315
image_def = customize_image(image,based_w,based_h) image_def = customize_image(image, based_w, based_h)
bg_img = image_def.bg_img bg_img = image_def.bg_img
bg_color = image_def.bg_color bg_color = image_def.bg_color
text_color = image_def.text_color text_color = image_def.text_color
highlight_color = image_def.highlight_color # highlight_color = image_def.highlight_color
# 确定贴图路径 # 确定贴图路径
abyss0_path = os.path.join(TEXT_PATH, "abyss_0.png") abyss0_path = os.path.join(TEXT_PATH, "abyss_0.png")
@ -813,11 +823,12 @@ async def draw_abyss0_pic(uid, nickname, image=None, mode=2, date="1"):
return resultmes return resultmes
async def draw_abyss_pic(uid: str, nickname: str, floor_num : int, image: Optional[str] = None, mode: int = 2, date : str = "1"): async def draw_abyss_pic(uid: str, nickname: str, floor_num: int, image: Optional[Match] = None, mode: int = 2,
date: str = "1"):
# 获取Cookies # 获取Cookies
data_def = get_cookies() data_def = get_cookies()
retcode = await data_def.get_useable_cookies(uid, mode, date) retcode = await data_def.get_useable_cookies(uid, mode, date)
if retcode != True: if not retcode:
return retcode return retcode
raw_char_data = data_def.raw_data raw_char_data = data_def.raw_data
raw_data = data_def.raw_abyss_data raw_data = data_def.raw_abyss_data
@ -837,11 +848,11 @@ async def draw_abyss_pic(uid: str, nickname: str, floor_num : int, image: Option
# 获取背景图片各项参数 # 获取背景图片各项参数
based_w = 900 based_w = 900
based_h = 440 + levels_num * 340 based_h = 440 + levels_num * 340
image_def = customize_image(image,based_w,based_h) image_def = customize_image(image, based_w, based_h)
bg_img = image_def.bg_img bg_img = image_def.bg_img
bg_color = image_def.bg_color bg_color = image_def.bg_color
text_color = image_def.text_color text_color = image_def.text_color
highlight_color = image_def.highlight_color # highlight_color = image_def.highlight_color
# 打开图片 # 打开图片
abyss1_path = os.path.join(TEXT_PATH, "abyss_1.png") abyss1_path = os.path.join(TEXT_PATH, "abyss_1.png")
@ -968,11 +979,91 @@ async def draw_abyss_pic(uid: str, nickname: str, floor_num : int, image: Option
return resultmes return resultmes
async def draw_pic(uid: str, nickname: str, image: Optional[str] = None, mode: int = 2, role_level: Optional[int] = None): async def draw_char_pic(img: Image, char_data: dict, index: int, bg_color: tuple[int, int, int],
text_color: tuple[int, int, int], bg_detail_color: tuple[int, int, int],
char_high_color: tuple[int, int, int], uid, use_cookies):
char_mingzuo = 0
for k in char_data['constellations']:
if k['is_actived']:
char_mingzuo += 1
if char_data['rarity'] == 5:
char_0 = Image.new("RGBA", (180, 90), char_high_color)
else:
char_0 = Image.new("RGBA", (180, 90), bg_color)
char_0_raw = Image.open(os.path.join(TEXT_PATH, "char_0.png"))
alpha = char_0_raw.getchannel('A')
char_0.putalpha(alpha)
char_2 = Image.new("RGBA", (180, 90), bg_detail_color)
char_2_raw = Image.open(os.path.join(TEXT_PATH, "char_2.png"))
alpha = char_2_raw.getchannel('A')
char_2.putalpha(alpha)
"""
char_3 = Image.new("RGBA", (180, 90), bg_detail_color)
char_3_raw = Image.open(os.path.join(TEXT_PATH, "char_3.png"))
alpha = char_3_raw.getchannel('A')
char_3.putalpha(alpha)
"""
char_1_mask = Image.open(os.path.join(TEXT_PATH, "char_1_mask.png"))
char_talent_data = await get_calculate_info(uid, str(char_data["id"]), use_cookies)
if not os.path.exists(os.path.join(WEAPON_PATH, str(char_data['weapon']['icon'].split('/')[-1]))):
get_weapon_pic(char_data['weapon']['icon'])
if not os.path.exists(os.path.join(CHAR_PATH, str(char_data['id']) + ".png")):
get_char_pic(char_data['id'], char_data['icon'])
char_img = Image.open(os.path.join(CHAR_PATH, str(char_data["id"]) + ".png")).resize((81, 81),
Image.ANTIALIAS)
weapon_img = Image.open(
os.path.join(WEAPON_PATH, str(char_data['weapon']['icon'].split('/')[-1]))).resize((40, 40),
Image.ANTIALIAS)
weapon_1_mask = char_1_mask.resize((40, 40), Image.ANTIALIAS)
char_0_temp = Image.new("RGBA", (180, 90))
char_0_temp.paste(char_img, (8, 5), char_1_mask)
char_0_temp.paste(weapon_img, (70, 45), weapon_1_mask)
char_0.paste(char_0_temp, (0, 0), char_0_temp)
char_0.paste(char_2, (0, 0), char_2)
# char_0.paste(char_3, (0, 0), char_3)
draw_text = ImageDraw.Draw(char_0)
for i in range(0, 2):
draw_text.text((106 + 23 * i, 17),
f'{str(char_talent_data["data"]["skill_list"][i]["level_current"])}', text_color,
genshin_font(15), anchor="mm")
if len(char_talent_data["data"]["skill_list"]) == 7 and char_data["name"] != "珊瑚宫心海":
draw_text.text((106 + 23 * 2, 17),
f'{str(char_talent_data["data"]["skill_list"][3]["level_current"])}', text_color,
genshin_font(15), anchor="mm")
else:
draw_text.text((106 + 23 * 2, 17),
f'{str(char_talent_data["data"]["skill_list"][2]["level_current"])}', text_color,
genshin_font(15), anchor="mm")
draw_text.text((42, 77), "Lv.{}".format(str(char_data["level"])), text_color, genshin_font(16),
anchor="mm")
draw_text.text((162, 38), "{}".format(char_mingzuo), text_color, genshin_font(18), anchor="rm")
draw_text.text((115, 57), 'Lv.{}'.format(str(char_data['weapon']['level'])), text_color,
genshin_font(18), anchor="lm")
draw_text.text((115, 75), '{}'.format(str(char_data['weapon']['affix_level'])), text_color,
genshin_font(16), anchor="lm")
if str(char_data["fetter"]) == "10" or str(char_data["name"]) == "旅行者":
draw_text.text((74, 19), "", text_color, genshin_font(14), anchor="mm")
else:
draw_text.text((73, 18), '{}'.format(str(char_data['fetter'])), text_color, genshin_font(16),
anchor="mm")
char_crop = (75 + 190 * (index % 4), 800 + 100 * (index // 4))
img.paste(char_0, char_crop, char_0)
async def draw_pic(uid: str, nickname: str, image: Optional[Match] = None, mode: int = 2,
role_level: Optional[int] = None):
# 获取Cookies # 获取Cookies
data_def = get_cookies() data_def = get_cookies()
retcode = await data_def.get_useable_cookies(uid, mode) retcode = await data_def.get_useable_cookies(uid, mode)
if retcode != True: if not retcode:
return retcode return retcode
use_cookies = data_def.useable_cookies use_cookies = data_def.useable_cookies
raw_data = data_def.raw_data raw_data = data_def.raw_data
@ -998,11 +1089,11 @@ async def draw_pic(uid: str, nickname: str, image: Optional[str] = None, mode: i
# 获取背景图片各项参数 # 获取背景图片各项参数
based_w = 900 based_w = 900
based_h = 870 + char_hang * 100 if char_num > 8 else 890 + char_hang * 110 based_h = 870 + char_hang * 100 if char_num > 8 else 890 + char_hang * 110
image_def = customize_image(image,based_w,based_h) image_def = customize_image(image, based_w, based_h)
bg_img = image_def.bg_img bg_img = image_def.bg_img
bg_color = image_def.bg_color bg_color = image_def.bg_color
text_color = image_def.text_color text_color = image_def.text_color
highlight_color = image_def.highlight_color # highlight_color = image_def.highlight_color
char_color = image_def.char_color char_color = image_def.char_color
bg_detail_color = image_def.bg_detail_color bg_detail_color = image_def.bg_detail_color
char_high_color = image_def.char_high_color char_high_color = image_def.char_high_color
@ -1076,7 +1167,8 @@ async def draw_pic(uid: str, nickname: str, image: Optional[str] = None, mode: i
text_draw.text((513, 550), str(raw_data['stats']['geoculus_number']), text_color, genshin_font(22)) text_draw.text((513, 550), str(raw_data['stats']['geoculus_number']), text_color, genshin_font(22))
# 雪山 # 雪山
text_draw.text((745, 373.5), str(raw_data['world_explorations'][2]['exploration_percentage'] / 10) + '%', text_color, text_draw.text((745, 373.5), str(raw_data['world_explorations'][2]['exploration_percentage'] / 10) + '%',
text_color,
genshin_font(22)) genshin_font(22))
text_draw.text((745, 407.1), 'lv.' + str(raw_data['world_explorations'][2]['level']), text_color, genshin_font(22)) text_draw.text((745, 407.1), 'lv.' + str(raw_data['world_explorations'][2]['level']), text_color, genshin_font(22))
@ -1133,79 +1225,16 @@ async def draw_pic(uid: str, nickname: str, image: Optional[str] = None, mode: i
char_fg = Image.open(char_fg_path) char_fg = Image.open(char_fg_path)
num = 0 num = 0
for index,i in enumerate(char_datas): for index, i in enumerate(char_datas):
if i['rarity'] > 5: if i['rarity'] > 5:
char_datas[index]['rarity'] = 3 char_datas[index]['rarity'] = 3
char_datas.sort(key=lambda x: (-x['rarity'], -x['level'], -x['fetter'])) char_datas.sort(key=lambda x: (-x['rarity'], -x['level'], -x['fetter']))
if char_num > 8: if char_num > 8:
tasks = [] tasks = []
for index,i in enumerate(char_datas): for index, i in enumerate(char_datas):
async def draw_char_pic(img: Image, char_data: json, index: int, bg_color :tuple[int, int, int], tasks.append(draw_char_pic(bg_img, i, index, char_color, text_color, bg_detail_color, char_high_color, uid,
text_color: tuple[int, int, int], bg_detail_color: tuple[int, int, int], use_cookies))
char_high_color: tuple[int, int, int]):
char_mingzuo = 0
for k in char_data['constellations']:
if k['is_actived']:
char_mingzuo += 1
if char_data['rarity'] == 5:
char_0 = Image.new("RGBA", (180, 90), char_high_color)
else:
char_0 = Image.new("RGBA", (180, 90), bg_color)
char_0_raw = Image.open(os.path.join(TEXT_PATH, "char_0.png"))
alpha = char_0_raw.getchannel('A')
char_0.putalpha(alpha)
char_2 = Image.new("RGBA", (180, 90), bg_detail_color)
char_2_raw = Image.open(os.path.join(TEXT_PATH, "char_2.png"))
alpha = char_2_raw.getchannel('A')
char_2.putalpha(alpha)
"""
char_3 = Image.new("RGBA", (180, 90), bg_detail_color)
char_3_raw = Image.open(os.path.join(TEXT_PATH, "char_3.png"))
alpha = char_3_raw.getchannel('A')
char_3.putalpha(alpha)
"""
char_1_mask = Image.open(os.path.join(TEXT_PATH, "char_1_mask.png"))
char_talent_data = await get_calculate_info(uid, str(char_data["id"]), use_cookies)
if not os.path.exists(os.path.join(WEAPON_PATH, str(char_data['weapon']['icon'].split('/')[-1]))):
get_weapon_pic(char_data['weapon']['icon'])
if not os.path.exists(os.path.join(CHAR_PATH, str(char_data['id']) + ".png")):
get_char_pic(char_data['id'], char_data['icon'])
char_img = Image.open(os.path.join(CHAR_PATH, str(char_data["id"]) + ".png")).resize((81, 81), Image.ANTIALIAS)
weapon_img = Image.open(os.path.join(WEAPON_PATH, str(char_data['weapon']['icon'].split('/')[-1]))).resize((40, 40), Image.ANTIALIAS)
weapon_1_mask = char_1_mask.resize((40, 40), Image.ANTIALIAS)
char_0_temp = Image.new("RGBA", (180, 90))
char_0_temp.paste(char_img,(8, 5),char_1_mask)
char_0_temp.paste(weapon_img,(70, 45),weapon_1_mask)
char_0.paste(char_0_temp, (0, 0), char_0_temp)
char_0.paste(char_2, (0, 0), char_2)
#char_0.paste(char_3, (0, 0), char_3)
draw_text = ImageDraw.Draw(char_0)
for i in range(0,2):
draw_text.text((106 + 23*i, 17), f'{str(char_talent_data["data"]["skill_list"][i]["level_current"])}', text_color, genshin_font(15),anchor="mm")
if len(char_talent_data["data"]["skill_list"]) == 7 and char_data["name"] != "珊瑚宫心海":
draw_text.text((106 + 23*2, 17), f'{str(char_talent_data["data"]["skill_list"][3]["level_current"])}', text_color, genshin_font(15),anchor="mm")
else:
draw_text.text((106 + 23*2, 17), f'{str(char_talent_data["data"]["skill_list"][2]["level_current"])}', text_color, genshin_font(15),anchor="mm")
draw_text.text((42,77), "Lv.{}".format(str(char_data["level"])), text_color, genshin_font(16),anchor="mm")
draw_text.text((162,38), "{}".format( char_mingzuo), text_color, genshin_font(18),anchor="rm")
draw_text.text((115,57), 'Lv.{}'.format(str(char_data['weapon']['level'])), text_color, genshin_font(18),anchor="lm")
draw_text.text((115,75), '{}'.format(str(char_data['weapon']['affix_level'])), text_color, genshin_font(16),anchor="lm")
if str(char_data["fetter"]) == "10" or str(char_data["name"]) == "旅行者":
draw_text.text((74, 19), "", text_color, genshin_font(14),anchor="mm")
else:
draw_text.text((73, 18), '{}'.format(str(char_data['fetter'])), text_color, genshin_font(16),anchor="mm")
char_crop = (75 + 190 * (index % 4), 800 + 100 * (index // 4))
img.paste(char_0, char_crop, char_0)
tasks.append(draw_char_pic(bg_img, i, index, char_color, text_color, bg_detail_color, char_high_color))
await asyncio.wait(tasks) await asyncio.wait(tasks)
""" """
char_mingzuo = 0 char_mingzuo = 0
@ -1323,9 +1352,9 @@ async def draw_pic(uid: str, nickname: str, image: Optional[str] = None, mode: i
char_stand_img = os.path.join(CHAR_IMG_PATH, str(char_img_icon.split('/')[-1])) char_stand_img = os.path.join(CHAR_IMG_PATH, str(char_img_icon.split('/')[-1]))
char_stand_mask = Image.open(os.path.join(TEXT_PATH, "stand_mask.png")) char_stand_mask = Image.open(os.path.join(TEXT_PATH, "stand_mask.png"))
#char_namecard_img = Image.open(os.path.join(CHAR_NAMECARD_PATH,str(i['icon'].split('_')[-1]))) # char_namecard_img = Image.open(os.path.join(CHAR_NAMECARD_PATH,str(i['icon'].split('_')[-1])))
#char_namecard_img = char_namecard_img.resize((591,81), Image.ANTIALIAS) # char_namecard_img = char_namecard_img.resize((591,81), Image.ANTIALIAS)
#char_namecard_img.putalpha(char_namecard_img.getchannel('A').point(lambda i: i*0.8 if i>0 else 0)) # char_namecard_img.putalpha(char_namecard_img.getchannel('A').point(lambda i: i*0.8 if i>0 else 0))
char_stand = Image.open(char_stand_img) char_stand = Image.open(char_stand_img)
char_img = Image.open(char) char_img = Image.open(char)
char_img = char_img.resize((100, 100), Image.ANTIALIAS) char_img = char_img.resize((100, 100), Image.ANTIALIAS)
@ -1339,7 +1368,7 @@ async def draw_pic(uid: str, nickname: str, image: Optional[str] = None, mode: i
weapon_bg = Image.open(get_text(char_weapon_star, 3)) weapon_bg = Image.open(get_text(char_weapon_star, 3))
charpic_temp.paste(char_stand, (395, -99), char_stand_mask) charpic_temp.paste(char_stand, (395, -99), char_stand_mask)
#charpic_temp.paste(char_namecard_img, (247, 24), char_namecard_img) # charpic_temp.paste(char_namecard_img, (247, 24), char_namecard_img)
charpic.paste(weapon_bg, (72, 10), weapon_bg) charpic.paste(weapon_bg, (72, 10), weapon_bg)
charpic_temp.paste(char_img, (81, 13), charpic_mask) charpic_temp.paste(char_img, (81, 13), charpic_mask)
charpic_temp.paste(char_fg, (0, 0), char_fg) charpic_temp.paste(char_fg, (0, 0), char_fg)
@ -1392,8 +1421,7 @@ async def draw_pic(uid: str, nickname: str, image: Optional[str] = None, mode: i
return resultmes return resultmes
async def draw_info_pic(uid: str,image :Optional[str] = None) -> str: async def draw_info_pic(uid: str, image: Optional[Match] = None) -> str:
def seconds2hours(seconds: int) -> str: def seconds2hours(seconds: int) -> str:
m, s = divmod(int(seconds), 60) m, s = divmod(int(seconds), 60)
h, m = divmod(m, 60) h, m = divmod(m, 60)
@ -1402,11 +1430,11 @@ async def draw_info_pic(uid: str,image :Optional[str] = None) -> str:
# 获取Cookies # 获取Cookies
data_def = get_cookies() data_def = get_cookies()
retcode = await data_def.get_useable_cookies(uid) retcode = await data_def.get_useable_cookies(uid)
if retcode != True: if not retcode:
return retcode return retcode
raw_data = data_def.raw_data raw_data = data_def.raw_data
char_data = raw_data["data"]["avatars"] char_data = raw_data["data"]["avatars"]
#获取数据 # 获取数据
award_data = await get_award(uid) award_data = await get_award(uid)
daily_data = await get_daily_data(uid) daily_data = await get_daily_data(uid)
daily_data = daily_data["data"] daily_data = daily_data["data"]
@ -1415,7 +1443,7 @@ async def draw_info_pic(uid: str,image :Optional[str] = None) -> str:
# 获取背景图片各项参数 # 获取背景图片各项参数
based_w = 900 based_w = 900
based_h = 1380 based_h = 1380
image_def = customize_image(image,based_w,based_h) image_def = customize_image(image, based_w, based_h)
bg_img = image_def.bg_img bg_img = image_def.bg_img
bg_color = image_def.bg_color bg_color = image_def.bg_color
text_color = image_def.text_color text_color = image_def.text_color
@ -1443,7 +1471,7 @@ async def draw_info_pic(uid: str,image :Optional[str] = None) -> str:
info3 = Image.open(info3_path) info3 = Image.open(info3_path)
avatar_bg = Image.open(avatar_bg_path) avatar_bg = Image.open(avatar_bg_path)
avatar_fg = Image.open(avatar_fg_path) avatar_fg = Image.open(avatar_fg_path)
avatar_bg_color = Image.new("RGBA", (316, 100), bg_color) avatar_bg_color = Image.new("RGBA", (316, 100), bg_color)
bg_img.paste(avatar_bg_color, (113, 98), avatar_bg) bg_img.paste(avatar_bg_color, (113, 98), avatar_bg)
bg_img.paste(avatar_fg, (114, 95), avatar_fg) bg_img.paste(avatar_fg, (114, 95), avatar_fg)
@ -1455,111 +1483,130 @@ async def draw_info_pic(uid: str,image :Optional[str] = None) -> str:
bg_img.paste(info2_color, (0, 0), info2) bg_img.paste(info2_color, (0, 0), info2)
bg_img.paste(info3, (0, 0), info3) bg_img.paste(info3, (0, 0), info3)
text_draw = ImageDraw.Draw(bg_img) text_draw = ImageDraw.Draw(bg_img)
#用户信息 # 用户信息
text_draw.text((220, 137), f"{nickname}", text_color, genshin_font(32),anchor="lm") text_draw.text((220, 137), f"{nickname}", text_color, genshin_font(32), anchor="lm")
text_draw.text((235, 170), 'UID ' + f"{uid}", text_color, genshin_font(14),anchor="lm") text_draw.text((235, 170), 'UID ' + f"{uid}", text_color, genshin_font(14), anchor="lm")
#本日原石/摩拉 # 本日原石/摩拉
text_draw.text((675, 148), f"{award_data['data']['day_data']['current_primogems']}/{award_data['data']['day_data']['last_primogems']}", text_color, genshin_font(28),anchor="lm") text_draw.text((675, 148),
text_draw.text((675, 212), f"{award_data['data']['day_data']['current_mora']}\n{award_data['data']['day_data']['last_mora']}", text_color, genshin_font(28),anchor="lm") f"{award_data['data']['day_data']['current_primogems']}/{award_data['data']['day_data']['last_primogems']}",
text_color, genshin_font(28), anchor="lm")
text_draw.text((675, 212),
f"{award_data['data']['day_data']['current_mora']}\n{award_data['data']['day_data']['last_mora']}",
text_color, genshin_font(28), anchor="lm")
#本月/上月原石 # 本月/上月原石
text_draw.text((722, 287), f"{award_data['data']['month_data']['current_primogems']}", text_color, genshin_font(21),anchor="lm") text_draw.text((722, 287), f"{award_data['data']['month_data']['current_primogems']}", text_color, genshin_font(21),
text_draw.text((722, 323), f"{award_data['data']['month_data']['last_primogems']}", text_color, genshin_font(21),anchor="lm") anchor="lm")
text_draw.text((722, 323), f"{award_data['data']['month_data']['last_primogems']}", text_color, genshin_font(21),
anchor="lm")
#本月/上月摩拉 # 本月/上月摩拉
text_draw.text((722, 359), f"{award_data['data']['month_data']['current_mora']}", text_color, genshin_font(21),anchor="lm") text_draw.text((722, 359), f"{award_data['data']['month_data']['current_mora']}", text_color, genshin_font(21),
text_draw.text((722, 395), f"{award_data['data']['month_data']['last_mora']}", text_color, genshin_font(21),anchor="lm") anchor="lm")
text_draw.text((722, 395), f"{award_data['data']['month_data']['last_mora']}", text_color, genshin_font(21),
anchor="lm")
#收入比例 # 收入比例
for index,i in enumerate(award_data['data']['month_data']['group_by']): for index, i in enumerate(award_data['data']['month_data']['group_by']):
text_draw.text((681, 445 + index * 32), f"{str(i['num'])}({str(i['percent'])}%)", text_color, genshin_font(21),anchor="lm") text_draw.text((681, 445 + index * 32), f"{str(i['num'])}({str(i['percent'])}%)", text_color, genshin_font(21),
anchor="lm")
#基本四项 # 基本四项
text_draw.text((390, 314), f"{daily_data['current_resin']}/{daily_data['max_resin']}", text_color, genshin_font(26),anchor="lm") text_draw.text((390, 314), f"{daily_data['current_resin']}/{daily_data['max_resin']}", text_color, genshin_font(26),
text_draw.text((390, 408), f'{daily_data["current_home_coin"]}/{daily_data["max_home_coin"]}', text_color, genshin_font(26),anchor="lm") anchor="lm")
text_draw.text((390, 503), f"{daily_data['finished_task_num']}/{daily_data['total_task_num']}", text_color, genshin_font(26),anchor="lm") text_draw.text((390, 408), f'{daily_data["current_home_coin"]}/{daily_data["max_home_coin"]}', text_color,
text_draw.text((390, 597), f"{str(daily_data['resin_discount_num_limit'] - daily_data['remain_resin_discount_num'])}/{daily_data['resin_discount_num_limit']}", text_color, genshin_font(26),anchor="lm") genshin_font(26), anchor="lm")
text_draw.text((390, 503), f"{daily_data['finished_task_num']}/{daily_data['total_task_num']}", text_color,
genshin_font(26), anchor="lm")
text_draw.text((390, 597),
f"{str(daily_data['resin_discount_num_limit'] - daily_data['remain_resin_discount_num'])}/{daily_data['resin_discount_num_limit']}",
text_color, genshin_font(26), anchor="lm")
#树脂恢复时间计算 # 树脂恢复时间计算
resin_recovery_time = seconds2hours( if int(daily_data['resin_recovery_time']) <= 0:
daily_data['resin_recovery_time']) text_draw.text((170, 331), f"已全部恢复", text_color, genshin_font(18), anchor="lm")
next_resin_rec_time = seconds2hours( else:
8 * 60 - ((daily_data['max_resin'] - daily_data['current_resin']) * 8 * 60 - int( resin_recovery_time = seconds2hours(
daily_data['resin_recovery_time']))) daily_data['resin_recovery_time'])
text_draw.text((268, 305), f" {next_resin_rec_time}", text_color, genshin_font(18),anchor="lm") next_resin_rec_time = seconds2hours(
8 * 60 - ((daily_data['max_resin'] - daily_data['current_resin']) * 8 * 60 - int(
daily_data['resin_recovery_time'])))
text_draw.text((268, 305), f" {next_resin_rec_time}", text_color, genshin_font(18), anchor="lm")
text_draw.text((170, 331), f"预计 后全部恢复", text_color, genshin_font(18),anchor="lm") text_draw.text((170, 331), f"预计 后全部恢复", text_color, genshin_font(18), anchor="lm")
text_draw.text((208, 331), f"{resin_recovery_time}", highlight_color, genshin_font(18),anchor="lm") text_draw.text((208, 331), f"{resin_recovery_time}", highlight_color, genshin_font(18), anchor="lm")
#洞天宝钱时间计算 # 洞天宝钱时间计算
coin_rec_time = seconds2hours(int(daily_data["home_coin_recovery_time"])) coin_rec_time = seconds2hours(int(daily_data["home_coin_recovery_time"]))
if daily_data["home_coin_recovery_time"] == "0": if int(daily_data["home_coin_recovery_time"]) <= 0:
text_draw.text((170, 425), f"", text_color, genshin_font(18),anchor="lm") text_draw.text((170, 425), f"达到上限", text_color, genshin_font(18), anchor="lm")
else: else:
coin_add_speed = math.ceil((daily_data["max_home_coin"] - daily_data["current_home_coin"]) / ( coin_add_speed = math.ceil((daily_data["max_home_coin"] - daily_data["current_home_coin"]) / (
int(daily_data["home_coin_recovery_time"]) / 60 / 60)) int(daily_data["home_coin_recovery_time"]) / 60 / 60))
text_draw.text((270, 399), f"{coin_add_speed}/h", text_color, genshin_font(18),anchor="lm") text_draw.text((270, 399), f"{coin_add_speed}/h", text_color, genshin_font(18), anchor="lm")
text_draw.text((170, 425), f"预计 后达到上限", text_color, genshin_font(18),anchor="lm") text_draw.text((170, 425), f"预计 后达到上限", text_color, genshin_font(18), anchor="lm")
text_draw.text((208, 425), f"{coin_rec_time}", highlight_color, genshin_font(18),anchor="lm") text_draw.text((208, 425), f"{coin_rec_time}", highlight_color, genshin_font(18), anchor="lm")
if daily_data['is_extra_task_reward_received']: if daily_data['is_extra_task_reward_received']:
daily_task_status = "「每日委托」奖励已领取" daily_task_status = "「每日委托」奖励已领取"
else: else:
daily_task_status = "「每日委托」奖励未领取" daily_task_status = "「每日委托」奖励未领取"
#详细信息 # 详细信息
text_draw.text((170, 518), f"{daily_task_status}", text_color, genshin_font(18),anchor="lm") text_draw.text((170, 518), f"{daily_task_status}", text_color, genshin_font(18), anchor="lm")
text_draw.text((170, 614), f"本周剩余消耗减半次数", text_color, genshin_font(18),anchor="lm") text_draw.text((170, 614), f"本周剩余消耗减半次数", text_color, genshin_font(18), anchor="lm")
#派遣图片准备 # 派遣图片准备
char_bg_path = os.path.join(TEXT_PATH, "char_bg.png") char_bg_path = os.path.join(TEXT_PATH, "char_bg.png")
char_bg = Image.open(char_bg_path) char_bg = Image.open(char_bg_path)
charset_mask = Image.new("RGBA", (900, 130), char_color) charset_mask = Image.new("RGBA", (900, 130), char_color)
#派遣 # 派遣
for index,i in enumerate(daily_data["expeditions"]): for index, i in enumerate(daily_data["expeditions"]):
name = ''
for j in char_data: for j in char_data:
if i["avatar_side_icon"].split("_")[-1] == j["image"].split("_")[-1]: if i["avatar_side_icon"].split("_")[-1] == j["image"].split("_")[-1]:
name = j["name"] name = j["name"]
if not os.path.exists(os.path.join(CHAR_IMG_PATH, f"UI_AvatarIcon_{i['avatar_side_icon'].split('_')[-1][:-4]}@2x.png")): if not os.path.exists(
get_char_img_pic(f"https://upload-bbs.mihoyo.com/game_record/genshin/character_image/UI_AvatarIcon_{i['avatar_side_icon'].split('_')[-1][:-4]}@2x.png") os.path.join(CHAR_IMG_PATH, f"UI_AvatarIcon_{i['avatar_side_icon'].split('_')[-1][:-4]}@2x.png")):
#char_stand_img = os.path.join(CHAR_IMG_PATH, f"UI_AvatarIcon_{i['avatar_side_icon'].split('_')[-1][:-4]}@2x.png") get_char_img_pic(
#char_stand = Image.open(char_stand_img) f"https://upload-bbs.mihoyo.com/game_record/genshin/character_image/UI_AvatarIcon_{i['avatar_side_icon'].split('_')[-1][:-4]}@2x.png")
#char_stand_mask = Image.open(os.path.join(TEXT_PATH, "stand_mask.png")) # char_stand_img = os.path.join(CHAR_IMG_PATH, f"UI_AvatarIcon_{i['avatar_side_icon'].split('_')[-1][:-4]}@2x.png")
# char_stand = Image.open(char_stand_img)
# char_stand_mask = Image.open(os.path.join(TEXT_PATH, "stand_mask.png"))
#charpic_temp = Image.new("RGBA", (900, 130)) # charpic_temp = Image.new("RGBA", (900, 130))
#charpic_temp.paste(char_stand, (395, -99), char_stand_mask) # charpic_temp.paste(char_stand, (395, -99), char_stand_mask)
charpic = Image.new("RGBA", (900, 130)) charpic = Image.new("RGBA", (900, 130))
char_icon = Image.open(BytesIO(get(i['avatar_side_icon']).content)) char_icon = Image.open(BytesIO(get(i['avatar_side_icon']).content))
char_namecard_img = Image.open(os.path.join(CHAR_NAMECARD_PATH,str(name + ".png"))) char_namecard_img = Image.open(os.path.join(CHAR_NAMECARD_PATH, str(name + ".png")))
char_namecard_img = char_namecard_img.resize((591,81), Image.ANTIALIAS) char_namecard_img = char_namecard_img.resize((591, 81), Image.ANTIALIAS)
char_namecard_img.putalpha(char_namecard_img.getchannel('A').point(lambda i: i*0.8 if i>0 else 0)) char_namecard_img.putalpha(char_namecard_img.getchannel('A').point(lambda x: round(x * 0.8) if x > 0 else 0))
char_icon_scale = char_icon.resize((140,140),Image.ANTIALIAS) char_icon_scale = char_icon.resize((140, 140), Image.ANTIALIAS)
charpic.paste(charset_mask, (0, 0), char_bg) charpic.paste(charset_mask, (0, 0), char_bg)
charpic.paste(char_icon_scale, (63, -26), char_icon_scale) charpic.paste(char_icon_scale, (63, -26), char_icon_scale)
charpic.paste(char_namecard_img, (247, 24), char_namecard_img) charpic.paste(char_namecard_img, (247, 24), char_namecard_img)
charpic_draw = ImageDraw.Draw(charpic) charpic_draw = ImageDraw.Draw(charpic)
if i['status'] == 'Finished': if i['status'] == 'Finished':
charpic_draw.text((200, 65), f"探索完成", text_color, genshin_font(24),anchor="lm") charpic_draw.text((200, 65), f"探索完成", text_color, genshin_font(24), anchor="lm")
else: else:
remained_timed: str = seconds2hours(i['remained_time']) remained_timed: str = seconds2hours(i['remained_time'])
charpic_draw.text((200, 65), f"剩余时间 {remained_timed}", text_color, genshin_font(24),anchor="lm") charpic_draw.text((200, 65), f"剩余时间 {remained_timed}", text_color, genshin_font(24), anchor="lm")
bg_img.paste(charpic, (-15,748 + 115*index), charpic) bg_img.paste(charpic, (-15, 748 + 115 * index), charpic)
end_pic = Image.open(os.path.join(TEXT_PATH,"abyss_3.png")) end_pic = Image.open(os.path.join(TEXT_PATH, "abyss_3.png"))
bg_img.paste(end_pic,(0,1340),end_pic) bg_img.paste(end_pic, (0, 1340), end_pic)
bg_img = bg_img.convert('RGB') bg_img = bg_img.convert('RGB')
result_buffer = BytesIO() result_buffer = BytesIO()
@ -1568,6 +1615,7 @@ async def draw_info_pic(uid: str,image :Optional[str] = None) -> str:
resultmes = imgmes resultmes = imgmes
return resultmes return resultmes
async def draw_event_pic() -> None: async def draw_event_pic() -> None:
raw_data = await get_genshin_events("List") raw_data = await get_genshin_events("List")
raw_time_data = await get_genshin_events("Content") raw_time_data = await get_genshin_events("Content")
@ -1654,4 +1702,4 @@ async def draw_event_pic() -> None:
base_img = base_img.convert('RGB') base_img = base_img.convert('RGB')
base_img.save(os.path.join(FILE2_PATH, 'event.jpg'), format='JPEG', subsampling=0, quality=90) base_img.save(os.path.join(FILE2_PATH, 'event.jpg'), format='JPEG', subsampling=0, quality=90)
return return

View File

@ -1,15 +1,10 @@
import json
import math import math
import os import os
import sys import sys
import random
import re
import sqlite3
from base64 import b64encode from base64 import b64encode
from openpyxl import load_workbook
from io import BytesIO from io import BytesIO
import requests from openpyxl import load_workbook
sys.path.append(os.path.dirname(os.path.abspath(__file__))) sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from .get_data import * from .get_data import *
@ -17,7 +12,7 @@ from .get_image import draw_event_pic
import get_mihoyo_bbs_coin as coin import get_mihoyo_bbs_coin as coin
FILE_PATH = os.path.dirname(__file__) FILE_PATH = os.path.dirname(__file__)
FILE2_PATH = os.path.join(FILE_PATH, 'mihoyo_bbs') FILE2_PATH = os.path.join(FILE_PATH, 'mihoyo_libs/mihoyo_bbs')
INDEX_PATH = os.path.join(FILE2_PATH, 'index') INDEX_PATH = os.path.join(FILE2_PATH, 'index')
Texture_PATH = os.path.join(FILE2_PATH, 'texture2d') Texture_PATH = os.path.join(FILE2_PATH, 'texture2d')
@ -160,6 +155,7 @@ char_adv_im = '''【{}】
圣遗物 圣遗物
{}''' {}'''
async def weapon_adv(name): async def weapon_adv(name):
char_adv_path = os.path.join(FILE_PATH, "mihoyo_libs/Genshin All Char.xlsx") char_adv_path = os.path.join(FILE_PATH, "mihoyo_libs/Genshin All Char.xlsx")
wb = load_workbook(char_adv_path) wb = load_workbook(char_adv_path)
@ -182,6 +178,7 @@ async def weapon_adv(name):
im = "没有角色能使用【{}".format(weapon_name) im = "没有角色能使用【{}".format(weapon_name)
return im return im
async def char_adv(name): async def char_adv(name):
char_name = None char_name = None
char_adv_path = os.path.join(FILE_PATH, "mihoyo_libs/Genshin All Char.xlsx") char_adv_path = os.path.join(FILE_PATH, "mihoyo_libs/Genshin All Char.xlsx")
@ -192,7 +189,7 @@ async def char_adv(name):
for i in char_list: for i in char_list:
if i.value: if i.value:
if all(g in i.value for g in name): if all(g in i.value for g in name):
#if name in i.value: # if name in i.value:
index = i.row index = i.row
char_name = i.value char_name = i.value
if index: if index:
@ -204,7 +201,7 @@ async def char_adv(name):
weapon_5star = weapon_5star[:-1] weapon_5star = weapon_5star[:-1]
else: else:
weapon_5star = "无推荐" weapon_5star = "无推荐"
weapon_4star = "" weapon_4star = ""
for i in range(index, index + 5): for i in range(index, index + 5):
if ws.cell(i, 3).value: if ws.cell(i, 3).value:
@ -213,7 +210,7 @@ async def char_adv(name):
weapon_4star = weapon_4star[:-1] weapon_4star = weapon_4star[:-1]
else: else:
weapon_4star = "无推荐" weapon_4star = "无推荐"
weapon_3star = "" weapon_3star = ""
for i in range(index, index + 5): for i in range(index, index + 5):
if ws.cell(i, 4).value: if ws.cell(i, 4).value:
@ -239,6 +236,7 @@ async def char_adv(name):
im = char_adv_im.format(char_name, weapon_5star, weapon_4star, weapon_3star, artifacts) im = char_adv_im.format(char_name, weapon_5star, weapon_4star, weapon_3star, artifacts)
return im return im
async def deal_ck(mes, qid): async def deal_ck(mes, qid):
if "stoken" in mes: if "stoken" in mes:
login_ticket = re.search(r"login_ticket=([0-9a-zA-Z]+)", mes).group(0).split('=')[1] login_ticket = re.search(r"login_ticket=([0-9a-zA-Z]+)", mes).group(0).split('=')[1]
@ -276,7 +274,8 @@ async def deal_ck(mes, qid):
await cookies_db(uid, cookie, qid) await cookies_db(uid, cookie, qid)
return f'添加Cookies成功\nCookies属于个人重要信息如果你是在不知情的情况下添加请马上修改米游社账户密码保护个人隐私\n————\n' \ return f'添加Cookies成功\nCookies属于个人重要信息如果你是在不知情的情况下添加请马上修改米游社账户密码保护个人隐私\n————\n' \
f'如果需要【开启自动签到】和【开启推送】还需要在【群聊中】使用命令“绑定uid”绑定你的uid。\n例如绑定uid123456789。' f'如果需要【开启自动签到】和【开启推送】还需要在【群聊中】使用命令“绑定uid”绑定你的uid。\n例如绑定uid123456789。'
async def award(uid): async def award(uid):
data = await get_award(uid) data = await get_award(uid)
@ -422,6 +421,7 @@ async def daily(mode="push", uid=None):
temp_list = [] temp_list = []
conn = sqlite3.connect('ID_DATA.db') conn = sqlite3.connect('ID_DATA.db')
c = conn.cursor() c = conn.cursor()
c_data = None
if mode == "push": if mode == "push":
cursor = c.execute( cursor = c.execute(
"SELECT * FROM NewCookiesTable WHERE StatusA != ?", ("off",)) "SELECT * FROM NewCookiesTable WHERE StatusA != ?", ("off",))
@ -509,7 +509,8 @@ async def daily(mode="push", uid=None):
{"qid": row[2], "gid": row[3], "message": send_mes}) {"qid": row[2], "gid": row[3], "message": send_mes})
return temp_list return temp_list
async def mihoyo_coin(qid,s_cookies = None):
async def mihoyo_coin(qid, s_cookies=None):
uid = await select_db(qid, mode="uid") uid = await select_db(qid, mode="uid")
uid = uid[0] uid = uid[0]
if s_cookies is None: if s_cookies is None:
@ -522,6 +523,7 @@ async def mihoyo_coin(qid,s_cookies = None):
im = "你还没有绑定Stoken~" im = "你还没有绑定Stoken~"
return im return im
async def get_event_pic(): async def get_event_pic():
img_path = os.path.join(FILE2_PATH, "event.jpg") img_path = os.path.join(FILE2_PATH, "event.jpg")
while True: while True:
@ -535,6 +537,7 @@ async def get_event_pic():
await draw_event_pic() await draw_event_pic()
return img_mes return img_mes
async def weapon_wiki(name, level=None): async def weapon_wiki(name, level=None):
data = await get_weapon_info(name) data = await get_weapon_info(name)
if "errcode" in data: if "errcode" in data:
@ -581,6 +584,7 @@ async def weapon_wiki(name, level=None):
async def char_wiki(name, mode="char", level=None): async def char_wiki(name, mode="char", level=None):
im = ''
data = await get_char_info(name, mode, level if mode == "char" else None) data = await get_char_info(name, mode, level if mode == "char" else None)
if mode == "char": if mode == "char":
if isinstance(data, list): if isinstance(data, list):
@ -744,4 +748,4 @@ async def char_wiki(name, mode="char", level=None):
im = "{}\n{}".format(skill_name, skill_info) im = "{}\n{}".format(skill_name, skill_info)
else: else:
im = "不存在该天赋。" im = "不存在该天赋。"
return im return im