diff --git a/liteyuki/liteyuki_main/runtime.py b/liteyuki/liteyuki_main/runtime.py index 62723cb0..fdbcef3f 100644 --- a/liteyuki/liteyuki_main/runtime.py +++ b/liteyuki/liteyuki_main/runtime.py @@ -1,3 +1,4 @@ +import json import platform import nonebot @@ -7,15 +8,17 @@ from nonebot import on_command from nonebot.adapters.onebot.v11 import MessageSegment from nonebot.permission import SUPERUSER -from liteyuki.utils import __NAME__, __VERSION__ +from liteyuki.utils import __NAME__, __VERSION__, load_from_yaml from liteyuki.utils.htmlrender import template2image -from liteyuki.utils.language import get_user_lang +from liteyuki.utils.language import Language, get_default_lang, get_user_lang from liteyuki.utils.ly_typing import T_Bot, T_MessageEvent from liteyuki.utils.resource import get_path from liteyuki.utils.tools import convert_size stats = on_command("stats", aliases={"状态"}, priority=5, permission=SUPERUSER) +config = load_from_yaml("config.yml") + protocol_names = { 0: "iPad", 1: "Android Phone", @@ -29,19 +32,108 @@ protocol_names = { @stats.handle() async def _(bot: T_Bot, event: T_MessageEvent): ulang = get_user_lang(str(event.user_id)) - fake_device_info: dict = bot.config.dict().get("fake_device_info", {}) - mem_total = fake_device_info.get('mem', {}).get('total', psutil.virtual_memory().total) + image = await template2image( + get_path("templates/stats.html", abs_path=True), + { + "data": await get_stats_data(bot.self_id, ulang.lang_code) + }, + debug=True + ) + await stats.finish(MessageSegment.image(image)) + + +async def get_bots_data(ulang: Language, self_id: "") -> list: + bots_data = [] + for bot_id, bot in nonebot.get_bots().items(): + groups = 0 + friends = 0 + status = {} + bot_name = bot_id + version_info = {} + try: + bot_name = (await bot.get_login_info())["nickname"] + groups = len(await bot.get_group_list()) + friends = len(await bot.get_friend_list()) + status = await bot.get_status() + version_info = await bot.get_version_info() + except Exception: + pass + + statistics = status.get("stat", {}) + app_name = version_info.get("app_name", "UnknownImplementation") + if app_name in ["Lagrange.OneBot", "LLOneBot", "Shamrock"]: + icon = f"https://q.qlogo.cn/g?b=qq&nk={bot_id}&s=640" + else: + icon = "./img/liteyuki.png" + bot_data = { + "name": bot_name, + "icon": icon, + "id" : bot_id, + "tags": [ + protocol_names.get(version_info.get("protocol_name"), "Online"), + f"{ulang.get('liteyuki.stats.groups')} {groups}", + f"{ulang.get('liteyuki.stats.friends')} {friends}", + f"{ulang.get('liteyuki.stats.sent')} {statistics.get('message_sent', 0)}", + f"{ulang.get('liteyuki.stats.received')} {statistics.get('message_received', 0)}", + app_name, + + ], + "self": bot_id == self_id, # 判断是否是自己 + } + bots_data.append(bot_data) + bots_data.append( + { + "name": "Liteyuki", + "icon": "./img/liteyuki.png", + "id" : "liteyuki", + "tags": [ + f"{__NAME__} {__VERSION__}", + f"{ulang.get('liteyuki.stats.plugins')} {len(nonebot.get_loaded_plugins())}", + f"Nonebot {nonebot.__version__}", + f"{platform.python_implementation()} {platform.python_version()}", + ] + } + ) + return bots_data + + +async def get_stats_data(self_id: str = None, lang: str = None): + if self_id is None: + self_id = list(nonebot.get_bots().keys())[0] if len(nonebot.get_bots()) > 0 else "liteyuki" + if lang is None: + ulang = get_default_lang() + else: + ulang = Language(lang) + + fake_device_info: dict = config.get("fake_device_info", {}) + + mem_info = psutil.virtual_memory() + mem_total = fake_device_info.get('mem', {}).get('total', mem_info.total) + + convert_size(mem_total, 1, False) + mem_total_show = convert_size(mem_total, 1) # 格式化带单位 mem_used_bot = psutil.Process().memory_info().rss - mem_used_other = psutil.virtual_memory().used - mem_used_bot - mem_free = mem_total - mem_used_other - mem_used_bot + mem_used_bot_show = convert_size(mem_used_bot, 1) + mem_used_other = mem_info.used - mem_used_bot + mem_free = mem_total - mem_info.used + mem_used_show = convert_size(mem_total - mem_used_bot - mem_used_other, 1) # 计算已用格式化带单位 - groups = len(await bot.get_group_list()) - friends = len(await bot.get_friend_list()) + swap_info = psutil.swap_memory() - status = await bot.get_status() - statistics = status.get("stat", {}) - version_info = await bot.get_version_info() + disk_data = [] + for disk in psutil.disk_partitions(all=True): + disk_usage = psutil.disk_usage(disk.mountpoint) + disk_total_show = convert_size(disk_usage.total, 1) + disk_free_show = convert_size(disk_usage.free, 1) + disk_data.append( + { + "name" : disk.device, + "total" : disk_total_show, + "free" : disk_free_show, + "percent": disk_usage.percent, + } + ) cpu_info = get_cpu_info() if "AMD" in cpu_info.get("brand_raw", ""): @@ -56,7 +148,7 @@ async def _(bot: T_Bot, event: T_MessageEvent): cpu_info = get_cpu_info() templ = { - "CPUDATA" : [ + "cpu" : [ { "name" : "USED", "value": psutil.cpu_percent(interval=1) @@ -66,7 +158,7 @@ async def _(bot: T_Bot, event: T_MessageEvent): "value": 100 - psutil.cpu_percent(interval=1) } ], - "MEMDATA" : [ + "mem" : [ { "name" : "OTHER", @@ -81,7 +173,7 @@ async def _(bot: T_Bot, event: T_MessageEvent): "value": mem_used_bot }, ], - "SWAPDATA" : [ + "swap" : [ { "name" : "USED", "value": psutil.swap_memory().used @@ -91,44 +183,30 @@ async def _(bot: T_Bot, event: T_MessageEvent): "value": psutil.swap_memory().free } ], - "BOT_ID" : bot.self_id, - "BOT_NAME" : (await bot.get_login_info())["nickname"], - "BOT_TAGS" : [ - protocol_names.get(version_info.get("protocol_name"), "Online"), - f"{ulang.get('liteyuki.stats.plugins')} {len(nonebot.get_loaded_plugins())}", - f"{ulang.get('liteyuki.stats.groups')} {groups}", - f"{ulang.get('liteyuki.stats.friends')} {friends}", - f"{ulang.get('liteyuki.stats.sent')} {statistics.get('message_sent', 0)}", - f"{ulang.get('liteyuki.stats.received')} {statistics.get('message_received', 0)}", - f"{__NAME__} {__VERSION__}", - f"Nonebot {nonebot.__version__}", - f"{platform.python_implementation()} {platform.python_version()}", - version_info.get("app_name"), - ], - "CPU_TAGS" : [ + "disk" : disk_data, # list[{"name":"C", "total":100, "used":50, "free":50}] + "bot" : await get_bots_data(ulang, self_id), + "cpuTags" : [ f"{brand} {cpu_info.get('arch', 'Unknown')}", f"{fake_device_info.get('cpu', {}).get('cores', psutil.cpu_count(logical=False))}C " f"{fake_device_info.get('cpu', {}).get('logical_cores', psutil.cpu_count(logical=True))}T", f"{fake_device_info.get('cpu', {}).get('frequency', psutil.cpu_freq().current) / 1000}GHz" ], - "MEM_TAGS" : [ - f"Bot {convert_size(mem_used_bot, 1)}", - f"{ulang.get('main.monitor.used')} {convert_size(mem_used_other + mem_used_bot, 1)}", - f"{ulang.get('main.monitor.total')} {convert_size(mem_total, 1)}", + "memTags" : [ + f"Bot {mem_used_bot_show}", + f"{ulang.get('main.monitor.used')} {mem_used_show}", + f"{ulang.get('main.monitor.total')} {mem_total_show}", + f"{ulang.get('main.monitor.free')} {convert_size(mem_free, 1)}", ], - "SWAP_TAGS": [ - f"{ulang.get('main.monitor.used')} {convert_size(psutil.swap_memory().used, 1)}", - f"{ulang.get('main.monitor.total')} {convert_size(psutil.swap_memory().total, 1)}", + "swapTags" : [ + f"{ulang.get('main.monitor.used')} {convert_size(swap_info.used, 1)}", + f"{ulang.get('main.monitor.total')} {convert_size(swap_info.total, 1)}", + f"{ulang.get('main.monitor.free')} {convert_size(swap_info.free, 1)}", ], - "CPU" : ulang.get("main.monitor.cpu"), - "MEM" : ulang.get("main.monitor.memory"), - "SWAP" : ulang.get("main.monitor.swap"), + "cpu_trans" : ulang.get("main.monitor.cpu"), + "mem_trans" : ulang.get("main.monitor.memory"), + "swap_trans" : ulang.get("main.monitor.swap"), + "used_trans" : ulang.get("main.monitor.used"), + "free_trans" : ulang.get("main.monitor.free"), + "total_trans": ulang.get("main.monitor.total"), } - image_bytes = await template2image( - template=get_path("templates/stats.html", abs_path=True), - templates=templ, - scale_factor=1, - debug=True - ) - # await md.send_image(image_bytes, bot, event=event) - await stats.finish(MessageSegment.image(image_bytes)) + return templ diff --git a/liteyuki/plugins/liteyuki_weather/models.py b/liteyuki/plugins/liteyuki_weather/models.py index 3937f986..0b6340b2 100644 --- a/liteyuki/plugins/liteyuki_weather/models.py +++ b/liteyuki/plugins/liteyuki_weather/models.py @@ -1,4 +1,4 @@ - +from nonebot import on_command from liteyuki.utils.data import LiteModel @@ -11,3 +11,30 @@ class WeatherNow(LiteModel): time: str = "" city: str = "" + +weather = on_command("weather", aliases={"天气", "查天气", "天气预报", "查天气预报"}) +weather_now = on_command("weather_now", aliases={"实时天气", "查实时天气", "实时天气预报", "查实时天气预报"}) +weather_forecast = on_command("weather_forecast", aliases={"天气预报", "查天气预报", "未来天气", "查未来天气"}) +weather_warning = on_command("weather_warning", aliases={"天气预警", "查天气预警", "天气警告", "查天气警告"}) +weather_life = on_command("weather_life", aliases={"生活指数", "查生活指数", "生活指数预报", "查生活指数预报"}) +weather_air = on_command("weather_air", aliases={"空气质量", "查空气质量", "空气质量预报", "查空气质量预报"}) +weather_rain = on_command("weather_rain", aliases={"降雨预报", "查降雨预报", "降雨量", "查降雨量"}) +weather_snow = on_command("weather_snow", aliases={"降雪预报", "查降雪预报", "降雪量", "查降雪量"}) + + +@weather.handle() +async def handle_weather(bot, event): + args = str(event.get_message()).strip() + if not args: + await weather.finish("请输入要查询的城市") + else: + pass + + +@weather_now.handle() +async def handle_weather_now(bot, event): + pass + +@weather_forecast.handle() +async def handle_weather_forecast(bot, event): + pass diff --git a/liteyuki/resources/fonts/bold.ttf b/liteyuki/resources/fonts/bold.ttf deleted file mode 100644 index eda4bea1..00000000 Binary files a/liteyuki/resources/fonts/bold.ttf and /dev/null differ diff --git a/liteyuki/resources/fonts/heavy.ttf b/liteyuki/resources/fonts/heavy.ttf deleted file mode 100644 index 16d5c2b1..00000000 Binary files a/liteyuki/resources/fonts/heavy.ttf and /dev/null differ diff --git a/liteyuki/resources/fonts/normal.ttf b/liteyuki/resources/fonts/normal.ttf deleted file mode 100644 index efaedf2a..00000000 Binary files a/liteyuki/resources/fonts/normal.ttf and /dev/null differ diff --git a/liteyuki/resources/fonts/thin.ttf b/liteyuki/resources/fonts/thin.ttf deleted file mode 100644 index 17dd2a50..00000000 Binary files a/liteyuki/resources/fonts/thin.ttf and /dev/null differ diff --git a/liteyuki/resources/lang/de.lang b/liteyuki/resources/lang/de.lang index 43559e5e..09bcdccb 100644 --- a/liteyuki/resources/lang/de.lang +++ b/liteyuki/resources/lang/de.lang @@ -97,4 +97,5 @@ user.profile.set_failed={ATTR} festlegen fehlgeschlagen. Bitte überprüfen Sie, liteyuki.image_mode_on=Markdown-Bild liteyuki.image_mode_off=Markdown-Link -npm.page=Page {PAGE}/{TOTAL} \ No newline at end of file +npm.page=Page {PAGE}/{TOTAL} +main.monitor.free=Free \ No newline at end of file diff --git a/liteyuki/resources/lang/en.lang b/liteyuki/resources/lang/en.lang index ff5c223c..cc18e2a3 100644 --- a/liteyuki/resources/lang/en.lang +++ b/liteyuki/resources/lang/en.lang @@ -1,10 +1,10 @@ language.name=English -log.debug=Debug -log.info=Info -log.warning=Warning -log.error=Error -log.success=Success +log.debug=DEBUG +log.info=INFO +log.warning=WARNING +log.error=ERROR +log.success=SUCCESS liteyuki.restart=Restart liteyuki.restart_now=Restart Now @@ -97,4 +97,5 @@ user.profile.set_failed=Setting {ATTR} failed. Please check if the input is vali liteyuki.image_mode_on=Enable markdown image liteyuki.image_mode_off=Closed markdown image -npm.page=Page {PAGE}/{TOTAL} \ No newline at end of file +npm.page=Page {PAGE}/{TOTAL} +main.monitor.free=Free \ No newline at end of file diff --git a/liteyuki/resources/lang/es.lang b/liteyuki/resources/lang/es.lang index a345e7f4..742a3bdd 100644 --- a/liteyuki/resources/lang/es.lang +++ b/liteyuki/resources/lang/es.lang @@ -92,4 +92,10 @@ user.profile.nickname.desc=Establecer el apodo del Bot para el usuario user.profile.input_value=Por favor ingresa {ATTR} user.profile.set_success={ATTR} establecido correctamente a {VALUE} -user.profile.set_failed=Fallo al establecer {ATTR}. Por favor, verifica si la entrada es válida. \ No newline at end of file +user.profile.set_failed=Fallo al establecer {ATTR}. Por favor, verifica si la entrada es válida. + +liteyuki.image_mode_on=Markdown de imagen abierta +liteyuki.image_mode_off=Markdown de imagen cerrada + +npm.page=Página {PAGE}/{TOTAL} +main.monitor.free=Libre \ No newline at end of file diff --git a/liteyuki/resources/lang/fr.lang b/liteyuki/resources/lang/fr.lang index 59cf1b4d..0eabb100 100644 --- a/liteyuki/resources/lang/fr.lang +++ b/liteyuki/resources/lang/fr.lang @@ -92,4 +92,7 @@ user.profile.nickname.desc=Définir le pseudo du Bot pour l'utilisateur user.profile.input_value=Veuillez entrer {ATTR} user.profile.set_success={ATTR} défini avec succès sur {VALUE} -user.profile.set_failed=Échec de la définition de {ATTR}. Veuillez vérifier si l'entrée est valide. \ No newline at end of file +user.profile.set_failed=Échec de la définition de {ATTR}. Veuillez vérifier si l'entrée est valide. + +liteyuki.image_mode_on=Ouvert markdown image +liteyuki.image_mode_off=Fermé markdown image \ No newline at end of file diff --git a/liteyuki/resources/lang/zh-CN.lang b/liteyuki/resources/lang/zh-CN.lang index ce32624f..c9bd3517 100644 --- a/liteyuki/resources/lang/zh-CN.lang +++ b/liteyuki/resources/lang/zh-CN.lang @@ -97,4 +97,5 @@ user.profile.set_failed=设置 {ATTR} 失败,请检查输入是否合法 liteyuki.image_mode_on=开启Markdown图片模式 liteyuki.image_mode_off=关闭Markdown图片模式 -npm.page=第{PAGE}/{TOTAL}页 \ No newline at end of file +npm.page=第{PAGE}/{TOTAL}页 +main.monitor.free=空闲 \ No newline at end of file diff --git a/liteyuki/resources/templates/css/fonts.css b/liteyuki/resources/templates/css/fonts.css index f33f5267..f80e5eef 100644 --- a/liteyuki/resources/templates/css/fonts.css +++ b/liteyuki/resources/templates/css/fonts.css @@ -1,13 +1,54 @@ +/*MiSans*/ + @font-face { font-family: 'MiSans'; - src: url('../../fonts/normal.ttf') format('truetype'); + src: url('../fonts/MiSans/MiSans-Normal.woff2') format('truetype'); font-weight: normal; - font-style: normal; } @font-face { font-family: 'MiSans'; - src: url('../../fonts/bold.ttf') format('truetype'); + src: url('../fonts/MiSans/MiSans-Bold.woff2') format('truetype'); font-weight: bold; - font-style: normal; } + +/*MapleMono*/ +@font-face { + font-family: 'MapleMono'; + src: url('../fonts/MapleMono/MapleMono-Light.woff2') format('truetype'); + font-weight: 200; +} + +@font-face { + font-family: 'MapleMono'; + src: url('../fonts/MapleMono/MapleMono-LightItalic.woff2') format('truetype'); + font-weight: 200; + font-style: italic; +} + + +@font-face { + font-family: 'MapleMono'; + src: url('../fonts/MapleMono/MapleMono-Regular.woff2') format('truetype'); + font-weight: 400; +} + +@font-face { + font-family: 'MapleMono'; + src: url('../fonts/MapleMono/MapleMono-Italic.woff2') format('truetype'); + font-weight: 400; + font-style: italic; +} + +@font-face { + font-family: 'MapleMono'; + src: url('../fonts/MapleMono/MapleMono-Bold.woff2') format('truetype'); + font-weight: 700; +} + +@font-face { + font-family: 'MapleMono'; + src: url('../fonts/MapleMono/MapleMono-BoldItalic.woff2') format('truetype'); + font-weight: 700; + font-style: italic; +} \ No newline at end of file diff --git a/liteyuki/resources/templates/fonts/MapleMono/MapleMono-Bold.woff2 b/liteyuki/resources/templates/fonts/MapleMono/MapleMono-Bold.woff2 new file mode 100644 index 00000000..bedd45b5 Binary files /dev/null and b/liteyuki/resources/templates/fonts/MapleMono/MapleMono-Bold.woff2 differ diff --git a/liteyuki/resources/templates/fonts/MapleMono/MapleMono-BoldItalic.woff2 b/liteyuki/resources/templates/fonts/MapleMono/MapleMono-BoldItalic.woff2 new file mode 100644 index 00000000..c4acc5af Binary files /dev/null and b/liteyuki/resources/templates/fonts/MapleMono/MapleMono-BoldItalic.woff2 differ diff --git a/liteyuki/resources/templates/fonts/MapleMono/MapleMono-Italic.woff2 b/liteyuki/resources/templates/fonts/MapleMono/MapleMono-Italic.woff2 new file mode 100644 index 00000000..6b044cce Binary files /dev/null and b/liteyuki/resources/templates/fonts/MapleMono/MapleMono-Italic.woff2 differ diff --git a/liteyuki/resources/templates/fonts/MapleMono/MapleMono-Light.woff2 b/liteyuki/resources/templates/fonts/MapleMono/MapleMono-Light.woff2 new file mode 100644 index 00000000..e5f93c46 Binary files /dev/null and b/liteyuki/resources/templates/fonts/MapleMono/MapleMono-Light.woff2 differ diff --git a/liteyuki/resources/templates/fonts/MapleMono/MapleMono-LightItalic.woff2 b/liteyuki/resources/templates/fonts/MapleMono/MapleMono-LightItalic.woff2 new file mode 100644 index 00000000..f8b95a6b Binary files /dev/null and b/liteyuki/resources/templates/fonts/MapleMono/MapleMono-LightItalic.woff2 differ diff --git a/liteyuki/resources/templates/fonts/MapleMono/MapleMono-Regular.woff2 b/liteyuki/resources/templates/fonts/MapleMono/MapleMono-Regular.woff2 new file mode 100644 index 00000000..cbbe6f8c Binary files /dev/null and b/liteyuki/resources/templates/fonts/MapleMono/MapleMono-Regular.woff2 differ diff --git a/liteyuki/resources/templates/fonts/MiSans/MiSans-Bold.woff2 b/liteyuki/resources/templates/fonts/MiSans/MiSans-Bold.woff2 new file mode 100644 index 00000000..f966f5af Binary files /dev/null and b/liteyuki/resources/templates/fonts/MiSans/MiSans-Bold.woff2 differ diff --git a/liteyuki/resources/templates/fonts/MiSans/MiSans-Demibold.woff2 b/liteyuki/resources/templates/fonts/MiSans/MiSans-Demibold.woff2 new file mode 100644 index 00000000..7cf38819 Binary files /dev/null and b/liteyuki/resources/templates/fonts/MiSans/MiSans-Demibold.woff2 differ diff --git a/liteyuki/resources/templates/fonts/MiSans/MiSans-ExtraLight.woff2 b/liteyuki/resources/templates/fonts/MiSans/MiSans-ExtraLight.woff2 new file mode 100644 index 00000000..b93c8505 Binary files /dev/null and b/liteyuki/resources/templates/fonts/MiSans/MiSans-ExtraLight.woff2 differ diff --git a/liteyuki/resources/templates/fonts/MiSans/MiSans-Heavy.woff2 b/liteyuki/resources/templates/fonts/MiSans/MiSans-Heavy.woff2 new file mode 100644 index 00000000..2eb66cd6 Binary files /dev/null and b/liteyuki/resources/templates/fonts/MiSans/MiSans-Heavy.woff2 differ diff --git a/liteyuki/resources/templates/fonts/MiSans/MiSans-Light.woff2 b/liteyuki/resources/templates/fonts/MiSans/MiSans-Light.woff2 new file mode 100644 index 00000000..6067ea25 Binary files /dev/null and b/liteyuki/resources/templates/fonts/MiSans/MiSans-Light.woff2 differ diff --git a/liteyuki/resources/templates/fonts/MiSans/MiSans-Medium.woff2 b/liteyuki/resources/templates/fonts/MiSans/MiSans-Medium.woff2 new file mode 100644 index 00000000..993d1f6f Binary files /dev/null and b/liteyuki/resources/templates/fonts/MiSans/MiSans-Medium.woff2 differ diff --git a/liteyuki/resources/templates/fonts/MiSans/MiSans-Normal.woff2 b/liteyuki/resources/templates/fonts/MiSans/MiSans-Normal.woff2 new file mode 100644 index 00000000..ae0649f2 Binary files /dev/null and b/liteyuki/resources/templates/fonts/MiSans/MiSans-Normal.woff2 differ diff --git a/liteyuki/resources/templates/fonts/MiSans/MiSans-Regular.woff2 b/liteyuki/resources/templates/fonts/MiSans/MiSans-Regular.woff2 new file mode 100644 index 00000000..7544be21 Binary files /dev/null and b/liteyuki/resources/templates/fonts/MiSans/MiSans-Regular.woff2 differ diff --git a/liteyuki/resources/templates/fonts/MiSans/MiSans-Semibold.woff2 b/liteyuki/resources/templates/fonts/MiSans/MiSans-Semibold.woff2 new file mode 100644 index 00000000..e98f6cf2 Binary files /dev/null and b/liteyuki/resources/templates/fonts/MiSans/MiSans-Semibold.woff2 differ diff --git a/liteyuki/resources/templates/fonts/MiSans/MiSans-Thin.woff2 b/liteyuki/resources/templates/fonts/MiSans/MiSans-Thin.woff2 new file mode 100644 index 00000000..0ef3e88e Binary files /dev/null and b/liteyuki/resources/templates/fonts/MiSans/MiSans-Thin.woff2 differ diff --git a/liteyuki/resources/templates/img/bg2.jpg b/liteyuki/resources/templates/img/bg2.jpg new file mode 100644 index 00000000..75e9e44e Binary files /dev/null and b/liteyuki/resources/templates/img/bg2.jpg differ diff --git a/liteyuki/resources/templates/img/bg3.jpg b/liteyuki/resources/templates/img/bg3.jpg new file mode 100644 index 00000000..3e0f0781 Binary files /dev/null and b/liteyuki/resources/templates/img/bg3.jpg differ diff --git a/liteyuki/resources/templates/img/bg4.jpg b/liteyuki/resources/templates/img/bg4.jpg new file mode 100644 index 00000000..66229d15 Binary files /dev/null and b/liteyuki/resources/templates/img/bg4.jpg differ diff --git a/liteyuki/resources/templates/img/liteyuki.png b/liteyuki/resources/templates/img/liteyuki.png new file mode 100644 index 00000000..6512544c Binary files /dev/null and b/liteyuki/resources/templates/img/liteyuki.png differ diff --git a/liteyuki/resources/templates/stats.html b/liteyuki/resources/templates/stats.html index ede0fc03..24fb3534 100644 --- a/liteyuki/resources/templates/stats.html +++ b/liteyuki/resources/templates/stats.html @@ -1,13 +1,27 @@ - +
- -