@@ -2,4 +2,4 @@ from .command_manager import matcher
|
|||||||
from .config_loader import global_config
|
from .config_loader import global_config
|
||||||
from .WS import WS
|
from .WS import WS
|
||||||
|
|
||||||
__all__ = ["WS", "matcher", "global_config"]
|
__all__ = ["WS", "matcher", "global_config", "PluginDataManager"]
|
||||||
|
|||||||
@@ -3,7 +3,9 @@
|
|||||||
|
|
||||||
负责扫描、加载和管理 `base_plugins` 目录下的所有插件。
|
负责扫描、加载和管理 `base_plugins` 目录下的所有插件。
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import importlib
|
import importlib
|
||||||
|
import json
|
||||||
import os
|
import os
|
||||||
import pkgutil
|
import pkgutil
|
||||||
import sys
|
import sys
|
||||||
@@ -19,10 +21,12 @@ def load_all_plugins():
|
|||||||
该函数会遍历 `plugins` 目录下的所有模块:
|
该函数会遍历 `plugins` 目录下的所有模块:
|
||||||
1. 如果模块已加载,则执行 reload 操作(用于热重载)。
|
1. 如果模块已加载,则执行 reload 操作(用于热重载)。
|
||||||
2. 如果模块未加载,则执行 import 操作。
|
2. 如果模块未加载,则执行 import 操作。
|
||||||
|
|
||||||
加载过程中会提取插件元数据 `__plugin_meta__` 并注册到 CommandManager。
|
加载过程中会提取插件元数据 `__plugin_meta__` 并注册到 CommandManager。
|
||||||
"""
|
"""
|
||||||
plugin_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "plugins")
|
plugin_dir = os.path.join(
|
||||||
|
os.path.dirname(os.path.abspath(__file__)), "..", "plugins"
|
||||||
|
)
|
||||||
package_name = "plugins"
|
package_name = "plugins"
|
||||||
|
|
||||||
logger.info(f"正在从 {package_name} 加载插件...")
|
logger.info(f"正在从 {package_name} 加载插件...")
|
||||||
@@ -37,13 +41,84 @@ def load_all_plugins():
|
|||||||
else:
|
else:
|
||||||
module = importlib.import_module(full_module_name)
|
module = importlib.import_module(full_module_name)
|
||||||
action = "加载"
|
action = "加载"
|
||||||
|
|
||||||
# 提取插件元数据
|
# 提取插件元数据
|
||||||
if hasattr(module, "__plugin_meta__"):
|
if hasattr(module, "__plugin_meta__"):
|
||||||
meta = getattr(module, "__plugin_meta__")
|
meta = getattr(module, "__plugin_meta__")
|
||||||
matcher.plugins[full_module_name] = meta
|
matcher.plugins[full_module_name] = meta
|
||||||
|
|
||||||
type_str = "包" if is_pkg else "文件"
|
type_str = "包" if is_pkg else "文件"
|
||||||
logger.success(f" [{type_str}] 成功{action}: {module_name}")
|
logger.success(f" [{type_str}] 成功{action}: {module_name}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f" {action if 'action' in locals() else '加载'}插件 {module_name} 失败: {e}")
|
print(
|
||||||
|
f" {action if 'action' in locals() else '加载'}插件 {module_name} 失败: {e}"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class PluginDataManager:
|
||||||
|
"""
|
||||||
|
用于管理插件产生的数据文件的类
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, plugin_name: str):
|
||||||
|
"""
|
||||||
|
初始化插件数据管理器
|
||||||
|
|
||||||
|
:param plugin_name: 插件名称
|
||||||
|
"""
|
||||||
|
self.plugin_name = plugin_name
|
||||||
|
self.data_file = os.path.join(
|
||||||
|
os.path.dirname(os.path.abspath(__file__)),
|
||||||
|
"..",
|
||||||
|
"plugins",
|
||||||
|
"data",
|
||||||
|
self.plugin_name + ".json",
|
||||||
|
)
|
||||||
|
self.data = {}
|
||||||
|
self.load()
|
||||||
|
|
||||||
|
def load(self):
|
||||||
|
"""读取配置文件"""
|
||||||
|
if not os.path.exists(self.data_file):
|
||||||
|
with open(self.data_file, "w", encoding="utf-8") as f:
|
||||||
|
self.set(self.plugin_name, [])
|
||||||
|
try:
|
||||||
|
with open(self.data_file, "r", encoding="utf-8") as f:
|
||||||
|
self.data = json.load(f)
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
self.data = {}
|
||||||
|
|
||||||
|
def save(self):
|
||||||
|
"""保存配置到文件"""
|
||||||
|
with open(self.data_file, "w", encoding="utf-8") as f:
|
||||||
|
json.dump(self.data, f, indent=2, ensure_ascii=False)
|
||||||
|
|
||||||
|
def get(self, key, default=None):
|
||||||
|
"""获取配置项"""
|
||||||
|
return self.data.get(key, default)
|
||||||
|
|
||||||
|
def set(self, key, value):
|
||||||
|
"""设置配置项"""
|
||||||
|
self.data[key] = value
|
||||||
|
self.save()
|
||||||
|
|
||||||
|
def add(self, key, value):
|
||||||
|
"""添加配置项"""
|
||||||
|
if key not in self.data:
|
||||||
|
self.data[key] = []
|
||||||
|
self.data[key].append(value)
|
||||||
|
self.save()
|
||||||
|
|
||||||
|
def remove(self, key):
|
||||||
|
"""删除配置项"""
|
||||||
|
if key in self.data:
|
||||||
|
del self.data[key]
|
||||||
|
self.save()
|
||||||
|
|
||||||
|
def clear(self):
|
||||||
|
"""清空所有配置"""
|
||||||
|
self.data.clear()
|
||||||
|
self.save()
|
||||||
|
|
||||||
|
def get_all(self):
|
||||||
|
return self.data.copy()
|
||||||
|
|||||||
@@ -1,20 +1,47 @@
|
|||||||
from .events.base import OneBotEvent
|
from .events.base import OneBotEvent
|
||||||
from .events.message import MessageEvent, PrivateMessageEvent, GroupMessageEvent, MessageSegment
|
|
||||||
from .events.notice import (
|
|
||||||
NoticeEvent, FriendAddNoticeEvent, FriendRecallNoticeEvent,
|
|
||||||
GroupRecallNoticeEvent, GroupIncreaseNoticeEvent,
|
|
||||||
GroupDecreaseNoticeEvent, GroupAdminNoticeEvent, GroupBanNoticeEvent,
|
|
||||||
GroupUploadNoticeEvent, GroupUploadFile,
|
|
||||||
NotifyNoticeEvent, PokeNotifyEvent, LuckyKingNotifyEvent, HonorNotifyEvent,
|
|
||||||
GroupCardNoticeEvent, OfflineFileNoticeEvent, OfflineFile,
|
|
||||||
ClientStatusNoticeEvent, ClientStatus, EssenceNoticeEvent
|
|
||||||
)
|
|
||||||
from .events.request import RequestEvent, FriendRequestEvent, GroupRequestEvent
|
|
||||||
from .events.meta import MetaEvent, HeartbeatEvent, LifeCycleEvent, HeartbeatStatus
|
|
||||||
from .events.factory import EventFactory
|
from .events.factory import EventFactory
|
||||||
|
from .events.message import (
|
||||||
|
GroupMessageEvent,
|
||||||
|
MessageEvent,
|
||||||
|
MessageSegment,
|
||||||
|
PrivateMessageEvent,
|
||||||
|
)
|
||||||
|
from .events.meta import HeartbeatEvent, HeartbeatStatus, LifeCycleEvent, MetaEvent
|
||||||
|
from .events.notice import (
|
||||||
|
ClientStatus,
|
||||||
|
ClientStatusNoticeEvent,
|
||||||
|
EssenceNoticeEvent,
|
||||||
|
FriendAddNoticeEvent,
|
||||||
|
FriendRecallNoticeEvent,
|
||||||
|
GroupAdminNoticeEvent,
|
||||||
|
GroupBanNoticeEvent,
|
||||||
|
GroupCardNoticeEvent,
|
||||||
|
GroupDecreaseNoticeEvent,
|
||||||
|
GroupIncreaseNoticeEvent,
|
||||||
|
GroupRecallNoticeEvent,
|
||||||
|
GroupUploadFile,
|
||||||
|
GroupUploadNoticeEvent,
|
||||||
|
HonorNotifyEvent,
|
||||||
|
LuckyKingNotifyEvent,
|
||||||
|
NoticeEvent,
|
||||||
|
NotifyNoticeEvent,
|
||||||
|
OfflineFile,
|
||||||
|
OfflineFileNoticeEvent,
|
||||||
|
PokeNotifyEvent,
|
||||||
|
)
|
||||||
|
from .events.request import FriendRequestEvent, GroupRequestEvent, RequestEvent
|
||||||
from .objects import (
|
from .objects import (
|
||||||
GroupInfo, GroupMemberInfo, FriendInfo, StrangerInfo, LoginInfo,
|
CurrentTalkative,
|
||||||
VersionInfo, Status, EssenceMessage, GroupHonorInfo, CurrentTalkative, HonorInfo
|
EssenceMessage,
|
||||||
|
FriendInfo,
|
||||||
|
GroupHonorInfo,
|
||||||
|
GroupInfo,
|
||||||
|
GroupMemberInfo,
|
||||||
|
HonorInfo,
|
||||||
|
LoginInfo,
|
||||||
|
Status,
|
||||||
|
StrangerInfo,
|
||||||
|
VersionInfo,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Alias for backward compatibility
|
# Alias for backward compatibility
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
该模块定义了 `MessageSegment` 类,用于构建和表示 OneBot v11 协议中的消息段。
|
该模块定义了 `MessageSegment` 类,用于构建和表示 OneBot v11 协议中的消息段。
|
||||||
通过此类,可以方便地创建文本、图片、At 等不同类型的消息内容,并支持链式操作。
|
通过此类,可以方便地创建文本、图片、At 等不同类型的消息内容,并支持链式操作。
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from typing import Any, Dict
|
from typing import Any, Dict
|
||||||
|
|
||||||
@@ -67,7 +68,7 @@ class MessageSegment:
|
|||||||
# --- 快捷构造方法 ---
|
# --- 快捷构造方法 ---
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def text(text: str) -> "MessageSegment":
|
def text(text: str) -> "MessageSegment": # noqa: F811
|
||||||
"""
|
"""
|
||||||
创建一个文本消息段。
|
创建一个文本消息段。
|
||||||
|
|
||||||
|
|||||||
115
plugins/admin.py
Normal file
115
plugins/admin.py
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
from core import PluginDataManager
|
||||||
|
from core.bot import Bot
|
||||||
|
from core.command_manager import matcher
|
||||||
|
from models import GroupMessageEvent
|
||||||
|
|
||||||
|
__plugin_meta__ = {
|
||||||
|
"name": "admin",
|
||||||
|
"description": "机器人权限管理插件",
|
||||||
|
"usage": "/admin",
|
||||||
|
}
|
||||||
|
|
||||||
|
data = PluginDataManager("admin")
|
||||||
|
|
||||||
|
|
||||||
|
@matcher.command("admin")
|
||||||
|
async def handle_permission(bot: Bot, event: GroupMessageEvent, args: list[str]):
|
||||||
|
if not args:
|
||||||
|
await event.reply(
|
||||||
|
"机器人权限管理插件指令:\n/admin list 列出所有权限\n/admin add member <QQ号> 添加群成员权限\n/admin remove member <QQ号> 删除群成员权限\n/admin add group <群号> 添加群权限\n/admin remove group <群号> 删除群权限\n/admin clear member 清空群成员权限\n/admin clear group 清空群权限\n/admin clear all 清空所有权限"
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
if str(event.user_id) not in data.get("members", []):
|
||||||
|
await event.reply("你没有权限使用此命令。")
|
||||||
|
return
|
||||||
|
if str(event.group_id) not in data.get("groups", []):
|
||||||
|
await event.reply("群聊不在权限中")
|
||||||
|
return
|
||||||
|
|
||||||
|
action = args[0].lower()
|
||||||
|
|
||||||
|
# ensure storage keys exist
|
||||||
|
members = data.get("members", []) or []
|
||||||
|
groups = data.get("groups", []) or []
|
||||||
|
|
||||||
|
if action == "list":
|
||||||
|
msg_lines = ["当前权限列表:"]
|
||||||
|
msg_lines.append(
|
||||||
|
f"群成员权限 ({len(members)}): {', '.join(members) if members else '无'}"
|
||||||
|
)
|
||||||
|
msg_lines.append(
|
||||||
|
f"群权限 ({len(groups)}): {', '.join(groups) if groups else '无'}"
|
||||||
|
)
|
||||||
|
await event.reply("\n".join(msg_lines))
|
||||||
|
return
|
||||||
|
|
||||||
|
if action in ("add", "remove"):
|
||||||
|
if len(args) < 3:
|
||||||
|
await event.reply("参数错误,示例:/admin add member 123456")
|
||||||
|
return
|
||||||
|
|
||||||
|
target = args[1].lower()
|
||||||
|
value = args[2]
|
||||||
|
|
||||||
|
if target == "member":
|
||||||
|
# operate on members list
|
||||||
|
if action == "add":
|
||||||
|
if str(value) in members:
|
||||||
|
await event.reply(f"成员 {value} 已存在,无需重复添加。")
|
||||||
|
return
|
||||||
|
members.append(str(value))
|
||||||
|
data.set("members", members)
|
||||||
|
await event.reply(f"已添加群成员权限:{value}")
|
||||||
|
return
|
||||||
|
else: # remove
|
||||||
|
if str(value) not in members:
|
||||||
|
await event.reply(f"成员 {value} 不在权限列表中。")
|
||||||
|
return
|
||||||
|
members = [m for m in members if m != str(value)]
|
||||||
|
data.set("members", members)
|
||||||
|
await event.reply(f"已移除群成员权限:{value}")
|
||||||
|
return
|
||||||
|
|
||||||
|
if target == "group":
|
||||||
|
if action == "add":
|
||||||
|
if str(value) in groups:
|
||||||
|
await event.reply(f"群 {value} 已存在,无需重复添加。")
|
||||||
|
return
|
||||||
|
groups.append(str(value))
|
||||||
|
data.set("groups", groups)
|
||||||
|
await event.reply(f"已添加群权限:{value}")
|
||||||
|
return
|
||||||
|
else: # remove
|
||||||
|
if str(value) not in groups:
|
||||||
|
await event.reply(f"群 {value} 不在权限列表中。")
|
||||||
|
return
|
||||||
|
groups = [g for g in groups if g != str(value)]
|
||||||
|
data.set("groups", groups)
|
||||||
|
await event.reply(f"已移除群权限:{value}")
|
||||||
|
return
|
||||||
|
|
||||||
|
await event.reply("未知目标类型,请使用 member 或 group")
|
||||||
|
return
|
||||||
|
|
||||||
|
if action == "clear":
|
||||||
|
if len(args) < 2:
|
||||||
|
await event.reply("参数错误,示例:/admin clear member")
|
||||||
|
return
|
||||||
|
target = args[1].lower()
|
||||||
|
if target == "member":
|
||||||
|
data.set("members", [])
|
||||||
|
await event.reply("已清空群成员权限。")
|
||||||
|
return
|
||||||
|
if target == "group":
|
||||||
|
data.set("groups", [])
|
||||||
|
await event.reply("已清空群权限。")
|
||||||
|
return
|
||||||
|
if target == "all":
|
||||||
|
data.clear()
|
||||||
|
await event.reply("已清空所有权限。")
|
||||||
|
return
|
||||||
|
await event.reply("未知清空目标,请使用 member/group/all")
|
||||||
|
return
|
||||||
|
|
||||||
|
await event.reply("未知指令,使用 /admin 查看帮助")
|
||||||
1
plugins/data/admin.json
Normal file
1
plugins/data/admin.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{}
|
||||||
@@ -10,6 +10,12 @@ from core.bot import Bot
|
|||||||
from core.command_manager import matcher
|
from core.command_manager import matcher
|
||||||
from models import MessageEvent, MessageSegment
|
from models import MessageEvent, MessageSegment
|
||||||
|
|
||||||
|
__plugin_meta__ = {
|
||||||
|
"name": "jrcd",
|
||||||
|
"description": "来看看你的长度吧!",
|
||||||
|
"usage": "/jrcd\n/bbcd [@某人]",
|
||||||
|
}
|
||||||
|
|
||||||
# jrcd
|
# jrcd
|
||||||
JRCDMSG_1 = [
|
JRCDMSG_1 = [
|
||||||
"今天的长度是%scm,可以让我一口吃掉吗罒ω罒",
|
"今天的长度是%scm,可以让我一口吃掉吗罒ω罒",
|
||||||
@@ -28,15 +34,15 @@ JRCDMSG_3 = [
|
|||||||
"今天的长度是%scm,单是看到哥哥的长度就....(〃w〃)",
|
"今天的长度是%scm,单是看到哥哥的长度就....(〃w〃)",
|
||||||
]
|
]
|
||||||
|
|
||||||
# bbcd short
|
|
||||||
BBCDMSG1 = ["还行,可以尝试一下(๑‾ ꇴ ‾๑)"]
|
|
||||||
BBCDMSG2 = ["差的不多,富贵险中求一下(*°ー°)v?"]
|
|
||||||
BBCDMSG3 = ["快逃!!!!!!!!(o(*°▽°*)o)"]
|
|
||||||
|
|
||||||
# bbcd long
|
# bbcd long
|
||||||
BBCDMSG4 = ["差的不多,富贵险中求一下(*°ー°)v?", "还行,可以尝试一下(๑‾ ꇴ ‾๑)"]
|
BBCDMSG1 = ["还行,可以尝试一下(๑‾ ꇴ ‾๑)"]
|
||||||
BBCDMSG5 = ["不错的成绩,努力一下或许可以让他受孕哦..(〃w〃)"]
|
BBCDMSG2 = ["不错的成绩,努力一下或许可以让他受孕哦..(〃w〃)"]
|
||||||
BBCDMSG6 = ["好猛,试试强制让他受孕吧!!!(((o(*°▽°*)o)))"]
|
BBCDMSG3 = ["好猛,试试强制让他受孕吧!!!(((o(*°▽°*)o)))"]
|
||||||
|
|
||||||
|
# bbcd short
|
||||||
|
BBCDMSG4 = ["差的不多,富贵险中求一下(*°ー°)v?"]
|
||||||
|
BBCDMSG5 = ["还行,可以尝试一下(๑‾ ꇴ ‾๑)"]
|
||||||
|
BBCDMSG6 = ["快逃!!!!!!!!(o(*°▽°*)o)"]
|
||||||
|
|
||||||
# bbcd equal
|
# bbcd equal
|
||||||
BBCDMSG7 = ["试试刺刀看看谁能赢吧!"]
|
BBCDMSG7 = ["试试刺刀看看谁能赢吧!"]
|
||||||
|
|||||||
@@ -9,6 +9,12 @@ from core.bot import Bot
|
|||||||
from core.command_manager import matcher
|
from core.command_manager import matcher
|
||||||
from models import MessageEvent, MessageSegment
|
from models import MessageEvent, MessageSegment
|
||||||
|
|
||||||
|
__plugin_meta__ = {
|
||||||
|
"name": "thpic",
|
||||||
|
"description": "来看看东方Project的图片吧!",
|
||||||
|
"usage": "/thpic",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@matcher.command("thpic")
|
@matcher.command("thpic")
|
||||||
async def handle_echo(bot: Bot, event: MessageEvent, args: list[str]):
|
async def handle_echo(bot: Bot, event: MessageEvent, args: list[str]):
|
||||||
|
|||||||
Reference in New Issue
Block a user