🎨 修复BUG, 调整样式 (#497)
@ -3,8 +3,9 @@ from typing import Dict, Tuple, Union, Literal
|
||||
|
||||
from PIL import Image, ImageDraw
|
||||
from gsuid_core.utils.api.mys.models import IndexData
|
||||
from gsuid_core.utils.error_reply import get_error_img
|
||||
|
||||
from ..utils.convert import GsCookie
|
||||
from ..utils.mys_api import mys_api
|
||||
from ..utils.image.convert import convert_img
|
||||
from ..utils.map.GS_MAP_PATH import avatarId2Name
|
||||
from ..utils.fonts.genshin_fonts import gs_font_30, gs_font_40
|
||||
@ -65,23 +66,19 @@ async def draw_explora_img(
|
||||
return await draw_base_img(qid, uid, '探索')
|
||||
|
||||
|
||||
async def get_base_data(uid: str) -> Union[str, IndexData]:
|
||||
async def get_base_data(uid: str) -> Union[bytes, str, IndexData]:
|
||||
# 获取Cookies
|
||||
data_def = GsCookie()
|
||||
retcode = await data_def.get_cookie(uid)
|
||||
if retcode:
|
||||
return retcode
|
||||
raw_data = data_def.raw_data
|
||||
if raw_data is None:
|
||||
return '数据异常!'
|
||||
raw_data = await mys_api.get_info(uid, None)
|
||||
if isinstance(raw_data, int):
|
||||
return await get_error_img(raw_data)
|
||||
return raw_data
|
||||
|
||||
|
||||
async def get_explore_data(
|
||||
uid: str,
|
||||
) -> Union[str, Tuple[Dict[str, float], Dict[str, str], str, str, str]]:
|
||||
) -> Union[bytes, str, Tuple[Dict[str, float], Dict[str, str], str, str, str]]:
|
||||
raw_data = await get_base_data(uid)
|
||||
if isinstance(raw_data, str):
|
||||
if isinstance(raw_data, str) or isinstance(raw_data, bytes):
|
||||
return raw_data
|
||||
|
||||
# 处理数据
|
||||
@ -125,9 +122,9 @@ async def get_explore_data(
|
||||
|
||||
async def get_collection_data(
|
||||
uid: str,
|
||||
) -> Union[str, Tuple[Dict[str, float], Dict[str, str], str, str, str]]:
|
||||
) -> Union[bytes, str, Tuple[Dict[str, float], Dict[str, str], str, str, str]]:
|
||||
raw_data = await get_base_data(uid)
|
||||
if isinstance(raw_data, str):
|
||||
if isinstance(raw_data, str) or isinstance(raw_data, bytes):
|
||||
return raw_data
|
||||
raw_data = raw_data['stats']
|
||||
|
||||
@ -172,8 +169,10 @@ async def draw_base_img(
|
||||
data = await get_collection_data(uid)
|
||||
else:
|
||||
data = await get_explore_data(uid)
|
||||
if isinstance(data, str):
|
||||
|
||||
if isinstance(data, str) or isinstance(data, bytes):
|
||||
return data
|
||||
|
||||
percent_data, value_data = data[0], data[1]
|
||||
|
||||
# 获取背景图片各项参数
|
||||
|
@ -13,6 +13,8 @@ from gsuid_core.utils.error_reply import UID_HINT
|
||||
from .to_data import switch_api
|
||||
from .to_card import enka_to_card
|
||||
from ..utils.convert import get_uid
|
||||
from .start import refresh_player_list
|
||||
from .draw_artifacts_lib import draw_lib
|
||||
from ..utils.image.convert import convert_img
|
||||
from ..utils.map.GS_MAP_PATH import alias_data
|
||||
from .draw_char_rank import draw_cahrcard_list
|
||||
@ -24,6 +26,28 @@ sv_get_enka = SV('面板查询', priority=10)
|
||||
sv_get_original_pic = SV('查看面板原图', priority=5)
|
||||
|
||||
|
||||
@sv_get_enka.on_fullmatch('刷新圣遗物仓库')
|
||||
async def sned_fresh_list(bot: Bot, ev: Event):
|
||||
# 获取uid
|
||||
uid = await get_uid(bot, ev)
|
||||
if uid is None:
|
||||
return await bot.send(UID_HINT)
|
||||
logger.info(f'[刷新圣遗物仓库]uid: {uid}')
|
||||
|
||||
await bot.send(await refresh_player_list(uid))
|
||||
|
||||
|
||||
@sv_get_enka.on_fullmatch('圣遗物仓库')
|
||||
async def sned_aritifacts_list(bot: Bot, ev: Event):
|
||||
# 获取uid
|
||||
uid = await get_uid(bot, ev)
|
||||
if uid is None:
|
||||
return await bot.send(UID_HINT)
|
||||
logger.info(f'[圣遗物仓库]uid: {uid}')
|
||||
|
||||
await bot.send(await draw_lib(ev.user_id, uid))
|
||||
|
||||
|
||||
@sv_get_original_pic.on_fullmatch(('原图'))
|
||||
async def sned_original_pic(bot: Bot, ev: Event):
|
||||
if ev.reply:
|
||||
|
62
GenshinUID/genshinuid_enka/draw_artifacts_lib.py
Normal file
@ -0,0 +1,62 @@
|
||||
import json
|
||||
from typing import Dict, Union, Optional
|
||||
|
||||
import aiofiles
|
||||
from PIL import Image, ImageDraw
|
||||
|
||||
from .etc.etc import TEXT_PATH
|
||||
from .start import refresh_player_list
|
||||
from ..utils.image.convert import convert_img
|
||||
from .draw_normal import _get_single_artifact_img
|
||||
from ..utils.fonts.genshin_fonts import gs_font_36
|
||||
from ..utils.resource.RESOURCE_PATH import PLAYER_PATH
|
||||
from ..utils.image.image_tools import get_qq_avatar, draw_pic_with_ring
|
||||
|
||||
|
||||
async def get_artifacts_lib_data(uid: str) -> Optional[Dict]:
|
||||
path = PLAYER_PATH / uid / 'artifacts.json'
|
||||
data = None
|
||||
if not path.exists():
|
||||
await refresh_player_list(uid)
|
||||
|
||||
if path.exists():
|
||||
async with aiofiles.open(path, 'rb') as file:
|
||||
data = json.loads(await file.read())
|
||||
all_list = [x for v in data['data'].values() for x in v]
|
||||
|
||||
if len(all_list) == 0:
|
||||
return None
|
||||
elif 'cv_score' not in all_list[0]:
|
||||
path.unlink()
|
||||
await refresh_player_list(uid)
|
||||
async with aiofiles.open(path, 'rb') as file:
|
||||
data = json.loads(await file.read())
|
||||
|
||||
return data
|
||||
|
||||
|
||||
async def draw_lib(user_id: str, uid: str) -> Union[bytes, str]:
|
||||
data = await get_artifacts_lib_data(uid)
|
||||
if data is None:
|
||||
return '你还没有圣遗物数据...请尝试使用[强制刷新]获取数据!'
|
||||
|
||||
all_list = [x for v in data['data'].values() for x in v]
|
||||
all_list.sort(key=lambda x: x['cv_score'], reverse=True)
|
||||
|
||||
lst = all_list[:20]
|
||||
|
||||
bg = Image.open(TEXT_PATH / 'artifacts_lib_bg.png')
|
||||
avatar = await get_qq_avatar(user_id)
|
||||
avatar_img = await draw_pic_with_ring(avatar, 280)
|
||||
|
||||
bg.paste(avatar_img, (115, 88), avatar_img)
|
||||
|
||||
for index, artifact in enumerate(lst):
|
||||
img = await _get_single_artifact_img(artifact)
|
||||
bg.paste(img, (24 + (index % 4) * 310, 570 + (index // 4) * 360), img)
|
||||
|
||||
bg_draw = ImageDraw.Draw(bg)
|
||||
bg_draw.text((268, 498), f'UID {uid}', 'white', gs_font_36, 'mm')
|
||||
all_black = Image.new('RGBA', bg.size, (0, 0, 0))
|
||||
bg = Image.alpha_composite(all_black, bg)
|
||||
return await convert_img(bg)
|
@ -39,7 +39,7 @@ async def draw_char_card(
|
||||
char_info_2 = Image.open(TEXT_PATH / 'char_info_2.png')
|
||||
img.paste(char_info_1, (0, 0), char_info_1)
|
||||
img.paste(char_info_2, (0, 1085), char_info_2)
|
||||
img.paste(dmg_img, (0, 1850), dmg_img)
|
||||
img.paste(dmg_img, (0, 1820), dmg_img)
|
||||
await get_artifacts_card(char, img)
|
||||
img_text = ImageDraw.Draw(img)
|
||||
artifacts_all_score = await get_all_artifacts_value(
|
||||
@ -51,29 +51,37 @@ async def draw_char_card(
|
||||
percent_str = f'{char.percent}%'
|
||||
# 角色评分
|
||||
img_text.text(
|
||||
(768, 1564),
|
||||
(783, 1570),
|
||||
f'{round(artifacts_all_score, 1)}',
|
||||
(255, 255, 255),
|
||||
gs_font_50,
|
||||
anchor='mm',
|
||||
)
|
||||
img_text.text(
|
||||
(768, 1726),
|
||||
(783, 1730),
|
||||
percent_str,
|
||||
(255, 255, 255),
|
||||
gs_font_50,
|
||||
anchor='mm',
|
||||
)
|
||||
img_text.text(
|
||||
(768, 1673),
|
||||
(783, 1676),
|
||||
f'{char.seq_str}',
|
||||
(255, 255, 255),
|
||||
gs_font_18,
|
||||
anchor='mm',
|
||||
)
|
||||
'''
|
||||
res = await convert_img(img)
|
||||
if isinstance(res, str):
|
||||
res = b''
|
||||
'''
|
||||
|
||||
img_text.text(
|
||||
(475, img.size[1] - 35),
|
||||
'Power by Wuyi & '
|
||||
'Data by Enka.network & '
|
||||
'Created by GsCore & GenshinUID',
|
||||
(200, 200, 200),
|
||||
gs_font_18,
|
||||
anchor='mm',
|
||||
)
|
||||
|
||||
black = Image.new('RGBA', img.size, (0, 0, 0))
|
||||
img = Image.alpha_composite(black, img)
|
||||
return img
|
||||
|
@ -1,7 +1,7 @@
|
||||
import math
|
||||
import random
|
||||
from io import BytesIO
|
||||
from typing import Optional
|
||||
from typing import Dict, Optional
|
||||
|
||||
import aiofiles
|
||||
from httpx import get
|
||||
@ -26,11 +26,11 @@ from ..utils.resource.RESOURCE_PATH import (
|
||||
)
|
||||
|
||||
ARTIFACTS_POS = {
|
||||
'生之花': (18, 1075),
|
||||
'死之羽': (318, 1075),
|
||||
'时之沙': (618, 1075),
|
||||
'空之杯': (18, 1447),
|
||||
'理之冠': (318, 1447),
|
||||
'生之花': (13, 1087),
|
||||
'死之羽': (323, 1087),
|
||||
'时之沙': (633, 1087),
|
||||
'空之杯': (13, 1447),
|
||||
'理之冠': (323, 1447),
|
||||
}
|
||||
PIC_API = gsconfig.get_config('random_pic_API').data
|
||||
|
||||
@ -110,14 +110,14 @@ async def get_char_card_base(char: Character) -> Image.Image:
|
||||
anchor='lm',
|
||||
)
|
||||
char_info_text.text(
|
||||
(412, 710),
|
||||
(420, 710),
|
||||
weapon_type,
|
||||
(255, 255, 255),
|
||||
genshin_font_origin(20),
|
||||
anchor='lm',
|
||||
)
|
||||
char_info_text.text(
|
||||
(412, 750),
|
||||
(420, 750),
|
||||
'基础攻击力',
|
||||
(255, 255, 255),
|
||||
genshin_font_origin(32),
|
||||
@ -136,7 +136,7 @@ async def get_char_card_base(char: Character) -> Image.Image:
|
||||
'statValue'
|
||||
]
|
||||
char_info_text.text(
|
||||
(412, 801),
|
||||
(420, 801),
|
||||
weapon_sub_info,
|
||||
(255, 255, 255),
|
||||
genshin_font_origin(32),
|
||||
@ -151,7 +151,7 @@ async def get_char_card_base(char: Character) -> Image.Image:
|
||||
)
|
||||
else:
|
||||
char_info_text.text(
|
||||
(412, 801),
|
||||
(420, 801),
|
||||
'该武器无副词条',
|
||||
(255, 255, 255),
|
||||
genshin_font_origin(32),
|
||||
@ -222,25 +222,25 @@ async def get_char_card_base(char: Character) -> Image.Image:
|
||||
anchor='lm',
|
||||
)
|
||||
char_info_text.text(
|
||||
(103, 812),
|
||||
f'{str(a_skill_level)}',
|
||||
(103, 820),
|
||||
f'{a_skill_level}',
|
||||
(255, 255, 255),
|
||||
genshin_font_origin(30),
|
||||
genshin_font_origin(22),
|
||||
anchor='mm',
|
||||
)
|
||||
char_info_text.text(
|
||||
(103, 915),
|
||||
f'{str(e_skill_level)}',
|
||||
(103, 923),
|
||||
f'{e_skill_level}',
|
||||
(255, 255, 255),
|
||||
genshin_font_origin(30),
|
||||
genshin_font_origin(22),
|
||||
anchor='mm',
|
||||
)
|
||||
|
||||
char_info_text.text(
|
||||
(103, 1016),
|
||||
f'{str(q_skill_level)}',
|
||||
(103, 1024),
|
||||
f'{q_skill_level}',
|
||||
(255, 255, 255),
|
||||
genshin_font_origin(30),
|
||||
genshin_font_origin(22),
|
||||
anchor='mm',
|
||||
)
|
||||
|
||||
@ -446,154 +446,227 @@ async def get_char_img(
|
||||
return char_result
|
||||
|
||||
|
||||
async def _get_single_artifact_img(aritifact: Dict) -> Image.Image:
|
||||
'''
|
||||
注意这里的aritifact不是原始的数据, 是带了评分的数据
|
||||
'''
|
||||
artifactimg_bg = Image.open(TEXT_PATH / 'char_info_artifacts_bg.png')
|
||||
artifacts_img = Image.open(TEXT_PATH / 'char_info_artifacts.png')
|
||||
artifacts_piece_img = Image.open(
|
||||
REL_PATH / '{}.png'.format(aritifact['aritifactName'])
|
||||
)
|
||||
artifacts_piece_new_img = artifacts_piece_img.resize(
|
||||
(90, 90), Image.Resampling.LANCZOS
|
||||
).convert('RGBA')
|
||||
|
||||
artifacts_img.paste(
|
||||
artifacts_piece_new_img, (26, 32), artifacts_piece_new_img
|
||||
)
|
||||
aritifactStar_img = get_star_png(aritifact['aritifactStar'])
|
||||
aritifactStar_img = aritifactStar_img.resize((90, 23))
|
||||
|
||||
# 圣遗物星星和名称&位置
|
||||
artifacts_img.paste(aritifactStar_img, (121, 63), aritifactStar_img)
|
||||
artifacts_text = ImageDraw.Draw(artifacts_img)
|
||||
if len(aritifact['aritifactName']) <= 8:
|
||||
main_name = aritifact['aritifactName']
|
||||
else:
|
||||
main_name = (
|
||||
aritifact['aritifactName'][:4] + aritifact['aritifactName'][4:]
|
||||
)
|
||||
artifacts_text.text(
|
||||
(124, 51),
|
||||
main_name,
|
||||
(255, 255, 255),
|
||||
genshin_font_origin(22),
|
||||
anchor='lm',
|
||||
)
|
||||
'''
|
||||
artifacts_text.text(
|
||||
(30, 102),
|
||||
artifactsPos,
|
||||
(255, 255, 255),
|
||||
genshin_font_origin(20),
|
||||
anchor='lm',
|
||||
)
|
||||
'''
|
||||
|
||||
mainValue: float = aritifact['reliquaryMainstat']['statValue']
|
||||
mainName: str = aritifact['reliquaryMainstat']['statName']
|
||||
mainLevel: int = aritifact['aritifactLevel']
|
||||
|
||||
if mainName in ['攻击力', '血量', '防御力', '元素精通']:
|
||||
mainValueStr = str(mainValue)
|
||||
else:
|
||||
mainValueStr = str(mainValue) + '%'
|
||||
|
||||
mainNameNew = (
|
||||
mainName.replace('百分比', '')
|
||||
.replace('伤害加成', '伤加成')
|
||||
.replace('元素', '')
|
||||
.replace('理', '')
|
||||
)
|
||||
|
||||
artifacts_text.text(
|
||||
(38, 150),
|
||||
mainNameNew,
|
||||
(255, 255, 255),
|
||||
genshin_font_origin(28),
|
||||
anchor='lm',
|
||||
)
|
||||
artifacts_text.text(
|
||||
(271, 150),
|
||||
mainValueStr,
|
||||
(255, 255, 255),
|
||||
genshin_font_origin(28),
|
||||
anchor='rm',
|
||||
)
|
||||
artifacts_text.text(
|
||||
(232, 75),
|
||||
f'+{mainLevel}',
|
||||
(255, 255, 255),
|
||||
genshin_font_origin(16),
|
||||
anchor='mm',
|
||||
)
|
||||
|
||||
for index, i in enumerate(aritifact['reliquarySubstats']):
|
||||
subName: str = i['statName']
|
||||
subValue: float = i['statValue']
|
||||
if subName in ['攻击力', '血量', '防御力', '元素精通']:
|
||||
subValueStr = str(subValue)
|
||||
else:
|
||||
subValueStr = str(subValue) + '%'
|
||||
value_temp = i['value_score']
|
||||
subNameStr = subName.replace('百分比', '').replace('元素', '')
|
||||
# 副词条文字颜色
|
||||
if value_temp == 0:
|
||||
artifacts_color = (120, 120, 120)
|
||||
else:
|
||||
artifacts_color = (255, 255, 255)
|
||||
|
||||
# 副词条底色
|
||||
if value_temp >= 3.4:
|
||||
artifacts_bg = (205, 135, 76)
|
||||
if value_temp >= 4.5:
|
||||
artifacts_bg = (158, 39, 39)
|
||||
artifacts_text.rounded_rectangle(
|
||||
(25, 184 + index * 35, 283, 213 + index * 35),
|
||||
fill=artifacts_bg,
|
||||
radius=8,
|
||||
)
|
||||
|
||||
artifacts_text.text(
|
||||
(22, 200 + index * 35),
|
||||
'·{}'.format(subNameStr),
|
||||
artifacts_color,
|
||||
genshin_font_origin(25),
|
||||
anchor='lm',
|
||||
)
|
||||
artifacts_text.text(
|
||||
(266, 200 + index * 35),
|
||||
'{}'.format(subValueStr),
|
||||
artifacts_color,
|
||||
genshin_font_origin(25),
|
||||
anchor='rm',
|
||||
)
|
||||
artifactsScore = aritifact['value_score']
|
||||
cv_score = aritifact['cv_score']
|
||||
|
||||
if artifactsScore >= 8.4:
|
||||
artifactsScore_color = (158, 39, 39)
|
||||
elif artifactsScore >= 6.5:
|
||||
artifactsScore_color = (205, 135, 76)
|
||||
elif artifactsScore >= 5.2:
|
||||
artifactsScore_color = (143, 123, 174)
|
||||
else:
|
||||
artifactsScore_color = (94, 96, 95)
|
||||
|
||||
if cv_score >= 50:
|
||||
cv_color = (158, 39, 39)
|
||||
elif cv_score >= 45:
|
||||
cv_color = (205, 135, 76)
|
||||
elif cv_score >= 39:
|
||||
cv_color = (143, 123, 174)
|
||||
else:
|
||||
cv_color = (94, 96, 95)
|
||||
|
||||
artifacts_text.rounded_rectangle(
|
||||
(121, 99, 193, 119), fill=artifactsScore_color, radius=8
|
||||
)
|
||||
artifacts_text.rounded_rectangle(
|
||||
(200, 99, 272, 119), fill=cv_color, radius=8
|
||||
)
|
||||
|
||||
artifacts_text.text(
|
||||
(156, 109),
|
||||
'{:.2f}'.format(artifactsScore) + '条',
|
||||
(255, 255, 255),
|
||||
genshin_font_origin(18),
|
||||
anchor='mm',
|
||||
)
|
||||
|
||||
artifacts_text.text(
|
||||
(235, 109),
|
||||
'{:.1f}'.format(cv_score) + '分',
|
||||
(255, 255, 255),
|
||||
genshin_font_origin(18),
|
||||
anchor='mm',
|
||||
)
|
||||
|
||||
artifactimg_bg.paste(artifacts_img, (0, 0), artifacts_img)
|
||||
return artifactimg_bg
|
||||
|
||||
|
||||
async def get_artifact_score_data(aritifact: Dict, char: Character) -> Dict:
|
||||
all_value_score = 0
|
||||
all_cv_score = 0
|
||||
for i in aritifact['reliquarySubstats']:
|
||||
subName: str = i['statName']
|
||||
subValue: float = i['statValue']
|
||||
if not hasattr(char, 'baseAtk'):
|
||||
await char.new()
|
||||
cv_score = 0
|
||||
|
||||
if subName == '暴击率':
|
||||
cv_score += subValue * 2
|
||||
elif subName == '暴击伤害':
|
||||
cv_score += subValue
|
||||
|
||||
value_temp = await get_artifacts_value(
|
||||
subName,
|
||||
subValue,
|
||||
char.baseAtk,
|
||||
char.baseHp,
|
||||
char.baseDef,
|
||||
char.char_name,
|
||||
)
|
||||
|
||||
i['value_score'] = value_temp
|
||||
i['cv_score'] = cv_score
|
||||
|
||||
all_cv_score += cv_score
|
||||
all_value_score += value_temp
|
||||
|
||||
aritifact['cv_score'] = all_cv_score
|
||||
aritifact['value_score'] = all_value_score
|
||||
|
||||
return aritifact
|
||||
|
||||
|
||||
async def get_single_artifact_img(
|
||||
aritifact: Dict, char: Character
|
||||
) -> Image.Image:
|
||||
new_aritifact = await get_artifact_score_data(aritifact, char)
|
||||
img = await _get_single_artifact_img(new_aritifact)
|
||||
for i in aritifact['reliquarySubstats']:
|
||||
char.artifacts_all_score += i['value_score']
|
||||
return img
|
||||
|
||||
|
||||
async def get_artifacts_card(char: Character, img: Image.Image):
|
||||
card_prop = char.card_prop
|
||||
# 圣遗物部分
|
||||
for aritifact in card_prop['equipList']:
|
||||
artifacts_img = Image.open(TEXT_PATH / 'char_info_artifacts.png')
|
||||
artifacts_piece_img = Image.open(
|
||||
REL_PATH / '{}.png'.format(aritifact['aritifactName'])
|
||||
)
|
||||
artifacts_piece_new_img = artifacts_piece_img.resize(
|
||||
(120, 120), Image.Resampling.LANCZOS
|
||||
).convert("RGBA")
|
||||
|
||||
artifacts_img.paste(
|
||||
artifacts_piece_new_img, (165, 22), artifacts_piece_new_img
|
||||
)
|
||||
aritifactStar_img = get_star_png(aritifact['aritifactStar'])
|
||||
artifactsPos = aritifact['aritifactPieceName']
|
||||
|
||||
# 圣遗物星星和名称&位置
|
||||
artifacts_img.paste(aritifactStar_img, (16, 115), aritifactStar_img)
|
||||
artifacts_text = ImageDraw.Draw(artifacts_img)
|
||||
if len(aritifact['aritifactName']) <= 5:
|
||||
main_name = aritifact['aritifactName']
|
||||
else:
|
||||
main_name = (
|
||||
aritifact['aritifactName'][:2] + aritifact['aritifactName'][4:]
|
||||
)
|
||||
artifacts_text.text(
|
||||
(22, 100),
|
||||
main_name,
|
||||
(255, 255, 255),
|
||||
genshin_font_origin(28),
|
||||
anchor='lm',
|
||||
)
|
||||
'''
|
||||
artifacts_text.text(
|
||||
(30, 102),
|
||||
artifactsPos,
|
||||
(255, 255, 255),
|
||||
genshin_font_origin(20),
|
||||
anchor='lm',
|
||||
)
|
||||
'''
|
||||
|
||||
mainValue: float = aritifact['reliquaryMainstat']['statValue']
|
||||
mainName: str = aritifact['reliquaryMainstat']['statName']
|
||||
mainLevel: int = aritifact['aritifactLevel']
|
||||
|
||||
if mainName in ['攻击力', '血量', '防御力', '元素精通']:
|
||||
mainValueStr = str(mainValue)
|
||||
else:
|
||||
mainValueStr = str(mainValue) + '%'
|
||||
|
||||
mainNameNew = (
|
||||
mainName.replace('百分比', '')
|
||||
.replace('伤害加成', '伤加成')
|
||||
.replace('元素', '')
|
||||
.replace('理', '')
|
||||
)
|
||||
|
||||
artifacts_text.text(
|
||||
(34, 174),
|
||||
mainNameNew,
|
||||
(255, 255, 255),
|
||||
genshin_font_origin(28),
|
||||
anchor='lm',
|
||||
)
|
||||
artifacts_text.text(
|
||||
(266, 174),
|
||||
mainValueStr,
|
||||
(255, 255, 255),
|
||||
genshin_font_origin(28),
|
||||
anchor='rm',
|
||||
)
|
||||
artifacts_text.text(
|
||||
(246, 132),
|
||||
'+{}'.format(str(mainLevel)),
|
||||
(255, 255, 255),
|
||||
genshin_font_origin(23),
|
||||
anchor='mm',
|
||||
)
|
||||
|
||||
artifactsScore = 0
|
||||
for index, i in enumerate(aritifact['reliquarySubstats']):
|
||||
subName: str = i['statName']
|
||||
subValue: float = i['statValue']
|
||||
if subName in ['攻击力', '血量', '防御力', '元素精通']:
|
||||
subValueStr = str(subValue)
|
||||
else:
|
||||
subValueStr = str(subValue) + '%'
|
||||
value_temp = await get_artifacts_value(
|
||||
subName,
|
||||
subValue,
|
||||
char.baseAtk,
|
||||
char.baseHp,
|
||||
char.baseDef,
|
||||
char.char_name,
|
||||
)
|
||||
artifactsScore += value_temp
|
||||
subNameStr = subName.replace('百分比', '').replace('元素', '')
|
||||
# 副词条文字颜色
|
||||
if value_temp == 0:
|
||||
artifacts_color = (160, 160, 160)
|
||||
else:
|
||||
artifacts_color = (255, 255, 255)
|
||||
|
||||
# 副词条底色
|
||||
if value_temp >= 3.4:
|
||||
artifacts_bg = (205, 135, 76)
|
||||
if value_temp >= 4.5:
|
||||
artifacts_bg = (158, 39, 39)
|
||||
artifacts_text.rounded_rectangle(
|
||||
(22, 209 + index * 35, 274, 238 + index * 35),
|
||||
fill=artifacts_bg,
|
||||
radius=8,
|
||||
)
|
||||
|
||||
artifacts_text.text(
|
||||
(22, 225 + index * 35),
|
||||
'·{}'.format(subNameStr),
|
||||
artifacts_color,
|
||||
genshin_font_origin(25),
|
||||
anchor='lm',
|
||||
)
|
||||
artifacts_text.text(
|
||||
(266, 225 + index * 35),
|
||||
'{}'.format(subValueStr),
|
||||
artifacts_color,
|
||||
genshin_font_origin(25),
|
||||
anchor='rm',
|
||||
)
|
||||
if artifactsScore >= 8.4:
|
||||
artifactsScore_color = (158, 39, 39)
|
||||
elif artifactsScore >= 6.5:
|
||||
artifactsScore_color = (205, 135, 76)
|
||||
elif artifactsScore >= 5.2:
|
||||
artifactsScore_color = (143, 123, 174)
|
||||
else:
|
||||
artifactsScore_color = (94, 96, 95)
|
||||
char.artifacts_all_score += artifactsScore
|
||||
artifacts_text.rounded_rectangle(
|
||||
(21, 45, 104, 75), fill=artifactsScore_color, radius=8
|
||||
)
|
||||
artifacts_text.text(
|
||||
(26, 60),
|
||||
'{:.2f}'.format(artifactsScore) + '条',
|
||||
(255, 255, 255),
|
||||
genshin_font_origin(23),
|
||||
anchor='lm',
|
||||
)
|
||||
artifacts_img = await get_single_artifact_img(aritifact, char)
|
||||
img.paste(artifacts_img, ARTIFACTS_POS[artifactsPos], artifacts_img)
|
||||
|
@ -1,5 +1,6 @@
|
||||
import re
|
||||
import json
|
||||
import asyncio
|
||||
from copy import deepcopy
|
||||
|
||||
import aiofiles
|
||||
@ -8,30 +9,53 @@ from gsuid_core.logger import logger
|
||||
from ..utils.resource.RESOURCE_PATH import PLAYER_PATH
|
||||
from .to_data import ARTIFACT_DATA, input_artifacts_data
|
||||
|
||||
pattern = r'^[\u4e00-\u9fa5]'
|
||||
|
||||
|
||||
async def refresh_player_list(uid: str) -> str:
|
||||
player = PLAYER_PATH / uid
|
||||
path = player / 'artifacts.json'
|
||||
all_artifacts = deepcopy(ARTIFACT_DATA)
|
||||
if not path.exists():
|
||||
logger.info(f'UID{player.name} 不存在圣遗物列表,开始生成中...')
|
||||
else:
|
||||
async with aiofiles.open(path, 'r', encoding='UTF-8') as file:
|
||||
all_artifacts = json.loads(await file.read())
|
||||
|
||||
all_list = [x for v in all_artifacts['data'].values() for x in v]
|
||||
|
||||
if len(all_list) >= 1 and 'cv_score' not in all_list[0]:
|
||||
path.unlink()
|
||||
# return '删除旧数据中...请重新刷新!'
|
||||
|
||||
num = 0
|
||||
for char in player.iterdir():
|
||||
match = re.match(pattern, char.name)
|
||||
if match:
|
||||
async with aiofiles.open(char, 'r', encoding='UTF-8') as file:
|
||||
char_data = json.loads(await file.read())
|
||||
|
||||
for artifact in char_data['equipList']:
|
||||
all_artifacts = await input_artifacts_data(
|
||||
artifact,
|
||||
all_artifacts,
|
||||
char_data['avatarId'],
|
||||
char_data,
|
||||
)
|
||||
num += 1
|
||||
|
||||
await asyncio.sleep(0.5)
|
||||
# 保存原始数据
|
||||
async with aiofiles.open(path, 'w', encoding='UTF-8') as file:
|
||||
await file.write(
|
||||
json.dumps(all_artifacts, indent=4, ensure_ascii=False)
|
||||
)
|
||||
|
||||
return f'刷新成功, 本次刷新 {num} 个圣遗物!'
|
||||
|
||||
|
||||
async def check_artifacts_list():
|
||||
pattern = r'^[\u4e00-\u9fa5]'
|
||||
logger.info('开始检查是否创建圣遗物列表...')
|
||||
for player in PLAYER_PATH.iterdir():
|
||||
path = player / 'artifacts.json'
|
||||
all_artifacts = deepcopy(ARTIFACT_DATA)
|
||||
if not path.exists():
|
||||
logger.info(f'UID{player.name} 不存在圣遗物列表,开始生成中...')
|
||||
for char in player.iterdir():
|
||||
match = re.match(pattern, char.name)
|
||||
if match:
|
||||
async with aiofiles.open(
|
||||
char, 'r', encoding='UTF-8'
|
||||
) as file:
|
||||
char_data = json.loads(await file.read())
|
||||
|
||||
for artifact in char_data['equipList']:
|
||||
all_artifacts = await input_artifacts_data(
|
||||
artifact, all_artifacts, char_data['avatarId']
|
||||
)
|
||||
# 保存原始数据
|
||||
async with aiofiles.open(path, 'w', encoding='UTF-8') as file:
|
||||
await file.write(
|
||||
json.dumps(all_artifacts, indent=4, ensure_ascii=False)
|
||||
)
|
||||
await refresh_player_list(player.name)
|
||||
logger.info('圣遗物列表检查完成!')
|
||||
|
BIN
GenshinUID/genshinuid_enka/texture2D/artifacts_lib_bg.png
Normal file
After Width: | Height: | Size: 498 KiB |
Before Width: | Height: | Size: 114 KiB After Width: | Height: | Size: 127 KiB |
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 17 KiB |
BIN
GenshinUID/genshinuid_enka/texture2D/char_info_artifacts_bg.png
Normal file
After Width: | Height: | Size: 9.0 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 8.8 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 8.7 KiB |
@ -1,5 +1,7 @@
|
||||
import json
|
||||
import time
|
||||
import asyncio
|
||||
import threading
|
||||
from copy import deepcopy
|
||||
from typing import Dict, List, Union, Literal, Optional
|
||||
|
||||
@ -10,6 +12,8 @@ from gsuid_core.utils.api.enka.models import EnkaData
|
||||
from gsuid_core.utils.api.enka.request import get_enka_info
|
||||
from gsuid_core.utils.api.minigg.request import get_weapon_info
|
||||
|
||||
from .mono.Character import Character
|
||||
from .draw_normal import get_artifact_score_data
|
||||
from ..utils.resource.RESOURCE_PATH import PLAYER_PATH
|
||||
from ..utils.ambr_to_minigg import convert_ambr_to_weapon
|
||||
from ..utils.map.GS_MAP_PATH import (
|
||||
@ -357,10 +361,6 @@ async def enka_to_dict(
|
||||
for sub in artifact_temp['reliquarySubstats']:
|
||||
sub['statName'] = propId2Name[sub['appendPropId']]
|
||||
|
||||
await input_artifacts_data(
|
||||
artifact_temp, all_artifacts_data, avatarId
|
||||
)
|
||||
|
||||
# 加入单个圣遗物部件
|
||||
artifacts_info.append(artifact_temp)
|
||||
|
||||
@ -389,6 +389,18 @@ async def enka_to_dict(
|
||||
if char_data['equipSets']['set'].startswith('|'):
|
||||
char_data['equipSets']['set'] = char_data['equipSets']['set'][1:]
|
||||
|
||||
threading.Thread(
|
||||
target=lambda: asyncio.run(
|
||||
_get_data(
|
||||
artifacts_info,
|
||||
all_artifacts_data,
|
||||
avatarId,
|
||||
char_data,
|
||||
)
|
||||
),
|
||||
daemon=True,
|
||||
).start()
|
||||
|
||||
char_dict_list.append(char_data)
|
||||
async with aiofiles.open(
|
||||
path / '{}.json'.format(avatarName), 'w', encoding='UTF-8'
|
||||
@ -414,9 +426,27 @@ async def enka_to_data(
|
||||
return f'UID{uid}刷新完成!\n本次缓存:{char_name_list_str}'
|
||||
|
||||
|
||||
async def input_artifacts_data(
|
||||
artifact_temp: Dict, all_artifacts_data: Dict, avatarId: int
|
||||
async def _get_data(
|
||||
artifacts_info: List,
|
||||
all_artifacts_data: Dict,
|
||||
avatarId: int,
|
||||
char_data: Dict,
|
||||
):
|
||||
for _artifact in artifacts_info:
|
||||
await input_artifacts_data(
|
||||
deepcopy(_artifact), all_artifacts_data, avatarId, char_data
|
||||
)
|
||||
|
||||
|
||||
async def input_artifacts_data(
|
||||
artifact_temp: Dict,
|
||||
all_artifacts_data: Dict,
|
||||
avatarId: int,
|
||||
char_data: Dict,
|
||||
):
|
||||
artifact_temp = await get_artifact_score_data(
|
||||
artifact_temp, Character(char_data)
|
||||
)
|
||||
# 加入圣遗物数据列表
|
||||
if (
|
||||
artifact_temp
|
||||
|