适配nonebot2 beta4,fix bug

This commit is contained in:
CMHopeSunshine 2022-06-21 16:26:13 +08:00
parent 5e227d9647
commit ba21faad20
23 changed files with 556 additions and 271 deletions

View File

@ -1,11 +1,14 @@
import asyncio import asyncio
from pathlib import Path from pathlib import Path
from typing import Union
from nonebot import on_command from nonebot import on_command
from nonebot.adapters.onebot.v11 import GroupMessageEvent, MessageSegment, Bot, MessageEvent from nonebot.adapters.onebot.v11 import GroupMessageEvent, PrivateMessageEvent, MessageSegment, Bot, MessageEvent, \
Message
from nonebot.exception import FinishedException from nonebot.exception import FinishedException
from nonebot.params import CommandArg from nonebot.params import CommandArg
from nonebot.permission import SUPERUSER from nonebot.permission import SUPERUSER
from nonebot.plugin import PluginMetadata
from utils.config import config from utils.config import config
from . import download_data from . import download_data
@ -16,10 +19,22 @@ setting_time = config.paimon_guess_voice # 游戏持续时间
dir_name = Path() / 'data' / 'LittlePaimon' / 'guess_voice' / 'voice' dir_name = Path() / 'data' / 'LittlePaimon' / 'guess_voice' / 'voice'
__paimon_help__ = {
__plugin_meta__ = PluginMetadata(
name="原神猜语音",
description="小派蒙的原神猜语音模块",
usage=(
"原神猜语音[语言]\n"
"原神语音[语言]<角色名>\n"
"更新原神语音资源\n"
),
extra={
'type': '娱乐', 'type': '娱乐',
'range': ['group'] 'range': ['private', 'group'],
} "author": "惜月 <277073121@qq.com>",
"version": "1.0.0",
},
)
guess_game = on_command('原神猜语音', priority=12, block=True) guess_game = on_command('原神猜语音', priority=12, block=True)
guess_game.__paimon_help__ = { guess_game.__paimon_help__ = {
@ -45,9 +60,9 @@ async def download_voice(bot: Bot, event: MessageEvent):
@guess_game.handle() @guess_game.handle()
async def guess_genshin_voice(bot: Bot, event: GroupMessageEvent, msg=CommandArg()): async def guess_genshin_voice(bot: Bot, event: GroupMessageEvent, msg: Message = CommandArg()):
await download_voice(bot, event) await download_voice(bot, event)
keyword = str(msg).strip() keyword = msg.extract_plain_text().strip()
guess = Guess(event.group_id, time=setting_time) guess = Guess(event.group_id, time=setting_time)
hard_mode = False hard_mode = False
@ -85,13 +100,20 @@ async def guess_genshin_voice(bot: Bot, event: GroupMessageEvent, msg=CommandArg
@ys_voice.handle() @ys_voice.handle()
async def get_genshin_voice(bot: Bot, event: GroupMessageEvent, msg=CommandArg()): async def get_genshin_voice(bot: Bot, event: Union[GroupMessageEvent, PrivateMessageEvent], msg: Message = CommandArg()):
name = str(msg).strip() name = msg.extract_plain_text().strip()
if name.startswith(''): if name.startswith(''):
language = '' language = ''
name = name[1:] name = name[1:]
elif name.startswith(''):
language = ''
name = name[1:]
elif name.startswith(''):
language = ''
name = name[1:]
else: else:
language = '' language = ''
name = name.replace('', '')
await download_voice(bot, event) await download_voice(bot, event)
path = await get_random_voice(name, language) path = await get_random_voice(name, language)
if not path: if not path:
@ -100,7 +122,7 @@ async def get_genshin_voice(bot: Bot, event: GroupMessageEvent, msg=CommandArg()
@update_ys_voice.handle() @update_ys_voice.handle()
async def update_genshin_voice(bot: Bot, event: GroupMessageEvent): async def update_genshin_voice(bot: Bot, event: Union[GroupMessageEvent, PrivateMessageEvent]):
await update_ys_voice.send('将在后台开始更新原神语音资源,请耐心等待资源下载完成后再使用原神语音') await update_ys_voice.send('将在后台开始更新原神语音资源,请耐心等待资源下载完成后再使用原神语音')
await download_data.update_voice_data() await download_data.update_voice_data()
await update_ys_voice.finish('原神语音资源更新完成') await update_ys_voice.finish('原神语音资源更新完成')

View File

@ -1,24 +1,30 @@
from nonebot import require, get_bot, on_command, logger from nonebot import require, get_bot, on_command, logger
from nonebot.adapters.onebot.v11 import MessageEvent, Message from nonebot.adapters.onebot.v11 import MessageEvent, Message
from nonebot.params import CommandArg from nonebot.params import CommandArg
from nonebot.plugin import PluginMetadata
from utils.file_handler import load_json, save_json from utils.file_handler import load_json, save_json
from utils.message_util import MessageBuild, get_message_id from utils.message_util import MessageBuild, get_message_id
from .generate import * from .generate import *
import re import re
HELP_STR = ''' require('nonebot_plugin_apscheduler')
原神活动日历 from nonebot_plugin_apscheduler import scheduler
原神日历 : 查看本群订阅服务器日历
原神日历 on/off : 订阅/取消订阅指定服务器的日历推送
原神日历 time : : 设置日历推送时间
原神日历 status : 查看本群日历推送设置
'''.strip()
__paimon_help__ = { __plugin_meta__ = PluginMetadata(
name="原神日历",
description="查看原神活动日历",
usage=(
"原神日历 : 查看本群订阅服务器日历\n"
"原神日历 on 时间/off : 订阅/取消订阅指定服务器的日历推送\n"
),
extra={
'type': '原神Wiki', 'type': '原神Wiki',
'range': ['private', 'group', 'guild'] 'range': ['private', 'group', 'guild'],
} "author": "nicklly <1134741727@qq.com>",
"version": "1.0.0",
},
)
calendar = on_command('原神日历', aliases={"原神日历", 'ysrl', '原神日程'}, priority=24, block=True) calendar = on_command('原神日历', aliases={"原神日历", 'ysrl', '原神日程'}, priority=24, block=True)
calendar.__paimon_help__ = { calendar.__paimon_help__ = {
@ -26,7 +32,6 @@ calendar.__paimon_help__ = {
"introduce": "查看原神活动日历后加on时间/off可以开启定时推送", "introduce": "查看原神活动日历后加on时间/off可以开启定时推送",
"priority": 99 "priority": 99
} }
scheduler = require('nonebot_plugin_apscheduler').scheduler
async def send_calendar(push_id, push_data): async def send_calendar(push_id, push_data):

View File

@ -20,12 +20,14 @@ from utils.config import config
message_id_lock = threading.Lock() message_id_lock = threading.Lock()
message_id_dict = {} message_id_dict = {}
# 检测是否开启该群的机器学习 # 检测是否开启该群的机器学习
def checkGroup(event: GroupMessageEvent) -> bool: def checkGroup(event: GroupMessageEvent) -> bool:
if event.group_id in Chat.learningGroup: if event.group_id in Chat.learningGroup:
return True return True
return False return False
async def check_accounts(event: GroupMessageEvent) -> bool: async def check_accounts(event: GroupMessageEvent) -> bool:
# 不响应其他nonebot_plugin_gocqhttp机器人账号的信息 # 不响应其他nonebot_plugin_gocqhttp机器人账号的信息
if os.path.exists('accounts'): if os.path.exists('accounts'):
@ -91,7 +93,6 @@ async def is_shutup(self_id: int, group_id: int) -> bool:
@any_msg.handle() @any_msg.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State): async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
delay = random.randint(2, 4) delay = random.randint(2, 4)
for item in state['answers']: for item in state['answers']:
logger.info(f'repeater派蒙[{event.self_id}]准备向群[{event.group_id}]回复[{item}]') logger.info(f'repeater派蒙[{event.self_id}]准备向群[{event.group_id}]回复[{item}]')
@ -220,6 +221,7 @@ def update_data():
Chat.clearup_context() Chat.clearup_context()
Chat.completely_sober() Chat.completely_sober()
# 群组开启 # 群组开启
onLearningGroup = on_message( onLearningGroup = on_message(
rule=to_me() & keyword("派蒙学习开启", "说怪话"), rule=to_me() & keyword("派蒙学习开启", "说怪话"),
@ -232,6 +234,8 @@ onLearningGroup.__paimon_help__ = {
"introduce": "开启派蒙在该群的机器学习能力", "introduce": "开启派蒙在该群的机器学习能力",
"priority": 94 "priority": 94
} }
@onLearningGroup.handle() @onLearningGroup.handle()
async def _(bot: Bot, event: GroupMessageEvent): async def _(bot: Bot, event: GroupMessageEvent):
if checkGroup(event): if checkGroup(event):
@ -240,6 +244,7 @@ async def _(bot: Bot, event: GroupMessageEvent):
Chat.learningGroup.append(event.group_id) Chat.learningGroup.append(event.group_id)
await onLearningGroup.finish("派蒙开始学习群友说怪话!") await onLearningGroup.finish("派蒙开始学习群友说怪话!")
# 群组关闭 # 群组关闭
offLearningGroup = on_message( offLearningGroup = on_message(
rule=to_me() & keyword("派蒙学习关闭", "不准说怪话"), rule=to_me() & keyword("派蒙学习关闭", "不准说怪话"),
@ -252,6 +257,8 @@ offLearningGroup.__paimon_help__ = {
"introduce": "关闭派蒙在该群的机器学习能力", "introduce": "关闭派蒙在该群的机器学习能力",
"priority": 95 "priority": 95
} }
@offLearningGroup.handle() @offLearningGroup.handle()
async def _(bot: Bot, event: GroupMessageEvent): async def _(bot: Bot, event: GroupMessageEvent):
if not checkGroup(event): if not checkGroup(event):
@ -260,6 +267,7 @@ async def _(bot: Bot, event: GroupMessageEvent):
Chat.learningGroup.remove(event.group_id) Chat.learningGroup.remove(event.group_id)
await offLearningGroup.finish("派蒙不学就是了TAT") await offLearningGroup.finish("派蒙不学就是了TAT")
# 发癫 # 发癫
fun_msg = on_message( fun_msg = on_message(
rule=to_me() & keyword('发癫', '派蒙发癫', '喝酒') & Rule(checkGroup), rule=to_me() & keyword('发癫', '派蒙发癫', '喝酒') & Rule(checkGroup),
@ -272,6 +280,8 @@ fun_msg.__paimon_help__ = {
"introduce": "派蒙喝醉了在群里发癫", "introduce": "派蒙喝醉了在群里发癫",
"priority": 96 "priority": 96
} }
@fun_msg.handle() @fun_msg.handle()
async def funmsg(bot: Bot, event: GroupMessageEvent): async def funmsg(bot: Bot, event: GroupMessageEvent):
logger.info(f'repeater派蒙开始发癫') logger.info(f'repeater派蒙开始发癫')
@ -284,6 +294,7 @@ async def funmsg(bot: Bot, event: GroupMessageEvent):
msg_send = ['呀,旅行者。你今天走起路来,怎么看着摇摇晃晃的?嘿嘿嘿~~~', '……&%*&U*……&%'] msg_send = ['呀,旅行者。你今天走起路来,怎么看着摇摇晃晃的?嘿嘿嘿~~~', '……&%*&U*……&%']
await fun_msg.finish(random.choice(msg_send)) await fun_msg.finish(random.choice(msg_send))
# 停止发癫 # 停止发癫
stop_fun_msg = on_message( stop_fun_msg = on_message(
rule=to_me() & keyword('恢复', '不准发癫', '停止', 'stop'), rule=to_me() & keyword('恢复', '不准发癫', '停止', 'stop'),
@ -296,6 +307,8 @@ stop_fun_msg.__paimon_help__ = {
"introduce": "让派蒙恢复正常", "introduce": "让派蒙恢复正常",
"priority": 97 "priority": 97
} }
@stop_fun_msg.handle() @stop_fun_msg.handle()
async def stopfunmsg(bot: Bot, event: GroupMessageEvent): async def stopfunmsg(bot: Bot, event: GroupMessageEvent):
logger.info(f'repeater派蒙停止发癫') logger.info(f'repeater派蒙停止发癫')
@ -308,6 +321,7 @@ async def stopfunmsg(bot: Bot, event: GroupMessageEvent):
msg_send = ['呃...头好疼...恢复了'] msg_send = ['呃...头好疼...恢复了']
await stop_fun_msg.finish(msg_send) await stop_fun_msg.finish(msg_send)
# 上调学习能力和主动发言 # 上调学习能力和主动发言
upLearning = on_message( upLearning = on_message(
rule=to_me() & keyword('加强学习能力', '派蒙快学', '再学快点', '多说点话') & Rule(checkGroup), rule=to_me() & keyword('加强学习能力', '派蒙快学', '再学快点', '多说点话') & Rule(checkGroup),
@ -320,6 +334,8 @@ upLearning.__paimon_help__ = {
"introduce": "增强派蒙的学习能力", "introduce": "增强派蒙的学习能力",
"priority": 98 "priority": 98
} }
@upLearning.handle() @upLearning.handle()
async def _(bot: Bot, event: GroupMessageEvent): async def _(bot: Bot, event: GroupMessageEvent):
if Chat.speak_threshold == 1: if Chat.speak_threshold == 1:
@ -330,6 +346,7 @@ async def _(bot: Bot, event: GroupMessageEvent):
Chat.answer_threshold = Chat.speak_threshold Chat.answer_threshold = Chat.speak_threshold
await upLearning.finish("派蒙会努力学习的") await upLearning.finish("派蒙会努力学习的")
# 降低学习能力和主动发言 # 降低学习能力和主动发言
downLearning = on_message( downLearning = on_message(
rule=to_me() & keyword('降低学习能力', '派蒙变笨', '笨比派蒙', '少说点话') & Rule(checkGroup), rule=to_me() & keyword('降低学习能力', '派蒙变笨', '笨比派蒙', '少说点话') & Rule(checkGroup),
@ -342,6 +359,8 @@ downLearning.__paimon_help__ = {
"introduce": "降低派蒙的学习能力", "introduce": "降低派蒙的学习能力",
"priority": 99 "priority": 99
} }
@downLearning.handle() @downLearning.handle()
async def _(bot: Bot, event: GroupMessageEvent): async def _(bot: Bot, event: GroupMessageEvent):
if Chat.speak_threshold == 6: if Chat.speak_threshold == 6:

View File

@ -1,10 +1,13 @@
import random import random
from pathlib import Path
from typing import Union
from nonebot import on_regex, on_command, logger from nonebot import on_regex, on_command, logger
from nonebot.matcher import matchers from nonebot.matcher import matchers
from nonebot.plugin import PluginMetadata
from nonebot.rule import Rule from nonebot.rule import Rule
from nonebot import get_driver from nonebot import get_driver
from nonebot.adapters.onebot.v11 import Bot, MessageEvent, GroupMessageEvent, MessageSegment from nonebot.adapters.onebot.v11 import Bot, MessageEvent, GroupMessageEvent, PrivateMessageEvent
from nonebot.exception import FinishedException from nonebot.exception import FinishedException
from utils.config import config from utils.config import config
@ -12,18 +15,28 @@ from utils.auth_util import FreqLimiter2
from utils.message_util import MessageBuild from utils.message_util import MessageBuild
from utils.file_handler import load_json_from_url from utils.file_handler import load_json_from_url
__paimon_help__ = {
'type': '派蒙机器学习', __plugin_meta__ = PluginMetadata(
'range': ['private', 'group', 'guild'] name="派蒙聊天",
} description="派蒙会发语音、会学群友们说骚话哦(",
usage=(
"被动技能"
),
extra={
'type': '派蒙聊天',
'range': ['group'],
"author": "惜月 SCUOP",
"version": "1.0.1",
},
)
if config.paimon_mongodb_url: if config.paimon_mongodb_url:
try: try:
from .Learning_repeate import main from .Learning_repeate import main
except ImportError: except ImportError:
logger.info('派蒙机器学习聊天启用失败可能是mongodb连接失败或缺少相关库') logger.warning('派蒙机器学习聊天启用失败可能是mongodb连接失败或缺少相关库jieba_fast、pymongo、pypinyin')
else: else:
logger.info('派蒙机器学习聊天启用失败mongodb尚未配置') logger.warning('派蒙机器学习聊天启用失败尚未配置mongodb连接url')
driver = get_driver() driver = get_driver()
@ -32,20 +45,17 @@ chat_lmt = FreqLimiter2(60)
update_voice = on_command('更新派蒙语音', priority=2) update_voice = on_command('更新派蒙语音', priority=2)
# TODO 被动效果
def check_group(event: Union[GroupMessageEvent, PrivateMessageEvent]) -> bool:
def check_group(event: GroupMessageEvent) -> bool: return True if isinstance(event, PrivateMessageEvent) else event.group_id in config.paimon_chat_group
if event.group_id in config.paimon_chat_group:
return True
return False
@update_voice.handle() @update_voice.handle()
async def update_paimon_voice(event: MessageEvent): async def update_paimon_voice(event: MessageEvent):
try: try:
old_len = len([m for m in matchers[10] if m.plugin_name == 'Paimon_Chat']) old_len = len([m for m in matchers[10] if m.plugin_name == 'Paimon_Chat'])
voice_list = await load_json_from_url('https://static.cherishmoon.fun/LittlePaimon/voice/voice_list.json') path = Path() / 'data' / 'LittlePaimon' / 'voice' / 'voice_list.json'
voice_list = await load_json_from_url('https://static.cherishmoon.fun/LittlePaimon/voice/voice_list.json', path, True)
matchers[10] = [m for m in matchers[10] if m.plugin_name != 'Paimon_Chat'] matchers[10] = [m for m in matchers[10] if m.plugin_name != 'Paimon_Chat']
for key, value in voice_list.items(): for key, value in voice_list.items():
create_matcher(key, value['pattern'], value['cooldown'], value['pro'], value['files']) create_matcher(key, value['pattern'], value['cooldown'], value['pro'], value['files'])
@ -62,21 +72,25 @@ def create_matcher(chat_word: str, pattern: str, cooldown: int, pro: float, resp
def check_pro() -> bool: def check_pro() -> bool:
return random.random() < pro return random.random() < pro
def check_cooldown(event: GroupMessageEvent) -> bool: def check_cooldown(event: Union[GroupMessageEvent, PrivateMessageEvent]) -> bool:
return chat_lmt.check(event.group_id, chat_word) return chat_lmt.check(event.group_id, chat_word)
hammer = on_regex(pattern, priority=10, rule=Rule(check_group, check_pro, check_cooldown)) hammer = on_regex(pattern, priority=10, rule=Rule(check_group, check_pro, check_cooldown))
hammer.plugin_name = 'Paimon_Chat' hammer.plugin_name = 'Paimon_Chat'
@hammer.handle() @hammer.handle()
async def handler(event: GroupMessageEvent): async def handler(event: Union[GroupMessageEvent, PrivateMessageEvent]):
try: try:
chat_lmt.start_cd(event.group_id, chat_word, cooldown) chat_lmt.start_cd(event.group_id, chat_word, cooldown)
response = random.choice(responses) response: str = random.choice(responses)
if '.mp3' not in response: if response.endswith('.mp3'):
await hammer.finish(response)
else:
await hammer.finish(await MessageBuild.StaticRecord(url=f'LittlePaimon/voice/{response}')) await hammer.finish(await MessageBuild.StaticRecord(url=f'LittlePaimon/voice/{response}'))
if response.endswith(('.png', '.jpg', '.jpeg', '.image', '.gif')):
await hammer.finish(await MessageBuild.StaticImage(url=f'LittlePaimon/voice/{response}'))
if response.endswith(('.mp4', '.avi')):
await hammer.finish(await MessageBuild.StaticVideo(url=f'LittlePaimon/voice/{response}'))
else:
await hammer.finish(MessageBuild.Text(response))
except FinishedException: except FinishedException:
raise raise
except Exception as e: except Exception as e:
@ -85,6 +99,7 @@ def create_matcher(chat_word: str, pattern: str, cooldown: int, pro: float, resp
@driver.on_startup @driver.on_startup
async def load_voice(): async def load_voice():
voice_list = await load_json_from_url('https://static.cherishmoon.fun/LittlePaimon/voice/voice_list.json') path = Path() / 'data' / 'LittlePaimon' / 'voice' / 'voice_list.json'
voice_list = await load_json_from_url('https://static.cherishmoon.fun/LittlePaimon/voice/voice_list.json', path)
for k, v in voice_list.items(): for k, v in voice_list.items():
create_matcher(k, v['pattern'], v['cooldown'], v['pro'], v['files']) create_matcher(k, v['pattern'], v['cooldown'], v['pro'], v['files'])

View File

@ -7,27 +7,39 @@ from nonebot.adapters.onebot.v11 import MessageEvent, Message, GroupMessageEvent
from nonebot.internal.matcher import Matcher from nonebot.internal.matcher import Matcher
from nonebot.internal.params import ArgPlainText from nonebot.internal.params import ArgPlainText
from nonebot.params import CommandArg from nonebot.params import CommandArg
from nonebot.plugin import PluginMetadata
from .data_source import get_Info, get_Notification, check_token from .data_source import get_Info, get_Notification, check_token
from utils.decorator import exception_handler from utils.decorator import exception_handler
from utils.file_handler import load_json, save_json from utils.file_handler import load_json, save_json
HELP_STR = '''
云原神相关功能 __plugin_meta__ = PluginMetadata(
云原神 绑定/bind : 绑定云原神的token name="云原神",
云原神 信息/info: 查询云原神账户信息 description="云原神相关功能模块",
'''.strip() usage=(
"云原神 绑定/bind : 绑定云原神的token\n"
"云原神 信息/info: 查询云原神账户信息\n"
),
extra={
'type': '工具',
'range': ['private', 'group'],
"author": "nicklly <1134741727@qq.com>",
"version": "1.0.0",
},
)
cloud_ys = on_command('云原神', aliases={'云原神', 'yys'}, priority=16, block=True) cloud_ys = on_command('云原神', aliases={'云原神', 'yys'}, priority=16, block=True)
rm_cloud_ys = on_command('云原神解绑', aliases={'yys解绑', 'yys解除绑定', 'yysdel'}, priority=16, block=True) rm_cloud_ys = on_command('云原神解绑', aliases={'yys解绑', 'yys解除绑定', 'yysdel'}, priority=16, block=True)
cloud_ys.__paimon_help__ = { cloud_ys.__paimon_help__ = {
"usage": "云原神", "usage": "云原神",
"introduce": "查询云原神账户信息, 绑定token进行签到", "introduce": "查询云原神账户信息, 绑定token进行签到",
"priority": 99 "priority": 95
} }
rm_cloud_ys.__paimon_help__ = { rm_cloud_ys.__paimon_help__ = {
"usage": "云原神解绑", "usage": "云原神解绑",
"introduce": "解绑cookie并取消自动签到", "introduce": "解绑cookie并取消自动签到",
"priority": 99 "priority": 96
} }
scheduler = require('nonebot_plugin_apscheduler').scheduler scheduler = require('nonebot_plugin_apscheduler').scheduler
uuid = str(uuid.uuid4()) uuid = str(uuid.uuid4())

View File

@ -2,12 +2,26 @@ import re
from nonebot import on_command from nonebot import on_command
from nonebot.params import CommandArg, T_State, Arg from nonebot.params import CommandArg, T_State, Arg
from nonebot.adapters.onebot.v11 import PrivateMessageEvent, Message from nonebot.adapters.onebot.v11 import PrivateMessageEvent, Message
from nonebot.plugin import PluginMetadata
from .data_source import get_address, get_goods, save_exchange_info, get_exchange_info, delete_exchange_info from .data_source import get_address, get_goods, save_exchange_info, get_exchange_info, delete_exchange_info
__paimon_help__ = {
__plugin_meta__ = PluginMetadata(
name="米游币商品抢兑",
description="小派蒙的米游币商品抢兑模块",
usage=(
"myb 跟随派蒙的指引录入兑换计划\n"
"myb_info 查看当前的兑换计划\n"
"myb_delete 删除你的所有兑换计划\n"
),
extra={
'type': '工具', 'type': '工具',
'range': ['private'] 'range': ['private'],
} "author": "惜月 <277073121@qq.com>",
"version": "1.0.0",
},
)
myb_exchange = on_command('myb', aliases={'米游币兑换', '米游币商品兑换', '米游社商品兑换'}, priority=4, block=True) myb_exchange = on_command('myb', aliases={'米游币兑换', '米游币商品兑换', '米游社商品兑换'}, priority=4, block=True)
myb_exchange.__paimon_help__ = { myb_exchange.__paimon_help__ = {

View File

@ -4,6 +4,7 @@ from typing import Dict
from nonebot import on_command, on_regex from nonebot import on_command, on_regex
from nonebot.adapters.onebot.v11 import MessageEvent, GroupMessageEvent, Message from nonebot.adapters.onebot.v11 import MessageEvent, GroupMessageEvent, Message
from nonebot.params import RegexDict, CommandArg from nonebot.params import RegexDict, CommandArg
from nonebot.plugin import PluginMetadata
from utils.config import config from utils.config import config
from utils import aiorequests from utils import aiorequests
@ -11,22 +12,27 @@ from utils.auth_util import FreqLimiter
from .gacha_info import * from .gacha_info import *
from .gacha_res import more_ten from .gacha_res import more_ten
__usage__ = '''
1.[抽n十连xx池]抽n次xx池的十连最多同时5次
*池子和官方同步有角色1|角色2|武器|常驻默认为角色1
2.[模拟抽卡记录]查看模拟抽卡记录总结
3.[模拟抽卡记录 角色/武器]查看模拟抽卡抽到的五星角色/武器
4.[删除模拟抽卡记录]顾名思义
5.[选择定轨 武器全名]选择武器定轨
6.[查看定轨]查看当前定轨的武器
7.[删除定轨]删除当前定轨的武器
'''
__help_version__ = '1.0.1'
__paimon_help__ = { __plugin_meta__ = PluginMetadata(
name="原神模拟抽卡",
description="小派蒙的原神模拟抽卡模块",
usage=(
"1.[抽n十连xx池]抽n次xx池的十连最多同时5次"
"*池子和官方同步有角色1|角色2|武器|常驻默认为角色1"
"2.[模拟抽卡记录]查看模拟抽卡记录总结"
"3.[模拟抽卡记录 角色/武器]查看模拟抽卡抽到的五星角色/武器"
"4.[删除模拟抽卡记录]顾名思义"
"5.[选择定轨 武器全名]选择武器定轨"
"6.[查看定轨]查看当前定轨的武器"
"7.[删除定轨]删除当前定轨的武器"
),
extra={
'type': '原神模拟抽卡', 'type': '原神模拟抽卡',
'range': ['private', 'group', 'guild'] 'range': ['private', 'group', 'guild'],
} "author": "惜月 <277073121@qq.com>",
"version": "1.0.3",
},
)
sim_gacha = on_regex(r'^抽((?P<num>\d+)|(?:.*))十连(?P<pool>.*?)$', priority=5, block=True) sim_gacha = on_regex(r'^抽((?P<num>\d+)|(?:.*))十连(?P<pool>.*?)$', priority=5, block=True)
sim_gacha.__paimon_help__ = { sim_gacha.__paimon_help__ = {

View File

@ -6,25 +6,28 @@ from typing import Union
from nonebot import on_command from nonebot import on_command
from nonebot.adapters.onebot.v11 import Bot, Message, MessageEvent, GroupMessageEvent from nonebot.adapters.onebot.v11 import Bot, Message, MessageEvent, GroupMessageEvent
from nonebot.params import CommandArg from nonebot.params import CommandArg
from nonebot.plugin import PluginMetadata
from utils.message_util import get_uid_in_msg from utils.message_util import get_uid_in_msg
from .api import toApi, checkApi from .api import toApi, checkApi
from .gacha_logs import get_data from .gacha_logs import get_data
from .get_img import get_gacha_log_img from .get_img import get_gacha_log_img
from pathlib import Path
__usage__ = ''' __plugin_meta__ = PluginMetadata(
1.[获取抽卡记录 (uid) (url)]提供url获取原神抽卡记录需要一定时间 name="Paimon_Gacha_Log",
2.[查看抽卡记录 (uid)]查看抽卡记录分析 description="小派蒙的原神抽卡记录模块",
3.[导出抽卡记录 (uid) (xlsx/json)]导出抽卡记录文件上传到群文件中 usage=(
''' "1.[获取抽卡记录 (uid) (url)]提供url获取原神抽卡记录需要一定时间"
__help_version__ = '0.9.0' "2.[查看抽卡记录 (uid)]查看抽卡记录分析"
"3.[导出抽卡记录 (uid) (xlsx/json)]导出抽卡记录文件,上传到群文件中"
__paimon_help__ = { ),
extra={
'type': '原神抽卡记录', 'type': '原神抽卡记录',
'range': ['private', 'group', 'guild'] 'range': ['private', 'group', 'guild'],
} "author": "惜月 <277073121@qq.com>",
"version": "0.1.3",
},
)
gacha_log_export = on_command('ckjldc', aliases={'抽卡记录导出', '导出抽卡记录'}, priority=5, block=True) gacha_log_export = on_command('ckjldc', aliases={'抽卡记录导出', '导出抽卡记录'}, priority=5, block=True)
gacha_log_export.__paimon_help__ = { gacha_log_export.__paimon_help__ = {

View File

@ -6,7 +6,8 @@ from collections import defaultdict
from nonebot import on_command, require, logger, get_bot from nonebot import on_command, require, logger, get_bot
from nonebot.adapters.onebot.v11 import MessageEvent, Message, Bot, MessageSegment from nonebot.adapters.onebot.v11 import MessageEvent, Message, Bot, MessageSegment
from nonebot.params import CommandArg from nonebot.params import CommandArg, Arg
from nonebot.plugin import PluginMetadata
from nonebot.typing import T_State from nonebot.typing import T_State
from nonebot.permission import SUPERUSER from nonebot.permission import SUPERUSER
from nonebot.rule import to_me from nonebot.rule import to_me
@ -34,36 +35,44 @@ from .draw_role_card import draw_role_card
require('nonebot_plugin_apscheduler') require('nonebot_plugin_apscheduler')
from nonebot_plugin_apscheduler import scheduler from nonebot_plugin_apscheduler import scheduler
__usage__ = '''
[ys (uid)]查看原神个人卡片(包含宝箱探索度等数据)
[ysa (uid)]查看所有公开的8角色的简略信息
[ysc (uid) 角色名]查看公开的8角色的详细信息
*绑定私人cookie之后就可以查看所有角色啦
--------
[ssbq/实时便签 (uid)]查询当前树脂洞天宝钱派遣状况等
[ssbq (uid) 开启提醒(树脂数)/关闭提醒]开启/关闭树脂提醒达到树脂数时会在群里艾特你
*绑定私人cookie之后才能使用
--------
[sy/深渊查询/深境螺旋查询 (uid) (层数)]查询深渊战绩信息
*绑定私人cookie之后才能查看层数具体阵容哦
--------
[mys签到]手动进行一次米游社原神签到
[mys自动签到开启uid/关闭]开启米游社原神自动签到
--------
[myzj/每月札记/zj (uid) (月份)]查看该月份获得的原石摩拉数
*绑定私人cookie之后才能使用,只能查看最近3个月的记录,默认为本月
--------
[ysb cookie]绑定你的私人cookie以开启高级功能
[删除ck]删除你的私人cookie
[添加公共ck cookie]添加公共cookie以供大众查询*仅管理员
'''
__paimon_help__ = { __plugin_meta__ = PluginMetadata(
name="Paimon_Info",
description="小派蒙的原神信息查询模块",
usage=(
"[ys (uid)]查看原神个人卡片(包含宝箱、探索度等数据)\n"
"[ysa (uid)]查看所有公开的8角色的简略信息\n"
"[ysc (uid) 角色名]查看公开的8角色的详细信息\n"
"*绑定私人cookie之后就可以查看所有角色啦\n"
"--------\n"
"[ssbq/实时便签 (uid)]查询当前树脂、洞天宝钱、派遣状况等\n"
"[ssbq (uid) 开启提醒(树脂数)/关闭提醒]开启/关闭树脂提醒,达到树脂数时会在群里艾特你\n"
"*绑定私人cookie之后才能使用\n"
"--------\n"
"[sy/深渊查询/深境螺旋查询 (uid) (层数)]查询深渊战绩信息\n"
"*绑定私人cookie之后才能查看层数具体阵容哦\n"
"--------\n"
"[mys签到]手动进行一次米游社原神签到\n"
"[mys自动签到开启uid/关闭]开启米游社原神自动签到\n"
"--------\n"
"[myzj/每月札记/zj (uid) (月份)]查看该月份获得的原石、摩拉数\n"
"*绑定私人cookie之后才能使用,只能查看最近3个月的记录,默认为本月\n"
"--------\n"
"[ysb cookie]绑定你的私人cookie以开启高级功能\n"
"[删除ck]删除你的私人cookie\n"
"[添加公共ck cookie]添加公共cookie以供大众查询*仅管理员\n"
"--------\n"
"[更新角色信息 uid]更新游戏内展柜8个角色的面板信息\n"
"[ysd 角色名 uid]查看指定角色的详细面板信息\n"
),
extra={
'type': '原神信息查询', 'type': '原神信息查询',
'range': ['private', 'group', 'guild'] 'range': ['private', 'group', 'guild'],
} "author": "惜月 <277073121@qq.com>",
"version": "0.1.3",
},
)
__help_version__ = '1.1.0'
sy = on_command('sy', aliases={'深渊信息', '深境螺旋信息'}, priority=7, block=True) sy = on_command('sy', aliases={'深渊信息', '深境螺旋信息'}, priority=7, block=True)
sy.__paimon_help__ = { sy.__paimon_help__ = {
@ -483,7 +492,7 @@ async def mys_sign_auto_handler(event: MessageEvent, msg: Message = CommandArg()
ud_lmt = FreqLimiter(300) ud_lmt = FreqLimiter(300)
ud_p_lmt = FreqLimiter(12) ud_p_lmt = FreqLimiter(15)
@update_info.handle() @update_info.handle()
@ -496,33 +505,38 @@ async def _(event: MessageEvent, state: T_State, msg: Message = CommandArg()):
for msg_seg in msg: for msg_seg in msg:
if msg_seg.type == "at": if msg_seg.type == "at":
user = msg_seg.data['qq'] user = msg_seg.data['qq']
break
if user: if user:
state['uid'] = await get_last_query(str(user)) uid = await get_last_query(str(user))
if uid:
state['uid'] = uid
else: else:
state['uid'] = await get_last_query(str(event.user_id)) uid = await get_last_query(str(event.user_id))
if not ud_lmt.check(state['uid']): if uid:
state['uid'] = uid
if 'uid' in state and not ud_lmt.check(state['uid']):
await update_info.finish(f'每个uid每5分钟才能更新一次信息请稍等一下吧~(剩余{ud_lmt.left_time(state["uid"])}秒)') await update_info.finish(f'每个uid每5分钟才能更新一次信息请稍等一下吧~(剩余{ud_lmt.left_time(state["uid"])}秒)')
if not ud_p_lmt.check(get_message_id(event)): if not ud_p_lmt.check(get_message_id(event)):
await update_info.finish(f'每个会话每12秒才能更新一次信息,请稍等一下吧~(剩余{ud_lmt.left_time(get_message_id(event))}秒)') await update_info.finish(f'每个会话每15秒才能更新一次信息,请稍等一下吧~(剩余{ud_lmt.left_time(get_message_id(event))}秒)')
@update_info.got('uid', prompt='请把要更新的uid给派蒙哦~') @update_info.got('uid', prompt='请把要更新的uid给派蒙哦~')
@exception_handler() @exception_handler()
async def _(event: MessageEvent, state: T_State): async def _(event: MessageEvent, uid: Message = Arg('uid')):
uid = transform_uid(state['uid']) uid = transform_uid(uid)
if not uid: if not uid:
await update_info.finish('个uid不正确哦~,请检查一下', at_sender=True) await update_info.finish('好像不是一正确的uid哦~,请检查一下', at_sender=True)
await update_last_query(str(event.user_id), uid) await update_last_query(str(event.user_id), uid)
await update_info.send('派蒙开始更新信息~请稍等哦~') await update_info.send('派蒙开始更新信息~请稍等哦~')
enka_data = await get_enka_data(uid) enka_data = await get_enka_data(uid)
if not enka_data: if not enka_data:
if uid[0] == '5' or uid[0] == '2': if uid[0] == '5' or uid[0] == '2':
await update_info.finish('暂不支持B服和2开头的账号哦~请等待开发者更新吧~') await update_info.finish('暂不支持B服账号哦~请等待开发者更新吧~')
else: else:
await update_info.finish('派蒙没有查到该uid的信息哦~') await update_info.finish('派蒙没有查到该uid的信息哦~')
ud_lmt.start_cd(uid, 300) ud_lmt.start_cd(uid, 300)
ud_lmt.start_cd(get_message_id(event), 12) ud_lmt.start_cd(get_message_id(event), 15)
player_info = PlayerInfo(uid) player_info = PlayerInfo(uid)
player_info.set_player(enka_data['playerInfo']) player_info.set_player(enka_data['playerInfo'])
if 'avatarInfoList' not in enka_data: if 'avatarInfoList' not in enka_data:

View File

@ -1,25 +1,7 @@
# # 点餐功能
# from .order import *
#
# # 新闻功能
# from .news import *
#
# # 随机图片功能
# from .random_img import *
#
# # 处理好友和群请求功能
# from .auto_handle import *
#
# # 对联功能
# from .couplets import *
#
# from .help import help_
# 如果不需要某项功能将其from xx import * 注释掉即可
from nonebot import load_plugins from nonebot import load_plugins
import os import os
load_plugins(os.path.dirname(__file__)) load_plugins(os.path.dirname(__file__))

View File

@ -2,15 +2,27 @@ from urllib.parse import quote
from nonebot import on_command from nonebot import on_command
from nonebot.params import CommandArg from nonebot.params import CommandArg
from nonebot.adapters.onebot.v11 import MessageEvent from nonebot.adapters.onebot.v11 import MessageEvent
from nonebot.plugin import PluginMetadata
from utils.auth_util import FreqLimiter from utils.auth_util import FreqLimiter
from utils.message_util import get_message_id from utils.message_util import get_message_id
from utils.config import config from utils.config import config
from utils import aiorequests from utils import aiorequests
__paimon_help__ = {
__plugin_meta__ = PluginMetadata(
name="对对联",
description="人工智能和你对对联",
usage=(
"对对联 <对联内容>"
),
extra={
'type': '娱乐', 'type': '娱乐',
'range': ['private', 'group', 'guild'] 'range': ['private', 'group', 'guild'],
} "author": "惜月 <277073121@qq.com>",
"version": "1.0.0",
},
)
couplets = on_command('对联', aliases={'对对联'}, priority=13, block=True) couplets = on_command('对联', aliases={'对对联'}, priority=13, block=True)
couplets.__paimon_help__ = { couplets.__paimon_help__ = {
@ -38,7 +50,7 @@ async def couplets_handler(event: MessageEvent, msg=CommandArg()):
num = num if num < 10 else 10 num = num if num < 10 else 10
couplets_limit.start_cd(get_message_id(event), config.paimon_couplets_cd) couplets_limit.start_cd(get_message_id(event), config.paimon_couplets_cd)
text = quote(str(word)) text = quote(str(word))
url = f'https://ai-backend.binwang.me/v0.2/couplet/{text}' url = f'https://seq2seq-couplet-model.rssbrain.com/v0.2/couplet/{text}'
res = await aiorequests.get(url=url) res = await aiorequests.get(url=url)
res = res.json() res = res.json()
result = '' result = ''

View File

@ -2,14 +2,26 @@ import re
from nonebot import on_command, require, get_bot, logger from nonebot import on_command, require, get_bot, logger
from nonebot.params import CommandArg from nonebot.params import CommandArg
from nonebot.adapters.onebot.v11 import MessageEvent, MessageSegment, Message from nonebot.adapters.onebot.v11 import MessageEvent, MessageSegment, Message
from nonebot.plugin import PluginMetadata
from utils import aiorequests from utils import aiorequests
from utils.file_handler import load_json, save_json from utils.file_handler import load_json, save_json
from utils.message_util import get_message_id from utils.message_util import get_message_id
__paimon_help__ = {
__plugin_meta__ = PluginMetadata(
name="今日早报",
description="60秒读世界早报",
usage=(
"今日早报 后加on时间/off可以开启/关闭推送"
),
extra={
'type': '娱乐', 'type': '娱乐',
'range': ['private', 'group', 'guild'] 'range': ['private', 'group', 'guild'],
} "author": "惜月 <277073121@qq.com>",
"version": "1.0.0",
},
)
news60s_pic = on_command('早报', aliases={'今日早报', '今日新闻', '60s读世界'}, priority=13, block=True) news60s_pic = on_command('早报', aliases={'今日早报', '今日新闻', '60s读世界'}, priority=13, block=True)
news60s_pic.__paimon_help__ = { news60s_pic.__paimon_help__ = {

View File

@ -2,13 +2,25 @@ import random
from nonebot import on_command from nonebot import on_command
from nonebot.params import CommandArg from nonebot.params import CommandArg
from nonebot.adapters.onebot.v11 import Message, MessageEvent, MessageSegment from nonebot.adapters.onebot.v11 import Message, MessageEvent, MessageSegment
from nonebot.plugin import PluginMetadata
from utils.auth_util import FreqLimiter from utils.auth_util import FreqLimiter
from utils import aiorequests from utils import aiorequests
__paimon_help__ = {
__plugin_meta__ = PluginMetadata(
name="点餐",
description="点餐查看食物图片",
usage=(
"点餐 食物名"
),
extra={
'type': '娱乐', 'type': '娱乐',
'range': ['private', 'group', 'guild'] 'range': ['private', 'group', 'guild'],
} "author": "惜月 <277073121@qq.com>",
"version": "1.0.0",
},
)
order_pic = on_command('点菜', aliases={'点餐', '食谱', '我想吃'}, priority=13, block=True) order_pic = on_command('点菜', aliases={'点餐', '食谱', '我想吃'}, priority=13, block=True)
order_pic.__paimon_help__ = { order_pic.__paimon_help__ = {

View File

@ -5,17 +5,26 @@ from nonebot import on_command
from nonebot import plugin as nb_plugin from nonebot import plugin as nb_plugin
from nonebot.params import Depends from nonebot.params import Depends
from nonebot.adapters.onebot.v11 import MessageEvent from nonebot.adapters.onebot.v11 import MessageEvent
from nonebot.plugin import PluginMetadata
from utils.message_util import MessageBuild from utils.message_util import MessageBuild
__version__ = 'v1.0.0'
__paimon_help__ = { __plugin_meta__ = PluginMetadata(
name="帮助菜单",
description="自动读取插件的信息,生成帮助菜单图片",
usage=(
"help"
),
extra={
'type': '工具', 'type': '工具',
'range': ['private', 'group', 'guild'] 'range': ['private', 'group', 'guild'],
} "author": "惜月 <277073121@qq.com>",
"version": "v1.0.0",
},
)
help_ = on_command('help', aliases={'帮助菜单'}, priority=1, block=True) help_ = on_command('help', aliases={'帮助菜单', '派蒙帮助'}, priority=1, block=True)
help_.__paimon_help__ = { help_.__paimon_help__ = {
"usage": "帮助菜单|help", "usage": "帮助菜单|help",
"introduce": "查看派蒙的帮助信息", "introduce": "查看派蒙的帮助信息",
@ -84,7 +93,7 @@ def draw_help_info(help_info: dict):
img.paste(bg_img, (0, 0), bg_img) img.paste(bg_img, (0, 0), bg_img)
draw = ImageDraw.Draw(img) draw = ImageDraw.Draw(img)
draw_shadow_text(draw, (50, 50), '派蒙帮助', get_font(140), (255, 255, 255), (0, 0, 0, 255), (3, 3)) draw_shadow_text(draw, (50, 50), '派蒙帮助', get_font(140), (255, 255, 255), (0, 0, 0, 255), (3, 3))
draw_shadow_text(draw, (610, 140), __version__, get_font(50), (255, 255, 255), (0, 0, 0, 255), (3, 3)) draw_shadow_text(draw, (610, 140), __plugin_meta__.extra.get('version', '1.0.0'), get_font(50), (255, 255, 255), (0, 0, 0, 255), (3, 3))
draw_shadow_text(draw, (520, 250), '<>内为必须,[]内为可选,()内只需要第一次', get_font(50), (255, 255, 255), (0, 0, 0, 255), (2, 2)) draw_shadow_text(draw, (520, 250), '<>内为必须,[]内为可选,()内只需要第一次', get_font(50), (255, 255, 255), (0, 0, 0, 255), (2, 2))
draw_shadow_text(draw, (620, 300), '描述前带*号说明需要绑定私人cookie', get_font(50), (255, 255, 255), (0, 0, 0, 255), (2, 2)) draw_shadow_text(draw, (620, 300), '描述前带*号说明需要绑定私人cookie', get_font(50), (255, 255, 255), (0, 0, 0, 255), (2, 2))
n = 400 n = 400
@ -101,20 +110,22 @@ async def get_all_plugin(event: MessageEvent) -> dict:
help_info: Dict[str, List[dict]] = {} help_info: Dict[str, List[dict]] = {}
for plugin in plugin_list: for plugin in plugin_list:
try: try:
plugin_info = plugin.module.__getattribute__('__paimon_help__') plugin_type = plugin.metadata.extra.get('type', '其他')
plugin_range = plugin.metadata.extra.get('range', ['private', 'group', 'guild'])
except AttributeError: except AttributeError:
plugin_info = {'type': '其他', 'range': ['private', 'group', 'guild']} plugin_type = '其他'
if event.message_type not in plugin_info['range']: plugin_range = ['private', 'group', 'guild']
if event.message_type not in plugin_range:
continue continue
if plugin_info['type'] not in help_info: if plugin_type not in help_info:
help_info[plugin_info['type']] = [] help_info[plugin_type] = []
matchers = plugin.matcher matchers = plugin.matcher
for matcher in matchers: for matcher in matchers:
try: try:
matchers_info = matcher.__paimon_help__ matchers_info = matcher.__paimon_help__
if 'priority' not in matchers_info: if 'priority' not in matchers_info:
matchers_info['priority'] = 99 matchers_info['priority'] = 99
help_info[plugin_info['type']].append(matchers_info) help_info[plugin_type].append(matchers_info)
except AttributeError: except AttributeError:
pass pass
help_info = {k: v for k, v in help_info.items() if v} help_info = {k: v for k, v in help_info.items() if v}

View File

@ -2,15 +2,28 @@ import random
from nonebot import on_command, on_regex from nonebot import on_command, on_regex
from nonebot.params import RegexGroup from nonebot.params import RegexGroup
from nonebot.adapters.onebot.v11 import Bot, MessageEvent, MessageSegment from nonebot.adapters.onebot.v11 import Bot, MessageEvent, MessageSegment
from nonebot.plugin import PluginMetadata
from utils.config import config from utils.config import config
from utils.auth_util import FreqLimiter from utils.auth_util import FreqLimiter
from utils.message_util import get_message_id from utils.message_util import get_message_id
from utils.decorator import auto_withdraw from utils.decorator import auto_withdraw
__paimon_help__ = {
__plugin_meta__ = PluginMetadata(
name="随机图片",
description="从各随机图片接口获取一张图片",
usage=(
"来点猫片\n"
"来点二次元图\n"
),
extra={
'type': '娱乐', 'type': '娱乐',
'range': ['private', 'group', 'guild'] 'range': ['private', 'group', 'guild'],
} "author": "惜月 <277073121@qq.com>",
"version": "1.0.0",
},
)
cat_lmt = FreqLimiter(config.paimon_cat_cd) cat_lmt = FreqLimiter(config.paimon_cat_cd)
ecy_lmt = FreqLimiter(config.paimon_ecy_cd) ecy_lmt = FreqLimiter(config.paimon_ecy_cd)

View File

@ -6,28 +6,42 @@ from nonebot import on_endswith, on_command, on_regex
from nonebot.adapters.onebot.v11 import MessageEvent, Message, MessageSegment from nonebot.adapters.onebot.v11 import MessageEvent, Message, MessageSegment
from nonebot.params import RegexDict from nonebot.params import RegexDict
from nonebot.typing import T_State from nonebot.typing import T_State
from nonebot.plugin import PluginMetadata
from utils.alias_handler import get_match_alias from utils.alias_handler import get_match_alias
from utils.file_handler import load_json_from_url from utils.file_handler import load_json_from_url
from utils.message_util import MessageBuild from utils.message_util import MessageBuild
from .abyss_rate_draw import draw_rate_rank, draw_teams_rate from .abyss_rate_draw import draw_rate_rank, draw_teams_rate
__usage__ = '''
1.[xx角色攻略]查看西风驿站出品的角色一图流攻略
2.[xx角色材料]查看惜月出品的角色材料统计
3.[xx参考面板]查看blue菌hehe出品的参考面板攻略
4.[xx收益曲线]查看blue菌hehe出品的收益曲线攻略
*感谢来自大佬们的授权角色支持别名查询
5.[今日/明日/周x材料]查看每日角色天赋材料和武器突破材料表
6.[深渊登场率]查看2.6深渊角色登场率
7.[深渊上半/下半阵容出场率]查看2.6深渊阵容出场率
'''
__help_version__ = '1.0.4'
__paimon_help__ = { __paimon_help__ = {
'type': '原神Wiki', 'type': '原神Wiki',
'range': ['private', 'group', 'guild'] 'range': ['private', 'group', 'guild']
} }
__plugin_meta__ = PluginMetadata(
name="Paimon_Wiki",
description="小派蒙的wiki查询模块",
usage=(
"1.[xx角色攻略]查看西风驿站出品的角色一图流攻略\n"
"2.[xx角色材料]查看惜月出品的角色材料统计\n"
"3.[xx参考面板]查看blue菌hehe出品的参考面板攻略\n"
"4.[xx收益曲线]查看blue菌hehe出品的收益曲线攻略\n"
"5.[今日/明日/周x材料]查看每日角色天赋材料和武器突破材料表\n"
"6.[深渊登场率]查看2.6深渊角色登场率\n"
"7.[深渊上半/下半阵容出场率]查看2.6深渊阵容出场率\n"
"8.[xx武器攻略]查看武器攻略\n"
"9.[xx原魔图鉴]查看原魔图鉴\n"
),
extra={
'type': '原神Wiki',
'range': ['private', 'group', 'guild'],
"author": "惜月 <277073121@qq.com>",
"version": "0.1.3",
},
)
res_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'res') res_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'res')
guide = on_endswith('角色攻略', priority=8) guide = on_endswith('角色攻略', priority=8)

View File

@ -64,45 +64,21 @@
</details> </details>
## 丨更新日志 ## 丨更新日志
+ 5.19 > README只展示最近2条更新全部更新日志详见[这里](https://github.com/CMHopeSunshine/LittlePaimon/blob/nonebot2/UPDATE_LOG.md)
- 米游社签到新增`全部重签`,仅限超级管理员使用,需@机器人
- `原神猜语音`不再需要`我猜`,直接回答角色别名即可参与猜猜看
- 异步请求库从`aiohttp`改用`httpx`,需安装依赖库`pip install httpx`
- 修复`60秒读世界`在频道无法关闭推送的BUG
+ 5.20
- 修复`ysc`缺少资源问题
- 封装部分常用方法,优化导包
- `Paimon_Chat`新增`更新派蒙语音`,实时更新语音
+ 5.21
- 修复可能因ssl证书导致的静态资源下载问题
+ 5.23
- 新增`xx原魔图鉴`
+ 5.25
- `ys、ysc、ysa、sy`等和`wiki`模块指令可以对话式查询
+ 5.27
- 新增`原神日历`[@nicklly](https://github.com/nicklly)
+ 5.28
- `Paimon_Chat`聊天新增`学习群友发言`(魔改自[Pallas-Bot](https://github.com/InvoluteHell/Pallas-Bot/tree/master/src/plugins/repeater)),需安装`jieba_fast、pymongo、pypinyin依赖库``mongodb数据库`且在`.env.*`配置文件中添加mongodb连接参数`paimon_mongodb_url`,例如`paimon_mongodb_url=mongodb://localhost:27017/`
+ 6.3
- 新增游戏内展柜角色面板卡片,使用`更新角色面板`来获取角色,`ysd角色名`来查看角色卡片
- 修复部分不记录上次查询的uid的bug
- 大幅缩短深渊指令`sy`的缓存时间
+ 6.6
- 修复`模拟抽卡定轨``抽卡记录导出`bug
+ 6.7
- 修复`原神猜语音``模拟抽卡``nonebot2.0.0b3`版本Union校验产生的bug`原神猜语音`将暂时无法私聊使用
+ 6.9
- 新增`帮助菜单`指令~~(不太好看,继续美化)~~
+ 6.12
- 新增`云原神签到`等功能[@nicklly](https://github.com/nicklly)
- 修复部分bug新增`好友、群新成员和龙王提醒`[#45](https://github.com/CMHopeSunshine/LittlePaimon/issues/45)
+ 6.19 + 6.19
- 新增`米游币商品兑换`功能,私聊机器人发送`myb`跟着一步步指引来做目前该功能还没有机会做测试出现问题请提issue - 新增`米游币商品兑换`功能,私聊机器人发送`myb`跟着一步步指引来做目前该功能还没有机会做测试出现问题请提issue
- `ysb`绑定cookie的方法增加腾讯文档 - `ysb`绑定cookie的方法增加腾讯文档
+ 6.21
- 适配`nonebot2 beta4`插件元数据请更新nb版本`pip install nonebot2 --upgrade`
- `Paimon_Chat`现在可以发图片、视频等,可自行添加
- 修复`Paimon_Wiki`搜索对象名结果只有一个时仍需要选择的bug
- 对对联功能api更换
- 增加部分注释文档
## 丨功能列表 ## 丨功能列表
详见[功能列表](https://blog.cherishmoon.fun/posts/nonebot2funclist.html) 详见我的博客[功能列表](https://blog.cherishmoon.fun/posts/nonebot2funclist.html) <br>
博客内容可能滞后于实际版本 ~~太懒了~~
## 丨部署方法 ## 丨部署方法
### 我很熟悉NoneBot2 ### 我很熟悉NoneBot2

43
UPDATE_LOG.md Normal file
View File

@ -0,0 +1,43 @@
# LittlePaimon更新日志
+ 5.19
- 米游社签到新增`全部重签`,仅限超级管理员使用,需@机器人
- `原神猜语音`不再需要`我猜`,直接回答角色别名即可参与猜猜看
- 异步请求库从`aiohttp`改用`httpx`,需安装依赖库`pip install httpx`
- 修复`60秒读世界`在频道无法关闭推送的BUG
+ 5.20
- 修复`ysc`缺少资源问题
- 封装部分常用方法,优化导包
- `Paimon_Chat`新增`更新派蒙语音`,实时更新语音
+ 5.21
- 修复可能因ssl证书导致的静态资源下载问题
+ 5.23
- 新增`xx原魔图鉴`
+ 5.25
- `ys、ysc、ysa、sy`等和`wiki`模块指令可以对话式查询
+ 5.27
- 新增`原神日历`[@nicklly](https://github.com/nicklly)
+ 5.28
- `Paimon_Chat`聊天新增`学习群友发言`(魔改自[Pallas-Bot](https://github.com/InvoluteHell/Pallas-Bot/tree/master/src/plugins/repeater)),需安装`jieba_fast、pymongo、pypinyin依赖库``mongodb数据库`且在`.env.*`配置文件中添加mongodb连接参数`paimon_mongodb_url`,例如`paimon_mongodb_url=mongodb://localhost:27017/`
+ 6.3
- 新增游戏内展柜角色面板卡片,使用`更新角色面板`来获取角色,`ysd角色名`来查看角色卡片
- 修复部分不记录上次查询的uid的bug
- 大幅缩短深渊指令`sy`的缓存时间
+ 6.6
- 修复`模拟抽卡定轨``抽卡记录导出`bug
+ 6.7
- 修复`原神猜语音``模拟抽卡``nonebot2.0.0b3`版本Union校验产生的bug`原神猜语音`将暂时无法私聊使用
+ 6.9
- 新增`帮助菜单`指令 ~~(不太好看,继续美化)~~
+ 6.12
- 新增`云原神签到`等功能[@nicklly](https://github.com/nicklly)
- 修复部分bug新增`好友、群新成员和龙王提醒`[#45](https://github.com/CMHopeSunshine/LittlePaimon/issues/45)
+ 6.19
- 新增`米游币商品兑换`功能,私聊机器人发送`myb`跟着一步步指引来做目前该功能还没有机会做测试出现问题请提issue
- `ysb`绑定cookie的方法增加腾讯文档
+ 6.21
- 适配`nonebot2 beta4`插件元数据请更新nb版本`pip install nonebot2 --upgrade`
- `Paimon_Chat`现在可以发图片、视频等,可自行添加
- 修复`Paimon_Wiki`搜索对象名结果只有一个时仍需要选择的bug
- 对对联功能api更换
- 增加部分注释文档

View File

@ -94,7 +94,7 @@ async def get_img(url: str,
timeout=timeout, timeout=timeout,
**kwargs) **kwargs)
resp = resp.read() resp = resp.read()
if b'error' in resp: if 'NoSuchKey' in resp:
return 'No Such File' return 'No Such File'
img = Image.open(BytesIO(resp)) img = Image.open(BytesIO(resp))
except SSLCertVerificationError: except SSLCertVerificationError:

View File

@ -26,7 +26,6 @@ def get_name_by_id(role_id: str):
return None return None
def get_match_alias(msg: str, type: str = 'roles', single_to_dict: bool = False) -> Union[str, list, dict]: def get_match_alias(msg: str, type: str = 'roles', single_to_dict: bool = False) -> Union[str, list, dict]:
alias_file = load_json(path=os.path.join(os.path.dirname(__file__), 'alias.json')) alias_file = load_json(path=os.path.join(os.path.dirname(__file__), 'alias.json'))
alias_list = alias_file[type] alias_list = alias_file[type]
@ -42,6 +41,8 @@ def get_match_alias(msg: str, type: str = 'roles', single_to_dict: bool = False)
else: else:
return alias[0] return alias[0]
elif match_list: elif match_list:
if len(match_list) == 1:
return alias[0]
possible[alias[0]] = role_id possible[alias[0]] = role_id
return possible return possible
elif type == 'weapons': elif type == 'weapons':

View File

@ -13,6 +13,16 @@ def load_image(
crop: Optional[Tuple[int, int, int, int]] = None, crop: Optional[Tuple[int, int, int, int]] = None,
mode: Optional[str] = None, mode: Optional[str] = None,
): ):
"""
说明
读取图像并预处理
参数
:param path: 图片路径
:param size: 预处理尺寸
:param crop: 预处理裁剪大小
:param mode: 预处理图像模式
:return: 图像对象
"""
img = Image.open(path) img = Image.open(path)
if size: if size:
if isinstance(size, float): if isinstance(size, float):
@ -26,7 +36,16 @@ def load_image(
return img return img
def load_json(file: str = None, path: Union[Path, str] = None, encoding: str = 'utf-8'): def load_json(file: str = None, path: Union[Path, str] = None, encoding: str = 'utf-8') -> dict:
"""
说明
读取本地json文件返回json字典file和path参数2选1即可file需为data/LittlePaimon中的文件path哪的文件都行
参数
:param file: 文件名
:param path: 文件路径
:param encoding: 编码默认为utf-8
:return: json字典
"""
if file and not path: if file and not path:
path = Path() / 'data' / 'LittlePaimon' / file path = Path() / 'data' / 'LittlePaimon' / file
elif path: elif path:
@ -37,12 +56,25 @@ def load_json(file: str = None, path: Union[Path, str] = None, encoding: str = '
return json.load(path.open('r', encoding=encoding)) return json.load(path.open('r', encoding=encoding))
async def load_json_from_url(url: str): async def load_json_from_url(url: str, path: Union[Path, str] = None, force_refresh: bool = False) -> dict:
"""
从网络url中读取json当有path参数时如果path文件不存在就会从url下载保存到path如果path文件存在则直接读取path
:param url: url
:param path: 本地json文件路径
:param force_refresh: 是否强制重新下载
:return: json字典
"""
if path and Path(path).exists() and not force_refresh:
return load_json(path=path)
else:
try: try:
resp = await aiorequests.get(url) resp = await aiorequests.get(url)
except SSLCertVerificationError: except SSLCertVerificationError:
resp = await aiorequests.get(url.replace('https', 'http')) resp = await aiorequests.get(url.replace('https', 'http'))
return resp.json() data = resp.json()
if path and not Path(path).exists():
save_json(data=data, path=path)
return data
def save_json(data, file: str = None, path: Union[Path, str] = None, encoding: str = 'utf-8'): def save_json(data, file: str = None, path: Union[Path, str] = None, encoding: str = 'utf-8'):

4
utils/json/ban_word.txt Normal file
View File

@ -0,0 +1,4 @@
[CQ:
[cq:
[Cq:
[cQ:

View File

@ -13,6 +13,12 @@ from .db_util import get_last_query, update_last_query
from .file_handler import load_image from .file_handler import load_image
from . import aiorequests from . import aiorequests
# 加载敏感违禁词列表
ban_word = []
with open(Path(__file__).parent / 'json' / 'ban_word.txt', 'r', encoding='utf-8') as f:
for line in f:
ban_word.append(line.strip())
class MessageBuild: class MessageBuild:
@ -25,6 +31,16 @@ class MessageBuild:
quality: Optional[int] = 100, quality: Optional[int] = 100,
mode: Optional[str] = 'RGB' mode: Optional[str] = 'RGB'
) -> MessageSegment: ) -> MessageSegment:
"""
说明
图片预处理并构造成MessageSegment
:param img: 图片Image对象或图片路径
:param size: 预处理尺寸
:param crop: 预处理裁剪大小
:param quality: 预处理图片质量
:param mode: 预处理图像模式
:return: MessageSegment.image
"""
if isinstance(img, str) or isinstance(img, Path): if isinstance(img, str) or isinstance(img, Path):
img = load_image(path=img, size=size, mode=mode, crop=crop) img = load_image(path=img, size=size, mode=mode, crop=crop)
else: else:
@ -48,11 +64,26 @@ class MessageBuild:
size: Optional[Tuple[int, int]] = None, size: Optional[Tuple[int, int]] = None,
crop: Optional[Tuple[int, int, int, int]] = None, crop: Optional[Tuple[int, int, int, int]] = None,
quality: Optional[int] = 100, quality: Optional[int] = 100,
mode: Optional[str] = 'RGB', mode: Optional[str] = None,
tips: Optional[str] = None tips: Optional[str] = None,
is_check_time: Optional[bool] = True,
check_time_day: Optional[int] = 3
): ):
"""
从url下载图片并预处理并构造成MessageSegment如果url的图片已存在本地则直接读取本地图片
:param url: 图片url
:param size: 预处理尺寸
:param crop: 预处理裁剪大小
:param quality: 预处理图片质量
:param mode: 预处理图像模式
:param tips: url中不存在该图片时的提示语
:param is_check_time: 是否检查本地图片最后修改时间
:param check_time_day: 检查本地图片最后修改时间的天数超过该天数则重新下载图片
:return: MessageSegment.image
"""
path = Path() / 'data' / url path = Path() / 'data' / url
if path.exists() and not check_time(path.stat().st_mtime, 3): if path.exists() and (
not is_check_time or (is_check_time and not check_time(path.stat().st_mtime, check_time_day))):
img = Image.open(path) img = Image.open(path)
else: else:
path.parent.mkdir(parents=True, exist_ok=True) path.parent.mkdir(parents=True, exist_ok=True)
@ -63,23 +94,35 @@ class MessageBuild:
img = img.resize(size) img = img.resize(size)
if crop: if crop:
img = img.crop(crop) img = img.crop(crop)
bio = BytesIO() if mode:
img = img.convert(mode) img = img.convert(mode)
img.save(bio, format='JPEG' if mode == 'RGB' else 'PNG', quality=quality) bio = BytesIO()
img.save(bio, format=img.format, quality=quality)
return MessageSegment.image(bio) return MessageSegment.image(bio)
@classmethod @classmethod
def Text(cls, text: str) -> MessageSegment: def Text(cls, text: str) -> MessageSegment:
# TODO 过滤负面文本 """
过滤文本中的敏感词
:param text: 文本
:return: MessageSegment.text
"""
for word in ban_word:
if word in text:
text = text.replace(word, '*')
return MessageSegment.text(text) return MessageSegment.text(text)
@classmethod @classmethod
def Record(cls, path: str) -> MessageSegment: def Record(cls, path: str) -> MessageSegment:
# TODO 网络语音
return MessageSegment.record(path) return MessageSegment.record(path)
@classmethod @classmethod
async def StaticRecord(cls, url: str) -> MessageSegment: async def StaticRecord(cls, url: str) -> MessageSegment:
"""
从url中下载音频文件并构造成MessageSegment如果本地已有该音频文件则直接读取本地文件
:param url: 语音url
:return: MessageSegment.record
"""
path = Path() / 'data' / url path = Path() / 'data' / url
if not path.exists(): if not path.exists():
path.parent.mkdir(parents=True, exist_ok=True) path.parent.mkdir(parents=True, exist_ok=True)
@ -88,6 +131,25 @@ class MessageBuild:
path.write_bytes(content) path.write_bytes(content)
return MessageSegment.record(file=path) return MessageSegment.record(file=path)
@classmethod
def Video(cls, path: str) -> MessageSegment:
return MessageSegment.video(path)
@classmethod
async def StaticVideo(cls, url: str) -> MessageSegment:
"""
从url中下载视频文件并构造成MessageSegment如果本地已有该视频文件则直接读取本地文件
:param url: 视频url
:return: MessageSegment.video
"""
path = Path() / 'data' / url
if not path.exists():
path.parent.mkdir(parents=True, exist_ok=True)
resp = await aiorequests.get(url='https://static.cherishmoon.fun/' + url)
content = resp.content
path.write_bytes(content)
return MessageSegment.video(file=path)
async def get_at_target(msg): async def get_at_target(msg):
for msg_seg in msg: for msg_seg in msg:
@ -174,6 +236,8 @@ def replace_all(raw_text: str, text_list: Union[str, list]):
def transform_uid(msg): def transform_uid(msg):
if not msg:
return None
if isinstance(msg, Message): if isinstance(msg, Message):
msg = msg.extract_plain_text().strip() msg = msg.extract_plain_text().strip()
check_uid = msg.split(' ') check_uid = msg.split(' ')
@ -193,4 +257,3 @@ def check_time(time_stamp, n=1):
return True return True
else: else:
return False return False