mirror of
https://github.com/zhenxun-org/zhenxun_bot.git
synced 2025-12-14 21:52:56 +08:00
更新开箱指令
This commit is contained in:
parent
5b9218251e
commit
a43a7b5f75
@ -5,6 +5,7 @@ from tortoise import fields
|
||||
|
||||
from configs.config import Config
|
||||
from services.db_context import Model
|
||||
from services.log import logger
|
||||
|
||||
|
||||
class GroupInfoUser(Model):
|
||||
@ -39,7 +40,7 @@ class GroupInfoUser(Model):
|
||||
"""
|
||||
return set(
|
||||
await cls.filter(group_id=group_id).values_list("user_qq", flat=True)
|
||||
)
|
||||
) # type: ignore
|
||||
|
||||
@classmethod
|
||||
async def set_user_nickname(cls, user_qq: int, group_id: int, nickname: str):
|
||||
@ -67,7 +68,7 @@ class GroupInfoUser(Model):
|
||||
"""
|
||||
return list(
|
||||
await cls.filter(user_qq=user_qq).values_list("group_id", flat=True)
|
||||
)
|
||||
) # type: ignore
|
||||
|
||||
@classmethod
|
||||
async def get_user_nickname(cls, user_qq: int, group_id: int) -> str:
|
||||
@ -90,6 +91,9 @@ class GroupInfoUser(Model):
|
||||
|
||||
@classmethod
|
||||
async def get_group_member_uid(cls, user_qq: int, group_id: int) -> Optional[int]:
|
||||
logger.debug(
|
||||
f"GroupInfoUser 尝试获取 用户[<u><e>{user_qq}</e></u>] 群聊[<u><e>{group_id}</e></u>] UID"
|
||||
)
|
||||
user, _ = await cls.get_or_create(user_qq=user_qq, group_id=group_id)
|
||||
_max_uid_user, _ = await cls.get_or_create(user_qq=114514, group_id=114514)
|
||||
_max_uid = _max_uid_user.uid
|
||||
@ -101,6 +105,9 @@ class GroupInfoUser(Model):
|
||||
user.uid = _max_uid + 1
|
||||
_max_uid_user.uid = _max_uid + 1
|
||||
await cls.bulk_update([user, _max_uid_user], ["uid"])
|
||||
logger.debug(
|
||||
f"GroupInfoUser 获取 用户[<u><e>{user_qq}</e></u>] 群聊[<u><e>{group_id}</e></u>] UID: {user.uid}"
|
||||
)
|
||||
return user.uid
|
||||
|
||||
@classmethod
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
import asyncio
|
||||
import random
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Any, List, Tuple
|
||||
|
||||
from nonebot import on_command
|
||||
@ -12,17 +14,25 @@ from nonebot.typing import T_State
|
||||
|
||||
from configs.config import Config
|
||||
from configs.path_config import IMAGE_PATH
|
||||
from utils.utils import is_number, scheduler
|
||||
from services.log import logger
|
||||
from utils.message_builder import image
|
||||
from utils.utils import CN2NUM, is_number, scheduler
|
||||
|
||||
from .open_cases_c import (
|
||||
auto_update,
|
||||
get_my_knifes,
|
||||
group_statistics,
|
||||
open_case,
|
||||
open_multiple_case,
|
||||
total_open_statistics,
|
||||
update,
|
||||
)
|
||||
from .utils import CASE2ID, CaseManager, reset_count_daily, update_case_data
|
||||
from .utils import (
|
||||
CASE2ID,
|
||||
CaseManager,
|
||||
build_case_image,
|
||||
reset_count_daily,
|
||||
update_case_data,
|
||||
)
|
||||
|
||||
__zx_plugin_name__ = "开箱"
|
||||
__plugin_usage__ = """
|
||||
@ -35,14 +45,10 @@ usage:
|
||||
我的开箱
|
||||
我的金色
|
||||
群开箱统计
|
||||
查看武器箱?[武器箱]
|
||||
* 不包含[武器箱]时随机开箱 *
|
||||
目前支持的武器箱:
|
||||
1.狂牙大行动武器箱
|
||||
2.突围大行动武器箱
|
||||
3.命悬一线武器箱
|
||||
4.裂空武器箱
|
||||
5.光谱武器箱
|
||||
示例:开箱 命悬一线
|
||||
示例: 查看武器箱
|
||||
示例: 查看武器箱英勇
|
||||
""".strip()
|
||||
__plugin_superuser_usage__ = """
|
||||
usage:
|
||||
@ -61,6 +67,7 @@ __plugin_cmd__ = [
|
||||
"我的开箱",
|
||||
"我的金色",
|
||||
"群开箱统计",
|
||||
"查看武器箱?[武器箱]",
|
||||
"更新开箱图片 ?[武器箱] [_superuser]",
|
||||
"更新开箱价格 ?[武器箱] [_superuser]",
|
||||
]
|
||||
@ -89,10 +96,7 @@ __plugin_configs__ = {
|
||||
"default_value": 3,
|
||||
"type": int,
|
||||
},
|
||||
"COOKIE": {
|
||||
"value": None,
|
||||
"help": "BUFF的cookie",
|
||||
},
|
||||
"COOKIE": {"value": None, "help": "BUFF的cookie", "type": str},
|
||||
"BUFF_PROXY": {"value": None, "help": "使用代理访问BUFF"},
|
||||
"DAILY_UPDATE": {
|
||||
"value": None,
|
||||
@ -121,8 +125,11 @@ total_case_data = cases_matcher_group.on_command(
|
||||
)
|
||||
group_open_case_statistics = cases_matcher_group.on_command("群开箱统计")
|
||||
open_multiple = cases_matcher_group.on_regex("(.*)连开箱(.*)?")
|
||||
update_data = on_command("更新武器箱", priority=1, permission=SUPERUSER, block=True)
|
||||
update_case = on_command("更新武器箱", priority=1, permission=SUPERUSER, block=True)
|
||||
show_case = on_command("查看武器箱", priority=5, block=True)
|
||||
my_knifes = on_command("我的金色", priority=1, permission=GROUP, block=True)
|
||||
show_skin = on_command("查看皮肤", priority=5, block=True)
|
||||
# show_case = on_command("test", priority=1, permission=GROUP, block=True)
|
||||
|
||||
|
||||
@reload_count.handle()
|
||||
@ -163,9 +170,9 @@ async def _(
|
||||
event: GroupMessageEvent, state: T_State, reg_group: Tuple[Any, ...] = RegexGroup()
|
||||
):
|
||||
num, case_name = reg_group
|
||||
if is_number(num) or num_dict.get(num):
|
||||
if is_number(num) or CN2NUM.get(num):
|
||||
try:
|
||||
num = num_dict[num]
|
||||
num = CN2NUM[num]
|
||||
except KeyError:
|
||||
num = int(num)
|
||||
if num > 30:
|
||||
@ -181,41 +188,7 @@ async def _(
|
||||
)
|
||||
|
||||
|
||||
num_dict = {
|
||||
"一": 1,
|
||||
"二": 2,
|
||||
"三": 3,
|
||||
"四": 4,
|
||||
"五": 5,
|
||||
"六": 6,
|
||||
"七": 7,
|
||||
"八": 8,
|
||||
"九": 9,
|
||||
"十": 10,
|
||||
"十一": 11,
|
||||
"十二": 12,
|
||||
"十三": 13,
|
||||
"十四": 14,
|
||||
"十五": 15,
|
||||
"十六": 16,
|
||||
"十七": 17,
|
||||
"十八": 18,
|
||||
"十九": 19,
|
||||
"二十": 20,
|
||||
"二十一": 21,
|
||||
"二十二": 22,
|
||||
"二十三": 23,
|
||||
"二十四": 24,
|
||||
"二十五": 25,
|
||||
"二十六": 26,
|
||||
"二十七": 27,
|
||||
"二十八": 28,
|
||||
"二十九": 29,
|
||||
"三十": 30,
|
||||
}
|
||||
|
||||
|
||||
@update_data.handle()
|
||||
@update_case.handle()
|
||||
async def _(event: MessageEvent, arg: Message = CommandArg()):
|
||||
msg = arg.extract_plain_text().strip()
|
||||
if not msg:
|
||||
@ -225,9 +198,38 @@ async def _(event: MessageEvent, arg: Message = CommandArg()):
|
||||
case_list.append(f"{i+1}.{case_name} [已更新]")
|
||||
else:
|
||||
case_list.append(f"{i+1}.{case_name}")
|
||||
await update_data.finish("未指定武器箱, 当前已包含武器箱\n" + "\n".join(case_list))
|
||||
await update_data.send(f"开始更新武器箱: {msg}, 请稍等")
|
||||
await update_data.send(await update_case_data(msg), at_sender=True)
|
||||
await update_case.finish("未指定武器箱, 当前已包含武器箱\n" + "\n".join(case_list))
|
||||
if msg == "ALL":
|
||||
await update_case.send(f"即将更新所有武器箱, 请稍等")
|
||||
case_list = list(CASE2ID.keys())
|
||||
for i, case_name in enumerate(case_list):
|
||||
try:
|
||||
await update_case_data(case_name)
|
||||
rand = random.randint(300, 500)
|
||||
result = "更新全部武器箱完成"
|
||||
if i < len(case_list):
|
||||
next_case = case_list[i + 1]
|
||||
result = f"将在 {rand} 秒后更新下一武器箱: {next_case}"
|
||||
await update_case.send(f"成功更新武器箱: {case_name}, {result}")
|
||||
logger.info(f"成功更新武器箱: {case_name}, {result}", "更新武器箱")
|
||||
await asyncio.sleep(rand)
|
||||
except Exception as e:
|
||||
logger.error(f"自动更新武器箱: {case_name}", e=e)
|
||||
await update_case.send(f"成功自动更新武器箱: {case_name} 发生错误: {type(e)}: {e}")
|
||||
await update_case.send(f"开始更新全部武器箱完成")
|
||||
else:
|
||||
await update_case.send(f"开始更新武器箱: {msg}, 请稍等")
|
||||
await update_case.send(await update_case_data(msg), at_sender=True)
|
||||
|
||||
|
||||
@show_case.handle()
|
||||
async def _(arg: Message = CommandArg()):
|
||||
msg = arg.extract_plain_text().strip()
|
||||
result = await build_case_image(msg)
|
||||
if isinstance(result, str):
|
||||
await show_case.send(result)
|
||||
else:
|
||||
await show_case.send(image(result))
|
||||
|
||||
|
||||
# 重置开箱
|
||||
@ -238,3 +240,21 @@ async def _(event: MessageEvent, arg: Message = CommandArg()):
|
||||
)
|
||||
async def _():
|
||||
await reset_count_daily()
|
||||
|
||||
|
||||
@scheduler.scheduled_job(
|
||||
"cron",
|
||||
hour=23,
|
||||
minute=48,
|
||||
)
|
||||
async def _():
|
||||
now = datetime.now()
|
||||
hour = random.choice([0, 1, 2, 3])
|
||||
date = now + timedelta(minutes=1)
|
||||
logger.debug(f"将在 {date} 时自动更新武器箱...", "更新武器箱")
|
||||
scheduler.add_job(
|
||||
auto_update,
|
||||
"date",
|
||||
run_date=date.replace(microsecond=0),
|
||||
id=f"auto_update_csgo_cases",
|
||||
)
|
||||
|
||||
94
plugins/open_cases/build_image.py
Normal file
94
plugins/open_cases/build_image.py
Normal file
@ -0,0 +1,94 @@
|
||||
from datetime import timedelta, timezone
|
||||
from typing import Optional
|
||||
|
||||
from configs.path_config import IMAGE_PATH
|
||||
from services.log import logger
|
||||
from utils.image_utils import BuildImage
|
||||
from utils.utils import cn2py
|
||||
|
||||
from .config import COLOR2COLOR, COLOR2NAME
|
||||
from .models.buff_skin import BuffSkin
|
||||
|
||||
BASE_PATH = IMAGE_PATH / "csgo_cases"
|
||||
|
||||
ICON_PATH = IMAGE_PATH / "_icon"
|
||||
|
||||
|
||||
async def generate_skin(skin: BuffSkin) -> Optional[BuildImage]:
|
||||
"""构造皮肤图片
|
||||
|
||||
Args:
|
||||
skin (BuffSkin): BuffSkin
|
||||
|
||||
Returns:
|
||||
Optional[BuildImage]: 图片
|
||||
"""
|
||||
name = skin.name + "-" + skin.skin_name + "-" + skin.abrasion
|
||||
file_path = BASE_PATH / cn2py(skin.case_name) / f"{cn2py(name)}.jpg"
|
||||
if not file_path.exists():
|
||||
logger.warning(f"皮肤图片: {name} 不存在", "查看武器箱")
|
||||
return None
|
||||
if skin.color == "CASE":
|
||||
skin_img = BuildImage(200, 200, background=file_path)
|
||||
case_bk = BuildImage(
|
||||
700, 200, color=(25, 25, 25, 100), font_size=25, font="CJGaoDeGuo.otf"
|
||||
)
|
||||
await case_bk.apaste(skin_img, (10, 10), True)
|
||||
await case_bk.aline((250, 10, 250, 190))
|
||||
await case_bk.aline((280, 160, 660, 160))
|
||||
name_icon = BuildImage(30, 30, background=ICON_PATH / "box_white.png")
|
||||
await case_bk.apaste(name_icon, (260, 25), True)
|
||||
await case_bk.atext((295, 30), "名称:", (255, 255, 255))
|
||||
await case_bk.atext((345, 25), skin.case_name, (255, 0, 38), font_size=30)
|
||||
|
||||
type_icon = BuildImage(30, 30, background=ICON_PATH / "type_white.png")
|
||||
await case_bk.apaste(type_icon, (260, 70), True)
|
||||
await case_bk.atext((295, 75), "类型:", (255, 255, 255))
|
||||
await case_bk.atext((345, 72), "武器箱", (0, 157, 255), font_size=30)
|
||||
|
||||
price_icon = BuildImage(30, 30, background=ICON_PATH / "price_white.png")
|
||||
await case_bk.apaste(price_icon, (260, 114), True)
|
||||
await case_bk.atext((295, 120), "单价:", (255, 255, 255))
|
||||
await case_bk.atext(
|
||||
(340, 116), str(skin.sell_min_price), (0, 255, 98), font_size=30
|
||||
)
|
||||
|
||||
price_icon = BuildImage(30, 30, background=ICON_PATH / "num_white.png")
|
||||
await case_bk.apaste(price_icon, (455, 70), True)
|
||||
await case_bk.atext((490, 75), "在售:", (255, 255, 255))
|
||||
await case_bk.atext((535, 72), str(skin.sell_num), (144, 0, 255), font_size=30)
|
||||
|
||||
price_icon = BuildImage(30, 30, background=ICON_PATH / "want_buy_white.png")
|
||||
await case_bk.apaste(price_icon, (455, 114), True)
|
||||
await case_bk.atext((490, 120), "求购:", (255, 255, 255))
|
||||
await case_bk.atext((535, 116), str(skin.buy_num), (144, 0, 255), font_size=30)
|
||||
|
||||
await case_bk.atext((275, 165), "更新时间", (255, 255, 255), font_size=22)
|
||||
date = str(
|
||||
skin.update_time.replace(microsecond=0).astimezone(
|
||||
timezone(timedelta(hours=8))
|
||||
)
|
||||
).split("+")[0]
|
||||
await case_bk.atext(
|
||||
(344, 170),
|
||||
date,
|
||||
(255, 255, 255),
|
||||
font_size=30,
|
||||
)
|
||||
return case_bk
|
||||
else:
|
||||
skin_bk = BuildImage(
|
||||
235, 250, color=(25, 25, 25, 100), font_size=25, font="CJGaoDeGuo.otf"
|
||||
)
|
||||
skin_image = BuildImage(205, 153, background=file_path)
|
||||
skin_bk.paste(skin_image, (10, 30), alpha=True)
|
||||
# skin_bk.paste(circular_red, (-20, 10), True)
|
||||
skin_bk.line((10, 180, 220, 180))
|
||||
skin_bk.text((10, 10), skin.name, (255, 255, 255))
|
||||
skin_bk.text((10, 185), f"{skin.skin_name}", (255, 255, 255), "by_width")
|
||||
skin_bk.text((10, 218), "品质:", (255, 255, 255))
|
||||
skin_bk.text((55, 218), COLOR2NAME[skin.color][:2], COLOR2COLOR[skin.color])
|
||||
skin_bk.text((100, 218), "类型:", (255, 255, 255))
|
||||
skin_bk.text((145, 218), skin.weapon_type, (255, 255, 255))
|
||||
return skin_bk
|
||||
return None
|
||||
@ -1,6 +1,7 @@
|
||||
import random
|
||||
from typing import List, Tuple
|
||||
|
||||
from configs.path_config import IMAGE_PATH
|
||||
from services.log import logger
|
||||
|
||||
from .models.buff_skin import BuffSkin
|
||||
@ -33,6 +34,41 @@ BATTLE_SCARED_S = 0.45
|
||||
BATTLE_SCARED_E = 0.99999
|
||||
|
||||
|
||||
NAME2COLOR = {
|
||||
"消费级": "WHITE",
|
||||
"工业级": "LIGHTBLUE",
|
||||
"军规级": "BLUE",
|
||||
"受限": "PURPLE",
|
||||
"保密": "PINK",
|
||||
"隐秘": "RED",
|
||||
"非凡": "KNIFE",
|
||||
}
|
||||
|
||||
COLOR2NAME = {
|
||||
"WHITE": "消费级",
|
||||
"LIGHTBLUE": "工业级",
|
||||
"BLUE": "军规级",
|
||||
"PURPLE": "受限",
|
||||
"PINK": "保密",
|
||||
"RED": "隐秘",
|
||||
"KNIFE": "非凡",
|
||||
}
|
||||
|
||||
COLOR2COLOR = {
|
||||
"WHITE": (255, 255, 255),
|
||||
"LIGHTBLUE": (0, 179, 255),
|
||||
"BLUE": (0, 85, 255),
|
||||
"PURPLE": (149, 0, 255),
|
||||
"PINK": (255, 0, 162),
|
||||
"RED": (255, 34, 0),
|
||||
"KNIFE": (255, 225, 0),
|
||||
}
|
||||
|
||||
ABRASION_SORT = ["崭新出厂", "略有磨损", "久经沙场", "破损不堪", "战横累累"]
|
||||
|
||||
CASE_BACKGROUND = IMAGE_PATH / "csgo_cases" / "_background" / "shu"
|
||||
|
||||
|
||||
CASE2ID = {
|
||||
"变革": "set_community_32",
|
||||
"反冲": "set_community_31",
|
||||
|
||||
@ -12,7 +12,7 @@ from models.sign_group_user import SignGroupUser
|
||||
from services.log import logger
|
||||
from utils.image_utils import BuildImage
|
||||
from utils.message_builder import image
|
||||
from utils.utils import cn2py, scheduler
|
||||
from utils.utils import cn2py
|
||||
|
||||
from .config import *
|
||||
from .models.open_cases_log import OpenCasesLog
|
||||
@ -99,7 +99,7 @@ async def open_case(user_qq: int, group_id: int, case_name: str) -> Union[str, M
|
||||
if not case_name:
|
||||
case_name = random.choice(CaseManager.CURRENT_CASES) # type: ignore
|
||||
if case_name not in CaseManager.CURRENT_CASES:
|
||||
return "武器箱未收录, 当前可用武器箱:\n" + "\n".join(CaseManager.CURRENT_CASES) # type: ignore
|
||||
return "武器箱未收录, 当前可用武器箱:\n" + ", ".join(CaseManager.CURRENT_CASES) # type: ignore
|
||||
logger.debug(f"尝试开启武器箱: {case_name}", "开箱", user_qq, group_id)
|
||||
case = cn2py(case_name)
|
||||
user = await OpenCasesUser.get_or_none(user_qq=user_qq, group_id=group_id)
|
||||
@ -152,7 +152,7 @@ async def open_case(user_qq: int, group_id: int, case_name: str) -> Union[str, M
|
||||
+ "\n"
|
||||
+ f"皮肤:[{COLOR2NAME[skin.color]}]{skin.name}{'(StatTrak™)' if skin.is_stattrak else ''} | {skin.skin_name} ({skin.abrasion})\n"
|
||||
f"磨损:{rand}\n"
|
||||
f"价格:{price_result}\n箱子单价:{case_price}\n花费:{17 + case_price}\n"
|
||||
f"价格:{price_result}\n箱子单价:{case_price}\n花费:{17 + case_price:.2f}\n"
|
||||
f":{ridicule_result}"
|
||||
)
|
||||
|
||||
@ -176,7 +176,7 @@ async def open_multiple_case(
|
||||
if not case_name:
|
||||
case_name = random.choice(CaseManager.CURRENT_CASES) # type: ignore
|
||||
if case_name not in CaseManager.CURRENT_CASES:
|
||||
return "武器箱未收录, 当前可用武器箱:\n" + "\n".join(CaseManager.CURRENT_CASES) # type: ignore
|
||||
return "武器箱未收录, 当前可用武器箱:\n" + ", ".join(CaseManager.CURRENT_CASES) # type: ignore
|
||||
user, _ = await OpenCasesUser.get_or_create(
|
||||
user_qq=user_qq,
|
||||
group_id=group_id,
|
||||
@ -208,7 +208,6 @@ async def open_multiple_case(
|
||||
case_price = 0
|
||||
if case_skin := await BuffSkin.get_or_none(case_name=case_name, color="CASE"):
|
||||
case_price = case_skin.sell_min_price
|
||||
print(user.today_open_total)
|
||||
cnt = 0
|
||||
for skin, rand in skin_list:
|
||||
total_price += skin.sell_min_price
|
||||
@ -255,7 +254,6 @@ async def open_multiple_case(
|
||||
)
|
||||
)
|
||||
await user.save()
|
||||
print(user.today_open_total)
|
||||
if log_list:
|
||||
await OpenCasesLog.bulk_create(log_list, 10)
|
||||
logger.debug(f"添加 {len(log_list)} 条开箱日志", "开箱", user_qq, group_id)
|
||||
@ -271,7 +269,7 @@ async def open_multiple_case(
|
||||
+ image(markImg.pic2bs4())
|
||||
+ "\n"
|
||||
+ result[:-1]
|
||||
+ f"\n箱子单价:{case_price}\n总获取金额:{total_price:.2f}\n总花费:{(17 + case_price) * num}"
|
||||
+ f"\n箱子单价:{case_price}\n总获取金额:{total_price:.2f}\n总花费:{(17 + case_price) * num:.2f}"
|
||||
)
|
||||
|
||||
|
||||
@ -427,24 +425,8 @@ async def get_old_knife(user_id: int, group_id: int) -> List[OpenCasesLog]:
|
||||
return data_list
|
||||
|
||||
|
||||
@scheduler.scheduled_job(
|
||||
"cron",
|
||||
hour=0,
|
||||
minute=1,
|
||||
)
|
||||
async def _():
|
||||
now = datetime.now()
|
||||
hour = random.choice([0, 1, 2, 3])
|
||||
date = now + timedelta(hours=hour)
|
||||
scheduler.add_job(
|
||||
update,
|
||||
"date",
|
||||
run_date=date.replace(microsecond=0),
|
||||
id=f"auto_update_csgo_cases",
|
||||
)
|
||||
|
||||
|
||||
async def update():
|
||||
async def auto_update():
|
||||
"""自动更新武器箱"""
|
||||
if case_list := Config.get_config("open_cases", "DAILY_UPDATE"):
|
||||
logger.debug("尝试自动更新武器箱", "更新武器箱")
|
||||
if "ALL" in case_list:
|
||||
@ -455,7 +437,7 @@ async def update():
|
||||
try:
|
||||
await update_case_data(case_name)
|
||||
rand = random.randint(300, 500)
|
||||
logger.debug(f"成功自动更新武器箱: {case_name}, 将在 {rand} 秒后再次更新下一武器箱", "更新武器箱")
|
||||
logger.info(f"成功自动更新武器箱: {case_name}, 将在 {rand} 秒后再次更新下一武器箱", "更新武器箱")
|
||||
await asyncio.sleep(rand)
|
||||
except Exception as e:
|
||||
logger.error(f"自动更新武器箱: {case_name}", e=e)
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import asyncio
|
||||
import os
|
||||
import random
|
||||
import time
|
||||
from datetime import datetime
|
||||
@ -10,9 +11,11 @@ from configs.config import Config
|
||||
from configs.path_config import IMAGE_PATH
|
||||
from services.log import logger
|
||||
from utils.http_utils import AsyncHttpx
|
||||
from utils.image_utils import BuildImage
|
||||
from utils.utils import broadcast_group, cn2py
|
||||
|
||||
from .config import CASE2ID
|
||||
from .build_image import generate_skin
|
||||
from .config import CASE2ID, CASE_BACKGROUND, COLOR2NAME, NAME2COLOR
|
||||
from .models.buff_skin import BuffSkin
|
||||
from .models.buff_skin_log import BuffSkinLog
|
||||
from .models.open_cases_user import OpenCasesUser
|
||||
@ -20,9 +23,6 @@ from .models.open_cases_user import OpenCasesUser
|
||||
URL = "https://buff.163.com/api/market/goods"
|
||||
# proxies = 'http://49.75.59.242:3128'
|
||||
|
||||
NAME2COLOR = {"消费级": "WHITE", "工业级": "LIGHTBLUE", "军规级": "BLUE", "受限": "PURPLE", "保密": "PINK", "隐秘": "RED", "非凡": "KNIFE"}
|
||||
|
||||
CURRENT_CASES = []
|
||||
|
||||
driver = nonebot.get_driver()
|
||||
|
||||
@ -220,10 +220,10 @@ async def search_skin_page(
|
||||
obj["weapon_type"] = tags["type"]["localized_name"] # 枪械类型
|
||||
if obj["weapon_type"] in ["音乐盒", "印花", "探员"]:
|
||||
continue
|
||||
if obj["weapon_type"] in ["匕首", "手套"]:
|
||||
elif obj["weapon_type"] in ["匕首", "手套"]:
|
||||
obj["color"] = "KNIFE"
|
||||
obj["name"] = data["short_name"].split("(")[0].strip() # 名称
|
||||
if obj["weapon_type"] in ["武器箱"]:
|
||||
elif obj["weapon_type"] in ["武器箱"]:
|
||||
obj["color"] = "CASE"
|
||||
obj["name"] = data["short_name"]
|
||||
else:
|
||||
@ -260,6 +260,151 @@ async def search_skin_page(
|
||||
return f'访问失败: {json_data["error"]}', -1
|
||||
|
||||
|
||||
async def build_case_image(case_name: str) -> Union[BuildImage, str]:
|
||||
"""构造武器箱图片
|
||||
|
||||
Args:
|
||||
case_name (str): 名称
|
||||
|
||||
Returns:
|
||||
Union[BuildImage, str]: 图片
|
||||
"""
|
||||
background = random.choice(os.listdir(CASE_BACKGROUND))
|
||||
background_img = BuildImage(0, 0, background=CASE_BACKGROUND / background)
|
||||
if case_name:
|
||||
skin_list_ = await BuffSkin.filter(case_name=case_name).all()
|
||||
case = None
|
||||
skin_list: List[BuffSkin] = []
|
||||
exists_name = []
|
||||
for skin in skin_list_:
|
||||
if skin.color == "CASE":
|
||||
case = skin
|
||||
else:
|
||||
name = skin.name + skin.skin_name
|
||||
if name not in exists_name:
|
||||
skin_list.append(skin)
|
||||
exists_name.append(name)
|
||||
generate_img = {}
|
||||
for skin in skin_list:
|
||||
skin_img = await generate_skin(skin)
|
||||
if skin_img:
|
||||
if not generate_img.get(skin.color):
|
||||
generate_img[skin.color] = []
|
||||
generate_img[skin.color].append(skin_img)
|
||||
skin_image_list = []
|
||||
for color in COLOR2NAME:
|
||||
if generate_img.get(color):
|
||||
skin_image_list = skin_image_list + generate_img[color]
|
||||
img = skin_image_list[0]
|
||||
img_w, img_h = img.size
|
||||
total_size = (img_w + 25) * (img_h + 10) * len(skin_image_list) # 总面积
|
||||
new_size = get_bk_image_size(total_size, background_img.size, img.size, 250)
|
||||
A = BuildImage(
|
||||
new_size[0] + 50, new_size[1], background=CASE_BACKGROUND / background
|
||||
)
|
||||
await A.afilter("GaussianBlur", 2)
|
||||
if case:
|
||||
case_img = await generate_skin(case)
|
||||
if case_img:
|
||||
A.paste(case_img, (25, 25), True)
|
||||
w = 25
|
||||
h = 230
|
||||
skin_image_list.reverse()
|
||||
for image in skin_image_list:
|
||||
A.paste(image, (w, h), True)
|
||||
w += image.w + 20
|
||||
if w + image.w - 25 > A.w:
|
||||
h += image.h + 10
|
||||
w = 25
|
||||
if h + img_h + 100 < A.h:
|
||||
await A.acrop((0, 0, A.w, h + img_h + 100))
|
||||
return A
|
||||
else:
|
||||
skin_list = await BuffSkin.filter(color="CASE").all()
|
||||
image_list: List[BuildImage] = []
|
||||
for skin in skin_list:
|
||||
if img := await generate_skin(skin):
|
||||
image_list.append(img)
|
||||
if not image_list:
|
||||
return "未收录武器箱"
|
||||
w = 25
|
||||
h = 150
|
||||
img = image_list[0]
|
||||
img_w, img_h = img.size
|
||||
total_size = (img_w + 25) * (img_h + 10) * len(image_list) # 总面积
|
||||
|
||||
new_size = get_bk_image_size(total_size, background_img.size, img.size, 155)
|
||||
A = BuildImage(
|
||||
new_size[0] + 50, new_size[1], background=CASE_BACKGROUND / background
|
||||
)
|
||||
await A.afilter("GaussianBlur", 2)
|
||||
bk_img = BuildImage(
|
||||
img_w, 120, color=(25, 25, 25, 100), font_size=60, font="CJGaoDeGuo.otf"
|
||||
)
|
||||
await bk_img.atext(
|
||||
(0, 0), f"已收录 {len(image_list)} 个武器箱", (255, 255, 255), center_type="center"
|
||||
)
|
||||
await A.apaste(bk_img, (10, 10), True, "by_width")
|
||||
for image in image_list:
|
||||
A.paste(image, (w, h), True)
|
||||
w += image.w + 20
|
||||
if w + image.w - 25 > A.w:
|
||||
h += image.h + 10
|
||||
w = 25
|
||||
if h + img_h + 100 < A.h:
|
||||
await A.acrop((0, 0, A.w, h + img_h + 100))
|
||||
return A
|
||||
|
||||
|
||||
def get_bk_image_size(
|
||||
total_size: int,
|
||||
base_size: Tuple[int, int],
|
||||
img_size: Tuple[int, int],
|
||||
extra_height: int = 0,
|
||||
):
|
||||
"""获取所需背景大小且不改变图片长宽比
|
||||
|
||||
Args:
|
||||
total_size (int): 总面积
|
||||
base_size (Tuple[int, int]): 初始背景大小
|
||||
img_size (Tuple[int, int]): 贴图大小
|
||||
|
||||
Returns:
|
||||
_type_: 满足所有贴图大小
|
||||
"""
|
||||
bk_w, bk_h = base_size
|
||||
img_w, img_h = img_size
|
||||
is_add_title_size = False
|
||||
left_dis = 0
|
||||
right_dis = 0
|
||||
old_size = (0, 0)
|
||||
new_size = (0, 0)
|
||||
ratio = 1.1
|
||||
while 1:
|
||||
w_ = int(ratio * bk_w)
|
||||
h_ = int(ratio * bk_h)
|
||||
size = w_ * h_
|
||||
if size < total_size:
|
||||
left_dis = size
|
||||
else:
|
||||
right_dis = size
|
||||
r = w_ / (img_w + 25)
|
||||
if right_dis and r - int(r) < 0.1:
|
||||
if not is_add_title_size and extra_height:
|
||||
total_size = int(total_size + w_ * extra_height)
|
||||
is_add_title_size = True
|
||||
right_dis = 0
|
||||
continue
|
||||
if total_size - left_dis > right_dis - total_size:
|
||||
new_size = (w_, h_)
|
||||
else:
|
||||
new_size = old_size
|
||||
break
|
||||
old_size = (w_, h_)
|
||||
ratio += 0.1
|
||||
return new_size
|
||||
|
||||
|
||||
async def reset_count_daily():
|
||||
"""
|
||||
重置每日开箱
|
||||
|
||||
@ -34,6 +34,40 @@ GDict = {
|
||||
}
|
||||
|
||||
|
||||
CN2NUM = {
|
||||
"一": 1,
|
||||
"二": 2,
|
||||
"三": 3,
|
||||
"四": 4,
|
||||
"五": 5,
|
||||
"六": 6,
|
||||
"七": 7,
|
||||
"八": 8,
|
||||
"九": 9,
|
||||
"十": 10,
|
||||
"十一": 11,
|
||||
"十二": 12,
|
||||
"十三": 13,
|
||||
"十四": 14,
|
||||
"十五": 15,
|
||||
"十六": 16,
|
||||
"十七": 17,
|
||||
"十八": 18,
|
||||
"十九": 19,
|
||||
"二十": 20,
|
||||
"二十一": 21,
|
||||
"二十二": 22,
|
||||
"二十三": 23,
|
||||
"二十四": 24,
|
||||
"二十五": 25,
|
||||
"二十六": 26,
|
||||
"二十七": 27,
|
||||
"二十八": 28,
|
||||
"二十九": 29,
|
||||
"三十": 30,
|
||||
}
|
||||
|
||||
|
||||
class CountLimiter:
|
||||
"""
|
||||
次数检测工具,检测调用次数是否超过设定值
|
||||
|
||||
Loading…
Reference in New Issue
Block a user