mirror of
https://github.com/baiqwerdvd/StarRailUID.git
synced 2025-05-05 03:03:45 +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,
|
avatar_id: str,
|
||||||
) -> Union[HakushHsrCharacter, None]:
|
) -> Union[HakushHsrCharacter, None]:
|
||||||
async with AsyncClient(
|
async with AsyncClient(
|
||||||
base_url='https://api.hakush.in/hsr/data',
|
base_url="https://api.hakush.in/hsr/data",
|
||||||
headers=_HEADER,
|
headers=_HEADER,
|
||||||
timeout=30,
|
timeout=30,
|
||||||
) as client:
|
) 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:
|
if req.status_code == 200:
|
||||||
return convert(req.json(), type=HakushHsrCharacter)
|
return convert(req.json(), type=HakushHsrCharacter)
|
||||||
return None
|
return None
|
||||||
@ -30,39 +30,35 @@ async def get_lightcone_data(
|
|||||||
lightcone_id: str,
|
lightcone_id: str,
|
||||||
) -> Union[HakushHsrLightcone, None]:
|
) -> Union[HakushHsrLightcone, None]:
|
||||||
async with AsyncClient(
|
async with AsyncClient(
|
||||||
base_url='https://api.hakush.in/hsr/data',
|
base_url="https://api.hakush.in/hsr/data",
|
||||||
headers=_HEADER,
|
headers=_HEADER,
|
||||||
timeout=30,
|
timeout=30,
|
||||||
) as client:
|
) 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:
|
if req.status_code == 200:
|
||||||
return convert(req.json(), type=HakushHsrLightcone)
|
return convert(req.json(), type=HakushHsrLightcone)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
async def get_character_index() -> (
|
async def get_character_index() -> Union[Dict[str, HakushHsrCharacterIndex], None]:
|
||||||
Union[Dict[str, HakushHsrCharacterIndex], None]
|
|
||||||
):
|
|
||||||
async with AsyncClient(
|
async with AsyncClient(
|
||||||
base_url='https://api.hakush.in/hsr/data',
|
base_url="https://api.hakush.in/hsr/data",
|
||||||
headers=_HEADER,
|
headers=_HEADER,
|
||||||
timeout=30,
|
timeout=30,
|
||||||
) as client:
|
) as client:
|
||||||
req = await client.get('/character.json')
|
req = await client.get("/character.json")
|
||||||
if req.status_code == 200:
|
if req.status_code == 200:
|
||||||
return convert(req.json(), type=Dict[str, HakushHsrCharacterIndex])
|
return convert(req.json(), type=Dict[str, HakushHsrCharacterIndex])
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
async def get_lightcone_index() -> (
|
async def get_lightcone_index() -> Union[Dict[str, HakushHsrLightconeIndex], None]:
|
||||||
Union[Dict[str, HakushHsrLightconeIndex], None]
|
|
||||||
):
|
|
||||||
async with AsyncClient(
|
async with AsyncClient(
|
||||||
base_url='https://api.hakush.in/hsr/data',
|
base_url="https://api.hakush.in/hsr/data",
|
||||||
headers=_HEADER,
|
headers=_HEADER,
|
||||||
timeout=30,
|
timeout=30,
|
||||||
) as client:
|
) as client:
|
||||||
req = await client.get('/character.json')
|
req = await client.get("/character.json")
|
||||||
if req.status_code == 200:
|
if req.status_code == 200:
|
||||||
return convert(req.json(), type=Dict[str, HakushHsrLightconeIndex])
|
return convert(req.json(), type=Dict[str, HakushHsrLightconeIndex])
|
||||||
return None
|
return None
|
||||||
|
@ -3,4 +3,4 @@
|
|||||||
from .models import MihomoData as MihomoData
|
from .models import MihomoData as MihomoData
|
||||||
from .requests import get_char_card_info as requests
|
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 def get_char_card_info(uid: str) -> MihomoData:
|
||||||
async with AsyncClient(
|
async with AsyncClient(
|
||||||
base_url='http://api.mihomo.me',
|
base_url="http://api.mihomo.me",
|
||||||
headers=_HEADER,
|
headers=_HEADER,
|
||||||
timeout=30,
|
timeout=30,
|
||||||
) as client:
|
) as client:
|
||||||
req = await client.get(f'/sr_info/{uid}')
|
req = await client.get(f"/sr_info/{uid}")
|
||||||
path = PLAYER_PATH / str(uid)
|
path = PLAYER_PATH / str(uid)
|
||||||
path.mkdir(parents=True, exist_ok=True)
|
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)
|
file.write(req.text)
|
||||||
return convert(req.json(), type=MihomoData)
|
return convert(req.json(), type=MihomoData)
|
||||||
|
@ -1,75 +1,65 @@
|
|||||||
# flake8: noqa
|
# flake8: noqa
|
||||||
OLD_URL = 'https://api-takumi.mihoyo.com'
|
OLD_URL = "https://api-takumi.mihoyo.com"
|
||||||
OS_OLD_URL = 'https://api-os-takumi.mihoyo.com'
|
OS_OLD_URL = "https://api-os-takumi.mihoyo.com"
|
||||||
NEW_URL = 'https://api-takumi-record.mihoyo.com'
|
NEW_URL = "https://api-takumi-record.mihoyo.com"
|
||||||
OS_URL = 'https://sg-public-api.hoyolab.com'
|
OS_URL = "https://sg-public-api.hoyolab.com"
|
||||||
OS_INFO_URL = 'https://bbs-api-os.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 = f"{OLD_URL}/event/luna/info"
|
||||||
STAR_RAIL_SIGN_INFO_URL_OS = f'{OS_URL}/event/luna/os/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 = f"{OLD_URL}/event/luna/home"
|
||||||
STAR_RAIL_SIGN_LIST_URL_OS = f'{OS_URL}/event/luna/os/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_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_EXTRA_REWARD_URL = f"{OLD_URL}/event/luna/extra_reward"
|
||||||
STAR_RAIL_SIGN_URL = f'{OLD_URL}/event/luna/sign'
|
STAR_RAIL_SIGN_URL = f"{OLD_URL}/event/luna/sign"
|
||||||
STAR_RAIL_SIGN_URL_OS = f'{OS_URL}/event/luna/os/sign'
|
STAR_RAIL_SIGN_URL_OS = f"{OS_URL}/event/luna/os/sign"
|
||||||
STAR_RAIL_MONTH_INFO_URL = (
|
STAR_RAIL_MONTH_INFO_URL = f"{OLD_URL}/event/srledger/month_info" # 开拓阅历接口
|
||||||
f'{OLD_URL}/event/srledger/month_info' # 开拓阅历接口
|
|
||||||
)
|
|
||||||
STAR_RAIL_MONTH_DETAIL_URL = (
|
STAR_RAIL_MONTH_DETAIL_URL = (
|
||||||
f'{OLD_URL}/event/srledger/month_detail' # 开拓阅历详情接口
|
f"{OLD_URL}/event/srledger/month_detail" # 开拓阅历详情接口
|
||||||
)
|
)
|
||||||
|
|
||||||
STAR_RAIL_NOTE_URL = (
|
STAR_RAIL_NOTE_URL = f"{NEW_URL}/game_record/app/hkrpg/api/note" # 实时便签接口
|
||||||
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_NOTE_URL_OS = (
|
STAR_RAIL_INDEX_URL_OS = f"{OS_INFO_URL}/game_record/hkrpg/api/index" # 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 = (
|
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 = (
|
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 = (
|
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 = (
|
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_LIST_URL = f"{OLD_URL}/event/rpgcalc/avatar/list"
|
||||||
STAR_RAIL_AVATAR_DETAIL_URL = f'{OLD_URL}/event/rpgcalc/avatar/detail'
|
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 = f"{NEW_URL}/game_record/app/hkrpg/api/challenge" # 忘却之庭
|
||||||
CHALLENGE_INFO_URL_OS = f'{OS_INFO_URL}/game_record/hkrpg/api/challenge' # OS忘却之庭
|
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_STORY_INFO_URL = (
|
||||||
CHALLENGE_BOSS_INFO_URL = f'{NEW_URL}/game_record/app/hkrpg/api/challenge_boss' # 末日幻影
|
f"{NEW_URL}/game_record/app/hkrpg/api/challenge_story" # 虚构叙事
|
||||||
|
|
||||||
ROGUE_INFO_URL = (
|
|
||||||
f'{NEW_URL}/game_record/app/hkrpg/api/rogue' # 角色模拟宇宙信息接口
|
|
||||||
)
|
)
|
||||||
|
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 = (
|
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 = f"{OLD_URL}/common/gacha_record/api/getGachaLog"
|
||||||
STAR_RAIL_GACHA_LOG_URL_OS = (
|
STAR_RAIL_GACHA_LOG_URL_OS = f"{OS_OLD_URL}/common/gacha_record/api/getGachaLog"
|
||||||
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 = "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_OS = "https://sg-public-data-api.hoyoverse.com/device-fp/api/getFp"
|
||||||
# CREATE_QRCODE = f'{OLD_URL}/event/bbs_sign_reward/gen_auth_code'
|
# 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()
|
_API = locals()
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
from gsuid_core.version import __version__
|
from gsuid_core.version import __version__
|
||||||
|
|
||||||
_HEADER = {'User-Agent': f'StarRailUID/{__version__}'}
|
_HEADER = {"User-Agent": f"StarRailUID/{__version__}"}
|
||||||
|
@ -1,45 +1,43 @@
|
|||||||
import re
|
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.bot import Bot
|
||||||
from gsuid_core.models import Event
|
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 gsuid_core.utils.error_reply import UID_HINT
|
||||||
|
|
||||||
from ..utils.convert import get_uid
|
sv_srabyss = SV("sr查询深渊")
|
||||||
from ..utils.sr_prefix import PREFIX
|
|
||||||
from .draw_abyss_card import draw_abyss_img
|
|
||||||
|
|
||||||
sv_srabyss = SV('sr查询深渊')
|
|
||||||
|
|
||||||
|
|
||||||
@sv_srabyss.on_command(
|
@sv_srabyss.on_command(
|
||||||
(
|
(
|
||||||
f'{PREFIX}查询深渊',
|
f"{PREFIX}查询深渊",
|
||||||
f'{PREFIX}查询上期深渊',
|
f"{PREFIX}查询上期深渊",
|
||||||
f'{PREFIX}上期深渊',
|
f"{PREFIX}上期深渊",
|
||||||
f'{PREFIX}深渊',
|
f"{PREFIX}深渊",
|
||||||
),
|
),
|
||||||
block=True,
|
block=True,
|
||||||
)
|
)
|
||||||
async def send_srabyss_info(bot: Bot, ev: Event):
|
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:
|
if name:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
await bot.logger.info('开始执行[sr查询深渊信息]')
|
await bot.logger.info("开始执行[sr查询深渊信息]")
|
||||||
get_uid_ = await get_uid(bot, ev, True)
|
uid, user_id = await get_uid(bot, ev, GsBind, "sr", True)
|
||||||
if get_uid_ is None:
|
|
||||||
return await bot.send(UID_HINT)
|
|
||||||
uid, user_id = get_uid_
|
|
||||||
if uid is None:
|
if uid is None:
|
||||||
return await bot.send(UID_HINT)
|
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:
|
if "上期" in ev.command:
|
||||||
schedule_type = '2'
|
schedule_type = "2"
|
||||||
else:
|
else:
|
||||||
schedule_type = '1'
|
schedule_type = "1"
|
||||||
await bot.logger.info(f'[sr查询深渊信息]深渊期数: {schedule_type}')
|
await bot.logger.info(f"[sr查询深渊信息]深渊期数: {schedule_type}")
|
||||||
|
|
||||||
im = await draw_abyss_img(user_id, uid, ev.sender, schedule_type)
|
im = await draw_abyss_img(user_id, uid, ev.sender, schedule_type)
|
||||||
await bot.send(im)
|
await bot.send(im)
|
||||||
|
@ -1,17 +1,7 @@
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Union, Optional
|
from typing import Any, Dict, 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 import get_icon
|
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 ..sruid_utils.api.mys.models import AbyssAvatar
|
||||||
from ..utils.fonts.starrail_fonts import (
|
from ..utils.fonts.starrail_fonts import (
|
||||||
sr_font_22,
|
sr_font_22,
|
||||||
@ -20,39 +10,41 @@ from ..utils.fonts.starrail_fonts import (
|
|||||||
sr_font_34,
|
sr_font_34,
|
||||||
sr_font_42,
|
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)
|
white_color = (255, 255, 255)
|
||||||
gray_color = (175, 175, 175)
|
gray_color = (175, 175, 175)
|
||||||
img_bg = Image.open(TEXT_PATH / 'bg.jpg')
|
img_bg = Image.open(TEXT_PATH / "bg.jpg")
|
||||||
level_cover = Image.open(TEXT_PATH / 'level_cover.png').convert('RGBA')
|
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_4 = Image.open(TEXT_PATH / "char4_bg.png").convert("RGBA")
|
||||||
char_bg_5 = Image.open(TEXT_PATH / 'char5_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')
|
rank_bg = Image.open(TEXT_PATH / "rank_bg.png").convert("RGBA")
|
||||||
star_yes = Image.open(TEXT_PATH / 'star.png').convert('RGBA')
|
star_yes = Image.open(TEXT_PATH / "star.png").convert("RGBA")
|
||||||
star_gray = Image.open(TEXT_PATH / 'star_gray.png').convert('RGBA')
|
star_gray = Image.open(TEXT_PATH / "star_gray.png").convert("RGBA")
|
||||||
|
|
||||||
elements = {
|
elements = {
|
||||||
'ice': Image.open(TEXT_PATH / 'IconNatureColorIce.png').convert('RGBA'),
|
"ice": Image.open(TEXT_PATH / "IconNatureColorIce.png").convert("RGBA"),
|
||||||
'fire': Image.open(TEXT_PATH / 'IconNatureColorFire.png').convert('RGBA'),
|
"fire": Image.open(TEXT_PATH / "IconNatureColorFire.png").convert("RGBA"),
|
||||||
'imaginary': Image.open(
|
"imaginary": Image.open(TEXT_PATH / "IconNatureColorImaginary.png").convert("RGBA"),
|
||||||
TEXT_PATH / 'IconNatureColorImaginary.png'
|
"quantum": Image.open(TEXT_PATH / "IconNatureColorQuantum.png").convert("RGBA"),
|
||||||
).convert('RGBA'),
|
"lightning": Image.open(TEXT_PATH / "IconNatureColorThunder.png").convert("RGBA"),
|
||||||
'quantum': Image.open(TEXT_PATH / 'IconNatureColorQuantum.png').convert(
|
"wind": Image.open(TEXT_PATH / "IconNatureColorWind.png").convert("RGBA"),
|
||||||
'RGBA'
|
"physical": Image.open(TEXT_PATH / "IconNaturePhysical.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:
|
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(
|
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_bg.paste(rank_bg, (150, 16), mask=rank_bg)
|
||||||
char_card_draw.text(
|
char_card_draw.text(
|
||||||
(162, 31),
|
(162, 31),
|
||||||
f'{char.rank}',
|
f"{char.rank}",
|
||||||
font=sr_font_22,
|
font=sr_font_22,
|
||||||
fill=white_color,
|
fill=white_color,
|
||||||
anchor='mm',
|
anchor="mm",
|
||||||
)
|
)
|
||||||
char_card_draw.text(
|
char_card_draw.text(
|
||||||
(100, 165),
|
(100, 165),
|
||||||
f'等级 {char.level}',
|
f"等级 {char.level}",
|
||||||
font=sr_font_22,
|
font=sr_font_22,
|
||||||
fill=white_color,
|
fill=white_color,
|
||||||
anchor='mm',
|
anchor="mm",
|
||||||
)
|
)
|
||||||
floor_pic.paste(
|
floor_pic.paste(
|
||||||
char_bg,
|
char_bg,
|
||||||
@ -92,16 +84,16 @@ async def _draw_abyss_card(
|
|||||||
|
|
||||||
|
|
||||||
async def _draw_floor_card(
|
async def _draw_floor_card(
|
||||||
level_star: int,
|
level_star: Union[int, str],
|
||||||
floor_pic: Image.Image,
|
floor_pic: Image.Image,
|
||||||
img: Image.Image,
|
img: Image.Image,
|
||||||
index_floor: int,
|
index_floor: int,
|
||||||
floor_name: str,
|
floor_name: str,
|
||||||
round_num: int,
|
round_num: Union[int, None],
|
||||||
):
|
):
|
||||||
for index_num in [0, 1, 2]:
|
for index_num in [0, 1, 2]:
|
||||||
star_num = index_num + 1
|
star_num = index_num + 1
|
||||||
if star_num <= level_star:
|
if star_num <= int(level_star):
|
||||||
star_pic = star_yes.copy()
|
star_pic = star_yes.copy()
|
||||||
else:
|
else:
|
||||||
star_pic = star_gray.copy()
|
star_pic = star_gray.copy()
|
||||||
@ -112,14 +104,14 @@ async def _draw_floor_card(
|
|||||||
floor_name,
|
floor_name,
|
||||||
font=sr_font_42,
|
font=sr_font_42,
|
||||||
fill=white_color,
|
fill=white_color,
|
||||||
anchor='mm',
|
anchor="mm",
|
||||||
)
|
)
|
||||||
floor_pic_draw.text(
|
floor_pic_draw.text(
|
||||||
(802, 60),
|
(802, 60),
|
||||||
f'使用轮: {round_num}',
|
f"使用轮: {round_num}",
|
||||||
font=sr_font_28,
|
font=sr_font_28,
|
||||||
fill=gray_color,
|
fill=gray_color,
|
||||||
anchor='rm',
|
anchor="rm",
|
||||||
)
|
)
|
||||||
img.paste(floor_pic, (0, 657 + index_floor * 570), floor_pic)
|
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(
|
async def draw_abyss_img(
|
||||||
qid: Union[str, int],
|
qid: Union[str, int],
|
||||||
uid: str,
|
uid: str,
|
||||||
sender: Union[str, str],
|
sender: Dict[str, Any],
|
||||||
schedule_type: str = '1',
|
schedule_type: str = "1",
|
||||||
) -> Union[bytes, str]:
|
) -> Union[bytes, str]:
|
||||||
raw_abyss_data = await mys_api.get_abyss_info(uid, schedule_type)
|
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)
|
return get_error(raw_abyss_data)
|
||||||
|
|
||||||
# 获取查询者数据
|
# 获取查询者数据
|
||||||
if raw_abyss_data.max_floor == '':
|
if raw_abyss_data.max_floor == "":
|
||||||
return '你还没有挑战本期深渊!\n可以使用[sr上期深渊]命令查询上期~'
|
return "你还没有挑战本期深渊!\n可以使用[sr上期深渊]命令查询上期~"
|
||||||
# 过滤掉 is_fast(快速通关) 为 True 的项
|
# 过滤掉 is_fast (快速通关) 为 True 的项
|
||||||
floor_detail = [detail for detail in raw_abyss_data.all_floor_detail if not detail.is_fast]
|
floor_detail = [
|
||||||
|
detail for detail in raw_abyss_data.all_floor_detail if not detail.is_fast
|
||||||
|
]
|
||||||
floor_num = len(floor_detail)
|
floor_num = len(floor_detail)
|
||||||
|
|
||||||
# 获取背景图片各项参数
|
# 获取背景图片各项参数
|
||||||
@ -147,15 +141,15 @@ async def draw_abyss_img(
|
|||||||
based_h = 657 + 570 * floor_num
|
based_h = 657 + 570 * floor_num
|
||||||
img = img_bg.copy()
|
img = img_bg.copy()
|
||||||
img = img.crop((0, 0, based_w, based_h))
|
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)
|
img.paste(abyss_title, (0, 0), abyss_title)
|
||||||
|
|
||||||
# 获取头像
|
# 获取头像
|
||||||
_id = str(qid)
|
_id = str(qid)
|
||||||
if _id.startswith('http'):
|
if _id.startswith("http"):
|
||||||
char_pic = await get_qq_avatar(avatar_url=_id)
|
char_pic = await get_qq_avatar(avatar_url=_id)
|
||||||
elif sender.get('avatar') is not None:
|
elif sender.get("avatar") is not None:
|
||||||
char_pic = await get_qq_avatar(avatar_url=sender['avatar'])
|
char_pic = await get_qq_avatar(avatar_url=sender["avatar"])
|
||||||
else:
|
else:
|
||||||
char_pic = await get_qq_avatar(qid=qid)
|
char_pic = await get_qq_avatar(qid=qid)
|
||||||
char_pic = await draw_pic_with_ring(char_pic, 250, None, False)
|
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 = 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.paste(abyss_data, (0, 500), abyss_data)
|
||||||
|
|
||||||
# 最深抵达
|
# 最深抵达
|
||||||
img_draw.text(
|
img_draw.text(
|
||||||
(220, 565),
|
(220, 565),
|
||||||
f'{raw_abyss_data.max_floor}',
|
f"{raw_abyss_data.max_floor}",
|
||||||
white_color,
|
white_color,
|
||||||
sr_font_34,
|
sr_font_34,
|
||||||
'lm',
|
"lm",
|
||||||
)
|
)
|
||||||
# 挑战次数
|
# 挑战次数
|
||||||
img_draw.text(
|
img_draw.text(
|
||||||
(220, 612),
|
(220, 612),
|
||||||
f'{raw_abyss_data.battle_num}',
|
f"{raw_abyss_data.battle_num}",
|
||||||
white_color,
|
white_color,
|
||||||
sr_font_34,
|
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.paste(star_num_pic, (615, 557), star_num_pic)
|
||||||
|
|
||||||
img_draw.text(
|
img_draw.text(
|
||||||
(695, 590),
|
(695, 590),
|
||||||
f'{raw_abyss_data.star_num}/36',
|
f"{raw_abyss_data.star_num}/36",
|
||||||
white_color,
|
white_color,
|
||||||
sr_font_42,
|
sr_font_42,
|
||||||
'lm',
|
"lm",
|
||||||
)
|
)
|
||||||
|
|
||||||
for index_floor, level in enumerate(raw_abyss_data.all_floor_detail):
|
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
|
level_star = level.star_num
|
||||||
floor_name = level.name
|
floor_name = level.name
|
||||||
round_num = level.round_num
|
round_num = level.round_num
|
||||||
@ -211,23 +205,24 @@ async def draw_abyss_img(
|
|||||||
time_array = node_1.challenge_time
|
time_array = node_1.challenge_time
|
||||||
else:
|
else:
|
||||||
time_array = node_2.challenge_time
|
time_array = node_2.challenge_time
|
||||||
time_str = f'{time_array.year}-{time_array.month}'
|
assert time_array is not None
|
||||||
time_str = f'{time_str}-{time_array.day}'
|
time_str = f"{time_array.year}-{time_array.month}"
|
||||||
time_str = f'{time_str} {time_array.hour}:{time_array.minute}:00'
|
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 = ImageDraw.Draw(floor_pic)
|
||||||
floor_pic_draw.text(
|
floor_pic_draw.text(
|
||||||
(112, 120 + index_part * 219),
|
(112, 120 + index_part * 219),
|
||||||
f'节点{node_num}',
|
f"节点{node_num}",
|
||||||
white_color,
|
white_color,
|
||||||
sr_font_30,
|
sr_font_30,
|
||||||
'lm',
|
"lm",
|
||||||
)
|
)
|
||||||
floor_pic_draw.text(
|
floor_pic_draw.text(
|
||||||
(201, 120 + index_part * 219),
|
(201, 120 + index_part * 219),
|
||||||
f'{time_str}',
|
f"{time_str}",
|
||||||
gray_color,
|
gray_color,
|
||||||
sr_font_22,
|
sr_font_22,
|
||||||
'lm',
|
"lm",
|
||||||
)
|
)
|
||||||
if node_num == 1:
|
if node_num == 1:
|
||||||
avatars_array = node_1
|
avatars_array = node_1
|
||||||
@ -251,5 +246,5 @@ async def draw_abyss_img(
|
|||||||
)
|
)
|
||||||
|
|
||||||
res = await convert_img(img)
|
res = await convert_img(img)
|
||||||
logger.info('[查询深渊信息]绘图已完成,等待发送!')
|
logger.info("[查询深渊信息]绘图已完成,等待发送!")
|
||||||
return res
|
return res
|
||||||
|
@ -6,14 +6,14 @@ from PIL import Image
|
|||||||
from aiohttp import ClientSession
|
from aiohttp import ClientSession
|
||||||
from gsuid_core.data_store import get_res_path
|
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)
|
ROLEINFO_PATH.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
|
||||||
async def get_icon(url: str) -> Image.Image:
|
async def get_icon(url: str) -> Image.Image:
|
||||||
name = url.split('/')[-1]
|
name = url.split("/")[-1]
|
||||||
path = ROLEINFO_PATH / name
|
path = ROLEINFO_PATH / name
|
||||||
if (path).exists():
|
if (path).exists():
|
||||||
content = path.read_bytes()
|
content = path.read_bytes()
|
||||||
@ -21,6 +21,6 @@ async def get_icon(url: str) -> Image.Image:
|
|||||||
async with ClientSession() as client:
|
async with ClientSession() as client:
|
||||||
async with client.get(url) as resp:
|
async with client.get(url) as resp:
|
||||||
content = await resp.read()
|
content = await resp.read()
|
||||||
with Path.open(path, 'wb') as f:
|
with Path.open(path, "wb") as f:
|
||||||
f.write(content)
|
f.write(content)
|
||||||
return Image.open(BytesIO(content)).convert('RGBA')
|
return Image.open(BytesIO(content)).convert("RGBA")
|
||||||
|
@ -1,45 +1,43 @@
|
|||||||
import re
|
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.bot import Bot
|
||||||
from gsuid_core.models import Event
|
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 gsuid_core.utils.error_reply import UID_HINT
|
||||||
|
|
||||||
from ..utils.convert import get_uid
|
sv_abyss_boss = SV("sr查询末日幻影")
|
||||||
from ..utils.sr_prefix import PREFIX
|
|
||||||
from .draw_abyss_card import draw_abyss_img
|
|
||||||
|
|
||||||
sv_abyss_boss = SV('sr查询末日幻影')
|
|
||||||
|
|
||||||
|
|
||||||
@sv_abyss_boss.on_command(
|
@sv_abyss_boss.on_command(
|
||||||
(
|
(
|
||||||
f'{PREFIX}查询末日幻影',
|
f"{PREFIX}查询末日幻影",
|
||||||
f'{PREFIX}查询上期末日幻影',
|
f"{PREFIX}查询上期末日幻影",
|
||||||
f'{PREFIX}上期末日',
|
f"{PREFIX}上期末日",
|
||||||
f'{PREFIX}末日',
|
f"{PREFIX}末日",
|
||||||
),
|
),
|
||||||
block=True,
|
block=True,
|
||||||
)
|
)
|
||||||
async def send_srabyss_info(bot: Bot, ev: Event):
|
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:
|
if name:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
await bot.logger.info('开始执行[sr查询末日幻影信息]')
|
await bot.logger.info("开始执行[sr查询末日幻影信息]")
|
||||||
get_uid_ = await get_uid(bot, ev, True)
|
uid, user_id = await get_uid(bot, ev, GsBind, "sr", True)
|
||||||
if get_uid_ is None:
|
|
||||||
return await bot.send(UID_HINT)
|
|
||||||
uid, user_id = get_uid_
|
|
||||||
if uid is None:
|
if uid is None:
|
||||||
return await bot.send(UID_HINT)
|
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:
|
if "上期" in ev.command:
|
||||||
schedule_type = '2'
|
schedule_type = "2"
|
||||||
else:
|
else:
|
||||||
schedule_type = '1'
|
schedule_type = "1"
|
||||||
await bot.logger.info(f'[sr查询末日幻影信息]末日幻影期数: {schedule_type}')
|
await bot.logger.info(f"[sr查询末日幻影信息]末日幻影期数: {schedule_type}")
|
||||||
|
|
||||||
im = await draw_abyss_img(user_id, uid, ev.sender, schedule_type)
|
im = await draw_abyss_img(user_id, uid, ev.sender, schedule_type)
|
||||||
await bot.send(im)
|
await bot.send(im)
|
||||||
|
@ -1,17 +1,7 @@
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Union, Optional
|
from typing import Any, Dict, 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 import get_icon
|
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 ..sruid_utils.api.mys.models import AbyssAvatar
|
||||||
from ..utils.fonts.starrail_fonts import (
|
from ..utils.fonts.starrail_fonts import (
|
||||||
sr_font_22,
|
sr_font_22,
|
||||||
@ -20,39 +10,41 @@ from ..utils.fonts.starrail_fonts import (
|
|||||||
sr_font_34,
|
sr_font_34,
|
||||||
sr_font_42,
|
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)
|
white_color = (255, 255, 255)
|
||||||
gray_color = (175, 175, 175)
|
gray_color = (175, 175, 175)
|
||||||
img_bg = Image.open(TEXT_PATH / 'bg.jpg')
|
img_bg = Image.open(TEXT_PATH / "bg.jpg")
|
||||||
level_cover = Image.open(TEXT_PATH / 'level_cover.png').convert('RGBA')
|
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_4 = Image.open(TEXT_PATH / "char4_bg.png").convert("RGBA")
|
||||||
char_bg_5 = Image.open(TEXT_PATH / 'char5_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')
|
rank_bg = Image.open(TEXT_PATH / "rank_bg.png").convert("RGBA")
|
||||||
star_yes = Image.open(TEXT_PATH / 'star.png').convert('RGBA')
|
star_yes = Image.open(TEXT_PATH / "star.png").convert("RGBA")
|
||||||
star_gray = Image.open(TEXT_PATH / 'star_gray.png').convert('RGBA')
|
star_gray = Image.open(TEXT_PATH / "star_gray.png").convert("RGBA")
|
||||||
|
|
||||||
elements = {
|
elements = {
|
||||||
'ice': Image.open(TEXT_PATH / 'IconNatureColorIce.png').convert('RGBA'),
|
"ice": Image.open(TEXT_PATH / "IconNatureColorIce.png").convert("RGBA"),
|
||||||
'fire': Image.open(TEXT_PATH / 'IconNatureColorFire.png').convert('RGBA'),
|
"fire": Image.open(TEXT_PATH / "IconNatureColorFire.png").convert("RGBA"),
|
||||||
'imaginary': Image.open(
|
"imaginary": Image.open(TEXT_PATH / "IconNatureColorImaginary.png").convert("RGBA"),
|
||||||
TEXT_PATH / 'IconNatureColorImaginary.png'
|
"quantum": Image.open(TEXT_PATH / "IconNatureColorQuantum.png").convert("RGBA"),
|
||||||
).convert('RGBA'),
|
"lightning": Image.open(TEXT_PATH / "IconNatureColorThunder.png").convert("RGBA"),
|
||||||
'quantum': Image.open(TEXT_PATH / 'IconNatureColorQuantum.png').convert(
|
"wind": Image.open(TEXT_PATH / "IconNatureColorWind.png").convert("RGBA"),
|
||||||
'RGBA'
|
"physical": Image.open(TEXT_PATH / "IconNaturePhysical.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:
|
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(
|
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_bg.paste(rank_bg, (150, 16), mask=rank_bg)
|
||||||
char_card_draw.text(
|
char_card_draw.text(
|
||||||
(162, 31),
|
(162, 31),
|
||||||
f'{char.rank}',
|
f"{char.rank}",
|
||||||
font=sr_font_22,
|
font=sr_font_22,
|
||||||
fill=white_color,
|
fill=white_color,
|
||||||
anchor='mm',
|
anchor="mm",
|
||||||
)
|
)
|
||||||
char_card_draw.text(
|
char_card_draw.text(
|
||||||
(100, 165),
|
(100, 165),
|
||||||
f'等级 {char.level}',
|
f"等级 {char.level}",
|
||||||
font=sr_font_22,
|
font=sr_font_22,
|
||||||
fill=white_color,
|
fill=white_color,
|
||||||
anchor='mm',
|
anchor="mm",
|
||||||
)
|
)
|
||||||
floor_pic.paste(
|
floor_pic.paste(
|
||||||
char_bg,
|
char_bg,
|
||||||
@ -114,7 +106,7 @@ async def _draw_floor_card(
|
|||||||
floor_name,
|
floor_name,
|
||||||
font=sr_font_42,
|
font=sr_font_42,
|
||||||
fill=white_color,
|
fill=white_color,
|
||||||
anchor='mm',
|
anchor="mm",
|
||||||
)
|
)
|
||||||
img.paste(floor_pic, (0, 657 + index_floor * 570), floor_pic)
|
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(
|
async def draw_abyss_img(
|
||||||
qid: Union[str, int],
|
qid: Union[str, int],
|
||||||
uid: str,
|
uid: str,
|
||||||
sender: Union[str, str],
|
sender: Dict[str, Any],
|
||||||
schedule_type: str = '1',
|
schedule_type: str = "1",
|
||||||
) -> Union[bytes, str]:
|
) -> Union[bytes, str]:
|
||||||
raw_abyss_data = await mys_api.get_abyss_boss_info(uid, schedule_type)
|
raw_abyss_data = await mys_api.get_abyss_boss_info(uid, schedule_type)
|
||||||
if isinstance(raw_abyss_data, int):
|
if isinstance(raw_abyss_data, int):
|
||||||
return get_error(raw_abyss_data)
|
return get_error(raw_abyss_data)
|
||||||
|
|
||||||
# 获取查询者数据
|
# 获取查询者数据
|
||||||
if raw_abyss_data.max_floor == '':
|
if raw_abyss_data.max_floor == "":
|
||||||
return '你还没有挑战本期末日幻影!\n可以使用[sr上期末日幻影]命令查询上期~'
|
return "你还没有挑战本期末日幻影!\n可以使用[sr上期末日幻影]命令查询上期~"
|
||||||
# 过滤掉 is_fast(快速通关) 为 True 的项
|
# 过滤掉 is_fast (快速通关) 为 True 的项
|
||||||
floor_detail = [detail for detail in raw_abyss_data.all_floor_detail if not detail.is_fast]
|
floor_detail = [
|
||||||
|
detail for detail in raw_abyss_data.all_floor_detail if not detail.is_fast
|
||||||
|
]
|
||||||
floor_num = len(floor_detail)
|
floor_num = len(floor_detail)
|
||||||
|
|
||||||
# 获取背景图片各项参数
|
# 获取背景图片各项参数
|
||||||
@ -141,15 +135,15 @@ async def draw_abyss_img(
|
|||||||
based_h = 657 + 570 * floor_num
|
based_h = 657 + 570 * floor_num
|
||||||
img = img_bg.copy()
|
img = img_bg.copy()
|
||||||
img = img.crop((0, 0, based_w, based_h))
|
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)
|
img.paste(abyss_title, (0, 0), abyss_title)
|
||||||
|
|
||||||
# 获取头像
|
# 获取头像
|
||||||
_id = str(qid)
|
_id = str(qid)
|
||||||
if _id.startswith('http'):
|
if _id.startswith("http"):
|
||||||
char_pic = await get_qq_avatar(avatar_url=_id)
|
char_pic = await get_qq_avatar(avatar_url=_id)
|
||||||
elif sender.get('avatar') is not None:
|
elif sender.get("avatar") is not None:
|
||||||
char_pic = await get_qq_avatar(avatar_url=sender['avatar'])
|
char_pic = await get_qq_avatar(avatar_url=sender["avatar"])
|
||||||
else:
|
else:
|
||||||
char_pic = await get_qq_avatar(qid=qid)
|
char_pic = await get_qq_avatar(qid=qid)
|
||||||
char_pic = await draw_pic_with_ring(char_pic, 250, None, False)
|
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 = 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.paste(abyss_data, (0, 500), abyss_data)
|
||||||
|
|
||||||
# 最深抵达
|
# 最深抵达
|
||||||
img_draw.text(
|
img_draw.text(
|
||||||
(220, 565),
|
(220, 565),
|
||||||
f'{raw_abyss_data.max_floor}',
|
f"{raw_abyss_data.max_floor}",
|
||||||
white_color,
|
white_color,
|
||||||
sr_font_34,
|
sr_font_34,
|
||||||
'lm',
|
"lm",
|
||||||
)
|
)
|
||||||
# 挑战次数
|
# 挑战次数
|
||||||
img_draw.text(
|
img_draw.text(
|
||||||
(220, 612),
|
(220, 612),
|
||||||
f'{raw_abyss_data.battle_num}',
|
f"{raw_abyss_data.battle_num}",
|
||||||
white_color,
|
white_color,
|
||||||
sr_font_34,
|
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.paste(star_num_pic, (615, 557), star_num_pic)
|
||||||
|
|
||||||
img_draw.text(
|
img_draw.text(
|
||||||
(695, 590),
|
(695, 590),
|
||||||
f'{raw_abyss_data.star_num}/12',
|
f"{raw_abyss_data.star_num}/12",
|
||||||
white_color,
|
white_color,
|
||||||
sr_font_42,
|
sr_font_42,
|
||||||
'lm',
|
"lm",
|
||||||
)
|
)
|
||||||
|
|
||||||
for index_floor, level in enumerate(floor_detail):
|
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)
|
level_star = int(level.star_num)
|
||||||
floor_name = level.name
|
floor_name = level.name
|
||||||
node_1 = level.node_1
|
node_1 = level.node_1
|
||||||
@ -204,23 +198,24 @@ async def draw_abyss_img(
|
|||||||
time_array = node_1.challenge_time
|
time_array = node_1.challenge_time
|
||||||
else:
|
else:
|
||||||
time_array = node_2.challenge_time
|
time_array = node_2.challenge_time
|
||||||
time_str = f'{time_array.year}-{time_array.month}'
|
assert time_array is not None
|
||||||
time_str = f'{time_str}-{time_array.day}'
|
time_str = f"{time_array.year}-{time_array.month}"
|
||||||
time_str = f'{time_str} {time_array.hour}:{time_array.minute}:00'
|
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 = ImageDraw.Draw(floor_pic)
|
||||||
floor_pic_draw.text(
|
floor_pic_draw.text(
|
||||||
(112, 120 + index_part * 219),
|
(112, 120 + index_part * 219),
|
||||||
f'节点{node_num}',
|
f"节点{node_num}",
|
||||||
white_color,
|
white_color,
|
||||||
sr_font_30,
|
sr_font_30,
|
||||||
'lm',
|
"lm",
|
||||||
)
|
)
|
||||||
floor_pic_draw.text(
|
floor_pic_draw.text(
|
||||||
(201, 120 + index_part * 219),
|
(201, 120 + index_part * 219),
|
||||||
f'{time_str}',
|
f"{time_str}",
|
||||||
gray_color,
|
gray_color,
|
||||||
sr_font_22,
|
sr_font_22,
|
||||||
'lm',
|
"lm",
|
||||||
)
|
)
|
||||||
if node_num == 1:
|
if node_num == 1:
|
||||||
avatars_array = node_1
|
avatars_array = node_1
|
||||||
@ -240,9 +235,8 @@ async def draw_abyss_img(
|
|||||||
img,
|
img,
|
||||||
index_floor,
|
index_floor,
|
||||||
floor_name,
|
floor_name,
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
res = await convert_img(img)
|
res = await convert_img(img)
|
||||||
logger.info('[查询末日幻影信息]绘图已完成,等待发送!')
|
logger.info("[查询末日幻影信息]绘图已完成,等待发送!")
|
||||||
return res
|
return res
|
||||||
|
@ -6,14 +6,14 @@ from PIL import Image
|
|||||||
from aiohttp import ClientSession
|
from aiohttp import ClientSession
|
||||||
from gsuid_core.data_store import get_res_path
|
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)
|
ROLEINFO_PATH.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
|
||||||
async def get_icon(url: str) -> Image.Image:
|
async def get_icon(url: str) -> Image.Image:
|
||||||
name = url.split('/')[-1]
|
name = url.split("/")[-1]
|
||||||
path = ROLEINFO_PATH / name
|
path = ROLEINFO_PATH / name
|
||||||
if (path).exists():
|
if (path).exists():
|
||||||
content = path.read_bytes()
|
content = path.read_bytes()
|
||||||
@ -21,6 +21,6 @@ async def get_icon(url: str) -> Image.Image:
|
|||||||
async with ClientSession() as client:
|
async with ClientSession() as client:
|
||||||
async with client.get(url) as resp:
|
async with client.get(url) as resp:
|
||||||
content = await resp.read()
|
content = await resp.read()
|
||||||
with Path.open(path, 'wb') as f:
|
with Path.open(path, "wb") as f:
|
||||||
f.write(content)
|
f.write(content)
|
||||||
return Image.open(BytesIO(content)).convert('RGBA')
|
return Image.open(BytesIO(content)).convert("RGBA")
|
||||||
|
@ -1,47 +1,45 @@
|
|||||||
import re
|
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.bot import Bot
|
||||||
from gsuid_core.models import Event
|
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 gsuid_core.utils.error_reply import UID_HINT
|
||||||
|
|
||||||
from ..utils.convert import get_uid
|
sv_abyss_story = SV("sr查询虚构叙事")
|
||||||
from ..utils.sr_prefix import PREFIX
|
|
||||||
from .draw_abyss_card import draw_abyss_img
|
|
||||||
|
|
||||||
sv_abyss_story = SV('sr查询虚构叙事')
|
|
||||||
|
|
||||||
|
|
||||||
@sv_abyss_story.on_command(
|
@sv_abyss_story.on_command(
|
||||||
(
|
(
|
||||||
f'{PREFIX}查询虚构叙事',
|
f"{PREFIX}查询虚构叙事",
|
||||||
f'{PREFIX}xg',
|
f"{PREFIX}xg",
|
||||||
f'{PREFIX}查询上期虚构叙事',
|
f"{PREFIX}查询上期虚构叙事",
|
||||||
f'{PREFIX}sqxg',
|
f"{PREFIX}sqxg",
|
||||||
f'{PREFIX}上期虚构',
|
f"{PREFIX}上期虚构",
|
||||||
f'{PREFIX}虚构',
|
f"{PREFIX}虚构",
|
||||||
),
|
),
|
||||||
block=True,
|
block=True,
|
||||||
)
|
)
|
||||||
async def send_srabyss_info(bot: Bot, ev: Event):
|
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:
|
if name:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
await bot.logger.info('开始执行[sr查询虚构叙事信息]')
|
await bot.logger.info("开始执行[sr查询虚构叙事信息]")
|
||||||
get_uid_ = await get_uid(bot, ev, True)
|
uid, user_id = await get_uid(bot, ev, GsBind, "sr", True)
|
||||||
if get_uid_ is None:
|
|
||||||
return await bot.send(UID_HINT)
|
|
||||||
uid, user_id = get_uid_
|
|
||||||
if uid is None:
|
if uid is None:
|
||||||
return await bot.send(UID_HINT)
|
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:
|
if "sq" in ev.command or "上期" in ev.command:
|
||||||
schedule_type = '2'
|
schedule_type = "2"
|
||||||
else:
|
else:
|
||||||
schedule_type = '1'
|
schedule_type = "1"
|
||||||
await bot.logger.info(f'[sr查询虚构叙事信息]虚构叙事期数: {schedule_type}')
|
await bot.logger.info(f"[sr查询虚构叙事信息]虚构叙事期数: {schedule_type}")
|
||||||
|
|
||||||
im = await draw_abyss_img(user_id, uid, ev.sender, schedule_type)
|
im = await draw_abyss_img(user_id, uid, ev.sender, schedule_type)
|
||||||
await bot.send(im)
|
await bot.send(im)
|
||||||
|
@ -1,17 +1,7 @@
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Union, Optional
|
from typing import Any, Dict, 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 import get_icon
|
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 ..sruid_utils.api.mys.models import AbyssAvatar
|
||||||
from ..utils.fonts.starrail_fonts import (
|
from ..utils.fonts.starrail_fonts import (
|
||||||
sr_font_22,
|
sr_font_22,
|
||||||
@ -20,39 +10,41 @@ from ..utils.fonts.starrail_fonts import (
|
|||||||
sr_font_34,
|
sr_font_34,
|
||||||
sr_font_42,
|
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)
|
white_color = (255, 255, 255)
|
||||||
gray_color = (175, 175, 175)
|
gray_color = (175, 175, 175)
|
||||||
img_bg = Image.open(TEXT_PATH / 'bg.jpg')
|
img_bg = Image.open(TEXT_PATH / "bg.jpg")
|
||||||
level_cover = Image.open(TEXT_PATH / 'level_cover.png').convert('RGBA')
|
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_4 = Image.open(TEXT_PATH / "char4_bg.png").convert("RGBA")
|
||||||
char_bg_5 = Image.open(TEXT_PATH / 'char5_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')
|
rank_bg = Image.open(TEXT_PATH / "rank_bg.png").convert("RGBA")
|
||||||
star_yes = Image.open(TEXT_PATH / 'star.png').convert('RGBA')
|
star_yes = Image.open(TEXT_PATH / "star.png").convert("RGBA")
|
||||||
star_gray = Image.open(TEXT_PATH / 'star_gray.png').convert('RGBA')
|
star_gray = Image.open(TEXT_PATH / "star_gray.png").convert("RGBA")
|
||||||
|
|
||||||
elements = {
|
elements = {
|
||||||
'ice': Image.open(TEXT_PATH / 'IconNatureColorIce.png').convert('RGBA'),
|
"ice": Image.open(TEXT_PATH / "IconNatureColorIce.png").convert("RGBA"),
|
||||||
'fire': Image.open(TEXT_PATH / 'IconNatureColorFire.png').convert('RGBA'),
|
"fire": Image.open(TEXT_PATH / "IconNatureColorFire.png").convert("RGBA"),
|
||||||
'imaginary': Image.open(
|
"imaginary": Image.open(TEXT_PATH / "IconNatureColorImaginary.png").convert("RGBA"),
|
||||||
TEXT_PATH / 'IconNatureColorImaginary.png'
|
"quantum": Image.open(TEXT_PATH / "IconNatureColorQuantum.png").convert("RGBA"),
|
||||||
).convert('RGBA'),
|
"lightning": Image.open(TEXT_PATH / "IconNatureColorThunder.png").convert("RGBA"),
|
||||||
'quantum': Image.open(TEXT_PATH / 'IconNatureColorQuantum.png').convert(
|
"wind": Image.open(TEXT_PATH / "IconNatureColorWind.png").convert("RGBA"),
|
||||||
'RGBA'
|
"physical": Image.open(TEXT_PATH / "IconNaturePhysical.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:
|
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(
|
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_bg.paste(rank_bg, (150, 16), mask=rank_bg)
|
||||||
char_card_draw.text(
|
char_card_draw.text(
|
||||||
(162, 31),
|
(162, 31),
|
||||||
f'{char.rank}',
|
f"{char.rank}",
|
||||||
font=sr_font_22,
|
font=sr_font_22,
|
||||||
fill=white_color,
|
fill=white_color,
|
||||||
anchor='mm',
|
anchor="mm",
|
||||||
)
|
)
|
||||||
# 不存在自动下载
|
# 不存在自动下载
|
||||||
# if not char_pic_path.exists():
|
# 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.paste(talent_pic, (137, 260), talent_pic)
|
||||||
char_card_draw.text(
|
char_card_draw.text(
|
||||||
(100, 165),
|
(100, 165),
|
||||||
f'等级 {char.level}',
|
f"等级 {char.level}",
|
||||||
font=sr_font_22,
|
font=sr_font_22,
|
||||||
fill=white_color,
|
fill=white_color,
|
||||||
anchor='mm',
|
anchor="mm",
|
||||||
)
|
)
|
||||||
floor_pic.paste(
|
floor_pic.paste(
|
||||||
char_bg,
|
char_bg,
|
||||||
@ -102,16 +94,16 @@ async def _draw_abyss_card(
|
|||||||
|
|
||||||
|
|
||||||
async def _draw_floor_card(
|
async def _draw_floor_card(
|
||||||
level_star: int,
|
level_star: Union[int, str],
|
||||||
floor_pic: Image.Image,
|
floor_pic: Image.Image,
|
||||||
img: Image.Image,
|
img: Image.Image,
|
||||||
index_floor: int,
|
index_floor: int,
|
||||||
floor_name: str,
|
floor_name: str,
|
||||||
round_num: int,
|
round_num: Union[int, None],
|
||||||
):
|
):
|
||||||
for index_num in [0, 1, 2]:
|
for index_num in [0, 1, 2]:
|
||||||
star_num = index_num + 1
|
star_num = index_num + 1
|
||||||
if star_num <= level_star:
|
if star_num <= int(level_star):
|
||||||
star_pic = star_yes.copy()
|
star_pic = star_yes.copy()
|
||||||
else:
|
else:
|
||||||
star_pic = star_gray.copy()
|
star_pic = star_gray.copy()
|
||||||
@ -122,14 +114,14 @@ async def _draw_floor_card(
|
|||||||
floor_name,
|
floor_name,
|
||||||
font=sr_font_42,
|
font=sr_font_42,
|
||||||
fill=white_color,
|
fill=white_color,
|
||||||
anchor='mm',
|
anchor="mm",
|
||||||
)
|
)
|
||||||
floor_pic_draw.text(
|
floor_pic_draw.text(
|
||||||
(802, 60),
|
(802, 60),
|
||||||
f'使用轮: {round_num}',
|
f"使用轮: {round_num}",
|
||||||
font=sr_font_28,
|
font=sr_font_28,
|
||||||
fill=gray_color,
|
fill=gray_color,
|
||||||
anchor='rm',
|
anchor="rm",
|
||||||
)
|
)
|
||||||
img.paste(floor_pic, (0, 657 + index_floor * 570), floor_pic)
|
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(
|
async def draw_abyss_img(
|
||||||
qid: Union[str, int],
|
qid: Union[str, int],
|
||||||
uid: str,
|
uid: str,
|
||||||
sender: Union[str, str],
|
sender: Dict[str, Any],
|
||||||
schedule_type: str = '1',
|
schedule_type: str = "1",
|
||||||
) -> Union[bytes, str]:
|
) -> Union[bytes, str]:
|
||||||
raw_abyss_data = await mys_api.get_abyss_story_info(uid, schedule_type)
|
raw_abyss_data = await mys_api.get_abyss_story_info(uid, schedule_type)
|
||||||
if isinstance(raw_abyss_data, int):
|
if isinstance(raw_abyss_data, int):
|
||||||
return get_error(raw_abyss_data)
|
return get_error(raw_abyss_data)
|
||||||
|
|
||||||
# 获取查询者数据
|
# 获取查询者数据
|
||||||
if raw_abyss_data.max_floor == '':
|
if raw_abyss_data.max_floor == "":
|
||||||
return '你还没有挑战本期虚构叙事!\n可以使用[sr上期虚构叙事]命令查询上期~'
|
return "你还没有挑战本期虚构叙事!\n可以使用[sr上期虚构叙事]命令查询上期~"
|
||||||
# 过滤掉 is_fast(快速通关) 为 True 的项
|
# 过滤掉 is_fast (快速通关) 为 True 的项
|
||||||
floor_detail = [detail for detail in raw_abyss_data.all_floor_detail if not detail.is_fast]
|
floor_detail = [
|
||||||
|
detail for detail in raw_abyss_data.all_floor_detail if not detail.is_fast
|
||||||
|
]
|
||||||
floor_num = len(floor_detail)
|
floor_num = len(floor_detail)
|
||||||
|
|
||||||
# 获取背景图片各项参数
|
# 获取背景图片各项参数
|
||||||
@ -156,15 +150,15 @@ async def draw_abyss_img(
|
|||||||
based_h = 657 + 570 * floor_num
|
based_h = 657 + 570 * floor_num
|
||||||
img = img_bg.copy()
|
img = img_bg.copy()
|
||||||
img = img.crop((0, 0, based_w, based_h))
|
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)
|
img.paste(abyss_title, (0, 0), abyss_title)
|
||||||
|
|
||||||
# 获取头像
|
# 获取头像
|
||||||
_id = str(qid)
|
_id = str(qid)
|
||||||
if _id.startswith('http'):
|
if _id.startswith("http"):
|
||||||
char_pic = await get_qq_avatar(avatar_url=_id)
|
char_pic = await get_qq_avatar(avatar_url=_id)
|
||||||
elif sender.get('avatar') is not None:
|
elif sender.get("avatar") is not None:
|
||||||
char_pic = await get_qq_avatar(avatar_url=sender['avatar'])
|
char_pic = await get_qq_avatar(avatar_url=sender["avatar"])
|
||||||
else:
|
else:
|
||||||
char_pic = await get_qq_avatar(qid=qid)
|
char_pic = await get_qq_avatar(qid=qid)
|
||||||
char_pic = await draw_pic_with_ring(char_pic, 250, None, False)
|
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 = 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.paste(abyss_data, (0, 500), abyss_data)
|
||||||
|
|
||||||
# 最深抵达
|
# 最深抵达
|
||||||
img_draw.text(
|
img_draw.text(
|
||||||
(220, 565),
|
(220, 565),
|
||||||
f'{raw_abyss_data.max_floor}',
|
f"{raw_abyss_data.max_floor}",
|
||||||
white_color,
|
white_color,
|
||||||
sr_font_34,
|
sr_font_34,
|
||||||
'lm',
|
"lm",
|
||||||
)
|
)
|
||||||
# 挑战次数
|
# 挑战次数
|
||||||
img_draw.text(
|
img_draw.text(
|
||||||
(220, 612),
|
(220, 612),
|
||||||
f'{raw_abyss_data.battle_num}',
|
f"{raw_abyss_data.battle_num}",
|
||||||
white_color,
|
white_color,
|
||||||
sr_font_34,
|
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.paste(star_num_pic, (615, 557), star_num_pic)
|
||||||
|
|
||||||
img_draw.text(
|
img_draw.text(
|
||||||
(695, 590),
|
(695, 590),
|
||||||
f'{raw_abyss_data.star_num}/12',
|
f"{raw_abyss_data.star_num}/12",
|
||||||
white_color,
|
white_color,
|
||||||
sr_font_42,
|
sr_font_42,
|
||||||
'lm',
|
"lm",
|
||||||
)
|
)
|
||||||
|
|
||||||
for index_floor, level in enumerate(raw_abyss_data.all_floor_detail):
|
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
|
level_star = level.star_num
|
||||||
floor_name = level.name
|
floor_name = level.name
|
||||||
round_num = level.round_num
|
round_num = level.round_num
|
||||||
@ -220,23 +214,24 @@ async def draw_abyss_img(
|
|||||||
time_array = node_1.challenge_time
|
time_array = node_1.challenge_time
|
||||||
else:
|
else:
|
||||||
time_array = node_2.challenge_time
|
time_array = node_2.challenge_time
|
||||||
time_str = f'{time_array.year}-{time_array.month}'
|
assert time_array is not None
|
||||||
time_str = f'{time_str}-{time_array.day}'
|
time_str = f"{time_array.year}-{time_array.month}"
|
||||||
time_str = f'{time_str} {time_array.hour}:{time_array.minute}:00'
|
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 = ImageDraw.Draw(floor_pic)
|
||||||
floor_pic_draw.text(
|
floor_pic_draw.text(
|
||||||
(112, 120 + index_part * 219),
|
(112, 120 + index_part * 219),
|
||||||
f'节点{node_num}',
|
f"节点{node_num}",
|
||||||
white_color,
|
white_color,
|
||||||
sr_font_30,
|
sr_font_30,
|
||||||
'lm',
|
"lm",
|
||||||
)
|
)
|
||||||
floor_pic_draw.text(
|
floor_pic_draw.text(
|
||||||
(201, 120 + index_part * 219),
|
(201, 120 + index_part * 219),
|
||||||
f'{time_str}',
|
f"{time_str}",
|
||||||
gray_color,
|
gray_color,
|
||||||
sr_font_22,
|
sr_font_22,
|
||||||
'lm',
|
"lm",
|
||||||
)
|
)
|
||||||
if node_num == 1:
|
if node_num == 1:
|
||||||
avatars_array = node_1
|
avatars_array = node_1
|
||||||
@ -261,5 +256,5 @@ async def draw_abyss_img(
|
|||||||
)
|
)
|
||||||
|
|
||||||
res = await convert_img(img)
|
res = await convert_img(img)
|
||||||
logger.info('[查询虚构叙事信息]绘图已完成,等待发送!')
|
logger.info("[查询虚构叙事信息]绘图已完成,等待发送!")
|
||||||
return res
|
return res
|
||||||
|
@ -6,14 +6,14 @@ from PIL import Image
|
|||||||
from aiohttp import ClientSession
|
from aiohttp import ClientSession
|
||||||
from gsuid_core.data_store import get_res_path
|
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)
|
ROLEINFO_PATH.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
|
||||||
async def get_icon(url: str) -> Image.Image:
|
async def get_icon(url: str) -> Image.Image:
|
||||||
name = url.split('/')[-1]
|
name = url.split("/")[-1]
|
||||||
path = ROLEINFO_PATH / name
|
path = ROLEINFO_PATH / name
|
||||||
if (path).exists():
|
if (path).exists():
|
||||||
content = path.read_bytes()
|
content = path.read_bytes()
|
||||||
@ -21,6 +21,6 @@ async def get_icon(url: str) -> Image.Image:
|
|||||||
async with ClientSession() as client:
|
async with ClientSession() as client:
|
||||||
async with client.get(url) as resp:
|
async with client.get(url) as resp:
|
||||||
content = await resp.read()
|
content = await resp.read()
|
||||||
with Path.open(path, 'wb') as f:
|
with Path.open(path, "wb") as f:
|
||||||
f.write(content)
|
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 typing import TYPE_CHECKING
|
||||||
|
|
||||||
from ..utils.convert import get_uid
|
|
||||||
from ..utils.error_reply import UID_HINT
|
from ..utils.error_reply import UID_HINT
|
||||||
from ..utils.map.name_covert import (
|
from ..utils.map.name_covert import (
|
||||||
alias_to_char_name,
|
alias_to_char_name,
|
||||||
@ -10,26 +9,29 @@ from ..utils.mys_api import mys_api
|
|||||||
from ..utils.sr_prefix import PREFIX
|
from ..utils.sr_prefix import PREFIX
|
||||||
|
|
||||||
from gsuid_core.sv import SV
|
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
|
from gsuid_core.utils.error_reply import get_error
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from gsuid_core.bot import Bot
|
from gsuid_core.bot import Bot
|
||||||
from gsuid_core.models import Event
|
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)
|
@sv_char_calc.on_command(f"{PREFIX}养成计算", block=True)
|
||||||
async def send_char_calc_info(bot: 'Bot', ev: 'Event'):
|
async def send_char_calc_info(bot: "Bot", ev: "Event"):
|
||||||
name = ev.text.strip()
|
name = ev.text.strip()
|
||||||
char_id = await name_to_avatar_id(name)
|
char_id = await name_to_avatar_id(name)
|
||||||
if char_id == '':
|
if char_id == "":
|
||||||
result_fake_name = await alias_to_char_name(name)
|
result_fake_name = await alias_to_char_name(name)
|
||||||
if result_fake_name is None:
|
if result_fake_name is None:
|
||||||
return '请输入正确的角色名'
|
return "请输入正确的角色名"
|
||||||
fake_name = result_fake_name
|
fake_name = result_fake_name
|
||||||
char_id = await name_to_avatar_id(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:
|
if uid is None:
|
||||||
return await bot.send(UID_HINT)
|
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
|
avatar_skills = avatar_detail.skills + avatar_detail.skills_other
|
||||||
skill_list = []
|
skill_list = []
|
||||||
for skill in avatar_skills:
|
for skill in avatar_skills:
|
||||||
skill_list.append(
|
skill_list.append(f"{skill.point_id}({skill.cur_level}/{skill.max_level})")
|
||||||
f'{skill.point_id}({skill.cur_level}/{skill.max_level})'
|
|
||||||
)
|
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
@ -1,28 +1,29 @@
|
|||||||
import re
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
import re
|
||||||
from typing import Tuple, cast
|
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 PIL import Image
|
||||||
from gsuid_core.sv import SV
|
|
||||||
from gsuid_core.bot import Bot
|
from gsuid_core.bot import Bot
|
||||||
from gsuid_core.models import Event
|
|
||||||
from gsuid_core.message_models import Button
|
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 starrail_damage_cal.map.SR_MAP_PATH import avatarId2Name
|
||||||
|
|
||||||
from .to_card import api_to_card
|
sv_char_info_config = SV("sr面板设置", pm=2)
|
||||||
from ..utils.convert import get_uid
|
sv_get_char_info = SV("sr面板查询", priority=10)
|
||||||
from ..utils.sr_prefix import PREFIX
|
sv_get_sr_original_pic = SV("sr查看面板原图", priority=5)
|
||||||
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_get_char_info.on_prefix(f'{PREFIX}查询')
|
@sv_get_char_info.on_prefix(f"{PREFIX}查询")
|
||||||
async def send_char_info(bot: Bot, ev: Event):
|
async def send_char_info(bot: Bot, ev: Event):
|
||||||
name = ev.text.strip()
|
name = ev.text.strip()
|
||||||
im = await _get_char_info(bot, ev, ev.text)
|
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(
|
await bot.send_option(
|
||||||
img,
|
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]:
|
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]))
|
f.write(cast(bytes, im[1]))
|
||||||
elif isinstance(im, Image.Image):
|
elif isinstance(im, Image.Image):
|
||||||
await bot.send(await convert_img(im))
|
await bot.send(await convert_img(im))
|
||||||
@ -50,14 +51,14 @@ async def send_char_info(bot: Bot, ev: Event):
|
|||||||
await bot.send_option(
|
await bot.send_option(
|
||||||
im,
|
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:
|
elif im is None:
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
await bot.send('发生未知错误')
|
await bot.send("发生未知错误")
|
||||||
|
|
||||||
|
|
||||||
async def _get_char_info(bot: Bot, ev: Event, text: str):
|
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:
|
if not msg:
|
||||||
return None
|
return None
|
||||||
# 获取角色名
|
# 获取角色名
|
||||||
await bot.logger.info('开始执行[查询角色面板]')
|
await bot.logger.info("开始执行[查询角色面板]")
|
||||||
# 获取uid
|
# 获取uid
|
||||||
if '换' in msg or '拿' in msg or '带' in msg:
|
if "换" in msg or "拿" in msg or "带" in msg:
|
||||||
uid = await get_uid(bot, ev, False, True)
|
uid = await get_uid(bot, ev, GsBind, "sr", False)
|
||||||
else:
|
else:
|
||||||
uid = await get_uid(bot, ev)
|
uid = await get_uid(bot, ev, GsBind, "sr")
|
||||||
msg = ' '.join(re.findall('[\u4e00-\u9fa5]+', text))
|
msg = " ".join(re.findall("[\u4e00-\u9fa5]+", text))
|
||||||
if uid is None:
|
if uid is None:
|
||||||
return await bot.send(UID_HINT)
|
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)
|
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):
|
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:
|
if uid is None:
|
||||||
return await bot.send(UID_HINT)
|
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)
|
im = await api_to_card(uid)
|
||||||
await bot.logger.info(f'UID{uid}获取角色数据成功!')
|
await bot.logger.info(f"UID{uid}获取角色数据成功!")
|
||||||
if isinstance(im, Tuple):
|
if isinstance(im, Tuple):
|
||||||
buttons = [
|
buttons = [
|
||||||
Button(
|
Button(
|
||||||
f'✅查询{avatarId2Name[str(avatarid)]}',
|
f"✅查询{avatarId2Name[str(avatarid)]}",
|
||||||
f'sr查询{avatarId2Name[str(avatarid)]}',
|
f"sr查询{avatarId2Name[str(avatarid)]}",
|
||||||
)
|
)
|
||||||
for avatarid in im[1]
|
for avatarid in im[1]
|
||||||
]
|
]
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,67 +1,67 @@
|
|||||||
import re
|
|
||||||
import json
|
import json
|
||||||
from pathlib import Path
|
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 gsuid_core.logger import logger
|
||||||
from starrail_damage_cal.to_data import api_to_dict
|
|
||||||
from starrail_damage_cal.excel.model import (
|
from starrail_damage_cal.excel.model import (
|
||||||
AvatarPromotionConfig,
|
AvatarPromotionConfig,
|
||||||
EquipmentPromotionConfig,
|
EquipmentPromotionConfig,
|
||||||
)
|
)
|
||||||
|
from starrail_damage_cal.to_data import api_to_dict
|
||||||
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,
|
|
||||||
)
|
|
||||||
|
|
||||||
WEAPON_TO_INT = {
|
WEAPON_TO_INT = {
|
||||||
'一': 1,
|
"一": 1,
|
||||||
'二': 2,
|
"二": 2,
|
||||||
'三': 3,
|
"三": 3,
|
||||||
'四': 4,
|
"四": 4,
|
||||||
'五': 5,
|
"五": 5,
|
||||||
'满': 5,
|
"满": 5,
|
||||||
}
|
}
|
||||||
|
|
||||||
CHAR_TO_INT = {
|
CHAR_TO_INT = {
|
||||||
'零': 0,
|
"零": 0,
|
||||||
'一': 1,
|
"一": 1,
|
||||||
'二': 2,
|
"二": 2,
|
||||||
'三': 3,
|
"三": 3,
|
||||||
'四': 4,
|
"四": 4,
|
||||||
'五': 5,
|
"五": 5,
|
||||||
'六': 6,
|
"六": 6,
|
||||||
'满': 6,
|
"满": 6,
|
||||||
}
|
}
|
||||||
|
|
||||||
PieceName_ilst = {
|
PieceName_ilst = {
|
||||||
0: ['头', '帽'],
|
0: ["头", "帽"],
|
||||||
1: ['手'],
|
1: ["手"],
|
||||||
2: ['衣', '服', '躯'],
|
2: ["衣", "服", "躯"],
|
||||||
3: ['鞋', '腿'],
|
3: ["鞋", "腿"],
|
||||||
4: ['球'],
|
4: ["球"],
|
||||||
5: ['绳', '链'],
|
5: ["绳", "链"],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -77,11 +77,11 @@ async def draw_char_info_img(raw_mes: str, sr_uid: str):
|
|||||||
char = await get_char(*_args)
|
char = await get_char(*_args)
|
||||||
|
|
||||||
if isinstance(char, str):
|
if isinstance(char, str):
|
||||||
logger.info('[sr查询角色] 绘图失败, 替换的武器不正确!')
|
logger.info("[sr查询角色] 绘图失败, 替换的武器不正确!")
|
||||||
return char
|
return char
|
||||||
|
|
||||||
im = await draw_char_img(char, sr_uid, raw_mes)
|
im = await draw_char_img(char, sr_uid, raw_mes)
|
||||||
logger.info('[查询角色] 绘图完成,等待发送...')
|
logger.info("[查询角色] 绘图完成,等待发送...")
|
||||||
return im
|
return im
|
||||||
|
|
||||||
|
|
||||||
@ -92,24 +92,24 @@ async def get_char_args(
|
|||||||
# 六命希儿带于夜色中换1000xxxx4青雀遗器换1000xxxx6希儿头换银狼手
|
# 六命希儿带于夜色中换1000xxxx4青雀遗器换1000xxxx6希儿头换银狼手
|
||||||
# 六命希儿带于夜色中换1000xxxx6希儿头
|
# 六命希儿带于夜色中换1000xxxx6希儿头
|
||||||
# 希儿换银狼手
|
# 希儿换银狼手
|
||||||
fake_name = ''
|
fake_name = ""
|
||||||
talent_num = None
|
talent_num = None
|
||||||
char_data = {}
|
char_data = {}
|
||||||
weapon, weapon_affix = None, None
|
weapon, weapon_affix = None, None
|
||||||
|
|
||||||
msg = msg.replace('带', '换').replace('拿', '换').replace('圣遗物', '遗器')
|
msg = msg.replace("带", "换").replace("拿", "换").replace("圣遗物", "遗器")
|
||||||
|
|
||||||
# 希儿带于夜色中换1000xxxx6希儿头
|
# 希儿带于夜色中换1000xxxx6希儿头
|
||||||
msg_list = msg.split('换')
|
msg_list = msg.split("换")
|
||||||
for index, part in enumerate(msg_list):
|
for index, part in enumerate(msg_list):
|
||||||
changeuid = await get_part_uid(part, uid)
|
changeuid = await get_part_uid(part, uid)
|
||||||
if changeuid is None:
|
if changeuid is None:
|
||||||
return 'UID不正确噢~'
|
return "UID不正确噢~"
|
||||||
# 判断主体
|
# 判断主体
|
||||||
if index == 0:
|
if index == 0:
|
||||||
fake_name, talent_num = await get_fake_char_str(part)
|
fake_name, talent_num = await get_fake_char_str(part)
|
||||||
# 判断是否开启fake_char
|
# 判断是否开启fake_char
|
||||||
if '遗器' in msg:
|
if "遗器" in msg:
|
||||||
char_data = await get_char_data(uid, fake_name)
|
char_data = await get_char_data(uid, fake_name)
|
||||||
if isinstance(char_data, str):
|
if isinstance(char_data, str):
|
||||||
char_data = await make_new_charinfo(uid, fake_name)
|
char_data = await make_new_charinfo(uid, fake_name)
|
||||||
@ -119,29 +119,25 @@ async def get_char_args(
|
|||||||
return char_data
|
return char_data
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if '遗器' in part:
|
if "遗器" in part:
|
||||||
char_data = await get_fake_char_data(
|
char_data = await get_fake_char_data(
|
||||||
char_data,
|
char_data,
|
||||||
part.replace('遗器', '').replace(changeuid, ''),
|
part.replace("遗器", "").replace(changeuid, ""),
|
||||||
changeuid,
|
changeuid,
|
||||||
)
|
)
|
||||||
if isinstance(char_data, str):
|
if isinstance(char_data, str):
|
||||||
return char_data
|
return char_data
|
||||||
else:
|
else:
|
||||||
for i, s in enumerate(
|
for i, s in enumerate(["头部", "手部", "躯干", "腿部", "位面球", "连结绳"]):
|
||||||
['头部', '手部', '躯干', '腿部', '位面球', '连结绳']
|
if "赤沙" in part:
|
||||||
):
|
|
||||||
if '赤沙' in part:
|
|
||||||
continue
|
continue
|
||||||
if part[-1] in PieceName_ilst[i]:
|
if part[-1] in PieceName_ilst[i]:
|
||||||
if isinstance(char_data, str):
|
if isinstance(char_data, str):
|
||||||
return char_data
|
return char_data
|
||||||
char_data = await change_equip(
|
char_data = await change_equip(changeuid, char_data, part, s, i)
|
||||||
changeuid, char_data, part, s, i
|
|
||||||
)
|
|
||||||
if not char_data:
|
if not char_data:
|
||||||
change_name = part.replace(part[-1], '')
|
change_name = part.replace(part[-1], "")
|
||||||
return f'要替换的{change_name}的{s}遗器不存在噢~'
|
return f"要替换的{change_name}的{s}遗器不存在噢~"
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
weapon, weapon_affix = await get_fake_weapon_str(part)
|
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
|
return char_data, weapon, weapon_affix, talent_num
|
||||||
|
|
||||||
|
|
||||||
async def change_equip(
|
async def change_equip(uid: str, char_data: Dict, part: str, s: str, i: int) -> Dict:
|
||||||
uid: str, char_data: Dict, part: str, s: str, i: int
|
char_name = part.replace(part[-1], "").replace(uid, "")
|
||||||
) -> Dict:
|
|
||||||
char_name = part.replace(part[-1], '').replace(uid, '')
|
|
||||||
fake_data = await get_char_data(uid, char_name)
|
fake_data = await get_char_data(uid, char_name)
|
||||||
if isinstance(fake_data, str):
|
if isinstance(fake_data, str):
|
||||||
return {}
|
return {}
|
||||||
relicmap = i + 1
|
relicmap = i + 1
|
||||||
for equip in fake_data['RelicInfo']:
|
for equip in fake_data["RelicInfo"]:
|
||||||
if str(str(equip['relicId'])[-1]) == str(relicmap):
|
if str(str(equip["relicId"])[-1]) == str(relicmap):
|
||||||
char_data['RelicInfo'][i] = equip
|
char_data["RelicInfo"][i] = equip
|
||||||
break
|
break
|
||||||
return char_data
|
return char_data
|
||||||
|
|
||||||
|
|
||||||
async def get_part_uid(part: str, uid: str):
|
async def get_part_uid(part: str, uid: str):
|
||||||
sr_uid = uid
|
sr_uid = uid
|
||||||
uid_data = re.findall(r'\d{9}', part)
|
uid_data = re.findall(r"\d{9}", part)
|
||||||
if uid_data:
|
if uid_data:
|
||||||
sr_uid: Optional[str] = uid_data[0]
|
sr_uid: Optional[str] = uid_data[0]
|
||||||
return sr_uid
|
return sr_uid
|
||||||
@ -178,9 +172,7 @@ async def get_fake_char_str(char_name: str) -> Tuple[str, Optional[int]]:
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
talent_num = None
|
talent_num = None
|
||||||
if ('魂' in char_name or '命' in char_name) and char_name[
|
if ("魂" in char_name or "命" in char_name) and char_name[0] in CHAR_TO_INT:
|
||||||
0
|
|
||||||
] in CHAR_TO_INT:
|
|
||||||
talent_num = CHAR_TO_INT[char_name[0]]
|
talent_num = CHAR_TO_INT[char_name[0]]
|
||||||
char_name = char_name[2:]
|
char_name = char_name[2:]
|
||||||
return char_name, talent_num
|
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]]:
|
async def get_fake_weapon_str(msg: str) -> Tuple[str, Optional[int]]:
|
||||||
weapon_affix = 1
|
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_affix = WEAPON_TO_INT[msg[1]]
|
||||||
weapon = msg[2:]
|
weapon = msg[2:]
|
||||||
else:
|
else:
|
||||||
@ -203,7 +195,7 @@ async def get_fake_char_data(
|
|||||||
if isinstance(original_data, str):
|
if isinstance(original_data, str):
|
||||||
return original_data
|
return original_data
|
||||||
if isinstance(original_data, Dict):
|
if isinstance(original_data, Dict):
|
||||||
char_data['RelicInfo'] = original_data['RelicInfo']
|
char_data["RelicInfo"] = original_data["RelicInfo"]
|
||||||
|
|
||||||
return char_data
|
return char_data
|
||||||
|
|
||||||
@ -212,16 +204,16 @@ async def get_char_data(
|
|||||||
uid: str, char_name: str, enable_self: bool = True
|
uid: str, char_name: str, enable_self: bool = True
|
||||||
) -> Union[Dict, str]:
|
) -> Union[Dict, str]:
|
||||||
player_path = PLAYER_PATH / str(uid)
|
player_path = PLAYER_PATH / str(uid)
|
||||||
SELF_PATH = player_path / 'SELF'
|
SELF_PATH = player_path / "SELF"
|
||||||
if '开拓者' in str(char_name):
|
if "开拓者" in str(char_name):
|
||||||
char_name = '开拓者'
|
char_name = "开拓者"
|
||||||
char_id = await name_to_avatar_id(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_name = await alias_to_char_name(char_name)
|
||||||
if char_name is False:
|
if char_name is False:
|
||||||
return '请输入正确的角色名'
|
return "请输入正确的角色名"
|
||||||
char_path = player_path / f'{char_name}.json'
|
char_path = player_path / f"{char_name}.json"
|
||||||
char_self_path = SELF_PATH / f'{char_name}.json'
|
char_self_path = SELF_PATH / f"{char_name}.json"
|
||||||
path = Path()
|
path = Path()
|
||||||
if char_path.exists():
|
if char_path.exists():
|
||||||
path = char_path
|
path = char_path
|
||||||
@ -243,7 +235,7 @@ async def get_char_data(
|
|||||||
else:
|
else:
|
||||||
return CHAR_HINT.format(char_name, char_name)
|
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)
|
return json.load(fp)
|
||||||
|
|
||||||
|
|
||||||
@ -252,39 +244,29 @@ async def make_new_charinfo(
|
|||||||
fake_name: str,
|
fake_name: str,
|
||||||
):
|
):
|
||||||
char_data = {}
|
char_data = {}
|
||||||
char_data['uid'] = uid
|
char_data["uid"] = uid
|
||||||
char_data['nickName'] = 'test'
|
char_data["nickName"] = "test"
|
||||||
char_id = await name_to_avatar_id(fake_name)
|
char_id = await name_to_avatar_id(fake_name)
|
||||||
if char_id == '':
|
if char_id == "":
|
||||||
fake_name = await alias_to_char_name(fake_name)
|
fake_name = await alias_to_char_name(fake_name)
|
||||||
if fake_name is False:
|
if fake_name is False:
|
||||||
return '请输入正确的角色名'
|
return "请输入正确的角色名"
|
||||||
char_id = await name_to_avatar_id(fake_name)
|
char_id = await name_to_avatar_id(fake_name)
|
||||||
char_data['avatarId'] = int(char_id)
|
char_data["avatarId"] = int(char_id)
|
||||||
char_data['avatarName'] = fake_name
|
char_data["avatarName"] = fake_name
|
||||||
char_data['avatarElement'] = avatarId2DamageType[
|
char_data["avatarElement"] = avatarId2DamageType[str(char_data["avatarId"])]
|
||||||
str(char_data['avatarId'])
|
char_data["avatarRarity"] = str(avatarId2Rarity[str(char_data["avatarId"])])
|
||||||
]
|
char_data["avatarPromotion"] = 6
|
||||||
char_data['avatarRarity'] = str(
|
char_data["avatarLevel"] = 80
|
||||||
avatarId2Rarity[str(char_data['avatarId'])]
|
char_data["avatarSkill"] = await get_skill_list(char_data["avatarId"])
|
||||||
)
|
char_data["avatarExtraAbility"] = await get_extra_list(char_data["avatarId"])
|
||||||
char_data['avatarPromotion'] = 6
|
char_data["avatarAttributeBonus"] = await get_attribute_list(char_data["avatarId"])
|
||||||
char_data['avatarLevel'] = 80
|
char_data["RelicInfo"] = []
|
||||||
char_data['avatarSkill'] = await get_skill_list(char_data['avatarId'])
|
char_data["avatarEnName"] = avatarId2EnName[str(char_data["avatarId"])]
|
||||||
char_data['avatarExtraAbility'] = await get_extra_list(
|
char_data["rank"] = 0
|
||||||
char_data['avatarId']
|
char_data["rankList"] = []
|
||||||
)
|
char_data["baseAttributes"] = await get_baseAttributes(char_data["avatarId"])
|
||||||
char_data['avatarAttributeBonus'] = await get_attribute_list(
|
char_data["equipmentInfo"] = {}
|
||||||
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
|
return char_data
|
||||||
|
|
||||||
|
|
||||||
@ -293,35 +275,40 @@ async def get_baseAttributes(
|
|||||||
):
|
):
|
||||||
# 处理基础属性
|
# 处理基础属性
|
||||||
base_attributes = {}
|
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.AttackBase.Value
|
||||||
+ avatar_promotion_base.AttackAdd.Value * (80 - 1)
|
+ avatar_promotion_base.AttackAdd.Value * (80 - 1)
|
||||||
)
|
)
|
||||||
# 防御力
|
# 防御力
|
||||||
base_attributes['defence'] = (
|
base_attributes["defence"] = (
|
||||||
avatar_promotion_base.DefenceBase.Value
|
avatar_promotion_base.DefenceBase.Value
|
||||||
+ avatar_promotion_base.DefenceAdd.Value * (80 - 1)
|
+ avatar_promotion_base.DefenceAdd.Value * (80 - 1)
|
||||||
)
|
)
|
||||||
# 血量
|
# 血量
|
||||||
base_attributes['hp'] = (
|
base_attributes["hp"] = (
|
||||||
avatar_promotion_base.HPBase.Value
|
avatar_promotion_base.HPBase.Value
|
||||||
+ avatar_promotion_base.HPAdd.Value * (80 - 1)
|
+ 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'] = (
|
base_attributes["CriticalChanceBase"] = avatar_promotion_base.CriticalChance.Value
|
||||||
avatar_promotion_base.CriticalChance.Value
|
|
||||||
)
|
|
||||||
# 暴击伤害
|
# 暴击伤害
|
||||||
base_attributes['CriticalDamageBase'] = (
|
base_attributes["CriticalDamageBase"] = avatar_promotion_base.CriticalDamage.Value
|
||||||
avatar_promotion_base.CriticalDamage.Value
|
|
||||||
)
|
|
||||||
# 嘲讽
|
# 嘲讽
|
||||||
base_attributes['BaseAggro'] = avatar_promotion_base.BaseAggro.Value
|
base_attributes["BaseAggro"] = avatar_promotion_base.BaseAggro.Value
|
||||||
return base_attributes
|
return base_attributes
|
||||||
|
|
||||||
|
|
||||||
@ -331,21 +318,19 @@ async def get_attribute_list(
|
|||||||
attribute_list = []
|
attribute_list = []
|
||||||
for attributeid in [201, 202, 203, 204, 205, 206, 207, 208, 209, 210]:
|
for attributeid in [201, 202, 203, 204, 205, 206, 207, 208, 209, 210]:
|
||||||
attribute_bonus_temp = {}
|
attribute_bonus_temp = {}
|
||||||
attribute_bonus_temp['attributeBonusId'] = char_id * 1000 + attributeid
|
attribute_bonus_temp["attributeBonusId"] = char_id * 1000 + attributeid
|
||||||
attribute_bonus_temp['attributeBonusLevel'] = 1
|
attribute_bonus_temp["attributeBonusLevel"] = 1
|
||||||
status_add = characterSkillTree[str(char_id)][
|
status_add = characterSkillTree[str(char_id)][
|
||||||
str(attribute_bonus_temp['attributeBonusId'])
|
str(attribute_bonus_temp["attributeBonusId"])
|
||||||
]['levels'][0]['properties']
|
]["levels"][0]["properties"]
|
||||||
attribute_bonus_temp['statusAdd'] = {}
|
attribute_bonus_temp["statusAdd"] = {}
|
||||||
if status_add:
|
if status_add:
|
||||||
for property_ in status_add:
|
for property_ in status_add:
|
||||||
attribute_bonus_temp['statusAdd']['property'] = property_[
|
attribute_bonus_temp["statusAdd"]["property"] = property_["type"]
|
||||||
'type'
|
attribute_bonus_temp["statusAdd"]["name"] = Property2Name[
|
||||||
|
property_["type"]
|
||||||
]
|
]
|
||||||
attribute_bonus_temp['statusAdd']['name'] = Property2Name[
|
attribute_bonus_temp["statusAdd"]["value"] = property_["value"]
|
||||||
property_['type']
|
|
||||||
]
|
|
||||||
attribute_bonus_temp['statusAdd']['value'] = property_['value']
|
|
||||||
attribute_list.append(attribute_bonus_temp)
|
attribute_list.append(attribute_bonus_temp)
|
||||||
return attribute_list
|
return attribute_list
|
||||||
|
|
||||||
@ -356,8 +341,8 @@ async def get_extra_list(
|
|||||||
extra_list = []
|
extra_list = []
|
||||||
for extraid in [101, 102, 103]:
|
for extraid in [101, 102, 103]:
|
||||||
extra_temp = {}
|
extra_temp = {}
|
||||||
extra_temp['extraAbilityId'] = char_id * 1000 + extraid
|
extra_temp["extraAbilityId"] = char_id * 1000 + extraid
|
||||||
extra_temp['extraAbilityLevel'] = 1
|
extra_temp["extraAbilityLevel"] = 1
|
||||||
extra_list.append(extra_temp)
|
extra_list.append(extra_temp)
|
||||||
return extra_list
|
return extra_list
|
||||||
|
|
||||||
@ -368,18 +353,16 @@ async def get_skill_list(
|
|||||||
Skilllist = []
|
Skilllist = []
|
||||||
for skillid in [1, 2, 3, 4, 7]:
|
for skillid in [1, 2, 3, 4, 7]:
|
||||||
skill_temp = {}
|
skill_temp = {}
|
||||||
skill_temp['skillId'] = char_id * 100 + skillid
|
skill_temp["skillId"] = char_id * 100 + skillid
|
||||||
skill_temp['skillName'] = skillId2Name[str(skill_temp['skillId'])]
|
skill_temp["skillName"] = skillId2Name[str(skill_temp["skillId"])]
|
||||||
skill_temp['skillEffect'] = skillId2Effect[str(skill_temp['skillId'])]
|
skill_temp["skillEffect"] = skillId2Effect[str(skill_temp["skillId"])]
|
||||||
skill_temp['skillAttackType'] = skillId2AttackType[
|
skill_temp["skillAttackType"] = skillId2AttackType[str(skill_temp["skillId"])]
|
||||||
str(skill_temp['skillId'])
|
|
||||||
]
|
|
||||||
skilllevel = 10
|
skilllevel = 10
|
||||||
if skillid == 1:
|
if skillid == 1:
|
||||||
skilllevel = 6
|
skilllevel = 6
|
||||||
if skillid == 7:
|
if skillid == 7:
|
||||||
skilllevel = 1
|
skilllevel = 1
|
||||||
skill_temp['skillLevel'] = skilllevel
|
skill_temp["skillLevel"] = skilllevel
|
||||||
Skilllist.append(skill_temp)
|
Skilllist.append(skill_temp)
|
||||||
return Skilllist
|
return Skilllist
|
||||||
|
|
||||||
@ -391,9 +374,9 @@ async def get_rank_list(
|
|||||||
rank_temp = []
|
rank_temp = []
|
||||||
for index in range(talent_num):
|
for index in range(talent_num):
|
||||||
rankTemp = {}
|
rankTemp = {}
|
||||||
rank_id = int(str(char_id) + '0' + str(index + 1))
|
rank_id = int(str(char_id) + "0" + str(index + 1))
|
||||||
rankTemp['rankId'] = rank_id
|
rankTemp["rankId"] = rank_id
|
||||||
rankTemp['rankName'] = rankId2Name[str(rank_id)]
|
rankTemp["rankName"] = rankId2Name[str(rank_id)]
|
||||||
rank_temp.append(rankTemp)
|
rank_temp.append(rankTemp)
|
||||||
return rank_temp
|
return rank_temp
|
||||||
|
|
||||||
@ -407,82 +390,82 @@ async def get_char(
|
|||||||
if isinstance(talent_num, int):
|
if isinstance(talent_num, int):
|
||||||
# 处理命座
|
# 处理命座
|
||||||
rank_temp = []
|
rank_temp = []
|
||||||
char_data['rank'] = talent_num
|
char_data["rank"] = talent_num
|
||||||
for index in range(talent_num):
|
for index in range(talent_num):
|
||||||
rankTemp = {}
|
rankTemp = {}
|
||||||
rank_id = int(str(char_data['avatarId']) + '0' + str(index + 1))
|
rank_id = int(str(char_data["avatarId"]) + "0" + str(index + 1))
|
||||||
rankTemp['rankId'] = rank_id
|
rankTemp["rankId"] = rank_id
|
||||||
rankTemp['rankName'] = rankId2Name[str(rank_id)]
|
rankTemp["rankName"] = rankId2Name[str(rank_id)]
|
||||||
rank_temp.append(rankTemp)
|
rank_temp.append(rankTemp)
|
||||||
char_data['rankList'] = rank_temp
|
char_data["rankList"] = rank_temp
|
||||||
|
|
||||||
# 处理命座中的 level_up_skills
|
# 处理命座中的 level_up_skills
|
||||||
if char_data.get('rankList'):
|
if char_data.get("rankList"):
|
||||||
for rank_item in char_data['rankList']:
|
for rank_item in char_data["rankList"]:
|
||||||
rank_id = rank_item['rankId']
|
rank_id = rank_item["rankId"]
|
||||||
level_up_skill = AvatarRankSkillUp[str(rank_id)]
|
level_up_skill = AvatarRankSkillUp[str(rank_id)]
|
||||||
if level_up_skill:
|
if level_up_skill:
|
||||||
for item in level_up_skill:
|
for item in level_up_skill:
|
||||||
skill_id = item['id']
|
skill_id = item["id"]
|
||||||
skill_up_num = item['num']
|
skill_up_num = item["num"]
|
||||||
# 查找skill_id在不在avatarSkill中
|
# 查找skill_id在不在avatarSkill中
|
||||||
for index, skill_item in enumerate(
|
for index, skill_item in enumerate(char_data["avatarSkill"]):
|
||||||
char_data['avatarSkill']
|
if str(skill_id) == str(skill_item["skillId"]):
|
||||||
):
|
|
||||||
if str(skill_id) == str(skill_item['skillId']):
|
|
||||||
if skill_id[-1] == 1:
|
if skill_id[-1] == 1:
|
||||||
skilllevel_max = 7
|
skilllevel_max = 7
|
||||||
else:
|
else:
|
||||||
skilllevel_max = 12
|
skilllevel_max = 12
|
||||||
skilllevel = min(
|
skilllevel = min(
|
||||||
skilllevel_max,
|
skilllevel_max,
|
||||||
char_data['avatarSkill'][index][
|
char_data["avatarSkill"][index]["skillLevel"]
|
||||||
'skillLevel'
|
|
||||||
]
|
|
||||||
+ skill_up_num,
|
+ skill_up_num,
|
||||||
)
|
)
|
||||||
char_data['avatarSkill'][index][
|
char_data["avatarSkill"][index]["skillLevel"] = (
|
||||||
'skillLevel'
|
skilllevel
|
||||||
] = skilllevel
|
)
|
||||||
break
|
break
|
||||||
|
|
||||||
if isinstance(weapon, str):
|
if isinstance(weapon, str):
|
||||||
# 处理武器
|
# 处理武器
|
||||||
equipmentid = await name_to_weapon_id(weapon)
|
equipmentid = await name_to_weapon_id(weapon)
|
||||||
if equipmentid == '':
|
if equipmentid == "":
|
||||||
weapon = await alias_to_weapon_name(weapon)
|
weapon = await alias_to_weapon_name(weapon)
|
||||||
equipmentid = await name_to_weapon_id(weapon)
|
equipmentid = await name_to_weapon_id(weapon)
|
||||||
equipment_info = {}
|
equipment_info = {}
|
||||||
equipment_info['equipmentID'] = int(equipmentid)
|
equipment_info["equipmentID"] = int(equipmentid)
|
||||||
equipment_info['equipmentName'] = EquipmentID2Name[str(equipmentid)]
|
equipment_info["equipmentName"] = EquipmentID2Name[str(equipmentid)]
|
||||||
|
|
||||||
equipment_info['equipmentLevel'] = 80
|
equipment_info["equipmentLevel"] = 80
|
||||||
equipment_info['equipmentPromotion'] = 6
|
equipment_info["equipmentPromotion"] = 6
|
||||||
equipment_info['equipmentRank'] = weapon_affix
|
equipment_info["equipmentRank"] = weapon_affix
|
||||||
equipment_info['equipmentRarity'] = EquipmentID2Rarity[
|
equipment_info["equipmentRarity"] = EquipmentID2Rarity[str(equipmentid)]
|
||||||
str(equipmentid)
|
|
||||||
]
|
|
||||||
equipment_base_attributes = {}
|
equipment_base_attributes = {}
|
||||||
equipment_promotion_base = EquipmentPromotionConfig.Equipment[
|
|
||||||
str(equipmentid)
|
equipment_promotion_base = None
|
||||||
]['6']
|
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.BaseHP.Value
|
||||||
+ equipment_promotion_base.BaseHPAdd.Value * (80 - 1)
|
+ equipment_promotion_base.BaseHPAdd.Value * (80 - 1)
|
||||||
)
|
)
|
||||||
# 攻击力
|
# 攻击力
|
||||||
equipment_base_attributes['attack'] = (
|
equipment_base_attributes["attack"] = (
|
||||||
equipment_promotion_base.BaseAttack.Value
|
equipment_promotion_base.BaseAttack.Value
|
||||||
+ equipment_promotion_base.BaseAttackAdd.Value * (80 - 1)
|
+ equipment_promotion_base.BaseAttackAdd.Value * (80 - 1)
|
||||||
)
|
)
|
||||||
# 防御力
|
# 防御力
|
||||||
equipment_base_attributes['defence'] = (
|
equipment_base_attributes["defence"] = (
|
||||||
equipment_promotion_base.BaseDefence.Value
|
equipment_promotion_base.BaseDefence.Value
|
||||||
+ equipment_promotion_base.BaseDefenceAdd.Value * (80 - 1)
|
+ 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
|
return char_data
|
||||||
|
@ -19,12 +19,12 @@ second_color = (67, 61, 56)
|
|||||||
white_color = (247, 247, 247)
|
white_color = (247, 247, 247)
|
||||||
gray_color = (175, 175, 175)
|
gray_color = (175, 175, 175)
|
||||||
|
|
||||||
TEXT_PATH = Path(__file__).parent / 'texture2D'
|
TEXT_PATH = Path(__file__).parent / "texture2D"
|
||||||
char_mask = Image.open(TEXT_PATH / 'ring_mask.png')
|
char_mask = Image.open(TEXT_PATH / "ring_mask.png")
|
||||||
char_bg_mask = Image.open(TEXT_PATH / 'char_bg_mask.png')
|
char_bg_mask = Image.open(TEXT_PATH / "char_bg_mask.png")
|
||||||
tag = Image.open(TEXT_PATH / 'tag.png')
|
tag = Image.open(TEXT_PATH / "tag.png")
|
||||||
footbar = Image.open(TEXT_PATH / 'footbar.png')
|
footbar = Image.open(TEXT_PATH / "footbar.png")
|
||||||
pic_500 = Image.open(TEXT_PATH / '500.png')
|
pic_500 = Image.open(TEXT_PATH / "500.png")
|
||||||
|
|
||||||
|
|
||||||
async def api_to_card(uid: str) -> Union[Tuple[bytes, List[str]], bytes]:
|
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)]
|
avatarName = avatarId2Name[str(char)]
|
||||||
char_data_list.append(
|
char_data_list.append(
|
||||||
{
|
{
|
||||||
'avatarName': avatarName,
|
"avatarName": avatarName,
|
||||||
'avatarId': str(char),
|
"avatarId": str(char),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
if showfrom == 0:
|
if showfrom == 0:
|
||||||
line1 = f'展柜内有 {len(char_data_list)} 个角色!'
|
line1 = f"展柜内有 {len(char_data_list)} 个角色!"
|
||||||
elif char_data_list is None:
|
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:
|
else:
|
||||||
line1 = f'UID {uid} 刷新成功'
|
line1 = f"UID {uid} 刷新成功"
|
||||||
line2 = (
|
line2 = f'可以使用 sr查询{char_data_list[0]["avatarName"]} 查询详情角色面板'
|
||||||
f'可以使用 sr查询{char_data_list[0]["avatarName"]} 查询详情角色面板'
|
|
||||||
)
|
|
||||||
char_num = len(char_data_list)
|
char_num = len(char_data_list)
|
||||||
if char_num <= 4:
|
if char_num <= 4:
|
||||||
based_w, based_h = 1380, 926
|
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
|
show_type = 0
|
||||||
based_w, based_h = 1380, 310 + (((char_num - 1) // 4) + 1) * 320
|
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 = crop_center_img(img, based_w, based_h)
|
||||||
img.paste(tag, (0, 0), tag)
|
img.paste(tag, (0, 0), tag)
|
||||||
|
|
||||||
img_draw = ImageDraw.Draw(img, 'RGBA')
|
img_draw = ImageDraw.Draw(img, "RGBA")
|
||||||
|
|
||||||
# 写底层文字
|
# 写底层文字
|
||||||
img_draw.text(
|
img_draw.text(
|
||||||
(690, based_h - 26),
|
(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),
|
(22, 22, 22),
|
||||||
fw_font_28,
|
fw_font_28,
|
||||||
'mm',
|
"mm",
|
||||||
)
|
)
|
||||||
|
|
||||||
img_draw.text(
|
img_draw.text(
|
||||||
@ -93,14 +91,14 @@ async def draw_enka_card(uid: str, char_list: List, showfrom: int = 0):
|
|||||||
line1,
|
line1,
|
||||||
white_color,
|
white_color,
|
||||||
sr_font_58,
|
sr_font_58,
|
||||||
'lm',
|
"lm",
|
||||||
)
|
)
|
||||||
img_draw.text(
|
img_draw.text(
|
||||||
(225, 175),
|
(225, 175),
|
||||||
line2,
|
line2,
|
||||||
gray_color,
|
gray_color,
|
||||||
sr_font_24,
|
sr_font_24,
|
||||||
'lm',
|
"lm",
|
||||||
)
|
)
|
||||||
tasks = []
|
tasks = []
|
||||||
for index, char_data in enumerate(char_data_list):
|
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):
|
async def draw_mihomo_char(index: int, img: Image.Image, char_data: Dict):
|
||||||
char_id = char_data['avatarId']
|
char_id = char_data["avatarId"]
|
||||||
char_name = char_data['avatarName']
|
char_name = char_data["avatarName"]
|
||||||
char_star = await avatar_id_to_char_star(str(char_id))
|
char_star = await avatar_id_to_char_star(str(char_id))
|
||||||
char_card = Image.open(TEXT_PATH / f'char{char_star}_bg.png')
|
char_card = Image.open(TEXT_PATH / f"char{char_star}_bg.png")
|
||||||
char_temp = Image.new('RGBA', (300, 650))
|
char_temp = Image.new("RGBA", (300, 650))
|
||||||
char_img = (
|
char_img = (
|
||||||
Image.open(str(CHAR_PREVIEW_PATH / f'{char_id}.png'))
|
Image.open(str(CHAR_PREVIEW_PATH / f"{char_id}.png"))
|
||||||
.convert('RGBA')
|
.convert("RGBA")
|
||||||
.resize((449, 615))
|
.resize((449, 615))
|
||||||
)
|
)
|
||||||
if char_name == '希儿':
|
if char_name == "希儿":
|
||||||
char_img = char_img.resize((449, 650))
|
char_img = char_img.resize((449, 650))
|
||||||
char_img = char_img.crop((135, 0, 379, 457))
|
char_img = char_img.crop((135, 0, 379, 457))
|
||||||
char_temp.paste(char_img, (32, 98), char_img)
|
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_temp.paste(char_img, (32, 38), char_img)
|
||||||
char_card.paste(char_temp, (0, 0), char_bg_mask)
|
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(
|
img_draw.text(
|
||||||
(150, 585),
|
(150, 585),
|
||||||
char_name,
|
char_name,
|
||||||
white_color,
|
white_color,
|
||||||
sr_font_30,
|
sr_font_30,
|
||||||
'mm',
|
"mm",
|
||||||
)
|
)
|
||||||
x = 42 + index * 325
|
x = 42 + index * 325
|
||||||
img.paste(char_card, (x, 199), char_card)
|
img.paste(char_card, (x, 199), char_card)
|
||||||
|
|
||||||
|
|
||||||
async def draw_enka_char(index: int, img: Image.Image, char_data: Dict):
|
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_star = await avatar_id_to_char_star(str(char_id))
|
||||||
char_card = Image.open(TEXT_PATH / f'ring_{char_star}.png')
|
char_card = Image.open(TEXT_PATH / f"ring_{char_star}.png")
|
||||||
_path = CHAR_PREVIEW_PATH / f'{char_id}.png'
|
_path = CHAR_PREVIEW_PATH / f"{char_id}.png"
|
||||||
char_img = Image.open(_path).convert('RGBA')
|
char_img = Image.open(_path).convert("RGBA")
|
||||||
char_img = char_img.resize(
|
char_img = char_img.resize(
|
||||||
(int(char_img.size[0] * 0.76), int(char_img.size[1] * 0.76))
|
(int(char_img.size[0] * 0.76), int(char_img.size[1] * 0.76))
|
||||||
)
|
)
|
||||||
|
|
||||||
char_temp = Image.new('RGBA', (300, 400))
|
char_temp = Image.new("RGBA", (300, 400))
|
||||||
card_temp = Image.new('RGBA', (300, 400))
|
card_temp = Image.new("RGBA", (300, 400))
|
||||||
char_temp.paste(char_img, (19, 57), char_img)
|
char_temp.paste(char_img, (19, 57), char_img)
|
||||||
card_temp.paste(char_temp, (0, 0), char_mask)
|
card_temp.paste(char_temp, (0, 0), char_mask)
|
||||||
|
|
||||||
char_draw = ImageDraw.Draw(card_temp)
|
char_draw = ImageDraw.Draw(card_temp)
|
||||||
char_draw.text(
|
char_draw.text(
|
||||||
(144, 285),
|
(144, 285),
|
||||||
char_data['avatarName'],
|
char_data["avatarName"],
|
||||||
'white',
|
"white",
|
||||||
sr_font_30,
|
sr_font_30,
|
||||||
'mm',
|
"mm",
|
||||||
)
|
)
|
||||||
|
|
||||||
img.paste(
|
img.paste(
|
||||||
|
@ -7,18 +7,16 @@ from gsuid_core.models import Event
|
|||||||
from gsuid_core.sv import SV
|
from gsuid_core.sv import SV
|
||||||
from gsuid_core.utils.database.models import GsBind
|
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):
|
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:
|
if uid is None:
|
||||||
return await bot.send('[星穹铁道] 你还没有绑定UID哦!')
|
return await bot.send("[星穹铁道] 你还没有绑定UID哦!")
|
||||||
logger.info(
|
logger.info(f"[{ev.user_id}] [UID{uid}]尝试[{ev.command[2:]}]了[{ev.text}]功能")
|
||||||
f'[{ev.user_id}] [UID{uid}]尝试[{ev.command[2:]}]了[{ev.text}]功能'
|
|
||||||
)
|
|
||||||
await bot.send(await set_config_func(uid, ev))
|
await bot.send(await set_config_func(uid, ev))
|
||||||
return None
|
return None
|
||||||
|
@ -4,47 +4,43 @@ from gsuid_core.utils.plugins_config.models import (
|
|||||||
GSC,
|
GSC,
|
||||||
GsStrConfig,
|
GsStrConfig,
|
||||||
GsBoolConfig,
|
GsBoolConfig,
|
||||||
GsListStrConfig, GsIntConfig,
|
GsListStrConfig,
|
||||||
|
GsIntConfig,
|
||||||
)
|
)
|
||||||
|
|
||||||
CONIFG_DEFAULT: Dict[str, GSC] = {
|
CONIFG_DEFAULT: Dict[str, GSC] = {
|
||||||
'SignTime': GsListStrConfig(
|
"SignTime": GsListStrConfig(
|
||||||
'每晚签到时间设置', '每晚米游社签到时间设置(时,分)', ['0', '38']
|
"每晚签到时间设置", "每晚米游社签到时间设置(时,分)", ["0", "38"]
|
||||||
),
|
),
|
||||||
'PrivateSignReport': GsBoolConfig(
|
"PrivateSignReport": GsBoolConfig(
|
||||||
'签到私聊报告',
|
"签到私聊报告",
|
||||||
'关闭后将不再给任何人推送当天签到任务完成情况',
|
"关闭后将不再给任何人推送当天签到任务完成情况",
|
||||||
False,
|
False,
|
||||||
),
|
),
|
||||||
'SchedSignin': GsBoolConfig(
|
"SchedSignin": GsBoolConfig(
|
||||||
'定时签到',
|
"定时签到",
|
||||||
'开启后每晚00:30将开始自动签到任务',
|
"开启后每晚00:30将开始自动签到任务",
|
||||||
True,
|
True,
|
||||||
),
|
),
|
||||||
'SchedStaminaPush': GsBoolConfig(
|
"SchedStaminaPush": GsBoolConfig(
|
||||||
'定时检查开拓力',
|
"定时检查开拓力",
|
||||||
'开启后每隔半小时检查一次开拓力',
|
"开启后每隔半小时检查一次开拓力",
|
||||||
True,
|
True,
|
||||||
),
|
),
|
||||||
'push_max_value': GsIntConfig(
|
"push_max_value": GsIntConfig("提醒阈值", "发送提醒的阈值", 200, 240),
|
||||||
'提醒阈值',
|
"CrazyNotice": GsBoolConfig(
|
||||||
'发送提醒的阈值',
|
"催命模式",
|
||||||
200,
|
"开启后当达到推送阈值将会一直推送",
|
||||||
240
|
|
||||||
),
|
|
||||||
'CrazyNotice': GsBoolConfig(
|
|
||||||
'催命模式',
|
|
||||||
'开启后当达到推送阈值将会一直推送',
|
|
||||||
False,
|
False,
|
||||||
),
|
),
|
||||||
'StarRailPrefix': GsStrConfig(
|
"StarRailPrefix": GsStrConfig(
|
||||||
'插件命令前缀(确认无冲突再修改)',
|
"插件命令前缀(确认无冲突再修改)",
|
||||||
'用于本插件的前缀设定',
|
"用于本插件的前缀设定",
|
||||||
'sr',
|
"sr",
|
||||||
),
|
),
|
||||||
'WidgetResin': GsBoolConfig(
|
"WidgetResin": GsBoolConfig(
|
||||||
'体力使用组件API',
|
"体力使用组件API",
|
||||||
'开启后mr功能将转为调用组件API, 可能缺失数据、数据不准',
|
"开启后mr功能将转为调用组件API, 可能缺失数据、数据不准",
|
||||||
True,
|
True,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
@ -8,26 +8,26 @@ async def set_config_func(
|
|||||||
uid: str,
|
uid: str,
|
||||||
ev: Event,
|
ev: Event,
|
||||||
):
|
):
|
||||||
if '开启' in ev.command:
|
if "开启" in ev.command:
|
||||||
if ev.user_type == 'direct':
|
if ev.user_type == "direct":
|
||||||
value = 'on'
|
value = "on"
|
||||||
elif ev.group_id:
|
elif ev.group_id:
|
||||||
value = ev.group_id
|
value = ev.group_id
|
||||||
else:
|
else:
|
||||||
value = 'on'
|
value = "on"
|
||||||
else:
|
else:
|
||||||
value = 'off'
|
value = "off"
|
||||||
|
|
||||||
text = await set_database_value(
|
text = await set_database_value(
|
||||||
GsUser,
|
GsUser,
|
||||||
'sr',
|
"sr",
|
||||||
'sr开启',
|
"sr开启",
|
||||||
ev.text.strip(),
|
ev.text.strip(),
|
||||||
uid,
|
uid,
|
||||||
ev.bot_id,
|
ev.bot_id,
|
||||||
value,
|
value,
|
||||||
)
|
)
|
||||||
if text is None:
|
if text is None:
|
||||||
return '[星穹铁道] 未找到配置项'
|
return "[星穹铁道] 未找到配置项"
|
||||||
logger.success(f'[UID{uid}]成功将配置[SR自动签到]设置为[{value}]!')
|
logger.success(f"[UID{uid}]成功将配置[SR自动签到]设置为[{value}]!")
|
||||||
return text
|
return text
|
||||||
|
@ -4,7 +4,7 @@ from .config_default import CONIFG_DEFAULT
|
|||||||
from ..utils.resource.RESOURCE_PATH import CONFIG_PATH
|
from ..utils.resource.RESOURCE_PATH import CONFIG_PATH
|
||||||
|
|
||||||
srconfig = StringConfig(
|
srconfig = StringConfig(
|
||||||
'StarRailUID',
|
"StarRailUID",
|
||||||
CONFIG_PATH,
|
CONFIG_PATH,
|
||||||
CONIFG_DEFAULT,
|
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.bot import Bot
|
||||||
from gsuid_core.models import Event
|
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
|
sv_gacha_log = SV("sr抽卡记录")
|
||||||
from ..utils.sr_prefix import PREFIX
|
sv_get_gachalog_by_link = SV("sr导入抽卡链接", area="DIRECT")
|
||||||
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.on_fullmatch(f'{PREFIX}抽卡记录')
|
@sv_gacha_log.on_fullmatch(f"{PREFIX}抽卡记录")
|
||||||
async def send_gacha_log_card_info(bot: Bot, ev: Event):
|
async def send_gacha_log_card_info(bot: Bot, ev: Event):
|
||||||
await bot.logger.info('开始执行[sr抽卡记录]')
|
await bot.logger.info("开始执行[sr抽卡记录]")
|
||||||
get_uid_ = await get_uid(bot, ev, True, False)
|
uid, user_id = await get_uid(bot, ev, GsBind, "sr", True)
|
||||||
if get_uid_ is None:
|
|
||||||
return await bot.send(UID_HINT)
|
|
||||||
uid, user_id = get_uid_
|
|
||||||
if uid is None:
|
if uid is None:
|
||||||
return await bot.send(UID_HINT)
|
return await bot.send(UID_HINT)
|
||||||
im = await draw_gachalogs_img(uid, user_id)
|
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
|
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):
|
async def get_gachalog_by_link(bot: Bot, ev: Event):
|
||||||
await bot.logger.info('开始执行[sr导入抽卡链接]')
|
await bot.logger.info("开始执行[sr导入抽卡链接]")
|
||||||
uid = await get_uid(bot, ev, only_uid=True)
|
uid = await get_uid(bot, ev, GsBind, "sr")
|
||||||
if uid is None:
|
if uid is None:
|
||||||
return await bot.send(UID_HINT)
|
return await bot.send(UID_HINT)
|
||||||
gacha_url = ev.text.strip()
|
gacha_url = ev.text.strip()
|
||||||
if not gacha_url or not isinstance(gacha_url, str):
|
if not gacha_url or not isinstance(gacha_url, str):
|
||||||
return await bot.send('请给出正确的抽卡记录链接')
|
return await bot.send("请给出正确的抽卡记录链接")
|
||||||
is_force = False
|
is_force = False
|
||||||
if ev.command.startswith('强制'):
|
if ev.command.startswith("强制"):
|
||||||
await bot.logger.info('[WARNING]本次为强制刷新')
|
await bot.logger.info("[WARNING]本次为强制刷新")
|
||||||
is_force = True
|
is_force = True
|
||||||
await bot.send(
|
await bot.send(f"UID{uid}开始执行[刷新抽卡记录],需要一定时间...请勿重复触发!")
|
||||||
f'UID{uid}开始执行[刷新抽卡记录],需要一定时间...请勿重复触发!'
|
|
||||||
)
|
|
||||||
im = await save_gachalogs(uid, gacha_url, None, is_force)
|
im = await save_gachalogs(uid, gacha_url, None, is_force)
|
||||||
return await bot.send(im)
|
return await bot.send(im)
|
||||||
|
@ -1,24 +1,9 @@
|
|||||||
import json
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import datetime
|
import datetime
|
||||||
|
import json
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import List, Tuple, Union
|
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 (
|
from ..utils.fonts.starrail_fonts import (
|
||||||
sr_font_20,
|
sr_font_20,
|
||||||
sr_font_24,
|
sr_font_24,
|
||||||
@ -26,13 +11,28 @@ from ..utils.fonts.starrail_fonts import (
|
|||||||
sr_font_38,
|
sr_font_38,
|
||||||
sr_font_40,
|
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'
|
from PIL import Image, ImageDraw
|
||||||
EMO_PATH = Path(__file__).parent / 'texture2d' / 'emo'
|
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')
|
# up_tag = Image.open(TEXT_PATH / 'up.png')
|
||||||
Abg3_img = Image.open(TEXT_PATH / 'Abg3.png')
|
Abg3_img = Image.open(TEXT_PATH / "Abg3.png")
|
||||||
bg1_img = Image.open(TEXT_PATH / 'bg1.png')
|
bg1_img = Image.open(TEXT_PATH / "bg1.png")
|
||||||
|
|
||||||
first_color = (29, 29, 29)
|
first_color = (29, 29, 29)
|
||||||
brown_color = (41, 25, 0)
|
brown_color = (41, 25, 0)
|
||||||
@ -42,33 +42,33 @@ white_color = (213, 213, 213)
|
|||||||
whole_white_color = (255, 255, 255)
|
whole_white_color = (255, 255, 255)
|
||||||
|
|
||||||
CHANGE_MAP = {
|
CHANGE_MAP = {
|
||||||
'始发跃迁': 'begin',
|
"始发跃迁": "begin",
|
||||||
'群星跃迁': 'normal',
|
"群星跃迁": "normal",
|
||||||
'角色跃迁': 'char',
|
"角色跃迁": "char",
|
||||||
'光锥跃迁': 'weapon',
|
"光锥跃迁": "weapon",
|
||||||
}
|
}
|
||||||
HOMO_TAG = ['非到极致', '运气不好', '平稳保底', '小欧一把', '欧狗在此']
|
HOMO_TAG = ["非到极致", "运气不好", "平稳保底", "小欧一把", "欧狗在此"]
|
||||||
NORMAL_LIST = [
|
NORMAL_LIST = [
|
||||||
'彦卿',
|
"彦卿",
|
||||||
'白露',
|
"白露",
|
||||||
'姬子',
|
"姬子",
|
||||||
'瓦尔特',
|
"瓦尔特",
|
||||||
'布洛妮娅',
|
"布洛妮娅",
|
||||||
'克拉拉',
|
"克拉拉",
|
||||||
'杰帕德',
|
"杰帕德",
|
||||||
'银河铁道之夜',
|
"银河铁道之夜",
|
||||||
'以世界之名',
|
"以世界之名",
|
||||||
'但战斗还未结束',
|
"但战斗还未结束",
|
||||||
'制胜的瞬间',
|
"制胜的瞬间",
|
||||||
'无可取代的东西',
|
"无可取代的东西",
|
||||||
'时节不居',
|
"时节不居",
|
||||||
'如泥酣眠',
|
"如泥酣眠",
|
||||||
]
|
]
|
||||||
|
|
||||||
UP_LIST = {
|
UP_LIST = {
|
||||||
'刻晴': [(2021, 2, 17, 18, 0, 0), (2021, 3, 2, 15, 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)],
|
"提纳里": [(2022, 8, 24, 11, 0, 0), (2022, 9, 9, 17, 59, 59)],
|
||||||
'迪希雅': [(2023, 3, 1, 11, 0, 0), (2023, 3, 21, 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,
|
gacha_num: int,
|
||||||
is_up: bool,
|
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)
|
card_img_draw = ImageDraw.Draw(card_img)
|
||||||
point = (47, 31)
|
point = (47, 31)
|
||||||
text_point = (100, 165)
|
text_point = (100, 165)
|
||||||
if card_type == '角色':
|
if card_type == "角色":
|
||||||
_id = await name_to_avatar_id(name)
|
_id = await name_to_avatar_id(name)
|
||||||
item_pic = (
|
item_pic = (
|
||||||
Image.open(CHAR_ICON_PATH / f'{_id}.png')
|
Image.open(CHAR_ICON_PATH / f"{_id}.png").convert("RGBA").resize((105, 105))
|
||||||
.convert('RGBA')
|
|
||||||
.resize((105, 105))
|
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
name = await name_to_weapon_id(name)
|
name = await name_to_weapon_id(name)
|
||||||
# _id = await weapon_id_to_en_name(name)
|
# _id = await weapon_id_to_en_name(name)
|
||||||
item_pic = (
|
item_pic = (
|
||||||
Image.open(WEAPON_PATH / f'{name}.png')
|
Image.open(WEAPON_PATH / f"{name}.png").convert("RGBA").resize((124, 124))
|
||||||
.convert('RGBA')
|
|
||||||
.resize((124, 124))
|
|
||||||
)
|
)
|
||||||
point = (37, 24)
|
point = (37, 24)
|
||||||
card_img.paste(item_pic, point, item_pic)
|
card_img.paste(item_pic, point, item_pic)
|
||||||
@ -107,17 +103,15 @@ async def _draw_card(
|
|||||||
text_color = green_color
|
text_color = green_color
|
||||||
else:
|
else:
|
||||||
text_color = brown_color
|
text_color = brown_color
|
||||||
card_img_draw.text(
|
card_img_draw.text(text_point, f"{gacha_num}抽", text_color, sr_font_24, "mm")
|
||||||
text_point, f'{gacha_num}抽', text_color, sr_font_24, 'mm'
|
|
||||||
)
|
|
||||||
if is_up:
|
if is_up:
|
||||||
logger.info(f'up: {name}')
|
logger.info(f"up: {name}")
|
||||||
# card_img.paste(up_tag, (47, -2), up_tag)
|
# card_img.paste(up_tag, (47, -2), up_tag)
|
||||||
img.paste(card_img, xy_point, card_img)
|
img.paste(card_img, xy_point, card_img)
|
||||||
|
|
||||||
|
|
||||||
async def random_emo_pic(level: int) -> Image.Image:
|
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)
|
return Image.open(emo_fold)
|
||||||
|
|
||||||
|
|
||||||
@ -140,7 +134,7 @@ def check_up(name: str, _time: str) -> bool:
|
|||||||
time = UP_LIST[char]
|
time = UP_LIST[char]
|
||||||
s_time = datetime.datetime(*time[0])
|
s_time = datetime.datetime(*time[0])
|
||||||
e_time = datetime.datetime(*time[1])
|
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:
|
if gacha_time < s_time or gacha_time > e_time:
|
||||||
return False
|
return False
|
||||||
return True
|
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]:
|
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():
|
if not path.exists():
|
||||||
return '你还没有跃迁数据噢~\n请使用命令`sr导入抽卡链接`更新跃迁数据~'
|
return "你还没有跃迁数据噢~\n请使用命令`sr导入抽卡链接`更新跃迁数据~"
|
||||||
with Path.open(path, encoding='UTF-8') as f:
|
with Path.open(path, encoding="UTF-8") as f:
|
||||||
gacha_data = json.load(f)
|
gacha_data = json.load(f)
|
||||||
|
|
||||||
# 数据初始化
|
# 数据初始化
|
||||||
total_data = {}
|
total_data = {}
|
||||||
for i in ['群星跃迁', '始发跃迁', '角色跃迁', '光锥跃迁']:
|
for i in ["群星跃迁", "始发跃迁", "角色跃迁", "光锥跃迁"]:
|
||||||
total_data[i] = {
|
total_data[i] = {
|
||||||
'total': 0, # 五星总数
|
"total": 0, # 五星总数
|
||||||
'avg': 0, # 抽卡平均数
|
"avg": 0, # 抽卡平均数
|
||||||
'avg_up': 0, # up平均数
|
"avg_up": 0, # up平均数
|
||||||
'remain': 0, # 已xx抽未出金
|
"remain": 0, # 已xx抽未出金
|
||||||
'r_num': [], # 不包含首位的抽卡数量
|
"r_num": [], # 不包含首位的抽卡数量
|
||||||
'e_num': [], # 包含首位的up抽卡数量
|
"e_num": [], # 包含首位的up抽卡数量
|
||||||
'up_list': [], # 抽到的UP列表(不包含首位)
|
"up_list": [], # 抽到的UP列表(不包含首位)
|
||||||
'normal_list': [], # 抽到的五星列表(不包含首位)
|
"normal_list": [], # 抽到的五星列表(不包含首位)
|
||||||
'list': [], # 抽到的五星列表
|
"list": [], # 抽到的五星列表
|
||||||
'time_range': '', # 抽卡时间
|
"time_range": "", # 抽卡时间
|
||||||
'all_time': 0, # 抽卡总计秒数
|
"all_time": 0, # 抽卡总计秒数
|
||||||
'type': '一般型', # 抽卡类型: 随缘型, 氪金型, 规划型, 仓鼠型, 佛系型
|
"type": "一般型", # 抽卡类型: 随缘型, 氪金型, 规划型, 仓鼠型, 佛系型
|
||||||
'short_gacha_data': {'time': 0, 'num': 0},
|
"short_gacha_data": {"time": 0, "num": 0},
|
||||||
'long_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
|
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]):
|
for index, data in enumerate(data_list[::-1]):
|
||||||
# 计算抽卡时间跨度
|
# 计算抽卡时间跨度
|
||||||
if index == 0:
|
if index == 0:
|
||||||
total_data[i]['time_range'] = data['time']
|
total_data[i]["time_range"] = data["time"]
|
||||||
if index == len(data_list) - 1:
|
if index == len(data_list) - 1:
|
||||||
total_data[i]['all_time'] = (
|
total_data[i]["all_time"] = (
|
||||||
datetime.datetime.strptime(
|
datetime.datetime.strptime(data["time"], "%Y-%m-%d %H:%M:%S")
|
||||||
data['time'], '%Y-%m-%d %H:%M:%S'
|
|
||||||
)
|
|
||||||
- datetime.datetime.strptime(
|
- 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_seconds()
|
||||||
total_data[i]['time_range'] += '~' + data['time']
|
total_data[i]["time_range"] += "~" + data["time"]
|
||||||
|
|
||||||
# 计算时间间隔
|
# 计算时间间隔
|
||||||
if index != 0:
|
if index != 0:
|
||||||
now_time = datetime.datetime.strptime(
|
now_time = datetime.datetime.strptime(data["time"], "%Y-%m-%d %H:%M:%S")
|
||||||
data['time'], '%Y-%m-%d %H:%M:%S'
|
|
||||||
)
|
|
||||||
dis = (now_time - temp_time).total_seconds()
|
dis = (now_time - temp_time).total_seconds()
|
||||||
temp_time = now_time
|
temp_time = now_time
|
||||||
if dis <= 5000:
|
if dis <= 5000:
|
||||||
total_data[i]['short_gacha_data']['num'] += 1
|
total_data[i]["short_gacha_data"]["num"] += 1
|
||||||
total_data[i]['short_gacha_data']['time'] += dis
|
total_data[i]["short_gacha_data"]["time"] += dis
|
||||||
elif dis >= 86400:
|
elif dis >= 86400:
|
||||||
total_data[i]['long_gacha_data']['num'] += 1
|
total_data[i]["long_gacha_data"]["num"] += 1
|
||||||
total_data[i]['long_gacha_data']['time'] += dis
|
total_data[i]["long_gacha_data"]["time"] += dis
|
||||||
else:
|
else:
|
||||||
temp_time = datetime.datetime.strptime(
|
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
|
# 判断是否是UP
|
||||||
if data['name'] in NORMAL_LIST:
|
if data["name"] in NORMAL_LIST:
|
||||||
data['is_up'] = False
|
data["is_up"] = False
|
||||||
elif data['name'] in UP_LIST:
|
elif data["name"] in UP_LIST:
|
||||||
data['is_up'] = check_up(data['name'], data['time'])
|
data["is_up"] = check_up(data["name"], data["time"])
|
||||||
else:
|
else:
|
||||||
data['is_up'] = True
|
data["is_up"] = True
|
||||||
|
|
||||||
# 往里加东西
|
# 往里加东西
|
||||||
if is_not_first:
|
if is_not_first:
|
||||||
total_data[i]['r_num'].append(num)
|
total_data[i]["r_num"].append(num)
|
||||||
total_data[i]['normal_list'].append(data)
|
total_data[i]["normal_list"].append(data)
|
||||||
if data['is_up']:
|
if data["is_up"]:
|
||||||
total_data[i]['up_list'].append(data)
|
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
|
is_not_first = True
|
||||||
|
|
||||||
num = 1
|
num = 1
|
||||||
# 五星总数增加1
|
# 五星总数增加1
|
||||||
total_data[i]['total'] += 1
|
total_data[i]["total"] += 1
|
||||||
else:
|
else:
|
||||||
num += 1
|
num += 1
|
||||||
|
|
||||||
# 计算已多少抽
|
# 计算已多少抽
|
||||||
total_data[i]['remain'] = num - 1
|
total_data[i]["remain"] = num - 1
|
||||||
|
|
||||||
# 计算平均抽卡数
|
# 计算平均抽卡数
|
||||||
if len(total_data[i]['normal_list']) == 0:
|
if len(total_data[i]["normal_list"]) == 0:
|
||||||
total_data[i]['avg'] = 0
|
total_data[i]["avg"] = 0
|
||||||
else:
|
else:
|
||||||
total_data[i]['avg'] = float(
|
total_data[i]["avg"] = float(
|
||||||
'{:.2f}'.format(
|
"{:.2f}".format(
|
||||||
sum(total_data[i]['r_num']) / len(total_data[i]['r_num'])
|
sum(total_data[i]["r_num"]) / len(total_data[i]["r_num"])
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
# 计算平均up数量
|
# 计算平均up数量
|
||||||
if len(total_data[i]['up_list']) == 0:
|
if len(total_data[i]["up_list"]) == 0:
|
||||||
total_data[i]['avg_up'] = 0
|
total_data[i]["avg_up"] = 0
|
||||||
else:
|
else:
|
||||||
total_data[i]['avg_up'] = float(
|
total_data[i]["avg_up"] = float(
|
||||||
'{:.2f}'.format(
|
"{:.2f}".format(
|
||||||
sum(total_data[i]['r_num']) / len(total_data[i]['up_list'])
|
sum(total_data[i]["r_num"]) / len(total_data[i]["up_list"])
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
# 计算抽卡类型
|
# 计算抽卡类型
|
||||||
# 如果抽卡总数小于40
|
# 如果抽卡总数小于40
|
||||||
if gacha_data[f'{CHANGE_MAP[i]}_gacha_num'] <= 40:
|
if gacha_data[f"{CHANGE_MAP[i]}_gacha_num"] <= 40:
|
||||||
total_data[i]['type'] = '佛系型'
|
total_data[i]["type"] = "佛系型"
|
||||||
# 如果长时抽卡总数占据了总抽卡数的70%
|
# 如果长时抽卡总数占据了总抽卡数的70%
|
||||||
elif (
|
elif (
|
||||||
total_data[i]['long_gacha_data']['num']
|
total_data[i]["long_gacha_data"]["num"]
|
||||||
/ gacha_data[f'{CHANGE_MAP[i]}_gacha_num']
|
/ gacha_data[f"{CHANGE_MAP[i]}_gacha_num"]
|
||||||
>= 0.7
|
>= 0.7
|
||||||
):
|
):
|
||||||
total_data[i]['type'] = '随缘型'
|
total_data[i]["type"] = "随缘型"
|
||||||
# 如果短时抽卡总数占据了总抽卡数的70%
|
# 如果短时抽卡总数占据了总抽卡数的70%
|
||||||
elif (
|
elif (
|
||||||
total_data[i]['short_gacha_data']['num']
|
total_data[i]["short_gacha_data"]["num"]
|
||||||
/ gacha_data[f'{CHANGE_MAP[i]}_gacha_num']
|
/ gacha_data[f"{CHANGE_MAP[i]}_gacha_num"]
|
||||||
>= 0.7
|
>= 0.7
|
||||||
):
|
):
|
||||||
total_data[i]['type'] = '规划型'
|
total_data[i]["type"] = "规划型"
|
||||||
# 如果抽卡数量远远大于标称抽卡数量
|
# 如果抽卡数量远远大于标称抽卡数量
|
||||||
elif (
|
elif (
|
||||||
total_data[i]['all_time'] / 30000
|
total_data[i]["all_time"] / 30000
|
||||||
<= gacha_data[f'{CHANGE_MAP[i]}_gacha_num']
|
<= gacha_data[f"{CHANGE_MAP[i]}_gacha_num"]
|
||||||
):
|
):
|
||||||
# 如果长时抽卡数量大于短时抽卡数量
|
# 如果长时抽卡数量大于短时抽卡数量
|
||||||
if (
|
if (
|
||||||
total_data[i]['long_gacha_data']['num']
|
total_data[i]["long_gacha_data"]["num"]
|
||||||
>= total_data[i]['short_gacha_data']['num']
|
>= total_data[i]["short_gacha_data"]["num"]
|
||||||
):
|
):
|
||||||
total_data[i]['type'] = '规划型'
|
total_data[i]["type"] = "规划型"
|
||||||
else:
|
else:
|
||||||
total_data[i]['type'] = '氪金型'
|
total_data[i]["type"] = "氪金型"
|
||||||
# 如果抽卡数量远远小于标称抽卡数量
|
# 如果抽卡数量远远小于标称抽卡数量
|
||||||
elif (
|
elif (
|
||||||
total_data[i]['all_time'] / 32000
|
total_data[i]["all_time"] / 32000
|
||||||
>= gacha_data[f'{CHANGE_MAP[i]}_gacha_num'] * 2
|
>= gacha_data[f"{CHANGE_MAP[i]}_gacha_num"] * 2
|
||||||
):
|
):
|
||||||
total_data[i]['type'] = '仓鼠型'
|
total_data[i]["type"] = "仓鼠型"
|
||||||
|
|
||||||
# 常量偏移数据
|
# 常量偏移数据
|
||||||
single_y = 170
|
single_y = 170
|
||||||
|
|
||||||
# 计算图片尺寸
|
# 计算图片尺寸
|
||||||
normal_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
|
begin_y = (1 + ((total_data["始发跃迁"]["total"] - 1) // 5)) * single_y
|
||||||
char_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
|
weapon_y = (1 + ((total_data["光锥跃迁"]["total"] - 1) // 5)) * single_y
|
||||||
|
|
||||||
# 获取背景图片各项参数
|
# 获取背景图片各项参数
|
||||||
_id = str(user_id)
|
_id = str(user_id)
|
||||||
if _id.startswith('http'):
|
if _id.startswith("http"):
|
||||||
char_pic = await get_qq_avatar(avatar_url=_id)
|
char_pic = await get_qq_avatar(avatar_url=_id)
|
||||||
else:
|
else:
|
||||||
char_pic = await get_qq_avatar(qid=user_id)
|
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 = Abg3_img.copy()
|
||||||
img = await get_color_bg(
|
img = await get_color_bg(800, 1600 + 400 + normal_y + char_y + weapon_y + begin_y)
|
||||||
800, 1600 + 400 + normal_y + char_y + weapon_y + begin_y
|
|
||||||
)
|
|
||||||
gacha_title = bg1_img.copy()
|
gacha_title = bg1_img.copy()
|
||||||
gacha_title.paste(char_pic, (297, 81), char_pic)
|
gacha_title.paste(char_pic, (297, 81), char_pic)
|
||||||
img.paste(gacha_title, (0, 0), gacha_title)
|
img.paste(gacha_title, (0, 0), gacha_title)
|
||||||
img_draw = ImageDraw.Draw(img)
|
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
|
# 处理title
|
||||||
# {'total': 0, 'avg': 0, 'remain': 0, 'list': []}
|
# {'total': 0, 'avg': 0, 'remain': 0, 'list': []}
|
||||||
type_list = ['角色跃迁', '光锥跃迁', '群星跃迁', '始发跃迁']
|
type_list = ["角色跃迁", "光锥跃迁", "群星跃迁", "始发跃迁"]
|
||||||
y_extend = 0
|
y_extend = 0
|
||||||
level = 3
|
level = 3
|
||||||
for index, i in enumerate(type_list):
|
for index, i in enumerate(type_list):
|
||||||
title = Image.open(TEXT_PATH / 'bg2.png')
|
title = Image.open(TEXT_PATH / "bg2.png")
|
||||||
if i == '群星跃迁':
|
if i == "群星跃迁":
|
||||||
level = await get_level_from_list(
|
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(
|
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(
|
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:
|
else:
|
||||||
level = await get_level_from_list(
|
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)
|
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.paste(emo_pic, (500, 123), emo_pic)
|
||||||
title_draw = ImageDraw.Draw(title)
|
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']:
|
if total_data[i]["time_range"]:
|
||||||
time_range = total_data[i]['time_range']
|
time_range = total_data[i]["time_range"]
|
||||||
else:
|
else:
|
||||||
time_range = '暂未抽过卡!'
|
time_range = "暂未抽过卡!"
|
||||||
title_draw.text((78, 340), time_range, brown_color, sr_font_20, 'lm')
|
title_draw.text((78, 340), time_range, brown_color, sr_font_20, "lm")
|
||||||
# 平均抽卡数量
|
# 平均抽卡数量
|
||||||
title_draw.text(
|
title_draw.text(
|
||||||
(143, 215),
|
(143, 215),
|
||||||
str(total_data[i]['avg']),
|
str(total_data[i]["avg"]),
|
||||||
first_color,
|
first_color,
|
||||||
sr_font_40,
|
sr_font_40,
|
||||||
'mm',
|
"mm",
|
||||||
)
|
)
|
||||||
# 平均up
|
# 平均up
|
||||||
title_draw.text(
|
title_draw.text(
|
||||||
(280, 215),
|
(280, 215),
|
||||||
str(total_data[i]['avg_up']),
|
str(total_data[i]["avg_up"]),
|
||||||
first_color,
|
first_color,
|
||||||
sr_font_40,
|
sr_font_40,
|
||||||
'mm',
|
"mm",
|
||||||
)
|
)
|
||||||
# 抽卡总数
|
# 抽卡总数
|
||||||
title_draw.text(
|
title_draw.text(
|
||||||
(413, 215),
|
(413, 215),
|
||||||
str(gacha_data[f'{CHANGE_MAP[i]}_gacha_num']),
|
str(gacha_data[f"{CHANGE_MAP[i]}_gacha_num"]),
|
||||||
first_color,
|
first_color,
|
||||||
sr_font_40,
|
sr_font_40,
|
||||||
'mm',
|
"mm",
|
||||||
)
|
)
|
||||||
# 已抽数
|
# 已抽数
|
||||||
title_draw.text(
|
title_draw.text(
|
||||||
(333, 75),
|
(333, 75),
|
||||||
str(total_data[i]['remain']),
|
str(total_data[i]["remain"]),
|
||||||
red_color,
|
red_color,
|
||||||
sr_font_28,
|
sr_font_28,
|
||||||
'mm',
|
"mm",
|
||||||
)
|
)
|
||||||
y_extend += (
|
y_extend += (
|
||||||
(1 + ((total_data[type_list[index - 1]]['total'] - 1) // 5))
|
(1 + ((total_data[type_list[index - 1]]["total"] - 1) // 5)) * single_y
|
||||||
* single_y
|
|
||||||
if index != 0
|
if index != 0
|
||||||
else 0
|
else 0
|
||||||
)
|
)
|
||||||
y = 350 + index * 400 + y_extend
|
y = 350 + index * 400 + y_extend
|
||||||
img.paste(title, (0, y), title)
|
img.paste(title, (0, y), title)
|
||||||
tasks = []
|
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_x = (item_index % 5) * 138 + 25
|
||||||
item_y = (item_index // 5) * single_y + y + 355
|
item_y = (item_index // 5) * single_y + y + 355
|
||||||
xy_point = (item_x, item_y)
|
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(
|
_draw_card(
|
||||||
img,
|
img,
|
||||||
xy_point,
|
xy_point,
|
||||||
item['item_type'],
|
item["item_type"],
|
||||||
item['name'],
|
item["name"],
|
||||||
item['gacha_num'],
|
item["gacha_num"],
|
||||||
item['is_up'],
|
item["is_up"],
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
await asyncio.gather(*tasks)
|
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)
|
res = await convert_img(img)
|
||||||
logger.info('[查询抽卡]绘图已完成,等待发送!')
|
logger.info("[查询抽卡]绘图已完成,等待发送!")
|
||||||
# res = 123
|
# res = 123
|
||||||
return res
|
return res
|
||||||
|
@ -12,29 +12,27 @@ from ..utils.resource.RESOURCE_PATH import PLAYER_PATH
|
|||||||
from ..sruid_utils.api.mys.models import SingleGachaLog
|
from ..sruid_utils.api.mys.models import SingleGachaLog
|
||||||
|
|
||||||
gacha_type_meta_data = {
|
gacha_type_meta_data = {
|
||||||
'群星跃迁': ['1'],
|
"群星跃迁": ["1"],
|
||||||
'始发跃迁': ['2'],
|
"始发跃迁": ["2"],
|
||||||
'角色跃迁': ['11'],
|
"角色跃迁": ["11"],
|
||||||
'光锥跃迁': ['12'],
|
"光锥跃迁": ["12"],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async def get_new_gachalog_by_link(
|
async def get_new_gachalog_by_link(
|
||||||
uid: str, gacha_url: str, full_data: Dict, is_force: bool
|
uid: str, gacha_url: str, full_data: Dict, is_force: bool
|
||||||
):
|
):
|
||||||
full_data = msgspec.convert(
|
full_data = msgspec.convert(full_data, type=Dict[str, List[SingleGachaLog]])
|
||||||
full_data, type=Dict[str, List[SingleGachaLog]]
|
|
||||||
)
|
|
||||||
temp = []
|
temp = []
|
||||||
for gacha_name in gacha_type_meta_data:
|
for gacha_name in gacha_type_meta_data:
|
||||||
for gacha_type in gacha_type_meta_data[gacha_name]:
|
for gacha_type in gacha_type_meta_data[gacha_name]:
|
||||||
end_id = '0'
|
end_id = "0"
|
||||||
for page in range(1, 999):
|
for page in range(1, 999):
|
||||||
url = parse.urlparse(gacha_url)
|
url = parse.urlparse(gacha_url)
|
||||||
url_parse = parse.parse_qs(url.query)
|
url_parse = parse.parse_qs(url.query)
|
||||||
if 'authkey' not in url_parse:
|
if "authkey" not in url_parse:
|
||||||
return {}
|
return {}
|
||||||
authkey = url_parse['authkey'][0]
|
authkey = url_parse["authkey"][0]
|
||||||
data = await mys_api.get_gacha_log_by_link_in_authkey(
|
data = await mys_api.get_gacha_log_by_link_in_authkey(
|
||||||
uid, authkey, gacha_type, page, end_id
|
uid, authkey, gacha_type, page, end_id
|
||||||
)
|
)
|
||||||
@ -74,13 +72,13 @@ async def save_gachalogs(
|
|||||||
|
|
||||||
# 获取当前时间
|
# 获取当前时间
|
||||||
now = datetime.now()
|
now = datetime.now()
|
||||||
current_time = now.strftime('%Y-%m-%d %H-%M-%S')
|
current_time = now.strftime("%Y-%m-%d %H-%M-%S")
|
||||||
|
|
||||||
# 初始化最后保存的数据
|
# 初始化最后保存的数据
|
||||||
result = {}
|
result = {}
|
||||||
|
|
||||||
# 抽卡记录json路径
|
# 抽卡记录json路径
|
||||||
gachalogs_path = path / 'gacha_logs.json'
|
gachalogs_path = path / "gacha_logs.json"
|
||||||
|
|
||||||
# 如果有老的,准备合并, 先打开文件
|
# 如果有老的,准备合并, 先打开文件
|
||||||
gachalogs_history = {}
|
gachalogs_history = {}
|
||||||
@ -91,19 +89,19 @@ async def save_gachalogs(
|
|||||||
old_weapon_gacha_num,
|
old_weapon_gacha_num,
|
||||||
) = (0, 0, 0, 0)
|
) = (0, 0, 0, 0)
|
||||||
if gachalogs_path.exists():
|
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: Dict = json.load(f)
|
||||||
gachalogs_history = gachalogs_history['data']
|
gachalogs_history = gachalogs_history["data"]
|
||||||
old_normal_gacha_num = len(gachalogs_history['群星跃迁'])
|
old_normal_gacha_num = len(gachalogs_history["群星跃迁"])
|
||||||
old_begin_gacha_num = len(gachalogs_history['始发跃迁'])
|
old_begin_gacha_num = len(gachalogs_history["始发跃迁"])
|
||||||
old_char_gacha_num = len(gachalogs_history['角色跃迁'])
|
old_char_gacha_num = len(gachalogs_history["角色跃迁"])
|
||||||
old_weapon_gacha_num = len(gachalogs_history['光锥跃迁'])
|
old_weapon_gacha_num = len(gachalogs_history["光锥跃迁"])
|
||||||
else:
|
else:
|
||||||
gachalogs_history = {
|
gachalogs_history = {
|
||||||
'群星跃迁': [],
|
"群星跃迁": [],
|
||||||
'始发跃迁': [],
|
"始发跃迁": [],
|
||||||
'角色跃迁': [],
|
"角色跃迁": [],
|
||||||
'光锥跃迁': [],
|
"光锥跃迁": [],
|
||||||
}
|
}
|
||||||
|
|
||||||
# 获取新抽卡记录
|
# 获取新抽卡记录
|
||||||
@ -113,69 +111,66 @@ async def save_gachalogs(
|
|||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
new_data = {
|
new_data = {
|
||||||
'始发跃迁': [],
|
"始发跃迁": [],
|
||||||
'群星跃迁': [],
|
"群星跃迁": [],
|
||||||
'角色跃迁': [],
|
"角色跃迁": [],
|
||||||
'光锥跃迁': [],
|
"光锥跃迁": [],
|
||||||
}
|
}
|
||||||
if gachalogs_history:
|
if gachalogs_history:
|
||||||
for i in ['始发跃迁', '群星跃迁', '角色跃迁', '光锥跃迁']:
|
for i in ["始发跃迁", "群星跃迁", "角色跃迁", "光锥跃迁"]:
|
||||||
for item in raw_data[i]:
|
for item in raw_data[i]:
|
||||||
if (
|
if item not in gachalogs_history[i] and item not in new_data[i]:
|
||||||
item not in gachalogs_history[i]
|
|
||||||
and item not in new_data[i]
|
|
||||||
):
|
|
||||||
new_data[i].append(item)
|
new_data[i].append(item)
|
||||||
raw_data = new_data
|
raw_data = new_data
|
||||||
for i in ['始发跃迁', '群星跃迁', '角色跃迁', '光锥跃迁']:
|
for i in ["始发跃迁", "群星跃迁", "角色跃迁", "光锥跃迁"]:
|
||||||
raw_data[i].extend(gachalogs_history[i])
|
raw_data[i].extend(gachalogs_history[i])
|
||||||
|
|
||||||
if raw_data == {} or not raw_data:
|
if raw_data == {} or not raw_data:
|
||||||
return '请给出正确的抽卡记录链接或链接已失效'
|
return "请给出正确的抽卡记录链接或链接已失效"
|
||||||
|
|
||||||
temp_data = {
|
temp_data = {
|
||||||
'始发跃迁': [],
|
"始发跃迁": [],
|
||||||
'群星跃迁': [],
|
"群星跃迁": [],
|
||||||
'角色跃迁': [],
|
"角色跃迁": [],
|
||||||
'光锥跃迁': [],
|
"光锥跃迁": [],
|
||||||
}
|
}
|
||||||
for i in ['始发跃迁', '群星跃迁', '角色跃迁', '光锥跃迁']:
|
for i in ["始发跃迁", "群星跃迁", "角色跃迁", "光锥跃迁"]:
|
||||||
for item in raw_data[i]:
|
for item in raw_data[i]:
|
||||||
if item not in temp_data[i]:
|
if item not in temp_data[i]:
|
||||||
temp_data[i].append(item)
|
temp_data[i].append(item)
|
||||||
raw_data = temp_data
|
raw_data = temp_data
|
||||||
|
|
||||||
result['uid'] = uid
|
result["uid"] = uid
|
||||||
result['data_time'] = current_time
|
result["data_time"] = current_time
|
||||||
result['normal_gacha_num'] = len(raw_data['群星跃迁'])
|
result["normal_gacha_num"] = len(raw_data["群星跃迁"])
|
||||||
result['begin_gacha_num'] = len(raw_data['始发跃迁'])
|
result["begin_gacha_num"] = len(raw_data["始发跃迁"])
|
||||||
result['char_gacha_num'] = len(raw_data['角色跃迁'])
|
result["char_gacha_num"] = len(raw_data["角色跃迁"])
|
||||||
result['weapon_gacha_num'] = len(raw_data['光锥跃迁'])
|
result["weapon_gacha_num"] = len(raw_data["光锥跃迁"])
|
||||||
for i in ['群星跃迁', '角色跃迁', '光锥跃迁']:
|
for i in ["群星跃迁", "角色跃迁", "光锥跃迁"]:
|
||||||
if len(raw_data[i]) > 1:
|
if len(raw_data[i]) > 1:
|
||||||
raw_data[i].sort(key=lambda x: (-int(x.id)))
|
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
|
normal_add = result["normal_gacha_num"] - old_normal_gacha_num
|
||||||
begin_gacha_add = result['begin_gacha_num'] - old_begin_gacha_num
|
begin_gacha_add = result["begin_gacha_num"] - old_begin_gacha_num
|
||||||
char_add = result['char_gacha_num'] - old_char_gacha_num
|
char_add = result["char_gacha_num"] - old_char_gacha_num
|
||||||
weapon_add = result['weapon_gacha_num'] - old_weapon_gacha_num
|
weapon_add = result["weapon_gacha_num"] - old_weapon_gacha_num
|
||||||
all_add = normal_add + char_add + weapon_add + begin_gacha_add
|
all_add = normal_add + char_add + weapon_add + begin_gacha_add
|
||||||
|
|
||||||
# 保存文件
|
# 保存文件
|
||||||
result = msgspec.to_builtins(result)
|
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)
|
json.dump(result, file, indent=2, ensure_ascii=False)
|
||||||
|
|
||||||
# 回复文字
|
# 回复文字
|
||||||
if all_add == 0:
|
if all_add == 0:
|
||||||
im = f'UID{uid}没有新增祈愿数据!'
|
im = f"UID{uid}没有新增祈愿数据!"
|
||||||
else:
|
else:
|
||||||
im = (
|
im = (
|
||||||
f'UID{uid}数据更新成功!'
|
f"UID{uid}数据更新成功!"
|
||||||
f'本次更新{all_add}个数据\n'
|
f"本次更新{all_add}个数据\n"
|
||||||
f'群星跃迁{normal_add}个\n始发跃迁{begin_gacha_add}\n'
|
f"群星跃迁{normal_add}个\n始发跃迁{begin_gacha_add}\n"
|
||||||
f'角色跃迁{char_add}个\n光锥跃迁{weapon_add}个!'
|
f"角色跃迁{char_add}个\n光锥跃迁{weapon_add}个!"
|
||||||
)
|
)
|
||||||
return im
|
return im
|
||||||
|
@ -6,11 +6,11 @@ from gsuid_core.logger import logger
|
|||||||
from .get_help import get_core_help
|
from .get_help import get_core_help
|
||||||
from ..utils.sr_prefix import PREFIX
|
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):
|
async def send_help_img(bot: Bot, ev: Event):
|
||||||
logger.info('开始执行[sr帮助]')
|
logger.info("开始执行[sr帮助]")
|
||||||
im = await get_core_help()
|
im = await get_core_help()
|
||||||
await bot.send(im)
|
await bot.send(im)
|
||||||
|
@ -10,32 +10,30 @@ from gsuid_core.help.draw_plugin_help import get_help
|
|||||||
from ..version import StarRail_version
|
from ..version import StarRail_version
|
||||||
from ..utils.fonts.starrail_fonts import starrail_font_origin
|
from ..utils.fonts.starrail_fonts import starrail_font_origin
|
||||||
|
|
||||||
TEXT_PATH = Path(__file__).parent / 'texture2d'
|
TEXT_PATH = Path(__file__).parent / "texture2d"
|
||||||
HELP_DATA = Path(__file__).parent / 'Help.json'
|
HELP_DATA = Path(__file__).parent / "Help.json"
|
||||||
|
|
||||||
|
|
||||||
async def get_help_data() -> Optional[Dict[str, PluginHelp]]:
|
async def get_help_data() -> Optional[Dict[str, PluginHelp]]:
|
||||||
if HELP_DATA.exists():
|
if HELP_DATA.exists():
|
||||||
async with aiofiles.open(HELP_DATA, 'rb') as file:
|
async with aiofiles.open(HELP_DATA, "rb") as file:
|
||||||
return msgjson.decode(
|
return msgjson.decode(await file.read(), type=Dict[str, PluginHelp])
|
||||||
await file.read(), type=Dict[str, PluginHelp]
|
|
||||||
)
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
async def get_core_help() -> Union[bytes, str]:
|
async def get_core_help() -> Union[bytes, str]:
|
||||||
help_data = await get_help_data()
|
help_data = await get_help_data()
|
||||||
if help_data is None:
|
if help_data is None:
|
||||||
return '暂未找到帮助数据...'
|
return "暂未找到帮助数据..."
|
||||||
|
|
||||||
return await get_help(
|
return await get_help(
|
||||||
'StarRailUID',
|
"StarRailUID",
|
||||||
f'版本号:{StarRail_version}',
|
f"版本号:{StarRail_version}",
|
||||||
help_data,
|
help_data,
|
||||||
Image.open(TEXT_PATH / 'bg.jpg'),
|
Image.open(TEXT_PATH / "bg.jpg"),
|
||||||
Image.open(TEXT_PATH / 'ICON.png'),
|
Image.open(TEXT_PATH / "ICON.png"),
|
||||||
Image.open(TEXT_PATH / 'badge.png'),
|
Image.open(TEXT_PATH / "badge.png"),
|
||||||
Image.open(TEXT_PATH / 'banner.png'),
|
Image.open(TEXT_PATH / "banner.png"),
|
||||||
Image.open(TEXT_PATH / 'button.png'),
|
Image.open(TEXT_PATH / "button.png"),
|
||||||
starrail_font_origin,
|
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.bot import Bot
|
||||||
from gsuid_core.models import Event
|
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.database.models import GsBind
|
||||||
|
|
||||||
from .note_text import award
|
sv_get_monthly_data = SV("sr查询月历")
|
||||||
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.on_fullmatch(f'{PREFIX}每月统计')
|
@sv_get_monthly_data.on_fullmatch(f"{PREFIX}每月统计")
|
||||||
async def send_monthly_data(bot: Bot, ev: Event):
|
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:
|
if sr_uid is None:
|
||||||
return UID_HINT
|
return UID_HINT
|
||||||
await bot.send(await award(sr_uid))
|
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(
|
@sv_get_monthly_data.on_fullmatch(
|
||||||
(
|
(
|
||||||
f'{PREFIX}开拓月历',
|
f"{PREFIX}开拓月历",
|
||||||
f'{PREFIX}zj',
|
f"{PREFIX}zj",
|
||||||
f'{PREFIX}月历',
|
f"{PREFIX}月历",
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
async def send_monthly_pic(bot: Bot, ev: Event):
|
async def send_monthly_pic(bot: Bot, ev: Event):
|
||||||
await bot.logger.info('开始执行[sr开拓月历]')
|
await bot.logger.info("开始执行[sr开拓月历]")
|
||||||
sr_uid = await get_uid(bot, ev)
|
sr_uid = await get_uid(bot, ev, GsBind, "sr")
|
||||||
if sr_uid is None:
|
if sr_uid is None:
|
||||||
return UID_HINT
|
return UID_HINT
|
||||||
im = await draw_note_img(str(sr_uid))
|
im = await draw_note_img(str(sr_uid))
|
||||||
|
@ -1,23 +1,23 @@
|
|||||||
|
from datetime import datetime
|
||||||
import json
|
import json
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Union
|
from typing import Union
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
from PIL import Image, ImageDraw
|
from PIL import Image, ImageDraw
|
||||||
from msgspec import json as msgjson
|
|
||||||
from gsuid_core.logger import logger
|
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 ..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.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')
|
monthly_bg = Image.open(TEXT_PATH / "monthly_bg.png")
|
||||||
avatar_default = Image.open(TEXT_PATH / '200101.png')
|
avatar_default = Image.open(TEXT_PATH / "200101.png")
|
||||||
|
|
||||||
first_color = (29, 29, 29)
|
first_color = (29, 29, 29)
|
||||||
second_color = (67, 61, 56)
|
second_color = (67, 61, 56)
|
||||||
@ -26,20 +26,20 @@ black_color = (54, 54, 54)
|
|||||||
white_color = (213, 213, 213)
|
white_color = (213, 213, 213)
|
||||||
|
|
||||||
COLOR_MAP = {
|
COLOR_MAP = {
|
||||||
'每日活跃': (248, 227, 157),
|
"每日活跃": (248, 227, 157),
|
||||||
'活动奖励': (99, 231, 176),
|
"活动奖励": (99, 231, 176),
|
||||||
'冒险奖励': (114, 205, 251),
|
"冒险奖励": (114, 205, 251),
|
||||||
'模拟宇宙奖励': (160, 149, 248),
|
"模拟宇宙奖励": (160, 149, 248),
|
||||||
'忘却之庭奖励': (221, 119, 250),
|
"忘却之庭奖励": (221, 119, 250),
|
||||||
'邮件奖励': (244, 110, 104),
|
"邮件奖励": (244, 110, 104),
|
||||||
'其他': (255, 242, 200),
|
"其他": (255, 242, 200),
|
||||||
'Daily Activity': (248, 227, 157),
|
"Daily Activity": (248, 227, 157),
|
||||||
'Events': (99, 231, 176),
|
"Events": (99, 231, 176),
|
||||||
'Adventure': (114, 205, 251),
|
"Adventure": (114, 205, 251),
|
||||||
'moni': (160, 149, 248),
|
"moni": (160, 149, 248),
|
||||||
'Spiral Abyss': (221, 119, 250),
|
"Spiral Abyss": (221, 119, 250),
|
||||||
'Quests': (244, 110, 104),
|
"Quests": (244, 110, 104),
|
||||||
'Other': (255, 242, 200),
|
"Other": (255, 242, 200),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -50,25 +50,25 @@ async def draw_note_img(sr_uid: str) -> Union[bytes, str]:
|
|||||||
|
|
||||||
# 获取当前时间
|
# 获取当前时间
|
||||||
now = datetime.now()
|
now = datetime.now()
|
||||||
current_year_mon = now.strftime('%Y-%m')
|
current_year_mon = now.strftime("%Y-%m")
|
||||||
add_month = ''
|
add_month = ""
|
||||||
if int(now.month) < 10:
|
if int(now.month) < 10:
|
||||||
add_month = '0'
|
add_month = "0"
|
||||||
now_month = str(now.year) + str(add_month) + str(now.month)
|
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):
|
if isinstance(data, int):
|
||||||
return get_error(data)
|
return get_error(data)
|
||||||
|
|
||||||
# 保存数据
|
# 保存数据
|
||||||
with Path.open(
|
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:
|
) as f:
|
||||||
save_json_data = msgjson.format(msgjson.encode(data), indent=4)
|
save_json_data = msgjson.format(msgjson.encode(data), indent=4)
|
||||||
save_data = json.dumps(
|
save_data = json.dumps(
|
||||||
{
|
{
|
||||||
'data_time': now.strftime('%Y-%m-%d %H:%M:%S'),
|
"data_time": now.strftime("%Y-%m-%d %H:%M:%S"),
|
||||||
'data': save_json_data.decode('utf-8'),
|
"data": save_json_data.decode("utf-8"),
|
||||||
},
|
},
|
||||||
ensure_ascii=False,
|
ensure_ascii=False,
|
||||||
)
|
)
|
||||||
@ -80,33 +80,31 @@ async def draw_note_img(sr_uid: str) -> Union[bytes, str]:
|
|||||||
if last_month == 0:
|
if last_month == 0:
|
||||||
last_month = 12
|
last_month = 12
|
||||||
last_year -= 1
|
last_year -= 1
|
||||||
last_year_mon = f'{last_year}-{last_month:02d}'
|
last_year_mon = f"{last_year}-{last_month:02d}"
|
||||||
last_monthly_path = path / f'monthly_{last_year_mon}.json'
|
last_monthly_path = path / f"monthly_{last_year_mon}.json"
|
||||||
if last_monthly_path.exists():
|
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 = json.load(f)
|
||||||
last_monthly_data = msgjson.decode(
|
last_monthly_data = msgjson.decode(
|
||||||
last_monthly_data['data'], type=MonthlyAward
|
last_monthly_data["data"], type=MonthlyAward
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
add_month = ''
|
add_month = ""
|
||||||
if int(last_month) < 10:
|
if int(last_month) < 10:
|
||||||
add_month = '0'
|
add_month = "0"
|
||||||
find_last_month = str(last_year) + str(add_month) + str(last_month)
|
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):
|
if isinstance(last_monthly_data, int):
|
||||||
return get_error(last_monthly_data)
|
return get_error(last_monthly_data)
|
||||||
# 保存上月数据
|
# 保存上月数据
|
||||||
with Path.open(
|
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:
|
) as f:
|
||||||
save_json_data = msgjson.format(
|
save_json_data = msgjson.format(msgjson.encode(last_monthly_data), indent=4)
|
||||||
msgjson.encode(last_monthly_data), indent=4
|
|
||||||
)
|
|
||||||
save_data = json.dumps(
|
save_data = json.dumps(
|
||||||
{
|
{
|
||||||
'data_time': now.strftime('%Y-%m-%d %H:%M:%S'),
|
"data_time": now.strftime("%Y-%m-%d %H:%M:%S"),
|
||||||
'data': save_json_data.decode('utf-8'),
|
"data": save_json_data.decode("utf-8"),
|
||||||
},
|
},
|
||||||
ensure_ascii=False,
|
ensure_ascii=False,
|
||||||
)
|
)
|
||||||
@ -141,7 +139,7 @@ async def draw_note_img(sr_uid: str) -> Union[bytes, str]:
|
|||||||
|
|
||||||
img = monthly_bg.copy()
|
img = monthly_bg.copy()
|
||||||
avatar_img = avatar_default.copy()
|
avatar_img = avatar_default.copy()
|
||||||
char_pic = avatar_img.convert('RGBA').resize(
|
char_pic = avatar_img.convert("RGBA").resize(
|
||||||
(125, 125),
|
(125, 125),
|
||||||
Image.Resampling.LANCZOS, # type: ignore
|
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)
|
img_draw = ImageDraw.Draw(img)
|
||||||
|
|
||||||
# 写Nickname
|
# 写Nickname
|
||||||
img_draw.text(
|
img_draw.text((310, 184), nickname, font=sr_font_34, fill=first_color, anchor="lm")
|
||||||
(310, 184), nickname, font=sr_font_34, fill=first_color, anchor='lm'
|
|
||||||
)
|
|
||||||
|
|
||||||
# 写UID
|
# 写UID
|
||||||
img_draw.text(
|
img_draw.text(
|
||||||
(267, 219),
|
(267, 219),
|
||||||
f'UID {sr_uid}',
|
f"UID {sr_uid}",
|
||||||
font=sr_font_20,
|
font=sr_font_20,
|
||||||
fill=second_color2,
|
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,
|
day_hcoin_str,
|
||||||
font=sr_font_28,
|
font=sr_font_28,
|
||||||
fill=white_color,
|
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,
|
month_hcoin_str,
|
||||||
font=sr_font_28,
|
font=sr_font_28,
|
||||||
fill=white_color,
|
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,
|
lastday_hcoin_str,
|
||||||
font=sr_font_28,
|
font=sr_font_28,
|
||||||
fill=black_color,
|
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,
|
lastmonth_hcoin_str,
|
||||||
font=sr_font_28,
|
font=sr_font_28,
|
||||||
fill=black_color,
|
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,
|
day_rails_pass_str,
|
||||||
font=sr_font_28,
|
font=sr_font_28,
|
||||||
fill=white_color,
|
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,
|
month_rails_pass_str,
|
||||||
font=sr_font_28,
|
font=sr_font_28,
|
||||||
fill=white_color,
|
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,
|
lastday_rails_pass_str,
|
||||||
font=sr_font_28,
|
font=sr_font_28,
|
||||||
fill=black_color,
|
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,
|
lastmonth_rails_pass_str,
|
||||||
font=sr_font_28,
|
font=sr_font_28,
|
||||||
fill=black_color,
|
fill=black_color,
|
||||||
anchor='lm',
|
anchor="lm",
|
||||||
)
|
)
|
||||||
xy = ((0, 0), (2100, 2100))
|
xy = ((0, 0), (2100, 2100))
|
||||||
temp = -90
|
temp = -90
|
||||||
if not data.month_data.group_by:
|
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 = ImageDraw.Draw(pie_image)
|
||||||
pie_image_draw.ellipse(xy, fill=(128, 128, 128))
|
pie_image_draw.ellipse(xy, fill=(128, 128, 128))
|
||||||
else:
|
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 = ImageDraw.Draw(pie_image)
|
||||||
for _index, i in enumerate(data.month_data.group_by):
|
for _index, i in enumerate(data.month_data.group_by):
|
||||||
pie_image_draw.pieslice(
|
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
|
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))
|
pie_image_draw.ellipse((150, 150, 1950, 1950), fill=(255, 255, 255, 0))
|
||||||
|
|
||||||
position = (1050, 1050)
|
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)
|
img.paste(result_pie, (138, 618), result_pie)
|
||||||
|
|
||||||
if last_monthly_data:
|
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)
|
pie_image_draw = ImageDraw.Draw(pie_image)
|
||||||
for _index, i in enumerate(last_monthly_data.month_data.group_by):
|
for _index, i in enumerate(last_monthly_data.month_data.group_by):
|
||||||
pie_image_draw.pieslice(
|
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
|
temp = temp + (i.percent / 100) * 360
|
||||||
else:
|
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 = ImageDraw.Draw(pie_image)
|
||||||
pie_image_draw.ellipse(xy, fill=(128, 128, 128))
|
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))
|
pie_image_draw.ellipse((150, 150, 1950, 1950), fill=(255, 255, 255, 0))
|
||||||
|
|
||||||
position = (1050, 1050)
|
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.paste(result_pie, (138, 618 + 350), result_pie)
|
||||||
|
|
||||||
img = await convert_img(img)
|
img = await convert_img(img)
|
||||||
logger.info('[开拓月历] 图片绘制完成!等待发送...')
|
logger.info("[开拓月历] 图片绘制完成!等待发送...")
|
||||||
return img
|
return img
|
||||||
|
|
||||||
|
|
||||||
async def int_carry(i: int) -> str:
|
async def int_carry(i: int) -> str:
|
||||||
if i >= 100000:
|
if i >= 100000:
|
||||||
i_str = f'{i / 10000:.1f}W'
|
i_str = f"{i / 10000:.1f}W"
|
||||||
else:
|
else:
|
||||||
i_str = str(i)
|
i_str = str(i)
|
||||||
return i_str
|
return i_str
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from ..utils.mys_api import mys_api
|
|
||||||
from ..utils.error_reply import get_error
|
from ..utils.error_reply import get_error
|
||||||
|
from ..utils.mys_api import mys_api
|
||||||
|
|
||||||
month_im = """==============
|
month_im = """==============
|
||||||
SR_UID:{}
|
SR_UID:{}
|
||||||
@ -24,7 +24,7 @@ SR_UID:{}
|
|||||||
|
|
||||||
async def award(uid) -> str:
|
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):
|
if isinstance(data, int):
|
||||||
return get_error(data)
|
return get_error(data)
|
||||||
day_hcoin = data.day_data.current_hcoin
|
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
|
month_rails_pass = data.month_data.current_rails_pass
|
||||||
lastmonth_stone = data.month_data.last_hcoin
|
lastmonth_stone = data.month_data.last_hcoin
|
||||||
lastmonth_rails_pass = data.month_data.last_rails_pass
|
lastmonth_rails_pass = data.month_data.last_rails_pass
|
||||||
group_str = ''
|
group_str = ""
|
||||||
for i in data.month_data.group_by:
|
for i in data.month_data.group_by:
|
||||||
group_str = (
|
group_str = (
|
||||||
group_str
|
group_str
|
||||||
+ i.action_name
|
+ i.action_name
|
||||||
+ ':'
|
+ ":"
|
||||||
+ str(i.num)
|
+ str(i.num)
|
||||||
+ '('
|
+ "("
|
||||||
+ str(i.percent)
|
+ str(i.percent)
|
||||||
+ '%)'
|
+ "%)"
|
||||||
+ '\n'
|
+ "\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
return month_im.format(
|
return month_im.format(
|
||||||
|
@ -6,18 +6,16 @@ from gsuid_core.logger import logger
|
|||||||
from ..utils.sr_prefix import PREFIX
|
from ..utils.sr_prefix import PREFIX
|
||||||
from ..utils.resource.download_from_cos import check_use
|
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):
|
async def send_download_resource_msg(bot: Bot, ev: Event):
|
||||||
await bot.send('sr正在开始下载~可能需要较久的时间!')
|
await bot.send("sr正在开始下载~可能需要较久的时间!")
|
||||||
im = await check_use()
|
im = await check_use()
|
||||||
await bot.send(im)
|
await bot.send(im)
|
||||||
|
|
||||||
|
|
||||||
async def startup():
|
async def startup():
|
||||||
logger.info(
|
logger.info("[sr资源文件下载] 正在检查与下载缺失的资源文件,可能需要较长时间,请稍等")
|
||||||
'[sr资源文件下载] 正在检查与下载缺失的资源文件,可能需要较长时间,请稍等'
|
logger.info(f"[sr资源文件下载] {await check_use()}")
|
||||||
)
|
|
||||||
logger.info(f'[sr资源文件下载] {await check_use()}')
|
|
||||||
|
@ -1,60 +1,58 @@
|
|||||||
import re
|
import re
|
||||||
|
|
||||||
from gsuid_core.sv import SV
|
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.bot import Bot
|
||||||
from gsuid_core.models import Event
|
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 gsuid_core.utils.error_reply import UID_HINT
|
||||||
|
|
||||||
from ..utils.convert import get_uid
|
sv_srabyss = SV("sr查询模拟宇宙")
|
||||||
from ..utils.sr_prefix import PREFIX
|
sv_srabyss_locust = SV("sr查询寰宇蝗灾")
|
||||||
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(
|
@sv_srabyss.on_command(
|
||||||
(
|
(
|
||||||
f'{PREFIX}查询宇宙',
|
f"{PREFIX}查询宇宙",
|
||||||
f'{PREFIX}yz',
|
f"{PREFIX}yz",
|
||||||
f'{PREFIX}查询上期宇宙',
|
f"{PREFIX}查询上期宇宙",
|
||||||
f'{PREFIX}sqyz',
|
f"{PREFIX}sqyz",
|
||||||
f'{PREFIX}上期宇宙',
|
f"{PREFIX}上期宇宙",
|
||||||
f'{PREFIX}宇宙',
|
f"{PREFIX}宇宙",
|
||||||
f'{PREFIX}查询模拟宇宙',
|
f"{PREFIX}查询模拟宇宙",
|
||||||
f'{PREFIX}上期模拟宇宙',
|
f"{PREFIX}上期模拟宇宙",
|
||||||
f'{PREFIX}查询上期模拟宇宙',
|
f"{PREFIX}查询上期模拟宇宙",
|
||||||
),
|
),
|
||||||
block=True,
|
block=True,
|
||||||
)
|
)
|
||||||
async def send_srabyss_info(bot: Bot, ev: Event):
|
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:
|
if name:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
await bot.logger.info('开始执行[sr查询模拟宇宙信息]')
|
await bot.logger.info("开始执行[sr查询模拟宇宙信息]")
|
||||||
get_uid_ = await get_uid(bot, ev, True)
|
uid, user_id = await get_uid(bot, ev, GsBind, "sr", True)
|
||||||
if get_uid_ is None:
|
|
||||||
return await bot.send(UID_HINT)
|
|
||||||
uid, user_id = get_uid_
|
|
||||||
if uid is None:
|
if uid is None:
|
||||||
return await bot.send(UID_HINT)
|
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:
|
if "sq" in ev.command or "上期" in ev.command:
|
||||||
schedule_type = '2'
|
schedule_type = "2"
|
||||||
else:
|
else:
|
||||||
schedule_type = '3'
|
schedule_type = "3"
|
||||||
await bot.logger.info(f'[sr查询模拟宇宙信息]模拟宇宙期数: {schedule_type}')
|
await bot.logger.info(f"[sr查询模拟宇宙信息]模拟宇宙期数: {schedule_type}")
|
||||||
|
|
||||||
if ev.text in ['一', '二', '三', '四', '五', '六']:
|
if ev.text in ["一", "二", "三", "四", "五", "六"]:
|
||||||
floor = (
|
floor = (
|
||||||
ev.text.replace('一', '1')
|
ev.text.replace("一", "1")
|
||||||
.replace('二', '2')
|
.replace("二", "2")
|
||||||
.replace('三', '3')
|
.replace("三", "3")
|
||||||
.replace('四', '4')
|
.replace("四", "4")
|
||||||
.replace('五', '5')
|
.replace("五", "5")
|
||||||
.replace('六', '6')
|
.replace("六", "6")
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
floor = ev.text
|
floor = ev.text
|
||||||
@ -62,7 +60,7 @@ async def send_srabyss_info(bot: Bot, ev: Event):
|
|||||||
floor = int(floor)
|
floor = int(floor)
|
||||||
else:
|
else:
|
||||||
floor = None
|
floor = None
|
||||||
await bot.logger.info(f'[sr查询模拟宇宙信息]模拟宇宙世界数: {floor}')
|
await bot.logger.info(f"[sr查询模拟宇宙信息]模拟宇宙世界数: {floor}")
|
||||||
im = await draw_rogue_img(user_id, uid, ev.sender, floor, schedule_type)
|
im = await draw_rogue_img(user_id, uid, ev.sender, floor, schedule_type)
|
||||||
await bot.send(im)
|
await bot.send(im)
|
||||||
return None
|
return None
|
||||||
@ -70,26 +68,23 @@ async def send_srabyss_info(bot: Bot, ev: Event):
|
|||||||
|
|
||||||
@sv_srabyss_locust.on_command(
|
@sv_srabyss_locust.on_command(
|
||||||
(
|
(
|
||||||
f'{PREFIX}寰宇蝗灾',
|
f"{PREFIX}寰宇蝗灾",
|
||||||
f'{PREFIX}hyhz',
|
f"{PREFIX}hyhz",
|
||||||
f'{PREFIX}查询寰宇蝗灾',
|
f"{PREFIX}查询寰宇蝗灾",
|
||||||
f'{PREFIX}sqhyhz',
|
f"{PREFIX}sqhyhz",
|
||||||
),
|
),
|
||||||
block=True,
|
block=True,
|
||||||
)
|
)
|
||||||
async def send_srabyss_locust_info(bot: Bot, ev: Event):
|
async def send_srabyss_locust_info(bot: Bot, ev: Event):
|
||||||
name = ''.join(re.findall('[\u4e00-\u9fa5]', ev.text))
|
name = "".join(re.findall("[\u4e00-\u9fa5]", ev.text))
|
||||||
if name:
|
if name:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
await bot.logger.info('开始执行[sr查询寰宇蝗灾信息]')
|
await bot.logger.info("开始执行[sr查询寰宇蝗灾信息]")
|
||||||
get_uid_ = await get_uid(bot, ev, True)
|
uid, user_id = await get_uid(bot, ev, GsBind, "sr", True)
|
||||||
if get_uid_ is None:
|
|
||||||
return await bot.send(UID_HINT)
|
|
||||||
uid, user_id = get_uid_
|
|
||||||
if uid is None:
|
if uid is None:
|
||||||
return await bot.send(UID_HINT)
|
return await bot.send(UID_HINT)
|
||||||
await bot.logger.info(f'[sr查询寰宇蝗灾信息]uid: {uid}')
|
await bot.logger.info(f"[sr查询寰宇蝗灾信息]uid: {uid}")
|
||||||
im = await draw_rogue_locust_img(user_id, uid, ev.sender)
|
im = await draw_rogue_locust_img(user_id, uid, ev.sender)
|
||||||
await bot.send(im)
|
await bot.send(im)
|
||||||
return None
|
return None
|
||||||
|
@ -1,95 +1,87 @@
|
|||||||
import math
|
import math
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import 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 import get_icon
|
from .utils import get_icon
|
||||||
from ..utils.mys_api import mys_api
|
from ..sruid_utils.api.mys.models import (
|
||||||
from ..utils.image.convert import convert_img
|
LocustBlocks,
|
||||||
|
RogueAvatar,
|
||||||
|
RogueBuffitems,
|
||||||
|
RogueMiracles,
|
||||||
|
)
|
||||||
from ..utils.fonts.starrail_fonts import (
|
from ..utils.fonts.starrail_fonts import (
|
||||||
sr_font_22,
|
sr_font_22,
|
||||||
sr_font_28,
|
sr_font_28,
|
||||||
sr_font_34,
|
sr_font_34,
|
||||||
sr_font_42,
|
sr_font_42,
|
||||||
)
|
)
|
||||||
from ..sruid_utils.api.mys.models import (
|
from ..utils.mys_api import mys_api
|
||||||
RogueAvatar,
|
|
||||||
LocustBlocks,
|
from PIL import Image, ImageDraw
|
||||||
RogueMiracles,
|
from gsuid_core.logger import logger
|
||||||
RogueBuffitems,
|
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'
|
TEXT_PATH = Path(__file__).parent / "texture2D"
|
||||||
white_color = (255, 255, 255)
|
white_color = (255, 255, 255)
|
||||||
gray_color = (175, 175, 175)
|
gray_color = (175, 175, 175)
|
||||||
img_bg = Image.open(TEXT_PATH / 'bg.jpg')
|
img_bg = Image.open(TEXT_PATH / "bg.jpg")
|
||||||
level_cover = Image.open(TEXT_PATH / 'level_cover.png').convert('RGBA')
|
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_4 = Image.open(TEXT_PATH / "char4_bg.png").convert("RGBA")
|
||||||
char_bg_5 = Image.open(TEXT_PATH / 'char5_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')
|
rank_bg = Image.open(TEXT_PATH / "rank_bg.png").convert("RGBA")
|
||||||
content_center = Image.open(TEXT_PATH / 'center.png').convert('RGBA')
|
content_center = Image.open(TEXT_PATH / "center.png").convert("RGBA")
|
||||||
|
|
||||||
elements = {
|
elements = {
|
||||||
'ice': Image.open(TEXT_PATH / 'IconNatureColorIce.png').convert('RGBA'),
|
"ice": Image.open(TEXT_PATH / "IconNatureColorIce.png").convert("RGBA"),
|
||||||
'fire': Image.open(TEXT_PATH / 'IconNatureColorFire.png').convert('RGBA'),
|
"fire": Image.open(TEXT_PATH / "IconNatureColorFire.png").convert("RGBA"),
|
||||||
'imaginary': Image.open(
|
"imaginary": Image.open(TEXT_PATH / "IconNatureColorImaginary.png").convert("RGBA"),
|
||||||
TEXT_PATH / 'IconNatureColorImaginary.png'
|
"quantum": Image.open(TEXT_PATH / "IconNatureColorQuantum.png").convert("RGBA"),
|
||||||
).convert('RGBA'),
|
"lightning": Image.open(TEXT_PATH / "IconNatureColorThunder.png").convert("RGBA"),
|
||||||
'quantum': Image.open(TEXT_PATH / 'IconNatureColorQuantum.png').convert(
|
"wind": Image.open(TEXT_PATH / "IconNatureColorWind.png").convert("RGBA"),
|
||||||
'RGBA'
|
"physical": Image.open(TEXT_PATH / "IconNaturePhysical.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'
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
progresslist = {
|
progresslist = {
|
||||||
1: '第一世界',
|
1: "第一世界",
|
||||||
2: '第二世界',
|
2: "第二世界",
|
||||||
3: '第三世界',
|
3: "第三世界",
|
||||||
4: '第四世界',
|
4: "第四世界",
|
||||||
5: '第五世界',
|
5: "第五世界",
|
||||||
6: '第六世界',
|
6: "第六世界",
|
||||||
7: '第七世界',
|
7: "第七世界",
|
||||||
8: '第八世界',
|
8: "第八世界",
|
||||||
}
|
}
|
||||||
|
|
||||||
difficultylist = {
|
difficultylist = {
|
||||||
1: 'I',
|
1: "I",
|
||||||
2: 'Ⅱ',
|
2: "Ⅱ",
|
||||||
3: 'Ⅲ',
|
3: "Ⅲ",
|
||||||
4: 'Ⅳ',
|
4: "Ⅳ",
|
||||||
5: 'V',
|
5: "V",
|
||||||
6: 'Ⅵ',
|
6: "Ⅵ",
|
||||||
7: 'Ⅶ',
|
7: "Ⅶ",
|
||||||
8: 'Ⅷ',
|
8: "Ⅷ",
|
||||||
}
|
}
|
||||||
|
|
||||||
bufflist = {
|
bufflist = {
|
||||||
120: '存护',
|
120: "存护",
|
||||||
121: '记忆',
|
121: "记忆",
|
||||||
122: '虚无',
|
122: "虚无",
|
||||||
123: '丰饶',
|
123: "丰饶",
|
||||||
124: '巡猎',
|
124: "巡猎",
|
||||||
125: '毁灭',
|
125: "毁灭",
|
||||||
126: '欢愉',
|
126: "欢愉",
|
||||||
127: '繁育',
|
127: "繁育",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async def get_abyss_star_pic(star: int) -> Image.Image:
|
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_rogue_buff(
|
async def _draw_rogue_buff(
|
||||||
@ -101,15 +93,15 @@ async def _draw_rogue_buff(
|
|||||||
):
|
):
|
||||||
draw_height = 0
|
draw_height = 0
|
||||||
floor_pic_draw = ImageDraw.Draw(floor_pic)
|
floor_pic_draw = ImageDraw.Draw(floor_pic)
|
||||||
buff_icon_img = Image.open(TEXT_PATH / f'{buff_icon}.png')
|
buff_icon_img = Image.open(TEXT_PATH / f"{buff_icon}.png")
|
||||||
buff_icon_img = buff_icon_img.resize((40, 40))
|
buff_icon_img = buff_icon_img.resize((40, 40))
|
||||||
floor_pic.paste(buff_icon_img, (95, 400 + buff_height), buff_icon_img)
|
floor_pic.paste(buff_icon_img, (95, 400 + buff_height), buff_icon_img)
|
||||||
floor_pic_draw.text(
|
floor_pic_draw.text(
|
||||||
(140, 425 + buff_height),
|
(140, 425 + buff_height),
|
||||||
f'{buff_name}:',
|
f"{buff_name}:",
|
||||||
font=sr_font_28,
|
font=sr_font_28,
|
||||||
fill=gray_color,
|
fill=gray_color,
|
||||||
anchor='lm',
|
anchor="lm",
|
||||||
)
|
)
|
||||||
draw_height = draw_height + 40
|
draw_height = draw_height + 40
|
||||||
buff_num = len(buffs)
|
buff_num = len(buffs)
|
||||||
@ -125,9 +117,7 @@ async def _draw_rogue_buff(
|
|||||||
is_evoluted = 1
|
is_evoluted = 1
|
||||||
else:
|
else:
|
||||||
is_evoluted = 0
|
is_evoluted = 0
|
||||||
buff_bg = Image.open(
|
buff_bg = Image.open(TEXT_PATH / f"zhufu_{item.rank}_{is_evoluted}.png")
|
||||||
TEXT_PATH / f'zhufu_{item.rank}_{is_evoluted}.png'
|
|
||||||
)
|
|
||||||
buff_bg = buff_bg.resize((233, 35))
|
buff_bg = buff_bg.resize((233, 35))
|
||||||
z_left = 90 + 240 * zb_list[jishu][1]
|
z_left = 90 + 240 * zb_list[jishu][1]
|
||||||
z_top = buff_height + 450 + 55 * zb_list[jishu][0]
|
z_top = buff_height + 450 + 55 * zb_list[jishu][0]
|
||||||
@ -138,7 +128,7 @@ async def _draw_rogue_buff(
|
|||||||
item.name,
|
item.name,
|
||||||
font=sr_font_22,
|
font=sr_font_22,
|
||||||
fill=white_color,
|
fill=white_color,
|
||||||
anchor='mm',
|
anchor="mm",
|
||||||
)
|
)
|
||||||
return draw_height
|
return draw_height
|
||||||
|
|
||||||
@ -159,7 +149,7 @@ async def _draw_rogue_blocks(
|
|||||||
zb_list.append([m, n])
|
zb_list.append([m, n])
|
||||||
jishu = 0
|
jishu = 0
|
||||||
for block in blocks:
|
for block in blocks:
|
||||||
block_icon = Image.open(TEXT_PATH / f'{block.name}.png')
|
block_icon = Image.open(TEXT_PATH / f"{block.name}.png")
|
||||||
z_left_bg = 90 + 357 * zb_list[jishu][1]
|
z_left_bg = 90 + 357 * zb_list[jishu][1]
|
||||||
z_top_bg = buff_height + 470 + 80 * zb_list[jishu][0]
|
z_top_bg = buff_height + 470 + 80 * zb_list[jishu][0]
|
||||||
jishu = jishu + 1
|
jishu = jishu + 1
|
||||||
@ -168,10 +158,10 @@ async def _draw_rogue_blocks(
|
|||||||
floor_pic.paste(block_icon, (z_left_icon, z_top_icon), mask=block_icon)
|
floor_pic.paste(block_icon, (z_left_icon, z_top_icon), mask=block_icon)
|
||||||
floor_pic_draw.text(
|
floor_pic_draw.text(
|
||||||
(z_left_bg + 80, z_top_bg + 35),
|
(z_left_bg + 80, z_top_bg + 35),
|
||||||
f'{block.name} x{block.num}',
|
f"{block.name} x{block.num}",
|
||||||
font=sr_font_22,
|
font=sr_font_22,
|
||||||
fill=white_color,
|
fill=white_color,
|
||||||
anchor='lm',
|
anchor="lm",
|
||||||
)
|
)
|
||||||
return draw_height
|
return draw_height
|
||||||
|
|
||||||
@ -226,17 +216,17 @@ async def _draw_rogue_card(
|
|||||||
char_bg.paste(rank_bg, (150, 16), mask=rank_bg)
|
char_bg.paste(rank_bg, (150, 16), mask=rank_bg)
|
||||||
char_card_draw.text(
|
char_card_draw.text(
|
||||||
(162, 31),
|
(162, 31),
|
||||||
f'{char.rank}',
|
f"{char.rank}",
|
||||||
font=sr_font_22,
|
font=sr_font_22,
|
||||||
fill=white_color,
|
fill=white_color,
|
||||||
anchor='mm',
|
anchor="mm",
|
||||||
)
|
)
|
||||||
char_card_draw.text(
|
char_card_draw.text(
|
||||||
(100, 165),
|
(100, 165),
|
||||||
f'等级 {char.level}',
|
f"等级 {char.level}",
|
||||||
font=sr_font_22,
|
font=sr_font_22,
|
||||||
fill=white_color,
|
fill=white_color,
|
||||||
anchor='mm',
|
anchor="mm",
|
||||||
)
|
)
|
||||||
floor_pic.paste(
|
floor_pic.paste(
|
||||||
char_bg,
|
char_bg,
|
||||||
@ -248,17 +238,17 @@ async def _draw_rogue_card(
|
|||||||
async def draw_rogue_img(
|
async def draw_rogue_img(
|
||||||
qid: Union[str, int],
|
qid: Union[str, int],
|
||||||
uid: str,
|
uid: str,
|
||||||
sender: Union[str, str],
|
sender: Dict[str, Any],
|
||||||
floor: Optional[int] = None,
|
floor: Optional[int] = None,
|
||||||
schedule_type: str = '3',
|
schedule_type: str = "3",
|
||||||
) -> Union[bytes, str]:
|
) -> Union[bytes, str]:
|
||||||
raw_rogue_data = await mys_api.get_rogue_info(uid, '3')
|
raw_rogue_data = await mys_api.get_rogue_info(uid, "3")
|
||||||
|
|
||||||
if isinstance(raw_rogue_data, int):
|
if isinstance(raw_rogue_data, int):
|
||||||
return get_error(raw_rogue_data)
|
return get_error(raw_rogue_data)
|
||||||
|
|
||||||
# 计算背景图尺寸
|
# 计算背景图尺寸
|
||||||
if schedule_type == '3':
|
if schedule_type == "3":
|
||||||
rogue_detail = raw_rogue_data.current_record.records
|
rogue_detail = raw_rogue_data.current_record.records
|
||||||
else:
|
else:
|
||||||
rogue_detail = raw_rogue_data.last_record.records
|
rogue_detail = raw_rogue_data.last_record.records
|
||||||
@ -305,29 +295,29 @@ async def draw_rogue_img(
|
|||||||
# 获取查询者数据
|
# 获取查询者数据
|
||||||
if floor:
|
if floor:
|
||||||
if floor > 8:
|
if floor > 8:
|
||||||
return '世界不能大于第八世界!'
|
return "世界不能大于第八世界!"
|
||||||
if floor not in detail_list:
|
if floor not in detail_list:
|
||||||
return '你还没有挑战该模拟宇宙!'
|
return "你还没有挑战该模拟宇宙!"
|
||||||
elif schedule_type == '3':
|
elif schedule_type == "3":
|
||||||
if raw_rogue_data.current_record.basic.finish_cnt == 0:
|
if raw_rogue_data.current_record.basic.finish_cnt == 0:
|
||||||
return '你还没有挑战本期模拟宇宙!\n可以使用[sr上期模拟宇宙]命令查询上期~'
|
return "你还没有挑战本期模拟宇宙!\n可以使用[sr上期模拟宇宙]命令查询上期~"
|
||||||
elif raw_rogue_data.last_record.basic.finish_cnt == 0:
|
elif raw_rogue_data.last_record.basic.finish_cnt == 0:
|
||||||
return '你还没有挑战上期模拟宇宙!\n可以使用[sr模拟宇宙]命令查询本期~'
|
return "你还没有挑战上期模拟宇宙!\n可以使用[sr模拟宇宙]命令查询本期~"
|
||||||
|
|
||||||
# 获取背景图片各项参数
|
# 获取背景图片各项参数
|
||||||
based_w = 900
|
based_w = 900
|
||||||
img = Image.new('RGB', (based_w, based_h), (10, 18, 49))
|
img = Image.new("RGB", (based_w, based_h), (10, 18, 49))
|
||||||
img.paste(img_bg, (0, 0))
|
img.paste(img_bg, (0, 0))
|
||||||
# img = img.crop((0, 0, based_w, based_h))
|
# img = img.crop((0, 0, based_w, based_h))
|
||||||
rogue_title = Image.open(TEXT_PATH / 'head.png')
|
rogue_title = Image.open(TEXT_PATH / "head.png")
|
||||||
img.paste(rogue_title, (0, 0), rogue_title)
|
img.paste(rogue_title, (0, 0), rogue_title)
|
||||||
|
|
||||||
# 获取头像
|
# 获取头像
|
||||||
_id = str(qid)
|
_id = str(qid)
|
||||||
if _id.startswith('http'):
|
if _id.startswith("http"):
|
||||||
char_pic = await get_qq_avatar(avatar_url=_id)
|
char_pic = await get_qq_avatar(avatar_url=_id)
|
||||||
elif sender.get('avatar') is not None:
|
elif sender.get("avatar") is not None:
|
||||||
char_pic = await get_qq_avatar(avatar_url=sender['avatar'])
|
char_pic = await get_qq_avatar(avatar_url=sender["avatar"])
|
||||||
else:
|
else:
|
||||||
char_pic = await get_qq_avatar(qid=qid)
|
char_pic = await get_qq_avatar(qid=qid)
|
||||||
char_pic = await draw_pic_with_ring(char_pic, 250, None, False)
|
char_pic = await draw_pic_with_ring(char_pic, 250, None, False)
|
||||||
@ -336,58 +326,58 @@ async def draw_rogue_img(
|
|||||||
|
|
||||||
# 绘制抬头
|
# 绘制抬头
|
||||||
img_draw = ImageDraw.Draw(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")
|
||||||
|
|
||||||
# 总体数据
|
# 总体数据
|
||||||
rogue_data = Image.open(TEXT_PATH / 'data.png')
|
rogue_data = Image.open(TEXT_PATH / "data.png")
|
||||||
img.paste(rogue_data, (0, 500), rogue_data)
|
img.paste(rogue_data, (0, 500), rogue_data)
|
||||||
|
|
||||||
# 技能树激活
|
# 技能树激活
|
||||||
img_draw.text(
|
img_draw.text(
|
||||||
(165, 569),
|
(165, 569),
|
||||||
f'{raw_rogue_data.basic_info.unlocked_skill_points}',
|
f"{raw_rogue_data.basic_info.unlocked_skill_points}",
|
||||||
white_color,
|
white_color,
|
||||||
sr_font_42,
|
sr_font_42,
|
||||||
'mm',
|
"mm",
|
||||||
)
|
)
|
||||||
img_draw.text(
|
img_draw.text(
|
||||||
(165, 615),
|
(165, 615),
|
||||||
'已激活技能树',
|
"已激活技能树",
|
||||||
gray_color,
|
gray_color,
|
||||||
sr_font_28,
|
sr_font_28,
|
||||||
'mm',
|
"mm",
|
||||||
)
|
)
|
||||||
|
|
||||||
# 奇物解锁
|
# 奇物解锁
|
||||||
img_draw.text(
|
img_draw.text(
|
||||||
(450, 569),
|
(450, 569),
|
||||||
f'{raw_rogue_data.basic_info.unlocked_miracle_num}',
|
f"{raw_rogue_data.basic_info.unlocked_miracle_num}",
|
||||||
white_color,
|
white_color,
|
||||||
sr_font_42,
|
sr_font_42,
|
||||||
'mm',
|
"mm",
|
||||||
)
|
)
|
||||||
img_draw.text(
|
img_draw.text(
|
||||||
(450, 615),
|
(450, 615),
|
||||||
'已解锁奇物',
|
"已解锁奇物",
|
||||||
gray_color,
|
gray_color,
|
||||||
sr_font_28,
|
sr_font_28,
|
||||||
'mm',
|
"mm",
|
||||||
)
|
)
|
||||||
|
|
||||||
# 祝福解锁
|
# 祝福解锁
|
||||||
img_draw.text(
|
img_draw.text(
|
||||||
(730, 569),
|
(730, 569),
|
||||||
f'{raw_rogue_data.basic_info.unlocked_buff_num}',
|
f"{raw_rogue_data.basic_info.unlocked_buff_num}",
|
||||||
white_color,
|
white_color,
|
||||||
sr_font_42,
|
sr_font_42,
|
||||||
'mm',
|
"mm",
|
||||||
)
|
)
|
||||||
img_draw.text(
|
img_draw.text(
|
||||||
(730, 615),
|
(730, 615),
|
||||||
'已解锁祝福',
|
"已解锁祝福",
|
||||||
gray_color,
|
gray_color,
|
||||||
sr_font_28,
|
sr_font_28,
|
||||||
'mm',
|
"mm",
|
||||||
)
|
)
|
||||||
|
|
||||||
for index_floor, detail in enumerate(rogue_detail):
|
for index_floor, detail in enumerate(rogue_detail):
|
||||||
@ -400,25 +390,19 @@ async def draw_rogue_img(
|
|||||||
if detail_h_list[index_floor] is None:
|
if detail_h_list[index_floor] is None:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
floor_pic = Image.open(TEXT_PATH / 'detail_bg.png').convert('RGBA')
|
floor_pic = Image.open(TEXT_PATH / "detail_bg.png").convert("RGBA")
|
||||||
floor_pic = floor_pic.resize((900, detail_h_list[index_floor]))
|
floor_pic = floor_pic.resize((900, detail_h_list[index_floor]))
|
||||||
|
|
||||||
floor_top_pic = Image.open(TEXT_PATH / 'floor_bg_top.png').convert(
|
floor_top_pic = Image.open(TEXT_PATH / "floor_bg_top.png").convert("RGBA")
|
||||||
'RGBA'
|
|
||||||
)
|
|
||||||
floor_pic.paste(floor_top_pic, (0, 0), floor_top_pic)
|
floor_pic.paste(floor_top_pic, (0, 0), floor_top_pic)
|
||||||
|
|
||||||
floor_center_pic = Image.open(
|
floor_center_pic = Image.open(TEXT_PATH / "floor_bg_center.png").convert("RGBA")
|
||||||
TEXT_PATH / 'floor_bg_center.png'
|
|
||||||
).convert('RGBA')
|
|
||||||
floor_center_pic = floor_center_pic.resize(
|
floor_center_pic = floor_center_pic.resize(
|
||||||
(900, detail_h_list[index_floor] - 170)
|
(900, detail_h_list[index_floor] - 170)
|
||||||
)
|
)
|
||||||
floor_pic.paste(floor_center_pic, (0, 100), floor_center_pic)
|
floor_pic.paste(floor_center_pic, (0, 100), floor_center_pic)
|
||||||
|
|
||||||
floor_bot_pic = Image.open(TEXT_PATH / 'floor_bg_bot.png').convert(
|
floor_bot_pic = Image.open(TEXT_PATH / "floor_bg_bot.png").convert("RGBA")
|
||||||
'RGBA'
|
|
||||||
)
|
|
||||||
floor_pic.paste(
|
floor_pic.paste(
|
||||||
floor_bot_pic, (0, detail_h_list[index_floor] - 70), floor_bot_pic
|
floor_bot_pic, (0, detail_h_list[index_floor] - 70), floor_bot_pic
|
||||||
)
|
)
|
||||||
@ -427,30 +411,30 @@ async def draw_rogue_img(
|
|||||||
difficulty_name = difficultylist[detail.difficulty]
|
difficulty_name = difficultylist[detail.difficulty]
|
||||||
|
|
||||||
time_array = detail.finish_time
|
time_array = detail.finish_time
|
||||||
time_str = f'{time_array.year}-{time_array.month}'
|
time_str = f"{time_array.year}-{time_array.month}"
|
||||||
time_str = f'{time_str}-{time_array.day}'
|
time_str = f"{time_str}-{time_array.day}"
|
||||||
time_str = f'{time_str} {time_array.hour}:{time_array.minute}'
|
time_str = f"{time_str} {time_array.hour}:{time_array.minute}"
|
||||||
floor_pic_draw = ImageDraw.Draw(floor_pic)
|
floor_pic_draw = ImageDraw.Draw(floor_pic)
|
||||||
floor_pic_draw.text(
|
floor_pic_draw.text(
|
||||||
(450, 60),
|
(450, 60),
|
||||||
f'{floor_name} {difficulty_name}',
|
f"{floor_name} {difficulty_name}",
|
||||||
white_color,
|
white_color,
|
||||||
sr_font_42,
|
sr_font_42,
|
||||||
'mm',
|
"mm",
|
||||||
)
|
)
|
||||||
floor_pic_draw.text(
|
floor_pic_draw.text(
|
||||||
(93, 120),
|
(93, 120),
|
||||||
f'挑战时间:{time_str}',
|
f"挑战时间:{time_str}",
|
||||||
gray_color,
|
gray_color,
|
||||||
sr_font_22,
|
sr_font_22,
|
||||||
'lm',
|
"lm",
|
||||||
)
|
)
|
||||||
floor_pic_draw.text(
|
floor_pic_draw.text(
|
||||||
(800, 120),
|
(800, 120),
|
||||||
f'当前积分:{detail.score}',
|
f"当前积分:{detail.score}",
|
||||||
gray_color,
|
gray_color,
|
||||||
sr_font_22,
|
sr_font_22,
|
||||||
'rm',
|
"rm",
|
||||||
)
|
)
|
||||||
|
|
||||||
# 角色
|
# 角色
|
||||||
@ -478,10 +462,10 @@ async def draw_rogue_img(
|
|||||||
if len(detail.base_type_list) > 0:
|
if len(detail.base_type_list) > 0:
|
||||||
floor_pic_draw.text(
|
floor_pic_draw.text(
|
||||||
(93, 370),
|
(93, 370),
|
||||||
'获得祝福',
|
"获得祝福",
|
||||||
white_color,
|
white_color,
|
||||||
sr_font_34,
|
sr_font_34,
|
||||||
'lm',
|
"lm",
|
||||||
)
|
)
|
||||||
floor_pic.paste(content_center, (0, 390), content_center)
|
floor_pic.paste(content_center, (0, 390), content_center)
|
||||||
for buff in detail.buffs:
|
for buff in detail.buffs:
|
||||||
@ -501,14 +485,12 @@ async def draw_rogue_img(
|
|||||||
if len(detail.miracles) > 0:
|
if len(detail.miracles) > 0:
|
||||||
floor_pic_draw.text(
|
floor_pic_draw.text(
|
||||||
(93, 370 + buff_height + 60),
|
(93, 370 + buff_height + 60),
|
||||||
'获得奇物',
|
"获得奇物",
|
||||||
white_color,
|
white_color,
|
||||||
sr_font_34,
|
sr_font_34,
|
||||||
'lm',
|
"lm",
|
||||||
)
|
|
||||||
floor_pic.paste(
|
|
||||||
content_center, (0, 370 + buff_height + 80), content_center
|
|
||||||
)
|
)
|
||||||
|
floor_pic.paste(content_center, (0, 370 + buff_height + 80), content_center)
|
||||||
await _draw_rogue_miracles(
|
await _draw_rogue_miracles(
|
||||||
detail.miracles,
|
detail.miracles,
|
||||||
floor_pic,
|
floor_pic,
|
||||||
@ -529,16 +511,16 @@ async def draw_rogue_img(
|
|||||||
# )
|
# )
|
||||||
|
|
||||||
res = await convert_img(img)
|
res = await convert_img(img)
|
||||||
logger.info('[查询模拟宇宙]绘图已完成,等待发送!')
|
logger.info("[查询模拟宇宙]绘图已完成,等待发送!")
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
async def draw_rogue_locust_img(
|
async def draw_rogue_locust_img(
|
||||||
qid: Union[str, int],
|
qid: Union[str, int],
|
||||||
uid: str,
|
uid: str,
|
||||||
sender: Union[str, str],
|
sender: Dict[str, Any],
|
||||||
) -> Union[bytes, str]:
|
) -> Union[bytes, str]:
|
||||||
raw_rogue_data = await mys_api.get_rogue_locust_info(uid, '3')
|
raw_rogue_data = await mys_api.get_rogue_locust_info(uid, "3")
|
||||||
|
|
||||||
if isinstance(raw_rogue_data, int):
|
if isinstance(raw_rogue_data, int):
|
||||||
return get_error(raw_rogue_data)
|
return get_error(raw_rogue_data)
|
||||||
@ -598,22 +580,22 @@ async def draw_rogue_locust_img(
|
|||||||
|
|
||||||
# 获取查询者数据
|
# 获取查询者数据
|
||||||
if len(rogue_detail) == 0:
|
if len(rogue_detail) == 0:
|
||||||
return '你还没有挑战寰宇蝗灾~'
|
return "你还没有挑战寰宇蝗灾~"
|
||||||
|
|
||||||
# 获取背景图片各项参数
|
# 获取背景图片各项参数
|
||||||
based_w = 900
|
based_w = 900
|
||||||
img = Image.new('RGB', (based_w, based_h), (10, 18, 49))
|
img = Image.new("RGB", (based_w, based_h), (10, 18, 49))
|
||||||
img.paste(img_bg, (0, 0))
|
img.paste(img_bg, (0, 0))
|
||||||
# img = img.crop((0, 0, based_w, based_h))
|
# img = img.crop((0, 0, based_w, based_h))
|
||||||
rogue_title = Image.open(TEXT_PATH / 'head.png')
|
rogue_title = Image.open(TEXT_PATH / "head.png")
|
||||||
img.paste(rogue_title, (0, 0), rogue_title)
|
img.paste(rogue_title, (0, 0), rogue_title)
|
||||||
|
|
||||||
# 获取头像
|
# 获取头像
|
||||||
_id = str(qid)
|
_id = str(qid)
|
||||||
if _id.startswith('http'):
|
if _id.startswith("http"):
|
||||||
char_pic = await get_qq_avatar(avatar_url=_id)
|
char_pic = await get_qq_avatar(avatar_url=_id)
|
||||||
elif sender.get('avatar') is not None:
|
elif sender.get("avatar") is not None:
|
||||||
char_pic = await get_qq_avatar(avatar_url=sender['avatar'])
|
char_pic = await get_qq_avatar(avatar_url=sender["avatar"])
|
||||||
else:
|
else:
|
||||||
char_pic = await get_qq_avatar(qid=qid)
|
char_pic = await get_qq_avatar(qid=qid)
|
||||||
char_pic = await draw_pic_with_ring(char_pic, 250, None, False)
|
char_pic = await draw_pic_with_ring(char_pic, 250, None, False)
|
||||||
@ -622,83 +604,77 @@ async def draw_rogue_locust_img(
|
|||||||
|
|
||||||
# 绘制抬头
|
# 绘制抬头
|
||||||
img_draw = ImageDraw.Draw(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")
|
||||||
|
|
||||||
# 总体数据
|
# 总体数据
|
||||||
rogue_data = Image.open(TEXT_PATH / 'data.png')
|
rogue_data = Image.open(TEXT_PATH / "data.png")
|
||||||
img.paste(rogue_data, (0, 500), rogue_data)
|
img.paste(rogue_data, (0, 500), rogue_data)
|
||||||
|
|
||||||
# 行者之道激活
|
# 行者之道激活
|
||||||
img_draw.text(
|
img_draw.text(
|
||||||
(165, 569),
|
(165, 569),
|
||||||
f'{raw_rogue_data.basic.cnt.narrow}',
|
f"{raw_rogue_data.basic.cnt.narrow}",
|
||||||
white_color,
|
white_color,
|
||||||
sr_font_42,
|
sr_font_42,
|
||||||
'mm',
|
"mm",
|
||||||
)
|
)
|
||||||
img_draw.text(
|
img_draw.text(
|
||||||
(165, 615),
|
(165, 615),
|
||||||
'行者之道',
|
"行者之道",
|
||||||
gray_color,
|
gray_color,
|
||||||
sr_font_28,
|
sr_font_28,
|
||||||
'mm',
|
"mm",
|
||||||
)
|
)
|
||||||
|
|
||||||
# 奇物解锁
|
# 奇物解锁
|
||||||
img_draw.text(
|
img_draw.text(
|
||||||
(450, 569),
|
(450, 569),
|
||||||
f'{raw_rogue_data.basic.cnt.miracle}',
|
f"{raw_rogue_data.basic.cnt.miracle}",
|
||||||
white_color,
|
white_color,
|
||||||
sr_font_42,
|
sr_font_42,
|
||||||
'mm',
|
"mm",
|
||||||
)
|
)
|
||||||
img_draw.text(
|
img_draw.text(
|
||||||
(450, 615),
|
(450, 615),
|
||||||
'已解锁奇物',
|
"已解锁奇物",
|
||||||
gray_color,
|
gray_color,
|
||||||
sr_font_28,
|
sr_font_28,
|
||||||
'mm',
|
"mm",
|
||||||
)
|
)
|
||||||
|
|
||||||
# 事件解锁
|
# 事件解锁
|
||||||
img_draw.text(
|
img_draw.text(
|
||||||
(730, 569),
|
(730, 569),
|
||||||
f'{raw_rogue_data.basic.cnt.event}',
|
f"{raw_rogue_data.basic.cnt.event}",
|
||||||
white_color,
|
white_color,
|
||||||
sr_font_42,
|
sr_font_42,
|
||||||
'mm',
|
"mm",
|
||||||
)
|
)
|
||||||
img_draw.text(
|
img_draw.text(
|
||||||
(730, 615),
|
(730, 615),
|
||||||
'已解锁事件',
|
"已解锁事件",
|
||||||
gray_color,
|
gray_color,
|
||||||
sr_font_28,
|
sr_font_28,
|
||||||
'mm',
|
"mm",
|
||||||
)
|
)
|
||||||
|
|
||||||
for index_floor, detail in enumerate(rogue_detail):
|
for index_floor, detail in enumerate(rogue_detail):
|
||||||
if detail_h_list[index_floor] is None:
|
if detail_h_list[index_floor] is None:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
floor_pic = Image.open(TEXT_PATH / 'detail_bg.png').convert('RGBA')
|
floor_pic = Image.open(TEXT_PATH / "detail_bg.png").convert("RGBA")
|
||||||
floor_pic = floor_pic.resize((900, detail_h_list[index_floor]))
|
floor_pic = floor_pic.resize((900, detail_h_list[index_floor]))
|
||||||
|
|
||||||
floor_top_pic = Image.open(TEXT_PATH / 'floor_bg_top.png').convert(
|
floor_top_pic = Image.open(TEXT_PATH / "floor_bg_top.png").convert("RGBA")
|
||||||
'RGBA'
|
|
||||||
)
|
|
||||||
floor_pic.paste(floor_top_pic, (0, 0), floor_top_pic)
|
floor_pic.paste(floor_top_pic, (0, 0), floor_top_pic)
|
||||||
|
|
||||||
floor_center_pic = Image.open(
|
floor_center_pic = Image.open(TEXT_PATH / "floor_bg_center.png").convert("RGBA")
|
||||||
TEXT_PATH / 'floor_bg_center.png'
|
|
||||||
).convert('RGBA')
|
|
||||||
floor_center_pic = floor_center_pic.resize(
|
floor_center_pic = floor_center_pic.resize(
|
||||||
(900, detail_h_list[index_floor] - 170)
|
(900, detail_h_list[index_floor] - 170)
|
||||||
)
|
)
|
||||||
floor_pic.paste(floor_center_pic, (0, 100), floor_center_pic)
|
floor_pic.paste(floor_center_pic, (0, 100), floor_center_pic)
|
||||||
|
|
||||||
floor_bot_pic = Image.open(TEXT_PATH / 'floor_bg_bot.png').convert(
|
floor_bot_pic = Image.open(TEXT_PATH / "floor_bg_bot.png").convert("RGBA")
|
||||||
'RGBA'
|
|
||||||
)
|
|
||||||
floor_pic.paste(
|
floor_pic.paste(
|
||||||
floor_bot_pic, (0, detail_h_list[index_floor] - 70), floor_bot_pic
|
floor_bot_pic, (0, detail_h_list[index_floor] - 70), floor_bot_pic
|
||||||
)
|
)
|
||||||
@ -707,39 +683,39 @@ async def draw_rogue_locust_img(
|
|||||||
difficulty_name = difficultylist[detail.difficulty]
|
difficulty_name = difficultylist[detail.difficulty]
|
||||||
|
|
||||||
time_array = detail.finish_time
|
time_array = detail.finish_time
|
||||||
time_str = f'{time_array.year}-{time_array.month}'
|
time_str = f"{time_array.year}-{time_array.month}"
|
||||||
time_str = f'{time_str}-{time_array.day}'
|
time_str = f"{time_str}-{time_array.day}"
|
||||||
time_str = f'{time_str} {time_array.hour}:{time_array.minute}'
|
time_str = f"{time_str} {time_array.hour}:{time_array.minute}"
|
||||||
floor_pic_draw = ImageDraw.Draw(floor_pic)
|
floor_pic_draw = ImageDraw.Draw(floor_pic)
|
||||||
floor_pic_draw.text(
|
floor_pic_draw.text(
|
||||||
(450, 60),
|
(450, 60),
|
||||||
f'{floor_name} {difficulty_name}',
|
f"{floor_name} {difficulty_name}",
|
||||||
white_color,
|
white_color,
|
||||||
sr_font_42,
|
sr_font_42,
|
||||||
'mm',
|
"mm",
|
||||||
)
|
)
|
||||||
floor_pic_draw.text(
|
floor_pic_draw.text(
|
||||||
(93, 120),
|
(93, 120),
|
||||||
f'挑战时间:{time_str}',
|
f"挑战时间:{time_str}",
|
||||||
gray_color,
|
gray_color,
|
||||||
sr_font_22,
|
sr_font_22,
|
||||||
'lm',
|
"lm",
|
||||||
)
|
)
|
||||||
if detail.fury.type == 1:
|
if detail.fury.type == 1:
|
||||||
floor_pic_draw.text(
|
floor_pic_draw.text(
|
||||||
(800, 120),
|
(800, 120),
|
||||||
f'扰动等级:{detail.fury.point}',
|
f"扰动等级:{detail.fury.point}",
|
||||||
gray_color,
|
gray_color,
|
||||||
sr_font_22,
|
sr_font_22,
|
||||||
'rm',
|
"rm",
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
floor_pic_draw.text(
|
floor_pic_draw.text(
|
||||||
(800, 120),
|
(800, 120),
|
||||||
f'位面紊乱倒计时:{detail.fury.point}',
|
f"位面紊乱倒计时:{detail.fury.point}",
|
||||||
gray_color,
|
gray_color,
|
||||||
sr_font_22,
|
sr_font_22,
|
||||||
'rm',
|
"rm",
|
||||||
)
|
)
|
||||||
|
|
||||||
# 角色
|
# 角色
|
||||||
@ -767,10 +743,10 @@ async def draw_rogue_locust_img(
|
|||||||
if len(detail.base_type_list) > 0:
|
if len(detail.base_type_list) > 0:
|
||||||
floor_pic_draw.text(
|
floor_pic_draw.text(
|
||||||
(93, 370),
|
(93, 370),
|
||||||
'获得祝福',
|
"获得祝福",
|
||||||
white_color,
|
white_color,
|
||||||
sr_font_34,
|
sr_font_34,
|
||||||
'lm',
|
"lm",
|
||||||
)
|
)
|
||||||
floor_pic.paste(content_center, (0, 390), content_center)
|
floor_pic.paste(content_center, (0, 390), content_center)
|
||||||
for buff in detail.buffs:
|
for buff in detail.buffs:
|
||||||
@ -791,10 +767,10 @@ async def draw_rogue_locust_img(
|
|||||||
if len(detail.miracles) > 0:
|
if len(detail.miracles) > 0:
|
||||||
floor_pic_draw.text(
|
floor_pic_draw.text(
|
||||||
(93, 370 + miracles_height + 60),
|
(93, 370 + miracles_height + 60),
|
||||||
'获得奇物',
|
"获得奇物",
|
||||||
white_color,
|
white_color,
|
||||||
sr_font_34,
|
sr_font_34,
|
||||||
'lm',
|
"lm",
|
||||||
)
|
)
|
||||||
floor_pic.paste(
|
floor_pic.paste(
|
||||||
content_center, (0, 370 + miracles_height + 80), content_center
|
content_center, (0, 370 + miracles_height + 80), content_center
|
||||||
@ -812,10 +788,10 @@ async def draw_rogue_locust_img(
|
|||||||
if len(detail.blocks) > 0:
|
if len(detail.blocks) > 0:
|
||||||
floor_pic_draw.text(
|
floor_pic_draw.text(
|
||||||
(93, 370 + blocks_height + 60),
|
(93, 370 + blocks_height + 60),
|
||||||
'通过区域类型',
|
"通过区域类型",
|
||||||
white_color,
|
white_color,
|
||||||
sr_font_34,
|
sr_font_34,
|
||||||
'lm',
|
"lm",
|
||||||
)
|
)
|
||||||
floor_pic.paste(
|
floor_pic.paste(
|
||||||
content_center, (0, 370 + blocks_height + 80), content_center
|
content_center, (0, 370 + blocks_height + 80), content_center
|
||||||
@ -842,5 +818,5 @@ async def draw_rogue_locust_img(
|
|||||||
# )
|
# )
|
||||||
|
|
||||||
res = await convert_img(img)
|
res = await convert_img(img)
|
||||||
logger.info('[查询寰宇蝗灾]绘图已完成,等待发送!')
|
logger.info("[查询寰宇蝗灾]绘图已完成,等待发送!")
|
||||||
return res
|
return res
|
||||||
|
@ -6,14 +6,14 @@ from PIL import Image
|
|||||||
from aiohttp import ClientSession
|
from aiohttp import ClientSession
|
||||||
from gsuid_core.data_store import get_res_path
|
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)
|
ROLEINFO_PATH.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
|
||||||
async def get_icon(url: str) -> Image.Image:
|
async def get_icon(url: str) -> Image.Image:
|
||||||
name = url.split('/')[-1]
|
name = url.split("/")[-1]
|
||||||
path = ROLEINFO_PATH / name
|
path = ROLEINFO_PATH / name
|
||||||
if (path).exists():
|
if (path).exists():
|
||||||
content = path.read_bytes()
|
content = path.read_bytes()
|
||||||
@ -21,6 +21,6 @@ async def get_icon(url: str) -> Image.Image:
|
|||||||
async with ClientSession() as client:
|
async with ClientSession() as client:
|
||||||
async with client.get(url) as resp:
|
async with client.get(url) as resp:
|
||||||
content = await resp.read()
|
content = await resp.read()
|
||||||
with Path.open(path, 'wb') as f:
|
with Path.open(path, "wb") as f:
|
||||||
f.write(content)
|
f.write(content)
|
||||||
return Image.open(BytesIO(content)).convert('RGBA')
|
return Image.open(BytesIO(content)).convert("RGBA")
|
||||||
|
@ -1,47 +1,45 @@
|
|||||||
import re
|
import re
|
||||||
|
|
||||||
from gsuid_core.sv import SV
|
from .draw_roleinfo_card import get_detail_img, get_role_img
|
||||||
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 ..utils.error_reply import UID_HINT
|
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):
|
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:
|
if name:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
uid = await get_uid(bot, ev)
|
uid = await get_uid(bot, ev, GsBind, "sr")
|
||||||
if uid is None:
|
if uid is None:
|
||||||
return '你还没有绑定UID噢,请使用[sr绑定uid123]完成绑定!'
|
return "你还没有绑定UID噢,请使用[sr绑定uid123]完成绑定!"
|
||||||
|
|
||||||
logger.info(f'[sr查询信息]UID: {uid}')
|
logger.info(f"[sr查询信息]UID: {uid}")
|
||||||
await bot.logger.info('开始执行[sr查询信息]')
|
await bot.logger.info("开始执行[sr查询信息]")
|
||||||
await bot.send(await get_role_img(uid))
|
await bot.send(await get_role_img(uid))
|
||||||
return None
|
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):
|
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:
|
if name:
|
||||||
return None
|
return None
|
||||||
get_uid_ = await get_uid(bot, ev, True)
|
uid, user_id = await get_uid(bot, ev, GsBind, "sr", True)
|
||||||
if get_uid_ is None:
|
|
||||||
return await bot.send(UID_HINT)
|
|
||||||
uid, user_id = get_uid_
|
|
||||||
if uid is None:
|
if uid is None:
|
||||||
return await bot.send(UID_HINT)
|
return await bot.send(UID_HINT)
|
||||||
|
|
||||||
logger.info(f'[sr查询信息]UID: {uid}')
|
logger.info(f"[sr查询信息]UID: {uid}")
|
||||||
await bot.logger.info('开始执行[sr查询信息]')
|
await bot.logger.info("开始执行[sr查询信息]")
|
||||||
await bot.send(await get_detail_img(user_id, uid, ev.sender))
|
await bot.send(await get_detail_img(user_id, uid, ev.sender))
|
||||||
return None
|
return None
|
||||||
|
@ -1,26 +1,16 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
from pathlib import Path
|
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 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 (
|
from ..sruid_utils.api.mys.models import (
|
||||||
Stats,
|
|
||||||
AvatarDetail,
|
AvatarDetail,
|
||||||
RoleBasicInfo,
|
|
||||||
AvatarListItem,
|
AvatarListItem,
|
||||||
AvatarListItemDetail,
|
AvatarListItemDetail,
|
||||||
|
RoleBasicInfo,
|
||||||
|
Stats,
|
||||||
)
|
)
|
||||||
|
from ..utils.fonts.first_world import fw_font_24
|
||||||
from ..utils.fonts.starrail_fonts import (
|
from ..utils.fonts.starrail_fonts import (
|
||||||
sr_font_22,
|
sr_font_22,
|
||||||
sr_font_24,
|
sr_font_24,
|
||||||
@ -28,41 +18,41 @@ from ..utils.fonts.starrail_fonts import (
|
|||||||
sr_font_30,
|
sr_font_30,
|
||||||
sr_font_36,
|
sr_font_36,
|
||||||
)
|
)
|
||||||
|
from ..utils.mys_api import mys_api
|
||||||
|
|
||||||
TEXT_PATH = Path(__file__).parent / 'texture2D'
|
from PIL import Image, ImageDraw
|
||||||
|
from gsuid_core.logger import logger
|
||||||
bg1 = Image.open(TEXT_PATH / 'bg1.png')
|
from gsuid_core.utils.error_reply import get_error
|
||||||
bg2 = Image.open(TEXT_PATH / 'bg2.png')
|
from gsuid_core.utils.image.convert import convert_img
|
||||||
bg3 = Image.open(TEXT_PATH / 'bg3.png')
|
from gsuid_core.utils.image.image_tools import (
|
||||||
user_avatar = (
|
draw_pic_with_ring,
|
||||||
Image.open(TEXT_PATH / '200101.png').resize((220, 220)).convert('RGBA')
|
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')
|
TEXT_PATH = Path(__file__).parent / "texture2D"
|
||||||
circle = Image.open(TEXT_PATH / 'char_weapon_bg.png').convert('RGBA')
|
|
||||||
bg_img = Image.open(TEXT_PATH / 'bg_light.jpg')
|
bg1 = Image.open(TEXT_PATH / "bg1.png")
|
||||||
rank_bg = Image.open(TEXT_PATH / 'rank_bg.png').convert('RGBA')
|
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)
|
bg_color = (248, 248, 248)
|
||||||
white_color = (255, 255, 255)
|
white_color = (255, 255, 255)
|
||||||
color_color = (40, 18, 7)
|
color_color = (40, 18, 7)
|
||||||
first_color = (22, 8, 31)
|
first_color = (22, 8, 31)
|
||||||
|
|
||||||
elements = {
|
elements = {
|
||||||
'ice': Image.open(TEXT_PATH / 'IconNatureColorIce.png').convert('RGBA'),
|
"ice": Image.open(TEXT_PATH / "IconNatureColorIce.png").convert("RGBA"),
|
||||||
'fire': Image.open(TEXT_PATH / 'IconNatureColorFire.png').convert('RGBA'),
|
"fire": Image.open(TEXT_PATH / "IconNatureColorFire.png").convert("RGBA"),
|
||||||
'imaginary': Image.open(
|
"imaginary": Image.open(TEXT_PATH / "IconNatureColorImaginary.png").convert("RGBA"),
|
||||||
TEXT_PATH / 'IconNatureColorImaginary.png'
|
"quantum": Image.open(TEXT_PATH / "IconNatureColorQuantum.png").convert("RGBA"),
|
||||||
).convert('RGBA'),
|
"lightning": Image.open(TEXT_PATH / "IconNatureColorThunder.png").convert("RGBA"),
|
||||||
'quantum': Image.open(TEXT_PATH / 'IconNatureColorQuantum.png').convert(
|
"wind": Image.open(TEXT_PATH / "IconNatureColorWind.png").convert("RGBA"),
|
||||||
'RGBA'
|
"physical": Image.open(TEXT_PATH / "IconNaturePhysical.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)
|
return await draw_role_card(uid)
|
||||||
|
|
||||||
|
|
||||||
async def get_detail_img(
|
async def get_detail_img(qid: Union[str, int], uid: str, sender) -> Union[bytes, str]:
|
||||||
qid: Union[str, int], uid: str, sender
|
|
||||||
) -> Union[bytes, str]:
|
|
||||||
return await get_detail_card(qid, uid, sender)
|
return await get_detail_card(qid, uid, sender)
|
||||||
|
|
||||||
|
|
||||||
def _lv(level: int) -> str:
|
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(
|
async def _draw_card_1(
|
||||||
@ -100,16 +88,14 @@ async def _draw_card_1(
|
|||||||
bg1_draw = ImageDraw.Draw(img_bg1)
|
bg1_draw = ImageDraw.Draw(img_bg1)
|
||||||
|
|
||||||
# 写Nickname
|
# 写Nickname
|
||||||
bg1_draw.text(
|
bg1_draw.text((400, 85), nickname, font=sr_font_36, fill=white_color, anchor="mm")
|
||||||
(400, 85), nickname, font=sr_font_36, fill=white_color, anchor='mm'
|
|
||||||
)
|
|
||||||
# 写UID
|
# 写UID
|
||||||
bg1_draw.text(
|
bg1_draw.text(
|
||||||
(400, 165),
|
(400, 165),
|
||||||
f'UID {sr_uid}',
|
f"UID {sr_uid}",
|
||||||
font=sr_font_30,
|
font=sr_font_30,
|
||||||
fill=white_color,
|
fill=white_color,
|
||||||
anchor='mm',
|
anchor="mm",
|
||||||
)
|
)
|
||||||
# 贴头像
|
# 贴头像
|
||||||
img_bg1.paste(user_avatar, (286, 213), mask=user_avatar)
|
img_bg1.paste(user_avatar, (286, 213), mask=user_avatar)
|
||||||
@ -120,31 +106,31 @@ async def _draw_card_1(
|
|||||||
str(active_days),
|
str(active_days),
|
||||||
font=sr_font_36,
|
font=sr_font_36,
|
||||||
fill=white_color,
|
fill=white_color,
|
||||||
anchor='mm',
|
anchor="mm",
|
||||||
) # 活跃天数
|
) # 活跃天数
|
||||||
bg1_draw.text(
|
bg1_draw.text(
|
||||||
(270, 590),
|
(270, 590),
|
||||||
str(avater_num),
|
str(avater_num),
|
||||||
font=sr_font_36,
|
font=sr_font_36,
|
||||||
fill=white_color,
|
fill=white_color,
|
||||||
anchor='mm',
|
anchor="mm",
|
||||||
) # 解锁角色
|
) # 解锁角色
|
||||||
bg1_draw.text(
|
bg1_draw.text(
|
||||||
(398, 590),
|
(398, 590),
|
||||||
str(achievement_num),
|
str(achievement_num),
|
||||||
font=sr_font_36,
|
font=sr_font_36,
|
||||||
fill=white_color,
|
fill=white_color,
|
||||||
anchor='mm',
|
anchor="mm",
|
||||||
) # 达成成就
|
) # 达成成就
|
||||||
bg1_draw.text(
|
bg1_draw.text(
|
||||||
(525, 590),
|
(525, 590),
|
||||||
str(chest_num),
|
str(chest_num),
|
||||||
font=sr_font_36,
|
font=sr_font_36,
|
||||||
fill=white_color,
|
fill=white_color,
|
||||||
anchor='mm',
|
anchor="mm",
|
||||||
) # 战利品开启
|
) # 战利品开启
|
||||||
bg1_draw.text(
|
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,
|
abyss_process,
|
||||||
font=sr_font_30,
|
font=sr_font_30,
|
||||||
fill=first_color,
|
fill=first_color,
|
||||||
anchor='mm',
|
anchor="mm",
|
||||||
)
|
)
|
||||||
|
|
||||||
return img_bg1
|
return img_bg1
|
||||||
@ -174,10 +160,10 @@ async def _draw_avatar_card(
|
|||||||
char_bg.paste(rank_bg, (89, 6), mask=rank_bg)
|
char_bg.paste(rank_bg, (89, 6), mask=rank_bg)
|
||||||
char_draw.text(
|
char_draw.text(
|
||||||
(100, 21),
|
(100, 21),
|
||||||
f'{avatar.rank}',
|
f"{avatar.rank}",
|
||||||
font=sr_font_22,
|
font=sr_font_22,
|
||||||
fill=white_color,
|
fill=white_color,
|
||||||
anchor='mm',
|
anchor="mm",
|
||||||
)
|
)
|
||||||
|
|
||||||
if equip := equips[avatar.id]:
|
if equip := equips[avatar.id]:
|
||||||
@ -190,7 +176,7 @@ async def _draw_avatar_card(
|
|||||||
_lv(avatar.level),
|
_lv(avatar.level),
|
||||||
font=sr_font_24,
|
font=sr_font_24,
|
||||||
fill=color_color,
|
fill=color_color,
|
||||||
anchor='mm',
|
anchor="mm",
|
||||||
)
|
)
|
||||||
return char_bg
|
return char_bg
|
||||||
|
|
||||||
@ -214,12 +200,9 @@ async def _draw_card_2(
|
|||||||
) -> Image.Image:
|
) -> Image.Image:
|
||||||
# 角色部分 每五个一组
|
# 角色部分 每五个一组
|
||||||
lines = await asyncio.gather(
|
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
|
y = 0
|
||||||
for line in lines:
|
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)
|
return get_error(role_basic_info)
|
||||||
else:
|
else:
|
||||||
role_basic_info = {}
|
role_basic_info = {}
|
||||||
role_basic_info['nickname'] = '开拓者'
|
role_basic_info["nickname"] = "开拓者"
|
||||||
role_basic_info['level'] = 0
|
role_basic_info["level"] = 0
|
||||||
|
|
||||||
if isinstance(role_index, int):
|
if isinstance(role_index, int):
|
||||||
return get_error(role_index)
|
return get_error(role_index)
|
||||||
@ -266,7 +249,7 @@ async def draw_role_card(sr_uid: str) -> Union[bytes, str]:
|
|||||||
)
|
)
|
||||||
img2: Image.Image
|
img2: Image.Image
|
||||||
height = img2.size[1]
|
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(img1, (0, 0))
|
||||||
img.paste(img2, (0, 810))
|
img.paste(img2, (0, 810))
|
||||||
img.paste(bg3, (0, height + 810))
|
img.paste(bg3, (0, height + 810))
|
||||||
@ -279,69 +262,69 @@ async def _draw_detail_card(
|
|||||||
index: int,
|
index: int,
|
||||||
char_info: Image.Image,
|
char_info: Image.Image,
|
||||||
) -> Image.Image:
|
) -> Image.Image:
|
||||||
if str(avatar.rarity) == '5':
|
if str(avatar.rarity) == "5":
|
||||||
avatar_img = Image.open(TEXT_PATH / 'bar_5.png')
|
avatar_img = Image.open(TEXT_PATH / "bar_5.png")
|
||||||
else:
|
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)
|
avatar_draw = ImageDraw.Draw(avatar_img)
|
||||||
char_icon = (await get_icon(avatar.icon)).resize((40, 40))
|
char_icon = (await get_icon(avatar.icon)).resize((40, 40))
|
||||||
element_icon = elements[avatar.element]
|
element_icon = elements[avatar.element]
|
||||||
avatar_img.paste(char_icon, (75, 10), mask=char_icon)
|
avatar_img.paste(char_icon, (75, 10), mask=char_icon)
|
||||||
avatar_draw.text(
|
avatar_draw.text(
|
||||||
(130, 30),
|
(130, 30),
|
||||||
f'{avatar.name}',
|
f"{avatar.name}",
|
||||||
first_color,
|
first_color,
|
||||||
sr_font_24,
|
sr_font_24,
|
||||||
'lm',
|
"lm",
|
||||||
)
|
)
|
||||||
avatar_img.paste(element_icon, (270, 10), mask=element_icon)
|
avatar_img.paste(element_icon, (270, 10), mask=element_icon)
|
||||||
|
|
||||||
avatar_draw.text(
|
avatar_draw.text(
|
||||||
(339, 30),
|
(339, 30),
|
||||||
f'{avatar.level}',
|
f"{avatar.level}",
|
||||||
first_color,
|
first_color,
|
||||||
sr_font_24,
|
sr_font_24,
|
||||||
'mm',
|
"mm",
|
||||||
)
|
)
|
||||||
|
|
||||||
avatar_draw.text(
|
avatar_draw.text(
|
||||||
(385, 30),
|
(385, 30),
|
||||||
f'{avatar.rank}',
|
f"{avatar.rank}",
|
||||||
first_color,
|
first_color,
|
||||||
sr_font_24,
|
sr_font_24,
|
||||||
'mm',
|
"mm",
|
||||||
)
|
)
|
||||||
|
|
||||||
avatar_draw.text(
|
avatar_draw.text(
|
||||||
(429, 30),
|
(429, 30),
|
||||||
f'{avatar_detail.skills[0].cur_level}',
|
f"{avatar_detail.skills[0].cur_level}",
|
||||||
first_color,
|
first_color,
|
||||||
sr_font_24,
|
sr_font_24,
|
||||||
'mm',
|
"mm",
|
||||||
)
|
)
|
||||||
|
|
||||||
avatar_draw.text(
|
avatar_draw.text(
|
||||||
(469, 30),
|
(469, 30),
|
||||||
f'{avatar_detail.skills[1].cur_level}',
|
f"{avatar_detail.skills[1].cur_level}",
|
||||||
first_color,
|
first_color,
|
||||||
sr_font_24,
|
sr_font_24,
|
||||||
'mm',
|
"mm",
|
||||||
)
|
)
|
||||||
|
|
||||||
avatar_draw.text(
|
avatar_draw.text(
|
||||||
(515, 30),
|
(515, 30),
|
||||||
f'{avatar_detail.skills[2].cur_level}',
|
f"{avatar_detail.skills[2].cur_level}",
|
||||||
first_color,
|
first_color,
|
||||||
sr_font_24,
|
sr_font_24,
|
||||||
'mm',
|
"mm",
|
||||||
)
|
)
|
||||||
|
|
||||||
avatar_draw.text(
|
avatar_draw.text(
|
||||||
(553, 30),
|
(553, 30),
|
||||||
f'{avatar_detail.skills[3].cur_level}',
|
f"{avatar_detail.skills[3].cur_level}",
|
||||||
first_color,
|
first_color,
|
||||||
sr_font_24,
|
sr_font_24,
|
||||||
'mm',
|
"mm",
|
||||||
)
|
)
|
||||||
|
|
||||||
if avatar.equip:
|
if avatar.equip:
|
||||||
@ -350,26 +333,26 @@ async def _draw_detail_card(
|
|||||||
|
|
||||||
avatar_draw.text(
|
avatar_draw.text(
|
||||||
(680, 30),
|
(680, 30),
|
||||||
f'{avatar.equip.rank}',
|
f"{avatar.equip.rank}",
|
||||||
first_color,
|
first_color,
|
||||||
sr_font_24,
|
sr_font_24,
|
||||||
'mm',
|
"mm",
|
||||||
)
|
)
|
||||||
|
|
||||||
avatar_draw.text(
|
avatar_draw.text(
|
||||||
(734, 30),
|
(734, 30),
|
||||||
f'Lv.{avatar.equip.level}',
|
f"Lv.{avatar.equip.level}",
|
||||||
first_color,
|
first_color,
|
||||||
sr_font_24,
|
sr_font_24,
|
||||||
'lm',
|
"lm",
|
||||||
)
|
)
|
||||||
|
|
||||||
avatar_draw.text(
|
avatar_draw.text(
|
||||||
(804, 30),
|
(804, 30),
|
||||||
f'{avatar.equip.name}',
|
f"{avatar.equip.name}",
|
||||||
first_color,
|
first_color,
|
||||||
sr_font_24,
|
sr_font_24,
|
||||||
'lm',
|
"lm",
|
||||||
)
|
)
|
||||||
|
|
||||||
char_info.paste(avatar_img, (0, 585 + 62 * index), mask=avatar_img)
|
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(
|
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]:
|
) -> Union[bytes, str]:
|
||||||
# 获取角色列表
|
# 获取角色列表
|
||||||
avatar_list = await mys_api.get_avatar_info(sr_uid, 1001)
|
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_info = char_info.resize((1050, img_height))
|
||||||
char_img_draw = ImageDraw.Draw(char_info)
|
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)
|
char_info.paste(char_title, (0, 0), char_title)
|
||||||
|
|
||||||
# 获取头像
|
# 获取头像
|
||||||
_id = str(qid)
|
_id = str(qid)
|
||||||
if _id.startswith('http'):
|
if _id.startswith("http"):
|
||||||
char_pic = await get_qq_avatar(avatar_url=_id)
|
char_pic = await get_qq_avatar(avatar_url=_id)
|
||||||
elif sender.get('avatar') is not None:
|
elif sender.get("avatar") is not None:
|
||||||
char_pic = await get_qq_avatar(avatar_url=sender['avatar'])
|
char_pic = await get_qq_avatar(avatar_url=sender["avatar"])
|
||||||
else:
|
else:
|
||||||
char_pic = await get_qq_avatar(qid=qid)
|
char_pic = await get_qq_avatar(qid=qid)
|
||||||
char_pic = await draw_pic_with_ring(char_pic, 250, None, False)
|
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_info.paste(char_pic, (400, 88), char_pic)
|
||||||
|
|
||||||
# 绘制抬头
|
# 绘制抬头
|
||||||
char_img_draw.text(
|
char_img_draw.text((525, 420), f"UID {sr_uid}", white_color, sr_font_28, "mm")
|
||||||
(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)
|
char_info.paste(title_img, (0, 515), mask=title_img)
|
||||||
|
|
||||||
for index, avatar in enumerate(avatar_list.avatar_list):
|
for index, avatar in enumerate(avatar_list.avatar_list):
|
||||||
@ -431,12 +412,12 @@ async def get_detail_card(
|
|||||||
# 写底层文字
|
# 写底层文字
|
||||||
char_img_draw.text(
|
char_img_draw.text(
|
||||||
(525, img_height - 45),
|
(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),
|
(255, 255, 255),
|
||||||
fw_font_24,
|
fw_font_24,
|
||||||
'mm',
|
"mm",
|
||||||
)
|
)
|
||||||
|
|
||||||
res = await convert_img(char_info)
|
res = await convert_img(char_info)
|
||||||
logger.info('[查询练度统计]绘图已完成,等待发送!')
|
logger.info("[查询练度统计]绘图已完成,等待发送!")
|
||||||
return res
|
return res
|
||||||
|
@ -6,9 +6,9 @@ from PIL import Image
|
|||||||
from aiohttp import ClientSession
|
from aiohttp import ClientSession
|
||||||
from gsuid_core.data_store import get_res_path
|
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)
|
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:
|
async def get_icon(url: str) -> Image.Image:
|
||||||
name = url.split('/')[-1]
|
name = url.split("/")[-1]
|
||||||
path = ROLEINFO_PATH / name
|
path = ROLEINFO_PATH / name
|
||||||
if (path).exists():
|
if (path).exists():
|
||||||
content = path.read_bytes()
|
content = path.read_bytes()
|
||||||
@ -26,6 +26,6 @@ async def get_icon(url: str) -> Image.Image:
|
|||||||
async with ClientSession() as client:
|
async with ClientSession() as client:
|
||||||
async with client.get(url) as resp:
|
async with client.get(url) as resp:
|
||||||
content = await resp.read()
|
content = await resp.read()
|
||||||
with Path.open(path, 'wb') as f:
|
with Path.open(path, "wb") as f:
|
||||||
f.write(content)
|
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.database.models import GsBind
|
||||||
from gsuid_core.utils.sign.sign import daily_sign, sign_in
|
from gsuid_core.utils.sign.sign import daily_sign, sign_in
|
||||||
|
|
||||||
SIGN_TIME = srconfig.get_config('SignTime').data
|
SIGN_TIME = srconfig.get_config("SignTime").data
|
||||||
IS_REPORT = srconfig.get_config('PrivateSignReport').data
|
IS_REPORT = srconfig.get_config("PrivateSignReport").data
|
||||||
|
|
||||||
sv_sign = SV('星穹铁道签到')
|
sv_sign = SV("星穹铁道签到")
|
||||||
sv_sign_config = SV('星穹铁道管理', pm=2)
|
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):
|
async def get_sign_func(bot: Bot, ev: Event):
|
||||||
logger.info(f'[星穹铁道] [签到] 用户: {ev.user_id}')
|
logger.info(f"[星穹铁道] [签到] 用户: {ev.user_id}")
|
||||||
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:
|
if uid is None:
|
||||||
return await bot.send(UID_HINT)
|
return await bot.send(UID_HINT)
|
||||||
logger.info(f'[星穹铁道] [签到] UID: {uid}')
|
logger.info(f"[星穹铁道] [签到] UID: {uid}")
|
||||||
await bot.send(await sign_in(uid, 'sr'))
|
await bot.send(await sign_in(uid, "sr"))
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
@sv_sign_config.on_fullmatch(f'{PREFIX}全部重签')
|
@sv_sign_config.on_fullmatch(f"{PREFIX}全部重签")
|
||||||
async def recheck(bot: Bot, ev: Event):
|
async def recheck(bot: Bot, ev: Event):
|
||||||
await bot.logger.info('开始执行[全部重签]')
|
await bot.logger.info("开始执行[全部重签]")
|
||||||
await bot.send('[星穹铁道] [全部重签] 已开始执行!')
|
await bot.send("[星穹铁道] [全部重签] 已开始执行!")
|
||||||
result = await daily_sign('sr')
|
result = await daily_sign("sr")
|
||||||
if not IS_REPORT:
|
if not IS_REPORT:
|
||||||
result['private_msg_dict'] = {}
|
result["private_msg_dict"] = {}
|
||||||
await send_board_cast_msg(result)
|
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():
|
async def sr_sign_at_night():
|
||||||
if srconfig.get_config('SchedSignin').data:
|
if srconfig.get_config("SchedSignin").data:
|
||||||
result = await daily_sign('sr')
|
result = await daily_sign("sr")
|
||||||
if not IS_REPORT:
|
if not IS_REPORT:
|
||||||
result['private_msg_dict'] = {}
|
result["private_msg_dict"] = {}
|
||||||
await send_board_cast_msg(result)
|
await send_board_cast_msg(result)
|
||||||
|
@ -1,82 +1,83 @@
|
|||||||
import asyncio
|
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.bot import Bot
|
||||||
from gsuid_core.gss import gss
|
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.logger import logger
|
||||||
|
from gsuid_core.models import Event
|
||||||
from gsuid_core.segment import MessageSegment
|
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
|
sv_get_stamina = SV("sr查询体力")
|
||||||
from .notice import get_notice_list
|
sv_get_stamina_admin = SV("sr强制推送", pm=1)
|
||||||
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.on_fullmatch(f'{PREFIX}当前状态')
|
@sv_get_stamina.on_fullmatch(f"{PREFIX}当前状态")
|
||||||
async def send_daily_info(bot: Bot, ev: Event):
|
async def send_daily_info(bot: Bot, ev: Event):
|
||||||
await bot.logger.info('开始执行[sr每日信息文字版]')
|
await bot.logger.info("开始执行[sr每日信息文字版]")
|
||||||
uid = await get_uid(bot, ev)
|
uid = await get_uid(bot, ev, GsBind, "sr")
|
||||||
if uid is None:
|
if uid is None:
|
||||||
return await bot.send(UID_HINT)
|
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)
|
im = await get_stamina_text(uid)
|
||||||
await bot.send(im)
|
await bot.send(im)
|
||||||
return None
|
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):
|
async def force_notice_job(bot: Bot, ev: Event):
|
||||||
await bot.logger.info('开始执行[sr强制推送体力信息]')
|
await bot.logger.info("开始执行[sr强制推送体力信息]")
|
||||||
await sr_notice_job()
|
await sr_notice_job()
|
||||||
|
|
||||||
|
|
||||||
@scheduler.scheduled_job('cron', minute='*/30')
|
@scheduler.scheduled_job("cron", minute="*/30")
|
||||||
async def sr_notice_job():
|
async def sr_notice_job():
|
||||||
result = await get_notice_list()
|
result = await get_notice_list()
|
||||||
logger.info('[sr推送检查]完成!等待消息推送中...')
|
logger.info("[sr推送检查]完成!等待消息推送中...")
|
||||||
logger.debug(result)
|
logger.debug(result)
|
||||||
|
|
||||||
# 执行私聊推送
|
# 执行私聊推送
|
||||||
for bot_id in result:
|
for bot_id in result:
|
||||||
for BOT_ID in gss.active_bot:
|
for BOT_ID in gss.active_bot:
|
||||||
bot = gss.active_bot[BOT_ID]
|
bot = gss.active_bot[BOT_ID]
|
||||||
for user_id in result[bot_id]['direct']:
|
for user_id in result[bot_id]["direct"]:
|
||||||
msg = result[bot_id]['direct'][user_id]
|
msg = result[bot_id]["direct"][user_id]
|
||||||
await bot.target_send(msg, 'direct', user_id, bot_id, '', '')
|
await bot.target_send(msg, "direct", user_id, bot_id, "", "")
|
||||||
await asyncio.sleep(0.5)
|
await asyncio.sleep(0.5)
|
||||||
logger.info('[sr推送检查] 私聊推送完成')
|
logger.info("[sr推送检查] 私聊推送完成")
|
||||||
for gid in result[bot_id]['group']:
|
for gid in result[bot_id]["group"]:
|
||||||
msg_list = []
|
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_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))
|
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)
|
await asyncio.sleep(0.5)
|
||||||
logger.info('[sr推送检查] 群聊推送完成')
|
logger.info("[sr推送检查] 群聊推送完成")
|
||||||
|
|
||||||
|
|
||||||
@sv_get_stamina.on_fullmatch(
|
@sv_get_stamina.on_fullmatch(
|
||||||
(
|
(
|
||||||
f'{PREFIX}每日',
|
f"{PREFIX}每日",
|
||||||
f'{PREFIX}mr',
|
f"{PREFIX}mr",
|
||||||
f'{PREFIX}实时便笺',
|
f"{PREFIX}实时便笺",
|
||||||
f'{PREFIX}便笺',
|
f"{PREFIX}便笺",
|
||||||
f'{PREFIX}便签',
|
f"{PREFIX}便签",
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
async def send_daily_info_pic(bot: Bot, ev: Event):
|
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
|
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)
|
im = await get_stamina_img(bot.bot_id, user_id)
|
||||||
await bot.send(im)
|
await bot.send(im)
|
||||||
|
@ -3,16 +3,14 @@ from io import BytesIO
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
import aiohttp
|
|
||||||
from PIL import Image, ImageDraw
|
from PIL import Image, ImageDraw
|
||||||
|
import aiohttp
|
||||||
from gsuid_core.logger import logger
|
from gsuid_core.logger import logger
|
||||||
from gsuid_core.utils.database.models import GsBind, GsUser
|
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 ..sruid_utils.api.mys.models import Expedition
|
||||||
from ..starrailuid_config.sr_config import srconfig
|
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.error_reply import get_error as get_error_msg
|
||||||
from ..utils.fonts.starrail_fonts import (
|
from ..utils.fonts.starrail_fonts import (
|
||||||
sr_font_22,
|
sr_font_22,
|
||||||
@ -21,18 +19,20 @@ from ..utils.fonts.starrail_fonts import (
|
|||||||
sr_font_36,
|
sr_font_36,
|
||||||
sr_font_50,
|
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_bg = Image.open(TEXT_PATH / "note_bg.png")
|
||||||
note_travel_bg = Image.open(TEXT_PATH / 'note_travel_bg.png')
|
note_travel_bg = Image.open(TEXT_PATH / "note_travel_bg.png")
|
||||||
warn_pic = Image.open(TEXT_PATH / 'warn.png')
|
warn_pic = Image.open(TEXT_PATH / "warn.png")
|
||||||
|
|
||||||
based_w = 700
|
based_w = 700
|
||||||
based_h = 1200
|
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)
|
first_color = (29, 29, 29)
|
||||||
second_color = (98, 98, 98)
|
second_color = (98, 98, 98)
|
||||||
@ -45,7 +45,7 @@ red_color = (235, 61, 75)
|
|||||||
def seconds2hours(seconds: int) -> str:
|
def seconds2hours(seconds: int) -> str:
|
||||||
m, s = divmod(int(seconds), 60)
|
m, s = divmod(int(seconds), 60)
|
||||||
h, m = divmod(m, 60)
|
h, m = divmod(m, 60)
|
||||||
return '%02d:%02d:%02d' % (h, m, s)
|
return "%02d:%02d:%02d" % (h, m, s)
|
||||||
|
|
||||||
|
|
||||||
async def download_image(url: str) -> Image.Image:
|
async def download_image(url: str) -> Image.Image:
|
||||||
@ -68,14 +68,14 @@ async def _draw_task_img(
|
|||||||
for i in range(2):
|
for i in range(2):
|
||||||
avatar_url = char.avatars[i]
|
avatar_url = char.avatars[i]
|
||||||
image = await download_image(avatar_url)
|
image = await download_image(avatar_url)
|
||||||
char_pic = image.convert('RGBA').resize(
|
char_pic = image.convert("RGBA").resize(
|
||||||
(40, 40),
|
(40, 40),
|
||||||
Image.Resampling.LANCZOS, # type: ignore
|
Image.Resampling.LANCZOS, # type: ignore
|
||||||
)
|
)
|
||||||
note_travel_img.paste(char_pic, (495 + 68 * i, 20), char_pic)
|
note_travel_img.paste(char_pic, (495 + 68 * i, 20), char_pic)
|
||||||
img.paste(note_travel_img, (0, 790 + index * 80), note_travel_img)
|
img.paste(note_travel_img, (0, 790 + index * 80), note_travel_img)
|
||||||
if char.status == 'Finished':
|
if char.status == "Finished":
|
||||||
status_mark = '待收取'
|
status_mark = "待收取"
|
||||||
else:
|
else:
|
||||||
status_mark = str(remaining_time)
|
status_mark = str(remaining_time)
|
||||||
img_draw.text(
|
img_draw.text(
|
||||||
@ -83,55 +83,55 @@ async def _draw_task_img(
|
|||||||
expedition_name,
|
expedition_name,
|
||||||
font=sr_font_22,
|
font=sr_font_22,
|
||||||
fill=white_color,
|
fill=white_color,
|
||||||
anchor='lm',
|
anchor="lm",
|
||||||
)
|
)
|
||||||
img_draw.text(
|
img_draw.text(
|
||||||
(380, 830 + index * 80),
|
(380, 830 + index * 80),
|
||||||
status_mark,
|
status_mark,
|
||||||
font=sr_font_22,
|
font=sr_font_22,
|
||||||
fill=white_color,
|
fill=white_color,
|
||||||
anchor='mm',
|
anchor="mm",
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
note_travel_img = note_travel_bg.copy()
|
note_travel_img = note_travel_bg.copy()
|
||||||
img.paste(note_travel_img, (0, 790 + index * 80), note_travel_img)
|
img.paste(note_travel_img, (0, 790 + index * 80), note_travel_img)
|
||||||
img_draw.text(
|
img_draw.text(
|
||||||
(120, 830 + index * 80),
|
(120, 830 + index * 80),
|
||||||
'等待加入探索队列...',
|
"等待加入探索队列...",
|
||||||
font=sr_font_22,
|
font=sr_font_22,
|
||||||
fill=white_color,
|
fill=white_color,
|
||||||
anchor='lm',
|
anchor="lm",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def get_stamina_img(bot_id: str, user_id: str):
|
async def get_stamina_img(bot_id: str, user_id: str):
|
||||||
try:
|
try:
|
||||||
uid_list = await GsBind.get_uid_list_by_game(user_id, bot_id, 'sr')
|
uid_list = await GsBind.get_uid_list_by_game(user_id, bot_id, "sr")
|
||||||
logger.info(f'[每日信息]UID: {uid_list}')
|
logger.info(f"[每日信息]UID: {uid_list}")
|
||||||
if uid_list is None:
|
if uid_list is None:
|
||||||
return '请先绑定一个UID再来查询哦~'
|
return "请先绑定一个UID再来查询哦~"
|
||||||
# 进行校验UID是否绑定CK
|
# 进行校验UID是否绑定CK
|
||||||
useable_uid_list = []
|
useable_uid_list = []
|
||||||
for uid in 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:
|
if status is not None:
|
||||||
useable_uid_list.append(uid)
|
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:
|
if len(useable_uid_list) == 0:
|
||||||
return '请先绑定一个可用CK & UID再来查询哦~'
|
return "请先绑定一个可用CK & UID再来查询哦~"
|
||||||
# 开始绘图任务
|
# 开始绘图任务
|
||||||
task = []
|
task = []
|
||||||
img = Image.new(
|
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):
|
for uid_index, uid in enumerate(useable_uid_list):
|
||||||
task.append(_draw_all_stamina_img(img, uid, uid_index))
|
task.append(_draw_all_stamina_img(img, uid, uid_index))
|
||||||
await asyncio.gather(*task)
|
await asyncio.gather(*task)
|
||||||
res = await convert_img(img)
|
res = await convert_img(img)
|
||||||
logger.info('[查询每日信息]绘图已完成,等待发送!')
|
logger.info("[查询每日信息]绘图已完成,等待发送!")
|
||||||
except TypeError:
|
except TypeError:
|
||||||
logger.exception('[查询每日信息]绘图失败!')
|
logger.exception("[查询每日信息]绘图失败!")
|
||||||
res = '你绑定过的UID中可能存在过期CK~请重新绑定一下噢~'
|
res = "你绑定过的UID中可能存在过期CK~请重新绑定一下噢~"
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
@ -147,18 +147,18 @@ def get_error(img: Image.Image, uid: str, daily_data: int):
|
|||||||
# 写UID
|
# 写UID
|
||||||
img_draw.text(
|
img_draw.text(
|
||||||
(350, 680),
|
(350, 680),
|
||||||
f'UID{uid}',
|
f"UID{uid}",
|
||||||
font=sr_font_26,
|
font=sr_font_26,
|
||||||
fill=first_color,
|
fill=first_color,
|
||||||
anchor='mm',
|
anchor="mm",
|
||||||
)
|
)
|
||||||
error_text = get_error_msg(daily_data)
|
error_text = get_error_msg(daily_data)
|
||||||
img_draw.text(
|
img_draw.text(
|
||||||
(350, 650),
|
(350, 650),
|
||||||
f'{error_text}, 错误码{daily_data}',
|
f"{error_text}, 错误码{daily_data}",
|
||||||
font=sr_font_26,
|
font=sr_font_26,
|
||||||
fill=red_color,
|
fill=red_color,
|
||||||
anchor='mm',
|
anchor="mm",
|
||||||
)
|
)
|
||||||
return img
|
return img
|
||||||
|
|
||||||
@ -166,7 +166,7 @@ def get_error(img: Image.Image, uid: str, daily_data: int):
|
|||||||
async def seconds2hours_zhcn(seconds: int) -> str:
|
async def seconds2hours_zhcn(seconds: int) -> str:
|
||||||
m, s = divmod(int(seconds), 60)
|
m, s = divmod(int(seconds), 60)
|
||||||
h, m = divmod(m, 60)
|
h, m = divmod(m, 60)
|
||||||
return '%02d小时%02d分' % (h, m)
|
return "%02d小时%02d分" % (h, m)
|
||||||
|
|
||||||
|
|
||||||
async def draw_stamina_img(sr_uid: str) -> Image.Image:
|
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 = transform_fake_resin(_daily_data)
|
||||||
daily_data = _daily_data
|
daily_data = _daily_data
|
||||||
else:
|
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):
|
if isinstance(daily_data, int):
|
||||||
return get_error(img, sr_uid, daily_data)
|
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
|
nickname = role_basic_info.nickname
|
||||||
level = role_basic_info.level
|
level = role_basic_info.level
|
||||||
else:
|
else:
|
||||||
nickname = '开拓者'
|
nickname = "开拓者"
|
||||||
level = '0'
|
level = "0"
|
||||||
|
|
||||||
# 开拓力
|
# 开拓力
|
||||||
stamina = daily_data.current_stamina
|
stamina = daily_data.current_stamina
|
||||||
max_stamina = daily_data.max_stamina
|
max_stamina = daily_data.max_stamina
|
||||||
stamina_str = f'{stamina}/{max_stamina}'
|
stamina_str = f"{stamina}/{max_stamina}"
|
||||||
stamina_percent = stamina / max_stamina
|
stamina_percent = stamina / max_stamina
|
||||||
if stamina_percent > 0.8:
|
if stamina_percent > 0.8:
|
||||||
stamina_color = red_color
|
stamina_color = red_color
|
||||||
@ -216,31 +216,23 @@ async def draw_stamina_img(sr_uid: str) -> Image.Image:
|
|||||||
# 派遣
|
# 派遣
|
||||||
task_task = []
|
task_task = []
|
||||||
for i in range(4):
|
for i in range(4):
|
||||||
char = (
|
char = daily_data.expeditions[i] if i < len(daily_data.expeditions) else None
|
||||||
daily_data.expeditions[i]
|
|
||||||
if i < len(daily_data.expeditions)
|
|
||||||
else None
|
|
||||||
)
|
|
||||||
task_task.append(_draw_task_img(img, img_draw, i, char))
|
task_task.append(_draw_task_img(img, img_draw, i, char))
|
||||||
await asyncio.gather(*task_task)
|
await asyncio.gather(*task_task)
|
||||||
|
|
||||||
# 绘制树脂圆环
|
# 绘制树脂圆环
|
||||||
ring_pic = Image.open(TEXT_PATH / 'ring.apng')
|
ring_pic = Image.open(TEXT_PATH / "ring.apng")
|
||||||
percent = (
|
percent = round(stamina_percent * 89) if round(stamina_percent * 89) <= 89 else 89
|
||||||
round(stamina_percent * 89)
|
|
||||||
if round(stamina_percent * 89) <= 89
|
|
||||||
else 89
|
|
||||||
)
|
|
||||||
ring_pic.seek(percent)
|
ring_pic.seek(percent)
|
||||||
img.paste(ring_pic, (0, 5), ring_pic)
|
img.paste(ring_pic, (0, 5), ring_pic)
|
||||||
|
|
||||||
# 写树脂剩余时间
|
# 写树脂剩余时间
|
||||||
img_draw.text(
|
img_draw.text(
|
||||||
(350, 490),
|
(350, 490),
|
||||||
f'还剩{stamina_recovery_time}',
|
f"还剩{stamina_recovery_time}",
|
||||||
font=sr_font_24,
|
font=sr_font_24,
|
||||||
fill=stamina_color,
|
fill=stamina_color,
|
||||||
anchor='mm',
|
anchor="mm",
|
||||||
)
|
)
|
||||||
# 写Nickname
|
# 写Nickname
|
||||||
img_draw.text(
|
img_draw.text(
|
||||||
@ -248,23 +240,23 @@ async def draw_stamina_img(sr_uid: str) -> Image.Image:
|
|||||||
nickname,
|
nickname,
|
||||||
font=sr_font_36,
|
font=sr_font_36,
|
||||||
fill=white_color,
|
fill=white_color,
|
||||||
anchor='mm',
|
anchor="mm",
|
||||||
)
|
)
|
||||||
# 写开拓等级
|
# 写开拓等级
|
||||||
img_draw.text(
|
img_draw.text(
|
||||||
(350, 190),
|
(350, 190),
|
||||||
f'开拓等级{level}',
|
f"开拓等级{level}",
|
||||||
font=sr_font_24,
|
font=sr_font_24,
|
||||||
fill=white_color,
|
fill=white_color,
|
||||||
anchor='mm',
|
anchor="mm",
|
||||||
)
|
)
|
||||||
# 写UID
|
# 写UID
|
||||||
img_draw.text(
|
img_draw.text(
|
||||||
(350, 663),
|
(350, 663),
|
||||||
f'UID{sr_uid}',
|
f"UID{sr_uid}",
|
||||||
font=sr_font_26,
|
font=sr_font_26,
|
||||||
fill=first_color,
|
fill=first_color,
|
||||||
anchor='mm',
|
anchor="mm",
|
||||||
)
|
)
|
||||||
# 写树脂
|
# 写树脂
|
||||||
img_draw.text(
|
img_draw.text(
|
||||||
@ -272,7 +264,7 @@ async def draw_stamina_img(sr_uid: str) -> Image.Image:
|
|||||||
stamina_str,
|
stamina_str,
|
||||||
font=sr_font_50,
|
font=sr_font_50,
|
||||||
fill=first_color,
|
fill=first_color,
|
||||||
anchor='mm',
|
anchor="mm",
|
||||||
)
|
)
|
||||||
|
|
||||||
return img
|
return img
|
||||||
|
@ -8,11 +8,11 @@ from ..sruid_utils.api.mys.models import DailyNoteData
|
|||||||
from ..starrailuid_config.sr_config import srconfig
|
from ..starrailuid_config.sr_config import srconfig
|
||||||
from ..utils.mys_api import mys_api
|
from ..utils.mys_api import mys_api
|
||||||
|
|
||||||
MR_NOTICE = '\n可发送[srmr]或者[sr每日]来查看更多信息!\n'
|
MR_NOTICE = "\n可发送[srmr]或者[sr每日]来查看更多信息!\n"
|
||||||
|
|
||||||
NOTICE = {
|
NOTICE = {
|
||||||
'stamina': f'你的开拓力快满啦!{MR_NOTICE}',
|
"stamina": f"你的开拓力快满啦!{MR_NOTICE}",
|
||||||
'go': 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()
|
user_list = await GsUser.get_all_push_user_list()
|
||||||
for user in user_list:
|
for user in user_list:
|
||||||
if user.sr_uid is not None:
|
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):
|
if isinstance(raw_data, int):
|
||||||
logger.error(f'[sr推送提醒]获取{user.sr_uid}的数据失败!')
|
logger.error(f"[sr推送提醒]获取{user.sr_uid}的数据失败!")
|
||||||
continue
|
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(
|
msg_dict = await all_check(
|
||||||
user.bot_id,
|
user.bot_id,
|
||||||
raw_data,
|
raw_data,
|
||||||
@ -48,59 +48,59 @@ async def all_check(
|
|||||||
) -> Dict[str, Dict[str, Dict]]:
|
) -> Dict[str, Dict[str, Dict]]:
|
||||||
for mode in NOTICE.keys():
|
for mode in NOTICE.keys():
|
||||||
# 检查条件
|
# 检查条件
|
||||||
if push_data[f'{mode}_is_push'] == 'on':
|
if push_data[f"{mode}_is_push"] == "on":
|
||||||
if srconfig.get_config('CrazyNotice').data:
|
if srconfig.get_config("CrazyNotice").data:
|
||||||
if not await check(mode, raw_data, push_data[f'{mode}_value']):
|
if not await check(mode, raw_data, push_data[f"{mode}_value"]):
|
||||||
await GsPush.update_data_by_uid(
|
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
|
continue
|
||||||
# 准备推送
|
# 准备推送
|
||||||
if await check(mode, raw_data, push_data[f'{mode}_value']):
|
if await check(mode, raw_data, push_data[f"{mode}_value"]):
|
||||||
if push_data[f'{mode}_push'] == 'off':
|
if push_data[f"{mode}_push"] == "off":
|
||||||
pass
|
pass
|
||||||
# on 推送到私聊
|
# on 推送到私聊
|
||||||
else:
|
else:
|
||||||
# 初始化
|
# 初始化
|
||||||
if bot_id not in msg_dict:
|
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']:
|
if user_id not in msg_dict[bot_id]["direct"]:
|
||||||
msg_dict[bot_id]['direct'][user_id] = NOTICE[mode]
|
msg_dict[bot_id]["direct"][user_id] = NOTICE[mode]
|
||||||
else:
|
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(
|
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:
|
else:
|
||||||
# 初始化
|
# 初始化
|
||||||
gid = push_data[f'{mode}_push']
|
gid = push_data[f"{mode}_push"]
|
||||||
if gid not in msg_dict[bot_id]['group']:
|
if gid not in msg_dict[bot_id]["group"]:
|
||||||
msg_dict[bot_id]['group'][gid] = {}
|
msg_dict[bot_id]["group"][gid] = {}
|
||||||
|
|
||||||
if user_id not in 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]
|
msg_dict[bot_id]["group"][gid][user_id] = NOTICE[mode]
|
||||||
else:
|
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(
|
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
|
return msg_dict
|
||||||
|
|
||||||
|
|
||||||
async def check(mode: str, data: DailyNoteData, limit: int) -> bool:
|
async def check(mode: str, data: DailyNoteData, limit: int) -> bool:
|
||||||
if mode == 'resin':
|
if mode == "resin":
|
||||||
if data.current_stamina >= limit:
|
if data.current_stamina >= limit:
|
||||||
return True
|
return True
|
||||||
if data.current_stamina >= data.max_stamina:
|
if data.current_stamina >= data.max_stamina:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
if mode == 'go':
|
if mode == "go":
|
||||||
for i in data.expeditions:
|
for i in data.expeditions:
|
||||||
if i.status == 'Ongoing':
|
if i.status == "Ongoing":
|
||||||
if i.remaining_time <= limit * 60:
|
if i.remaining_time <= limit * 60:
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
|
@ -2,8 +2,8 @@ from typing import List
|
|||||||
|
|
||||||
from gsuid_core.logger import logger
|
from gsuid_core.logger import logger
|
||||||
|
|
||||||
from ..utils.mys_api import mys_api
|
|
||||||
from ..utils.error_reply import get_error
|
from ..utils.error_reply import get_error
|
||||||
|
from ..utils.mys_api import mys_api
|
||||||
|
|
||||||
daily_im = """*数据刷新可能存在一定延迟,请以当前游戏实际数据为准
|
daily_im = """*数据刷新可能存在一定延迟,请以当前游戏实际数据为准
|
||||||
==============
|
==============
|
||||||
@ -16,31 +16,27 @@ daily_im = """*数据刷新可能存在一定延迟,请以当前游戏实际数
|
|||||||
def seconds2hours(seconds: int) -> str:
|
def seconds2hours(seconds: int) -> str:
|
||||||
m, s = divmod(int(seconds), 60)
|
m, s = divmod(int(seconds), 60)
|
||||||
h, m = divmod(m, 60)
|
h, m = divmod(m, 60)
|
||||||
return '%02d:%02d:%02d' % (h, m, s)
|
return "%02d:%02d:%02d" % (h, m, s)
|
||||||
|
|
||||||
|
|
||||||
async def get_stamina_text(uid: str) -> str:
|
async def get_stamina_text(uid: str) -> str:
|
||||||
try:
|
try:
|
||||||
dailydata = await mys_api.get_daily_data(uid)
|
dailydata = await mys_api.get_sr_daily_data(uid)
|
||||||
if isinstance(dailydata, int):
|
if isinstance(dailydata, int):
|
||||||
return get_error(dailydata)
|
return get_error(dailydata)
|
||||||
max_stamina = dailydata.max_stamina
|
max_stamina = dailydata.max_stamina
|
||||||
rec_time = ''
|
rec_time = ""
|
||||||
current_stamina = dailydata.current_stamina
|
current_stamina = dailydata.current_stamina
|
||||||
if current_stamina < 160:
|
if current_stamina < 160:
|
||||||
stamina_recover_time = seconds2hours(
|
stamina_recover_time = seconds2hours(dailydata.stamina_recover_time)
|
||||||
dailydata.stamina_recover_time
|
|
||||||
)
|
|
||||||
next_stamina_rec_time = seconds2hours(
|
next_stamina_rec_time = seconds2hours(
|
||||||
8 * 60
|
8 * 60
|
||||||
- (
|
- (
|
||||||
(dailydata.max_stamina - dailydata.current_stamina)
|
(dailydata.max_stamina - dailydata.current_stamina) * 8 * 60
|
||||||
* 8
|
|
||||||
* 60
|
|
||||||
- dailydata.stamina_recover_time
|
- 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
|
accepted_epedition_num = dailydata.accepted_expedition_num
|
||||||
total_expedition_num = dailydata.total_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:
|
for expedition in dailydata.expeditions:
|
||||||
expedition_name = expedition.name
|
expedition_name = expedition.name
|
||||||
|
|
||||||
if expedition.status == 'Finished':
|
if expedition.status == "Finished":
|
||||||
expedition_info.append(f'{expedition_name} 探索完成')
|
expedition_info.append(f"{expedition_name} 探索完成")
|
||||||
finished_expedition_num += 1
|
finished_expedition_num += 1
|
||||||
else:
|
else:
|
||||||
remaining_time: str = seconds2hours(expedition.remaining_time)
|
remaining_time: str = seconds2hours(expedition.remaining_time)
|
||||||
expedition_info.append(
|
expedition_info.append(f"{expedition_name} 剩余时间{remaining_time}")
|
||||||
f'{expedition_name} 剩余时间{remaining_time}'
|
|
||||||
)
|
|
||||||
|
|
||||||
expedition_data = '\n'.join(expedition_info)
|
expedition_data = "\n".join(expedition_info)
|
||||||
return daily_im.format(
|
return daily_im.format(
|
||||||
current_stamina,
|
current_stamina,
|
||||||
max_stamina,
|
max_stamina,
|
||||||
@ -69,5 +63,5 @@ async def get_stamina_text(uid: str) -> str:
|
|||||||
expedition_data,
|
expedition_data,
|
||||||
)
|
)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
logger.exception('[查询当前状态]查询失败!')
|
logger.exception("[查询当前状态]查询失败!")
|
||||||
return '你绑定过的UID中可能存在过期CK~请重新绑定一下噢~'
|
return "你绑定过的UID中可能存在过期CK~请重新绑定一下噢~"
|
||||||
|
@ -7,72 +7,72 @@ from ..utils.message import send_diff_msg
|
|||||||
from ..utils.sr_prefix import PREFIX
|
from ..utils.sr_prefix import PREFIX
|
||||||
from .draw_user_card import get_user_card
|
from .draw_user_card import get_user_card
|
||||||
|
|
||||||
sv_user_config = SV('sr用户管理', pm=2)
|
sv_user_config = SV("sr用户管理", pm=2)
|
||||||
sv_user_info = SV('sr用户信息')
|
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):
|
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)
|
uid_list = await get_user_card(ev.bot_id, ev.user_id)
|
||||||
if not uid_list:
|
if not uid_list:
|
||||||
return await bot.send('你还没有绑定SR_UID哦!')
|
return await bot.send("你还没有绑定SR_UID哦!")
|
||||||
await bot.logger.info('sr[查询用户绑定状态]完成!等待图片发送中...')
|
await bot.logger.info("sr[查询用户绑定状态]完成!等待图片发送中...")
|
||||||
await bot.send(uid_list)
|
await bot.send(uid_list)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
@sv_user_info.on_command(
|
@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):
|
async def send_link_uid_msg(bot: Bot, ev: Event):
|
||||||
await bot.logger.info('sr开始执行[绑定/解绑用户信息]')
|
await bot.logger.info("sr开始执行[绑定/解绑用户信息]")
|
||||||
qid = ev.user_id
|
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()
|
sr_uid = ev.text.strip()
|
||||||
if sr_uid and not sr_uid.isdigit():
|
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(
|
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(
|
return await send_diff_msg(
|
||||||
bot,
|
bot,
|
||||||
data,
|
data,
|
||||||
{
|
{
|
||||||
0: f'✅[崩铁]绑定UID{sr_uid}成功!',
|
0: f"✅[崩铁]绑定UID{sr_uid}成功!",
|
||||||
-1: f'❌SR_UID{sr_uid}的位数不正确!',
|
-1: f"❌SR_UID{sr_uid}的位数不正确!",
|
||||||
-2: f'❌SR_UID{sr_uid}已经绑定过了!',
|
-2: f"❌SR_UID{sr_uid}已经绑定过了!",
|
||||||
-3: '❌你输入了错误的格式!',
|
-3: "❌你输入了错误的格式!",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
if '切换' in ev.command:
|
if "切换" in ev.command:
|
||||||
data = await GsBind.switch_uid_by_game(qid, ev.bot_id, sr_uid, 'sr')
|
data = await GsBind.switch_uid_by_game(qid, ev.bot_id, sr_uid, "sr")
|
||||||
return await send_diff_msg(
|
return await send_diff_msg(
|
||||||
bot,
|
bot,
|
||||||
data,
|
data,
|
||||||
{
|
{
|
||||||
0: f'✅[崩铁]切换uid{sr_uid}成功!',
|
0: f"✅[崩铁]切换uid{sr_uid}成功!",
|
||||||
-1: '❌[崩铁]不存在绑定记录!',
|
-1: "❌[崩铁]不存在绑定记录!",
|
||||||
-2: '❌[崩铁]请绑定两个以上UID再进行切换!',
|
-2: "❌[崩铁]请绑定两个以上UID再进行切换!",
|
||||||
-3: '❌[崩铁]请绑定两个以上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(
|
return await send_diff_msg(
|
||||||
bot,
|
bot,
|
||||||
data,
|
data,
|
||||||
{
|
{
|
||||||
0: f'✅[崩铁]删除UID{sr_uid}成功!',
|
0: f"✅[崩铁]删除UID{sr_uid}成功!",
|
||||||
-1: f'❌[崩铁]该UID{sr_uid}不在已绑定列表中!',
|
-1: f"❌[崩铁]该UID{sr_uid}不在已绑定列表中!",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -20,104 +20,104 @@ from ..utils.resource.RESOURCE_PATH import (
|
|||||||
WIKI_MATERIAL_FOR_ROLE,
|
WIKI_MATERIAL_FOR_ROLE,
|
||||||
)
|
)
|
||||||
|
|
||||||
sv_sr_wiki = SV('星铁WIKI')
|
sv_sr_wiki = SV("星铁WIKI")
|
||||||
sv_sr_guide = SV('星铁攻略')
|
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):
|
async def send_role_wiki_pic(bot: Bot, ev: Event):
|
||||||
char_name = ' '.join(re.findall('[\u4e00-\u9fa5]+', ev.text))
|
char_name = " ".join(re.findall("[\u4e00-\u9fa5]+", ev.text))
|
||||||
await bot.logger.info(f'开始获取{char_name}图鉴')
|
await bot.logger.info(f"开始获取{char_name}图鉴")
|
||||||
if '开拓者' in str(char_name):
|
if "开拓者" in str(char_name):
|
||||||
char_name = '开拓者'
|
char_name = "开拓者"
|
||||||
char_id = await name_to_avatar_id(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_name = await alias_to_char_name(char_name)
|
||||||
char_id = await name_to_avatar_id(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():
|
if img.exists():
|
||||||
img = await convert_img(img)
|
img = await convert_img(img)
|
||||||
await bot.logger.info(f'获得{char_name}图鉴图片成功!')
|
await bot.logger.info(f"获得{char_name}图鉴图片成功!")
|
||||||
await bot.send(img)
|
await bot.send(img)
|
||||||
else:
|
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):
|
async def send_role_guide_pic(bot: Bot, ev: Event):
|
||||||
char_name = ' '.join(re.findall('[\u4e00-\u9fa5]+', ev.text))
|
char_name = " ".join(re.findall("[\u4e00-\u9fa5]+", ev.text))
|
||||||
await bot.logger.info(f'开始获取{char_name}图鉴')
|
await bot.logger.info(f"开始获取{char_name}图鉴")
|
||||||
if '开拓者' in str(char_name):
|
if "开拓者" in str(char_name):
|
||||||
char_name = '开拓者'
|
char_name = "开拓者"
|
||||||
char_id = await name_to_avatar_id(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_name = await alias_to_char_name(char_name)
|
||||||
char_id = await name_to_avatar_id(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():
|
if img.exists():
|
||||||
img = await convert_img(img)
|
img = await convert_img(img)
|
||||||
await bot.logger.info(f'获得{char_id}图鉴图片成功!')
|
await bot.logger.info(f"获得{char_id}图鉴图片成功!")
|
||||||
await bot.send(img)
|
await bot.send(img)
|
||||||
else:
|
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):
|
async def send_weapon_guide_pic(bot: Bot, ev: Event):
|
||||||
msg = ' '.join(re.findall('[\u4e00-\u9fa5]+', ev.text))
|
msg = " ".join(re.findall("[\u4e00-\u9fa5]+", ev.text))
|
||||||
await bot.logger.info(f'开始获取{msg}图鉴')
|
await bot.logger.info(f"开始获取{msg}图鉴")
|
||||||
light_cone_id = await name_to_weapon_id(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():
|
if img.exists():
|
||||||
img = await convert_img(img)
|
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)
|
await bot.send(img)
|
||||||
else:
|
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):
|
async def send_relic_wiki_pic(bot: Bot, ev: Event):
|
||||||
msg = ' '.join(re.findall('[\u4e00-\u9fa5]+', ev.text))
|
msg = " ".join(re.findall("[\u4e00-\u9fa5]+", ev.text))
|
||||||
await bot.logger.info(f'开始获取{msg}遗器')
|
await bot.logger.info(f"开始获取{msg}遗器")
|
||||||
set_id = await name_to_relic_set_id(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():
|
if img.exists():
|
||||||
img = await convert_img(img)
|
img = await convert_img(img)
|
||||||
await bot.logger.info(f'获得{msg}遗器图片成功!')
|
await bot.logger.info(f"获得{msg}遗器图片成功!")
|
||||||
await bot.send(img)
|
await bot.send(img)
|
||||||
else:
|
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):
|
async def send_material_for_role_wiki_pic(bot: Bot, ev: Event):
|
||||||
char_name = ' '.join(re.findall('[\u4e00-\u9fa5]+', ev.text))
|
char_name = " ".join(re.findall("[\u4e00-\u9fa5]+", ev.text))
|
||||||
await bot.logger.info(f'开始获取{char_name}突破材料')
|
await bot.logger.info(f"开始获取{char_name}突破材料")
|
||||||
if '开拓者' in str(char_name):
|
if "开拓者" in str(char_name):
|
||||||
char_name = '开拓者'
|
char_name = "开拓者"
|
||||||
char_id = await name_to_avatar_id(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_name = await alias_to_char_name(char_name)
|
||||||
char_id = await name_to_avatar_id(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():
|
if img.exists():
|
||||||
img = await convert_img(img)
|
img = await convert_img(img)
|
||||||
await bot.logger.info(f'获得{char_name}突破材料图片成功!')
|
await bot.logger.info(f"获得{char_name}突破材料图片成功!")
|
||||||
await bot.send(img)
|
await bot.send(img)
|
||||||
else:
|
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):
|
async def send_light_cone_wiki_pic(bot: Bot, ev: Event):
|
||||||
msg = ' '.join(re.findall('[\u4e00-\u9fa5]+', ev.text))
|
msg = " ".join(re.findall("[\u4e00-\u9fa5]+", ev.text))
|
||||||
await bot.logger.info(f'开始获取{msg}武器')
|
await bot.logger.info(f"开始获取{msg}武器")
|
||||||
light_cone_id = await name_to_weapon_id(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():
|
if img.exists():
|
||||||
img = await convert_img(img)
|
img = await convert_img(img)
|
||||||
await bot.logger.info(f'获得{msg}武器图片成功!')
|
await bot.logger.info(f"获得{msg}武器图片成功!")
|
||||||
await bot.send(img)
|
await bot.send(img)
|
||||||
else:
|
else:
|
||||||
await bot.logger.warning(f'未找到{msg}武器图片')
|
await bot.logger.warning(f"未找到{msg}武器图片")
|
||||||
|
@ -1,36 +1,12 @@
|
|||||||
import re
|
from typing import Optional, Tuple, Union
|
||||||
from typing import Tuple, Union, Optional, overload
|
|
||||||
|
|
||||||
from gsuid_core.bot import Bot
|
from gsuid_core.bot import Bot
|
||||||
from gsuid_core.models import Event
|
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
|
from gsuid_core.utils.database.models import GsBind
|
||||||
|
|
||||||
|
|
||||||
@overload
|
|
||||||
async def get_uid(
|
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
|
||||||
) -> 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
|
|
||||||
) -> Union[Optional[str], Tuple[Optional[str], str]]:
|
) -> Union[Optional[str], Tuple[Optional[str], str]]:
|
||||||
uid_data = re.findall(r'\d{9}', ev.text)
|
return await get_uid_db(bot, ev, GsBind, "sr", get_user_id) # type: ignore
|
||||||
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
|
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
||||||
UID_HINT = '你还没有绑定过uid哦!\n请使用[sr绑定uid123456]命令绑定!'
|
UID_HINT = "你还没有绑定过uid哦!\n请使用[sr绑定uid123456]命令绑定!"
|
||||||
MYS_HINT = '你还没有绑定过mysid哦!\n请使用[绑定mys1234]命令绑定!'
|
MYS_HINT = "你还没有绑定过mysid哦!\n请使用[绑定mys1234]命令绑定!"
|
||||||
CK_HINT = """你还没有绑定过Cookie哦!发送【ck帮助】获取帮助!
|
CK_HINT = """你还没有绑定过Cookie哦!发送【ck帮助】获取帮助!
|
||||||
警告:绑定Cookie可能会带来未知的账号风险,请确保信任机器人管理员"""
|
警告:绑定Cookie可能会带来未知的账号风险,请确保信任机器人管理员"""
|
||||||
CHAR_HINT = '您的支援/星海同行角色没有{}的数据哦!\n请先把{}放入支援/星海同行中再使用【sr强制刷新】命令来缓存数据进行查询! !'
|
CHAR_HINT = "您的支援/星海同行角色没有{}的数据哦!\n请先把{}放入支援/星海同行中再使用【sr强制刷新】命令来缓存数据进行查询! !"
|
||||||
VERIFY_HINT = """出现验证码!
|
VERIFY_HINT = """出现验证码!
|
||||||
如已绑定CK: 请至米游社软件->我的->我的角色处解锁验证码
|
如已绑定CK: 请至米游社软件->我的->我的角色处解锁验证码
|
||||||
(可使用[gs关闭推送]命令关闭体力推送以减少出现验证码风险)
|
(可使用[gs关闭推送]命令关闭体力推送以减少出现验证码风险)
|
||||||
如未绑定CK: 可联系管理员使用[gs清除缓存]命令
|
如未绑定CK: 可联系管理员使用[gs清除缓存]命令
|
||||||
"""
|
"""
|
||||||
SK_HINT = '你还没有绑定过Stoken或者Stoken已失效~\n请群聊发送 [扫码登陆] 或加好友私聊Bot [添加]后跟SK格式 以绑定SK'
|
SK_HINT = "你还没有绑定过Stoken或者Stoken已失效~\n请群聊发送 [扫码登陆] 或加好友私聊Bot [添加]后跟SK格式 以绑定SK"
|
||||||
UPDATE_HINT = """更新失败!更多错误信息请查看控制台...
|
UPDATE_HINT = """更新失败!更多错误信息请查看控制台...
|
||||||
>> 可以尝试使用
|
>> 可以尝试使用
|
||||||
>> [gs强制更新](危险)
|
>> [gs强制更新](危险)
|
||||||
@ -21,27 +21,27 @@ def get_error(retcode: Union[int, str]) -> str:
|
|||||||
if retcode == -51:
|
if retcode == -51:
|
||||||
return CK_HINT
|
return CK_HINT
|
||||||
if retcode == -100:
|
if retcode == -100:
|
||||||
return '您的cookie已经失效, 请重新获取!'
|
return "您的cookie已经失效, 请重新获取!"
|
||||||
if retcode == 10001:
|
if retcode == 10001:
|
||||||
return '您的cookie已经失效, 请重新获取!'
|
return "您的cookie已经失效, 请重新获取!"
|
||||||
if retcode == 10101:
|
if retcode == 10101:
|
||||||
return '当前查询CK已超过每日30次上限!'
|
return "当前查询CK已超过每日30次上限!"
|
||||||
if retcode == 10102:
|
if retcode == 10102:
|
||||||
return '当前查询id已经设置了隐私, 无法查询!'
|
return "当前查询id已经设置了隐私, 无法查询!"
|
||||||
if retcode == 1034:
|
if retcode == 1034:
|
||||||
return VERIFY_HINT
|
return VERIFY_HINT
|
||||||
if retcode == -10001:
|
if retcode == -10001:
|
||||||
return '请求体出错, 请检查具体实现代码...'
|
return "请求体出错, 请检查具体实现代码..."
|
||||||
if retcode == 10104:
|
if retcode == 10104:
|
||||||
return CK_HINT
|
return CK_HINT
|
||||||
if retcode == -512009:
|
if retcode == -512009:
|
||||||
return '[留影叙佳期]已经获取过该内容~!'
|
return "[留影叙佳期]已经获取过该内容~!"
|
||||||
if retcode == -201:
|
if retcode == -201:
|
||||||
return '你的账号可能已被封禁, 请联系米游社客服...'
|
return "你的账号可能已被封禁, 请联系米游社客服..."
|
||||||
if retcode == -501101:
|
if retcode == -501101:
|
||||||
return '当前角色冒险等阶未达到10级, 暂时无法参加此活动...'
|
return "当前角色冒险等阶未达到10级, 暂时无法参加此活动..."
|
||||||
if retcode == 400:
|
if retcode == 400:
|
||||||
return '[MINIGG]暂未找到此内容...'
|
return "[MINIGG]暂未找到此内容..."
|
||||||
if retcode == -400:
|
if retcode == -400:
|
||||||
return '请输入更详细的名称...'
|
return "请输入更详细的名称..."
|
||||||
return f'API报错, 错误码为{retcode}!'
|
return f"API报错, 错误码为{retcode}!"
|
||||||
|
@ -88,8 +88,6 @@ class SingleRelicSubAffix(Struct):
|
|||||||
|
|
||||||
|
|
||||||
AvatarPromotionConfig = convert(AvatarPromotion, List[SingleAvatarPromotion])
|
AvatarPromotionConfig = convert(AvatarPromotion, List[SingleAvatarPromotion])
|
||||||
EquipmentPromotionConfig = convert(
|
EquipmentPromotionConfig = convert(EquipmentPromotion, List[SingleEquipmentPromotion])
|
||||||
EquipmentPromotion, List[SingleEquipmentPromotion]
|
|
||||||
)
|
|
||||||
RelicMainAffixConfig = convert(RelicMainAffix, List[SingleRelicMainAffix])
|
RelicMainAffixConfig = convert(RelicMainAffix, List[SingleRelicMainAffix])
|
||||||
RelicSubAffixConfig = convert(RelicSubAffix, List[SingleRelicSubAffix])
|
RelicSubAffixConfig = convert(RelicSubAffix, List[SingleRelicSubAffix])
|
||||||
|
@ -3,17 +3,17 @@ from pathlib import Path
|
|||||||
|
|
||||||
EXCEL = Path(__file__).parent
|
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)
|
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)
|
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)
|
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)
|
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)
|
light_cone_ranks = json.load(f)
|
||||||
|
@ -2,7 +2,7 @@ from pathlib import Path
|
|||||||
|
|
||||||
from PIL import ImageFont
|
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:
|
def first_word_origin(size: int) -> ImageFont.FreeTypeFont:
|
||||||
|
@ -2,7 +2,7 @@ from pathlib import Path
|
|||||||
|
|
||||||
from PIL import ImageFont
|
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:
|
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 ..resource.RESOURCE_PATH import CU_BG_PATH
|
||||||
from ...starrailuid_config.sr_config import srconfig
|
from ...starrailuid_config.sr_config import srconfig
|
||||||
|
|
||||||
BG_PATH = Path(__file__).parent / 'bg'
|
BG_PATH = Path(__file__).parent / "bg"
|
||||||
NM_BG_PATH = BG_PATH / 'nm_bg'
|
NM_BG_PATH = BG_PATH / "nm_bg"
|
||||||
SP_BG_PATH = BG_PATH / 'sp_bg'
|
SP_BG_PATH = BG_PATH / "sp_bg"
|
||||||
|
|
||||||
if list(CU_BG_PATH.iterdir()) != []:
|
if list(CU_BG_PATH.iterdir()) != []:
|
||||||
bg_path = CU_BG_PATH
|
bg_path = CU_BG_PATH
|
||||||
@ -35,10 +35,10 @@ async def get_color_bg(
|
|||||||
bg: Optional[str] = None,
|
bg: Optional[str] = None,
|
||||||
without_mask: bool = False,
|
without_mask: bool = False,
|
||||||
) -> Image.Image:
|
) -> Image.Image:
|
||||||
image = ''
|
image = ""
|
||||||
if bg and srconfig.get_config('DefaultBaseBG').data:
|
if bg and srconfig.get_config("DefaultBaseBG").data:
|
||||||
path = SP_BG_PATH / f'{bg}.jpg'
|
path = SP_BG_PATH / f"{bg}.jpg"
|
||||||
path2 = CU_BG_PATH / f'{bg}.jpg'
|
path2 = CU_BG_PATH / f"{bg}.jpg"
|
||||||
if path2.exists():
|
if path2.exists():
|
||||||
image = Image.open(path2)
|
image = Image.open(path2)
|
||||||
elif path.exists():
|
elif path.exists():
|
||||||
@ -47,9 +47,7 @@ async def get_color_bg(
|
|||||||
img = CI_img.get_image(image, based_w, based_h)
|
img = CI_img.get_image(image, based_w, based_h)
|
||||||
color = CI_img.get_bg_color(img)
|
color = CI_img.get_bg_color(img)
|
||||||
if not without_mask:
|
if not without_mask:
|
||||||
color_mask = Image.new('RGBA', (based_w, based_h), color)
|
color_mask = Image.new("RGBA", (based_w, based_h), color)
|
||||||
enka_mask = Image.open(TEXT_PATH / 'bg_mask.png').resize(
|
enka_mask = Image.open(TEXT_PATH / "bg_mask.png").resize((based_w, based_h))
|
||||||
(based_w, based_h)
|
|
||||||
)
|
|
||||||
img.paste(color_mask, (0, 0), enka_mask)
|
img.paste(color_mask, (0, 0), enka_mask)
|
||||||
return img
|
return img
|
||||||
|
@ -12,36 +12,34 @@ class RelicSetStatusAdd(Struct):
|
|||||||
Value: float
|
Value: float
|
||||||
|
|
||||||
|
|
||||||
MAP = Path(__file__).parent / 'data'
|
MAP = Path(__file__).parent / "data"
|
||||||
|
|
||||||
version = StarRail_version
|
version = StarRail_version
|
||||||
|
|
||||||
avatarId2Name_fileName = f'avatarId2Name_mapping_{version}.json'
|
avatarId2Name_fileName = f"avatarId2Name_mapping_{version}.json"
|
||||||
avatarId2EnName_fileName = f'avatarId2EnName_mapping_{version}.json'
|
avatarId2EnName_fileName = f"avatarId2EnName_mapping_{version}.json"
|
||||||
EquipmentID2Name_fileName = f'EquipmentID2Name_mapping_{version}.json'
|
EquipmentID2Name_fileName = f"EquipmentID2Name_mapping_{version}.json"
|
||||||
EquipmentID2EnName_fileName = f'EquipmentID2EnName_mapping_{version}.json'
|
EquipmentID2EnName_fileName = f"EquipmentID2EnName_mapping_{version}.json"
|
||||||
skillId2Name_fileName = f'skillId2Name_mapping_{version}.json'
|
skillId2Name_fileName = f"skillId2Name_mapping_{version}.json"
|
||||||
skillId2Type_fileName = f'skillId2Type_mapping_{version}.json'
|
skillId2Type_fileName = f"skillId2Type_mapping_{version}.json"
|
||||||
Property2Name_fileName = f'Property2Name_mapping_{version}.json'
|
Property2Name_fileName = f"Property2Name_mapping_{version}.json"
|
||||||
RelicId2SetId_fileName = f'RelicId2SetId_mapping_{version}.json'
|
RelicId2SetId_fileName = f"RelicId2SetId_mapping_{version}.json"
|
||||||
SetId2Name_fileName = f'SetId2Name_mapping_{version}.json'
|
SetId2Name_fileName = f"SetId2Name_mapping_{version}.json"
|
||||||
rankId2Name_fileName = f'rankId2Name_mapping_{version}.json'
|
rankId2Name_fileName = f"rankId2Name_mapping_{version}.json"
|
||||||
characterSkillTree_fileName = f'characterSkillTree_mapping_{version}.json'
|
characterSkillTree_fileName = f"characterSkillTree_mapping_{version}.json"
|
||||||
avatarId2DamageType_fileName = f'avatarId2DamageType_mapping_{version}.json'
|
avatarId2DamageType_fileName = f"avatarId2DamageType_mapping_{version}.json"
|
||||||
avatarId2Rarity_fileName = f'avatarId2Rarity_mapping_{version}.json'
|
avatarId2Rarity_fileName = f"avatarId2Rarity_mapping_{version}.json"
|
||||||
EquipmentID2AbilityProperty_fileName = (
|
EquipmentID2AbilityProperty_fileName = (
|
||||||
f'EquipmentID2AbilityProperty_mapping_{version}.json'
|
f"EquipmentID2AbilityProperty_mapping_{version}.json"
|
||||||
)
|
)
|
||||||
RelicSetSkill_fileName = f'RelicSetSkill_mapping_{version}.json'
|
RelicSetSkill_fileName = f"RelicSetSkill_mapping_{version}.json"
|
||||||
skillId2AttackType_fileName = f'skillId2AttackType_mapping_{version}.json'
|
skillId2AttackType_fileName = f"skillId2AttackType_mapping_{version}.json"
|
||||||
EquipmentID2Rarity_fileName = f'EquipmentID2Rarity_mapping_{version}.json'
|
EquipmentID2Rarity_fileName = f"EquipmentID2Rarity_mapping_{version}.json"
|
||||||
RelicId2Rarity_fileName = f'RelicId2Rarity_mapping_{version}.json'
|
RelicId2Rarity_fileName = f"RelicId2Rarity_mapping_{version}.json"
|
||||||
ItemId2Name_fileName = f'ItemId2Name_mapping_{version}.json'
|
ItemId2Name_fileName = f"ItemId2Name_mapping_{version}.json"
|
||||||
RelicId2MainAffixGroup_fileName = (
|
RelicId2MainAffixGroup_fileName = f"RelicId2MainAffixGroup_mapping_{version}.json"
|
||||||
f'RelicId2MainAffixGroup_mapping_{version}.json'
|
AvatarRelicScore_fileName = "AvatarRelicScore.json"
|
||||||
)
|
avatarRankSkillUp_fileName = f"avatarRankSkillUp_mapping_{version}.json"
|
||||||
AvatarRelicScore_fileName = 'AvatarRelicScore.json'
|
|
||||||
avatarRankSkillUp_fileName = f'avatarRankSkillUp_mapping_{version}.json'
|
|
||||||
|
|
||||||
|
|
||||||
class TS(TypedDict):
|
class TS(TypedDict):
|
||||||
@ -54,51 +52,49 @@ class LU(TypedDict):
|
|||||||
num: int
|
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])
|
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])
|
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])
|
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])
|
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])
|
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])
|
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])
|
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])
|
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])
|
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])
|
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])
|
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])
|
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]])
|
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])
|
avatarId2Rarity = msgjson.decode(f.read(), type=Dict[str, str])
|
||||||
|
|
||||||
with Path.open(
|
with Path.open(MAP / EquipmentID2AbilityProperty_fileName, encoding="UTF-8") as f:
|
||||||
MAP / EquipmentID2AbilityProperty_fileName, encoding='UTF-8'
|
|
||||||
) as f:
|
|
||||||
EquipmentID2AbilityProperty = msgjson.decode(
|
EquipmentID2AbilityProperty = msgjson.decode(
|
||||||
f.read(), type=Dict[str, Dict[str, List]]
|
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]])
|
# RelicSetSkill = convert(json.load(f), Dict[str, Dict[str, object]])
|
||||||
# print(RelicSetSkill)
|
# 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])
|
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])
|
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])
|
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])
|
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])
|
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])
|
AvatarRelicScore = msgjson.decode(f.read(), type=List[Dict])
|
||||||
|
|
||||||
with Path.open(MAP / avatarRankSkillUp_fileName, encoding='UTF-8') as f:
|
with Path.open(MAP / avatarRankSkillUp_fileName, encoding="UTF-8") as f:
|
||||||
AvatarRankSkillUp = msgjson.decode(
|
AvatarRankSkillUp = msgjson.decode(f.read(), type=Dict[str, Union[List[LU], None]])
|
||||||
f.read(), type=Dict[str, Union[List[LU], None]]
|
|
||||||
)
|
|
||||||
|
@ -1,54 +1,54 @@
|
|||||||
import json
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
ItemConfigRelic = json.load(f)
|
||||||
|
|
||||||
avatarId2Name = {}
|
avatarId2Name = {}
|
||||||
@ -74,32 +74,32 @@ RelicId2MainAffixGroup = {}
|
|||||||
|
|
||||||
for char in characters:
|
for char in characters:
|
||||||
char_item = characters[char]
|
char_item = characters[char]
|
||||||
rank_list = characters[char]['ranks']
|
rank_list = characters[char]["ranks"]
|
||||||
rarity = characters[char]['rarity']
|
rarity = characters[char]["rarity"]
|
||||||
avatarId2Rarity[char] = str(rarity)
|
avatarId2Rarity[char] = str(rarity)
|
||||||
for rank in rank_list:
|
for rank in rank_list:
|
||||||
if character_ranks.get(str(rank)):
|
if character_ranks.get(str(rank)):
|
||||||
eidolon = character_ranks[str(rank)]
|
eidolon = character_ranks[str(rank)]
|
||||||
rank_id = eidolon['id']
|
rank_id = eidolon["id"]
|
||||||
rank_name = eidolon['name']
|
rank_name = eidolon["name"]
|
||||||
rankId2Name[rank_id] = rank_name
|
rankId2Name[rank_id] = rank_name
|
||||||
|
|
||||||
for item in AvatarConfig:
|
for item in AvatarConfig:
|
||||||
avatar_item = AvatarConfig[item]
|
avatar_item = AvatarConfig[item]
|
||||||
avatar_id = avatar_item['AvatarID']
|
avatar_id = avatar_item["AvatarID"]
|
||||||
avatar_name_hash = avatar_item['AvatarName']['Hash']
|
avatar_name_hash = avatar_item["AvatarName"]["Hash"]
|
||||||
avatar_damage_type = avatar_item['DamageType']
|
avatar_damage_type = avatar_item["DamageType"]
|
||||||
avatar_en_name = ''
|
avatar_en_name = ""
|
||||||
avatar_name = ''
|
avatar_name = ""
|
||||||
for item in TextMapCN:
|
for item in TextMapCN:
|
||||||
if str(item) == str(avatar_name_hash):
|
if str(item) == str(avatar_name_hash):
|
||||||
avatar_name = TextMapCN[item]
|
avatar_name = TextMapCN[item]
|
||||||
if avatar_name == '{NICKNAME}':
|
if avatar_name == "{NICKNAME}":
|
||||||
avatar_name = '开拓者'
|
avatar_name = "开拓者"
|
||||||
break
|
break
|
||||||
for item in TextMapEN:
|
for item in TextMapEN:
|
||||||
if str(item) == str(avatar_name_hash):
|
if str(item) == str(avatar_name_hash):
|
||||||
avatar_en_name = TextMapEN[item].replace(' ', '')
|
avatar_en_name = TextMapEN[item].replace(" ", "")
|
||||||
break
|
break
|
||||||
avatarId2EnName[avatar_id] = avatar_en_name
|
avatarId2EnName[avatar_id] = avatar_en_name
|
||||||
avatarId2Name[avatar_id] = avatar_name
|
avatarId2Name[avatar_id] = avatar_name
|
||||||
@ -108,9 +108,9 @@ for item in AvatarConfig:
|
|||||||
|
|
||||||
for item in EquipmentConfig:
|
for item in EquipmentConfig:
|
||||||
equipment_item = EquipmentConfig[item]
|
equipment_item = EquipmentConfig[item]
|
||||||
equipment_id = equipment_item['EquipmentID']
|
equipment_id = equipment_item["EquipmentID"]
|
||||||
equipment_name_hash = equipment_item['EquipmentName']['Hash']
|
equipment_name_hash = equipment_item["EquipmentName"]["Hash"]
|
||||||
equipment_name = ''
|
equipment_name = ""
|
||||||
for item in TextMapCN:
|
for item in TextMapCN:
|
||||||
if str(item) == str(equipment_name_hash):
|
if str(item) == str(equipment_name_hash):
|
||||||
equipment_name = TextMapCN[item]
|
equipment_name = TextMapCN[item]
|
||||||
@ -122,30 +122,30 @@ for item in EquipmentSkillConfig:
|
|||||||
equipment_item = EquipmentSkillConfig[item]
|
equipment_item = EquipmentSkillConfig[item]
|
||||||
EquipmentID2AbilityProperty[str(item)] = {}
|
EquipmentID2AbilityProperty[str(item)] = {}
|
||||||
for i in equipment_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
|
EquipmentID2AbilityProperty[str(item)][i] = equipment_ability_property
|
||||||
|
|
||||||
|
|
||||||
for item in EquipmentConfig:
|
for item in EquipmentConfig:
|
||||||
equipment_item = EquipmentConfig[item]
|
equipment_item = EquipmentConfig[item]
|
||||||
equipment_id = equipment_item['EquipmentID']
|
equipment_id = equipment_item["EquipmentID"]
|
||||||
equipment_name_hash = equipment_item['EquipmentName']['Hash']
|
equipment_name_hash = equipment_item["EquipmentName"]["Hash"]
|
||||||
equipment_name = ''
|
equipment_name = ""
|
||||||
for item in TextMapEN:
|
for item in TextMapEN:
|
||||||
if str(item) == str(equipment_name_hash):
|
if str(item) == str(equipment_name_hash):
|
||||||
equipment_name = TextMapEN[item].replace(' ', '')
|
equipment_name = TextMapEN[item].replace(" ", "")
|
||||||
break
|
break
|
||||||
EquipmentID2EnName[equipment_id] = equipment_name
|
EquipmentID2EnName[equipment_id] = equipment_name
|
||||||
|
|
||||||
|
|
||||||
for skill in AvatarSkillConfig:
|
for skill in AvatarSkillConfig:
|
||||||
skill_item = AvatarSkillConfig[skill]
|
skill_item = AvatarSkillConfig[skill]
|
||||||
skill_id = skill_item['1']['SkillID']
|
skill_id = skill_item["1"]["SkillID"]
|
||||||
skill_name_hash = skill_item['1']['SkillName']['Hash']
|
skill_name_hash = skill_item["1"]["SkillName"]["Hash"]
|
||||||
skill_type_hash = skill_item['1']['SkillTag']['Hash']
|
skill_type_hash = skill_item["1"]["SkillTag"]["Hash"]
|
||||||
skill_attack_type = skill_item['1'].get('AttackType', '')
|
skill_attack_type = skill_item["1"].get("AttackType", "")
|
||||||
skill_name = ''
|
skill_name = ""
|
||||||
skill_type = ''
|
skill_type = ""
|
||||||
for item in TextMapCN:
|
for item in TextMapCN:
|
||||||
if str(item) == str(skill_name_hash):
|
if str(item) == str(skill_name_hash):
|
||||||
skill_name = TextMapCN[item]
|
skill_name = TextMapCN[item]
|
||||||
@ -160,12 +160,12 @@ for skill in AvatarSkillConfig:
|
|||||||
|
|
||||||
|
|
||||||
for avatar_property in AvatarPropertyConfig:
|
for avatar_property in AvatarPropertyConfig:
|
||||||
PropertyType = AvatarPropertyConfig[avatar_property]['PropertyType']
|
PropertyType = AvatarPropertyConfig[avatar_property]["PropertyType"]
|
||||||
PropertyName = AvatarPropertyConfig[avatar_property]['PropertyName']
|
PropertyName = AvatarPropertyConfig[avatar_property]["PropertyName"]
|
||||||
PropertyNameHash = AvatarPropertyConfig[avatar_property][
|
PropertyNameHash = AvatarPropertyConfig[avatar_property]["PropertyNameFilter"][
|
||||||
'PropertyNameFilter'
|
"Hash"
|
||||||
]['Hash']
|
]
|
||||||
Property_Name = ''
|
Property_Name = ""
|
||||||
for item in TextMapCN:
|
for item in TextMapCN:
|
||||||
if str(item) == str(PropertyNameHash):
|
if str(item) == str(PropertyNameHash):
|
||||||
Property_Name = TextMapCN[item]
|
Property_Name = TextMapCN[item]
|
||||||
@ -174,13 +174,13 @@ for avatar_property in AvatarPropertyConfig:
|
|||||||
|
|
||||||
|
|
||||||
for relic in RelicConfig:
|
for relic in RelicConfig:
|
||||||
Relic2SetId[relic] = RelicConfig[relic]['SetID']
|
Relic2SetId[relic] = RelicConfig[relic]["SetID"]
|
||||||
RelicId2MainAffixGroup[relic] = RelicConfig[relic]['MainAffixGroup']
|
RelicId2MainAffixGroup[relic] = RelicConfig[relic]["MainAffixGroup"]
|
||||||
|
|
||||||
|
|
||||||
for set_group in RelicSetConfig:
|
for set_group in RelicSetConfig:
|
||||||
set_name_hash = RelicSetConfig[set_group]['SetName']['Hash']
|
set_name_hash = RelicSetConfig[set_group]["SetName"]["Hash"]
|
||||||
set_name = ''
|
set_name = ""
|
||||||
for item in TextMapCN:
|
for item in TextMapCN:
|
||||||
if str(item) == str(set_name_hash):
|
if str(item) == str(set_name_hash):
|
||||||
set_name = TextMapCN[item]
|
set_name = TextMapCN[item]
|
||||||
@ -189,13 +189,13 @@ for set_group in RelicSetConfig:
|
|||||||
|
|
||||||
|
|
||||||
for character in characters:
|
for character in characters:
|
||||||
char_id = characters[character]['id']
|
char_id = characters[character]["id"]
|
||||||
characterSkillTree[str(char_id)] = (
|
characterSkillTree[str(char_id)] = (
|
||||||
{}
|
{}
|
||||||
if str(char_id) not in characterSkillTree
|
if str(char_id) not in characterSkillTree
|
||||||
else characterSkillTree[str(char_id)]
|
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:
|
for skill in skill_tree_list:
|
||||||
skill_tree = character_skill_trees[skill]
|
skill_tree = character_skill_trees[skill]
|
||||||
characterSkillTree[str(char_id)][str(skill)] = skill_tree
|
characterSkillTree[str(char_id)][str(skill)] = skill_tree
|
||||||
@ -203,38 +203,34 @@ for character in characters:
|
|||||||
|
|
||||||
for set_ in RelicSetSkillConfig:
|
for set_ in RelicSetSkillConfig:
|
||||||
for item in RelicSetSkillConfig[set_]:
|
for item in RelicSetSkillConfig[set_]:
|
||||||
set_id = RelicSetSkillConfig[set_][item]['SetID']
|
set_id = RelicSetSkillConfig[set_][item]["SetID"]
|
||||||
property_list = RelicSetSkillConfig[set_][item]['PropertyList']
|
property_list = RelicSetSkillConfig[set_][item]["PropertyList"]
|
||||||
RelicSetSkill[set_] = (
|
RelicSetSkill[set_] = {} if set_ not in RelicSetSkill else RelicSetSkill[set_]
|
||||||
{} if set_ not in RelicSetSkill else RelicSetSkill[set_]
|
|
||||||
)
|
|
||||||
RelicSetSkill[set_][item] = (
|
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:
|
for property_ in property_list:
|
||||||
property_id = property_['NAOGDGBJNOJ']
|
property_id = property_["NAOGDGBJNOJ"]
|
||||||
property_value = property_['MBOHKHKHFPD']['Value']
|
property_value = property_["MBOHKHKHFPD"]["Value"]
|
||||||
RelicSetSkill[set_][item]['Property'] = property_id
|
RelicSetSkill[set_][item]["Property"] = property_id
|
||||||
RelicSetSkill[set_][item]['Value'] = property_value
|
RelicSetSkill[set_][item]["Value"] = property_value
|
||||||
|
|
||||||
|
|
||||||
for light_cone in light_cones:
|
for light_cone in light_cones:
|
||||||
rarity = light_cones[light_cone]['rarity']
|
rarity = light_cones[light_cone]["rarity"]
|
||||||
light_cone_id = light_cones[light_cone]['id']
|
light_cone_id = light_cones[light_cone]["id"]
|
||||||
EquipmentID2Rarity[light_cone_id] = rarity
|
EquipmentID2Rarity[light_cone_id] = rarity
|
||||||
|
|
||||||
|
|
||||||
for item in relics_new:
|
for item in relics_new:
|
||||||
rarity = relics_new[item]['rarity']
|
rarity = relics_new[item]["rarity"]
|
||||||
relic_id = relics_new[item]['id']
|
relic_id = relics_new[item]["id"]
|
||||||
RelicId2Rarity[relic_id] = rarity
|
RelicId2Rarity[relic_id] = rarity
|
||||||
|
|
||||||
for item in ItemConfigRelic:
|
for item in ItemConfigRelic:
|
||||||
item_id = ItemConfigRelic[item]['ID']
|
item_id = ItemConfigRelic[item]["ID"]
|
||||||
item_name_hash = ItemConfigRelic[item]['ItemName']['Hash']
|
item_name_hash = ItemConfigRelic[item]["ItemName"]["Hash"]
|
||||||
item_name = ''
|
item_name = ""
|
||||||
for item in TextMapCN:
|
for item in TextMapCN:
|
||||||
if str(item) == str(item_name_hash):
|
if str(item) == str(item_name_hash):
|
||||||
item_name = TextMapCN[item]
|
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:
|
async def name_to_avatar_id(name: str) -> str:
|
||||||
avatar_id = ''
|
avatar_id = ""
|
||||||
for i in avatarId2Name:
|
for i in avatarId2Name:
|
||||||
if avatarId2Name[i] == name:
|
if avatarId2Name[i] == name:
|
||||||
avatar_id = i
|
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:
|
async def alias_to_char_name(char_name: str) -> str:
|
||||||
for i in alias_data['characters']:
|
for i in alias_data["characters"]:
|
||||||
if char_name in alias_data['characters'][i]:
|
if char_name in alias_data["characters"][i]:
|
||||||
return alias_data['characters'][i][0]
|
return alias_data["characters"][i][0]
|
||||||
return char_name
|
return char_name
|
||||||
|
|
||||||
|
|
||||||
async def alias_to_weapon_name(weapon_name: str) -> str:
|
async def alias_to_weapon_name(weapon_name: str) -> str:
|
||||||
for i in alias_data['light_cones']:
|
for i in alias_data["light_cones"]:
|
||||||
if weapon_name in alias_data['light_cones'][i]:
|
if weapon_name in alias_data["light_cones"][i]:
|
||||||
return alias_data['light_cones'][i][0]
|
return alias_data["light_cones"][i][0]
|
||||||
return weapon_name
|
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:
|
async def name_to_weapon_id(name: str) -> str:
|
||||||
weapon_id = ''
|
weapon_id = ""
|
||||||
for i in EquipmentID2Name:
|
for i in EquipmentID2Name:
|
||||||
if EquipmentID2Name[i] == name:
|
if EquipmentID2Name[i] == name:
|
||||||
weapon_id = i
|
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:
|
async def en_name_to_weapon_id(name: str) -> str:
|
||||||
weapon_id = ''
|
weapon_id = ""
|
||||||
for i in EquipmentID2EnName:
|
for i in EquipmentID2EnName:
|
||||||
if EquipmentID2EnName[i] == name:
|
if EquipmentID2EnName[i] == name:
|
||||||
weapon_id = i
|
weapon_id = i
|
||||||
|
@ -1,66 +1,55 @@
|
|||||||
import copy
|
import copy
|
||||||
import time
|
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 (
|
from gsuid_core.utils.api.mys.tools import (
|
||||||
mys_version,
|
|
||||||
_random_int_ds,
|
|
||||||
generate_os_ds,
|
generate_os_ds,
|
||||||
|
get_ds_token,
|
||||||
get_web_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.api import _API
|
||||||
from ..sruid_utils.api.mys.models import (
|
from ..sruid_utils.api.mys.models import (
|
||||||
MysSign,
|
AbyssBossData,
|
||||||
|
AbyssData,
|
||||||
|
AbyssStoryData,
|
||||||
|
AvatarDetail,
|
||||||
|
AvatarInfo,
|
||||||
|
DailyNoteData,
|
||||||
GachaLog,
|
GachaLog,
|
||||||
|
MonthlyAward,
|
||||||
|
MysSign,
|
||||||
|
RogueData,
|
||||||
|
RogueLocustData,
|
||||||
|
RoleBasicInfo,
|
||||||
|
RoleIndex,
|
||||||
SignInfo,
|
SignInfo,
|
||||||
SignList,
|
SignList,
|
||||||
AbyssData,
|
|
||||||
RogueData,
|
|
||||||
RoleIndex,
|
|
||||||
AvatarInfo,
|
|
||||||
AvatarDetail,
|
|
||||||
MonthlyAward,
|
|
||||||
DailyNoteData,
|
|
||||||
RoleBasicInfo,
|
|
||||||
WidgetStamina,
|
WidgetStamina,
|
||||||
RogueLocustData, AbyssStoryData, AbyssBossData,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
RECOGNIZE_SERVER = {
|
RECOGNIZE_SERVER = {
|
||||||
'1': 'prod_gf_cn',
|
"1": "prod_gf_cn",
|
||||||
'2': 'prod_gf_cn',
|
"2": "prod_gf_cn",
|
||||||
'5': 'prod_qd_cn',
|
"5": "prod_qd_cn",
|
||||||
'6': 'prod_official_usa',
|
"6": "prod_official_usa",
|
||||||
'7': 'prod_official_euro',
|
"7": "prod_official_euro",
|
||||||
'8': 'prod_official_asia',
|
"8": "prod_official_asia",
|
||||||
'9': 'prod_official_cht',
|
"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):
|
class MysApi(_MysApi):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
async def get_sr_ck(
|
async def get_sr_ck(
|
||||||
self, uid: str, mode: Literal['OWNER', 'RANDOM'] = 'RANDOM'
|
self, uid: str, mode: Literal["OWNER", "RANDOM"] = "RANDOM"
|
||||||
) -> Optional[str]:
|
) -> Optional[str]:
|
||||||
return await self.get_ck(uid, mode, 'sr')
|
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
|
|
||||||
|
|
||||||
async def simple_sr_req(
|
async def simple_sr_req(
|
||||||
self,
|
self,
|
||||||
@ -76,40 +65,38 @@ class MysApi(_MysApi):
|
|||||||
params,
|
params,
|
||||||
header,
|
header,
|
||||||
cookie,
|
cookie,
|
||||||
'sr',
|
"sr",
|
||||||
)
|
)
|
||||||
|
|
||||||
async def get_daily_data(self, uid: str) -> Union[DailyNoteData, int]:
|
async def get_sr_daily_data(self, uid: str) -> Union[DailyNoteData, int]:
|
||||||
is_os = self.check_os(uid)
|
if self.check_os(uid, game_name="sr"):
|
||||||
if is_os:
|
|
||||||
HEADER = copy.deepcopy(self._HEADER_OS)
|
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:
|
if ck is None:
|
||||||
return -51
|
return -51
|
||||||
HEADER['Cookie'] = ck
|
HEADER["Cookie"] = ck
|
||||||
HEADER['DS'] = generate_os_ds()
|
HEADER["DS"] = generate_os_ds()
|
||||||
header = HEADER
|
header = HEADER
|
||||||
data = await self.simple_sr_req(
|
data = await self.simple_sr_req(
|
||||||
'STAR_RAIL_NOTE_URL',
|
"STAR_RAIL_NOTE_URL",
|
||||||
uid,
|
uid,
|
||||||
params={
|
params={
|
||||||
'role_id': uid,
|
"role_id": uid,
|
||||||
'server': RECOGNIZE_SERVER.get(str(uid)[0], 'prod_gf_cn'),
|
"server": RECOGNIZE_SERVER.get(str(uid)[0], "prod_gf_cn"),
|
||||||
},
|
},
|
||||||
header=header,
|
header=header,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
data = await self.simple_sr_req(
|
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):
|
if isinstance(data, Dict):
|
||||||
# workaround for mistake params in hoyolab
|
# workaround for mistake params in hoyolab
|
||||||
if data['data']['accepted_epedition_num']:
|
if data["data"]["accepted_epedition_num"]:
|
||||||
data['data']['accepted_expedition_num'] = data['data'][
|
data["data"]["accepted_expedition_num"] = data["data"][
|
||||||
'accepted_epedition_num'
|
"accepted_epedition_num"
|
||||||
]
|
]
|
||||||
data = msgspec.convert(data['data'], type=DailyNoteData)
|
data = msgspec.convert(data["data"], type=DailyNoteData)
|
||||||
# data = cast(DailyNoteData, data['data'])
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
async def get_widget_stamina_data(
|
async def get_widget_stamina_data(
|
||||||
@ -117,389 +104,373 @@ class MysApi(_MysApi):
|
|||||||
uid: str,
|
uid: str,
|
||||||
) -> Union[WidgetStamina, int]:
|
) -> Union[WidgetStamina, int]:
|
||||||
header = copy.deepcopy(self._HEADER)
|
header = copy.deepcopy(self._HEADER)
|
||||||
sk = await self.get_stoken(uid, 'sr')
|
sk = await self.get_stoken(uid, "sr")
|
||||||
if sk is None:
|
if sk is None:
|
||||||
return -51
|
return -51
|
||||||
header['Cookie'] = sk
|
header["Cookie"] = sk
|
||||||
header['x-rpc-channel'] = 'beta'
|
header["x-rpc-channel"] = "beta"
|
||||||
device_id = await self.get_user_device_id(uid, 'sr')
|
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-device_id"] = "23" if device_id is None else device_id
|
||||||
header['x-rpc-app_version'] = '2.53.0'
|
header["x-rpc-app_version"] = "2.53.0"
|
||||||
header['x-rpc-device_model'] = 'Mi 10'
|
header["x-rpc-device_model"] = "Mi 10"
|
||||||
fp = await self.get_user_fp(uid, 'sr')
|
fp = await self.get_user_fp(uid, "sr")
|
||||||
header['x-rpc-device_fp'] = 'Asmr489' if fp is None else fp
|
header["x-rpc-device_fp"] = "Asmr489" if fp is None else fp
|
||||||
header['x-rpc-client_type'] = '2'
|
header["x-rpc-client_type"] = "2"
|
||||||
header['DS'] = get_ds_token2()
|
header["DS"] = get_ds_token()
|
||||||
header['Referer'] = 'https://app.mihoyo.com'
|
header["Referer"] = "https://app.mihoyo.com"
|
||||||
del header['Origin']
|
del header["Origin"]
|
||||||
header['x-rpc-sys_version'] = '12'
|
header["x-rpc-sys_version"] = "12"
|
||||||
header['User-Agent'] = 'okhttp/4.8.0'
|
header["User-Agent"] = "okhttp/4.8.0"
|
||||||
data = await self._mys_request(
|
data = await self._mys_request(
|
||||||
_API['STAR_RAIL_WIDGRT_URL'],
|
_API["STAR_RAIL_WIDGRT_URL"],
|
||||||
'GET',
|
"GET",
|
||||||
header,
|
header,
|
||||||
)
|
)
|
||||||
if isinstance(data, Dict):
|
if isinstance(data, Dict):
|
||||||
data = msgspec.convert(data['data'], type=WidgetStamina)
|
data = msgspec.convert(data["data"], type=WidgetStamina)
|
||||||
# data = cast(WidgetStamina, data['data'])
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
async def get_role_index(self, uid: str) -> Union[RoleIndex, int]:
|
async def get_role_index(self, uid: str) -> Union[RoleIndex, int]:
|
||||||
is_os = self.check_os(uid)
|
if self.check_os(uid, game_name="sr"):
|
||||||
if is_os:
|
|
||||||
HEADER = copy.deepcopy(self._HEADER_OS)
|
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:
|
if ck is None:
|
||||||
return -51
|
return -51
|
||||||
HEADER['Cookie'] = ck
|
HEADER["Cookie"] = ck
|
||||||
HEADER['DS'] = generate_os_ds()
|
HEADER["DS"] = generate_os_ds()
|
||||||
header = HEADER
|
header = HEADER
|
||||||
data = await self.simple_sr_req(
|
data = await self.simple_sr_req(
|
||||||
'STAR_RAIL_INDEX_URL',
|
"STAR_RAIL_INDEX_URL",
|
||||||
uid,
|
uid,
|
||||||
params={
|
params={
|
||||||
'role_id': uid,
|
"role_id": uid,
|
||||||
'server': RECOGNIZE_SERVER.get(str(uid)[0], 'prod_gf_cn'),
|
"server": RECOGNIZE_SERVER.get(str(uid)[0], "prod_gf_cn"),
|
||||||
},
|
},
|
||||||
header=header,
|
header=header,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
data = await self.simple_sr_req(
|
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):
|
if isinstance(data, Dict):
|
||||||
data = msgspec.convert(data['data'], type=RoleIndex)
|
data = msgspec.convert(data["data"], type=RoleIndex)
|
||||||
# data = cast(RoleIndex, data['data'])
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
async def get_gacha_log_by_link_in_authkey(
|
async def get_gacha_log_by_link_in_authkey(
|
||||||
self,
|
self,
|
||||||
uid: str,
|
uid: str,
|
||||||
authkey: str,
|
authkey: str,
|
||||||
gacha_type: str = '11',
|
gacha_type: str = "11",
|
||||||
page: int = 1,
|
page: int = 1,
|
||||||
end_id: str = '0',
|
end_id: str = "0",
|
||||||
) -> Union[int, GachaLog]:
|
) -> Union[int, GachaLog]:
|
||||||
# server_id = 'cn_qd01' if
|
|
||||||
# uid[0] == '5' else 'cn_gf01'
|
|
||||||
server_id = RECOGNIZE_SERVER.get(str(uid)[0])
|
server_id = RECOGNIZE_SERVER.get(str(uid)[0])
|
||||||
if self.check_os(uid):
|
if self.check_os(uid):
|
||||||
HEADER = copy.deepcopy(self._HEADER_OS)
|
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:
|
if ck is None:
|
||||||
return -51
|
return -51
|
||||||
HEADER['Cookie'] = ck
|
HEADER["Cookie"] = ck
|
||||||
HEADER['DS'] = generate_os_ds()
|
HEADER["DS"] = generate_os_ds()
|
||||||
header = HEADER
|
header = HEADER
|
||||||
url = self.MAPI['STAR_RAIL_GACHA_LOG_URL_OS']
|
url = self.MAPI["STAR_RAIL_GACHA_LOG_URL_OS"]
|
||||||
game_biz = 'hkrpg_global'
|
game_biz = "hkrpg_global"
|
||||||
else:
|
else:
|
||||||
header = self._HEADER
|
header = self._HEADER
|
||||||
url = self.MAPI['STAR_RAIL_GACHA_LOG_URL']
|
url = self.MAPI["STAR_RAIL_GACHA_LOG_URL"]
|
||||||
game_biz = 'hkrpg_cn'
|
game_biz = "hkrpg_cn"
|
||||||
data = await self._mys_request(
|
data = await self._mys_request(
|
||||||
url=url,
|
url=url,
|
||||||
method='GET',
|
method="GET",
|
||||||
header=header,
|
header=header,
|
||||||
params={
|
params={
|
||||||
'authkey_ver': '1',
|
"authkey_ver": "1",
|
||||||
'sign_type': '2',
|
"sign_type": "2",
|
||||||
'auth_appid': 'webview_gacha',
|
"auth_appid": "webview_gacha",
|
||||||
'default_gacha_type': 11,
|
"default_gacha_type": 11,
|
||||||
'gacha_id': 'dbebc8d9fbb0d4ffa067423482ce505bc5ea',
|
"gacha_id": "dbebc8d9fbb0d4ffa067423482ce505bc5ea",
|
||||||
'timestamp': str(int(time.time())),
|
"timestamp": str(int(time.time())),
|
||||||
'lang': 'zh-cn',
|
"lang": "zh-cn",
|
||||||
'plat_type': 'pc',
|
"plat_type": "pc",
|
||||||
'region': server_id,
|
"region": server_id,
|
||||||
'authkey': authkey,
|
"authkey": authkey,
|
||||||
'game_biz': game_biz,
|
"game_biz": game_biz,
|
||||||
'gacha_type': gacha_type,
|
"gacha_type": gacha_type,
|
||||||
'page': page,
|
"page": page,
|
||||||
'size': '20',
|
"size": "20",
|
||||||
'end_id': end_id,
|
"end_id": end_id,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
if isinstance(data, Dict):
|
if isinstance(data, Dict):
|
||||||
data = msgspec.convert(data['data'], type=GachaLog)
|
data = msgspec.convert(data["data"], type=GachaLog)
|
||||||
# data = cast(GachaLog, data['data'])
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
async def get_avatar_info(
|
async def get_avatar_info(
|
||||||
self, uid: str, avatar_id: int, need_wiki: bool = False
|
self, uid: str, avatar_id: int, need_wiki: bool = False
|
||||||
) -> Union[AvatarInfo, int]:
|
) -> Union[AvatarInfo, int]:
|
||||||
is_os = self.check_os(uid)
|
if self.check_os(uid, game_name="sr"):
|
||||||
if is_os:
|
|
||||||
HEADER = copy.deepcopy(self._HEADER_OS)
|
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:
|
if ck is None:
|
||||||
return -51
|
return -51
|
||||||
HEADER['Cookie'] = ck
|
HEADER["Cookie"] = ck
|
||||||
HEADER['DS'] = generate_os_ds()
|
HEADER["DS"] = generate_os_ds()
|
||||||
header = HEADER
|
header = HEADER
|
||||||
data = await self.simple_sr_req(
|
data = await self.simple_sr_req(
|
||||||
'STAR_RAIL_AVATAR_INFO_URL',
|
"STAR_RAIL_AVATAR_INFO_URL",
|
||||||
uid,
|
uid,
|
||||||
params={
|
params={
|
||||||
'need_wiki': 'true' if need_wiki else 'false',
|
"need_wiki": "true" if need_wiki else "false",
|
||||||
'role_id': uid,
|
"role_id": uid,
|
||||||
'server': RECOGNIZE_SERVER.get(str(uid)[0], 'prod_gf_cn'),
|
"server": RECOGNIZE_SERVER.get(str(uid)[0], "prod_official_asia"),
|
||||||
},
|
},
|
||||||
header=header,
|
header=header,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
data = await self.simple_sr_req(
|
data = await self.simple_sr_req(
|
||||||
'STAR_RAIL_AVATAR_INFO_URL',
|
"STAR_RAIL_AVATAR_INFO_URL",
|
||||||
uid,
|
uid,
|
||||||
params={
|
params={
|
||||||
'id': avatar_id,
|
"id": avatar_id,
|
||||||
'need_wiki': 'true' if need_wiki else 'false',
|
"need_wiki": "true" if need_wiki else "false",
|
||||||
'role_id': uid,
|
"role_id": uid,
|
||||||
'server': RECOGNIZE_SERVER.get(str(uid)[0], 'prod_gf_cn'),
|
"server": RECOGNIZE_SERVER.get(str(uid)[0], "prod_gf_cn"),
|
||||||
},
|
},
|
||||||
header=self._HEADER,
|
header=self._HEADER,
|
||||||
)
|
)
|
||||||
if isinstance(data, Dict):
|
if isinstance(data, Dict):
|
||||||
data = msgspec.convert(data['data'], type=AvatarInfo)
|
data = msgspec.convert(data["data"], type=AvatarInfo)
|
||||||
# data = cast(AvatarInfo, data['data'])
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
async def get_avatar_detail(self, uid: str, avatarid: str):
|
async def get_avatar_detail(self, uid: str, avatarid: str):
|
||||||
data = await self.simple_sr_req(
|
data = await self.simple_sr_req(
|
||||||
'STAR_RAIL_AVATAR_DETAIL_URL',
|
"STAR_RAIL_AVATAR_DETAIL_URL",
|
||||||
uid,
|
uid,
|
||||||
params={
|
params={
|
||||||
'game': 'hkrpg',
|
"game": "hkrpg",
|
||||||
'lang': 'zh-cn',
|
"lang": "zh-cn",
|
||||||
'item_id': avatarid,
|
"item_id": avatarid,
|
||||||
'tab_from': 'TabOwned',
|
"tab_from": "TabOwned",
|
||||||
'change_target_level': '0',
|
"change_target_level": "0",
|
||||||
'uid': uid,
|
"uid": uid,
|
||||||
'region': RECOGNIZE_SERVER.get(str(uid)[0], 'prod_gf_cn'),
|
"region": RECOGNIZE_SERVER.get(str(uid)[0], "prod_gf_cn"),
|
||||||
},
|
},
|
||||||
header=self._HEADER,
|
header=self._HEADER,
|
||||||
)
|
)
|
||||||
if isinstance(data, Dict):
|
if isinstance(data, Dict):
|
||||||
data = msgspec.convert(data['data'], type=AvatarDetail)
|
data = msgspec.convert(data["data"], type=AvatarDetail)
|
||||||
return data
|
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)
|
is_os = self.check_os(uid)
|
||||||
if is_os:
|
if is_os:
|
||||||
params = {
|
params = {
|
||||||
'act_id': 'e202303301540311',
|
"act_id": "e202303301540311",
|
||||||
'lang': 'zh-cn',
|
"lang": "zh-cn",
|
||||||
}
|
}
|
||||||
|
|
||||||
else:
|
else:
|
||||||
params = {
|
params = {
|
||||||
'act_id': 'e202304121516551',
|
"act_id": "e202304121516551",
|
||||||
'lang': 'zh-cn',
|
"lang": "zh-cn",
|
||||||
}
|
}
|
||||||
|
|
||||||
data = await self._mys_req_get(
|
data = await self._mys_req_get(
|
||||||
'STAR_RAIL_SIGN_LIST_URL',
|
"STAR_RAIL_SIGN_LIST_URL",
|
||||||
is_os,
|
is_os,
|
||||||
params,
|
params,
|
||||||
)
|
)
|
||||||
if isinstance(data, Dict):
|
if isinstance(data, Dict):
|
||||||
data = msgspec.convert(data['data'], type=SignList)
|
data = msgspec.convert(data["data"], type=SignList)
|
||||||
# data = cast(SignList, data['data'])
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
async def get_sign_info(self, uid) -> Union[SignInfo, int]:
|
async def get_sr_sign_info(self, uid) -> Union[SignInfo, int]:
|
||||||
# server_id = RECOGNIZE_SERVER.get(str(uid)[0])
|
|
||||||
is_os = self.check_os(uid)
|
is_os = self.check_os(uid)
|
||||||
if is_os:
|
if is_os:
|
||||||
# TODO
|
# TODO
|
||||||
params = {
|
params = {
|
||||||
'act_id': 'e202303301540311',
|
"act_id": "e202303301540311",
|
||||||
'lang': 'zh-cn',
|
"lang": "zh-cn",
|
||||||
}
|
}
|
||||||
HEADER = copy.deepcopy(self._HEADER_OS)
|
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:
|
if ck is None:
|
||||||
return -51
|
return -51
|
||||||
HEADER['Cookie'] = ck
|
HEADER["Cookie"] = ck
|
||||||
HEADER['DS'] = generate_os_ds()
|
HEADER["DS"] = generate_os_ds()
|
||||||
header = HEADER
|
header = HEADER
|
||||||
else:
|
else:
|
||||||
params = {
|
params = {
|
||||||
'act_id': 'e202304121516551',
|
"act_id": "e202304121516551",
|
||||||
'lang': 'zh-cn',
|
"lang": "zh-cn",
|
||||||
'region': 'prod_gf_cn',
|
"region": "prod_gf_cn",
|
||||||
'uid': uid,
|
"uid": uid,
|
||||||
}
|
}
|
||||||
header = self._HEADER
|
header = self._HEADER
|
||||||
data = await self._mys_req_get(
|
data = await self._mys_req_get(
|
||||||
'STAR_RAIL_SIGN_INFO_URL',
|
"STAR_RAIL_SIGN_INFO_URL",
|
||||||
is_os,
|
is_os,
|
||||||
params,
|
params,
|
||||||
header,
|
header,
|
||||||
)
|
)
|
||||||
if isinstance(data, Dict):
|
if isinstance(data, Dict):
|
||||||
data = msgspec.convert(data['data'], type=SignInfo)
|
data = msgspec.convert(data["data"], type=SignInfo)
|
||||||
# data = cast(SignInfo, data['data'])
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
async def get_abyss_info(
|
async def get_abyss_info(
|
||||||
self,
|
self,
|
||||||
uid: str,
|
uid: str,
|
||||||
schedule_type='1',
|
schedule_type="1",
|
||||||
ck: Optional[str] = None,
|
ck: Optional[str] = None,
|
||||||
) -> Union[AbyssData, int]:
|
) -> Union[AbyssData, int]:
|
||||||
server_id = self.RECOGNIZE_SERVER.get(uid[0])
|
server_id = self.RECOGNIZE_SERVER.get(uid[0])
|
||||||
is_os = self.check_os(uid)
|
if self.check_os(uid, game_name="sr"):
|
||||||
if is_os:
|
|
||||||
HEADER = copy.deepcopy(self._HEADER_OS)
|
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:
|
if ck is None:
|
||||||
return -51
|
return -51
|
||||||
HEADER['Cookie'] = ck
|
HEADER["Cookie"] = ck
|
||||||
HEADER['DS'] = generate_os_ds()
|
HEADER["DS"] = generate_os_ds()
|
||||||
header = HEADER
|
header = HEADER
|
||||||
data = await self.simple_sr_req(
|
data = await self.simple_sr_req(
|
||||||
'CHALLENGE_INFO_URL',
|
"CHALLENGE_INFO_URL",
|
||||||
uid,
|
uid,
|
||||||
params={
|
params={
|
||||||
'need_all': 'true',
|
"need_all": "true",
|
||||||
'role_id': uid,
|
"role_id": uid,
|
||||||
'schedule_type': schedule_type,
|
"schedule_type": schedule_type,
|
||||||
'server': server_id,
|
"server": server_id,
|
||||||
},
|
},
|
||||||
header=header,
|
header=header,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
data = await self.simple_sr_req(
|
data = await self.simple_sr_req(
|
||||||
'CHALLENGE_INFO_URL',
|
"CHALLENGE_INFO_URL",
|
||||||
uid,
|
uid,
|
||||||
params={
|
params={
|
||||||
'isPrev': 'true',
|
"isPrev": "true",
|
||||||
'need_all': 'true',
|
"need_all": "true",
|
||||||
'role_id': uid,
|
"role_id": uid,
|
||||||
'schedule_type': schedule_type,
|
"schedule_type": schedule_type,
|
||||||
'server': server_id,
|
"server": server_id,
|
||||||
},
|
},
|
||||||
cookie=ck,
|
cookie=ck,
|
||||||
header=self._HEADER,
|
header=self._HEADER,
|
||||||
)
|
)
|
||||||
if isinstance(data, Dict):
|
if isinstance(data, Dict):
|
||||||
data = msgspec.convert(data['data'], type=AbyssData)
|
data = msgspec.convert(data["data"], type=AbyssData)
|
||||||
# data = cast(AbyssData, data['data'])
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
async def get_abyss_story_info(
|
async def get_abyss_story_info(
|
||||||
self,
|
self,
|
||||||
uid: str,
|
uid: str,
|
||||||
schedule_type='1',
|
schedule_type="1",
|
||||||
ck: Optional[str] = None,
|
ck: Optional[str] = None,
|
||||||
) -> Union[AbyssData, int]:
|
) -> Union[AbyssStoryData, int]:
|
||||||
server_id = self.RECOGNIZE_SERVER.get(uid[0])
|
server_id = self.RECOGNIZE_SERVER.get(uid[0])
|
||||||
is_os = self.check_os(uid)
|
if self.check_os(uid, game_name="sr"):
|
||||||
if is_os:
|
|
||||||
HEADER = copy.deepcopy(self._HEADER_OS)
|
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:
|
if ck is None:
|
||||||
return -51
|
return -51
|
||||||
HEADER['Cookie'] = ck
|
HEADER["Cookie"] = ck
|
||||||
HEADER['DS'] = generate_os_ds()
|
HEADER["DS"] = generate_os_ds()
|
||||||
header = HEADER
|
header = HEADER
|
||||||
data = await self.simple_sr_req(
|
data = await self.simple_sr_req(
|
||||||
'CHALLENGE_STORY_INFO_URL',
|
"CHALLENGE_STORY_INFO_URL",
|
||||||
uid,
|
uid,
|
||||||
params={
|
params={
|
||||||
'need_all': 'true',
|
"need_all": "true",
|
||||||
'role_id': uid,
|
"role_id": uid,
|
||||||
'schedule_type': schedule_type,
|
"schedule_type": schedule_type,
|
||||||
'server': server_id,
|
"server": server_id,
|
||||||
},
|
},
|
||||||
header=header,
|
header=header,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
data = await self.simple_sr_req(
|
data = await self.simple_sr_req(
|
||||||
'CHALLENGE_STORY_INFO_URL',
|
"CHALLENGE_STORY_INFO_URL",
|
||||||
uid,
|
uid,
|
||||||
params={
|
params={
|
||||||
'isPrev': 'true',
|
"isPrev": "true",
|
||||||
'need_all': 'true',
|
"need_all": "true",
|
||||||
'role_id': uid,
|
"role_id": uid,
|
||||||
'schedule_type': schedule_type,
|
"schedule_type": schedule_type,
|
||||||
'server': server_id,
|
"server": server_id,
|
||||||
},
|
},
|
||||||
cookie=ck,
|
cookie=ck,
|
||||||
header=self._HEADER,
|
header=self._HEADER,
|
||||||
)
|
)
|
||||||
if isinstance(data, Dict):
|
if isinstance(data, Dict):
|
||||||
data = msgspec.convert(data['data'], type=AbyssStoryData)
|
data = msgspec.convert(data["data"], type=AbyssStoryData)
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
async def get_abyss_boss_info(
|
async def get_abyss_boss_info(
|
||||||
self,
|
self,
|
||||||
uid: str,
|
uid: str,
|
||||||
schedule_type='1',
|
schedule_type="1",
|
||||||
ck: Optional[str] = None,
|
ck: Optional[str] = None,
|
||||||
) -> Union[AbyssBossData, int]:
|
) -> Union[AbyssBossData, int]:
|
||||||
server_id = self.RECOGNIZE_SERVER.get(uid[0])
|
server_id = self.RECOGNIZE_SERVER.get(uid[0])
|
||||||
is_os = self.check_os(uid)
|
if self.check_os(uid, game_name="sr"):
|
||||||
if is_os:
|
|
||||||
HEADER = copy.deepcopy(self._HEADER_OS)
|
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:
|
if ck is None:
|
||||||
return -51
|
return -51
|
||||||
HEADER['Cookie'] = ck
|
HEADER["Cookie"] = ck
|
||||||
HEADER['DS'] = generate_os_ds()
|
HEADER["DS"] = generate_os_ds()
|
||||||
header = HEADER
|
header = HEADER
|
||||||
data = await self.simple_sr_req(
|
data = await self.simple_sr_req(
|
||||||
'CHALLENGE_BOSS_INFO_URL',
|
"CHALLENGE_BOSS_INFO_URL",
|
||||||
uid,
|
uid,
|
||||||
params={
|
params={
|
||||||
'need_all': 'true',
|
"need_all": "true",
|
||||||
'role_id': uid,
|
"role_id": uid,
|
||||||
'schedule_type': schedule_type,
|
"schedule_type": schedule_type,
|
||||||
'server': server_id,
|
"server": server_id,
|
||||||
},
|
},
|
||||||
header=header,
|
header=header,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
data = await self.simple_sr_req(
|
data = await self.simple_sr_req(
|
||||||
'CHALLENGE_BOSS_INFO_URL',
|
"CHALLENGE_BOSS_INFO_URL",
|
||||||
uid,
|
uid,
|
||||||
params={
|
params={
|
||||||
'isPrev': 'true',
|
"isPrev": "true",
|
||||||
'need_all': 'true',
|
"need_all": "true",
|
||||||
'role_id': uid,
|
"role_id": uid,
|
||||||
'schedule_type': schedule_type,
|
"schedule_type": schedule_type,
|
||||||
'server': server_id,
|
"server": server_id,
|
||||||
},
|
},
|
||||||
cookie=ck,
|
cookie=ck,
|
||||||
header=self._HEADER,
|
header=self._HEADER,
|
||||||
)
|
)
|
||||||
if isinstance(data, Dict):
|
if isinstance(data, Dict):
|
||||||
data = msgspec.convert(data['data'], type=AbyssBossData)
|
data = msgspec.convert(data["data"], type=AbyssBossData)
|
||||||
# data = cast(AbyssData, data['data'])
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
async def get_rogue_info(
|
async def get_rogue_info(
|
||||||
self,
|
self,
|
||||||
uid: str,
|
uid: str,
|
||||||
schedule_type='3',
|
schedule_type="3",
|
||||||
ck: Optional[str] = None,
|
ck: Optional[str] = None,
|
||||||
) -> Union[RogueData, int]:
|
) -> Union[RogueData, int]:
|
||||||
server_id = self.RECOGNIZE_SERVER.get(uid[0])
|
server_id = self.RECOGNIZE_SERVER.get(uid[0])
|
||||||
data = await self.simple_sr_req(
|
data = await self.simple_sr_req(
|
||||||
'ROGUE_INFO_URL',
|
"ROGUE_INFO_URL",
|
||||||
uid,
|
uid,
|
||||||
params={
|
params={
|
||||||
'need_detail': 'true',
|
"need_detail": "true",
|
||||||
'role_id': uid,
|
"role_id": uid,
|
||||||
'schedule_type': schedule_type,
|
"schedule_type": schedule_type,
|
||||||
'server': server_id,
|
"server": server_id,
|
||||||
},
|
},
|
||||||
cookie=ck,
|
cookie=ck,
|
||||||
header=self._HEADER,
|
header=self._HEADER,
|
||||||
)
|
)
|
||||||
if isinstance(data, Dict):
|
if isinstance(data, Dict):
|
||||||
data = msgspec.convert(data['data'], type=RogueData)
|
data = msgspec.convert(data["data"], type=RogueData)
|
||||||
# data = cast(RogueData, data['data'])
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
async def get_rogue_locust_info(
|
async def get_rogue_locust_info(
|
||||||
@ -508,99 +479,96 @@ class MysApi(_MysApi):
|
|||||||
ck: Optional[str] = None,
|
ck: Optional[str] = None,
|
||||||
) -> Union[RogueLocustData, int]:
|
) -> Union[RogueLocustData, int]:
|
||||||
server_id = self.RECOGNIZE_SERVER.get(uid[0])
|
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(
|
data = await self.simple_sr_req(
|
||||||
'ROGUE_LOCUST_INFO_URL',
|
"ROGUE_LOCUST_INFO_URL",
|
||||||
uid,
|
uid,
|
||||||
params={
|
params={
|
||||||
'need_detail': 'true',
|
"need_detail": "true",
|
||||||
'role_id': uid,
|
"role_id": uid,
|
||||||
'server': server_id,
|
"server": server_id,
|
||||||
},
|
},
|
||||||
cookie=ck,
|
cookie=ck,
|
||||||
header=self._HEADER,
|
header=self._HEADER,
|
||||||
)
|
)
|
||||||
if isinstance(data, Dict):
|
if isinstance(data, Dict):
|
||||||
data = msgspec.convert(data['data'], type=RogueLocustData)
|
data = msgspec.convert(data["data"], type=RogueLocustData)
|
||||||
# data = cast(RogueLocustData, data['data'])
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
async def mys_sign(
|
async def sr_mys_sign(
|
||||||
self, uid, header=None, server_id='cn_gf01'
|
self, uid, header=None, server_id="cn_gf01"
|
||||||
) -> Union[MysSign, int]:
|
) -> Union[MysSign, int]:
|
||||||
if header is None:
|
if header is None:
|
||||||
header = {}
|
header = {}
|
||||||
ck = await self.get_sr_ck(uid, 'OWNER')
|
ck = await self.get_sr_ck(uid, "OWNER")
|
||||||
if ck is None:
|
if ck is None:
|
||||||
return -51
|
return -51
|
||||||
if int(str(uid)[0]) < 6:
|
if int(str(uid)[0]) < 6:
|
||||||
HEADER = copy.deepcopy(self._HEADER)
|
HEADER = copy.deepcopy(self._HEADER)
|
||||||
HEADER['Cookie'] = ck
|
HEADER["Cookie"] = ck
|
||||||
HEADER['x-rpc-app_version'] = mys_version
|
HEADER["x-rpc-app_version"] = mys_version
|
||||||
HEADER['x-rpc-client_type'] = '5'
|
HEADER["x-rpc-client_type"] = "5"
|
||||||
HEADER['X_Requested_With'] = 'com.mihoyo.hyperion'
|
HEADER["X_Requested_With"] = "com.mihoyo.hyperion"
|
||||||
HEADER['DS'] = get_web_ds_token(True)
|
HEADER["DS"] = get_web_ds_token(True)
|
||||||
HEADER['Referer'] = 'https://webstatic.mihoyo.com'
|
HEADER["Referer"] = "https://webstatic.mihoyo.com"
|
||||||
HEADER.update(header)
|
HEADER.update(header)
|
||||||
data = await self._mys_request(
|
data = await self._mys_request(
|
||||||
url=_API['STAR_RAIL_SIGN_URL'],
|
url=_API["STAR_RAIL_SIGN_URL"],
|
||||||
method='POST',
|
method="POST",
|
||||||
header=HEADER,
|
header=HEADER,
|
||||||
data={
|
data={
|
||||||
'act_id': 'e202304121516551',
|
"act_id": "e202304121516551",
|
||||||
'region': 'prod_gf_cn',
|
"region": "prod_gf_cn",
|
||||||
'uid': uid,
|
"uid": uid,
|
||||||
'lang': 'zh-cn',
|
"lang": "zh-cn",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
HEADER = copy.deepcopy(self._HEADER_OS)
|
HEADER = copy.deepcopy(self._HEADER_OS)
|
||||||
HEADER['Cookie'] = ck
|
HEADER["Cookie"] = ck
|
||||||
HEADER['DS'] = generate_os_ds()
|
HEADER["DS"] = generate_os_ds()
|
||||||
HEADER.update(header)
|
HEADER.update(header)
|
||||||
data = await self._mys_request(
|
data = await self._mys_request(
|
||||||
url=_API['STAR_RAIL_SIGN_URL_OS'],
|
url=_API["STAR_RAIL_SIGN_URL_OS"],
|
||||||
method='POST',
|
method="POST",
|
||||||
header=HEADER,
|
header=HEADER,
|
||||||
data={
|
data={
|
||||||
'act_id': 'e202303301540311',
|
"act_id": "e202303301540311",
|
||||||
'lang': 'zh-cn',
|
"lang": "zh-cn",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
if isinstance(data, Dict):
|
if isinstance(data, Dict):
|
||||||
data = msgspec.convert(data['data'], type=MysSign)
|
data = msgspec.convert(data["data"], type=MysSign)
|
||||||
# data = cast(MysSign, data['data'])
|
|
||||||
return data
|
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])
|
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:
|
if ck is None:
|
||||||
return -51
|
return -51
|
||||||
if int(str(sr_uid)[0]) < 6:
|
if int(str(sr_uid)[0]) < 6:
|
||||||
HEADER = copy.deepcopy(self._HEADER)
|
HEADER = copy.deepcopy(self._HEADER)
|
||||||
HEADER['Cookie'] = ck
|
HEADER["Cookie"] = ck
|
||||||
HEADER['DS'] = get_web_ds_token(True)
|
HEADER["DS"] = get_web_ds_token(True)
|
||||||
data = await self._mys_request(
|
data = await self._mys_request(
|
||||||
url=_API['STAR_RAIL_MONTH_INFO_URL'],
|
url=_API["STAR_RAIL_MONTH_INFO_URL"],
|
||||||
method='GET',
|
method="GET",
|
||||||
header=HEADER,
|
header=HEADER,
|
||||||
params={'uid': sr_uid, 'region': server_id, 'month': month},
|
params={"uid": sr_uid, "region": server_id, "month": month},
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
HEADER = copy.deepcopy(self._HEADER_OS)
|
HEADER = copy.deepcopy(self._HEADER_OS)
|
||||||
HEADER['Cookie'] = ck
|
HEADER["Cookie"] = ck
|
||||||
HEADER['DS'] = generate_os_ds()
|
HEADER["DS"] = generate_os_ds()
|
||||||
data = await self._mys_request(
|
data = await self._mys_request(
|
||||||
url=_API['STAR_RAIL_MONTH_INFO_URL'],
|
url=_API["STAR_RAIL_MONTH_INFO_URL"],
|
||||||
method='GET',
|
method="GET",
|
||||||
header=HEADER,
|
header=HEADER,
|
||||||
params={'uid': sr_uid, 'region': server_id, 'month': month},
|
params={"uid": sr_uid, "region": server_id, "month": month},
|
||||||
use_proxy=True,
|
use_proxy=True,
|
||||||
)
|
)
|
||||||
if isinstance(data, Dict):
|
if isinstance(data, Dict):
|
||||||
data = msgspec.convert(data['data'], type=MonthlyAward)
|
data = msgspec.convert(data["data"], type=MonthlyAward)
|
||||||
# data = cast(MonthlyAward, data['data'])
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
async def get_role_basic_info(
|
async def get_role_basic_info(
|
||||||
@ -608,11 +576,10 @@ class MysApi(_MysApi):
|
|||||||
sr_uid: str,
|
sr_uid: str,
|
||||||
) -> Union[RoleBasicInfo, int]:
|
) -> Union[RoleBasicInfo, int]:
|
||||||
data = await self.simple_sr_req(
|
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):
|
if isinstance(data, Dict):
|
||||||
data = msgspec.convert(data['data'], type=RoleBasicInfo)
|
data = msgspec.convert(data["data"], type=RoleBasicInfo)
|
||||||
# data = cast(RoleBasicInfo, data['data'])
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,35 +3,35 @@ from pathlib import Path
|
|||||||
|
|
||||||
from gsuid_core.data_store import get_res_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))
|
sys.path.append(str(MAIN_PATH))
|
||||||
|
|
||||||
CU_BG_PATH = MAIN_PATH / 'bg'
|
CU_BG_PATH = MAIN_PATH / "bg"
|
||||||
CONFIG_PATH = MAIN_PATH / 'config.json'
|
CONFIG_PATH = MAIN_PATH / "config.json"
|
||||||
PLAYER_PATH = MAIN_PATH / 'players'
|
PLAYER_PATH = MAIN_PATH / "players"
|
||||||
RESOURCE_PATH = MAIN_PATH / 'resource'
|
RESOURCE_PATH = MAIN_PATH / "resource"
|
||||||
WIKI_PATH = MAIN_PATH / 'wiki'
|
WIKI_PATH = MAIN_PATH / "wiki"
|
||||||
GUIDE_PATH = MAIN_PATH / 'guide'
|
GUIDE_PATH = MAIN_PATH / "guide"
|
||||||
|
|
||||||
CHAR_ICON_PATH = RESOURCE_PATH / 'character'
|
CHAR_ICON_PATH = RESOURCE_PATH / "character"
|
||||||
CHAR_PORTRAIT_PATH = RESOURCE_PATH / 'character_portrait'
|
CHAR_PORTRAIT_PATH = RESOURCE_PATH / "character_portrait"
|
||||||
CONSUMABLE_PATH = RESOURCE_PATH / 'consumable'
|
CONSUMABLE_PATH = RESOURCE_PATH / "consumable"
|
||||||
ELEMENT_PATH = RESOURCE_PATH / 'element'
|
ELEMENT_PATH = RESOURCE_PATH / "element"
|
||||||
WEAPON_PATH = RESOURCE_PATH / 'light_cone'
|
WEAPON_PATH = RESOURCE_PATH / "light_cone"
|
||||||
RELIC_PATH = RESOURCE_PATH / 'relic'
|
RELIC_PATH = RESOURCE_PATH / "relic"
|
||||||
SKILL_PATH = RESOURCE_PATH / 'skill'
|
SKILL_PATH = RESOURCE_PATH / "skill"
|
||||||
TEMP_PATH = RESOURCE_PATH / 'temp'
|
TEMP_PATH = RESOURCE_PATH / "temp"
|
||||||
CHAR_PREVIEW_PATH = RESOURCE_PATH / 'character_preview'
|
CHAR_PREVIEW_PATH = RESOURCE_PATH / "character_preview"
|
||||||
|
|
||||||
WIKI_LIGHT_CONE_PATH = WIKI_PATH / 'light_cone'
|
WIKI_LIGHT_CONE_PATH = WIKI_PATH / "light_cone"
|
||||||
WIKI_MATERIAL_FOR_ROLE = WIKI_PATH / 'character_material'
|
WIKI_MATERIAL_FOR_ROLE = WIKI_PATH / "character_material"
|
||||||
WIKI_RELIC_PATH = WIKI_PATH / 'relic_set'
|
WIKI_RELIC_PATH = WIKI_PATH / "relic_set"
|
||||||
WIKI_ROLE_PATH = WIKI_PATH / 'character_overview'
|
WIKI_ROLE_PATH = WIKI_PATH / "character_overview"
|
||||||
|
|
||||||
GUIDE_LIGHT_CONE_PATH = GUIDE_PATH / 'light_cone'
|
GUIDE_LIGHT_CONE_PATH = GUIDE_PATH / "light_cone"
|
||||||
GUIDE_CHARACTER_PATH = GUIDE_PATH / 'character_overview'
|
GUIDE_CHARACTER_PATH = GUIDE_PATH / "character_overview"
|
||||||
|
|
||||||
TEXT2D_PATH = Path(__file__).parent / 'texture2d'
|
TEXT2D_PATH = Path(__file__).parent / "texture2d"
|
||||||
|
|
||||||
|
|
||||||
def init_dir():
|
def init_dir():
|
||||||
|
@ -20,22 +20,22 @@ from gsuid_core.utils.download_resource.download_core import download_all_file
|
|||||||
|
|
||||||
async def check_use():
|
async def check_use():
|
||||||
await download_all_file(
|
await download_all_file(
|
||||||
'StarRailUID',
|
"StarRailUID",
|
||||||
{
|
{
|
||||||
'resource/character': CHAR_ICON_PATH,
|
"resource/character": CHAR_ICON_PATH,
|
||||||
'resource/character_portrait': CHAR_PORTRAIT_PATH,
|
"resource/character_portrait": CHAR_PORTRAIT_PATH,
|
||||||
'resource/character_preview': CHAR_PREVIEW_PATH,
|
"resource/character_preview": CHAR_PREVIEW_PATH,
|
||||||
'resource/consumable': CONSUMABLE_PATH,
|
"resource/consumable": CONSUMABLE_PATH,
|
||||||
'resource/element': ELEMENT_PATH,
|
"resource/element": ELEMENT_PATH,
|
||||||
'guide/character_overview': GUIDE_CHARACTER_PATH,
|
"guide/character_overview": GUIDE_CHARACTER_PATH,
|
||||||
'guide/light_cone': GUIDE_LIGHT_CONE_PATH,
|
"guide/light_cone": GUIDE_LIGHT_CONE_PATH,
|
||||||
'resource/relic': RELIC_PATH,
|
"resource/relic": RELIC_PATH,
|
||||||
'resource/skill': SKILL_PATH,
|
"resource/skill": SKILL_PATH,
|
||||||
'resource/light_cone': WEAPON_PATH,
|
"resource/light_cone": WEAPON_PATH,
|
||||||
'wiki/light_cone': WIKI_LIGHT_CONE_PATH,
|
"wiki/light_cone": WIKI_LIGHT_CONE_PATH,
|
||||||
'wiki/character_material': WIKI_MATERIAL_FOR_ROLE,
|
"wiki/character_material": WIKI_MATERIAL_FOR_ROLE,
|
||||||
'wiki/relic_set': WIKI_RELIC_PATH,
|
"wiki/relic_set": WIKI_RELIC_PATH,
|
||||||
'wiki/character_overview': WIKI_ROLE_PATH,
|
"wiki/character_overview": WIKI_ROLE_PATH,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
return 'sr全部资源下载完成!'
|
return "sr全部资源下载完成!"
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
from ..starrailuid_config.sr_config import srconfig
|
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'
|
StarRailUID_version = "0.1.0"
|
||||||
StarRail_version = '2.4.0'
|
StarRail_version = "2.4.0"
|
||||||
|
@ -38,9 +38,13 @@ pytest = "^7.2.0"
|
|||||||
pytest-asyncio = "^0.20.3"
|
pytest-asyncio = "^0.20.3"
|
||||||
|
|
||||||
[tool.ruff]
|
[tool.ruff]
|
||||||
line-length = 79
|
line-length = 88
|
||||||
|
target-version = "py38"
|
||||||
|
|
||||||
|
[tool.ruff.lint]
|
||||||
select = [
|
select = [
|
||||||
"E", "W", # pycodestyle
|
"E",
|
||||||
|
"W", # pycodestyle
|
||||||
"F", # pyflakes
|
"F", # pyflakes
|
||||||
# "I", # isort
|
# "I", # isort
|
||||||
"RUF", # ruff
|
"RUF", # ruff
|
||||||
@ -78,30 +82,17 @@ ignore = [
|
|||||||
"PLR0911",
|
"PLR0911",
|
||||||
"PLW0603", # Using the global statement
|
"PLW0603", # Using the global statement
|
||||||
"TRY002",
|
"TRY002",
|
||||||
"TRY003"
|
"TRY003",
|
||||||
]
|
]
|
||||||
exclude = [
|
exclude = ["gen.py", ".ruff_cache"]
|
||||||
"gen.py",
|
|
||||||
".ruff_cache"
|
|
||||||
]
|
|
||||||
# Assume Python 3.8
|
|
||||||
target-version = "py38"
|
|
||||||
|
|
||||||
[tool.ruff.flake8-quotes]
|
[tool.ruff.lint.isort]
|
||||||
inline-quotes = "single"
|
|
||||||
|
|
||||||
[tool.ruff.format]
|
|
||||||
quote-style = "single"
|
|
||||||
|
|
||||||
[tool.ruff.isort]
|
|
||||||
case-sensitive = true
|
case-sensitive = true
|
||||||
force-sort-within-sections = true
|
force-sort-within-sections = true
|
||||||
extra-standard-library = ["typing_extensions"]
|
extra-standard-library = ["typing_extensions"]
|
||||||
#force-wrap-aliases = true
|
|
||||||
combine-as-imports = true
|
combine-as-imports = true
|
||||||
order-by-type = true
|
order-by-type = true
|
||||||
relative-imports-order = "closest-to-furthest"
|
relative-imports-order = "closest-to-furthest"
|
||||||
section-order = ["future", "standard-library", "first-party", "local-folder", "third-party"]
|
|
||||||
|
|
||||||
[tool.pdm]
|
[tool.pdm]
|
||||||
[tool.pdm.build]
|
[tool.pdm.build]
|
||||||
@ -140,13 +131,9 @@ dev = [
|
|||||||
"pre-commit>=3.3.2",
|
"pre-commit>=3.3.2",
|
||||||
"flake8>=6.0.0",
|
"flake8>=6.0.0",
|
||||||
"isort>=5.12.0",
|
"isort>=5.12.0",
|
||||||
"pycln>=2.1.2"
|
"pycln>=2.1.2",
|
||||||
]
|
|
||||||
test = [
|
|
||||||
"nonebug>=0.3.0",
|
|
||||||
"pytest>=7.2.0",
|
|
||||||
"pytest-asyncio>=0.20.3"
|
|
||||||
]
|
]
|
||||||
|
test = ["nonebug>=0.3.0", "pytest>=7.2.0", "pytest-asyncio>=0.20.3"]
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["pdm-backend"]
|
requires = ["pdm-backend"]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user