支持2.4

This commit is contained in:
baiqwerdvd 2024-07-31 17:11:18 +08:00
parent be48f78136
commit 7b9167d5c2
No known key found for this signature in database
GPG Key ID: 7717E46E1797411A
45 changed files with 57474 additions and 52252 deletions

View File

@ -2,7 +2,7 @@
"python.languageServer": "None",
"editor.formatOnSave": true,
"[python]": {
"editor.defaultFormatter": "ms-python.black-formatter",
"editor.defaultFormatter": "charliermarsh.ruff",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.organizeImports": "explicit"

View File

@ -1,5 +1,5 @@
"""Mihomo.me api 包装
"""
"""Mihomo.me api 包装"""
from .models import MihomoData as MihomoData
from .requests import get_char_card_info as requests

View File

@ -0,0 +1,46 @@
from typing import TYPE_CHECKING
from ..utils.convert import get_uid
from ..utils.error_reply import UID_HINT
from ..utils.map.name_covert import (
alias_to_char_name,
name_to_avatar_id,
)
from ..utils.mys_api import mys_api
from ..utils.sr_prefix import PREFIX
from gsuid_core.sv import SV
from gsuid_core.utils.error_reply import get_error
if TYPE_CHECKING:
from gsuid_core.bot import Bot
from gsuid_core.models import Event
sv_char_calc = SV('sr养成计算')
@sv_char_calc.on_command(f'{PREFIX}养成计算', block=True)
async def send_char_calc_info(bot: 'Bot', ev: 'Event'):
name = ev.text.strip()
char_id = await name_to_avatar_id(name)
if char_id == '':
result_fake_name = await alias_to_char_name(name)
if result_fake_name is None:
return '请输入正确的角色名'
fake_name = result_fake_name
char_id = await name_to_avatar_id(fake_name)
uid = await get_uid(bot, ev, only_uid=True)
if uid is None:
return await bot.send(UID_HINT)
avatar_detail = await mys_api.get_avatar_detail(uid, str(char_id))
if isinstance(avatar_detail, int):
return get_error(avatar_detail)
avatar_skills = avatar_detail.skills + avatar_detail.skills_other
skill_list = []
for skill in avatar_skills:
skill_list.append(
f'{skill.point_id}({skill.cur_level}/{skill.max_level})'
)
return None

View File

@ -95,7 +95,9 @@ RELIC_CNT = {
}
async def draw_char_img(char_data: Dict, sr_uid: str, msg: str) -> Union[bytes, str]:
async def draw_char_img(
char_data: Dict, sr_uid: str, msg: str
) -> Union[bytes, str]:
if isinstance(char_data, str):
return char_data
char = await cal_char_info(char_data)
@ -132,7 +134,9 @@ async def draw_char_img(char_data: Dict, sr_uid: str, msg: str) -> Union[bytes,
# 放角色名
char_img_draw = ImageDraw.Draw(char_info)
char_img_draw.text((620, 162), char.char_name, (255, 255, 255), sr_font_38, 'lm')
char_img_draw.text(
(620, 162), 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] # type: ignore
else:
@ -184,7 +188,9 @@ async def draw_char_img(char_data: Dict, sr_uid: str, msg: str) -> Union[bytes,
0,
)
)
attr_bg_draw.text((413, 31), f'{hp + add_hp}', white_color, sr_font_26, 'rm')
attr_bg_draw.text(
(413, 31), f'{hp + add_hp}', white_color, sr_font_26, 'rm'
)
attr_bg_draw.text(
(428, 31),
f'(+{round(add_hp)!s})',
@ -275,7 +281,9 @@ async def draw_char_img(char_data: Dict, sr_uid: str, msg: str) -> Union[bytes,
'rm',
)
# 效果命中
status_probability_base = char.add_attr.get('StatusProbabilityBase', 0) * 100
status_probability_base = (
char.add_attr.get('StatusProbabilityBase', 0) * 100
)
attr_bg_draw.text(
(500, 31 + 48 * 6),
f'{status_probability_base:.1f}%',
@ -293,7 +301,9 @@ async def draw_char_img(char_data: Dict, sr_uid: str, msg: str) -> Union[bytes,
'rm',
)
# 击破特攻
status_resistance_base = char.add_attr.get('BreakDamageAddedRatioBase', 0) * 100
status_resistance_base = (
char.add_attr.get('BreakDamageAddedRatioBase', 0) * 100
)
attr_bg_draw.text(
(500, 31 + 48 * 8),
f'{status_resistance_base:.1f}%',
@ -409,7 +419,8 @@ async def draw_char_img(char_data: Dict, sr_uid: str, msg: str) -> Union[bytes,
weapon_bg.paste(rank_img, (weapon_name_len + 330, 2), rank_img)
rarity_img = Image.open(
TEXT_PATH / f'LightCore_Rarity{char.equipment["equipmentRarity"]}.png'
TEXT_PATH
/ f'LightCore_Rarity{char.equipment["equipmentRarity"]}.png'
).resize((306, 72))
weapon_bg.paste(rarity_img, (223, 55), rarity_img)
weapon_bg_draw.text(
@ -422,9 +433,9 @@ async def draw_char_img(char_data: Dict, sr_uid: str, msg: str) -> Union[bytes,
# 武器技能
desc = light_cone_ranks[str(char.equipment['equipmentID'])]['desc']
desc_params = light_cone_ranks[str(char.equipment['equipmentID'])]['params'][
char.equipment['equipmentRank'] - 1
]
desc_params = light_cone_ranks[str(char.equipment['equipmentID'])][
'params'
][char.equipment['equipmentRank'] - 1]
for i in range(len(desc_params)):
temp = math.floor(desc_params[i] * 1000) / 10
desc = desc.replace(f'#{i + 1}[i]%', f'{temp!s}%')
@ -594,7 +605,9 @@ async def draw_char_img(char_data: Dict, sr_uid: str, msg: str) -> Union[bytes,
anchor='rm',
)
char_info.paste(relic_img, RELIC_POS[str(relic['Type'])], relic_img)
char_info.paste(
relic_img, RELIC_POS[str(relic['Type'])], relic_img
)
relic_score += single_relic_score
if relic_score > 210:
relic_value_level = Image.open(TEXT_PATH / 'CommonIconSSS.png')
@ -666,7 +679,9 @@ async def draw_char_img(char_data: Dict, sr_uid: str, msg: str) -> Union[bytes,
damage_img = Image.open(TEXT_PATH / 'attack_1.png')
else:
damage_img = Image.open(TEXT_PATH / 'attack_2.png')
char_info.paste(damage_img, (0, 2028 + damage_num * 48), damage_img)
char_info.paste(
damage_img, (0, 2028 + damage_num * 48), damage_img
)
char_img_draw.text(
(55, 2048 + damage_num * 48),
f'{damage_info["name"]}',
@ -821,7 +836,9 @@ async def get_relic_score(
add_value = subValue * 0.3 * 0.5 * weight_dict['AttackDelta'] * 1.0
relic_score += add_value
if subProperty == 'DefenceDelta':
add_value = subValue * 0.3 * 0.5 * weight_dict['DefenceDelta'] * 1.0
add_value = (
subValue * 0.3 * 0.5 * weight_dict['DefenceDelta'] * 1.0
)
relic_score += add_value
if subProperty == 'HPDelta':
add_value = subValue * 0.158 * 0.5 * weight_dict['HPDelta'] * 1.0
@ -830,7 +847,9 @@ async def get_relic_score(
add_value = subValue * 1.5 * weight_dict['AttackAddedRatio'] * 100
relic_score += add_value
if subProperty == 'DefenceAddedRatio':
add_value = subValue * 1.19 * weight_dict['DefenceAddedRatio'] * 100
add_value = (
subValue * 1.19 * weight_dict['DefenceAddedRatio'] * 100
)
relic_score += add_value
if subProperty == 'HPAddedRatio':
add_value = subValue * 1.5 * weight_dict['HPAddedRatio'] * 100
@ -839,12 +858,18 @@ async def get_relic_score(
add_value = subValue * 2.53 * weight_dict['SpeedDelta']
relic_score += add_value
if subProperty == 'BreakDamageAddedRatioBase':
add_value = subValue * 1.0 * weight_dict['BreakDamageAddedRatioBase'] * 100
add_value = (
subValue * 1.0 * weight_dict['BreakDamageAddedRatioBase'] * 100
)
relic_score += add_value
if subProperty == 'StatusProbabilityBase':
add_value = subValue * 1.49 * weight_dict['StatusProbabilityBase'] * 100
add_value = (
subValue * 1.49 * weight_dict['StatusProbabilityBase'] * 100
)
relic_score += add_value
if subProperty == 'StatusResistanceBase':
add_value = subValue * 1.49 * weight_dict['StatusResistanceBase'] * 100
add_value = (
subValue * 1.49 * weight_dict['StatusResistanceBase'] * 100
)
relic_score += add_value
return relic_score

View File

@ -97,11 +97,7 @@ async def get_char_args(
char_data = {}
weapon, weapon_affix = None, None
msg = (
msg.replace('', '')
.replace('', '')
.replace('圣遗物', '遗器')
)
msg = msg.replace('', '').replace('', '').replace('圣遗物', '遗器')
# 希儿带于夜色中换1000xxxx6希儿头
msg_list = msg.split('')
@ -132,13 +128,17 @@ async def get_char_args(
if isinstance(char_data, str):
return char_data
else:
for i, s in enumerate(['头部', '手部', '躯干', '腿部', '位面球', '连结绳']):
for i, s in enumerate(
['头部', '手部', '躯干', '腿部', '位面球', '连结绳']
):
if '赤沙' in part:
continue
if part[-1] in PieceName_ilst[i]:
if isinstance(char_data, str):
return char_data
char_data = await change_equip(changeuid, char_data, part, s, i)
char_data = await change_equip(
changeuid, char_data, part, s, i
)
if not char_data:
change_name = part.replace(part[-1], '')
return f'要替换的{change_name}{s}遗器不存在噢~'
@ -149,7 +149,9 @@ async def get_char_args(
return char_data, weapon, weapon_affix, talent_num
async def change_equip(uid: str, char_data: Dict, part: str, s: str, i: int) -> Dict:
async def change_equip(
uid: str, char_data: Dict, part: str, s: str, i: int
) -> Dict:
char_name = part.replace(part[-1], '').replace(uid, '')
fake_data = await get_char_data(uid, char_name)
if isinstance(fake_data, str):
@ -176,7 +178,9 @@ async def get_fake_char_str(char_name: str) -> Tuple[str, Optional[int]]:
"""
talent_num = None
if ('' in char_name or '' in char_name) and char_name[0] in CHAR_TO_INT:
if ('' in char_name or '' in char_name) and char_name[
0
] in CHAR_TO_INT:
talent_num = CHAR_TO_INT[char_name[0]]
char_name = char_name[2:]
return char_name, talent_num
@ -258,18 +262,28 @@ async def make_new_charinfo(
char_id = await name_to_avatar_id(fake_name)
char_data['avatarId'] = int(char_id)
char_data['avatarName'] = fake_name
char_data['avatarElement'] = avatarId2DamageType[str(char_data['avatarId'])]
char_data['avatarRarity'] = str(avatarId2Rarity[str(char_data['avatarId'])])
char_data['avatarElement'] = avatarId2DamageType[
str(char_data['avatarId'])
]
char_data['avatarRarity'] = str(
avatarId2Rarity[str(char_data['avatarId'])]
)
char_data['avatarPromotion'] = 6
char_data['avatarLevel'] = 80
char_data['avatarSkill'] = await get_skill_list(char_data['avatarId'])
char_data['avatarExtraAbility'] = await get_extra_list(char_data['avatarId'])
char_data['avatarAttributeBonus'] = await get_attribute_list(char_data['avatarId'])
char_data['avatarExtraAbility'] = await get_extra_list(
char_data['avatarId']
)
char_data['avatarAttributeBonus'] = await get_attribute_list(
char_data['avatarId']
)
char_data['RelicInfo'] = []
char_data['avatarEnName'] = avatarId2EnName[str(char_data['avatarId'])]
char_data['rank'] = 0
char_data['rankList'] = []
char_data['baseAttributes'] = await get_baseAttributes(char_data['avatarId'])
char_data['baseAttributes'] = await get_baseAttributes(
char_data['avatarId']
)
char_data['equipmentInfo'] = {}
return char_data
@ -299,9 +313,13 @@ async def get_baseAttributes(
# 速度
base_attributes['speed'] = avatar_promotion_base.SpeedBase.Value
# 暴击率
base_attributes['CriticalChanceBase'] = avatar_promotion_base.CriticalChance.Value
base_attributes['CriticalChanceBase'] = (
avatar_promotion_base.CriticalChance.Value
)
# 暴击伤害
base_attributes['CriticalDamageBase'] = avatar_promotion_base.CriticalDamage.Value
base_attributes['CriticalDamageBase'] = (
avatar_promotion_base.CriticalDamage.Value
)
# 嘲讽
base_attributes['BaseAggro'] = avatar_promotion_base.BaseAggro.Value
return base_attributes
@ -321,7 +339,9 @@ async def get_attribute_list(
attribute_bonus_temp['statusAdd'] = {}
if status_add:
for property_ in status_add:
attribute_bonus_temp['statusAdd']['property'] = property_['type']
attribute_bonus_temp['statusAdd']['property'] = property_[
'type'
]
attribute_bonus_temp['statusAdd']['name'] = Property2Name[
property_['type']
]
@ -351,7 +371,9 @@ async def get_skill_list(
skill_temp['skillId'] = char_id * 100 + skillid
skill_temp['skillName'] = skillId2Name[str(skill_temp['skillId'])]
skill_temp['skillEffect'] = skillId2Effect[str(skill_temp['skillId'])]
skill_temp['skillAttackType'] = skillId2AttackType[str(skill_temp['skillId'])]
skill_temp['skillAttackType'] = skillId2AttackType[
str(skill_temp['skillId'])
]
skilllevel = 10
if skillid == 1:
skilllevel = 6
@ -404,7 +426,9 @@ async def get_char(
skill_id = item['id']
skill_up_num = item['num']
# 查找skill_id在不在avatarSkill中
for index, skill_item in enumerate(char_data['avatarSkill']):
for index, skill_item in enumerate(
char_data['avatarSkill']
):
if str(skill_id) == str(skill_item['skillId']):
if skill_id[-1] == 1:
skilllevel_max = 7
@ -412,7 +436,9 @@ async def get_char(
skilllevel_max = 12
skilllevel = min(
skilllevel_max,
char_data['avatarSkill'][index]['skillLevel']
char_data['avatarSkill'][index][
'skillLevel'
]
+ skill_up_num,
)
char_data['avatarSkill'][index][
@ -433,11 +459,13 @@ async def get_char(
equipment_info['equipmentLevel'] = 80
equipment_info['equipmentPromotion'] = 6
equipment_info['equipmentRank'] = weapon_affix
equipment_info['equipmentRarity'] = EquipmentID2Rarity[str(equipmentid)]
equipment_base_attributes = {}
equipment_promotion_base = EquipmentPromotionConfig.Equipment[str(equipmentid)][
'6'
equipment_info['equipmentRarity'] = EquipmentID2Rarity[
str(equipmentid)
]
equipment_base_attributes = {}
equipment_promotion_base = EquipmentPromotionConfig.Equipment[
str(equipmentid)
]['6']
# 生命值
equipment_base_attributes['hp'] = (

View File

@ -62,7 +62,9 @@ async def draw_enka_card(uid: str, char_list: List, showfrom: int = 0):
return await convert_img(Image.new('RGBA', (0, 1), (255, 255, 255)))
else:
line1 = f'UID {uid} 刷新成功'
line2 = f'可以使用 sr查询{char_data_list[0]["avatarName"]} 查询详情角色面板'
line2 = (
f'可以使用 sr查询{char_data_list[0]["avatarName"]} 查询详情角色面板'
)
char_num = len(char_data_list)
if char_num <= 4:
based_w, based_h = 1380, 926

View File

@ -1,12 +1,12 @@
from gsuid_core.sv import SV
from gsuid_core.bot import Bot
from gsuid_core.models import Event
from gsuid_core.logger import logger
from gsuid_core.utils.database.models import GsBind
from .set_config import set_config_func
from ..starrailuid_config.sr_config import srconfig
from gsuid_core.bot import Bot
from gsuid_core.logger import logger
from gsuid_core.models import Event
from gsuid_core.sv import SV
from gsuid_core.utils.database.models import GsBind
PREFIX = srconfig.get_config('StarRailPrefix').data
sv_self_config = SV('星穹铁道配置')
@ -16,6 +16,9 @@ sv_self_config = SV('星穹铁道配置')
async def open_switch_func(bot: Bot, ev: Event):
uid = await GsBind.get_uid_by_game(ev.user_id, ev.bot_id, 'sr')
if uid is None:
return await bot.send('[星穹铁道] 你还没有绑定UID哦')
logger.info(f'[{ev.user_id}] [UID{uid}]尝试[{ev.command[2:]}]了[{ev.text}]功能')
return await bot.send('[星穹铁道] 你还没有绑定UID哦!')
logger.info(
f'[{ev.user_id}] [UID{uid}]尝试[{ev.command[2:]}]了[{ev.text}]功能'
)
await bot.send(await set_config_func(uid, ev))
return None

View File

@ -1,7 +1,7 @@
from gsuid_core.models import Event
from gsuid_core.logger import logger
from gsuid_core.utils.database.models import GsUser
from gsuid_core.models import Event
from gsuid_core.utils.database.config_switch import set_database_value
from gsuid_core.utils.database.models import GsUser
async def set_config_func(
@ -11,8 +11,7 @@ async def set_config_func(
if '开启' in ev.command:
if ev.user_type == 'direct':
value = 'on'
else:
if ev.group_id:
elif ev.group_id:
value = ev.group_id
else:
value = 'on'
@ -30,6 +29,5 @@ async def set_config_func(
)
if text is None:
return '[星穹铁道] 未找到配置项'
else:
logger.success(f'[UID{uid}]成功将配置[SR自动签到]设置为[{value}]!')
return text

View File

@ -70,7 +70,9 @@ async def get_role_img(uid: str) -> Union[bytes, str]:
return await draw_role_card(uid)
async def get_detail_img(qid: Union[str, int], uid: str, sender) -> Union[bytes, str]:
async def get_detail_img(
qid: Union[str, int], uid: str, sender
) -> Union[bytes, str]:
return await get_detail_card(qid, uid, sender)

View File

@ -1,15 +1,15 @@
from gsuid_core.sv import SV
from gsuid_core.bot import Bot
from gsuid_core.models import Event
from gsuid_core.aps import scheduler
from gsuid_core.logger import logger
from gsuid_core.utils.database.models import GsBind
from gsuid_core.utils.sign.sign import sign_in, daily_sign
from gsuid_core.utils.boardcast.send_msg import send_board_cast_msg
from ..utils.sr_prefix import PREFIX
from ..utils.error_reply import UID_HINT
from ..starrailuid_config.sr_config import srconfig
from ..utils.error_reply import UID_HINT
from ..utils.sr_prefix import PREFIX
from gsuid_core.aps import scheduler
from gsuid_core.bot import Bot
from gsuid_core.logger import logger
from gsuid_core.models import Event
from gsuid_core.sv import SV
from gsuid_core.utils.boardcast.send_msg import send_board_cast_msg
from gsuid_core.utils.database.models import GsBind
from gsuid_core.utils.sign.sign import daily_sign, sign_in
SIGN_TIME = srconfig.get_config('SignTime').data
IS_REPORT = srconfig.get_config('PrivateSignReport').data
@ -26,6 +26,7 @@ async def get_sign_func(bot: Bot, ev: Event):
return await bot.send(UID_HINT)
logger.info(f'[星穹铁道] [签到] UID: {uid}')
await bot.send(await sign_in(uid, 'sr'))
return None
@sv_sign_config.on_fullmatch(f'{PREFIX}全部重签')

View File

@ -9,15 +9,13 @@ from gsuid_core.utils.database.models import GsBind
@overload
async def get_uid(
bot: Bot, ev: Event, get_user_id: bool = False, only_uid: bool = False
) -> Optional[str]:
...
) -> Optional[str]: ...
@overload
async def get_uid(
bot: Bot, ev: Event, get_user_id: bool = True, only_uid: bool = False
) -> Tuple[Optional[str], str]:
...
) -> Tuple[Optional[str], str]: ...
async def get_uid(

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,78 +1,77 @@
[
{
"2": {
"1": {
"GroupID": 2,
"AffixID": 1,
"Property": "HPDelta",
"BaseValue": {
"Value": 13.548016000073403
"Value": 13.548016
},
"StepValue": {
"Value": 1.693502000765875
"Value": 1.693502
},
"StepNum": 2
},
"2": {
{
"GroupID": 2,
"AffixID": 2,
"Property": "AttackDelta",
"BaseValue": {
"Value": 6.774008000502363
"Value": 6.774008
},
"StepValue": {
"Value": 0.8467510011978447
"Value": 0.846751
},
"StepNum": 2
},
"3": {
{
"GroupID": 2,
"AffixID": 3,
"Property": "DefenceDelta",
"BaseValue": {
"Value": 6.774008000502363
"Value": 6.774008
},
"StepValue": {
"Value": 0.8467510011978447
"Value": 0.846751
},
"StepNum": 2
},
"4": {
{
"GroupID": 2,
"AffixID": 4,
"Property": "HPAddedRatio",
"BaseValue": {
"Value": 0.013824000488966703
"Value": 0.013824001
},
"StepValue": {
"Value": 0.0017280005849897861
"Value": 0.0017280006
},
"StepNum": 2
},
"5": {
{
"GroupID": 2,
"AffixID": 5,
"Property": "AttackAddedRatio",
"BaseValue": {
"Value": 0.013824000488966703
"Value": 0.013824001
},
"StepValue": {
"Value": 0.0017280005849897861
"Value": 0.0017280006
},
"StepNum": 2
},
"6": {
{
"GroupID": 2,
"AffixID": 6,
"Property": "DefenceAddedRatio",
"BaseValue": {
"Value": 0.017280000261962414
"Value": 0.017280001
},
"StepValue": {
"Value": 0.002160000381991267
"Value": 0.0021600004
},
"StepNum": 2
},
"7": {
{
"GroupID": 2,
"AffixID": 7,
"Property": "SpeedDelta",
@ -80,437 +79,431 @@
"Value": 1
},
"StepValue": {
"Value": 0.10000000009313226
"Value": 0.1
},
"StepNum": 2
},
"8": {
{
"GroupID": 2,
"AffixID": 8,
"Property": "CriticalChanceBase",
"BaseValue": {
"Value": 0.010368000715970993
"Value": 0.010368001
},
"StepValue": {
"Value": 0.001296000787988305
"Value": 0.0012960008
},
"StepNum": 2
},
"9": {
{
"GroupID": 2,
"AffixID": 9,
"Property": "CriticalDamageBase",
"BaseValue": {
"Value": 0.020736000733450055
"Value": 0.020736001
},
"StepValue": {
"Value": 0.0025920008774846792
"Value": 0.0025920009
},
"StepNum": 2
},
"10": {
{
"GroupID": 2,
"AffixID": 10,
"Property": "StatusProbabilityBase",
"BaseValue": {
"Value": 0.013824000488966703
"Value": 0.013824001
},
"StepValue": {
"Value": 0.0017280005849897861
"Value": 0.0017280006
},
"StepNum": 2
},
"11": {
{
"GroupID": 2,
"AffixID": 11,
"Property": "StatusResistanceBase",
"BaseValue": {
"Value": 0.013824000488966703
"Value": 0.013824001
},
"StepValue": {
"Value": 0.0017280005849897861
"Value": 0.0017280006
},
"StepNum": 2
},
"12": {
{
"GroupID": 2,
"AffixID": 12,
"Property": "BreakDamageAddedRatioBase",
"BaseValue": {
"Value": 0.020736000733450055
"Value": 0.020736001
},
"StepValue": {
"Value": 0.0025920008774846792
"Value": 0.0025920009
},
"StepNum": 2
}
},
"3": {
"1": {
{
"GroupID": 3,
"AffixID": 1,
"Property": "HPDelta",
"BaseValue": {
"Value": 20.32202300033532
"Value": 20.322023
},
"StepValue": {
"Value": 2.540253001032397
"Value": 2.540253
},
"StepNum": 2
},
"2": {
{
"GroupID": 3,
"AffixID": 2,
"Property": "AttackDelta",
"BaseValue": {
"Value": 10.161012000171468
"Value": 10.161012
},
"StepValue": {
"Value": 1.2701260005123913
"Value": 1.270126
},
"StepNum": 2
},
"3": {
{
"GroupID": 3,
"AffixID": 3,
"Property": "DefenceDelta",
"BaseValue": {
"Value": 10.161012000171468
"Value": 10.161012
},
"StepValue": {
"Value": 1.2701260005123913
"Value": 1.270126
},
"StepNum": 2
},
"4": {
{
"GroupID": 3,
"AffixID": 4,
"Property": "HPAddedRatio",
"BaseValue": {
"Value": 0.020736000733450055
"Value": 0.020736001
},
"StepValue": {
"Value": 0.0025920008774846792
"Value": 0.0025920009
},
"StepNum": 2
},
"5": {
{
"GroupID": 3,
"AffixID": 5,
"Property": "AttackAddedRatio",
"BaseValue": {
"Value": 0.020736000733450055
"Value": 0.020736001
},
"StepValue": {
"Value": 0.0025920008774846792
"Value": 0.0025920009
},
"StepNum": 2
},
"6": {
{
"GroupID": 3,
"AffixID": 6,
"Property": "DefenceAddedRatio",
"BaseValue": {
"Value": 0.02592000039294362
"Value": 0.02592
},
"StepValue": {
"Value": 0.0032400002237409353
"Value": 0.0032400002
},
"StepNum": 2
},
"7": {
{
"GroupID": 3,
"AffixID": 7,
"Property": "SpeedDelta",
"BaseValue": {
"Value": 1.2000000001862645
"Value": 1.2
},
"StepValue": {
"Value": 0.10000000009313226
"Value": 0.1
},
"StepNum": 2
},
"8": {
{
"GroupID": 3,
"AffixID": 8,
"Property": "CriticalChanceBase",
"BaseValue": {
"Value": 0.015552000375464559
"Value": 0.015552
},
"StepValue": {
"Value": 0.0019440008327364922
"Value": 0.0019440008
},
"StepNum": 2
},
"9": {
{
"GroupID": 3,
"AffixID": 9,
"Property": "CriticalDamageBase",
"BaseValue": {
"Value": 0.031104000052437186
"Value": 0.031104
},
"StepValue": {
"Value": 0.0038880009669810534
"Value": 0.003888001
},
"StepNum": 2
},
"10": {
{
"GroupID": 3,
"AffixID": 10,
"Property": "StatusProbabilityBase",
"BaseValue": {
"Value": 0.020736000733450055
"Value": 0.020736001
},
"StepValue": {
"Value": 0.0025920008774846792
"Value": 0.0025920009
},
"StepNum": 2
},
"11": {
{
"GroupID": 3,
"AffixID": 11,
"Property": "StatusResistanceBase",
"BaseValue": {
"Value": 0.020736000733450055
"Value": 0.020736001
},
"StepValue": {
"Value": 0.0025920008774846792
"Value": 0.0025920009
},
"StepNum": 2
},
"12": {
{
"GroupID": 3,
"AffixID": 12,
"Property": "BreakDamageAddedRatioBase",
"BaseValue": {
"Value": 0.031104000052437186
"Value": 0.031104
},
"StepValue": {
"Value": 0.0038880009669810534
"Value": 0.003888001
},
"StepNum": 2
}
},
"4": {
"1": {
{
"GroupID": 4,
"AffixID": 1,
"Property": "HPDelta",
"BaseValue": {
"Value": 27.09603099990636
"Value": 27.096031
},
"StepValue": {
"Value": 3.3870039999019355
"Value": 3.387004
},
"StepNum": 2
},
"2": {
{
"GroupID": 4,
"AffixID": 2,
"Property": "AttackDelta",
"BaseValue": {
"Value": 13.548016000073403
"Value": 13.548016
},
"StepValue": {
"Value": 1.693502000765875
"Value": 1.693502
},
"StepNum": 2
},
"3": {
{
"GroupID": 4,
"AffixID": 3,
"Property": "DefenceDelta",
"BaseValue": {
"Value": 13.548016000073403
"Value": 13.548016
},
"StepValue": {
"Value": 1.693502000765875
"Value": 1.693502
},
"StepNum": 2
},
"4": {
{
"GroupID": 4,
"AffixID": 4,
"Property": "HPAddedRatio",
"BaseValue": {
"Value": 0.027648000279441476
"Value": 0.027648
},
"StepValue": {
"Value": 0.0034560004714876413
"Value": 0.0034560005
},
"StepNum": 2
},
"5": {
{
"GroupID": 4,
"AffixID": 5,
"Property": "AttackAddedRatio",
"BaseValue": {
"Value": 0.027648000279441476
"Value": 0.027648
},
"StepValue": {
"Value": 0.0034560004714876413
"Value": 0.0034560005
},
"StepNum": 2
},
"6": {
{
"GroupID": 4,
"AffixID": 6,
"Property": "DefenceAddedRatio",
"BaseValue": {
"Value": 0.03456000052392483
"Value": 0.034560002
},
"StepValue": {
"Value": 0.0043200000654906034
"Value": 0.0043200003
},
"StepNum": 2
},
"7": {
{
"GroupID": 4,
"AffixID": 7,
"Property": "SpeedDelta",
"BaseValue": {
"Value": 1.6000000005587935
"Value": 1.6
},
"StepValue": {
"Value": 0.20000000018626451
"Value": 0.2
},
"StepNum": 2
},
"8": {
{
"GroupID": 4,
"AffixID": 8,
"Property": "CriticalChanceBase",
"BaseValue": {
"Value": 0.020736000733450055
"Value": 0.020736001
},
"StepValue": {
"Value": 0.0025920008774846792
"Value": 0.0025920009
},
"StepNum": 2
},
"9": {
{
"GroupID": 4,
"AffixID": 9,
"Property": "CriticalDamageBase",
"BaseValue": {
"Value": 0.04147200076840818
"Value": 0.041472
},
"StepValue": {
"Value": 0.0051840003579854965
"Value": 0.0051840004
},
"StepNum": 2
},
"10": {
{
"GroupID": 4,
"AffixID": 10,
"Property": "StatusProbabilityBase",
"BaseValue": {
"Value": 0.027648000279441476
"Value": 0.027648
},
"StepValue": {
"Value": 0.0034560004714876413
"Value": 0.0034560005
},
"StepNum": 2
},
"11": {
{
"GroupID": 4,
"AffixID": 11,
"Property": "StatusResistanceBase",
"BaseValue": {
"Value": 0.027648000279441476
"Value": 0.027648
},
"StepValue": {
"Value": 0.0034560004714876413
"Value": 0.0034560005
},
"StepNum": 2
},
"12": {
{
"GroupID": 4,
"AffixID": 12,
"Property": "BreakDamageAddedRatioBase",
"BaseValue": {
"Value": 0.04147200076840818
"Value": 0.041472
},
"StepValue": {
"Value": 0.0051840003579854965
"Value": 0.0051840004
},
"StepNum": 2
}
},
"5": {
"1": {
{
"GroupID": 5,
"AffixID": 1,
"Property": "HPDelta",
"BaseValue": {
"Value": 33.870039001107216
"Value": 33.87004
},
"StepValue": {
"Value": 4.23375500086695
"Value": 4.233755
},
"StepNum": 2
},
"2": {
{
"GroupID": 5,
"AffixID": 2,
"Property": "AttackDelta",
"BaseValue": {
"Value": 16.935019000666216
"Value": 16.935019
},
"StepValue": {
"Value": 2.1168770007789135
"Value": 2.116877
},
"StepNum": 2
},
"3": {
{
"GroupID": 5,
"AffixID": 3,
"Property": "DefenceDelta",
"BaseValue": {
"Value": 16.935019000666216
"Value": 16.935019
},
"StepValue": {
"Value": 2.1168770007789135
"Value": 2.116877
},
"StepNum": 2
},
"4": {
{
"GroupID": 5,
"AffixID": 4,
"Property": "HPAddedRatio",
"BaseValue": {
"Value": 0.03456000052392483
"Value": 0.034560002
},
"StepValue": {
"Value": 0.0043200000654906034
"Value": 0.0043200003
},
"StepNum": 2
},
"5": {
{
"GroupID": 5,
"AffixID": 5,
"Property": "AttackAddedRatio",
"BaseValue": {
"Value": 0.03456000052392483
"Value": 0.034560002
},
"StepValue": {
"Value": 0.0043200000654906034
"Value": 0.0043200003
},
"StepNum": 2
},
"6": {
{
"GroupID": 5,
"AffixID": 6,
"Property": "DefenceAddedRatio",
"BaseValue": {
"Value": 0.043199999956414104
"Value": 0.0432
},
"StepValue": {
"Value": 0.005399999907240272
"Value": 0.0054
},
"StepNum": 2
},
"7": {
{
"GroupID": 5,
"AffixID": 7,
"Property": "SpeedDelta",
@ -518,69 +511,68 @@
"Value": 2
},
"StepValue": {
"Value": 0.3000000002793968
"Value": 0.3
},
"StepNum": 2
},
"8": {
{
"GroupID": 5,
"AffixID": 8,
"Property": "CriticalChanceBase",
"BaseValue": {
"Value": 0.02592000039294362
"Value": 0.02592
},
"StepValue": {
"Value": 0.0032400002237409353
"Value": 0.0032400002
},
"StepNum": 2
},
"9": {
{
"GroupID": 5,
"AffixID": 9,
"Property": "CriticalDamageBase",
"BaseValue": {
"Value": 0.05184000078588724
"Value": 0.05184
},
"StepValue": {
"Value": 0.006480000447481871
"Value": 0.0064800004
},
"StepNum": 2
},
"10": {
{
"GroupID": 5,
"AffixID": 10,
"Property": "StatusProbabilityBase",
"BaseValue": {
"Value": 0.03456000052392483
"Value": 0.034560002
},
"StepValue": {
"Value": 0.0043200000654906034
"Value": 0.0043200003
},
"StepNum": 2
},
"11": {
{
"GroupID": 5,
"AffixID": 11,
"Property": "StatusResistanceBase",
"BaseValue": {
"Value": 0.03456000052392483
"Value": 0.034560002
},
"StepValue": {
"Value": 0.0043200000654906034
"Value": 0.0043200003
},
"StepNum": 2
},
"12": {
{
"GroupID": 5,
"AffixID": 12,
"Property": "BreakDamageAddedRatioBase",
"BaseValue": {
"Value": 0.05184000078588724
"Value": 0.05184
},
"StepValue": {
"Value": 0.006480000447481871
"Value": 0.0064800004
},
"StepNum": 2
}
}
}
]

View File

@ -2987,6 +2987,65 @@
]
]
},
"21046": {
"id": "21046",
"skill": "莫失莫忘",
"desc": "使装备者的攻击力提高#1[i]%。进入战斗时,若有两名及以上我方角色拥有任意相同命途,使这些角色的暴击伤害提高#2[i]%。同类技能无法重复生效。",
"params": [
[
0.16,
0.16
],
[
0.2,
0.2
],
[
0.24,
0.24
],
[
0.28,
0.28
],
[
0.32,
0.32
]
],
"properties": [
[
{
"type": "AttackAddedRatio",
"value": 0.16
}
],
[
{
"type": "AttackAddedRatio",
"value": 0.2
}
],
[
{
"type": "AttackAddedRatio",
"value": 0.24
}
],
[
{
"type": "AttackAddedRatio",
"value": 0.28
}
],
[
{
"type": "AttackAddedRatio",
"value": 0.32
}
]
]
},
"22000": {
"id": "22000",
"skill": "眼疾手快",
@ -5215,6 +5274,154 @@
]
]
},
"23029": {
"id": "23029",
"skill": "世事无痕",
"desc": "使装备者的效果命中提高#1[i]%,装备者施放普攻、战技、终结技攻击敌方目标后,有#2[i]%的基础概率使其陷入【卸甲】状态。【卸甲】状态下,敌方目标受到的伤害提高#3[i]%,持续#4[i]回合。若目标处于装备者施加的持续伤害状态,则有#5[i]%的基础概率将装备者施加的【卸甲】状态升级成【穷寇】状态,使敌方目标受到的伤害额外提高#6[i]%,持续#4[i]回合,期间装备者无法对其施加【卸甲】。",
"params": [
[
0.6,
0.6,
0.1,
2,
0.6,
0.14
],
[
0.7,
0.6,
0.12,
2,
0.6,
0.16
],
[
0.8,
0.6,
0.14,
2,
0.6,
0.18
],
[
0.9,
0.6,
0.16,
2,
0.6,
0.2
],
[
1,
0.6,
0.18,
2,
0.6,
0.22
]
],
"properties": [
[
{
"type": "StatusProbabilityBase",
"value": 0.6
}
],
[
{
"type": "StatusProbabilityBase",
"value": 0.7
}
],
[
{
"type": "StatusProbabilityBase",
"value": 0.8
}
],
[
{
"type": "StatusProbabilityBase",
"value": 0.9
}
],
[
{
"type": "StatusProbabilityBase",
"value": 1
}
]
]
},
"23030": {
"id": "23030",
"skill": "沉酣",
"desc": "使装备者受到攻击的概率大幅提高,暴击伤害提高#1[i]%。当装备者施放终结技后获得1层【火舞】持续2回合最多叠加#2[i]层。每层【火舞】使装备者追加攻击造成的伤害提高#3[i]%。",
"params": [
[
0.36,
2,
0.36,
5
],
[
0.42,
2,
0.42,
5
],
[
0.48,
2,
0.48,
5
],
[
0.54,
2,
0.54,
5
],
[
0.6,
2,
0.6,
5
]
],
"properties": [
[
{
"type": "CriticalDamageBase",
"value": 0.36
}
],
[
{
"type": "CriticalDamageBase",
"value": 0.42
}
],
[
{
"type": "CriticalDamageBase",
"value": 0.48
}
],
[
{
"type": "CriticalDamageBase",
"value": 0.54
}
],
[
{
"type": "CriticalDamageBase",
"value": 0.6
}
]
]
},
"24000": {
"id": "24000",
"skill": "扑火",

View File

@ -1,14 +1,14 @@
from typing import Dict, List, Union
from msgspec import Struct
from .read_excel import (
RelicSubAffix,
RelicMainAffix,
AvatarPromotion,
EquipmentPromotion,
RelicMainAffix,
RelicSubAffix,
)
from msgspec import Struct, convert
class PromotionCost(Struct):
ItemID: int
@ -71,205 +71,25 @@ class SingleRelicSubAffix(Struct):
StepNum: int
class AvatarPromotionConfigModel(Struct):
Avatar: Dict[str, Dict[str, SingleAvatarPromotion]]
# class AvatarPromotionConfigModel(Struct):
# Avatar: List[Dict[str, SingleAvatarPromotion]]
@classmethod
def from_json(cls, data: Dict):
return cls(
Avatar={
avatar_id: {
promotion: SingleAvatarPromotion(
AvatarID=promotion_dict[promotion]['AvatarID'],
Promotion=promotion_dict[promotion]['Promotion'],
PromotionCostList=[
PromotionCost(
ItemID=item['ItemID'], ItemNum=item['ItemNum']
# class EquipmentPromotionConfigModel(Struct):
# Equipment: List[Dict[str, SingleEquipmentPromotion]]
# class RelicMainAffixConfigModel(Struct):
# Relic: List[Dict[str, SingleRelicMainAffix]]
# class RelicSubAffixConfigModel(Struct):
# Relic: Dict[str, Dict[str, SingleRelicSubAffix]]
AvatarPromotionConfig = convert(AvatarPromotion, List[SingleAvatarPromotion])
EquipmentPromotionConfig = convert(
EquipmentPromotion, List[SingleEquipmentPromotion]
)
for item in promotion_dict[promotion][
'PromotionCostList'
]
],
PlayerLevelRequire=promotion_dict[promotion].get(
'PlayerLevelRequire', None
),
WorldLevelRequire=promotion_dict[promotion].get(
'WorldLevelRequire', None
),
MaxLevel=promotion_dict[promotion]['MaxLevel'],
AttackBase=PromotionAttr(
Value=promotion_dict[promotion]['AttackBase'][
'Value'
]
),
AttackAdd=PromotionAttr(
Value=promotion_dict[promotion]['AttackAdd'][
'Value'
]
),
DefenceBase=PromotionAttr(
Value=promotion_dict[promotion]['DefenceBase'][
'Value'
]
),
DefenceAdd=PromotionAttr(
Value=promotion_dict[promotion]['DefenceAdd'][
'Value'
]
),
HPBase=PromotionAttr(
Value=promotion_dict[promotion]['HPBase']['Value']
),
HPAdd=PromotionAttr(
Value=promotion_dict[promotion]['HPAdd']['Value']
),
SpeedBase=PromotionAttr(
Value=promotion_dict[promotion]['SpeedBase'][
'Value'
]
),
CriticalChance=PromotionAttr(
Value=promotion_dict[promotion]['CriticalChance'][
'Value'
]
),
CriticalDamage=PromotionAttr(
Value=promotion_dict[promotion]['CriticalDamage'][
'Value'
]
),
BaseAggro=PromotionAttr(
Value=promotion_dict[promotion]['BaseAggro'][
'Value'
]
),
)
for promotion in promotion_dict.keys()
}
for avatar_id, promotion_dict in data.items()
}
)
class EquipmentPromotionConfigModel(Struct):
Equipment: Dict[str, Dict[str, SingleEquipmentPromotion]]
@classmethod
def from_json(cls, data: Dict):
return cls(
Equipment={
equipment_id: {
promotion: SingleEquipmentPromotion(
EquipmentID=promotion_dict[promotion]['EquipmentID'],
Promotion=promotion_dict[promotion]['Promotion'],
PromotionCostList=[
PromotionCost(
ItemID=item['ItemID'], ItemNum=item['ItemNum']
)
for item in promotion_dict[promotion][
'PromotionCostList'
]
],
PlayerLevelRequire=promotion_dict[promotion].get(
'PlayerLevelRequire', None
),
WorldLevelRequire=promotion_dict[promotion].get(
'WorldLevelRequire', None
),
MaxLevel=promotion_dict[promotion]['MaxLevel'],
BaseHP=PromotionAttr(
Value=promotion_dict[promotion]['BaseHP']['Value']
),
BaseHPAdd=PromotionAttr(
Value=promotion_dict[promotion]['BaseHPAdd'][
'Value'
]
),
BaseAttack=PromotionAttr(
Value=promotion_dict[promotion]['BaseAttack'][
'Value'
]
),
BaseAttackAdd=PromotionAttr(
Value=promotion_dict[promotion]['BaseAttackAdd'][
'Value'
]
),
BaseDefence=PromotionAttr(
Value=promotion_dict[promotion]['BaseDefence'][
'Value'
]
),
BaseDefenceAdd=PromotionAttr(
Value=promotion_dict[promotion]['BaseDefenceAdd'][
'Value'
]
),
)
for promotion in promotion_dict.keys()
}
for equipment_id, promotion_dict in data.items()
}
)
class RelicMainAffixConfigModel(Struct):
Relic: Dict[str, Dict[str, SingleRelicMainAffix]]
@classmethod
def from_json(cls, data: Dict):
return cls(
Relic={
relic_id: {
group_id: SingleRelicMainAffix(
GroupID=affix_dict[group_id]['GroupID'],
AffixID=affix_dict[group_id]['AffixID'],
Property=affix_dict[group_id]['Property'],
BaseValue=PromotionAttr(
Value=affix_dict[group_id]['BaseValue']['Value']
),
LevelAdd=PromotionAttr(
Value=affix_dict[group_id]['LevelAdd']['Value']
),
IsAvailable=affix_dict[group_id]['IsAvailable'],
)
for group_id in affix_dict.keys()
}
for relic_id, affix_dict in data.items()
}
)
class RelicSubAffixConfigModel(Struct):
Relic: Dict[str, Dict[str, SingleRelicSubAffix]]
@classmethod
def from_json(cls, data: Dict):
return cls(
Relic={
relic_id: {
group_id: SingleRelicSubAffix(
GroupID=affix_dict[group_id]['GroupID'],
AffixID=affix_dict[group_id]['AffixID'],
Property=affix_dict[group_id]['Property'],
BaseValue=PromotionAttr(
Value=affix_dict[group_id]['BaseValue']['Value']
),
StepValue=PromotionAttr(
Value=affix_dict[group_id]['StepValue']['Value']
),
StepNum=affix_dict[group_id]['StepNum'],
)
for group_id in affix_dict.keys()
}
for relic_id, affix_dict in data.items()
}
)
AvatarPromotionConfig = AvatarPromotionConfigModel.from_json(AvatarPromotion)
EquipmentPromotionConfig = EquipmentPromotionConfigModel.from_json(
EquipmentPromotion
)
RelicMainAffixConfig = RelicMainAffixConfigModel.from_json(RelicMainAffix)
RelicSubAffixConfig = RelicSubAffixConfigModel.from_json(RelicSubAffix)
RelicMainAffixConfig = convert(RelicMainAffix, List[SingleRelicMainAffix])
RelicSubAffixConfig = convert(RelicSubAffix, List[SingleRelicSubAffix])

View File

@ -8,23 +8,19 @@ from PIL import Image, ImageFont
@overload
async def convert_img(img: Image.Image, is_base64: bool = False) -> bytes:
...
async def convert_img(img: Image.Image, is_base64: bool = False) -> bytes: ...
@overload
async def convert_img(img: Image.Image, is_base64: bool = True) -> str:
...
async def convert_img(img: Image.Image, is_base64: bool = True) -> str: ...
@overload
async def convert_img(img: bytes, is_base64: bool = False) -> str:
...
async def convert_img(img: bytes, is_base64: bool = False) -> str: ...
@overload
async def convert_img(img: Path, is_base64: bool = False) -> str:
...
async def convert_img(img: Path, is_base64: bool = False) -> str: ...
async def convert_img(

View File

@ -1,11 +1,16 @@
import json
from pathlib import Path
from typing import Dict, List, Union, TypedDict
from msgspec import json as msgjson
from typing import Dict, List, Optional, TypedDict, Union
from ...version import StarRail_version
from .model.RelicSetSkill import RelicSetSkillModel
from msgspec import Struct, convert, json as msgjson
class RelicSetStatusAdd(Struct):
Property: str
Value: float
MAP = Path(__file__).parent / 'data'
@ -17,7 +22,7 @@ EquipmentID2Name_fileName = f'EquipmentID2Name_mapping_{version}.json'
EquipmentID2EnName_fileName = f'EquipmentID2EnName_mapping_{version}.json'
skillId2Name_fileName = f'skillId2Name_mapping_{version}.json'
skillId2Type_fileName = f'skillId2Type_mapping_{version}.json'
Property2Name_fileName = 'Property2Name.json'
Property2Name_fileName = f'Property2Name_mapping_{version}.json'
RelicId2SetId_fileName = f'RelicId2SetId_mapping_{version}.json'
SetId2Name_fileName = f'SetId2Name_mapping_{version}.json'
rankId2Name_fileName = f'rankId2Name_mapping_{version}.json'
@ -98,9 +103,9 @@ with Path.open(
f.read(), type=Dict[str, Dict[str, List]]
)
with Path.open(MAP / RelicSetSkill_fileName, encoding='UTF-8') as f:
data = json.load(f)
RelicSetSkill = RelicSetSkillModel.from_json(data)
# with Path.open(MAP / RelicSetSkill_fileName, encoding='UTF-8') as f:
# RelicSetSkill = convert(json.load(f), Dict[str, Dict[str, object]])
# print(RelicSetSkill)
with Path.open(MAP / skillId2AttackType_fileName, encoding='UTF-8') as f:
skillId2AttackType = msgjson.decode(f.read(), type=Dict[str, str])

View File

@ -2898,6 +2898,48 @@
}
]
},
"21046": {
"1": [
{
"PropertyType": "AttackAddedRatio",
"Value": {
"Value": 0.16
}
}
],
"2": [
{
"PropertyType": "AttackAddedRatio",
"Value": {
"Value": 0.2
}
}
],
"3": [
{
"PropertyType": "AttackAddedRatio",
"Value": {
"Value": 0.24
}
}
],
"4": [
{
"PropertyType": "AttackAddedRatio",
"Value": {
"Value": 0.28
}
}
],
"5": [
{
"PropertyType": "AttackAddedRatio",
"Value": {
"Value": 0.32
}
}
]
},
"22002": {
"1": [
{
@ -2946,5 +2988,89 @@
"3": [],
"4": [],
"5": []
},
"23030": {
"1": [
{
"PropertyType": "CriticalDamageBase",
"Value": {
"Value": 0.36
}
}
],
"2": [
{
"PropertyType": "CriticalDamageBase",
"Value": {
"Value": 0.42
}
}
],
"3": [
{
"PropertyType": "CriticalDamageBase",
"Value": {
"Value": 0.48
}
}
],
"4": [
{
"PropertyType": "CriticalDamageBase",
"Value": {
"Value": 0.54
}
}
],
"5": [
{
"PropertyType": "CriticalDamageBase",
"Value": {
"Value": 0.6
}
}
]
},
"23029": {
"1": [
{
"PropertyType": "StatusProbabilityBase",
"Value": {
"Value": 0.6
}
}
],
"2": [
{
"PropertyType": "StatusProbabilityBase",
"Value": {
"Value": 0.7
}
}
],
"3": [
{
"PropertyType": "StatusProbabilityBase",
"Value": {
"Value": 0.8
}
}
],
"4": [
{
"PropertyType": "StatusProbabilityBase",
"Value": {
"Value": 0.9
}
}
],
"5": [
{
"PropertyType": "StatusProbabilityBase",
"Value": {
"Value": 1
}
}
]
}
}

View File

@ -101,6 +101,9 @@
"23028": "YetHopeIsPriceless",
"21044": "BoundlessChoreo",
"21045": "AftertheCharmonyFall",
"21046": "PoisedtoBloom",
"22002": "ForTomorrow'sJourney",
"23026": "FlowingNightglow"
"23026": "FlowingNightglow",
"23030": "DanceatSunset",
"23029": "ThoseManySprings"
}

View File

@ -101,6 +101,9 @@
"23028": "偏偏希望无价",
"21044": "无边曼舞",
"21045": "谐乐静默之后",
"21046": "芳华待灼",
"22002": "为了明日的旅途",
"23026": "夜色流光溢彩"
"23026": "夜色流光溢彩",
"23030": "落日时起舞",
"23029": "那无数个春天"
}

View File

@ -66,6 +66,7 @@
"21043": 4,
"21044": 4,
"21045": 4,
"21046": 4,
"22000": 4,
"22001": 4,
"22002": 4,
@ -98,6 +99,8 @@
"23026": 5,
"23027": 5,
"23028": 5,
"23029": 5,
"23030": 5,
"24000": 5,
"24001": 5,
"24002": 5,

View File

@ -1,55 +0,0 @@
{
"MaxHP": "生命值",
"Attack": "攻击力",
"Defence": "防御力",
"Speed": "速度",
"CriticalChance": "暴击率",
"CriticalDamage": "暴击伤害",
"BreakDamageAddedRatio": "击破特攻",
"BreakDamageAddedRatioBase": "击破特攻",
"HealRatio": "治疗量加成",
"MaxSP": "能量上限",
"SPRatio": "能量恢复效率",
"StatusProbability": "效果命中",
"StatusResistance": "效果抵抗",
"CriticalChanceBase": "暴击率",
"CriticalDamageBase": "暴击伤害",
"HealRatioBase": "治疗量加成",
"StanceBreakAddedRatio": "dev_失效字段",
"SPRatioBase": "能量恢复效率",
"StatusProbabilityBase": "效果命中",
"StatusResistanceBase": "效果抵抗",
"PhysicalAddedRatio": "物理属性伤害提高",
"PhysicalResistance": "物理属性抗性提高",
"FireAddedRatio": "火属性伤害提高",
"FireResistance": "火属性抗性提高",
"IceAddedRatio": "冰属性伤害提高",
"IceResistance": "冰属性抗性提高",
"ThunderAddedRatio": "雷属性伤害提高",
"ThunderResistance": "雷属性抗性提高",
"WindAddedRatio": "风属性伤害提高",
"WindResistance": "风属性抗性提高",
"QuantumAddedRatio": "量子属性伤害提高",
"QuantumResistance": "量子属性抗性提高",
"ImaginaryAddedRatio": "虚数属性伤害提高",
"ImaginaryResistance": "虚数属性抗性提高",
"BaseHP": "基础生命值提高<unbreak>#1[i]</unbreak>",
"HPDelta": "生命值",
"HPAddedRatio": "生命值百分比",
"BaseAttack": "基础攻击力提高<unbreak>#1[i]</unbreak>",
"AttackDelta": "攻击力",
"AttackAddedRatio": "攻击力百分比",
"BaseDefence": "基础防御力提高<unbreak>#1[i]</unbreak>",
"DefenceDelta": "防御力",
"DefenceAddedRatio": "防御力百分比",
"BaseSpeed": "速度",
"HealTakenRatio": "治疗量加成",
"PhysicalResistanceDelta": "物理属性抗性提高",
"FireResistanceDelta": "火属性抗性提高",
"IceResistanceDelta": "冰属性抗性提高",
"ThunderResistanceDelta": "雷属性抗性提高",
"WindResistanceDelta": "风属性抗性提高",
"QuantumResistanceDelta": "量子属性抗性提高",
"ImaginaryResistanceDelta": "虚数属性抗性提高",
"SpeedDelta": "速度"
}

View File

@ -9,7 +9,6 @@
"BreakDamageAddedRatioBase": "击破特攻",
"HealRatio": "治疗量加成",
"MaxSP": "能量上限",
"SpecialMaxSP": "",
"SPRatio": "能量恢复效率",
"StatusProbability": "效果命中",
"StatusResistance": "效果抵抗",

View File

@ -1,238 +0,0 @@
{
"101": {
"2": {
"Property": "HealRatioBase",
"Value": 0.1
},
"4": {}
},
"102": {
"2": {
"Property": "AttackAddedRatio",
"Value": 0.12
},
"4": {
"Property": "SpeedAddedRatio",
"Value": 0.06
}
},
"103": {
"2": {
"Property": "DefenceAddedRatio",
"Value": 0.15
},
"4": {}
},
"104": {
"2": {
"Property": "IceAddedRatio",
"Value": 0.1
},
"4": {}
},
"105": {
"2": {
"Property": "PhysicalAddedRatio",
"Value": 0.1
},
"4": {}
},
"106": {
"2": {},
"4": {}
},
"107": {
"2": {
"Property": "FireAddedRatio",
"Value": 0.1
},
"4": {}
},
"108": {
"2": {
"Property": "QuantumAddedRatio",
"Value": 0.1
},
"4": {}
},
"109": {
"2": {
"Property": "ThunderAddedRatio",
"Value": 0.1
},
"4": {}
},
"110": {
"2": {
"Property": "WindAddedRatio",
"Value": 0.1
},
"4": {}
},
"111": {
"2": {
"Property": "BreakDamageAddedRatioBase",
"Value": 0.16
},
"4": {
"Property": "BreakDamageAddedRatioBase",
"Value": 0.16
}
},
"112": {
"2": {
"Property": "ImaginaryAddedRatio",
"Value": 0.1
},
"4": {}
},
"301": {
"2": {
"Property": "AttackAddedRatio",
"Value": 0.12
}
},
"302": {
"2": {
"Property": "HPAddedRatio",
"Value": 0.12
}
},
"303": {
"2": {
"Property": "StatusProbabilityBase",
"Value": 0.1
}
},
"304": {
"2": {
"Property": "DefenceAddedRatio",
"Value": 0.15
}
},
"305": {
"2": {
"Property": "CriticalDamageBase",
"Value": 0.16
}
},
"306": {
"2": {
"Property": "CriticalChanceBase",
"Value": 0.08
}
},
"307": {
"2": {
"Property": "BreakDamageAddedRatioBase",
"Value": 0.16
}
},
"308": {
"2": {
"Property": "SPRatioBase",
"Value": 0.05
}
},
"309": {
"2": {
"Property": "CriticalChanceBase",
"Value": 0.08
}
},
"310": {
"2": {
"Property": "StatusResistanceBase",
"Value": 0.1
}
},
"113": {
"2": {
"Property": "HPAddedRatio",
"Value": 0.12
},
"4": {}
},
"114": {
"2": {
"Property": "SpeedAddedRatio",
"Value": 0.06
},
"4": {}
},
"115": {
"2": {},
"4": {}
},
"116": {
"2": {
"Property": "AttackAddedRatio",
"Value": 0.12
},
"4": {}
},
"311": {
"2": {
"Property": "AttackAddedRatio",
"Value": 0.12
}
},
"312": {
"2": {
"Property": "SPRatioBase",
"Value": 0.05
}
},
"117": {
"2": {},
"4": {
"Property": "CriticalChanceBase",
"Value": 0.04
}
},
"118": {
"2": {
"Property": "BreakDamageAddedRatioBase",
"Value": 0.16
},
"4": {}
},
"313": {
"2": {
"Property": "CriticalChanceBase",
"Value": 0.04
}
},
"314": {
"2": {
"Property": "AttackAddedRatio",
"Value": 0.12
}
},
"119": {
"2": {
"Property": "BreakDamageAddedRatioBase",
"Value": 0.16
},
"4": {}
},
"120": {
"2": {
"Property": "AttackAddedRatio",
"Value": 0.12
},
"4": {
"Property": "CriticalChanceBase",
"Value": 0.06
}
},
"315": {
"2": {}
},
"316": {
"2": {
"Property": "SpeedAddedRatio",
"Value": 0.06
}
}
}

View File

@ -0,0 +1,238 @@
{
"101": {
"2": {
"Property": "HealRatioBase",
"Value": 0.1
},
"4": {}
},
"102": {
"2": {
"Property": "AttackAddedRatio",
"Value": 0.12
},
"4": {
"Property": "SpeedAddedRatio",
"Value": 0.06
}
},
"103": {
"2": {
"Property": "DefenceAddedRatio",
"Value": 0.15
},
"4": {}
},
"104": {
"2": {
"Property": "IceAddedRatio",
"Value": 0.1
},
"4": {}
},
"105": {
"2": {
"Property": "PhysicalAddedRatio",
"Value": 0.1
},
"4": {}
},
"106": {
"2": {},
"4": {}
},
"107": {
"2": {
"Property": "FireAddedRatio",
"Value": 0.1
},
"4": {}
},
"108": {
"2": {
"Property": "QuantumAddedRatio",
"Value": 0.1
},
"4": {}
},
"109": {
"2": {
"Property": "ThunderAddedRatio",
"Value": 0.1
},
"4": {}
},
"110": {
"2": {
"Property": "WindAddedRatio",
"Value": 0.1
},
"4": {}
},
"111": {
"2": {
"Property": "BreakDamageAddedRatioBase",
"Value": 0.16
},
"4": {
"Property": "BreakDamageAddedRatioBase",
"Value": 0.16
}
},
"112": {
"2": {
"Property": "ImaginaryAddedRatio",
"Value": 0.1
},
"4": {}
},
"301": {
"2": {
"Property": "AttackAddedRatio",
"Value": 0.12
}
},
"302": {
"2": {
"Property": "HPAddedRatio",
"Value": 0.12
}
},
"303": {
"2": {
"Property": "StatusProbabilityBase",
"Value": 0.1
}
},
"304": {
"2": {
"Property": "DefenceAddedRatio",
"Value": 0.15
}
},
"305": {
"2": {
"Property": "CriticalDamageBase",
"Value": 0.16
}
},
"306": {
"2": {
"Property": "CriticalChanceBase",
"Value": 0.08
}
},
"307": {
"2": {
"Property": "BreakDamageAddedRatioBase",
"Value": 0.16
}
},
"308": {
"2": {
"Property": "SPRatioBase",
"Value": 0.05
}
},
"309": {
"2": {
"Property": "CriticalChanceBase",
"Value": 0.08
}
},
"310": {
"2": {
"Property": "StatusResistanceBase",
"Value": 0.1
}
},
"113": {
"2": {
"Property": "HPAddedRatio",
"Value": 0.12
},
"4": {}
},
"114": {
"2": {
"Property": "SpeedAddedRatio",
"Value": 0.06
},
"4": {}
},
"115": {
"2": {},
"4": {}
},
"116": {
"2": {
"Property": "AttackAddedRatio",
"Value": 0.12
},
"4": {}
},
"311": {
"2": {
"Property": "AttackAddedRatio",
"Value": 0.12
}
},
"312": {
"2": {
"Property": "SPRatioBase",
"Value": 0.05
}
},
"117": {
"2": {},
"4": {
"Property": "CriticalChanceBase",
"Value": 0.04
}
},
"118": {
"2": {
"Property": "BreakDamageAddedRatioBase",
"Value": 0.16
},
"4": {}
},
"313": {
"2": {
"Property": "CriticalChanceBase",
"Value": 0.04
}
},
"314": {
"2": {
"Property": "AttackAddedRatio",
"Value": 0.12
}
},
"119": {
"2": {
"Property": "BreakDamageAddedRatioBase",
"Value": 0.16
},
"4": {}
},
"120": {
"2": {
"Property": "AttackAddedRatio",
"Value": 0.12
},
"4": {
"Property": "CriticalChanceBase",
"Value": 0.06
}
},
"315": {
"2": {}
},
"316": {
"2": {
"Property": "SpeedAddedRatio",
"Value": 0.06
}
}
}

View File

@ -36,6 +36,9 @@
"1214": "Quantum",
"1215": "Physical",
"1217": "Wind",
"1218": "Fire",
"1221": "Physical",
"1224": "Imaginary",
"1301": "Fire",
"1302": "Physical",
"1303": "Ice",

View File

@ -36,6 +36,9 @@
"1214": "Xueyi",
"1215": "Hanya",
"1217": "Huohuo",
"1218": "Jiaoqiu",
"1221": "Yunli",
"1224": "March7th",
"1301": "Gallagher",
"1302": "Argenti",
"1303": "RuanMei",

View File

@ -36,6 +36,9 @@
"1214": "雪衣",
"1215": "寒鸦",
"1217": "藿藿",
"1218": "椒丘",
"1221": "云璃",
"1224": "三月七",
"1301": "加拉赫",
"1302": "银枝",
"1303": "阮•梅",

View File

@ -1,58 +0,0 @@
{
"1001": "4",
"1002": "4",
"1003": "5",
"1004": "5",
"1005": "5",
"1006": "5",
"1008": "4",
"1009": "4",
"1013": "4",
"1101": "5",
"1102": "5",
"1103": "4",
"1104": "5",
"1105": "4",
"1106": "4",
"1107": "5",
"1108": "4",
"1109": "4",
"1110": "4",
"1111": "4",
"1112": "5",
"1201": "4",
"1202": "4",
"1203": "5",
"1204": "5",
"1205": "5",
"1206": "4",
"1207": "4",
"1208": "5",
"1209": "5",
"1210": "4",
"1211": "5",
"1212": "5",
"1213": "5",
"1214": "4",
"1215": "4",
"1217": "5",
"1301": "4",
"1302": "5",
"1303": "5",
"1304": "5",
"1305": "5",
"1306": "5",
"1307": "5",
"1308": "5",
"1309": "5",
"1310": "5",
"1312": "4",
"1314": "5",
"1315": "5",
"8001": "5",
"8002": "5",
"8003": "5",
"8004": "5",
"8005": "5",
"8006": "5"
}

View File

@ -36,6 +36,9 @@
"1214": "4",
"1215": "4",
"1217": "5",
"1218": "5",
"1221": "5",
"1224": "4",
"1301": "4",
"1302": "5",
"1303": "5",

View File

@ -919,6 +919,82 @@
}
],
"121706": [],
"121801": [],
"121802": [],
"121803": [
{
"id": "121802",
"num": 2
},
{
"id": "121801",
"num": 1
}
],
"121804": [],
"121805": [
{
"id": "121803",
"num": 2
},
{
"id": "121804",
"num": 2
}
],
"121806": [],
"122101": [],
"122102": [],
"122103": [
{
"id": "122103",
"num": 2
},
{
"id": "122101",
"num": 1
}
],
"122104": [],
"122105": [
{
"id": "122102",
"num": 2
},
{
"id": "122104",
"num": 2
}
],
"122106": [],
"122401": [],
"122402": [],
"122403": [
{
"id": "122402",
"num": 2
},
{
"id": "122401",
"num": 1
},
{
"id": "122408",
"num": 1
}
],
"122404": [],
"122405": [
{
"id": "122403",
"num": 2
},
{
"id": "122404",
"num": 2
}
],
"122406": [],
"130101": [],
"130102": [],
"130103": [

View File

@ -221,6 +221,24 @@
"121704": "坐卧不离,争拗难宁",
"121705": "降妖捉鬼,十王敕令",
"121706": "同休共戚,相须而行",
"121801": "五味五走,生熟有定",
"121802": "爽口作疾,厚味措毒",
"121803": "和合之妙,敌不及拒",
"121804": "藏腑和平,血气资荣",
"121805": "明争天地,暗斗变击",
"121806": "九沸九变,火为之纪",
"122101": "沉锋离垢",
"122102": "初芒破生",
"122103": "九尺运斤",
"122104": "大匠击橐",
"122105": "恒兵匪石",
"122106": "剑胆琴心",
"122401": "初花学剑动星芒",
"122402": "白刃耀雪舞骇浪",
"122403": "头脑机灵本领强",
"122404": "龙飞凤舞不窝囊",
"122405": "多练武术少吃糖",
"122406": "天下第一本姑娘",
"130101": "盐与犬",
"130102": "狮子之尾",
"130103": "逝者的新生",

View File

@ -358,5 +358,24 @@
"130603": "Ultra",
"130604": "",
"130606": "MazeNormal",
"130607": "Maze"
"130607": "Maze",
"121801": "Normal",
"121802": "BPSkill",
"121803": "Ultra",
"121804": "",
"121806": "MazeNormal",
"121807": "Maze",
"122401": "Normal",
"122408": "Normal",
"122402": "BPSkill",
"122403": "Ultra",
"122404": "",
"122406": "MazeNormal",
"122407": "Maze",
"122101": "Normal",
"122102": "BPSkill",
"122103": "Ultra",
"122104": "",
"122106": "MazeNormal",
"122107": "Maze"
}

View File

@ -358,5 +358,24 @@
"130603": "一人千役",
"130604": "叙述性诡计",
"130606": "攻击",
"130607": "不可靠叙事者"
"130607": "不可靠叙事者",
"121801": "仁火攻心",
"121802": "燔燎急袭",
"121803": "鼎阵妙法,奇正相生",
"121804": "四示八权,纤滋精味",
"121806": "攻击",
"121807": "旺火却乱",
"122401": "荡涤妖邪琉璃剑",
"122408": "一扎眉攒,二扎心",
"122402": "师父,请喝茶!",
"122403": "盖世女侠三月七",
"122404": "师父,我悟了!",
"122406": "攻击",
"122407": "一气化三餐",
"122101": "翻风转日",
"122102": "飞铗震赫",
"122103": "剑为地纪,刃惊天宗",
"122104": "闪铄",
"122106": "攻击",
"122107": "后发先至"
}

View File

@ -358,5 +358,24 @@
"130603": "辅助",
"130604": "辅助",
"130606": "",
"130607": "辅助"
"130607": "辅助",
"121801": "单攻",
"121802": "扩散",
"121803": "群攻",
"121804": "妨害",
"121806": "",
"121807": "妨害",
"122401": "单攻",
"122408": "单攻",
"122402": "辅助",
"122403": "单攻",
"122404": "强化",
"122406": "",
"122407": "强化",
"122101": "单攻",
"122102": "扩散",
"122103": "强化",
"122104": "扩散",
"122106": "",
"122107": "强化"
}

View File

@ -1,28 +1,6 @@
from typing import Dict, Union
from msgspec import Struct
class RelicSetStatusAdd(Struct):
Property: str
Value: float
class RelicSetSkillModel(Struct):
RelicSet: Dict[str, Dict[str, Union[RelicSetStatusAdd, None]]]
@classmethod
def from_json(cls, data: Dict):
return cls(
RelicSet={
str(k): {
str(k2): RelicSetStatusAdd(
Property=v2['Property'], Value=v2['Value']
)
if v2
else None
for k2, v2 in v.items()
}
for k, v in data.items()
}
)

View File

@ -1,2 +1,2 @@
StarRailUID_version = '0.1.0'
StarRail_version = '2.3.0'
StarRail_version = '2.4.0'