Merge remote-tracking branch 'origin/master'

# Conflicts:
#	mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/MessageSource.kt
This commit is contained in:
Him188 2020-05-09 15:38:20 +08:00
commit 1c1a37a103
14 changed files with 121 additions and 24 deletions

View File

@ -7,7 +7,7 @@ assignees: ''
---
## 问题
<!--在这里简略描述你遇到的问题-->
@ -17,14 +17,18 @@ assignees: ''
<!--如果有控制台报错,请尽量在这里附加全面的日志. (不建议截图)-->
```
## 如何复现
### 如何复现
<!--在这里简略说明如何让这个问题再次发生-->
<!--可使用 1. 2. 3. 的列表格式,或其他任意恰当的格式-->
### 版本
mirai: `` <!--在``中填写你正在使用的版本号如0.40.0-->
<!--如有必要,你可以在下文继续添加其他信息-->

View File

@ -18,6 +18,7 @@ buildscript {
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${Versions.Kotlin.stdlib}")
classpath("org.jetbrains.kotlin:kotlin-serialization:${Versions.Kotlin.stdlib}")
classpath("org.jetbrains.kotlinx:atomicfu-gradle-plugin:${Versions.Kotlin.atomicFU}")
classpath("org.jetbrains.kotlinx:binary-compatibility-validator:${Versions.Kotlin.binaryValidator}")
}
}
@ -26,6 +27,10 @@ plugins {
// id("com.jfrog.bintray") version Versions.Publishing.bintray apply false
}
// https://github.com/kotlin/binary-compatibility-validator
apply(plugin = "binary-compatibility-validator")
project.ext.set("isAndroidSDKAvailable", false)
// until
@ -139,17 +144,20 @@ subprojects {
}
fun Project.findLatestFile(): Map.Entry<String, File>? {
fun Project.findLatestFile(): Map.Entry<String, File> {
return File(projectDir, "build/libs").walk()
.filter { it.isFile }
.onEach { println("all files=$it") }
.filter { it.name.matches(Regex("""${project.name}-([0-9]|\.)*\.jar""")) }
.filter { it.name.matches(Regex("""${project.name}-[0-9][0-9]*(\.[0-9]*)*.*\.jar""")) }
.onEach { println("matched file: ${it.name}") }
.associateBy { it.nameWithoutExtension.substringAfterLast('-') }
.onEach { println("versions: $it") }
.maxBy {
it.key.split('.').foldRightIndexed(0) { index: Int, s: String, acc: Int ->
acc + 100.0.pow(2 - index).toInt() * (s.toIntOrNull() ?: 0)
}
.maxBy { (version, file) ->
version.split('.').let {
if (it.size == 2) it + "0"
else it
}.reversed().foldIndexed(0) { index: Int, acc: Int, s: String ->
acc + 100.0.pow(index).toInt() * (s.toIntOrNull() ?: 0)
}
} ?: error("cannot find any file to upload")
}

View File

@ -18,6 +18,7 @@ object Versions {
const val atomicFU = "0.14.2"
const val serialization = "0.20.0"
const val ktor = "1.3.2"
const val binaryValidator = "0.2.3"
const val io = "0.1.16"
const val coroutinesIo = "0.1.16"

View File

@ -0,0 +1,13 @@
apiValidation {
ignoredPackages += [
"net.mamoe.mirai.event.internal",
"net.mamoe.mirai.utils.internal"
]
ignoredPackages += [
"net.mamoe.mirai.qqandroid.contact",
"net.mamoe.mirai.qqandroid.message",
"net.mamoe.mirai.qqandroid.network",
"net.mamoe.mirai.qqandroid.utils"
]
}

View File

@ -504,8 +504,8 @@ internal class MsgSvc : ProtoBuf {
@Serializable
internal class SecretFileHead(
@ProtoId(1) @JvmField val secretFileMsg: SubMsgType0xc1.MsgBody? = null,
@ProtoId(2) @JvmField val secretFileStatus: SubMsgType0x1a.MsgBody? = null
@ProtoId(1) @JvmField val secretFileMsg: SubMsgType0xc1.MsgBody? = null
// @ProtoId(2) @JvmField val secretFileStatus: SubMsgType0x1a.MsgBody? = null
)
@Serializable
@ -815,6 +815,7 @@ internal class SubMsgType0xc1 {
) : ProtoBuf
}
/*
@Serializable
internal class SubMsgType0x1a {
@Serializable
@ -830,4 +831,4 @@ internal class SubMsgType0x1a {
@ProtoId(9) @JvmField val fromUin: Long = 0L,
@ProtoId(10) @JvmField val toUin: Long = 0L
) : ProtoBuf
}
}*/

View File

@ -515,6 +515,7 @@ internal class Submsgtype0x129 {
}
/*
internal class Submsgtype0x1a {
internal class SubMsgType0x1a : ProtoBuf {
@Serializable
@ -531,7 +532,7 @@ internal class Submsgtype0x1a {
@ProtoId(10) @JvmField val toUin: Long = 0L
) : ProtoBuf
}
}
}*/
internal class Submsgtype0x26 {
@ -2730,6 +2731,7 @@ internal class Submsgtype0xbe {
}
/*
internal class Submsgtype0xc1 {
internal class Submsgtype0xc1 : ProtoBuf {
@Serializable
@ -2740,7 +2742,7 @@ internal class Submsgtype0xc1 {
) : ProtoBuf
}
}
*/
internal class Submsgtype0xc3 {
internal class Submsgtype0xc3 : ProtoBuf {

View File

@ -52,7 +52,7 @@ internal class NewContact {
struct.msgSeq,
msgAdditional,
struct.reqUin,
Group.calculateGroupUinByGroupCode(groupCode),
groupCode,
reqUinNick
)
}
@ -143,7 +143,7 @@ internal class NewContact {
bot,
struct.msgSeq,
actionUin,
Group.calculateGroupUinByGroupCode(groupCode),
groupCode,
groupName,
actionUinNick
)
@ -155,7 +155,7 @@ internal class NewContact {
struct.msgSeq,
msgAdditional,
struct.reqUin,
Group.calculateGroupUinByGroupCode(groupCode),
groupCode,
groupName,
reqUinNick
)
@ -185,7 +185,7 @@ internal class NewContact {
true -> 11 // accept
false -> 12 // reject
},
groupCode = Group.calculateGroupCodeByGroupUin(event.groupId),
groupCode = event.groupId,
msg = "",
remark = "",
blacklist = blackList

View File

@ -13,6 +13,7 @@ package net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive
import kotlinx.io.core.*
import kotlinx.serialization.Serializable
import net.mamoe.mirai.Bot
import net.mamoe.mirai.LowLevelAPI
import net.mamoe.mirai.contact.MemberPermission
import net.mamoe.mirai.contact.nameCardOrNick
@ -401,13 +402,15 @@ internal class OnlinePush {
when {
pkg.authorUin == bot.id && operator.id == bot.id -> null
else -> {
MessageRecallEvent.GroupRecall(bot,
MessageRecallEvent.GroupRecall(
bot,
pkg.authorUin,
pkg.seq,
pkg.msgRandom,
pkg.time,
operator,
group)
group
)
}
}
}
@ -583,6 +586,10 @@ internal class OnlinePush {
} ?: emptySequence()
}
fun Submsgtype0x27.SubMsgType0x27.ModCustomFace.transform(bot: QQAndroidBot): Sequence<Packet> =
sequenceOf(BotFaceChangedEvent(Bot.getInstance(uin)))
return@lambda528 vProtobuf.loadAs(Submsgtype0x27.SubMsgType0x27.MsgBody.serializer()).msgModInfos.asSequence()
.flatMap {
when {
@ -590,6 +597,7 @@ internal class OnlinePush {
it.msgDelFriend != null -> it.msgDelFriend.transform(bot)
it.msgModGroupProfile != null -> it.msgModGroupProfile.transform(bot)
it.msgModGroupMemberProfile != null -> it.msgModGroupMemberProfile.transform(bot)
it.msgModCustomFace != null -> it.msgModCustomFace.transform(bot)
else -> {
bot.network.logger.debug {
"Transformers528 0x27L: new data: ${it._miraiContentToString()}"

View File

@ -24,6 +24,7 @@ import net.mamoe.mirai.network.closeAndJoin
import net.mamoe.mirai.utils.*
import net.mamoe.mirai.utils.internal.retryCatching
import kotlin.coroutines.CoroutineContext
import kotlin.time.Duration
import kotlin.time.ExperimentalTime
import kotlin.time.measureTime
@ -138,7 +139,7 @@ abstract class BotImpl<N : BotNetworkHandler> constructor(
reconnect()
}
logger.info { "Reconnected successfully in ${time.inMilliseconds} ms" }
logger.info { "Reconnected successfully in ${time.asHumanReadable}" }
}
is BotOfflineEvent.Active -> {
val msg = if (event.cause == null) {

View File

@ -287,7 +287,7 @@ open class MessageSubscribersBuilder<M : MessageEvent, out Ret, R : RR, RR>(
@MessageDsl
fun atAll(): ListeningFilter = content { message.firstIsInstanceOrNull<AtAll>() != null }
/** [消息内容][Message.contentToString]包含 [AtAll] */
/** [消息内容][Message.contentToString]包含目标为 [target] 的 [At] */
@MessageDsl
fun at(target: Long): ListeningFilter = content { message.firstIsInstanceOrNull<At>()?.target == target }

View File

@ -88,6 +88,13 @@ data class BotReloginEvent(
val cause: Throwable?
) : BotEvent, BotActiveEvent, AbstractEvent()
/**
* [Bot] 头像被修改通过其他客户端修改了Bot的头像
*/
data class BotFaceChangedEvent(
override val bot: Bot
) : BotEvent, Packet, AbstractEvent()
// endregion
// region 消息

View File

@ -15,6 +15,10 @@ package net.mamoe.mirai.utils
import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName
import kotlin.jvm.JvmSynthetic
import kotlin.math.floor
import kotlin.time.Duration
import kotlin.time.DurationUnit
import kotlin.time.ExperimentalTime
/**
* 时间戳
@ -77,3 +81,20 @@ inline val Int.weeksToSeconds: Long
@get:JvmSynthetic
inline val Int.monthsToSeconds: Long
get() = this * 30.daysToSeconds
@ExperimentalTime
val Duration.asHumanReadable: String
get() {
val builder = StringBuilder()
val days = toInt(DurationUnit.DAYS)
val hours = toInt(DurationUnit.HOURS) % 24
val minutes = toInt(DurationUnit.MINUTES) % 60
val s = floor(toDouble(DurationUnit.SECONDS) % 60 * 1000) / 1000
with(builder) {
if (days != 0) append("${days}d ")
if (hours != 0) append("${hours}h ")
if (minutes != 0) append("${minutes}min ")
append("${s}s")
}
return builder.toString()
}

View File

@ -0,0 +1,31 @@
/*
* 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.utils
import kotlin.test.Test
import kotlin.test.assertTrue
import kotlin.time.DurationUnit
import kotlin.time.ExperimentalTime
import kotlin.time.toDuration
internal class TimeTest {
@ExperimentalTime
@Test
fun testTimeHumanReadable() {
val time0 = 1.toDuration(DurationUnit.DAYS) +
20.toDuration(DurationUnit.HOURS) +
15.toDuration(DurationUnit.MINUTES) +
2057.toDuration(DurationUnit.MILLISECONDS)
println(time0.asHumanReadable)
assertTrue { time0.asHumanReadable == "1d 20h 15min 2.057s" }
val time1 = 1.toDuration(DurationUnit.DAYS) + 59.toDuration(DurationUnit.MINUTES)
println(time1.asHumanReadable)
assertTrue { time1.asHumanReadable == "1d 59min 0.0s" }
}
}

View File

@ -24,8 +24,8 @@ internal actual class DeferredReusableInput actual constructor(
is InputStream -> strategy.newImageCache(input)
is ByteArray -> strategy.newImageCache(input)
is Input -> strategy.newImageCache(input)
is BufferedImage -> strategy.newImageCache(input, extraArg as String)
is URL -> strategy.newImageCache(input)
is BufferedImage -> strategy.newImageCache(input, extraArg as String)
else -> error("Internal error: unsupported DeferredReusableInput.input: ${input::class.qualifiedName}")
}.input
}