mirror of
https://github.com/zhenxun-org/zhenxun_bot.git
synced 2026-10-10 22:30:02 +08:00
✨ 部分功能适配QQ BOT (#1701)
This commit is contained in:
@@ -9,6 +9,13 @@ from nonebot.adapters import Bot
|
||||
from nonebot.drivers import Driver
|
||||
from tortoise.exceptions import OperationalError
|
||||
|
||||
require("nonebot_plugin_apscheduler")
|
||||
require("nonebot_plugin_alconna")
|
||||
require("nonebot_plugin_session")
|
||||
require("nonebot_plugin_userinfo")
|
||||
require("nonebot_plugin_htmlrender")
|
||||
# require("nonebot_plugin_uninfo")
|
||||
|
||||
from zhenxun.services.log import logger
|
||||
from zhenxun.models.sign_user import SignUser
|
||||
from zhenxun.models.goods_info import GoodsInfo
|
||||
@@ -17,14 +24,6 @@ from zhenxun.utils.decorator.shop import shop_register
|
||||
from zhenxun.models.bot_connect_log import BotConnectLog
|
||||
from zhenxun.models.group_member_info import GroupInfoUser
|
||||
|
||||
require("nonebot_plugin_apscheduler")
|
||||
require("nonebot_plugin_alconna")
|
||||
require("nonebot_plugin_session")
|
||||
require("nonebot_plugin_userinfo")
|
||||
require("nonebot_plugin_htmlrender")
|
||||
require("nonebot_plugin_uninfo")
|
||||
|
||||
|
||||
driver: Driver = nonebot.get_driver()
|
||||
|
||||
|
||||
|
||||
@@ -2,12 +2,14 @@ from pathlib import Path
|
||||
|
||||
import aiofiles
|
||||
from nonebot.rule import to_me
|
||||
from nonebot_plugin_uninfo import Uninfo
|
||||
from nonebot.plugin import PluginMetadata
|
||||
from nonebot_plugin_session import EventSession
|
||||
from nonebot_plugin_alconna import Alconna, Arparma, on_alconna
|
||||
|
||||
from zhenxun.services.log import logger
|
||||
from zhenxun.utils.message import MessageUtils
|
||||
from zhenxun.utils.platform import PlatformUtils
|
||||
from zhenxun.configs.path_config import DATA_PATH
|
||||
from zhenxun.configs.utils import PluginExtraData
|
||||
|
||||
__plugin_meta__ = PluginMetadata(
|
||||
@@ -25,19 +27,33 @@ _matcher = on_alconna(Alconna("关于"), priority=5, block=True, rule=to_me())
|
||||
|
||||
|
||||
@_matcher.handle()
|
||||
async def _(session: EventSession, arparma: Arparma):
|
||||
async def _(session: Uninfo, arparma: Arparma):
|
||||
ver_file = Path() / "__version__"
|
||||
version = None
|
||||
if ver_file.exists():
|
||||
async with aiofiles.open(ver_file, encoding="utf8") as f:
|
||||
if text := await f.read():
|
||||
version = text.split(":")[-1].strip()
|
||||
info = f"""
|
||||
if PlatformUtils.is_qbot(session):
|
||||
info: list[str | Path] = [
|
||||
f"""
|
||||
『绪山真寻Bot』
|
||||
版本:{version}
|
||||
简介:基于Nonebot2开发,支持多平台,是一个非常可爱的Bot呀,希望与大家要好好相处
|
||||
""".strip()
|
||||
]
|
||||
path = DATA_PATH / "about.png"
|
||||
if path.exists():
|
||||
info.append(path)
|
||||
else:
|
||||
info = [
|
||||
f"""
|
||||
『绪山真寻Bot』
|
||||
版本:{version}
|
||||
简介:基于Nonebot2开发,支持多平台,是一个非常可爱的Bot呀,希望与大家要好好相处
|
||||
项目地址:https://github.com/HibiKier/zhenxun_bot
|
||||
文档地址:https://hibikier.github.io/zhenxun_bot/
|
||||
""".strip()
|
||||
await MessageUtils.build_message(info).send()
|
||||
""".strip()
|
||||
]
|
||||
await MessageUtils.build_message(info).send() # type: ignore
|
||||
logger.info("查看关于", arparma.header_result, session=session)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from nonebot.rule import to_me
|
||||
from nonebot.adapters import Bot
|
||||
from nonebot_plugin_uninfo import Uninfo
|
||||
from nonebot.plugin import PluginMetadata
|
||||
from nonebot_plugin_session import EventSession
|
||||
from nonebot_plugin_alconna import (
|
||||
Args,
|
||||
Match,
|
||||
@@ -58,28 +58,26 @@ _matcher = on_alconna(
|
||||
async def _(
|
||||
bot: Bot,
|
||||
name: Match[str],
|
||||
session: EventSession,
|
||||
session: Uninfo,
|
||||
is_superuser: Query[bool] = AlconnaQuery("superuser.value", False),
|
||||
):
|
||||
if not session.id1:
|
||||
await MessageUtils.build_message("用户id为空...").finish()
|
||||
_is_superuser = is_superuser.result if is_superuser.available else False
|
||||
if name.available:
|
||||
if _is_superuser and session.id1 not in bot.config.superusers:
|
||||
if _is_superuser and session.user.id not in bot.config.superusers:
|
||||
_is_superuser = False
|
||||
if result := await get_plugin_help(session.id1, name.result, _is_superuser):
|
||||
if result := await get_plugin_help(session.user.id, name.result, _is_superuser):
|
||||
await MessageUtils.build_message(result).send(reply_to=True)
|
||||
else:
|
||||
await MessageUtils.build_message("没有此功能的帮助信息...").send(
|
||||
reply_to=True
|
||||
)
|
||||
logger.info(f"查看帮助详情: {name.result}", "帮助", session=session)
|
||||
elif gid := session.id3 or session.id2:
|
||||
elif session.group and (gid := session.group.id):
|
||||
_image_path = GROUP_HELP_PATH / f"{gid}.png"
|
||||
if not _image_path.exists():
|
||||
await create_help_img(bot.self_id, gid, session.platform)
|
||||
await create_help_img(session, gid)
|
||||
await MessageUtils.build_message(_image_path).finish()
|
||||
else:
|
||||
if not SIMPLE_HELP_IMAGE.exists():
|
||||
await create_help_img(bot.self_id, None, session.platform)
|
||||
await create_help_img(session, None)
|
||||
await MessageUtils.build_message(SIMPLE_HELP_IMAGE).finish()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import nonebot
|
||||
from nonebot_plugin_uninfo import Uninfo
|
||||
|
||||
from zhenxun.utils.enum import PluginType
|
||||
from zhenxun.models.level_user import LevelUser
|
||||
@@ -19,19 +20,18 @@ background = IMAGE_PATH / "background" / "0.png"
|
||||
driver = nonebot.get_driver()
|
||||
|
||||
|
||||
async def create_help_img(bot_id: str, group_id: str | None, platform: str):
|
||||
async def create_help_img(session: Uninfo, group_id: str | None):
|
||||
"""生成帮助图片
|
||||
|
||||
参数:
|
||||
bot_id: bot id
|
||||
session: Uninfo
|
||||
group_id: 群号
|
||||
platform: 平台
|
||||
"""
|
||||
help_type: str = base_config.get("type")
|
||||
if help_type.lower() == "html":
|
||||
result = BuildImage.open(await build_html_image(group_id))
|
||||
elif help_type.lower() == "zhenxun":
|
||||
result = BuildImage.open(await build_zhenxun_image(bot_id, group_id, platform))
|
||||
result = BuildImage.open(await build_zhenxun_image(session, group_id))
|
||||
else:
|
||||
result = await build_normal_image(group_id)
|
||||
if group_id:
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
from pydantic import BaseModel
|
||||
from nonebot_plugin_uninfo import Uninfo
|
||||
from nonebot_plugin_htmlrender import template_to_pic
|
||||
|
||||
from zhenxun.utils.enum import BlockType
|
||||
from zhenxun.configs.config import BotConfig
|
||||
from zhenxun.utils.platform import PlatformUtils
|
||||
from zhenxun.models.plugin_info import PluginInfo
|
||||
from zhenxun.configs.path_config import TEMPLATE_PATH
|
||||
@@ -60,7 +62,15 @@ def build_plugin_data(classify: dict[str, list[Item]]) -> list[dict[str, str]]:
|
||||
for menu, value in classify.items()
|
||||
]
|
||||
plugin_list = build_line_data(plugin_list)
|
||||
plugin_list.insert(0, build_plugin_line(menu_key, max_data, 30, 100))
|
||||
plugin_list.insert(
|
||||
0,
|
||||
build_plugin_line(
|
||||
menu_key if menu_key not in ["normal", "功能"] else "主要功能",
|
||||
max_data,
|
||||
30,
|
||||
100,
|
||||
),
|
||||
)
|
||||
return plugin_list
|
||||
|
||||
|
||||
@@ -113,25 +123,25 @@ def build_line_data(plugin_list: list[dict]) -> list[dict]:
|
||||
return data
|
||||
|
||||
|
||||
async def build_zhenxun_image(
|
||||
bot_id: str, group_id: str | None, platform: str
|
||||
) -> bytes:
|
||||
async def build_zhenxun_image(session: Uninfo, group_id: str | None) -> bytes:
|
||||
"""构造真寻帮助图片
|
||||
|
||||
参数:
|
||||
bot_id: bot_id
|
||||
group_id: 群号
|
||||
platform: 平台
|
||||
"""
|
||||
classify = await classify_plugin(group_id, __handle_item)
|
||||
plugin_list = build_plugin_data(classify)
|
||||
platform = PlatformUtils.get_platform(session)
|
||||
bot_id = BotConfig.get_qbot_uid(session.self_id) or session.self_id
|
||||
bot_ava = PlatformUtils.get_user_avatar_url(bot_id, platform)
|
||||
return await template_to_pic(
|
||||
template_path=str((TEMPLATE_PATH / "ss_menu").absolute()),
|
||||
template_name="main.html",
|
||||
templates={
|
||||
"data": {
|
||||
"plugin_list": plugin_list,
|
||||
"ava": PlatformUtils.get_user_avatar_url(bot_id, platform),
|
||||
"ava": bot_ava,
|
||||
}
|
||||
},
|
||||
pages={
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
from nonebot.adapters import Bot
|
||||
from nonebot_plugin_uninfo import Uninfo
|
||||
from nonebot.plugin import PluginMetadata
|
||||
from nonebot_plugin_session import EventSession
|
||||
from playwright.async_api import TimeoutError
|
||||
from nonebot_plugin_alconna import At, Args, Match, Alconna, Arparma, on_alconna
|
||||
|
||||
from zhenxun.services.log import logger
|
||||
from zhenxun.utils.enum import PluginType
|
||||
from zhenxun.utils.depends import UserName
|
||||
from zhenxun.utils.message import MessageUtils
|
||||
from zhenxun.utils.platform import PlatformUtils
|
||||
from zhenxun.configs.utils import PluginExtraData
|
||||
from zhenxun.models.group_member_info import GroupInfoUser
|
||||
|
||||
@@ -31,26 +30,29 @@ _matcher = on_alconna(Alconna("我的信息", Args["at_user?", At]), priority=5,
|
||||
@_matcher.handle()
|
||||
async def _(
|
||||
bot: Bot,
|
||||
session: EventSession,
|
||||
session: Uninfo,
|
||||
arparma: Arparma,
|
||||
at_user: Match[At],
|
||||
nickname: str = UserName(),
|
||||
):
|
||||
user_id = session.id1
|
||||
if at_user.available:
|
||||
user_id = session.user.id
|
||||
if at_user.available and session.group:
|
||||
user_id = at_user.result.target
|
||||
if user := await GroupInfoUser.get_or_none(
|
||||
user_id=user_id, group_id=session.id2
|
||||
user_id=user_id, group_id=session.group.id
|
||||
):
|
||||
nickname = user.user_name
|
||||
else:
|
||||
nickname = user_id
|
||||
if not user_id:
|
||||
await MessageUtils.build_message("用户id为空...").finish(reply_to=True)
|
||||
try:
|
||||
result = await get_user_info(bot, user_id, session.id2, nickname)
|
||||
result = await get_user_info(
|
||||
session, bot, user_id, session.group.id if session.group else None, nickname
|
||||
)
|
||||
await MessageUtils.build_message(result).send(at_sender=True)
|
||||
logger.info("获取用户信息", arparma.header_result, session=session)
|
||||
except TimeoutError as e:
|
||||
logger.error("获取用户信息超时", arparma.header_result, session=session, e=e)
|
||||
await MessageUtils.build_message("获取用户信息超时...").finish(reply_to=True)
|
||||
except Exception as e:
|
||||
logger.error("获取用户信息失败", arparma.header_result, session=session, e=e)
|
||||
await MessageUtils.build_message("获取用户信息失败...").finish(reply_to=True)
|
||||
|
||||
@@ -4,6 +4,7 @@ from datetime import datetime, timedelta
|
||||
from nonebot.adapters import Bot
|
||||
from tortoise.functions import Count
|
||||
from tortoise.expressions import RawSQL
|
||||
from nonebot_plugin_uninfo import Uninfo
|
||||
from nonebot_plugin_htmlrender import template_to_pic
|
||||
|
||||
from zhenxun.models.sign_user import SignUser
|
||||
@@ -130,11 +131,12 @@ async def get_chat_history(
|
||||
|
||||
|
||||
async def get_user_info(
|
||||
bot: Bot, user_id: str, group_id: str | None, nickname: str
|
||||
session: Uninfo, bot: Bot, user_id: str, group_id: str | None, nickname: str
|
||||
) -> bytes:
|
||||
"""获取用户个人信息
|
||||
|
||||
参数:
|
||||
session: Uninfo
|
||||
bot: Bot
|
||||
user_id: 用户id
|
||||
group_id: 群id
|
||||
@@ -162,7 +164,7 @@ async def get_user_info(
|
||||
data = {
|
||||
"date": now.date(),
|
||||
"weather": weather,
|
||||
"ava_url": ava_url,
|
||||
"ava_url": session.user.avatar,
|
||||
"nickname": nickname,
|
||||
"title": "勇 者",
|
||||
"race": random.choice(RACE),
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
import nonebot
|
||||
|
||||
from zhenxun.services.log import logger
|
||||
|
||||
path = Path(__file__).parent
|
||||
|
||||
for f in os.listdir(path):
|
||||
_p = path / f
|
||||
if _p.is_dir():
|
||||
nonebot.load_plugins(str(_p.resolve()))
|
||||
|
||||
try:
|
||||
from nonebot.adapters.onebot.v11 import Bot
|
||||
|
||||
nonebot.load_plugins(str((path / "qq").resolve()))
|
||||
except ImportError:
|
||||
logger.warning("未安装 onebot-adapter,无法加载QQ平台专用插件...")
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from nonebot.adapters import Bot
|
||||
from nonebot_plugin_uninfo import Uninfo
|
||||
from nonebot import on_notice, on_request
|
||||
from nonebot.plugin import PluginMetadata
|
||||
from nonebot.adapters.onebot.v11 import (
|
||||
@@ -100,7 +101,11 @@ add_group = on_request(priority=1, block=False)
|
||||
|
||||
|
||||
@group_increase_handle.handle()
|
||||
async def _(bot: Bot, event: GroupIncreaseNoticeEvent | GroupMemberIncreaseEvent):
|
||||
async def _(
|
||||
bot: Bot,
|
||||
session: Uninfo,
|
||||
event: GroupIncreaseNoticeEvent | GroupMemberIncreaseEvent,
|
||||
):
|
||||
user_id = str(event.user_id)
|
||||
group_id = str(event.group_id)
|
||||
if user_id == bot.self_id:
|
||||
@@ -113,11 +118,15 @@ async def _(bot: Bot, event: GroupIncreaseNoticeEvent | GroupMemberIncreaseEvent
|
||||
except ForceAddGroupError as e:
|
||||
await PlatformUtils.send_superuser(bot, e.get_info())
|
||||
else:
|
||||
await GroupManager.add_user(bot, user_id, group_id)
|
||||
await GroupManager.add_user(session, bot, user_id, group_id)
|
||||
|
||||
|
||||
@group_decrease_handle.handle()
|
||||
async def _(bot: Bot, event: GroupDecreaseNoticeEvent | GroupMemberDecreaseEvent):
|
||||
async def _(
|
||||
bot: Bot,
|
||||
session: Uninfo,
|
||||
event: GroupDecreaseNoticeEvent | GroupMemberDecreaseEvent,
|
||||
):
|
||||
user_id = str(event.user_id)
|
||||
group_id = str(event.group_id)
|
||||
if event.sub_type == "kick_me":
|
||||
@@ -128,6 +137,6 @@ async def _(bot: Bot, event: GroupDecreaseNoticeEvent | GroupMemberDecreaseEvent
|
||||
bot, user_id, group_id, str(event.operator_id), event.sub_type
|
||||
)
|
||||
if result and not await CommonUtils.task_is_block(
|
||||
"refund_group_remind", group_id
|
||||
session, "refund_group_remind"
|
||||
):
|
||||
await group_decrease_handle.send(result)
|
||||
|
||||
@@ -7,6 +7,7 @@ from datetime import datetime
|
||||
import ujson as json
|
||||
from nonebot.adapters import Bot
|
||||
from nonebot_plugin_alconna import At
|
||||
from nonebot_plugin_uninfo import Uninfo
|
||||
|
||||
from zhenxun.services.log import logger
|
||||
from zhenxun.configs.config import Config
|
||||
@@ -202,7 +203,7 @@ class GroupManager:
|
||||
).send()
|
||||
|
||||
@classmethod
|
||||
async def add_user(cls, bot: Bot, user_id: str, group_id: str):
|
||||
async def add_user(cls, session: Uninfo, bot: Bot, user_id: str, group_id: str):
|
||||
"""拉入用户
|
||||
|
||||
参数:
|
||||
@@ -219,7 +220,7 @@ class GroupManager:
|
||||
)
|
||||
logger.info(f"用户{user_info['user_id']} 所属{user_info['group_id']} 更新成功")
|
||||
if not await CommonUtils.task_is_block(
|
||||
"group_welcome", group_id
|
||||
session, "group_welcome"
|
||||
) and cls._flmt.check(group_id):
|
||||
await cls.__send_welcome_message(user_id, group_id)
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import nonebot
|
||||
from nonebot.adapters import Bot
|
||||
from nonebot.plugin import PluginMetadata
|
||||
from nonebot_plugin_apscheduler import scheduler
|
||||
|
||||
@@ -26,15 +27,15 @@ __plugin_meta__ = PluginMetadata(
|
||||
driver = nonebot.get_driver()
|
||||
|
||||
|
||||
async def check(group_id: str) -> bool:
|
||||
return not await CommonUtils.task_is_block("morning_goodnight", group_id)
|
||||
async def check(bot: Bot, group_id: str) -> bool:
|
||||
return not await CommonUtils.task_is_block(bot, "morning_goodnight", group_id)
|
||||
|
||||
|
||||
# 早上好
|
||||
@scheduler.scheduled_job(
|
||||
"cron",
|
||||
hour=6,
|
||||
minute=1,
|
||||
hour=14,
|
||||
minute=52,
|
||||
)
|
||||
async def _():
|
||||
message = MessageUtils.build_message(["早上好", IMAGE_PATH / "zhenxun" / "zao.jpg"])
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
from nonebot.adapters import Bot, Event
|
||||
from nonebot_plugin_uninfo import Uninfo
|
||||
from nonebot.plugin import PluginMetadata
|
||||
from nonebot_plugin_session import EventSession
|
||||
from nonebot_plugin_userinfo import UserInfo, EventUserInfo
|
||||
from nonebot_plugin_alconna import (
|
||||
Args,
|
||||
Match,
|
||||
Query,
|
||||
Option,
|
||||
UniMsg,
|
||||
@@ -17,6 +18,7 @@ from nonebot_plugin_alconna import (
|
||||
)
|
||||
|
||||
from zhenxun.services.log import logger
|
||||
from zhenxun.utils.depends import UserName
|
||||
from zhenxun.utils.message import MessageUtils
|
||||
from zhenxun.utils.exception import GoodsNotFound
|
||||
from zhenxun.utils.enum import BlockType, PluginType
|
||||
@@ -53,8 +55,8 @@ _matcher = on_alconna(
|
||||
Option("--all", action=store_true),
|
||||
Subcommand("my-cost", help_text="我的金币"),
|
||||
Subcommand("my-props", help_text="我的道具"),
|
||||
Subcommand("buy", Args["name", str]["num", int, 1], help_text="购买道具"),
|
||||
Subcommand("use", Args["name", str]["num?", int, 1], help_text="使用道具"),
|
||||
Subcommand("buy", Args["name?", str]["num?", int], help_text="购买道具"),
|
||||
Subcommand("use", Args["name?", str]["num?", int], help_text="使用道具"),
|
||||
Subcommand("gold-list", Args["num?", int], help_text="金币排行"),
|
||||
),
|
||||
priority=5,
|
||||
@@ -76,16 +78,16 @@ _matcher.shortcut(
|
||||
)
|
||||
|
||||
_matcher.shortcut(
|
||||
"购买道具",
|
||||
"购买道具(?P<name>.*?)",
|
||||
command="商店",
|
||||
arguments=["buy", "{%0}"],
|
||||
arguments=["buy", "{name}"],
|
||||
prefix=True,
|
||||
)
|
||||
|
||||
_matcher.shortcut(
|
||||
"使用道具",
|
||||
"使用道具(?P<name>.*?)",
|
||||
command="商店",
|
||||
arguments=["use", "{%0}"],
|
||||
arguments=["use", "{name}"],
|
||||
prefix=True,
|
||||
)
|
||||
|
||||
@@ -122,14 +124,12 @@ async def _(session: EventSession, arparma: Arparma):
|
||||
|
||||
|
||||
@_matcher.assign("my-props")
|
||||
async def _(
|
||||
session: EventSession, arparma: Arparma, user_info: UserInfo = EventUserInfo()
|
||||
):
|
||||
async def _(session: EventSession, arparma: Arparma, nickname: str = UserName()):
|
||||
if session.id1:
|
||||
logger.info("查看道具", arparma.header_result, session=session)
|
||||
if image := await ShopManage.my_props(
|
||||
session.id1,
|
||||
user_info.user_displayname or user_info.user_name,
|
||||
nickname,
|
||||
session.platform,
|
||||
):
|
||||
await MessageUtils.build_message(image.pic2bytes()).finish(reply_to=True)
|
||||
@@ -139,17 +139,23 @@ async def _(
|
||||
|
||||
|
||||
@_matcher.assign("buy")
|
||||
async def _(session: EventSession, arparma: Arparma, name: str, num: int):
|
||||
if session.id1:
|
||||
logger.info(
|
||||
f"购买道具 {name}, 数量: {num}",
|
||||
arparma.header_result,
|
||||
session=session,
|
||||
)
|
||||
result = await ShopManage.buy_prop(session.id1, name, num, session.platform)
|
||||
await MessageUtils.build_message(result).send(reply_to=True)
|
||||
else:
|
||||
await MessageUtils.build_message("用户id为空...").send(reply_to=True)
|
||||
async def _(
|
||||
session: Uninfo,
|
||||
arparma: Arparma,
|
||||
name: Match[str],
|
||||
num: Query[int] = AlconnaQuery("num", 1),
|
||||
):
|
||||
if not name.available:
|
||||
await MessageUtils.build_message(
|
||||
"请在指令后跟需要购买的道具名称或id..."
|
||||
).finish(reply_to=True)
|
||||
logger.info(
|
||||
f"购买道具 {name}, 数量: {num}",
|
||||
arparma.header_result,
|
||||
session=session,
|
||||
)
|
||||
result = await ShopManage.buy_prop(session.user.id, name.result, num.result)
|
||||
await MessageUtils.build_message(result).send(reply_to=True)
|
||||
|
||||
|
||||
@_matcher.assign("use")
|
||||
@@ -159,11 +165,17 @@ async def _(
|
||||
message: UniMsg,
|
||||
session: EventSession,
|
||||
arparma: Arparma,
|
||||
name: str,
|
||||
num: int,
|
||||
name: Match[str],
|
||||
num: Query[int] = AlconnaQuery("num", 1),
|
||||
):
|
||||
if not name.available:
|
||||
await MessageUtils.build_message(
|
||||
"请在指令后跟需要使用的道具名称或id..."
|
||||
).finish(reply_to=True)
|
||||
try:
|
||||
result = await ShopManage.use(bot, event, session, message, name, num, "")
|
||||
result = await ShopManage.use(
|
||||
bot, event, session, message, name.result, num.result, ""
|
||||
)
|
||||
logger.info(
|
||||
f"使用道具 {name}, 数量: {num}", arparma.header_result, session=session
|
||||
)
|
||||
@@ -179,24 +191,21 @@ async def _(
|
||||
|
||||
@_matcher.assign("gold-list")
|
||||
async def _(
|
||||
session: EventSession, arparma: Arparma, num: Query[int] = AlconnaQuery("num", 10)
|
||||
session: Uninfo, arparma: Arparma, num: Query[int] = AlconnaQuery("num", 10)
|
||||
):
|
||||
if num.result > 50:
|
||||
await MessageUtils.build_message("排行榜人数不能超过50哦...").finish()
|
||||
if session.id1:
|
||||
gid = session.id3 or session.id2
|
||||
if not arparma.find("all") and not gid:
|
||||
await MessageUtils.build_message(
|
||||
"私聊中无法查看 '金币排行',请发送 '金币总排行'"
|
||||
).finish()
|
||||
if arparma.find("all"):
|
||||
gid = None
|
||||
result = await gold_rank(session.id1, gid, num.result, session.platform)
|
||||
logger.info(
|
||||
"查看金币排行",
|
||||
arparma.header_result,
|
||||
session=session,
|
||||
)
|
||||
await MessageUtils.build_message(result).send(reply_to=True)
|
||||
else:
|
||||
await MessageUtils.build_message("用户id为空...").send(reply_to=True)
|
||||
gid = session.group.id if session.group else None
|
||||
if not arparma.find("all") and not gid:
|
||||
await MessageUtils.build_message(
|
||||
"私聊中无法查看 '金币排行',请发送 '金币总排行'"
|
||||
).finish()
|
||||
if arparma.find("all"):
|
||||
gid = None
|
||||
result = await gold_rank(session, gid, num.result)
|
||||
logger.info(
|
||||
"查看金币排行",
|
||||
arparma.header_result,
|
||||
session=session,
|
||||
)
|
||||
await MessageUtils.build_message(result).send(reply_to=True)
|
||||
|
||||
@@ -6,6 +6,7 @@ from types import MappingProxyType
|
||||
from collections.abc import Callable
|
||||
|
||||
from nonebot.adapters import Bot, Event
|
||||
from nonebot_plugin_uninfo import Uninfo
|
||||
from pydantic import BaseModel, create_model
|
||||
from nonebot_plugin_session import EventSession
|
||||
from nonebot_plugin_alconna import UniMsg, UniMessage
|
||||
@@ -58,9 +59,9 @@ class Goods(BaseModel):
|
||||
class ShopParam(BaseModel):
|
||||
goods_name: str
|
||||
"""商品名称"""
|
||||
user_id: int
|
||||
user_id: str
|
||||
"""用户id"""
|
||||
group_id: int
|
||||
group_id: str | None
|
||||
"""群聊id"""
|
||||
bot: Any
|
||||
"""bot"""
|
||||
@@ -80,16 +81,17 @@ class ShopParam(BaseModel):
|
||||
"""UniMessage"""
|
||||
|
||||
|
||||
async def gold_rank(user_id: str, group_id: str | None, num: int, platform: str):
|
||||
async def gold_rank(session: Uninfo, group_id: str | None, num: int):
|
||||
query = UserConsole
|
||||
if group_id:
|
||||
uid_list = await GroupInfoUser.filter(group_id=group_id).values_list(
|
||||
"user_id", flat=True
|
||||
)
|
||||
query = query.filter(user_id__in=uid_list)
|
||||
if uid_list:
|
||||
query = query.filter(user_id__in=uid_list)
|
||||
user_list = await query.annotate().order_by("-gold").values_list("user_id", "gold")
|
||||
user_id_list = [user[0] for user in user_list]
|
||||
index = user_id_list.index(user_id) + 1
|
||||
index = user_id_list.index(session.user.id) + 1
|
||||
user_list = user_list[:num] if num < len(user_list) else user_list
|
||||
friend_user = await FriendUser.filter(user_id__in=user_id_list).values_list(
|
||||
"user_id", "user_name"
|
||||
@@ -103,8 +105,11 @@ async def gold_rank(user_id: str, group_id: str | None, num: int, platform: str)
|
||||
uid2name[g[0]] = g[1]
|
||||
column_name = ["排名", "-", "名称", "金币", "平台"]
|
||||
data_list = []
|
||||
platform = PlatformUtils.get_platform(session)
|
||||
for i, user in enumerate(user_list):
|
||||
ava_bytes = await PlatformUtils.get_user_avatar(user[0], platform)
|
||||
ava_bytes = await PlatformUtils.get_user_avatar(
|
||||
user[0], platform, session.self_id
|
||||
)
|
||||
data_list.append(
|
||||
[
|
||||
f"{i+1}",
|
||||
@@ -294,9 +299,12 @@ class ShopManage:
|
||||
str | MessageFactory | None: 使用完成后返回信息
|
||||
"""
|
||||
if goods_name.isdigit():
|
||||
user = await UserConsole.get_user(user_id=session.id1) # type: ignore
|
||||
uuid = list(user.props.keys())[int(goods_name)]
|
||||
goods_info = await GoodsInfo.get_or_none(uuid=uuid)
|
||||
try:
|
||||
user = await UserConsole.get_user(user_id=session.id1) # type: ignore
|
||||
uuid = list(user.props.keys())[int(goods_name)]
|
||||
goods_info = await GoodsInfo.get_or_none(uuid=uuid)
|
||||
except IndexError:
|
||||
return "仓库中道具不存在..."
|
||||
else:
|
||||
goods_info = await GoodsInfo.get_or_none(goods_name=goods_name)
|
||||
if not goods_info:
|
||||
@@ -647,9 +655,10 @@ class ShopManage:
|
||||
shop = BuildImage(w, h, font_size=20, color="#f9f6f2")
|
||||
await shop.paste(A, (20, 230))
|
||||
await shop.paste(shop_logo, (450, 30))
|
||||
tip = "注【通过 购买道具 序号 或者 商品名称 购买】"
|
||||
await shop.text(
|
||||
(
|
||||
int((1000 - shop.getsize("注【通过 序号 或者 商品名称 购买】")[0]) / 2),
|
||||
int((1000 - shop.getsize(tip)[0]) / 2),
|
||||
170,
|
||||
),
|
||||
"注【通过 序号 或者 商品名称 购买】",
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
from nonebot_plugin_uninfo import Uninfo
|
||||
from nonebot.plugin import PluginMetadata
|
||||
from nonebot_plugin_session import EventSession
|
||||
from nonebot_plugin_apscheduler import scheduler
|
||||
@@ -115,6 +116,13 @@ _sign_matcher.shortcut(
|
||||
prefix=True,
|
||||
)
|
||||
|
||||
_sign_matcher.shortcut(
|
||||
"签到排行",
|
||||
command="签到",
|
||||
arguments=["--list"],
|
||||
prefix=True,
|
||||
)
|
||||
|
||||
_sign_matcher.shortcut(
|
||||
"好感度总排行",
|
||||
command="签到",
|
||||
@@ -122,43 +130,44 @@ _sign_matcher.shortcut(
|
||||
prefix=True,
|
||||
)
|
||||
|
||||
_sign_matcher.shortcut(
|
||||
"签到总排行",
|
||||
command="签到",
|
||||
arguments=["--global", "--list"],
|
||||
prefix=True,
|
||||
)
|
||||
|
||||
|
||||
@_sign_matcher.assign("$main")
|
||||
async def _(session: EventSession, arparma: Arparma, nickname: str = UserName()):
|
||||
if session.id1:
|
||||
if path := await SignManage.sign(session, nickname):
|
||||
logger.info("签到成功", arparma.header_result, session=session)
|
||||
await MessageUtils.build_message(path).finish()
|
||||
return MessageUtils.build_message("用户id为空...").send()
|
||||
async def _(session: Uninfo, arparma: Arparma, nickname: str = UserName()):
|
||||
path = await SignManage.sign(session, nickname)
|
||||
logger.info("签到成功", arparma.header_result, session=session)
|
||||
await MessageUtils.build_message(path).finish()
|
||||
|
||||
|
||||
@_sign_matcher.assign("my")
|
||||
async def _(session: EventSession, arparma: Arparma, nickname: str = UserName()):
|
||||
if session.id1:
|
||||
if image := await SignManage.sign(session, nickname, True):
|
||||
logger.info("查看我的签到", arparma.header_result, session=session)
|
||||
await MessageUtils.build_message(image).finish()
|
||||
return MessageUtils.build_message("用户id为空...").send()
|
||||
async def _(session: Uninfo, arparma: Arparma, nickname: str = UserName()):
|
||||
path = await SignManage.sign(session, nickname, True)
|
||||
logger.info("查看我的签到", arparma.header_result, session=session)
|
||||
await MessageUtils.build_message(path).finish()
|
||||
|
||||
|
||||
@_sign_matcher.assign("list")
|
||||
async def _(
|
||||
session: EventSession, arparma: Arparma, num: Query[int] = AlconnaQuery("num", 10)
|
||||
session: Uninfo, arparma: Arparma, num: Query[int] = AlconnaQuery("num", 10)
|
||||
):
|
||||
if num.result > 50:
|
||||
await MessageUtils.build_message("排行榜人数不能超过50哦...").finish()
|
||||
gid = session.id3 or session.id2
|
||||
gid = session.group.id if session.group else None
|
||||
if not arparma.find("global") and not gid:
|
||||
await MessageUtils.build_message(
|
||||
"私聊中无法查看 '好感度排行',请发送 '好感度总排行'"
|
||||
).finish()
|
||||
if session.id1:
|
||||
if arparma.find("global"):
|
||||
gid = None
|
||||
if image := await SignManage.rank(session.id1, num.result, gid):
|
||||
logger.info("查看签到排行", arparma.header_result, session=session)
|
||||
await MessageUtils.build_message(image).finish()
|
||||
return MessageUtils.build_message("用户id为空...").send()
|
||||
if arparma.find("global"):
|
||||
gid = None
|
||||
image = await SignManage.rank(session, num.result, gid)
|
||||
logger.info("查看签到排行", arparma.header_result, session=session)
|
||||
await MessageUtils.build_message(image).send()
|
||||
|
||||
|
||||
@scheduler.scheduled_job(
|
||||
|
||||
@@ -4,12 +4,12 @@ from pathlib import Path
|
||||
from datetime import datetime
|
||||
|
||||
import pytz
|
||||
from nonebot_plugin_session import EventSession
|
||||
from nonebot_plugin_uninfo import Uninfo
|
||||
|
||||
from zhenxun.services.log import logger
|
||||
from zhenxun.models.sign_log import SignLog
|
||||
from zhenxun.models.sign_user import SignUser
|
||||
from zhenxun.utils.utils import get_user_avatar
|
||||
from zhenxun.utils.platform import PlatformUtils
|
||||
from zhenxun.models.friend_user import FriendUser
|
||||
from zhenxun.configs.path_config import IMAGE_PATH
|
||||
from zhenxun.models.user_console import UserConsole
|
||||
@@ -32,12 +32,12 @@ PLATFORM_PATH = {
|
||||
class SignManage:
|
||||
@classmethod
|
||||
async def rank(
|
||||
cls, user_id: str, num: int, group_id: str | None = None
|
||||
cls, session: Uninfo, num: int, group_id: str | None = None
|
||||
) -> BuildImage: # sourcery skip: avoid-builtin-shadow
|
||||
"""好感度排行
|
||||
|
||||
参数:
|
||||
user_id: 用户id
|
||||
session: Uninfo
|
||||
num: 排行榜数量
|
||||
group_id: 群组id
|
||||
|
||||
@@ -49,14 +49,15 @@ class SignManage:
|
||||
user_list = await GroupInfoUser.filter(group_id=group_id).values_list(
|
||||
"user_id", flat=True
|
||||
)
|
||||
query = query.filter(user_id__in=user_list)
|
||||
if user_list:
|
||||
query = query.filter(user_id__in=user_list)
|
||||
user_list = (
|
||||
await query.annotate()
|
||||
.order_by("-impression")
|
||||
.values_list("user_id", "impression", "sign_count", "platform")
|
||||
)
|
||||
user_id_list = [user[0] for user in user_list]
|
||||
index = user_id_list.index(user_id) + 1
|
||||
index = user_id_list.index(session.user.id) + 1
|
||||
user_list = user_list[:num] if num < len(user_list) else user_list
|
||||
column_name = ["排名", "-", "名称", "好感度", "签到次数", "平台"]
|
||||
friend_list = await FriendUser.filter(user_id__in=user_id_list).values_list(
|
||||
@@ -70,8 +71,11 @@ class SignManage:
|
||||
for g in group_user:
|
||||
uid2name[g[0]] = g[1]
|
||||
data_list = []
|
||||
platform = PlatformUtils.get_platform(session)
|
||||
for i, user in enumerate(user_list):
|
||||
bytes = await get_user_avatar(user[0])
|
||||
bytes = await PlatformUtils.get_user_avatar(
|
||||
user[0], platform, session.self_id
|
||||
)
|
||||
data_list.append(
|
||||
[
|
||||
f"{i+1}",
|
||||
@@ -92,28 +96,29 @@ class SignManage:
|
||||
|
||||
@classmethod
|
||||
async def sign(
|
||||
cls, session: EventSession, nickname: str, is_card_view: bool = False
|
||||
) -> Path | None:
|
||||
cls, session: Uninfo, nickname: str, is_card_view: bool = False
|
||||
) -> Path:
|
||||
"""签到
|
||||
|
||||
参数:
|
||||
session: Session
|
||||
session: Uninfo
|
||||
nickname: 用户昵称
|
||||
is_card_view: 是否展示卡片
|
||||
|
||||
返回:
|
||||
Path: 卡片路径
|
||||
"""
|
||||
if not session.id1:
|
||||
return None
|
||||
platform = PlatformUtils.get_platform(session)
|
||||
now = datetime.now(pytz.timezone("Asia/Shanghai"))
|
||||
user_console = await UserConsole.get_user(session.id1, session.platform)
|
||||
user_console = await UserConsole.get_user(session.user.id, platform)
|
||||
user, _ = await SignUser.get_or_create(
|
||||
user_id=session.id1,
|
||||
defaults={"user_console": user_console, "platform": session.platform},
|
||||
user_id=session.user.id,
|
||||
defaults={"user_console": user_console, "platform": platform},
|
||||
)
|
||||
new_log = (
|
||||
await SignLog.filter(user_id=session.id1).order_by("-create_time").first()
|
||||
await SignLog.filter(user_id=session.user.id)
|
||||
.order_by("-create_time")
|
||||
.first()
|
||||
)
|
||||
log_time = None
|
||||
if new_log:
|
||||
@@ -123,7 +128,13 @@ class SignManage:
|
||||
if not is_card_view and (not new_log or (log_time and log_time != now.date())):
|
||||
return await cls._handle_sign_in(user, nickname, session)
|
||||
return await get_card(
|
||||
user, nickname, -1, user_console.gold, "", is_card_view=is_card_view
|
||||
user,
|
||||
session,
|
||||
nickname,
|
||||
-1,
|
||||
user_console.gold,
|
||||
"",
|
||||
is_card_view=is_card_view,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@@ -131,36 +142,35 @@ class SignManage:
|
||||
cls,
|
||||
user: SignUser,
|
||||
nickname: str,
|
||||
session: EventSession,
|
||||
session: Uninfo,
|
||||
) -> Path:
|
||||
"""签到处理
|
||||
|
||||
参数:
|
||||
user: SignUser
|
||||
nickname: 用户昵称
|
||||
session: Session
|
||||
session: Uninfo
|
||||
|
||||
返回:
|
||||
Path: 卡片路径
|
||||
"""
|
||||
platform = PlatformUtils.get_platform(session)
|
||||
impression_added = (secrets.randbelow(99) + 1) / 100
|
||||
rand = random.random()
|
||||
add_probability = float(user.add_probability)
|
||||
specify_probability = user.specify_probability
|
||||
if rand + add_probability > 0.97 or rand < specify_probability:
|
||||
impression_added *= 2
|
||||
await SignUser.sign(user, impression_added, session.bot_id, session.platform)
|
||||
await SignUser.sign(user, impression_added, session.self_id, platform)
|
||||
gold = random.randint(1, 100)
|
||||
gift = random_event(float(user.impression))
|
||||
if isinstance(gift, int):
|
||||
gold += gift
|
||||
await UserConsole.add_gold(
|
||||
user.user_id, gold + gift, "sign_in", session.platform
|
||||
)
|
||||
await UserConsole.add_gold(user.user_id, gold + gift, "sign_in", platform)
|
||||
gift = f"额外金币 +{gift}"
|
||||
else:
|
||||
await UserConsole.add_gold(user.user_id, gold, "sign_in", session.platform)
|
||||
await UserConsole.add_props_by_name(user.user_id, gift, 1, session.platform)
|
||||
await UserConsole.add_gold(user.user_id, gold, "sign_in", platform)
|
||||
await UserConsole.add_props_by_name(user.user_id, gift, 1, platform)
|
||||
gift += " + 1"
|
||||
logger.info(
|
||||
f"签到成功. score: {user.impression:.2f} "
|
||||
@@ -170,6 +180,7 @@ class SignManage:
|
||||
)
|
||||
return await get_card(
|
||||
user,
|
||||
session,
|
||||
nickname,
|
||||
impression_added,
|
||||
gold,
|
||||
|
||||
@@ -7,13 +7,13 @@ from datetime import datetime
|
||||
import pytz
|
||||
import nonebot
|
||||
from nonebot.drivers import Driver
|
||||
from nonebot_plugin_uninfo import Uninfo
|
||||
from nonebot_plugin_htmlrender import template_to_pic
|
||||
|
||||
from zhenxun.models.sign_log import SignLog
|
||||
from zhenxun.models.sign_user import SignUser
|
||||
from zhenxun.utils.utils import get_user_avatar
|
||||
from zhenxun.utils.http_utils import AsyncHttpx
|
||||
from zhenxun.utils.image_utils import BuildImage
|
||||
from zhenxun.utils.platform import PlatformUtils
|
||||
from zhenxun.configs.config import Config, BotConfig
|
||||
from zhenxun.configs.path_config import IMAGE_PATH, TEMPLATE_PATH
|
||||
|
||||
@@ -63,6 +63,7 @@ async def init_image():
|
||||
|
||||
async def get_card(
|
||||
user: SignUser,
|
||||
session: Uninfo,
|
||||
nickname: str,
|
||||
add_impression: float,
|
||||
gold: int | None,
|
||||
@@ -74,6 +75,7 @@ async def get_card(
|
||||
|
||||
参数:
|
||||
user: SignUser
|
||||
session: Uninfo
|
||||
nickname: 用户昵称
|
||||
impression: 新增的好感度
|
||||
gold: 金币
|
||||
@@ -99,17 +101,18 @@ async def get_card(
|
||||
is_card_view = True
|
||||
return (
|
||||
await _generate_html_card(
|
||||
user, nickname, add_impression, gold, gift, is_double, is_card_view
|
||||
user, session, nickname, add_impression, gold, gift, is_double, is_card_view
|
||||
)
|
||||
if base_config.get("IMAGE_STYLE") == "zhenxun"
|
||||
else await _generate_card(
|
||||
user, nickname, add_impression, gold, gift, is_double, is_card_view
|
||||
user, session, nickname, add_impression, gold, gift, is_double, is_card_view
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
async def _generate_card(
|
||||
user: SignUser,
|
||||
session: Uninfo,
|
||||
nickname: str,
|
||||
add_impression: float,
|
||||
gold: int | None,
|
||||
@@ -121,6 +124,7 @@ async def _generate_card(
|
||||
|
||||
参数:
|
||||
user: SignUser
|
||||
session: Uninfo
|
||||
nickname: 用户昵称
|
||||
add_impression: 新增的好感度
|
||||
gold: 金币
|
||||
@@ -137,7 +141,9 @@ async def _generate_card(
|
||||
140,
|
||||
background=SIGN_BORDER_PATH / "ava_border_01.png",
|
||||
)
|
||||
if user.platform == "qq" and (byt := await get_user_avatar(user.user_id)):
|
||||
if session.user.avatar and (
|
||||
byt := await AsyncHttpx.get_content(session.user.avatar)
|
||||
):
|
||||
ava = BuildImage(107, 107, background=BytesIO(byt))
|
||||
else:
|
||||
ava = BuildImage(107, 107, (0, 0, 0))
|
||||
@@ -273,10 +279,6 @@ async def _generate_card(
|
||||
await bk.paste(nickname_img, (30, 15))
|
||||
await bk.paste(uid_img, (30, 85))
|
||||
await bk.paste(A, (0, 150))
|
||||
# await bk.text((30, 167), "Accumulative check-in for")
|
||||
# _x = bk.getsize("Accumulative check-in for")[0] + sign_day_img.width + 45
|
||||
# await bk.paste(sign_day_img, (398, 158))
|
||||
# await bk.text((_x, 167), "days")
|
||||
await bk.paste(tip_image, (10, 167))
|
||||
await bk.paste(date_img, (220, 370))
|
||||
await bk.paste(lik_text1_img, (220, 240))
|
||||
@@ -377,6 +379,7 @@ def clear_sign_data_pic():
|
||||
|
||||
async def _generate_html_card(
|
||||
user: SignUser,
|
||||
session: Uninfo,
|
||||
nickname: str,
|
||||
add_impression: float,
|
||||
gold: int | None,
|
||||
@@ -388,6 +391,7 @@ async def _generate_html_card(
|
||||
|
||||
参数:
|
||||
user: SignUser
|
||||
session: Uninfo
|
||||
nickname: 用户昵称
|
||||
add_impression: 新增的好感度
|
||||
gold: 金币
|
||||
@@ -420,9 +424,8 @@ async def _generate_html_card(
|
||||
next_impression - previous_impression
|
||||
)
|
||||
now = datetime.now()
|
||||
ava_url = PlatformUtils.get_user_avatar_url(user.user_id, "qq")
|
||||
data = {
|
||||
"ava_url": ava_url,
|
||||
"ava_url": session.user.avatar,
|
||||
"name": nickname,
|
||||
"uid": uid,
|
||||
"sign_count": f"{user.sign_count}",
|
||||
|
||||
@@ -16,7 +16,6 @@ from zhenxun.utils.common_utils import CommonUtils
|
||||
|
||||
|
||||
class BroadcastManage:
|
||||
|
||||
@classmethod
|
||||
async def send(
|
||||
cls, bot: Bot, message: UniMsg, session: EventSession
|
||||
@@ -43,8 +42,9 @@ class BroadcastManage:
|
||||
for group in group_list:
|
||||
try:
|
||||
if not await CommonUtils.task_is_block(
|
||||
group.group_id,
|
||||
bot,
|
||||
"broadcast", # group.channel_id
|
||||
group.group_id,
|
||||
):
|
||||
target = PlatformUtils.get_target(
|
||||
bot, None, group.channel_id or group.group_id
|
||||
|
||||
@@ -15,6 +15,19 @@ class BotSetting(BaseModel):
|
||||
"""数据库链接"""
|
||||
platform_superusers: dict[str, list[str]] = {}
|
||||
"""平台超级用户"""
|
||||
qbot_id_data: dict[str, str] = {}
|
||||
"""官bot id:账号id"""
|
||||
|
||||
def get_qbot_uid(self, qbot_id: str) -> str | None:
|
||||
"""获取官bot账号id
|
||||
|
||||
参数:
|
||||
qbot_id: 官bot id
|
||||
|
||||
返回:
|
||||
str: 账号id
|
||||
"""
|
||||
return self.qbot_id_data.get(qbot_id)
|
||||
|
||||
def get_superuser(self, platform: str) -> list[str]:
|
||||
"""获取超级用户
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
from .db_context import *
|
||||
from .log import *
|
||||
|
||||
@@ -4,13 +4,11 @@ from tortoise.models import Model as Model_
|
||||
from nonebot.utils import is_coroutine_callable
|
||||
|
||||
from zhenxun.configs.config import BotConfig
|
||||
from zhenxun.configs.path_config import DATA_PATH
|
||||
|
||||
from .log import logger
|
||||
|
||||
SCRIPT_METHOD = []
|
||||
MODELS: list[str] = []
|
||||
DATABASE_SETTING_FILE = DATA_PATH / "database.json"
|
||||
|
||||
|
||||
class Model(Model_):
|
||||
|
||||
+81
-4
@@ -7,6 +7,7 @@ require("nonebot_plugin_session")
|
||||
from loguru import logger as logger_
|
||||
from nonebot_plugin_session import Session
|
||||
from nonebot.log import default_filter, default_format
|
||||
from nonebot_plugin_uninfo import Session as uninfoSession
|
||||
|
||||
from zhenxun.configs.path_config import LOG_PATH
|
||||
|
||||
@@ -77,13 +78,25 @@ class logger:
|
||||
platform: str | None = None,
|
||||
): ...
|
||||
|
||||
@overload
|
||||
@classmethod
|
||||
def info(
|
||||
cls,
|
||||
info: str,
|
||||
command: str | None = None,
|
||||
*,
|
||||
session: int | str | Session | None = None,
|
||||
session: uninfoSession | None = None,
|
||||
target: Any = None,
|
||||
platform: str | None = None,
|
||||
): ...
|
||||
|
||||
@classmethod
|
||||
def info(
|
||||
cls,
|
||||
info: str,
|
||||
command: str | None = None,
|
||||
*,
|
||||
session: int | str | Session | uninfoSession | None = None,
|
||||
group_id: int | str | None = None,
|
||||
adapter: str | None = None,
|
||||
target: Any = None,
|
||||
@@ -98,6 +111,12 @@ class logger:
|
||||
elif session.id2:
|
||||
group_id = f"{session.id2}"
|
||||
platform = platform or session.platform
|
||||
elif isinstance(session, uninfoSession):
|
||||
user_id = session.user.id
|
||||
adapter = session.adapter
|
||||
if session.group:
|
||||
group_id = session.group.id
|
||||
platform = session.basic["scope"]
|
||||
template = cls.__parser_template(
|
||||
info, command, user_id, group_id, adapter, target, platform
|
||||
)
|
||||
@@ -150,13 +169,27 @@ class logger:
|
||||
e: Exception | None = None,
|
||||
): ...
|
||||
|
||||
@overload
|
||||
@classmethod
|
||||
def warning(
|
||||
cls,
|
||||
info: str,
|
||||
command: str | None = None,
|
||||
*,
|
||||
session: int | str | Session | None = None,
|
||||
session: uninfoSession | None = None,
|
||||
adapter: str | None = None,
|
||||
target: Any = None,
|
||||
platform: str | None = None,
|
||||
e: Exception | None = None,
|
||||
): ...
|
||||
|
||||
@classmethod
|
||||
def warning(
|
||||
cls,
|
||||
info: str,
|
||||
command: str | None = None,
|
||||
*,
|
||||
session: int | str | Session | uninfoSession | None = None,
|
||||
group_id: int | str | None = None,
|
||||
adapter: str | None = None,
|
||||
target: Any = None,
|
||||
@@ -172,6 +205,12 @@ class logger:
|
||||
elif session.id2:
|
||||
group_id = f"{session.id2}"
|
||||
platform = platform or session.platform
|
||||
elif isinstance(session, uninfoSession):
|
||||
user_id = session.user.id
|
||||
adapter = session.adapter
|
||||
if session.group:
|
||||
group_id = session.group.id
|
||||
platform = session.basic["scope"]
|
||||
template = cls.__parser_template(
|
||||
info, command, user_id, group_id, adapter, target, platform
|
||||
)
|
||||
@@ -210,13 +249,26 @@ class logger:
|
||||
e: Exception | None = None,
|
||||
): ...
|
||||
|
||||
@overload
|
||||
@classmethod
|
||||
def error(
|
||||
cls,
|
||||
info: str,
|
||||
command: str | None = None,
|
||||
*,
|
||||
session: int | str | Session | None = None,
|
||||
session: uninfoSession | None = None,
|
||||
target: Any = None,
|
||||
platform: str | None = None,
|
||||
e: Exception | None = None,
|
||||
): ...
|
||||
|
||||
@classmethod
|
||||
def error(
|
||||
cls,
|
||||
info: str,
|
||||
command: str | None = None,
|
||||
*,
|
||||
session: int | str | Session | uninfoSession | None = None,
|
||||
group_id: int | str | None = None,
|
||||
adapter: str | None = None,
|
||||
target: Any = None,
|
||||
@@ -232,6 +284,12 @@ class logger:
|
||||
elif session.id2:
|
||||
group_id = f"{session.id2}"
|
||||
platform = platform or session.platform
|
||||
elif isinstance(session, uninfoSession):
|
||||
user_id = session.user.id
|
||||
adapter = session.adapter
|
||||
if session.group:
|
||||
group_id = session.group.id
|
||||
platform = session.basic["scope"]
|
||||
template = cls.__parser_template(
|
||||
info, command, user_id, group_id, adapter, target, platform
|
||||
)
|
||||
@@ -270,13 +328,26 @@ class logger:
|
||||
e: Exception | None = None,
|
||||
): ...
|
||||
|
||||
@overload
|
||||
@classmethod
|
||||
def debug(
|
||||
cls,
|
||||
info: str,
|
||||
command: str | None = None,
|
||||
*,
|
||||
session: int | str | Session | None = None,
|
||||
session: uninfoSession | None = None,
|
||||
target: Any = None,
|
||||
platform: str | None = None,
|
||||
e: Exception | None = None,
|
||||
): ...
|
||||
|
||||
@classmethod
|
||||
def debug(
|
||||
cls,
|
||||
info: str,
|
||||
command: str | None = None,
|
||||
*,
|
||||
session: int | str | Session | uninfoSession | None = None,
|
||||
group_id: int | str | None = None,
|
||||
adapter: str | None = None,
|
||||
target: Any = None,
|
||||
@@ -292,6 +363,12 @@ class logger:
|
||||
elif session.id2:
|
||||
group_id = f"{session.id2}"
|
||||
platform = platform or session.platform
|
||||
elif isinstance(session, uninfoSession):
|
||||
user_id = session.user.id
|
||||
adapter = session.adapter
|
||||
if session.group:
|
||||
group_id = session.group.id
|
||||
platform = session.basic["scope"]
|
||||
template = cls.__parser_template(
|
||||
info, command, user_id, group_id, adapter, target, platform
|
||||
)
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
from nonebot.adapters import Bot
|
||||
from nonebot_plugin_uninfo import Uninfo, Session, SupportScope, get_interface
|
||||
|
||||
from zhenxun.services.log import logger
|
||||
from zhenxun.configs.config import BotConfig
|
||||
from zhenxun.models.task_info import TaskInfo
|
||||
@@ -6,9 +9,10 @@ from zhenxun.models.group_console import GroupConsole
|
||||
|
||||
|
||||
class CommonUtils:
|
||||
|
||||
@classmethod
|
||||
async def task_is_block(cls, module: str, group_id: str | None) -> bool:
|
||||
async def task_is_block(
|
||||
cls, session: Uninfo | Bot, module: str, group_id: str | None = None
|
||||
) -> bool:
|
||||
"""判断被动技能是否可以发送
|
||||
|
||||
参数:
|
||||
@@ -18,6 +22,19 @@ class CommonUtils:
|
||||
返回:
|
||||
bool: 是否可以发送
|
||||
"""
|
||||
if isinstance(session, Bot):
|
||||
if interface := get_interface(session):
|
||||
info = interface.basic_info()
|
||||
if info["scope"] == SupportScope.qq_api:
|
||||
logger.info("q官bot放弃所有被动技能发言...")
|
||||
"""q官bot放弃所有被动技能发言"""
|
||||
return False
|
||||
if session.scene == SupportScope.qq_api:
|
||||
"""q官bot放弃所有被动技能发言"""
|
||||
logger.info("q官bot放弃所有被动技能发言...")
|
||||
return False
|
||||
if not group_id and isinstance(session, Session):
|
||||
group_id = session.group.id if session.group else None
|
||||
if task := await TaskInfo.get_or_none(module=module):
|
||||
"""被动全局状态"""
|
||||
if not task.status:
|
||||
@@ -39,7 +56,6 @@ class CommonUtils:
|
||||
|
||||
|
||||
class SqlUtils:
|
||||
|
||||
@classmethod
|
||||
def random(cls, query, limit: int = 1) -> str:
|
||||
db_class_name = BotConfig.get_sql_type()
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
from typing import Any
|
||||
|
||||
from nonebot.internal.params import Depends
|
||||
from nonebot.matcher import Matcher
|
||||
from nonebot.params import Command
|
||||
from nonebot.matcher import Matcher
|
||||
from nonebot_plugin_uninfo import Uninfo
|
||||
from nonebot.internal.params import Depends
|
||||
from nonebot_plugin_session import EventSession
|
||||
from nonebot_plugin_userinfo import EventUserInfo, UserInfo
|
||||
|
||||
from zhenxun.configs.config import Config
|
||||
from zhenxun.utils.message import MessageUtils
|
||||
@@ -49,10 +49,8 @@ def UserName():
|
||||
用户名称
|
||||
"""
|
||||
|
||||
async def dependency(user_info: UserInfo = EventUserInfo()):
|
||||
return (
|
||||
user_info.user_displayname or user_info.user_remark or user_info.user_name
|
||||
) or ""
|
||||
async def dependency(user_info: Uninfo):
|
||||
return user_info.user.nick or user_info.user.name or ""
|
||||
|
||||
return Depends(dependency)
|
||||
|
||||
|
||||
@@ -202,6 +202,11 @@ class AsyncHttpx:
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
async def get_content(cls, url: str, **kwargs) -> bytes | None:
|
||||
res = await cls.get(url, **kwargs)
|
||||
return res.content if res and res.status_code == 200 else None
|
||||
|
||||
@classmethod
|
||||
async def download_file(
|
||||
cls,
|
||||
|
||||
+47
-25
@@ -7,20 +7,24 @@ import nonebot
|
||||
from pydantic import BaseModel
|
||||
from nonebot.adapters import Bot
|
||||
from nonebot.utils import is_coroutine_callable
|
||||
from nonebot_plugin_uninfo import get_interface
|
||||
from nonebot_plugin_alconna import SupportScope
|
||||
from nonebot.adapters.dodo import Bot as DodoBot
|
||||
from nonebot.adapters.onebot.v11 import Bot as v11Bot
|
||||
from nonebot.adapters.onebot.v12 import Bot as v12Bot
|
||||
from nonebot_plugin_uninfo import Uninfo, get_interface
|
||||
from nonebot.adapters.kaiheila import Bot as KaiheilaBot
|
||||
from nonebot_plugin_alconna.uniseg import Target, Receipt, UniMessage
|
||||
|
||||
from zhenxun.services.log import logger
|
||||
from zhenxun.configs.config import BotConfig
|
||||
from zhenxun.utils.message import MessageUtils
|
||||
from zhenxun.utils.http_utils import AsyncHttpx
|
||||
from zhenxun.models.friend_user import FriendUser
|
||||
from zhenxun.utils.exception import NotFindSuperuser
|
||||
from zhenxun.models.group_console import GroupConsole
|
||||
|
||||
driver = nonebot.get_driver()
|
||||
|
||||
|
||||
class UserData(BaseModel):
|
||||
name: str
|
||||
@@ -40,6 +44,18 @@ class UserData(BaseModel):
|
||||
|
||||
|
||||
class PlatformUtils:
|
||||
@classmethod
|
||||
def is_qbot(cls, session: Uninfo) -> bool:
|
||||
"""判断bot是否为qq官bot
|
||||
|
||||
参数:
|
||||
session: Uninfo
|
||||
|
||||
返回:
|
||||
bool: 是否为官bot
|
||||
"""
|
||||
return session.scope == SupportScope.qq_api
|
||||
|
||||
@classmethod
|
||||
async def ban_user(cls, bot: Bot, user_id: str, group_id: str, duration: int):
|
||||
"""禁言
|
||||
@@ -244,30 +260,27 @@ class PlatformUtils:
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
async def get_user_avatar(cls, user_id: str, platform: str) -> bytes | None:
|
||||
async def get_user_avatar(
|
||||
cls, user_id: str, platform: str, appid: str | None = None
|
||||
) -> bytes | None:
|
||||
"""快捷获取用户头像
|
||||
|
||||
参数:
|
||||
user_id: 用户id
|
||||
platform: 平台
|
||||
"""
|
||||
url = None
|
||||
if platform == "qq":
|
||||
url = f"http://q1.qlogo.cn/g?b=qq&nk={user_id}&s=160"
|
||||
async with httpx.AsyncClient() as client:
|
||||
for _ in range(3):
|
||||
try:
|
||||
return (await client.get(url)).content
|
||||
except Exception:
|
||||
logger.error(
|
||||
"获取用户头像错误",
|
||||
"Util",
|
||||
target=user_id,
|
||||
platform=platform,
|
||||
)
|
||||
return None
|
||||
if user_id.isdigit():
|
||||
url = f"http://q1.qlogo.cn/g?b=qq&nk={user_id}&s=160"
|
||||
else:
|
||||
url = f"https://q.qlogo.cn/qqapp/{appid}/{user_id}/100"
|
||||
return await AsyncHttpx.get_content(url) if url else None
|
||||
|
||||
@classmethod
|
||||
def get_user_avatar_url(cls, user_id: str, platform: str) -> str | None:
|
||||
def get_user_avatar_url(
|
||||
cls, user_id: str, platform: str, appid: str | None = None
|
||||
) -> str | None:
|
||||
"""快捷获取用户头像url
|
||||
|
||||
参数:
|
||||
@@ -275,8 +288,13 @@ class PlatformUtils:
|
||||
platform: 平台
|
||||
"""
|
||||
if platform == "qq":
|
||||
return f"http://q1.qlogo.cn/g?b=qq&nk={user_id}&s=160"
|
||||
return None
|
||||
return (
|
||||
f"http://q1.qlogo.cn/g?b=qq&nk={user_id}&s=160"
|
||||
if user_id.isdigit()
|
||||
else f"https://q.qlogo.cn/qqapp/{appid}/{user_id}/100"
|
||||
)
|
||||
else:
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
async def get_group_avatar(cls, gid: str, platform: str) -> bytes | None:
|
||||
@@ -371,7 +389,7 @@ class PlatformUtils:
|
||||
return len(create_list)
|
||||
|
||||
@classmethod
|
||||
def get_platform(cls, bot: Bot) -> str | None:
|
||||
def get_platform(cls, t: Bot | Uninfo) -> str:
|
||||
"""获取平台
|
||||
|
||||
参数:
|
||||
@@ -380,9 +398,13 @@ class PlatformUtils:
|
||||
返回:
|
||||
str | None: 平台
|
||||
"""
|
||||
if interface := get_interface(bot):
|
||||
info = interface.basic_info()
|
||||
platform = info["scope"].lower()
|
||||
if isinstance(t, Bot):
|
||||
if interface := get_interface(t):
|
||||
info = interface.basic_info()
|
||||
platform = info["scope"].lower()
|
||||
return "qq" if platform.startswith("qq") else platform
|
||||
else:
|
||||
platform = t.basic["scope"].lower()
|
||||
return "qq" if platform.startswith("qq") else platform
|
||||
return "unknown"
|
||||
|
||||
@@ -548,7 +570,7 @@ async def broadcast_group(
|
||||
bot: Bot | list[Bot] | None = None,
|
||||
bot_id: str | set[str] | None = None,
|
||||
ignore_group: set[int] | None = None,
|
||||
check_func: Callable[[str], Awaitable] | None = None,
|
||||
check_func: Callable[[Bot, str], Awaitable] | None = None,
|
||||
log_cmd: str | None = None,
|
||||
platform: Literal["qq", "dodo", "kaiheila"] | None = None,
|
||||
):
|
||||
@@ -611,9 +633,9 @@ async def broadcast_group(
|
||||
is_run = False
|
||||
if check_func:
|
||||
if is_coroutine_callable(check_func):
|
||||
is_run = await check_func(group.group_id)
|
||||
is_run = await check_func(_bot, group.group_id)
|
||||
else:
|
||||
is_run = check_func(group.group_id)
|
||||
is_run = check_func(_bot, group.group_id)
|
||||
if not is_run:
|
||||
logger.debug(
|
||||
"广播方法检测运行方法为 False, 已跳过...",
|
||||
|
||||
+14
-7
@@ -1,10 +1,12 @@
|
||||
from nonebot.internal.rule import Rule
|
||||
from nonebot.adapters import Bot, Event
|
||||
from nonebot.permission import SUPERUSER
|
||||
from nonebot_plugin_session import EventSession, SessionLevel
|
||||
from nonebot_plugin_uninfo import Uninfo
|
||||
from nonebot_plugin_session import EventSession
|
||||
|
||||
from zhenxun.configs.config import Config
|
||||
from zhenxun.models.level_user import LevelUser
|
||||
from zhenxun.utils.platform import PlatformUtils
|
||||
|
||||
|
||||
def admin_check(a: int | str, key: str | None = None) -> Rule:
|
||||
@@ -19,33 +21,38 @@ def admin_check(a: int | str, key: str | None = None) -> Rule:
|
||||
Rule: Rule
|
||||
"""
|
||||
|
||||
async def _rule(bot: Bot, event: Event, session: EventSession) -> bool:
|
||||
async def _rule(bot: Bot, event: Event, session: Uninfo) -> bool:
|
||||
if await SUPERUSER(bot, event):
|
||||
return True
|
||||
if session.id1 and session.id2:
|
||||
if PlatformUtils.is_qbot(session):
|
||||
"""官bot接口,放弃所有权限检查"""
|
||||
return False
|
||||
if session.id and session.group:
|
||||
level = a
|
||||
if isinstance(a, str) and key:
|
||||
level = Config.get_config(a, key)
|
||||
if level is not None:
|
||||
return bool(
|
||||
await LevelUser.check_level(session.id1, session.id2, int(level))
|
||||
await LevelUser.check_level(
|
||||
session.id, session.group.id, int(level)
|
||||
)
|
||||
)
|
||||
return False
|
||||
|
||||
return Rule(_rule)
|
||||
|
||||
|
||||
def ensure_group(session: EventSession) -> bool:
|
||||
def ensure_group(session: Uninfo) -> bool:
|
||||
"""
|
||||
是否在群聊中
|
||||
|
||||
参数:
|
||||
session: session
|
||||
session: Uninfo
|
||||
|
||||
返回:
|
||||
bool: bool
|
||||
"""
|
||||
return session.level in [SessionLevel.LEVEL2, SessionLevel.LEVEL3]
|
||||
return bool(session.group)
|
||||
|
||||
|
||||
def ensure_private(session: EventSession) -> bool:
|
||||
|
||||
Reference in New Issue
Block a user