Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
M
Mirai
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
MyCard
Mirai
Commits
b8b749bf
Commit
b8b749bf
authored
Apr 06, 2020
by
Him188
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Completed CombinedMessage redesigning and constraining on concatenation
parent
eaa1e96a
Changes
20
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
494 additions
and
282 deletions
+494
-282
compatibility-validator/build.gradle.kts
compatibility-validator/build.gradle.kts
+18
-1
compatibility-validator/src/main/kotlin/compatibility/testKotlinCompatibility.kt
.../src/main/kotlin/compatibility/testKotlinCompatibility.kt
+14
-0
compatibility-validator/src/test/kotlin/compatibility/CombinedMessageTest.kt
...ator/src/test/kotlin/compatibility/CombinedMessageTest.kt
+79
-0
compatibility-validator/src/test/kotlin/compatibility/TestKotlinCompatibility.kt
.../src/test/kotlin/compatibility/TestKotlinCompatibility.kt
+27
-0
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.common.kt
...n/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.common.kt
+4
-2
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/QQImpl.kt
...onMain/kotlin/net/mamoe/mirai/qqandroid/contact/QQImpl.kt
+1
-1
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt
...moe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt
+2
-2
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/jce/FriendList.kt
...e/mirai/qqandroid/network/protocol/data/jce/FriendList.kt
+1
-1
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt
+1
-0
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/subscribeMessages.kt
...monMain/kotlin/net.mamoe.mirai/event/subscribeMessages.kt
+2
-2
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/MessagePacket.kt
...ommonMain/kotlin/net.mamoe.mirai/message/MessagePacket.kt
+8
-8
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/At.kt
.../src/commonMain/kotlin/net.mamoe.mirai/message/data/At.kt
+3
-1
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/AtAll.kt
...c/commonMain/kotlin/net.mamoe.mirai/message/data/AtAll.kt
+3
-1
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/CombinedMessage.kt
...in/kotlin/net.mamoe.mirai/message/data/CombinedMessage.kt
+52
-46
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/Message.kt
...commonMain/kotlin/net.mamoe.mirai/message/data/Message.kt
+143
-48
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/MessageChain.kt
...nMain/kotlin/net.mamoe.mirai/message/data/MessageChain.kt
+65
-57
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/PlainText.kt
...mmonMain/kotlin/net.mamoe.mirai/message/data/PlainText.kt
+0
-1
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/BotConfiguration.kt
...mmonMain/kotlin/net.mamoe.mirai/utils/BotConfiguration.kt
+0
-24
mirai-core/src/commonTest/kotlin/net/mamoe/mirai/message.data/CombinedMessageTest.kt
...otlin/net/mamoe/mirai/message.data/CombinedMessageTest.kt
+4
-81
mirai-core/src/commonTest/kotlin/net/mamoe/mirai/message.data/ConstrainSingleTest.kt
...otlin/net/mamoe/mirai/message.data/ConstrainSingleTest.kt
+67
-6
No files found.
compatibility-validator/build.gradle.kts
View file @
b8b749bf
...
@@ -7,6 +7,11 @@ plugins {
...
@@ -7,6 +7,11 @@ plugins {
description
=
"Binary and source compatibility validator for mirai-core and mirai-core-qqandroid"
description
=
"Binary and source compatibility validator for mirai-core and mirai-core-qqandroid"
repositories
{
mavenCentral
()
jcenter
()
}
kotlin
{
kotlin
{
sourceSets
{
sourceSets
{
all
{
all
{
...
@@ -17,7 +22,19 @@ kotlin {
...
@@ -17,7 +22,19 @@ kotlin {
main
{
main
{
dependencies
{
dependencies
{
api
(
kotlin
(
"stdlib"
))
api
(
kotlin
(
"stdlib"
))
api
(
project
(
":mirai-core-qqandroid"
))
runtimeOnly
(
project
(
":mirai-core-qqandroid"
))
compileOnly
(
"net.mamoe:mirai-core-qqandroid-jvm:0.33.0"
)
api
(
kotlinx
(
"coroutines-core"
,
Versions
.
Kotlin
.
coroutines
))
}
}
test
{
dependencies
{
api
(
kotlin
(
"stdlib"
))
api
(
kotlin
(
"test"
))
api
(
kotlin
(
"test-junit"
))
runtimeOnly
(
project
(
":mirai-core-qqandroid"
))
compileOnly
(
"net.mamoe:mirai-core-qqandroid-jvm:0.33.0"
)
api
(
kotlinx
(
"coroutines-core"
,
Versions
.
Kotlin
.
coroutines
))
api
(
kotlinx
(
"coroutines-core"
,
Versions
.
Kotlin
.
coroutines
))
}
}
}
}
...
...
compatibility-validator/src/main/kotlin/compatibility/testKotlinCompatibility.kt
0 → 100644
View file @
b8b749bf
/*
* 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
compatibility
fun
main
()
{
}
\ No newline at end of file
compatibility-validator/src/test/kotlin/compatibility/CombinedMessageTest.kt
0 → 100644
View file @
b8b749bf
package
compatibility
import
net.mamoe.mirai.message.data.*
import
net.mamoe.mirai.utils.MiraiInternalAPI
import
kotlin.test.Test
import
kotlin.test.assertEquals
@OptIn
(
MiraiInternalAPI
::
class
)
internal
class
CombinedMessageTest
{
@Test
fun
testAsSequence
()
{
var
message
:
Message
=
"Hello "
.
toMessage
()
message
+=
"World"
assertEquals
(
"Hello World"
,
(
message
as
CombinedMessage
).
asSequence
().
joinToString
(
separator
=
""
)
)
}
@Test
fun
testAsSequence2
()
{
var
message
:
Message
=
"Hello "
.
toMessage
()
message
+=
listOf
(
PlainText
(
"W"
),
PlainText
(
"o"
),
PlainText
(
"r"
)
+
PlainText
(
"ld"
)
).
asMessageChain
()
assertEquals
(
"Hello World"
,
(
message
as
CombinedMessage
).
asSequence
().
joinToString
(
separator
=
""
)
)
}
}
fun
<
T
>
Iterator
<
T
>.
joinToString
(
separator
:
CharSequence
=
", "
,
prefix
:
CharSequence
=
""
,
postfix
:
CharSequence
=
""
,
limit
:
Int
=
-
1
,
truncated
:
CharSequence
=
"..."
,
transform
:
((
T
)
->
CharSequence
)?
=
null
):
String
{
return
joinTo
(
StringBuilder
(),
separator
,
prefix
,
postfix
,
limit
,
truncated
,
transform
).
toString
()
}
fun
<
T
,
A
:
Appendable
>
Iterator
<
T
>.
joinTo
(
buffer
:
A
,
separator
:
CharSequence
=
", "
,
prefix
:
CharSequence
=
""
,
postfix
:
CharSequence
=
""
,
limit
:
Int
=
-
1
,
truncated
:
CharSequence
=
"..."
,
transform
:
((
T
)
->
CharSequence
)?
=
null
):
A
{
buffer
.
append
(
prefix
)
var
count
=
0
for
(
element
in
this
)
{
if
(++
count
>
1
)
buffer
.
append
(
separator
)
if
(
limit
<
0
||
count
<=
limit
)
{
buffer
.
appendElement
(
element
,
transform
)
}
else
break
}
if
(
limit
in
0
until
count
)
buffer
.
append
(
truncated
)
buffer
.
append
(
postfix
)
return
buffer
}
internal
fun
<
T
>
Appendable
.
appendElement
(
element
:
T
,
transform
:
((
T
)
->
CharSequence
)?)
{
when
{
transform
!=
null
->
append
(
transform
(
element
))
element
is
CharSequence
?
->
append
(
element
)
element
is
Char
->
append
(
element
)
else
->
append
(
element
.
toString
())
}
}
\ No newline at end of file
compatibility-validator/src/test/kotlin/compatibility/TestKotlinCompatibility.kt
0 → 100644
View file @
b8b749bf
/*
* 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
compatibility
import
net.mamoe.mirai.message.data.Message
import
net.mamoe.mirai.message.data.PlainText
import
org.junit.Test
internal
class
TestKotlinCompatibility
{
@Test
fun
testMessageChain
()
{
val
x
=
PlainText
(
"te"
)
+
PlainText
(
"st"
)
println
(
Message
::
class
.
java
.
declaredMethods
.
joinToString
(
"\n"
))
println
()
println
(
x
::
class
.
java
.
declaredMethods
.
joinToString
(
"\n"
))
}
}
\ No newline at end of file
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.common.kt
View file @
b8b749bf
...
@@ -56,6 +56,7 @@ import kotlin.coroutines.CoroutineContext
...
@@ -56,6 +56,7 @@ import kotlin.coroutines.CoroutineContext
import
kotlin.jvm.JvmSynthetic
import
kotlin.jvm.JvmSynthetic
import
kotlin.math.absoluteValue
import
kotlin.math.absoluteValue
import
kotlin.random.Random
import
kotlin.random.Random
import
net.mamoe.mirai.qqandroid.network.protocol.data.jce.FriendInfo
as
JceFriendInfo
@OptIn
(
ExperimentalContracts
::
class
)
@OptIn
(
ExperimentalContracts
::
class
)
internal
fun
Bot
.
asQQAndroidBot
():
QQAndroidBot
{
internal
fun
Bot
.
asQQAndroidBot
():
QQAndroidBot
{
...
@@ -98,8 +99,9 @@ internal abstract class QQAndroidBotBase constructor(
...
@@ -98,8 +99,9 @@ internal abstract class QQAndroidBotBase constructor(
override
val
friends
:
ContactList
<
QQ
>
=
ContactList
(
LockFreeLinkedList
())
override
val
friends
:
ContactList
<
QQ
>
=
ContactList
(
LockFreeLinkedList
())
override
lateinit
var
nick
:
String
override
val
nick
:
String
get
()
=
selfInfo
.
nick
internal
set
internal
lateinit
var
selfInfo
:
JceFriendInfo
override
val
selfQQ
:
QQ
by
lazy
{
override
val
selfQQ
:
QQ
by
lazy
{
@OptIn
(
LowLevelAPI
::
class
)
@OptIn
(
LowLevelAPI
::
class
)
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/QQImpl.kt
View file @
b8b749bf
...
@@ -51,7 +51,7 @@ import kotlin.jvm.JvmSynthetic
...
@@ -51,7 +51,7 @@ import kotlin.jvm.JvmSynthetic
internal
inline
class
FriendInfoImpl
(
internal
inline
class
FriendInfoImpl
(
private
val
jceFriendInfo
:
net
.
mamoe
.
mirai
.
qqandroid
.
network
.
protocol
.
data
.
jce
.
FriendInfo
private
val
jceFriendInfo
:
net
.
mamoe
.
mirai
.
qqandroid
.
network
.
protocol
.
data
.
jce
.
FriendInfo
)
:
FriendInfo
{
)
:
FriendInfo
{
override
val
nick
:
String
get
()
=
jceFriendInfo
.
nick
?:
""
override
val
nick
:
String
get
()
=
jceFriendInfo
.
nick
override
val
uin
:
Long
get
()
=
jceFriendInfo
.
friendUin
override
val
uin
:
Long
get
()
=
jceFriendInfo
.
friendUin
}
}
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt
View file @
b8b749bf
...
@@ -223,8 +223,8 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
...
@@ -223,8 +223,8 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
}
}
// self info
// self info
data
.
selfInfo
?.
apply
{
data
.
selfInfo
?.
run
{
bot
.
nick
=
nick
?:
""
bot
.
selfInfo
=
this
// bot.remark = remark ?: ""
// bot.remark = remark ?: ""
// bot.sex = sex
// bot.sex = sex
}
}
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/jce/FriendList.kt
View file @
b8b749bf
...
@@ -109,7 +109,7 @@ internal class FriendInfo(
...
@@ -109,7 +109,7 @@ internal class FriendInfo(
@JceId
(
11
)
val
sqqOnLineStateV2
:
Byte
?
=
null
,
@JceId
(
11
)
val
sqqOnLineStateV2
:
Byte
?
=
null
,
@JceId
(
12
)
val
sShowName
:
String
?
=
""
,
@JceId
(
12
)
val
sShowName
:
String
?
=
""
,
@JceId
(
13
)
val
isRemark
:
Byte
?
=
null
,
@JceId
(
13
)
val
isRemark
:
Byte
?
=
null
,
@JceId
(
14
)
val
nick
:
String
?
=
""
,
@JceId
(
14
)
val
nick
:
String
=
""
,
@JceId
(
15
)
val
specialFlag
:
Byte
?
=
null
,
@JceId
(
15
)
val
specialFlag
:
Byte
?
=
null
,
@JceId
(
16
)
val
vecIMGroupID
:
ByteArray
?
=
null
,
@JceId
(
16
)
val
vecIMGroupID
:
ByteArray
?
=
null
,
@JceId
(
17
)
val
vecMSFGroupID
:
ByteArray
?
=
null
,
@JceId
(
17
)
val
vecMSFGroupID
:
ByteArray
?
=
null
,
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt
View file @
b8b749bf
...
@@ -87,6 +87,7 @@ expect abstract class Bot() : CoroutineScope, LowLevelBotAPIAccessor {
...
@@ -87,6 +87,7 @@ expect abstract class Bot() : CoroutineScope, LowLevelBotAPIAccessor {
/**
/**
* 昵称
* 昵称
*/
*/
@SinceMirai
(
"0.33.1"
)
abstract
val
nick
:
String
abstract
val
nick
:
String
/**
/**
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/subscribeMessages.kt
View file @
b8b749bf
...
@@ -24,7 +24,7 @@ import net.mamoe.mirai.message.ContactMessage
...
@@ -24,7 +24,7 @@ import net.mamoe.mirai.message.ContactMessage
import
net.mamoe.mirai.message.FriendMessage
import
net.mamoe.mirai.message.FriendMessage
import
net.mamoe.mirai.message.GroupMessage
import
net.mamoe.mirai.message.GroupMessage
import
net.mamoe.mirai.message.data.Message
import
net.mamoe.mirai.message.data.Message
import
net.mamoe.mirai.message.data.first
import
net.mamoe.mirai.message.data.first
IsInstance
import
net.mamoe.mirai.utils.SinceMirai
import
net.mamoe.mirai.utils.SinceMirai
import
kotlin.contracts.ExperimentalContracts
import
kotlin.contracts.ExperimentalContracts
import
kotlin.contracts.InvocationKind
import
kotlin.contracts.InvocationKind
...
@@ -700,7 +700,7 @@ open class MessageSubscribersBuilder<M : ContactMessage, out Ret, R : RR, RR>(
...
@@ -700,7 +700,7 @@ open class MessageSubscribersBuilder<M : ContactMessage, out Ret, R : RR, RR>(
@MessageDsl
@MessageDsl
@SinceMirai
(
"0.30.0"
)
@SinceMirai
(
"0.30.0"
)
inline
fun
<
reified
N
:
Message
>
has
(
noinline
onEvent
:
@MessageDsl
suspend
M
.(
N
)
->
R
):
Ret
=
inline
fun
<
reified
N
:
Message
>
has
(
noinline
onEvent
:
@MessageDsl
suspend
M
.(
N
)
->
R
):
Ret
=
content
({
message
.
any
{
it
is
N
}
},
{
onEvent
.
invoke
(
this
,
message
.
first
())
})
content
({
message
.
any
{
it
is
N
}
},
{
onEvent
.
invoke
(
this
,
message
.
first
IsInstance
())
})
/**
/**
* 如果 [mapper] 返回值非空, 就执行 [onEvent]
* 如果 [mapper] 返回值非空, 就执行 [onEvent]
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/MessagePacket.kt
View file @
b8b749bf
...
@@ -357,8 +357,8 @@ suspend inline fun <reified M : Message> ContactMessage.nextMessageContaining(
...
@@ -357,8 +357,8 @@ suspend inline fun <reified M : Message> ContactMessage.nextMessageContaining(
):
M
{
):
M
{
return
subscribingGet
<
ContactMessage
,
ContactMessage
>(
timeoutMillis
)
{
return
subscribingGet
<
ContactMessage
,
ContactMessage
>(
timeoutMillis
)
{
takeIf
{
this
.
isContextIdenticalWith
(
this
@
nextMessageContaining
)
}
takeIf
{
this
.
isContextIdenticalWith
(
this
@
nextMessageContaining
)
}
.
takeIf
{
this
.
message
.
any
<
M
>()
}
.
takeIf
{
this
.
message
.
any
IsInstance
<
M
>()
}
}.
message
.
first
()
}.
message
.
first
IsInstance
()
}
}
@JvmSynthetic
@JvmSynthetic
...
@@ -370,8 +370,8 @@ inline fun <reified M : Message> ContactMessage.nextMessageContainingAsync(
...
@@ -370,8 +370,8 @@ inline fun <reified M : Message> ContactMessage.nextMessageContainingAsync(
@Suppress
(
"RemoveExplicitTypeArguments"
)
@Suppress
(
"RemoveExplicitTypeArguments"
)
subscribingGet
<
ContactMessage
,
ContactMessage
>(
timeoutMillis
)
{
subscribingGet
<
ContactMessage
,
ContactMessage
>(
timeoutMillis
)
{
takeIf
{
this
.
isContextIdenticalWith
(
this
@
nextMessageContainingAsync
)
}
takeIf
{
this
.
isContextIdenticalWith
(
this
@
nextMessageContainingAsync
)
}
.
takeIf
{
this
.
message
.
any
<
M
>()
}
.
takeIf
{
this
.
message
.
any
IsInstance
<
M
>()
}
}.
message
.
first
<
M
>()
}.
message
.
first
IsInstance
<
M
>()
}
}
}
}
...
@@ -391,8 +391,8 @@ suspend inline fun <reified M : Message> ContactMessage.nextMessageContainingOrN
...
@@ -391,8 +391,8 @@ suspend inline fun <reified M : Message> ContactMessage.nextMessageContainingOrN
):
M
?
{
):
M
?
{
return
subscribingGetOrNull
<
ContactMessage
,
ContactMessage
>(
timeoutMillis
)
{
return
subscribingGetOrNull
<
ContactMessage
,
ContactMessage
>(
timeoutMillis
)
{
takeIf
{
this
.
isContextIdenticalWith
(
this
@
nextMessageContainingOrNull
)
}
takeIf
{
this
.
isContextIdenticalWith
(
this
@
nextMessageContainingOrNull
)
}
.
takeIf
{
this
.
message
.
any
<
M
>()
}
.
takeIf
{
this
.
message
.
any
IsInstance
<
M
>()
}
}
?.
message
?.
first
()
}
?.
message
?.
first
IsInstance
()
}
}
@JvmSynthetic
@JvmSynthetic
...
@@ -403,8 +403,8 @@ inline fun <reified M : Message> ContactMessage.nextMessageContainingOrNullAsync
...
@@ -403,8 +403,8 @@ inline fun <reified M : Message> ContactMessage.nextMessageContainingOrNullAsync
return
this
.
bot
.
async
(
coroutineContext
)
{
return
this
.
bot
.
async
(
coroutineContext
)
{
subscribingGetOrNull
<
ContactMessage
,
ContactMessage
>(
timeoutMillis
)
{
subscribingGetOrNull
<
ContactMessage
,
ContactMessage
>(
timeoutMillis
)
{
takeIf
{
this
.
isContextIdenticalWith
(
this
@
nextMessageContainingOrNullAsync
)
}
takeIf
{
this
.
isContextIdenticalWith
(
this
@
nextMessageContainingOrNullAsync
)
}
.
takeIf
{
this
.
message
.
any
<
M
>()
}
.
takeIf
{
this
.
message
.
any
IsInstance
<
M
>()
}
}
?.
message
?.
first
<
M
>()
}
?.
message
?.
first
IsInstance
<
M
>()
}
}
}
}
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/At.kt
View file @
b8b749bf
...
@@ -17,6 +17,7 @@ package net.mamoe.mirai.message.data
...
@@ -17,6 +17,7 @@ package net.mamoe.mirai.message.data
import
net.mamoe.mirai.LowLevelAPI
import
net.mamoe.mirai.LowLevelAPI
import
net.mamoe.mirai.contact.Member
import
net.mamoe.mirai.contact.Member
import
net.mamoe.mirai.contact.nameCardOrNick
import
net.mamoe.mirai.contact.nameCardOrNick
import
net.mamoe.mirai.utils.MiraiInternalAPI
import
kotlin.jvm.JvmMultifileClass
import
kotlin.jvm.JvmMultifileClass
import
kotlin.jvm.JvmName
import
kotlin.jvm.JvmName
import
kotlin.jvm.JvmStatic
import
kotlin.jvm.JvmStatic
...
@@ -56,6 +57,7 @@ private constructor(val target: Long, val display: String) :
...
@@ -56,6 +57,7 @@ private constructor(val target: Long, val display: String) :
}
}
// 自动为消息补充 " "
// 自动为消息补充 " "
@OptIn
(
MiraiInternalAPI
::
class
)
@Suppress
(
"INAPPLICABLE_JVM_NAME"
)
@Suppress
(
"INAPPLICABLE_JVM_NAME"
)
@Deprecated
(
"for binary compatibility"
,
level
=
DeprecationLevel
.
HIDDEN
)
@Deprecated
(
"for binary compatibility"
,
level
=
DeprecationLevel
.
HIDDEN
)
@JvmName
(
"followedBy"
)
@JvmName
(
"followedBy"
)
...
@@ -67,7 +69,7 @@ private constructor(val target: Long, val display: String) :
...
@@ -67,7 +69,7 @@ private constructor(val target: Long, val display: String) :
return
followedByInternalForBinaryCompatibility
(
PlainText
(
" "
)
+
tail
)
return
followedByInternalForBinaryCompatibility
(
PlainText
(
" "
)
+
tail
)
}
}
override
fun
followedBy
(
tail
:
Message
):
Message
{
override
fun
followedBy
(
tail
:
Message
):
Message
Chain
{
if
(
tail
is
PlainText
&&
tail
.
stringValue
.
startsWith
(
' '
))
{
if
(
tail
is
PlainText
&&
tail
.
stringValue
.
startsWith
(
' '
))
{
return
super
.
followedBy
(
tail
)
return
super
.
followedBy
(
tail
)
}
}
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/AtAll.kt
View file @
b8b749bf
...
@@ -12,6 +12,7 @@
...
@@ -12,6 +12,7 @@
package
net.mamoe.mirai.message.data
package
net.mamoe.mirai.message.data
import
net.mamoe.mirai.utils.MiraiInternalAPI
import
net.mamoe.mirai.utils.SinceMirai
import
net.mamoe.mirai.utils.SinceMirai
import
kotlin.jvm.JvmMultifileClass
import
kotlin.jvm.JvmMultifileClass
import
kotlin.jvm.JvmName
import
kotlin.jvm.JvmName
...
@@ -42,6 +43,7 @@ object AtAll :
...
@@ -42,6 +43,7 @@ object AtAll :
override
fun
contentToString
():
String
=
display
override
fun
contentToString
():
String
=
display
// 自动为消息补充 " "
// 自动为消息补充 " "
@OptIn
(
MiraiInternalAPI
::
class
)
@Deprecated
(
"for binary compatibility"
,
level
=
DeprecationLevel
.
HIDDEN
)
@Deprecated
(
"for binary compatibility"
,
level
=
DeprecationLevel
.
HIDDEN
)
@Suppress
(
"INAPPLICABLE_JVM_NAME"
)
@Suppress
(
"INAPPLICABLE_JVM_NAME"
)
@JvmName
(
"followedBy"
)
@JvmName
(
"followedBy"
)
...
@@ -53,7 +55,7 @@ object AtAll :
...
@@ -53,7 +55,7 @@ object AtAll :
return
followedByInternalForBinaryCompatibility
(
PlainText
(
" "
)
+
tail
)
return
followedByInternalForBinaryCompatibility
(
PlainText
(
" "
)
+
tail
)
}
}
override
fun
followedBy
(
tail
:
Message
):
Message
{
override
fun
followedBy
(
tail
:
Message
):
Message
Chain
{
if
(
tail
is
PlainText
&&
tail
.
stringValue
.
startsWith
(
' '
))
{
if
(
tail
is
PlainText
&&
tail
.
stringValue
.
startsWith
(
' '
))
{
return
super
.
followedBy
(
tail
)
return
super
.
followedBy
(
tail
)
}
}
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/CombinedMessage.kt
View file @
b8b749bf
...
@@ -14,11 +14,13 @@ package net.mamoe.mirai.message.data
...
@@ -14,11 +14,13 @@ package net.mamoe.mirai.message.data
import
net.mamoe.mirai.utils.MiraiExperimentalAPI
import
net.mamoe.mirai.utils.MiraiExperimentalAPI
import
net.mamoe.mirai.utils.MiraiInternalAPI
import
net.mamoe.mirai.utils.MiraiInternalAPI
import
net.mamoe.mirai.utils.PlannedRemoval
import
kotlin.jvm.JvmMultifileClass
import
kotlin.jvm.JvmMultifileClass
import
kotlin.jvm.JvmName
import
kotlin.jvm.JvmName
import
kotlin.jvm.JvmSynthetic
/**
/**
*
链接的两个消息
.
*
快速链接的两个消息 (避免构造新的 list)
.
*
*
* 不要直接构造 [CombinedMessage], 使用 [Message.plus]
* 不要直接构造 [CombinedMessage], 使用 [Message.plus]
* 要连接多个 [Message], 使用 [buildMessageChain]
* 要连接多个 [Message], 使用 [buildMessageChain]
...
@@ -27,64 +29,68 @@ import kotlin.jvm.JvmName
...
@@ -27,64 +29,68 @@ import kotlin.jvm.JvmName
*
*
* Left-biased list
* Left-biased list
*/
*/
@MiraiInternalAPI
(
"this API is going to be internal"
)
class
CombinedMessage
class
CombinedMessage
@Deprecated
(
message
=
"use Message.plus"
,
level
=
DeprecationLevel
.
ERROR
)
internal
constructor
(
@MiraiInternalAPI
(
"CombinedMessage 构造器可能会在将来被改动"
)
constructor
(
internal
val
left
:
Message
,
// 必须已经完成 constrain single
@MiraiExperimentalAPI
(
"CombinedMessage.left 可能会在将来被改动"
)
internal
val
tail
:
Message
val
left
:
SingleMessage
,
)
:
Message
,
MessageChain
{
@MiraiExperimentalAPI
(
"CombinedMessage.tail 可能会在将来被改动"
)
val
tail
:
SingleMessage
)
:
Iterable
<
SingleMessage
>,
Message
{
/*
// 不要把它用作 local function, 会编译错误
@OptIn(MiraiExperimentalAPI::class)
private suspend fun SequenceScope<Message>.yieldCombinedOrElements(message: Message) {
when (message) {
is CombinedMessage -> {
// fast path, 避免创建新的 iterator, 也不会挂起协程
yieldCombinedOrElements(message.left)
yieldCombinedOrElements(message.tail)
}
is Iterable<*> -> {
// 更好的性能, 因为协程不会挂起.
// 这可能会导致爆栈 (十万个元素), 但作为消息序列足够了.
message.forEach {
yieldCombinedOrElements(
it as? Message ?: error(
"A Message implementing Iterable must implement Iterable<Message>, " +
"whereas got ${it!!::class.simpleName}"
)
)
}
}
else -> {
check(message is SingleMessage) {
"unsupported Message type. " +
"A Message must be a CombinedMessage, a Iterable<Message> or a SingleMessage"
}
yield(message)
}
}
}
*/
@OptIn
(
MiraiExperimentalAPI
::
class
)
@OptIn
(
MiraiExperimentalAPI
::
class
)
fun
asSequence
():
Sequence
<
SingleMessage
>
=
sequence
{
fun
asSequence
():
Sequence
<
SingleMessage
>
=
sequence
{
yield
(
left
)
yieldCombinedOrElementsFlatten
(
this
@CombinedMessage
)
yield
(
tail
)
}
}
override
fun
iterator
():
Iterator
<
SingleMessage
>
{
override
fun
iterator
():
Iterator
<
SingleMessage
>
{
return
asSequence
().
iterator
()
return
asSequence
().
iterator
()
}
}
@PlannedRemoval
(
"1.0.0"
)
@Deprecated
(
"有歧义, 自行使用 contentToString() 比较"
,
ReplaceWith
(
"this.contentToString() == other"
),
DeprecationLevel
.
HIDDEN
)
override
fun
contains
(
sub
:
String
):
Boolean
{
return
contentToString
().
contains
(
sub
)
}
override
val
size
:
Int
=
when
{
left
===
EmptyMessageChain
&&
tail
!==
EmptyMessageChain
->
1
left
===
EmptyMessageChain
&&
tail
===
EmptyMessageChain
->
0
left
!==
EmptyMessageChain
&&
tail
===
EmptyMessageChain
->
1
left
!==
EmptyMessageChain
&&
tail
!==
EmptyMessageChain
->
2
else
->
error
(
"stub"
)
}
@OptIn
(
MiraiExperimentalAPI
::
class
)
@OptIn
(
MiraiExperimentalAPI
::
class
)
override
fun
toString
():
String
{
override
fun
toString
():
String
{
return
tail
.
toString
()
+
left
.
toString
()
return
tail
.
toString
()
+
left
.
toString
()
}
}
override
fun
contentToString
():
String
{
override
fun
contentToString
():
String
{
return
toString
()
return
left
.
contentToString
()
+
tail
.
contentToString
()
}
}
@JvmSynthetic
// 不要把它用作 local function, 会编译错误
@OptIn
(
MiraiExperimentalAPI
::
class
,
MiraiInternalAPI
::
class
)
private
suspend
fun
SequenceScope
<
SingleMessage
>.
yieldCombinedOrElementsFlatten
(
message
:
Message
)
{
when
(
message
)
{
is
CombinedMessage
->
{
// fast path, 避免创建新的 iterator, 也不会挂起协程
yieldCombinedOrElementsFlatten
(
message
.
left
)
yieldCombinedOrElementsFlatten
(
message
.
tail
)
}
is
MessageChain
->
{
yieldAll
(
message
)
}
else
->
{
check
(
message
is
SingleMessage
)
{
"unsupported Message type: ${message::class}"
+
"A Message must be a CombinedMessage, a Iterable<Message> or a SingleMessage"
}
yield
(
message
)
}
}
}
}
}
\ No newline at end of file
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/Message.kt
View file @
b8b749bf
This diff is collapsed.
Click to expand it.
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/MessageChain.kt
View file @
b8b749bf
This diff is collapsed.
Click to expand it.
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/PlainText.kt
View file @
b8b749bf
...
@@ -30,7 +30,6 @@ class PlainText(val stringValue: String) :
...
@@ -30,7 +30,6 @@ class PlainText(val stringValue: String) :
@Suppress
(
"unused"
)
@Suppress
(
"unused"
)
constructor
(
charSequence
:
CharSequence
)
:
this
(
charSequence
.
toString
())
constructor
(
charSequence
:
CharSequence
)
:
this
(
charSequence
.
toString
())
override
operator
fun
contains
(
sub
:
String
):
Boolean
=
sub
in
stringValue
override
fun
toString
():
String
=
stringValue
override
fun
toString
():
String
=
stringValue
override
fun
contentToString
():
String
=
stringValue
override
fun
contentToString
():
String
=
stringValue
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/BotConfiguration.kt
View file @
b8b749bf
...
@@ -97,30 +97,6 @@ open class BotConfiguration {
...
@@ -97,30 +97,6 @@ open class BotConfiguration {
fun
fileBasedDeviceInfo
(
filename
:
String
=
"device.json"
)
{
fun
fileBasedDeviceInfo
(
filename
:
String
=
"device.json"
)
{
deviceInfo
=
getFileBasedDeviceInfoSupplier
(
filename
)
deviceInfo
=
getFileBasedDeviceInfoSupplier
(
filename
)
}
}
@PlannedRemoval
(
"0.34.0"
)
@Deprecated
(
"use fileBasedDeviceInfo(filepath"
,
level
=
DeprecationLevel
.
ERROR
,
replaceWith
=
ReplaceWith
(
"fileBasedDeviceInfo"
)
)
operator
fun
FileBasedDeviceInfo
.
unaryPlus
()
{
fileBasedDeviceInfo
(
this
.
filepath
)
}
}
/**
* 使用文件系统存储设备信息.
*/
@PlannedRemoval
(
"0.34.0"
)
@Deprecated
(
"use fileBasedDeviceInfo(filepath"
,
level
=
DeprecationLevel
.
ERROR
)
inline
class
FileBasedDeviceInfo
(
val
filepath
:
String
)
{
/**
* 使用 "device.json" 存储设备信息
*/
companion
object
ByDeviceDotJson
}
}
@OptIn
(
ExperimentalMultiplatform
::
class
)
@OptIn
(
ExperimentalMultiplatform
::
class
)
...
...
mirai-core/src/commonTest/kotlin/net/mamoe/mirai/message.data/CombinedMessageTest.kt
View file @
b8b749bf
package
net.mamoe.mirai.message.data
package
net.mamoe.mirai.message.data
import
net.mamoe.mirai.utils.MiraiInternalAPI
import
kotlin.test.Test
import
kotlin.test.Test
import
kotlin.test.assertEquals
import
kotlin.test.assertEquals
import
kotlin.time.ExperimentalTime
import
kotlin.time.measureTime
@OptIn
(
MiraiInternalAPI
::
class
)
internal
class
CombinedMessageTest
{
internal
class
CombinedMessageTest
{
@Test
@Test
fun
testAsSequence
()
{
fun
testAsSequence
()
{
var
message
:
Message
=
"Hello "
.
toMessage
()
var
message
:
Message
=
"Hello "
.
toMessage
()
...
@@ -32,84 +33,6 @@ internal class CombinedMessageTest {
...
@@ -32,84 +33,6 @@ internal class CombinedMessageTest {
(
message
as
CombinedMessage
).
asSequence
().
joinToString
(
separator
=
""
)
(
message
as
CombinedMessage
).
asSequence
().
joinToString
(
separator
=
""
)
)
)
}
}
private
val
toAdd
=
"1"
.
toMessage
()
@OptIn
(
ExperimentalTime
::
class
)
@Test
fun
speedTest
()
=
repeat
(
100
)
{
var
count
=
1L
repeat
(
Int
.
MAX_VALUE
)
{
count
++
}
var
combineMessage
:
Message
=
toAdd
println
(
"init combine ok "
+
measureTime
{
repeat
(
1000
)
{
combineMessage
+=
toAdd
}
}.
inMilliseconds
)
val
list
=
mutableListOf
<
Message
>()
println
(
"init messageChain ok "
+
measureTime
{
repeat
(
1000
)
{
list
+=
toAdd
}
}.
inMilliseconds
)
measureTime
{
list
.
joinToString
(
separator
=
""
)
}.
let
{
time
->
println
(
"list foreach: ${time.inMilliseconds} ms"
)
}
measureTime
{
(
combineMessage
as
CombinedMessage
).
iterator
().
joinToString
(
separator
=
""
)
}.
let
{
time
->
println
(
"combined iterate: ${time.inMilliseconds} ms"
)
}
measureTime
{
(
combineMessage
as
CombinedMessage
).
asSequence
().
joinToString
(
separator
=
""
)
}.
let
{
time
->
println
(
"combined sequence: ${time.inMilliseconds} ms"
)
}
repeat
(
5
)
{
println
()
}
}
@OptIn
(
ExperimentalTime
::
class
)
@Test
fun
testFastIteration
()
{
println
(
"start!"
)
println
(
"start!"
)
println
(
"start!"
)
println
(
"start!"
)
var
combineMessage
:
Message
=
toAdd
println
(
"init combine ok "
+
measureTime
{
repeat
(
1000
)
{
combineMessage
+=
toAdd
}
}.
inMilliseconds
)
measureTime
{
(
combineMessage
as
CombinedMessage
).
iterator
().
joinToString
(
separator
=
""
)
}.
let
{
time
->
println
(
"combine: ${time.inMilliseconds} ms"
)
}
}
}
}
fun
<
T
>
Iterator
<
T
>.
joinToString
(
fun
<
T
>
Iterator
<
T
>.
joinToString
(
...
@@ -140,7 +63,7 @@ fun <T, A : Appendable> Iterator<T>.joinTo(
...
@@ -140,7 +63,7 @@ fun <T, A : Appendable> Iterator<T>.joinTo(
buffer
.
appendElement
(
element
,
transform
)
buffer
.
appendElement
(
element
,
transform
)
}
else
break
}
else
break
}
}
if
(
limit
>=
0
&&
count
>
limi
t
)
buffer
.
append
(
truncated
)
if
(
limit
in
0
until
coun
t
)
buffer
.
append
(
truncated
)
buffer
.
append
(
postfix
)
buffer
.
append
(
postfix
)
return
buffer
return
buffer
}
}
...
...
mirai-core/src/commonTest/kotlin/net/mamoe/mirai/message.data/ConstrainSingleTest.kt
View file @
b8b749bf
...
@@ -10,9 +10,11 @@
...
@@ -10,9 +10,11 @@
package
net.mamoe.mirai.message.data
package
net.mamoe.mirai.message.data
import
net.mamoe.mirai.utils.MiraiExperimentalAPI
import
net.mamoe.mirai.utils.MiraiExperimentalAPI
import
net.mamoe.mirai.utils.MiraiInternalAPI
import
kotlin.test.Test
import
kotlin.test.Test
import
kotlin.test.assertEquals
import
kotlin.test.assertEquals
import
kotlin.test.assertSame
import
kotlin.test.assertSame
import
kotlin.test.assertTrue
@OptIn
(
MiraiExperimentalAPI
::
class
)
@OptIn
(
MiraiExperimentalAPI
::
class
)
...
@@ -25,7 +27,7 @@ internal class TestConstrainSingleMessage : ConstrainSingle<TestConstrainSingleM
...
@@ -25,7 +27,7 @@ internal class TestConstrainSingleMessage : ConstrainSingle<TestConstrainSingleM
override
fun
toString
():
String
=
"<TestConstrainSingleMessage#${super.hashCode()}>"
override
fun
toString
():
String
=
"<TestConstrainSingleMessage#${super.hashCode()}>"
override
fun
contentToString
():
String
{
override
fun
contentToString
():
String
{
TODO
(
"Not yet implemented"
)
return
""
}
}
override
val
key
:
Message
.
Key
<
TestConstrainSingleMessage
>
override
val
key
:
Message
.
Key
<
TestConstrainSingleMessage
>
...
@@ -46,16 +48,75 @@ internal class TestConstrainSingleMessage : ConstrainSingle<TestConstrainSingleM
...
@@ -46,16 +48,75 @@ internal class TestConstrainSingleMessage : ConstrainSingle<TestConstrainSingleM
}
}
}
}
@OptIn
(
MiraiExperimentalAPI
::
class
)
internal
class
ConstrainSingleTest
{
internal
class
ConstrainSingleTest
{
@OptIn
(
MiraiExperimentalAPI
::
class
)
@OptIn
(
MiraiInternalAPI
::
class
)
@Test
fun
testCombine
()
{
val
result
=
PlainText
(
"te"
)
+
PlainText
(
"st"
)
assertTrue
(
result
is
CombinedMessage
)
assertEquals
(
"te"
,
result
.
left
.
contentToString
())
assertEquals
(
"st"
,
result
.
tail
.
contentToString
())
assertEquals
(
2
,
result
.
size
)
assertEquals
(
"test"
,
result
.
contentToString
())
}
@Test
fun
testSinglePlusChain
()
{
val
result
=
PlainText
(
"te"
)
+
buildMessageChain
{
add
(
TestConstrainSingleMessage
())
add
(
"st"
)
}
assertTrue
(
result
is
MessageChainImplByCollection
)
assertEquals
(
3
,
result
.
size
)
assertEquals
(
result
.
contentToString
(),
"test"
)
}
@Test
fun
testSinglePlusChainConstrain
()
{
val
chain
=
buildMessageChain
{
add
(
TestConstrainSingleMessage
())
add
(
"st"
)
}
val
result
=
TestConstrainSingleMessage
()
+
chain
assertSame
(
chain
,
result
)
assertEquals
(
2
,
result
.
size
)
assertEquals
(
result
.
contentToString
(),
"st"
)
assertTrue
{
result
.
first
()
is
TestConstrainSingleMessage
}
}
@Test
fun
testSinglePlusSingle
()
{
val
new
=
TestConstrainSingleMessage
()
val
combined
=
(
TestConstrainSingleMessage
()
+
new
)
assertTrue
(
combined
is
SingleMessageChainImpl
)
assertSame
(
new
,
combined
.
delegate
)
}
@Test
@Test
fun
testC
onstrainSingleInPlus
()
{
fun
testC
hainPlusSingle
()
{
val
new
=
TestConstrainSingleMessage
()
val
new
=
TestConstrainSingleMessage
()
val
combined
=
(
TestConstrainSingleMessage
()
+
new
)
as
CombinedMessage
assertEquals
(
combined
.
left
,
EmptyMessageChain
)
val
result
=
buildMessageChain
{
assertSame
(
combined
.
tail
,
new
)
add
(
" "
)
add
(
Face
(
Face
.
hao
))
add
(
TestConstrainSingleMessage
())
add
(
PlainText
(
"ss"
)
+
" "
)
}
+
buildMessageChain
{
add
(
PlainText
(
"p "
))
add
(
new
)
add
(
PlainText
(
"test"
))
}
assertEquals
(
7
,
result
.
size
)
assertEquals
(
" [表情]ss p test"
,
result
.
contentToString
())
result
as
MessageChainImplByCollection
assertSame
(
new
,
result
.
delegate
.
toTypedArray
()[
2
])
}
}
@Test
// net.mamoe.mirai/message/data/MessageChain.kt:441
@Test
// net.mamoe.mirai/message/data/MessageChain.kt:441
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment