mirror of
https://github.com/zhenxun-org/zhenxun_bot.git
synced 2025-12-15 14:22:55 +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 configs.config import Config
|
||||||
from services.db_context import Model
|
from services.db_context import Model
|
||||||
|
from services.log import logger
|
||||||
|
|
||||||
|
|
||||||
class GroupInfoUser(Model):
|
class GroupInfoUser(Model):
|
||||||
@ -39,7 +40,7 @@ class GroupInfoUser(Model):
|
|||||||
"""
|
"""
|
||||||
return set(
|
return set(
|
||||||
await cls.filter(group_id=group_id).values_list("user_qq", flat=True)
|
await cls.filter(group_id=group_id).values_list("user_qq", flat=True)
|
||||||
)
|
) # type: ignore
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def set_user_nickname(cls, user_qq: int, group_id: int, nickname: str):
|
async def set_user_nickname(cls, user_qq: int, group_id: int, nickname: str):
|
||||||
@ -67,7 +68,7 @@ class GroupInfoUser(Model):
|
|||||||
"""
|
"""
|
||||||
return list(
|
return list(
|
||||||
await cls.filter(user_qq=user_qq).values_list("group_id", flat=True)
|
await cls.filter(user_qq=user_qq).values_list("group_id", flat=True)
|
||||||
)
|
) # type: ignore
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def get_user_nickname(cls, user_qq: int, group_id: int) -> str:
|
async def get_user_nickname(cls, user_qq: int, group_id: int) -> str:
|
||||||
@ -90,6 +91,9 @@ class GroupInfoUser(Model):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def get_group_member_uid(cls, user_qq: int, group_id: int) -> Optional[int]:
|
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)
|
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_user, _ = await cls.get_or_create(user_qq=114514, group_id=114514)
|
||||||
_max_uid = _max_uid_user.uid
|
_max_uid = _max_uid_user.uid
|
||||||
@ -101,6 +105,9 @@ class GroupInfoUser(Model):
|
|||||||
user.uid = _max_uid + 1
|
user.uid = _max_uid + 1
|
||||||
_max_uid_user.uid = _max_uid + 1
|
_max_uid_user.uid = _max_uid + 1
|
||||||
await cls.bulk_update([user, _max_uid_user], ["uid"])
|
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
|
return user.uid
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|||||||
@ -1,4 +1,6 @@
|
|||||||
|
import asyncio
|
||||||
import random
|
import random
|
||||||
|
from datetime import datetime, timedelta
|
||||||
from typing import Any, List, Tuple
|
from typing import Any, List, Tuple
|
||||||
|
|
||||||
from nonebot import on_command
|
from nonebot import on_command
|
||||||
@ -12,17 +14,25 @@ from nonebot.typing import T_State
|
|||||||
|
|
||||||
from configs.config import Config
|
from configs.config import Config
|
||||||
from configs.path_config import IMAGE_PATH
|
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 (
|
from .open_cases_c import (
|
||||||
|
auto_update,
|
||||||
get_my_knifes,
|
get_my_knifes,
|
||||||
group_statistics,
|
group_statistics,
|
||||||
open_case,
|
open_case,
|
||||||
open_multiple_case,
|
open_multiple_case,
|
||||||
total_open_statistics,
|
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__ = "开箱"
|
__zx_plugin_name__ = "开箱"
|
||||||
__plugin_usage__ = """
|
__plugin_usage__ = """
|
||||||
@ -35,14 +45,10 @@ usage:
|
|||||||
我的开箱
|
我的开箱
|
||||||
我的金色
|
我的金色
|
||||||
群开箱统计
|
群开箱统计
|
||||||
|
查看武器箱?[武器箱]
|
||||||
* 不包含[武器箱]时随机开箱 *
|
* 不包含[武器箱]时随机开箱 *
|
||||||
目前支持的武器箱:
|
示例: 查看武器箱
|
||||||
1.狂牙大行动武器箱
|
示例: 查看武器箱英勇
|
||||||
2.突围大行动武器箱
|
|
||||||
3.命悬一线武器箱
|
|
||||||
4.裂空武器箱
|
|
||||||
5.光谱武器箱
|
|
||||||
示例:开箱 命悬一线
|
|
||||||
""".strip()
|
""".strip()
|
||||||
__plugin_superuser_usage__ = """
|
__plugin_superuser_usage__ = """
|
||||||
usage:
|
usage:
|
||||||
@ -61,6 +67,7 @@ __plugin_cmd__ = [
|
|||||||
"我的开箱",
|
"我的开箱",
|
||||||
"我的金色",
|
"我的金色",
|
||||||
"群开箱统计",
|
"群开箱统计",
|
||||||
|
"查看武器箱?[武器箱]",
|
||||||
"更新开箱图片 ?[武器箱] [_superuser]",
|
"更新开箱图片 ?[武器箱] [_superuser]",
|
||||||
"更新开箱价格 ?[武器箱] [_superuser]",
|
"更新开箱价格 ?[武器箱] [_superuser]",
|
||||||
]
|
]
|
||||||
@ -89,10 +96,7 @@ __plugin_configs__ = {
|
|||||||
"default_value": 3,
|
"default_value": 3,
|
||||||
"type": int,
|
"type": int,
|
||||||
},
|
},
|
||||||
"COOKIE": {
|
"COOKIE": {"value": None, "help": "BUFF的cookie", "type": str},
|
||||||
"value": None,
|
|
||||||
"help": "BUFF的cookie",
|
|
||||||
},
|
|
||||||
"BUFF_PROXY": {"value": None, "help": "使用代理访问BUFF"},
|
"BUFF_PROXY": {"value": None, "help": "使用代理访问BUFF"},
|
||||||
"DAILY_UPDATE": {
|
"DAILY_UPDATE": {
|
||||||
"value": None,
|
"value": None,
|
||||||
@ -121,8 +125,11 @@ total_case_data = cases_matcher_group.on_command(
|
|||||||
)
|
)
|
||||||
group_open_case_statistics = cases_matcher_group.on_command("群开箱统计")
|
group_open_case_statistics = cases_matcher_group.on_command("群开箱统计")
|
||||||
open_multiple = cases_matcher_group.on_regex("(.*)连开箱(.*)?")
|
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)
|
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()
|
@reload_count.handle()
|
||||||
@ -163,9 +170,9 @@ async def _(
|
|||||||
event: GroupMessageEvent, state: T_State, reg_group: Tuple[Any, ...] = RegexGroup()
|
event: GroupMessageEvent, state: T_State, reg_group: Tuple[Any, ...] = RegexGroup()
|
||||||
):
|
):
|
||||||
num, case_name = reg_group
|
num, case_name = reg_group
|
||||||
if is_number(num) or num_dict.get(num):
|
if is_number(num) or CN2NUM.get(num):
|
||||||
try:
|
try:
|
||||||
num = num_dict[num]
|
num = CN2NUM[num]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
num = int(num)
|
num = int(num)
|
||||||
if num > 30:
|
if num > 30:
|
||||||
@ -181,41 +188,7 @@ async def _(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
num_dict = {
|
@update_case.handle()
|
||||||
"一": 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()
|
|
||||||
async def _(event: MessageEvent, arg: Message = CommandArg()):
|
async def _(event: MessageEvent, arg: Message = CommandArg()):
|
||||||
msg = arg.extract_plain_text().strip()
|
msg = arg.extract_plain_text().strip()
|
||||||
if not msg:
|
if not msg:
|
||||||
@ -225,9 +198,38 @@ async def _(event: MessageEvent, arg: Message = CommandArg()):
|
|||||||
case_list.append(f"{i+1}.{case_name} [已更新]")
|
case_list.append(f"{i+1}.{case_name} [已更新]")
|
||||||
else:
|
else:
|
||||||
case_list.append(f"{i+1}.{case_name}")
|
case_list.append(f"{i+1}.{case_name}")
|
||||||
await update_data.finish("未指定武器箱, 当前已包含武器箱\n" + "\n".join(case_list))
|
await update_case.finish("未指定武器箱, 当前已包含武器箱\n" + "\n".join(case_list))
|
||||||
await update_data.send(f"开始更新武器箱: {msg}, 请稍等")
|
if msg == "ALL":
|
||||||
await update_data.send(await update_case_data(msg), at_sender=True)
|
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 _():
|
async def _():
|
||||||
await reset_count_daily()
|
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
|
import random
|
||||||
from typing import List, Tuple
|
from typing import List, Tuple
|
||||||
|
|
||||||
|
from configs.path_config import IMAGE_PATH
|
||||||
from services.log import logger
|
from services.log import logger
|
||||||
|
|
||||||
from .models.buff_skin import BuffSkin
|
from .models.buff_skin import BuffSkin
|
||||||
@ -33,6 +34,41 @@ BATTLE_SCARED_S = 0.45
|
|||||||
BATTLE_SCARED_E = 0.99999
|
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 = {
|
CASE2ID = {
|
||||||
"变革": "set_community_32",
|
"变革": "set_community_32",
|
||||||
"反冲": "set_community_31",
|
"反冲": "set_community_31",
|
||||||
|
|||||||
@ -12,7 +12,7 @@ from models.sign_group_user import SignGroupUser
|
|||||||
from services.log import logger
|
from services.log import logger
|
||||||
from utils.image_utils import BuildImage
|
from utils.image_utils import BuildImage
|
||||||
from utils.message_builder import image
|
from utils.message_builder import image
|
||||||
from utils.utils import cn2py, scheduler
|
from utils.utils import cn2py
|
||||||
|
|
||||||
from .config import *
|
from .config import *
|
||||||
from .models.open_cases_log import OpenCasesLog
|
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:
|
if not case_name:
|
||||||
case_name = random.choice(CaseManager.CURRENT_CASES) # type: ignore
|
case_name = random.choice(CaseManager.CURRENT_CASES) # type: ignore
|
||||||
if case_name not in CaseManager.CURRENT_CASES:
|
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)
|
logger.debug(f"尝试开启武器箱: {case_name}", "开箱", user_qq, group_id)
|
||||||
case = cn2py(case_name)
|
case = cn2py(case_name)
|
||||||
user = await OpenCasesUser.get_or_none(user_qq=user_qq, group_id=group_id)
|
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"
|
+ "\n"
|
||||||
+ f"皮肤:[{COLOR2NAME[skin.color]}]{skin.name}{'(StatTrak™)' if skin.is_stattrak else ''} | {skin.skin_name} ({skin.abrasion})\n"
|
+ f"皮肤:[{COLOR2NAME[skin.color]}]{skin.name}{'(StatTrak™)' if skin.is_stattrak else ''} | {skin.skin_name} ({skin.abrasion})\n"
|
||||||
f"磨损:{rand}\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}"
|
f":{ridicule_result}"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -176,7 +176,7 @@ async def open_multiple_case(
|
|||||||
if not case_name:
|
if not case_name:
|
||||||
case_name = random.choice(CaseManager.CURRENT_CASES) # type: ignore
|
case_name = random.choice(CaseManager.CURRENT_CASES) # type: ignore
|
||||||
if case_name not in CaseManager.CURRENT_CASES:
|
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, _ = await OpenCasesUser.get_or_create(
|
||||||
user_qq=user_qq,
|
user_qq=user_qq,
|
||||||
group_id=group_id,
|
group_id=group_id,
|
||||||
@ -208,7 +208,6 @@ async def open_multiple_case(
|
|||||||
case_price = 0
|
case_price = 0
|
||||||
if case_skin := await BuffSkin.get_or_none(case_name=case_name, color="CASE"):
|
if case_skin := await BuffSkin.get_or_none(case_name=case_name, color="CASE"):
|
||||||
case_price = case_skin.sell_min_price
|
case_price = case_skin.sell_min_price
|
||||||
print(user.today_open_total)
|
|
||||||
cnt = 0
|
cnt = 0
|
||||||
for skin, rand in skin_list:
|
for skin, rand in skin_list:
|
||||||
total_price += skin.sell_min_price
|
total_price += skin.sell_min_price
|
||||||
@ -255,7 +254,6 @@ async def open_multiple_case(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
await user.save()
|
await user.save()
|
||||||
print(user.today_open_total)
|
|
||||||
if log_list:
|
if log_list:
|
||||||
await OpenCasesLog.bulk_create(log_list, 10)
|
await OpenCasesLog.bulk_create(log_list, 10)
|
||||||
logger.debug(f"添加 {len(log_list)} 条开箱日志", "开箱", user_qq, group_id)
|
logger.debug(f"添加 {len(log_list)} 条开箱日志", "开箱", user_qq, group_id)
|
||||||
@ -271,7 +269,7 @@ async def open_multiple_case(
|
|||||||
+ image(markImg.pic2bs4())
|
+ image(markImg.pic2bs4())
|
||||||
+ "\n"
|
+ "\n"
|
||||||
+ result[:-1]
|
+ 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
|
return data_list
|
||||||
|
|
||||||
|
|
||||||
@scheduler.scheduled_job(
|
async def auto_update():
|
||||||
"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():
|
|
||||||
if case_list := Config.get_config("open_cases", "DAILY_UPDATE"):
|
if case_list := Config.get_config("open_cases", "DAILY_UPDATE"):
|
||||||
logger.debug("尝试自动更新武器箱", "更新武器箱")
|
logger.debug("尝试自动更新武器箱", "更新武器箱")
|
||||||
if "ALL" in case_list:
|
if "ALL" in case_list:
|
||||||
@ -455,7 +437,7 @@ async def update():
|
|||||||
try:
|
try:
|
||||||
await update_case_data(case_name)
|
await update_case_data(case_name)
|
||||||
rand = random.randint(300, 500)
|
rand = random.randint(300, 500)
|
||||||
logger.debug(f"成功自动更新武器箱: {case_name}, 将在 {rand} 秒后再次更新下一武器箱", "更新武器箱")
|
logger.info(f"成功自动更新武器箱: {case_name}, 将在 {rand} 秒后再次更新下一武器箱", "更新武器箱")
|
||||||
await asyncio.sleep(rand)
|
await asyncio.sleep(rand)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"自动更新武器箱: {case_name}", e=e)
|
logger.error(f"自动更新武器箱: {case_name}", e=e)
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
|
import os
|
||||||
import random
|
import random
|
||||||
import time
|
import time
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
@ -10,9 +11,11 @@ from configs.config import Config
|
|||||||
from configs.path_config import IMAGE_PATH
|
from configs.path_config import IMAGE_PATH
|
||||||
from services.log import logger
|
from services.log import logger
|
||||||
from utils.http_utils import AsyncHttpx
|
from utils.http_utils import AsyncHttpx
|
||||||
|
from utils.image_utils import BuildImage
|
||||||
from utils.utils import broadcast_group, cn2py
|
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 import BuffSkin
|
||||||
from .models.buff_skin_log import BuffSkinLog
|
from .models.buff_skin_log import BuffSkinLog
|
||||||
from .models.open_cases_user import OpenCasesUser
|
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"
|
URL = "https://buff.163.com/api/market/goods"
|
||||||
# proxies = 'http://49.75.59.242:3128'
|
# proxies = 'http://49.75.59.242:3128'
|
||||||
|
|
||||||
NAME2COLOR = {"消费级": "WHITE", "工业级": "LIGHTBLUE", "军规级": "BLUE", "受限": "PURPLE", "保密": "PINK", "隐秘": "RED", "非凡": "KNIFE"}
|
|
||||||
|
|
||||||
CURRENT_CASES = []
|
|
||||||
|
|
||||||
driver = nonebot.get_driver()
|
driver = nonebot.get_driver()
|
||||||
|
|
||||||
@ -220,10 +220,10 @@ async def search_skin_page(
|
|||||||
obj["weapon_type"] = tags["type"]["localized_name"] # 枪械类型
|
obj["weapon_type"] = tags["type"]["localized_name"] # 枪械类型
|
||||||
if obj["weapon_type"] in ["音乐盒", "印花", "探员"]:
|
if obj["weapon_type"] in ["音乐盒", "印花", "探员"]:
|
||||||
continue
|
continue
|
||||||
if obj["weapon_type"] in ["匕首", "手套"]:
|
elif obj["weapon_type"] in ["匕首", "手套"]:
|
||||||
obj["color"] = "KNIFE"
|
obj["color"] = "KNIFE"
|
||||||
obj["name"] = data["short_name"].split("(")[0].strip() # 名称
|
obj["name"] = data["short_name"].split("(")[0].strip() # 名称
|
||||||
if obj["weapon_type"] in ["武器箱"]:
|
elif obj["weapon_type"] in ["武器箱"]:
|
||||||
obj["color"] = "CASE"
|
obj["color"] = "CASE"
|
||||||
obj["name"] = data["short_name"]
|
obj["name"] = data["short_name"]
|
||||||
else:
|
else:
|
||||||
@ -260,6 +260,151 @@ async def search_skin_page(
|
|||||||
return f'访问失败: {json_data["error"]}', -1
|
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():
|
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:
|
class CountLimiter:
|
||||||
"""
|
"""
|
||||||
次数检测工具,检测调用次数是否超过设定值
|
次数检测工具,检测调用次数是否超过设定值
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user