mirror of
https://github.com/xuthus83/LittlePaimon.git
synced 2024-12-16 13:40:53 +08:00
✨ 新增深渊配队
,将深渊相关指令统一到一个插件,修改设置别名
命令
This commit is contained in:
parent
b40535e45f
commit
24d4ac595a
83
LittlePaimon/plugins/Paimon_Abyss/__init__.py
Normal file
83
LittlePaimon/plugins/Paimon_Abyss/__init__.py
Normal file
@ -0,0 +1,83 @@
|
||||
from nonebot import on_command
|
||||
from nonebot.adapters.onebot.v11 import Message, MessageEvent, GroupMessageEvent
|
||||
from nonebot.params import Arg
|
||||
from nonebot.plugin import PluginMetadata
|
||||
|
||||
from LittlePaimon.utils import logger
|
||||
from LittlePaimon.utils.genshin import GenshinInfoManager
|
||||
from LittlePaimon.utils.message import CommandPlayer
|
||||
from .abyss_statistics import get_statistics
|
||||
from .draw_abyss import draw_abyss_card
|
||||
from .youchuang import draw_team
|
||||
|
||||
__plugin_meta__ = PluginMetadata(
|
||||
name='原神深渊查询',
|
||||
description='原神深渊查询',
|
||||
usage='...',
|
||||
extra={
|
||||
'author': '惜月',
|
||||
'version': '3.0',
|
||||
'priority': 2,
|
||||
}
|
||||
)
|
||||
|
||||
sy = on_command('sy', aliases={'深渊战报', '深渊信息'}, priority=10, block=True, state={
|
||||
'pm_name': 'sy',
|
||||
'pm_description': '查看本期|上期的深渊战报',
|
||||
'pm_usage': 'sy(uid)(本期|上期)',
|
||||
'pm_priority': 1
|
||||
})
|
||||
abyss_stat = on_command('深渊统计', aliases={'深渊群数据', '深渊群排行'}, priority=10, block=True, state={
|
||||
'pm_name': '深渊统计',
|
||||
'pm_description': '查看本群深渊统计,仅群可用',
|
||||
'pm_usage': '深渊统计',
|
||||
'pm_priority': 2
|
||||
})
|
||||
abyss_team = on_command('深渊配队', aliases={'配队推荐', '深渊阵容'}, priority=10, block=True, state={
|
||||
'pm_name': '深渊配队',
|
||||
'pm_description': '查看深渊配队推荐,数据来源于游创工坊',
|
||||
'pm_usage': '深渊配队',
|
||||
'pm_priority': 3
|
||||
})
|
||||
|
||||
|
||||
@sy.handle()
|
||||
async def _(event: MessageEvent, players=CommandPlayer(), msg: str = Arg('msg')):
|
||||
logger.info('原神深渊战报', '开始执行')
|
||||
abyss_index = 2 if any(i in msg for i in ['上', 'last']) else 1
|
||||
msg = Message()
|
||||
for player in players:
|
||||
logger.info('原神深渊战报', '➤ ', {'用户': players[0].user_id, 'UID': players[0].uid})
|
||||
gim = GenshinInfoManager(player.user_id, player.uid)
|
||||
abyss_info = await gim.get_abyss_info(abyss_index)
|
||||
if isinstance(abyss_info, str):
|
||||
logger.info('原神深渊战报', '➤➤', {}, abyss_info, False)
|
||||
msg += f'UID{player.uid}{abyss_info}\n'
|
||||
else:
|
||||
logger.info('原神深渊战报', '➤➤', {}, '数据获取成功', True)
|
||||
try:
|
||||
img = await draw_abyss_card(abyss_info)
|
||||
logger.info('原神深渊战报', '➤➤➤', {}, '制图完成', True)
|
||||
msg += img
|
||||
except Exception as e:
|
||||
logger.info('原神深渊战报', '➤➤➤', {}, f'制图出错:{e}', False)
|
||||
msg += F'UID{player.uid}制图时出错:{e}\n'
|
||||
await sy.finish(msg, at_sender=True)
|
||||
|
||||
|
||||
@abyss_stat.handle()
|
||||
async def _(event: GroupMessageEvent):
|
||||
try:
|
||||
result = await get_statistics(event.group_id)
|
||||
except Exception as e:
|
||||
result = f'制作深渊统计时出错:{e}'
|
||||
await abyss_stat.finish(result)
|
||||
|
||||
|
||||
@abyss_team.handle()
|
||||
async def _(event: MessageEvent):
|
||||
try:
|
||||
result = await draw_team(str(event.user_id))
|
||||
except Exception as e:
|
||||
result = f'制作深渊配队时出错:{e}'
|
||||
await abyss_team.finish(result)
|
1
LittlePaimon/plugins/Paimon_Abyss/youchuang/__init__.py
Normal file
1
LittlePaimon/plugins/Paimon_Abyss/youchuang/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
from .draw import draw_team
|
39
LittlePaimon/plugins/Paimon_Abyss/youchuang/api.py
Normal file
39
LittlePaimon/plugins/Paimon_Abyss/youchuang/api.py
Normal file
@ -0,0 +1,39 @@
|
||||
from typing import List, Tuple
|
||||
|
||||
from pydantic import parse_obj_as
|
||||
from LittlePaimon.utils.requests import aiorequests
|
||||
from .models import TeamRateResult, TeamRate
|
||||
|
||||
# API均来自微信公众号`原神创意工坊`,感谢坊主提供的API
|
||||
BASE_API = 'https://www.youchuang.fun'
|
||||
TEAM_RATE_API = f'{BASE_API}/gamerole/formationRate'
|
||||
|
||||
VERSION_API = 'https://api-cloudgame-static.mihoyo.com/hk4e_cg_cn/gamer/api/getFunctionShieldNew?client_type=1'
|
||||
HEADERS = {
|
||||
'Host': 'www.youchuang.fun',
|
||||
'Referer': 'https://servicewechat.com/wxce4dbe0cb0f764b3/91/page-frame.html',
|
||||
'User-Agent': 'Mozilla/5.0 (iPad; CPU OS 15_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) '
|
||||
'Mobile/15E148 MicroMessenger/8.0.20(0x1800142f) NetType/WIFI Language/zh_CN',
|
||||
'content-type': 'application/json'
|
||||
}
|
||||
|
||||
|
||||
async def get_game_version() -> float:
|
||||
data = await aiorequests.get(VERSION_API)
|
||||
data = data.json()
|
||||
return float(data['data']['config']['cg.key_function_queue_news']['versions'][0].replace('.0', ''))
|
||||
|
||||
|
||||
async def get_team_rate() -> Tuple[TeamRateResult, float]:
|
||||
version = await get_game_version()
|
||||
data_up = (await aiorequests.post(TEAM_RATE_API, json={
|
||||
'version': version,
|
||||
'layer': 1
|
||||
}, headers=HEADERS)).json()['result']
|
||||
data_down = (await aiorequests.post(TEAM_RATE_API, json={
|
||||
'version': version,
|
||||
'layer': 2
|
||||
}, headers=HEADERS)).json()['result']
|
||||
return TeamRateResult(rateListUp=parse_obj_as(List[TeamRate], data_up['rateList']),
|
||||
rateListDown=parse_obj_as(List[TeamRate], data_down['rateList']),
|
||||
userCount=data_up['userCount']), version
|
60
LittlePaimon/plugins/Paimon_Abyss/youchuang/draw.py
Normal file
60
LittlePaimon/plugins/Paimon_Abyss/youchuang/draw.py
Normal file
@ -0,0 +1,60 @@
|
||||
import asyncio
|
||||
from typing import List
|
||||
|
||||
from LittlePaimon.database.models import Character, LastQuery
|
||||
from LittlePaimon.config import RESOURCE_BASE_PATH
|
||||
from LittlePaimon.utils.files import load_image
|
||||
from LittlePaimon.utils.alias import get_chara_icon
|
||||
from LittlePaimon.utils.image import PMImage, font_manager as fm
|
||||
from LittlePaimon.utils.message import MessageBuild
|
||||
from .api import get_team_rate
|
||||
from .models import TeamRate
|
||||
|
||||
|
||||
async def draw_team_line(up: TeamRate, down: TeamRate, characters: List[str]) -> PMImage:
|
||||
img = PMImage(size=(1013, 127), mode='RGBA', color=(0, 0, 0, 0))
|
||||
for i, member in enumerate(up.formation):
|
||||
owned = member.name in characters if characters else True
|
||||
await img.paste(await load_image(RESOURCE_BASE_PATH / 'icon' / f'{member.star}starbox.png'), (110 * i, 0))
|
||||
await img.paste(
|
||||
await load_image(RESOURCE_BASE_PATH / 'avatar' / f'{get_chara_icon(name=member.name)}.png', size=(100, 100)),
|
||||
(110 * i, 1))
|
||||
await img.text(member.name if owned else '未拥有', (110 * i, 110 * i + 100), 103, fm.get('hywh', 18), '#33231a',
|
||||
'center')
|
||||
if not owned:
|
||||
await img.paste(await load_image(RESOURCE_BASE_PATH / 'icon' / 'grey_box.png'), (110 * i, 0))
|
||||
await img.text(f'{round(up.rate * 100, 2)}%', 439, 30, fm.get('bahnschrift_bold', 30), '#33231a')
|
||||
for i, member in enumerate(down.formation):
|
||||
owned = member.name in characters if characters else True
|
||||
await img.paste(await load_image(RESOURCE_BASE_PATH / 'icon' / f'{member.star}starbox.png'), (583 + 110 * i, 0))
|
||||
await img.paste(
|
||||
await load_image(RESOURCE_BASE_PATH / 'avatar' / f'{get_chara_icon(name=member.name)}.png', size=(100, 100)),
|
||||
(583 + 110 * i, 1))
|
||||
await img.text(member.name if owned else '未拥有', (583 + 110 * i, 110 * i + 683), 103, fm.get('hywh', 18), '#33231a',
|
||||
'center')
|
||||
if not owned:
|
||||
await img.paste(await load_image(RESOURCE_BASE_PATH / 'icon' / 'grey_box.png'), (583 + 110 * i, 0))
|
||||
await img.text(f'{round(down.rate * 100, 2)}%', 574, 59, fm.get('bahnschrift_bold', 30), '#33231a', 'right')
|
||||
return img
|
||||
|
||||
|
||||
async def draw_team(user_id: str):
|
||||
if last_query := await LastQuery.get_or_none(user_id=user_id):
|
||||
charas = await Character.filter(user_id=user_id, uid=last_query.uid)
|
||||
else:
|
||||
charas = await Character.filter(user_id=user_id)
|
||||
characters = [chara.name for chara in charas if chara is not None]
|
||||
team_data, version = await get_team_rate()
|
||||
if characters:
|
||||
team_data.sort_by_own(characters)
|
||||
img = PMImage(RESOURCE_BASE_PATH / 'abyss' / 'team_bg.png')
|
||||
await img.text('深境螺旋十二层配队', 36, 29, fm.get('优设标题黑', 72), '#40342d')
|
||||
await img.paste(await load_image(RESOURCE_BASE_PATH / 'general' / 'bubble.png'), (625, 35))
|
||||
await img.text(f'{version}版本', (625, 625 + 147), 38, fm.get('SourceHanSansCN-Bold.otf', 30), 'white', 'center')
|
||||
await img.text('CREATED BY LITTLEPAIMON | DATA FROM YOU-CHUANG',
|
||||
1025, 158, fm.get('bahnschrift_regular.ttf', 30), '#8c4c2e', 'right')
|
||||
|
||||
await asyncio.gather(*[img.paste(await draw_team_line(team_data.rateListUp[i], team_data.rateListDown[i], characters), (33, 222 + 153 * i)) for i in range(15)])
|
||||
return MessageBuild.Image(img, mode='RGB', quality=80)
|
||||
|
||||
|
33
LittlePaimon/plugins/Paimon_Abyss/youchuang/models.py
Normal file
33
LittlePaimon/plugins/Paimon_Abyss/youchuang/models.py
Normal file
@ -0,0 +1,33 @@
|
||||
from typing import List, Optional
|
||||
|
||||
from pydantic import BaseModel, validator
|
||||
|
||||
|
||||
class Member(BaseModel):
|
||||
star: int
|
||||
attr: str
|
||||
name: str
|
||||
|
||||
|
||||
class TeamRate(BaseModel):
|
||||
rate: float
|
||||
formation: List[Member]
|
||||
ownerNum: Optional[int]
|
||||
|
||||
@validator('rate', pre=True)
|
||||
def str2float(cls, v):
|
||||
return float(v.replace('%', '')) / 100.0 if isinstance(v, str) else v
|
||||
|
||||
|
||||
class TeamRateResult(BaseModel):
|
||||
rateListUp: List[TeamRate]
|
||||
rateListDown: List[TeamRate]
|
||||
userCount: int
|
||||
|
||||
def sort_by_own(self, characters: List[str]):
|
||||
for team in self.rateListUp:
|
||||
team.ownerNum = len(set(characters) & {member.name for member in team.formation})
|
||||
for team in self.rateListDown:
|
||||
team.ownerNum = len(set(characters) & {member.name for member in team.formation})
|
||||
self.rateListUp.sort(key=lambda x: (x.ownerNum / 4 * x.rate), reverse=True)
|
||||
self.rateListDown.sort(key=lambda x: (x.ownerNum / 4 * x.rate), reverse=True)
|
@ -1,7 +1,8 @@
|
||||
from nonebot import on_command, on_regex
|
||||
from nonebot.adapters.onebot.v11 import Message, MessageEvent, MessageSegment, GroupMessageEvent
|
||||
from nonebot.params import Arg, RegexDict, CommandArg
|
||||
from nonebot import on_command
|
||||
from nonebot.adapters.onebot.v11 import Message, MessageEvent, MessageSegment
|
||||
from nonebot.params import Arg, ArgPlainText, CommandArg
|
||||
from nonebot.plugin import PluginMetadata
|
||||
from nonebot.typing import T_State
|
||||
|
||||
from LittlePaimon import NICKNAME
|
||||
from LittlePaimon.database.models import PlayerAlias
|
||||
@ -9,14 +10,12 @@ from LittlePaimon.utils import logger
|
||||
from LittlePaimon.utils.message import CommandPlayer, CommandCharacter, CommandUID
|
||||
from LittlePaimon.utils.genshin import GenshinInfoManager
|
||||
from LittlePaimon.utils.tool import freq_limiter
|
||||
from LittlePaimon.utils.typing import CHARA_RE
|
||||
from LittlePaimon.utils.typing import CHARACTERS
|
||||
|
||||
from .draw_player_card import draw_player_card
|
||||
from .draw_character_bag import draw_chara_bag
|
||||
from .draw_character_detail import draw_chara_detail
|
||||
from .draw_character_card import draw_chara_card
|
||||
from .draw_abyss import draw_abyss_card
|
||||
from .abyss_statistics import get_statistics
|
||||
|
||||
__plugin_meta__ = PluginMetadata(
|
||||
name='原神信息查询',
|
||||
@ -41,12 +40,6 @@ ysa = on_command('ysa', aliases={'角色背包', '练度统计'}, priority=10, b
|
||||
'pm_usage': 'ysa(uid)',
|
||||
'pm_priority': 2
|
||||
})
|
||||
sy = on_command('sy', aliases={'深渊战报', '深渊信息'}, priority=10, block=True, state={
|
||||
'pm_name': 'sy',
|
||||
'pm_description': '查看本期|上期的深渊战报',
|
||||
'pm_usage': 'sy(uid)(本期|上期)',
|
||||
'pm_priority': 3
|
||||
})
|
||||
ysc = on_command('ysc', aliases={'角色图', '角色卡片'}, priority=10, block=True, state={
|
||||
'pm_name': 'ysc',
|
||||
'pm_description': '随机角色同人图+角色信息卡片',
|
||||
@ -65,14 +58,12 @@ update_info = on_command('udi', aliases={'更新角色信息', '更新面板', '
|
||||
'pm_usage': '更新角色信息[天赋](uid)',
|
||||
'pm_priority': 6
|
||||
})
|
||||
add_alias = on_regex(
|
||||
rf'((?P<chara>{CHARA_RE})是[我俺咱]的?(?P<alias>\w+))|([我俺咱]的?(?P<alias2>\w+)[是叫名](?P<chara2>{CHARA_RE}))', priority=10,
|
||||
block=True, state={
|
||||
'pm_name': '角色别名设置',
|
||||
'pm_description': '设置专属于你的角色别名',
|
||||
'pm_usage': '<角色名>是我<别名>',
|
||||
'pm_priority': 7
|
||||
})
|
||||
add_alias = on_command('设置别名', priority=10, block=True, state={
|
||||
'pm_name': '角色别名设置',
|
||||
'pm_description': '设置专属于你的角色别名,例如【设置别名钟离 老公】',
|
||||
'pm_usage': '设置别名<角色> <别名>',
|
||||
'pm_priority': 7
|
||||
})
|
||||
delete_alias = on_command('删除别名', priority=10, block=True, state={
|
||||
'pm_name': '角色别名删除',
|
||||
'pm_description': '删除你已设置的角色别名',
|
||||
@ -85,12 +76,6 @@ show_alias = on_command('查看别名', priority=10, block=True, state={
|
||||
'pm_usage': '查看别名',
|
||||
'pm_priority': 9
|
||||
})
|
||||
show_abyss = on_command('深渊统计', priority=10, block=True, state={
|
||||
'pm_name': '深渊统计',
|
||||
'pm_description': '查看本群深渊统计,仅群可用',
|
||||
'pm_usage': '深渊统计',
|
||||
'pm_priority': 10
|
||||
})
|
||||
|
||||
|
||||
@ys.handle()
|
||||
@ -149,30 +134,6 @@ async def _(event: MessageEvent, players=CommandPlayer(2)):
|
||||
await ysa.finish(msg, at_sender=True)
|
||||
|
||||
|
||||
@sy.handle()
|
||||
async def _(event: MessageEvent, players=CommandPlayer(), msg: str = Arg('msg')):
|
||||
logger.info('原神深渊战报', '开始执行')
|
||||
abyss_index = 2 if any(i in msg for i in ['上', 'last']) else 1
|
||||
msg = Message()
|
||||
for player in players:
|
||||
logger.info('原神深渊战报', '➤ ', {'用户': players[0].user_id, 'UID': players[0].uid})
|
||||
gim = GenshinInfoManager(player.user_id, player.uid)
|
||||
abyss_info = await gim.get_abyss_info(abyss_index)
|
||||
if isinstance(abyss_info, str):
|
||||
logger.info('原神深渊战报', '➤➤', {}, abyss_info, False)
|
||||
msg += f'UID{player.uid}{abyss_info}\n'
|
||||
else:
|
||||
logger.info('原神深渊战报', '➤➤', {}, '数据获取成功', True)
|
||||
try:
|
||||
img = await draw_abyss_card(abyss_info)
|
||||
logger.info('原神深渊战报', '➤➤➤', {}, '制图完成', True)
|
||||
msg += img
|
||||
except Exception as e:
|
||||
logger.info('原神深渊战报', '➤➤➤', {}, f'制图出错:{e}', False)
|
||||
msg += F'UID{player.uid}制图时出错:{e}\n'
|
||||
await ysa.finish(msg, at_sender=True)
|
||||
|
||||
|
||||
@ysc.handle()
|
||||
async def _(event: MessageEvent, players=CommandPlayer(only_cn=False), characters=CommandCharacter()):
|
||||
logger.info('原神角色卡片', '开始执行')
|
||||
@ -267,21 +228,42 @@ async def _(event: MessageEvent, uid=CommandUID(), msg: str = Arg('msg')):
|
||||
|
||||
|
||||
@add_alias.handle()
|
||||
async def _(event: MessageEvent, regex_dict: dict = RegexDict()):
|
||||
chara = regex_dict['chara'] or regex_dict['chara2']
|
||||
alias = regex_dict['alias'] or regex_dict['alias2']
|
||||
async def _(event: MessageEvent, state: T_State, msg: Message = CommandArg()):
|
||||
msg = msg.extract_plain_text().strip().split(' ')
|
||||
if msg[0] in CHARACTERS:
|
||||
state['chara'] = Message(msg[0])
|
||||
else:
|
||||
await add_alias.finish(f'{NICKNAME}不认识{msg[0]}哦,请使用角色全称', at_sender=True)
|
||||
if len(msg) > 1:
|
||||
state['alias'] = Message(msg[1])
|
||||
|
||||
|
||||
@add_alias.got('alias', prompt=Message.template('你想把{chara}设置为你的谁呢?'))
|
||||
async def _(event: MessageEvent, chara: str = ArgPlainText('chara'), alias: str = ArgPlainText('alias')):
|
||||
await PlayerAlias.update_or_create(user_id=str(event.user_id), alias=alias, defaults={'character': chara})
|
||||
await add_alias.finish(f'{NICKNAME}知道{chara}是你的{alias}啦..')
|
||||
await add_alias.finish(f'设置成功,{NICKNAME}知道{chara}是你的{alias}啦..')
|
||||
|
||||
|
||||
@delete_alias.handle()
|
||||
async def _(event: MessageEvent, msg: Message = CommandArg()):
|
||||
msg = msg.extract_plain_text().strip()
|
||||
if alias := await PlayerAlias.get_or_none(user_id=str(event.user_id), alias=msg):
|
||||
async def _(event: MessageEvent, state: T_State, msg: Message = CommandArg()):
|
||||
if msg:
|
||||
state['alias'] = msg
|
||||
elif aliases := await PlayerAlias.filter(user_id=str(event.user_id)).all():
|
||||
state['msg'] = '你已设置以下别名:\n' + '\n'.join([f'{i.alias} -> {i.character}' for i in aliases]) + '\n请输入你想删除的别名或发送"全部"删除全部别名'
|
||||
else:
|
||||
await delete_alias.finish('你还没有设置任何别名哦')
|
||||
|
||||
|
||||
@delete_alias.got('alias', prompt=Message.template('{msg}'))
|
||||
async def _(event: MessageEvent, msg: str = ArgPlainText('alias')):
|
||||
if msg == '全部':
|
||||
await PlayerAlias.filter(user_id=str(event.user_id)).delete()
|
||||
await delete_alias.finish('已删除你设置的全部别名')
|
||||
elif alias := await PlayerAlias.get_or_none(user_id=str(event.user_id), alias=msg):
|
||||
await alias.delete()
|
||||
await delete_alias.finish(f'别名{msg}删除成功!', at_sender=True)
|
||||
else:
|
||||
await delete_alias.finish(f'你并没有将{msg}设置为某个角色的别名', at_sender=True)
|
||||
await delete_alias.reject(f'你并没有将{msg}设置为某个角色的别名', at_sender=True)
|
||||
|
||||
|
||||
@show_alias.handle()
|
||||
@ -291,9 +273,3 @@ async def _(event: MessageEvent):
|
||||
at_sender=True)
|
||||
else:
|
||||
await show_alias.finish('你还没有设置过角色别名哦', at_sender=True)
|
||||
|
||||
|
||||
@show_abyss.handle()
|
||||
async def _(event: GroupMessageEvent):
|
||||
result = await get_statistics(event.group_id)
|
||||
await show_abyss.finish(result)
|
||||
|
Loading…
x
Reference in New Issue
Block a user