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
3dfaa4ee
Commit
3dfaa4ee
authored
Oct 25, 2019
by
Him188
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Powerful MessageChains
parent
ffe8339c
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
272 additions
and
65 deletions
+272
-65
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt
.../src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt
+2
-9
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/Message.kt
.../src/commonMain/kotlin/net.mamoe.mirai/message/Message.kt
+223
-25
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/Messages.kt
...src/commonMain/kotlin/net.mamoe.mirai/message/Messages.kt
+13
-2
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/MessageEventPackets.kt
.../network/protocol/tim/packet/event/MessageEventPackets.kt
+2
-1
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/network/protocol/tim/packet/PacketInternalJvm.kt
...oe/mirai/network/protocol/tim/packet/PacketInternalJvm.kt
+31
-28
mirai-demos/mirai-demo-1/src/main/java/demo1/Main.kt
mirai-demos/mirai-demo-1/src/main/java/demo1/Main.kt
+1
-0
No files found.
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt
View file @
3dfaa4ee
...
...
@@ -24,15 +24,8 @@ sealed class Contact(val bot: Bot, val id: UInt) {
abstract
suspend
fun
sendMessage
(
message
:
MessageChain
)
suspend
fun
sendMessage
(
message
:
Message
)
{
if
(
message
is
MessageChain
)
{
return
sendMessage
(
message
)
}
return
sendMessage
(
message
.
toChain
())
}
suspend
fun
sendMessage
(
plain
:
String
)
=
this
.
sendMessage
(
PlainText
(
plain
))
suspend
fun
sendMessage
(
message
:
Message
)
=
sendMessage
(
message
.
toChain
())
suspend
fun
sendMessage
(
plain
:
String
)
=
sendMessage
(
PlainText
(
plain
))
abstract
suspend
fun
sendXMLMessage
(
message
:
String
)
}
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/Message.kt
View file @
3dfaa4ee
...
...
@@ -70,8 +70,8 @@ interface Message {
* ```
*/
fun
concat
(
tail
:
Message
):
MessageChain
=
if
(
tail
is
MessageChain
)
MessageChain
(
this
).
also
{
tail
.
forEach
{
child
->
it
.
concat
(
child
)
}
}
else
MessageChain
(
this
,
tail
)
if
(
tail
is
MessageChain
)
tail
.
concat
(
this
)
/*MessageChainImpl(this).also { tail.forEach { child -> it.concat(child) } }*/
else
MessageChain
Impl
(
this
,
tail
)
infix
operator
fun
plus
(
another
:
Message
):
MessageChain
=
this
.
concat
(
another
)
infix
operator
fun
plus
(
another
:
String
):
MessageChain
=
this
.
concat
(
another
.
toMessage
())
...
...
@@ -129,23 +129,142 @@ inline class Face(val id: FaceID) : Message {
}
// ==================================== MessageChain ====================================
/**
* 构造无初始元素的可修改的 [MessageChain]. 初始大小将会被设定为 8
*/
@Suppress
(
"FunctionName"
)
fun
MessageChain
():
MessageChain
=
MessageChainImpl
(
ArrayList
(
8
))
/**
* 构造无初始元素的可修改的 [MessageChain]. 初始大小将会被设定为 [initialCapacity]
*/
@Suppress
(
"FunctionName"
)
fun
MessageChain
(
initialCapacity
:
Int
):
MessageChain
=
MessageChainImpl
(
ArrayList
(
initialCapacity
))
/**
* 构造 [MessageChain]
* 若仅提供一个参数, 请考虑使用 [Message.toChain] 以优化性能
*/
@Suppress
(
"FunctionName"
)
fun
MessageChain
(
vararg
messages
:
Message
):
MessageChain
=
MessageChainImpl
(
messages
.
toMutableList
())
/**
* 构造 [MessageChain]
*/
@Suppress
(
"FunctionName"
)
fun
MessageChain
(
messages
:
Iterable
<
Message
>):
MessageChain
=
MessageChainImpl
(
messages
.
toMutableList
())
/**
* 构造单元素的不可修改的 [MessageChain]. 内部类实现为 [SingleMessageChain]
*
* 参数 [delegate] 不能为 [MessageChain] 的实例, 否则将会抛出异常.
* 使用 [Message.toChain] 将帮助提前处理这个问题.
*
* @param delegate 所构造的单元素 [MessageChain] 代表的 [Message]
* @throws IllegalArgumentException 当 [delegate] 为 [MessageChain] 的实例时
* @see Message.toChain 将
*/
@Suppress
(
"FunctionName"
)
fun
SingleMessageChain
(
delegate
:
Message
):
MessageChain
{
require
(
delegate
!
is
MessageChain
)
{
"delegate for SingleMessageChain should not be any instance of MessageChain"
}
return
SingleMessageChainImpl
(
delegate
)
}
/**
* 消息链. 即 MutableList<Message>.
* 它
是一个特殊的 [Message], 实现 [MutableList] 接口, 但将所有的接口调用都转到内部维护的另一个 [MutableList], [delegate
]
* 它
的一般实现为 [MessageChainImpl], `null` 实现为 [NullMessageChain
]
*
* 有关 [MessageChain] 的创建和连接:
* - 当任意两个不是 [MessageChain] 的 [Message] 相连接后, 将会产生一个 [MessageChain].
* - 若两个 [MessageChain] 连接, 后一个将会被
添加
到第一个内.
* - 若两个 [MessageChain] 连接, 后一个将会被
合并
到第一个内.
* - 若一个 [MessageChain] 与一个其他 [Message] 连接, [Message] 将会被添加入 [MessageChain].
* - 若一个 [Message] 与一个 [MessageChain] 连接,
将会创建一个新的 [MessageChain], 并顺序添加连接时的参数
.
* - 若一个 [Message] 与一个 [MessageChain] 连接,
[Message] 将会被添加入 [MessageChain]
.
*/
inline
class
MessageChain
constructor
(
interface
MessageChain
:
Message
,
MutableList
<
Message
>
{
// region Message override
override
val
stringValue
:
String
override
operator
fun
contains
(
sub
:
String
):
Boolean
override
fun
concat
(
tail
:
Message
):
MessageChain
// endregion
operator
fun
plusAssign
(
message
:
Message
)
{
this
.
concat
(
message
)
}
operator
fun
plusAssign
(
plain
:
String
)
{
this
.
concat
(
plain
.
toMessage
())
}
}
/**
* Null 的 [MessageChain].
* 它不包含任何元素, 也没有创建任何 list.
*
* - 所有 get 方法均抛出 [NoSuchElementException]
* - 所有 add 方法均抛出 [UnsupportedOperationException]
* - 其他判断类方法均 false 或 -1
*/
object
NullMessageChain
:
MessageChain
{
override
fun
subList
(
fromIndex
:
Int
,
toIndex
:
Int
):
MutableList
<
Message
>
=
unsupported
()
override
val
stringValue
:
String
get
()
=
""
override
fun
contains
(
sub
:
String
):
Boolean
=
false
override
fun
contains
(
element
:
Message
):
Boolean
=
false
override
fun
concat
(
tail
:
Message
):
MessageChain
=
MessageChainImpl
(
tail
)
override
val
size
:
Int
=
0
override
fun
containsAll
(
elements
:
Collection
<
Message
>):
Boolean
=
false
override
fun
get
(
index
:
Int
):
Message
=
throw
NoSuchElementException
()
override
fun
indexOf
(
element
:
Message
):
Int
=
-
1
override
fun
isEmpty
():
Boolean
=
true
override
fun
iterator
():
MutableIterator
<
Message
>
=
object
:
MutableIterator
<
Message
>
{
override
fun
hasNext
():
Boolean
=
false
override
fun
next
():
Message
=
throw
NoSuchElementException
()
override
fun
remove
()
=
throw
NoSuchElementException
()
}
override
fun
lastIndexOf
(
element
:
Message
):
Int
=
-
1
override
fun
add
(
element
:
Message
):
Boolean
=
unsupported
()
override
fun
add
(
index
:
Int
,
element
:
Message
)
=
unsupported
()
override
fun
addAll
(
index
:
Int
,
elements
:
Collection
<
Message
>):
Boolean
=
unsupported
()
override
fun
addAll
(
elements
:
Collection
<
Message
>):
Boolean
=
unsupported
()
override
fun
clear
()
{}
override
fun
listIterator
():
MutableListIterator
<
Message
>
=
object
:
MutableListIterator
<
Message
>
{
override
fun
hasPrevious
():
Boolean
=
false
override
fun
nextIndex
():
Int
=
-
1
override
fun
previous
():
Message
=
throw
NoSuchElementException
()
override
fun
previousIndex
():
Int
=
-
1
override
fun
add
(
element
:
Message
)
=
unsupported
()
override
fun
hasNext
():
Boolean
=
false
override
fun
next
():
Message
=
throw
NoSuchElementException
()
override
fun
remove
()
=
throw
NoSuchElementException
()
override
fun
set
(
element
:
Message
)
=
unsupported
()
}
override
fun
listIterator
(
index
:
Int
):
MutableListIterator
<
Message
>
=
unsupported
()
override
fun
remove
(
element
:
Message
):
Boolean
=
false
override
fun
removeAll
(
elements
:
Collection
<
Message
>):
Boolean
=
false
override
fun
removeAt
(
index
:
Int
):
Message
=
throw
NoSuchElementException
()
override
fun
retainAll
(
elements
:
Collection
<
Message
>):
Boolean
=
false
override
fun
set
(
index
:
Int
,
element
:
Message
):
Message
=
unsupported
()
private
fun
unsupported
():
Nothing
=
throw
UnsupportedOperationException
()
}
/**
* [MessageChain] 实现
* 它是一个特殊的 [Message], 实现 [MutableList] 接口, 但将所有的接口调用都转到内部维护的另一个 [MutableList].
*/
internal
inline
class
MessageChainImpl
constructor
(
/**
* Elements will not be instances of [MessageChain]
*/
private
val
delegate
:
MutableList
<
Message
>
)
:
Message
,
MutableList
<
Message
>
{
)
:
Message
,
MutableList
<
Message
>
,
MessageChain
{
constructor
()
:
this
(
ArrayList
(
8
))
constructor
(
initialCapacity
:
Int
)
:
this
(
ArrayList
(
initialCapacity
))
constructor
(
vararg
messages
:
Message
)
:
this
(
messages
.
toMutableList
())
constructor
(
messages
:
Iterable
<
Message
>)
:
this
(
messages
.
toMutableList
())
...
...
@@ -154,33 +273,20 @@ inline class MessageChain constructor(
override
operator
fun
contains
(
sub
:
String
):
Boolean
=
delegate
.
any
{
it
.
contains
(
sub
)
}
override
fun
concat
(
tail
:
Message
):
MessageChain
{
if
(
tail
is
MessageChain
)
tail
.
delegate
.
forEach
{
child
->
this
.
concat
(
child
)
}
if
(
tail
is
MessageChain
)
tail
.
forEach
{
child
->
this
.
concat
(
child
)
}
else
this
.
delegate
.
add
(
tail
)
return
this
}
// endregion
/**
* 获取第一个 [M] 类型的实例
* @throws [NoSuchElementException] 如果找不到该类型的实例
*/
inline
fun
<
reified
M
:
Message
>
first
():
Message
=
this
.
first
{
M
::
class
.
isInstance
(
it
)
}
/**
* 获取第一个 [M] 类型的实例
*/
inline
fun
<
reified
M
:
Message
>
firstOrNull
():
Message
?
=
this
.
firstOrNull
{
M
::
class
.
isInstance
(
it
)
}
operator
fun
plusAssign
(
message
:
Message
)
{
// endregion
override
operator
fun
plusAssign
(
message
:
Message
)
{
this
.
concat
(
message
)
}
operator
fun
plusAssign
(
plain
:
String
)
{
o
verride
o
perator
fun
plusAssign
(
plain
:
String
)
{
this
.
concat
(
plain
.
toMessage
())
}
// region MutableList override
override
fun
containsAll
(
elements
:
Collection
<
Message
>):
Boolean
=
delegate
.
containsAll
(
elements
)
...
...
@@ -206,3 +312,95 @@ inline class MessageChain constructor(
override
val
size
:
Int
get
()
=
delegate
.
size
// endregion
}
/**
* 单个成员的不可修改的 [MessageChain].
* 在连接时将会把它当做一个普通 [Message] 看待.
*/
internal
inline
class
SingleMessageChainImpl
(
private
val
delegate
:
Message
)
:
Message
,
MutableList
<
Message
>,
MessageChain
{
// region Message override
override
val
stringValue
:
String
get
()
=
this
.
delegate
.
stringValue
override
operator
fun
contains
(
sub
:
String
):
Boolean
=
delegate
.
contains
(
sub
)
override
fun
concat
(
tail
:
Message
):
MessageChain
{
if
(
tail
is
MessageChain
)
tail
.
forEach
{
child
->
this
.
concat
(
child
)
}
else
MessageChain
(
delegate
,
tail
)
return
this
}
// endregion
// region MutableList override
override
fun
containsAll
(
elements
:
Collection
<
Message
>):
Boolean
=
elements
.
all
{
it
===
delegate
}
override
operator
fun
get
(
index
:
Int
):
Message
=
if
(
index
==
0
)
delegate
else
throw
NoSuchElementException
()
override
fun
indexOf
(
element
:
Message
):
Int
=
if
(
delegate
===
element
)
0
else
-
1
override
fun
isEmpty
():
Boolean
=
false
override
fun
lastIndexOf
(
element
:
Message
):
Int
=
if
(
delegate
===
element
)
0
else
-
1
override
fun
add
(
element
:
Message
):
Boolean
=
throw
UnsupportedOperationException
()
override
fun
add
(
index
:
Int
,
element
:
Message
)
=
throw
UnsupportedOperationException
()
override
fun
addAll
(
index
:
Int
,
elements
:
Collection
<
Message
>):
Boolean
=
throw
UnsupportedOperationException
()
override
fun
addAll
(
elements
:
Collection
<
Message
>):
Boolean
=
throw
UnsupportedOperationException
()
override
fun
clear
()
=
throw
UnsupportedOperationException
()
override
fun
listIterator
():
MutableListIterator
<
Message
>
=
object
:
MutableListIterator
<
Message
>
{
private
var
hasNext
=
true
override
fun
hasPrevious
():
Boolean
=
false
override
fun
nextIndex
():
Int
=
if
(
hasNext
)
0
else
-
1
override
fun
previous
():
Message
=
throw
NoSuchElementException
()
override
fun
previousIndex
():
Int
=
-
1
override
fun
add
(
element
:
Message
)
=
throw
UnsupportedOperationException
()
override
fun
hasNext
():
Boolean
=
!
hasNext
override
fun
next
():
Message
=
if
(
hasNext
)
{
hasNext
=
false
this
@SingleMessageChainImpl
}
else
throw
NoSuchElementException
()
override
fun
remove
()
=
throw
UnsupportedOperationException
()
override
fun
set
(
element
:
Message
)
=
throw
UnsupportedOperationException
()
}
override
fun
listIterator
(
index
:
Int
):
MutableListIterator
<
Message
>
=
throw
UnsupportedOperationException
()
override
fun
remove
(
element
:
Message
):
Boolean
=
throw
UnsupportedOperationException
()
override
fun
removeAll
(
elements
:
Collection
<
Message
>):
Boolean
=
throw
UnsupportedOperationException
()
override
fun
removeAt
(
index
:
Int
):
Message
=
throw
UnsupportedOperationException
()
override
fun
retainAll
(
elements
:
Collection
<
Message
>):
Boolean
=
throw
UnsupportedOperationException
()
override
fun
set
(
index
:
Int
,
element
:
Message
):
Message
=
throw
UnsupportedOperationException
()
override
fun
subList
(
fromIndex
:
Int
,
toIndex
:
Int
):
MutableList
<
Message
>
{
return
if
(
fromIndex
==
0
)
when
(
toIndex
)
{
1
->
mutableListOf
<
Message
>(
this
)
0
->
mutableListOf
()
else
->
throw
UnsupportedOperationException
()
}
else
throw
UnsupportedOperationException
()
}
override
fun
iterator
():
MutableIterator
<
Message
>
=
object
:
MutableIterator
<
Message
>
{
private
var
hasNext
=
true
override
fun
hasNext
():
Boolean
=
!
hasNext
override
fun
next
():
Message
=
if
(
hasNext
)
{
hasNext
=
false
this
@SingleMessageChainImpl
}
else
throw
NoSuchElementException
()
override
fun
remove
()
=
throw
UnsupportedOperationException
()
}
override
operator
fun
contains
(
element
:
Message
):
Boolean
=
element
===
delegate
override
val
size
:
Int
get
()
=
1
// endregion
}
/**
* 获取第一个 [M] 类型的实例
*/
inline
fun
<
reified
M
:
Message
>
MessageChain
.
firstOrNull
():
Message
?
=
this
.
firstOrNull
{
M
::
class
.
isInstance
(
it
)
}
/**
* 获取第一个 [M] 类型的实例
* @throws [NoSuchElementException] 如果找不到该类型的实例
*/
inline
fun
<
reified
M
:
Message
>
MessageChain
.
first
():
Message
=
this
.
first
{
M
::
class
.
isInstance
(
it
)
}
\ No newline at end of file
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/Messages.kt
View file @
3dfaa4ee
...
...
@@ -7,9 +7,20 @@ package net.mamoe.mirai.message
fun
String
.
toMessage
():
PlainText
=
PlainText
(
this
)
/**
* 构造 [MessageChain]
* 得到包含 [this] 的 [MessageChain].
* 若 [this] 为 [MessageChain] 将直接返回 this
* 否则将调用 [SingleMessageChain] 构造一个唯一成员不可修改的 [SingleMessageChainImpl]
*
* @see SingleMessageChain
* @see SingleMessageChainImpl
*/
fun
Message
.
toChain
():
MessageChain
=
if
(
this
is
MessageChain
)
this
else
SingleMessageChain
(
this
)
/**
* 以 [this] 为代表 (delegate) 构造 [SingleMessageChain].
* @throws IllegalArgumentException 当 [this] 为 [MessageChain] 的实例时
*/
fun
Message
.
toChain
():
MessageChain
=
if
(
this
is
MessageChain
)
this
else
MessageChain
(
this
)
fun
Message
.
singleChain
():
MessageChain
=
Single
MessageChain
(
this
)
/**
* 构造 [MessageChain]
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/MessageEventPackets.kt
View file @
3dfaa4ee
...
...
@@ -6,6 +6,7 @@ import kotlinx.io.core.ByteReadPacket
import
kotlinx.io.core.discardExact
import
kotlinx.io.core.readUInt
import
net.mamoe.mirai.message.MessageChain
import
net.mamoe.mirai.message.NullMessageChain
import
net.mamoe.mirai.message.internal.readMessageChain
import
net.mamoe.mirai.utils.io.*
import
kotlin.properties.Delegates
...
...
@@ -26,7 +27,7 @@ class ServerGroupMessageEventPacket(input: ByteReadPacket, eventIdentity: EventP
* 发送方权限.
*/
lateinit
var
senderPermission
:
SenderPermission
var
message
:
MessageChain
by
Delegates
.
notNull
()
var
message
:
MessageChain
=
NullMessageChain
override
fun
decode
()
=
with
(
input
)
{
discardExact
(
31
)
...
...
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/network/protocol/tim/packet/PacketInternalJvm.kt
View file @
3dfaa4ee
...
...
@@ -36,15 +36,17 @@ private object IgnoreIdList : List<String> by listOf(
"EMPTY_ID_HEX"
,
"input"
,
"output"
,
"this\$0"
,
"\$\$delegatedProperties"
,
"UninitializedByteReadPacket"
,
"sessionKey"
)
internal
actual
fun
Packet
.
packetToString
():
String
=
PacketNameFormatter
.
adjustName
(
this
::
class
.
simpleName
+
"(${this.idHexString})"
)
+
this
::
class
.
java
.
allDeclaredFields
.
filterNot
{
it
.
name
in
IgnoreIdList
||
/*"delegate" in it.name||*/
"$"
in
it
.
name
}
.
filterNot
{
it
.
name
in
IgnoreIdList
/*|| "delegate" in it.name|| "$" in it.name */
}
.
joinToString
(
", "
,
"{"
,
"}"
)
{
it
.
isAccessible
=
true
it
.
name
+
"="
+
it
.
get
(
this
).
let
{
value
->
it
.
name
.
replace
(
"\$delegate"
,
""
)
+
"="
+
it
.
get
(
this
).
let
{
value
->
when
(
value
)
{
null
->
null
is
ByteArray
->
value
.
toUHexString
()
...
...
@@ -52,6 +54,7 @@ internal actual fun Packet.packetToString(): String = PacketNameFormatter.adjust
is
ByteReadPacket
->
"[ByteReadPacket(${value.remaining})]"
//is ByteReadPacket -> value.copy().readBytes().toUHexString()
is
IoBuffer
->
"[IoBuffer(${value.readRemaining})]"
is
Lazy
<
*
>
->
"[Lazy]"
else
->
value
.
toString
()
}
}
...
...
mirai-demos/mirai-demo-1/src/main/java/demo1/Main.kt
View file @
3dfaa4ee
...
...
@@ -15,6 +15,7 @@ import net.mamoe.mirai.login
import
net.mamoe.mirai.message.Image
import
net.mamoe.mirai.message.ImageId
import
net.mamoe.mirai.message.PlainText
import
net.mamoe.mirai.message.firstOrNull
import
net.mamoe.mirai.network.protocol.tim.packet.OutgoingRawPacket
import
net.mamoe.mirai.network.protocol.tim.packet.login.LoginResult
import
net.mamoe.mirai.network.protocol.tim.packet.uploadImage
...
...
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