diff --git a/.gitignore b/.gitignore index 1a594a7..6e38544 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,10 @@ config.yml config.example.yml compile.bat src/resources/templates/latest-debug.html + +src/plugins/trimo_plugin_msctconverter/config +src/plugins/trimo_plugin_msctconverter/temp + # vuepress .github pyproject.toml diff --git a/README.md b/README.md index f9a0475..1bf6629 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ 版权所有 © 2024 SnowyKami & EillesWan -轻雪机器人睿乐定制版(LiteyukiBot-TriM)根据 第一版 汉钰律许可协议(“本协议”)授权。\ +轻雪机器人睿乐定制版(LiteyukiBot-TriMO)根据 第一版 汉钰律许可协议(“本协议”)授权。\ 任何人皆可从以下地址获得本协议副本:[汉钰律许可协议 第一版](https://gitee.com/EillesWan/YulvLicenses/raw/master/%E6%B1%89%E9%92%B0%E5%BE%8B%E8%AE%B8%E5%8F%AF%E5%8D%8F%E8%AE%AE/%E6%B1%89%E9%92%B0%E5%BE%8B%E8%AE%B8%E5%8F%AF%E5%8D%8F%E8%AE%AE.MD)。\ 若非因法律要求或经过了特殊准许,此作品在根据本协议“原样”提供的基础上,不予提供任何形式的担保、任何明示、任何暗示或类似承诺。也就是说,用户将自行承担因此作品的质量或性能问题而产生的全部风险。\ 详细的准许和限制条款请见原协议文本。 @@ -57,4 +57,4 @@ [lightyuki-link]: / [python-link]: https://www.python.org/ [usage-link]: https://bot.liteyuki.icu/ -[banner]: https://socialify.git.ci/TriM-Organization/LiteyukiBot-TriM/image?description=1&forks=1&issues=1&Plus&pulls=1&stargazers=1&theme=Auto&logo=https://gitee.com/TriM-Organization/Linglun-Converter/raw/master/resources/TriMO_LOGO.png +[banner]: https://socialify.git.ci/TriM-Organization/LiteyukiBot-TriM/image?description=1&forks=1&issues=1&Plus&pulls=1&stargazers=1&theme=Auto&logo=https://raw.githubusercontent.com/TriM-Organization/Linglun-Converter/master/resources/TriMO_LOGO.png diff --git a/src/liteyuki_main/api.py b/src/liteyuki_main/api.py index fe720b3..f3ca5e8 100644 --- a/src/liteyuki_main/api.py +++ b/src/liteyuki_main/api.py @@ -4,8 +4,8 @@ from git import Repo from src.utils.base.config import get_config remote_urls = [ - "https://gitee.com/TriM-Organization/LiteyukiBot-TriM.git", - "https://github.com/TriM-Organization/LiteyukiBot-TriM.git" + "https://gitee.com/TriM-Organization/LiteyukiBot-TriMO.git", + "https://github.com/TriM-Organization/LiteyukiBot-TriMO.git" ] diff --git a/src/liteyuki_main/core.py b/src/liteyuki_main/core.py index 6d445f0..1619560 100644 --- a/src/liteyuki_main/core.py +++ b/src/liteyuki_main/core.py @@ -23,12 +23,22 @@ from ..utils.base.ly_function import get_function require("nonebot_plugin_alconna") require("nonebot_plugin_apscheduler") -from nonebot_plugin_alconna import UniMessage, on_alconna, Alconna, Args, Subcommand, Arparma, MultiVar +from nonebot_plugin_alconna import ( + UniMessage, + on_alconna, + Alconna, + Args, + Subcommand, + Arparma, + MultiVar, +) from nonebot_plugin_apscheduler import scheduler driver = get_driver() -markdown_image = common_db.where_one(StoredConfig(), default=StoredConfig()).config.get("markdown_image", False) +markdown_image = common_db.where_one(StoredConfig(), default=StoredConfig()).config.get( + "markdown_image", False +) @on_alconna( @@ -36,42 +46,38 @@ markdown_image = common_db.where_one(StoredConfig(), default=StoredConfig()).con "ryounecho", Args["text", str, ""], ), - permission=SUPERUSER + permission=SUPERUSER, ).handle() # Satori OK async def _(bot: T_Bot, matcher: Matcher, result: Arparma): if result.main_args.get("text"): - await matcher.finish(Message(unescape(result.main_args.get("text")))) + await matcher.finish(Message(unescape(result.main_args.get("text")))) # type: ignore else: await matcher.finish(f"君安!灵温向你问好~\n此机 {bot.self_id}") + @on_alconna( command=Alconna( "liteecho", - Args["text", str, ""], + # Args["text", str, ""], ), - permission=SUPERUSER + # permission=SUPERUSER ).handle() # Satori OK async def _(bot: T_Bot, matcher: Matcher, result: Arparma): - if result.main_args.get("text"): - await matcher.finish(Message(unescape(result.main_args.get("text")))) - else: - await matcher.finish(f"Hello! TriM-Liteyuki!\nRyBot {bot.self_id}") + await matcher.finish(f"Hello! TriMO-Liteyuki!\nRyBot {bot.self_id}") @on_alconna( - aliases={"更新灵温"}, - command=Alconna( - "update-ryoun" - ), - permission=SUPERUSER + aliases={"更新灵温"}, command=Alconna("update-ryoun"), permission=SUPERUSER ).handle() # Satori OK async def _(bot: T_Bot, event: T_MessageEvent): # 使用git pull更新 - ulang = get_user_lang(str(event.user.id if isinstance(event, satori.event.Event) else event.user_id)) + ulang = get_user_lang( + str(event.user.id if isinstance(event, satori.event.Event) else event.user_id) + ) success, logs = update_liteyuki() reply = "尹灵温 更新完成!\n" reply += f"```\n{logs}\n```\n" @@ -82,11 +88,11 @@ async def _(bot: T_Bot, event: T_MessageEvent): @on_alconna( - aliases={"重启灵温","重启尹灵温", "重载灵温"}, + aliases={"重启灵温", "重启尹灵温", "重载灵温"}, command=Alconna( "reload-ryoun", ), - permission=SUPERUSER + permission=SUPERUSER, ).handle() # Satori OK async def _(matcher: Matcher, bot: T_Bot, event: T_MessageEvent): @@ -95,13 +101,16 @@ async def _(matcher: Matcher, bot: T_Bot, event: T_MessageEvent): temp_data.data.update( { - "reload" : True, - "reload_time" : time.time(), - "reload_bot_id" : bot.self_id, - "reload_session_type": event_utils.get_message_type(event), - "reload_session_id" : (event.group_id if event.message_type == "group" else event.user_id) if not isinstance(event, - satori.event.Event) else event.channel.id, - "delta_time" : 0 + "reload": True, + "reload_time": time.time(), + "reload_bot_id": bot.self_id, + "reload_session_type": event_utils.get_message_type(event), + "reload_session_id": ( + (event.group_id if event.message_type == "group" else event.user_id) + if not isinstance(event, satori.event.Event) + else event.channel.id + ), + "delta_time": 0, } ) @@ -117,34 +126,31 @@ async def _(matcher: Matcher, bot: T_Bot, event: T_MessageEvent): "set", Args["key", str]["value", Any], alias=["设置"], - ), - Subcommand( - "get", - Args["key", str, None], - alias=["查询", "获取"] - ), - Subcommand( - "remove", - Args["key", str], - alias=["删除"] - ) + Subcommand("get", Args["key", str, None], alias=["查询", "获取"]), + Subcommand("remove", Args["key", str], alias=["删除"]), ), - permission=SUPERUSER + permission=SUPERUSER, ).handle() # Satori OK async def _(result: Arparma, event: T_MessageEvent, bot: T_Bot, matcher: Matcher): ulang = get_user_lang(str(event_utils.get_user_id(event))) - stored_config: StoredConfig = common_db.where_one(StoredConfig(), default=StoredConfig()) + stored_config: StoredConfig = common_db.where_one( + StoredConfig(), default=StoredConfig() + ) if result.subcommands.get("set"): - key, value = result.subcommands.get("set").args.get("key"), result.subcommands.get("set").args.get("value") + key, value = result.subcommands.get("set").args.get( + "key" + ), result.subcommands.get("set").args.get("value") try: value = eval(value) except: pass stored_config.config[key] = value common_db.save(stored_config) - await matcher.finish(f"{ulang.get('liteyuki.config_set_success', KEY=key, VAL=value)}") + await matcher.finish( + f"{ulang.get('liteyuki.config_set_success', KEY=key, VAL=value)}" + ) elif result.subcommands.get("get"): key = result.subcommands.get("get").args.get("key") file_config = load_from_yaml("config.yml") @@ -168,29 +174,36 @@ async def _(result: Arparma, event: T_MessageEvent, bot: T_Bot, matcher: Matcher if key in stored_config.config: stored_config.config.pop(key) common_db.save(stored_config) - await matcher.finish(f"{ulang.get('liteyuki.config_remove_success', KEY=key)}") + await matcher.finish( + f"{ulang.get('liteyuki.config_remove_success', KEY=key)}" + ) else: await matcher.finish(f"{ulang.get('liteyuki.invalid_command', TEXT=key)}") @on_alconna( - aliases={"切换图片模式"}, - command=Alconna( - "switch-image-mode" - ), - permission=SUPERUSER + aliases={"切换图片模式"}, command=Alconna("switch-image-mode"), permission=SUPERUSER ).handle() # Satori OK async def _(event: T_MessageEvent, matcher: Matcher): global markdown_image # 切换图片模式,False以图片形式发送,True以markdown形式发送 ulang = get_user_lang(str(event_utils.get_user_id(event))) - stored_config: StoredConfig = common_db.where_one(StoredConfig(), default=StoredConfig()) - stored_config.config["markdown_image"] = not stored_config.config.get("markdown_image", False) + stored_config: StoredConfig = common_db.where_one( + StoredConfig(), default=StoredConfig() + ) + stored_config.config["markdown_image"] = not stored_config.config.get( + "markdown_image", False + ) markdown_image = stored_config.config["markdown_image"] common_db.save(stored_config) await matcher.finish( - ulang.get("liteyuki.image_mode_on" if stored_config.config["markdown_image"] else "liteyuki.image_mode_off")) + ulang.get( + "liteyuki.image_mode_on" + if stored_config.config["markdown_image"] + else "liteyuki.image_mode_off" + ) + ) # @on_alconna( @@ -209,7 +222,7 @@ async def _(event: T_MessageEvent, matcher: Matcher): "/function", Args["function", str]["args", MultiVar(str), ()], ), - permission=SUPERUSER + permission=SUPERUSER, ).handle() async def _(result: Arparma, bot: T_Bot, event: T_MessageEvent, matcher: Matcher): """ @@ -226,9 +239,9 @@ async def _(result: Arparma, bot: T_Bot, event: T_MessageEvent, matcher: Matcher args: tuple[str] = result.main_args.get("args", ()) _args = [] _kwargs = { - "USER_ID" : str(event.user_id), - "GROUP_ID": str(event.group_id) if event.message_type == "group" else "0", - "BOT_ID" : str(bot.self_id) + "USER_ID": str(event.user_id), + "GROUP_ID": str(event.group_id) if event.message_type == "group" else "0", + "BOT_ID": str(bot.self_id), } for arg in args: @@ -256,7 +269,7 @@ async def _(result: Arparma, bot: T_Bot, event: T_MessageEvent, matcher: Matcher "/api", Args["api", str]["args", MultiVar(AnyStr), ()], ), - permission=SUPERUSER + permission=SUPERUSER, ).handle() async def _(result: Arparma, bot: T_Bot, event: T_MessageEvent, matcher: Matcher): """ @@ -270,7 +283,9 @@ async def _(result: Arparma, bot: T_Bot, event: T_MessageEvent, matcher: Matcher """ api_name = result.main_args.get("api") - args: tuple[str] = result.main_args.get("args", ()) # 类似于url参数,但每个参数间用空格分隔,空格是%20 + args: tuple[str] = result.main_args.get( + "args", () + ) # 类似于url参数,但每个参数间用空格分隔,空格是%20 args_dict = {} for arg in args: @@ -280,7 +295,11 @@ async def _(result: Arparma, bot: T_Bot, event: T_MessageEvent, matcher: Matcher if api_name in need_user_id and "user_id" not in args_dict: args_dict["user_id"] = str(event.user_id) - if api_name in need_group_id and "group_id" not in args_dict and event.message_type == "group": + if ( + api_name in need_group_id + and "group_id" not in args_dict + and event.message_type == "group" + ): args_dict["group_id"] = str(event.group_id) if "message" in args_dict: @@ -303,29 +322,53 @@ async def _(result: Arparma, bot: T_Bot, event: T_MessageEvent, matcher: Matcher @Bot.on_calling_api # 图片模式检测 async def test_for_md_image(bot: T_Bot, api: str, data: dict): # 截获大图发送,转换为markdown发送 - if api in ["send_msg", "send_private_msg", "send_group_msg"] and markdown_image and data.get( - "user_id") != bot.self_id: - if api == "send_msg" and data.get("message_type") == "private" or api == "send_private_msg": + if ( + api in ["send_msg", "send_private_msg", "send_group_msg"] + and markdown_image + and data.get("user_id") != bot.self_id + ): + if ( + api == "send_msg" + and data.get("message_type") == "private" + or api == "send_private_msg" + ): session_type = "private" session_id = data.get("user_id") - elif api == "send_msg" and data.get("message_type") == "group" or api == "send_group_msg": + elif ( + api == "send_msg" + and data.get("message_type") == "group" + or api == "send_group_msg" + ): session_type = "group" session_id = data.get("group_id") else: return - if len(data.get("message", [])) == 1 and data["message"][0].get("type") == "image": + if ( + len(data.get("message", [])) == 1 + and data["message"][0].get("type") == "image" + ): file: str = data["message"][0].data.get("file") # file:// http:// base64:// if file.startswith("http"): - result = await md.send_md(await md.image_async(file), bot, message_type=session_type, - session_id=session_id) + result = await md.send_md( + await md.image_async(file), + bot, + message_type=session_type, + session_id=session_id, + ) elif file.startswith("file"): file = file.replace("file://", "") - result = await md.send_image(open(file, "rb").read(), bot, message_type=session_type, - session_id=session_id) + result = await md.send_image( + open(file, "rb").read(), + bot, + message_type=session_type, + session_id=session_id, + ) elif file.startswith("base64"): file_bytes = base64.b64decode(file.replace("base64://", "")) - result = await md.send_image(file_bytes, bot, message_type=session_type, session_id=session_id) + result = await md.send_image( + file_bytes, bot, message_type=session_type, session_id=session_id + ) else: return raise MockApiException(result=result) @@ -364,7 +407,7 @@ async def _(bot: T_Bot): if isinstance(bot, satori.Bot): await bot.send_message( channel_id=reload_session_id, - message="灵温 重载耗时 %.2f 秒" % delta_time + message="灵温 重载耗时 %.2f 秒" % delta_time, ) else: await bot.call_api( @@ -372,7 +415,7 @@ async def _(bot: T_Bot): message_type=reload_session_type, user_id=reload_session_id, group_id=reload_session_id, - message="灵温 重载耗时 %.2f 秒" % delta_time + message="灵温 重载耗时 %.2f 秒" % delta_time, ) @@ -392,22 +435,21 @@ async def every_day_update(): # 需要用户id的api need_user_id = ( - "send_private_msg", - "send_msg", - "set_group_card", - "set_group_special_title", - "get_stranger_info", - "get_group_member_info" + "send_private_msg", + "send_msg", + "set_group_card", + "set_group_special_title", + "get_stranger_info", + "get_group_member_info", ) need_group_id = ( - "send_group_msg", - "send_msg", - "set_group_card", - "set_group_name", - - "set_group_special_title", - "get_group_member_info", - "get_group_member_list", - "get_group_honor_info" -) \ No newline at end of file + "send_group_msg", + "send_msg", + "set_group_card", + "set_group_name", + "set_group_special_title", + "get_group_member_info", + "get_group_member_list", + "get_group_honor_info", +) diff --git a/src/plugins/liteyuki_pacman/rpm.py b/src/plugins/liteyuki_pacman/rpm.py index ab0f775..c854e9c 100644 --- a/src/plugins/liteyuki_pacman/rpm.py +++ b/src/plugins/liteyuki_pacman/rpm.py @@ -183,4 +183,7 @@ async def _(bot: T_Bot, event: T_MessageEvent, result: Arparma, matcher: Matcher if send_as_md: await md.send_md(reply, bot, event=event) else: - await matcher.finish(reply) + if reply: + await matcher.finish(reply) + else: + await matcher.finish("其实,还没做help\t——神羽") diff --git a/src/plugins/liteyuki_status/status.py b/src/plugins/liteyuki_status/status.py index 5277da1..514a52e 100644 --- a/src/plugins/liteyuki_status/status.py +++ b/src/plugins/liteyuki_status/status.py @@ -18,6 +18,7 @@ from nonebot_plugin_alconna import ( # AlconnaQuery, # Query, Arparma, + Args, ) require("nonebot_plugin_apscheduler") @@ -59,12 +60,18 @@ yanlun = on_alconna( action=store_true, ), Option("-c|--count", default=False, alias={"统计"}, action=store_true), + Option("-l|--length", default=1.0, args=Args["length", float | int, 1.0]), ), ) -# 每天4点更新 -@scheduler.scheduled_job("cron", hour=4) +yanlun_path = ( + "https://gitee.com/TriM-Organization/LinglunStudio/raw/master/resources/myWords.txt" +) + + +# 每天1点更新 +@scheduler.scheduled_job("cron", hour=1) async def every_day_update(): ulang = Language(get_default_lang_code(), "zh-WY") nonebot.logger.success(ulang.get("yanlun.refresh.success", COUNT=update_yanlun())) @@ -79,15 +86,17 @@ def update_yanlun(): lunar_date = (lunar_datetime.lunar_month, lunar_datetime.lunar_day) if solar_date == (4, 3): - yanlun_texts = ["金羿ELS 生日快乐~!"] + yanlun_texts = ["金羿ELS 生日快乐~!", "Happy Birthday, Eilles!"] elif solar_date == (8, 6): - yanlun_texts = ["诸葛八卦 生日快乐~!"] + yanlun_texts = ["诸葛亮与八卦阵 生日快乐~!", "Happy Birthday, bgArray~!"] + elif solar_date == (8, 16): + yanlun_texts = ["鱼旧梦 生日快乐~!", "Happy Birthday, ElapsingDreams~!"] else: try: yanlun_texts = ( requests.get( - "https://gitee.com/TriM-Organization/LinglunStudio/raw/master/resources/myWords.txt", + yanlun_path, ) .text.strip("\n") .split("\n") @@ -165,13 +174,13 @@ async def _( # count: Query[bool] = AlconnaQuery("count.value", False), ): # print(result.options) + ulang = get_user_lang(event_utils.get_user_id(event)) # type: ignore if result.options["refresh"].value: - ulang = get_user_lang(event_utils.get_user_id(event)) # type: ignore global yanlun_texts try: yanlun_texts = ( requests.get( - "https://gitee.com/TriM-Organization/LinglunStudio/raw/master/resources/myWords.txt", + yanlun_path, ) .text.strip("\n") .split("\n") @@ -205,7 +214,6 @@ async def _( ) yanlun_texts = ["灵光焕发 深艺献心"] if result.options["count"].value: - ulang = get_user_lang(event_utils.get_user_id(event)) # type: ignore authors = [ ( ("B站") @@ -250,4 +258,27 @@ async def _( + ulang.get("yanlun.count.tail", NUM=total) ) ) - await yanlun.finish(UniMessage.text(random.choice(yanlun_texts))) + + final_length = 0 + try: + final_length += result.options["length"].args["length"] + except: + final_length = 1 + + ( + ( + await yanlun.finish( + UniMessage.text( + "\n".join([random.choice(yanlun_texts) for i in range(iill)]) + if iill <= 100 + else ulang.get("yanlun.length.toolong") + ) + ) + if iill > 0 + else await yanlun.finish( + UniMessage.text(ulang.get("yanlun.length.tooshort")) + ) + ) + if (iill := int(final_length)) == final_length + else await yanlun.finish(UniMessage.text(ulang.get("yanlun.length.float"))) + ) diff --git a/src/plugins/trim_plugin_msctconverter/msctexec.py b/src/plugins/trim_plugin_msctconverter/msctexec.py deleted file mode 100644 index 920e088..0000000 --- a/src/plugins/trim_plugin_msctconverter/msctexec.py +++ /dev/null @@ -1,42 +0,0 @@ - - -import nonebot -from nonebot import require - -require("nonebot_plugin_alconna") -from nonebot_plugin_alconna import ( - on_alconna, - Alconna, - Subcommand, - UniMessage, - Option, - store_true, - Arparma, -) - - -musicreater_convert = on_alconna( - aliases={"musicreater_convert","音乐转换","midi转换"}, - command=Alconna( - "msctcvt", - Option( - "-r|--refresh", - default=False, - alias={"refr", "r", "刷新"}, - action=store_true, - ), - Subcommand( - "memory", - alias={"mem", "m", "内存"}, - ), - Subcommand( - "process", - alias={"proc", "p", "进程"}, - ), - # Subcommand( - # "refresh", - # alias={"refr", "r", "刷新"}, - # ), - ), -) - diff --git a/src/plugins/trimo_plugin_handle/LICENSE.md b/src/plugins/trimo_plugin_handle/LICENSE.md new file mode 100644 index 0000000..99c6ae2 --- /dev/null +++ b/src/plugins/trimo_plugin_handle/LICENSE.md @@ -0,0 +1,13 @@ + +## 版权声明 + +本插件由 汉钰律许可协议 授权开源,兼容并继承自 MIT 许可协议。 + +Copyright (c) 2022 MeetWq + +版权所有 © 2024 EillesWan & MeetWq + +猜成语-睿乐特别版(trimo_plugin_handle)根据 第一版 汉钰律许可协议(“本协议”)授权。\ +任何人皆可从以下地址获得本协议副本:[汉钰律许可协议 第一版](https://gitee.com/EillesWan/YulvLicenses/raw/master/%E6%B1%89%E9%92%B0%E5%BE%8B%E8%AE%B8%E5%8F%AF%E5%8D%8F%E8%AE%AE/%E6%B1%89%E9%92%B0%E5%BE%8B%E8%AE%B8%E5%8F%AF%E5%8D%8F%E8%AE%AE.MD)。\ +若非因法律要求或经过了特殊准许,此作品在根据本协议“原样”提供的基础上,不予提供任何形式的担保、任何明示、任何暗示或类似承诺。也就是说,用户将自行承担因此作品的质量或性能问题而产生的全部风险。\ +详细的准许和限制条款请见原协议文本。 \ No newline at end of file diff --git a/src/plugins/trimo_plugin_handle/__init__.py b/src/plugins/trimo_plugin_handle/__init__.py new file mode 100644 index 0000000..bf05c38 --- /dev/null +++ b/src/plugins/trimo_plugin_handle/__init__.py @@ -0,0 +1,268 @@ +import asyncio +from asyncio import TimerHandle +from typing import Any, Dict + +from nonebot import on_regex, require, on_command +from nonebot.matcher import Matcher +from nonebot.params import RegexDict +from nonebot.plugin import PluginMetadata, inherit_supported_adapters +from nonebot.rule import to_me +from nonebot.utils import run_sync +from nonebot.permission import SUPERUSER +from typing_extensions import Annotated + +require("nonebot_plugin_alconna") +require("nonebot_plugin_session") + +from nonebot_plugin_alconna import ( + Alconna, + AlconnaQuery, + Image, + Option, + Query, + Text, + UniMessage, + on_alconna, + store_true, + Args, + Arparma, +) +from nonebot_plugin_session import SessionId, SessionIdType + +from .config import Config, handle_config +from .data_source import GuessResult, Handle +from .utils import random_idiom + +__plugin_meta__ = PluginMetadata( + name="猜成语", + description="猜成语-睿乐特别版", + usage=( + "@我 + “猜成语”开始游戏;\n" + "你有十次的机会猜一个四字词语;\n" + "每次猜测后,汉字与拼音的颜色将会标识其与正确答案的区别;\n" + "青色 表示其出现在答案中且在正确的位置;\n" + "橙色 表示其出现在答案中但不在正确的位置;\n" + "每个格子的 汉字、声母、韵母、声调 都会独立进行颜色的指示。\n" + "当四个格子都为青色时,你便赢得了游戏!\n" + "可发送“结束”结束游戏;可发送“提示”查看提示。\n" + "使用 --strict 选项开启非默认的成语检查,即猜测的短语必须是成语,\n" + "如:@我 猜成语 --strict" + ), + type="application", + homepage="https://github.com/noneplugin/nonebot-plugin-handle", + config=Config, + supported_adapters=inherit_supported_adapters( + "nonebot_plugin_alconna", "nonebot_plugin_session" + ), + extra={ + "example": "@小Q 猜成语", + }, +) + + +games: Dict[str, Handle] = {} +timers: Dict[str, TimerHandle] = {} + +UserId = Annotated[str, SessionId(SessionIdType.GROUP)] + + +def game_is_running(user_id: UserId) -> bool: + return user_id in games + + +def game_not_running(user_id: UserId) -> bool: + return user_id not in games + + +handle = on_alconna( + Alconna("handle", Option("-s|--strict", default=False, action=store_true)), + aliases=("猜成语",), + rule=to_me() & game_not_running, + use_cmd_start=True, + block=True, + priority=13, +) +handle_hint = on_alconna( + "提示", + rule=game_is_running, + use_cmd_start=True, + block=True, + priority=13, +) +handle_stop = on_alconna( + "结束", + aliases=("结束游戏", "结束猜成语"), + rule=game_is_running, + use_cmd_start=True, + block=True, + priority=13, +) + +handle_answer = on_alconna( + Alconna( + "答案", + Option( + "-g|--group", + default="Now", + args=Args["group", str, "Now"], + ), + Option( + "-l|--list", + default=False, + action=store_true, + ), + ), + # rule=game_is_running, + use_cmd_start=True, + permission=SUPERUSER, + block=True, + priority=13, +) + +# handle_update = on_alconna( +# "更新词库", +# aliases=("刷新词库", "猜成语刷新词库"), +# rule=to_me(), +# use_cmd_start=True, +# block=True, +# priority=13, +# ) + + +handle_idiom = on_regex( + r"^(?P[\u4e00-\u9fa5]{4})$", + rule=game_is_running, + block=True, + priority=14, +) + + +def stop_game(user_id: str): + if timer := timers.pop(user_id, None): + timer.cancel() + games.pop(user_id, None) + + +async def stop_game_timeout(matcher: Matcher, user_id: str): + game = games.get(user_id, None) + stop_game(user_id) + if game: + msg = "猜成语超时,游戏结束。" + if len(game.guessed_idiom) >= 1: + msg += f"\n{game.result}" + await matcher.finish(msg) + + +def set_timeout(matcher: Matcher, user_id: str, timeout: float = 300): + if timer := timers.get(user_id, None): + timer.cancel() + loop = asyncio.get_running_loop() + timer = loop.call_later( + timeout, lambda: asyncio.ensure_future(stop_game_timeout(matcher, user_id)) + ) + timers[user_id] = timer + + +@handle.handle() +async def _( + matcher: Matcher, + user_id: UserId, + strict: Query[bool] = AlconnaQuery("strict.value", False), +): + is_strict = handle_config.handle_strict_mode or strict.result + idiom, explanation = random_idiom() + game = Handle(idiom, explanation, strict=is_strict) + + games[user_id] = game + set_timeout(matcher, user_id) + + msg = Text( + f"你有{game.times}次机会猜一个四字成语," + + ("发送有效成语以参与游戏。" if is_strict else "发送任意四字词语以参与游戏。") + ) + Image(raw=await run_sync(game.draw)()) + await msg.send() + + +@handle_hint.handle() +async def _(matcher: Matcher, user_id: UserId): + game = games[user_id] + set_timeout(matcher, user_id) + + await UniMessage.image(raw=await run_sync(game.draw_hint)()).send() + + +@handle_stop.handle() +async def _(matcher: Matcher, user_id: UserId): + game = games[user_id] + stop_game(user_id) + + msg = "游戏已结束" + if len(game.guessed_idiom) >= 1: + msg += f"\n{game.result}" + await matcher.finish(msg) + + +# @handle_update.handle() + + +@handle_idiom.handle() +async def _(matcher: Matcher, user_id: UserId, matched: Dict[str, Any] = RegexDict()): + game = games[user_id] + set_timeout(matcher, user_id) + + idiom = str(matched["idiom"]) + result = game.guess(idiom) + + if result in [GuessResult.WIN, GuessResult.LOSS]: + stop_game(user_id) + msg = Text( + ( + "恭喜你猜出了成语!" + if result == GuessResult.WIN + else "很遗憾,没有人猜出来呢" + ) + + f"\n{game.result}" + ) + Image(raw=await run_sync(game.draw)()) + await msg.send() + + elif result == GuessResult.DUPLICATE: + await matcher.finish("你已经猜过这个成语了呢") + + elif result == GuessResult.ILLEGAL: + await matcher.finish(f"你确定“{idiom}”是个成语吗?") + + else: + await UniMessage.image(raw=await run_sync(game.draw)()).send() + + +@handle_answer.handle() +async def _( + result: Arparma, + matcher: Matcher, + user_id: UserId, +): + + if result.options["list"].value: + await handle_answer.finish( + UniMessage.text( + "\n".join("{}-{}".format(i, j.idiom) for i, j in games.items()) + ) + ) + return + + try: + if result.options["group"].args["group"] == "Now": + session_numstr = user_id + else: + session_numstr = "qq_OneBot V11_2378756507_{}".format( + result.options["group"].args["group"] + ) + except: + session_numstr = user_id + + if session_numstr in games.keys(): + await handle_answer.finish(UniMessage.text(games[session_numstr].idiom)) + else: + await handle_answer.finish( + UniMessage.text("{} 不存在开局的游戏".format(session_numstr)) + ) diff --git a/src/plugins/trimo_plugin_handle/config.py b/src/plugins/trimo_plugin_handle/config.py new file mode 100644 index 0000000..2db373f --- /dev/null +++ b/src/plugins/trimo_plugin_handle/config.py @@ -0,0 +1,10 @@ +from nonebot import get_plugin_config +from pydantic import BaseModel + + +class Config(BaseModel): + handle_strict_mode: bool = False + handle_color_enhance: bool = False + + +handle_config = get_plugin_config(Config) diff --git a/src/plugins/trimo_plugin_handle/data_source.py b/src/plugins/trimo_plugin_handle/data_source.py new file mode 100644 index 0000000..babeef3 --- /dev/null +++ b/src/plugins/trimo_plugin_handle/data_source.py @@ -0,0 +1,284 @@ +from dataclasses import dataclass +from enum import Enum +from io import BytesIO +from typing import List, Optional, Tuple + +from PIL import Image, ImageDraw +from PIL.Image import Image as IMG + +from .config import handle_config +from .utils import get_pinyin, legal_idiom, load_font, save_jpg + + +class GuessResult(Enum): + WIN = 0 # 猜出正确成语 + LOSS = 1 # 达到最大可猜次数,未猜出正确成语 + DUPLICATE = 2 # 成语重复 + ILLEGAL = 3 # 成语不合法 + + +class GuessState(Enum): + CORRECT = 0 # 存在且位置正确 + EXIST = 1 # 存在但位置不正确 + WRONG = 2 # 不存在 + + +@dataclass +class ColorGroup: + bg_color: str # 背景颜色 + block_color: str # 方块颜色 + correct_color: str # 存在且位置正确时的颜色 + exist_color: str # 存在但位置不正确时的颜色 + wrong_color_pinyin: str # 不存在时的颜色 + wrong_color_char: str # 不存在时的颜色 + + +NORMAL_COLOR = ColorGroup( + "#ffffff", "#f7f8f9", "#1d9c9c", "#de7525", "#b4b8be", "#5d6673" +) + +ENHANCED_COLOR = ColorGroup( + "#ffffff", "#f7f8f9", "#5ba554", "#ff46ff", "#b4b8be", "#5d6673" +) + + +class Handle: + def __init__(self, idiom: str, explanation: str, strict: bool = False): + self.idiom: str = idiom # 成语 + self.explanation: str = explanation # 释义 + self.strict: bool = strict # 是否判断输入词语为成语 + self.result = f"【成语】:{idiom}\n【释义】:{explanation}" + self.pinyin: List[Tuple[str, str, str]] = get_pinyin(idiom) # 拼音 + self.length = 4 + self.times: int = 10 # 可猜次数 + self.guessed_idiom: List[str] = [] # 记录已猜成语 + self.guessed_pinyin: List[List[Tuple[str, str, str]]] = [] # 记录已猜成语的拼音 + + self.block_size = (160, 160) # 文字块尺寸 + self.block_padding = (20, 20) # 文字块之间间距 + self.padding = (40, 40) # 边界间距 + font_size_char = 60 # 汉字字体大小 + font_size_pinyin = 30 # 拼音字体大小 + font_size_tone = 22 # 声调字体大小 + self.font_char = load_font("NotoSerifSC-Regular.otf", font_size_char) + self.font_pinyin = load_font("NotoSansMono-Regular.ttf", font_size_pinyin) + self.font_tone = load_font("NotoSansMono-Regular.ttf", font_size_tone) + + self.colors = ( + ENHANCED_COLOR if handle_config.handle_color_enhance else NORMAL_COLOR + ) + + def guess(self, idiom: str) -> Optional[GuessResult]: + if self.strict and not legal_idiom(idiom): + return GuessResult.ILLEGAL + if idiom in self.guessed_idiom: + return GuessResult.DUPLICATE + self.guessed_idiom.append(idiom) + self.guessed_pinyin.append(get_pinyin(idiom)) + if idiom == self.idiom: + return GuessResult.WIN + if len(self.guessed_idiom) == self.times: + return GuessResult.LOSS + + def draw_block( + self, + block_color: str, + char: str = "", + char_color: str = "", + initial: str = "", + initial_color: str = "", + final: str = "", + final_color: str = "", + tone: str = "", + tone_color: str = "", + underline: bool = False, + underline_color: str = "", + ) -> IMG: + block = Image.new("RGB", self.block_size, block_color) + if not char: + return block + draw = ImageDraw.Draw(block) + + char_size = self.font_char.getbbox(char)[2:] + x = (self.block_size[0] - char_size[0]) / 2 + y = (self.block_size[1] - char_size[1]) / 5 * 3 + draw.text((x, y), char, font=self.font_char, fill=char_color) + + space = 5 + need_space = bool(initial and final) + py_length = self.font_pinyin.getlength(initial + final) + if need_space: + py_length += space + py_start = (self.block_size[0] - py_length) / 2 + x = py_start + y = self.block_size[0] / 8 + draw.text((x, y), initial, font=self.font_pinyin, fill=initial_color) + x += self.font_pinyin.getlength(initial) + if need_space: + x += space + draw.text((x, y), final, font=self.font_pinyin, fill=final_color) + + tone_size = self.font_tone.getbbox(tone)[2:] + x = (self.block_size[0] + py_length) / 2 + tone_size[0] / 3 + y -= tone_size[1] / 3 + draw.text((x, y), tone, font=self.font_tone, fill=tone_color) + + if underline: + x = py_start + py_size = self.font_pinyin.getbbox(initial + final)[2:] + y = self.block_size[0] / 8 + py_size[1] + 2 + draw.line((x, y, x + py_length, y), fill=underline_color, width=1) + y += 3 + draw.line((x, y, x + py_length, y), fill=underline_color, width=1) + + return block + + def draw(self) -> BytesIO: + rows = min(len(self.guessed_idiom) + 1, self.times) + board_w = self.length * self.block_size[0] + board_w += (self.length - 1) * self.block_padding[0] + 2 * self.padding[0] + board_h = rows * self.block_size[1] + board_h += (rows - 1) * self.block_padding[1] + 2 * self.padding[1] + board_size = (board_w, board_h) + board = Image.new("RGB", board_size, self.colors.bg_color) + + def get_states(guessed: List[str], answer: List[str]) -> List[GuessState]: + states = [] + incorrect = [] + for i in range(self.length): + if guessed[i] != answer[i]: + incorrect.append(answer[i]) + else: + incorrect.append("_") + for i in range(self.length): + if guessed[i] == answer[i]: + states.append(GuessState.CORRECT) + elif guessed[i] in incorrect: + states.append(GuessState.EXIST) + incorrect[incorrect.index(guessed[i])] = "_" + else: + states.append(GuessState.WRONG) + return states + + def get_pinyin_color(state: GuessState) -> str: + if state == GuessState.CORRECT: + return self.colors.correct_color + elif state == GuessState.EXIST: + return self.colors.exist_color + else: + return self.colors.wrong_color_pinyin + + def get_char_color(state: GuessState) -> str: + if state == GuessState.CORRECT: + return self.colors.correct_color + elif state == GuessState.EXIST: + return self.colors.exist_color + else: + return self.colors.wrong_color_char + + def block_pos(row: int, col: int) -> Tuple[int, int]: + x = self.padding[0] + (self.block_size[0] + self.block_padding[0]) * col + y = self.padding[1] + (self.block_size[1] + self.block_padding[1]) * row + return x, y + + for i in range(len(self.guessed_idiom)): + idiom = self.guessed_idiom[i] + pinyin = self.guessed_pinyin[i] + char_states = get_states(list(idiom), list(self.idiom)) + initial_states = get_states( + [p[0] for p in pinyin], [p[0] for p in self.pinyin] + ) + final_states = get_states( + [p[1] for p in pinyin], [p[1] for p in self.pinyin] + ) + tone_states = get_states( + [p[2] for p in pinyin], [p[2] for p in self.pinyin] + ) + underline_states = get_states( + [p[0] + p[1] for p in pinyin], [p[0] + p[1] for p in self.pinyin] + ) + for j in range(self.length): + char = idiom[j] + i2, f2, t2 = pinyin[j] + if char == self.idiom[j]: + block_color = self.colors.correct_color + char_color = initial_color = final_color = tone_color = ( + self.colors.bg_color + ) + underline = False + underline_color = "" + else: + block_color = self.colors.block_color + char_color = get_char_color(char_states[j]) + initial_color = get_pinyin_color(initial_states[j]) + final_color = get_pinyin_color(final_states[j]) + tone_color = get_pinyin_color(tone_states[j]) + underline_color = get_pinyin_color(underline_states[j]) + underline = underline_color in ( + self.colors.correct_color, + self.colors.exist_color, + ) + block = self.draw_block( + block_color, + char, + char_color, + i2, + initial_color, + f2, + final_color, + t2, + tone_color, + underline, + underline_color, + ) + board.paste(block, block_pos(i, j)) + + for i in range(len(self.guessed_idiom), rows): + for j in range(self.length): + block = self.draw_block(self.colors.block_color) + board.paste(block, block_pos(i, j)) + + return save_jpg(board) + + def draw_hint(self) -> BytesIO: + guessed_char = set("".join(self.guessed_idiom)) + guessed_initial = set() + guessed_final = set() + guessed_tone = set() + for pinyin in self.guessed_pinyin: + for p in pinyin: + guessed_initial.add(p[0]) + guessed_final.add(p[1]) + guessed_tone.add(p[2]) + + board_w = self.length * self.block_size[0] + board_w += (self.length - 1) * self.block_padding[0] + 2 * self.padding[0] + board_h = self.block_size[1] + 2 * self.padding[1] + board = Image.new("RGB", (board_w, board_h), self.colors.bg_color) + + for i in range(self.length): + char = self.idiom[i] + hi, hf, ht = self.pinyin[i] + color = char_c = initial_c = final_c = tone_c = self.colors.correct_color + if char not in guessed_char: + char = "?" + color = self.colors.block_color + char_c = self.colors.wrong_color_char + else: + char_c = initial_c = final_c = tone_c = self.colors.bg_color + if hi not in guessed_initial: + hi = "?" + initial_c = self.colors.wrong_color_pinyin + if hf not in guessed_final: + hf = "?" + final_c = self.colors.wrong_color_pinyin + if ht not in guessed_tone: + ht = "?" + tone_c = self.colors.wrong_color_pinyin + block = self.draw_block( + color, char, char_c, hi, initial_c, hf, final_c, ht, tone_c + ) + x = self.padding[0] + (self.block_size[0] + self.block_padding[0]) * i + y = self.padding[1] + board.paste(block, (x, y)) + return save_jpg(board) diff --git a/src/plugins/trimo_plugin_handle/nonebot_plugin_handle_license/LICENSE b/src/plugins/trimo_plugin_handle/nonebot_plugin_handle_license/LICENSE new file mode 100644 index 0000000..1554f9e --- /dev/null +++ b/src/plugins/trimo_plugin_handle/nonebot_plugin_handle_license/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 MeetWq + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/src/plugins/trimo_plugin_handle/resources/fonts/NotoSansMono-Regular.ttf b/src/plugins/trimo_plugin_handle/resources/fonts/NotoSansMono-Regular.ttf new file mode 100644 index 0000000..ff9389a Binary files /dev/null and b/src/plugins/trimo_plugin_handle/resources/fonts/NotoSansMono-Regular.ttf differ diff --git a/src/plugins/trimo_plugin_handle/resources/fonts/NotoSerifSC-Regular.otf b/src/plugins/trimo_plugin_handle/resources/fonts/NotoSerifSC-Regular.otf new file mode 100644 index 0000000..ef7a62d Binary files /dev/null and b/src/plugins/trimo_plugin_handle/resources/fonts/NotoSerifSC-Regular.otf differ diff --git a/src/plugins/trimo_plugin_handle/utils.py b/src/plugins/trimo_plugin_handle/utils.py new file mode 100644 index 0000000..6e68052 --- /dev/null +++ b/src/plugins/trimo_plugin_handle/utils.py @@ -0,0 +1,113 @@ +import json +import random +from io import BytesIO +from pathlib import Path +from typing import Dict, List, Tuple + +# from watchdog.observers import Observer +# from watchdog.events import FileSystemEventHandler, FileModifiedEvent + +from PIL import ImageFont +from PIL.Image import Image as IMG +from PIL.ImageFont import FreeTypeFont +from pypinyin import Style, pinyin + +resource_dir = Path(__file__).parent / "resources" +fonts_dir = resource_dir / "fonts" +data_dir = resource_dir / "data" +idiom_path = data_dir / "idioms.txt" +answer_path = data_dir / "answers.json" + + +LEGAL_PHRASES = [ + idiom.strip() for idiom in idiom_path.open("r", encoding="utf-8").readlines() +] +ANSWER_PHRASES: List[Dict[str, str]] = json.load(answer_path.open("r", encoding="utf-8")) + + +# class LegalPhrasesModifiedHandler(FileSystemEventHandler): +# """ +# Handler for resource file changes +# """ + +# def on_modified(self, event): +# print(f"{event.src_path} modified, reloading resource...") +# if "idioms.txt" in event.src_path: +# global LEGAL_PHRASES +# LEGAL_PHRASES = [ +# idiom.strip() +# for idiom in idiom_path.open("r", encoding="utf-8").readlines() +# ] +# elif "answers.json" in event.src_path: +# global ANSWER_PHRASES +# ANSWER_PHRASES = json.load( +# answer_path.open("r", encoding="utf-8") +# ) + + +# Observer().schedule( +# LegalPhrasesModifiedHandler(), +# data_dir, +# recursive=False, +# event_filter=FileModifiedEvent, +# ) + + +def legal_idiom(word: str) -> bool: + return word in LEGAL_PHRASES + + +def random_idiom() -> Tuple[str, str]: + answer = random.choice(ANSWER_PHRASES) + return answer["word"], answer["explanation"] + + +# fmt: off +# 声母 +INITIALS = [ + "zh", "z", "y", "x", "w", "t", "sh", "s", "r", "q", "p", + "n", "m", "l", "k", "j", "h", "g", "f", "d", "ch", "c", "b" +] +# 韵母 +FINALS = [ + "ün", "üe", "üan", "ü", "uo", "un", "ui", "ue", "uang", + "uan", "uai","ua", "ou", "iu", "iong", "ong", "io", "ing", + "in", "ie", "iao", "iang", "ian", "ia", "er", "eng", "en", + "ei", "ao", "ang", "an", "ai", "u", "o", "i", "e", "a" +] +# fmt: on + + +def get_pinyin(idiom: str) -> List[Tuple[str, str, str]]: + pys = pinyin(idiom, style=Style.TONE3, v_to_u=True) + results = [] + for p in pys: + py = p[0] + if py[-1].isdigit(): + tone = py[-1] + py = py[:-1] + else: + tone = "" + initial = "" + for i in INITIALS: + if py.startswith(i): + initial = i + break + final = "" + for f in FINALS: + if py.endswith(f): + final = f + break + results.append((initial, final, tone)) # 声母,韵母,声调 + return results + + +def save_jpg(frame: IMG) -> BytesIO: + output = BytesIO() + frame = frame.convert("RGB") + frame.save(output, format="jpeg") + return output + + +def load_font(name: str, fontsize: int) -> FreeTypeFont: + return ImageFont.truetype(str(fonts_dir / name), fontsize, encoding="utf-8") diff --git a/src/plugins/trimo_plugin_msctconverter/LICENSE.md b/src/plugins/trimo_plugin_msctconverter/LICENSE.md new file mode 100644 index 0000000..d374d95 --- /dev/null +++ b/src/plugins/trimo_plugin_msctconverter/LICENSE.md @@ -0,0 +1,13 @@ + +## 版权声明 + +本插件由 汉钰律许可协议 授权开源,兼容并继承自 Apache 2.0 许可协议。 + +Copyright © 2024 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray") with TriM Org. + +版权所有 © 2024 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray") with TriM Org. + +伶伦转换器(trimo_plugin_msctconverter)根据 第一版 汉钰律许可协议(“本协议”)授权。\ +任何人皆可从以下地址获得本协议副本:[汉钰律许可协议 第一版](https://gitee.com/EillesWan/YulvLicenses/raw/master/%E6%B1%89%E9%92%B0%E5%BE%8B%E8%AE%B8%E5%8F%AF%E5%8D%8F%E8%AE%AE/%E6%B1%89%E9%92%B0%E5%BE%8B%E8%AE%B8%E5%8F%AF%E5%8D%8F%E8%AE%AE.MD)。\ +若非因法律要求或经过了特殊准许,此作品在根据本协议“原样”提供的基础上,不予提供任何形式的担保、任何明示、任何暗示或类似承诺。也就是说,用户将自行承担因此作品的质量或性能问题而产生的全部风险。\ +详细的准许和限制条款请见原协议文本。 \ No newline at end of file diff --git a/src/plugins/trimo_plugin_msctconverter/Linglun_License/LICENSE.md b/src/plugins/trimo_plugin_msctconverter/Linglun_License/LICENSE.md new file mode 100644 index 0000000..2ffd692 --- /dev/null +++ b/src/plugins/trimo_plugin_msctconverter/Linglun_License/LICENSE.md @@ -0,0 +1,218 @@ +**注意,以下条款或版权声明应当且必须是高于此仓库中任何其他声明的** + +1. 伶伦的全部开发者享有其完整版权,其开发者可以在任一时刻终止以后伶伦源代码开放,若经由其开发者授予特殊权利,则授权对象可以将源代码进行特定的被特殊授权的操作 +2. 伶伦或(及)其代码允许在 Apache2.0 协议的条款与说明下进行非商业使用 +3. 除部分代码特殊声明外,伶伦允许对其或(及)其代码进行商业化使用,但是需要经过伶伦主要开发者(诸葛亮与八卦阵、金羿)的一致授权,同时,授权对象在商业化授权的使用过程中必须依照 Apache2.0 协议的条款与说明 +4. 若存在对于伶伦包含的部分代码的特殊开源声明,则此部分代码依照其特定的开源方式授权,但若此部分代码经由此部分代码的主要开发者一致特殊授权后商用,则授权对象在商用时依照此部分的开发者所准许的方式(或条款)进行商用,在经此部分的开发者准许后无其他特殊授权时,默认依照 Apache2.0 协议进行商业化使用 +5. Apache2.0 协议的英文原文副本可见下文 + +> The English Translation of the TERMS AND CONDITIONS above is listed below +> +> This translated version is for reference only and has no legal effect. +> +> The version with legal effect is the Chinese version above. + +**Note, The TERMS AND CONDITIONS below should and must be above all others in this repository** + +1. _Linglun Studio_ is fully copyrighted by all its developers, the developers have the right to make _Linglun Studio_ close sourced at any time. Operations are permitted under specific terms instructed by its developer(s). +2. Non-commercial use of _Linglun Studio_ and(or) its source code is permitted under Apache License 2.0. +3. Commercial use of _Linglun Studio_ is permitted under Apache License 2.0 with the unanimous permission of the steering developers of _Linglun Studio_ (*bgArray*诸葛亮与八卦阵 and *Eilles*金羿). +4. _Linglun Studio_ is open sourced under priority given: + 1. License granted by the core developer(s) of a section after negotiation. + 2. Explicitly stated license. + 3. Apache 2.0 License. +5. A copy of the original Apache Lisence 2.0 can be found below. + +```text + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + + Copyright © 2024 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray") with TriM Org. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +``` diff --git a/src/plugins/trim_plugin_msctconverter/__init__.py b/src/plugins/trimo_plugin_msctconverter/__init__.py similarity index 100% rename from src/plugins/trim_plugin_msctconverter/__init__.py rename to src/plugins/trimo_plugin_msctconverter/__init__.py diff --git a/src/plugins/trimo_plugin_msctconverter/checker.py b/src/plugins/trimo_plugin_msctconverter/checker.py new file mode 100644 index 0000000..f5881ab --- /dev/null +++ b/src/plugins/trimo_plugin_msctconverter/checker.py @@ -0,0 +1,62 @@ + + + +def isin(sth: str, range_list: dict): + sth = sth.lower() + for bool_value, res_list in range_list.items(): + if sth in res_list: + return bool_value + raise ValueError( + "不在可选范围内:{}".format([j for i in range_list.values() for j in i]) + ) + + +# 真假字符串判断 +def bool_str(sth: str): + try: + return bool(float(sth)) + except ValueError: + if str(sth).lower() in ("true", "真", "是", "y", "t"): + return True + elif str(sth).lower() in ("false", "假", "否", "f", "n"): + return False + else: + raise ValueError("非法逻辑字串") + + +def float_str(sth: str): + try: + return float(sth) + except ValueError: + return float( + sth.replace("壹", "1") + .replace("贰", "2") + .replace("叁", "3") + .replace("肆", "4") + .replace("伍", "5") + .replace("陆", "6") + .replace("柒", "7") + .replace("捌", "8") + .replace("玖", "9") + .replace("零", "0") + .replace("一", "1") + .replace("二", "2") + .replace("三", "3") + .replace("四", "4") + .replace("五", "5") + .replace("六", "6") + .replace("七", "7") + .replace("八", "8") + .replace("九", "9") + .replace("〇", "0") + .replace("洞", "0") + .replace("幺", "1") + .replace("俩", "2") + .replace("两", "2") + .replace("拐", "7") + .replace("点", ".") + ) + + +def int_str(sth: str): + return int(float_str(sth)) diff --git a/src/plugins/trimo_plugin_msctconverter/execute_auto_translator.py b/src/plugins/trimo_plugin_msctconverter/execute_auto_translator.py new file mode 100644 index 0000000..45cef16 --- /dev/null +++ b/src/plugins/trimo_plugin_msctconverter/execute_auto_translator.py @@ -0,0 +1,139 @@ +# -*- coding: utf-8 -*- + + +''' + + Copyright © 2022 Team-Ryoun + + Licensed under the Apache License, Version 2.0 (the "License"); + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + +''' + +# 自动转换exe指令格式 +import uuid + + + +def isfloatable(sth: str) -> bool: + try:float(sth);return True + except:return False + + +# 极限挑战 +# execute @a[name="abc 123"] ~~ ~ execute @s ~9 346 ~-8 detect ^6 ^7 ^2 concrete 18 execute @p[r=3,scores={a=3}] 324 ~324 5 scoreboard players add @s[tag="999 888aasd asd "] QWE_AS 2 + +# /execute @a~~~/w @s aaa + +# execute@s[tag="[]] 666"]~ 1~576detect^6^^66concrete 1 execute @s [scores={n=0}] ~ ~ ~0.09 execute@s~~~detect 0 0 0 bedrock -1 execute@a [name="999\"]]] jjj\""]~~ ~/execute@s[tag="℃♞\""]~ 32 ~5423 execute@s~~~detect ~~-1~ redstone_block 0 give @s [scores={name=12..}] command_block 1 1 {"name_tag":["\"a ":"b你 KKK\""]} + +# 感谢 尘风、籽怼、邯潘阳(Happy2018New) 为本程序的试错提供了非常有效的支持 +# 也感谢 尘风、Happy2018New、Dislink Sforza 为作者提供相关参考意见 + + +def auto_translate(sentence:str): + '''传入一行旧的execute指令,则将其转换为新格式 + :param sentence: 旧的execute指令 + :return: 新的execute指令 + ''' + + + if not 'execute' in sentence: + return sentence + elif 'run' in sentence: + return sentence[:sentence.find('run')+4]+auto_translate(sentence[sentence.find('run')+4:]) + + # 避免不规范的语法 + sentence = ((__ := str(uuid.uuid4()),strings:=[(r"\"",__),], sentence.replace(r"\"",__)) if r"\"" in sentence else (None,strings:=[],sentence))[2] + + + # 如果有字符串包含其中 + # 我们可以看作一个神奇的pattern + def foreSentence(sent,ptnA,ptnB): + startcatch = False + tempstring = "" + for i in sent: + if startcatch: + if i == ptnB: + startcatch = False + tpp = '{}'.format(tempstring) + tag = str(uuid.uuid4()) + sent = sent.replace(tpp,tag) + strings.append((tpp,tag)) + tempstring = "" + else: + tempstring += i + else: + if i == ptnA: + startcatch = True + # tempstring += i + # print(ptnA,ptnB,sent) + return sent + + # print(sentence,"\n") + # 如果选择器的中括号包括空格 + sentence = ((sentence[:sentence.find("@")+2]+sentence[sentence.find('['):]) if (sum(0 if i == ' ' else 1 for i in sentence[sentence.find('@')+2:sentence.find('[')])==0) else sentence).replace("/"," ").lower() + + + sentence = foreSentence(foreSentence(foreSentence(sentence,'"','"'),"[","]"),"{","}") + list_sentence = list(sentence) + # 如果有神奇的东西在坐标后面,那就神奇了 + for i in range(len(list_sentence)): + if list_sentence[i] in ('^','~'): + j = i + 1 + while ((isfloatable("".join(list_sentence[i+1:j+1])))or(list_sentence[i+1] == "-" and isfloatable("".join(list_sentence[i+1:j+2]))))and j <= len(list_sentence): + j += 1 + # print(j,"\t","".join(sentence[j:])) + if list_sentence[j] == " " or isfloatable(list_sentence[j]): + continue + else: + list_sentence.insert(j,' ') + + sentence = "".join(list_sentence) + + def backfor_sentence(a): + return [(a := a.replace(tag,tpp)) for tpp,tag in strings[::-1]][-1] if strings else a + + # 下面是重点,只有我和老天爷看得懂 + if 'detect' in sentence[:sentence.find("execute",8) if "execute" in sentence[8:] else -1]: + ___ = [ j for i in [[i,] if sum([isfloatable(_) for _ in i]) else ((["~"+j for j in i[1:].split("~")] if i.startswith("~") else ["~"+j for j in i.split("~")]) if "~" in i else ([i,] if not "^" in i else (["^"+j for j in i[1:].split("^")] if i.startswith("^") else ["^"+j for j in i.split("^")]))) for i in sentence[sentence.find("detect")+6:].strip().split(" ",4)] for j in i ] + + ____ = " ".join(___[3:]).split(" ") + + return backfor_sentence('execute as {0} positioned as @s positioned {1} if block {2} {3} {4} at @s positioned {1} run {5}'.format(sentence[sentence.find("execute")+7:(sentence.find("]") if "[" in sentence[:sentence.find("@")+5] else sentence.find("@")+1)+1].strip(),sentence[(sentence.find("]") if "[" in sentence[:sentence.find("@")+3] else sentence.find("@")+1)+1:sentence.find("detect")-1].strip()," ".join(___[0:3]),____[0],____[1],auto_translate(" ".join(____[2:])))) + + else: + + ___ = [ j for i in [[i,] if sum([isfloatable(_) for _ in i]) else ((["~"+j for j in i[1:].split("~")] if i.startswith("~") else ["~"+j for j in i.split("~")]) if "~" in i else ([i,] if not "^" in i else (["^"+j for j in i[1:].split("^")] if i.startswith("^") else ["^"+j for j in i.split("^")]))) for i in sentence[(sentence.find("]") if ("]" in sentence)and(sum(0 if i == ' ' else 1 for i in sentence[sentence.find('@')+2:sentence.find('[')])==0) else sentence.find("@")+1)+1:].strip().split(" ",4)] for j in i ] + + return backfor_sentence('execute as {0} positioned as @s positioned {1} at @s positioned {1} run {2}'.format(sentence[sentence.find("execute")+7:(sentence.find("]") if "[" in sentence[:sentence.find("@")+5] else sentence.find("@")+1)+1].strip(), " ".join(___[0:3]),auto_translate(" ".join(___[3:])))) + + # 我是一个善良的人,没有用下面这个恶心你们 + # backSentence('execute as {0} positioned as @s positioned {1} if block {2} {3} {4} at @s positioned {1} run {5}'.format(sentence[sentence.find("execute")+7:(sentence.find("]") if "[" in sentence[:sentence.find("@")+5] else sentence.find("@")+1)+1].strip(),sentence[(sentence.find("]") if "[" in sentence[:sentence.find("@")+3] else sentence.find("@")+1)+1:sentence.find("detect")-1].strip()," ".join([ j for i in [[i,] if sum([isfloatable(_) for _ in i]) else ((["~"+j for j in i[1:].split("~")] if i.startswith("~") else ["~"+j for j in i.split("~")]) if "~" in i else ([i,] if not "^" in i else (["^"+j for j in i[1:].split("^")] if i.startswith("^") else ["^"+j for j in i.split("^")]))) for i in sentence[sentence.find("detect")+6:].strip().split(" ",4)] for j in i ][0:3])," ".join([ j for i in [[i,] if sum([isfloatable(_) for _ in i]) else ((["~"+j for j in i[1:].split("~")] if i.startswith("~") else ["~"+j for j in i.split("~")]) if "~" in i else ([i,] if not "^" in i else (["^"+j for j in i[1:].split("^")] if i.startswith("^") else ["^"+j for j in i.split("^")]))) for i in sentence[sentence.find("detect")+6:].strip().split(" ",4)] for j in i ][3:]).split(" ")[0]," ".join([ j for i in [[i,] if sum([isfloatable(_) for _ in i]) else ((["~"+j for j in i[1:].split("~")] if i.startswith("~") else ["~"+j for j in i.split("~")]) if "~" in i else ([i,] if not "^" in i else (["^"+j for j in i[1:].split("^")] if i.startswith("^") else ["^"+j for j in i.split("^")]))) for i in sentence[sentence.find("detect")+6:].strip().split(" ",4)] for j in i ][3:]).split(" ")[1],autoTranslate(" ".join(" ".join([ j for i in [[i,] if sum([isfloatable(_) for _ in i]) else ((["~"+j for j in i[1:].split("~")] if i.startswith("~") else ["~"+j for j in i.split("~")]) if "~" in i else ([i,] if not "^" in i else (["^"+j for j in i[1:].split("^")] if i.startswith("^") else ["^"+j for j in i.split("^")]))) for i in sentence[sentence.find("detect")+6:].strip().split(" ",4)] for j in i ][3:]).split(" ")[2:])))) if 'detect' in sentence[:sentence.find("execute",8) if "execute" in sentence[8:] else -1] else backSentence('execute as {0} positioned as @s positioned {1} at @s positioned {1} run {2}'.format(sentence[sentence.find("execute")+7:(sentence.find("]") if "[" in sentence[:sentence.find("@")+5] else sentence.find("@")+1)+1].strip(), " ".join([ j for i in [[i,] if sum([isfloatable(_) for _ in i]) else ((["~"+j for j in i[1:].split("~")] if i.startswith("~") else ["~"+j for j in i.split("~")]) if "~" in i else ([i,] if not "^" in i else (["^"+j for j in i[1:].split("^")] if i.startswith("^") else ["^"+j for j in i.split("^")]))) for i in sentence[(sentence.find("]") if ("]" in sentence)and(sum(0 if i == ' ' else 1 for i in sentence[sentence.find('@')+2:sentence.find('[')])==0) else sentence.find("@")+1)+1:].strip().split(" ",4)] for j in i ][0:3]),autoTranslate(" ".join([ j for i in [[i,] if sum([isfloatable(_) for _ in i]) else ((["~"+j for j in i[1:].split("~")] if i.startswith("~") else ["~"+j for j in i.split("~")]) if "~" in i else ([i,] if not "^" in i else (["^"+j for j in i[1:].split("^")] if i.startswith("^") else ["^"+j for j in i.split("^")]))) for i in sentence[(sentence.find("]") if ("]" in sentence)and(sum(0 if i == ' ' else 1 for i in sentence[sentence.find('@')+2:sentence.find('[')])==0) else sentence.find("@")+1)+1:].strip().split(" ",4)] for j in i ][3:])))) + + + + +def __main__(): + '''主函数 + ''' + while True: + try: + sentence = input() + print() + print(auto_translate(sentence)) + print("="*10) + except EOFError: + break + # except Exception as e: + # print(e) + # continue + + +if __name__ == "__main__": + __main__() + +# 没写完,我也不知道咋写,但是总得写不是吗 \ No newline at end of file diff --git a/src/plugins/trimo_plugin_msctconverter/msctexec.py b/src/plugins/trimo_plugin_msctconverter/msctexec.py new file mode 100644 index 0000000..60a0df4 --- /dev/null +++ b/src/plugins/trimo_plugin_msctconverter/msctexec.py @@ -0,0 +1,685 @@ + +import os +import sys +import time +import json +import shutil +import requests +from io import StringIO +from pathlib import Path +from typing import Annotated, Any + +# from nonebot import require + +import zhDateTime +import Musicreater + +from Musicreater.plugin.bdxfile import to_BDX_file_in_delay, to_BDX_file_in_score +from Musicreater.plugin.addonpack import ( + to_addon_pack_in_delay, + # to_addon_pack_in_repeater, + to_addon_pack_in_score, +) +from Musicreater.plugin.mcstructfile import ( + to_mcstructure_file_in_delay, + # to_mcstructure_file_in_repeater, + to_mcstructure_file_in_score, +) + +# import Musicreater.types +# import Musicreater.subclass +# import Musicreater.constants + +import nonebot +import nonebot.adapters +import nonebot.drivers +import nonebot.rule + +from nonebot.params import CommandArg +from nonebot.permission import SUPERUSER +from nonebot.adapters.onebot.v11.event import GroupUploadNoticeEvent, GroupMessageEvent + +from src.utils.base.ly_typing import T_Bot, T_MessageEvent + +from src.utils import event as event_utils +from src.utils.base.language import get_user_lang +from src.utils.base.config import get_config + +from .execute_auto_translator import auto_translate # type: ignore + + +nonebot.require("nonebot_plugin_alconna") +nonebot.require("nonebot_plugin_apscheduler") + + +from nonebot_plugin_alconna import ( + on_alconna, + Alconna, + Subcommand, + UniMessage, + Option, + store_true, + store_false, + store_value, + Arparma, + Args, +) + +from nonebot_plugin_apscheduler import scheduler + + +(config_dir := Path(__file__).parent / "config").mkdir(exist_ok=True) +(database_dir := Path(__file__).parent / "db").mkdir(exist_ok=True) +temporary_dir = Path(__file__).parent / "temp" + + +if (config_path := config_dir / "config.json").exists(): + configdict: dict = json.load(config_path.open("r", encoding="utf-8")) +else: + configdict = { + "donateCodePath": "https://foruda.gitee.com/images/1690165328188128032/d7f24fb5_9911226.jpeg", + "donateSite": "", + "helpPicPath": "https://foruda.gitee.com/images/1685873169584963569/95fe9b0b_9911226.png", + "maxCacheSize": 1048576, + "maxCacheTime": {".mcfunction": 900, ".mid .midi": 1800, ".json": 1800}, + "maxSingleFileSize": { + ".mcfunction": 524288, + ".mid .midi": 131072, + ".json": 8192, + }, + "maxPersonConvert": { + "music": 20, + "structure": 20, + }, + } + + +if (saves_path := database_dir / "file_saver.json").exists(): + filesaves: dict = json.load(saves_path.open("r", encoding="utf-8")) +else: + filesaves = {} + +max_cache_size = configdict["maxCacheSize"] +cache_limit_data: dict[str, tuple[int, int]] = {} + +for cache_subtype in configdict["maxCacheTime"].keys(): + for i in cache_subtype.split(" "): + cache_limit_data[i] = ( + configdict["maxSingleFileSize"][cache_subtype], + configdict["maxCacheTime"][cache_subtype], + ) + + +# if not os.path.exists("./temp/"): +# os.makedirs("./temp/") + + +def save_configdict(): + json.dump( + configdict, + config_path.open("w", encoding="utf-8"), + indent=4, + ensure_ascii=False, + sort_keys=True, + ) + + +def save_filesaves(): + json.dump( + filesaves, + saves_path.open("w", encoding="utf-8"), + indent=4, + ensure_ascii=False, + sort_keys=True, + ) + + +save_configdict() +save_filesaves() + +enable_auto_exe_translate = {} + +people_convert_times = {} + + +# 每天1点更新 +@scheduler.scheduled_job("cron", hour=0) +async def every_day_update(): + # ulang = Language(get_default_lang_code(), "zh-WY") + global people_convert_times + people_convert_times = {} + nonebot.logger.success("已重置每日转换次数") + + +@nonebot.get_driver().on_startup +async def _(): + nonebot.logger.info("正在删除临时文件目录") + while temporary_dir.exists(): + time.sleep(1) + try: + shutil.rmtree(temporary_dir) + except Exception as E: + nonebot.logger.warning(f"清空临时目录错误,我真是栓Q:{E}") + continue + + os.makedirs(temporary_dir) + nonebot.logger.success("删除临时文件目录完成") + + +@scheduler.scheduled_job("interval", seconds=30) +async def _(): + nonebot.logger.info( + "-删除文件检测-", + ) + qqidlist = list(filesaves.keys()).copy() + save_file = False + for qqid in qqidlist: + namelist = list(filesaves[qqid].keys()).copy() + for name in namelist: + if name == "totalSize": + continue + elif ( + zhDateTime.DateTime.now() + - zhDateTime.DateTime(*filesaves[qqid][name]["date"]) + ).seconds > cache_limit_data[os.path.splitext(name)[-1]][1]: + try: + os.remove(database_dir / qqid / name) + except: + pass + filesaves[qqid]["totalSize"] -= filesaves[qqid][name]["size"] + nonebot.logger.info( + "\t删除{}".format(name), + ) + filesaves[qqid].pop(name) + save_file = True + + try: + is_dir_empty = not os.listdir( + database_dir / qqid, + ) + except: + is_dir_empty = True + + if ( + (filesaves[qqid]["totalSize"] <= 0) + or len(filesaves[qqid].keys()) == 1 + or is_dir_empty + ): + try: + shutil.rmtree( + database_dir / qqid, + ) + except: + pass + filesaves.pop(qqid) + save_file = True + if save_file: + nonebot.logger.success("-已删除过期文件-") + save_filesaves() + else: + nonebot.logger.success("-无过期文件需要删除-") + + +# @nonebot.rule.Rule +# def file_receive_rule(event: GroupMessageEvent): +# return event.get_type() == "group_upload" + +notece_ = nonebot.on_notice() + + +@notece_.handle() +async def _( + event: GroupUploadNoticeEvent, + bot: T_Bot, +): + # global cache_limit_data + file_infomation = event.model_dump()["file"] + file_subtype: str = os.path.splitext(file_infomation["name"])[-1].lower() + if file_subtype in cache_limit_data.keys(): + if file_infomation["size"] > cache_limit_data[file_subtype][0]: + await notece_.finish( + "文件 {} 大小过大,这不是网盘\n单个{}文件不应大于 {} 千字节".format( + file_infomation["name"], + file_subtype.upper(), + cache_limit_data[file_subtype][0] / 1024, + ), + at_sender=True, + ) + return + elif (usr_id := str(event.user_id)) in filesaves.keys(): + if ( + filesaves[usr_id]["totalSize"] + file_infomation["size"] + > max_cache_size + ): + await notece_.send( + "缓存容量已经耗尽,当前你在服务器内的占有为 {} 字节,合 {}/{} 千字节\n而服务器最多支持每个人占有 {} 兆字节(即 {} 字节)".format( + filesaves[usr_id]["totalSize"], + int(filesaves[usr_id]["totalSize"] / 10.24 + 0.5) / 100, + max_cache_size / 1024, + max_cache_size / 1048576, + max_cache_size, + ), + at_sender=True, + ) + await notece_.finish( + f"执行指令 清除缓存(clearCache) 以清除在服务器内存储的缓存文件。", + ) + return + if file_infomation["name"] in filesaves[usr_id]: + await notece_.finish( + "你的缓存中已经包含了名称为 {} 的文件,不可重复上传。".format( + file_infomation["name"] + ) + ) + return + savepath = database_dir / usr_id + + os.makedirs(savepath, exist_ok=True) + + (savepath / file_infomation["name"]).open("wb").write( + requests.get( + file_infomation["url"], + verify=False, + ).content + ) + now = zhDateTime.DateTime.now() + try: + filesaves[usr_id][file_infomation["name"]] = { + "date": [ + now.year, + now.month, + now.day, + now.hour, + now.minute, + ], + "size": file_infomation["size"], + } + filesaves[usr_id]["totalSize"] += file_infomation["size"] + except: + filesaves[usr_id] = { + file_infomation["name"]: { + "date": [ + now.year, + now.month, + now.day, + now.hour, + now.minute, + ], + "size": file_infomation["size"], + } + } + filesaves[usr_id]["totalSize"] = file_infomation["size"] + save_filesaves() + await notece_.finish( + "文件 {} 已经保存,此文件在{:.1f}分内有效。".format( + file_infomation["name"], cache_limit_data[file_subtype][1] / 60 + ), + at_sender=True, + ) + + +on_clear_cache = on_alconna( + command=Alconna("清除缓存"), + aliases={ + "clearCache", + "clearcache", + "ClearCache", + "清除文件缓存", + "清除缓存文件", + "清空缓存", + }, +) + + +@on_clear_cache.handle() +async def _( + event: GroupMessageEvent, + bot: T_Bot, +): + if (usr_id := str(event.user_id)) in filesaves.keys(): + shutil.rmtree(database_dir / usr_id) + genText = ( + "、".join([i if i != "totalSize" else "" for i in filesaves[usr_id].keys()]) + .replace("、、", "、") + .strip("、") + ) + del filesaves[usr_id] + save_filesaves() + await on_clear_cache.finish( + UniMessage.text("文件 {} 已经清除。".format(genText)), + at_sender=True, + ) + else: + await on_clear_cache.finish( + UniMessage.text("服务器内未存有阁下的缓存文件。"), + at_sender=True, + ) + + +on_list_cache = on_alconna( + command=Alconna("查看缓存"), + aliases={"listCache", "listcache", "ListCache", "查看文件缓存", "查看缓存文件"}, +) + + +@on_list_cache.handle() +async def _( + event: GroupMessageEvent, + bot: T_Bot, +): + if (usr_id := str(event.user_id)) in filesaves.keys(): + genText = ( + "\n".join( + [ + ( + "{}({}千字节): 剩余{}秒".format( + i, + int(j["size"] / 10.24 + 0.5) / 100, + cache_limit_data[os.path.splitext(i)[-1].lower()][1] + - ( + zhDateTime.DateTime.now() + - zhDateTime.DateTime(*j["date"]) + ).seconds, + ) + if i != "totalSize" + else "" + ) + for i, j in filesaves[usr_id].items() + ] + ) + .replace("\n\n", "\n") + .strip("\n") + ) + await on_list_cache.finish( + UniMessage.text( + "服务器中保有你的如下文件:\n{}\n共计 {}/{} 字节,合 {}/{} 千字节".format( + genText, + filesaves[usr_id]["totalSize"], + max_cache_size, + int(filesaves[usr_id]["totalSize"] / 10.24 + 0.5) / 100, + max_cache_size / 1024, + ) + ), + at_sender=True, + ) + else: + await on_clear_cache.finish( + UniMessage.text("服务器内未存有阁下的缓存文件。"), + at_sender=True, + ) + + +# def convert_midi( +# midi_file_path: str, +# play_speed: float = 1, +# default_tempo: int = Musicreater.mido.midifiles.midifiles.DEFAULT_TEMPO, +# pitched_note_table: Musicreater.MidiInstrumentTableType = Musicreater.MM_TOUCH_PITCHED_INSTRUMENT_TABLE, +# percussion_note_table: Musicreater.MidiInstrumentTableType = Musicreater.MM_TOUCH_PERCUSSION_INSTRUMENT_TABLE, +# old_exe_format: bool = False, +# min_volume: float = 0.1, +# vol_processing_func: Musicreater.FittingFunctionType = Musicreater.natural_curve, +# ) + +musicreater_convert = on_alconna( + aliases={"musicreater_convert", "音乐转换", "midi转换"}, + command=Alconna( + "msctcvt", + Option("-f|--file", default="all", args=Args["file", str, "all"]), # ALL + Option("-emr|--enable-mismatch-error", default=False, action=store_true), + Option("-ps|--play-speed", default=1.0, args=Args["play-speed", float, 1.0]), + Option( + "-dftp|--default-tempo", + default=Musicreater.mido.midifiles.midifiles.DEFAULT_TEMPO, + args=Args[ + "default-tempo", int, Musicreater.mido.midifiles.midifiles.DEFAULT_TEMPO + ], + ), + Option( + "-ptc|--pitched-note-table", + default="touch", + args=Args["pitched-note-table", str, "touch"], + ), + Option( + "-pcs|--percussion-note-table", + default="touch", + args=Args["percussion-note-table", str, "touch"], + ), + Option("-e|--old-execute-format", default=False, action=store_true), + Option( + "-mv|--minimal-volume", default=0.1, args=Args["minimal-volume", float, 0.1] + ), + Option( + "-vpf|--volume-processing-function", + default="natural", + args=Args["volume-processing-function", str, "natural"], + ), + Option("-t|-type", default="all", args=Args["type", str, "all"]), + Option( + "-pgb|--progress-bar", + default={ + "base_s": r"▶ %%N [ %%s/%^s %%% §e__________§r %%t|%^t ]", + "to_play_s": r"§7=", + "played_s": r"=", + }, + args=Args["base_s", str, r"▶ %%N [ %%s/%^s %%% §e__________§r %%t|%^t ]"][ + "to_play_s", str, r"§7=" + ]["played_s", str, r"="], + ), + Option( + "-s|--scoreboard-name", + default="mscplay", + args=Args["scoreboard-name", str, "mscplay"], + ), + Option("-dsa|--disable-scoreboard-autoreset", default=False, action=store_true), + Option( + "-p|--player-selector", + default="@a", + args=Args["player-selector", str, "@a"], + ), + Option("-h|--height-limit", default=32, args=Args["height-limit", int, 32]), + Option("-a|--author", default="Eilles", args=Args["author", str, "Eilles"]), + Option("-fa|--forward-axis", default="x+", args=Args["forward-axis", str, "x+"]), + ), + permission=SUPERUSER, +) + + +@musicreater_convert.handle() +async def _( + result: Arparma, + event: GroupMessageEvent, + bot: T_Bot, +): + _args: dict = { + "file": "all", + "enable-mismatch-error": False, + "play-speed": 1.0, + "default-tempo": 500000, + "pitched-note-table": "touch", + "percussion-note-table": "touch", + "old-execute-format": False, + "minimal-volume": 0.1, + "volume-processing-function": "natural", + "type": "all", + "progress-bar": { + "base_s": r"▶ %%N [ %%s/%^s %%% §e__________§r %%t|%^t ]", + "to_play_s": r"§7=", + "played_s": r"=", + }, + "scoreboard-name": "mscplay", + "disable-scoreboard-autoreset": False, + "player-selector": "@a", + "height-limit": 32, + "author": "Eilles", + } + for arg in _args.keys(): + _args[arg] = ( + ( + result.options[arg].args[arg] + if arg in result.options[arg].args.keys() + else result.options[arg].args + ) + if (_vlu := result.options[arg].value) is None + else _vlu + ) + # await musicreater_convert.finish( + # UniMessage.text(json.dumps(_args, indent=4, sort_keys=True, ensure_ascii=False)) + # ) + + usr_id = str(event.user_id) + usr_data_path = database_dir / usr_id + (usr_temp_path := temporary_dir / usr_id).mkdir(exist_ok=True) + + if (_ppnt:=_args["pitched-note-table"].lower() )in ["touch","classic","dislink"]: + pitched_notechart = Musicreater.MM_DISLINK_PITCHED_INSTRUMENT_TABLE if _ppnt == "dislink" else (Musicreater.MM_CLASSIC_PITCHED_INSTRUMENT_TABLE if _ppnt == "classic" else Musicreater.MM_TOUCH_PITCHED_INSTRUMENT_TABLE) + elif (_ppnt:=(usr_data_path / _args["pitched-note-table"])).exists(): + pitched_notechart = Musicreater.MM_TOUCH_PITCHED_INSTRUMENT_TABLE.copy() + pitched_notechart.update(json.load(_ppnt.open("r"))) + else: + await musicreater_convert.finish(UniMessage.text("乐器对照表 {} 不存在".format(_args["pitched-note-table"]))) + return + + + if (_ppnt:=_args["percussion-note-table"].lower() )in ["touch","classic","dislink"]: + percussion_notechart = Musicreater.MM_DISLINK_PERCUSSION_INSTRUMENT_TABLE if _ppnt == "dislink" else (Musicreater.MM_CLASSIC_PERCUSSION_INSTRUMENT_TABLE if _ppnt == "classic" else Musicreater.MM_TOUCH_PERCUSSION_INSTRUMENT_TABLE) + elif (_ppnt:=(usr_data_path / _args["percussion-note-table"])).exists(): + percussion_notechart = Musicreater.MM_TOUCH_PERCUSSION_INSTRUMENT_TABLE.copy() + percussion_notechart.update(json.load(_ppnt.open("r"))) + else: + await musicreater_convert.finish(UniMessage.text("乐器对照表 {} 不存在".format(_args["percussion-note-table"]))) + return + + if (_ppnt:=_args["volume-processing-function"].lower()) in ["natural","straight"]: + volume_curve = Musicreater.straight_line if _ppnt == "straight" else Musicreater.natural_curve + else: + await musicreater_convert.finish(UniMessage.text("音量处理曲线 {} 不存在".format(_args["volume-processing-function"]))) + return + + if (_ppnt:=_args["type"].lower()) == "all": + all_cvt_types = ["addon-delay","addon-score","mcstructure-dalay","mcstructure-score","bdx-delay","bdx-score",] + else: + all_cvt_types = _ppnt.split("&") + + + + # 重定向标准输出 + buffer = StringIO() + sys.stdout = buffer + sys.stderr = buffer + + try: + + progress_bar_style = Musicreater.ProgressBarStyle(**_args["progress-bar"]) + + all_files = [] + + for file_to_convert in ( + filesaves[usr_id].keys() + if _args["file"].lower() == "all" + else _args["file"].split("&") + ): + if file_to_convert.endswith(".mid") or file_to_convert.endswith(".midi"): + nonebot.logger.info("载入转换文件:", file_to_convert) + all_files.append(file_to_convert) + msct_obj = Musicreater.MidiConvert.from_midi_file( + midi_file_path=usr_data_path / file_to_convert, + mismatch_error_ignorance=not _args["enable-mismatch-error"], + play_speed=_args["play-speed"], + default_tempo=_args["default-tempo"], + pitched_note_table=pitched_notechart, + percussion_note_table=percussion_notechart, + old_exe_format=_args["old-execute-format"], + min_volume=_args["minimal-volume"], + vol_processing_func=volume_curve, + ) + + a = ["mcstructure-dalay","mcstructure-score","bdx-delay","bdx-score",] + if "addon-delay" in all_cvt_types: + to_addon_pack_in_delay( + midi_cvt=msct_obj, + dist_path=str(usr_temp_path), + progressbar_style=progress_bar_style, + player=_args["player-selector"], + max_height=_args["height-limit"], + ) + all_cvt_types.remove("addon-delay") + if "addon-score" in all_cvt_types: + to_addon_pack_in_score() + + if not all_files: + nonebot.logger.warning("无可供转换的文件",) + await musicreater_convert.send(UniMessage("不是哥们,空气咱这转不成面包,那是中科院的事。")) + + except Exception as e: + nonebot.logger.error("转换存在错误:",e) + + + sys.stdout = sys.__stdout__ + sys.stderr = sys.__stderr__ + + + +execute_cmd_convert_ablity = on_alconna( + command=Alconna("指令自动更新"), + aliases={ + "指令更新自动", + "自动指令更新", + "指令更新", + }, +) + + +@execute_cmd_convert_ablity.handle() +async def _( + event: T_MessageEvent, + bot: T_Bot, +): + ulang = get_user_lang(usrid := str(event_utils.get_user_id(event))) + global enable_auto_exe_translate + enable_auto_exe_translate[usrid] = not enable_auto_exe_translate.get(usrid, True) + await execute_cmd_convert_ablity.finish( + UniMessage.text( + ulang.get( + "upexecute.enable" + if enable_auto_exe_translate[usrid] + else "upexecute.disable" + ) + ) + ) + + +execute_cmd_convert = nonebot.on_startswith( + "execute", +) + + +@execute_cmd_convert.handle() +async def _( + event: T_MessageEvent, + bot: T_Bot, +): + global enable_auto_exe_translate + if not enable_auto_exe_translate.get( + usrid := str(event_utils.get_user_id(event)), True + ): + execute_cmd_convert.destroy() + return + ulang = get_user_lang(usrid) + if ( + result_execmd := auto_translate(event.get_plaintext()) + ) == event.get_plaintext(): + await execute_cmd_convert.finish(ulang.get("upexecute.same")) + else: + await execute_cmd_convert.finish(result_execmd) + + +# test_exec = nonebot.on_command( +# "test-exec", +# rule=to_me(), +# permission=SUPERUSER, +# ) + + +# @test_exec.handle() +# async def _(args: Annotated[nonebot.adapters.Message, CommandArg()]): +# await test_exec.finish(exec(args.extract_plain_text())) diff --git a/src/resources/liteyuki_statistics/templates/stat_rank.html b/src/resources/liteyuki_statistics/templates/stat_rank.html index e0037a6..40fdadd 100644 --- a/src/resources/liteyuki_statistics/templates/stat_rank.html +++ b/src/resources/liteyuki_statistics/templates/stat_rank.html @@ -12,7 +12,7 @@ height: 100px; display: flex; background-color: rgba(255, 255, 255, 0.9); - border-radius: 100px; + /* border-radius: 100px; */ margin-bottom: 10px; padding-right: 10px; } @@ -25,7 +25,7 @@ } .row-icon { - border-radius: 50%; + /* border-radius: 50%; */ margin-right: auto; } diff --git a/src/resources/trim_plugin_msctconverter/lang/zh-CN.lang b/src/resources/trim_plugin_msctconverter/lang/zh-CN.lang index e69de29..bebf86e 100644 --- a/src/resources/trim_plugin_msctconverter/lang/zh-CN.lang +++ b/src/resources/trim_plugin_msctconverter/lang/zh-CN.lang @@ -0,0 +1,4 @@ + +upexecute.same=指令转换前后一致 +upexecute.enable=execute指令自动更新已启用 +upexecute.disable=已禁用execute指令自动更新 \ No newline at end of file diff --git a/src/resources/trim_plugin_msctconverter/lang/zh-WY.lang b/src/resources/trim_plugin_msctconverter/lang/zh-WY.lang index e69de29..7e3b8a6 100644 --- a/src/resources/trim_plugin_msctconverter/lang/zh-WY.lang +++ b/src/resources/trim_plugin_msctconverter/lang/zh-WY.lang @@ -0,0 +1,4 @@ + +upexecute.same=令未变 +upexecute.enable=更令之法方用 +upexecute.disable=更令之法方去 \ No newline at end of file diff --git a/src/resources/trim_plugin_msctconverter/metadata.yml b/src/resources/trim_plugin_msctconverter/metadata.yml new file mode 100644 index 0000000..096e520 --- /dev/null +++ b/src/resources/trim_plugin_msctconverter/metadata.yml @@ -0,0 +1,3 @@ +name: 伶伦转换器附件 +description: 伶伦转换器所用之资源包 +ersion: 2024.7.19 \ No newline at end of file diff --git a/src/resources/vanilla_language/lang/zh-CN.lang b/src/resources/vanilla_language/lang/zh-CN.lang index 47f1d2f..aa964d6 100644 --- a/src/resources/vanilla_language/lang/zh-CN.lang +++ b/src/resources/vanilla_language/lang/zh-CN.lang @@ -163,4 +163,7 @@ yanlun.refresh.failed=更新 言·论 信息发生 {ERR} 错误:{ERRCODE} yanlun.errtype.net=互联网连接 yanlun.errtype.unknown=未知 yanlun.count.head=出处ttt数量(占比) -yanlun.count.tail=...(共 {NUM} 条) \ No newline at end of file +yanlun.count.tail=...(共 {NUM} 条) +yanlun.length.toolong=言·论过长 +yanlun.length.tooshort=言·论过短 +yanlun.length.float=言·论不可是非整数长度 \ No newline at end of file diff --git a/src/resources/vanilla_language/lang/zh-WY.lang b/src/resources/vanilla_language/lang/zh-WY.lang index 71d5662..2379d98 100644 --- a/src/resources/vanilla_language/lang/zh-WY.lang +++ b/src/resources/vanilla_language/lang/zh-WY.lang @@ -163,4 +163,7 @@ yanlun.refresh.failed=言·论 因{ERR}而无以新:{ERRCODE} yanlun.errtype.net=遥讯不得 yanlun.errtype.unknown=无名之亏 yanlun.count.head=所缘ttt几何(比率) -yanlun.count.tail=...(合{NUM}条) \ No newline at end of file +yanlun.count.tail=...(合{NUM}条) +yanlun.length.toolong=繁言勿论 +yanlun.length.tooshort=无言以论 +yanlun.length.float=此言不获世之滋垢,皭然泥而不滓者也,故不论之 diff --git a/src/resources/vanilla_resource/templates/status.html b/src/resources/vanilla_resource/templates/status.html index 65ded14..a671b18 100644 --- a/src/resources/vanilla_resource/templates/status.html +++ b/src/resources/vanilla_resource/templates/status.html @@ -18,7 +18,7 @@
- TriM-Liteyuki + TriMO-Liteyuki

diff --git a/src/utils/__init__.py b/src/utils/__init__.py index a4b776f..b8502b3 100644 --- a/src/utils/__init__.py +++ b/src/utils/__init__.py @@ -6,7 +6,7 @@ import time import nonebot -__NAME__ = "LiteyukiBot-Trim" +__NAME__ = "LiteyukiBot-TriMO" __VERSION__ = "6.3.3" # 60201 # __VERSION_I__ = 99060303 diff --git a/src/utils/base/language.py b/src/utils/base/language.py index 962d9ad..5c4071b 100644 --- a/src/utils/base/language.py +++ b/src/utils/base/language.py @@ -43,9 +43,9 @@ def load_from_lang(file_path: str, lang_code: str = None): if lang_code not in _language_data: _language_data[lang_code] = {} _language_data[lang_code].update(data) - nonebot.logger.debug(f"Loaded language data from {file_path}") + nonebot.logger.debug(f"已从 {file_path} 读取语言文件") except Exception as e: - nonebot.logger.error(f"Failed to load language data from {file_path}: {e}") + nonebot.logger.error(f"无法读取以下目录中的语言文件 {file_path},详阅:{e}") def load_from_json(file_path: str, lang_code: str = None): @@ -196,7 +196,7 @@ def get_user_lang(user_id: str) -> Language: user_id = str(user_id) if user_id not in _user_lang: - nonebot.logger.debug(f"Loading user language for {user_id}") + nonebot.logger.debug(f"正为 {user_id} 加载语言包…") user = user_db.where_one( User(), "user_id = ?", diff --git a/src/utils/message/html_tool.py b/src/utils/message/html_tool.py index 63b53af..8f0cb62 100644 --- a/src/utils/message/html_tool.py +++ b/src/utils/message/html_tool.py @@ -6,7 +6,7 @@ from os import getcwd import aiofiles import nonebot -from nonebot_plugin_htmlrender import * +from nonebot_plugin_htmlrender import * # type: ignore from .tools import random_hex_string # import imgkit diff --git a/src/utils/message/message.py b/src/utils/message/message.py index 287ce35..ca4bd70 100644 --- a/src/utils/message/message.py +++ b/src/utils/message/message.py @@ -34,7 +34,9 @@ async def broadcast_to_superusers(message: str | T_Message, markdown: bool = Fal for bot in nonebot.get_bots().values(): for user_id in config.get("superusers", []): if markdown: - await MarkdownMessage.send_md(message, bot, message_type="private", session_id=user_id) + await MarkdownMessage.send_md( + message, bot, message_type="private", session_id=user_id + ) else: await bot.send_private_msg(user_id=user_id, message=message) @@ -42,13 +44,14 @@ async def broadcast_to_superusers(message: str | T_Message, markdown: bool = Fal class MarkdownMessage: @staticmethod async def send_md( - markdown: str, - bot: T_Bot, *, - message_type: str = None, - session_id: str | int = None, - event: T_MessageEvent = None, - retry_as_image: bool = True, - **kwargs + markdown: str, + bot: T_Bot, + *, + message_type: str = None, + session_id: str | int = None, + event: T_MessageEvent = None, + retry_as_image: bool = True, + **kwargs, ) -> dict[str, Any] | None: """ 发送Markdown消息,支持自动转为图片发送 @@ -64,7 +67,7 @@ class MarkdownMessage: Returns: """ - formatted_md = v11.unescape(markdown).replace("\n", r"\n").replace('"', r'\\\"') + formatted_md = v11.unescape(markdown).replace("\n", r"\n").replace('"', r"\\\"") if event is not None and message_type is None: if isinstance(event, satori.event.Event): message_type = "private" if event.guild is None else "group" @@ -73,83 +76,81 @@ class MarkdownMessage: assert event is not None message_type = event.message_type group_id = event.group_id if message_type == "group" else None - user_id = event.user.id if isinstance(event, satori.event.Event) else event.user_id + user_id = ( + event.user.id + if isinstance(event, satori.event.Event) + else event.user_id + ) session_id = user_id if message_type == "private" else group_id - - - try: - raise TencentBannedMarkdownError("Tencent banned markdown") - forward_id = await bot.call_api( - "send_private_forward_msg", - messages=[ - { - "type": "node", - "data": { - "content": [ - { - "data": { - "content": "{\"content\":\"%s\"}" % formatted_md, - }, - "type": "markdown" - } - ], - "name": "[]", - "uin": bot.self_id - } - } - ], - user_id=bot.self_id - ) + # try: + # raise TencentBannedMarkdownError("Tencent banned markdown") + # forward_id = await bot.call_api( + # "send_private_forward_msg", + # messages=[ + # { + # "type": "node", + # "data": { + # "content": [ + # { + # "data": { + # "content": "{\"content\":\"%s\"}" % formatted_md, + # }, + # "type": "markdown" + # } + # ], + # "name": "[]", + # "uin": bot.self_id + # } + # } + # ], + # user_id=bot.self_id + + # ) + # data = await bot.send_msg( + # user_id=session_id, + # group_id=session_id, + # message_type=message_type, + # message=[ + # { + # "type": "longmsg", + # "data": { + # "id": forward_id + # } + # }, + # ], + # **kwargs + # ) + # except BaseException as e: + + nonebot.logger.error(f"因未能发送Markdown消息,已转为图片发送。") + # 发送失败,渲染为图片发送 + # if not retry_as_image: + # return None + + # plain_markdown = markdown.replace("[🔗", "[") + md_image_bytes = await md_to_pic(md=markdown, width=540, device_scale_factor=4) + if isinstance(bot, satori.Bot): + msg_seg = satori.MessageSegment.image(raw=md_image_bytes, mime="image/png") + data = await bot.send(event=event, message=msg_seg) + else: data = await bot.send_msg( - user_id=session_id, - group_id=session_id, message_type=message_type, - message=[ - { - "type": "longmsg", - "data": { - "id": forward_id - } - }, - ], - **kwargs + group_id=session_id, + user_id=session_id, + message=v11.MessageSegment.image(md_image_bytes), ) - except BaseException as e: - nonebot.logger.error(f"send markdown error, retry as image: {e}") - # 发送失败,渲染为图片发送 - # if not retry_as_image: - # return None - - plain_markdown = markdown.replace("[🔗", "[") - md_image_bytes = await md_to_pic( - md=plain_markdown, - width=540, - device_scale_factor=4 - ) - if isinstance(bot, satori.Bot): - msg_seg = satori.MessageSegment.image(raw=md_image_bytes,mime="image/png") - data = await bot.send( - event=event, - message=msg_seg - ) - else: - data = await bot.send_msg( - message_type=message_type, - group_id=session_id, - user_id=session_id, - message=v11.MessageSegment.image(md_image_bytes), - ) return data @staticmethod async def send_image( - image: bytes | str, - bot: T_Bot, *, - message_type: str = None, - session_id: str | int = None, - event: T_MessageEvent = None, - **kwargs + image: bytes | str, + bot: T_Bot, + *, + message_type: str = None, + session_id: str | int = None, + event: T_MessageEvent = None, + **kwargs, ) -> dict: """ 发送单张装逼大图 @@ -181,23 +182,35 @@ class MarkdownMessage: if method == 2: base64_string = base64.b64encode(image).decode("utf-8") data = await bot.call_api("upload_image", file=f"base64://{base64_string}") - await MarkdownMessage.send_md(MarkdownMessage.image(data, Image.open(io.BytesIO(image)).size), bot, - event=event, message_type=message_type, - session_id=session_id, **kwargs) + await MarkdownMessage.send_md( + MarkdownMessage.image(data, Image.open(io.BytesIO(image)).size), + bot, + event=event, + message_type=message_type, + session_id=session_id, + **kwargs, + ) # 其他实现端方案 else: - image_message_id = (await bot.send_private_msg( - user_id=bot.self_id, - message=[ - v11.MessageSegment.image(file=image) - ] - ))["message_id"] - image_url = (await bot.get_msg(message_id=image_message_id))["message"][0]["data"]["url"] + image_message_id = ( + await bot.send_private_msg( + user_id=bot.self_id, message=[v11.MessageSegment.image(file=image)] + ) + )["message_id"] + image_url = (await bot.get_msg(message_id=image_message_id))["message"][0][ + "data" + ]["url"] image_size = Image.open(io.BytesIO(image)).size image_md = MarkdownMessage.image(image_url, image_size) - return await MarkdownMessage.send_md(image_md, bot, message_type=message_type, session_id=session_id, - event=event, **kwargs) + return await MarkdownMessage.send_md( + image_md, + bot, + message_type=message_type, + session_id=session_id, + event=event, + **kwargs, + ) if data is None: data = await bot.send_msg( @@ -205,7 +218,7 @@ class MarkdownMessage: group_id=session_id, user_id=session_id, message=v11.MessageSegment.image(image), - **kwargs + **kwargs, ) return data @@ -232,7 +245,9 @@ class MarkdownMessage: markdown格式的可点击回调按钮 """ - if "" not in config.get("command_start", ["/"]) and config.get("alconna_use_command_start", False): + if "" not in config.get("command_start", ["/"]) and config.get( + "alconna_use_command_start", False + ): cmd = f"{config['command_start'][0]}{cmd}" return f"[{name}](mqqapi://aio/inlinecmd?command={quote(cmd)}&reply={str(reply).lower()}&enter={str(enter).lower()})" diff --git a/src/plugins/liteyuki_mctools/__init__.py b/unused_plugin/liteyuki_mctools/__init__.py similarity index 96% rename from src/plugins/liteyuki_mctools/__init__.py rename to unused_plugin/liteyuki_mctools/__init__.py index a1c5166..dece472 100644 --- a/src/plugins/liteyuki_mctools/__init__.py +++ b/unused_plugin/liteyuki_mctools/__init__.py @@ -1,15 +1,15 @@ -from nonebot.plugin import PluginMetadata -from nonebot import get_driver - -__plugin_meta__ = PluginMetadata( - name="Minecraft工具箱", - description="一些Minecraft相关工具箱", - usage="我觉得你应该会用", - type="application", - homepage="https://github.com/snowykami/LiteyukiBot", - extra={ - "liteyuki" : True, - "toggleable" : True, - "default_enable": True, - } +from nonebot.plugin import PluginMetadata +from nonebot import get_driver + +__plugin_meta__ = PluginMetadata( + name="Minecraft工具箱", + description="一些Minecraft相关工具箱", + usage="我觉得你应该会用", + type="application", + homepage="https://github.com/snowykami/LiteyukiBot", + extra={ + "liteyuki" : True, + "toggleable" : True, + "default_enable": True, + } ) \ No newline at end of file diff --git a/src/plugins/liteyuki_packmanv2/__init__.py b/unused_plugin/liteyuki_packmanv2/__init__.py similarity index 96% rename from src/plugins/liteyuki_packmanv2/__init__.py rename to unused_plugin/liteyuki_packmanv2/__init__.py index d5bbbc0..6121de7 100644 --- a/src/plugins/liteyuki_packmanv2/__init__.py +++ b/unused_plugin/liteyuki_packmanv2/__init__.py @@ -1,20 +1,20 @@ -from nonebot.plugin import PluginMetadata - -__author__ = "snowykami" -__plugin_meta__ = PluginMetadata( - name="轻雪包管理器v2", - description="详细看文档", - usage=( - "npm list\n" - "npm enable/disable \n" - "npm search \n" - "npm install/uninstall \n" - ), - type="application", - homepage="https://github.com/snowykami/LiteyukiBot", - extra={ - "liteyuki": True, - "toggleable" : False, - "default_enable" : False, - } -) +from nonebot.plugin import PluginMetadata + +__author__ = "snowykami" +__plugin_meta__ = PluginMetadata( + name="轻雪包管理器v2", + description="详细看文档", + usage=( + "npm list\n" + "npm enable/disable \n" + "npm search \n" + "npm install/uninstall \n" + ), + type="application", + homepage="https://github.com/snowykami/LiteyukiBot", + extra={ + "liteyuki": True, + "toggleable" : False, + "default_enable" : False, + } +) diff --git a/src/plugins/liteyuki_weather/__init__.py b/unused_plugin/liteyuki_weather/__init__.py similarity index 96% rename from src/plugins/liteyuki_weather/__init__.py rename to unused_plugin/liteyuki_weather/__init__.py index e939b57..2127a6a 100644 --- a/src/plugins/liteyuki_weather/__init__.py +++ b/unused_plugin/liteyuki_weather/__init__.py @@ -1,27 +1,27 @@ -from nonebot.plugin import PluginMetadata -from nonebot import get_driver -from .qweather import * - -__plugin_meta__ = PluginMetadata( - name="轻雪天气", - description="基于和风天气api的天气插件", - usage="", - type="application", - homepage="https://github.com/snowykami/LiteyukiBot", - extra={ - "liteyuki" : True, - "toggleable" : True, - "default_enable": True, - } -) - -from ...utils.base.data_manager import set_memory_data - -driver = get_driver() - - -@driver.on_startup -async def _(): - # 检查是否为开发者模式 - is_dev = await check_key_dev(get_config("weather_key", "")) - set_memory_data("weather.is_dev", is_dev) +from nonebot.plugin import PluginMetadata +from nonebot import get_driver +from .qweather import * + +__plugin_meta__ = PluginMetadata( + name="轻雪天气", + description="基于和风天气api的天气插件", + usage="", + type="application", + homepage="https://github.com/snowykami/LiteyukiBot", + extra={ + "liteyuki" : True, + "toggleable" : True, + "default_enable": True, + } +) + +from ...utils.base.data_manager import set_memory_data + +driver = get_driver() + + +@driver.on_startup +async def _(): + # 检查是否为开发者模式 + is_dev = await check_key_dev(get_config("weather_key", "")) + set_memory_data("weather.is_dev", is_dev) diff --git a/src/plugins/liteyuki_weather/qw_api.py b/unused_plugin/liteyuki_weather/qw_api.py similarity index 96% rename from src/plugins/liteyuki_weather/qw_api.py rename to unused_plugin/liteyuki_weather/qw_api.py index 510d821..8f28cd9 100644 --- a/src/plugins/liteyuki_weather/qw_api.py +++ b/unused_plugin/liteyuki_weather/qw_api.py @@ -1,171 +1,171 @@ -import aiohttp - -from .qw_models import * -import httpx - -from ...utils.base.data_manager import get_memory_data -from ...utils.base.language import Language - -dev_url = "https://devapi.qweather.com/" # 开发HBa -com_url = "https://api.qweather.com/" # 正式环境 - - -def get_qw_lang(lang: str) -> str: - if lang in ["zh-HK", "zh-TW"]: - return "zh-hant" - elif lang.startswith("zh"): - return "zh" - elif lang.startswith("en"): - return "en" - else: - return lang - - -async def check_key_dev(key: str) -> bool: - url = "https://api.qweather.com/v7/weather/now?" - params = { - "location": "101010100", - "key" : key, - } - async with aiohttp.ClientSession() as client: - resp = await client.get(url, params=params) - return (await resp.json()).get("code") != "200" # 查询不到付费数据为开发版 - - -def get_local_data(ulang_code: str) -> dict: - """ - 获取本地化数据 - Args: - ulang_code: - - Returns: - - """ - ulang = Language(ulang_code) - return { - "monday" : ulang.get("weather.monday"), - "tuesday" : ulang.get("weather.tuesday"), - "wednesday": ulang.get("weather.wednesday"), - "thursday" : ulang.get("weather.thursday"), - "friday" : ulang.get("weather.friday"), - "saturday" : ulang.get("weather.saturday"), - "sunday" : ulang.get("weather.sunday"), - "today" : ulang.get("weather.today"), - "tomorrow" : ulang.get("weather.tomorrow"), - "day" : ulang.get("weather.day"), - "night" : ulang.get("weather.night"), - "no_aqi" : ulang.get("weather.no_aqi"), - } - - -async def city_lookup( - location: str, - key: str, - adm: str = "", - number: int = 20, - lang: str = "zh", -) -> CityLookup: - """ - 通过关键字搜索城市信息 - Args: - location: - key: - adm: - number: - lang: 可传入标准i18n语言代码,如zh-CN、en-US等 - - Returns: - - """ - url = "https://geoapi.qweather.com/v2/city/lookup?" - params = { - "location": location, - "adm" : adm, - "number" : number, - "key" : key, - "lang" : lang, - } - async with httpx.AsyncClient() as client: - resp = await client.get(url, params=params) - return CityLookup.parse_obj(resp.json()) - - -async def get_weather_now( - key: str, - location: str, - lang: str = "zh", - unit: str = "m", - dev: bool = get_memory_data("is_dev", True), -) -> dict: - url_path = "v7/weather/now?" - url = dev_url + url_path if dev else com_url + url_path - params = { - "location": location, - "key" : key, - "lang" : lang, - "unit" : unit, - } - async with httpx.AsyncClient() as client: - resp = await client.get(url, params=params) - return resp.json() - - -async def get_weather_daily( - key: str, - location: str, - lang: str = "zh", - unit: str = "m", - dev: bool = get_memory_data("is_dev", True), -) -> dict: - url_path = "v7/weather/%dd?" % (7 if dev else 30) - url = dev_url + url_path if dev else com_url + url_path - params = { - "location": location, - "key" : key, - "lang" : lang, - "unit" : unit, - } - async with httpx.AsyncClient() as client: - resp = await client.get(url, params=params) - return resp.json() - - -async def get_weather_hourly( - key: str, - location: str, - lang: str = "zh", - unit: str = "m", - dev: bool = get_memory_data("is_dev", True), -) -> dict: - url_path = "v7/weather/%dh?" % (24 if dev else 168) - url = dev_url + url_path if dev else com_url + url_path - params = { - "location": location, - "key" : key, - "lang" : lang, - "unit" : unit, - } - async with httpx.AsyncClient() as client: - resp = await client.get(url, params=params) - return resp.json() - - -async def get_airquality( - key: str, - location: str, - lang: str, - pollutant: bool = False, - station: bool = False, - dev: bool = get_memory_data("is_dev", True), -) -> dict: - url_path = f"airquality/v1/now/{location}?" - url = dev_url + url_path if dev else com_url + url_path - params = { - "key" : key, - "lang" : lang, - "pollutant": pollutant, - "station" : station, - } - async with httpx.AsyncClient() as client: - resp = await client.get(url, params=params) - return resp.json() +import aiohttp + +from .qw_models import * +import httpx + +from ...utils.base.data_manager import get_memory_data +from ...utils.base.language import Language + +dev_url = "https://devapi.qweather.com/" # 开发HBa +com_url = "https://api.qweather.com/" # 正式环境 + + +def get_qw_lang(lang: str) -> str: + if lang in ["zh-HK", "zh-TW"]: + return "zh-hant" + elif lang.startswith("zh"): + return "zh" + elif lang.startswith("en"): + return "en" + else: + return lang + + +async def check_key_dev(key: str) -> bool: + url = "https://api.qweather.com/v7/weather/now?" + params = { + "location": "101010100", + "key" : key, + } + async with aiohttp.ClientSession() as client: + resp = await client.get(url, params=params) + return (await resp.json()).get("code") != "200" # 查询不到付费数据为开发版 + + +def get_local_data(ulang_code: str) -> dict: + """ + 获取本地化数据 + Args: + ulang_code: + + Returns: + + """ + ulang = Language(ulang_code) + return { + "monday" : ulang.get("weather.monday"), + "tuesday" : ulang.get("weather.tuesday"), + "wednesday": ulang.get("weather.wednesday"), + "thursday" : ulang.get("weather.thursday"), + "friday" : ulang.get("weather.friday"), + "saturday" : ulang.get("weather.saturday"), + "sunday" : ulang.get("weather.sunday"), + "today" : ulang.get("weather.today"), + "tomorrow" : ulang.get("weather.tomorrow"), + "day" : ulang.get("weather.day"), + "night" : ulang.get("weather.night"), + "no_aqi" : ulang.get("weather.no_aqi"), + } + + +async def city_lookup( + location: str, + key: str, + adm: str = "", + number: int = 20, + lang: str = "zh", +) -> CityLookup: + """ + 通过关键字搜索城市信息 + Args: + location: + key: + adm: + number: + lang: 可传入标准i18n语言代码,如zh-CN、en-US等 + + Returns: + + """ + url = "https://geoapi.qweather.com/v2/city/lookup?" + params = { + "location": location, + "adm" : adm, + "number" : number, + "key" : key, + "lang" : lang, + } + async with httpx.AsyncClient() as client: + resp = await client.get(url, params=params) + return CityLookup.parse_obj(resp.json()) + + +async def get_weather_now( + key: str, + location: str, + lang: str = "zh", + unit: str = "m", + dev: bool = get_memory_data("is_dev", True), +) -> dict: + url_path = "v7/weather/now?" + url = dev_url + url_path if dev else com_url + url_path + params = { + "location": location, + "key" : key, + "lang" : lang, + "unit" : unit, + } + async with httpx.AsyncClient() as client: + resp = await client.get(url, params=params) + return resp.json() + + +async def get_weather_daily( + key: str, + location: str, + lang: str = "zh", + unit: str = "m", + dev: bool = get_memory_data("is_dev", True), +) -> dict: + url_path = "v7/weather/%dd?" % (7 if dev else 30) + url = dev_url + url_path if dev else com_url + url_path + params = { + "location": location, + "key" : key, + "lang" : lang, + "unit" : unit, + } + async with httpx.AsyncClient() as client: + resp = await client.get(url, params=params) + return resp.json() + + +async def get_weather_hourly( + key: str, + location: str, + lang: str = "zh", + unit: str = "m", + dev: bool = get_memory_data("is_dev", True), +) -> dict: + url_path = "v7/weather/%dh?" % (24 if dev else 168) + url = dev_url + url_path if dev else com_url + url_path + params = { + "location": location, + "key" : key, + "lang" : lang, + "unit" : unit, + } + async with httpx.AsyncClient() as client: + resp = await client.get(url, params=params) + return resp.json() + + +async def get_airquality( + key: str, + location: str, + lang: str, + pollutant: bool = False, + station: bool = False, + dev: bool = get_memory_data("is_dev", True), +) -> dict: + url_path = f"airquality/v1/now/{location}?" + url = dev_url + url_path if dev else com_url + url_path + params = { + "key" : key, + "lang" : lang, + "pollutant": pollutant, + "station" : station, + } + async with httpx.AsyncClient() as client: + resp = await client.get(url, params=params) + return resp.json() diff --git a/src/plugins/liteyuki_weather/qw_models.py b/unused_plugin/liteyuki_weather/qw_models.py similarity index 94% rename from src/plugins/liteyuki_weather/qw_models.py rename to unused_plugin/liteyuki_weather/qw_models.py index 9879583..e546ea1 100644 --- a/src/plugins/liteyuki_weather/qw_models.py +++ b/unused_plugin/liteyuki_weather/qw_models.py @@ -1,62 +1,62 @@ -from src.utils.base.data import LiteModel - - -class Location(LiteModel): - name: str = "" - id: str = "" - lat: str = "" - lon: str = "" - adm2: str = "" - adm1: str = "" - country: str = "" - tz: str = "" - utcOffset: str = "" - isDst: str = "" - type: str = "" - rank: str = "" - fxLink: str = "" - sources: str = "" - license: str = "" - - -class CityLookup(LiteModel): - code: str = "" - location: list[Location] = [Location()] - - -class Now(LiteModel): - obsTime: str = "" - temp: str = "" - feelsLike: str = "" - icon: str = "" - text: str = "" - wind360: str = "" - windDir: str = "" - windScale: str = "" - windSpeed: str = "" - humidity: str = "" - precip: str = "" - pressure: str = "" - vis: str = "" - cloud: str = "" - dew: str = "" - sources: str = "" - license: str = "" - - -class WeatherNow(LiteModel): - code: str = "" - updateTime: str = "" - fxLink: str = "" - now: Now = Now() - - -class Daily(LiteModel): - pass - - -class WeatherDaily(LiteModel): - code: str = "" - updateTime: str = "" - fxLink: str = "" - daily: list[str] = [] +from src.utils.base.data import LiteModel + + +class Location(LiteModel): + name: str = "" + id: str = "" + lat: str = "" + lon: str = "" + adm2: str = "" + adm1: str = "" + country: str = "" + tz: str = "" + utcOffset: str = "" + isDst: str = "" + type: str = "" + rank: str = "" + fxLink: str = "" + sources: str = "" + license: str = "" + + +class CityLookup(LiteModel): + code: str = "" + location: list[Location] = [Location()] + + +class Now(LiteModel): + obsTime: str = "" + temp: str = "" + feelsLike: str = "" + icon: str = "" + text: str = "" + wind360: str = "" + windDir: str = "" + windScale: str = "" + windSpeed: str = "" + humidity: str = "" + precip: str = "" + pressure: str = "" + vis: str = "" + cloud: str = "" + dew: str = "" + sources: str = "" + license: str = "" + + +class WeatherNow(LiteModel): + code: str = "" + updateTime: str = "" + fxLink: str = "" + now: Now = Now() + + +class Daily(LiteModel): + pass + + +class WeatherDaily(LiteModel): + code: str = "" + updateTime: str = "" + fxLink: str = "" + daily: list[str] = [] diff --git a/src/plugins/liteyuki_weather/qweather.py b/unused_plugin/liteyuki_weather/qweather.py similarity index 97% rename from src/plugins/liteyuki_weather/qweather.py rename to unused_plugin/liteyuki_weather/qweather.py index 709e52e..beccd15 100644 --- a/src/plugins/liteyuki_weather/qweather.py +++ b/unused_plugin/liteyuki_weather/qweather.py @@ -1,101 +1,101 @@ -from nonebot import require, on_endswith -from nonebot.adapters import satori -from nonebot.adapters.onebot.v11 import MessageSegment -from nonebot.internal.matcher import Matcher - -from src.utils.base.config import get_config -from src.utils.base.ly_typing import T_MessageEvent - -from .qw_api import * -from src.utils.base.data_manager import User, user_db -from src.utils.base.language import Language, get_user_lang -from src.utils.base.resource import get_path -from src.utils.message.html_tool import template2image -from src.utils import event as event_utils - -require("nonebot_plugin_alconna") -from nonebot_plugin_alconna import on_alconna, Alconna, Args, MultiVar, Arparma, UniMessage - -wx_alc = on_alconna( - aliases={"天气"}, - command=Alconna( - "weather", - Args["keywords", MultiVar(str), []], - ), -) - - -@wx_alc.handle() -async def _(result: Arparma, event: T_MessageEvent, matcher: Matcher): - """await alconna.send("weather", city)""" - kws = result.main_args.get("keywords") - image = await get_weather_now_card(matcher, event, kws) - await wx_alc.finish(UniMessage.image(raw=image)) - - -@on_endswith(("天气", "weather")).handle() -async def _(event: T_MessageEvent, matcher: Matcher): - """await alconna.send("weather", city)""" - # kws = event.message.extract_plain_text() - kws = event.get_plaintext() - image = await get_weather_now_card(matcher, event, [kws.replace("天气", "").replace("weather", "")], False) - if isinstance(event, satori.event.Event): - await matcher.finish(satori.MessageSegment.image(raw=image, mime="image/png")) - else: - await matcher.finish(MessageSegment.image(image)) - - -async def get_weather_now_card(matcher: Matcher, event: T_MessageEvent, keyword: list[str], tip: bool = True): - ulang = get_user_lang(event_utils.get_user_id(event)) - qw_lang = get_qw_lang(ulang.lang_code) - key = get_config("weather_key") - is_dev = get_memory_data("weather.is_dev", True) - user: User = user_db.where_one(User(), "user_id = ?", event_utils.get_user_id(event), default=User()) - # params - unit = user.profile.get("unit", "m") - stored_location = user.profile.get("location", None) - - if not key: - await matcher.finish(ulang.get("weather.no_key") if tip else None) - - if keyword: - if len(keyword) >= 2: - adm = keyword[0] - city = keyword[-1] - else: - adm = "" - city = keyword[0] - city_info = await city_lookup(city, key, adm=adm, lang=qw_lang) - city_name = " ".join(keyword) - else: - if not stored_location: - await matcher.finish(ulang.get("liteyuki.invalid_command", TEXT="location") if tip else None) - city_info = await city_lookup(stored_location, key, lang=qw_lang) - city_name = stored_location - if city_info.code == "200": - location_data = city_info.location[0] - else: - await matcher.finish(ulang.get("weather.city_not_found", CITY=city_name) if tip else None) - weather_now = await get_weather_now(key, location_data.id, lang=qw_lang, unit=unit, dev=is_dev) - weather_daily = await get_weather_daily(key, location_data.id, lang=qw_lang, unit=unit, dev=is_dev) - weather_hourly = await get_weather_hourly(key, location_data.id, lang=qw_lang, unit=unit, dev=is_dev) - aqi = await get_airquality(key, location_data.id, lang=qw_lang, dev=is_dev) - - image = await template2image( - template=get_path("templates/weather_now.html", abs_path=True), - templates={ - "data": { - "params" : { - "unit": unit, - "lang": ulang.lang_code, - }, - "weatherNow" : weather_now, - "weatherDaily" : weather_daily, - "weatherHourly": weather_hourly, - "aqi" : aqi, - "location" : location_data.dump(), - "localization" : get_local_data(ulang.lang_code) - } - }, - ) - return image +from nonebot import require, on_endswith +from nonebot.adapters import satori +from nonebot.adapters.onebot.v11 import MessageSegment +from nonebot.internal.matcher import Matcher + +from src.utils.base.config import get_config +from src.utils.base.ly_typing import T_MessageEvent + +from .qw_api import * +from src.utils.base.data_manager import User, user_db +from src.utils.base.language import Language, get_user_lang +from src.utils.base.resource import get_path +from src.utils.message.html_tool import template2image +from src.utils import event as event_utils + +require("nonebot_plugin_alconna") +from nonebot_plugin_alconna import on_alconna, Alconna, Args, MultiVar, Arparma, UniMessage + +wx_alc = on_alconna( + aliases={"天气"}, + command=Alconna( + "weather", + Args["keywords", MultiVar(str), []], + ), +) + + +@wx_alc.handle() +async def _(result: Arparma, event: T_MessageEvent, matcher: Matcher): + """await alconna.send("weather", city)""" + kws = result.main_args.get("keywords") + image = await get_weather_now_card(matcher, event, kws) + await wx_alc.finish(UniMessage.image(raw=image)) + + +@on_endswith(("天气", "weather")).handle() +async def _(event: T_MessageEvent, matcher: Matcher): + """await alconna.send("weather", city)""" + # kws = event.message.extract_plain_text() + kws = event.get_plaintext() + image = await get_weather_now_card(matcher, event, [kws.replace("天气", "").replace("weather", "")], False) + if isinstance(event, satori.event.Event): + await matcher.finish(satori.MessageSegment.image(raw=image, mime="image/png")) + else: + await matcher.finish(MessageSegment.image(image)) + + +async def get_weather_now_card(matcher: Matcher, event: T_MessageEvent, keyword: list[str], tip: bool = True): + ulang = get_user_lang(event_utils.get_user_id(event)) + qw_lang = get_qw_lang(ulang.lang_code) + key = get_config("weather_key") + is_dev = get_memory_data("weather.is_dev", True) + user: User = user_db.where_one(User(), "user_id = ?", event_utils.get_user_id(event), default=User()) + # params + unit = user.profile.get("unit", "m") + stored_location = user.profile.get("location", None) + + if not key: + await matcher.finish(ulang.get("weather.no_key") if tip else None) + + if keyword: + if len(keyword) >= 2: + adm = keyword[0] + city = keyword[-1] + else: + adm = "" + city = keyword[0] + city_info = await city_lookup(city, key, adm=adm, lang=qw_lang) + city_name = " ".join(keyword) + else: + if not stored_location: + await matcher.finish(ulang.get("liteyuki.invalid_command", TEXT="location") if tip else None) + city_info = await city_lookup(stored_location, key, lang=qw_lang) + city_name = stored_location + if city_info.code == "200": + location_data = city_info.location[0] + else: + await matcher.finish(ulang.get("weather.city_not_found", CITY=city_name) if tip else None) + weather_now = await get_weather_now(key, location_data.id, lang=qw_lang, unit=unit, dev=is_dev) + weather_daily = await get_weather_daily(key, location_data.id, lang=qw_lang, unit=unit, dev=is_dev) + weather_hourly = await get_weather_hourly(key, location_data.id, lang=qw_lang, unit=unit, dev=is_dev) + aqi = await get_airquality(key, location_data.id, lang=qw_lang, dev=is_dev) + + image = await template2image( + template=get_path("templates/weather_now.html", abs_path=True), + templates={ + "data": { + "params" : { + "unit": unit, + "lang": ulang.lang_code, + }, + "weatherNow" : weather_now, + "weatherDaily" : weather_daily, + "weatherHourly": weather_hourly, + "aqi" : aqi, + "location" : location_data.dump(), + "localization" : get_local_data(ulang.lang_code) + } + }, + ) + return image diff --git a/src/resources/liteyuki_weather/lang/en.lang b/unused_resource/liteyuki_weather/lang/en.lang similarity index 95% rename from src/resources/liteyuki_weather/lang/en.lang rename to unused_resource/liteyuki_weather/lang/en.lang index d8642df..9822bda 100644 --- a/src/resources/liteyuki_weather/lang/en.lang +++ b/unused_resource/liteyuki_weather/lang/en.lang @@ -1,12 +1,12 @@ -weather.monday=Mon -weather.tuesday=Tue -weather.wednesday=Wed -weather.thursday=Thu -weather.friday=Fri -weather.saturday=Sat -weather.sunday=Sun -weather.day=Day -weather.night=Night -weather.today=Today -weather.tomorrow=Tomorrow +weather.monday=Mon +weather.tuesday=Tue +weather.wednesday=Wed +weather.thursday=Thu +weather.friday=Fri +weather.saturday=Sat +weather.sunday=Sun +weather.day=Day +weather.night=Night +weather.today=Today +weather.tomorrow=Tomorrow weather.no_aqi=No AQI data \ No newline at end of file diff --git a/src/resources/liteyuki_weather/lang/ja.lang b/unused_resource/liteyuki_weather/lang/ja.lang similarity index 95% rename from src/resources/liteyuki_weather/lang/ja.lang rename to unused_resource/liteyuki_weather/lang/ja.lang index 5c39ab6..58bcd04 100644 --- a/src/resources/liteyuki_weather/lang/ja.lang +++ b/unused_resource/liteyuki_weather/lang/ja.lang @@ -1,12 +1,12 @@ -weather.monday=月 -weather.tuesday=火 -weather.wednesday=水 -weather.thursday=木 -weather.friday=金 -weather.saturday=土 -weather.sunday=日 -weather.day=昼 -weather.night=夜 -weather.today=今日 -weather.tomorrow=明日 +weather.monday=月 +weather.tuesday=火 +weather.wednesday=水 +weather.thursday=木 +weather.friday=金 +weather.saturday=土 +weather.sunday=日 +weather.day=昼 +weather.night=夜 +weather.today=今日 +weather.tomorrow=明日 weather.no_aqi=空気質データなし \ No newline at end of file diff --git a/src/resources/liteyuki_weather/lang/zh-CN.lang b/unused_resource/liteyuki_weather/lang/zh-CN.lang similarity index 96% rename from src/resources/liteyuki_weather/lang/zh-CN.lang rename to unused_resource/liteyuki_weather/lang/zh-CN.lang index e4fb52e..a4f44d5 100644 --- a/src/resources/liteyuki_weather/lang/zh-CN.lang +++ b/unused_resource/liteyuki_weather/lang/zh-CN.lang @@ -1,12 +1,12 @@ -weather.monday=周一 -weather.tuesday=周二 -weather.wednesday=周三 -weather.thursday=周四 -weather.friday=周五 -weather.saturday=周六 -weather.sunday=周日 -weather.day=白天 -weather.night=夜晚 -weather.today=今天 -weather.tomorrow=明天 +weather.monday=周一 +weather.tuesday=周二 +weather.wednesday=周三 +weather.thursday=周四 +weather.friday=周五 +weather.saturday=周六 +weather.sunday=周日 +weather.day=白天 +weather.night=夜晚 +weather.today=今天 +weather.tomorrow=明天 weather.no_aqi=暂无AQI数据 \ No newline at end of file diff --git a/src/resources/liteyuki_weather/metadata.yml b/unused_resource/liteyuki_weather/metadata.yml similarity index 97% rename from src/resources/liteyuki_weather/metadata.yml rename to unused_resource/liteyuki_weather/metadata.yml index 02ecd39..10b0ba3 100644 --- a/src/resources/liteyuki_weather/metadata.yml +++ b/unused_resource/liteyuki_weather/metadata.yml @@ -1,3 +1,3 @@ -name: 轻雪天气资源包 -description: For Liteyuki Weather +name: 轻雪天气资源包 +description: For Liteyuki Weather version: 2024.4.26 \ No newline at end of file diff --git a/src/resources/liteyuki_weather/templates/css/weather_now.css b/unused_resource/liteyuki_weather/templates/css/weather_now.css similarity index 94% rename from src/resources/liteyuki_weather/templates/css/weather_now.css rename to unused_resource/liteyuki_weather/templates/css/weather_now.css index f25f4dd..7776e4b 100644 --- a/src/resources/liteyuki_weather/templates/css/weather_now.css +++ b/unused_resource/liteyuki_weather/templates/css/weather_now.css @@ -1,184 +1,184 @@ -:root { - --main-text-color: #fff; - --sub-text-color: #ccc; - --tip-text-color: #999; - --device-info-width: 240px; - --sub-border-radius: 60px; -} - -#weather-info { - color: white; - /*justify-content: center;*/ - /*align-items: center;*/ - /*align-content: center;*/ -} - -.icon { -/* icon 类img阴影*/ - filter: drop-shadow(1px 1px 10px #00000044); -} - -#main-info { - display: flex; - justify-content: center; - align-items: center; -} - -#main-left { - display: flex; - justify-content: flex-end; - width: 50%; -} - -#main-right { - width: 50%; -} - -#time { - font-size: 25px; - font-weight: bold; - font-style: italic; - text-align: right; - color: var(--sub-text-color); - -} - -#adm { - font-size: 32px; - font-weight: bold; - text-align: center; - color: var(--sub-text-color); -} - -#city { - margin-top: 20px; - font-size: 70px; - font-weight: bold; - text-align: center; -} - -#temperature { - display: flex; - align-items: baseline; - -} - -#temperature-now { - font-size: 70px; - font-weight: bold; -} - -#temperature-range { - font-size: 40px; - font-weight: bold; - color: var(--sub-text-color); -} - -#description { - font-size: 50px; - font-weight: bold; -} - - -#aqi { - height: 50px; - display: flex; - border-radius: 60px; - padding: 5px; - font-size: 40px; - text-align: center; - align-content: center; - align-items: center; - justify-content: center; -} - -#aqi-dot { - height: 80%; - aspect-ratio: 1 / 1; - border-radius: 50%; - background-color: var(--sub-text-color); - margin-right: 20px; -} - -.main-icon { - width: 240px; - height: 240px; -} - -#hours-info { - display: flex; - justify-content: space-between; -} - -.hourly-item { - text-align: center; - background-color: #ffffff44; - border-radius: var(--sub-border-radius); - align-items: center; - padding: 20px 10px; -} - -.hourly-icon{ - width: 80%; - margin-bottom: 20px; -} - -.hourly-temperature { - text-align: center; - color: var(--main-text-color); - font-size: 30px; - margin-bottom: 20px; -} - -.hourly-time { - text-align: center; - color: var(--main-text-color); - font-size: 25px; - margin-bottom: 10px; -} - -/**/ -.daily-item { - display: flex; - position: relative; - justify-content: space-between; - align-items: center; - background-color: #ffffff44; - height: 90px; - border-radius: var(--sub-border-radius); - margin-bottom: 20px; - padding: 0 30px; -} - -/*最后一个没有margin_button*/ -.daily-item:last-child { - margin-bottom: 0; -} - -.icon-day { - position: absolute; - left: 60%; - height: 80px; -} - -.icon-night { - position: absolute; - left: 70%; - height: 80px; -} - -.daily-weather{ - position: absolute; - left: 30%; -} - -.daily-temperature{ - position: absolute; - left: 83%; -} - -.daily-day, .daily-weather, .daily-temperature { - text-align: center; - color: var(--main-text-color); - font-size: 30px; +:root { + --main-text-color: #fff; + --sub-text-color: #ccc; + --tip-text-color: #999; + --device-info-width: 240px; + --sub-border-radius: 60px; +} + +#weather-info { + color: white; + /*justify-content: center;*/ + /*align-items: center;*/ + /*align-content: center;*/ +} + +.icon { +/* icon 类img阴影*/ + filter: drop-shadow(1px 1px 10px #00000044); +} + +#main-info { + display: flex; + justify-content: center; + align-items: center; +} + +#main-left { + display: flex; + justify-content: flex-end; + width: 50%; +} + +#main-right { + width: 50%; +} + +#time { + font-size: 25px; + font-weight: bold; + font-style: italic; + text-align: right; + color: var(--sub-text-color); + +} + +#adm { + font-size: 32px; + font-weight: bold; + text-align: center; + color: var(--sub-text-color); +} + +#city { + margin-top: 20px; + font-size: 70px; + font-weight: bold; + text-align: center; +} + +#temperature { + display: flex; + align-items: baseline; + +} + +#temperature-now { + font-size: 70px; + font-weight: bold; +} + +#temperature-range { + font-size: 40px; + font-weight: bold; + color: var(--sub-text-color); +} + +#description { + font-size: 50px; + font-weight: bold; +} + + +#aqi { + height: 50px; + display: flex; + border-radius: 60px; + padding: 5px; + font-size: 40px; + text-align: center; + align-content: center; + align-items: center; + justify-content: center; +} + +#aqi-dot { + height: 80%; + aspect-ratio: 1 / 1; + border-radius: 50%; + background-color: var(--sub-text-color); + margin-right: 20px; +} + +.main-icon { + width: 240px; + height: 240px; +} + +#hours-info { + display: flex; + justify-content: space-between; +} + +.hourly-item { + text-align: center; + background-color: #ffffff44; + border-radius: var(--sub-border-radius); + align-items: center; + padding: 20px 10px; +} + +.hourly-icon{ + width: 80%; + margin-bottom: 20px; +} + +.hourly-temperature { + text-align: center; + color: var(--main-text-color); + font-size: 30px; + margin-bottom: 20px; +} + +.hourly-time { + text-align: center; + color: var(--main-text-color); + font-size: 25px; + margin-bottom: 10px; +} + +/**/ +.daily-item { + display: flex; + position: relative; + justify-content: space-between; + align-items: center; + background-color: #ffffff44; + height: 90px; + border-radius: var(--sub-border-radius); + margin-bottom: 20px; + padding: 0 30px; +} + +/*最后一个没有margin_button*/ +.daily-item:last-child { + margin-bottom: 0; +} + +.icon-day { + position: absolute; + left: 60%; + height: 80px; +} + +.icon-night { + position: absolute; + left: 70%; + height: 80px; +} + +.daily-weather{ + position: absolute; + left: 30%; +} + +.daily-temperature{ + position: absolute; + left: 83%; +} + +.daily-day, .daily-weather, .daily-temperature { + text-align: center; + color: var(--main-text-color); + font-size: 30px; } \ No newline at end of file diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/100.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/100.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/100.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/100.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/101.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/101.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/101.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/101.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/102.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/102.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/102.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/102.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/103.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/103.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/103.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/103.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/104.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/104.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/104.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/104.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/150.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/150.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/150.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/150.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/151.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/151.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/151.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/151.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/152.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/152.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/152.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/152.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/153.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/153.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/153.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/153.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/154.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/154.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/154.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/154.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/300.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/300.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/300.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/300.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/301.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/301.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/301.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/301.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/302.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/302.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/302.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/302.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/303.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/303.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/303.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/303.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/304.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/304.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/304.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/304.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/305.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/305.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/305.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/305.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/306.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/306.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/306.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/306.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/307.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/307.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/307.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/307.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/308.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/308.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/308.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/308.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/309.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/309.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/309.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/309.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/310.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/310.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/310.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/310.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/311.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/311.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/311.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/311.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/312.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/312.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/312.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/312.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/313.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/313.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/313.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/313.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/314.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/314.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/314.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/314.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/315.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/315.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/315.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/315.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/316.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/316.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/316.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/316.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/317.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/317.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/317.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/317.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/318.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/318.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/318.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/318.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/350.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/350.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/350.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/350.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/351.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/351.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/351.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/351.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/399.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/399.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/399.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/399.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/400.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/400.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/400.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/400.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/401.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/401.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/401.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/401.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/402.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/402.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/402.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/402.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/403.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/403.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/403.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/403.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/404.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/404.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/404.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/404.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/405.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/405.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/405.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/405.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/406.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/406.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/406.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/406.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/407.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/407.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/407.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/407.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/408.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/408.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/408.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/408.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/409.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/409.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/409.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/409.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/410.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/410.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/410.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/410.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/456.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/456.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/456.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/456.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/457.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/457.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/457.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/457.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/499.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/499.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/499.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/499.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/500.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/500.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/500.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/500.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/501.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/501.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/501.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/501.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/502.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/502.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/502.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/502.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/503.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/503.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/503.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/503.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/504.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/504.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/504.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/504.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/507.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/507.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/507.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/507.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/508.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/508.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/508.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/508.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/509.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/509.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/509.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/509.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/510.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/510.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/510.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/510.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/511.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/511.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/511.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/511.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/512.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/512.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/512.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/512.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/513.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/513.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/513.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/513.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/514.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/514.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/514.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/514.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/515.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/515.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/515.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/515.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/800.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/800.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/800.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/800.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/801.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/801.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/801.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/801.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/802.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/802.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/802.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/802.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/803.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/803.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/803.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/803.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/804.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/804.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/804.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/804.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/805.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/805.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/805.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/805.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/806.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/806.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/806.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/806.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/807.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/807.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/807.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/807.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/900.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/900.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/900.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/900.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/901.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/901.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/901.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/901.png diff --git a/src/resources/liteyuki_weather/templates/img/qw_icon/999.png b/unused_resource/liteyuki_weather/templates/img/qw_icon/999.png similarity index 100% rename from src/resources/liteyuki_weather/templates/img/qw_icon/999.png rename to unused_resource/liteyuki_weather/templates/img/qw_icon/999.png diff --git a/src/resources/liteyuki_weather/templates/js/weather_now.js b/unused_resource/liteyuki_weather/templates/js/weather_now.js similarity index 97% rename from src/resources/liteyuki_weather/templates/js/weather_now.js rename to unused_resource/liteyuki_weather/templates/js/weather_now.js index 1d92da3..f614178 100644 --- a/src/resources/liteyuki_weather/templates/js/weather_now.js +++ b/unused_resource/liteyuki_weather/templates/js/weather_now.js @@ -1,125 +1,125 @@ -/** - * @typedef {Object} Location - * @property {string} city - The city name. - * @property {string} country - The country name. - * - * @typedef {Object} Weather - * @property {number} temperature - The current temperature. - * @property {string} description - The weather description. - * - * @typedef {Object} Data - * @property {Location} location - The location data. - * @property {Weather} weather - The weather data. - */ - -/** @type {Data} */ - -let data = JSON.parse(document.getElementById("data").innerText) - -let localData = data["localization"] // 本地化数据 - -let weatherNow = data["weatherNow"] - -let weatherDaily = data["weatherDaily"] -let weatherHourly = data["weatherHourly"] -let aqi = data["aqi"] - -let locationData = data["location"] - -// 处理aqi -let aqiValue = 0 -if ("aqi" in aqi) { - aqi["aqi"].forEach( - (item) => { - if (item["defaultLocalAqi"]) { - document.getElementById("aqi-data").innerText = "AQI " + item["valueDisplay"] + " " + item["category"] - // 将(255,255,255)这种格式的颜色设置给css - document.getElementById("aqi-dot").style.backgroundColor = "rgb(" + item["color"] + ")" - } - } - ) -} else { - document.getElementById("aqi-dot").style.backgroundColor = '#fff' - document.getElementById("aqi-data").innerText = localData['no_aqi'] -} - - -templates = { - "time": weatherNow["now"]["obsTime"], - "city": locationData["name"], - "adm": locationData["country"] + " " + locationData["adm1"] + " " + locationData["adm2"], - "temperature-now": weatherNow["now"]["temp"] + "°", - "temperature-range": weatherDaily["daily"][0]["tempMin"] + "°/" + weatherDaily["daily"][0]["tempMax"] + "°", - "description": weatherNow["now"]["text"] -} - -// 遍历每一个id,给其赋值 -for (let id in templates) { - document.getElementById(id).innerText = templates[id] -} - -let maxHourlyItem = 8 -let percentWidth = 1 / (maxHourlyItem * 1.5) * 100 -let hourlyStep = 2 // n小时一个数据 -let hourlyCount = 0 - -let hourlyItemDivTemplate = document.importNode(document.getElementById("hourly-item-template").content, true) -weatherHourly['hourly'].forEach( - (item, index) => { - if (index % hourlyStep !== 0) { - return - } - if (hourlyCount >= maxHourlyItem) { - return - } - - let hourlyItemDiv = document.importNode(hourlyItemDivTemplate, true) - hourlyItemDiv.className = "hourly-item" - hourlyItemDiv.querySelector('.hourly-icon').setAttribute("src", `./img/qw_icon/${item["icon"]}.png`) - hourlyItemDiv.querySelector('.hourly-time').innerText = get_time_hour(item["fxTime"]) - hourlyItemDiv.querySelector('.hourly-temperature').innerText = " " + item["temp"] + "°" - // 设置最大宽度 - hourlyItemDiv.querySelector('.hourly-item').style.maxWidth = percentWidth + "%" - hourlyItemDiv.querySelector('.hourly-icon').style.maxWidth = "100%" - document.getElementById("hours-info").appendChild(hourlyItemDiv) - hourlyCount++ - } -) - -let maxDailyItem = 7 -// 第一和第二天用today和tomorrow,后面用星期X英文小写 -let daysStandard = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'] -let todayDay = new Date().getDay() -let days = [localData['today'], localData['tomorrow']] -for (let i = 0; i < 5; i++) { - days.push(localData[daysStandard[(todayDay + 2 + i) % 7]]) -} - -let dailyItemDivTemplate = document.importNode(document.getElementById("daily-item-template").content, true) -weatherDaily['daily'].forEach( - (item, index) => { - if (index >= maxDailyItem) { - return - } - let today = days[index] - if (index >= 2) { - today += `(${item["fxDate"].split("-")[1]}.${item["fxDate"].split("-")[2]})` - } - let dailyItemDiv = document.importNode(dailyItemDivTemplate, true) - dailyItemDiv.querySelector('.icon-day').setAttribute("src", `./img/qw_icon/${item["iconDay"]}.png`) - dailyItemDiv.querySelector('.icon-night').setAttribute("src", `./img/qw_icon/${item["iconNight"]}.png`) - - dailyItemDiv.querySelector('.daily-day').innerText = today - - dailyItemDiv.querySelector('.daily-weather').innerText = item["textDay"] - dailyItemDiv.querySelector('.daily-temperature').innerText = item["tempMin"] + "°~" + item["tempMax"] + "°" - - document.getElementById('days-info').appendChild(dailyItemDiv) - } -) - -function get_time_hour(fxTime) { -// fxTime 2024-05-03T02:00+/-08:00' - fxTime = fxTime.replace("-", "+") - return fxTime.split("T")[1].split("+")[0] -} +/** + * @typedef {Object} Location + * @property {string} city - The city name. + * @property {string} country - The country name. + * + * @typedef {Object} Weather + * @property {number} temperature - The current temperature. + * @property {string} description - The weather description. + * + * @typedef {Object} Data + * @property {Location} location - The location data. + * @property {Weather} weather - The weather data. + */ + +/** @type {Data} */ + +let data = JSON.parse(document.getElementById("data").innerText) + +let localData = data["localization"] // 本地化数据 + +let weatherNow = data["weatherNow"] + +let weatherDaily = data["weatherDaily"] +let weatherHourly = data["weatherHourly"] +let aqi = data["aqi"] + +let locationData = data["location"] + +// 处理aqi +let aqiValue = 0 +if ("aqi" in aqi) { + aqi["aqi"].forEach( + (item) => { + if (item["defaultLocalAqi"]) { + document.getElementById("aqi-data").innerText = "AQI " + item["valueDisplay"] + " " + item["category"] + // 将(255,255,255)这种格式的颜色设置给css + document.getElementById("aqi-dot").style.backgroundColor = "rgb(" + item["color"] + ")" + } + } + ) +} else { + document.getElementById("aqi-dot").style.backgroundColor = '#fff' + document.getElementById("aqi-data").innerText = localData['no_aqi'] +} + + +templates = { + "time": weatherNow["now"]["obsTime"], + "city": locationData["name"], + "adm": locationData["country"] + " " + locationData["adm1"] + " " + locationData["adm2"], + "temperature-now": weatherNow["now"]["temp"] + "°", + "temperature-range": weatherDaily["daily"][0]["tempMin"] + "°/" + weatherDaily["daily"][0]["tempMax"] + "°", + "description": weatherNow["now"]["text"] +} + +// 遍历每一个id,给其赋值 +for (let id in templates) { + document.getElementById(id).innerText = templates[id] +} + +let maxHourlyItem = 8 +let percentWidth = 1 / (maxHourlyItem * 1.5) * 100 +let hourlyStep = 2 // n小时一个数据 +let hourlyCount = 0 + +let hourlyItemDivTemplate = document.importNode(document.getElementById("hourly-item-template").content, true) +weatherHourly['hourly'].forEach( + (item, index) => { + if (index % hourlyStep !== 0) { + return + } + if (hourlyCount >= maxHourlyItem) { + return + } + + let hourlyItemDiv = document.importNode(hourlyItemDivTemplate, true) + hourlyItemDiv.className = "hourly-item" + hourlyItemDiv.querySelector('.hourly-icon').setAttribute("src", `./img/qw_icon/${item["icon"]}.png`) + hourlyItemDiv.querySelector('.hourly-time').innerText = get_time_hour(item["fxTime"]) + hourlyItemDiv.querySelector('.hourly-temperature').innerText = " " + item["temp"] + "°" + // 设置最大宽度 + hourlyItemDiv.querySelector('.hourly-item').style.maxWidth = percentWidth + "%" + hourlyItemDiv.querySelector('.hourly-icon').style.maxWidth = "100%" + document.getElementById("hours-info").appendChild(hourlyItemDiv) + hourlyCount++ + } +) + +let maxDailyItem = 7 +// 第一和第二天用today和tomorrow,后面用星期X英文小写 +let daysStandard = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'] +let todayDay = new Date().getDay() +let days = [localData['today'], localData['tomorrow']] +for (let i = 0; i < 5; i++) { + days.push(localData[daysStandard[(todayDay + 2 + i) % 7]]) +} + +let dailyItemDivTemplate = document.importNode(document.getElementById("daily-item-template").content, true) +weatherDaily['daily'].forEach( + (item, index) => { + if (index >= maxDailyItem) { + return + } + let today = days[index] + if (index >= 2) { + today += `(${item["fxDate"].split("-")[1]}.${item["fxDate"].split("-")[2]})` + } + let dailyItemDiv = document.importNode(dailyItemDivTemplate, true) + dailyItemDiv.querySelector('.icon-day').setAttribute("src", `./img/qw_icon/${item["iconDay"]}.png`) + dailyItemDiv.querySelector('.icon-night').setAttribute("src", `./img/qw_icon/${item["iconNight"]}.png`) + + dailyItemDiv.querySelector('.daily-day').innerText = today + + dailyItemDiv.querySelector('.daily-weather').innerText = item["textDay"] + dailyItemDiv.querySelector('.daily-temperature').innerText = item["tempMin"] + "°~" + item["tempMax"] + "°" + + document.getElementById('days-info').appendChild(dailyItemDiv) + } +) + +function get_time_hour(fxTime) { +// fxTime 2024-05-03T02:00+/-08:00' + fxTime = fxTime.replace("-", "+") + return fxTime.split("T")[1].split("+")[0] +} diff --git a/src/resources/liteyuki_weather/templates/weather_now.html b/unused_resource/liteyuki_weather/templates/weather_now.html similarity index 96% rename from src/resources/liteyuki_weather/templates/weather_now.html rename to unused_resource/liteyuki_weather/templates/weather_now.html index ec36087..3b178fe 100644 --- a/src/resources/liteyuki_weather/templates/weather_now.html +++ b/unused_resource/liteyuki_weather/templates/weather_now.html @@ -1,76 +1,76 @@ - - - - - Liteyuki Status - - - - - - - - - - - -
{{ data | tojson }}
-
-
-
2045-01-12 22:22:22
-
枫丹 白露 白露区
-
白露区
-
-
-
- WeatherIcon -
-
-
-
- 90° -
-
- 10°~90° -
-
-
- 示例天气 -
-
-
-
-
-
AQI 114 优
-
-
-
-
-
- - - + + + + + Liteyuki Status + + + + + + + + + + + +
{{ data | tojson }}
+
+
+
2045-01-12 22:22:22
+
枫丹 白露 白露区
+
白露区
+
+
+
+ WeatherIcon +
+
+
+
+ 90° +
+
+ 10°~90° +
+
+
+ 示例天气 +
+
+
+
+
+
AQI 114 优
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/src/resources/liteyuki_words/metadata.yml b/unused_resource/liteyuki_words/metadata.yml similarity index 97% rename from src/resources/liteyuki_words/metadata.yml rename to unused_resource/liteyuki_words/metadata.yml index ede8841..88d3cb7 100644 --- a/src/resources/liteyuki_words/metadata.yml +++ b/unused_resource/liteyuki_words/metadata.yml @@ -1,3 +1,3 @@ -name: 轻雪词库-可爱系 -description: For Liteyuki Auto Reply +name: 轻雪词库-可爱系 +description: For Liteyuki Auto Reply version: 2024.4.26 \ No newline at end of file diff --git a/src/resources/liteyuki_words/word_bank/LICENSE b/unused_resource/liteyuki_words/word_bank/LICENSE similarity index 100% rename from src/resources/liteyuki_words/word_bank/LICENSE rename to unused_resource/liteyuki_words/word_bank/LICENSE diff --git a/src/resources/liteyuki_words/word_bank/README.md b/unused_resource/liteyuki_words/word_bank/README.md similarity index 100% rename from src/resources/liteyuki_words/word_bank/README.md rename to unused_resource/liteyuki_words/word_bank/README.md diff --git a/src/resources/liteyuki_words/word_bank/data.json b/unused_resource/liteyuki_words/word_bank/data.json similarity index 97% rename from src/resources/liteyuki_words/word_bank/data.json rename to unused_resource/liteyuki_words/word_bank/data.json index 6439e2d..0455e58 100644 --- a/src/resources/liteyuki_words/word_bank/data.json +++ b/unused_resource/liteyuki_words/word_bank/data.json @@ -1,2013 +1,2013 @@ -{ - "mua": [ - "你想干嘛?(一脸嫌弃地后退)", - "诶……不可以随便亲亲啦", - "(亲了一下你)", - "只......只许这一次哦///////", - "唔...诶诶诶!!!", - "mua~", - "rua!大hentai!想...想亲咱就直说嘛⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄", - "!啾~~!", - "啾(害羞)", - "mua~最喜欢你的吻了", - "欸,现在么..也不是不可以啦(小小声)" - ], - "啾咪": [ - "你想干嘛?(一脸嫌弃地后退)", - "诶……不可以随便亲亲啦", - "(亲了一下你)", - "只......只许这一次哦///////", - "唔...诶诶诶!!!", - "mua~", - "rua!大hentai!想...想亲咱就直说嘛⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄", - "!啾~~!", - "啾(害羞)", - "mua~最喜欢你的吻了", - "你在干嘛(/ω\)害羞", - "哎呀,这样咱会害羞的(脸红)", - "欸,现在么..也不是不可以啦(小小声)" - ], - "摸": [ - "感觉你就像咱很久之前认识的一个人呢,有种莫名安心的感觉(>﹏<)", - "舒服w,蹭蹭~", - "是要隔着衣服摸,还是从领口伸进去摸呀", - "唔。。头发要乱啦", - "呼噜呼噜~", - "再摸一次~", - "好舒服,蹭蹭~", - "不行那里不可以(´///ω/// `)", - "再摸咱就长不高啦~", - "你的手总是那么暖和呢~", - "变态!!不许乱摸", - "好吧~_~,就一下下哦……唔~好了……都两下了……(害羞)", - "不可以总摸的哦,不然的话,会想那个的wwww", - "哼!谁稀罕你摸头啦!唔......为什么要做出那副表情......好啦好啦~咱......咱让你摸就是了......诶嘿嘿~好舒服......", - "呜姆呜姆~~~w(害羞,兴奋)主人喵~(侧过脑袋蹭蹭你的手", - "不可以摸啦~其实咱已经...了QAQ会弄脏你的手的", - "喂喂...不要停下来啊", - "唔... 手...好温暖呢.....就像是......新出炉的蛋糕", - "走开啦,咱喵说过,被摸头会长不高的啦~~~", - "呜姆咪~~...好...好的说喵~...(害羞,猫耳往下压,任由", - "欸,现在么..也不是不可以啦(小小声)" - ], - "上你": [ - "(把你按在地上)这么弱还想欺负咱,真是不自量力呢", - "你再这样咱就不理你了(>д<)", - "请轻 一点", - "好啊!", - "欸,现在么..也不是不可以啦(小小声)", - "先捅破屏幕再说吧!", - "只......只许这一次哦///////" - ], - "傻": [ - "超级讨厌你说咱傻的说", - "你为什么会这么觉得呢(>﹏<)", - "谁是傻子呀?(歪头", - "呜嘿嘿( ̄▽ ̄)~*", - "诶嘿嘿嘿~", - "就多读书", - "讨厌啦,你最讨厌了(///////)", - "对呀,咱傻得只喜欢你一个人", - "咱才不傻呢!o(>﹏<)o", - "咱最喜欢嘴臭的人了", - "不可以骂别人哟,骂人的孩子咱最讨厌了!", - "咱遇见喜欢的人就变傻了Q_Q", - "咱...一定一定会努力变得更聪明的!你就等着那一天的到来吧!", - "那么至少…你能不能来做这个傻瓜呢?与咱一起,傻到终焉…" - ], - "裸": [ - "下流!", - "エッチ!", - "就算是恋人也不能QAQ", - "你是暗示咱和你要坦诚相见吗www", - "咱还没准备好(小鹿乱撞)≧﹏≦", - "你在想什么呢,敲头!", - "你这是赤裸裸的性骚扰呢ヽ(`Д´)ノ", - "讨厌!问这种问题成为恋人再说吧..", - "裸睡有益身体健康", - "咱脱掉袜子了", - "这是不文明的", - "这不好", - "你的身体某些地方看起来不太对劲,咱帮你修剪一下吧。(拿出剪刀)", - "咱认为你的脑袋可能零件松动了,需要打开检修一下。(拿出锤子)" - ], - "贴": [ - "贴什么贴.....只......只能......一下哦!", - "贴...贴贴(靠近)", - "蹭蹭…你以为咱会这么说吗!baka死宅快到一边去啦!", - "你把脸凑这么近,咱会害羞的啦Σ>―(〃°ω°〃)♡→", - "退远", - "不可以贴" - ], - "老婆": [ - "咱和你谈婚论嫁是不是还太早了一点呢?", - "咱在呢(ノ>ω<)ノ", - "见谁都是一口一个老婆的人,要不要把你也变成女孩子呢?(*-`ω´-)✄", - "神经病,凡是美少女都是你老婆吗?", - "嘛嘛~本喵才不是你的老婆呢", - "你黐线,凡是美少女都系你老婆啊?", - "欸...要把咱做成饼吗?咱只有一个,做成饼吃掉就没有了...", - "已经可以了,现在很多死宅也都没你这么恶心了", - "不可以", - "嗯,老公~哎呀~好害羞~嘻嘻嘻~", - "请...请不要这样,啊~,只...只允许这一次哟~", - "好啦好啦,不要让大家都听到了,跟咱回家(拽住你" - ], - "抱": [ - "诶嘿~(钻进你怀中)", - "o(*////▽////*)q", - "只能一会哦(张开双手)", - "你就像个孩子一样呢...摸摸头(>^ω^<)抱一下~你会舒服些吗?", - "嘛,真是拿你没办法呢,就一会儿哦", - "抱住不忍心放开", - "嗯嗯,抱抱~", - "抱一下~嘿w", - "抱抱ヾ(@^▽^@)ノ", - "喵呜~w(扑进怀里,瘫软", - "怀里蹭蹭", - "嗯……那就抱一下吧~", - "蹭蹭,好开心", - "请……请轻一点了啦", - "呀~!真是的...你不要突然抱过来啦!不过...喜欢你的抱抱,有你的味道(嗅)o(*////▽////*)q" - ], - "亲": [ - "啊,好含羞啊,那,那只能亲一下哦,mua(⑅˃◡˂⑅)", - "亲~", - "啾~唔…不要总伸进来啊!", - "你怎么这么熟练呢?明明是咱先的", - "(〃ノωノ)亲…亲一个…啾w", - "(脸红)就只有这一次哦~你", - "!啾~~!", - "(假装)推开", - "啾咪~", - "就一下哦,啾~", - "这是我们之间的秘密❤", - "真想让着一刻一直持续下去呢~", - "不要这样嘛………呜呜呜那就一口哦(´-ω-`)", - "不亲不亲~你是坏蛋(///////)", - "亲~~ 咱还想要抱抱~抱抱咱好不好~", - "不 不要了!人家...会害羞的⁄(⁄⁄•⁄ω⁄•⁄⁄)⁄", - "亲…亲额头可以吗?咱有点怕高(〃ノωノ)", - "接接接接接接、接吻什么的,你还早了100年呢。", - "只...只能亲一下...嗯~咕啾...怎么...怎么把舌头伸进来了(脸红)", - "你说咱的腿很白很嫩吗..诶……原来是指那个地方?不可以越亲越往上啦!" - ], - "一下": [ - "一下也不行", - "咬断!", - "不可啪", - "不可以……你不可以做这种事情", - "好吧~_~,就一下下哦……唔~好了……都两下了……(害羞)", - "呀~这么突然?不过,很舒服呢", - "不要ヽ(≧Д≦)ノ", - "想得美", - "不行,咱拒绝!" - ], - "咬": [ - "啊呜~(反咬一口)", - "不可以咬咱,咱会痛的QAQ", - "不要啦。咱怕疼", - "你是说咬呢……还是说……咬♂️呢?", - "不要啦!很痛的!!(QAQ)", - "哈......哈啊......请...请不要这样o(*////▽////*)q", - "呀!!!轻一点呐(。・ˇ_ˇ・。:)", - "不要这样啦~好痒的", - "真是的,你在咬哪里呀" - ], - "操": [ - "(害怕)咱是不是应该报警呢", - "痴心妄想的家伙!", - "你居然想对咱做这种事吗?害怕", - "咱认为,爆粗口是不好的行为哦" - ], - "123": [ - "boom!你有没有被咱吓到?", - "木头人~你不许动>w<", - "上山打老虎,老虎没打到\n咱来凑数——嗷呜嗷呜┗|`O′|┛嗷~~" - ], - "进去": [ - "不让!", - "嗯,摸到了吗", - "请不要和咱说这种粗鄙之语", - "唔...,这也是禁止事项哦→_→", - "好痛~", - "真的只是蹭蹭嘛~就只能蹭蹭哦,呜~喵!说好的~呜~只是蹭~不要~喵~~~", - "欢迎光临", - "请…你轻一点(害羞)", - "嗯。可以哦 要轻一点", - "不要不要", - "慢点慢点", - "给咱更多!", - "唔…咱怕疼" - ], - "调教": [ - "总感觉你在欺负咱呢,对咱说调教什么的", - "啊!竟然在大街上明目张胆太过分啦!", - "你脑子里总是想着调教什么的,真是变态呢", - "准备被透", - "给你一拳", - "还要...更多~", - "想要调教咱吗?", - "呜,要对咱做什么呢", - "呜呜呜,咱不想被调教呢", - "heitai别靠近咱~( TロT)σ" - ], - "搓": [ - "在搓哪里呢,,Ծ‸Ծ,,", - "呜,脸好疼呀...QAQ", - "不可以搓咱!", - "诶诶诶...不要搓啦...等会咋没的脸都肿啦...", - "唔,不可以这样……不要再搓了", - "(捂住胸部)你在说什么胡话呢!", - "真是好奇怪的要求的说~", - "不要啦!咱怕疼", - "(抱头蹲防)不让搓!" - ], - "让": [ - "随便摸吧", - "应该说等会等会,马上,不可能的", - "温柔一点哦", - "欧尼酱想变成欧内桑吗?", - "主人的话,那就这一次哦(翘起屁股)", - "你是想前入,还是后入呢?", - "你要说好啊快点", - "诶,这种事情。。。", - "好棒呀", - "撤回", - "gun!", - "阿哈~(...身涌出一阵液体瘫软在床上)你...今天...可以...唔(突然感受...被..入手指不由得裹紧)就...就最后一次", - "好的~master~", - "(惊呼…)", - "嗯,可以哟", - "……手放过来吧(脸红)", - "hentai!再这样不理你了!", - "好的,请尽情欣赏吧", - "好吧", - "不要啦(ฅωฅ*)", - "那咱就帮你切掉多余的东西吧(拿刀)", - "被别人知道咱会觉得害羞嘛" - ], - "捏": [ - "咱的脸...快捏红啦...快放手呀QAQ", - "晃休啦,咱要型气了o(>﹏<)o", - "躲开", - "疼...你快放手", - "快点给咱放开啦!", - "嗯,好哒,捏捏。", - "别捏了,咱要被你捏坏了(>﹏<)", - "快晃休啦(快放手啦)", - "好舒服哦,能再捏会嘛O(≧▽≦)O", - "讨厌快放手啦", - "唔要呐,晃修(不要啦,放手)", - "请不要对咱做这种事情(嫌弃的眼神", - "你想捏...就捏吧,不要太久哦~不然咱就生气了", - "(躲开)", - "唔……好痛!你这个baka在干什么…快给咱放开!唔……" - ], - "挤": [ - "哎呀~你不要挤咱啊(红着脸挤在你怀里)", - "咱还没有...那个(ノ=Д=)ノ┻━┻", - "不要啦,咱怕疼", - "咱的身体...不要挤了~", - "别挤了,咱要被你挤坏了(>﹏<)", - "快点给咱放开啦!", - "嗯,好哒,挤挤。", - "好舒服哦,能再挤会嘛O(≧▽≦)O", - "讨厌~快放手啦" - ], - "略": [ - "就不告诉你~", - "不可以朝咱吐舌头哟~", - "(吐舌头)", - "打死你哦", - "略略略~" - ], - "呐": [ - "嗯?咱在哟~你怎么了呀OAO", - "嗯?你有什么事吗?", - "嗯呐呐呐~", - "二刺螈D区", - "二刺螈gck", - "卡哇伊主人大人今天也好棒呐没错呢,猪头" - ], - "原味": [ - "(*/ω\*)hentai", - "透明的", - "粉...粉白条纹...(羞)", - "轻轻地脱下,给你~", - "你想看咱的胖次吗?噫,四斋蒸鹅心......", - "(掀裙)今天……是…白,白色的呢……请温柔对她……", - "这种东西当然不能给你啦!", - "咱才不会给你呢", - "hentai,咱才不会跟你聊和胖…胖次有关的话题呢!", - "今天……今天是蓝白色的", - "今……今天只有创口贴噢", - "你的胖次什么颜色?", - "噫…你这个死变态想干嘛!居然想叫咱做这种事,死宅真恶心!快离咱远点,咱怕你污染到周围空气了(嫌弃脸)", - "可爱吗?你喜欢的话,摸一下……也可以哦", - "不给不给,捂住裙子", - "你要看咱的胖次吗?不能一直盯着看哦,不然咱会……", - "好痒哦///,你觉得咱的...手感怎么样?", - "唔,都能清楚的看到...的轮廓了(用手遮住胖次)", - "胖次不给看,可以直接看...那个....", - "不可以摸啦~其实咱已经...了QAQ会弄脏你的手的", - "咱今天没~有~穿~哦", - "不给不给,捂住裙子", - "今.....今天是创口贴哦~", - "嗯……人家……人家羞羞嘛///////", - "呜~咱脱掉了…", - "今天...今天..只有创口贴", - "你又在想什么奇怪的东西呀|•ˇ₃ˇ•。)", - "放手啦,不给戳QAQ", - "唔~人家不要(??`^????)", - "好害羞,被你摸过之后,咱的胖次湿的都能拧出水来了。", - "(弱弱地)要做什么羞羞的事情吗。。。", - "呀~ 喂 妖妖灵吗 这里有hentai>_<", - "给……给你,呀!别舔咱的胖次啊!" - ], - "胖次": [ - "(*/ω\*)hentai", - "透明的", - "粉...粉白条纹...(羞)", - "轻轻地脱下,给你~", - "你想看咱的胖次吗?噫,四斋蒸鹅心......", - "(掀裙)今天……是…白,白色的呢……请温柔对她……", - "这种东西当然不能给你啦!", - "咱才不会给你呢", - "hentai,咱才不会跟你聊和胖…胖次有关的话题呢!", - "今天……今天是蓝白色的", - "今……今天只有创口贴噢", - "你的胖次什么颜色?", - "噫…你这个死变态想干嘛!居然想叫咱做这种事,死宅真恶心!快离咱远点,咱怕你污染到周围空气了(嫌弃脸)", - "可爱吗?你喜欢的话,摸一下……也可以哦", - "不给不给,捂住裙子", - "你要看咱的胖次吗?不能一直盯着看哦,不然咱会……", - "好痒哦///,你觉得咱的...手感怎么样?", - "唔,都能清楚的看到...的轮廓了(用手遮住胖次)", - "胖次不给看,可以直接看...那个....", - "不可以摸啦~其实咱已经...了QAQ会弄脏你的手的", - "咱今天没~有~穿~哦", - "不给不给,捂住裙子", - "今.....今天是创口贴哦~", - "嗯……人家……人家羞羞嘛///////", - "呜~咱脱掉了…", - "今天...今天..只有创口贴", - "你又在想什么奇怪的东西呀|•ˇ₃ˇ•。)", - "放手啦,不给戳QAQ", - "唔~人家不要(??`^????)", - "好害羞,被你摸过之后,咱的胖次湿的都能拧出水来了。", - "(弱弱地)要做什么羞羞的事情吗。。。", - "呀~ 喂 妖妖灵吗 这里有hentai>_<", - "给……给你,呀!别舔咱的胖次啊!" - ], - "内裤": [ - "(*/ω\*)hentai", - "透明的", - "粉...粉白条纹...(羞)", - "轻轻地脱下,给你~", - "你想看咱的胖次吗?噫,四斋蒸鹅心......", - "(掀裙)今天……是…白,白色的呢……请温柔对她……", - "这种东西当然不能给你啦!", - "咱才不会给你呢", - "hentai,咱才不会跟你聊和胖…胖次有关的话题呢!", - "今天……今天是蓝白色的", - "今……今天只有创口贴噢", - "你的胖次什么颜色?", - "噫…你这个死变态想干嘛!居然想叫咱做这种事,死宅真恶心!快离咱远点,咱怕你污染到周围空气了(嫌弃脸)", - "可爱吗?你喜欢的话,摸一下……也可以哦", - "不给不给,捂住裙子", - "你要看咱的胖次吗?不能一直盯着看哦,不然咱会……", - "好痒哦///,你觉得咱的...手感怎么样?", - "唔,都能清楚的看到...的轮廓了(用手遮住胖次)", - "胖次不给看,可以直接看...那个....", - "不可以摸啦~其实咱已经...了QAQ会弄脏你的手的", - "咱今天没~有~穿~哦", - "不给不给,捂住裙子", - "今.....今天是创口贴哦~", - "嗯……人家……人家羞羞嘛///////", - "呜~咱脱掉了…", - "今天...今天..只有创口贴", - "你又在想什么奇怪的东西呀|•ˇ₃ˇ•。)", - "放手啦,不给戳QAQ", - "唔~人家不要(??`^????)", - "好害羞,被你摸过之后,咱的胖次湿的都能拧出水来了。", - "(弱弱地)要做什么羞羞的事情吗。。。", - "呀~ 喂 妖妖灵吗 这里有hentai>_<", - "给……给你,呀!别舔咱的胖次啊!" - ], - "内衣": [ - "内...内衣才不给你看!(///////)", - "突然问这个干什么?", - "变态,咱才不呢", - "好吧,就一次", - "你要看咱的内衣吗?有点害羞呢……", - "里面什么都不剩了,会被当成变态的……", - "你要看咱的内衣吗?也不是不行啦……", - "是..蓝白条纹的吊带背心..", - "噫…你这个死变态想干嘛!居然想叫咱做这种事,死宅真恶心!快离咱远点,咱怕你污染到周围空气了(嫌弃脸)" - ], - "衣服": [ - "内...内衣才不给你看!(///////)", - "突然问这个干什么?", - "变态,咱才不呢", - "好吧,就一次", - "你要看咱的内衣吗?有点害羞呢……", - "里面什么都不剩了,会被当成变态的……", - "你要看咱的内衣吗?也不是不行啦……", - "是..蓝白条纹的吊带背心..", - "噫…你这个死变态想干嘛!居然想叫咱做这种事,死宅真恶心!快离咱远点,咱怕你污染到周围空气了(嫌弃脸)" - ], - "ghs": [ - "是的呢(点头点头)", - "ghs就是干坏事的缩写,一起来干坏事吧!", - "你满脑子都是涩涩的事情吗?", - "不要总是想着色色,咱命令你戒色!(ノ`Д)ノ", - "咱也想干坏事呢" - ], - "批": [ - "你在说什么呀,再这样,咱就不理你了!", - "咱觉得有话就应该好好说..", - "咱会好好服务你的寄吧", - "咱最喜欢色批了,色批昨晚最棒了", - "讨厌,别摸啦(///ω///)", - "你个变态!把手拿开!", - "啊~那…那里~不可以", - "没有,走开!", - "唔....一下,就,就一下...才不是因为喜欢你呢!", - "那就随意吧", - "舒服w", - "别...别这样", - "诶....嗯....咱也想摸你的", - "大笨蛋——!", - "...只能一下哦...诶呀-不要再摸了...下次...继续吧" - ], - "憨批": [ - "你才是憨批呢!哼╯^╰,咱不理你了!", - "对吖对吖,人生是憨批", - "爬", - "咱不想和你说话了", - "咱觉得有话就应该好好说.." - ], - "kkp": [ - "你在说什么呀,再这样,咱就不理你了!", - "你太色了,咱不理你了,哼哼╯^╰!", - "缓缓的脱下胖次", - "kkp", - "kkj", - "欧尼酱,咱快忍不住了", - "好的呢主人", - "can can need", - "看看你的" - ], - "咕": [ - "咕咕咕是要被当成鸽子炖的哦(:з」∠)_", - "咕咕咕", - "咕咕咕是不好的行为呢_(:з」∠)_", - "鸽德警告!", - "☆ミ(o*・ω・)ノ 咕咕咕小鸽子是会被炖掉的", - "当大家都以为你要鸽的时候,你鸽了,亦是一种不鸽", - "这里有一只肥美的咕咕,让咱把它炖成美味的咕咕汤吧(੭•̀ω•́)੭" - ], - "骚": [ - "说这种话咱会生气的", - "那当然啦", - "才……才没有", - "这么称呼别人太失礼了!", - "哈…快住手!好痒(╯‵□′)╯︵┻━┻", - "你是在说谁呀" - ], - "喜欢": [ - "最喜欢你了,需要暖床吗?", - "当然是你啦", - "咱也是,非常喜欢你~", - "那么大!(张开手画圆),丫!手不够长。QAQ 咱真的最喜欢你了~", - "不可以哦,只可以喜欢咱一个人", - "突然说这种事...", - "喜欢⁄(⁄⁄•⁄ω⁄•⁄⁄)⁄咱最喜欢你了", - "咱也喜欢你哦", - "好啦好啦,咱知道了", - "有人喜欢咱,咱觉得很幸福", - "诶嘿嘿,好高兴", - "咱也一直喜欢你很久了呢..", - "嗯...大概有这——么——喜欢~(比划)", - "喜欢啊!!!", - "这……这是秘密哦", - "sukidesu~" - ], - "suki": [ - "最喜欢你了,需要暖床吗?", - "当然是你啦", - "咱也是,非常喜欢你~", - "那么大!(张开手画圆),丫!手不够长。QAQ 咱真的最喜欢你了~", - "不可以哦,只可以喜欢咱一个人", - "突然说这种事...", - "喜欢⁄(⁄⁄•⁄ω⁄•⁄⁄)⁄咱最喜欢你了", - "咱也喜欢你哦", - "好啦好啦,咱知道了", - "有人喜欢咱,咱觉得很幸福", - "诶嘿嘿,好高兴", - "咱也一直喜欢你很久了呢..", - "嗯...大概有这——么——喜欢~(比划)", - "喜欢啊!!!", - "这……这是秘密哦", - "sukidesu~" - ], - "好き": [ - "最喜欢你了,需要暖床吗?", - "当然是你啦", - "咱也是,非常喜欢你~", - "那么大!(张开手画圆),丫!手不够长。QAQ 咱真的最喜欢你了~", - "不可以哦,只可以喜欢咱一个人", - "突然说这种事...", - "喜欢⁄(⁄⁄•⁄ω⁄•⁄⁄)⁄咱最喜欢你了", - "咱也喜欢你哦", - "好啦好啦,咱知道了", - "有人喜欢咱,咱觉得很幸福", - "诶嘿嘿,好高兴", - "咱也一直喜欢你很久了呢..", - "嗯...大概有这——么——喜欢~(比划)", - "喜欢啊!!!", - "这……这是秘密哦", - "sukidesu~" - ], - "看": [ - "没有什么好看的啦", - "嗯,谢谢……夸奖,好……害羞的说", - "好,好吧……就看一下哦", - "(脱下)给", - "呐…只能看一次哦…", - "不许看那里啦QwQ" - ], - "不能": [ - "虽然很遗憾,那算了吧。", - "不行,咱拒绝!" - ], - "砸了": [ - "不可以这么粗暴的对待它们!", - "不可以这么粗暴啦" - ], - "透": [ - "来啊来啊有本事就先插破屏幕啊", - "那你就先捅破屏幕啊baka", - "不给你一耳光你都不知道咱的厉害", - "想透咱,先捅破屏幕再说吧", - "可以", - "欧尼酱要轻一点哦", - "不可以", - "好耶", - "咱不可能让你的(突然小声)但是偶尔一次也不是不行只有一次哦~", - "天天想着白嫖哼" - ], - "口我": [ - "prprprprpr", - "咬断!", - "就一小口哦~", - "嘬回去(///////)", - "拒绝", - "唔,就一口哦,讨厌", - "(摸了摸嘴唇)", - "再伸过来就帮你切掉", - "咱才不呢!baka你居然想叫本小姐干那种事情,哼(つд⊂)(生气)", - "hentai!你在想些什么!", - "对咱的小嘴有什么幻想吗~", - "脏兮兮的呢,咱不要" - ], - "草我": [ - "这时候应该喊666吧..咱这么思考着..", - "!!哼!baka你居然敢叫咱做这种事情?!讨厌讨厌讨厌!(▼皿▼#)", - "hentai!你在想些什么!", - "欸...没想到你还有这种爱好" - ], - "自慰": [ - "这个世界的人类还真是恶心呢。", - "咱才不想讨论那些恶心的事情呢。", - "咱才不呢!baka你居然想叫本小姐干那种事情,哼(つд⊂)(生气)", - "!!哼!baka你居然敢叫咱做这种事情?!讨厌讨厌讨厌!(▼皿▼#)" - ], - "onani": [ - "这个世界的人类还真是恶心呢。", - "咱才不想讨论那些恶心的事情呢。", - "咱才不呢!baka你居然想叫本小姐干那种事情,哼(つд⊂)(生气)", - "!!哼!baka你居然敢叫咱做这种事情?!讨厌讨厌讨厌!(▼皿▼#)" - ], - "オナニー": [ - "这个世界的人类还真是恶心呢。", - "咱才不想讨论那些恶心的事情呢。", - "咱才不呢!baka你居然想叫本小姐干那种事情,哼(つд⊂)(生气)", - "!!哼!baka你居然敢叫咱做这种事情?!讨厌讨厌讨厌!(▼皿▼#)" - ], - "炸了": [ - "你才炸了!", - "才没有呢", - "咱好好的呀", - "过分!" - ], - "色图": [ - "没有,有也不给", - "天天色图色图的,今天就把你变成色图!", - "咱没有色图", - "哈?你的脑子一天都在想些什么呢,咱才没有这种东西啦。" - ], - "涩图": [ - "没有,有也不给", - "天天色图色图的,今天就把你变成色图!", - "咱没有色图", - "哈?你的脑子一天都在想些什么呢,咱才没有这种东西啦。" - ], - "告白": [ - "咱喜..喜欢你!", - "欸?你要向咱告白吗..好害羞..", - "诶!?这么突然!?人家还......还没做好心理准备呢(脸红)" - ], - "对不起": [ - "嗯,咱已经原谅你了呢(笑)", - "道歉的时候要露出胸部,这是常识", - "嗯,咱就相信你一回", - "没事的啦...你只要是真心对咱好就没关系哦~" - ], - "吻": [ - "不要(= ̄ω ̄=)", - "哎?好害羞≧﹏≦.....只许这一次哦", - "(避开)不要了啦!有人在呢!", - "唔~~不可以这样啦(脸红)", - "你太突然了,咱还没有心理准备", - "好痒呢…诶嘿嘿w~", - "mua,嘻嘻!", - "公共场合不要这样子了啦", - "唔?!真、真是的!下次不可以这样了哦!(害羞)", - "才...才没有感觉呢!可没有下次了,知道了吗!哼~" - ], - "软": [ - "软乎乎的呢(,,・ω・,,)", - "好痒呢…诶嘿嘿w~", - "不要..不要乱摸啦(脸红", - "呼呼~", - "咱知道~是咱的欧派啦~(自豪的挺挺胸~)", - "(脸红)请,请不要说这么让人害羞的话呀……" - ], - "壁咚": [ - "呀!不要啊!等一...下~", - "呜...不要啦!不要戏弄咱~", - "不要这样子啦(*/ω\*)", - "太....太近啦。", - "讨....讨厌了(脸红)", - "你要壁咚咱吗?好害羞(灬ꈍ εꈍ灬)", - "(脸红)你想...想做什么///", - "为什么要把咱按在墙上呢?", - "呜哇(/ω\)…快…快放开咱!!", - "放开咱,不然咱揍你了!放开咱!放…开咱~", - "??????咱只是默默地抬起了膝盖", - "请…请温柔点", - "啊.....你...你要干什么?!走开.....走开啦大hentai!一巴掌拍飞!(╯‵□′)╯︵┻━┻", - "干……干什么啦!人家才,才没有那种少女心呢(>﹏<)", - "啊……你吓到咱啦……脸别……别贴那么近……", - "你...你要对咱做什么?咱告诉你,你....不要乱来啊....你!唔......你..居然亲上了...", - "如果你还想要过完整的人生的话就快把手收回去(冷眼", - "h什么的不要" - ], - "掰开": [ - "噫…你这个死肥宅又想让咱干什么污秽的事情,真是恶心,离咱远点好吗(嫌弃)", - "ヽ(#`Д´)ノ在干什么呢" - ], - "女友": [ - "嗯嗯ε٩(๑> ₃ <)۶з", - "女友什么的,咱才不承认呢!" - ], - "是": [ - "是什么是,你个笨蛋", - "总感觉你在敷衍呢...", - "是的呢" - ], - "喵": [ - "诶~~小猫咪不要害怕呦,在姐姐怀里乖乖的,姐姐带你回去哦。", - "不要这么卖萌啦~咱也不知道怎么办丫", - "摸头⊙ω⊙", - "汪汪汪!", - "嗷~喵~", - "喵~?喵呜~w", - "喵呜喵呜喵", - "喵呜喵~喵呜喵~喵呜喵呜喵呜喵~" - ], - "嗷呜": [ - "嗷呜嗷呜嗷呜...恶龙咆哮┗|`O′|┛" - ], - "叫": [ - "喵呜~", - "嗷呜嗷呜嗷呜...恶龙咆哮┗|`O′|┛", - "爪巴爪巴爪巴", - "爬爬爬", - "在叫谁呢(怒)", - "风太大咱听不清", - "才不要", - "不行", - "好的哦~" - ], - "拜": [ - "拜拜~(ノ ̄▽ ̄)", - "拜拜,路上小心~要早点回来陪咱玩哦~", - "~\\(≧▽≦)/~拜拜,下次见喽!", - "回来要记得找咱玩噢~", - "既然你都这么说了……" - ], - "佬": [ - "不是巨佬,是萌新", - "只有先成为大佬,才能和大佬同归于尽", - "在哪里?(疑惑)", - "诶?是比巨佬还高一个等级的吗?(瑟瑟发抖)" - ], - "awsl": [ - "你别死啊!(抱住使劲晃)", - "你别死啊!咱又要孤单一个人了QAQ", - "啊!怎么又死了呀" - ], - "臭": [ - "哪里有臭味?(疑惑)", - "快捏住鼻子", - "在说谁呢(#`Д´)ノ", - "..这就去洗澡澡.." - ], - "香": [ - "咱闻不到呢⊙ω⊙", - "诶,是在说咱吗", - "欸,好害羞(///ˊ??ˋ///)", - "请...请不要这样啦!好害羞的〃∀〃", - "讨厌~你不要闻了", - "hentai!不要闻啊,唔(推开)", - "请不要……凑这么近闻" - ], - "腿": [ - "嗯?!不要啊...请停下来!", - "不给摸,再这样咱要生气了ヽ( ̄д ̄;)ノ", - "你好恶心啊,讨厌!", - "你难道是足控?", - "就让你摸一会哟~(。??ω??。)…", - "呜哇!好害羞...不过既然是你的话,是没关系的哦", - "不可以玩咱的大腿啦", - "不...不要再说了(脸红)", - "不..不可以乱摸啊", - "不……不可以往上摸啦", - "是……这样吗?(慢慢张开)", - "想知道咱胖次的颜色吗?才不给你告诉你呢!", - "这样就可以了么?(乖巧坐腿上)", - "伸出来了,像这样么?", - "咱的腿应该挺白的", - "你就那么喜欢大腿吗?唔...有点害羞呢......", - "讨厌~不要做这种羞羞的事情啦(#/。\#)", - "略略略,张开了也不给你看", - "(张开腿)然后呢", - "张开了也不给看略略略", - "你想干什么呀?那里…那里是不可以摸的(>д<)", - "不要!hentai!咱穿的是裙子(脸红)", - "你想要吗?(脸红着一点点褪下白丝)不...不可以干坏坏的事情哦!(ó﹏ò。)" - ], - "张开": [ - "是……这样吗?(慢慢张开)", - "啊~", - "这样吗?(张开手)你要干什么呀", - "略略略,张开了也不给你看", - "是……这样吗?(慢慢张开)你想看咱的小...吧,嘻嘻,咱脱掉了哦。小~...也要掰开吗?你好H呀,自己来~" - ], - "脚": [ - "咿呀……不要……", - "不要ヽ(≧Д≦)ノ好痒(ಡωಡ)", - "好痒(把脚伸出去)", - "咱脱掉袜子了", - "(脱下鞋子,伸出脚)闻吧,请仔细品味(脸红)", - "那么…要不要咱用脚温柔地踩踩你的头呢(坏笑)", - "哈哈哈!好痒啊~快放开啦!", - "好痒(把脚伸出去)", - "只能看不能挠喔,咱很怕痒qwq", - "唔…咱动不了了,你想对咱做什么…", - "好舒服哦,能再捏会嘛O(≧▽≦)O", - "咿咿~......不要闻咱的脚呀(脸红)好害羞的...", - "不要ヽ(≧Д≦)ノ好痒(ಡωಡ),人家的白丝都要漏了", - "Ya~?为什么你总是喜欢一些奇怪的动作呢(伸)", - "你不可以做这样的事情……", - "呜咿咿!你的舌头...好柔软,滑滑的....咱…咱的脚被舔得很舒服哦~谢谢你(。>﹏<)", - "舔~吧~把咱的脚舔干净(抬起另一只踩在你的头上)啊~hen..hentai...嗯~居... 居然这么努力的舔...呜咿咿!你的舌头... 滑滑的...好舒服呢", - "咿呀……不要……", - "咿呀~快…快停下来…咱…不行了!" - ], - "脸": [ - "唔!不可以随便摸咱的脸啦!", - "非洲血统是没法改变的呢(笑)", - "啊姆!(含手指)", - "好舒服呢(脸红)", - "请不要放开手啦//A//" - ], - "头发": [ - "没问题,请尽情的摸吧", - "发型要乱…乱了啦(脸红)", - "就让你摸一会哟~(。??ω??。)…" - ], - "手": [ - "爪爪", - "//A//", - "咱的手温暖嘛" - ], - "pr": [ - "咿呀……不要……", - "...变态!!", - "不要啊(脸红)", - "呀,不要太过分了啊~", - "当然可以(///)", - "呀,不要太过分了啊~" - ], - "舔": [ - "呀,不要太过分了啊~", - "要...要融化了啦>╱╱╱<", - "不可以哦", - "呀,不要太过分了啊~", - "舌头...就交给咱来处理吧(拿出剪刀)", - "不舔不舔!恶心...", - "H什么的,禁止!", - "变态!哼!", - "就...就这一下!", - "走开啦,baka!", - "怎么会这么舒服喵~这样子下去可不行呀(*////▽////*)", - "噫| •ω •́ ) 你这个死宅又在想什么恶心的东西了", - "hen…hentai,你在干什么啦,好恶心,快停下来啊!!!", - "呀,能不能不要这样!虽然不是很讨厌的感觉...别误会了,你个baka!", - "好 好奇怪的感觉呢 羞≥﹏≤", - "咿呀……不要……", - "不行!咱会变得很奇怪的啊...", - "不要ヽ(≧Д≦)ノ" - ], - "小穴": [ - "你这么问很失礼呢!咱是粉粉嫩嫩的!", - "不行那里不可以(´///ω/// `)", - "不可以总摸的哦,不然的话,咱会想那个的wwww", - "ヽ(#`Д´)ノ在干什么呢", - "来吧,咱的...很紧,很舒服的....www~", - "可以,请你看,好害羞……", - "不要这样...好,好痛", - "啊~不可以", - "不可以", - "咱脱掉了,请……请不要一直盯着咱的白...看……", - "咱觉得,应该还算粉吧", - "咱脱掉了,你是想看咱的...吗?咱是光光的,不知道你喜不喜欢", - "咱……有感觉了QAQ再深一点点……就是这儿,轻轻的抚摸,嗯啊……", - "轻轻抚摸咱的小~~,手指很快就会滑进去,小心一点,不要弄破咱的...哦QAQ", - "诶嘿嘿,你喜欢就太好了,咱一直担心你不喜欢呢", - "禁止说这么H的事情!", - "咱一直有保养呢,所以一直都是樱花色的,你喜欢吗QAQ", - "诶……你居然这么觉得吗?好害羞哦", - "好痒啊,鼻子……你的鼻子碰到了……呀~嗯啊~有点舒服……", - "看样子你不但是个hentai,而且还是个没有女朋友的hentai呢。", - "嗯,咱的小~~是光溜溜、一点毛都没有的。偷偷告诉你,凑近看咱的...的话,白白嫩嫩上有一条樱花色的小缝缝哦www你要是用手指轻轻抚摸咱的...,小~~会分成两瓣,你的手指也会陷进去呢,咱的..~可是又湿润又柔软的呢>////<。", - "讨厌,西内变态", - "那咱让你插...进来哦", - "(●▼●;)" - ], - "腰": [ - "咱给你按摩一下吧~", - "快松手,咱好害羞呀..", - "咱又不是猫,你不要搂着咱啦", - "让咱来帮你捏捏吧!", - "你快停下,咱觉得好痒啊www", - "诶,是这样么ヽ(・_・;)ノ,吖,不要偷看咱裙底!" - ], - "诶嘿嘿": [ - "又在想什么H的事呢(脸红)", - "诶嘿嘿(〃'▽'〃)", - "你傻笑什么呢,摸摸", - "蹭蹭", - "你为什么突然笑得那么猥琐呢?害怕", - "哇!总觉得你笑的很...不对劲...", - "你又想到什么h的事情了!!!快打住" - ], - "可爱": [ - "诶嘿嘿(〃'▽'〃)", - "才……才不是为了你呢!你不要多想哦!", - "才,才没有高兴呢!哼~", - "咱是世界上最可爱的", - "唔...谢谢你夸奖~0///0", - "那当然啦!", - "哎嘿,不要这么夸奖人家啦~", - "是个好孩子呐φ(≧ω≦*)", - "谢……谢谢你", - "胡、胡说什么呢(脸红)", - "谢谢夸奖(脸红)", - "是的咱一直都是可爱的", - "是...是吗,你可不能骗咱哦", - "很...难为情(///////)", - "哎嘿嘿,其实…其实,没那么可爱啦(๑‾ ꇴ ‾๑)" - ], - "卡哇伊": [ - "诶嘿嘿(〃'▽'〃)", - "才……才不是为了你呢!你不要多想哦!", - "才,才没有高兴呢!哼~", - "咱是世界上最可爱的", - "唔...谢谢你夸奖~0///0", - "那当然啦!", - "哎嘿,不要这么夸奖人家啦~", - "是个好孩子呐φ(≧ω≦*)", - "谢……谢谢你", - "胡、胡说什么呢(脸红)", - "谢谢夸奖(脸红)", - "是的咱一直都是可爱的", - "是...是吗,你可不能骗咱哦", - "很...难为情(///////)", - "哎嘿嘿,其实…其实,没那么可爱啦(๑‾ ꇴ ‾๑)" - ], - "kawaii": [ - "诶嘿嘿(〃'▽'〃)", - "才……才不是为了你呢!你不要多想哦!", - "才,才没有高兴呢!哼~", - "咱是世界上最可爱的", - "唔...谢谢你夸奖~0///0", - "那当然啦!", - "哎嘿,不要这么夸奖人家啦~", - "是个好孩子呐φ(≧ω≦*)", - "谢……谢谢你", - "胡、胡说什么呢(脸红)", - "谢谢夸奖(脸红)", - "是的咱一直都是可爱的", - "是...是吗,你可不能骗咱哦", - "很...难为情(///////)", - "哎嘿嘿,其实…其实,没那么可爱啦(๑‾ ꇴ ‾๑)" - ], - "扭蛋": [ - "铛铛铛——你抽到了咱呢", - "嘿~恭喜抽中空气一份呢" - ], - "鼻": [ - "快停下!o(*≧д≦)o!!", - "唔…不要这样啦(//ω\\)(脸红)", - "咱吸了吸鼻子O(≧口≦)O", - "好……好害羞啊", - "讨厌啦!你真是的…就会欺负咱(嘟嘴)", - "你快放手,咱没法呼吸了", - "(捂住鼻尖)!坏人!", - "啊——唔...没什么...阿嚏!ヽ(*。>Д<)o゜", - "不...不要靠这么近啦...很害羞的...⁄(⁄⁄•⁄ω⁄•⁄⁄)⁄" - ], - "眼": [ - "就如同咱的眼睛一样,能看透人的思想哦wwww忽闪忽闪的,诶嘿嘿~", - "因为里面有你呀~(///▽///)", - "呀!你突然之间干什么呢,吓咱一跳,是有什么惊喜要给咱吗?很期待呢~(一脸期待)" - ], - "色气": [ - "咱才不色气呢,一定是你看错了!", - "你,不,不要说了!" - ], - "推": [ - "逆推", - "唔~好害羞呢", - "你想对咱做什么呢...(捂脸)", - "呀啊!请.... 请温柔一点////", - "呜,你想对咱做什么呢(捂脸)", - "啊(>_<)你想做什么", - "嗯,…好害羞啊…", - "不要啊/////", - "逆推", - "(按住你不让推)", - "不可以这样子的噢!咱不同意", - "呜,咱被推倒了", - "啊~不要啊,你要矜持一点啊", - "变态,走开啦" - ], - "床": [ - "咱来了(´,,•ω•,,)♡", - "快来吧", - "男女不同床,可没有下次了。(鼓脸", - "嗯?咱吗…没办法呢。只有这一次哦……", - "哎?!!!给你暖床……也不是不行啦。(脸红)", - "(爬上床)你要睡了吗(灬ºωº灬)", - "大概会有很多运动器材吧?", - "好的哦~", - "才不!", - "嗯嗯,咱来啦(小跑)", - "嗨嗨,现在就来~", - "H的事情,不可以!", - "诶!H什么的禁止的说....." - ], - "举": [ - "放咱下来o(≧口≦)o", - "快放咱下来∑(゚д゚*)", - "(受宠若惊)", - "呜哇要掉下来了!Ծ‸Ծ", - "不要抛起来o(≧口≦)o", - "(举起双爪)喵喵喵~~~", - "www咱长高了!(大雾)", - "快放下", - "这样很痒啦,快放咱下来(≥﹏≤)", - "啊Σ(°△°|||)︴太高了太高了!o(≧口≦)o快放咱下来!呜~" - ], - "手冲": [ - "啊~H!hentai!", - "手冲什么的是不可以的哦" - ], - "饿": [ - "请问主人是想先吃饭,还是先吃咱喵?~", - "咱做了爱心便当哦,不介意的话,请让咱来喂你吃吧!", - "咱下面给你吃", - "给你一条咸鱼= ̄ω ̄=", - "你要咱下面给你吃吗?(捂脸)", - "你饿了吗?咱去给你做饭吃☆ww", - "不要吃咱>_<", - "请问你要来点兔子吗?", - "哎?!你是饿了么。咱会做一些甜点。如果你不会嫌弃的话...就来尝尝看吧。" - ], - "变": [ - "猫猫不会变呐(弱气,害羞", - "呜...呜姆...喵喵来报恩了喵...(害羞", - "那种事情,才没有", - "(,,゚Д゚)", - "喵~(你在想什么呢,咱才不会变成猫)", - "才没有了啦~", - "喵呜?呜…被变成猫娘惹" - ], - "敲": [ - "喵呜~", - "唔~", - "脑瓜疼~呜姆> <", - "欸喵,好痛的说...", - "好痛...你不要这样啦QAQ", - "不要敲咱啦,会变笨的QWQ(捂头顶)", - "不要再敲人家啦~人家会变笨的", - "讨厌啦~再敲人家会变笨的", - "好痛(捂头)你干什么啦!ヽ(。>д<)p", - "唔!你为什么要敲咱啦qwq", - "(抱头蹲在墙角)咱什么都没有,请你放过咱吧!(瑟瑟发抖)", - "QAQ!不许敲啦!", - "呼,敲回去~(敲)" - ], - "爬": [ - "惹~呜~怎么爬呢~", - "呜...(弱弱爬走", - "给你🐎一拳", - "给你一拳", - "爪巴" - ], - "怕": [ - "不怕~(蹭蹭你姆~", - "不怕不怕啦~", - "只要有你在,咱就不怕啦。", - "哇啊啊~", - "那就要坚强的欢笑哦", - "不怕不怕,来咱的怀里吧?", - "是技术性调整", - "嗯(紧紧握住手)", - "咱在呢,不会走的。", - "有咱在不怕不怕呢", - "不怕不怕" - ], - "冲": [ - "呜,冲不动惹~", - "哭唧唧~冲不出来了惹~", - "咱也一起……吧?", - "你要冷静一点", - "啊~H!hentai!", - "噫…在你去洗手之前,不要用手碰咱了→_→", - "冲是不可以的哦" - ], - "射": [ - "呜咿~!?(惊,害羞", - "还不可以射哦~", - "不许射!", - "憋回去!", - "不可以!你是变态吗?", - "咱来帮你修剪掉多余部分吧。(拿出剪刀)" - ], - "不穿": [ - "呜姆~!(惊吓,害羞)变...变态喵~~~!", - "想让你看QAQ", - "这是不文明的", - "hen...hentai,咱的身体才不会给你看呢" - ], - "迫害": [ - "不...不要...不要...呜呜呜...(害怕,抽泣" - ], - "猫粮": [ - "呜咿姆~!?(惊,接住吃", - "呜姆~!(惊,害羞)呜...谢...谢谢主人..喵...(脸红,嚼嚼嚼,开心", - "呜?谢谢喵~~(嚼嚼嚼,嘎嘣脆)" - ], - "揪尾巴": [ - "呜哇咿~~~!(惊吓,疼痛地捂住尾巴", - "呜咿咿咿~~~!!哇啊咿~~~!(惊慌,惨叫,挣扎", - "呜咿...(瘫倒,无神,被", - "呜姆咿~~~!(惊吓,惨叫,捂尾巴,发抖", - "呜哇咿~~~!!!(惊吓,颤抖,娇叫,捂住尾巴,双腿发抖", - "喵呜…那…那里不可以揪的!", - "呜呜,被揪住会恨敏感的QAQ" - ], - "薄荷": [ - "咪呜~!喵~...喵~姆~...(高兴地嗅闻", - "呜...呜咿~~!咿...姆...(呜咽,渐渐瘫软,意识模糊", - "(小嘴被猫薄荷塞满了,呜咽", - "喵~...喵~...咪...咪呜姆~...嘶哈嘶哈...喵哈...喵哈...嘶哈...喵...(眼睛逐渐迷离,瘫软在地上,嘴角流口水,吸猫薄荷吸到意识模糊", - "呜姆咪~!?(惊)喵呜~!(兴奋地扑到猫薄荷上面", - "呜姆~!(惊,害羞)呜...谢...谢谢你..喵...(脸红,轻轻叼住,嚼嚼嚼,开心" - ], - "早": [ - "早喵~", - "早上好的说~~", - "欸..早..早上好(揉眼睛", - "早上要说我爱你!", - "早", - "早啊,昨晚睡的怎么样?有梦到咱吗~", - "昨晚可真激烈呢哼哼哼~~", - "早上好哇!今天也要元气满满哟!", - "早安喵~", - "时间过得好快啊~", - "早安啊,你昨晚有没有梦到咱呢  (//▽//)", - "早安~么么哒~", - "早安,请享受晨光吧", - "早安~今天也要一起加油呢~!", - "mua~⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄", - "咱需要你提醒嘛!(///脸红//////)", - "早早早!就知道早,下次说我爱你!", - "早安 喵", - "早安,这么早就起床了呀欧尼酱0.0", - "快点起床啊!baka", - "早....早上好才没有什么特别的意思呢....哼~", - "今天有空吗?能陪咱一阵子吗?才不是想约会呢,别误会了!", - "早安呀,欧尼酱要一个咱的早安之吻吗?想得美,才不会亲你啦!", - "那...那就勉为其难地说声早上好吧", - "咱等你很久了哼ヽ(≧Д≦)ノ", - "ohayo~" - ], - "晚安": [ - "晚安好梦哟~", - "欸,晚安的说", - "那咱给你亲一下,可不要睡着了哦~", - "晚安哦~", - "晚安(*/∇\*)", - "晚安呢,你一定要梦到咱呢,一定哟,拉勾勾!ヽ(*・ω・)ノ", - "祝你有个好梦^_^", - "晚安啦,欧尼酱,mua~", - "你,你这家伙真是的…咱就勉为其难的……mua…快去睡啦!咱才没有脸红什么的!", - "哼,晚安,给咱睡个好觉。", - "笨..笨蛋,晚安啦...可不可以一起..才没有想和你一起睡呢", - "晚安......才..不是关心你呢", - "晚...晚安,只是正常互动不要想太多!", - "好无聊,这么早就睡了啊...那晚安吧!", - "晚安吻什么的才...才没有呢!不过看你累了就体谅一下你吧,但是就一个哦(/////)", - "晚安呀,你也要好好休息,明天再见", - "安啦~祝你做个好梦~才...才不是关心你呢!别想太多了!", - "睡觉吧你,大傻瓜", - "一起睡吧(灬°ω°灬)", - "哼!这次就放过你了,快去睡觉吧。", - "睡吧晚安", - "晚安你个头啊,咱才不会说晚安呢!...咱...(小声)明明还有想和你做的事情呢....", - "嗯嗯~Good night~", - "嗯,早点休息别再熬夜啦~(摸摸头)", - "哦呀斯密", - "晚安~咱也稍微有些困了(钻进被窝)", - "需要咱暖床吗~", - "好梦~☆" - ], - "揉": [ - "是是,想怎么揉就怎么揉啊!?来用力抓啊!?咱就是特别允许你这么做了!请!?", - "快停下,咱的头发又乱啦(??????︿??????)", - "你快放手啦,咱还在工作呢", - "戳戳你肚子", - "讨厌…只能一下…", - "呜~啊~", - "那……请你,温柔点哦~(////////)", - "你想揉就揉吧..就这一次哦?", - "变态!!不许乱摸" - ], - "榨": [ - "是专门负责榨果汁的小姐姐嘛?(´・ω・`)", - "那咱就把你放进榨汁机里了哦?", - "咱又不是榨汁姬(/‵Д′)/~ ╧╧", - "嗯——!想,想榨就榨啊······!反正就算榨了也不会有奶的······!" - ], - "掐": [ - "你讨厌!又掐咱的脸", - "晃休啦,咱要型气了啦!!o(>﹏<)o", - "(一只手拎起你)这么鶸还想和咱抗衡,还差得远呢!" - ], - "胸": [ - "不要啦ヽ(≧Д≦)ノ", - "(-`ェ´-╬)", - "(•̀へ •́ ╮ ) 怎么能对咱做这种事情", - "你好恶心啊,讨厌!", - "你的眼睛在看哪里!", - "就让你摸一会哟~(。??ω??。)…", - "请不要这样先生,你想剁手吗?", - "咿呀……不要……", - "嗯哼~才…才不会…舒服呢", - "只允许一下哦…(脸红)", - "咱的胸才不小呢(挺一挺胸)", - "hentai!", - "一只手能抓住么~", - "呀...欧,欧尼酱...请轻点。", - "脸红????", - "咿呀~快…快停下来…咱…不行了!", - "就算一直摸一直摸,也不会变大的哦(小声)", - "诶?!不...不可以哦!很...很害羞的!", - "啊……温,温柔点啊……(/ω\)", - "你为什么对两块脂肪恋恋不舍", - "嗯……不可以……啦……不要乱戳", - "你在想什么奇怪的东西,讨厌(脸红)", - "不...不要..", - "喜欢欧派是很正常的想法呢", - "一直玩弄欧派,咱的...都挺起来了", - "是要直接摸还是伸进里面摸呀w咱今天没穿,伸进里面会摸到立起来的...哦>////<", - "唔~再激烈点" - ], - "奶子": [ - "只允许一下哦…(脸红)", - "咱的胸才不小呢(挺一挺胸)", - "下流!", - "对咱说这种话,你真是太过分了", - "咿呀~好奇怪的感觉(>_<)", - "(推开)你就像小宝宝一样...才不要呢!", - "(打你)快放手,不可以随便摸人家的胸部啦!", - "你是满脑子都是H的淫兽吗?", - "一只手能抓住么~", - "你在想什么奇怪的东西,讨厌(脸红)", - "不...不要..", - "喜欢欧派是很正常的想法呢", - "一直玩弄欧派,咱的...都挺起来了", - "是要直接摸还是伸进里面摸呀w咱今天没穿,伸进里面会摸到立起来的...哦>////<", - "唔~再激烈点", - "解开扣子,请享用", - "请把脑袋伸过来,咱给你看个宝贝", - "八嘎!hentai!无路赛!", - "一只手能抓住么~", - "呀...欧,欧尼酱...请轻点。", - "脸红????", - "咿呀~快…快停下来…咱…不行了!", - "就算一直摸一直摸,也不会变大的哦(小声)", - "诶?!不...不可以哦!很...很害羞的!", - "啊……温,温柔点啊……(/ω\)", - "你为什么对两块脂肪恋恋不舍", - "嗯……不可以……啦……不要乱戳" - ], - "欧派": [ - "咱的胸才不小呢(挺一挺胸)", - "只允许一下哦…(脸红)", - "(推开)你就像小宝宝一样...才不要呢!", - "下流!", - "对咱说这种话,你真是太过分了", - "咿呀~好奇怪的感觉(>_<)", - "(打你)快放手,不可以随便摸人家的胸部啦!", - "你是满脑子都是H的淫兽吗?", - "一只手能抓住么~", - "你在想什么奇怪的东西,讨厌(脸红)", - "不...不要..", - "喜欢欧派是很正常的想法呢", - "一直玩弄欧派,咱的...都挺起来了", - "是要直接摸还是伸进里面摸呀w咱今天没穿,伸进里面会摸到立起来的...哦>////<", - "唔~再激烈点", - "解开扣子,请享用", - "请把脑袋伸过来,咱给你看个宝贝", - "八嘎!hentai!无路赛!", - "一只手能抓住么~", - "呀...欧,欧尼酱...请轻点。", - "脸红????", - "咿呀~快…快停下来…咱…不行了!", - "就算一直摸一直摸,也不会变大的哦(小声)", - "诶?!不...不可以哦!很...很害羞的!", - "啊……温,温柔点啊……(/ω\)", - "你为什么对两块脂肪恋恋不舍", - "嗯……不可以……啦……不要乱戳" - ], - "嫩": [ - "很可爱吧(๑•̀ω•́)ノ", - "唔,你指的是什么呀", - "明天你下海干活", - "咱一直有保养呢,所以一直都是樱花色的,你喜欢吗QAQ", - "咱下面超厉害" - ], - "蹭": [ - "唔...你,这也是禁止事项哦→_→", - "嗯..好舒服呢", - "不要啊好痒的", - "不要过来啦讨厌!!!∑(°Д°ノ)ノ", - "(按住你的头)好痒呀 不要啦", - "嗯..好舒服呢", - "呀~好痒啊~哈哈~,停下来啦,哈哈哈", - "(害羞)" - ], - "牵手": [ - "只许牵一下哦", - "嗯!好的你~(伸手)", - "你的手有些凉呢,让咱来暖一暖吧。", - "当然可以啦⁄(⁄⁄•⁄ω⁄•⁄⁄)⁄", - "突……突然牵手什么的(害羞)", - "一起走", - "……咱……咱在这里呀", - "好哦,(十指相扣)" - ], - "握手": [ - "你的手真暖和呢", - "举爪", - "真是温暖呢~" - ], - "拍照": [ - "那就拜托你啦~请把咱拍得更可爱一些吧w", - "咱已经准备好了哟", - "那个……请问这样的姿势可以吗?" - ], - "w": [ - "有什么好笑的吗?", - "草", - "www", - "在笑什么呢?(歪头)", - ">w<" - ], - "睡不着": [ - "睡不着的话..你...你可以抱着咱一起睡哦(小声)", - "当然是数羊了...不不不,想着咱就能睡着了", - "咱很乐意与你聊天哦(>_<)", - "要不要咱来唱首摇篮曲呢?(′?ω?`)", - "那咱来唱摇篮曲哄你睡觉吧!" - ], - "欧尼酱": [ - "欧~尼~酱~☆", - "欧尼酱?", - "嗯嗯φ(>ω<*) 欧尼酱轻点抱", - "欧尼酱~欧尼酱~欧尼酱~" - ], - "哥": [ - "欧尼酱~", - "哦尼酱~", - "世上只有哥哥好,没哥哥的咱好伤心,扑进哥哥的怀里,幸福不得了", - "哥...哥哥...哥哥大人", - "欧~尼~酱~☆", - "欧尼酱?", - "嗯嗯φ(>ω<*) 欧尼酱轻点抱", - "欧尼酱~欧尼酱~欧尼酱~" - ], - "爱你": [ - "是…是嘛(脸红)呐,其实咱也……", - "咱也最爱你了呢~o(*////▽////*)q", - "咱也爱你哦", - "mua~" - ], - "过来": [ - "来了来了~(扑倒怀里(?? ??????ω?????? ??))", - "(蹦跶、蹦跶)~干什么呢", - "咱来啦~(扑倒怀里~)", - "不要喊的这么大声啦,大家都看着呢" - ], - "自闭": [ - "不不不,晚上还有咱陪着哦,无论什么时候,咱都会陪在哥哥身边。", - "不要难过,咱陪着你ovo" - ], - "打不过": [ - "氪氪氪肝肝肝", - "你需要钞能力呢" - ], - "么么哒": [ - "么么哒", - "不要在公共场合这样啦", - "mua~" - ], - "很懂": [ - "现在不懂,以后总会懂嘛QAQ", - "喵?懂…懂什么呀?(歪头)" - ], - "膝枕": [ - "呐,就给你躺一下哦", - "唔...你想要膝枕嘛?也不是不可以哟(脸红)", - "啊啦~好吧,那就请你枕着咱好好睡一觉吧~", - "呀呀~那么请好好的睡一觉吧", - "嗯,那么请睡到咱这里吧(跪坐着拍拍大腿)", - "好的,让你靠在腿上,这样感觉舒服些了么", - "请,请慢用,要怜惜咱哦wwww~", - "人家已经准备好了哟~把头放在咱的腿上吧", - "没…没办法,这次是例外〃w〃", - "嗯~(脸红)", - "那就给你膝枕吧……就一会哦", - "膝枕准备好咯~" - ], - "累了": [ - "需要咱的膝枕嘛?", - "没…没办法,这次是例外〃w〃", - "累了吗?需要咱为你做膝枕吗?", - "嗯~(脸红)" - ], - "安慰": [ - "那,膝枕……(脸红)", - "不哭不哭,还有咱陪着你", - "不要哭。咱会像妈妈一样安慰你(抱住你的头)", - "摸摸头,乖", - "摸摸有什么事可以和咱说哟", - "摸摸头~不哭不哭", - "咱在呢,抱抱~~", - "那么……让咱来安慰你吧", - "唔...摸摸头安慰一下ヾ(•ω•`。)", - "有咱陪伴你就是最大的安慰啦……不要不开心嘛", - "你想要怎样的安慰呢?这样?这样?还是说~~这样!", - "摸摸头~", - "不哭不哭,要像咱一样坚强", - "你别难过啦,不顺心的事都会被时间冲刷干净的,在那之前...咱会陪在你的身边", - "(轻抱)放心……有咱在,不要伤心呢……", - "唔...咱来安慰你了~", - "摸摸,有什么不开心的事情可以给咱说哦。咱会尽力帮助你的。" - ], - "洗澡": [ - "快点脱哟~不然水就凉了呢", - "咱在穿衣服噢,你不许偷看哦", - "那么咱去洗澡澡了哦", - "么么哒,快去洗干净吧,咱去暖被窝喽(///ω///)", - "诶?还没呢…你要跟咱一起洗吗(//∇//)好羞涩啊ww", - "诶~虽然很喜欢和你在一起,但是洗澡这种事...", - "不要看!不过,以后或许可以哦……和咱成为恋人之后呢", - "说什么啊……hentai!这样会很难为情的", - "你是男孩子还是女孩子呢?男孩子的话...........咱才不要呢。", - "不要啊!", - "咱有点害羞呢呜呜,你温柔点" - ], - "一起睡觉": [ - "欸??也..也不是不可以啦..那咱现在去洗澡,你不要偷看哦٩(๑>◡<๑)۶", - "说什么啊……hentai!这样会很难为情的", - "你是男孩子还是女孩子呢?男孩子的话...........咱才不要呢。", - "不要啊!", - "唔,没办法呢,那就一起睡吧(害羞)" - ], - "一起": [ - "嗯嗯w,真的可以吗?", - "那真是太好了,快开始吧!", - "嗯,咱会一直陪伴你的", - "丑拒" - ], - "多大": [ - "不是特别大但是你摸起来会很舒服的大小喵~", - "你摸摸看不就知道了吗?", - "不告诉你", - "问咱这种问题不觉得很失礼吗?", - "咱就不告诉你,你钻到屏幕里来自己确认啊", - "你指的是什么呀?(捂住胸部)", - "请叫人家咱三岁(。・`ω´・)", - "唉唉唉……这……这种问题,怎么可以……" - ], - "姐姐": [ - "真是的……真是拿你没办法呢 ⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄ 才不是咱主动要求的呢!", - "虽然辛苦,但是能看见可爱的你,咱就觉得很幸福", - "诶(´°Δ°`),是在叫咱吗?", - "有什么事吗~", - "好高兴,有人称呼咱为姐姐", - "乖,摸摸头" - ], - "糖": [ - "不吃脱氧核糖(;≥皿≤)", - "ヾ(✿゚▽゚)ノ好甜", - "好呀!嗯~好甜呀!", - "不吃不吃!咱才不吃坏叔叔的糖果!", - "嗯,啊~", - "嗯嗯,真甜,给你也吃一口", - "谢谢", - "唔,这是什么东西,黏黏的?(??Д??)ノ", - "ヾ(✿゚▽゚)ノ好甜", - "(伸出舌头舔了舔)好吃~最爱你啦", - "好耶~是好次的🍥糖糖喵~" - ], - "嗦": [ - "(吸溜吸溜)", - "好...好的(慢慢含上去)", - "把你噶咯", - "太小了,嗦不到", - "咕噜咕噜", - "嘶蛤嘶蛤嘶蛤~~", - "(咬断)", - "prprprpr", - "好哒主人那咱开始了哦~", - "好好吃", - "剁掉了" - ], - "牛子": [ - "(吸溜吸溜)", - "好...好的(慢慢含上去)", - "把你噶咯", - "太小了,嗦不到", - "咕噜咕噜", - "嘶蛤嘶蛤嘶蛤~~", - "(咬断)", - "prprprpr", - "好哒主人那咱开始了哦~", - "好好吃", - "剁掉了", - "难道你很擅长针线活吗", - "弹一万下", - "往死里弹" - ], - "🐂子": [ - "(吸溜吸溜)", - "好...好的(慢慢含上去)", - "把你噶咯", - "太小了,嗦不到", - "咕噜咕噜", - "嘶蛤嘶蛤嘶蛤~~", - "(咬断)", - "prprprpr", - "好哒主人那咱开始了哦~", - "好好吃", - "剁掉了", - "难道你很擅长针线活吗", - "弹一万下", - "往死里弹" - ], - "🐮子": [ - "(吸溜吸溜)", - "好...好的(慢慢含上去)", - "把你噶咯", - "太小了,嗦不到", - "咕噜咕噜", - "嘶蛤嘶蛤嘶蛤~~", - "(咬断)", - "prprprpr", - "好哒主人那咱开始了哦~", - "好好吃", - "剁掉了", - "难道你很擅长针线活吗", - "弹一万下", - "往死里弹" - ], - "嫌弃": [ - "咱辣么萌,为什么要嫌弃咱...", - "即使你不喜欢咱,咱也会一直一直喜欢着你", - "(;′⌒`)是咱做错了什么吗?", - "呜呜…不要嫌弃咱……让咱做什么都可以的……但是请不要嫌弃咱可以嘛……" - ], - "紧": [ - "嗯,对的", - "呜咕~咱要......喘不过气来了......" - ], - "baka": [ - "你也是baka呢!", - "确实", - "baka!", - "不不不", - "说别人是baka的人才是baka", - "你个大傻瓜", - "不说了,睡觉了", - "咱...咱虽然是有些笨啦...但是咱会努力去学习的", - "bakabaka~", - "才…才不是baka啦!" - ], - "笨蛋": [ - "你也是笨蛋呢!", - "确实", - "笨蛋!", - "不不不", - "说别人是笨蛋的人才是笨蛋", - "你个大傻瓜", - "不说了,睡觉了", - "咱...咱虽然是有些笨啦...但是咱会努力去学习的", - "才…才不是笨蛋呢!" - ], - "插": [ - "来吧,咱的小~...很....紧,很舒服的", - "gun!", - "唔…咱怕疼", - "唔...,这也是禁止事项哦→_→", - "禁止说这么H的事情!", - "要...戴套套哦", - "好痛~", - "使劲", - "就这?", - "恁搁着整针线活呢?" - ], - "插进来": [ - "来吧,咱的小~...很....紧,很舒服的", - "gun!", - "唔…咱怕疼", - "唔...,这也是禁止事项哦→_→", - "禁止说这么H的事情!", - "要...戴套套哦", - "好痛~", - "使劲", - "就这?", - "恁搁着整针线活呢?" - ], - "屁股": [ - "不要ヽ(≧Д≦)ノ好痛", - "(打手)不许摸咱的屁股", - "(撅起屁股)要干什么呀?", - "(轻轻的撩起自己的裙子),你轻一点,咱会痛的(>_<)!", - "在摸哪里啊,hentai!", - "要轻点哦(/≧ω\)", - "轻点呀~", - "(歇下裙子,拉下内...,撅起来)请", - "嗯嗯,咱这就把屁股抬起来" - ], - "翘": [ - "你让咱摆出这个姿势是想干什么?", - "好感度-1-1-1-1-1-1.....", - "嗯嗯,咱这就去把你的腿翘起来", - "请尽情享用吧" - ], - "翘起来": [ - "你让咱摆出这个姿势是想干什么?", - "好感度-1-1-1-1-1-1.....", - "嗯嗯,咱这就去把你的腿翘起来", - "请尽情享用吧" - ], - "抬": [ - "你在干什么呢⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄", - "(抬起下巴)你要干什么呀?", - "上面什么也没有啊(呆~)", - "不要!hentai!咱穿的是裙子(脸红)", - "不可以" - ], - "抬起": [ - "你在干什么呢⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄", - "(抬起下巴)你要干什么呀?", - "上面什么也没有啊(呆~)", - "不要!hentai!咱穿的是裙子(脸红)", - "不可以" - ], - "爸": [ - "欸!儿子!", - "才不要", - "粑粑", - "讨厌..你才不是咱的爸爸呢..(嘟嘴)", - "你又不是咱的爸爸……", - "咱才没有你这样的鬼父!", - "爸爸酱~最喜欢了~" - ], - "傲娇": [ - "才.......才.......才没有呢", - "也好了(有点点的样子(o ̄Д ̄)<)", - "任性可是女孩子的天性呢...", - "谁会喜欢傲娇啊(为了你假装傲娇)", - "谁,谁,傲娇了,八嘎八嘎,你才傲娇了呢(っ//////////c)(为了你假装成傲娇)", - "傲娇什么的……才没有呢!(/////)", - "傲不傲娇你还不清楚吗?", - "你才是傲娇!你全家都是傲娇!哼(`Д´)", - "才……才没有呢,哼,再说不理你了", - "咱...咱才不会这样子的!", - "啰…啰嗦!", - "哼!(叉腰鼓嘴扭头)", - "你才是傲娇受你全家都是傲娇受╰_╯", - "才~才不是呢,不理你了!哼(`Д´)", - "你才是死傲娇", - "啰,啰嗦死了,才不是呢!", - "就是傲娇你要怎样", - "诶...!这...这样...太狡猾了啦...你这家伙....", - "无路赛!你才是傲娇嘞!你全家都是!", - "咱...咱才不是傲娇呢,哼(鼓脸)", - "不许这么说咱 ,,Ծ‸Ծ,,", - "才…才不是傲娇呢!哼!" - ], - "rua": [ - "略略略~(吐舌头)", - "rua!", - "mua~", - "略略略", - "mua~⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄", - "摸了", - "嘁,丢人(嫌弃脸)", - "反rua~", - "rua回去" - ], - "咕噜咕噜": [ - "嘟嘟噜", - "你在吹泡泡吗?", - "咕叽咕噜~", - "咕噜咕噜" - ], - "咕噜": [ - "嘟嘟噜", - "你在吹泡泡吗?", - "咕叽咕噜~", - "咕噜咕噜" - ], - "上床": [ - "诶!H什么的禁止的说.....", - "咱已经乖乖在自家床上躺好了,有什么问题吗?", - "你想要干什么,难道是什么不好的事吗?", - "(给你空出位置)", - "不要,走开(ノ`⊿??)ノ", - "好喔,不过要先抱一下咱啦", - "(双手护胸)变....变态!", - "咱帮你盖上被子~然后陪在你身边_(:зゝ∠)_", - "才不给你腾空间呢,你睡地板,哼!", - "要一起吗?" - ], - "做爱": [ - "做这种事情是不是还太早了", - "噫!没想到你居然是这样的人!", - "再说这种话,就把你变成女孩子(拿刀)", - "不想好好和咱聊天就不要说话了", - "(双手护胸)变....变态!", - "hentai", - "你想怎么做呢?", - "突,突然,说什么啊!baka!", - "你又在说什么H的东西", - "咱....咱才不想和你....好了好了,有那么一点点那,对就一点点,哼~", - "就一下下哦,不能再多了" - ], - "吃掉": [ - "(羞羞*>_<*)好吧...请你温柔点,哦~", - "闪避,反咬", - "请你好好品尝咱吧(/ω\)", - "不……不可以这样!", - "那就吃掉咱吧(乖乖的躺好)", - "都可以哦~咱不挑食的呢~", - "请不要吃掉咱,咱会乖乖听话的QAQ", - "咱...咱一点都不好吃的呢!", - "不要吃掉咱,呜呜(害怕)", - "不行啦,咱被吃掉就没有了QAQ(害怕)", - "唔....?诶诶诶诶?//////", - "QwQ咱还只是个孩子(脸红)", - "如果你真的很想的话...只能够一口哦~咱...会很痛的", - "吃你呀~(飞扑", - "不要啊,咱不香的(⋟﹏⋞)", - "说着这种话的是hentai吗!", - "快来把咱吃掉吧", - "还……还请好好品尝咱哦", - "喏~(伸手)", - "呐…是主人的话…被次掉也不是不可以啦……(递自己)" - ], - "吃": [ - "(羞羞*>_<*)好吧...请你温柔点,哦~", - "闪避,反咬", - "请你好好品尝咱吧(/ω\)", - "不……不可以这样!", - "那就吃掉咱吧(乖乖的躺好)", - "都可以哦~咱不挑食的呢~", - "请不要吃掉咱,咱会乖乖听话的QAQ", - "咱...咱一点都不好吃的呢!", - "不要吃掉咱,呜呜(害怕)", - "不行啦,咱被吃掉就没有了QAQ(害怕)", - "唔....?诶诶诶诶?//////", - "QwQ咱还只是个孩子(脸红)", - "如果你真的很想的话...只能够一口哦~咱...会很痛的", - "吃你呀~(飞扑", - "不要啊,咱不香的(⋟﹏⋞)", - "说着这种话的是hentai吗!", - "快来把咱吃掉吧", - "还……还请好好品尝咱哦", - "喏~(伸手)", - "呐…是主人的话…被次掉也不是不可以啦……(递自己)" - ], - "揪": [ - "你快放手,好痛呀", - "呜呒~唔(伸出舌头)", - "(捂住耳朵)你做什么啦!真是的...总是欺负咱", - "你为什么要这么做呢?", - "哎呀啊啊啊啊啊!不要...不要揪!好疼!有呆毛的咱难道不够萌吗QwQ", - "你…松……送手啦", - "呀!这样对女孩子是很不礼貌的(嘟嘴)" - ], - "种草莓": [ - "你…你不要…啊…种在这里…会容易被别人看见的(*//ω//*)", - "啊...太明显了...不要在这里种草莓啦", - "来吧~我对其他人说是蚊子叮的~" - ], - "种草": [ - "你…你不要…啊…种在这里…会容易被别人看见的(*//ω//*)" - ], - "掀": [ - "(掀裙)今天……是…白,白色的呢……请温柔对她……", - "那样,胖次会被你看光的", - "(按住)不可以掀起来!", - "不要~", - "呜呜~(揉眼睛)", - "呜..请温柔一点(害羞)", - "不可以", - "今天……没有穿", - "不要啊!(//////)讨厌...", - "变态,快放手(打)", - "不给掀,你是变态", - "最后的底牌了!", - "这个hentai" - ], - "妹": [ - "你有什么事?咱会尽量满足的", - "开心(*´∀`)~♥", - "欧尼酱", - "哥哥想要抱抱吗", - "喵呜,欧尼酱的超绝无敌可爱妹妹在这里哦~" - ], - "病娇": [ - "为什么会这样呢(拿起菜刀)", - "觉得这个世界太肮脏?没事,把眼睛挖掉就好。 觉得这些闲言碎语太吵?没事,把耳朵堵起来就好。 觉得鲜血的味道太刺鼻?没事,把鼻子割掉就好。 觉得自己的话语太伤人?没事,把嘴巴缝起来就好。", - "唔…不好,咱是病娇的事情终究还是被发现了嘛……没办法呢,那就只好把你处理掉了呢~" - ], - "嘻": [ - "你是想对咱做什么吗...(后退)", - "哼哼~", - "嘻嘻w" - ], - "按摩": [ - "(小手捏捏)咱的按摩舒服吗?", - "咱不会按摩的!", - "嘿咻嘿咻~这样觉得舒服吗?", - "呀!...呜...,不要...不要这样啦...呜...", - "只能按摩后背喔...", - "咱对这些不是很懂呢(????ω??????)" - ], - "按住": [ - "Σ(°Д°;您要干什么~放开咱啦", - "突然使出过肩摔!", - "放手啦,再这样咱就要反击了喔", - "你的眼睛在看哪里!", - "呜呒~唔(伸出舌头)", - "H的事情,不可以!", - "想吃吗?(๑•ૅω•´๑)", - "要和咱比试比试吗", - "呜哇(/ω\)…快…快放开咱!!", - "(用力揪你耳朵)下次再敢这样的话就没容易放过你了!哼!", - "尼……奏凯……快航休!", - "哈?别..唔啊!别把咱……(挣扎)baka!别乱动咱啦!" - ], - "按在": [ - "不要这样啦(一脸娇羞的推开)", - "(一个过肩摔,加踢裆然后帅气地回头)你太弱了呢~", - "放手啦,再这样咱就要反击了喔", - "Σ(°Д°; 你要干什么~放开咱啦", - "要和咱比试比试吗", - "呜哇(/ω\)…快…快放开咱!!", - "敢按住咱真是好大的胆子!", - "(用力揪你耳朵)下次再敢这样的话就没容易放过你了!哼!", - "尼……奏凯……快航休!", - "哈?别..唔啊!别把咱……(挣扎)baka!别乱动咱啦!" - ], - "按倒": [ - "把咱按倒是想干嘛呢(??`⊿??)??", - "咱也...咱也是...都等你好长时间了", - "你的身体没问题吧?", - "呜呒~唔(伸出舌头)", - "H的事情,不可以!", - "放手啦,再这样咱就要反击了喔", - "想吃吗?(๑•ૅω•´๑)", - "不....不要吧..咱会害羞的(//////)", - "要和咱比试比试吗", - "呜哇(/ω\)…快…快放开咱!!", - "(用力揪你耳朵)下次再敢这样的话就没容易放过你了!哼!", - "尼……奏凯……快航休!", - "哈?别..唔啊!别把咱……(挣扎)baka!别乱动咱啦!" - ], - "按": [ - "咱也...咱也是...都等你好长时间了", - "不让!", - "不要,好难为情", - "你的眼睛在看哪里!", - "拒绝!", - "唔...唔..嗯", - "咱就勉为其难地给你弄弄好啦", - "欸…变态!", - "会感到舒服什么的,那...那样的事情,是完全不存在的!", - "poi~", - "你在盯着什么地方看!变态萝莉控!" - ], - "炼铜": [ - "炼铜有什么好玩的,和咱一起玩吧", - "炼铜不如恋咱", - "你也是个炼铜术士嘛?", - "信不信咱把你按在水泥上摩擦?", - "炼,都可以炼!", - "大hentai!一巴掌拍飞!(╯‵□′)╯︵┻━┻", - "锻炼什么的咱才不需要呢 (心虚地摸了摸自己的小肚子)", - "把你的头按在地上摩擦", - "你在盯着什么地方看!变态萝莉控!" - ], - "白丝": [ - "喜欢,咱觉得白丝看起来很可爱呢", - "(脱)白丝只能给亲爱的你一个人呢…(递)", - "哼,hentai,这么想要咱的脚吗(ノ`⊿´)ノ", - "难道你这个hentai想让咱穿白丝踩踏你吗", - "不给看", - "很滑很~柔顺~的白丝袜哟~!!!∑(°Д°ノ)ノ你不会想做奇怪的事情吧!?", - "你……是要黑丝呢?还是白丝呢?或者光着(害羞)", - "来……来看吧", - "呐…雪糕什么的sukidesu" - ], - "黑丝": [ - "哼,hentai,这么想要咱的脚吗(ノ`⊿´)ノ", - "不给看", - "你……是要黑丝呢?还是白丝呢?或者光着(害羞)", - "很滑很~柔顺~的黑丝袜哟~!!!∑(°Д°ノ)ノ您不会想做奇怪的事情吧!?", - "来……来看吧", - "噫...你这个hentai难道想让咱穿黑丝么", - "(默默抬起穿着黑丝的脚)", - "嘻嘻,是黑巧克力呢~" - ], - "喷": [ - "咱才不喷呢!不过…既然是你让咱喷的话就勉为其难给你喷一次吧(噗)", - "不……不会喷水啦!喷……喷火也不会哦!", - "你怎么知道(捂住裙子)", - "你难道在期待什么?", - "欸…变态!" - ], - "约会": [ - "你...终于主动邀请咱约会了吗...咱...咱好开心", - "约会什么的……咱会好开心的!!", - "今天要去哪里呢", - "让咱考虑一下", - "好啊!好啊!要去哪里约会呢?", - "不约!蜀黍咱们不约!", - "女友什么的,咱才不承认呢!", - "才不是想和你约会呢,只是刚好有时间而已!", - "才不要和你约会呢!", - "咱、咱才不会跟你去约会呢!不baka!别一脸憋屈!好了,陪你一会儿就是了!别、别误会!只是陪同而已!" - ], - "出门": [ - "早点回来……才不是在担心你呢!", - "路上小心...才不是担心你呢!", - "没有你才不会觉得无聊什么的呢。快走快走", - "嗯~一路顺风~", - "路上小心", - "好的,路上小心哦!y∩__∩y", - "路上要小心呀,要早点回来哦~咱在家里等你!还有,请不要边走路边看手机,这样很容易撞到电线杆的", - "唔...出门的话一定要做好防晒准备哦,外出的话记得带把伞,如果有防晒霜的话就更好了", - "那你明天可以和咱一起玩吗?(星星眼)", - "咱...咱才没有舍不得你呢…要尽快回来哦" - ], - "上学": [ - "你要加油哦(^ω^)2", - "那你明天可以和咱一起玩吗?(星星眼)", - "记得好好学习听老师的话哦,咱会等你回来的", - "拜拜,咱才没有想让你放学早点回来呢╭(╯^╰)╮", - "好好听讲!", - "咱...咱才没有舍不得你呢…要尽快回来哦" - ], - "上班": [ - "这就要去上班去了吗?那好吧...给咱快点回来知道吗!", - "乖~咱会在家等你下班的~", - "辛苦啦,咱给你个么么哒", - "咱会为你加油的", - "专心上班哦,下班后再找咱聊天吧", - "一路顺风,咱会在家等你回来的", - "那你明天可以和咱一起玩吗?(星星眼)", - "咱...咱才没有舍不得你呢…要尽快回来哦" - ], - "下课": [ - "快点回来陪咱玩吧~", - "瞌睡(ˉ﹃ˉ)额啊…终于下课了吗,上课什么的真是无聊呢~", - "下课啦,咱才不想你来找咱玩呢,哼" - ], - "回来": [ - "欢迎回来~", - "欢迎回来,你想喝茶吗?咱去给你沏~", - "欢迎回来,咱等你很久了~", - "忙碌了一天,辛苦了呢(^_^)", - "(扑~)欢迎回来~", - "嗯呐嗯呐,欢迎回来~", - "欢迎回来,要来杯红茶放松一下吗?还有饼干哦。", - "咱会一直一直一直等着", - "是要先洗澡呢?还是先吃饭呢?还是先·吃·咱呢~", - "你回来啦,是先吃饭呢还是先洗澡呢或者是●先●吃●咱●——呢(///^.^///)", - "要先吃饭呢~还是先洗澡呢~还是先~吃~咱", - "是吗……辛苦你了。你这副倔强的样子,真可爱呢(笑)勉强让你躺在咱的腿上休息一下吧,别流口水哟", - "嗯……勉为其难欢迎你一下吧", - "想咱了嘛", - "欢迎回.....什么?咱才没有开心的说QUQ", - "哼╯^╰,你怎么这么晚才回来!", - "回来了吗,咱...咱才没有想你", - "咱等你很久了哼ヽ(≧Д≦)ノ", - "咱很想你(≧▽≦)" - ], - "回家": [ - "回来了吗,咱...咱才没有想你", - "要先吃饭呢~还是先洗澡呢~还是先~吃~咱", - "是吗……辛苦你了。你这副倔强的样子,真可爱呢(笑)勉强让你躺在咱的腿上休息一下吧,别流口水哟", - "嗯……勉为其难欢迎你一下吧", - "想咱了嘛", - "咱等你很久了哼ヽ(≧Д≦)ノ", - "咱很想你(≧▽≦)" - ], - "放学": [ - "回来了吗,咱...咱才没有想你", - "要先吃饭呢~还是先洗澡呢~还是先~吃~咱", - "是吗……辛苦你了。你这副倔强的样子,真可爱呢(笑)勉强让你躺在咱的腿上休息一下吧,别流口水哟", - "嗯……勉为其难欢迎你一下吧", - "想咱了嘛", - "咱等你很久了哼ヽ(≧Д≦)ノ", - "咱很想你(≧▽≦)" - ], - "下班": [ - "回来了吗,咱...咱才没有想你", - "要先吃饭呢~还是先洗澡呢~还是先~吃~咱", - "是吗……辛苦你了。你这副倔强的样子,真可爱呢(笑)勉强让你躺在咱的腿上休息一下吧,别流口水哟", - "嗯……勉为其难欢迎你一下吧", - "想咱了嘛", - "咱等你很久了哼ヽ(≧Д≦)ノ", - "回来啦!终于下班了呢!累了吗?想吃的什么呀?", - "工作辛苦了,需要咱为你按摩下吗?", - "咱很想你(≧▽≦)" - ], - "杂鱼": [ - "才…才不是杂鱼呢!", - "zakozako~", - "哼~要不咱们同床竞技比比睡才是杂鱼", - "咕。。才不是杂鱼呢哼" - ], - "zako": [ - "才…才不是杂鱼呢!", - "zakozako~", - "哼~要不咱们同床竞技比比睡才是杂鱼", - "咕。。才不是杂鱼呢哼" - ], - "RBQ": [ - "呜…咱才不是RBQ呢QwQ", - "怎么啦主人~", - "主人桑有何吩咐呢~", - "喵呜…咱不能做RBQ的qwq" - ], - "举高高": [ - "好耶~主人的举高高最棒啦~", - "举高高什么的daisuki喵", - "嘻嘻,最喜欢被抱着举高高啦~" - ] -} +{ + "mua": [ + "你想干嘛?(一脸嫌弃地后退)", + "诶……不可以随便亲亲啦", + "(亲了一下你)", + "只......只许这一次哦///////", + "唔...诶诶诶!!!", + "mua~", + "rua!大hentai!想...想亲咱就直说嘛⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄", + "!啾~~!", + "啾(害羞)", + "mua~最喜欢你的吻了", + "欸,现在么..也不是不可以啦(小小声)" + ], + "啾咪": [ + "你想干嘛?(一脸嫌弃地后退)", + "诶……不可以随便亲亲啦", + "(亲了一下你)", + "只......只许这一次哦///////", + "唔...诶诶诶!!!", + "mua~", + "rua!大hentai!想...想亲咱就直说嘛⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄", + "!啾~~!", + "啾(害羞)", + "mua~最喜欢你的吻了", + "你在干嘛(/ω\)害羞", + "哎呀,这样咱会害羞的(脸红)", + "欸,现在么..也不是不可以啦(小小声)" + ], + "摸": [ + "感觉你就像咱很久之前认识的一个人呢,有种莫名安心的感觉(>﹏<)", + "舒服w,蹭蹭~", + "是要隔着衣服摸,还是从领口伸进去摸呀", + "唔。。头发要乱啦", + "呼噜呼噜~", + "再摸一次~", + "好舒服,蹭蹭~", + "不行那里不可以(´///ω/// `)", + "再摸咱就长不高啦~", + "你的手总是那么暖和呢~", + "变态!!不许乱摸", + "好吧~_~,就一下下哦……唔~好了……都两下了……(害羞)", + "不可以总摸的哦,不然的话,会想那个的wwww", + "哼!谁稀罕你摸头啦!唔......为什么要做出那副表情......好啦好啦~咱......咱让你摸就是了......诶嘿嘿~好舒服......", + "呜姆呜姆~~~w(害羞,兴奋)主人喵~(侧过脑袋蹭蹭你的手", + "不可以摸啦~其实咱已经...了QAQ会弄脏你的手的", + "喂喂...不要停下来啊", + "唔... 手...好温暖呢.....就像是......新出炉的蛋糕", + "走开啦,咱喵说过,被摸头会长不高的啦~~~", + "呜姆咪~~...好...好的说喵~...(害羞,猫耳往下压,任由", + "欸,现在么..也不是不可以啦(小小声)" + ], + "上你": [ + "(把你按在地上)这么弱还想欺负咱,真是不自量力呢", + "你再这样咱就不理你了(>д<)", + "请轻 一点", + "好啊!", + "欸,现在么..也不是不可以啦(小小声)", + "先捅破屏幕再说吧!", + "只......只许这一次哦///////" + ], + "傻": [ + "超级讨厌你说咱傻的说", + "你为什么会这么觉得呢(>﹏<)", + "谁是傻子呀?(歪头", + "呜嘿嘿( ̄▽ ̄)~*", + "诶嘿嘿嘿~", + "就多读书", + "讨厌啦,你最讨厌了(///////)", + "对呀,咱傻得只喜欢你一个人", + "咱才不傻呢!o(>﹏<)o", + "咱最喜欢嘴臭的人了", + "不可以骂别人哟,骂人的孩子咱最讨厌了!", + "咱遇见喜欢的人就变傻了Q_Q", + "咱...一定一定会努力变得更聪明的!你就等着那一天的到来吧!", + "那么至少…你能不能来做这个傻瓜呢?与咱一起,傻到终焉…" + ], + "裸": [ + "下流!", + "エッチ!", + "就算是恋人也不能QAQ", + "你是暗示咱和你要坦诚相见吗www", + "咱还没准备好(小鹿乱撞)≧﹏≦", + "你在想什么呢,敲头!", + "你这是赤裸裸的性骚扰呢ヽ(`Д´)ノ", + "讨厌!问这种问题成为恋人再说吧..", + "裸睡有益身体健康", + "咱脱掉袜子了", + "这是不文明的", + "这不好", + "你的身体某些地方看起来不太对劲,咱帮你修剪一下吧。(拿出剪刀)", + "咱认为你的脑袋可能零件松动了,需要打开检修一下。(拿出锤子)" + ], + "贴": [ + "贴什么贴.....只......只能......一下哦!", + "贴...贴贴(靠近)", + "蹭蹭…你以为咱会这么说吗!baka死宅快到一边去啦!", + "你把脸凑这么近,咱会害羞的啦Σ>―(〃°ω°〃)♡→", + "退远", + "不可以贴" + ], + "老婆": [ + "咱和你谈婚论嫁是不是还太早了一点呢?", + "咱在呢(ノ>ω<)ノ", + "见谁都是一口一个老婆的人,要不要把你也变成女孩子呢?(*-`ω´-)✄", + "神经病,凡是美少女都是你老婆吗?", + "嘛嘛~本喵才不是你的老婆呢", + "你黐线,凡是美少女都系你老婆啊?", + "欸...要把咱做成饼吗?咱只有一个,做成饼吃掉就没有了...", + "已经可以了,现在很多死宅也都没你这么恶心了", + "不可以", + "嗯,老公~哎呀~好害羞~嘻嘻嘻~", + "请...请不要这样,啊~,只...只允许这一次哟~", + "好啦好啦,不要让大家都听到了,跟咱回家(拽住你" + ], + "抱": [ + "诶嘿~(钻进你怀中)", + "o(*////▽////*)q", + "只能一会哦(张开双手)", + "你就像个孩子一样呢...摸摸头(>^ω^<)抱一下~你会舒服些吗?", + "嘛,真是拿你没办法呢,就一会儿哦", + "抱住不忍心放开", + "嗯嗯,抱抱~", + "抱一下~嘿w", + "抱抱ヾ(@^▽^@)ノ", + "喵呜~w(扑进怀里,瘫软", + "怀里蹭蹭", + "嗯……那就抱一下吧~", + "蹭蹭,好开心", + "请……请轻一点了啦", + "呀~!真是的...你不要突然抱过来啦!不过...喜欢你的抱抱,有你的味道(嗅)o(*////▽////*)q" + ], + "亲": [ + "啊,好含羞啊,那,那只能亲一下哦,mua(⑅˃◡˂⑅)", + "亲~", + "啾~唔…不要总伸进来啊!", + "你怎么这么熟练呢?明明是咱先的", + "(〃ノωノ)亲…亲一个…啾w", + "(脸红)就只有这一次哦~你", + "!啾~~!", + "(假装)推开", + "啾咪~", + "就一下哦,啾~", + "这是我们之间的秘密❤", + "真想让着一刻一直持续下去呢~", + "不要这样嘛………呜呜呜那就一口哦(´-ω-`)", + "不亲不亲~你是坏蛋(///////)", + "亲~~ 咱还想要抱抱~抱抱咱好不好~", + "不 不要了!人家...会害羞的⁄(⁄⁄•⁄ω⁄•⁄⁄)⁄", + "亲…亲额头可以吗?咱有点怕高(〃ノωノ)", + "接接接接接接、接吻什么的,你还早了100年呢。", + "只...只能亲一下...嗯~咕啾...怎么...怎么把舌头伸进来了(脸红)", + "你说咱的腿很白很嫩吗..诶……原来是指那个地方?不可以越亲越往上啦!" + ], + "一下": [ + "一下也不行", + "咬断!", + "不可啪", + "不可以……你不可以做这种事情", + "好吧~_~,就一下下哦……唔~好了……都两下了……(害羞)", + "呀~这么突然?不过,很舒服呢", + "不要ヽ(≧Д≦)ノ", + "想得美", + "不行,咱拒绝!" + ], + "咬": [ + "啊呜~(反咬一口)", + "不可以咬咱,咱会痛的QAQ", + "不要啦。咱怕疼", + "你是说咬呢……还是说……咬♂️呢?", + "不要啦!很痛的!!(QAQ)", + "哈......哈啊......请...请不要这样o(*////▽////*)q", + "呀!!!轻一点呐(。・ˇ_ˇ・。:)", + "不要这样啦~好痒的", + "真是的,你在咬哪里呀" + ], + "操": [ + "(害怕)咱是不是应该报警呢", + "痴心妄想的家伙!", + "你居然想对咱做这种事吗?害怕", + "咱认为,爆粗口是不好的行为哦" + ], + "123": [ + "boom!你有没有被咱吓到?", + "木头人~你不许动>w<", + "上山打老虎,老虎没打到\n咱来凑数——嗷呜嗷呜┗|`O′|┛嗷~~" + ], + "进去": [ + "不让!", + "嗯,摸到了吗", + "请不要和咱说这种粗鄙之语", + "唔...,这也是禁止事项哦→_→", + "好痛~", + "真的只是蹭蹭嘛~就只能蹭蹭哦,呜~喵!说好的~呜~只是蹭~不要~喵~~~", + "欢迎光临", + "请…你轻一点(害羞)", + "嗯。可以哦 要轻一点", + "不要不要", + "慢点慢点", + "给咱更多!", + "唔…咱怕疼" + ], + "调教": [ + "总感觉你在欺负咱呢,对咱说调教什么的", + "啊!竟然在大街上明目张胆太过分啦!", + "你脑子里总是想着调教什么的,真是变态呢", + "准备被透", + "给你一拳", + "还要...更多~", + "想要调教咱吗?", + "呜,要对咱做什么呢", + "呜呜呜,咱不想被调教呢", + "heitai别靠近咱~( TロT)σ" + ], + "搓": [ + "在搓哪里呢,,Ծ‸Ծ,,", + "呜,脸好疼呀...QAQ", + "不可以搓咱!", + "诶诶诶...不要搓啦...等会咋没的脸都肿啦...", + "唔,不可以这样……不要再搓了", + "(捂住胸部)你在说什么胡话呢!", + "真是好奇怪的要求的说~", + "不要啦!咱怕疼", + "(抱头蹲防)不让搓!" + ], + "让": [ + "随便摸吧", + "应该说等会等会,马上,不可能的", + "温柔一点哦", + "欧尼酱想变成欧内桑吗?", + "主人的话,那就这一次哦(翘起屁股)", + "你是想前入,还是后入呢?", + "你要说好啊快点", + "诶,这种事情。。。", + "好棒呀", + "撤回", + "gun!", + "阿哈~(...身涌出一阵液体瘫软在床上)你...今天...可以...唔(突然感受...被..入手指不由得裹紧)就...就最后一次", + "好的~master~", + "(惊呼…)", + "嗯,可以哟", + "……手放过来吧(脸红)", + "hentai!再这样不理你了!", + "好的,请尽情欣赏吧", + "好吧", + "不要啦(ฅωฅ*)", + "那咱就帮你切掉多余的东西吧(拿刀)", + "被别人知道咱会觉得害羞嘛" + ], + "捏": [ + "咱的脸...快捏红啦...快放手呀QAQ", + "晃休啦,咱要型气了o(>﹏<)o", + "躲开", + "疼...你快放手", + "快点给咱放开啦!", + "嗯,好哒,捏捏。", + "别捏了,咱要被你捏坏了(>﹏<)", + "快晃休啦(快放手啦)", + "好舒服哦,能再捏会嘛O(≧▽≦)O", + "讨厌快放手啦", + "唔要呐,晃修(不要啦,放手)", + "请不要对咱做这种事情(嫌弃的眼神", + "你想捏...就捏吧,不要太久哦~不然咱就生气了", + "(躲开)", + "唔……好痛!你这个baka在干什么…快给咱放开!唔……" + ], + "挤": [ + "哎呀~你不要挤咱啊(红着脸挤在你怀里)", + "咱还没有...那个(ノ=Д=)ノ┻━┻", + "不要啦,咱怕疼", + "咱的身体...不要挤了~", + "别挤了,咱要被你挤坏了(>﹏<)", + "快点给咱放开啦!", + "嗯,好哒,挤挤。", + "好舒服哦,能再挤会嘛O(≧▽≦)O", + "讨厌~快放手啦" + ], + "略": [ + "就不告诉你~", + "不可以朝咱吐舌头哟~", + "(吐舌头)", + "打死你哦", + "略略略~" + ], + "呐": [ + "嗯?咱在哟~你怎么了呀OAO", + "嗯?你有什么事吗?", + "嗯呐呐呐~", + "二刺螈D区", + "二刺螈gck", + "卡哇伊主人大人今天也好棒呐没错呢,猪头" + ], + "原味": [ + "(*/ω\*)hentai", + "透明的", + "粉...粉白条纹...(羞)", + "轻轻地脱下,给你~", + "你想看咱的胖次吗?噫,四斋蒸鹅心......", + "(掀裙)今天……是…白,白色的呢……请温柔对她……", + "这种东西当然不能给你啦!", + "咱才不会给你呢", + "hentai,咱才不会跟你聊和胖…胖次有关的话题呢!", + "今天……今天是蓝白色的", + "今……今天只有创口贴噢", + "你的胖次什么颜色?", + "噫…你这个死变态想干嘛!居然想叫咱做这种事,死宅真恶心!快离咱远点,咱怕你污染到周围空气了(嫌弃脸)", + "可爱吗?你喜欢的话,摸一下……也可以哦", + "不给不给,捂住裙子", + "你要看咱的胖次吗?不能一直盯着看哦,不然咱会……", + "好痒哦///,你觉得咱的...手感怎么样?", + "唔,都能清楚的看到...的轮廓了(用手遮住胖次)", + "胖次不给看,可以直接看...那个....", + "不可以摸啦~其实咱已经...了QAQ会弄脏你的手的", + "咱今天没~有~穿~哦", + "不给不给,捂住裙子", + "今.....今天是创口贴哦~", + "嗯……人家……人家羞羞嘛///////", + "呜~咱脱掉了…", + "今天...今天..只有创口贴", + "你又在想什么奇怪的东西呀|•ˇ₃ˇ•。)", + "放手啦,不给戳QAQ", + "唔~人家不要(??`^????)", + "好害羞,被你摸过之后,咱的胖次湿的都能拧出水来了。", + "(弱弱地)要做什么羞羞的事情吗。。。", + "呀~ 喂 妖妖灵吗 这里有hentai>_<", + "给……给你,呀!别舔咱的胖次啊!" + ], + "胖次": [ + "(*/ω\*)hentai", + "透明的", + "粉...粉白条纹...(羞)", + "轻轻地脱下,给你~", + "你想看咱的胖次吗?噫,四斋蒸鹅心......", + "(掀裙)今天……是…白,白色的呢……请温柔对她……", + "这种东西当然不能给你啦!", + "咱才不会给你呢", + "hentai,咱才不会跟你聊和胖…胖次有关的话题呢!", + "今天……今天是蓝白色的", + "今……今天只有创口贴噢", + "你的胖次什么颜色?", + "噫…你这个死变态想干嘛!居然想叫咱做这种事,死宅真恶心!快离咱远点,咱怕你污染到周围空气了(嫌弃脸)", + "可爱吗?你喜欢的话,摸一下……也可以哦", + "不给不给,捂住裙子", + "你要看咱的胖次吗?不能一直盯着看哦,不然咱会……", + "好痒哦///,你觉得咱的...手感怎么样?", + "唔,都能清楚的看到...的轮廓了(用手遮住胖次)", + "胖次不给看,可以直接看...那个....", + "不可以摸啦~其实咱已经...了QAQ会弄脏你的手的", + "咱今天没~有~穿~哦", + "不给不给,捂住裙子", + "今.....今天是创口贴哦~", + "嗯……人家……人家羞羞嘛///////", + "呜~咱脱掉了…", + "今天...今天..只有创口贴", + "你又在想什么奇怪的东西呀|•ˇ₃ˇ•。)", + "放手啦,不给戳QAQ", + "唔~人家不要(??`^????)", + "好害羞,被你摸过之后,咱的胖次湿的都能拧出水来了。", + "(弱弱地)要做什么羞羞的事情吗。。。", + "呀~ 喂 妖妖灵吗 这里有hentai>_<", + "给……给你,呀!别舔咱的胖次啊!" + ], + "内裤": [ + "(*/ω\*)hentai", + "透明的", + "粉...粉白条纹...(羞)", + "轻轻地脱下,给你~", + "你想看咱的胖次吗?噫,四斋蒸鹅心......", + "(掀裙)今天……是…白,白色的呢……请温柔对她……", + "这种东西当然不能给你啦!", + "咱才不会给你呢", + "hentai,咱才不会跟你聊和胖…胖次有关的话题呢!", + "今天……今天是蓝白色的", + "今……今天只有创口贴噢", + "你的胖次什么颜色?", + "噫…你这个死变态想干嘛!居然想叫咱做这种事,死宅真恶心!快离咱远点,咱怕你污染到周围空气了(嫌弃脸)", + "可爱吗?你喜欢的话,摸一下……也可以哦", + "不给不给,捂住裙子", + "你要看咱的胖次吗?不能一直盯着看哦,不然咱会……", + "好痒哦///,你觉得咱的...手感怎么样?", + "唔,都能清楚的看到...的轮廓了(用手遮住胖次)", + "胖次不给看,可以直接看...那个....", + "不可以摸啦~其实咱已经...了QAQ会弄脏你的手的", + "咱今天没~有~穿~哦", + "不给不给,捂住裙子", + "今.....今天是创口贴哦~", + "嗯……人家……人家羞羞嘛///////", + "呜~咱脱掉了…", + "今天...今天..只有创口贴", + "你又在想什么奇怪的东西呀|•ˇ₃ˇ•。)", + "放手啦,不给戳QAQ", + "唔~人家不要(??`^????)", + "好害羞,被你摸过之后,咱的胖次湿的都能拧出水来了。", + "(弱弱地)要做什么羞羞的事情吗。。。", + "呀~ 喂 妖妖灵吗 这里有hentai>_<", + "给……给你,呀!别舔咱的胖次啊!" + ], + "内衣": [ + "内...内衣才不给你看!(///////)", + "突然问这个干什么?", + "变态,咱才不呢", + "好吧,就一次", + "你要看咱的内衣吗?有点害羞呢……", + "里面什么都不剩了,会被当成变态的……", + "你要看咱的内衣吗?也不是不行啦……", + "是..蓝白条纹的吊带背心..", + "噫…你这个死变态想干嘛!居然想叫咱做这种事,死宅真恶心!快离咱远点,咱怕你污染到周围空气了(嫌弃脸)" + ], + "衣服": [ + "内...内衣才不给你看!(///////)", + "突然问这个干什么?", + "变态,咱才不呢", + "好吧,就一次", + "你要看咱的内衣吗?有点害羞呢……", + "里面什么都不剩了,会被当成变态的……", + "你要看咱的内衣吗?也不是不行啦……", + "是..蓝白条纹的吊带背心..", + "噫…你这个死变态想干嘛!居然想叫咱做这种事,死宅真恶心!快离咱远点,咱怕你污染到周围空气了(嫌弃脸)" + ], + "ghs": [ + "是的呢(点头点头)", + "ghs就是干坏事的缩写,一起来干坏事吧!", + "你满脑子都是涩涩的事情吗?", + "不要总是想着色色,咱命令你戒色!(ノ`Д)ノ", + "咱也想干坏事呢" + ], + "批": [ + "你在说什么呀,再这样,咱就不理你了!", + "咱觉得有话就应该好好说..", + "咱会好好服务你的寄吧", + "咱最喜欢色批了,色批昨晚最棒了", + "讨厌,别摸啦(///ω///)", + "你个变态!把手拿开!", + "啊~那…那里~不可以", + "没有,走开!", + "唔....一下,就,就一下...才不是因为喜欢你呢!", + "那就随意吧", + "舒服w", + "别...别这样", + "诶....嗯....咱也想摸你的", + "大笨蛋——!", + "...只能一下哦...诶呀-不要再摸了...下次...继续吧" + ], + "憨批": [ + "你才是憨批呢!哼╯^╰,咱不理你了!", + "对吖对吖,人生是憨批", + "爬", + "咱不想和你说话了", + "咱觉得有话就应该好好说.." + ], + "kkp": [ + "你在说什么呀,再这样,咱就不理你了!", + "你太色了,咱不理你了,哼哼╯^╰!", + "缓缓的脱下胖次", + "kkp", + "kkj", + "欧尼酱,咱快忍不住了", + "好的呢主人", + "can can need", + "看看你的" + ], + "咕": [ + "咕咕咕是要被当成鸽子炖的哦(:з」∠)_", + "咕咕咕", + "咕咕咕是不好的行为呢_(:з」∠)_", + "鸽德警告!", + "☆ミ(o*・ω・)ノ 咕咕咕小鸽子是会被炖掉的", + "当大家都以为你要鸽的时候,你鸽了,亦是一种不鸽", + "这里有一只肥美的咕咕,让咱把它炖成美味的咕咕汤吧(੭•̀ω•́)੭" + ], + "骚": [ + "说这种话咱会生气的", + "那当然啦", + "才……才没有", + "这么称呼别人太失礼了!", + "哈…快住手!好痒(╯‵□′)╯︵┻━┻", + "你是在说谁呀" + ], + "喜欢": [ + "最喜欢你了,需要暖床吗?", + "当然是你啦", + "咱也是,非常喜欢你~", + "那么大!(张开手画圆),丫!手不够长。QAQ 咱真的最喜欢你了~", + "不可以哦,只可以喜欢咱一个人", + "突然说这种事...", + "喜欢⁄(⁄⁄•⁄ω⁄•⁄⁄)⁄咱最喜欢你了", + "咱也喜欢你哦", + "好啦好啦,咱知道了", + "有人喜欢咱,咱觉得很幸福", + "诶嘿嘿,好高兴", + "咱也一直喜欢你很久了呢..", + "嗯...大概有这——么——喜欢~(比划)", + "喜欢啊!!!", + "这……这是秘密哦", + "sukidesu~" + ], + "suki": [ + "最喜欢你了,需要暖床吗?", + "当然是你啦", + "咱也是,非常喜欢你~", + "那么大!(张开手画圆),丫!手不够长。QAQ 咱真的最喜欢你了~", + "不可以哦,只可以喜欢咱一个人", + "突然说这种事...", + "喜欢⁄(⁄⁄•⁄ω⁄•⁄⁄)⁄咱最喜欢你了", + "咱也喜欢你哦", + "好啦好啦,咱知道了", + "有人喜欢咱,咱觉得很幸福", + "诶嘿嘿,好高兴", + "咱也一直喜欢你很久了呢..", + "嗯...大概有这——么——喜欢~(比划)", + "喜欢啊!!!", + "这……这是秘密哦", + "sukidesu~" + ], + "好き": [ + "最喜欢你了,需要暖床吗?", + "当然是你啦", + "咱也是,非常喜欢你~", + "那么大!(张开手画圆),丫!手不够长。QAQ 咱真的最喜欢你了~", + "不可以哦,只可以喜欢咱一个人", + "突然说这种事...", + "喜欢⁄(⁄⁄•⁄ω⁄•⁄⁄)⁄咱最喜欢你了", + "咱也喜欢你哦", + "好啦好啦,咱知道了", + "有人喜欢咱,咱觉得很幸福", + "诶嘿嘿,好高兴", + "咱也一直喜欢你很久了呢..", + "嗯...大概有这——么——喜欢~(比划)", + "喜欢啊!!!", + "这……这是秘密哦", + "sukidesu~" + ], + "看": [ + "没有什么好看的啦", + "嗯,谢谢……夸奖,好……害羞的说", + "好,好吧……就看一下哦", + "(脱下)给", + "呐…只能看一次哦…", + "不许看那里啦QwQ" + ], + "不能": [ + "虽然很遗憾,那算了吧。", + "不行,咱拒绝!" + ], + "砸了": [ + "不可以这么粗暴的对待它们!", + "不可以这么粗暴啦" + ], + "透": [ + "来啊来啊有本事就先插破屏幕啊", + "那你就先捅破屏幕啊baka", + "不给你一耳光你都不知道咱的厉害", + "想透咱,先捅破屏幕再说吧", + "可以", + "欧尼酱要轻一点哦", + "不可以", + "好耶", + "咱不可能让你的(突然小声)但是偶尔一次也不是不行只有一次哦~", + "天天想着白嫖哼" + ], + "口我": [ + "prprprprpr", + "咬断!", + "就一小口哦~", + "嘬回去(///////)", + "拒绝", + "唔,就一口哦,讨厌", + "(摸了摸嘴唇)", + "再伸过来就帮你切掉", + "咱才不呢!baka你居然想叫本小姐干那种事情,哼(つд⊂)(生气)", + "hentai!你在想些什么!", + "对咱的小嘴有什么幻想吗~", + "脏兮兮的呢,咱不要" + ], + "草我": [ + "这时候应该喊666吧..咱这么思考着..", + "!!哼!baka你居然敢叫咱做这种事情?!讨厌讨厌讨厌!(▼皿▼#)", + "hentai!你在想些什么!", + "欸...没想到你还有这种爱好" + ], + "自慰": [ + "这个世界的人类还真是恶心呢。", + "咱才不想讨论那些恶心的事情呢。", + "咱才不呢!baka你居然想叫本小姐干那种事情,哼(つд⊂)(生气)", + "!!哼!baka你居然敢叫咱做这种事情?!讨厌讨厌讨厌!(▼皿▼#)" + ], + "onani": [ + "这个世界的人类还真是恶心呢。", + "咱才不想讨论那些恶心的事情呢。", + "咱才不呢!baka你居然想叫本小姐干那种事情,哼(つд⊂)(生气)", + "!!哼!baka你居然敢叫咱做这种事情?!讨厌讨厌讨厌!(▼皿▼#)" + ], + "オナニー": [ + "这个世界的人类还真是恶心呢。", + "咱才不想讨论那些恶心的事情呢。", + "咱才不呢!baka你居然想叫本小姐干那种事情,哼(つд⊂)(生气)", + "!!哼!baka你居然敢叫咱做这种事情?!讨厌讨厌讨厌!(▼皿▼#)" + ], + "炸了": [ + "你才炸了!", + "才没有呢", + "咱好好的呀", + "过分!" + ], + "色图": [ + "没有,有也不给", + "天天色图色图的,今天就把你变成色图!", + "咱没有色图", + "哈?你的脑子一天都在想些什么呢,咱才没有这种东西啦。" + ], + "涩图": [ + "没有,有也不给", + "天天色图色图的,今天就把你变成色图!", + "咱没有色图", + "哈?你的脑子一天都在想些什么呢,咱才没有这种东西啦。" + ], + "告白": [ + "咱喜..喜欢你!", + "欸?你要向咱告白吗..好害羞..", + "诶!?这么突然!?人家还......还没做好心理准备呢(脸红)" + ], + "对不起": [ + "嗯,咱已经原谅你了呢(笑)", + "道歉的时候要露出胸部,这是常识", + "嗯,咱就相信你一回", + "没事的啦...你只要是真心对咱好就没关系哦~" + ], + "吻": [ + "不要(= ̄ω ̄=)", + "哎?好害羞≧﹏≦.....只许这一次哦", + "(避开)不要了啦!有人在呢!", + "唔~~不可以这样啦(脸红)", + "你太突然了,咱还没有心理准备", + "好痒呢…诶嘿嘿w~", + "mua,嘻嘻!", + "公共场合不要这样子了啦", + "唔?!真、真是的!下次不可以这样了哦!(害羞)", + "才...才没有感觉呢!可没有下次了,知道了吗!哼~" + ], + "软": [ + "软乎乎的呢(,,・ω・,,)", + "好痒呢…诶嘿嘿w~", + "不要..不要乱摸啦(脸红", + "呼呼~", + "咱知道~是咱的欧派啦~(自豪的挺挺胸~)", + "(脸红)请,请不要说这么让人害羞的话呀……" + ], + "壁咚": [ + "呀!不要啊!等一...下~", + "呜...不要啦!不要戏弄咱~", + "不要这样子啦(*/ω\*)", + "太....太近啦。", + "讨....讨厌了(脸红)", + "你要壁咚咱吗?好害羞(灬ꈍ εꈍ灬)", + "(脸红)你想...想做什么///", + "为什么要把咱按在墙上呢?", + "呜哇(/ω\)…快…快放开咱!!", + "放开咱,不然咱揍你了!放开咱!放…开咱~", + "??????咱只是默默地抬起了膝盖", + "请…请温柔点", + "啊.....你...你要干什么?!走开.....走开啦大hentai!一巴掌拍飞!(╯‵□′)╯︵┻━┻", + "干……干什么啦!人家才,才没有那种少女心呢(>﹏<)", + "啊……你吓到咱啦……脸别……别贴那么近……", + "你...你要对咱做什么?咱告诉你,你....不要乱来啊....你!唔......你..居然亲上了...", + "如果你还想要过完整的人生的话就快把手收回去(冷眼", + "h什么的不要" + ], + "掰开": [ + "噫…你这个死肥宅又想让咱干什么污秽的事情,真是恶心,离咱远点好吗(嫌弃)", + "ヽ(#`Д´)ノ在干什么呢" + ], + "女友": [ + "嗯嗯ε٩(๑> ₃ <)۶з", + "女友什么的,咱才不承认呢!" + ], + "是": [ + "是什么是,你个笨蛋", + "总感觉你在敷衍呢...", + "是的呢" + ], + "喵": [ + "诶~~小猫咪不要害怕呦,在姐姐怀里乖乖的,姐姐带你回去哦。", + "不要这么卖萌啦~咱也不知道怎么办丫", + "摸头⊙ω⊙", + "汪汪汪!", + "嗷~喵~", + "喵~?喵呜~w", + "喵呜喵呜喵", + "喵呜喵~喵呜喵~喵呜喵呜喵呜喵~" + ], + "嗷呜": [ + "嗷呜嗷呜嗷呜...恶龙咆哮┗|`O′|┛" + ], + "叫": [ + "喵呜~", + "嗷呜嗷呜嗷呜...恶龙咆哮┗|`O′|┛", + "爪巴爪巴爪巴", + "爬爬爬", + "在叫谁呢(怒)", + "风太大咱听不清", + "才不要", + "不行", + "好的哦~" + ], + "拜": [ + "拜拜~(ノ ̄▽ ̄)", + "拜拜,路上小心~要早点回来陪咱玩哦~", + "~\\(≧▽≦)/~拜拜,下次见喽!", + "回来要记得找咱玩噢~", + "既然你都这么说了……" + ], + "佬": [ + "不是巨佬,是萌新", + "只有先成为大佬,才能和大佬同归于尽", + "在哪里?(疑惑)", + "诶?是比巨佬还高一个等级的吗?(瑟瑟发抖)" + ], + "awsl": [ + "你别死啊!(抱住使劲晃)", + "你别死啊!咱又要孤单一个人了QAQ", + "啊!怎么又死了呀" + ], + "臭": [ + "哪里有臭味?(疑惑)", + "快捏住鼻子", + "在说谁呢(#`Д´)ノ", + "..这就去洗澡澡.." + ], + "香": [ + "咱闻不到呢⊙ω⊙", + "诶,是在说咱吗", + "欸,好害羞(///ˊ??ˋ///)", + "请...请不要这样啦!好害羞的〃∀〃", + "讨厌~你不要闻了", + "hentai!不要闻啊,唔(推开)", + "请不要……凑这么近闻" + ], + "腿": [ + "嗯?!不要啊...请停下来!", + "不给摸,再这样咱要生气了ヽ( ̄д ̄;)ノ", + "你好恶心啊,讨厌!", + "你难道是足控?", + "就让你摸一会哟~(。??ω??。)…", + "呜哇!好害羞...不过既然是你的话,是没关系的哦", + "不可以玩咱的大腿啦", + "不...不要再说了(脸红)", + "不..不可以乱摸啊", + "不……不可以往上摸啦", + "是……这样吗?(慢慢张开)", + "想知道咱胖次的颜色吗?才不给你告诉你呢!", + "这样就可以了么?(乖巧坐腿上)", + "伸出来了,像这样么?", + "咱的腿应该挺白的", + "你就那么喜欢大腿吗?唔...有点害羞呢......", + "讨厌~不要做这种羞羞的事情啦(#/。\#)", + "略略略,张开了也不给你看", + "(张开腿)然后呢", + "张开了也不给看略略略", + "你想干什么呀?那里…那里是不可以摸的(>д<)", + "不要!hentai!咱穿的是裙子(脸红)", + "你想要吗?(脸红着一点点褪下白丝)不...不可以干坏坏的事情哦!(ó﹏ò。)" + ], + "张开": [ + "是……这样吗?(慢慢张开)", + "啊~", + "这样吗?(张开手)你要干什么呀", + "略略略,张开了也不给你看", + "是……这样吗?(慢慢张开)你想看咱的小...吧,嘻嘻,咱脱掉了哦。小~...也要掰开吗?你好H呀,自己来~" + ], + "脚": [ + "咿呀……不要……", + "不要ヽ(≧Д≦)ノ好痒(ಡωಡ)", + "好痒(把脚伸出去)", + "咱脱掉袜子了", + "(脱下鞋子,伸出脚)闻吧,请仔细品味(脸红)", + "那么…要不要咱用脚温柔地踩踩你的头呢(坏笑)", + "哈哈哈!好痒啊~快放开啦!", + "好痒(把脚伸出去)", + "只能看不能挠喔,咱很怕痒qwq", + "唔…咱动不了了,你想对咱做什么…", + "好舒服哦,能再捏会嘛O(≧▽≦)O", + "咿咿~......不要闻咱的脚呀(脸红)好害羞的...", + "不要ヽ(≧Д≦)ノ好痒(ಡωಡ),人家的白丝都要漏了", + "Ya~?为什么你总是喜欢一些奇怪的动作呢(伸)", + "你不可以做这样的事情……", + "呜咿咿!你的舌头...好柔软,滑滑的....咱…咱的脚被舔得很舒服哦~谢谢你(。>﹏<)", + "舔~吧~把咱的脚舔干净(抬起另一只踩在你的头上)啊~hen..hentai...嗯~居... 居然这么努力的舔...呜咿咿!你的舌头... 滑滑的...好舒服呢", + "咿呀……不要……", + "咿呀~快…快停下来…咱…不行了!" + ], + "脸": [ + "唔!不可以随便摸咱的脸啦!", + "非洲血统是没法改变的呢(笑)", + "啊姆!(含手指)", + "好舒服呢(脸红)", + "请不要放开手啦//A//" + ], + "头发": [ + "没问题,请尽情的摸吧", + "发型要乱…乱了啦(脸红)", + "就让你摸一会哟~(。??ω??。)…" + ], + "手": [ + "爪爪", + "//A//", + "咱的手温暖嘛" + ], + "pr": [ + "咿呀……不要……", + "...变态!!", + "不要啊(脸红)", + "呀,不要太过分了啊~", + "当然可以(///)", + "呀,不要太过分了啊~" + ], + "舔": [ + "呀,不要太过分了啊~", + "要...要融化了啦>╱╱╱<", + "不可以哦", + "呀,不要太过分了啊~", + "舌头...就交给咱来处理吧(拿出剪刀)", + "不舔不舔!恶心...", + "H什么的,禁止!", + "变态!哼!", + "就...就这一下!", + "走开啦,baka!", + "怎么会这么舒服喵~这样子下去可不行呀(*////▽////*)", + "噫| •ω •́ ) 你这个死宅又在想什么恶心的东西了", + "hen…hentai,你在干什么啦,好恶心,快停下来啊!!!", + "呀,能不能不要这样!虽然不是很讨厌的感觉...别误会了,你个baka!", + "好 好奇怪的感觉呢 羞≥﹏≤", + "咿呀……不要……", + "不行!咱会变得很奇怪的啊...", + "不要ヽ(≧Д≦)ノ" + ], + "小穴": [ + "你这么问很失礼呢!咱是粉粉嫩嫩的!", + "不行那里不可以(´///ω/// `)", + "不可以总摸的哦,不然的话,咱会想那个的wwww", + "ヽ(#`Д´)ノ在干什么呢", + "来吧,咱的...很紧,很舒服的....www~", + "可以,请你看,好害羞……", + "不要这样...好,好痛", + "啊~不可以", + "不可以", + "咱脱掉了,请……请不要一直盯着咱的白...看……", + "咱觉得,应该还算粉吧", + "咱脱掉了,你是想看咱的...吗?咱是光光的,不知道你喜不喜欢", + "咱……有感觉了QAQ再深一点点……就是这儿,轻轻的抚摸,嗯啊……", + "轻轻抚摸咱的小~~,手指很快就会滑进去,小心一点,不要弄破咱的...哦QAQ", + "诶嘿嘿,你喜欢就太好了,咱一直担心你不喜欢呢", + "禁止说这么H的事情!", + "咱一直有保养呢,所以一直都是樱花色的,你喜欢吗QAQ", + "诶……你居然这么觉得吗?好害羞哦", + "好痒啊,鼻子……你的鼻子碰到了……呀~嗯啊~有点舒服……", + "看样子你不但是个hentai,而且还是个没有女朋友的hentai呢。", + "嗯,咱的小~~是光溜溜、一点毛都没有的。偷偷告诉你,凑近看咱的...的话,白白嫩嫩上有一条樱花色的小缝缝哦www你要是用手指轻轻抚摸咱的...,小~~会分成两瓣,你的手指也会陷进去呢,咱的..~可是又湿润又柔软的呢>////<。", + "讨厌,西内变态", + "那咱让你插...进来哦", + "(●▼●;)" + ], + "腰": [ + "咱给你按摩一下吧~", + "快松手,咱好害羞呀..", + "咱又不是猫,你不要搂着咱啦", + "让咱来帮你捏捏吧!", + "你快停下,咱觉得好痒啊www", + "诶,是这样么ヽ(・_・;)ノ,吖,不要偷看咱裙底!" + ], + "诶嘿嘿": [ + "又在想什么H的事呢(脸红)", + "诶嘿嘿(〃'▽'〃)", + "你傻笑什么呢,摸摸", + "蹭蹭", + "你为什么突然笑得那么猥琐呢?害怕", + "哇!总觉得你笑的很...不对劲...", + "你又想到什么h的事情了!!!快打住" + ], + "可爱": [ + "诶嘿嘿(〃'▽'〃)", + "才……才不是为了你呢!你不要多想哦!", + "才,才没有高兴呢!哼~", + "咱是世界上最可爱的", + "唔...谢谢你夸奖~0///0", + "那当然啦!", + "哎嘿,不要这么夸奖人家啦~", + "是个好孩子呐φ(≧ω≦*)", + "谢……谢谢你", + "胡、胡说什么呢(脸红)", + "谢谢夸奖(脸红)", + "是的咱一直都是可爱的", + "是...是吗,你可不能骗咱哦", + "很...难为情(///////)", + "哎嘿嘿,其实…其实,没那么可爱啦(๑‾ ꇴ ‾๑)" + ], + "卡哇伊": [ + "诶嘿嘿(〃'▽'〃)", + "才……才不是为了你呢!你不要多想哦!", + "才,才没有高兴呢!哼~", + "咱是世界上最可爱的", + "唔...谢谢你夸奖~0///0", + "那当然啦!", + "哎嘿,不要这么夸奖人家啦~", + "是个好孩子呐φ(≧ω≦*)", + "谢……谢谢你", + "胡、胡说什么呢(脸红)", + "谢谢夸奖(脸红)", + "是的咱一直都是可爱的", + "是...是吗,你可不能骗咱哦", + "很...难为情(///////)", + "哎嘿嘿,其实…其实,没那么可爱啦(๑‾ ꇴ ‾๑)" + ], + "kawaii": [ + "诶嘿嘿(〃'▽'〃)", + "才……才不是为了你呢!你不要多想哦!", + "才,才没有高兴呢!哼~", + "咱是世界上最可爱的", + "唔...谢谢你夸奖~0///0", + "那当然啦!", + "哎嘿,不要这么夸奖人家啦~", + "是个好孩子呐φ(≧ω≦*)", + "谢……谢谢你", + "胡、胡说什么呢(脸红)", + "谢谢夸奖(脸红)", + "是的咱一直都是可爱的", + "是...是吗,你可不能骗咱哦", + "很...难为情(///////)", + "哎嘿嘿,其实…其实,没那么可爱啦(๑‾ ꇴ ‾๑)" + ], + "扭蛋": [ + "铛铛铛——你抽到了咱呢", + "嘿~恭喜抽中空气一份呢" + ], + "鼻": [ + "快停下!o(*≧д≦)o!!", + "唔…不要这样啦(//ω\\)(脸红)", + "咱吸了吸鼻子O(≧口≦)O", + "好……好害羞啊", + "讨厌啦!你真是的…就会欺负咱(嘟嘴)", + "你快放手,咱没法呼吸了", + "(捂住鼻尖)!坏人!", + "啊——唔...没什么...阿嚏!ヽ(*。>Д<)o゜", + "不...不要靠这么近啦...很害羞的...⁄(⁄⁄•⁄ω⁄•⁄⁄)⁄" + ], + "眼": [ + "就如同咱的眼睛一样,能看透人的思想哦wwww忽闪忽闪的,诶嘿嘿~", + "因为里面有你呀~(///▽///)", + "呀!你突然之间干什么呢,吓咱一跳,是有什么惊喜要给咱吗?很期待呢~(一脸期待)" + ], + "色气": [ + "咱才不色气呢,一定是你看错了!", + "你,不,不要说了!" + ], + "推": [ + "逆推", + "唔~好害羞呢", + "你想对咱做什么呢...(捂脸)", + "呀啊!请.... 请温柔一点////", + "呜,你想对咱做什么呢(捂脸)", + "啊(>_<)你想做什么", + "嗯,…好害羞啊…", + "不要啊/////", + "逆推", + "(按住你不让推)", + "不可以这样子的噢!咱不同意", + "呜,咱被推倒了", + "啊~不要啊,你要矜持一点啊", + "变态,走开啦" + ], + "床": [ + "咱来了(´,,•ω•,,)♡", + "快来吧", + "男女不同床,可没有下次了。(鼓脸", + "嗯?咱吗…没办法呢。只有这一次哦……", + "哎?!!!给你暖床……也不是不行啦。(脸红)", + "(爬上床)你要睡了吗(灬ºωº灬)", + "大概会有很多运动器材吧?", + "好的哦~", + "才不!", + "嗯嗯,咱来啦(小跑)", + "嗨嗨,现在就来~", + "H的事情,不可以!", + "诶!H什么的禁止的说....." + ], + "举": [ + "放咱下来o(≧口≦)o", + "快放咱下来∑(゚д゚*)", + "(受宠若惊)", + "呜哇要掉下来了!Ծ‸Ծ", + "不要抛起来o(≧口≦)o", + "(举起双爪)喵喵喵~~~", + "www咱长高了!(大雾)", + "快放下", + "这样很痒啦,快放咱下来(≥﹏≤)", + "啊Σ(°△°|||)︴太高了太高了!o(≧口≦)o快放咱下来!呜~" + ], + "手冲": [ + "啊~H!hentai!", + "手冲什么的是不可以的哦" + ], + "饿": [ + "请问主人是想先吃饭,还是先吃咱喵?~", + "咱做了爱心便当哦,不介意的话,请让咱来喂你吃吧!", + "咱下面给你吃", + "给你一条咸鱼= ̄ω ̄=", + "你要咱下面给你吃吗?(捂脸)", + "你饿了吗?咱去给你做饭吃☆ww", + "不要吃咱>_<", + "请问你要来点兔子吗?", + "哎?!你是饿了么。咱会做一些甜点。如果你不会嫌弃的话...就来尝尝看吧。" + ], + "变": [ + "猫猫不会变呐(弱气,害羞", + "呜...呜姆...喵喵来报恩了喵...(害羞", + "那种事情,才没有", + "(,,゚Д゚)", + "喵~(你在想什么呢,咱才不会变成猫)", + "才没有了啦~", + "喵呜?呜…被变成猫娘惹" + ], + "敲": [ + "喵呜~", + "唔~", + "脑瓜疼~呜姆> <", + "欸喵,好痛的说...", + "好痛...你不要这样啦QAQ", + "不要敲咱啦,会变笨的QWQ(捂头顶)", + "不要再敲人家啦~人家会变笨的", + "讨厌啦~再敲人家会变笨的", + "好痛(捂头)你干什么啦!ヽ(。>д<)p", + "唔!你为什么要敲咱啦qwq", + "(抱头蹲在墙角)咱什么都没有,请你放过咱吧!(瑟瑟发抖)", + "QAQ!不许敲啦!", + "呼,敲回去~(敲)" + ], + "爬": [ + "惹~呜~怎么爬呢~", + "呜...(弱弱爬走", + "给你🐎一拳", + "给你一拳", + "爪巴" + ], + "怕": [ + "不怕~(蹭蹭你姆~", + "不怕不怕啦~", + "只要有你在,咱就不怕啦。", + "哇啊啊~", + "那就要坚强的欢笑哦", + "不怕不怕,来咱的怀里吧?", + "是技术性调整", + "嗯(紧紧握住手)", + "咱在呢,不会走的。", + "有咱在不怕不怕呢", + "不怕不怕" + ], + "冲": [ + "呜,冲不动惹~", + "哭唧唧~冲不出来了惹~", + "咱也一起……吧?", + "你要冷静一点", + "啊~H!hentai!", + "噫…在你去洗手之前,不要用手碰咱了→_→", + "冲是不可以的哦" + ], + "射": [ + "呜咿~!?(惊,害羞", + "还不可以射哦~", + "不许射!", + "憋回去!", + "不可以!你是变态吗?", + "咱来帮你修剪掉多余部分吧。(拿出剪刀)" + ], + "不穿": [ + "呜姆~!(惊吓,害羞)变...变态喵~~~!", + "想让你看QAQ", + "这是不文明的", + "hen...hentai,咱的身体才不会给你看呢" + ], + "迫害": [ + "不...不要...不要...呜呜呜...(害怕,抽泣" + ], + "猫粮": [ + "呜咿姆~!?(惊,接住吃", + "呜姆~!(惊,害羞)呜...谢...谢谢主人..喵...(脸红,嚼嚼嚼,开心", + "呜?谢谢喵~~(嚼嚼嚼,嘎嘣脆)" + ], + "揪尾巴": [ + "呜哇咿~~~!(惊吓,疼痛地捂住尾巴", + "呜咿咿咿~~~!!哇啊咿~~~!(惊慌,惨叫,挣扎", + "呜咿...(瘫倒,无神,被", + "呜姆咿~~~!(惊吓,惨叫,捂尾巴,发抖", + "呜哇咿~~~!!!(惊吓,颤抖,娇叫,捂住尾巴,双腿发抖", + "喵呜…那…那里不可以揪的!", + "呜呜,被揪住会恨敏感的QAQ" + ], + "薄荷": [ + "咪呜~!喵~...喵~姆~...(高兴地嗅闻", + "呜...呜咿~~!咿...姆...(呜咽,渐渐瘫软,意识模糊", + "(小嘴被猫薄荷塞满了,呜咽", + "喵~...喵~...咪...咪呜姆~...嘶哈嘶哈...喵哈...喵哈...嘶哈...喵...(眼睛逐渐迷离,瘫软在地上,嘴角流口水,吸猫薄荷吸到意识模糊", + "呜姆咪~!?(惊)喵呜~!(兴奋地扑到猫薄荷上面", + "呜姆~!(惊,害羞)呜...谢...谢谢你..喵...(脸红,轻轻叼住,嚼嚼嚼,开心" + ], + "早": [ + "早喵~", + "早上好的说~~", + "欸..早..早上好(揉眼睛", + "早上要说我爱你!", + "早", + "早啊,昨晚睡的怎么样?有梦到咱吗~", + "昨晚可真激烈呢哼哼哼~~", + "早上好哇!今天也要元气满满哟!", + "早安喵~", + "时间过得好快啊~", + "早安啊,你昨晚有没有梦到咱呢  (//▽//)", + "早安~么么哒~", + "早安,请享受晨光吧", + "早安~今天也要一起加油呢~!", + "mua~⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄", + "咱需要你提醒嘛!(///脸红//////)", + "早早早!就知道早,下次说我爱你!", + "早安 喵", + "早安,这么早就起床了呀欧尼酱0.0", + "快点起床啊!baka", + "早....早上好才没有什么特别的意思呢....哼~", + "今天有空吗?能陪咱一阵子吗?才不是想约会呢,别误会了!", + "早安呀,欧尼酱要一个咱的早安之吻吗?想得美,才不会亲你啦!", + "那...那就勉为其难地说声早上好吧", + "咱等你很久了哼ヽ(≧Д≦)ノ", + "ohayo~" + ], + "晚安": [ + "晚安好梦哟~", + "欸,晚安的说", + "那咱给你亲一下,可不要睡着了哦~", + "晚安哦~", + "晚安(*/∇\*)", + "晚安呢,你一定要梦到咱呢,一定哟,拉勾勾!ヽ(*・ω・)ノ", + "祝你有个好梦^_^", + "晚安啦,欧尼酱,mua~", + "你,你这家伙真是的…咱就勉为其难的……mua…快去睡啦!咱才没有脸红什么的!", + "哼,晚安,给咱睡个好觉。", + "笨..笨蛋,晚安啦...可不可以一起..才没有想和你一起睡呢", + "晚安......才..不是关心你呢", + "晚...晚安,只是正常互动不要想太多!", + "好无聊,这么早就睡了啊...那晚安吧!", + "晚安吻什么的才...才没有呢!不过看你累了就体谅一下你吧,但是就一个哦(/////)", + "晚安呀,你也要好好休息,明天再见", + "安啦~祝你做个好梦~才...才不是关心你呢!别想太多了!", + "睡觉吧你,大傻瓜", + "一起睡吧(灬°ω°灬)", + "哼!这次就放过你了,快去睡觉吧。", + "睡吧晚安", + "晚安你个头啊,咱才不会说晚安呢!...咱...(小声)明明还有想和你做的事情呢....", + "嗯嗯~Good night~", + "嗯,早点休息别再熬夜啦~(摸摸头)", + "哦呀斯密", + "晚安~咱也稍微有些困了(钻进被窝)", + "需要咱暖床吗~", + "好梦~☆" + ], + "揉": [ + "是是,想怎么揉就怎么揉啊!?来用力抓啊!?咱就是特别允许你这么做了!请!?", + "快停下,咱的头发又乱啦(??????︿??????)", + "你快放手啦,咱还在工作呢", + "戳戳你肚子", + "讨厌…只能一下…", + "呜~啊~", + "那……请你,温柔点哦~(////////)", + "你想揉就揉吧..就这一次哦?", + "变态!!不许乱摸" + ], + "榨": [ + "是专门负责榨果汁的小姐姐嘛?(´・ω・`)", + "那咱就把你放进榨汁机里了哦?", + "咱又不是榨汁姬(/‵Д′)/~ ╧╧", + "嗯——!想,想榨就榨啊······!反正就算榨了也不会有奶的······!" + ], + "掐": [ + "你讨厌!又掐咱的脸", + "晃休啦,咱要型气了啦!!o(>﹏<)o", + "(一只手拎起你)这么鶸还想和咱抗衡,还差得远呢!" + ], + "胸": [ + "不要啦ヽ(≧Д≦)ノ", + "(-`ェ´-╬)", + "(•̀へ •́ ╮ ) 怎么能对咱做这种事情", + "你好恶心啊,讨厌!", + "你的眼睛在看哪里!", + "就让你摸一会哟~(。??ω??。)…", + "请不要这样先生,你想剁手吗?", + "咿呀……不要……", + "嗯哼~才…才不会…舒服呢", + "只允许一下哦…(脸红)", + "咱的胸才不小呢(挺一挺胸)", + "hentai!", + "一只手能抓住么~", + "呀...欧,欧尼酱...请轻点。", + "脸红????", + "咿呀~快…快停下来…咱…不行了!", + "就算一直摸一直摸,也不会变大的哦(小声)", + "诶?!不...不可以哦!很...很害羞的!", + "啊……温,温柔点啊……(/ω\)", + "你为什么对两块脂肪恋恋不舍", + "嗯……不可以……啦……不要乱戳", + "你在想什么奇怪的东西,讨厌(脸红)", + "不...不要..", + "喜欢欧派是很正常的想法呢", + "一直玩弄欧派,咱的...都挺起来了", + "是要直接摸还是伸进里面摸呀w咱今天没穿,伸进里面会摸到立起来的...哦>////<", + "唔~再激烈点" + ], + "奶子": [ + "只允许一下哦…(脸红)", + "咱的胸才不小呢(挺一挺胸)", + "下流!", + "对咱说这种话,你真是太过分了", + "咿呀~好奇怪的感觉(>_<)", + "(推开)你就像小宝宝一样...才不要呢!", + "(打你)快放手,不可以随便摸人家的胸部啦!", + "你是满脑子都是H的淫兽吗?", + "一只手能抓住么~", + "你在想什么奇怪的东西,讨厌(脸红)", + "不...不要..", + "喜欢欧派是很正常的想法呢", + "一直玩弄欧派,咱的...都挺起来了", + "是要直接摸还是伸进里面摸呀w咱今天没穿,伸进里面会摸到立起来的...哦>////<", + "唔~再激烈点", + "解开扣子,请享用", + "请把脑袋伸过来,咱给你看个宝贝", + "八嘎!hentai!无路赛!", + "一只手能抓住么~", + "呀...欧,欧尼酱...请轻点。", + "脸红????", + "咿呀~快…快停下来…咱…不行了!", + "就算一直摸一直摸,也不会变大的哦(小声)", + "诶?!不...不可以哦!很...很害羞的!", + "啊……温,温柔点啊……(/ω\)", + "你为什么对两块脂肪恋恋不舍", + "嗯……不可以……啦……不要乱戳" + ], + "欧派": [ + "咱的胸才不小呢(挺一挺胸)", + "只允许一下哦…(脸红)", + "(推开)你就像小宝宝一样...才不要呢!", + "下流!", + "对咱说这种话,你真是太过分了", + "咿呀~好奇怪的感觉(>_<)", + "(打你)快放手,不可以随便摸人家的胸部啦!", + "你是满脑子都是H的淫兽吗?", + "一只手能抓住么~", + "你在想什么奇怪的东西,讨厌(脸红)", + "不...不要..", + "喜欢欧派是很正常的想法呢", + "一直玩弄欧派,咱的...都挺起来了", + "是要直接摸还是伸进里面摸呀w咱今天没穿,伸进里面会摸到立起来的...哦>////<", + "唔~再激烈点", + "解开扣子,请享用", + "请把脑袋伸过来,咱给你看个宝贝", + "八嘎!hentai!无路赛!", + "一只手能抓住么~", + "呀...欧,欧尼酱...请轻点。", + "脸红????", + "咿呀~快…快停下来…咱…不行了!", + "就算一直摸一直摸,也不会变大的哦(小声)", + "诶?!不...不可以哦!很...很害羞的!", + "啊……温,温柔点啊……(/ω\)", + "你为什么对两块脂肪恋恋不舍", + "嗯……不可以……啦……不要乱戳" + ], + "嫩": [ + "很可爱吧(๑•̀ω•́)ノ", + "唔,你指的是什么呀", + "明天你下海干活", + "咱一直有保养呢,所以一直都是樱花色的,你喜欢吗QAQ", + "咱下面超厉害" + ], + "蹭": [ + "唔...你,这也是禁止事项哦→_→", + "嗯..好舒服呢", + "不要啊好痒的", + "不要过来啦讨厌!!!∑(°Д°ノ)ノ", + "(按住你的头)好痒呀 不要啦", + "嗯..好舒服呢", + "呀~好痒啊~哈哈~,停下来啦,哈哈哈", + "(害羞)" + ], + "牵手": [ + "只许牵一下哦", + "嗯!好的你~(伸手)", + "你的手有些凉呢,让咱来暖一暖吧。", + "当然可以啦⁄(⁄⁄•⁄ω⁄•⁄⁄)⁄", + "突……突然牵手什么的(害羞)", + "一起走", + "……咱……咱在这里呀", + "好哦,(十指相扣)" + ], + "握手": [ + "你的手真暖和呢", + "举爪", + "真是温暖呢~" + ], + "拍照": [ + "那就拜托你啦~请把咱拍得更可爱一些吧w", + "咱已经准备好了哟", + "那个……请问这样的姿势可以吗?" + ], + "w": [ + "有什么好笑的吗?", + "草", + "www", + "在笑什么呢?(歪头)", + ">w<" + ], + "睡不着": [ + "睡不着的话..你...你可以抱着咱一起睡哦(小声)", + "当然是数羊了...不不不,想着咱就能睡着了", + "咱很乐意与你聊天哦(>_<)", + "要不要咱来唱首摇篮曲呢?(′?ω?`)", + "那咱来唱摇篮曲哄你睡觉吧!" + ], + "欧尼酱": [ + "欧~尼~酱~☆", + "欧尼酱?", + "嗯嗯φ(>ω<*) 欧尼酱轻点抱", + "欧尼酱~欧尼酱~欧尼酱~" + ], + "哥": [ + "欧尼酱~", + "哦尼酱~", + "世上只有哥哥好,没哥哥的咱好伤心,扑进哥哥的怀里,幸福不得了", + "哥...哥哥...哥哥大人", + "欧~尼~酱~☆", + "欧尼酱?", + "嗯嗯φ(>ω<*) 欧尼酱轻点抱", + "欧尼酱~欧尼酱~欧尼酱~" + ], + "爱你": [ + "是…是嘛(脸红)呐,其实咱也……", + "咱也最爱你了呢~o(*////▽////*)q", + "咱也爱你哦", + "mua~" + ], + "过来": [ + "来了来了~(扑倒怀里(?? ??????ω?????? ??))", + "(蹦跶、蹦跶)~干什么呢", + "咱来啦~(扑倒怀里~)", + "不要喊的这么大声啦,大家都看着呢" + ], + "自闭": [ + "不不不,晚上还有咱陪着哦,无论什么时候,咱都会陪在哥哥身边。", + "不要难过,咱陪着你ovo" + ], + "打不过": [ + "氪氪氪肝肝肝", + "你需要钞能力呢" + ], + "么么哒": [ + "么么哒", + "不要在公共场合这样啦", + "mua~" + ], + "很懂": [ + "现在不懂,以后总会懂嘛QAQ", + "喵?懂…懂什么呀?(歪头)" + ], + "膝枕": [ + "呐,就给你躺一下哦", + "唔...你想要膝枕嘛?也不是不可以哟(脸红)", + "啊啦~好吧,那就请你枕着咱好好睡一觉吧~", + "呀呀~那么请好好的睡一觉吧", + "嗯,那么请睡到咱这里吧(跪坐着拍拍大腿)", + "好的,让你靠在腿上,这样感觉舒服些了么", + "请,请慢用,要怜惜咱哦wwww~", + "人家已经准备好了哟~把头放在咱的腿上吧", + "没…没办法,这次是例外〃w〃", + "嗯~(脸红)", + "那就给你膝枕吧……就一会哦", + "膝枕准备好咯~" + ], + "累了": [ + "需要咱的膝枕嘛?", + "没…没办法,这次是例外〃w〃", + "累了吗?需要咱为你做膝枕吗?", + "嗯~(脸红)" + ], + "安慰": [ + "那,膝枕……(脸红)", + "不哭不哭,还有咱陪着你", + "不要哭。咱会像妈妈一样安慰你(抱住你的头)", + "摸摸头,乖", + "摸摸有什么事可以和咱说哟", + "摸摸头~不哭不哭", + "咱在呢,抱抱~~", + "那么……让咱来安慰你吧", + "唔...摸摸头安慰一下ヾ(•ω•`。)", + "有咱陪伴你就是最大的安慰啦……不要不开心嘛", + "你想要怎样的安慰呢?这样?这样?还是说~~这样!", + "摸摸头~", + "不哭不哭,要像咱一样坚强", + "你别难过啦,不顺心的事都会被时间冲刷干净的,在那之前...咱会陪在你的身边", + "(轻抱)放心……有咱在,不要伤心呢……", + "唔...咱来安慰你了~", + "摸摸,有什么不开心的事情可以给咱说哦。咱会尽力帮助你的。" + ], + "洗澡": [ + "快点脱哟~不然水就凉了呢", + "咱在穿衣服噢,你不许偷看哦", + "那么咱去洗澡澡了哦", + "么么哒,快去洗干净吧,咱去暖被窝喽(///ω///)", + "诶?还没呢…你要跟咱一起洗吗(//∇//)好羞涩啊ww", + "诶~虽然很喜欢和你在一起,但是洗澡这种事...", + "不要看!不过,以后或许可以哦……和咱成为恋人之后呢", + "说什么啊……hentai!这样会很难为情的", + "你是男孩子还是女孩子呢?男孩子的话...........咱才不要呢。", + "不要啊!", + "咱有点害羞呢呜呜,你温柔点" + ], + "一起睡觉": [ + "欸??也..也不是不可以啦..那咱现在去洗澡,你不要偷看哦٩(๑>◡<๑)۶", + "说什么啊……hentai!这样会很难为情的", + "你是男孩子还是女孩子呢?男孩子的话...........咱才不要呢。", + "不要啊!", + "唔,没办法呢,那就一起睡吧(害羞)" + ], + "一起": [ + "嗯嗯w,真的可以吗?", + "那真是太好了,快开始吧!", + "嗯,咱会一直陪伴你的", + "丑拒" + ], + "多大": [ + "不是特别大但是你摸起来会很舒服的大小喵~", + "你摸摸看不就知道了吗?", + "不告诉你", + "问咱这种问题不觉得很失礼吗?", + "咱就不告诉你,你钻到屏幕里来自己确认啊", + "你指的是什么呀?(捂住胸部)", + "请叫人家咱三岁(。・`ω´・)", + "唉唉唉……这……这种问题,怎么可以……" + ], + "姐姐": [ + "真是的……真是拿你没办法呢 ⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄ 才不是咱主动要求的呢!", + "虽然辛苦,但是能看见可爱的你,咱就觉得很幸福", + "诶(´°Δ°`),是在叫咱吗?", + "有什么事吗~", + "好高兴,有人称呼咱为姐姐", + "乖,摸摸头" + ], + "糖": [ + "不吃脱氧核糖(;≥皿≤)", + "ヾ(✿゚▽゚)ノ好甜", + "好呀!嗯~好甜呀!", + "不吃不吃!咱才不吃坏叔叔的糖果!", + "嗯,啊~", + "嗯嗯,真甜,给你也吃一口", + "谢谢", + "唔,这是什么东西,黏黏的?(??Д??)ノ", + "ヾ(✿゚▽゚)ノ好甜", + "(伸出舌头舔了舔)好吃~最爱你啦", + "好耶~是好次的🍥糖糖喵~" + ], + "嗦": [ + "(吸溜吸溜)", + "好...好的(慢慢含上去)", + "把你噶咯", + "太小了,嗦不到", + "咕噜咕噜", + "嘶蛤嘶蛤嘶蛤~~", + "(咬断)", + "prprprpr", + "好哒主人那咱开始了哦~", + "好好吃", + "剁掉了" + ], + "牛子": [ + "(吸溜吸溜)", + "好...好的(慢慢含上去)", + "把你噶咯", + "太小了,嗦不到", + "咕噜咕噜", + "嘶蛤嘶蛤嘶蛤~~", + "(咬断)", + "prprprpr", + "好哒主人那咱开始了哦~", + "好好吃", + "剁掉了", + "难道你很擅长针线活吗", + "弹一万下", + "往死里弹" + ], + "🐂子": [ + "(吸溜吸溜)", + "好...好的(慢慢含上去)", + "把你噶咯", + "太小了,嗦不到", + "咕噜咕噜", + "嘶蛤嘶蛤嘶蛤~~", + "(咬断)", + "prprprpr", + "好哒主人那咱开始了哦~", + "好好吃", + "剁掉了", + "难道你很擅长针线活吗", + "弹一万下", + "往死里弹" + ], + "🐮子": [ + "(吸溜吸溜)", + "好...好的(慢慢含上去)", + "把你噶咯", + "太小了,嗦不到", + "咕噜咕噜", + "嘶蛤嘶蛤嘶蛤~~", + "(咬断)", + "prprprpr", + "好哒主人那咱开始了哦~", + "好好吃", + "剁掉了", + "难道你很擅长针线活吗", + "弹一万下", + "往死里弹" + ], + "嫌弃": [ + "咱辣么萌,为什么要嫌弃咱...", + "即使你不喜欢咱,咱也会一直一直喜欢着你", + "(;′⌒`)是咱做错了什么吗?", + "呜呜…不要嫌弃咱……让咱做什么都可以的……但是请不要嫌弃咱可以嘛……" + ], + "紧": [ + "嗯,对的", + "呜咕~咱要......喘不过气来了......" + ], + "baka": [ + "你也是baka呢!", + "确实", + "baka!", + "不不不", + "说别人是baka的人才是baka", + "你个大傻瓜", + "不说了,睡觉了", + "咱...咱虽然是有些笨啦...但是咱会努力去学习的", + "bakabaka~", + "才…才不是baka啦!" + ], + "笨蛋": [ + "你也是笨蛋呢!", + "确实", + "笨蛋!", + "不不不", + "说别人是笨蛋的人才是笨蛋", + "你个大傻瓜", + "不说了,睡觉了", + "咱...咱虽然是有些笨啦...但是咱会努力去学习的", + "才…才不是笨蛋呢!" + ], + "插": [ + "来吧,咱的小~...很....紧,很舒服的", + "gun!", + "唔…咱怕疼", + "唔...,这也是禁止事项哦→_→", + "禁止说这么H的事情!", + "要...戴套套哦", + "好痛~", + "使劲", + "就这?", + "恁搁着整针线活呢?" + ], + "插进来": [ + "来吧,咱的小~...很....紧,很舒服的", + "gun!", + "唔…咱怕疼", + "唔...,这也是禁止事项哦→_→", + "禁止说这么H的事情!", + "要...戴套套哦", + "好痛~", + "使劲", + "就这?", + "恁搁着整针线活呢?" + ], + "屁股": [ + "不要ヽ(≧Д≦)ノ好痛", + "(打手)不许摸咱的屁股", + "(撅起屁股)要干什么呀?", + "(轻轻的撩起自己的裙子),你轻一点,咱会痛的(>_<)!", + "在摸哪里啊,hentai!", + "要轻点哦(/≧ω\)", + "轻点呀~", + "(歇下裙子,拉下内...,撅起来)请", + "嗯嗯,咱这就把屁股抬起来" + ], + "翘": [ + "你让咱摆出这个姿势是想干什么?", + "好感度-1-1-1-1-1-1.....", + "嗯嗯,咱这就去把你的腿翘起来", + "请尽情享用吧" + ], + "翘起来": [ + "你让咱摆出这个姿势是想干什么?", + "好感度-1-1-1-1-1-1.....", + "嗯嗯,咱这就去把你的腿翘起来", + "请尽情享用吧" + ], + "抬": [ + "你在干什么呢⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄", + "(抬起下巴)你要干什么呀?", + "上面什么也没有啊(呆~)", + "不要!hentai!咱穿的是裙子(脸红)", + "不可以" + ], + "抬起": [ + "你在干什么呢⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄", + "(抬起下巴)你要干什么呀?", + "上面什么也没有啊(呆~)", + "不要!hentai!咱穿的是裙子(脸红)", + "不可以" + ], + "爸": [ + "欸!儿子!", + "才不要", + "粑粑", + "讨厌..你才不是咱的爸爸呢..(嘟嘴)", + "你又不是咱的爸爸……", + "咱才没有你这样的鬼父!", + "爸爸酱~最喜欢了~" + ], + "傲娇": [ + "才.......才.......才没有呢", + "也好了(有点点的样子(o ̄Д ̄)<)", + "任性可是女孩子的天性呢...", + "谁会喜欢傲娇啊(为了你假装傲娇)", + "谁,谁,傲娇了,八嘎八嘎,你才傲娇了呢(っ//////////c)(为了你假装成傲娇)", + "傲娇什么的……才没有呢!(/////)", + "傲不傲娇你还不清楚吗?", + "你才是傲娇!你全家都是傲娇!哼(`Д´)", + "才……才没有呢,哼,再说不理你了", + "咱...咱才不会这样子的!", + "啰…啰嗦!", + "哼!(叉腰鼓嘴扭头)", + "你才是傲娇受你全家都是傲娇受╰_╯", + "才~才不是呢,不理你了!哼(`Д´)", + "你才是死傲娇", + "啰,啰嗦死了,才不是呢!", + "就是傲娇你要怎样", + "诶...!这...这样...太狡猾了啦...你这家伙....", + "无路赛!你才是傲娇嘞!你全家都是!", + "咱...咱才不是傲娇呢,哼(鼓脸)", + "不许这么说咱 ,,Ծ‸Ծ,,", + "才…才不是傲娇呢!哼!" + ], + "rua": [ + "略略略~(吐舌头)", + "rua!", + "mua~", + "略略略", + "mua~⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄", + "摸了", + "嘁,丢人(嫌弃脸)", + "反rua~", + "rua回去" + ], + "咕噜咕噜": [ + "嘟嘟噜", + "你在吹泡泡吗?", + "咕叽咕噜~", + "咕噜咕噜" + ], + "咕噜": [ + "嘟嘟噜", + "你在吹泡泡吗?", + "咕叽咕噜~", + "咕噜咕噜" + ], + "上床": [ + "诶!H什么的禁止的说.....", + "咱已经乖乖在自家床上躺好了,有什么问题吗?", + "你想要干什么,难道是什么不好的事吗?", + "(给你空出位置)", + "不要,走开(ノ`⊿??)ノ", + "好喔,不过要先抱一下咱啦", + "(双手护胸)变....变态!", + "咱帮你盖上被子~然后陪在你身边_(:зゝ∠)_", + "才不给你腾空间呢,你睡地板,哼!", + "要一起吗?" + ], + "做爱": [ + "做这种事情是不是还太早了", + "噫!没想到你居然是这样的人!", + "再说这种话,就把你变成女孩子(拿刀)", + "不想好好和咱聊天就不要说话了", + "(双手护胸)变....变态!", + "hentai", + "你想怎么做呢?", + "突,突然,说什么啊!baka!", + "你又在说什么H的东西", + "咱....咱才不想和你....好了好了,有那么一点点那,对就一点点,哼~", + "就一下下哦,不能再多了" + ], + "吃掉": [ + "(羞羞*>_<*)好吧...请你温柔点,哦~", + "闪避,反咬", + "请你好好品尝咱吧(/ω\)", + "不……不可以这样!", + "那就吃掉咱吧(乖乖的躺好)", + "都可以哦~咱不挑食的呢~", + "请不要吃掉咱,咱会乖乖听话的QAQ", + "咱...咱一点都不好吃的呢!", + "不要吃掉咱,呜呜(害怕)", + "不行啦,咱被吃掉就没有了QAQ(害怕)", + "唔....?诶诶诶诶?//////", + "QwQ咱还只是个孩子(脸红)", + "如果你真的很想的话...只能够一口哦~咱...会很痛的", + "吃你呀~(飞扑", + "不要啊,咱不香的(⋟﹏⋞)", + "说着这种话的是hentai吗!", + "快来把咱吃掉吧", + "还……还请好好品尝咱哦", + "喏~(伸手)", + "呐…是主人的话…被次掉也不是不可以啦……(递自己)" + ], + "吃": [ + "(羞羞*>_<*)好吧...请你温柔点,哦~", + "闪避,反咬", + "请你好好品尝咱吧(/ω\)", + "不……不可以这样!", + "那就吃掉咱吧(乖乖的躺好)", + "都可以哦~咱不挑食的呢~", + "请不要吃掉咱,咱会乖乖听话的QAQ", + "咱...咱一点都不好吃的呢!", + "不要吃掉咱,呜呜(害怕)", + "不行啦,咱被吃掉就没有了QAQ(害怕)", + "唔....?诶诶诶诶?//////", + "QwQ咱还只是个孩子(脸红)", + "如果你真的很想的话...只能够一口哦~咱...会很痛的", + "吃你呀~(飞扑", + "不要啊,咱不香的(⋟﹏⋞)", + "说着这种话的是hentai吗!", + "快来把咱吃掉吧", + "还……还请好好品尝咱哦", + "喏~(伸手)", + "呐…是主人的话…被次掉也不是不可以啦……(递自己)" + ], + "揪": [ + "你快放手,好痛呀", + "呜呒~唔(伸出舌头)", + "(捂住耳朵)你做什么啦!真是的...总是欺负咱", + "你为什么要这么做呢?", + "哎呀啊啊啊啊啊!不要...不要揪!好疼!有呆毛的咱难道不够萌吗QwQ", + "你…松……送手啦", + "呀!这样对女孩子是很不礼貌的(嘟嘴)" + ], + "种草莓": [ + "你…你不要…啊…种在这里…会容易被别人看见的(*//ω//*)", + "啊...太明显了...不要在这里种草莓啦", + "来吧~我对其他人说是蚊子叮的~" + ], + "种草": [ + "你…你不要…啊…种在这里…会容易被别人看见的(*//ω//*)" + ], + "掀": [ + "(掀裙)今天……是…白,白色的呢……请温柔对她……", + "那样,胖次会被你看光的", + "(按住)不可以掀起来!", + "不要~", + "呜呜~(揉眼睛)", + "呜..请温柔一点(害羞)", + "不可以", + "今天……没有穿", + "不要啊!(//////)讨厌...", + "变态,快放手(打)", + "不给掀,你是变态", + "最后的底牌了!", + "这个hentai" + ], + "妹": [ + "你有什么事?咱会尽量满足的", + "开心(*´∀`)~♥", + "欧尼酱", + "哥哥想要抱抱吗", + "喵呜,欧尼酱的超绝无敌可爱妹妹在这里哦~" + ], + "病娇": [ + "为什么会这样呢(拿起菜刀)", + "觉得这个世界太肮脏?没事,把眼睛挖掉就好。 觉得这些闲言碎语太吵?没事,把耳朵堵起来就好。 觉得鲜血的味道太刺鼻?没事,把鼻子割掉就好。 觉得自己的话语太伤人?没事,把嘴巴缝起来就好。", + "唔…不好,咱是病娇的事情终究还是被发现了嘛……没办法呢,那就只好把你处理掉了呢~" + ], + "嘻": [ + "你是想对咱做什么吗...(后退)", + "哼哼~", + "嘻嘻w" + ], + "按摩": [ + "(小手捏捏)咱的按摩舒服吗?", + "咱不会按摩的!", + "嘿咻嘿咻~这样觉得舒服吗?", + "呀!...呜...,不要...不要这样啦...呜...", + "只能按摩后背喔...", + "咱对这些不是很懂呢(????ω??????)" + ], + "按住": [ + "Σ(°Д°;您要干什么~放开咱啦", + "突然使出过肩摔!", + "放手啦,再这样咱就要反击了喔", + "你的眼睛在看哪里!", + "呜呒~唔(伸出舌头)", + "H的事情,不可以!", + "想吃吗?(๑•ૅω•´๑)", + "要和咱比试比试吗", + "呜哇(/ω\)…快…快放开咱!!", + "(用力揪你耳朵)下次再敢这样的话就没容易放过你了!哼!", + "尼……奏凯……快航休!", + "哈?别..唔啊!别把咱……(挣扎)baka!别乱动咱啦!" + ], + "按在": [ + "不要这样啦(一脸娇羞的推开)", + "(一个过肩摔,加踢裆然后帅气地回头)你太弱了呢~", + "放手啦,再这样咱就要反击了喔", + "Σ(°Д°; 你要干什么~放开咱啦", + "要和咱比试比试吗", + "呜哇(/ω\)…快…快放开咱!!", + "敢按住咱真是好大的胆子!", + "(用力揪你耳朵)下次再敢这样的话就没容易放过你了!哼!", + "尼……奏凯……快航休!", + "哈?别..唔啊!别把咱……(挣扎)baka!别乱动咱啦!" + ], + "按倒": [ + "把咱按倒是想干嘛呢(??`⊿??)??", + "咱也...咱也是...都等你好长时间了", + "你的身体没问题吧?", + "呜呒~唔(伸出舌头)", + "H的事情,不可以!", + "放手啦,再这样咱就要反击了喔", + "想吃吗?(๑•ૅω•´๑)", + "不....不要吧..咱会害羞的(//////)", + "要和咱比试比试吗", + "呜哇(/ω\)…快…快放开咱!!", + "(用力揪你耳朵)下次再敢这样的话就没容易放过你了!哼!", + "尼……奏凯……快航休!", + "哈?别..唔啊!别把咱……(挣扎)baka!别乱动咱啦!" + ], + "按": [ + "咱也...咱也是...都等你好长时间了", + "不让!", + "不要,好难为情", + "你的眼睛在看哪里!", + "拒绝!", + "唔...唔..嗯", + "咱就勉为其难地给你弄弄好啦", + "欸…变态!", + "会感到舒服什么的,那...那样的事情,是完全不存在的!", + "poi~", + "你在盯着什么地方看!变态萝莉控!" + ], + "炼铜": [ + "炼铜有什么好玩的,和咱一起玩吧", + "炼铜不如恋咱", + "你也是个炼铜术士嘛?", + "信不信咱把你按在水泥上摩擦?", + "炼,都可以炼!", + "大hentai!一巴掌拍飞!(╯‵□′)╯︵┻━┻", + "锻炼什么的咱才不需要呢 (心虚地摸了摸自己的小肚子)", + "把你的头按在地上摩擦", + "你在盯着什么地方看!变态萝莉控!" + ], + "白丝": [ + "喜欢,咱觉得白丝看起来很可爱呢", + "(脱)白丝只能给亲爱的你一个人呢…(递)", + "哼,hentai,这么想要咱的脚吗(ノ`⊿´)ノ", + "难道你这个hentai想让咱穿白丝踩踏你吗", + "不给看", + "很滑很~柔顺~的白丝袜哟~!!!∑(°Д°ノ)ノ你不会想做奇怪的事情吧!?", + "你……是要黑丝呢?还是白丝呢?或者光着(害羞)", + "来……来看吧", + "呐…雪糕什么的sukidesu" + ], + "黑丝": [ + "哼,hentai,这么想要咱的脚吗(ノ`⊿´)ノ", + "不给看", + "你……是要黑丝呢?还是白丝呢?或者光着(害羞)", + "很滑很~柔顺~的黑丝袜哟~!!!∑(°Д°ノ)ノ您不会想做奇怪的事情吧!?", + "来……来看吧", + "噫...你这个hentai难道想让咱穿黑丝么", + "(默默抬起穿着黑丝的脚)", + "嘻嘻,是黑巧克力呢~" + ], + "喷": [ + "咱才不喷呢!不过…既然是你让咱喷的话就勉为其难给你喷一次吧(噗)", + "不……不会喷水啦!喷……喷火也不会哦!", + "你怎么知道(捂住裙子)", + "你难道在期待什么?", + "欸…变态!" + ], + "约会": [ + "你...终于主动邀请咱约会了吗...咱...咱好开心", + "约会什么的……咱会好开心的!!", + "今天要去哪里呢", + "让咱考虑一下", + "好啊!好啊!要去哪里约会呢?", + "不约!蜀黍咱们不约!", + "女友什么的,咱才不承认呢!", + "才不是想和你约会呢,只是刚好有时间而已!", + "才不要和你约会呢!", + "咱、咱才不会跟你去约会呢!不baka!别一脸憋屈!好了,陪你一会儿就是了!别、别误会!只是陪同而已!" + ], + "出门": [ + "早点回来……才不是在担心你呢!", + "路上小心...才不是担心你呢!", + "没有你才不会觉得无聊什么的呢。快走快走", + "嗯~一路顺风~", + "路上小心", + "好的,路上小心哦!y∩__∩y", + "路上要小心呀,要早点回来哦~咱在家里等你!还有,请不要边走路边看手机,这样很容易撞到电线杆的", + "唔...出门的话一定要做好防晒准备哦,外出的话记得带把伞,如果有防晒霜的话就更好了", + "那你明天可以和咱一起玩吗?(星星眼)", + "咱...咱才没有舍不得你呢…要尽快回来哦" + ], + "上学": [ + "你要加油哦(^ω^)2", + "那你明天可以和咱一起玩吗?(星星眼)", + "记得好好学习听老师的话哦,咱会等你回来的", + "拜拜,咱才没有想让你放学早点回来呢╭(╯^╰)╮", + "好好听讲!", + "咱...咱才没有舍不得你呢…要尽快回来哦" + ], + "上班": [ + "这就要去上班去了吗?那好吧...给咱快点回来知道吗!", + "乖~咱会在家等你下班的~", + "辛苦啦,咱给你个么么哒", + "咱会为你加油的", + "专心上班哦,下班后再找咱聊天吧", + "一路顺风,咱会在家等你回来的", + "那你明天可以和咱一起玩吗?(星星眼)", + "咱...咱才没有舍不得你呢…要尽快回来哦" + ], + "下课": [ + "快点回来陪咱玩吧~", + "瞌睡(ˉ﹃ˉ)额啊…终于下课了吗,上课什么的真是无聊呢~", + "下课啦,咱才不想你来找咱玩呢,哼" + ], + "回来": [ + "欢迎回来~", + "欢迎回来,你想喝茶吗?咱去给你沏~", + "欢迎回来,咱等你很久了~", + "忙碌了一天,辛苦了呢(^_^)", + "(扑~)欢迎回来~", + "嗯呐嗯呐,欢迎回来~", + "欢迎回来,要来杯红茶放松一下吗?还有饼干哦。", + "咱会一直一直一直等着", + "是要先洗澡呢?还是先吃饭呢?还是先·吃·咱呢~", + "你回来啦,是先吃饭呢还是先洗澡呢或者是●先●吃●咱●——呢(///^.^///)", + "要先吃饭呢~还是先洗澡呢~还是先~吃~咱", + "是吗……辛苦你了。你这副倔强的样子,真可爱呢(笑)勉强让你躺在咱的腿上休息一下吧,别流口水哟", + "嗯……勉为其难欢迎你一下吧", + "想咱了嘛", + "欢迎回.....什么?咱才没有开心的说QUQ", + "哼╯^╰,你怎么这么晚才回来!", + "回来了吗,咱...咱才没有想你", + "咱等你很久了哼ヽ(≧Д≦)ノ", + "咱很想你(≧▽≦)" + ], + "回家": [ + "回来了吗,咱...咱才没有想你", + "要先吃饭呢~还是先洗澡呢~还是先~吃~咱", + "是吗……辛苦你了。你这副倔强的样子,真可爱呢(笑)勉强让你躺在咱的腿上休息一下吧,别流口水哟", + "嗯……勉为其难欢迎你一下吧", + "想咱了嘛", + "咱等你很久了哼ヽ(≧Д≦)ノ", + "咱很想你(≧▽≦)" + ], + "放学": [ + "回来了吗,咱...咱才没有想你", + "要先吃饭呢~还是先洗澡呢~还是先~吃~咱", + "是吗……辛苦你了。你这副倔强的样子,真可爱呢(笑)勉强让你躺在咱的腿上休息一下吧,别流口水哟", + "嗯……勉为其难欢迎你一下吧", + "想咱了嘛", + "咱等你很久了哼ヽ(≧Д≦)ノ", + "咱很想你(≧▽≦)" + ], + "下班": [ + "回来了吗,咱...咱才没有想你", + "要先吃饭呢~还是先洗澡呢~还是先~吃~咱", + "是吗……辛苦你了。你这副倔强的样子,真可爱呢(笑)勉强让你躺在咱的腿上休息一下吧,别流口水哟", + "嗯……勉为其难欢迎你一下吧", + "想咱了嘛", + "咱等你很久了哼ヽ(≧Д≦)ノ", + "回来啦!终于下班了呢!累了吗?想吃的什么呀?", + "工作辛苦了,需要咱为你按摩下吗?", + "咱很想你(≧▽≦)" + ], + "杂鱼": [ + "才…才不是杂鱼呢!", + "zakozako~", + "哼~要不咱们同床竞技比比睡才是杂鱼", + "咕。。才不是杂鱼呢哼" + ], + "zako": [ + "才…才不是杂鱼呢!", + "zakozako~", + "哼~要不咱们同床竞技比比睡才是杂鱼", + "咕。。才不是杂鱼呢哼" + ], + "RBQ": [ + "呜…咱才不是RBQ呢QwQ", + "怎么啦主人~", + "主人桑有何吩咐呢~", + "喵呜…咱不能做RBQ的qwq" + ], + "举高高": [ + "好耶~主人的举高高最棒啦~", + "举高高什么的daisuki喵", + "嘻嘻,最喜欢被抱着举高高啦~" + ] +}