diff --git a/.gitignore b/.gitignore index b5b4e04..b589ae7 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,8 @@ help_preview.html __rank_preview.html __rank_preview.png .playwright-cli/ +# 预渲染回归产物(脚本 + 对比图,纯本地,不入库) +test_output/ # 本地文档 / 项目主页(不入库) index.html diff --git a/.vscode/settings.json b/.vscode/settings.json index 994214d..ffb29d9 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -17,4 +17,4 @@ "files.exclude": { "**/__pycache__": true } -} +} \ No newline at end of file diff --git a/TodayWaifu/help.py b/TodayWaifu/help.py index 88d6161..13953f9 100644 --- a/TodayWaifu/help.py +++ b/TodayWaifu/help.py @@ -16,7 +16,6 @@ from gsuid_core.help.draw_new_plugin_help import get_new_help from .shared import ( - BASE_DIR, LOG_PREFIX, HELP_ICON_PATH, Bot, @@ -31,22 +30,44 @@ from .executor import run_blocking from ..daily_wife_config import DailyWifeShowConfig +# 横幅、背景、分类条与命令卡贴图统一由外部绘图资源包提供,路径在该包内解析。 +# 横幅/背景/分类条随风格成套切换,故不固定为模块级常量,而是每次调用时按风格解析; +# 命令卡片贴图与风格无关,是唯一可以全局固定的资源。 +from ..todaywaifu_help.get_help import ( + HELP_DATA as _HELP_JSON_PATH, + ICON_PATH as _ICON_PATH, + ITEM_PATH as _HELP_ITEM, + DEFAULT_STYLE as _HELP_DEFAULT_STYLE, + HELP_STYLE_NAMES as _HELP_STYLE_NAMES, + HELP_TEXT_COLORS, + HelpButtons, + resolve_style_path, + attach_command_icons, +) + # 资源签名:路径、mtime_ns、大小;缺失时为 None # 用 mtime_ns 而非秒级 mtime:同秒内的两次写入在秒级精度下无法区分,会漏掉重绘。 PathSignature = tuple[str, int, int] | None -# 帮助缓存键:5 个资源签名 + 列数 + 权限等级(见 _help_cache_key) +# 帮助缓存键:7 个资源签名 + 列数 + 权限等级 + 风格编号(见 _help_cache_key) # 权限等级参与键是因为帮助内容随权限裁剪,不同权限的用户不能共用同一张图。 +# 分类条与命令卡贴图同样计入签名:它们参与渲染,替换后若不换键会长期显示旧图。 +# 风格编号显式入键:横幅/背景/分类条按风格成套切换,仅靠路径签名虽也能区分, +# 但一旦两套风格共用某张资源,键就会静默复用另一种风格的旧图。 HelpCacheKey = tuple[ - PathSignature, PathSignature, PathSignature, PathSignature, PathSignature, int, int + PathSignature, + PathSignature, + PathSignature, + PathSignature, + PathSignature, + tuple[PathSignature, ...], + PathSignature, + int, + int, + int, ] # 帮助图缓存容量刻意很小(4):键维度多,不同键的图几乎不会复用, # 保留过多只会长期占用内存中较大的位图。 -_HELP_JSON_PATH = BASE_DIR / 'help.json' -_TEXTURE_DIR = BASE_DIR / 'texture2d' -_BANNER_BG_PATH = _TEXTURE_DIR / 'help_banner.png' -_BG_PATH = _TEXTURE_DIR / 'help_bg.jpg' -_ICON_PATH = _TEXTURE_DIR / 'icons' _HELP_CACHE_MAX_ENTRIES = 4 _HELP_CACHE: OrderedDict[HelpCacheKey, str] = OrderedDict() # 在途渲染合并表:同一键的并发请求共享一次渲染,否则同时多人触发帮助会重复起绘图任务。 @@ -70,6 +91,20 @@ def _show_config_path(key: str) -> Path | None: return path if path.is_file() else None +def _help_style() -> int: + """读出配置里的帮助图风格编号,越界或非整数一律回落到默认风格。 + + 风格决定整套横幅/背景/分类条贴图,取值非法时不能静默套用另一套风格, + 因此这里先夹到已知编号区间再交由 resolve_style_path 解析目录。 + """ + value = DailyWifeShowConfig.get_config('DailyWifeHelpStyle').data + try: + style = int(value) + except (TypeError, ValueError): + style = _HELP_DEFAULT_STYLE + return style if style in _HELP_STYLE_NAMES else _HELP_DEFAULT_STYLE + + def _help_column() -> int: # 列数必须夹在 [1, 10]:绘图布局在超出该范围时会溢出画布或除零, # 非法配置按默认 3 列处理。 @@ -97,18 +132,25 @@ def _help_cache_key( icon_path: Path, banner_bg_path: Path, help_bg_path: Path, + text_path: Path, + style: int, column: int, pm: int, ) -> HelpCacheKey: - # 五个签名对应五份参与渲染的资源,缺一都会导致「换了图但帮助未更新」。 + # 每个签名对应一份参与渲染的资源,缺一都会导致「换了图但帮助未更新」。 return ( _path_signature(_HELP_JSON_PATH), _path_signature(icon_path), _path_signature(banner_bg_path), _path_signature(help_bg_path), _path_signature(_ICON_PATH), + # 分类条为多张轮换,故整组取签名;命令卡为单张。 + tuple(_path_signature(path) for path in sorted(text_path.glob('cag_bg*.png'))), + # 命令卡与风格无关,取共用的那一份。 + _path_signature(_HELP_ITEM), column, pm, + style, ) @@ -116,35 +158,41 @@ def _build_help_inputs( plugin_icon_path: Path, custom_banner_bg_path: Path | None, custom_help_bg_path: Path | None, -) -> tuple[Image.Image, dict[str, PluginHelp], dict[str, Image.Image | Path]]: + text_path: Path, +) -> tuple[ + Image.Image, + dict[str, PluginHelp], + dict[str, Image.Image | Path | list[Image.Image]], +]: """在线程中读取 JSON 和 PIL 资源,避免阻塞事件循环。""" with Image.open(plugin_icon_path) as source: icon = source.convert('RGBA') - extra: dict[str, Image.Image | Path] = {} - banner_bg_path = custom_banner_bg_path or _BANNER_BG_PATH + extra: dict[str, Image.Image | Path | list[Image.Image]] = {} + # text_path 是当前风格的内置贴图目录,仅在用户未上传自定义图时才作为回落。 + banner_bg_path = custom_banner_bg_path or text_path / 'banner_bg.jpg' if banner_bg_path.is_file(): with Image.open(banner_bg_path) as source: - banner = source.convert('RGBA') - if custom_banner_bg_path is None: - # 内置横幅只取顶部 40%:原图是整幅插画,直接使用会让横幅比例失真。 - width, height = banner.size - extra['banner_bg'] = banner.crop((0, 0, width, int(height * 0.40))) - else: - # 用户自定义横幅已按横幅比例制作,原样使用,不做裁切。 - extra['banner_bg'] = banner.copy() - - help_bg_path = custom_help_bg_path or _BG_PATH + # 横幅已按横幅比例制作,内置与自定义都不再裁切。 + extra['banner_bg'] = source.convert('RGBA') + + help_bg_path = custom_help_bg_path or text_path / 'bg.jpg' if help_bg_path.is_file(): with Image.open(help_bg_path) as source: - # 背景按画布尺寸等比覆盖裁切,不做纯色填充(浅色主题下会露出色带) - extra['help_bg'] = source.convert('RGBA').copy() + extra['help_bg'] = source.convert('RGBA') # 图标以目录形式传入而非逐个打开:绘图工具按需读取,避免一次性载入全部图标位图。 if _ICON_PATH.is_dir(): extra['icon_path'] = _ICON_PATH - return icon, _load_help_data(), extra + # 分类条与命令卡按卡片式版式绘制:分类条取自当前风格目录并多张轮换, + # 命令卡为两风格共用的单张。 + buttons = HelpButtons(text_path) + extra['cag_bg'] = buttons.cag_bg + extra['item_bg'] = buttons.item + + # 逐条命令补上图标:help.json 只写命令名,图标需按别名表回查资源目录。 + return icon, attach_command_icons(_load_help_data(), _ICON_PATH), extra async def _render_help( @@ -152,6 +200,7 @@ async def _render_help( plugin_icon_path: Path, custom_banner_bg_path: Path | None, custom_help_bg_path: Path | None, + text_path: Path, column: int, pm: int, ) -> str: @@ -163,6 +212,7 @@ async def render() -> str: plugin_icon_path, custom_banner_bg_path, custom_help_bg_path, + text_path, ) return await get_new_help( plugin_name='TodayWaifu', @@ -177,6 +227,8 @@ async def render() -> str: enable_cache=False, column=column, pm=pm, + # 浅色立绘底上默认灰字几乎不可见,这里显式指定深色文字。 + **HELP_TEXT_COLORS, **extra, ) @@ -220,15 +272,21 @@ async def daily_wife_help(bot: Bot, ev: Event) -> list[str] | None: custom_banner_bg_path = _show_config_path('DailyWifeHelpBannerBgUpload') custom_help_bg_path = _show_config_path('DailyWifeHelpBgUpload') + # 风格决定内置横幅/背景/分类条取自哪一套贴图;先解析出目录再据此拼路径, + # 这样键中登记的路径与 _build_help_inputs 的实际取值必然一致。 + style = _help_style() + text_path = resolve_style_path(style) # 键中登记的是实际参与渲染的路径(自定义或内置),与 _build_help_inputs 的选择 # 逻辑保持一致,否则自定义图切换后缓存键不变,帮助图不会更新。 - banner_bg_path = custom_banner_bg_path or _BANNER_BG_PATH - help_bg_path = custom_help_bg_path or _BG_PATH + banner_bg_path = custom_banner_bg_path or text_path / 'banner_bg.jpg' + help_bg_path = custom_help_bg_path or text_path / 'bg.jpg' column = _help_column() key = _help_cache_key( plugin_icon_path, banner_bg_path, help_bg_path, + text_path, + style, column, int(ev.user_pm), ) @@ -239,6 +297,7 @@ async def daily_wife_help(bot: Bot, ev: Event) -> list[str] | None: plugin_icon_path, custom_banner_bg_path, custom_help_bg_path, + text_path, column, int(ev.user_pm), ) diff --git a/config_default.py b/config_default.py index 3fd67e7..63cc50a 100644 --- a/config_default.py +++ b/config_default.py @@ -34,15 +34,13 @@ ), 'DailyWifePgrImageSource': GsStrConfig( '战双老婆图片数据源', - '选择 local 只使用本地战双图库目录;' - '选择 gallery 优先使用远程图库接口,接口不可用时回退本地。默认 gallery', + '选择 local 只使用本地战双图库目录;选择 gallery 优先使用远程图库接口,接口不可用时回退本地。默认 gallery', 'gallery', options=['local', 'gallery'], ), 'DailyLoliImageSource': GsStrConfig( '萝莉图片数据源', - '选择 local 只使用本地萝莉图库;' - '选择 gallery 优先使用远程图库接口,接口不可用时回退本地。默认 gallery', + '选择 local 只使用本地萝莉图库;选择 gallery 优先使用远程图库接口,接口不可用时回退本地。默认 gallery', 'gallery', options=['local', 'gallery'], ), @@ -122,7 +120,6 @@ '允许使用本插件全部图片上传功能的用户 ID。机器人主人无需加入白名单', [], ), - '_DividerNteWife': GsDivider('异环老婆', ''), 'DailyWifeNteEnabled': GsBoolConfig( '启用今日异环老婆', @@ -197,10 +194,7 @@ ), 'DailyWifeShowUserId': GsBoolConfig( '显示触发者 ID', - ( - '开启后文字说明额外附带一行“你的ID:xxx”,' - '方便 QQ 官方机器人等平台的群友复制 OpenID 进行抢老婆/送老婆' - ), + ('开启后文字说明额外附带一行“你的ID:xxx”,方便 QQ 官方机器人等平台的群友复制 OpenID 进行抢老婆/送老婆'), False, ), 'DailyWifeDebugMode': GsBoolConfig( @@ -208,7 +202,6 @@ '开启后机器人主人每次抽取都会临时随机重抽,不读取或写入当天记录,便于调试', False, ), - '_DividerAssignWife': GsDivider('分配老婆', ''), 'DailyWifeAssignWhitelist': GsListStrConfig( '分配老婆白名单', @@ -220,14 +213,12 @@ '允许使用指定老婆功能的用户 ID。机器人主人无需加入白名单;功能开关和权限可在“今日老婆-指定老婆”服务中配置', [], ), - '_DividerDailyWife': GsDivider('今日老婆', ''), 'DailyWifeTextTemplate': GsStrConfig( '今日老婆文字模板', '今日老婆的文字说明模板,可用变量:{name} 角色名,{role_id} 数字 ID', '你今天的老婆是{name}', ), - '_DividerGroupMember': GsDivider('群友玩法', ''), 'DailyWifeEnableGroupMember': GsBoolConfig( '今日老婆概率抽群友', @@ -254,7 +245,6 @@ '「娶群友」命令的文字说明模板,可用变量:{name} 群友昵称,{user_id} 群友 QQ', '你娶到的群友是{name}', ), - '_DividerDailyHusband': GsDivider('今日老公', ''), 'DailyWifeHusbandEnabled': GsBoolConfig( '启用今日老公', @@ -266,14 +256,12 @@ '今日老公的文字说明模板,可用变量:{name} 角色名,{role_id} 数字 ID', '你今天的老公是{name}', ), - '_DividerDailyLoli': GsDivider('今日萝莉', ''), 'DailyLoliEnabled': GsBoolConfig( '启用今日萝莉', '开启后可使用「今日萝莉」命令;关闭后命令不生效。图片内容风险请自行承担', True, ), - '_DividerDailyShota': GsDivider('今日正太', ''), 'DailyShotaEnabled': GsBoolConfig( '启用今日正太', @@ -285,7 +273,6 @@ '今日正太的文字说明模板', '你今天的正太来啦!', ), - '_DividerRob': GsDivider('抢夺设置', ''), 'DailyWifeRobEnabled': GsBoolConfig( '启用抢老婆', @@ -342,7 +329,6 @@ '可用变量:{name} 名称,{role_id} 图片标识,{target} 被抢用户 ID', '抢正太成功!你把对方今天的正太抢过来了!', ), - '_DividerGift': GsDivider('赠送设置', ''), 'DailyWifeGiftEnabled': GsBoolConfig( '启用送老婆', @@ -411,10 +397,17 @@ 'help_icon', 'png', ), + 'DailyWifeHelpStyle': GsIntConfig( + '帮助图风格', + '控制帮助图整体配色:1=二次元风格(立绘横幅+渐变分类条),2=手绘风格(柔和手绘底+爱心分类条)。默认 2', + 2, + 2, + options=[1, 2], + ), 'DailyWifeHelpColumn': GsIntConfig( - '帮助展示行数', - '控制帮助图每组展示数量,默认 4,可按需要调整', - 4, - 10, + '帮助图宽度(每行列数)', + '控制帮助图一行放几条命令:4 更紧凑,3 留白更多。数值越大画布越宽;上限 5,超过会溢出画布', + 3, + 5, ), } diff --git a/tests/compatibility_manifest.json b/tests/compatibility_manifest.json index 2aa826f..bc80f45 100644 --- a/tests/compatibility_manifest.json +++ b/tests/compatibility_manifest.json @@ -324,9 +324,13 @@ "key": "DailyWifeHelpIconUpload", "expr": "GsImageConfig('帮助头像', '自定义「今日老婆帮助」左上角头像,建议使用方形图片', str(SHOW_CONFIG_PATH / 'help_icon.png'), str(SHOW_CONFIG_PATH), 'help_icon', 'png')" }, + { + "key": "DailyWifeHelpStyle", + "expr": "GsIntConfig('帮助图风格', '控制帮助图整体配色:1=二次元风格(立绘横幅+渐变分类条),2=手绘风格(柔和手绘底+爱心分类条)。默认 2', 2, 2, options=[1, 2])" + }, { "key": "DailyWifeHelpColumn", - "expr": "GsIntConfig('帮助展示行数', '控制帮助图每组展示数量,默认 4,可按需要调整', 4, 10)" + "expr": "GsIntConfig('帮助图宽度(每行列数)', '控制帮助图一行放几条命令:4 更紧凑,3 留白更多。数值越大画布越宽;上限 5,超过会溢出画布', 4, 5)" } ] }, diff --git a/todaywaifu_help/__init__.py b/todaywaifu_help/__init__.py new file mode 100644 index 0000000..ae46921 --- /dev/null +++ b/todaywaifu_help/__init__.py @@ -0,0 +1,33 @@ +"""TodayWaifu 帮助图渲染。 + +命令入口仍在 TodayWaifu/help.py(priority=0,避免被「今日老婆」前缀截获)。 + +提供两套可切换的绘图风格(1=二次元风格,2=手绘风格,默认 2), +分类条、背景与横幅按风格成套切换,命令卡片贴图两风格共用。 +""" + +from .get_help import ( + ICON, + ICON_PATH, + ITEM_PATH, + TEXT_PATH, + HELP_STYLES, + DEFAULT_STYLE, + HELP_STYLE_NAMES, + HelpButtons, + get_help, + resolve_style_path, +) + +__all__ = [ + "ICON", + "ICON_PATH", + "TEXT_PATH", + "ITEM_PATH", + "HELP_STYLES", + "HELP_STYLE_NAMES", + "DEFAULT_STYLE", + "HelpButtons", + "get_help", + "resolve_style_path", +] diff --git a/todaywaifu_help/get_help.py b/todaywaifu_help/get_help.py new file mode 100644 index 0000000..d26ca1f --- /dev/null +++ b/todaywaifu_help/get_help.py @@ -0,0 +1,176 @@ +from __future__ import annotations + +import json +from typing import Dict, Optional +from pathlib import Path + +import aiofiles +from PIL import Image + +from gsuid_core.help.model import PluginHelp +from gsuid_core.help.draw_new_plugin_help import get_new_help + +PLUGIN_DIR = Path(__file__).resolve().parent.parent +ICON = PLUGIN_DIR / "ICON.png" +HELP_DATA = PLUGIN_DIR / "help.json" +ICON_PATH = PLUGIN_DIR / "texture2d" / "icons" +TEXT_PATH = Path(__file__).resolve().parent / "texture2d" +# 命令卡片贴图与风格无关:两种风格下都是同一张 490x175,故只存一份共用, +# 不放进风格目录里重复两遍。 +ITEM_PATH = TEXT_PATH / "item.png" + +# 帮助图风格编号 -> 该风格的横幅/背景/分类条所在子目录。 +# 分类条、背景与横幅是一整套配色,交叉取用(如手绘横幅配二次元分类条)会明显割裂, +# 故按风格整套切换,不提供跨风格混搭的入口。 +HELP_STYLES: Dict[int, Path] = { + 1: TEXT_PATH / "anime", + 2: TEXT_PATH / "handdrawn", +} +HELP_STYLE_NAMES: Dict[int, str] = { + 1: "二次元风格", + 2: "手绘风格", +} +# 手绘风格为默认:底色柔和浅,深色标题文字在其上对比度最高、最易读。 +DEFAULT_STYLE = 2 + +# 浅色立绘底上,light 模式默认灰 (102,102,102) 几乎看不见 +HELP_TEXT_COLORS = { + "banner_title_color": (10, 12, 16), + "banner_sub_color": (22, 24, 30), + "cag_title_color": (10, 12, 16), + "cag_sub_color": (22, 24, 30), +} + +# help.json 命令名 -> texture2d/icons 文件名(不含后缀) +ICON_ALIAS: Dict[str, str] = { + "今日老婆": "今日老婆", + "今日老公": "今日老公", + "今日异环老婆": "今日老婆", + "今日战双老婆": "今日老婆", + "上传战双老婆图片": "老婆上传图片", + "今日普通老婆": "今日老婆", + "老婆列表": "老婆列表", + "老公列表": "老公列表", + "普通老婆列表": "老婆列表", + "抢老婆": "抢老婆", + "送老婆": "送老婆", + "接受老婆赠送": "同意送老婆", + "拒绝老婆赠送": "拒绝送老婆", + "抢老公": "抢老婆", + "送老公": "送老婆", + "接受老公赠送": "同意送老婆", + "拒绝老公赠送": "拒绝送老婆", + "离婚": "老婆删除", + "老公离婚": "老婆删除", + "娶群友": "娶群友", + "今日萝莉": "今日萝莉", + "抢萝莉": "抢老婆", + "送萝莉": "送老婆", + "接受萝莉赠送": "同意送老婆", + "拒绝萝莉赠送": "拒绝送老婆", + "萝莉离婚": "删除萝莉图片", + "上传萝莉图片": "今日萝莉上传", + "查看萝莉图片": "今日萝莉列表", + "删除萝莉图片": "删除萝莉图片", + # 今日正太与今日萝莉同构,复用萝莉一套图标。 + "今日正太": "今日萝莉", + "抢正太": "抢老婆", + "送正太": "送老婆", + "接受正太赠送": "同意送老婆", + "拒绝正太赠送": "拒绝送老婆", + "正太离婚": "老婆删除", + "创建老婆": "老婆创建", + "上传老婆图片": "老婆上传图片", + "查看老婆图片": "老婆图片列表", + "删除老婆": "老婆删除", + "分配老婆": "分配老婆", +} + + +class HelpButtons: + """帮助图按钮贴图包:item 为命令卡片,cag_bg 为分类条(可多张循环)。 + + 卡片贴图两种风格共用,故从 texture2d 根目录取;分类条按风格取自各自子目录。 + """ + + def __init__(self, text_path: Path = TEXT_PATH, item_path: Path = ITEM_PATH): + self.item = Image.open(item_path).convert("RGBA") + numbered = sorted( + text_path.glob("cag_bg_[0-9]*.png"), + key=lambda p: p.stem, + ) + if numbered: + self.cag_bg = [Image.open(path).convert("RGBA") for path in numbered] + else: + self.cag_bg = [Image.open(text_path / "cag_bg.png").convert("RGBA")] + + +def resolve_style_path(style: int) -> Path: + """把配置里的风格编号解析成贴图目录,未知编号回落到默认风格。 + + 该值来自用户手填的配置,可能越界或根本不是整数;此处不抛错而是回落到默认风格, + 避免一个无效取值让整个帮助命令不可用。 + """ + return HELP_STYLES.get(style, HELP_STYLES[DEFAULT_STYLE]) + + +def attach_command_icons( + plugin_help: Dict[str, PluginHelp], icon_path: Path +) -> Dict[str, PluginHelp]: + for group in plugin_help.values(): + for item in group.get("data", []): + name = str(item.get("name", "")) + stem = ICON_ALIAS.get(name, name) + icon_file = icon_path / f"{stem}.png" + if icon_file.is_file(): + item["icon"] = str(icon_file) + return plugin_help + + +async def get_help_data() -> Dict[str, PluginHelp]: + async with aiofiles.open(HELP_DATA, "rb") as file: + return json.loads(await file.read()) + + +async def get_help( + pm: int = 6, + *, + plugin_icon: Optional[Image.Image] = None, + banner_bg: Optional[Image.Image] = None, + help_bg: Optional[Image.Image] = None, + icon_path: Optional[Path] = None, + column: int = 4, + style: int = DEFAULT_STYLE, + enable_cache: bool = False, + plugin_prefix: str = "", +): + icon_dir = icon_path or ICON_PATH + # 横幅/背景/分类条统一按风格取,避免交叉取用产生割裂的配色。 + text_dir = resolve_style_path(style) + plugin_help = attach_command_icons(await get_help_data(), icon_dir) + buts = HelpButtons(text_dir) + if plugin_icon is None: + plugin_icon = Image.open(ICON).convert("RGBA") + if banner_bg is None: + banner_bg = Image.open(text_dir / "banner_bg.jpg").convert("RGBA") + if help_bg is None: + help_bg = Image.open(text_dir / "bg.jpg").convert("RGBA") + + return await get_new_help( + plugin_name="TodayWaifu", + plugin_info={"v1.0": ""}, + plugin_icon=plugin_icon, + plugin_help=plugin_help, + plugin_prefix=plugin_prefix, + help_mode="light", + banner_bg=banner_bg, + banner_sub_text="找到你今天的她", + help_bg=help_bg, + cag_bg=buts, + item_bg=buts.item, + icon_path=icon_dir, + enable_cache=enable_cache, + column=column, + pm=pm, + **HELP_TEXT_COLORS, + ) diff --git a/todaywaifu_help/texture2d/anime/banner_bg.jpg b/todaywaifu_help/texture2d/anime/banner_bg.jpg new file mode 100644 index 0000000..3a67ee3 Binary files /dev/null and b/todaywaifu_help/texture2d/anime/banner_bg.jpg differ diff --git a/todaywaifu_help/texture2d/anime/bg.jpg b/todaywaifu_help/texture2d/anime/bg.jpg new file mode 100644 index 0000000..dd4c63f Binary files /dev/null and b/todaywaifu_help/texture2d/anime/bg.jpg differ diff --git a/todaywaifu_help/texture2d/anime/cag_bg_1.png b/todaywaifu_help/texture2d/anime/cag_bg_1.png new file mode 100644 index 0000000..b4348ce Binary files /dev/null and b/todaywaifu_help/texture2d/anime/cag_bg_1.png differ diff --git a/todaywaifu_help/texture2d/anime/cag_bg_2.png b/todaywaifu_help/texture2d/anime/cag_bg_2.png new file mode 100644 index 0000000..aabb85e Binary files /dev/null and b/todaywaifu_help/texture2d/anime/cag_bg_2.png differ diff --git a/todaywaifu_help/texture2d/anime/cag_bg_3.png b/todaywaifu_help/texture2d/anime/cag_bg_3.png new file mode 100644 index 0000000..4a00e3c Binary files /dev/null and b/todaywaifu_help/texture2d/anime/cag_bg_3.png differ diff --git a/todaywaifu_help/texture2d/anime/cag_bg_4.png b/todaywaifu_help/texture2d/anime/cag_bg_4.png new file mode 100644 index 0000000..d3a6981 Binary files /dev/null and b/todaywaifu_help/texture2d/anime/cag_bg_4.png differ diff --git a/todaywaifu_help/texture2d/handdrawn/banner_bg.jpg b/todaywaifu_help/texture2d/handdrawn/banner_bg.jpg new file mode 100644 index 0000000..9d3153d Binary files /dev/null and b/todaywaifu_help/texture2d/handdrawn/banner_bg.jpg differ diff --git a/todaywaifu_help/texture2d/handdrawn/bg.jpg b/todaywaifu_help/texture2d/handdrawn/bg.jpg new file mode 100644 index 0000000..2568d8d Binary files /dev/null and b/todaywaifu_help/texture2d/handdrawn/bg.jpg differ diff --git a/todaywaifu_help/texture2d/handdrawn/cag_bg_1.png b/todaywaifu_help/texture2d/handdrawn/cag_bg_1.png new file mode 100644 index 0000000..82b6582 Binary files /dev/null and b/todaywaifu_help/texture2d/handdrawn/cag_bg_1.png differ diff --git a/todaywaifu_help/texture2d/handdrawn/cag_bg_2.png b/todaywaifu_help/texture2d/handdrawn/cag_bg_2.png new file mode 100644 index 0000000..2fa2f40 Binary files /dev/null and b/todaywaifu_help/texture2d/handdrawn/cag_bg_2.png differ diff --git a/todaywaifu_help/texture2d/handdrawn/cag_bg_3.png b/todaywaifu_help/texture2d/handdrawn/cag_bg_3.png new file mode 100644 index 0000000..9746ab4 Binary files /dev/null and b/todaywaifu_help/texture2d/handdrawn/cag_bg_3.png differ diff --git a/todaywaifu_help/texture2d/handdrawn/cag_bg_4.png b/todaywaifu_help/texture2d/handdrawn/cag_bg_4.png new file mode 100644 index 0000000..eae966c Binary files /dev/null and b/todaywaifu_help/texture2d/handdrawn/cag_bg_4.png differ diff --git a/todaywaifu_help/texture2d/item.png b/todaywaifu_help/texture2d/item.png new file mode 100644 index 0000000..a0b4e89 Binary files /dev/null and b/todaywaifu_help/texture2d/item.png differ