ysd支持旅行者、增加地区图标、优化评分算法,fix bug

This commit is contained in:
CMHopeSunshine 2022-06-28 19:44:18 +08:00
parent b46072baed
commit 3dd68e9a0e
25 changed files with 1100 additions and 386 deletions

View File

@ -1,8 +1,3 @@
# -*- coding: UTF-8 -*-
"""
该脚本可以直接获取wiki上的语音文件 并保存进数据库中
"""
import json
import os
from pathlib import Path
@ -14,7 +9,6 @@ from sqlitedict import SqliteDict # TODO 加入requirements
from utils import aiorequests
from .util import get_path
# OUT_PUT = Path(__file__).parent / 'voice'
OUT_PUT = Path() / 'data' / 'LittlePaimon' / 'guess_voice' / 'voice'
BASE_URL = 'https://wiki.biligame.com/ys/'
@ -28,11 +22,8 @@ config = {
'voice_language': ['', '', '']
}
# dir_data = os.path.join(os.path.dirname(__file__), 'data')
dir_data = Path() / 'data' / 'LittlePaimon' / 'guess_voice' / 'data'
# if not os.path.exists(dir_data):
# os.makedirs(dir_data)
dir_data.mkdir(parents=True, exist_ok=True)

View File

@ -15,21 +15,14 @@ from sqlitedict import SqliteDict
from .download_data import voice_list_by_mys, voice_detail_by_mys
from .util import get_path, require_file
from utils.alias_handler import get_alias_by_name
scheduler = require('nonebot_plugin_apscheduler').scheduler
# dir_data = os.path.join(os.path.dirname(__file__), 'data')
dir_data = Path() / 'data' / 'LittlePaimon' / 'guess_voice' / 'data'
# data_path = os.path.join(os.path.dirname(__file__), 'voice')
data_path = Path() / 'data' / 'LittlePaimon' / 'guess_voice' / 'voice'
# data2_path = os.path.join(os.path.dirname(__file__), 'voice2')
data2_path = Path() / 'data' / 'LittlePaimon' / 'guess_voice' / 'voice2'
# if not os.path.exists(dir_data):
# os.makedirs(dir_data)
dir_data.mkdir(parents=True, exist_ok=True)
db = {}
@ -57,15 +50,23 @@ with open(os.path.join(os.path.dirname(__file__), 'character.json'), 'r', encodi
def create_guess_matcher(role_name, second, group_id):
"""
创建一个猜语音的正则匹配matcher正则内容为角色的别名
:param role_name: 角色名
:param second: 结束时间
:param group_id: 进行的群组
:return: None
"""
def check_group(event: GroupMessageEvent):
if event.group_id == group_id:
return True
return False
alias_list = character_json.get(role_name, [])
re_str = role_name + '|' + '|'.join(alias_list)
alias_list = get_alias_by_name(role_name)
re_str = '|'.join(alias_list)
guess_matcher = on_regex(re_str, temp=True, rule=Rule(check_group))
guess_matcher.plugin_name = "Guess_voice"
guess_matcher.expire_time = datetime.timedelta(seconds=second)
@guess_matcher.handle()
async def _(event: GroupMessageEvent):

View File

@ -199,7 +199,7 @@ async def create_item(rank, item_type, name, element, count, dg_time):
return bg
async def ten(uid, gacha_data) -> PngImagePlugin.PngImageFile:
async def ten(uid, gacha_data):
gacha_list = []
for i in range(0, 10):
if gacha_data['gacha_type'] == 'all_star':
@ -210,7 +210,6 @@ async def ten(uid, gacha_data) -> PngImagePlugin.PngImageFile:
role = once(uid, gacha_data).copy()
gacha_list.append(role)
gacha_list.sort(key=lambda x: x["rank"], reverse=True)
img: PngImagePlugin.PngImageFile
img = Image.open(os.path.join(RES_PATH, 'background.png'))
i = 0
for wish in gacha_list:
@ -245,4 +244,4 @@ async def more_ten(uid, gacha_data, num, sd):
draw = ImageDraw.Draw(img)
draw.text((27, 575 * num - 30), ('@%s %s Created By LittlePaimon' % (str(sd.nickname), time_str)), font=time_font,
fill="#8E8E8E")
return MessageBuild.Image(img, quality=75)
return MessageBuild.Image(img, quality=75, mode='RGB')

View File

@ -4,7 +4,7 @@ from utils import aiorequests
def toApi(url):
spliturl = str(url).split("?")
spliturl = str(url).replace('amp;', '').split("?")
if "webstatic-sea" in spliturl[0] or "hk4e-api-os" in spliturl[0]:
spliturl[0] = "https://hk4e-api-os.mihoyo.com/event/gacha_info/api/getGachaLog"
else:

View File

@ -141,4 +141,4 @@ async def get_gacha_log_img(gacha_data, pool):
img_draw.text((595, 44), f'UID:{gacha_data["uid"]}', font=get_font(16), fill='black')
img_draw.text((530, total_height - 45), 'Created by LittlePaimon', font=get_font(16), fill='black')
return MessageBuild.Image(img)
return MessageBuild.Image(img, mode='RGB')

View File

@ -155,4 +155,4 @@ async def draw_abyss_card(data, uid, floor_num):
total_img.alpha_composite(floor_img, (5, 5 + 524 + 5 + h))
h += 1210
return MessageBuild.Image(total_img, quality=75)
return MessageBuild.Image(total_img, quality=75, mode='RGB')

View File

@ -157,4 +157,4 @@ async def draw_daily_note_card(data, uid):
bg_img.alpha_composite(role_img, (1220, 200))
now = datetime.datetime.now().strftime('%m月%d%H:%M')
bg_draw.text((554, 1794), 'Created by LittlePaimon·' + now, fill='#5680d2', font=get_font(40, '优设标题黑.ttf'))
return MessageBuild.Image(bg_img, size=0.35, quality=70)
return MessageBuild.Image(bg_img, size=0.35, quality=70, mode='RGB')

View File

@ -114,4 +114,4 @@ async def draw_monthinfo_card(data):
bg_draw.text((49, 857), f'本月相比上个月,原石{ysstr},摩拉{mlstr}', font=get_font(23), fill='#27384C')
bg_draw.text((167, 900), 'Created by LittlePaimon', font=get_font(21), fill='#27384C')
return MessageBuild.Image(bg_img, quality=70)
return MessageBuild.Image(bg_img, quality=70, mode='RGB')

View File

@ -495,4 +495,4 @@ async def draw_chara_card(data, skill_data, chara_name, uid):
bg_draw.text((330, 371), 'Created by LittlePaimon', font=get_font(20), fill='white')
return MessageBuild.Image(bg_img, size=0.95, quality=80)
return MessageBuild.Image(bg_img, size=0.95, quality=80, mode='RGB')

View File

@ -1,8 +1,8 @@
from PIL import Image, ImageDraw, ImageFont
from pathlib import Path
from utils.file_handler import load_image
from utils.enka_util import artifact_total_score, check_effective
from utils.file_handler import load_image, load_json
from utils.enka_util import get_artifact_suit, artifact_total_value, get_expect_score, get_effective, check_effective
from utils import aiorequests
from utils.message_util import MessageBuild
@ -34,78 +34,86 @@ for i in range(1, 6):
paint = load_image(res_path / 'player_card2' / '立绘框.png', mode='RGBA')
lock = load_image(res_path / 'player_card2' / '锁.png', mode='RGBA', size=(45, 45))
loading = load_image(res_path / 'player_card2' / '加载中.png', mode='RGBA', size=(120, 120))
region = load_json(path=Path(__file__).parent.parent / 'utils' / 'json' / 'role_region.json')
def get_font(size, font='hywh.ttf'):
return ImageFont.truetype(str(res_path / font), size)
def draw_right_text(draw, text, width, height, fill, font):
text_length = draw.textlength(text, font=font)
draw.text((width - text_length, height), text, fill=fill,
font=font)
def draw_center_text(draw, text, left_width, right_width, height, fill, font):
text_length = draw.textlength(text, font=font)
draw.text((left_width + (right_width - left_width - text_length) / 2, height), text, fill=fill,
font=font)
async def draw_role_card(uid, data):
bg = Image.new('RGBA', (1080, 1920), (0, 0, 0, 0))
bg.alpha_composite(bg_card[data['元素']], (0, 0))
bg.alpha_composite(base_mask, (0, 0))
if data['名称'] not in ['', '', '埃洛伊']:
region_icon = load_image(path=res_path / 'player_card2' / f'{region[data["名称"]]}.png', size=(130, 130))
bg.alpha_composite(region_icon, (0, 4))
bg_draw = ImageDraw.Draw(bg)
bg_draw.text((131, 100), f"UID{uid}", fill='white', font=get_font(48, 'number.ttf'))
bg_draw.text((134, 150), data['名称'], fill='white', font=get_font(72, '优设标题黑.ttf'))
bg.alpha_composite(level_mask, (298 + 60 * (len(data['名称']) - 2), 172))
bg_draw.text((330 + 60 * (len(data['名称']) - 2), 174), f'LV{data["等级"]}', fill='black',
font=get_font(48, 'number.ttf'))
draw_center_text(bg_draw, f'LV{data["等级"]}', 298 + 60 * (len(data['名称']) - 2), 298 + 60 * (len(data['名称']) - 2) + 171, 174, 'black', get_font(48, 'number.ttf'))
# 属性值
prop = data['属性']
bg_draw.text((89, 262), '生命值', fill='white', font=get_font(34, 'hywh.ttf'))
text_length = 473 - (len(str(prop['基础生命'])) + len(str(prop['额外生命']))) * 20 - 12
bg_draw.text((text_length, 264), f"{prop['基础生命']}", fill='white', font=get_font(34, 'number.ttf'))
bg_draw.text((text_length + len(str(prop['基础生命'])) * 20 + 3, 264), f"+{prop['额外生命']}", fill='#59c538',
font=get_font(34, 'number.ttf'))
text_length = bg_draw.textlength(f"+{prop['额外生命']}", font=get_font(34, 'number.ttf'))
draw_right_text(bg_draw, f"{prop['基础生命']}", 480 - text_length - 5, 264, 'white', get_font(34, 'number.ttf'))
draw_right_text(bg_draw, f"+{prop['额外生命']}", 480, 264, '#59c538', get_font(34, 'number.ttf'))
bg_draw.text((89, 319), '攻击力', fill='white', font=get_font(34, 'hywh.ttf'))
text_length = 473 - (len(str(prop['基础攻击'])) + len(str(prop['额外攻击']))) * 20 - 12
bg_draw.text((text_length, 321), f"{prop['基础攻击']}", fill='white', font=get_font(34, 'number.ttf'))
bg_draw.text((text_length + len(str(prop['基础攻击'])) * 20 + 3, 321), f"+{prop['额外攻击']}", fill='#59c538',
font=get_font(34, 'number.ttf'))
text_length = bg_draw.textlength(f"+{prop['额外攻击']}", font=get_font(34, 'number.ttf'))
draw_right_text(bg_draw, f"{prop['基础攻击']}", 480 - text_length - 5, 321, 'white', get_font(34, 'number.ttf'))
draw_right_text(bg_draw, f"+{prop['额外攻击']}", 480, 321, '#59c538', get_font(34, 'number.ttf'))
bg_draw.text((89, 377), '防御力', fill='white', font=get_font(34, 'hywh.ttf'))
text_length = 473 - (len(str(prop['基础防御'])) + len(str(prop['额外防御']))) * 20 - 12
bg_draw.text((text_length, 379), f"{prop['基础防御']}", fill='white', font=get_font(34, 'number.ttf'))
bg_draw.text((text_length + len(str(prop['基础防御'])) * 20 + 3, 379), f"+{prop['额外防御']}", fill='#59c538',
font=get_font(34, 'number.ttf'))
text_length = bg_draw.textlength(f"+{prop['额外防御']}", font=get_font(34, 'number.ttf'))
draw_right_text(bg_draw, f"{prop['基础防御']}", 480 - text_length - 5, 379, 'white', get_font(34, 'number.ttf'))
draw_right_text(bg_draw, f"+{prop['额外防御']}", 480, 379, '#59c538', get_font(34, 'number.ttf'))
text = round(prop['暴击率'] * 100, 1)
bg_draw.text((89, 436), '暴击率', fill='white', font=get_font(34, 'hywh.ttf'))
bg_draw.text((473 - len(str(text)) * 17 - 17, 438), f"{text}%", fill='white',
font=get_font(34, 'number.ttf'))
draw_right_text(bg_draw, f"{text}%", 480, 438, 'white', get_font(34, 'number.ttf'))
text = round(prop['暴击伤害'] * 100, 1)
bg_draw.text((89, 493), '暴击伤害', fill='white', font=get_font(34, 'hywh.ttf'))
bg_draw.text((473 - len(str(text)) * 17 - 17, 495), f"{text}%", fill='white',
font=get_font(34, 'number.ttf'))
draw_right_text(bg_draw, f"{text}%", 480, 495, 'white', get_font(34, 'number.ttf'))
bg_draw.text((89, 551), '元素精通', fill='white', font=get_font(34, 'hywh.ttf'))
bg_draw.text((473 - len(str(prop['元素精通'])) * 18, 553), f"{prop['元素精通']}", fill='white',
font=get_font(34, 'number.ttf'))
draw_right_text(bg_draw, str(prop['元素精通']), 480, 553, 'white', get_font(34, 'number.ttf'))
text = round(prop['元素充能效率'] * 100, 1)
bg_draw.text((89, 610), '充能效率', fill='white', font=get_font(34, 'hywh.ttf'))
bg_draw.text((473 - len(str(text)) * 17 - 17, 612), f"{text}%", fill='white',
font=get_font(34, 'number.ttf'))
draw_right_text(bg_draw, f"{text}%", 480, 612, 'white', get_font(34, 'number.ttf'))
max_element = max(prop['伤害加成'])
text = round(max_element * 100, 1)
bg_draw.text((89, 669), f'{element_type[prop["伤害加成"].index(max_element)]}伤害加成', fill='white',
font=get_font(34, 'hywh.ttf'))
bg_draw.text((473 - len(str(text)) * 16 - 16, 671), f"{text}%", fill='white',
font=get_font(34, 'number.ttf'))
draw_right_text(bg_draw, f"{text}%", 480, 671, 'white', get_font(34, 'number.ttf'))
# 天赋
if data['名称'] in ['神里绫华', '莫娜']:
data['天赋'].pop(2)
for i in range(3):
bg.alpha_composite(base_icon[data['元素']].resize((132, 142)), (564, 253 + 147 * i))
bg_draw.text((522 if data['天赋'][i]['等级'] < 10 else 513, 310 + 147 * i), str(data['天赋'][i]['等级']), fill='black',
font=get_font(34, 'number.ttf'))
draw_center_text(bg_draw, str(data['天赋'][i]['等级']), 510, 552, 310 + 147 * i, 'black', get_font(34, 'number.ttf'))
skill_icon = res_path2 / 'skill' / f'{data["天赋"][i]["图标"]}.png'
skill_icon = await aiorequests.get_img(url=skill_url.format(data["天赋"][i]["图标"]), size=(57, 57), save_path=skill_icon)
skill_icon = await aiorequests.get_img(url=skill_url.format(data["天赋"][i]["图标"]), size=(57, 57),
save_path=skill_icon)
bg.alpha_composite(skill_icon, (603, 298 + 147 * i))
# 命座
@ -113,7 +121,8 @@ async def draw_role_card(uid, data):
for talent in data['命座']:
bg.alpha_composite((base_icon[data['元素']]).resize((83, 90)), (510 + t * 84, 790))
talent_icon = res_path2 / 'skill' / f'{talent["图标"]}.png'
talent_icon = await aiorequests.get_img(url=talent_url.format(talent["图标"]), size=(45, 45), save_path=talent_icon)
talent_icon = await aiorequests.get_img(url=talent_url.format(talent["图标"]), size=(45, 45),
save_path=talent_icon)
bg.alpha_composite(talent_icon, (529 + t * 84, 813))
t += 1
for t2 in range(t, 6):
@ -123,15 +132,18 @@ async def draw_role_card(uid, data):
# 武器
bg.alpha_composite(weapon_bg[data['武器']['星级'] - 1], (91, 760))
weapon_icon = res_path2 / 'weapon' / f'{data["武器"]["图标"]}.png'
weapon_icon = await aiorequests.get_img(url=weapon_url.format(data["武器"]["图标"]), size=(150, 150), save_path=weapon_icon)
weapon_icon = await aiorequests.get_img(url=weapon_url.format(data["武器"]["图标"]), size=(150, 150),
save_path=weapon_icon)
bg.alpha_composite(weapon_icon, (91, 760))
bg_draw.text((268, 758), data['武器']['名称'], fill='white', font=get_font(34, 'hywh.ttf'))
for i in range(data['武器']['星级']):
bg.alpha_composite(star, (267 + i * 30, 799))
bg_draw.text((283, 835), f'LV{data["武器"]["等级"]}', fill='black', font=get_font(27, 'number.ttf'))
draw_center_text(bg_draw, f'LV{data["武器"]["等级"]}', 268, 268 + 98, 835, 'black', get_font(27, 'number.ttf'))
bg_draw.text((266, 869), f'精炼{data["武器"]["精炼等级"]}', fill='white', font=get_font(34, 'hywh.ttf'))
# 圣遗物
effective = get_effective(data['名称'], data['武器']['名称'], data['圣遗物'], data['元素'])
average = get_expect_score(effective)
total_score = 0
# 第一排
for i in range(2):
@ -141,35 +153,38 @@ async def draw_role_card(uid, data):
break
bg.alpha_composite(weapon_bg[artifact['星级'] - 1].resize((100, 100)), (587 + 317 * i, 1002))
reli_path = res_path2 / 'reli' / f'{artifact["图标"]}.png'
reli_path = await aiorequests.get_img(url=artifact_url.format(artifact["图标"]), size=(100, 100), save_path=reli_path)
reli_path = await aiorequests.get_img(url=artifact_url.format(artifact["图标"]), size=(100, 100),
save_path=reli_path)
bg.alpha_composite(reli_path, (587 + 317 * i, 1002))
bg_draw.text((412 + 317 * i, 950), artifact['名称'], fill='white', font=get_font(40))
score = artifact_total_score(artifact['词条'])
total_score += score
rank = 'SSS' if score >= 45 else 'SS' if 40 <= score < 45 else 'S' if 35 <= score < 40 else 'A' if 30 <= score < 35 else 'B' if 25 <= score < 30 else 'C'
bg_draw.text((412 + 317 * i, 998), f'{rank}-{score}', fill='#ffde6b', font=get_font(28, 'number.ttf'))
bg_draw.text((411 + 317 * i, 951), artifact['名称'], fill='white', font=get_font(40))
value, score = artifact_total_value(data['属性'], artifact, effective)
total_score += value
rank = 'SSS' if score >= 140 else 'SS' if 120 <= score < 140 else 'S' if 100 <= score < 120 else 'A' if 75 <= score < 100 else 'B' if 50 <= score < 75 else 'C'
bg_draw.text((412 + 317 * i, 998), f'{rank}-{value}', fill='#ffde6b', font=get_font(28, 'number.ttf'))
bg.alpha_composite(level_mask.resize((98, 30)), (412 + 317 * i, 1032))
bg_draw.text((433 + 317 * i, 1033), f"LV{artifact['等级']}", fill='black', font=get_font(27, 'number.ttf'))
bg_draw.text((411 + 317 * i, 1067), artifact['主属性']['属性名'], fill='white', font=get_font(25))
draw_center_text(bg_draw, f"LV{artifact['等级']}", 412 + 317 * i, 412 + 317 * i + 98, 1033, 'black', get_font(27, 'number.ttf'))
bg_draw.text((411 + 317 * i, 1069), artifact['主属性']['属性名'], fill='white', font=get_font(25))
if artifact['主属性']['属性名'] not in ['生命值', '攻击力', '元素精通']:
bg_draw.text((408 + 317 * i, 1100), f"+{artifact['主属性']['属性值']}%", fill='white', font=get_font(25, 'number.ttf'))
bg_draw.text((408 + 317 * i, 1100), f"+{artifact['主属性']['属性值']}%", fill='white',
font=get_font(25, 'number.ttf'))
else:
bg_draw.text((408 + 317 * i, 1100), f"+{artifact['主属性']['属性值']}", fill='white', font=get_font(48, 'number.ttf'))
bg_draw.text((408 + 317 * i, 1100), f"+{artifact['主属性']['属性值']}", fill='white',
font=get_font(48, 'number.ttf'))
for j in range(len(artifact['词条'])):
if '百分比' in artifact['词条'][j]['属性名']:
text = artifact['词条'][j]['属性名'].replace('百分比', '')
else:
text = artifact['词条'][j]['属性名']
bg_draw.text((411 + 317 * i, 1163 + 50 * j), text, fill='white' if check_effective(data['名称'], artifact['词条'][j]['属性名']) else '#afafaf', font=get_font(25))
bg_draw.text((411 + 317 * i, 1163 + 50 * j), text,
fill='white' if check_effective(artifact['词条'][j]['属性名'], effective) else '#afafaf',
font=get_font(25))
if artifact['词条'][j]['属性名'] not in ['攻击力', '防御力', '生命值', '元素精通']:
num = '+' + str(artifact['词条'][j]['属性值']) + '%'
text_length = 671 - len(str(artifact['词条'][j]['属性值'])) * 13 + 317 * i - 35 + 8
if '.' not in str(artifact['词条'][j]['属性值']):
text_length -= 5
else:
num = '+' + str(artifact['词条'][j]['属性值'])
text_length = 671 - len(str(artifact['词条'][j]['属性值'])) * 13 + 317 * i - 15
bg_draw.text((text_length, 1163 + 50 * j), num, fill='white' if check_effective(data['名称'], artifact['词条'][j]['属性名']) else '#afafaf', font=get_font(25, 'number.ttf'))
draw_right_text(bg_draw, num, 679 + 317 * i, 1163 + 50 * j,
fill='white' if check_effective(artifact['词条'][j]['属性名'], effective) else '#afafaf',
font=get_font(25, 'number.ttf'))
# 第二排
for i in range(3):
try:
@ -181,88 +196,78 @@ async def draw_role_card(uid, data):
reli_path = await aiorequests.get_img(url=artifact_url.format(artifact["图标"]), size=(100, 100),
save_path=reli_path)
bg.alpha_composite(reli_path, (270 + 317 * i, 1439))
bg_draw.text((95 + 317 * i, 1387), artifact['名称'], fill='white', font=get_font(40))
score = artifact_total_score(artifact['词条'])
total_score += score
rank = 'SSS' if score >= 45 else 'SS' if 40 <= score < 45 else 'S' if 35 <= score < 40 else 'A' if 30 <= score < 35 else 'B' if 25 <= score < 30 else 'C'
bg_draw.text((95 + 317 * i, 1435), f'{rank}-{score}', fill='#ffde6b', font=get_font(28, 'number.ttf'))
bg_draw.text((94 + 317 * i, 1388), artifact['名称'], fill='white', font=get_font(40))
value, score = artifact_total_value(data['属性'], artifact, effective)
total_score += value
rank = 'SSS' if score >= 140 else 'SS' if 120 <= score < 140 else 'S' if 100 <= score < 120 else 'A' if 75 <= score < 100 else 'B' if 50 <= score < 75 else 'C'
bg_draw.text((95 + 317 * i, 1435), f'{rank}-{value}', fill='#ffde6b', font=get_font(28, 'number.ttf'))
bg.alpha_composite(level_mask.resize((98, 30)), (95 + 317 * i, 1469))
bg_draw.text((116 + 317 * i, 1470), f"LV{artifact['等级']}", fill='black', font=get_font(27, 'number.ttf'))
bg_draw.text((94 + 317 * i, 1504), artifact['主属性']['属性名'], fill='white', font=get_font(25))
draw_center_text(bg_draw, f"LV{artifact['等级']}", 95 + 317 * i, 95 + 317 * i + 98, 1470, 'black',
get_font(27, 'number.ttf'))
bg_draw.text((94 + 317 * i, 1506), artifact['主属性']['属性名'], fill='white', font=get_font(25))
if artifact['主属性']['属性名'] not in ['生命值', '攻击力', '元素精通']:
bg_draw.text((91 + 317 * i, 1537), f"+{artifact['主属性']['属性值']}%", fill='white', font=get_font(48, 'number.ttf'))
bg_draw.text((91 + 317 * i, 1537), f"+{artifact['主属性']['属性值']}%", fill='white',
font=get_font(48, 'number.ttf'))
else:
bg_draw.text((91 + 317 * i, 1537), f"+{artifact['主属性']['属性值']}", fill='white', font=get_font(48, 'number.ttf'))
bg_draw.text((91 + 317 * i, 1537), f"+{artifact['主属性']['属性值']}", fill='white',
font=get_font(48, 'number.ttf'))
for j in range(len(artifact['词条'])):
if '百分比' in artifact['词条'][j]['属性名']:
text = artifact['词条'][j]['属性名'].replace('百分比', '')
else:
text = artifact['词条'][j]['属性名']
bg_draw.text((94 + 317 * i, 1600 + 50 * j), text, fill='white' if check_effective(data['名称'], artifact['词条'][j]['属性名']) else '#afafaf', font=get_font(25))
bg_draw.text((94 + 317 * i, 1600 + 50 * j), text,
fill='white' if check_effective(artifact['词条'][j]['属性名'], effective) else '#afafaf',
font=get_font(25))
if artifact['词条'][j]['属性名'] not in ['攻击力', '防御力', '生命值', '元素精通']:
num = '+' + str(artifact['词条'][j]['属性值']) + '%'
text_length = 354 - len(str(artifact['词条'][j]['属性值'])) * 13 + 317 * i - 35 + 8
if '.' not in str(artifact['词条'][j]['属性值']):
text_length -= 5
else:
num = '+' + str(artifact['词条'][j]['属性值'])
text_length = 354 - len(str(artifact['词条'][j]['属性值'])) * 13 + 317 * i - 15
bg_draw.text((text_length, 1600 + 50 * j), num, fill='white' if check_effective(data['名称'], artifact['词条'][j]['属性名']) else '#afafaf', font=get_font(25, 'number.ttf'))
draw_right_text(bg_draw, num, 362 + 317 * i, 1600 + 50 * j,
fill='white' if check_effective(artifact['词条'][j]['属性名'], effective) else '#afafaf',
font=get_font(25, 'number.ttf'))
# 圣遗物评分
bg_draw.text((118, 1057), '圣遗物总评分', fill='#afafaf', font=get_font(36))
bg_draw.text((192, 974), str(round(total_score, 1)), fill='white', font=get_font(60, 'number.ttf'))
total_rank = 'S' if total_score >= 200 else 'A' if 160 <= total_score < 200 else 'B' if 120 <= total_score < 160 else 'C'
bg.alpha_composite(rank_icon[total_rank], (110, 964))
bg_draw.text((119, 1057), '总有效词条数', fill='#afafaf', font=get_font(36))
score_pro = total_score / (average * 5) * 100
total_rank = 'SSS' if score_pro >= 140 else 'SS' if 120 <= score_pro < 140 else 'S' if 100 <= score_pro < 120 else 'A' if 75 <= score_pro < 100 else 'B' if 50 <= score_pro < 75 else 'C'
if len(total_rank) == 3:
bg.alpha_composite(rank_icon[total_rank[0]], (95, 964))
bg.alpha_composite(rank_icon[total_rank[0]], (145, 964))
bg.alpha_composite(rank_icon[total_rank[0]], (195, 964))
bg_draw.text((250, 974), str(round(total_score, 1)), fill='white', font=get_font(60, 'number.ttf'))
elif len(total_rank) == 2:
bg.alpha_composite(rank_icon[total_rank[0]], (125, 964))
bg.alpha_composite(rank_icon[total_rank[0]], (175, 964))
bg_draw.text((235, 974), str(round(total_score, 1)), fill='white', font=get_font(60, 'number.ttf'))
else:
bg.alpha_composite(rank_icon[total_rank[0]], (143, 964))
bg_draw.text((217, 974), str(round(total_score, 1)), fill='white', font=get_font(60, 'number.ttf'))
# 圣遗物套装
suit = []
suit2 = []
flag = False
for artifact in data['圣遗物']:
suit.append(artifact['所属套装'])
for s in suit:
if s not in suit2 and 1 < suit.count(s) < 4:
suit2.append(s)
if suit.count(s) >= 4:
for r in data['圣遗物']:
if r['所属套装'] == s:
reli_path = res_path2 / 'reli' / f'{r["图标"]}.png'
reli_path = await aiorequests.get_img(url=artifact_url.format(r["图标"]), size=(110, 110),
save_path=reli_path)
bg.alpha_composite(reli_path, (76, 1130))
bg.alpha_composite(reli_path, (76, 1255))
bg_draw.text((184, 1168), f'{s[:2]}四件套', fill='white', font=get_font(36))
bg_draw.text((184, 1292), f'{s[:2]}四件套', fill='white', font=get_font(36))
flag = True
break
if len(suit2) == 2:
bg_draw.text((184, 1168), f'{suit2[0][:2]}两件套', fill='white', font=get_font(36))
bg_draw.text((184, 1292), f'{suit2[1][:2]}两件套', fill='white', font=get_font(36))
n = 0
for r in data["圣遗物"]:
if n == 2:
break
if r['所属套装'] in suit2:
suit2.remove(r['所属套装'])
reli_path = res_path2 / 'reli' / f'{r["图标"]}.png'
reli_path = await aiorequests.get_img(url=artifact_url.format(r["图标"]), size=(110, 110),
save_path=reli_path)
bg.alpha_composite(reli_path, (76, 1130 + n * 125))
n += 1
elif len(suit2) == 1:
bg_draw.text((184, 1168), f'{suit2[0][:2]}两件套', fill='white', font=get_font(36))
bg_draw.text((184, 1292), '未激活套装', fill='white', font=get_font(36))
for r in data["圣遗物"]:
if r['所属套装'] in suit2:
reli_path = res_path2 / 'reli' / f'{r["图标"]}.png'
reli_path = await aiorequests.get_img(url=artifact_url.format(r["图标"]), size=(110, 110),
save_path=reli_path)
bg.alpha_composite(reli_path, (76, 1130))
break
elif not flag:
suit = get_artifact_suit(data['圣遗物'])
if not suit:
bg_draw.text((184, 1168), '未激活套装', fill='white', font=get_font(36))
bg_draw.text((184, 1292), '未激活套装', fill='white', font=get_font(36))
elif len(suit) == 1:
artifact_path = res_path2 / 'reli' / f'{suit[0][1]}.png'
artifact_path = await aiorequests.get_img(url=artifact_url.format(suit[0][1]), size=(110, 110),
save_path=artifact_path)
bg.alpha_composite(artifact_path, (76, 1130))
bg.alpha_composite(artifact_path, (76, 1255))
bg_draw.text((184, 1168), f'{suit[0][0][:2]}四件套', fill='white', font=get_font(36))
bg_draw.text((184, 1292), f'{suit[0][0][:2]}四件套', fill='white', font=get_font(36))
else:
artifact_path1 = res_path2 / 'reli' / f'{suit[0][1]}.png'
artifact_path1 = await aiorequests.get_img(url=artifact_url.format(suit[0][1]), size=(110, 110),
save_path=artifact_path1)
artifact_path2 = res_path2 / 'reli' / f'{suit[1][1]}.png'
artifact_path2 = await aiorequests.get_img(url=artifact_url.format(suit[1][1]), size=(110, 110),
save_path=artifact_path2)
bg.alpha_composite(artifact_path1, (76, 1130))
bg.alpha_composite(artifact_path2, (76, 1255))
bg_draw.text((184, 1168), f'{suit[0][0][:2]}两件套', fill='white', font=get_font(36))
bg_draw.text((184, 1292), f'{suit[1][0][:2]}两件套', fill='white', font=get_font(36))
# 立绘
paint_path = res_path / 'player_card2' / '立绘' / f'{data["名称"]}.png'
@ -275,6 +280,4 @@ async def draw_role_card(uid, data):
bg_draw.text((50, 1870), f'更新于{data["更新时间"].replace("2022-", "")}', fill='white', font=get_font(36, '优设标题黑.ttf'))
bg_draw.text((560, 1869), 'Created by LittlePaimon', fill='white', font=get_font(36, '优设标题黑.ttf'))
return MessageBuild.Image(bg, quality=75)
return MessageBuild.Image(bg, quality=75, mode='RGB')

View File

@ -2,85 +2,70 @@
<a href="https://github.com/CMHopeSunshine/LittlePaimon/tree/nonebot2"><img src="http://static.cherishmoon.fun/LittlePaimon/readme/logo.png" width="256" height="256" alt="LittlePaimon"></a>
</p>
<h1 align="center">小派蒙|LittlePaimon</h1>
<h4 align="center">✨基于<a href="https://github.com/Ice-Cirno/HoshinoBot" target="_blank">HoshinoBot</a>|<a href="https://github.com/nonebot/nonebot2" target="_blank">NoneBot2</a><a href="https://github.com/Mrs4s/go-cqhttp" target="_blank">go-cqhttp</a>的原神Q群机器人✨</h4>
<h4 align="center">✨基于<a href="https://github.com/nonebot/nonebot2" target="_blank">NoneBot2</a><a href="https://github.com/Mrs4s/go-cqhttp" target="_blank">go-cqhttp</a>的原神Q群机器人✨</h4>
<p align="center">
<a href="https://cdn.jsdelivr.net/gh/CMHopeSunshine/LittlePaimon@master/LICENSE"><img src="https://img.shields.io/github/license/CMHopeSunshine/LittlePaimon" alt="license"></a>
<img src="https://img.shields.io/badge/Python-3.8+-yellow" alt="python">
<a href="https://qun.qq.com/qqweb/qunpro/share?_wv=3&_wwv=128&inviteCode=MmWrI&from=246610&biz=ka"><img src="https://img.shields.io/badge/QQ频道交流-尘世闲游-green?style=flat-square" alt="QQ guild"></a>
<img src="https://img.shields.io/badge/Nonebot-2.0.0b4-green" alt="python">
<a href="https://qun.qq.com/qqweb/qunpro/share?_wv=3&_wwv=128&inviteCode=MmWrI&from=246610&biz=ka"><img src="https://img.shields.io/badge/QQ频道交流-尘世闲游-blue?style=flat-square" alt="QQ guild"></a>
</p>
## 丨简介
原神多功能机器人通过米游社接口查询uid的游戏信息并提供WIKI查询和各种各样的好玩的功能。
本README为NoneBot2版的介绍Hoshino版详见
本README为NoneBot2版的介绍Hoshino版详见对应分支(已停更)
+ [Github主页](https://github.com/CMHopeSunshine/LittlePaimon)
+ [Github主页](https://github.com/CMHopeSunshine/LittlePaimon/tree/master)
+ [README博客](https://blog.cherishmoon.fun/posts/littlepaimon-hoshino.html)
## 丨功能示例
<img src="http://static.cherishmoon.fun/LittlePaimon/readme/ys.jpg" alt="ys">
<img src="https://static.cherishmoon.fun/LittlePaimon/readme/ys.jpg" alt="ys">
<details>
<summary>角色背包</summary>
<img src="http://static.cherishmoon.fun/LittlePaimon/readme/ysa.jpg" alt="ysa">
<summary>角色面板</summary>
<img src="https://static.cherishmoon.fun/LittlePaimon/readme/ysd.jpg" alt="ysd">
</details>
<details>
<summary>角色详情</summary>
<img src="http://static.cherishmoon.fun/LittlePaimon/readme/ysc.jpg" alt="ysc">
<summary>角色背包</summary>
<img src="https://static.cherishmoon.fun/LittlePaimon/readme/ysa.jpg" alt="ysa">
</details>
<details>
<summary>深渊信息</summary>
<img src="http://static.cherishmoon.fun/LittlePaimon/readme/sy12.jpg" alt="sy">
<img src="https://static.cherishmoon.fun/LittlePaimon/readme/sy12.jpg" alt="sy">
</details>
<details>
<summary>模拟抽卡</summary>
<img src="http://static.cherishmoon.fun/LittlePaimon/readme/十连.jpg" alt="十连">
<img src="https://static.cherishmoon.fun/LittlePaimon/readme/十连.jpg" alt="十连">
</details>
<details>
<summary>实时便签</summary>
<img src="http://static.cherishmoon.fun/LittlePaimon/readme/ssbq.jpg" alt="ssbq">
<img src="https://static.cherishmoon.fun/LittlePaimon/readme/ssbq.jpg" alt="ssbq">
</details>
<details>
<summary>每月札记</summary>
<img src="http://static.cherishmoon.fun/LittlePaimon/readme/myzj.jpg" alt="myzj">
<img src="https://static.cherishmoon.fun/LittlePaimon/readme/myzj.jpg" alt="myzj">
</details>
<details>
<summary>角色材料</summary>
<img src="http://static.cherishmoon.fun/LittlePaimon/readme/material.png" alt="material">
</details>
<details>
<summary>抽卡记录</summary>
<img src="http://static.cherishmoon.fun/LittlePaimon/readme/gachalog.jpg" alt="gachalog">
<img src="https://static.cherishmoon.fun/LittlePaimon/readme/material.png" alt="material">
</details>
## 丨更新日志
> README只展示最近更新全部更新日志详见[这里](https://github.com/CMHopeSunshine/LittlePaimon/blob/nonebot2/UPDATE_LOG.md)
+ 6.21
- 适配`nonebot2 beta4`插件元数据,**请更新nb版本`pip install nonebot2 --upgrade`**
- `Paimon_Chat`现在可以发图片、视频等,可自行添加
- 修复`Paimon_Wiki`搜索对象名结果只有一个时仍需要选择的bug
- 对对联功能api更换
- 增加部分注释文档
- 更换原神日历样式[@nicklly](https://github.com/nicklly) 需用到htmlrender插件`pip install nonebot-plugin-htmlrender`
- 添加`pyproject.toml``poetry.lock`
+ 6.22
- 增加文本敏感词过滤
- fix `原神日历`和发送图片bug
+ 6.23
- 新增查看所有已获取面板信息的角色的列表`ysda`
- 暂时取消凌晨3点的自动更新角色面板操作
+ 6.25
- 添加`requirements.txt`
+ 6.28
- `ysd`现在支持查看`旅行者`面板信息,增加地区图标显示
- 优化`ysd`圣遗物评分算法,现在以有效词条数来决定评级,能简单判断角色多种流派玩法[#40](https://github.com/CMHopeSunshine/LittlePaimon/issues/40)
- 优化`ysd`面板属性和圣遗物词条不对齐的问题
- `原神猜语音`新的角色也能正确匹配识别[#82](https://github.com/CMHopeSunshine/LittlePaimon/pull/82)
- 修复`获取抽卡记录`问题[#81](https://github.com/CMHopeSunshine/LittlePaimon/issues/81)
## 丨功能列表
@ -92,12 +77,13 @@
+ 部署NoneBot2和go-cqhttp
+ 在NoneBot2根目录克隆本项目
+ 在NoneBot2**根目录**,克隆本项目
`git clone https://github.com/CMHopeSunshine/LittlePaimon `
+ 安装依赖
```bash
# 在插件目录运行:
# pip方式
pip install -r requirements.txt
# 如果你使用poetry进行环境管理可以
@ -135,7 +121,7 @@ javascript:(function(){prompt(document.domain,document.cookie)})();
- [NoneBot2](https://github.com/nonebot/nonebot2) - 跨平台异步机器人框架
- [go-cqhttp](https://github.com/Mrs4s/go-cqhttp) - Onebot标准的框架实现
- [西北一枝花](https://github.com/Nwflower) - 美工大大和武器攻略图提供
- [nicklly](https://github.com/nicklly) 、[SCU_OP](https://github.com/SCUOP) - PR贡献者们
- [nicklly](https://github.com/nicklly) 、[SCU_OP](https://github.com/SCUOP) 、[meatjam](https://github.com/meatjam) - PR贡献者们
- [egenshin](https://github.com/pcrbot/erinilis-modules/tree/master/egenshin) - 抽卡和猜语音代码、资源参考
- [bluemushoom](https://bbs.nga.cn/nuke.php?func=ucp&uid=62861898) - 全角色收益曲线和参考面板攻略图来源
- [genshin-gacha-export](https://github.com/sunfkny/genshin-gacha-export) - 抽卡记录导出代码参考
@ -162,6 +148,8 @@ javascript:(function(){prompt(document.domain,document.cookie)})();
| SCU_OP | 30 |
| 南絮ヽ | 20 |
| 夜空koi我老婆 | 30 |
| 昔。 | 5 |
| dix | 20 |
## 丨其他
- 本项目仅供学习使用,禁止用于商业用途

View File

@ -51,3 +51,9 @@
- 暂时取消凌晨3点的自动更新角色面板操作
+ 6.25
- 添加`requirements.txt`
+ 6.28
- `ysd`现在支持查看`旅行者`面板信息,增加地区图标显示
- 优化`ysd`圣遗物评分算法,现在以有效词条数来决定评级,能简单判断角色多种流派玩法[#40](https://github.com/CMHopeSunshine/LittlePaimon/issues/40)
- 优化`ysd`面板属性和圣遗物词条不对齐的问题
- `原神猜语音`新的角色也能正确匹配识别[#82](https://github.com/CMHopeSunshine/LittlePaimon/pull/82)
- 修复`获取抽卡记录`问题[#81](https://github.com/CMHopeSunshine/LittlePaimon/issues/81)

BIN
res/player_card2/璃月.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

BIN
res/player_card2/稻妻.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 KiB

BIN
res/player_card2/至冬.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
res/player_card2/蒙德.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

View File

@ -1,7 +1,7 @@
import difflib
from typing import Union
from .file_handler import load_json
import os
from pathlib import Path
def get_short_name(name: str):
@ -10,7 +10,7 @@ def get_short_name(name: str):
:param name: 角色或武器名
:return: 短名字符串
"""
short_name = load_json(path=os.path.join(os.path.dirname(__file__), 'short_name.json'))
short_name = load_json(path=Path(__file__).parent / 'json' / 'short_name.json')
return name if name not in short_name.keys() else short_name[name]
@ -20,7 +20,7 @@ def get_id_by_name(name: str):
:param name: 角色名
:return: id字符串
"""
alias_file = load_json(path=os.path.join(os.path.dirname(__file__), 'alias.json'))
alias_file = load_json(path=Path(__file__).parent / 'json' / 'alias.json')
name_list = alias_file['roles']
for role_id, alias in name_list.items():
if name in alias:
@ -33,7 +33,7 @@ def get_name_by_id(role_id: str):
:param role_id: 角色id
:return: 角色名字符串
"""
alias_file = load_json(path=os.path.join(os.path.dirname(__file__), 'alias.json'))
alias_file = load_json(path=Path(__file__).parent / 'json' / 'alias.json')
name_list = alias_file['roles']
if role_id in name_list:
return name_list[role_id][0]
@ -41,6 +41,20 @@ def get_name_by_id(role_id: str):
return None
def get_alias_by_name(name: str):
"""
根据角色名字获取角色的别名
:param name: 角色名
:return: 别名列表
"""
alias_file = load_json(path=Path(__file__).parent / 'json' / 'alias.json')
name_list = alias_file['roles']
for r in name_list.values():
if name in r:
return r
return None
def get_match_alias(msg: str, type: str = 'roles', single_to_dict: bool = False) -> Union[str, list, dict]:
"""
根据字符串消息获取与之相似或匹配的角色武器原魔名
@ -49,7 +63,7 @@ def get_match_alias(msg: str, type: str = 'roles', single_to_dict: bool = False)
:param single_to_dict: 是否将角色单结果也转换成{角色:id}字典
:return: 匹配的字符串列表或字典
"""
alias_file = load_json(path=os.path.join(os.path.dirname(__file__), 'alias.json'))
alias_file = load_json(path=Path(__file__).parent / 'json' / 'alias.json')
alias_list = alias_file[type]
if msg in ['风主', '岩主', '雷主']:
return msg

View File

@ -1,5 +1,6 @@
from pathlib import Path
import datetime
import re
from utils.alias_handler import get_name_by_id
from utils.file_handler import load_json, save_json
@ -19,7 +20,6 @@ class PlayerInfo:
self.data = load_json(path=self.path)
self.player_info = self.data['玩家信息'] if '玩家信息' in self.data else {}
self.roles = self.data['角色'] if '角色' in self.data else {}
# self.artifacts = self.data['圣遗物'] if '圣遗物' in self.data else transform_artifacts(self.roles)
def set_player(self, data: dict):
self.player_info['昵称'] = data.get('nickname', 'unknown')
@ -35,11 +35,17 @@ class PlayerInfo:
def set_role(self, data: dict):
role_info = {}
role_name = get_name_by_id(str(data['avatarId']))
if role_name not in ['', '']:
if role_name not in ['unknown', 'None']:
role_info['名称'] = role_name
role_info['角色ID'] = data['avatarId']
role_info['等级'] = int(data['propMap']['4001']['val'])
role_info['好感度'] = data['fetterInfo']['expLevel']
if role_name in ['', '']:
traveler_skill = role_skill['Name'][list(data['skillLevelMap'].keys())[-1]]
find_element = re.search(r'(风|雷|岩|草|水|火|冰)', traveler_skill).group(1)
role_info['元素'] = find_element
role_name = find_element + ''
else:
role_info['元素'] = role_element[role_name]
role_info['天赋'] = []
@ -118,33 +124,11 @@ class PlayerInfo:
artifact_info['词条'] = []
for reliquary in artifact['flat']['reliquarySubstats']:
artifact_info['词条'].append({'属性名': prop_list[reliquary['appendPropId']],
'属性值': reliquary['statValue'],
'评分': artifact_score(role_name, prop_list[reliquary['appendPropId']],
reliquary['statValue'], artifact_info['部位'])})
'属性值': reliquary['statValue']})
artifacts.append(artifact_info)
role_info['圣遗物'] = artifacts
role_info['更新时间'] = datetime.datetime.strftime(datetime.datetime.now(), '%Y-%m-%d %H:%M:%S')
self.roles[role_name] = role_info
# self.set_artifacts(data)
# def set_artifacts(self, data):
# for artifact in data['equipList'][:-1]:
# artifact_info = {}
# artifact_info['名称'] = artifact_list['Name'][artifact['flat']['icon']]
# artifact_info['图标'] = artifact['flat']['icon']
# artifact_info['部位'] = artifact_list['Piece'][artifact['flat']['icon'].split('_')[-1]][1]
# artifact_info['所属套装'] = artifact_list['Mapping'][artifact_info['名称']]
# artifact_info['等级'] = artifact['reliquary']['level'] - 1
# artifact_info['星级'] = artifact['flat']['rankLevel']
# artifact_info['主属性'] = {'属性名': prop_list[artifact['flat']['reliquaryMainstat']['mainPropId']],
# '属性值': artifact['flat']['reliquaryMainstat']['statValue']}
# artifact_info['词条'] = []
# for reliquary in artifact['flat']['reliquarySubstats']:
# artifact_info['词条'].append({'属性名': prop_list[reliquary['appendPropId']],
# '属性值': reliquary['statValue']})
# artifact_info['角色名'] = get_name_by_id(str(data['avatarId']))
# if artifact_info not in self.artifacts:
# self.artifacts.append(artifact_info)
self.roles[role_info['名称']] = role_info
def get_player_info(self):
return self.player_info
@ -173,69 +157,106 @@ def dictList_to_list(data):
new_data = {}
for d in data:
name = get_name_by_id(str(d['avatarId']))
if name not in ['', '']:
new_data[name] = d['avatarId']
return new_data
# def transform_artifacts(data):
# artifacts = []
# for role in data.values():
# for artifact in role['圣遗物']:
# artifacts_temp = {}
# artifacts_temp['名称'] = artifact['名称']
# artifacts_temp['图标'] = artifact['图标']
# artifacts_temp['部位'] = artifact['部位']
# artifacts_temp['所属套装'] = artifact['所属套装']
# artifacts_temp['等级'] = artifact['等级']
# artifacts_temp['星级'] = artifact['星级']
# artifacts_temp['主属性'] = artifact['主属性']
# artifacts_temp['词条'] = []
# for reliquary in artifact['词条']:
# artifacts_temp['词条'].append({'属性名': reliquary['属性名'],
# '属性值': reliquary['属性值']})
# artifacts_temp['角色名'] = role['名称']
# artifacts.append(artifacts_temp)
# return artifacts
def artifact_value(role_prop: dict, prop_name: str, prop_value: float, effective: dict):
"""
计算圣遗物单词条的有效词条数
:param role_prop: 角色基础属性
:param prop_name: 属性名
:param prop_value: 属性值
:param effective: 有效词条列表
:return: 评分
"""
prop_map = {'攻击力': 4.975, '生命值': 4.975, '防御力': 6.2, '暴击率': 3.3, '暴击伤害': 6.6, '元素精通': 19.75, '元素充能效率': 5.5}
if prop_name in effective.keys() and prop_name in ['攻击力', '生命值', '防御力']:
return round(prop_value / role_prop[prop_name] * 100 / prop_map[prop_name] * effective[prop_name], 2)
if prop_name.replace('百分比', '') in effective.keys():
return round(prop_value / prop_map[prop_name.replace('百分比', '')] * effective[prop_name.replace('百分比', '')], 2)
return 0
def artifact_score(role_name, prop_name, prop_value, artifact_type):
effective = ra_score['Role'][role_name]
score = 0
if '攻击力' in effective:
if prop_name == '攻击力':
score = prop_value * 0.24
elif prop_name == '百分比攻击力':
score = prop_value * 1
if '生命值' in effective:
if prop_name == '生命值':
score = prop_value * 0.014
elif prop_name == '百分比生命值':
score = prop_value * 0.86
if '防御力' in effective:
if prop_name == '防御力':
score = prop_value * 0.18
elif prop_name == '百分比防御力':
score = prop_value * 0.7
if '元素精通' in effective and prop_name == '元素精通':
score = prop_value * 0.25
if '元素充能效率' in effective and prop_name == '元素充能效率':
score = prop_value * 0.65
if '暴击率' in effective and prop_name == '暴击率':
if artifact_type == '理之冠':
score = prop_value * 3
def artifact_total_value(role_prop: dict, artifact: dict, effective: dict):
"""
计算圣遗物总有效词条数以及评分
:param role_prop: 角色基础属性
:param artifact: 圣遗物信息
:param effective: 有效词条列表
:return: 总词条数评分
"""
new_role_prop = {'攻击力': role_prop['基础攻击'], '生命值': role_prop['基础生命'], '防御力': role_prop['基础防御']}
value = 0
for i in artifact['词条']:
value += artifact_value(new_role_prop, i['属性名'], i['属性值'], effective)
value = round(value, 2)
return value, round(value / get_expect_score(effective) * 100, 1)
def get_effective(role_name: str, role_weapon: str, artifacts: list, element: str = ''):
"""
根据角色的武器圣遗物来判断获取该角色有效词条列表
:param role_name: 角色名
:param role_weapon: 角色武器
:param artifacts: 角色圣遗物列表
:param element: 角色元素仅需主角传入
:return: 有效词条列表
"""
if role_name in ['', '']:
role_name = str(element) + ''
if role_name in ra_score['Role']:
if role_name == '钟离':
if artifacts[-2]['主属性']['属性名'] == '岩元素伤害加成':
return ra_score['Role'][role_name]['岩伤']
elif artifacts[-2]['主属性']['属性名'] in ['物理伤害加成', '火元素伤害加成', '冰元素伤害加成']:
return ra_score['Role'][role_name]['武神']
if role_name == '班尼特' and artifacts[-2]['主属性']['属性名'] == '火元素伤害加成':
return ra_score['Role'][role_name]['输出']
if role_name == '甘雨':
suit = get_artifact_suit(artifacts)
if suit and ('乐团' in suit[0][0] or (len(suit) == 2 and '乐团' in suit[1][0])):
return ra_score['Role'][role_name]['融化']
if role_name == '申鹤' and artifacts[-2]['主属性']['属性名'] == '冰元素伤害加成':
return ra_score['Role'][role_name]['输出']
if role_name == '七七' and artifacts[-2]['主属性']['属性名'] == '物理伤害加成':
return ra_score['Role'][role_name]['输出']
if role_name in ['枫原万叶', '温迪', '砂糖'] and artifacts[-2]['主属性']['属性名'] == '风元素伤害加成':
return ra_score['Role'][role_name]['输出']
if '西风' in role_weapon and '西风' in ra_score['Role'][role_name]:
return ra_score['Role'][role_name]['西风']
return ra_score['Role'][role_name]['常规']
else:
score = prop_value * 2
if '暴击伤害' in effective and prop_name == '暴击伤害':
if artifact_type == '理之冠':
score = prop_value * 1.5
return {'攻击力': 1, '暴击率': 1, '暴击伤害': 1}
def get_expect_score(effective: dict):
"""
计算单个圣遗物小毕业所需的期望词条数
:param effective: 有效词条列表
:return: 期望词条数
"""
total = 0
if len(effective.keys()) == 2:
average = 15 / 5
elif len(effective.keys()) == 3:
average = 24 / 5
elif len(effective.keys()) == 4:
average = 28 / 5
else:
score = prop_value * 1
return round(score, 2)
average = 30 / 5
for name, value in effective.items():
total += value * average
return round(total / len(effective.keys()), 2)
def check_effective(role_name, prop_name):
effective = ra_score['Role'][role_name]
def check_effective(prop_name: str, effective: dict):
"""
检查词条是否有效
:param prop_name: 词条属性名
:param effective: 有效词条列表
:return: 是否有效
"""
if '攻击力' in effective and '攻击力' in prop_name:
return True
if '生命值' in effective and '生命值' in prop_name:
@ -245,8 +266,27 @@ def check_effective(role_name, prop_name):
return prop_name in effective
def artifact_total_score(data):
score = 0
for i in data:
score += i['评分']
return round(score, 1)
def get_artifact_suit(artifacts: list):
"""
获取圣遗物套装
:param artifacts: 圣遗物列表
:return: 套装列表
"""
suit = []
suit2 = []
final_suit = []
for artifact in artifacts:
suit.append(artifact['所属套装'])
for s in suit:
if s not in suit2 and 1 < suit.count(s) < 4:
suit2.append(s)
if suit.count(s) >= 4:
for r in artifacts:
if r['所属套装'] == s:
return [[s, r['图标']]]
if len(suit2) == 2:
for r in artifacts:
if r['所属套装'] in suit2:
final_suit.append([r['所属套装'], r['图标']])
suit2.remove(r['所属套装'])
return final_suit

View File

@ -1,5 +0,0 @@
{
"标题": "小派蒙使用帮助",
"子标题": "Powered by CherishMoon",
"原神信息查询": ""
}

View File

@ -50,7 +50,7 @@
"10000064": ["云堇", "云先生"],
"10000066": ["神里绫人", "0人", "大舅子", "小舅子", "绫人", "神里哥", "凌人", "神里凌人"],
"10000060": ["夜兰", "夜阑", "叶兰"],
"10000065": ["久岐忍", "忍者", "阿卡丽"],
"10000065": ["久岐忍", "忍者", "阿卡丽", "97忍", "97人"],
"11111113": ["鹿野院平藏", "近战法师"]
},
"weapons": {

View File

@ -0,0 +1,52 @@
{
"胡桃": "璃月",
"托马": "稻妻",
"宵宫": "稻妻",
"烟绯": "璃月",
"可莉": "蒙德",
"迪卢克": "蒙德",
"辛焱": "璃月",
"安柏": "蒙德",
"香菱": "璃月",
"班尼特": "蒙德",
"珊瑚宫心海": "稻妻",
"达达利亚": "至冬",
"行秋": "璃月",
"莫娜": "蒙德",
"芭芭拉": "蒙德",
"申鹤": "璃月",
"神里绫华": "稻妻",
"优菈": "蒙德",
"甘雨": "璃月",
"凯亚": "蒙德",
"重云": "璃月",
"七七": "璃月",
"迪奥娜": "蒙德",
"罗莎莉亚": "蒙德",
"埃洛伊": "异界",
"八重神子": "稻妻",
"雷电将军": "稻妻",
"九条裟罗": "稻妻",
"刻晴": "璃月",
"雷泽": "蒙德",
"菲谢尔": "蒙德",
"丽莎": "蒙德",
"北斗": "璃月",
"早柚": "稻妻",
"枫原万叶": "稻妻",
"魈": "璃月",
"温迪": "蒙德",
"琴": "蒙德",
"砂糖": "蒙德",
"荒泷一斗": "稻妻",
"五郎": "稻妻",
"阿贝多": "蒙德",
"钟离": "璃月",
"诺艾尔": "蒙德",
"凝光": "璃月",
"云堇": "璃月",
"神里绫人": "稻妻",
"夜兰": "璃月",
"久岐忍": "蒙德",
"鹿野院平藏": "稻妻"
}

View File

@ -1,110 +1,734 @@
{
"Role":{
"胡桃": ["暴击率", "暴击伤害", "生命值", "元素精通"],
"托马": ["生命值", "元素充能效率"],
"宵宫": ["暴击率", "暴击伤害", "攻击力", "元素精通"],
"烟绯": ["暴击率", "暴击伤害", "攻击力", "元素精通"],
"可莉": ["暴击率", "暴击伤害", "攻击力", "元素精通"],
"迪卢克": ["暴击率", "暴击伤害", "攻击力", "元素精通"],
"辛焱": ["暴击率", "暴击伤害", "攻击力", "防御力"],
"安柏": ["暴击率", "暴击伤害", "攻击力", "元素充能效率"],
"香菱": ["暴击率", "暴击伤害", "攻击力", "元素精通", "元素充能效率"],
"班尼特": ["生命值", "元素充能效率"],
"珊瑚宫心海": ["生命值", "元素充能效率"],
"达达利亚": ["暴击率", "暴击伤害", "攻击力"],
"行秋": ["暴击率", "暴击伤害", "攻击力", "元素充能效率"],
"莫娜": ["暴击率", "暴击伤害", "攻击力", "元素精通", "元素充能效率"],
"芭芭拉": ["生命值", "元素充能效率"],
"申鹤": ["攻击力", "元素充能效率"],
"神里绫华": ["暴击率", "暴击伤害", "攻击力", "元素充能效率"],
"优菈": ["暴击率", "暴击伤害", "攻击力", "元素充能效率"],
"甘雨": ["暴击率", "暴击伤害", "攻击力", "元素精通"],
"凯亚": ["暴击率", "暴击伤害", "攻击力", "元素充能效率"],
"重云": ["暴击率", "暴击伤害", "攻击力", "元素充能效率"],
"七七": ["攻击力", "元素充能效率"],
"迪奥娜": ["生命值", "元素充能效率"],
"罗莎莉亚": ["暴击率", "暴击伤害", "攻击力", "元素充能效率"],
"埃洛伊": ["暴击率", "暴击伤害", "攻击力"],
"八重神子": ["暴击率", "暴击伤害", "攻击力", "元素充能效率", "元素精通"],
"雷电将军": ["暴击率", "暴击伤害", "攻击力", "元素充能效率"],
"九条裟罗": ["暴击率", "暴击伤害", "攻击力", "元素充能效率"],
"刻晴": ["暴击率", "暴击伤害", "攻击力"],
"雷泽": ["暴击率", "暴击伤害", "攻击力"],
"菲谢尔": ["暴击率", "暴击伤害", "攻击力"],
"丽莎": ["暴击率", "暴击伤害", "攻击力", "元素充能效率"],
"北斗": ["暴击率", "暴击伤害", "攻击力", "元素充能效率"],
"雷主": ["暴击率", "暴击伤害", "攻击力", "元素充能效率"],
"早柚": ["元素精通", "元素充能效率"],
"枫原万叶": ["暴击率", "暴击伤害", "元素精通", "元素充能效率"],
"魈": ["暴击率", "暴击伤害", "攻击力", "元素充能效率"],
"温迪": ["暴击率", "暴击伤害", "攻击力", "元素充能效率", "元素精通"],
"琴": ["暴击率", "暴击伤害", "攻击力", "元素充能效率"],
"砂糖": ["暴击率", "暴击伤害", "攻击力", "元素充能效率"],
"风主": ["暴击率", "暴击伤害", "攻击力", "元素充能效率"],
"荒泷一斗": ["暴击率", "暴击伤害", "防御力", "元素充能效率"],
"五郎": ["防御力", "元素充能效率"],
"阿贝多": ["暴击率", "暴击伤害", "防御力"],
"钟离": ["暴击率", "暴击伤害", "生命值", "攻击力", "元素充能效率"],
"诺艾尔": ["暴击率", "暴击伤害", "防御力", "元素充能效率"],
"凝光": ["暴击率", "暴击伤害", "攻击力"],
"岩主": ["暴击率", "暴击伤害", "攻击力", "元素充能效率"],
"云堇": ["防御力", "元素充能效率"],
"神里绫人": ["暴击率", "暴击伤害", "攻击力", "生命值"],
"夜兰": ["暴击率", "暴击伤害", "生命值", "元素充能效率"],
"久岐忍": ["暴击率", "暴击伤害", "攻击力", "元素充能效率"]
"Role": {
"胡桃": {
"常规": {
"攻击力": 0.4,
"暴击率": 1,
"暴击伤害": 1,
"生命值": 1,
"元素精通": 1
}
},
"托马": {
"常规": {
"生命值": 1,
"元素充能效率": 1
},
"西风": {
"生命值": 1,
"元素充能效率": 1,
"暴击率": 0.4
}
},
"宵宫": {
"常规": {
"暴击率": 1,
"暴击伤害": 1,
"攻击力": 1,
"元素精通": 1
}
},
"烟绯": {
"常规": {
"暴击率": 1,
"暴击伤害": 1,
"攻击力": 1,
"元素精通": 1
}
},
"可莉": {
"常规": {
"暴击率": 1,
"暴击伤害": 1,
"攻击力": 1,
"元素精通": 1
}
},
"迪卢克": {
"常规": {
"暴击率": 1,
"暴击伤害": 1,
"攻击力": 1,
"元素精通": 1
}
},
"辛焱": {
"常规": {
"暴击率": 1,
"暴击伤害": 1,
"攻击力": 1,
"防御力": 1
}
},
"安柏": {
"常规": {
"暴击率": 1,
"暴击伤害": 1,
"攻击力": 1,
"元素充能效率": 1
}
},
"香菱": {
"常规": {
"暴击率": 1,
"暴击伤害": 1,
"攻击力": 1,
"元素精通": 1,
"元素充能效率": 1
}
},
"班尼特": {
"常规": {
"生命值": 1,
"元素充能效率": 1
},
"西风": {
"生命值": 1,
"元素充能效率": 1,
"暴击率": 0.4
},
"输出": {
"生命值": 1,
"攻击力": 1,
"暴击率": 1,
"暴击伤害": 1,
"元素充能效率": 1
}
},
"珊瑚宫心海": {
"常规": {
"生命值": 1,
"元素充能效率": 1
}
},
"达达利亚": {
"常规": {
"暴击率": 1,
"暴击伤害": 1,
"攻击力": 1,
"元素精通": 1
}
},
"行秋": {
"常规": {
"暴击率": 1,
"暴击伤害": 1,
"攻击力": 1,
"元素充能效率": 1,
"生命值": 0.4
}
},
"莫娜": {
"常规": {
"暴击率": 1,
"暴击伤害": 1,
"攻击力": 1,
"元素精通": 1,
"元素充能效率": 1
}
},
"芭芭拉": {
"常规": {
"生命值": 1,
"元素充能效率": 1
},
"西风": {
"生命值": 1,
"元素充能效率": 1,
"暴击率": 0.4
}
},
"申鹤": {
"常规": {
"攻击力": 1,
"元素充能效率": 1
},
"西风": {
"攻击力": 1,
"元素充能效率": 1,
"暴击率": 0.4
},
"输出": {
"攻击力": 1,
"暴击率": 1,
"暴击伤害": 1,
"元素充能效率": 1
}
},
"神里绫华": {
"常规": {
"暴击率": 1,
"暴击伤害": 1,
"攻击力": 1,
"元素充能效率": 1
}
},
"优菈": {
"常规": {
"暴击率": 1,
"暴击伤害": 1,
"攻击力": 1,
"元素充能效率": 1
}
},
"甘雨": {
"常规": {
"暴击率": 1,
"暴击伤害": 1,
"攻击力": 1,
"元素充能效率": 1
},
"融化": {
"暴击率": 1,
"暴击伤害": 1,
"攻击力": 1,
"元素精通": 1
}
},
"凯亚": {
"常规": {
"暴击率": 1,
"暴击伤害": 1,
"攻击力": 1,
"元素充能效率": 1
}
},
"重云": {
"常规": {
"暴击率": 1,
"暴击伤害": 1,
"攻击力": 1,
"元素充能效率": 1
}
},
"七七": {
"常规": {
"攻击力": 1,
"元素充能效率": 1
},
"西风": {
"攻击力": 1,
"元素充能效率": 1,
"暴击率": 0.4
},
"输出": {
"攻击力": 1,
"暴击率": 1,
"暴击伤害": 1
}
},
"迪奥娜": {
"常规": {
"生命值": 1,
"元素充能效率": 1
},
"西风": {
"生命值": 1,
"元素充能效率": 1,
"暴击率": 0.4
}
},
"罗莎莉亚": {
"常规": {
"暴击率": 1,
"暴击伤害": 1,
"攻击力": 1,
"元素充能效率": 1
}
},
"埃洛伊": {
"常规": {
"暴击率": 1,
"暴击伤害": 1,
"攻击力": 1
}
},
"八重神子": {
"常规": {
"暴击率": 1,
"暴击伤害": 1,
"攻击力": 1,
"元素充能效率": 1,
"元素精通": 1
}
},
"雷电将军": {
"常规": {
"暴击率": 1,
"暴击伤害": 1,
"攻击力": 1,
"元素充能效率": 1
}
},
"九条裟罗": {
"常规": {
"暴击率": 1,
"暴击伤害": 1,
"攻击力": 1,
"元素充能效率": 1
}
},
"刻晴": {
"常规": {
"暴击率": 1,
"暴击伤害": 1,
"攻击力": 1
}
},
"雷泽": {
"常规": {
"暴击率": 1,
"暴击伤害": 1,
"攻击力": 1
}
},
"菲谢尔": {
"常规": {
"暴击率": 1,
"暴击伤害": 1,
"攻击力": 1
}
},
"丽莎": {
"常规": {
"暴击率": 1,
"暴击伤害": 1,
"攻击力": 1,
"元素充能效率": 1
}
},
"北斗": {
"常规": {
"暴击率": 1,
"暴击伤害": 1,
"攻击力": 1,
"元素充能效率": 1
}
},
"雷主": {
"常规": {
"暴击率": 1,
"暴击伤害": 1,
"攻击力": 1,
"元素充能效率": 1
}
},
"早柚": {
"常规": {
"元素精通": 1,
"元素充能效率": 1
},
"西风": {
"元素精通": 1,
"元素充能效率": 1,
"暴击率": 0.4
}
},
"枫原万叶": {
"常规": {
"元素精通": 1,
"元素充能效率": 1
},
"西风": {
"元素精通": 1,
"元素充能效率": 1,
"暴击率": 0.4
},
"输出": {
"暴击率": 1,
"暴击伤害": 1,
"攻击力": 1,
"元素精通": 1,
"元素充能效率": 1
}
},
"魈": {
"常规": {
"暴击率": 1,
"暴击伤害": 1,
"攻击力": 1,
"元素充能效率": 1
}
},
"温迪": {
"常规": {
"元素充能效率": 1,
"元素精通": 1
},
"西风": {
"元素精通": 1,
"元素充能效率": 1,
"暴击率": 0.4
},
"输出": {
"暴击率": 1,
"暴击伤害": 1,
"攻击力": 1,
"元素充能效率": 1,
"元素精通": 1
}
},
"琴": {
"常规": {
"暴击率": 1,
"暴击伤害": 1,
"攻击力": 1,
"元素充能效率": 1
}
},
"砂糖": {
"常规": {
"元素充能效率": 1,
"元素精通": 1
},
"西风": {
"元素精通": 1,
"元素充能效率": 1,
"暴击率": 0.4
},
"常规": {
"暴击率": 1,
"暴击伤害": 1,
"攻击力": 1,
"元素充能效率": 1,
"元素精通": 1
}
},
"风主": {
"常规": {
"暴击率": 1,
"暴击伤害": 1,
"攻击力": 1,
"元素充能效率": 1
}
},
"荒泷一斗": {
"常规": {
"暴击率": 1,
"暴击伤害": 1,
"防御力": 1,
"元素充能效率": 1
}
},
"五郎": {
"常规": {
"防御力": 1,
"元素充能效率": 1
},
"西风": {
"防御力": 1,
"元素充能效率": 1,
"暴击率": 0.4
}
},
"阿贝多": {
"常规": {
"暴击率": 1,
"暴击伤害": 1,
"防御力": 1
}
},
"钟离": {
"常规": {
"生命值": 1,
"元素充能效率": 1
},
"西风": {
"生命值": 1,
"元素充能效率": 1,
"暴击率": 0.4
},
"岩伤": {
"暴击率": 1,
"暴击伤害": 1,
"生命值": 1,
"攻击力": 1,
"元素充能效率": 1
},
"武神": {
"暴击率": 1,
"暴击伤害": 1,
"生命值": 1,
"攻击力": 1
}
},
"诺艾尔": {
"常规": {
"暴击率": 1,
"暴击伤害": 1,
"防御力": 1,
"元素充能效率": 1
}
},
"凝光": {
"常规": {
"暴击率": 1,
"暴击伤害": 1,
"攻击力": 1
}
},
"岩主": {
"常规": {
"暴击率": 1,
"暴击伤害": 1,
"攻击力": 1,
"元素充能效率": 1
}
},
"云堇": {
"常规": {
"防御力": 1,
"元素充能效率": 1
},
"西风": {
"防御力": 1,
"元素充能效率": 1,
"暴击率": 0.4
}
},
"神里绫人": {
"常规": {
"暴击率": 1,
"暴击伤害": 1,
"攻击力": 1,
"生命值": 0.6
}
},
"夜兰": {
"常规": {
"暴击率": 1,
"暴击伤害": 1,
"生命值": 1,
"元素充能效率": 1
}
},
"久岐忍": {
"常规": {
"元素精通": 1,
"元素充能效率": 1
},
"西风": {
"元素精通": 1,
"元素充能效率": 1,
"暴击率": 0.4
},
"输出": {
"暴击率": 1,
"暴击伤害": 1,
"攻击力": 1,
"元素精通": 1,
"元素充能效率": 1
}
}
},
"Talent": {
"胡桃": [1, 2],
"托马": [1, 2],
"宵宫": [1, 2],
"烟绯": [1, 2],
"可莉": [1, 2],
"迪卢克": [1, 2],
"辛焱": [1, 2],
"安柏": [2, 1],
"香菱": [2, 1],
"班尼特": [1, 2],
"珊瑚宫心海": [2, 1],
"达达利亚": [1, 2],
"行秋": [2, 1],
"莫娜": [2, 1],
"芭芭拉": [2, 1],
"申鹤": [1, 2],
"神里绫华": [3, 1],
"优菈": [2, 1],
"甘雨": [2, 1],
"凯亚": [1, 2],
"重云": [2, 1],
"七七": [2, 1],
"迪奥娜": [2, 1],
"罗莎莉亚": [1, 2],
"埃洛伊": [0, 0],
"八重神子": [1, 2],
"雷电将军": [2, 1],
"九条裟罗": [2, 1],
"刻晴": [2, 1],
"雷泽": [2, 1],
"菲谢尔": [1, 2],
"丽莎": [2, 1],
"北斗": [1, 2],
"雷主": [1, 2],
"早柚": [2, 1],
"枫原万叶": [1, 2],
"魈": [1, 2],
"温迪": [2, 1],
"琴": [2, 1],
"砂糖": [1, 2],
"风主": [1, 2],
"荒泷一斗": [1, 2],
"五郎": [1, 2],
"阿贝多": [1, 2],
"钟离": [1, 2],
"诺艾尔": [1, 2],
"凝光": [2, 1],
"岩主": [1, 2],
"云堇": [2, 1],
"神里绫人": [1, 2],
"夜兰": [2, 1],
"久岐忍": [1, 2]
"胡桃": [
1,
2
],
"托马": [
1,
2
],
"宵宫": [
1,
2
],
"烟绯": [
1,
2
],
"可莉": [
1,
2
],
"迪卢克": [
1,
2
],
"辛焱": [
1,
2
],
"安柏": [
2,
1
],
"香菱": [
2,
1
],
"班尼特": [
1,
2
],
"珊瑚宫心海": [
2,
1
],
"达达利亚": [
1,
2
],
"行秋": [
2,
1
],
"莫娜": [
2,
1
],
"芭芭拉": [
2,
1
],
"申鹤": [
1,
2
],
"神里绫华": [
3,
1
],
"优菈": [
2,
1
],
"甘雨": [
2,
1
],
"凯亚": [
1,
2
],
"重云": [
2,
1
],
"七七": [
2,
1
],
"迪奥娜": [
2,
1
],
"罗莎莉亚": [
1,
2
],
"埃洛伊": [
0,
0
],
"八重神子": [
1,
2
],
"雷电将军": [
2,
1
],
"九条裟罗": [
2,
1
],
"刻晴": [
2,
1
],
"雷泽": [
2,
1
],
"菲谢尔": [
1,
2
],
"丽莎": [
2,
1
],
"北斗": [
1,
2
],
"雷主": [
1,
2
],
"早柚": [
2,
1
],
"枫原万叶": [
1,
2
],
"魈": [
1,
2
],
"温迪": [
2,
1
],
"琴": [
2,
1
],
"砂糖": [
1,
2
],
"风主": [
1,
2
],
"荒泷一斗": [
1,
2
],
"五郎": [
1,
2
],
"阿贝多": [
1,
2
],
"钟离": [
1,
2
],
"诺艾尔": [
1,
2
],
"凝光": [
2,
1
],
"岩主": [
1,
2
],
"云堇": [
2,
1
],
"神里绫人": [
1,
2
],
"夜兰": [
2,
1
],
"久岐忍": [
1,
2
]
}
}

View File

@ -51,6 +51,7 @@
"神里绫人": "绫人",
"夜兰": "夜兰",
"久岐忍": "阿忍",
"鹿野院平藏": "鹿野",
"神乐之真意": "神乐",
"息灾": "息灾",
"赤角石溃杵": "赤角",