zhenxun_bot/zhenxun/plugins/bym_ai/bym_gift/data_source.py

174 lines
4.7 KiB
Python
Raw Normal View History

2025-07-01 16:56:34 +08:00
import asyncio
from collections.abc import Callable
from datetime import datetime
import inspect
import random
from types import MappingProxyType
from nonebot.adapters import Bot, Event
from nonebot.utils import is_coroutine_callable
from nonebot_plugin_alconna import UniMessage, UniMsg
from nonebot_plugin_uninfo import Uninfo
from tortoise.expressions import F
from zhenxun.configs.config import BotConfig
from zhenxun.configs.path_config import IMAGE_PATH
from zhenxun.utils.platform import PlatformUtils
from ..exception import GiftRepeatSendException
from ..models.bym_gift_log import GiftLog
from ..models.bym_gift_store import GiftStore
from ..models.bym_user import BymUser
from .gift_register import gift_register
ICON_PATH = IMAGE_PATH / "gift_icon"
ICON_PATH.mkdir(parents=True, exist_ok=True)
gift_list = []
async def send_gift(user_id: str, session: Uninfo) -> str:
global gift_list
if (
await GiftLog.filter(
user_id=session.user.id, create_time__gte=datetime.now().date(), type=0
).count()
> 2
):
raise GiftRepeatSendException
if not gift_list:
gift_list = await GiftStore.all()
gift = random.choice(gift_list)
user = await BymUser.get_user(user_id, PlatformUtils.get_platform(session))
if gift.uuid not in user.props:
user.props[gift.uuid] = 0
user.props[gift.uuid] += 1
await asyncio.gather(
*[
user.save(update_fields=["props"]),
GiftLog.create(user_id=user_id, uuid=gift.uuid, type=0),
GiftStore.filter(uuid=gift.uuid).update(count=F("count") + 1),
]
)
return f"{BotConfig.self_nickname}赠送了{gift.name}作为礼物。"
def __build_params(
bot: Bot,
event: Event,
session: Uninfo,
message: UniMsg,
gift: GiftStore,
num: int,
):
group_id = None
if session.group:
group_id = session.group.parent.id if session.group.parent else session.group.id
return {
"_bot": bot,
"event": event,
"user_id": session.user.id,
"group_id": group_id,
"num": num,
"name": gift.name,
"message": message,
}
def __parse_args(
args: MappingProxyType,
**kwargs,
) -> dict:
"""解析参数
参数:
args: MappingProxyType
返回:
list[Any]: 参数
"""
_kwargs = kwargs.copy()
for key in kwargs:
if key not in args:
del _kwargs[key]
return _kwargs
async def __run(
func: Callable,
**kwargs,
) -> str | UniMessage | None:
"""运行道具函数
参数:
goods: Goods
param: ShopParam
返回:
str | MessageFactory | None: 使用完成后返回信息
"""
args = inspect.signature(func).parameters # type: ignore
if args and next(iter(args.keys())) != "kwargs":
return (
await func(**__parse_args(args, **kwargs))
if is_coroutine_callable(func)
else func(**__parse_args(args, **kwargs))
)
if is_coroutine_callable(func):
return await func()
else:
return func()
async def use_gift(
bot: Bot,
event: Event,
session: Uninfo,
message: UniMsg,
name: str,
num: int,
) -> str | UniMessage:
"""使用道具
参数:
bot: Bot
event: Event
session: Session
message: 消息
name: 礼物名称
num: 使用数量
text: 其他信息
返回:
str | MessageFactory: 使用完成后返回信息
"""
user = await BymUser.get_user(user_id=session.user.id)
if name.isdigit():
try:
uuid = list(user.props.keys())[int(name)]
gift_info = await GiftStore.get_or_none(uuid=uuid)
except IndexError:
return "仓库中礼物不存在..."
else:
gift_info = await GiftStore.get_or_none(goods_name=name)
if not gift_info:
return f"{name} 不存在..."
func = gift_register.get_func(gift_info.name)
if not func:
return f"{gift_info.name} 未注册使用函数, 无法使用..."
if user.props[gift_info.uuid] < num:
return f"你的 {gift_info.name} 数量不足 {num} 个..."
kwargs = __build_params(bot, event, session, message, gift_info, num)
result = await __run(func, **kwargs)
if gift_info.uuid not in user.usage_count:
user.usage_count[gift_info.uuid] = 0
user.usage_count[gift_info.uuid] += num
user.props[gift_info.uuid] -= num
if user.props[gift_info.uuid] < 0:
del user.props[gift_info.uuid]
await user.save(update_fields=["props", "usage_count"])
await GiftLog.create(user_id=session.user.id, uuid=gift_info.uuid, type=1)
if not result:
result = f"使用道具 {gift_info.name} {num} 次成功!"
return result