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
587fab23
Commit
587fab23
authored
Feb 21, 2020
by
Him188
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Support recall, add MessageReceipt
parent
ff8e6e8b
Changes
23
Hide whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
528 additions
and
179 deletions
+528
-179
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/ContactImpl.kt
...ommonMain/kotlin/net/mamoe/mirai/qqandroid/ContactImpl.kt
+44
-6
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/MsgRevokeUserDef.kt
...qqandroid/network/protocol/data/proto/MsgRevokeUserDef.kt
+38
-0
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/PacketFactory.kt
.../mirai/qqandroid/network/protocol/packet/PacketFactory.kt
+3
-1
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/PbMessageSvc.kt
...ai/qqandroid/network/protocol/packet/chat/PbMessageSvc.kt
+91
-0
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.kt
...ndroid/network/protocol/packet/chat/receive/MessageSvc.kt
+59
-6
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/OnlinePush.kt
...ndroid/network/protocol/packet/chat/receive/OnlinePush.kt
+9
-3
mirai-core-qqandroid/src/jvmTest/kotlin/androidPacketTests/clientToServer.kt
...d/src/jvmTest/kotlin/androidPacketTests/clientToServer.kt
+2
-0
mirai-core-qqandroid/src/jvmTest/kotlin/test/ProtoBufDataClassGenerator.kt
...oid/src/jvmTest/kotlin/test/ProtoBufDataClassGenerator.kt
+1
-1
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt
+1
-3
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt
.../src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt
+9
-3
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Group.kt
...re/src/commonMain/kotlin/net.mamoe.mirai/contact/Group.kt
+89
-1
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/QQ.kt
...-core/src/commonMain/kotlin/net.mamoe.mirai/contact/QQ.kt
+19
-0
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/data/GroupInfo.kt
...e/src/commonMain/kotlin/net.mamoe.mirai/data/GroupInfo.kt
+11
-0
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/Event.kt
...core/src/commonMain/kotlin/net.mamoe.mirai/event/Event.kt
+0
-0
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/linear.kt
...ore/src/commonMain/kotlin/net.mamoe.mirai/event/linear.kt
+11
-0
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/subscribeMessages.kt
...monMain/kotlin/net.mamoe.mirai/event/subscribeMessages.kt
+0
-0
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/subscriber.kt
...src/commonMain/kotlin/net.mamoe.mirai/event/subscriber.kt
+0
-0
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/GroupMessage.kt
...commonMain/kotlin/net.mamoe.mirai/message/GroupMessage.kt
+7
-3
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/MessagePacket.kt
...ommonMain/kotlin/net.mamoe.mirai/message/MessagePacket.kt
+7
-20
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/MessageReceipt.kt
...mmonMain/kotlin/net.mamoe.mirai/message/MessageReceipt.kt
+108
-0
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/MessageChain.kt
...nMain/kotlin/net.mamoe.mirai/message/data/MessageChain.kt
+17
-119
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/MessageSource.kt
...Main/kotlin/net.mamoe.mirai/message/data/MessageSource.kt
+1
-1
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/PlainText.kt
...mmonMain/kotlin/net.mamoe.mirai/message/data/PlainText.kt
+1
-12
No files found.
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/ContactImpl.kt
View file @
587fab23
...
@@ -16,14 +16,13 @@ import net.mamoe.mirai.event.broadcast
...
@@ -16,14 +16,13 @@ import net.mamoe.mirai.event.broadcast
import
net.mamoe.mirai.event.events.*
import
net.mamoe.mirai.event.events.*
import
net.mamoe.mirai.event.events.MessageSendEvent.FriendMessageSendEvent
import
net.mamoe.mirai.event.events.MessageSendEvent.FriendMessageSendEvent
import
net.mamoe.mirai.event.events.MessageSendEvent.GroupMessageSendEvent
import
net.mamoe.mirai.event.events.MessageSendEvent.GroupMessageSendEvent
import
net.mamoe.mirai.message.data.CustomFaceFromFile
import
net.mamoe.mirai.message.MessageReceipt
import
net.mamoe.mirai.message.data.Image
import
net.mamoe.mirai.message.data.*
import
net.mamoe.mirai.message.data.MessageChain
import
net.mamoe.mirai.message.data.NotOnlineImageFromFile
import
net.mamoe.mirai.qqandroid.network.highway.HighwayHelper
import
net.mamoe.mirai.qqandroid.network.highway.HighwayHelper
import
net.mamoe.mirai.qqandroid.network.highway.postImage
import
net.mamoe.mirai.qqandroid.network.highway.postImage
import
net.mamoe.mirai.qqandroid.network.protocol.data.jce.StTroopMemberInfo
import
net.mamoe.mirai.qqandroid.network.protocol.data.jce.StTroopMemberInfo
import
net.mamoe.mirai.qqandroid.network.protocol.data.proto.Cmd0x352
import
net.mamoe.mirai.qqandroid.network.protocol.data.proto.Cmd0x352
import
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.PbMessageSvc
import
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.TroopManagement
import
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.TroopManagement
import
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image.ImgStore
import
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image.ImgStore
import
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image.LongConn
import
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image.LongConn
...
@@ -66,7 +65,7 @@ internal class QQImpl(
...
@@ -66,7 +65,7 @@ internal class QQImpl(
override
val
nick
:
String
override
val
nick
:
String
get
()
=
friendInfo
.
nick
get
()
=
friendInfo
.
nick
override
suspend
fun
sendMessage
(
message
:
MessageChain
)
{
override
suspend
fun
sendMessage
(
message
:
MessageChain
)
:
MessageReceipt
<
QQ
>
{
val
event
=
FriendMessageSendEvent
(
this
,
message
).
broadcast
()
val
event
=
FriendMessageSendEvent
(
this
,
message
).
broadcast
()
if
(
event
.
isCancelled
)
{
if
(
event
.
isCancelled
)
{
throw
EventCancelledException
(
"cancelled by FriendMessageSendEvent"
)
throw
EventCancelledException
(
"cancelled by FriendMessageSendEvent"
)
...
@@ -80,6 +79,7 @@ internal class QQImpl(
...
@@ -80,6 +79,7 @@ internal class QQImpl(
).
sendAndExpect
<
MessageSvc
.
PbSendMsg
.
Response
>()
is
MessageSvc
.
PbSendMsg
.
Response
.
SUCCESS
).
sendAndExpect
<
MessageSvc
.
PbSendMsg
.
Response
>()
is
MessageSvc
.
PbSendMsg
.
Response
.
SUCCESS
)
{
"send message failed"
}
)
{
"send message failed"
}
}
}
return
MessageReceipt
(
message
,
this
)
}
}
override
suspend
fun
uploadImage
(
image
:
ExternalImage
):
Image
=
try
{
override
suspend
fun
uploadImage
(
image
:
ExternalImage
):
Image
=
try
{
...
@@ -325,6 +325,24 @@ internal class GroupImpl(
...
@@ -325,6 +325,24 @@ internal class GroupImpl(
override
lateinit
var
owner
:
Member
override
lateinit
var
owner
:
Member
@UseExperimental
(
MiraiExperimentalAPI
::
class
)
override
val
botAsMember
:
Member
by
lazy
{
Member
(
object
:
MemberInfo
{
override
val
nameCard
:
String
get
()
=
bot
.
nick
// TODO: 2020/2/21 机器人在群内的昵称获取
override
val
permission
:
MemberPermission
get
()
=
botPermission
override
val
specialTitle
:
String
get
()
=
""
// TODO: 2020/2/21 获取机器人在群里的头衔
override
val
muteTimestamp
:
Int
get
()
=
botMuteRemaining
override
val
uin
:
Long
get
()
=
bot
.
uin
override
val
nick
:
String
get
()
=
bot
.
nick
})
}
@UseExperimental
(
MiraiExperimentalAPI
::
class
)
@UseExperimental
(
MiraiExperimentalAPI
::
class
)
override
lateinit
var
botPermission
:
MemberPermission
override
lateinit
var
botPermission
:
MemberPermission
...
@@ -340,6 +358,9 @@ internal class GroupImpl(
...
@@ -340,6 +358,9 @@ internal class GroupImpl(
override
val
members
:
ContactList
<
Member
>
=
ContactList
(
members
.
mapNotNull
{
override
val
members
:
ContactList
<
Member
>
=
ContactList
(
members
.
mapNotNull
{
if
(
it
.
uin
==
bot
.
uin
)
{
if
(
it
.
uin
==
bot
.
uin
)
{
botPermission
=
it
.
permission
botPermission
=
it
.
permission
if
(
it
.
permission
==
MemberPermission
.
OWNER
)
{
owner
=
botAsMember
}
null
null
}
else
Member
(
it
).
also
{
member
->
}
else
Member
(
it
).
also
{
member
->
if
(
member
.
permission
==
MemberPermission
.
OWNER
)
{
if
(
member
.
permission
==
MemberPermission
.
OWNER
)
{
...
@@ -475,6 +496,18 @@ internal class GroupImpl(
...
@@ -475,6 +496,18 @@ internal class GroupImpl(
TODO
(
"not implemented"
)
TODO
(
"not implemented"
)
}
}
override
suspend
fun
recall
(
source
:
MessageSource
)
{
if
(
source
.
senderId
!=
bot
.
uin
)
{
checkBotPermissionOperator
()
}
bot
.
network
.
run
{
val
response
=
PbMessageSvc
.
PbMsgWithDraw
.
Group
(
bot
.
client
,
this
@GroupImpl
.
id
,
source
.
sequenceId
,
source
.
messageUid
.
toInt
())
.
sendAndExpect
<
PbMessageSvc
.
PbMsgWithDraw
.
Response
>()
check
(
response
is
PbMessageSvc
.
PbMsgWithDraw
.
Response
.
Success
)
{
"Failed to recall message #${source.sequenceId}: $response"
}
}
}
@UseExperimental
(
MiraiExperimentalAPI
::
class
)
@UseExperimental
(
MiraiExperimentalAPI
::
class
)
override
fun
Member
(
memberInfo
:
MemberInfo
):
Member
{
override
fun
Member
(
memberInfo
:
MemberInfo
):
Member
{
return
MemberImpl
(
return
MemberImpl
(
...
@@ -498,7 +531,7 @@ internal class GroupImpl(
...
@@ -498,7 +531,7 @@ internal class GroupImpl(
return
members
.
delegate
.
filteringGetOrNull
{
it
.
id
==
id
}
return
members
.
delegate
.
filteringGetOrNull
{
it
.
id
==
id
}
}
}
override
suspend
fun
sendMessage
(
message
:
MessageChain
)
{
override
suspend
fun
sendMessage
(
message
:
MessageChain
)
:
MessageReceipt
<
Group
>
{
check
(!
isBotMuted
)
{
"bot is muted. Remaining seconds=$botMuteRemaining"
}
check
(!
isBotMuted
)
{
"bot is muted. Remaining seconds=$botMuteRemaining"
}
val
event
=
GroupMessageSendEvent
(
this
,
message
).
broadcast
()
val
event
=
GroupMessageSendEvent
(
this
,
message
).
broadcast
()
if
(
event
.
isCancelled
)
{
if
(
event
.
isCancelled
)
{
...
@@ -514,6 +547,11 @@ internal class GroupImpl(
...
@@ -514,6 +547,11 @@ internal class GroupImpl(
response
is
MessageSvc
.
PbSendMsg
.
Response
.
SUCCESS
response
is
MessageSvc
.
PbSendMsg
.
Response
.
SUCCESS
)
{
"send message failed: $response"
}
)
{
"send message failed: $response"
}
}
}
((
message
.
last
()
as
MessageSource
)
as
MessageSvc
.
PbSendMsg
.
MessageSourceFromSend
)
.
startWaitingSequenceId
(
this
)
return
MessageReceipt
(
message
,
this
)
}
}
override
suspend
fun
uploadImage
(
image
:
ExternalImage
):
Image
=
try
{
override
suspend
fun
uploadImage
(
image
:
ExternalImage
):
Image
=
try
{
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/MsgRevokeUserDef.kt
0 → 100644
View file @
587fab23
/*
* 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.qqandroid.network.protocol.data.proto
import
kotlinx.serialization.SerialId
import
kotlinx.serialization.Serializable
import
net.mamoe.mirai.qqandroid.io.ProtoBuf
class
MsgRevokeUserDef
:
ProtoBuf
{
@Serializable
class
MsgInfoUserDef
(
@SerialId
(
1
)
val
longMessageFlag
:
Int
=
0
,
@SerialId
(
2
)
val
longMsgInfo
:
List
<
MsgInfoDef
>?
=
null
,
@SerialId
(
3
)
val
fileUuid
:
List
<
String
>
=
listOf
()
)
:
ProtoBuf
{
@Serializable
class
MsgInfoDef
(
@SerialId
(
1
)
val
msgSeq
:
Int
=
0
,
@SerialId
(
2
)
val
longMsgId
:
Int
=
0
,
@SerialId
(
3
)
val
longMsgNum
:
Int
=
0
,
@SerialId
(
4
)
val
longMsgIndex
:
Int
=
0
)
:
ProtoBuf
}
@Serializable
class
UinTypeUserDef
(
@SerialId
(
1
)
val
fromUinType
:
Int
=
0
,
@SerialId
(
2
)
val
fromGroupCode
:
Long
=
0L
,
@SerialId
(
3
)
val
fileUuid
:
List
<
String
>
=
listOf
()
)
:
ProtoBuf
}
\ No newline at end of file
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/PacketFactory.kt
View file @
587fab23
...
@@ -14,6 +14,7 @@ import kotlinx.io.pool.useInstance
...
@@ -14,6 +14,7 @@ import kotlinx.io.pool.useInstance
import
net.mamoe.mirai.data.Packet
import
net.mamoe.mirai.data.Packet
import
net.mamoe.mirai.event.Event
import
net.mamoe.mirai.event.Event
import
net.mamoe.mirai.qqandroid.QQAndroidBot
import
net.mamoe.mirai.qqandroid.QQAndroidBot
import
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.PbMessageSvc
import
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.TroopManagement
import
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.TroopManagement
import
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image.ImgStore
import
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image.ImgStore
import
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image.LongConn
import
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image.LongConn
...
@@ -138,7 +139,8 @@ internal object KnownPacketFactories {
...
@@ -138,7 +139,8 @@ internal object KnownPacketFactories {
TroopManagement
.
GetGroupInfo
,
TroopManagement
.
GetGroupInfo
,
TroopManagement
.
EditGroupNametag
,
TroopManagement
.
EditGroupNametag
,
TroopManagement
.
Kick
,
TroopManagement
.
Kick
,
Heartbeat
.
Alive
Heartbeat
.
Alive
,
PbMessageSvc
.
PbMsgWithDraw
)
)
object
IncomingFactories
:
List
<
IncomingPacketFactory
<
*
>>
by
mutableListOf
(
object
IncomingFactories
:
List
<
IncomingPacketFactory
<
*
>>
by
mutableListOf
(
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/PbMessageSvc.kt
0 → 100644
View file @
587fab23
/*
* 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.qqandroid.network.protocol.packet.chat
import
kotlinx.io.core.ByteReadPacket
import
net.mamoe.mirai.data.Packet
import
net.mamoe.mirai.qqandroid.QQAndroidBot
import
net.mamoe.mirai.qqandroid.io.serialization.readProtoBuf
import
net.mamoe.mirai.qqandroid.io.serialization.toByteArray
import
net.mamoe.mirai.qqandroid.io.serialization.writeProtoBuf
import
net.mamoe.mirai.qqandroid.network.QQAndroidClient
import
net.mamoe.mirai.qqandroid.network.protocol.data.proto.MsgRevokeUserDef
import
net.mamoe.mirai.qqandroid.network.protocol.data.proto.MsgSvc
import
net.mamoe.mirai.qqandroid.network.protocol.packet.OutgoingPacket
import
net.mamoe.mirai.qqandroid.network.protocol.packet.OutgoingPacketFactory
import
net.mamoe.mirai.qqandroid.network.protocol.packet.buildOutgoingUniPacket
internal
class
PbMessageSvc
{
object
PbMsgWithDraw
:
OutgoingPacketFactory
<
PbMsgWithDraw
.
Response
>(
"PbMessageSvc.PbMsgWithDraw"
)
{
sealed
class
Response
:
Packet
{
object
Success
:
Response
()
{
override
fun
toString
():
String
{
return
"PbMessageSvc.PbMsgWithDraw.Response.Success"
}
}
data class
Failed
(
val
result
:
Int
,
val
errorMessage
:
String
)
:
Response
()
}
// 12 1A 08 01 10 00 18 E7 C1 AD B8 02 22 0A 08 BF BA 03 10 BF 81 CB B7 03 2A 02 08 00
fun
Group
(
client
:
QQAndroidClient
,
groupCode
:
Long
,
messageSequenceId
:
Int
,
// 56639
messageRandom
:
Int
,
// 921878719
messageType
:
Int
=
0
):
OutgoingPacket
=
buildOutgoingUniPacket
(
client
)
{
writeProtoBuf
(
MsgSvc
.
PbMsgWithDrawReq
.
serializer
(),
MsgSvc
.
PbMsgWithDrawReq
(
groupWithDraw
=
listOf
(
MsgSvc
.
PbGroupMsgWithDrawReq
(
subCmd
=
1
,
groupType
=
0
,
// 普通群
groupCode
=
groupCode
,
msgList
=
listOf
(
MsgSvc
.
PbGroupMsgWithDrawReq
.
MessageInfo
(
msgSeq
=
messageSequenceId
,
msgRandom
=
messageRandom
,
msgType
=
messageType
)
),
userdef
=
MsgRevokeUserDef
.
MsgInfoUserDef
(
longMessageFlag
=
0
).
toByteArray
(
MsgRevokeUserDef
.
MsgInfoUserDef
.
serializer
())
)
)
)
)
}
override
suspend
fun
ByteReadPacket
.
decode
(
bot
:
QQAndroidBot
):
Response
{
val
resp
=
readProtoBuf
(
MsgSvc
.
PbMsgWithDrawResp
.
serializer
())
resp
.
groupWithDraw
?.
firstOrNull
()
?.
let
{
if
(
it
.
result
!=
0
)
{
return
Response
.
Failed
(
it
.
result
,
it
.
errmsg
)
}
return
Response
.
Success
}
resp
.
c2cWithDraw
?.
firstOrNull
()
?.
let
{
if
(
it
.
result
!=
0
)
{
return
Response
.
Failed
(
it
.
result
,
it
.
errmsg
)
}
return
Response
.
Success
}
return
Response
.
Failed
(-
1
,
"No response"
)
}
}
}
\ No newline at end of file
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.kt
View file @
587fab23
...
@@ -9,18 +9,25 @@
...
@@ -9,18 +9,25 @@
package
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive
package
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive
import
kotlinx.coroutines.CompletableDeferred
import
kotlinx.coroutines.ExperimentalCoroutinesApi
import
kotlinx.io.core.ByteReadPacket
import
kotlinx.io.core.ByteReadPacket
import
kotlinx.io.core.discardExact
import
kotlinx.io.core.discardExact
import
net.mamoe.mirai.contact.Contact
import
net.mamoe.mirai.contact.Group
import
net.mamoe.mirai.contact.Group
import
net.mamoe.mirai.contact.MemberPermission
import
net.mamoe.mirai.contact.MemberPermission
import
net.mamoe.mirai.data.MemberInfo
import
net.mamoe.mirai.data.MemberInfo
import
net.mamoe.mirai.data.MultiPacket
import
net.mamoe.mirai.data.MultiPacket
import
net.mamoe.mirai.data.Packet
import
net.mamoe.mirai.data.Packet
import
net.mamoe.mirai.event.ListeningStatus
import
net.mamoe.mirai.event.events.BotJoinGroupEvent
import
net.mamoe.mirai.event.events.BotJoinGroupEvent
import
net.mamoe.mirai.event.events.BotOfflineEvent
import
net.mamoe.mirai.event.events.BotOfflineEvent
import
net.mamoe.mirai.event.events.MemberJoinEvent
import
net.mamoe.mirai.event.events.MemberJoinEvent
import
net.mamoe.mirai.event.subscribe
import
net.mamoe.mirai.message.FriendMessage
import
net.mamoe.mirai.message.FriendMessage
import
net.mamoe.mirai.message.data.MessageChain
import
net.mamoe.mirai.message.data.MessageChain
import
net.mamoe.mirai.message.data.MessageSource
import
net.mamoe.mirai.message.data.addOrRemove
import
net.mamoe.mirai.qqandroid.GroupImpl
import
net.mamoe.mirai.qqandroid.GroupImpl
import
net.mamoe.mirai.qqandroid.QQAndroidBot
import
net.mamoe.mirai.qqandroid.QQAndroidBot
import
net.mamoe.mirai.qqandroid.io.serialization.decodeUniPacket
import
net.mamoe.mirai.qqandroid.io.serialization.decodeUniPacket
...
@@ -262,6 +269,36 @@ internal class MessageSvc {
...
@@ -262,6 +269,36 @@ internal class MessageSvc {
}
}
}
}
internal
class
MessageSourceFromSend
(
override
val
messageUid
:
Long
,
override
val
time
:
Long
,
override
val
senderId
:
Long
,
override
val
groupId
:
Long
,
override
val
sourceMessage
:
MessageChain
)
:
MessageSource
{
lateinit
var
sequenceIdDeferred
:
CompletableDeferred
<
Int
>
fun
startWaitingSequenceId
(
contact
:
Contact
)
{
sequenceIdDeferred
=
CompletableDeferred
()
contact
.
subscribe
<
OnlinePush
.
PbPushGroupMsg
.
SendGroupMessageReceipt
>
{
event
->
if
(
event
.
messageRandom
==
messageUid
.
toInt
())
{
sequenceIdDeferred
.
complete
(
event
.
sequenceId
)
return
@
subscribe
ListeningStatus
.
STOPPED
}
return
@
subscribe
ListeningStatus
.
LISTENING
}
}
@UseExperimental
(
ExperimentalCoroutinesApi
::
class
)
override
val
sequenceId
:
Int
get
()
=
sequenceIdDeferred
.
getCompleted
()
override
fun
toString
():
String
{
return
""
}
}
/**
/**
* 发送好友消息
* 发送好友消息
*/
*/
...
@@ -271,9 +308,17 @@ internal class MessageSvc {
...
@@ -271,9 +308,17 @@ internal class MessageSvc {
toUin
:
Long
,
toUin
:
Long
,
message
:
MessageChain
message
:
MessageChain
):
OutgoingPacket
=
buildOutgoingUniPacket
(
client
)
{
):
OutgoingPacket
=
buildOutgoingUniPacket
(
client
)
{
///writeFully("0A 08 0A 06 08 89 FC A6 8C 0B 12 06 08 01 10 00 18 00 1A 1F 0A 1D 12 08 0A 06 0A 04 F0 9F 92 A9 12 11 AA 02 0E 88 01 00 9A 01 08 78 00 F8 01 00 C8 02 00 20 9B 7A 28 F4 CA 9B B8 03 32 34 08 92 C2 C4 F1 05 10 92 C2 C4 F1 05 18 E6 ED B9 C3 02 20 89 FE BE A4 06 28 89 84 F9 A2 06 48 DE 8C EA E5 0E 58 D9 BD BB A0 09 60 1D 68 92 C2 C4 F1 05 70 00 40 01".hexToBytes())
///writeFully("0A 08 0A 06 08 89 FC A6 8C 0B 12 06 08 01 10 00 18 00 1A 1F 0A 1D 12 08 0A 06 0A 04 F0 9F 92 A9 12 11 AA 02 0E 88 01 00 9A 01 08 78 00 F8 01 00 C8 02 00 20 9B 7A 28 F4 CA 9B B8 03 32 34 08 92 C2 C4 F1 05 10 92 C2 C4 F1 05 18 E6 ED B9 C3 02 20 89 FE BE A4 06 28 89 84 F9 A2 06 48 DE 8C EA E5 0E 58 D9 BD BB A0 09 60 1D 68 92 C2 C4 F1 05 70 00 40 01".hexToBytes())
val
source
=
MessageSourceFromSend
(
messageUid
=
Random
.
nextInt
().
absoluteValue
.
toLong
()
and
0
xffffffff
,
senderId
=
client
.
uin
,
time
=
currentTimeSeconds
+
client
.
timeDifference
,
groupId
=
0
,
sourceMessage
=
message
)
message
.
addOrRemove
(
source
)
///return@buildOutgoingUniPacket
///return@buildOutgoingUniPacket
writeProtoBuf
(
writeProtoBuf
(
MsgSvc
.
PbSendMsgReq
.
serializer
(),
MsgSvc
.
PbSendMsgReq
(
MsgSvc
.
PbSendMsgReq
.
serializer
(),
MsgSvc
.
PbSendMsgReq
(
...
@@ -285,8 +330,8 @@ internal class MessageSvc {
...
@@ -285,8 +330,8 @@ internal class MessageSvc {
)
)
),
),
msgSeq
=
client
.
atomicNextMessageSequenceId
(),
msgSeq
=
client
.
atomicNextMessageSequenceId
(),
msgRand
=
Random
.
nextInt
().
absoluteValue
,
msgRand
=
source
.
messageUid
.
toInt
()
,
syncCookie
=
SyncCookie
(
time
=
currentTimeSeconds
).
toByteArray
(
SyncCookie
.
serializer
())
syncCookie
=
SyncCookie
(
time
=
source
.
time
).
toByteArray
(
SyncCookie
.
serializer
())
// msgVia = 1
// msgVia = 1
)
)
)
)
...
@@ -302,11 +347,19 @@ internal class MessageSvc {
...
@@ -302,11 +347,19 @@ internal class MessageSvc {
message
:
MessageChain
message
:
MessageChain
):
OutgoingPacket
=
buildOutgoingUniPacket
(
client
)
{
):
OutgoingPacket
=
buildOutgoingUniPacket
(
client
)
{
val
source
=
MessageSourceFromSend
(
messageUid
=
Random
.
nextInt
().
absoluteValue
.
toLong
()
and
0
xffffffff
,
senderId
=
client
.
uin
,
time
=
currentTimeSeconds
+
client
.
timeDifference
,
groupId
=
groupCode
,
sourceMessage
=
message
)
message
.
addOrRemove
(
source
)
///writeFully("0A 08 0A 06 08 89 FC A6 8C 0B 12 06 08 01 10 00 18 00 1A 1F 0A 1D 12 08 0A 06 0A 04 F0 9F 92 A9 12 11 AA 02 0E 88 01 00 9A 01 08 78 00 F8 01 00 C8 02 00 20 9B 7A 28 F4 CA 9B B8 03 32 34 08 92 C2 C4 F1 05 10 92 C2 C4 F1 05 18 E6 ED B9 C3 02 20 89 FE BE A4 06 28 89 84 F9 A2 06 48 DE 8C EA E5 0E 58 D9 BD BB A0 09 60 1D 68 92 C2 C4 F1 05 70 00 40 01".hexToBytes())
///writeFully("0A 08 0A 06 08 89 FC A6 8C 0B 12 06 08 01 10 00 18 00 1A 1F 0A 1D 12 08 0A 06 0A 04 F0 9F 92 A9 12 11 AA 02 0E 88 01 00 9A 01 08 78 00 F8 01 00 C8 02 00 20 9B 7A 28 F4 CA 9B B8 03 32 34 08 92 C2 C4 F1 05 10 92 C2 C4 F1 05 18 E6 ED B9 C3 02 20 89 FE BE A4 06 28 89 84 F9 A2 06 48 DE 8C EA E5 0E 58 D9 BD BB A0 09 60 1D 68 92 C2 C4 F1 05 70 00 40 01".hexToBytes())
// DebugLogger.debug("sending group message: " + message.toRichTextElems().contentToString())
// DebugLogger.debug("sending group message: " + message.toRichTextElems().contentToString())
val
seq
=
client
.
atomicNextMessageSequenceId
()
///return@buildOutgoingUniPacket
///return@buildOutgoingUniPacket
writeProtoBuf
(
writeProtoBuf
(
MsgSvc
.
PbSendMsgReq
.
serializer
(),
MsgSvc
.
PbSendMsgReq
(
MsgSvc
.
PbSendMsgReq
.
serializer
(),
MsgSvc
.
PbSendMsgReq
(
...
@@ -317,8 +370,8 @@ internal class MessageSvc {
...
@@ -317,8 +370,8 @@ internal class MessageSvc {
elems
=
message
.
toRichTextElems
()
elems
=
message
.
toRichTextElems
()
)
)
),
),
msgSeq
=
seq
,
msgSeq
=
client
.
atomicNextMessageSequenceId
()
,
msgRand
=
Random
.
nextInt
().
absoluteValue
,
msgRand
=
source
.
messageUid
.
toInt
()
,
syncCookie
=
EMPTY_BYTE_ARRAY
,
syncCookie
=
EMPTY_BYTE_ARRAY
,
msgVia
=
1
msgVia
=
1
)
)
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/OnlinePush.kt
View file @
587fab23
...
@@ -19,6 +19,7 @@ import net.mamoe.mirai.contact.MemberPermission
...
@@ -19,6 +19,7 @@ import net.mamoe.mirai.contact.MemberPermission
import
net.mamoe.mirai.data.MultiPacket
import
net.mamoe.mirai.data.MultiPacket
import
net.mamoe.mirai.data.NoPacket
import
net.mamoe.mirai.data.NoPacket
import
net.mamoe.mirai.data.Packet
import
net.mamoe.mirai.data.Packet
import
net.mamoe.mirai.event.Event
import
net.mamoe.mirai.event.events.*
import
net.mamoe.mirai.event.events.*
import
net.mamoe.mirai.message.GroupMessage
import
net.mamoe.mirai.message.GroupMessage
import
net.mamoe.mirai.qqandroid.GroupImpl
import
net.mamoe.mirai.qqandroid.GroupImpl
...
@@ -46,9 +47,14 @@ internal class OnlinePush {
...
@@ -46,9 +47,14 @@ internal class OnlinePush {
/**
/**
* 接受群消息
* 接受群消息
*/
*/
internal
object
PbPushGroupMsg
:
IncomingPacketFactory
<
GroupMessage
?
>(
"OnlinePush.PbPushGroupMsg"
)
{
internal
object
PbPushGroupMsg
:
IncomingPacketFactory
<
Packet
?
>(
"OnlinePush.PbPushGroupMsg"
)
{
internal
class
SendGroupMessageReceipt
(
val
messageRandom
:
Int
,
val
sequenceId
:
Int
)
:
Packet
,
Event
@UseExperimental
(
ExperimentalStdlibApi
::
class
)
@UseExperimental
(
ExperimentalStdlibApi
::
class
)
override
suspend
fun
ByteReadPacket
.
decode
(
bot
:
QQAndroidBot
,
sequenceId
:
Int
):
GroupMessage
?
{
override
suspend
fun
ByteReadPacket
.
decode
(
bot
:
QQAndroidBot
,
sequenceId
:
Int
):
Packet
?
{
// 00 00 02 E4 0A D5 05 0A 4F 08 A2 FF 8C F0 03 10 DD F1 92 B7 07 18 52 20 00 28 BC 3D 30 8C 82 AB F1 05 38 D2 80 E0 8C 80 80 80 80 02 4A 21 08 E7 C1 AD B8 02 10 01 18 BA 05 22 09 48 69 6D 31 38 38 6D 6F 65 30 06 38 02 42 05 4D 69 72 61 69 50 01 58 01 60 00 88 01 08 12 06 08 01 10 00 18 00 1A F9 04 0A F6 04 0A 26 08 00 10 87 82 AB F1 05 18 B7 B4 BF 30 20 00 28 0C 30 00 38 86 01 40 22 4A 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91 12 E6 03 42 E3 03 12 2A 7B 34 45 31 38 35 38 32 32 2D 30 45 37 42 2D 46 38 30 46 2D 43 35 42 31 2D 33 34 34 38 38 33 37 34 44 33 39 43 7D 2E 6A 70 67 22 00 2A 04 03 00 00 00 32 60 15 36 20 39 36 6B 45 31 41 38 35 32 32 39 64 63 36 39 38 34 37 39 37 37 62 20 20 20 20 20 20 35 30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 7B 34 45 31 38 35 38 32 32 2D 30 45 37 42 2D 46 38 30 46 2D 43 35 42 31 2D 33 34 34 38 38 33 37 34 44 33 39 43 7D 2E 6A 70 67 31 32 31 32 41 38 C6 BB 8A A9 08 40 FB AE 9E C2 09 48 50 50 41 5A 00 60 01 6A 10 4E 18 58 22 0E 7B F8 0F C5 B1 34 48 83 74 D3 9C 72 59 2F 67 63 68 61 74 70 69 63 5F 6E 65 77 2F 31 30 34 30 34 30 30 32 39 30 2F 36 35 35 30 35 37 31 32 37 2D 32 32 33 33 36 33 38 33 34 32 2D 34 45 31 38 35 38 32 32 30 45 37 42 46 38 30 46 43 35 42 31 33 34 34 38 38 33 37 34 44 33 39 43 2F 31 39 38 3F 74 65 72 6D 3D 32 82 01 57 2F 67 63 68 61 74 70 69 63 5F 6E 65 77 2F 31 30 34 30 34 30 30 32 39 30 2F 36 35 35 30 35 37 31 32 37 2D 32 32 33 33 36 33 38 33 34 32 2D 34 45 31 38 35 38 32 32 30 45 37 42 46 38 30 46 43 35 42 31 33 34 34 38 38 33 37 34 44 33 39 43 2F 30 3F 74 65 72 6D 3D 32 B0 01 4D B8 01 2E C8 01 FF 05 D8 01 4D E0 01 2E FA 01 59 2F 67 63 68 61 74 70 69 63 5F 6E 65 77 2F 31 30 34 30 34 30 30 32 39 30 2F 36 35 35 30 35 37 31 32 37 2D 32 32 33 33 36 33 38 33 34 32 2D 34 45 31 38 35 38 32 32 30 45 37 42 46 38 30 46 43 35 42 31 33 34 34 38 38 33 37 34 44 33 39 43 2F 34 30 30 3F 74 65 72 6D 3D 32 80 02 4D 88 02 2E 12 45 AA 02 42 50 03 60 00 68 00 9A 01 39 08 09 20 BF 50 80 01 01 C8 01 00 F0 01 00 F8 01 00 90 02 00 98 03 00 A0 03 20 B0 03 00 C0 03 00 D0 03 00 E8 03 00 8A 04 04 08 02 08 01 90 04 80 80 80 10 B8 04 00 C0 04 00 12 06 4A 04 08 00 40 01 12 14 82 01 11 0A 09 48 69 6D 31 38 38 6D 6F 65 18 06 20 08 28 03 10 8A CA 9D A1 07 1A 00
// 00 00 02 E4 0A D5 05 0A 4F 08 A2 FF 8C F0 03 10 DD F1 92 B7 07 18 52 20 00 28 BC 3D 30 8C 82 AB F1 05 38 D2 80 E0 8C 80 80 80 80 02 4A 21 08 E7 C1 AD B8 02 10 01 18 BA 05 22 09 48 69 6D 31 38 38 6D 6F 65 30 06 38 02 42 05 4D 69 72 61 69 50 01 58 01 60 00 88 01 08 12 06 08 01 10 00 18 00 1A F9 04 0A F6 04 0A 26 08 00 10 87 82 AB F1 05 18 B7 B4 BF 30 20 00 28 0C 30 00 38 86 01 40 22 4A 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91 12 E6 03 42 E3 03 12 2A 7B 34 45 31 38 35 38 32 32 2D 30 45 37 42 2D 46 38 30 46 2D 43 35 42 31 2D 33 34 34 38 38 33 37 34 44 33 39 43 7D 2E 6A 70 67 22 00 2A 04 03 00 00 00 32 60 15 36 20 39 36 6B 45 31 41 38 35 32 32 39 64 63 36 39 38 34 37 39 37 37 62 20 20 20 20 20 20 35 30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 7B 34 45 31 38 35 38 32 32 2D 30 45 37 42 2D 46 38 30 46 2D 43 35 42 31 2D 33 34 34 38 38 33 37 34 44 33 39 43 7D 2E 6A 70 67 31 32 31 32 41 38 C6 BB 8A A9 08 40 FB AE 9E C2 09 48 50 50 41 5A 00 60 01 6A 10 4E 18 58 22 0E 7B F8 0F C5 B1 34 48 83 74 D3 9C 72 59 2F 67 63 68 61 74 70 69 63 5F 6E 65 77 2F 31 30 34 30 34 30 30 32 39 30 2F 36 35 35 30 35 37 31 32 37 2D 32 32 33 33 36 33 38 33 34 32 2D 34 45 31 38 35 38 32 32 30 45 37 42 46 38 30 46 43 35 42 31 33 34 34 38 38 33 37 34 44 33 39 43 2F 31 39 38 3F 74 65 72 6D 3D 32 82 01 57 2F 67 63 68 61 74 70 69 63 5F 6E 65 77 2F 31 30 34 30 34 30 30 32 39 30 2F 36 35 35 30 35 37 31 32 37 2D 32 32 33 33 36 33 38 33 34 32 2D 34 45 31 38 35 38 32 32 30 45 37 42 46 38 30 46 43 35 42 31 33 34 34 38 38 33 37 34 44 33 39 43 2F 30 3F 74 65 72 6D 3D 32 B0 01 4D B8 01 2E C8 01 FF 05 D8 01 4D E0 01 2E FA 01 59 2F 67 63 68 61 74 70 69 63 5F 6E 65 77 2F 31 30 34 30 34 30 30 32 39 30 2F 36 35 35 30 35 37 31 32 37 2D 32 32 33 33 36 33 38 33 34 32 2D 34 45 31 38 35 38 32 32 30 45 37 42 46 38 30 46 43 35 42 31 33 34 34 38 38 33 37 34 44 33 39 43 2F 34 30 30 3F 74 65 72 6D 3D 32 80 02 4D 88 02 2E 12 45 AA 02 42 50 03 60 00 68 00 9A 01 39 08 09 20 BF 50 80 01 01 C8 01 00 F0 01 00 F8 01 00 90 02 00 98 03 00 A0 03 20 B0 03 00 C0 03 00 D0 03 00 E8 03 00 8A 04 04 08 02 08 01 90 04 80 80 80 10 B8 04 00 C0 04 00 12 06 4A 04 08 00 40 01 12 14 82 01 11 0A 09 48 69 6D 31 38 38 6D 6F 65 18 06 20 08 28 03 10 8A CA 9D A1 07 1A 00
if
(!
bot
.
firstLoginSucceed
)
return
null
if
(!
bot
.
firstLoginSucceed
)
return
null
val
pbPushMsg
=
readProtoBuf
(
MsgOnlinePush
.
PbPushMsg
.
serializer
())
val
pbPushMsg
=
readProtoBuf
(
MsgOnlinePush
.
PbPushMsg
.
serializer
())
...
@@ -56,7 +62,7 @@ internal class OnlinePush {
...
@@ -56,7 +62,7 @@ internal class OnlinePush {
val
extraInfo
:
ImMsgBody
.
ExtraInfo
?
=
pbPushMsg
.
msg
.
msgBody
.
richText
.
elems
.
firstOrNull
{
it
.
extraInfo
!=
null
}
?.
extraInfo
val
extraInfo
:
ImMsgBody
.
ExtraInfo
?
=
pbPushMsg
.
msg
.
msgBody
.
richText
.
elems
.
firstOrNull
{
it
.
extraInfo
!=
null
}
?.
extraInfo
if
(
pbPushMsg
.
msg
.
msgHead
.
fromUin
==
bot
.
uin
)
{
if
(
pbPushMsg
.
msg
.
msgHead
.
fromUin
==
bot
.
uin
)
{
return
null
return
SendGroupMessageReceipt
(
pbPushMsg
.
msg
.
msgBody
.
richText
.
attr
!!
.
random
,
pbPushMsg
.
msg
.
msgHead
.
msgSeq
)
}
}
val
group
=
bot
.
getGroup
(
pbPushMsg
.
msg
.
msgHead
.
groupInfo
!!
.
groupCode
)
val
group
=
bot
.
getGroup
(
pbPushMsg
.
msg
.
msgHead
.
groupInfo
!!
.
groupCode
)
...
...
mirai-core-qqandroid/src/jvmTest/kotlin/androidPacketTests/clientToServer.kt
View file @
587fab23
...
@@ -107,6 +107,8 @@ fun main() {
...
@@ -107,6 +107,8 @@ fun main() {
* 顶层方法. TCP 切掉头后直接来这里
* 顶层方法. TCP 切掉头后直接来这里
*/
*/
fun
ByteReadPacket
.
decodeMultiClientToServerPackets
()
{
fun
ByteReadPacket
.
decodeMultiClientToServerPackets
()
{
DebugLogger
.
enable
()
PacketLogger
.
enable
()
println
(
"=======================处理客户端到服务器======================="
)
println
(
"=======================处理客户端到服务器======================="
)
var
count
=
0
var
count
=
0
while
(
remaining
!=
0L
)
{
while
(
remaining
!=
0L
)
{
...
...
mirai-core-qqandroid/src/jvmTest/kotlin/test/ProtoBufDataClassGenerator.kt
View file @
587fab23
...
@@ -25,7 +25,7 @@ fun main() {
...
@@ -25,7 +25,7 @@ fun main() {
println
(
println
(
File
(
File
(
"""
"""
E:\Projects\QQAndroidFF\app\src\main\java\tencent\im\
statsvc\getonlin
e
E:\Projects\QQAndroidFF\app\src\main\java\tencent\im\
msgrevok
e
"""
.
trimIndent
()
"""
.
trimIndent
()
)
)
.
generateUnarrangedClasses
().
toMutableList
().
arrangeClasses
().
joinToString
(
"\n\n"
)
.
generateUnarrangedClasses
().
toMutableList
().
arrangeClasses
().
joinToString
(
"\n\n"
)
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt
View file @
587fab23
...
@@ -84,7 +84,7 @@ abstract class Bot : CoroutineScope {
...
@@ -84,7 +84,7 @@ abstract class Bot : CoroutineScope {
*/
*/
@MiraiExperimentalAPI
(
"还未支持"
)
@MiraiExperimentalAPI
(
"还未支持"
)
val
nick
:
String
val
nick
:
String
get
()
=
TODO
(
"bot 昵称获取"
)
get
()
=
""
//
TODO("bot 昵称获取")
/**
/**
* 日志记录器
* 日志记录器
...
@@ -175,8 +175,6 @@ abstract class Bot : CoroutineScope {
...
@@ -175,8 +175,6 @@ abstract class Bot : CoroutineScope {
*/
*/
abstract
suspend
fun
queryGroupMemberList
(
groupUin
:
Long
,
groupCode
:
Long
,
ownerId
:
Long
):
Sequence
<
MemberInfo
>
abstract
suspend
fun
queryGroupMemberList
(
groupUin
:
Long
,
groupCode
:
Long
,
ownerId
:
Long
):
Sequence
<
MemberInfo
>
// TODO 目前还不能构造群对象. 这将在以后支持
// endregion
// endregion
// region network
// region network
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt
View file @
587fab23
...
@@ -18,6 +18,7 @@ import net.mamoe.mirai.event.events.EventCancelledException
...
@@ -18,6 +18,7 @@ import net.mamoe.mirai.event.events.EventCancelledException
import
net.mamoe.mirai.event.events.ImageUploadEvent
import
net.mamoe.mirai.event.events.ImageUploadEvent
import
net.mamoe.mirai.event.events.MessageSendEvent.FriendMessageSendEvent
import
net.mamoe.mirai.event.events.MessageSendEvent.FriendMessageSendEvent
import
net.mamoe.mirai.event.events.MessageSendEvent.GroupMessageSendEvent
import
net.mamoe.mirai.event.events.MessageSendEvent.GroupMessageSendEvent
import
net.mamoe.mirai.message.MessageReceipt
import
net.mamoe.mirai.message.data.*
import
net.mamoe.mirai.message.data.*
import
net.mamoe.mirai.utils.ExternalImage
import
net.mamoe.mirai.utils.ExternalImage
import
net.mamoe.mirai.utils.WeakRefProperty
import
net.mamoe.mirai.utils.WeakRefProperty
...
@@ -40,19 +41,24 @@ interface Contact : CoroutineScope {
...
@@ -40,19 +41,24 @@ interface Contact : CoroutineScope {
*
*
* 对于 [QQ], `uin` 与 `id` 是相同的意思.
* 对于 [QQ], `uin` 与 `id` 是相同的意思.
* 对于 [Group], `groupCode` 与 `id` 是相同的意思.
* 对于 [Group], `groupCode` 与 `id` 是相同的意思.
*
* @see QQ.id
* @see Group.id
*/
*/
val
id
:
Long
val
id
:
Long
/**
/**
* 向这个对象发送消息.
* 向这个对象发送消息.
发送成功后 [message] 中会添加 [MessageSource], 此后可以 [引用回复][MessageReceipt.quote](仅群聊)或 [撤回][MessageReceipt.recall] 这条消息.
*
*
* @see FriendMessageSendEvent 发送好友信息事件, cancellable
* @see FriendMessageSendEvent 发送好友信息事件, cancellable
* @see GroupMessageSendEvent 发送群消息事件. cancellable
* @see GroupMessageSendEvent 发送群消息事件. cancellable
*
*
* @throws EventCancelledException 当发送消息事件被取消
* @throws EventCancelledException 当发送消息事件被取消
* @throws IllegalStateException 发送群消息时若 [Bot] 被禁言抛出
* @throws IllegalStateException 发送群消息时若 [Bot] 被禁言抛出
*
* @return 消息回执. 可 [引用回复][MessageReceipt.quote](仅群聊)或 [撤回][MessageReceipt.recall] 这条消息.
*/
*/
suspend
fun
sendMessage
(
message
:
MessageChain
)
suspend
fun
sendMessage
(
message
:
MessageChain
)
:
MessageReceipt
<
out
Contact
>
/**
/**
* 上传一个图片以备发送.
* 上传一个图片以备发送.
...
@@ -88,4 +94,4 @@ interface Contact : CoroutineScope {
...
@@ -88,4 +94,4 @@ interface Contact : CoroutineScope {
suspend
inline
fun
Contact
.
sendMessage
(
message
:
Message
)
=
sendMessage
(
message
.
toChain
())
suspend
inline
fun
Contact
.
sendMessage
(
message
:
Message
)
=
sendMessage
(
message
.
toChain
())
suspend
inline
fun
Contact
.
sendMessage
(
plain
:
String
)
=
sendMessage
(
plain
.
singleChain
())
suspend
inline
fun
Contact
.
sendMessage
(
plain
:
String
)
=
sendMessage
(
plain
.
toMessage
())
\ No newline at end of file
\ No newline at end of file
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Group.kt
View file @
587fab23
...
@@ -11,11 +11,22 @@
...
@@ -11,11 +11,22 @@
package
net.mamoe.mirai.contact
package
net.mamoe.mirai.contact
import
kotlinx.coroutines.CoroutineName
import
kotlinx.coroutines.CoroutineScope
import
kotlinx.coroutines.CoroutineScope
import
kotlinx.coroutines.Job
import
kotlinx.coroutines.launch
import
net.mamoe.mirai.Bot
import
net.mamoe.mirai.Bot
import
net.mamoe.mirai.data.MemberInfo
import
net.mamoe.mirai.data.MemberInfo
import
net.mamoe.mirai.event.events.*
import
net.mamoe.mirai.event.events.*
import
net.mamoe.mirai.event.events.MessageSendEvent.FriendMessageSendEvent
import
net.mamoe.mirai.event.events.MessageSendEvent.GroupMessageSendEvent
import
net.mamoe.mirai.message.MessageReceipt
import
net.mamoe.mirai.message.data.MessageChain
import
net.mamoe.mirai.message.data.MessageSource
import
net.mamoe.mirai.message.data.quote
import
net.mamoe.mirai.utils.MiraiExperimentalAPI
import
net.mamoe.mirai.utils.MiraiExperimentalAPI
import
kotlin.coroutines.CoroutineContext
import
kotlin.coroutines.EmptyCoroutineContext
import
kotlin.jvm.JvmName
import
kotlin.jvm.JvmName
/**
/**
...
@@ -83,10 +94,18 @@ interface Group : Contact, CoroutineScope {
...
@@ -83,10 +94,18 @@ interface Group : Contact, CoroutineScope {
override
val
id
:
Long
override
val
id
:
Long
/**
/**
* 群主
* 群主.
*
* @return 若机器人是群主, 返回 [botAsMember]. 否则返回相应的成员
*/
*/
val
owner
:
Member
val
owner
:
Member
/**
* [Bot] 在群内的 [Member] 实例
*/
@MiraiExperimentalAPI
val
botAsMember
:
Member
/**
/**
* 机器人被禁言还剩余多少秒
* 机器人被禁言还剩余多少秒
*
*
...
@@ -133,6 +152,17 @@ interface Group : Contact, CoroutineScope {
...
@@ -133,6 +152,17 @@ interface Group : Contact, CoroutineScope {
@MiraiExperimentalAPI
(
"还未支持"
)
@MiraiExperimentalAPI
(
"还未支持"
)
suspend
fun
quit
():
Boolean
suspend
fun
quit
():
Boolean
/**
* 撤回这条消息.
*
* [Bot] 撤回自己的消息不需要权限.
* [Bot] 撤回群员的消息需要管理员权限.
*
* @throws PermissionDeniedException 当 [Bot] 无权限操作时
* @see Group.recall (扩展函数) 接受参数 [MessageChain]
*/
suspend
fun
recall
(
source
:
MessageSource
)
/**
/**
* 构造一个 [Member].
* 构造一个 [Member].
* 非特殊情况请不要使用这个函数. 优先使用 [get].
* 非特殊情况请不要使用这个函数. 优先使用 [get].
...
@@ -142,6 +172,19 @@ interface Group : Contact, CoroutineScope {
...
@@ -142,6 +172,19 @@ interface Group : Contact, CoroutineScope {
@JvmName
(
"newMember"
)
@JvmName
(
"newMember"
)
fun
Member
(
memberInfo
:
MemberInfo
):
Member
fun
Member
(
memberInfo
:
MemberInfo
):
Member
/**
* 向这个对象发送消息. 发送成功后 [message] 中会添加 [MessageSource], 此后可以 [引用回复][quote] 或 [撤回][recall] 这条消息.
*
* @see FriendMessageSendEvent 发送好友信息事件, cancellable
* @see GroupMessageSendEvent 发送群消息事件. cancellable
*
* @throws EventCancelledException 当发送消息事件被取消
* @throws IllegalStateException 发送群消息时若 [Bot] 被禁言抛出
*
* @return 消息回执. 可进行撤回 ([MessageReceipt.recall])
*/
override
suspend
fun
sendMessage
(
message
:
MessageChain
):
MessageReceipt
<
Group
>
companion
object
{
companion
object
{
/**
/**
...
@@ -184,7 +227,52 @@ interface Group : Contact, CoroutineScope {
...
@@ -184,7 +227,52 @@ interface Group : Contact, CoroutineScope {
fun
toFullString
():
String
=
"Group(id=${this.id}, name=$name, owner=${owner.id}, members=${members.idContentString})"
fun
toFullString
():
String
=
"Group(id=${this.id}, name=$name, owner=${owner.id}, members=${members.idContentString})"
}
}
/**
* 撤回这条消息.
*
* [Bot] 撤回自己的消息不需要权限.
* [Bot] 撤回群员的消息需要管理员权限.
*
* @throws PermissionDeniedException 当 [Bot] 无权限操作时
* @see Group.recall
*/
suspend
inline
fun
Group
.
recall
(
message
:
MessageChain
)
=
this
.
recall
(
message
[
MessageSource
])
/**
* 在一段时间后撤回这条消息.
*
* @param delay 延迟的时间, 单位为毫秒
* @param coroutineContext 额外的 [CoroutineContext]
* @see recall
*/
fun
Group
.
recallIn
(
message
:
MessageSource
,
delay
:
Long
,
coroutineContext
:
CoroutineContext
=
EmptyCoroutineContext
):
Job
=
this
.
launch
(
coroutineContext
+
CoroutineName
(
"MessageRecall"
))
{
kotlinx
.
coroutines
.
delay
(
delay
)
recall
(
message
)
}
/**
* 在一段时间后撤回这条消息.
*
* @param delay 延迟的时间, 单位为毫秒
* @param coroutineContext 额外的 [CoroutineContext]
* @see recall
*/
fun
Group
.
recallIn
(
message
:
MessageChain
,
delay
:
Long
,
coroutineContext
:
CoroutineContext
=
EmptyCoroutineContext
):
Job
=
this
.
launch
(
coroutineContext
+
CoroutineName
(
"MessageRecall"
))
{
kotlinx
.
coroutines
.
delay
(
delay
)
recall
(
message
)
}
/**
/**
* 返回机器人是否正在被禁言
* 返回机器人是否正在被禁言
*
* @see Group.botMuteRemaining 剩余禁言时间
*/
*/
val
Group
.
isBotMuted
:
Boolean
get
()
=
this
.
botMuteRemaining
!=
0
val
Group
.
isBotMuted
:
Boolean
get
()
=
this
.
botMuteRemaining
!=
0
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/QQ.kt
View file @
587fab23
...
@@ -16,6 +16,12 @@ import net.mamoe.mirai.Bot
...
@@ -16,6 +16,12 @@ import net.mamoe.mirai.Bot
import
net.mamoe.mirai.data.FriendNameRemark
import
net.mamoe.mirai.data.FriendNameRemark
import
net.mamoe.mirai.data.PreviousNameList
import
net.mamoe.mirai.data.PreviousNameList
import
net.mamoe.mirai.data.Profile
import
net.mamoe.mirai.data.Profile
import
net.mamoe.mirai.event.events.EventCancelledException
import
net.mamoe.mirai.event.events.MessageSendEvent.FriendMessageSendEvent
import
net.mamoe.mirai.event.events.MessageSendEvent.GroupMessageSendEvent
import
net.mamoe.mirai.message.MessageReceipt
import
net.mamoe.mirai.message.data.MessageChain
import
net.mamoe.mirai.message.data.MessageSource
import
net.mamoe.mirai.utils.MiraiExperimentalAPI
import
net.mamoe.mirai.utils.MiraiExperimentalAPI
/**
/**
...
@@ -68,4 +74,17 @@ interface QQ : Contact, CoroutineScope {
...
@@ -68,4 +74,17 @@ interface QQ : Contact, CoroutineScope {
*/
*/
@MiraiExperimentalAPI
(
"还未支持"
)
@MiraiExperimentalAPI
(
"还未支持"
)
suspend
fun
queryRemark
():
FriendNameRemark
suspend
fun
queryRemark
():
FriendNameRemark
/**
* 向这个对象发送消息. 发送成功后 [message] 中会添加 [MessageSource], 此后可以 [撤回][recall] 这条消息.
*
* @see FriendMessageSendEvent 发送好友信息事件, cancellable
* @see GroupMessageSendEvent 发送群消息事件. cancellable
*
* @throws EventCancelledException 当发送消息事件被取消
* @throws IllegalStateException 发送群消息时若 [Bot] 被禁言抛出
*
* @return 消息回执. 可进行撤回 ([MessageReceipt.recall])
*/
override
suspend
fun
sendMessage
(
message
:
MessageChain
):
MessageReceipt
<
QQ
>
}
}
\ No newline at end of file
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/data/GroupInfo.kt
View file @
587fab23
...
@@ -62,4 +62,15 @@ interface GroupInfo {
...
@@ -62,4 +62,15 @@ interface GroupInfo {
* 机器人被禁言还剩时间, 秒.
* 机器人被禁言还剩时间, 秒.
*/
*/
val
botMuteRemaining
:
Int
val
botMuteRemaining
:
Int
/*
/**
* 机器人的头衔
*/
val botSpecialTitle: String
/**
* 机器人的昵称
*/
val botNameCard: String*/
}
}
\ No newline at end of file
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/
Subscribable
.kt
→
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/
Event
.kt
View file @
587fab23
File moved
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/linear.kt
0 → 100644
View file @
587fab23
/*
* 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
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/
MessageSubscriber
s.kt
→
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/
subscribeMessage
s.kt
View file @
587fab23
File moved
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/
Subscribers
.kt
→
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/
subscriber
.kt
View file @
587fab23
File moved
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/GroupMessage.kt
View file @
587fab23
...
@@ -10,12 +10,11 @@
...
@@ -10,12 +10,11 @@
package
net.mamoe.mirai.message
package
net.mamoe.mirai.message
import
net.mamoe.mirai.Bot
import
net.mamoe.mirai.Bot
import
net.mamoe.mirai.contact.Group
import
net.mamoe.mirai.contact.*
import
net.mamoe.mirai.contact.Member
import
net.mamoe.mirai.contact.MemberPermission
import
net.mamoe.mirai.event.Event
import
net.mamoe.mirai.event.Event
import
net.mamoe.mirai.message.data.Message
import
net.mamoe.mirai.message.data.Message
import
net.mamoe.mirai.message.data.MessageChain
import
net.mamoe.mirai.message.data.MessageChain
import
net.mamoe.mirai.message.data.MessageSource
import
net.mamoe.mirai.utils.getValue
import
net.mamoe.mirai.utils.getValue
import
net.mamoe.mirai.utils.unsafeWeakRef
import
net.mamoe.mirai.utils.unsafeWeakRef
import
kotlin.jvm.JvmName
import
kotlin.jvm.JvmName
...
@@ -60,6 +59,11 @@ class GroupMessage(
...
@@ -60,6 +59,11 @@ class GroupMessage(
@JvmName
(
"reply2"
)
@JvmName
(
"reply2"
)
suspend
inline
fun
MessageChain
.
quoteReply
()
=
quoteReply
(
this
)
suspend
inline
fun
MessageChain
.
quoteReply
()
=
quoteReply
(
this
)
suspend
inline
fun
MessageChain
.
recall
()
=
group
.
recall
(
this
)
suspend
inline
fun
MessageSource
.
recall
()
=
group
.
recall
(
this
)
inline
fun
MessageSource
.
recallIn
(
delay
:
Long
)
=
group
.
recallIn
(
this
,
delay
)
inline
fun
MessageChain
.
recallIn
(
delay
:
Long
)
=
group
.
recallIn
(
this
,
delay
)
override
fun
toString
():
String
=
override
fun
toString
():
String
=
"GroupMessage(group=${group.id}, senderName=$senderName, sender=${sender.id}, permission=${permission.name}, message=$message)"
"GroupMessage(group=${group.id}, senderName=$senderName, sender=${sender.id}, permission=${permission.name}, message=$message)"
}
}
\ No newline at end of file
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/MessagePacket.kt
View file @
587fab23
...
@@ -35,7 +35,7 @@ expect abstract class MessagePacket<TSender : QQ, TSubject : Contact>(bot: Bot)
...
@@ -35,7 +35,7 @@ expect abstract class MessagePacket<TSender : QQ, TSubject : Contact>(bot: Bot)
/**
/**
* 仅内部使用, 请使用 [MessagePacket]
* 仅内部使用, 请使用 [MessagePacket]
*/
// Tips: 在 IntelliJ 中 (左侧边栏) 打开 `Structure`, 可查看类结构
*/
// Tips: 在 IntelliJ 中 (左侧边栏) 打开 `Structure`, 可查看类结构
@Suppress
(
"NOTHING_TO_INLINE"
)
@Suppress
(
"NOTHING_TO_INLINE"
,
"UNCHECKED_CAST"
)
@MiraiInternalAPI
@MiraiInternalAPI
abstract
class
MessagePacketBase
<
TSender
:
QQ
,
TSubject
:
Contact
>(
_bot
:
Bot
)
:
Packet
,
BotEvent
{
abstract
class
MessagePacketBase
<
TSender
:
QQ
,
TSubject
:
Contact
>(
_bot
:
Bot
)
:
Packet
,
BotEvent
{
/**
/**
...
@@ -73,20 +73,19 @@ abstract class MessagePacketBase<TSender : QQ, TSubject : Contact>(_bot: Bot) :
...
@@ -73,20 +73,19 @@ abstract class MessagePacketBase<TSender : QQ, TSubject : Contact>(_bot: Bot) :
* 对于好友消息事件, 这个方法将会给好友 ([subject]) 发送消息
* 对于好友消息事件, 这个方法将会给好友 ([subject]) 发送消息
* 对于群消息事件, 这个方法将会给群 ([subject]) 发送消息
* 对于群消息事件, 这个方法将会给群 ([subject]) 发送消息
*/
*/
suspend
inline
fun
reply
(
message
:
MessageChain
)
=
subject
.
sendMessage
(
message
)
suspend
inline
fun
reply
(
message
:
MessageChain
)
:
MessageReceipt
<
TSubject
>
=
subject
.
sendMessage
(
message
)
as
MessageReceipt
<
TSubject
>
suspend
inline
fun
reply
(
message
:
Message
)
=
subject
.
sendMessage
(
message
.
toChain
())
suspend
inline
fun
reply
(
message
:
Message
)
:
MessageReceipt
<
TSubject
>
=
subject
.
sendMessage
(
message
.
toChain
())
as
MessageReceipt
<
TSubject
>
suspend
inline
fun
reply
(
plain
:
String
)
=
subject
.
sendMessage
(
plain
.
singleChain
())
suspend
inline
fun
reply
(
plain
:
String
)
:
MessageReceipt
<
TSubject
>
=
subject
.
sendMessage
(
plain
.
toMessage
().
toChain
())
as
MessageReceipt
<
TSubject
>
@JvmName
(
"reply1"
)
@JvmName
(
"reply1"
)
suspend
inline
fun
String
.
reply
()
=
reply
(
this
)
suspend
inline
fun
String
.
reply
()
:
MessageReceipt
<
TSubject
>
=
reply
(
this
)
@JvmName
(
"reply1"
)
@JvmName
(
"reply1"
)
suspend
inline
fun
Message
.
reply
()
=
reply
(
this
)
suspend
inline
fun
Message
.
reply
()
:
MessageReceipt
<
TSubject
>
=
reply
(
this
)
@JvmName
(
"reply1"
)
@JvmName
(
"reply1"
)
suspend
inline
fun
MessageChain
.
reply
()
=
reply
(
this
)
suspend
inline
fun
MessageChain
.
reply
():
MessageReceipt
<
TSubject
>
=
reply
(
this
)
// endregion
// endregion
// region
// region
...
@@ -135,16 +134,4 @@ abstract class MessagePacketBase<TSender : QQ, TSubject : Contact>(_bot: Bot) :
...
@@ -135,16 +134,4 @@ abstract class MessagePacketBase<TSender : QQ, TSubject : Contact>(_bot: Bot) :
*/
*/
suspend
inline
fun
Image
.
download
():
ByteReadPacket
=
bot
.
run
{
download
()
}
suspend
inline
fun
Image
.
download
():
ByteReadPacket
=
bot
.
run
{
download
()
}
// endregion
// endregion
@Deprecated
(
message
=
"这个函数有歧义, 将在不久后删除"
,
replaceWith
=
ReplaceWith
(
"bot.getFriend(this.target)"
))
fun
At
.
qq
():
QQ
=
bot
.
getFriend
(
this
.
target
)
@Deprecated
(
message
=
"这个函数有歧义, 将在不久后删除"
,
replaceWith
=
ReplaceWith
(
"bot.getFriend(this.toLong())"
))
fun
Int
.
qq
():
QQ
=
bot
.
getFriend
(
this
.
coerceAtLeastOrFail
(
0
).
toLong
())
@Deprecated
(
message
=
"这个函数有歧义, 将在不久后删除"
,
replaceWith
=
ReplaceWith
(
"bot.getFriend(this)"
))
fun
Long
.
qq
():
QQ
=
bot
.
getFriend
(
this
.
coerceAtLeastOrFail
(
0
))
@Deprecated
(
message
=
"这个函数有歧义, 将在不久后删除"
,
replaceWith
=
ReplaceWith
(
"bot.getGroup(this)"
))
fun
Long
.
group
():
Group
=
bot
.
getGroup
(
this
)
}
}
\ No newline at end of file
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/MessageReceipt.kt
0 → 100644
View file @
587fab23
/*
* 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.message
import
kotlinx.atomicfu.atomic
import
kotlinx.coroutines.Job
import
net.mamoe.mirai.Bot
import
net.mamoe.mirai.contact.*
import
net.mamoe.mirai.message.data.MessageChain
import
net.mamoe.mirai.message.data.quote
import
net.mamoe.mirai.utils.MiraiExperimentalAPI
import
net.mamoe.mirai.utils.getValue
import
net.mamoe.mirai.utils.unsafeWeakRef
/**
* 发送消息后得到的回执. 可用于撤回.
*
* 此对象持有 [Contact] 的弱引用, [Bot] 离线后将会释放引用, 届时 [target] 将无法访问.
*
* @see Group.sendMessage 发送群消息, 返回回执(此对象)
* @see QQ.sendMessage 发送群消息, 返回回执(此对象)
*/
open
class
MessageReceipt
<
C
:
Contact
>(
val
originalMessage
:
MessageChain
,
target
:
C
)
{
init
{
require
(
target
is
Group
||
target
is
QQ
)
{
"target must be either Group or QQ"
}
}
/**
* 发送目标, 为 [Group] 或 [QQ]
*/
val
target
:
C
by
target
.
unsafeWeakRef
()
private
val
_isRecalled
=
atomic
(
false
)
/**
* 判断消息是否已被撤回.
*/
val
isRecalled
:
Boolean
get
()
=
_isRecalled
.
value
/**
* 撤回这条消息. [recall] 或 [recallIn] 只能被调用一次.
*
* @see Group.recall
* @throws IllegalStateException 当此消息已经被撤回或正计划撤回时
*/
@UseExperimental
(
MiraiExperimentalAPI
::
class
)
suspend
fun
recall
()
{
@Suppress
(
"BooleanLiteralArgument"
)
if
(
_isRecalled
.
compareAndSet
(
false
,
true
))
{
when
(
val
contact
=
target
)
{
is
Group
->
{
contact
.
recall
(
originalMessage
)
}
is
QQ
->
{
TODO
()
}
else
->
error
(
"Unknown contact type"
)
}
}
else
error
(
"message is already or planned to be recalled"
)
}
/**
* 撤回这条消息. [recall] 或 [recallIn] 只能被调用一次.
*
* @param delay 延迟时间, 单位为毫秒
*
* @throws IllegalStateException 当此消息已经被撤回或正计划撤回时
*/
@UseExperimental
(
MiraiExperimentalAPI
::
class
)
fun
recallIn
(
delay
:
Long
):
Job
{
@Suppress
(
"BooleanLiteralArgument"
)
if
(
_isRecalled
.
compareAndSet
(
false
,
true
))
{
when
(
val
contact
=
target
)
{
is
Group
->
{
return
contact
.
recallIn
(
originalMessage
,
delay
)
}
is
QQ
->
{
TODO
()
}
else
->
error
(
"Unknown contact type"
)
}
}
else
error
(
"message is already or planned to be recalled"
)
}
/**
* 引用这条消息. 仅群消息能被引用
*
* @see MessageChain.quote 引用一条消息
*
* @throws IllegalStateException 当此消息不是群消息时
*/
@UseExperimental
(
MiraiExperimentalAPI
::
class
)
open
fun
quote
():
MessageChain
{
val
target
=
target
check
(
target
is
Group
)
{
"quote is only available for GroupMessage"
}
return
this
.
originalMessage
.
quote
(
target
.
botAsMember
)
}
}
\ No newline at end of file
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/MessageChain.kt
View file @
587fab23
...
@@ -13,9 +13,6 @@
...
@@ -13,9 +13,6 @@
package
net.mamoe.mirai.message.data
package
net.mamoe.mirai.message.data
import
net.mamoe.mirai.message.data.NullMessageChain.toString
import
net.mamoe.mirai.message.data.NullMessageChain.toString
import
net.mamoe.mirai.utils.MiraiExperimentalAPI
import
kotlin.contracts.ExperimentalContracts
import
kotlin.contracts.contract
import
kotlin.js.JsName
import
kotlin.js.JsName
import
kotlin.jvm.JvmMultifileClass
import
kotlin.jvm.JvmMultifileClass
import
kotlin.jvm.JvmName
import
kotlin.jvm.JvmName
...
@@ -68,6 +65,15 @@ interface MessageChain : Message, MutableList<Message> {
...
@@ -68,6 +65,15 @@ interface MessageChain : Message, MutableList<Message> {
}
}
}
}
/**
* 先删除同类型的消息, 再添加 [message]
*/
fun
MessageChain
.
addOrRemove
(
message
:
Message
)
{
val
clazz
=
message
::
class
this.remove
All
{
clazz
.
isInstance
(
it
)
}
this
.
add
(
message
)
}
/**
/**
* 遍历每一个有内容的消息, 即 [At], [AtAll], [PlainText], [Image], [Face], [XMLMessage]
* 遍历每一个有内容的消息, 即 [At], [AtAll], [PlainText], [Image], [Face], [XMLMessage]
*/
*/
...
@@ -133,37 +139,23 @@ fun MessageChain(vararg messages: Message): MessageChain =
...
@@ -133,37 +139,23 @@ fun MessageChain(vararg messages: Message): MessageChain =
else
MessageChainImpl
(
messages
.
toMutableList
())
else
MessageChainImpl
(
messages
.
toMutableList
())
/**
/**
* 构造 [MessageChain]
* 构造 [MessageChain] 的快速途径 (无 [Array] 创建)
* 若仅提供一个参数, 请考虑使用 [Message.toChain] 以优化性能
*/
*/
@JvmName
(
"newChain"
)
@JvmName
(
"newChain"
)
@JsName
(
"newChain"
)
@JsName
(
"newChain"
)
@Suppress
(
"FunctionName"
)
@Suppress
(
"FunctionName"
)
fun
MessageChain
(
message
s
:
Iterable
<
Message
>
):
MessageChain
=
fun
MessageChain
(
message
:
Message
):
MessageChain
=
MessageChainImpl
(
m
essages
.
toMutableList
(
))
MessageChainImpl
(
m
utableListOf
(
message
))
/**
/**
* 构造单元素的不可修改的 [MessageChain]. 内部类实现为 [SingleMessageChain]
* 构造 [MessageChain]
*
* 参数 [delegate] 不能为 [MessageChain] 的实例, 否则将会抛出异常.
* 使用 [Message.toChain] 将帮助提前处理这个问题.
*
* @param delegate 所构造的单元素 [MessageChain] 代表的 [Message]
* @throws IllegalArgumentException 当 [delegate] 为 [MessageChain] 的实例时
*
* @see Message.toChain receiver 模式
*/
*/
@JvmName
(
"new
SingleMessage
Chain"
)
@JvmName
(
"newChain"
)
@JsName
(
"newChain"
)
@JsName
(
"newChain"
)
@MiraiExperimentalAPI
@UseExperimental
(
ExperimentalContracts
::
class
)
@Suppress
(
"FunctionName"
)
@Suppress
(
"FunctionName"
)
fun
SingleMessageChain
(
delegate
:
Message
):
MessageChain
{
fun
MessageChain
(
messages
:
Iterable
<
Message
>):
MessageChain
=
contract
{
MessageChainImpl
(
messages
.
toMutableList
())
returns
()
implies
(
delegate
!
is
MessageChain
)
}
require
(
delegate
!
is
MessageChain
)
{
"delegate for SingleMessageChain should not be any instance of MessageChain"
}
return
SingleMessageChainImpl
(
delegate
)
}
/**
/**
...
@@ -387,97 +379,3 @@ internal inline class MessageChainImpl constructor(
...
@@ -387,97 +379,3 @@ internal inline class MessageChainImpl constructor(
// endregion
// endregion
}
}
/**
* 单个成员的不可修改的 [MessageChain].
*
* 在连接时将会把它当做一个普通 [Message] 看待, 但它不能被 [plusAssign]
*/
@PublishedApi
internal
inline
class
SingleMessageChainImpl
(
private
val
delegate
:
Message
)
:
Message
,
MutableList
<
Message
>,
MessageChain
{
// region Message override
override
operator
fun
contains
(
sub
:
String
):
Boolean
=
delegate
.
contains
(
sub
)
override
fun
followedBy
(
tail
:
Message
):
MessageChain
{
require
(
tail
!
is
SingleOnly
)
{
"SingleOnly Message cannot follow another message"
}
return
if
(
tail
is
MessageChain
)
tail
.
apply
{
followedBy
(
delegate
)
}
else
MessageChain
(
delegate
,
tail
)
}
override
fun
plusAssign
(
message
:
Message
)
=
throw
UnsupportedOperationException
(
"SingleMessageChainImpl cannot be plusAssigned"
)
override
fun
toString
():
String
=
delegate
.
toString
()
// 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
=
!
hasNext
override
fun
nextIndex
():
Int
=
if
(
hasNext
)
0
else
-
1
override
fun
previous
():
Message
=
if
(
hasPrevious
())
{
hasNext
=
true
delegate
}
else
throw
NoSuchElementException
()
override
fun
previousIndex
():
Int
=
if
(!
hasNext
)
0
else
-
1
override
fun
add
(
element
:
Message
)
=
throw
UnsupportedOperationException
()
override
fun
hasNext
():
Boolean
=
hasNext
override
fun
next
():
Message
=
if
(
hasNext
)
{
hasNext
=
false
delegate
}
else
throw
NoSuchElementException
()
override
fun
remove
()
=
throw
UnsupportedOperationException
()
override
fun
set
(
element
:
Message
)
=
throw
UnsupportedOperationException
()
}
override
fun
listIterator
(
index
:
Int
):
MutableListIterator
<
Message
>
=
if
(
index
==
0
)
listIterator
()
else
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
delegate
}
else
throw
NoSuchElementException
()
override
fun
remove
()
=
throw
UnsupportedOperationException
()
}
override
operator
fun
contains
(
element
:
Message
):
Boolean
=
element
==
delegate
override
val
size
:
Int
get
()
=
1
// endregion
}
\ No newline at end of file
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/MessageSource.kt
View file @
587fab23
...
@@ -47,7 +47,7 @@ interface MessageSource : Message {
...
@@ -47,7 +47,7 @@ interface MessageSource : Message {
val
senderId
:
Long
val
senderId
:
Long
/**
/**
* 群号码
* 群号码
, 为 0 时则来自好友消息
*/
*/
val
groupId
:
Long
val
groupId
:
Long
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/PlainText.kt
View file @
587fab23
...
@@ -38,15 +38,4 @@ inline class PlainText(val stringValue: String) : Message {
...
@@ -38,15 +38,4 @@ inline class PlainText(val stringValue: String) : Message {
* 构造 [PlainText]
* 构造 [PlainText]
*/
*/
@Suppress
(
"NOTHING_TO_INLINE"
)
@Suppress
(
"NOTHING_TO_INLINE"
)
inline
fun
String
.
toMessage
():
PlainText
=
PlainText
(
this
)
inline
fun
String
.
toMessage
():
PlainText
=
PlainText
(
this
)
\ No newline at end of file
/**
* 得到包含作为 [PlainText] 的 [this] 的 [MessageChain].
*
* @return 唯一成员且不可修改的 [SingleMessageChainImpl]
*
* @see SingleMessageChain
* @see SingleMessageChainImpl
*/
@Suppress
(
"NOTHING_TO_INLINE"
)
inline
fun
String
.
singleChain
():
MessageChain
=
SingleMessageChainImpl
(
this
.
toMessage
())
\ No newline at end of file
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