# 自定义过滤规则 >[info] 核心`1.8.0`版本后支持使用者自定义并使用一些过滤规则。 如果`@Filter`注解中的参数无法满足你繁杂的过滤规则,那么你可以来看看如何自定义一套过滤规则并使用它们。 >[warning] 自定义过滤规则的优先级位于`@Filter`所有自带过滤规则之后,只有当`@Filter`自带的规则全部通过之后才会触发后续规则。 ## **自定义过滤接口** 首先,你需要写一个类并实现`com.forte.qqrobot.listener.Filterable` 接口,并实现其中的方法: ```java /** * 根据自定义规则对消息进行过滤 * @param filter filter注解对象 * @param msgget 接收到的消息 * @param at 判断当前消息是否被at的函数 * @return 是否通过 */ boolean filter(Filter filter, MsgGet msgget, AtDetection at); ``` >[danger] `AtDetection`在核心`1.8.0`中存在bug无法使用,`1.8.1`中被修复。 当过滤规则被触发的时候,参数中`filter`即为当前监听函数上存在的`@Filter`注解,`msgget`即为当前接收到的消息,`at`则可以通过`test()`方法来判断当前方法中是否at了机器人自身。*不过最保险的方法还是直接使用字符串判断。* 而方法的返回值即代表了是否放行此次过滤。如果不放行,则后续的过滤器不会被触发,监听函数也不会被触发。 其中,返回值`true`代表放行,`false`代表不放行。 ## **注册自定义过滤** 你有两种方式来注册一个自定义过滤。 >[warning] 无论使用哪种方法注入,都需要先实现`Filterable`接口。 ### **自动注册** 你可以写一个实现了`Filterable`接口的实现类,并将其注入依赖中心。之后,框架会在启动的时候自动搜寻以被注入的所有`Filterable`实现类并自动注册。 >[info] 前提是此类能够被扫描到。 * 你可以选择使用`@Beans`进行注入,被注入的自定义过滤的名称就是类名的开头小写。 * 你可以选择使用`@DIYFilter`进行注入,`@DIYFilter`存在一个`value`参数,如果这个参数不填,则效果与`@Beans`相同,如果填了,那么注册的这个自定义过滤的名称就与你所填写的参数一致。 举个栗子: #### **@Beans** ```java @Beans public class TestFilter2 implements Filterable { @Override public boolean filter(Filter filter, MsgGet msgget, AtDetection at) { return true; } } ``` >[warning] 1.9.0更新后,接口参数变成了:`filter(Filter filter, MsgGet msgget, AtDetection at, ListenContext context);` #### **@DIYFilter** ```java @DIYFilter("filter2") public class TestFilter2 implements Filterable { @Override public boolean filter(Filter filter, MsgGet msgget, AtDetection at) { return true; } } ``` ### **手动注册** 除了自动注册以外,我还提供了一个手动注册的方法,就是使用`ListenerFilter`类的静态方法`registerFilter`来注册一个自定义过滤: ```java ListenerFilter.registerFilter("TEST_FILTER3", new TestFilter3()); ListenerFilter.registerFilter("TEST_FILTER4", (filter, msg, at, context) -> true); ``` 很显而易见的,第一个参数即为名称,而第二个就是实例对象或者一个lambda表达式了。 >[danger] 无论任何方法,如果注册的监听函数出现了名称冲突,会抛出异常。 ## **使用自定义过滤** 注册好了自定义过滤,该如何使用呢?直接在`@Filter`的参数`diyFilter`中填入你所注册的自定义过滤器的名称即可。 如果你填了多个名称,你可以使用`mostDIYType`参数来决定它们的匹配规则。 例如: ```java @Listen(MsgGetTypes.privateMsg) @Filter(diyFilter = "TEST_FILTER3") public void run(PrivateMsg privateMsg){ // todo something... } ``` >[info] `mostDIYType`参数是类型为`MostDIYType`的枚举类型,可以至[枚举章节](./枚举.md)查找。