Releases: simple-robot/simpler-robot
v2.1.0-RC.4
v2.1.0-RC.4
如果没有bug被发现下一个版本就是v2.1.0
了,有bug请尽快反馈。
核心
- 修复无法读取
simbot-bots
目录下bot文件的问题。
mirai组件
- 更新mirai版本到 v2.6.7
v2.1.0-RC.3
V2.1.0-RC.3
中间漏了个RC.2,但是我忘了更新了什么
核心
-
调整
ListenerFunction.groups
,现在将会得到一个不可变列表List<ListenerGroup>
-
约定
ListenerGroup
由ListenerGroupManager
的实现统一管理。 -
监听函数现在可以直接注入
ListenerFunction
来得到当前执行的监听函数对象实例了。 -
提供
DetailAccountInfo
接口,为AccountInfo
接口的扩展,实现此接口的实例可以得到更多信息。if(accountInfo instanceof DetailAccountInfo) { /* do something... */ }
-
GroupMsg
中的getBotInfo
返回值调整为GroupBotInfo
,可以在其中得到更多信息。 -
GroupAccountInfo
现在可以得到权限信息了。
定时任务模块
repeat
默认值调整为-1
。(#127)
v2.1.0-M1
v2.1.0-M1
实际上这个版本应该是叫
v2.1.0-RC.1
来着。如果有下个修复版,将会命名为v2.1.0-RC.2
核心
-
多bot配置方式变更。 (#68)
现在,除了在配置文件中填写simbot.core.bots
以外,支持使用simbot-bots/*.bot
的方式配置你的bot信息。
在resource目录或者项目根目录下创建目录:simbot-bots
,并在其中创建任意bot
格式文件,从此文件中填写你的bot信息。
例如forli.bot
:code=这是账号 verification=这是密码
当然,绝大多数情况下,
verification
的含义与password
一致,因此你可以填写:code=这是账号 password=这是密码
关于每个组件中,你的bot配置项具体要填什么内容,以对应组件实际情况为准。其中,所有组件必须保证
code
作为唯一标识存在。聪明的你已经发现了,
bot
格式的文件与properties
格式一致。
mirai组件
- 为事件线程池提供参数配置 (#125)
注意,这些配置在未来某版本后会被核心提供的场景线程池所取代。
# 核心线程数,默认cpu*2 simbot.component.mirai.dispatcher.corePoolSize= # 最大线程数,默认cpu*4 simbot.component.mirai.dispatcher.maximumPoolSize= # 线程存活时间(毫秒),默认1000 simbot.component.mirai.dispatcher.keepAliveTime=
fix
- Too many SetterInfo and SenderInfo instance (#124)
需要观察的问题
v2.1.0-BETA.1
v2.1.0-BETA.1
核心
注意:这是一个不兼容变更。
@Priority(1)
@OnPrivate
public void listen1(ListenerContext context) {
ScopeContext scopeContext = context.getContext(ListenerContext.Scope.GLOBAL);
// 向Global作用域的上下文中设置一个值。
scopeContext.set("age", 50);
// 从global作用域的上下文中得到一个值
scopeContext.get("name");
}
@Priority(2)
@OnPrivate
public void listen2(@ContextValue(value = "age", scopes = ListenerContext.Scope.GLOBAL) Integer age) {
// 支持监听函数从上下文中得注入参数
System.out.println("age: " + age);
}
由上述可以看到,ListenerContext
存在两个主要变更:
ListenerContext
通过getContext
方法,填入一个作用域枚举ListenerContext.Scope
作为参数,得到其对应的作用域下的上下文。
目前存在两个作用域:GLOBAL(全局)
、EVENT_INSTANT(事件瞬时)
- 某作用域下的值可以通过
@ContextValue
注入至当前监听函数的参数中。需要注意的是,目前@ContextValue
的注入暂不提供自动类型转化,因此需要注意类型一致问题。
@Beans
@ListenGroup("GlobalGroup1")
public class TestListener {
@ListenGroup("Group1")
@OnPrivate
public void listen1() {
System.out.println("1");
}
@ListenGroup(value = "Group1", append = false)
@OnPrivate
public void listen2() {
System.out.println("2");
}
@ListenGroup({"Group2", "Group3"})
@OnPrivate
public void listen3() {
System.out.println("3");
}
}
由上述内容可见,@ListenGroup
用于为监听函数提供“分组”的能力。其可以标记于类上或者方法上。当类上与方法上同时存在的时候,通过 append=true/false
来决定当前方法是否需要继承类上所标记的分组。
一个监听函数可以存在多个分组。
分组功能仍处于初期阶段,其目前的主要功能是为拦截器提供更好的分组拦截机制。
伴随着 @ListenGroup
的存在,核心提供了两个用于拦截分组函数的拦截器:GroupedListenerInterceptor
及其子抽象类 FixedRangeGroupedListenerInterceptor
.
以 FixedRangeGroupedListenerInterceptor
为例:
@Beans
public class ListenerInterceptorByGroup extends FixedRangeGroupedListenerInterceptor {
@NotNull
@Override
protected InterceptionType doIntercept(@NotNull ListenerInterceptContext context, @Nullable String group) {
System.out.println("拦截的组:" + group);
System.out.println("listener: " + context.getListenerFunction().getId());
// 放行
return InterceptionType.PASS;
}
/**
* 拦截分组 "Group1" 的监听函数。 只会因初始化而被调用一次。
*
*/
@NotNull
@Override
protected String[] getGroupRange() {
return new String[]{"Group1"};
}
}
你可以通过规定你所需拦截的范围来对指定分组的监听函数进行拦截。
v2.0.8
v2.0.7
v2.0.6
v2.0.6
此版本存在AtDetection NPE的问题,不建议使用。see v2.0.7
核心
- 尝试调整
MessageGet.flag
等标识相关API。
mirai组件
- 修改部分内部的送信逻辑(主要为setter中的相关api)
And other beta version
2.0.6-BETA.5
2.0.6-BETA.4
2.0.6-BETA.3
2.0.6-BETA.2
2.0.6-BETA.1
v2.0.6-BETA.5
v2.0.6-BETA.5
全局
- 更新 forte-common 版本到 v1.0.0-BETA.1 (修复
getListByType
的bug #3)
核心
-
提供一个
SimbotContextClosedHandle
接口以支持当执行SimbotContext.close
的时候执行逻辑。此接口一般用于组件。 -
提供接口
RemoteResourceInProcessor
来统一组件的资源获取行为(多指获取远程图片输入流等),并允许用户进行实现。
此接口存在一个子接口SuspendRemoteResourceInProcessor
以支持suspend函数。( #93 )如果你需要重写组件下的资源获取方式,实现
RemoteResourceInProcessor
接口 (或者它的子接口) 并通过@Beans
注入。
public class TestProcessor implements RemoteResourceInProcessor {
@NotNull
@Override
public InputStream processor(RemoteResourceContext processContext) throws IOException {
// 获取需要下载的路径/连接
String link = processContext.getLink();
URL url = new URL(link);
// 获取输入流
return url.openStream();
}
}
mirai组件
v2.0.6-BETA.4
v2.0.6-BETA.4
核心
-
为
MsgInterceptChainFactory
和ListenerInterceptChainFactory
增加一个isEmpty
用于判断当前是否存在相关拦截,
以解决在用户未使用任何拦截器的情况下依旧创建了大量拦截器所需类的问题,节约资源使用。(#90) -
尝试修复一段时间运行后卡死(无法接收处理消息)的问题。 (#92)
-
尝试优化核心
AtDetection
相关逻辑并提升运行效率减少占用。 -
重新定义部分Flag相关接口。(理论上对之前版本是可兼容的)
mirai组件
-
尝试优化mirai组件的特殊
AtDetection
相关逻辑并提升运行效率。 -
简单调整 mirai组件内部的
BotAliveThread
终止方式。 -
为mirai组件中的
MiraiMessageContentBuilder
提供更多支持原生mirai消息构建的方法。简单示例:
/** 注入得到mirai组件环境下的 MiraiMessageContentBuilderFactory 工厂。 */ @Depend private MiraiMessageContentBuilderFactory builderFactory; @Listen(GroupMsg.class) public void listen(Sender sender) { MiraiMessageContentBuilder builder = builderFactory.getMessageContentBuilder(); // 以下这些是Mirai的原生消息信息 At at1 = new At(123); AtAll atAll = AtAll.INSTANCE; PlainText text = new PlainText("这是一段文字"); // 构建一个原生的Mirai消息链 MessageChainBuilder nativeMsgBuilder = new MessageChainBuilder(); MessageChain chain = nativeMsgBuilder .append(at1) .append(atAll) .append(text) .build(); builder = builder // 这是simbot所提供的构建方法 .at("123123") // 将这个消息链通过 builder.message 植入当前的simbot消息构建器 .message(chain); /* mirai组件下提供了以下方法来支持原生mirai消息拼接: - message(Message) // Message是原生mirai的类型 - singleMessage(SingleMessage) // SingleMessage是原生mirai的类型 - messageContent(MiraiMessageContent) // MiraiMessageContent是simbot-mirai组件提供的包装类型 // 这是为kotlin使用者调用的方法,提供一个Neko(可省略), // 和一个 suspend函数,此函数接收一个 Content 参数(一般为发送目标的对象,例如一个群或者一个好友), 并通过这个目标得到一个 SingleMessage示例。 - message(Neko?, suspend (Contact) -> SingleMessage) // 这是为Java使用者调用的方法,含义与上面这个一样,只不过函数不是suspend类型。 - messageLazy(Neko?, (Contact) -> SingleMessage) // 对于上述这两个有函数的方法,如果你想发送的消息无法返回一个 SingleMessage, 而是直接调用方法发送(例如mirai发送头像戳一戳nudge), // 那么你可以在发送完成后返回一个: // Java: EmptySingleMessage.INSTANCE // Kotlin: EmptySingleMessage */ // 构建为消息正文,并发送 MiraiMessageContent build = builder.build(); sender.sendGroupMsg(123456, build); }
-
消息撤回支持解析普通的flagContent.id。(即支持消息标识序列化)
需要注意的是,这次支持并不会兼容之前版本的flagContent.id,只有2.0.6及之后版本的id允许反序列化。(因为变更了id的规则)
简单示例:
@Listen(GroupMsg.class) public void listen(GroupMsg msg, Setter setter) { // 这是正常得到的flag。 GroupMsg.MessageFlag flag = msg.getFlag(); // 得到这个flag的id。 String id = flag.getFlag().getId(); System.out.println("id = " + id); // 假设你中途序列化了,并只保存了ID值。 // 你可以通过 Flags.getFlag 或者 Flags.getFlagById 进行反序列化。 // 方法1:Flags.getFlag // getFlag需要一个FlagContent参数, // 对于群消息,你可以使用 GroupMsg.FlagContent.byId(id) // 对于私聊消息,你可以使用 PrivateMsg.FlagContent.byId(id) Flag<GroupMsg.FlagContent> flagById1 = Flags.getFlag(GroupMsg.FlagContent.byId(id)); // 方法2:Flags.getFlagById // getFlagById需要一个ID参数,以及一个 “通过ID获取Content” 的函数。 // 关于第二个函数参数, // 对于群消息,你可以使用 Flags.getFlagById(id, GroupMsg.FlagContent::byId); // 这等同于 Flags.getFlagById(id, id -> GroupMsg.FlagContent.byId(id)); // 对于私聊消息,你可以使用 Flags.getFlagById(id, PrivateMsg.FlagContent::byId); // 这等同于 Flags.getFlagById(id, id -> PrivateMsg.FlagContent.byId(id)); Flag<GroupMsg.FlagContent> flagById2 = Flags.getFlagById(id, GroupMsg.FlagContent::byId); // 反序列化后进行撤回 setter.setMsgRecall(flagById1); }
-
简单优化mirai组件下消息撤回时出现的异常警告,且消息撤回时如果出现可控的已知异常(例如权限不足)则会输出 警告 日志并返回false响应。