mirror of
https://github.com/KimigaiiWuyi/GenshinUID.git
synced 2025-05-08 04:55:51 +08:00
✨ 新增gs未复刻列表
This commit is contained in:
parent
89ece1846b
commit
b8f773ad0c
@ -546,6 +546,14 @@
|
||||
"need_ck": false,
|
||||
"need_sk": false,
|
||||
"need_admin": false
|
||||
},
|
||||
{
|
||||
"name": "未复刻列表",
|
||||
"desc": "查看角色武器卡池未复刻时间",
|
||||
"eg": "未复刻列表",
|
||||
"need_ck": false,
|
||||
"need_sk": false,
|
||||
"need_admin": false
|
||||
}
|
||||
]
|
||||
},
|
||||
|
17
GenshinUID/genshinuid_returnlist/__init__.py
Normal file
17
GenshinUID/genshinuid_returnlist/__init__.py
Normal file
@ -0,0 +1,17 @@
|
||||
from gsuid_core.sv import SV
|
||||
from gsuid_core.bot import Bot
|
||||
from gsuid_core.models import Event
|
||||
from gsuid_core.logger import logger
|
||||
|
||||
from .draw_teyvat_returnlist import draw_teyvat_returnlist_img
|
||||
|
||||
sv_get_returnlist = SV('查询未复刻天数', priority=4)
|
||||
|
||||
|
||||
@sv_get_returnlist.on_fullmatch(
|
||||
('未复刻', '未复刻列表', '复刻列表'), block=True
|
||||
)
|
||||
async def send_abyss_pic(bot: Bot, ev: Event):
|
||||
img = await draw_teyvat_returnlist_img()
|
||||
logger.info('[未复刻] 获得未复刻UP列表成功!')
|
||||
await bot.send(img)
|
162
GenshinUID/genshinuid_returnlist/draw_teyvat_returnlist.py
Normal file
162
GenshinUID/genshinuid_returnlist/draw_teyvat_returnlist.py
Normal file
@ -0,0 +1,162 @@
|
||||
from pathlib import Path
|
||||
from typing import Union, Literal
|
||||
|
||||
from PIL import Image, ImageDraw
|
||||
from gsuid_core.utils.error_reply import get_error
|
||||
|
||||
from ..version import Genshin_version
|
||||
from ..utils.image.convert import convert_img
|
||||
from ..utils.api.teyvat.request import teyvat_api
|
||||
from ..utils.map.name_covert import name_to_avatar_id
|
||||
from ..utils.image.image_tools import get_v4_bg, add_footer
|
||||
from ..utils.api.teyvat.models import WeaponData, CharacterData
|
||||
from ..utils.resource.RESOURCE_PATH import CHAR_PATH, WEAPON_PATH
|
||||
from ..utils.fonts.genshin_fonts import gs_font_24, gs_font_30, gs_font_38
|
||||
|
||||
TEXT_PATH = Path(__file__).parent / 'texture2d'
|
||||
COLOR_MAP = {
|
||||
1.5: (241, 18, 18),
|
||||
1.3: (112, 18, 241),
|
||||
1.1: (49, 88, 192),
|
||||
0.8: (66, 114, 14),
|
||||
}
|
||||
|
||||
|
||||
async def draw_item(
|
||||
item: Union[CharacterData, WeaponData],
|
||||
_type: Literal['char', 'weapon'],
|
||||
):
|
||||
days = item['days']
|
||||
lv_str = item['history'][-1]
|
||||
last_version = float(lv_str[:3])
|
||||
version_cut = float(Genshin_version[:3]) - last_version
|
||||
|
||||
for rg in COLOR_MAP:
|
||||
if version_cut >= rg:
|
||||
color = COLOR_MAP[rg]
|
||||
break
|
||||
else:
|
||||
color = (37, 37, 37)
|
||||
|
||||
if _type == 'char':
|
||||
char_id = await name_to_avatar_id(item['role'])
|
||||
item_img = Image.open(CHAR_PATH / f'{char_id}.png')
|
||||
else:
|
||||
item_img = Image.open(WEAPON_PATH / f'{item["role"]}.png')
|
||||
|
||||
star = item['star']
|
||||
item_bg = Image.open(TEXT_PATH / f'star{star}.png')
|
||||
item_draw = ImageDraw.Draw(item_bg)
|
||||
|
||||
item_img = item_img.resize((164, 164))
|
||||
item_img = item_img.convert('RGBA')
|
||||
item_bg.paste(item_img, (25, 35), item_img)
|
||||
|
||||
item_draw.rounded_rectangle((55, 30, 155, 60), fill=color, radius=20)
|
||||
|
||||
'''
|
||||
item_draw.text(
|
||||
(105, 244),
|
||||
'未复刻天数',
|
||||
'white',
|
||||
gs_font_26,
|
||||
'mm',
|
||||
)
|
||||
'''
|
||||
|
||||
item_draw.text(
|
||||
(105, 228),
|
||||
f'{days}天',
|
||||
'white',
|
||||
gs_font_38,
|
||||
'mm',
|
||||
)
|
||||
|
||||
item_draw.text(
|
||||
(105, 45),
|
||||
f'{lv_str[:-1]}',
|
||||
'white',
|
||||
gs_font_24,
|
||||
'mm',
|
||||
)
|
||||
return item_bg
|
||||
|
||||
|
||||
async def draw_teyvat_returnlist_img():
|
||||
data = await teyvat_api.get_return_list()
|
||||
if isinstance(data, int):
|
||||
return get_error(data)
|
||||
|
||||
version = data['version']
|
||||
char5_list = data['result'][0][:12]
|
||||
char4_list = data['result'][1][:12]
|
||||
weapon5_list = data['result'][2][:12]
|
||||
_weapon4_list = data['result'][3][:12]
|
||||
|
||||
weapon4_list = []
|
||||
for weapon4 in _weapon4_list:
|
||||
weapon4['star'] = 4
|
||||
weapon4_list.append(weapon4)
|
||||
|
||||
w, h = 1400, 500 + 150 + 100 + 110
|
||||
|
||||
len1 = (((len(char5_list) - 1) // 6) + 1) * 274
|
||||
len2 = (((len(char4_list) - 1) // 6) + 1) * 274
|
||||
len3 = (((len(weapon5_list) - 1) // 6) + 1) * 274
|
||||
len4 = (((len(weapon4_list) - 1) // 6) + 1) * 274
|
||||
|
||||
h += len1 + len2 + len3 + len4
|
||||
|
||||
img = get_v4_bg(w, h)
|
||||
|
||||
title = Image.open(TEXT_PATH / 'title.png')
|
||||
title_draw = ImageDraw.Draw(title)
|
||||
|
||||
bar1 = Image.open(TEXT_PATH / 'bar1.png')
|
||||
bar2 = Image.open(TEXT_PATH / 'bar2.png')
|
||||
|
||||
title_draw.text(
|
||||
(643, 356),
|
||||
f'{version}',
|
||||
(255, 255, 255),
|
||||
gs_font_30,
|
||||
'mm',
|
||||
)
|
||||
|
||||
img.paste(title, (0, 0), title)
|
||||
|
||||
img.paste(bar1, (0, 540), bar1)
|
||||
|
||||
for i, item in enumerate(char5_list):
|
||||
x = (i % 6) * 210 + 67
|
||||
y = (i // 6) * 274 + 623
|
||||
|
||||
item = await draw_item(item, 'char')
|
||||
img.paste(item, (x, y), item)
|
||||
|
||||
for i, item in enumerate(char4_list):
|
||||
x = (i % 6) * 210 + 67
|
||||
y = (i // 6) * 274 + 623 + len1
|
||||
|
||||
item = await draw_item(item, 'char')
|
||||
img.paste(item, (x, y), item)
|
||||
|
||||
img.paste(bar2, (0, 540 + 90 + 40 + len1 + len2), bar2)
|
||||
|
||||
for i, item in enumerate(weapon5_list):
|
||||
x = (i % 6) * 210 + 67
|
||||
y = (i // 6) * 274 + 623 + len1 + len2 + 90 + 40
|
||||
|
||||
item = await draw_item(item, 'weapon')
|
||||
img.paste(item, (x, y), item)
|
||||
|
||||
for i, item in enumerate(weapon4_list):
|
||||
x = (i % 6) * 210 + 67
|
||||
y = (i // 6) * 274 + 623 + len1 + len2 + len3 + 90 + 40
|
||||
|
||||
item = await draw_item(item, 'weapon')
|
||||
img.paste(item, (x, y), item)
|
||||
|
||||
img = add_footer(img, w)
|
||||
res = await convert_img(img)
|
||||
return res
|
BIN
GenshinUID/genshinuid_returnlist/texture2d/bar1.png
Normal file
BIN
GenshinUID/genshinuid_returnlist/texture2d/bar1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
BIN
GenshinUID/genshinuid_returnlist/texture2d/bar2.png
Normal file
BIN
GenshinUID/genshinuid_returnlist/texture2d/bar2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
BIN
GenshinUID/genshinuid_returnlist/texture2d/star4.png
Normal file
BIN
GenshinUID/genshinuid_returnlist/texture2d/star4.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 46 KiB |
BIN
GenshinUID/genshinuid_returnlist/texture2d/star5.png
Normal file
BIN
GenshinUID/genshinuid_returnlist/texture2d/star5.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 37 KiB |
BIN
GenshinUID/genshinuid_returnlist/texture2d/title.png
Normal file
BIN
GenshinUID/genshinuid_returnlist/texture2d/title.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 941 KiB |
@ -1,3 +1,4 @@
|
||||
LELAER_API = 'https://api.lelaer.com/ys'
|
||||
|
||||
AbyssRank_API = f'{LELAER_API}/getAbyssRank.php?star=all&role=all'
|
||||
ReturnList_API = f'{LELAER_API}/getRerunList.php'
|
||||
|
@ -102,3 +102,34 @@ class TeyvatAbyssRank(TypedDict):
|
||||
List[CharacterUsage],
|
||||
List[TeyvatTeam],
|
||||
]
|
||||
|
||||
|
||||
class CharacterData(TypedDict):
|
||||
role: str
|
||||
avatar: str
|
||||
star: int
|
||||
days: int
|
||||
intro: str
|
||||
history: List[str]
|
||||
width: int
|
||||
|
||||
|
||||
class WeaponData(TypedDict):
|
||||
role: str
|
||||
avatar: str
|
||||
star: int
|
||||
days: int
|
||||
intro: str
|
||||
history: List[str]
|
||||
width: int
|
||||
|
||||
|
||||
class TeyvatReturnList(TypedDict):
|
||||
code: int
|
||||
version: str
|
||||
result: Tuple[
|
||||
List[CharacterData],
|
||||
List[CharacterData],
|
||||
List[WeaponData],
|
||||
List[WeaponData],
|
||||
]
|
||||
|
@ -4,8 +4,8 @@ from typing import Any, Dict, Union, Literal, Optional, cast
|
||||
from httpx import AsyncClient
|
||||
from gsuid_core.logger import logger
|
||||
|
||||
from .api import AbyssRank_API
|
||||
from .models import TeyvatAbyssRank
|
||||
from .api import AbyssRank_API, ReturnList_API
|
||||
from .models import TeyvatAbyssRank, TeyvatReturnList
|
||||
|
||||
|
||||
class _TeyvatAPI:
|
||||
@ -22,6 +22,16 @@ class _TeyvatAPI:
|
||||
else:
|
||||
return -500
|
||||
|
||||
async def get_return_list(self) -> Union[TeyvatReturnList, int]:
|
||||
data = await self._teyvat_request(ReturnList_API)
|
||||
if isinstance(data, Dict) and 'code' in data:
|
||||
if data['code'] == 200:
|
||||
return cast(TeyvatReturnList, data)
|
||||
else:
|
||||
return data['code']
|
||||
else:
|
||||
return -500
|
||||
|
||||
async def _teyvat_request(
|
||||
self,
|
||||
url: str,
|
||||
|
Loading…
x
Reference in New Issue
Block a user