update v0.0.8.0

This commit is contained in:
HibiKier
2022-01-05 22:32:59 +08:00
parent 5e5168f804
commit 30b56583bd
47 changed files with 1521 additions and 1281 deletions
+1 -1
View File
@@ -40,7 +40,7 @@ def is_expired(data: dict):
# 检查写入
def check_write(data: dict, up_char_file):
if not is_expired(data['char']):
if is_expired(data['char']):
for x in list(data.keys()):
data[x]['title'] = ''
else:
+10 -8
View File
@@ -146,12 +146,14 @@ 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 # 保底
add = 0.0
if genshin_count.get(user_id) and _count <= 90:
if genshin_count.get(user_id) and _count <= _x:
f_count = genshin_count[user_id]
else:
f_count = 0
if genshin_pl_count.get(user_id) and _count <= 90:
if genshin_pl_count.get(user_id) and _count <= _x:
count = genshin_pl_count[user_id]
else:
count = 0
@@ -159,23 +161,23 @@ def _format_card_information(_count: int, user_id, pool_name):
count += 1
f_count += 1
# 十连保底
if count == 10 and f_count != 90:
if f_count >= 72:
if count == 10 and f_count != _x:
if f_count >= _start_add_count:
add += I72_ADD
char, code = _get_genshin_card(2, pool_name, add=add)
count = 0
# 大保底
elif f_count == 90:
elif f_count == _x:
char, code = _get_genshin_card(3, pool_name)
else:
if f_count >= 72:
if f_count >= _start_add_count:
add += I72_ADD
char, code = _get_genshin_card(pool_name=pool_name, add=add)
if code == 1:
count = 0
star_list[code] += 1
if code == 0:
if _count <= 90:
if _count <= _x:
genshin_five[user_id] = f_count
add = 0.0
f_count = 0
@@ -186,7 +188,7 @@ def _format_card_information(_count: int, user_id, pool_name):
except KeyError:
five_dict[char.name] = 1
char_list.append(char)
if _count <= 90:
if _count <= _x:
genshin_count[user_id] = f_count
genshin_pl_count[user_id] = count
return char_list, five_list, five_index_list, five_dict, star_list
+8 -17
View File
@@ -7,9 +7,10 @@ from utils.browser import get_browser
from configs.path_config import IMAGE_PATH
import nonebot
from services.log import logger
from utils.utils import scheduler
from nonebot.permission import SUPERUSER
from pathlib import Path
from typing import List
from datetime import datetime, timedelta
import os
import asyncio
import time
@@ -52,9 +53,12 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
if time.strftime("%w") == "0":
await material.send("今天是周日,所有材料副本都开放了。")
return
file_name = str((datetime.now() - timedelta(hours=4)).date())
if not (Path(IMAGE_PATH) / "genshin" / "material" / f"{file_name}.png").exists():
await update_image()
await material.send(
Message(
image("daily_material.png", "genshin/material")
image(f"{file_name}.png", "genshin/material")
+ "\n※ 每日素材数据来源于 genshin.pub"
)
)
@@ -73,7 +77,6 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
await super_cmd.send(f"更新失败...")
@driver.on_startup
async def update_image():
page = None
try:
@@ -140,7 +143,8 @@ async def update_image():
background_img.paste(x, (current_width, current_height))
current_height += x.size[1]
current_width += 600
background_img.save(f"{IMAGE_PATH}/genshin/material/daily_material.png")
file_name = str((datetime.now() - timedelta(hours=4)).date())
background_img.save(f"{IMAGE_PATH}/genshin/material/{file_name}.png")
await page.close()
return True
except Exception as e:
@@ -163,16 +167,3 @@ def get_background_height(weapons_imgs: List[str]) -> int:
return height
@scheduler.scheduled_job(
"cron",
hour=4,
minute=1,
)
async def _():
for _ in range(5):
try:
await update_image()
logger.info(f"更新每日天赋素材成功...")
break
except Exception as e:
logger.error(f"更新每日天赋素材出错 e:{e}")
@@ -64,7 +64,7 @@ async def get_image(
"affix_level": char["weapon"]["affix_level"],
}
await init_image(char_data_list, _x)
await init_image(char_data_list, _x, home_data_list)
return await get_genshin_image(
user_id,
uid,
@@ -510,11 +510,12 @@ def get_char_data_image(
return region, _h
async def init_image(char_data_list: List[Dict], char_detailed_dict: dict):
async def init_image(char_data_list: List[Dict], char_detailed_dict: dict, home_data_list: List[Dict]):
"""
下载头像
:param char_data_list: 角色列表
:param char_detailed_dict: 角色武器
:param home_data_list: 家园列表
"""
for char in char_data_list:
file = image_path / "chars" / f'{char["name"]}.png'
@@ -528,3 +529,10 @@ async def init_image(char_data_list: List[Dict], char_detailed_dict: dict):
await AsyncHttpx.download_file(
char_detailed_dict[char]["weapon_image"], file
)
for home in home_data_list:
file = image_path / "homes" / f'{home["name"]}.png'
file.parent.mkdir(parents=True, exist_ok=True)
if not file.exists():
await AsyncHttpx.download_file(
home["icon"], file
)
+21 -8
View File
@@ -41,8 +41,19 @@ usage:
示例:塞红包 1000
示例:塞红包 1000 10
""".strip()
__plugin_superuser_usage__ = """
usage:
节日全群红包指令
指令:
节日红包 [金额] [数量] ?[祝福语] ?[指定群]
""".strip()
__plugin_des__ = "运气项目又来了"
__plugin_cmd__ = ["塞红包 [金币数] ?[红包数=5]", "开/抢", "退回"]
__plugin_cmd__ = [
"塞红包 [金币数] ?[红包数=5]",
"开/抢",
"退回",
"节日红包 [金额] [数量] ?[祝福语] ?[指定群] [_superuser]",
]
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {
@@ -51,9 +62,7 @@ __plugin_settings__ = {
"limit_superuser": False,
"cmd": ["金币红包", "塞红包"],
}
__plugin_resources__ = {
"prts": IMAGE_PATH
}
__plugin_resources__ = {"prts": IMAGE_PATH}
gold_redbag = on_command(
"塞红包", aliases={"金币红包"}, priority=5, block=True, permission=GROUP
@@ -143,10 +152,12 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
flag, amount = await check_gold(event.user_id, event.group_id, amount)
if not flag:
await gold_redbag.finish(amount, at_sender=True)
group_member_num = (await bot.get_group_info(group_id=event.group_id))['member_count']
group_member_num = (await bot.get_group_info(group_id=event.group_id))[
"member_count"
]
num = int(num)
if num > group_member_num:
await gold_redbag.send('你发的红包数量也太多了,已经为你修改成与本群人数相同的红包数量...')
await gold_redbag.send("你发的红包数量也太多了,已经为你修改成与本群人数相同的红包数量...")
num = group_member_num
nickname = event.sender.card if event.sender.card else event.sender.nickname
flag, result = init_redbag(
@@ -181,7 +192,7 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
.replace("。", "")
)
if msg:
if '红包' not in msg:
if "红包" not in msg:
return
flag1 = True
flag2 = True
@@ -306,7 +317,9 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
await end_festive_redbag(bot, g)
except JobLookupError:
pass
init_redbag(int(bot.self_id), g, f"{NICKNAME}", amount, num, int(bot.self_id), 1)
init_redbag(
int(bot.self_id), g, f"{NICKNAME}", amount, num, int(bot.self_id), 1
)
scheduler.add_job(
end_festive_redbag,
"date",
@@ -20,7 +20,7 @@ except ModuleNotFoundError:
__zx_plugin_name__ = "本地图库"
__plugin_usage__ = f"""
usage:
发送指定图库下的随机或指定id图片
发送指定图库下的随机或指定id图片genshin_memo
指令:
{Config.get_config("image_management", "IMAGE_DIR_LIST")} ?[id]
示例:美图
@@ -105,7 +105,7 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
path = get_message_imgs(event.json())
if path in Config.get_config("image_management", "IMAGE_DIR_LIST"):
state["path"] = path
await continuous_upload_img.send("图来!!")
await continuous_upload_img.send("图来!!【停止请发送 ‘stop’ 开始上传】")
state["tmp"] = []
+21
View File
@@ -124,6 +124,27 @@ class Setu(db.Model):
).gino.first()
)
@classmethod
async def delete_image(cls, pid: int) -> int:
"""
说明:
删除图片并替换
参数:
:param pid: 图片pid
"""
query = await cls.query.where(cls.pid == pid).gino.first()
if query:
is_r18 = query.is_r18
num = await cls.get_image_count(is_r18)
x = await cls.query.where((cls.is_r18 == is_r18) & (cls.local_id == num - 1)).gino.first()
_tmp_local_id = x.local_id
if x:
x.update(local_id=query.local_id).apply()
await cls.delete.where(cls.pid == pid).gino.status()
return _tmp_local_id
return -1
@classmethod
async def update_setu_data(
cls,
@@ -3,7 +3,7 @@ from services.log import logger
from datetime import datetime
from utils.image_utils import compressed_image, get_img_hash
from utils.utils import get_bot
from asyncio.exceptions import TimeoutError
from PIL import UnidentifiedImageError
from ..model import Setu
from asyncpg.exceptions import UniqueViolationError
from configs.config import Config
@@ -142,6 +142,14 @@ async def update_setu_img():
continue
img_hash = str(get_img_hash(f"{path}/{image.local_id}.jpg"))
await Setu.update_setu_data(image.pid, img_hash=img_hash)
except UnidentifiedImageError:
# 图片已删除
with open(local_image, 'r') as f:
if '404 Not Found' in f.read():
max_num = await Setu.delete_image(image.pid)
local_image.unlink()
os.rename(path / f"{max_num}.jpg", local_image)
logger.warning(f"更新色图 PID:{image.pid} 404,已删除并替换")
except Exception as e:
_success -= 1
logger.error(f"更新色图 {image.local_id}.jpg 错误 {type(e)}: {e}")
+36
View File
@@ -0,0 +1,36 @@
from nonebot import on_command
from nonebot.adapters.cqhttp import Bot, PrivateMessageEvent, GroupMessageEvent
from nonebot.typing import T_State
from nonebot.rule import to_me
__zx_plugin_name__ = "服务器 [Hidden]"
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
server_ip = on_command("服务器", aliases={"ip"}, rule=to_me(), priority=5, block=True)
@server_ip.handle()
async def _(bot: Bot, event: PrivateMessageEvent, state: T_State):
await server_ip.finish(
"|* 请不要发给其他人! *|\n"
"\t121.40.195.22\n"
"|* 请不要发给其他人! *|\n"
"csgo ~号键控制台输入 connect 121.40.195.22 进入服务器\n"
"然后再公屏输入 !diy 来使用皮肤(英文感叹号,注意)\n"
"【说不定可以凑到内战噢,欢迎~{娱乐为主}】",
at_sender=True,
)
@server_ip.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
if event.group_id == 698279647:
await server_ip.finish(
"嗨呀!当前服务器地址是:" "\n\tay: 121.40.195.22" "\n\t夜之北枭: 101.132.170.254"
)
elif event.group_id == 1046451860:
await server_ip.finish("嗨呀!当前服务器地址是:\n121.40.195.22\n !diy")
else:
await server_ip.finish("不好意思呀,小真寻不能为你使用此功能,因为服务器IP是真寻的小秘密呀!", at_sender=True)
-14
View File
@@ -1,14 +0,0 @@
import nonebot
from configs.config import Config
Config.add_plugin_config(
"shop",
"IMPORT_DEFAULT_SHOP_GOODS",
True,
help_="导入商店自带的三个商品",
default_value=True
)
nonebot.load_plugins("plugins/shop")
-89
View File
@@ -1,89 +0,0 @@
from nonebot import on_command
from services.log import logger
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent
from nonebot.typing import T_State
from utils.utils import get_message_text, is_number
from models.bag_user import BagUser
from services.db_context import db
from nonebot.adapters.cqhttp.permission import GROUP
from .models.goods_info import GoodsInfo
__zx_plugin_name__ = "商店 - 购买道具"
__plugin_usage__ = """
usage:
购买道具
指令:
购买 [序号或名称] ?[数量=1]
示例:购买 好感双倍加持卡Ⅰ
示例:购买 1 4
""".strip()
__plugin_des__ = "商店 - 购买道具"
__plugin_cmd__ = ["购买 [序号或名称] ?[数量=1]"]
__plugin_type__ = ('商店',)
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {
"level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ["商店", "购买道具"],
}
buy = on_command("购买", aliases={"购买道具"}, priority=5, block=True, permission=GROUP)
@buy.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
if get_message_text(event.json()) in ["神秘药水"]:
await buy.finish("你们看看就好啦,这是不可能卖给你们的~", at_sender=True)
goods_lst = await GoodsInfo.get_all_goods()
goods_name_lst = [x.goods_name for x in goods_lst]
msg = get_message_text(event.json()).strip().split(" ")
num = 1
if len(msg) > 1:
if is_number(msg[1]) and int(msg[1]) > 0:
num = int(msg[1])
else:
await buy.finish("购买的数量要是数字且大于0!", at_sender=True)
# print(msg, num)
if is_number(msg[0]):
msg = int(msg[0])
if msg > len(goods_lst) or msg < 1:
await buy.finish("请输入正确的商品id!", at_sender=True)
goods = goods_lst[msg - 1]
else:
if msg[0] in goods_name_lst:
for i in range(len(goods_name_lst)):
if msg[0] == goods_name_lst[i]:
goods = goods_lst[i]
break
else:
await buy.finish("请输入正确的商品名称!")
else:
await buy.finish("请输入正确的商品名称!", at_sender=True)
async with db.transaction():
if (
await BagUser.get_gold(event.user_id, event.group_id)
) < goods.goods_price * num:
await buy.finish("您的金币好像不太够哦", at_sender=True)
if await BagUser.spend_gold(
event.user_id, event.group_id, goods.goods_price * num
):
for _ in range(num):
await BagUser.add_props(event.user_id, event.group_id, goods.goods_name)
await buy.send(
f"花费 {goods.goods_price*num} 金币购买 {goods.goods_name} ×{num} 成功!",
at_sender=True,
)
logger.info(
f"USER {event.user_id} GROUP {event.group_id} "
f"花费 {goods.goods_price*num} 金币购买 {goods.goods_name} ×{num} 成功!"
)
else:
await buy.send(f"{goods.goods_name} 购买失败!", at_sender=True)
logger.info(
f"USER {event.user_id} GROUP {event.group_id} "
f"花费 {goods.goods_price*num} 金币购买 {goods.goods_name} ×{num} 失败!"
)
-52
View File
@@ -1,52 +0,0 @@
from nonebot import on_command
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent
from nonebot.typing import T_State
from nonebot.adapters.cqhttp.permission import GROUP
from utils.data_utils import init_rank
from models.bag_user import BagUser
from utils.message_builder import image
from utils.utils import get_message_text, is_number
__zx_plugin_name__ = "商店 - 我的金币"
__plugin_usage__ = """
usage:
我的金币
指令:
我的金币
""".strip()
__plugin_des__ = "商店 - 我的金币"
__plugin_cmd__ = ["我的金币"]
__plugin_type__ = ("商店",)
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {
"level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ["商店", "我的金币"],
}
my_gold = on_command("我的金币", priority=5, block=True, permission=GROUP)
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))
@gold_rank.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
num = get_message_text(event.json())
if is_number(num) and 51 > int(num) > 10:
num = int(num)
else:
num = 10
all_users = await BagUser.get_all_users(event.group_id)
all_user_id = [user.user_qq for user in all_users]
all_user_data = [user.gold for user in all_users]
rank_image = await init_rank("金币排行", all_user_id, all_user_data, event.group_id, num)
if rank_image:
await gold_rank.finish(image(b64=rank_image.pic2bs4()))
-1
View File
@@ -1 +0,0 @@
from .goods_info import *
-129
View File
@@ -1,129 +0,0 @@
from services.db_context import db
from typing import Optional, List
class GoodsInfo(db.Model):
__tablename__ = "goods_info"
id = db.Column(db.Integer(), primary_key=True)
goods_name = db.Column(db.TEXT(), nullable=False) # 名称
goods_price = db.Column(db.Integer(), nullable=False) # 价格
goods_description = db.Column(db.TEXT(), nullable=False) # 商品描述
goods_discount = db.Column(db.Numeric(scale=3, asdecimal=False), default=1) # 打折
goods_limit_time = db.Column(db.BigInteger(), default=0) # 限时
_idx1 = db.Index("goods_group_users_idx1", "goods_name", unique=True)
@classmethod
async def add_goods(
cls,
goods_name: str,
goods_price: int,
goods_description: str,
goods_discount: float = 1,
goods_limit_time: int = 0,
) -> bool:
"""
说明:
添加商品
参数:
:param goods_name: 商品名称
:param goods_price: 商品价格
:param goods_description: 商品简介
:param goods_discount: 商品折扣
:param goods_limit_time: 商品限时
"""
try:
await cls.create(
goods_name=goods_name,
goods_price=goods_price,
goods_description=goods_description,
goods_discount=goods_discount,
goods_limit_time=goods_limit_time,
)
return True
except Exception:
return False
@classmethod
async def delete_goods(cls, goods_name: str) -> bool:
"""
说明:
删除商品
参数:
:param goods_name: 商品名称
"""
query = (
await cls.query.where(cls.goods_name == goods_name)
.with_for_update()
.gino.first()
)
if not query:
return False
await query.delete()
return True
@classmethod
async def update_goods(
cls,
goods_name: str,
goods_price: Optional[int] = None,
goods_description: Optional[str] = None,
goods_discount: Optional[float] = None,
goods_limit_time: Optional[int] = None,
) -> bool:
"""
说明:
更新商品信息
参数:
:param goods_name: 商品名称
:param goods_price: 商品价格
:param goods_description: 商品简介
:param goods_discount: 商品折扣
:param goods_limit_time: 商品限时时间
"""
try:
query = (
await cls.query.where(cls.goods_name == goods_name)
.with_for_update()
.gino.first()
)
if not query:
return False
if goods_price:
await query.update(goods_price=goods_price).apply()
if goods_description:
await query.update(goods_description=goods_description).apply()
if goods_discount:
await query.update(goods_discount=goods_discount).apply()
if goods_limit_time:
await query.update(goods_limit_time=goods_limit_time).apply()
return True
except Exception:
return False
@classmethod
async def get_goods_info(cls, goods_name: str) -> "GoodsInfo":
"""
说明:
获取商品对象
参数:
:param goods_name: 商品名称
"""
query = await cls.query.where(cls.goods_name == goods_name).gino.first()
return query
@classmethod
async def get_all_goods(cls) -> List["GoodsInfo"]:
"""
说明:
获得全部有序商品对象
"""
query = await cls.query.gino.all()
id_lst = [x.id for x in query]
goods_lst = []
for _ in range(len(query)):
min_id = min(id_lst)
goods_lst.append([x for x in query if x.id == min_id][0])
id_lst.remove(min_id)
return goods_lst
-52
View File
@@ -1,52 +0,0 @@
from nonebot import on_command
from services.log import logger
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent
from nonebot.typing import T_State
from models.bag_user import BagUser
from nonebot.adapters.cqhttp.permission import GROUP
__zx_plugin_name__ = "商店 - 我的道具"
__plugin_usage__ = """
usage:
我的道具
指令:
我的道具
""".strip()
__plugin_des__ = "商店 - 我的道具"
__plugin_cmd__ = ["我的道具"]
__plugin_type__ = ('商店',)
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {
"level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ["商店", "我的道具"],
}
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)
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"
await my_props.send("\n" + rst[:-1], at_sender=True)
logger.info(f"USER {event.user_id} GROUP {event.group_id} 查看我的道具")
else:
await my_props.finish("您的背包里没有任何的道具噢~", at_sender=True)
-26
View File
@@ -1,26 +0,0 @@
from utils.utils import scheduler
from models.bag_user import BagUser
from services.log import logger
__zx_plugin_name__ = "每日金币重置 [Hidden]"
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
# 重置每日金币
@scheduler.scheduled_job(
"cron",
hour=0,
minute=1,
)
async def _():
try:
user_list = await BagUser.get_all_users()
for user in user_list:
await user.update(
get_today_gold=0,
spend_today_gold=0,
).apply()
except Exception as e:
logger.error(f"重置每日金币错误 e:{e}")
-154
View File
@@ -1,154 +0,0 @@
from nonebot import on_command
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, add_goods, del_goods, update_goods
from nonebot.permission import SUPERUSER
from utils.utils import get_message_text, is_number
from services.log import logger
import os
import time
__zx_plugin_name__ = "商店"
__plugin_usage__ = """
usage:
商店项目,这可不是奸商
指令:
商店
""".strip()
__plugin_superuser_usage__ = """
usage:
商品操作
指令:
添加商品 [名称]-[价格]-[描述]-?[折扣](小数)-?[限时时间](分钟)
删除商品 [名称或序号]
修改商品 -name [名称或序号] -price [价格] -des [描述] -discount [折扣] -time [限时]
示例:添加商品-昏睡红茶-300-一杯上好的奇怪红茶-0.9-60
示例:删除商品 2
示例:修改商品 -name 1 -price 900: 修改序号为1的商品的价格为900
* 修改商品只需添加需要值即可 *
""".strip()
__plugin_des__ = "商店系统[金币回收计划]"
__plugin_cmd__ = [
"商店",
"添加商品 [名称]-[价格]-[描述]-?[折扣](小数)-?[限时时间](分钟) [_superuser]",
"删除商品 [名称或序号] [_superuser]",
"修改商品 -name [名称或序号] -price [价格] -des [描述] -discount [折扣] -time [限时] [_superuser]",
]
__plugin_type__ = ('商店',)
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {
"level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ["商店"],
}
shop_help = on_command("商店", priority=5, block=True)
shop_add_goods = on_command("添加商品", priority=5, permission=SUPERUSER, block=True)
shop_del_goods = on_command("删除商品", priority=5, permission=SUPERUSER, block=True)
shop_update_goods = on_command("修改商品", priority=5, permission=SUPERUSER, block=True)
@shop_help.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
if not os.path.exists(f"{IMAGE_PATH}/shop_help.png"):
await create_shop_help()
await shop_help.send(image("shop_help.png"))
@shop_add_goods.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = get_message_text(event.json())
if msg:
msg = msg.split("-")
if len(msg) < 3:
await shop_add_goods.finish("商品参数不完全...", at_sender=True)
if not is_number(msg[1]):
await shop_add_goods.finish("商品的价格必须是合法数字!", at_sender=True)
msg[1] = int(msg[1])
if len(msg) > 3:
if not is_number(msg[3]):
await shop_add_goods.finish("商品的折扣要小数啊!", at_sender=True)
msg[3] = float(msg[3])
if len(msg) > 4:
if not is_number(msg[4]):
await shop_add_goods.finish("商品的限时时间是要写多少分钟噢!", at_sender=True)
msg[4] = time.time() + int(msg[4]) * 60
if await add_goods(msg):
await shop_add_goods.send(f"添加商品 {msg[0]} 成功...", at_sender=True)
if os.path.exists(f"{IMAGE_PATH}/shop_help.png"):
os.remove(f"{IMAGE_PATH}/shop_help.png")
logger.info(f"USER {event.user_id} 上传商品 {msg} 成功")
else:
await shop_add_goods.send(f"添加商品 {msg[0]} 失败了...", at_sender=True)
logger.warning(f"USER {event.user_id} 上传商品 {msg} 失败")
@shop_del_goods.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = get_message_text(event.json())
if msg:
name = ""
id_ = 0
if is_number(msg):
id_ = int(msg)
else:
name = msg
rst, goods_name, code = await del_goods(name, id_)
if code == 200:
await shop_del_goods.send(f"删除商品 {goods_name} 成功了...", at_sender=True)
if os.path.exists(f"{IMAGE_PATH}/shop_help.png"):
os.remove(f"{IMAGE_PATH}/shop_help.png")
logger.info(f"USER {event.user_id} 删除商品 {goods_name} 成功")
else:
await shop_del_goods.send(f"删除商品 {goods_name} 失败了...", at_sender=True)
logger.info(f"USER {event.user_id} 删除商品 {goods_name} 失败")
@shop_update_goods.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = get_message_text(event.json())
if msg:
tmp = {}
msg = msg.split("-")
for x in msg:
if x.find("name") != -1:
tmp["name"] = x.split(" ")[1].strip()
elif x.find("price") != -1:
tmp["price"] = x.split(" ")[1].strip()
if not is_number(tmp["price"]):
await shop_update_goods.finish("价格必须是数字啊!", at_sender=True)
tmp["price"] = int(tmp["price"])
elif x.find("des") != -1:
tmp["des"] = x.split(" ")[1].strip()
elif x.find("discount") != -1:
tmp["discount"] = x.split(" ")[1].strip()
if not is_number(tmp["discount"]):
await shop_update_goods.finish("折扣必须是数字啊!", at_sender=True)
tmp["discount"] = float(tmp["discount"])
elif x.find("time") != -1:
tmp["time"] = x.split(" ")[1].strip()
if not is_number(tmp["time"]):
await shop_update_goods.finish("限时时间必须是数字啊!", at_sender=True)
tmp["time"] = time.time() + tmp["time"] * 60
if not tmp.get("name"):
await shop_update_goods.finish("未指定商品名称(序号也可)!", at_sender=True)
if is_number(tmp["name"]):
tmp["name"] = int(tmp["name"])
flag, name, text = await update_goods(tmp)
if flag:
await shop_update_goods.send(f"修改商品 {name} 成功了...\n{text}", at_sender=True)
if os.path.exists(f"{IMAGE_PATH}/shop_help.png"):
os.remove(f"{IMAGE_PATH}/shop_help.png")
logger.info(f"USER {event.user_id} 修改商品 {name} 数据 {tmp} 成功")
else:
await shop_update_goods.send(f"修改商品 {name} 失败了...", at_sender=True)
logger.info(f"USER {event.user_id} 修改商品 {name} 数据 {tmp} 失败")
-126
View File
@@ -1,126 +0,0 @@
from ..models.goods_info import GoodsInfo
from utils.image_utils import BuildImage
from utils.utils import is_number
from configs.path_config import IMAGE_PATH
from configs.config import Config
from nonebot import Driver
import nonebot
import time
import os
driver: Driver = nonebot.get_driver()
# 导入内置商品 | 重新生成商店图片
@driver.on_startup
async def init_default_shop_goods():
if os.path.exists(f"{IMAGE_PATH}/shop_help.png"):
os.remove(f"{IMAGE_PATH}/shop_help.png")
if Config.get_config("shop", "IMPORT_DEFAULT_SHOP_GOODS"):
await add_goods(["好感度双倍加持卡Ⅰ", 30, "下次签到双倍好感度概率 + 10%(谁才是真命天子?)(同类商品将覆盖)"])
await add_goods(["好感度双倍加持卡Ⅱ", 150, "下次签到双倍好感度概率 + 20%(平平庸庸)(同类商品将覆盖)"])
await add_goods(["好感度双倍加持卡Ⅲ", 250, "下次签到双倍好感度概率 + 30%(金币才是真命天子!)(同类商品将覆盖)"])
# 创建商店界面
async def create_shop_help():
goods_lst = await GoodsInfo.get_all_goods()
tmp = ""
idx = 1
for goods in goods_lst:
tmp += (
f"{idx}.{goods.goods_name}\t\t售价:{goods.goods_price}金币\n"
f"\t\t{goods.goods_description}\n"
)
idx += 1
w = 1000
h = 400 + len(goods_lst) * 40
h = 1000 if h < 1000 else h
shop_logo = BuildImage(100, 100, background=f"{IMAGE_PATH}/other/shop_text.png")
shop = BuildImage(w, h, font_size=20)
zhenxun_img = BuildImage(525, 581, background=f"{IMAGE_PATH}/zhenxun/toukan_2.png")
shop.paste(zhenxun_img, (780, 100))
shop.paste(shop_logo, (450, 30), True)
shop.text(
(int((1000 - shop.getsize("注【通过 序号 或者 商品名称 购买】")[0]) / 2), 170),
"注【通过 序号 或者 商品名称 购买】",
)
shop.text((20, 230), tmp[:-1])
shop.text((20, h - 100), "神秘药水\t\t售价:9999999金币\n\t\t鬼知道会有什么效果~")
shop.save(f"{IMAGE_PATH}/shop_help.png")
# 添加商品
async def add_goods(msg: list):
data = {
"名称": None,
"价格": None,
"描述": None,
"折扣": 1,
"限时": 0,
}
keys = list(data.keys())
idx = 0
for x in msg:
data[keys[idx]] = x
idx += 1
return await GoodsInfo.add_goods(
data["名称"], data["价格"], data["描述"], data["折扣"], data["限时"]
)
# 删除商品
async def del_goods(name: str, id_: int):
goods_lst = await GoodsInfo.get_all_goods()
if id_:
if id_ < 1 or id_ > len(goods_lst):
return "序号错误,没有该序号商品...", "", 999
goods_name = goods_lst[id_ - 1].goods_name
if await GoodsInfo.delete_goods(goods_name):
return f"删除商品 {goods_name} 成功!", goods_name, 200
else:
return f"删除商品 {goods_name} 失败!", goods_name, 999
if name:
if await GoodsInfo.delete_goods(name):
return f"删除商品 {name} 成功!", name, 200
else:
return f"删除商品 {name} 失败!", name, 999
# 更新商品信息
async def update_goods(data: dict):
goods_lst = await GoodsInfo.get_all_goods()
if is_number(data["name"]):
if data["name"] < 1 or data["name"] > len(goods_lst):
return "序号错误,没有该序号的商品...", "", 999
goods = goods_lst[data["name"] - 1]
else:
goods = await GoodsInfo.get_goods_info(data["name"])
if not goods:
return "名称错误,没有该名称的商品...", "", 999
name = goods.goods_name
price = goods.goods_price
des = goods.goods_description
discount = goods.goods_discount
limit_time = goods.goods_limit_time
tmp = ""
if data.get("price"):
tmp += f'价格:{price} --> {data["price"]}\n'
price = data["price"]
if data.get("des"):
tmp += f'描述:{des} --> {data["des"]}\n'
des = data["des"]
if data.get("discount"):
tmp += f'折扣:{discount} --> {data["discount"]}\n'
discount = data["discount"]
if data.get("time"):
old_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(limit_time))
new_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(data["time"]))
tmp += f"折扣:{old_time} --> {new_time}\n"
limit_time = data["time"]
return (
await GoodsInfo.update_goods(name, price, des, discount, limit_time),
name,
tmp[:-1],
)
-71
View File
@@ -1,71 +0,0 @@
from nonebot import on_command
from services.log import logger
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent
from nonebot.typing import T_State
from utils.utils import is_number, get_message_text
from models.bag_user import BagUser
from nonebot.adapters.cqhttp.permission import GROUP
from services.db_context import db
from .data_source import effect
__zx_plugin_name__ = "商店 - 使用道具"
__plugin_usage__ = """
usage:
普通的使用道具
指令:
使用道具 [序号或道具名称]
* 序号以 ”我的道具“ 为准 *
""".strip()
__plugin_des__ = "商店 - 使用道具"
__plugin_cmd__ = ["使用道具 [序号或道具名称]"]
__plugin_type__ = ('商店',)
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {
"level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ["商店", "使用道具"],
}
use_props = on_command("使用道具", priority=5, block=True, permission=GROUP)
@use_props.handle()
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:
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]
else:
await use_props.finish("仔细看看自己的道具仓库有没有这个道具?", at_sender=True)
else:
if msg not in pname_list:
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)
logger.info(
f"USER {event.user_id} GROUP {event.group_id} 使用道具 {name} 成功"
)
else:
await use_props.send(f"使用道具 {name} 失败!", at_sender=True)
logger.info(
f"USER {event.user_id} GROUP {event.group_id} 使用道具 {name} 失败"
)
else:
await use_props.send("您的背包里没有任何的道具噢~", at_sender=True)
-14
View File
@@ -1,14 +0,0 @@
from models.sign_group_user import SignGroupUser
async def effect(user_id: int, group_id: int, name: str) -> bool:
if name in ["好感双倍加持卡Ⅰ", "好感度双倍加持卡Ⅰ"]:
user = await SignGroupUser.ensure(user_id, group_id)
await user.update(add_probability=0.1).apply()
if name in ["好感双倍加持卡Ⅱ", "好感度双倍加持卡Ⅱ"]:
user = await SignGroupUser.ensure(user_id, group_id)
await user.update(add_probability=0.2).apply()
if name in ["好感双倍加持卡Ⅲ", "好感度双倍加持卡Ⅲ"]:
user = await SignGroupUser.ensure(user_id, group_id)
await user.update(add_probability=0.3).apply()
return True
+2 -2
View File
@@ -28,14 +28,14 @@ usage:
每日签到
会影响色图概率和开箱次数,以及签到的随机道具获取
指令:
签到
签到 ?[all]: all代表签到所有群
我的签到
好感度排行
好感度总排行
* 签到时有 3% 概率 * 2 *
""".strip()
__plugin_des__ = "每日签到,证明你在这里"
__plugin_cmd__ = ["签到", "我的签到", "好感度排行", "好感度总排行"]
__plugin_cmd__ = ["签到 ?[all]", "我的签到", "好感度排行", "好感度总排行"]
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {
+1 -1
View File
@@ -59,7 +59,7 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
await yiqing.send(rely)
logger.info(
f"(USER {event.user_id}, GROUP "
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) 查询疫情失败"
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) 查询疫情成功"
)
else:
await yiqing.send(f"{NICKNAME}没有查到{msg}的疫情查询...")
+30 -25
View File
@@ -1,7 +1,10 @@
from configs.path_config import TEXT_PATH
from typing import List
from typing import List, Union
from pathlib import Path
from utils.http_utils import AsyncHttpx
from utils.image_utils import text2image
from utils.message_builder import image
from nonebot.adapters.cqhttp import MessageSegment
import ujson as json
china_city = Path(TEXT_PATH) / "china_city.json"
@@ -12,7 +15,7 @@ data = {}
url = "https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5"
async def get_yiqing_data(area: str):
async def get_yiqing_data(area: str) -> Union[str, MessageSegment]:
"""
查看疫情数据
:param area: 省份/城市
@@ -40,16 +43,16 @@ async def get_yiqing_data(area: str):
if area == "中国":
data_ = epidemic_data["areaTree"][0]
else:
data_ = [
x
for x in epidemic_data["areaTree"][0]["children"]
if x["name"] == province
][0]
if city:
try:
try:
data_ = [
x
for x in epidemic_data["areaTree"][0]["children"]
if x["name"] == province
][0]
if city:
data_ = [x for x in data_["children"] if x["name"] == city][0]
except IndexError:
return "未查询到..."
except IndexError:
return "未查询到..."
confirm = data_["total"]["confirm"] # 累计确诊
heal = data_["total"]["heal"] # 累计治愈
dead = data_["total"]["dead"] # 累计死亡
@@ -59,20 +62,22 @@ async def get_yiqing_data(area: str):
suspect = data_["total"]["suspect"] # 疑似
add_confirm = data_["today"]["confirm"] # 新增确诊
x = f"{city}市" if city else f"{province}{province_type}"
return (
f"{x} 疫情数据:\n"
f"\t目前确诊:\n"
f"\t\t确诊人数:{now_confirm}(+{add_confirm})\n"
f"\t\t疑似人数:{suspect}\n"
f"==================\n"
f"\t累计数据:\n"
f"\t\t确诊人数:{confirm}\n"
f"\t\t治愈人数:{heal}\n"
f"\t\t死亡人数:{dead}\n"
f"\t治愈率:{heal_rate}%\n"
f"\t死亡率:{dead_rate}%\n"
f"更新日期:{last_update_time}"
)
return image(b64=await text2image(
f"""
{x} 疫情数据:
目前确诊:
确诊人数:<f font_color=red>{now_confirm}(+{add_confirm})</f>
疑似人数:{suspect}
-----------------
累计数据:
确诊人数:<f font_color=red>{confirm}</f>
治愈人数:<f font_color=#39de4b>{heal}</f>
死亡人数:<f font_color=#191d19>{dead}</f>
治愈率:{heal_rate}%
死亡率:{dead_rate}%
更新日期:{last_update_time}
""", font_size=30, color="#f9f6f2"
))
def get_city_and_province_list() -> List[str]:
+43 -23
View File
@@ -6,8 +6,12 @@
# @File : other_than.py
# @Software: PyCharm
from utils.http_utils import AsyncHttpx
from nonebot.adapters.cqhttp import MessageSegment
from typing import Optional
from services.log import logger
from utils.image_utils import text2image
from utils.message_builder import image
from json.decoder import JSONDecodeError
import re
import json
@@ -23,50 +27,66 @@ def intcomma(value) -> str:
return new if orig == new else intcomma(new)
async def get_other_data(place: str) -> Optional[str]:
async def get_other_data(place: str, count: int = 0) -> Optional[MessageSegment]:
"""
:param place: 地名
:param count: 递归次数
:return: 格式化字符串
"""
if count == 5:
return None
try:
html = (
(await AsyncHttpx.get("https://news.ifeng.com/c/special/7uLj4F83Cqm"))
.text.replace("\n", "")
.replace(" ", "")
)
find_data = re.compile(r"varallData=(.*?);</script>")
sum_ = re.findall(find_data, html)[0]
sum_ = json.loads(sum_)
except JSONDecodeError:
return await get_other_data(place, count + 1)
except Exception as e:
logger.error(f"疫情查询发生错误 {type(e)}:{e}")
return None
find_data = re.compile(r"varallData=(.*?);</script>")
sum_ = re.findall(find_data, html)[0]
try:
sum_ = json.loads(sum_)
other_country = sum_["yiqing_v2"]["dataList"][29]["child"]
for country in other_country:
if place == country["name2"]:
return (
f"{place} 疫情数据:\n"
"——————————————\n"
f"新增病例:{intcomma(country['quezhen_add'])}\n"
f"现有确诊:{intcomma(country['quezhen_xianyou'])}\n"
f"累计确诊:{intcomma(country['quezhen'])}\n"
f"累计治愈:{intcomma(country['zhiyu'])}\n"
f"死亡:{intcomma(country['siwang'])}\n"
"——————————————"
# f"更新时间:{country['sys_publishDateTime']}"
# 时间无法精确到分钟,网页用了js我暂时找不到
return image(
b64=await text2image(
f" {place} 疫情数据:\n"
"——————————————\n"
f" 新增病例:<f font_color=red>{intcomma(country['quezhen_add'])}</f>\n"
f" 现有确诊:<f font_color=red>{intcomma(country['quezhen_xianyou'])}</f>\n"
f" 累计确诊:<f font_color=red>{intcomma(country['quezhen'])}</f>\n"
f" 累计治愈:<f font_color=#39de4b>{intcomma(country['zhiyu'])}</f>\n"
f" 死亡:{intcomma(country['siwang'])}\n"
"——————————————"
# f"更新时间:{country['sys_publishDateTime']}"
# 时间无法精确到分钟,网页用了js我暂时找不到
,
font_size=30,
color="#f9f6f2",
padding=15
)
)
else:
for city in country["child"]:
if place == city["name3"]:
return (
f"{place} 疫情数据:\n"
"——————————————\n"
f"新增病例:{intcomma(city['quezhen_add'])}\n"
f"累计确诊:{intcomma(city['quezhen'])}\n"
f"累计治愈:{intcomma(city['zhiyu'])}\n"
f"死亡:{intcomma(city['siwang'])}\n"
"——————————————"
return image(
b64=await text2image(
f"\n{place} 疫情数据:\n"
"——————————————\n"
f"\t新增病例:<f font_color=red>{intcomma(city['quezhen_add'])}</f>\n"
f"\t累计确诊:<f font_color=red>{intcomma(city['quezhen'])}</f>\n"
f"\t累计治愈:<f font_color=#39de4b>{intcomma(city['zhiyu'])}</f>\n"
f"\t死亡:{intcomma(city['siwang'])}\n"
"——————————————\n",
font_size=30,
color="#f9f6f2",
padding=15
)
)
except Exception as e:
logger.error(f"疫情查询发生错误 {type(e)}:{e}")