通过 Monkey Patch 的方式拦截 Bot.send 和 Bot.target_send 方法 只会安装一次,所有插件的 hooks 都会被调用
()
| 156 | |
| 157 | |
| 158 | def install_bot_hooks(): |
| 159 | """ |
| 160 | 通过 Monkey Patch 的方式拦截 Bot.send 和 Bot.target_send 方法 |
| 161 | 只会安装一次,所有插件的 hooks 都会被调用 |
| 162 | """ |
| 163 | if hasattr(Bot, "_bot_hooks_installed"): |
| 164 | logger.debug("[库洛签到·BotHook] Bot hooks 已经安装,跳过") |
| 165 | return |
| 166 | |
| 167 | original_send = Bot.send |
| 168 | original_target_send = Bot.target_send |
| 169 | |
| 170 | # 包装 send 方法 |
| 171 | async def hooked_send(self, *args, **kwargs): |
| 172 | # 调用 hooks |
| 173 | user_id = getattr(self.ev, "user_id", None) if hasattr(self, "ev") else None |
| 174 | bot_id = getattr(self, "bot_id", "") if hasattr(self, "bot_id") else "" |
| 175 | bot_self_id = getattr(self, "bot_self_id", "") if hasattr(self, "bot_self_id") else "" |
| 176 | |
| 177 | # 调用所有插件的用户活跃度 hooks |
| 178 | await _call_all_user_activity_hooks(user_id, bot_id, bot_self_id) |
| 179 | |
| 180 | # 调用所有插件的 target_send hooks (群组消息时更新群组绑定) |
| 181 | if hasattr(self, "ev"): |
| 182 | target_type = getattr(self.ev, "user_type", "") |
| 183 | group_id = getattr(self.ev, "group_id", None) |
| 184 | if target_type and group_id: |
| 185 | await _call_all_target_send_hooks(target_type, group_id, bot_id, bot_self_id) |
| 186 | await _call_all_group_activity_hooks(group_id, bot_id, bot_self_id) |
| 187 | |
| 188 | # 调用原始方法 |
| 189 | return await original_send(self, *args, **kwargs) |
| 190 | |
| 191 | # 包装 target_send 方法 |
| 192 | async def hooked_target_send(self, *args, **kwargs): |
| 193 | # 从 Bot 实例的 ev 属性获取正确的 bot 信息 |
| 194 | if hasattr(self, "ev") and len(args) >= 3: |
| 195 | target_type = args[1] |
| 196 | target_id = args[2] |
| 197 | bot_id = getattr(self.ev, "real_bot_id", getattr(self, "bot_id", "")) |
| 198 | bot_self_id = getattr(self.ev, "bot_self_id", getattr(self, "bot_self_id", "")) |
| 199 | |
| 200 | # 调用所有插件的 target_send hooks |
| 201 | await _call_all_target_send_hooks(target_type, target_id, bot_id, bot_self_id) |
| 202 | |
| 203 | # 调用原始方法 |
| 204 | return await original_target_send(self, *args, **kwargs) |
| 205 | |
| 206 | # 替换方法 |
| 207 | Bot.send = hooked_send |
| 208 | Bot.target_send = hooked_target_send |
| 209 | Bot._bot_hooks_installed = True |
| 210 | |
| 211 | logger.debug("[库洛签到·BotHook] Bot hooks 已安装") |