diff --git a/README.md b/README.md index fe83b576..6bd91fa7 100644 --- a/README.md +++ b/README.md @@ -15,40 +15,19 @@ ## 📣 更新内容 > [!IMPORTANT] -> v2.0.1 无法正常运行,已经撤销 +> v2.0.0 突破性更新 +> https://github.com/Ljzd-PRO/nonebot-plugin-mystool/releases/tag/v2.0.0 -### 2024.1.29 - v2.1.0 +### 2024.3.8 - v2.2.0 -- 更换 QQ 频道主动私信发送方式以及频道 ID 储存方式,可能修复无法私信的问题 (#236) -> [!TIP] -> 对机器人发送 `/私信响应`,可完成频道信息获取保存, \ -> 以便主动机器人私信。登录米游社账号时也会保存。 +#### 💡 新特性 +- 在未开启 崩坏:星穹铁道 便笺通知的情况下输出便笺检查结果日志 -- 修复 v2.0.1 的 `ImportError` 错误 (#251) -- 修复插件无法自动创建 `data` 目录以创建配置文件和数据文件的问题 (#250) - -- 更新插件配置的 `preference.github_proxy` 默认值为 `https://mirror.ghproxy.com/` -> [!NOTE] -> `preference.github_proxy` 用于使用代理以更快地从 GitHub 下载 Source Han Sans 思源黑体 字体。 \ -> 只有新生成的配置文件会使用新默认值,对于之前创建的配置文件,如果想使用新默认值则需要手动修改。 - -- 显示米游社账号时除了显示米游社UID,还会显示登录时获取到的手机尾号4位,方便辨识账号 (#242) -> [!IMPORTANT] -> 目前还在考虑是否需要通过一个用户设置选项,来控制是否显示手机尾号,并默认关闭,以保护用户隐私 \ -> 如果觉得有必要可以在 [Discussion 讨论页面](https://github.com/Ljzd-PRO/nonebot-plugin-mystool/discussions/247) 的对应话题提出或投票。 - -### 2024.1.27 - v2.0.0 - -- 项目结构重构,解决了开发时容易出现循环导入 (circular import) 之类的问题,结束了之前的混乱。~~虽然可能还是很乱(~~ :octocat: -- 命令帮助信息相关代码重构 -- 插件配置相关代码重构,新的配置文件为 `configV2.json`,与V1版本不兼容 -- 插件配置中设备信息和 Salt 配置重构,从 `.env` 和环境变量中读取,与V1版本不兼容 -- 插件数据相关代码重构,新的配置文件为 `configV2.json`,与V1版本不兼容 -- 修复兑换计划添加的相关代码的Bug -- 修复商品兑换图片生成相关问题 (v2.0.0) - -> [!NOTE] -> 不需要担心插件配置和数据文件的兼容性,插件启动(导入)时会自动将V1版本的插件数据文件进行备份和升级 +#### 🐛 Bug 修复 +- 修复 OneBotV11 适配器私信发送失败的问题 (#260, #264) +- 修复 崩坏:星穹铁道 便笺提醒失效的问题 - by @Joseandluue +- 更改 崩坏:星穹铁道 便笺检查的每日实训/模拟宇宙通知逻辑 - by @Joseandluue +- 更正 崩坏:星穹铁道 便笺检查的开拓力阈值范围 - by @Joseandluue ## ⚡ 功能和特性 diff --git a/pyproject.toml b/pyproject.toml index fee26700..cf71725f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "nonebot-plugin-mystool" -version = "v2.1.0" +version = "v2.2.0" description = "QQ聊天、频道机器人插件 | 米游社工具-每日米游币任务、游戏签到、商品兑换、免抓包登录、原神崩铁便笺提醒" license = "MIT" authors = [ @@ -24,9 +24,9 @@ packages = [ [tool.poetry.dependencies] python = ">=3.9,<4.0" -httpx = ">=0.24.1,<0.27.0" +httpx = ">=0.24.1,<0.28.0" nonebot_plugin_apscheduler = ">=0.2.0" -nonebot-plugin-send-anything-anywhere = "^0.5.0" +nonebot-plugin-send-anything-anywhere = ">=0.5,<0.7" ntplib = "^0.4.0" Pillow = ">=9.5,<11.0" requests = "^2.31.0" @@ -36,7 +36,7 @@ tenacity = "^8.2.3" qrcode = "^7.4.2" pydantic = "^1.10.14" nonebot2 = ">=2.0.0" -pytz = "^2023.4" +pytz = ">=2023.4,<2025.0" [tool.poetry.group.test.dependencies] nonebot2 = { version = "^2.0.1", extras = ["fastapi", "httpx", "websockets"] } diff --git a/src/nonebot_plugin_mystool/__init__.py b/src/nonebot_plugin_mystool/__init__.py index c6c139f7..6b1c3bc3 100644 --- a/src/nonebot_plugin_mystool/__init__.py +++ b/src/nonebot_plugin_mystool/__init__.py @@ -1,7 +1,3 @@ -from nonebot.log import logger - -logger.info("插件目前为V2版本,可能不稳定,如果出现异常可以更换 v1.4.4 版本") - from nonebot.plugin import PluginMetadata from . import _version diff --git a/src/nonebot_plugin_mystool/_version.py b/src/nonebot_plugin_mystool/_version.py index 51f8c49e..6cd5d0dd 100644 --- a/src/nonebot_plugin_mystool/_version.py +++ b/src/nonebot_plugin_mystool/_version.py @@ -1 +1 @@ -__version__ = "v2.1.0" +__version__ = "v2.2.0" diff --git a/src/nonebot_plugin_mystool/command/plan.py b/src/nonebot_plugin_mystool/command/plan.py index 3bd4925c..696a50e9 100644 --- a/src/nonebot_plugin_mystool/command/plan.py +++ b/src/nonebot_plugin_mystool/command/plan.py @@ -548,6 +548,7 @@ async def genshin_note_check(user: UserData, user_ids: Iterable[str], matcher: M genshin_notice.transformer = True if not do_notice: + logger.info(f"原神实时便笺:账户 {account.display_name} 树脂:{note.current_resin},未满足推送条件") return msg += "❖原神·实时便笺❖" \ @@ -601,40 +602,28 @@ async def starrail_note_check(user: UserData, user_ids: Iterable[str], matcher: if note.current_stamina >= note.max_stamina: starrail_notice.current_stamina_full = True msg += '❕您的开拓力已经溢出\n' + if note.current_train_score != note.max_train_score: + msg += '❕您的每日实训未完成\n' do_notice = True elif not starrail_notice.current_stamina: starrail_notice.current_stamina_full = False starrail_notice.current_stamina = True msg += '❕您的开拓力已达到提醒阈值\n' + if note.current_train_score != note.max_train_score: + msg += '❕您的每日实训未完成\n' do_notice = True else: starrail_notice.current_stamina = False starrail_notice.current_stamina_full = False - # 每日实训状态提醒 - if note.current_train_score != note.max_train_score: - # 防止重复提醒 - # if not starrail_notice.current_train_score: - if not starrail_notice.current_train_score \ - and plugin_config.preference.notice_time: # 注意此处添加notice_time是为了防止每日首次推送通知在4:00后一段时间 - starrail_notice.current_train_score = True # notice_time = plan_time +1h - msg += '❕您的每日实训未完成\n' # 通知逻辑变动后,如不添加notice_time,便笺检查在xx:20,便笺检查间隔1h,则每日首次通知在04:20 - do_notice = True - else: - starrail_notice.current_train_score = False - # 每周模拟宇宙积分提醒 if note.current_rogue_score != note.max_rogue_score: - # 防止重复提醒 - if not starrail_notice.current_rogue_score \ - and plugin_config.preference.notice_time: # notice_time同理 - starrail_notice.current_rogue_score = True + if plugin_config.preference.notice_time: msg += '❕您的模拟宇宙积分还没打满\n\n' do_notice = True - else: - starrail_notice.current_rogue_score = False if not do_notice: + logger.info(f"崩铁实时便笺:账户 {account.display_name} 开拓力:{note.current_stamina},未满足推送条件") return msg += "❖星穹铁道·实时便笺❖" \ diff --git a/src/nonebot_plugin_mystool/command/setting.py b/src/nonebot_plugin_mystool/command/setting.py index 4ceb4665..b9b8e1d0 100644 --- a/src/nonebot_plugin_mystool/command/setting.py +++ b/src/nonebot_plugin_mystool/command/setting.py @@ -180,7 +180,7 @@ async def _(_: Union[GeneralMessageEvent], state: T_State, notice_game=ArgStr()) elif notice_game == "2": await account_setting.send( "请输入想要所需阈值数字,开拓力达到该值时将进行通知:" - "可用范围 [0, 180]" + "可用范围 [0, 240]" "\n\n🚪发送“退出”即可退出" ) state["setting_item"] = "setting_notice_value_sr" @@ -215,14 +215,14 @@ async def _(_: Union[GeneralMessageEvent], state: T_State, setting_value=ArgStr( except ValueError: await account_setting.reject("⚠️请输入有效的数字。") else: - if 0 <= stamina_threshold <= 180: + if 0 <= stamina_threshold <= 240: # 输入有效的数字范围,将 stamina_threshold 赋值为输入的整数 account.user_stamina_threshold = stamina_threshold PluginDataManager.write_plugin_data() await account_setting.finish("更改崩铁便笺开拓力提醒阈值成功\n" f"⏰当前提醒阈值:{stamina_threshold}") else: - await account_setting.reject("⚠️输入的数字范围应在 0 到 180 之间。") + await account_setting.reject("⚠️输入的数字范围应在 0 到 240 之间。") elif state["setting_item"] == "mission_games": games_input = setting_value.split() diff --git a/src/nonebot_plugin_mystool/model/config.py b/src/nonebot_plugin_mystool/model/config.py index 1524b38d..1b31f1f7 100644 --- a/src/nonebot_plugin_mystool/model/config.py +++ b/src/nonebot_plugin_mystool/model/config.py @@ -110,10 +110,13 @@ def _(cls, v: Optional[Path]): @property def notice_time(self) -> bool: - now_time = datetime.now().time() - note_time = datetime.strptime(self.plan_time, "%H:%M") - note_time = note_time + timedelta(hours=1) - return now_time > note_time.time() + now_hour = datetime.now().hour + now_minute = datetime.now().minute + set_time = "20:00" + notice_time = int(set_time[:2]) * 60 + int(set_time[3:]) + start_time = notice_time - self.resin_interval + end_time = notice_time + self.resin_interval + return start_time <= (now_hour * 60 + now_minute) % (24 * 60) <= end_time class GoodListImageConfig(BaseModel): diff --git a/src/nonebot_plugin_mystool/utils/common.py b/src/nonebot_plugin_mystool/utils/common.py index 617aa604..3e2e5f59 100644 --- a/src/nonebot_plugin_mystool/utils/common.py +++ b/src/nonebot_plugin_mystool/utils/common.py @@ -33,7 +33,6 @@ Adapter as OneBotV11Adapter, Bot as OneBotV11Bot from nonebot.adapters.qq import DirectMessageCreateEvent, MessageCreateEvent, \ Adapter as QQGuildAdapter, Bot as QQGuildBot, MessageEvent -from nonebot.exception import ActionFailed from nonebot.log import logger from nonebot.log import logger from qrcode import QRCode @@ -343,7 +342,7 @@ async def send_private_msg( message: Union[str, MessageSegmentFactory, AggregatedMessageFactory], use: Union[Bot, Adapter] = None, guild_id: int = None -) -> Tuple[bool, Optional[ActionFailed]]: +) -> Tuple[bool, Optional[Exception]]: """ 主动发送私信消息 @@ -365,45 +364,32 @@ async def send_private_msg( else: bots = nonebot.get_bots().values() - # 获取 PlatformTarget 对象 - if isinstance(use, (OneBotV11Bot, OneBotV11Adapter)): - target = TargetQQPrivate(user_id=user_id_int) - logger.info(f"{plugin_config.preference.log_head}向用户 {user_id} 发送 QQ 聊天私信 user_id: {user_id_int}") - else: - if guild_id is None: - if user := PluginDataManager.plugin_data.users.get(user_id): - if not (guild_id := user.qq_guild.get(user_id)): - logger.error(f"{plugin_config.preference.log_head}用户 {user_id} 数据中没有任何频道ID") - return False, None - else: - logger.error(f"{plugin_config.preference.log_head}用户数据中不存在用户 {user_id},无法获取频道ID") - return False, None - target = TargetQQGuildDirect(recipient_id=user_id_int, source_guild_id=guild_id) - logger.info(f"{plugin_config.preference.log_head}向用户 {user_id} 发送 QQ 频道私信" - f" recipient_id: {user_id_int}, source_guild_id: {guild_id}") - - # 发送 - - exception = None - error_flag = True - for bot in bots: try: - await message.send_to(target=target, bot=bot) - except Exception as e: - exception = e - else: - error_flag = False + # 获取 PlatformTarget 对象 + if isinstance(bot, OneBotV11Bot): + target = TargetQQPrivate(user_id=user_id_int) + logger.info( + f"{plugin_config.preference.log_head}向用户 {user_id} 发送 QQ 聊天私信 user_id: {user_id_int}") + else: + if guild_id is None: + if user := PluginDataManager.plugin_data.users.get(user_id): + if not (guild_id := user.qq_guild.get(user_id)): + logger.error(f"{plugin_config.preference.log_head}用户 {user_id} 数据中没有任何频道ID") + return False, None + else: + logger.error( + f"{plugin_config.preference.log_head}用户数据中不存在用户 {user_id},无法获取频道ID") + return False, None + target = TargetQQGuildDirect(recipient_id=user_id_int, source_guild_id=guild_id) + logger.info(f"{plugin_config.preference.log_head}向用户 {user_id} 发送 QQ 频道私信" + f" recipient_id: {user_id_int}, source_guild_id: {guild_id}") - if error_flag: - try: - await message.send_to(target=target) + await message.send_to(target=target, bot=bot) except Exception as e: - exception = e + return False, e else: - error_flag = False - - return not error_flag, exception + return True, None def get_unique_users() -> Iterable[Tuple[str, UserData]]: