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
6f0853e6
Commit
6f0853e6
authored
Jun 14, 2020
by
Him188
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement `MessagePreSendEvent` and `MessagePostSendEvent`.
Deprecate `MessageSendEvent` Fix #339
parent
4c79d4cd
Changes
11
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
618 additions
and
266 deletions
+618
-266
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/FriendImpl.kt
...in/kotlin/net/mamoe/mirai/qqandroid/contact/FriendImpl.kt
+50
-46
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/GroupImpl.kt
...ain/kotlin/net/mamoe/mirai/qqandroid/contact/GroupImpl.kt
+57
-59
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/MemberImpl.kt
...in/kotlin/net/mamoe/mirai/qqandroid/contact/MemberImpl.kt
+45
-19
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/util.kt
...mmonMain/kotlin/net/mamoe/mirai/qqandroid/contact/util.kt
+52
-20
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.PbSendMsg.kt
...work/protocol/packet/chat/receive/MessageSvc.PbSendMsg.kt
+90
-76
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt
.../src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt
+6
-8
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Friend.kt
...e/src/commonMain/kotlin/net.mamoe.mirai/contact/Friend.kt
+7
-5
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Group.kt
...re/src/commonMain/kotlin/net.mamoe.mirai/contact/Group.kt
+5
-5
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Member.kt
...e/src/commonMain/kotlin/net.mamoe.mirai/contact/Member.kt
+11
-3
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/User.kt
...ore/src/commonMain/kotlin/net.mamoe.mirai/contact/User.kt
+4
-8
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/events/message.kt
...commonMain/kotlin/net.mamoe.mirai/event/events/message.kt
+291
-17
No files found.
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/FriendImpl.kt
View file @
6f0853e6
...
@@ -33,6 +33,7 @@ import net.mamoe.mirai.event.events.ImageUploadEvent
...
@@ -33,6 +33,7 @@ import net.mamoe.mirai.event.events.ImageUploadEvent
import
net.mamoe.mirai.message.MessageReceipt
import
net.mamoe.mirai.message.MessageReceipt
import
net.mamoe.mirai.message.data.Image
import
net.mamoe.mirai.message.data.Image
import
net.mamoe.mirai.message.data.Message
import
net.mamoe.mirai.message.data.Message
import
net.mamoe.mirai.message.data.OfflineFriendImage
import
net.mamoe.mirai.message.data.isContentNotEmpty
import
net.mamoe.mirai.message.data.isContentNotEmpty
import
net.mamoe.mirai.qqandroid.QQAndroidBot
import
net.mamoe.mirai.qqandroid.QQAndroidBot
import
net.mamoe.mirai.qqandroid.network.highway.postImage
import
net.mamoe.mirai.qqandroid.network.highway.postImage
...
@@ -87,7 +88,11 @@ internal class FriendImpl(
...
@@ -87,7 +88,11 @@ internal class FriendImpl(
@Suppress
(
"DuplicatedCode"
)
@Suppress
(
"DuplicatedCode"
)
override
suspend
fun
sendMessage
(
message
:
Message
):
MessageReceipt
<
Friend
>
{
override
suspend
fun
sendMessage
(
message
:
Message
):
MessageReceipt
<
Friend
>
{
require
(
message
.
isContentNotEmpty
())
{
"message is empty"
}
require
(
message
.
isContentNotEmpty
())
{
"message is empty"
}
return
sendMessageImpl
(
this
,
message
).
also
{
return
sendMessageImpl
(
message
,
friendReceiptConstructor
=
{
MessageReceipt
(
it
,
this
,
null
)
},
tReceiptConstructor
=
{
MessageReceipt
(
it
,
this
,
null
)
}
).
also
{
logMessageSent
(
message
)
logMessageSent
(
message
)
}
}
}
}
...
@@ -101,23 +106,23 @@ internal class FriendImpl(
...
@@ -101,23 +106,23 @@ internal class FriendImpl(
if
(
BeforeImageUploadEvent
(
this
,
image
).
broadcast
().
isCancelled
)
{
if
(
BeforeImageUploadEvent
(
this
,
image
).
broadcast
().
isCancelled
)
{
throw
EventCancelledException
(
"cancelled by BeforeImageUploadEvent.ToGroup"
)
throw
EventCancelledException
(
"cancelled by BeforeImageUploadEvent.ToGroup"
)
}
}
bot
.
network
.
run
{
val
response
=
bot
.
network
.
run
{
val
response
=
LongConn
.
OffPicUp
(
LongConn
.
OffPicUp
(
bot
.
client
,
Cmd0x352
.
TryUpImgReq
(
bot
.
client
,
Cmd0x352
.
TryUpImgReq
(
srcUin
=
bot
.
id
.
toInt
(),
srcUin
=
bot
.
id
.
toInt
(),
dstUin
=
id
.
toInt
(),
dstUin
=
id
.
toInt
(),
fileId
=
0
,
fileId
=
0
,
fileMd5
=
@Suppress
(
"INVISIBLE_MEMBER"
)
image
.
md5
,
fileMd5
=
image
.
md5
,
fileSize
=
@Suppress
(
"INVISIBLE_MEMBER"
)
fileSize
=
image
.
input
.
size
.
toInt
(),
image
.
input
.
size
.
toInt
(),
fileName
=
image
.
md5
.
toUHexString
(
""
)
+
"."
+
ExternalImage
.
defaultFormatName
,
fileName
=
@Suppress
(
"INVISIBLE_MEMBER"
)
image
.
md5
.
toUHexString
(
""
)
+
"."
+
ExternalImage
.
defaultFormatName
,
imgOriginal
=
1
imgOriginal
=
1
)
)
).
sendAndExpect
<
LongConn
.
OffPicUp
.
Response
>()
).
sendAndExpect
<
LongConn
.
OffPicUp
.
Response
>()
}
@Suppress
(
"UNCHECKED_CAST"
,
"DEPRECATION"
,
"INVISIBLE_MEMBER
"
)
@Suppress
(
"UNCHECKED_CAST"
,
"DEPRECATION
"
)
return
when
(
response
)
{
when
(
response
)
{
is
LongConn
.
OffPicUp
.
Response
.
FileExists
->
net
.
mamoe
.
mirai
.
message
.
data
.
OfflineFriendImage
(
response
.
resourceId
)
is
LongConn
.
OffPicUp
.
Response
.
FileExists
->
OfflineFriendImage
(
response
.
resourceId
)
.
also
{
.
also
{
ImageUploadEvent
.
Succeed
(
this
@FriendImpl
,
image
,
it
).
broadcast
()
ImageUploadEvent
.
Succeed
(
this
@FriendImpl
,
image
,
it
).
broadcast
()
}
}
...
@@ -151,7 +156,7 @@ internal class FriendImpl(
...
@@ -151,7 +156,7 @@ internal class FriendImpl(
)*/
)*/
// 为什么不能 ??
// 为什么不能 ??
return
net
.
mamoe
.
mirai
.
message
.
data
.
OfflineFriendImage
(
response
.
resourceId
).
also
{
OfflineFriendImage
(
response
.
resourceId
).
also
{
ImageUploadEvent
.
Succeed
(
this
@FriendImpl
,
image
,
it
).
broadcast
()
ImageUploadEvent
.
Succeed
(
this
@FriendImpl
,
image
,
it
).
broadcast
()
}
}
}
}
...
@@ -160,7 +165,6 @@ internal class FriendImpl(
...
@@ -160,7 +165,6 @@ internal class FriendImpl(
error
(
response
.
message
)
error
(
response
.
message
)
}
}
}
}
}
}
finally
{
}
finally
{
@Suppress
(
"INVISIBLE_MEMBER"
,
"INVISIBLE_REFERENCE"
)
@Suppress
(
"INVISIBLE_MEMBER"
,
"INVISIBLE_REFERENCE"
)
(
image
.
input
as
?
Closeable
)
?.
close
()
(
image
.
input
as
?
Closeable
)
?.
close
()
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/GroupImpl.kt
View file @
6f0853e6
...
@@ -22,7 +22,6 @@ import net.mamoe.mirai.data.GroupInfo
...
@@ -22,7 +22,6 @@ import net.mamoe.mirai.data.GroupInfo
import
net.mamoe.mirai.data.MemberInfo
import
net.mamoe.mirai.data.MemberInfo
import
net.mamoe.mirai.event.broadcast
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.GroupMessageSendEvent
import
net.mamoe.mirai.message.MessageReceipt
import
net.mamoe.mirai.message.MessageReceipt
import
net.mamoe.mirai.message.data.*
import
net.mamoe.mirai.message.data.*
import
net.mamoe.mirai.qqandroid.QQAndroidBot
import
net.mamoe.mirai.qqandroid.QQAndroidBot
...
@@ -33,6 +32,7 @@ import net.mamoe.mirai.qqandroid.network.highway.HighwayHelper
...
@@ -33,6 +32,7 @@ import net.mamoe.mirai.qqandroid.network.highway.HighwayHelper
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.receive.MessageSvcPbSendMsg
import
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.MessageSvcPbSendMsg
import
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.createToGroup
import
net.mamoe.mirai.qqandroid.network.protocol.packet.list.ProfileService
import
net.mamoe.mirai.qqandroid.network.protocol.packet.list.ProfileService
import
net.mamoe.mirai.qqandroid.utils.estimateLength
import
net.mamoe.mirai.qqandroid.utils.estimateLength
import
net.mamoe.mirai.utils.*
import
net.mamoe.mirai.utils.*
...
@@ -304,80 +304,66 @@ internal class GroupImpl(
...
@@ -304,80 +304,66 @@ internal class GroupImpl(
check
(
message
.
nodeList
.
size
<
200
)
{
check
(
message
.
nodeList
.
size
<
200
)
{
throw
MessageTooLargeException
(
throw
MessageTooLargeException
(
this
,
message
,
message
,
this
,
message
,
message
,
"ForwardMessage allows up to 200 nodes, but found ${message.nodeList.size}"
)
"ForwardMessage allows up to 200 nodes, but found ${message.nodeList.size}"
)
}
}
return
bot
.
lowLevelSendGroupLongOrForwardMessage
(
this
.
id
,
message
.
nodeList
,
false
,
message
)
return
bot
.
lowLevelSendGroupLongOrForwardMessage
(
this
.
id
,
message
.
nodeList
,
false
,
message
)
}
}
val
msg
:
MessageChain
val
msg
:
MessageChain
=
if
(
message
!
is
LongMessage
&&
message
!
is
ForwardMessageInternal
)
{
val
chain
=
kotlin
.
runCatching
{
if
(
message
!
is
LongMessage
&&
message
!
is
ForwardMessageInternal
)
{
GroupMessagePreSendEvent
(
this
,
message
).
broadcast
()
val
event
=
GroupMessageSendEvent
(
this
,
message
.
asMessageChain
()).
broadcast
()
}.
onSuccess
{
if
(
even
t
.
isCancelled
)
{
check
(!
i
t
.
isCancelled
)
{
throw
EventCancelledException
(
"cancelled by GroupMessag
eSendEvent"
)
throw
EventCancelledException
(
"cancelled by GroupMessagePr
eSendEvent"
)
}
}
}.
getOrElse
{
throw
EventCancelledException
(
"exception thrown when broadcasting GroupMessagePreSendEvent"
,
it
)
}.
message
.
asMessageChain
()
val
length
=
event
.
message
.
estimateLength
(
703
)
// 阈值为700左右,限制到3的倍数
val
length
=
chain
.
estimateLength
(
703
)
// 阈值为700左右,限制到3的倍数
var
imageCnt
=
0
// 通过下方逻辑短路延迟计算
var
imageCnt
=
0
// 通过下方逻辑短路延迟计算
if
(
length
>
5000
||
event
.
message
.
count
{
it
is
Image
}.
apply
{
imageCnt
=
this
}
>
50
)
{
if
(
length
>
5000
||
chain
.
count
{
it
is
Image
}.
apply
{
imageCnt
=
this
}
>
50
)
{
throw
MessageTooLargeException
(
throw
MessageTooLargeException
(
this
,
this
,
message
,
chain
,
message
,
"message(${chain.joinToString("", limit = 10)}) is too large. Allow up to 50 images or 5000 chars"
event
.
message
,
"message(${event.message.joinToString(
""
,
limit
=
10
)})
is
too
large
.
Allow
up
to
50
images
or
5000
chars
"
)
)
}
}
if
(
length
>
702
||
imageCnt
>
2
)
{
if
(
length
>
702
||
imageCnt
>
2
)
{
return
bot
.
lowLevelSendGroupLongOrForwardMessage
(
this
.
id
,
return
bot
.
lowLevelSendGroupLongOrForwardMessage
(
listOf
(
ForwardMessage
.
Node
(
this
.
id
,
listOf
(
ForwardMessage
.
Node
(
senderId
=
bot
.
id
,
senderId
=
bot
.
id
,
time
=
currentTimeSeconds
.
toInt
(),
time
=
currentTimeSeconds
.
toInt
(),
message
=
event
.
message
,
message
=
chain
,
senderName
=
bot
.
nick
)
senderName
=
bot
.
nick
)
),
),
true
,
null
)
true
,
null
)
}
}
chain
}
else
message
.
asMessageChain
()
msg
=
event
.
message
}
else
msg
=
message
.
asMessageChain
()
msg
.
firstIsInstanceOrNull
<
QuoteReply
>()
?.
source
?.
ensureSequenceIdAvailable
()
msg
.
firstIsInstanceOrNull
<
QuoteReply
>()
?.
source
?.
ensureSequenceIdAvailable
()
lateinit
var
source
:
MessageSourceToGroupImpl
bot
.
network
.
run
{
val
result
=
bot
.
network
.
runCatching
{
val
response
:
MessageSvcPbSendMsg
.
Response
=
MessageSvcPbSendMsg
.
createToGroup
(
val
source
:
MessageSourceToGroupImpl
MessageSvcPbSendMsg
.
createToGroup
(
bot
.
client
,
bot
.
client
,
this
@GroupImpl
,
this
@GroupImpl
,
msg
,
msg
,
isForward
isForward
)
{
)
{
source
=
it
source
=
it
}.
sendAndExpect
()
}.
sendAndExpect
<
MessageSvcPbSendMsg
.
Response
>().
let
{
if
(
response
is
MessageSvcPbSendMsg
.
Response
.
Failed
)
{
check
(
it
is
MessageSvcPbSendMsg
.
Response
.
SUCCESS
)
{
when
(
response
.
resultType
)
{
"Send temp message failed: $it"
120
->
throw
BotIsBeingMutedException
(
this
@GroupImpl
)
34
->
{
kotlin
.
runCatching
{
// allow retry once
return
bot
.
lowLevelSendGroupLongOrForwardMessage
(
id
,
listOf
(
ForwardMessage
.
Node
(
senderId
=
bot
.
id
,
time
=
currentTimeSeconds
.
toInt
(),
message
=
msg
,
senderName
=
bot
.
nick
)
),
true
,
null
)
}.
getOrElse
{
throw
IllegalStateException
(
"internal error: send message failed(34)"
,
it
)
}
}
else
->
error
(
"send message failed: $response"
)
}
}
}
}
}
...
@@ -391,7 +377,19 @@ internal class GroupImpl(
...
@@ -391,7 +377,19 @@ internal class GroupImpl(
bot
.
network
.
logger
.
warning
(
e
)
bot
.
network
.
logger
.
warning
(
e
)
}
}
return
MessageReceipt
(
source
,
this
,
botAsMember
)
MessageReceipt
(
source
,
this
@GroupImpl
,
botAsMember
)
}
result
.
fold
(
onSuccess
=
{
GroupMessagePostSendEvent
(
this
,
msg
,
null
,
it
)
},
onFailure
=
{
GroupMessagePostSendEvent
(
this
,
msg
,
it
,
null
)
}
).
broadcast
()
return
result
.
getOrThrow
()
}
}
@Suppress
(
"DEPRECATION"
)
@Suppress
(
"DEPRECATION"
)
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/MemberImpl.kt
View file @
6f0853e6
...
@@ -28,6 +28,7 @@ import net.mamoe.mirai.qqandroid.message.firstIsInstanceOrNull
...
@@ -28,6 +28,7 @@ import net.mamoe.mirai.qqandroid.message.firstIsInstanceOrNull
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.packet.chat.TroopManagement
import
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.TroopManagement
import
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.MessageSvcPbSendMsg
import
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.MessageSvcPbSendMsg
import
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.createToTemp
import
net.mamoe.mirai.utils.ExternalImage
import
net.mamoe.mirai.utils.ExternalImage
import
net.mamoe.mirai.utils.currentTimeSeconds
import
net.mamoe.mirai.utils.currentTimeSeconds
import
net.mamoe.mirai.utils.getValue
import
net.mamoe.mirai.utils.getValue
...
@@ -54,34 +55,59 @@ internal class MemberImpl constructor(
...
@@ -54,34 +55,59 @@ internal class MemberImpl constructor(
override
val
id
:
Long
=
qq
.
id
override
val
id
:
Long
=
qq
.
id
override
val
nick
:
String
=
qq
.
nick
override
val
nick
:
String
=
qq
.
nick
@Suppress
(
"UNCHECKED_CAST"
)
@JvmSynthetic
@JvmSynthetic
override
suspend
fun
sendMessage
(
message
:
Message
):
MessageReceipt
<
Member
>
{
override
suspend
fun
sendMessage
(
message
:
Message
):
MessageReceipt
<
Member
>
{
require
(
message
.
isContentNotEmpty
())
{
"message is empty"
}
require
(
message
.
isContentNotEmpty
())
{
"message is empty"
}
return
(
this
.
asFriendOrNull
()
?.
sendMessageImpl
(
this
,
message
)
?:
sendMessageImpl
(
message
))
val
asFriend
=
this
.
asFriendOrNull
()
.
also
{
logMessageSent
(
message
)
}
return
(
asFriend
?.
sendMessageImpl
(
message
,
friendReceiptConstructor
=
{
MessageReceipt
(
it
,
asFriend
,
null
)
},
tReceiptConstructor
=
{
MessageReceipt
(
it
,
this
,
null
)
}
)
?:
sendMessageImpl
(
message
)).
also
{
logMessageSent
(
message
)
}
}
}
private
suspend
fun
sendMessageImpl
(
message
:
Message
):
MessageReceipt
<
Member
>
{
private
suspend
fun
sendMessageImpl
(
message
:
Message
):
MessageReceipt
<
Member
>
{
val
event
=
MessageSendEvent
.
TempMessageSendEvent
(
this
,
message
.
asMessageChain
()).
broadcast
()
val
chain
=
kotlin
.
runCatching
{
if
(
event
.
isCancelled
)
{
TempMessagePreSendEvent
(
this
,
message
).
broadcast
()
throw
EventCancelledException
(
"cancelled by TempMessageSendEvent"
)
}.
onSuccess
{
check
(!
it
.
isCancelled
)
{
throw
EventCancelledException
(
"cancelled by TempMessagePreSendEvent"
)
}
}
event
.
message
.
firstIsInstanceOrNull
<
QuoteReply
>()
?.
source
?.
ensureSequenceIdAvailable
()
}.
getOrElse
{
throw
EventCancelledException
(
"exception thrown when broadcasting TempMessagePreSendEvent"
,
it
)
}.
message
.
asMessageChain
()
lateinit
var
source
:
MessageSourceToTempImpl
chain
.
firstIsInstanceOrNull
<
QuoteReply
>()
?.
source
?.
ensureSequenceIdAvailable
()
bot
.
network
.
run
{
check
(
val
result
=
bot
.
network
.
runCatching
{
val
source
:
MessageSourceToTempImpl
MessageSvcPbSendMsg
.
createToTemp
(
MessageSvcPbSendMsg
.
createToTemp
(
bot
.
client
,
bot
.
client
,
this
@MemberImpl
,
this
@MemberImpl
,
message
.
asMessageChain
()
chain
)
{
)
{
source
=
it
source
=
it
}.
sendAndExpect
<
MessageSvcPbSendMsg
.
Response
>()
is
MessageSvcPbSendMsg
.
Response
.
SUCCESS
}.
sendAndExpect
<
MessageSvcPbSendMsg
.
Response
>().
let
{
)
{
"send message failed"
}
check
(
it
is
MessageSvcPbSendMsg
.
Response
.
SUCCESS
)
{
"Send temp message failed: $it"
}
}
}
return
MessageReceipt
(
source
,
this
,
null
)
MessageReceipt
(
source
,
this
@MemberImpl
,
null
)
}
result
.
fold
(
onSuccess
=
{
TempMessagePostSendEvent
(
this
,
chain
,
null
,
it
)
},
onFailure
=
{
TempMessagePostSendEvent
(
this
,
chain
,
it
,
null
)
}
).
broadcast
()
return
result
.
getOrThrow
()
}
}
@JvmSynthetic
@JvmSynthetic
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/util.kt
View file @
6f0853e6
...
@@ -12,40 +12,72 @@ package net.mamoe.mirai.qqandroid.contact
...
@@ -12,40 +12,72 @@ package net.mamoe.mirai.qqandroid.contact
import
net.mamoe.mirai.contact.Contact
import
net.mamoe.mirai.contact.Contact
import
net.mamoe.mirai.contact.Friend
import
net.mamoe.mirai.contact.Friend
import
net.mamoe.mirai.contact.User
import
net.mamoe.mirai.event.broadcast
import
net.mamoe.mirai.event.broadcast
import
net.mamoe.mirai.event.events.EventCancelledException
import
net.mamoe.mirai.event.events.EventCancelledException
import
net.mamoe.mirai.event.events.MessageSendEvent
import
net.mamoe.mirai.event.events.FriendMessagePostSendEvent
import
net.mamoe.mirai.event.events.FriendMessagePreSendEvent
import
net.mamoe.mirai.message.*
import
net.mamoe.mirai.message.*
import
net.mamoe.mirai.message.data.Message
import
net.mamoe.mirai.message.data.Message
import
net.mamoe.mirai.message.data.QuoteReply
import
net.mamoe.mirai.message.data.QuoteReply
import
net.mamoe.mirai.message.data.asMessageChain
import
net.mamoe.mirai.message.data.asMessageChain
import
net.mamoe.mirai.message.data.firstIsInstanceOrNull
import
net.mamoe.mirai.qqandroid.asQQAndroidBot
import
net.mamoe.mirai.qqandroid.asQQAndroidBot
import
net.mamoe.mirai.qqandroid.message.MessageSourceToFriendImpl
import
net.mamoe.mirai.qqandroid.message.MessageSourceToFriendImpl
import
net.mamoe.mirai.qqandroid.message.ensureSequenceIdAvailable
import
net.mamoe.mirai.qqandroid.message.ensureSequenceIdAvailable
import
net.mamoe.mirai.qqandroid.message.firstIsInstanceOrNull
import
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.MessageSvcPbSendMsg
import
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.MessageSvcPbSendMsg
import
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.createToFriend
import
net.mamoe.mirai.utils.verbose
import
net.mamoe.mirai.utils.verbose
import
kotlin.contracts.InvocationKind
import
kotlin.contracts.contract
internal
suspend
fun
<
T
:
Contact
>
Friend
.
sendMessageImpl
(
generic
:
T
,
message
:
Message
):
MessageReceipt
<
T
>
{
internal
suspend
fun
<
T
:
User
>
Friend
.
sendMessageImpl
(
val
event
=
MessageSendEvent
.
FriendMessageSendEvent
(
this
,
message
.
asMessageChain
()).
broadcast
()
message
:
Message
,
if
(
event
.
isCancelled
)
{
friendReceiptConstructor
:
(
MessageSourceToFriendImpl
)
->
MessageReceipt
<
Friend
>,
throw
EventCancelledException
(
"cancelled by FriendMessageSendEvent"
)
tReceiptConstructor
:
(
MessageSourceToFriendImpl
)
->
MessageReceipt
<
T
>
):
MessageReceipt
<
T
>
{
contract
{
callsInPlace
(
friendReceiptConstructor
,
InvocationKind
.
EXACTLY_ONCE
)
}
val
bot
=
bot
.
asQQAndroidBot
()
val
chain
=
kotlin
.
runCatching
{
FriendMessagePreSendEvent
(
this
,
message
).
broadcast
()
}.
onSuccess
{
check
(!
it
.
isCancelled
)
{
throw
EventCancelledException
(
"cancelled by FriendMessagePreSendEvent"
)
}
}
event
.
message
.
firstIsInstanceOrNull
<
QuoteReply
>()
?.
source
?.
ensureSequenceIdAvailable
()
}.
getOrElse
{
throw
EventCancelledException
(
"exception thrown when broadcasting FriendMessagePreSendEvent"
,
it
)
}.
message
.
asMessageChain
()
chain
.
firstIsInstanceOrNull
<
QuoteReply
>()
?.
source
?.
ensureSequenceIdAvailable
()
lateinit
var
source
:
MessageSourceToFriendImpl
lateinit
var
source
:
MessageSourceToFriendImpl
val
bot
=
bot
.
asQQAndroidBot
()
val
result
=
bot
.
network
.
runCatching
{
bot
.
network
.
run
{
check
(
MessageSvcPbSendMsg
.
createToFriend
(
MessageSvcPbSendMsg
.
createToFriend
(
bot
.
asQQAndroidBot
()
.
client
,
bot
.
client
,
this
@
sendMessageImpl
,
this
@
sendMessageImpl
,
event
.
message
chain
)
{
)
{
source
=
it
source
=
it
}.
sendAndExpect
<
MessageSvcPbSendMsg
.
Response
>()
is
MessageSvcPbSendMsg
.
Response
.
SUCCESS
}.
sendAndExpect
<
MessageSvcPbSendMsg
.
Response
>().
let
{
)
{
"send message failed"
}
check
(
it
is
MessageSvcPbSendMsg
.
Response
.
SUCCESS
)
{
"Send temp message failed: $it"
}
}
return
MessageReceipt
(
source
,
generic
,
null
)
}
friendReceiptConstructor
(
source
)
}
result
.
fold
(
onSuccess
=
{
FriendMessagePostSendEvent
(
this
,
chain
,
null
,
it
)
},
onFailure
=
{
FriendMessagePostSendEvent
(
this
,
chain
,
it
,
null
)
}
).
broadcast
()
result
.
getOrThrow
()
return
tReceiptConstructor
(
source
)
}
}
internal
fun
Contact
.
logMessageSent
(
message
:
Message
)
{
internal
fun
Contact
.
logMessageSent
(
message
:
Message
)
{
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.PbSendMsg.kt
View file @
6f0853e6
...
@@ -34,6 +34,8 @@ import net.mamoe.mirai.qqandroid.utils.io.serialization.readProtoBuf
...
@@ -34,6 +34,8 @@ import net.mamoe.mirai.qqandroid.utils.io.serialization.readProtoBuf
import
net.mamoe.mirai.qqandroid.utils.io.serialization.toByteArray
import
net.mamoe.mirai.qqandroid.utils.io.serialization.toByteArray
import
net.mamoe.mirai.qqandroid.utils.io.serialization.writeProtoBuf
import
net.mamoe.mirai.qqandroid.utils.io.serialization.writeProtoBuf
import
net.mamoe.mirai.utils.currentTimeSeconds
import
net.mamoe.mirai.utils.currentTimeSeconds
import
kotlin.contracts.InvocationKind
import
kotlin.contracts.contract
import
kotlin.math.absoluteValue
import
kotlin.math.absoluteValue
import
kotlin.random.Random
import
kotlin.random.Random
...
@@ -52,34 +54,11 @@ internal object MessageSvcPbSendMsg : OutgoingPacketFactory<MessageSvcPbSendMsg.
...
@@ -52,34 +54,11 @@ internal object MessageSvcPbSendMsg : OutgoingPacketFactory<MessageSvcPbSendMsg.
}
}
}
}
inline
fun
createToFriend
(
client
:
QQAndroidClient
,
qq
:
Friend
,
message
:
MessageChain
,
crossinline
sourceCallback
:
(
MessageSourceToFriendImpl
)
->
Unit
):
OutgoingPacket
{
val
rand
=
Random
.
nextInt
().
absoluteValue
val
source
=
MessageSourceToFriendImpl
(
internalId
=
rand
,
sender
=
client
.
bot
,
target
=
qq
,
time
=
currentTimeSeconds
.
toInt
(),
sequenceId
=
client
.
nextFriendSeq
(),
originalMessage
=
message
)
sourceCallback
(
source
)
return
createToFriend
(
client
,
qq
.
id
,
message
,
source
)
}
/**
/**
* 发送好友消息
* 发送好友消息
*/
*/
@Suppress
(
"FunctionName"
)
@Suppress
(
"FunctionName"
)
private
fun
createToFriend
(
internal
fun
createToFriendImpl
(
client
:
QQAndroidClient
,
client
:
QQAndroidClient
,
toUin
:
Long
,
toUin
:
Long
,
message
:
MessageChain
,
message
:
MessageChain
,
...
@@ -106,33 +85,10 @@ internal object MessageSvcPbSendMsg : OutgoingPacketFactory<MessageSvcPbSendMsg.
...
@@ -106,33 +85,10 @@ internal object MessageSvcPbSendMsg : OutgoingPacketFactory<MessageSvcPbSendMsg.
}
}
inline
fun
createToTemp
(
client
:
QQAndroidClient
,
member
:
Member
,
message
:
MessageChain
,
sourceCallback
:
(
MessageSourceToTempImpl
)
->
Unit
):
OutgoingPacket
{
val
source
=
MessageSourceToTempImpl
(
internalId
=
Random
.
nextInt
().
absoluteValue
,
sender
=
client
.
bot
,
target
=
member
,
time
=
currentTimeSeconds
.
toInt
(),
sequenceId
=
client
.
atomicNextMessageSequenceId
(),
originalMessage
=
message
)
sourceCallback
(
source
)
return
createToTemp
(
client
,
(
member
.
group
as
GroupImpl
).
uin
,
member
.
id
,
message
,
source
)
}
/**
/**
* 发送临时消息
* 发送临时消息
*/
*/
private
fun
createToTemp
(
internal
fun
createToTempImpl
(
client
:
QQAndroidClient
,
client
:
QQAndroidClient
,
groupUin
:
Long
,
groupUin
:
Long
,
toUin
:
Long
,
toUin
:
Long
,
...
@@ -158,37 +114,11 @@ internal object MessageSvcPbSendMsg : OutgoingPacketFactory<MessageSvcPbSendMsg.
...
@@ -158,37 +114,11 @@ internal object MessageSvcPbSendMsg : OutgoingPacketFactory<MessageSvcPbSendMsg.
}
}
inline
fun
createToGroup
(
client
:
QQAndroidClient
,
group
:
Group
,
message
:
MessageChain
,
isForward
:
Boolean
,
sourceCallback
:
(
MessageSourceToGroupImpl
)
->
Unit
):
OutgoingPacket
{
val
source
=
MessageSourceToGroupImpl
(
group
,
internalId
=
Random
.
nextInt
().
absoluteValue
,
sender
=
client
.
bot
,
target
=
group
,
time
=
currentTimeSeconds
.
toInt
(),
originalMessage
=
message
//,
// sourceMessage = message
)
sourceCallback
(
source
)
return
createToGroup
(
client
,
group
.
id
,
message
,
isForward
,
source
)
}
/**
/**
* 发送群消息
* 发送群消息
*/
*/
@Suppress
(
"FunctionName"
)
@Suppress
(
"FunctionName"
)
private
fun
createToGroup
(
internal
fun
createToGroupImpl
(
client
:
QQAndroidClient
,
client
:
QQAndroidClient
,
groupCode
:
Long
,
groupCode
:
Long
,
message
:
MessageChain
,
message
:
MessageChain
,
...
@@ -231,7 +161,91 @@ internal object MessageSvcPbSendMsg : OutgoingPacketFactory<MessageSvcPbSendMsg.
...
@@ -231,7 +161,91 @@ internal object MessageSvcPbSendMsg : OutgoingPacketFactory<MessageSvcPbSendMsg.
Response
.
Failed
(
Response
.
Failed
(
response
.
result
,
response
.
result
,
response
.
errtype
,
response
.
errtype
,
response
.
errmsg
)
response
.
errmsg
)
}
}
}
internal
inline
fun
MessageSvcPbSendMsg
.
createToTemp
(
client
:
QQAndroidClient
,
member
:
Member
,
message
:
MessageChain
,
crossinline
sourceCallback
:
(
MessageSourceToTempImpl
)
->
Unit
):
OutgoingPacket
{
contract
{
callsInPlace
(
sourceCallback
,
InvocationKind
.
EXACTLY_ONCE
)
}
}
val
source
=
MessageSourceToTempImpl
(
internalId
=
Random
.
nextInt
().
absoluteValue
,
sender
=
client
.
bot
,
target
=
member
,
time
=
currentTimeSeconds
.
toInt
(),
sequenceId
=
client
.
atomicNextMessageSequenceId
(),
originalMessage
=
message
)
sourceCallback
(
source
)
return
createToTempImpl
(
client
,
(
member
.
group
as
GroupImpl
).
uin
,
member
.
id
,
message
,
source
)
}
internal
inline
fun
MessageSvcPbSendMsg
.
createToFriend
(
client
:
QQAndroidClient
,
qq
:
Friend
,
message
:
MessageChain
,
crossinline
sourceCallback
:
(
MessageSourceToFriendImpl
)
->
Unit
):
OutgoingPacket
{
contract
{
callsInPlace
(
sourceCallback
,
InvocationKind
.
EXACTLY_ONCE
)
}
}
val
rand
=
Random
.
nextInt
().
absoluteValue
val
source
=
MessageSourceToFriendImpl
(
internalId
=
rand
,
sender
=
client
.
bot
,
target
=
qq
,
time
=
currentTimeSeconds
.
toInt
(),
sequenceId
=
client
.
nextFriendSeq
(),
originalMessage
=
message
)
sourceCallback
(
source
)
return
createToFriendImpl
(
client
,
qq
.
id
,
message
,
source
)
}
internal
inline
fun
MessageSvcPbSendMsg
.
createToGroup
(
client
:
QQAndroidClient
,
group
:
Group
,
message
:
MessageChain
,
isForward
:
Boolean
,
crossinline
sourceCallback
:
(
MessageSourceToGroupImpl
)
->
Unit
):
OutgoingPacket
{
contract
{
callsInPlace
(
sourceCallback
,
InvocationKind
.
EXACTLY_ONCE
)
}
val
source
=
MessageSourceToGroupImpl
(
group
,
internalId
=
Random
.
nextInt
().
absoluteValue
,
sender
=
client
.
bot
,
target
=
group
,
time
=
currentTimeSeconds
.
toInt
(),
originalMessage
=
message
//,
// sourceMessage = message
)
sourceCallback
(
source
)
return
createToGroupImpl
(
client
,
group
.
id
,
message
,
isForward
,
source
)
}
}
\ No newline at end of file
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt
View file @
6f0853e6
...
@@ -16,13 +16,11 @@ import kotlinx.coroutines.CoroutineScope
...
@@ -16,13 +16,11 @@ import kotlinx.coroutines.CoroutineScope
import
kotlinx.coroutines.Job
import
kotlinx.coroutines.Job
import
net.mamoe.mirai.Bot
import
net.mamoe.mirai.Bot
import
net.mamoe.mirai.JavaFriendlyAPI
import
net.mamoe.mirai.JavaFriendlyAPI
import
net.mamoe.mirai.event.events.BeforeImageUploadEvent
import
net.mamoe.mirai.event.events.*
import
net.mamoe.mirai.event.events.EventCancelledException
import
net.mamoe.mirai.event.events.ImageUploadEvent
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.MessageReceipt
import
net.mamoe.mirai.message.data.*
import
net.mamoe.mirai.message.data.*
import
net.mamoe.mirai.message.quote
import
net.mamoe.mirai.message.recall
import
net.mamoe.mirai.recall
import
net.mamoe.mirai.recall
import
net.mamoe.mirai.recallIn
import
net.mamoe.mirai.recallIn
import
net.mamoe.mirai.utils.ExternalImage
import
net.mamoe.mirai.utils.ExternalImage
...
@@ -57,8 +55,8 @@ abstract class Contact : ContactOrBot, CoroutineScope, ContactJavaFriendlyAPI {
...
@@ -57,8 +55,8 @@ abstract class Contact : ContactOrBot, CoroutineScope, ContactJavaFriendlyAPI {
*
*
* 单条消息最大可发送 4500 字符或 50 张图片.
* 单条消息最大可发送 4500 字符或 50 张图片.
*
*
* @see
FriendMessageSendEvent 发送好友信息事件, cancellable
* @see
MessagePreSendEvent 发送消息前事件
* @see
GroupMessageSendEvent 发送群消息事件. cancellable
* @see
MessagePostSendEvent 发送消息后事件
*
*
* @throws EventCancelledException 当发送消息事件被取消时抛出
* @throws EventCancelledException 当发送消息事件被取消时抛出
* @throws BotIsBeingMutedException 发送群消息时若 [Bot] 被禁言抛出
* @throws BotIsBeingMutedException 发送群消息时若 [Bot] 被禁言抛出
...
@@ -71,7 +69,7 @@ abstract class Contact : ContactOrBot, CoroutineScope, ContactJavaFriendlyAPI {
...
@@ -71,7 +69,7 @@ abstract class Contact : ContactOrBot, CoroutineScope, ContactJavaFriendlyAPI {
abstract
suspend
fun
sendMessage
(
message
:
Message
):
MessageReceipt
<
Contact
>
abstract
suspend
fun
sendMessage
(
message
:
Message
):
MessageReceipt
<
Contact
>
@Suppress
(
"INVISIBLE_MEMBER"
,
"INVISIBLE_REFERENCE"
,
"VIRTUAL_MEMBER_HIDDEN"
,
"OVERRIDE_BY_INLINE"
)
@Suppress
(
"INVISIBLE_MEMBER"
,
"INVISIBLE_REFERENCE"
,
"VIRTUAL_MEMBER_HIDDEN"
,
"OVERRIDE_BY_INLINE"
)
@
kotlin
.
internal
.
InlineOnly
// purely virtual
@
kotlin
.
internal
.
InlineOnly
@JvmSynthetic
@JvmSynthetic
suspend
inline
fun
sendMessage
(
message
:
String
):
MessageReceipt
<
Contact
>
{
suspend
inline
fun
sendMessage
(
message
:
String
):
MessageReceipt
<
Contact
>
{
return
sendMessage
(
message
.
toMessage
())
return
sendMessage
(
message
.
toMessage
())
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Friend.kt
View file @
6f0853e6
...
@@ -14,12 +14,14 @@ package net.mamoe.mirai.contact
...
@@ -14,12 +14,14 @@ package net.mamoe.mirai.contact
import
kotlinx.coroutines.CoroutineScope
import
kotlinx.coroutines.CoroutineScope
import
net.mamoe.mirai.Bot
import
net.mamoe.mirai.Bot
import
net.mamoe.mirai.event.events.EventCancelledException
import
net.mamoe.mirai.event.events.EventCancelledException
import
net.mamoe.mirai.event.events.
MessageSendEvent.FriendMessage
SendEvent
import
net.mamoe.mirai.event.events.
FriendMessagePost
SendEvent
import
net.mamoe.mirai.event.events.
MessageSendEvent.GroupMessag
eSendEvent
import
net.mamoe.mirai.event.events.
FriendMessagePr
eSendEvent
import
net.mamoe.mirai.message.FriendMessageEvent
import
net.mamoe.mirai.message.FriendMessageEvent
import
net.mamoe.mirai.message.MessageReceipt
import
net.mamoe.mirai.message.MessageReceipt
import
net.mamoe.mirai.message.data.Message
import
net.mamoe.mirai.message.data.Message
import
net.mamoe.mirai.message.data.isContentEmpty
import
net.mamoe.mirai.message.data.toMessage
import
net.mamoe.mirai.message.data.toMessage
import
net.mamoe.mirai.message.recall
import
kotlin.jvm.JvmSynthetic
import
kotlin.jvm.JvmSynthetic
/**
/**
...
@@ -55,8 +57,8 @@ abstract class Friend : User(), CoroutineScope {
...
@@ -55,8 +57,8 @@ abstract class Friend : User(), CoroutineScope {
*
*
* 单条消息最大可发送 4500 字符或 50 张图片.
* 单条消息最大可发送 4500 字符或 50 张图片.
*
*
* @see FriendMessage
SendEvent 发送好友信息事件, cancellable
* @see FriendMessage
PreSendEvent 发送消息前事件
* @see
GroupMessageSendEvent 发送群消息事件. cancellable
* @see
FriendMessagePostSendEvent 发送消息后事件
*
*
* @throws EventCancelledException 当发送消息事件被取消时抛出
* @throws EventCancelledException 当发送消息事件被取消时抛出
* @throws BotIsBeingMutedException 发送群消息时若 [Bot] 被禁言抛出
* @throws BotIsBeingMutedException 发送群消息时若 [Bot] 被禁言抛出
...
@@ -69,7 +71,7 @@ abstract class Friend : User(), CoroutineScope {
...
@@ -69,7 +71,7 @@ abstract class Friend : User(), CoroutineScope {
abstract
override
suspend
fun
sendMessage
(
message
:
Message
):
MessageReceipt
<
Friend
>
abstract
override
suspend
fun
sendMessage
(
message
:
Message
):
MessageReceipt
<
Friend
>
@Suppress
(
"INVISIBLE_MEMBER"
,
"INVISIBLE_REFERENCE"
,
"VIRTUAL_MEMBER_HIDDEN"
,
"OVERRIDE_BY_INLINE"
)
@Suppress
(
"INVISIBLE_MEMBER"
,
"INVISIBLE_REFERENCE"
,
"VIRTUAL_MEMBER_HIDDEN"
,
"OVERRIDE_BY_INLINE"
)
@
kotlin
.
internal
.
InlineOnly
// purely virtual
@
kotlin
.
internal
.
InlineOnly
@JvmSynthetic
@JvmSynthetic
suspend
inline
fun
sendMessage
(
message
:
String
):
MessageReceipt
<
Friend
>
{
suspend
inline
fun
sendMessage
(
message
:
String
):
MessageReceipt
<
Friend
>
{
return
sendMessage
(
message
.
toMessage
())
return
sendMessage
(
message
.
toMessage
())
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Group.kt
View file @
6f0853e6
...
@@ -17,12 +17,12 @@ import net.mamoe.mirai.JavaFriendlyAPI
...
@@ -17,12 +17,12 @@ import net.mamoe.mirai.JavaFriendlyAPI
import
net.mamoe.mirai.LowLevelAPI
import
net.mamoe.mirai.LowLevelAPI
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.MessageReceipt
import
net.mamoe.mirai.message.data.Image
import
net.mamoe.mirai.message.data.Image
import
net.mamoe.mirai.message.data.Message
import
net.mamoe.mirai.message.data.Message
import
net.mamoe.mirai.message.data.isContentEmpty
import
net.mamoe.mirai.message.data.toMessage
import
net.mamoe.mirai.message.data.toMessage
import
net.mamoe.mirai.message.recall
import
net.mamoe.mirai.utils.*
import
net.mamoe.mirai.utils.*
import
net.mamoe.mirai.utils.internal.runBlocking
import
net.mamoe.mirai.utils.internal.runBlocking
import
kotlin.jvm.JvmName
import
kotlin.jvm.JvmName
...
@@ -137,8 +137,8 @@ abstract class Group : Contact(), CoroutineScope {
...
@@ -137,8 +137,8 @@ abstract class Group : Contact(), CoroutineScope {
*
*
* 单条消息最大可发送 4500 字符或 50 张图片.
* 单条消息最大可发送 4500 字符或 50 张图片.
*
*
* @see
FriendMessageSendEvent 发送好友信息事件, cancellable
* @see
GroupMessagePreSendEvent 发送消息前事件
* @see GroupMessage
SendEvent 发送群消息事件. cancellable
* @see GroupMessage
PostSendEvent 发送消息后事件
*
*
* @throws EventCancelledException 当发送消息事件被取消时抛出
* @throws EventCancelledException 当发送消息事件被取消时抛出
* @throws BotIsBeingMutedException 发送群消息时若 [Bot] 被禁言抛出
* @throws BotIsBeingMutedException 发送群消息时若 [Bot] 被禁言抛出
...
@@ -154,7 +154,7 @@ abstract class Group : Contact(), CoroutineScope {
...
@@ -154,7 +154,7 @@ abstract class Group : Contact(), CoroutineScope {
* @see sendMessage
* @see sendMessage
*/
*/
@Suppress
(
"INVISIBLE_MEMBER"
,
"INVISIBLE_REFERENCE"
,
"VIRTUAL_MEMBER_HIDDEN"
,
"OVERRIDE_BY_INLINE"
)
@Suppress
(
"INVISIBLE_MEMBER"
,
"INVISIBLE_REFERENCE"
,
"VIRTUAL_MEMBER_HIDDEN"
,
"OVERRIDE_BY_INLINE"
)
@
kotlin
.
internal
.
InlineOnly
// purely virtual
@
kotlin
.
internal
.
InlineOnly
@JvmSynthetic
@JvmSynthetic
suspend
inline
fun
sendMessage
(
message
:
String
):
MessageReceipt
<
Group
>
{
suspend
inline
fun
sendMessage
(
message
:
String
):
MessageReceipt
<
Group
>
{
return
sendMessage
(
message
.
toMessage
())
return
sendMessage
(
message
.
toMessage
())
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Member.kt
View file @
6f0853e6
...
@@ -17,7 +17,12 @@ import net.mamoe.mirai.event.events.*
...
@@ -17,7 +17,12 @@ import net.mamoe.mirai.event.events.*
import
net.mamoe.mirai.getFriendOrNull
import
net.mamoe.mirai.getFriendOrNull
import
net.mamoe.mirai.message.MessageReceipt
import
net.mamoe.mirai.message.MessageReceipt
import
net.mamoe.mirai.message.data.Message
import
net.mamoe.mirai.message.data.Message
import
net.mamoe.mirai.message.data.isContentEmpty
import
net.mamoe.mirai.message.data.toMessage
import
net.mamoe.mirai.message.data.toMessage
import
net.mamoe.mirai.message.recall
import
net.mamoe.mirai.utils.hoursToSeconds
import
net.mamoe.mirai.utils.daysToSeconds
import
net.mamoe.mirai.utils.minutesToSeconds
import
net.mamoe.mirai.utils.WeakRefProperty
import
net.mamoe.mirai.utils.WeakRefProperty
import
kotlin.jvm.JvmSynthetic
import
kotlin.jvm.JvmSynthetic
import
kotlin.time.Duration
import
kotlin.time.Duration
...
@@ -139,8 +144,11 @@ abstract class Member : MemberJavaFriendlyAPI, User() {
...
@@ -139,8 +144,11 @@ abstract class Member : MemberJavaFriendlyAPI, User() {
*
*
* 单条消息最大可发送 4500 字符或 50 张图片.
* 单条消息最大可发送 4500 字符或 50 张图片.
*
*
* @see MessageSendEvent.FriendMessageSendEvent 发送好友信息事件, cancellable
* @see FriendMessagePreSendEvent 当此成员是好友时发送消息前事件
* @see MessageSendEvent.GroupMessageSendEvent 发送群消息事件. cancellable
* @see FriendMessagePostSendEvent 当此成员是好友时发送消息后事件
*
* @see TempMessagePreSendEvent 当此成员不是好友时发送消息前事件
* @see TempMessagePostSendEvent 当此成员不是好友时发送消息后事件
*
*
* @throws EventCancelledException 当发送消息事件被取消时抛出
* @throws EventCancelledException 当发送消息事件被取消时抛出
* @throws BotIsBeingMutedException 发送群消息时若 [Bot] 被禁言抛出
* @throws BotIsBeingMutedException 发送群消息时若 [Bot] 被禁言抛出
...
@@ -156,7 +164,7 @@ abstract class Member : MemberJavaFriendlyAPI, User() {
...
@@ -156,7 +164,7 @@ abstract class Member : MemberJavaFriendlyAPI, User() {
* @see sendMessage
* @see sendMessage
*/
*/
@Suppress
(
"INVISIBLE_MEMBER"
,
"INVISIBLE_REFERENCE"
,
"VIRTUAL_MEMBER_HIDDEN"
,
"OVERRIDE_BY_INLINE"
)
@Suppress
(
"INVISIBLE_MEMBER"
,
"INVISIBLE_REFERENCE"
,
"VIRTUAL_MEMBER_HIDDEN"
,
"OVERRIDE_BY_INLINE"
)
@
kotlin
.
internal
.
InlineOnly
// purely virtual
@
kotlin
.
internal
.
InlineOnly
@JvmSynthetic
@JvmSynthetic
suspend
inline
fun
sendMessage
(
message
:
String
):
MessageReceipt
<
Member
>
{
suspend
inline
fun
sendMessage
(
message
:
String
):
MessageReceipt
<
Member
>
{
return
sendMessage
(
message
.
toMessage
())
return
sendMessage
(
message
.
toMessage
())
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/User.kt
View file @
6f0853e6
...
@@ -13,11 +13,7 @@ package net.mamoe.mirai.contact
...
@@ -13,11 +13,7 @@ package net.mamoe.mirai.contact
import
kotlinx.coroutines.CoroutineScope
import
kotlinx.coroutines.CoroutineScope
import
net.mamoe.mirai.Bot
import
net.mamoe.mirai.Bot
import
net.mamoe.mirai.event.events.BeforeImageUploadEvent
import
net.mamoe.mirai.event.events.*
import
net.mamoe.mirai.event.events.EventCancelledException
import
net.mamoe.mirai.event.events.ImageUploadEvent
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.MessageReceipt
import
net.mamoe.mirai.message.data.Image
import
net.mamoe.mirai.message.data.Image
import
net.mamoe.mirai.message.data.Message
import
net.mamoe.mirai.message.data.Message
...
@@ -58,8 +54,8 @@ abstract class User : Contact(), CoroutineScope {
...
@@ -58,8 +54,8 @@ abstract class User : Contact(), CoroutineScope {
*
*
* 单条消息最大可发送 4500 字符或 50 张图片.
* 单条消息最大可发送 4500 字符或 50 张图片.
*
*
* @see
FriendMessageSendEvent 发送好友信息事件, cancellable
* @see
UserMessagePreSendEvent 发送消息前事件
* @see
GroupMessageSendEvent 发送群消息事件. cancellable
* @see
UserMessagePostSendEvent 发送消息后事件
*
*
* @throws EventCancelledException 当发送消息事件被取消时抛出
* @throws EventCancelledException 当发送消息事件被取消时抛出
* @throws BotIsBeingMutedException 发送群消息时若 [Bot] 被禁言抛出
* @throws BotIsBeingMutedException 发送群消息时若 [Bot] 被禁言抛出
...
@@ -75,7 +71,7 @@ abstract class User : Contact(), CoroutineScope {
...
@@ -75,7 +71,7 @@ abstract class User : Contact(), CoroutineScope {
* @see sendMessage
* @see sendMessage
*/
*/
@Suppress
(
"INVISIBLE_MEMBER"
,
"INVISIBLE_REFERENCE"
,
"VIRTUAL_MEMBER_HIDDEN"
,
"OVERRIDE_BY_INLINE"
)
@Suppress
(
"INVISIBLE_MEMBER"
,
"INVISIBLE_REFERENCE"
,
"VIRTUAL_MEMBER_HIDDEN"
,
"OVERRIDE_BY_INLINE"
)
@
kotlin
.
internal
.
InlineOnly
// purely virtual
@
kotlin
.
internal
.
InlineOnly
@JvmSynthetic
@JvmSynthetic
suspend
inline
fun
sendMessage
(
message
:
String
):
MessageReceipt
<
User
>
{
suspend
inline
fun
sendMessage
(
message
:
String
):
MessageReceipt
<
User
>
{
return
sendMessage
(
message
.
toMessage
())
return
sendMessage
(
message
.
toMessage
())
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/events/message.kt
View file @
6f0853e6
...
@@ -9,7 +9,7 @@
...
@@ -9,7 +9,7 @@
@
file
:
JvmMultifileClass
@
file
:
JvmMultifileClass
@
file
:
JvmName
(
"BotEventsKt"
)
@
file
:
JvmName
(
"BotEventsKt"
)
@
file
:
Suppress
(
"unused"
)
@
file
:
Suppress
(
"unused"
,
"INVISIBLE_MEMBER"
,
"INVISIBLE_REFERENCE"
,
"RESULT_CLASS_IN_RETURN_TYPE"
)
package
net.mamoe.mirai.event.events
package
net.mamoe.mirai.event.events
...
@@ -19,41 +19,253 @@ import net.mamoe.mirai.event.AbstractEvent
...
@@ -19,41 +19,253 @@ import net.mamoe.mirai.event.AbstractEvent
import
net.mamoe.mirai.event.CancellableEvent
import
net.mamoe.mirai.event.CancellableEvent
import
net.mamoe.mirai.event.events.ImageUploadEvent.Failed
import
net.mamoe.mirai.event.events.ImageUploadEvent.Failed
import
net.mamoe.mirai.event.events.ImageUploadEvent.Succeed
import
net.mamoe.mirai.event.events.ImageUploadEvent.Succeed
import
net.mamoe.mirai.message.MessageReceipt
import
net.mamoe.mirai.message.data.Image
import
net.mamoe.mirai.message.data.Image
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.message.data.MessageSource
import
net.mamoe.mirai.qqandroid.network.Packet
import
net.mamoe.mirai.qqandroid.network.Packet
import
net.mamoe.mirai.utils.ExternalImage
import
net.mamoe.mirai.utils.ExternalImage
import
net.mamoe.mirai.utils.PlannedRemoval
import
net.mamoe.mirai.utils.SinceMirai
import
kotlin.internal.InlineOnly
import
kotlin.jvm.JvmMultifileClass
import
kotlin.jvm.JvmMultifileClass
import
kotlin.jvm.JvmName
import
kotlin.jvm.JvmName
import
kotlin.jvm.JvmSynthetic
// region MessagePreSendEvent
/**
/**
* 主动发送消息
* 在发送消息前广播的事件. 可被 [取消][CancellableEvent.cancel].
*
* 此事件总是在 [MessagePostSendEvent] 之前广播.
*
* 当 [MessagePreSendEvent] 被 [取消][CancellableEvent.cancel] 后:
* - [MessagePostSendEvent] 不会广播
* - 消息不会发送.
* - [Contact.sendMessage] 会抛出异常 [EventCancelledException]
*
*
* @see Contact.sendMessage 发送消息. 为广播这个事件的唯一途径
* @see Contact.sendMessage 发送消息. 为广播这个事件的唯一途径
*/
*/
sealed
class
MessageSendEvent
:
BotEvent
,
BotActiveEvent
,
AbstractEvent
()
{
@SinceMirai
(
"1.1.0"
)
sealed
class
MessagePreSendEvent
:
BotEvent
,
BotActiveEvent
,
AbstractEvent
(),
CancellableEvent
{
/** 发信目标. */
abstract
val
target
:
Contact
abstract
val
target
:
Contact
final
override
val
bot
:
Bot
final
override
val
bot
:
Bot
get
()
=
target
.
bot
get
()
=
target
.
bot
data class
GroupMessageSendEvent
internal
constructor
(
/** 待发送的消息. 修改后将会同时应用于发送. */
abstract
var
message
:
Message
}
/**
* 在发送群消息前广播的事件.
* @see MessagePreSendEvent
*/
@SinceMirai
(
"1.1.0"
)
data class
GroupMessagePreSendEvent
internal
constructor
(
/** 发信目标. */
override
val
target
:
Group
,
override
val
target
:
Group
,
var
message
:
MessageChain
/** 待发送的消息. 修改后将会同时应用于发送. */
)
:
MessageSendEvent
(),
CancellableEvent
override
var
message
:
Message
)
:
MessagePreSendEvent
()
data class
FriendMessageSendEvent
internal
constructor
(
/**
* 在发送好友或群临时会话消息前广播的事件.
* @see MessagePreSendEvent
*/
@SinceMirai
(
"1.1.0"
)
sealed
class
UserMessagePreSendEvent
:
MessagePreSendEvent
()
{
/** 发信目标. */
abstract
override
val
target
:
User
}
/**
* 在发送好友消息前广播的事件.
* @see MessagePreSendEvent
*/
@SinceMirai
(
"1.1.0"
)
data class
FriendMessagePreSendEvent
internal
constructor
(
/** 发信目标. */
override
val
target
:
Friend
,
override
val
target
:
Friend
,
var
message
:
MessageChain
/** 待发送的消息. 修改后将会同时应用于发送. */
)
:
MessageSendEvent
(),
CancellableEvent
override
var
message
:
Message
)
:
UserMessagePreSendEvent
()
data class
TempMessageSendEvent
internal
constructor
(
/**
* 在发送群临时会话消息前广播的事件.
* @see MessagePreSendEvent
*/
@SinceMirai
(
"1.1.0"
)
data class
TempMessagePreSendEvent
internal
constructor
(
/** 发信目标. */
override
val
target
:
Member
,
override
val
target
:
Member
,
var
message
:
MessageChain
/** 待发送的消息. 修改后将会同时应用于发送. */
)
:
MessageSendEvent
(),
CancellableEvent
override
var
message
:
Message
)
:
UserMessagePreSendEvent
()
{
val
group
get
()
=
target
.
group
}
}
// endregion
// region MessagePostSendEvent
/**
* 在发送消息后广播的事件, 总是在 [MessagePreSendEvent] 之后广播.
*
* 只要 [MessagePreSendEvent] 未被 [取消][CancellableEvent.cancel], [MessagePostSendEvent] 就一定会被广播, 并携带 [发送时产生的异常][MessagePostSendEvent.exception] (如果有).
*
* 在此事件广播前, 消息一定已经发送成功, 或产生一个异常.
*
* @see Contact.sendMessage 发送消息. 为广播这个事件的唯一途径
* @see MessagePreSendEvent
*/
@SinceMirai
(
"1.1.0"
)
sealed
class
MessagePostSendEvent
<
C
:
Contact
>
:
BotEvent
,
BotActiveEvent
,
AbstractEvent
()
{
/** 发信目标. */
abstract
val
target
:
C
final
override
val
bot
:
Bot
get
()
=
target
.
bot
/** 待发送的消息. 此为 [MessagePreSendEvent.message] 的最终值. */
abstract
val
message
:
MessageChain
/**
* 发送消息时抛出的异常. `null` 表示消息成功发送.
* @see result
*/
abstract
val
exception
:
Throwable
?
/**
* 发送消息成功时的回执. `null` 表示消息发送失败.
* @see result
*/
abstract
val
receipt
:
MessageReceipt
<
C
>?
}
/**
* 获取指代这条已经发送的消息的 [MessageSource]. 若消息发送失败, 返回 `null`
* @see MessagePostSendEvent.sourceResult
*/
@
get
:
JvmSynthetic
@SinceMirai
(
"1.1.0"
)
inline
val
MessagePostSendEvent
<*>.
source
:
MessageSource
?
get
()
=
receipt
?.
source
/**
* 获取指代这条已经发送的消息的 [MessageSource], 并包装为 [kotlin.Result]
* @see MessagePostSendEvent.result
*/
@
get
:
JvmSynthetic
@SinceMirai
(
"1.1.0"
)
inline
val
MessagePostSendEvent
<*>.
sourceResult
:
Result
<
MessageSource
>
get
()
=
result
.
map
{
it
.
source
}
/**
* 在此消息发送成功时返回 `true`.
* @see MessagePostSendEvent.exception
* @see MessagePostSendEvent.result
*/
@
get
:
JvmSynthetic
@SinceMirai
(
"1.1.0"
)
inline
val
MessagePostSendEvent
<*>.
isSuccess
:
Boolean
get
()
=
exception
==
null
/**
* 在此消息发送失败时返回 `true`.
* @see MessagePostSendEvent.exception
* @see MessagePostSendEvent.result
*/
@
get
:
JvmSynthetic
@SinceMirai
(
"1.1.0"
)
inline
val
MessagePostSendEvent
<*>.
isFailure
:
Boolean
get
()
=
exception
!=
null
/**
* 将 [MessagePostSendEvent.exception] 与 [MessagePostSendEvent.receipt] 表示为 [Result]
*/
@InlineOnly
@SinceMirai
(
"1.1.0"
)
inline
val
<
C
:
Contact
>
MessagePostSendEvent
<
C
>.
result
:
Result
<
MessageReceipt
<
C
>>
get
()
=
exception
.
let
{
exception
->
if
(
exception
!=
null
)
Result
.
failure
(
exception
)
else
Result
.
success
(
receipt
!!
)
}
/**
* 在群消息发送后广播的事件.
* @see MessagePostSendEvent
*/
@SinceMirai
(
"1.1.0"
)
data class
GroupMessagePostSendEvent
internal
constructor
(
/** 发信目标. */
override
val
target
:
Group
,
/** 待发送的消息. 此为 [MessagePreSendEvent.message] 的最终值. */
override
val
message
:
MessageChain
,
/**
* 发送消息时抛出的异常. `null` 表示消息成功发送.
* @see result
*/
override
val
exception
:
Throwable
?,
/**
* 发送消息成功时的回执. `null` 表示消息发送失败.
* @see result
*/
override
val
receipt
:
MessageReceipt
<
Group
>?
)
:
MessagePostSendEvent
<
Group
>()
/**
* 在好友或群临时会话消息发送后广播的事件.
* @see MessagePostSendEvent
*/
@SinceMirai
(
"1.1.0"
)
sealed
class
UserMessagePostSendEvent
<
C
:
User
>
:
MessagePostSendEvent
<
C
>()
/**
* 在好友消息发送后广播的事件.
* @see MessagePostSendEvent
*/
@SinceMirai
(
"1.1.0"
)
data class
FriendMessagePostSendEvent
internal
constructor
(
/** 发信目标. */
override
val
target
:
Friend
,
/** 待发送的消息. 此为 [MessagePreSendEvent.message] 的最终值. */
override
val
message
:
MessageChain
,
/**
* 发送消息时抛出的异常. `null` 表示消息成功发送.
* @see result
*/
override
val
exception
:
Throwable
?,
/**
* 发送消息成功时的回执. `null` 表示消息发送失败.
* @see result
*/
override
val
receipt
:
MessageReceipt
<
Friend
>?
)
:
UserMessagePostSendEvent
<
Friend
>()
/**
* 在群临时会话消息发送后广播的事件.
* @see MessagePostSendEvent
*/
@SinceMirai
(
"1.1.0"
)
data class
TempMessagePostSendEvent
internal
constructor
(
/** 发信目标. */
override
val
target
:
Member
,
/** 待发送的消息. 此为 [MessagePreSendEvent.message] 的最终值. */
override
val
message
:
MessageChain
,
/**
* 发送消息时抛出的异常. `null` 表示消息成功发送.
* @see result
*/
override
val
exception
:
Throwable
?,
/**
* 发送消息成功时的回执. `null` 表示消息发送失败.
* @see result
*/
override
val
receipt
:
MessageReceipt
<
Member
>?
)
:
UserMessagePostSendEvent
<
Member
>()
{
val
group
get
()
=
target
.
group
}
// endregion
/**
/**
* 消息撤回事件. 可是任意消息被任意人撤回.
* 消息撤回事件. 可是任意消息被任意人撤回.
*
*
...
@@ -177,3 +389,65 @@ sealed class ImageUploadEvent : BotEvent, BotActiveEvent, AbstractEvent() {
...
@@ -177,3 +389,65 @@ sealed class ImageUploadEvent : BotEvent, BotActiveEvent, AbstractEvent() {
)
:
ImageUploadEvent
()
)
:
ImageUploadEvent
()
}
}
// region deprecated
/**
* 主动发送消息
*
* @see Contact.sendMessage 发送消息. 为广播这个事件的唯一途径
*/
@Suppress
(
"DEPRECATION"
)
@PlannedRemoval
(
"1.3.0"
)
// arise deprecation level to ERROR in 1.2.0.
@Deprecated
(
message
=
"""
以 MessagePreSendEvent 和 MessagePostSendEvent 替换.
"""
,
replaceWith
=
ReplaceWith
(
"MessagePreSendEvent"
,
"net.mamoe.mirai.event.events.MessagePreSendEvent"
),
level
=
DeprecationLevel
.
WARNING
)
sealed
class
MessageSendEvent
:
BotEvent
,
BotActiveEvent
,
AbstractEvent
()
{
abstract
val
target
:
Contact
final
override
val
bot
:
Bot
get
()
=
target
.
bot
@Deprecated
(
message
=
"""
以 GroupMessagePreSendEvent 和 GroupMessagePostSendEvent 替换.
"""
,
replaceWith
=
ReplaceWith
(
"GroupMessagePreSendEvent"
,
"net.mamoe.mirai.event.events.GroupMessagePreSendEvent"
),
level
=
DeprecationLevel
.
WARNING
)
data class
GroupMessageSendEvent
internal
constructor
(
override
val
target
:
Group
,
var
message
:
MessageChain
)
:
MessageSendEvent
(),
CancellableEvent
@Deprecated
(
message
=
"""
以 FriendMessagePreSendEvent 和 FriendMessagePostSendEvent 替换.
"""
,
replaceWith
=
ReplaceWith
(
"FriendMessagePreSendEvent"
,
"net.mamoe.mirai.event.events.FriendMessagePreSendEvent"
),
level
=
DeprecationLevel
.
WARNING
)
data class
FriendMessageSendEvent
internal
constructor
(
override
val
target
:
Friend
,
var
message
:
MessageChain
)
:
MessageSendEvent
(),
CancellableEvent
@Deprecated
(
message
=
"""
以 TempMessagePreSendEvent 和 TempMessagePostSendEvent 替换.
"""
,
replaceWith
=
ReplaceWith
(
"TempMessagePreSendEvent"
,
"net.mamoe.mirai.event.events.TempMessagePreSendEvent"
),
level
=
DeprecationLevel
.
WARNING
)
data class
TempMessageSendEvent
internal
constructor
(
override
val
target
:
Member
,
var
message
:
MessageChain
)
:
MessageSendEvent
(),
CancellableEvent
}
// endregion
\ 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