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
Expand all
Hide 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
import
net.mamoe.mirai.message.MessageReceipt
import
net.mamoe.mirai.message.data.Image
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.qqandroid.QQAndroidBot
import
net.mamoe.mirai.qqandroid.network.highway.postImage
...
...
@@ -87,7 +88,11 @@ internal class FriendImpl(
@Suppress
(
"DuplicatedCode"
)
override
suspend
fun
sendMessage
(
message
:
Message
):
MessageReceipt
<
Friend
>
{
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
)
}
}
...
...
@@ -101,65 +106,64 @@ internal class FriendImpl(
if
(
BeforeImageUploadEvent
(
this
,
image
).
broadcast
().
isCancelled
)
{
throw
EventCancelledException
(
"cancelled by BeforeImageUploadEvent.ToGroup"
)
}
bot
.
network
.
run
{
val
response
=
LongConn
.
OffPicUp
(
val
response
=
bot
.
network
.
run
{
LongConn
.
OffPicUp
(
bot
.
client
,
Cmd0x352
.
TryUpImgReq
(
srcUin
=
bot
.
id
.
toInt
(),
dstUin
=
id
.
toInt
(),
fileId
=
0
,
fileMd5
=
@Suppress
(
"INVISIBLE_MEMBER"
)
image
.
md5
,
fileSize
=
@Suppress
(
"INVISIBLE_MEMBER"
)
image
.
input
.
size
.
toInt
(),
fileName
=
@Suppress
(
"INVISIBLE_MEMBER"
)
image
.
md5
.
toUHexString
(
""
)
+
"."
+
ExternalImage
.
defaultFormatName
,
fileMd5
=
image
.
md5
,
fileSize
=
image
.
input
.
size
.
toInt
(),
fileName
=
image
.
md5
.
toUHexString
(
""
)
+
"."
+
ExternalImage
.
defaultFormatName
,
imgOriginal
=
1
)
).
sendAndExpect
<
LongConn
.
OffPicUp
.
Response
>()
}
@Suppress
(
"UNCHECKED_CAST"
,
"DEPRECATION"
,
"INVISIBLE_MEMBER
"
)
return
when
(
response
)
{
is
LongConn
.
OffPicUp
.
Response
.
FileExists
->
net
.
mamoe
.
mirai
.
message
.
data
.
OfflineFriendImage
(
response
.
resourceId
)
.
also
{
ImageUploadEvent
.
Succeed
(
this
@FriendImpl
,
image
,
it
).
broadcast
()
}
is
LongConn
.
OffPicUp
.
Response
.
RequireUpload
->
{
bot
.
network
.
logger
.
verbose
{
"[Http] Uploading friend image, size=${image.input.size.sizeToString()}"
}
@Suppress
(
"UNCHECKED_CAST"
,
"DEPRECATION
"
)
when
(
response
)
{
is
LongConn
.
OffPicUp
.
Response
.
FileExists
->
OfflineFriendImage
(
response
.
resourceId
)
.
also
{
ImageUploadEvent
.
Succeed
(
this
@FriendImpl
,
image
,
it
).
broadcast
()
}
is
LongConn
.
OffPicUp
.
Response
.
RequireUpload
->
{
bot
.
network
.
logger
.
verbose
{
"[Http] Uploading friend image, size=${image.input.size.sizeToString()}"
}
val
time
=
measureTime
{
MiraiPlatformUtils
.
Http
.
postImage
(
"0x6ff0070"
,
bot
.
id
,
null
,
imageInput
=
image
.
input
,
uKeyHex
=
response
.
uKey
.
toUHexString
(
""
)
)
}
val
time
=
measureTime
{
MiraiPlatformUtils
.
Http
.
postImage
(
"0x6ff0070"
,
bot
.
id
,
null
,
imageInput
=
image
.
input
,
uKeyHex
=
response
.
uKey
.
toUHexString
(
""
)
)
}
bot
.
network
.
logger
.
verbose
{
"[Http] Uploading friend image: succeed at ${(image.input.size.toDouble() / 1024 / time.inSeconds).roundToInt()} KiB/s"
}
bot
.
network
.
logger
.
verbose
{
"[Http] Uploading friend image: succeed at ${(image.input.size.toDouble() / 1024 / time.inSeconds).roundToInt()} KiB/s"
}
/*
HighwayHelper.uploadImageToServers(
bot,
response.serverIp.zip(response.serverPort),
response.uKey,
image,
kind = "friend",
commandId = 1
)*/
// 为什么不能 ??
/*
HighwayHelper.uploadImageToServers(
bot,
response.serverIp.zip(response.serverPort),
response.uKey,
image,
kind = "friend",
commandId = 1
)*/
// 为什么不能 ??
return
net
.
mamoe
.
mirai
.
message
.
data
.
OfflineFriendImage
(
response
.
resourceId
).
also
{
ImageUploadEvent
.
Succeed
(
this
@FriendImpl
,
image
,
it
).
broadcast
()
}
}
is
LongConn
.
OffPicUp
.
Response
.
Failed
->
{
ImageUploadEvent
.
Failed
(
this
@FriendImpl
,
image
,
-
1
,
response
.
message
).
broadcast
()
error
(
response
.
message
)
OfflineFriendImage
(
response
.
resourceId
).
also
{
ImageUploadEvent
.
Succeed
(
this
@FriendImpl
,
image
,
it
).
broadcast
()
}
}
is
LongConn
.
OffPicUp
.
Response
.
Failed
->
{
ImageUploadEvent
.
Failed
(
this
@FriendImpl
,
image
,
-
1
,
response
.
message
).
broadcast
()
error
(
response
.
message
)
}
}
}
finally
{
@Suppress
(
"INVISIBLE_MEMBER"
,
"INVISIBLE_REFERENCE"
)
...
...
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
import
net.mamoe.mirai.data.MemberInfo
import
net.mamoe.mirai.event.broadcast
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.data.*
import
net.mamoe.mirai.qqandroid.QQAndroidBot
...
...
@@ -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.image.ImgStore
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.utils.estimateLength
import
net.mamoe.mirai.utils.*
...
...
@@ -304,94 +304,92 @@ internal class GroupImpl(
check
(
message
.
nodeList
.
size
<
200
)
{
throw
MessageTooLargeException
(
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
)
}
val
msg
:
MessageChain
if
(
message
!
is
LongMessage
&&
message
!
is
ForwardMessageInternal
)
{
val
event
=
GroupMessageSendEvent
(
this
,
message
.
asMessageChain
()).
broadcast
()
if
(
event
.
isCancelled
)
{
throw
EventCancelledException
(
"cancelled by GroupMessageSendEvent"
)
}
val
msg
:
MessageChain
=
if
(
message
!
is
LongMessage
&&
message
!
is
ForwardMessageInternal
)
{
val
chain
=
kotlin
.
runCatching
{
GroupMessagePreSendEvent
(
this
,
message
).
broadcast
()
}.
onSuccess
{
check
(!
it
.
isCancelled
)
{
throw
EventCancelledException
(
"cancelled by GroupMessagePreSendEvent"
)
}
}.
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
// 通过下方逻辑短路延迟计算
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
(
this
,
message
,
event
.
message
,
"message(${event.message.joinToString(
""
,
limit
=
10
)})
is
too
large
.
Allow
up
to
50
images
or
5000
chars
"
this
,
message
,
chain
,
"message(${chain.joinToString("", limit = 10)}) is too large. Allow up to 50 images or 5000 chars"
)
}
if
(
length
>
702
||
imageCnt
>
2
)
{
return
bot
.
lowLevelSendGroupLongOrForwardMessage
(
this
.
id
,
listOf
(
ForwardMessage
.
Node
(
senderId
=
bot
.
id
,
time
=
currentTimeSeconds
.
toInt
(),
message
=
event
.
message
,
senderName
=
bot
.
nick
)
return
bot
.
lowLevelSendGroupLongOrForwardMessage
(
this
.
id
,
listOf
(
ForwardMessage
.
Node
(
senderId
=
bot
.
id
,
time
=
currentTimeSeconds
.
toInt
(),
message
=
chain
,
senderName
=
bot
.
nick
)
),
true
,
null
)
true
,
null
)
}
chain
}
else
message
.
asMessageChain
()
msg
=
event
.
message
}
else
msg
=
message
.
asMessageChain
()
msg
.
firstIsInstanceOrNull
<
QuoteReply
>()
?.
source
?.
ensureSequenceIdAvailable
()
lateinit
var
source
:
MessageSourceToGroupImpl
bot
.
network
.
run
{
val
response
:
MessageSvcPbSendMsg
.
Response
=
MessageSvcPbSendMsg
.
createToGroup
(
val
result
=
bot
.
network
.
runCatching
{
val
source
:
MessageSourceToGroupImpl
MessageSvcPbSendMsg
.
createToGroup
(
bot
.
client
,
this
@GroupImpl
,
msg
,
isForward
)
{
source
=
it
}.
sendAndExpect
()
if
(
response
is
MessageSvcPbSendMsg
.
Response
.
Failed
)
{
when
(
response
.
resultType
)
{
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"
)
}.
sendAndExpect
<
MessageSvcPbSendMsg
.
Response
>().
let
{
check
(
it
is
MessageSvcPbSendMsg
.
Response
.
SUCCESS
)
{
"Send temp message failed: $it"
}
}
}
try
{
source
.
ensureSequenceIdAvailable
()
}
catch
(
e
:
Exception
)
{
bot
.
network
.
logger
.
warning
{
"Timeout awaiting sequenceId for group message(${message.contentToString()
.
take
(
10
)}).
Some
features
may
not
work
properly
"
try
{
source
.
ensureSequenceIdAvailable
()
}
catch
(
e
:
Exception
)
{
bot
.
network
.
logger
.
warning
{
"Timeout awaiting sequenceId for group message(${message.contentToString()
.
take
(
10
)}).
Some
features
may
not
work
properly
"
}
bot
.
network
.
logger
.
warning
(
e
)
}
bot
.
network
.
logger
.
warning
(
e
)
MessageReceipt
(
source
,
this
@GroupImpl
,
botAsMember
)
}
return
MessageReceipt
(
source
,
this
,
botAsMember
)
result
.
fold
(
onSuccess
=
{
GroupMessagePostSendEvent
(
this
,
msg
,
null
,
it
)
},
onFailure
=
{
GroupMessagePostSendEvent
(
this
,
msg
,
it
,
null
)
}
).
broadcast
()
return
result
.
getOrThrow
()
}
@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
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.receive.MessageSvcPbSendMsg
import
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.createToTemp
import
net.mamoe.mirai.utils.ExternalImage
import
net.mamoe.mirai.utils.currentTimeSeconds
import
net.mamoe.mirai.utils.getValue
...
...
@@ -54,34 +55,59 @@ internal class MemberImpl constructor(
override
val
id
:
Long
=
qq
.
id
override
val
nick
:
String
=
qq
.
nick
@Suppress
(
"UNCHECKED_CAST"
)
@JvmSynthetic
override
suspend
fun
sendMessage
(
message
:
Message
):
MessageReceipt
<
Member
>
{
require
(
message
.
isContentNotEmpty
())
{
"message is empty"
}
return
(
this
.
asFriendOrNull
()
?.
sendMessageImpl
(
this
,
message
)
?:
sendMessageImpl
(
message
))
.
also
{
logMessageSent
(
message
)
}
val
asFriend
=
this
.
asFriendOrNull
()
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
>
{
val
event
=
MessageSendEvent
.
TempMessageSendEvent
(
this
,
message
.
asMessageChain
()).
broadcast
()
if
(
event
.
isCancelled
)
{
throw
EventCancelledException
(
"cancelled by TempMessageSendEvent"
)
}
event
.
message
.
firstIsInstanceOrNull
<
QuoteReply
>()
?.
source
?.
ensureSequenceIdAvailable
()
val
chain
=
kotlin
.
runCatching
{
TempMessagePreSendEvent
(
this
,
message
).
broadcast
()
}.
onSuccess
{
check
(!
it
.
isCancelled
)
{
throw
EventCancelledException
(
"cancelled by TempMessagePreSendEvent"
)
}
}.
getOrElse
{
throw
EventCancelledException
(
"exception thrown when broadcasting TempMessagePreSendEvent"
,
it
)
}.
message
.
asMessageChain
()
lateinit
var
source
:
MessageSourceToTempImpl
bot
.
network
.
run
{
check
(
MessageSvcPbSendMsg
.
createToTemp
(
bot
.
client
,
this
@MemberImpl
,
message
.
asMessageChain
()
)
{
source
=
it
}.
sendAndExpect
<
MessageSvcPbSendMsg
.
Response
>()
is
MessageSvcPbSendMsg
.
Response
.
SUCCESS
)
{
"send message failed"
}
chain
.
firstIsInstanceOrNull
<
QuoteReply
>()
?.
source
?.
ensureSequenceIdAvailable
()
val
result
=
bot
.
network
.
runCatching
{
val
source
:
MessageSourceToTempImpl
MessageSvcPbSendMsg
.
createToTemp
(
bot
.
client
,
this
@MemberImpl
,
chain
)
{
source
=
it
}.
sendAndExpect
<
MessageSvcPbSendMsg
.
Response
>().
let
{
check
(
it
is
MessageSvcPbSendMsg
.
Response
.
SUCCESS
)
{
"Send temp message failed: $it"
}
}
MessageReceipt
(
source
,
this
@MemberImpl
,
null
)
}
return
MessageReceipt
(
source
,
this
,
null
)
result
.
fold
(
onSuccess
=
{
TempMessagePostSendEvent
(
this
,
chain
,
null
,
it
)
},
onFailure
=
{
TempMessagePostSendEvent
(
this
,
chain
,
it
,
null
)
}
).
broadcast
()
return
result
.
getOrThrow
()
}
@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
import
net.mamoe.mirai.contact.Contact
import
net.mamoe.mirai.contact.Friend
import
net.mamoe.mirai.contact.User
import
net.mamoe.mirai.event.broadcast
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.data.Message
import
net.mamoe.mirai.message.data.QuoteReply
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.message.MessageSourceToFriendImpl
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.createToFriend
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
>
{
val
event
=
MessageSendEvent
.
FriendMessageSendEvent
(
this
,
message
.
asMessageChain
()).
broadcast
()
if
(
event
.
isCancelled
)
{
throw
EventCancelledException
(
"cancelled by FriendMessageSendEvent"
)
}
event
.
message
.
firstIsInstanceOrNull
<
QuoteReply
>()
?.
source
?.
ensureSequenceIdAvailable
()
lateinit
var
source
:
MessageSourceToFriendImpl
internal
suspend
fun
<
T
:
User
>
Friend
.
sendMessageImpl
(
message
:
Message
,
friendReceiptConstructor
:
(
MessageSourceToFriendImpl
)
->
MessageReceipt
<
Friend
>,
tReceiptConstructor
:
(
MessageSourceToFriendImpl
)
->
MessageReceipt
<
T
>
):
MessageReceipt
<
T
>
{
contract
{
callsInPlace
(
friendReceiptConstructor
,
InvocationKind
.
EXACTLY_ONCE
)
}
val
bot
=
bot
.
asQQAndroidBot
()
bot
.
network
.
run
{
check
(
MessageSvcPbSendMsg
.
createToFriend
(
bot
.
asQQAndroidBot
().
client
,
this
@
sendMessageImpl
,
event
.
message
)
{
source
=
it
}.
sendAndExpect
<
MessageSvcPbSendMsg
.
Response
>()
is
MessageSvcPbSendMsg
.
Response
.
SUCCESS
)
{
"send message failed"
}
val
chain
=
kotlin
.
runCatching
{
FriendMessagePreSendEvent
(
this
,
message
).
broadcast
()
}.
onSuccess
{
check
(!
it
.
isCancelled
)
{
throw
EventCancelledException
(
"cancelled by FriendMessagePreSendEvent"
)
}
}.
getOrElse
{
throw
EventCancelledException
(
"exception thrown when broadcasting FriendMessagePreSendEvent"
,
it
)
}.
message
.
asMessageChain
()
chain
.
firstIsInstanceOrNull
<
QuoteReply
>()
?.
source
?.
ensureSequenceIdAvailable
()
lateinit
var
source
:
MessageSourceToFriendImpl
val
result
=
bot
.
network
.
runCatching
{
MessageSvcPbSendMsg
.
createToFriend
(
bot
.
client
,
this
@
sendMessageImpl
,
chain
)
{
source
=
it
}.
sendAndExpect
<
MessageSvcPbSendMsg
.
Response
>().
let
{
check
(
it
is
MessageSvcPbSendMsg
.
Response
.
SUCCESS
)
{
"Send temp message failed: $it"
}
}
friendReceiptConstructor
(
source
)
}
return
MessageReceipt
(
source
,
generic
,
null
)
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
)
{
...
...
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
import
net.mamoe.mirai.qqandroid.utils.io.serialization.toByteArray
import
net.mamoe.mirai.qqandroid.utils.io.serialization.writeProtoBuf
import
net.mamoe.mirai.utils.currentTimeSeconds
import
kotlin.contracts.InvocationKind
import
kotlin.contracts.contract
import
kotlin.math.absoluteValue
import
kotlin.random.Random
...
...
@@ -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"
)
private
fun
createToFriend
(
internal
fun
createToFriendImpl
(
client
:
QQAndroidClient
,
toUin
:
Long
,
message
:
MessageChain
,
...
...
@@ -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
,
groupUin
:
Long
,
toUin
:
Long
,
...
...
@@ -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"
)
private
fun
createToGroup
(
internal
fun
createToGroupImpl
(
client
:
QQAndroidClient
,
groupCode
:
Long
,
message
:
MessageChain
,
...
...
@@ -231,7 +161,91 @@ internal object MessageSvcPbSendMsg : OutgoingPacketFactory<MessageSvcPbSendMsg.
Response
.
Failed
(
response
.
result
,
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
import
kotlinx.coroutines.Job
import
net.mamoe.mirai.Bot
import
net.mamoe.mirai.JavaFriendlyAPI
import
net.mamoe.mirai.event.events.BeforeImageUploadEvent
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.event.events.*
import
net.mamoe.mirai.message.MessageReceipt
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.recallIn
import
net.mamoe.mirai.utils.ExternalImage
...
...
@@ -57,8 +55,8 @@ abstract class Contact : ContactOrBot, CoroutineScope, ContactJavaFriendlyAPI {
*
* 单条消息最大可发送 4500 字符或 50 张图片.
*
* @see
FriendMessageSendEvent 发送好友信息事件, cancellable
* @see
GroupMessageSendEvent 发送群消息事件. cancellable
* @see
MessagePreSendEvent 发送消息前事件
* @see
MessagePostSendEvent 发送消息后事件
*
* @throws EventCancelledException 当发送消息事件被取消时抛出
* @throws BotIsBeingMutedException 发送群消息时若 [Bot] 被禁言抛出
...
...
@@ -71,7 +69,7 @@ abstract class Contact : ContactOrBot, CoroutineScope, ContactJavaFriendlyAPI {
abstract
suspend
fun
sendMessage
(
message
:
Message
):
MessageReceipt
<
Contact
>
@Suppress
(
"INVISIBLE_MEMBER"
,
"INVISIBLE_REFERENCE"
,
"VIRTUAL_MEMBER_HIDDEN"
,
"OVERRIDE_BY_INLINE"
)
@
kotlin
.
internal
.
InlineOnly
// purely virtual
@
kotlin
.
internal
.
InlineOnly
@JvmSynthetic
suspend
inline
fun
sendMessage
(
message
:
String
):
MessageReceipt
<
Contact
>
{
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
import
kotlinx.coroutines.CoroutineScope
import
net.mamoe.mirai.Bot
import
net.mamoe.mirai.event.events.EventCancelledException
import
net.mamoe.mirai.event.events.
MessageSendEvent.FriendMessage
SendEvent
import
net.mamoe.mirai.event.events.
MessageSendEvent.GroupMessag
eSendEvent
import
net.mamoe.mirai.event.events.
FriendMessagePost
SendEvent
import
net.mamoe.mirai.event.events.
FriendMessagePr
eSendEvent
import
net.mamoe.mirai.message.FriendMessageEvent
import
net.mamoe.mirai.message.MessageReceipt
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.recall
import
kotlin.jvm.JvmSynthetic
/**
...
...
@@ -55,8 +57,8 @@ abstract class Friend : User(), CoroutineScope {
*
* 单条消息最大可发送 4500 字符或 50 张图片.
*
* @see FriendMessage
SendEvent 发送好友信息事件, cancellable
* @see
GroupMessageSendEvent 发送群消息事件. cancellable
* @see FriendMessage
PreSendEvent 发送消息前事件
* @see
FriendMessagePostSendEvent 发送消息后事件
*
* @throws EventCancelledException 当发送消息事件被取消时抛出
* @throws BotIsBeingMutedException 发送群消息时若 [Bot] 被禁言抛出
...
...
@@ -69,7 +71,7 @@ abstract class Friend : User(), CoroutineScope {
abstract
override
suspend
fun
sendMessage
(
message
:
Message
):
MessageReceipt
<
Friend
>
@Suppress
(
"INVISIBLE_MEMBER"
,
"INVISIBLE_REFERENCE"
,
"VIRTUAL_MEMBER_HIDDEN"
,
"OVERRIDE_BY_INLINE"
)
@
kotlin
.
internal
.
InlineOnly
// purely virtual
@
kotlin
.
internal
.
InlineOnly
@JvmSynthetic
suspend
inline
fun
sendMessage
(
message
:
String
):
MessageReceipt
<
Friend
>
{
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
import
net.mamoe.mirai.LowLevelAPI
import
net.mamoe.mirai.data.MemberInfo
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.Image
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.recall
import
net.mamoe.mirai.utils.*
import
net.mamoe.mirai.utils.internal.runBlocking
import
kotlin.jvm.JvmName
...
...
@@ -137,8 +137,8 @@ abstract class Group : Contact(), CoroutineScope {
*
* 单条消息最大可发送 4500 字符或 50 张图片.
*
* @see
FriendMessageSendEvent 发送好友信息事件, cancellable
* @see GroupMessage
SendEvent 发送群消息事件. cancellable
* @see
GroupMessagePreSendEvent 发送消息前事件
* @see GroupMessage
PostSendEvent 发送消息后事件
*
* @throws EventCancelledException 当发送消息事件被取消时抛出
* @throws BotIsBeingMutedException 发送群消息时若 [Bot] 被禁言抛出
...
...
@@ -154,7 +154,7 @@ abstract class Group : Contact(), CoroutineScope {
* @see sendMessage
*/
@Suppress
(
"INVISIBLE_MEMBER"
,
"INVISIBLE_REFERENCE"
,
"VIRTUAL_MEMBER_HIDDEN"
,
"OVERRIDE_BY_INLINE"
)
@
kotlin
.
internal
.
InlineOnly
// purely virtual
@
kotlin
.
internal
.
InlineOnly
@JvmSynthetic
suspend
inline
fun
sendMessage
(
message
:
String
):
MessageReceipt
<
Group
>
{
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.*
import
net.mamoe.mirai.getFriendOrNull
import
net.mamoe.mirai.message.MessageReceipt
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.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
kotlin.jvm.JvmSynthetic
import
kotlin.time.Duration
...
...
@@ -139,8 +144,11 @@ abstract class Member : MemberJavaFriendlyAPI, User() {
*
* 单条消息最大可发送 4500 字符或 50 张图片.
*
* @see MessageSendEvent.FriendMessageSendEvent 发送好友信息事件, cancellable
* @see MessageSendEvent.GroupMessageSendEvent 发送群消息事件. cancellable
* @see FriendMessagePreSendEvent 当此成员是好友时发送消息前事件
* @see FriendMessagePostSendEvent 当此成员是好友时发送消息后事件
*
* @see TempMessagePreSendEvent 当此成员不是好友时发送消息前事件
* @see TempMessagePostSendEvent 当此成员不是好友时发送消息后事件
*
* @throws EventCancelledException 当发送消息事件被取消时抛出
* @throws BotIsBeingMutedException 发送群消息时若 [Bot] 被禁言抛出
...
...
@@ -156,7 +164,7 @@ abstract class Member : MemberJavaFriendlyAPI, User() {
* @see sendMessage
*/
@Suppress
(
"INVISIBLE_MEMBER"
,
"INVISIBLE_REFERENCE"
,
"VIRTUAL_MEMBER_HIDDEN"
,
"OVERRIDE_BY_INLINE"
)
@
kotlin
.
internal
.
InlineOnly
// purely virtual
@
kotlin
.
internal
.
InlineOnly
@JvmSynthetic
suspend
inline
fun
sendMessage
(
message
:
String
):
MessageReceipt
<
Member
>
{
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
import
kotlinx.coroutines.CoroutineScope
import
net.mamoe.mirai.Bot
import
net.mamoe.mirai.event.events.BeforeImageUploadEvent
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.event.events.*
import
net.mamoe.mirai.message.MessageReceipt
import
net.mamoe.mirai.message.data.Image
import
net.mamoe.mirai.message.data.Message
...
...
@@ -58,8 +54,8 @@ abstract class User : Contact(), CoroutineScope {
*
* 单条消息最大可发送 4500 字符或 50 张图片.
*
* @see
FriendMessageSendEvent 发送好友信息事件, cancellable
* @see
GroupMessageSendEvent 发送群消息事件. cancellable
* @see
UserMessagePreSendEvent 发送消息前事件
* @see
UserMessagePostSendEvent 发送消息后事件
*
* @throws EventCancelledException 当发送消息事件被取消时抛出
* @throws BotIsBeingMutedException 发送群消息时若 [Bot] 被禁言抛出
...
...
@@ -75,7 +71,7 @@ abstract class User : Contact(), CoroutineScope {
* @see sendMessage
*/
@Suppress
(
"INVISIBLE_MEMBER"
,
"INVISIBLE_REFERENCE"
,
"VIRTUAL_MEMBER_HIDDEN"
,
"OVERRIDE_BY_INLINE"
)
@
kotlin
.
internal
.
InlineOnly
// purely virtual
@
kotlin
.
internal
.
InlineOnly
@JvmSynthetic
suspend
inline
fun
sendMessage
(
message
:
String
):
MessageReceipt
<
User
>
{
return
sendMessage
(
message
.
toMessage
())
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/events/message.kt
View file @
6f0853e6
This diff is collapsed.
Click to expand it.
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