diff --git a/gsuid_core/help/draw_help.py b/gsuid_core/help/draw_help.py index 5cb0ea6..4495e58 100644 --- a/gsuid_core/help/draw_help.py +++ b/gsuid_core/help/draw_help.py @@ -6,7 +6,7 @@ from PIL import Image, ImageDraw from gsuid_core.sv import SV # 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' 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_draw = ImageDraw.Draw(tag) 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 return tag @@ -65,7 +65,7 @@ def get_command_bg(command: str, tag_type: str): img = Image.new('RGBA', (220, 40)) img_draw = ImageDraw.Draw(img) 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) img.paste(tag, (160, 0), tag) 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.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((770, 15, 820, 50), 10, _c(sv.pm)) sv_img_draw.rounded_rectangle((830, 15, 880, 50), 10, _c(sv.area)) 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( - (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( - (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) @@ -152,7 +152,7 @@ def get_plugin_bg(plugin_name: str, sv_list: List[SV]): ) img_draw = ImageDraw.Draw(img) 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 for _img in img_list: diff --git a/gsuid_core/plugins/core_command/core_user/__init__.py b/gsuid_core/plugins/core_command/core_user/__init__.py new file mode 100644 index 0000000..c639662 --- /dev/null +++ b/gsuid_core/plugins/core_command/core_user/__init__.py @@ -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) diff --git a/gsuid_core/plugins/core_command/core_user/draw_user_card.py b/gsuid_core/plugins/core_command/core_user/draw_user_card.py new file mode 100644 index 0000000..21425eb --- /dev/null +++ b/gsuid_core/plugins/core_command/core_user/draw_user_card.py @@ -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) diff --git a/gsuid_core/plugins/core_command/core_user/texture2d/status_off.png b/gsuid_core/plugins/core_command/core_user/texture2d/status_off.png new file mode 100644 index 0000000..7d3b8f0 Binary files /dev/null and b/gsuid_core/plugins/core_command/core_user/texture2d/status_off.png differ diff --git a/gsuid_core/plugins/core_command/core_user/texture2d/status_on.png b/gsuid_core/plugins/core_command/core_user/texture2d/status_on.png new file mode 100644 index 0000000..f289fe8 Binary files /dev/null and b/gsuid_core/plugins/core_command/core_user/texture2d/status_on.png differ diff --git a/gsuid_core/plugins/core_command/core_user/texture2d/user_bg.png b/gsuid_core/plugins/core_command/core_user/texture2d/user_bg.png new file mode 100644 index 0000000..56e89eb Binary files /dev/null and b/gsuid_core/plugins/core_command/core_user/texture2d/user_bg.png differ diff --git a/gsuid_core/plugins/core_command/core_user/texture2d/user_title.png b/gsuid_core/plugins/core_command/core_user/texture2d/user_title.png new file mode 100644 index 0000000..d969e3b Binary files /dev/null and b/gsuid_core/plugins/core_command/core_user/texture2d/user_title.png differ diff --git a/gsuid_core/utils/database/dal.py b/gsuid_core/utils/database/dal.py index b513cbd..337e2e5 100644 --- a/gsuid_core/utils/database/dal.py +++ b/gsuid_core/utils/database/dal.py @@ -44,6 +44,8 @@ class SQLA: 'ALTER TABLE GsUser ADD COLUMN sr_region TEXT', 'ALTER TABLE GsUser ADD COLUMN fp 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', ] async with self.async_session() as session: @@ -338,6 +340,8 @@ class SQLA: else None, fp=fp, device_id=device_id, + sr_push_switch='off', + sr_sign_switch='off', ) session.add(user_data) await session.commit() @@ -565,7 +569,7 @@ class SQLA: return None async def get_switch_status_list( - self, switch: Literal['push', 'sign', 'bbs'] + self, switch: Literal['push', 'sign', 'bbs', 'sr_push', 'sr_sign'] ) -> List[GsUser]: async with self.async_session() as session: async with session.begin(): diff --git a/gsuid_core/utils/database/models.py b/gsuid_core/utils/database/models.py index a869125..4d320c6 100644 --- a/gsuid_core/utils/database/models.py +++ b/gsuid_core/utils/database/models.py @@ -28,6 +28,8 @@ class GsUser(SQLModel, table=True): push_switch: str = Field(title='全局推送开关') sign_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='状态') fp: Optional[str] = Field(default=None, title='Fingerprint') 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='序号') bot_id: str = Field(title='平台') uid: str = Field(default=None, title='原神UID') - coin_push: Optional[str] = Field(title='洞天宝钱推送') - coin_value: Optional[int] = Field(title='洞天宝钱阈值') - coin_is_push: Optional[str] = Field(title='洞天宝钱是否已推送') - resin_push: Optional[str] = Field(title='体力推送') - resin_value: Optional[int] = Field(title='体力阈值') - resin_is_push: Optional[str] = Field(title='体力是否已推送') - go_push: Optional[str] = Field(title='派遣推送') - go_value: Optional[int] = Field(title='派遣阈值') - go_is_push: Optional[str] = Field(title='派遣是否已推送') - transform_push: Optional[str] = Field(title='质变仪推送') - transform_value: Optional[int] = Field(title='质变仪阈值') - transform_is_push: Optional[str] = Field(title='质变仪是否已推送') + coin_push: Optional[str] = Field(title='洞天宝钱推送', default='off') + coin_value: Optional[int] = Field(title='洞天宝钱阈值', default=2100) + coin_is_push: Optional[str] = Field(title='洞天宝钱是否已推送', default='off') + resin_push: Optional[str] = Field(title='体力推送', default='off') + resin_value: Optional[int] = Field(title='体力阈值', default=140) + resin_is_push: Optional[str] = Field(title='体力是否已推送', default='off') + go_push: Optional[str] = Field(title='派遣推送', default='off') + go_value: Optional[int] = Field(title='派遣阈值', default=300) + go_is_push: Optional[str] = Field(title='派遣是否已推送', default='off') + transform_push: Optional[str] = Field(title='质变仪推送', default='off') + transform_value: Optional[int] = Field(title='质变仪阈值', default=1000) + transform_is_push: Optional[str] = Field(title='质变仪是否已推送', default='off') diff --git a/gsuid_core/utils/default_bg/bg.jpg b/gsuid_core/utils/default_bg/bg.jpg index ed6924e..76042e0 100644 Binary files a/gsuid_core/utils/default_bg/bg.jpg and b/gsuid_core/utils/default_bg/bg.jpg differ diff --git a/gsuid_core/utils/smile_fonts/smile_fonts.py b/gsuid_core/utils/fonts/fonts.py similarity index 50% rename from gsuid_core/utils/smile_fonts/smile_fonts.py rename to gsuid_core/utils/fonts/fonts.py index da218b9..298c49b 100644 --- a/gsuid_core/utils/smile_fonts/smile_fonts.py +++ b/gsuid_core/utils/fonts/fonts.py @@ -2,8 +2,8 @@ from pathlib import Path 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) diff --git a/gsuid_core/utils/fonts/yuanshen_origin.ttf b/gsuid_core/utils/fonts/yuanshen_origin.ttf new file mode 100644 index 0000000..cd3ecd4 Binary files /dev/null and b/gsuid_core/utils/fonts/yuanshen_origin.ttf differ diff --git a/gsuid_core/utils/smile_fonts/SmileySans.ttf b/gsuid_core/utils/smile_fonts/SmileySans.ttf deleted file mode 100644 index 052a2f7..0000000 Binary files a/gsuid_core/utils/smile_fonts/SmileySans.ttf and /dev/null differ