mirror of
https://github.com/baiqwerdvd/StarRailUID.git
synced 2025-05-04 18:57:33 +08:00
small fix
This commit is contained in:
parent
1dfab6c55b
commit
5e57113f2d
@ -16,11 +16,11 @@ async def get_character_data(
|
||||
avatar_id: str,
|
||||
) -> Union[HakushHsrCharacter, None]:
|
||||
async with AsyncClient(
|
||||
base_url='https://api.hakush.in/hsr/data',
|
||||
base_url="https://api.hakush.in/hsr/data",
|
||||
headers=_HEADER,
|
||||
timeout=30,
|
||||
) as client:
|
||||
req = await client.get(f'/cn/character/{avatar_id}.json')
|
||||
req = await client.get(f"/cn/character/{avatar_id}.json")
|
||||
if req.status_code == 200:
|
||||
return convert(req.json(), type=HakushHsrCharacter)
|
||||
return None
|
||||
@ -30,39 +30,35 @@ async def get_lightcone_data(
|
||||
lightcone_id: str,
|
||||
) -> Union[HakushHsrLightcone, None]:
|
||||
async with AsyncClient(
|
||||
base_url='https://api.hakush.in/hsr/data',
|
||||
base_url="https://api.hakush.in/hsr/data",
|
||||
headers=_HEADER,
|
||||
timeout=30,
|
||||
) as client:
|
||||
req = await client.get(f'/cn/lightcone/{lightcone_id}.json')
|
||||
req = await client.get(f"/cn/lightcone/{lightcone_id}.json")
|
||||
if req.status_code == 200:
|
||||
return convert(req.json(), type=HakushHsrLightcone)
|
||||
return None
|
||||
|
||||
|
||||
async def get_character_index() -> (
|
||||
Union[Dict[str, HakushHsrCharacterIndex], None]
|
||||
):
|
||||
async def get_character_index() -> Union[Dict[str, HakushHsrCharacterIndex], None]:
|
||||
async with AsyncClient(
|
||||
base_url='https://api.hakush.in/hsr/data',
|
||||
base_url="https://api.hakush.in/hsr/data",
|
||||
headers=_HEADER,
|
||||
timeout=30,
|
||||
) as client:
|
||||
req = await client.get('/character.json')
|
||||
req = await client.get("/character.json")
|
||||
if req.status_code == 200:
|
||||
return convert(req.json(), type=Dict[str, HakushHsrCharacterIndex])
|
||||
return None
|
||||
|
||||
|
||||
async def get_lightcone_index() -> (
|
||||
Union[Dict[str, HakushHsrLightconeIndex], None]
|
||||
):
|
||||
async def get_lightcone_index() -> Union[Dict[str, HakushHsrLightconeIndex], None]:
|
||||
async with AsyncClient(
|
||||
base_url='https://api.hakush.in/hsr/data',
|
||||
base_url="https://api.hakush.in/hsr/data",
|
||||
headers=_HEADER,
|
||||
timeout=30,
|
||||
) as client:
|
||||
req = await client.get('/character.json')
|
||||
req = await client.get("/character.json")
|
||||
if req.status_code == 200:
|
||||
return convert(req.json(), type=Dict[str, HakushHsrLightconeIndex])
|
||||
return None
|
||||
|
@ -3,4 +3,4 @@
|
||||
from .models import MihomoData as MihomoData
|
||||
from .requests import get_char_card_info as requests
|
||||
|
||||
__all__ = ['requests', 'MihomoData']
|
||||
__all__ = ["requests", "MihomoData"]
|
||||
|
@ -12,13 +12,13 @@ from ....utils.resource.RESOURCE_PATH import PLAYER_PATH
|
||||
|
||||
async def get_char_card_info(uid: str) -> MihomoData:
|
||||
async with AsyncClient(
|
||||
base_url='http://api.mihomo.me',
|
||||
base_url="http://api.mihomo.me",
|
||||
headers=_HEADER,
|
||||
timeout=30,
|
||||
) as client:
|
||||
req = await client.get(f'/sr_info/{uid}')
|
||||
req = await client.get(f"/sr_info/{uid}")
|
||||
path = PLAYER_PATH / str(uid)
|
||||
path.mkdir(parents=True, exist_ok=True)
|
||||
with Path.open(path / f'{uid!s}.json', 'w') as file:
|
||||
with Path.open(path / f"{uid!s}.json", "w") as file:
|
||||
file.write(req.text)
|
||||
return convert(req.json(), type=MihomoData)
|
||||
|
@ -1,75 +1,65 @@
|
||||
# flake8: noqa
|
||||
OLD_URL = 'https://api-takumi.mihoyo.com'
|
||||
OS_OLD_URL = 'https://api-os-takumi.mihoyo.com'
|
||||
NEW_URL = 'https://api-takumi-record.mihoyo.com'
|
||||
OS_URL = 'https://sg-public-api.hoyolab.com'
|
||||
OS_INFO_URL = 'https://bbs-api-os.hoyolab.com'
|
||||
OLD_URL = "https://api-takumi.mihoyo.com"
|
||||
OS_OLD_URL = "https://api-os-takumi.mihoyo.com"
|
||||
NEW_URL = "https://api-takumi-record.mihoyo.com"
|
||||
OS_URL = "https://sg-public-api.hoyolab.com"
|
||||
OS_INFO_URL = "https://bbs-api-os.hoyolab.com"
|
||||
|
||||
STAR_RAIL_SIGN_INFO_URL = f'{OLD_URL}/event/luna/info'
|
||||
STAR_RAIL_SIGN_INFO_URL_OS = f'{OS_URL}/event/luna/os/info'
|
||||
STAR_RAIL_SIGN_LIST_URL = f'{OLD_URL}/event/luna/home'
|
||||
STAR_RAIL_SIGN_LIST_URL_OS = f'{OS_URL}/event/luna/os/home'
|
||||
STAR_RAIL_SIGN_EXTRA_INFO_URL = f'{OLD_URL}/event/luna/extra_info'
|
||||
STAR_RAIL_SIGN_EXTRA_REWARD_URL = f'{OLD_URL}/event/luna/extra_reward'
|
||||
STAR_RAIL_SIGN_URL = f'{OLD_URL}/event/luna/sign'
|
||||
STAR_RAIL_SIGN_URL_OS = f'{OS_URL}/event/luna/os/sign'
|
||||
STAR_RAIL_MONTH_INFO_URL = (
|
||||
f'{OLD_URL}/event/srledger/month_info' # 开拓阅历接口
|
||||
)
|
||||
STAR_RAIL_SIGN_INFO_URL = f"{OLD_URL}/event/luna/info"
|
||||
STAR_RAIL_SIGN_INFO_URL_OS = f"{OS_URL}/event/luna/os/info"
|
||||
STAR_RAIL_SIGN_LIST_URL = f"{OLD_URL}/event/luna/home"
|
||||
STAR_RAIL_SIGN_LIST_URL_OS = f"{OS_URL}/event/luna/os/home"
|
||||
STAR_RAIL_SIGN_EXTRA_INFO_URL = f"{OLD_URL}/event/luna/extra_info"
|
||||
STAR_RAIL_SIGN_EXTRA_REWARD_URL = f"{OLD_URL}/event/luna/extra_reward"
|
||||
STAR_RAIL_SIGN_URL = f"{OLD_URL}/event/luna/sign"
|
||||
STAR_RAIL_SIGN_URL_OS = f"{OS_URL}/event/luna/os/sign"
|
||||
STAR_RAIL_MONTH_INFO_URL = f"{OLD_URL}/event/srledger/month_info" # 开拓阅历接口
|
||||
STAR_RAIL_MONTH_DETAIL_URL = (
|
||||
f'{OLD_URL}/event/srledger/month_detail' # 开拓阅历详情接口
|
||||
f"{OLD_URL}/event/srledger/month_detail" # 开拓阅历详情接口
|
||||
)
|
||||
|
||||
STAR_RAIL_NOTE_URL = (
|
||||
f'{NEW_URL}/game_record/app/hkrpg/api/note' # 实时便签接口
|
||||
)
|
||||
STAR_RAIL_NOTE_URL_OS = (
|
||||
f'{OS_INFO_URL}/game_record/hkrpg/api/note' # OS实时便签接口
|
||||
)
|
||||
STAR_RAIL_INDEX_URL = (
|
||||
f'{NEW_URL}/game_record/app/hkrpg/api/index' # 角色橱窗接口
|
||||
)
|
||||
STAR_RAIL_INDEX_URL_OS = (
|
||||
f'{OS_INFO_URL}/game_record/hkrpg/api/index' # OS角色橱窗接口
|
||||
)
|
||||
STAR_RAIL_NOTE_URL = f"{NEW_URL}/game_record/app/hkrpg/api/note" # 实时便签接口
|
||||
STAR_RAIL_NOTE_URL_OS = f"{OS_INFO_URL}/game_record/hkrpg/api/note" # OS实时便签接口
|
||||
STAR_RAIL_INDEX_URL = f"{NEW_URL}/game_record/app/hkrpg/api/index" # 角色橱窗接口
|
||||
STAR_RAIL_INDEX_URL_OS = f"{OS_INFO_URL}/game_record/hkrpg/api/index" # OS角色橱窗接口
|
||||
STAR_RAIL_AVATAR_BASIC_URL = (
|
||||
f'{NEW_URL}/game_record/app/hkrpg/api/avatar/basic' # 全部角色接口
|
||||
f"{NEW_URL}/game_record/app/hkrpg/api/avatar/basic" # 全部角色接口
|
||||
)
|
||||
STAR_RAIL_ROLE_BASIC_INFO_URL = (
|
||||
f'{NEW_URL}/game_record/app/hkrpg/api/role/basicInfo' # 角色基础信息接口
|
||||
f"{NEW_URL}/game_record/app/hkrpg/api/role/basicInfo" # 角色基础信息接口
|
||||
)
|
||||
STAR_RAIL_ROLE_BASIC_INFO_URL_OS = f'{OS_INFO_URL}/game_record/hkrpg/api/index'
|
||||
STAR_RAIL_ROLE_BASIC_INFO_URL_OS = f"{OS_INFO_URL}/game_record/hkrpg/api/index"
|
||||
STAR_RAIL_AVATAR_INFO_URL = (
|
||||
f'{NEW_URL}/game_record/app/hkrpg/api/avatar/info' # 角色详细信息接口
|
||||
f"{NEW_URL}/game_record/app/hkrpg/api/avatar/info" # 角色详细信息接口
|
||||
)
|
||||
STAR_RAIL_AVATAR_INFO_URL_OS = (
|
||||
f'{OS_INFO_URL}/game_record/hkrpg/api/avatar/info' # OS角色详细信息接口
|
||||
f"{OS_INFO_URL}/game_record/hkrpg/api/avatar/info" # OS角色详细信息接口
|
||||
)
|
||||
|
||||
STAR_RAIL_AVATAR_LIST_URL = f'{OLD_URL}/event/rpgcalc/avatar/list'
|
||||
STAR_RAIL_AVATAR_DETAIL_URL = f'{OLD_URL}/event/rpgcalc/avatar/detail'
|
||||
STAR_RAIL_AVATAR_LIST_URL = f"{OLD_URL}/event/rpgcalc/avatar/list"
|
||||
STAR_RAIL_AVATAR_DETAIL_URL = f"{OLD_URL}/event/rpgcalc/avatar/detail"
|
||||
|
||||
CHALLENGE_INFO_URL = f'{NEW_URL}/game_record/app/hkrpg/api/challenge' # 忘却之庭
|
||||
CHALLENGE_INFO_URL_OS = f'{OS_INFO_URL}/game_record/hkrpg/api/challenge' # OS忘却之庭
|
||||
CHALLENGE_STORY_INFO_URL = f'{NEW_URL}/game_record/app/hkrpg/api/challenge_story' # 虚构叙事
|
||||
CHALLENGE_BOSS_INFO_URL = f'{NEW_URL}/game_record/app/hkrpg/api/challenge_boss' # 末日幻影
|
||||
|
||||
ROGUE_INFO_URL = (
|
||||
f'{NEW_URL}/game_record/app/hkrpg/api/rogue' # 角色模拟宇宙信息接口
|
||||
CHALLENGE_INFO_URL = f"{NEW_URL}/game_record/app/hkrpg/api/challenge" # 忘却之庭
|
||||
CHALLENGE_INFO_URL_OS = f"{OS_INFO_URL}/game_record/hkrpg/api/challenge" # OS忘却之庭
|
||||
CHALLENGE_STORY_INFO_URL = (
|
||||
f"{NEW_URL}/game_record/app/hkrpg/api/challenge_story" # 虚构叙事
|
||||
)
|
||||
CHALLENGE_BOSS_INFO_URL = (
|
||||
f"{NEW_URL}/game_record/app/hkrpg/api/challenge_boss" # 末日幻影
|
||||
)
|
||||
|
||||
ROGUE_INFO_URL = f"{NEW_URL}/game_record/app/hkrpg/api/rogue" # 角色模拟宇宙信息接口
|
||||
ROGUE_LOCUST_INFO_URL = (
|
||||
f'{NEW_URL}/game_record/app/hkrpg/api/rogue_locust' # 角色寰宇蝗灾信息接口
|
||||
f"{NEW_URL}/game_record/app/hkrpg/api/rogue_locust" # 角色寰宇蝗灾信息接口
|
||||
)
|
||||
|
||||
STAR_RAIL_GACHA_LOG_URL = f'{OLD_URL}/common/gacha_record/api/getGachaLog'
|
||||
STAR_RAIL_GACHA_LOG_URL_OS = (
|
||||
f'{OS_OLD_URL}/common/gacha_record/api/getGachaLog'
|
||||
)
|
||||
STAR_RAIL_GACHA_LOG_URL = f"{OLD_URL}/common/gacha_record/api/getGachaLog"
|
||||
STAR_RAIL_GACHA_LOG_URL_OS = f"{OS_OLD_URL}/common/gacha_record/api/getGachaLog"
|
||||
|
||||
GET_FP_URL = 'https://public-data-api.mihoyo.com/device-fp/api/getFp'
|
||||
GET_FP_URL_OS = 'https://sg-public-data-api.hoyoverse.com/device-fp/api/getFp'
|
||||
GET_FP_URL = "https://public-data-api.mihoyo.com/device-fp/api/getFp"
|
||||
GET_FP_URL_OS = "https://sg-public-data-api.hoyoverse.com/device-fp/api/getFp"
|
||||
# CREATE_QRCODE = f'{OLD_URL}/event/bbs_sign_reward/gen_auth_code'
|
||||
|
||||
STAR_RAIL_WIDGRT_URL = f'{NEW_URL}/game_record/app/hkrpg/aapi/widget'
|
||||
STAR_RAIL_WIDGRT_URL = f"{NEW_URL}/game_record/app/hkrpg/aapi/widget"
|
||||
|
||||
_API = locals()
|
||||
|
@ -1,3 +1,3 @@
|
||||
from gsuid_core.version import __version__
|
||||
|
||||
_HEADER = {'User-Agent': f'StarRailUID/{__version__}'}
|
||||
_HEADER = {"User-Agent": f"StarRailUID/{__version__}"}
|
||||
|
@ -1,45 +1,43 @@
|
||||
import re
|
||||
|
||||
from gsuid_core.sv import SV
|
||||
from .draw_abyss_card import draw_abyss_img
|
||||
from ..utils.sr_prefix import PREFIX
|
||||
|
||||
from gsuid_core.bot import Bot
|
||||
from gsuid_core.models import Event
|
||||
from gsuid_core.sv import SV
|
||||
from gsuid_core.utils.database.api import get_uid
|
||||
from gsuid_core.utils.database.models import GsBind
|
||||
from gsuid_core.utils.error_reply import UID_HINT
|
||||
|
||||
from ..utils.convert import get_uid
|
||||
from ..utils.sr_prefix import PREFIX
|
||||
from .draw_abyss_card import draw_abyss_img
|
||||
|
||||
sv_srabyss = SV('sr查询深渊')
|
||||
sv_srabyss = SV("sr查询深渊")
|
||||
|
||||
|
||||
@sv_srabyss.on_command(
|
||||
(
|
||||
f'{PREFIX}查询深渊',
|
||||
f'{PREFIX}查询上期深渊',
|
||||
f'{PREFIX}上期深渊',
|
||||
f'{PREFIX}深渊',
|
||||
f"{PREFIX}查询深渊",
|
||||
f"{PREFIX}查询上期深渊",
|
||||
f"{PREFIX}上期深渊",
|
||||
f"{PREFIX}深渊",
|
||||
),
|
||||
block=True,
|
||||
)
|
||||
async def send_srabyss_info(bot: Bot, ev: Event):
|
||||
name = ''.join(re.findall('[\u4e00-\u9fa5]', ev.text))
|
||||
name = "".join(re.findall("[\u4e00-\u9fa5]", ev.text))
|
||||
if name:
|
||||
return None
|
||||
|
||||
await bot.logger.info('开始执行[sr查询深渊信息]')
|
||||
get_uid_ = await get_uid(bot, ev, True)
|
||||
if get_uid_ is None:
|
||||
return await bot.send(UID_HINT)
|
||||
uid, user_id = get_uid_
|
||||
await bot.logger.info("开始执行[sr查询深渊信息]")
|
||||
uid, user_id = await get_uid(bot, ev, GsBind, "sr", True)
|
||||
if uid is None:
|
||||
return await bot.send(UID_HINT)
|
||||
await bot.logger.info(f'[sr查询深渊信息]uid: {uid}')
|
||||
await bot.logger.info(f"[sr查询深渊信息]uid: {uid}")
|
||||
|
||||
if '上期' in ev.command:
|
||||
schedule_type = '2'
|
||||
if "上期" in ev.command:
|
||||
schedule_type = "2"
|
||||
else:
|
||||
schedule_type = '1'
|
||||
await bot.logger.info(f'[sr查询深渊信息]深渊期数: {schedule_type}')
|
||||
schedule_type = "1"
|
||||
await bot.logger.info(f"[sr查询深渊信息]深渊期数: {schedule_type}")
|
||||
|
||||
im = await draw_abyss_img(user_id, uid, ev.sender, schedule_type)
|
||||
await bot.send(im)
|
||||
|
@ -1,17 +1,7 @@
|
||||
from pathlib import Path
|
||||
from typing import Union, Optional
|
||||
|
||||
from PIL import Image, ImageDraw
|
||||
from gsuid_core.logger import logger
|
||||
from gsuid_core.utils.error_reply import get_error
|
||||
from gsuid_core.utils.image.image_tools import (
|
||||
get_qq_avatar,
|
||||
draw_pic_with_ring,
|
||||
)
|
||||
from typing import Any, Dict, Union
|
||||
|
||||
from .utils import get_icon
|
||||
from ..utils.mys_api import mys_api
|
||||
from ..utils.image.convert import convert_img
|
||||
from ..sruid_utils.api.mys.models import AbyssAvatar
|
||||
from ..utils.fonts.starrail_fonts import (
|
||||
sr_font_22,
|
||||
@ -20,39 +10,41 @@ from ..utils.fonts.starrail_fonts import (
|
||||
sr_font_34,
|
||||
sr_font_42,
|
||||
)
|
||||
from ..utils.mys_api import mys_api
|
||||
|
||||
TEXT_PATH = Path(__file__).parent / 'texture2D'
|
||||
from PIL import Image, ImageDraw
|
||||
from gsuid_core.logger import logger
|
||||
from gsuid_core.utils.error_reply import get_error
|
||||
from gsuid_core.utils.image.convert import convert_img
|
||||
from gsuid_core.utils.image.image_tools import (
|
||||
draw_pic_with_ring,
|
||||
get_qq_avatar,
|
||||
)
|
||||
|
||||
TEXT_PATH = Path(__file__).parent / "texture2D"
|
||||
white_color = (255, 255, 255)
|
||||
gray_color = (175, 175, 175)
|
||||
img_bg = Image.open(TEXT_PATH / 'bg.jpg')
|
||||
level_cover = Image.open(TEXT_PATH / 'level_cover.png').convert('RGBA')
|
||||
char_bg_4 = Image.open(TEXT_PATH / 'char4_bg.png').convert('RGBA')
|
||||
char_bg_5 = Image.open(TEXT_PATH / 'char5_bg.png').convert('RGBA')
|
||||
rank_bg = Image.open(TEXT_PATH / 'rank_bg.png').convert('RGBA')
|
||||
star_yes = Image.open(TEXT_PATH / 'star.png').convert('RGBA')
|
||||
star_gray = Image.open(TEXT_PATH / 'star_gray.png').convert('RGBA')
|
||||
img_bg = Image.open(TEXT_PATH / "bg.jpg")
|
||||
level_cover = Image.open(TEXT_PATH / "level_cover.png").convert("RGBA")
|
||||
char_bg_4 = Image.open(TEXT_PATH / "char4_bg.png").convert("RGBA")
|
||||
char_bg_5 = Image.open(TEXT_PATH / "char5_bg.png").convert("RGBA")
|
||||
rank_bg = Image.open(TEXT_PATH / "rank_bg.png").convert("RGBA")
|
||||
star_yes = Image.open(TEXT_PATH / "star.png").convert("RGBA")
|
||||
star_gray = Image.open(TEXT_PATH / "star_gray.png").convert("RGBA")
|
||||
|
||||
elements = {
|
||||
'ice': Image.open(TEXT_PATH / 'IconNatureColorIce.png').convert('RGBA'),
|
||||
'fire': Image.open(TEXT_PATH / 'IconNatureColorFire.png').convert('RGBA'),
|
||||
'imaginary': Image.open(
|
||||
TEXT_PATH / 'IconNatureColorImaginary.png'
|
||||
).convert('RGBA'),
|
||||
'quantum': Image.open(TEXT_PATH / 'IconNatureColorQuantum.png').convert(
|
||||
'RGBA'
|
||||
),
|
||||
'lightning': Image.open(TEXT_PATH / 'IconNatureColorThunder.png').convert(
|
||||
'RGBA'
|
||||
),
|
||||
'wind': Image.open(TEXT_PATH / 'IconNatureColorWind.png').convert('RGBA'),
|
||||
'physical': Image.open(TEXT_PATH / 'IconNaturePhysical.png').convert(
|
||||
'RGBA'
|
||||
),
|
||||
"ice": Image.open(TEXT_PATH / "IconNatureColorIce.png").convert("RGBA"),
|
||||
"fire": Image.open(TEXT_PATH / "IconNatureColorFire.png").convert("RGBA"),
|
||||
"imaginary": Image.open(TEXT_PATH / "IconNatureColorImaginary.png").convert("RGBA"),
|
||||
"quantum": Image.open(TEXT_PATH / "IconNatureColorQuantum.png").convert("RGBA"),
|
||||
"lightning": Image.open(TEXT_PATH / "IconNatureColorThunder.png").convert("RGBA"),
|
||||
"wind": Image.open(TEXT_PATH / "IconNatureColorWind.png").convert("RGBA"),
|
||||
"physical": Image.open(TEXT_PATH / "IconNaturePhysical.png").convert("RGBA"),
|
||||
}
|
||||
|
||||
|
||||
async def get_abyss_star_pic(star: int) -> Image.Image:
|
||||
return Image.open(TEXT_PATH / f'star{star}.png')
|
||||
return Image.open(TEXT_PATH / f"star{star}.png")
|
||||
|
||||
|
||||
async def _draw_abyss_card(
|
||||
@ -72,17 +64,17 @@ async def _draw_abyss_card(
|
||||
char_bg.paste(rank_bg, (150, 16), mask=rank_bg)
|
||||
char_card_draw.text(
|
||||
(162, 31),
|
||||
f'{char.rank}',
|
||||
f"{char.rank}",
|
||||
font=sr_font_22,
|
||||
fill=white_color,
|
||||
anchor='mm',
|
||||
anchor="mm",
|
||||
)
|
||||
char_card_draw.text(
|
||||
(100, 165),
|
||||
f'等级 {char.level}',
|
||||
f"等级 {char.level}",
|
||||
font=sr_font_22,
|
||||
fill=white_color,
|
||||
anchor='mm',
|
||||
anchor="mm",
|
||||
)
|
||||
floor_pic.paste(
|
||||
char_bg,
|
||||
@ -92,16 +84,16 @@ async def _draw_abyss_card(
|
||||
|
||||
|
||||
async def _draw_floor_card(
|
||||
level_star: int,
|
||||
level_star: Union[int, str],
|
||||
floor_pic: Image.Image,
|
||||
img: Image.Image,
|
||||
index_floor: int,
|
||||
floor_name: str,
|
||||
round_num: int,
|
||||
round_num: Union[int, None],
|
||||
):
|
||||
for index_num in [0, 1, 2]:
|
||||
star_num = index_num + 1
|
||||
if star_num <= level_star:
|
||||
if star_num <= int(level_star):
|
||||
star_pic = star_yes.copy()
|
||||
else:
|
||||
star_pic = star_gray.copy()
|
||||
@ -112,14 +104,14 @@ async def _draw_floor_card(
|
||||
floor_name,
|
||||
font=sr_font_42,
|
||||
fill=white_color,
|
||||
anchor='mm',
|
||||
anchor="mm",
|
||||
)
|
||||
floor_pic_draw.text(
|
||||
(802, 60),
|
||||
f'使用轮: {round_num}',
|
||||
f"使用轮: {round_num}",
|
||||
font=sr_font_28,
|
||||
fill=gray_color,
|
||||
anchor='rm',
|
||||
anchor="rm",
|
||||
)
|
||||
img.paste(floor_pic, (0, 657 + index_floor * 570), floor_pic)
|
||||
|
||||
@ -127,8 +119,8 @@ async def _draw_floor_card(
|
||||
async def draw_abyss_img(
|
||||
qid: Union[str, int],
|
||||
uid: str,
|
||||
sender: Union[str, str],
|
||||
schedule_type: str = '1',
|
||||
sender: Dict[str, Any],
|
||||
schedule_type: str = "1",
|
||||
) -> Union[bytes, str]:
|
||||
raw_abyss_data = await mys_api.get_abyss_info(uid, schedule_type)
|
||||
|
||||
@ -136,10 +128,12 @@ async def draw_abyss_img(
|
||||
return get_error(raw_abyss_data)
|
||||
|
||||
# 获取查询者数据
|
||||
if raw_abyss_data.max_floor == '':
|
||||
return '你还没有挑战本期深渊!\n可以使用[sr上期深渊]命令查询上期~'
|
||||
# 过滤掉 is_fast(快速通关) 为 True 的项
|
||||
floor_detail = [detail for detail in raw_abyss_data.all_floor_detail if not detail.is_fast]
|
||||
if raw_abyss_data.max_floor == "":
|
||||
return "你还没有挑战本期深渊!\n可以使用[sr上期深渊]命令查询上期~"
|
||||
# 过滤掉 is_fast (快速通关) 为 True 的项
|
||||
floor_detail = [
|
||||
detail for detail in raw_abyss_data.all_floor_detail if not detail.is_fast
|
||||
]
|
||||
floor_num = len(floor_detail)
|
||||
|
||||
# 获取背景图片各项参数
|
||||
@ -147,15 +141,15 @@ async def draw_abyss_img(
|
||||
based_h = 657 + 570 * floor_num
|
||||
img = img_bg.copy()
|
||||
img = img.crop((0, 0, based_w, based_h))
|
||||
abyss_title = Image.open(TEXT_PATH / 'head.png')
|
||||
abyss_title = Image.open(TEXT_PATH / "head.png")
|
||||
img.paste(abyss_title, (0, 0), abyss_title)
|
||||
|
||||
# 获取头像
|
||||
_id = str(qid)
|
||||
if _id.startswith('http'):
|
||||
if _id.startswith("http"):
|
||||
char_pic = await get_qq_avatar(avatar_url=_id)
|
||||
elif sender.get('avatar') is not None:
|
||||
char_pic = await get_qq_avatar(avatar_url=sender['avatar'])
|
||||
elif sender.get("avatar") is not None:
|
||||
char_pic = await get_qq_avatar(avatar_url=sender["avatar"])
|
||||
else:
|
||||
char_pic = await get_qq_avatar(qid=qid)
|
||||
char_pic = await draw_pic_with_ring(char_pic, 250, None, False)
|
||||
@ -164,42 +158,42 @@ async def draw_abyss_img(
|
||||
|
||||
# 绘制抬头
|
||||
img_draw = ImageDraw.Draw(img)
|
||||
img_draw.text((450, 442), f'UID {uid}', white_color, sr_font_28, 'mm')
|
||||
img_draw.text((450, 442), f"UID {uid}", white_color, sr_font_28, "mm")
|
||||
|
||||
# 总体数据
|
||||
abyss_data = Image.open(TEXT_PATH / 'data.png')
|
||||
abyss_data = Image.open(TEXT_PATH / "data.png")
|
||||
img.paste(abyss_data, (0, 500), abyss_data)
|
||||
|
||||
# 最深抵达
|
||||
img_draw.text(
|
||||
(220, 565),
|
||||
f'{raw_abyss_data.max_floor}',
|
||||
f"{raw_abyss_data.max_floor}",
|
||||
white_color,
|
||||
sr_font_34,
|
||||
'lm',
|
||||
"lm",
|
||||
)
|
||||
# 挑战次数
|
||||
img_draw.text(
|
||||
(220, 612),
|
||||
f'{raw_abyss_data.battle_num}',
|
||||
f"{raw_abyss_data.battle_num}",
|
||||
white_color,
|
||||
sr_font_34,
|
||||
'lm',
|
||||
"lm",
|
||||
)
|
||||
|
||||
star_num_pic = Image.open(TEXT_PATH / 'star.png')
|
||||
star_num_pic = Image.open(TEXT_PATH / "star.png")
|
||||
img.paste(star_num_pic, (615, 557), star_num_pic)
|
||||
|
||||
img_draw.text(
|
||||
(695, 590),
|
||||
f'{raw_abyss_data.star_num}/36',
|
||||
f"{raw_abyss_data.star_num}/36",
|
||||
white_color,
|
||||
sr_font_42,
|
||||
'lm',
|
||||
"lm",
|
||||
)
|
||||
|
||||
for index_floor, level in enumerate(raw_abyss_data.all_floor_detail):
|
||||
floor_pic = Image.open(TEXT_PATH / 'floor_bg.png')
|
||||
floor_pic = Image.open(TEXT_PATH / "floor_bg.png")
|
||||
level_star = level.star_num
|
||||
floor_name = level.name
|
||||
round_num = level.round_num
|
||||
@ -211,23 +205,24 @@ async def draw_abyss_img(
|
||||
time_array = node_1.challenge_time
|
||||
else:
|
||||
time_array = node_2.challenge_time
|
||||
time_str = f'{time_array.year}-{time_array.month}'
|
||||
time_str = f'{time_str}-{time_array.day}'
|
||||
time_str = f'{time_str} {time_array.hour}:{time_array.minute}:00'
|
||||
assert time_array is not None
|
||||
time_str = f"{time_array.year}-{time_array.month}"
|
||||
time_str = f"{time_str}-{time_array.day}"
|
||||
time_str = f"{time_str} {time_array.hour}:{time_array.minute}:00"
|
||||
floor_pic_draw = ImageDraw.Draw(floor_pic)
|
||||
floor_pic_draw.text(
|
||||
(112, 120 + index_part * 219),
|
||||
f'节点{node_num}',
|
||||
f"节点{node_num}",
|
||||
white_color,
|
||||
sr_font_30,
|
||||
'lm',
|
||||
"lm",
|
||||
)
|
||||
floor_pic_draw.text(
|
||||
(201, 120 + index_part * 219),
|
||||
f'{time_str}',
|
||||
f"{time_str}",
|
||||
gray_color,
|
||||
sr_font_22,
|
||||
'lm',
|
||||
"lm",
|
||||
)
|
||||
if node_num == 1:
|
||||
avatars_array = node_1
|
||||
@ -251,5 +246,5 @@ async def draw_abyss_img(
|
||||
)
|
||||
|
||||
res = await convert_img(img)
|
||||
logger.info('[查询深渊信息]绘图已完成,等待发送!')
|
||||
logger.info("[查询深渊信息]绘图已完成,等待发送!")
|
||||
return res
|
||||
|
@ -6,14 +6,14 @@ from PIL import Image
|
||||
from aiohttp import ClientSession
|
||||
from gsuid_core.data_store import get_res_path
|
||||
|
||||
T = TypeVar('T')
|
||||
T = TypeVar("T")
|
||||
|
||||
ROLEINFO_PATH = get_res_path() / 'StarRailUID' / 'roleinfo'
|
||||
ROLEINFO_PATH = get_res_path() / "StarRailUID" / "roleinfo"
|
||||
ROLEINFO_PATH.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
|
||||
async def get_icon(url: str) -> Image.Image:
|
||||
name = url.split('/')[-1]
|
||||
name = url.split("/")[-1]
|
||||
path = ROLEINFO_PATH / name
|
||||
if (path).exists():
|
||||
content = path.read_bytes()
|
||||
@ -21,6 +21,6 @@ async def get_icon(url: str) -> Image.Image:
|
||||
async with ClientSession() as client:
|
||||
async with client.get(url) as resp:
|
||||
content = await resp.read()
|
||||
with Path.open(path, 'wb') as f:
|
||||
with Path.open(path, "wb") as f:
|
||||
f.write(content)
|
||||
return Image.open(BytesIO(content)).convert('RGBA')
|
||||
return Image.open(BytesIO(content)).convert("RGBA")
|
||||
|
@ -1,45 +1,43 @@
|
||||
import re
|
||||
|
||||
from gsuid_core.sv import SV
|
||||
from .draw_abyss_card import draw_abyss_img
|
||||
from ..utils.sr_prefix import PREFIX
|
||||
|
||||
from gsuid_core.bot import Bot
|
||||
from gsuid_core.models import Event
|
||||
from gsuid_core.sv import SV
|
||||
from gsuid_core.utils.database.api import get_uid
|
||||
from gsuid_core.utils.database.models import GsBind
|
||||
from gsuid_core.utils.error_reply import UID_HINT
|
||||
|
||||
from ..utils.convert import get_uid
|
||||
from ..utils.sr_prefix import PREFIX
|
||||
from .draw_abyss_card import draw_abyss_img
|
||||
|
||||
sv_abyss_boss = SV('sr查询末日幻影')
|
||||
sv_abyss_boss = SV("sr查询末日幻影")
|
||||
|
||||
|
||||
@sv_abyss_boss.on_command(
|
||||
(
|
||||
f'{PREFIX}查询末日幻影',
|
||||
f'{PREFIX}查询上期末日幻影',
|
||||
f'{PREFIX}上期末日',
|
||||
f'{PREFIX}末日',
|
||||
f"{PREFIX}查询末日幻影",
|
||||
f"{PREFIX}查询上期末日幻影",
|
||||
f"{PREFIX}上期末日",
|
||||
f"{PREFIX}末日",
|
||||
),
|
||||
block=True,
|
||||
)
|
||||
async def send_srabyss_info(bot: Bot, ev: Event):
|
||||
name = ''.join(re.findall('[\u4e00-\u9fa5]', ev.text))
|
||||
name = "".join(re.findall("[\u4e00-\u9fa5]", ev.text))
|
||||
if name:
|
||||
return None
|
||||
|
||||
await bot.logger.info('开始执行[sr查询末日幻影信息]')
|
||||
get_uid_ = await get_uid(bot, ev, True)
|
||||
if get_uid_ is None:
|
||||
return await bot.send(UID_HINT)
|
||||
uid, user_id = get_uid_
|
||||
await bot.logger.info("开始执行[sr查询末日幻影信息]")
|
||||
uid, user_id = await get_uid(bot, ev, GsBind, "sr", True)
|
||||
if uid is None:
|
||||
return await bot.send(UID_HINT)
|
||||
await bot.logger.info(f'[sr查询末日幻影信息]uid: {uid}')
|
||||
await bot.logger.info(f"[sr查询末日幻影信息]uid: {uid}")
|
||||
|
||||
if '上期' in ev.command:
|
||||
schedule_type = '2'
|
||||
if "上期" in ev.command:
|
||||
schedule_type = "2"
|
||||
else:
|
||||
schedule_type = '1'
|
||||
await bot.logger.info(f'[sr查询末日幻影信息]末日幻影期数: {schedule_type}')
|
||||
schedule_type = "1"
|
||||
await bot.logger.info(f"[sr查询末日幻影信息]末日幻影期数: {schedule_type}")
|
||||
|
||||
im = await draw_abyss_img(user_id, uid, ev.sender, schedule_type)
|
||||
await bot.send(im)
|
||||
|
@ -1,17 +1,7 @@
|
||||
from pathlib import Path
|
||||
from typing import Union, Optional
|
||||
|
||||
from PIL import Image, ImageDraw
|
||||
from gsuid_core.logger import logger
|
||||
from gsuid_core.utils.error_reply import get_error
|
||||
from gsuid_core.utils.image.image_tools import (
|
||||
get_qq_avatar,
|
||||
draw_pic_with_ring,
|
||||
)
|
||||
from typing import Any, Dict, Union
|
||||
|
||||
from .utils import get_icon
|
||||
from ..utils.mys_api import mys_api
|
||||
from ..utils.image.convert import convert_img
|
||||
from ..sruid_utils.api.mys.models import AbyssAvatar
|
||||
from ..utils.fonts.starrail_fonts import (
|
||||
sr_font_22,
|
||||
@ -20,39 +10,41 @@ from ..utils.fonts.starrail_fonts import (
|
||||
sr_font_34,
|
||||
sr_font_42,
|
||||
)
|
||||
from ..utils.mys_api import mys_api
|
||||
|
||||
TEXT_PATH = Path(__file__).parent / 'texture2D'
|
||||
from PIL import Image, ImageDraw
|
||||
from gsuid_core.logger import logger
|
||||
from gsuid_core.utils.error_reply import get_error
|
||||
from gsuid_core.utils.image.convert import convert_img
|
||||
from gsuid_core.utils.image.image_tools import (
|
||||
draw_pic_with_ring,
|
||||
get_qq_avatar,
|
||||
)
|
||||
|
||||
TEXT_PATH = Path(__file__).parent / "texture2D"
|
||||
white_color = (255, 255, 255)
|
||||
gray_color = (175, 175, 175)
|
||||
img_bg = Image.open(TEXT_PATH / 'bg.jpg')
|
||||
level_cover = Image.open(TEXT_PATH / 'level_cover.png').convert('RGBA')
|
||||
char_bg_4 = Image.open(TEXT_PATH / 'char4_bg.png').convert('RGBA')
|
||||
char_bg_5 = Image.open(TEXT_PATH / 'char5_bg.png').convert('RGBA')
|
||||
rank_bg = Image.open(TEXT_PATH / 'rank_bg.png').convert('RGBA')
|
||||
star_yes = Image.open(TEXT_PATH / 'star.png').convert('RGBA')
|
||||
star_gray = Image.open(TEXT_PATH / 'star_gray.png').convert('RGBA')
|
||||
img_bg = Image.open(TEXT_PATH / "bg.jpg")
|
||||
level_cover = Image.open(TEXT_PATH / "level_cover.png").convert("RGBA")
|
||||
char_bg_4 = Image.open(TEXT_PATH / "char4_bg.png").convert("RGBA")
|
||||
char_bg_5 = Image.open(TEXT_PATH / "char5_bg.png").convert("RGBA")
|
||||
rank_bg = Image.open(TEXT_PATH / "rank_bg.png").convert("RGBA")
|
||||
star_yes = Image.open(TEXT_PATH / "star.png").convert("RGBA")
|
||||
star_gray = Image.open(TEXT_PATH / "star_gray.png").convert("RGBA")
|
||||
|
||||
elements = {
|
||||
'ice': Image.open(TEXT_PATH / 'IconNatureColorIce.png').convert('RGBA'),
|
||||
'fire': Image.open(TEXT_PATH / 'IconNatureColorFire.png').convert('RGBA'),
|
||||
'imaginary': Image.open(
|
||||
TEXT_PATH / 'IconNatureColorImaginary.png'
|
||||
).convert('RGBA'),
|
||||
'quantum': Image.open(TEXT_PATH / 'IconNatureColorQuantum.png').convert(
|
||||
'RGBA'
|
||||
),
|
||||
'lightning': Image.open(TEXT_PATH / 'IconNatureColorThunder.png').convert(
|
||||
'RGBA'
|
||||
),
|
||||
'wind': Image.open(TEXT_PATH / 'IconNatureColorWind.png').convert('RGBA'),
|
||||
'physical': Image.open(TEXT_PATH / 'IconNaturePhysical.png').convert(
|
||||
'RGBA'
|
||||
),
|
||||
"ice": Image.open(TEXT_PATH / "IconNatureColorIce.png").convert("RGBA"),
|
||||
"fire": Image.open(TEXT_PATH / "IconNatureColorFire.png").convert("RGBA"),
|
||||
"imaginary": Image.open(TEXT_PATH / "IconNatureColorImaginary.png").convert("RGBA"),
|
||||
"quantum": Image.open(TEXT_PATH / "IconNatureColorQuantum.png").convert("RGBA"),
|
||||
"lightning": Image.open(TEXT_PATH / "IconNatureColorThunder.png").convert("RGBA"),
|
||||
"wind": Image.open(TEXT_PATH / "IconNatureColorWind.png").convert("RGBA"),
|
||||
"physical": Image.open(TEXT_PATH / "IconNaturePhysical.png").convert("RGBA"),
|
||||
}
|
||||
|
||||
|
||||
async def get_abyss_star_pic(star: int) -> Image.Image:
|
||||
return Image.open(TEXT_PATH / f'star{star}.png')
|
||||
return Image.open(TEXT_PATH / f"star{star}.png")
|
||||
|
||||
|
||||
async def _draw_abyss_card(
|
||||
@ -75,17 +67,17 @@ async def _draw_abyss_card(
|
||||
char_bg.paste(rank_bg, (150, 16), mask=rank_bg)
|
||||
char_card_draw.text(
|
||||
(162, 31),
|
||||
f'{char.rank}',
|
||||
f"{char.rank}",
|
||||
font=sr_font_22,
|
||||
fill=white_color,
|
||||
anchor='mm',
|
||||
anchor="mm",
|
||||
)
|
||||
char_card_draw.text(
|
||||
(100, 165),
|
||||
f'等级 {char.level}',
|
||||
f"等级 {char.level}",
|
||||
font=sr_font_22,
|
||||
fill=white_color,
|
||||
anchor='mm',
|
||||
anchor="mm",
|
||||
)
|
||||
floor_pic.paste(
|
||||
char_bg,
|
||||
@ -114,7 +106,7 @@ async def _draw_floor_card(
|
||||
floor_name,
|
||||
font=sr_font_42,
|
||||
fill=white_color,
|
||||
anchor='mm',
|
||||
anchor="mm",
|
||||
)
|
||||
img.paste(floor_pic, (0, 657 + index_floor * 570), floor_pic)
|
||||
|
||||
@ -122,18 +114,20 @@ async def _draw_floor_card(
|
||||
async def draw_abyss_img(
|
||||
qid: Union[str, int],
|
||||
uid: str,
|
||||
sender: Union[str, str],
|
||||
schedule_type: str = '1',
|
||||
sender: Dict[str, Any],
|
||||
schedule_type: str = "1",
|
||||
) -> Union[bytes, str]:
|
||||
raw_abyss_data = await mys_api.get_abyss_boss_info(uid, schedule_type)
|
||||
if isinstance(raw_abyss_data, int):
|
||||
return get_error(raw_abyss_data)
|
||||
|
||||
# 获取查询者数据
|
||||
if raw_abyss_data.max_floor == '':
|
||||
return '你还没有挑战本期末日幻影!\n可以使用[sr上期末日幻影]命令查询上期~'
|
||||
# 过滤掉 is_fast(快速通关) 为 True 的项
|
||||
floor_detail = [detail for detail in raw_abyss_data.all_floor_detail if not detail.is_fast]
|
||||
if raw_abyss_data.max_floor == "":
|
||||
return "你还没有挑战本期末日幻影!\n可以使用[sr上期末日幻影]命令查询上期~"
|
||||
# 过滤掉 is_fast (快速通关) 为 True 的项
|
||||
floor_detail = [
|
||||
detail for detail in raw_abyss_data.all_floor_detail if not detail.is_fast
|
||||
]
|
||||
floor_num = len(floor_detail)
|
||||
|
||||
# 获取背景图片各项参数
|
||||
@ -141,15 +135,15 @@ async def draw_abyss_img(
|
||||
based_h = 657 + 570 * floor_num
|
||||
img = img_bg.copy()
|
||||
img = img.crop((0, 0, based_w, based_h))
|
||||
abyss_title = Image.open(TEXT_PATH / 'head.png')
|
||||
abyss_title = Image.open(TEXT_PATH / "head.png")
|
||||
img.paste(abyss_title, (0, 0), abyss_title)
|
||||
|
||||
# 获取头像
|
||||
_id = str(qid)
|
||||
if _id.startswith('http'):
|
||||
if _id.startswith("http"):
|
||||
char_pic = await get_qq_avatar(avatar_url=_id)
|
||||
elif sender.get('avatar') is not None:
|
||||
char_pic = await get_qq_avatar(avatar_url=sender['avatar'])
|
||||
elif sender.get("avatar") is not None:
|
||||
char_pic = await get_qq_avatar(avatar_url=sender["avatar"])
|
||||
else:
|
||||
char_pic = await get_qq_avatar(qid=qid)
|
||||
char_pic = await draw_pic_with_ring(char_pic, 250, None, False)
|
||||
@ -158,42 +152,42 @@ async def draw_abyss_img(
|
||||
|
||||
# 绘制抬头
|
||||
img_draw = ImageDraw.Draw(img)
|
||||
img_draw.text((450, 442), f'UID {uid}', white_color, sr_font_28, 'mm')
|
||||
img_draw.text((450, 442), f"UID {uid}", white_color, sr_font_28, "mm")
|
||||
|
||||
# 总体数据
|
||||
abyss_data = Image.open(TEXT_PATH / 'data.png')
|
||||
abyss_data = Image.open(TEXT_PATH / "data.png")
|
||||
img.paste(abyss_data, (0, 500), abyss_data)
|
||||
|
||||
# 最深抵达
|
||||
img_draw.text(
|
||||
(220, 565),
|
||||
f'{raw_abyss_data.max_floor}',
|
||||
f"{raw_abyss_data.max_floor}",
|
||||
white_color,
|
||||
sr_font_34,
|
||||
'lm',
|
||||
"lm",
|
||||
)
|
||||
# 挑战次数
|
||||
img_draw.text(
|
||||
(220, 612),
|
||||
f'{raw_abyss_data.battle_num}',
|
||||
f"{raw_abyss_data.battle_num}",
|
||||
white_color,
|
||||
sr_font_34,
|
||||
'lm',
|
||||
"lm",
|
||||
)
|
||||
|
||||
star_num_pic = Image.open(TEXT_PATH / 'star.png')
|
||||
star_num_pic = Image.open(TEXT_PATH / "star.png")
|
||||
img.paste(star_num_pic, (615, 557), star_num_pic)
|
||||
|
||||
img_draw.text(
|
||||
(695, 590),
|
||||
f'{raw_abyss_data.star_num}/12',
|
||||
f"{raw_abyss_data.star_num}/12",
|
||||
white_color,
|
||||
sr_font_42,
|
||||
'lm',
|
||||
"lm",
|
||||
)
|
||||
|
||||
for index_floor, level in enumerate(floor_detail):
|
||||
floor_pic = Image.open(TEXT_PATH / 'floor_bg.png')
|
||||
floor_pic = Image.open(TEXT_PATH / "floor_bg.png")
|
||||
level_star = int(level.star_num)
|
||||
floor_name = level.name
|
||||
node_1 = level.node_1
|
||||
@ -204,23 +198,24 @@ async def draw_abyss_img(
|
||||
time_array = node_1.challenge_time
|
||||
else:
|
||||
time_array = node_2.challenge_time
|
||||
time_str = f'{time_array.year}-{time_array.month}'
|
||||
time_str = f'{time_str}-{time_array.day}'
|
||||
time_str = f'{time_str} {time_array.hour}:{time_array.minute}:00'
|
||||
assert time_array is not None
|
||||
time_str = f"{time_array.year}-{time_array.month}"
|
||||
time_str = f"{time_str}-{time_array.day}"
|
||||
time_str = f"{time_str} {time_array.hour}:{time_array.minute}:00"
|
||||
floor_pic_draw = ImageDraw.Draw(floor_pic)
|
||||
floor_pic_draw.text(
|
||||
(112, 120 + index_part * 219),
|
||||
f'节点{node_num}',
|
||||
f"节点{node_num}",
|
||||
white_color,
|
||||
sr_font_30,
|
||||
'lm',
|
||||
"lm",
|
||||
)
|
||||
floor_pic_draw.text(
|
||||
(201, 120 + index_part * 219),
|
||||
f'{time_str}',
|
||||
f"{time_str}",
|
||||
gray_color,
|
||||
sr_font_22,
|
||||
'lm',
|
||||
"lm",
|
||||
)
|
||||
if node_num == 1:
|
||||
avatars_array = node_1
|
||||
@ -240,9 +235,8 @@ async def draw_abyss_img(
|
||||
img,
|
||||
index_floor,
|
||||
floor_name,
|
||||
|
||||
)
|
||||
|
||||
res = await convert_img(img)
|
||||
logger.info('[查询末日幻影信息]绘图已完成,等待发送!')
|
||||
logger.info("[查询末日幻影信息]绘图已完成,等待发送!")
|
||||
return res
|
||||
|
@ -6,14 +6,14 @@ from PIL import Image
|
||||
from aiohttp import ClientSession
|
||||
from gsuid_core.data_store import get_res_path
|
||||
|
||||
T = TypeVar('T')
|
||||
T = TypeVar("T")
|
||||
|
||||
ROLEINFO_PATH = get_res_path() / 'StarRailUID' / 'roleinfo'
|
||||
ROLEINFO_PATH = get_res_path() / "StarRailUID" / "roleinfo"
|
||||
ROLEINFO_PATH.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
|
||||
async def get_icon(url: str) -> Image.Image:
|
||||
name = url.split('/')[-1]
|
||||
name = url.split("/")[-1]
|
||||
path = ROLEINFO_PATH / name
|
||||
if (path).exists():
|
||||
content = path.read_bytes()
|
||||
@ -21,6 +21,6 @@ async def get_icon(url: str) -> Image.Image:
|
||||
async with ClientSession() as client:
|
||||
async with client.get(url) as resp:
|
||||
content = await resp.read()
|
||||
with Path.open(path, 'wb') as f:
|
||||
with Path.open(path, "wb") as f:
|
||||
f.write(content)
|
||||
return Image.open(BytesIO(content)).convert('RGBA')
|
||||
return Image.open(BytesIO(content)).convert("RGBA")
|
||||
|
@ -1,47 +1,45 @@
|
||||
import re
|
||||
|
||||
from gsuid_core.sv import SV
|
||||
from .draw_abyss_card import draw_abyss_img
|
||||
from ..utils.sr_prefix import PREFIX
|
||||
|
||||
from gsuid_core.bot import Bot
|
||||
from gsuid_core.models import Event
|
||||
from gsuid_core.sv import SV
|
||||
from gsuid_core.utils.database.api import get_uid
|
||||
from gsuid_core.utils.database.models import GsBind
|
||||
from gsuid_core.utils.error_reply import UID_HINT
|
||||
|
||||
from ..utils.convert import get_uid
|
||||
from ..utils.sr_prefix import PREFIX
|
||||
from .draw_abyss_card import draw_abyss_img
|
||||
|
||||
sv_abyss_story = SV('sr查询虚构叙事')
|
||||
sv_abyss_story = SV("sr查询虚构叙事")
|
||||
|
||||
|
||||
@sv_abyss_story.on_command(
|
||||
(
|
||||
f'{PREFIX}查询虚构叙事',
|
||||
f'{PREFIX}xg',
|
||||
f'{PREFIX}查询上期虚构叙事',
|
||||
f'{PREFIX}sqxg',
|
||||
f'{PREFIX}上期虚构',
|
||||
f'{PREFIX}虚构',
|
||||
f"{PREFIX}查询虚构叙事",
|
||||
f"{PREFIX}xg",
|
||||
f"{PREFIX}查询上期虚构叙事",
|
||||
f"{PREFIX}sqxg",
|
||||
f"{PREFIX}上期虚构",
|
||||
f"{PREFIX}虚构",
|
||||
),
|
||||
block=True,
|
||||
)
|
||||
async def send_srabyss_info(bot: Bot, ev: Event):
|
||||
name = ''.join(re.findall('[\u4e00-\u9fa5]', ev.text))
|
||||
name = "".join(re.findall("[\u4e00-\u9fa5]", ev.text))
|
||||
if name:
|
||||
return None
|
||||
|
||||
await bot.logger.info('开始执行[sr查询虚构叙事信息]')
|
||||
get_uid_ = await get_uid(bot, ev, True)
|
||||
if get_uid_ is None:
|
||||
return await bot.send(UID_HINT)
|
||||
uid, user_id = get_uid_
|
||||
await bot.logger.info("开始执行[sr查询虚构叙事信息]")
|
||||
uid, user_id = await get_uid(bot, ev, GsBind, "sr", True)
|
||||
if uid is None:
|
||||
return await bot.send(UID_HINT)
|
||||
await bot.logger.info(f'[sr查询虚构叙事信息]uid: {uid}')
|
||||
await bot.logger.info(f"[sr查询虚构叙事信息]uid: {uid}")
|
||||
|
||||
if 'sq' in ev.command or '上期' in ev.command:
|
||||
schedule_type = '2'
|
||||
if "sq" in ev.command or "上期" in ev.command:
|
||||
schedule_type = "2"
|
||||
else:
|
||||
schedule_type = '1'
|
||||
await bot.logger.info(f'[sr查询虚构叙事信息]虚构叙事期数: {schedule_type}')
|
||||
schedule_type = "1"
|
||||
await bot.logger.info(f"[sr查询虚构叙事信息]虚构叙事期数: {schedule_type}")
|
||||
|
||||
im = await draw_abyss_img(user_id, uid, ev.sender, schedule_type)
|
||||
await bot.send(im)
|
||||
|
@ -1,17 +1,7 @@
|
||||
from pathlib import Path
|
||||
from typing import Union, Optional
|
||||
|
||||
from PIL import Image, ImageDraw
|
||||
from gsuid_core.logger import logger
|
||||
from gsuid_core.utils.error_reply import get_error
|
||||
from gsuid_core.utils.image.image_tools import (
|
||||
get_qq_avatar,
|
||||
draw_pic_with_ring,
|
||||
)
|
||||
from typing import Any, Dict, Union
|
||||
|
||||
from .utils import get_icon
|
||||
from ..utils.mys_api import mys_api
|
||||
from ..utils.image.convert import convert_img
|
||||
from ..sruid_utils.api.mys.models import AbyssAvatar
|
||||
from ..utils.fonts.starrail_fonts import (
|
||||
sr_font_22,
|
||||
@ -20,39 +10,41 @@ from ..utils.fonts.starrail_fonts import (
|
||||
sr_font_34,
|
||||
sr_font_42,
|
||||
)
|
||||
from ..utils.mys_api import mys_api
|
||||
|
||||
TEXT_PATH = Path(__file__).parent / 'texture2D'
|
||||
from PIL import Image, ImageDraw
|
||||
from gsuid_core.logger import logger
|
||||
from gsuid_core.utils.error_reply import get_error
|
||||
from gsuid_core.utils.image.convert import convert_img
|
||||
from gsuid_core.utils.image.image_tools import (
|
||||
draw_pic_with_ring,
|
||||
get_qq_avatar,
|
||||
)
|
||||
|
||||
TEXT_PATH = Path(__file__).parent / "texture2D"
|
||||
white_color = (255, 255, 255)
|
||||
gray_color = (175, 175, 175)
|
||||
img_bg = Image.open(TEXT_PATH / 'bg.jpg')
|
||||
level_cover = Image.open(TEXT_PATH / 'level_cover.png').convert('RGBA')
|
||||
char_bg_4 = Image.open(TEXT_PATH / 'char4_bg.png').convert('RGBA')
|
||||
char_bg_5 = Image.open(TEXT_PATH / 'char5_bg.png').convert('RGBA')
|
||||
rank_bg = Image.open(TEXT_PATH / 'rank_bg.png').convert('RGBA')
|
||||
star_yes = Image.open(TEXT_PATH / 'star.png').convert('RGBA')
|
||||
star_gray = Image.open(TEXT_PATH / 'star_gray.png').convert('RGBA')
|
||||
img_bg = Image.open(TEXT_PATH / "bg.jpg")
|
||||
level_cover = Image.open(TEXT_PATH / "level_cover.png").convert("RGBA")
|
||||
char_bg_4 = Image.open(TEXT_PATH / "char4_bg.png").convert("RGBA")
|
||||
char_bg_5 = Image.open(TEXT_PATH / "char5_bg.png").convert("RGBA")
|
||||
rank_bg = Image.open(TEXT_PATH / "rank_bg.png").convert("RGBA")
|
||||
star_yes = Image.open(TEXT_PATH / "star.png").convert("RGBA")
|
||||
star_gray = Image.open(TEXT_PATH / "star_gray.png").convert("RGBA")
|
||||
|
||||
elements = {
|
||||
'ice': Image.open(TEXT_PATH / 'IconNatureColorIce.png').convert('RGBA'),
|
||||
'fire': Image.open(TEXT_PATH / 'IconNatureColorFire.png').convert('RGBA'),
|
||||
'imaginary': Image.open(
|
||||
TEXT_PATH / 'IconNatureColorImaginary.png'
|
||||
).convert('RGBA'),
|
||||
'quantum': Image.open(TEXT_PATH / 'IconNatureColorQuantum.png').convert(
|
||||
'RGBA'
|
||||
),
|
||||
'lightning': Image.open(TEXT_PATH / 'IconNatureColorThunder.png').convert(
|
||||
'RGBA'
|
||||
),
|
||||
'wind': Image.open(TEXT_PATH / 'IconNatureColorWind.png').convert('RGBA'),
|
||||
'physical': Image.open(TEXT_PATH / 'IconNaturePhysical.png').convert(
|
||||
'RGBA'
|
||||
),
|
||||
"ice": Image.open(TEXT_PATH / "IconNatureColorIce.png").convert("RGBA"),
|
||||
"fire": Image.open(TEXT_PATH / "IconNatureColorFire.png").convert("RGBA"),
|
||||
"imaginary": Image.open(TEXT_PATH / "IconNatureColorImaginary.png").convert("RGBA"),
|
||||
"quantum": Image.open(TEXT_PATH / "IconNatureColorQuantum.png").convert("RGBA"),
|
||||
"lightning": Image.open(TEXT_PATH / "IconNatureColorThunder.png").convert("RGBA"),
|
||||
"wind": Image.open(TEXT_PATH / "IconNatureColorWind.png").convert("RGBA"),
|
||||
"physical": Image.open(TEXT_PATH / "IconNaturePhysical.png").convert("RGBA"),
|
||||
}
|
||||
|
||||
|
||||
async def get_abyss_star_pic(star: int) -> Image.Image:
|
||||
return Image.open(TEXT_PATH / f'star{star}.png')
|
||||
return Image.open(TEXT_PATH / f"star{star}.png")
|
||||
|
||||
|
||||
async def _draw_abyss_card(
|
||||
@ -76,10 +68,10 @@ async def _draw_abyss_card(
|
||||
char_bg.paste(rank_bg, (150, 16), mask=rank_bg)
|
||||
char_card_draw.text(
|
||||
(162, 31),
|
||||
f'{char.rank}',
|
||||
f"{char.rank}",
|
||||
font=sr_font_22,
|
||||
fill=white_color,
|
||||
anchor='mm',
|
||||
anchor="mm",
|
||||
)
|
||||
# 不存在自动下载
|
||||
# if not char_pic_path.exists():
|
||||
@ -89,10 +81,10 @@ async def _draw_abyss_card(
|
||||
# char_card.paste(talent_pic, (137, 260), talent_pic)
|
||||
char_card_draw.text(
|
||||
(100, 165),
|
||||
f'等级 {char.level}',
|
||||
f"等级 {char.level}",
|
||||
font=sr_font_22,
|
||||
fill=white_color,
|
||||
anchor='mm',
|
||||
anchor="mm",
|
||||
)
|
||||
floor_pic.paste(
|
||||
char_bg,
|
||||
@ -102,16 +94,16 @@ async def _draw_abyss_card(
|
||||
|
||||
|
||||
async def _draw_floor_card(
|
||||
level_star: int,
|
||||
level_star: Union[int, str],
|
||||
floor_pic: Image.Image,
|
||||
img: Image.Image,
|
||||
index_floor: int,
|
||||
floor_name: str,
|
||||
round_num: int,
|
||||
round_num: Union[int, None],
|
||||
):
|
||||
for index_num in [0, 1, 2]:
|
||||
star_num = index_num + 1
|
||||
if star_num <= level_star:
|
||||
if star_num <= int(level_star):
|
||||
star_pic = star_yes.copy()
|
||||
else:
|
||||
star_pic = star_gray.copy()
|
||||
@ -122,14 +114,14 @@ async def _draw_floor_card(
|
||||
floor_name,
|
||||
font=sr_font_42,
|
||||
fill=white_color,
|
||||
anchor='mm',
|
||||
anchor="mm",
|
||||
)
|
||||
floor_pic_draw.text(
|
||||
(802, 60),
|
||||
f'使用轮: {round_num}',
|
||||
f"使用轮: {round_num}",
|
||||
font=sr_font_28,
|
||||
fill=gray_color,
|
||||
anchor='rm',
|
||||
anchor="rm",
|
||||
)
|
||||
img.paste(floor_pic, (0, 657 + index_floor * 570), floor_pic)
|
||||
|
||||
@ -137,18 +129,20 @@ async def _draw_floor_card(
|
||||
async def draw_abyss_img(
|
||||
qid: Union[str, int],
|
||||
uid: str,
|
||||
sender: Union[str, str],
|
||||
schedule_type: str = '1',
|
||||
sender: Dict[str, Any],
|
||||
schedule_type: str = "1",
|
||||
) -> Union[bytes, str]:
|
||||
raw_abyss_data = await mys_api.get_abyss_story_info(uid, schedule_type)
|
||||
if isinstance(raw_abyss_data, int):
|
||||
return get_error(raw_abyss_data)
|
||||
|
||||
# 获取查询者数据
|
||||
if raw_abyss_data.max_floor == '':
|
||||
return '你还没有挑战本期虚构叙事!\n可以使用[sr上期虚构叙事]命令查询上期~'
|
||||
# 过滤掉 is_fast(快速通关) 为 True 的项
|
||||
floor_detail = [detail for detail in raw_abyss_data.all_floor_detail if not detail.is_fast]
|
||||
if raw_abyss_data.max_floor == "":
|
||||
return "你还没有挑战本期虚构叙事!\n可以使用[sr上期虚构叙事]命令查询上期~"
|
||||
# 过滤掉 is_fast (快速通关) 为 True 的项
|
||||
floor_detail = [
|
||||
detail for detail in raw_abyss_data.all_floor_detail if not detail.is_fast
|
||||
]
|
||||
floor_num = len(floor_detail)
|
||||
|
||||
# 获取背景图片各项参数
|
||||
@ -156,15 +150,15 @@ async def draw_abyss_img(
|
||||
based_h = 657 + 570 * floor_num
|
||||
img = img_bg.copy()
|
||||
img = img.crop((0, 0, based_w, based_h))
|
||||
abyss_title = Image.open(TEXT_PATH / 'head.png')
|
||||
abyss_title = Image.open(TEXT_PATH / "head.png")
|
||||
img.paste(abyss_title, (0, 0), abyss_title)
|
||||
|
||||
# 获取头像
|
||||
_id = str(qid)
|
||||
if _id.startswith('http'):
|
||||
if _id.startswith("http"):
|
||||
char_pic = await get_qq_avatar(avatar_url=_id)
|
||||
elif sender.get('avatar') is not None:
|
||||
char_pic = await get_qq_avatar(avatar_url=sender['avatar'])
|
||||
elif sender.get("avatar") is not None:
|
||||
char_pic = await get_qq_avatar(avatar_url=sender["avatar"])
|
||||
else:
|
||||
char_pic = await get_qq_avatar(qid=qid)
|
||||
char_pic = await draw_pic_with_ring(char_pic, 250, None, False)
|
||||
@ -173,42 +167,42 @@ async def draw_abyss_img(
|
||||
|
||||
# 绘制抬头
|
||||
img_draw = ImageDraw.Draw(img)
|
||||
img_draw.text((450, 442), f'UID {uid}', white_color, sr_font_28, 'mm')
|
||||
img_draw.text((450, 442), f"UID {uid}", white_color, sr_font_28, "mm")
|
||||
|
||||
# 总体数据
|
||||
abyss_data = Image.open(TEXT_PATH / 'data.png')
|
||||
abyss_data = Image.open(TEXT_PATH / "data.png")
|
||||
img.paste(abyss_data, (0, 500), abyss_data)
|
||||
|
||||
# 最深抵达
|
||||
img_draw.text(
|
||||
(220, 565),
|
||||
f'{raw_abyss_data.max_floor}',
|
||||
f"{raw_abyss_data.max_floor}",
|
||||
white_color,
|
||||
sr_font_34,
|
||||
'lm',
|
||||
"lm",
|
||||
)
|
||||
# 挑战次数
|
||||
img_draw.text(
|
||||
(220, 612),
|
||||
f'{raw_abyss_data.battle_num}',
|
||||
f"{raw_abyss_data.battle_num}",
|
||||
white_color,
|
||||
sr_font_34,
|
||||
'lm',
|
||||
"lm",
|
||||
)
|
||||
|
||||
star_num_pic = Image.open(TEXT_PATH / 'star.png')
|
||||
star_num_pic = Image.open(TEXT_PATH / "star.png")
|
||||
img.paste(star_num_pic, (615, 557), star_num_pic)
|
||||
|
||||
img_draw.text(
|
||||
(695, 590),
|
||||
f'{raw_abyss_data.star_num}/12',
|
||||
f"{raw_abyss_data.star_num}/12",
|
||||
white_color,
|
||||
sr_font_42,
|
||||
'lm',
|
||||
"lm",
|
||||
)
|
||||
|
||||
for index_floor, level in enumerate(raw_abyss_data.all_floor_detail):
|
||||
floor_pic = Image.open(TEXT_PATH / 'floor_bg.png')
|
||||
floor_pic = Image.open(TEXT_PATH / "floor_bg.png")
|
||||
level_star = level.star_num
|
||||
floor_name = level.name
|
||||
round_num = level.round_num
|
||||
@ -220,23 +214,24 @@ async def draw_abyss_img(
|
||||
time_array = node_1.challenge_time
|
||||
else:
|
||||
time_array = node_2.challenge_time
|
||||
time_str = f'{time_array.year}-{time_array.month}'
|
||||
time_str = f'{time_str}-{time_array.day}'
|
||||
time_str = f'{time_str} {time_array.hour}:{time_array.minute}:00'
|
||||
assert time_array is not None
|
||||
time_str = f"{time_array.year}-{time_array.month}"
|
||||
time_str = f"{time_str}-{time_array.day}"
|
||||
time_str = f"{time_str} {time_array.hour}:{time_array.minute}:00"
|
||||
floor_pic_draw = ImageDraw.Draw(floor_pic)
|
||||
floor_pic_draw.text(
|
||||
(112, 120 + index_part * 219),
|
||||
f'节点{node_num}',
|
||||
f"节点{node_num}",
|
||||
white_color,
|
||||
sr_font_30,
|
||||
'lm',
|
||||
"lm",
|
||||
)
|
||||
floor_pic_draw.text(
|
||||
(201, 120 + index_part * 219),
|
||||
f'{time_str}',
|
||||
f"{time_str}",
|
||||
gray_color,
|
||||
sr_font_22,
|
||||
'lm',
|
||||
"lm",
|
||||
)
|
||||
if node_num == 1:
|
||||
avatars_array = node_1
|
||||
@ -261,5 +256,5 @@ async def draw_abyss_img(
|
||||
)
|
||||
|
||||
res = await convert_img(img)
|
||||
logger.info('[查询虚构叙事信息]绘图已完成,等待发送!')
|
||||
logger.info("[查询虚构叙事信息]绘图已完成,等待发送!")
|
||||
return res
|
||||
|
@ -6,14 +6,14 @@ from PIL import Image
|
||||
from aiohttp import ClientSession
|
||||
from gsuid_core.data_store import get_res_path
|
||||
|
||||
T = TypeVar('T')
|
||||
T = TypeVar("T")
|
||||
|
||||
ROLEINFO_PATH = get_res_path() / 'StarRailUID' / 'roleinfo'
|
||||
ROLEINFO_PATH = get_res_path() / "StarRailUID" / "roleinfo"
|
||||
ROLEINFO_PATH.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
|
||||
async def get_icon(url: str) -> Image.Image:
|
||||
name = url.split('/')[-1]
|
||||
name = url.split("/")[-1]
|
||||
path = ROLEINFO_PATH / name
|
||||
if (path).exists():
|
||||
content = path.read_bytes()
|
||||
@ -21,6 +21,6 @@ async def get_icon(url: str) -> Image.Image:
|
||||
async with ClientSession() as client:
|
||||
async with client.get(url) as resp:
|
||||
content = await resp.read()
|
||||
with Path.open(path, 'wb') as f:
|
||||
with Path.open(path, "wb") as f:
|
||||
f.write(content)
|
||||
return Image.open(BytesIO(content)).convert('RGBA')
|
||||
return Image.open(BytesIO(content)).convert("RGBA")
|
||||
|
@ -1,6 +1,5 @@
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from ..utils.convert import get_uid
|
||||
from ..utils.error_reply import UID_HINT
|
||||
from ..utils.map.name_covert import (
|
||||
alias_to_char_name,
|
||||
@ -10,26 +9,29 @@ from ..utils.mys_api import mys_api
|
||||
from ..utils.sr_prefix import PREFIX
|
||||
|
||||
from gsuid_core.sv import SV
|
||||
from gsuid_core.utils.database.api import get_uid
|
||||
from gsuid_core.utils.database.models import GsBind
|
||||
from gsuid_core.utils.error_reply import get_error
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from gsuid_core.bot import Bot
|
||||
from gsuid_core.models import Event
|
||||
|
||||
sv_char_calc = SV('sr养成计算')
|
||||
sv_char_calc = SV("sr养成计算")
|
||||
|
||||
|
||||
@sv_char_calc.on_command(f'{PREFIX}养成计算', block=True)
|
||||
async def send_char_calc_info(bot: 'Bot', ev: 'Event'):
|
||||
@sv_char_calc.on_command(f"{PREFIX}养成计算", block=True)
|
||||
async def send_char_calc_info(bot: "Bot", ev: "Event"):
|
||||
name = ev.text.strip()
|
||||
char_id = await name_to_avatar_id(name)
|
||||
if char_id == '':
|
||||
if char_id == "":
|
||||
result_fake_name = await alias_to_char_name(name)
|
||||
if result_fake_name is None:
|
||||
return '请输入正确的角色名'
|
||||
return "请输入正确的角色名"
|
||||
fake_name = result_fake_name
|
||||
char_id = await name_to_avatar_id(fake_name)
|
||||
uid = await get_uid(bot, ev, only_uid=True)
|
||||
|
||||
uid = await get_uid(bot, ev, GsBind, "sr")
|
||||
|
||||
if uid is None:
|
||||
return await bot.send(UID_HINT)
|
||||
@ -39,8 +41,6 @@ async def send_char_calc_info(bot: 'Bot', ev: 'Event'):
|
||||
avatar_skills = avatar_detail.skills + avatar_detail.skills_other
|
||||
skill_list = []
|
||||
for skill in avatar_skills:
|
||||
skill_list.append(
|
||||
f'{skill.point_id}({skill.cur_level}/{skill.max_level})'
|
||||
)
|
||||
skill_list.append(f"{skill.point_id}({skill.cur_level}/{skill.max_level})")
|
||||
|
||||
return None
|
||||
|
@ -1,28 +1,29 @@
|
||||
import re
|
||||
from pathlib import Path
|
||||
import re
|
||||
from typing import Tuple, cast
|
||||
|
||||
from .get_char_img import draw_char_info_img
|
||||
from .to_card import api_to_card
|
||||
from ..utils.error_reply import UID_HINT
|
||||
from ..utils.resource.RESOURCE_PATH import TEMP_PATH
|
||||
from ..utils.sr_prefix import PREFIX
|
||||
|
||||
from PIL import Image
|
||||
from gsuid_core.sv import SV
|
||||
from gsuid_core.bot import Bot
|
||||
from gsuid_core.models import Event
|
||||
from gsuid_core.message_models import Button
|
||||
from gsuid_core.models import Event
|
||||
from gsuid_core.sv import SV
|
||||
from gsuid_core.utils.database.api import get_uid
|
||||
from gsuid_core.utils.database.models import GsBind
|
||||
from gsuid_core.utils.image.convert import convert_img
|
||||
from starrail_damage_cal.map.SR_MAP_PATH import avatarId2Name
|
||||
|
||||
from .to_card import api_to_card
|
||||
from ..utils.convert import get_uid
|
||||
from ..utils.sr_prefix import PREFIX
|
||||
from ..utils.error_reply import UID_HINT
|
||||
from .get_char_img import draw_char_info_img
|
||||
from ..utils.image.convert import convert_img
|
||||
from ..utils.resource.RESOURCE_PATH import TEMP_PATH
|
||||
|
||||
sv_char_info_config = SV('sr面板设置', pm=2)
|
||||
sv_get_char_info = SV('sr面板查询', priority=10)
|
||||
sv_get_sr_original_pic = SV('sr查看面板原图', priority=5)
|
||||
sv_char_info_config = SV("sr面板设置", pm=2)
|
||||
sv_get_char_info = SV("sr面板查询", priority=10)
|
||||
sv_get_sr_original_pic = SV("sr查看面板原图", priority=5)
|
||||
|
||||
|
||||
@sv_get_char_info.on_prefix(f'{PREFIX}查询')
|
||||
@sv_get_char_info.on_prefix(f"{PREFIX}查询")
|
||||
async def send_char_info(bot: Bot, ev: Event):
|
||||
name = ev.text.strip()
|
||||
im = await _get_char_info(bot, ev, ev.text)
|
||||
@ -36,12 +37,12 @@ async def send_char_info(bot: Bot, ev: Event):
|
||||
await bot.send_option(
|
||||
img,
|
||||
[
|
||||
Button('🔄更换武器', f'sr查询{name}换', action=2),
|
||||
Button('⏫提高命座', f'sr查询六魂{name}', action=2),
|
||||
Button("🔄更换武器", f"sr查询{name}换", action=2),
|
||||
Button("⏫提高命座", f"sr查询六魂{name}", action=2),
|
||||
],
|
||||
)
|
||||
if im[1]:
|
||||
with Path.open(TEMP_PATH / f'{ev.msg_id}.jpg', 'wb') as f:
|
||||
with Path.open(TEMP_PATH / f"{ev.msg_id}.jpg", "wb") as f:
|
||||
f.write(cast(bytes, im[1]))
|
||||
elif isinstance(im, Image.Image):
|
||||
await bot.send(await convert_img(im))
|
||||
@ -50,14 +51,14 @@ async def send_char_info(bot: Bot, ev: Event):
|
||||
await bot.send_option(
|
||||
im,
|
||||
[
|
||||
Button('🔄更换武器', f'sr查询{name}换', action=2),
|
||||
Button('⏫提高命座', f'sr查询六魂{name}', action=2),
|
||||
Button("🔄更换武器", f"sr查询{name}换", action=2),
|
||||
Button("⏫提高命座", f"sr查询六魂{name}", action=2),
|
||||
],
|
||||
)
|
||||
elif im is None:
|
||||
return
|
||||
else:
|
||||
await bot.send('发生未知错误')
|
||||
await bot.send("发生未知错误")
|
||||
|
||||
|
||||
async def _get_char_info(bot: Bot, ev: Event, text: str):
|
||||
@ -66,33 +67,33 @@ async def _get_char_info(bot: Bot, ev: Event, text: str):
|
||||
if not msg:
|
||||
return None
|
||||
# 获取角色名
|
||||
await bot.logger.info('开始执行[查询角色面板]')
|
||||
await bot.logger.info("开始执行[查询角色面板]")
|
||||
# 获取uid
|
||||
if '换' in msg or '拿' in msg or '带' in msg:
|
||||
uid = await get_uid(bot, ev, False, True)
|
||||
if "换" in msg or "拿" in msg or "带" in msg:
|
||||
uid = await get_uid(bot, ev, GsBind, "sr", False)
|
||||
else:
|
||||
uid = await get_uid(bot, ev)
|
||||
msg = ' '.join(re.findall('[\u4e00-\u9fa5]+', text))
|
||||
uid = await get_uid(bot, ev, GsBind, "sr")
|
||||
msg = " ".join(re.findall("[\u4e00-\u9fa5]+", text))
|
||||
if uid is None:
|
||||
return await bot.send(UID_HINT)
|
||||
await bot.logger.info(f'[查询角色面板]uid: {uid}')
|
||||
await bot.logger.info(f"[查询角色面板]uid: {uid}")
|
||||
|
||||
return await draw_char_info_img(msg, uid)
|
||||
|
||||
|
||||
@sv_get_char_info.on_command(f'{PREFIX}强制刷新')
|
||||
@sv_get_char_info.on_command(f"{PREFIX}强制刷新")
|
||||
async def send_card_info(bot: Bot, ev: Event):
|
||||
uid = await get_uid(bot, ev)
|
||||
uid = await get_uid(bot, ev, GsBind, "sr")
|
||||
if uid is None:
|
||||
return await bot.send(UID_HINT)
|
||||
await bot.logger.info(f'[sr强制刷新]uid: {uid}')
|
||||
await bot.logger.info(f"[sr强制刷新]uid: {uid}")
|
||||
im = await api_to_card(uid)
|
||||
await bot.logger.info(f'UID{uid}获取角色数据成功!')
|
||||
await bot.logger.info(f"UID{uid}获取角色数据成功!")
|
||||
if isinstance(im, Tuple):
|
||||
buttons = [
|
||||
Button(
|
||||
f'✅查询{avatarId2Name[str(avatarid)]}',
|
||||
f'sr查询{avatarId2Name[str(avatarid)]}',
|
||||
f"✅查询{avatarId2Name[str(avatarid)]}",
|
||||
f"sr查询{avatarId2Name[str(avatarid)]}",
|
||||
)
|
||||
for avatarid in im[1]
|
||||
]
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,67 +1,67 @@
|
||||
import re
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Dict, Tuple, Union, Optional
|
||||
import re
|
||||
from typing import Dict, Optional, Tuple, Union
|
||||
|
||||
from .draw_char_img import draw_char_img
|
||||
from ..utils.error_reply import CHAR_HINT
|
||||
from ..utils.map.SR_MAP_PATH import (
|
||||
AvatarRankSkillUp,
|
||||
EquipmentID2Name,
|
||||
EquipmentID2Rarity,
|
||||
Property2Name,
|
||||
avatarId2DamageType,
|
||||
avatarId2EnName,
|
||||
avatarId2Name,
|
||||
avatarId2Rarity,
|
||||
characterSkillTree,
|
||||
rankId2Name,
|
||||
skillId2AttackType,
|
||||
skillId2Effect,
|
||||
skillId2Name,
|
||||
)
|
||||
from ..utils.map.name_covert import (
|
||||
alias_to_char_name,
|
||||
alias_to_weapon_name,
|
||||
name_to_avatar_id,
|
||||
name_to_weapon_id,
|
||||
)
|
||||
from ..utils.resource.RESOURCE_PATH import PLAYER_PATH
|
||||
|
||||
from gsuid_core.logger import logger
|
||||
from starrail_damage_cal.to_data import api_to_dict
|
||||
from starrail_damage_cal.excel.model import (
|
||||
AvatarPromotionConfig,
|
||||
EquipmentPromotionConfig,
|
||||
)
|
||||
|
||||
from .draw_char_img import draw_char_img
|
||||
from ..utils.error_reply import CHAR_HINT
|
||||
from ..utils.resource.RESOURCE_PATH import PLAYER_PATH
|
||||
from ..utils.map.name_covert import (
|
||||
name_to_avatar_id,
|
||||
name_to_weapon_id,
|
||||
alias_to_char_name,
|
||||
alias_to_weapon_name,
|
||||
)
|
||||
from ..utils.map.SR_MAP_PATH import (
|
||||
Property2Name,
|
||||
EquipmentID2Name,
|
||||
AvatarRankSkillUp,
|
||||
EquipmentID2Rarity,
|
||||
rankId2Name,
|
||||
skillId2Name,
|
||||
avatarId2Name,
|
||||
skillId2Effect,
|
||||
avatarId2EnName,
|
||||
avatarId2Rarity,
|
||||
characterSkillTree,
|
||||
skillId2AttackType,
|
||||
avatarId2DamageType,
|
||||
)
|
||||
from starrail_damage_cal.to_data import api_to_dict
|
||||
|
||||
WEAPON_TO_INT = {
|
||||
'一': 1,
|
||||
'二': 2,
|
||||
'三': 3,
|
||||
'四': 4,
|
||||
'五': 5,
|
||||
'满': 5,
|
||||
"一": 1,
|
||||
"二": 2,
|
||||
"三": 3,
|
||||
"四": 4,
|
||||
"五": 5,
|
||||
"满": 5,
|
||||
}
|
||||
|
||||
CHAR_TO_INT = {
|
||||
'零': 0,
|
||||
'一': 1,
|
||||
'二': 2,
|
||||
'三': 3,
|
||||
'四': 4,
|
||||
'五': 5,
|
||||
'六': 6,
|
||||
'满': 6,
|
||||
"零": 0,
|
||||
"一": 1,
|
||||
"二": 2,
|
||||
"三": 3,
|
||||
"四": 4,
|
||||
"五": 5,
|
||||
"六": 6,
|
||||
"满": 6,
|
||||
}
|
||||
|
||||
PieceName_ilst = {
|
||||
0: ['头', '帽'],
|
||||
1: ['手'],
|
||||
2: ['衣', '服', '躯'],
|
||||
3: ['鞋', '腿'],
|
||||
4: ['球'],
|
||||
5: ['绳', '链'],
|
||||
0: ["头", "帽"],
|
||||
1: ["手"],
|
||||
2: ["衣", "服", "躯"],
|
||||
3: ["鞋", "腿"],
|
||||
4: ["球"],
|
||||
5: ["绳", "链"],
|
||||
}
|
||||
|
||||
|
||||
@ -77,11 +77,11 @@ async def draw_char_info_img(raw_mes: str, sr_uid: str):
|
||||
char = await get_char(*_args)
|
||||
|
||||
if isinstance(char, str):
|
||||
logger.info('[sr查询角色] 绘图失败, 替换的武器不正确!')
|
||||
logger.info("[sr查询角色] 绘图失败, 替换的武器不正确!")
|
||||
return char
|
||||
|
||||
im = await draw_char_img(char, sr_uid, raw_mes)
|
||||
logger.info('[查询角色] 绘图完成,等待发送...')
|
||||
logger.info("[查询角色] 绘图完成,等待发送...")
|
||||
return im
|
||||
|
||||
|
||||
@ -92,24 +92,24 @@ async def get_char_args(
|
||||
# 六命希儿带于夜色中换1000xxxx4青雀遗器换1000xxxx6希儿头换银狼手
|
||||
# 六命希儿带于夜色中换1000xxxx6希儿头
|
||||
# 希儿换银狼手
|
||||
fake_name = ''
|
||||
fake_name = ""
|
||||
talent_num = None
|
||||
char_data = {}
|
||||
weapon, weapon_affix = None, None
|
||||
|
||||
msg = msg.replace('带', '换').replace('拿', '换').replace('圣遗物', '遗器')
|
||||
msg = msg.replace("带", "换").replace("拿", "换").replace("圣遗物", "遗器")
|
||||
|
||||
# 希儿带于夜色中换1000xxxx6希儿头
|
||||
msg_list = msg.split('换')
|
||||
msg_list = msg.split("换")
|
||||
for index, part in enumerate(msg_list):
|
||||
changeuid = await get_part_uid(part, uid)
|
||||
if changeuid is None:
|
||||
return 'UID不正确噢~'
|
||||
return "UID不正确噢~"
|
||||
# 判断主体
|
||||
if index == 0:
|
||||
fake_name, talent_num = await get_fake_char_str(part)
|
||||
# 判断是否开启fake_char
|
||||
if '遗器' in msg:
|
||||
if "遗器" in msg:
|
||||
char_data = await get_char_data(uid, fake_name)
|
||||
if isinstance(char_data, str):
|
||||
char_data = await make_new_charinfo(uid, fake_name)
|
||||
@ -119,29 +119,25 @@ async def get_char_args(
|
||||
return char_data
|
||||
continue
|
||||
|
||||
if '遗器' in part:
|
||||
if "遗器" in part:
|
||||
char_data = await get_fake_char_data(
|
||||
char_data,
|
||||
part.replace('遗器', '').replace(changeuid, ''),
|
||||
part.replace("遗器", "").replace(changeuid, ""),
|
||||
changeuid,
|
||||
)
|
||||
if isinstance(char_data, str):
|
||||
return char_data
|
||||
else:
|
||||
for i, s in enumerate(
|
||||
['头部', '手部', '躯干', '腿部', '位面球', '连结绳']
|
||||
):
|
||||
if '赤沙' in part:
|
||||
for i, s in enumerate(["头部", "手部", "躯干", "腿部", "位面球", "连结绳"]):
|
||||
if "赤沙" in part:
|
||||
continue
|
||||
if part[-1] in PieceName_ilst[i]:
|
||||
if isinstance(char_data, str):
|
||||
return char_data
|
||||
char_data = await change_equip(
|
||||
changeuid, char_data, part, s, i
|
||||
)
|
||||
char_data = await change_equip(changeuid, char_data, part, s, i)
|
||||
if not char_data:
|
||||
change_name = part.replace(part[-1], '')
|
||||
return f'要替换的{change_name}的{s}遗器不存在噢~'
|
||||
change_name = part.replace(part[-1], "")
|
||||
return f"要替换的{change_name}的{s}遗器不存在噢~"
|
||||
break
|
||||
else:
|
||||
weapon, weapon_affix = await get_fake_weapon_str(part)
|
||||
@ -149,24 +145,22 @@ async def get_char_args(
|
||||
return char_data, weapon, weapon_affix, talent_num
|
||||
|
||||
|
||||
async def change_equip(
|
||||
uid: str, char_data: Dict, part: str, s: str, i: int
|
||||
) -> Dict:
|
||||
char_name = part.replace(part[-1], '').replace(uid, '')
|
||||
async def change_equip(uid: str, char_data: Dict, part: str, s: str, i: int) -> Dict:
|
||||
char_name = part.replace(part[-1], "").replace(uid, "")
|
||||
fake_data = await get_char_data(uid, char_name)
|
||||
if isinstance(fake_data, str):
|
||||
return {}
|
||||
relicmap = i + 1
|
||||
for equip in fake_data['RelicInfo']:
|
||||
if str(str(equip['relicId'])[-1]) == str(relicmap):
|
||||
char_data['RelicInfo'][i] = equip
|
||||
for equip in fake_data["RelicInfo"]:
|
||||
if str(str(equip["relicId"])[-1]) == str(relicmap):
|
||||
char_data["RelicInfo"][i] = equip
|
||||
break
|
||||
return char_data
|
||||
|
||||
|
||||
async def get_part_uid(part: str, uid: str):
|
||||
sr_uid = uid
|
||||
uid_data = re.findall(r'\d{9}', part)
|
||||
uid_data = re.findall(r"\d{9}", part)
|
||||
if uid_data:
|
||||
sr_uid: Optional[str] = uid_data[0]
|
||||
return sr_uid
|
||||
@ -178,9 +172,7 @@ async def get_fake_char_str(char_name: str) -> Tuple[str, Optional[int]]:
|
||||
|
||||
"""
|
||||
talent_num = None
|
||||
if ('魂' in char_name or '命' in char_name) and char_name[
|
||||
0
|
||||
] in CHAR_TO_INT:
|
||||
if ("魂" in char_name or "命" in char_name) and char_name[0] in CHAR_TO_INT:
|
||||
talent_num = CHAR_TO_INT[char_name[0]]
|
||||
char_name = char_name[2:]
|
||||
return char_name, talent_num
|
||||
@ -188,7 +180,7 @@ async def get_fake_char_str(char_name: str) -> Tuple[str, Optional[int]]:
|
||||
|
||||
async def get_fake_weapon_str(msg: str) -> Tuple[str, Optional[int]]:
|
||||
weapon_affix = 1
|
||||
if '精' in msg and msg[1] in WEAPON_TO_INT:
|
||||
if "精" in msg and msg[1] in WEAPON_TO_INT:
|
||||
weapon_affix = WEAPON_TO_INT[msg[1]]
|
||||
weapon = msg[2:]
|
||||
else:
|
||||
@ -203,7 +195,7 @@ async def get_fake_char_data(
|
||||
if isinstance(original_data, str):
|
||||
return original_data
|
||||
if isinstance(original_data, Dict):
|
||||
char_data['RelicInfo'] = original_data['RelicInfo']
|
||||
char_data["RelicInfo"] = original_data["RelicInfo"]
|
||||
|
||||
return char_data
|
||||
|
||||
@ -212,16 +204,16 @@ async def get_char_data(
|
||||
uid: str, char_name: str, enable_self: bool = True
|
||||
) -> Union[Dict, str]:
|
||||
player_path = PLAYER_PATH / str(uid)
|
||||
SELF_PATH = player_path / 'SELF'
|
||||
if '开拓者' in str(char_name):
|
||||
char_name = '开拓者'
|
||||
SELF_PATH = player_path / "SELF"
|
||||
if "开拓者" in str(char_name):
|
||||
char_name = "开拓者"
|
||||
char_id = await name_to_avatar_id(char_name)
|
||||
if char_id == '':
|
||||
if char_id == "":
|
||||
char_name = await alias_to_char_name(char_name)
|
||||
if char_name is False:
|
||||
return '请输入正确的角色名'
|
||||
char_path = player_path / f'{char_name}.json'
|
||||
char_self_path = SELF_PATH / f'{char_name}.json'
|
||||
return "请输入正确的角色名"
|
||||
char_path = player_path / f"{char_name}.json"
|
||||
char_self_path = SELF_PATH / f"{char_name}.json"
|
||||
path = Path()
|
||||
if char_path.exists():
|
||||
path = char_path
|
||||
@ -243,7 +235,7 @@ async def get_char_data(
|
||||
else:
|
||||
return CHAR_HINT.format(char_name, char_name)
|
||||
|
||||
with Path.open(path, encoding='utf8') as fp:
|
||||
with Path.open(path, encoding="utf8") as fp:
|
||||
return json.load(fp)
|
||||
|
||||
|
||||
@ -252,39 +244,29 @@ async def make_new_charinfo(
|
||||
fake_name: str,
|
||||
):
|
||||
char_data = {}
|
||||
char_data['uid'] = uid
|
||||
char_data['nickName'] = 'test'
|
||||
char_data["uid"] = uid
|
||||
char_data["nickName"] = "test"
|
||||
char_id = await name_to_avatar_id(fake_name)
|
||||
if char_id == '':
|
||||
if char_id == "":
|
||||
fake_name = await alias_to_char_name(fake_name)
|
||||
if fake_name is False:
|
||||
return '请输入正确的角色名'
|
||||
return "请输入正确的角色名"
|
||||
char_id = await name_to_avatar_id(fake_name)
|
||||
char_data['avatarId'] = int(char_id)
|
||||
char_data['avatarName'] = fake_name
|
||||
char_data['avatarElement'] = avatarId2DamageType[
|
||||
str(char_data['avatarId'])
|
||||
]
|
||||
char_data['avatarRarity'] = str(
|
||||
avatarId2Rarity[str(char_data['avatarId'])]
|
||||
)
|
||||
char_data['avatarPromotion'] = 6
|
||||
char_data['avatarLevel'] = 80
|
||||
char_data['avatarSkill'] = await get_skill_list(char_data['avatarId'])
|
||||
char_data['avatarExtraAbility'] = await get_extra_list(
|
||||
char_data['avatarId']
|
||||
)
|
||||
char_data['avatarAttributeBonus'] = await get_attribute_list(
|
||||
char_data['avatarId']
|
||||
)
|
||||
char_data['RelicInfo'] = []
|
||||
char_data['avatarEnName'] = avatarId2EnName[str(char_data['avatarId'])]
|
||||
char_data['rank'] = 0
|
||||
char_data['rankList'] = []
|
||||
char_data['baseAttributes'] = await get_baseAttributes(
|
||||
char_data['avatarId']
|
||||
)
|
||||
char_data['equipmentInfo'] = {}
|
||||
char_data["avatarId"] = int(char_id)
|
||||
char_data["avatarName"] = fake_name
|
||||
char_data["avatarElement"] = avatarId2DamageType[str(char_data["avatarId"])]
|
||||
char_data["avatarRarity"] = str(avatarId2Rarity[str(char_data["avatarId"])])
|
||||
char_data["avatarPromotion"] = 6
|
||||
char_data["avatarLevel"] = 80
|
||||
char_data["avatarSkill"] = await get_skill_list(char_data["avatarId"])
|
||||
char_data["avatarExtraAbility"] = await get_extra_list(char_data["avatarId"])
|
||||
char_data["avatarAttributeBonus"] = await get_attribute_list(char_data["avatarId"])
|
||||
char_data["RelicInfo"] = []
|
||||
char_data["avatarEnName"] = avatarId2EnName[str(char_data["avatarId"])]
|
||||
char_data["rank"] = 0
|
||||
char_data["rankList"] = []
|
||||
char_data["baseAttributes"] = await get_baseAttributes(char_data["avatarId"])
|
||||
char_data["equipmentInfo"] = {}
|
||||
return char_data
|
||||
|
||||
|
||||
@ -293,35 +275,40 @@ async def get_baseAttributes(
|
||||
):
|
||||
# 处理基础属性
|
||||
base_attributes = {}
|
||||
avatar_promotion_base = AvatarPromotionConfig.Avatar[str(char_id)]['6']
|
||||
|
||||
avatar_promotion_base = None
|
||||
for avatar in AvatarPromotionConfig:
|
||||
if avatar.AvatarID == str(char_id):
|
||||
avatar_promotion_base = avatar
|
||||
break
|
||||
|
||||
if not avatar_promotion_base:
|
||||
msg = f"AvatarPromotionConfig not found: {char_id}"
|
||||
raise ValueError(msg)
|
||||
|
||||
# 攻击力
|
||||
base_attributes['attack'] = (
|
||||
base_attributes["attack"] = (
|
||||
avatar_promotion_base.AttackBase.Value
|
||||
+ avatar_promotion_base.AttackAdd.Value * (80 - 1)
|
||||
)
|
||||
# 防御力
|
||||
base_attributes['defence'] = (
|
||||
base_attributes["defence"] = (
|
||||
avatar_promotion_base.DefenceBase.Value
|
||||
+ avatar_promotion_base.DefenceAdd.Value * (80 - 1)
|
||||
)
|
||||
# 血量
|
||||
base_attributes['hp'] = (
|
||||
base_attributes["hp"] = (
|
||||
avatar_promotion_base.HPBase.Value
|
||||
+ avatar_promotion_base.HPAdd.Value * (80 - 1)
|
||||
)
|
||||
# 速度
|
||||
base_attributes['speed'] = avatar_promotion_base.SpeedBase.Value
|
||||
base_attributes["speed"] = avatar_promotion_base.SpeedBase.Value
|
||||
# 暴击率
|
||||
base_attributes['CriticalChanceBase'] = (
|
||||
avatar_promotion_base.CriticalChance.Value
|
||||
)
|
||||
base_attributes["CriticalChanceBase"] = avatar_promotion_base.CriticalChance.Value
|
||||
# 暴击伤害
|
||||
base_attributes['CriticalDamageBase'] = (
|
||||
avatar_promotion_base.CriticalDamage.Value
|
||||
)
|
||||
base_attributes["CriticalDamageBase"] = avatar_promotion_base.CriticalDamage.Value
|
||||
# 嘲讽
|
||||
base_attributes['BaseAggro'] = avatar_promotion_base.BaseAggro.Value
|
||||
base_attributes["BaseAggro"] = avatar_promotion_base.BaseAggro.Value
|
||||
return base_attributes
|
||||
|
||||
|
||||
@ -331,21 +318,19 @@ async def get_attribute_list(
|
||||
attribute_list = []
|
||||
for attributeid in [201, 202, 203, 204, 205, 206, 207, 208, 209, 210]:
|
||||
attribute_bonus_temp = {}
|
||||
attribute_bonus_temp['attributeBonusId'] = char_id * 1000 + attributeid
|
||||
attribute_bonus_temp['attributeBonusLevel'] = 1
|
||||
attribute_bonus_temp["attributeBonusId"] = char_id * 1000 + attributeid
|
||||
attribute_bonus_temp["attributeBonusLevel"] = 1
|
||||
status_add = characterSkillTree[str(char_id)][
|
||||
str(attribute_bonus_temp['attributeBonusId'])
|
||||
]['levels'][0]['properties']
|
||||
attribute_bonus_temp['statusAdd'] = {}
|
||||
str(attribute_bonus_temp["attributeBonusId"])
|
||||
]["levels"][0]["properties"]
|
||||
attribute_bonus_temp["statusAdd"] = {}
|
||||
if status_add:
|
||||
for property_ in status_add:
|
||||
attribute_bonus_temp['statusAdd']['property'] = property_[
|
||||
'type'
|
||||
attribute_bonus_temp["statusAdd"]["property"] = property_["type"]
|
||||
attribute_bonus_temp["statusAdd"]["name"] = Property2Name[
|
||||
property_["type"]
|
||||
]
|
||||
attribute_bonus_temp['statusAdd']['name'] = Property2Name[
|
||||
property_['type']
|
||||
]
|
||||
attribute_bonus_temp['statusAdd']['value'] = property_['value']
|
||||
attribute_bonus_temp["statusAdd"]["value"] = property_["value"]
|
||||
attribute_list.append(attribute_bonus_temp)
|
||||
return attribute_list
|
||||
|
||||
@ -356,8 +341,8 @@ async def get_extra_list(
|
||||
extra_list = []
|
||||
for extraid in [101, 102, 103]:
|
||||
extra_temp = {}
|
||||
extra_temp['extraAbilityId'] = char_id * 1000 + extraid
|
||||
extra_temp['extraAbilityLevel'] = 1
|
||||
extra_temp["extraAbilityId"] = char_id * 1000 + extraid
|
||||
extra_temp["extraAbilityLevel"] = 1
|
||||
extra_list.append(extra_temp)
|
||||
return extra_list
|
||||
|
||||
@ -368,18 +353,16 @@ async def get_skill_list(
|
||||
Skilllist = []
|
||||
for skillid in [1, 2, 3, 4, 7]:
|
||||
skill_temp = {}
|
||||
skill_temp['skillId'] = char_id * 100 + skillid
|
||||
skill_temp['skillName'] = skillId2Name[str(skill_temp['skillId'])]
|
||||
skill_temp['skillEffect'] = skillId2Effect[str(skill_temp['skillId'])]
|
||||
skill_temp['skillAttackType'] = skillId2AttackType[
|
||||
str(skill_temp['skillId'])
|
||||
]
|
||||
skill_temp["skillId"] = char_id * 100 + skillid
|
||||
skill_temp["skillName"] = skillId2Name[str(skill_temp["skillId"])]
|
||||
skill_temp["skillEffect"] = skillId2Effect[str(skill_temp["skillId"])]
|
||||
skill_temp["skillAttackType"] = skillId2AttackType[str(skill_temp["skillId"])]
|
||||
skilllevel = 10
|
||||
if skillid == 1:
|
||||
skilllevel = 6
|
||||
if skillid == 7:
|
||||
skilllevel = 1
|
||||
skill_temp['skillLevel'] = skilllevel
|
||||
skill_temp["skillLevel"] = skilllevel
|
||||
Skilllist.append(skill_temp)
|
||||
return Skilllist
|
||||
|
||||
@ -391,9 +374,9 @@ async def get_rank_list(
|
||||
rank_temp = []
|
||||
for index in range(talent_num):
|
||||
rankTemp = {}
|
||||
rank_id = int(str(char_id) + '0' + str(index + 1))
|
||||
rankTemp['rankId'] = rank_id
|
||||
rankTemp['rankName'] = rankId2Name[str(rank_id)]
|
||||
rank_id = int(str(char_id) + "0" + str(index + 1))
|
||||
rankTemp["rankId"] = rank_id
|
||||
rankTemp["rankName"] = rankId2Name[str(rank_id)]
|
||||
rank_temp.append(rankTemp)
|
||||
return rank_temp
|
||||
|
||||
@ -407,82 +390,82 @@ async def get_char(
|
||||
if isinstance(talent_num, int):
|
||||
# 处理命座
|
||||
rank_temp = []
|
||||
char_data['rank'] = talent_num
|
||||
char_data["rank"] = talent_num
|
||||
for index in range(talent_num):
|
||||
rankTemp = {}
|
||||
rank_id = int(str(char_data['avatarId']) + '0' + str(index + 1))
|
||||
rankTemp['rankId'] = rank_id
|
||||
rankTemp['rankName'] = rankId2Name[str(rank_id)]
|
||||
rank_id = int(str(char_data["avatarId"]) + "0" + str(index + 1))
|
||||
rankTemp["rankId"] = rank_id
|
||||
rankTemp["rankName"] = rankId2Name[str(rank_id)]
|
||||
rank_temp.append(rankTemp)
|
||||
char_data['rankList'] = rank_temp
|
||||
char_data["rankList"] = rank_temp
|
||||
|
||||
# 处理命座中的 level_up_skills
|
||||
if char_data.get('rankList'):
|
||||
for rank_item in char_data['rankList']:
|
||||
rank_id = rank_item['rankId']
|
||||
if char_data.get("rankList"):
|
||||
for rank_item in char_data["rankList"]:
|
||||
rank_id = rank_item["rankId"]
|
||||
level_up_skill = AvatarRankSkillUp[str(rank_id)]
|
||||
if level_up_skill:
|
||||
for item in level_up_skill:
|
||||
skill_id = item['id']
|
||||
skill_up_num = item['num']
|
||||
skill_id = item["id"]
|
||||
skill_up_num = item["num"]
|
||||
# 查找skill_id在不在avatarSkill中
|
||||
for index, skill_item in enumerate(
|
||||
char_data['avatarSkill']
|
||||
):
|
||||
if str(skill_id) == str(skill_item['skillId']):
|
||||
for index, skill_item in enumerate(char_data["avatarSkill"]):
|
||||
if str(skill_id) == str(skill_item["skillId"]):
|
||||
if skill_id[-1] == 1:
|
||||
skilllevel_max = 7
|
||||
else:
|
||||
skilllevel_max = 12
|
||||
skilllevel = min(
|
||||
skilllevel_max,
|
||||
char_data['avatarSkill'][index][
|
||||
'skillLevel'
|
||||
]
|
||||
char_data["avatarSkill"][index]["skillLevel"]
|
||||
+ skill_up_num,
|
||||
)
|
||||
char_data['avatarSkill'][index][
|
||||
'skillLevel'
|
||||
] = skilllevel
|
||||
char_data["avatarSkill"][index]["skillLevel"] = (
|
||||
skilllevel
|
||||
)
|
||||
break
|
||||
|
||||
if isinstance(weapon, str):
|
||||
# 处理武器
|
||||
equipmentid = await name_to_weapon_id(weapon)
|
||||
if equipmentid == '':
|
||||
if equipmentid == "":
|
||||
weapon = await alias_to_weapon_name(weapon)
|
||||
equipmentid = await name_to_weapon_id(weapon)
|
||||
equipment_info = {}
|
||||
equipment_info['equipmentID'] = int(equipmentid)
|
||||
equipment_info['equipmentName'] = EquipmentID2Name[str(equipmentid)]
|
||||
equipment_info["equipmentID"] = int(equipmentid)
|
||||
equipment_info["equipmentName"] = EquipmentID2Name[str(equipmentid)]
|
||||
|
||||
equipment_info['equipmentLevel'] = 80
|
||||
equipment_info['equipmentPromotion'] = 6
|
||||
equipment_info['equipmentRank'] = weapon_affix
|
||||
equipment_info['equipmentRarity'] = EquipmentID2Rarity[
|
||||
str(equipmentid)
|
||||
]
|
||||
equipment_info["equipmentLevel"] = 80
|
||||
equipment_info["equipmentPromotion"] = 6
|
||||
equipment_info["equipmentRank"] = weapon_affix
|
||||
equipment_info["equipmentRarity"] = EquipmentID2Rarity[str(equipmentid)]
|
||||
equipment_base_attributes = {}
|
||||
equipment_promotion_base = EquipmentPromotionConfig.Equipment[
|
||||
str(equipmentid)
|
||||
]['6']
|
||||
|
||||
equipment_promotion_base = None
|
||||
for equipment in EquipmentPromotionConfig:
|
||||
if equipment.EquipmentID == str(equipmentid):
|
||||
equipment_promotion_base = equipment
|
||||
break
|
||||
if not equipment_promotion_base:
|
||||
msg = f"EquipmentPromotionConfig not found: {equipmentid}"
|
||||
raise ValueError(msg)
|
||||
|
||||
# 生命值
|
||||
equipment_base_attributes['hp'] = (
|
||||
equipment_base_attributes["hp"] = (
|
||||
equipment_promotion_base.BaseHP.Value
|
||||
+ equipment_promotion_base.BaseHPAdd.Value * (80 - 1)
|
||||
)
|
||||
# 攻击力
|
||||
equipment_base_attributes['attack'] = (
|
||||
equipment_base_attributes["attack"] = (
|
||||
equipment_promotion_base.BaseAttack.Value
|
||||
+ equipment_promotion_base.BaseAttackAdd.Value * (80 - 1)
|
||||
)
|
||||
# 防御力
|
||||
equipment_base_attributes['defence'] = (
|
||||
equipment_base_attributes["defence"] = (
|
||||
equipment_promotion_base.BaseDefence.Value
|
||||
+ equipment_promotion_base.BaseDefenceAdd.Value * (80 - 1)
|
||||
)
|
||||
equipment_info['baseAttributes'] = equipment_base_attributes
|
||||
equipment_info["baseAttributes"] = equipment_base_attributes
|
||||
|
||||
char_data['equipmentInfo'] = equipment_info
|
||||
char_data["equipmentInfo"] = equipment_info
|
||||
return char_data
|
||||
|
@ -19,12 +19,12 @@ second_color = (67, 61, 56)
|
||||
white_color = (247, 247, 247)
|
||||
gray_color = (175, 175, 175)
|
||||
|
||||
TEXT_PATH = Path(__file__).parent / 'texture2D'
|
||||
char_mask = Image.open(TEXT_PATH / 'ring_mask.png')
|
||||
char_bg_mask = Image.open(TEXT_PATH / 'char_bg_mask.png')
|
||||
tag = Image.open(TEXT_PATH / 'tag.png')
|
||||
footbar = Image.open(TEXT_PATH / 'footbar.png')
|
||||
pic_500 = Image.open(TEXT_PATH / '500.png')
|
||||
TEXT_PATH = Path(__file__).parent / "texture2D"
|
||||
char_mask = Image.open(TEXT_PATH / "ring_mask.png")
|
||||
char_bg_mask = Image.open(TEXT_PATH / "char_bg_mask.png")
|
||||
tag = Image.open(TEXT_PATH / "tag.png")
|
||||
footbar = Image.open(TEXT_PATH / "footbar.png")
|
||||
pic_500 = Image.open(TEXT_PATH / "500.png")
|
||||
|
||||
|
||||
async def api_to_card(uid: str) -> Union[Tuple[bytes, List[str]], bytes]:
|
||||
@ -52,19 +52,17 @@ async def draw_enka_card(uid: str, char_list: List, showfrom: int = 0):
|
||||
avatarName = avatarId2Name[str(char)]
|
||||
char_data_list.append(
|
||||
{
|
||||
'avatarName': avatarName,
|
||||
'avatarId': str(char),
|
||||
"avatarName": avatarName,
|
||||
"avatarId": str(char),
|
||||
}
|
||||
)
|
||||
if showfrom == 0:
|
||||
line1 = f'展柜内有 {len(char_data_list)} 个角色!'
|
||||
line1 = f"展柜内有 {len(char_data_list)} 个角色!"
|
||||
elif char_data_list is None:
|
||||
return await convert_img(Image.new('RGBA', (0, 1), (255, 255, 255)))
|
||||
return await convert_img(Image.new("RGBA", (0, 1), (255, 255, 255)))
|
||||
else:
|
||||
line1 = f'UID {uid} 刷新成功'
|
||||
line2 = (
|
||||
f'可以使用 sr查询{char_data_list[0]["avatarName"]} 查询详情角色面板'
|
||||
)
|
||||
line1 = f"UID {uid} 刷新成功"
|
||||
line2 = f'可以使用 sr查询{char_data_list[0]["avatarName"]} 查询详情角色面板'
|
||||
char_num = len(char_data_list)
|
||||
if char_num <= 4:
|
||||
based_w, based_h = 1380, 926
|
||||
@ -73,19 +71,19 @@ async def draw_enka_card(uid: str, char_list: List, showfrom: int = 0):
|
||||
show_type = 0
|
||||
based_w, based_h = 1380, 310 + (((char_num - 1) // 4) + 1) * 320
|
||||
|
||||
img = Image.open(TEXT_PATH / 'shin.jpg')
|
||||
img = Image.open(TEXT_PATH / "shin.jpg")
|
||||
img = crop_center_img(img, based_w, based_h)
|
||||
img.paste(tag, (0, 0), tag)
|
||||
|
||||
img_draw = ImageDraw.Draw(img, 'RGBA')
|
||||
img_draw = ImageDraw.Draw(img, "RGBA")
|
||||
|
||||
# 写底层文字
|
||||
img_draw.text(
|
||||
(690, based_h - 26),
|
||||
'--Created by qwerdvd-Designed By Wuyi-Thank for mihomo.me--',
|
||||
"--Created by qwerdvd-Designed By Wuyi-Thank for mihomo.me--",
|
||||
(22, 22, 22),
|
||||
fw_font_28,
|
||||
'mm',
|
||||
"mm",
|
||||
)
|
||||
|
||||
img_draw.text(
|
||||
@ -93,14 +91,14 @@ async def draw_enka_card(uid: str, char_list: List, showfrom: int = 0):
|
||||
line1,
|
||||
white_color,
|
||||
sr_font_58,
|
||||
'lm',
|
||||
"lm",
|
||||
)
|
||||
img_draw.text(
|
||||
(225, 175),
|
||||
line2,
|
||||
gray_color,
|
||||
sr_font_24,
|
||||
'lm',
|
||||
"lm",
|
||||
)
|
||||
tasks = []
|
||||
for index, char_data in enumerate(char_data_list):
|
||||
@ -113,17 +111,17 @@ async def draw_enka_card(uid: str, char_list: List, showfrom: int = 0):
|
||||
|
||||
|
||||
async def draw_mihomo_char(index: int, img: Image.Image, char_data: Dict):
|
||||
char_id = char_data['avatarId']
|
||||
char_name = char_data['avatarName']
|
||||
char_id = char_data["avatarId"]
|
||||
char_name = char_data["avatarName"]
|
||||
char_star = await avatar_id_to_char_star(str(char_id))
|
||||
char_card = Image.open(TEXT_PATH / f'char{char_star}_bg.png')
|
||||
char_temp = Image.new('RGBA', (300, 650))
|
||||
char_card = Image.open(TEXT_PATH / f"char{char_star}_bg.png")
|
||||
char_temp = Image.new("RGBA", (300, 650))
|
||||
char_img = (
|
||||
Image.open(str(CHAR_PREVIEW_PATH / f'{char_id}.png'))
|
||||
.convert('RGBA')
|
||||
Image.open(str(CHAR_PREVIEW_PATH / f"{char_id}.png"))
|
||||
.convert("RGBA")
|
||||
.resize((449, 615))
|
||||
)
|
||||
if char_name == '希儿':
|
||||
if char_name == "希儿":
|
||||
char_img = char_img.resize((449, 650))
|
||||
char_img = char_img.crop((135, 0, 379, 457))
|
||||
char_temp.paste(char_img, (32, 98), char_img)
|
||||
@ -132,40 +130,40 @@ async def draw_mihomo_char(index: int, img: Image.Image, char_data: Dict):
|
||||
char_temp.paste(char_img, (32, 38), char_img)
|
||||
char_card.paste(char_temp, (0, 0), char_bg_mask)
|
||||
|
||||
img_draw = ImageDraw.Draw(char_card, 'RGBA')
|
||||
img_draw = ImageDraw.Draw(char_card, "RGBA")
|
||||
img_draw.text(
|
||||
(150, 585),
|
||||
char_name,
|
||||
white_color,
|
||||
sr_font_30,
|
||||
'mm',
|
||||
"mm",
|
||||
)
|
||||
x = 42 + index * 325
|
||||
img.paste(char_card, (x, 199), char_card)
|
||||
|
||||
|
||||
async def draw_enka_char(index: int, img: Image.Image, char_data: Dict):
|
||||
char_id = char_data['avatarId']
|
||||
char_id = char_data["avatarId"]
|
||||
char_star = await avatar_id_to_char_star(str(char_id))
|
||||
char_card = Image.open(TEXT_PATH / f'ring_{char_star}.png')
|
||||
_path = CHAR_PREVIEW_PATH / f'{char_id}.png'
|
||||
char_img = Image.open(_path).convert('RGBA')
|
||||
char_card = Image.open(TEXT_PATH / f"ring_{char_star}.png")
|
||||
_path = CHAR_PREVIEW_PATH / f"{char_id}.png"
|
||||
char_img = Image.open(_path).convert("RGBA")
|
||||
char_img = char_img.resize(
|
||||
(int(char_img.size[0] * 0.76), int(char_img.size[1] * 0.76))
|
||||
)
|
||||
|
||||
char_temp = Image.new('RGBA', (300, 400))
|
||||
card_temp = Image.new('RGBA', (300, 400))
|
||||
char_temp = Image.new("RGBA", (300, 400))
|
||||
card_temp = Image.new("RGBA", (300, 400))
|
||||
char_temp.paste(char_img, (19, 57), char_img)
|
||||
card_temp.paste(char_temp, (0, 0), char_mask)
|
||||
|
||||
char_draw = ImageDraw.Draw(card_temp)
|
||||
char_draw.text(
|
||||
(144, 285),
|
||||
char_data['avatarName'],
|
||||
'white',
|
||||
char_data["avatarName"],
|
||||
"white",
|
||||
sr_font_30,
|
||||
'mm',
|
||||
"mm",
|
||||
)
|
||||
|
||||
img.paste(
|
||||
|
@ -7,18 +7,16 @@ from gsuid_core.models import Event
|
||||
from gsuid_core.sv import SV
|
||||
from gsuid_core.utils.database.models import GsBind
|
||||
|
||||
PREFIX = srconfig.get_config('StarRailPrefix').data
|
||||
PREFIX = srconfig.get_config("StarRailPrefix").data
|
||||
|
||||
sv_self_config = SV('星穹铁道配置')
|
||||
sv_self_config = SV("星穹铁道配置")
|
||||
|
||||
|
||||
@sv_self_config.on_prefix((f'{PREFIX}开启', f'{PREFIX}关闭'))
|
||||
@sv_self_config.on_prefix((f"{PREFIX}开启", f"{PREFIX}关闭"))
|
||||
async def open_switch_func(bot: Bot, ev: Event):
|
||||
uid = await GsBind.get_uid_by_game(ev.user_id, ev.bot_id, 'sr')
|
||||
uid = await GsBind.get_uid_by_game(ev.user_id, ev.bot_id, "sr")
|
||||
if uid is None:
|
||||
return await bot.send('[星穹铁道] 你还没有绑定UID哦!')
|
||||
logger.info(
|
||||
f'[{ev.user_id}] [UID{uid}]尝试[{ev.command[2:]}]了[{ev.text}]功能'
|
||||
)
|
||||
return await bot.send("[星穹铁道] 你还没有绑定UID哦!")
|
||||
logger.info(f"[{ev.user_id}] [UID{uid}]尝试[{ev.command[2:]}]了[{ev.text}]功能")
|
||||
await bot.send(await set_config_func(uid, ev))
|
||||
return None
|
||||
|
@ -4,47 +4,43 @@ from gsuid_core.utils.plugins_config.models import (
|
||||
GSC,
|
||||
GsStrConfig,
|
||||
GsBoolConfig,
|
||||
GsListStrConfig, GsIntConfig,
|
||||
GsListStrConfig,
|
||||
GsIntConfig,
|
||||
)
|
||||
|
||||
CONIFG_DEFAULT: Dict[str, GSC] = {
|
||||
'SignTime': GsListStrConfig(
|
||||
'每晚签到时间设置', '每晚米游社签到时间设置(时,分)', ['0', '38']
|
||||
"SignTime": GsListStrConfig(
|
||||
"每晚签到时间设置", "每晚米游社签到时间设置(时,分)", ["0", "38"]
|
||||
),
|
||||
'PrivateSignReport': GsBoolConfig(
|
||||
'签到私聊报告',
|
||||
'关闭后将不再给任何人推送当天签到任务完成情况',
|
||||
"PrivateSignReport": GsBoolConfig(
|
||||
"签到私聊报告",
|
||||
"关闭后将不再给任何人推送当天签到任务完成情况",
|
||||
False,
|
||||
),
|
||||
'SchedSignin': GsBoolConfig(
|
||||
'定时签到',
|
||||
'开启后每晚00:30将开始自动签到任务',
|
||||
"SchedSignin": GsBoolConfig(
|
||||
"定时签到",
|
||||
"开启后每晚00:30将开始自动签到任务",
|
||||
True,
|
||||
),
|
||||
'SchedStaminaPush': GsBoolConfig(
|
||||
'定时检查开拓力',
|
||||
'开启后每隔半小时检查一次开拓力',
|
||||
"SchedStaminaPush": GsBoolConfig(
|
||||
"定时检查开拓力",
|
||||
"开启后每隔半小时检查一次开拓力",
|
||||
True,
|
||||
),
|
||||
'push_max_value': GsIntConfig(
|
||||
'提醒阈值',
|
||||
'发送提醒的阈值',
|
||||
200,
|
||||
240
|
||||
),
|
||||
'CrazyNotice': GsBoolConfig(
|
||||
'催命模式',
|
||||
'开启后当达到推送阈值将会一直推送',
|
||||
"push_max_value": GsIntConfig("提醒阈值", "发送提醒的阈值", 200, 240),
|
||||
"CrazyNotice": GsBoolConfig(
|
||||
"催命模式",
|
||||
"开启后当达到推送阈值将会一直推送",
|
||||
False,
|
||||
),
|
||||
'StarRailPrefix': GsStrConfig(
|
||||
'插件命令前缀(确认无冲突再修改)',
|
||||
'用于本插件的前缀设定',
|
||||
'sr',
|
||||
"StarRailPrefix": GsStrConfig(
|
||||
"插件命令前缀(确认无冲突再修改)",
|
||||
"用于本插件的前缀设定",
|
||||
"sr",
|
||||
),
|
||||
'WidgetResin': GsBoolConfig(
|
||||
'体力使用组件API',
|
||||
'开启后mr功能将转为调用组件API, 可能缺失数据、数据不准',
|
||||
"WidgetResin": GsBoolConfig(
|
||||
"体力使用组件API",
|
||||
"开启后mr功能将转为调用组件API, 可能缺失数据、数据不准",
|
||||
True,
|
||||
),
|
||||
}
|
||||
|
@ -8,26 +8,26 @@ async def set_config_func(
|
||||
uid: str,
|
||||
ev: Event,
|
||||
):
|
||||
if '开启' in ev.command:
|
||||
if ev.user_type == 'direct':
|
||||
value = 'on'
|
||||
if "开启" in ev.command:
|
||||
if ev.user_type == "direct":
|
||||
value = "on"
|
||||
elif ev.group_id:
|
||||
value = ev.group_id
|
||||
else:
|
||||
value = 'on'
|
||||
value = "on"
|
||||
else:
|
||||
value = 'off'
|
||||
value = "off"
|
||||
|
||||
text = await set_database_value(
|
||||
GsUser,
|
||||
'sr',
|
||||
'sr开启',
|
||||
"sr",
|
||||
"sr开启",
|
||||
ev.text.strip(),
|
||||
uid,
|
||||
ev.bot_id,
|
||||
value,
|
||||
)
|
||||
if text is None:
|
||||
return '[星穹铁道] 未找到配置项'
|
||||
logger.success(f'[UID{uid}]成功将配置[SR自动签到]设置为[{value}]!')
|
||||
return "[星穹铁道] 未找到配置项"
|
||||
logger.success(f"[UID{uid}]成功将配置[SR自动签到]设置为[{value}]!")
|
||||
return text
|
||||
|
@ -4,7 +4,7 @@ from .config_default import CONIFG_DEFAULT
|
||||
from ..utils.resource.RESOURCE_PATH import CONFIG_PATH
|
||||
|
||||
srconfig = StringConfig(
|
||||
'StarRailUID',
|
||||
"StarRailUID",
|
||||
CONFIG_PATH,
|
||||
CONIFG_DEFAULT,
|
||||
)
|
||||
|
@ -1,24 +1,22 @@
|
||||
from gsuid_core.sv import SV
|
||||
from .draw_gachalogs import draw_gachalogs_img
|
||||
from .get_gachalogs import save_gachalogs
|
||||
from ..utils.error_reply import UID_HINT
|
||||
from ..utils.sr_prefix import PREFIX
|
||||
|
||||
from gsuid_core.bot import Bot
|
||||
from gsuid_core.models import Event
|
||||
from gsuid_core.sv import SV
|
||||
from gsuid_core.utils.database.api import get_uid
|
||||
from gsuid_core.utils.database.models import GsBind
|
||||
|
||||
from ..utils.convert import get_uid
|
||||
from ..utils.sr_prefix import PREFIX
|
||||
from ..utils.error_reply import UID_HINT
|
||||
from .get_gachalogs import save_gachalogs
|
||||
from .draw_gachalogs import draw_gachalogs_img
|
||||
|
||||
sv_gacha_log = SV('sr抽卡记录')
|
||||
sv_get_gachalog_by_link = SV('sr导入抽卡链接', area='DIRECT')
|
||||
sv_gacha_log = SV("sr抽卡记录")
|
||||
sv_get_gachalog_by_link = SV("sr导入抽卡链接", area="DIRECT")
|
||||
|
||||
|
||||
@sv_gacha_log.on_fullmatch(f'{PREFIX}抽卡记录')
|
||||
@sv_gacha_log.on_fullmatch(f"{PREFIX}抽卡记录")
|
||||
async def send_gacha_log_card_info(bot: Bot, ev: Event):
|
||||
await bot.logger.info('开始执行[sr抽卡记录]')
|
||||
get_uid_ = await get_uid(bot, ev, True, False)
|
||||
if get_uid_ is None:
|
||||
return await bot.send(UID_HINT)
|
||||
uid, user_id = get_uid_
|
||||
await bot.logger.info("开始执行[sr抽卡记录]")
|
||||
uid, user_id = await get_uid(bot, ev, GsBind, "sr", True)
|
||||
if uid is None:
|
||||
return await bot.send(UID_HINT)
|
||||
im = await draw_gachalogs_img(uid, user_id)
|
||||
@ -26,21 +24,19 @@ async def send_gacha_log_card_info(bot: Bot, ev: Event):
|
||||
return None
|
||||
|
||||
|
||||
@sv_get_gachalog_by_link.on_command(f'{PREFIX}导入抽卡链接')
|
||||
@sv_get_gachalog_by_link.on_command(f"{PREFIX}导入抽卡链接")
|
||||
async def get_gachalog_by_link(bot: Bot, ev: Event):
|
||||
await bot.logger.info('开始执行[sr导入抽卡链接]')
|
||||
uid = await get_uid(bot, ev, only_uid=True)
|
||||
await bot.logger.info("开始执行[sr导入抽卡链接]")
|
||||
uid = await get_uid(bot, ev, GsBind, "sr")
|
||||
if uid is None:
|
||||
return await bot.send(UID_HINT)
|
||||
gacha_url = ev.text.strip()
|
||||
if not gacha_url or not isinstance(gacha_url, str):
|
||||
return await bot.send('请给出正确的抽卡记录链接')
|
||||
return await bot.send("请给出正确的抽卡记录链接")
|
||||
is_force = False
|
||||
if ev.command.startswith('强制'):
|
||||
await bot.logger.info('[WARNING]本次为强制刷新')
|
||||
if ev.command.startswith("强制"):
|
||||
await bot.logger.info("[WARNING]本次为强制刷新")
|
||||
is_force = True
|
||||
await bot.send(
|
||||
f'UID{uid}开始执行[刷新抽卡记录],需要一定时间...请勿重复触发!'
|
||||
)
|
||||
await bot.send(f"UID{uid}开始执行[刷新抽卡记录],需要一定时间...请勿重复触发!")
|
||||
im = await save_gachalogs(uid, gacha_url, None, is_force)
|
||||
return await bot.send(im)
|
||||
|
@ -1,24 +1,9 @@
|
||||
import json
|
||||
import asyncio
|
||||
import datetime
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import List, Tuple, Union
|
||||
|
||||
from PIL import Image, ImageDraw
|
||||
from gsuid_core.logger import logger
|
||||
from gsuid_core.utils.image.image_tools import (
|
||||
get_color_bg,
|
||||
get_qq_avatar,
|
||||
draw_pic_with_ring,
|
||||
)
|
||||
|
||||
from ..utils.image.convert import convert_img
|
||||
from ..utils.map.name_covert import name_to_avatar_id, name_to_weapon_id
|
||||
from ..utils.resource.RESOURCE_PATH import (
|
||||
PLAYER_PATH,
|
||||
WEAPON_PATH,
|
||||
CHAR_ICON_PATH,
|
||||
)
|
||||
from ..utils.fonts.starrail_fonts import (
|
||||
sr_font_20,
|
||||
sr_font_24,
|
||||
@ -26,13 +11,28 @@ from ..utils.fonts.starrail_fonts import (
|
||||
sr_font_38,
|
||||
sr_font_40,
|
||||
)
|
||||
from ..utils.map.name_covert import name_to_avatar_id, name_to_weapon_id
|
||||
from ..utils.resource.RESOURCE_PATH import (
|
||||
CHAR_ICON_PATH,
|
||||
PLAYER_PATH,
|
||||
WEAPON_PATH,
|
||||
)
|
||||
|
||||
TEXT_PATH = Path(__file__).parent / 'texture2d'
|
||||
EMO_PATH = Path(__file__).parent / 'texture2d' / 'emo'
|
||||
from PIL import Image, ImageDraw
|
||||
from gsuid_core.logger import logger
|
||||
from gsuid_core.utils.image.convert import convert_img
|
||||
from gsuid_core.utils.image.image_tools import (
|
||||
draw_pic_with_ring,
|
||||
get_color_bg,
|
||||
get_qq_avatar,
|
||||
)
|
||||
|
||||
TEXT_PATH = Path(__file__).parent / "texture2d"
|
||||
EMO_PATH = Path(__file__).parent / "texture2d" / "emo"
|
||||
|
||||
# up_tag = Image.open(TEXT_PATH / 'up.png')
|
||||
Abg3_img = Image.open(TEXT_PATH / 'Abg3.png')
|
||||
bg1_img = Image.open(TEXT_PATH / 'bg1.png')
|
||||
Abg3_img = Image.open(TEXT_PATH / "Abg3.png")
|
||||
bg1_img = Image.open(TEXT_PATH / "bg1.png")
|
||||
|
||||
first_color = (29, 29, 29)
|
||||
brown_color = (41, 25, 0)
|
||||
@ -42,33 +42,33 @@ white_color = (213, 213, 213)
|
||||
whole_white_color = (255, 255, 255)
|
||||
|
||||
CHANGE_MAP = {
|
||||
'始发跃迁': 'begin',
|
||||
'群星跃迁': 'normal',
|
||||
'角色跃迁': 'char',
|
||||
'光锥跃迁': 'weapon',
|
||||
"始发跃迁": "begin",
|
||||
"群星跃迁": "normal",
|
||||
"角色跃迁": "char",
|
||||
"光锥跃迁": "weapon",
|
||||
}
|
||||
HOMO_TAG = ['非到极致', '运气不好', '平稳保底', '小欧一把', '欧狗在此']
|
||||
HOMO_TAG = ["非到极致", "运气不好", "平稳保底", "小欧一把", "欧狗在此"]
|
||||
NORMAL_LIST = [
|
||||
'彦卿',
|
||||
'白露',
|
||||
'姬子',
|
||||
'瓦尔特',
|
||||
'布洛妮娅',
|
||||
'克拉拉',
|
||||
'杰帕德',
|
||||
'银河铁道之夜',
|
||||
'以世界之名',
|
||||
'但战斗还未结束',
|
||||
'制胜的瞬间',
|
||||
'无可取代的东西',
|
||||
'时节不居',
|
||||
'如泥酣眠',
|
||||
"彦卿",
|
||||
"白露",
|
||||
"姬子",
|
||||
"瓦尔特",
|
||||
"布洛妮娅",
|
||||
"克拉拉",
|
||||
"杰帕德",
|
||||
"银河铁道之夜",
|
||||
"以世界之名",
|
||||
"但战斗还未结束",
|
||||
"制胜的瞬间",
|
||||
"无可取代的东西",
|
||||
"时节不居",
|
||||
"如泥酣眠",
|
||||
]
|
||||
|
||||
UP_LIST = {
|
||||
'刻晴': [(2021, 2, 17, 18, 0, 0), (2021, 3, 2, 15, 59, 59)],
|
||||
'提纳里': [(2022, 8, 24, 11, 0, 0), (2022, 9, 9, 17, 59, 59)],
|
||||
'迪希雅': [(2023, 3, 1, 11, 0, 0), (2023, 3, 21, 17, 59, 59)],
|
||||
"刻晴": [(2021, 2, 17, 18, 0, 0), (2021, 3, 2, 15, 59, 59)],
|
||||
"提纳里": [(2022, 8, 24, 11, 0, 0), (2022, 9, 9, 17, 59, 59)],
|
||||
"迪希雅": [(2023, 3, 1, 11, 0, 0), (2023, 3, 21, 17, 59, 59)],
|
||||
}
|
||||
|
||||
|
||||
@ -80,24 +80,20 @@ async def _draw_card(
|
||||
gacha_num: int,
|
||||
is_up: bool,
|
||||
):
|
||||
card_img = Image.open(TEXT_PATH / 'char_bg.png')
|
||||
card_img = Image.open(TEXT_PATH / "char_bg.png")
|
||||
card_img_draw = ImageDraw.Draw(card_img)
|
||||
point = (47, 31)
|
||||
text_point = (100, 165)
|
||||
if card_type == '角色':
|
||||
if card_type == "角色":
|
||||
_id = await name_to_avatar_id(name)
|
||||
item_pic = (
|
||||
Image.open(CHAR_ICON_PATH / f'{_id}.png')
|
||||
.convert('RGBA')
|
||||
.resize((105, 105))
|
||||
Image.open(CHAR_ICON_PATH / f"{_id}.png").convert("RGBA").resize((105, 105))
|
||||
)
|
||||
else:
|
||||
name = await name_to_weapon_id(name)
|
||||
# _id = await weapon_id_to_en_name(name)
|
||||
item_pic = (
|
||||
Image.open(WEAPON_PATH / f'{name}.png')
|
||||
.convert('RGBA')
|
||||
.resize((124, 124))
|
||||
Image.open(WEAPON_PATH / f"{name}.png").convert("RGBA").resize((124, 124))
|
||||
)
|
||||
point = (37, 24)
|
||||
card_img.paste(item_pic, point, item_pic)
|
||||
@ -107,17 +103,15 @@ async def _draw_card(
|
||||
text_color = green_color
|
||||
else:
|
||||
text_color = brown_color
|
||||
card_img_draw.text(
|
||||
text_point, f'{gacha_num}抽', text_color, sr_font_24, 'mm'
|
||||
)
|
||||
card_img_draw.text(text_point, f"{gacha_num}抽", text_color, sr_font_24, "mm")
|
||||
if is_up:
|
||||
logger.info(f'up: {name}')
|
||||
logger.info(f"up: {name}")
|
||||
# card_img.paste(up_tag, (47, -2), up_tag)
|
||||
img.paste(card_img, xy_point, card_img)
|
||||
|
||||
|
||||
async def random_emo_pic(level: int) -> Image.Image:
|
||||
emo_fold = EMO_PATH / f'3000{level}.png'
|
||||
emo_fold = EMO_PATH / f"3000{level}.png"
|
||||
return Image.open(emo_fold)
|
||||
|
||||
|
||||
@ -140,7 +134,7 @@ def check_up(name: str, _time: str) -> bool:
|
||||
time = UP_LIST[char]
|
||||
s_time = datetime.datetime(*time[0])
|
||||
e_time = datetime.datetime(*time[1])
|
||||
gacha_time = datetime.datetime.strptime(_time, '%Y-%m-%d %H:%M:%S')
|
||||
gacha_time = datetime.datetime.strptime(_time, "%Y-%m-%d %H:%M:%S")
|
||||
if gacha_time < s_time or gacha_time > e_time:
|
||||
return False
|
||||
return True
|
||||
@ -148,33 +142,33 @@ def check_up(name: str, _time: str) -> bool:
|
||||
|
||||
|
||||
async def draw_gachalogs_img(uid: str, user_id: str) -> Union[bytes, str]:
|
||||
path = PLAYER_PATH / str(uid) / 'gacha_logs.json'
|
||||
path = PLAYER_PATH / str(uid) / "gacha_logs.json"
|
||||
if not path.exists():
|
||||
return '你还没有跃迁数据噢~\n请使用命令`sr导入抽卡链接`更新跃迁数据~'
|
||||
with Path.open(path, encoding='UTF-8') as f:
|
||||
return "你还没有跃迁数据噢~\n请使用命令`sr导入抽卡链接`更新跃迁数据~"
|
||||
with Path.open(path, encoding="UTF-8") as f:
|
||||
gacha_data = json.load(f)
|
||||
|
||||
# 数据初始化
|
||||
total_data = {}
|
||||
for i in ['群星跃迁', '始发跃迁', '角色跃迁', '光锥跃迁']:
|
||||
for i in ["群星跃迁", "始发跃迁", "角色跃迁", "光锥跃迁"]:
|
||||
total_data[i] = {
|
||||
'total': 0, # 五星总数
|
||||
'avg': 0, # 抽卡平均数
|
||||
'avg_up': 0, # up平均数
|
||||
'remain': 0, # 已xx抽未出金
|
||||
'r_num': [], # 不包含首位的抽卡数量
|
||||
'e_num': [], # 包含首位的up抽卡数量
|
||||
'up_list': [], # 抽到的UP列表(不包含首位)
|
||||
'normal_list': [], # 抽到的五星列表(不包含首位)
|
||||
'list': [], # 抽到的五星列表
|
||||
'time_range': '', # 抽卡时间
|
||||
'all_time': 0, # 抽卡总计秒数
|
||||
'type': '一般型', # 抽卡类型: 随缘型, 氪金型, 规划型, 仓鼠型, 佛系型
|
||||
'short_gacha_data': {'time': 0, 'num': 0},
|
||||
'long_gacha_data': {'time': 0, 'num': 0},
|
||||
"total": 0, # 五星总数
|
||||
"avg": 0, # 抽卡平均数
|
||||
"avg_up": 0, # up平均数
|
||||
"remain": 0, # 已xx抽未出金
|
||||
"r_num": [], # 不包含首位的抽卡数量
|
||||
"e_num": [], # 包含首位的up抽卡数量
|
||||
"up_list": [], # 抽到的UP列表(不包含首位)
|
||||
"normal_list": [], # 抽到的五星列表(不包含首位)
|
||||
"list": [], # 抽到的五星列表
|
||||
"time_range": "", # 抽卡时间
|
||||
"all_time": 0, # 抽卡总计秒数
|
||||
"type": "一般型", # 抽卡类型: 随缘型, 氪金型, 规划型, 仓鼠型, 佛系型
|
||||
"short_gacha_data": {"time": 0, "num": 0},
|
||||
"long_gacha_data": {"time": 0, "num": 0},
|
||||
}
|
||||
# 拿到数据列表
|
||||
data_list = gacha_data['data'][i]
|
||||
data_list = gacha_data["data"][i]
|
||||
# 初始化开关
|
||||
is_not_first = True
|
||||
# 开始初始化抽卡数
|
||||
@ -184,141 +178,137 @@ async def draw_gachalogs_img(uid: str, user_id: str) -> Union[bytes, str]:
|
||||
for index, data in enumerate(data_list[::-1]):
|
||||
# 计算抽卡时间跨度
|
||||
if index == 0:
|
||||
total_data[i]['time_range'] = data['time']
|
||||
total_data[i]["time_range"] = data["time"]
|
||||
if index == len(data_list) - 1:
|
||||
total_data[i]['all_time'] = (
|
||||
datetime.datetime.strptime(
|
||||
data['time'], '%Y-%m-%d %H:%M:%S'
|
||||
)
|
||||
total_data[i]["all_time"] = (
|
||||
datetime.datetime.strptime(data["time"], "%Y-%m-%d %H:%M:%S")
|
||||
- datetime.datetime.strptime(
|
||||
total_data[i]['time_range'], '%Y-%m-%d %H:%M:%S'
|
||||
total_data[i]["time_range"], "%Y-%m-%d %H:%M:%S"
|
||||
)
|
||||
).total_seconds()
|
||||
total_data[i]['time_range'] += '~' + data['time']
|
||||
total_data[i]["time_range"] += "~" + data["time"]
|
||||
|
||||
# 计算时间间隔
|
||||
if index != 0:
|
||||
now_time = datetime.datetime.strptime(
|
||||
data['time'], '%Y-%m-%d %H:%M:%S'
|
||||
)
|
||||
now_time = datetime.datetime.strptime(data["time"], "%Y-%m-%d %H:%M:%S")
|
||||
dis = (now_time - temp_time).total_seconds()
|
||||
temp_time = now_time
|
||||
if dis <= 5000:
|
||||
total_data[i]['short_gacha_data']['num'] += 1
|
||||
total_data[i]['short_gacha_data']['time'] += dis
|
||||
total_data[i]["short_gacha_data"]["num"] += 1
|
||||
total_data[i]["short_gacha_data"]["time"] += dis
|
||||
elif dis >= 86400:
|
||||
total_data[i]['long_gacha_data']['num'] += 1
|
||||
total_data[i]['long_gacha_data']['time'] += dis
|
||||
total_data[i]["long_gacha_data"]["num"] += 1
|
||||
total_data[i]["long_gacha_data"]["time"] += dis
|
||||
else:
|
||||
temp_time = datetime.datetime.strptime(
|
||||
data['time'], '%Y-%m-%d %H:%M:%S'
|
||||
data["time"], "%Y-%m-%d %H:%M:%S"
|
||||
)
|
||||
|
||||
# 如果这是个五星
|
||||
if data['rank_type'] == '5':
|
||||
if data["rank_type"] == "5":
|
||||
# 抽到这个五星花了多少抽
|
||||
data['gacha_num'] = num
|
||||
data["gacha_num"] = num
|
||||
|
||||
# 判断是否是UP
|
||||
if data['name'] in NORMAL_LIST:
|
||||
data['is_up'] = False
|
||||
elif data['name'] in UP_LIST:
|
||||
data['is_up'] = check_up(data['name'], data['time'])
|
||||
if data["name"] in NORMAL_LIST:
|
||||
data["is_up"] = False
|
||||
elif data["name"] in UP_LIST:
|
||||
data["is_up"] = check_up(data["name"], data["time"])
|
||||
else:
|
||||
data['is_up'] = True
|
||||
data["is_up"] = True
|
||||
|
||||
# 往里加东西
|
||||
if is_not_first:
|
||||
total_data[i]['r_num'].append(num)
|
||||
total_data[i]['normal_list'].append(data)
|
||||
if data['is_up']:
|
||||
total_data[i]['up_list'].append(data)
|
||||
total_data[i]["r_num"].append(num)
|
||||
total_data[i]["normal_list"].append(data)
|
||||
if data["is_up"]:
|
||||
total_data[i]["up_list"].append(data)
|
||||
|
||||
# 把这个数据扔到抽到的五星列表内
|
||||
total_data[i]['list'].append(data)
|
||||
total_data[i]["list"].append(data)
|
||||
|
||||
# 判断经过了第一个
|
||||
if total_data[i]['list']:
|
||||
if total_data[i]["list"]:
|
||||
is_not_first = True
|
||||
|
||||
num = 1
|
||||
# 五星总数增加1
|
||||
total_data[i]['total'] += 1
|
||||
total_data[i]["total"] += 1
|
||||
else:
|
||||
num += 1
|
||||
|
||||
# 计算已多少抽
|
||||
total_data[i]['remain'] = num - 1
|
||||
total_data[i]["remain"] = num - 1
|
||||
|
||||
# 计算平均抽卡数
|
||||
if len(total_data[i]['normal_list']) == 0:
|
||||
total_data[i]['avg'] = 0
|
||||
if len(total_data[i]["normal_list"]) == 0:
|
||||
total_data[i]["avg"] = 0
|
||||
else:
|
||||
total_data[i]['avg'] = float(
|
||||
'{:.2f}'.format(
|
||||
sum(total_data[i]['r_num']) / len(total_data[i]['r_num'])
|
||||
total_data[i]["avg"] = float(
|
||||
"{:.2f}".format(
|
||||
sum(total_data[i]["r_num"]) / len(total_data[i]["r_num"])
|
||||
)
|
||||
)
|
||||
# 计算平均up数量
|
||||
if len(total_data[i]['up_list']) == 0:
|
||||
total_data[i]['avg_up'] = 0
|
||||
if len(total_data[i]["up_list"]) == 0:
|
||||
total_data[i]["avg_up"] = 0
|
||||
else:
|
||||
total_data[i]['avg_up'] = float(
|
||||
'{:.2f}'.format(
|
||||
sum(total_data[i]['r_num']) / len(total_data[i]['up_list'])
|
||||
total_data[i]["avg_up"] = float(
|
||||
"{:.2f}".format(
|
||||
sum(total_data[i]["r_num"]) / len(total_data[i]["up_list"])
|
||||
)
|
||||
)
|
||||
|
||||
# 计算抽卡类型
|
||||
# 如果抽卡总数小于40
|
||||
if gacha_data[f'{CHANGE_MAP[i]}_gacha_num'] <= 40:
|
||||
total_data[i]['type'] = '佛系型'
|
||||
if gacha_data[f"{CHANGE_MAP[i]}_gacha_num"] <= 40:
|
||||
total_data[i]["type"] = "佛系型"
|
||||
# 如果长时抽卡总数占据了总抽卡数的70%
|
||||
elif (
|
||||
total_data[i]['long_gacha_data']['num']
|
||||
/ gacha_data[f'{CHANGE_MAP[i]}_gacha_num']
|
||||
total_data[i]["long_gacha_data"]["num"]
|
||||
/ gacha_data[f"{CHANGE_MAP[i]}_gacha_num"]
|
||||
>= 0.7
|
||||
):
|
||||
total_data[i]['type'] = '随缘型'
|
||||
total_data[i]["type"] = "随缘型"
|
||||
# 如果短时抽卡总数占据了总抽卡数的70%
|
||||
elif (
|
||||
total_data[i]['short_gacha_data']['num']
|
||||
/ gacha_data[f'{CHANGE_MAP[i]}_gacha_num']
|
||||
total_data[i]["short_gacha_data"]["num"]
|
||||
/ gacha_data[f"{CHANGE_MAP[i]}_gacha_num"]
|
||||
>= 0.7
|
||||
):
|
||||
total_data[i]['type'] = '规划型'
|
||||
total_data[i]["type"] = "规划型"
|
||||
# 如果抽卡数量远远大于标称抽卡数量
|
||||
elif (
|
||||
total_data[i]['all_time'] / 30000
|
||||
<= gacha_data[f'{CHANGE_MAP[i]}_gacha_num']
|
||||
total_data[i]["all_time"] / 30000
|
||||
<= gacha_data[f"{CHANGE_MAP[i]}_gacha_num"]
|
||||
):
|
||||
# 如果长时抽卡数量大于短时抽卡数量
|
||||
if (
|
||||
total_data[i]['long_gacha_data']['num']
|
||||
>= total_data[i]['short_gacha_data']['num']
|
||||
total_data[i]["long_gacha_data"]["num"]
|
||||
>= total_data[i]["short_gacha_data"]["num"]
|
||||
):
|
||||
total_data[i]['type'] = '规划型'
|
||||
total_data[i]["type"] = "规划型"
|
||||
else:
|
||||
total_data[i]['type'] = '氪金型'
|
||||
total_data[i]["type"] = "氪金型"
|
||||
# 如果抽卡数量远远小于标称抽卡数量
|
||||
elif (
|
||||
total_data[i]['all_time'] / 32000
|
||||
>= gacha_data[f'{CHANGE_MAP[i]}_gacha_num'] * 2
|
||||
total_data[i]["all_time"] / 32000
|
||||
>= gacha_data[f"{CHANGE_MAP[i]}_gacha_num"] * 2
|
||||
):
|
||||
total_data[i]['type'] = '仓鼠型'
|
||||
total_data[i]["type"] = "仓鼠型"
|
||||
|
||||
# 常量偏移数据
|
||||
single_y = 170
|
||||
|
||||
# 计算图片尺寸
|
||||
normal_y = (1 + ((total_data['群星跃迁']['total'] - 1) // 5)) * single_y
|
||||
begin_y = (1 + ((total_data['始发跃迁']['total'] - 1) // 5)) * single_y
|
||||
char_y = (1 + ((total_data['角色跃迁']['total'] - 1) // 5)) * single_y
|
||||
weapon_y = (1 + ((total_data['光锥跃迁']['total'] - 1) // 5)) * single_y
|
||||
normal_y = (1 + ((total_data["群星跃迁"]["total"] - 1) // 5)) * single_y
|
||||
begin_y = (1 + ((total_data["始发跃迁"]["total"] - 1) // 5)) * single_y
|
||||
char_y = (1 + ((total_data["角色跃迁"]["total"] - 1) // 5)) * single_y
|
||||
weapon_y = (1 + ((total_data["光锥跃迁"]["total"] - 1) // 5)) * single_y
|
||||
|
||||
# 获取背景图片各项参数
|
||||
_id = str(user_id)
|
||||
if _id.startswith('http'):
|
||||
if _id.startswith("http"):
|
||||
char_pic = await get_qq_avatar(avatar_url=_id)
|
||||
else:
|
||||
char_pic = await get_qq_avatar(qid=user_id)
|
||||
@ -326,37 +316,35 @@ async def draw_gachalogs_img(uid: str, user_id: str) -> Union[bytes, str]:
|
||||
|
||||
# 获取背景图片各项参数
|
||||
img = Abg3_img.copy()
|
||||
img = await get_color_bg(
|
||||
800, 1600 + 400 + normal_y + char_y + weapon_y + begin_y
|
||||
)
|
||||
img = await get_color_bg(800, 1600 + 400 + normal_y + char_y + weapon_y + begin_y)
|
||||
gacha_title = bg1_img.copy()
|
||||
gacha_title.paste(char_pic, (297, 81), char_pic)
|
||||
img.paste(gacha_title, (0, 0), gacha_title)
|
||||
img_draw = ImageDraw.Draw(img)
|
||||
img_draw.text((400, 345), f'UID {uid}', white_color, sr_font_28, 'mm')
|
||||
img_draw.text((400, 345), f"UID {uid}", white_color, sr_font_28, "mm")
|
||||
|
||||
# 处理title
|
||||
# {'total': 0, 'avg': 0, 'remain': 0, 'list': []}
|
||||
type_list = ['角色跃迁', '光锥跃迁', '群星跃迁', '始发跃迁']
|
||||
type_list = ["角色跃迁", "光锥跃迁", "群星跃迁", "始发跃迁"]
|
||||
y_extend = 0
|
||||
level = 3
|
||||
for index, i in enumerate(type_list):
|
||||
title = Image.open(TEXT_PATH / 'bg2.png')
|
||||
if i == '群星跃迁':
|
||||
title = Image.open(TEXT_PATH / "bg2.png")
|
||||
if i == "群星跃迁":
|
||||
level = await get_level_from_list(
|
||||
total_data[i]['avg'], [54, 61, 67, 73, 80]
|
||||
total_data[i]["avg"], [54, 61, 67, 73, 80]
|
||||
)
|
||||
elif i == '始发跃迁':
|
||||
elif i == "始发跃迁":
|
||||
level = await get_level_from_list(
|
||||
total_data[i]['avg'], [10, 20, 30, 40, 50]
|
||||
total_data[i]["avg"], [10, 20, 30, 40, 50]
|
||||
)
|
||||
elif i == '光锥跃迁':
|
||||
elif i == "光锥跃迁":
|
||||
level = await get_level_from_list(
|
||||
total_data[i]['avg_up'], [62, 75, 88, 99, 111]
|
||||
total_data[i]["avg_up"], [62, 75, 88, 99, 111]
|
||||
)
|
||||
else:
|
||||
level = await get_level_from_list(
|
||||
total_data[i]['avg_up'], [74, 87, 99, 105, 120]
|
||||
total_data[i]["avg_up"], [74, 87, 99, 105, 120]
|
||||
)
|
||||
|
||||
emo_pic = await random_emo_pic(level)
|
||||
@ -364,55 +352,54 @@ async def draw_gachalogs_img(uid: str, user_id: str) -> Union[bytes, str]:
|
||||
title.paste(emo_pic, (500, 123), emo_pic)
|
||||
title_draw = ImageDraw.Draw(title)
|
||||
# 卡池
|
||||
title_draw.text((110, 73), i, whole_white_color, sr_font_38, 'lm')
|
||||
title_draw.text((110, 73), i, whole_white_color, sr_font_38, "lm")
|
||||
# 抽卡时间
|
||||
if total_data[i]['time_range']:
|
||||
time_range = total_data[i]['time_range']
|
||||
if total_data[i]["time_range"]:
|
||||
time_range = total_data[i]["time_range"]
|
||||
else:
|
||||
time_range = '暂未抽过卡!'
|
||||
title_draw.text((78, 340), time_range, brown_color, sr_font_20, 'lm')
|
||||
time_range = "暂未抽过卡!"
|
||||
title_draw.text((78, 340), time_range, brown_color, sr_font_20, "lm")
|
||||
# 平均抽卡数量
|
||||
title_draw.text(
|
||||
(143, 215),
|
||||
str(total_data[i]['avg']),
|
||||
str(total_data[i]["avg"]),
|
||||
first_color,
|
||||
sr_font_40,
|
||||
'mm',
|
||||
"mm",
|
||||
)
|
||||
# 平均up
|
||||
title_draw.text(
|
||||
(280, 215),
|
||||
str(total_data[i]['avg_up']),
|
||||
str(total_data[i]["avg_up"]),
|
||||
first_color,
|
||||
sr_font_40,
|
||||
'mm',
|
||||
"mm",
|
||||
)
|
||||
# 抽卡总数
|
||||
title_draw.text(
|
||||
(413, 215),
|
||||
str(gacha_data[f'{CHANGE_MAP[i]}_gacha_num']),
|
||||
str(gacha_data[f"{CHANGE_MAP[i]}_gacha_num"]),
|
||||
first_color,
|
||||
sr_font_40,
|
||||
'mm',
|
||||
"mm",
|
||||
)
|
||||
# 已抽数
|
||||
title_draw.text(
|
||||
(333, 75),
|
||||
str(total_data[i]['remain']),
|
||||
str(total_data[i]["remain"]),
|
||||
red_color,
|
||||
sr_font_28,
|
||||
'mm',
|
||||
"mm",
|
||||
)
|
||||
y_extend += (
|
||||
(1 + ((total_data[type_list[index - 1]]['total'] - 1) // 5))
|
||||
* single_y
|
||||
(1 + ((total_data[type_list[index - 1]]["total"] - 1) // 5)) * single_y
|
||||
if index != 0
|
||||
else 0
|
||||
)
|
||||
y = 350 + index * 400 + y_extend
|
||||
img.paste(title, (0, y), title)
|
||||
tasks = []
|
||||
for item_index, item in enumerate(total_data[i]['list']):
|
||||
for item_index, item in enumerate(total_data[i]["list"]):
|
||||
item_x = (item_index % 5) * 138 + 25
|
||||
item_y = (item_index // 5) * single_y + y + 355
|
||||
xy_point = (item_x, item_y)
|
||||
@ -420,10 +407,10 @@ async def draw_gachalogs_img(uid: str, user_id: str) -> Union[bytes, str]:
|
||||
_draw_card(
|
||||
img,
|
||||
xy_point,
|
||||
item['item_type'],
|
||||
item['name'],
|
||||
item['gacha_num'],
|
||||
item['is_up'],
|
||||
item["item_type"],
|
||||
item["name"],
|
||||
item["gacha_num"],
|
||||
item["is_up"],
|
||||
)
|
||||
)
|
||||
await asyncio.gather(*tasks)
|
||||
@ -431,6 +418,6 @@ async def draw_gachalogs_img(uid: str, user_id: str) -> Union[bytes, str]:
|
||||
|
||||
# 发送图片
|
||||
res = await convert_img(img)
|
||||
logger.info('[查询抽卡]绘图已完成,等待发送!')
|
||||
logger.info("[查询抽卡]绘图已完成,等待发送!")
|
||||
# res = 123
|
||||
return res
|
||||
|
@ -12,29 +12,27 @@ from ..utils.resource.RESOURCE_PATH import PLAYER_PATH
|
||||
from ..sruid_utils.api.mys.models import SingleGachaLog
|
||||
|
||||
gacha_type_meta_data = {
|
||||
'群星跃迁': ['1'],
|
||||
'始发跃迁': ['2'],
|
||||
'角色跃迁': ['11'],
|
||||
'光锥跃迁': ['12'],
|
||||
"群星跃迁": ["1"],
|
||||
"始发跃迁": ["2"],
|
||||
"角色跃迁": ["11"],
|
||||
"光锥跃迁": ["12"],
|
||||
}
|
||||
|
||||
|
||||
async def get_new_gachalog_by_link(
|
||||
uid: str, gacha_url: str, full_data: Dict, is_force: bool
|
||||
):
|
||||
full_data = msgspec.convert(
|
||||
full_data, type=Dict[str, List[SingleGachaLog]]
|
||||
)
|
||||
full_data = msgspec.convert(full_data, type=Dict[str, List[SingleGachaLog]])
|
||||
temp = []
|
||||
for gacha_name in gacha_type_meta_data:
|
||||
for gacha_type in gacha_type_meta_data[gacha_name]:
|
||||
end_id = '0'
|
||||
end_id = "0"
|
||||
for page in range(1, 999):
|
||||
url = parse.urlparse(gacha_url)
|
||||
url_parse = parse.parse_qs(url.query)
|
||||
if 'authkey' not in url_parse:
|
||||
if "authkey" not in url_parse:
|
||||
return {}
|
||||
authkey = url_parse['authkey'][0]
|
||||
authkey = url_parse["authkey"][0]
|
||||
data = await mys_api.get_gacha_log_by_link_in_authkey(
|
||||
uid, authkey, gacha_type, page, end_id
|
||||
)
|
||||
@ -74,13 +72,13 @@ async def save_gachalogs(
|
||||
|
||||
# 获取当前时间
|
||||
now = datetime.now()
|
||||
current_time = now.strftime('%Y-%m-%d %H-%M-%S')
|
||||
current_time = now.strftime("%Y-%m-%d %H-%M-%S")
|
||||
|
||||
# 初始化最后保存的数据
|
||||
result = {}
|
||||
|
||||
# 抽卡记录json路径
|
||||
gachalogs_path = path / 'gacha_logs.json'
|
||||
gachalogs_path = path / "gacha_logs.json"
|
||||
|
||||
# 如果有老的,准备合并, 先打开文件
|
||||
gachalogs_history = {}
|
||||
@ -91,19 +89,19 @@ async def save_gachalogs(
|
||||
old_weapon_gacha_num,
|
||||
) = (0, 0, 0, 0)
|
||||
if gachalogs_path.exists():
|
||||
with Path.open(gachalogs_path, encoding='UTF-8') as f:
|
||||
with Path.open(gachalogs_path, encoding="UTF-8") as f:
|
||||
gachalogs_history: Dict = json.load(f)
|
||||
gachalogs_history = gachalogs_history['data']
|
||||
old_normal_gacha_num = len(gachalogs_history['群星跃迁'])
|
||||
old_begin_gacha_num = len(gachalogs_history['始发跃迁'])
|
||||
old_char_gacha_num = len(gachalogs_history['角色跃迁'])
|
||||
old_weapon_gacha_num = len(gachalogs_history['光锥跃迁'])
|
||||
gachalogs_history = gachalogs_history["data"]
|
||||
old_normal_gacha_num = len(gachalogs_history["群星跃迁"])
|
||||
old_begin_gacha_num = len(gachalogs_history["始发跃迁"])
|
||||
old_char_gacha_num = len(gachalogs_history["角色跃迁"])
|
||||
old_weapon_gacha_num = len(gachalogs_history["光锥跃迁"])
|
||||
else:
|
||||
gachalogs_history = {
|
||||
'群星跃迁': [],
|
||||
'始发跃迁': [],
|
||||
'角色跃迁': [],
|
||||
'光锥跃迁': [],
|
||||
"群星跃迁": [],
|
||||
"始发跃迁": [],
|
||||
"角色跃迁": [],
|
||||
"光锥跃迁": [],
|
||||
}
|
||||
|
||||
# 获取新抽卡记录
|
||||
@ -113,69 +111,66 @@ async def save_gachalogs(
|
||||
)
|
||||
else:
|
||||
new_data = {
|
||||
'始发跃迁': [],
|
||||
'群星跃迁': [],
|
||||
'角色跃迁': [],
|
||||
'光锥跃迁': [],
|
||||
"始发跃迁": [],
|
||||
"群星跃迁": [],
|
||||
"角色跃迁": [],
|
||||
"光锥跃迁": [],
|
||||
}
|
||||
if gachalogs_history:
|
||||
for i in ['始发跃迁', '群星跃迁', '角色跃迁', '光锥跃迁']:
|
||||
for i in ["始发跃迁", "群星跃迁", "角色跃迁", "光锥跃迁"]:
|
||||
for item in raw_data[i]:
|
||||
if (
|
||||
item not in gachalogs_history[i]
|
||||
and item not in new_data[i]
|
||||
):
|
||||
if item not in gachalogs_history[i] and item not in new_data[i]:
|
||||
new_data[i].append(item)
|
||||
raw_data = new_data
|
||||
for i in ['始发跃迁', '群星跃迁', '角色跃迁', '光锥跃迁']:
|
||||
for i in ["始发跃迁", "群星跃迁", "角色跃迁", "光锥跃迁"]:
|
||||
raw_data[i].extend(gachalogs_history[i])
|
||||
|
||||
if raw_data == {} or not raw_data:
|
||||
return '请给出正确的抽卡记录链接或链接已失效'
|
||||
return "请给出正确的抽卡记录链接或链接已失效"
|
||||
|
||||
temp_data = {
|
||||
'始发跃迁': [],
|
||||
'群星跃迁': [],
|
||||
'角色跃迁': [],
|
||||
'光锥跃迁': [],
|
||||
"始发跃迁": [],
|
||||
"群星跃迁": [],
|
||||
"角色跃迁": [],
|
||||
"光锥跃迁": [],
|
||||
}
|
||||
for i in ['始发跃迁', '群星跃迁', '角色跃迁', '光锥跃迁']:
|
||||
for i in ["始发跃迁", "群星跃迁", "角色跃迁", "光锥跃迁"]:
|
||||
for item in raw_data[i]:
|
||||
if item not in temp_data[i]:
|
||||
temp_data[i].append(item)
|
||||
raw_data = temp_data
|
||||
|
||||
result['uid'] = uid
|
||||
result['data_time'] = current_time
|
||||
result['normal_gacha_num'] = len(raw_data['群星跃迁'])
|
||||
result['begin_gacha_num'] = len(raw_data['始发跃迁'])
|
||||
result['char_gacha_num'] = len(raw_data['角色跃迁'])
|
||||
result['weapon_gacha_num'] = len(raw_data['光锥跃迁'])
|
||||
for i in ['群星跃迁', '角色跃迁', '光锥跃迁']:
|
||||
result["uid"] = uid
|
||||
result["data_time"] = current_time
|
||||
result["normal_gacha_num"] = len(raw_data["群星跃迁"])
|
||||
result["begin_gacha_num"] = len(raw_data["始发跃迁"])
|
||||
result["char_gacha_num"] = len(raw_data["角色跃迁"])
|
||||
result["weapon_gacha_num"] = len(raw_data["光锥跃迁"])
|
||||
for i in ["群星跃迁", "角色跃迁", "光锥跃迁"]:
|
||||
if len(raw_data[i]) > 1:
|
||||
raw_data[i].sort(key=lambda x: (-int(x.id)))
|
||||
result['data'] = raw_data
|
||||
result["data"] = raw_data
|
||||
|
||||
# 计算数据
|
||||
normal_add = result['normal_gacha_num'] - old_normal_gacha_num
|
||||
begin_gacha_add = result['begin_gacha_num'] - old_begin_gacha_num
|
||||
char_add = result['char_gacha_num'] - old_char_gacha_num
|
||||
weapon_add = result['weapon_gacha_num'] - old_weapon_gacha_num
|
||||
normal_add = result["normal_gacha_num"] - old_normal_gacha_num
|
||||
begin_gacha_add = result["begin_gacha_num"] - old_begin_gacha_num
|
||||
char_add = result["char_gacha_num"] - old_char_gacha_num
|
||||
weapon_add = result["weapon_gacha_num"] - old_weapon_gacha_num
|
||||
all_add = normal_add + char_add + weapon_add + begin_gacha_add
|
||||
|
||||
# 保存文件
|
||||
result = msgspec.to_builtins(result)
|
||||
with Path.open(gachalogs_path, 'w', encoding='UTF-8') as file:
|
||||
with Path.open(gachalogs_path, "w", encoding="UTF-8") as file:
|
||||
json.dump(result, file, indent=2, ensure_ascii=False)
|
||||
|
||||
# 回复文字
|
||||
if all_add == 0:
|
||||
im = f'UID{uid}没有新增祈愿数据!'
|
||||
im = f"UID{uid}没有新增祈愿数据!"
|
||||
else:
|
||||
im = (
|
||||
f'UID{uid}数据更新成功!'
|
||||
f'本次更新{all_add}个数据\n'
|
||||
f'群星跃迁{normal_add}个\n始发跃迁{begin_gacha_add}\n'
|
||||
f'角色跃迁{char_add}个\n光锥跃迁{weapon_add}个!'
|
||||
f"UID{uid}数据更新成功!"
|
||||
f"本次更新{all_add}个数据\n"
|
||||
f"群星跃迁{normal_add}个\n始发跃迁{begin_gacha_add}\n"
|
||||
f"角色跃迁{char_add}个\n光锥跃迁{weapon_add}个!"
|
||||
)
|
||||
return im
|
||||
|
@ -6,11 +6,11 @@ from gsuid_core.logger import logger
|
||||
from .get_help import get_core_help
|
||||
from ..utils.sr_prefix import PREFIX
|
||||
|
||||
sv_sr_help = SV('sr帮助')
|
||||
sv_sr_help = SV("sr帮助")
|
||||
|
||||
|
||||
@sv_sr_help.on_fullmatch(f'{PREFIX}帮助')
|
||||
@sv_sr_help.on_fullmatch(f"{PREFIX}帮助")
|
||||
async def send_help_img(bot: Bot, ev: Event):
|
||||
logger.info('开始执行[sr帮助]')
|
||||
logger.info("开始执行[sr帮助]")
|
||||
im = await get_core_help()
|
||||
await bot.send(im)
|
||||
|
@ -10,32 +10,30 @@ from gsuid_core.help.draw_plugin_help import get_help
|
||||
from ..version import StarRail_version
|
||||
from ..utils.fonts.starrail_fonts import starrail_font_origin
|
||||
|
||||
TEXT_PATH = Path(__file__).parent / 'texture2d'
|
||||
HELP_DATA = Path(__file__).parent / 'Help.json'
|
||||
TEXT_PATH = Path(__file__).parent / "texture2d"
|
||||
HELP_DATA = Path(__file__).parent / "Help.json"
|
||||
|
||||
|
||||
async def get_help_data() -> Optional[Dict[str, PluginHelp]]:
|
||||
if HELP_DATA.exists():
|
||||
async with aiofiles.open(HELP_DATA, 'rb') as file:
|
||||
return msgjson.decode(
|
||||
await file.read(), type=Dict[str, PluginHelp]
|
||||
)
|
||||
async with aiofiles.open(HELP_DATA, "rb") as file:
|
||||
return msgjson.decode(await file.read(), type=Dict[str, PluginHelp])
|
||||
return None
|
||||
|
||||
|
||||
async def get_core_help() -> Union[bytes, str]:
|
||||
help_data = await get_help_data()
|
||||
if help_data is None:
|
||||
return '暂未找到帮助数据...'
|
||||
return "暂未找到帮助数据..."
|
||||
|
||||
return await get_help(
|
||||
'StarRailUID',
|
||||
f'版本号:{StarRail_version}',
|
||||
"StarRailUID",
|
||||
f"版本号:{StarRail_version}",
|
||||
help_data,
|
||||
Image.open(TEXT_PATH / 'bg.jpg'),
|
||||
Image.open(TEXT_PATH / 'ICON.png'),
|
||||
Image.open(TEXT_PATH / 'badge.png'),
|
||||
Image.open(TEXT_PATH / 'banner.png'),
|
||||
Image.open(TEXT_PATH / 'button.png'),
|
||||
Image.open(TEXT_PATH / "bg.jpg"),
|
||||
Image.open(TEXT_PATH / "ICON.png"),
|
||||
Image.open(TEXT_PATH / "badge.png"),
|
||||
Image.open(TEXT_PATH / "banner.png"),
|
||||
Image.open(TEXT_PATH / "button.png"),
|
||||
starrail_font_origin,
|
||||
)
|
||||
|
@ -1,21 +1,21 @@
|
||||
from gsuid_core.sv import SV
|
||||
from .draw_note_card import draw_note_img
|
||||
from .note_text import award
|
||||
from ..utils.error_reply import UID_HINT
|
||||
from ..utils.sr_prefix import PREFIX
|
||||
|
||||
from gsuid_core.bot import Bot
|
||||
from gsuid_core.models import Event
|
||||
from gsuid_core.sv import SV
|
||||
from gsuid_core.utils.database.api import get_uid
|
||||
from gsuid_core.utils.database.models import GsBind
|
||||
|
||||
from .note_text import award
|
||||
from ..utils.convert import get_uid
|
||||
from ..utils.sr_prefix import PREFIX
|
||||
from ..utils.error_reply import UID_HINT
|
||||
from .draw_note_card import draw_note_img
|
||||
|
||||
sv_get_monthly_data = SV('sr查询月历')
|
||||
sv_get_monthly_data = SV("sr查询月历")
|
||||
|
||||
|
||||
# 群聊内 每月统计 功能
|
||||
@sv_get_monthly_data.on_fullmatch(f'{PREFIX}每月统计')
|
||||
@sv_get_monthly_data.on_fullmatch(f"{PREFIX}每月统计")
|
||||
async def send_monthly_data(bot: Bot, ev: Event):
|
||||
sr_uid = await GsBind.get_uid_by_game(ev.user_id, ev.bot_id, 'sr')
|
||||
sr_uid = await GsBind.get_uid_by_game(ev.user_id, ev.bot_id, "sr")
|
||||
if sr_uid is None:
|
||||
return UID_HINT
|
||||
await bot.send(await award(sr_uid))
|
||||
@ -24,14 +24,14 @@ async def send_monthly_data(bot: Bot, ev: Event):
|
||||
|
||||
@sv_get_monthly_data.on_fullmatch(
|
||||
(
|
||||
f'{PREFIX}开拓月历',
|
||||
f'{PREFIX}zj',
|
||||
f'{PREFIX}月历',
|
||||
f"{PREFIX}开拓月历",
|
||||
f"{PREFIX}zj",
|
||||
f"{PREFIX}月历",
|
||||
)
|
||||
)
|
||||
async def send_monthly_pic(bot: Bot, ev: Event):
|
||||
await bot.logger.info('开始执行[sr开拓月历]')
|
||||
sr_uid = await get_uid(bot, ev)
|
||||
await bot.logger.info("开始执行[sr开拓月历]")
|
||||
sr_uid = await get_uid(bot, ev, GsBind, "sr")
|
||||
if sr_uid is None:
|
||||
return UID_HINT
|
||||
im = await draw_note_img(str(sr_uid))
|
||||
|
@ -1,23 +1,23 @@
|
||||
from datetime import datetime
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Union
|
||||
from datetime import datetime
|
||||
|
||||
from PIL import Image, ImageDraw
|
||||
from msgspec import json as msgjson
|
||||
from gsuid_core.logger import logger
|
||||
from gsuid_core.utils.image.convert import convert_img
|
||||
from msgspec import json as msgjson
|
||||
|
||||
from ..utils.mys_api import mys_api
|
||||
from ..utils.error_reply import get_error
|
||||
from ..utils.image.convert import convert_img
|
||||
from ..sruid_utils.api.mys.models import MonthlyAward
|
||||
from ..utils.resource.RESOURCE_PATH import PLAYER_PATH
|
||||
from ..utils.error_reply import get_error
|
||||
from ..utils.fonts.starrail_fonts import sr_font_20, sr_font_28, sr_font_34
|
||||
from ..utils.mys_api import mys_api
|
||||
from ..utils.resource.RESOURCE_PATH import PLAYER_PATH
|
||||
|
||||
TEXT_PATH = Path(__file__).parent / 'texture2d'
|
||||
TEXT_PATH = Path(__file__).parent / "texture2d"
|
||||
|
||||
monthly_bg = Image.open(TEXT_PATH / 'monthly_bg.png')
|
||||
avatar_default = Image.open(TEXT_PATH / '200101.png')
|
||||
monthly_bg = Image.open(TEXT_PATH / "monthly_bg.png")
|
||||
avatar_default = Image.open(TEXT_PATH / "200101.png")
|
||||
|
||||
first_color = (29, 29, 29)
|
||||
second_color = (67, 61, 56)
|
||||
@ -26,20 +26,20 @@ black_color = (54, 54, 54)
|
||||
white_color = (213, 213, 213)
|
||||
|
||||
COLOR_MAP = {
|
||||
'每日活跃': (248, 227, 157),
|
||||
'活动奖励': (99, 231, 176),
|
||||
'冒险奖励': (114, 205, 251),
|
||||
'模拟宇宙奖励': (160, 149, 248),
|
||||
'忘却之庭奖励': (221, 119, 250),
|
||||
'邮件奖励': (244, 110, 104),
|
||||
'其他': (255, 242, 200),
|
||||
'Daily Activity': (248, 227, 157),
|
||||
'Events': (99, 231, 176),
|
||||
'Adventure': (114, 205, 251),
|
||||
'moni': (160, 149, 248),
|
||||
'Spiral Abyss': (221, 119, 250),
|
||||
'Quests': (244, 110, 104),
|
||||
'Other': (255, 242, 200),
|
||||
"每日活跃": (248, 227, 157),
|
||||
"活动奖励": (99, 231, 176),
|
||||
"冒险奖励": (114, 205, 251),
|
||||
"模拟宇宙奖励": (160, 149, 248),
|
||||
"忘却之庭奖励": (221, 119, 250),
|
||||
"邮件奖励": (244, 110, 104),
|
||||
"其他": (255, 242, 200),
|
||||
"Daily Activity": (248, 227, 157),
|
||||
"Events": (99, 231, 176),
|
||||
"Adventure": (114, 205, 251),
|
||||
"moni": (160, 149, 248),
|
||||
"Spiral Abyss": (221, 119, 250),
|
||||
"Quests": (244, 110, 104),
|
||||
"Other": (255, 242, 200),
|
||||
}
|
||||
|
||||
|
||||
@ -50,25 +50,25 @@ async def draw_note_img(sr_uid: str) -> Union[bytes, str]:
|
||||
|
||||
# 获取当前时间
|
||||
now = datetime.now()
|
||||
current_year_mon = now.strftime('%Y-%m')
|
||||
add_month = ''
|
||||
current_year_mon = now.strftime("%Y-%m")
|
||||
add_month = ""
|
||||
if int(now.month) < 10:
|
||||
add_month = '0'
|
||||
add_month = "0"
|
||||
now_month = str(now.year) + str(add_month) + str(now.month)
|
||||
# 获取数据
|
||||
data = await mys_api.get_award(sr_uid, now_month)
|
||||
data = await mys_api.get_sr_award(sr_uid, now_month)
|
||||
if isinstance(data, int):
|
||||
return get_error(data)
|
||||
|
||||
# 保存数据
|
||||
with Path.open(
|
||||
path / f'monthly_{current_year_mon}.json', 'w', encoding='utf-8'
|
||||
path / f"monthly_{current_year_mon}.json", "w", encoding="utf-8"
|
||||
) as f:
|
||||
save_json_data = msgjson.format(msgjson.encode(data), indent=4)
|
||||
save_data = json.dumps(
|
||||
{
|
||||
'data_time': now.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
'data': save_json_data.decode('utf-8'),
|
||||
"data_time": now.strftime("%Y-%m-%d %H:%M:%S"),
|
||||
"data": save_json_data.decode("utf-8"),
|
||||
},
|
||||
ensure_ascii=False,
|
||||
)
|
||||
@ -80,33 +80,31 @@ async def draw_note_img(sr_uid: str) -> Union[bytes, str]:
|
||||
if last_month == 0:
|
||||
last_month = 12
|
||||
last_year -= 1
|
||||
last_year_mon = f'{last_year}-{last_month:02d}'
|
||||
last_monthly_path = path / f'monthly_{last_year_mon}.json'
|
||||
last_year_mon = f"{last_year}-{last_month:02d}"
|
||||
last_monthly_path = path / f"monthly_{last_year_mon}.json"
|
||||
if last_monthly_path.exists():
|
||||
with Path.open(last_monthly_path, encoding='utf-8') as f:
|
||||
with Path.open(last_monthly_path, encoding="utf-8") as f:
|
||||
last_monthly_data = json.load(f)
|
||||
last_monthly_data = msgjson.decode(
|
||||
last_monthly_data['data'], type=MonthlyAward
|
||||
last_monthly_data["data"], type=MonthlyAward
|
||||
)
|
||||
else:
|
||||
add_month = ''
|
||||
add_month = ""
|
||||
if int(last_month) < 10:
|
||||
add_month = '0'
|
||||
add_month = "0"
|
||||
find_last_month = str(last_year) + str(add_month) + str(last_month)
|
||||
last_monthly_data = await mys_api.get_award(sr_uid, find_last_month)
|
||||
last_monthly_data = await mys_api.get_sr_award(sr_uid, find_last_month)
|
||||
if isinstance(last_monthly_data, int):
|
||||
return get_error(last_monthly_data)
|
||||
# 保存上月数据
|
||||
with Path.open(
|
||||
path / f'monthly_{last_year_mon}.json', 'w', encoding='utf-8'
|
||||
path / f"monthly_{last_year_mon}.json", "w", encoding="utf-8"
|
||||
) as f:
|
||||
save_json_data = msgjson.format(
|
||||
msgjson.encode(last_monthly_data), indent=4
|
||||
)
|
||||
save_json_data = msgjson.format(msgjson.encode(last_monthly_data), indent=4)
|
||||
save_data = json.dumps(
|
||||
{
|
||||
'data_time': now.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
'data': save_json_data.decode('utf-8'),
|
||||
"data_time": now.strftime("%Y-%m-%d %H:%M:%S"),
|
||||
"data": save_json_data.decode("utf-8"),
|
||||
},
|
||||
ensure_ascii=False,
|
||||
)
|
||||
@ -141,7 +139,7 @@ async def draw_note_img(sr_uid: str) -> Union[bytes, str]:
|
||||
|
||||
img = monthly_bg.copy()
|
||||
avatar_img = avatar_default.copy()
|
||||
char_pic = avatar_img.convert('RGBA').resize(
|
||||
char_pic = avatar_img.convert("RGBA").resize(
|
||||
(125, 125),
|
||||
Image.Resampling.LANCZOS, # type: ignore
|
||||
)
|
||||
@ -149,17 +147,15 @@ async def draw_note_img(sr_uid: str) -> Union[bytes, str]:
|
||||
img_draw = ImageDraw.Draw(img)
|
||||
|
||||
# 写Nickname
|
||||
img_draw.text(
|
||||
(310, 184), nickname, font=sr_font_34, fill=first_color, anchor='lm'
|
||||
)
|
||||
img_draw.text((310, 184), nickname, font=sr_font_34, fill=first_color, anchor="lm")
|
||||
|
||||
# 写UID
|
||||
img_draw.text(
|
||||
(267, 219),
|
||||
f'UID {sr_uid}',
|
||||
f"UID {sr_uid}",
|
||||
font=sr_font_20,
|
||||
fill=second_color2,
|
||||
anchor='lm',
|
||||
anchor="lm",
|
||||
)
|
||||
|
||||
# 写本日星琼
|
||||
@ -168,7 +164,7 @@ async def draw_note_img(sr_uid: str) -> Union[bytes, str]:
|
||||
day_hcoin_str,
|
||||
font=sr_font_28,
|
||||
fill=white_color,
|
||||
anchor='lm',
|
||||
anchor="lm",
|
||||
)
|
||||
|
||||
# 写本月星琼
|
||||
@ -177,7 +173,7 @@ async def draw_note_img(sr_uid: str) -> Union[bytes, str]:
|
||||
month_hcoin_str,
|
||||
font=sr_font_28,
|
||||
fill=white_color,
|
||||
anchor='lm',
|
||||
anchor="lm",
|
||||
)
|
||||
|
||||
# 写昨日星琼
|
||||
@ -186,7 +182,7 @@ async def draw_note_img(sr_uid: str) -> Union[bytes, str]:
|
||||
lastday_hcoin_str,
|
||||
font=sr_font_28,
|
||||
fill=black_color,
|
||||
anchor='lm',
|
||||
anchor="lm",
|
||||
)
|
||||
|
||||
# 写上月星琼
|
||||
@ -195,7 +191,7 @@ async def draw_note_img(sr_uid: str) -> Union[bytes, str]:
|
||||
lastmonth_hcoin_str,
|
||||
font=sr_font_28,
|
||||
fill=black_color,
|
||||
anchor='lm',
|
||||
anchor="lm",
|
||||
)
|
||||
|
||||
# 写本日铁票
|
||||
@ -204,7 +200,7 @@ async def draw_note_img(sr_uid: str) -> Union[bytes, str]:
|
||||
day_rails_pass_str,
|
||||
font=sr_font_28,
|
||||
fill=white_color,
|
||||
anchor='lm',
|
||||
anchor="lm",
|
||||
)
|
||||
|
||||
# 写本月铁票
|
||||
@ -213,7 +209,7 @@ async def draw_note_img(sr_uid: str) -> Union[bytes, str]:
|
||||
month_rails_pass_str,
|
||||
font=sr_font_28,
|
||||
fill=white_color,
|
||||
anchor='lm',
|
||||
anchor="lm",
|
||||
)
|
||||
|
||||
# 写昨日铁票
|
||||
@ -222,7 +218,7 @@ async def draw_note_img(sr_uid: str) -> Union[bytes, str]:
|
||||
lastday_rails_pass_str,
|
||||
font=sr_font_28,
|
||||
fill=black_color,
|
||||
anchor='lm',
|
||||
anchor="lm",
|
||||
)
|
||||
|
||||
# 写上月铁票
|
||||
@ -231,16 +227,16 @@ async def draw_note_img(sr_uid: str) -> Union[bytes, str]:
|
||||
lastmonth_rails_pass_str,
|
||||
font=sr_font_28,
|
||||
fill=black_color,
|
||||
anchor='lm',
|
||||
anchor="lm",
|
||||
)
|
||||
xy = ((0, 0), (2100, 2100))
|
||||
temp = -90
|
||||
if not data.month_data.group_by:
|
||||
pie_image = Image.new('RGBA', (2100, 2100), color=(255, 255, 255, 0))
|
||||
pie_image = Image.new("RGBA", (2100, 2100), color=(255, 255, 255, 0))
|
||||
pie_image_draw = ImageDraw.Draw(pie_image)
|
||||
pie_image_draw.ellipse(xy, fill=(128, 128, 128))
|
||||
else:
|
||||
pie_image = Image.new('RGBA', (2100, 2100), color=(255, 255, 255, 0))
|
||||
pie_image = Image.new("RGBA", (2100, 2100), color=(255, 255, 255, 0))
|
||||
pie_image_draw = ImageDraw.Draw(pie_image)
|
||||
for _index, i in enumerate(data.month_data.group_by):
|
||||
pie_image_draw.pieslice(
|
||||
@ -251,7 +247,7 @@ async def draw_note_img(sr_uid: str) -> Union[bytes, str]:
|
||||
)
|
||||
temp = temp + (i.percent / 100) * 360
|
||||
# 绘制蒙版圆形
|
||||
new_image = Image.new('RGBA', (2100, 2100), color=(255, 255, 255, 0))
|
||||
new_image = Image.new("RGBA", (2100, 2100), color=(255, 255, 255, 0))
|
||||
pie_image_draw.ellipse((150, 150, 1950, 1950), fill=(255, 255, 255, 0))
|
||||
|
||||
position = (1050, 1050)
|
||||
@ -260,7 +256,7 @@ async def draw_note_img(sr_uid: str) -> Union[bytes, str]:
|
||||
img.paste(result_pie, (138, 618), result_pie)
|
||||
|
||||
if last_monthly_data:
|
||||
pie_image = Image.new('RGBA', (2100, 2100), color=(255, 255, 255, 0))
|
||||
pie_image = Image.new("RGBA", (2100, 2100), color=(255, 255, 255, 0))
|
||||
pie_image_draw = ImageDraw.Draw(pie_image)
|
||||
for _index, i in enumerate(last_monthly_data.month_data.group_by):
|
||||
pie_image_draw.pieslice(
|
||||
@ -271,12 +267,12 @@ async def draw_note_img(sr_uid: str) -> Union[bytes, str]:
|
||||
)
|
||||
temp = temp + (i.percent / 100) * 360
|
||||
else:
|
||||
pie_image = Image.new('RGBA', (2100, 2100), color=(255, 255, 255, 0))
|
||||
pie_image = Image.new("RGBA", (2100, 2100), color=(255, 255, 255, 0))
|
||||
pie_image_draw = ImageDraw.Draw(pie_image)
|
||||
pie_image_draw.ellipse(xy, fill=(128, 128, 128))
|
||||
|
||||
# 绘制蒙版圆形
|
||||
new_image = Image.new('RGBA', (2100, 2100), color=(255, 255, 255, 0))
|
||||
new_image = Image.new("RGBA", (2100, 2100), color=(255, 255, 255, 0))
|
||||
pie_image_draw.ellipse((150, 150, 1950, 1950), fill=(255, 255, 255, 0))
|
||||
|
||||
position = (1050, 1050)
|
||||
@ -285,13 +281,13 @@ async def draw_note_img(sr_uid: str) -> Union[bytes, str]:
|
||||
img.paste(result_pie, (138, 618 + 350), result_pie)
|
||||
|
||||
img = await convert_img(img)
|
||||
logger.info('[开拓月历] 图片绘制完成!等待发送...')
|
||||
logger.info("[开拓月历] 图片绘制完成!等待发送...")
|
||||
return img
|
||||
|
||||
|
||||
async def int_carry(i: int) -> str:
|
||||
if i >= 100000:
|
||||
i_str = f'{i / 10000:.1f}W'
|
||||
i_str = f"{i / 10000:.1f}W"
|
||||
else:
|
||||
i_str = str(i)
|
||||
return i_str
|
||||
|
@ -1,7 +1,7 @@
|
||||
from datetime import datetime
|
||||
|
||||
from ..utils.mys_api import mys_api
|
||||
from ..utils.error_reply import get_error
|
||||
from ..utils.mys_api import mys_api
|
||||
|
||||
month_im = """==============
|
||||
SR_UID:{}
|
||||
@ -24,7 +24,7 @@ SR_UID:{}
|
||||
|
||||
async def award(uid) -> str:
|
||||
# 获取当前的月份
|
||||
data = await mys_api.get_award(uid, datetime.now().month)
|
||||
data = await mys_api.get_sr_award(uid, datetime.now().month)
|
||||
if isinstance(data, int):
|
||||
return get_error(data)
|
||||
day_hcoin = data.day_data.current_hcoin
|
||||
@ -38,17 +38,17 @@ async def award(uid) -> str:
|
||||
month_rails_pass = data.month_data.current_rails_pass
|
||||
lastmonth_stone = data.month_data.last_hcoin
|
||||
lastmonth_rails_pass = data.month_data.last_rails_pass
|
||||
group_str = ''
|
||||
group_str = ""
|
||||
for i in data.month_data.group_by:
|
||||
group_str = (
|
||||
group_str
|
||||
+ i.action_name
|
||||
+ ':'
|
||||
+ ":"
|
||||
+ str(i.num)
|
||||
+ '('
|
||||
+ "("
|
||||
+ str(i.percent)
|
||||
+ '%)'
|
||||
+ '\n'
|
||||
+ "%)"
|
||||
+ "\n"
|
||||
)
|
||||
|
||||
return month_im.format(
|
||||
|
@ -6,18 +6,16 @@ from gsuid_core.logger import logger
|
||||
from ..utils.sr_prefix import PREFIX
|
||||
from ..utils.resource.download_from_cos import check_use
|
||||
|
||||
sv_sr_download_config = SV('sr下载资源', pm=1)
|
||||
sv_sr_download_config = SV("sr下载资源", pm=1)
|
||||
|
||||
|
||||
@sv_sr_download_config.on_fullmatch(f'{PREFIX}下载全部资源')
|
||||
@sv_sr_download_config.on_fullmatch(f"{PREFIX}下载全部资源")
|
||||
async def send_download_resource_msg(bot: Bot, ev: Event):
|
||||
await bot.send('sr正在开始下载~可能需要较久的时间!')
|
||||
await bot.send("sr正在开始下载~可能需要较久的时间!")
|
||||
im = await check_use()
|
||||
await bot.send(im)
|
||||
|
||||
|
||||
async def startup():
|
||||
logger.info(
|
||||
'[sr资源文件下载] 正在检查与下载缺失的资源文件,可能需要较长时间,请稍等'
|
||||
)
|
||||
logger.info(f'[sr资源文件下载] {await check_use()}')
|
||||
logger.info("[sr资源文件下载] 正在检查与下载缺失的资源文件,可能需要较长时间,请稍等")
|
||||
logger.info(f"[sr资源文件下载] {await check_use()}")
|
||||
|
@ -1,95 +1,90 @@
|
||||
import re
|
||||
|
||||
from gsuid_core.sv import SV
|
||||
from gsuid_core.bot import Bot
|
||||
from gsuid_core.models import Event
|
||||
from gsuid_core.utils.error_reply import UID_HINT
|
||||
|
||||
from ..utils.convert import get_uid
|
||||
from ..utils.sr_prefix import PREFIX
|
||||
from .draw_rogue_card import draw_rogue_img, draw_rogue_locust_img
|
||||
|
||||
sv_srabyss = SV('sr查询模拟宇宙')
|
||||
sv_srabyss_locust = SV('sr查询寰宇蝗灾')
|
||||
|
||||
|
||||
@sv_srabyss.on_command(
|
||||
(
|
||||
f'{PREFIX}查询宇宙',
|
||||
f'{PREFIX}yz',
|
||||
f'{PREFIX}查询上期宇宙',
|
||||
f'{PREFIX}sqyz',
|
||||
f'{PREFIX}上期宇宙',
|
||||
f'{PREFIX}宇宙',
|
||||
f'{PREFIX}查询模拟宇宙',
|
||||
f'{PREFIX}上期模拟宇宙',
|
||||
f'{PREFIX}查询上期模拟宇宙',
|
||||
),
|
||||
block=True,
|
||||
)
|
||||
async def send_srabyss_info(bot: Bot, ev: Event):
|
||||
name = ''.join(re.findall('[\u4e00-\u9fa5]', ev.text))
|
||||
if name:
|
||||
return None
|
||||
|
||||
await bot.logger.info('开始执行[sr查询模拟宇宙信息]')
|
||||
get_uid_ = await get_uid(bot, ev, True)
|
||||
if get_uid_ is None:
|
||||
return await bot.send(UID_HINT)
|
||||
uid, user_id = get_uid_
|
||||
if uid is None:
|
||||
return await bot.send(UID_HINT)
|
||||
await bot.logger.info(f'[sr查询模拟宇宙信息]uid: {uid}')
|
||||
|
||||
if 'sq' in ev.command or '上期' in ev.command:
|
||||
schedule_type = '2'
|
||||
else:
|
||||
schedule_type = '3'
|
||||
await bot.logger.info(f'[sr查询模拟宇宙信息]模拟宇宙期数: {schedule_type}')
|
||||
|
||||
if ev.text in ['一', '二', '三', '四', '五', '六']:
|
||||
floor = (
|
||||
ev.text.replace('一', '1')
|
||||
.replace('二', '2')
|
||||
.replace('三', '3')
|
||||
.replace('四', '4')
|
||||
.replace('五', '5')
|
||||
.replace('六', '6')
|
||||
)
|
||||
else:
|
||||
floor = ev.text
|
||||
if floor and floor.isdigit():
|
||||
floor = int(floor)
|
||||
else:
|
||||
floor = None
|
||||
await bot.logger.info(f'[sr查询模拟宇宙信息]模拟宇宙世界数: {floor}')
|
||||
im = await draw_rogue_img(user_id, uid, ev.sender, floor, schedule_type)
|
||||
await bot.send(im)
|
||||
return None
|
||||
|
||||
|
||||
@sv_srabyss_locust.on_command(
|
||||
(
|
||||
f'{PREFIX}寰宇蝗灾',
|
||||
f'{PREFIX}hyhz',
|
||||
f'{PREFIX}查询寰宇蝗灾',
|
||||
f'{PREFIX}sqhyhz',
|
||||
),
|
||||
block=True,
|
||||
)
|
||||
async def send_srabyss_locust_info(bot: Bot, ev: Event):
|
||||
name = ''.join(re.findall('[\u4e00-\u9fa5]', ev.text))
|
||||
if name:
|
||||
return None
|
||||
|
||||
await bot.logger.info('开始执行[sr查询寰宇蝗灾信息]')
|
||||
get_uid_ = await get_uid(bot, ev, True)
|
||||
if get_uid_ is None:
|
||||
return await bot.send(UID_HINT)
|
||||
uid, user_id = get_uid_
|
||||
if uid is None:
|
||||
return await bot.send(UID_HINT)
|
||||
await bot.logger.info(f'[sr查询寰宇蝗灾信息]uid: {uid}')
|
||||
im = await draw_rogue_locust_img(user_id, uid, ev.sender)
|
||||
await bot.send(im)
|
||||
return None
|
||||
import re
|
||||
|
||||
from .draw_rogue_card import draw_rogue_img, draw_rogue_locust_img
|
||||
from ..utils.sr_prefix import PREFIX
|
||||
|
||||
from gsuid_core.bot import Bot
|
||||
from gsuid_core.models import Event
|
||||
from gsuid_core.sv import SV
|
||||
from gsuid_core.utils.database.api import get_uid
|
||||
from gsuid_core.utils.database.models import GsBind
|
||||
from gsuid_core.utils.error_reply import UID_HINT
|
||||
|
||||
sv_srabyss = SV("sr查询模拟宇宙")
|
||||
sv_srabyss_locust = SV("sr查询寰宇蝗灾")
|
||||
|
||||
|
||||
@sv_srabyss.on_command(
|
||||
(
|
||||
f"{PREFIX}查询宇宙",
|
||||
f"{PREFIX}yz",
|
||||
f"{PREFIX}查询上期宇宙",
|
||||
f"{PREFIX}sqyz",
|
||||
f"{PREFIX}上期宇宙",
|
||||
f"{PREFIX}宇宙",
|
||||
f"{PREFIX}查询模拟宇宙",
|
||||
f"{PREFIX}上期模拟宇宙",
|
||||
f"{PREFIX}查询上期模拟宇宙",
|
||||
),
|
||||
block=True,
|
||||
)
|
||||
async def send_srabyss_info(bot: Bot, ev: Event):
|
||||
name = "".join(re.findall("[\u4e00-\u9fa5]", ev.text))
|
||||
if name:
|
||||
return None
|
||||
|
||||
await bot.logger.info("开始执行[sr查询模拟宇宙信息]")
|
||||
uid, user_id = await get_uid(bot, ev, GsBind, "sr", True)
|
||||
if uid is None:
|
||||
return await bot.send(UID_HINT)
|
||||
await bot.logger.info(f"[sr查询模拟宇宙信息]uid: {uid}")
|
||||
|
||||
if "sq" in ev.command or "上期" in ev.command:
|
||||
schedule_type = "2"
|
||||
else:
|
||||
schedule_type = "3"
|
||||
await bot.logger.info(f"[sr查询模拟宇宙信息]模拟宇宙期数: {schedule_type}")
|
||||
|
||||
if ev.text in ["一", "二", "三", "四", "五", "六"]:
|
||||
floor = (
|
||||
ev.text.replace("一", "1")
|
||||
.replace("二", "2")
|
||||
.replace("三", "3")
|
||||
.replace("四", "4")
|
||||
.replace("五", "5")
|
||||
.replace("六", "6")
|
||||
)
|
||||
else:
|
||||
floor = ev.text
|
||||
if floor and floor.isdigit():
|
||||
floor = int(floor)
|
||||
else:
|
||||
floor = None
|
||||
await bot.logger.info(f"[sr查询模拟宇宙信息]模拟宇宙世界数: {floor}")
|
||||
im = await draw_rogue_img(user_id, uid, ev.sender, floor, schedule_type)
|
||||
await bot.send(im)
|
||||
return None
|
||||
|
||||
|
||||
@sv_srabyss_locust.on_command(
|
||||
(
|
||||
f"{PREFIX}寰宇蝗灾",
|
||||
f"{PREFIX}hyhz",
|
||||
f"{PREFIX}查询寰宇蝗灾",
|
||||
f"{PREFIX}sqhyhz",
|
||||
),
|
||||
block=True,
|
||||
)
|
||||
async def send_srabyss_locust_info(bot: Bot, ev: Event):
|
||||
name = "".join(re.findall("[\u4e00-\u9fa5]", ev.text))
|
||||
if name:
|
||||
return None
|
||||
|
||||
await bot.logger.info("开始执行[sr查询寰宇蝗灾信息]")
|
||||
uid, user_id = await get_uid(bot, ev, GsBind, "sr", True)
|
||||
if uid is None:
|
||||
return await bot.send(UID_HINT)
|
||||
await bot.logger.info(f"[sr查询寰宇蝗灾信息]uid: {uid}")
|
||||
im = await draw_rogue_locust_img(user_id, uid, ev.sender)
|
||||
await bot.send(im)
|
||||
return None
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -6,14 +6,14 @@ from PIL import Image
|
||||
from aiohttp import ClientSession
|
||||
from gsuid_core.data_store import get_res_path
|
||||
|
||||
T = TypeVar('T')
|
||||
T = TypeVar("T")
|
||||
|
||||
ROLEINFO_PATH = get_res_path() / 'StarRailUID' / 'roleinfo'
|
||||
ROLEINFO_PATH = get_res_path() / "StarRailUID" / "roleinfo"
|
||||
ROLEINFO_PATH.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
|
||||
async def get_icon(url: str) -> Image.Image:
|
||||
name = url.split('/')[-1]
|
||||
name = url.split("/")[-1]
|
||||
path = ROLEINFO_PATH / name
|
||||
if (path).exists():
|
||||
content = path.read_bytes()
|
||||
@ -21,6 +21,6 @@ async def get_icon(url: str) -> Image.Image:
|
||||
async with ClientSession() as client:
|
||||
async with client.get(url) as resp:
|
||||
content = await resp.read()
|
||||
with Path.open(path, 'wb') as f:
|
||||
with Path.open(path, "wb") as f:
|
||||
f.write(content)
|
||||
return Image.open(BytesIO(content)).convert('RGBA')
|
||||
return Image.open(BytesIO(content)).convert("RGBA")
|
||||
|
@ -1,47 +1,45 @@
|
||||
import re
|
||||
|
||||
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 ..utils.convert import get_uid
|
||||
from ..utils.sr_prefix import PREFIX
|
||||
from .draw_roleinfo_card import get_detail_img, get_role_img
|
||||
from ..utils.error_reply import UID_HINT
|
||||
from .draw_roleinfo_card import get_role_img, get_detail_img
|
||||
from ..utils.sr_prefix import PREFIX
|
||||
|
||||
sv_get_info = SV('sr查询信息')
|
||||
from gsuid_core.bot import Bot
|
||||
from gsuid_core.logger import logger
|
||||
from gsuid_core.models import Event
|
||||
from gsuid_core.sv import SV
|
||||
from gsuid_core.utils.database.api import get_uid
|
||||
from gsuid_core.utils.database.models import GsBind
|
||||
|
||||
sv_get_info = SV("sr查询信息")
|
||||
|
||||
|
||||
@sv_get_info.on_command(f'{PREFIX}uid')
|
||||
@sv_get_info.on_command(f"{PREFIX}uid")
|
||||
async def send_role_info(bot: Bot, ev: Event):
|
||||
name = ''.join(re.findall('[\u4e00-\u9fa5]', ev.text))
|
||||
name = "".join(re.findall("[\u4e00-\u9fa5]", ev.text))
|
||||
if name:
|
||||
return None
|
||||
|
||||
uid = await get_uid(bot, ev)
|
||||
uid = await get_uid(bot, ev, GsBind, "sr")
|
||||
if uid is None:
|
||||
return '你还没有绑定UID噢,请使用[sr绑定uid123]完成绑定!'
|
||||
return "你还没有绑定UID噢,请使用[sr绑定uid123]完成绑定!"
|
||||
|
||||
logger.info(f'[sr查询信息]UID: {uid}')
|
||||
await bot.logger.info('开始执行[sr查询信息]')
|
||||
logger.info(f"[sr查询信息]UID: {uid}")
|
||||
await bot.logger.info("开始执行[sr查询信息]")
|
||||
await bot.send(await get_role_img(uid))
|
||||
return None
|
||||
|
||||
|
||||
@sv_get_info.on_command(f'{PREFIX}练度统计')
|
||||
@sv_get_info.on_command(f"{PREFIX}练度统计")
|
||||
async def send_detail_info(bot: Bot, ev: Event):
|
||||
name = ''.join(re.findall('[\u4e00-\u9fa5]', ev.text))
|
||||
name = "".join(re.findall("[\u4e00-\u9fa5]", ev.text))
|
||||
if name:
|
||||
return None
|
||||
get_uid_ = await get_uid(bot, ev, True)
|
||||
if get_uid_ is None:
|
||||
return await bot.send(UID_HINT)
|
||||
uid, user_id = get_uid_
|
||||
uid, user_id = await get_uid(bot, ev, GsBind, "sr", True)
|
||||
if uid is None:
|
||||
return await bot.send(UID_HINT)
|
||||
|
||||
logger.info(f'[sr查询信息]UID: {uid}')
|
||||
await bot.logger.info('开始执行[sr查询信息]')
|
||||
logger.info(f"[sr查询信息]UID: {uid}")
|
||||
await bot.logger.info("开始执行[sr查询信息]")
|
||||
await bot.send(await get_detail_img(user_id, uid, ev.sender))
|
||||
return None
|
||||
|
@ -1,26 +1,16 @@
|
||||
import asyncio
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, Union, Optional
|
||||
from typing import Any, Dict, List, Optional, Union
|
||||
|
||||
from PIL import Image, ImageDraw
|
||||
from gsuid_core.logger import logger
|
||||
from gsuid_core.utils.error_reply import get_error
|
||||
from gsuid_core.utils.image.image_tools import (
|
||||
get_qq_avatar,
|
||||
draw_pic_with_ring,
|
||||
)
|
||||
|
||||
from ..utils.mys_api import mys_api
|
||||
from .utils import get_icon, wrap_list
|
||||
from ..utils.image.convert import convert_img
|
||||
from ..utils.fonts.first_world import fw_font_24
|
||||
from ..sruid_utils.api.mys.models import (
|
||||
Stats,
|
||||
AvatarDetail,
|
||||
RoleBasicInfo,
|
||||
AvatarListItem,
|
||||
AvatarListItemDetail,
|
||||
RoleBasicInfo,
|
||||
Stats,
|
||||
)
|
||||
from ..utils.fonts.first_world import fw_font_24
|
||||
from ..utils.fonts.starrail_fonts import (
|
||||
sr_font_22,
|
||||
sr_font_24,
|
||||
@ -28,41 +18,41 @@ from ..utils.fonts.starrail_fonts import (
|
||||
sr_font_30,
|
||||
sr_font_36,
|
||||
)
|
||||
from ..utils.mys_api import mys_api
|
||||
|
||||
TEXT_PATH = Path(__file__).parent / 'texture2D'
|
||||
|
||||
bg1 = Image.open(TEXT_PATH / 'bg1.png')
|
||||
bg2 = Image.open(TEXT_PATH / 'bg2.png')
|
||||
bg3 = Image.open(TEXT_PATH / 'bg3.png')
|
||||
user_avatar = (
|
||||
Image.open(TEXT_PATH / '200101.png').resize((220, 220)).convert('RGBA')
|
||||
from PIL import Image, ImageDraw
|
||||
from gsuid_core.logger import logger
|
||||
from gsuid_core.utils.error_reply import get_error
|
||||
from gsuid_core.utils.image.convert import convert_img
|
||||
from gsuid_core.utils.image.image_tools import (
|
||||
draw_pic_with_ring,
|
||||
get_qq_avatar,
|
||||
)
|
||||
char_bg_4 = Image.open(TEXT_PATH / 'rarity4_bg.png').convert('RGBA')
|
||||
char_bg_5 = Image.open(TEXT_PATH / 'rarity5_bg.png').convert('RGBA')
|
||||
circle = Image.open(TEXT_PATH / 'char_weapon_bg.png').convert('RGBA')
|
||||
bg_img = Image.open(TEXT_PATH / 'bg_light.jpg')
|
||||
rank_bg = Image.open(TEXT_PATH / 'rank_bg.png').convert('RGBA')
|
||||
|
||||
TEXT_PATH = Path(__file__).parent / "texture2D"
|
||||
|
||||
bg1 = Image.open(TEXT_PATH / "bg1.png")
|
||||
bg2 = Image.open(TEXT_PATH / "bg2.png")
|
||||
bg3 = Image.open(TEXT_PATH / "bg3.png")
|
||||
user_avatar = Image.open(TEXT_PATH / "200101.png").resize((220, 220)).convert("RGBA")
|
||||
char_bg_4 = Image.open(TEXT_PATH / "rarity4_bg.png").convert("RGBA")
|
||||
char_bg_5 = Image.open(TEXT_PATH / "rarity5_bg.png").convert("RGBA")
|
||||
circle = Image.open(TEXT_PATH / "char_weapon_bg.png").convert("RGBA")
|
||||
bg_img = Image.open(TEXT_PATH / "bg_light.jpg")
|
||||
rank_bg = Image.open(TEXT_PATH / "rank_bg.png").convert("RGBA")
|
||||
bg_color = (248, 248, 248)
|
||||
white_color = (255, 255, 255)
|
||||
color_color = (40, 18, 7)
|
||||
first_color = (22, 8, 31)
|
||||
|
||||
elements = {
|
||||
'ice': Image.open(TEXT_PATH / 'IconNatureColorIce.png').convert('RGBA'),
|
||||
'fire': Image.open(TEXT_PATH / 'IconNatureColorFire.png').convert('RGBA'),
|
||||
'imaginary': Image.open(
|
||||
TEXT_PATH / 'IconNatureColorImaginary.png'
|
||||
).convert('RGBA'),
|
||||
'quantum': Image.open(TEXT_PATH / 'IconNatureColorQuantum.png').convert(
|
||||
'RGBA'
|
||||
),
|
||||
'lightning': Image.open(TEXT_PATH / 'IconNatureColorThunder.png').convert(
|
||||
'RGBA'
|
||||
),
|
||||
'wind': Image.open(TEXT_PATH / 'IconNatureColorWind.png').convert('RGBA'),
|
||||
'physical': Image.open(TEXT_PATH / 'IconNaturePhysical.png').convert(
|
||||
'RGBA'
|
||||
),
|
||||
"ice": Image.open(TEXT_PATH / "IconNatureColorIce.png").convert("RGBA"),
|
||||
"fire": Image.open(TEXT_PATH / "IconNatureColorFire.png").convert("RGBA"),
|
||||
"imaginary": Image.open(TEXT_PATH / "IconNatureColorImaginary.png").convert("RGBA"),
|
||||
"quantum": Image.open(TEXT_PATH / "IconNatureColorQuantum.png").convert("RGBA"),
|
||||
"lightning": Image.open(TEXT_PATH / "IconNatureColorThunder.png").convert("RGBA"),
|
||||
"wind": Image.open(TEXT_PATH / "IconNatureColorWind.png").convert("RGBA"),
|
||||
"physical": Image.open(TEXT_PATH / "IconNaturePhysical.png").convert("RGBA"),
|
||||
}
|
||||
|
||||
|
||||
@ -70,14 +60,12 @@ async def get_role_img(uid: str) -> Union[bytes, str]:
|
||||
return await draw_role_card(uid)
|
||||
|
||||
|
||||
async def get_detail_img(
|
||||
qid: Union[str, int], uid: str, sender
|
||||
) -> Union[bytes, str]:
|
||||
async def get_detail_img(qid: Union[str, int], uid: str, sender) -> Union[bytes, str]:
|
||||
return await get_detail_card(qid, uid, sender)
|
||||
|
||||
|
||||
def _lv(level: int) -> str:
|
||||
return f'Lv.0{level}' if level < 10 else f'Lv.{level}'
|
||||
return f"Lv.0{level}" if level < 10 else f"Lv.{level}"
|
||||
|
||||
|
||||
async def _draw_card_1(
|
||||
@ -100,16 +88,14 @@ async def _draw_card_1(
|
||||
bg1_draw = ImageDraw.Draw(img_bg1)
|
||||
|
||||
# 写Nickname
|
||||
bg1_draw.text(
|
||||
(400, 85), nickname, font=sr_font_36, fill=white_color, anchor='mm'
|
||||
)
|
||||
bg1_draw.text((400, 85), nickname, font=sr_font_36, fill=white_color, anchor="mm")
|
||||
# 写UID
|
||||
bg1_draw.text(
|
||||
(400, 165),
|
||||
f'UID {sr_uid}',
|
||||
f"UID {sr_uid}",
|
||||
font=sr_font_30,
|
||||
fill=white_color,
|
||||
anchor='mm',
|
||||
anchor="mm",
|
||||
)
|
||||
# 贴头像
|
||||
img_bg1.paste(user_avatar, (286, 213), mask=user_avatar)
|
||||
@ -120,31 +106,31 @@ async def _draw_card_1(
|
||||
str(active_days),
|
||||
font=sr_font_36,
|
||||
fill=white_color,
|
||||
anchor='mm',
|
||||
anchor="mm",
|
||||
) # 活跃天数
|
||||
bg1_draw.text(
|
||||
(270, 590),
|
||||
str(avater_num),
|
||||
font=sr_font_36,
|
||||
fill=white_color,
|
||||
anchor='mm',
|
||||
anchor="mm",
|
||||
) # 解锁角色
|
||||
bg1_draw.text(
|
||||
(398, 590),
|
||||
str(achievement_num),
|
||||
font=sr_font_36,
|
||||
fill=white_color,
|
||||
anchor='mm',
|
||||
anchor="mm",
|
||||
) # 达成成就
|
||||
bg1_draw.text(
|
||||
(525, 590),
|
||||
str(chest_num),
|
||||
font=sr_font_36,
|
||||
fill=white_color,
|
||||
anchor='mm',
|
||||
anchor="mm",
|
||||
) # 战利品开启
|
||||
bg1_draw.text(
|
||||
(666, 590), str(level), font=sr_font_36, fill=white_color, anchor='mm'
|
||||
(666, 590), str(level), font=sr_font_36, fill=white_color, anchor="mm"
|
||||
) # 开拓等级
|
||||
|
||||
# 画忘却之庭
|
||||
@ -153,7 +139,7 @@ async def _draw_card_1(
|
||||
abyss_process,
|
||||
font=sr_font_30,
|
||||
fill=first_color,
|
||||
anchor='mm',
|
||||
anchor="mm",
|
||||
)
|
||||
|
||||
return img_bg1
|
||||
@ -174,10 +160,10 @@ async def _draw_avatar_card(
|
||||
char_bg.paste(rank_bg, (89, 6), mask=rank_bg)
|
||||
char_draw.text(
|
||||
(100, 21),
|
||||
f'{avatar.rank}',
|
||||
f"{avatar.rank}",
|
||||
font=sr_font_22,
|
||||
fill=white_color,
|
||||
anchor='mm',
|
||||
anchor="mm",
|
||||
)
|
||||
|
||||
if equip := equips[avatar.id]:
|
||||
@ -190,7 +176,7 @@ async def _draw_avatar_card(
|
||||
_lv(avatar.level),
|
||||
font=sr_font_24,
|
||||
fill=color_color,
|
||||
anchor='mm',
|
||||
anchor="mm",
|
||||
)
|
||||
return char_bg
|
||||
|
||||
@ -214,12 +200,9 @@ async def _draw_card_2(
|
||||
) -> Image.Image:
|
||||
# 角色部分 每五个一组
|
||||
lines = await asyncio.gather(
|
||||
*[
|
||||
_draw_line(five_avatars, equips)
|
||||
for five_avatars in wrap_list(avatars, 5)
|
||||
]
|
||||
*[_draw_line(five_avatars, equips) for five_avatars in wrap_list(avatars, 5)]
|
||||
)
|
||||
img_card_2 = Image.new('RGBA', (800, len(lines) * 200))
|
||||
img_card_2 = Image.new("RGBA", (800, len(lines) * 200))
|
||||
|
||||
y = 0
|
||||
for line in lines:
|
||||
@ -237,8 +220,8 @@ async def draw_role_card(sr_uid: str) -> Union[bytes, str]:
|
||||
return get_error(role_basic_info)
|
||||
else:
|
||||
role_basic_info = {}
|
||||
role_basic_info['nickname'] = '开拓者'
|
||||
role_basic_info['level'] = 0
|
||||
role_basic_info["nickname"] = "开拓者"
|
||||
role_basic_info["level"] = 0
|
||||
|
||||
if isinstance(role_index, int):
|
||||
return get_error(role_index)
|
||||
@ -266,7 +249,7 @@ async def draw_role_card(sr_uid: str) -> Union[bytes, str]:
|
||||
)
|
||||
img2: Image.Image
|
||||
height = img2.size[1]
|
||||
img = Image.new('RGBA', (800, 880 + height), bg_color)
|
||||
img = Image.new("RGBA", (800, 880 + height), bg_color)
|
||||
img.paste(img1, (0, 0))
|
||||
img.paste(img2, (0, 810))
|
||||
img.paste(bg3, (0, height + 810))
|
||||
@ -279,69 +262,69 @@ async def _draw_detail_card(
|
||||
index: int,
|
||||
char_info: Image.Image,
|
||||
) -> Image.Image:
|
||||
if str(avatar.rarity) == '5':
|
||||
avatar_img = Image.open(TEXT_PATH / 'bar_5.png')
|
||||
if str(avatar.rarity) == "5":
|
||||
avatar_img = Image.open(TEXT_PATH / "bar_5.png")
|
||||
else:
|
||||
avatar_img = Image.open(TEXT_PATH / 'bar_4.png')
|
||||
avatar_img = Image.open(TEXT_PATH / "bar_4.png")
|
||||
avatar_draw = ImageDraw.Draw(avatar_img)
|
||||
char_icon = (await get_icon(avatar.icon)).resize((40, 40))
|
||||
element_icon = elements[avatar.element]
|
||||
avatar_img.paste(char_icon, (75, 10), mask=char_icon)
|
||||
avatar_draw.text(
|
||||
(130, 30),
|
||||
f'{avatar.name}',
|
||||
f"{avatar.name}",
|
||||
first_color,
|
||||
sr_font_24,
|
||||
'lm',
|
||||
"lm",
|
||||
)
|
||||
avatar_img.paste(element_icon, (270, 10), mask=element_icon)
|
||||
|
||||
avatar_draw.text(
|
||||
(339, 30),
|
||||
f'{avatar.level}',
|
||||
f"{avatar.level}",
|
||||
first_color,
|
||||
sr_font_24,
|
||||
'mm',
|
||||
"mm",
|
||||
)
|
||||
|
||||
avatar_draw.text(
|
||||
(385, 30),
|
||||
f'{avatar.rank}',
|
||||
f"{avatar.rank}",
|
||||
first_color,
|
||||
sr_font_24,
|
||||
'mm',
|
||||
"mm",
|
||||
)
|
||||
|
||||
avatar_draw.text(
|
||||
(429, 30),
|
||||
f'{avatar_detail.skills[0].cur_level}',
|
||||
f"{avatar_detail.skills[0].cur_level}",
|
||||
first_color,
|
||||
sr_font_24,
|
||||
'mm',
|
||||
"mm",
|
||||
)
|
||||
|
||||
avatar_draw.text(
|
||||
(469, 30),
|
||||
f'{avatar_detail.skills[1].cur_level}',
|
||||
f"{avatar_detail.skills[1].cur_level}",
|
||||
first_color,
|
||||
sr_font_24,
|
||||
'mm',
|
||||
"mm",
|
||||
)
|
||||
|
||||
avatar_draw.text(
|
||||
(515, 30),
|
||||
f'{avatar_detail.skills[2].cur_level}',
|
||||
f"{avatar_detail.skills[2].cur_level}",
|
||||
first_color,
|
||||
sr_font_24,
|
||||
'mm',
|
||||
"mm",
|
||||
)
|
||||
|
||||
avatar_draw.text(
|
||||
(553, 30),
|
||||
f'{avatar_detail.skills[3].cur_level}',
|
||||
f"{avatar_detail.skills[3].cur_level}",
|
||||
first_color,
|
||||
sr_font_24,
|
||||
'mm',
|
||||
"mm",
|
||||
)
|
||||
|
||||
if avatar.equip:
|
||||
@ -350,26 +333,26 @@ async def _draw_detail_card(
|
||||
|
||||
avatar_draw.text(
|
||||
(680, 30),
|
||||
f'{avatar.equip.rank}',
|
||||
f"{avatar.equip.rank}",
|
||||
first_color,
|
||||
sr_font_24,
|
||||
'mm',
|
||||
"mm",
|
||||
)
|
||||
|
||||
avatar_draw.text(
|
||||
(734, 30),
|
||||
f'Lv.{avatar.equip.level}',
|
||||
f"Lv.{avatar.equip.level}",
|
||||
first_color,
|
||||
sr_font_24,
|
||||
'lm',
|
||||
"lm",
|
||||
)
|
||||
|
||||
avatar_draw.text(
|
||||
(804, 30),
|
||||
f'{avatar.equip.name}',
|
||||
f"{avatar.equip.name}",
|
||||
first_color,
|
||||
sr_font_24,
|
||||
'lm',
|
||||
"lm",
|
||||
)
|
||||
|
||||
char_info.paste(avatar_img, (0, 585 + 62 * index), mask=avatar_img)
|
||||
@ -378,7 +361,7 @@ async def _draw_detail_card(
|
||||
|
||||
|
||||
async def get_detail_card(
|
||||
qid: Union[str, int], sr_uid: str, sender: Union[str, str]
|
||||
qid: Union[str, int], sr_uid: str, sender: Dict[str, Any]
|
||||
) -> Union[bytes, str]:
|
||||
# 获取角色列表
|
||||
avatar_list = await mys_api.get_avatar_info(sr_uid, 1001)
|
||||
@ -393,15 +376,15 @@ async def get_detail_card(
|
||||
char_info = char_info.resize((1050, img_height))
|
||||
char_img_draw = ImageDraw.Draw(char_info)
|
||||
|
||||
char_title = Image.open(TEXT_PATH / 'title.png')
|
||||
char_title = Image.open(TEXT_PATH / "title.png")
|
||||
char_info.paste(char_title, (0, 0), char_title)
|
||||
|
||||
# 获取头像
|
||||
_id = str(qid)
|
||||
if _id.startswith('http'):
|
||||
if _id.startswith("http"):
|
||||
char_pic = await get_qq_avatar(avatar_url=_id)
|
||||
elif sender.get('avatar') is not None:
|
||||
char_pic = await get_qq_avatar(avatar_url=sender['avatar'])
|
||||
elif sender.get("avatar") is not None:
|
||||
char_pic = await get_qq_avatar(avatar_url=sender["avatar"])
|
||||
else:
|
||||
char_pic = await get_qq_avatar(qid=qid)
|
||||
char_pic = await draw_pic_with_ring(char_pic, 250, None, False)
|
||||
@ -409,11 +392,9 @@ async def get_detail_card(
|
||||
char_info.paste(char_pic, (400, 88), char_pic)
|
||||
|
||||
# 绘制抬头
|
||||
char_img_draw.text(
|
||||
(525, 420), f'UID {sr_uid}', white_color, sr_font_28, 'mm'
|
||||
)
|
||||
char_img_draw.text((525, 420), f"UID {sr_uid}", white_color, sr_font_28, "mm")
|
||||
|
||||
title_img = Image.open(TEXT_PATH / 'bar_title.png')
|
||||
title_img = Image.open(TEXT_PATH / "bar_title.png")
|
||||
char_info.paste(title_img, (0, 515), mask=title_img)
|
||||
|
||||
for index, avatar in enumerate(avatar_list.avatar_list):
|
||||
@ -431,12 +412,12 @@ async def get_detail_card(
|
||||
# 写底层文字
|
||||
char_img_draw.text(
|
||||
(525, img_height - 45),
|
||||
'--SR skill statistics by StarrailUID & Code by jiluoQAQ & Power by GsCore--',
|
||||
"--SR skill statistics by StarrailUID & Code by jiluoQAQ & Power by GsCore--",
|
||||
(255, 255, 255),
|
||||
fw_font_24,
|
||||
'mm',
|
||||
"mm",
|
||||
)
|
||||
|
||||
res = await convert_img(char_info)
|
||||
logger.info('[查询练度统计]绘图已完成,等待发送!')
|
||||
logger.info("[查询练度统计]绘图已完成,等待发送!")
|
||||
return res
|
||||
|
@ -6,9 +6,9 @@ from PIL import Image
|
||||
from aiohttp import ClientSession
|
||||
from gsuid_core.data_store import get_res_path
|
||||
|
||||
T = TypeVar('T')
|
||||
T = TypeVar("T")
|
||||
|
||||
ROLEINFO_PATH = get_res_path() / 'StarRailUID' / 'roleinfo'
|
||||
ROLEINFO_PATH = get_res_path() / "StarRailUID" / "roleinfo"
|
||||
ROLEINFO_PATH.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
|
||||
@ -18,7 +18,7 @@ def wrap_list(lst: List[T], n: int) -> Generator[List[T], None, None]:
|
||||
|
||||
|
||||
async def get_icon(url: str) -> Image.Image:
|
||||
name = url.split('/')[-1]
|
||||
name = url.split("/")[-1]
|
||||
path = ROLEINFO_PATH / name
|
||||
if (path).exists():
|
||||
content = path.read_bytes()
|
||||
@ -26,6 +26,6 @@ async def get_icon(url: str) -> Image.Image:
|
||||
async with ClientSession() as client:
|
||||
async with client.get(url) as resp:
|
||||
content = await resp.read()
|
||||
with Path.open(path, 'wb') as f:
|
||||
with Path.open(path, "wb") as f:
|
||||
f.write(content)
|
||||
return Image.open(BytesIO(content)).convert('RGBA')
|
||||
return Image.open(BytesIO(content)).convert("RGBA")
|
||||
|
@ -11,40 +11,40 @@ from gsuid_core.utils.boardcast.send_msg import send_board_cast_msg
|
||||
from gsuid_core.utils.database.models import GsBind
|
||||
from gsuid_core.utils.sign.sign import daily_sign, sign_in
|
||||
|
||||
SIGN_TIME = srconfig.get_config('SignTime').data
|
||||
IS_REPORT = srconfig.get_config('PrivateSignReport').data
|
||||
SIGN_TIME = srconfig.get_config("SignTime").data
|
||||
IS_REPORT = srconfig.get_config("PrivateSignReport").data
|
||||
|
||||
sv_sign = SV('星穹铁道签到')
|
||||
sv_sign_config = SV('星穹铁道管理', pm=2)
|
||||
sv_sign = SV("星穹铁道签到")
|
||||
sv_sign_config = SV("星穹铁道管理", pm=2)
|
||||
|
||||
|
||||
@sv_sign.on_fullmatch(f'{PREFIX}签到')
|
||||
@sv_sign.on_fullmatch(f"{PREFIX}签到")
|
||||
async def get_sign_func(bot: Bot, ev: Event):
|
||||
logger.info(f'[星穹铁道] [签到] 用户: {ev.user_id}')
|
||||
uid = await GsBind.get_uid_by_game(ev.user_id, ev.bot_id, 'sr')
|
||||
logger.info(f"[星穹铁道] [签到] 用户: {ev.user_id}")
|
||||
uid = await GsBind.get_uid_by_game(ev.user_id, ev.bot_id, "sr")
|
||||
if uid is None:
|
||||
return await bot.send(UID_HINT)
|
||||
logger.info(f'[星穹铁道] [签到] UID: {uid}')
|
||||
await bot.send(await sign_in(uid, 'sr'))
|
||||
logger.info(f"[星穹铁道] [签到] UID: {uid}")
|
||||
await bot.send(await sign_in(uid, "sr"))
|
||||
return None
|
||||
|
||||
|
||||
@sv_sign_config.on_fullmatch(f'{PREFIX}全部重签')
|
||||
@sv_sign_config.on_fullmatch(f"{PREFIX}全部重签")
|
||||
async def recheck(bot: Bot, ev: Event):
|
||||
await bot.logger.info('开始执行[全部重签]')
|
||||
await bot.send('[星穹铁道] [全部重签] 已开始执行!')
|
||||
result = await daily_sign('sr')
|
||||
await bot.logger.info("开始执行[全部重签]")
|
||||
await bot.send("[星穹铁道] [全部重签] 已开始执行!")
|
||||
result = await daily_sign("sr")
|
||||
if not IS_REPORT:
|
||||
result['private_msg_dict'] = {}
|
||||
result["private_msg_dict"] = {}
|
||||
await send_board_cast_msg(result)
|
||||
await bot.send('[星穹铁道] [全部重签] 执行完成!')
|
||||
await bot.send("[星穹铁道] [全部重签] 执行完成!")
|
||||
|
||||
|
||||
# 每日零点半执行米游社星穹铁道签到
|
||||
@scheduler.scheduled_job('cron', hour=SIGN_TIME[0], minute=SIGN_TIME[1])
|
||||
@scheduler.scheduled_job("cron", hour=SIGN_TIME[0], minute=SIGN_TIME[1])
|
||||
async def sr_sign_at_night():
|
||||
if srconfig.get_config('SchedSignin').data:
|
||||
result = await daily_sign('sr')
|
||||
if srconfig.get_config("SchedSignin").data:
|
||||
result = await daily_sign("sr")
|
||||
if not IS_REPORT:
|
||||
result['private_msg_dict'] = {}
|
||||
result["private_msg_dict"] = {}
|
||||
await send_board_cast_msg(result)
|
||||
|
@ -1,82 +1,83 @@
|
||||
import asyncio
|
||||
|
||||
from gsuid_core.sv import SV
|
||||
from .draw_stamina_card import get_stamina_img
|
||||
from .notice import get_notice_list
|
||||
from .stamina_text import get_stamina_text
|
||||
from ..utils.error_reply import UID_HINT
|
||||
from ..utils.sr_prefix import PREFIX
|
||||
|
||||
from gsuid_core.aps import scheduler
|
||||
from gsuid_core.bot import Bot
|
||||
from gsuid_core.gss import gss
|
||||
from gsuid_core.models import Event
|
||||
from gsuid_core.aps import scheduler
|
||||
from gsuid_core.logger import logger
|
||||
from gsuid_core.models import Event
|
||||
from gsuid_core.segment import MessageSegment
|
||||
from gsuid_core.sv import SV
|
||||
from gsuid_core.utils.database.api import get_uid
|
||||
from gsuid_core.utils.database.models import GsBind
|
||||
|
||||
from ..utils.convert import get_uid
|
||||
from .notice import get_notice_list
|
||||
from ..utils.sr_prefix import PREFIX
|
||||
from ..utils.error_reply import UID_HINT
|
||||
from .stamina_text import get_stamina_text
|
||||
from .draw_stamina_card import get_stamina_img
|
||||
|
||||
sv_get_stamina = SV('sr查询体力')
|
||||
sv_get_stamina_admin = SV('sr强制推送', pm=1)
|
||||
sv_get_stamina = SV("sr查询体力")
|
||||
sv_get_stamina_admin = SV("sr强制推送", pm=1)
|
||||
|
||||
|
||||
@sv_get_stamina.on_fullmatch(f'{PREFIX}当前状态')
|
||||
@sv_get_stamina.on_fullmatch(f"{PREFIX}当前状态")
|
||||
async def send_daily_info(bot: Bot, ev: Event):
|
||||
await bot.logger.info('开始执行[sr每日信息文字版]')
|
||||
uid = await get_uid(bot, ev)
|
||||
await bot.logger.info("开始执行[sr每日信息文字版]")
|
||||
uid = await get_uid(bot, ev, GsBind, "sr")
|
||||
if uid is None:
|
||||
return await bot.send(UID_HINT)
|
||||
await bot.logger.info(f'[sr每日信息文字版]UID: {uid}')
|
||||
await bot.logger.info(f"[sr每日信息文字版]UID: {uid}")
|
||||
|
||||
im = await get_stamina_text(uid)
|
||||
await bot.send(im)
|
||||
return None
|
||||
|
||||
|
||||
@sv_get_stamina_admin.on_fullmatch(f'{PREFIX}强制推送体力提醒')
|
||||
@sv_get_stamina_admin.on_fullmatch(f"{PREFIX}强制推送体力提醒")
|
||||
async def force_notice_job(bot: Bot, ev: Event):
|
||||
await bot.logger.info('开始执行[sr强制推送体力信息]')
|
||||
await bot.logger.info("开始执行[sr强制推送体力信息]")
|
||||
await sr_notice_job()
|
||||
|
||||
|
||||
@scheduler.scheduled_job('cron', minute='*/30')
|
||||
@scheduler.scheduled_job("cron", minute="*/30")
|
||||
async def sr_notice_job():
|
||||
result = await get_notice_list()
|
||||
logger.info('[sr推送检查]完成!等待消息推送中...')
|
||||
logger.info("[sr推送检查]完成!等待消息推送中...")
|
||||
logger.debug(result)
|
||||
|
||||
# 执行私聊推送
|
||||
for bot_id in result:
|
||||
for BOT_ID in gss.active_bot:
|
||||
bot = gss.active_bot[BOT_ID]
|
||||
for user_id in result[bot_id]['direct']:
|
||||
msg = result[bot_id]['direct'][user_id]
|
||||
await bot.target_send(msg, 'direct', user_id, bot_id, '', '')
|
||||
for user_id in result[bot_id]["direct"]:
|
||||
msg = result[bot_id]["direct"][user_id]
|
||||
await bot.target_send(msg, "direct", user_id, bot_id, "", "")
|
||||
await asyncio.sleep(0.5)
|
||||
logger.info('[sr推送检查] 私聊推送完成')
|
||||
for gid in result[bot_id]['group']:
|
||||
logger.info("[sr推送检查] 私聊推送完成")
|
||||
for gid in result[bot_id]["group"]:
|
||||
msg_list = []
|
||||
for user_id in result[bot_id]['group'][gid]:
|
||||
for user_id in result[bot_id]["group"][gid]:
|
||||
msg_list.append(MessageSegment.at(user_id))
|
||||
msg = result[bot_id]['group'][gid][user_id]
|
||||
msg = result[bot_id]["group"][gid][user_id]
|
||||
msg_list.append(MessageSegment.text(msg))
|
||||
await bot.target_send(msg_list, 'group', gid, bot_id, '', '')
|
||||
await bot.target_send(msg_list, "group", gid, bot_id, "", "")
|
||||
await asyncio.sleep(0.5)
|
||||
logger.info('[sr推送检查] 群聊推送完成')
|
||||
logger.info("[sr推送检查] 群聊推送完成")
|
||||
|
||||
|
||||
@sv_get_stamina.on_fullmatch(
|
||||
(
|
||||
f'{PREFIX}每日',
|
||||
f'{PREFIX}mr',
|
||||
f'{PREFIX}实时便笺',
|
||||
f'{PREFIX}便笺',
|
||||
f'{PREFIX}便签',
|
||||
f"{PREFIX}每日",
|
||||
f"{PREFIX}mr",
|
||||
f"{PREFIX}实时便笺",
|
||||
f"{PREFIX}便笺",
|
||||
f"{PREFIX}便签",
|
||||
)
|
||||
)
|
||||
async def send_daily_info_pic(bot: Bot, ev: Event):
|
||||
await bot.logger.info('开始执行[sr每日信息]')
|
||||
await bot.logger.info("开始执行[sr每日信息]")
|
||||
user_id = ev.at if ev.at else ev.user_id
|
||||
await bot.logger.info(f'[sr每日信息]QQ号: {user_id}')
|
||||
await bot.logger.info(f"[sr每日信息]QQ号: {user_id}")
|
||||
|
||||
im = await get_stamina_img(bot.bot_id, user_id)
|
||||
await bot.send(im)
|
||||
|
@ -3,16 +3,14 @@ from io import BytesIO
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
import aiohttp
|
||||
from PIL import Image, ImageDraw
|
||||
import aiohttp
|
||||
from gsuid_core.logger import logger
|
||||
from gsuid_core.utils.database.models import GsBind, GsUser
|
||||
from gsuid_core.utils.image.convert import convert_img
|
||||
|
||||
from ..utils.mys_api import mys_api
|
||||
from ..utils.image.convert import convert_img
|
||||
from ..sruid_utils.api.mys.models import Expedition
|
||||
from ..starrailuid_config.sr_config import srconfig
|
||||
from ..utils.image.image_tools import get_simple_bg
|
||||
from ..utils.error_reply import get_error as get_error_msg
|
||||
from ..utils.fonts.starrail_fonts import (
|
||||
sr_font_22,
|
||||
@ -21,18 +19,20 @@ from ..utils.fonts.starrail_fonts import (
|
||||
sr_font_36,
|
||||
sr_font_50,
|
||||
)
|
||||
from ..utils.image.image_tools import get_simple_bg
|
||||
from ..utils.mys_api import mys_api
|
||||
|
||||
use_widget = srconfig.get_config('WidgetResin').data
|
||||
use_widget = srconfig.get_config("WidgetResin").data
|
||||
|
||||
TEXT_PATH = Path(__file__).parent / 'texture2D'
|
||||
TEXT_PATH = Path(__file__).parent / "texture2D"
|
||||
|
||||
note_bg = Image.open(TEXT_PATH / 'note_bg.png')
|
||||
note_travel_bg = Image.open(TEXT_PATH / 'note_travel_bg.png')
|
||||
warn_pic = Image.open(TEXT_PATH / 'warn.png')
|
||||
note_bg = Image.open(TEXT_PATH / "note_bg.png")
|
||||
note_travel_bg = Image.open(TEXT_PATH / "note_travel_bg.png")
|
||||
warn_pic = Image.open(TEXT_PATH / "warn.png")
|
||||
|
||||
based_w = 700
|
||||
based_h = 1200
|
||||
white_overlay = Image.new('RGBA', (based_w, based_h), (255, 251, 242, 225))
|
||||
white_overlay = Image.new("RGBA", (based_w, based_h), (255, 251, 242, 225))
|
||||
|
||||
first_color = (29, 29, 29)
|
||||
second_color = (98, 98, 98)
|
||||
@ -45,7 +45,7 @@ red_color = (235, 61, 75)
|
||||
def seconds2hours(seconds: int) -> str:
|
||||
m, s = divmod(int(seconds), 60)
|
||||
h, m = divmod(m, 60)
|
||||
return '%02d:%02d:%02d' % (h, m, s)
|
||||
return "%02d:%02d:%02d" % (h, m, s)
|
||||
|
||||
|
||||
async def download_image(url: str) -> Image.Image:
|
||||
@ -68,14 +68,14 @@ async def _draw_task_img(
|
||||
for i in range(2):
|
||||
avatar_url = char.avatars[i]
|
||||
image = await download_image(avatar_url)
|
||||
char_pic = image.convert('RGBA').resize(
|
||||
char_pic = image.convert("RGBA").resize(
|
||||
(40, 40),
|
||||
Image.Resampling.LANCZOS, # type: ignore
|
||||
)
|
||||
note_travel_img.paste(char_pic, (495 + 68 * i, 20), char_pic)
|
||||
img.paste(note_travel_img, (0, 790 + index * 80), note_travel_img)
|
||||
if char.status == 'Finished':
|
||||
status_mark = '待收取'
|
||||
if char.status == "Finished":
|
||||
status_mark = "待收取"
|
||||
else:
|
||||
status_mark = str(remaining_time)
|
||||
img_draw.text(
|
||||
@ -83,55 +83,55 @@ async def _draw_task_img(
|
||||
expedition_name,
|
||||
font=sr_font_22,
|
||||
fill=white_color,
|
||||
anchor='lm',
|
||||
anchor="lm",
|
||||
)
|
||||
img_draw.text(
|
||||
(380, 830 + index * 80),
|
||||
status_mark,
|
||||
font=sr_font_22,
|
||||
fill=white_color,
|
||||
anchor='mm',
|
||||
anchor="mm",
|
||||
)
|
||||
else:
|
||||
note_travel_img = note_travel_bg.copy()
|
||||
img.paste(note_travel_img, (0, 790 + index * 80), note_travel_img)
|
||||
img_draw.text(
|
||||
(120, 830 + index * 80),
|
||||
'等待加入探索队列...',
|
||||
"等待加入探索队列...",
|
||||
font=sr_font_22,
|
||||
fill=white_color,
|
||||
anchor='lm',
|
||||
anchor="lm",
|
||||
)
|
||||
|
||||
|
||||
async def get_stamina_img(bot_id: str, user_id: str):
|
||||
try:
|
||||
uid_list = await GsBind.get_uid_list_by_game(user_id, bot_id, 'sr')
|
||||
logger.info(f'[每日信息]UID: {uid_list}')
|
||||
uid_list = await GsBind.get_uid_list_by_game(user_id, bot_id, "sr")
|
||||
logger.info(f"[每日信息]UID: {uid_list}")
|
||||
if uid_list is None:
|
||||
return '请先绑定一个UID再来查询哦~'
|
||||
return "请先绑定一个UID再来查询哦~"
|
||||
# 进行校验UID是否绑定CK
|
||||
useable_uid_list = []
|
||||
for uid in uid_list:
|
||||
status = await GsUser.get_user_cookie_by_uid(uid, 'sr')
|
||||
status = await GsUser.get_user_cookie_by_uid(uid, "sr")
|
||||
if status is not None:
|
||||
useable_uid_list.append(uid)
|
||||
logger.info(f'[每日信息]可用UID: {useable_uid_list}')
|
||||
logger.info(f"[每日信息]可用UID: {useable_uid_list}")
|
||||
if len(useable_uid_list) == 0:
|
||||
return '请先绑定一个可用CK & UID再来查询哦~'
|
||||
return "请先绑定一个可用CK & UID再来查询哦~"
|
||||
# 开始绘图任务
|
||||
task = []
|
||||
img = Image.new(
|
||||
'RGBA', (based_w * len(useable_uid_list), based_h), (0, 0, 0, 0)
|
||||
"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_stamina_img(img, uid, uid_index))
|
||||
await asyncio.gather(*task)
|
||||
res = await convert_img(img)
|
||||
logger.info('[查询每日信息]绘图已完成,等待发送!')
|
||||
logger.info("[查询每日信息]绘图已完成,等待发送!")
|
||||
except TypeError:
|
||||
logger.exception('[查询每日信息]绘图失败!')
|
||||
res = '你绑定过的UID中可能存在过期CK~请重新绑定一下噢~'
|
||||
logger.exception("[查询每日信息]绘图失败!")
|
||||
res = "你绑定过的UID中可能存在过期CK~请重新绑定一下噢~"
|
||||
|
||||
return res
|
||||
|
||||
@ -147,18 +147,18 @@ def get_error(img: Image.Image, uid: str, daily_data: int):
|
||||
# 写UID
|
||||
img_draw.text(
|
||||
(350, 680),
|
||||
f'UID{uid}',
|
||||
f"UID{uid}",
|
||||
font=sr_font_26,
|
||||
fill=first_color,
|
||||
anchor='mm',
|
||||
anchor="mm",
|
||||
)
|
||||
error_text = get_error_msg(daily_data)
|
||||
img_draw.text(
|
||||
(350, 650),
|
||||
f'{error_text}, 错误码{daily_data}',
|
||||
f"{error_text}, 错误码{daily_data}",
|
||||
font=sr_font_26,
|
||||
fill=red_color,
|
||||
anchor='mm',
|
||||
anchor="mm",
|
||||
)
|
||||
return img
|
||||
|
||||
@ -166,7 +166,7 @@ def get_error(img: Image.Image, uid: str, daily_data: int):
|
||||
async def seconds2hours_zhcn(seconds: int) -> str:
|
||||
m, s = divmod(int(seconds), 60)
|
||||
h, m = divmod(m, 60)
|
||||
return '%02d小时%02d分' % (h, m)
|
||||
return "%02d小时%02d分" % (h, m)
|
||||
|
||||
|
||||
async def draw_stamina_img(sr_uid: str) -> Image.Image:
|
||||
@ -181,7 +181,7 @@ async def draw_stamina_img(sr_uid: str) -> Image.Image:
|
||||
# daily_data = transform_fake_resin(_daily_data)
|
||||
daily_data = _daily_data
|
||||
else:
|
||||
daily_data = await mys_api.get_daily_data(sr_uid)
|
||||
daily_data = await mys_api.get_sr_daily_data(sr_uid)
|
||||
if isinstance(daily_data, int):
|
||||
return get_error(img, sr_uid, daily_data)
|
||||
|
||||
@ -194,13 +194,13 @@ async def draw_stamina_img(sr_uid: str) -> Image.Image:
|
||||
nickname = role_basic_info.nickname
|
||||
level = role_basic_info.level
|
||||
else:
|
||||
nickname = '开拓者'
|
||||
level = '0'
|
||||
nickname = "开拓者"
|
||||
level = "0"
|
||||
|
||||
# 开拓力
|
||||
stamina = daily_data.current_stamina
|
||||
max_stamina = daily_data.max_stamina
|
||||
stamina_str = f'{stamina}/{max_stamina}'
|
||||
stamina_str = f"{stamina}/{max_stamina}"
|
||||
stamina_percent = stamina / max_stamina
|
||||
if stamina_percent > 0.8:
|
||||
stamina_color = red_color
|
||||
@ -216,31 +216,23 @@ async def draw_stamina_img(sr_uid: str) -> Image.Image:
|
||||
# 派遣
|
||||
task_task = []
|
||||
for i in range(4):
|
||||
char = (
|
||||
daily_data.expeditions[i]
|
||||
if i < len(daily_data.expeditions)
|
||||
else None
|
||||
)
|
||||
char = daily_data.expeditions[i] if i < len(daily_data.expeditions) else None
|
||||
task_task.append(_draw_task_img(img, img_draw, i, char))
|
||||
await asyncio.gather(*task_task)
|
||||
|
||||
# 绘制树脂圆环
|
||||
ring_pic = Image.open(TEXT_PATH / 'ring.apng')
|
||||
percent = (
|
||||
round(stamina_percent * 89)
|
||||
if round(stamina_percent * 89) <= 89
|
||||
else 89
|
||||
)
|
||||
ring_pic = Image.open(TEXT_PATH / "ring.apng")
|
||||
percent = round(stamina_percent * 89) if round(stamina_percent * 89) <= 89 else 89
|
||||
ring_pic.seek(percent)
|
||||
img.paste(ring_pic, (0, 5), ring_pic)
|
||||
|
||||
# 写树脂剩余时间
|
||||
img_draw.text(
|
||||
(350, 490),
|
||||
f'还剩{stamina_recovery_time}',
|
||||
f"还剩{stamina_recovery_time}",
|
||||
font=sr_font_24,
|
||||
fill=stamina_color,
|
||||
anchor='mm',
|
||||
anchor="mm",
|
||||
)
|
||||
# 写Nickname
|
||||
img_draw.text(
|
||||
@ -248,23 +240,23 @@ async def draw_stamina_img(sr_uid: str) -> Image.Image:
|
||||
nickname,
|
||||
font=sr_font_36,
|
||||
fill=white_color,
|
||||
anchor='mm',
|
||||
anchor="mm",
|
||||
)
|
||||
# 写开拓等级
|
||||
img_draw.text(
|
||||
(350, 190),
|
||||
f'开拓等级{level}',
|
||||
f"开拓等级{level}",
|
||||
font=sr_font_24,
|
||||
fill=white_color,
|
||||
anchor='mm',
|
||||
anchor="mm",
|
||||
)
|
||||
# 写UID
|
||||
img_draw.text(
|
||||
(350, 663),
|
||||
f'UID{sr_uid}',
|
||||
f"UID{sr_uid}",
|
||||
font=sr_font_26,
|
||||
fill=first_color,
|
||||
anchor='mm',
|
||||
anchor="mm",
|
||||
)
|
||||
# 写树脂
|
||||
img_draw.text(
|
||||
@ -272,7 +264,7 @@ async def draw_stamina_img(sr_uid: str) -> Image.Image:
|
||||
stamina_str,
|
||||
font=sr_font_50,
|
||||
fill=first_color,
|
||||
anchor='mm',
|
||||
anchor="mm",
|
||||
)
|
||||
|
||||
return img
|
||||
|
@ -8,11 +8,11 @@ from ..sruid_utils.api.mys.models import DailyNoteData
|
||||
from ..starrailuid_config.sr_config import srconfig
|
||||
from ..utils.mys_api import mys_api
|
||||
|
||||
MR_NOTICE = '\n可发送[srmr]或者[sr每日]来查看更多信息!\n'
|
||||
MR_NOTICE = "\n可发送[srmr]或者[sr每日]来查看更多信息!\n"
|
||||
|
||||
NOTICE = {
|
||||
'stamina': f'你的开拓力快满啦!{MR_NOTICE}',
|
||||
'go': f'你有派遣信息即将可收取!{MR_NOTICE}',
|
||||
"stamina": f"你的开拓力快满啦!{MR_NOTICE}",
|
||||
"go": f"你有派遣信息即将可收取!{MR_NOTICE}",
|
||||
}
|
||||
|
||||
|
||||
@ -22,11 +22,11 @@ async def get_notice_list() -> Dict[str, Dict[str, Dict]]:
|
||||
user_list = await GsUser.get_all_push_user_list()
|
||||
for user in user_list:
|
||||
if user.sr_uid is not None:
|
||||
raw_data = await mys_api.get_daily_data(user.sr_uid)
|
||||
raw_data = await mys_api.get_sr_daily_data(user.sr_uid)
|
||||
if isinstance(raw_data, int):
|
||||
logger.error(f'[sr推送提醒]获取{user.sr_uid}的数据失败!')
|
||||
logger.error(f"[sr推送提醒]获取{user.sr_uid}的数据失败!")
|
||||
continue
|
||||
push_data = await GsPush.select_data_by_uid(user.sr_uid, 'sr')
|
||||
push_data = await GsPush.select_data_by_uid(user.sr_uid, "sr")
|
||||
msg_dict = await all_check(
|
||||
user.bot_id,
|
||||
raw_data,
|
||||
@ -48,59 +48,59 @@ async def all_check(
|
||||
) -> Dict[str, Dict[str, Dict]]:
|
||||
for mode in NOTICE.keys():
|
||||
# 检查条件
|
||||
if push_data[f'{mode}_is_push'] == 'on':
|
||||
if srconfig.get_config('CrazyNotice').data:
|
||||
if not await check(mode, raw_data, push_data[f'{mode}_value']):
|
||||
if push_data[f"{mode}_is_push"] == "on":
|
||||
if srconfig.get_config("CrazyNotice").data:
|
||||
if not await check(mode, raw_data, push_data[f"{mode}_value"]):
|
||||
await GsPush.update_data_by_uid(
|
||||
uid, bot_id, 'sr', **{f'{mode}_is_push': 'off'}
|
||||
uid, bot_id, "sr", **{f"{mode}_is_push": "off"}
|
||||
)
|
||||
continue
|
||||
# 准备推送
|
||||
if await check(mode, raw_data, push_data[f'{mode}_value']):
|
||||
if push_data[f'{mode}_push'] == 'off':
|
||||
if await check(mode, raw_data, push_data[f"{mode}_value"]):
|
||||
if push_data[f"{mode}_push"] == "off":
|
||||
pass
|
||||
# on 推送到私聊
|
||||
else:
|
||||
# 初始化
|
||||
if bot_id not in msg_dict:
|
||||
msg_dict[bot_id] = {'direct': {}, 'group': {}}
|
||||
msg_dict[bot_id] = {"direct": {}, "group": {}}
|
||||
|
||||
if push_data[f'{mode}_push'] == 'on':
|
||||
if push_data[f"{mode}_push"] == "on":
|
||||
# 添加私聊信息
|
||||
if user_id not in msg_dict[bot_id]['direct']:
|
||||
msg_dict[bot_id]['direct'][user_id] = NOTICE[mode]
|
||||
if user_id not in msg_dict[bot_id]["direct"]:
|
||||
msg_dict[bot_id]["direct"][user_id] = NOTICE[mode]
|
||||
else:
|
||||
msg_dict[bot_id]['direct'][user_id] += NOTICE[mode]
|
||||
msg_dict[bot_id]["direct"][user_id] += NOTICE[mode]
|
||||
await GsPush.update_data_by_uid(
|
||||
uid, bot_id, 'sr', **{f'{mode}_is_push': 'on'}
|
||||
uid, bot_id, "sr", **{f"{mode}_is_push": "on"}
|
||||
)
|
||||
# 群号推送到群聊
|
||||
else:
|
||||
# 初始化
|
||||
gid = push_data[f'{mode}_push']
|
||||
if gid not in msg_dict[bot_id]['group']:
|
||||
msg_dict[bot_id]['group'][gid] = {}
|
||||
gid = push_data[f"{mode}_push"]
|
||||
if gid not in msg_dict[bot_id]["group"]:
|
||||
msg_dict[bot_id]["group"][gid] = {}
|
||||
|
||||
if user_id not in msg_dict[bot_id]['group'][gid]:
|
||||
msg_dict[bot_id]['group'][gid][user_id] = NOTICE[mode]
|
||||
if user_id not in msg_dict[bot_id]["group"][gid]:
|
||||
msg_dict[bot_id]["group"][gid][user_id] = NOTICE[mode]
|
||||
else:
|
||||
msg_dict[bot_id]['group'][gid][user_id] += NOTICE[mode]
|
||||
msg_dict[bot_id]["group"][gid][user_id] += NOTICE[mode]
|
||||
await GsPush.update_data_by_uid(
|
||||
uid, bot_id, 'sr', **{f'{mode}_is_push': 'on'}
|
||||
uid, bot_id, "sr", **{f"{mode}_is_push": "on"}
|
||||
)
|
||||
return msg_dict
|
||||
|
||||
|
||||
async def check(mode: str, data: DailyNoteData, limit: int) -> bool:
|
||||
if mode == 'resin':
|
||||
if mode == "resin":
|
||||
if data.current_stamina >= limit:
|
||||
return True
|
||||
if data.current_stamina >= data.max_stamina:
|
||||
return True
|
||||
return False
|
||||
if mode == 'go':
|
||||
if mode == "go":
|
||||
for i in data.expeditions:
|
||||
if i.status == 'Ongoing':
|
||||
if i.status == "Ongoing":
|
||||
if i.remaining_time <= limit * 60:
|
||||
return True
|
||||
else:
|
||||
|
@ -2,8 +2,8 @@ from typing import List
|
||||
|
||||
from gsuid_core.logger import logger
|
||||
|
||||
from ..utils.mys_api import mys_api
|
||||
from ..utils.error_reply import get_error
|
||||
from ..utils.mys_api import mys_api
|
||||
|
||||
daily_im = """*数据刷新可能存在一定延迟,请以当前游戏实际数据为准
|
||||
==============
|
||||
@ -16,31 +16,27 @@ daily_im = """*数据刷新可能存在一定延迟,请以当前游戏实际数
|
||||
def seconds2hours(seconds: int) -> str:
|
||||
m, s = divmod(int(seconds), 60)
|
||||
h, m = divmod(m, 60)
|
||||
return '%02d:%02d:%02d' % (h, m, s)
|
||||
return "%02d:%02d:%02d" % (h, m, s)
|
||||
|
||||
|
||||
async def get_stamina_text(uid: str) -> str:
|
||||
try:
|
||||
dailydata = await mys_api.get_daily_data(uid)
|
||||
dailydata = await mys_api.get_sr_daily_data(uid)
|
||||
if isinstance(dailydata, int):
|
||||
return get_error(dailydata)
|
||||
max_stamina = dailydata.max_stamina
|
||||
rec_time = ''
|
||||
rec_time = ""
|
||||
current_stamina = dailydata.current_stamina
|
||||
if current_stamina < 160:
|
||||
stamina_recover_time = seconds2hours(
|
||||
dailydata.stamina_recover_time
|
||||
)
|
||||
stamina_recover_time = seconds2hours(dailydata.stamina_recover_time)
|
||||
next_stamina_rec_time = seconds2hours(
|
||||
8 * 60
|
||||
- (
|
||||
(dailydata.max_stamina - dailydata.current_stamina)
|
||||
* 8
|
||||
* 60
|
||||
(dailydata.max_stamina - dailydata.current_stamina) * 8 * 60
|
||||
- dailydata.stamina_recover_time
|
||||
)
|
||||
)
|
||||
rec_time = f' ({next_stamina_rec_time}/{stamina_recover_time})'
|
||||
rec_time = f" ({next_stamina_rec_time}/{stamina_recover_time})"
|
||||
|
||||
accepted_epedition_num = dailydata.accepted_expedition_num
|
||||
total_expedition_num = dailydata.total_expedition_num
|
||||
@ -49,16 +45,14 @@ async def get_stamina_text(uid: str) -> str:
|
||||
for expedition in dailydata.expeditions:
|
||||
expedition_name = expedition.name
|
||||
|
||||
if expedition.status == 'Finished':
|
||||
expedition_info.append(f'{expedition_name} 探索完成')
|
||||
if expedition.status == "Finished":
|
||||
expedition_info.append(f"{expedition_name} 探索完成")
|
||||
finished_expedition_num += 1
|
||||
else:
|
||||
remaining_time: str = seconds2hours(expedition.remaining_time)
|
||||
expedition_info.append(
|
||||
f'{expedition_name} 剩余时间{remaining_time}'
|
||||
)
|
||||
expedition_info.append(f"{expedition_name} 剩余时间{remaining_time}")
|
||||
|
||||
expedition_data = '\n'.join(expedition_info)
|
||||
expedition_data = "\n".join(expedition_info)
|
||||
return daily_im.format(
|
||||
current_stamina,
|
||||
max_stamina,
|
||||
@ -69,5 +63,5 @@ async def get_stamina_text(uid: str) -> str:
|
||||
expedition_data,
|
||||
)
|
||||
except TypeError:
|
||||
logger.exception('[查询当前状态]查询失败!')
|
||||
return '你绑定过的UID中可能存在过期CK~请重新绑定一下噢~'
|
||||
logger.exception("[查询当前状态]查询失败!")
|
||||
return "你绑定过的UID中可能存在过期CK~请重新绑定一下噢~"
|
||||
|
@ -7,72 +7,72 @@ from ..utils.message import send_diff_msg
|
||||
from ..utils.sr_prefix import PREFIX
|
||||
from .draw_user_card import get_user_card
|
||||
|
||||
sv_user_config = SV('sr用户管理', pm=2)
|
||||
sv_user_info = SV('sr用户信息')
|
||||
sv_user_config = SV("sr用户管理", pm=2)
|
||||
sv_user_info = SV("sr用户信息")
|
||||
|
||||
|
||||
@sv_user_info.on_fullmatch(f'{PREFIX}绑定信息')
|
||||
@sv_user_info.on_fullmatch(f"{PREFIX}绑定信息")
|
||||
async def send_bind_card(bot: Bot, ev: Event):
|
||||
await bot.logger.info('sr开始执行[查询用户绑定状态]')
|
||||
await bot.logger.info("sr开始执行[查询用户绑定状态]")
|
||||
uid_list = await get_user_card(ev.bot_id, ev.user_id)
|
||||
if not uid_list:
|
||||
return await bot.send('你还没有绑定SR_UID哦!')
|
||||
await bot.logger.info('sr[查询用户绑定状态]完成!等待图片发送中...')
|
||||
return await bot.send("你还没有绑定SR_UID哦!")
|
||||
await bot.logger.info("sr[查询用户绑定状态]完成!等待图片发送中...")
|
||||
await bot.send(uid_list)
|
||||
return None
|
||||
|
||||
|
||||
@sv_user_info.on_command(
|
||||
(
|
||||
f'{PREFIX}绑定uid',
|
||||
f'{PREFIX}切换uid',
|
||||
f'{PREFIX}删除uid',
|
||||
f'{PREFIX}解绑uid',
|
||||
f"{PREFIX}绑定uid",
|
||||
f"{PREFIX}切换uid",
|
||||
f"{PREFIX}删除uid",
|
||||
f"{PREFIX}解绑uid",
|
||||
)
|
||||
)
|
||||
async def send_link_uid_msg(bot: Bot, ev: Event):
|
||||
await bot.logger.info('sr开始执行[绑定/解绑用户信息]')
|
||||
await bot.logger.info("sr开始执行[绑定/解绑用户信息]")
|
||||
qid = ev.user_id
|
||||
await bot.logger.info(f'sr[绑定/解绑]UserID: {qid}')
|
||||
await bot.logger.info(f"sr[绑定/解绑]UserID: {qid}")
|
||||
|
||||
sr_uid = ev.text.strip()
|
||||
if sr_uid and not sr_uid.isdigit():
|
||||
return await bot.send('你输入了错误的格式!')
|
||||
return await bot.send("你输入了错误的格式!")
|
||||
|
||||
if '绑定' in ev.command:
|
||||
if "绑定" in ev.command:
|
||||
data = await GsBind.insert_uid(
|
||||
qid, ev.bot_id, sr_uid, ev.group_id, 9, game_name='sr'
|
||||
qid, ev.bot_id, sr_uid, ev.group_id, 9, game_name="sr"
|
||||
)
|
||||
return await send_diff_msg(
|
||||
bot,
|
||||
data,
|
||||
{
|
||||
0: f'✅[崩铁]绑定UID{sr_uid}成功!',
|
||||
-1: f'❌SR_UID{sr_uid}的位数不正确!',
|
||||
-2: f'❌SR_UID{sr_uid}已经绑定过了!',
|
||||
-3: '❌你输入了错误的格式!',
|
||||
0: f"✅[崩铁]绑定UID{sr_uid}成功!",
|
||||
-1: f"❌SR_UID{sr_uid}的位数不正确!",
|
||||
-2: f"❌SR_UID{sr_uid}已经绑定过了!",
|
||||
-3: "❌你输入了错误的格式!",
|
||||
},
|
||||
)
|
||||
|
||||
if '切换' in ev.command:
|
||||
data = await GsBind.switch_uid_by_game(qid, ev.bot_id, sr_uid, 'sr')
|
||||
if "切换" in ev.command:
|
||||
data = await GsBind.switch_uid_by_game(qid, ev.bot_id, sr_uid, "sr")
|
||||
return await send_diff_msg(
|
||||
bot,
|
||||
data,
|
||||
{
|
||||
0: f'✅[崩铁]切换uid{sr_uid}成功!',
|
||||
-1: '❌[崩铁]不存在绑定记录!',
|
||||
-2: '❌[崩铁]请绑定两个以上UID再进行切换!',
|
||||
-3: '❌[崩铁]请绑定两个以上UID再进行切换!',
|
||||
0: f"✅[崩铁]切换uid{sr_uid}成功!",
|
||||
-1: "❌[崩铁]不存在绑定记录!",
|
||||
-2: "❌[崩铁]请绑定两个以上UID再进行切换!",
|
||||
-3: "❌[崩铁]请绑定两个以上UID再进行切换!",
|
||||
},
|
||||
)
|
||||
|
||||
data = await GsBind.delete_uid(qid, ev.bot_id, sr_uid, 'sr')
|
||||
data = await GsBind.delete_uid(qid, ev.bot_id, sr_uid, "sr")
|
||||
return await send_diff_msg(
|
||||
bot,
|
||||
data,
|
||||
{
|
||||
0: f'✅[崩铁]删除UID{sr_uid}成功!',
|
||||
-1: f'❌[崩铁]该UID{sr_uid}不在已绑定列表中!',
|
||||
0: f"✅[崩铁]删除UID{sr_uid}成功!",
|
||||
-1: f"❌[崩铁]该UID{sr_uid}不在已绑定列表中!",
|
||||
},
|
||||
)
|
||||
|
@ -20,104 +20,104 @@ from ..utils.resource.RESOURCE_PATH import (
|
||||
WIKI_MATERIAL_FOR_ROLE,
|
||||
)
|
||||
|
||||
sv_sr_wiki = SV('星铁WIKI')
|
||||
sv_sr_guide = SV('星铁攻略')
|
||||
sv_sr_wiki = SV("星铁WIKI")
|
||||
sv_sr_guide = SV("星铁攻略")
|
||||
|
||||
|
||||
@sv_sr_wiki.on_prefix('sr角色图鉴')
|
||||
@sv_sr_wiki.on_prefix("sr角色图鉴")
|
||||
async def send_role_wiki_pic(bot: Bot, ev: Event):
|
||||
char_name = ' '.join(re.findall('[\u4e00-\u9fa5]+', ev.text))
|
||||
await bot.logger.info(f'开始获取{char_name}图鉴')
|
||||
if '开拓者' in str(char_name):
|
||||
char_name = '开拓者'
|
||||
char_name = " ".join(re.findall("[\u4e00-\u9fa5]+", ev.text))
|
||||
await bot.logger.info(f"开始获取{char_name}图鉴")
|
||||
if "开拓者" in str(char_name):
|
||||
char_name = "开拓者"
|
||||
char_id = await name_to_avatar_id(char_name)
|
||||
if char_id == '':
|
||||
if char_id == "":
|
||||
char_name = await alias_to_char_name(char_name)
|
||||
char_id = await name_to_avatar_id(char_name)
|
||||
img = WIKI_ROLE_PATH / f'{char_id}.png'
|
||||
img = WIKI_ROLE_PATH / f"{char_id}.png"
|
||||
if img.exists():
|
||||
img = await convert_img(img)
|
||||
await bot.logger.info(f'获得{char_name}图鉴图片成功!')
|
||||
await bot.logger.info(f"获得{char_name}图鉴图片成功!")
|
||||
await bot.send(img)
|
||||
else:
|
||||
await bot.logger.warning(f'未找到{char_name}图鉴图片')
|
||||
await bot.logger.warning(f"未找到{char_name}图鉴图片")
|
||||
|
||||
|
||||
@sv_sr_guide.on_prefix('sr角色攻略')
|
||||
@sv_sr_guide.on_prefix("sr角色攻略")
|
||||
async def send_role_guide_pic(bot: Bot, ev: Event):
|
||||
char_name = ' '.join(re.findall('[\u4e00-\u9fa5]+', ev.text))
|
||||
await bot.logger.info(f'开始获取{char_name}图鉴')
|
||||
if '开拓者' in str(char_name):
|
||||
char_name = '开拓者'
|
||||
char_name = " ".join(re.findall("[\u4e00-\u9fa5]+", ev.text))
|
||||
await bot.logger.info(f"开始获取{char_name}图鉴")
|
||||
if "开拓者" in str(char_name):
|
||||
char_name = "开拓者"
|
||||
char_id = await name_to_avatar_id(char_name)
|
||||
if char_id == '':
|
||||
if char_id == "":
|
||||
char_name = await alias_to_char_name(char_name)
|
||||
char_id = await name_to_avatar_id(char_name)
|
||||
img = GUIDE_CHARACTER_PATH / f'{char_id}.png'
|
||||
img = GUIDE_CHARACTER_PATH / f"{char_id}.png"
|
||||
if img.exists():
|
||||
img = await convert_img(img)
|
||||
await bot.logger.info(f'获得{char_id}图鉴图片成功!')
|
||||
await bot.logger.info(f"获得{char_id}图鉴图片成功!")
|
||||
await bot.send(img)
|
||||
else:
|
||||
await bot.logger.warning(f'未找到{char_id}图鉴图片')
|
||||
await bot.logger.warning(f"未找到{char_id}图鉴图片")
|
||||
|
||||
|
||||
@sv_sr_guide.on_prefix('sr光锥攻略')
|
||||
@sv_sr_guide.on_prefix("sr光锥攻略")
|
||||
async def send_weapon_guide_pic(bot: Bot, ev: Event):
|
||||
msg = ' '.join(re.findall('[\u4e00-\u9fa5]+', ev.text))
|
||||
await bot.logger.info(f'开始获取{msg}图鉴')
|
||||
msg = " ".join(re.findall("[\u4e00-\u9fa5]+", ev.text))
|
||||
await bot.logger.info(f"开始获取{msg}图鉴")
|
||||
light_cone_id = await name_to_weapon_id(msg)
|
||||
img = GUIDE_LIGHT_CONE_PATH / f'{light_cone_id}.png'
|
||||
img = GUIDE_LIGHT_CONE_PATH / f"{light_cone_id}.png"
|
||||
if img.exists():
|
||||
img = await convert_img(img)
|
||||
await bot.logger.info(f'获得{light_cone_id}光锥图片成功!')
|
||||
await bot.logger.info(f"获得{light_cone_id}光锥图片成功!")
|
||||
await bot.send(img)
|
||||
else:
|
||||
await bot.logger.warning(f'未找到{light_cone_id}光锥图片')
|
||||
await bot.logger.warning(f"未找到{light_cone_id}光锥图片")
|
||||
|
||||
|
||||
@sv_sr_wiki.on_prefix('sr遗器')
|
||||
@sv_sr_wiki.on_prefix("sr遗器")
|
||||
async def send_relic_wiki_pic(bot: Bot, ev: Event):
|
||||
msg = ' '.join(re.findall('[\u4e00-\u9fa5]+', ev.text))
|
||||
await bot.logger.info(f'开始获取{msg}遗器')
|
||||
msg = " ".join(re.findall("[\u4e00-\u9fa5]+", ev.text))
|
||||
await bot.logger.info(f"开始获取{msg}遗器")
|
||||
set_id = await name_to_relic_set_id(msg)
|
||||
img = WIKI_RELIC_PATH / f'{set_id}.png'
|
||||
img = WIKI_RELIC_PATH / f"{set_id}.png"
|
||||
if img.exists():
|
||||
img = await convert_img(img)
|
||||
await bot.logger.info(f'获得{msg}遗器图片成功!')
|
||||
await bot.logger.info(f"获得{msg}遗器图片成功!")
|
||||
await bot.send(img)
|
||||
else:
|
||||
await bot.logger.warning(f'未找到{msg}遗器图片')
|
||||
await bot.logger.warning(f"未找到{msg}遗器图片")
|
||||
|
||||
|
||||
@sv_sr_wiki.on_prefix('sr突破材料')
|
||||
@sv_sr_wiki.on_prefix("sr突破材料")
|
||||
async def send_material_for_role_wiki_pic(bot: Bot, ev: Event):
|
||||
char_name = ' '.join(re.findall('[\u4e00-\u9fa5]+', ev.text))
|
||||
await bot.logger.info(f'开始获取{char_name}突破材料')
|
||||
if '开拓者' in str(char_name):
|
||||
char_name = '开拓者'
|
||||
char_name = " ".join(re.findall("[\u4e00-\u9fa5]+", ev.text))
|
||||
await bot.logger.info(f"开始获取{char_name}突破材料")
|
||||
if "开拓者" in str(char_name):
|
||||
char_name = "开拓者"
|
||||
char_id = await name_to_avatar_id(char_name)
|
||||
if char_id == '':
|
||||
if char_id == "":
|
||||
char_name = await alias_to_char_name(char_name)
|
||||
char_id = await name_to_avatar_id(char_name)
|
||||
img = WIKI_MATERIAL_FOR_ROLE / f'{char_id}.png'
|
||||
img = WIKI_MATERIAL_FOR_ROLE / f"{char_id}.png"
|
||||
if img.exists():
|
||||
img = await convert_img(img)
|
||||
await bot.logger.info(f'获得{char_name}突破材料图片成功!')
|
||||
await bot.logger.info(f"获得{char_name}突破材料图片成功!")
|
||||
await bot.send(img)
|
||||
else:
|
||||
await bot.logger.warning(f'未找到{char_name}突破材料图片')
|
||||
await bot.logger.warning(f"未找到{char_name}突破材料图片")
|
||||
|
||||
|
||||
@sv_sr_wiki.on_prefix('sr武器')
|
||||
@sv_sr_wiki.on_prefix("sr武器")
|
||||
async def send_light_cone_wiki_pic(bot: Bot, ev: Event):
|
||||
msg = ' '.join(re.findall('[\u4e00-\u9fa5]+', ev.text))
|
||||
await bot.logger.info(f'开始获取{msg}武器')
|
||||
msg = " ".join(re.findall("[\u4e00-\u9fa5]+", ev.text))
|
||||
await bot.logger.info(f"开始获取{msg}武器")
|
||||
light_cone_id = await name_to_weapon_id(msg)
|
||||
img = WIKI_LIGHT_CONE_PATH / f'{light_cone_id}.png'
|
||||
img = WIKI_LIGHT_CONE_PATH / f"{light_cone_id}.png"
|
||||
if img.exists():
|
||||
img = await convert_img(img)
|
||||
await bot.logger.info(f'获得{msg}武器图片成功!')
|
||||
await bot.logger.info(f"获得{msg}武器图片成功!")
|
||||
await bot.send(img)
|
||||
else:
|
||||
await bot.logger.warning(f'未找到{msg}武器图片')
|
||||
await bot.logger.warning(f"未找到{msg}武器图片")
|
||||
|
@ -1,36 +1,12 @@
|
||||
import re
|
||||
from typing import Tuple, Union, Optional, overload
|
||||
from typing import Optional, Tuple, Union
|
||||
|
||||
from gsuid_core.bot import Bot
|
||||
from gsuid_core.models import Event
|
||||
from gsuid_core.utils.database.api import get_uid as get_uid_db
|
||||
from gsuid_core.utils.database.models import GsBind
|
||||
|
||||
|
||||
@overload
|
||||
async def get_uid(
|
||||
bot: Bot, ev: Event, get_user_id: bool = False, only_uid: bool = False
|
||||
) -> Optional[str]: ...
|
||||
|
||||
|
||||
@overload
|
||||
async def get_uid(
|
||||
bot: Bot, ev: Event, get_user_id: bool = True, only_uid: bool = False
|
||||
) -> Tuple[Optional[str], str]: ...
|
||||
|
||||
|
||||
async def get_uid(
|
||||
bot: Bot, ev: Event, get_user_id: bool = False, only_uid: bool = False
|
||||
bot: Bot, ev: Event, get_user_id: bool = False
|
||||
) -> Union[Optional[str], Tuple[Optional[str], str]]:
|
||||
uid_data = re.findall(r'\d{9}', ev.text)
|
||||
user_id = ev.at if ev.at else ev.user_id
|
||||
if uid_data:
|
||||
sr_uid: Optional[str] = uid_data[0]
|
||||
if sr_uid:
|
||||
ev.text = ev.text.replace(sr_uid, '')
|
||||
else:
|
||||
sr_uid = await GsBind.get_uid_by_game(ev.user_id, ev.bot_id, 'sr')
|
||||
if only_uid:
|
||||
sr_uid = await GsBind.get_uid_by_game(ev.user_id, ev.bot_id, 'sr')
|
||||
if get_user_id:
|
||||
return sr_uid, user_id
|
||||
return sr_uid
|
||||
return await get_uid_db(bot, ev, GsBind, "sr", get_user_id) # type: ignore
|
||||
|
@ -1,16 +1,16 @@
|
||||
from typing import Union
|
||||
|
||||
UID_HINT = '你还没有绑定过uid哦!\n请使用[sr绑定uid123456]命令绑定!'
|
||||
MYS_HINT = '你还没有绑定过mysid哦!\n请使用[绑定mys1234]命令绑定!'
|
||||
UID_HINT = "你还没有绑定过uid哦!\n请使用[sr绑定uid123456]命令绑定!"
|
||||
MYS_HINT = "你还没有绑定过mysid哦!\n请使用[绑定mys1234]命令绑定!"
|
||||
CK_HINT = """你还没有绑定过Cookie哦!发送【ck帮助】获取帮助!
|
||||
警告:绑定Cookie可能会带来未知的账号风险,请确保信任机器人管理员"""
|
||||
CHAR_HINT = '您的支援/星海同行角色没有{}的数据哦!\n请先把{}放入支援/星海同行中再使用【sr强制刷新】命令来缓存数据进行查询! !'
|
||||
CHAR_HINT = "您的支援/星海同行角色没有{}的数据哦!\n请先把{}放入支援/星海同行中再使用【sr强制刷新】命令来缓存数据进行查询! !"
|
||||
VERIFY_HINT = """出现验证码!
|
||||
如已绑定CK: 请至米游社软件->我的->我的角色处解锁验证码
|
||||
(可使用[gs关闭推送]命令关闭体力推送以减少出现验证码风险)
|
||||
如未绑定CK: 可联系管理员使用[gs清除缓存]命令
|
||||
"""
|
||||
SK_HINT = '你还没有绑定过Stoken或者Stoken已失效~\n请群聊发送 [扫码登陆] 或加好友私聊Bot [添加]后跟SK格式 以绑定SK'
|
||||
SK_HINT = "你还没有绑定过Stoken或者Stoken已失效~\n请群聊发送 [扫码登陆] 或加好友私聊Bot [添加]后跟SK格式 以绑定SK"
|
||||
UPDATE_HINT = """更新失败!更多错误信息请查看控制台...
|
||||
>> 可以尝试使用
|
||||
>> [gs强制更新](危险)
|
||||
@ -21,27 +21,27 @@ def get_error(retcode: Union[int, str]) -> str:
|
||||
if retcode == -51:
|
||||
return CK_HINT
|
||||
if retcode == -100:
|
||||
return '您的cookie已经失效, 请重新获取!'
|
||||
return "您的cookie已经失效, 请重新获取!"
|
||||
if retcode == 10001:
|
||||
return '您的cookie已经失效, 请重新获取!'
|
||||
return "您的cookie已经失效, 请重新获取!"
|
||||
if retcode == 10101:
|
||||
return '当前查询CK已超过每日30次上限!'
|
||||
return "当前查询CK已超过每日30次上限!"
|
||||
if retcode == 10102:
|
||||
return '当前查询id已经设置了隐私, 无法查询!'
|
||||
return "当前查询id已经设置了隐私, 无法查询!"
|
||||
if retcode == 1034:
|
||||
return VERIFY_HINT
|
||||
if retcode == -10001:
|
||||
return '请求体出错, 请检查具体实现代码...'
|
||||
return "请求体出错, 请检查具体实现代码..."
|
||||
if retcode == 10104:
|
||||
return CK_HINT
|
||||
if retcode == -512009:
|
||||
return '[留影叙佳期]已经获取过该内容~!'
|
||||
return "[留影叙佳期]已经获取过该内容~!"
|
||||
if retcode == -201:
|
||||
return '你的账号可能已被封禁, 请联系米游社客服...'
|
||||
return "你的账号可能已被封禁, 请联系米游社客服..."
|
||||
if retcode == -501101:
|
||||
return '当前角色冒险等阶未达到10级, 暂时无法参加此活动...'
|
||||
return "当前角色冒险等阶未达到10级, 暂时无法参加此活动..."
|
||||
if retcode == 400:
|
||||
return '[MINIGG]暂未找到此内容...'
|
||||
return "[MINIGG]暂未找到此内容..."
|
||||
if retcode == -400:
|
||||
return '请输入更详细的名称...'
|
||||
return f'API报错, 错误码为{retcode}!'
|
||||
return "请输入更详细的名称..."
|
||||
return f"API报错, 错误码为{retcode}!"
|
||||
|
@ -88,8 +88,6 @@ class SingleRelicSubAffix(Struct):
|
||||
|
||||
|
||||
AvatarPromotionConfig = convert(AvatarPromotion, List[SingleAvatarPromotion])
|
||||
EquipmentPromotionConfig = convert(
|
||||
EquipmentPromotion, List[SingleEquipmentPromotion]
|
||||
)
|
||||
EquipmentPromotionConfig = convert(EquipmentPromotion, List[SingleEquipmentPromotion])
|
||||
RelicMainAffixConfig = convert(RelicMainAffix, List[SingleRelicMainAffix])
|
||||
RelicSubAffixConfig = convert(RelicSubAffix, List[SingleRelicSubAffix])
|
||||
|
@ -3,17 +3,17 @@ from pathlib import Path
|
||||
|
||||
EXCEL = Path(__file__).parent
|
||||
|
||||
with Path.open(EXCEL / 'RelicMainAffixConfig.json', encoding='utf8') as f:
|
||||
with Path.open(EXCEL / "RelicMainAffixConfig.json", encoding="utf8") as f:
|
||||
RelicMainAffix = json.load(f)
|
||||
|
||||
with Path.open(EXCEL / 'RelicSubAffixConfig.json', encoding='utf8') as f:
|
||||
with Path.open(EXCEL / "RelicSubAffixConfig.json", encoding="utf8") as f:
|
||||
RelicSubAffix = json.load(f)
|
||||
|
||||
with Path.open(EXCEL / 'AvatarPromotionConfig.json', encoding='utf8') as f:
|
||||
with Path.open(EXCEL / "AvatarPromotionConfig.json", encoding="utf8") as f:
|
||||
AvatarPromotion = json.load(f)
|
||||
|
||||
with Path.open(EXCEL / 'EquipmentPromotionConfig.json', encoding='utf8') as f:
|
||||
with Path.open(EXCEL / "EquipmentPromotionConfig.json", encoding="utf8") as f:
|
||||
EquipmentPromotion = json.load(f)
|
||||
|
||||
with Path.open(EXCEL / 'light_cone_ranks.json', encoding='utf8') as f:
|
||||
with Path.open(EXCEL / "light_cone_ranks.json", encoding="utf8") as f:
|
||||
light_cone_ranks = json.load(f)
|
||||
|
@ -2,7 +2,7 @@ from pathlib import Path
|
||||
|
||||
from PIL import ImageFont
|
||||
|
||||
FONT_ORIGIN_PATH = Path(__file__).parent / 'FirstWorld.ttf'
|
||||
FONT_ORIGIN_PATH = Path(__file__).parent / "FirstWorld.ttf"
|
||||
|
||||
|
||||
def first_word_origin(size: int) -> ImageFont.FreeTypeFont:
|
||||
|
@ -2,7 +2,7 @@ from pathlib import Path
|
||||
|
||||
from PIL import ImageFont
|
||||
|
||||
FONT_ORIGIN_PATH = Path(__file__).parent / 'starrail_origin.ttf'
|
||||
FONT_ORIGIN_PATH = Path(__file__).parent / "starrail_origin.ttf"
|
||||
|
||||
|
||||
def starrail_font_origin(size: int) -> ImageFont.FreeTypeFont:
|
||||
|
@ -1,107 +0,0 @@
|
||||
from io import BytesIO
|
||||
from pathlib import Path
|
||||
from base64 import b64encode
|
||||
from typing import Union, overload
|
||||
|
||||
import aiofiles
|
||||
from PIL import Image, ImageFont
|
||||
|
||||
|
||||
@overload
|
||||
async def convert_img(img: Image.Image, is_base64: bool = False) -> bytes: ...
|
||||
|
||||
|
||||
@overload
|
||||
async def convert_img(img: Image.Image, is_base64: bool = True) -> str: ...
|
||||
|
||||
|
||||
@overload
|
||||
async def convert_img(img: bytes, is_base64: bool = False) -> str: ...
|
||||
|
||||
|
||||
@overload
|
||||
async def convert_img(img: Path, is_base64: bool = False) -> str: ...
|
||||
|
||||
|
||||
async def convert_img(
|
||||
img: Union[Image.Image, str, Path, bytes], is_base64: bool = False
|
||||
) -> Union[str, bytes]:
|
||||
"""
|
||||
:说明:
|
||||
将PIL.Image对象转换为bytes或者base64格式。
|
||||
:参数:
|
||||
* img (Image): 图片。
|
||||
* is_base64 (bool): 是否转换为base64格式, 不填默认转为bytes。
|
||||
:返回:
|
||||
* res: bytes对象或base64编码图片。
|
||||
"""
|
||||
if isinstance(img, Image.Image):
|
||||
img = img.convert('RGB')
|
||||
result_buffer = BytesIO()
|
||||
img.save(result_buffer, format='PNG', quality=80, subsampling=0)
|
||||
res = result_buffer.getvalue()
|
||||
if is_base64:
|
||||
res = 'base64://' + b64encode(res).decode()
|
||||
return res
|
||||
if isinstance(img, bytes):
|
||||
pass
|
||||
else:
|
||||
async with aiofiles.open(img, 'rb') as fp:
|
||||
img = await fp.read()
|
||||
return f'base64://{b64encode(img).decode()}'
|
||||
|
||||
|
||||
async def str_lenth(r: str, size: int, limit: int = 540) -> str:
|
||||
result = ''
|
||||
temp = 0
|
||||
for i in r:
|
||||
if i == '\n':
|
||||
temp = 0
|
||||
result += i
|
||||
continue
|
||||
|
||||
if temp >= limit:
|
||||
result += '\n' + i
|
||||
temp = 0
|
||||
else:
|
||||
result += i
|
||||
|
||||
if i.isdigit():
|
||||
temp += round(size / 10 * 6)
|
||||
elif i == '/':
|
||||
temp += round(size / 10 * 2.2)
|
||||
elif i == '.':
|
||||
temp += round(size / 10 * 3)
|
||||
elif i == '%':
|
||||
temp += round(size / 10 * 9.4)
|
||||
else:
|
||||
temp += size
|
||||
return result
|
||||
|
||||
|
||||
def get_str_size(
|
||||
r: str, font: ImageFont.FreeTypeFont, limit: int = 540
|
||||
) -> str:
|
||||
result = ''
|
||||
line = ''
|
||||
for i in r:
|
||||
if i == '\n':
|
||||
result += f'{line}\n'
|
||||
line = ''
|
||||
continue
|
||||
|
||||
line += i
|
||||
if hasattr(font, 'getsize'):
|
||||
size, _ = font.getsize(line) # type: ignore
|
||||
else:
|
||||
size, _, _, _ = font.getbbox(line)
|
||||
if size >= limit:
|
||||
result += f'{line}\n'
|
||||
line = ''
|
||||
result += line
|
||||
return result
|
||||
|
||||
|
||||
def get_height(content: str, size: int) -> int:
|
||||
line_count = content.count('\n')
|
||||
return (line_count + 1) * size
|
@ -7,9 +7,9 @@ from gsuid_core.utils.image.image_tools import TEXT_PATH, CustomizeImage
|
||||
from ..resource.RESOURCE_PATH import CU_BG_PATH
|
||||
from ...starrailuid_config.sr_config import srconfig
|
||||
|
||||
BG_PATH = Path(__file__).parent / 'bg'
|
||||
NM_BG_PATH = BG_PATH / 'nm_bg'
|
||||
SP_BG_PATH = BG_PATH / 'sp_bg'
|
||||
BG_PATH = Path(__file__).parent / "bg"
|
||||
NM_BG_PATH = BG_PATH / "nm_bg"
|
||||
SP_BG_PATH = BG_PATH / "sp_bg"
|
||||
|
||||
if list(CU_BG_PATH.iterdir()) != []:
|
||||
bg_path = CU_BG_PATH
|
||||
@ -35,10 +35,10 @@ async def get_color_bg(
|
||||
bg: Optional[str] = None,
|
||||
without_mask: bool = False,
|
||||
) -> Image.Image:
|
||||
image = ''
|
||||
if bg and srconfig.get_config('DefaultBaseBG').data:
|
||||
path = SP_BG_PATH / f'{bg}.jpg'
|
||||
path2 = CU_BG_PATH / f'{bg}.jpg'
|
||||
image = ""
|
||||
if bg and srconfig.get_config("DefaultBaseBG").data:
|
||||
path = SP_BG_PATH / f"{bg}.jpg"
|
||||
path2 = CU_BG_PATH / f"{bg}.jpg"
|
||||
if path2.exists():
|
||||
image = Image.open(path2)
|
||||
elif path.exists():
|
||||
@ -47,9 +47,7 @@ async def get_color_bg(
|
||||
img = CI_img.get_image(image, based_w, based_h)
|
||||
color = CI_img.get_bg_color(img)
|
||||
if not without_mask:
|
||||
color_mask = Image.new('RGBA', (based_w, based_h), color)
|
||||
enka_mask = Image.open(TEXT_PATH / 'bg_mask.png').resize(
|
||||
(based_w, based_h)
|
||||
)
|
||||
color_mask = Image.new("RGBA", (based_w, based_h), color)
|
||||
enka_mask = Image.open(TEXT_PATH / "bg_mask.png").resize((based_w, based_h))
|
||||
img.paste(color_mask, (0, 0), enka_mask)
|
||||
return img
|
||||
|
@ -12,36 +12,34 @@ class RelicSetStatusAdd(Struct):
|
||||
Value: float
|
||||
|
||||
|
||||
MAP = Path(__file__).parent / 'data'
|
||||
MAP = Path(__file__).parent / "data"
|
||||
|
||||
version = StarRail_version
|
||||
|
||||
avatarId2Name_fileName = f'avatarId2Name_mapping_{version}.json'
|
||||
avatarId2EnName_fileName = f'avatarId2EnName_mapping_{version}.json'
|
||||
EquipmentID2Name_fileName = f'EquipmentID2Name_mapping_{version}.json'
|
||||
EquipmentID2EnName_fileName = f'EquipmentID2EnName_mapping_{version}.json'
|
||||
skillId2Name_fileName = f'skillId2Name_mapping_{version}.json'
|
||||
skillId2Type_fileName = f'skillId2Type_mapping_{version}.json'
|
||||
Property2Name_fileName = f'Property2Name_mapping_{version}.json'
|
||||
RelicId2SetId_fileName = f'RelicId2SetId_mapping_{version}.json'
|
||||
SetId2Name_fileName = f'SetId2Name_mapping_{version}.json'
|
||||
rankId2Name_fileName = f'rankId2Name_mapping_{version}.json'
|
||||
characterSkillTree_fileName = f'characterSkillTree_mapping_{version}.json'
|
||||
avatarId2DamageType_fileName = f'avatarId2DamageType_mapping_{version}.json'
|
||||
avatarId2Rarity_fileName = f'avatarId2Rarity_mapping_{version}.json'
|
||||
avatarId2Name_fileName = f"avatarId2Name_mapping_{version}.json"
|
||||
avatarId2EnName_fileName = f"avatarId2EnName_mapping_{version}.json"
|
||||
EquipmentID2Name_fileName = f"EquipmentID2Name_mapping_{version}.json"
|
||||
EquipmentID2EnName_fileName = f"EquipmentID2EnName_mapping_{version}.json"
|
||||
skillId2Name_fileName = f"skillId2Name_mapping_{version}.json"
|
||||
skillId2Type_fileName = f"skillId2Type_mapping_{version}.json"
|
||||
Property2Name_fileName = f"Property2Name_mapping_{version}.json"
|
||||
RelicId2SetId_fileName = f"RelicId2SetId_mapping_{version}.json"
|
||||
SetId2Name_fileName = f"SetId2Name_mapping_{version}.json"
|
||||
rankId2Name_fileName = f"rankId2Name_mapping_{version}.json"
|
||||
characterSkillTree_fileName = f"characterSkillTree_mapping_{version}.json"
|
||||
avatarId2DamageType_fileName = f"avatarId2DamageType_mapping_{version}.json"
|
||||
avatarId2Rarity_fileName = f"avatarId2Rarity_mapping_{version}.json"
|
||||
EquipmentID2AbilityProperty_fileName = (
|
||||
f'EquipmentID2AbilityProperty_mapping_{version}.json'
|
||||
f"EquipmentID2AbilityProperty_mapping_{version}.json"
|
||||
)
|
||||
RelicSetSkill_fileName = f'RelicSetSkill_mapping_{version}.json'
|
||||
skillId2AttackType_fileName = f'skillId2AttackType_mapping_{version}.json'
|
||||
EquipmentID2Rarity_fileName = f'EquipmentID2Rarity_mapping_{version}.json'
|
||||
RelicId2Rarity_fileName = f'RelicId2Rarity_mapping_{version}.json'
|
||||
ItemId2Name_fileName = f'ItemId2Name_mapping_{version}.json'
|
||||
RelicId2MainAffixGroup_fileName = (
|
||||
f'RelicId2MainAffixGroup_mapping_{version}.json'
|
||||
)
|
||||
AvatarRelicScore_fileName = 'AvatarRelicScore.json'
|
||||
avatarRankSkillUp_fileName = f'avatarRankSkillUp_mapping_{version}.json'
|
||||
RelicSetSkill_fileName = f"RelicSetSkill_mapping_{version}.json"
|
||||
skillId2AttackType_fileName = f"skillId2AttackType_mapping_{version}.json"
|
||||
EquipmentID2Rarity_fileName = f"EquipmentID2Rarity_mapping_{version}.json"
|
||||
RelicId2Rarity_fileName = f"RelicId2Rarity_mapping_{version}.json"
|
||||
ItemId2Name_fileName = f"ItemId2Name_mapping_{version}.json"
|
||||
RelicId2MainAffixGroup_fileName = f"RelicId2MainAffixGroup_mapping_{version}.json"
|
||||
AvatarRelicScore_fileName = "AvatarRelicScore.json"
|
||||
avatarRankSkillUp_fileName = f"avatarRankSkillUp_mapping_{version}.json"
|
||||
|
||||
|
||||
class TS(TypedDict):
|
||||
@ -54,51 +52,49 @@ class LU(TypedDict):
|
||||
num: int
|
||||
|
||||
|
||||
with Path.open(MAP / avatarId2Name_fileName, encoding='UTF-8') as f:
|
||||
with Path.open(MAP / avatarId2Name_fileName, encoding="UTF-8") as f:
|
||||
avatarId2Name = msgjson.decode(f.read(), type=Dict[str, str])
|
||||
|
||||
with Path.open(MAP / avatarId2EnName_fileName, encoding='UTF-8') as f:
|
||||
with Path.open(MAP / avatarId2EnName_fileName, encoding="UTF-8") as f:
|
||||
avatarId2EnName = msgjson.decode(f.read(), type=Dict[str, str])
|
||||
|
||||
with Path.open(MAP / EquipmentID2Name_fileName, encoding='UTF-8') as f:
|
||||
with Path.open(MAP / EquipmentID2Name_fileName, encoding="UTF-8") as f:
|
||||
EquipmentID2Name = msgjson.decode(f.read(), type=Dict[str, str])
|
||||
|
||||
with Path.open(MAP / EquipmentID2EnName_fileName, encoding='UTF-8') as f:
|
||||
with Path.open(MAP / EquipmentID2EnName_fileName, encoding="UTF-8") as f:
|
||||
EquipmentID2EnName = msgjson.decode(f.read(), type=Dict[str, str])
|
||||
|
||||
with Path.open(MAP / skillId2Name_fileName, encoding='UTF-8') as f:
|
||||
with Path.open(MAP / skillId2Name_fileName, encoding="UTF-8") as f:
|
||||
skillId2Name = msgjson.decode(f.read(), type=Dict[str, str])
|
||||
|
||||
with Path.open(MAP / skillId2Type_fileName, encoding='UTF-8') as f:
|
||||
with Path.open(MAP / skillId2Type_fileName, encoding="UTF-8") as f:
|
||||
skillId2Effect = msgjson.decode(f.read(), type=Dict[str, str])
|
||||
|
||||
with Path.open(MAP / Property2Name_fileName, encoding='UTF-8') as f:
|
||||
with Path.open(MAP / Property2Name_fileName, encoding="UTF-8") as f:
|
||||
Property2Name = msgjson.decode(f.read(), type=Dict[str, str])
|
||||
|
||||
with Path.open(MAP / RelicId2SetId_fileName, encoding='UTF-8') as f:
|
||||
with Path.open(MAP / RelicId2SetId_fileName, encoding="UTF-8") as f:
|
||||
RelicId2SetId = msgjson.decode(f.read(), type=Dict[str, int])
|
||||
|
||||
with Path.open(MAP / SetId2Name_fileName, encoding='UTF-8') as f:
|
||||
with Path.open(MAP / SetId2Name_fileName, encoding="UTF-8") as f:
|
||||
SetId2Name = msgjson.decode(f.read(), type=Dict[str, str])
|
||||
|
||||
with Path.open(MAP / rankId2Name_fileName, encoding='UTF-8') as f:
|
||||
with Path.open(MAP / rankId2Name_fileName, encoding="UTF-8") as f:
|
||||
rankId2Name = msgjson.decode(f.read(), type=Dict[str, str])
|
||||
|
||||
with Path.open(MAP / characterSkillTree_fileName, encoding='UTF-8') as f:
|
||||
with Path.open(MAP / characterSkillTree_fileName, encoding="UTF-8") as f:
|
||||
characterSkillTree = msgjson.decode(f.read(), type=Dict[str, Dict])
|
||||
|
||||
with Path.open(MAP / avatarId2DamageType_fileName, encoding='UTF-8') as f:
|
||||
with Path.open(MAP / avatarId2DamageType_fileName, encoding="UTF-8") as f:
|
||||
avatarId2DamageType = msgjson.decode(f.read(), type=Dict[str, str])
|
||||
|
||||
with Path.open(MAP / 'char_alias.json', encoding='UTF-8') as f:
|
||||
with Path.open(MAP / "char_alias.json", encoding="UTF-8") as f:
|
||||
alias_data = msgjson.decode(f.read(), type=Dict[str, Dict[str, List]])
|
||||
|
||||
with Path.open(MAP / avatarId2Rarity_fileName, encoding='UTF-8') as f:
|
||||
with Path.open(MAP / avatarId2Rarity_fileName, encoding="UTF-8") as f:
|
||||
avatarId2Rarity = msgjson.decode(f.read(), type=Dict[str, str])
|
||||
|
||||
with Path.open(
|
||||
MAP / EquipmentID2AbilityProperty_fileName, encoding='UTF-8'
|
||||
) as f:
|
||||
with Path.open(MAP / EquipmentID2AbilityProperty_fileName, encoding="UTF-8") as f:
|
||||
EquipmentID2AbilityProperty = msgjson.decode(
|
||||
f.read(), type=Dict[str, Dict[str, List]]
|
||||
)
|
||||
@ -107,25 +103,23 @@ with Path.open(
|
||||
# RelicSetSkill = convert(json.load(f), Dict[str, Dict[str, object]])
|
||||
# print(RelicSetSkill)
|
||||
|
||||
with Path.open(MAP / skillId2AttackType_fileName, encoding='UTF-8') as f:
|
||||
with Path.open(MAP / skillId2AttackType_fileName, encoding="UTF-8") as f:
|
||||
skillId2AttackType = msgjson.decode(f.read(), type=Dict[str, str])
|
||||
|
||||
with Path.open(MAP / EquipmentID2Rarity_fileName, encoding='UTF-8') as f:
|
||||
with Path.open(MAP / EquipmentID2Rarity_fileName, encoding="UTF-8") as f:
|
||||
EquipmentID2Rarity = msgjson.decode(f.read(), type=Dict[str, int])
|
||||
|
||||
with Path.open(MAP / RelicId2Rarity_fileName, encoding='UTF-8') as f:
|
||||
with Path.open(MAP / RelicId2Rarity_fileName, encoding="UTF-8") as f:
|
||||
RelicId2Rarity = msgjson.decode(f.read(), type=Dict[str, int])
|
||||
|
||||
with Path.open(MAP / ItemId2Name_fileName, encoding='UTF-8') as f:
|
||||
with Path.open(MAP / ItemId2Name_fileName, encoding="UTF-8") as f:
|
||||
ItemId2Name = msgjson.decode(f.read(), type=Dict[str, str])
|
||||
|
||||
with Path.open(MAP / RelicId2MainAffixGroup_fileName, encoding='UTF-8') as f:
|
||||
with Path.open(MAP / RelicId2MainAffixGroup_fileName, encoding="UTF-8") as f:
|
||||
RelicId2MainAffixGroup = msgjson.decode(f.read(), type=Dict[str, int])
|
||||
|
||||
with Path.open(MAP / AvatarRelicScore_fileName, encoding='UTF-8') as f:
|
||||
with Path.open(MAP / AvatarRelicScore_fileName, encoding="UTF-8") as f:
|
||||
AvatarRelicScore = msgjson.decode(f.read(), type=List[Dict])
|
||||
|
||||
with Path.open(MAP / avatarRankSkillUp_fileName, encoding='UTF-8') as f:
|
||||
AvatarRankSkillUp = msgjson.decode(
|
||||
f.read(), type=Dict[str, Union[List[LU], None]]
|
||||
)
|
||||
with Path.open(MAP / avatarRankSkillUp_fileName, encoding="UTF-8") as f:
|
||||
AvatarRankSkillUp = msgjson.decode(f.read(), type=Dict[str, Union[List[LU], None]])
|
||||
|
@ -1,54 +1,54 @@
|
||||
import json
|
||||
|
||||
with open('./data/characters.json', 'r', encoding='utf8') as f:
|
||||
with open("./data/characters.json", "r", encoding="utf8") as f:
|
||||
characters = json.load(f)
|
||||
|
||||
with open('./data/character_ranks.json', 'r', encoding='utf8') as f:
|
||||
with open("./data/character_ranks.json", "r", encoding="utf8") as f:
|
||||
character_ranks = json.load(f)
|
||||
|
||||
with open('./data/character_skills.json', 'r', encoding='utf8') as f:
|
||||
with open("./data/character_skills.json", "r", encoding="utf8") as f:
|
||||
character_skills = json.load(f)
|
||||
|
||||
with open('./data/character_skill_trees.json', 'r', encoding='utf8') as f:
|
||||
with open("./data/character_skill_trees.json", "r", encoding="utf8") as f:
|
||||
character_skill_trees = json.load(f)
|
||||
|
||||
with open('./data/AvatarConfig.json', 'r', encoding='utf8') as f:
|
||||
with open("./data/AvatarConfig.json", "r", encoding="utf8") as f:
|
||||
AvatarConfig = json.load(f)
|
||||
|
||||
with open('./data/TextMapCN.json', 'r', encoding='utf8') as f:
|
||||
with open("./data/TextMapCN.json", "r", encoding="utf8") as f:
|
||||
TextMapCN = json.load(f)
|
||||
|
||||
with open('./data/TextMapEN.json', 'r', encoding='utf8') as f:
|
||||
with open("./data/TextMapEN.json", "r", encoding="utf8") as f:
|
||||
TextMapEN = json.load(f)
|
||||
|
||||
with open('./data/EquipmentConfig.json', 'r', encoding='utf8') as f:
|
||||
with open("./data/EquipmentConfig.json", "r", encoding="utf8") as f:
|
||||
EquipmentConfig = json.load(f)
|
||||
|
||||
with open('./data/AvatarSkillConfig.json', 'r', encoding='utf8') as f:
|
||||
with open("./data/AvatarSkillConfig.json", "r", encoding="utf8") as f:
|
||||
AvatarSkillConfig = json.load(f)
|
||||
|
||||
with open('./data/AvatarPropertyConfig.json', 'r', encoding='utf8') as f:
|
||||
with open("./data/AvatarPropertyConfig.json", "r", encoding="utf8") as f:
|
||||
AvatarPropertyConfig = json.load(f)
|
||||
|
||||
with open('./data/EquipmentSkillConfig.json', 'r', encoding='utf8') as f:
|
||||
with open("./data/EquipmentSkillConfig.json", "r", encoding="utf8") as f:
|
||||
EquipmentSkillConfig = json.load(f)
|
||||
|
||||
with open('./data/RelicConfig.json', 'r', encoding='utf8') as f:
|
||||
with open("./data/RelicConfig.json", "r", encoding="utf8") as f:
|
||||
RelicConfig = json.load(f)
|
||||
|
||||
with open('./data/RelicSetConfig.json', 'r', encoding='utf8') as f:
|
||||
with open("./data/RelicSetConfig.json", "r", encoding="utf8") as f:
|
||||
RelicSetConfig = json.load(f)
|
||||
|
||||
with open('./data/RelicSetSkillConfig.json', 'r', encoding='utf8') as f:
|
||||
with open("./data/RelicSetSkillConfig.json", "r", encoding="utf8") as f:
|
||||
RelicSetSkillConfig = json.load(f)
|
||||
|
||||
with open('./data/light_cones.json', 'r', encoding='utf8') as f:
|
||||
with open("./data/light_cones.json", "r", encoding="utf8") as f:
|
||||
light_cones = json.load(f)
|
||||
|
||||
with open('./data/relics_new.json', 'r', encoding='utf8') as f:
|
||||
with open("./data/relics_new.json", "r", encoding="utf8") as f:
|
||||
relics_new = json.load(f)
|
||||
|
||||
with open('./data/ItemConfigRelic.json', 'r', encoding='utf8') as f:
|
||||
with open("./data/ItemConfigRelic.json", "r", encoding="utf8") as f:
|
||||
ItemConfigRelic = json.load(f)
|
||||
|
||||
avatarId2Name = {}
|
||||
@ -74,32 +74,32 @@ RelicId2MainAffixGroup = {}
|
||||
|
||||
for char in characters:
|
||||
char_item = characters[char]
|
||||
rank_list = characters[char]['ranks']
|
||||
rarity = characters[char]['rarity']
|
||||
rank_list = characters[char]["ranks"]
|
||||
rarity = characters[char]["rarity"]
|
||||
avatarId2Rarity[char] = str(rarity)
|
||||
for rank in rank_list:
|
||||
if character_ranks.get(str(rank)):
|
||||
eidolon = character_ranks[str(rank)]
|
||||
rank_id = eidolon['id']
|
||||
rank_name = eidolon['name']
|
||||
rank_id = eidolon["id"]
|
||||
rank_name = eidolon["name"]
|
||||
rankId2Name[rank_id] = rank_name
|
||||
|
||||
for item in AvatarConfig:
|
||||
avatar_item = AvatarConfig[item]
|
||||
avatar_id = avatar_item['AvatarID']
|
||||
avatar_name_hash = avatar_item['AvatarName']['Hash']
|
||||
avatar_damage_type = avatar_item['DamageType']
|
||||
avatar_en_name = ''
|
||||
avatar_name = ''
|
||||
avatar_id = avatar_item["AvatarID"]
|
||||
avatar_name_hash = avatar_item["AvatarName"]["Hash"]
|
||||
avatar_damage_type = avatar_item["DamageType"]
|
||||
avatar_en_name = ""
|
||||
avatar_name = ""
|
||||
for item in TextMapCN:
|
||||
if str(item) == str(avatar_name_hash):
|
||||
avatar_name = TextMapCN[item]
|
||||
if avatar_name == '{NICKNAME}':
|
||||
avatar_name = '开拓者'
|
||||
if avatar_name == "{NICKNAME}":
|
||||
avatar_name = "开拓者"
|
||||
break
|
||||
for item in TextMapEN:
|
||||
if str(item) == str(avatar_name_hash):
|
||||
avatar_en_name = TextMapEN[item].replace(' ', '')
|
||||
avatar_en_name = TextMapEN[item].replace(" ", "")
|
||||
break
|
||||
avatarId2EnName[avatar_id] = avatar_en_name
|
||||
avatarId2Name[avatar_id] = avatar_name
|
||||
@ -108,9 +108,9 @@ for item in AvatarConfig:
|
||||
|
||||
for item in EquipmentConfig:
|
||||
equipment_item = EquipmentConfig[item]
|
||||
equipment_id = equipment_item['EquipmentID']
|
||||
equipment_name_hash = equipment_item['EquipmentName']['Hash']
|
||||
equipment_name = ''
|
||||
equipment_id = equipment_item["EquipmentID"]
|
||||
equipment_name_hash = equipment_item["EquipmentName"]["Hash"]
|
||||
equipment_name = ""
|
||||
for item in TextMapCN:
|
||||
if str(item) == str(equipment_name_hash):
|
||||
equipment_name = TextMapCN[item]
|
||||
@ -122,30 +122,30 @@ for item in EquipmentSkillConfig:
|
||||
equipment_item = EquipmentSkillConfig[item]
|
||||
EquipmentID2AbilityProperty[str(item)] = {}
|
||||
for i in equipment_item:
|
||||
equipment_ability_property = equipment_item[str(i)]['AbilityProperty']
|
||||
equipment_ability_property = equipment_item[str(i)]["AbilityProperty"]
|
||||
EquipmentID2AbilityProperty[str(item)][i] = equipment_ability_property
|
||||
|
||||
|
||||
for item in EquipmentConfig:
|
||||
equipment_item = EquipmentConfig[item]
|
||||
equipment_id = equipment_item['EquipmentID']
|
||||
equipment_name_hash = equipment_item['EquipmentName']['Hash']
|
||||
equipment_name = ''
|
||||
equipment_id = equipment_item["EquipmentID"]
|
||||
equipment_name_hash = equipment_item["EquipmentName"]["Hash"]
|
||||
equipment_name = ""
|
||||
for item in TextMapEN:
|
||||
if str(item) == str(equipment_name_hash):
|
||||
equipment_name = TextMapEN[item].replace(' ', '')
|
||||
equipment_name = TextMapEN[item].replace(" ", "")
|
||||
break
|
||||
EquipmentID2EnName[equipment_id] = equipment_name
|
||||
|
||||
|
||||
for skill in AvatarSkillConfig:
|
||||
skill_item = AvatarSkillConfig[skill]
|
||||
skill_id = skill_item['1']['SkillID']
|
||||
skill_name_hash = skill_item['1']['SkillName']['Hash']
|
||||
skill_type_hash = skill_item['1']['SkillTag']['Hash']
|
||||
skill_attack_type = skill_item['1'].get('AttackType', '')
|
||||
skill_name = ''
|
||||
skill_type = ''
|
||||
skill_id = skill_item["1"]["SkillID"]
|
||||
skill_name_hash = skill_item["1"]["SkillName"]["Hash"]
|
||||
skill_type_hash = skill_item["1"]["SkillTag"]["Hash"]
|
||||
skill_attack_type = skill_item["1"].get("AttackType", "")
|
||||
skill_name = ""
|
||||
skill_type = ""
|
||||
for item in TextMapCN:
|
||||
if str(item) == str(skill_name_hash):
|
||||
skill_name = TextMapCN[item]
|
||||
@ -160,12 +160,12 @@ for skill in AvatarSkillConfig:
|
||||
|
||||
|
||||
for avatar_property in AvatarPropertyConfig:
|
||||
PropertyType = AvatarPropertyConfig[avatar_property]['PropertyType']
|
||||
PropertyName = AvatarPropertyConfig[avatar_property]['PropertyName']
|
||||
PropertyNameHash = AvatarPropertyConfig[avatar_property][
|
||||
'PropertyNameFilter'
|
||||
]['Hash']
|
||||
Property_Name = ''
|
||||
PropertyType = AvatarPropertyConfig[avatar_property]["PropertyType"]
|
||||
PropertyName = AvatarPropertyConfig[avatar_property]["PropertyName"]
|
||||
PropertyNameHash = AvatarPropertyConfig[avatar_property]["PropertyNameFilter"][
|
||||
"Hash"
|
||||
]
|
||||
Property_Name = ""
|
||||
for item in TextMapCN:
|
||||
if str(item) == str(PropertyNameHash):
|
||||
Property_Name = TextMapCN[item]
|
||||
@ -174,13 +174,13 @@ for avatar_property in AvatarPropertyConfig:
|
||||
|
||||
|
||||
for relic in RelicConfig:
|
||||
Relic2SetId[relic] = RelicConfig[relic]['SetID']
|
||||
RelicId2MainAffixGroup[relic] = RelicConfig[relic]['MainAffixGroup']
|
||||
Relic2SetId[relic] = RelicConfig[relic]["SetID"]
|
||||
RelicId2MainAffixGroup[relic] = RelicConfig[relic]["MainAffixGroup"]
|
||||
|
||||
|
||||
for set_group in RelicSetConfig:
|
||||
set_name_hash = RelicSetConfig[set_group]['SetName']['Hash']
|
||||
set_name = ''
|
||||
set_name_hash = RelicSetConfig[set_group]["SetName"]["Hash"]
|
||||
set_name = ""
|
||||
for item in TextMapCN:
|
||||
if str(item) == str(set_name_hash):
|
||||
set_name = TextMapCN[item]
|
||||
@ -189,13 +189,13 @@ for set_group in RelicSetConfig:
|
||||
|
||||
|
||||
for character in characters:
|
||||
char_id = characters[character]['id']
|
||||
char_id = characters[character]["id"]
|
||||
characterSkillTree[str(char_id)] = (
|
||||
{}
|
||||
if str(char_id) not in characterSkillTree
|
||||
else characterSkillTree[str(char_id)]
|
||||
)
|
||||
skill_tree_list = characters[character]['skill_trees']
|
||||
skill_tree_list = characters[character]["skill_trees"]
|
||||
for skill in skill_tree_list:
|
||||
skill_tree = character_skill_trees[skill]
|
||||
characterSkillTree[str(char_id)][str(skill)] = skill_tree
|
||||
@ -203,38 +203,34 @@ for character in characters:
|
||||
|
||||
for set_ in RelicSetSkillConfig:
|
||||
for item in RelicSetSkillConfig[set_]:
|
||||
set_id = RelicSetSkillConfig[set_][item]['SetID']
|
||||
property_list = RelicSetSkillConfig[set_][item]['PropertyList']
|
||||
RelicSetSkill[set_] = (
|
||||
{} if set_ not in RelicSetSkill else RelicSetSkill[set_]
|
||||
)
|
||||
set_id = RelicSetSkillConfig[set_][item]["SetID"]
|
||||
property_list = RelicSetSkillConfig[set_][item]["PropertyList"]
|
||||
RelicSetSkill[set_] = {} if set_ not in RelicSetSkill else RelicSetSkill[set_]
|
||||
RelicSetSkill[set_][item] = (
|
||||
{}
|
||||
if item not in RelicSetSkill[set_]
|
||||
else RelicSetSkill[set_][item]
|
||||
{} if item not in RelicSetSkill[set_] else RelicSetSkill[set_][item]
|
||||
)
|
||||
for property_ in property_list:
|
||||
property_id = property_['NAOGDGBJNOJ']
|
||||
property_value = property_['MBOHKHKHFPD']['Value']
|
||||
RelicSetSkill[set_][item]['Property'] = property_id
|
||||
RelicSetSkill[set_][item]['Value'] = property_value
|
||||
property_id = property_["NAOGDGBJNOJ"]
|
||||
property_value = property_["MBOHKHKHFPD"]["Value"]
|
||||
RelicSetSkill[set_][item]["Property"] = property_id
|
||||
RelicSetSkill[set_][item]["Value"] = property_value
|
||||
|
||||
|
||||
for light_cone in light_cones:
|
||||
rarity = light_cones[light_cone]['rarity']
|
||||
light_cone_id = light_cones[light_cone]['id']
|
||||
rarity = light_cones[light_cone]["rarity"]
|
||||
light_cone_id = light_cones[light_cone]["id"]
|
||||
EquipmentID2Rarity[light_cone_id] = rarity
|
||||
|
||||
|
||||
for item in relics_new:
|
||||
rarity = relics_new[item]['rarity']
|
||||
relic_id = relics_new[item]['id']
|
||||
rarity = relics_new[item]["rarity"]
|
||||
relic_id = relics_new[item]["id"]
|
||||
RelicId2Rarity[relic_id] = rarity
|
||||
|
||||
for item in ItemConfigRelic:
|
||||
item_id = ItemConfigRelic[item]['ID']
|
||||
item_name_hash = ItemConfigRelic[item]['ItemName']['Hash']
|
||||
item_name = ''
|
||||
item_id = ItemConfigRelic[item]["ID"]
|
||||
item_name_hash = ItemConfigRelic[item]["ItemName"]["Hash"]
|
||||
item_name = ""
|
||||
for item in TextMapCN:
|
||||
if str(item) == str(item_name_hash):
|
||||
item_name = TextMapCN[item]
|
||||
|
@ -20,7 +20,7 @@ async def avatar_id_to_name(avatar_id: str) -> str:
|
||||
|
||||
|
||||
async def name_to_avatar_id(name: str) -> str:
|
||||
avatar_id = ''
|
||||
avatar_id = ""
|
||||
for i in avatarId2Name:
|
||||
if avatarId2Name[i] == name:
|
||||
avatar_id = i
|
||||
@ -33,16 +33,16 @@ async def avatar_id_to_char_star(char_id: str) -> str:
|
||||
|
||||
|
||||
async def alias_to_char_name(char_name: str) -> str:
|
||||
for i in alias_data['characters']:
|
||||
if char_name in alias_data['characters'][i]:
|
||||
return alias_data['characters'][i][0]
|
||||
for i in alias_data["characters"]:
|
||||
if char_name in alias_data["characters"][i]:
|
||||
return alias_data["characters"][i][0]
|
||||
return char_name
|
||||
|
||||
|
||||
async def alias_to_weapon_name(weapon_name: str) -> str:
|
||||
for i in alias_data['light_cones']:
|
||||
if weapon_name in alias_data['light_cones'][i]:
|
||||
return alias_data['light_cones'][i][0]
|
||||
for i in alias_data["light_cones"]:
|
||||
if weapon_name in alias_data["light_cones"][i]:
|
||||
return alias_data["light_cones"][i][0]
|
||||
return weapon_name
|
||||
|
||||
|
||||
@ -51,7 +51,7 @@ async def weapon_id_to_name(weapon_id: str) -> str:
|
||||
|
||||
|
||||
async def name_to_weapon_id(name: str) -> str:
|
||||
weapon_id = ''
|
||||
weapon_id = ""
|
||||
for i in EquipmentID2Name:
|
||||
if EquipmentID2Name[i] == name:
|
||||
weapon_id = i
|
||||
@ -64,7 +64,7 @@ async def weapon_id_to_en_name(weapon_id: str) -> str:
|
||||
|
||||
|
||||
async def en_name_to_weapon_id(name: str) -> str:
|
||||
weapon_id = ''
|
||||
weapon_id = ""
|
||||
for i in EquipmentID2EnName:
|
||||
if EquipmentID2EnName[i] == name:
|
||||
weapon_id = i
|
||||
|
@ -1,66 +1,55 @@
|
||||
import copy
|
||||
import time
|
||||
from typing import Any, Dict, Union, Literal, Optional
|
||||
from typing import Dict, Literal, Optional, Union
|
||||
|
||||
import msgspec
|
||||
from gsuid_core.utils.api.mys_api import _MysApi
|
||||
|
||||
# from gsuid_core.utils.api.mys.models import MysSign, SignList
|
||||
from gsuid_core.utils.api.mys.tools import (
|
||||
mys_version,
|
||||
_random_int_ds,
|
||||
generate_os_ds,
|
||||
get_ds_token,
|
||||
get_web_ds_token,
|
||||
mys_version,
|
||||
)
|
||||
from gsuid_core.utils.api.mys_api import _MysApi
|
||||
import msgspec
|
||||
|
||||
from ..sruid_utils.api.mys.api import _API
|
||||
from ..sruid_utils.api.mys.models import (
|
||||
MysSign,
|
||||
AbyssBossData,
|
||||
AbyssData,
|
||||
AbyssStoryData,
|
||||
AvatarDetail,
|
||||
AvatarInfo,
|
||||
DailyNoteData,
|
||||
GachaLog,
|
||||
MonthlyAward,
|
||||
MysSign,
|
||||
RogueData,
|
||||
RogueLocustData,
|
||||
RoleBasicInfo,
|
||||
RoleIndex,
|
||||
SignInfo,
|
||||
SignList,
|
||||
AbyssData,
|
||||
RogueData,
|
||||
RoleIndex,
|
||||
AvatarInfo,
|
||||
AvatarDetail,
|
||||
MonthlyAward,
|
||||
DailyNoteData,
|
||||
RoleBasicInfo,
|
||||
WidgetStamina,
|
||||
RogueLocustData, AbyssStoryData, AbyssBossData,
|
||||
)
|
||||
|
||||
RECOGNIZE_SERVER = {
|
||||
'1': 'prod_gf_cn',
|
||||
'2': 'prod_gf_cn',
|
||||
'5': 'prod_qd_cn',
|
||||
'6': 'prod_official_usa',
|
||||
'7': 'prod_official_euro',
|
||||
'8': 'prod_official_asia',
|
||||
'9': 'prod_official_cht',
|
||||
"1": "prod_gf_cn",
|
||||
"2": "prod_gf_cn",
|
||||
"5": "prod_qd_cn",
|
||||
"6": "prod_official_usa",
|
||||
"7": "prod_official_euro",
|
||||
"8": "prod_official_asia",
|
||||
"9": "prod_official_cht",
|
||||
}
|
||||
|
||||
|
||||
def get_ds_token2(
|
||||
q: str = '',
|
||||
b: Optional[Dict[str, Any]] = None,
|
||||
):
|
||||
salt = 't0qEgfub6cvueAPgR5m9aQWWVciEer7v'
|
||||
return _random_int_ds(salt, q, b)
|
||||
|
||||
|
||||
class MysApi(_MysApi):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
async def get_sr_ck(
|
||||
self, uid: str, mode: Literal['OWNER', 'RANDOM'] = 'RANDOM'
|
||||
self, uid: str, mode: Literal["OWNER", "RANDOM"] = "RANDOM"
|
||||
) -> Optional[str]:
|
||||
return await self.get_ck(uid, mode, 'sr')
|
||||
|
||||
def check_os(self, uid: str) -> bool:
|
||||
return False if int(str(uid)[0]) < 6 else True
|
||||
return await self.get_ck(uid, mode, "sr")
|
||||
|
||||
async def simple_sr_req(
|
||||
self,
|
||||
@ -76,40 +65,38 @@ class MysApi(_MysApi):
|
||||
params,
|
||||
header,
|
||||
cookie,
|
||||
'sr',
|
||||
"sr",
|
||||
)
|
||||
|
||||
async def get_daily_data(self, uid: str) -> Union[DailyNoteData, int]:
|
||||
is_os = self.check_os(uid)
|
||||
if is_os:
|
||||
async def get_sr_daily_data(self, uid: str) -> Union[DailyNoteData, int]:
|
||||
if self.check_os(uid, game_name="sr"):
|
||||
HEADER = copy.deepcopy(self._HEADER_OS)
|
||||
ck = await self.get_sr_ck(uid, 'OWNER')
|
||||
ck = await self.get_sr_ck(uid, "OWNER")
|
||||
if ck is None:
|
||||
return -51
|
||||
HEADER['Cookie'] = ck
|
||||
HEADER['DS'] = generate_os_ds()
|
||||
HEADER["Cookie"] = ck
|
||||
HEADER["DS"] = generate_os_ds()
|
||||
header = HEADER
|
||||
data = await self.simple_sr_req(
|
||||
'STAR_RAIL_NOTE_URL',
|
||||
"STAR_RAIL_NOTE_URL",
|
||||
uid,
|
||||
params={
|
||||
'role_id': uid,
|
||||
'server': RECOGNIZE_SERVER.get(str(uid)[0], 'prod_gf_cn'),
|
||||
"role_id": uid,
|
||||
"server": RECOGNIZE_SERVER.get(str(uid)[0], "prod_gf_cn"),
|
||||
},
|
||||
header=header,
|
||||
)
|
||||
else:
|
||||
data = await self.simple_sr_req(
|
||||
'STAR_RAIL_NOTE_URL', uid, header=self._HEADER
|
||||
"STAR_RAIL_NOTE_URL", uid, header=self._HEADER
|
||||
)
|
||||
if isinstance(data, Dict):
|
||||
# workaround for mistake params in hoyolab
|
||||
if data['data']['accepted_epedition_num']:
|
||||
data['data']['accepted_expedition_num'] = data['data'][
|
||||
'accepted_epedition_num'
|
||||
if data["data"]["accepted_epedition_num"]:
|
||||
data["data"]["accepted_expedition_num"] = data["data"][
|
||||
"accepted_epedition_num"
|
||||
]
|
||||
data = msgspec.convert(data['data'], type=DailyNoteData)
|
||||
# data = cast(DailyNoteData, data['data'])
|
||||
data = msgspec.convert(data["data"], type=DailyNoteData)
|
||||
return data
|
||||
|
||||
async def get_widget_stamina_data(
|
||||
@ -117,389 +104,373 @@ class MysApi(_MysApi):
|
||||
uid: str,
|
||||
) -> Union[WidgetStamina, int]:
|
||||
header = copy.deepcopy(self._HEADER)
|
||||
sk = await self.get_stoken(uid, 'sr')
|
||||
sk = await self.get_stoken(uid, "sr")
|
||||
if sk is None:
|
||||
return -51
|
||||
header['Cookie'] = sk
|
||||
header['x-rpc-channel'] = 'beta'
|
||||
device_id = await self.get_user_device_id(uid, 'sr')
|
||||
header['x-rpc-device_id'] = '23' if device_id is None else device_id
|
||||
header['x-rpc-app_version'] = '2.53.0'
|
||||
header['x-rpc-device_model'] = 'Mi 10'
|
||||
fp = await self.get_user_fp(uid, 'sr')
|
||||
header['x-rpc-device_fp'] = 'Asmr489' if fp is None else fp
|
||||
header['x-rpc-client_type'] = '2'
|
||||
header['DS'] = get_ds_token2()
|
||||
header['Referer'] = 'https://app.mihoyo.com'
|
||||
del header['Origin']
|
||||
header['x-rpc-sys_version'] = '12'
|
||||
header['User-Agent'] = 'okhttp/4.8.0'
|
||||
header["Cookie"] = sk
|
||||
header["x-rpc-channel"] = "beta"
|
||||
device_id = await self.get_user_device_id(uid, "sr")
|
||||
header["x-rpc-device_id"] = "23" if device_id is None else device_id
|
||||
header["x-rpc-app_version"] = "2.53.0"
|
||||
header["x-rpc-device_model"] = "Mi 10"
|
||||
fp = await self.get_user_fp(uid, "sr")
|
||||
header["x-rpc-device_fp"] = "Asmr489" if fp is None else fp
|
||||
header["x-rpc-client_type"] = "2"
|
||||
header["DS"] = get_ds_token()
|
||||
header["Referer"] = "https://app.mihoyo.com"
|
||||
del header["Origin"]
|
||||
header["x-rpc-sys_version"] = "12"
|
||||
header["User-Agent"] = "okhttp/4.8.0"
|
||||
data = await self._mys_request(
|
||||
_API['STAR_RAIL_WIDGRT_URL'],
|
||||
'GET',
|
||||
_API["STAR_RAIL_WIDGRT_URL"],
|
||||
"GET",
|
||||
header,
|
||||
)
|
||||
if isinstance(data, Dict):
|
||||
data = msgspec.convert(data['data'], type=WidgetStamina)
|
||||
# data = cast(WidgetStamina, data['data'])
|
||||
data = msgspec.convert(data["data"], type=WidgetStamina)
|
||||
return data
|
||||
|
||||
async def get_role_index(self, uid: str) -> Union[RoleIndex, int]:
|
||||
is_os = self.check_os(uid)
|
||||
if is_os:
|
||||
if self.check_os(uid, game_name="sr"):
|
||||
HEADER = copy.deepcopy(self._HEADER_OS)
|
||||
ck = await self.get_sr_ck(uid, 'OWNER')
|
||||
ck = await self.get_sr_ck(uid, "OWNER")
|
||||
if ck is None:
|
||||
return -51
|
||||
HEADER['Cookie'] = ck
|
||||
HEADER['DS'] = generate_os_ds()
|
||||
HEADER["Cookie"] = ck
|
||||
HEADER["DS"] = generate_os_ds()
|
||||
header = HEADER
|
||||
data = await self.simple_sr_req(
|
||||
'STAR_RAIL_INDEX_URL',
|
||||
"STAR_RAIL_INDEX_URL",
|
||||
uid,
|
||||
params={
|
||||
'role_id': uid,
|
||||
'server': RECOGNIZE_SERVER.get(str(uid)[0], 'prod_gf_cn'),
|
||||
"role_id": uid,
|
||||
"server": RECOGNIZE_SERVER.get(str(uid)[0], "prod_gf_cn"),
|
||||
},
|
||||
header=header,
|
||||
)
|
||||
else:
|
||||
data = await self.simple_sr_req(
|
||||
'STAR_RAIL_INDEX_URL', uid, header=self._HEADER
|
||||
"STAR_RAIL_INDEX_URL", uid, header=self._HEADER
|
||||
)
|
||||
if isinstance(data, Dict):
|
||||
data = msgspec.convert(data['data'], type=RoleIndex)
|
||||
# data = cast(RoleIndex, data['data'])
|
||||
data = msgspec.convert(data["data"], type=RoleIndex)
|
||||
return data
|
||||
|
||||
async def get_gacha_log_by_link_in_authkey(
|
||||
self,
|
||||
uid: str,
|
||||
authkey: str,
|
||||
gacha_type: str = '11',
|
||||
gacha_type: str = "11",
|
||||
page: int = 1,
|
||||
end_id: str = '0',
|
||||
end_id: str = "0",
|
||||
) -> Union[int, GachaLog]:
|
||||
# server_id = 'cn_qd01' if
|
||||
# uid[0] == '5' else 'cn_gf01'
|
||||
server_id = RECOGNIZE_SERVER.get(str(uid)[0])
|
||||
if self.check_os(uid):
|
||||
HEADER = copy.deepcopy(self._HEADER_OS)
|
||||
ck = await self.get_sr_ck(uid, 'OWNER')
|
||||
ck = await self.get_sr_ck(uid, "OWNER")
|
||||
if ck is None:
|
||||
return -51
|
||||
HEADER['Cookie'] = ck
|
||||
HEADER['DS'] = generate_os_ds()
|
||||
HEADER["Cookie"] = ck
|
||||
HEADER["DS"] = generate_os_ds()
|
||||
header = HEADER
|
||||
url = self.MAPI['STAR_RAIL_GACHA_LOG_URL_OS']
|
||||
game_biz = 'hkrpg_global'
|
||||
url = self.MAPI["STAR_RAIL_GACHA_LOG_URL_OS"]
|
||||
game_biz = "hkrpg_global"
|
||||
else:
|
||||
header = self._HEADER
|
||||
url = self.MAPI['STAR_RAIL_GACHA_LOG_URL']
|
||||
game_biz = 'hkrpg_cn'
|
||||
url = self.MAPI["STAR_RAIL_GACHA_LOG_URL"]
|
||||
game_biz = "hkrpg_cn"
|
||||
data = await self._mys_request(
|
||||
url=url,
|
||||
method='GET',
|
||||
method="GET",
|
||||
header=header,
|
||||
params={
|
||||
'authkey_ver': '1',
|
||||
'sign_type': '2',
|
||||
'auth_appid': 'webview_gacha',
|
||||
'default_gacha_type': 11,
|
||||
'gacha_id': 'dbebc8d9fbb0d4ffa067423482ce505bc5ea',
|
||||
'timestamp': str(int(time.time())),
|
||||
'lang': 'zh-cn',
|
||||
'plat_type': 'pc',
|
||||
'region': server_id,
|
||||
'authkey': authkey,
|
||||
'game_biz': game_biz,
|
||||
'gacha_type': gacha_type,
|
||||
'page': page,
|
||||
'size': '20',
|
||||
'end_id': end_id,
|
||||
"authkey_ver": "1",
|
||||
"sign_type": "2",
|
||||
"auth_appid": "webview_gacha",
|
||||
"default_gacha_type": 11,
|
||||
"gacha_id": "dbebc8d9fbb0d4ffa067423482ce505bc5ea",
|
||||
"timestamp": str(int(time.time())),
|
||||
"lang": "zh-cn",
|
||||
"plat_type": "pc",
|
||||
"region": server_id,
|
||||
"authkey": authkey,
|
||||
"game_biz": game_biz,
|
||||
"gacha_type": gacha_type,
|
||||
"page": page,
|
||||
"size": "20",
|
||||
"end_id": end_id,
|
||||
},
|
||||
)
|
||||
if isinstance(data, Dict):
|
||||
data = msgspec.convert(data['data'], type=GachaLog)
|
||||
# data = cast(GachaLog, data['data'])
|
||||
data = msgspec.convert(data["data"], type=GachaLog)
|
||||
return data
|
||||
|
||||
async def get_avatar_info(
|
||||
self, uid: str, avatar_id: int, need_wiki: bool = False
|
||||
) -> Union[AvatarInfo, int]:
|
||||
is_os = self.check_os(uid)
|
||||
if is_os:
|
||||
if self.check_os(uid, game_name="sr"):
|
||||
HEADER = copy.deepcopy(self._HEADER_OS)
|
||||
ck = await self.get_sr_ck(uid, 'OWNER')
|
||||
ck = await self.get_sr_ck(uid, "OWNER")
|
||||
if ck is None:
|
||||
return -51
|
||||
HEADER['Cookie'] = ck
|
||||
HEADER['DS'] = generate_os_ds()
|
||||
HEADER["Cookie"] = ck
|
||||
HEADER["DS"] = generate_os_ds()
|
||||
header = HEADER
|
||||
data = await self.simple_sr_req(
|
||||
'STAR_RAIL_AVATAR_INFO_URL',
|
||||
"STAR_RAIL_AVATAR_INFO_URL",
|
||||
uid,
|
||||
params={
|
||||
'need_wiki': 'true' if need_wiki else 'false',
|
||||
'role_id': uid,
|
||||
'server': RECOGNIZE_SERVER.get(str(uid)[0], 'prod_gf_cn'),
|
||||
"need_wiki": "true" if need_wiki else "false",
|
||||
"role_id": uid,
|
||||
"server": RECOGNIZE_SERVER.get(str(uid)[0], "prod_official_asia"),
|
||||
},
|
||||
header=header,
|
||||
)
|
||||
else:
|
||||
data = await self.simple_sr_req(
|
||||
'STAR_RAIL_AVATAR_INFO_URL',
|
||||
"STAR_RAIL_AVATAR_INFO_URL",
|
||||
uid,
|
||||
params={
|
||||
'id': avatar_id,
|
||||
'need_wiki': 'true' if need_wiki else 'false',
|
||||
'role_id': uid,
|
||||
'server': RECOGNIZE_SERVER.get(str(uid)[0], 'prod_gf_cn'),
|
||||
"id": avatar_id,
|
||||
"need_wiki": "true" if need_wiki else "false",
|
||||
"role_id": uid,
|
||||
"server": RECOGNIZE_SERVER.get(str(uid)[0], "prod_gf_cn"),
|
||||
},
|
||||
header=self._HEADER,
|
||||
)
|
||||
if isinstance(data, Dict):
|
||||
data = msgspec.convert(data['data'], type=AvatarInfo)
|
||||
# data = cast(AvatarInfo, data['data'])
|
||||
data = msgspec.convert(data["data"], type=AvatarInfo)
|
||||
return data
|
||||
|
||||
async def get_avatar_detail(self, uid: str, avatarid: str):
|
||||
data = await self.simple_sr_req(
|
||||
'STAR_RAIL_AVATAR_DETAIL_URL',
|
||||
"STAR_RAIL_AVATAR_DETAIL_URL",
|
||||
uid,
|
||||
params={
|
||||
'game': 'hkrpg',
|
||||
'lang': 'zh-cn',
|
||||
'item_id': avatarid,
|
||||
'tab_from': 'TabOwned',
|
||||
'change_target_level': '0',
|
||||
'uid': uid,
|
||||
'region': RECOGNIZE_SERVER.get(str(uid)[0], 'prod_gf_cn'),
|
||||
"game": "hkrpg",
|
||||
"lang": "zh-cn",
|
||||
"item_id": avatarid,
|
||||
"tab_from": "TabOwned",
|
||||
"change_target_level": "0",
|
||||
"uid": uid,
|
||||
"region": RECOGNIZE_SERVER.get(str(uid)[0], "prod_gf_cn"),
|
||||
},
|
||||
header=self._HEADER,
|
||||
)
|
||||
if isinstance(data, Dict):
|
||||
data = msgspec.convert(data['data'], type=AvatarDetail)
|
||||
data = msgspec.convert(data["data"], type=AvatarDetail)
|
||||
return data
|
||||
|
||||
async def get_sign_list(self, uid) -> Union[SignList, int]:
|
||||
async def get_sr_sign_list(self, uid) -> Union[SignList, int]:
|
||||
is_os = self.check_os(uid)
|
||||
if is_os:
|
||||
params = {
|
||||
'act_id': 'e202303301540311',
|
||||
'lang': 'zh-cn',
|
||||
"act_id": "e202303301540311",
|
||||
"lang": "zh-cn",
|
||||
}
|
||||
|
||||
else:
|
||||
params = {
|
||||
'act_id': 'e202304121516551',
|
||||
'lang': 'zh-cn',
|
||||
"act_id": "e202304121516551",
|
||||
"lang": "zh-cn",
|
||||
}
|
||||
|
||||
data = await self._mys_req_get(
|
||||
'STAR_RAIL_SIGN_LIST_URL',
|
||||
"STAR_RAIL_SIGN_LIST_URL",
|
||||
is_os,
|
||||
params,
|
||||
)
|
||||
if isinstance(data, Dict):
|
||||
data = msgspec.convert(data['data'], type=SignList)
|
||||
# data = cast(SignList, data['data'])
|
||||
data = msgspec.convert(data["data"], type=SignList)
|
||||
return data
|
||||
|
||||
async def get_sign_info(self, uid) -> Union[SignInfo, int]:
|
||||
# server_id = RECOGNIZE_SERVER.get(str(uid)[0])
|
||||
async def get_sr_sign_info(self, uid) -> Union[SignInfo, int]:
|
||||
is_os = self.check_os(uid)
|
||||
if is_os:
|
||||
# TODO
|
||||
params = {
|
||||
'act_id': 'e202303301540311',
|
||||
'lang': 'zh-cn',
|
||||
"act_id": "e202303301540311",
|
||||
"lang": "zh-cn",
|
||||
}
|
||||
HEADER = copy.deepcopy(self._HEADER_OS)
|
||||
ck = await self.get_sr_ck(uid, 'OWNER')
|
||||
ck = await self.get_sr_ck(uid, "OWNER")
|
||||
if ck is None:
|
||||
return -51
|
||||
HEADER['Cookie'] = ck
|
||||
HEADER['DS'] = generate_os_ds()
|
||||
HEADER["Cookie"] = ck
|
||||
HEADER["DS"] = generate_os_ds()
|
||||
header = HEADER
|
||||
else:
|
||||
params = {
|
||||
'act_id': 'e202304121516551',
|
||||
'lang': 'zh-cn',
|
||||
'region': 'prod_gf_cn',
|
||||
'uid': uid,
|
||||
"act_id": "e202304121516551",
|
||||
"lang": "zh-cn",
|
||||
"region": "prod_gf_cn",
|
||||
"uid": uid,
|
||||
}
|
||||
header = self._HEADER
|
||||
data = await self._mys_req_get(
|
||||
'STAR_RAIL_SIGN_INFO_URL',
|
||||
"STAR_RAIL_SIGN_INFO_URL",
|
||||
is_os,
|
||||
params,
|
||||
header,
|
||||
)
|
||||
if isinstance(data, Dict):
|
||||
data = msgspec.convert(data['data'], type=SignInfo)
|
||||
# data = cast(SignInfo, data['data'])
|
||||
data = msgspec.convert(data["data"], type=SignInfo)
|
||||
return data
|
||||
|
||||
async def get_abyss_info(
|
||||
self,
|
||||
uid: str,
|
||||
schedule_type='1',
|
||||
schedule_type="1",
|
||||
ck: Optional[str] = None,
|
||||
) -> Union[AbyssData, int]:
|
||||
server_id = self.RECOGNIZE_SERVER.get(uid[0])
|
||||
is_os = self.check_os(uid)
|
||||
if is_os:
|
||||
if self.check_os(uid, game_name="sr"):
|
||||
HEADER = copy.deepcopy(self._HEADER_OS)
|
||||
ck = await self.get_sr_ck(uid, 'OWNER')
|
||||
ck = await self.get_sr_ck(uid, "OWNER")
|
||||
if ck is None:
|
||||
return -51
|
||||
HEADER['Cookie'] = ck
|
||||
HEADER['DS'] = generate_os_ds()
|
||||
HEADER["Cookie"] = ck
|
||||
HEADER["DS"] = generate_os_ds()
|
||||
header = HEADER
|
||||
data = await self.simple_sr_req(
|
||||
'CHALLENGE_INFO_URL',
|
||||
"CHALLENGE_INFO_URL",
|
||||
uid,
|
||||
params={
|
||||
'need_all': 'true',
|
||||
'role_id': uid,
|
||||
'schedule_type': schedule_type,
|
||||
'server': server_id,
|
||||
"need_all": "true",
|
||||
"role_id": uid,
|
||||
"schedule_type": schedule_type,
|
||||
"server": server_id,
|
||||
},
|
||||
header=header,
|
||||
)
|
||||
else:
|
||||
data = await self.simple_sr_req(
|
||||
'CHALLENGE_INFO_URL',
|
||||
"CHALLENGE_INFO_URL",
|
||||
uid,
|
||||
params={
|
||||
'isPrev': 'true',
|
||||
'need_all': 'true',
|
||||
'role_id': uid,
|
||||
'schedule_type': schedule_type,
|
||||
'server': server_id,
|
||||
"isPrev": "true",
|
||||
"need_all": "true",
|
||||
"role_id": uid,
|
||||
"schedule_type": schedule_type,
|
||||
"server": server_id,
|
||||
},
|
||||
cookie=ck,
|
||||
header=self._HEADER,
|
||||
)
|
||||
if isinstance(data, Dict):
|
||||
data = msgspec.convert(data['data'], type=AbyssData)
|
||||
# data = cast(AbyssData, data['data'])
|
||||
data = msgspec.convert(data["data"], type=AbyssData)
|
||||
return data
|
||||
|
||||
async def get_abyss_story_info(
|
||||
self,
|
||||
uid: str,
|
||||
schedule_type='1',
|
||||
schedule_type="1",
|
||||
ck: Optional[str] = None,
|
||||
) -> Union[AbyssData, int]:
|
||||
) -> Union[AbyssStoryData, int]:
|
||||
server_id = self.RECOGNIZE_SERVER.get(uid[0])
|
||||
is_os = self.check_os(uid)
|
||||
if is_os:
|
||||
if self.check_os(uid, game_name="sr"):
|
||||
HEADER = copy.deepcopy(self._HEADER_OS)
|
||||
ck = await self.get_sr_ck(uid, 'OWNER')
|
||||
ck = await self.get_sr_ck(uid, "OWNER")
|
||||
if ck is None:
|
||||
return -51
|
||||
HEADER['Cookie'] = ck
|
||||
HEADER['DS'] = generate_os_ds()
|
||||
HEADER["Cookie"] = ck
|
||||
HEADER["DS"] = generate_os_ds()
|
||||
header = HEADER
|
||||
data = await self.simple_sr_req(
|
||||
'CHALLENGE_STORY_INFO_URL',
|
||||
"CHALLENGE_STORY_INFO_URL",
|
||||
uid,
|
||||
params={
|
||||
'need_all': 'true',
|
||||
'role_id': uid,
|
||||
'schedule_type': schedule_type,
|
||||
'server': server_id,
|
||||
"need_all": "true",
|
||||
"role_id": uid,
|
||||
"schedule_type": schedule_type,
|
||||
"server": server_id,
|
||||
},
|
||||
header=header,
|
||||
)
|
||||
else:
|
||||
data = await self.simple_sr_req(
|
||||
'CHALLENGE_STORY_INFO_URL',
|
||||
"CHALLENGE_STORY_INFO_URL",
|
||||
uid,
|
||||
params={
|
||||
'isPrev': 'true',
|
||||
'need_all': 'true',
|
||||
'role_id': uid,
|
||||
'schedule_type': schedule_type,
|
||||
'server': server_id,
|
||||
"isPrev": "true",
|
||||
"need_all": "true",
|
||||
"role_id": uid,
|
||||
"schedule_type": schedule_type,
|
||||
"server": server_id,
|
||||
},
|
||||
cookie=ck,
|
||||
header=self._HEADER,
|
||||
)
|
||||
if isinstance(data, Dict):
|
||||
data = msgspec.convert(data['data'], type=AbyssStoryData)
|
||||
data = msgspec.convert(data["data"], type=AbyssStoryData)
|
||||
|
||||
return data
|
||||
|
||||
async def get_abyss_boss_info(
|
||||
self,
|
||||
uid: str,
|
||||
schedule_type='1',
|
||||
schedule_type="1",
|
||||
ck: Optional[str] = None,
|
||||
) -> Union[AbyssBossData, int]:
|
||||
server_id = self.RECOGNIZE_SERVER.get(uid[0])
|
||||
is_os = self.check_os(uid)
|
||||
if is_os:
|
||||
if self.check_os(uid, game_name="sr"):
|
||||
HEADER = copy.deepcopy(self._HEADER_OS)
|
||||
ck = await self.get_sr_ck(uid, 'OWNER')
|
||||
ck = await self.get_sr_ck(uid, "OWNER")
|
||||
if ck is None:
|
||||
return -51
|
||||
HEADER['Cookie'] = ck
|
||||
HEADER['DS'] = generate_os_ds()
|
||||
HEADER["Cookie"] = ck
|
||||
HEADER["DS"] = generate_os_ds()
|
||||
header = HEADER
|
||||
data = await self.simple_sr_req(
|
||||
'CHALLENGE_BOSS_INFO_URL',
|
||||
"CHALLENGE_BOSS_INFO_URL",
|
||||
uid,
|
||||
params={
|
||||
'need_all': 'true',
|
||||
'role_id': uid,
|
||||
'schedule_type': schedule_type,
|
||||
'server': server_id,
|
||||
"need_all": "true",
|
||||
"role_id": uid,
|
||||
"schedule_type": schedule_type,
|
||||
"server": server_id,
|
||||
},
|
||||
header=header,
|
||||
)
|
||||
else:
|
||||
data = await self.simple_sr_req(
|
||||
'CHALLENGE_BOSS_INFO_URL',
|
||||
"CHALLENGE_BOSS_INFO_URL",
|
||||
uid,
|
||||
params={
|
||||
'isPrev': 'true',
|
||||
'need_all': 'true',
|
||||
'role_id': uid,
|
||||
'schedule_type': schedule_type,
|
||||
'server': server_id,
|
||||
"isPrev": "true",
|
||||
"need_all": "true",
|
||||
"role_id": uid,
|
||||
"schedule_type": schedule_type,
|
||||
"server": server_id,
|
||||
},
|
||||
cookie=ck,
|
||||
header=self._HEADER,
|
||||
)
|
||||
if isinstance(data, Dict):
|
||||
data = msgspec.convert(data['data'], type=AbyssBossData)
|
||||
# data = cast(AbyssData, data['data'])
|
||||
data = msgspec.convert(data["data"], type=AbyssBossData)
|
||||
return data
|
||||
|
||||
async def get_rogue_info(
|
||||
self,
|
||||
uid: str,
|
||||
schedule_type='3',
|
||||
schedule_type="3",
|
||||
ck: Optional[str] = None,
|
||||
) -> Union[RogueData, int]:
|
||||
server_id = self.RECOGNIZE_SERVER.get(uid[0])
|
||||
data = await self.simple_sr_req(
|
||||
'ROGUE_INFO_URL',
|
||||
"ROGUE_INFO_URL",
|
||||
uid,
|
||||
params={
|
||||
'need_detail': 'true',
|
||||
'role_id': uid,
|
||||
'schedule_type': schedule_type,
|
||||
'server': server_id,
|
||||
"need_detail": "true",
|
||||
"role_id": uid,
|
||||
"schedule_type": schedule_type,
|
||||
"server": server_id,
|
||||
},
|
||||
cookie=ck,
|
||||
header=self._HEADER,
|
||||
)
|
||||
if isinstance(data, Dict):
|
||||
data = msgspec.convert(data['data'], type=RogueData)
|
||||
# data = cast(RogueData, data['data'])
|
||||
data = msgspec.convert(data["data"], type=RogueData)
|
||||
return data
|
||||
|
||||
async def get_rogue_locust_info(
|
||||
@ -508,99 +479,96 @@ class MysApi(_MysApi):
|
||||
ck: Optional[str] = None,
|
||||
) -> Union[RogueLocustData, int]:
|
||||
server_id = self.RECOGNIZE_SERVER.get(uid[0])
|
||||
ck = await self.get_sr_ck(uid, 'OWNER')
|
||||
ck = await self.get_sr_ck(uid, "OWNER")
|
||||
data = await self.simple_sr_req(
|
||||
'ROGUE_LOCUST_INFO_URL',
|
||||
"ROGUE_LOCUST_INFO_URL",
|
||||
uid,
|
||||
params={
|
||||
'need_detail': 'true',
|
||||
'role_id': uid,
|
||||
'server': server_id,
|
||||
"need_detail": "true",
|
||||
"role_id": uid,
|
||||
"server": server_id,
|
||||
},
|
||||
cookie=ck,
|
||||
header=self._HEADER,
|
||||
)
|
||||
if isinstance(data, Dict):
|
||||
data = msgspec.convert(data['data'], type=RogueLocustData)
|
||||
# data = cast(RogueLocustData, data['data'])
|
||||
data = msgspec.convert(data["data"], type=RogueLocustData)
|
||||
return data
|
||||
|
||||
async def mys_sign(
|
||||
self, uid, header=None, server_id='cn_gf01'
|
||||
async def sr_mys_sign(
|
||||
self, uid, header=None, server_id="cn_gf01"
|
||||
) -> Union[MysSign, int]:
|
||||
if header is None:
|
||||
header = {}
|
||||
ck = await self.get_sr_ck(uid, 'OWNER')
|
||||
ck = await self.get_sr_ck(uid, "OWNER")
|
||||
if ck is None:
|
||||
return -51
|
||||
if int(str(uid)[0]) < 6:
|
||||
HEADER = copy.deepcopy(self._HEADER)
|
||||
HEADER['Cookie'] = ck
|
||||
HEADER['x-rpc-app_version'] = mys_version
|
||||
HEADER['x-rpc-client_type'] = '5'
|
||||
HEADER['X_Requested_With'] = 'com.mihoyo.hyperion'
|
||||
HEADER['DS'] = get_web_ds_token(True)
|
||||
HEADER['Referer'] = 'https://webstatic.mihoyo.com'
|
||||
HEADER["Cookie"] = ck
|
||||
HEADER["x-rpc-app_version"] = mys_version
|
||||
HEADER["x-rpc-client_type"] = "5"
|
||||
HEADER["X_Requested_With"] = "com.mihoyo.hyperion"
|
||||
HEADER["DS"] = get_web_ds_token(True)
|
||||
HEADER["Referer"] = "https://webstatic.mihoyo.com"
|
||||
HEADER.update(header)
|
||||
data = await self._mys_request(
|
||||
url=_API['STAR_RAIL_SIGN_URL'],
|
||||
method='POST',
|
||||
url=_API["STAR_RAIL_SIGN_URL"],
|
||||
method="POST",
|
||||
header=HEADER,
|
||||
data={
|
||||
'act_id': 'e202304121516551',
|
||||
'region': 'prod_gf_cn',
|
||||
'uid': uid,
|
||||
'lang': 'zh-cn',
|
||||
"act_id": "e202304121516551",
|
||||
"region": "prod_gf_cn",
|
||||
"uid": uid,
|
||||
"lang": "zh-cn",
|
||||
},
|
||||
)
|
||||
else:
|
||||
HEADER = copy.deepcopy(self._HEADER_OS)
|
||||
HEADER['Cookie'] = ck
|
||||
HEADER['DS'] = generate_os_ds()
|
||||
HEADER["Cookie"] = ck
|
||||
HEADER["DS"] = generate_os_ds()
|
||||
HEADER.update(header)
|
||||
data = await self._mys_request(
|
||||
url=_API['STAR_RAIL_SIGN_URL_OS'],
|
||||
method='POST',
|
||||
url=_API["STAR_RAIL_SIGN_URL_OS"],
|
||||
method="POST",
|
||||
header=HEADER,
|
||||
data={
|
||||
'act_id': 'e202303301540311',
|
||||
'lang': 'zh-cn',
|
||||
"act_id": "e202303301540311",
|
||||
"lang": "zh-cn",
|
||||
},
|
||||
)
|
||||
if isinstance(data, Dict):
|
||||
data = msgspec.convert(data['data'], type=MysSign)
|
||||
# data = cast(MysSign, data['data'])
|
||||
data = msgspec.convert(data["data"], type=MysSign)
|
||||
return data
|
||||
|
||||
async def get_award(self, sr_uid, month) -> Union[MonthlyAward, int]:
|
||||
async def get_sr_award(self, sr_uid, month) -> Union[MonthlyAward, int]:
|
||||
server_id = RECOGNIZE_SERVER.get(str(sr_uid)[0])
|
||||
ck = await self.get_sr_ck(sr_uid, 'OWNER')
|
||||
ck = await self.get_sr_ck(sr_uid, "OWNER")
|
||||
if ck is None:
|
||||
return -51
|
||||
if int(str(sr_uid)[0]) < 6:
|
||||
HEADER = copy.deepcopy(self._HEADER)
|
||||
HEADER['Cookie'] = ck
|
||||
HEADER['DS'] = get_web_ds_token(True)
|
||||
HEADER["Cookie"] = ck
|
||||
HEADER["DS"] = get_web_ds_token(True)
|
||||
data = await self._mys_request(
|
||||
url=_API['STAR_RAIL_MONTH_INFO_URL'],
|
||||
method='GET',
|
||||
url=_API["STAR_RAIL_MONTH_INFO_URL"],
|
||||
method="GET",
|
||||
header=HEADER,
|
||||
params={'uid': sr_uid, 'region': server_id, 'month': month},
|
||||
params={"uid": sr_uid, "region": server_id, "month": month},
|
||||
)
|
||||
else:
|
||||
HEADER = copy.deepcopy(self._HEADER_OS)
|
||||
HEADER['Cookie'] = ck
|
||||
HEADER['DS'] = generate_os_ds()
|
||||
HEADER["Cookie"] = ck
|
||||
HEADER["DS"] = generate_os_ds()
|
||||
data = await self._mys_request(
|
||||
url=_API['STAR_RAIL_MONTH_INFO_URL'],
|
||||
method='GET',
|
||||
url=_API["STAR_RAIL_MONTH_INFO_URL"],
|
||||
method="GET",
|
||||
header=HEADER,
|
||||
params={'uid': sr_uid, 'region': server_id, 'month': month},
|
||||
params={"uid": sr_uid, "region": server_id, "month": month},
|
||||
use_proxy=True,
|
||||
)
|
||||
if isinstance(data, Dict):
|
||||
data = msgspec.convert(data['data'], type=MonthlyAward)
|
||||
# data = cast(MonthlyAward, data['data'])
|
||||
data = msgspec.convert(data["data"], type=MonthlyAward)
|
||||
return data
|
||||
|
||||
async def get_role_basic_info(
|
||||
@ -608,11 +576,10 @@ class MysApi(_MysApi):
|
||||
sr_uid: str,
|
||||
) -> Union[RoleBasicInfo, int]:
|
||||
data = await self.simple_sr_req(
|
||||
'STAR_RAIL_ROLE_BASIC_INFO_URL', sr_uid, header=self._HEADER
|
||||
"STAR_RAIL_ROLE_BASIC_INFO_URL", sr_uid, header=self._HEADER
|
||||
)
|
||||
if isinstance(data, Dict):
|
||||
data = msgspec.convert(data['data'], type=RoleBasicInfo)
|
||||
# data = cast(RoleBasicInfo, data['data'])
|
||||
data = msgspec.convert(data["data"], type=RoleBasicInfo)
|
||||
return data
|
||||
|
||||
|
||||
|
@ -3,35 +3,35 @@ from pathlib import Path
|
||||
|
||||
from gsuid_core.data_store import get_res_path
|
||||
|
||||
MAIN_PATH = get_res_path() / 'StarRailUID'
|
||||
MAIN_PATH = get_res_path() / "StarRailUID"
|
||||
sys.path.append(str(MAIN_PATH))
|
||||
|
||||
CU_BG_PATH = MAIN_PATH / 'bg'
|
||||
CONFIG_PATH = MAIN_PATH / 'config.json'
|
||||
PLAYER_PATH = MAIN_PATH / 'players'
|
||||
RESOURCE_PATH = MAIN_PATH / 'resource'
|
||||
WIKI_PATH = MAIN_PATH / 'wiki'
|
||||
GUIDE_PATH = MAIN_PATH / 'guide'
|
||||
CU_BG_PATH = MAIN_PATH / "bg"
|
||||
CONFIG_PATH = MAIN_PATH / "config.json"
|
||||
PLAYER_PATH = MAIN_PATH / "players"
|
||||
RESOURCE_PATH = MAIN_PATH / "resource"
|
||||
WIKI_PATH = MAIN_PATH / "wiki"
|
||||
GUIDE_PATH = MAIN_PATH / "guide"
|
||||
|
||||
CHAR_ICON_PATH = RESOURCE_PATH / 'character'
|
||||
CHAR_PORTRAIT_PATH = RESOURCE_PATH / 'character_portrait'
|
||||
CONSUMABLE_PATH = RESOURCE_PATH / 'consumable'
|
||||
ELEMENT_PATH = RESOURCE_PATH / 'element'
|
||||
WEAPON_PATH = RESOURCE_PATH / 'light_cone'
|
||||
RELIC_PATH = RESOURCE_PATH / 'relic'
|
||||
SKILL_PATH = RESOURCE_PATH / 'skill'
|
||||
TEMP_PATH = RESOURCE_PATH / 'temp'
|
||||
CHAR_PREVIEW_PATH = RESOURCE_PATH / 'character_preview'
|
||||
CHAR_ICON_PATH = RESOURCE_PATH / "character"
|
||||
CHAR_PORTRAIT_PATH = RESOURCE_PATH / "character_portrait"
|
||||
CONSUMABLE_PATH = RESOURCE_PATH / "consumable"
|
||||
ELEMENT_PATH = RESOURCE_PATH / "element"
|
||||
WEAPON_PATH = RESOURCE_PATH / "light_cone"
|
||||
RELIC_PATH = RESOURCE_PATH / "relic"
|
||||
SKILL_PATH = RESOURCE_PATH / "skill"
|
||||
TEMP_PATH = RESOURCE_PATH / "temp"
|
||||
CHAR_PREVIEW_PATH = RESOURCE_PATH / "character_preview"
|
||||
|
||||
WIKI_LIGHT_CONE_PATH = WIKI_PATH / 'light_cone'
|
||||
WIKI_MATERIAL_FOR_ROLE = WIKI_PATH / 'character_material'
|
||||
WIKI_RELIC_PATH = WIKI_PATH / 'relic_set'
|
||||
WIKI_ROLE_PATH = WIKI_PATH / 'character_overview'
|
||||
WIKI_LIGHT_CONE_PATH = WIKI_PATH / "light_cone"
|
||||
WIKI_MATERIAL_FOR_ROLE = WIKI_PATH / "character_material"
|
||||
WIKI_RELIC_PATH = WIKI_PATH / "relic_set"
|
||||
WIKI_ROLE_PATH = WIKI_PATH / "character_overview"
|
||||
|
||||
GUIDE_LIGHT_CONE_PATH = GUIDE_PATH / 'light_cone'
|
||||
GUIDE_CHARACTER_PATH = GUIDE_PATH / 'character_overview'
|
||||
GUIDE_LIGHT_CONE_PATH = GUIDE_PATH / "light_cone"
|
||||
GUIDE_CHARACTER_PATH = GUIDE_PATH / "character_overview"
|
||||
|
||||
TEXT2D_PATH = Path(__file__).parent / 'texture2d'
|
||||
TEXT2D_PATH = Path(__file__).parent / "texture2d"
|
||||
|
||||
|
||||
def init_dir():
|
||||
|
@ -20,22 +20,22 @@ from gsuid_core.utils.download_resource.download_core import download_all_file
|
||||
|
||||
async def check_use():
|
||||
await download_all_file(
|
||||
'StarRailUID',
|
||||
"StarRailUID",
|
||||
{
|
||||
'resource/character': CHAR_ICON_PATH,
|
||||
'resource/character_portrait': CHAR_PORTRAIT_PATH,
|
||||
'resource/character_preview': CHAR_PREVIEW_PATH,
|
||||
'resource/consumable': CONSUMABLE_PATH,
|
||||
'resource/element': ELEMENT_PATH,
|
||||
'guide/character_overview': GUIDE_CHARACTER_PATH,
|
||||
'guide/light_cone': GUIDE_LIGHT_CONE_PATH,
|
||||
'resource/relic': RELIC_PATH,
|
||||
'resource/skill': SKILL_PATH,
|
||||
'resource/light_cone': WEAPON_PATH,
|
||||
'wiki/light_cone': WIKI_LIGHT_CONE_PATH,
|
||||
'wiki/character_material': WIKI_MATERIAL_FOR_ROLE,
|
||||
'wiki/relic_set': WIKI_RELIC_PATH,
|
||||
'wiki/character_overview': WIKI_ROLE_PATH,
|
||||
"resource/character": CHAR_ICON_PATH,
|
||||
"resource/character_portrait": CHAR_PORTRAIT_PATH,
|
||||
"resource/character_preview": CHAR_PREVIEW_PATH,
|
||||
"resource/consumable": CONSUMABLE_PATH,
|
||||
"resource/element": ELEMENT_PATH,
|
||||
"guide/character_overview": GUIDE_CHARACTER_PATH,
|
||||
"guide/light_cone": GUIDE_LIGHT_CONE_PATH,
|
||||
"resource/relic": RELIC_PATH,
|
||||
"resource/skill": SKILL_PATH,
|
||||
"resource/light_cone": WEAPON_PATH,
|
||||
"wiki/light_cone": WIKI_LIGHT_CONE_PATH,
|
||||
"wiki/character_material": WIKI_MATERIAL_FOR_ROLE,
|
||||
"wiki/relic_set": WIKI_RELIC_PATH,
|
||||
"wiki/character_overview": WIKI_ROLE_PATH,
|
||||
},
|
||||
)
|
||||
return 'sr全部资源下载完成!'
|
||||
return "sr全部资源下载完成!"
|
||||
|
@ -1,3 +1,3 @@
|
||||
from ..starrailuid_config.sr_config import srconfig
|
||||
|
||||
PREFIX = srconfig.get_config('StarRailPrefix').data
|
||||
PREFIX = srconfig.get_config("StarRailPrefix").data
|
||||
|
@ -1,2 +1,2 @@
|
||||
StarRailUID_version = '0.1.0'
|
||||
StarRail_version = '2.4.0'
|
||||
StarRailUID_version = "0.1.0"
|
||||
StarRail_version = "2.4.0"
|
||||
|
103
pyproject.toml
103
pyproject.toml
@ -38,33 +38,37 @@ pytest = "^7.2.0"
|
||||
pytest-asyncio = "^0.20.3"
|
||||
|
||||
[tool.ruff]
|
||||
line-length = 79
|
||||
line-length = 88
|
||||
target-version = "py38"
|
||||
|
||||
[tool.ruff.lint]
|
||||
select = [
|
||||
"E", "W", # pycodestyle
|
||||
"F", # pyflakes
|
||||
"E",
|
||||
"W", # pycodestyle
|
||||
"F", # pyflakes
|
||||
# "I", # isort
|
||||
"RUF", # ruff
|
||||
"TRY", # tryceratops
|
||||
"RUF", # ruff
|
||||
"TRY", # tryceratops
|
||||
"UP",
|
||||
|
||||
# pylint
|
||||
"PLW", # Warning
|
||||
"PLR", # Refactor
|
||||
"PLE", # Error
|
||||
"PLW", # Warning
|
||||
"PLR", # Refactor
|
||||
"PLE", # Error
|
||||
|
||||
"PTH", # flake8-use-pathlib
|
||||
"SLF", # flake8-self
|
||||
"RET", # flake8-return
|
||||
"RSE", # flake8-raise
|
||||
"T20", # flake8-print
|
||||
"PIE", # flake8-pie
|
||||
"ISC", # flake8-implicit-str-concat
|
||||
"C4", # flake8-comprehensions
|
||||
"COM", # flake8-commas
|
||||
"A", # flake8-builtins
|
||||
"B", # flake8-bugbear
|
||||
"ASYNC", # flake8-async
|
||||
"Q", # flake8-quotes
|
||||
"PTH", # flake8-use-pathlib
|
||||
"SLF", # flake8-self
|
||||
"RET", # flake8-return
|
||||
"RSE", # flake8-raise
|
||||
"T20", # flake8-print
|
||||
"PIE", # flake8-pie
|
||||
"ISC", # flake8-implicit-str-concat
|
||||
"C4", # flake8-comprehensions
|
||||
"COM", # flake8-commas
|
||||
"A", # flake8-builtins
|
||||
"B", # flake8-bugbear
|
||||
"ASYNC", # flake8-async
|
||||
"Q", # flake8-quotes
|
||||
]
|
||||
ignore = [
|
||||
"ISC",
|
||||
@ -76,32 +80,19 @@ ignore = [
|
||||
"PLR0915",
|
||||
"PLR0913",
|
||||
"PLR0911",
|
||||
"PLW0603", # Using the global statement
|
||||
"PLW0603", # Using the global statement
|
||||
"TRY002",
|
||||
"TRY003"
|
||||
"TRY003",
|
||||
]
|
||||
exclude = [
|
||||
"gen.py",
|
||||
".ruff_cache"
|
||||
]
|
||||
# Assume Python 3.8
|
||||
target-version = "py38"
|
||||
exclude = ["gen.py", ".ruff_cache"]
|
||||
|
||||
[tool.ruff.flake8-quotes]
|
||||
inline-quotes = "single"
|
||||
|
||||
[tool.ruff.format]
|
||||
quote-style = "single"
|
||||
|
||||
[tool.ruff.isort]
|
||||
[tool.ruff.lint.isort]
|
||||
case-sensitive = true
|
||||
force-sort-within-sections = true
|
||||
extra-standard-library = ["typing_extensions"]
|
||||
#force-wrap-aliases = true
|
||||
combine-as-imports = true
|
||||
order-by-type = true
|
||||
relative-imports-order = "closest-to-furthest"
|
||||
section-order = ["future", "standard-library", "first-party", "local-folder", "third-party"]
|
||||
|
||||
[tool.pdm]
|
||||
[tool.pdm.build]
|
||||
@ -117,36 +108,32 @@ name = "StarRailUID"
|
||||
version = "0.1.0"
|
||||
description = "支持 NoneBot2 & HoshinoBot & ZeroBot & YunzaiBot 的全功能星穹铁道Bot插件"
|
||||
authors = [
|
||||
{name = "qwerdvd", email = "105906879+qwerdvd@users.noreply.github.com"},
|
||||
{ name = "qwerdvd", email = "105906879+qwerdvd@users.noreply.github.com" },
|
||||
]
|
||||
dependencies = [
|
||||
"beautifulsoup4>=4.12.2",
|
||||
"msgspec>=0.18.4",
|
||||
"httpx>=0.25.0",
|
||||
"pillow>=10.1.0",
|
||||
"aiofiles>=23.2.1",
|
||||
"aiohttp>=3.8.6",
|
||||
"qrcode[pil]>=7.4.2",
|
||||
"starrail-damage-cal>=1.2.1",
|
||||
"beautifulsoup4>=4.12.2",
|
||||
"msgspec>=0.18.4",
|
||||
"httpx>=0.25.0",
|
||||
"pillow>=10.1.0",
|
||||
"aiofiles>=23.2.1",
|
||||
"aiohttp>=3.8.6",
|
||||
"qrcode[pil]>=7.4.2",
|
||||
"starrail-damage-cal>=1.2.1",
|
||||
]
|
||||
requires-python = ">=3.8.1,<4.0"
|
||||
readme = "README.md"
|
||||
license = {text = "GPL-3.0-or-later"}
|
||||
license = { text = "GPL-3.0-or-later" }
|
||||
|
||||
|
||||
[tool.pdm.dev-dependencies]
|
||||
dev = [
|
||||
"ruff>=0.0.276",
|
||||
"pre-commit>=3.3.2",
|
||||
"flake8>=6.0.0",
|
||||
"isort>=5.12.0",
|
||||
"pycln>=2.1.2"
|
||||
]
|
||||
test = [
|
||||
"nonebug>=0.3.0",
|
||||
"pytest>=7.2.0",
|
||||
"pytest-asyncio>=0.20.3"
|
||||
"ruff>=0.0.276",
|
||||
"pre-commit>=3.3.2",
|
||||
"flake8>=6.0.0",
|
||||
"isort>=5.12.0",
|
||||
"pycln>=2.1.2",
|
||||
]
|
||||
test = ["nonebug>=0.3.0", "pytest>=7.2.0", "pytest-asyncio>=0.20.3"]
|
||||
|
||||
[build-system]
|
||||
requires = ["pdm-backend"]
|
||||
|
Loading…
x
Reference in New Issue
Block a user