mirror of
https://github.com/zhenxun-org/zhenxun_bot.git
synced 2025-12-15 06:12:53 +08:00
更新至nonebot-rc1
This commit is contained in:
parent
e9216a472f
commit
0bfe398dc4
13
README.md
13
README.md
@ -286,6 +286,17 @@ PS: **ARM平台** 请使用全量版 同时 **如果你的机器 RAM < 1G 可能
|
||||
|
||||
## 更新
|
||||
|
||||
### 2022/10/15
|
||||
|
||||
* nonebot2版本更新为rc1
|
||||
* 我的道具改为图片形式
|
||||
* 商品添加图标与是否为被动道具(被动道具无法被主动使用)
|
||||
* 商品添加使用前方法和使用后方法(类似hook),使用方法具体查看文档或签到商品文件中注册的例子
|
||||
|
||||
### 2022/10/9
|
||||
|
||||
* 修复碧蓝档案角色获取问题,换源 [@pull/1124](https://github.com/HibiKier/zhenxun_bot/pull/1124)
|
||||
|
||||
### 2022/10/7
|
||||
|
||||
* 修复 B 站请求返回 -401 错误 [@pull/1119](https://github.com/HibiKier/zhenxun_bot/pull/1119)
|
||||
@ -368,7 +379,7 @@ PS: **ARM平台** 请使用全量版 同时 **如果你的机器 RAM < 1G 可能
|
||||
* 修复b站转发解析av号无法解析
|
||||
* B站订阅直播订阅支持短号
|
||||
* 开箱提供重置开箱命令,重置今日所有开箱数据(重置次数,并不会删除今日已开箱记录)
|
||||
* 提供全局字典GDict,通过from utils.manager import GDict导入
|
||||
* 提供全局字典GDict,通过from utils.utils import GDict导入
|
||||
* 适配omega 13w张图的数据结构表(建议删表重导)
|
||||
* 除首次启动外将配置替换加入单次定时任务,加快启动速度
|
||||
* fix: WordBank.check() [@pull/1008](https://github.com/HibiKier/zhenxun_bot/pull/1008)
|
||||
|
||||
@ -15,7 +15,7 @@ from configs.path_config import TEXT_PATH
|
||||
from asyncio.exceptions import TimeoutError
|
||||
from typing import List
|
||||
from utils.http_utils import AsyncHttpx
|
||||
from utils.manager import GDict
|
||||
from utils.utils import GDict
|
||||
from utils.utils import scheduler
|
||||
import nonebot
|
||||
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
from nonebot import on_command
|
||||
|
||||
from models.shop_log import ShopLog
|
||||
from services.log import logger
|
||||
from nonebot.adapters.onebot.v11 import GroupMessageEvent, Message
|
||||
from nonebot.params import CommandArg
|
||||
@ -46,10 +48,7 @@ async def _(event: GroupMessageEvent, arg: Message = CommandArg()):
|
||||
for x in await GoodsInfo.get_all_goods()
|
||||
if x.goods_limit_time > time.time() or x.goods_limit_time == 0
|
||||
]
|
||||
goods_name_list = [
|
||||
x.goods_name
|
||||
for x in goods_list
|
||||
]
|
||||
goods_name_list = [x.goods_name for x in goods_list]
|
||||
msg = arg.extract_plain_text().strip().split()
|
||||
num = 1
|
||||
if len(msg) > 1:
|
||||
@ -77,11 +76,15 @@ async def _(event: GroupMessageEvent, arg: Message = CommandArg()):
|
||||
await BagUser.get_gold(event.user_id, event.group_id)
|
||||
) < goods.goods_price * num * goods.goods_discount:
|
||||
await buy.finish("您的金币好像不太够哦", at_sender=True)
|
||||
flag, n = await GoodsInfo.check_user_daily_purchase(goods, event.user_id, event.group_id, num)
|
||||
flag, n = await GoodsInfo.check_user_daily_purchase(
|
||||
goods, event.user_id, event.group_id, num
|
||||
)
|
||||
if flag:
|
||||
await buy.finish(f"该次购买将超过每日次数限制,目前该道具还可以购买{n}次哦", at_sender=True)
|
||||
if await BagUser.buy_property(event.user_id, event.group_id, goods, num):
|
||||
await GoodsInfo.add_user_daily_purchase(goods, event.user_id, event.group_id, num)
|
||||
await GoodsInfo.add_user_daily_purchase(
|
||||
goods, event.user_id, event.group_id, num
|
||||
)
|
||||
await buy.send(
|
||||
f"花费 {goods.goods_price * num * goods.goods_discount} 金币购买 {goods.goods_name} ×{num} 成功!",
|
||||
at_sender=True,
|
||||
@ -90,6 +93,14 @@ async def _(event: GroupMessageEvent, arg: Message = CommandArg()):
|
||||
f"USER {event.user_id} GROUP {event.group_id} "
|
||||
f"花费 {goods.goods_price*num} 金币购买 {goods.goods_name} ×{num} 成功!"
|
||||
)
|
||||
await ShopLog.add_shop_log(
|
||||
event.user_id,
|
||||
event.group_id,
|
||||
0,
|
||||
goods.goods_name,
|
||||
num,
|
||||
goods.goods_price * num * goods.goods_discount,
|
||||
)
|
||||
else:
|
||||
await buy.send(f"{goods.goods_name} 购买失败!", at_sender=True)
|
||||
logger.info(
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
from nonebot import on_command
|
||||
|
||||
from utils.message_builder import image
|
||||
from ._data_source import create_bag_image
|
||||
from services.log import logger
|
||||
from nonebot.adapters.onebot.v11 import GroupMessageEvent
|
||||
from models.bag_user import BagUser
|
||||
@ -32,10 +35,11 @@ my_props = on_command("我的道具", priority=5, block=True, permission=GROUP)
|
||||
async def _(event: GroupMessageEvent):
|
||||
props = await BagUser.get_property(event.user_id, event.group_id)
|
||||
if props:
|
||||
rst = ""
|
||||
for i, p in enumerate(props.keys()):
|
||||
rst += f"{i+1}.{p}\t×{props[p]}\n"
|
||||
await my_props.send("\n" + rst[:-1], at_sender=True)
|
||||
await my_props.send(image(b64=await create_bag_image(props)))
|
||||
# rst = ""
|
||||
# for i, p in enumerate(props.keys()):
|
||||
# rst += f"{i+1}.{p}\t×{props[p]}\n"
|
||||
# await my_props.send("\n" + rst[:-1], at_sender=True)
|
||||
logger.info(f"USER {event.user_id} GROUP {event.group_id} 查看我的道具")
|
||||
else:
|
||||
await my_props.finish("您的背包里没有任何的道具噢~", at_sender=True)
|
||||
66
basic_plugins/shop/my_props/_data_source.py
Normal file
66
basic_plugins/shop/my_props/_data_source.py
Normal file
@ -0,0 +1,66 @@
|
||||
from typing import Dict, List
|
||||
|
||||
from models.bag_user import BagUser
|
||||
from models.goods_info import GoodsInfo
|
||||
from utils.image_utils import BuildImage
|
||||
from configs.path_config import IMAGE_PATH
|
||||
|
||||
|
||||
icon_path = IMAGE_PATH / 'shop_icon'
|
||||
|
||||
|
||||
async def create_bag_image(props: Dict[str, int]):
|
||||
"""
|
||||
说明:
|
||||
创建背包道具图片
|
||||
参数:
|
||||
:param props: 道具仓库字典
|
||||
"""
|
||||
goods_list = await GoodsInfo.get_all_goods()
|
||||
active_props = await _init_prop(props, [x for x in goods_list if not x.is_passive])
|
||||
passive_props = await _init_prop(props, [x for x in goods_list if x.is_passive])
|
||||
A = BuildImage(active_props.w + passive_props.w + 100, max(active_props.h, passive_props.h) + 100, font="CJGaoDeGuo.otf", font_size=30, color="#f9f6f2")
|
||||
await A.apaste(active_props, (50, 70))
|
||||
await A.apaste(passive_props, (active_props.w + 50, 70))
|
||||
await A.aline((active_props.w + 45, 70, active_props.w + 45, A.h - 20), fill=(0, 0, 0))
|
||||
await A.atext((50, 30), "主动道具")
|
||||
await A.atext((active_props.w + 55, 30), "被动道具")
|
||||
return A.pic2bs4()
|
||||
|
||||
|
||||
async def _init_prop(props: Dict[str, int], _props: List[GoodsInfo]) -> BuildImage:
|
||||
"""
|
||||
说明:
|
||||
构造道具列表图片
|
||||
参数:
|
||||
:param props: 道具仓库字典
|
||||
:param _props: 道具列表
|
||||
"""
|
||||
active_name = [x.goods_name for x in _props]
|
||||
name_list = [x for x in props.keys() if x in active_name]
|
||||
temp_img = BuildImage(0, 0, font_size=20)
|
||||
image_list = []
|
||||
num_list = []
|
||||
for i, name in enumerate(name_list):
|
||||
img = BuildImage(temp_img.getsize(name)[0] + 50, 30, font="msyh.ttf", font_size=20, color="#f9f6f2")
|
||||
await img.atext((30, 5), f'{i + 1}.{name}')
|
||||
goods = [x for x in _props if x.goods_name == name][0]
|
||||
if goods.icon and (icon_path / goods.icon).exists():
|
||||
icon = BuildImage(30, 30, background=icon_path / goods.icon)
|
||||
await img.apaste(icon, alpha=True)
|
||||
image_list.append(img)
|
||||
num_list.append(BuildImage(30, 30, font_size=20, plain_text=f"×{props[name]}"))
|
||||
max_w = 0
|
||||
num_max_w = 0
|
||||
h = 0
|
||||
for img, num in zip(image_list, num_list):
|
||||
h += img.h
|
||||
max_w = max_w if max_w > img.w else img.w
|
||||
num_max_w = num_max_w if num_max_w > num.w else num.w
|
||||
A = BuildImage(max_w + num_max_w + 30, h, color="#f9f6f2")
|
||||
curr_h = 0
|
||||
for img, num in zip(image_list, num_list):
|
||||
await A.apaste(img, (0, curr_h))
|
||||
await A.apaste(num, (max_w + 20, curr_h + 5), True)
|
||||
curr_h += img.h
|
||||
return A
|
||||
@ -6,7 +6,6 @@ from utils.message_builder import image
|
||||
from nonebot.permission import SUPERUSER
|
||||
from utils.utils import is_number, scheduler
|
||||
from nonebot.params import CommandArg
|
||||
from nonebot.plugin import export
|
||||
from services.log import logger
|
||||
import os
|
||||
|
||||
@ -51,11 +50,6 @@ __plugin_block_limit__ = {
|
||||
"limit_type": "group"
|
||||
}
|
||||
|
||||
# 导出方法供其他插件使用
|
||||
export = export()
|
||||
export.register_goods = register_goods
|
||||
export.delete_goods = delete_goods
|
||||
export.update_goods = update_goods
|
||||
|
||||
shop_help = on_command("商店", priority=5, block=True)
|
||||
|
||||
|
||||
@ -2,49 +2,17 @@ from PIL import Image
|
||||
|
||||
from models.goods_info import GoodsInfo
|
||||
from utils.image_utils import BuildImage
|
||||
from models.sign_group_user import SignGroupUser
|
||||
from utils.utils import is_number
|
||||
from configs.path_config import IMAGE_PATH
|
||||
from typing import Optional, Union, Tuple
|
||||
from configs.config import Config
|
||||
from nonebot import Driver
|
||||
from nonebot.plugin import require
|
||||
from utils.decorator.shop import shop_register
|
||||
import nonebot
|
||||
from utils.utils import GDict
|
||||
import time
|
||||
|
||||
driver: Driver = nonebot.get_driver()
|
||||
icon_path = IMAGE_PATH / 'shop_icon'
|
||||
|
||||
|
||||
use = require("use")
|
||||
|
||||
|
||||
@driver.on_startup
|
||||
async def init_default_shop_goods():
|
||||
"""
|
||||
导入内置的三个商品
|
||||
"""
|
||||
|
||||
@shop_register(
|
||||
name=("好感度双倍加持卡Ⅰ", "好感度双倍加持卡Ⅱ", "好感度双倍加持卡Ⅲ"),
|
||||
price=(30, 150, 250),
|
||||
des=(
|
||||
"下次签到双倍好感度概率 + 10%(谁才是真命天子?)(同类商品将覆盖)",
|
||||
"下次签到双倍好感度概率 + 20%(平平庸庸)(同类商品将覆盖)",
|
||||
"下次签到双倍好感度概率 + 30%(金币才是真命天子!)(同类商品将覆盖)",
|
||||
),
|
||||
load_status=Config.get_config("shop", "IMPORT_DEFAULT_SHOP_GOODS"),
|
||||
daily_limit=(10, 20, 30),
|
||||
** {"好感度双倍加持卡Ⅰ_prob": 0.1, "好感度双倍加持卡Ⅱ_prob": 0.2, "好感度双倍加持卡Ⅲ_prob": 0.3},
|
||||
)
|
||||
async def sign_card(user_id: int, group_id: int, prob: float):
|
||||
user = await SignGroupUser.ensure(user_id, group_id)
|
||||
await user.update(add_probability=prob).apply()
|
||||
|
||||
|
||||
@driver.on_bot_connect
|
||||
async def _():
|
||||
await shop_register.load_register()
|
||||
GDict['run_sql'].append("ALTER TABLE goods_info ADD is_passive boolean DEFAULT False;")
|
||||
GDict['run_sql'].append("ALTER TABLE goods_info ADD icon VARCHAR(255);")
|
||||
|
||||
|
||||
# 创建商店界面
|
||||
@ -63,7 +31,7 @@ async def create_shop_help() -> str:
|
||||
if goods.goods_limit_time == 0 or time.time() < goods.goods_limit_time:
|
||||
h += len(goods.goods_description.strip().split("\n")) * font_h + 80
|
||||
_list.append(goods)
|
||||
A = BuildImage(1000, h, color="#f9f6f2")
|
||||
A = BuildImage(1100, h, color="#f9f6f2")
|
||||
current_h = 0
|
||||
total_n = 0
|
||||
for goods in _list:
|
||||
@ -106,9 +74,12 @@ async def create_shop_help() -> str:
|
||||
await goods_image.apaste(name_image, (0, 5), True, center_type="by_width")
|
||||
await goods_image.atext((15, 50), f"简介:{goods.goods_description}")
|
||||
await goods_image.acircle_corner(20)
|
||||
await bk.apaste(goods_image, alpha=True)
|
||||
if goods.icon and (icon_path / goods.icon).exists():
|
||||
icon = BuildImage(100, 100, background=icon_path / goods.icon)
|
||||
await bk.apaste(icon)
|
||||
await bk.apaste(goods_image, (100, 0), alpha=True)
|
||||
n = 0
|
||||
_w = 550
|
||||
_w = 650
|
||||
# 添加限时图标和时间
|
||||
if goods.goods_limit_time > 0:
|
||||
n += 140
|
||||
@ -162,14 +133,14 @@ async def create_shop_help() -> str:
|
||||
if total_n < n:
|
||||
total_n = n
|
||||
if n:
|
||||
await bk.aline((550, -1, 550 + n, -1), "#a29ad6", 5)
|
||||
await bk.aline((550, 80, 550 + n, 80), "#a29ad6", 5)
|
||||
await bk.aline((650, -1, 650 + n, -1), "#a29ad6", 5)
|
||||
await bk.aline((650, 80, 650 + n, 80), "#a29ad6", 5)
|
||||
|
||||
# 添加限时图标和时间
|
||||
idx += 1
|
||||
await A.apaste(bk, (0, current_h), True)
|
||||
current_h += 90
|
||||
w = 850
|
||||
w = 950
|
||||
if total_n:
|
||||
w += total_n
|
||||
h = A.h + 230 + 100
|
||||
@ -197,6 +168,8 @@ async def register_goods(
|
||||
discount: Optional[float] = 1,
|
||||
limit_time: Optional[int] = 0,
|
||||
daily_limit: Optional[int] = 0,
|
||||
is_passive: Optional[bool] = False,
|
||||
icon: Optional[str] = None,
|
||||
) -> bool:
|
||||
"""
|
||||
添加商品
|
||||
@ -209,6 +182,8 @@ async def register_goods(
|
||||
:param discount: 商品折扣
|
||||
:param limit_time: 商品限时销售时间,单位为小时
|
||||
:param daily_limit: 每日购买次数限制
|
||||
:param is_passive: 是否为被动
|
||||
:param icon: 图标
|
||||
:return: 是否添加成功
|
||||
"""
|
||||
if not await GoodsInfo.get_goods_info(name):
|
||||
@ -220,7 +195,7 @@ async def register_goods(
|
||||
else 0
|
||||
)
|
||||
return await GoodsInfo.add_goods(
|
||||
name, int(price), des, float(discount), limit_time, daily_limit
|
||||
name, int(price), des, float(discount), limit_time, daily_limit, is_passive, icon
|
||||
)
|
||||
return False
|
||||
|
||||
@ -272,6 +247,7 @@ async def update_goods(**kwargs) -> Tuple[bool, str, str]:
|
||||
discount = goods.goods_discount
|
||||
limit_time = goods.goods_limit_time
|
||||
daily_limit = goods.daily_limit
|
||||
is_passive = goods.is_passive
|
||||
new_time = 0
|
||||
tmp = ""
|
||||
if kwargs.get("price"):
|
||||
@ -294,6 +270,9 @@ async def update_goods(**kwargs) -> Tuple[bool, str, str]:
|
||||
if kwargs.get("daily_limit"):
|
||||
tmp += f'每日购买限制:{daily_limit} --> {kwargs["daily_limit"]}\n' if daily_limit else "取消了购买限制\n"
|
||||
daily_limit = int(kwargs["daily_limit"])
|
||||
if kwargs.get("is_passive"):
|
||||
tmp += f'被动道具:{is_passive} --> {kwargs["is_passive"]}\n'
|
||||
des = kwargs["is_passive"]
|
||||
await GoodsInfo.update_goods(
|
||||
name,
|
||||
int(price),
|
||||
@ -304,7 +283,8 @@ async def update_goods(**kwargs) -> Tuple[bool, str, str]:
|
||||
if limit_time != 0 and new_time
|
||||
else 0
|
||||
),
|
||||
daily_limit
|
||||
daily_limit,
|
||||
is_passive
|
||||
)
|
||||
return True, name, tmp[:-1],
|
||||
|
||||
|
||||
@ -1,13 +1,16 @@
|
||||
from nonebot import on_command
|
||||
|
||||
from models.shop_log import ShopLog
|
||||
from services.log import logger
|
||||
from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent, Message
|
||||
from nonebot.params import CommandArg
|
||||
|
||||
from utils.decorator.shop import NotMeetUseConditionsException
|
||||
from utils.utils import is_number
|
||||
from models.bag_user import BagUser
|
||||
from nonebot.adapters.onebot.v11.permission import GROUP
|
||||
from services.db_context import db
|
||||
from nonebot.plugin import export
|
||||
from .data_source import effect, register_use, func_manager
|
||||
from .data_source import effect, register_use, func_manager, build_params
|
||||
|
||||
|
||||
__zx_plugin_name__ = "商店 - 使用道具"
|
||||
@ -30,9 +33,6 @@ __plugin_settings__ = {
|
||||
"cmd": ["商店", "使用道具"],
|
||||
}
|
||||
|
||||
# 导出方法供其他插件使用
|
||||
export = export()
|
||||
export.register_use = register_use
|
||||
|
||||
use_props = on_command("使用道具", priority=5, block=True, permission=GROUP)
|
||||
|
||||
@ -45,23 +45,29 @@ async def _(bot: Bot, event: GroupMessageEvent, arg: Message = CommandArg()):
|
||||
if len(msg_sp) > 1 and is_number(msg_sp[-1]) and int(msg_sp[-1]) > 0:
|
||||
num = int(msg.split()[-1])
|
||||
msg = " ".join(msg.split()[:-1])
|
||||
property_ = await BagUser.get_property(event.user_id, event.group_id)
|
||||
property_ = await BagUser.get_property(event.user_id, event.group_id, True)
|
||||
if property_:
|
||||
async with db.transaction():
|
||||
if is_number(msg):
|
||||
if 0 < int(msg) <= len(property_):
|
||||
name = list(property_.keys())[int(msg) - 1]
|
||||
else:
|
||||
await use_props.finish("仔细看看自己的道具仓库有没有这个道具?", at_sender=True)
|
||||
name = None
|
||||
if is_number(msg):
|
||||
if 0 < int(msg) <= len(property_):
|
||||
name = list(property_.keys())[int(msg) - 1]
|
||||
else:
|
||||
if msg not in property_.keys():
|
||||
await use_props.finish("道具名称错误!", at_sender=True)
|
||||
name = msg
|
||||
_user_prop_count = property_[name]
|
||||
if num > _user_prop_count:
|
||||
await use_props.finish(f"道具数量不足,无法使用{num}次!")
|
||||
if num > (n := func_manager.get_max_num_limit(name)):
|
||||
await use_props.finish(f"该道具单次只能使用 {n} 个!")
|
||||
await use_props.finish("仔细看看自己的道具仓库有没有这个道具?", at_sender=True)
|
||||
else:
|
||||
if msg not in property_.keys():
|
||||
await use_props.finish("道具名称错误!", at_sender=True)
|
||||
name = msg
|
||||
_user_prop_count = property_[name]
|
||||
if num > _user_prop_count:
|
||||
await use_props.finish(f"道具数量不足,无法使用{num}次!")
|
||||
if num > (n := func_manager.get_max_num_limit(name)):
|
||||
await use_props.finish(f"该道具单次只能使用 {n} 个!")
|
||||
model, kwargs = build_params(bot, event, name, num)
|
||||
try:
|
||||
await func_manager.run_handle(type_="before_handle", param=model, **kwargs)
|
||||
except NotMeetUseConditionsException as e:
|
||||
await use_props.finish(e.get_info(), at_sender=True)
|
||||
async with db.transaction():
|
||||
if await BagUser.delete_property(
|
||||
event.user_id, event.group_id, name, num
|
||||
):
|
||||
@ -72,10 +78,12 @@ async def _(bot: Bot, event: GroupMessageEvent, arg: Message = CommandArg()):
|
||||
logger.info(
|
||||
f"USER {event.user_id} GROUP {event.group_id} 使用道具 {name} {num} 次成功"
|
||||
)
|
||||
await ShopLog.add_shop_log(event.user_id, event.group_id, 1, name, num)
|
||||
else:
|
||||
await use_props.send(f"使用道具 {name} {num} 次失败!", at_sender=True)
|
||||
logger.info(
|
||||
f"USER {event.user_id} GROUP {event.group_id} 使用道具 {name} {num} 次失败"
|
||||
)
|
||||
await func_manager.run_handle(type_="after_handle", param=model, **kwargs)
|
||||
else:
|
||||
await use_props.send("您的背包里没有任何的道具噢", at_sender=True)
|
||||
|
||||
@ -3,7 +3,7 @@ from services.log import logger
|
||||
from nonebot.adapters.onebot.v11 import Bot
|
||||
from pydantic import create_model
|
||||
from utils.models import ShopParam
|
||||
from typing import Optional, Union
|
||||
from typing import Optional, Union, Callable, List, Tuple, Dict, Any
|
||||
from types import MappingProxyType
|
||||
import inspect
|
||||
import asyncio
|
||||
@ -13,6 +13,30 @@ class GoodsUseFuncManager:
|
||||
def __init__(self):
|
||||
self._data = {}
|
||||
|
||||
def register_use_before_handle(self, goods_name: str, fun_list: List[Callable]):
|
||||
"""
|
||||
说明:
|
||||
注册商品使用前函数
|
||||
参数:
|
||||
:param goods_name: 商品名称
|
||||
:param fun_list: 函数列表
|
||||
"""
|
||||
if fun_list:
|
||||
self._data[goods_name]["before_handle"] = fun_list
|
||||
logger.info(f"register_use_before_handle 成功注册商品:{goods_name} 的{len(fun_list)}个使用前函数")
|
||||
|
||||
def register_use_after_handle(self, goods_name: str, fun_list: List[Callable]):
|
||||
"""
|
||||
说明:
|
||||
注册商品使用后函数
|
||||
参数:
|
||||
:param goods_name: 商品名称
|
||||
:param fun_list: 函数列表
|
||||
"""
|
||||
if fun_list:
|
||||
self._data[goods_name]["after_handle"] = fun_list
|
||||
logger.info(f"register_use_after_handle 成功注册商品:{goods_name} 的{len(fun_list)}个使用后函数")
|
||||
|
||||
def register_use(self, goods_name: str, **kwargs):
|
||||
"""
|
||||
注册商品使用方法
|
||||
@ -26,7 +50,7 @@ class GoodsUseFuncManager:
|
||||
判断商品使用方法是否被注册
|
||||
:param goods_name: 商品名称
|
||||
"""
|
||||
return bool(self ._data.get(goods_name))
|
||||
return bool(self._data.get(goods_name))
|
||||
|
||||
def get_max_num_limit(self, goods_name: str) -> int:
|
||||
"""
|
||||
@ -37,6 +61,21 @@ class GoodsUseFuncManager:
|
||||
return self._data[goods_name]["kwargs"]["max_num_limit"]
|
||||
return 1
|
||||
|
||||
def _parse_args(self, args_: MappingProxyType, param: ShopParam, **kwargs):
|
||||
param_list_ = []
|
||||
_bot = param.bot
|
||||
param.bot = None
|
||||
param_json = param.dict()
|
||||
param_json["bot"] = _bot
|
||||
for par in args_.keys():
|
||||
if par in ["shop_param"]:
|
||||
param_list_.append(param)
|
||||
elif par not in ["args", "kwargs"]:
|
||||
param_list_.append(param_json.get(par))
|
||||
if kwargs.get(par) is not None:
|
||||
del kwargs[par]
|
||||
return param_list_
|
||||
|
||||
async def use(
|
||||
self, param: ShopParam, **kwargs
|
||||
) -> Optional[Union[str, MessageSegment]]:
|
||||
@ -45,31 +84,18 @@ class GoodsUseFuncManager:
|
||||
:param param: BaseModel
|
||||
:param kwargs: kwargs
|
||||
"""
|
||||
def parse_args(args_: MappingProxyType):
|
||||
param_list_ = []
|
||||
_bot = param.bot
|
||||
param.bot = None
|
||||
param_json = param.dict()
|
||||
param_json["bot"] = _bot
|
||||
for par in args_.keys():
|
||||
if par in ["shop_param"]:
|
||||
param_list_.append(param)
|
||||
elif par not in ["args", "kwargs"]:
|
||||
param_list_.append(param_json.get(par))
|
||||
if kwargs.get(par) is not None:
|
||||
del kwargs[par]
|
||||
return param_list_
|
||||
goods_name = param.goods_name
|
||||
if self.exists(goods_name):
|
||||
# 使用方法
|
||||
args = inspect.signature(self._data[goods_name]["func"]).parameters
|
||||
if args and list(args.keys())[0] != "kwargs":
|
||||
if asyncio.iscoroutinefunction(self._data[goods_name]["func"]):
|
||||
return await self._data[goods_name]["func"](
|
||||
*parse_args(args)
|
||||
*self._parse_args(args, param, **kwargs)
|
||||
)
|
||||
else:
|
||||
return self._data[goods_name]["func"](
|
||||
*parse_args(args)
|
||||
*self._parse_args(args, param, **kwargs)
|
||||
)
|
||||
else:
|
||||
if asyncio.iscoroutinefunction(self._data[goods_name]["func"]):
|
||||
@ -81,6 +107,21 @@ class GoodsUseFuncManager:
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
async def run_handle(self, goods_name: str, type_: str, param: ShopParam, **kwargs):
|
||||
if self._data[goods_name].get(type_):
|
||||
for func in self._data[goods_name].get(type_):
|
||||
args = inspect.signature(func).parameters
|
||||
if args and list(args.keys())[0] != "kwargs":
|
||||
if asyncio.iscoroutinefunction(func):
|
||||
await func(*self._parse_args(args, param, **kwargs))
|
||||
else:
|
||||
func(*self._parse_args(args, param, **kwargs))
|
||||
else:
|
||||
if asyncio.iscoroutinefunction(func):
|
||||
await func(**kwargs)
|
||||
else:
|
||||
func(**kwargs)
|
||||
|
||||
def check_send_success_message(self, goods_name: str) -> bool:
|
||||
"""
|
||||
检查是否发送使用成功信息
|
||||
@ -115,6 +156,34 @@ class GoodsUseFuncManager:
|
||||
func_manager = GoodsUseFuncManager()
|
||||
|
||||
|
||||
def build_params(
|
||||
bot: Bot, event: GroupMessageEvent, goods_name: str, num: int
|
||||
) -> Tuple[ShopParam, Dict[str, Any]]:
|
||||
"""
|
||||
说明:
|
||||
构造参数
|
||||
参数:
|
||||
:param bot: bot
|
||||
:param event: event
|
||||
:param goods_name: 商品名称
|
||||
:param num: 数量
|
||||
:return:
|
||||
"""
|
||||
_kwargs = func_manager.get_kwargs(goods_name)
|
||||
return (
|
||||
func_manager.init_model(goods_name, bot, event, num),
|
||||
{
|
||||
**_kwargs,
|
||||
"_bot": bot,
|
||||
"event": event,
|
||||
"group_id": event.group_id,
|
||||
"user_id": event.user_id,
|
||||
"num": num,
|
||||
"goods_name": goods_name,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
async def effect(
|
||||
bot: Bot, event: GroupMessageEvent, goods_name: str, num: int
|
||||
) -> Optional[Union[str, MessageSegment]]:
|
||||
@ -130,24 +199,14 @@ async def effect(
|
||||
# try:
|
||||
if func_manager.exists(goods_name):
|
||||
_kwargs = func_manager.get_kwargs(goods_name)
|
||||
return await func_manager.use(
|
||||
func_manager.init_model(goods_name, bot, event, num),
|
||||
**{
|
||||
**_kwargs,
|
||||
"_bot": bot,
|
||||
"event": event,
|
||||
"group_id": event.group_id,
|
||||
"user_id": event.user_id,
|
||||
"num": num,
|
||||
"goods_name": goods_name,
|
||||
},
|
||||
)
|
||||
model, kwargs = build_params(bot, event, goods_name, num)
|
||||
return await func_manager.use(model, **kwargs)
|
||||
# except Exception as e:
|
||||
# logger.error(f"use 商品生效函数effect 发生错误 {type(e)}:{e}")
|
||||
return None
|
||||
|
||||
|
||||
def register_use(goods_name: str, func, **kwargs):
|
||||
def register_use(goods_name: str, func: Callable, **kwargs):
|
||||
"""
|
||||
注册商品使用方法
|
||||
:param goods_name: 商品名称
|
||||
|
||||
@ -2,6 +2,7 @@ from services.db_context import db
|
||||
from typing import Dict
|
||||
from typing import Optional, List
|
||||
from services.log import logger
|
||||
from .goods_info import GoodsInfo
|
||||
|
||||
|
||||
class BagUser(db.Model):
|
||||
@ -62,17 +63,24 @@ class BagUser(db.Model):
|
||||
return 100
|
||||
|
||||
@classmethod
|
||||
async def get_property(cls, user_qq: int, group_id: int) -> Dict[str, int]:
|
||||
async def get_property(cls, user_qq: int, group_id: int, only_active: bool = False) -> Dict[str, int]:
|
||||
"""
|
||||
说明:
|
||||
获取当前道具
|
||||
参数:
|
||||
:param user_qq: qq号
|
||||
:param group_id: 所在群号
|
||||
:param only_active: 仅仅获取主动使用的道具
|
||||
"""
|
||||
query = cls.query.where((cls.user_qq == user_qq) & (cls.group_id == group_id))
|
||||
user = await query.gino.first()
|
||||
if user:
|
||||
if only_active and user.property:
|
||||
data = {}
|
||||
name_list = [x.goods_name for x in await GoodsInfo.get_all_goods() if not x.is_passive]
|
||||
for key in [x for x in user.property.keys() if x in name_list]:
|
||||
data[key] = user.property[key]
|
||||
return data
|
||||
return user.property
|
||||
else:
|
||||
await cls.create(
|
||||
|
||||
@ -16,6 +16,8 @@ class GoodsInfo(db.Model):
|
||||
daily_purchase_limit = db.Column(
|
||||
db.JSON(), nullable=False, default={}
|
||||
) # 每日购买限制数据存储
|
||||
is_passive = db.Column(db.Boolean(), nullable=False, default=0) # 是否为被动
|
||||
icon = db.Column(db.String(), nullable=False, default=0) # 图标
|
||||
|
||||
_idx1 = db.Index("goods_group_users_idx1", "goods_name", unique=True)
|
||||
|
||||
@ -28,6 +30,8 @@ class GoodsInfo(db.Model):
|
||||
goods_discount: float = 1,
|
||||
goods_limit_time: int = 0,
|
||||
daily_limit: int = 0,
|
||||
is_passive: bool = False,
|
||||
icon: Optional[str] = None,
|
||||
) -> bool:
|
||||
"""
|
||||
说明:
|
||||
@ -39,6 +43,8 @@ class GoodsInfo(db.Model):
|
||||
:param goods_discount: 商品折扣
|
||||
:param goods_limit_time: 商品限时
|
||||
:param daily_limit: 每日购买限制
|
||||
:param is_passive: 是否为被动道具
|
||||
:param icon: 图标
|
||||
"""
|
||||
try:
|
||||
if not await cls.get_goods_info(goods_name):
|
||||
@ -49,10 +55,12 @@ class GoodsInfo(db.Model):
|
||||
goods_discount=goods_discount,
|
||||
goods_limit_time=goods_limit_time,
|
||||
daily_limit=daily_limit,
|
||||
is_passive=is_passive,
|
||||
icon=icon
|
||||
)
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"GoodsInfo add_goods 发生错误 {type(e)}:{e}")
|
||||
logger.error(f"GoodsInfo add_goods {goods_name} 发生错误 {type(e)}:{e}")
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
@ -81,7 +89,9 @@ class GoodsInfo(db.Model):
|
||||
goods_description: Optional[str] = None,
|
||||
goods_discount: Optional[float] = None,
|
||||
goods_limit_time: Optional[int] = None,
|
||||
daily_limit: Optional[int] = None
|
||||
daily_limit: Optional[int] = None,
|
||||
is_passive: Optional[bool] = None,
|
||||
icon: Optional[str] = None,
|
||||
) -> bool:
|
||||
"""
|
||||
说明:
|
||||
@ -93,6 +103,8 @@ class GoodsInfo(db.Model):
|
||||
:param goods_discount: 商品折扣
|
||||
:param goods_limit_time: 商品限时时间
|
||||
:param daily_limit: 每日次数限制
|
||||
:param is_passive: 是否为被动
|
||||
:param icon: 图标
|
||||
"""
|
||||
try:
|
||||
query = (
|
||||
@ -108,6 +120,8 @@ class GoodsInfo(db.Model):
|
||||
goods_discount=goods_discount or query.goods_discount,
|
||||
goods_limit_time=goods_limit_time if goods_limit_time is not None else query.goods_limit_time,
|
||||
daily_limit=daily_limit if daily_limit is not None else query.daily_limit,
|
||||
is_passive=is_passive if is_passive is not None else query.is_passive,
|
||||
icon=icon or query.icon
|
||||
).apply()
|
||||
return True
|
||||
except Exception as e:
|
||||
|
||||
59
models/shop_log.py
Normal file
59
models/shop_log.py
Normal file
@ -0,0 +1,59 @@
|
||||
from datetime import datetime
|
||||
|
||||
from services.db_context import db
|
||||
|
||||
|
||||
class ShopLog(db.Model):
|
||||
__tablename__ = "shop_log"
|
||||
id = db.Column(db.Integer(), primary_key=True)
|
||||
user_qq = db.Column(db.BigInteger(), nullable=False)
|
||||
group_id = db.Column(db.BigInteger(), nullable=False)
|
||||
type = db.Column(db.Integer(), nullable=False) # 0: 购买,1: 使用
|
||||
goods_name = db.Column(db.String(), default=100)
|
||||
spend_gold = db.Column(db.Integer(), nullable=False)
|
||||
num = db.Column(db.Integer(), nullable=False)
|
||||
create_time = db.Column(db.DateTime(timezone=True), nullable=False)
|
||||
|
||||
@classmethod
|
||||
async def add_shop_log(
|
||||
cls,
|
||||
user_qq: int,
|
||||
group_id: int,
|
||||
type_: int,
|
||||
goods_name: str,
|
||||
num: int,
|
||||
spend_gold: int = 0,
|
||||
):
|
||||
"""
|
||||
说明:
|
||||
添加商店购买或使用日志
|
||||
参数:
|
||||
:param user_qq: qq号
|
||||
:param group_id: 所在群号
|
||||
:param type_: 类型
|
||||
:param goods_name: 商品名称
|
||||
:param num: 数量
|
||||
:param spend_gold: 花费金币
|
||||
"""
|
||||
await cls.create(
|
||||
user_qq=user_qq,
|
||||
group_id=group_id,
|
||||
type=type_,
|
||||
goods_name=goods_name,
|
||||
num=num,
|
||||
spend_gold=spend_gold,
|
||||
create_time=datetime.now(),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
async def get_user_log(cls, user_qq: int, group_id: int) -> "ShopLog":
|
||||
"""
|
||||
说明:
|
||||
获取用户日志
|
||||
参数:
|
||||
:param user_qq: qq号
|
||||
:param group_id: 所在群号
|
||||
"""
|
||||
return await cls.query.where(
|
||||
(cls.user_qq == user_qq) & (cls.group_qq == group_id)
|
||||
).first()
|
||||
@ -3,7 +3,6 @@ from nonebot.adapters.onebot.v11 import MessageEvent, GroupMessageEvent
|
||||
from services.log import logger
|
||||
from .data_source import get_user_memo, get_memo
|
||||
from .._models import Genshin
|
||||
from nonebot.plugin import export
|
||||
|
||||
|
||||
__zx_plugin_name__ = "原神便笺查询"
|
||||
@ -28,10 +27,6 @@ __plugin_settings__ = {
|
||||
__plugin_block_limit__ = {}
|
||||
|
||||
|
||||
export = export()
|
||||
|
||||
export.get_memo = get_memo
|
||||
|
||||
query_memo_matcher = on_command("原神便签查询", aliases={"原神便笺查询", "yss"}, priority=5, block=True)
|
||||
|
||||
|
||||
|
||||
@ -19,7 +19,9 @@ import pytz
|
||||
driver: Driver = nonebot.get_driver()
|
||||
|
||||
|
||||
get_memo = require("query_memo").get_memo
|
||||
require("query_memo")
|
||||
|
||||
from ..query_memo import get_memo
|
||||
|
||||
|
||||
global_map = {}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
from configs.config import Config
|
||||
from utils.manager import GDict
|
||||
from utils.utils import GDict
|
||||
import nonebot
|
||||
|
||||
|
||||
|
||||
@ -18,6 +18,7 @@ from configs.path_config import DATA_PATH
|
||||
from services.log import logger
|
||||
from .utils import clear_sign_data_pic
|
||||
from utils.utils import is_number
|
||||
from .goods_register import driver
|
||||
|
||||
try:
|
||||
import ujson as json
|
||||
|
||||
60
plugins/sign_in/goods_register.py
Normal file
60
plugins/sign_in/goods_register.py
Normal file
@ -0,0 +1,60 @@
|
||||
|
||||
from models.sign_group_user import SignGroupUser
|
||||
from configs.config import Config
|
||||
from nonebot import Driver
|
||||
from utils.decorator.shop import shop_register, NotMeetUseConditionsException
|
||||
import nonebot
|
||||
|
||||
driver: Driver = nonebot.get_driver()
|
||||
|
||||
|
||||
@driver.on_startup
|
||||
async def _():
|
||||
"""
|
||||
导入内置的三个商品
|
||||
"""
|
||||
|
||||
@shop_register(
|
||||
name=("好感度双倍加持卡Ⅰ", "好感度双倍加持卡Ⅱ", "好感度双倍加持卡Ⅲ"),
|
||||
price=(30, 150, 250),
|
||||
des=(
|
||||
"下次签到双倍好感度概率 + 10%(谁才是真命天子?)(同类商品将覆盖)",
|
||||
"下次签到双倍好感度概率 + 20%(平平庸庸)(同类商品将覆盖)",
|
||||
"下次签到双倍好感度概率 + 30%(金币才是真命天子!)(同类商品将覆盖)",
|
||||
),
|
||||
load_status=Config.get_config("shop", "IMPORT_DEFAULT_SHOP_GOODS"),
|
||||
icon=("favorability_card_1.png", "favorability_card_2.png", "favorability_card_3.png"),
|
||||
** {"好感度双倍加持卡Ⅰ_prob": 0.1, "好感度双倍加持卡Ⅱ_prob": 0.2, "好感度双倍加持卡Ⅲ_prob": 0.3},
|
||||
)
|
||||
async def sign_card(user_id: int, group_id: int, prob: float):
|
||||
user = await SignGroupUser.ensure(user_id, group_id)
|
||||
await user.update(add_probability=prob).apply()
|
||||
|
||||
@shop_register(
|
||||
name="测试道具A",
|
||||
price=99,
|
||||
des="随便侧而出",
|
||||
load_status=False,
|
||||
icon="sword.png",
|
||||
)
|
||||
async def _(user_id: int, group_id: int):
|
||||
print(user_id, group_id, '使用测试道具')
|
||||
|
||||
@shop_register.before_handle(name="测试道具A", load_status=False)
|
||||
async def _(user_id: int, group_id: int):
|
||||
print(user_id, group_id, '第一个使用前函数(before handle)')
|
||||
|
||||
@shop_register.before_handle(name="测试道具A", load_status=False)
|
||||
async def _(user_id: int, group_id: int):
|
||||
print(user_id, group_id, '第二个使用前函数(before handle)222')
|
||||
raise NotMeetUseConditionsException("太笨了!") # 抛出异常,阻断使用,并返回信息
|
||||
|
||||
@shop_register.after_handle(name="测试道具A", load_status=False)
|
||||
async def _(user_id: int, group_id: int):
|
||||
print(user_id, group_id, '第一个使用后函数(after handle)')
|
||||
|
||||
|
||||
@driver.on_bot_connect
|
||||
async def _():
|
||||
await shop_register.load_register()
|
||||
|
||||
821
poetry.lock
generated
821
poetry.lock
generated
File diff suppressed because it is too large
Load Diff
@ -12,13 +12,12 @@ url = "https://mirrors.aliyun.com/pypi/simple/"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.8"
|
||||
nonebot2 = "^2.0.0-beta.4"
|
||||
nonebot2 = "^2.0.0rc1"
|
||||
nonebot-adapter-onebot = "^2.0.0-beta.1"
|
||||
aiofiles = "^0.8.0"
|
||||
aiohttp = "3.7.4.post0"
|
||||
beautifulsoup4 = "4.9.3"
|
||||
feedparser = "^6.0.8"
|
||||
gino = "^1.0.1"
|
||||
httpx = "^0.23.0"
|
||||
ImageHash = "^4.2.1"
|
||||
jieba = "^0.42.1"
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
from typing import Callable, Union, Tuple
|
||||
from typing import Callable, Union, Tuple, Optional
|
||||
from nonebot.adapters.onebot.v11 import MessageSegment, Message
|
||||
from nonebot.plugin import require
|
||||
|
||||
|
||||
use = require("use")
|
||||
shop = require("shop_handle")
|
||||
require("use")
|
||||
require("shop_handle")
|
||||
|
||||
|
||||
class ShopRegister(dict):
|
||||
@ -12,6 +12,44 @@ class ShopRegister(dict):
|
||||
self._data = {}
|
||||
self._flag = True
|
||||
|
||||
def before_handle(self, name: Union[str, Tuple[str, ...]], load_status: bool = True):
|
||||
"""
|
||||
说明:
|
||||
使用前检查方法
|
||||
参数:
|
||||
:param name: 道具名称
|
||||
:param load_status: 加载状态
|
||||
"""
|
||||
def register_before_handle(name_list: Tuple[str, ...], func: Callable):
|
||||
if load_status:
|
||||
for name_ in name_list:
|
||||
if not self._data[name_]:
|
||||
self._data[name_] = {}
|
||||
if not self._data[name_].get('before_handle'):
|
||||
self._data[name_]['before_handle'] = []
|
||||
self._data[name]['before_handle'].append(func)
|
||||
_name = (name,) if isinstance(name, str) else name
|
||||
return lambda func: register_before_handle(_name, func)
|
||||
|
||||
def after_handle(self, name: Union[str, Tuple[str, ...]], load_status: bool = True):
|
||||
"""
|
||||
说明:
|
||||
使用后执行方法
|
||||
参数:
|
||||
:param name: 道具名称
|
||||
:param load_status: 加载状态
|
||||
"""
|
||||
def register_after_handle(name_list: Tuple[str, ...], func: Callable):
|
||||
if load_status:
|
||||
for name_ in name_list:
|
||||
if not self._data[name_]:
|
||||
self._data[name_] = {}
|
||||
if not self._data[name_].get('after_handle'):
|
||||
self._data[name_]['after_handle'] = []
|
||||
self._data[name_]['after_handle'].append(func)
|
||||
_name = (name,) if isinstance(name, str) else name
|
||||
return lambda func: register_after_handle(_name, func)
|
||||
|
||||
def register(
|
||||
self,
|
||||
name: Tuple[str, ...],
|
||||
@ -21,13 +59,15 @@ class ShopRegister(dict):
|
||||
limit_time: Tuple[int, ...],
|
||||
load_status: Tuple[bool, ...],
|
||||
daily_limit: Tuple[int, ...],
|
||||
is_passive: Tuple[bool, ...],
|
||||
icon: Tuple[str, ...],
|
||||
**kwargs,
|
||||
):
|
||||
def add_register_item(func: Callable):
|
||||
if name in self._data.keys():
|
||||
raise ValueError("该商品已注册,请替换其他名称!")
|
||||
for n, p, d, dd, l, s, dl in zip(
|
||||
name, price, des, discount, limit_time, load_status, daily_limit
|
||||
for n, p, d, dd, l, s, dl, pa, i in zip(
|
||||
name, price, des, discount, limit_time, load_status, daily_limit, is_passive, icon
|
||||
):
|
||||
if s:
|
||||
_temp_kwargs = {}
|
||||
@ -36,46 +76,58 @@ class ShopRegister(dict):
|
||||
_temp_kwargs[key.split("_", maxsplit=1)[-1]] = value
|
||||
else:
|
||||
_temp_kwargs[key] = value
|
||||
self._data[n] = {
|
||||
temp = self._data.get(n, {})
|
||||
temp.update({
|
||||
"price": p,
|
||||
"des": d,
|
||||
"discount": dd,
|
||||
"limit_time": l,
|
||||
"daily_limit": dl,
|
||||
"icon": i,
|
||||
"is_passive": pa,
|
||||
"func": func,
|
||||
"kwargs": _temp_kwargs,
|
||||
}
|
||||
})
|
||||
self._data[n] = temp
|
||||
return func
|
||||
|
||||
return lambda func: add_register_item(func)
|
||||
|
||||
async def load_register(self):
|
||||
from basic_plugins.shop.use.data_source import register_use, func_manager
|
||||
from basic_plugins.shop.shop_handle.data_source import register_goods
|
||||
# 统一进行注册
|
||||
if self._flag:
|
||||
# 只进行一次注册
|
||||
self._flag = False
|
||||
for name in self._data.keys():
|
||||
await shop.register_goods(
|
||||
await register_goods(
|
||||
name,
|
||||
self._data[name]["price"],
|
||||
self._data[name]["des"],
|
||||
self._data[name]["discount"],
|
||||
self._data[name]["limit_time"],
|
||||
self._data[name]["daily_limit"],
|
||||
self._data[name]["is_passive"],
|
||||
self._data[name]["icon"],
|
||||
)
|
||||
use.register_use(
|
||||
register_use(
|
||||
name, self._data[name]["func"], **self._data[name]["kwargs"]
|
||||
)
|
||||
func_manager.register_use_before_handle(name, self._data[name].get('before_handle', []))
|
||||
func_manager.register_use_after_handle(name, self._data[name].get('after_handle', []))
|
||||
|
||||
def __call__(
|
||||
self,
|
||||
name: Union[str, Tuple[str, ...]],
|
||||
price: Union[float, Tuple[float, ...]],
|
||||
des: Union[str, Tuple[str, ...]],
|
||||
discount: Union[float, Tuple[float, ...]] = 1,
|
||||
limit_time: Union[int, Tuple[int, ...]] = 0,
|
||||
load_status: Union[bool, Tuple[bool, ...]] = True,
|
||||
daily_limit: Union[int, Tuple[int, ...]] = 0,
|
||||
name: Union[str, Tuple[str, ...]], # 名称
|
||||
price: Union[float, Tuple[float, ...]], # 价格
|
||||
des: Union[str, Tuple[str, ...]], # 简介
|
||||
discount: Union[float, Tuple[float, ...]] = 1, # 折扣
|
||||
limit_time: Union[int, Tuple[int, ...]] = 0, # 限时
|
||||
load_status: Union[bool, Tuple[bool, ...]] = True, # 加载状态
|
||||
daily_limit: Union[int, Tuple[int, ...]] = 0, # 每日限购
|
||||
is_passive: Union[bool, Tuple[bool, ...]] = False, # 被动道具(无法被'使用道具'命令消耗)
|
||||
icon: Union[str, Tuple[str, ...]] = False, # 图标
|
||||
**kwargs,
|
||||
):
|
||||
_tuple_list = []
|
||||
@ -89,35 +141,15 @@ class ShopRegister(dict):
|
||||
f"注册商品 {name} 中 name,price,des,discount,limit_time,load_status,daily_limit 数量不符!"
|
||||
)
|
||||
_current_len = _current_len if _current_len > -1 else 1
|
||||
_name = name if isinstance(name, tuple) else (name,)
|
||||
_price = (
|
||||
price
|
||||
if isinstance(price, tuple)
|
||||
else tuple([price for _ in range(_current_len)])
|
||||
)
|
||||
_discount = (
|
||||
discount
|
||||
if isinstance(discount, tuple)
|
||||
else tuple([discount for _ in range(_current_len)])
|
||||
)
|
||||
_limit_time = (
|
||||
limit_time
|
||||
if isinstance(limit_time, tuple)
|
||||
else tuple([limit_time for _ in range(_current_len)])
|
||||
)
|
||||
_des = (
|
||||
des if isinstance(des, tuple) else tuple([des for _ in range(_current_len)])
|
||||
)
|
||||
_load_status = (
|
||||
load_status
|
||||
if isinstance(load_status, tuple)
|
||||
else tuple([load_status for _ in range(_current_len)])
|
||||
)
|
||||
_daily_limit = (
|
||||
daily_limit
|
||||
if isinstance(daily_limit, tuple)
|
||||
else tuple([daily_limit for _ in range(_current_len)])
|
||||
)
|
||||
_name = self.__get(name, _current_len)
|
||||
_price = self.__get(price, _current_len)
|
||||
_discount = self.__get(discount, _current_len)
|
||||
_limit_time = self.__get(limit_time, _current_len)
|
||||
_des = self.__get(des, _current_len)
|
||||
_load_status = self.__get(load_status, _current_len)
|
||||
_daily_limit = self.__get(daily_limit, _current_len)
|
||||
_is_passive = self.__get(is_passive, _current_len)
|
||||
_icon = self.__get(icon, _current_len)
|
||||
return self.register(
|
||||
_name,
|
||||
_price,
|
||||
@ -126,9 +158,14 @@ class ShopRegister(dict):
|
||||
_limit_time,
|
||||
_load_status,
|
||||
_daily_limit,
|
||||
_is_passive,
|
||||
_icon,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
def __get(self, value, _current_len):
|
||||
return value if isinstance(value, tuple) else tuple([value for _ in range(_current_len)])
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
self._data[key] = value
|
||||
|
||||
@ -151,4 +188,18 @@ class ShopRegister(dict):
|
||||
return self._data.items()
|
||||
|
||||
|
||||
class NotMeetUseConditionsException(Exception):
|
||||
|
||||
"""
|
||||
不满足条件异常类
|
||||
"""
|
||||
|
||||
def __init__(self, info: Optional[Union[str, MessageSegment, Message]]):
|
||||
super().__init__(self)
|
||||
self._info = info
|
||||
|
||||
def get_info(self):
|
||||
return self._info
|
||||
|
||||
|
||||
shop_register = ShopRegister()
|
||||
|
||||
@ -14,11 +14,6 @@ from .requests_manager import RequestManager
|
||||
from configs.path_config import DATA_PATH
|
||||
|
||||
|
||||
# 全局字典
|
||||
GDict = {
|
||||
"run_sql": [] # 需要启动前运行的sql语句
|
||||
}
|
||||
|
||||
# 群功能开关 | 群被动技能 | 群权限 管理
|
||||
group_manager: Optional[GroupManager] = GroupManager(
|
||||
DATA_PATH / "manager" / "group_manager.json"
|
||||
|
||||
@ -18,8 +18,17 @@ try:
|
||||
except ModuleNotFoundError:
|
||||
import json
|
||||
|
||||
require("nonebot_plugin_apscheduler")
|
||||
from nonebot_plugin_apscheduler import scheduler
|
||||
|
||||
scheduler = require("nonebot_plugin_apscheduler").scheduler
|
||||
scheduler = scheduler
|
||||
|
||||
# 全局字典
|
||||
GDict = {
|
||||
"run_sql": [], # 需要启动前运行的sql语句
|
||||
"_shop_before_handle": {}, # 商品使用前函数
|
||||
"_shop_after_handle": {}, # 商品使用后函数
|
||||
}
|
||||
|
||||
|
||||
class CountLimiter:
|
||||
@ -110,8 +119,8 @@ class BanCheckLimiter:
|
||||
self.mint[key] = 0
|
||||
return False
|
||||
if (
|
||||
self.mint[key] >= self.default_count
|
||||
and time.time() - self.mtime[key] < self.default_check_time
|
||||
self.mint[key] >= self.default_count
|
||||
and time.time() - self.mtime[key] < self.default_check_time
|
||||
):
|
||||
self.mtime[key] = time.time()
|
||||
self.mint[key] = 0
|
||||
@ -402,7 +411,7 @@ def cn2py(word: str) -> str:
|
||||
|
||||
|
||||
def change_pixiv_image_links(
|
||||
url: str, size: Optional[str] = None, nginx_url: Optional[str] = None
|
||||
url: str, size: Optional[str] = None, nginx_url: Optional[str] = None
|
||||
):
|
||||
"""
|
||||
说明:
|
||||
@ -422,8 +431,8 @@ def change_pixiv_image_links(
|
||||
if nginx_url:
|
||||
url = (
|
||||
url.replace("i.pximg.net", nginx_url)
|
||||
.replace("i.pixiv.cat", nginx_url)
|
||||
.replace("_webp", "")
|
||||
.replace("i.pixiv.cat", nginx_url)
|
||||
.replace("_webp", "")
|
||||
)
|
||||
return url
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user