update code

This commit is contained in:
hibiki 2021-08-17 23:17:08 +08:00
parent 3c6a365718
commit 1996f0d96a
73 changed files with 1501 additions and 1163 deletions

View File

@ -10,7 +10,7 @@ NICKNAME=["真寻", "小真寻", "绪山真寻", "小寻子"]
SESSION_EXPIRE_TIMEOUT=30
DEBUG=true
DEBUG=False
# 服务器和端口
HOST = 127.0.0.1
PORT = 8080

View File

@ -1,4 +1,3 @@
from .utils.util import get_config_data
from typing import List, Optional, Tuple
from services.service_config import TL_M_KEY, SYSTEM_M_PROXY, ALAPI_M_TOKEN
@ -11,6 +10,8 @@ except ModuleNotFoundError:
# 是否使用配置文件
USE_CONFIG_FILE: bool = False
# 回复消息名称
NICKNAME: str = '小真寻'
# API KEY必要
RSSHUBAPP: str = "https://rsshub.app" # rsshub
@ -35,7 +36,7 @@ SYSTEM_PROXY: Optional[str] = None # 全局代理
BUFF_PROXY: Optional[str] = None # Buff代理
# 公开图库列表
IMAGE_DIR_LIST: List[str] = ["色图", "美图", "萝莉", "壁纸"]
IMAGE_DIR_LIST: List[str] = ["美图", "萝莉", "壁纸"]
# 对被ban用户发送的消息
BAN_RESULT: str = "才不会给你发消息."
@ -77,6 +78,8 @@ MUTE_DEFAULT_COUNT: int = 10 # 刷屏禁言默认检测次数
MUTE_DEFAULT_TIME: int = 7 # 刷屏检测默认规定时间
MUTE_DEFAULT_DURATION: int = 10 # 刷屏检测默禁言时长(分钟)
CHECK_NOTICE_INFO_CD = 300 # 群检测个人权限检测等各种检测提示信息cd
# 注:即在 MALICIOUS_CHECK_TIME 时间内触发相同命令 MALICIOUS_BAN_COUNT 将被ban MALICIOUS_BAN_TIME 分钟
MALICIOUS_BAN_TIME: int = 30 # 恶意命令触发检测触发后ban的时长分钟
MALICIOUS_BAN_COUNT: int = 8 # 恶意命令触发检测最大触发次数
@ -190,6 +193,14 @@ plugins2info_dict = {
"level": 5,
"cmd": ["pix", "PIX", "pIX", "Pix", "PIx"],
},
"wbtop": {
"level": 5,
"cmd": ['微博热搜', "微博", "wbtop"]
},
"update_info": {
"level": 5,
"cmd": ['更新信息', '更新日志']
}
}
if TL_M_KEY:

View File

@ -1,6 +1,6 @@
from .utils.util import get_config_data
from pathlib import Path
from configs.config import USE_CONFIG_FILE
# from configs.config import USE_CONFIG_FILE
# 图片路径
IMAGE_PATH = Path("resources/img/")
@ -20,24 +20,24 @@ TEMP_PATH = Path("resources/img/temp/")
def init_path():
global IMAGE_PATH, VOICE_PATH, TXT_PATH, LOG_PATH, TTF_PATH, DATA_PATH, TEMP_PATH
if USE_CONFIG_FILE:
data = get_config_data()
if data.get('IMAGE_PATH'):
IMAGE_PATH = Path(data['IMAGE_PATH'])
if data.get('VOICE_PATH'):
VOICE_PATH = Path(data['VOICE_PATH'])
if data.get('TXT_PATH'):
TXT_PATH = Path(data['TXT_PATH'])
if data.get('LOG_PATH'):
LOG_PATH = Path(data['LOG_PATH'])
if data.get('TTF_PATH'):
TTF_PATH = Path(data['TTF_PATH'])
if data.get('DATA_PATH'):
DATA_PATH = Path(data['DATA_PATH'])
if data.get('DRAW_PATH'):
DRAW_PATH = Path(data['DRAW_PATH'])
if data.get('TEMP_PATH'):
TEMP_PATH = Path(data['TEMP_PATH'])
# if USE_CONFIG_FILE:
# data = get_config_data()
# if data.get('IMAGE_PATH'):
# IMAGE_PATH = Path(data['IMAGE_PATH'])
# if data.get('VOICE_PATH'):
# VOICE_PATH = Path(data['VOICE_PATH'])
# if data.get('TXT_PATH'):
# TXT_PATH = Path(data['TXT_PATH'])
# if data.get('LOG_PATH'):
# LOG_PATH = Path(data['LOG_PATH'])
# if data.get('TTF_PATH'):
# TTF_PATH = Path(data['TTF_PATH'])
# if data.get('DATA_PATH'):
# DATA_PATH = Path(data['DATA_PATH'])
# if data.get('DRAW_PATH'):
# DRAW_PATH = Path(data['DRAW_PATH'])
# if data.get('TEMP_PATH'):
# TEMP_PATH = Path(data['TEMP_PATH'])
IMAGE_PATH.mkdir(parents=True, exist_ok=True)
VOICE_PATH.mkdir(parents=True, exist_ok=True)
TXT_PATH.mkdir(parents=True, exist_ok=True)

View File

@ -9,6 +9,7 @@ from nonebot.typing import T_State
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent, MessageEvent
from nonebot.adapters.cqhttp.permission import GROUP
from utils.utils import FreqLimiter
from configs.config import NICKNAME
__plugin_name__ = "基本设置 [Hidden]"
@ -38,15 +39,16 @@ self_introduction = on_command(
@self_introduction.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
result = (
"我叫绪山真寻\n"
"你们可以叫我真寻,小真寻,哪怕你们叫我小寻子我也能接受!\n"
"年龄的话我还是个**岁初中生(至少现在是)\n"
"身高保密!!!(也就比美波里(姐姐..(妹妹))矮一点)\n"
"我生日是在3月6号, 能记住的话我会很高兴的\n现在是自宅警备系的现役JC\n"
"最好的朋友是椛!\n" + image("zhenxun")
)
await self_introduction.finish(result)
if NICKNAME.find('真寻') != -1:
result = (
"我叫绪山真寻\n"
"你们可以叫我真寻,小真寻,哪怕你们叫我小寻子我也能接受!\n"
"年龄的话我还是个**岁初中生(至少现在是)\n"
"身高保密!!!(也就比美波里(姐姐..(妹妹))矮一点)\n"
"我生日是在3月6号, 能记住的话我会很高兴的\n现在是自宅警备系的现役JC\n"
"最好的朋友是椛!\n" + image("zhenxun")
)
await self_introduction.finish(result)
my_wife = on_keyword({"老婆"}, rule=to_me(), priority=5, block=True)

View File

@ -7,7 +7,6 @@ import aiohttp
from utils.message_builder import image
from utils.utils import get_local_proxy, get_bot
from pathlib import Path
from nonebot import require
from configs.config import plugins2info_dict
from models.group_member_info import GroupInfoUser
import time
@ -15,145 +14,181 @@ from datetime import datetime
from services.db_context import db
from models.level_user import LevelUser
from configs.config import ADMIN_DEFAULT_AUTH
from utils.static_data import group_manager
from utils.image_utils import CreateImg
import asyncio
try:
import ujson as json
except ModuleNotFoundError:
import json
export = require("nonebot_plugin_manager")
command_dict = {
'早晚安': 'zwa',
'进群欢迎': 'hy',
'每日开箱重置提醒': 'kxcz',
'b站转发解析': 'blpar',
'epic': 'epic',
'丢人爬': 'pa',
'原神黄历提醒': 'almanac',
"早晚安": "zwa",
"进群欢迎": "hy",
"每日开箱重置提醒": "kxcz",
"b站转发解析": "blpar",
"epic": "epic",
"丢人爬": "pa",
"原神黄历提醒": "almanac",
}
command_list = list(command_dict.values())
command_info_dt = {
'早晚安': '将会在每晚11:59晚安在6:01早安哦',
'每日开箱重置提醒': '将会在每日00:01提示开箱重置',
'epic': '将会在每日中午12:01发送可白嫖的epic游戏',
'原神黄历提醒': '将会在每日8:00发送当日的原神黄历',
"早晚安": "将会在每晚11:59晚安在6:01早安哦",
"每日开箱重置提醒": "将会在每日00:01提示开箱重置",
"epic": "将会在每日中午12:01发送可白嫖的epic游戏",
"原神黄历提醒": "将会在每日8:00发送当日的原神黄历",
}
async def remind_status(group: int, name: str, flag: bool) -> str:
_name = ''
_name = ""
if name in command_dict.values():
_name = list(command_dict.keys())[list(command_dict.values()).index(name)]
if flag:
rst = '开启'
rst = "开启"
if await GroupRemind.get_status(group, name):
return f'该群已经{rst}{_name},请勿重复开启!'
return f"该群已经{rst}{_name},请勿重复开启!"
else:
rst = '关闭'
rst = "关闭"
if not await GroupRemind.get_status(group, name):
return f'该群已经{rst}{_name},请勿重复开启!'
return f"该群已经{rst}{_name},请勿重复开启!"
if await GroupRemind.set_status(group, name, flag):
info = command_info_dt[_name] if command_info_dt.get(_name) else ''
info = command_info_dt[_name] if command_info_dt.get(_name) else ""
if info:
info = '\n' + info
return f'成功{rst} {_name}0v0 {info}'
info = "\n" + info
return f"成功{rst} {_name}0v0 {info}"
else:
return f'{rst} {_name} 失败了...'
return f"{rst} {_name} 失败了..."
async def set_group_status(name: str, group_id: int):
flag = None
if name[:2] == '开启':
if name[:2] == "开启":
flag = True
elif name[:2] == '关闭':
elif name[:2] == "关闭":
flag = False
cmd = name[2:]
if cmd in ['全部通知', '所有通知']:
if cmd in ["全部通知", "所有通知"]:
for command in command_list:
await remind_status(group_id, command, flag)
return f'{name[:2]}所有通知!'
return f"{name[:2]}所有通知!"
return await remind_status(group_id, command_dict[cmd], flag)
async def group_current_status(group_id: int):
result = f'(被动技能)\n早晚安通知:{"" if await GroupRemind.get_status(group_id, "zwa") else "×"}\n' \
f'进群欢迎:{"" if await GroupRemind.get_status(group_id, "hy") else "×"}\n' \
f'每日开箱重置通知:{"" if await GroupRemind.get_status(group_id, "kxcz") else "×"}\n' \
f'b站转发解析{"" if await GroupRemind.get_status(group_id, "blpar") else "×"}\n' \
f'丢人爬:{"" if await GroupRemind.get_status(group_id, "pa") else "×"}\n' \
f'epic免费游戏{"" if await GroupRemind.get_status(group_id, "epic") else "×"}\n' \
f'原神黄历提醒:{"" if await GroupRemind.get_status(group_id, "almanac") else "×"}'
result = (
f'(被动技能)\n早晚安通知:{"" if await GroupRemind.get_status(group_id, "zwa") else "×"}\n'
f'进群欢迎:{"" if await GroupRemind.get_status(group_id, "hy") else "×"}\n'
f'每日开箱重置通知:{"" if await GroupRemind.get_status(group_id, "kxcz") else "×"}\n'
f'b站转发解析{"" if await GroupRemind.get_status(group_id, "blpar") else "×"}\n'
f'丢人爬:{"" if await GroupRemind.get_status(group_id, "pa") else "×"}\n'
f'epic免费游戏{"" if await GroupRemind.get_status(group_id, "epic") else "×"}\n'
f'原神黄历提醒:{"" if await GroupRemind.get_status(group_id, "almanac") else "×"}'
)
return result
custom_welcome_msg_json = Path() / "data" / "custom_welcome_msg" / "custom_welcome_msg.json"
custom_welcome_msg_json = (
Path() / "data" / "custom_welcome_msg" / "custom_welcome_msg.json"
)
async def custom_group_welcome(msg, imgs, user_id, group_id):
img_result = ''
img = imgs[0] if imgs else ''
result = ''
if os.path.exists(DATA_PATH + f'custom_welcome_msg/{group_id}.jpg'):
os.remove(DATA_PATH + f'custom_welcome_msg/{group_id}.jpg')
img_result = ""
img = imgs[0] if imgs else ""
result = ""
if os.path.exists(DATA_PATH + f"custom_welcome_msg/{group_id}.jpg"):
os.remove(DATA_PATH + f"custom_welcome_msg/{group_id}.jpg")
# print(custom_welcome_msg_json)
if not custom_welcome_msg_json.exists():
custom_welcome_msg_json.parent.mkdir(parents=True, exist_ok=True)
data = {}
else:
try:
data = json.load(open(custom_welcome_msg_json, 'r'))
data = json.load(open(custom_welcome_msg_json, "r"))
except FileNotFoundError:
data = {}
try:
if msg:
data[str(group_id)] = str(msg)
json.dump(data, open(custom_welcome_msg_json, 'w'), indent=4, ensure_ascii=False)
logger.info(f'USER {user_id} GROUP {group_id} 更换群欢迎消息 {msg}')
json.dump(
data, open(custom_welcome_msg_json, "w"), indent=4, ensure_ascii=False
)
logger.info(f"USER {user_id} GROUP {group_id} 更换群欢迎消息 {msg}")
result += msg
if img:
async with aiohttp.ClientSession() as session:
async with session.get(img, proxy=get_local_proxy()) as response:
async with aiofiles.open(DATA_PATH + f'custom_welcome_msg/{group_id}.jpg', 'wb') as f:
async with aiofiles.open(
DATA_PATH + f"custom_welcome_msg/{group_id}.jpg", "wb"
) as f:
await f.write(await response.read())
img_result = image(abspath=DATA_PATH + f'custom_welcome_msg/{group_id}.jpg')
logger.info(f'USER {user_id} GROUP {group_id} 更换群欢迎消息图片')
img_result = image(abspath=DATA_PATH + f"custom_welcome_msg/{group_id}.jpg")
logger.info(f"USER {user_id} GROUP {group_id} 更换群欢迎消息图片")
except Exception as e:
logger.error(f'GROUP {group_id} 替换群消息失败 e:{e}')
return '替换群消息失败..'
return f'替换群欢迎消息成功:\n{result}' + img_result
logger.error(f"GROUP {group_id} 替换群消息失败 e:{e}")
return "替换群消息失败.."
return f"替换群欢迎消息成功:\n{result}" + img_result
async def change_group_switch(cmd: str, group_id: int):
def change_group_switch(cmd: str, group_id: int, is_super: bool = False):
group_help_file = Path(DATA_PATH) / "group_help" / f"{group_id}.png"
group_id = str(group_id)
status = cmd[:2]
cmd = cmd[2:]
try:
with open(DATA_PATH + 'manager/plugin_list.json', 'r', encoding='utf8') as f:
plugin_list = json.load(f)
except ValueError:
pass
except FileNotFoundError:
pass
for plugin_cmd in plugins2info_dict.keys():
if cmd in plugins2info_dict[plugin_cmd]['cmd']:
# print(plugin_list[plugin_cmd])
if status == '开启':
# if group_id in plugin_list[plugin_cmd]:
if group_id not in plugin_list[plugin_cmd] or plugin_list[plugin_cmd][group_id]:
return f'功能 {cmd} 正处于开启状态!不要重复开启.'
export.unblock_plugin(group_id, plugin_cmd)
if cmd in plugins2info_dict[plugin_cmd]["cmd"]:
if is_super:
plugin_cmd = f'{plugin_cmd}:super'
if status == "开启":
if group_manager.get_plugin_status(plugin_cmd, group_id):
return f"功能 {cmd} 正处于开启状态!不要重复开启."
group_manager.unblock_plugin(plugin_cmd, group_id)
else:
if group_id in plugin_list[plugin_cmd]:
if not plugin_list[plugin_cmd][group_id]:
return f'功能 {cmd} 正处于关闭状态!不要重复关闭.'
export.block_plugin(group_id, plugin_cmd)
if os.path.exists(DATA_PATH + f'group_help/{group_id}.png'):
os.remove(DATA_PATH + f'group_help/{group_id}.png')
if not group_manager.get_plugin_status(plugin_cmd, group_id):
return f"功能 {cmd} 正处于关闭状态!不要重复关闭."
group_manager.block_plugin(plugin_cmd, group_id)
if group_help_file.exists():
group_help_file.unlink()
return f"{status} {cmd} 功能!"
return f"没有找到 {cmd} 功能..."
return f'{status} {cmd} 功能!'
return f'没有找到 {cmd} 功能喔'
def set_plugin_status(cmd: str, block_type: str = "all"):
status = cmd[:2]
cmd = cmd[2:]
for plugin_cmd in plugins2info_dict.keys():
if cmd in plugins2info_dict[plugin_cmd]["cmd"]:
if status == "开启":
group_manager.unblock_plugin(plugin_cmd)
else:
group_manager.block_plugin(plugin_cmd, block_type=block_type)
break
async def get_plugin_status():
return await asyncio.get_event_loop().run_in_executor(None, _get_plugin_status)
def _get_plugin_status():
rst = '\t功能\n'
flag_str = '状态'.rjust(4) + '\n'
for plugin_cmd in plugins2info_dict:
flag = group_manager.get_plugin_block_type(plugin_cmd)
flag = flag.upper() + ' CLOSE' if flag else 'OPEN'
rst += f'{plugins2info_dict[plugin_cmd]["cmd"][0]}\n'
flag_str += f'{flag}\n'
height = len(rst.split('\n')) * 24
a = CreateImg(150, height, font_size=20)
a.text((10, 10), rst)
b = CreateImg(200, height, font_size=20)
b.text((10, 10), flag_str)
A = CreateImg(380, height)
A.paste(a)
A.paste(b, (150, 0))
return image(b64=A.pic2bs4())
async def update_member_info(group_id: int) -> bool:
@ -163,35 +198,61 @@ async def update_member_info(group_id: int) -> bool:
_exist_member_list = []
# try:
for user_info in _group_user_list:
if user_info['card'] == "":
nickname = user_info['nickname']
if user_info["card"] == "":
nickname = user_info["nickname"]
else:
nickname = user_info['card']
nickname = user_info["card"]
async with db.transaction():
# 更新权限
if user_info['role'] in ['owner', 'admin'] and not await LevelUser.is_group_flag(user_info['user_id'], group_id):
await LevelUser.set_level(user_info['user_id'], user_info['group_id'], ADMIN_DEFAULT_AUTH)
if str(user_info['user_id']) in bot.config.superusers:
await LevelUser.set_level(user_info['user_id'], user_info['group_id'], 9)
user = await GroupInfoUser.get_member_info(user_info['user_id'], user_info['group_id'])
if (
user_info["role"]
in [
"owner",
"admin",
]
and not await LevelUser.is_group_flag(user_info["user_id"], group_id)
):
await LevelUser.set_level(
user_info["user_id"], user_info["group_id"], ADMIN_DEFAULT_AUTH
)
if str(user_info["user_id"]) in bot.config.superusers:
await LevelUser.set_level(
user_info["user_id"], user_info["group_id"], 9
)
user = await GroupInfoUser.get_member_info(
user_info["user_id"], user_info["group_id"]
)
if user:
if user.user_name != nickname:
await user.update(user_name=nickname).apply()
logger.info(f"用户{user_info['user_id']} 所属{user_info['group_id']} 更新群昵称成功")
_exist_member_list.append(int(user_info['user_id']))
logger.info(
f"用户{user_info['user_id']} 所属{user_info['group_id']} 更新群昵称成功"
)
_exist_member_list.append(int(user_info["user_id"]))
continue
join_time = datetime.strptime(
time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(user_info['join_time'])), "%Y-%m-%d %H:%M:%S")
time.strftime(
"%Y-%m-%d %H:%M:%S", time.localtime(user_info["join_time"])
),
"%Y-%m-%d %H:%M:%S",
)
if await GroupInfoUser.add_member_info(
user_info['user_id'],
user_info['group_id'],
nickname,
join_time,):
_exist_member_list.append(int(user_info['user_id']))
user_info["user_id"],
user_info["group_id"],
nickname,
join_time,
):
_exist_member_list.append(int(user_info["user_id"]))
logger.info(f"用户{user_info['user_id']} 所属{user_info['group_id']} 更新成功")
else:
_error_member_list.append(f"用户{user_info['user_id']} 所属{user_info['group_id']} 更新失败\n")
_del_member_list = list(set(_exist_member_list).difference(set(await GroupInfoUser.get_group_member_id_list(group_id))))
_error_member_list.append(
f"用户{user_info['user_id']} 所属{user_info['group_id']} 更新失败\n"
)
_del_member_list = list(
set(_exist_member_list).difference(
set(await GroupInfoUser.get_group_member_id_list(group_id))
)
)
if _del_member_list:
for del_user in _del_member_list:
if await GroupInfoUser.delete_member_info(del_user, group_id):
@ -202,9 +263,7 @@ async def update_member_info(group_id: int) -> bool:
result = ""
for error_user in _error_member_list:
result += error_user
await bot.send_private_msg(user_id=int(list(bot.config.superusers)[0]), message=result[:-1])
await bot.send_private_msg(
user_id=int(list(bot.config.superusers)[0]), message=result[:-1]
)
return True

View File

@ -39,7 +39,7 @@ group_status = on_command(
"群通知状态",
},
permission=GROUP,
priority=1,
priority=5,
block=True,
)

View File

@ -1,10 +1,11 @@
from nonebot import on_command
from nonebot.typing import T_State
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent
from .data_source import change_group_switch
from nonebot.adapters.cqhttp.permission import GROUP
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent, MessageEvent
from .data_source import change_group_switch, set_plugin_status, get_plugin_status
from services.log import logger
from configs.config import plugins2info_dict
from configs.config import plugins2info_dict, NICKNAME
from utils.utils import get_message_text, is_number
from nonebot.permission import SUPERUSER
__plugin_name__ = "群功能开关"
@ -25,17 +26,52 @@ cmds = set(cmds)
switch_rule = on_command(
"switch_rule", aliases=cmds, permission=GROUP, priority=4, block=True
"switch_rule", aliases=cmds, priority=5, block=True
)
plugins_status = on_command('功能状态', permission=SUPERUSER, priority=5, block=True)
@switch_rule.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
await switch_rule.send(
await change_group_switch(
state["_prefix"]["raw_command"].strip(), event.group_id
async def _(bot: Bot, event: MessageEvent, state: T_State):
if isinstance(event, GroupMessageEvent):
await switch_rule.send(
change_group_switch(
state["_prefix"]["raw_command"].strip(), event.group_id
)
)
)
logger.info(
f'USER {event.user_id} GROUP {event.group_id} 使用群功能管理命令 {state["_prefix"]["raw_command"]}'
)
logger.info(
f'USER {event.user_id} GROUP {event.group_id} 使用群功能管理命令 {state["_prefix"]["raw_command"]}'
)
else:
if str(event.user_id) in bot.config.superusers:
block_type = get_message_text(event.json())
_cmd = state["_prefix"]["raw_command"].strip()
if is_number(block_type):
if not int(block_type) in [g["group_id"] for g in await bot.get_group_list(self_id=int(bot.self_id))]:
await switch_rule.finish(f'{NICKNAME}未加入群聊:{block_type}')
change_group_switch(_cmd, int(block_type), True)
group_name = (await bot.get_group_info(group_id=int(block_type)))['group_name']
await switch_rule.send(f'已禁用群聊 {group_name}({block_type}) 的 {_cmd[2:]} 功能')
else:
if block_type not in ['all', 'private', 'group', 'a', 'p', 'g']:
block_type = 'all'
block_type = 'all' if block_type == 'a' else block_type
block_type = 'private' if block_type == 'p' else block_type
block_type = 'group' if block_type == 'g' else block_type
set_plugin_status(_cmd, block_type)
if block_type == 'all':
await switch_rule.send(f'{_cmd[:2]}功能:{_cmd[2:]}')
elif block_type == 'private':
await switch_rule.send(f'已在私聊中{_cmd[:2]}功能:{_cmd[2:]}')
else:
await switch_rule.send(f'已在群聊中{_cmd[:2]}功能:{_cmd[2:]}')
logger.info(
f'USER {event.user_id} 使用功能管理命令 {state["_prefix"]["raw_command"]} | {block_type}'
)
@plugins_status.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
await plugins_status.send(await get_plugin_status())

View File

@ -5,25 +5,22 @@ from nonebot.adapters.cqhttp import GroupMessageEvent
from utils.image_utils import CreateImg
from configs.path_config import IMAGE_PATH
from utils.message_builder import image
from configs.config import NICKNAME
__plugin_name__ = '管理帮助 [Hidden]'
__plugin_usage__ = '''管理帮助(权限等级)
__plugin_usage__ = f'''管理帮助(权限等级)
1.更新群组成员列表(1)
2.功能开关 --> 指令:开启/关闭xx功能(2)
3.查看群被动技能 --> 指令:群通知状态(2)
4.自定义群欢迎 --> 指令:自定义进群欢迎消息(2)
5.将用户拉入真寻黑名单 --> .ban/.unban(5)
5.将用户拉入{NICKNAME}黑名单 --> .ban/.unban(5)
6.刷屏禁言相关 --> 指令:刷屏检测设置/设置检测时间
\t\t/设置检测次数/设置禁言时长(5)
7.群员活跃度相关 --> 指令:群员活跃检测设置
设置群员活跃检测时长()
添加群员活跃检测白名单[at]...
查看群员活跃检测白名单(5)
8.上传图片(6)
8.上传图片/连续上传图片(6)
9.移动图片(7)
10.删除图片(7)
对我说 真寻帮助 指令 获取对应详细帮助
对我说 {NICKNAME}帮助 指令 获取对应详细帮助
群主与管理员默认 5 级权限
'''

View File

@ -1,4 +1,4 @@
from configs.config import TL_KEY, ALAPI_TOKEN, ALAPI_AI_CHECK
from configs.config import TL_KEY, ALAPI_TOKEN, ALAPI_AI_CHECK, NICKNAME
from configs.path_config import IMAGE_PATH, DATA_PATH
from aiohttp.client import ClientSession
from services.log import logger
@ -104,7 +104,7 @@ async def xie_ai(text: str, sess: ClientSession):
if data["result"] == 0:
content = data["content"]
if "菲菲" in content:
content = content.replace("菲菲", "真寻")
content = content.replace("菲菲", f"{NICKNAME}")
if "公众号" in content:
content = ""
if "{br}" in content:
@ -150,7 +150,7 @@ def no_result() -> str:
random.choice(
[
"你在说啥子?",
f"纯洁的小真寻没听懂",
f"纯洁的{NICKNAME}没听懂",
"下次再告诉你(下次一定)",
"你觉得我听懂了吗?嗯?",
"我!不!知!道!",

View File

@ -1,8 +1,8 @@
from nonebot import on_command
from nonebot.adapters.cqhttp import Bot, MessageEvent
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent
from nonebot.typing import T_State
from configs.config import ALAPI_TOKEN
from .util import get_data
from .data_source import get_data
from services.log import logger
__plugin_name__ = '网易云热评'
@ -27,7 +27,7 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
song_name = data['title']
await comments_163.send(f'{comment}\n\t——《{song_name}')
logger.info(
f"(USER {event.user_id}, GROUP {event.group_id if event.message_type != 'private' else 'private'})"
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
f" 发送网易云热评: {comment} \n\t\t————{song_name}")

View File

@ -1,10 +1,10 @@
from nonebot import on_command
from nonebot.adapters.cqhttp import Bot, MessageEvent, Message
from nonebot.adapters.cqhttp import Bot, MessageEvent, Message, GroupMessageEvent
from nonebot.typing import T_State
from configs.config import ALAPI_TOKEN
from utils.message_builder import image
from utils.utils import get_message_text
from .util import get_data
from .data_source import get_data
from services.log import logger
__plugin_name__ = 'b封面'
@ -33,7 +33,7 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
img = data['cover']
await cover.send(Message(f'title{title}\n{image(img)}'))
logger.info(
f"(USER {event.user_id}, GROUP {event.group_id if event.message_type != 'private' else 'private'})"
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
f" 获取b站封面: {title} url{img}")

View File

@ -0,0 +1,39 @@
from nonebot.adapters.cqhttp import MessageSegment
from utils.image_utils import CreateImg
from utils.message_builder import image
from configs.path_config import IMAGE_PATH
import aiohttp
async def get_data(url: str, params: dict):
async with aiohttp.ClientSession() as session:
try:
async with session.get(
url, timeout=2, params=params
) as response:
data = await response.json()
if data["code"] == 200:
if not data["data"]:
return "没有搜索到...", 997
return data, 200
else:
return f'发生了错误...code{data["code"]}', 999
except TimeoutError:
return "超时了....", 998
def gen_wbtop_pic(data) -> MessageSegment:
bk = CreateImg(700, 32 * 50 + 280, 700, 32, color='#797979')
wbtop_bk = CreateImg(700, 280, background=f'{IMAGE_PATH}/other/webtop.png')
bk.paste(wbtop_bk)
text_bk = CreateImg(700, 32 * 50, 700, 32, color='#797979')
for i, data in enumerate(data):
title = f"{i+1}. {data['hot_word']}"
hot = data['hot_word_num']
img = CreateImg(700, 30, font_size=20)
w, h = img.getsize(title)
img.text((10, int((30 - h) / 2)), title)
img.text((580, int((30 - h) / 2)), hot)
text_bk.paste(img)
bk.paste(text_bk, (0, 280))
return image(b64=bk.pic2bs4())

View File

@ -1,9 +1,9 @@
from nonebot import on_command
from nonebot.adapters.cqhttp import Bot, MessageEvent
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent
from nonebot.typing import T_State
from configs.config import ALAPI_TOKEN
from services.log import logger
from .util import get_data
from .data_source import get_data
__plugin_name__ = '古诗'
__plugin_usage__ = '用法: 无'
@ -29,7 +29,7 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
author = data['author']
await poetry.send(f'{content}\n\t——{author}{title}')
logger.info(
f"(USER {event.user_id}, GROUP {event.group_id if event.message_type != 'private' else 'private'})"
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
f" 发送古诗: f'{content}\n\t--{author}{title}'")

View File

@ -1,17 +0,0 @@
import aiohttp
from utils.utils import get_local_proxy
async def get_data(url: str, params: dict):
async with aiohttp.ClientSession() as session:
try:
async with session.get(url, proxy=get_local_proxy(), timeout=2, params=params) as response:
data = await response.json()
if data['code'] == 200:
if not data['data']:
return '没有搜索到...', 997
return data, 200
else:
return f'发生了错误...code{data["code"]}', 999
except TimeoutError:
return '超时了....', 998

62
plugins/alapi/wbtop.py Normal file
View File

@ -0,0 +1,62 @@
from nonebot import on_command
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent
from nonebot.typing import T_State
from configs.config import ALAPI_TOKEN
from services.log import logger
from .data_source import get_data, gen_wbtop_pic
from utils.browser import get_browser
from utils.utils import get_message_text, is_number
from configs.path_config import IMAGE_PATH
from utils.message_builder import image
import asyncio
__plugin_name__ = '微博热搜'
__plugin_usage__ = '用法: 无'
wbtop = on_command("wbtop", aliases={'微博热搜'}, priority=5, block=True)
wbtop_url = 'https://v2.alapi.cn/api/new/wbtop'
wbtop_data = []
@wbtop.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
global wbtop_data
msg = get_message_text(event.json())
if not wbtop_data or not msg:
params = {
'token': ALAPI_TOKEN
}
data, code = await get_data(wbtop_url, params)
if code != 200:
await wbtop.finish(data, at_sender=True)
wbtop_data = data['data']
img = await asyncio.get_event_loop().run_in_executor(None, gen_wbtop_pic, wbtop_data)
await wbtop.send(img)
logger.info(
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
f" 查询微博热搜")
if is_number(msg) and 0 < int(msg) <= 50:
url = wbtop_data[int(msg) - 1]['url']
browser = await get_browser()
page = None
try:
if not browser:
logger.warning('获取 browser 失败,请部署至 linux 环境....')
await wbtop.finish('获取 browser 对象失败...')
page = await browser.new_page()
await page.goto(url, wait_until='networkidle', timeout=10000)
await page.set_viewport_size({"width": 2560, "height": 1080})
div = await page.query_selector("#pl_feedlist_index")
await div.screenshot(path=f'{IMAGE_PATH}/temp/webtop_{event.user_id}.png', timeout=100000)
await page.close()
await wbtop.send(image(f'webtop_{event.user_id}.png', 'temp'))
except Exception as e:
logger.error(f'微博热搜截图出错... {type(e)}: {e}')
if page:
await page.close()
await wbtop.send('发生了一些错误.....')

View File

@ -2,7 +2,7 @@ from nonebot import on_request
from nonebot.adapters.cqhttp import Bot, FriendRequestEvent, GroupRequestEvent
from models.friend_user import FriendUser
from datetime import datetime
from configs.config import AUTO_ADD_FRIEND
from configs.config import AUTO_ADD_FRIEND, NICKNAME
from nonebot.adapters.cqhttp.exception import ActionFailed
from utils.utils import scheduler
import time
@ -70,7 +70,9 @@ async def _(bot: Bot, event: GroupRequestEvent, state: dict):
)
await bot.send_private_msg(
user_id=event.user_id,
message="想要邀请我偷偷入群嘛~已经提醒真寻的管理员大人了\n" "请确保已经群主或群管理沟通过!\n" "等待管理员处理吧!",
message=f"想要邀请我偷偷入群嘛~已经提醒{NICKNAME}的管理员大人了\n"
"请确保已经群主或群管理沟通过!\n"
"等待管理员处理吧!",
)

View File

@ -3,16 +3,17 @@ from models.ban_user import BanUser
from models.level_user import LevelUser
from nonebot.typing import T_State
from nonebot.adapters.cqhttp import Bot
from nonebot.adapters.cqhttp import GroupMessageEvent
from nonebot.adapters.cqhttp import GroupMessageEvent, PrivateMessageEvent
from nonebot.adapters.cqhttp.permission import GROUP
from utils.utils import get_message_at, get_message_text, is_number
from configs.config import NICKNAME
from services.log import logger
__plugin_name__ = "Ban/unBan"
__plugin_usage__ = (
"用法:\n"
"(不是禁言!是针对真寻是否处理封禁用户消息)\n"
f"(不是禁言!是针对{NICKNAME}是否处理封禁用户消息)\n"
"封禁/解封用户 [小时] [分钟]\n"
"示例:.ban @djdsk\n"
"示例:.ban @djdsk 0 30\n"
@ -25,7 +26,6 @@ ban = on_command(
".ban",
aliases={".unban", "/ban", "/unban"},
priority=5,
permission=GROUP,
block=True,
)
@ -58,7 +58,7 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
and str(event.user_id) not in bot.config.superusers
):
await ban.finish(
f"您的权限等级比对方低或相等, {list(bot.config.nickname)[0]}不能为您使用此功能!",
f"您的权限等级比对方低或相等, {NICKNAME}不能为您使用此功能!",
at_sender=True,
)
if await BanUser.ban(
@ -67,7 +67,7 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
logger.info(
f"USER {event.user_id} GROUP {event.group_id} 将 USER {qq} 封禁 时长 {time/60} 分钟"
)
result = f"已经将 {user_name} 加入{list(bot.config.nickname)[0]}的黑名单了!"
result = f"已经将 {user_name} 加入{NICKNAME}的黑名单了!"
if time != -1:
result += f"将在 {time/60} 分钟后解封"
else:
@ -102,6 +102,58 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
await ban.finish("艾特人了吗??", at_sender=True)
await ban.finish(result, at_sender=True)
@ban.handle()
async def _(bot: Bot, event: PrivateMessageEvent, state: T_State):
if str(event.user_id) in bot.config.superusers:
msg = get_message_text(event.json())
msg = msg.split()
if is_number(msg[0]):
qq = int(msg[0])
if state["_prefix"]["raw_command"] in [".ban", "/ban"]:
hour = 0
minute = 0
if len(msg) > 1 and is_number(msg[1]):
hour = int(msg[1])
if len(msg) > 2 and is_number(msg[2]):
minute = int(msg[2])
time = hour * 60 * 60 + minute * 60
time = time if time else -1
if await BanUser.ban(
qq, 9, time
):
logger.info(
f"USER {event.user_id} 将 USER {qq} 封禁 时长 {time/60} 分钟"
)
result = f"已经将 {qq} 加入{NICKNAME}的黑名单了!"
if time != -1:
result += f"将在 {time/60} 分钟后解封"
else:
result += f"将在 ∞ 分钟后解封"
await ban.send(result)
else:
time = await BanUser.check_ban_time(qq)
if is_number(time):
time = abs(int(time))
if time < 60:
time = str(time) + ""
else:
time = str(int(time / 60)) + " 分钟"
else:
time += " 分钟"
await ban.send(f"{qq} 已在黑名单!预计 {time}后解封")
else:
if await BanUser.unban(qq):
logger.info(
f"USER {event.user_id} 将 USER {qq} 解禁"
)
result = f"已经把 {qq} 从黑名单中删除了!"
else:
result = f"{qq} 不在黑名单!"
await ban.send(result)
else:
await ban.finish('qq号必须是数字\n格式:.ban [qq] [hour]? [minute]?', at_sender=True)

View File

@ -2,7 +2,7 @@ from nonebot.adapters.cqhttp import Bot, MessageEvent
from nonebot.typing import T_State
from nonebot.permission import SUPERUSER
from nonebot import on_command
from .data_source import check_update, get_latest_version
from .data_source import check_update, get_latest_version_data
from services.log import logger
from utils.utils import scheduler, get_bot
from pathlib import Path
@ -65,8 +65,9 @@ async def _():
_version = (
open(_version_file, "r", encoding="utf8").readline().split(":")[-1].strip()
)
latest_version, tar_gz_url = await get_latest_version()
if latest_version and tar_gz_url:
data = await get_latest_version_data()
if data:
latest_version = data["name"]
if _version != latest_version:
bot = get_bot()
await bot.send_private_msg(

View File

@ -1,11 +1,11 @@
from aiohttp.client_exceptions import ClientConnectorError
from nonebot.adapters.cqhttp import Bot
from utils.user_agent import get_user_agent
from utils.utils import get_local_proxy, get_bot
from utils.utils import get_local_proxy
from utils.image_utils import CreateImg
from configs.path_config import IMAGE_PATH
from typing import List
from bs4.element import Tag
from services.log import logger
from bs4 import BeautifulSoup
from pathlib import Path
import ujson as json
import nonebot
@ -24,8 +24,7 @@ if str(platform.system()).lower() == "windows":
driver = nonebot.get_driver()
version_url = "https://github.com/HibiKier/zhenxun_bot/releases"
main_url = "https://github.com/HibiKier/zhenxun_bot"
release_url = "https://api.github.com/repos/HibiKier/zhenxun_bot/releases/latest"
_version_file = Path() / "__version__"
zhenxun_latest_tar_gz = Path() / "zhenxun_latest_file.tar.gz"
@ -33,30 +32,24 @@ temp_dir = Path() / "temp"
backup_dir = Path() / "backup"
@driver.on_startup
def init():
@driver.on_bot_connect
async def remind(bot: Bot):
if str(platform.system()).lower() != "windows":
restart = Path() / "restart.sh"
env_file = Path() / ".env.dev"
if not restart.exists() and env_file.exists():
with open(env_file, "r", encoding="utf8") as ef:
data = ef.readlines()
port = [x.split("=")[1].strip() for x in data if "port" in x.lower()][0]
if not restart.exists():
with open(restart, "w", encoding="utf8") as f:
f.write(
"pid=$(netstat -tunlp | grep " + port + " | awk '{print $7}')\n"
f"pid=$(netstat -tunlp | grep "
+ str(bot.config.port)
+ " | awk '{print $7}')\n"
"pid=${pid%/*}\n"
"kill -9 $pid\n"
"sleep 3\n"
"python3 bot.py"
)
os.system("chmod +x ./restart.sh")
logger.info("已自动生成 restart.sh(重启) 文件,请检查是否与本地指令符合...")
@driver.on_bot_connect
async def remind(bot: Bot):
is_restart_file = Path() / 'is_restart'
logger.info("已自动生成 restart.sh(重启) 文件,请检查脚本是否与本地指令符合...")
is_restart_file = Path() / "is_restart"
if is_restart_file.exists():
await bot.send_private_msg(
user_id=int(list(bot.config.superusers)[0]),
@ -72,9 +65,11 @@ async def check_update(bot: Bot) -> int:
_version = (
open(_version_file, "r", encoding="utf8").readline().split(":")[-1].strip()
)
latest_version, tar_gz_url = await get_latest_version()
if latest_version and tar_gz_url:
data = await get_latest_version_data()
if data:
latest_version = data["name"]
if _version != latest_version:
tar_gz_url = data["tarball_url"]
logger.info(f"检测真寻已更新,当前版本:{_version},最新版本:{latest_version}")
await bot.send_private_msg(
user_id=int(list(bot.config.superusers)[0]),
@ -88,22 +83,22 @@ async def check_update(bot: Bot) -> int:
)
logger.info("真寻更新完毕,清理文件完成....")
logger.info("开始获取真寻更新日志.....")
update_info = await get_updated_info()
if update_info:
logger.info("获取真寻更新日志成功...开始发送日志...")
await bot.send_private_msg(
user_id=int(list(bot.config.superusers)[0]),
message=f"真寻更新完成,版本:{_version} -> {latest_version}\n"
f"更新日志:\n"
f"{update_info}",
)
else:
logger.warning("获取真寻更新日志失败...")
await bot.send_private_msg(
user_id=int(list(bot.config.superusers)[0]),
message=f"真寻更新完成,版本:{_version} -> {latest_version}\n"
f"获取真寻更新日志失败...",
)
update_info = data["body"]
await bot.send_private_msg(
user_id=int(list(bot.config.superusers)[0]),
message=f"真寻更新完成,版本:{_version} -> {latest_version}\n"
f"更新日期:{data['created_at']}\n"
f"更新日志:\n"
f"{update_info}",
)
width = 0
height = len(update_info.split('\n')) * 24
for m in update_info.split('\n'):
if len(m) * 20 > width:
width = len(m) * 17
A = CreateImg(800, height, font_size=20)
A.text((10, 10), update_info)
A.save(f'{IMAGE_PATH}/update_info.png')
return 200
else:
logger.warning(f"下载真寻最新版本失败...版本号:{latest_version}")
@ -187,29 +182,16 @@ def _file_handle(latest_version: str):
# 获取最新版本号
async def get_latest_version() -> "str, str":
async def get_latest_version_data() -> dict:
async with aiohttp.ClientSession(headers=get_user_agent()) as session:
for _ in range(3):
try:
async with session.get(version_url, proxy=get_local_proxy()) as res:
async with session.get(release_url, proxy=get_local_proxy()) as res:
if res.status == 200:
soup = BeautifulSoup(await res.text(), "lxml")
div = soup.find("div", {"class": "release-entry"})
latest_version = (
div.find(
"div", {"class": "f1 flex-auto min-width-0 text-normal"}
)
.find("a")
.text
)
tar_gz_url = div.find_all(
"a", {"class": "d-flex flex-items-center"}
)[-1].get("href")
tar_gz_url = f"https://github.com{tar_gz_url}"
return latest_version, tar_gz_url
return await res.json()
except (TimeoutError, ClientConnectorError):
pass
return "", ""
return {}
# 下载文件
@ -236,33 +218,3 @@ def check_old_lines(lines: List[str], line: str) -> str:
if len(l) > len(line):
return l
return line
async def get_updated_info() -> str:
async with aiohttp.ClientSession(headers=get_user_agent()) as session:
for _ in range(3):
try:
async with session.get(main_url, proxy=get_local_proxy()) as res:
soup = BeautifulSoup(await res.text(), "lxml")
children_list = list(soup.find("article").children)
children_list = [x for x in children_list if x != "\n"]
for i, children in enumerate(children_list):
a = children.find("a")
if a and isinstance(a, Tag) and a.get("href") == "#更新":
update_info = ""
tmp_children_list = children_list[i:]
tmp_children_list = [
x for x in tmp_children_list if "ul" in str(x)
]
for j, chi in enumerate(tmp_children_list):
if "ul" in str(chi):
update_time = children_list[i:][j + 1].text
update_info += f"更新日期:{update_time}\n"
ul = children_list[i:][j + 2]
break
for li in ul.find_all("li"):
update_info += f"\t{li.text}\n"
return update_info
except (TimeoutError, ClientConnectorError):
pass
return ""

View File

@ -7,6 +7,7 @@ from nonebot.typing import T_State
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent
from configs.config import IMAGE_DIR_LIST
from utils.utils import is_number, cn2py
from pathlib import Path
import os
__plugin_name__ = "删除图片"
@ -51,28 +52,30 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
async def arg_handle(bot: Bot, event: MessageEvent, state: T_State):
path = cn2py(state["path"])
img_id = state["id"]
path = IMAGE_PATH + path
# path = IMAGE_PATH + path
path = Path(IMAGE_PATH) / path
temp = Path(IMAGE_PATH) / 'temp'
max_id = len(os.listdir(path)) - 1
if int(img_id) > max_id or int(img_id) < 0:
await delete_img.finish(f"Id超过上下限上限{max_id}", at_sender=True)
try:
if os.path.exists(IMAGE_PATH + TEMP_PATH + "delete.jpg"):
os.remove(IMAGE_PATH + TEMP_PATH + "delete.jpg")
if os.path.exists(temp / "delete.jpg"):
os.remove(temp / "delete.jpg")
logger.info("删除图片 delete.jpg 成功")
except Exception as e:
logger.warning(f"删除图片 delete.jpg 失败 e{e}")
try:
os.rename(path + img_id + ".jpg", IMAGE_PATH + TEMP_PATH + "delete.jpg")
logger.info(f"移动 {path}{img_id}.jpg 移动成功")
os.rename(path / f"{img_id}.jpg", temp / "delete.jpg")
logger.info(f"移动 {path}/{img_id}.jpg 移动成功")
except Exception as e:
logger.warning(f"{path}{img_id}.jpg --> 移动失败 e:{e}")
if not os.path.exists(path + img_id + ".jpg"):
logger.warning(f"{path}/{img_id}.jpg --> 移动失败 e:{e}")
if not os.path.exists(path / f"{img_id}.jpg"):
try:
if int(img_id) != max_id:
os.rename(path + str(max_id) + ".jpg", path + img_id + ".jpg")
except FileExistsError:
logger.error(f"{path}{max_id}.jpg 替换 {path}{img_id}.jpg 失败 e:{e}")
logger.info(f"{path}{max_id}.jpg 替换 {path}{img_id}.jpg 成功")
os.rename(path / f"{max_id}.jpg", path / f"{img_id}.jpg")
except FileExistsError as e:
logger.error(f"{path}/{max_id}.jpg 替换 {path}/{img_id}.jpg 失败 e:{e}")
logger.info(f"{path}/{max_id}.jpg 替换 {path}/{img_id}.jpg 成功")
logger.info(
f"USER {event.user_id} GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'}"
f" -> id: {img_id} 删除成功"

View File

@ -1,6 +1,6 @@
from nonebot import on_command
from services.log import logger
from nonebot.adapters.cqhttp import Bot, MessageEvent
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent
from nonebot.typing import T_State
from utils.utils import scheduler, get_bot
from .data_source import get_epic_game
@ -20,7 +20,7 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
result, code = await get_epic_game()
await epic.send(result)
logger.info(
f"(USER {event.user_id}, GROUP {event.group_id if event.message_type != 'private' else 'private'})"
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
f" 获取epic免费游戏"
)

View File

@ -16,22 +16,40 @@ from configs.config import FUDU_PROBABILITY
class Fudu:
def __init__(self):
self.mlist = defaultdict(list)
self.data = {}
def append(self, key, content):
self.mlist[key].append(content)
self._create(key)
self.data[key]['data'].append(content)
def clear(self, key):
self.mlist[key] = []
self._create(key)
self.data[key]['data'] = []
self.data[key]['is_repeater'] = False
def size(self, key) -> int:
return len(self.mlist[key])
self._create(key)
return len(self.data[key]['data'])
def check(self, key, content) -> bool:
return self.mlist[key][0] == content
self._create(key)
return self.data[key]['data'][0] == content
def get(self, key):
return self.mlist[key][0]
self._create(key)
return self.data[key]['data'][0]
def is_repeater(self, key):
self._create(key)
return self.data[key]['is_repeater']
def set_repeater(self, key):
self._create(key)
self.data[key]['is_repeater'] = True
def _create(self, key):
if self.data.get(key) is None:
self.data[key] = {'is_repeater': False, 'data': []}
_fudulist = Fudu()
@ -64,7 +82,7 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
_fudulist.clear(event.group_id)
_fudulist.append(event.group_id, add_msg)
if _fudulist.size(event.group_id) > 2:
if random.random() < FUDU_PROBABILITY:
if random.random() < FUDU_PROBABILITY and not _fudulist.is_repeater(event.group_id):
if random.random() < 0.2:
await fudu.finish("打断施法!")
if imgs and msg:
@ -77,7 +95,7 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
rst = ""
if rst:
await fudu.send(rst)
_fudulist.clear(event.group_id)
_fudulist.set_repeater(event.group_id)
async def get_fudu_img_hash(url, group_id):

View File

@ -5,6 +5,7 @@ from utils.utils import get_message_text, scheduler
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent, Message
from nonebot.typing import T_State
from services.log import logger
from nonebot.permission import SUPERUSER
import re
try:
@ -21,7 +22,7 @@ __plugin_usage__ = (
qr = on_command("原神资源查询", priority=5, block=True)
qr_lst = on_command("原神资源列表", priority=5, block=True)
rex_qr = on_regex(".*?(在哪|在哪里|哪有|哪里有).*?", rule=to_me(), priority=5, block=True)
update_info = on_command('更新原神资源信息', priority=1, block=True)
update_info = on_command('更新原神资源信息', permission=SUPERUSER, priority=1, block=True)
@qr.handle()

View File

@ -46,7 +46,7 @@ MAP_RATIO = 0.5
async def query_resource(resource_name: str) -> str:
global CENTER_POINT
planning_route: bool = False
if resource_name and resource_name[-2:] == "路径":
if resource_name and resource_name[-2:] in ["路径", "路线"]:
resource_name = resource_name[:-2].strip()
planning_route = True
if not resource_name or resource_name not in resource_name_list:

View File

@ -81,7 +81,7 @@ async def _(bot: Bot, event: GroupIncreaseNoticeEvent, state: dict):
@group_decrease_handle.handle()
async def _(bot: Bot, event: GroupDecreaseNoticeEvent, state: dict):
# 真寻被踢出群
# 被踢出群
if event.sub_type == "kick_me":
group_id = event.group_id
operator_id = event.operator_id

View File

@ -1,116 +0,0 @@
from nonebot import on_command, on_regex
from utils.utils import get_message_text, is_number, FreqLimiter
from nonebot.rule import to_me
from services.log import logger
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent, MessageEvent, GROUP
from nonebot.typing import T_State
from nonebot.matcher import Matcher
from nonebot.permission import SUPERUSER
from pathlib import Path
from configs.config import plugins2info_dict
from nonebot.message import run_preprocessor, IgnoredException
try:
import ujson as json
except ModuleNotFoundError:
import json
__plugin_name__ = "群权限"
__plugin_usage__ = "区分权限功能"
flmt = FreqLimiter(60)
group_level_data = Path() / "data" / "manager" / "group_level.json"
group_level_data.parent.mkdir(exist_ok=True, parents=True)
group_data = {}
if group_level_data.exists():
group_data = json.load(open(group_level_data, "r", encoding="utf8"))
@run_preprocessor
async def _(matcher: Matcher, bot: Bot, event: GroupMessageEvent, state: T_State):
if not isinstance(event, MessageEvent):
return
if matcher.type == "message" and matcher.priority not in [1, 9]:
if isinstance(event, GroupMessageEvent):
if not group_data.get(str(event.group_id)):
group_data[str(event.group_id)] = 5
if not check_level_group(matcher.module, event.group_id):
try:
if flmt.check(event.group_id):
flmt.start_cd(event.group_id)
await bot.send_group_msg(
group_id=event.group_id, message="群权限不足..."
)
except AttributeError:
pass
raise IgnoredException("群权限不足")
add_group_level = on_command("修改群权限", priority=1, permission=SUPERUSER, block=True)
my_group_level = on_command(
"查看群权限", aliases={"群权限"}, priority=5, permission=GROUP, block=True
)
what_up_group_level = on_regex(
".*?(提高|提升|升高|增加|加上)(.*?)群权限.*?",
rule=to_me(),
priority=5,
permission=GROUP,
block=True,
)
@add_group_level.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = get_message_text(event.json())
if not msg:
await add_group_level.finish("用法:修改群权限 [group] [level]")
msg = msg.split(" ")
if len(msg) < 2:
await add_group_level.finish("参数不完全..[group] [level]")
if is_number(msg[0]) and is_number(msg[1]):
group_id = msg[0]
level = int(msg[1])
else:
await add_group_level.finish("参数错误...group和level必须是数字..")
if not group_data.get(group_id):
group_data[group_id] = 5
await add_group_level.send("修改成功...", at_sender=True)
await bot.send_group_msg(
group_id=int(group_id), message=f"管理员修改了此群权限:{group_data[group_id]} -> {level}"
)
group_data[group_id] = level
with open(group_level_data, "w", encoding="utf8") as f:
json.dump(group_data, f, ensure_ascii=False, indent=4)
logger.info(f"{event.user_id} 修改了 {group_id} 的权限:{level}")
@my_group_level.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
if group_data.get(str(event.group_id)):
level = group_data[str(event.group_id)]
tmp = ""
for plugin in plugins2info_dict:
if plugins2info_dict[plugin]["level"] > level:
plugin_name = plugins2info_dict[plugin]["cmd"][0]
if plugin_name == "pixiv":
plugin_name = "搜图 p站排行"
tmp += f"{plugin_name}\n"
if tmp:
tmp = "\n目前无法使用的功能:\n" + tmp
await my_group_level.finish(f"当前群权限:{level}{tmp}")
@what_up_group_level.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
await what_up_group_level.finish(
f"[此功能用于防止内鬼,如果引起不便那真是抱歉了]\n" f"目前提高群权限的方法:\n" f"\t1.管理员修改权限"
)
# 检查权限
def check_level_group(module: str, group_id: int) -> bool:
if plugins2info_dict.get(module):
if plugins2info_dict[module]["level"] > group_data[str(group_id)]:
return False
return True

View File

@ -0,0 +1,102 @@
from nonebot import on_command, on_regex
from utils.utils import get_message_text, is_number
from nonebot.rule import to_me
from services.log import logger
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent, MessageEvent, GROUP
from nonebot.typing import T_State
from nonebot.permission import SUPERUSER
from configs.config import plugins2info_dict, NICKNAME
from utils.static_data import group_manager
try:
import ujson as json
except ModuleNotFoundError:
import json
__plugin_name__ = "群权限操作"
__plugin_usage__ = "区分权限功能"
add_group_level = on_command("修改群权限", priority=1, permission=SUPERUSER, block=True)
my_group_level = on_command(
"查看群权限", aliases={"群权限"}, priority=5, permission=GROUP, block=True
)
what_up_group_level = on_regex(
".*?(提高|提升|升高|增加|加上)(.*?)群权限.*?",
rule=to_me(),
priority=5,
permission=GROUP,
block=True,
)
manager_group_whitelist = on_command(
"添加群白名单", aliases={"删除群白名单"}, priority=1, permission=SUPERUSER, block=True
)
@add_group_level.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = get_message_text(event.json())
if not msg:
await add_group_level.finish("用法:修改群权限 [group] [level]")
msg = msg.split(" ")
if len(msg) < 2:
await add_group_level.finish("参数不完全..[group] [level]")
if is_number(msg[0]) and is_number(msg[1]):
group_id = msg[0]
level = int(msg[1])
else:
await add_group_level.finish("参数错误...group和level必须是数字..")
old_level = group_manager.get_group_level(group_id)
group_manager.set_group_level(group_id, level)
await add_group_level.send("修改成功...", at_sender=True)
await bot.send_group_msg(
group_id=int(group_id), message=f"管理员修改了此群权限:{old_level} -> {level}"
)
logger.info(f"{event.user_id} 修改了 {group_id} 的权限:{level}")
@my_group_level.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
level = group_manager.get_group_level(str(event.group_id))
tmp = ""
for plugin in plugins2info_dict:
if plugins2info_dict[plugin]["level"] > level:
plugin_name = plugins2info_dict[plugin]["cmd"][0]
if plugin_name == "pixiv":
plugin_name = "搜图 p站排行"
tmp += f"{plugin_name}\n"
if tmp:
tmp = "\n目前无法使用的功能:\n" + tmp
await my_group_level.finish(f"当前群权限:{level}{tmp}")
@what_up_group_level.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
await what_up_group_level.finish(
f"[此功能用于防止内鬼,如果引起不便那真是抱歉了]\n" f"目前提高群权限的方法:\n" f"\t1.管理员修改权限"
)
@manager_group_whitelist.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = get_message_text(event.json()).split()
all_group = [
g["group_id"] for g in await bot.get_group_list(self_id=int(bot.self_id))
]
group_list = []
for group in msg:
if is_number(group) and int(group) in all_group:
group_list.append(int(group))
if group_list:
for group in group_list:
if state["_prefix"]["raw_command"] in ["添加群白名单"]:
group_manager.add_group_white_list(group)
else:
group_manager.delete_group_white_list(group)
group_list = [str(x) for x in group_list]
await manager_group_whitelist.send(
"已成功将 " + "\n".join(group_list) + " " + state["_prefix"]["raw_command"]
)
else:
await manager_group_whitelist.send(f"添加失败,请检查{NICKNAME}是否已加入这些群聊或重复添加/删除群白单名")

View File

@ -6,12 +6,9 @@ from configs.path_config import DATA_PATH
from utils.message_builder import image
import os
from .data_source import create_help_img, create_group_help_img, get_plugin_help
from nonebot import require
from utils.utils import get_message_text
export = require("nonebot_plugin_manager")
__plugin_name__ = "帮助"

View File

@ -1,3 +1,5 @@
from configs.config import NICKNAME
# 实用
utility_help = {
"update_pic": "一些对图片的操作 --> 指令:操作图片/图片/修改图片(包含 10 种图片操作)",
@ -46,12 +48,13 @@ entertainment_help = {
"qiu_qiu_translation": "这家伙到底在说什么? --> 指令:丘丘翻译/丘丘一下/丘丘语翻译",
"query_resource_points": "地图资源速速查看 --> 指令:原神资源查询xx[路径]/原神资源列表/哪里有xx/xx在哪(xx=资源名称)",
"russian": "紧张刺激的俄罗斯轮盘 --> 指令:俄罗斯轮盘帮助",
"gold_redbag": "运气项目又来啦! --> 指令:塞红包/ 抢红包指令: 开/抢/戳一戳真寻/ 退回:退回未抢完的红包",
"poetry": "突然文艺的真寻是否搞错了什么 --> 指令:念诗/来首诗/念首诗",
"gold_redbag": f"运气项目又来啦! --> 指令:塞红包/ 抢红包指令: 开/抢/戳一戳{NICKNAME}/ 退回:退回未抢完的红包",
"poetry": f"突然文艺的{NICKNAME}是否搞错了什么 --> 指令:念诗/来首诗/念首诗",
"comments_163": "生了个人,我很抱歉 --> 指令:到点了/12点了/网易云热评/网易云评论",
"pix_gallery": "偶尔也想看看美图? --> 指令:PIX [关键词/uid/pid:pid] [num]/查看pix图库 [关键词]/显示pix关键词",
'nbnhhsh': "会说话就多说点! --> 指令:nbnhhsh/能不能好好说话 [文本](空格划分)",
"roll": "让真寻来帮你决定吧! --> 指令:roll/ roll [文本](空格划分)"
"roll": f"{NICKNAME}来帮你决定吧! --> 指令:roll/ roll [文本](空格划分)",
"wbtop": f"刚买完瓜,在吃瓜现场 --> 指令:微博热搜/微博热搜 [数字]"
}
# 其他
other_help = [
@ -60,7 +63,7 @@ other_help = [
"不得看看自己权力多大? --> 指令:我的权限",
"有人记得你是什么时候加入我们的 --> 指令:我的信息",
"让我看看更新了什么 --> 指令:更新信息",
"真寻给我把话收回去! --> 指令:撤回 [id](默认0)",
f"{NICKNAME}给我把话收回去! --> 指令:撤回 [id](默认0)",
"群拥有的权限 --> 指令:查看群权限",
"数据统计可视化_1 --> 指令:功能调用统计/日功能调用统计/周功能调用统计/月功能调用统计",
"数据统计可视化_2 --> 指令:周功能调用统计 [功能名称]/月功能调用统计 [功能名称]",

View File

@ -1,18 +1,16 @@
from utils.image_utils import CreateImg
from configs.path_config import IMAGE_PATH, DATA_PATH
import ujson as json
import os
from pathlib import Path
from .config import *
from nonebot import require
from configs.config import (
INITIAL_OPEN_CASE_COUNT,
INITIAL_SETU_PROBABILITY,
ADMIN_DEFAULT_AUTH,
)
from configs.config import plugins2info_dict
from configs.config import plugins2info_dict, NICKNAME
from utils.static_data import group_manager
import nonebot
export = require("nonebot_plugin_manager")
width = 1600
e_height = 0
@ -22,8 +20,9 @@ o_height = 1500
def create_help_img():
if os.path.exists(IMAGE_PATH + "help.png"):
os.remove(IMAGE_PATH + "help.png")
help_img_file = Path(IMAGE_PATH) / 'help.png'
if help_img_file.exists():
help_img_file.unlink()
h = (
100
+ len(utility_help) * 24
@ -60,10 +59,10 @@ def create_help_img():
A.paste(o, (0, o_height))
A.text(
(10, h * 0.68),
"大部分交互功能可以通过输入‘取消’,‘算了’来取消当前交互\n真寻说 “真寻帮助 指令名” 获取对应详细帮助\n"
f"大部分交互功能可以通过输入‘取消’,‘算了’来取消当前交互\n{NICKNAME}说 “{NICKNAME}帮助 指令名” 获取对应详细帮助\n"
"可以通过 “滴滴滴- [消息]” 联系管理员(有趣的想法尽管来吧!<还有Bug和建议>"
"\n[群管理员请看 管理员帮助(群主与管理员自带 5 级权限)]\n\n"
"\t「如果真寻回复了一些不符合人设的话那是因为每日白嫖的图灵次数已用完使用的是备用接口【QAQ】」",
f"\t「如果{NICKNAME}回复了一些不符合人设的话那是因为每日白嫖的图灵次数已用完使用的是备用接口【QAQ】」",
)
A.save(IMAGE_PATH + "help.png")
@ -71,11 +70,6 @@ def create_help_img():
def create_group_help_img(group_id: int):
group_id = str(group_id)
try:
with open(DATA_PATH + "manager/plugin_list.json", "r", encoding="utf8") as f:
plugin_list = json.load(f)
except (ValueError, FileNotFoundError):
pass
h = (
100
+ len(utility_help) * 24
@ -89,7 +83,7 @@ def create_group_help_img(group_id: int):
rst = ""
i = 1
for cmd in entertainment_help.keys():
flag, dfg = parse_cmd(cmd, group_id, plugin_list)
flag, dfg = parse_cmd(cmd, group_id)
if dfg:
cmd = rcmd(dfg)
rst += f"{flag}{i}.{entertainment_help[cmd]}\n"
@ -100,7 +94,7 @@ def create_group_help_img(group_id: int):
rst = ""
i = 1
for cmd in utility_help.keys():
flag, dfg = parse_cmd(cmd, group_id, plugin_list)
flag, dfg = parse_cmd(cmd, group_id)
rst += f"{flag}{i}.{utility_help[cmd]}\n"
i += 1
u.text((10, 10), "实用功能:", fill=(255, 255, 255))
@ -118,7 +112,7 @@ def create_group_help_img(group_id: int):
# A.text((width, 10), f'总开关【{"√" if data["总开关"] else "×"}】')
A.text(
(10, h * 0.68),
"大部分交互功能可以通过输入‘取消’,‘算了’来取消当前交互\n真寻说 “真寻帮助 指令名” 获取对应详细帮助\n"
f"大部分交互功能可以通过输入‘取消’,‘算了’来取消当前交互\n{NICKNAME}说 “{NICKNAME}帮助 指令名” 获取对应详细帮助\n"
"可以通过 “滴滴滴- [消息]” 联系管理员(有趣的想法尽管来吧!<还有Bug和建议>"
f"\n[群管理员请看 管理员帮助(群主与管理员自带 {ADMIN_DEFAULT_AUTH} 级权限)]",
)
@ -130,12 +124,12 @@ def create_group_help_img(group_id: int):
f"\t\t示例:开启签到\n"
f"\t\t可以通过管理员开关自动发送消息(早晚安等)\n"
f"\t\t^请查看管理员帮助^\n\n"
f"\t「如果真寻回复了一些不符合人设的话那是因为每日白嫖的图灵次数已用完使用的是备用接口【QAQ】」",
f"\t「如果{NICKNAME}回复了一些不符合人设的话那是因为每日白嫖的图灵次数已用完使用的是备用接口【QAQ】」",
)
A.save(DATA_PATH + f"group_help/{group_id}.png")
def parse_cmd(cmd, group_id, plugin_list):
def parse_cmd(cmd, group_id):
flag = ""
dfg = None
if cmd.find("draw_card") != -1:
@ -148,9 +142,8 @@ def parse_cmd(cmd, group_id, plugin_list):
elif cmd == "pixiv_s":
cmd = "pixiv"
dfg = "s"
if group_id in plugin_list[cmd]:
if not plugin_list[cmd][group_id]:
flag = "×"
if not group_manager.get_plugin_status(cmd, group_id):
flag = "×"
if cmd in ["bt", "reimu", "nickname"]:
flag = "- "
return flag, dfg

View File

@ -1,5 +1,6 @@
from nonebot.matcher import Matcher
from nonebot.message import run_preprocessor, IgnoredException
from nonebot.adapters.cqhttp.exception import ActionFailed
from nonebot.typing import T_State
from nonebot.adapters.cqhttp import (
Bot,
@ -13,12 +14,16 @@ from configs.config import (
MALICIOUS_BAN_TIME,
MALICIOUS_CHECK_TIME,
MALICIOUS_BAN_COUNT,
CHECK_NOTICE_INFO_CD,
plugins2info_dict,
)
from models.ban_user import BanUser
from utils.utils import is_number, static_flmt, BanCheckLimiter
from utils.message_builder import at
from services.log import logger
from models.level_user import LevelUser
from utils.static_data import group_manager
from utils.utils import FreqLimiter
try:
import ujson as json
@ -45,24 +50,34 @@ async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
time = str(int(time / 60)) + ""
else:
time = str(time) + ""
if event.message_type == "group":
if isinstance(event, GroupMessageEvent):
if not static_flmt.check(event.user_id):
raise IgnoredException("用户处于黑名单中")
static_flmt.start_cd(event.user_id)
if matcher.priority != 9:
await bot.send_group_msg(
group_id=event.group_id,
message=at(event.user_id) + BAN_RESULT + f" 在..在 {time}后才会理你喔",
)
try:
await bot.send_group_msg(
group_id=event.group_id,
message=at(event.user_id)
+ BAN_RESULT
+ f" 在..在 {time}后才会理你喔",
)
except ActionFailed:
pass
else:
if not static_flmt.check(event.user_id):
raise IgnoredException("用户处于黑名单中")
static_flmt.start_cd(event.user_id)
if matcher.priority != 9:
await bot.send_private_msg(
user_id=event.user_id,
message=at(event.user_id) + BAN_RESULT + f" 在..在 {time}后才会理你喔",
)
try:
await bot.send_private_msg(
user_id=event.user_id,
message=at(event.user_id)
+ BAN_RESULT
+ f" 在..在 {time}后才会理你喔",
)
except ActionFailed:
pass
raise IgnoredException("用户处于黑名单中")
@ -85,47 +100,153 @@ async def _(matcher: Matcher, bot: Bot, event: GroupMessageEvent, state: T_State
if not static_flmt.check(event.user_id):
return
static_flmt.start_cd(event.user_id)
await bot.send_group_msg(
group_id=event.group_id,
message=at(event.user_id) + "检测到恶意触发命令,您将被封禁 30 分钟",
)
try:
await bot.send_group_msg(
group_id=event.group_id,
message=at(event.user_id) + "检测到恶意触发命令,您将被封禁 30 分钟",
)
except ActionFailed:
pass
else:
if not static_flmt.check(event.user_id):
return
static_flmt.start_cd(event.user_id)
await bot.send_private_msg(
user_id=event.user_id,
message=at(event.user_id) + "检测到恶意触发命令,您将被封禁 30 分钟",
)
try:
await bot.send_private_msg(
user_id=event.user_id,
message=at(event.user_id) + "检测到恶意触发命令,您将被封禁 30 分钟",
)
except ActionFailed:
pass
raise IgnoredException("检测到恶意触发命令")
_blmt.add(f'{event.user_id}{state["_prefix"]["raw_command"]}')
_flmt = FreqLimiter(CHECK_NOTICE_INFO_CD)
_flmt_g = FreqLimiter(CHECK_NOTICE_INFO_CD)
_flmt_s = FreqLimiter(CHECK_NOTICE_INFO_CD)
_flmt_c = FreqLimiter(CHECK_NOTICE_INFO_CD)
# 权限检测
@run_preprocessor
async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
if not isinstance(event, MessageEvent) or await BanUser.is_ban(event.user_id):
if (
not isinstance(event, MessageEvent)
or await BanUser.is_ban(event.user_id)
or str(event.user_id) in bot.config.superusers
):
return
if matcher.module in admin_plugins_auth.keys() and matcher.priority not in [1, 9]:
if event.message_type == "group":
module = matcher.module
if module in admin_plugins_auth.keys() and matcher.priority not in [1, 9]:
if isinstance(event, GroupMessageEvent):
# 个人权限
if not await LevelUser.check_level(
event.user_id, event.group_id, admin_plugins_auth[matcher.module]
event.user_id, event.group_id, admin_plugins_auth[module]
):
await bot.send_group_msg(
group_id=event.group_id,
message=f"{at(event.user_id)}你的权限不足喔,该功能需要的权限等级:"
f"{admin_plugins_auth[matcher.module]}",
)
try:
if _flmt.check(event.user_id):
_flmt.start_cd(event.user_id)
await bot.send_group_msg(
group_id=event.group_id,
message=f"{at(event.user_id)}你的权限不足喔,该功能需要的权限等级:"
f"{admin_plugins_auth[module]}",
)
except ActionFailed:
pass
raise IgnoredException("权限不足")
else:
if not await LevelUser.check_level(
event.user_id, 0, admin_plugins_auth[matcher.module]
event.user_id, 0, admin_plugins_auth[module]
):
await bot.send_private_msg(
user_id=event.user_id,
message=f"你的权限不足喔,该功能需要的权限等级:{admin_plugins_auth[matcher.module]}",
)
try:
await bot.send_private_msg(
user_id=event.user_id,
message=f"你的权限不足喔,该功能需要的权限等级:{admin_plugins_auth[module]}",
)
except ActionFailed:
pass
raise IgnoredException("权限不足")
if module in plugins2info_dict.keys():
if isinstance(event, GroupMessageEvent):
# 群权限
if plugins2info_dict[module]["level"] > group_manager.get_group_level(
str(event.group_id)
):
try:
if _flmt_g.check(event.user_id):
_flmt_g.start_cd(event.user_id)
await bot.send_group_msg(
group_id=event.group_id, message="群权限不足..."
)
except ActionFailed:
pass
raise IgnoredException("群权限不足")
# 插件状态
if not group_manager.get_plugin_status(module, str(event.group_id)):
try:
if _flmt_s.check(event.group_id):
_flmt_s.start_cd(event.group_id)
await bot.send_group_msg(
group_id=event.group_id, message="该群未开启此功能.."
)
except ActionFailed:
pass
raise IgnoredException("未开启此功能...")
# 管理员禁用
if not group_manager.get_plugin_status(
f"{module}:super", str(event.group_id)
):
try:
if _flmt_s.check(event.group_id):
_flmt_s.start_cd(event.group_id)
await bot.send_group_msg(
group_id=event.group_id, message="管理员禁用了此群该功能..."
)
except ActionFailed:
pass
raise IgnoredException("管理员禁用了此群该功能...")
# 群聊禁用
if not group_manager.get_plugin_status(module, block_type="group"):
try:
if _flmt_c.check(event.group_id):
_flmt_c.start_cd(event.group_id)
await bot.send_group_msg(
group_id=event.group_id, message="该功能在群聊中已被禁用..."
)
except ActionFailed:
pass
raise IgnoredException("该插件在群聊中已被禁用...")
else:
# 私聊禁用
if not group_manager.get_plugin_status(module, block_type="private"):
try:
if _flmt_c.check(event.user_id):
_flmt_c.start_cd(event.user_id)
await bot.send_private_msg(
user_id=event.user_id, message="该功能在私聊中已被禁用..."
)
except ActionFailed:
pass
raise IgnoredException("该插件在私聊中已被禁用...")
# 维护
if not group_manager.get_plugin_status(
module, block_type="all"
) and not group_manager.check_group_is_white(event.group_id):
try:
if _flmt_c.check(event.group_id):
_flmt_c.start_cd(event.group_id)
if isinstance(event, GroupMessageEvent):
await bot.send_group_msg(
group_id=event.group_id, message="此功能正在维护..."
)
else:
await bot.send_private_msg(
user_id=event.user_id, message="此功能正在维护..."
)
except ActionFailed:
pass
raise IgnoredException("此功能正在维护...")
# 为什么AI会自己和自己聊天
@ -145,5 +266,3 @@ async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
if matcher.type == "message":
if state["_prefix"]["raw_command"] and matcher.module == "ai":
raise IgnoredException("有命令就别说话了")

View File

@ -5,9 +5,10 @@ from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent
from nonebot.typing import T_State
import aiohttp
from asyncio.exceptions import TimeoutError
from configs.config import NICKNAME
__plugin_name__ = "鸡汤"
__plugin_usage__ = "用法: 发送’鸡汤‘,真寻亲自为你喝鸡汤"
__plugin_usage__ = f"用法: 发送’鸡汤‘,{NICKNAME}亲自为你喝鸡汤"
url = "https://v2.alapi.cn/api/soul"

View File

@ -7,6 +7,7 @@ from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent
from configs.config import IMAGE_DIR_LIST
from utils.utils import is_number, cn2py
from configs.path_config import IMAGE_PATH
from pathlib import Path
__plugin_name__ = "移动图片"
@ -59,31 +60,32 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
@move_img.got("id", prompt="要移动的图片id是")
async def _(bot: Bot, event: MessageEvent, state: T_State):
img_id = state["id"]
source_path = IMAGE_PATH + cn2py(state["source_path"])
destination_path = IMAGE_PATH + cn2py(state["destination_path"])
source_path = Path(IMAGE_PATH) / cn2py(state["source_path"])
destination_path = Path(IMAGE_PATH) / cn2py(state["destination_path"])
destination_path.mkdir(parents=True, exist_ok=True)
max_id = len(os.listdir(source_path)) - 1
des_max_id = len(os.listdir(destination_path))
if int(img_id) > max_id or int(img_id) < 0:
await move_img.finish(f"Id超过上下限上限{max_id}", at_sender=True)
try:
os.rename(
source_path + img_id + ".jpg", destination_path + str(des_max_id) + ".jpg"
source_path / f"{img_id}.jpg", destination_path / f"{des_max_id}.jpg"
)
logger.info(
f"移动 {source_path}{img_id}.jpg ---> {destination_path}{des_max_id} 移动成功"
f"移动 {source_path}/{img_id}.jpg ---> {destination_path}/{des_max_id} 移动成功"
)
except Exception as e:
logger.warning(
f"移动 {source_path}{img_id}.jpg ---> {destination_path}{des_max_id} 移动失败 e:{e}"
f"移动 {source_path}/{img_id}.jpg ---> {destination_path}/{des_max_id} 移动失败 e:{e}"
)
await move_img.finish(f"移动图片id{img_id} 失败了...", at_sender=True)
if max_id > 0:
try:
os.rename(source_path + str(max_id) + ".jpg", source_path + img_id + ".jpg")
logger.info(f"{source_path}{max_id}.jpg 替换 {source_path}{img_id}.jpg 成功")
os.rename(source_path / f"{max_id}.jpg", source_path / f"{img_id}.jpg")
logger.info(f"{source_path}/{max_id}.jpg 替换 {source_path}/{img_id}.jpg 成功")
except Exception as e:
logger.warning(
f"{source_path}{max_id}.jpg 替换 {source_path}{img_id}.jpg 失败 e:{e}"
f"{source_path}/{max_id}.jpg 替换 {source_path}/{img_id}.jpg 失败 e:{e}"
)
await move_img.finish(f"替换图片id{max_id} -> {img_id} 失败了...", at_sender=True)
logger.info(

View File

@ -11,7 +11,7 @@ from utils.image_utils import get_img_hash
from services.log import logger
import aiohttp
import aiofiles
from configs.config import MUTE_DEFAULT_COUNT, MUTE_DEFAULT_TIME, MUTE_DEFAULT_DURATION
from configs.config import MUTE_DEFAULT_COUNT, MUTE_DEFAULT_TIME, MUTE_DEFAULT_DURATION, NICKNAME
try:
import ujson as json
@ -105,7 +105,7 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
user_id=event.user_id,
duration=mute_data[group_id]["duration"],
)
await mute.send("检测到恶意刷屏,真寻要把你关进小黑屋!", at_sender=True)
await mute.send(f"检测到恶意刷屏,{NICKNAME}要把你关进小黑屋!", at_sender=True)
mute_dict[event.user_id]["count"] = 0
logger.info(
f"USER {event.user_id} GROUP {event.group_id} "

View File

@ -8,11 +8,12 @@ from models.friend_user import FriendUser
import random
from models.ban_user import BanUser
from services.log import logger
from configs.config import NICKNAME
__plugin_name__ = "昵称系统"
__plugin_usage__ = "用法:\n" "以后叫我 [名称]\n" "真寻我是谁"
__plugin_usage__ = f"用法:\n以后叫我 [名称]\n{NICKNAME}我是谁"
nickname = on_command(
"nickname",
@ -46,13 +47,13 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
await nickname.send(
random.choice(
[
"好啦好啦,我知道啦,{},以后就这么叫你吧",
"嗯嗯,小真寻记住你的昵称了哦,{}",
"好突然,突然要叫你昵称什么的...{}..",
"小真寻会好好记住的{}的,放心吧",
"好..好.,那窝以后就叫你{}了.",
f"好啦好啦,我知道啦,{msg},以后就这么叫你吧",
f"嗯嗯,{NICKNAME}记住你的昵称了哦,{msg}",
f"好突然,突然要叫你昵称什么的...{msg}..",
f"{NICKNAME}会好好记住的{msg}的,放心吧",
f"好..好.,那窝以后就叫你{msg}了.",
]
).format(msg)
)
)
logger.info(f"USER {event.user_id} GROUP {event.group_id} 设置群昵称 {msg}")
else:
@ -71,13 +72,13 @@ async def _(bot: Bot, event: PrivateMessageEvent, state: T_State):
await nickname.send(
random.choice(
[
"好啦好啦,我知道啦,{},以后就这么叫你吧",
"嗯嗯,小真寻记住你的昵称了哦,{}",
"好突然,突然要叫你昵称什么的...{}..",
"小真寻会好好记住的{}的,放心吧",
"好..好.,那窝以后就叫你{}了.",
f"好啦好啦,我知道啦,{msg},以后就这么叫你吧",
f"嗯嗯,{NICKNAME}记住你的昵称了哦,{msg}",
f"好突然,突然要叫你昵称什么的...{msg}..",
f"{NICKNAME}会好好记住的{msg}的,放心吧",
f"好..好.,那窝以后就叫你{msg}了.",
]
).format(msg)
)
)
logger.info(f"USER {event.user_id} 设置昵称 {msg}")
else:
@ -97,14 +98,14 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
await my_nickname.send(
random.choice(
[
"我肯定记得你啊,你是{}",
"我不会忘记你的,你也不要忘记我!{}",
"哼哼,真寻记忆力可是很好的,{}",
"嗯?你是失忆了嘛...{}..",
"不要小看真寻的记忆力啊!笨蛋{}QAQ",
"哎?{}..怎么了吗..突然这样问..",
f"我肯定记得你啊,你是{nickname_}",
f"我不会忘记你的,你也不要忘记我!{nickname_}",
f"哼哼,{NICKNAME}记忆力可是很好的,{nickname_}",
f"嗯?你是失忆了嘛...{nickname_}..",
f"不要小看{NICKNAME}的记忆力啊!笨蛋{nickname_}QAQ",
f"哎?{nickname_}..怎么了吗..突然这样问..",
]
).format(nickname_)
)
)
else:
nickname_ = event.sender.card if event.sender.card else event.sender.nickname
@ -122,14 +123,14 @@ async def _(bot: Bot, event: PrivateMessageEvent, state: T_State):
await my_nickname.send(
random.choice(
[
"我肯定记得你啊,你是{}",
"我不会忘记你的,你也不要忘记我!{}",
"哼哼,真寻记忆力可是很好的,{}",
"嗯?你是失忆了嘛...{}..",
"不要小看真寻的记忆力啊!笨蛋{}QAQ",
"哎?{}..怎么了吗..突然这样问..",
f"我肯定记得你啊,你是{nickname_}",
f"我不会忘记你的,你也不要忘记我!{nickname_}",
f"哼哼,{NICKNAME}记忆力可是很好的,{nickname_}",
f"嗯?你是失忆了嘛...{nickname_}..",
f"不要小看{NICKNAME}的记忆力啊!笨蛋{nickname_}QAQ",
f"哎?{nickname_}..怎么了吗..突然这样问..",
]
).format(nickname_)
)
)
else:
nickname_ = (await bot.get_stranger_info(user_id=event.user_id))["nickname"]
@ -149,13 +150,13 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
await cancel_nickname.send(
random.choice(
[
"呜..真寻睡一觉就会忘记的..和梦一样..{}",
"窝知道了..{}..",
"是真寻哪里做的不好嘛..好吧..晚安{}",
"呃,{},下次我绝对绝对绝对不会再忘记你!",
"可..可恶!{}!太可恶了!呜",
f"呜..{NICKNAME}睡一觉就会忘记的..和梦一样..{nickname_}",
f"窝知道了..{nickname_}..",
f"{NICKNAME}哪里做的不好嘛..好吧..晚安{nickname_}",
f"呃,{nickname_},下次我绝对绝对绝对不会再忘记你!",
f"可..可恶!{nickname_}!太可恶了!呜",
]
).format(nickname_)
)
)
await GroupInfoUser.set_group_member_nickname(event.user_id, event.group_id, "")
await BanUser.ban(event.user_id, 9, 60)
@ -170,13 +171,13 @@ async def _(bot: Bot, event: PrivateMessageEvent, state: T_State):
await cancel_nickname.send(
random.choice(
[
"呜..真寻睡一觉就会忘记的..和梦一样..{}",
"窝知道了..{}..",
"是真寻哪里做的不好嘛..好吧..晚安 {}",
"呃,{},下次我绝对绝对绝对不会再忘记你!",
"可..可恶!{}!太可恶了!呜",
f"呜..{NICKNAME}睡一觉就会忘记的..和梦一样..{nickname_}",
f"窝知道了..{nickname_}..",
f"{NICKNAME}哪里做的不好嘛..好吧..晚安{nickname_}",
f"呃,{nickname_},下次我绝对绝对绝对不会再忘记你!",
f"可..可恶!{nickname_}!太可恶了!呜",
]
).format(nickname_)
)
)
await FriendUser.get_user_name(event.user_id)
await BanUser.ban(event.user_id, 9, 60)

View File

@ -1,122 +0,0 @@
from nonebot.plugin import on_shell_command, get_loaded_plugins, export
from nonebot.matcher import Matcher
from nonebot.typing import T_State
from nonebot.exception import IgnoredException
from nonebot.message import run_preprocessor
from nonebot.adapters.cqhttp import (
Event,
Bot,
GroupMessageEvent,
PrivateMessageEvent,
MessageEvent,
)
from configs.config import plugins2info_dict
from utils.utils import FreqLimiter
from models.ban_user import BanUser
from .data import (
block_plugin,
unblock_plugin,
get_group_plugin_list,
auto_update_plugin_list,
)
from .parser import npm_parser
# 导出给其他插件使用
export = export()
export.block_plugin = block_plugin
export.unblock_plugin = unblock_plugin
export.get_group_plugin_list = get_group_plugin_list
# 注册 shell_like 事件响应器
plugin_manager = on_shell_command("npm", parser=npm_parser, priority=1)
flmt = FreqLimiter(60)
# 在 Matcher 运行前检测其是否启用
@run_preprocessor
async def _(matcher: Matcher, bot: Bot, event: Event, state: T_State):
if not isinstance(event, MessageEvent) and matcher.module != 'poke':
return
plugin = matcher.module
group_id = _get_group_id(event)
loaded_plugin_list = _get_loaded_plugin_list()
plugin_list = auto_update_plugin_list(loaded_plugin_list)
# 无视本插件的 Matcher
if (
plugin not in plugins2info_dict
or matcher.priority in [1, 9]
or await BanUser.is_ban(event.user_id)
):
return
if isinstance(event, PrivateMessageEvent) and plugin_list[plugin]["default"]:
return
if not plugin_list[plugin]["default"]:
if str(event.user_id) in bot.config.superusers:
return
if isinstance(event, GroupMessageEvent):
if flmt.check(event.group_id):
flmt.start_cd(event.group_id)
await bot.send_group_msg(group_id=event.group_id, message="此功能正在维护...")
else:
if flmt.check(event.user_id):
flmt.start_cd(event.user_id)
await bot.send_private_msg(user_id=event.user_id, message="此功能正在维护...")
raise IgnoredException(f"Nonebot Plugin Manager has blocked {plugin} !")
if group_id in plugin_list[plugin]:
if not plugin_list[plugin][group_id]:
if plugin != "ai" and matcher.type == "message":
if flmt.check(event.group_id):
flmt.start_cd(event.group_id)
await bot.send_group_msg(
group_id=event.group_id, message="该群未开启此功能.."
)
raise IgnoredException(f"Nonebot Plugin Manager has blocked {plugin} !")
@plugin_manager.handle()
async def _(bot: Bot, event: Event, state: T_State):
args = state["args"]
group_id = _get_group_id(event)
is_admin = _is_admin(event)
is_superuser = _is_superuser(bot, event)
if group_id == 0:
group_id = "default"
if hasattr(args, "handle"):
await plugin_manager.finish(args.handle(args, group_id, is_admin, is_superuser))
# 获取插件列表,并自动排除本插件
def _get_loaded_plugin_list() -> list:
return list(
filter(
lambda plugin: plugin != "nonebot_plugin_manager",
map(lambda plugin: plugin.name, get_loaded_plugins()),
)
)
def _get_group_id(event: Event) -> str:
try:
group_id = event.group_id
except AttributeError:
group_id = "default"
return str(group_id) if group_id else "default"
def _is_admin(event: Event) -> bool:
return (
event.sender.role in ["admin", "owner"]
if isinstance(event, GroupMessageEvent)
else False
)
def _is_superuser(bot: Bot, event: Event) -> bool:
return str(event.user_id) in bot.config.superusers
plugins_dict = {}

View File

@ -1,121 +0,0 @@
import json
import httpx
from pathlib import Path
from configs.config import plugins2info_dict
_DATA_PATH = Path() / "data" / "manager" / "plugin_list.json"
def get_store_plugin_info(plugin: str) -> str:
store_plugin_list = _get_store_plugin_list()
if plugin in store_plugin_list:
plugin = store_plugin_list[plugin]
return (
f"ID: {plugin['id']}\n"
f"Name: {plugin['name']}\n"
f"Description: {plugin['desc']}\n"
f"Version: {httpx.get('https://pypi.org/pypi/'+plugin['link']+'/json').json()['info']['version']}\n"
f"Author: {plugin['author']}\n"
f"Repo: https://github.com/{plugin['repo']}"
)
else:
return "查无此插件!"
def get_group_plugin_list(group_id: str) -> dict:
plugin_list = _load_plugin_list()
group_plugin_list = {}
for plugin in plugin_list:
if group_id in plugin_list[plugin]:
group_plugin_list[plugin] = plugin_list[plugin][group_id]
else:
group_plugin_list[plugin] = plugin_list[plugin]["default"]
return group_plugin_list
def get_store_pulgin_list() -> str:
message = "商店插件列表如下:"
for plugin in _get_store_plugin_list():
if plugin in _load_plugin_list() or plugin == "nonebot_plugin_manager":
message += f"\n[o] {plugin}"
else:
message += f"\n[x] {plugin}"
return message
def auto_update_plugin_list(loaded_plugin_list: list, keep_history: bool = False):
plugin_list = _load_plugin_list()
for plugin in loaded_plugin_list:
if plugin not in plugin_list:
plugin_list[plugin] = {"default": True}
if not keep_history:
plugin_list = {
key: plugin_list[key] for key in plugin_list if key in loaded_plugin_list
}
_dump_plugin_list(plugin_list)
return plugin_list
def block_plugin(group_id: str, *plugins: str):
return _update_plugin_list(group_id, True, *plugins)
def unblock_plugin(group_id: str, *plugins: str):
return _update_plugin_list(group_id, False, *plugins)
# 获取商店插件列表
def _get_store_plugin_list() -> dict:
store_plugin_list = {}
for plugin in httpx.get(
"https://cdn.jsdelivr.net/gh/nonebot/nonebot2@master/docs/.vuepress/public/plugins.json"
).json():
store_plugin_list.update({plugin["id"]: plugin})
return store_plugin_list
# 更新插件列表
def _update_plugin_list(group_id: str, block: bool, *plugins: str) -> str:
plugin_list = _load_plugin_list()
message = "结果如下:"
operate = "屏蔽" if block else "启用"
for plugin in plugins:
for values in plugins2info_dict.values():
if plugin in values['cmd']:
plugin = list(plugins2info_dict.keys())[list(plugins2info_dict.values()).index(values)]
# print(plugin)
break
message += "\n"
if plugin in plugin_list:
if (
not group_id in plugin_list[plugin]
or plugin_list[plugin][group_id] == block
):
plugin_list[plugin][group_id] = not block
message += f"插件{plugin}{operate}成功!"
print(plugin_list[plugin][group_id])
else:
message += f"插件{plugin}已经{operate}"
else:
message += f"插件{plugin}不存在!"
_dump_plugin_list(plugin_list)
return message
# 加载插件列表
def _load_plugin_list() -> dict:
try:
return json.load(_DATA_PATH.open("r", encoding="utf-8"))
except FileNotFoundError:
return {}
# 保存插件列表
def _dump_plugin_list(plugin_list: dict):
_DATA_PATH.parent.mkdir(parents=True, exist_ok=True)
json.dump(
plugin_list,
_DATA_PATH.open("w", encoding="utf-8"),
indent=4,
separators=(",", ": "),
)

View File

@ -1,138 +0,0 @@
from argparse import Namespace
from .data import *
def handle_list(
args: Namespace,
group_id: str,
is_admin: bool,
is_superuser: bool,
) -> str:
message = ""
if args.store:
if is_superuser:
return get_store_pulgin_list()
else:
return "获取商店插件列表需要超级用户权限!"
if args.default:
if is_superuser:
group_id = "default"
message += "默认"
else:
return "获取默认插件列表需要超级用户权限!"
if args.group:
if is_superuser:
group_id = args.group
message += f"{args.group}"
else:
return "获取指定群插件列表需要超级用户权限!"
message += "插件列表如下:\n"
message += "\n".join(
f"[{'o' if get_group_plugin_list(group_id)[plugin] else 'x'}] {plugin}"
for plugin in get_group_plugin_list(group_id)
)
return message
def handle_block(
args: Namespace,
group_id: str,
is_admin: bool,
is_superuser: bool,
) -> str:
if not is_admin and not is_superuser:
return "管理插件需要群管理员权限!"
message = ""
if args.default:
if is_superuser:
group_id = "default"
message += "默认"
else:
return "管理默认插件需要超级用户权限!"
if args.group:
if is_superuser:
group_id = args.group
message += f"{args.group}"
else:
return "管理指定群插件需要超级用户权限!"
message += block_plugin(group_id, *args.plugins)
return message
def handle_unblock(
args: Namespace,
group_id: str,
is_admin: bool,
is_superuser: bool,
) -> str:
message = ""
if not is_admin and not is_superuser:
return "管理插件需要群管理员权限!"
if args.default:
if is_superuser:
group_id = "default"
message += "默认"
else:
return "管理默认插件需要超级用户权限!"
if args.group:
if is_superuser:
group_id = args.group
message += f"{args.group}"
else:
return "管理指定群插件需要超级用户权限!"
message += unblock_plugin(group_id, *args.plugins)
return message
def handle_info(
args: Namespace,
group_id: str,
is_admin: bool,
is_superuser: bool,
) -> str:
if not is_admin and not is_superuser:
return "管理插件需要超级权限!"
return get_store_plugin_info(args.plugin)
def handle_install(
args: Namespace,
group_id: str,
is_admin: bool,
is_superuser: bool,
) -> str:
pass
def handle_update(
args: Namespace,
group_id: str,
is_admin: bool,
is_superuser: bool,
) -> str:
pass
def handle_uninstall(
args: Namespace,
group_id: str,
is_admin: bool,
is_superuser: bool,
) -> str:
pass

View File

@ -1,60 +0,0 @@
from nonebot.rule import ArgumentParser
from .handle import *
npm_parser = ArgumentParser("npm", add_help=False)
npm_parser.add_argument(
"-h", "--help", action="store_true", help="show this help message and exit"
)
npm_subparsers = npm_parser.add_subparsers()
list_parser = npm_subparsers.add_parser("list", help="show plugin list")
list_parser.add_argument(
"-s", "--store", action="store_true", help="show plugin store list"
)
list_parser.add_argument(
"-d", "--default", action="store_true", help="show default plugin list"
)
list_parser.add_argument("-g", "--group", action="store", help="show group plugin list")
list_parser.set_defaults(handle=handle_list)
block_parser = npm_subparsers.add_parser("block", help="block plugin")
block_parser.add_argument("plugins", nargs="*", help="plugins you want to block")
block_parser.add_argument("-d", "--default", action="store_true", help="set default")
block_parser.add_argument("-a", "--all", action="store_true", help="select all plugin")
block_parser.add_argument("-g", "--group", action="store", help="set in group")
block_parser.set_defaults(handle=handle_block)
unblock_parser = npm_subparsers.add_parser("unblock", help="unblock plugin")
unblock_parser.add_argument("plugins", nargs="*", help="plugins you want to unblock")
unblock_parser.add_argument("-d", "--default", action="store_true", help="set default")
unblock_parser.add_argument(
"-a", "--all", action="store_true", help="select all plugin"
)
unblock_parser.add_argument("-g", "--group", action="store", help="set in group")
unblock_parser.set_defaults(handle=handle_unblock)
info_parser = npm_subparsers.add_parser("info", help="show plugin info")
info_parser.add_argument("plugin", help="plugins you want to know")
info_parser.set_defaults(handle=handle_info)
install_parser = npm_subparsers.add_parser("install", help="install plugin")
install_parser.add_argument("plugins", nargs="*", help="plugins you want to install")
install_parser.add_argument("-i", "--index", action="store", help="point to a mirror")
install_parser.set_defaults(handle=handle_install)
update_parser = npm_subparsers.add_parser("update", help="update plugin")
update_parser.add_argument("plugins", nargs="*", help="plugins you want to update")
update_parser.add_argument("-a", "--all", action="store_true", help="select all plugin")
update_parser.add_argument("-i", "--index", action="store", help="point to a mirror")
update_parser.set_defaults(handle=handle_update)
uninstall_parser = npm_subparsers.add_parser("uninstall", help="uninstall plugin")
uninstall_parser.add_argument(
"plugins", nargs="*", help="plugins you want to uninstall"
)
uninstall_parser.add_argument(
"-a", "--all", action="store_true", help="select all plugin"
)
uninstall_parser.set_defaults(handle=handle_uninstall)

View File

@ -15,7 +15,7 @@ __plugin_name__ = "我有一个朋友"
__plugin_usage__ = "用法:我有一个朋友说/问 [消息] [at](不艾特则群员随机)"
one_friend = on_regex(
"^我.*?朋友.*?(想问问|说|让我问问|想问|让我问|想知道|让我帮他问问|让我" "帮他问|让我帮忙问|让我帮忙问问|问).*",
"^我.*?朋友.*?(想问问|说|让我问问|想问|让我问|想知道|让我帮他问问|让我帮他问|让我帮忙问|让我帮忙问问|问).*",
priority=5,
block=True,
)
@ -41,10 +41,13 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
)
]
)
user_name = '朋友'
else:
qq = qq[0]
at_user = await bot.get_group_member_info(group_id=event.group_id, user_id=qq)
user_name = at_user['card'] if at_user['card'] else at_user['nickname']
msg = re.search(
r"^我.*?朋友.*?" r"(想问问|说|让我问问|想问|让我问|想知道|让我帮他问问|让我帮他问|让我帮忙问|让我帮忙问问|问)(.*)", msg
r"^我.*?朋友.*?(想问问|说|让我问问|想问|让我问|想知道|让我帮他问问|让我帮他问|让我帮忙问|让我帮忙问问|问)(.*)", msg
)
msg = msg.group(2)
if not msg:
@ -52,9 +55,8 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
msg = msg.replace("", "").replace("", "").replace("", "")
ava = CreateImg(100, 100, background=BytesIO(await get_pic(qq)))
ava.circle()
text = CreateImg(60, 30, font_size=30)
text.text((0, 0), "朋友")
# text.show()
text = CreateImg(300, 30, font_size=30)
text.text((0, 0), user_name)
A = CreateImg(700, 150, font_size=25, color="white")
A.paste(ava, (30, 25), True)
A.paste(text, (150, 40))

View File

@ -15,6 +15,7 @@ from .open_cases_c import (
open_shilian_case,
)
from .utils import util_get_buff_price, util_get_buff_img, update_count_daily
from configs.config import NICKNAME
__plugin_name__ = "开箱"
__plugin_usage__ = (
@ -26,7 +27,7 @@ __plugin_usage__ = (
"3.命悬一线武器箱\n\t"
"4.裂空武器箱\n\t"
"5.光谱武器箱\n"
"示例:小真寻开箱 突围大行动(不输入指定武器箱则随机)\n"
f"示例:{NICKNAME}开箱 突围大行动(不输入指定武器箱则随机)\n"
"示例:我的开箱(开箱统计)\n"
"示例:群开箱统计\n"
"示例:我的金色"

View File

@ -2,17 +2,21 @@ from nonebot import on_message
from services.log import logger
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent
from nonebot.typing import T_State
from utils.utils import get_message_json, get_local_proxy
import json
from utils.utils import get_message_json, get_local_proxy, get_message_text
from utils.user_agent import get_user_agent
from nonebot.adapters.cqhttp.permission import GROUP
from bilibili_api import video
from utils.message_builder import image
from models.group_remind import GroupRemind
from nonebot.adapters.cqhttp.exception import ActionFailed
from utils.image_utils import CreateImg
from utils.browser import get_browser
from configs.path_config import IMAGE_PATH
import asyncio
import time
import aiohttp
from bilibili_api import settings
import ujson as json
if get_local_proxy():
settings.proxy = get_local_proxy()
@ -22,43 +26,110 @@ parse_bilibili_json = on_message(priority=1, permission=GROUP, block=False)
@parse_bilibili_json.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
if await GroupRemind.get_status(event.group_id, "blpar") and get_message_json(
event.json()
):
try:
data = json.loads(get_message_json(event.json())[0]["data"])
except (IndexError, KeyError):
return
if data:
if data.get("desc") == "哔哩哔哩":
if await GroupRemind.get_status(event.group_id, "blpar"):
vd_info = None
if get_message_json(event.json()):
try:
data = json.loads(get_message_json(event.json())[0]["data"])
except (IndexError, KeyError):
data = None
if data:
# 转发视频
if data.get("desc") == "哔哩哔哩":
async with aiohttp.ClientSession(
headers=get_user_agent()
) as session:
async with session.get(
data["meta"]["detail_1"]["qqdocurl"],
proxy=get_local_proxy(),
timeout=7,
) as response:
url = str(response.url).split("?")[0]
bvid = url.split("/")[-1]
vd_info = await video.Video(bvid=bvid).get_info()
# 转发专栏
if (
data.get("meta")
and data["meta"].get("news")
and data["meta"]["news"].get("desc") == "哔哩哔哩专栏"
):
url = data["meta"]["news"]["jumpUrl"]
page = None
try:
browser = await get_browser()
if not browser:
return
page = await browser.new_page(
user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
" (KHTML, like Gecko) Chrome/93.0.4530.0 Safari/537.36"
)
await page.goto(url, wait_until="networkidle", timeout=10000)
await page.set_viewport_size({"width": 2560, "height": 1080})
await page.click("#app > div")
# await page.click("text=继续阅读全文", timeout=3000)
div = await page.query_selector("#app > div")
await div.screenshot(
path=f"{IMAGE_PATH}/temp/cv_{event.user_id}.png",
timeout=100000,
)
await asyncio.get_event_loop().run_in_executor(
None, resize, f"{IMAGE_PATH}/temp/cv_{event.user_id}.png"
)
await parse_bilibili_json.send(
image(f"cv_{event.user_id}.png", "temp")
)
await page.close()
logger.info(
f"USER {event.user_id} GROUP {event.group_id} 解析bilibili转发 {url}"
)
except Exception as e:
logger.error(f"尝试解析bilibili专栏 {url} 失败 {type(e)}{e}")
if page:
await page.close()
return
# BV
if get_message_text(event.json()):
msg = get_message_text(event.json())
if "https://b23.tv" in msg:
url = "https://" + msg[msg.find("b23.tv") : msg.find("b23.tv") + 13]
async with aiohttp.ClientSession(headers=get_user_agent()) as session:
async with session.get(
data["meta"]["detail_1"]["qqdocurl"],
url,
proxy=get_local_proxy(),
timeout=7,
) as response:
url = str(response.url).split("?")[0]
bvid = url.split("/")[-1]
vd_info = await video.Video(bvid=bvid).get_info()
aid = vd_info["aid"]
title = vd_info["title"]
author = vd_info["owner"]["name"]
reply = vd_info["stat"]["reply"] # 回复
favorite = vd_info["stat"]["favorite"] # 收藏
coin = vd_info["stat"]["coin"] # 投币
# like = vd_info['stat']['like'] # 点赞
# danmu = vd_info['stat']['danmaku'] # 弹幕
date = time.strftime("%Y-%m-%d", time.localtime(vd_info["ctime"]))
try:
await parse_bilibili_json.send(
image(vd_info["pic"]) + f"\nav{aid}\n标题:{title}\n"
f"UP{author}\n"
f"上传日期:{date}\n"
f"回复:{reply},收藏:{favorite},投币:{coin}\n"
f"{url}"
)
except ActionFailed:
logger.warning(f"{event.group_id} 发送bilibili解析失败")
logger.info(
f"USER {event.user_id} GROUP {event.group_id} 解析bilibili转发 {url}"
if "https://www.bilibili.com/video" in msg:
url = msg.split("?")[0]
msg = url.split("/")[-1]
vd_info = await video.Video(bvid=msg).get_info()
if vd_info:
aid = vd_info["aid"]
title = vd_info["title"]
author = vd_info["owner"]["name"]
reply = vd_info["stat"]["reply"] # 回复
favorite = vd_info["stat"]["favorite"] # 收藏
coin = vd_info["stat"]["coin"] # 投币
# like = vd_info['stat']['like'] # 点赞
# danmu = vd_info['stat']['danmaku'] # 弹幕
date = time.strftime("%Y-%m-%d", time.localtime(vd_info["ctime"]))
try:
await parse_bilibili_json.send(
image(vd_info["pic"]) + f"\nav{aid}\n标题:{title}\n"
f"UP{author}\n"
f"上传日期:{date}\n"
f"回复:{reply},收藏:{favorite},投币:{coin}\n"
f"{url}"
)
except ActionFailed:
logger.warning(f"{event.group_id} 发送bilibili解析失败")
logger.info(
f"USER {event.user_id} GROUP {event.group_id} 解析bilibili转发 {url}"
)
def resize(path: str):
A = CreateImg(0, 0, background=path, ratio=0.5)
A.save(path)

View File

@ -81,7 +81,6 @@ async def _(matcher: Matcher, bot: Bot, event: Event, state: T_State):
user_id=event.user_id, message=f"P站排行榜或搜图正在搜索噢不要重复触发命令呀"
)
raise IgnoredException("pixiv插件正在访问")
_ulmt.set_True(event.user_id)
@run_postprocessor
@ -106,6 +105,7 @@ pixiv_keyword = on_command("搜图", priority=5, block=True)
@pixiv_rank.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = get_message_text(event.json()).strip()
_ulmt.set_True(event.user_id)
msg = msg.split(" ")
msg = [m for m in msg if m]
if not msg:
@ -150,6 +150,7 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
@pixiv_keyword.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = get_message_text(event.json()).strip()
_ulmt.set_True(event.user_id)
if event.message_type == "group":
if msg.find("r18") != -1:
await pixiv_keyword.finish("(脸红#) 你不会害羞的 八嘎!", at_sender=True)

View File

@ -2,11 +2,11 @@ from nonebot import on_command
from nonebot.adapters.cqhttp.permission import PRIVATE
from .data_source import from_reimu_get_info
from services.log import logger
from nonebot.adapters.cqhttp import Bot, Event, PrivateMessageEvent
from nonebot.adapters.cqhttp import Bot, PrivateMessageEvent
from nonebot.typing import T_State
from utils.utils import is_number, get_message_text, UserExistLimiter, scheduler
from models.count_user import UserCount
from configs.config import COUNT_PER_DAY_REIMU
from configs.config import COUNT_PER_DAY_REIMU, NICKNAME
__plugin_name__ = "上车"
__plugin_usage__ = r"""
@ -63,7 +63,7 @@ async def _(bot: Bot, event: PrivateMessageEvent, state: T_State):
keyword = state["keyword"]
page = state["page"]
await UserCount.add_count(event.user_id, "reimu")
await reimu.send("已经帮你关好车门了,请等待发车(不加真寻好友的话是欣赏不到旅途的风景的)", at_sender=True)
await reimu.send(f"已经帮你关好车门了,请等待发车(不加{NICKNAME}好友的话是欣赏不到旅途的风景的)", at_sender=True)
reimu_report = await from_reimu_get_info(keyword, page)
if reimu_report:
await reimu.send(reimu_report)

View File

@ -5,6 +5,7 @@ from models.group_remind import GroupRemind
from models.group_info import GroupInfo
from models.friend_user import FriendUser
from nonebot.adapters.cqhttp.exception import ActionFailed
from configs.config import NICKNAME
__name__ = "早晚安 [Hidden]"
@ -56,7 +57,7 @@ async def _():
result = image("sleep.jpg", "zhenxun")
try:
await bot.send_group_msg(
group_id=g, message="小真寻要睡觉了,你们也要早点睡呀" + result
group_id=g, message=f"{NICKNAME}要睡觉了,你们也要早点睡呀" + result
)
except ActionFailed:
logger.warning(f"{g} 群被禁言中,无法发送晚安")

View File

@ -3,6 +3,7 @@ from nonebot.typing import T_State
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent
from utils.utils import get_message_text
from services.log import logger
from configs.config import NICKNAME
import random
import asyncio
@ -36,7 +37,7 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
await roll.send(
random.choice(
[
f"真寻看看是什么结果!答案是:‘{x}",
f"{NICKNAME}看看是什么结果!答案是:‘{x}",
f"根据命运的指引,接下来{user_name} {x} 会比较好",
f"祈愿被回应了!是 {x}",
f"结束了,{user_name},命运之轮停在了 {x}",

View File

@ -11,7 +11,7 @@ from models.bag_user import BagUser
from services.log import logger
import time
from .data_source import rank
from configs.config import MAX_RUSSIAN_BET_GOLD
from configs.config import MAX_RUSSIAN_BET_GOLD, NICKNAME
__plugin_name__ = '俄罗斯轮盘'
@ -248,7 +248,7 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
if event.user_id != rs_player[event.group_id][1] and event.user_id != rs_player[event.group_id][2]:
await shot.finish(random.choice([
f'不要打扰 {player1_name}{player2_name} 的决斗啊!',
'给我好好做好一个观众!不然小真寻就要生气了',
f'给我好好做好一个观众!不然{NICKNAME}就要生气了',
f'不要捣乱啊baka{(await GroupInfoUser.get_member_info(event.user_id, event.group_id)).user_name}'
]), at_sender=True)
await shot.finish(f'你的左轮不是连发的!该 '
@ -322,7 +322,7 @@ async def end_game(bot: Bot, event: GroupMessageEvent):
f'\t累计败场:{lose_user.fail_count}\n'
f'\t累计输掉金币:{lose_user.lose_money}\n'
f'-------------------\n'
f'哼哼,真寻从中收取了 {float(rand)}%({fee}金币) 作为手续费!\n'
f'哼哼,{NICKNAME}从中收取了 {float(rand)}%({fee}金币) 作为手续费!\n'
f'子弹排列:{bullet_str[:-1]}')
rs_player[event.group_id] = {}

View File

@ -1,4 +1,5 @@
from lxml import etree
from lxml import etree
import feedparser
from urllib import parse
from services.log import logger

View File

@ -6,6 +6,7 @@ from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent
from nonebot.rule import to_me
from nonebot.permission import SUPERUSER
from utils.utils import UserExistLimiter, get_message_text
from configs.config import NICKNAME
__plugin_name__ = "查询皮肤"
@ -50,7 +51,7 @@ async def arg_handle(bot: Bot, event: MessageEvent, state: T_State):
try:
result, status_code = await get_price(name)
except FileNotFoundError:
await search_skin.finish('请先对真寻"设置cookie"来设置cookie')
await search_skin.finish(F'请先对{NICKNAME}"设置cookie"来设置cookie')
if status_code in [996, 997, 998]:
_ulmt.set_False(event.user_id)
await search_skin.finish(result)

View File

@ -27,7 +27,6 @@ __plugin_usage__ = (
_flmt = FreqLimiter(1)
IMAGE_DIR_LIST.remove("色图")
cmd = set(IMAGE_DIR_LIST)
# print(cmd)

View File

@ -34,7 +34,7 @@ from .data_source import (
add_data_to_database,
)
from nonebot.adapters.cqhttp.exception import ActionFailed
from configs.config import ONLY_USE_LOCAL_SETU, WITHDRAW_SETU_TIME
from configs.config import ONLY_USE_LOCAL_SETU, WITHDRAW_SETU_TIME, NICKNAME
from utils.message_builder import at
import re
import asyncio
@ -60,7 +60,10 @@ __plugin_usage__ = f"""示例:
如果图片数量与数字不符
原因1网络不好网线被拔QAQ
原因2搜索到的总数小于数字
原因3图太色或者小错误了"""
原因3图太色或者小错误了
示例
色图 萝莉|少女 白丝|黑丝
色图 萝莉 猫娘"""
_flmt = FreqLimiter(5)
_ulmt = UserExistLimiter()
@ -83,7 +86,6 @@ async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
user_id=event.user_id, message=f"您有色图正在处理,请稍等....."
)
raise IgnoredException("色图正在处理!")
_ulmt.set_True(event.user_id)
@run_postprocessor
@ -118,7 +120,7 @@ setu = on_command(
"色图", aliases={"涩图", "不够色", "来一发", "再来点", "色图r"}, priority=5, block=True
)
setu_reg = on_regex("(.*)[份|发|张|个|次|点](.*)[瑟|色|涩]图", priority=5, block=True)
setu_reg = on_regex("(.*)[份|发|张|个|次|点](.*)[瑟|色|涩]图$", priority=5, block=True)
find_setu = on_command("查色图", priority=5, block=True)
@ -134,6 +136,7 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
luox = get_luoxiang(impression)
if luox:
await setu.finish(luox)
_ulmt.set_True(event.user_id)
if not _flmt.check(event.user_id):
await setu.finish("您冲得太快了,请稍候再冲", at_sender=True)
_flmt.start_cd(event.user_id)
@ -253,7 +256,7 @@ async def send_setu_handle(
# 非 id在线搜索
tags = msg.split()
# 真寻的色图?怎么可能
if "真寻" in tags:
if f"{NICKNAME}" in tags:
await matcher.finish("咳咳咳,虽然我很可爱,但是我木有自己的色图~~~有的话记得发我一份呀")
# 本地先拿图,下载失败补上去
setu_list, code = await get_setu_list(tags=msg.split(), r18=r18)
@ -301,6 +304,8 @@ async def send_setu_handle(
return
# 本地无图 或 超过上下限
if code != 200 or (not setu_list and ONLY_USE_LOCAL_SETU):
if code == 999:
await matcher.finish('网络连接失败...', at_sender=True)
await matcher.finish(setu_list[0], at_sender=True)
elif not setu_list:
await matcher.finish(error_info, at_sender=True)

View File

@ -7,6 +7,7 @@ from asyncpg.exceptions import UniqueViolationError
from utils.utils import get_local_proxy
from asyncio.exceptions import TimeoutError
from typing import List, Optional
from configs.config import INITIAL_SETU_PROBABILITY, NICKNAME
from models.setu import Setu
import aiohttp
import aiofiles
@ -29,12 +30,12 @@ r18_path = "_r18/"
async def get_setu_urls(
tags: List[str], num: int = 1, r18: int = 0, command: str = ""
) -> "List[str], List[str], List[tuple], int":
tags = tags[:20] if len(tags) > 20 else tags
tags = tags[:3] if len(tags) > 3 else tags
params = {
"r18": r18, # 添加r18参数 0为否1为是2为混合
"tag": "|".join(tags), # 若指定tag
"num": 100, # 一次返回的结果数量范围为1到10不提供 APIKEY 时固定为1
"size": ["original"], # 是否使用 master_1200 缩略图,以节省流量或提升加载速度
"tag": tags, # 若指定tag
"num": 100, # 一次返回的结果数量
"size": ["original"],
}
async with aiohttp.ClientSession() as session:
for count in range(3):
@ -105,8 +106,7 @@ async def search_online_setu(
> 1024 * 1024 * 1.5
):
compressed_image(
os.path.join(path_, f"{index}.jpg"),
os.path.join(path_, f"{index}.jpg"),
f"{IMAGE_PATH}/{path_}/{index}.jpg",
)
logger.info(f"下载 lolicon图片 {url_} 成功, id{index}")
return image(file, path_), index
@ -188,12 +188,12 @@ def gen_message(setu_image: Setu, img_msg: bool = False):
# 罗翔老师!
def get_luoxiang(impression):
probability = impression + 70
probability = impression + INITIAL_SETU_PROBABILITY * 100
if probability < random.randint(1, 101):
return (
"我为什么要给你发这个?"
+ image(random.choice(os.listdir(IMAGE_PATH + "luoxiang/")), "luoxiang")
+ "\n(快向小真寻签到提升好感度吧!)"
+ f"\n(快向{NICKNAME}签到提升好感度吧!)"
)
return None

View File

@ -22,6 +22,7 @@ from services.log import logger
from nonebot.permission import SUPERUSER
from nonebot.rule import to_me
from datetime import datetime, timedelta
from configs.config import NICKNAME
import random
import time
@ -278,7 +279,7 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
gl = await bot.get_group_list(self_id=int(bot.self_id))
gl = [g["group_id"] for g in gl]
for g in gl:
init_redbag(int(bot.self_id), g, "可爱的小真寻", amount, num, int(bot.self_id), 1)
init_redbag(int(bot.self_id), g, f"{NICKNAME}", amount, num, int(bot.self_id), 1)
scheduler.add_job(
end_festive_redbag,
"date",
@ -289,7 +290,7 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
try:
await bot.send_group_msg(
group_id=g,
message=f"可爱的小真寻发起了金币红包\n金额:{amount}\n数量:{num}\n"
message=f"{NICKNAME}发起了金币红包\n金额:{amount}\n数量:{num}\n"
+ image(
b64=await generate_send_redbag_pic(int(bot.self_id), greetings)
),
@ -380,7 +381,7 @@ async def get_redbag_img(user_id: int, group_id: int):
async def end_festive_redbag(bot: Bot, group_id: int):
global festive_redbag_data
message = (
f"真寻的节日红包过时了,一共开启了 "
f"{NICKNAME}的节日红包过时了,一共开启了 "
f"{festive_redbag_data[group_id]['num'] - len(festive_redbag_data[group_id]['redbag'])}"
f" 个红包,共 {festive_redbag_data[group_id]['open_amount']} 金币"
)

View File

@ -6,7 +6,7 @@ from services.db_context import db
from models.sigin_group_user import SignGroupUser
from models.group_member_info import GroupInfoUser
from models.bag_user import BagUser
from configs.config import MAX_SIGN_GOLD
from configs.config import MAX_SIGN_GOLD, NICKNAME
from utils.image_utils import CreateImg
import aiohttp
from asyncio.exceptions import TimeoutError
@ -219,6 +219,6 @@ async def _pst(users: list, impressions: list, groups: list):
width += 580
W = CreateImg(1740, 3700, color="#FFE4C4", font_size=130)
W.paste(A, (0, 260))
font_w, font_h = W.getsize("真寻的好感度总榜")
W.text((int((1740 - font_w) / 2), int((260 - font_h) / 2)), "真寻的好感度总榜")
font_w, font_h = W.getsize(f"{NICKNAME}的好感度总榜")
W.text((int((1740 - font_w) / 2), int((260 - font_h) / 2)), f"{NICKNAME}的好感度总榜")
return W.pic2bs4()

View File

@ -86,7 +86,7 @@ async def _(
state: T_State,
):
global _prefix_count_dict
if matcher.type == "message" and matcher.priority not in [1, 9]:
if matcher.type == "message" and matcher.priority not in [1, 9] and matcher.module not in ['update_info']:
model = matcher.module
day_index = _prefix_count_dict["day_index"]
# print(f'model --> {model}')

View File

@ -3,24 +3,21 @@ from nonebot.permission import SUPERUSER
from nonebot.typing import T_State
from nonebot.adapters import Bot, Event
from nonebot.rule import to_me
from utils.image_utils import CreateImg
from configs.path_config import IMAGE_PATH
from utils.message_builder import image
super_help = on_command(
"超级用户帮助", rule=to_me(), priority=1, permission=SUPERUSER, block=True
)
@super_help.handle()
async def _(bot: Bot, event: Event, state: T_State):
result = """超级用户帮助:
result = """超级用户帮助:
*可多个类型参数 可省略参数
1.添加/删除管理 [at] [level]
2.查看群组/查看好友
3.广播 --> 指令:广播- [msg]
3.广播- [msg]
4.更新色图
5.回复 --> 指令:/t命令帮助
6.更新/设置cookie --> 指令:更新/设置cookie [cookie]
7.开启广播通知 --> 指令:开启广播通知 [群号]
8.退群 --> 指令:退群 [群号]
5./t命令帮助
6.更新/设置cookie [cookie]
7.开启/关闭广播通知 [群号]
8.退群 [群号]
9.自检
10.更新价格/更加图片 [武器箱]
11.更新好友信息
@ -29,16 +26,31 @@ async def _(bot: Bot, event: Event, state: T_State):
14.添加商品 [名称]-[价格]-[描述]-[折扣]-[限时时间]
15.删除商品 [名称(序号)]
16.修改商品 -name [名称(序号)] -price [价格] -des [描述] -discount [折扣] -time [限时]
17.节日红包 [金额] [数量] [祝福语](可省) *[指定群](可省)
17.节日红包 [金额] [数量] [祝福语](可省) *?[指定群
18.更新原神今日素材
19.更新原神资源信息
20.添加pix关键词/uid/pid *[关键词/uid/pid] [-f](强制通过不检测)
20.添加pix关键词/uid/pid *[关键词/uid/pid] ?[-f](强制通过不检测)
21.通过/取消pix关键词 [keyword/pid:pid/uid:uid]
22.删除pix关键词 [keyword/uid/pid:pid]
23.更新pix关键词 [keyword/pid:pid/uid:uid] [num]
24.删除pix图片 *[pid] [-b](同时加入黑名单)?
24.删除pix图片 *[pid] ?[-b](同时加入黑名单)
25.查看pix图库 [keyword]
26.pix检测更新 [update]
27.检查更新真寻
28.真寻重启"""
await super_help.finish(result, at_sender=True)
28.真寻重启
29.添加/删除群白名单 *[群号]
30.关闭[功能] ?[群号](有群号时禁用指定群)"""
height = len(result.split('\n')) * 24
A = CreateImg(1000, height, font_size=20)
A.text((10, 10), result)
A.save(f'{IMAGE_PATH}/super_help.png')
super_help = on_command(
"超级用户帮助", rule=to_me(), priority=1, permission=SUPERUSER, block=True
)
@super_help.handle()
async def _(bot: Bot, event: Event, state: T_State):
await super_help.finish(image('super_help.png'), at_sender=True)

View File

@ -8,7 +8,7 @@ __plugin_name__ = '更新信息'
__plugin_usage__ = ''
update_info = on_command("更新信息", priority=5, block=True)
update_info = on_command("更新信息", aliases={'更新日志'}, priority=5, block=True)
@update_info.handle()

View File

@ -11,33 +11,34 @@ import aiofiles
import aiohttp
from utils.utils import is_number, get_message_text
from utils.image_utils import CreateImg, pic2b64
from configs.config import NICKNAME
import cv2
import numpy as np
__plugin_name__ = "图片"
__plugin_usage__ = """图片用法(目前):
__plugin_usage__ = f"""图片用法(目前):
可以输入 指定操作 序号 来进行选择
1.修改尺寸 (x) (y) 图片(在文字后跟图片即可)
示例小真寻修改图片 修改尺寸 200 300 图片(在文字后跟图片即可)
示例{NICKNAME}修改图片 修改尺寸 200 300 图片(在文字后跟图片即可)
2.等比压缩 比例(x) 图片(在文字后跟图片即可)
示例小真寻修改图片 等比压缩 2 图片(在文字后跟图片即可)
示例{NICKNAME}修改图片 等比压缩 2 图片(在文字后跟图片即可)
3.旋转图片 角度(x) 图片(在文字后跟图片即可)
示例小真寻修改图片 旋转图片 45 图片(在文字后跟图片即可)
示例{NICKNAME}修改图片 旋转图片 45 图片(在文字后跟图片即可)
4.水平翻转
示例小真寻修改图片 水平翻转 图片
示例{NICKNAME}修改图片 水平翻转 图片
5.铅笔滤镜
示例小真寻修改图片 铅笔滤镜 图片
示例{NICKNAME}修改图片 铅笔滤镜 图片
6.模糊效果
示例小真寻修改图片 模糊效果 图片
示例{NICKNAME}修改图片 模糊效果 图片
7.锐化效果
示例小真寻修改图片 锐化效果 图片
示例{NICKNAME}修改图片 锐化效果 图片
8.高斯模糊
示例小真寻修改图片 高斯模糊 图片
示例{NICKNAME}修改图片 高斯模糊 图片
9.边缘检测
示例小真寻修改图片 边缘检测 图片
示例{NICKNAME}修改图片 边缘检测 图片
10.底色替换 颜色 颜色 图片 不专业支持->绿
示例小真寻修改图片 底色替换 蓝色 红色 图片"""
示例{NICKNAME}修改图片 底色替换 蓝色 红色 图片"""
# IMAGE_LOCAL = IMAGE_PATH + "temp/{}_update.png"
method_flag = ""
@ -219,7 +220,7 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
img = img.resize((int(x * width), int(x * height)))
result += image(b64=pic2b64(img))
else:
await update_img.finish("小真寻不支持图片压缩后宽或高大于8000的存在")
await update_img.finish(f"{NICKNAME}不支持图片压缩后宽或高大于8000的存在")
if method in ["旋转图片", "3"]:
for i in range(index):
img = Image.open(IMAGE_PATH + f"temp/{event.user_id}_{i}_update.png")

View File

@ -93,8 +93,10 @@ async def update_setu_img():
for image in image_list:
count += 1
path = _path / "_r18" if image.is_r18 else _path / "_setu"
rar_path = "r18_rar" if image.is_r18 else "rar"
rar_path = _path / "r18_rar" if image.is_r18 else _path / "rar"
local_image = path / f"{image.local_id}.jpg"
path.mkdir(exist_ok=True, parents=True)
rar_path.mkdir(exist_ok=True, parents=True)
if not local_image.exists() or not image.img_hash:
for _ in range(3):
try:
@ -103,7 +105,7 @@ async def update_setu_img():
) as response:
if response.status == 200:
async with aiofiles.open(
f"{IMAGE_PATH}/{rar_path}/{image.local_id}.jpg",
rar_path / f'{image.local_id}.jpg',
"wb",
) as f:
await f.write(await response.read())
@ -111,28 +113,25 @@ async def update_setu_img():
try:
if (
os.path.getsize(
f"{IMAGE_PATH}/{rar_path}/{image.local_id}.jpg"
rar_path / f'{image.local_id}.jpg',
)
> 1024 * 1024 * 1.5
):
compressed_image(
os.path.join(
rar_path, f"{image.local_id}.jpg"
),
os.path.join(path, f"{image.local_id}.jpg"),
rar_path / f"{image.local_id}.jpg",
path / f"{image.local_id}.jpg"
)
else:
logger.info(
f"不需要压缩,移动图片 {IMAGE_PATH}/{rar_path}/{image.local_id}.jpg "
f"不需要压缩,移动图片{rar_path}/{image.local_id}.jpg "
f"--> /{path}/{image.local_id}.jpg"
)
os.rename(
f"{IMAGE_PATH}/{rar_path}/{image.local_id}.jpg",
f"{rar_path}/{image.local_id}.jpg",
f"{path}/{image.local_id}.jpg",
)
except FileNotFoundError:
logger.warning(f"文件 {image.local_id}.jpg 不存在,跳过...")
_success -= 1
continue
img_hash = str(
get_img_hash(
@ -146,7 +145,6 @@ async def update_setu_img():
except (TimeoutError, ClientConnectorError) as e:
logger.warning(f"{image.local_id}.jpg 更新失败 ..{type(e)}{e}")
except Exception as e:
_success -= 1
logger.error(f"更新色图 {image.local_id}.jpg 错误 {type(e)}: {e}")
if type(e) not in error_type:
error_type.append(type(e))

View File

@ -1,15 +1,9 @@
from nonebot import on_command
from configs.path_config import IMAGE_PATH
from services.log import logger
import os
from nonebot.rule import to_me
from nonebot.typing import T_State
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent
from utils.utils import get_message_imgs, get_message_text
import aiohttp
import aiofiles
from utils.utils import cn2py
from configs.config import IMAGE_DIR_LIST
from .data_source import upload_image_to_local
__plugin_name__ = "上传图片"
__plugin_usage__ = (
@ -18,22 +12,24 @@ __plugin_usage__ = (
"2.上传图片 [序号] [图片], 即在相应目录下添加图片\n\t\t示例: 上传图片 1 [图片]"
)
upload_img = on_command("上传图片", rule=to_me(), priority=5, block=True)
continuous_upload_img = on_command('连续上传图片', rule=to_me(), priority=5, block=True)
@upload_img.args_parser
async def parse(bot: Bot, event: MessageEvent, state: T_State):
if str(event.get_message()) in ["取消", "算了"]:
async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = get_message_text(event.json())
if msg in ["取消", "算了"]:
await upload_img.finish("已取消操作..", at_sender=True)
if state["_current_key"] in ["path"]:
if str(event.get_message()) not in IMAGE_DIR_LIST:
if msg not in IMAGE_DIR_LIST:
await upload_img.reject("此目录不正确,请重新输入目录!")
state[state["_current_key"]] = str(event.get_message())
state['path'] = msg
if state["_current_key"] in ["imgs"]:
if not get_message_imgs(event.json()):
await upload_img.reject("图呢图呢图呢图呢GKD")
state[state["_current_key"]] = get_message_imgs(event.json())
state['imgs'] = get_message_imgs(event.json())
@upload_img.handle()
@ -41,59 +37,65 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
raw_arg = get_message_text(event.json())
img_list = get_message_imgs(event.json())
if raw_arg:
if str(event.get_message()) in ["帮助"]:
await upload_img.finish(__plugin_usage__)
if raw_arg.split("[")[0] in IMAGE_DIR_LIST:
state["path"] = raw_arg.split("[")[0]
if raw_arg in IMAGE_DIR_LIST:
state["path"] = raw_arg
if img_list:
state["imgs"] = img_list
@upload_img.got("path", prompt="要将图片上传至什么图库呢?")
@upload_img.got('path', prompt='要将图片上传至什么图库呢?')
async def _(bot: Bot, event: MessageEvent, state: T_State):
pass
@upload_img.got("imgs", prompt="图呢图呢图呢图呢GKD")
async def _(bot: Bot, event: MessageEvent, state: T_State):
path = IMAGE_PATH + cn2py(state["path"]) + '/'
img_list = state["imgs"]
img_id = len(os.listdir(path))
failed_list = []
success_id = ""
async with aiohttp.ClientSession() as session:
for img_url in img_list:
try:
async with session.get(img_url, timeout=7) as response:
if response.status == 200:
async with aiofiles.open(
path + str(img_id) + ".jpg", "wb"
) as f:
await f.write(await response.read())
success_id += str(img_id) + ""
img_id += 1
else:
failed_list.append(img_url)
logger.warning(f"图片:{img_url} 下载失败....")
except TimeoutError as e:
logger.warning(f"图片:{img_url} 下载超时....e:{e}")
if img_url not in failed_list:
failed_list.append(img_url)
failed_result = ""
for img in failed_list:
failed_result += str(img) + "\n"
logger.info(
f"USER {event.user_id} GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'}"
f" 上传图片至 {state['path']}{len(img_list)} 张,失败 {len(failed_list)}id={success_id[:-1]}"
)
if failed_result:
await upload_img.finish(
f"这次一共为 {state['path']}库 添加了 {len(img_list) - len(failed_list)} 张图片\n"
f"依次的Id为{success_id[:-1]}\n"
f"上传失败:{failed_result[:-1]}\n"
f"小真寻感谢您对图库的扩充!WW",
at_sender=True,
)
path = state['path']
img_list = state['imgs']
group_id = 0
if isinstance(event, GroupMessageEvent):
group_id = event.group_id
await upload_img.send(await upload_image_to_local(img_list, path, event.user_id, group_id))
@continuous_upload_img.args_parser
async def _(bot: Bot, event: MessageEvent, state: T_State):
if str(event.get_message()) in ["取消", "算了"]:
await continuous_upload_img.finish("已取消操作..", at_sender=True)
if state["_current_key"] in ["path"]:
if str(event.get_message()) not in IMAGE_DIR_LIST:
await continuous_upload_img.reject("此目录不正确,请重新输入目录!")
state[state["_current_key"]] = str(event.get_message())
else:
await upload_img.finish(
f"这次一共为 {state['path']}库 添加了 {len(img_list)} 张图片\n"
f"依次的Id为{success_id[:-1]}\n"
f"小真寻感谢您对图库的扩充!WW",
at_sender=True,
)
if get_message_text(event.json()) not in ['stop']:
img = get_message_imgs(event.json())
if img:
state['tmp'].extend(img)
await continuous_upload_img.reject('图再来!!')
else:
state['imgs'] = state['tmp']
@continuous_upload_img.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
path = get_message_imgs(event.json())
if path in IMAGE_DIR_LIST:
state['path'] = path
await continuous_upload_img.send('图来!!')
state['tmp'] = []
@continuous_upload_img.got("path", prompt="要将图片上传至什么图库呢?")
async def _(bot: Bot, event: MessageEvent, state: T_State):
pass
@continuous_upload_img.got("imgs", prompt="图呢图呢图呢图呢GKD")
async def _(bot: Bot, event: MessageEvent, state: T_State):
path = state['path']
img_list = state['imgs']
group_id = 0
if isinstance(event, GroupMessageEvent):
group_id = event.group_id
await continuous_upload_img.send(await upload_image_to_local(img_list, path, event.user_id, group_id))

View File

@ -0,0 +1,51 @@
from configs.config import NICKNAME
from typing import List
from configs.path_config import IMAGE_PATH
from services.log import logger
from utils.utils import cn2py
from pathlib import Path
import aiofiles
import aiohttp
import os
async def upload_image_to_local(
img_list: List[str], path: str, user_id: int, group_id: int = 0
) -> str:
_path = path
path = Path(IMAGE_PATH) / cn2py(path)
path.mkdir(parents=True, exist_ok=True)
img_id = len(os.listdir(path))
failed_list = []
success_id = ""
async with aiohttp.ClientSession() as session:
for img_url in img_list:
try:
async with session.get(img_url, timeout=7) as response:
if response.status == 200:
async with aiofiles.open(path / f"{img_id}.jpg", "wb") as f:
await f.write(await response.read())
success_id += str(img_id) + ""
img_id += 1
else:
failed_list.append(img_url)
logger.warning(f"图片:{img_url} 下载失败....")
except TimeoutError as e:
logger.warning(f"图片:{img_url} 下载超时....e:{e}")
if img_url not in failed_list:
failed_list.append(img_url)
failed_result = ""
for img in failed_list:
failed_result += str(img) + "\n"
logger.info(
f"USER {user_id} GROUP {group_id}"
f" 上传图片至 {_path}{len(img_list)} 张,失败 {len(failed_list)}id={success_id[:-1]}"
)
if failed_list:
return (
f"这次一共为 {_path}库 添加了 {len(img_list) - len(failed_list)} 张图片\n"
f"依次的Id为{success_id[:-1]}\n上传失败:{failed_result[:-1]}\n{NICKNAME}感谢您对图库的扩充!WW"
)
else:
return f"这次一共为 {_path}库 添加了 {len(img_list)} 张图片\n依次的Id为" \
f"{success_id[:-1]}\n{NICKNAME}感谢您对图库的扩充!WW"

View File

@ -17,8 +17,11 @@ weather = on_regex(r".*?(.*)市?的?天气.*?", priority=5, block=True)
@weather.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = get_message_text(event.json())
msg = re.search(r".*?(.*)市?的?天气.*?", msg)
msg = msg.group(1)
msg1 = re.search(r".*?(.*)市?的?天气.*?", msg)
msg2 = re.search(r".*?天气(.*).*?", msg)
msg1 = msg1.group(1)
msg2 = msg2.group(1)
msg = msg1 if msg1 else msg2
if msg[-1] == "":
msg = msg[:-1]
if msg[-1] != "":

View File

@ -2,6 +2,7 @@ from services.log import logger
from utils.message_builder import image
from utils.user_agent import get_user_agent
from configs.path_config import TXT_PATH
from configs.config import NICKNAME
from asyncio.exceptions import TimeoutError
from typing import List
from nonebot import Driver
@ -26,7 +27,7 @@ async def get_weather_of_city(city: str) -> str:
if code == 999:
return "不要查一个省份的天气啊,很累人的!"
elif code == 998:
return "真寻只可以查询国内的天气喔..."
return f"{NICKNAME}只可以查询国内城市的天气喔..."
else:
async with aiohttp.ClientSession(headers=get_user_agent()) as session:
async with session.get(
@ -35,7 +36,7 @@ async def get_weather_of_city(city: str) -> str:
data_json = json.loads(await res.text(encoding="utf8"))
if "desc" in data_json:
if data_json["desc"] == "invilad-citykey":
return "你为啥不查火星的天气呢?小真寻只支持国内天气查询!!" + image(
return f"你为啥不查火星的天气呢?{NICKNAME}只支持国内天气查询!!" + image(
"shengqi", "zhenxun"
)
elif data_json["desc"] == "OK":

View File

@ -1,5 +1,6 @@
from utils.user_agent import get_user_agent
from configs.path_config import TXT_PATH
from configs.config import NICKNAME
from typing import List
from pathlib import Path
import ujson as json
@ -37,7 +38,7 @@ async def get_yiqing_data(area: str):
province = p
city = area
if not province and not city:
return "小真寻只支持国内的疫情查询喔..."
return f"{NICKNAME}只支持国内的疫情查询喔..."
async with aiohttp.ClientSession(headers=get_user_agent()) as session:
async with session.get(url, timeout=7) as response:
epidemic_data = json.loads((await response.json())["data"])

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

View File

@ -1,21 +1,49 @@
{
"update_file": [
".env.dev",
"configs/config.py",
"configs/path_config.py",
"plugins/aconfig",
"plugins/admin_bot_manage",
"plugins/admin_help",
"plugins/ai",
"plugins/alapi",
"plugins/auto_invite",
"plugins/ban",
"plugins/check_zhenxun_update",
"plugins/genshin/material_remind",
"plugins/delete_img",
"plugins/fudu.py",
"plugins/genshin/query_resource_points",
"plugins/group_handle",
"plugins/help",
"plugins/hook.py",
"plugins/jitang.py",
"plugins/move_img",
"plugins/mute.py",
"plugins/nickname.py",
"plugins/one_friend",
"plugins/open_cases",
"plugins/parse_bilibili_json.py",
"plugins/pixiv",
"plugins/reimu",
"plugins/remind",
"plugins/roll.py",
"plugins/russian",
"plugins/search_anime",
"plugins/search_buff_skin_price",
"plugins/send_img",
"plugins/send_setu",
"plugins/shop/gold_redbag",
"plugins/sign_in/group_user_checkin.py",
"plugins/statistics_hook.py",
"plugins/super_help",
"plugins/update_info.py",
"plugins/update_setu",
"plugins/upload_img",
"plugins/weather",
"plugins/yiqing",
"bot.py",
"plugins/admin_bot_manage/update_group_member_info.py",
"plugins/send_img"
"utils/image_utils.py"
],
"add_file": ["plugins/nbnhhsh.py", "plugins/roll.py"],
"delete_file": [" plugins/admin_bot_manage/__init__.py"]
"add_file": ["plugins/group_manager", "resources/img/other/webtop.png", "utils/static_data"],
"delete_file": ["plugins/group_level", "plugins/nonebot_plugin_manager"]
}

View File

@ -13,14 +13,14 @@ _browser: Optional[Browser] = None
async def init(**kwargs) -> Optional[Browser]:
try:
global _browser
browser = await async_playwright().start()
_browser = await browser.chromium.launch(**kwargs)
return _browser
except NotImplementedError:
logger.warning("win环境下 初始化playwright失败....请替换环境至linux")
return None
# try:
global _browser
browser = await async_playwright().start()
_browser = await browser.chromium.launch(**kwargs)
return _browser
# except NotImplementedError:
# logger.warning("win环境下 初始化playwright失败....请替换环境至linux")
# return None
async def get_browser(**kwargs) -> Browser:

View File

@ -3,7 +3,7 @@ from PIL import Image, ImageFile, ImageDraw, ImageFont
from imagehash import ImageHash
from io import BytesIO
from matplotlib import pyplot as plt
from typing import Tuple, Optional
from typing import Tuple, Optional, Union
from pathlib import Path
import cv2
import base64
@ -45,7 +45,7 @@ def get_img_hash(image_file: str) -> ImageHash:
return hash_value
def compressed_image(in_file: str, out_file: str = None, ratio: float = 0.9):
def compressed_image(in_file: Union[str, Path], out_file: Union[str, Path] = None, ratio: float = 0.9):
"""
说明
压缩图片
@ -54,8 +54,11 @@ def compressed_image(in_file: str, out_file: str = None, ratio: float = 0.9):
:param out_file: 压缩后输出的文件路径
:param ratio: 压缩率宽高 * 压缩率
"""
in_file = Path(IMAGE_PATH) / in_file
out_file = Path(IMAGE_PATH) / out_file if out_file else in_file
in_file = Path(IMAGE_PATH) / in_file if isinstance(in_file, str) else in_file
if out_file:
out_file = Path(IMAGE_PATH) / out_file if isinstance(out_file, str) else out_file
else:
out_file = in_file
h, w, d = cv2.imread(str(in_file.absolute())).shape
img = cv2.resize(cv2.imread(str(in_file.absolute())), (int(w * ratio), int(h * ratio)))
cv2.imwrite(str(out_file.absolute()), img)

View File

@ -0,0 +1,11 @@
from typing import Optional
from .group_manager import GroupManager
from pathlib import Path
from .data_source import init
# 群权限
group_manager: Optional[GroupManager] = GroupManager(
Path() / "data" / "manager" / "group_manager.json"
)
init(group_manager)

View File

@ -0,0 +1,51 @@
from typing import Union
from pathlib import Path
import ujson as json
class StaticData:
"""
静态数据共享类
"""
def __init__(self, file: Path):
file.parent.mkdir(exist_ok=True, parents=True)
self.file = file
self.data = {}
if file.exists():
self.data: dict = json.load(open(file, "r", encoding="utf8"))
def set(self, key, value):
self.data[key] = value
def get(self, key):
return self.data.get(key)
def delete(self, key):
if self.data.get(key) is not None:
del self.data[key]
def save(self, path: Union[str, Path] = None):
path = path if path else self.file
with open(path, "w", encoding="utf8") as f:
json.dump(self.data, f, ensure_ascii=False, indent=4)
def reload(self):
if self.file.exists():
self.data: dict = json.load(open(self.file, "r", encoding="utf8"))
def is_exists(self):
return self.file.exists()
def is_empty(self):
return bool(len(self.data))
def __str__(self):
return str(self.data)
def __setitem__(self, key, value):
self.data[key] = value
def __getitem__(self, key):
return self.data[key]

View File

@ -0,0 +1,27 @@
from pathlib import Path
import ujson as json
from .group_manager import GroupManager
def init(group_manager: GroupManager):
old_group_level_file = Path() / "data" / "manager" / "group_level.json"
old_plugin_list_file = Path() / "data" / "manager" / "plugin_list.json"
if old_group_level_file.exists():
data = json.load(open(old_group_level_file, 'r', encoding='utf8'))
for key in data.keys():
group = key
level = data[key]
group_manager.set_group_level(group, level)
old_group_level_file.unlink()
group_manager.save()
if old_plugin_list_file.exists():
data = json.load(open(old_plugin_list_file, 'r', encoding='utf8'))
for plugin in data.keys():
for group in data[plugin].keys():
if group == 'default' and not data[plugin]['default']:
group_manager.block_plugin(plugin)
elif not data[plugin][group]:
group_manager.block_plugin(plugin, group)
old_plugin_list_file.unlink()
group_manager.save()

View File

@ -0,0 +1,186 @@
from typing import Optional
from pathlib import Path
from .data_class import StaticData
class GroupManager(StaticData):
"""
群权限 | 功能 | 聊天时间 管理器
"""
def __init__(self, file: Path):
super().__init__(file)
if not self.data:
self.data = {"super": {"close_plugins": {}, "white_group_list": []}, "group_manager": {}}
def block_plugin(
self, plugin_cmd: str, group_id: Optional[str] = None, block_type: str = "all"
):
"""
说明
锁定插件
参数
:param plugin_cmd: 功能模块名
:param group_id: 群组None时为超级用户禁用
:param block_type: 限制类型
"""
self._set_plugin_status(plugin_cmd, "block", group_id, block_type)
def unblock_plugin(self, plugin_cmd: str, group_id: Optional[str] = None):
"""
说明
解锁插件
参数
:param plugin_cmd: 功能模块名
:param group_id: 群组
"""
self._set_plugin_status(plugin_cmd, "unblock", group_id)
def set_group_level(self, group_id: str, level: int):
"""
说明
设置群权限
参数
:param group_id: 群组
:param level: 权限等级
"""
if not self.data["group_manager"].get(group_id):
self._init_group(group_id)
self.data["group_manager"][group_id]["level"] = level
self.save()
def get_plugin_status(
self, plugin_cmd: str, group_id: Optional[str] = None, block_type: str = "all"
) -> bool:
"""
说明
获取插件状态
参数
:param plugin_cmd: 功能模块名
:param group_id: 群组
:param block_type: 限制类型
"""
if group_id:
if not self.data["group_manager"].get(group_id):
self._init_group(group_id)
return True
if plugin_cmd in self.data["group_manager"][group_id]["close_plugins"]:
return False
return True
else:
if plugin_cmd in self.data["super"]["close_plugins"]:
if (
self.data["super"]["close_plugins"][plugin_cmd] == "all"
and block_type == "all"
):
return False
else:
return (
not self.data["super"]["close_plugins"][plugin_cmd]
== block_type
)
return True
def get_plugin_block_type(self, plugin_cmd: str) -> str:
"""
说明
获取功能限制类型
参数
:param plugin_cmd: 模块名称
"""
if plugin_cmd in self.data["super"]["close_plugins"]:
return self.data["super"]["close_plugins"][plugin_cmd]
return ""
def get_group_level(self, group_id: str) -> int:
"""
说明
获取群等级
参数
:param group_id: 群号
"""
if not self.data["group_manager"].get(group_id):
self._init_group(group_id)
return self.data["group_manager"][group_id]["level"]
def check_group_is_white(self, group_id: int) -> bool:
"""
说明
检测群聊是否在白名单
参数
:param group_id: 群号
"""
return group_id in self.data['super']['white_group_list']
def add_group_white_list(self, group_id: int):
"""
说明
将群聊加入白名单
参数
:param group_id: 群号
"""
if group_id not in self.data['super']['white_group_list']:
self.data['super']['white_group_list'].append(group_id)
def delete_group_white_list(self, group_id: int):
"""
说明
将群聊从白名单中删除
参数
:param group_id: 群号
"""
if group_id in self.data['super']['white_group_list']:
self.data['super']['white_group_list'].remove(group_id)
def _set_plugin_status(
self,
plugin_cmd: str,
status: str,
group_id: Optional[str],
block_type: str = "all",
):
"""
说明
设置功能开关状态
参数
:param plugin_cmd: 功能模块名
:param status: 功能状态
:param group_id: 群组
:param block_type: 限制类型
"""
if group_id:
if not self.data["group_manager"].get(group_id):
self._init_group(group_id)
if status == "block":
if (
plugin_cmd
not in self.data["group_manager"][group_id]["close_plugins"]
):
self.data["group_manager"][group_id]["close_plugins"].append(
plugin_cmd
)
else:
if plugin_cmd in self.data["group_manager"][group_id]["close_plugins"]:
self.data["group_manager"][group_id]["close_plugins"].remove(
plugin_cmd
)
else:
if status == "block":
if (
plugin_cmd not in self.data["super"]["close_plugins"]
or block_type != self.data["super"]["close_plugins"][plugin_cmd]
):
self.data["super"]["close_plugins"][plugin_cmd] = block_type
else:
if plugin_cmd in self.data["super"]["close_plugins"]:
del self.data["super"]["close_plugins"][plugin_cmd]
self.save()
def _init_group(self, group_id: str):
"""
说明
初始化群数据
参数
:param group_id: 群号
"""
self.data["group_manager"][group_id] = {"level": 5, "close_plugins": []}