update v0.0.5.0

This commit is contained in:
HibiKier 2021-10-03 14:24:07 +08:00
parent 87ed445a58
commit 00658cf165
182 changed files with 6439 additions and 3845 deletions

View File

@ -1 +1 @@
__version__: v0.0.4.7
__version__: v0.0.5.0

7
bot.py
View File

@ -2,19 +2,14 @@ import nonebot
from nonebot.adapters.cqhttp import Bot as CQHTTPBot
from services.db_context import init, disconnect
nonebot.init()
driver = nonebot.get_driver()
driver.register_adapter("cqhttp", CQHTTPBot)
config = driver.config
driver.on_startup(init)
driver.on_shutdown(disconnect)
nonebot.load_builtin_plugins()
nonebot.load_plugins("plugins")
nonebot.load_plugins("plugins/shop")
nonebot.load_plugins("plugins/genshin")
nonebot.load_plugins("plugins/alapi")
nonebot.load_plugins("plugins/pix_gallery")
nonebot.load_plugins("plugins/admin_bot_manage")
if __name__ == "__main__":

View File

@ -1,20 +1,11 @@
from typing import List, Optional, Tuple
from services.service_config import TL_M_KEY, SYSTEM_M_PROXY, ALAPI_M_TOKEN
from .utils.init_config import init_config
from configs.path_config import DATA_PATH
try:
import ujson as json
except ModuleNotFoundError:
import json
# 是否使用配置文件
# 使用配置文件在每次启动时 plugins2info_dict, plugins2cd_dict, plugins2exists_dict 将从本地读取
# 除了 plugins2info_dict 新增内容键值会写入 plugins2info_file
# 其他修改或新增在 configs.config.py中对 plugins2info_dict, plugins2cd_dict, plugins2exists_dict 的配置无效
# 目录data/configs/
USE_CONFIG_FILE: bool = False
# 回复消息名称
NICKNAME: str = "小真寻"
@ -95,13 +86,13 @@ CHECK_NOTICE_INFO_CD = 300 # 群检测,个人权限检测等各种检测提
# 注:即在 MALICIOUS_CHECK_TIME 时间内触发相同命令 MALICIOUS_BAN_COUNT 将被ban MALICIOUS_BAN_TIME 分钟
MALICIOUS_BAN_TIME: int = 30 # 恶意命令触发检测触发后ban的时长分钟
MALICIOUS_BAN_COUNT: int = 3 # 恶意命令触发检测最大触发次数
MALICIOUS_BAN_COUNT: int = 6 # 恶意命令触发检测最大触发次数
MALICIOUS_CHECK_TIME: int = 5 # 恶意命令触发检测规定时间内(秒)
# LEVEL
DELETE_IMG_LEVEL: int = 7 # 删除图片权限
MOVE_IMG_LEVEL: int = 7 # 移动图片权限
UPLOAD_LEVEL: int = 6 # 上传图片权限
UPLOAD_IMG_LEVEL: int = 6 # 上传图片权限
BAN_LEVEL: int = 5 # BAN权限
OC_LEVEL: int = 2 # 开关群功能权限
MUTE_LEVEL: int = 5 # 更改禁言设置权限
@ -117,7 +108,7 @@ HIBIAPI_BOOKMARKS: int = 5000
# 需要为哪些群更新最新版gocq吗上传最新版gocq
# 示例:[434995955, 239483248]
UPDATE_GOCQ_GROUP: List[int] = []
UPDATE_GOCQ_GROUP: List[int] = [774261838]
# 是否存储色图
DOWNLOAD_SETU: bool = True
@ -132,173 +123,6 @@ IMPORT_DEFAULT_SHOP_GOODS: bool = True
# 真寻是否自动更新
AUTO_UPDATE_ZHENXUN: bool = True
# 群管理员功能 与 对应权限
admin_plugins_auth = {
"custom_welcome_message": OC_LEVEL,
"group_notification_state": OC_LEVEL,
"switch_rule": OC_LEVEL,
"update_group_member_info": OC_LEVEL,
"ban": BAN_LEVEL,
"delete_img": DELETE_IMG_LEVEL,
"move_img": MOVE_IMG_LEVEL,
"upload_img": UPLOAD_LEVEL,
"admin_help": 1,
"mute": MUTE_LEVEL,
"member_activity_handle": MEMBER_ACTIVITY_LEVEL,
}
# 需要cd的功能方便管理[秒]
# 自定义的功能需要cd也可以在此配置
# key模块名称
# cdcd 时长(秒)
# status此限制的开关状态
# check_type'private'/'group'/'all',限制私聊/群聊/全部
# limit_type监听对象以user_id或group_id作为键来限制'user'用户id'group'群id
# 示例:'user'用户N秒内触发1次'group'群N秒内触发1次
# rst回复的话可以添加[at][uname][nickname]来对应艾特,用户群名称,昵称系统昵称
# rst 为 "" 或 None 时则不回复
# rst示例"[uname]你冲的太快了,[nickname]先生,请稍后再冲[at]"
# rst回复"老色批你冲的太快了,欧尼酱先生,请稍后再冲@老色批"
# 用户昵称↑ 昵称系统的昵称↑ 艾特用户↑
plugins2cd_dict = {
"open_cases": {
"cd": 5,
"status": True,
"check_type": "all",
"limit_type": "user",
"rst": "着什么急啊,慢慢来!",
},
"send_setu": {
"cd": 5,
"status": True,
"check_type": "all",
"limit_type": "user",
"rst": "您冲得太快了,请稍候再冲",
},
"sign_in": {
"cd": 5,
"status": True,
"check_type": "group",
"limit_type": "user",
"rst": None,
}
}
# 用户调用阻塞(方便管理)
# 即 当用户调用此功能还未结束时
# 用发送消息阻止用户重复调用此命令直到该命令结束
# 参数同上 plugin2cd_dict
plugins2exists_dict = {
"send_setu": {
"status": True,
"check_type": "all",
"limit_type": "user",
"rst": "您有色图正在处理,请稍等.....",
},
"pixiv": {
"status": True,
"check_type": "all",
"limit_type": "user",
"rst": "P站排行榜或搜图正在搜索请不要重复触发命令...",
},
"pix": {
"status": True,
"check_type": "all",
"limit_type": "user",
"rst": "您有PIX图片正在处理请稍等...",
}
}
# 模块与对应命令和对应群权限
# 用于生成帮助图片 和 开关功能
# key模块名称
# level需要的群等级
# default_status加入群时功能的默认开关状态
# cmd关闭[cmd] 都会触发命令 关闭对应功能cmd列表第一个词为统计的功能名称
plugins2info_dict = {
"sign_in": {"level": 5, "default_status": True, "cmd": ["签到"]},
"send_img": {
"level": 5,
"default_status": True,
"cmd": ["发送图片", "发图", "萝莉", "美图", "壁纸"],
},
"send_setu": {"level": 9, "default_status": True, "cmd": ["色图", "涩图", "瑟图", "查色图"]},
"white2black": {"level": 5, "default_status": True, "cmd": ["黑白图", "黑白草图"]},
"coser": {"level": 9, "default_status": True, "cmd": ["coser", "cos"]},
"quotations": {"level": 5, "default_status": True, "cmd": ["语录"]},
"jitang": {"level": 5, "default_status": True, "cmd": ["鸡汤"]},
"send_dinggong_voice": {
"level": 5,
"default_status": True,
"cmd": ["骂我", "骂老子", "骂劳资"],
},
"open_cases": {
"level": 5,
"default_status": True,
"cmd": ["开箱", "我的开箱", "群开箱统计", "我的金色"],
},
"luxun": {"level": 5, "default_status": True, "cmd": ["鲁迅说", "鲁迅说过"]},
"fake_msg": {"level": 5, "default_status": True, "cmd": ["假消息"]},
"buy": {"level": 5, "default_status": True, "cmd": ["购买", "购买道具"]},
"my_gold": {"level": 5, "default_status": True, "cmd": ["我的金币"]},
"my_props": {"level": 5, "default_status": True, "cmd": ["我的道具"]},
"shop_handle": {"level": 5, "default_status": True, "cmd": ["商店"]},
"update_pic": {"level": 5, "default_status": True, "cmd": ["图片", "操作图片", "修改图片"]},
"search_buff_skin_price": {"level": 5, "default_status": True, "cmd": ["查询皮肤"]},
"weather": {"level": 5, "default_status": True, "cmd": ["天气", "查询天气", "天气查询"]},
"yiqing": {"level": 5, "default_status": True, "cmd": ["疫情", "疫情查询", "查询疫情"]},
"what_anime": {"level": 5, "default_status": True, "cmd": ["识番"]},
"search_anime": {"level": 5, "default_status": True, "cmd": ["搜番"]},
"songpicker2": {"level": 5, "default_status": True, "cmd": ["点歌"]},
"epic": {"level": 5, "default_status": True, "cmd": ["epic"]},
"pixiv": {"level": 9, "default_status": True, "cmd": ["pixiv", "p站排行", "搜图"]},
"poke": {"level": 5, "default_status": True, "cmd": ["戳一戳", "拍一拍"]},
"draw_card": {
"level": 5,
"default_status": True,
"cmd": [
"抽卡",
"游戏抽卡",
],
},
"ai": {"level": 5, "default_status": True, "cmd": ["ai", "Ai", "AI", "aI"]},
"one_friend": {"level": 5, "default_status": True, "cmd": ["我有一个朋友", "我有一个朋友想问问"]},
"translate": {
"level": 5,
"default_status": True,
"cmd": ["翻译", "英翻", "翻英", "日翻", "翻日", "韩翻", "翻韩"],
},
"nonebot_plugin_picsearcher": {"level": 5, "default_status": True, "cmd": ["识图"]},
"almanac": {"level": 5, "default_status": True, "cmd": ["原神黄历", "黄历"]},
"material_remind": {"level": 5, "default_status": True, "cmd": ["今日素材", "天赋材料"]},
"qiu_qiu_translation": {
"level": 5,
"default_status": True,
"cmd": ["丘丘翻译", "丘丘一下", "丘丘语翻译"],
},
"query_resource_points": {
"level": 5,
"default_status": True,
"cmd": ["原神资源查询", "原神资源列表"],
},
"russian": {"level": 5, "default_status": True, "cmd": ["俄罗斯轮盘", "俄罗斯转盘", "装弹"]},
"gold_redbag": {"level": 5, "default_status": True, "cmd": ["塞红包", "红包", "抢红包"]},
"poetry": {"level": 5, "default_status": True, "cmd": ["念诗", "来首诗", "念首诗"]},
"comments_163": {
"level": 5,
"default_status": True,
"cmd": ["到点了", "12点了", "网易云热评", "网易云评论"],
},
"cover": {"level": 5, "default_status": True, "cmd": ["b封面", "B封面"]},
"pid_search": {"level": 9, "default_status": True, "cmd": ["p搜", "P搜"]},
"pix": {
"level": 5,
"default_status": True,
"cmd": ["pix", "PIX", "pIX", "Pix", "PIx"],
},
"wbtop": {"level": 5, "default_status": True, "cmd": ["微博热搜", "微博", "wbtop"]},
"update_info": {"level": 5, "default_status": True, "cmd": ["更新信息", "更新日志"]},
}
if TL_M_KEY:
TL_KEY = TL_M_KEY
@ -312,9 +136,4 @@ HIBIAPI = HIBIAPI[:-1] if HIBIAPI[-1] == "/" else HIBIAPI
RSSHUBAPP = RSSHUBAPP[:-1] if RSSHUBAPP[-1] == "/" else RSSHUBAPP
if USE_CONFIG_FILE:
# 读取配置文件
plugins2info_dict, plugins2cd_dict, plugins2exists_dict = init_config(
plugins2info_dict, plugins2cd_dict, plugins2exists_dict, DATA_PATH
)

View File

@ -1,17 +1,15 @@
from .utils.util import get_config_data
from pathlib import Path
# from configs.config import USE_CONFIG_FILE
# 图片路径
IMAGE_PATH = Path("resources/img/")
# 音频路径
VOICE_PATH = Path("resources/voice/")
# 文本路径
TXT_PATH = Path("resources/txt/")
TEXT_PATH = Path("resources/txt/")
# 日志路径
LOG_PATH = Path("log/")
# 字体路径
TTF_PATH = Path("resources/ttf/")
FONT_PATH = Path("resources/ttf/")
# 数据路径
DATA_PATH = Path("data/")
# 临时图片路径
@ -19,38 +17,20 @@ 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'])
global IMAGE_PATH, VOICE_PATH, TEXT_PATH, LOG_PATH, FONT_PATH, DATA_PATH, 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)
TEXT_PATH.mkdir(parents=True, exist_ok=True)
LOG_PATH.mkdir(parents=True, exist_ok=True)
TTF_PATH.mkdir(parents=True, exist_ok=True)
FONT_PATH.mkdir(parents=True, exist_ok=True)
DATA_PATH.mkdir(parents=True, exist_ok=True)
TEMP_PATH.mkdir(parents=True, exist_ok=True)
IMAGE_PATH = str(IMAGE_PATH.absolute()) + '/'
VOICE_PATH = str(VOICE_PATH.absolute()) + '/'
TXT_PATH = str(TXT_PATH.absolute()) + '/'
TEXT_PATH = str(TEXT_PATH.absolute()) + '/'
LOG_PATH = str(LOG_PATH.absolute()) + '/'
TTF_PATH = str(TTF_PATH.absolute()) + '/'
FONT_PATH = str(FONT_PATH.absolute()) + '/'
DATA_PATH = str(DATA_PATH.absolute()) + '/'
TEMP_PATH = str(TEMP_PATH.absolute()) + '/'
@ -58,5 +38,4 @@ def init_path():
init_path()
if __name__ == '__main__':
print(IMAGE_PATH)

View File

@ -1,42 +0,0 @@
from pathlib import Path
try:
import ujson as json
except ModuleNotFoundError:
import json
def init_config(plugins2info_dict, plugins2cd_dict, plugins2exists_dict, DATA_PATH):
plugins2info_file = Path(DATA_PATH) / 'configs' / 'plugins2info.json'
plugins2info_file.parent.mkdir(exist_ok=True, parents=True)
if plugins2info_file.exists():
with open(plugins2info_file, 'r', encoding='utf8') as f:
_data = json.load(f)
for p in plugins2info_dict:
if not _data.get(p):
_data[p] = plugins2info_dict[p]
with open(plugins2info_file, 'w') as wf:
json.dump(_data, wf, ensure_ascii=False, indent=4)
plugins2info_dict = _data
else:
with open(plugins2info_file, 'w', encoding='utf8') as wf:
json.dump(plugins2info_dict, wf, ensure_ascii=False, indent=4)
plugins2cd_file = Path(DATA_PATH) / 'configs' / 'plugins2cd.json'
if plugins2cd_file.exists():
with open(plugins2cd_file, 'r', encoding='utf8') as f:
plugins2cd_dict = json.load(f)
else:
with open(plugins2cd_file, 'w', encoding='utf8') as wf:
json.dump(plugins2cd_dict, wf, ensure_ascii=False, indent=4)
plugins2exists_file = Path(DATA_PATH) / 'configs' / 'plugins2exists.json'
if plugins2exists_file.exists():
with open(plugins2exists_file, 'r', encoding='utf8') as f:
plugins2exists_dict = json.load(f)
else:
with open(plugins2exists_file, 'w', encoding='utf8') as wf:
json.dump(plugins2exists_dict, wf, ensure_ascii=False, indent=4)
return plugins2info_dict, plugins2cd_dict, plugins2exists_dict

View File

@ -1,35 +0,0 @@
from pathlib import Path
from configs.utils.init_config import init_config
try:
import ujson as json
except ModuleNotFoundError:
import json
data: dict = {}
def get_config_data():
global data
if not data:
try:
base_config = json.load(open(Path() / "config.json", 'r', encoding='utf8'))
plugins2cmd_config = json.load(open(Path() / 'configs' / 'plugins2cmd_config.json', 'r', encoding='utf8'))
other_config = json.load(open(Path() / 'configs' / 'other_config.json', 'r', encoding='utf8'))
for key in base_config.keys():
data.update(base_config[key])
for key in plugins2cmd_config.keys():
data.update(plugins2cmd_config[key])
for key in other_config.keys():
data.update(other_config[key])
except FileNotFoundError:
# logger.warning('配置文件不存在,生成默认配置....请填写数据库等必要数据后再次启动bot...')
init_config()
raise FileNotFoundError('配置文件不存在,生成默认配置....请填写数据库等必要数据后再次启动bot...')
except ValueError:
# logger.error('配置文件错误....')
raise ValueError('配置文件错误....')
return data

View File

@ -102,4 +102,4 @@ class GroupRemind(db.Model):
).apply()
return True
except Exception as e:
return False
return False

View File

View File

@ -12,22 +12,24 @@ from utils.utils import FreqLimiter
from configs.config import NICKNAME
__plugin_name__ = "基本设置 [Hidden]"
__zx_plugin_name__ = "基本设置 [Hidden]"
__plugin_usage__ = "用法: 无"
__plugin_version__ = 0.1
__plugin_author__ = 'HibiKier'
_flmt = FreqLimiter(300)
config_playgame = on_keyword({"打游戏"}, permission=GROUP, priority=1, block=True)
config_play_game = on_keyword({"打游戏"}, permission=GROUP, priority=1, block=True)
@config_playgame.handle()
@config_play_game.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
if not _flmt.check(event.group_id):
return
_flmt.start_cd(event.group_id)
await config_playgame.finish(
await config_play_game.finish(
image(random.choice(os.listdir(IMAGE_PATH + "dayouxi/")), "dayouxi")
)

View File

@ -0,0 +1,3 @@
import nonebot
nonebot.load_plugins("plugins/admin_bot_manage")

View File

@ -4,16 +4,26 @@ from nonebot.typing import T_State
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent
from .data_source import custom_group_welcome
from nonebot.adapters.cqhttp.permission import GROUP
from configs.config import OC_LEVEL
from services.log import logger
__plugin_name__ = "自定义进群欢迎消息"
__zx_plugin_name__ = "自定义进群欢迎消息 [Admin]"
__plugin_usage__ = """
自定义进群欢迎消息 [消息] [图片](可省略)
示例自定义进群欢迎消息 欢迎新人[图片]
"""
usage
指令
自定义进群欢迎消息 ?[文本] ?[图片]
示例自定义进群欢迎消息 欢迎新人[图片]
Note可以通过[at]来确认是否艾特新成员
示例自定义进群欢迎消息 欢迎你[at]
""".strip()
__plugin_des__ = '简易的自定义群欢迎消息'
__plugin_cmd__ = ['自定义群欢迎消息 ?[文本] ?[图片]']
__plugin_version__ = 0.1
__plugin_author__ = 'HibiKier'
__plugin_settings__ = {
"admin_level": OC_LEVEL,
}
custom_welcome = on_command(
"自定义进群欢迎消息",
@ -26,12 +36,16 @@ custom_welcome = on_command(
@custom_welcome.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
msg = get_message_text(event.json())
imgs = get_message_imgs(event.json())
if not msg and not imgs:
await custom_welcome.finish(__plugin_usage__)
await custom_welcome.send(
await custom_group_welcome(msg, imgs, event.user_id, event.group_id),
at_sender=True,
)
logger.info(f"USER {event.user_id} GROUP {event.group_id} 自定义群欢迎消息:{msg}")
try:
msg = get_message_text(event.json())
imgs = get_message_imgs(event.json())
if not msg and not imgs:
await custom_welcome.finish(__plugin_usage__)
await custom_welcome.send(
await custom_group_welcome(msg, imgs, event.user_id, event.group_id),
at_sender=True,
)
logger.info(f"USER {event.user_id} GROUP {event.group_id} 自定义群欢迎消息:{msg}")
except Exception as e:
logger.error(f"自定义进群欢迎消息发生错误 {type(e)}{e}")
await custom_welcome.send("发生了一些未知错误...")

View File

@ -1,4 +1,5 @@
from models.group_remind import GroupRemind
from typing import List
from nonebot.adapters.cqhttp.message import MessageSegment
from services.log import logger
from configs.path_config import DATA_PATH
from utils.message_builder import image
@ -9,9 +10,8 @@ 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.manager import group_manager, plugins2settings_manager
from utils.image_utils import CreateImg
from configs.config import plugins2info_dict
import aiofiles
import aiohttp
import asyncio
@ -24,70 +24,16 @@ except ModuleNotFoundError:
import json
command_dict = {
"早晚安": "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发送当日的原神黄历",
}
async def remind_status(group: int, name: str, flag: bool) -> str:
_name = ""
if name in command_dict.values():
_name = list(command_dict.keys())[list(command_dict.values()).index(name)]
if flag:
rst = "开启"
if await GroupRemind.get_status(group, name):
return f"该群已经{rst}{_name},请勿重复开启!"
else:
rst = "关闭"
if not await GroupRemind.get_status(group, 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 ""
if info:
info = "\n" + info
return f"成功{rst} {_name}0v0 {info}"
else:
return f"{rst} {_name} 失败了..."
async def set_group_status(name: str, group_id: int):
flag = None
if name[:2] == "开启":
flag = True
elif name[:2] == "关闭":
flag = False
cmd = name[2:]
if cmd in ["全部通知", "所有通知"]:
for command in command_list:
await remind_status(group_id, command, flag)
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 "×"}'
)
return result
async def group_current_status(group_id: int) -> str:
"""
获取当前所有通知的开关
:param group_id: 群号
"""
rst = "[被动技能 状态]\n"
_data = group_manager.get_task_data()
for task in _data.keys():
rst += f'{_data[task]}: {"" if await group_manager.check_group_task_status(group_id, task) else "×"}\n'
return rst.strip()
custom_welcome_msg_json = (
@ -95,13 +41,21 @@ custom_welcome_msg_json = (
)
async def custom_group_welcome(msg, imgs, user_id, group_id):
async def custom_group_welcome(
msg: str, imgs: List[str], user_id: int, group_id: int
) -> str:
"""
替换群欢迎消息
:param msg: 欢迎消息文本
:param imgs: 欢迎消息图片只取第一张
:param user_id: 用户id用于log记录
:param 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")
# print(custom_welcome_msg_json)
if not custom_welcome_msg_json.exists():
custom_welcome_msg_json.parent.mkdir(parents=True, exist_ok=True)
data = {}
@ -133,54 +87,99 @@ async def custom_group_welcome(msg, imgs, user_id, group_id):
return f"替换群欢迎消息成功:\n{result}" + img_result
def change_group_switch(cmd: str, group_id: int, is_super: bool = False):
task_data = None
async def change_group_switch(cmd: str, group_id: int, is_super: bool = False):
global task_data
"""
修改群功能状态
:param cmd: 功能名称
:param group_id: 群号
:param is_super: 是否位超级用户超级用户用于私聊开关功能状态
"""
if not task_data:
task_data = group_manager.get_task_data()
group_help_file = Path(DATA_PATH) / "group_help" / f"{group_id}.png"
group_id = str(group_id)
status = cmd[:2]
cmd = cmd[2:]
for plugin_cmd in plugins2info_dict.keys():
if cmd in plugins2info_dict[plugin_cmd]["cmd"]:
if is_super:
plugin_cmd = f'{plugin_cmd}:super'
type_ = 'plugin'
modules = plugins2settings_manager.get_plugin_module(cmd, True)
if cmd == '全部被动':
for task in task_data:
if status == "开启":
if group_manager.get_plugin_status(plugin_cmd, group_id):
return f"功能 {cmd} 正处于开启状态!不要重复开启."
group_manager.unblock_plugin(plugin_cmd, group_id)
if not await group_manager.check_group_task_status(group_id, task):
await group_manager.open_group_task(group_id, task)
else:
if not group_manager.get_plugin_status(plugin_cmd, group_id):
if await group_manager.check_group_task_status(group_id, task):
await group_manager.close_group_task(group_id, task)
return f"{status} 全部被动技能!"
if cmd in [task_data[x] for x in task_data.keys()]:
type_ = 'task'
modules = [x for x in task_data.keys() if task_data[x] == cmd]
for module in modules:
if is_super:
module = f"{module}:super"
if status == "开启":
if type_ == 'task':
if await group_manager.check_group_task_status(group_id, module):
return f"被动 {task_data[module]} 正处于开启状态!不要重复开启."
await group_manager.open_group_task(group_id, module)
else:
if group_manager.get_plugin_status(module, group_id):
return f"功能 {cmd} 正处于开启状态!不要重复开启."
group_manager.unblock_plugin(module, group_id)
else:
if type_ == 'task':
if not await group_manager.check_group_task_status(group_id, module):
return f"被动 {task_data[module]} 正处于关闭状态!不要重复关闭."
await group_manager.close_group_task(group_id, module)
else:
if not group_manager.get_plugin_status(module, 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} 功能..."
group_manager.block_plugin(module, group_id)
if group_help_file.exists():
group_help_file.unlink()
return f"{status} {cmd} 功能!"
def set_plugin_status(cmd: str, block_type: str = "all"):
"""
设置插件功能状态超级用户使用
:param cmd: 功能名称
:param block_type: 限制类型, 'all': 私聊+群里, 'private': 私聊, 'group': 群聊
"""
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
module = plugins2settings_manager.get_plugin_module(cmd)
if status == "开启":
group_manager.unblock_plugin(module)
else:
group_manager.block_plugin(module, block_type=block_type)
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
def _get_plugin_status() -> MessageSegment:
"""
合成功能状态图片
"""
rst = "\t功能\n"
flag_str = "状态".rjust(4) + "\n"
for module in plugins2settings_manager.get_data():
flag = group_manager.get_plugin_block_type(module)
flag = flag.upper() + " CLOSE" if flag else "OPEN"
try:
rst += f'{plugins2settings_manager.get(module)["cmd"][0]}\n'
except IndexError:
rst += f"{module}\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)
@ -192,6 +191,10 @@ def _get_plugin_status():
async def update_member_info(group_id: int) -> bool:
"""
更新群成员信息
:param group_id: 群号
"""
bot = get_bot()
_group_user_list = await bot.get_group_member_list(group_id=group_id)
_error_member_list = []
@ -267,7 +270,3 @@ async def update_member_info(group_id: int) -> bool:
user_id=int(list(bot.config.superusers)[0]), message=result[:-1]
)
return True

View File

@ -1,57 +0,0 @@
from nonebot.typing import T_State
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent
from .data_source import set_group_status, group_current_status
from nonebot.adapters.cqhttp.permission import GROUP
from services.log import logger
from nonebot import on_command
__plugin_name__ = "群通知开关"
__plugin_usage__ = """
示例
开启早晚安
关闭早晚安
"""
group_status = on_command(
"oc_reminds",
aliases={
"开启早晚安",
"关闭早晚安",
"开启进群欢迎",
"关闭进群欢迎",
"开启每日开箱重置提醒",
"关闭每日开箱重置提醒",
"开启b站转发解析",
"关闭b站转发解析",
"开启epic通知",
"关闭epic通知",
"开启丢人爬",
"关闭丢人爬",
"开启原神黄历提醒",
"关闭原神黄历提醒",
"开启全部通知",
"开启所有通知",
"关闭全部通知",
"关闭所有通知",
"群通知状态",
},
permission=GROUP,
priority=5,
block=True,
)
@group_status.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
if state["_prefix"]["raw_command"] in ["群通知状态"]:
await group_status.finish(await group_current_status(event.group_id))
await group_status.send(
await set_group_status(state["_prefix"]["raw_command"], event.group_id),
at_sender=True,
)
logger.info(
f'USER {event.user_id} GROUP {event.group_id} 使用群通知管理命令 {state["_prefix"]["raw_command"]}'
)

View File

@ -0,0 +1,42 @@
from nonebot.adapters.cqhttp import Bot, Event
from nonebot.typing import T_State
from utils.manager import group_manager, plugins2settings_manager
from utils.utils import get_message_text
from services.log import logger
cmd = []
def switch_rule(bot: Bot, event: Event, state: T_State) -> bool:
"""
检测文本是否是关闭功能命令
:param bot: pass
:param event: pass
:param state: pass
"""
try:
if not cmd:
cmd.append('关闭全部被动')
cmd.append('开启全部被动')
_data = group_manager.get_task_data()
for key in _data:
cmd.append(f"开启{_data[key]}")
cmd.append(f"关闭{_data[key]}")
cmd.append(f"开启 {_data[key]}")
cmd.append(f"关闭 {_data[key]}")
_data = plugins2settings_manager.get_data()
for key in _data:
try:
for x in _data[key]["cmd"]:
cmd.append(f"开启{x}")
cmd.append(f"关闭{x}")
cmd.append(f"开启 {x}")
cmd.append(f"关闭 {x}")
except KeyError:
pass
msg = get_message_text(event.json()).split()
msg = msg[0] if msg else ""
return msg in cmd
except Exception as e:
logger.error(f"检测是否为功能开关命令发生错误 {type(e)}: {e}")
return False

View File

@ -1,78 +1,106 @@
from nonebot import on_command
from nonebot import on_command, on_message
from nonebot.typing import T_State
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent, MessageEvent
from .data_source import change_group_switch, set_plugin_status, get_plugin_status
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent, MessageEvent, GROUP
from .data_source import (
change_group_switch,
set_plugin_status,
get_plugin_status,
group_current_status,
)
from services.log import logger
from configs.config import plugins2info_dict, NICKNAME
from configs.config import NICKNAME, OC_LEVEL
from utils.utils import get_message_text, is_number
from nonebot.permission import SUPERUSER
from .rule import switch_rule
__plugin_name__ = "群功能开关"
__zx_plugin_name__ = "群功能开关 [Admin]"
__plugin_usage__ = """
示例
开启色图
关闭色图
"""
usage
群内功能与被动技能开关
指令
开启/关闭[功能]
群被动状态
开启全部被动
关闭全部被动
示例开启/关闭色图
""".strip()
__plugin_superuser_usage__ = """
usage:
功能总开关与指定群禁用
指令
功能状态
开启/关闭[功能] [group]
开启/关闭[功能] ['private'/'group']
""".strip()
__plugin_des__ = "群内功能开关"
__plugin_cmd__ = [
"开启/关闭[功能]",
"群被动状态",
"开启全部被动",
"关闭全部被动",
"功能状态 [_superuser]",
"开启/关闭[功能] [group] [_superuser]",
"开启/关闭[功能] ['private'/'group'] [_superuser]",
]
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {
"admin_level": OC_LEVEL,
}
switch_rule_matcher = on_message(rule=switch_rule, priority=4, block=True)
plugins_status = on_command("功能状态", permission=SUPERUSER, priority=5, block=True)
group_task_status = on_command("群被动状态", permission=GROUP, priority=5, block=True)
cmds = []
for cmd_list in plugins2info_dict.values():
for cmd in cmd_list["cmd"]:
cmds.append(f"开启{cmd}")
cmds.append(f"关闭{cmd}")
cmds = set(cmds)
switch_rule = on_command(
"switch_rule", aliases=cmds, priority=5, block=True
)
plugins_status = on_command('功能状态', permission=SUPERUSER, priority=5, block=True)
@switch_rule.handle()
@switch_rule_matcher.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
_cmd = get_message_text(event.json()).split()[0]
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"]}'
)
await switch_rule_matcher.send(await change_group_switch(_cmd, event.group_id))
logger.info(f"USER {event.user_id} GROUP {event.group_id} 使用群功能管理命令 {_cmd}")
else:
if str(event.user_id) in bot.config.superusers:
block_type = get_message_text(event.json())
block_type = block_type if block_type else 'a'
_cmd = state["_prefix"]["raw_command"].strip()
block_type = " ".join(get_message_text(event.json()).split()[1:])
block_type = block_type if block_type else "a"
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:]} 功能')
elif block_type in ['all', 'private', 'group', 'a', 'p', 'g']:
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
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_matcher.finish(f"{NICKNAME}未加入群聊:{block_type}")
await 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_matcher.send(
f"已禁用群聊 {group_name}({block_type}) 的 {_cmd[2:]} 功能"
)
elif block_type in ["all", "private", "group", "a", "p", "g"]:
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:]}')
if block_type == "all":
await switch_rule_matcher.send(f"{_cmd[:2]}功能:{_cmd[2:]}")
elif block_type == "private":
await switch_rule_matcher.send(f"已在私聊中{_cmd[:2]}功能:{_cmd[2:]}")
else:
await switch_rule.send(f'已在群聊中{_cmd[:2]}功能:{_cmd[2:]}')
await switch_rule_matcher.send(f"已在群聊中{_cmd[:2]}功能:{_cmd[2:]}")
else:
await switch_rule.finish('格式错误:关闭[功能] [group]/[p/g]')
logger.info(
f'USER {event.user_id} 使用功能管理命令 {state["_prefix"]["raw_command"]} | {block_type}'
)
await switch_rule_matcher.finish("格式错误:关闭[功能] [group]/[p/g]")
logger.info(f"USER {event.user_id} 使用功能管理命令 {_cmd} | {block_type}")
@plugins_status.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
await plugins_status.send(await get_plugin_status())
@group_task_status.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
await group_task_status.send(await group_current_status(event.group_id))

View File

@ -5,6 +5,13 @@ from models.group_info import GroupInfo
from asyncpg.exceptions import ConnectionDoesNotExistError
__zx_plugin_name__ = '管理方面定时任务 [Hidden]'
__plugin_usage__ = ''
__plugin_des__ = '成员信息和管理权限的定时更新'
__plugin_version__ = 0.1
__plugin_author__ = 'HibiKier'
# 自动更新群员信息
@scheduler.scheduled_job(
"cron",
@ -13,14 +20,15 @@ from asyncpg.exceptions import ConnectionDoesNotExistError
)
async def _():
bot = get_bot()
gl = await bot.get_group_list(self_id=bot.self_id)
gl = [g["group_id"] for g in gl]
for g in gl:
try:
await update_member_info(g)
logger.info(f"更新群组 g:{g} 成功")
except Exception as e:
logger.error(f"更新群组错误 g:{g} e:{e}")
if bot:
gl = await bot.get_group_list()
gl = [g["group_id"] for g in gl]
for g in gl:
try:
await update_member_info(g)
logger.info(f"更新群组 g:{g} 成功")
except Exception as e:
logger.error(f"更新群组错误 g:{g} e:{e}")
# 快速更新群员信息以及管理员权限
@ -31,12 +39,13 @@ async def _():
async def _():
try:
bot = get_bot()
gl = await bot.get_group_list(self_id=bot.self_id)
gl = [g["group_id"] for g in gl]
all_group = [x.group_id for x in await GroupInfo.get_all_group()]
for g in gl:
if g not in all_group:
await update_member_info(g)
logger.info(f"快速更新群信息以及权限:{g}")
if bot:
gl = await bot.get_group_list()
gl = [g["group_id"] for g in gl]
all_group = [x.group_id for x in await GroupInfo.get_all_group()]
for g in gl:
if g not in all_group:
await update_member_info(g)
logger.info(f"快速更新群信息以及权限:{g}")
except (IndexError, ConnectionDoesNotExistError):
pass

View File

@ -3,14 +3,20 @@ from nonebot.typing import T_State
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent, GROUP, GroupIncreaseNoticeEvent
from .data_source import update_member_info
__plugin_name__ = "更新群组成员列表"
__zx_plugin_name__ = "更新群组成员列表 [Admin]"
__plugin_usage__ = """
说明
更新群组成员的基本信息
示例
更新群组成员列表
"""
usage
更新群组成员的基本信息
指令
更新群组成员列表/更新群组成员信息
""".strip()
__plugin_des__ = '更新群组成员列表'
__plugin_cmd__ = ['更新群组成员列表']
__plugin_version__ = 0.1
__plugin_author__ = 'HibiKier'
__plugin_settings__ = {
"admin_level": 1,
}
refresh_member_group = on_command(

View File

@ -7,9 +7,9 @@ from models.group_member_info import GroupInfoUser
from configs.config import ADMIN_DEFAULT_AUTH
__plugin_name__ = "群管理员监测"
__plugin_usage__ = ""
__zx_plugin_name__ = "群管理员变动监测 [Hidden]"
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
admin_notice = on_notice(priority=5)

View File

@ -2,55 +2,26 @@ from nonebot import on_command
from nonebot.typing import T_State
from nonebot.adapters import Bot
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
from .data_source import create_help_image, admin_help_image
__plugin_name__ = '管理帮助 [Hidden]'
__plugin_usage__ = f'''[权限等级]管理帮助:
[1]1.更新群组成员列表
[2]2.功能开关 --> 指令:开启/关闭xx功能
[2]3.查看群被动技能 --> 指令:群通知状态
[2]4.自定义群欢迎 --> 指令:自定义进群欢迎消息
[5]5.将用户拉入{NICKNAME}黑名单 --> .ban/.unban
[5]6.刷屏禁言相关 -> 指令:刷屏检测设置/设置检测时间
\t\t/设置检测次数/设置禁言时长
[5]7.群订阅相关 -> 指令添加订阅 [主播/up/番剧] [id/番名/链接]
\t\t/删除订阅 [id]/ 查看订阅
[5]8.群员活跃度相关 --> 指令:群员活跃检测设置
设置群员活跃检测时长()
添加群员活跃检测白名单[at]...
查看群员活跃检测白名单
[6]8.上传图片/连续上传图片(6)
[7]9.移动图片(7)
[7]10.删除图片(7)
对我说 {NICKNAME}帮助 指令 获取对应详细帮助
群主与管理员默认 5 级权限
'''
passive_help = '''【被动技能开关(2)
开启/关闭早晚安
开启/关闭进群欢迎
开启/关闭每日开箱重置提醒
开启/关闭b站转发解析
开启/关闭丢人爬
开启/关闭epic通知
开启/关闭原神黄历提醒
开启/关闭全部通知
'''
__zx_plugin_name__ = '管理帮助 [Admin]'
__plugin_usage__ = '管理员帮助,在群内回复“管理员帮助”'
__plugin_version__ = 0.1
__plugin_author__ = 'HibiKier'
__plugin_settings__ = {
"admin_level": 1,
}
admin_help = on_command("管理员帮助", aliases={"管理帮助"}, priority=5, block=True)
admin_help_img = CreateImg(1200, 600, font_size=24)
admin_help_img.text((10, 10), __plugin_usage__)
text_img = CreateImg(450, 600, font_size=24)
text_img.text((0, 0), passive_help)
admin_help_img.paste(text_img, (850, 50))
admin_help_img.save(IMAGE_PATH + 'admin_help_img.png')
if admin_help_image.exists():
admin_help_image.unlink()
@admin_help.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
if not admin_help_image.exists():
await create_help_image()
await admin_help.send(image('admin_help_img.png'))

View File

@ -0,0 +1,91 @@
from utils.image_utils import CreateImg
from configs.path_config import IMAGE_PATH
from services.log import logger
from utils.utils import get_matchers
from utils.manager import group_manager
from nonebot.adapters.cqhttp import Bot
from pathlib import Path
from nonebot import Driver
import asyncio
import nonebot
driver: Driver = nonebot.get_driver()
background = Path(IMAGE_PATH) / "background" / "0.png"
admin_help_image = Path(IMAGE_PATH) / 'admin_help_img.png'
@driver.on_bot_connect
async def create_help_image(bot: Bot = None):
"""
创建管理员帮助图片
"""
if not group_manager.get_task_data():
await group_manager.init_group_task()
logger.info(f'已成功加载 {len(group_manager.get_task_data())} 个被动技能.')
await asyncio.get_event_loop().run_in_executor(
None, _create_help_image
)
def _create_help_image():
"""
创建管理员帮助图片
"""
_matchers = get_matchers()
_plugin_name_list = []
width = 0
_plugin_level = {}
for matcher in _matchers:
_plugin = nonebot.plugin.get_plugin(matcher.module)
_module = _plugin.module
try:
plugin_name = _module.__getattribute__("__zx_plugin_name__")
except AttributeError:
continue
try:
if (
"[admin]" in plugin_name.lower()
and plugin_name not in _plugin_name_list
and plugin_name != "管理帮助 [Admin]"
):
_plugin_name_list.append(plugin_name)
plugin_settings = _module.__getattribute__("__plugin_settings__")
plugin_des = _module.__getattribute__("__plugin_des__")
plugin_cmd = _module.__getattribute__("__plugin_cmd__")
plugin_cmd = [x for x in plugin_cmd if "[_superuser]" not in x]
admin_level = int(plugin_settings["admin_level"])
if _plugin_level.get(admin_level):
_plugin_level[admin_level].append(
f"[{admin_level}] {plugin_des} -> " + " / ".join(plugin_cmd)
)
else:
_plugin_level[admin_level] = [
f"[{admin_level}] {plugin_des} -> " + " / ".join(plugin_cmd)
]
x = len(f"[{admin_level}] {plugin_des} -> " + " / ".join(plugin_cmd)) * 23
width = width if width > x else x
except AttributeError:
logger.warning(f"获取管理插件 {matcher.module}: {plugin_name} 设置失败...")
help_str = "* 注: * 代表可有多个相同参数 ? 代表可省略该参数 *\n\n" \
"[权限等级] 管理员帮助:\n\n"
x = list(_plugin_level.keys())
x.sort()
for level in x:
for help_ in _plugin_level[level]:
help_str += f"\t{help_}\n\n"
help_str += '-----[被动技能开关]-----\n\n'
task_data = group_manager.get_task_data()
for i, x in enumerate(task_data.keys()):
help_str += f'{i+1}.开启/关闭{task_data[x]}\n\n'
height = len(help_str.split("\n")) * 33
A = CreateImg(width, height, font_size=24)
_background = CreateImg(width, height, background=background)
A.text((150, 110), help_str)
A.paste(_background, alpha=True)
A.save(admin_help_image)
logger.info(f'已成功加载 {len(_plugin_name_list)} 条管理员命令')

View File

@ -1,20 +1,33 @@
from .data_source import get_chat_result, hello, no_result
from services.log import logger
from nonebot import on_message
from nonebot.rule import to_me
from nonebot.typing import T_State
from nonebot.adapters.cqhttp import (
Bot,
PrivateMessageEvent,
GroupMessageEvent,
Message,
MessageEvent,
)
from utils.utils import get_message_text, get_message_imgs
from nonebot.rule import to_me
from nonebot.typing import T_State
from models.friend_user import FriendUser
from models.group_member_info import GroupInfoUser
from services.log import logger
from utils.utils import get_message_text, get_message_imgs
from .data_source import get_chat_result, hello, no_result
from configs.config import NICKNAME
__plugin_name__ = "AI [Hidden]"
__zx_plugin_name__ = "AI"
__plugin_usage__ = f"""
usage
{NICKNAME}普普通通的对话吧
"""
__plugin_version__ = 0.1
__plugin_author__ = 'HibiKier'
__plugin_settings__ = {
"level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ["Ai", "ai", "AI", "aI"],
}
ai = on_message(rule=to_me(), priority=8)
@ -38,20 +51,20 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
]:
await ai.finish(hello())
img = imgs[0] if imgs else ""
if isinstance(event, PrivateMessageEvent):
nickname = await FriendUser.get_friend_nickname(event.user_id)
else:
if isinstance(event, GroupMessageEvent):
nickname = await GroupInfoUser.get_group_member_nickname(
event.user_id, event.group_id
)
else:
nickname = await FriendUser.get_friend_nickname(event.user_id)
if not nickname:
if isinstance(event, PrivateMessageEvent):
nickname = event.sender.nickname
else:
if isinstance(event, GroupMessageEvent):
nickname = event.sender.card if event.sender.card else event.sender.nickname
else:
nickname = event.sender.nickname
result = await get_chat_result(msg, img, event.user_id, nickname)
logger.info(
f"USER {event.user_id} GROUP {event.group_id if not isinstance(event, PrivateMessageEvent) else ''} "
f"USER {event.user_id} GROUP {event.group_id if isinstance(event, GroupMessageEvent) else ''} "
f"问题:{msg} ---- 回答:{result}"
)
if result:

View File

@ -1,19 +1,21 @@
import os
import random
import re
import aiohttp
from aiohttp.client import ClientSession
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
from utils.message_builder import image, face
from utils.utils import get_bot
import re
import aiohttp
import random
import os
try:
import ujson as json
except ModuleNotFoundError:
import json
url = "http://openapi.tuling123.com/openapi/api/v2"
check_url = "https://v2.alapi.cn/api/censor/text"
@ -24,6 +26,14 @@ anime_data = json.load(open(DATA_PATH + "anime.json", "r", encoding="utf8"))
async def get_chat_result(text: str, img_url: str, user_id: int, nickname: str) -> str:
"""
获取 AI 返回值顺序图灵 -> 青云客
:param text: 问题
:param img_url: 图片链接
:param user_id: 用户id
:param nickname: 用户昵称
:return: 回答
"""
global index
if index == 5:
index = 0
@ -50,7 +60,15 @@ async def get_chat_result(text: str, img_url: str, user_id: int, nickname: str)
# 图灵接口
async def tu_ling(text: str, img_url: str, user_id: int, sess: ClientSession):
async def tu_ling(text: str, img_url: str, user_id: int, sess: ClientSession) -> str:
"""
获取图灵接口的回复
:param text: 问题
:param img_url: 图片链接
:param user_id: 用户id
:param sess: AIOHTTP SESSION
:return: 图灵回复
"""
global index
try:
if text:
@ -94,7 +112,13 @@ async def tu_ling(text: str, img_url: str, user_id: int, sess: ClientSession):
# 屑 AI
async def xie_ai(text: str, sess: ClientSession):
async def xie_ai(text: str, sess: ClientSession) -> str:
"""
获取青云客回复
:param text: 问题
:param sess: AIOHTTP SESSION
:return: 青云可回复
"""
async with sess.get(
f"http://api.qingyunke.com/api.php?key=free&appid=0&msg={text}"
) as res:
@ -104,8 +128,8 @@ async def xie_ai(text: str, sess: ClientSession):
content = data["content"]
if "菲菲" in content:
content = content.replace("菲菲", NICKNAME)
if '艳儿' in content:
content = content.replace('艳儿', NICKNAME)
if "艳儿" in content:
content = content.replace("艳儿", NICKNAME)
if "公众号" in content:
content = ""
if "{br}" in content:
@ -123,11 +147,17 @@ async def xie_ai(text: str, sess: ClientSession):
)
else:
break
return content if not content and not ALAPI_AI_CHECK else await check_text(content, sess)
return (
content
if not content and not ALAPI_AI_CHECK
else await check_text(content, sess)
)
# 打招呼内容
def hello() -> str:
"""
一些打招呼的内容
"""
result = random.choice(
(
"哦豁?!",
@ -147,6 +177,9 @@ def hello() -> str:
# 没有回答时回复内容
def no_result() -> str:
"""
没有回答时的回复
"""
return (
random.choice(
[
@ -161,8 +194,12 @@ def no_result() -> str:
)
# 检测屑AI回复的文本是否是 *话
async def check_text(text: str, sess: ClientSession) -> str:
"""
ALAPI文本检测主要针对青云客API检测为恶俗文本改为无回复的回答
:param text: 回复
:param sess: AIOHTTP SESSION
"""
if not ALAPI_TOKEN:
return text
params = {"token": ALAPI_TOKEN, "text": text}
@ -170,8 +207,8 @@ async def check_text(text: str, sess: ClientSession) -> str:
async with sess.get(check_url, timeout=2, params=params) as response:
data = await response.json()
if data["code"] == 200:
if data['data']["conclusion_type"] == 2:
return ''
if data["data"]["conclusion_type"] == 2:
return ""
except Exception as e:
logger.error(f"检测违规文本错误...{type(e)}{e}")
return text

View File

@ -0,0 +1,3 @@
import nonebot
nonebot.load_plugins("plugins/alapi")

View File

@ -5,32 +5,44 @@ from configs.config import ALAPI_TOKEN
from .data_source import get_data
from services.log import logger
__plugin_name__ = '网易云热评'
__plugin_usage__ = '用法: 生了个人,我很抱歉'
comments_163 = on_command("网易云热评", aliases={'网易云评论', '到点了', '12点了'}, priority=5, block=True)
__zx_plugin_name__ = "网易云热评"
__plugin_usage__ = """
usage
到点了还是防不了下塔
指令
网易云热评/到点了/12点了
""".strip()
__plugin_des__ = "生了个人,我很抱歉"
__plugin_cmd__ = ["网易云热评", "到点了", "12点了"]
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {
"level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ["网易云热评", "网易云评论", "到点了", "12点了"],
}
comments_163_url = 'https://v2.alapi.cn/api/comment'
comments_163 = on_command(
"网易云热评", aliases={"网易云评论", "到点了", "12点了"}, priority=5, block=True
)
comments_163_url = "https://v2.alapi.cn/api/comment"
@comments_163.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
params = {
'token': ALAPI_TOKEN
}
params = {"token": ALAPI_TOKEN}
data, code = await get_data(comments_163_url, params)
if code != 200:
await comments_163.finish(data, at_sender=True)
data = data['data']
comment = data['comment_content']
song_name = data['title']
await comments_163.send(f'{comment}\n\t——《{song_name}')
data = data["data"]
comment = data["comment_content"]
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 isinstance(event, GroupMessageEvent) else 'private'})"
f" 发送网易云热评: {comment} \n\t\t————{song_name}")
f" 发送网易云热评: {comment} \n\t\t————{song_name}"
)

View File

@ -7,9 +7,22 @@ from utils.utils import get_message_text
from .data_source import get_data
from services.log import logger
__plugin_name__ = 'b封面'
__plugin_usage__ = '用法: b封面 (链接avbvcv直播id)\n\t' \
'示例b封面 av86863038'
__zx_plugin_name__ = 'b封面'
__plugin_usage__ = """usage
b封面 [链接/av/bv/cv/直播id]
示例b封面 av86863038
"""
__plugin_des__ = '快捷的b站视频封面获取方式'
__plugin_cmd__ = ['b封面/B封面']
__plugin_type__ = ('一些工具',)
__plugin_version__ = 0.1
__plugin_author__ = 'HibiKier'
__plugin_settings__ = {
"level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ["b封面", 'B封面'],
}
cover = on_command('b封面', aliases={'B封面'}, priority=5, block=True)

View File

@ -2,10 +2,16 @@ 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
from typing import Union
import aiohttp
async def get_data(url: str, params: dict):
async def get_data(url: str, params: dict) -> 'Union[dict, str], int':
"""
获取ALAPI数据
:param url: 请求链接
:param params: 参数
"""
async with aiohttp.ClientSession() as session:
try:
async with session.get(
@ -22,7 +28,11 @@ async def get_data(url: str, params: dict):
return "超时了....", 998
def gen_wbtop_pic(data) -> MessageSegment:
def gen_wbtop_pic(data: dict) -> MessageSegment:
"""
生成微博热搜图片
:param data: 微博热搜数据
"""
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)

View File

@ -5,9 +5,21 @@ from configs.config import ALAPI_TOKEN
from services.log import logger
from .data_source import get_data
__plugin_name__ = '古诗'
__plugin_usage__ = '用法: 无'
__zx_plugin_name__ = '古诗'
__plugin_usage__ = """usage
平白无故念首诗
示例念诗/来首诗/念首诗
"""
__plugin_des__ = '为什么突然文艺起来了!'
__plugin_cmd__ = ['念诗/来首诗/念首诗']
__plugin_version__ = 0.1
__plugin_author__ = 'HibiKier'
__plugin_settings__ = {
"level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ['念诗', '来首诗', '念首诗'],
}
poetry = on_command("念诗", aliases={'来首诗', '念首诗'}, priority=5, block=True)

View File

@ -10,9 +10,25 @@ from configs.path_config import IMAGE_PATH
from utils.message_builder import image
import asyncio
__plugin_name__ = '微博热搜'
__plugin_usage__ = '用法: 无'
__zx_plugin_name__ = '微博热搜'
__plugin_usage__ = """
usage
在QQ上吃个瓜
指令
微博热搜发送实时热搜
微博热搜 [id]截图该热搜页面
示例微博热搜 5
""".strip()
__plugin_des__ = '刚买完瓜,在吃瓜现场'
__plugin_cmd__ = ['微博热搜', '微博热搜 [id]']
__plugin_version__ = 0.1
__plugin_author__ = 'HibiKier'
__plugin_settings__ = {
"level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ['微博热搜'],
}
wbtop = on_command("wbtop", aliases={'微博热搜'}, priority=5, block=True)
@ -52,9 +68,9 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
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 div.screenshot(path=f'{IMAGE_PATH}/temp/wbtop_{event.user_id}.png', timeout=100000)
await page.close()
await wbtop.send(image(f'webtop_{event.user_id}.png', 'temp'))
await wbtop.send(image(f'wbtop_{event.user_id}.png', 'temp'))
except Exception as e:
logger.error(f'微博热搜截图出错... {type(e)}: {e}')
if page:

View File

@ -7,7 +7,9 @@ from nonebot.adapters.cqhttp.exception import ActionFailed
from utils.utils import scheduler
import time
__plugin_name__ = "好友群聊处理请求 [Hidden]"
__zx_plugin_name__ = "好友群聊处理请求 [Hidden]"
__plugin_version__ = 0.1
__plugin_author__ = 'HibiKier'
friend_req = on_request(priority=5)

View File

@ -5,21 +5,37 @@ from nonebot.typing import T_State
from nonebot.adapters.cqhttp import Bot
from nonebot.adapters.cqhttp import GroupMessageEvent, PrivateMessageEvent
from utils.utils import get_message_at, get_message_text, is_number
from configs.config import NICKNAME
from configs.config import NICKNAME, BAN_LEVEL
from nonebot.permission import SUPERUSER
from services.log import logger
__plugin_name__ = "Ban/unBan"
__plugin_usage__ = (
"用法:\n"
f"(不是禁言!是针对{NICKNAME}是否处理封禁用户消息)\n"
"封禁/解封用户 [小时] [分钟]\n"
"示例:.ban @djdsk\n"
"示例:.ban @djdsk 0 30\n"
"示例:.ban @sdasf 4\n"
"示例:.unban @sdasf"
)
__zx_plugin_name__ = "封禁Ban用户 [Admin]"
__plugin_usage__ = """
usage
将用户拉入或拉出黑名单
指令:
.ban [at] ?[小时] ?[分钟]
.unban
示例.ban @user
示例.ban @user 6
示例.ban @user 3 10
示例.unban @user
""".strip()
__plugin_superuser_usage__ = """
usage
屏蔽用户消息相当于最上级.ban
指令
b了 [at]
示例b了 @user
""".strip()
__plugin_des__ = '你被逮捕了!丢进小黑屋!'
__plugin_cmd__ = ['.ban [at] ?[小时] ?[分钟]', '.unban [at]', 'b了 [at] [_superuser]']
__plugin_version__ = 0.1
__plugin_author__ = 'HibiKier'
__plugin_settings__ = {
"admin_level": BAN_LEVEL,
}
ban = on_command(
@ -167,7 +183,7 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
if not await BanUser.ban(qq, 10, 99999999):
await BanUser.unban(qq)
await BanUser.ban(qq, 10, 99999999)
await ban.send(f"{user_name} 已在黑名单!预计不解封了..")
await ban.send(f"已将 {user_name} 拉入黑名单!")
else:
await super_ban.send('需要艾特被super ban的对象..')

View File

@ -19,12 +19,31 @@ from services.log import logger
from nonebot import Driver
import nonebot
__plugin_name__ = "B站订阅"
__plugin_usage__ = """B站订阅帮助
添加订阅 [主播/UP/番剧] [id/链接/番名]
删除订阅 [id]
查看订阅"""
__zx_plugin_name__ = "B站订阅"
__plugin_usage__ = """
usage
B站直播番剧UP动态开播等提醒
主播订阅相当于 直播间订阅 + UP订阅
指令[示例Id乱打的仅做示例]
添加订阅 ['主播'/'UP'/'番剧'] [id/链接/番名]
删除订阅 [id]
查看订阅
示例添加订阅主播 2345344 <-(直播房间id)
示例添加订阅UP 2355543 <-(个人主页id)
示例添加订阅番剧 史莱姆 <-(支持模糊搜索)
示例添加订阅番剧 125344 <-(番剧id)
示例删除订阅 2324344 <-(任意id通过查看订阅获取)
""".strip()
__plugin_des__ = '非常便利的B站订阅通知'
__plugin_cmd__ = ['添加订阅 [主播/UP/番剧] [id/链接/番名]', '删除订阅 [id]', '查看订阅']
__plugin_version__ = 0.1
__plugin_author__ = 'HibiKier'
__plugin_settings__ = {
"level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ["B站订阅", 'b站订阅', '添加订阅', '删除订阅', '查看订阅'],
}
add_sub = on_command("添加订阅", priority=5, block=True)
del_sub = on_command("删除订阅", priority=5, block=True)

View File

@ -5,12 +5,21 @@ from nonebot.permission import SUPERUSER
import asyncio
from utils.utils import get_message_text, get_message_imgs
from services.log import logger
from models.group_remind import GroupRemind
from utils.message_builder import image
from utils.manager import group_manager
__plugin_name__ = "广播 [Hidden]"
__plugin_usage__ = '广播- [消息] or [图片]'
__zx_plugin_name__ = "广播 [Superuser]"
__plugin_usage__ = """
usage
指令
广播- ?[消息] ?[图片]
示例广播- 你们好
""".strip()
__plugin_des__ = "昭告天下!"
__plugin_cmd__ = ["广播-"]
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_task__ = {"broadcast": "广播"}
broadcast = on_command("广播-", priority=1, permission=SUPERUSER, block=True)
@ -19,30 +28,32 @@ broadcast = on_command("广播-", priority=1, permission=SUPERUSER, block=True)
async def _(bot: Bot, event: Event, state: T_State):
msg = get_message_text(event.json())
imgs = get_message_imgs(event.json())
rst = ''
rst = ""
for img in imgs:
rst += image(img)
sid = bot.self_id
gl = await bot.get_group_list(self_id=sid)
gl = [g['group_id'] for g in gl]
gl = [
g["group_id"]
for g in gl
if await group_manager.check_group_task_status(g["group_id"], "broadcast")
]
g_cnt = len(gl)
cnt = 0
error = ""
x = 0.25
for g in gl:
if await GroupRemind.get_status(g, 'gb'):
await asyncio.sleep(0.5)
try:
await bot.send_group_msg(self_id=sid, group_id=g, message=msg+rst)
logger.info(f'{g} 投递广播成功')
except Exception as e:
logger.error(f'{g} 投递广播失败:{type(e)}')
try:
await broadcast.send(f'{g} 投递广播失败:{type(e)}')
except Exception as e:
logger.critical(f'向广播发起者进行错误回报时发生错误:{type(e)}')
await broadcast.send(f'广播完成!')
cnt += 1
if cnt / g_cnt > x:
await broadcast.send(f"已播报至 {int(cnt / g_cnt * 100)}% 的群聊")
x += 0.25
try:
await bot.send_group_msg(self_id=sid, group_id=g, message=msg + rst)
logger.info(f"GROUP {g} 投递广播成功")
except Exception as e:
logger.error(f"GROUP {g} 投递广播失败:{type(e)}")
error += f"GROUP {g} 投递广播失败:{type(e)}\n"
await asyncio.sleep(0.5)
await broadcast.send(f"已播报至 100% 的群聊")
if error:
await broadcast.send(f"播报时错误:{error}")

View File

@ -6,21 +6,33 @@ from nonebot.adapters import Bot
from nonebot.adapters.cqhttp import PrivateMessageEvent
from utils.utils import get_message_text
from nonebot.adapters.cqhttp.permission import PRIVATE
from utils.utils import UserExistLimiter
from asyncio.exceptions import TimeoutError
from aiohttp.client_exceptions import ServerDisconnectedError
__plugin_name__ = "磁力搜索"
__plugin_usage__ = r"""
* 请各位使用后不要转发 *
* 拒绝反冲斗士 *
bt [关键词] [页数](默认为1)
示例
bt 钢铁侠
bt 钢铁侠 3
__zx_plugin_name__ = "磁力搜索"
__plugin_usage__ = """
usage
* 请各位使用后不要转发 *
* 拒绝反冲斗士 *
指令
bt [关键词] ?[页数]
示例bt 钢铁侠
示例bt 钢铁侠 3
""".strip()
__plugin_des__ = "bt(磁力搜索)[仅支持私聊,懂的都懂]"
__plugin_cmd__ = ["bt [关键词] ?[页数]"]
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {
"level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ["bt", "磁力搜索", "Bt", "BT"],
}
__plugin_block_limit__ = {
"rst": "您有bt任务正在进行请等待结束."
}
_ulmt = UserExistLimiter()
bt = on_command("bt", permission=PRIVATE, priority=5, block=True)
@ -38,8 +50,6 @@ async def _(bot: Bot, event: PrivateMessageEvent, state: T_State):
@bt.handle()
async def _(bot: Bot, event: PrivateMessageEvent, state: T_State):
if _ulmt.check(event.user_id):
await bt.finish("您有bt任务正在进行请等待结束.", at_sender=True)
mp = get_message_text(event.json())
if not mp:
return
@ -54,7 +64,6 @@ async def _(bot: Bot, event: PrivateMessageEvent, state: T_State):
@bt.got("keyword", prompt="虚空磁力查什么GKD")
async def _(bot: Bot, event: PrivateMessageEvent, state: T_State):
_ulmt.set_true(event.user_id)
keyword = state["keyword"]
page = state["page"]
await bt.send("开始搜索....", at_sender=True)
@ -72,16 +81,12 @@ async def _(bot: Bot, event: PrivateMessageEvent, state: T_State):
)
send_flag = True
except TimeoutError:
_ulmt.set_false(event.user_id)
await bt.finish(f"搜索 {keyword} 超时...")
except ServerDisconnectedError:
_ulmt.set_false(event.user_id)
await bt.finish(f"搜索 {keyword} 连接失败")
except Exception as e:
_ulmt.set_false(event.user_id)
await bt.finish(f"bt 其他未知错误..")
logger.error(f"bt 错误 e{e}")
if not send_flag:
await bt.send(f"{keyword} 未搜索到...")
logger.info(f"USER {event.user_id} BT搜索 {keyword}{page}")
_ulmt.set_false(event.user_id)

View File

@ -0,0 +1,57 @@
from .music_163 import get_song_id, get_song_info
from nonebot.adapters.cqhttp import Bot, Event, GroupMessageEvent
from nonebot.typing import T_State
from services.log import logger
from nonebot import on_command
__zx_plugin_name__ = "点歌"
__plugin_usage__ = """
usage
在线点歌
指令
点歌 [歌名]
""".strip()
__plugin_des__ = "为你点播了一首曾经的歌"
__plugin_cmd__ = ["点歌 [歌名]"]
__plugin_type__ = ("一些工具",)
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {
"level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ["点歌"],
}
songpicker = on_command("点歌", priority=5, block=True)
@songpicker.handle()
async def handle_first_receive(bot: Bot, event: Event, state: T_State):
args = str(event.get_message()).strip()
if args:
state["song_name"] = args
@songpicker.got("song_name", prompt="歌名是?")
async def _(bot: Bot, event: Event, state: T_State):
song = state["song_name"]
song_id = await get_song_id(song)
if not song_id:
await songpicker.finish("没有找到这首歌!", at_sender=True)
for _ in range(3):
song_content = [{"type": "music", "data": {"type": 163, "id": song_id}}]
logger.info(
f"(USER {event.user_id}, GROUP "
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
f" 点歌 :{song}"
)
await songpicker.finish(song_content)
else:
await songpicker.finish("网易云繁忙...")

View File

@ -0,0 +1,47 @@
import aiohttp
import json
headers = {"referer": "http://music.163.com"}
cookies = {"appver": "2.0.2"}
async def search_song(song_name: str):
async with aiohttp.ClientSession(
headers=headers, cookies=cookies
) as session:
async with session.post(
f"http://music.163.com/api/search/get/",
data={"s": song_name, "limit": 1, "type": 1, "offset": 0},
) as r:
if r.status != 200:
return None
r = await r.text()
return json.loads(r)
async def get_song_id(songName: str) -> int:
"""
根据用户输入的songName 获取候选songId列表 [默认songId数量5]
"""
r = await search_song(songName)
return r["result"]["songs"][0]["id"]
async def get_song_info(songId: int):
"""
获取歌曲信息
"""
async with aiohttp.ClientSession(
headers=headers, cookies=cookies
) as session:
async with session.post(
f"http://music.163.com/api/song/detail/?id={songId}&ids=%5B{songId}%5D",
) as r:
if r.status != 200:
return None
r = await r.text()
return json.loads(r)

View File

@ -6,9 +6,18 @@ from nonebot.rule import to_me
from nonebot.permission import SUPERUSER
__plugin_name__ = "自我检查 [Hidden]"
__zx_plugin_name__ = "服务器自我检查 [Superuser]"
__plugin_usage__ = """
usage
查看服务器当前状态
指令
自检
"""
__plugin_des__ = "查看服务器当前状态"
__plugin_cmd__ = ["自检/check"]
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_usage__ = "用法:自检"
check = Check()

View File

@ -12,9 +12,29 @@ import platform
import os
update_zhenxun = on_command('检查更新真寻', permission=SUPERUSER, priority=1, block=True)
__zx_plugin_name__ = "自动更新 [Superuser]"
__plugin_usage__ = """
usage
检查更新真寻最新版本包括了自动更新
指令
检查更新真寻
重启
""".strip()
__plugin_des__ = "就算是真寻也会成长的"
__plugin_cmd__ = ["检查更新真寻", "重启"]
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
restart = on_command('重启', aliases={'restart'}, permission=SUPERUSER, rule=to_me(), priority=1, block=True)
update_zhenxun = on_command("检查更新真寻", permission=SUPERUSER, priority=1, block=True)
restart = on_command(
"重启",
aliases={"restart"},
permission=SUPERUSER,
rule=to_me(),
priority=1,
block=True,
)
@update_zhenxun.handle()
@ -22,40 +42,38 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
try:
code, error = await check_update(bot)
if error:
logger.error(f'更新真寻未知错误 {error}')
logger.error(f"更新真寻未知错误 {error}")
await bot.send_private_msg(
user_id=int(list(bot.config.superusers)[0]),
message=f'更新真寻未知错误 {error}'
user_id=int(list(bot.config.superusers)[0]), message=f"更新真寻未知错误 {error}"
)
except Exception as e:
logger.error(f'更新真寻未知错误 {type(e)}{e}')
logger.error(f"更新真寻未知错误 {type(e)}{e}")
await bot.send_private_msg(
user_id=int(list(bot.config.superusers)[0]),
message=f'更新真寻未知错误 {type(e)}{e}'
message=f"更新真寻未知错误 {type(e)}{e}",
)
else:
if code == 200:
await bot.send_private_msg(
user_id=int(list(bot.config.superusers)[0]),
message=f'更新完毕,请重启真寻....'
user_id=int(list(bot.config.superusers)[0]), message=f"更新完毕,请重启真寻...."
)
@restart.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
if str(platform.system()).lower() == 'windows':
await restart.finish('暂无windows重启脚本...')
if str(platform.system()).lower() == "windows":
await restart.finish("暂无windows重启脚本...")
@restart.got('flag', prompt='确定是否重启真寻?(重启失败咱们将失去联系,请谨慎!)')
@restart.got("flag", prompt="确定是否重启真寻?(重启失败咱们将失去联系,请谨慎!)")
async def _(bot: Bot, event: MessageEvent, state: T_State):
flag = state['flag']
if flag.lower() in ['true', '', '', '确定', '确定是']:
await restart.send('开始重启真寻..请稍等...')
open('is_restart', 'w')
os.system('./restart.sh')
flag = state["flag"]
if flag.lower() in ["true", "", "", "确定", "确定是"]:
await restart.send("开始重启真寻..请稍等...")
open("is_restart", "w")
os.system("./restart.sh")
else:
await restart.send('已取消操作...')
await restart.send("已取消操作...")
@scheduler.scheduled_job(
@ -69,7 +87,10 @@ async def _():
_version_file = Path() / "__version__"
if _version_file.exists():
_version = (
open(_version_file, "r", encoding="utf8").readline().split(":")[-1].strip()
open(_version_file, "r", encoding="utf8")
.readline()
.split(":")[-1]
.strip()
)
data = await get_latest_version_data()
if data:
@ -78,24 +99,21 @@ async def _():
bot = get_bot()
await bot.send_private_msg(
user_id=int(list(bot.config.superusers)[0]),
message=f'检测到真寻版本更新\n'
f'当前版本:{_version},最新版本:{latest_version}\n'
f'尝试自动更新...'
message=f"检测到真寻版本更新\n"
f"当前版本:{_version},最新版本:{latest_version}\n"
f"尝试自动更新...",
)
try:
code = await check_update(bot)
except Exception as e:
logger.error(f'更新真寻未知错误 {type(e)}{e}')
logger.error(f"更新真寻未知错误 {type(e)}{e}")
await bot.send_private_msg(
user_id=int(list(bot.config.superusers)[0]),
message=f'更新真寻未知错误 {type(e)}{e}\n'
message=f"更新真寻未知错误 {type(e)}{e}\n",
)
else:
if code == 200:
await bot.send_private_msg(
user_id=int(list(bot.config.superusers)[0]),
message=f'更新完毕,请重启真寻....'
message=f"更新完毕,请重启真寻....",
)

View File

@ -117,7 +117,6 @@ async def check_update(bot: Bot) -> 'int, str':
user_id=int(list(bot.config.superusers)[0]),
message=f"自动获取真寻版本成功:{latest_version},当前版本为最新版,无需更新...",
)
return 200, ''
else:
logger.warning("自动获取真寻版本失败....")
await bot.send_private_msg(
@ -227,6 +226,6 @@ def check_old_lines(lines: List[str], line: str) -> str:
return line
for l in lines:
if "=" in l and l.split("=")[0].strip() == line.split("=")[0].strip():
if len(l) > len(line):
if l.split("=")[1].strip() == 'None':
return l
return line

View File

@ -5,21 +5,34 @@ from services.log import logger
from asyncio.exceptions import TimeoutError
from utils.message_builder import image
from configs.path_config import IMAGE_PATH
from utils.utils import get_local_proxy
import aiohttp
import aiofiles
import re
__plugin_name__ = "coser"
__plugin_usage__ = "用法发送coser"
__zx_plugin_name__ = "coser"
__plugin_usage__ = """
usage
三次元也不戳嘿嘿嘿
指令
cos/coser
""".strip()
__plugin_des__ = "三次元也不戳,嘿嘿嘿"
__plugin_cmd__ = ["cos/coser"]
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {
"level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ["cos", "coser", "括丝", "COS", "Cos", "cOS", "coS"],
}
coser = on_command(
"cos", aliases={"coser", "括丝", "COS", "Cos", "cOS", "coS"}, priority=5, block=True
)
url = "http://api520.ltd/api/cosplay.php"
url = "http://ovooa.com/API/cosplay/api.php"
@coser.handle()
@ -28,24 +41,29 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
try:
for _ in range(3):
try:
async with session.get(url, timeout=2) as response:
_url = await response.text()
async with session.get(_url, timeout=5, verify_ssl=False) as res:
async with session.get(url, proxy=get_local_proxy(), timeout=2) as response:
_url = (await response.json())['text']
async with session.get(
_url, timeout=5, proxy=get_local_proxy(), verify_ssl=False
) as res:
if res.status == 200:
async with aiofiles.open(f'{IMAGE_PATH}/temp/{event.user_id}_coser.jpg', 'wb') as f:
async with aiofiles.open(
f"{IMAGE_PATH}/temp/{event.user_id}_coser.jpg", "wb"
) as f:
await f.write(await res.read())
logger.info(
f"(USER {event.user_id}, "
f"GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
f" 发送COSER"
)
await coser.send(image(f'{event.user_id}_coser.jpg', 'temp'))
await coser.send(
image(f"{event.user_id}_coser.jpg", "temp")
)
break
except TimeoutError:
except (TimeoutError, KeyError):
pass
else:
await coser.send('你cos给我看')
await coser.send("你cos给我看")
except Exception as e:
await coser.send('发生了预料之外的错误..请稍后再试或联系管理员修复...')
logger.error(f'coser 发送了未知错误 {type(e)}{e}')
await coser.send("发生了预料之外的错误..请稍后再试或联系管理员修复...")
logger.error(f"coser 发送了未知错误 {type(e)}{e}")

View File

@ -1,29 +0,0 @@
from pathlib import Path
from services.db_context import db
from asyncpg.exceptions import DuplicateColumnError
import nonebot
driver = nonebot.get_driver()
@driver.on_startup
async def _init_database():
file = Path() / 'plugins' / 'database_scripts.py'
if file.exists():
update_sql = [
'ALTER TABLE russian_users ADD winning_streak Integer default 0;',
'ALTER TABLE russian_users ADD losing_streak Integer default 0;',
'ALTER TABLE russian_users ADD max_winning_streak Integer default 0;',
'ALTER TABLE russian_users ADD max_losing_streak Integer default 0;',
'ALTER TABLE group_info_users ADD uid Integer default 0;'
]
for sql in update_sql:
try:
query = db.text(sql)
await db.first(query)
except DuplicateColumnError:
pass
file.unlink()

View File

@ -8,9 +8,46 @@ from services.log import logger
from utils.message_builder import at
__plugin_name__ = "联系管理员"
__plugin_usage__ = "用法:滴滴滴- [消息]"
__zx_plugin_name__ = "联系管理员"
__plugin_usage__ = """
usage
有什么话想对管理员说嘛
指令
[滴滴滴]/滴滴滴- ?[文本] ?[图片]
示例滴滴滴- 我喜欢你
""".strip()
__plugin_superuser_usage__ = """
superuser usage
管理员对消息的回复
指令[以下qq与group均为乱打]
/t: 查看当前存储的消息
/t [qq] [group] [文本]: 在group回复指定用户
/t [qq] [文本]: 私聊用户
/t -1 [group] [文本]: 在group内发送消息
/t [id] [文本]: 回复指定id的对话id在 /t 中获取
示例/t 73747222 32848432 你好啊
示例/t 73747222 你好不好
示例/t -1 32848432 我不太好
示例/t 0 我收到你的话了
"""
__plugin_des__ = "跨越空间与时间跟管理员对话"
__plugin_cmd__ = [
"滴滴滴-/[滴滴滴] ?[文本] ?[图片]",
"/t [_superuser]",
"t [qq] [group] [文本] [_superuser]",
"/t [qq] [文本] [_superuser]",
"/t -1 [group] [_superuser]",
"/t [id] [文本] [_superuser]",
]
__plugin_type__ = ("联系管理员",)
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {
"level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ["滴滴滴-", "滴滴滴"],
}
dialogue_data = {}
@ -57,7 +94,7 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
"user_id": event.user_id,
"group_id": group_id,
"group_name": group_name,
"msg": f'{text} {img_msg}',
"msg": f"{text} {img_msg}",
}
# print(dialogue_data)
logger.info(f"Q{uid}@群{group_id} 联系管理员:{coffee} text:{text}")
@ -66,22 +103,15 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
@reply.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = get_message_text(event.json())
if msg in ["帮助"]:
await reply.finish(
f"/t [qq] [group] [text] -> 回复指定用户\n"
f"/t [qq] [text] -> 私聊用户\n"
f"/t -1 [group] -> 在某群发送消息\n"
f"/t [id] [text] -> 回复指定id的对话"
)
if not msg:
result = "*****待回复消息总览*****\n"
for key in dialogue_data.keys():
result += (
f'id{key}\n'
f"id{key}\n"
f'\t昵称:{dialogue_data[key]["nickname"]}({dialogue_data[key]["user_id"]})\n'
f'\t群群:{dialogue_data[key]["group_name"]}({dialogue_data[key]["group_id"]})\n'
f'\t消息:{dialogue_data[key]["msg"]}'
f'\n--------------------\n'
f"\n--------------------\n"
)
await reply.finish(Message(result[:-1]))
msg = msg.split()

View File

@ -1,8 +1,13 @@
from nonebot import on_regex, on_keyword
from nonebot.adapters.cqhttp import Bot, MessageEvent, Message
from nonebot.adapters.cqhttp import Bot, MessageEvent, Message, GroupMessageEvent
from nonebot.permission import SUPERUSER
from nonebot.typing import T_State
from .genshin_handle import genshin_draw, update_genshin_info, reset_count, reload_genshin_pool
from .genshin_handle import (
genshin_draw,
update_genshin_info,
reset_count,
reload_genshin_pool,
)
from .prts_handle import update_prts_info, prts_draw, reload_prts_pool
from .pretty_handle import update_pretty_info, pretty_draw, reload_pretty_pool
from .guardian_handle import update_guardian_info, guardian_draw
@ -13,52 +18,164 @@ from .onmyoji_handle import update_onmyoji_info, onmyoji_draw
from .update_game_info import update_info
from .util import is_number, check_num
from .rule import is_switch
from .config import PRTS_FLAG, PRETTY_FLAG, GUARDIAN_FLAG, GENSHIN_FLAG, PCR_FLAG, AZUR_FLAG, FGO_FLAG, ONMYOJI_FLAG
from .config import (
PRTS_FLAG,
PRETTY_FLAG,
GUARDIAN_FLAG,
GENSHIN_FLAG,
PCR_FLAG,
AZUR_FLAG,
FGO_FLAG,
ONMYOJI_FLAG,
)
from .async_update_game_info import async_update_game
import re
import asyncio
from utils.utils import scheduler
from services.log import logger
__plugin_name__ = '游戏抽卡'
__zx_plugin_name__ = "游戏抽卡"
__plugin_usage__ = """
usage
模拟赛马娘原神明日方舟坎公骑冠剑公主连结(/)碧蓝航线FGO阴阳师进行抽卡
指令
原神[1-300]: 原神常驻池
原神角色[1-300]: 原神角色UP池子
原神武器[1-300]: 原神武器UP池子
重置原神抽卡: 清空当前卡池的抽卡次数[即从0开始计算UP概率]
方舟[1-300]: 方舟卡池当有当期UP时指向UP池
赛马娘[1-200]: 赛马娘卡池当有当期UP时指向UP池
坎公骑冠剑[1-300]: 坎公骑冠剑卡池当有当期UP时指向UP池
pcr/公主连接[1-300]: 公主连接卡池
碧蓝航线/碧蓝[重型/轻型/特型][1-300]: 碧蓝航线重型/轻型/特型卡池
fgo[1-300]: fgo卡池
阴阳师[1-300]: 阴阳师卡池
* 以上指令可以通过 XX一井 来指定最大抽取数量 *
* 示例原神一井 *
""".strip()
__plugin_superuser_usage__ = """
usage
卡池方面的更新
指令
更新方舟信息
重载方舟卡池
更新原神信息
重载原神卡池
更新赛马娘信息
重载赛马娘卡池
更新坎公骑冠剑信息
更新碧蓝航线信息
更新fgo信息
更新阴阳师信息
""".strip()
__plugin_des__ = "就算是模拟抽卡也不能改变自己是个非酋"
__plugin_cmd__ = [
"原神[1-300]抽",
"原神角色[1-300]抽",
"原神武器[1-300]抽",
"重置原神抽卡",
"方舟[1-300]抽",
"赛马娘[1-200]抽",
"坎公骑冠剑[1-300]抽",
"pcr/公主连接[1-300]抽",
"fgo[1-300]抽",
"阴阳师[1-300]抽",
"更新方舟信息 [_superuser]",
"重载方舟卡池 [_superuser]",
"更新原神信息 [_superuser]",
"重载原神卡池 [_superuser]",
"更新赛马娘信息 [_superuser]",
"重载赛马娘卡池 [_superuser]",
"更新坎公骑冠剑信息 [_superuser]",
"更新碧蓝航线信息 [_superuser]",
"更新fgo信息 [_superuser]",
"更新阴阳师信息 [_superuser]",
]
__plugin_type__ = ("抽卡相关", 1)
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {
"level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ["游戏抽卡", "抽卡"],
}
prts = on_regex(r'.*?方舟[1-9|一][0-9]{0,2}[抽|井]', rule=is_switch('prts'), priority=5, block=True)
prts_update = on_keyword({'更新方舟信息', '更新明日方舟信息'}, permission=SUPERUSER, priority=1, block=True)
prts_up_reload = on_keyword({'重载方舟卡池'}, priority=1, block=True)
prts = on_regex(
r".*?方舟[1-9|一][0-9]{0,2}[抽|井]", rule=is_switch("prts"), priority=5, block=True
)
prts_update = on_keyword(
{"更新方舟信息", "更新明日方舟信息"}, permission=SUPERUSER, priority=1, block=True
)
prts_up_reload = on_keyword({"重载方舟卡池"}, priority=1, block=True)
genshin = on_regex('.*?原神(武器|角色)?池?[1-9|一][0-9]{0,2}[抽|井]', rule=is_switch('genshin'), priority=5, block=True)
genshin_update = on_keyword({'更新原神信息'}, permission=SUPERUSER, priority=1, block=True)
genshin_reset = on_keyword({'重置原神抽卡'}, priority=1, block=True)
genshin_up_reload = on_keyword({'重载原神卡池'}, priority=1, block=True)
genshin = on_regex(
".*?原神(武器|角色)?池?[1-9|一][0-9]{0,2}[抽|井]",
rule=is_switch("genshin"),
priority=5,
block=True,
)
genshin_update = on_keyword({"更新原神信息"}, permission=SUPERUSER, priority=1, block=True)
genshin_reset = on_keyword({"重置原神抽卡"}, priority=1, block=True)
genshin_up_reload = on_keyword({"重载原神卡池"}, priority=1, block=True)
pretty = on_regex('.*?马娘卡?[1-9|一][0-9]{0,2}[抽|井]', rule=is_switch('pretty'), priority=5, block=True)
pretty_update = on_keyword({'更新马娘信息', '更新赛马娘信息'}, permission=SUPERUSER, priority=1, block=True)
pretty_up_reload = on_keyword({'重载赛马娘卡池'}, priority=1, block=True)
pretty = on_regex(
".*?马娘卡?[1-9|一][0-9]{0,2}[抽|井]", rule=is_switch("pretty"), priority=5, block=True
)
pretty_update = on_keyword(
{"更新马娘信息", "更新赛马娘信息"}, permission=SUPERUSER, priority=1, block=True
)
pretty_up_reload = on_keyword({"重载赛马娘卡池"}, priority=1, block=True)
guardian = on_regex('.*?坎公骑冠剑武?器?[1-9|一][0-9]{0,2}[抽|井]', rule=is_switch('guardian'), priority=5, block=True)
guardian_update = on_keyword({'更新坎公骑冠剑信息'}, permission=SUPERUSER, priority=1, block=True)
guardian = on_regex(
".*?坎公骑冠剑武?器?[1-9|一][0-9]{0,2}[抽|井]",
rule=is_switch("guardian"),
priority=5,
block=True,
)
guardian_update = on_keyword(
{"更新坎公骑冠剑信息"}, permission=SUPERUSER, priority=1, block=True
)
pcr = on_regex('.*?(pcr|公主连结|公主连接|公主链接|公主焊接)[1-9|一][0-9]{0,2}[抽|井]', rule=is_switch('pcr'), priority=5, block=True)
pcr_update = on_keyword({'更新pcr信息', '更新公主连结信息'}, permission=SUPERUSER, priority=1, block=True)
pcr = on_regex(
".*?(pcr|公主连结|公主连接|公主链接|公主焊接)[1-9|一][0-9]{0,2}[抽|井]",
rule=is_switch("pcr"),
priority=5,
block=True,
)
pcr_update = on_keyword(
{"更新pcr信息", "更新公主连结信息"}, permission=SUPERUSER, priority=1, block=True
)
azur = on_regex('.*?碧蓝航?线?(轻型|重型|特型)池?[1-9|一][0-9]{0,2}[抽]', rule=is_switch('azur'), priority=5, block=True)
azur_update = on_keyword({'更新碧蓝信息', '更新碧蓝航线信息'}, permission=SUPERUSER, priority=1, block=True)
azur = on_regex(
".*?碧蓝航?线?(轻型|重型|特型)池?[1-9|一][0-9]{0,2}[抽]",
rule=is_switch("azur"),
priority=5,
block=True,
)
azur_update = on_keyword(
{"更新碧蓝信息", "更新碧蓝航线信息"}, permission=SUPERUSER, priority=1, block=True
)
fgo = on_regex('.*?fgo[1-9|一][0-9]{0,2}[抽]', rule=is_switch('fgo'), priority=5, block=True)
fgo_update = on_keyword({'更新fgo信息'}, permission=SUPERUSER, priority=1, block=True)
fgo = on_regex(
".*?fgo[1-9|一][0-9]{0,2}[抽]", rule=is_switch("fgo"), priority=5, block=True
)
fgo_update = on_keyword({"更新fgo信息"}, permission=SUPERUSER, priority=1, block=True)
onmyoji = on_regex('.*?阴阳师[1-9|一][0-9]{0,2}[抽]', rule=is_switch('onmyoji'), priority=5, block=True)
onmyoji_update = on_keyword({'更新阴阳师信息'}, permission=SUPERUSER, priority=1, block=True)
onmyoji = on_regex(
".*?阴阳师[1-9|一][0-9]{0,2}[抽]", rule=is_switch("onmyoji"), priority=5, block=True
)
onmyoji_update = on_keyword({"更新阴阳师信息"}, permission=SUPERUSER, priority=1, block=True)
@prts.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = str(event.get_message()).strip()
if msg in ['方舟一井', '方舟1井']:
if msg in ["方舟一井", "方舟1井"]:
num = 300
else:
rmsg = re.search(r'.*?方舟(.*)抽', msg)
rmsg = re.search(r".*?方舟(.*)抽", msg)
if rmsg:
num, flag = check_num(rmsg.group(1), 300)
if not flag:
@ -67,29 +184,30 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
return
await prts.send(await prts_draw(int(num)), at_sender=True)
logger.info(
f"(USER {event.user_id}, GROUP {event.group_id if event.message_type != 'private' else 'private'}) 方舟 {num}")
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) 方舟 {num}"
)
@prts_up_reload.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
text = await reload_prts_pool()
await prts_up_reload.finish(Message(f'重载完成!\n{text}'))
await prts_up_reload.finish(Message(f"重载完成!\n{text}"))
@genshin.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = str(event.get_message()).strip()
rmsg = re.search(r'.*?原神(武器|角色)?池?(.*)[抽|井]', msg)
rmsg = re.search(r".*?原神(武器|角色)?池?(.*)[抽|井]", msg)
if rmsg:
pool_name = rmsg.group(1)
if pool_name == '武器':
pool_name = 'arms'
elif pool_name == '角色':
pool_name = 'char'
if pool_name == "武器":
pool_name = "arms"
elif pool_name == "角色":
pool_name = "char"
else:
pool_name = ''
pool_name = ""
num = rmsg.group(2)
if msg.find('一井') != -1 or msg.find('1井') != -1:
if msg.find("一井") != -1 or msg.find("1井") != -1:
num = 180
else:
num, flag = check_num(num, 180)
@ -97,41 +215,44 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
await genshin.finish(num, at_sender=True)
else:
return
await genshin.send(await genshin_draw(event.user_id, int(num), pool_name), at_sender=True)
await genshin.send(
await genshin_draw(event.user_id, int(num), pool_name), at_sender=True
)
logger.info(
f"(USER {event.user_id}, GROUP {event.group_id if event.message_type != 'private' else 'private'}) 原神 {num}")
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) 原神 {num}"
)
@genshin_up_reload.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
text = await reload_genshin_pool()
await genshin_reset.finish(Message(f'重载成功!\n{text}'))
await genshin_reset.finish(Message(f"重载成功!\n{text}"))
@genshin_reset.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
reset_count(event.user_id)
await genshin_reset.send('重置了原神抽卡次数', at_sender=True)
await genshin_reset.send("重置了原神抽卡次数", at_sender=True)
@pretty.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = str(event.get_message()).strip()
if msg.find('1井') != -1 or msg.find('一井') != -1:
if msg.find("1井") != -1 or msg.find("一井") != -1:
num = 200
if msg.find("") == -1:
pool_name = 'char'
pool_name = "char"
else:
pool_name = 'card'
pool_name = "card"
else:
rmsg = re.search(r'.*?马娘(.*)抽', msg)
rmsg = re.search(r".*?马娘(.*)抽", msg)
if rmsg:
num = rmsg.group(1)
if num[0] == '':
if num[0] == "":
num = num[1:]
pool_name = 'card'
pool_name = "card"
else:
pool_name = 'char'
pool_name = "char"
num, flag = check_num(num, 200)
if not flag:
await pretty.finish(num, at_sender=True)
@ -139,30 +260,31 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
return
await pretty.send(await pretty_draw(int(num), pool_name), at_sender=True)
logger.info(
f"(USER {event.user_id}, GROUP {event.group_id if event.message_type != 'private' else 'private'}) 赛马娘 {num}")
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) 赛马娘 {num}"
)
@pretty_up_reload.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
text = await reload_pretty_pool()
await genshin_reset.finish(Message(f'重载成功!\n{text}'))
await genshin_reset.finish(Message(f"重载成功!\n{text}"))
@guardian.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = str(event.get_message()).strip()
pool_name = 'char'
if msg.find('1井') != -1 or msg.find('一井') != -1:
pool_name = "char"
if msg.find("1井") != -1 or msg.find("一井") != -1:
num = 300
if msg.find('武器') != -1:
pool_name = 'arms'
if msg.find("武器") != -1:
pool_name = "arms"
else:
rmsg = re.search(r'.*?坎公骑冠剑(.*)抽', msg)
rmsg = re.search(r".*?坎公骑冠剑(.*)抽", msg)
if rmsg:
num = rmsg.group(1)
if num.find('武器') != -1:
pool_name = 'arms'
num = num.replace('武器', '')
if num.find("武器") != -1:
pool_name = "arms"
num = num.replace("武器", "")
num, flag = check_num(num, 300)
if not flag:
await guardian.finish(num, at_sender=True)
@ -170,16 +292,17 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
return
await guardian.send(await guardian_draw(int(num), pool_name), at_sender=True)
logger.info(
f"(USER {event.user_id}, GROUP {event.group_id if event.message_type != 'private' else 'private'}) 坎公骑冠剑 {num}")
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) 坎公骑冠剑 {num}"
)
@pcr.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = str(event.get_message()).strip()
if msg.find('1井') != -1 or msg.find('一井') != -1:
if msg.find("1井") != -1 or msg.find("一井") != -1:
num = 300
else:
rmsg = re.search(r'.*?(pcr|公主连结)(.*)[抽|井]', msg)
rmsg = re.search(r".*?(pcr|公主连结)(.*)[抽|井]", msg)
if rmsg:
num, flag = check_num(rmsg.group(2), 300)
if not flag:
@ -188,13 +311,14 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
return
await pcr.send(await pcr_draw(int(num)), at_sender=True)
logger.info(
f"(USER {event.user_id}, GROUP {event.group_id if event.message_type != 'private' else 'private'}) 公主连结 {num}")
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) 公主连结 {num}"
)
@azur.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = str(event.get_message()).strip()
rmsg = re.search('.*?碧蓝航?线?(轻型|重型|特型)池?(.*)[抽]', msg)
rmsg = re.search(".*?碧蓝航?线?(轻型|重型|特型)池?(.*)[抽]", msg)
if rmsg:
pool_name = rmsg.group(1)
num, flag = check_num(rmsg.group(2), 300)
@ -204,13 +328,14 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
return
await azur.send(await azur_draw(int(num), pool_name), at_sender=True)
logger.info(
f"(USER {event.user_id}, GROUP {event.group_id if event.message_type != 'private' else 'private'}) 碧蓝航线 {num}")
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) 碧蓝航线 {num}"
)
@fgo.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = str(event.get_message()).strip()
rmsg = re.search('.*?fgo(.*)抽', msg)
rmsg = re.search(".*?fgo(.*)抽", msg)
if rmsg:
num, flag = check_num(rmsg.group(1), 300)
if not flag:
@ -219,13 +344,14 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
return
await fgo.send(await fgo_draw(int(num)), at_sender=True)
logger.info(
f"(USER {event.user_id}, GROUP {event.group_id if event.message_type != 'private' else 'private'}) fgo {num}")
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) fgo {num}"
)
@onmyoji.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = str(event.get_message()).strip()
rmsg = re.search('.*?阴阳师(.*)抽', msg)
rmsg = re.search(".*?阴阳师(.*)抽", msg)
if rmsg:
num, flag = check_num(rmsg.group(1), 300)
if not flag:
@ -234,60 +360,61 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
return
await onmyoji.send(await onmyoji_draw(int(num)), at_sender=True)
logger.info(
f"(USER {event.user_id}, GROUP {event.group_id if event.message_type != 'private' else 'private'}) 阴阳师 {num}")
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) 阴阳师 {num}"
)
@prts_update.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
await update_prts_info()
await prts_update.finish('更新完成!')
await prts_update.finish("更新完成!")
@genshin_update.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
await update_genshin_info()
await genshin_update.finish('更新完成!')
await genshin_update.finish("更新完成!")
@pretty_update.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
await update_pretty_info()
await genshin_update.finish('更新完成!')
await genshin_update.finish("更新完成!")
@guardian_update.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
await update_guardian_info()
await genshin_update.finish('更新完成!')
await genshin_update.finish("更新完成!")
@pcr_update.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
await update_pcr_info()
await genshin_update.finish('更新完成!')
await genshin_update.finish("更新完成!")
@azur_update.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
await update_azur_info()
await genshin_update.finish('更新完成!')
await genshin_update.finish("更新完成!")
@fgo_update.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
await update_fgo_info()
await genshin_update.finish('更新完成!')
await genshin_update.finish("更新完成!")
@onmyoji_update.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
await update_onmyoji_info()
await genshin_update.finish('更新完成!')
await genshin_update.finish("更新完成!")
# 更新资源
@scheduler.scheduled_job(
'cron',
"cron",
hour=4,
minute=1,
)
@ -310,42 +437,40 @@ async def _():
if ONMYOJI_FLAG:
tasks.append(asyncio.ensure_future(update_onmyoji_info()))
await asyncio.gather(*tasks)
logger.info('draw_card 抽卡自动更新完成...')
logger.info("draw_card 抽卡自动更新完成...")
# 每天四点重载方舟up卡池
@scheduler.scheduled_job(
'cron',
"cron",
hour=4,
minute=1,
)
async def _():
if PRTS_FLAG:
await reload_prts_pool()
logger.info('自动重载方舟卡池UP成功')
logger.info("自动重载方舟卡池UP成功")
# 每天四点重载赛马娘up卡池
@scheduler.scheduled_job(
'cron',
"cron",
hour=4,
minute=1,
)
async def _():
if PRETTY_FLAG:
await reload_pretty_pool()
logger.info('自动重载赛马娘UP成功')
logger.info("自动重载赛马娘UP成功")
# 每天下午六点点重载原神up卡池
@scheduler.scheduled_job(
'cron',
"cron",
hour=18,
minute=1,
)
async def _():
if PRTS_FLAG:
await reload_genshin_pool()
logger.info('自动重载原神卡池UP成功')
logger.info("自动重载原神卡池UP成功")

View File

@ -1,5 +1,6 @@
from typing import Any
from .config import DATA_PATH
from utils.utils import is_number
from pathlib import Path
try:
import ujson as json
@ -65,11 +66,12 @@ def init_game_pool(game: str, data: dict, Operator: Any):
tmp_lst.append(Operator(name=data[key]['名称'], star=int(data[key]['星级']), limited=limited))
if game == 'azur':
for key in data.keys():
limited = False
if '可以建造' not in data[key]['获取途径']:
limited = True
tmp_lst.append(Operator(name=data[key]['名称'], star=int(data[key]['星级']),
limited=limited, itype=data[key]['类型']))
if is_number(data[key]['星级']):
limited = False
if '可以建造' not in data[key]['获取途径']:
limited = True
tmp_lst.append(Operator(name=data[key]['名称'], star=int(data[key]['星级']),
limited=limited, itype=data[key]['类型']))
if game in ['fgo', 'fgo_card']:
for key in data.keys():
limited = False

View File

@ -1,42 +1,37 @@
from nonebot.rule import Rule
from nonebot.adapters.cqhttp import Bot, MessageEvent
from nonebot.typing import T_State
from .config import GENSHIN_FLAG, PRTS_FLAG, PRETTY_FLAG, GUARDIAN_FLAG, PCR_FLAG, AZUR_FLAG, FGO_FLAG, ONMYOJI_FLAG
from .config import (
GENSHIN_FLAG,
PRTS_FLAG,
PRETTY_FLAG,
GUARDIAN_FLAG,
PCR_FLAG,
AZUR_FLAG,
FGO_FLAG,
ONMYOJI_FLAG,
)
def is_switch(game_name: str) -> Rule:
async def _is_switch(bot: Bot, event: MessageEvent, state: T_State) -> bool:
if game_name == 'prts':
if game_name == "prts":
return PRTS_FLAG
if game_name == 'genshin':
if game_name == "genshin":
return GENSHIN_FLAG
if game_name == 'pretty':
if game_name == "pretty":
return PRETTY_FLAG
if game_name == 'guardian':
if game_name == "guardian":
return GUARDIAN_FLAG
if game_name == 'pcr':
if game_name == "pcr":
return PCR_FLAG
if game_name == 'azur':
if game_name == "azur":
return AZUR_FLAG
if game_name == 'fgo':
if game_name == "fgo":
return FGO_FLAG
if game_name == 'onmyoji':
if game_name == "onmyoji":
return ONMYOJI_FLAG
else:
return False
return Rule(_is_switch)

View File

@ -83,6 +83,8 @@ async def _last_check(data: dict, game_name: str, session: aiohttp.ClientSession
'-舰娘头像外框精锐.png',
'https://patchwiki.biligame.com/images/blhx/thumb/a/a2/ptog1j220x5q02hytpwc8al7f229qk9.png/60px-'
'舰娘头像外框超稀有.png'
'https://patchwiki.biligame.com/images/blhx/thumb/0/0f/n28p7p3opfn5mhgjyio55ljsllhknwz.png/60px-'
'舰娘头像外框精锐META.png'
]:
await download_img(url, 'azur', f'{idx}_star')
idx += 1
@ -135,7 +137,7 @@ async def retrieve_char_data(char: bs4.element.Tag, game_name: str, data: dict,
member_dict['头像'] = unquote(str(avatar_img['src']).split(' ')[-2])
except TypeError:
member_dict['头像'] = "img link not find..."
logger(f'{member_dict["名称"]} 图片缺失....')
logger.warning(f'{member_dict["名称"]} 图片缺失....')
star = char.find('div').find('img')['alt']
if star == '舰娘头像外框普通.png':
star = 1
@ -147,7 +149,9 @@ async def retrieve_char_data(char: bs4.element.Tag, game_name: str, data: dict,
star = 4
elif star == '舰娘头像外框海上传奇.png':
star = 5
elif star in ['舰娘头像外框最高方案.png', '舰娘头像外框决战方案.png', '舰娘头像外框超稀有META.png']:
elif star in ['舰娘头像外框最高方案.png', '舰娘头像外框决战方案.png', '舰娘头像外框超稀有META.png', '舰娘头像外框精锐META.png']:
star = 6
else:
star = 6
member_dict['星级'] = star
member_dict['类型'] = azur_type[str(index)]

View File

@ -4,13 +4,28 @@ 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
from models.group_remind import GroupRemind
from nonebot.adapters.cqhttp.exception import ActionFailed
__plugin_name__ = "epic免费游戏提醒"
__plugin_usage__ = "用法发送epic"
from utils.manager import group_manager
__zx_plugin_name__ = "epic免费游戏"
__plugin_usage__ = """
usage
可以不玩不能没有每日白嫖
指令
epic
""".strip()
__plugin_des__ = "可以不玩,不能没有,每日白嫖"
__plugin_cmd__ = ["epic"]
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {
"level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ["epic"],
}
__plugin_task__ = {
'epic_free_game': 'epic免费游戏'
}
epic = on_command("epic", priority=5, block=True)
@ -33,13 +48,13 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
)
async def _():
bot = get_bot()
gl = await bot.get_group_list(self_id=bot.self_id)
gl = await bot.get_group_list()
gl = [g["group_id"] for g in gl]
for g in gl:
if await GroupRemind.get_status(g, "epic"):
result, code = await get_epic_game()
if code == 200:
try:
if await group_manager.check_group_task_status(g, 'epic_free_game'):
try:
result, code = await get_epic_game()
if code == 200:
await bot.send_group_msg(group_id=g, message=result)
except ActionFailed:
logger.error(f"{g} epic免费游戏推送错误")
except Exception as e:
logger.error(f"GROUP {g} epic免费游戏推送错误 {type(e)}: {e}")

View File

@ -6,12 +6,24 @@ from utils.message_builder import share
from services.log import logger
__plugin_name = "假消息"
__plugin_usage__ = (
"用法:\n格式:假消息 [网址] [标题] [内容](可省) [图片](可省)\n"
"示例:假消息 www.4399.com 我喜欢萝莉 为什么我喜欢... [图片]"
)
__zx_plugin_name__ = "构造分享消息"
__plugin_usage__ = """
usage
自定义的分享消息构造
指令
假消息 [网址] [标题] ?[内容] ?[图片]
示例假消息 www.4399.com 我喜欢萝莉 为什么我喜欢... [图片]
""".strip()
__plugin_des__ = "自定义的分享消息构造"
__plugin_cmd__ = ["假消息 [网址] [标题] ?[内容] ?[图片]"]
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {
"level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ["假消息"],
}
fake_msg = on_command("假消息", priority=5, block=True)

View File

@ -11,6 +11,19 @@ import aiohttp
import aiofiles
from asyncio.exceptions import TimeoutError
from configs.config import FUDU_PROBABILITY
from utils.manager import group_manager
__zx_plugin_name__ = "复读"
__plugin_usage__ = """
usage
重复3次相同的消息时会复读
""".strip()
__plugin_des__ = "群友的本质是什么?是复读机哒!"
__plugin_type__ = ("被动相关",)
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_task__ = {"fudu": "复读"}
class Fudu:
@ -59,7 +72,11 @@ fudu = on_message(permission=GROUP, priority=9)
@fudu.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
if event.is_tome() or state["_prefix"]["raw_command"]:
if (
event.is_tome()
or state["_prefix"]["raw_command"]
or not await group_manager.check_group_task_status(event.group_id, "fudu")
):
return
if get_message_text(event.json()):
if get_message_text(event.json()).find("@可爱的小真寻") != -1:

View File

@ -0,0 +1,3 @@
import nonebot
nonebot.load_plugins("plugins/genshin")

View File

@ -1,25 +1,44 @@
from .alc import get_almanac_base64_str, load_data
import os
from utils.utils import get_bot, scheduler
from nonebot import on_command
from models.level_user import LevelUser
from nonebot.typing import T_State
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent, MessageEvent
from utils.message_builder import image
from services.log import logger
from models.group_remind import GroupRemind
from configs.path_config import IMAGE_PATH
from .data_source import get_alc_image
from utils.manager import group_manager
from pathlib import Path
FILE_PATH = os.path.dirname(__file__)
__zx_plugin_name__ = "原神老黄历"
__plugin_usage__ = """
usage
有时候也该迷信一回特别是运气方面
指令
原神黄历
""".strip()
__plugin_des__ = "有时候也该迷信一回!特别是运气方面"
__plugin_cmd__ = ["原神黄历"]
__plugin_type__ = ("原神相关",)
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {
"level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ["原神黄历", "原神老黄历"],
}
__plugin_task__ = {"genshin_alc": "原神黄历提醒"}
almanac = on_command("原神黄历", priority=5, block=True)
reload = on_command("重载原神黄历数据", priority=5, block=True)
ALC_PATH = Path(IMAGE_PATH) / "genshin" / "alc"
ALC_PATH.mkdir(parents=True, exist_ok=True)
@almanac.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
almanac_base64 = get_almanac_base64_str()
mes = image(b64=almanac_base64) + "\n ※ 黄历数据来源于 genshin.pub"
alc_img = await get_alc_image(ALC_PATH)
mes = alc_img + "\n ※ 黄历数据来源于 genshin.pub"
await almanac.send(mes)
logger.info(
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
@ -27,13 +46,6 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
)
@reload.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
if await LevelUser.check_level(event.user_id, event.group_id, 5):
load_data()
await reload.send("重载成功")
@scheduler.scheduled_job(
"cron",
hour=10,
@ -42,10 +54,11 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
async def _():
# 每日提醒
bot = get_bot()
gl = await bot.get_group_list(self_id=bot.self_id)
gl = [g["group_id"] for g in gl]
almanac_base64 = get_almanac_base64_str()
mes = image(b64=almanac_base64) + "\n ※ 黄历数据来源于 genshin.pub"
for gid in gl:
if await GroupRemind.get_status(gid, "almanac"):
await bot.send_group_msg(group_id=int(gid), message=mes)
if bot:
gl = await bot.get_group_list()
gl = [g["group_id"] for g in gl]
alc_img = await get_alc_image(ALC_PATH)
mes = alc_img + "\n ※ 黄历数据来源于 genshin.pub"
for gid in gl:
if await group_manager.check_group_task_status(gid, "genshin_alc"):
await bot.send_group_msg(group_id=int(gid), message=mes)

View File

@ -1,123 +0,0 @@
from PIL import Image, ImageDraw, ImageFont
from io import BytesIO
import os
import json
import random
import base64
import time
FILE_PATH = os.path.dirname(__file__)
FONT_PATH = os.path.join(FILE_PATH, "汉仪文黑.ttf")
data = {} # configs.json里的数据
almanac_data = {
# 生成的黄历base64字符串和黄历更新日期
"date": "",
"almanac_base64_str": ""
}
chinese = {"0": "", "1": "", "2": "", "3": "", "4": "", "5": "", "6": "", "7": "", "8": "", "9": ""}
def month_to_chinese(month: str):
# 把日期数字转成中文数字
m = int(month)
if m < 10:
return chinese[month[-1]]
elif m < 20:
return "" + chinese[month[-1]]
else:
return chinese[month[0]] + "" + chinese[month[-1]]
def load_data():
# 载入config.json文件的数据
global data
with open(os.path.join(FILE_PATH, 'config.json'), 'r', encoding='UTF-8') as f:
data = json.load(f)
almanac_data["date"] = ""
almanac_data["almanac_base64_str"] = ""
load_data()
def seed_random_list(seed: str, l: list):
# 使用随机种子随机选择列表中的元素,相同的种子和列表将返回同样的输出
seed = seed + str(l)
random.seed(seed)
index = random.random() * len(l)
return l[int(index)]
def generate_almanac():
# 生成黄历图片然后转换成base64保存到 almanac_data["almanac_base64_str"]
seed = time.strftime("%Y-%m-%d")
offset = 1
today_luck = []
l = list(data.keys())
while len(today_luck) < 6:
# 随机6个不同的运势放到 today_luck
r = seed_random_list(str(offset) + seed, l)
if r in today_luck:
offset += 1
else:
today_luck.append(r)
back = Image.open(os.path.join(FILE_PATH, "back.png"))
year = time.strftime("%Y")
month = month_to_chinese(time.strftime("%m")) + ""
day = month_to_chinese(time.strftime("%d")) + ""
draw = ImageDraw.Draw(back)
draw.text((118, 165), year, fill="#8d7650ff", font=ImageFont.truetype(FONT_PATH, size=30), anchor="mm",
align="center")
draw.text((260, 165), day, fill="#f7f8f2ff", font=ImageFont.truetype(FONT_PATH, size=35), anchor="mm",
align="center")
draw.text((410, 165), month, fill="#8d7650ff", font=ImageFont.truetype(FONT_PATH, size=30), anchor="mm",
align="center")
buff = Image.new("RGBA", (325, 160))
debuff = Image.new("RGBA", (325, 160))
buff_draw = ImageDraw.Draw(buff)
debuff_draw = ImageDraw.Draw(debuff)
for i in range(3):
buff_name = today_luck[i]
debuff_name = today_luck[(i + 3)]
buff_effect = seed_random_list(seed, data[buff_name]["buff"])
debuff_effect = seed_random_list(seed, data[debuff_name]["debuff"])
buff_draw.text((0, i * 53), buff_name, fill="#756141ff", font=ImageFont.truetype(FONT_PATH, size=25))
debuff_draw.text((0, i * 53), debuff_name, fill="#756141ff", font=ImageFont.truetype(FONT_PATH, size=25))
buff_draw.text((0, i * 53 + 28), buff_effect, fill="#b5b3acff", font=ImageFont.truetype(FONT_PATH, size=19))
debuff_draw.text((0, i * 53 + 28), debuff_effect, fill="#b5b3acff", font=ImageFont.truetype(FONT_PATH, size=19))
back.paste(buff, (150, 230), buff)
back.paste(debuff, (150, 400), debuff)
bio = BytesIO()
back.save(bio, format='PNG')
base64_str = base64.b64encode(bio.getvalue()).decode()
almanac_data["date"] = time.strftime("%Y-%m-%d")
almanac_data["almanac_base64_str"] = 'base64://' + base64_str
def get_almanac_base64_str():
# if almanac_data["date"] == time.strftime("%Y-%m-%d"):
# return almanac_data["almanac_base64_str"]
# else:
# generate_almanac()
# return almanac_data["almanac_base64_str"]
generate_almanac()
return almanac_data["almanac_base64_str"]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

View File

@ -1,70 +0,0 @@
{
"抽卡":{
"buff": ["欧气满满,十连出金","出金不歪"],
"debuff": ["武器大师","保底出金","金色会是痛苦大剑"]
},
"刷世界boss":{
"buff": ["双攻双爆角斗士"],
"debuff": ["只有保底材料","贪生怕死角斗士"]
},
"刷风本":{
"buff": ["会有极品猎人套","会掉真正的少女心","治疗加成少女头"],
"debuff": ["勇往直前少女心","少女飘摇的杀意","少女暴怒的容颜"]
},
"刷火本":{
"buff": ["魔女帽子火伤杯","暴伤魔女帽!","火伤魔女心!"],
"debuff": ["幡 然 醒 悟","这么阴间的地方真的会有魔女套吗?","不务正业火魔女","会匹配到3个卢姥爷"]
},
"刷岩本":{
"buff": ["悠久的磐岩伴你左右","岩神的庇护常在"],
"debuff": ["防御流星杯,你值得拥有"]
},
"刷宗室":{
"buff": ["物理伤害骑士道,元素精通宗室套"],
"debuff": ["贪生怕死骑士道,物理伤害宗室杯"]
},
"刷冰本":{
"buff": ["双暴词条概率up"],
"debuff": ["防御力船帽,无人可及"]
},
"刷雷本":{
"buff": ["愿雷鸟伴你左右"],
"debuff": ["来表演一个只掉平雷套的绝活","风神忽悠雷凶兆"]
},
"锄大地":{
"buff": ["会掉一大堆紫色材料"],
"debuff": ["深渊法师爱你哟","会被冰水法控到死"]
},
"挖矿":{
"buff": ["开矿出双材料"],
"debuff": ["去别人世界会被拒"]
},
"刷天赋本":{
"buff": ["金色!我看到了金色的书!"],
"debuff": ["2蓝2绿不会变"]
},
"刷突破材料":{
"buff": ["金色!我看到了金色的材料!"],
"debuff": ["2蓝2绿不会变"]
},
"升级圣遗物":{
"buff": ["稀有词条跳跳跳","会双爆拉满"],
"debuff": ["女 仆 狂 喜","无中生有防御力","生命拉满","完美避开双爆"]
},
"打风魔龙":{
"buff": ["看我一箭一个风魔鸡","今天特瓦林可以给想要的突破材料","5金加原胚"],
"debuff": ["会不小心掉下平台","不小心被地板烫死了"]
},
"打狼王":{
"buff": ["今天安德琉斯的心情不错可以py一下","5金加原胚"],
"debuff": ["狼尾巴*1"]
},
"打公子":{
"buff": ["今天可以和公子py想要的突破材料","5金加原胚"],
"debuff": ["要角没有!要命一条!"]
}
}

View File

@ -0,0 +1,43 @@
from utils.browser import get_browser
from utils.message_builder import image
from datetime import datetime
from services.log import logger
from pathlib import Path
import os
url = "https://genshin.pub"
async def get_alc_image(path: Path):
date = datetime.now().date()
for file in os.listdir(path):
if f'{date}.png' != file:
file = path / file
file.unlink()
if f'{date}.png' in os.listdir(path):
return image(f'{date}.png', 'genshin/alc')
page = None
try:
browser = await get_browser()
page = await browser.new_page()
await page.goto(url, wait_until="networkidle", timeout=10000)
await page.set_viewport_size({"width": 2560, "height": 1080})
card = await page.query_selector('.GSAlmanacs_gs_almanacs__3qT_A')
await card.screenshot(path=path / f'{date}.png', timeout=100000)
except Exception as e:
logger.error(f'获取原神黄历发生错误..{type(e)}: {e}')
finally:
if page:
await page.close()
return image(f'{date}.png', 'genshin/alc')

View File

@ -12,14 +12,39 @@ from nonebot.permission import SUPERUSER
from typing import List
import os
import asyncio
import time
__zx_plugin_name__ = "原神今日素材"
__plugin_usage__ = """
usage
看看原神今天要刷什么
指令
今日素材/今天素材
""".strip()
__plugin_superuser_usage__ = """
usage
更新原神今日素材
指令
更新原神今日素材
""".strip()
__plugin_des__ = "看看原神今天要刷什么"
__plugin_cmd__ = ["今日素材/今天素材", "更新原神今日素材 [_superuser]"]
__plugin_type__ = ("原神相关",)
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {
"level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ["今日素材", "今天素材"],
}
driver: Driver = nonebot.get_driver()
material = on_command('今日素材', aliases={'今日材料', '今天素材', '今天材料'}, priority=5, block=True)
material = on_command("今日素材", aliases={"今日材料", "今天素材", "今天材料"}, priority=5, block=True)
super_cmd = on_command('更新原神今日素材', permission=SUPERUSER, priority=1, block=True)
super_cmd = on_command("更新原神今日素材", permission=SUPERUSER, priority=1, block=True)
@material.handle()
@ -27,49 +52,62 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
if time.strftime("%w") == "0":
await material.send("今天是周日,所有材料副本都开放了。")
return
await material.send(Message(image('daily_material.png', 'genshin/material') + '\n※ 每日素材数据来源于 genshin.pub'))
await material.send(
Message(
image("daily_material.png", "genshin/material")
+ "\n※ 每日素材数据来源于 genshin.pub"
)
)
logger.info(
f"(USER {event.user_id}, GROUP {event.group_id if event.message_type != 'private' else 'private'})"
f" 发送查看今日素材")
f" 发送查看今日素材"
)
@super_cmd.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
if await update_image():
await super_cmd.send('更新成功...')
logger.info(f'更新每日天赋素材成功...')
await super_cmd.send("更新成功...")
logger.info(f"更新每日天赋素材成功...")
else:
await super_cmd.send(f'更新失败...')
await super_cmd.send(f"更新失败...")
@driver.on_startup
async def update_image():
page = None
try:
if not os.path.exists(f'{IMAGE_PATH}/genshin/material'):
os.mkdir(f'{IMAGE_PATH}/genshin/material')
for file in os.listdir(f'{IMAGE_PATH}/genshin/material'):
os.remove(f'{IMAGE_PATH}/genshin/material/{file}')
if not os.path.exists(f"{IMAGE_PATH}/genshin/material"):
os.mkdir(f"{IMAGE_PATH}/genshin/material")
for file in os.listdir(f"{IMAGE_PATH}/genshin/material"):
os.remove(f"{IMAGE_PATH}/genshin/material/{file}")
browser = await get_browser()
if not browser:
logger.warning('获取 browser 失败,请部署至 linux 环境....')
logger.warning("获取 browser 失败,请部署至 linux 环境....")
return False
url = 'https://genshin.pub/daily'
url = "https://genshin.pub/daily"
page = await browser.new_page()
await page.goto(url, wait_until='networkidle', timeout=10000)
await page.goto(url, wait_until="networkidle", timeout=10000)
await page.set_viewport_size({"width": 2560, "height": 1080})
await page.evaluate("""
await page.evaluate(
"""
document.getElementsByClassName('GSTitleBar_gs_titlebar__2IJqy')[0].remove();
e = document.getElementsByClassName('GSContainer_gs_container__2FbUz')[0];
e.setAttribute("style", "height:880px");
""")
"""
)
await page.click("button")
div = await page.query_selector(".GSContainer_content_box__1sIXz")
for i, card in enumerate(await page.query_selector_all(".GSTraitCotainer_trait_section__1f3bc")):
for i, card in enumerate(
await page.query_selector_all(".GSTraitCotainer_trait_section__1f3bc")
):
index = 0
type_ = 'char' if not i else 'weapons'
type_ = "char" if not i else "weapons"
for x in await card.query_selector_all("xpath=child::*"):
await x.screenshot(path=f'{IMAGE_PATH}/genshin/material/{type_}_{index}.png', timeout=100000)
await x.screenshot(
path=f"{IMAGE_PATH}/genshin/material/{type_}_{index}.png",
timeout=100000,
)
# 下滑两次
for _ in range(3):
await div.press("PageDown")
@ -77,13 +115,23 @@ async def update_image():
# 结束后上滑至顶
for _ in range(index * 3):
await div.press("PageUp")
file_list = os.listdir(f'{IMAGE_PATH}/genshin/material')
char_imgs = [f'{IMAGE_PATH}/genshin/material/{x}' for x in file_list if x.startswith('char')]
weapons_imgs = [f'{IMAGE_PATH}/genshin/material/{x}' for x in file_list if x.startswith('weapons')]
file_list = os.listdir(f"{IMAGE_PATH}/genshin/material")
char_imgs = [
f"{IMAGE_PATH}/genshin/material/{x}"
for x in file_list
if x.startswith("char")
]
weapons_imgs = [
f"{IMAGE_PATH}/genshin/material/{x}"
for x in file_list
if x.startswith("weapons")
]
char_imgs.sort()
weapons_imgs.sort()
height = await asyncio.get_event_loop().run_in_executor(None, get_background_height, weapons_imgs)
background_img = CreateImg(1200, height + 100, color='#f6f2ee')
height = await asyncio.get_event_loop().run_in_executor(
None, get_background_height, weapons_imgs
)
background_img = CreateImg(1200, height + 100, color="#f6f2ee")
current_width = 50
for imgs in [char_imgs, weapons_imgs]:
current_height = 20
@ -92,11 +140,11 @@ async def update_image():
background_img.paste(x, (current_width, current_height))
current_height += x.size[1]
current_width += 600
background_img.save(f'{IMAGE_PATH}/genshin/material/daily_material.png')
background_img.save(f"{IMAGE_PATH}/genshin/material/daily_material.png")
await page.close()
return True
except Exception as e:
logger.error(f'原神每日素材更新出错... {type(e)}: {e}')
logger.error(f"原神每日素材更新出错... {type(e)}: {e}")
if page:
await page.close()
return False
@ -116,7 +164,7 @@ def get_background_height(weapons_imgs: List[str]) -> int:
@scheduler.scheduled_job(
'cron',
"cron",
hour=4,
minute=1,
)
@ -124,11 +172,7 @@ async def _():
for _ in range(5):
try:
await update_image()
logger.info(f'更新每日天赋素材成功...')
logger.info(f"更新每日天赋素材成功...")
break
except Exception as e:
logger.error(f'更新每日天赋素材出错 e{e}')
logger.error(f"更新每日天赋素材出错 e{e}")

View File

@ -5,9 +5,24 @@ from nonebot import on_command
from utils.utils import get_message_text
from services.log import logger
__plugin_name__ = "丘丘语翻译"
__plugin_usage__ = "用法:丘丘翻译 [消息]"
__zx_plugin_name__ = "丘丘语翻译"
__plugin_usage__ = """
usage
异世界旅游小助手仅支持丘丘语翻译至中文
指令
丘丘语翻译/丘丘一下 [文本]
""".strip()
__plugin_des__ = "其实我听得懂丘丘人讲话"
__plugin_cmd__ = ["丘丘语翻译/丘丘一下 [文本]"]
__plugin_type__ = ("原神相关",)
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {
"level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ["丘丘语翻译", "丘丘一下"],
}
qiuqiu = on_command("丘丘语翻译", aliases={"丘丘一下", "丘丘翻译"}, priority=5, block=True)

View File

@ -1,6 +1,5 @@
from nonebot import on_command, on_regex
from nonebot.rule import to_me
from .query_resource import get_resource_type_list, query_resource, init
from .query_resource import get_resource_type_list, query_resource, init, check_resource_exists
from utils.utils import get_message_text, scheduler
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent, Message
from nonebot.typing import T_State
@ -14,28 +13,53 @@ try:
except ModuleNotFoundError:
import json
__plugin_name__ = "原神资源查询"
__zx_plugin_name__ = "原神资源查询"
__plugin_usage__ = """
usage
不需要打开网页就能帮你生成资源图片
指令
原神资源查询 [资源名称]
原神资源列表
[资源名称]在哪
哪有[资源名称]
""".strip()
__plugin_superuser_usage__ = """
usage
更新原神资源信息
指令
更新原神资源信息
""".strip()
__plugin_des__ = "原神大地图资源速速查看"
__plugin_cmd__ = ["原神资源查询 [资源名称]", "原神资源列表", "[资源名称]在哪/哪有[资源名称]", "更新原神资源信息 [_superuser]"]
__plugin_type__ = ("原神相关",)
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {
"level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ["原神资源查询", "原神资源列表"],
}
__plugin_usage__ = (
"用法:\n" "\t原神资源查询 [消息]\n" "\t原神资源列表\n" "\t[消息]在哪\n" "\t哪有[消息]\n" "[消息] = 资源名称"
)
qr = on_command("原神资源查询", priority=5, block=True)
qr = on_command("原神资源查询", aliases={"原神资源查找"}, 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('更新原神资源信息', permission=SUPERUSER, priority=1, block=True)
rex_qr = on_regex(".*?(在哪|在哪里|哪有|哪里有).*?", priority=5, block=True)
update_info = on_command("更新原神资源信息", permission=SUPERUSER, priority=1, block=True)
@qr.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
resource_name = get_message_text(event.json())
await qr.send('正在生成位置....')
rst = await query_resource(resource_name)
await qr.send(Message(rst), at_sender=True)
logger.info(
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
f" 查询原神材料:" + resource_name
)
if check_resource_exists(resource_name):
await qr.send("正在生成位置....")
resource = await query_resource(resource_name)
await qr.send(Message(resource), at_sender=True)
logger.info(
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
f" 查询原神材料:" + resource_name
)
else:
await qr.send(f"未查找到 {resource_name} 资源,可通过 “原神资源列表” 获取全部资源名称..")
@rex_qr.handle()
@ -47,14 +71,15 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
else:
rs = re.search(".*?(哪有|哪里有)(.*)", msg)
resource_name = rs.group(2) if rs else ""
if resource_name:
await qr.send('正在生成位置....')
msg = await query_resource(resource_name)
await rex_qr.send(Message(msg), at_sender=True)
logger.info(
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
f" 查询原神材料:" + resource_name
)
if check_resource_exists(resource_name):
await qr.send("正在生成位置....")
resource = await query_resource(resource_name)
if resource:
await rex_qr.send(Message(resource), at_sender=True)
logger.info(
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
f" 查询原神材料:" + resource_name
)
@qr_lst.handle()
@ -87,17 +112,17 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
@update_info.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
await init(True)
await update_info.send('更新原神资源信息完成...')
await update_info.send("更新原神资源信息完成...")
@scheduler.scheduled_job(
'cron',
"cron",
hour=5,
minute=1,
)
async def _():
try:
await init()
logger.info(f'每日更新原神材料信息成功!')
logger.info(f"每日更新原神材料信息成功!")
except Exception as e:
logger.error(f'每日更新原神材料信息错误:{e}')
logger.error(f"每日更新原神材料信息错误:{e}")

View File

@ -1,5 +1,5 @@
from pathlib import Path
from configs.path_config import IMAGE_PATH, TXT_PATH
from configs.path_config import IMAGE_PATH, TEXT_PATH
from utils.image_utils import CreateImg
from typing import Tuple, List
from math import sqrt, pow
@ -12,8 +12,8 @@ except ModuleNotFoundError:
icon_path = Path(IMAGE_PATH) / "genshin" / "genshin_icon"
map_path = Path(IMAGE_PATH) / "genshin" / "map" / "map.png"
resource_label_file = Path(TXT_PATH) / "genshin" / "resource_label_file.json"
resource_point_file = Path(TXT_PATH) / "genshin" / "resource_point_file.json"
resource_label_file = Path(TEXT_PATH) / "genshin" / "resource_label_file.json"
resource_point_file = Path(TEXT_PATH) / "genshin" / "resource_point_file.json"
class Map:

View File

@ -1,5 +1,5 @@
from typing import Tuple, Optional, List
from configs.path_config import IMAGE_PATH, TXT_PATH
from configs.path_config import IMAGE_PATH, TEXT_PATH
from PIL.Image import UnidentifiedImageError
from utils.message_builder import image
from services.log import logger
@ -30,9 +30,9 @@ MAP_URL = "https://api-static.mihoyo.com/common/map_user/ys_obc/v1/map/info?map_
icon_path = Path(IMAGE_PATH) / "genshin" / "genshin_icon"
map_path = Path(IMAGE_PATH) / "genshin" / "map"
resource_label_file = Path(TXT_PATH) / "genshin" / "resource_label_file.json"
resource_point_file = Path(TXT_PATH) / "genshin" / "resource_point_file.json"
resource_type_file = Path(TXT_PATH) / "genshin" / "resource_type_file.json"
resource_label_file = Path(TEXT_PATH) / "genshin" / "resource_label_file.json"
resource_point_file = Path(TEXT_PATH) / "genshin" / "resource_point_file.json"
resource_type_file = Path(TEXT_PATH) / "genshin" / "resource_type_file.json"
# 地图中心坐标
CENTER_POINT: Optional[Tuple[int, int]] = None
@ -50,7 +50,8 @@ async def query_resource(resource_name: str) -> str:
resource_name = resource_name[:-2].strip()
planning_route = True
if not resource_name or resource_name not in resource_name_list:
return f"未查找到 {resource_name} 资源,可通过 “原神资源列表” 获取全部资源名称.."
# return f"未查找到 {resource_name} 资源,可通过 “原神资源列表” 获取全部资源名称.."
return ''
map_ = Map(
resource_name, CENTER_POINT, planning_route=planning_route, ratio=MAP_RATIO
)
@ -81,23 +82,36 @@ def get_resource_type_list():
return mes
def check_resource_exists(resource: str) -> bool:
"""
检查资源是否存在
:param resource: 资源名称
"""
resource = resource.replace('路径', '').replace('路线', '')
return resource in resource_name_list
@driver.on_startup
async def init(flag: bool = False):
global CENTER_POINT, resource_name_list
semaphore = asyncio.Semaphore(10)
async with aiohttp.ClientSession(headers=get_user_agent()) as session:
await download_map_init(session, semaphore, MAP_RATIO, flag)
await download_resource_data(session, semaphore)
await download_resource_type(session)
if not CENTER_POINT:
CENTER_POINT = json.load(open(resource_label_file, "r", encoding="utf8"))[
"CENTER_POINT"
]
with open(resource_type_file, "r", encoding="utf8") as f:
data = json.load(f)
for id_ in data:
for x in data[id_]["children"]:
resource_name_list.append(x["name"])
try:
semaphore = asyncio.Semaphore(10)
async with aiohttp.ClientSession(headers=get_user_agent()) as session:
await download_map_init(session, semaphore, MAP_RATIO, flag)
await download_resource_data(session, semaphore)
await download_resource_type(session)
if not CENTER_POINT:
CENTER_POINT = json.load(open(resource_label_file, "r", encoding="utf8"))[
"CENTER_POINT"
]
with open(resource_type_file, "r", encoding="utf8") as f:
data = json.load(f)
for id_ in data:
for x in data[id_]["children"]:
resource_name_list.append(x["name"])
except TimeoutError:
logger.warning('原神资源查询信息初始化超时....')
pass
# 图标及位置资源

View File

@ -1,197 +1,195 @@
from utils.message_builder import image
from utils.utils import scheduler, get_bot
from services.log import logger
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]"
# 早上好
@scheduler.scheduled_job(
"cron",
# year=None,
# month=None,
# day=None,
# week=None,
# day_of_week="mon,tue,wed,thu,fri",
hour=6,
minute=1,
# second=None,
# start_date=None,
# end_date=None,
# timezone=None,
)
async def _():
try:
bot = get_bot()
gl = await bot.get_group_list(self_id=bot.self_id)
gl = [g["group_id"] for g in gl]
for g in gl:
if await GroupRemind.get_status(g, "zwa"):
result = image("zao.jpg", "zhenxun")
try:
await bot.send_group_msg(group_id=g, message="早上好" + result)
except ActionFailed:
logger.warning(f"{g} 群被禁言中,无法发送早安")
except Exception as e:
logger.error(f"早晚安错误 e:{e}")
# 睡觉了
@scheduler.scheduled_job(
"cron",
hour=23,
minute=59,
)
async def _():
try:
bot = get_bot()
gl = await bot.get_group_list(self_id=bot.self_id)
gl = [g["group_id"] for g in gl]
for g in gl:
if await GroupRemind.get_status(g, "zwa"):
result = image("sleep.jpg", "zhenxun")
try:
await bot.send_group_msg(
group_id=g, message=f"{NICKNAME}要睡觉了,你们也要早点睡呀" + result
)
except ActionFailed:
logger.warning(f"{g} 群被禁言中,无法发送晚安")
except Exception as e:
logger.error(f"早晚安错误 e:{e}")
# 自动更新群组信息
@scheduler.scheduled_job(
"cron",
hour=3,
minute=1,
)
async def _():
try:
bot = get_bot()
gl = await bot.get_group_list(self_id=bot.self_id)
gl = [g["group_id"] for g in gl]
for g in gl:
group_info = await bot.get_group_info(group_id=g)
await GroupInfo.add_group_info(
group_info["group_id"],
group_info["group_name"],
group_info["max_member_count"],
group_info["member_count"],
)
logger.info(f"自动更新群组 {g} 信息成功")
except Exception as e:
logger.error(f"自动更新群组信息错误 e:{e}")
# 自动更新好友信息
@scheduler.scheduled_job(
"cron",
hour=3,
minute=1,
)
async def _():
try:
bot = get_bot()
fl = await bot.get_friend_list(self_id=bot.self_id)
for f in fl:
if await FriendUser.add_friend_info(f["user_id"], f["nickname"]):
logger.info(f'自动更新好友 {f["user_id"]} 信息成功')
else:
logger.warning(f'自动更新好友 {f["user_id"]} 信息失败')
except Exception as e:
logger.error(f"自动更新群组信息错误 e:{e}")
# 一次性任务
# 固定时间触发,仅触发一次:
#
# from datetime import datetime
#
# @nonebot.scheduler.scheduled_job(
# 'date',
# run_date=datetime(2021, 1, 1, 0, 0),
# # timezone=None,
# )
# async def _():
# await bot.send_group_msg(group_id=123456,
# message="2021新年快乐")
# 定期任务
# 从 start_date 开始到 end_date 结束,根据类似 Cron
#
# 的规则触发任务:
#
# @nonebot.scheduler.scheduled_job(
# 'cron',
# # year=None,
# # month=None,
# # day=None,
# # week=None,
# day_of_week="mon,tue,wed,thu,fri",
# hour=7,
# # minute=None,
# # second=None,
# # start_date=None,
# # end_date=None,
# # timezone=None,
# )
# async def _():
# await bot.send_group_msg(group_id=123456,
# message="起床啦!")
# 间隔任务
#
# interval 触发器
#
# 从 start_date 开始,每间隔一段时间触发,到 end_date 结束:
#
# @nonebot.scheduler.scheduled_job(
# 'interval',
# # weeks=0,
# # days=0,
# # hours=0,
# minutes=5,
# # seconds=0,
# # start_date=time.now(),
# # end_date=None,
# )
# async def _():
# has_new_item = check_new_item()
# if has_new_item:
# await bot.send_group_msg(group_id=123456,
# message="XX有更新啦")
# 动态的计划任务
# import datetime
#
# from apscheduler.triggers.date import DateTrigger # 一次性触发器
# # from apscheduler.triggers.cron import CronTrigger # 定期触发器
# # from apscheduler.triggers.interval import IntervalTrigger # 间隔触发器
# from nonebot import on_command, scheduler
#
# @on_command('赖床')
# async def _(session: CommandSession):
# await session.send('我会在5分钟后再喊你')
#
# # 制作一个“5分钟后”触发器
# delta = datetime.timedelta(minutes=5)
# trigger = DateTrigger(
# run_date=datetime.datetime.now() + delta
# )
#
# # 添加任务
# scheduler.add_job(
# func=session.send, # 要添加任务的函数,不要带参数
# trigger=trigger, # 触发器
# args=('不要再赖床啦!',), # 函数的参数列表,注意:只有一个值时,不能省略末尾的逗号
# # kwargs=None,
# misfire_grace_time=60, # 允许的误差时间,建议不要省略
# # jobstore='default', # 任务储存库,在下一小节中说明
# )
from utils.message_builder import image
from utils.utils import scheduler, get_bot
from nonebot import on_message
from services.log import logger
from models.group_info import GroupInfo
from models.friend_user import FriendUser
from nonebot.adapters.cqhttp.exception import ActionFailed
from configs.config import NICKNAME
from utils.manager import group_manager
__zx_plugin_name__ = "群定时任务相关 [Hidden]"
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_task__ = {'zwa': '早晚安'}
x = on_message(priority=9, block=False)
# 早上好
@scheduler.scheduled_job(
"cron",
hour=6,
minute=1,
)
async def _():
try:
bot = get_bot()
gl = await bot.get_group_list()
gl = [g["group_id"] for g in gl]
for g in gl:
if await group_manager.check_group_task_status(g, 'zwa'):
result = image("zao.jpg", "zhenxun")
try:
await bot.send_group_msg(group_id=g, message="早上好" + result)
except ActionFailed:
logger.warning(f"{g} 群被禁言中,无法发送早安")
except Exception as e:
logger.error(f"早晚安错误 e:{e}")
# 睡觉了
@scheduler.scheduled_job(
"cron",
hour=23,
minute=59,
)
async def _():
try:
bot = get_bot()
gl = await bot.get_group_list()
gl = [g["group_id"] for g in gl]
for g in gl:
if await group_manager.check_group_task_status(g, 'zwa'):
result = image("sleep.jpg", "zhenxun")
try:
await bot.send_group_msg(
group_id=g, message=f"{NICKNAME}要睡觉了,你们也要早点睡呀" + result
)
except ActionFailed:
logger.warning(f"{g} 群被禁言中,无法发送晚安")
except Exception as e:
logger.error(f"早晚安错误 e:{e}")
# 自动更新群组信息
@scheduler.scheduled_job(
"cron",
hour=3,
minute=1,
)
async def _():
try:
bot = get_bot()
gl = await bot.get_group_list()
gl = [g["group_id"] for g in gl]
for g in gl:
group_info = await bot.get_group_info(group_id=g)
await GroupInfo.add_group_info(
group_info["group_id"],
group_info["group_name"],
group_info["max_member_count"],
group_info["member_count"],
)
logger.info(f"自动更新群组 {g} 信息成功")
except Exception as e:
logger.error(f"自动更新群组信息错误 e:{e}")
# 自动更新好友信息
@scheduler.scheduled_job(
"cron",
hour=3,
minute=1,
)
async def _():
try:
bot = get_bot()
fl = await bot.get_friend_list()
for f in fl:
if await FriendUser.add_friend_info(f["user_id"], f["nickname"]):
logger.info(f'自动更新好友 {f["user_id"]} 信息成功')
else:
logger.warning(f'自动更新好友 {f["user_id"]} 信息失败')
except Exception as e:
logger.error(f"自动更新群组信息错误 e:{e}")
# 一次性任务
# 固定时间触发,仅触发一次:
#
# from datetime import datetime
#
# @nonebot.scheduler.scheduled_job(
# 'date',
# run_date=datetime(2021, 1, 1, 0, 0),
# # timezone=None,
# )
# async def _():
# await bot.send_group_msg(group_id=123456,
# message="2021新年快乐")
# 定期任务
# 从 start_date 开始到 end_date 结束,根据类似 Cron
#
# 的规则触发任务:
#
# @nonebot.scheduler.scheduled_job(
# 'cron',
# # year=None,
# # month=None,
# # day=None,
# # week=None,
# day_of_week="mon,tue,wed,thu,fri",
# hour=7,
# # minute=None,
# # second=None,
# # start_date=None,
# # end_date=None,
# # timezone=None,
# )
# async def _():
# await bot.send_group_msg(group_id=123456,
# message="起床啦!")
# 间隔任务
#
# interval 触发器
#
# 从 start_date 开始,每间隔一段时间触发,到 end_date 结束:
#
# @nonebot.scheduler.scheduled_job(
# 'interval',
# # weeks=0,
# # days=0,
# # hours=0,
# minutes=5,
# # seconds=0,
# # start_date=time.now(),
# # end_date=None,
# )
# async def _():
# has_new_item = check_new_item()
# if has_new_item:
# await bot.send_group_msg(group_id=123456,
# message="XX有更新啦")
# 动态的计划任务
# import datetime
#
# from apscheduler.triggers.date import DateTrigger # 一次性触发器
# # from apscheduler.triggers.cron import CronTrigger # 定期触发器
# # from apscheduler.triggers.interval import IntervalTrigger # 间隔触发器
# from nonebot import on_command, scheduler
#
# @on_command('赖床')
# async def _(session: CommandSession):
# await session.send('我会在5分钟后再喊你')
#
# # 制作一个“5分钟后”触发器
# delta = datetime.timedelta(minutes=5)
# trigger = DateTrigger(
# run_date=datetime.datetime.now() + delta
# )
#
# # 添加任务
# scheduler.add_job(
# func=session.send, # 要添加任务的函数,不要带参数
# trigger=trigger, # 触发器
# args=('不要再赖床啦!',), # 函数的参数列表,注意:只有一个值时,不能省略末尾的逗号
# # kwargs=None,
# misfire_grace_time=60, # 允许的误差时间,建议不要省略
# # jobstore='default', # 任务储存库,在下一小节中说明
# )

View File

@ -4,28 +4,31 @@ from utils.message_builder import image
from models.group_member_info import GroupInfoUser
from datetime import datetime
from services.log import logger
from models.group_remind import GroupRemind
from nonebot.adapters.cqhttp import (
Bot,
GroupIncreaseNoticeEvent,
GroupDecreaseNoticeEvent,
)
from nonebot.adapters.cqhttp.exception import ActionFailed
from configs.config import plugins2info_dict
from utils.static_data import group_manager
from utils.manager import group_manager, plugins2settings_manager
from models.group_info import GroupInfo
from pathlib import Path
import random
import os
try:
import ujson as json
except ModuleNotFoundError:
import json
__plugin_name__ = "群事件处理 [Hidden]"
__usage__ = "用法:无"
__zx_plugin_name__ = "群事件处理 [Hidden]"
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_task__ = {
'group_welcome': '进群欢迎',
'refund_group_remind': '退群提醒'
}
# 群员增加处理
@ -39,10 +42,11 @@ add_group = on_request(priority=1, block=False)
@group_increase_handle.handle()
async def _(bot: Bot, event: GroupIncreaseNoticeEvent, state: dict):
if event.user_id == int(bot.self_id):
if event.group_id not in group_manager['group_manager'].keys():
for plugin in plugins2info_dict.keys():
if not plugins2info_dict[plugin]['default_status']:
group_manager.block_plugin(plugin, str(event.group_id))
if event.group_id not in group_manager["group_manager"].keys():
data = plugins2settings_manager.get_data()
for plugin in data.keys():
if not data[plugin]["default_status"]:
group_manager.block_plugin(plugin, event.group_id)
else:
join_time = datetime.now()
user_info = await bot.get_group_member_info(
@ -59,7 +63,7 @@ async def _(bot: Bot, event: GroupIncreaseNoticeEvent, state: dict):
logger.info(f"用户{user_info['user_id']} 所属{user_info['group_id']} 更新失败")
# 群欢迎消息
if await GroupRemind.get_status(event.group_id, "hy"):
if await group_manager.check_group_task_status(event.group_id, 'group_welcome'):
msg = ""
img = ""
at_flag = False
@ -74,7 +78,9 @@ async def _(bot: Bot, event: GroupIncreaseNoticeEvent, state: dict):
msg = msg.replace("[at]", "")
at_flag = True
if os.path.exists(DATA_PATH + f"custom_welcome_msg/{event.group_id}.jpg"):
img = image(abspath=DATA_PATH + f"custom_welcome_msg/{event.group_id}.jpg")
img = image(
abspath=DATA_PATH + f"custom_welcome_msg/{event.group_id}.jpg"
)
if msg or img:
await group_increase_handle.send(
"\n" + msg.strip() + img, at_sender=at_flag
@ -104,9 +110,9 @@ async def _(bot: Bot, event: GroupDecreaseNoticeEvent, state: dict):
await bot.send_private_msg(
user_id=coffee,
message=f"****呜..一份踢出报告****\n"
f"我被 {operator_name}({operator_id})\n"
f"踢出了 {group_name}({group_id})\n"
f"日期:{str(datetime.now()).split('.')[0]}",
f"我被 {operator_name}({operator_id})\n"
f"踢出了 {group_name}({group_id})\n"
f"日期:{str(datetime.now()).split('.')[0]}",
)
return
try:
@ -115,20 +121,21 @@ async def _(bot: Bot, event: GroupDecreaseNoticeEvent, state: dict):
).user_name
except AttributeError:
user_name = str(event.user_id)
rst = ""
if event.sub_type == "leave":
rst = f"{user_name}离开了我们..."
if event.sub_type == "kick":
operator = await bot.get_group_member_info(
user_id=event.operator_id, group_id=event.group_id
)
operator_name = operator["card"] if operator["card"] else operator["nickname"]
rst = f"{user_name}{operator_name} 送走了."
if await GroupInfoUser.delete_member_info(event.user_id, event.group_id):
logger.info(f"用户{user_name}, qq={event.user_id} 所属{event.group_id} 删除成功")
else:
logger.info(f"用户{user_name}, qq={event.user_id} 所属{event.group_id} 删除失败")
try:
await group_decrease_handle.send(f"{rst}")
except ActionFailed:
return
if await group_manager.check_group_task_status(event.group_id, 'refund_group_remind'):
rst = ""
if event.sub_type == "leave":
rst = f"{user_name}离开了我们..."
if event.sub_type == "kick":
operator = await bot.get_group_member_info(
user_id=event.operator_id, group_id=event.group_id
)
operator_name = operator["card"] if operator["card"] else operator["nickname"]
rst = f"{user_name}{operator_name} 送走了."
try:
await group_decrease_handle.send(f"{rst}")
except ActionFailed:
return

View File

@ -1,35 +1,35 @@
from nonebot import on_message
from nonebot.adapters.cqhttp.permission import GROUP
from nonebot.typing import T_State
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent
import time
from .data_source import cancel_all_notice, save_data, get_data, set_data_value
from services.log import logger
__plugin_name__ = "查看群最后聊天时间 [Hidden]"
__plugin_usage__ = "用法:无"
last_chat = on_message(priority=1, block=False, permission=GROUP)
@last_chat.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
time_data = await get_data()
set_data_value(event.group_id, time.time())
if event.group_id in time_data["_group"]:
time_data["_group"].remove(event.group_id)
set_data_value("_group", time_data["_group"])
for key in time_data.keys():
if key not in ["check_time", "_group"]:
if key not in time_data["_group"]:
if time.time() - time_data[key] > 60 * 60 * 36:
await cancel_all_notice(key)
time_data["_group"].append(key)
set_data_value("_group", time_data["_group"])
logger.info(f"GROUP {event.group_id} 因群内发言时间大于36小时被取消全部通知")
if time.time() - time_data["check_time"] > 60 * 60 * 1:
set_data_value("check_time", time.time())
save_data()
from nonebot import on_message
from nonebot.adapters.cqhttp.permission import GROUP
from nonebot.typing import T_State
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent
import time
from .data_source import cancel_all_notice, save_data, get_data, set_data_value
from services.log import logger
__zx_plugin_name__ = "最后聊天时间记录 [Hidden]"
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
last_chat = on_message(priority=1, block=False, permission=GROUP)
@last_chat.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
time_data = await get_data()
set_data_value(event.group_id, time.time())
if event.group_id in time_data["_group"]:
time_data["_group"].remove(event.group_id)
set_data_value("_group", time_data["_group"])
for key in time_data.keys():
if key not in ["check_time", "_group"]:
if key not in time_data["_group"]:
if time.time() - time_data[key] > 60 * 60 * 36:
await cancel_all_notice(key)
time_data["_group"].append(key)
set_data_value("_group", time_data["_group"])
logger.info(f"GROUP {event.group_id} 因群内发言时间大于36小时被取消全部通知")
if time.time() - time_data["check_time"] > 60 * 60 * 1:
set_data_value("check_time", time.time())
save_data()

View File

@ -1,71 +1,67 @@
from configs.path_config import DATA_PATH
from utils.utils import get_bot
from models.group_remind import GroupRemind
from datetime import datetime
import time
from services.log import logger
try:
import ujson as json
except ModuleNotFoundError:
import json
time_data = {}
async def init():
global time_data
bot = get_bot()
gl = await bot.get_group_list(self_id=bot.self_id)
gl = [g["group_id"] for g in gl]
data = read_data("group_last_chat_time.json")
for g in gl:
if not data.get(g):
time_data[g] = time.time()
if not time_data.get("check_time"):
time_data["check_time"] = time.time()
if not time_data.get("_group"):
time_data["_group"] = []
save_data()
return time_data
def read_data(file_name: str):
try:
with open(DATA_PATH + file_name, "r", encoding="utf8") as f:
return json.load(f)
except (ValueError, FileNotFoundError):
return {}
def save_data():
with open(DATA_PATH + "group_last_chat_time.json", "w") as f:
json.dump(time_data, f, indent=4)
logger.info(
f'自动存储 group_last_chat_time.json 时间:{str(datetime.now()).split(".")[0]}'
)
command_list = ["zwa", "hy", "kxcz", "blpar", "epic", "pa", "gb"]
# 取消全部通知
async def cancel_all_notice(group_id):
group_id = int(group_id)
for command in command_list:
if await GroupRemind.get_status(group_id, command):
await GroupRemind.set_status(group_id, command, False)
logger.info(f"关闭了 {group_id} 群的全部通知")
async def get_data():
global time_data
if not time_data:
time_data = await init()
return time_data
def set_data_value(key, value):
global time_data
time_data[key] = value
from configs.path_config import DATA_PATH
from utils.utils import get_bot
from datetime import datetime
import time
from services.log import logger
from utils.manager import group_manager
try:
import ujson as json
except ModuleNotFoundError:
import json
time_data = {}
async def init():
global time_data
bot = get_bot()
gl = await bot.get_group_list()
gl = [g["group_id"] for g in gl]
data = read_data("group_last_chat_time.json")
for g in gl:
if not data.get(g):
time_data[g] = time.time()
if not time_data.get("check_time"):
time_data["check_time"] = time.time()
if not time_data.get("_group"):
time_data["_group"] = []
save_data()
return time_data
def read_data(file_name: str):
try:
with open(DATA_PATH + file_name, "r", encoding="utf8") as f:
return json.load(f)
except (ValueError, FileNotFoundError):
return {}
def save_data():
with open(DATA_PATH + "group_last_chat_time.json", "w") as f:
json.dump(time_data, f, indent=4)
logger.info(
f'自动存储 group_last_chat_time.json 时间:{str(datetime.now()).split(".")[0]}'
)
# 取消全部通知
async def cancel_all_notice(group_id):
group_id = int(group_id)
for command in group_manager.get_task_data():
if await group_manager.check_group_task_status(group_id, command):
await group_manager.close_group_task(group_id, command)
logger.info(f"关闭了 {group_id} 群的全部通知")
async def get_data():
global time_data
if not time_data:
time_data = await init()
return time_data
def set_data_value(key, value):
global time_data
time_data[key] = value

View File

@ -5,16 +5,28 @@ 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
from configs.config import NICKNAME
from utils.manager import group_manager, plugins2settings_manager
try:
import ujson as json
except ModuleNotFoundError:
import json
__plugin_name__ = "群权限操作"
__plugin_usage__ = "区分权限功能"
__zx_plugin_name__ = "群权限操作 [Superuser]"
__plugin_usage__ = """
usage
对群权限 | 群白名单 的操作
指令
修改群权限 [group] [等级]
添加群白名单 *[group]
删除群白名单 *[group]
查看群白名单
""".strip()
__plugin_des__ = "对群权限 | 群白名单 的操作"
__plugin_cmd__ = ["修改群权限 [group] [等级]", "添加群白名单 *[group]", "删除群白名单 *[group]", "查看群白名单"]
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
add_group_level = on_command("修改群权限", priority=1, permission=SUPERUSER, block=True)
@ -33,12 +45,16 @@ manager_group_whitelist = on_command(
"添加群白名单", aliases={"删除群白名单"}, priority=1, permission=SUPERUSER, block=True
)
show_group_whitelist = on_command('查看群白名单', priority=1, permission=SUPERUSER, block=True)
show_group_whitelist = on_command(
"查看群白名单", 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())
group_id = 0
level = 0
if not msg:
await add_group_level.finish("用法:修改群权限 [group] [level]")
msg = msg.split(" ")
@ -52,19 +68,21 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
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}"
)
if level > -1:
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))
level = group_manager.get_group_level(event.group_id)
tmp = ""
for plugin in plugins2info_dict:
if plugins2info_dict[plugin]["level"] > level:
plugin_name = plugins2info_dict[plugin]["cmd"][0]
data = plugins2settings_manager.get_data()
for module in data:
if data[module]["level"] > level:
plugin_name = data[module]["cmd"][0]
if plugin_name == "pixiv":
plugin_name = "搜图 p站排行"
tmp += f"{plugin_name}\n"
@ -109,6 +127,6 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
x = group_manager.get_group_white_list()
x = [str(g) for g in x]
if x:
await show_group_whitelist.send("目前的群白名单:\n" + '\n'.join(x))
await show_group_whitelist.send("目前的群白名单:\n" + "\n".join(x))
else:
await show_group_whitelist.send('没有任何群在群白名单...')
await show_group_whitelist.send("没有任何群在群白名单...")

View File

@ -12,9 +12,23 @@ try:
except ModuleNotFoundError:
import json
__plugin_name__ = "查看群欢迎消息"
__plugin_usage__ = ""
__zx_plugin_name__ = "查看群欢迎消息"
__plugin_usage__ = """
usage
查看当前的群欢迎消息
指令
查看群欢迎消息
""".strip()
__plugin_des__ = "查看群欢迎消息"
__plugin_cmd__ = ["查看群欢迎消息"]
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {
"level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ["查看群欢迎消息"],
}
view_custom_welcome = on_command(
"群欢迎消息", aliases={"查看群欢迎消息", "查看当前群欢迎消息"}, permission=GROUP, priority=5, block=True

View File

@ -1,43 +1,61 @@
from nonebot import on_command
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent, PrivateMessageEvent
from nonebot.adapters.cqhttp import (
Bot,
MessageEvent,
)
from nonebot.typing import T_State
from nonebot.rule import to_me
from configs.path_config import DATA_PATH
from configs.path_config import IMAGE_PATH
from utils.message_builder import image
import os
from .data_source import create_help_img, create_group_help_img, get_plugin_help
from .data_source import create_help_img, get_plugin_help
from utils.utils import get_message_text
from pathlib import Path
__plugin_name__ = "帮助"
__zx_plugin_name__ = "帮助"
if not os.path.exists(DATA_PATH + "group_help/"):
os.mkdir(DATA_PATH + "group_help/")
create_help_img()
for file in os.listdir(DATA_PATH + "group_help/"):
os.remove(DATA_PATH + "group_help/" + file)
help_image = Path(IMAGE_PATH) / "help.png"
simple_help_image = Path(IMAGE_PATH) / "simple_help.png"
if help_image.exists():
help_image.unlink()
if simple_help_image.exists():
simple_help_image.unlink()
_help = on_command("功能", rule=to_me(), aliases={"help", "帮助"}, priority=1, block=True)
_help = on_command("详细功能", rule=to_me(), aliases={"详细帮助"}, priority=1, block=True)
simple_help = on_command("功能", rule=to_me(), aliases={"help", "帮助"}, priority=1, block=True)
@_help.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
msg = get_message_text(event.json())
if not msg:
if not os.path.exists(DATA_PATH + f"group_help/{event.group_id}.png"):
create_group_help_img(event.group_id)
await _help.finish(
image(abspath=DATA_PATH + f"group_help/{event.group_id}.png")
)
else:
await _help.finish(get_plugin_help(msg))
async def _(bot: Bot, event: MessageEvent, state: T_State):
if not help_image.exists():
if help_image.exists():
help_image.unlink()
if simple_help_image.exists():
simple_help_image.unlink()
await create_help_img(help_image, simple_help_image)
await _help.finish(image("help.png"))
@_help.handle()
async def _(bot: Bot, event: PrivateMessageEvent, state: T_State):
@simple_help.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = get_message_text(event.json())
if not msg:
await _help.finish(image("help.png"))
is_super = False
if msg:
if '-super' in msg:
if str(event.user_id) in bot.config.superusers:
is_super = True
msg = msg.replace('-super', '')
msg = get_plugin_help(msg, is_super)
if msg:
await _help.send(image(b64=msg))
else:
await _help.send("没有此功能的帮助信息...")
else:
await _help.finish(get_plugin_help(msg))
if not simple_help_image.exists():
if help_image.exists():
help_image.unlink()
if simple_help_image.exists():
simple_help_image.unlink()
await create_help_img(help_image, simple_help_image)
await _help.finish(image("simple_help.png"))

View File

@ -1,72 +0,0 @@
from configs.config import NICKNAME
# 实用
utility_help = {
"update_pic": "一些对图片的操作 --> 指令:操作图片/图片/修改图片(包含 10 种图片操作)",
"search_buff_skin_price": "BUFF皮肤底价查询 --> 指令:查询皮肤(代理ip不得劲)",
"weather": "天气查询 --> 指令:xx天气",
"yiqing": "实时疫情数据 --> 指令:疫情查询/疫情/查询疫情",
"bt": "bt(磁力搜索){仅支持私聊,懂的都懂} --> 指令:bt",
"reimu": "老司机必备!{仅支持私聊,懂的都懂}-> 指令:上车",
"what_anime": "靠图识番 --> 指令:识番",
"nonebot_plugin_picsearcher": "以图搜图 --> 指令:识图/这是什么/上一张图是什么",
"search_anime": "找不到想看的动漫吗? --> 指令:搜番",
"songpicker2": "来一首歌听听? --> 指令:点歌",
"epic": "epic速速白嫖 --> 指令:epic",
"pixiv_r": "P站排行榜直接冲 --> 指令:p站排行(可含参数)",
"pixiv_s": "P站的图随便搜搜 --> 指令:搜图(可含参数)",
"pid_search": "通过PID搜索图片 --> 指令:p搜 [pid]",
"translate": "出国旅游助手(狗头) --> 指令:英翻/翻英/日翻/翻日/韩翻/翻韩",
"cover": "快捷的b站封面获取方式 --> 指令:b封面 [连接/av/bv/cv/直播id]",
}
# 娱乐
entertainment_help = {
"sign_in": "签到(影响色图和开箱) --> 指令:签到/我的签到/好感度排行/好感度总榜/好感度总榜[屏蔽我/显示我]",
"send_img": "发送图片 --> 指令:美图/萝莉/壁纸/(美图/萝莉/壁纸[id])/N张图xx(N<=9)",
"send_setu": "不要小看涩图啊混蛋! --> 指令:色图/色图[id]/n张色图/n张xx色图/查色图/...(请查看 色图 帮助)",
"white2black_img": "黑白草图 --> 指令:黑白图/黑白草图",
"coser": "三次元也不戳 --> 指令:coser",
"jitang": "不喝点什么不舒服 --> 指令:鸡汤/语录",
"send_dinggong_voice": "骂我(傲娇?) --> 指令:骂老子",
"poke": "戳一戳发送语音美图萝莉图不美哉?",
"open_cases": "模拟开箱(戒赌) --> 指令:开箱(N连开箱[N<=30])/我的开箱/群开箱统计/我的金色",
"luxun": "鲁迅说过 --> 指令:鲁迅说",
"fake_msg": "构造一个假消息 --> 指令:假消息",
"shop_handle": "商店系统(初始送100金币) --> 指令:商店/我的金币/购买道具/使用道具",
"draw_card_prts": "换个地方当非酋TvT... --> 指令:方舟一井/方舟N抽0<N<300",
"draw_card_genshin": "提瓦特是个好地方! --> 指令:原神一井/原神N抽0<N<180/原神武器/角色N抽/重置原神抽卡次数",
"draw_card_pretty": "赛马娘!!!! --> 指令:赛马娘一井/赛马娘N抽/赛马娘卡一井/赛马娘卡N抽(0<N<200)",
"draw_card_guardian": "坎公骑冠剑.... --> 指令:坎公骑冠剑一井/坎公骑冠剑武器一井/坎公骑冠剑N抽/坎公骑冠剑武器N抽(0<N<300)",
"draw_card_pcr": "公主连结(国服)来几发 --> 指令:pcr一井/pcrN抽(0<N<300)",
"draw_card_azur": "我跟方舟坐狱友 --> 指令:碧蓝轻型/重型/特型N抽(0<N<300)",
"draw_card_fgo": "你就是我的马斯塔嘛 --> 指令:fgoN抽(0<N<300)",
"draw_card_onmyoji": "普通的阴阳师召唤 --> 指令:阴阳师N抽(0<N<300)",
"one_friend": "我有一个朋友想问问... --> 指令:我有一个朋友想问问xxx(内容)",
"nickname": "区区昵称! --> 指令:以后叫我xx(昵称)/我是谁/取消昵称",
"almanac": "这是一张正经的黄历 --> 指令:原神黄历",
"material_remind": "看看原神今天要刷什么 --> 指令:今日素材/今日材料/今天素材/今天材料",
"qiu_qiu_translation": "这家伙到底在说什么? --> 指令:丘丘翻译/丘丘一下/丘丘语翻译",
"query_resource_points": "地图资源速速查看 --> 指令:原神资源查询xx[路径]/原神资源列表/哪里有xx/xx在哪(xx=资源名称)",
"russian": "紧张刺激的俄罗斯轮盘 --> 指令:俄罗斯轮盘帮助",
"gold_redbag": f"运气项目又来啦! --> 指令:塞红包/ 抢红包指令: 开/抢/戳一戳{NICKNAME}/ 退回:退回未抢完的红包",
"poetry": f"突然文艺的{NICKNAME}是否搞错了什么 --> 指令:念诗/来首诗/念首诗",
"comments_163": "生了个人,我很抱歉 --> 指令:到点了/12点了/网易云热评/网易云评论",
"pix_gallery": "偶尔也想看看美图? --> 指令:PIX [关键词/uid/pid:pid] [num]/查看pix图库 [关键词]/显示pix关键词",
'nbnhhsh': "会说话就多说点! --> 指令:nbnhhsh/能不能好好说话 [文本](空格划分)",
"roll": f"{NICKNAME}来帮你决定吧! --> 指令:roll/ roll [文本](空格划分)",
"wbtop": f"刚买完瓜,在吃瓜现场 --> 指令:微博热搜/微博热搜 [数字]",
"bilibili_sub": f"非常快捷的订阅播报 --> 指令:添加订阅 [主播/up/番剧] [id/番名/链接] / 删除订阅 [id]/ 查看订阅"
}
# 其他
other_help = [
"查看当前的群欢迎消息 --> 指令:群欢迎消息",
"这是一份正经的自我介绍 --> 指令:自我介绍",
"不得看看自己权力多大? --> 指令:我的权限",
"有人记得你是什么时候加入我们的 --> 指令:我的信息",
"让我看看更新了什么 --> 指令:更新信息",
f"{NICKNAME}给我把话收回去! --> 指令:撤回 [id](默认0)",
"群拥有的权限 --> 指令:查看群权限",
"数据统计可视化_1 --> 指令:功能调用统计/日功能调用统计/周功能调用统计/月功能调用统计",
"数据统计可视化_2 --> 指令:周功能调用统计 [功能名称]/月功能调用统计 [功能名称]",
"这里是PIX图库 --> 指令:添加pix关键词 [关键词]/添加pixuid/pid [UID/PID]/我的pix关键词",
]

View File

@ -1,175 +1,289 @@
from utils.image_utils import CreateImg
from configs.path_config import IMAGE_PATH, DATA_PATH
from configs.path_config import IMAGE_PATH
from utils.manager import plugins2settings_manager
from typing import Optional
from services.log import logger
from pathlib import Path
from .config import *
from configs.config import (
INITIAL_OPEN_CASE_COUNT,
INITIAL_SETU_PROBABILITY,
ADMIN_DEFAULT_AUTH,
)
from configs.config import plugins2info_dict, NICKNAME
from utils.static_data import group_manager
from utils.utils import get_matchers
import random
import asyncio
import nonebot
import os
width = 1600
random_bk_path = Path(IMAGE_PATH) / "background" / "help" / "simple_help"
background = Path(IMAGE_PATH) / "background" / "0.png"
def create_help_img():
help_img_file = Path(IMAGE_PATH) / 'help.png'
if help_img_file.exists():
help_img_file.unlink()
h = (
100
+ len(utility_help) * 24
+ len(entertainment_help) * 24
+ len(other_help) * 24
) + 800
A = CreateImg(width, h - 200, font_size=24)
e = CreateImg(width, len(entertainment_help) * 26 + 100, font_size=24)
rst = ""
i = 0
for cmd in entertainment_help:
rst += f"{i + 1}.{entertainment_help[cmd]}\n"
i += 1
e.text((10, 10), "娱乐功能:")
e.text((40, 40), rst)
u = CreateImg(width, len(utility_help) * 26 + 100, font_size=24, color="black")
rst = ""
i = 0
for cmd in utility_help:
rst += f"{i + 1}.{utility_help[cmd]}\n"
i += 1
u.text((10, 10), "实用功能:", fill=(255, 255, 255))
u.text((40, 40), rst, fill=(255, 255, 255))
o = CreateImg(width, len(other_help) * 26 + 100, font_size=24)
rst = ""
for i in range(len(other_help)):
rst += f"{i + 1}.{other_help[i]}\n"
i += 1
o.text((10, 10), "其他功能:")
o.text((40, 40), rst)
A.paste(e, (0, 0))
A.paste(u, (0, e.h))
A.paste(o, (0, e.h + u.h))
A.text(
(10, e.h + u.h + o.h + 50),
f"大部分交互功能可以通过输入‘取消’,‘算了’来取消当前交互\n{NICKNAME}说 “{NICKNAME}帮助 指令名” 获取对应详细帮助\n"
"可以通过 “滴滴滴- [消息]” 联系管理员(有趣的想法尽管来吧!<还有Bug和建议>"
"\n[群管理员请看 管理员帮助(群主与管理员自带 5 级权限)]\n\n"
f"\t「如果{NICKNAME}回复了一些不符合人设的话那是因为每日白嫖的图灵次数已用完使用的是备用接口【QAQ】」",
async def create_help_img(help_image: Path, simple_help_image: Path):
"""
生成帮助图片
:param help_image: 图片路径
:param simple_help_image: 简易帮助图片路径
"""
return await asyncio.get_event_loop().run_in_executor(
None, _create_help_img, help_image, simple_help_image
)
A.save(IMAGE_PATH + "help.png")
def create_group_help_img(group_id: int):
group_id = str(group_id)
h = (
100
+ len(utility_help) * 24
+ len(entertainment_help) * 24
+ len(other_help) * 24
) + 800
A = CreateImg(width, h, font_size=24)
u = CreateImg(width, len(utility_help) * 26 + 100, font_size=24, color="black")
o = CreateImg(width, len(other_help) * 26 + 100, font_size=24)
e = CreateImg(width, len(entertainment_help) * 26 + 100, font_size=24)
rst = ""
i = 1
for cmd in entertainment_help.keys():
flag, dfg = parse_cmd(cmd, group_id)
if dfg:
cmd = rcmd(dfg)
rst += f"{flag}{i}.{entertainment_help[cmd]}\n"
i += 1
e.text((10, 10), "娱乐功能:")
e.text((40, 40), rst)
rst = ""
i = 1
for cmd in utility_help.keys():
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))
u.text((40, 40), rst, fill=(255, 255, 255))
rst = ""
for i in range(len(other_help)):
rst += f"{i + 1}.{other_help[i]}\n"
o.text((10, 10), "其他功能:")
o.text((40, 40), rst)
A.paste(e, (0, 0))
A.paste(u, (0, e.h))
A.paste(o, (0, e.h + u.h))
# A.text((width, 10), f'总开关【{"√" if data["总开关"] else "×"}】')
A.text(
(10, e.h + u.h + o.h + 50),
f"大部分交互功能可以通过输入‘取消’,‘算了’来取消当前交互\n{NICKNAME}说 “{NICKNAME}帮助 指令名” 获取对应详细帮助\n"
"可以通过 “滴滴滴- [消息]” 联系管理员(有趣的想法尽管来吧!<还有Bug和建议>"
f"\n[群管理员请看 管理员帮助(群主与管理员自带 {ADMIN_DEFAULT_AUTH} 级权限)]",
def _create_help_img(help_image: Path, simple_help_image: Path):
"""
生成帮助图片
:param help_image: 图片路径
:param simple_help_image: 简易帮助图片路径
"""
_matchers = get_matchers()
width = 0
matchers_data = {}
_des_tmp = {}
_plugin_name_tmp = []
_tmp = []
tmp_img = CreateImg(0, 0, plain_text="1", font_size=24)
font_height = tmp_img.h
for matcher in _matchers:
plugin_name = None
_plugin = nonebot.plugin.get_plugin(matcher.module)
_module = _plugin.module
try:
plugin_name = _module.__getattribute__("__zx_plugin_name__")
try:
plugin_des = _module.__getattribute__("__plugin_des__")
except AttributeError:
plugin_des = "_"
if (
"[hidden]" in plugin_name.lower()
or "[admin]" in plugin_name.lower()
or "[superuser]" in plugin_name.lower()
or plugin_name in _plugin_name_tmp
or plugin_name == "帮助"
):
continue
plugin_type = ("normal",)
text_type = 0
if plugins2settings_manager.get(
matcher.module
) and plugins2settings_manager[matcher.module].get("plugin_type"):
plugin_type = tuple(
plugins2settings_manager.get_plugin_data(matcher.module)[
"plugin_type"
]
)
else:
try:
plugin_type = _module.__getattribute__("__plugin_type__")
except AttributeError:
pass
if len(plugin_type) > 1:
try:
text_type = int(plugin_type[1])
except ValueError as e:
logger.warning(f"生成列向帮助排列失败 {plugin_name}: {type(e)}: {e}")
plugin_type = plugin_type[0]
else:
plugin_type = plugin_type[0]
try:
plugin_cmd = _module.__getattribute__("__plugin_cmd__")
plugin_cmd = [x for x in plugin_cmd if "[_superuser]" not in x]
except AttributeError:
plugin_cmd = []
if plugin_type not in matchers_data.keys():
matchers_data[plugin_type] = {}
if plugin_des in _des_tmp.keys():
try:
matchers_data[plugin_type][_des_tmp[plugin_des]]["cmd"] = (
matchers_data[plugin_type][_des_tmp[plugin_des]]["cmd"]
+ plugin_cmd
)
except KeyError as e:
logger.warning(f"{type(e)}: {e}")
else:
matchers_data[plugin_type][plugin_name] = {
"des": plugin_des,
"cmd": plugin_cmd,
"text_type": text_type,
}
try:
if text_type == 0:
x = tmp_img.getsize(
f'{plugin_name}: {matchers_data[plugin_type][plugin_name]["des"]} ->'
+ " / ".join(matchers_data[plugin_type][plugin_name]["cmd"])
)[0]
width = width if width > x else x
except KeyError:
pass
if plugin_des not in _des_tmp:
_des_tmp[plugin_des] = plugin_name
except AttributeError as e:
if plugin_name not in _plugin_name_tmp:
logger.warning(f"获取功能 {matcher.module}: {plugin_name} 设置失败...e{e}")
if plugin_name not in _plugin_name_tmp:
_plugin_name_tmp.append(plugin_name)
help_img_list = []
simple_help_img_list = []
types = list(matchers_data.keys())
types.sort()
ix = 0
for type_ in types:
keys = list(matchers_data[type_].keys())
keys.sort()
help_str = f"{type_ if type_ != 'normal' else '功能'}:\n\n"
simple_help_str = f"{type_ if type_ != 'normal' else '功能'}:\n\n"
for i, k in enumerate(keys):
simple_help_str += f"{i+1}.{k}\n"
if matchers_data[type_][k]["text_type"] == 1:
_x = tmp_img.getsize(
f"{i+1}".rjust(5)
+ f'.{k}: {matchers_data[type_][k]["des"]} {"->" if matchers_data[type_][k]["cmd"] else ""} '
)[0]
_str = (
f"{i+1}".rjust(5)
+ f'.{k}: {matchers_data[type_][k]["des"]} {"->" if matchers_data[type_][k]["cmd"] else ""} '
)
_str += matchers_data[type_][k]["cmd"][0] + "\n"
for c in matchers_data[type_][k]["cmd"][1:]:
_str += "".rjust(int(_x * 0.125) + 1) + f"{c}\n"
help_str += _str
else:
help_str += (
f"{i+1}".rjust(5)
+ f'.{k}: {matchers_data[type_][k]["des"]} {"->" if matchers_data[type_][k]["cmd"] else ""} '
+ " / ".join(matchers_data[type_][k]["cmd"])
+ "\n"
)
height = len(help_str.split("\n")) * (font_height + 5)
simple_height = len(simple_help_str.split("\n")) * (font_height + 5)
A = CreateImg(
width + 150, height, font_size=24, color="white" if not ix % 2 else "black"
)
A.text((10, 10), help_str, (255, 255, 255) if ix % 2 else (0, 0, 0))
simple_width = 0
for x in [tmp_img.getsize(x)[0] for x in simple_help_str.split("\n")]:
simple_width = simple_width if simple_width > x else x
bk = CreateImg(
simple_width + 20, simple_height, font_size=24, color="#6495ED"
)
B = CreateImg(
simple_width + 20,
simple_height,
font_size=24,
color="white" if not ix % 2 else "black",
)
B.text((10, 10), simple_help_str, (255, 255, 255) if ix % 2 else (0, 0, 0))
bk.paste(B, center_type="center")
bk.transparent(2)
ix += 1
help_img_list.append(A)
simple_help_img_list.append(bk)
height = 0
for img in help_img_list:
height += img.h
A = CreateImg(width + 150, height + 50, font_size=24)
A.text((10, 10), '* 注: * 代表可有多个相同参数 ? 代表可省略该参数 *\n\n" "功能名: 功能简介 -> 指令\n\n')
current_height = 50
for img in help_img_list:
A.paste(img, (0, current_height))
current_height += img.h
A.save(help_image)
height = 0
width = 0
for img in simple_help_img_list:
if img.h > height:
height = img.h
width += img.w + 10
B = CreateImg(width + 100, height + 250, font_size=24)
width, _ = get_max_width_or_paste(simple_help_img_list, B)
bk = None
random_bk = os.listdir(random_bk_path)
if random_bk:
bk = random.choice(random_bk)
x = max(width + 50, height + 250)
B = CreateImg(
x,
x,
font_size=24,
color="#FFEFD5",
background=random_bk_path / bk,
)
A.text(
(10, e.h + u.h + o.h + 250),
f"【注】「色图概率:好感度 + {int(INITIAL_SETU_PROBABILITY*100)}%\n"
f"\t\t每 3 点好感度 + 1次开箱初始 {INITIAL_OPEN_CASE_COUNT}\n"
f"\t\t开启/关闭功能只需输入‘开启/关闭 指令名’(每个功能的第一个指令)」\n"
f"\t\t示例:开启签到\n"
f"\t\t可以通过管理员开关自动发送消息(早晚安等)\n"
f"\t\t^请查看管理员帮助^\n\n"
f"\t「如果{NICKNAME}回复了一些不符合人设的话那是因为每日白嫖的图灵次数已用完使用的是备用接口【QAQ】」",
)
A.save(DATA_PATH + f"group_help/{group_id}.png")
B.filter("GaussianBlur", 10)
_, B = get_max_width_or_paste(simple_help_img_list, B, True)
w = 10
h = 10
for msg in ['目前支持的功能列表:', '可以通过 ‘帮助[功能名称] 来获取对应功能的使用方法', '或者使用 ‘详细帮助’ 来获取所有功能方法']:
text = CreateImg(
0,
0,
plain_text=msg,
font_size=24,
color=(255, 255, 255, 0),
font='yuanshen.ttf'
)
B.paste(text, (w, h), True)
h += 50
if msg == '目前支持的功能列表:':
w += 50
B.save(simple_help_image)
def parse_cmd(cmd, group_id):
flag = ""
dfg = None
if cmd.find("draw_card") != -1:
lst = cmd.split("_")
cmd = lst[0] + "_" + lst[1]
dfg = lst[-1]
elif cmd == "pixiv_r":
cmd = "pixiv"
dfg = "r"
elif cmd == "pixiv_s":
cmd = "pixiv"
dfg = "s"
if not group_manager.get_plugin_status(cmd, group_id):
flag = "×"
if cmd in ["bt", "reimu", "nickname"]:
flag = "- "
return flag, dfg
def get_max_width_or_paste(
simple_help_img_list: list, B: CreateImg = None, is_paste: bool = False
) -> "int, CreateImg":
"""
获取最大宽度或直接贴图
:param simple_help_img_list: 简单帮助图片列表
:param B: 背景图
:param is_paste: 是否直接贴图
"""
current_width = 50
current_height = 180
max_width = simple_help_img_list[0].w
for i in range(len(simple_help_img_list)):
try:
if is_paste and B:
B.paste(simple_help_img_list[i], (current_width, current_height), True)
current_height += simple_help_img_list[i].h + 40
if current_height + simple_help_img_list[i + 1].h > B.h - 10:
current_height = 180
current_width += max_width + 30
max_width = 0
elif simple_help_img_list[i].w > max_width:
max_width = simple_help_img_list[i].w
except IndexError:
pass
if current_width > simple_help_img_list[0].w + 50:
current_width += simple_help_img_list[-1].w
return current_width, B
def rcmd(dfg):
if dfg in [
"prts",
"genshin",
"pretty",
"guardian",
"pcr",
"azur",
"onmyoji",
"fgo",
]:
return "draw_card_" + dfg
if dfg == "r":
return "pixiv_r"
if dfg == "s":
return "pixiv_s"
def get_plugin_help(msg: str) -> str:
plugin = None
for p in plugins2info_dict.keys():
if msg in plugins2info_dict[p]["cmd"]:
plugin = nonebot.plugin.get_plugin(p)
break
if plugin:
result = plugin.module.__getattribute__("__plugin_usage__")
return result
else:
return "没有此功能的帮助信息..."
def get_plugin_help(msg: str, is_super: bool = False) -> Optional[str]:
"""
获取功能的帮助信息
:param msg: 功能cmd
:param is_super: 是否为超级用户
"""
module = plugins2settings_manager.get_plugin_module(msg)
if module:
try:
plugin = nonebot.plugin.get_plugin(module)
if plugin:
if is_super:
result = plugin.module.__getattribute__(
"__plugin_superuser_usage__"
)
else:
result = plugin.module.__getattribute__("__plugin_usage__")
width = 0
for x in result.split("\n"):
_width = len(x) * 24
width = width if width > _width else _width
height = len(result.split("\n")) * 45
A = CreateImg(width, height, font_size=24)
bk = CreateImg(
width, height, background=Path(IMAGE_PATH) / "background" / "1.png"
)
A.paste(bk, alpha=True)
A.text((int(width * 0.048), int(height * 0.21)), result)
return A.pic2bs4()
except AttributeError:
pass
return None

View File

@ -2,6 +2,12 @@ from nonebot.matcher import Matcher
from nonebot.message import run_preprocessor, run_postprocessor, IgnoredException
from nonebot.adapters.cqhttp.exception import ActionFailed
from models.group_member_info import GroupInfoUser
from utils.manager import (
plugins2cd_manager,
plugins2block_manager,
plugins2settings_manager,
admin_manager
)
from models.friend_user import FriendUser
from typing import Optional
from nonebot.typing import T_State
@ -16,14 +22,10 @@ from nonebot.adapters.cqhttp import (
)
from configs.config import (
BAN_RESULT,
admin_plugins_auth,
MALICIOUS_BAN_TIME,
MALICIOUS_CHECK_TIME,
MALICIOUS_BAN_COUNT,
CHECK_NOTICE_INFO_CD,
plugins2info_dict,
plugins2cd_dict,
plugins2exists_dict,
)
from models.ban_user import BanUser
from utils.utils import (
@ -31,13 +33,12 @@ from utils.utils import (
static_flmt,
BanCheckLimiter,
FreqLimiter,
UserExistLimiter,
)
from utils.static_data import withdraw_message_id_manager
from utils.manager import withdraw_message_manager
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.manager import group_manager
import asyncio
try:
@ -45,8 +46,6 @@ try:
except ModuleNotFoundError:
import json
withdraw_message_id_manager["message_id"] = []
# 检查是否被ban
@run_preprocessor
@ -153,18 +152,27 @@ ignore_rst_module = ["ai", "poke"]
@run_preprocessor
async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
global _exists_msg
module = matcher.module
plugins2info_dict = plugins2settings_manager.get_data()
if (
(not isinstance(event, MessageEvent) and matcher.module != "poke")
(not isinstance(event, MessageEvent) and module != "poke")
or await BanUser.is_ban(event.user_id)
or str(event.user_id) in bot.config.superusers
and str(event.user_id) not in bot.config.superusers
) or (
str(event.user_id) in bot.config.superusers
and plugins2info_dict.get(module)
and not plugins2info_dict[module]["limit_superuser"]
):
return
module = matcher.module
if module in admin_plugins_auth.keys() and matcher.priority not in [1, 9]:
# 黑名单检测
if isinstance(event, GroupMessageEvent):
if group_manager.get_group_level(event.group_id) < 0:
raise IgnoredException("群黑名单")
if module in admin_manager.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[module]
event.user_id, event.group_id, admin_manager.get_plugin_level(module)
):
try:
if _flmt.check(event.user_id):
@ -172,19 +180,19 @@ async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
await bot.send_group_msg(
group_id=event.group_id,
message=f"{at(event.user_id)}你的权限不足喔,该功能需要的权限等级:"
f"{admin_plugins_auth[module]}",
f"{admin_manager.get_plugin_level(module)}",
)
except ActionFailed:
pass
raise IgnoredException("权限不足")
else:
if not await LevelUser.check_level(
event.user_id, 0, admin_plugins_auth[module]
event.user_id, 0, admin_manager.get_plugin_level(module)
):
try:
await bot.send_private_msg(
user_id=event.user_id,
message=f"你的权限不足喔,该功能需要的权限等级:{admin_plugins_auth[module]}",
message=f"你的权限不足喔,该功能需要的权限等级:{admin_manager.get_plugin_level(module)}",
)
except ActionFailed:
pass
@ -198,7 +206,7 @@ async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
_exists_msg[event.group_id] = False
# 群权限
if plugins2info_dict[module]["level"] > group_manager.get_group_level(
str(event.group_id)
event.group_id
):
try:
if _flmt_g.check(event.user_id) and module not in ignore_rst_module:
@ -211,7 +219,7 @@ async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
_exists_msg[event.group_id] = True
raise IgnoredException("群权限不足")
# 插件状态
if not group_manager.get_plugin_status(module, str(event.group_id)):
if not group_manager.get_plugin_status(module, event.group_id):
try:
if module not in ignore_rst_module and _flmt_s.check(
event.group_id
@ -223,11 +231,10 @@ async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
except ActionFailed:
pass
_exists_msg[event.group_id] = True
print(123123)
raise IgnoredException("未开启此功能...")
# 管理员禁用
if not group_manager.get_plugin_status(
f"{module}:super", str(event.group_id)
):
if not group_manager.get_plugin_status(f"{module}:super", event.group_id):
try:
if (
_flmt_s.check(event.group_id)
@ -295,18 +302,6 @@ async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
raise IgnoredException("此功能正在维护...")
check_flmt = {}
for plugin in plugins2cd_dict.keys():
if plugins2cd_dict[plugin]["status"]:
check_flmt[plugin] = FreqLimiter(plugins2cd_dict[plugin]["cd"])
check_elmt = {}
for plugin in plugins2exists_dict.keys():
if plugins2exists_dict[plugin]["status"]:
check_elmt[plugin] = UserExistLimiter()
# 命令cd 和 命令阻塞
@run_preprocessor
async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
@ -316,56 +311,46 @@ async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
module = matcher.module
if isinstance(event, GroupMessageEvent) and _exists_msg.get(event.group_id) is None:
_exists_msg[event.group_id] = False
if module in plugins2cd_dict.keys() and module in check_flmt.keys():
if plugins2cd_manager.check_plugin_cd_status(module):
plugin_cd_data = plugins2cd_manager.get_plugin_cd_data(module)
check_type = plugin_cd_data["check_type"]
limit_type = plugin_cd_data["limit_type"]
rst = plugin_cd_data["rst"]
if (
(
isinstance(event, PrivateMessageEvent)
and plugins2cd_dict[module]["check_type"] == "private"
)
or (
isinstance(event, GroupMessageEvent)
and plugins2cd_dict[module]["check_type"] == "group"
)
or plugins2cd_dict[module]["check_type"] == "all"
) and plugins2cd_dict[module]["cd"] > 0:
(isinstance(event, PrivateMessageEvent) and check_type == "private")
or (isinstance(event, GroupMessageEvent) and check_type == "group")
or plugins2cd_manager.get_plugin_data(module).get("check_type") == "all"
):
cd_type_ = event.user_id
if plugins2cd_dict[module]["limit_type"] == "group" and isinstance(
event, GroupMessageEvent
):
if limit_type == "group" and isinstance(event, GroupMessageEvent):
cd_type_ = event.group_id
if not check_flmt[module].check(cd_type_):
rst = plugins2cd_dict[module]["rst"]
if not plugins2cd_manager.check(module, cd_type_):
if rst:
rst = await init_rst(rst, event)
await send_msg(rst, bot, event)
raise IgnoredException(f"{module} 正在cd中...")
else:
check_flmt[module].start_cd(cd_type_)
if module in plugins2exists_dict.keys() and module in check_elmt.keys():
plugins2cd_manager.start_cd(module, cd_type_)
if plugins2block_manager.check_plugin_block_status(module):
plugin_block_data = plugins2block_manager.get_plugin_block_data(module)
check_type = plugin_block_data["check_type"]
limit_type = plugin_block_data["limit_type"]
rst = plugin_block_data["rst"]
if (
(
isinstance(event, PrivateMessageEvent)
and plugins2exists_dict[module]["check_type"] == "private"
)
or (
isinstance(event, GroupMessageEvent)
and plugins2exists_dict[module]["check_type"] == "group"
)
or plugins2exists_dict[module]["check_type"] == "all"
(isinstance(event, PrivateMessageEvent) and check_type == "private")
or (isinstance(event, GroupMessageEvent) and check_type == "group")
or check_type == "all"
):
exists_type_ = event.user_id
if plugins2exists_dict[module]["limit_type"] == "group" and isinstance(
event, GroupMessageEvent
):
exists_type_ = event.group_id
if check_elmt[module].check(exists_type_):
rst = plugins2exists_dict[module]["rst"]
block_type_ = event.user_id
if limit_type == "group" and isinstance(event, GroupMessageEvent):
block_type_ = event.group_id
if plugins2block_manager.check(block_type_, module):
if rst:
rst = await init_rst(rst, event)
await send_msg(rst, bot, event)
raise IgnoredException(f"{event.user_id}正在调用{module}....")
else:
check_elmt[module].set_true(exists_type_)
plugins2block_manager.set_true(block_type_, module)
async def send_msg(rst: str, bot: Bot, event: MessageEvent):
@ -399,23 +384,18 @@ async def _(
if not isinstance(event, MessageEvent) and matcher.module != "poke":
return
module = matcher.module
if module in plugins2exists_dict.keys() and module in check_elmt.keys():
if plugins2block_manager.check_plugin_block_status(module):
plugin_block_data = plugins2block_manager.get_plugin_block_data(module)
check_type = plugin_block_data["check_type"]
limit_type = plugin_block_data["limit_type"]
if not (
(
isinstance(event, GroupMessageEvent)
and plugins2exists_dict[module]["check_type"] == "private"
)
or (
isinstance(event, PrivateMessageEvent)
and plugins2exists_dict[module]["check_type"] == "group"
)
(isinstance(event, GroupMessageEvent) and check_type == "private")
or (isinstance(event, PrivateMessageEvent) and check_type == "group")
):
exists_type_ = event.user_id
if plugins2exists_dict[module]["limit_type"] == "group" and isinstance(
event, GroupMessageEvent
):
exists_type_ = event.group_id
check_elmt[module].set_false(exists_type_)
block_type_ = event.user_id
if limit_type == "group" and isinstance(event, GroupMessageEvent):
block_type_ = event.group_id
plugins2block_manager.set_false(block_type_, module)
async def init_rst(rst: str, event: MessageEvent):
@ -445,9 +425,9 @@ async def _(
state: T_State,
):
tasks = []
for id_, time in withdraw_message_id_manager["message_id"]:
for id_, time in withdraw_message_manager.data:
tasks.append(asyncio.ensure_future(_withdraw_message(bot, id_, time)))
withdraw_message_id_manager["message_id"].remove((id_, time))
withdraw_message_manager.remove((id_, time))
await asyncio.gather(*tasks)

View File

@ -0,0 +1,3 @@
import nonebot
nonebot.load_plugins("plugins/image_management")

View File

@ -1,86 +1,97 @@
from configs.path_config import IMAGE_PATH, TEMP_PATH
from utils.message_builder import image
from services.log import logger
from nonebot import on_command
from nonebot.rule import to_me
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__ = "删除图片"
__plugin_usage__ = (
"删除图片帮助:\n\t"
"1.查看列表 --> 指令: 删除图片 列表/目录\n\t"
"2.删除图片 图库 id, 即在相应目录下删除图片\n\t\t示例: 删除图片 色图 1 "
)
delete_img = on_command("删除图片", priority=5, rule=to_me(), block=True)
@delete_img.args_parser
async def parse(bot: Bot, event: MessageEvent, state: T_State):
if str(event.get_message()) in ["取消", "算了"]:
await delete_img.finish("已取消操作..", at_sender=True)
if state["_current_key"] in ["path"]:
if str(event.get_message()) not in IMAGE_DIR_LIST:
await delete_img.reject("此目录不正确,请重新输入目录!")
state[state["_current_key"]] = str(event.get_message())
if state["_current_key"] == "id":
if not is_number(str(event.get_message())):
await delete_img.reject("id不正确请重新输入数字...")
state[state["_current_key"]] = str(event.get_message())
@delete_img.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
raw_arg = str(event.get_message()).strip()
if raw_arg:
args = raw_arg.split(" ")
if args[0] in ["帮助"]:
await delete_img.finish(__plugin_usage__)
if len(args) >= 2 and args[0] in IMAGE_DIR_LIST and is_number(args[1]):
state["path"] = args[0]
state["id"] = args[1]
@delete_img.got("path", prompt="请输入要删除的目标图库?")
@delete_img.got("id", prompt="请输入要删除的图片id")
async def arg_handle(bot: Bot, event: MessageEvent, state: T_State):
path = cn2py(state["path"])
img_id = state["id"]
# 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(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 / 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 / f"{img_id}.jpg"):
try:
if int(img_id) != max_id:
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} 删除成功"
)
await delete_img.finish(
f"id: {img_id} 删除成功" + image("delete.jpg", TEMP_PATH), at_sender=True
)
await delete_img.finish(f"id: {img_id} 删除失败!")
from configs.path_config import IMAGE_PATH, TEMP_PATH
from utils.message_builder import image
from services.log import logger
from nonebot import on_command
from nonebot.rule import to_me
from nonebot.typing import T_State
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent
from configs.config import DELETE_IMG_LEVEL
from configs.config import IMAGE_DIR_LIST
from utils.utils import is_number, cn2py, get_message_text
from pathlib import Path
import os
__zx_plugin_name__ = "删除图片 [Admin]"
__plugin_usage__ = """
usage
删除图库指定图片
指令
删除图片 [图库] [id]
查看图库
示例删除图片 美图 666
""".strip()
__plugin_des__ = "不好看的图片删掉删掉!"
__plugin_cmd__ = ["删除图片 [图库] [id]", "查看公开图库"]
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {
"admin_level": DELETE_IMG_LEVEL
}
delete_img = on_command("删除图片", priority=5, rule=to_me(), block=True)
@delete_img.args_parser
async def parse(bot: Bot, event: MessageEvent, state: T_State):
if get_message_text(event.json()) in ["取消", "算了"]:
await delete_img.finish("已取消操作..", at_sender=True)
if state["_current_key"] in ["path"]:
if get_message_text(event.json()) not in IMAGE_DIR_LIST:
await delete_img.reject("此目录不正确,请重新输入目录!")
state[state["_current_key"]] = get_message_text(event.json())
if state["_current_key"] == "id":
if not is_number(get_message_text(event.json())):
await delete_img.reject("id不正确请重新输入数字...")
state[state["_current_key"]] = get_message_text(event.json())
@delete_img.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
raw_arg = get_message_text(event.json()).strip()
if raw_arg:
args = raw_arg.split(" ")
if args[0] in ["帮助"]:
await delete_img.finish(__plugin_usage__)
if len(args) >= 2 and args[0] in IMAGE_DIR_LIST and is_number(args[1]):
state["path"] = args[0]
state["id"] = args[1]
@delete_img.got("path", prompt="请输入要删除的目标图库?")
@delete_img.got("id", prompt="请输入要删除的图片id")
async def arg_handle(bot: Bot, event: MessageEvent, state: T_State):
path = cn2py(state["path"])
img_id = state["id"]
# 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(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 / 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 / f"{img_id}.jpg"):
try:
if int(img_id) != max_id:
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} 删除成功"
)
await delete_img.finish(
f"id: {img_id} 删除成功" + image("delete.jpg", TEMP_PATH), at_sender=True
)
await delete_img.finish(f"id: {img_id} 删除失败!")

View File

@ -1,95 +1,105 @@
import os
from services.log import logger
from nonebot import on_command
from nonebot.rule import to_me
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 configs.path_config import IMAGE_PATH
from pathlib import Path
__plugin_name__ = "移动图片"
__plugin_usage__ = (
"移动图片帮助:\n\t"
"1.查看列表 --> 指令: 移动图片 列表/目录\n\t"
"2.移动图片 源 目的 id\n\t\t示例: 移动图片 色图 美图 1234"
)
move_img = on_command("移动图片", priority=5, rule=to_me(), block=True)
@move_img.args_parser
async def parse(bot: Bot, event: MessageEvent, state: T_State):
if str(event.get_message()) in ["取消", "算了"]:
await move_img.finish("已取消操作..", at_sender=True)
if state["_current_key"] in ["source_path", "destination_path"]:
if str(event.get_message()) not in IMAGE_DIR_LIST:
await move_img.reject("此目录不正确,请重新输入目录!")
state[state["_current_key"]] = str(event.get_message())
if state["_current_key"] == "id":
if not is_number(str(event.get_message())):
await move_img.reject("id不正确请重新输入数字...")
state[state["_current_key"]] = str(event.get_message())
@move_img.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
raw_arg = str(event.get_message()).strip()
if raw_arg:
args = raw_arg.split(" ")
if args[0] in ["帮助"]:
await move_img.finish(__plugin_usage__)
if (
len(args) >= 3
and args[0] in IMAGE_DIR_LIST
and args[1] in IMAGE_DIR_LIST
and is_number(args[2])
):
state["source_path"] = args[0]
state["destination_path"] = args[1]
state["id"] = args[2]
else:
await move_img.finish("参数错误,请重试", at_sender=True)
@move_img.got("source_path", prompt="要从哪个图库移出?")
@move_img.got("destination_path", prompt="要移动到哪个图库?")
@move_img.got("id", prompt="要移动的图片id是")
async def _(bot: Bot, event: MessageEvent, state: T_State):
img_id = state["id"]
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 / f"{img_id}.jpg", destination_path / f"{des_max_id}.jpg"
)
logger.info(
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}"
)
await move_img.finish(f"移动图片id{img_id} 失败了...", at_sender=True)
if max_id > 0:
try:
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}"
)
await move_img.finish(f"替换图片id{max_id} -> {img_id} 失败了...", at_sender=True)
logger.info(
f"USER {event.user_id} GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'} ->"
f" {source_path} --> {destination_path} (id{img_id}) 移动图片成功"
)
await move_img.finish(f"移动图片 id{img_id} --> id{des_max_id}成功", at_sender=True)
import os
from services.log import logger
from nonebot import on_command
from nonebot.rule import to_me
from nonebot.typing import T_State
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent
from configs.config import IMAGE_DIR_LIST, MOVE_IMG_LEVEL
from utils.utils import is_number, cn2py
from configs.path_config import IMAGE_PATH
from pathlib import Path
__zx_plugin_name__ = "移动图片 [Admin]"
__plugin_usage__ = """
usage
图库间的图片移动操作
指令
移动图片 [源图库] [目标图库] [id]
查看图库
示例移动图片 萝莉 美图 234
""".strip()
__plugin_des__ = "图库间的图片移动操作"
__plugin_cmd__ = ["移动图片 [源图库] [目标图库] [id]", "查看公开图库"]
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {
"admin_level": MOVE_IMG_LEVEL
}
move_img = on_command("移动图片", priority=5, rule=to_me(), block=True)
@move_img.args_parser
async def parse(bot: Bot, event: MessageEvent, state: T_State):
if str(event.get_message()) in ["取消", "算了"]:
await move_img.finish("已取消操作..", at_sender=True)
if state["_current_key"] in ["source_path", "destination_path"]:
if str(event.get_message()) not in IMAGE_DIR_LIST:
await move_img.reject("此目录不正确,请重新输入目录!")
state[state["_current_key"]] = str(event.get_message())
if state["_current_key"] == "id":
if not is_number(str(event.get_message())):
await move_img.reject("id不正确请重新输入数字...")
state[state["_current_key"]] = str(event.get_message())
@move_img.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
raw_arg = str(event.get_message()).strip()
if raw_arg:
args = raw_arg.split(" ")
if args[0] in ["帮助"]:
await move_img.finish(__plugin_usage__)
if (
len(args) >= 3
and args[0] in IMAGE_DIR_LIST
and args[1] in IMAGE_DIR_LIST
and is_number(args[2])
):
state["source_path"] = args[0]
state["destination_path"] = args[1]
state["id"] = args[2]
else:
await move_img.finish("参数错误,请重试", at_sender=True)
@move_img.got("source_path", prompt="要从哪个图库移出?")
@move_img.got("destination_path", prompt="要移动到哪个图库?")
@move_img.got("id", prompt="要移动的图片id是")
async def _(bot: Bot, event: MessageEvent, state: T_State):
img_id = state["id"]
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 / f"{img_id}.jpg", destination_path / f"{des_max_id}.jpg"
)
logger.info(
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}"
)
await move_img.finish(f"移动图片id{img_id} 失败了...", at_sender=True)
if max_id > 0:
try:
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}"
)
await move_img.finish(f"替换图片id{max_id} -> {img_id} 失败了...", at_sender=True)
logger.info(
f"USER {event.user_id} GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'} ->"
f" {source_path} --> {destination_path} (id{img_id}) 移动图片成功"
)
await move_img.finish(f"移动图片 id{img_id} --> id{des_max_id}成功", at_sender=True)

View File

@ -1,103 +1,127 @@
from nonebot import on_command
from nonebot.rule import to_me
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 get_message_imgs, get_message_text
from .data_source import upload_image_to_local
__plugin_name__ = "上传图片"
__plugin_usage__ = (
"上传图片帮助:\n\t"
"1.查看列表 --> 指令: 上传图片 列表/目录\n\t"
"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 _(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 msg not in IMAGE_DIR_LIST:
await upload_img.reject("此目录不正确,请重新输入目录!")
state['path'] = msg
if state["_current_key"] in ["imgs"]:
if not get_message_imgs(event.json()):
await upload_img.reject("图呢图呢图呢图呢GKD")
state['imgs'] = get_message_imgs(event.json())
@upload_img.handle()
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 raw_arg in IMAGE_DIR_LIST:
state["path"] = raw_arg
if img_list:
state["imgs"] = img_list
@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 = 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:
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))
from nonebot import on_command
from nonebot.rule import to_me
from nonebot.typing import T_State
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent
from configs.config import IMAGE_DIR_LIST, UPLOAD_IMG_LEVEL
from utils.utils import get_message_imgs, get_message_text
from .data_source import upload_image_to_local
__zx_plugin_name__ = "上传图片 [Admin]"
__plugin_usage__ = """
usage
上传图片至指定图库
指令
查看图库
上传图片 [图库] [图片]
连续上传图片 [图库]
示例上传图片 美图 [图片]
* 连续上传图片可以通过发送 stop 表示停止收集发送的图片可以开始上传 *
""".strip()
__plugin_des__ = "指定图库图片上传"
__plugin_cmd__ = ["上传图片 [图库] [图片]", "连续上传图片 [图库]", "查看公开图库"]
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {"admin_level": UPLOAD_IMG_LEVEL}
upload_img = on_command("上传图片", rule=to_me(), priority=5, block=True)
continuous_upload_img = on_command("连续上传图片", rule=to_me(), priority=5, block=True)
show_gallery = on_command("查看公开图库", priority=1, block=True)
@show_gallery.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
x = '公开图库列表:\n'
for i, e in enumerate(IMAGE_DIR_LIST):
x += f'\t{i+1}.{e}\n'
await show_gallery.send(x[:-1])
@upload_img.args_parser
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 msg not in IMAGE_DIR_LIST:
await upload_img.reject("此目录不正确,请重新输入目录!")
state["path"] = msg
if state["_current_key"] in ["imgs"]:
if not get_message_imgs(event.json()):
await upload_img.reject("图呢图呢图呢图呢GKD")
state["imgs"] = get_message_imgs(event.json())
@upload_img.handle()
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 raw_arg in IMAGE_DIR_LIST:
state["path"] = raw_arg
if img_list:
state["imgs"] = img_list
@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 = 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:
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,36 @@
from .data_source import (
init_plugins_settings,
init_plugins_cd_limit,
init_plugins_block_limit,
init_group_manager,
)
from nonebot.adapters.cqhttp import Bot
from configs.path_config import DATA_PATH
from services.log import logger
from nonebot import Driver
import nonebot
__zx_plugin_name__ = "初始化插件数据 [Hidden]"
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
driver: Driver = nonebot.get_driver()
@driver.on_startup
def _():
"""
初始化数据
"""
init_plugins_settings(DATA_PATH)
init_plugins_cd_limit(DATA_PATH)
init_plugins_block_limit(DATA_PATH)
logger.info("初始化数据完成...")
@driver.on_bot_connect
async def _(bot: Bot):
await init_group_manager()

View File

@ -0,0 +1,290 @@
from pathlib import Path
from ruamel.yaml import YAML, round_trip_load, round_trip_dump
from utils.manager import (
plugins2settings_manager,
plugins2cd_manager,
plugins2block_manager,
group_manager,
admin_manager
)
from services.db_context import db
from asyncpg.exceptions import DuplicateColumnError
from services.log import logger
from utils.utils import get_matchers
import nonebot
try:
import ujson as json
except ModuleNotFoundError:
import json
try:
from models.group_remind import GroupRemind
except ModuleNotFoundError:
pass
yaml = YAML(typ="safe")
def init_plugins_settings(data_path: str):
"""
初始化插件设置从插件中获取 __zx_plugin_name____plugin_cmd____plugin_settings__
"""
plugins2config_file = Path(data_path) / "configs" / "plugins2settings.yaml"
plugins2config_file.parent.mkdir(exist_ok=True, parents=True)
_matchers = get_matchers()
_data = {}
if plugins2config_file.exists():
with open(plugins2config_file, "r", encoding="utf8") as f:
_data = yaml.load(f)
_data = _data["PluginSettings"] if _data else {}
_tmp_module = {}
_tmp = []
for matcher in _matchers:
if matcher.module in _data.keys():
plugins2settings_manager.add_plugin_settings(
matcher.module,
plugin_type=_data[matcher.module]["plugin_type"],
data_dict=_data[matcher.module],
)
if _data[matcher.module]['cmd']:
_tmp_module[matcher.module] = _data[matcher.module]['cmd'][0]
else:
_plugin = nonebot.plugin.get_plugin(matcher.module)
_module = _plugin.module
try:
plugin_name = _module.__getattribute__("__zx_plugin_name__")
if "[admin]" in plugin_name.lower():
try:
level = (_module.__getattribute__("__plugin_settings__"))['admin_level']
except (AttributeError, KeyError):
level = 5
admin_manager.add_admin_command(matcher.module, level)
if (
"[hidden]" in plugin_name.lower()
or "[admin]" in plugin_name.lower()
or "[superuser]" in plugin_name.lower()
or matcher.module in plugins2settings_manager.keys()
):
continue
except AttributeError:
if matcher.module not in _tmp:
logger.warning(
f"获取插件 {matcher.module} __zx_plugin_name__ 失败...,插件控制未加载."
)
else:
try:
_tmp_module[matcher.module] = plugin_name
plugin_settings = _module.__getattribute__("__plugin_settings__")
if plugin_settings['cmd'] and plugin_name not in plugin_settings['cmd']:
plugin_settings['cmd'].append(plugin_name)
if plugins2settings_manager.get(
matcher.module
) and plugins2settings_manager[matcher.module].get("plugin_type"):
plugin_type = tuple(
plugins2settings_manager.get_plugin_data(matcher.module)[
"plugin_type"
]
)
else:
try:
plugin_type = _module.__getattribute__("__plugin_type__")
except AttributeError:
plugin_type = ("normal",)
if plugin_settings and matcher.module:
plugins2settings_manager.add_plugin_settings(
matcher.module,
plugin_type=plugin_type,
data_dict=plugin_settings,
)
except AttributeError:
pass
_tmp.append(matcher.module)
_tmp_data = {"PluginSettings": plugins2settings_manager.get_data()}
with open(plugins2config_file, "w", encoding="utf8") as wf:
yaml.dump(_tmp_data, wf)
_data = round_trip_load(open(plugins2config_file, encoding="utf8"))
_data["PluginSettings"].yaml_set_start_comment(
"""# 模块与对应命令和对应群权限
# 用于生成帮助图片 和 开关功能
# key模块名称
# level需要的群等级
# default_status加入群时功能的默认开关状态
# limit_superuser: 功能状态是否限制超级用户
# cmd: 关闭[cmd] 都会触发命令 关闭对应功能cmd列表第一个词为统计的功能名称
# plugin_type: 帮助类别 示例:('原神相关',) 或 ('原神相关', 1)1代表帮助命令列向排列否则为横向排列""",
indent=2,
)
for plugin in _data["PluginSettings"].keys():
_data["PluginSettings"][plugin].yaml_set_start_comment(
f"{plugin}{_tmp_module[plugin]}", indent=2
)
with open(plugins2config_file, "w", encoding="utf8") as wf:
round_trip_dump(_data, wf)
logger.info(f"已成功加载 {len(plugins2settings_manager.get_data())} 个非限制插件.")
print(admin_manager)
def init_plugins_cd_limit(data_path):
"""
加载 cd 限制
"""
plugins2cd_file = Path(data_path) / "configs" / "plugins2cd.yaml"
plugins2cd_file.parent.mkdir(exist_ok=True, parents=True)
_data = {}
_matchers = get_matchers()
for matcher in _matchers:
if not plugins2cd_manager.get_plugin_cd_data(matcher.module):
_plugin = nonebot.plugin.get_plugin(matcher.module)
_module = _plugin.module
try:
plugin_cd_limit = _module.__getattribute__("__plugin_cd_limit__")
plugins2cd_manager.add_cd_limit(
matcher.module, data_dict=plugin_cd_limit
)
except AttributeError:
pass
if plugins2cd_file.exists():
with open(plugins2cd_file, "r", encoding="utf8") as f:
_data = yaml.load(f)
_data = _data if _data else {}
if _data.get("PluginCdLimit"):
for plugin in _data["PluginCdLimit"].keys():
plugins2cd_manager.add_cd_limit(
plugin, data_dict=_data["PluginCdLimit"][plugin]
)
_tmp_data = {"PluginCdLimit": plugins2cd_manager.get_data()}
with open(plugins2cd_file, "w", encoding="utf8") as wf:
yaml.dump(_tmp_data, wf)
_data = round_trip_load(open(plugins2cd_file, encoding="utf8"))
_data["PluginCdLimit"].yaml_set_start_comment(
"""# 需要cd的功能
# 自定义的功能需要cd也可以在此配置
# key模块名称
# cdcd 时长(秒)
# status此限制的开关状态
# check_type'private'/'group'/'all',限制私聊/群聊/全部
# limit_type监听对象以user_id或group_id作为键来限制'user'用户id'group'群id
# 示例:'user'用户N秒内触发1次'group'群N秒内触发1次
# rst回复的话可以添加[at][uname][nickname]来对应艾特,用户群名称,昵称系统昵称
# rst 为 "" 或 None 时则不回复
# rst示例"[uname]你冲的太快了,[nickname]先生,请稍后再冲[at]"
# rst回复"老色批你冲的太快了,欧尼酱先生,请稍后再冲@老色批"
# 用户昵称↑ 昵称系统的昵称↑ 艾特用户↑""",
indent=2,
)
with open(plugins2cd_file, "w", encoding="utf8") as wf:
round_trip_dump(_data, wf)
plugins2cd_manager.reload_cd_limit()
def init_plugins_block_limit(data_path):
"""
加载阻塞限制
"""
plugins2block_file = Path(data_path) / "configs" / "plugins2block.yaml"
plugins2block_file.parent.mkdir(exist_ok=True, parents=True)
_data = {}
_matchers = get_matchers()
for matcher in _matchers:
if not plugins2block_manager.get_plugin_block_data(matcher.module):
_plugin = nonebot.plugin.get_plugin(matcher.module)
_module = _plugin.module
try:
plugin_block_limit = _module.__getattribute__("__plugin_block_limit__")
plugins2block_manager.add_block_limit(
matcher.module, data_dict=plugin_block_limit
)
except AttributeError:
pass
if plugins2block_file.exists():
with open(plugins2block_file, "r", encoding="utf8") as f:
_data = yaml.load(f)
_data = _data if _data else {}
if _data.get("PluginBlockLimit"):
for plugin in _data["PluginBlockLimit"].keys():
plugins2block_manager.add_block_limit(
plugin, data_dict=_data["PluginBlockLimit"][plugin]
)
_tmp_data = {"PluginBlockLimit": plugins2block_manager.get_data()}
with open(plugins2block_file, "w", encoding="utf8") as wf:
yaml.dump(_tmp_data, wf)
_data = round_trip_load(open(plugins2block_file, encoding="utf8"))
_data["PluginBlockLimit"].yaml_set_start_comment(
"""# 用户调用阻塞
# 即 当用户调用此功能还未结束时
# 用发送消息阻止用户重复调用此命令直到该命令结束
# key模块名称
# cdcd 时长(秒)
# status此限制的开关状态
# check_type'private'/'group'/'all',限制私聊/群聊/全部
# limit_type监听对象以user_id或group_id作为键来限制'user'用户id'group'群id
# 示例:'user'用户N秒内触发1次'group'群N秒内触发1次
# rst回复的话可以添加[at][uname][nickname]来对应艾特,用户群名称,昵称系统昵称
# rst 为 "" 或 None 时则不回复
# rst示例"[uname]你冲的太快了,[nickname]先生,请稍后再冲[at]"
# rst回复"老色批你冲的太快了,欧尼酱先生,请稍后再冲@老色批"
# 用户昵称↑ 昵称系统的昵称↑ 艾特用户↑""",
indent=2,
)
with open(plugins2block_file, "w", encoding="utf8") as wf:
round_trip_dump(_data, wf)
plugins2block_manager.reload_block_limit()
async def init_group_manager():
"""
旧数据格式替换为新格式
初始化数据
"""
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()
old_data_table = Path() / "models" / "group_remind.py"
try:
if old_data_table.exists():
b = {
"hy": "group_welcome",
"kxcz": "open_case_reset_remind",
"zwa": "zwa",
"blpar": "bilibili_parse",
"epic": "epic_free_game",
"pa": "pa",
"almanac": "genshin_alc",
}
for group in group_manager.get_data()["group_manager"]:
for remind in b:
try:
status = await GroupRemind.get_status(int(group), remind)
if status is not None:
if status:
await group_manager.open_group_task(group, b[remind])
logger.info(f"读取旧数据-->{group} 开启 {b[remind]}")
else:
await group_manager.close_group_task(group, b[remind])
logger.info(f"读取旧数据-->{group} 关闭 {b[remind]}")
except Exception as e:
pass
query = db.text("DROP TABLE group_reminds;")
await db.first(query)
old_data_table.unlink()
logger.info("旧数据读取完毕,删除了舍弃表 group_reminds...")
except (ModuleNotFoundError, DuplicateColumnError):
pass
group_manager.save()

View File

@ -5,11 +5,25 @@ 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__ = f"用法: 发送’鸡汤‘,{NICKNAME}亲自为你喝鸡汤"
__zx_plugin_name__ = "鸡汤"
__plugin_usage__ = """
usage
不喝点什么感觉有点不舒服
指令
鸡汤
""".strip()
__plugin_des__ = "喏,亲手为你煮的鸡汤"
__plugin_cmd__ = ["鸡汤"]
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {
"level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ["鸡汤", "毒鸡汤"],
}
url = "https://v2.alapi.cn/api/soul"

View File

@ -1,28 +1,41 @@
from PIL import ImageFont, ImageDraw, Image
import textwrap
from configs.path_config import IMAGE_PATH, TTF_PATH
from configs.path_config import IMAGE_PATH
from nonebot import on_command
from nonebot.typing import T_State
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent
from utils.message_builder import image
from services.log import logger
from utils.utils import UserExistLimiter, get_message_text
from utils.image_utils import pic2b64
__plugin_name__ = "鲁迅说"
__plugin_usage__ = "用法:鲁迅说 [消息]"
_ulmt = UserExistLimiter()
from utils.utils import get_message_text
from utils.image_utils import CreateImg
__zx_plugin_name__ = "鲁迅说"
__plugin_usage__ = """
usage
鲁迅说了啥
指令
鲁迅说 [文本]
""".strip()
__plugin_des__ = "鲁迅说他没说过这话!"
__plugin_cmd__ = ["鲁迅说"]
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {
"level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ["鲁迅说"],
}
__plugin_block_limit__ = {
"rst": "你的鲁迅正在说,等会"
}
luxun = on_command("鲁迅说过", aliases={"鲁迅说"}, priority=5, block=True)
luxun_author = CreateImg(0, 0, plain_text="--鲁迅", font_size=30, font='msyh.ttf', font_color=(255, 255, 255))
@luxun.handle()
async def handle(bot: Bot, event: MessageEvent, state: T_State):
if _ulmt.check(event.user_id):
await luxun.finish("你的鲁迅正在说,等会", at_sender=True)
args = get_message_text(event.json())
if args:
state["content"] = args if args else "烦了,不说了"
@ -30,39 +43,24 @@ async def handle(bot: Bot, event: MessageEvent, state: T_State):
@luxun.got("content", prompt="你让鲁迅说点啥?")
async def handle_event(bot: Bot, event: MessageEvent, state: T_State):
filename = str(event.user_id) + "_.jpg"
content = state["content"].strip()
if content.startswith(",") or content.startswith(""):
content = content[1:]
_ulmt.set_true(event.user_id)
if len(content) > 20:
_ulmt.set_false(event.user_id)
await luxun.finish("太长了, 鲁迅说不完!", at_sender=True)
else:
if len(content) >= 12:
content = content[:12] + "\n" + content[12:]
img = image(b64=process_pic(content, filename))
logger.info(
f"USER {event.user_id} GROUP "
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'} 鲁迅说过 {content}"
)
await luxun.send(img)
_ulmt.set_false(event.user_id)
def process_pic(content, filename) -> str:
text = content
para = textwrap.wrap(text, width=15)
MAX_W, MAX_H = 480, 280
bk_img = Image.open(IMAGE_PATH + "other/luxun.jpg")
font_path = TTF_PATH + "/msyh.ttf"
font = ImageFont.truetype(font_path, 37)
font2 = ImageFont.truetype(font_path, 30)
draw = ImageDraw.Draw(bk_img)
current_h, pad = 300, 10
for line in para:
w, h = draw.textsize(line, font=font)
draw.text(((MAX_W - w) / 2, current_h), line, font=font)
current_h += h + pad
draw.text((320, 400), "——鲁迅", font=font2, fill=(255, 255, 255))
return pic2b64(bk_img)
A = CreateImg(0, 0, font_size=37, background=f'{IMAGE_PATH}/other/luxun.jpg', font='msyh.ttf')
x = ""
if len(content) > 40:
await luxun.finish('太长了,鲁迅说不完...')
while A.getsize(content)[0] > A.w - 50:
n = int(len(content) / 2)
x += content[:n] + '\n'
content = content[n:]
x += content
if len(x.split('\n')) > 2:
await luxun.finish('太长了,鲁迅说不完...')
A.text((int((480 - A.getsize(x.split("\n")[0])[0]) / 2), 300), x, (255, 255, 255))
A.paste(luxun_author, (320, 400), True)
await luxun.send(image(b64=A.pic2bs4()))
logger.info(
f"USER {event.user_id} GROUP "
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'} 鲁迅说过 {content}"
)

View File

@ -9,27 +9,47 @@ from nonebot.adapters.cqhttp.exception import ActionFailed
from configs.path_config import DATA_PATH, IMAGE_PATH
from utils.image_utils import get_img_hash
from services.log import logger
from configs.config import MUTE_LEVEL
import aiohttp
import aiofiles
from configs.config import MUTE_DEFAULT_COUNT, MUTE_DEFAULT_TIME, MUTE_DEFAULT_DURATION, NICKNAME
from configs.config import (
MUTE_DEFAULT_COUNT,
MUTE_DEFAULT_TIME,
MUTE_DEFAULT_DURATION,
NICKNAME,
)
try:
import ujson as json
except ModuleNotFoundError:
import json
__plugin_name__ = "刷屏禁言"
__plugin_usage__ = "刷屏禁言检测"
__zx_plugin_name__ = "刷屏禁言 [Admin]"
__plugin_usage__ = f"""
usage
刷屏禁言相关操作需要 {NICKNAME} 有群管理员权限
指令
设置刷屏检测时间 []
设置刷屏检测次数 [次数]
设置刷屏禁言时长 [分钟]
刷屏检测设置: 查看当前的刷屏检测设置
* X 秒内发送同样消息 N 禁言 M 分钟 *
""".strip()
__plugin_des__ = "刷屏禁言相关操作"
__plugin_cmd__ = ["设置刷屏检测时间 [秒]", "设置刷屏检测次数 [次数]", "设置刷屏禁言时长 [分钟]", "刷屏检测设置"]
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {"admin_level": MUTE_LEVEL}
mute = on_message(priority=1, block=False)
mute_setting = on_command(
"mute_setting",
aliases={"设置检测时间", "设置检测次数", "设置禁言时长", "刷屏检测设置"},
aliases={"设置刷屏检测时间", "设置刷屏检测次数", "设置刷屏禁言时长", "刷屏检测设置"},
permission=GROUP,
block=True,
priority=5
priority=5,
)
@ -51,14 +71,16 @@ def save_data():
async def download_img_and_hash(url, group_id):
try:
async with aiohttp.ClientSession() as session:
async with session.get(url, proxy=get_local_proxy(), timeout=10) as response:
async with session.get(
url, proxy=get_local_proxy(), timeout=10
) as response:
async with aiofiles.open(
IMAGE_PATH + f"temp/mute_{group_id}_img.jpg", "wb"
) as f:
await f.write(await response.read())
return str(get_img_hash(IMAGE_PATH + f"temp/mute_{group_id}_img.jpg"))
except TimeoutError:
return ''
return ""
mute_dict = {}

View File

@ -6,8 +6,19 @@ from models.group_member_info import GroupInfoUser
from datetime import timedelta
from models.level_user import LevelUser
__plugin_name__ = "更新群组成员列表 [Hidden]"
__plugin_usage__ = "用法:\n" "更新群员的信息"
__zx_plugin_name__ = "个人信息权限查看"
__plugin_usage__ = """
usage
个人信息权限查看
指令
我的信息
我的权限
""".strip()
__plugin_des__ = "我们还记得你和你的权利"
__plugin_cmd__ = ["我的信息", "我的权限"]
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
get_my_group_info = on_command("我的信息", permission=GROUP, priority=1, block=True)

View File

@ -6,9 +6,24 @@ from services.log import logger
import ujson as json
import aiohttp
__plugin_name__ = "能不能好好说话"
__plugin_usage__ = "用法:\n nbnhhsh [文本]"
__zx_plugin_name__ = "能不能好好说话"
__plugin_usage__ = """
usage
说人话
指令
nbnhhsh [文本]
""".strip()
__plugin_des__ = "能不能好好说话,说人话"
__plugin_cmd__ = ["nbnhhsh [文本]"]
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {
"level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ["能不能好好说话", "nbnhhsh"],
}
HHSH_GUESS_URL = "https://lab.magiconch.com/api/nbnhhsh/guess"
@ -18,6 +33,8 @@ nbnhhsh = on_command("nbnhhsh", aliases={"能不能好好说话"}, priority=5, b
@nbnhhsh.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = get_message_text(event.json())
if not msg:
await nbnhhsh.finish('没话说就别说话!')
async with aiohttp.ClientSession(
headers={"content-type": "application/json"}
) as session:

View File

@ -11,9 +11,18 @@ from services.log import logger
from configs.config import NICKNAME
__plugin_name__ = "昵称系统"
__plugin_usage__ = f"用法:\n以后叫我 [名称]\n{NICKNAME}我是谁"
__zx_plugin_name__ = "昵称系统"
__plugin_usage__ = f"""
usage
个人昵称系统群聊 私聊 昵称相互独立
指令
以后叫我 [昵称]
{NICKNAME}我是谁
""".strip()
__plugin_des__ = "区区昵称,才不想叫呢!"
__plugin_cmd__ = ["以后叫我 [昵称]", f"{NICKNAME}我是谁"]
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
nickname = on_command(
"nickname",

View File

@ -19,16 +19,31 @@ from .trace import get_des as get_des_trace
from .yandex import get_des as get_des_yandex
__plugin_name__ = "识图"
__plugin_usage__ = "用法:识图 [参数](默认nao) [图片]\n" "参数列表:\n" "\t1.nao\n" "\t2.asc"
__zx_plugin_name__ = "识图"
__plugin_usage__ = """
usage
识别图片 [二次元图片]
指令
识图 [图片]
""".strip()
__plugin_des__ = "以图搜图,看破本源"
__plugin_cmd__ = ["识图"]
__plugin_type__ = ("一些工具",)
__plugin_version__ = 0.1
__plugin_author__ = "synodriver"
__plugin_settings__ = {
"level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ["识图"],
}
async def get_des(url: str, mode: str, user_id: int):
"""
:param url: 图片链接
:param mode: 图源
:return:
:param user_id: 用户 id
"""
if mode == "iqdb":
async for msg in get_des_iqdb(url):
@ -57,8 +72,6 @@ setu = on_command("识图", aliases={"search"}, block=True, priority=5)
async def handle_first_receive(bot: Bot, event: MessageEvent, state: T_State):
msg = get_message_text(event.json())
imgs = get_message_imgs(event.json())
if msg in ["帮助"]:
await setu.finish("示例:\n\t识图 (图片)\n\t识图asc (图片)")
if imgs:
state["setu"] = imgs[0]
if msg:
@ -94,13 +107,16 @@ async def get_setu(bot: Bot, event: MessageEvent, state: T_State):
await bot.send(event=event, message="正在处理图片")
idx = 1
async for msg in get_des(url, mod, event.user_id):
await bot.send(event=event, message=msg)
if idx == MAX_FIND_IMG_COUNT:
break
idx += 1
if msg:
await bot.send(event=event, message=msg)
if idx == MAX_FIND_IMG_COUNT:
break
idx += 1
if id == 1:
await bot.send(event=event, message='没找着.')
logger.info(
f"(USER {event.user_id}, GROUP "
f"{event.group_id if event.message_type != 'private' else 'private'}) 识图:{url}"
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) 识图:{url}"
)
# image_data: List[Tuple] = await get_pic_from_url(url)
# await setu.finish("hso")

View File

@ -93,12 +93,13 @@ async def get_des(url: str, user_id: int):
return
for pic in image_data:
# print(pic)
msg = await download_img(pic[0], user_id) \
+ f"\n相似度:{pic[1]}" \
f"\n标题:{pic[2] if (str(pic[2]).strip() != 'Creator:' and len(str(pic[2]).split('-')) < 3) else '未知'}" \
f"\nPID:{pic[3]}" \
f"\nmember:{pic[4]}\n"
yield msg
if int(str(pic[1]).split('.')[0]) > 80:
msg = await download_img(pic[0], user_id) \
+ f"\n相似度:{pic[1]}" \
f"\n标题:{pic[2] if (str(pic[2]).strip() != 'Creator:' and len(str(pic[2]).split('-')) < 3) else '未知'}" \
f"\nPID:{pic[3]}" \
f"\nmember:{pic[4]}\n"
yield msg
pass

View File

@ -8,10 +8,25 @@ from utils.utils import get_message_text, get_message_at
from utils.message_builder import image
import re
from utils.image_utils import CreateImg
from asyncio.exceptions import TimeoutError
__plugin_name__ = "我有一个朋友"
__plugin_usage__ = "用法:我有一个朋友说/问 [消息] [at](不艾特则群员随机)"
__zx_plugin_name__ = "我有一个朋友"
__plugin_usage__ = """
usage
我有一个朋友他...不知道是不是你
指令
我有一个朋友想问问 [文本] ?[at]: 当at时你的朋友就是艾特对象
""".strip()
__plugin_des__ = "我有一个朋友想问问..."
__plugin_cmd__ = ["我有一个朋友想问问[文本] ?[at]"]
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {
"level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ["我有一个朋友想问问", "我有一个朋友"],
}
one_friend = on_regex(
"^我.*?朋友.*?(想问问|说|让我问问|想问|让我问|想知道|让我帮他问问|让我帮他问|让我帮忙问|让我帮忙问问|问).*",
@ -23,8 +38,13 @@ one_friend = on_regex(
async def get_pic(qq):
url = f"http://q1.qlogo.cn/g?b=qq&nk={qq}&s=100"
async with aiohttp.ClientSession() as session:
async with session.get(url, timeout=5) as response:
return await response.read()
for _ in range(3):
try:
async with session.get(url, timeout=5) as response:
return await response.read()
except TimeoutError:
pass
return None
@one_friend.handle()
@ -40,11 +60,11 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
)
]
)
user_name = '朋友'
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']
user_name = at_user["card"] if at_user["card"] else at_user["nickname"]
msg = re.search(
r"^我.*?朋友.*?(想问问|说|让我问问|想问|让我问|想知道|让我帮他问问|让我帮他问|让我帮忙问|让我帮忙问问|问)(.*)", msg
)
@ -52,7 +72,11 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
if not msg:
msg = "都不知道问什么"
msg = msg.replace("", "").replace("", "").replace("", "")
ava = CreateImg(100, 100, background=BytesIO(await get_pic(qq)))
x = await get_pic(qq)
if x:
ava = CreateImg(100, 100, background=BytesIO(await get_pic(qq)))
else:
ava = CreateImg(100, 100, color=(0, 0, 0))
ava.circle()
text = CreateImg(300, 30, font_size=30)
text.text((0, 0), user_name)

View File

@ -1,4 +1,6 @@
from typing import Type
from nonebot import on_command
from nonebot.matcher import Matcher
from utils.utils import scheduler, get_message_text, is_number
from nonebot.adapters.cqhttp.permission import GROUP
from nonebot.typing import T_State
@ -15,23 +17,57 @@ 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__ = (
"用法:\n"
"看看你的人品罢了\n"
"目前只支持\n\t"
"1.狂牙大行动武器箱\n\t"
"2.突围大行动武器箱\n\t"
"3.命悬一线武器箱\n\t"
"4.裂空武器箱\n\t"
"5.光谱武器箱\n"
f"示例:{NICKNAME}开箱 突围大行动(不输入指定武器箱则随机)\n"
"示例:我的开箱(开箱统计)\n"
"示例:群开箱统计\n"
"示例:我的金色"
)
__zx_plugin_name__ = "开箱"
__plugin_usage__ = """
usage
看看你的人品罢了
模拟开箱完美公布的真实概率只想看看替你省了多少钱
指令
开箱 ?[武器箱]
[1-30]连开箱 ?[武器箱]
我的开箱
我的金色
群开箱统计
* 不包含[武器箱]时随机开箱 *
目前支持的武器箱
1.狂牙大行动武器箱
2.突围大行动武器箱
3.命悬一线武器箱
4.裂空武器箱
5.光谱武器箱
示例开箱 命悬一线
""".strip()
__plugin_superuser_usage__ = """
usage
更新皮肤指令
指令
更新开箱图片 ?[武器箱]
更新开箱价格 ?[武器箱]
* 不指定武器箱时则全部更新 *
* 过多的爬取会导致账号API被封 *
""".strip()
__plugin_des__ = "csgo模拟开箱[戒赌]"
__plugin_cmd__ = [
"开箱 ?[武器箱]",
"[1-30]连开箱 ?[武器箱]",
"我的开箱",
"我的金色",
"群开箱统计",
"更新开箱图片 ?[武器箱] [_superuser]",
"更新开箱价格 ?[武器箱] [_superuser]",
]
__plugin_type__ = ("抽卡相关", 1)
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {
"level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ["csgo开箱", "开箱"],
}
__plugin_task__ = {"open_case_reset_remind": "每日开箱重置提醒"}
__plugin_cd_limit__ = {"rst": "着什么急啊,慢慢来!"}
cases_name = ["狂牙大行动", "突围大行动", "命悬一线", "裂空", "光谱"]
@ -43,12 +79,8 @@ k_open_case = cases_matcher_group.on_command("开箱")
@k_open_case.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
if str(event.get_message()).strip() in ["帮助"]:
await k_open_case.finish(__plugin_usage__)
# if not _flmt.check(event.user_id):
# await k_open_case.finish("着什么急啊,慢慢来!", at_sender=True)
# _flmt.start_cd(event.user_id)
case_name = get_message_text(event.json())
case_name = case_name.replace("武器箱", "").strip()
if case_name:
result = await open_case(event.user_id, event.group_id, case_name)
else:
@ -89,7 +121,7 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
)
open_shilian = cases_matcher_group.on_regex(".*连开箱")
open_shilian: Type[Matcher] = cases_matcher_group.on_regex(".*连开箱")
@open_shilian.handle()
@ -108,11 +140,12 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
num = int(num)
if num > 30:
await open_shilian.finish("开箱次数不要超过30啊笨蛋", at_sender=True)
if num < 0:
await open_shilian.finish("再负开箱就扣你明天开箱数了!", at_sender=True)
else:
await open_shilian.finish("必须要是数字切不要超过30啊笨蛋中文也可", at_sender=True)
case_name = rs.group(2).strip()
if case_name.find("武器箱") != -1:
case_name = case_name.replace("武器箱", "").strip()
case_name = case_name.replace("武器箱", "").strip()
if not case_name:
case_name = random.choice(cases_name)
elif case_name not in cases_name:
@ -157,7 +190,7 @@ num_dict = {
}
update_price = on_command("更新价格", priority=1, permission=SUPERUSER, block=True)
update_price = on_command("更新开箱价格", priority=1, permission=SUPERUSER, block=True)
@update_price.handle()
@ -165,7 +198,7 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
await update_price.send(await util_get_buff_price(str(event.get_message())))
update_img = on_command("更新图片", priority=1, permission=SUPERUSER, block=True)
update_img = on_command("更新开箱图片", priority=1, permission=SUPERUSER, block=True)
@update_img.handle()

View File

@ -9,12 +9,12 @@ from models.open_cases_user import OpenCasesUser
import os
from services.log import logger
from utils.utils import get_bot
from models.group_remind import GroupRemind
from utils.utils import get_cookie_text
from asyncio.exceptions import TimeoutError
import pypinyin
from nonebot.adapters.cqhttp.exception import ActionFailed
from configs.config import BUFF_PROXY
from utils.manager import group_manager
url = "https://buff.163.com/api/market/goods"
# proxies = 'http://49.75.59.242:3128'
@ -264,10 +264,10 @@ async def update_count_daily():
today_open_total=0,
).apply()
bot = get_bot()
gl = await bot.get_group_list(self_id=bot.self_id)
gl = await bot.get_group_list()
gl = [g['group_id'] for g in gl]
for g in gl:
if await GroupRemind.get_status(g, 'kxcz'):
if await group_manager.check_group_task_status(g, 'open_case_reset_remind'):
try:
await bot.send_group_msg(group_id=g, message="今日开箱次数重置成功")
except ActionFailed:

View File

@ -7,7 +7,6 @@ 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
@ -16,8 +15,21 @@ import asyncio
import time
import aiohttp
from bilibili_api import settings
from utils.manager import group_manager
import ujson as json
__zx_plugin_name__ = "B站转发解析"
__plugin_usage__ = """
usage
B站转发解析解析b站分享信息支持bvbilibili链接b站手机端转发卡片cvb23.tv且5分钟内不解析相同url
""".strip()
__plugin_des__ = "B站转发解析"
__plugin_type__ = ("被动相关",)
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_task__ = {"bilibili_parse": "b站转发解析"}
if get_local_proxy():
settings.proxy = get_local_proxy()
@ -28,7 +40,7 @@ _tmp = {}
@parse_bilibili_json.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
if await GroupRemind.get_status(event.group_id, "blpar"):
if await group_manager.check_group_task_status(event.group_id, "bilibili_parse"):
vd_info = None
url = None
if get_message_json(event.json()):
@ -93,17 +105,17 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
if get_message_text(event.json()):
msg = get_message_text(event.json())
if "BV" in msg:
index = msg.find('BV')
if len(msg[index + 2:]) >= 10:
msg = msg[index: index + 12]
url = f'https://www.bilibili.com/video/{msg}'
index = msg.find("BV")
if len(msg[index + 2 :]) >= 10:
msg = msg[index : index + 12]
url = f"https://www.bilibili.com/video/{msg}"
vd_info = await video.Video(bvid=msg).get_info()
elif 'av' in msg:
index = msg.find('av')
if len(msg[index + 2:]) >= 9:
msg = msg[index + 2: index + 11]
elif "av" in msg:
index = msg.find("av")
if len(msg[index + 2 :]) >= 9:
msg = msg[index + 2 : index + 11]
if is_number(msg):
url = f'https://www.bilibili.com/video/{msg}'
url = f"https://www.bilibili.com/video/{msg}"
vd_info = await video.Video(aid=int(msg)).get_info()
elif "https://b23.tv" in msg:
url = "https://" + msg[msg.find("b23.tv") : msg.find("b23.tv") + 13]
@ -117,7 +129,9 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
bvid = url.split("/")[-1]
vd_info = await video.Video(bvid=bvid).get_info()
if vd_info:
if (url in _tmp.keys() and time.time() - _tmp[url] > 30) or url not in _tmp.keys():
if (
url in _tmp.keys() and time.time() - _tmp[url] > 30
) or url not in _tmp.keys():
_tmp[url] = time.time()
aid = vd_info["aid"]
title = vd_info["title"]

View File

@ -1,22 +1,40 @@
from asyncio.exceptions import TimeoutError
import aiofiles
import aiohttp
from nonebot import on_command
from nonebot.adapters.cqhttp import Bot, MessageEvent, Message, GroupMessageEvent
from nonebot.typing import T_State
from utils.utils import get_message_text, is_number
from utils.message_builder import image
import aiohttp
from services.log import logger
from asyncio.exceptions import TimeoutError
import asyncio
import aiofiles
from configs.path_config import IMAGE_PATH
from services.log import logger
from utils.message_builder import image
from utils.utils import get_message_text, is_number
from utils.manager import withdraw_message_manager
try:
import ujson as json
except ModuleNotFoundError:
import json
__plugin_name__ = "p搜"
__plugin_usage__ = "用法: 通过pid在Pixiv上搜索图片\n格式p搜 [pid]\n\t示例p搜 79520120"
__zx_plugin_name__ = "pid搜索"
__plugin_usage__ = """
usage
通过 pid 搜索图片
指令
p搜 [pid]
""".strip()
__plugin_des__ = "通过 pid 搜索图片"
__plugin_cmd__ = ["p搜 [pid]"]
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {
"level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ["p搜"],
}
pid_search = on_command("p搜", aliases={"pixiv搜", "P搜"}, priority=5, block=True)
@ -90,10 +108,7 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
f" 查询图片 PID{pid}"
)
if isinstance(event, GroupMessageEvent):
await asyncio.sleep(30)
await bot.delete_msg(
message_id=msg_id["message_id"], self_id=int(bot.self_id)
)
withdraw_message_manager.append((msg_id, 30))
break
else:
await pid_search.finish("图片下载失败了....", at_sender=True)
@ -103,6 +118,6 @@ async def download_pic(img_url: str, user_id: int):
async with aiohttp.ClientSession() as session:
async with session.get(img_url, timeout=2) as res:
async with aiofiles.open(
f"{IMAGE_PATH}/temp/pid_search_{user_id}.png", "wb"
f"{IMAGE_PATH}/temp/pid_search_{user_id}.png", "wb"
) as f:
await f.write(await res.read())

View File

@ -9,8 +9,14 @@ import nonebot
import asyncio
import os
driver: Driver = nonebot.get_driver()
__zx_plugin_name__ = "更新扩展图库Omega [Hidden]"
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
nonebot.load_plugins("plugins/pix_gallery")
driver: Driver = nonebot.get_driver()
illust_url = f"{HIBIAPI}/api/pixiv/illust"
@ -27,11 +33,13 @@ async def _init_omega_pixiv_illusts():
length = len([x for x in lines if "INSERT INTO" in x.upper()])
all_pid = await OmegaPixivIllusts.get_all_pid()
index = 0
logger.info('检测到OmegaPixivIllusts数据库准备开始更新....')
logger.info("检测到OmegaPixivIllusts数据库准备开始更新....")
for line in lines:
if "INSERT INTO" in line.upper():
index += 1
tasks.append(asyncio.ensure_future(_tasks(line, all_pid, length, index)))
tasks.append(
asyncio.ensure_future(_tasks(line, all_pid, length, index))
)
await asyncio.gather(*tasks)
omega_pixiv_illusts.unlink()
@ -45,12 +53,12 @@ async def _tasks(line: str, all_pid: List[int], length: int, index: int):
x = data.split(maxsplit=3)
pid = int(x[1][:-1].strip())
if pid in all_pid:
logger.info(f'添加OmegaPixivIllusts图库数据已存在 ---> pid{pid}')
logger.info(f"添加OmegaPixivIllusts图库数据已存在 ---> pid{pid}")
return
uid = int(x[2][:-1].strip())
x = x[3].split(", '")
title = x[0].strip()[1:-1]
tmp = x[1].split(', ')
tmp = x[1].split(", ")
author = tmp[0].strip()[:-1]
nsfw_tag = int(tmp[1])
width = int(tmp[2])
@ -68,9 +76,10 @@ async def _tasks(line: str, all_pid: List[int], length: int, index: int):
nsfw_tag,
tags,
datetime.min,
datetime.min
datetime.min,
):
logger.info(f"成功添加OmegaPixivIllusts图库数据 pid{pid} 本次预计存储 {length} 张,已更新第 {index}")
logger.info(
f"成功添加OmegaPixivIllusts图库数据 pid{pid} 本次预计存储 {length} 张,已更新第 {index}"
)
else:
logger.info(f"添加OmegaPixivIllusts图库数据已存在 ---> pid{pid}")

View File

@ -10,7 +10,7 @@ from nonebot.adapters.cqhttp import (
GroupMessageEvent,
PrivateMessageEvent,
)
from utils.static_data import withdraw_message_id_manager
from utils.manager import withdraw_message_manager
from nonebot.typing import T_State
from .data_source import get_image
from models.pixiv import Pixiv
@ -18,6 +18,40 @@ from nonebot import on_command
import random
__zx_plugin_name__ = "PIX"
__plugin_usage__ = """
usage
查看 pix 好康图库
指令
pix ?*[tags]: 通过 tag 获取相似图片不含tag时随机抽取
pix pid[pid]: 查看图库中指定pid图片
""".strip()
__plugin_superuser_usage__ = """
usage
超级用户额外的 pix 指令
指令
pix -s ?*[tags]: 通过tag获取色图不含tag时随机
pix -r ?*[tags]: 通过tag获取r18图不含tag时随机
""".strip()
__plugin_des__ = "这里是PIX图库"
__plugin_cmd__ = [
"pix ?*[tags]",
"pix pid [pid]",
"pix -s ?*[tags] [_superuser]",
"pix -r ?*[tags] [_superuser]",
]
__plugin_type__ = ("来点好康的",)
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {
"level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ["pix", "Pix", "PIX", "pIx"],
}
__plugin_block_limit__ = {"rst": "您有PIX图片正在处理请稍等..."}
pix = on_command("pix", aliases={"PIX", "Pix"}, priority=5, block=True)
@ -46,16 +80,16 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
)
else:
x = keyword.split()
if '-s' in x:
x.remove('-s')
if "-s" in x:
x.remove("-s")
nsfw_tag = 1
elif '-r' in x:
x.remove('-r')
elif "-r" in x:
x.remove("-r")
nsfw_tag = 2
else:
nsfw_tag = 0
if nsfw_tag != 0 and str(event.user_id) not in bot.config.superusers:
await pix.finish('你不能看这些噢,这些都是是留给管理员看的...')
await pix.finish("你不能看这些噢,这些都是是留给管理员看的...")
if len(x) > 1:
if is_number(x[-1]):
num = int(x[-1])
@ -128,6 +162,4 @@ def withdraw_message(event: MessageEvent, id_: int):
or (WITHDRAW_PIX_TIME[1] == 1 and isinstance(event, GroupMessageEvent))
or WITHDRAW_PIX_TIME[1] == 2
):
withdraw_message_id_manager["message_id"].append(
(id_, WITHDRAW_PIX_TIME[0])
)
withdraw_message_manager.append((id_, WITHDRAW_PIX_TIME[0]))

View File

@ -8,14 +8,19 @@ from models.pixiv_keyword_user import PixivKeywordUser
from models.pixiv import Pixiv
from nonebot.permission import SUPERUSER
__plugin_name__ = "添加PIX关键词/UID/PID | 添加PIX黑名单"
__zx_plugin_name__ = "PIX关键词/UID/PID添加管理 [Superuser]"
__plugin_usage__ = """
关键词添加搜图的关键词效果拉胯
UID搜集该画师的图片可指定收藏数
PID收录单张图片
PIX黑名单可以是当个pid也可以是pid_p0等
"""
usage
PIX关键词/UID/PID添加管理操作
指令
添加pix关键词 [Tag]: 添加一个pix搜索收录Tag
添加pixuid [uid]: 添加一个pix搜索收录uid
添加pixpid [pid]: 添加一个pix收录pid
""".strip()
__plugin_des__ = "PIX关键词/UID/PID添加管理"
__plugin_cmd__ = ["添加pix关键词 [Tag]", "添加pixuid [uid]", "添加pixpid [pid]"]
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
add_keyword = on_command("添加pix关键词", aliases={"添加pix关键字"}, priority=1, block=True)

View File

@ -11,12 +11,29 @@ from models.pixiv_keyword_user import PixivKeywordUser
from models.pixiv import Pixiv
__plugin_name__ = "通过/取消/删除pix关键词 | 删除pix图片"
__zx_plugin_name__ = "PIX关键词/UID/PID删除管理 [Superuser]"
__plugin_usage__ = """
通过/取消/删除pix关键词 [关键词/pid/uid] 示例通过pix关键词萝莉通过pix关键词uid:123456通过pix关键词pid:123456
删除pix图片 *[pid] 示例删除pix图片4223442
"""
usage
PIX关键词/UID/PID删除管理操作
指令
通过pix关键词 [关键词/pid/uid]
取消pix关键词 [关键词/pid/uid]
删除pix关键词 [关键词/pid/uid]
删除pix图片 *[pid]
示例通过pix关键词萝莉
示例通过pix关键词uid:123456
示例通过pix关键词pid:123456
示例删除pix图片4223442
""".strip()
__plugin_des__ = "PIX关键词/UID/PID删除管理"
__plugin_cmd__ = [
"通过pix关键词 [关键词/pid/uid]",
"取消pix关键词 [关键词/pid/uid]",
"删除pix关键词 [关键词/pid/uid]",
"删除pix图片 *[pid]",
]
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
pass_keyword = on_command(
@ -31,9 +48,7 @@ del_keyword = on_command(
"删除pix关键词", aliases={"删除pix关键字"}, permission=SUPERUSER, priority=1, block=True
)
del_pic = on_command(
"删除pix图片", permission=SUPERUSER, priority=1, block=True
)
del_pic = on_command("删除pix图片", permission=SUPERUSER, priority=1, block=True)
@del_keyword.handle()

View File

@ -7,11 +7,24 @@ from .data_source import gen_keyword_pic, get_keyword_num
from models.pixiv_keyword_user import PixivKeywordUser
import asyncio
__plugin_name__ = "查看pix图库"
__zx_plugin_name__ = "查看pix图库"
__plugin_usage__ = """
查看pix图库 [keyword]当keyword为空时检查所有图片
"""
usage
查看pix图库
指令
查看pix图库 ?[tags]: 查看指定tag图片数量为空时查看整个图库
""".strip()
__plugin_des__ = "让我看看管理员私藏了多少货"
__plugin_cmd__ = ["查看pix图库 ?[tags]"]
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {
"level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ["查看pix图库"],
}
my_keyword = on_command("我的pix关键词", aliases={"我的pix关键字"}, priority=1, block=True)

View File

@ -9,14 +9,20 @@ from nonebot.adapters.cqhttp import Bot, MessageEvent
import time
__plugin_name__ = "更新pix关键字 | pix检查更新"
__zx_plugin_name__ = "pix检查更新 [Superuser]"
__plugin_usage__ = """
更新pix收录的所有或指定数量的关键词/uid/pid
更新pix关键词 [keyword/uid/pid] [num]=all 示例更新pix关键词uid 5
pix检测更新检测从未更新过的uid和pid
"""
usage
更新pix收录的所有或指定数量的 关键词/uid/pid
指令
更新pix关键词 *[keyword/uid/pid] [num=max]: 更新仅keyword/uid/pid或全部
pix检测更新检测从未更新过的uid和pid
示例更新pix关键词keyword
示例更新pix关键词uid 10
""".strip()
__plugin_des__ = "pix图库收录数据检查更新"
__plugin_cmd__ = ["更新pix关键词 *[keyword/uid/pid] [num=max]", "pix检测更新"]
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
start_update = on_command(
"更新pix关键词", aliases={"更新pix关键字"}, permission=SUPERUSER, priority=1, block=True

View File

@ -13,38 +13,55 @@ from typing import Type
from nonebot.rule import to_me
import time
__plugin_name__ = "P站"
__zx_plugin_name__ = "P站排行/搜图"
__plugin_usage__ = """
usage
P站排行
可选参数
类型
1. 日排行
2. 周排行
3. 月排行
4. 原创排行
5. 新人排行
6. R18日排行
7. R18周排行
8. R18受男性欢迎排行
9. R18重口排行慎重
使用时选择参数序号即可R18仅可私聊
p站排行 ?[参数] ?[数量] ?[日期]
示例
p站排行榜 [无参数默认为日榜]
p站排行榜 1
p站排行榜 1 5
p站排行榜 1 5 2018-4-25
注意空格在线搜索会较慢
---------------------------------
P站搜图
搜图 [关键词] ?[数量] ?[页数=1] ?[r18](不屏蔽R-18)
示例
搜图 樱岛麻衣
搜图 樱岛麻衣 5
搜图 樱岛麻衣 5 r18
默认为 热度排序
注意空格在线搜索会较慢数量可能不符可能该页数量不够也可能被R-18屏蔽
""".strip()
__plugin_des__ = "P站排行榜直接冲P站搜图跟着冲"
__plugin_cmd__ = ["p站排行 ?[参数] ?[数量] ?[日期]", "搜图 [关键词] ?[数量] ?[页数=1] ?[r18](不屏蔽R-18)"]
__plugin_type__ = ("来点好康的",)
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {
"level": 9,
"default_status": True,
"limit_superuser": False,
"cmd": ["pixiv", "p站排行", "搜图", "p站搜图", "P站搜图"],
}
__plugin_block_limit__ = {
"rst": "P站排行榜或搜图正在搜索请不要重复触发命令..."
}
__plugin_usage__ = """P站排行榜帮助
可选参数
类型
1. 日排行
2. 周排行
3. 月排行
4. 原创排行
5. 新人排行
6. R18日排行
7. R18周排行
8. R18受男性欢迎排行
9. R18重口排行慎重
使用时选择参数序号即可R18仅可私聊
p站排行榜 [参数] [数量](可选) [日期](可选)
示例
p站排行榜 无参数默认为日榜
p站排行榜 1
p站排行榜 1 5
p站排行榜 1 5 2018-4-25
注意空格在线搜索会较慢
---------------------------------
'P站搜图帮助
搜图 [关键词] [数量](可选) [页数](可选默认1) [r18](不屏蔽R-18可选)
示例
搜图 樱岛麻衣
搜图 樱岛麻衣 5
搜图 樱岛麻衣 5 r18
默认为 热度排序
注意空格在线搜索会较慢数量可能不符可能该页数量不够也可能被R-18屏蔽
"""
rank_dict = {
"1": "day",
@ -60,7 +77,11 @@ rank_dict = {
pixiv_rank = on_command(
"p站排行", aliases={"P站排行榜", "p站排行榜", "P站排行榜", "P站排行"}, priority=5, block=True, rule=to_me()
"p站排行",
aliases={"P站排行榜", "p站排行榜", "P站排行榜", "P站排行"},
priority=5,
block=True,
rule=to_me(),
)
pixiv_keyword = on_command("搜图", priority=5, block=True, rule=to_me())
@ -108,9 +129,9 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = get_message_text(event.json())
if isinstance(event, GroupMessageEvent):
if 'r18' in msg.lower():
if "r18" in msg.lower():
await pixiv_keyword.finish("(脸红#) 你不会害羞的 八嘎!", at_sender=True)
r18 = 0 if 'r18' in msg else 1
r18 = 0 if "r18" in msg else 1
msg = msg.replace("r18", "").strip().split()
msg = [m.strip() for m in msg if m]
keyword = None
@ -148,13 +169,18 @@ def check_date(date):
return False
async def send_image(info_list: list, matcher: Type[Matcher], bot: Bot, event: MessageEvent):
async def send_image(
info_list: list, matcher: Type[Matcher], bot: Bot, event: MessageEvent
):
if isinstance(event, GroupMessageEvent):
await pixiv_rank.send('开始下载整理数据...')
await pixiv_rank.send("开始下载整理数据...")
idx = 0
mes_list = []
for title, author, urls in info_list:
_message = f'title: {title}\nauthor: {author}\n' + await download_pixiv_imgs(urls, event.user_id, idx)
_message = (
f"title: {title}\nauthor: {author}\n"
+ await download_pixiv_imgs(urls, event.user_id, idx)
)
data = {
"type": "node",
"data": {
@ -169,7 +195,10 @@ async def send_image(info_list: list, matcher: Type[Matcher], bot: Bot, event: M
else:
for title, author, urls in info_list:
try:
await matcher.send(f'title: {title}\n'
f'author: {author}\n' + await download_pixiv_imgs(urls, event.user_id))
await matcher.send(
f"title: {title}\n"
f"author: {author}\n"
+ await download_pixiv_imgs(urls, event.user_id)
)
except (NetworkError, TimeoutError, ClientConnectorError):
await matcher.send("这张图网络直接炸掉了!", at_sender=True)

View File

@ -84,6 +84,7 @@ async def download_pixiv_imgs(
result = ""
index = 0
for url in urls:
url = url.replace('_webp', '')
async with aiohttp.ClientSession(headers=headers) as session:
for _ in range(3):
try:

View File

@ -9,9 +9,22 @@ import random
from utils.utils import CountLimiter
from models.ban_user import BanUser
__plugin_name__ = "戳一戳 [Hidden]"
__zx_plugin_name__ = "戳一戳"
__plugin_usage__ = "用法:无"
__plugin_usage__ = """
usage
戳一戳随机掉落语音或美图萝莉图
""".strip()
__plugin_des__ = "戳一戳发送语音美图萝莉图不美哉?"
__plugin_type__ = ("被动相关",)
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {
"level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ["戳一戳"],
}
poke__reply = [
"lsp你再戳",

View File

@ -6,8 +6,23 @@ import aiohttp
from utils.utils import get_local_proxy
__plugin_name__ = "语录"
__plugin_usage__ = "用法: 二次元语录给你力量"
__zx_plugin_name__ = "一言二次元语录"
__plugin_usage__ = """
usage
一言二次元语录
指令
语录/二次元
""".strip()
__plugin_des__ = "二次元语录给你力量"
__plugin_cmd__ = ["语录/二次元"]
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {
"level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ["语录", "二次元"],
}
quotations = on_command("语录", aliases={"二次元", "二次元语录"}, priority=5, block=True)

View File

@ -4,23 +4,35 @@ from .data_source import from_reimu_get_info
from services.log import logger
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 utils.utils import is_number, get_message_text, UserBlockLimiter, scheduler
from models.count_user import UserCount
from configs.config import COUNT_PER_DAY_REIMU, NICKNAME
__plugin_name__ = "上车"
__plugin_usage__ = r"""
* 请各位使用后不要转发 *
* 大部分解压密码是⑨ *
/ 每人每天仅提供 5 次上车机会只能私聊更多次数请向管理员申请用爱发电限制小色批乱搜 /
/ 并不推荐小色批使用此功能主要是不够色目的不够明确 /
上车 [目的地]
上车 5 [目的地] 该目的地第5页停车场
ps: 请尽量提供具体的目的地名称
__zx_plugin_name__ = "上车"
__plugin_usage__ = """
usage
* 请各位使用后不要转发 *
* 大部分解压密码是⑨ *
/ 并不推荐小色批使用此功能[主要是不够色目的不够明确] /
指令
上车 ?[page] [目的地]
示例上车 萝莉
示例上车 5 萝莉: 该目的地第5页停车场
ps: 请尽量提供具体的目的地名称
""".strip()
__plugin_des__ = "都坐稳了,老司机焊死了车门![仅限私聊]"
__plugin_cmd__ = ["上车 ?[page] [目的地]"]
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {
"level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ["上车"],
}
_ulmt = UserExistLimiter()
_ulmt = UserBlockLimiter()
reimu = on_command("上车", permission=PRIVATE, block=True, priority=1)
@ -63,7 +75,9 @@ 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(f"已经帮你关好车门了,请等待发车(不加{NICKNAME}好友的话是欣赏不到旅途的风景的)", 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)

Some files were not shown because too many files have changed in this diff Show More