mirror of
https://github.com/zhenxun-org/zhenxun_bot.git
synced 2026-09-29 00:32:06 +08:00
update v0.0.9.0
This commit is contained in:
@@ -145,3 +145,4 @@ Yu-Gi-Oh/
|
||||
search_image/
|
||||
black_word/
|
||||
csgo/
|
||||
fantasy_card/
|
||||
|
||||
@@ -221,7 +221,26 @@ python bot.py
|
||||
|
||||
## 更新
|
||||
|
||||
### 2021/1/5 \[v0.0.7.2]
|
||||
### 2021/1/16 \[v0.0.9.0]
|
||||
|
||||
* Ai提供文本敏感词过滤器
|
||||
* 疫情插件适配新版腾讯API
|
||||
* 修复/t回复带空格切分
|
||||
* 修复原神玩家查询缺少渊下宫和稻妻家园以及角色不完全
|
||||
* 修复方法 text2image 中 padding 和 font 无法对纯文本生效
|
||||
* 修复签到图片中信息并未使用配置文件中的色图概率
|
||||
* 修改原神大地图合成方式,改为先压缩再合成
|
||||
* bag_user弃用字段props(该字段会在下次更新删除),使用新字段property
|
||||
* 数据库中所有belonging_group统一修改为group_id
|
||||
* 商店将registered_use和register_goods更名为register_use何register_goods
|
||||
* 商品注册提供了kwargs参数提供:
|
||||
* bot
|
||||
* event
|
||||
* 特殊字段
|
||||
* “send_success_msg”(发送成功的交互信息->即:使用道具 {name} {num} 次成功)
|
||||
* “_max_num_limit”(该道具单次使用的最多个数,默认1)
|
||||
|
||||
### 2021/1/5 \[v0.0.8.3]
|
||||
|
||||
* 提供金币消费hook,可在plugins2settings.yaml中配置该功能需要消费的金币
|
||||
* 商店插件将作为内置插件移动至basic_plugins
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
__version__: v0.0.8.0
|
||||
__version__: v0.0.8.1
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from nonebot import on_command
|
||||
from utils.utils import get_message_text, get_message_imgs
|
||||
from utils.utils import get_message_text, get_message_img
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent
|
||||
from .data_source import custom_group_welcome
|
||||
@@ -38,7 +38,7 @@ custom_welcome = on_command(
|
||||
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
|
||||
try:
|
||||
msg = get_message_text(event.json())
|
||||
imgs = get_message_imgs(event.json())
|
||||
imgs = get_message_img(event.json())
|
||||
if not msg and not imgs:
|
||||
await custom_welcome.finish(__plugin_usage__)
|
||||
await custom_welcome.send(
|
||||
|
||||
@@ -3,7 +3,7 @@ from nonebot.typing import T_State
|
||||
from nonebot.adapters import Bot, Event
|
||||
from nonebot.permission import SUPERUSER
|
||||
import asyncio
|
||||
from utils.utils import get_message_text, get_message_imgs
|
||||
from utils.utils import get_message_text, get_message_img
|
||||
from services.log import logger
|
||||
from utils.message_builder import image
|
||||
from utils.manager import group_manager
|
||||
@@ -35,7 +35,7 @@ broadcast = on_command("广播-", priority=1, permission=SUPERUSER, block=True)
|
||||
@broadcast.handle()
|
||||
async def _(bot: Bot, event: Event, state: T_State):
|
||||
msg = get_message_text(event.json())
|
||||
imgs = get_message_imgs(event.json())
|
||||
imgs = get_message_img(event.json())
|
||||
rst = ""
|
||||
for img in imgs:
|
||||
rst += image(img)
|
||||
|
||||
@@ -111,7 +111,7 @@ def _create_help_img(
|
||||
logger.warning(f"{type(e)}: {e}")
|
||||
else:
|
||||
matchers_data[plugin_type][plugin_name] = {
|
||||
"module": matcher.module,
|
||||
"modules": matcher.module,
|
||||
"des": plugin_des,
|
||||
"cmd": plugin_cmd,
|
||||
"text_type": text_type,
|
||||
@@ -147,16 +147,16 @@ def _create_help_img(
|
||||
# 禁用flag
|
||||
flag = True
|
||||
if plugins_manager.get_plugin_status(
|
||||
matchers_data[type_][k]["module"], "all"
|
||||
matchers_data[type_][k]["modules"], "all"
|
||||
):
|
||||
flag = False
|
||||
if group_id:
|
||||
flag = flag and plugins_manager.get_plugin_status(
|
||||
matchers_data[type_][k]["module"], "group"
|
||||
matchers_data[type_][k]["modules"], "group"
|
||||
)
|
||||
simple_help_str += (
|
||||
f"{i+1}.{k}<|_|~|>"
|
||||
f"{group_manager.get_plugin_status(matchers_data[type_][k]['module'], group_id) if group_id else '_'}|"
|
||||
f"{group_manager.get_plugin_status(matchers_data[type_][k]['modules'], group_id) if group_id else '_'}|"
|
||||
f"{flag}\n"
|
||||
)
|
||||
if matchers_data[type_][k]["text_type"] == 1:
|
||||
|
||||
@@ -260,34 +260,6 @@ async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
|
||||
# 以下为限制检测 #######################################################
|
||||
# 以下为限制检测 #######################################################
|
||||
# 以下为限制检测 #######################################################
|
||||
|
||||
# Cd
|
||||
if plugins2cd_manager.check_plugin_cd_status(module):
|
||||
plugin_cd_data = plugins2cd_manager.get_plugin_cd_data(module)
|
||||
check_type = plugin_cd_data["check_type"]
|
||||
limit_type = plugin_cd_data["limit_type"]
|
||||
rst = plugin_cd_data["rst"]
|
||||
if (
|
||||
(isinstance(event, PrivateMessageEvent) and check_type == "private")
|
||||
or (isinstance(event, GroupMessageEvent) and check_type == "group")
|
||||
or plugins2cd_manager.get_plugin_data(module).get("check_type") == "all"
|
||||
):
|
||||
cd_type_ = event.user_id
|
||||
if limit_type == "group" and isinstance(event, GroupMessageEvent):
|
||||
cd_type_ = event.group_id
|
||||
if not plugins2cd_manager.check(module, cd_type_):
|
||||
if rst:
|
||||
rst = await init_rst(rst, event)
|
||||
await send_msg(rst, bot, event)
|
||||
raise IgnoredException(f"{module} 正在cd中...")
|
||||
else:
|
||||
plugins2cd_manager.start_cd(module, cd_type_)
|
||||
module = matcher.module
|
||||
if (
|
||||
isinstance(event, GroupMessageEvent)
|
||||
and status_message_manager.get(event.group_id) is None
|
||||
):
|
||||
status_message_manager.delete(event.group_id)
|
||||
# Cd
|
||||
if plugins2cd_manager.check_plugin_cd_status(module):
|
||||
plugin_cd_data = plugins2cd_manager.get_plugin_cd_data(module)
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
from asyncpg.exceptions import (
|
||||
DuplicateColumnError,
|
||||
UndefinedColumnError,
|
||||
PostgresSyntaxError,
|
||||
)
|
||||
from nonebot import Driver
|
||||
from services.db_context import db
|
||||
from asyncpg.exceptions import DuplicateColumnError
|
||||
from models.group_info import GroupInfo
|
||||
from models.bag_user import BagUser
|
||||
from nonebot.adapters.cqhttp import Bot
|
||||
from services.log import logger
|
||||
from configs.path_config import TEXT_PATH
|
||||
from asyncio.exceptions import TimeoutError
|
||||
from typing import List
|
||||
from utils.http_utils import AsyncHttpx
|
||||
from utils.utils import scheduler
|
||||
from pathlib import Path
|
||||
@@ -61,15 +67,70 @@ async def _():
|
||||
"""
|
||||
数据库表结构变换
|
||||
"""
|
||||
_flag = []
|
||||
sql_str = [
|
||||
"ALTER TABLE group_info ADD group_flag Integer NOT NULL DEFAULT 0;" # group_info表添加一个group_flag
|
||||
(
|
||||
"ALTER TABLE group_info ADD group_flag Integer NOT NULL DEFAULT 0;",
|
||||
"group_info",
|
||||
), # group_info表添加一个group_flag
|
||||
(
|
||||
"ALTER TABLE bag_users rename belonging_group To group_id;",
|
||||
"bag_users",
|
||||
), # 将 bag_users 的 belonging_group 改为 group_id
|
||||
(
|
||||
"ALTER TABLE group_info_users rename belonging_group To group_id;",
|
||||
"group_info_users",
|
||||
),
|
||||
(
|
||||
"ALTER TABLE sign_group_users rename belonging_group To group_id;",
|
||||
"sign_group_users",
|
||||
),
|
||||
(
|
||||
"ALTER TABLE open_cases_users rename belonging_group To group_id;",
|
||||
"open_cases_users",
|
||||
),
|
||||
(
|
||||
"ALTER TABLE bag_users ADD property json NOT NULL DEFAULT '{}';",
|
||||
"bag_users",
|
||||
), # bag_users 新增字段 property 替代 props
|
||||
]
|
||||
for sql in sql_str:
|
||||
try:
|
||||
flag = sql[1]
|
||||
sql = sql[0]
|
||||
query = db.text(sql)
|
||||
await db.first(query)
|
||||
except DuplicateColumnError:
|
||||
logger.info(f"完成sql操作:{sql}")
|
||||
_flag.append(flag)
|
||||
except (DuplicateColumnError, UndefinedColumnError):
|
||||
pass
|
||||
except PostgresSyntaxError:
|
||||
logger.error(f"语法错误:执行sql失败:{sql}")
|
||||
# bag_user 将文本转为字典格式
|
||||
await __database_script(_flag)
|
||||
|
||||
# 完成后
|
||||
end_sql_str = [
|
||||
# "ALTER TABLE bag_users DROP COLUMN props;" # 删除 bag_users 的 props 字段(还不到时候)
|
||||
]
|
||||
for sql in end_sql_str:
|
||||
try:
|
||||
query = db.text(sql)
|
||||
await db.first(query)
|
||||
logger.info(f"完成执行sql操作:{sql}")
|
||||
except (DuplicateColumnError, UndefinedColumnError):
|
||||
pass
|
||||
except PostgresSyntaxError:
|
||||
logger.error(f"语法错误:执行sql失败:{sql}")
|
||||
|
||||
# str2json_sql = ["alter table bag_users alter COLUMN props type json USING props::json;"] # 字段类型替换
|
||||
# rename_sql = 'alter table {} rename {} to {};' # 字段更名
|
||||
# for sql in str2json_sql:
|
||||
# try:
|
||||
# query = db.text(sql)
|
||||
# await db.first(query)
|
||||
# except DuplicateColumnError:
|
||||
# pass
|
||||
|
||||
|
||||
@driver.on_bot_connect
|
||||
@@ -105,6 +166,26 @@ async def _(bot: Bot):
|
||||
logger.info(f"移除不存在的群聊信息:{group_id}")
|
||||
|
||||
|
||||
async def __database_script(_flag: List[str]):
|
||||
# bag_user 将文本转为字典格式
|
||||
if "bag_users" in _flag:
|
||||
for x in await BagUser.get_all_users():
|
||||
props = {}
|
||||
if x.props:
|
||||
for prop in [p for p in x.props.split(",") if p]:
|
||||
if props.get(prop):
|
||||
props[prop] += 1
|
||||
else:
|
||||
props[prop] = 1
|
||||
logger.info(
|
||||
f"__database_script USER {x.user_qq} GROUP {x.group_id} 更新数据 {props}"
|
||||
)
|
||||
await x.update(
|
||||
property=props,
|
||||
props="",
|
||||
).apply()
|
||||
|
||||
|
||||
# 自动更新城市列表
|
||||
@scheduler.scheduled_job(
|
||||
"cron",
|
||||
|
||||
@@ -29,6 +29,9 @@ __plugin_settings__ = {
|
||||
"limit_superuser": False,
|
||||
"cmd": ["商店", "购买道具"],
|
||||
}
|
||||
__plugin_cd_limit__ = {
|
||||
"cd": 3
|
||||
}
|
||||
|
||||
|
||||
buy = on_command("购买", aliases={"购买道具"}, priority=5, block=True, permission=GROUP)
|
||||
@@ -69,7 +72,7 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
|
||||
await BagUser.get_gold(event.user_id, event.group_id)
|
||||
) < goods.goods_price * num * goods.goods_discount:
|
||||
await buy.finish("您的金币好像不太够哦", at_sender=True)
|
||||
if await BagUser.buy_props(event.user_id, event.group_id, goods, num):
|
||||
if await BagUser.buy_property(event.user_id, event.group_id, goods, num):
|
||||
await buy.send(
|
||||
f"花费 {goods.goods_price * num * goods.goods_discount} 金币购买 {goods.goods_name} ×{num} 成功!",
|
||||
at_sender=True,
|
||||
|
||||
@@ -34,7 +34,7 @@ gold_rank = on_command("金币排行", priority=5, block=True, permission=GROUP)
|
||||
|
||||
@my_gold.handle()
|
||||
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
|
||||
await my_gold.finish(await BagUser.get_my_total_gold(event.user_id, event.group_id))
|
||||
await my_gold.finish(await BagUser.get_user_total_gold(event.user_id, event.group_id))
|
||||
|
||||
|
||||
@gold_rank.handle()
|
||||
|
||||
@@ -31,21 +31,11 @@ my_props = on_command("我的道具", priority=5, block=True, permission=GROUP)
|
||||
|
||||
@my_props.handle()
|
||||
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
|
||||
props = await BagUser.get_props(event.user_id, event.group_id)
|
||||
props = await BagUser.get_property(event.user_id, event.group_id)
|
||||
if props:
|
||||
pname_list = []
|
||||
pnum_list = []
|
||||
rst = ""
|
||||
props = props[:-1].split(",")
|
||||
for p in props:
|
||||
if p != "":
|
||||
if p in pname_list:
|
||||
pnum_list[pname_list.index(p)] += 1
|
||||
else:
|
||||
pname_list.append(p)
|
||||
pnum_list.append(1)
|
||||
for i in range(len(pname_list)):
|
||||
rst += f"{i+1}.{pname_list[i]}\t×{pnum_list[i]}\n"
|
||||
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:
|
||||
|
||||
@@ -3,7 +3,7 @@ from nonebot.adapters.cqhttp import Bot, GroupMessageEvent, MessageEvent
|
||||
from nonebot.typing import T_State
|
||||
from configs.path_config import IMAGE_PATH
|
||||
from utils.message_builder import image
|
||||
from .data_source import create_shop_help, delete_goods, update_goods, registered_goods, parse_goods_info
|
||||
from .data_source import create_shop_help, delete_goods, update_goods, register_goods, parse_goods_info
|
||||
from nonebot.permission import SUPERUSER
|
||||
from utils.utils import get_message_text, is_number
|
||||
from nonebot.plugin import export
|
||||
@@ -53,7 +53,7 @@ __plugin_block_limit__ = {
|
||||
|
||||
# 导出方法供其他插件使用
|
||||
export = export()
|
||||
export.registered_goods = registered_goods
|
||||
export.register_goods = register_goods
|
||||
export.delete_goods = delete_goods
|
||||
export.update_goods = update_goods
|
||||
|
||||
@@ -80,7 +80,7 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
await shop_add_goods.finish(data)
|
||||
if not data.get("name") or not data.get("price") or not data.get("des"):
|
||||
await shop_add_goods.finish("name:price:des 参数不可缺少!")
|
||||
if await registered_goods(**data):
|
||||
if await register_goods(**data):
|
||||
await shop_add_goods.send(f"添加商品 {data['name']} 成功!\n"
|
||||
f"名称:{data['name']}\n"
|
||||
f"价格:{data['price']}金币\n"
|
||||
|
||||
@@ -20,36 +20,24 @@ async def init_default_shop_goods():
|
||||
"""
|
||||
导入内置的三个商品
|
||||
"""
|
||||
|
||||
async def sign_card_1(**kwargs):
|
||||
async def sign_card(**kwargs):
|
||||
user_id = kwargs['user_id']
|
||||
group_id = kwargs['group_id']
|
||||
prob = kwargs["prob"]
|
||||
user = await SignGroupUser.ensure(user_id, group_id)
|
||||
await user.update(add_probability=0.1).apply()
|
||||
|
||||
async def sign_card_2(**kwargs):
|
||||
user_id = kwargs['user_id']
|
||||
group_id = kwargs['group_id']
|
||||
user = await SignGroupUser.ensure(user_id, group_id)
|
||||
await user.update(add_probability=0.2).apply()
|
||||
|
||||
async def sign_card_3(**kwargs):
|
||||
user_id = kwargs['user_id']
|
||||
group_id = kwargs['group_id']
|
||||
user = await SignGroupUser.ensure(user_id, group_id)
|
||||
await user.update(add_probability=0.3).apply()
|
||||
await user.update(add_probability=prob).apply()
|
||||
|
||||
if Config.get_config("shop", "IMPORT_DEFAULT_SHOP_GOODS"):
|
||||
await registered_goods(
|
||||
await register_goods(
|
||||
"好感度双倍加持卡Ⅰ", 30, "下次签到双倍好感度概率 + 10%(谁才是真命天子?)(同类商品将覆盖)"
|
||||
)
|
||||
use.registered_use("好感度双倍加持卡Ⅰ", sign_card_1)
|
||||
await registered_goods("好感度双倍加持卡Ⅱ", 150, "下次签到双倍好感度概率 + 20%(平平庸庸)(同类商品将覆盖)")
|
||||
use.registered_use("好感度双倍加持卡Ⅱ", sign_card_2)
|
||||
await registered_goods(
|
||||
use.register_use("好感度双倍加持卡Ⅰ", sign_card, **{"prob": 0.1})
|
||||
await register_goods("好感度双倍加持卡Ⅱ", 150, "下次签到双倍好感度概率 + 20%(平平庸庸)(同类商品将覆盖)")
|
||||
use.register_use("好感度双倍加持卡Ⅱ", sign_card, **{"prob": 0.2})
|
||||
await register_goods(
|
||||
"好感度双倍加持卡Ⅲ", 250, "下次签到双倍好感度概率 + 30%(金币才是真命天子!)(同类商品将覆盖)"
|
||||
)
|
||||
use.registered_use("好感度双倍加持卡Ⅲ", sign_card_3)
|
||||
use.register_use("好感度双倍加持卡Ⅲ", sign_card, **{"prob": 0.3})
|
||||
|
||||
|
||||
# 创建商店界面
|
||||
@@ -136,7 +124,7 @@ async def create_shop_help() -> str:
|
||||
return shop.pic2bs4()
|
||||
|
||||
|
||||
async def registered_goods(
|
||||
async def register_goods(
|
||||
name: str,
|
||||
price: int,
|
||||
des: str,
|
||||
|
||||
@@ -7,7 +7,7 @@ from models.bag_user import BagUser
|
||||
from nonebot.adapters.cqhttp.permission import GROUP
|
||||
from services.db_context import db
|
||||
from nonebot.plugin import export
|
||||
from .data_source import effect, registered_use
|
||||
from .data_source import effect, register_use, func_manager
|
||||
|
||||
|
||||
__zx_plugin_name__ = "商店 - 使用道具"
|
||||
@@ -15,7 +15,7 @@ __plugin_usage__ = """
|
||||
usage:
|
||||
普通的使用道具
|
||||
指令:
|
||||
使用道具 [序号或道具名称]
|
||||
使用道具 [序号或道具名称] ?[数量]=1
|
||||
* 序号以 ”我的道具“ 为准 *
|
||||
""".strip()
|
||||
__plugin_des__ = "商店 - 使用道具"
|
||||
@@ -32,7 +32,7 @@ __plugin_settings__ = {
|
||||
|
||||
# 导出方法供其他插件使用
|
||||
export = export()
|
||||
export.registered_use = registered_use
|
||||
export.register_use = register_use
|
||||
|
||||
use_props = on_command("使用道具", priority=5, block=True, permission=GROUP)
|
||||
|
||||
@@ -42,35 +42,40 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
|
||||
msg = get_message_text(event.json())
|
||||
if msg in ["", "帮助"]:
|
||||
await use_props.finish(__plugin_usage__)
|
||||
props = await BagUser.get_props(event.user_id, event.group_id)
|
||||
if props:
|
||||
num = 1
|
||||
msg_sp = msg.split()
|
||||
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)
|
||||
if property_:
|
||||
async with db.transaction():
|
||||
pname_list = []
|
||||
props = props[:-1].split(",")
|
||||
for p in props:
|
||||
if p != "":
|
||||
if p not in pname_list:
|
||||
pname_list.append(p)
|
||||
if is_number(msg):
|
||||
if 0 < int(msg) <= len(pname_list):
|
||||
name = pname_list[int(msg) - 1]
|
||||
if 0 < int(msg) <= len(property_):
|
||||
name = list(property_.keys())[int(msg) - 1]
|
||||
else:
|
||||
await use_props.finish("仔细看看自己的道具仓库有没有这个道具?", at_sender=True)
|
||||
else:
|
||||
if msg not in pname_list:
|
||||
if msg not in property_.keys():
|
||||
await use_props.finish("道具名称错误!", at_sender=True)
|
||||
name = msg
|
||||
if await BagUser.del_props(
|
||||
event.user_id, event.group_id, name
|
||||
) and await effect(event.user_id, event.group_id, name):
|
||||
await use_props.send(f"使用道具 {name} 成功!", at_sender=True)
|
||||
_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} 个!")
|
||||
if await BagUser.delete_property(
|
||||
event.user_id, event.group_id, name, num
|
||||
) and await effect(bot, event, name, num):
|
||||
if func_manager.check_send_success_message(name):
|
||||
await use_props.send(f"使用道具 {name} {num} 次成功!", at_sender=True)
|
||||
logger.info(
|
||||
f"USER {event.user_id} GROUP {event.group_id} 使用道具 {name} 成功"
|
||||
f"USER {event.user_id} GROUP {event.group_id} 使用道具 {name} {num} 次成功"
|
||||
)
|
||||
else:
|
||||
await use_props.send(f"使用道具 {name} 失败!", at_sender=True)
|
||||
await use_props.send(f"使用道具 {name} {num} 次失败!", at_sender=True)
|
||||
logger.info(
|
||||
f"USER {event.user_id} GROUP {event.group_id} 使用道具 {name} 失败"
|
||||
f"USER {event.user_id} GROUP {event.group_id} 使用道具 {name} {num} 次失败"
|
||||
)
|
||||
else:
|
||||
await use_props.send("您的背包里没有任何的道具噢~", at_sender=True)
|
||||
await use_props.send("您的背包里没有任何的道具噢", at_sender=True)
|
||||
|
||||
@@ -1,45 +1,119 @@
|
||||
import asyncio
|
||||
from nonebot.adapters.cqhttp import GroupMessageEvent
|
||||
from services.log import logger
|
||||
|
||||
_use_func_data = {}
|
||||
from nonebot.adapters.cqhttp import Bot
|
||||
import asyncio
|
||||
|
||||
|
||||
async def effect(user_id: int, group_id: int, goods_name: str) -> bool:
|
||||
class GoodsUseFuncManager:
|
||||
def __init__(self):
|
||||
self._data = {}
|
||||
|
||||
def register_use(self, goods_name: str, **kwargs):
|
||||
"""
|
||||
注册商品使用方法
|
||||
:param goods_name: 商品名称
|
||||
:param kwargs: kwargs
|
||||
"""
|
||||
self._data[goods_name] = kwargs
|
||||
|
||||
def exists(self, goods_name: str) -> bool:
|
||||
"""
|
||||
判断商品使用方法是否被注册
|
||||
:param goods_name: 商品名称
|
||||
"""
|
||||
return bool(self._data.get(goods_name))
|
||||
|
||||
def get_max_num_limit(self, goods_name: str) -> int:
|
||||
"""
|
||||
获取单次商品使用数量
|
||||
:param goods_name: 商品名称
|
||||
"""
|
||||
if self.exists(goods_name):
|
||||
return self._data[goods_name]["kwargs"]["_max_num_limit"]
|
||||
return 1
|
||||
|
||||
async def use(self, **kwargs):
|
||||
"""
|
||||
使用道具
|
||||
:param kwargs: kwargs
|
||||
"""
|
||||
goods_name = kwargs.get("goods_name")
|
||||
if self.exists(goods_name):
|
||||
if asyncio.iscoroutinefunction(self._data[goods_name]["func"]):
|
||||
await self._data[goods_name]["func"](
|
||||
**kwargs,
|
||||
)
|
||||
else:
|
||||
self._data[goods_name]["func"](
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
def check_send_success_message(self, goods_name: str) -> bool:
|
||||
"""
|
||||
检查是否发送使用成功信息
|
||||
:param goods_name: 商品名称
|
||||
"""
|
||||
if self.exists(goods_name):
|
||||
return bool(self._data[goods_name]["kwargs"]["send_success_msg"])
|
||||
return False
|
||||
|
||||
def get_kwargs(self, goods_name: str) -> dict:
|
||||
"""
|
||||
获取商品使用方法的kwargs
|
||||
:param goods_name: 商品名称
|
||||
"""
|
||||
if self.exists(goods_name):
|
||||
return self._data[goods_name]["kwargs"]
|
||||
return {}
|
||||
|
||||
|
||||
func_manager = GoodsUseFuncManager()
|
||||
|
||||
|
||||
async def effect(bot: Bot, event: GroupMessageEvent, goods_name: str, num: int) -> bool:
|
||||
"""
|
||||
商品生效
|
||||
:param user_id: 用户id
|
||||
:param group_id: 群号
|
||||
:param bot: Bot
|
||||
:param event: GroupMessageEvent
|
||||
:param goods_name: 商品名称
|
||||
:param num: 使用数量
|
||||
:return: 使用是否成功
|
||||
"""
|
||||
# 优先使用注册的商品插件
|
||||
try:
|
||||
if _use_func_data.get(goods_name):
|
||||
_kwargs = _use_func_data[goods_name]["kwargs"]
|
||||
_kwargs["goods_name"] = goods_name
|
||||
_kwargs["user_id"] = user_id
|
||||
_kwargs["group_id"] = group_id
|
||||
if asyncio.iscoroutinefunction(_use_func_data[goods_name]["func"]):
|
||||
await _use_func_data[goods_name]["func"](
|
||||
if func_manager.exists(goods_name):
|
||||
_kwargs = func_manager.get_kwargs(goods_name)
|
||||
await func_manager.use(
|
||||
**{
|
||||
**_kwargs,
|
||||
)
|
||||
else:
|
||||
_use_func_data[goods_name]["func"](
|
||||
**_kwargs,
|
||||
)
|
||||
"_bot": bot,
|
||||
"event": event,
|
||||
"group_id": event.group_id,
|
||||
"user_id": event.user_id,
|
||||
"num": num,
|
||||
"goods_name": goods_name,
|
||||
}
|
||||
)
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"use 商品生效函数effect 发生错误 {type(e)}:{e}")
|
||||
return False
|
||||
|
||||
|
||||
def registered_use(goods_name: str, func, **kwargs):
|
||||
def register_use(goods_name: str, func, **kwargs):
|
||||
"""
|
||||
注册商品使用方法
|
||||
:param goods_name: 商品名称
|
||||
:param func: 使用函数
|
||||
:param kwargs: kwargs
|
||||
"""
|
||||
if goods_name in _use_func_data.keys():
|
||||
if func_manager.exists(goods_name):
|
||||
raise ValueError("该商品使用函数已被注册!")
|
||||
_use_func_data[goods_name] = {"func": func, "kwargs": kwargs}
|
||||
# 发送使用成功信息
|
||||
if kwargs.get("send_success_msg") is None:
|
||||
kwargs["send_success_msg"] = True
|
||||
kwargs["_max_num_limit"] = (
|
||||
kwargs.get("_max_num_limit") if kwargs.get("_max_num_limit") else 1
|
||||
)
|
||||
func_manager.register_use(goods_name, **{"func": func, "kwargs": kwargs})
|
||||
logger.info(f"register_use 成功注册商品:{goods_name} 的使用函数")
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 772 KiB |
+59
-74
@@ -1,4 +1,5 @@
|
||||
from services.db_context import db
|
||||
from typing import Dict
|
||||
from typing import Optional, List
|
||||
from services.log import logger
|
||||
|
||||
@@ -7,33 +8,32 @@ class BagUser(db.Model):
|
||||
__tablename__ = "bag_users"
|
||||
id = db.Column(db.Integer(), primary_key=True)
|
||||
user_qq = db.Column(db.BigInteger(), nullable=False)
|
||||
belonging_group = db.Column(db.BigInteger(), nullable=False)
|
||||
group_id = db.Column(db.BigInteger(), nullable=False)
|
||||
gold = db.Column(db.Integer(), default=100)
|
||||
props = db.Column(db.TEXT(), nullable=False, default="")
|
||||
props = db.Column(db.TEXT(), nullable=False, default="") # 旧道具字段(废弃)
|
||||
spend_total_gold = db.Column(db.Integer(), default=0)
|
||||
get_total_gold = db.Column(db.Integer(), default=0)
|
||||
get_today_gold = db.Column(db.Integer(), default=0)
|
||||
spend_today_gold = db.Column(db.Integer(), default=0)
|
||||
property = db.Column(db.JSON(), nullable=False, default={}) # 新道具字段
|
||||
|
||||
_idx1 = db.Index("bag_group_users_idx1", "user_qq", "belonging_group", unique=True)
|
||||
_idx1 = db.Index("bag_group_users_idx1", "user_qq", "group_id", unique=True)
|
||||
|
||||
@classmethod
|
||||
async def get_my_total_gold(cls, user_qq: int, belonging_group: int) -> str:
|
||||
async def get_user_total_gold(cls, user_qq: int, group_id: int) -> str:
|
||||
"""
|
||||
说明:
|
||||
获取金币概况
|
||||
参数:
|
||||
:param user_qq: qq号
|
||||
:param belonging_group: 所在群号
|
||||
:param group_id: 所在群号
|
||||
"""
|
||||
query = cls.query.where(
|
||||
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||
)
|
||||
query = cls.query.where((cls.user_qq == user_qq) & (cls.group_id == group_id))
|
||||
user = await query.gino.first()
|
||||
if not user:
|
||||
user = await cls.create(
|
||||
user_qq=user_qq,
|
||||
belonging_group=belonging_group,
|
||||
group_id=group_id,
|
||||
)
|
||||
return (
|
||||
f"当前金币:{user.gold}\n今日获取金币:{user.get_today_gold}\n今日花费金币:{user.spend_today_gold}"
|
||||
@@ -42,62 +42,56 @@ class BagUser(db.Model):
|
||||
)
|
||||
|
||||
@classmethod
|
||||
async def get_gold(cls, user_qq: int, belonging_group: int) -> int:
|
||||
async def get_gold(cls, user_qq: int, group_id: int) -> int:
|
||||
"""
|
||||
说明:
|
||||
获取当前金币
|
||||
参数:
|
||||
:param user_qq: qq号
|
||||
:param belonging_group: 所在群号
|
||||
:param group_id: 所在群号
|
||||
"""
|
||||
query = cls.query.where(
|
||||
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||
)
|
||||
query = cls.query.where((cls.user_qq == user_qq) & (cls.group_id == group_id))
|
||||
user = await query.gino.first()
|
||||
if user:
|
||||
return user.gold
|
||||
else:
|
||||
await cls.create(
|
||||
user_qq=user_qq,
|
||||
belonging_group=belonging_group,
|
||||
group_id=group_id,
|
||||
)
|
||||
return 100
|
||||
|
||||
@classmethod
|
||||
async def get_props(cls, user_qq: int, belonging_group: int) -> str:
|
||||
async def get_property(cls, user_qq: int, group_id: int) -> Dict[str, int]:
|
||||
"""
|
||||
说明:
|
||||
获取当前道具
|
||||
参数:
|
||||
:param user_qq: qq号
|
||||
:param belonging_group: 所在群号
|
||||
:param group_id: 所在群号
|
||||
"""
|
||||
query = cls.query.where(
|
||||
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||
)
|
||||
query = cls.query.where((cls.user_qq == user_qq) & (cls.group_id == group_id))
|
||||
user = await query.gino.first()
|
||||
if user:
|
||||
return user.props
|
||||
return user.property
|
||||
else:
|
||||
await cls.create(
|
||||
user_qq=user_qq,
|
||||
belonging_group=belonging_group,
|
||||
group_id=group_id,
|
||||
)
|
||||
return ""
|
||||
return {}
|
||||
|
||||
@classmethod
|
||||
async def add_gold(cls, user_qq: int, belonging_group: int, num: int):
|
||||
async def add_gold(cls, user_qq: int, group_id: int, num: int):
|
||||
"""
|
||||
说明:
|
||||
增加金币
|
||||
参数:
|
||||
:param user_qq: qq号
|
||||
:param belonging_group: 所在群号
|
||||
:param group_id: 所在群号
|
||||
:param num: 金币数量
|
||||
"""
|
||||
query = cls.query.where(
|
||||
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||
)
|
||||
query = cls.query.where((cls.user_qq == user_qq) & (cls.group_id == group_id))
|
||||
query = query.with_for_update()
|
||||
user = await query.gino.first()
|
||||
if user:
|
||||
@@ -109,25 +103,23 @@ class BagUser(db.Model):
|
||||
else:
|
||||
await cls.create(
|
||||
user_qq=user_qq,
|
||||
belonging_group=belonging_group,
|
||||
group_id=group_id,
|
||||
gold=100 + num,
|
||||
get_total_gold=num,
|
||||
get_today_gold=num,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
async def spend_gold(cls, user_qq: int, belonging_group: int, num: int):
|
||||
async def spend_gold(cls, user_qq: int, group_id: int, num: int):
|
||||
"""
|
||||
说明:
|
||||
花费金币
|
||||
参数:
|
||||
:param user_qq: qq号
|
||||
:param belonging_group: 所在群号
|
||||
:param group_id: 所在群号
|
||||
:param num: 金币数量
|
||||
"""
|
||||
query = cls.query.where(
|
||||
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||
)
|
||||
query = cls.query.where((cls.user_qq == user_qq) & (cls.group_id == group_id))
|
||||
query = query.with_for_update()
|
||||
user = await query.gino.first()
|
||||
if user:
|
||||
@@ -139,91 +131,84 @@ class BagUser(db.Model):
|
||||
else:
|
||||
await cls.create(
|
||||
user_qq=user_qq,
|
||||
belonging_group=belonging_group,
|
||||
group_id=group_id,
|
||||
gold=100 - num,
|
||||
spend_total_gold=num,
|
||||
spend_today_gold=num,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
async def add_props(cls, user_qq: int, belonging_group: int, name: str):
|
||||
async def add_property(cls, user_qq: int, group_id: int, name: str):
|
||||
"""
|
||||
说明:
|
||||
增加道具
|
||||
参数:
|
||||
:param user_qq: qq号
|
||||
:param belonging_group: 所在群号
|
||||
:param group_id: 所在群号
|
||||
:param name: 道具名称
|
||||
"""
|
||||
query = cls.query.where(
|
||||
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||
)
|
||||
query = cls.query.where((cls.user_qq == user_qq) & (cls.group_id == group_id))
|
||||
query = query.with_for_update()
|
||||
user = await query.gino.first()
|
||||
if user:
|
||||
await user.update(props=user.props + f"{name},").apply()
|
||||
p = user.property
|
||||
if p.get(name) is None:
|
||||
p[name] = 1
|
||||
else:
|
||||
p[name] += 1
|
||||
await user.update(property=p).apply()
|
||||
else:
|
||||
await cls.create(
|
||||
user_qq=user_qq, belonging_group=belonging_group, props=f"{name},"
|
||||
)
|
||||
await cls.create(user_qq=user_qq, group_id=group_id, property={name: 1})
|
||||
|
||||
@classmethod
|
||||
async def del_props(cls, user_qq: int, belonging_group: int, name: str) -> bool:
|
||||
async def delete_property(
|
||||
cls, user_qq: int, group_id: int, name: str, num: int = 1
|
||||
) -> bool:
|
||||
"""
|
||||
说明:
|
||||
使用道具
|
||||
使用/删除 道具
|
||||
参数:
|
||||
:param user_qq: qq号
|
||||
:param belonging_group: 所在群号
|
||||
:param group_id: 所在群号
|
||||
:param name: 道具名称
|
||||
:param num: 使用个数
|
||||
"""
|
||||
query = cls.query.where(
|
||||
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||
)
|
||||
query = cls.query.where((cls.user_qq == user_qq) & (cls.group_id == group_id))
|
||||
query = query.with_for_update()
|
||||
user = await query.gino.first()
|
||||
if user:
|
||||
rst = ""
|
||||
props = user.props
|
||||
if props.find(name) != -1:
|
||||
props = props.split(",")
|
||||
try:
|
||||
index = props.index(name)
|
||||
except ValueError:
|
||||
return False
|
||||
props = props[:index] + props[index + 1 :]
|
||||
for p in props:
|
||||
if p != "":
|
||||
rst += p + ","
|
||||
await user.update(props=rst).apply()
|
||||
property_ = user.property
|
||||
if name in property_:
|
||||
if property_.get(name) == num:
|
||||
del property_[name]
|
||||
else:
|
||||
property_[name] -= num
|
||||
await user.update(property=property_).apply()
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
return False
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
async def buy_props(
|
||||
cls, user_qq: int, belonging_group: int, goods: "GoodsInfo", goods_num: int
|
||||
async def buy_property(
|
||||
cls, user_qq: int, group_id: int, goods: "GoodsInfo", goods_num: int
|
||||
) -> bool:
|
||||
"""
|
||||
说明:
|
||||
购买道具
|
||||
参数:
|
||||
:param user_qq: 用户qq
|
||||
:param belonging_group: 所在群聊
|
||||
:param group_id: 所在群聊
|
||||
:param goods: 商品
|
||||
:param goods_num: 商品数量
|
||||
"""
|
||||
try:
|
||||
# 折扣后金币
|
||||
spend_gold = goods.goods_discount * goods.goods_price * goods_num
|
||||
await BagUser.spend_gold(user_qq, belonging_group, spend_gold)
|
||||
await BagUser.spend_gold(user_qq, group_id, spend_gold)
|
||||
for _ in range(goods_num):
|
||||
await BagUser.add_props(user_qq, belonging_group, goods.goods_name)
|
||||
await BagUser.add_property(user_qq, group_id, goods.goods_name)
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"buy_props 发生错误 {type(e)}:{e}")
|
||||
logger.error(f"buy_property 发生错误 {type(e)}:{e}")
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
@@ -237,5 +222,5 @@ class BagUser(db.Model):
|
||||
if not group_id:
|
||||
query = await cls.query.gino.all()
|
||||
else:
|
||||
query = await cls.query.where((cls.belonging_group == group_id)).gino.all()
|
||||
query = await cls.query.where((cls.group_id == group_id)).gino.all()
|
||||
return query
|
||||
|
||||
+28
-28
@@ -10,18 +10,18 @@ class GroupInfoUser(db.Model):
|
||||
id = db.Column(db.Integer(), primary_key=True)
|
||||
user_qq = db.Column(db.BigInteger(), nullable=False)
|
||||
user_name = db.Column(db.Unicode(), nullable=False)
|
||||
belonging_group = db.Column(db.BigInteger(), nullable=False)
|
||||
group_id = db.Column(db.BigInteger(), nullable=False)
|
||||
user_join_time = db.Column(db.DateTime(), nullable=False)
|
||||
nickname = db.Column(db.Unicode())
|
||||
uid = db.Column(db.BigInteger())
|
||||
|
||||
_idx1 = db.Index("info_group_users_idx1", "user_qq", "belonging_group", unique=True)
|
||||
_idx1 = db.Index("info_group_users_idx1", "user_qq", "group_id", unique=True)
|
||||
|
||||
@classmethod
|
||||
async def add_member_info(
|
||||
cls,
|
||||
user_qq: int,
|
||||
belonging_group: int,
|
||||
group_id: int,
|
||||
user_name: str,
|
||||
user_join_time: datetime,
|
||||
uid: Optional[int] = None,
|
||||
@@ -31,20 +31,20 @@ class GroupInfoUser(db.Model):
|
||||
添加群内用户信息
|
||||
参数:
|
||||
:param user_qq: qq号
|
||||
:param belonging_group: 群号
|
||||
:param group_id: 群号
|
||||
:param user_name: 用户名称
|
||||
:param user_join_time: 入群时间
|
||||
:param uid: 用户唯一 id(自动生成)
|
||||
"""
|
||||
query = cls.query.where(
|
||||
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||
(cls.user_qq == user_qq) & (cls.group_id == group_id)
|
||||
)
|
||||
try:
|
||||
if not await query.gino.first():
|
||||
await cls.create(
|
||||
user_qq=user_qq,
|
||||
user_name=user_name,
|
||||
belonging_group=belonging_group,
|
||||
group_id=group_id,
|
||||
user_join_time=user_join_time,
|
||||
uid=uid
|
||||
)
|
||||
@@ -54,31 +54,31 @@ class GroupInfoUser(db.Model):
|
||||
|
||||
@classmethod
|
||||
async def get_member_info(
|
||||
cls, user_qq: int, belonging_group: int
|
||||
cls, user_qq: int, group_id: int
|
||||
) -> "GroupInfoUser":
|
||||
"""
|
||||
说明:
|
||||
查询群员信息
|
||||
参数:
|
||||
:param user_qq: qq号
|
||||
:param belonging_group: 群号
|
||||
:param group_id: 群号
|
||||
"""
|
||||
query = cls.query.where(
|
||||
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||
(cls.user_qq == user_qq) & (cls.group_id == group_id)
|
||||
)
|
||||
return await query.gino.first()
|
||||
|
||||
@classmethod
|
||||
async def delete_member_info(cls, user_qq: int, belonging_group: int) -> bool:
|
||||
async def delete_member_info(cls, user_qq: int, group_id: int) -> bool:
|
||||
"""
|
||||
说明:
|
||||
删除群员信息
|
||||
参数:
|
||||
:param user_qq: qq号
|
||||
:param belonging_group: 群号
|
||||
:param group_id: 群号
|
||||
"""
|
||||
query = cls.query.where(
|
||||
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||
(cls.user_qq == user_qq) & (cls.group_id == group_id)
|
||||
)
|
||||
query = query.with_for_update()
|
||||
user = await query.gino.first()
|
||||
@@ -87,40 +87,40 @@ class GroupInfoUser(db.Model):
|
||||
return True
|
||||
else:
|
||||
await cls.delete.where(
|
||||
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||
(cls.user_qq == user_qq) & (cls.group_id == group_id)
|
||||
).gino.status()
|
||||
return True
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
async def get_group_member_id_list(cls, belonging_group: int) -> List[int]:
|
||||
async def get_group_member_id_list(cls, group_id: int) -> List[int]:
|
||||
"""
|
||||
说明:
|
||||
获取该群所有用户qq
|
||||
参数:
|
||||
:param belonging_group: 群号
|
||||
:param group_id: 群号
|
||||
"""
|
||||
member_list = []
|
||||
query = cls.query.where((cls.belonging_group == belonging_group))
|
||||
query = cls.query.where((cls.group_id == group_id))
|
||||
for user in await query.gino.all():
|
||||
member_list.append(user.user_qq)
|
||||
return member_list
|
||||
|
||||
@classmethod
|
||||
async def set_group_member_nickname(
|
||||
cls, user_qq: int, belonging_group: int, nickname: str
|
||||
cls, user_qq: int, group_id: int, nickname: str
|
||||
) -> bool:
|
||||
"""
|
||||
说明:
|
||||
设置群员在该群内的昵称
|
||||
参数:
|
||||
:param user_qq: qq号
|
||||
:param belonging_group: 群号
|
||||
:param group_id: 群号
|
||||
:param nickname: 昵称
|
||||
"""
|
||||
query = cls.query.where(
|
||||
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||
(cls.user_qq == user_qq) & (cls.group_id == group_id)
|
||||
)
|
||||
user = await query.with_for_update().gino.first()
|
||||
if user:
|
||||
@@ -136,20 +136,20 @@ class GroupInfoUser(db.Model):
|
||||
"""
|
||||
query = await cls.query.where(cls.user_qq == user_qq).gino.all()
|
||||
if query:
|
||||
query = [x.belonging_group for x in query]
|
||||
query = [x.group_id for x in query]
|
||||
return query
|
||||
|
||||
@classmethod
|
||||
async def get_group_member_nickname(cls, user_qq: int, belonging_group: int) -> str:
|
||||
async def get_group_member_nickname(cls, user_qq: int, group_id: int) -> str:
|
||||
"""
|
||||
说明:
|
||||
获取用户在该群的昵称
|
||||
参数:
|
||||
:param user_qq: qq号
|
||||
:param belonging_group: 群号
|
||||
:param group_id: 群号
|
||||
"""
|
||||
query = cls.query.where(
|
||||
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||
(cls.user_qq == user_qq) & (cls.group_id == group_id)
|
||||
)
|
||||
user = await query.gino.first()
|
||||
if user:
|
||||
@@ -163,12 +163,12 @@ class GroupInfoUser(db.Model):
|
||||
return ""
|
||||
|
||||
@classmethod
|
||||
async def get_group_member_uid(cls, user_qq: int, belonging_group: int) -> Optional[str]:
|
||||
async def get_group_member_uid(cls, user_qq: int, group_id: int) -> Optional[str]:
|
||||
query = cls.query.where(
|
||||
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||
(cls.user_qq == user_qq) & (cls.group_id == group_id)
|
||||
)
|
||||
user = await query.gino.first()
|
||||
_max_uid = cls.query.where((cls.user_qq == 114514) & (cls.belonging_group == 114514)).with_for_update()
|
||||
_max_uid = cls.query.where((cls.user_qq == 114514) & (cls.group_id == 114514)).with_for_update()
|
||||
_max_uid_user = await _max_uid.gino.first()
|
||||
_max_uid = _max_uid_user.uid
|
||||
if not user or not user.uid:
|
||||
@@ -178,9 +178,9 @@ class GroupInfoUser(db.Model):
|
||||
return x.uid
|
||||
else:
|
||||
if not user:
|
||||
await GroupInfoUser.add_member_info(user_qq, belonging_group, '', datetime.min)
|
||||
await GroupInfoUser.add_member_info(user_qq, group_id, '', datetime.min)
|
||||
user = await cls.query.where(
|
||||
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||
(cls.user_qq == user_qq) & (cls.group_id == group_id)
|
||||
).gino.first()
|
||||
await user.update(
|
||||
uid=_max_uid + 1,
|
||||
|
||||
+11
-12
@@ -8,8 +8,7 @@ class SignGroupUser(db.Model):
|
||||
|
||||
id = db.Column(db.Integer(), primary_key=True)
|
||||
user_qq = db.Column(db.BigInteger(), nullable=False)
|
||||
belonging_group = db.Column(db.BigInteger(), nullable=False)
|
||||
|
||||
group_id = db.Column(db.BigInteger(), nullable=False)
|
||||
checkin_count = db.Column(db.Integer(), nullable=False)
|
||||
checkin_time_last = db.Column(db.DateTime(timezone=True), nullable=False)
|
||||
impression = db.Column(db.Numeric(scale=3, asdecimal=False), nullable=False)
|
||||
@@ -20,29 +19,29 @@ class SignGroupUser(db.Model):
|
||||
db.Numeric(scale=3, asdecimal=False), nullable=False, default=0
|
||||
)
|
||||
|
||||
_idx1 = db.Index("sign_group_users_idx1", "user_qq", "belonging_group", unique=True)
|
||||
_idx1 = db.Index("sign_group_users_idx1", "user_qq", "group_id", unique=True)
|
||||
|
||||
@classmethod
|
||||
async def ensure(
|
||||
cls, user_qq: int, belonging_group: int, for_update: bool = False
|
||||
cls, user_qq: int, group_id: int, for_update: bool = False
|
||||
) -> "SignGroupUser":
|
||||
"""
|
||||
说明:
|
||||
获取签到用户
|
||||
参数:
|
||||
:param user_qq: 用户qq
|
||||
:param belonging_group: 所在群聊
|
||||
:param group_id: 所在群聊
|
||||
:param for_update: 是否存在修改数据
|
||||
"""
|
||||
query = cls.query.where(
|
||||
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||
(cls.user_qq == user_qq) & (cls.group_id == group_id)
|
||||
)
|
||||
if for_update:
|
||||
query = query.with_for_update()
|
||||
user = await query.gino.first()
|
||||
return user or await cls.create(
|
||||
user_qq=user_qq,
|
||||
belonging_group=belonging_group,
|
||||
group_id=group_id,
|
||||
checkin_count=0,
|
||||
checkin_time_last=datetime.min, # 从未签到过
|
||||
impression=0,
|
||||
@@ -79,22 +78,22 @@ class SignGroupUser(db.Model):
|
||||
).apply()
|
||||
|
||||
@classmethod
|
||||
async def get_all_impression(cls, belonging_group: int) -> "list, list, list":
|
||||
async def get_all_impression(cls, group_id: int) -> "list, list, list":
|
||||
"""
|
||||
说明:
|
||||
获取该群所有用户 id 及对应 好感度
|
||||
参数:
|
||||
:param belonging_group: 群号
|
||||
:param group_id: 群号
|
||||
"""
|
||||
impression_list = []
|
||||
user_qq_list = []
|
||||
user_group = []
|
||||
if belonging_group:
|
||||
query = cls.query.where(cls.belonging_group == belonging_group)
|
||||
if group_id:
|
||||
query = cls.query.where(cls.group_id == group_id)
|
||||
else:
|
||||
query = cls.query
|
||||
for user in await query.gino.all():
|
||||
impression_list.append(user.impression)
|
||||
user_qq_list.append(user.user_qq)
|
||||
user_group.append(user.belonging_group)
|
||||
user_group.append(user.group_id)
|
||||
return user_qq_list, impression_list, user_group
|
||||
|
||||
+14
-17
@@ -11,7 +11,7 @@ from nonebot.typing import T_State
|
||||
from models.friend_user import FriendUser
|
||||
from models.group_member_info import GroupInfoUser
|
||||
from services.log import logger
|
||||
from utils.utils import get_message_text, get_message_imgs
|
||||
from utils.utils import get_message_text, get_message_img
|
||||
from .data_source import get_chat_result, hello, no_result
|
||||
from configs.config import NICKNAME, Config
|
||||
|
||||
@@ -21,27 +21,22 @@ usage:
|
||||
与{NICKNAME}普普通通的对话吧!
|
||||
"""
|
||||
__plugin_version__ = 0.1
|
||||
__plugin_author__ = 'HibiKier'
|
||||
__plugin_author__ = "HibiKier"
|
||||
__plugin_settings__ = {
|
||||
"level": 5,
|
||||
"cmd": ["Ai", "ai", "AI", "aI"],
|
||||
}
|
||||
__plugin_configs__ = {
|
||||
"TL_KEY": {
|
||||
"value": [],
|
||||
"help": "图灵Key"
|
||||
"TL_KEY": {"value": [], "help": "图灵Key"},
|
||||
"ALAPI_AI_CHECK": {"value": False, "help": "是否检测青云客骂娘回复", "default_value": False},
|
||||
"TEXT_FILTER": {
|
||||
"value": ["鸡", "口交"],
|
||||
"help": "文本过滤器,将敏感词更改为*",
|
||||
"default_value": [],
|
||||
},
|
||||
"ALAPI_AI_CHECK": {
|
||||
"value": False,
|
||||
"help": "是否检测青云客骂娘回复",
|
||||
"default_value": False
|
||||
}
|
||||
}
|
||||
Config.add_plugin_config(
|
||||
"alapi",
|
||||
"ALAPI_TOKEN",
|
||||
None,
|
||||
help_="在https://admin.alapi.cn/user/login登录后获取token"
|
||||
"alapi", "ALAPI_TOKEN", None, help_="在https://admin.alapi.cn/user/login登录后获取token"
|
||||
)
|
||||
|
||||
ai = on_message(rule=to_me(), priority=8)
|
||||
@@ -50,11 +45,11 @@ ai = on_message(rule=to_me(), priority=8)
|
||||
@ai.handle()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
msg = get_message_text(event.json())
|
||||
imgs = get_message_imgs(event.json())
|
||||
img = get_message_img(event.json())
|
||||
if "CQ:xml" in str(event.get_message()):
|
||||
return
|
||||
# 打招呼
|
||||
if (not msg and not imgs) or msg in [
|
||||
if (not msg and not img) or msg in [
|
||||
"你好啊",
|
||||
"你好",
|
||||
"在吗",
|
||||
@@ -65,7 +60,7 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
"在",
|
||||
]:
|
||||
await ai.finish(hello())
|
||||
img = imgs[0] if imgs else ""
|
||||
img = img[0] if img else ""
|
||||
if isinstance(event, GroupMessageEvent):
|
||||
nickname = await GroupInfoUser.get_group_member_nickname(
|
||||
event.user_id, event.group_id
|
||||
@@ -83,6 +78,8 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
f"问题:{msg} ---- 回答:{result}"
|
||||
)
|
||||
if result:
|
||||
for t in Config.get_config("ai", "TEXT_FILTER"):
|
||||
result = result.replace(t, "*")
|
||||
await ai.finish(Message(result))
|
||||
else:
|
||||
await ai.finish(no_result())
|
||||
|
||||
@@ -9,7 +9,7 @@ from .data_source import (
|
||||
get_media_id,
|
||||
get_sub_status,
|
||||
SubManager,
|
||||
BilibiliSub
|
||||
BilibiliSub,
|
||||
)
|
||||
from models.level_user import LevelUser
|
||||
from configs.config import Config
|
||||
@@ -163,11 +163,10 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
|
||||
@show_sub_info.handle()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
id_ = (
|
||||
f"{event.user_id}:{event.group_id}"
|
||||
if isinstance(event, GroupMessageEvent)
|
||||
else f"{event.user_id}"
|
||||
)
|
||||
if isinstance(event, GroupMessageEvent):
|
||||
id_ = f"{event.group_id}"
|
||||
else:
|
||||
id_ = f"{event.user_id}"
|
||||
data = await BilibiliSub.get_sub_data(id_)
|
||||
live_rst = ""
|
||||
up_rst = ""
|
||||
@@ -181,6 +180,7 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
up_rst += f"\tUP:{x.uname}\n" f"\tuid:{x.uid}\n" f"------------------\n"
|
||||
if x.sub_type == "season":
|
||||
season_rst += (
|
||||
f"\t番剧id:{x.sub_id}\n"
|
||||
f"\t番名:{x.season_name}\n"
|
||||
f"\t当前集数:{x.season_current_episode}\n"
|
||||
f"------------------\n"
|
||||
@@ -189,7 +189,9 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
up_rst = "当前订阅的UP:\n" + up_rst if up_rst else up_rst
|
||||
season_rst = "当前订阅的番剧:\n" + season_rst if season_rst else season_rst
|
||||
if not live_rst and not up_rst and not season_rst:
|
||||
live_rst = "您目前没有任何订阅..."
|
||||
live_rst = (
|
||||
"该群目前没有任何订阅..." if isinstance(event, GroupMessageEvent) else "您目前没有任何订阅..."
|
||||
)
|
||||
await show_sub_info.send(live_rst + up_rst + season_rst)
|
||||
|
||||
|
||||
|
||||
@@ -165,7 +165,9 @@ async def get_media_id(keyword: str) -> dict:
|
||||
for _ in range(3):
|
||||
try:
|
||||
_season_data = {}
|
||||
response = await AsyncHttpx.get(bilibili_search_url, params=params, timeout=5)
|
||||
response = await AsyncHttpx.get(
|
||||
bilibili_search_url, params=params, timeout=5
|
||||
)
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
if data.get("data"):
|
||||
@@ -254,7 +256,12 @@ async def _get_up_status(id_: int) -> Optional[str]:
|
||||
if dynamic_img:
|
||||
await BilibiliSub.update_sub_info(id_, dynamic_upload_time=dynamic_upload_time)
|
||||
rst += f"{uname} 发布了动态!\n" f"{dynamic_img}\n"
|
||||
if _user.latest_video_created < latest_video_created and video:
|
||||
if (
|
||||
latest_video_created
|
||||
and _user.latest_video_created
|
||||
and video
|
||||
and _user.latest_video_created < latest_video_created
|
||||
):
|
||||
rst = rst + "-------------\n" if rst else rst
|
||||
await BilibiliSub.update_sub_info(
|
||||
id_, latest_video_created=latest_video_created
|
||||
|
||||
@@ -2,7 +2,7 @@ from nonebot import on_command
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.adapters.cqhttp import Bot, MessageEvent, Message, GroupMessageEvent
|
||||
from nonebot.permission import SUPERUSER
|
||||
from utils.utils import get_message_text, is_number, get_message_imgs
|
||||
from utils.utils import get_message_text, is_number, get_message_img
|
||||
from utils.message_builder import image
|
||||
from utils.message_builder import text as _text
|
||||
from services.log import logger
|
||||
@@ -63,7 +63,7 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
coffee = int(list(bot.config.superusers)[0])
|
||||
text = get_message_text(event.json())
|
||||
img_msg = _text("")
|
||||
for img in get_message_imgs(event.json()):
|
||||
for img in get_message_img(event.json()):
|
||||
img_msg += image(img)
|
||||
if not text and not img_msg:
|
||||
await dialogue.send("请发送[滴滴滴]+您要说的内容~", at_sender=True)
|
||||
@@ -127,7 +127,7 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
id_ = msg[0]
|
||||
user_id = dialogue_data[id_]["user_id"]
|
||||
group_id = dialogue_data[id_]["group_id"]
|
||||
text = msg[1]
|
||||
text = " ".join(msg[1:])
|
||||
dialogue_data.pop(id_)
|
||||
else:
|
||||
user_id = 0
|
||||
@@ -140,13 +140,13 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
user_id = int(msg[0])
|
||||
if is_number(msg[1]) and len(msg[1]) > 5:
|
||||
group_id = int(msg[1])
|
||||
text = msg[2]
|
||||
text = " ".join(msg[2:])
|
||||
else:
|
||||
group_id = 0
|
||||
text = msg[1]
|
||||
text = " ".join(msg[1:])
|
||||
else:
|
||||
await reply.finish("第一参数,请输入数字.....", at_sender=True)
|
||||
for img in get_message_imgs(event.json()):
|
||||
for img in get_message_img(event.json()):
|
||||
text += image(img)
|
||||
if group_id:
|
||||
if user_id:
|
||||
|
||||
@@ -35,7 +35,7 @@ def is_expired(data: dict):
|
||||
now = datetime.now().date()
|
||||
except ValueError:
|
||||
return False
|
||||
return start_date <= now <= end_date
|
||||
return not start_date <= now <= end_date
|
||||
|
||||
|
||||
# 检查写入
|
||||
@@ -175,7 +175,7 @@ class GenshinAnnouncement:
|
||||
data[itype]['time'] = data[itype]['time'][:-1]
|
||||
if '版本更新后' in data[itype]['time']:
|
||||
sp = data[itype]['time'].split('~')
|
||||
end_time = datetime.strptime(sp[1].strip(), "%Y/%m/%d %H:%M:%S")
|
||||
end_time = datetime.strptime(sp[1].strip(), "%Y/%m/%d %H:%M")
|
||||
start_time = end_time - timedelta(days=20)
|
||||
data[itype]['time'] = start_time.strftime('%Y/%m/%d') + ' ~ ' + end_time.strftime('%Y/%m/%d')
|
||||
tmp = ''
|
||||
|
||||
@@ -2,9 +2,24 @@ import os
|
||||
from nonebot.adapters.cqhttp import MessageSegment, Message
|
||||
import random
|
||||
from .update_game_info import update_info
|
||||
from .util import generate_img, init_star_rst, BaseData, set_list, get_star, init_up_char
|
||||
from .config import GENSHIN_FIVE_P, GENSHIN_FOUR_P, GENSHIN_G_FIVE_P, GENSHIN_G_FOUR_P, GENSHIN_THREE_P, I72_ADD, \
|
||||
DRAW_PATH, GENSHIN_FLAG
|
||||
from .util import (
|
||||
generate_img,
|
||||
init_star_rst,
|
||||
BaseData,
|
||||
set_list,
|
||||
get_star,
|
||||
init_up_char,
|
||||
)
|
||||
from .config import (
|
||||
GENSHIN_FIVE_P,
|
||||
GENSHIN_FOUR_P,
|
||||
GENSHIN_G_FIVE_P,
|
||||
GENSHIN_G_FOUR_P,
|
||||
GENSHIN_THREE_P,
|
||||
I72_ADD,
|
||||
DRAW_PATH,
|
||||
GENSHIN_FLAG,
|
||||
)
|
||||
from dataclasses import dataclass
|
||||
from .init_card_pool import init_game_pool
|
||||
from .announcement import GenshinAnnouncement
|
||||
@@ -27,9 +42,9 @@ ALL_ARMS = []
|
||||
UP_CHAR = []
|
||||
UP_ARMS = []
|
||||
|
||||
_CURRENT_CHAR_POOL_TITLE = ''
|
||||
_CURRENT_ARMS_POOL_TITLE = ''
|
||||
POOL_IMG = ''
|
||||
_CURRENT_CHAR_POOL_TITLE = ""
|
||||
_CURRENT_ARMS_POOL_TITLE = ""
|
||||
POOL_IMG = ""
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -39,19 +54,25 @@ class GenshinChar(BaseData):
|
||||
|
||||
async def genshin_draw(user_id: int, count: int, pool_name: str):
|
||||
# 0 1 2
|
||||
cnlist = ['★★★★★', '★★★★', '★★★']
|
||||
char_list, five_list, five_index_list, char_dict, star_list = _format_card_information(count, user_id, pool_name)
|
||||
temp = ''
|
||||
title = ''
|
||||
cnlist = ["★★★★★", "★★★★", "★★★"]
|
||||
(
|
||||
char_list,
|
||||
five_list,
|
||||
five_index_list,
|
||||
char_dict,
|
||||
star_list,
|
||||
) = _format_card_information(count, user_id, pool_name)
|
||||
temp = ""
|
||||
title = ""
|
||||
up_type = []
|
||||
up_list = []
|
||||
if pool_name == 'char' and _CURRENT_CHAR_POOL_TITLE:
|
||||
if pool_name == "char" and _CURRENT_CHAR_POOL_TITLE:
|
||||
up_type = UP_CHAR
|
||||
title = _CURRENT_CHAR_POOL_TITLE
|
||||
elif pool_name == 'arms' and _CURRENT_ARMS_POOL_TITLE:
|
||||
elif pool_name == "arms" and _CURRENT_ARMS_POOL_TITLE:
|
||||
up_type = UP_ARMS
|
||||
title = _CURRENT_ARMS_POOL_TITLE
|
||||
tmp = ''
|
||||
tmp = ""
|
||||
if up_type:
|
||||
for x in up_type:
|
||||
for operator in x.operators:
|
||||
@@ -61,80 +82,118 @@ async def genshin_draw(user_id: int, count: int, pool_name: str):
|
||||
elif x.star == 4:
|
||||
tmp += f'四星UP:{" ".join(x.operators)}'
|
||||
rst = init_star_rst(star_list, cnlist, five_list, five_index_list, up_list)
|
||||
pool_info = f'当前up池:{title}\n{tmp}' if title else ''
|
||||
pool_info = f"当前up池:{title}\n{tmp}" if title else ""
|
||||
if count > 90:
|
||||
char_list = set_list(char_list)
|
||||
return pool_info + '\n' + MessageSegment.image(
|
||||
"base64://" + await generate_img(char_list, 'genshin', star_list)) + '\n' + rst[:-1] + \
|
||||
temp[:-1] + f'\n距离保底发还剩 {90 - genshin_count[user_id] if genshin_count.get(user_id) else "^"} 抽' \
|
||||
+ "\n【五星:0.6%,四星:5.1%\n第72抽开始五星概率每抽加0.585%】"
|
||||
return (
|
||||
pool_info
|
||||
+ "\n"
|
||||
+ MessageSegment.image(
|
||||
"base64://" + await generate_img(char_list, "genshin", star_list)
|
||||
)
|
||||
+ "\n"
|
||||
+ rst[:-1]
|
||||
+ temp[:-1]
|
||||
+ f'\n距离保底发还剩 {90 - genshin_count[user_id] if genshin_count.get(user_id) else "^"} 抽'
|
||||
+ "\n【五星:0.6%,四星:5.1%\n第72抽开始五星概率每抽加0.585%】"
|
||||
)
|
||||
|
||||
|
||||
async def update_genshin_info():
|
||||
global ALL_CHAR, ALL_ARMS
|
||||
url = 'https://wiki.biligame.com/ys/角色筛选'
|
||||
data, code = await update_info(url, 'genshin')
|
||||
url = "https://wiki.biligame.com/ys/角色筛选"
|
||||
data, code = await update_info(url, "genshin")
|
||||
if code == 200:
|
||||
ALL_CHAR = init_game_pool('genshin', data, GenshinChar)
|
||||
url = 'https://wiki.biligame.com/ys/武器图鉴'
|
||||
data, code = await update_info(url, 'genshin_arms', ['头像', '名称', '类型', '稀有度.alt',
|
||||
'获取途径', '初始基础属性1', '初始基础属性2',
|
||||
'攻击力(MAX)', '副属性(MAX)', '技能'])
|
||||
ALL_CHAR = init_game_pool("genshin", data, GenshinChar)
|
||||
url = "https://wiki.biligame.com/ys/武器图鉴"
|
||||
data, code = await update_info(
|
||||
url,
|
||||
"genshin_arms",
|
||||
[
|
||||
"头像",
|
||||
"名称",
|
||||
"类型",
|
||||
"稀有度.alt",
|
||||
"获取途径",
|
||||
"初始基础属性1",
|
||||
"初始基础属性2",
|
||||
"攻击力(MAX)",
|
||||
"副属性(MAX)",
|
||||
"技能",
|
||||
],
|
||||
)
|
||||
if code == 200:
|
||||
ALL_ARMS = init_game_pool('genshin_arms', data, GenshinChar)
|
||||
ALL_ARMS = init_game_pool("genshin_arms", data, GenshinChar)
|
||||
await _genshin_init_up_char()
|
||||
|
||||
|
||||
async def init_genshin_data():
|
||||
global ALL_CHAR, ALL_ARMS
|
||||
if GENSHIN_FLAG:
|
||||
if not os.path.exists(DRAW_PATH + 'genshin.json') or not os.path.exists(DRAW_PATH + 'genshin_arms.json'):
|
||||
if not os.path.exists(DRAW_PATH + "genshin.json") or not os.path.exists(
|
||||
DRAW_PATH + "genshin_arms.json"
|
||||
):
|
||||
await update_genshin_info()
|
||||
else:
|
||||
with open(DRAW_PATH + 'genshin.json', 'r', encoding='utf8') as f:
|
||||
with open(DRAW_PATH + "genshin.json", "r", encoding="utf8") as f:
|
||||
genshin_dict = json.load(f)
|
||||
with open(DRAW_PATH + 'genshin_arms.json', 'r', encoding='utf8') as f:
|
||||
with open(DRAW_PATH + "genshin_arms.json", "r", encoding="utf8") as f:
|
||||
genshin_ARMS_dict = json.load(f)
|
||||
ALL_CHAR = init_game_pool('genshin', genshin_dict, GenshinChar)
|
||||
ALL_ARMS = init_game_pool('genshin_arms', genshin_ARMS_dict, GenshinChar)
|
||||
ALL_CHAR = init_game_pool("genshin", genshin_dict, GenshinChar)
|
||||
ALL_ARMS = init_game_pool("genshin_arms", genshin_ARMS_dict, GenshinChar)
|
||||
await _genshin_init_up_char()
|
||||
|
||||
|
||||
# 抽取卡池
|
||||
def _get_genshin_card(mode: int = 1, pool_name: str = '', add: float = 0.0):
|
||||
def _get_genshin_card(mode: int = 1, pool_name: str = "", add: float = 0.0):
|
||||
global ALL_ARMS, ALL_CHAR, UP_ARMS, UP_CHAR, _CURRENT_ARMS_POOL_TITLE, _CURRENT_CHAR_POOL_TITLE
|
||||
if mode == 1:
|
||||
star = get_star([5, 4, 3], [GENSHIN_FIVE_P + add, GENSHIN_FOUR_P, GENSHIN_THREE_P])
|
||||
star = get_star(
|
||||
[5, 4, 3], [GENSHIN_FIVE_P + add, GENSHIN_FOUR_P, GENSHIN_THREE_P]
|
||||
)
|
||||
elif mode == 2:
|
||||
star = get_star([5, 4], [GENSHIN_G_FIVE_P + add, GENSHIN_G_FOUR_P])
|
||||
else:
|
||||
star = 5
|
||||
if pool_name == 'char':
|
||||
if pool_name == "char":
|
||||
data_lst = UP_CHAR
|
||||
flag = _CURRENT_CHAR_POOL_TITLE
|
||||
itype_all_lst = ALL_CHAR + [x for x in ALL_ARMS if x.star == star and x.star < 5]
|
||||
elif pool_name == 'arms':
|
||||
itype_all_lst = ALL_CHAR + [
|
||||
x for x in ALL_ARMS if x.star == star and x.star < 5
|
||||
]
|
||||
elif pool_name == "arms":
|
||||
data_lst = UP_ARMS
|
||||
flag = _CURRENT_ARMS_POOL_TITLE
|
||||
itype_all_lst = ALL_ARMS + [x for x in ALL_CHAR if x.star == star and x.star < 5]
|
||||
itype_all_lst = ALL_ARMS + [
|
||||
x for x in ALL_CHAR if x.star == star and x.star < 5
|
||||
]
|
||||
else:
|
||||
data_lst = ''
|
||||
flag = ''
|
||||
itype_all_lst = ''
|
||||
data_lst = ""
|
||||
flag = ""
|
||||
itype_all_lst = ""
|
||||
all_lst = ALL_ARMS + ALL_CHAR
|
||||
# 是否UP
|
||||
if flag and star > 3 and pool_name:
|
||||
# 获取up角色列表
|
||||
up_char_lst = [x.operators for x in data_lst if x.star == star][0]
|
||||
# 成功获取up角色
|
||||
if random.random() < 0.5:
|
||||
up_char_name = random.choice(up_char_lst)
|
||||
acquire_char = [x for x in all_lst if x.name == up_char_name][0]
|
||||
try:
|
||||
if flag and star > 3 and pool_name:
|
||||
# 获取up角色列表
|
||||
up_char_lst = [x.operators for x in data_lst if x.star == star][0]
|
||||
print(up_char_lst)
|
||||
# 成功获取up角色
|
||||
if random.random() < 0.5:
|
||||
up_char_name = random.choice(up_char_lst)
|
||||
acquire_char = [x for x in all_lst if x.name == up_char_name][0]
|
||||
else:
|
||||
# 无up
|
||||
all_char_lst = [
|
||||
x
|
||||
for x in itype_all_lst
|
||||
if x.star == star and x.name not in up_char_lst and not x.limited
|
||||
]
|
||||
acquire_char = random.choice(all_char_lst)
|
||||
else:
|
||||
# 无up
|
||||
all_char_lst = [x for x in itype_all_lst if x.star == star and x.name not in up_char_lst and not x.limited]
|
||||
acquire_char = random.choice(all_char_lst)
|
||||
else:
|
||||
chars = [x for x in all_lst if x.star == star and not x.limited]
|
||||
acquire_char = random.choice(chars)
|
||||
except IndexError:
|
||||
chars = [x for x in all_lst if x.star == star and not x.limited]
|
||||
acquire_char = random.choice(chars)
|
||||
return acquire_char, 5 - star
|
||||
@@ -146,8 +205,8 @@ def _format_card_information(_count: int, user_id, pool_name):
|
||||
five_index_list = []
|
||||
five_list = []
|
||||
five_dict = {}
|
||||
_start_add_count = 72 if pool_name == 'char' else 62
|
||||
_x = 90 if pool_name == 'char' else 80 # 保底
|
||||
_start_add_count = 72 if pool_name == "char" else 62
|
||||
_x = 90 if pool_name == "char" else 80 # 保底
|
||||
add = 0.0
|
||||
if genshin_count.get(user_id) and _count <= _x:
|
||||
f_count = genshin_count[user_id]
|
||||
@@ -202,9 +261,17 @@ def reset_count(user_id: int):
|
||||
# 获取up和概率
|
||||
async def _genshin_init_up_char():
|
||||
global _CURRENT_CHAR_POOL_TITLE, _CURRENT_ARMS_POOL_TITLE, UP_CHAR, UP_ARMS, POOL_IMG
|
||||
_CURRENT_CHAR_POOL_TITLE, _CURRENT_ARMS_POOL_TITLE, POOL_IMG, UP_CHAR, UP_ARMS = await init_up_char(announcement)
|
||||
(
|
||||
_CURRENT_CHAR_POOL_TITLE,
|
||||
_CURRENT_ARMS_POOL_TITLE,
|
||||
POOL_IMG,
|
||||
UP_CHAR,
|
||||
UP_ARMS,
|
||||
) = await init_up_char(announcement)
|
||||
|
||||
|
||||
async def reload_genshin_pool():
|
||||
await _genshin_init_up_char()
|
||||
return Message(f'当前UP池子:{_CURRENT_CHAR_POOL_TITLE} & {_CURRENT_ARMS_POOL_TITLE} {POOL_IMG}')
|
||||
return Message(
|
||||
f"当前UP池子:{_CURRENT_CHAR_POOL_TITLE} & {_CURRENT_ARMS_POOL_TITLE} {POOL_IMG}"
|
||||
)
|
||||
|
||||
@@ -182,7 +182,7 @@ def intermediate_check(member_dict: dict, key: str, game_name: str, td: bs4.elem
|
||||
if game_name == 'prts':
|
||||
if key == '获取途径':
|
||||
msg = re.search('<td.*?>([\\s\\S]*)</td>', str(td)).group(1).strip()
|
||||
msg = msg[:-1] if msg[-1] == '\n' else msg
|
||||
msg = msg[:-1] if msg and msg[-1] == '\n' else msg
|
||||
if msg.find('<a') != -1:
|
||||
for a in td.find_all('a'):
|
||||
msg = msg.replace(str(a), a.text)
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent
|
||||
from nonebot import on_command
|
||||
from utils.utils import get_message_imgs, get_message_text
|
||||
from utils.utils import get_message_img, get_message_text
|
||||
from utils.message_builder import share
|
||||
from services.log import logger
|
||||
|
||||
@@ -32,7 +32,7 @@ fake_msg = on_command("假消息", priority=5, block=True)
|
||||
@fake_msg.handle()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
msg = get_message_text(event.json()).split(" ")
|
||||
img = get_message_imgs(event.json())
|
||||
img = get_message_img(event.json())
|
||||
if len(msg) > 1:
|
||||
if len(msg) == 2:
|
||||
url = msg[0]
|
||||
|
||||
+2
-2
@@ -4,7 +4,7 @@ from utils.image_utils import get_img_hash
|
||||
import random
|
||||
from utils.message_builder import image
|
||||
from nonebot import on_message
|
||||
from utils.utils import get_message_text, get_message_imgs
|
||||
from utils.utils import get_message_text, get_message_img
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent
|
||||
from configs.config import Config
|
||||
@@ -90,7 +90,7 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
|
||||
if get_message_text(event.json()):
|
||||
if get_message_text(event.json()).find("@可爱的小真寻") != -1:
|
||||
await fudu.finish("复制粘贴的虚空艾特?", at_sender=True)
|
||||
imgs = get_message_imgs(event.json())
|
||||
imgs = get_message_img(event.json())
|
||||
msg = get_message_text(event.json())
|
||||
if not imgs and not msg:
|
||||
return
|
||||
|
||||
@@ -108,7 +108,6 @@ async def init(flag: bool = False):
|
||||
resource_name_list.append(x["name"])
|
||||
except TimeoutError:
|
||||
logger.warning('原神资源查询信息初始化超时....')
|
||||
pass
|
||||
|
||||
|
||||
# 图标及位置资源
|
||||
@@ -185,12 +184,13 @@ async def download_map_init(
|
||||
semaphore,
|
||||
force_flag=flag,
|
||||
)
|
||||
BuildImage(0, 0, background=f"{map_path}/{idx}.png", ratio=MAP_RATIO).save()
|
||||
idx += 1
|
||||
_w, h = BuildImage(0, 0, background=f"{map_path}/0.png", ratio=MAP_RATIO).size
|
||||
_w, h = BuildImage(0, 0, background=f"{map_path}/0.png").size
|
||||
w = _w * len(os.listdir(map_path))
|
||||
map_file = BuildImage(w, h, _w, h, ratio=MAP_RATIO)
|
||||
for i in range(idx):
|
||||
map_file.paste(BuildImage(0, 0, background=f"{map_path}/{i}.png", ratio=MAP_RATIO))
|
||||
map_file.paste(BuildImage(0, 0, background=f"{map_path}/{i}.png"))
|
||||
map_file.save(f"{map_path}/map.png")
|
||||
else:
|
||||
logger.warning(f'获取原神地图失败 msg: {data["message"]}')
|
||||
|
||||
@@ -64,7 +64,7 @@ async def get_image(
|
||||
"affix_level": char["weapon"]["affix_level"],
|
||||
}
|
||||
|
||||
await init_image(char_data_list, _x, home_data_list)
|
||||
await init_image(world_data_dict, char_data_list, _x, home_data_list)
|
||||
return await get_genshin_image(
|
||||
user_id,
|
||||
uid,
|
||||
@@ -204,6 +204,7 @@ def parsed_data(
|
||||
"image": world["icon"],
|
||||
"name": world["name"],
|
||||
"offerings": world["offerings"],
|
||||
"icon": world["icon"]
|
||||
}
|
||||
world_data_dict[world["name"]] = _x
|
||||
home_data_list = []
|
||||
|
||||
@@ -77,42 +77,38 @@ def _get_genshin_image(
|
||||
:param nickname: 用户昵称
|
||||
:param user_ava:用户头像
|
||||
"""
|
||||
x = 450 if char_detailed_dict else 330
|
||||
char_height = (
|
||||
len(char_data_list) / 7
|
||||
if len(char_data_list) % 7 == 0
|
||||
else len(char_data_list) / 7 + 1
|
||||
)
|
||||
foot = BuildImage(1700, 87, background=image_path / "head.png")
|
||||
head = BuildImage(1700, 87, background=image_path / "head.png")
|
||||
head.rotate(180)
|
||||
middle = BuildImage(
|
||||
1700, int(1600 + 200 + x * char_height), background=image_path / "middle.png"
|
||||
)
|
||||
A = BuildImage(middle.w, middle.h + foot.h + head.h)
|
||||
A.paste(head, (-5, 0), True)
|
||||
A.paste(middle, (0, head.h), True)
|
||||
A.paste(foot, (0, head.h + middle.h), True)
|
||||
A.crop((0, 0, A.w - 5, A.h))
|
||||
user_image = get_user_data_image(uid, role_data, mys_data, nickname, user_ava)
|
||||
home_image = get_home_data_image(home_data_list)
|
||||
country_image = get_country_data_image(world_data_dict)
|
||||
char_image, _h = get_char_data_image(char_data_list, char_detailed_dict)
|
||||
top_bk = BuildImage(user_image.w, user_image.h + home_image.h + 100, color="#F9F6F2")
|
||||
char_image = get_char_data_image(char_data_list, char_detailed_dict)
|
||||
top_bk = BuildImage(user_image.w, user_image.h + max([home_image.h, country_image.h]) + 100, color="#F9F6F2")
|
||||
top_bk.paste(user_image, alpha=True)
|
||||
top_bk.paste(home_image, (0, user_image.h + 50), alpha=True)
|
||||
top_bk.paste(country_image, (home_image.w + 100, user_image.h + 50), alpha=True)
|
||||
bar = BuildImage(1600, 200, font_size=50, color="#F9F6F2", font="HYWenHei-85W.ttf")
|
||||
bar.text((50, 10), "角色背包", (104, 103, 101))
|
||||
bar.line((50, 90, 1550, 90), (227, 219, 209), width=10)
|
||||
if A.h - top_bk.h - bar.h - _h > 200:
|
||||
_h = A.h - top_bk.h - bar.h - _h - 200
|
||||
|
||||
foot = BuildImage(1700, 87, background=image_path / "head.png")
|
||||
head = BuildImage(1700, 87, background=image_path / "head.png")
|
||||
head.rotate(180)
|
||||
middle = BuildImage(
|
||||
1700, top_bk.h + bar.h + char_image.h, background=image_path / "middle.png"
|
||||
)
|
||||
A = BuildImage(middle.w, middle.h + foot.h + head.h)
|
||||
A.paste(head, (-5, 0), True)
|
||||
A.paste(middle, (0, head.h), True)
|
||||
A.paste(foot, (0, head.h + middle.h), True)
|
||||
A.crop((0, 0, A.w - 5, A.h))
|
||||
if A.h - top_bk.h - bar.h - char_image.h > 200:
|
||||
_h = A.h - top_bk.h - bar.h - char_image.h - 200
|
||||
A.crop((0, 0, A.w, A.h - _h))
|
||||
A.paste(foot, (0, A.h - 87))
|
||||
A.paste(top_bk, (0, 100), center_type="by_width")
|
||||
A.paste(bar, (50, top_bk.h + 80))
|
||||
A.paste(char_image, (0, top_bk.h + bar.h + 10), center_type="by_width")
|
||||
rand = random.randint(1, 10000)
|
||||
A.resize(0.8)
|
||||
A.save(Path(IMAGE_PATH) / "temp" / f"genshin_user_card_{rand}.png")
|
||||
return image(f"genshin_user_card_{rand}.png", "temp")
|
||||
|
||||
@@ -233,8 +229,9 @@ def get_home_data_image(home_data_list: List[Dict]) -> BuildImage:
|
||||
画出家园数据
|
||||
:param home_data_list: 家园列表
|
||||
"""
|
||||
h = 130 + 300 * 4
|
||||
region = BuildImage(
|
||||
550, 1050, color="#E3DBD1", font="HYWenHei-85W.ttf", font_size=40
|
||||
550, h, color="#E3DBD1", font="HYWenHei-85W.ttf", font_size=40
|
||||
)
|
||||
try:
|
||||
region.text(
|
||||
@@ -245,7 +242,7 @@ def get_home_data_image(home_data_list: List[Dict]) -> BuildImage:
|
||||
)
|
||||
except (IndexError, KeyError):
|
||||
region.text((0, 30), f"尘歌壶 Lv.0", center_type="by_width")
|
||||
region.text((0, 980), f"仙力: 0", center_type="by_width")
|
||||
region.text((0, region.h - 70), f"仙力: 0", center_type="by_width")
|
||||
region.circle_corner(30)
|
||||
height = 100
|
||||
homes = os.listdir(image_path / "homes")
|
||||
@@ -300,9 +297,9 @@ def get_country_data_image(world_data_dict: Dict) -> BuildImage:
|
||||
画出国家探索供奉等图像
|
||||
:param world_data_dict: 国家数据字典
|
||||
"""
|
||||
region = BuildImage(790, 1050, color="#F9F6F2")
|
||||
region = BuildImage(790, 267 * len(world_data_dict), color="#F9F6F2")
|
||||
height = 0
|
||||
for country in ["蒙德", "龙脊雪山", "璃月", "稻妻"]:
|
||||
for country in ["蒙德", "龙脊雪山", "璃月", "稻妻", "渊下宫"]:
|
||||
x = BuildImage(790, 250, color="#3A4467")
|
||||
logo = BuildImage(180, 180, background=image_path / "logo" / f"{country}.png")
|
||||
tmp_bk = BuildImage(770, 230, color="#606779")
|
||||
@@ -356,6 +353,14 @@ def get_country_data_image(world_data_dict: Dict) -> BuildImage:
|
||||
f"Lv.{world_data_dict[country]['offerings'][0]['level']}",
|
||||
fill=(255, 255, 255),
|
||||
)
|
||||
elif country in ["渊下宫"]:
|
||||
content_bk.text((300, 0), "探索", fill=(239, 211, 114), center_type="by_height")
|
||||
content_bk.text(
|
||||
(450, 20),
|
||||
f"{world_data_dict[country]['exploration_percentage'] / 10}%",
|
||||
fill=(255, 255, 255),
|
||||
center_type="by_height",
|
||||
)
|
||||
x.paste(tmp_bk, alpha=True, center_type="center")
|
||||
x.paste(content_bk, alpha=True, center_type="center")
|
||||
x.circle_corner(20)
|
||||
@@ -372,12 +377,9 @@ def get_char_data_image(
|
||||
:param char_data_list: 角色列表
|
||||
:param char_detailed_dict: 角色武器
|
||||
"""
|
||||
x = 420 if char_detailed_dict else 350
|
||||
_h = x * int(
|
||||
len(char_data_list) / 7
|
||||
if len(char_data_list) % 7 == 0
|
||||
else len(char_data_list) / 7 + 1
|
||||
)
|
||||
lens = len(char_data_list) / 7 if len(char_data_list) % 7 == 0 else len(char_data_list) / 7 + 1
|
||||
x = 500
|
||||
_h = int(x * lens)
|
||||
region = BuildImage(
|
||||
1600,
|
||||
_h,
|
||||
@@ -389,12 +391,12 @@ def get_char_data_image(
|
||||
for char in char_data_list:
|
||||
if width + 230 > 1550:
|
||||
width = 120
|
||||
height += x
|
||||
height += 420
|
||||
idx += 1
|
||||
char_img = image_path / "chars" / f'{char["name"]}.png'
|
||||
char_bk = BuildImage(
|
||||
270,
|
||||
500 if char_detailed_dict else 400,
|
||||
500,
|
||||
background=image_path / "element.png",
|
||||
font="HYWenHei-85W.ttf",
|
||||
font_size=35,
|
||||
@@ -507,16 +509,23 @@ def get_char_data_image(
|
||||
char_bk.resize(0.8)
|
||||
region.paste(char_bk, (width, height), True)
|
||||
width += 230
|
||||
return region, _h
|
||||
region.crop((0, 0, region.w, height + 430))
|
||||
return region
|
||||
|
||||
|
||||
async def init_image(char_data_list: List[Dict], char_detailed_dict: dict, home_data_list: List[Dict]):
|
||||
async def init_image(world_data_dict: Dict[str, Dict[str, str]], char_data_list: List[Dict[str, str]], char_detailed_dict: dict, home_data_list: List[Dict]):
|
||||
"""
|
||||
下载头像
|
||||
:param world_data_dict: 地图标志
|
||||
:param char_data_list: 角色列表
|
||||
:param char_detailed_dict: 角色武器
|
||||
:param home_data_list: 家园列表
|
||||
"""
|
||||
for world in world_data_dict:
|
||||
file = image_path / "logo" / f'{world_data_dict[world]["name"]}.png'
|
||||
file.parent.mkdir(parents=True, exist_ok=True)
|
||||
if not file.exists():
|
||||
await AsyncHttpx.download_file(world_data_dict[world]["icon"], file)
|
||||
for char in char_data_list:
|
||||
file = image_path / "chars" / f'{char["name"]}.png'
|
||||
file.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
@@ -3,7 +3,7 @@ from nonebot.rule import to_me
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent
|
||||
from configs.config import Config
|
||||
from utils.utils import get_message_imgs, get_message_text
|
||||
from utils.utils import get_message_img, get_message_text
|
||||
from .data_source import upload_image_to_local
|
||||
|
||||
|
||||
@@ -49,15 +49,15 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
await upload_img.reject("此目录不正确,请重新输入目录!")
|
||||
state["path"] = msg
|
||||
if state["_current_key"] in ["imgs"]:
|
||||
if not get_message_imgs(event.json()):
|
||||
if not get_message_img(event.json()):
|
||||
await upload_img.reject("图呢图呢图呢图呢!GKD!")
|
||||
state["imgs"] = get_message_imgs(event.json())
|
||||
state["imgs"] = get_message_img(event.json())
|
||||
|
||||
|
||||
@upload_img.handle()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
raw_arg = get_message_text(event.json())
|
||||
img_list = get_message_imgs(event.json())
|
||||
img_list = get_message_img(event.json())
|
||||
if raw_arg:
|
||||
if raw_arg in Config.get_config("image_management", "IMAGE_DIR_LIST"):
|
||||
state["path"] = raw_arg
|
||||
@@ -92,7 +92,7 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
state[state["_current_key"]] = str(event.get_message())
|
||||
else:
|
||||
if get_message_text(event.json()) not in ["stop"]:
|
||||
img = get_message_imgs(event.json())
|
||||
img = get_message_img(event.json())
|
||||
if img:
|
||||
state["tmp"].extend(img)
|
||||
await continuous_upload_img.reject("图再来!!")
|
||||
@@ -102,7 +102,7 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
|
||||
@continuous_upload_img.handle()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
path = get_message_imgs(event.json())
|
||||
path = get_message_img(event.json())
|
||||
if path in Config.get_config("image_management", "IMAGE_DIR_LIST"):
|
||||
state["path"] = path
|
||||
await continuous_upload_img.send("图来!!【停止请发送 ‘stop’ 开始上传】")
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
from nonebot import on_message, on_command
|
||||
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent
|
||||
from nonebot.adapters.cqhttp.permission import GROUP
|
||||
from utils.utils import get_message_text, is_number, get_message_imgs
|
||||
from utils.utils import get_message_text, is_number, get_message_img
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.adapters.cqhttp.exception import ActionFailed
|
||||
from configs.path_config import DATA_PATH, TEMP_PATH
|
||||
@@ -87,7 +87,7 @@ mute_data = get_data()
|
||||
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
|
||||
group_id = str(event.group_id)
|
||||
msg = get_message_text(event.json())
|
||||
imgs = get_message_imgs(event.json())
|
||||
imgs = get_message_img(event.json())
|
||||
img_hash = ""
|
||||
for img in imgs:
|
||||
img_hash += await download_img_and_hash(img, event.group_id)
|
||||
|
||||
@@ -5,7 +5,7 @@ from nonebot.plugin import on_command, on_message
|
||||
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent
|
||||
from nonebot.typing import T_State
|
||||
from services.log import logger
|
||||
from utils.utils import get_message_text, get_message_imgs
|
||||
from utils.utils import get_message_text, get_message_img
|
||||
from configs.config import Config
|
||||
from nonebot.rule import to_me
|
||||
|
||||
@@ -72,7 +72,7 @@ setu = on_command("识图", aliases={"search"}, block=True, priority=5)
|
||||
@setu.handle()
|
||||
async def handle_first_receive(bot: Bot, event: MessageEvent, state: T_State):
|
||||
msg = get_message_text(event.json())
|
||||
imgs = get_message_imgs(event.json())
|
||||
imgs = get_message_img(event.json())
|
||||
if imgs:
|
||||
state["setu"] = imgs[0]
|
||||
if msg:
|
||||
@@ -87,7 +87,7 @@ async def handle_first_receive(bot: Bot, event: MessageEvent, state: T_State):
|
||||
|
||||
@setu.args_parser
|
||||
async def get_setu(bot: Bot, event: MessageEvent, state: T_State):
|
||||
imgs = get_message_imgs(event.json())
|
||||
imgs = get_message_img(event.json())
|
||||
msg = get_message_text(event.json())
|
||||
if not imgs:
|
||||
await setu.reject()
|
||||
|
||||
@@ -9,7 +9,7 @@ class OpenCasesUser(db.Model):
|
||||
|
||||
id = db.Column(db.Integer(), primary_key=True)
|
||||
user_qq = db.Column(db.BigInteger(), nullable=False)
|
||||
belonging_group = db.Column(db.BigInteger(), nullable=False)
|
||||
group_id = db.Column(db.BigInteger(), nullable=False)
|
||||
total_count = db.Column(db.Integer(), nullable=False, default=0)
|
||||
blue_count = db.Column(db.Integer(), nullable=False, default=0)
|
||||
blue_st_count = db.Column(db.Integer(), nullable=False, default=0)
|
||||
@@ -27,19 +27,19 @@ class OpenCasesUser(db.Model):
|
||||
open_cases_time_last = db.Column(db.DateTime(timezone=True), nullable=False, default=datetime.now())
|
||||
knifes_name = db.Column(db.Unicode(), nullable=False, default="")
|
||||
|
||||
_idx1 = db.Index('open_cases_group_users_idx1', 'user_qq', 'belonging_group', unique=True)
|
||||
_idx1 = db.Index('open_cases_group_users_idx1', 'user_qq', 'group_id', unique=True)
|
||||
|
||||
@classmethod
|
||||
async def ensure(cls, user_qq: int, belonging_group: int, for_update: bool = False) -> 'OpenCasesUser':
|
||||
async def ensure(cls, user_qq: int, group_id: int, for_update: bool = False) -> 'OpenCasesUser':
|
||||
query = cls.query.where(
|
||||
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||
(cls.user_qq == user_qq) & (cls.group_id == group_id)
|
||||
)
|
||||
if for_update:
|
||||
query = query.with_for_update()
|
||||
user = await query.gino.first()
|
||||
return user or await cls.create(
|
||||
user_qq=user_qq,
|
||||
belonging_group=belonging_group,
|
||||
group_id=group_id,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@@ -49,7 +49,7 @@ class OpenCasesUser(db.Model):
|
||||
query = await cls.query.gino.all()
|
||||
else:
|
||||
query = await cls.query.where(
|
||||
(cls.belonging_group == group_id)
|
||||
(cls.group_id == group_id)
|
||||
).gino.all()
|
||||
for user in query:
|
||||
user_list.append(user)
|
||||
|
||||
@@ -9,7 +9,7 @@ from gino.exceptions import UninitializedError
|
||||
from utils.utils import (
|
||||
is_number,
|
||||
get_message_text,
|
||||
get_message_imgs,
|
||||
get_message_img,
|
||||
)
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.adapters.cqhttp import (
|
||||
@@ -243,7 +243,7 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
if str(event.message) == "取消":
|
||||
await find_setu.finish("取消了操作", at_sender=True)
|
||||
imgs = get_message_imgs(event.json())
|
||||
imgs = get_message_img(event.json())
|
||||
if not imgs:
|
||||
await find_setu.reject("不搞错了,俺要图!")
|
||||
state["img"] = imgs[0]
|
||||
@@ -253,7 +253,7 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
if get_message_text(event.json()) in ["帮助"]:
|
||||
await find_setu.finish("通过图片获取本地色图id\n\t示例:查色图(图片)")
|
||||
imgs = get_message_imgs(event.json())
|
||||
imgs = get_message_img(event.json())
|
||||
if imgs:
|
||||
state["img"] = imgs[0]
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ update_setu = on_command(
|
||||
async def _(bot: Bot, event: Event, state: T_State):
|
||||
if Config.get_config("send_setu", "DOWNLOAD_SETU"):
|
||||
await update_setu.send("开始更新色图...", at_sender=True)
|
||||
await update_setu.send(await update_setu_img(), at_sender=True)
|
||||
await update_setu_img(True)
|
||||
else:
|
||||
await update_setu.finish("更新色图配置未开启")
|
||||
|
||||
|
||||
@@ -90,7 +90,11 @@ headers = {
|
||||
}
|
||||
|
||||
|
||||
async def update_setu_img():
|
||||
async def update_setu_img(flag: bool = False):
|
||||
"""
|
||||
更新色图
|
||||
:param flag: 是否手动更新
|
||||
"""
|
||||
image_list = await Setu.get_all_setu()
|
||||
image_list.reverse()
|
||||
_success = 0
|
||||
@@ -105,6 +109,9 @@ async def update_setu_img():
|
||||
path.mkdir(exist_ok=True, parents=True)
|
||||
rar_path.mkdir(exist_ok=True, parents=True)
|
||||
if not local_image.exists() or not image.img_hash:
|
||||
temp_file = rar_path / f"{image.local_id}.jpg"
|
||||
if temp_file.exists():
|
||||
temp_file.unlink()
|
||||
url_ = image.img_url
|
||||
ws_url = Config.get_config("pixiv", "PIXIV_NGINX_URL")
|
||||
if ws_url:
|
||||
@@ -158,8 +165,7 @@ async def update_setu_img():
|
||||
error_info.append(f"更新色图 {image.local_id}.jpg 错误 {type(e)}: {e}")
|
||||
else:
|
||||
logger.info(f"更新色图 {image.local_id}.jpg 已存在")
|
||||
error_info = ["无报错.."] if not error_info else error_info
|
||||
if count or _success or error_info:
|
||||
if _success or error_info or flag:
|
||||
await get_bot().send_private_msg(
|
||||
user_id=int(list(get_bot().config.superusers)[0]),
|
||||
message=f'{str(datetime.now()).split(".")[0]} 更新 色图 完成,本地存在 {count} 张,实际更新 {_success} 张,'
|
||||
|
||||
@@ -50,7 +50,7 @@ async def check_in_all(nickname: str, user_qq: int):
|
||||
async with db.transaction():
|
||||
present = datetime.now()
|
||||
for u in await SignGroupUser.get_user_all_data(user_qq):
|
||||
group = u.belonging_group
|
||||
group = u.group_id
|
||||
if not ((
|
||||
u.checkin_time_last + timedelta(hours=8)
|
||||
).date() >= present.date() or f"{u}_{group}_sign_{datetime.now().date()}" in os.listdir(
|
||||
@@ -79,18 +79,18 @@ async def _handle_check_in(
|
||||
gift = f"额外金币 + {gift}"
|
||||
else:
|
||||
await BagUser.add_gold(user_qq, group, gold)
|
||||
await BagUser.add_props(user_qq, group, gift)
|
||||
await BagUser.add_property(user_qq, group, gift)
|
||||
gift += ' + 1'
|
||||
if critx2 + add_probability > 0.97 or critx2 < specify_probability:
|
||||
logger.info(
|
||||
f"(USER {user.user_qq}, GROUP {user.belonging_group})"
|
||||
f"(USER {user.user_qq}, GROUP {user.group_id})"
|
||||
f" CHECKED IN successfully. score: {user.impression:.2f} "
|
||||
f"(+{impression_added * 2:.2f}).获取金币:{gold + gift if gift == 'gold' else gold}"
|
||||
)
|
||||
return await get_card(user, nickname, impression_added, gold, gift, True)
|
||||
else:
|
||||
logger.info(
|
||||
f"(USER {user.user_qq}, GROUP {user.belonging_group})"
|
||||
f"(USER {user.user_qq}, GROUP {user.group_id})"
|
||||
f" CHECKED IN successfully. score: {user.impression:.2f} "
|
||||
f"(+{impression_added:.2f}).获取金币:{gold + gift if gift == 'gold' else gold}"
|
||||
)
|
||||
|
||||
@@ -11,6 +11,7 @@ from .config import (
|
||||
from models.sign_group_user import SignGroupUser
|
||||
from models.group_member_info import GroupInfoUser
|
||||
from nonebot.adapters.cqhttp import MessageSegment
|
||||
from configs.config import Config
|
||||
from utils.utils import get_user_avatar
|
||||
from utils.image_utils import BuildImage
|
||||
from utils.message_builder import image
|
||||
@@ -55,32 +56,32 @@ async def get_card(
|
||||
_type = "view" if is_card_view else "sign"
|
||||
card_file = (
|
||||
Path(SIGN_TODAY_CARD_PATH)
|
||||
/ f"{user_id}_{user.belonging_group}_{_type}_{date}.png"
|
||||
/ f"{user_id}_{user.group_id}_{_type}_{date}.png"
|
||||
)
|
||||
if card_file.exists():
|
||||
return image(
|
||||
f"{user_id}_{user.belonging_group}_{_type}_{date}.png", "sign/today_card"
|
||||
f"{user_id}_{user.group_id}_{_type}_{date}.png", "sign/today_card"
|
||||
)
|
||||
else:
|
||||
if add_impression == -1:
|
||||
card_file = (
|
||||
Path(SIGN_TODAY_CARD_PATH)
|
||||
/ f"{user_id}_{user.belonging_group}_view_{date}.png"
|
||||
/ f"{user_id}_{user.group_id}_view_{date}.png"
|
||||
)
|
||||
if card_file.exists():
|
||||
return image(
|
||||
f"{user_id}_{user.belonging_group}_view_{date}.png",
|
||||
f"{user_id}_{user.group_id}_view_{date}.png",
|
||||
"sign/today_card",
|
||||
)
|
||||
is_card_view = True
|
||||
ava = BytesIO(await get_user_avatar(user_id))
|
||||
uid = await GroupInfoUser.get_group_member_uid(
|
||||
user.user_qq, user.belonging_group
|
||||
user.user_qq, user.group_id
|
||||
)
|
||||
impression_list = None
|
||||
if is_card_view:
|
||||
_, impression_list, _ = await SignGroupUser.get_all_impression(
|
||||
user.belonging_group
|
||||
user.group_id
|
||||
)
|
||||
return await asyncio.get_event_loop().run_in_executor(
|
||||
None,
|
||||
@@ -239,9 +240,10 @@ def _generate_card(
|
||||
f"上次签到日期:{'从未' if user.checkin_time_last == datetime.min else user.checkin_time_last.date()}",
|
||||
)
|
||||
today_data.text((0, 25), f"总金币:{gold}")
|
||||
default_setu_prob = Config.get_config("send_setu", "INITIAL_SETU_PROBABILITY") * 100
|
||||
today_data.text(
|
||||
(0, 50),
|
||||
f"色图概率:{(70 + user.impression if user.impression < 100 else 100):.2f}%",
|
||||
f"色图概率:{(default_setu_prob + user.impression if user.impression < 100 else 100):.2f}%",
|
||||
)
|
||||
today_data.text((0, 75), f"开箱次数:{(20 + int(user.impression / 3))}")
|
||||
_type = "view"
|
||||
@@ -285,10 +287,10 @@ def _generate_card(
|
||||
bk.paste(today_data, (580, 220), True)
|
||||
bk.paste(watermark, (15, 400), True)
|
||||
bk.save(
|
||||
SIGN_TODAY_CARD_PATH / f"{user_id}_{user.belonging_group}_{_type}_{data}.png"
|
||||
SIGN_TODAY_CARD_PATH / f"{user_id}_{user.group_id}_{_type}_{data}.png"
|
||||
)
|
||||
return image(
|
||||
f"{user_id}_{user.belonging_group}_{_type}_{data}.png", "sign/today_card"
|
||||
f"{user_id}_{user.group_id}_{_type}_{data}.png", "sign/today_card"
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ async def translate_msg(language_type, msg):
|
||||
}
|
||||
data = (await AsyncHttpx.post(url, data=data)).json()
|
||||
if data["errorCode"] == 0:
|
||||
return data["translateResult"][0][0]["tgt"]
|
||||
return f'原文:{msg}\n翻译{data["translateResult"][0][0]["tgt"]}'
|
||||
return "翻译惜败.."
|
||||
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ from services.log import logger
|
||||
from nonebot.rule import to_me
|
||||
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent
|
||||
from nonebot.typing import T_State
|
||||
from utils.utils import get_message_imgs
|
||||
from utils.utils import get_message_img
|
||||
from pathlib import Path
|
||||
from utils.utils import is_number, get_message_text
|
||||
from utils.image_utils import BuildImage, pic2b64
|
||||
@@ -150,9 +150,9 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
await update_img.reject("请输入支持的替换的底色:\n红色 蓝色 白色 绿色")
|
||||
state["y"] = str(event.get_message())
|
||||
if state["_current_key"] == "imgs":
|
||||
if not get_message_imgs(event.json()):
|
||||
if not get_message_img(event.json()):
|
||||
await update_img.reject("没图?没图?没图?来图速来!")
|
||||
state[state["_current_key"]] = get_message_imgs(event.json())
|
||||
state[state["_current_key"]] = get_message_img(event.json())
|
||||
|
||||
|
||||
@update_img.handle()
|
||||
@@ -160,7 +160,7 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
if str(event.get_message()) in ["帮助"]:
|
||||
await update_img.finish(image("update_img_help.png"))
|
||||
raw_arg = get_message_text(event.json())
|
||||
img_list = get_message_imgs(event.json())
|
||||
img_list = get_message_img(event.json())
|
||||
if raw_arg:
|
||||
args = raw_arg.split("[")[0].split(" ")
|
||||
print(args)
|
||||
|
||||
@@ -2,7 +2,7 @@ from .data_source import get_anime
|
||||
from nonebot import on_command
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent
|
||||
from utils.utils import get_message_imgs
|
||||
from utils.utils import get_message_img
|
||||
from services.log import logger
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ what_anime = on_command("识番", priority=5, block=True)
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
if str(event.get_message()) in ["取消", "算了"]:
|
||||
await what_anime.finish("已取消操作..", at_sender=True)
|
||||
img_url = get_message_imgs(event.json())
|
||||
img_url = get_message_img(event.json())
|
||||
if not img_url:
|
||||
await what_anime.reject(prompt="图呢图呢图呢图呢GKD", at_sender=True)
|
||||
state["img_url"] = img_url
|
||||
@@ -43,7 +43,7 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
if str(event.get_message()) in ["帮助"]:
|
||||
await what_anime.finish(__plugin_usage__)
|
||||
img_url = get_message_imgs(event.json())
|
||||
img_url = get_message_img(event.json())
|
||||
if img_url:
|
||||
state["img_url"] = img_url
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent
|
||||
from nonebot import on_command
|
||||
from utils.utils import get_message_imgs, get_message_text, is_chinese
|
||||
from utils.utils import get_message_img, get_message_text, is_chinese
|
||||
from utils.message_builder import image
|
||||
from configs.path_config import TEMP_PATH
|
||||
from utils.image_utils import BuildImage
|
||||
@@ -47,7 +47,7 @@ w2b_img = on_command("黑白草图", aliases={"黑白图"}, priority=5, block=Tr
|
||||
@w2b_img.handle()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
# try:
|
||||
img = get_message_imgs(event.json())
|
||||
img = get_message_img(event.json())
|
||||
msg = get_message_text(event.json())
|
||||
if not img or not msg:
|
||||
await w2b_img.finish(f"格式错误:\n" + __plugin_usage__)
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
from utils.utils import get_message_at, is_number, get_message_imgs, get_message_text
|
||||
from utils.utils import get_message_at, is_number, get_message_img, get_message_text
|
||||
from services.log import logger
|
||||
from configs.path_config import DATA_PATH
|
||||
from utils.http_utils import AsyncHttpx
|
||||
from .data_source import WordBankBuilder
|
||||
from configs.config import Config
|
||||
from utils.message_builder import image
|
||||
from utils.image_utils import text2image
|
||||
from .model import WordBank
|
||||
from nonebot.adapters.cqhttp import (
|
||||
Bot,
|
||||
@@ -42,7 +44,7 @@ __plugin_version__ = 0.1
|
||||
__plugin_author__ = "HibiKier"
|
||||
__plugin_settings__ = {
|
||||
"admin_level": Config.get_config("word_bank", "WORD_BANK_LEVEL"),
|
||||
"cmd": ["词库问答", "添加词条", "删除词条", "查看词条"]
|
||||
"cmd": ["词库问答", "添加词条", "删除词条", "查看词条"],
|
||||
}
|
||||
|
||||
data_dir = Path(DATA_PATH) / "word_bank"
|
||||
@@ -65,13 +67,13 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
|
||||
problem = r.group(1).strip()
|
||||
if not problem:
|
||||
await add_word.finish("未检测到词条问题...")
|
||||
answer = msg.split('答', maxsplit=1)[-1]
|
||||
answer = msg.split("答", maxsplit=1)[-1]
|
||||
if not answer:
|
||||
await add_word.finish("未检测到词条回答...")
|
||||
idx = 0
|
||||
for n in bot.config.nickname:
|
||||
if problem.startswith(n):
|
||||
_problem = f"[_to_me|{n}]" + problem[len(n):]
|
||||
_problem = f"[_to_me|{n}]" + problem[len(n) :]
|
||||
break
|
||||
else:
|
||||
_problem = problem
|
||||
@@ -82,7 +84,7 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
|
||||
answer = answer.replace(f"[CQ:at,qq={at_}]", f"[__placeholder_{idx}]", 1)
|
||||
_builder.set_placeholder(idx, at_)
|
||||
idx += 1
|
||||
for img in get_message_imgs(event.json()):
|
||||
for img in get_message_img(event.json()):
|
||||
_x = img.split("?")[0]
|
||||
r = re.search(rf"\[CQ:image,file=(.*),url={_x}.*?]", answer)
|
||||
if r:
|
||||
@@ -90,7 +92,8 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
|
||||
for i in range(3):
|
||||
answer = answer.replace(f",subType={i}", "")
|
||||
answer = answer.replace(
|
||||
rf"[CQ:image,file={r.group(1)},url={img}]", f"[__placeholder_{idx}]",
|
||||
rf"[CQ:image,file={r.group(1)},url={img}]",
|
||||
f"[__placeholder_{idx}]",
|
||||
)
|
||||
await AsyncHttpx.download_file(
|
||||
img, data_dir / f"{event.group_id}" / f"__placeholder_{rand}_{idx}.jpg"
|
||||
@@ -119,11 +122,13 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
|
||||
x = problem.split(":")[-1]
|
||||
if not is_number(x) or int(x) < 0:
|
||||
await delete_word.finish("id必须为数字且符合规范!")
|
||||
p = (await WordBank.get_group_all_problem(event.group_id))
|
||||
p = await WordBank.get_group_all_problem(event.group_id)
|
||||
if p:
|
||||
problem = p[int(x)]
|
||||
try:
|
||||
if answer := await WordBank.delete_problem_answer(event.user_id, event.group_id, problem, index):
|
||||
if answer := await WordBank.delete_problem_answer(
|
||||
event.user_id, event.group_id, problem, index
|
||||
):
|
||||
await delete_word.send(f"删除词条成功:{problem}\n回答:\n{answer}")
|
||||
logger.info(
|
||||
f"(USER {event.user_id}, GROUP "
|
||||
@@ -143,21 +148,20 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
|
||||
_problem_list = await WordBank.get_group_all_problem(event.group_id)
|
||||
if not _problem_list:
|
||||
await show_word.finish("该群未收录任何词条..")
|
||||
_problem_list = [f"{i}. {x}" for i, x in enumerate(_problem_list)]
|
||||
_problem_list = [f"\t{i}. {x}" for i, x in enumerate(_problem_list)]
|
||||
await show_word.send(
|
||||
"该群已收录的词条:\n" + "\n".join(_problem_list)
|
||||
image(
|
||||
b64=await text2image(
|
||||
"该群已收录的词条:\n\n" + "\n".join(_problem_list),
|
||||
padding=10,
|
||||
color="#f9f6f2",
|
||||
)
|
||||
)
|
||||
)
|
||||
else:
|
||||
_answer_list = await WordBank.get_group_all_answer(event.group_id, msg)
|
||||
if not _answer_list:
|
||||
await show_word.send(
|
||||
"未收录该词条..."
|
||||
)
|
||||
await show_word.send("未收录该词条...")
|
||||
else:
|
||||
_answer_list = [f"{i}. {x}" for i, x in enumerate(_answer_list)]
|
||||
await show_word.send(
|
||||
f"词条 {msg} 回答:\n" + "\n".join(_answer_list)
|
||||
)
|
||||
|
||||
|
||||
|
||||
await show_word.send(f"词条 {msg} 回答:\n" + "\n".join(_answer_list))
|
||||
|
||||
@@ -20,7 +20,7 @@ usage:
|
||||
""".strip()
|
||||
__plugin_des__ = "实时疫情数据查询"
|
||||
__plugin_cmd__ = ["疫情 [省份/城市]", "疫情 中国"]
|
||||
__plugin_type__ = ('一些工具',)
|
||||
__plugin_type__ = ("一些工具",)
|
||||
__plugin_version__ = 0.1
|
||||
__plugin_author__ = "HibiKier & yzyyz1387"
|
||||
__plugin_settings__ = {
|
||||
|
||||
@@ -56,18 +56,26 @@ async def get_yiqing_data(area: str) -> Union[str, MessageSegment]:
|
||||
confirm = data_["total"]["confirm"] # 累计确诊
|
||||
heal = data_["total"]["heal"] # 累计治愈
|
||||
dead = data_["total"]["dead"] # 累计死亡
|
||||
dead_rate = data_["total"]["deadRate"] # 死亡率
|
||||
heal_rate = data_["total"]["healRate"] # 治愈率
|
||||
now_confirm = data_["total"]["nowConfirm"] # 目前确诊
|
||||
suspect = data_["total"]["suspect"] # 疑似
|
||||
add_confirm = data_["today"]["confirm"] # 新增确诊
|
||||
grade = ""
|
||||
_grade_color = ""
|
||||
if data_["total"].get("grade"):
|
||||
grade = data_["total"]["grade"]
|
||||
if "中风险" in grade:
|
||||
_grade_color = "#fa9424"
|
||||
else:
|
||||
_grade_color = "red"
|
||||
|
||||
dead_rate = f"{dead / confirm * 100:.2f}" # 死亡率
|
||||
heal_rate = f"{heal / confirm * 100:.2f}" # 治愈率
|
||||
|
||||
x = f"{city}市" if city else f"{province}{province_type}"
|
||||
return image(b64=await text2image(
|
||||
f"""
|
||||
{x} 疫情数据:
|
||||
{x} 疫情数据 {f"(<f font_color={_grade_color}>{grade}</f>)" if grade else ""}:
|
||||
目前确诊:
|
||||
确诊人数:<f font_color=red>{now_confirm}(+{add_confirm})</f>
|
||||
疑似人数:{suspect}
|
||||
-----------------
|
||||
累计数据:
|
||||
确诊人数:<f font_color=red>{confirm}</f>
|
||||
|
||||
+2
-2
@@ -4,8 +4,8 @@
|
||||
"models",
|
||||
"services",
|
||||
"utils",
|
||||
"resources/ttf"
|
||||
"basic_plugins"
|
||||
],
|
||||
"add_file": ["resources/img/other/time.png"],
|
||||
"add_file": [],
|
||||
"delete_file": []
|
||||
}
|
||||
|
||||
+32
-23
@@ -168,6 +168,17 @@ async def text2image(
|
||||
:param font_color: 普通字体颜色
|
||||
:param padding: 文本外边距,元组类型时为 (上,左,下,右)
|
||||
"""
|
||||
pw = ph = top_padding = left_padding = 0
|
||||
if padding:
|
||||
if isinstance(padding, int):
|
||||
pw = padding * 2
|
||||
ph = padding * 2
|
||||
top_padding = left_padding = padding
|
||||
elif isinstance(padding, tuple):
|
||||
pw = padding[0] + padding[2]
|
||||
ph = padding[1] + padding[3]
|
||||
top_padding = padding[0]
|
||||
left_padding = padding[1]
|
||||
if auto_parse and re.search(r"<f(.*)>(.*)</f>", text):
|
||||
_data = []
|
||||
new_text = ""
|
||||
@@ -277,24 +288,13 @@ async def text2image(
|
||||
for img in image_list:
|
||||
height += img.h
|
||||
width = width if width > img.w else img.w
|
||||
top_padding = left_padding = 0
|
||||
if padding:
|
||||
if isinstance(padding, int):
|
||||
width += padding * 2
|
||||
height += padding * 2
|
||||
top_padding = left_padding = padding
|
||||
elif isinstance(padding, tuple):
|
||||
width += padding[0] + padding[2]
|
||||
height += padding[1] + padding[3]
|
||||
top_padding = padding[0]
|
||||
left_padding = padding[1]
|
||||
width += pw
|
||||
height += ph
|
||||
A = BuildImage(width + left_padding, height + top_padding, color=color)
|
||||
current_height = top_padding
|
||||
for img in image_list:
|
||||
await A.apaste(img, (left_padding, current_height), True)
|
||||
current_height += img.h
|
||||
# A.show()
|
||||
return A.pic2bs4()
|
||||
else:
|
||||
width = 0
|
||||
height = 0
|
||||
@@ -303,10 +303,18 @@ async def text2image(
|
||||
w, h = _tmp.getsize(x)
|
||||
height += h
|
||||
width = width if width > w else w
|
||||
A = BuildImage(width, height, font_size=font_size, color=color)
|
||||
await A.atext((0, 0), text, font_color)
|
||||
# A.show()
|
||||
return A.pic2bs4()
|
||||
width += pw
|
||||
height += ph
|
||||
A = BuildImage(
|
||||
width + left_padding,
|
||||
height + top_padding,
|
||||
font_size=font_size,
|
||||
color=color,
|
||||
font=font,
|
||||
)
|
||||
await A.atext((left_padding, top_padding), text, font_color)
|
||||
# A.show()
|
||||
return A.pic2bs4()
|
||||
|
||||
|
||||
class BuildImage:
|
||||
@@ -354,6 +362,7 @@ class BuildImage:
|
||||
self.font = ImageFont.truetype(FONT_PATH + font, int(font_size))
|
||||
if not plain_text and not color:
|
||||
color = (255, 255, 255)
|
||||
self.background = background
|
||||
if not background:
|
||||
if plain_text:
|
||||
if not color:
|
||||
@@ -589,7 +598,7 @@ class BuildImage:
|
||||
pos = (w, h)
|
||||
self.draw.text(pos, text, fill=fill, font=self.font)
|
||||
|
||||
async def asave(self, path: Union[str, Path]):
|
||||
async def asave(self, path: Optional[Union[str, Path]] = None):
|
||||
"""
|
||||
说明:
|
||||
异步 保存图片
|
||||
@@ -598,15 +607,15 @@ class BuildImage:
|
||||
"""
|
||||
await self.loop.run_in_executor(None, self.save, path)
|
||||
|
||||
def save(self, path: Union[str, Path]):
|
||||
def save(self, path: Optional[Union[str, Path]] = None):
|
||||
"""
|
||||
说明:
|
||||
保存图片
|
||||
参数:
|
||||
:param path: 图片路径
|
||||
"""
|
||||
if isinstance(path, Path):
|
||||
path = path.absolute()
|
||||
if not path:
|
||||
path = self.background
|
||||
self.markImg.save(path)
|
||||
|
||||
def show(self):
|
||||
@@ -847,8 +856,8 @@ class BuildImage:
|
||||
for j in range(r2):
|
||||
lx = abs(i - r) # 到圆心距离的横坐标
|
||||
ly = abs(j - r) # 到圆心距离的纵坐标
|
||||
l = (pow(lx, 2) + pow(ly, 2)) ** 0.5 # 三角函数 半径
|
||||
if l < r3:
|
||||
l_ = (pow(lx, 2) + pow(ly, 2)) ** 0.5 # 三角函数 半径
|
||||
if l_ < r3:
|
||||
pim_b[i - (r - r3), j - (r - r3)] = pim_a[i, j]
|
||||
self.markImg = imb
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ class AdminManager(StaticData):
|
||||
|
||||
def get_plugin_module(self, cmd: str) -> Optional[str]:
|
||||
"""
|
||||
根据 cmd 获取功能 module
|
||||
根据 cmd 获取功能 modules
|
||||
:param cmd: 命令
|
||||
"""
|
||||
for key in self._data.keys():
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#
|
||||
# def add_plugin_config(
|
||||
# self,
|
||||
# module: str,
|
||||
# modules: str,
|
||||
# key: str,
|
||||
# value: str,
|
||||
# help_: Optional[str] = None,
|
||||
@@ -26,39 +26,39 @@
|
||||
# ):
|
||||
# """
|
||||
# 为插件添加一个配置
|
||||
# :param module: 模块
|
||||
# :param modules: 模块
|
||||
# :param key: 键
|
||||
# :param value: 值
|
||||
# :param help_: 配置注解
|
||||
# :param default_value: 默认值
|
||||
# """
|
||||
# if self._data.get(module) is None:
|
||||
# self._data[module] = {}
|
||||
# self._data[module][key] = {
|
||||
# if self._data.get(modules) is None:
|
||||
# self._data[modules] = {}
|
||||
# self._data[modules][key] = {
|
||||
# "value": value,
|
||||
# "help": help_,
|
||||
# "default_value": default_value,
|
||||
# }
|
||||
#
|
||||
# def remove_plugin_config(self, module: str):
|
||||
# def remove_plugin_config(self, modules: str):
|
||||
# """
|
||||
# 为插件删除一个配置
|
||||
# :param module: 模块名
|
||||
# :param modules: 模块名
|
||||
# """
|
||||
# if module in self._data.keys():
|
||||
# del self._data[module]
|
||||
# if modules in self._data.keys():
|
||||
# del self._data[modules]
|
||||
#
|
||||
# def get_config(self, module: str, key: str) -> Optional[Any]:
|
||||
# def get_config(self, modules: str, key: str) -> Optional[Any]:
|
||||
# """
|
||||
# 获取指定配置值
|
||||
# :param module: 模块名
|
||||
# :param modules: 模块名
|
||||
# :param key: 配置名称
|
||||
# """
|
||||
# if module in self._data.keys():
|
||||
# if self._data[module].get(key):
|
||||
# if self._data[module][key]["value"] is None:
|
||||
# return self._data[module][key]["default_value"]
|
||||
# return self._data[module][key]["value"]
|
||||
# if modules in self._data.keys():
|
||||
# if self._data[modules].get(key):
|
||||
# if self._data[modules][key]["value"] is None:
|
||||
# return self._data[modules][key]["default_value"]
|
||||
# return self._data[modules][key]["value"]
|
||||
# return None
|
||||
#
|
||||
#
|
||||
|
||||
@@ -86,7 +86,7 @@ class Plugins2settingsManager(StaticData):
|
||||
self, cmd: str, is_all: bool = False
|
||||
) -> Union[str, List[str]]:
|
||||
"""
|
||||
根据 cmd 获取功能 module
|
||||
根据 cmd 获取功能 modules
|
||||
:param cmd: 命令
|
||||
:param is_all: 获取全部包含cmd的模块
|
||||
"""
|
||||
|
||||
+1
-1
@@ -208,7 +208,7 @@ def get_message_at(data: str) -> List[int]:
|
||||
return []
|
||||
|
||||
|
||||
def get_message_imgs(data: str) -> List[str]:
|
||||
def get_message_img(data: str) -> List[str]:
|
||||
"""
|
||||
说明:
|
||||
获取消息中所有的 图片 的链接
|
||||
|
||||
Reference in New Issue
Block a user