Commit 579b8da7 authored by Him188's avatar Him188

Merge branch 'dev'

parents 9892af59 181f4a53
# Version 1.x # Version 1.x
## `1.1.0` 2020/7/9
- 支持 Android 手表协议 (`BotConfiguration.MiraiProtocol.ANDROID_PAD`)
- `EventHandler` 现在支持 `Nothing` 类型.
- 修复无需同意直接进群时,在加载新群信息完成前收到消息过早处理的问题 (#370)
- 修复在某些情况下,管理员邀请群Bot加群会被误判为群成员申请加群的问题 (#402 by [@kenvix](https://github.com/kenvix))
- 修复从其他客户端加群时未同步的问题 (#404, #410)
- 修复 `ConfigPushSvc.PushReq` 解析失败的问题 (#417)
- 修复 `_lowLevelGetGroupActiveData`
- 修复 `SimpleListenerHost.coroutineScope` 潜在的 Job 被覆盖的问题
## `1.0.4` 2020/7/2
- 修复上传图片失败时内存泄露的问题 (#385)
- 修复大量图片同时上传时出错的问题 (#387)
- 修复在一些情况下 BotOfflineEvent 没有正常处理而无法继续接收消息的问题 (#376)
- 修复 Bot 在某个群 T 出某个人导致 Bot 终止的问题 (#372)
- 修复 `@PlannedRemoval` 的文档
## `1.1-EA2` 2020/7/2
- 添加 `BotConfiguration.json`, 作为序列化时使用的 Json format, 修复潜在的因 kotlinx.serialization 进行不兼容更新而导致的不兼容.
**不兼容变更**:
- Image.imageId 后缀由 `.mirai` 变为图片文件实际类型, 如 `.png`, `.jpg`. 兼容原 `.mirai` 后缀.
**修复**:
- ([1.0.4](https://github.com/mamoe/mirai/releases/tag/1.0.4) 中修复的问题)
- ([1.0.3](https://github.com/mamoe/mirai/releases/tag/1.0.3) 中修复的问题)
## `1.0.3` 2020/6/29
- 修复 friendlist.GetTroopListReqV2:java.lang.IllegalStateException: type mismatch 10 (#405)
## `1.1-EA` 2020/6/16 ## `1.1-EA` 2020/6/16
**1.1.0 Early Access** / **1.1.0 预览版**
**此版本新增的 API 可能不稳定, 且可能在下一个版本中删除.**
**主要**: **主要**:
- 添加实验性 `CodableMessage` 作为支持 mirai 码的 `Message` 的接口. - 添加实验性 `CodableMessage` 作为支持 mirai 码的 `Message` 的接口.
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
object Versions { object Versions {
object Mirai { object Mirai {
const val version = "1.1-EA" const val version = "1.1.0"
} }
object Kotlin { object Kotlin {
......
...@@ -74,7 +74,7 @@ object GitHub { ...@@ -74,7 +74,7 @@ object GitHub {
fun upload(file: File, project: Project, repo: String, targetFilePath: String) = runBlocking { fun upload(file: File, project: Project, repo: String, targetFilePath: String) = runBlocking {
val token = getGithubToken(project) val token = getGithubToken(project)
println("token.length=${token.length}") println("token.length=${token.length}")
val url = "https://api.github.com/repos/mamoe/$repo/contents/$targetFilePath" val url = "https://api.github.com/repos/project-mirai/$repo/contents/$targetFilePath"
retryCatching(100, onFailure = { delay(30_000) }) { // 403 forbidden? retryCatching(100, onFailure = { delay(30_000) }) { // 403 forbidden?
Http.put<String>("$url?access_token=$token") { Http.put<String>("$url?access_token=$token") {
val sha = retryCatching(3, onFailure = { delay(30_000) }) { val sha = retryCatching(3, onFailure = { delay(30_000) }) {
...@@ -121,7 +121,7 @@ object GitHub { ...@@ -121,7 +121,7 @@ object GitHub {
return withContext(Dispatchers.IO) { return withContext(Dispatchers.IO) {
val response = Jsoup val response = Jsoup
.connect( .connect(
"https://api.github.com/repos/mamoe/$repo/contents/$filePath?access_token=" + getGithubToken( "https://api.github.com/repos/project-mirai/$repo/contents/$filePath?access_token=" + getGithubToken(
project project
) )
) )
...@@ -150,7 +150,7 @@ object GitHub { ...@@ -150,7 +150,7 @@ object GitHub {
val resp = withContext(Dispatchers.IO) { val resp = withContext(Dispatchers.IO) {
Jsoup Jsoup
.connect( .connect(
"https://api.github.com/repos/mamoe/$repo/git/ref/heads/$branch?access_token=" + getGithubToken( "https://api.github.com/repos/project-mirai/$repo/git/ref/heads/$branch?access_token=" + getGithubToken(
project project
) )
) )
......
...@@ -24,7 +24,7 @@ bintray { ...@@ -24,7 +24,7 @@ bintray {
pkg { pkg {
repo = 'mirai' repo = 'mirai'
name = project.name name = "mirai-core"
licenses = ['AGPL'] licenses = ['AGPL']
vcsUrl = miraiGitHubUrl vcsUrl = miraiGitHubUrl
websiteUrl = miraiGitHubUrl websiteUrl = miraiGitHubUrl
......
...@@ -74,11 +74,13 @@ internal abstract class BotImpl<N : BotNetworkHandler> constructor( ...@@ -74,11 +74,13 @@ internal abstract class BotImpl<N : BotNetworkHandler> constructor(
// bot 还未登录就被 close // bot 还未登录就被 close
return@subscribeAlways return@subscribeAlways
} }
if (network.areYouOk() && event !is BotOfflineEvent.Force) { /*
if (network.areYouOk() && event !is BotOfflineEvent.Force && event !is BotOfflineEvent.MsfOffline) {
// network 运行正常 // network 运行正常
return@subscribeAlways return@subscribeAlways
} }*/
when (event) { when (event) {
is BotOfflineEvent.MsfOffline,
is BotOfflineEvent.Dropped, is BotOfflineEvent.Dropped,
is BotOfflineEvent.RequireReconnect is BotOfflineEvent.RequireReconnect
-> { -> {
...@@ -105,7 +107,12 @@ internal abstract class BotImpl<N : BotNetworkHandler> constructor( ...@@ -105,7 +107,12 @@ internal abstract class BotImpl<N : BotNetworkHandler> constructor(
@OptIn(ThisApiMustBeUsedInWithConnectionLockBlock::class) @OptIn(ThisApiMustBeUsedInWithConnectionLockBlock::class)
relogin((event as? BotOfflineEvent.Dropped)?.cause) relogin((event as? BotOfflineEvent.Dropped)?.cause)
} }
launch { BotReloginEvent(bot, (event as? BotOfflineEvent.Dropped)?.cause).broadcast() } launch {
BotReloginEvent(
bot,
(event as? BotOfflineEvent.CauseAware)?.cause
).broadcast()
}
return return
}.getOrElse { }.getOrElse {
if (it is LoginFailedException && !it.killBot) { if (it is LoginFailedException && !it.killBot) {
......
...@@ -144,6 +144,12 @@ internal class QQAndroidBot constructor( ...@@ -144,6 +144,12 @@ internal class QQAndroidBot constructor(
@Suppress("DuplicatedCode") @Suppress("DuplicatedCode")
@OptIn(LowLevelAPI::class) @OptIn(LowLevelAPI::class)
override suspend fun rejectMemberJoinRequest(event: MemberJoinRequestEvent, blackList: Boolean) { override suspend fun rejectMemberJoinRequest(event: MemberJoinRequestEvent, blackList: Boolean) {
rejectMemberJoinRequest(event, blackList, "")
}
@Suppress("DuplicatedCode")
@OptIn(LowLevelAPI::class)
override suspend fun rejectMemberJoinRequest(event: MemberJoinRequestEvent, blackList: Boolean, message: String) {
checkGroupPermission(event.bot, event.group) { event::class.simpleName ?: "<anonymous class>" } checkGroupPermission(event.bot, event.group) { event::class.simpleName ?: "<anonymous class>" }
check(event.responded.compareAndSet(false, true)) { check(event.responded.compareAndSet(false, true)) {
"the request $this has already been responded" "the request $this has already been responded"
...@@ -159,7 +165,8 @@ internal class QQAndroidBot constructor( ...@@ -159,7 +165,8 @@ internal class QQAndroidBot constructor(
fromNick = event.fromNick, fromNick = event.fromNick,
groupId = event.groupId, groupId = event.groupId,
accept = false, accept = false,
blackList = blackList blackList = blackList,
message = message
) )
} }
...@@ -578,13 +585,15 @@ internal abstract class QQAndroidBotBase constructor( ...@@ -578,13 +585,15 @@ internal abstract class QQAndroidBotBase constructor(
@LowLevelAPI @LowLevelAPI
@MiraiExperimentalAPI @MiraiExperimentalAPI
override suspend fun _lowLevelGetGroupActiveData(groupId: Long): GroupActiveData { override suspend fun _lowLevelGetGroupActiveData(groupId: Long, page: Int): GroupActiveData {
val data = network.async { val data = network.async {
HttpClient().get<String> { HttpClient().get<String> {
url("https://qqweb.qq.com/c/activedata/get_mygroup_data") url("https://qqweb.qq.com/c/activedata/get_mygroup_data")
parameter("bkn", bkn) parameter("bkn", bkn)
parameter("gc", groupId) parameter("gc", groupId)
if (page != -1) {
parameter("page", page)
}
headers { headers {
append( append(
"cookie", "cookie",
...@@ -755,7 +764,8 @@ internal abstract class QQAndroidBotBase constructor( ...@@ -755,7 +764,8 @@ internal abstract class QQAndroidBotBase constructor(
fromNick: String, fromNick: String,
groupId: Long, groupId: Long,
accept: Boolean?, accept: Boolean?,
blackList: Boolean blackList: Boolean,
message: String
) { ) {
network.apply { network.apply {
NewContact.SystemMsgNewGroup.Action( NewContact.SystemMsgNewGroup.Action(
...@@ -765,7 +775,8 @@ internal abstract class QQAndroidBotBase constructor( ...@@ -765,7 +775,8 @@ internal abstract class QQAndroidBotBase constructor(
groupId = groupId, groupId = groupId,
isInvited = false, isInvited = false,
accept = accept, accept = accept,
blackList = blackList blackList = blackList,
message = message
).sendWithoutExpect() ).sendWithoutExpect()
if (accept ?: return) if (accept ?: return)
groups[groupId].apply { groups[groupId].apply {
......
...@@ -114,7 +114,7 @@ internal class FriendImpl( ...@@ -114,7 +114,7 @@ internal class FriendImpl(
fileId = 0, fileId = 0,
fileMd5 = image.md5, fileMd5 = image.md5,
fileSize = image.input.size.toInt(), fileSize = image.input.size.toInt(),
fileName = image.md5.toUHexString("") + "." + ExternalImage.defaultFormatName, fileName = image.md5.toUHexString("") + "." + image.formatName,
imgOriginal = 1 imgOriginal = 1
) )
).sendAndExpect<LongConn.OffPicUp.Response>() ).sendAndExpect<LongConn.OffPicUp.Response>()
......
...@@ -237,7 +237,7 @@ internal class MemberImpl constructor( ...@@ -237,7 +237,7 @@ internal class MemberImpl constructor(
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") @Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
group.members.delegate.removeIf { it.id == this@MemberImpl.id } group.members.delegate.removeIf { it.id == this@MemberImpl.id }
this.cancel(CancellationException("Kicked by bot")) this@MemberImpl.cancel(CancellationException("Kicked by bot"))
MemberLeaveEvent.Kick(this@MemberImpl, null).broadcast() MemberLeaveEvent.Kick(this@MemberImpl, null).broadcast()
} }
} }
......
...@@ -96,14 +96,17 @@ internal class QQAndroidBotNetworkHandler(coroutineContext: CoroutineContext, bo ...@@ -96,14 +96,17 @@ internal class QQAndroidBotNetworkHandler(coroutineContext: CoroutineContext, bo
private fun startHeartbeatJobOrKill(cancelCause: CancellationException? = null): Job { private fun startHeartbeatJobOrKill(cancelCause: CancellationException? = null): Job {
heartbeatJob?.cancel(cancelCause) heartbeatJob?.cancel(cancelCause)
return this@QQAndroidBotNetworkHandler.launch(CoroutineName("Heartbeat")) { return this@QQAndroidBotNetworkHandler.launch(CoroutineName("Heartbeat")) heartBeatJob@{
while (this.isActive) { while (this.isActive) {
delay(bot.configuration.heartbeatPeriodMillis) delay(bot.configuration.heartbeatPeriodMillis)
val failException = doHeartBeat() val failException = doHeartBeat()
if (failException != null) { if (failException != null) {
delay(bot.configuration.firstReconnectDelayMillis) delay(bot.configuration.firstReconnectDelayMillis)
bot.launch { BotOfflineEvent.Dropped(bot, failException).broadcast() }
return@launch bot.launch {
BotOfflineEvent.Dropped(bot, failException).broadcast()
}
return@heartBeatJob
} }
} }
}.also { heartbeatJob = it } }.also { heartbeatJob = it }
......
...@@ -99,9 +99,13 @@ internal class StGroupRankInfo( ...@@ -99,9 +99,13 @@ internal class StGroupRankInfo(
@JceId(4) @JvmField val dwGroupRankSeq: Long? = null, @JceId(4) @JvmField val dwGroupRankSeq: Long? = null,
@JceId(5) @JvmField val ownerName: String? = "", @JceId(5) @JvmField val ownerName: String? = "",
@JceId(6) @JvmField val adminName: String? = "", @JceId(6) @JvmField val adminName: String? = "",
@JceId(7) @JvmField val dwOfficeMode: Long? = null @JceId(7) @JvmField val dwOfficeMode: Long? = null,
@JceId(9) @JvmField val fuckIssue405: List<FuckIssue405?>? = null // fake
) : JceStruct ) : JceStruct
@Serializable
internal class FuckIssue405
@Serializable @Serializable
internal class StFavoriteGroup( internal class StFavoriteGroup(
@JceId(0) @JvmField val dwGroupCode: Long, @JceId(0) @JvmField val dwGroupCode: Long,
......
...@@ -148,22 +148,22 @@ internal class NewContact { ...@@ -148,22 +148,22 @@ internal class NewContact {
return struct?.msg?.run { return struct?.msg?.run {
//this.soutv("SystemMsg") //this.soutv("SystemMsg")
when (subType) { when (subType) {
1 -> { //管理员邀 1 -> { // 处理被邀请入群 或 处理成员入群申
when (c2cInviteJoinGroupFlag) { when (groupMsgType) {
1 -> { 1 -> {
// 被邀请入群
BotInvitedJoinGroupRequestEvent(
bot, struct.msgSeq, actionUin,
groupCode, groupName, actionUinNick
)
}
0 -> {
// 成员申请入群 // 成员申请入群
MemberJoinRequestEvent( MemberJoinRequestEvent(
bot, struct.msgSeq, msgAdditional, bot, struct.msgSeq, msgAdditional,
struct.reqUin, groupCode, groupName, reqUinNick struct.reqUin, groupCode, groupName, reqUinNick
) )
} }
2 -> {
// 被邀请入群
BotInvitedJoinGroupRequestEvent(
bot, struct.msgSeq, actionUin,
groupCode, groupName, actionUinNick
)
}
else -> throw contextualBugReportException( else -> throw contextualBugReportException(
"parse SystemMsgNewGroup, subType=1", "parse SystemMsgNewGroup, subType=1",
this._miraiContentToString(), this._miraiContentToString(),
...@@ -171,16 +171,14 @@ internal class NewContact { ...@@ -171,16 +171,14 @@ internal class NewContact {
) )
} }
} }
2 -> { 2 -> { // 被邀请入群, 自动同意, 不需处理
// 被邀请入群, 自动同意
val group = bot.getNewGroup(groupCode) ?: return null val group = bot.getNewGroup(groupCode) ?: return null
val invitor = group[actionUin] val invitor = group[actionUin]
BotJoinGroupEvent.Invite(invitor) BotJoinGroupEvent.Invite(invitor)
} }
3 -> { 3 -> { // 已被请他管理员处理
// 已被请他管理员处理
null null
} }
5 -> { 5 -> {
...@@ -223,7 +221,8 @@ internal class NewContact { ...@@ -223,7 +221,8 @@ internal class NewContact {
groupId: Long, groupId: Long,
isInvited: Boolean, isInvited: Boolean,
accept: Boolean?, accept: Boolean?,
blackList: Boolean = false blackList: Boolean = false,
message: String = ""
) = ) =
buildOutgoingUniPacket(client) { buildOutgoingUniPacket(client) {
writeProtoBuf( writeProtoBuf(
...@@ -236,7 +235,7 @@ internal class NewContact { ...@@ -236,7 +235,7 @@ internal class NewContact {
false -> 12 // reject false -> 12 // reject
}, },
groupCode = groupId, groupCode = groupId,
msg = "", msg = message,
remark = "", remark = "",
blacklist = blackList blacklist = blackList
), ),
......
...@@ -44,6 +44,7 @@ import net.mamoe.mirai.qqandroid.network.protocol.packet.buildOutgoingUniPacket ...@@ -44,6 +44,7 @@ import net.mamoe.mirai.qqandroid.network.protocol.packet.buildOutgoingUniPacket
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.GroupInfoImpl import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.GroupInfoImpl
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.NewContact import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.NewContact
import net.mamoe.mirai.qqandroid.network.protocol.packet.list.FriendList import net.mamoe.mirai.qqandroid.network.protocol.packet.list.FriendList
import net.mamoe.mirai.qqandroid.utils._miraiContentToString
import net.mamoe.mirai.qqandroid.utils.io.serialization.readProtoBuf import net.mamoe.mirai.qqandroid.utils.io.serialization.readProtoBuf
import net.mamoe.mirai.qqandroid.utils.io.serialization.toByteArray import net.mamoe.mirai.qqandroid.utils.io.serialization.toByteArray
import net.mamoe.mirai.qqandroid.utils.io.serialization.writeProtoBuf import net.mamoe.mirai.qqandroid.utils.io.serialization.writeProtoBuf
...@@ -190,6 +191,20 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory<MessageSvcPbGetMsg.Re ...@@ -190,6 +191,20 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory<MessageSvcPbGetMsg.Re
34 -> { // 与 33 重复 34 -> { // 与 33 重复
return@mapNotNull null return@mapNotNull null
} }
85 -> bot.groupListModifyLock.withLock { // 其他客户端入群
val group = bot.getGroupByUinOrNull(msg.msgHead.fromUin)
if (msg.msgHead.toUin == bot.id && group == null) {
val newGroup = bot.getNewGroup(Group.calculateGroupCodeByGroupUin(msg.msgHead.fromUin))
?: return@mapNotNull null
bot.groups.delegate.addLast(newGroup)
return@mapNotNull BotJoinGroupEvent.Active(newGroup)
} else {
// unknown
return@mapNotNull null
}
}
/* /*
34 -> { // 主动入群 34 -> { // 主动入群
......
...@@ -81,7 +81,9 @@ internal object OnlinePushReqPush : IncomingPacketFactory<OnlinePushReqPush.ReqP ...@@ -81,7 +81,9 @@ internal object OnlinePushReqPush : IncomingPacketFactory<OnlinePushReqPush.ReqP
val packets: Sequence<Packet> = reqPushMsg.vMsgInfos.deco(bot.client) { msgInfo -> val packets: Sequence<Packet> = reqPushMsg.vMsgInfos.deco(bot.client) { msgInfo ->
when (msgInfo.shMsgType.toInt()) { when (msgInfo.shMsgType.toInt()) {
732 -> { 732 -> {
val group = bot.getGroup(readUInt().toLong()) val group = bot.getGroupOrNull(readUInt().toLong())
?: return@deco emptySequence() // group has not been initialized
GroupImpl.checkIsInstance(group) GroupImpl.checkIsInstance(group)
val internalType = readByte().toInt() val internalType = readByte().toInt()
...@@ -257,6 +259,7 @@ private object Transformers732 : Map<Int, Lambda732> by mapOf( ...@@ -257,6 +259,7 @@ private object Transformers732 : Map<Int, Lambda732> by mapOf(
} }
} }
@Suppress("DEPRECATION")
if (group.settings.isConfessTalkEnabled == new) { if (group.settings.isConfessTalkEnabled == new) {
return@lambda732 emptySequence() return@lambda732 emptySequence()
} }
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
package net.mamoe.mirai.qqandroid.network.protocol.packet.login package net.mamoe.mirai.qqandroid.network.protocol.packet.login
import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.use
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoId import kotlinx.serialization.protobuf.ProtoId
import net.mamoe.mirai.event.AbstractEvent import net.mamoe.mirai.event.AbstractEvent
...@@ -28,8 +29,7 @@ import net.mamoe.mirai.qqandroid.utils.io.ProtoBuf ...@@ -28,8 +29,7 @@ import net.mamoe.mirai.qqandroid.utils.io.ProtoBuf
import net.mamoe.mirai.qqandroid.utils.io.serialization.* import net.mamoe.mirai.qqandroid.utils.io.serialization.*
import net.mamoe.mirai.qqandroid.utils.io.withUse import net.mamoe.mirai.qqandroid.utils.io.withUse
import net.mamoe.mirai.qqandroid.utils.toReadPacket import net.mamoe.mirai.qqandroid.utils.toReadPacket
import net.mamoe.mirai.qqandroid.utils.toUHexString import net.mamoe.mirai.utils.verbose
import net.mamoe.mirai.utils.warning
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.PushReq as PushReqJceStruct import net.mamoe.mirai.qqandroid.network.protocol.data.jce.PushReq as PushReqJceStruct
...@@ -68,6 +68,13 @@ internal class ConfigPushSvc { ...@@ -68,6 +68,13 @@ internal class ConfigPushSvc {
} }
} }
private val default by lazy {
val default = """
09 00 01 0A 16 0C 31 38 33 2E 35 37 2E 35 33 2E 31 36 21 1F 90 0B 19 00 01 0A 16 0B 31 38 30 2E 39 36 2E 31 2E 33 30 20 50 0B 29 00 02 0A 16 0D 36 31 2E 31 38 33 2E 31 36 34 2E 34 34 20 50 0B 0A 16 0D 31 31 33 2E 39 36 2E 32 33 32 2E 39 32 20 50 0B 39 00 06 0A 16 0E 31 31 39 2E 31 34 37 2E 31 39 2E 32 34 31 20 50 0B 0A 16 0E 31 31 39 2E 31 34 37 2E 31 39 2E 32 34 34 20 50 0B 0A 16 0E 31 31 39 2E 31 34 37 2E 31 39 2E 32 34 35 20 50 0B 0A 16 0E 31 31 39 2E 31 34 37 2E 31 39 2E 32 35 32 20 50 0B 0A 16 0E 31 31 39 2E 31 34 37 2E 31 39 2E 32 35 33 20 50 0B 0A 16 11 73 63 61 6E 6E 6F 6E 2E 33 67 2E 71 71 2E 63 6F 6D 20 50 0B 49 00 04 0A 16 0E 31 31 33 2E 39 36 2E 32 33 32 2E 31 30 38 20 50 0B 0A 16 0D 31 38 33 2E 33 2E 32 33 33 2E 32 32 35 21 1F 90 0B 0A 16 0E 31 32 33 2E 31 35 30 2E 37 36 2E 31 36 38 21 01 BB 0B 0A 16 0D 31 38 30 2E 31 36 33 2E 32 35 2E 33 38 20 50 0B 5A 09 00 03 0A 00 01 19 00 04 0A 00 01 16 0E 31 31 33 2E 39 36 2E 32 33 32 2E 31 30 38 20 50 0B 0A 00 01 16 0D 31 38 33 2E 33 2E 32 33 33 2E 32 32 35 21 1F 90 0B 0A 00 01 16 0E 31 32 33 2E 31 35 30 2E 37 36 2E 31 36 38 21 01 BB 0B 0A 00 01 16 0D 31 38 30 2E 31 36 33 2E 32 35 2E 33 38 20 50 0B 29 0C 3C 0B 0A 00 05 19 00 04 0A 00 01 16 0E 31 31 33 2E 39 36 2E 32 33 32 2E 31 30 38 20 50 0B 0A 00 01 16 0D 31 38 33 2E 33 2E 32 33 33 2E 32 32 35 21 1F 90 0B 0A 00 01 16 0E 31 32 33 2E 31 35 30 2E 37 36 2E 31 36 38 21 01 BB 0B 0A 00 01 16 0D 31 38 30 2E 31 36 33 2E 32 35 2E 33 38 20 50 0B 29 0C 3C 0B 0A 00 0A 19 00 04 0A 00 01 16 0E 31 31 33 2E 39 36 2E 32 33 32 2E 31 30 38 20 50 0B 0A 00 01 16 0D 31 38 33 2E 33 2E 32 33 33 2E 32 32 35 21 1F 90 0B 0A 00 01 16 0E 31 32 33 2E 31 35 30 2E 37 36 2E 31 36 38 21 01 BB 0B 0A 00 01 16 0D 31 38 30 2E 31 36 33 2E 32 35 2E 33 38 20 50 0B 29 00 05 0A 0C 11 20 00 20 10 30 01 0B 0A 00 01 11 20 00 20 08 30 02 0B 0A 00 02 11 20 00 20 08 30 01 0B 0A 00 03 12 00 01 00 00 20 08 30 02 0B 0A 00 04 11 20 00 20 08 30 02 0B 3C 0B 1D 00 00 68 CA 62 F1 01 C2 AF E6 CF 29 4B 18 71 B5 EE 6B 63 EB F0 0B AB EE A0 5C 20 B9 83 E2 52 F7 BF C7 46 80 BC C3 7F 22 6B 6E 23 42 D0 8F C8 6A C4 F4 49 AA E7 94 EF D4 80 0A E4 8B BF E2 C0 4F FC C5 3F 97 1A E8 0F 0F 7D 06 47 62 C3 C8 07 4F E6 F6 E9 DB CB 4C F5 95 6A AD EC FD D0 46 A5 16 8D 30 02 D5 8A 86 2E 5F E8 D6 8C 2D 00 00 10 33 6E 59 70 73 47 38 52 6E 48 6A 64 51 48 46 54 32 76 E4 B8 DD 40 01 5D 00 01 02 54 8A 50 D0 04 0A 68 CA 62 F1 01 C2 AF E6 CF 29 4B 18 71 B5 EE 6B 63 EB F0 0B AB EE A0 5C 20 B9 83 E2 52 F7 BF C7 46 80 BC C3 7F 22 6B 6E 23 42 D0 8F C8 6A C4 F4 49 AA E7 94 EF D4 80 0A E4 8B BF E2 C0 4F FC C5 3F 97 1A E8 0F 0F 7D 06 47 62 C3 C8 07 4F E6 F6 E9 DB CB 4C F5 95 6A AD EC FD D0 46 A5 16 8D 30 02 D5 8A 86 2E 5F E8 D6 8C 12 10 33 6E 59 70 73 47 38 52 6E 48 6A 64 51 48 46 54 1A 40 08 01 12 0D 08 01 15 71 60 E8 6C 18 50 20 01 28 01 12 0E 08 01 15 B7 03 E9 E1 18 90 3F 20 01 28 01 12 0E 08 01 15 7B 96 4C A8 18 BB 03 20 02 28 00 12 0D 08 01 15 B4 A3 19 26 18 50 20 04 28 00 1A 40 08 05 12 0D 08 01 15 71 60 E8 6C 18 50 20 01 28 01 12 0E 08 01 15 B7 03 E9 E1 18 90 3F 20 01 28 01 12 0E 08 01 15 7B 96 4C A8 18 BB 03 20 02 28 00 12 0D 08 01 15 B4 A3 19 26 18 50 20 04 28 00 1A 78 08 0A 12 0D 08 01 15 71 60 E8 6C 18 50 20 01 28 01 12 0E 08 01 15 B7 03 E9 E1 18 90 3F 20 01 28 01 12 0E 08 01 15 7B 96 4C A8 18 BB 03 20 02 28 00 12 0D 08 01 15 B4 A3 19 26 18 50 20 04 28 00 22 09 08 00 10 80 40 18 10 20 01 22 09 08 01 10 80 40 18 08 20 02 22 09 08 02 10 80 40 18 08 20 01 22 0A 08 03 10 80 80 04 18 08 20 02 22 09 08 04 10 80 40 18 08 20 02 20 01 32 04 08 00 10 01 3A 2A 08 10 10 10 18 09 20 09 28 0F 30 0F 38 05 40 05 48 5A 50 01 58 5A 60 5A 68 5A 70 5A 78 0A 80 01 0A 88 01 0A 90 01 0A 98 01 0A 42 0A 08 00 10 00 18 00 20 00 28 00 4A 06 08 01 10 01 18 03 52 42 08 01 12 0A 08 00 10 80 80 04 18 10 20 02 12 0A 08 01 10 80 80 04 18 08 20 02 12 0A 08 02 10 80 80 01 18 08 20 01 12 0A 08 03 10 80 80 04 18 08 20 02 12 0A 08 04 10 80 80 04 18 08 20 02 18 00 20 00 5A 40 08 01 12 0A 08 00 10 80 80 04 18 10 20 02 12 0A 08 01 10 80 80 04 18 08 20 02 12 0A 08 02 10 80 80 01 18 08 20 01 12 0A 08 03 10 80 80 04 18 08 20 02 12 0A 08 04 10 80 80 04 18 08 20 02 18 00 70 02 78 02 80 01 FA 01 0B 69 00 01 0A 16 26 69 6D 67 63 61 63 68 65 2E 71 71 2E 63 6F 6D 2E 73 63 68 65 64 2E 70 31 76 36 2E 74 64 6E 73 76 36 2E 63 6F 6D 2E 20 50 0B 79 00 02 0A 16 0E 31 30 31 2E 32 32 37 2E 31 33 31 2E 36 37 20 50 0B 0A 16 0D 36 31 2E 31 35 31 2E 31 38 33 2E 32 31 20 50 0B 8A 06 0F 31 37 31 2E 31 31 32 2E 32 32 36 2E 32 33 37 10 03 0B 9A 09 00 0B 0A 00 0F 19 00 01 0A 12 71 19 A3 B4 20 50 0B 29 0C 0B 0A 00 04 19 00 01 0A 12 0B 27 59 65 20 50 0B 29 0C 0B 0A 00 0D 19 00 02 0A 12 55 31 BA DE 20 50 0B 0A 12 5B A0 6A 72 20 50 0B 29 0C 0B 0A 00 03 19 00 02 0A 12 C3 B9 D3 74 20 50 0B 0A 12 CC 43 E4 DD 20 50 0B 29 0C 0B 0A 00 07 19 00 01 0A 12 75 A2 E3 65 20 50 0B 29 0C 0B 0A 00 09 19 00 02 0A 12 BC 6C 24 B7 20 50 0B 0A 12 A6 6C 24 B7 20 50 0B 29 0C 0B 0A 00 0A 19 00 02 0A 12 11 B4 12 0E 20 50 0B 0A 12 15 8C D7 0E 20 50 0B 29 0C 0B 0A 00 05 19 00 01 0A 12 1D E2 03 B7 20 50 0B 29 0C 0B 0A 00 08 19 00 02 0A 12 DE 3F 5B 65 20 50 0B 0A 12 78 09 61 B4 20 50 0B 29 0C 0B 0A 00 06 19 00 02 0A 12 16 CF 97 3D 20 50 0B 0A 12 54 10 59 65 20 50 0B 29 0C 0B 0A 00 0E 19 00 02 0A 12 76 01 B1 6F 20 50 0B 0A 12 6B 89 31 3A 20 50 0B 29 0C 0B 0B AD 00 01 01 5B 08 01 10 A4 F6 AA 16 18 00 22 0A 31 39 39 34 37 30 31 30 32 31 28 AB E1 89 EF 0E 32 12 08 8E A4 D8 A5 09 10 50 18 89 D8 AC F0 08 20 50 28 64 32 12 08 8E A4 C4 DD 08 10 50 18 89 F4 DE E0 05 20 50 28 64 32 13 08 B4 C7 DA B0 02 10 50 18 8A EE D4 F2 0D 20 50 28 C8 01 32 13 08 B4 C7 DA A0 02 10 50 18 8A EC D0 86 0E 20 50 28 C8 01 32 13 08 8C 9D 9B 85 07 10 50 18 89 D6 AD 9C 09 20 50 28 AC 02 32 13 08 B7 81 97 F6 06 10 50 18 8A EC D4 96 02 20 50 28 AC 02 3A 1E 0A 10 24 0E 00 E1 A9 00 00 50 00 00 00 00 00 00 00 29 10 50 18 89 EC 8C B1 05 20 50 28 64 3A 1E 0A 10 24 0E 00 E1 A9 00 00 50 00 00 00 00 00 00 00 64 10 50 18 89 EC 8C D1 07 20 50 28 64 3A 1F 0A 10 24 0E 00 FF F1 01 00 10 00 00 00 00 00 00 01 6F 10 50 18 E4 E6 B1 F0 04 20 50 28 C8 01 3A 1F 0A 10 24 0E 00 FF F1 01 00 10 00 00 00 00 00 00 01 72 10 50 18 E4 E6 AD F0 0E 20 50 28 C8 01 3A 1F 0A 10 24 09 8C 1E 75 B0 00 13 00 00 00 00 00 00 00 36 10 50 18 89 EC 9C E8 0D 20 50 28 AC 02 3A 1F 0A 10 24 09 8C 54 10 03 00 10 00 00 00 00 00 00 00 55 10 50 18 89 CA 8C A0 01 20 50 28 AC 02
""".trimIndent().hexToBytes()
default.loadAs(FileStoragePushFSSvcListFuckKotlin.serializer())
}
override suspend fun ByteReadPacket.decode(bot: QQAndroidBot, sequenceId: Int): PushReqResponse? { override suspend fun ByteReadPacket.decode(bot: QQAndroidBot, sequenceId: Int): PushReqResponse? {
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") @Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
...@@ -76,29 +83,21 @@ internal class ConfigPushSvc { ...@@ -76,29 +83,21 @@ internal class ConfigPushSvc {
kotlin.runCatching { kotlin.runCatching {
val configPush = val configPush =
buffer.toReadPacket(length = length).readUniPacket(PushReqJceStruct.serializer(), "PushReq") buffer.toReadPacket(length = length)
.use { it.readUniPacket(PushReqJceStruct.serializer(), "PushReq") }
// 09 00 01 0A 16 0C 31 38 33 2E 35 37 2E 35 33 2E 31 36 21 1F 90 0B 19 00 01 0A 16 0B 31 38 30 2E 39 36 2E 31 2E 33 30 20 50 0B 29 00 02 0A 16 0D 36 31 2E 31 38 33 2E 31 36 34 2E 34 34 20 50 0B 0A 16 0D 31 31 33 2E 39 36 2E 32 33 32 2E 39 32 20 50 0B 39 00 06 0A 16 0E 31 31 39 2E 31 34 37 2E 31 39 2E 32 34 31 20 50 0B 0A 16 0E 31 31 39 2E 31 34 37 2E 31 39 2E 32 34 34 20 50 0B 0A 16 0E 31 31 39 2E 31 34 37 2E 31 39 2E 32 34 35 20 50 0B 0A 16 0E 31 31 39 2E 31 34 37 2E 31 39 2E 32 35 32 20 50 0B 0A 16 0E 31 31 39 2E 31 34 37 2E 31 39 2E 32 35 33 20 50 0B 0A 16 11 73 63 61 6E 6E 6F 6E 2E 33 67 2E 71 71 2E 63 6F 6D 20 50 0B 49 00 04 0A 16 0E 31 31 33 2E 39 36 2E 32 33 32 2E 31 30 38 20 50 0B 0A 16 0D 31 38 33 2E 33 2E 32 33 33 2E 32 32 35 21 1F 90 0B 0A 16 0E 31 32 33 2E 31 35 30 2E 37 36 2E 31 36 38 21 01 BB 0B 0A 16 0D 31 38 30 2E 31 36 33 2E 32 35 2E 33 38 20 50 0B 5A 09 00 03 0A 00 01 19 00 04 0A 00 01 16 0E 31 31 33 2E 39 36 2E 32 33 32 2E 31 30 38 20 50 0B 0A 00 01 16 0D 31 38 33 2E 33 2E 32 33 33 2E 32 32 35 21 1F 90 0B 0A 00 01 16 0E 31 32 33 2E 31 35 30 2E 37 36 2E 31 36 38 21 01 BB 0B 0A 00 01 16 0D 31 38 30 2E 31 36 33 2E 32 35 2E 33 38 20 50 0B 29 0C 3C 0B 0A 00 05 19 00 04 0A 00 01 16 0E 31 31 33 2E 39 36 2E 32 33 32 2E 31 30 38 20 50 0B 0A 00 01 16 0D 31 38 33 2E 33 2E 32 33 33 2E 32 32 35 21 1F 90 0B 0A 00 01 16 0E 31 32 33 2E 31 35 30 2E 37 36 2E 31 36 38 21 01 BB 0B 0A 00 01 16 0D 31 38 30 2E 31 36 33 2E 32 35 2E 33 38 20 50 0B 29 0C 3C 0B 0A 00 0A 19 00 04 0A 00 01 16 0E 31 31 33 2E 39 36 2E 32 33 32 2E 31 30 38 20 50 0B 0A 00 01 16 0D 31 38 33 2E 33 2E 32 33 33 2E 32 32 35 21 1F 90 0B 0A 00 01 16 0E 31 32 33 2E 31 35 30 2E 37 36 2E 31 36 38 21 01 BB 0B 0A 00 01 16 0D 31 38 30 2E 31 36 33 2E 32 35 2E 33 38 20 50 0B 29 00 05 0A 0C 11 20 00 20 10 30 01 0B 0A 00 01 11 20 00 20 08 30 02 0B 0A 00 02 11 20 00 20 08 30 01 0B 0A 00 03 12 00 01 00 00 20 08 30 02 0B 0A 00 04 11 20 00 20 08 30 02 0B 3C 0B 1D 00 00 68 CA 62 F1 01 C2 AF E6 CF 29 4B 18 71 B5 EE 6B 63 EB F0 0B AB EE A0 5C 20 B9 83 E2 52 F7 BF C7 46 80 BC C3 7F 22 6B 6E 23 42 D0 8F C8 6A C4 F4 49 AA E7 94 EF D4 80 0A E4 8B BF E2 C0 4F FC C5 3F 97 1A E8 0F 0F 7D 06 47 62 C3 C8 07 4F E6 F6 E9 DB CB 4C F5 95 6A AD EC FD D0 46 A5 16 8D 30 02 D5 8A 86 2E 5F E8 D6 8C 2D 00 00 10 33 6E 59 70 73 47 38 52 6E 48 6A 64 51 48 46 54 32 76 E4 B8 DD 40 01 5D 00 01 02 54 8A 50 D0 04 0A 68 CA 62 F1 01 C2 AF E6 CF 29 4B 18 71 B5 EE 6B 63 EB F0 0B AB EE A0 5C 20 B9 83 E2 52 F7 BF C7 46 80 BC C3 7F 22 6B 6E 23 42 D0 8F C8 6A C4 F4 49 AA E7 94 EF D4 80 0A E4 8B BF E2 C0 4F FC C5 3F 97 1A E8 0F 0F 7D 06 47 62 C3 C8 07 4F E6 F6 E9 DB CB 4C F5 95 6A AD EC FD D0 46 A5 16 8D 30 02 D5 8A 86 2E 5F E8 D6 8C 12 10 33 6E 59 70 73 47 38 52 6E 48 6A 64 51 48 46 54 1A 40 08 01 12 0D 08 01 15 71 60 E8 6C 18 50 20 01 28 01 12 0E 08 01 15 B7 03 E9 E1 18 90 3F 20 01 28 01 12 0E 08 01 15 7B 96 4C A8 18 BB 03 20 02 28 00 12 0D 08 01 15 B4 A3 19 26 18 50 20 04 28 00 1A 40 08 05 12 0D 08 01 15 71 60 E8 6C 18 50 20 01 28 01 12 0E 08 01 15 B7 03 E9 E1 18 90 3F 20 01 28 01 12 0E 08 01 15 7B 96 4C A8 18 BB 03 20 02 28 00 12 0D 08 01 15 B4 A3 19 26 18 50 20 04 28 00 1A 78 08 0A 12 0D 08 01 15 71 60 E8 6C 18 50 20 01 28 01 12 0E 08 01 15 B7 03 E9 E1 18 90 3F 20 01 28 01 12 0E 08 01 15 7B 96 4C A8 18 BB 03 20 02 28 00 12 0D 08 01 15 B4 A3 19 26 18 50 20 04 28 00 22 09 08 00 10 80 40 18 10 20 01 22 09 08 01 10 80 40 18 08 20 02 22 09 08 02 10 80 40 18 08 20 01 22 0A 08 03 10 80 80 04 18 08 20 02 22 09 08 04 10 80 40 18 08 20 02 20 01 32 04 08 00 10 01 3A 2A 08 10 10 10 18 09 20 09 28 0F 30 0F 38 05 40 05 48 5A 50 01 58 5A 60 5A 68 5A 70 5A 78 0A 80 01 0A 88 01 0A 90 01 0A 98 01 0A 42 0A 08 00 10 00 18 00 20 00 28 00 4A 06 08 01 10 01 18 03 52 42 08 01 12 0A 08 00 10 80 80 04 18 10 20 02 12 0A 08 01 10 80 80 04 18 08 20 02 12 0A 08 02 10 80 80 01 18 08 20 01 12 0A 08 03 10 80 80 04 18 08 20 02 12 0A 08 04 10 80 80 04 18 08 20 02 18 00 20 00 5A 40 08 01 12 0A 08 00 10 80 80 04 18 10 20 02 12 0A 08 01 10 80 80 04 18 08 20 02 12 0A 08 02 10 80 80 01 18 08 20 01 12 0A 08 03 10 80 80 04 18 08 20 02 12 0A 08 04 10 80 80 04 18 08 20 02 18 00 70 02 78 02 80 01 FA 01 0B 69 00 01 0A 16 26 69 6D 67 63 61 63 68 65 2E 71 71 2E 63 6F 6D 2E 73 63 68 65 64 2E 70 31 76 36 2E 74 64 6E 73 76 36 2E 63 6F 6D 2E 20 50 0B 79 00 02 0A 16 0E 31 30 31 2E 32 32 37 2E 31 33 31 2E 36 37 20 50 0B 0A 16 0D 36 31 2E 31 35 31 2E 31 38 33 2E 32 31 20 50 0B 8A 06 0F 31 37 31 2E 31 31 32 2E 32 32 36 2E 32 33 37 10 03 0B 9A 09 00 0B 0A 00 0F 19 00 01 0A 12 71 19 A3 B4 20 50 0B 29 0C 0B 0A 00 04 19 00 01 0A 12 0B 27 59 65 20 50 0B 29 0C 0B 0A 00 0D 19 00 02 0A 12 55 31 BA DE 20 50 0B 0A 12 5B A0 6A 72 20 50 0B 29 0C 0B 0A 00 03 19 00 02 0A 12 C3 B9 D3 74 20 50 0B 0A 12 CC 43 E4 DD 20 50 0B 29 0C 0B 0A 00 07 19 00 01 0A 12 75 A2 E3 65 20 50 0B 29 0C 0B 0A 00 09 19 00 02 0A 12 BC 6C 24 B7 20 50 0B 0A 12 A6 6C 24 B7 20 50 0B 29 0C 0B 0A 00 0A 19 00 02 0A 12 11 B4 12 0E 20 50 0B 0A 12 15 8C D7 0E 20 50 0B 29 0C 0B 0A 00 05 19 00 01 0A 12 1D E2 03 B7 20 50 0B 29 0C 0B 0A 00 08 19 00 02 0A 12 DE 3F 5B 65 20 50 0B 0A 12 78 09 61 B4 20 50 0B 29 0C 0B 0A 00 06 19 00 02 0A 12 16 CF 97 3D 20 50 0B 0A 12 54 10 59 65 20 50 0B 29 0C 0B 0A 00 0E 19 00 02 0A 12 76 01 B1 6F 20 50 0B 0A 12 6B 89 31 3A 20 50 0B 29 0C 0B 0B AD 00 01 01 5B 08 01 10 A4 F6 AA 16 18 00 22 0A 31 39 39 34 37 30 31 30 32 31 28 AB E1 89 EF 0E 32 12 08 8E A4 D8 A5 09 10 50 18 89 D8 AC F0 08 20 50 28 64 32 12 08 8E A4 C4 DD 08 10 50 18 89 F4 DE E0 05 20 50 28 64 32 13 08 B4 C7 DA B0 02 10 50 18 8A EE D4 F2 0D 20 50 28 C8 01 32 13 08 B4 C7 DA A0 02 10 50 18 8A EC D0 86 0E 20 50 28 C8 01 32 13 08 8C 9D 9B 85 07 10 50 18 89 D6 AD 9C 09 20 50 28 AC 02 32 13 08 B7 81 97 F6 06 10 50 18 8A EC D4 96 02 20 50 28 AC 02 3A 1E 0A 10 24 0E 00 E1 A9 00 00 50 00 00 00 00 00 00 00 29 10 50 18 89 EC 8C B1 05 20 50 28 64 3A 1E 0A 10 24 0E 00 E1 A9 00 00 50 00 00 00 00 00 00 00 64 10 50 18 89 EC 8C D1 07 20 50 28 64 3A 1F 0A 10 24 0E 00 FF F1 01 00 10 00 00 00 00 00 00 01 6F 10 50 18 E4 E6 B1 F0 04 20 50 28 C8 01 3A 1F 0A 10 24 0E 00 FF F1 01 00 10 00 00 00 00 00 00 01 72 10 50 18 E4 E6 AD F0 0E 20 50 28 C8 01 3A 1F 0A 10 24 09 8C 1E 75 B0 00 13 00 00 00 00 00 00 00 36 10 50 18 89 EC 9C E8 0D 20 50 28 AC 02 3A 1F 0A 10 24 09 8C 54 10 03 00 10 00 00 00 00 00 00 00 55 10 50 18 89 CA 8C A0 01 20 50 28 AC 02 // 09 00 01 0A 16 0C 31 38 33 2E 35 37 2E 35 33 2E 31 36 21 1F 90 0B 19 00 01 0A 16 0B 31 38 30 2E 39 36 2E 31 2E 33 30 20 50 0B 29 00 02 0A 16 0D 36 31 2E 31 38 33 2E 31 36 34 2E 34 34 20 50 0B 0A 16 0D 31 31 33 2E 39 36 2E 32 33 32 2E 39 32 20 50 0B 39 00 06 0A 16 0E 31 31 39 2E 31 34 37 2E 31 39 2E 32 34 31 20 50 0B 0A 16 0E 31 31 39 2E 31 34 37 2E 31 39 2E 32 34 34 20 50 0B 0A 16 0E 31 31 39 2E 31 34 37 2E 31 39 2E 32 34 35 20 50 0B 0A 16 0E 31 31 39 2E 31 34 37 2E 31 39 2E 32 35 32 20 50 0B 0A 16 0E 31 31 39 2E 31 34 37 2E 31 39 2E 32 35 33 20 50 0B 0A 16 11 73 63 61 6E 6E 6F 6E 2E 33 67 2E 71 71 2E 63 6F 6D 20 50 0B 49 00 04 0A 16 0E 31 31 33 2E 39 36 2E 32 33 32 2E 31 30 38 20 50 0B 0A 16 0D 31 38 33 2E 33 2E 32 33 33 2E 32 32 35 21 1F 90 0B 0A 16 0E 31 32 33 2E 31 35 30 2E 37 36 2E 31 36 38 21 01 BB 0B 0A 16 0D 31 38 30 2E 31 36 33 2E 32 35 2E 33 38 20 50 0B 5A 09 00 03 0A 00 01 19 00 04 0A 00 01 16 0E 31 31 33 2E 39 36 2E 32 33 32 2E 31 30 38 20 50 0B 0A 00 01 16 0D 31 38 33 2E 33 2E 32 33 33 2E 32 32 35 21 1F 90 0B 0A 00 01 16 0E 31 32 33 2E 31 35 30 2E 37 36 2E 31 36 38 21 01 BB 0B 0A 00 01 16 0D 31 38 30 2E 31 36 33 2E 32 35 2E 33 38 20 50 0B 29 0C 3C 0B 0A 00 05 19 00 04 0A 00 01 16 0E 31 31 33 2E 39 36 2E 32 33 32 2E 31 30 38 20 50 0B 0A 00 01 16 0D 31 38 33 2E 33 2E 32 33 33 2E 32 32 35 21 1F 90 0B 0A 00 01 16 0E 31 32 33 2E 31 35 30 2E 37 36 2E 31 36 38 21 01 BB 0B 0A 00 01 16 0D 31 38 30 2E 31 36 33 2E 32 35 2E 33 38 20 50 0B 29 0C 3C 0B 0A 00 0A 19 00 04 0A 00 01 16 0E 31 31 33 2E 39 36 2E 32 33 32 2E 31 30 38 20 50 0B 0A 00 01 16 0D 31 38 33 2E 33 2E 32 33 33 2E 32 32 35 21 1F 90 0B 0A 00 01 16 0E 31 32 33 2E 31 35 30 2E 37 36 2E 31 36 38 21 01 BB 0B 0A 00 01 16 0D 31 38 30 2E 31 36 33 2E 32 35 2E 33 38 20 50 0B 29 00 05 0A 0C 11 20 00 20 10 30 01 0B 0A 00 01 11 20 00 20 08 30 02 0B 0A 00 02 11 20 00 20 08 30 01 0B 0A 00 03 12 00 01 00 00 20 08 30 02 0B 0A 00 04 11 20 00 20 08 30 02 0B 3C 0B 1D 00 00 68 CA 62 F1 01 C2 AF E6 CF 29 4B 18 71 B5 EE 6B 63 EB F0 0B AB EE A0 5C 20 B9 83 E2 52 F7 BF C7 46 80 BC C3 7F 22 6B 6E 23 42 D0 8F C8 6A C4 F4 49 AA E7 94 EF D4 80 0A E4 8B BF E2 C0 4F FC C5 3F 97 1A E8 0F 0F 7D 06 47 62 C3 C8 07 4F E6 F6 E9 DB CB 4C F5 95 6A AD EC FD D0 46 A5 16 8D 30 02 D5 8A 86 2E 5F E8 D6 8C 2D 00 00 10 33 6E 59 70 73 47 38 52 6E 48 6A 64 51 48 46 54 32 76 E4 B8 DD 40 01 5D 00 01 02 54 8A 50 D0 04 0A 68 CA 62 F1 01 C2 AF E6 CF 29 4B 18 71 B5 EE 6B 63 EB F0 0B AB EE A0 5C 20 B9 83 E2 52 F7 BF C7 46 80 BC C3 7F 22 6B 6E 23 42 D0 8F C8 6A C4 F4 49 AA E7 94 EF D4 80 0A E4 8B BF E2 C0 4F FC C5 3F 97 1A E8 0F 0F 7D 06 47 62 C3 C8 07 4F E6 F6 E9 DB CB 4C F5 95 6A AD EC FD D0 46 A5 16 8D 30 02 D5 8A 86 2E 5F E8 D6 8C 12 10 33 6E 59 70 73 47 38 52 6E 48 6A 64 51 48 46 54 1A 40 08 01 12 0D 08 01 15 71 60 E8 6C 18 50 20 01 28 01 12 0E 08 01 15 B7 03 E9 E1 18 90 3F 20 01 28 01 12 0E 08 01 15 7B 96 4C A8 18 BB 03 20 02 28 00 12 0D 08 01 15 B4 A3 19 26 18 50 20 04 28 00 1A 40 08 05 12 0D 08 01 15 71 60 E8 6C 18 50 20 01 28 01 12 0E 08 01 15 B7 03 E9 E1 18 90 3F 20 01 28 01 12 0E 08 01 15 7B 96 4C A8 18 BB 03 20 02 28 00 12 0D 08 01 15 B4 A3 19 26 18 50 20 04 28 00 1A 78 08 0A 12 0D 08 01 15 71 60 E8 6C 18 50 20 01 28 01 12 0E 08 01 15 B7 03 E9 E1 18 90 3F 20 01 28 01 12 0E 08 01 15 7B 96 4C A8 18 BB 03 20 02 28 00 12 0D 08 01 15 B4 A3 19 26 18 50 20 04 28 00 22 09 08 00 10 80 40 18 10 20 01 22 09 08 01 10 80 40 18 08 20 02 22 09 08 02 10 80 40 18 08 20 01 22 0A 08 03 10 80 80 04 18 08 20 02 22 09 08 04 10 80 40 18 08 20 02 20 01 32 04 08 00 10 01 3A 2A 08 10 10 10 18 09 20 09 28 0F 30 0F 38 05 40 05 48 5A 50 01 58 5A 60 5A 68 5A 70 5A 78 0A 80 01 0A 88 01 0A 90 01 0A 98 01 0A 42 0A 08 00 10 00 18 00 20 00 28 00 4A 06 08 01 10 01 18 03 52 42 08 01 12 0A 08 00 10 80 80 04 18 10 20 02 12 0A 08 01 10 80 80 04 18 08 20 02 12 0A 08 02 10 80 80 01 18 08 20 01 12 0A 08 03 10 80 80 04 18 08 20 02 12 0A 08 04 10 80 80 04 18 08 20 02 18 00 20 00 5A 40 08 01 12 0A 08 00 10 80 80 04 18 10 20 02 12 0A 08 01 10 80 80 04 18 08 20 02 12 0A 08 02 10 80 80 01 18 08 20 01 12 0A 08 03 10 80 80 04 18 08 20 02 12 0A 08 04 10 80 80 04 18 08 20 02 18 00 70 02 78 02 80 01 FA 01 0B 69 00 01 0A 16 26 69 6D 67 63 61 63 68 65 2E 71 71 2E 63 6F 6D 2E 73 63 68 65 64 2E 70 31 76 36 2E 74 64 6E 73 76 36 2E 63 6F 6D 2E 20 50 0B 79 00 02 0A 16 0E 31 30 31 2E 32 32 37 2E 31 33 31 2E 36 37 20 50 0B 0A 16 0D 36 31 2E 31 35 31 2E 31 38 33 2E 32 31 20 50 0B 8A 06 0F 31 37 31 2E 31 31 32 2E 32 32 36 2E 32 33 37 10 03 0B 9A 09 00 0B 0A 00 0F 19 00 01 0A 12 71 19 A3 B4 20 50 0B 29 0C 0B 0A 00 04 19 00 01 0A 12 0B 27 59 65 20 50 0B 29 0C 0B 0A 00 0D 19 00 02 0A 12 55 31 BA DE 20 50 0B 0A 12 5B A0 6A 72 20 50 0B 29 0C 0B 0A 00 03 19 00 02 0A 12 C3 B9 D3 74 20 50 0B 0A 12 CC 43 E4 DD 20 50 0B 29 0C 0B 0A 00 07 19 00 01 0A 12 75 A2 E3 65 20 50 0B 29 0C 0B 0A 00 09 19 00 02 0A 12 BC 6C 24 B7 20 50 0B 0A 12 A6 6C 24 B7 20 50 0B 29 0C 0B 0A 00 0A 19 00 02 0A 12 11 B4 12 0E 20 50 0B 0A 12 15 8C D7 0E 20 50 0B 29 0C 0B 0A 00 05 19 00 01 0A 12 1D E2 03 B7 20 50 0B 29 0C 0B 0A 00 08 19 00 02 0A 12 DE 3F 5B 65 20 50 0B 0A 12 78 09 61 B4 20 50 0B 29 0C 0B 0A 00 06 19 00 02 0A 12 16 CF 97 3D 20 50 0B 0A 12 54 10 59 65 20 50 0B 29 0C 0B 0A 00 0E 19 00 02 0A 12 76 01 B1 6F 20 50 0B 0A 12 6B 89 31 3A 20 50 0B 29 0C 0B 0B AD 00 01 01 5B 08 01 10 A4 F6 AA 16 18 00 22 0A 31 39 39 34 37 30 31 30 32 31 28 AB E1 89 EF 0E 32 12 08 8E A4 D8 A5 09 10 50 18 89 D8 AC F0 08 20 50 28 64 32 12 08 8E A4 C4 DD 08 10 50 18 89 F4 DE E0 05 20 50 28 64 32 13 08 B4 C7 DA B0 02 10 50 18 8A EE D4 F2 0D 20 50 28 C8 01 32 13 08 B4 C7 DA A0 02 10 50 18 8A EC D0 86 0E 20 50 28 C8 01 32 13 08 8C 9D 9B 85 07 10 50 18 89 D6 AD 9C 09 20 50 28 AC 02 32 13 08 B7 81 97 F6 06 10 50 18 8A EC D4 96 02 20 50 28 AC 02 3A 1E 0A 10 24 0E 00 E1 A9 00 00 50 00 00 00 00 00 00 00 29 10 50 18 89 EC 8C B1 05 20 50 28 64 3A 1E 0A 10 24 0E 00 E1 A9 00 00 50 00 00 00 00 00 00 00 64 10 50 18 89 EC 8C D1 07 20 50 28 64 3A 1F 0A 10 24 0E 00 FF F1 01 00 10 00 00 00 00 00 00 01 6F 10 50 18 E4 E6 B1 F0 04 20 50 28 C8 01 3A 1F 0A 10 24 0E 00 FF F1 01 00 10 00 00 00 00 00 00 01 72 10 50 18 E4 E6 AD F0 0E 20 50 28 C8 01 3A 1F 0A 10 24 09 8C 1E 75 B0 00 13 00 00 00 00 00 00 00 36 10 50 18 89 EC 9C E8 0D 20 50 28 AC 02 3A 1F 0A 10 24 09 8C 54 10 03 00 10 00 00 00 00 00 00 00 55 10 50 18 89 CA 8C A0 01 20 50 28 AC 02
// ?? // ??
// 19 00 0A 0A 16 0C 31 31 33 2E 39 36 2E 31 32 2E 38 35 21 36 B0 30 01 4C 5C 60 08 70 01 86 02 73 7A 96 03 74 65 6C 0B 0A 16 0E 31 31 34 2E 32 32 31 2E 31 34 34 2E 33 33 21 36 B0 30 01 4C 5C 60 08 70 01 86 02 73 68 96 03 74 65 6C 0B 0A 16 0D 31 31 33 2E 39 36 2E 31 32 2E 32 32 34 21 1F 90 30 01 4C 5C 60 08 70 01 86 02 73 7A 96 03 74 65 6C 0B 0A 16 0C 34 32 2E 38 31 2E 31 37 32 2E 36 33 21 01 BB 30 01 4C 5C 60 08 70 01 86 02 74 6A 96 03 74 65 6C 0B 0A 16 0E 31 31 34 2E 32 32 31 2E 31 34 34 2E 37 36 20 50 30 01 4C 5C 60 08 70 01 86 02 73 68 96 03 74 65 6C 0B 0A 16 0D 31 31 33 2E 39 36 2E 31 32 2E 32 31 37 21 36 B0 30 01 4C 5C 60 08 70 01 86 02 73 7A 96 03 74 65 6C 0B 0A 16 0D 34 32 2E 38 31 2E 31 37 30 2E 31 32 32 21 01 BB 30 01 4C 5C 60 08 70 01 86 02 74 6A 96 03 74 65 6C 0B 0A 16 0E 31 31 34 2E 32 32 31 2E 31 34 38 2E 31 34 21 1F 90 30 01 4C 5C 60 08 70 01 86 02 73 68 96 03 74 65 6C 0B 0A 16 11 6D 73 66 77 69 66 69 2E 33 67 2E 71 71 2E 63 6F 6D 21 1F 90 30 01 4C 5C 60 08 7C 86 06 6F 74 68 65 72 73 96 06 6F 74 68 65 72 73 0B 0A 16 0D 34 32 2E 38 31 2E 31 37 32 2E 32 30 37 20 50 30 01 4C 5C 60 08 70 01 86 02 74 6A 96 03 74 65 6C 0B 39 00 0A 0A 16 0C 31 31 33 2E 39 36 2E 31 32 2E 38 35 21 36 B0 30 01 4C 5C 60 08 70 01 86 02 73 7A 96 03 74 65 6C 0B 0A 16 0E 31 31 34 2E 32 32 31 2E 31 34 34 2E 33 33 21 36 B0 30 01 4C 5C 60 08 70 01 86 02 73 68 96 03 74 65 6C 0B 0A 16 0D 31 31 33 2E 39 36 2E 31 32 2E 32 32 34 21 1F 90 30 01 4C 5C 60 08 70 01 86 02 73 7A 96 03 74 65 6C 0B 0A 16 0C 34 32 2E 38 31 2E 31 37 32 2E 36 33 21 01 BB 30 01 4C 5C 60 08 70 01 86 02 74 6A 96 03 74 65 6C 0B 0A 16 0E 31 31 34 2E 32 32 31 2E 31 34 34 2E 37 36 20 50 30 01 4C 5C 60 08 70 01 86 02 73 68 96 03 74 65 6C 0B 0A 16 0D 31 31 33 2E 39 36 2E 31 32 2E 32 31 37 21 36 B0 30 01 4C 5C 60 08 70 01 86 02 73 7A 96 03 74 65 6C 0B 0A 16 0D 34 32 2E 38 31 2E 31 37 30 2E 31 32 32 21 01 BB 30 01 4C 5C 60 08 70 01 86 02 74 6A 96 03 74 65 6C 0B 0A 16 0E 31 31 34 2E 32 32 31 2E 31 34 38 2E 31 34 21 1F 90 30 01 4C 5C 60 08 70 01 86 02 73 68 96 03 74 65 6C 0B 0A 16 11 6D 73 66 77 69 66 69 2E 33 67 2E 71 71 2E 63 6F 6D 21 1F 90 30 01 4C 5C 60 08 7C 86 06 6F 74 68 65 72 73 96 06 6F 74 68 65 72 73 0B 0A 16 0D 34 32 2E 38 31 2E 31 37 32 2E 32 30 37 20 50 30 01 4C 5C 60 08 70 01 86 02 74 6A 96 03 74 65 6C 0B 4C 5C 6C 70 01 89 00 04 0A 16 0C 31 31 33 2E 39 36 2E 31 33 2E 34 34 20 50 30 01 4C 50 03 60 08 7C 86 02 73 7A 96 03 74 65 6C 0B 0A 16 0E 31 31 34 2E 32 32 31 2E 31 34 34 2E 32 32 20 50 30 01 4C 50 03 60 08 7C 86 02 73 68 96 03 74 65 6C 0B 0A 16 0D 34 32 2E 38 31 2E 31 36 39 2E 31 30 35 20 50 30 01 4C 50 03 60 08 7C 86 02 74 6A 96 03 74 65 6C 0B 0A 16 0D 34 32 2E 38 31 2E 31 36 39 2E 31 30 35 20 50 30 01 4C 50 03 60 08 7C 86 02 74 6A 96 03 74 65 6C 0B 99 00 04 0A 16 0C 31 31 33 2E 39 36 2E 31 33 2E 34 34 20 50 30 01 4C 50 03 60 08 7C 86 02 73 7A 96 03 74 65 6C 0B 0A 16 0E 31 31 34 2E 32 32 31 2E 31 34 34 2E 32 32 20 50 30 01 4C 50 03 60 08 7C 86 02 73 68 96 03 74 65 6C 0B 0A 16 0D 34 32 2E 38 31 2E 31 36 39 2E 31 30 35 20 50 30 01 4C 50 03 60 08 7C 86 02 74 6A 96 03 74 65 6C 0B 0A 16 0D 34 32 2E 38 31 2E 31 36 39 2E 31 30 35 20 50 30 01 4C 50 03 60 08 7C 86 02 74 6A 96 03 74 65 6C 0B A9 0C B9 0C C9 0C D9 0C E0 01 FC 0F F6 10 28 32 30 32 30 2D 30 34 2D 31 32 20 31 39 3A 31 30 3A 30 38 20 64 65 6C 69 76 65 72 79 69 6E 67 20 61 20 70 6F 6C 69 63 79 // 19 00 0A 0A 16 0C 31 31 33 2E 39 36 2E 31 32 2E 38 35 21 36 B0 30 01 4C 5C 60 08 70 01 86 02 73 7A 96 03 74 65 6C 0B 0A 16 0E 31 31 34 2E 32 32 31 2E 31 34 34 2E 33 33 21 36 B0 30 01 4C 5C 60 08 70 01 86 02 73 68 96 03 74 65 6C 0B 0A 16 0D 31 31 33 2E 39 36 2E 31 32 2E 32 32 34 21 1F 90 30 01 4C 5C 60 08 70 01 86 02 73 7A 96 03 74 65 6C 0B 0A 16 0C 34 32 2E 38 31 2E 31 37 32 2E 36 33 21 01 BB 30 01 4C 5C 60 08 70 01 86 02 74 6A 96 03 74 65 6C 0B 0A 16 0E 31 31 34 2E 32 32 31 2E 31 34 34 2E 37 36 20 50 30 01 4C 5C 60 08 70 01 86 02 73 68 96 03 74 65 6C 0B 0A 16 0D 31 31 33 2E 39 36 2E 31 32 2E 32 31 37 21 36 B0 30 01 4C 5C 60 08 70 01 86 02 73 7A 96 03 74 65 6C 0B 0A 16 0D 34 32 2E 38 31 2E 31 37 30 2E 31 32 32 21 01 BB 30 01 4C 5C 60 08 70 01 86 02 74 6A 96 03 74 65 6C 0B 0A 16 0E 31 31 34 2E 32 32 31 2E 31 34 38 2E 31 34 21 1F 90 30 01 4C 5C 60 08 70 01 86 02 73 68 96 03 74 65 6C 0B 0A 16 11 6D 73 66 77 69 66 69 2E 33 67 2E 71 71 2E 63 6F 6D 21 1F 90 30 01 4C 5C 60 08 7C 86 06 6F 74 68 65 72 73 96 06 6F 74 68 65 72 73 0B 0A 16 0D 34 32 2E 38 31 2E 31 37 32 2E 32 30 37 20 50 30 01 4C 5C 60 08 70 01 86 02 74 6A 96 03 74 65 6C 0B 39 00 0A 0A 16 0C 31 31 33 2E 39 36 2E 31 32 2E 38 35 21 36 B0 30 01 4C 5C 60 08 70 01 86 02 73 7A 96 03 74 65 6C 0B 0A 16 0E 31 31 34 2E 32 32 31 2E 31 34 34 2E 33 33 21 36 B0 30 01 4C 5C 60 08 70 01 86 02 73 68 96 03 74 65 6C 0B 0A 16 0D 31 31 33 2E 39 36 2E 31 32 2E 32 32 34 21 1F 90 30 01 4C 5C 60 08 70 01 86 02 73 7A 96 03 74 65 6C 0B 0A 16 0C 34 32 2E 38 31 2E 31 37 32 2E 36 33 21 01 BB 30 01 4C 5C 60 08 70 01 86 02 74 6A 96 03 74 65 6C 0B 0A 16 0E 31 31 34 2E 32 32 31 2E 31 34 34 2E 37 36 20 50 30 01 4C 5C 60 08 70 01 86 02 73 68 96 03 74 65 6C 0B 0A 16 0D 31 31 33 2E 39 36 2E 31 32 2E 32 31 37 21 36 B0 30 01 4C 5C 60 08 70 01 86 02 73 7A 96 03 74 65 6C 0B 0A 16 0D 34 32 2E 38 31 2E 31 37 30 2E 31 32 32 21 01 BB 30 01 4C 5C 60 08 70 01 86 02 74 6A 96 03 74 65 6C 0B 0A 16 0E 31 31 34 2E 32 32 31 2E 31 34 38 2E 31 34 21 1F 90 30 01 4C 5C 60 08 70 01 86 02 73 68 96 03 74 65 6C 0B 0A 16 11 6D 73 66 77 69 66 69 2E 33 67 2E 71 71 2E 63 6F 6D 21 1F 90 30 01 4C 5C 60 08 7C 86 06 6F 74 68 65 72 73 96 06 6F 74 68 65 72 73 0B 0A 16 0D 34 32 2E 38 31 2E 31 37 32 2E 32 30 37 20 50 30 01 4C 5C 60 08 70 01 86 02 74 6A 96 03 74 65 6C 0B 4C 5C 6C 70 01 89 00 04 0A 16 0C 31 31 33 2E 39 36 2E 31 33 2E 34 34 20 50 30 01 4C 50 03 60 08 7C 86 02 73 7A 96 03 74 65 6C 0B 0A 16 0E 31 31 34 2E 32 32 31 2E 31 34 34 2E 32 32 20 50 30 01 4C 50 03 60 08 7C 86 02 73 68 96 03 74 65 6C 0B 0A 16 0D 34 32 2E 38 31 2E 31 36 39 2E 31 30 35 20 50 30 01 4C 50 03 60 08 7C 86 02 74 6A 96 03 74 65 6C 0B 0A 16 0D 34 32 2E 38 31 2E 31 36 39 2E 31 30 35 20 50 30 01 4C 50 03 60 08 7C 86 02 74 6A 96 03 74 65 6C 0B 99 00 04 0A 16 0C 31 31 33 2E 39 36 2E 31 33 2E 34 34 20 50 30 01 4C 50 03 60 08 7C 86 02 73 7A 96 03 74 65 6C 0B 0A 16 0E 31 31 34 2E 32 32 31 2E 31 34 34 2E 32 32 20 50 30 01 4C 50 03 60 08 7C 86 02 73 68 96 03 74 65 6C 0B 0A 16 0D 34 32 2E 38 31 2E 31 36 39 2E 31 30 35 20 50 30 01 4C 50 03 60 08 7C 86 02 74 6A 96 03 74 65 6C 0B 0A 16 0D 34 32 2E 38 31 2E 31 36 39 2E 31 30 35 20 50 30 01 4C 50 03 60 08 7C 86 02 74 6A 96 03 74 65 6C 0B A9 0C B9 0C C9 0C D9 0C E0 01 FC 0F F6 10 28 32 30 32 30 2D 30 34 2D 31 32 20 31 39 3A 31 30 3A 30 38 20 64 65 6C 69 76 65 72 79 69 6E 67 20 61 20 70 6F 6C 69 63 79
kotlin.runCatching { runCatching<Unit> {
configPush.jcebuf.loadAs(FileStoragePushFSSvcListFuckKotlin.serializer()).also { configPush.jcebuf.loadAs(FileStoragePushFSSvcListFuckKotlin.serializer()).also {
bot.client.fileStoragePushFSSvcList = it bot.client.fileStoragePushFSSvcList = it
} }
}.getOrElse { }.getOrElse {
val default = """ bot.client.fileStoragePushFSSvcList = default
09 00 01 0A 16 0C 31 38 33 2E 35 37 2E 35 33 2E 31 36 21 1F 90 0B 19 00 01 0A 16 0B 31 38 30 2E 39 36 2E 31 2E 33 30 20 50 0B 29 00 02 0A 16 0D 36 31 2E 31 38 33 2E 31 36 34 2E 34 34 20 50 0B 0A 16 0D 31 31 33 2E 39 36 2E 32 33 32 2E 39 32 20 50 0B 39 00 06 0A 16 0E 31 31 39 2E 31 34 37 2E 31 39 2E 32 34 31 20 50 0B 0A 16 0E 31 31 39 2E 31 34 37 2E 31 39 2E 32 34 34 20 50 0B 0A 16 0E 31 31 39 2E 31 34 37 2E 31 39 2E 32 34 35 20 50 0B 0A 16 0E 31 31 39 2E 31 34 37 2E 31 39 2E 32 35 32 20 50 0B 0A 16 0E 31 31 39 2E 31 34 37 2E 31 39 2E 32 35 33 20 50 0B 0A 16 11 73 63 61 6E 6E 6F 6E 2E 33 67 2E 71 71 2E 63 6F 6D 20 50 0B 49 00 04 0A 16 0E 31 31 33 2E 39 36 2E 32 33 32 2E 31 30 38 20 50 0B 0A 16 0D 31 38 33 2E 33 2E 32 33 33 2E 32 32 35 21 1F 90 0B 0A 16 0E 31 32 33 2E 31 35 30 2E 37 36 2E 31 36 38 21 01 BB 0B 0A 16 0D 31 38 30 2E 31 36 33 2E 32 35 2E 33 38 20 50 0B 5A 09 00 03 0A 00 01 19 00 04 0A 00 01 16 0E 31 31 33 2E 39 36 2E 32 33 32 2E 31 30 38 20 50 0B 0A 00 01 16 0D 31 38 33 2E 33 2E 32 33 33 2E 32 32 35 21 1F 90 0B 0A 00 01 16 0E 31 32 33 2E 31 35 30 2E 37 36 2E 31 36 38 21 01 BB 0B 0A 00 01 16 0D 31 38 30 2E 31 36 33 2E 32 35 2E 33 38 20 50 0B 29 0C 3C 0B 0A 00 05 19 00 04 0A 00 01 16 0E 31 31 33 2E 39 36 2E 32 33 32 2E 31 30 38 20 50 0B 0A 00 01 16 0D 31 38 33 2E 33 2E 32 33 33 2E 32 32 35 21 1F 90 0B 0A 00 01 16 0E 31 32 33 2E 31 35 30 2E 37 36 2E 31 36 38 21 01 BB 0B 0A 00 01 16 0D 31 38 30 2E 31 36 33 2E 32 35 2E 33 38 20 50 0B 29 0C 3C 0B 0A 00 0A 19 00 04 0A 00 01 16 0E 31 31 33 2E 39 36 2E 32 33 32 2E 31 30 38 20 50 0B 0A 00 01 16 0D 31 38 33 2E 33 2E 32 33 33 2E 32 32 35 21 1F 90 0B 0A 00 01 16 0E 31 32 33 2E 31 35 30 2E 37 36 2E 31 36 38 21 01 BB 0B 0A 00 01 16 0D 31 38 30 2E 31 36 33 2E 32 35 2E 33 38 20 50 0B 29 00 05 0A 0C 11 20 00 20 10 30 01 0B 0A 00 01 11 20 00 20 08 30 02 0B 0A 00 02 11 20 00 20 08 30 01 0B 0A 00 03 12 00 01 00 00 20 08 30 02 0B 0A 00 04 11 20 00 20 08 30 02 0B 3C 0B 1D 00 00 68 CA 62 F1 01 C2 AF E6 CF 29 4B 18 71 B5 EE 6B 63 EB F0 0B AB EE A0 5C 20 B9 83 E2 52 F7 BF C7 46 80 BC C3 7F 22 6B 6E 23 42 D0 8F C8 6A C4 F4 49 AA E7 94 EF D4 80 0A E4 8B BF E2 C0 4F FC C5 3F 97 1A E8 0F 0F 7D 06 47 62 C3 C8 07 4F E6 F6 E9 DB CB 4C F5 95 6A AD EC FD D0 46 A5 16 8D 30 02 D5 8A 86 2E 5F E8 D6 8C 2D 00 00 10 33 6E 59 70 73 47 38 52 6E 48 6A 64 51 48 46 54 32 76 E4 B8 DD 40 01 5D 00 01 02 54 8A 50 D0 04 0A 68 CA 62 F1 01 C2 AF E6 CF 29 4B 18 71 B5 EE 6B 63 EB F0 0B AB EE A0 5C 20 B9 83 E2 52 F7 BF C7 46 80 BC C3 7F 22 6B 6E 23 42 D0 8F C8 6A C4 F4 49 AA E7 94 EF D4 80 0A E4 8B BF E2 C0 4F FC C5 3F 97 1A E8 0F 0F 7D 06 47 62 C3 C8 07 4F E6 F6 E9 DB CB 4C F5 95 6A AD EC FD D0 46 A5 16 8D 30 02 D5 8A 86 2E 5F E8 D6 8C 12 10 33 6E 59 70 73 47 38 52 6E 48 6A 64 51 48 46 54 1A 40 08 01 12 0D 08 01 15 71 60 E8 6C 18 50 20 01 28 01 12 0E 08 01 15 B7 03 E9 E1 18 90 3F 20 01 28 01 12 0E 08 01 15 7B 96 4C A8 18 BB 03 20 02 28 00 12 0D 08 01 15 B4 A3 19 26 18 50 20 04 28 00 1A 40 08 05 12 0D 08 01 15 71 60 E8 6C 18 50 20 01 28 01 12 0E 08 01 15 B7 03 E9 E1 18 90 3F 20 01 28 01 12 0E 08 01 15 7B 96 4C A8 18 BB 03 20 02 28 00 12 0D 08 01 15 B4 A3 19 26 18 50 20 04 28 00 1A 78 08 0A 12 0D 08 01 15 71 60 E8 6C 18 50 20 01 28 01 12 0E 08 01 15 B7 03 E9 E1 18 90 3F 20 01 28 01 12 0E 08 01 15 7B 96 4C A8 18 BB 03 20 02 28 00 12 0D 08 01 15 B4 A3 19 26 18 50 20 04 28 00 22 09 08 00 10 80 40 18 10 20 01 22 09 08 01 10 80 40 18 08 20 02 22 09 08 02 10 80 40 18 08 20 01 22 0A 08 03 10 80 80 04 18 08 20 02 22 09 08 04 10 80 40 18 08 20 02 20 01 32 04 08 00 10 01 3A 2A 08 10 10 10 18 09 20 09 28 0F 30 0F 38 05 40 05 48 5A 50 01 58 5A 60 5A 68 5A 70 5A 78 0A 80 01 0A 88 01 0A 90 01 0A 98 01 0A 42 0A 08 00 10 00 18 00 20 00 28 00 4A 06 08 01 10 01 18 03 52 42 08 01 12 0A 08 00 10 80 80 04 18 10 20 02 12 0A 08 01 10 80 80 04 18 08 20 02 12 0A 08 02 10 80 80 01 18 08 20 01 12 0A 08 03 10 80 80 04 18 08 20 02 12 0A 08 04 10 80 80 04 18 08 20 02 18 00 20 00 5A 40 08 01 12 0A 08 00 10 80 80 04 18 10 20 02 12 0A 08 01 10 80 80 04 18 08 20 02 12 0A 08 02 10 80 80 01 18 08 20 01 12 0A 08 03 10 80 80 04 18 08 20 02 12 0A 08 04 10 80 80 04 18 08 20 02 18 00 70 02 78 02 80 01 FA 01 0B 69 00 01 0A 16 26 69 6D 67 63 61 63 68 65 2E 71 71 2E 63 6F 6D 2E 73 63 68 65 64 2E 70 31 76 36 2E 74 64 6E 73 76 36 2E 63 6F 6D 2E 20 50 0B 79 00 02 0A 16 0E 31 30 31 2E 32 32 37 2E 31 33 31 2E 36 37 20 50 0B 0A 16 0D 36 31 2E 31 35 31 2E 31 38 33 2E 32 31 20 50 0B 8A 06 0F 31 37 31 2E 31 31 32 2E 32 32 36 2E 32 33 37 10 03 0B 9A 09 00 0B 0A 00 0F 19 00 01 0A 12 71 19 A3 B4 20 50 0B 29 0C 0B 0A 00 04 19 00 01 0A 12 0B 27 59 65 20 50 0B 29 0C 0B 0A 00 0D 19 00 02 0A 12 55 31 BA DE 20 50 0B 0A 12 5B A0 6A 72 20 50 0B 29 0C 0B 0A 00 03 19 00 02 0A 12 C3 B9 D3 74 20 50 0B 0A 12 CC 43 E4 DD 20 50 0B 29 0C 0B 0A 00 07 19 00 01 0A 12 75 A2 E3 65 20 50 0B 29 0C 0B 0A 00 09 19 00 02 0A 12 BC 6C 24 B7 20 50 0B 0A 12 A6 6C 24 B7 20 50 0B 29 0C 0B 0A 00 0A 19 00 02 0A 12 11 B4 12 0E 20 50 0B 0A 12 15 8C D7 0E 20 50 0B 29 0C 0B 0A 00 05 19 00 01 0A 12 1D E2 03 B7 20 50 0B 29 0C 0B 0A 00 08 19 00 02 0A 12 DE 3F 5B 65 20 50 0B 0A 12 78 09 61 B4 20 50 0B 29 0C 0B 0A 00 06 19 00 02 0A 12 16 CF 97 3D 20 50 0B 0A 12 54 10 59 65 20 50 0B 29 0C 0B 0A 00 0E 19 00 02 0A 12 76 01 B1 6F 20 50 0B 0A 12 6B 89 31 3A 20 50 0B 29 0C 0B 0B AD 00 01 01 5B 08 01 10 A4 F6 AA 16 18 00 22 0A 31 39 39 34 37 30 31 30 32 31 28 AB E1 89 EF 0E 32 12 08 8E A4 D8 A5 09 10 50 18 89 D8 AC F0 08 20 50 28 64 32 12 08 8E A4 C4 DD 08 10 50 18 89 F4 DE E0 05 20 50 28 64 32 13 08 B4 C7 DA B0 02 10 50 18 8A EE D4 F2 0D 20 50 28 C8 01 32 13 08 B4 C7 DA A0 02 10 50 18 8A EC D0 86 0E 20 50 28 C8 01 32 13 08 8C 9D 9B 85 07 10 50 18 89 D6 AD 9C 09 20 50 28 AC 02 32 13 08 B7 81 97 F6 06 10 50 18 8A EC D4 96 02 20 50 28 AC 02 3A 1E 0A 10 24 0E 00 E1 A9 00 00 50 00 00 00 00 00 00 00 29 10 50 18 89 EC 8C B1 05 20 50 28 64 3A 1E 0A 10 24 0E 00 E1 A9 00 00 50 00 00 00 00 00 00 00 64 10 50 18 89 EC 8C D1 07 20 50 28 64 3A 1F 0A 10 24 0E 00 FF F1 01 00 10 00 00 00 00 00 00 01 6F 10 50 18 E4 E6 B1 F0 04 20 50 28 C8 01 3A 1F 0A 10 24 0E 00 FF F1 01 00 10 00 00 00 00 00 00 01 72 10 50 18 E4 E6 AD F0 0E 20 50 28 C8 01 3A 1F 0A 10 24 09 8C 1E 75 B0 00 13 00 00 00 00 00 00 00 36 10 50 18 89 EC 9C E8 0D 20 50 28 AC 02 3A 1F 0A 10 24 09 8C 54 10 03 00 10 00 00 00 00 00 00 00 55 10 50 18 89 CA 8C A0 01 20 50 28 AC 02
""".trimIndent().hexToBytes()
val client = bot.client
client.fileStoragePushFSSvcList =
default.loadAs(FileStoragePushFSSvcListFuckKotlin.serializer())
Unit
// 19 00 0A 0A 16 0F 31 31 34 2E 32 32 31 2E 31 34 34 2E 31 36 30 21 36 B0 30 01 4C 5C 60 08 70 01 86 02 73 68 96 03 74 65 6C 0B 0A 16 0C 31 31 33 2E 39 36 2E 31 33 2E 39 35 21 36 B0 30 01 4C 5C 60 08 70 01 86 02 73 7A 96 03 74 65 6C 0B 0A 16 0D 31 31 33 2E 39 36 2E 31 32 2E 32 31 37 21 1F 90 30 01 4C 5C 60 08 70 01 86 02 73 7A 96 03 74 65 6C 0B 0A 16 0D 34 32 2E 38 31 2E 31 37 30 2E 31 32 32 21 01 BB 30 01 4C 5C 60 08 70 01 86 02 74 6A 96 03 74 65 6C 0B 0A 16 0F 31 31 34 2E 32 32 31 2E 31 34 34 2E 32 31 32 20 50 30 01 4C 5C 60 08 70 01 86 02 73 68 96 03 74 65 6C 0B 0A 16 0A 31 34 2E 32 32 2E 33 2E 33 35 21 36 B0 30 01 4C 5C 60 08 70 01 86 02 73 7A 96 03 74 65 6C 0B 0A 16 0D 34 32 2E 38 31 2E 31 37 32 2E 31 35 36 21 01 BB 30 01 4C 5C 60 08 70 01 86 02 74 6A 96 03 74 65 6C 0B 0A 16 0E 31 31 34 2E 32 32 31 2E 31 34 34 2E 31 39 21 1F 90 30 01 4C 5C 60 08 70 01 86 02 73 68 96 03 74 65 6C 0B 0A 16 11 6D 73 66 77 69 66 69 2E 33 67 2E 71 71 2E 63 6F 6D 21 1F 90 30 01 4C 5C 60 08 7C 86 06 6F 74 68 65 72 73 96 06 6F 74 68 65 72 73 0B 0A 16 0D 34 32 2E 38 31 2E 31 37 30 2E 31 32 32 20 50 30 01 4C 5C 60 08 70 01 86 02 74 6A 96 03 74 65 6C 0B 39 00 0A 0A 16 0F 31 31 34 2E 32 32 31 2E 31 34 34 2E 31 36 30 21 36 B0 30 01 4C 5C 60 08 70 01 86 02 73 68 96 03 74 65 6C 0B 0A 16 0C 31 31 33 2E 39 36 2E 31 33 2E 39 35 21 36 B0 30 01 4C 5C 60 08 70 01 86 02 73 7A 96 03 74 65 6C 0B 0A 16 0D 31 31 33 2E 39 36 2E 31 32 2E 32 31 37 21 1F 90 30 01 4C 5C 60 08 70 01 86 02 73 7A 96 03 74 65 6C 0B 0A 16 0D 34 32 2E 38 31 2E 31 37 30 2E 31 32 32 21 01 BB 30 01 4C 5C 60 08 70 01 86 02 74 6A 96 03 74 65 6C 0B 0A 16 0F 31 31 34 2E 32 32 31 2E 31 34 34 2E 32 31 32 20 50 30 01 4C 5C 60 08 70 01 86 02 73 68 96 03 74 65 6C 0B 0A 16 0A 31 34 2E 32 32 2E 33 2E 33 35 21 36 B0 30 01 4C 5C 60 08 70 01 86 02 73 7A 96 03 74 65 6C 0B 0A 16 0D 34 32 2E 38 31 2E 31 37 32 2E 31 35 36 21 01 BB 30 01 4C 5C 60 08 70 01 86 02 74 6A 96 03 74 65 6C 0B 0A 16 0E 31 31 34 2E 32 32 31 2E 31 34 34 2E 31 39 21 1F 90 30 01 4C 5C 60 08 70 01 86 02 73 68 96 03 74 65 6C 0B 0A 16 11 6D 73 66 77 69 66 69 2E 33 67 2E 71 71 2E 63 6F 6D 21 1F 90 30 01 4C 5C 60 08 7C 86 06 6F 74 68 65 72 73 96 06 6F 74 68 65 72 73 0B 0A 16 0D 34 32 2E 38 31 2E 31 37 30 2E 31 32 32 20 50 30 01 4C 5C 60 08 70 01 86 02 74 6A 96 03 74 65 6C 0B 4C 5C 6C 70 01 89 00 04 0A 16 0E 31 31 34 2E 32 32 31 2E 31 34 34 2E 32 32 20 50 30 01 4C 50 03 60 08 7C 86 02 73 68 96 03 74 65 6C 0B 0A 16 0C 31 31 33 2E 39 36 2E 31 33 2E 34 34 20 50 30 01 4C 50 03 60 08 7C 86 02 73 7A 96 03 74 65 6C 0B 0A 16 0D 34 32 2E 38 31 2E 31 36 39 2E 31 30 35 20 50 30 01 4C 50 03 60 08 7C 86 02 74 6A 96 03 74 65 6C 0B 0A 16 0D 34 32 2E 38 31 2E 31 36 39 2E 31 30 35 20 50 30 01 4C 50 03 60 08 7C 86 02 74 6A 96 03 74 65 6C 0B 99 00 04 0A 16 0E 31 31 34 2E 32 32 31 2E 31 34 34 2E 32 32 20 50 30 01 4C 50 03 60 08 7C 86 02 73 68 96 03 74 65 6C 0B 0A 16 0C 31 31 33 2E 39 36 2E 31 33 2E 34 34 20 50 30 01 4C 50 03 60 08 7C 86 02 73 7A 96 03 74 65 6C 0B 0A 16 0D 34 32 2E 38 31 2E 31 36 39 2E 31 30 35 20 50 30 01 4C 50 03 60 08 7C 86 02 74 6A 96 03 74 65 6C 0B 0A 16 0D 34 32 2E 38 31 2E 31 36 39 2E 31 30 35 20 50 30 01 4C 50 03 60 08 7C 86 02 74 6A 96 03 74 65 6C 0B A9 0C B9 0C C9 0C D9 0C E0 01 FC 0F F6 10 28 32 30 32 30 2D 30 34 2D 31 34 20 32 31 3A 33 31 3A 31 36 20 64 65 6C 69 76 65 72 79 69 6E 67 20 61 20 70 6F 6C 69 63 79 // 19 00 0A 0A 16 0F 31 31 34 2E 32 32 31 2E 31 34 34 2E 31 36 30 21 36 B0 30 01 4C 5C 60 08 70 01 86 02 73 68 96 03 74 65 6C 0B 0A 16 0C 31 31 33 2E 39 36 2E 31 33 2E 39 35 21 36 B0 30 01 4C 5C 60 08 70 01 86 02 73 7A 96 03 74 65 6C 0B 0A 16 0D 31 31 33 2E 39 36 2E 31 32 2E 32 31 37 21 1F 90 30 01 4C 5C 60 08 70 01 86 02 73 7A 96 03 74 65 6C 0B 0A 16 0D 34 32 2E 38 31 2E 31 37 30 2E 31 32 32 21 01 BB 30 01 4C 5C 60 08 70 01 86 02 74 6A 96 03 74 65 6C 0B 0A 16 0F 31 31 34 2E 32 32 31 2E 31 34 34 2E 32 31 32 20 50 30 01 4C 5C 60 08 70 01 86 02 73 68 96 03 74 65 6C 0B 0A 16 0A 31 34 2E 32 32 2E 33 2E 33 35 21 36 B0 30 01 4C 5C 60 08 70 01 86 02 73 7A 96 03 74 65 6C 0B 0A 16 0D 34 32 2E 38 31 2E 31 37 32 2E 31 35 36 21 01 BB 30 01 4C 5C 60 08 70 01 86 02 74 6A 96 03 74 65 6C 0B 0A 16 0E 31 31 34 2E 32 32 31 2E 31 34 34 2E 31 39 21 1F 90 30 01 4C 5C 60 08 70 01 86 02 73 68 96 03 74 65 6C 0B 0A 16 11 6D 73 66 77 69 66 69 2E 33 67 2E 71 71 2E 63 6F 6D 21 1F 90 30 01 4C 5C 60 08 7C 86 06 6F 74 68 65 72 73 96 06 6F 74 68 65 72 73 0B 0A 16 0D 34 32 2E 38 31 2E 31 37 30 2E 31 32 32 20 50 30 01 4C 5C 60 08 70 01 86 02 74 6A 96 03 74 65 6C 0B 39 00 0A 0A 16 0F 31 31 34 2E 32 32 31 2E 31 34 34 2E 31 36 30 21 36 B0 30 01 4C 5C 60 08 70 01 86 02 73 68 96 03 74 65 6C 0B 0A 16 0C 31 31 33 2E 39 36 2E 31 33 2E 39 35 21 36 B0 30 01 4C 5C 60 08 70 01 86 02 73 7A 96 03 74 65 6C 0B 0A 16 0D 31 31 33 2E 39 36 2E 31 32 2E 32 31 37 21 1F 90 30 01 4C 5C 60 08 70 01 86 02 73 7A 96 03 74 65 6C 0B 0A 16 0D 34 32 2E 38 31 2E 31 37 30 2E 31 32 32 21 01 BB 30 01 4C 5C 60 08 70 01 86 02 74 6A 96 03 74 65 6C 0B 0A 16 0F 31 31 34 2E 32 32 31 2E 31 34 34 2E 32 31 32 20 50 30 01 4C 5C 60 08 70 01 86 02 73 68 96 03 74 65 6C 0B 0A 16 0A 31 34 2E 32 32 2E 33 2E 33 35 21 36 B0 30 01 4C 5C 60 08 70 01 86 02 73 7A 96 03 74 65 6C 0B 0A 16 0D 34 32 2E 38 31 2E 31 37 32 2E 31 35 36 21 01 BB 30 01 4C 5C 60 08 70 01 86 02 74 6A 96 03 74 65 6C 0B 0A 16 0E 31 31 34 2E 32 32 31 2E 31 34 34 2E 31 39 21 1F 90 30 01 4C 5C 60 08 70 01 86 02 73 68 96 03 74 65 6C 0B 0A 16 11 6D 73 66 77 69 66 69 2E 33 67 2E 71 71 2E 63 6F 6D 21 1F 90 30 01 4C 5C 60 08 7C 86 06 6F 74 68 65 72 73 96 06 6F 74 68 65 72 73 0B 0A 16 0D 34 32 2E 38 31 2E 31 37 30 2E 31 32 32 20 50 30 01 4C 5C 60 08 70 01 86 02 74 6A 96 03 74 65 6C 0B 4C 5C 6C 70 01 89 00 04 0A 16 0E 31 31 34 2E 32 32 31 2E 31 34 34 2E 32 32 20 50 30 01 4C 50 03 60 08 7C 86 02 73 68 96 03 74 65 6C 0B 0A 16 0C 31 31 33 2E 39 36 2E 31 33 2E 34 34 20 50 30 01 4C 50 03 60 08 7C 86 02 73 7A 96 03 74 65 6C 0B 0A 16 0D 34 32 2E 38 31 2E 31 36 39 2E 31 30 35 20 50 30 01 4C 50 03 60 08 7C 86 02 74 6A 96 03 74 65 6C 0B 0A 16 0D 34 32 2E 38 31 2E 31 36 39 2E 31 30 35 20 50 30 01 4C 50 03 60 08 7C 86 02 74 6A 96 03 74 65 6C 0B 99 00 04 0A 16 0E 31 31 34 2E 32 32 31 2E 31 34 34 2E 32 32 20 50 30 01 4C 50 03 60 08 7C 86 02 73 68 96 03 74 65 6C 0B 0A 16 0C 31 31 33 2E 39 36 2E 31 33 2E 34 34 20 50 30 01 4C 50 03 60 08 7C 86 02 73 7A 96 03 74 65 6C 0B 0A 16 0D 34 32 2E 38 31 2E 31 36 39 2E 31 30 35 20 50 30 01 4C 50 03 60 08 7C 86 02 74 6A 96 03 74 65 6C 0B 0A 16 0D 34 32 2E 38 31 2E 31 36 39 2E 31 30 35 20 50 30 01 4C 50 03 60 08 7C 86 02 74 6A 96 03 74 65 6C 0B A9 0C B9 0C C9 0C D9 0C E0 01 FC 0F F6 10 28 32 30 32 30 2D 30 34 2D 31 34 20 32 31 3A 33 31 3A 31 36 20 64 65 6C 69 76 65 72 79 69 6E 67 20 61 20 70 6F 6C 69 63 79
// failed // failed
} }
...@@ -112,8 +111,8 @@ internal class ConfigPushSvc { ...@@ -112,8 +111,8 @@ internal class ConfigPushSvc {
return readProtoBuf(PushReqResponse.ChangeServer.serializer()) return readProtoBuf(PushReqResponse.ChangeServer.serializer())
} }
}.getOrElse { }.getOrElse {
bot.network.logger.warning { "Cannot decode ConfigPushSvc.PushReq, data=${buffer.toUHexString()}" } bot.network.logger.verbose { "Cannot decode ConfigPushSvc.PushReq, this can often be ignored." }
bot.network.logger.warning(it) // bot.network.logger.debug(it)
return null return null
} }
} }
......
...@@ -182,7 +182,7 @@ internal class StatSvc { ...@@ -182,7 +182,7 @@ internal class StatSvc {
} }
internal object ReqMSFOffline : internal object ReqMSFOffline :
IncomingPacketFactory<BotOfflineEvent.Dropped>("StatSvc.ReqMSFOffline", "StatSvc.RspMSFForceOffline") { IncomingPacketFactory<BotOfflineEvent.MsfOffline>("StatSvc.ReqMSFOffline", "StatSvc.RspMSFForceOffline") {
internal data class MsfOfflineToken( internal data class MsfOfflineToken(
val uin: Long, val uin: Long,
...@@ -190,13 +190,13 @@ internal class StatSvc { ...@@ -190,13 +190,13 @@ internal class StatSvc {
val const: Byte val const: Byte
) : Packet, RuntimeException("dropped by StatSvc.ReqMSFOffline") ) : Packet, RuntimeException("dropped by StatSvc.ReqMSFOffline")
override suspend fun ByteReadPacket.decode(bot: QQAndroidBot, sequenceId: Int): BotOfflineEvent.Dropped { override suspend fun ByteReadPacket.decode(bot: QQAndroidBot, sequenceId: Int): BotOfflineEvent.MsfOffline {
val decodeUniPacket = readUniPacket(RequestMSFForceOffline.serializer()) val decodeUniPacket = readUniPacket(RequestMSFForceOffline.serializer())
@Suppress("INVISIBLE_MEMBER") @Suppress("INVISIBLE_MEMBER")
return BotOfflineEvent.Dropped(bot, MsfOfflineToken(decodeUniPacket.uin, decodeUniPacket.iSeqno, 0)) return BotOfflineEvent.MsfOffline(bot, MsfOfflineToken(decodeUniPacket.uin, decodeUniPacket.iSeqno, 0))
} }
override suspend fun QQAndroidBot.handle(packet: BotOfflineEvent.Dropped, sequenceId: Int): OutgoingPacket? { override suspend fun QQAndroidBot.handle(packet: BotOfflineEvent.MsfOffline, sequenceId: Int): OutgoingPacket? {
val cause = packet.cause val cause = packet.cause
check(cause is MsfOfflineToken) { "internal error: handling $packet in StatSvc.ReqMSFOffline" } check(cause is MsfOfflineToken) { "internal error: handling $packet in StatSvc.ReqMSFOffline" }
return buildResponseUniPacket(client) { return buildResponseUniPacket(client) {
......
...@@ -34,7 +34,9 @@ kotlin { ...@@ -34,7 +34,9 @@ kotlin {
) )
} }
jvm() jvm() {
// withJava() // https://youtrack.jetbrains.com/issue/KT-39991
}
sourceSets { sourceSets {
all { all {
......
...@@ -291,11 +291,13 @@ abstract class Bot internal constructor( ...@@ -291,11 +291,13 @@ abstract class Bot internal constructor(
@Deprecated( @Deprecated(
"use member function.", "use member function.",
replaceWith = ReplaceWith("event.reject(blackList)"), replaceWith = ReplaceWith("event.reject(blackList)"),
level = DeprecationLevel.ERROR level = DeprecationLevel.HIDDEN
) )
@JvmSynthetic
abstract suspend fun rejectMemberJoinRequest(event: MemberJoinRequestEvent, blackList: Boolean = false) abstract suspend fun rejectMemberJoinRequest(event: MemberJoinRequestEvent, blackList: Boolean = false)
@JvmSynthetic
abstract suspend fun rejectMemberJoinRequest(event: MemberJoinRequestEvent, blackList: Boolean = false, message: String = "")
/** /**
* 忽略加群验证(需管理员权限) * 忽略加群验证(需管理员权限)
* *
......
...@@ -26,109 +26,109 @@ data class GroupActiveData( ...@@ -26,109 +26,109 @@ data class GroupActiveData(
val info: GInfo? = null, val info: GInfo? = null,
@SerialName("role") @SerialName("role")
val role: Int? val role: Int? = 0
) { ) {
@Serializable @Serializable
data class GInfo( data class GInfo(
@SerialName("g_act_num") @SerialName("g_act_num")
val actNum: List<GActNum?>?, //发言人数列表 val actNum: List<GActNum?>? = null, //发言人数列表
@SerialName("g_createtime") @SerialName("g_createtime")
val createTime: Int?, val createTime: Int? = 0,
@SerialName("g_exit_num") @SerialName("g_exit_num")
val exitNum: List<GExitNum?>?, //退群人数列表 val exitNum: List<GExitNum?>? = null, //退群人数列表
@SerialName("g_join_num") @SerialName("g_join_num")
val joinNum: List<GJoinNum?>?, val joinNum: List<GJoinNum?>? = null,
@SerialName("g_mem_num") @SerialName("g_mem_num")
val memNum: List<GMemNum?>?, //人数变化 val memNum: List<GMemNum?>? = null, //人数变化
@SerialName("g_most_act") @SerialName("g_most_act")
val mostAct: List<GMostAct?>?, //发言排行 val mostAct: List<GMostAct?>? = null, //发言排行
@SerialName("g_sentences") @SerialName("g_sentences")
val sentences: List<GSentence?>?, val sentences: List<GSentence?>? = null,
@SerialName("gc") @SerialName("gc")
val gc: Int?, val gc: Int? = null,
@SerialName("gn") @SerialName("gn")
val gn: String?, val gn: String? = null,
@SerialName("gowner") @SerialName("gowner")
val gowner: String?, val gowner: String? = null,
@SerialName("isEnd") @SerialName("isEnd")
val isEnd: Int? val isEnd: Int? = null
) { ) {
@Serializable @Serializable
data class GActNum( data class GActNum(
@SerialName("date") @SerialName("date")
val date: String?, val date: String? = null,
@SerialName("num") @SerialName("num")
val num: Int? val num: Int? = 0
) )
@Serializable @Serializable
data class GExitNum( data class GExitNum(
@SerialName("date") @SerialName("date")
val date: String?, val date: String? = null,
@SerialName("num") @SerialName("num")
val num: Int? val num: Int? = 0
) )
@Serializable @Serializable
data class GJoinNum( data class GJoinNum(
@SerialName("date") @SerialName("date")
val date: String?, val date: String? = null,
@SerialName("num") @SerialName("num")
val num: Int? val num: Int? = 0
) )
@Serializable @Serializable
data class GMemNum( data class GMemNum(
@SerialName("date") @SerialName("date")
val date: String?, val date: String? = null,
@SerialName("num") @SerialName("num")
val num: Int? val num: Int? = 0
) )
@Serializable @Serializable
data class GMostAct( data class GMostAct(
@SerialName("name") @SerialName("name")
val name: String?, // 名称 不完整 val name: String? = null, // 名称 不完整
@SerialName("sentences_num") @SerialName("sentences_num")
val sentencesNum: Int?, // 发言数 val sentencesNum: Int? = 0, // 发言数
@SerialName("sta") @SerialName("sta")
val sta: Int?, val sta: Int? = 0,
@SerialName("uin") @SerialName("uin")
val uin: Long? val uin: Long? = 0
) )
@Serializable @Serializable
data class GSentence( data class GSentence(
@SerialName("date") @SerialName("date")
val date: String?, val date: String? = null,
@SerialName("num") @SerialName("num")
val num: Int? val num: Int? = 0
) )
} }
} }
\ No newline at end of file
...@@ -16,6 +16,9 @@ package net.mamoe.mirai.event.events ...@@ -16,6 +16,9 @@ package net.mamoe.mirai.event.events
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import net.mamoe.mirai.event.AbstractEvent import net.mamoe.mirai.event.AbstractEvent
import net.mamoe.mirai.qqandroid.network.Packet import net.mamoe.mirai.qqandroid.network.Packet
import net.mamoe.mirai.utils.MiraiExperimentalAPI
import net.mamoe.mirai.utils.MiraiInternalAPI
import net.mamoe.mirai.utils.SinceMirai
import kotlin.jvm.JvmMultifileClass import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName import kotlin.jvm.JvmName
...@@ -35,7 +38,8 @@ sealed class BotOfflineEvent : BotEvent, AbstractEvent() { ...@@ -35,7 +38,8 @@ sealed class BotOfflineEvent : BotEvent, AbstractEvent() {
/** /**
* 主动离线. 主动广播这个事件也可以让 [Bot] 关闭. * 主动离线. 主动广播这个事件也可以让 [Bot] 关闭.
*/ */
data class Active(override val bot: Bot, val cause: Throwable?) : BotOfflineEvent(), BotActiveEvent data class Active(override val bot: Bot, override val cause: Throwable?) : BotOfflineEvent(), BotActiveEvent,
CauseAware
/** /**
* 被挤下线 * 被挤下线
...@@ -45,15 +49,31 @@ sealed class BotOfflineEvent : BotEvent, AbstractEvent() { ...@@ -45,15 +49,31 @@ sealed class BotOfflineEvent : BotEvent, AbstractEvent() {
BotPassiveEvent BotPassiveEvent
/** /**
* 被服务器断开或因网络问题而掉线 * 被服务器断开
*/ */
data class Dropped internal constructor(override val bot: Bot, val cause: Throwable?) : BotOfflineEvent(), Packet, @SinceMirai("1.1.0")
BotPassiveEvent @MiraiInternalAPI("This is very experimental and might be changed")
data class MsfOffline internal constructor(override val bot: Bot, override val cause: Throwable?) :
BotOfflineEvent(), Packet,
BotPassiveEvent, CauseAware
/**
* 因网络问题而掉线
*/
data class Dropped internal constructor(override val bot: Bot, override val cause: Throwable?) : BotOfflineEvent(),
Packet,
BotPassiveEvent, CauseAware
/** /**
* 服务器主动要求更换另一个服务器 * 服务器主动要求更换另一个服务器
*/ */
@MiraiInternalAPI
data class RequireReconnect internal constructor(override val bot: Bot) : BotOfflineEvent(), Packet, BotPassiveEvent data class RequireReconnect internal constructor(override val bot: Bot) : BotOfflineEvent(), Packet, BotPassiveEvent
@MiraiExperimentalAPI
interface CauseAware {
val cause: Throwable?
}
} }
/** /**
......
...@@ -355,7 +355,8 @@ data class MemberJoinRequestEvent internal constructor( ...@@ -355,7 +355,8 @@ data class MemberJoinRequestEvent internal constructor(
suspend fun accept() = bot.acceptMemberJoinRequest(this) suspend fun accept() = bot.acceptMemberJoinRequest(this)
@JvmSynthetic @JvmSynthetic
suspend fun reject(blackList: Boolean = false) = bot.rejectMemberJoinRequest(this, blackList) @JvmOverloads
suspend fun reject(blackList: Boolean = false, message: String = "") = bot.rejectMemberJoinRequest(this, blackList, message)
@JvmSynthetic @JvmSynthetic
suspend fun ignore(blackList: Boolean = false) = bot.ignoreMemberJoinRequest(this, blackList) suspend fun ignore(blackList: Boolean = false) = bot.ignoreMemberJoinRequest(this, blackList)
...@@ -368,8 +369,8 @@ data class MemberJoinRequestEvent internal constructor( ...@@ -368,8 +369,8 @@ data class MemberJoinRequestEvent internal constructor(
@JavaFriendlyAPI @JavaFriendlyAPI
@JvmOverloads @JvmOverloads
@JvmName("reject") @JvmName("reject")
fun __rejectBlockingForJava__(blackList: Boolean = false) = fun __rejectBlockingForJava__(blackList: Boolean = false, message: String = "") =
runBlocking { bot.rejectMemberJoinRequest(this@MemberJoinRequestEvent, blackList) } runBlocking { bot.rejectMemberJoinRequest(this@MemberJoinRequestEvent, blackList, message) }
@JavaFriendlyAPI @JavaFriendlyAPI
@JvmOverloads @JvmOverloads
......
...@@ -112,10 +112,12 @@ interface LowLevelBotAPIAccessor { ...@@ -112,10 +112,12 @@ interface LowLevelBotAPIAccessor {
/** /**
* 获取群活跃信息 * 获取群活跃信息
* 不传page可得到趋势图
* page从0开始传入可以得到发言列表
*/ */
@LowLevelAPI @LowLevelAPI
@MiraiExperimentalAPI @MiraiExperimentalAPI
suspend fun _lowLevelGetGroupActiveData(groupId: Long): GroupActiveData suspend fun _lowLevelGetGroupActiveData(groupId: Long, page: Int = -1): GroupActiveData
/** /**
...@@ -123,19 +125,38 @@ interface LowLevelBotAPIAccessor { ...@@ -123,19 +125,38 @@ interface LowLevelBotAPIAccessor {
*/ */
@LowLevelAPI @LowLevelAPI
@MiraiExperimentalAPI @MiraiExperimentalAPI
suspend fun _lowLevelSolveNewFriendRequestEvent(eventId: Long, fromId: Long, fromNick: String, accept: Boolean, blackList: Boolean) suspend fun _lowLevelSolveNewFriendRequestEvent(
eventId: Long,
fromId: Long,
fromNick: String,
accept: Boolean,
blackList: Boolean
)
/** /**
* 处理被邀请加入一个群请求事件 * 处理被邀请加入一个群请求事件
*/ */
@LowLevelAPI @LowLevelAPI
@MiraiExperimentalAPI @MiraiExperimentalAPI
suspend fun _lowLevelSolveBotInvitedJoinGroupRequestEvent(eventId: Long, invitorId: Long, groupId: Long, accept: Boolean) suspend fun _lowLevelSolveBotInvitedJoinGroupRequestEvent(
eventId: Long,
invitorId: Long,
groupId: Long,
accept: Boolean
)
/** /**
* 处理账号请求加入群事件 * 处理账号请求加入群事件
*/ */
@LowLevelAPI @LowLevelAPI
@MiraiExperimentalAPI @MiraiExperimentalAPI
suspend fun _lowLevelSolveMemberJoinRequestEvent(eventId: Long, fromId: Long, fromNick: String, groupId: Long, accept: Boolean?, blackList: Boolean) suspend fun _lowLevelSolveMemberJoinRequestEvent(
eventId: Long,
fromId: Long,
fromNick: String,
groupId: Long,
accept: Boolean?,
blackList: Boolean,
message: String = ""
)
} }
...@@ -73,7 +73,7 @@ expect interface Image : Message, MessageContent, CodableMessage { ...@@ -73,7 +73,7 @@ expect interface Image : Message, MessageContent, CodableMessage {
* *
* ### 格式 * ### 格式
* 群图片: * 群图片:
* - [GROUP_IMAGE_ID_REGEX], 示例: `{01E9451B-70ED-EAE3-B37C-101F1EEBF5B5}.mirai` (后缀一定为 `".mirai"`) * - [GROUP_IMAGE_ID_REGEX], 示例: `{01E9451B-70ED-EAE3-B37C-101F1EEBF5B5}.ext` (ext系扩展名)
* *
* 好友图片: * 好友图片:
* - [FRIEND_IMAGE_ID_REGEX_1], 示例: `/f8f1ab55-bf8e-4236-b55e-955848d7069f` * - [FRIEND_IMAGE_ID_REGEX_1], 示例: `/f8f1ab55-bf8e-4236-b55e-955848d7069f`
...@@ -125,7 +125,7 @@ abstract class FriendImage internal constructor() : AbstractImage() { // change ...@@ -125,7 +125,7 @@ abstract class FriendImage internal constructor() : AbstractImage() { // change
/** /**
* 群图片. * 群图片.
* *
* @property imageId 形如 `{01E9451B-70ED-EAE3-B37C-101F1EEBF5B5}.mirai` (后缀一定为 `".mirai"`) * @property imageId 形如 `{01E9451B-70ED-EAE3-B37C-101F1EEBF5B5}.ext` (ext系扩展名)
* @see Image 查看更多说明 * @see Image 查看更多说明
*/ */
// CustomFace // CustomFace
...@@ -156,11 +156,11 @@ val FRIEND_IMAGE_ID_REGEX_2 = Regex("""/[0-9]*-[0-9]*-[0-9a-fA-F]{32}""") ...@@ -156,11 +156,11 @@ val FRIEND_IMAGE_ID_REGEX_2 = Regex("""/[0-9]*-[0-9]*-[0-9a-fA-F]{32}""")
/** /**
* 群图片 ID 正则表达式 * 群图片 ID 正则表达式
* *
* `{01E9451B-70ED-EAE3-B37C-101F1EEBF5B5}.mirai` * `{01E9451B-70ED-EAE3-B37C-101F1EEBF5B5}.ext`
*/ */
@Suppress("RegExpRedundantEscape") // This is required on Android @Suppress("RegExpRedundantEscape") // This is required on Android
// Java: MessageUtils.GROUP_IMAGE_ID_REGEX // Java: MessageUtils.GROUP_IMAGE_ID_REGEX
val GROUP_IMAGE_ID_REGEX = Regex("""\{[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}\}\.mirai""") val GROUP_IMAGE_ID_REGEX = Regex("""\{[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}\}\..{3,5}""")
/** /**
* 通过 [Image.imageId] 构造一个 [Image] 以便发送. * 通过 [Image.imageId] 构造一个 [Image] 以便发送.
......
...@@ -51,7 +51,7 @@ annotation class MiraiExperimentalAPI( ...@@ -51,7 +51,7 @@ annotation class MiraiExperimentalAPI(
annotation class SinceMirai(val version: String) annotation class SinceMirai(val version: String)
/** /**
* 标记一个正计划在 [version] 版本时删除的 API. * 标记一个正计划在 [version] 版本时删除 (对外隐藏) 的 API.
*/ */
@Target(CLASS, PROPERTY, FIELD, CONSTRUCTOR, FUNCTION, PROPERTY_GETTER, PROPERTY_SETTER, TYPEALIAS) @Target(CLASS, PROPERTY, FIELD, CONSTRUCTOR, FUNCTION, PROPERTY_GETTER, PROPERTY_SETTER, TYPEALIAS)
@Retention(AnnotationRetention.SOURCE) @Retention(AnnotationRetention.SOURCE)
......
...@@ -16,10 +16,10 @@ import kotlinx.serialization.UnstableDefault ...@@ -16,10 +16,10 @@ import kotlinx.serialization.UnstableDefault
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonConfiguration import kotlinx.serialization.json.JsonConfiguration
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import net.mamoe.mirai.utils.BotConfiguration.MiraiProtocol
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext import kotlin.coroutines.EmptyCoroutineContext
import kotlin.coroutines.coroutineContext import kotlin.coroutines.coroutineContext
import kotlin.jvm.JvmField
import kotlin.jvm.JvmStatic import kotlin.jvm.JvmStatic
import kotlin.jvm.JvmSynthetic import kotlin.jvm.JvmSynthetic
...@@ -52,6 +52,30 @@ expect open class BotConfiguration() : BotConfigurationBase { ...@@ -52,6 +52,30 @@ expect open class BotConfiguration() : BotConfigurationBase {
@ConfigurationDsl @ConfigurationDsl
fun randomDeviceInfo() fun randomDeviceInfo()
/**
* 协议类型, 服务器仅允许使用不同协议同时登录.
*/
enum class MiraiProtocol {
/**
* Android 手机.
*/
ANDROID_PHONE,
/**
* Android 平板.
*/
ANDROID_PAD,
/**
* Android 手表.
* */
@SinceMirai("1.1.0")
ANDROID_WATCH;
internal val id: Long
}
companion object { companion object {
/** 默认的配置实例. 可以进行修改 */ /** 默认的配置实例. 可以进行修改 */
@JvmStatic @JvmStatic
...@@ -61,10 +85,8 @@ expect open class BotConfiguration() : BotConfigurationBase { ...@@ -61,10 +85,8 @@ expect open class BotConfiguration() : BotConfigurationBase {
fun copy(): BotConfiguration fun copy(): BotConfiguration
} }
@MiraiInternalAPI
@Suppress("PropertyName")
@SinceMirai("1.1.0") @SinceMirai("1.1.0")
internal open class BotConfigurationBase internal constructor() { open class BotConfigurationBase internal constructor() {
/** /**
* 日志记录器 * 日志记录器
* *
...@@ -131,27 +153,6 @@ internal open class BotConfigurationBase internal constructor() { ...@@ -131,27 +153,6 @@ internal open class BotConfigurationBase internal constructor() {
Json(JsonConfiguration(isLenient = true, ignoreUnknownKeys = true)) Json(JsonConfiguration(isLenient = true, ignoreUnknownKeys = true))
}.getOrElse { Json(JsonConfiguration.Stable) } }.getOrElse { Json(JsonConfiguration.Stable) }
enum class MiraiProtocol(
/** 协议模块使用的 ID */
@JvmField internal val id: Long
) {
/**
* Android 手机.
*
* - 与手机冲突
* - 与平板和电脑不冲突
*/
ANDROID_PHONE(537062845),
/**
* Android 平板.
*
* - 与平板冲突
* - 与手机和电脑不冲突
*/
ANDROID_PAD(537062409)
}
/** /**
* 不显示网络日志. 不推荐. * 不显示网络日志. 不推荐.
* @see networkLoggerSupplier 更多日志处理方式 * @see networkLoggerSupplier 更多日志处理方式
......
...@@ -11,15 +11,18 @@ ...@@ -11,15 +11,18 @@
package net.mamoe.mirai.utils package net.mamoe.mirai.utils
import kotlinx.io.core.readBytes
import kotlinx.io.core.use
import net.mamoe.mirai.contact.Contact import net.mamoe.mirai.contact.Contact
import net.mamoe.mirai.contact.Group import net.mamoe.mirai.contact.Group
import net.mamoe.mirai.contact.User import net.mamoe.mirai.contact.User
import net.mamoe.mirai.message.MessageReceipt import net.mamoe.mirai.message.MessageReceipt
import net.mamoe.mirai.message.data.* import net.mamoe.mirai.message.data.Image
import net.mamoe.mirai.message.data.sendTo
import net.mamoe.mirai.message.data.toUHexString
import net.mamoe.mirai.utils.internal.DeferredReusableInput import net.mamoe.mirai.utils.internal.DeferredReusableInput
import net.mamoe.mirai.utils.internal.ReusableInput import net.mamoe.mirai.utils.internal.ReusableInput
import kotlin.jvm.JvmField import kotlin.jvm.JvmField
import kotlin.jvm.JvmName
import kotlin.jvm.JvmSynthetic import kotlin.jvm.JvmSynthetic
/** /**
...@@ -35,6 +38,12 @@ class ExternalImage internal constructor( ...@@ -35,6 +38,12 @@ class ExternalImage internal constructor(
internal val input: ReusableInput internal val input: ReusableInput
) { ) {
internal val md5: ByteArray get() = this.input.md5 internal val md5: ByteArray get() = this.input.md5
val formatName: String by lazy {
val hex = input.asInput().use {
it.readBytes(8).toUHexString("")
}
return@lazy hex.detectFormatName()
}
init { init {
if (input !is DeferredReusableInput) { if (input !is DeferredReusableInput) {
...@@ -67,6 +76,14 @@ class ExternalImage internal constructor( ...@@ -67,6 +76,14 @@ class ExternalImage internal constructor(
} }
internal fun calculateImageResourceId(): String = generateImageId(md5) internal fun calculateImageResourceId(): String = generateImageId(md5)
private fun String.detectFormatName(): String = when {
startsWith("FFD8") -> "jpg"
startsWith("89504E47") -> "png"
startsWith("47494638") -> "gif"
startsWith("424D") -> "bmp"
else -> defaultFormatName
}
} }
/* /*
......
...@@ -262,7 +262,7 @@ open class SimpleLogger( ...@@ -262,7 +262,7 @@ open class SimpleLogger(
enum class LogPriority( enum class LogPriority(
@MiraiExperimentalAPI val nameAligned: String, @MiraiExperimentalAPI val nameAligned: String,
@MiraiExperimentalAPI val simpleName: String, val simpleName: String,
@MiraiExperimentalAPI val correspondingFunction: MiraiLogger.(message: String?, e: Throwable?) -> Unit @MiraiExperimentalAPI val correspondingFunction: MiraiLogger.(message: String?, e: Throwable?) -> Unit
) { ) {
VERBOSE("VERBOSE", "V", MiraiLogger::verbose), VERBOSE("VERBOSE", "V", MiraiLogger::verbose),
......
...@@ -64,26 +64,22 @@ internal class ChunkedInput( ...@@ -64,26 +64,22 @@ internal class ChunkedInput(
* *
* 若 [ByteReadPacket.remaining] 小于 [sizePerPacket], 将会返回唯一元素 [this] 的 [Sequence] * 若 [ByteReadPacket.remaining] 小于 [sizePerPacket], 将会返回唯一元素 [this] 的 [Sequence]
*/ */
internal fun ByteReadPacket.chunkedFlow(sizePerPacket: Int): Flow<ChunkedInput> { internal fun ByteReadPacket.chunkedFlow(sizePerPacket: Int, buffer: ByteArray): Flow<ChunkedInput> {
ByteArrayPool.checkBufferSize(sizePerPacket) ByteArrayPool.checkBufferSize(sizePerPacket)
if (this.remaining <= sizePerPacket.toLong()) { if (this.remaining <= sizePerPacket.toLong()) {
ByteArrayPool.useInstance { buffer -> return flowOf(
return flowOf( ChunkedInput(
ChunkedInput( buffer,
buffer, this.readAvailable(buffer, 0, sizePerPacket)
this.readAvailable(buffer, 0, sizePerPacket)
)
) )
} )
} }
return flow { return flow {
ByteArrayPool.useInstance { buffer -> val chunkedInput = ChunkedInput(buffer, 0)
val chunkedInput = ChunkedInput(buffer, 0) do {
do { chunkedInput.size = this@chunkedFlow.readAvailable(buffer, 0, sizePerPacket)
chunkedInput.size = this@chunkedFlow.readAvailable(buffer, 0, sizePerPacket) emit(chunkedInput)
emit(chunkedInput) } while (this@chunkedFlow.isNotEmpty)
} while (this@chunkedFlow.isNotEmpty)
}
} }
} }
...@@ -93,19 +89,17 @@ internal fun ByteReadPacket.chunkedFlow(sizePerPacket: Int): Flow<ChunkedInput> ...@@ -93,19 +89,17 @@ internal fun ByteReadPacket.chunkedFlow(sizePerPacket: Int): Flow<ChunkedInput>
* 对于一个 1000 长度的 [ByteReadChannel] 和参数 [sizePerPacket] = 300, 将会产生含四个元素的 [Sequence], * 对于一个 1000 长度的 [ByteReadChannel] 和参数 [sizePerPacket] = 300, 将会产生含四个元素的 [Sequence],
* 其长度分别为: 300, 300, 300, 100. * 其长度分别为: 300, 300, 300, 100.
*/ */
internal fun ByteReadChannel.chunkedFlow(sizePerPacket: Int): Flow<ChunkedInput> { internal fun ByteReadChannel.chunkedFlow(sizePerPacket: Int, buffer: ByteArray): Flow<ChunkedInput> {
ByteArrayPool.checkBufferSize(sizePerPacket) ByteArrayPool.checkBufferSize(sizePerPacket)
if (this.isClosedForRead) { if (this.isClosedForRead) {
return flowOf() return flowOf()
} }
return flow { return flow {
ByteArrayPool.useInstance { buffer -> val chunkedInput = ChunkedInput(buffer, 0)
val chunkedInput = ChunkedInput(buffer, 0) do {
do { chunkedInput.size = this@chunkedFlow.readAvailable(buffer, 0, sizePerPacket)
chunkedInput.size = this@chunkedFlow.readAvailable(buffer, 0, sizePerPacket) emit(chunkedInput)
emit(chunkedInput) } while (!this@chunkedFlow.isClosedForRead)
} while (!this@chunkedFlow.isClosedForRead)
}
} }
} }
...@@ -117,7 +111,7 @@ internal fun ByteReadChannel.chunkedFlow(sizePerPacket: Int): Flow<ChunkedInput> ...@@ -117,7 +111,7 @@ internal fun ByteReadChannel.chunkedFlow(sizePerPacket: Int): Flow<ChunkedInput>
* 其长度分别为: 300, 300, 300, 100. * 其长度分别为: 300, 300, 300, 100.
*/ */
@OptIn(ExperimentalCoroutinesApi::class) @OptIn(ExperimentalCoroutinesApi::class)
internal fun Input.chunkedFlow(sizePerPacket: Int): Flow<ChunkedInput> { internal fun Input.chunkedFlow(sizePerPacket: Int, buffer: ByteArray): Flow<ChunkedInput> {
ByteArrayPool.checkBufferSize(sizePerPacket) ByteArrayPool.checkBufferSize(sizePerPacket)
if (this.endOfInput) { if (this.endOfInput) {
...@@ -125,12 +119,10 @@ internal fun Input.chunkedFlow(sizePerPacket: Int): Flow<ChunkedInput> { ...@@ -125,12 +119,10 @@ internal fun Input.chunkedFlow(sizePerPacket: Int): Flow<ChunkedInput> {
} }
return flow { return flow {
ByteArrayPool.useInstance { buffer -> val chunkedInput = ChunkedInput(buffer, 0)
val chunkedInput = ChunkedInput(buffer, 0) while (!this@chunkedFlow.endOfInput) {
while (!this@chunkedFlow.endOfInput) { chunkedInput.size = this@chunkedFlow.readAvailable(buffer, 0, sizePerPacket)
chunkedInput.size = this@chunkedFlow.readAvailable(buffer, 0, sizePerPacket) emit(chunkedInput)
emit(chunkedInput)
}
} }
} }
} }
...@@ -144,16 +136,14 @@ internal fun Input.chunkedFlow(sizePerPacket: Int): Flow<ChunkedInput> { ...@@ -144,16 +136,14 @@ internal fun Input.chunkedFlow(sizePerPacket: Int): Flow<ChunkedInput> {
* 若 [ByteReadPacket.remaining] 小于 [sizePerPacket], 将会返回唯一元素 [this] 的 [Sequence] * 若 [ByteReadPacket.remaining] 小于 [sizePerPacket], 将会返回唯一元素 [this] 的 [Sequence]
*/ */
@OptIn(ExperimentalCoroutinesApi::class, InternalSerializationApi::class) @OptIn(ExperimentalCoroutinesApi::class, InternalSerializationApi::class)
internal fun InputStream.chunkedFlow(sizePerPacket: Int): Flow<ChunkedInput> { internal fun InputStream.chunkedFlow(sizePerPacket: Int, buffer: ByteArray): Flow<ChunkedInput> {
ByteArrayPool.checkBufferSize(sizePerPacket) require(sizePerPacket <= buffer.size) { "sizePerPacket is too large. Maximum buffer size=buffer.size=${buffer.size}" }
return flow { return flow {
ByteArrayPool.useInstance { buffer -> val chunkedInput = ChunkedInput(buffer, 0)
val chunkedInput = ChunkedInput(buffer, 0) while (this@chunkedFlow.available() != 0) {
while (this@chunkedFlow.available() != 0) { chunkedInput.size = this@chunkedFlow.read(buffer, 0, sizePerPacket)
chunkedInput.size = this@chunkedFlow.read(buffer, 0, sizePerPacket) emit(chunkedInput)
emit(chunkedInput)
}
} }
} }
} }
\ No newline at end of file
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
* https://github.com/mamoe/mirai/blob/master/LICENSE * https://github.com/mamoe/mirai/blob/master/LICENSE
*/ */
@file:JvmMultifileClass
@file:JvmName("Events") @file:JvmName("Events")
@file:Suppress("unused", "INVISIBLE_MEMBER", "INVISIBLE_REFERENCE", "NOTHING_TO_INLINE") @file:Suppress("unused", "INVISIBLE_MEMBER", "INVISIBLE_REFERENCE", "NOTHING_TO_INLINE")
...@@ -37,18 +38,26 @@ import kotlin.reflect.jvm.kotlinFunction ...@@ -37,18 +38,26 @@ import kotlin.reflect.jvm.kotlinFunction
* *
* 支持的函数类型: * 支持的函数类型:
* ``` * ```
* // 所有函数参数, 函数返回值都不允许标记为可空 (带有 '?' 符号)
* // T 表示任何 Event 类型.
* suspend fun T.onEvent(T) * suspend fun T.onEvent(T)
* suspend fun T.onEvent(T): ListeningStatus * suspend fun T.onEvent(T): ListeningStatus
* suspend fun T.onEvent(T): Nothing
* suspend fun onEvent(T) * suspend fun onEvent(T)
* suspend fun onEvent(T): ListeningStatus * suspend fun onEvent(T): ListeningStatus
* suspend fun onEvent(T): Nothing
* suspend fun T.onEvent() * suspend fun T.onEvent()
* suspend fun T.onEvent(): ListeningStatus * suspend fun T.onEvent(): ListeningStatus
* suspend fun T.onEvent(): Nothing
* fun T.onEvent(T) * fun T.onEvent(T)
* fun T.onEvent(T): ListeningStatus * fun T.onEvent(T): ListeningStatus
* fun T.onEvent(T): Nothing
* fun onEvent(T) * fun onEvent(T)
* fun onEvent(T): ListeningStatus * fun onEvent(T): ListeningStatus
* fun onEvent(T): Nothing
* fun T.onEvent() * fun T.onEvent()
* fun T.onEvent(): ListeningStatus * fun T.onEvent(): ListeningStatus
* fun T.onEvent(): Nothing
* ``` * ```
* *
* Kotlin 使用示例: * Kotlin 使用示例:
...@@ -57,6 +66,8 @@ import kotlin.reflect.jvm.kotlinFunction ...@@ -57,6 +66,8 @@ import kotlin.reflect.jvm.kotlinFunction
* object MyEvents : ListenerHost { * object MyEvents : ListenerHost {
* override val coroutineContext = SupervisorJob() * override val coroutineContext = SupervisorJob()
* *
*
* // 可以抛出任何异常, 将在 this.coroutineContext 或 registerEvents 时提供的 CoroutineScope.coroutineContext 中的 CoroutineExceptionHandler 处理.
* @EventHandler * @EventHandler
* suspend fun MessageEvent.onMessage() { * suspend fun MessageEvent.onMessage() {
* reply("received") * reply("received")
...@@ -76,8 +87,17 @@ import kotlin.reflect.jvm.kotlinFunction ...@@ -76,8 +87,17 @@ import kotlin.reflect.jvm.kotlinFunction
* } * }
* *
* @EventHandler * @EventHandler
* suspend fun MessageEvent.onMessage() { * suspend fun MessageEvent.onMessage() { // 可以抛出任何异常, 将在 handleException 处理
* reply("received") * reply("received")
* // 无返回值 (或者返回 Unit), 表示一直监听事件.
* }
*
* @EventHandler
* suspend fun MessageEvent.onMessage(): ListeningStatus { // 可以抛出任何异常, 将在 handleException 处理
* reply("received")
*
* return ListeningStatus.LISTENING // 表示继续监听事件
* // return ListeningStatus.STOPPED // 表示停止监听事件
* } * }
* } * }
* *
...@@ -90,8 +110,10 @@ import kotlin.reflect.jvm.kotlinFunction ...@@ -90,8 +110,10 @@ import kotlin.reflect.jvm.kotlinFunction
* *
* 支持的方法类型 * 支持的方法类型
* ``` * ```
* // T 表示任何 Event 类型.
* void onEvent(T) * void onEvent(T)
* ListeningStatus onEvent(T) * Void onEvent(T)
* @NotNull ListeningStatus onEvent(T) // 返回 null 时将抛出异常
* ``` * ```
* *
* *
...@@ -99,13 +121,23 @@ import kotlin.reflect.jvm.kotlinFunction ...@@ -99,13 +121,23 @@ import kotlin.reflect.jvm.kotlinFunction
* ``` * ```
* public class MyEventHandlers extends SimpleListenerHost { * public class MyEventHandlers extends SimpleListenerHost {
* @Override * @Override
* public void handleException(CoroutineContext context, Throwable exception){ * public void handleException(@NotNull CoroutineContext context, @NotNull Throwable exception){
* // 处理事件处理时抛出的异常 * // 处理事件处理时抛出的异常
* } * }
* *
* @EventHandler * @EventHandler
* public void onMessage(MessageEvent event) throws Exception { * public void onMessage(@NotNull MessageEvent event) throws Exception { // 可以抛出任何异常, 将在 handleException 处理
* event.subject.sendMessage("received") * event.subject.sendMessage("received");
* // 无返回值, 表示一直监听事件.
* }
*
* @NotNull
* @EventHandler
* public ListeningStatus onMessage(@NotNull MessageEvent event) throws Exception { // 可以抛出任何异常, 将在 handleException 处理
* event.subject.sendMessage("received");
*
* return ListeningStatus.LISTENING; // 表示继续监听事件
* // return ListeningStatus.STOPPED; // 表示停止监听事件
* } * }
* } * }
* *
...@@ -152,7 +184,7 @@ abstract class SimpleListenerHost ...@@ -152,7 +184,7 @@ abstract class SimpleListenerHost
@JvmOverloads constructor(coroutineContext: CoroutineContext = EmptyCoroutineContext) : ListenerHost, CoroutineScope { @JvmOverloads constructor(coroutineContext: CoroutineContext = EmptyCoroutineContext) : ListenerHost, CoroutineScope {
final override val coroutineContext: CoroutineContext = final override val coroutineContext: CoroutineContext =
SupervisorJob(coroutineContext[Job]) + CoroutineExceptionHandler(::handleException) + coroutineContext CoroutineExceptionHandler(::handleException) + coroutineContext + SupervisorJob(coroutineContext[Job])
/** /**
* 处理事件处理中未捕获的异常. 在构造器中的 [coroutineContext] 未提供 [CoroutineExceptionHandler] 情况下必须继承此函数. * 处理事件处理中未捕获的异常. 在构造器中的 [coroutineContext] 未提供 [CoroutineExceptionHandler] 情况下必须继承此函数.
...@@ -260,6 +292,12 @@ private fun Method.registerEvent( ...@@ -260,6 +292,12 @@ private fun Method.registerEvent(
return ListeningStatus.STOPPED return ListeningStatus.STOPPED
} }
} }
require(!kotlinFunction.returnType.isMarkedNullable) {
"Kotlin event handlers cannot have nullable return type."
}
require(kotlinFunction.parameters.any { it.type.isMarkedNullable }) {
"Kotlin event handlers cannot have nullable parameter type."
}
when (kotlinFunction.returnType.classifier) { when (kotlinFunction.returnType.classifier) {
Unit::class, Nothing::class -> { Unit::class, Nothing::class -> {
scope.subscribeAlways( scope.subscribeAlways(
...@@ -299,7 +337,7 @@ private fun Method.registerEvent( ...@@ -299,7 +337,7 @@ private fun Method.registerEvent(
"Illegal method parameter. Required one exact Event subclass. found $paramType" "Illegal method parameter. Required one exact Event subclass. found $paramType"
} }
when (this.returnType) { when (this.returnType) {
Void::class.java, Void.TYPE -> { Void::class.java, Void.TYPE, Nothing::class.java -> {
scope.subscribeAlways( scope.subscribeAlways(
paramType.kotlin as KClass<out Event>, paramType.kotlin as KClass<out Event>,
priority = annotation.priority, priority = annotation.priority,
......
...@@ -127,6 +127,28 @@ actual open class BotConfiguration : BotConfigurationBase() { // open for Java ...@@ -127,6 +127,28 @@ actual open class BotConfiguration : BotConfigurationBase() { // open for Java
botLoggerSupplier = { SingleFileLogger(identity(it), file) } botLoggerSupplier = { SingleFileLogger(identity(it), file) }
} }
@Suppress("ACTUAL_WITHOUT_EXPECT")
actual enum class MiraiProtocol actual constructor(
/** 协议模块使用的 ID */
@JvmField actual internal val id: Long
) {
/**
* Android 手机.
*/
ANDROID_PHONE(537062845),
/**
* Android 平板.
*/
ANDROID_PAD(537062409),
/**
* Android 手表.
* */
@SinceMirai("1.1.0")
ANDROID_WATCH(537061176)
}
actual companion object { actual companion object {
/** 默认的配置实例. 可以进行修改 */ /** 默认的配置实例. 可以进行修改 */
@JvmStatic @JvmStatic
......
...@@ -53,50 +53,67 @@ actual open class PlatformLogger @JvmOverloads constructor( ...@@ -53,50 +53,67 @@ actual open class PlatformLogger @JvmOverloads constructor(
) : MiraiLoggerPlatformBase() { ) : MiraiLoggerPlatformBase() {
actual constructor(identity: String?) : this(identity, ::println) actual constructor(identity: String?) : this(identity, ::println)
private fun out(message: String?, priority: String, color: Color) { /**
if (isColored) output("$color$currentTimeFormatted $priority/$identity: $message") * 输出一条日志. [message] 末尾可能不带换行符.
else output("$currentTimeFormatted $priority/$identity: $message") */
@SinceMirai("1.1.0")
protected open fun printLog(message: String?, priority: SimpleLogger.LogPriority) {
if (isColored) output("${priority.color}$currentTimeFormatted ${priority.simpleName}/$identity: $message")
else output("$currentTimeFormatted ${priority.simpleName}/$identity: $message")
} }
override fun verbose0(message: String?) = out(message, "V", Color.RESET) /**
* 获取指定 [SimpleLogger.LogPriority] 的颜色
*/
@SinceMirai("1.1.0")
protected open val SimpleLogger.LogPriority.color: Color
get() = when (this) {
SimpleLogger.LogPriority.VERBOSE -> Color.RESET
SimpleLogger.LogPriority.INFO -> Color.LIGHT_GREEN
SimpleLogger.LogPriority.WARNING -> Color.LIGHT_RED
SimpleLogger.LogPriority.ERROR -> Color.RED
SimpleLogger.LogPriority.DEBUG -> Color.LIGHT_CYAN
}
override fun verbose0(message: String?) = printLog(message, SimpleLogger.LogPriority.VERBOSE)
override fun verbose0(message: String?, e: Throwable?) { override fun verbose0(message: String?, e: Throwable?) {
if (e != null) verbose((message ?: e.toString()) + "\n${e.stackTraceString}") if (e != null) verbose((message ?: e.toString()) + "\n${e.stackTraceString}")
else verbose(message.toString()) else verbose(message.toString())
} }
override fun info0(message: String?) = out(message, "I", Color.LIGHT_GREEN) override fun info0(message: String?) = printLog(message, SimpleLogger.LogPriority.INFO)
override fun info0(message: String?, e: Throwable?) { override fun info0(message: String?, e: Throwable?) {
if (e != null) info((message ?: e.toString()) + "\n${e.stackTraceString}") if (e != null) info((message ?: e.toString()) + "\n${e.stackTraceString}")
else info(message.toString()) else info(message.toString())
} }
override fun warning0(message: String?) = out(message, "W", Color.LIGHT_RED) override fun warning0(message: String?) = printLog(message, SimpleLogger.LogPriority.WARNING)
override fun warning0(message: String?, e: Throwable?) { override fun warning0(message: String?, e: Throwable?) {
if (e != null) warning((message ?: e.toString()) + "\n${e.stackTraceString}") if (e != null) warning((message ?: e.toString()) + "\n${e.stackTraceString}")
else warning(message.toString()) else warning(message.toString())
} }
override fun error0(message: String?) = out(message, "E", Color.RED) override fun error0(message: String?) = printLog(message, SimpleLogger.LogPriority.ERROR)
override fun error0(message: String?, e: Throwable?) { override fun error0(message: String?, e: Throwable?) {
if (e != null) error((message ?: e.toString()) + "\n${e.stackTraceString}") if (e != null) error((message ?: e.toString()) + "\n${e.stackTraceString}")
else error(message.toString()) else error(message.toString())
} }
override fun debug0(message: String?) = out(message, "D", Color.LIGHT_CYAN) override fun debug0(message: String?) = printLog(message, SimpleLogger.LogPriority.DEBUG)
override fun debug0(message: String?, e: Throwable?) { override fun debug0(message: String?, e: Throwable?) {
if (e != null) debug((message ?: e.toString()) + "\n${e.stackTraceString}") if (e != null) debug((message ?: e.toString()) + "\n${e.stackTraceString}")
else debug(message.toString()) else debug(message.toString())
} }
private val timeFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.SIMPLIFIED_CHINESE) @SinceMirai("1.1.0")
protected open val timeFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.SIMPLIFIED_CHINESE)
private val currentTimeFormatted get() = timeFormat.format(Date()) private val currentTimeFormatted get() = timeFormat.format(Date())
/** @MiraiExperimentalAPI("This is subject to change.")
* @author NaturalHG @SinceMirai("1.1.0")
*/ protected enum class Color(private val format: String) {
@Suppress("unused")
private enum class Color(private val format: String) {
RESET("\u001b[0m"), RESET("\u001b[0m"),
WHITE("\u001b[30m"), WHITE("\u001b[30m"),
......
...@@ -11,6 +11,8 @@ import net.mamoe.mirai.message.data.toLongUnsigned ...@@ -11,6 +11,8 @@ import net.mamoe.mirai.message.data.toLongUnsigned
import java.io.File import java.io.File
import java.io.InputStream import java.io.InputStream
internal const val DEFAULT_REUSABLE_INPUT_BUFFER_SIZE = 8192
internal actual fun ByteArray.asReusableInput(): ReusableInput { internal actual fun ByteArray.asReusableInput(): ReusableInput {
return object : ReusableInput { return object : ReusableInput {
override val md5: ByteArray = md5() override val md5: ByteArray = md5()
...@@ -18,9 +20,11 @@ internal actual fun ByteArray.asReusableInput(): ReusableInput { ...@@ -18,9 +20,11 @@ internal actual fun ByteArray.asReusableInput(): ReusableInput {
override fun chunkedFlow(sizePerPacket: Int): ChunkedFlowSession<ChunkedInput> { override fun chunkedFlow(sizePerPacket: Int): ChunkedFlowSession<ChunkedInput> {
return object : ChunkedFlowSession<ChunkedInput> { return object : ChunkedFlowSession<ChunkedInput> {
override val flow: Flow<ChunkedInput> = inputStream().chunkedFlow(sizePerPacket) private val stream = inputStream()
override val flow: Flow<ChunkedInput> = stream.chunkedFlow(sizePerPacket, ByteArray(DEFAULT_REUSABLE_INPUT_BUFFER_SIZE.coerceAtLeast(sizePerPacket)))
override fun close() { override fun close() {
stream.close()
// nothing to do // nothing to do
} }
} }
...@@ -46,7 +50,7 @@ internal fun File.asReusableInput(deleteOnClose: Boolean): ReusableInput { ...@@ -46,7 +50,7 @@ internal fun File.asReusableInput(deleteOnClose: Boolean): ReusableInput {
override fun chunkedFlow(sizePerPacket: Int): ChunkedFlowSession<ChunkedInput> { override fun chunkedFlow(sizePerPacket: Int): ChunkedFlowSession<ChunkedInput> {
val stream = inputStream() val stream = inputStream()
return object : ChunkedFlowSession<ChunkedInput> { return object : ChunkedFlowSession<ChunkedInput> {
override val flow: Flow<ChunkedInput> = stream.chunkedFlow(sizePerPacket) override val flow: Flow<ChunkedInput> = stream.chunkedFlow(sizePerPacket, ByteArray(DEFAULT_REUSABLE_INPUT_BUFFER_SIZE.coerceAtLeast(sizePerPacket)))
override fun close() { override fun close() {
stream.close() stream.close()
if (deleteOnClose) this@asReusableInput.delete() if (deleteOnClose) this@asReusableInput.delete()
...@@ -72,7 +76,7 @@ internal fun File.asReusableInput(deleteOnClose: Boolean, md5: ByteArray): Reusa ...@@ -72,7 +76,7 @@ internal fun File.asReusableInput(deleteOnClose: Boolean, md5: ByteArray): Reusa
override fun chunkedFlow(sizePerPacket: Int): ChunkedFlowSession<ChunkedInput> { override fun chunkedFlow(sizePerPacket: Int): ChunkedFlowSession<ChunkedInput> {
val stream = inputStream() val stream = inputStream()
return object : ChunkedFlowSession<ChunkedInput> { return object : ChunkedFlowSession<ChunkedInput> {
override val flow: Flow<ChunkedInput> = stream.chunkedFlow(sizePerPacket) override val flow: Flow<ChunkedInput> = stream.chunkedFlow(sizePerPacket, ByteArray(DEFAULT_REUSABLE_INPUT_BUFFER_SIZE.coerceAtLeast(sizePerPacket)))
override fun close() { override fun close() {
stream.close() stream.close()
if (deleteOnClose) this@asReusableInput.delete() if (deleteOnClose) this@asReusableInput.delete()
......
/*
* Copyright 2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
package net.mamoe.mirai.event;
import org.junit.Test;
import java.util.concurrent.atomic.AtomicInteger;
import static kotlin.test.AssertionsKt.assertEquals;
public class JvmMethodEventsTestJava extends SimpleListenerHost {
private final AtomicInteger called = new AtomicInteger(0);
@EventHandler
public void ev(TestEvent event) {
called.incrementAndGet();
}
@EventHandler
public Void ev2(TestEvent event) {
called.incrementAndGet();
return null;
}
@EventHandler
public ListeningStatus ev3(TestEvent event) {
called.incrementAndGet();
return ListeningStatus.LISTENING;
}
@EventHandler
public void ev(TestEvent event, TestEvent event2) {
called.incrementAndGet();
}
@EventHandler
public Void ev2(TestEvent event, TestEvent event2) {
called.incrementAndGet();
return null;
}
@EventHandler
public ListeningStatus ev3(TestEvent event, TestEvent event2) {
called.incrementAndGet();
return ListeningStatus.LISTENING;
}
@Test
public void test() {
Events.registerEvents(this);
EventKt.broadcast(new TestEvent());
assertEquals(6, called.get(), null);
}
}
\ No newline at end of file
...@@ -11,12 +11,12 @@ ...@@ -11,12 +11,12 @@
package net.mamoe.mirai.event package net.mamoe.mirai.event
import junit.framework.TestCase.assertEquals
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import net.mamoe.mirai.utils.internal.runBlocking import net.mamoe.mirai.utils.internal.runBlocking
import org.junit.Test import org.junit.Test
import java.util.concurrent.atomic.AtomicInteger import java.util.concurrent.atomic.AtomicInteger
import kotlin.coroutines.EmptyCoroutineContext import kotlin.coroutines.EmptyCoroutineContext
import kotlin.test.assertEquals
internal class JvmMethodEventsTest { internal class JvmMethodEventsTest {
...@@ -46,6 +46,13 @@ internal class JvmMethodEventsTest { ...@@ -46,6 +46,13 @@ internal class JvmMethodEventsTest {
called.getAndIncrement() called.getAndIncrement()
} }
@Suppress("unused")
@EventHandler
suspend fun `suspend param Void`(event: TestEvent): Void? {
called.getAndIncrement()
return null
}
@EventHandler @EventHandler
@Suppress("unused") @Suppress("unused")
fun TestEvent.`receiver param Unit`(event: TestEvent) { fun TestEvent.`receiver param Unit`(event: TestEvent) {
...@@ -81,15 +88,15 @@ internal class JvmMethodEventsTest { ...@@ -81,15 +88,15 @@ internal class JvmMethodEventsTest {
} }
} }
TestClass().run { // TestClass().run {
this.registerEvents() // this.registerEvents()
//
runBlocking { // runBlocking {
TestEvent().broadcast() // TestEvent().broadcast()
} // }
//
assertEquals(8, this.getCalled()) // assertEquals(9, this.getCalled())
} // }
} }
@Test @Test
...@@ -114,14 +121,14 @@ internal class JvmMethodEventsTest { ...@@ -114,14 +121,14 @@ internal class JvmMethodEventsTest {
} }
} }
TestClass().run { // TestClass().run {
this.registerEvents() // this.registerEvents()
//
runBlocking { // runBlocking {
TestEvent().broadcast() // TestEvent().broadcast()
} // }
//
assertEquals(1, this.getCalled()) // assertEquals(1, this.getCalled())
} // }
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment