Skip to content

Commit

Permalink
Merge pull request #47 from Ailitonia/dev
Browse files Browse the repository at this point in the history
Archived: Latest Stable Version for NoneBot 2.0.0a13.post1
  • Loading branch information
Ailitonia committed Aug 10, 2021
2 parents d0c04bf + 1896081 commit 9dc822e
Show file tree
Hide file tree
Showing 132 changed files with 10,247 additions and 3,154 deletions.
35 changes: 18 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,33 @@
## 功能 & 特点

- 基于异步 SQLAlchemy / MySQL 的数据存储
- 基于群组的通知权限、命令权限以及权限等级系统
- 基于插件节点的权限管理系统
- 权限控制及管理系统
- 针对不同群组可选启用通知权限、命令权限、权限等级控制
- 针对不同好友可选启用 Bot 功能
- 针对不同群组、好友独立配置插件权限节点
- 支持多协议端连接, 各协议端权限及订阅配置相互独立
- 命令冷却系统
- HTTP 代理功能
- 自动处理加好友和被邀请进群
- 插件帮助功能 (支持群聊 / 私聊)
- Bot对群组公告功能 (仅支持对群组)
- 定时消息功能 (仅支持对群组)
- 反闪照 (仅支持群聊)
- 反撤回 (仅支持群聊)
- B站动态订阅 (建议配置B站cookies) (支持群聊 / 私聊)
- B站直播间监控 (建议配置B站cookies) (支持群聊 / 私聊)
- 签到 (仅支持群聊)
- 求签 (仅支持群聊)
- 抽卡 (仅支持群聊)
- 能不能好好说话 (lab.magiconch.com API) (支持群聊 / 私聊)
- Pixiv助手 (需要 HTTP 代理, 除非部署在外网) (需要 go-cqhttp v0.9.40 及以上版本) (仅支持群聊)
- Pixiv订阅 (需要 HTTP 代理, 除非部署在外网) (仅支持群聊)
- Pixivision订阅 (需要 HTTP 代理, 除非部署在外网) (仅支持群聊)
- 复读姬 (仅支持群聊)
- roll点抽奖 (仅支持群聊)
- ShindanMaker占卜 (shindanmaker.com / 建议使用 HTTP 代理) (仅支持群聊)
- 搜番剧 (trace.moe API / 建议使用 HTTP 代理) (支持群聊 / 私聊)
- 搜二次元图 (Saucenao API 和 ascii2d / 建议使用 HTTP 代理) (支持群聊 / 私聊)
- 搜二次元图 (Saucenao API, iqbb 和 ascii2d / 建议使用 HTTP 代理) (支持群聊 / 私聊)
- 来点萌图 / 来点涩图 (需要 HTTP 代理, 除非部署在外网 / 图片数据库需要自己导入) (支持群聊 / 私聊)
- 表情包制作器 (支持群聊 / 私聊)
- 猫按钮 (测试) (仅支持群聊)
Expand All @@ -45,29 +54,21 @@

## 如何使用

0. 首先得有个MySQL数据库

1. 安装依赖: `pip install -r requirements.txt`

2. 配置.env中数据库相关配置(必需), 其他配置可选

3. 运行`python bot.py`

4. 在群组中使用 `/Omega` `/OmegaAuth` 等命令配置群组权限
请参考本仓库 [Wiki](https://github.com/Ailitonia/omega-miya/wiki)

## 关于图片数据

如果你不想自己收集图片数据, 可以将
[这组图片数据集](https://github.com/Ailitonia/omega-miya/raw/main/archive_data/db_pixiv.7z)
导入数据库
[这个图片数据库](https://github.com/Ailitonia/omega-miya/raw/main/archive_data/db_pixiv.7z)
导入, 基本都是按我自己口味收集的图片

这个图片集大概有5万条左右, 基本都是按我自己口味收集的图片
Update 2021.8.10: 最新发布图片数据库共 9w7 条图片数据 (包含已失效或画师已删除作品)

解压后直接把 `omega_pixiv_illusts.sql` 导入对应的 pixiv_illusts 表就好了

MD5: `8BF375B9687C397AE2040C8F9E28F68E`
MD5: `7AC9A77545E37F1B99F8D1948D0A9A78`

SHA1: `7CFF3593A85979B5D966773F3857577CFCC2FFBD`
SHA1: `1F129A18905D1590379AC761E2EAC69DAC2D42DA`

数据集来源是我的
[这个频道](https://t.me/amoeloli)
Expand Down
Binary file modified archive_data/db_pixiv.7z
Binary file not shown.
Binary file not shown.
6 changes: 5 additions & 1 deletion bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@
logger.add(log_info_path, rotation="00:00", diagnose=False, level="INFO", format=default_format, encoding='utf-8')
logger.add(log_error_path, rotation="00:00", diagnose=False, level="ERROR", format=default_format, encoding='utf-8')

# Add extra debug log file
# log_debug_name = f"{datetime.today().strftime('%Y%m%d-%H%M%S')}-DEBUG.log"
# log_debug_path = os.path.join(bot_log_path, log_debug_name)
# logger.add(log_debug_path, rotation="00:00", diagnose=False, level="DEBUG", format=default_format, encoding='utf-8')

# You can pass some keyword args config to init function
nonebot.init()

Expand All @@ -37,7 +42,6 @@
config.root_path_ = bot_root_path
config.tmp_path_ = bot_tmp_path


# 注册 cqhttp adapter
driver = nonebot.get_driver()
driver.register_adapter("cqhttp", CQHTTPBot)
Expand Down
133 changes: 133 additions & 0 deletions omega_miya/plugins/Omega_anti_flash/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
from nonebot import MatcherGroup, export, logger
from nonebot.permission import SUPERUSER
from nonebot.typing import T_State
from nonebot.adapters.cqhttp import Message
from nonebot.adapters.cqhttp.bot import Bot
from nonebot.adapters.cqhttp.event import MessageEvent, GroupMessageEvent, PrivateMessageEvent
from nonebot.adapters.cqhttp.permission import GROUP, GROUP_ADMIN, GROUP_OWNER
from omega_miya.utils.Omega_Base import DBBot, DBBotGroup, DBAuth, Result
from omega_miya.utils.Omega_plugin_utils import init_export, init_permission_state, OmegaRules


# Custom plugin usage text
__plugin_raw_name__ = __name__.split('.')[-1]
__plugin_name__ = 'AntiFlash'
__plugin_usage__ = r'''【AntiFlash 反闪照】
检测闪照并提取原图
**Permission**
Group only with
AuthNode
**AuthNode**
basic
**Usage**
**GroupAdmin and SuperUser Only**
/AntiFlash <ON|OFF>'''

# 声明本插件可配置的权限节点
__plugin_auth_node__ = [
'basic'
]

# Init plugin export
init_export(export(), __plugin_name__, __plugin_usage__, __plugin_auth_node__)


# 注册事件响应器
AntiFlash = MatcherGroup(type='message', permission=GROUP, priority=100, block=False)

anti_flash_admin = AntiFlash.on_command(
'AntiFlash',
aliases={'antiflash', '反闪照'},
# 使用run_preprocessor拦截权限管理, 在default_state初始化所需权限
state=init_permission_state(
name='anti_flash',
command=True,
level=10),
permission=GROUP_ADMIN | GROUP_OWNER | SUPERUSER,
priority=10,
block=True)


# 修改默认参数处理
@anti_flash_admin.args_parser
async def parse(bot: Bot, event: GroupMessageEvent, state: T_State):
args = str(event.get_plaintext()).strip().lower().split()
if not args:
await anti_flash_admin.reject('你似乎没有发送有效的参数呢QAQ, 请重新发送:')
state[state["_current_key"]] = args[0]
if state[state["_current_key"]] == '取消':
await anti_flash_admin.finish('操作已取消')


@anti_flash_admin.handle()
async def handle_first_receive(bot: Bot, event: GroupMessageEvent, state: T_State):
args = str(event.get_plaintext()).strip().lower().split()
if not args:
pass
elif args and len(args) == 1:
state['sub_command'] = args[0]
else:
await anti_flash_admin.finish('参数错误QAQ')


@anti_flash_admin.got('sub_command', prompt='执行操作?\n【ON/OFF】')
async def handle_sub_command_args(bot: Bot, event: GroupMessageEvent, state: T_State):
sub_command = state['sub_command']
if sub_command not in ['on', 'off']:
await anti_flash_admin.reject('没有这个选项哦, 请在【ON/OFF】中选择并重新发送, 取消命令请发送【取消】:')

if sub_command == 'on':
_res = await anti_flash_on(bot=bot, event=event, state=state)
elif sub_command == 'off':
_res = await anti_flash_off(bot=bot, event=event, state=state)
else:
_res = Result.IntResult(error=True, info='Unknown error, except sub_command', result=-1)

if _res.success():
logger.info(f"设置 AntiFlash 状态为 {sub_command} 成功, group_id: {event.group_id}, {_res.info}")
await anti_flash_admin.finish(f'已设置 AntiFlash 状态为 {sub_command}!')
else:
logger.error(f"设置 AntiFlash 状态为 {sub_command} 失败, group_id: {event.group_id}, {_res.info}")
await anti_flash_admin.finish(f'设置 AntiFlash 状态失败了QAQ, 请稍后再试~')


async def anti_flash_on(bot: Bot, event: GroupMessageEvent, state: T_State) -> Result.IntResult:
group_id = event.group_id
self_bot = DBBot(self_qq=int(bot.self_id))
group = DBBotGroup(group_id=group_id, self_bot=self_bot)
group_exist = await group.exist()
if not group_exist:
return Result.IntResult(error=False, info='Group not exist', result=-1)

auth_node = DBAuth(self_bot=self_bot, auth_id=group_id, auth_type='group', auth_node=f'{__plugin_raw_name__}.basic')
result = await auth_node.set(allow_tag=1, deny_tag=0, auth_info='启用反闪照')
return result


async def anti_flash_off(bot: Bot, event: GroupMessageEvent, state: T_State) -> Result.IntResult:
group_id = event.group_id
self_bot = DBBot(self_qq=int(bot.self_id))
group = DBBotGroup(group_id=group_id, self_bot=self_bot)
group_exist = await group.exist()
if not group_exist:
return Result.IntResult(error=False, info='Group not exist', result=-1)

auth_node = DBAuth(self_bot=self_bot, auth_id=group_id, auth_type='group', auth_node=f'{__plugin_raw_name__}.basic')
result = await auth_node.set(allow_tag=0, deny_tag=1, auth_info='禁用反闪照')
return result


anti_flash_handler = AntiFlash.on_message(rule=OmegaRules.has_auth_node(__plugin_raw_name__, 'basic'))


@anti_flash_handler.handle()
async def check_flash_img(bot: Bot, event: GroupMessageEvent, state: T_State):
for msg_seg in event.message:
if msg_seg.type == 'image':
if msg_seg.data.get('type') == 'flash':
msg = Message('AntiFlash 已检测到闪照:\n').append(str(msg_seg).replace(',type=flash', ''))
logger.info(f'AntiFlash 已处理闪照, message_id: {event.message_id}')
await anti_flash_handler.finish(msg)
143 changes: 143 additions & 0 deletions omega_miya/plugins/Omega_anti_recall/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
from nonebot import on_command, on_notice, export, logger
from nonebot.permission import SUPERUSER
from nonebot.typing import T_State
from nonebot.adapters.cqhttp import Message
from nonebot.adapters.cqhttp.bot import Bot
from nonebot.adapters.cqhttp.event import GroupMessageEvent, GroupRecallNoticeEvent
from nonebot.adapters.cqhttp.permission import GROUP_ADMIN, GROUP_OWNER
from omega_miya.utils.Omega_Base import DBBot, DBBotGroup, DBAuth, DBHistory, Result
from omega_miya.utils.Omega_plugin_utils import init_export, init_permission_state, OmegaRules


# Custom plugin usage text
__plugin_raw_name__ = __name__.split('.')[-1]
__plugin_name__ = 'AntiRecall'
__plugin_usage__ = r'''【AntiRecall 反撤回】
检测消息撤回并提取原消息
**Permission**
Group only with
AuthNode
**AuthNode**
basic
**Usage**
**GroupAdmin and SuperUser Only**
/AntiRecall <ON|OFF>'''

# 声明本插件可配置的权限节点
__plugin_auth_node__ = [
'basic'
]

# Init plugin export
init_export(export(), __plugin_name__, __plugin_usage__, __plugin_auth_node__)


# 注册事件响应器
anti_recall_admin = on_command(
'AntiRecall',
aliases={'antirecall', '反撤回'},
# 使用run_preprocessor拦截权限管理, 在default_state初始化所需权限
state=init_permission_state(
name='anti_recall',
command=True,
level=10),
permission=GROUP_ADMIN | GROUP_OWNER | SUPERUSER,
priority=10,
block=True)


# 修改默认参数处理
@anti_recall_admin.args_parser
async def parse(bot: Bot, event: GroupMessageEvent, state: T_State):
args = str(event.get_plaintext()).strip().lower().split()
if not args:
await anti_recall_admin.reject('你似乎没有发送有效的参数呢QAQ, 请重新发送:')
state[state["_current_key"]] = args[0]
if state[state["_current_key"]] == '取消':
await anti_recall_admin.finish('操作已取消')


@anti_recall_admin.handle()
async def handle_first_receive(bot: Bot, event: GroupMessageEvent, state: T_State):
args = str(event.get_plaintext()).strip().lower().split()
if not args:
pass
elif args and len(args) == 1:
state['sub_command'] = args[0]
else:
await anti_recall_admin.finish('参数错误QAQ')


@anti_recall_admin.got('sub_command', prompt='执行操作?\n【ON/OFF】')
async def handle_sub_command_args(bot: Bot, event: GroupMessageEvent, state: T_State):
sub_command = state['sub_command']
if sub_command not in ['on', 'off']:
await anti_recall_admin.reject('没有这个选项哦, 请在【ON/OFF】中选择并重新发送, 取消命令请发送【取消】:')

if sub_command == 'on':
_res = await anti_recall_on(bot=bot, event=event, state=state)
elif sub_command == 'off':
_res = await anti_recall_off(bot=bot, event=event, state=state)
else:
_res = Result.IntResult(error=True, info='Unknown error, except sub_command', result=-1)

if _res.success():
logger.info(f"设置 AntiRecall 状态为 {sub_command} 成功, group_id: {event.group_id}, {_res.info}")
await anti_recall_admin.finish(f'已设置 AntiRecall 状态为 {sub_command}!')
else:
logger.error(f"设置 AntiRecall 状态为 {sub_command} 失败, group_id: {event.group_id}, {_res.info}")
await anti_recall_admin.finish(f'设置 AntiRecall 状态失败了QAQ, 请稍后再试~')


async def anti_recall_on(bot: Bot, event: GroupMessageEvent, state: T_State) -> Result.IntResult:
group_id = event.group_id
self_bot = DBBot(self_qq=int(bot.self_id))
group = DBBotGroup(group_id=group_id, self_bot=self_bot)
group_exist = await group.exist()
if not group_exist:
return Result.IntResult(error=False, info='Group not exist', result=-1)

auth_node = DBAuth(self_bot=self_bot, auth_id=group_id, auth_type='group', auth_node=f'{__plugin_raw_name__}.basic')
result = await auth_node.set(allow_tag=1, deny_tag=0, auth_info='启用反撤回')
return result


async def anti_recall_off(bot: Bot, event: GroupMessageEvent, state: T_State) -> Result.IntResult:
group_id = event.group_id
self_bot = DBBot(self_qq=int(bot.self_id))
group = DBBotGroup(group_id=group_id, self_bot=self_bot)
group_exist = await group.exist()
if not group_exist:
return Result.IntResult(error=False, info='Group not exist', result=-1)

auth_node = DBAuth(self_bot=self_bot, auth_id=group_id, auth_type='group', auth_node=f'{__plugin_raw_name__}.basic')
result = await auth_node.set(allow_tag=0, deny_tag=1, auth_info='禁用反撤回')
return result


anti_recall_handler = on_notice(rule=OmegaRules.has_auth_node(__plugin_raw_name__, 'basic'), priority=100, block=False)


@anti_recall_handler.handle()
async def check_recall_notice(bot: Bot, event: GroupRecallNoticeEvent, state: T_State):
self_id = event.self_id
group_id = event.group_id
user_id = event.user_id
message_id = event.message_id
history_result = await DBHistory.search_unique_msg(
self_id=self_id, post_type='message', detail_type='group', sub_type='normal',
event_id=message_id, group_id=group_id, user_id=user_id)
if history_result.error:
logger.error(f'AntiRecall 查询历史消息失败, message_id: {message_id}, error: {history_result.info}')
return
else:
history = history_result.result
user_name = history.user_name
time = history.created_at
msg = history.msg_data
send_msg = Message(f"AntiRecall 已检测到撤回消息:\n{time}@{user_name}:\n").append(msg)
logger.info(f'AntiRecall 已处理撤回消息, message_id: {message_id}')
await anti_recall_handler.finish(send_msg)
Loading

0 comments on commit 9dc822e

Please sign in to comment.