# 阻断机制
阻断机制是核心框架提供的一种可以使得将监听函数进行分组管理的机制,通过此机制你可以做到例如:机器人开关指令、群内游戏状态变化等等。
> 阻断机制某种意义上来讲可以说是对监听函数的分组,此机制可能存在些许BUG。
## 注解
* ### @Block
> 阻断注解,用于定义一个监听函数的阻断名称
> 此注解并不是必须的,但是如果你需要使用阻断机制,我建议你加上。毕竟阻断机制阻断一个函数集是依据阻断名称来分类的。
> 参数:
| 参数 | 类型 | 默认值 | 含义 |
| --- | --- | --- | --- |
| `value` | `String[]` | `{}` | 被标注的函数的阻断名。阻断名可以有多个。 |
<br>
* ### @BlockFilter
> 此注解的参数、含义与`@Filter`完全相同,唯一一点不同的就是此注解是当标注的函数进入了阻断状态的时候才生效。
> 当消息接收,且函数为阻断状态,那么事件过滤器会优先用时`@BlockFilter`来过滤消息,假如没有则会尝试使用`@Filter`的过滤机制来过滤。
使用以上注解来对一个监听函数定义他的阻断名,然后通过在函数中使用送信器`MsgSender`来使函数进入或结束阻断状态。
`MsgSender`中与阻断相关的方法:
```java
//**************** 普通阻塞 ****************//
/**
* 开启阻塞-普通阻塞
* 仅仅添加当前这一个监听函数,不根据名称关联其他
函数
*/
public void onBlockOnlyThis(boolean append);
/**
* 开启阻塞-普通阻塞
* 仅仅添加当前这一个监听函数,不根据名称关联其他
* 如果存在其他阻塞函数,替换他们
为当前加入的函数
*/
public void onBlockOnlyThis();
/**
* 开启阻塞-普通阻塞
* 根据当前函数的阻塞名称添加全部同名函数
*/
public void onBlockByThisName(boolean append);
/**
* 开启阻塞-普通阻塞
* 根据当前函数的阻塞名称添加全部同名函数
* 如果存在其他阻塞函数,替换他们
为当前加入的函数
*/
public void onBlockByThisName();
/**
* 根据组名来使某个分组进入阻断状态
* 此方法当前执行的监听函数没有关联
*/
public void onBlockByName(String name, boolean append);
/**
* 根据组名来使某个分组进入阻断状态
* 如果存在其他阻塞函数,替换他们
为当前加入的函数
*/
public void onBlockByName(String name)
//**************** 全局阻塞 ****************//
/**
* 根据一个名称更新全局阻塞
*/
public void onGlobalBlockByName(String name);
/**
* 根据阻断名称的索引来更新全局阻塞
* 毕竟阻断注解中可以有多个名称
*/
public void onGlobalBlockByNameIndex(int index) throws NoSuchBlockNameException;
/**
* 根据第一个阻断名称来更新全剧阻塞
*/
public void onGlobalBlockByFirstName();
//**************** 获取阻断器部分信息 ****************//
/**
* 根据组名判断自己所在的组是否全部在阻断状态中
*/
public boolean isAllOnBlockByName();
/**
* 根据组名判断自己所在的组是否有任意在阻断状态中
*/
public boolean isAnyOnBlockByName();
/**
* 根据组名判断自己所在的组是否全部没有在阻断状态中
*/
public boolean isNoneOnBlockByName();
/**
* 判断自己是否存在于阻断队列
*/
public boolean isOnBlock();
/**
* 判断自己是否作为单独的阻断被阻断了
*/
public boolean isOnlyThisOnBlock();
//**************** 获取阻断状态的两个方法使用真实阻断器 ****************//
/**
* 获取当前处于全局阻断状态下的阻断组名
*
* @return 阻断组名
*/
public String getOnGlobalBlockName();
/**
* 获取当前处于普通阻断状态下的阻断组名列表
* @return 处于普通阻断状态下的阻断组名列表
*/
public String[] getOnNormalBlockNameArray();
//**************** 取消阻断相关 ****************//
/**
* 取消普通阻塞-即清空阻塞中的普通阻塞函数容器
* 使用真实阻断器,即此方法不论当前送信器中是否存在监听函数,都会生效。下面两个取消阻塞的方法同理
*/
public void unBlock();
/**
* 移除全局阻塞
-即清空阻塞中的全局阻塞函数
容器
*/
public void unGlobalBlock();
/**
* 取消全部阻塞
*/
public void unAllBlock();
```
### 解释
* ##### 送信器与真实阻断器
上面的方法中,有一些东西我认为我需要解释一下。
首先,在送信器中,每一个监听函数都会记录当前获取了送信器的监听函数。这也就是为什么上面的方法中很多方法是直接获取"当前执行的监听函数"以进入阻断状态的了。
但是,有些时候的送信器中是不存在监听函数的,例如启动器启动成功的回调函数所提供的送信器中就不存在什么监听函数,那么这该怎么办?
上面的方法中,有时候会看到"使用真实阻断器"这种说法。所谓的真实阻断器就是真正在使用的阻断器,而当送信器中不存在监听函数的时候,大部分方法使用的是"空阻断器",也就是说,当不存在监听函数的送信器如果执行了阻断相关的方法,如果没有提到使用的是否为"真实阻断器"的话,那么执行的阻断方法将会没有任何效果。
> 这是肯定的啦
* ##### 普通阻塞与全局阻塞
阻塞的方式有两种:普通阻塞和全局阻塞
> 当普通阻塞与全局阻塞同时存在的时候,仅全局阻塞生效。
**`普通阻塞**`
普通阻塞相对于全局阻塞来讲,优先级低,灵活性高。普通阻塞可以通过多种方式将监听函数添加进入阻塞状态:按照名称、按照自己、是否关联同名阻塞函数、是追加还是替换等等。
**`全局阻塞**`
全局阻塞的优先级比较高,但是没有那么高的灵活性。全局阻塞只能通过单个函数或阻塞函数的组名来进入阻塞状态,且无法追加。当你要将另外一组函数加入全局阻塞状态的时候,就会顶替掉当前的全局阻塞函数。
### 举个栗子
```java
/**
* 阻塞demo
**/
@Beans
@Listen(MsgGetTypes.privateMsg)
public class BlockTest {
/**
* 收到 hello的私聊消息的时候,会在控制台打印“hello”
*/
@Filter("hello")
public void hello(MsgSender msgSender){
System.out.println("hello");
}
/**
* name1组进入阻塞状态
*/
@Filter("onBlock")
@Block("name1")
public void in(MsgSender msgSender){
msgSender.onBlockByThisName();
}
/**
* 清空阻断状态
*/
@Filter("off")
@Block("name1")
public void off(MsgSender msgSender){
msgSender.unBlock();
}
}
```
> 上面的demo中,当私信一句"hello"的时候,控制台会打印一句"hello"(hello方法实现)
> 当私信收到一句"onBlock"的时候,阻塞组名为"name1"的函数进入阻塞状态,此时其他函数将会失效。再私信一句"hello"的时候将没有任何反应。\`\`
> 当私信一句"off"的时候,由于off方法阻塞组名为name1,此时会清空阻塞函数,此后再私信一句"hello"的时候,控制台又会打印hello了
- 前言
- 简单介绍
- 我该如何阅读文档
- 视频教程
- 安装与使用
- 开源协议
- 免责&捐助
- 注意事项
- 版本命名规则简介
- 主要功能版本历史
- 功能指引
- 通用API与功能
- 国际化语言
- 异常
- 消息监听
- @Listen
- @OnListen模板
- @Filter
- 消息参数截取
- @Spare
- @Constr
- @Ignore
- @ListenBreak
- @ListenBreakPlugin
- @ListenBody
- 监听响应
- 成功判定与返回值
- 监听上下文
- 动态参数
- 监听消息API
- 异步监听 @Async
- 限流监听 @Limit
- 自定义Http送信器
- 枚举与类型
- 送信器
- SENDER
- SETTER
- GETTER
- 返回值
- 其他位置
- 日志与日志拦截
- 异常处理
- 依赖注入
- 自定义依赖获取
- 批量依赖载入
- 注意事项
- 常量
- 定时任务
- 自定义过滤
- 拦截器
- 拦截器总定义
- 上下文对象总定义
- 监听消息拦截
- 送信器拦截
- 监听函数拦截
- CAT码
- CQ码
- CQCode
- CQ码工具类
- CQ扩展工具类
- AppendList拼接链
- 高级内容
- 阻断机制
- 截断机制
- 自定义枚举类型
- 枚举工厂
- byName注解
- 自定义注解
- 配置
- 文件配置
- 注解配置
- 参数配置
- 多配置
- 多账号
- 自定义账号管理器
- 小心!
- 核心版本与组件如何升级核心
- 核心版本迭代指南
- 核心
- 更新日志
- jar包与依赖
- 监听消息类结构图
- 快速启动
- 模组与扩展
- 模组开发
- 现有模组
- 通用模组-延时任务
- 通用模组-CQ码工具
- 转义器
- CQ码操作工具类
- CQ码模板-CodeTemplate
- CQ码载体-KQCode
- CQ码构建器
- MQ码工具类
- 通用模组-redis-bot管理器
- 通用模组-Debugger
- Debugger-common模块
- Debugger-server模块
- Debugger-client模块
- 通用模组-钉钉机器人
- 组件-Mirai(JVM)
- 快速开始(1.13+)
- springboot-starter
- 注意事项
- 配置
- 额外的内容
- 快速回复
- 额外监听
- CQ码解析
- 组件-酷Q(QQ)-CQ HTTP API(基本失效)
- 快速开始(推荐)
- 快速开始(1.7.x以下,不推荐)
- 快速开始(Springboot启动器)
- 启动器、启动接口与配置类
- 配置
- 文件配置
- 注意事项
- 更新日志
- 额外的内容
- 自定义额外监听
- CQ送信器
- 元事件
- 监听消息类结构图
- 组件-酷Q(QQ)-JCQ(失效)
- 快速开始
- 更新日志
- 额外的内容
- JCQ日志
- 配置
- 注意事项
- 监听消息类结构图
- 组件-酷Q(QQ)-HTTP TO CQ(失效)
- 快速开始(核心1.7.x及以下)
- 启动器、启动接口与配置类
- 配置
- 文件配置
- 注意事项
- 更新日志
- 监听消息类结构图
- 组件-酷Q(QQ)-LEMOC (失效)
- 快速开始(核心1.7.x及以下)
- 配置
- 注意事项
- 更新日志
- 监听消息类结构图
- Springboot快速启动器
- 常见问题汇总
- BUG反馈
- 更新计划总览