mirror of
https://github.com/Genshin-bots/gsuid_core.git
synced 2025-05-12 06:55:49 +08:00
✨ 新增绑定信息
This commit is contained in:
parent
152ce577e2
commit
ce6ece0801
@ -6,7 +6,7 @@ from PIL import Image, ImageDraw
|
|||||||
from gsuid_core.sv import SV
|
from gsuid_core.sv import SV
|
||||||
|
|
||||||
# from gsuid_core.utils.image.image_tools import get_color_bg
|
# from gsuid_core.utils.image.image_tools import get_color_bg
|
||||||
from gsuid_core.utils.smile_fonts.smile_fonts import smile_font
|
from gsuid_core.utils.fonts.fonts import core_font
|
||||||
|
|
||||||
TEXT_PATH = Path(__file__).parent / 'texture2d'
|
TEXT_PATH = Path(__file__).parent / 'texture2d'
|
||||||
CORE_HELP_IMG = Path(__file__).parent / 'core_help.jpg'
|
CORE_HELP_IMG = Path(__file__).parent / 'core_help.jpg'
|
||||||
@ -56,7 +56,7 @@ def get_tag(tag_type: str) -> Image.Image:
|
|||||||
tag = Image.new('RGBA', (60, 40))
|
tag = Image.new('RGBA', (60, 40))
|
||||||
tag_draw = ImageDraw.Draw(tag)
|
tag_draw = ImageDraw.Draw(tag)
|
||||||
tag_draw.rounded_rectangle((7, 5, 53, 35), 10, tag_color[tag_type])
|
tag_draw.rounded_rectangle((7, 5, 53, 35), 10, tag_color[tag_type])
|
||||||
tag_draw.text((30, 20), text, (62, 62, 62), smile_font(22), 'mm')
|
tag_draw.text((30, 20), text, (62, 62, 62), core_font(22), 'mm')
|
||||||
tags[tag_type] = tag
|
tags[tag_type] = tag
|
||||||
return tag
|
return tag
|
||||||
|
|
||||||
@ -65,7 +65,7 @@ def get_command_bg(command: str, tag_type: str):
|
|||||||
img = Image.new('RGBA', (220, 40))
|
img = Image.new('RGBA', (220, 40))
|
||||||
img_draw = ImageDraw.Draw(img)
|
img_draw = ImageDraw.Draw(img)
|
||||||
img_draw.rounded_rectangle((6, 5, 160, 35), 10, (230, 202, 167))
|
img_draw.rounded_rectangle((6, 5, 160, 35), 10, (230, 202, 167))
|
||||||
img_draw.text((83, 20), command, (62, 62, 62), smile_font(20), 'mm')
|
img_draw.text((83, 20), command, (62, 62, 62), core_font(20), 'mm')
|
||||||
tag = get_tag(tag_type)
|
tag = get_tag(tag_type)
|
||||||
img.paste(tag, (160, 0), tag)
|
img.paste(tag, (160, 0), tag)
|
||||||
return img
|
return img
|
||||||
@ -126,20 +126,20 @@ def get_plugin_bg(plugin_name: str, sv_list: List[SV]):
|
|||||||
)
|
)
|
||||||
|
|
||||||
sv_img_draw.rounded_rectangle((15, 19, 25, 50), 10, (62, 62, 62))
|
sv_img_draw.rounded_rectangle((15, 19, 25, 50), 10, (62, 62, 62))
|
||||||
sv_img_draw.text((45, 31), sv.name, (62, 62, 62), smile_font(36), 'lm')
|
sv_img_draw.text((45, 31), sv.name, (62, 62, 62), core_font(36), 'lm')
|
||||||
|
|
||||||
sv_img_draw.rounded_rectangle((710, 15, 760, 50), 10, _c(sv.enabled))
|
sv_img_draw.rounded_rectangle((710, 15, 760, 50), 10, _c(sv.enabled))
|
||||||
sv_img_draw.rounded_rectangle((770, 15, 820, 50), 10, _c(sv.pm))
|
sv_img_draw.rounded_rectangle((770, 15, 820, 50), 10, _c(sv.pm))
|
||||||
sv_img_draw.rounded_rectangle((830, 15, 880, 50), 10, _c(sv.area))
|
sv_img_draw.rounded_rectangle((830, 15, 880, 50), 10, _c(sv.area))
|
||||||
|
|
||||||
sv_img_draw.text(
|
sv_img_draw.text(
|
||||||
(735, 32), _t(sv.enabled), (62, 62, 62), smile_font(22), 'mm'
|
(735, 32), _t(sv.enabled), (62, 62, 62), core_font(22), 'mm'
|
||||||
)
|
)
|
||||||
sv_img_draw.text(
|
sv_img_draw.text(
|
||||||
(795, 32), _t(sv.pm), (62, 62, 62), smile_font(22), 'mm'
|
(795, 32), _t(sv.pm), (62, 62, 62), core_font(22), 'mm'
|
||||||
)
|
)
|
||||||
sv_img_draw.text(
|
sv_img_draw.text(
|
||||||
(855, 32), _t(sv.area), (62, 62, 62), smile_font(22), 'mm'
|
(855, 32), _t(sv.area), (62, 62, 62), core_font(22), 'mm'
|
||||||
)
|
)
|
||||||
img_list.append(sv_img)
|
img_list.append(sv_img)
|
||||||
|
|
||||||
@ -152,7 +152,7 @@ def get_plugin_bg(plugin_name: str, sv_list: List[SV]):
|
|||||||
)
|
)
|
||||||
img_draw = ImageDraw.Draw(img)
|
img_draw = ImageDraw.Draw(img)
|
||||||
img_draw.rounded_rectangle((10, 26, 890, 76), 10, (230, 202, 167))
|
img_draw.rounded_rectangle((10, 26, 890, 76), 10, (230, 202, 167))
|
||||||
img_draw.text((450, 51), plugin_name, (62, 62, 62), smile_font(42), 'mm')
|
img_draw.text((450, 51), plugin_name, (62, 62, 62), core_font(42), 'mm')
|
||||||
|
|
||||||
temp = 0
|
temp = 0
|
||||||
for _img in img_list:
|
for _img in img_list:
|
||||||
|
15
gsuid_core/plugins/core_command/core_user/__init__.py
Normal file
15
gsuid_core/plugins/core_command/core_user/__init__.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
from gsuid_core.sv import SV
|
||||||
|
from gsuid_core.bot import Bot
|
||||||
|
from gsuid_core.models import Event
|
||||||
|
|
||||||
|
from .draw_user_card import get_user_card
|
||||||
|
|
||||||
|
core_user_info = SV('core用户信息')
|
||||||
|
|
||||||
|
|
||||||
|
@core_user_info.on_fullmatch(('绑定信息'))
|
||||||
|
async def send_bind_card(bot: Bot, ev: Event):
|
||||||
|
await bot.logger.info('开始执行[查询用户绑定状态]')
|
||||||
|
im = await get_user_card(ev.bot_id, ev.user_id)
|
||||||
|
await bot.logger.info('[查询用户绑定状态]完成!等待图片发送中...')
|
||||||
|
await bot.send(im)
|
133
gsuid_core/plugins/core_command/core_user/draw_user_card.py
Normal file
133
gsuid_core/plugins/core_command/core_user/draw_user_card.py
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
from pathlib import Path
|
||||||
|
from typing import List, Tuple, Union, Optional
|
||||||
|
|
||||||
|
from PIL import Image, ImageDraw
|
||||||
|
|
||||||
|
from gsuid_core.utils.database.api import DBSqla
|
||||||
|
from gsuid_core.utils.fonts.fonts import core_font
|
||||||
|
from gsuid_core.utils.database.models import GsPush
|
||||||
|
from gsuid_core.utils.image.convert import convert_img
|
||||||
|
from gsuid_core.utils.image.image_tools import (
|
||||||
|
get_color_bg,
|
||||||
|
get_qq_avatar,
|
||||||
|
draw_pic_with_ring,
|
||||||
|
easy_alpha_composite,
|
||||||
|
)
|
||||||
|
|
||||||
|
TEXT_PATH = Path(__file__).parent / 'texture2d'
|
||||||
|
|
||||||
|
status_off = Image.open(TEXT_PATH / 'status_off.png')
|
||||||
|
status_on = Image.open(TEXT_PATH / 'status_on.png')
|
||||||
|
|
||||||
|
EN_MAP = {'coin': '宝钱', 'resin': '体力', 'go': '派遣', 'transform': '质变仪'}
|
||||||
|
|
||||||
|
|
||||||
|
async def get_user_card(bot_id: str, user_id: str) -> Union[bytes, str]:
|
||||||
|
get_sqla = DBSqla().get_sqla
|
||||||
|
sqla = get_sqla(bot_id)
|
||||||
|
uid_list: List = await sqla.get_bind_uid_list(user_id)
|
||||||
|
sr_uid_list = await sqla.get_bind_sruid_list(user_id)
|
||||||
|
user_list = await sqla.select_user_all_data_by_user_id(user_id)
|
||||||
|
|
||||||
|
if user_list is None:
|
||||||
|
return '你还没有绑定过UID或者CK!'
|
||||||
|
|
||||||
|
w, h = 750, len(max(uid_list, sr_uid_list)) * 900 + 470
|
||||||
|
|
||||||
|
# 获取背景图片各项参数
|
||||||
|
_id = str(user_id)
|
||||||
|
if _id.startswith('http'):
|
||||||
|
char_pic = await get_qq_avatar(avatar_url=_id)
|
||||||
|
else:
|
||||||
|
char_pic = await get_qq_avatar(qid=_id)
|
||||||
|
char_pic = await draw_pic_with_ring(char_pic, 290)
|
||||||
|
|
||||||
|
img = await get_color_bg(w, h)
|
||||||
|
img_mask = Image.new('RGBA', img.size, (255, 255, 255))
|
||||||
|
title = Image.open(TEXT_PATH / 'user_title.png')
|
||||||
|
title.paste(char_pic, (241, 40), char_pic)
|
||||||
|
|
||||||
|
title_draw = ImageDraw.Draw(title)
|
||||||
|
title_draw.text(
|
||||||
|
(375, 444), f'{bot_id} - {user_id}', (29, 29, 29), core_font(30), 'mm'
|
||||||
|
)
|
||||||
|
img.paste(title, (0, 0), title)
|
||||||
|
|
||||||
|
for index, user_data in enumerate(user_list):
|
||||||
|
user_card = Image.open(TEXT_PATH / 'user_bg.png')
|
||||||
|
user_draw = ImageDraw.Draw(user_card)
|
||||||
|
|
||||||
|
if user_data.uid is not None and user_data.uid != '0':
|
||||||
|
uid_text = f'原神UID {user_data.uid}'
|
||||||
|
user_push_data = await sqla.select_push_data(user_data.uid)
|
||||||
|
else:
|
||||||
|
uid_text = '未发现原神UID'
|
||||||
|
user_push_data = GsPush(bot_id='TEMP')
|
||||||
|
|
||||||
|
user_draw.text(
|
||||||
|
(375, 58),
|
||||||
|
uid_text,
|
||||||
|
(29, 29, 29),
|
||||||
|
font=core_font(36),
|
||||||
|
anchor='mm',
|
||||||
|
)
|
||||||
|
|
||||||
|
if user_data.sr_uid:
|
||||||
|
sruid_text = f'星铁UID {user_data.sr_uid}'
|
||||||
|
else:
|
||||||
|
sruid_text = '未发现星铁UID'
|
||||||
|
|
||||||
|
user_draw.text(
|
||||||
|
(375, 119),
|
||||||
|
sruid_text,
|
||||||
|
(29, 29, 29),
|
||||||
|
font=core_font(36),
|
||||||
|
anchor='mm',
|
||||||
|
)
|
||||||
|
|
||||||
|
x, y = 331, 112
|
||||||
|
b = 175
|
||||||
|
paste_switch(user_card, user_data.cookie, (241, b))
|
||||||
|
paste_switch(user_card, user_data.stoken, (241 + x, b))
|
||||||
|
paste_switch(user_card, user_data.sign_switch, (241, b + y))
|
||||||
|
paste_switch(user_card, user_data.bbs_switch, (241 + x, b + y))
|
||||||
|
paste_switch(user_card, user_data.push_switch, (241, b + 2 * y))
|
||||||
|
paste_switch(user_card, user_data.status, (241 + x, b + 2 * y), True)
|
||||||
|
|
||||||
|
for _index, mode in enumerate(['coin', 'resin', 'go', 'transform']):
|
||||||
|
paste_switch(
|
||||||
|
user_card,
|
||||||
|
getattr(user_push_data, f'{mode}_push'),
|
||||||
|
(241 + _index % 2 * x, b + (_index // 2 + 3) * y),
|
||||||
|
)
|
||||||
|
if getattr(user_push_data, f'{mode}_push') != 'off':
|
||||||
|
user_draw.text(
|
||||||
|
(268 + _index % 2 * x, 168 + (_index // 2 + 3) * y),
|
||||||
|
f'{getattr(user_push_data, f"{mode}_value")}',
|
||||||
|
(35, 35, 35),
|
||||||
|
font=core_font(15),
|
||||||
|
anchor='lm',
|
||||||
|
)
|
||||||
|
|
||||||
|
sr_sign = user_data.sr_sign_switch
|
||||||
|
sr_push = user_data.sr_push_switch
|
||||||
|
paste_switch(user_card, sr_sign, (241, b + 5 * y))
|
||||||
|
paste_switch(user_card, sr_push, (241 + x, b + 5 * y))
|
||||||
|
|
||||||
|
img.paste(user_card, (0, 500 + index * 690), user_card)
|
||||||
|
|
||||||
|
img = easy_alpha_composite(img_mask, img, (0, 0))
|
||||||
|
return await convert_img(img)
|
||||||
|
|
||||||
|
|
||||||
|
def paste_switch(
|
||||||
|
card: Image.Image,
|
||||||
|
status: Optional[str],
|
||||||
|
pos: Tuple[int, int],
|
||||||
|
is_status: bool = False,
|
||||||
|
):
|
||||||
|
if is_status:
|
||||||
|
pic = status_off if status else status_on
|
||||||
|
else:
|
||||||
|
pic = status_on if status != 'off' and status else status_off
|
||||||
|
card.paste(pic, pos, pic)
|
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
BIN
gsuid_core/plugins/core_command/core_user/texture2d/user_bg.png
Normal file
BIN
gsuid_core/plugins/core_command/core_user/texture2d/user_bg.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 194 KiB |
Binary file not shown.
After Width: | Height: | Size: 8.7 KiB |
@ -44,6 +44,8 @@ class SQLA:
|
|||||||
'ALTER TABLE GsUser ADD COLUMN sr_region TEXT',
|
'ALTER TABLE GsUser ADD COLUMN sr_region TEXT',
|
||||||
'ALTER TABLE GsUser ADD COLUMN fp TEXT',
|
'ALTER TABLE GsUser ADD COLUMN fp TEXT',
|
||||||
'ALTER TABLE GsUser ADD COLUMN device_id TEXT',
|
'ALTER TABLE GsUser ADD COLUMN device_id TEXT',
|
||||||
|
'ALTER TABLE GsUser ADD COLUMN sr_sign_switch TEXT DEFAULT "off"',
|
||||||
|
'ALTER TABLE GsUser ADD COLUMN sr_push_switch TEXT DEFAULT "off"',
|
||||||
'ALTER TABLE GsCache ADD COLUMN sr_uid TEXT',
|
'ALTER TABLE GsCache ADD COLUMN sr_uid TEXT',
|
||||||
]
|
]
|
||||||
async with self.async_session() as session:
|
async with self.async_session() as session:
|
||||||
@ -338,6 +340,8 @@ class SQLA:
|
|||||||
else None,
|
else None,
|
||||||
fp=fp,
|
fp=fp,
|
||||||
device_id=device_id,
|
device_id=device_id,
|
||||||
|
sr_push_switch='off',
|
||||||
|
sr_sign_switch='off',
|
||||||
)
|
)
|
||||||
session.add(user_data)
|
session.add(user_data)
|
||||||
await session.commit()
|
await session.commit()
|
||||||
@ -565,7 +569,7 @@ class SQLA:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
async def get_switch_status_list(
|
async def get_switch_status_list(
|
||||||
self, switch: Literal['push', 'sign', 'bbs']
|
self, switch: Literal['push', 'sign', 'bbs', 'sr_push', 'sr_sign']
|
||||||
) -> List[GsUser]:
|
) -> List[GsUser]:
|
||||||
async with self.async_session() as session:
|
async with self.async_session() as session:
|
||||||
async with session.begin():
|
async with session.begin():
|
||||||
|
@ -28,6 +28,8 @@ class GsUser(SQLModel, table=True):
|
|||||||
push_switch: str = Field(title='全局推送开关')
|
push_switch: str = Field(title='全局推送开关')
|
||||||
sign_switch: str = Field(title='自动签到')
|
sign_switch: str = Field(title='自动签到')
|
||||||
bbs_switch: str = Field(title='自动米游币')
|
bbs_switch: str = Field(title='自动米游币')
|
||||||
|
sr_push_switch: str = Field(title='星铁全局推送开关')
|
||||||
|
sr_sign_switch: str = Field(title='星铁自动签到')
|
||||||
status: Optional[str] = Field(default=None, title='状态')
|
status: Optional[str] = Field(default=None, title='状态')
|
||||||
fp: Optional[str] = Field(default=None, title='Fingerprint')
|
fp: Optional[str] = Field(default=None, title='Fingerprint')
|
||||||
device_id: Optional[str] = Field(default=None, title='设备ID')
|
device_id: Optional[str] = Field(default=None, title='设备ID')
|
||||||
@ -47,15 +49,15 @@ class GsPush(SQLModel, table=True):
|
|||||||
id: Optional[int] = Field(default=None, primary_key=True, title='序号')
|
id: Optional[int] = Field(default=None, primary_key=True, title='序号')
|
||||||
bot_id: str = Field(title='平台')
|
bot_id: str = Field(title='平台')
|
||||||
uid: str = Field(default=None, title='原神UID')
|
uid: str = Field(default=None, title='原神UID')
|
||||||
coin_push: Optional[str] = Field(title='洞天宝钱推送')
|
coin_push: Optional[str] = Field(title='洞天宝钱推送', default='off')
|
||||||
coin_value: Optional[int] = Field(title='洞天宝钱阈值')
|
coin_value: Optional[int] = Field(title='洞天宝钱阈值', default=2100)
|
||||||
coin_is_push: Optional[str] = Field(title='洞天宝钱是否已推送')
|
coin_is_push: Optional[str] = Field(title='洞天宝钱是否已推送', default='off')
|
||||||
resin_push: Optional[str] = Field(title='体力推送')
|
resin_push: Optional[str] = Field(title='体力推送', default='off')
|
||||||
resin_value: Optional[int] = Field(title='体力阈值')
|
resin_value: Optional[int] = Field(title='体力阈值', default=140)
|
||||||
resin_is_push: Optional[str] = Field(title='体力是否已推送')
|
resin_is_push: Optional[str] = Field(title='体力是否已推送', default='off')
|
||||||
go_push: Optional[str] = Field(title='派遣推送')
|
go_push: Optional[str] = Field(title='派遣推送', default='off')
|
||||||
go_value: Optional[int] = Field(title='派遣阈值')
|
go_value: Optional[int] = Field(title='派遣阈值', default=300)
|
||||||
go_is_push: Optional[str] = Field(title='派遣是否已推送')
|
go_is_push: Optional[str] = Field(title='派遣是否已推送', default='off')
|
||||||
transform_push: Optional[str] = Field(title='质变仪推送')
|
transform_push: Optional[str] = Field(title='质变仪推送', default='off')
|
||||||
transform_value: Optional[int] = Field(title='质变仪阈值')
|
transform_value: Optional[int] = Field(title='质变仪阈值', default=1000)
|
||||||
transform_is_push: Optional[str] = Field(title='质变仪是否已推送')
|
transform_is_push: Optional[str] = Field(title='质变仪是否已推送', default='off')
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 220 KiB After Width: | Height: | Size: 180 KiB |
@ -2,8 +2,8 @@ from pathlib import Path
|
|||||||
|
|
||||||
from PIL import ImageFont
|
from PIL import ImageFont
|
||||||
|
|
||||||
FONT_ORIGIN_PATH = Path(__file__).parent / 'SmileySans.ttf'
|
FONT_ORIGIN_PATH = Path(__file__).parent / 'yuanshen_origin.ttf'
|
||||||
|
|
||||||
|
|
||||||
def smile_font(size: int) -> ImageFont.FreeTypeFont:
|
def core_font(size: int) -> ImageFont.FreeTypeFont:
|
||||||
return ImageFont.truetype(str(FONT_ORIGIN_PATH), size=size)
|
return ImageFont.truetype(str(FONT_ORIGIN_PATH), size=size)
|
BIN
gsuid_core/utils/fonts/yuanshen_origin.ttf
Normal file
BIN
gsuid_core/utils/fonts/yuanshen_origin.ttf
Normal file
Binary file not shown.
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user