🎨 大规范

This commit is contained in:
qwerdvd 2023-08-30 20:03:54 +08:00
parent 361cd1f7cd
commit 7ee9ff6c42
59 changed files with 1059 additions and 607 deletions

View File

@ -1,6 +1,6 @@
"""Mihomo.me api 包装
"""
from .models import MihomoData as MihomoData # noqa: F401
from .requests import get_char_card_info as get_char_card_info # noqa: F401
from .models import MihomoData as MihomoData
from .requests import get_char_card_info as get_char_card_info
__all__ = ["requests", "MihomoData"]

View File

@ -1,6 +1,6 @@
from __future__ import annotations
from typing import List, Optional, TypedDict
from typing import TypedDict
class MihomoData(TypedDict):
@ -15,12 +15,12 @@ class Behavior(TypedDict):
class Equipment(TypedDict):
level: int
tid: int
promotion: Optional[int]
rank: Optional[int]
promotion: int | None
rank: int | None
class Relic(TypedDict):
subAffixList: List[SubAffix]
subAffixList: list[SubAffix]
tid: int
mainAffixId: int
type: int
@ -33,20 +33,20 @@ class SubAffix(TypedDict):
class Avatar(TypedDict):
skillTreeList: List[Behavior]
rank: Optional[int]
pos: Optional[int]
skillTreeList: list[Behavior]
rank: int | None
pos: int | None
avatarId: int
level: int
equipment: Optional[Equipment]
relicList: List[Relic]
equipment: Equipment | None
relicList: list[Relic]
promotion: int
class Challenge(TypedDict):
scheduleMaxLevel: int
MazeGroupIndex: Optional[int]
PreMazeGroupIndex: Optional[int]
MazeGroupIndex: int | None
PreMazeGroupIndex: int | None
class PlayerSpaceInfo(TypedDict):
@ -61,13 +61,13 @@ class PlayerDetailInfo(TypedDict):
assistAvatarDetail: Avatar
platform: str
isDisplayAvatar: bool
avatarDetailList: Optional[List[Avatar]]
avatarDetailList: list[Avatar] | None
uid: int
friendCount: int
worldLevel: int
nickname: str
Birthday: Optional[int]
Birthday: int | None
level: int
recordInfo: Optional[PlayerSpaceInfo]
recordInfo: PlayerSpaceInfo | None
headIcon: int
signature: Optional[str]
signature: str | None

View File

@ -91,6 +91,8 @@ class RogueRecordInfo(TypedDict):
miracles: List[RogueMiracles]
difficulty: int
progress: int
detail_h: Optional[int]
start_h: Optional[int]
class RogueBasic(TypedDict):

View File

@ -1,8 +1,8 @@
import re
from gsuid_core.sv import SV
from gsuid_core.bot import Bot
from gsuid_core.models import Event
from gsuid_core.sv import SV
from gsuid_core.utils.error_reply import UID_HINT
from ..utils.convert import get_uid
@ -26,19 +26,22 @@ sv_srabyss = SV('sr查询深渊')
async def send_srabyss_info(bot: Bot, ev: Event):
name = ''.join(re.findall('[\u4e00-\u9fa5]', ev.text))
if name:
return
return None
await bot.logger.info('开始执行[sr查询深渊信息]')
uid, user_id = await get_uid(bot, ev, True)
get_uid_ = await get_uid(bot, ev, True)
if get_uid_ is None:
return await bot.send(UID_HINT)
uid, user_id = get_uid_
if uid is None:
return await bot.send(UID_HINT)
await bot.logger.info('[sr查询深渊信息]uid: {}'.format(uid))
await bot.logger.info(f'[sr查询深渊信息]uid: {uid}')
if 'sq' in ev.command or '上期' in ev.command:
schedule_type = '2'
else:
schedule_type = '1'
await bot.logger.info('[sr查询深渊信息]深渊期数: {}'.format(schedule_type))
await bot.logger.info(f'[sr查询深渊信息]深渊期数: {schedule_type}')
if ev.text in ['', '', '', '', '', '', '', '', '', '']:
floor = (
@ -60,9 +63,10 @@ async def send_srabyss_info(bot: Bot, ev: Event):
else:
floor = None
# print(floor)
await bot.logger.info('[sr查询深渊信息]深渊层数: {}'.format(floor))
await bot.logger.info(f'[sr查询深渊信息]深渊层数: {floor}')
# data = GsCookie()
# raw_abyss_data = await data.get_spiral_abyss_data(uid, schedule_type)
# print(raw_abyss_data)
im = await draw_abyss_img(user_id, uid, floor, schedule_type)
await bot.send(im)
return None

View File

@ -1,18 +1,17 @@
from pathlib import Path
from typing import Union, Optional
from typing import 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,
get_qq_avatar,
)
from .utils import get_icon
from ..utils.convert import GsCookie
from ..utils.image.convert import convert_img
from ..sruid_utils.api.mys.models import AbyssAvatar
from ..utils.convert import GsCookie
from ..utils.fonts.starrail_fonts import (
sr_font_22,
sr_font_28,
@ -20,6 +19,8 @@ from ..utils.fonts.starrail_fonts import (
sr_font_34,
sr_font_42,
)
from ..utils.image.convert import convert_img
from .utils import get_icon
abyss_list = {
'1': '琥珀恩赐其一',
@ -65,8 +66,7 @@ elements = {
async def get_abyss_star_pic(star: int) -> Image.Image:
star_pic = Image.open(TEXT_PATH / f'star{star}.png')
return star_pic
return Image.open(TEXT_PATH / f'star{star}.png')
async def _draw_abyss_card(
@ -239,9 +239,8 @@ async def draw_abyss_img(
index_floor = 0
else:
continue
else:
if index_floor >= 3:
break
elif index_floor >= 3:
break
floor_pic = Image.open(TEXT_PATH / 'floor_bg.png')
level_star = level['star_num']
floor_name = level['name']

View File

@ -1,8 +1,10 @@
from io import BytesIO
from pathlib import Path
from typing import TypeVar
from PIL import Image
from aiohttp import ClientSession
from PIL import Image
from gsuid_core.data_store import get_res_path
T = TypeVar("T")
@ -20,6 +22,6 @@ async def get_icon(url: str) -> Image.Image:
async with ClientSession() as client:
async with client.get(url) as resp:
content = await resp.read()
with open(path, "wb") as f:
with Path.open(path, "wb") as f:
f.write(content)
return Image.open(BytesIO(content)).convert("RGBA")

View File

@ -1,20 +1,22 @@
import re
from pathlib import Path
# import json
from typing import Tuple
from typing import Tuple, cast
from PIL import Image
from gsuid_core.sv import SV
from gsuid_core.bot import Bot
from gsuid_core.models import Event
from gsuid_core.sv import SV
from .to_card import api_to_card
from ..utils.convert import get_uid
from ..utils.sr_prefix import PREFIX
from ..utils.error_reply import UID_HINT
from ..utils.image.convert import convert_img
from .draw_char_img import draw_char_info_img
from ..utils.resource.RESOURCE_PATH import TEMP_PATH
from ..utils.sr_prefix import PREFIX
from .draw_char_img import draw_char_info_img
from .to_card import api_to_card
sv_char_info_config = SV('sr面板设置', pm=2)
sv_get_char_info = SV('sr面板查询', priority=10)
@ -28,13 +30,13 @@ async def send_char_info(bot: Bot, ev: Event):
await bot.send(im)
elif isinstance(im, Tuple):
if isinstance(im[0], Image.Image):
img = await convert_img(im[0])
img = await convert_img(cast(Image.Image, im[0]))
else:
img = im[0]
img = str(im[0])
await bot.send(img)
if im[1]:
with open(TEMP_PATH / f'{ev.msg_id}.jpg', 'wb') as f:
f.write(im[1])
with Path.open(TEMP_PATH / f'{ev.msg_id}.jpg', 'wb') as f:
f.write(cast(bytes, im[1]))
elif isinstance(im, Image.Image):
await bot.send(await convert_img(im))
elif isinstance(im, bytes):
@ -49,16 +51,15 @@ async def _get_char_info(bot: Bot, ev: Event, text: str):
# 获取角色名
msg = ''.join(re.findall('[\u4e00-\u9fa5 ]', text))
if not msg:
return
return None
await bot.logger.info('开始执行[查询角色面板]')
# 获取uid
uid = await get_uid(bot, ev)
if uid is None:
return await bot.send(UID_HINT)
await bot.logger.info('[查询角色面板]uid: {}'.format(uid))
await bot.logger.info(f'[查询角色面板]uid: {uid}')
im = await draw_char_info_img(msg, uid, ev.image)
return im
return await draw_char_info_img(msg, uid)
@sv_get_char_info.on_command(f'{PREFIX}强制刷新')
@ -66,7 +67,8 @@ async def send_card_info(bot: Bot, ev: Event):
uid = await get_uid(bot, ev)
if uid is None:
return await bot.send(UID_HINT)
await bot.logger.info('[sr强制刷新]uid: {}'.format(uid))
await bot.logger.info(f'[sr强制刷新]uid: {uid}')
im = await api_to_card(uid)
await bot.logger.info(f'UID{uid}获取角色数据成功')
await bot.logger.info(f'UID{uid}获取角色数据成功!')
await bot.send(im)
return None

View File

@ -1,34 +1,19 @@
import re
import json
import math
import re
from pathlib import Path
from typing import Dict, Union, Optional
from typing import Dict, Union
from mpmath import mp, nstr
from PIL import Image, ImageDraw
from gsuid_core.logger import logger
from gsuid_core.utils.image.convert import convert_img
from gsuid_core.utils.image.image_tools import draw_text_by_line
from .to_data import api_to_dict
from .mono.Character import Character
from ..utils.error_reply import CHAR_HINT
from ..utils.fonts.first_world import fw_font_28
from ..utils.excel.read_excel import light_cone_ranks
from ..utils.map.name_covert import name_to_avatar_id, alias_to_char_name
from ..utils.map.SR_MAP_PATH import (
RelicId2Rarity,
AvatarRelicScore,
avatarId2Name,
avatarId2DamageType,
)
from ..utils.resource.RESOURCE_PATH import (
RELIC_PATH,
SKILL_PATH,
PLAYER_PATH,
WEAPON_PATH,
CHAR_PORTRAIT_PATH,
)
from ..utils.fonts.first_world import fw_font_28
from ..utils.fonts.starrail_fonts import (
sr_font_20,
sr_font_23,
@ -38,6 +23,22 @@ from ..utils.fonts.starrail_fonts import (
sr_font_34,
sr_font_38,
)
from ..utils.map.name_covert import alias_to_char_name, name_to_avatar_id
from ..utils.map.SR_MAP_PATH import (
AvatarRelicScore,
RelicId2Rarity,
avatarId2DamageType,
avatarId2Name,
)
from ..utils.resource.RESOURCE_PATH import (
CHAR_PORTRAIT_PATH,
PLAYER_PATH,
RELIC_PATH,
SKILL_PATH,
WEAPON_PATH,
)
from .mono.Character import Character
from .to_data import api_to_dict
mp.dps = 14
@ -76,7 +77,7 @@ RELIC_POS = {
}
async def draw_char_info_img(raw_mes: str, sr_uid: str, url: Optional[str]):
async def draw_char_info_img(raw_mes: str, sr_uid: str):
# 获取角色名
char_name = ' '.join(re.findall('[\u4e00-\u9fa5]+', raw_mes))
@ -104,7 +105,7 @@ async def draw_char_info_img(raw_mes: str, sr_uid: str, url: Optional[str]):
(620, 207), char.char_name, (255, 255, 255), sr_font_38, 'lm'
)
if hasattr(sr_font_38, 'getsize'):
char_name_len = sr_font_38.getsize(char.char_name)[0]
char_name_len = sr_font_38.getsize(char.char_name)[0] # type: ignore
else:
bbox = sr_font_38.getbbox(char.char_name)
char_name_len = bbox[2] - bbox[0]
@ -112,7 +113,7 @@ async def draw_char_info_img(raw_mes: str, sr_uid: str, url: Optional[str]):
# 放等级
char_img_draw.text(
(620 + char_name_len + 50, 212),
f'LV.{str(char.char_level)}',
f'LV.{char.char_level!s}',
white_color,
sr_font_24,
'mm',
@ -156,7 +157,7 @@ async def draw_char_info_img(raw_mes: str, sr_uid: str, url: Optional[str]):
)
attr_bg_draw.text(
(428, 31),
f'(+{str(round(add_hp))})',
f'(+{round(add_hp)!s})',
(95, 251, 80),
sr_font_26,
anchor='lm',
@ -177,7 +178,7 @@ async def draw_char_info_img(raw_mes: str, sr_uid: str, url: Optional[str]):
)
attr_bg_draw.text(
(428, 31 + 48),
f'(+{str(round(add_attack))})',
f'(+{round(add_attack)!s})',
(95, 251, 80),
sr_font_26,
anchor='lm',
@ -198,7 +199,7 @@ async def draw_char_info_img(raw_mes: str, sr_uid: str, url: Optional[str]):
)
attr_bg_draw.text(
(428, 31 + 48 * 2),
f'(+{str(round(add_defence))})',
f'(+{round(add_defence)!s})',
(95, 251, 80),
sr_font_26,
anchor='lm',
@ -217,7 +218,7 @@ async def draw_char_info_img(raw_mes: str, sr_uid: str, url: Optional[str]):
)
attr_bg_draw.text(
(428, 31 + 48 * 3),
f'(+{str(round(add_speed))})',
f'(+{round(add_speed)!s})',
(95, 251, 80),
sr_font_26,
anchor='lm',
@ -351,7 +352,7 @@ async def draw_char_info_img(raw_mes: str, sr_uid: str, url: Optional[str]):
'lm',
)
if hasattr(sr_font_34, 'getsize'):
weapon_name_len = sr_font_34.getsize(
weapon_name_len = sr_font_34.getsize( # type: ignore
char.equipment["equipmentName"]
)[0]
else:
@ -387,11 +388,11 @@ async def draw_char_info_img(raw_mes: str, sr_uid: str, url: Optional[str]):
desc_params = light_cone_ranks[str(char.equipment['equipmentID'])][
'params'
][char.equipment['equipmentRank'] - 1]
for i in range(0, len(desc_params)):
for i in range(len(desc_params)):
temp = math.floor(desc_params[i] * 1000) / 10
desc = desc.replace(f'#{i + 1}[i]%', f'{str(temp)}%')
desc = desc.replace(f'#{i + 1}[f1]%', f'{str(temp)}%')
for i in range(0, len(desc_params)):
desc = desc.replace(f'#{i + 1}[i]%', f'{temp!s}%')
desc = desc.replace(f'#{i + 1}[f1]%', f'{temp!s}%')
for i in range(len(desc_params)):
desc = desc.replace(f'#{i + 1}[i]', str(desc_params[i]))
draw_text_by_line(
weapon_bg, (286, 115), desc, sr_font_24, '#F9F9F9', 372
@ -413,7 +414,6 @@ async def draw_char_info_img(raw_mes: str, sr_uid: str, url: Optional[str]):
relic_score = 0
for relic in char.char_relic:
print(relic)
rarity = RelicId2Rarity[str(relic["relicId"])]
relic_img = Image.open(TEXT_PATH / f'yq_bg{rarity}.png')
if str(relic["SetId"])[0] == '3':
@ -474,14 +474,14 @@ async def draw_char_info_img(raw_mes: str, sr_uid: str, url: Optional[str]):
)
relic_img_draw.text(
(35, 195),
'+{}'.format(mainValueStr),
f'+{mainValueStr}',
(255, 255, 255),
sr_font_28,
anchor='lm',
)
relic_img_draw.text(
(180, 105),
'+{}'.format(str(main_level)),
f'+{main_level!s}',
(255, 255, 255),
sr_font_23,
anchor='mm',
@ -505,7 +505,6 @@ async def draw_char_info_img(raw_mes: str, sr_uid: str, url: Optional[str]):
* 10
)
single_relic_score += add_value
print(f'main_value_score: {main_value_score}')
single_relic_score += main_value_score
for index, i in enumerate(relic['SubAffixList']):
subName: str = i['Name']
@ -520,28 +519,28 @@ async def draw_char_info_img(raw_mes: str, sr_uid: str, url: Optional[str]):
if subName in ['攻击力', '生命值', '防御力', '速度']:
subValueStr = nstr(subValue, 3)
else:
subValueStr = nstr(subValue * 100, 3) + '%'
subValueStr = nstr(subValue * 100, 3) + '%' # type: ignore
subNameStr = subName.replace('百分比', '').replace('元素', '')
# 副词条文字颜色
relic_color = (255, 255, 255)
relic_img_draw.text(
(47, 237 + index * 47),
'{}'.format(subNameStr),
f'{subNameStr}',
relic_color,
sr_font_26,
anchor='lm',
)
relic_img_draw.text(
(290, 237 + index * 47),
'{}'.format(subValueStr),
f'{subValueStr}',
relic_color,
sr_font_26,
anchor='rm',
)
relic_img_draw.text(
(210, 195),
'{}'.format(int(single_relic_score)),
f'{int(single_relic_score)}',
(255, 255, 255),
sr_font_28,
anchor='rm',
@ -551,7 +550,6 @@ async def draw_char_info_img(raw_mes: str, sr_uid: str, url: Optional[str]):
relic_img, RELIC_POS[str(relic["Type"])], relic_img
)
relic_score += single_relic_score
print(relic_score)
if relic_score > 200:
relic_value_level = Image.open(TEXT_PATH / 'CommonIconS.png')
char_info.paste(relic_value_level, (780, 963), relic_value_level)
@ -611,6 +609,7 @@ async def get_char_data(
return "请输入正确的角色名"
char_path = player_path / f'{char_name}.json'
char_self_path = SELF_PATH / f'{char_name}.json'
path = Path()
if char_path.exists():
path = char_path
elif enable_self and char_self_path.exists():
@ -620,10 +619,9 @@ async def get_char_data(
charname_list = []
if isinstance(char_data_list, str):
return char_data_list
else:
for char in char_data_list:
charname = avatarId2Name[str(char)]
charname_list.append(charname)
for char in char_data_list:
charname = avatarId2Name[str(char)]
charname_list.append(charname)
if str(char_name) in charname_list:
if char_path.exists():
path = char_path
@ -632,9 +630,8 @@ async def get_char_data(
else:
return CHAR_HINT.format(char_name, char_name)
with open(path, 'r', encoding='utf8') as fp:
char_data = json.load(fp)
return char_data
with Path.open(path, encoding='utf8') as fp:
return json.load(fp)
async def get_relic_score(
@ -697,5 +694,4 @@ async def get_relic_score(
(subValue + 1) * 1.49 * weight_dict['StatusResistanceBase'] * 10
)
relic_score += add_value
print(f'{subProperty} : {relic_score}')
return relic_score

View File

@ -1,10 +1,11 @@
import json
from typing import Dict
from collections import Counter
from typing import Dict
from loguru import logger
from mpmath import mp
from ...utils.map.SR_MAP_PATH import RelicSetSkill, EquipmentID2AbilityProperty
from ...utils.map.SR_MAP_PATH import EquipmentID2AbilityProperty, RelicSetSkill
mp.dps = 14
@ -50,36 +51,35 @@ class Character:
async def get_equipment_info(self):
if self.equipment == {}:
return
else:
base_attr = self.base_attributes
equip = self.equipment
ability_property = EquipmentID2AbilityProperty[
str(equip['equipmentID'])
]
equip_rank = equip['equipmentRank']
base_attr = self.base_attributes
equip = self.equipment
ability_property = EquipmentID2AbilityProperty[
str(equip['equipmentID'])
]
equip_rank = equip['equipmentRank']
equip_ability_property = ability_property[str(equip_rank)]
equip_ability_property = ability_property[str(equip_rank)]
equip_add_base_attr = equip['baseAttributes']
hp = mp.mpf(base_attr['hp']) + mp.mpf(equip_add_base_attr['hp'])
attack = mp.mpf(base_attr['attack']) + mp.mpf(
equip_add_base_attr['attack']
)
defence = mp.mpf(base_attr['defence']) + mp.mpf(
equip_add_base_attr['defence']
)
base_attr['hp'] = str(hp)
base_attr['attack'] = str(attack)
base_attr['defence'] = str(defence)
self.base_attributes = base_attr
equip_add_base_attr = equip['baseAttributes']
hp = mp.mpf(base_attr['hp']) + mp.mpf(equip_add_base_attr['hp'])
attack = mp.mpf(base_attr['attack']) + mp.mpf(
equip_add_base_attr['attack']
)
defence = mp.mpf(base_attr['defence']) + mp.mpf(
equip_add_base_attr['defence']
)
base_attr['hp'] = str(hp)
base_attr['attack'] = str(attack)
base_attr['defence'] = str(defence)
self.base_attributes = base_attr
for equip_ability in equip_ability_property:
property_type = equip_ability['PropertyType']
value = equip_ability['Value']['Value']
if property_type in self.add_attr:
self.add_attr[property_type] += value
else:
self.add_attr[property_type] = value
for equip_ability in equip_ability_property:
property_type = equip_ability['PropertyType']
value = equip_ability['Value']['Value']
if property_type in self.add_attr:
self.add_attr[property_type] += value
else:
self.add_attr[property_type] = value
async def get_char_attribute_bonus(self):
attribute_bonus = self.attribute_bonus
@ -122,6 +122,7 @@ class Character:
set_property = ''
set_id = item[0]
count = item[1]
set_value = 0
if count >= 2 and RelicSetSkill[str(set_id)]['2'] != {}:
set_property = RelicSetSkill[str(set_id)]['2']['Property']
set_value = mp.mpf(RelicSetSkill[str(set_id)]['2']['Value'])
@ -136,5 +137,5 @@ class Character:
else:
self.add_attr[set_property] = str(set_value)
print(json.dumps(self.base_attributes))
print(json.dumps(self.add_attr))
logger.info(json.dumps(self.base_attributes))
logger.info(json.dumps(self.add_attr))

View File

@ -1,17 +1,16 @@
import asyncio
from pathlib import Path
from typing import List, Union, Optional
from typing import List, Union
from PIL import Image, ImageDraw
from gsuid_core.utils.api.enka.models import EnkaData
from .to_data import api_to_dict
from ..utils.image.convert import convert_img
from ..utils.fonts.first_world import fw_font_28
from ..utils.map.SR_MAP_PATH import avatarId2Name
from ..utils.map.name_covert import avatar_id_to_char_star
from ..utils.fonts.starrail_fonts import sr_font_24, sr_font_30, sr_font_58
from ..utils.image.convert import convert_img
from ..utils.map.name_covert import avatar_id_to_char_star
from ..utils.map.SR_MAP_PATH import avatarId2Name
from ..utils.resource.RESOURCE_PATH import CHAR_ICON_PATH, CHAR_PREVIEW_PATH
from .to_data import api_to_dict
half_color = (255, 255, 255, 120)
first_color = (29, 29, 29)
@ -28,11 +27,8 @@ footbar = Image.open(TEXT_PATH / 'footbar.png')
pic_500 = Image.open(TEXT_PATH / '500.png')
async def api_to_card(
uid: str, enka_data: Optional[EnkaData] = None
) -> Union[str, bytes]:
char_data_list = await api_to_dict(uid, enka_data)
print(char_data_list)
async def api_to_card(uid: str) -> Union[str, bytes]:
char_data_list = await api_to_dict(uid)
if (
not isinstance(char_data_list, str)
and char_data_list == []
@ -44,7 +40,7 @@ async def api_to_card(
async def draw_enka_card(
uid: str, char_list: Optional[List] = None, showfrom: int = 0
uid: str, char_list: List, showfrom: int = 0
):
char_data_list = []
if 1102 in char_list:
@ -108,8 +104,7 @@ async def draw_enka_card(
else:
tasks.append(draw_mihomo_char(index, img, char_data))
await asyncio.gather(*tasks)
img = await convert_img(img)
return img
return await convert_img(img)
async def draw_mihomo_char(index: int, img: Image.Image, char_data: dict):

View File

@ -1,34 +1,39 @@
import json
from typing import List, Union, Optional
from pathlib import Path
from typing import List, Optional, Union
from mpmath import mp
from httpx import ReadTimeout
from mpmath import mp
from gsuid_core.plugins.StarRailUID.StarRailUID.sruid_utils.api.mihomo.models import (
Avatar,
)
from ..utils.error_reply import UID_HINT
from ..sruid_utils.api.mihomo import MihomoData
from ..utils.resource.RESOURCE_PATH import PLAYER_PATH
from ..sruid_utils.api.mihomo.requests import get_char_card_info
# from gsuid_core.utils.api.minigg.request import get_weapon_info
from .cal_value import cal_relic_sub_affix, cal_relic_main_affix
from ..utils.error_reply import UID_HINT
from ..utils.excel.read_excel import AvatarPromotion, EquipmentPromotion
from ..utils.map.SR_MAP_PATH import (
SetId2Name,
EquipmentID2Name,
EquipmentID2Rarity,
ItemId2Name,
Property2Name,
RelicId2SetId,
EquipmentID2Name,
EquipmentID2Rarity,
rankId2Name,
skillId2Name,
avatarId2Name,
skillId2Effect,
SetId2Name,
avatarId2DamageType,
avatarId2EnName,
avatarId2Name,
avatarId2Rarity,
characterSkillTree,
rankId2Name,
skillId2AttackType,
avatarId2DamageType,
skillId2Effect,
skillId2Name,
)
from ..utils.resource.RESOURCE_PATH import PLAYER_PATH
# from gsuid_core.utils.api.minigg.request import get_weapon_info
from .cal_value import cal_relic_main_affix, cal_relic_sub_affix
mp.dps = 14
@ -55,25 +60,23 @@ async def api_to_dict(
if isinstance(sr_data, str):
return []
if isinstance(sr_data, dict):
print(sr_data)
if 'detailInfo' not in sr_data:
im = '服务器正在维护或者关闭中...\n检查Mihomo.me是否可以访问\n如可以访问,尝试上报Bug!'
return im
return '服务器正在维护或者关闭中...\n检查Mihomo.me是否可以访问\n如可以访问,尝试上报Bug!'
elif sr_data is None:
return []
PlayerDetailInfo = sr_data['detailInfo']
path = PLAYER_PATH / str(sr_uid)
path.mkdir(parents=True, exist_ok=True)
with open(
path / '{}.json'.format(str(sr_uid)), 'w', encoding='UTF-8'
with Path.open(
path / f'{sr_uid!s}.json', 'w', encoding='UTF-8'
) as file:
json.dump(PlayerDetailInfo, file, ensure_ascii=False)
with open(path / 'rawData.json', 'w', encoding='UTF-8') as file:
with Path.open(path / 'rawData.json', 'w', encoding='UTF-8') as file:
json.dump(sr_data, file, ensure_ascii=False)
if 'detailInfo' not in sr_data:
return f'SR_UID{sr_uid}刷新失败未打开角色展柜!'
return f'SR_UID{sr_uid}刷新失败!未打开角色展柜!'
char_name_list = []
char_id_list = []
@ -93,21 +96,21 @@ async def api_to_dict(
)
if PlayerDetailInfo.get('avatarDetailList'):
im += '星海同行'
for char in PlayerDetailInfo['avatarDetailList']:
if char['avatarId'] not in char_id_list:
char_dict, avatarName = await get_data(char, sr_data, sr_uid)
im += f' {avatarName}'
char_name_list.append(avatarName)
char_id_list.append(char['avatarId'])
if PlayerDetailInfo['avatarDetailList'] is not None:
for char in PlayerDetailInfo['avatarDetailList']:
if char['avatarId'] not in char_id_list:
_, avatarName = await get_data(char, sr_data, sr_uid)
im += f' {avatarName}'
char_name_list.append(avatarName)
char_id_list.append(char['avatarId'])
if not char_name_list:
im = f'UID: {sr_uid} 的角色展柜刷新失败!\n请检查UID是否正确或者角色展柜是否打开'
return im
return f'UID: {sr_uid} 的角色展柜刷新失败!\n请检查UID是否正确或者角色展柜是否打开!'
return char_id_list
async def get_data(char: dict, sr_data: dict, sr_uid: str):
async def get_data(char: Avatar, sr_data: MihomoData, sr_uid: str):
PlayerDetailInfo = sr_data['detailInfo']
path = PLAYER_PATH / str(sr_uid)
# 处理基本信息
@ -219,10 +222,10 @@ async def get_data(char: dict, sr_data: dict, sr_uid: str):
if relic.get('subAffixList'):
for sub_affix in relic['subAffixList']:
sub_affix_temp = {}
sub_affix_temp['SubAffixID'] = sub_affix['affixId']
sub_affix_temp['SubAffixID'] = sub_affix['affixID']
sub_affix_property, value = await cal_relic_sub_affix(
relic_id=relic['tid'],
affix_id=sub_affix['affixId'],
affix_id=sub_affix['affixID'],
cnt=sub_affix['cnt'],
step=sub_affix['step'] if 'step' in sub_affix else 0,
)
@ -238,7 +241,7 @@ async def get_data(char: dict, sr_data: dict, sr_uid: str):
# 处理命座
rank_temp = []
if 'rank' in char:
if char.get('rank') and char['rank'] is not None:
char_data['rank'] = char['rank']
for index in range(char['rank']):
rankTemp = {}
@ -293,7 +296,7 @@ async def get_data(char: dict, sr_data: dict, sr_uid: str):
# 处理武器
equipment_info = {}
if char.get('equipment'):
if char.get('equipment') and char['equipment'] is not None:
equipment_info['equipmentID'] = char['equipment']['tid']
equipment_info['equipmentName'] = EquipmentID2Name[
str(char['equipment']['tid'])
@ -334,8 +337,8 @@ async def get_data(char: dict, sr_data: dict, sr_uid: str):
char_data['equipmentInfo'] = equipment_info
with open(
path / '{}.json'.format(avatarName), 'w', encoding='UTF-8'
with Path.open(
path / f'{avatarName}.json', 'w', encoding='UTF-8'
) as file:
json.dump(char_data, file, ensure_ascii=False)
return char_data, avatarName
@ -352,4 +355,4 @@ async def api_to_data(
for char_data in raw_data:
char_name_list.append(char_data['avatarName'])
char_name_list_str = ','.join(char_name_list)
return f'UID{uid}刷新完成\n本次缓存:{char_name_list_str}'
return f'UID{uid}刷新完成!\n本次缓存:{char_name_list_str}'

View File

@ -8,7 +8,7 @@ from gsuid_core.utils.plugins_config.models import (
)
CONIFG_DEFAULT: Dict[str, GSC] = {
'SignTime': GsListStrConfig('每晚签到时间设置', '每晚米游社签到时间设置(时,分)', ['0', '38']),
'SignTime': GsListStrConfig('每晚签到时间设置', '每晚米游社签到时间设置(时,分)', ['0', '38']),
'SignReportSimple': GsBoolConfig(
'简洁签到报告',
'开启后可以大大减少每日签到报告字数',

View File

@ -1,14 +1,14 @@
import re
from gsuid_core.sv import SV
from gsuid_core.bot import Bot
from gsuid_core.models import Event
from gsuid_core.sv import SV
from .cal_damage import cal
from ..utils.convert import get_uid
from ..utils.sr_prefix import PREFIX
from ..utils.error_reply import UID_HINT
from ..starrailuid_charinfo.draw_char_img import get_char_data
from ..utils.convert import get_uid
from ..utils.error_reply import UID_HINT
from ..utils.sr_prefix import PREFIX
from .cal_damage import cal
sv_char_damage_cal = SV('sr伤害计算')
@ -17,16 +17,19 @@ sv_char_damage_cal = SV('sr伤害计算')
async def send_damage_msg(bot: Bot, ev: Event):
msg = ''.join(re.findall('[\u4e00-\u9fa5 ]', ev.text))
if not msg:
return
return None
await bot.logger.info('开始执行[角色伤害计算]')
# 获取uid
sr_uid = await get_uid(bot, ev)
if sr_uid is None:
return await bot.send(UID_HINT)
await bot.logger.info('[角色伤害计算]uid: {}'.format(sr_uid))
await bot.logger.info(f'[角色伤害计算]uid: {sr_uid}')
char_name = ' '.join(re.findall('[\u4e00-\u9fa5]+', msg))
char_data = await get_char_data(sr_uid, char_name)
if isinstance(char_data, str):
return await bot.send(char_data)
im = await cal(char_data)
await bot.send(im)
return None

View File

@ -2,9 +2,9 @@ from typing import Dict
from mpmath import mp
from .effect.Role import RoleInstance
from ..starrailuid_charinfo.mono.Character import Character
from ..starrailuid_charinfo.draw_char_img import cal_char_info
from ..starrailuid_charinfo.mono.Character import Character
from .effect.Role import RoleInstance
mp.dps = 14
@ -34,7 +34,6 @@ async def cal(char_data: Dict):
for skill_type in ['Normal', 'BPSkill', 'Ultra']:
role = RoleInstance(raw_data)
print(role)
im_tmp = await role.cal_damage(skill_type)
im.append(im_tmp)
return im

View File

@ -34,7 +34,8 @@ class Seele(BaseAvatar):
] = mp.mpf(0.2)
class Avatar:
def __new__(cls, char: Dict, skills: List):
class Avatar(Seele):
def __init__(self, char: Dict, skills: List):
if char['id'] == 1102:
return Seele(char, skills)
return None

View File

@ -1,15 +1,15 @@
import json
from abc import abstractmethod
from pathlib import Path
from typing import Dict, List
from abc import abstractmethod
from mpmath import mp
from .SkillBase import BaseSkills
from ....utils.excel.read_excel import AvatarPromotion
from .SkillBase import BaseSkills
path = Path(__file__).parent.parent
with open(path / 'Excel' / 'seele.json', 'r', encoding='utf-8') as f:
with Path.open(path / 'Excel' / 'seele.json', encoding='utf-8') as f:
skill_dict = json.load(f)
mp.dps = 14

View File

@ -8,7 +8,7 @@ mp.dps = 14
path = Path(__file__).parent.parent
with open(path / 'Excel' / 'seele.json', 'r', encoding='utf-8') as f:
with Path.open(path / 'Excel' / 'seele.json', encoding='utf-8') as f:
skill_dict = json.load(f)

View File

@ -1,11 +1,12 @@
from typing import Dict, List
from collections import Counter
from typing import Dict, List
from mpmath import mp
from gsuid_core.logger import logger
from ..Base.RelicBase import BaseRelicSetSkill, SingleRelic
from ..utils import merge_attribute
from ..Base.RelicBase import SingleRelic, BaseRelicSetSkill
class Relic101(BaseRelicSetSkill):
@ -48,7 +49,7 @@ class Relic103(BaseRelicSetSkill):
async def check(self, base_attr: Dict, attribute_bonus: Dict):
'''
战斗中生效装备者提供的护盾量提高
战斗中生效:装备者提供的护盾量提高
'''
logger.info('Relic103 check success')
return True
@ -267,6 +268,7 @@ class Relic301(BaseRelicSetSkill):
if merged_attr['speed'] >= mp.mpf(120):
logger.info('Relic306 check success')
return True
return None
async def set_skill_ability(self, base_attr: Dict, attribute_bonus: Dict):
if self.pieces2 and await self.check(base_attr, attribute_bonus):
@ -289,6 +291,7 @@ class Relic302(BaseRelicSetSkill):
if merged_attr['speed'] >= mp.mpf(120):
logger.info('Relic306 check success')
return True
return None
async def set_skill_ability(self, base_attr: Dict, attribute_bonus: Dict):
if self.pieces2 and await self.check(base_attr, attribute_bonus):
@ -312,7 +315,7 @@ class Relic303(BaseRelicSetSkill):
attack_added_ratio = attribute_bonus.get('AttackAddedRatio', 0)
merged_attr = await merge_attribute(base_attr, attribute_bonus)
status_probability = merged_attr.get('StatusProbability', 0)
# 提高装备者等同于当前效果命中25%的攻击力最多提高25%
# 提高装备者等同于当前效果命中25%的攻击力,最多提高25%
attribute_bonus['AttackAddedRatio'] = attack_added_ratio + min(
mp.mpf(0.25000000023283064), status_probability / mp.mpf(0.25)
)
@ -331,6 +334,7 @@ class Relic304(BaseRelicSetSkill):
if merged_attr['StatusProbability'] >= mp.mpf(0.5000000004656613):
logger.info('Relic306 check success')
return True
return None
async def set_skill_ability(self, base_attr: Dict, attribute_bonus: Dict):
if self.pieces2 and await self.check(base_attr, attribute_bonus):
@ -353,6 +357,7 @@ class Relic305(BaseRelicSetSkill):
if merged_attr['CriticalDamageBase'] >= mp.mpf(1.2000000001862645):
logger.info('Relic306 check success')
return True
return None
async def set_skill_ability(self, base_attr: Dict, attribute_bonus: Dict):
if self.pieces2 and await self.check(base_attr, attribute_bonus):
@ -375,6 +380,7 @@ class Relic306(BaseRelicSetSkill):
if merged_attr['CriticalChanceBase'] >= mp.mpf(0.5):
logger.info('Relic306 check success')
return True
return None
async def set_skill_ability(self, base_attr: Dict, attribute_bonus: Dict):
if self.pieces2 and await self.check(base_attr, attribute_bonus):
@ -399,6 +405,7 @@ class Relic307(BaseRelicSetSkill):
if merged_attr['speed'] >= mp.mpf(145):
logger.info('Relic306 check success')
return True
return None
async def set_skill_ability(self, base_attr: Dict, attribute_bonus: Dict):
if self.pieces2 and await self.check(base_attr, attribute_bonus):
@ -423,6 +430,7 @@ class Relic308(BaseRelicSetSkill):
if merged_attr['speed'] >= mp.mpf(120):
logger.info('Relic306 check success')
return True
return None
async def set_skill_ability(self, base_attr: Dict, attribute_bonus: Dict):
if self.pieces2 and await self.check(base_attr, attribute_bonus):
@ -519,4 +527,4 @@ class RelicSet:
elif set_id == 308:
self.SetSkill.append(Relic308(set_id, count))
else:
raise Exception('Unknow SetId: {}'.format(set_id))
raise Exception(f'Unknow SetId: {set_id}')

View File

@ -1,12 +1,13 @@
from typing import Dict
from mpmath import mp
from gsuid_core.logger import logger
from .Avatar.Avatar import Avatar
from .Weapon.Weapon import Weapon
from .utils import merge_attribute
from .Relic.Relic import RelicSet, SingleRelic
from .utils import merge_attribute
from .Weapon.Weapon import Weapon
mp.dps = 14
@ -29,9 +30,9 @@ class RoleInstance:
self.cal_weapon_attr_add()
def cal_role_base_attr(self):
print('cal_role_base_attr')
logger.info('cal_role_base_attr')
avatar_attribute = self.avatar.__dict__['avatar_attribute']
print(avatar_attribute)
logger.info(avatar_attribute)
for attribute in avatar_attribute:
if attribute in self.base_attr:
self.base_attr[attribute] += avatar_attribute[attribute]
@ -115,8 +116,8 @@ class RoleInstance:
]
async def cal_damage(self, skill_type):
print(self.base_attr)
print(self.attribute_bonus)
logger.info(self.base_attr)
logger.info(self.attribute_bonus)
# 检查武器战斗生效的buff
logger.info('检查武器战斗生效的buff')
self.attribute_bonus = await self.weapon.weapon_ability(
@ -127,12 +128,12 @@ class RoleInstance:
self.attribute_bonus = await set_skill.set_skill_ability(
self.base_attr, self.attribute_bonus
)
print('merge_attribute')
print(self.base_attr)
logger.info('merge_attribute')
logger.info(self.base_attr)
merged_attr = await merge_attribute(
self.base_attr, self.attribute_bonus
)
print(merged_attr)
logger.info(merged_attr)
attack = merged_attr['attack']
logger.info(f'攻击力: {attack}')
# 模拟 同属性弱点 同等级 的怪物
@ -176,7 +177,7 @@ class RoleInstance:
logger.info(f'技能区: {skill_multiplier}')
# 增伤区
# TODO: 这里计算只考虑了希儿需要重写 injury_area = self.avatar.Talent()
# TODO: 这里计算只考虑了希儿,需要重写 injury_area = self.avatar.Talent()
injury_area = self.avatar.Talent()
# 检查是否有对某一个技能的伤害加成
logger.info('检查是否有对某一个技能的伤害加成')

View File

@ -1,13 +1,13 @@
import json
from typing import Dict
from pathlib import Path
from typing import Dict
from mpmath import mp
from ..Base.WeaponBase import BaseWeapon
path = Path(__file__).parent.parent
with open(path / 'Excel' / 'weapon_effect.json', 'r', encoding='utf-8') as f:
with Path.open(path / 'Excel' / 'weapon_effect.json', encoding='utf-8') as f:
weapon_effect = json.load(f)
@ -106,6 +106,7 @@ class Adversarial(BaseWeapon):
]
)
return attribute_bonus
return None
class SubscribeforMore(BaseWeapon):
@ -137,6 +138,7 @@ class SubscribeforMore(BaseWeapon):
* 2
)
return attribute_bonus
return None
class RiverFlowsinSpring(BaseWeapon):
@ -144,8 +146,8 @@ class RiverFlowsinSpring(BaseWeapon):
super().__init__(weapon)
async def check(self):
# 进入战斗后使装备者速度提高8%造成的伤害提高12%。
# 当装备者受到伤害后该效果失效下个回合结束时该效果恢复。
# 进入战斗后,使装备者速度提高8%,造成的伤害提高12%。
# 当装备者受到伤害后该效果失效,下个回合结束时该效果恢复。
return True
async def weapon_ability(self, base_attr: Dict, attribute_bonus: Dict):
@ -167,6 +169,7 @@ class RiverFlowsinSpring(BaseWeapon):
]
)
return attribute_bonus
return None
class SleepLiketheDead(BaseWeapon):
@ -174,13 +177,14 @@ class SleepLiketheDead(BaseWeapon):
super().__init__(weapon)
async def check(self):
# 当装备者的普攻或战技伤害未造成暴击时使自身暴击率提高36%持续1回合。
# 当装备者的普攻或战技伤害未造成暴击时,使自身暴击率提高36%,持续1回合。
# 该效果每3回合可以触发1次。
return True
async def weapon_ability(self, base_attr: Dict, attribute_bonus: Dict):
if await self.check():
return attribute_bonus
return None
class OnlySilenceRemains(BaseWeapon):
@ -202,6 +206,7 @@ class OnlySilenceRemains(BaseWeapon):
]
)
return attribute_bonus
return None
class IntheNight(BaseWeapon):
@ -273,35 +278,38 @@ class CruisingintheStellarSea(BaseWeapon):
return attribute_bonus
class HuntWeapon:
def __new__(cls, weapon: Dict):
class HuntWeapon(
CruisingintheStellarSea, IntheNight, OnlySilenceRemains, SleepLiketheDead,
SubscribeforMore, Swordplay, DartingArrow, Adversarial,
RiverFlowsinSpring, Arrows, ReturntoDarkness
):
def __init__(self, weapon: Dict):
if weapon['id'] == 24001:
return CruisingintheStellarSea(weapon)
elif weapon['id'] == 23001:
if weapon['id'] == 23001:
return IntheNight(weapon)
elif weapon['id'] == 21003:
if weapon['id'] == 21003:
return OnlySilenceRemains(weapon)
elif weapon['id'] == 21024:
if weapon['id'] == 21024:
return RiverFlowsinSpring(weapon)
elif weapon['id'] == 20014:
if weapon['id'] == 20014:
return Adversarial(weapon)
elif weapon['id'] == 20007:
if weapon['id'] == 20007:
return DartingArrow(weapon)
elif weapon['id'] == 21010:
if weapon['id'] == 21010:
return Swordplay(weapon)
elif weapon['id'] == 21031:
if weapon['id'] == 21031:
return ReturntoDarkness(weapon)
elif weapon['id'] == 20000:
if weapon['id'] == 20000:
return Arrows(weapon)
else:
raise ValueError(f'未知武器id: {weapon["id"]}')
raise ValueError(f'未知武器id: {weapon["id"]}')
async def check_ability(self):
pass
class Weapon:
def __new__(cls, weapon: Dict):
class Weapon(HuntWeapon):
def __init__(self, weapon: Dict):
if weapon['id'] in [
23001,
21003,

View File

@ -1,28 +1,32 @@
from gsuid_core.sv import SV
from gsuid_core.bot import Bot
from gsuid_core.models import Event
from gsuid_core.sv import SV
from ..utils.convert import get_uid
from ..utils.sr_prefix import PREFIX
from ..utils.error_reply import UID_HINT
from .get_gachalogs import save_gachalogs
from ..utils.sr_prefix import PREFIX
from .draw_gachalogs import draw_gachalogs_img
from .get_gachalogs import save_gachalogs
sv_gacha_log = SV('sr抽卡记录')
sv_get_gachalog_by_link = SV('sr导入抽卡链接', area='DIRECT')
@sv_gacha_log.on_fullmatch((f'{PREFIX}抽卡记录'))
@sv_gacha_log.on_fullmatch(f'{PREFIX}抽卡记录')
async def send_gacha_log_card_info(bot: Bot, ev: Event):
await bot.logger.info('开始执行[sr抽卡记录]')
uid, user_id = await get_uid(bot, ev, True)
get_uid_ = await get_uid(bot, ev, True, False)
if get_uid_ is None:
return await bot.send(UID_HINT)
uid, user_id = get_uid_
if uid is None:
return await bot.send(UID_HINT)
im = await draw_gachalogs_img(uid, user_id)
await bot.send(im)
return None
@sv_get_gachalog_by_link.on_command((f'{PREFIX}导入抽卡链接'))
@sv_get_gachalog_by_link.on_command(f'{PREFIX}导入抽卡链接')
async def get_gachalog_by_link(bot: Bot, ev: Event):
await bot.logger.info('开始执行[sr导入抽卡链接]')
uid = await get_uid(bot, ev, only_uid=True)
@ -35,6 +39,6 @@ async def get_gachalog_by_link(bot: Bot, ev: Event):
if ev.command.startswith('强制'):
await bot.logger.info('[WARNING]本次为强制刷新')
is_force = True
await bot.send(f'UID{uid}开始执行[刷新抽卡记录],需要一定时间...请勿重复触发')
await bot.send(f'UID{uid}开始执行[刷新抽卡记录],需要一定时间...请勿重复触发!')
im = await save_gachalogs(uid, gacha_url, None, is_force)
return await bot.send(im)

View File

@ -4,13 +4,14 @@ import json
from pathlib import Path
from typing import List, Tuple, Union
from PIL import Image, ImageDraw
from gsuid_core.logger import logger
from gsuid_core.utils.image.image_tools import (
draw_pic_with_ring,
get_color_bg,
get_qq_avatar,
)
from PIL import Image, ImageDraw
from ..utils.fonts.starrail_fonts import (
sr_font_20,
@ -75,7 +76,7 @@ UP_LIST = {
async def _draw_card(
img: Image.Image,
xy_point: Tuple[int, int],
type: str,
card_type: str,
name: str,
gacha_num: int,
is_up: bool,
@ -84,7 +85,7 @@ async def _draw_card(
card_img_draw = ImageDraw.Draw(card_img)
point = (47, 31)
text_point = (100, 165)
if type == '角色':
if card_type == '角色':
_id = await name_to_avatar_id(name)
item_pic = (
Image.open(CHAR_ICON_PATH / f'{_id}.png')
@ -111,7 +112,7 @@ async def _draw_card(
text_point, f'{gacha_num}', text_color, sr_font_24, 'mm'
)
if is_up:
print(f'up: {name}')
logger.info(f'up: {name}')
# card_img.paste(up_tag, (47, -2), up_tag)
img.paste(card_img, xy_point, card_img)
@ -143,17 +144,15 @@ def check_up(name: str, _time: str) -> bool:
gacha_time = datetime.datetime.strptime(_time, '%Y-%m-%d %H:%M:%S')
if gacha_time < s_time or gacha_time > e_time:
return False
else:
return True
else:
return False
return True
return False
async def draw_gachalogs_img(uid: str, user_id: str) -> Union[bytes, str]:
path = PLAYER_PATH / str(uid) / 'gacha_logs.json'
if not path.exists():
return '你还没有跃迁数据噢~\n请使用命令`sr导入抽卡链接`更新跃迁数据~'
with open(path, 'r', encoding='UTF-8') as f:
with Path.open(path, encoding='UTF-8') as f:
gacha_data = json.load(f)
# 数据初始化
@ -339,7 +338,7 @@ async def draw_gachalogs_img(uid: str, user_id: str) -> Union[bytes, str]:
# 处理title
# {'total': 0, 'avg': 0, 'remain': 0, 'list': []}
type_list = ['角色跃迁', '光锥跃迁''群星跃迁', '始发跃迁']
type_list = ['角色跃迁', '光锥跃迁', '群星跃迁', '始发跃迁']
y_extend = 0
level = 3
for index, i in enumerate(type_list):
@ -352,15 +351,14 @@ async def draw_gachalogs_img(uid: str, user_id: str) -> Union[bytes, str]:
level = await get_level_from_list(
total_data[i]['avg'], [10, 20, 30, 40, 50]
)
elif i == '光锥跃迁':
level = await get_level_from_list(
total_data[i]['avg_up'], [62, 75, 88, 99, 111]
)
else:
if i == '光锥跃迁':
level = await get_level_from_list(
total_data[i]['avg_up'], [62, 75, 88, 99, 111]
)
else:
level = await get_level_from_list(
total_data[i]['avg_up'], [74, 87, 99, 105, 120]
)
level = await get_level_from_list(
total_data[i]['avg_up'], [74, 87, 99, 105, 120]
)
emo_pic = await random_emo_pic(level)
emo_pic = emo_pic.resize((195, 195))

View File

@ -1,8 +1,9 @@
import json
import asyncio
from urllib import parse
import json
from datetime import datetime
from pathlib import Path
from typing import Dict, Optional
from urllib import parse
from ..utils.mys_api import mys_api
from ..utils.resource.RESOURCE_PATH import PLAYER_PATH
@ -86,7 +87,7 @@ async def save_gachalogs(
old_weapon_gacha_num,
) = (0, 0, 0, 0)
if gachalogs_path.exists():
with open(gachalogs_path, "r", encoding='UTF-8') as f:
with Path.open(gachalogs_path, encoding='UTF-8') as f:
gachalogs_history: Dict = json.load(f)
gachalogs_history = gachalogs_history['data']
old_normal_gacha_num = len(gachalogs_history['群星跃迁'])
@ -149,7 +150,7 @@ async def save_gachalogs(
all_add = normal_add + char_add + weapon_add + begin_gacha_add
# 保存文件
with open(gachalogs_path, 'w', encoding='UTF-8') as file:
with Path.open(gachalogs_path, 'w', encoding='UTF-8') as file:
json.dump(result, file, ensure_ascii=False)
# 回复文字
@ -157,9 +158,9 @@ async def save_gachalogs(
im = f'UID{uid}没有新增祈愿数据!'
else:
im = (
f'UID{uid}数据更新成功'
f'UID{uid}数据更新成功!'
f'本次更新{all_add}个数据\n'
f'群星跃迁{normal_add}\n始发跃迁{begin_gacha_add}\n'
f'角色跃迁{char_add}\n光锥跃迁{weapon_add}'
f'角色跃迁{char_add}\n光锥跃迁{weapon_add}!'
)
return im

View File

@ -9,7 +9,7 @@ from ..utils.sr_prefix import PREFIX
sv_sr_help = SV('sr帮助')
@sv_sr_help.on_fullmatch((f'{PREFIX}帮助'))
@sv_sr_help.on_fullmatch(f'{PREFIX}帮助')
async def send_help_img(bot: Bot, ev: Event):
logger.info('开始执行[sr帮助]')
im = await get_core_help()

View File

@ -20,6 +20,7 @@ async def get_help_data() -> Optional[Dict[str, PluginHelp]]:
return msgjson.decode(
await file.read(), type=Dict[str, PluginHelp]
)
return None
async def get_core_help() -> Union[bytes, str]:
@ -27,9 +28,9 @@ async def get_core_help() -> Union[bytes, str]:
if help_data is None:
return '暂未找到帮助数据...'
img = await get_help(
return await get_help(
'StarRailUID',
f'版本号{StarRail_version}',
f'版本号:{StarRail_version}',
help_data,
Image.open(TEXT_PATH / 'bg.jpg'),
Image.open(TEXT_PATH / 'ICON.png'),
@ -38,4 +39,3 @@ async def get_core_help() -> Union[bytes, str]:
Image.open(TEXT_PATH / 'button.png'),
starrail_font_origin,
)
return img

View File

@ -13,13 +13,14 @@ 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):
sqla = get_sqla(ev.bot_id)
sr_uid = await sqla.get_bind_sruid(ev.user_id)
if sr_uid is None:
return UID_HINT
await bot.send(await award(sr_uid))
return None
@sv_get_monthly_data.on_fullmatch(
@ -32,3 +33,4 @@ async def send_monthly_pic(bot: Bot, ev: Event):
return UID_HINT
im = await draw_note_img(str(sr_uid))
await bot.send(im)
return None

View File

@ -1,16 +1,17 @@
import json
from datetime import datetime
from pathlib import Path
from typing import Union
from datetime import datetime
from PIL import Image, ImageDraw
from gsuid_core.logger import logger
from ..utils.mys_api import mys_api
from ..utils.error_reply import get_error
from ..utils.image.convert import convert_img
from ..utils.resource.RESOURCE_PATH import PLAYER_PATH
from ..utils.fonts.starrail_fonts import sr_font_20, sr_font_28, sr_font_34
from ..utils.image.convert import convert_img
from ..utils.mys_api import mys_api
from ..utils.resource.RESOURCE_PATH import PLAYER_PATH
TEXT_PATH = Path(__file__).parent / 'texture2d'
@ -53,14 +54,13 @@ async def draw_note_img(sr_uid: str) -> Union[bytes, str]:
if int(now.month) < 10:
add_month = '0'
now_month = str(now.year) + str(add_month) + str(now.month)
print(now_month)
# 获取数据
data = await mys_api.get_award(sr_uid, now_month)
if isinstance(data, int):
return get_error(data)
# 保存数据
with open(
with Path.open(
path / f'monthly_{current_year_mon}.json', 'w', encoding='utf-8'
) as f:
save_data = json.dumps(
@ -81,7 +81,7 @@ async def draw_note_img(sr_uid: str) -> Union[bytes, str]:
last_year_mon = f'{last_year}-{last_month:02d}'
last_monthly_path = path / f'monthly_{last_year_mon}.json'
if last_monthly_path.exists():
with open(last_monthly_path, 'r', 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 = last_monthly_data['data']
else:
@ -89,8 +89,9 @@ async def draw_note_img(sr_uid: str) -> Union[bytes, str]:
if int(last_month) < 10:
add_month = '0'
find_last_month = str(last_year) + str(add_month) + str(last_month)
print(find_last_month)
last_monthly_data = await mys_api.get_award(sr_uid, find_last_month)
if isinstance(last_monthly_data, int):
return get_error(last_monthly_data)
# nickname and level
role_basic_info = await mys_api.get_role_basic_info(sr_uid)
@ -221,7 +222,7 @@ async def draw_note_img(sr_uid: str) -> Union[bytes, str]:
else:
pie_image = Image.new("RGBA", (2100, 2100), color=(255, 255, 255, 0))
pie_image_draw = ImageDraw.Draw(pie_image)
for index, i in enumerate(data['month_data']['group_by']):
for _index, i in enumerate(data['month_data']['group_by']):
pie_image_draw.pieslice(
xy,
temp,
@ -241,7 +242,7 @@ async def draw_note_img(sr_uid: str) -> Union[bytes, str]:
if last_monthly_data:
pie_image = Image.new("RGBA", (2100, 2100), color=(255, 255, 255, 0))
pie_image_draw = ImageDraw.Draw(pie_image)
for index, i in enumerate(last_monthly_data['month_data']['group_by']):
for _index, i in enumerate(last_monthly_data['month_data']['group_by']):
pie_image_draw.pieslice(
xy,
temp,
@ -270,7 +271,7 @@ async def draw_note_img(sr_uid: str) -> Union[bytes, str]:
async def int_carry(i: int) -> str:
if i >= 100000:
i_str = '{:.1f}W'.format(i / 10000)
i_str = f'{i / 10000:.1f}W'
else:
i_str = str(i)
return i_str

View File

@ -1,27 +1,30 @@
from ..utils.mys_api import mys_api
from datetime import datetime
from ..utils.error_reply import get_error
from ..utils.mys_api import mys_api
month_im = """==============
SR_UID{}
SR_UID:{}
==============
本日获取星琼{}
本日获取星轨通票&星轨专票{}
本日获取星琼:{}
本日获取星轨通票&星轨专票:{}
==============
昨日获取星琼{}
昨日获取星轨通票&星轨专票{}
昨日获取星琼:{}
昨日获取星轨通票&星轨专票:{}
==============
本月获取星琼{}
本月获取星轨通票&星轨专票{}
本月获取星琼:{}
本月获取星轨通票&星轨专票:{}
==============
上月获取星琼{}
上月获取星轨通票&星轨专票{}
上月获取星琼:{}
上月获取星轨通票&星轨专票:{}
==============
星琼收入组成
星琼收入组成:
{}=============="""
async def award(uid) -> str:
data = await mys_api.get_award(uid)
# 获取当前的月份
data = await mys_api.get_award(uid, datetime.now().month)
if isinstance(data, int):
return get_error(data)
day_hcoin = data['day_data']['current_hcoin']
@ -40,15 +43,15 @@ async def award(uid) -> str:
group_str = (
group_str
+ i['action_name']
+ ''
+ ':'
+ str(i['num'])
+ ''
+ '('
+ str(i['percent'])
+ '%'
+ '%)'
+ '\n'
)
im = month_im.format(
return month_im.format(
uid,
day_hcoin,
day_rails_pass,
@ -60,4 +63,3 @@ async def award(uid) -> str:
lastmonth_rails_pass,
group_str,
)
return im

View File

@ -9,7 +9,7 @@ from ..utils.resource.download_all_resource import download_all_resource
sv_sr_download_config = SV('sr下载资源', pm=1)
@sv_sr_download_config.on_fullmatch((f'{PREFIX}下载全部资源'))
@sv_sr_download_config.on_fullmatch(f'{PREFIX}下载全部资源')
async def send_download_resource_msg(bot: Bot, ev: Event):
await bot.send('sr正在开始下载~可能需要较久的时间!')
im = await download_all_resource()
@ -17,5 +17,5 @@ async def send_download_resource_msg(bot: Bot, ev: Event):
async def startup():
logger.info('[sr资源文件下载] 正在检查与下载缺失的资源文件,可能需要较长时间,请稍等')
logger.info('[sr资源文件下载] 正在检查与下载缺失的资源文件,可能需要较长时间,请稍等')
logger.info(f'[sr资源文件下载] {await download_all_resource()}')

View File

@ -1,8 +1,8 @@
import re
from gsuid_core.sv import SV
from gsuid_core.bot import Bot
from gsuid_core.models import Event
from gsuid_core.sv import SV
from gsuid_core.utils.error_reply import UID_HINT
from ..utils.convert import get_uid
@ -29,19 +29,22 @@ sv_srabyss = SV('sr查询模拟宇宙')
async def send_srabyss_info(bot: Bot, ev: Event):
name = ''.join(re.findall('[\u4e00-\u9fa5]', ev.text))
if name:
return
return None
await bot.logger.info('开始执行[sr查询模拟宇宙信息]')
uid, user_id = await get_uid(bot, ev, True)
get_uid_ = await get_uid(bot, ev, True)
if get_uid_ is None:
return await bot.send(UID_HINT)
uid, user_id = get_uid_
if uid is None:
return await bot.send(UID_HINT)
await bot.logger.info('[sr查询模拟宇宙信息]uid: {}'.format(uid))
await bot.logger.info(f'[sr查询模拟宇宙信息]uid: {uid}')
if 'sq' in ev.command or '上期' in ev.command:
schedule_type = '2'
else:
schedule_type = '3'
await bot.logger.info('[sr查询模拟宇宙信息]模拟宇宙期数: {}'.format(schedule_type))
await bot.logger.info(f'[sr查询模拟宇宙信息]模拟宇宙期数: {schedule_type}')
if ev.text in ['', '', '', '', '', '']:
floor = (
@ -59,9 +62,10 @@ async def send_srabyss_info(bot: Bot, ev: Event):
else:
floor = None
# print(floor)
await bot.logger.info('[sr查询模拟宇宙信息]模拟宇宙世界数: {}'.format(floor))
await bot.logger.info(f'[sr查询模拟宇宙信息]模拟宇宙世界数: {floor}')
# data = GsCookie()
# raw_rogue_data = await data.get_rogue_data(uid, schedule_type)
# print(raw_rogue_data)
im = await draw_rogue_img(user_id, uid, floor, schedule_type)
await bot.send(im)
return None

View File

@ -1,29 +1,30 @@
import math
from pathlib import Path
from typing import List, Union, Optional
from typing import 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,
get_qq_avatar,
)
from .utils import get_icon
from ..utils.convert import GsCookie
from ..utils.image.convert import convert_img
from ..sruid_utils.api.mys.models import (
RogueAvatar,
RogueMiracles,
RogueBuffitems,
RogueMiracles,
)
from ..utils.convert import GsCookie
from ..utils.fonts.starrail_fonts import (
sr_font_22,
sr_font_28,
sr_font_34,
sr_font_42,
)
from ..utils.image.convert import convert_img
from .utils import get_icon
TEXT_PATH = Path(__file__).parent / 'texture2D'
white_color = (255, 255, 255)
@ -63,11 +64,11 @@ progresslist = {
}
difficultylist = {
1: '',
1: 'I',
2: '',
3: '',
4: '',
5: '',
5: 'V',
6: '',
}
@ -83,8 +84,7 @@ bufflist = {
async def get_abyss_star_pic(star: int) -> Image.Image:
star_pic = Image.open(TEXT_PATH / f'star{star}.png')
return star_pic
return Image.open(TEXT_PATH / f'star{star}.png')
async def _draw_rogue_buff(
@ -257,20 +257,18 @@ async def draw_rogue_img(
rogue_detail[index_floor]['start_h'] = based_h
if floor:
if progress == floor:
detail_h = detail_h
pass
else:
detail_h = 0
based_h = based_h + detail_h
print(based_h)
# 获取查询者数据
if floor:
if floor > 6:
return '世界不能大于第六世界!'
if floor not in detail_list:
return '你还没有挑战该模拟宇宙!'
else:
if raw_rogue_data['current_record']['basic']['finish_cnt'] == 0:
return '你还没有挑战本期模拟宇宙!\n可以使用[sr上期模拟宇宙]命令查询上期~'
elif raw_rogue_data['current_record']['basic']['finish_cnt'] == 0:
return '你还没有挑战本期模拟宇宙!\n可以使用[sr上期模拟宇宙]命令查询上期~'
# 获取背景图片各项参数
based_w = 900
@ -353,6 +351,9 @@ async def draw_rogue_img(
else:
continue
if detail['detail_h'] is None:
continue
floor_pic = Image.open(TEXT_PATH / 'detail_bg.png').convert("RGBA")
floor_pic = floor_pic.resize((900, detail['detail_h']))
@ -393,14 +394,14 @@ async def draw_rogue_img(
)
floor_pic_draw.text(
(93, 120),
f'挑战时间{time_str}',
f'挑战时间:{time_str}',
gray_color,
sr_font_22,
'lm',
)
floor_pic_draw.text(
(800, 120),
f'当前积分{detail["score"]}',
f'当前积分:{detail["score"]}',
gray_color,
sr_font_22,
'rm',
@ -468,6 +469,9 @@ async def draw_rogue_img(
buff_height,
)
if detail['start_h'] is None:
continue
img.paste(floor_pic, (0, detail['start_h']), floor_pic)
# await _draw_floor_card(
# level_star,

View File

@ -1,8 +1,10 @@
from io import BytesIO
from pathlib import Path
from typing import TypeVar
from PIL import Image
from aiohttp import ClientSession
from PIL import Image
from gsuid_core.data_store import get_res_path
T = TypeVar("T")
@ -20,6 +22,6 @@ async def get_icon(url: str) -> Image.Image:
async with ClientSession() as client:
async with client.get(url) as resp:
content = await resp.read()
with open(path, "wb") as f:
with Path.open(path, "wb") as f:
f.write(content)
return Image.open(BytesIO(content)).convert("RGBA")

View File

@ -12,11 +12,11 @@ from .draw_roleinfo_card import get_role_img
sv_get_info = SV('sr查询信息')
@sv_get_info.on_command((f'{PREFIX}uid'))
@sv_get_info.on_command(f'{PREFIX}uid')
async def send_role_info(bot: Bot, ev: Event):
name = ''.join(re.findall('[\u4e00-\u9fa5]', ev.text))
if name:
return
return None
uid = await get_uid(bot, ev)
if uid is None:
@ -25,3 +25,4 @@ async def send_role_info(bot: Bot, ev: Event):
logger.info(f'[sr查询信息]UID: {uid}')
await bot.logger.info('开始执行[sr查询信息]')
await bot.send(await get_role_img(uid))
return None

View File

@ -1,15 +1,16 @@
import asyncio
from pathlib import Path
from typing import Dict, List, Union, Optional
from typing import Dict, List, Optional, Union
from PIL import Image, ImageDraw
from gsuid_core.utils.error_reply import get_error
from ..sruid_utils.api.mys.models import AvatarListItem, RoleBasicInfo, Stats
from ..utils.fonts.starrail_fonts import sr_font_24, sr_font_30, sr_font_36
from ..utils.image.convert import convert_img
from ..utils.mys_api import mys_api
from .utils import get_icon, wrap_list
from ..utils.image.convert import convert_img
from ..utils.fonts.starrail_fonts import sr_font_24, sr_font_30, sr_font_36
from ..sruid_utils.api.mys.models import Stats, RoleBasicInfo, AvatarListItem
TEXT_PATH = Path(__file__).parent / 'texture2D'
@ -48,8 +49,7 @@ elements = {
async def get_role_img(uid: str) -> Union[bytes, str]:
im = await draw_role_card(uid)
return im
return await draw_role_card(uid)
def _lv(level: int) -> str:
@ -226,7 +226,7 @@ async def draw_role_card(sr_uid: str) -> Union[bytes, str]:
# 绘制总图
img1, img2 = await asyncio.gather(
*[
_draw_card_1(sr_uid, role_basic_info, stats),
_draw_card_1(sr_uid, role_basic_info, stats), # type: ignore
_draw_card_2(avatars, equips),
]
)

View File

@ -1,8 +1,10 @@
from io import BytesIO
from typing import List, TypeVar, Generator
from pathlib import Path
from typing import Generator, List, TypeVar
from PIL import Image
from aiohttp import ClientSession
from PIL import Image
from gsuid_core.data_store import get_res_path
T = TypeVar("T")
@ -13,7 +15,7 @@ ROLEINFO_PATH.mkdir(parents=True, exist_ok=True)
def wrap_list(lst: List[T], n: int) -> Generator[List[T], None, None]:
for i in range(0, len(lst), n):
yield lst[i : i + n] # noqa:E203
yield lst[i : i + n]
async def get_icon(url: str) -> Image.Image:
@ -25,6 +27,6 @@ async def get_icon(url: str) -> Image.Image:
async with ClientSession() as client:
async with client.get(url) as resp:
content = await resp.read()
with open(path, "wb") as f:
with Path.open(path, "wb") as f:
f.write(content)
return Image.open(BytesIO(content)).convert("RGBA")

View File

@ -30,13 +30,14 @@ async def sr_sign_at_night():
# 群聊内 签到 功能
@sv_sign.on_fullmatch(f'{PREFIX}签到')
async def get_sign_func(bot: Bot, ev: Event):
await bot.logger.info('[SR签到]QQ号: {}'.format(ev.user_id))
await bot.logger.info(f'[SR签到]QQ号: {ev.user_id}')
sqla = get_sqla(ev.bot_id)
sr_uid = await sqla.get_bind_sruid(ev.user_id)
if sr_uid is None:
return await bot.send(UID_HINT)
await bot.logger.info('[SR签到]UID: {}'.format(sr_uid))
await bot.logger.info(f'[SR签到]UID: {sr_uid}')
await bot.send(await sign_in(sr_uid))
return None
@sv_sign_config.on_fullmatch(f'{PREFIX}全部重签')
@ -73,11 +74,11 @@ async def send_daily_sign():
# 根据succee数判断是否为简洁推送
if group_msg_list[gid]['success'] >= 0:
report = (
'以下为签到失败报告{}'.format(group_msg_list[gid]['push_message'])
'以下为签到失败报告:{}'.format(group_msg_list[gid]['push_message'])
if group_msg_list[gid]['push_message'] != ''
else ''
)
msg_title = '星穹铁道今日自动签到已完成\n本群共签到成功{}人,共签到失败{}人。{}'.format(
msg_title = '星穹铁道今日自动签到已完成!\n本群共签到成功{}人,共签到失败{}人。{}'.format(
group_msg_list[gid]['success'],
group_msg_list[gid]['failed'],
report,

View File

@ -1,14 +1,14 @@
import random
import asyncio
import random
from copy import deepcopy
from gsuid_core.gss import gss
from gsuid_core.logger import logger
from gsuid_core.utils.plugins_config.gs_config import core_plugins_config
from ..starrailuid_config.sr_config import srconfig
from ..utils.api import get_sqla
from ..utils.mys_api import mys_api
from ..starrailuid_config.sr_config import srconfig
private_msg_list = {}
group_msg_list = {}
@ -22,8 +22,8 @@ async def sign_in(sr_uid: str) -> str:
sign_info = await mys_api.get_sign_info(sr_uid)
# 初步校验数据
if isinstance(sign_info, int):
logger.warning(f'[SR签到] {sr_uid} 出错, 请检查Cookies是否过期')
return '签到失败...请检查Cookies是否过期'
logger.warning(f'[SR签到] {sr_uid} 出错, 请检查Cookies是否过期!')
return '签到失败...请检查Cookies是否过期!'
# 检测是否已签到
if sign_info['is_sign']:
logger.info(f'[SR签到] {sr_uid} 该用户今日已签到,跳过...')
@ -32,7 +32,7 @@ async def sign_in(sr_uid: str) -> str:
day_of_month = int(sign_info['today'].split('-')[-1])
signed_count = int(sign_info['total_sign_day'])
sign_missed = day_of_month - signed_count
return f'今日已签到!本月漏签次数:{sign_missed}'
return f'今日已签到!本月漏签次数:{sign_missed}'
# 实际进行签到
Header = {}
@ -41,15 +41,15 @@ async def sign_in(sr_uid: str) -> str:
sign_data = await mys_api.mys_sign(uid=sr_uid, header=Header)
# 检测数据
if isinstance(sign_data, int):
logger.warning(f'[SR签到] {sr_uid} 出错, 请检查Cookies是否过期')
return 'sr签到失败...请检查Cookies是否过期'
logger.warning(f'[SR签到] {sr_uid} 出错, 请检查Cookies是否过期!')
return 'sr签到失败...请检查Cookies是否过期!'
if 'risk_code' in sign_data:
# 出现校验码
if sign_data['risk_code'] == 5001:
if core_plugins_config.get_config('CaptchaPass').data:
gt = sign_data['gt']
ch = sign_data['challenge']
vl, ch = await mys_api._pass(gt, ch, Header)
vl, ch = await mys_api._pass(gt, ch, Header) # noqa: SLF001
if vl:
delay = 1
Header['x-rpc-challenge'] = ch
@ -62,24 +62,21 @@ async def sign_in(sr_uid: str) -> str:
logger.info(f'[SR签到] {sr_uid} 未获取验证码,等待{delay}秒后重试...')
await asyncio.sleep(delay)
continue
else:
logger.info('配置文件暂未开启[跳过无感验证],结束本次任务...')
logger.info('配置文件暂未开启[跳过无感验证],结束本次任务...')
return '签到失败...出现验证码!'
# 成功签到!
if index == 0:
logger.info(f'[SR签到] {sr_uid} 该用户无校验码!')
else:
if index == 0:
logger.info(f'[SR签到] {sr_uid} 该用户无校验码!')
else:
logger.info(f'[SR签到] [无感验证] {sr_uid} 该用户重试 {index} 次验证成功!')
break
elif (int(str(sr_uid)[0]) > 5) and (sign_data['data']['code'] == 'ok'):
logger.info(f'[SR签到] [无感验证] {sr_uid} 该用户重试 {index} 次验证成功!')
break
if (int(str(sr_uid)[0]) > 5) and (sign_data['data']['code'] == 'ok'):
# 国际服签到无risk_code字段
logger.info(f'[SR国际服签到] {sr_uid} 签到成功!')
break
else:
# 重试超过阈值
logger.warning('[SR签到] 超过请求阈值...')
return 'sr签到失败...出现验证码!\n请过段时间使用[签到]或由管理员[全部重签]或手动至米游社进行签到!'
# 重试超过阈值
logger.warning('[SR签到] 超过请求阈值...')
return 'sr签到失败...出现验证码!\n请过段时间使用[签到]或由管理员[全部重签]或手动至米游社进行签到!'
# 签到失败
else:
im = 'sr签到失败!'
@ -89,9 +86,9 @@ async def sign_in(sr_uid: str) -> str:
sign_list = await mys_api.get_sign_list(sr_uid)
new_sign_info = await mys_api.get_sign_info(sr_uid)
if isinstance(sign_list, int) or isinstance(new_sign_info, int):
logger.warning(f'[SR签到] {sr_uid} 出错, 请检查Cookies是否过期')
return 'sr签到失败...请检查Cookies是否过期'
# 获取签到奖励物品,拿旧的总签到天数 + 1 为新的签到天数,再 -1 即为今日奖励物品的下标
logger.warning(f'[SR签到] {sr_uid} 出错, 请检查Cookies是否过期!')
return 'sr签到失败...请检查Cookies是否过期!'
# 获取签到奖励物品,拿旧的总签到天数 + 1 为新的签到天数,再 -1 即为今日奖励物品的下标
getitem = sign_list['awards'][int(sign_info['total_sign_day']) + 1 - 1]
get_im = f'本次sr签到获得{getitem["name"]}x{getitem["cnt"]}'
day_of_month = int(new_sign_info['today'].split('-')[-1])
@ -103,7 +100,7 @@ async def sign_in(sr_uid: str) -> str:
mes_im = 'sr签到失败...'
sign_missed -= 1
sign_missed = sign_info.get('sign_cnt_missed') or sign_missed
im = f'{mes_im}!\n{get_im}\n本月漏签次数{sign_missed}'
im = f'{mes_im}!\n{get_im}\n本月漏签次数:{sign_missed}'
logger.info(f'[SR签到] {sr_uid} 签到完成, 结果: {mes_im}, 漏签次数: {sign_missed}')
return im
@ -136,7 +133,7 @@ async def single_daily_sign(bot_id: str, sr_uid: str, gid: str, qid: str):
group_msg_list[gid]['success'] += 1
# 没有开启简洁签到, 则每条消息都要携带@信息
else:
# 不用MessageSegment.at(row[2])因为不方便移植
# 不用MessageSegment.at(row[2]),因为不方便移植
message = f'[CQ:at,qq={qid}] {im}'
group_msg_list[gid]['push_message'] += '\n' + message
group_msg_list[gid]['success'] -= 1

View File

@ -19,19 +19,20 @@ sv_get_stamina = SV('sr查询体力')
sv_get_stamina_admin = SV('sr强制推送', pm=1)
@sv_get_stamina.on_fullmatch((f'{PREFIX}当前状态'))
@sv_get_stamina.on_fullmatch(f'{PREFIX}当前状态')
async def send_daily_info(bot: Bot, ev: Event):
await bot.logger.info('开始执行[sr每日信息文字版]')
uid = await get_uid(bot, ev)
if uid is None:
return await bot.send(UID_HINT)
await bot.logger.info('[sr每日信息文字版]UID: {}'.format(uid))
await bot.logger.info(f'[sr每日信息文字版]UID: {uid}')
im = await get_stamina_text(uid)
await bot.send(im)
return None
@sv_get_stamina_admin.on_fullmatch((f'{PREFIX}强制推送体力提醒'))
@sv_get_stamina_admin.on_fullmatch(f'{PREFIX}强制推送体力提醒')
async def force_notice_job(bot: Bot, ev: Event):
await bot.logger.info('开始执行[sr强制推送体力信息]')
await sr_notice_job()
@ -75,7 +76,7 @@ async def sr_notice_job():
async def send_daily_info_pic(bot: Bot, ev: Event):
await bot.logger.info('开始执行[sr每日信息]')
user_id = ev.at if ev.at else ev.user_id
await bot.logger.info('[sr每日信息]QQ号: {}'.format(user_id))
await bot.logger.info(f'[sr每日信息]QQ号: {user_id}')
im = await get_stamina_img(bot.bot_id, user_id)
await bot.send(im)

View File

@ -1,18 +1,16 @@
import asyncio
from io import BytesIO
from typing import List
from pathlib import Path
from typing import Optional
import aiohttp
from PIL import Image, ImageDraw
from gsuid_core.logger import logger
from ..utils.api import get_sqla
from ..utils.mys_api import mys_api
from ..utils.image.convert import convert_img
from ..sruid_utils.api.mys.models import Expedition
from ..starrailuid_config.sr_config import srconfig
from ..utils.image.image_tools import get_simple_bg
from ..utils.api import get_sqla
from ..utils.fonts.starrail_fonts import (
sr_font_22,
sr_font_24,
@ -20,6 +18,9 @@ from ..utils.fonts.starrail_fonts import (
sr_font_36,
sr_font_50,
)
from ..utils.image.convert import convert_img
from ..utils.image.image_tools import get_simple_bg
from ..utils.mys_api import mys_api
use_widget = srconfig.get_config('WidgetResin').data
@ -51,15 +52,14 @@ async def download_image(url: str) -> Image.Image:
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
img_data = await response.read()
img = Image.open(BytesIO(img_data))
return img
return Image.open(BytesIO(img_data))
async def _draw_task_img(
img: Image.Image,
img_draw: ImageDraw.ImageDraw,
index: int,
char: Expedition,
char: Optional[Expedition],
):
if char is not None:
expedition_name = char['name']
@ -106,15 +106,17 @@ async def _draw_task_img(
async def get_stamina_img(bot_id: str, user_id: str):
try:
sqla = get_sqla(bot_id)
uid_list: List = await sqla.get_bind_sruid_list(user_id)
logger.info('[每日信息]UID: {}'.format(uid_list))
uid_list = await sqla.get_bind_sruid_list(user_id)
logger.info(f'[每日信息]UID: {uid_list}')
if uid_list is None:
return '请先绑定一个UID再来查询哦~'
# 进行校验UID是否绑定CK
useable_uid_list = []
for uid in uid_list:
status = await sqla.get_user_cookie(uid)
if status is not None:
useable_uid_list.append(uid)
logger.info('[每日信息]可用UID: {}'.format(useable_uid_list))
logger.info(f'[每日信息]可用UID: {useable_uid_list}')
if len(useable_uid_list) == 0:
return '请先绑定一个可用CK & UID再来查询哦~'
# 开始绘图任务
@ -179,11 +181,15 @@ async def draw_stamina_img(sr_uid: str) -> Image.Image:
daily_data = _daily_data
else:
daily_data = await mys_api.get_daily_data(sr_uid)
if isinstance(daily_data, int):
return get_error(img, sr_uid, daily_data)
# nickname and level
# deal with hoyolab with no nickname and level api
if int(str(sr_uid)[0]) < 6:
role_basic_info = await mys_api.get_role_basic_info(sr_uid)
if isinstance(role_basic_info, int):
return get_error(img, sr_uid, role_basic_info)
nickname = role_basic_info['nickname']
level = role_basic_info['level']
else:

View File

@ -3,16 +3,16 @@ from typing import Dict
from gsuid_core.gss import gss
from gsuid_core.logger import logger
from ..sruid_utils.api.mys.models import DailyNoteData
from ..starrailuid_config.sr_config import srconfig
from ..utils.api import get_sqla
from ..utils.mys_api import mys_api
from ..starrailuid_config.sr_config import srconfig
from ..sruid_utils.api.mys.models import DailyNoteData
MR_NOTICE = '\n可发送[srmr]或者[sr每日]来查看更多信息\n'
MR_NOTICE = '\n可发送[srmr]或者[sr每日]来查看更多信息!\n'
NOTICE = {
'stamina': f'你的开拓力快满啦{MR_NOTICE}',
'go': f'你有派遣信息即将可收取{MR_NOTICE}',
'stamina': f'你的开拓力快满啦!{MR_NOTICE}',
'go': f'你有派遣信息即将可收取!{MR_NOTICE}',
}
@ -93,10 +93,9 @@ async def check(mode: str, data: DailyNoteData, limit: int) -> bool:
if mode == 'resin':
if data['current_stamina'] >= limit:
return True
elif data['current_stamina'] >= data['max_stamina']:
if data['current_stamina'] >= data['max_stamina']:
return True
else:
return False
return False
if mode == 'go':
for i in data['expeditions']:
if i['status'] == 'Ongoing':
@ -105,3 +104,4 @@ async def check(mode: str, data: DailyNoteData, limit: int) -> bool:
else:
return True
return False
return False

View File

@ -2,14 +2,14 @@ from typing import List
from gsuid_core.logger import logger
from ..utils.mys_api import mys_api
from ..utils.error_reply import get_error
from ..utils.mys_api import mys_api
daily_im = """*数据刷新可能存在一定延迟请以当前游戏实际数据为准
daily_im = """*数据刷新可能存在一定延迟,请以当前游戏实际数据为准
==============
开拓力{}/{}{}
委托执行
总数/完成/上限{}/{}/{}
开拓力:{}/{}{}
委托执行:
总数/完成/上限:{}/{}/{}
{}"""
@ -42,7 +42,7 @@ async def get_stamina_text(uid: str) -> str:
)
rec_time = f' ({next_stamina_rec_time}/{stamina_recover_time})'
accepted_epedition_num = dailydata['accepted_epedition_num']
accepted_epedition_num = dailydata['accepted_expedition_num']
total_expedition_num = dailydata['total_expedition_num']
finished_expedition_num = 0
expedition_info: List[str] = []
@ -61,8 +61,7 @@ async def get_stamina_text(uid: str) -> str:
)
expedition_data = '\n'.join(expedition_info)
print(expedition_data)
send_mes = daily_im.format(
return daily_im.format(
current_stamina,
max_stamina,
rec_time,
@ -71,7 +70,6 @@ async def get_stamina_text(uid: str) -> str:
total_expedition_num,
expedition_data,
)
return send_mes
except TypeError:
logger.exception('[查询当前状态]查询失败!')
return '你绑定过的UID中可能存在过期CK~请重新绑定一下噢~'

View File

@ -1,12 +1,12 @@
from typing import List
from gsuid_core.sv import SV
from gsuid_core.bot import Bot
from gsuid_core.models import Event
from gsuid_core.sv import SV
from ..utils.api import get_sqla
from ..utils.sr_prefix import PREFIX
from ..utils.message import send_diff_msg
from ..utils.sr_prefix import PREFIX
from .draw_user_card import get_user_card
sv_user_config = SV('sr用户管理', pm=2)
@ -15,12 +15,15 @@ sv_user_info = SV('sr用户信息')
# sv_user_help = SV('sr绑定帮助')
@sv_user_info.on_fullmatch((f'{PREFIX}绑定信息'))
@sv_user_info.on_fullmatch(f'{PREFIX}绑定信息')
async def send_bind_card(bot: Bot, ev: Event):
await bot.logger.info('sr开始执行[查询用户绑定状态]')
uid_list = await get_user_card(ev.bot_id, ev.user_id)
if not uid_list:
return await bot.send('你还没有绑定SR_UID哦!')
await bot.logger.info('sr[查询用户绑定状态]完成!等待图片发送中...')
await bot.send(uid_list)
return None
@sv_user_info.on_command(
@ -29,7 +32,7 @@ async def send_bind_card(bot: Bot, ev: Event):
async def send_link_uid_msg(bot: Bot, ev: Event):
await bot.logger.info('sr开始执行[绑定/解绑用户信息]')
qid = ev.user_id
await bot.logger.info('sr[绑定/解绑]UserID: {}'.format(qid))
await bot.logger.info(f'sr[绑定/解绑]UserID: {qid}')
sqla = get_sqla(ev.bot_id)
sr_uid = ev.text.strip()
@ -42,25 +45,23 @@ async def send_link_uid_msg(bot: Bot, ev: Event):
bot,
data,
{
0: f'绑定SR_UID{sr_uid}成功',
-1: f'SR_UID{sr_uid}的位数不正确',
-2: f'SR_UID{sr_uid}已经绑定过了',
0: f'绑定SR_UID{sr_uid}成功!',
-1: f'SR_UID{sr_uid}的位数不正确!',
-2: f'SR_UID{sr_uid}已经绑定过了!',
-3: '你输入了错误的格式!',
},
)
elif '切换' in ev.command:
if '切换' in ev.command:
data = await sqla.switch_uid(qid, uid=sr_uid)
if isinstance(data, List):
return await bot.send(f'切换SR_UID{sr_uid}成功!')
else:
return await bot.send(f'尚未绑定该SR_UID{sr_uid}')
else:
data = await sqla.delete_bind_data(qid, sr_uid=sr_uid)
return await send_diff_msg(
bot,
data,
{
0: f'删除SR_UID{sr_uid}成功!',
-1: f'该SR_UID{sr_uid}不在已绑定列表中!',
},
)
return await bot.send(f'切换SR_UID{sr_uid}成功!')
return await bot.send(f'尚未绑定该SR_UID{sr_uid}')
data = await sqla.delete_bind_data(qid, sr_uid=sr_uid)
return await send_diff_msg(
bot,
data,
{
0: f'删除SR_UID{sr_uid}成功!',
-1: f'该SR_UID{sr_uid}不在已绑定列表中!',
},
)

View File

@ -1,10 +1,10 @@
from http.cookies import SimpleCookie
from pathlib import Path
from typing import Dict, List
from http.cookies import SimpleCookie
from ..utils.api import get_sqla
from ..utils.mys_api import mys_api
from ..utils.error_reply import UID_HINT
from ..utils.mys_api import mys_api
pic_path = Path(__file__).parent / 'pic'
id_list = [
@ -35,19 +35,19 @@ async def get_ck_by_all_stoken(bot_id: str):
user_data = await sqla.select_user_data(uid)
if user_data:
uid_dict[uid] = user_data.user_id
im = await refresh_ck_by_uid_list(bot_id, uid_dict)
return im
return await refresh_ck_by_uid_list(bot_id, uid_dict)
async def get_ck_by_stoken(bot_id: str, user_id: str):
sqla = get_sqla(bot_id)
uid_list: List = await sqla.get_bind_uid_list(user_id)
uid_list = await sqla.get_bind_uid_list(user_id)
if uid_list is None:
return '请先绑定一个UID噢~'
uid_dict = {uid: user_id for uid in uid_list}
im = await refresh_ck_by_uid_list(bot_id, uid_dict)
return im
return await refresh_ck_by_uid_list(bot_id, uid_dict)
async def refresh_ck_by_uid_list(bot_id: str, uid_dict: Dict):
async def refresh_ck_by_uid_list(bot_id: str, uid_dict: Dict) -> str:
sqla = get_sqla(bot_id)
uid_num = len(uid_dict)
if uid_num == 0:
@ -61,25 +61,23 @@ async def refresh_ck_by_uid_list(bot_id: str, uid_dict: Dict):
skip_num += 1
error_num += 1
continue
else:
qid = uid_dict[uid]
try:
mes = await _deal_ck(bot_id, stoken, qid)
except TypeError:
error_list[uid] = 'SK或CK已过期'
error_num += 1
continue
ok_num = mes.count('成功')
if ok_num < 2:
error_list[uid] = '可能是SK已过期~'
error_num += 1
continue
qid = uid_dict[uid]
try:
mes = await _deal_ck(bot_id, stoken, qid)
except TypeError:
error_list[uid] = 'SK或CK已过期!'
error_num += 1
continue
ok_num = mes.count('成功')
if ok_num < 2:
error_list[uid] = '可能是SK已过期~'
error_num += 1
continue
s_im = f'执行完成~成功刷新CK{uid_num - error_num}跳过{skip_num}个!'
s_im = f'执行完成~成功刷新CK{uid_num - error_num}!跳过{skip_num}个!'
f_im = '\n'.join([f'UID{u}:{error_list[u]}' for u in error_list])
im = f'{s_im}\n{f_im}' if f_im else s_im
return f'{s_im}\n{f_im}' if f_im else s_im
return im
async def deal_ck(bot_id: str, mes: str, user_id: str, mode: str = 'PIC'):
@ -97,9 +95,8 @@ async def _deal_ck_to_pic(im: str) -> bytes:
status_pic = pic_path / 'ck_ok.png'
else:
status_pic = pic_path / 'all_ok.png'
with open(status_pic, 'rb') as f:
img = f.read()
return img
with Path.open(status_pic, 'rb') as f:
return f.read()
async def get_account_id(simp_dict: SimpleCookie) -> str:
@ -121,7 +118,7 @@ async def _deal_ck(bot_id: str, mes: str, user_id: str) -> str:
if uid is None and sr_uid is None:
if uid is None:
return UID_HINT
elif sr_uid is None:
if sr_uid is None:
return '请绑定星穹铁道UID...'
im_list = []
@ -154,8 +151,7 @@ async def _deal_ck(bot_id: str, mes: str, user_id: str) -> str:
is_add_stoken = True
status = False
break
else:
return '返回值错误...'
return '返回值错误...'
if status:
for lt in lt_list:
if lt in simp_dict:
@ -218,12 +214,13 @@ async def _deal_ck(bot_id: str, mes: str, user_id: str) -> str:
break
else:
if not (uid or sr_uid):
return f'你的米游社账号{account_id}尚未绑定原神/星铁账号,请前往米游社操作!'
return f'你的米游社账号{account_id}尚未绑定原神/星铁账号,\
请前往米游社操作!'
except Exception:
pass
if not uid:
return f'你的米游社账号{account_id}尚未绑定原神/星铁账号,请前往米游社操作'
return f'你的米游社账号{account_id}尚未绑定原神/星铁账号,请前往米游社操作!'
await sqla.refresh_cache(uid)
if is_add_stoken:
@ -236,14 +233,13 @@ async def _deal_ck(bot_id: str, mes: str, user_id: str) -> str:
f'添加Cookies成功,account_id={account_id},cookie_token={cookie_token}'
)
im_list.append(
'Cookies和Stoken属于个人重要信息,如果你是在不知情的情况下添加,请马上修改米游社账户密码,保护个人隐私'
'Cookies和Stoken属于个人重要信息,如果你是在不知情的情况下添加,请马上修改米游社账户密码,保护个人隐私!'
)
im_list.append(
(
'如果需要【sr开启自动签到】和【sr开启推送】还需要在【群聊中】使用命令“绑定uid”绑定你的uid。'
'\n例如绑定uid123456789。'
)
'\n例如:绑定uid123456789。'
)
im_list.append('你可以使用命令【sr绑定信息】检查你的账号绑定情况')
im = '\n'.join(im_list)
return im
im_list.append('你可以使用命令【sr绑定信息】检查你的账号绑定情况!')
return '\n'.join(im_list)

View File

@ -1,5 +1,5 @@
# from pathlib import Path
from typing import List, Tuple, Optional
from typing import Optional, Tuple
from PIL import Image
@ -25,7 +25,7 @@ from ..utils.api import get_sqla
async def get_user_card(bot_id: str, user_id: str):
pass
sqla = get_sqla(bot_id)
uid_list: List = await sqla.get_bind_uid_list(user_id)
return await sqla.get_bind_uid_list(user_id)
# w, h = 750, len(uid_list) * 750 + 470
#
# # 获取背景图片各项参数
@ -97,7 +97,6 @@ async def get_user_card(bot_id: str, user_id: str):
# img.paste(user_card, (0, 500 + index * 690), user_card)
# return await convert_img(img)
return uid_list
def paste_switch(

View File

@ -9,7 +9,7 @@ CK_QRCODE_LOGIN = '''先发送【绑定uidxxx】绑定UID,
CK_CONSOLE = '''var cookie = document.cookie;
var Str_Num = cookie.indexOf('_MHYUUID=');
cookie = '添加 ' + cookie.substring(Str_Num);
var ask = confirm('Cookie:' + cookie + '\\n\\n按确认然后粘贴发送给机器人');
var ask = confirm('Cookie:' + cookie + '\\n\\n按确认,然后粘贴发送给机器人');
if (ask == true) {
copy(cookie);
msg = cookie
@ -18,18 +18,18 @@ if (ask == true) {
}
'''
CK_URL = '''1.复制上面全部代码然后打开下面的网站
CK_URL = '''1.复制上面全部代码,然后打开下面的网站
https://bbs.mihoyo.com/ys/obc/?bbs_presentation_style=no_header(国服)
https://www.hoyolab.com/home(国际服)
2.在页面上右键检查或者Ctrl+Shift+i
3.选择控制台(Console)粘贴回车在弹出的窗口点确认(点完自动复制)
4.然后在和机器人的私聊窗口粘贴发送即可
3.选择控制台(Console),粘贴,回车,在弹出的窗口点确认(点完自动复制)
4.然后在和机器人的私聊窗口,粘贴发送即可
'''
SK_URL = '''如果想获取SK,操作方法和上面一致,网址更换为
http://user.mihoyo.com/(国服)
登陆后,进入控制台粘贴代码
然后在和机器人的私聊窗口粘贴发送即可
然后在和机器人的私聊窗口,粘贴发送即可
'''

View File

@ -1,15 +1,16 @@
import asyncio
import base64
import io
import json
import base64
import asyncio
from http.cookies import SimpleCookie
from typing import Any, List, Tuple, Union, Literal
from typing import Any, List, Literal, Tuple, Union
import qrcode
from gsuid_core.bot import Bot
from gsuid_core.models import Event
from gsuid_core.logger import logger
from qrcode.constants import ERROR_CORRECT_L
from gsuid_core.bot import Bot
from gsuid_core.logger import logger
from gsuid_core.models import Event
from gsuid_core.segment import MessageSegment
from ..utils.api import get_sqla
@ -24,7 +25,7 @@ disnote = '''免责声明:您将通过扫码完成获取米游社sk以及ck。
def get_qrcode_base64(url):
qr = qrcode.QRCode(
qr = qrcode.QRCode( # type: ignore
version=1,
error_correction=ERROR_CORRECT_L,
box_size=10,
@ -74,7 +75,7 @@ async def qrcode_login(bot: Bot, ev: Event, user_id: str) -> str:
return await send_msg('链接创建失败...')
try:
im = []
im.append(MessageSegment.text('请使用米游社扫描下方二维码登录'))
im.append(MessageSegment.text('请使用米游社扫描下方二维码登录:'))
im.append(
MessageSegment.image(
f'base64://{get_qrcode_base64(code_data["url"])}'
@ -124,7 +125,7 @@ async def qrcode_login(bot: Bot, ev: Event, user_id: str) -> str:
uid_check = i['game_role_id']
break
else:
im = f'你的米游社账号{account_id}尚未绑定原神账号,请前往米游社操作!'
im = f'你的米游社账号{account_id}尚未绑定原神账号,请前往米游社操作!'
return await send_msg(im)
else:
im = '请求失败, 请稍后再试...'
@ -134,7 +135,8 @@ async def qrcode_login(bot: Bot, ev: Event, user_id: str) -> str:
# 没有在gsuid绑定uid的情况
if not uid_bind:
logger.warning('game_token获取失败')
im = '你还没有绑定uid, 请输入[绑定uid123456]绑定你的uid, 再发送[扫码登录]进行绑定'
im = '你还没有绑定uid, \
请输入[绑定uid123456]绑定你的uid, 再发送[扫码登录]进行绑定'
return await send_msg(im)
if isinstance(cookie_token, int):
return await send_msg('获取CK失败...')
@ -148,12 +150,11 @@ async def qrcode_login(bot: Bot, ev: Event, user_id: str) -> str:
'cookie_token': cookie_token['cookie_token'],
}
).output(header='', sep=';')
else:
logger.warning('game_token获取失败')
im = (
f'检测到扫码登录UID{uid_check}与绑定UID{uid_bind}不同, '
'gametoken获取失败, 请重新发送[扫码登录]进行登录!'
)
logger.warning('game_token获取失败')
im = (
f'检测到扫码登录UID{uid_check}与绑定UID{uid_bind}不同, '
'gametoken获取失败, 请重新发送[扫码登录]进行登录!'
)
else:
logger.warning('game_token获取失败')
im = 'game_token获取失败: 二维码已过期'

View File

@ -23,87 +23,87 @@ sv_sr_wiki = SV('星铁WIKI')
sv_sr_guide = SV('星铁攻略')
@sv_sr_wiki.on_prefix(('sr角色图鉴'))
@sv_sr_wiki.on_prefix('sr角色图鉴')
async def send_role_wiki_pic(bot: Bot, ev: Event):
msg = ' '.join(re.findall('[\u4e00-\u9fa5]+', ev.text))
await bot.logger.info('开始获取{}图鉴'.format(msg))
await bot.logger.info(f'开始获取{msg}图鉴')
name = await alias_to_char_name(msg)
img = WIKI_ROLE_PATH / '{}.png'.format(name)
img = WIKI_ROLE_PATH / f'{name}.png'
if img.exists():
img = await convert_img(img)
await bot.logger.info('获得{}图鉴图片成功!'.format(name))
await bot.logger.info(f'获得{name}图鉴图片成功!')
await bot.send(img)
else:
await bot.logger.warning('未找到{}图鉴图片'.format(name))
await bot.logger.warning(f'未找到{name}图鉴图片')
@sv_sr_guide.on_prefix(('sr角色攻略'))
@sv_sr_guide.on_prefix('sr角色攻略')
async def send_role_guide_pic(bot: Bot, ev: Event):
char_name = ' '.join(re.findall('[\u4e00-\u9fa5]+', ev.text))
await bot.logger.info('开始获取{}图鉴'.format(char_name))
await bot.logger.info(f'开始获取{char_name}图鉴')
if "开拓者" in str(char_name):
char_name = "开拓者"
char_id = await name_to_avatar_id(char_name)
if char_id == '':
char_name = await alias_to_char_name(char_name)
char_id = await name_to_avatar_id(char_name)
img = GUIDE_CHARACTER_PATH / '{}.png'.format(char_id)
img = GUIDE_CHARACTER_PATH / f'{char_id}.png'
if img.exists():
img = await convert_img(img)
await bot.logger.info('获得{}图鉴图片成功!'.format(char_id))
await bot.logger.info(f'获得{char_id}图鉴图片成功!')
await bot.send(img)
else:
await bot.logger.warning('未找到{}图鉴图片'.format(char_id))
await bot.logger.warning(f'未找到{char_id}图鉴图片')
@sv_sr_guide.on_prefix(('sr光锥攻略'))
@sv_sr_guide.on_prefix('sr光锥攻略')
async def send_weapon_guide_pic(bot: Bot, ev: Event):
msg = ' '.join(re.findall('[\u4e00-\u9fa5]+', ev.text))
await bot.logger.info('开始获取{}图鉴'.format(msg))
await bot.logger.info(f'开始获取{msg}图鉴')
light_cone_id = await name_to_weapon_id(msg)
img = GUIDE_LIGHT_CONE_PATH / '{}.png'.format(light_cone_id)
img = GUIDE_LIGHT_CONE_PATH / f'{light_cone_id}.png'
if img.exists():
img = await convert_img(img)
await bot.logger.info('获得{}光锥图片成功!'.format(light_cone_id))
await bot.logger.info(f'获得{light_cone_id}光锥图片成功!')
await bot.send(img)
else:
await bot.logger.warning('未找到{}光锥图片'.format(light_cone_id))
await bot.logger.warning(f'未找到{light_cone_id}光锥图片')
@sv_sr_wiki.on_prefix(('sr遗器'))
@sv_sr_wiki.on_prefix('sr遗器')
async def send_relic_wiki_pic(bot: Bot, ev: Event):
msg = ' '.join(re.findall('[\u4e00-\u9fa5]+', ev.text))
await bot.logger.info('开始获取{}遗器'.format(msg))
img = WIKI_RELIC_PATH / '{}.png'.format(msg)
await bot.logger.info(f'开始获取{msg}遗器')
img = WIKI_RELIC_PATH / f'{msg}.png'
if img.exists():
img = await convert_img(img)
await bot.logger.info('获得{}遗器图片成功!'.format(msg))
await bot.logger.info(f'获得{msg}遗器图片成功!')
await bot.send(img)
else:
await bot.logger.warning('未找到{}遗器图片'.format(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):
msg = ' '.join(re.findall('[\u4e00-\u9fa5]+', ev.text))
await bot.logger.info('开始获取{}突破材料'.format(msg))
img = WIKI_MATERIAL_FOR_ROLE / '{}.png'.format(msg)
await bot.logger.info(f'开始获取{msg}突破材料')
img = WIKI_MATERIAL_FOR_ROLE / f'{msg}.png'
if img.exists():
img = await convert_img(img)
await bot.logger.info('获得{}突破材料图片成功!'.format(msg))
await bot.logger.info(f'获得{msg}突破材料图片成功!')
await bot.send(img)
else:
await bot.logger.warning('未找到{}突破材料图片'.format(msg))
await bot.logger.warning(f'未找到{msg}突破材料图片')
@sv_sr_wiki.on_prefix(('sr武器'))
@sv_sr_wiki.on_prefix('sr武器')
async def send_light_cone_wiki_pic(bot: Bot, ev: Event):
msg = ' '.join(re.findall('[\u4e00-\u9fa5]+', ev.text))
await bot.logger.info('开始获取{}武器'.format(msg))
img = WIKI_LIGHT_CONE_PATH / '{}.png'.format(msg)
await bot.logger.info(f'开始获取{msg}武器')
img = WIKI_LIGHT_CONE_PATH / f'{msg}.png'
if img.exists():
img = await convert_img(img)
await bot.logger.info('获得{}武器图片成功!'.format(msg))
await bot.logger.info(f'获得{msg}武器图片成功!')
await bot.send(img)
else:
await bot.logger.warning('未找到{}武器图片'.format(msg))
await bot.logger.warning(f'未找到{msg}武器图片')

View File

@ -0,0 +1,144 @@
import json
import os
from pathlib import Path
from typing import Dict
from httpx import AsyncClient
def get_all_file(path):
# 获取文件夹下所有文件的路径
file_list = []
for root, _dirs, files in os.walk(path):
for file in files:
file_path = os.path.join(root, file)
file_list.append(file_path)
return file_list
FILE_ROOT_MAP = [
'character',
'character_portrait',
'character_preview',
'consumable',
'element',
'light_cone',
'relic',
'skill',
]
WIKI_ROOT_MAP = [
'lightcone',
'material for role',
'relic',
'role',
]
GUIDE_ROOT_MAP = [
'lightcone',
'character'
]
input_path = Path("C:/Users/qwerdvd/Desktop/gsuid_core/data/StarRailUID/resource")
wiki_path = Path("C:/Users/qwerdvd/Desktop/gsuid_core/data/StarRailUID/wiki")
guide_path = Path("C:/Users/qwerdvd/Desktop/gsuid_core/data/StarRailUID/guide")
file_list = get_all_file(input_path)
wiki_file_list = get_all_file(wiki_path)
guide_file_list = get_all_file(guide_path)
file_map = {
'resource': {
'character': {},
'character_portrait': {},
'character_preview': {},
'consumable': {},
'element': {},
'light_cone': {},
'relic': {},
'skill': {}
},
'wiki': {
'lightcone': {},
'material for role': {},
'relic': {},
'role': {},
},
'guide': {
'lightcone': {},
'character': {}
}
}
async def upload(file_path: str, token: str) -> Dict:
async with AsyncClient(
timeout=10
) as client:
req = await client.post(
'http://182.43.43.40:8765/nor.php',
data={
'token': token
},
files={
'file': open(file_path, 'rb')
}
)
print(req.status_code)
print(req.text)
return req.json()
async def main(token: str):
for file_root in FILE_ROOT_MAP:
for file in file_list:
file_name = file.split('\\')[-1]
file_path = file.split('\\')[-2]
if file_path == file_root:
print(f'upload res {file_path}_{file_name}')
data = await upload(file, token)
image_info_array = data[0]['image_info_array']
for image_info in image_info_array:
size = image_info['size']
url = image_info['url']
file_map['resource'][file_root][file_name] = {
'size': size,
'url': url
}
for file_root in WIKI_ROOT_MAP:
for file in wiki_file_list:
file_name = file.split('\\')[-1]
file_path = file.split('\\')[-2]
if file_path == file_root:
print(f'upload wiki {file_path}_{file_name}')
data = await upload(file, token)
image_info_array = data[0]['image_info_array']
for image_info in image_info_array:
size = image_info['size']
url = image_info['url']
file_map['wiki'][file_root][file_name] = {
'size': size,
'url': url
}
for file_root in GUIDE_ROOT_MAP:
for file in guide_file_list:
file_name = file.split('\\')[-1]
file_path = file.split('\\')[-2]
if file_path == file_root:
print(f'upload guide {file_path}_{file_name}')
data = await upload(file, token)
image_info_array = data[0]['image_info_array']
for image_info in image_info_array:
size = image_info['size']
url = image_info['url']
file_map['guide'][file_root][file_name] = {
'size': size,
'url': url
}
with open('./file_map.json', 'w', encoding='utf-8') as f:
f.write(json.dumps(file_map, ensure_ascii=False))
print(json.dumps(file_map, ensure_ascii=False))
if __name__ == '__main__':
import asyncio
token = 'BtxqvjajYEtbpzG3OJ5giOX06QVCQYzC'
asyncio.run(main(token))

View File

@ -1,14 +1,14 @@
import re
from typing import Tuple, Union, Optional, overload
from typing import Optional, Tuple, Union, overload
from gsuid_core.bot import Bot
from gsuid_core.models import Event
from gsuid_core.utils.api.mys.models import IndexData
from .api import get_sqla
from .mys_api import mys_api
from .error_reply import VERIFY_HINT
from ..sruid_utils.api.mys.models import AbyssData, RogueData
from .api import get_sqla
from .error_reply import VERIFY_HINT
from .mys_api import mys_api
@overload
@ -62,8 +62,7 @@ class GsCookie:
msg = await self.check_cookies_useable()
if isinstance(msg, str):
return msg
elif msg:
return ''
return ''
async def get_uid_data(self) -> Union[int, IndexData]:
data = await mys_api.get_info(self.uid, self.cookie)
@ -76,20 +75,18 @@ class GsCookie:
) -> Union[AbyssData, int]:
self.uid = uid
self.cookie = await self.sqla.get_random_cookie(uid)
data = await mys_api.get_srspiral_abyss_info(
return await mys_api.get_srspiral_abyss_info(
self.uid, schedule_type, self.cookie
)
return data
async def get_rogue_data(
self, uid: str, schedule_type: str = '3'
) -> Union[RogueData, int]:
self.uid = uid
self.cookie = await self.sqla.get_random_cookie(uid)
data = await mys_api.get_rogue_info(
return await mys_api.get_rogue_info(
self.uid, schedule_type, self.cookie
)
return data
async def check_cookies_useable(self):
if isinstance(self.raw_data, int) and self.cookie:
@ -98,15 +95,13 @@ class GsCookie:
await self.sqla.mark_invalid(self.cookie, 'error')
return False
# return '您的cookie已经失效, 请重新获取!'
elif retcode == 10101:
if retcode == 10101:
await self.sqla.mark_invalid(self.cookie, 'limit30')
return False
# return '当前查询CK已超过每日30次上限!'
elif retcode == 10102:
if retcode == 10102:
return '当前查询id已经设置了隐私, 无法查询!'
elif retcode == 1034:
if retcode == 1034:
return VERIFY_HINT
else:
return f'API报错, 错误码为{retcode}!'
else:
return True
return f'API报错, 错误码为{retcode}!'
return True

View File

@ -4,10 +4,10 @@ UID_HINT = '你还没有绑定过uid哦!\n请使用[sr绑定uid123456]命令绑
MYS_HINT = '你还没有绑定过mysid哦!\n请使用[绑定mys1234]命令绑定!'
CK_HINT = """你还没有绑定过Cookie哦!发送【ck帮助】获取帮助!
警告:绑定Cookie可能会带来未知的账号风险,请确保信任机器人管理员"""
CHAR_HINT = '您的支援/星海同行角色没有{}的数据哦\n请先把{}放入支援/星海同行中再使用【sr强制刷新】命令来缓存数据进行查询! '
CHAR_HINT = '您的支援/星海同行角色没有{}的数据哦!\n请先把{}放入支援/星海同行中再使用【sr强制刷新】命令来缓存数据进行查询! !'
VERIFY_HINT = '''出现验证码!
如已绑定CK: 请至米游社软件->我的->我的角色处解锁验证码
可使用[gs关闭推送]命令关闭体力推送以减少出现验证码风险
(可使用[gs关闭推送]命令关闭体力推送以减少出现验证码风险)
如未绑定CK: 可联系管理员使用[gs清除缓存]命令
'''
SK_HINT = '你还没有绑定过Stoken或者Stoken已失效~\n请群聊发送 [扫码登陆] 或加好友私聊Bot [添加]后跟SK格式 以绑定SK'
@ -20,29 +20,28 @@ UPDATE_HINT = '''更新失败!更多错误信息请查看控制台...
def get_error(retcode: Union[int, str]) -> str:
if retcode == -51:
return CK_HINT
elif retcode == -100:
if retcode == -100:
return '您的cookie已经失效, 请重新获取!'
elif retcode == 10001:
if retcode == 10001:
return '您的cookie已经失效, 请重新获取!'
elif retcode == 10101:
if retcode == 10101:
return '当前查询CK已超过每日30次上限!'
elif retcode == 10102:
if retcode == 10102:
return '当前查询id已经设置了隐私, 无法查询!'
elif retcode == 1034:
if retcode == 1034:
return VERIFY_HINT
elif retcode == -10001:
if retcode == -10001:
return '请求体出错, 请检查具体实现代码...'
elif retcode == 10104:
if retcode == 10104:
return CK_HINT
elif retcode == -512009:
if retcode == -512009:
return '[留影叙佳期]已经获取过该内容~!'
elif retcode == -201:
if retcode == -201:
return '你的账号可能已被封禁, 请联系米游社客服...'
elif retcode == -501101:
if retcode == -501101:
return '当前角色冒险等阶未达到10级, 暂时无法参加此活动...'
elif retcode == 400:
if retcode == 400:
return '[MINIGG]暂未找到此内容...'
elif retcode == -400:
if retcode == -400:
return '请输入更详细的名称...'
else:
return f'API报错, 错误码为{retcode}!'
return f'API报错, 错误码为{retcode}!'

View File

@ -3,17 +3,17 @@ from pathlib import Path
EXCEL = Path(__file__).parent
with open(EXCEL / 'RelicMainAffixConfig.json', 'r', encoding='utf8') as f:
with Path.open(EXCEL / 'RelicMainAffixConfig.json', encoding='utf8') as f:
RelicMainAffix = json.load(f)
with open(EXCEL / 'RelicSubAffixConfig.json', 'r', encoding='utf8') as f:
with Path.open(EXCEL / 'RelicSubAffixConfig.json', encoding='utf8') as f:
RelicSubAffix = json.load(f)
with open(EXCEL / 'AvatarPromotionConfig.json', 'r', encoding='utf8') as f:
with Path.open(EXCEL / 'AvatarPromotionConfig.json', encoding='utf8') as f:
AvatarPromotion = json.load(f)
with open(EXCEL / 'EquipmentPromotionConfig.json', 'r', encoding='utf8') as f:
with Path.open(EXCEL / 'EquipmentPromotionConfig.json', encoding='utf8') as f:
EquipmentPromotion = json.load(f)
with open(EXCEL / 'light_cone_ranks.json', 'r', encoding='utf8') as f:
with Path.open(EXCEL / 'light_cone_ranks.json', encoding='utf8') as f:
light_cone_ranks = json.load(f)

View File

@ -1,6 +1,6 @@
from base64 import b64encode
from io import BytesIO
from pathlib import Path
from base64 import b64encode
from typing import Union, overload
import aiofiles
@ -29,7 +29,7 @@ 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
):
) -> str | bytes:
"""
:说明:
将PIL.Image对象转换为bytes或者base64格式
@ -47,7 +47,7 @@ async def convert_img(
if is_base64:
res = 'base64://' + b64encode(res).decode()
return res
elif isinstance(img, bytes):
if isinstance(img, bytes):
pass
else:
async with aiofiles.open(img, 'rb') as fp:
@ -95,12 +95,14 @@ def get_str_size(
continue
line += i
size, _ = font.getsize(line)
if hasattr(font, 'getsize'):
size, _ = font.getsize(line) # type: ignore
else:
size, _, _, _ = font.getbbox(line)
if size >= limit:
result += f'{line}\n'
line = ''
else:
result += line
result += line
return result

View File

@ -41,72 +41,72 @@ class TS(TypedDict):
Icon: Dict[str, str]
with open(MAP / avatarId2Name_fileName, 'r', encoding='UTF-8') as f:
with Path.open(MAP / avatarId2Name_fileName, encoding='UTF-8') as f:
avatarId2Name = msgjson.decode(f.read(), type=Dict[str, str])
with open(MAP / avatarId2EnName_fileName, 'r', encoding='UTF-8') as f:
with Path.open(MAP / avatarId2EnName_fileName, encoding='UTF-8') as f:
avatarId2EnName = msgjson.decode(f.read(), type=Dict[str, str])
with open(MAP / EquipmentID2Name_fileName, 'r', encoding='UTF-8') as f:
with Path.open(MAP / EquipmentID2Name_fileName, encoding='UTF-8') as f:
EquipmentID2Name = msgjson.decode(f.read(), type=Dict[str, str])
with open(MAP / EquipmentID2EnName_fileName, 'r', encoding='UTF-8') as f:
with Path.open(MAP / EquipmentID2EnName_fileName, encoding='UTF-8') as f:
EquipmentID2EnName = msgjson.decode(f.read(), type=Dict[str, str])
with open(MAP / skillId2Name_fileName, 'r', encoding='UTF-8') as f:
with Path.open(MAP / skillId2Name_fileName, encoding='UTF-8') as f:
skillId2Name = msgjson.decode(f.read(), type=Dict[str, str])
with open(MAP / skillId2Type_fileName, 'r', encoding='UTF-8') as f:
with Path.open(MAP / skillId2Type_fileName, encoding='UTF-8') as f:
skillId2Effect = msgjson.decode(f.read(), type=Dict[str, str])
with open(MAP / Property2Name_fileName, 'r', encoding='UTF-8') as f:
with Path.open(MAP / Property2Name_fileName, encoding='UTF-8') as f:
Property2Name = msgjson.decode(f.read(), type=Dict[str, str])
with open(MAP / RelicId2SetId_fileName, 'r', encoding='UTF-8') as f:
with Path.open(MAP / RelicId2SetId_fileName, encoding='UTF-8') as f:
RelicId2SetId = msgjson.decode(f.read(), type=Dict[str, int])
with open(MAP / SetId2Name_fileName, 'r', encoding='UTF-8') as f:
with Path.open(MAP / SetId2Name_fileName, encoding='UTF-8') as f:
SetId2Name = msgjson.decode(f.read(), type=Dict[str, str])
with open(MAP / rankId2Name_fileName, 'r', encoding='UTF-8') as f:
with Path.open(MAP / rankId2Name_fileName, encoding='UTF-8') as f:
rankId2Name = msgjson.decode(f.read(), type=Dict[str, str])
with open(MAP / characterSkillTree_fileName, 'r', encoding='UTF-8') as f:
with Path.open(MAP / characterSkillTree_fileName, encoding='UTF-8') as f:
characterSkillTree = msgjson.decode(f.read(), type=Dict[str, dict])
with open(MAP / avatarId2DamageType_fileName, 'r', encoding='UTF-8') as f:
with Path.open(MAP / avatarId2DamageType_fileName, encoding='UTF-8') as f:
avatarId2DamageType = msgjson.decode(f.read(), type=Dict[str, str])
with open(MAP / 'char_alias.json', 'r', encoding='UTF-8') as f:
with Path.open(MAP / 'char_alias.json', encoding='UTF-8') as f:
alias_data = msgjson.decode(f.read(), type=Dict[str, Dict[str, List]])
with open(MAP / avatarId2Rarity_fileName, 'r', encoding='UTF-8') as f:
with Path.open(MAP / avatarId2Rarity_fileName, encoding='UTF-8') as f:
avatarId2Rarity = msgjson.decode(f.read(), type=Dict[str, str])
with open(
MAP / EquipmentID2AbilityProperty_fileName, 'r', encoding='UTF-8'
with Path.open(
MAP / EquipmentID2AbilityProperty_fileName, encoding='UTF-8'
) as f:
EquipmentID2AbilityProperty = msgjson.decode(
f.read(), type=Dict[str, Dict[str, List]]
)
with open(MAP / RelicSetSkill_fileName, 'r', encoding='UTF-8') as f:
with Path.open(MAP / RelicSetSkill_fileName, encoding='UTF-8') as f:
RelicSetSkill = msgjson.decode(f.read(), type=Dict[str, dict])
with open(MAP / skillId2AttackType_fileName, 'r', encoding='UTF-8') as f:
with Path.open(MAP / skillId2AttackType_fileName, encoding='UTF-8') as f:
skillId2AttackType = msgjson.decode(f.read(), type=Dict[str, str])
with open(MAP / EquipmentID2Rarity_fileName, 'r', encoding='UTF-8') as f:
with Path.open(MAP / EquipmentID2Rarity_fileName, encoding='UTF-8') as f:
EquipmentID2Rarity = msgjson.decode(f.read(), type=Dict[str, int])
with open(MAP / RelicId2Rarity_fileName, 'r', encoding='UTF-8') as f:
with Path.open(MAP / RelicId2Rarity_fileName, encoding='UTF-8') as f:
RelicId2Rarity = msgjson.decode(f.read(), type=Dict[str, int])
with open(MAP / ItemId2Name_fileName, 'r', encoding='UTF-8') as f:
with Path.open(MAP / ItemId2Name_fileName, encoding='UTF-8') as f:
ItemId2Name = msgjson.decode(f.read(), type=Dict[str, str])
with open(MAP / RelicId2MainAffixGroup_fileName, 'r', encoding='UTF-8') as f:
with Path.open(MAP / RelicId2MainAffixGroup_fileName, encoding='UTF-8') as f:
RelicId2MainAffixGroup = msgjson.decode(f.read(), type=Dict[str, int])
with open(MAP / AvatarRelicScore_fileName, 'r', encoding='UTF-8') as f:
with Path.open(MAP / AvatarRelicScore_fileName, encoding='UTF-8') as f:
AvatarRelicScore = msgjson.decode(f.read(), type=List[Dict])

View File

@ -0,0 +1,263 @@
import json
with open('./data/characters.json', 'r', encoding='utf8') as f:
characters = json.load(f)
with open('./data/character_ranks.json', 'r', encoding='utf8') as f:
character_ranks = json.load(f)
with open('./data/character_skills.json', 'r', encoding='utf8') as f:
character_skills = json.load(f)
with open('./data/character_skill_trees.json', 'r', encoding='utf8') as f:
character_skill_trees = json.load(f)
with open('./data/AvatarConfig.json', 'r', encoding='utf8') as f:
AvatarConfig = json.load(f)
with open('./data/TextMapCN.json', 'r', encoding='utf8') as f:
TextMapCN = json.load(f)
with open('./data/TextMapEN.json', 'r', encoding='utf8') as f:
TextMapEN = json.load(f)
with open('./data/EquipmentConfig.json', 'r', encoding='utf8') as f:
EquipmentConfig = json.load(f)
with open('./data/AvatarSkillConfig.json', 'r', encoding='utf8') as f:
AvatarSkillConfig = json.load(f)
with open('./data/AvatarPropertyConfig.json', 'r', encoding='utf8') as f:
AvatarPropertyConfig = json.load(f)
with open('./data/EquipmentSkillConfig.json', 'r', encoding='utf8') as f:
EquipmentSkillConfig = json.load(f)
with open('./data/RelicConfig.json', 'r', encoding='utf8') as f:
RelicConfig = json.load(f)
with open('./data/RelicSetConfig.json', 'r', encoding='utf8') as f:
RelicSetConfig = json.load(f)
with open('./data/RelicSetSkillConfig.json', 'r', encoding='utf8') as f:
RelicSetSkillConfig = json.load(f)
with open('./data/light_cones.json', 'r', encoding='utf8') as f:
light_cones = json.load(f)
with open('./data/relics_new.json', 'r', encoding='utf8') as f:
relics_new = json.load(f)
with open('./data/ItemConfigRelic.json', 'r', encoding='utf8') as f:
ItemConfigRelic = json.load(f)
avatarId2Name = {}
avatarId2EnName = {}
avatarId2DamageType = {}
avatarId2Rarity = {}
rankId2Name = {}
EquipmentID2Name = {}
EquipmentID2EnName = {}
EquipmentID2Rarity = {}
skillId2Name = {}
skillId2Type = {}
Property2Name = {}
Relic2SetId = {}
SetId2Name = {}
characterSkillTree = {}
EquipmentID2AbilityProperty = {}
RelicSetSkill = {}
skillId2AttackType = {}
RelicId2Rarity = {}
ItemId2Name = {}
RelicId2MainAffixGroup = {}
for char in characters:
char_item = characters[char]
rank_list = characters[char]['ranks']
rarity = characters[char]['rarity']
avatarId2Rarity[char] = str(rarity)
for rank in rank_list:
if character_ranks.get(str(rank)):
eidolon = character_ranks[str(rank)]
rank_id = eidolon['id']
rank_name = eidolon['name']
rankId2Name[rank_id] = rank_name
for item in AvatarConfig:
avatar_item = AvatarConfig[item]
avatar_id = avatar_item['AvatarID']
avatar_name_hash = avatar_item['AvatarName']['Hash']
avatar_damage_type = avatar_item['DamageType']
for item in TextMapCN:
if str(item) == str(avatar_name_hash):
avatar_name = TextMapCN[item]
if avatar_name == '{NICKNAME}':
avatar_name = '开拓者'
break
for item in TextMapEN:
if str(item) == str(avatar_name_hash):
avatar_en_name = TextMapEN[item].replace(' ', '')
break
avatarId2EnName[avatar_id] = avatar_en_name
avatarId2Name[avatar_id] = avatar_name
avatarId2DamageType[avatar_id] = avatar_damage_type
for item in EquipmentConfig:
equipment_item = EquipmentConfig[item]
equipment_id = equipment_item['EquipmentID']
equipment_name_hash = equipment_item['EquipmentName']['Hash']
for item in TextMapCN:
if str(item) == str(equipment_name_hash):
equipment_name = TextMapCN[item]
break
EquipmentID2Name[equipment_id] = equipment_name
for item in EquipmentSkillConfig:
equipment_item = EquipmentSkillConfig[item]
EquipmentID2AbilityProperty[str(item)] = {}
for i in equipment_item:
equipment_ability_property = equipment_item[str(i)]['AbilityProperty']
EquipmentID2AbilityProperty[str(item)][i] = equipment_ability_property
for item in EquipmentConfig:
equipment_item = EquipmentConfig[item]
equipment_id = equipment_item['EquipmentID']
equipment_name_hash = equipment_item['EquipmentName']['Hash']
for item in TextMapEN:
if str(item) == str(equipment_name_hash):
equipment_name = TextMapEN[item].replace(' ', '')
break
EquipmentID2EnName[equipment_id] = equipment_name
for skill in AvatarSkillConfig:
skill_item = AvatarSkillConfig[skill]
skill_id = skill_item['1']['SkillID']
skill_name_hash = skill_item['1']['SkillName']['Hash']
skill_type_hash = skill_item['1']['SkillTag']['Hash']
skill_attack_type = skill_item['1'].get('AttackType', '')
for item in TextMapCN:
if str(item) == str(skill_name_hash):
skill_name = TextMapCN[item]
break
skillId2Name[skill_id] = skill_name
for item in TextMapCN:
if str(item) == str(skill_type_hash):
skill_type = TextMapCN[item]
break
skillId2Type[skill_id] = skill_type
skillId2AttackType[skill_id] = skill_attack_type
for avatar_property in AvatarPropertyConfig:
PropertyType = AvatarPropertyConfig[avatar_property]['PropertyType']
PropertyName = AvatarPropertyConfig[avatar_property]['PropertyName']
PropertyNameHash = AvatarPropertyConfig[avatar_property]['PropertyNameFilter']['Hash']
for item in TextMapCN:
if str(item) == str(PropertyNameHash):
Property_Name = TextMapCN[item]
break
Property2Name[PropertyType] = Property_Name
for relic in RelicConfig:
Relic2SetId[relic] = RelicConfig[relic]['SetID']
RelicId2MainAffixGroup[relic] = RelicConfig[relic]['MainAffixGroup']
for set_group in RelicSetConfig:
set_name_hash = RelicSetConfig[set_group]['SetName']['Hash']
for item in TextMapCN:
if str(item) == str(set_name_hash):
set_name = TextMapCN[item]
break
SetId2Name[set_group] = set_name
for character in characters:
char_id = characters[character]['id']
characterSkillTree[str(char_id)] = {} if str(char_id) not in characterSkillTree else characterSkillTree[str(char_id)]
skill_tree_list = characters[character]['skill_trees']
for skill in skill_tree_list:
skill_tree = character_skill_trees[skill]
characterSkillTree[str(char_id)][str(skill)] = skill_tree
for set_ in RelicSetSkillConfig:
for item in RelicSetSkillConfig[set_]:
set_id = RelicSetSkillConfig[set_][item]['SetID']
property_list = RelicSetSkillConfig[set_][item]['PropertyList']
RelicSetSkill[set_] = {} if set_ not in RelicSetSkill else RelicSetSkill[set_]
RelicSetSkill[set_][item] = {} if item not in RelicSetSkill[set_] else RelicSetSkill[set_][item]
for property_ in property_list:
property_id = property_['NAOGDGBJNOJ']
property_value = property_['MBOHKHKHFPD']['Value']
RelicSetSkill[set_][item]['Property'] = property_id
RelicSetSkill[set_][item]['Value'] = property_value
for light_cone in light_cones:
rarity = light_cones[light_cone]['rarity']
light_cone_id = light_cones[light_cone]['id']
EquipmentID2Rarity[light_cone_id] = rarity
for item in relics_new:
rarity = relics_new[item]['rarity']
relic_id = relics_new[item]['id']
RelicId2Rarity[relic_id] = rarity
for item in ItemConfigRelic:
item_id = ItemConfigRelic[item]['ID']
item_name_hash = ItemConfigRelic[item]['ItemName']['Hash']
for item in TextMapCN:
if str(item) == str(item_name_hash):
item_name = TextMapCN[item]
break
ItemId2Name[item_id] = item_name
rankId2Name = json.dumps(rankId2Name, ensure_ascii=False)
avatarId2Name = json.dumps(avatarId2Name, ensure_ascii=False)
avatarId2EnName = json.dumps(avatarId2EnName, ensure_ascii=False)
avatarId2DamageType = json.dumps(avatarId2DamageType, ensure_ascii=False)
avatarId2Rarity = json.dumps(avatarId2Rarity, ensure_ascii=False)
EquipmentID2Name = json.dumps(EquipmentID2Name, ensure_ascii=False)
EquipmentID2EnName = json.dumps(EquipmentID2EnName, ensure_ascii=False)
skillId2Name = json.dumps(skillId2Name, ensure_ascii=False)
skillId2Type = json.dumps(skillId2Type, ensure_ascii=False)
Property2Name = json.dumps(Property2Name, ensure_ascii=False)
Relic2SetId = json.dumps(Relic2SetId, ensure_ascii=False)
SetId2Name = json.dumps(SetId2Name, ensure_ascii=False)
characterSkillTree = json.dumps(characterSkillTree, ensure_ascii=False)
EquipmentID2AbilityProperty = json.dumps(EquipmentID2AbilityProperty, ensure_ascii=False)
RelicSetSkill = json.dumps(RelicSetSkill, ensure_ascii=False)
skillId2AttackType = json.dumps(skillId2AttackType, ensure_ascii=False)
EquipmentID2Rarity = json.dumps(EquipmentID2Rarity, ensure_ascii=False)
RelicId2Rarity = json.dumps(RelicId2Rarity, ensure_ascii=False)
ItemId2Name = json.dumps(ItemId2Name, ensure_ascii=False)
RelicId2MainAffixGroup = json.dumps(RelicId2MainAffixGroup, ensure_ascii=False)
print(avatarId2Name)
print(avatarId2EnName)
print(EquipmentID2Name)
print(EquipmentID2EnName)
print(skillId2Name)
print(Property2Name)
print(Relic2SetId)
print(SetId2Name)
print(skillId2Type)
print(rankId2Name)
print(characterSkillTree)
print(avatarId2DamageType)
print(avatarId2Rarity)
print(EquipmentID2AbilityProperty)
print(RelicSetSkill)
print(skillId2AttackType)
print(EquipmentID2Rarity)
print(RelicId2Rarity)
print(ItemId2Name)
print(RelicId2MainAffixGroup)

View File

@ -8,8 +8,7 @@ from .SR_MAP_PATH import (
async def avatar_id_to_name(avatar_id: str) -> str:
char_name = avatarId2Name[avatar_id]
return char_name
return avatarId2Name[avatar_id]
async def name_to_avatar_id(name: str) -> str:
@ -22,8 +21,7 @@ async def name_to_avatar_id(name: str) -> str:
async def avatar_id_to_char_star(char_id: str) -> str:
char_star = avatarId2Rarity[str(char_id)]
return char_star
return avatarId2Rarity[str(char_id)]
async def alias_to_char_name(char_name: str) -> str:
@ -34,8 +32,7 @@ async def alias_to_char_name(char_name: str) -> str:
async def weapon_id_to_name(weapon_id: str) -> str:
weapon_name = EquipmentID2Name[weapon_id]
return weapon_name
return EquipmentID2Name[weapon_id]
async def name_to_weapon_id(name: str) -> str:
@ -48,8 +45,7 @@ async def name_to_weapon_id(name: str) -> str:
async def weapon_id_to_en_name(weapon_id: str) -> str:
weapon_en_name = EquipmentID2EnName[weapon_id]
return weapon_en_name
return EquipmentID2EnName[weapon_id]
async def en_name_to_weapon_id(name: str) -> str:

View File

@ -7,3 +7,4 @@ async def send_diff_msg(bot: Bot, code: Any, data: Dict):
for retcode in data:
if code == retcode:
return await bot.send(data[retcode])
return None

View File

@ -367,8 +367,10 @@ class MysApi(_MysApi):
return data
async def mys_sign(
self, uid, header={}, server_id='cn_gf01'
self, uid, header=None, server_id='cn_gf01'
) -> Union[MysSign, int]:
if header is None:
header = {}
ck = await self.get_ck(uid, 'OWNER')
if ck is None:
return -51

View File

@ -1,21 +1,21 @@
import os
import asyncio
from pathlib import Path
from typing import Dict, List, Tuple, Union
from typing import Dict, List, Tuple
from msgspec import json as msgjson
from gsuid_core.logger import logger
from aiohttp.client import ClientSession
from msgspec import json as msgjson
from gsuid_core.logger import logger
from .download_url import download_file
from .RESOURCE_PATH import WIKI_PATH, GUIDE_PATH, RESOURCE_PATH
from .RESOURCE_PATH import GUIDE_PATH, RESOURCE_PATH, WIKI_PATH
with open(
Path(__file__).parent / 'resource_map.json', 'r', encoding='UTF-8'
with Path.open(
Path(__file__).parent / 'resource_map.json', encoding='UTF-8'
) as f:
resource_map = msgjson.decode(
f.read(),
type=Dict[str, Dict[str, Dict[str, Dict[str, Union[int, str]]]]],
type=Dict[str, Dict[str, Dict[str, Dict[str, str | int]]]],
)
@ -74,16 +74,21 @@ async def download_all_file_from_cos():
else:
path = Path(GUIDE_PATH / resource_type / name)
if path.exists():
is_diff = size == os.stat(path).st_size
is_diff = size == Path.stat(path).st_size
else:
is_diff = True
if (
not path.exists()
or not os.stat(path).st_size
or not Path.stat(path).st_size
or not is_diff
):
logger.info(f'[cos]开始下载[{resource_type}]_[{name}]...')
temp_num += 1
if isinstance(url, int):
logger.error(
f'[cos]数据库[{resource_type}]_[{name}]下载失败!'
)
continue
TASKS.append(
asyncio.wait_for(
download_file(
@ -95,8 +100,7 @@ async def download_all_file_from_cos():
# await download_file(url, FILE_TO_PATH[file], name)
if len(TASKS) >= 10:
await _download(TASKS)
else:
await _download(TASKS)
await _download(TASKS)
if temp_num == 0:
im = f'[cos]数据库[{resource_type}]无需下载!'
else:
@ -114,7 +118,6 @@ async def download_all_file_from_cos():
)
if len(TASKS) >= 10:
await _download(TASKS)
else:
await _download(TASKS)
await _download(TASKS)
if count := len(failed_list):
logger.error(f'[cos]仍有{count}个文件未下载请使用命令 `下载全部资源` 重新下载')
logger.error(f'[cos]仍有{count}个文件未下载,请使用命令 `下载全部资源` 重新下载')

View File

@ -1,11 +1,12 @@
from typing import Tuple, Optional
from typing import Optional, Tuple
import aiofiles
from gsuid_core.logger import logger
from aiohttp.client import ClientSession
from aiohttp.client_exceptions import ClientConnectorError
from .RESOURCE_PATH import WIKI_PATH, GUIDE_PATH, RESOURCE_PATH
from gsuid_core.logger import logger
from .RESOURCE_PATH import GUIDE_PATH, RESOURCE_PATH, WIKI_PATH
PATHDICT = {
'resource': RESOURCE_PATH,
@ -19,7 +20,7 @@ async def download(
res_type: str,
resource_type: str,
name: str,
) -> Optional[Tuple[str, int, str]]:
) -> Optional[Tuple[str, str, str]]:
"""
:说明:
下载URL保存入目录
@ -27,7 +28,7 @@ async def download(
* url: `str`
资源下载地址
* res_type: `str`
资源类型`resource``wiki`
资源类型,`resource``wiki`
* resource_type: `str`
资源文件夹名
* name: `str`
@ -60,3 +61,4 @@ async def download_file(
PATHDICT[res_type] / resource_type / name, "wb"
) as f:
await f.write(content)
return None