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
f7040c18
Commit
f7040c18
authored
Mar 29, 2020
by
Him188
Committed by
GitHub
Mar 29, 2020
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #170 from mamoe/long-message
Support long message in general `sendMessage`
parents
6b332a73
2f063987
Changes
43
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
43 changed files
with
282 additions
and
373 deletions
+282
-373
mirai-core-qqandroid/src/androidMain/kotlin/net/mamoe/mirai/qqandroid/utils/cryptor/ECDHAndroid.kt
...in/net/mamoe/mirai/qqandroid/utils/cryptor/ECDHAndroid.kt
+2
-2
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.kt
...mmonMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.kt
+20
-32
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/GroupImpl.kt
...ain/kotlin/net/mamoe/mirai/qqandroid/contact/GroupImpl.kt
+14
-4
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/MemberImpl.kt
...in/kotlin/net/mamoe/mirai/qqandroid/contact/MemberImpl.kt
+2
-0
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/QQImpl.kt
...onMain/kotlin/net/mamoe/mirai/qqandroid/contact/QQImpl.kt
+22
-6
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/message/MessageSourceImpl.kt
...in/net/mamoe/mirai/qqandroid/message/MessageSourceImpl.kt
+3
-1
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/message/messages.kt
...Main/kotlin/net/mamoe/mirai/qqandroid/message/messages.kt
+27
-149
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/PacketFactory.kt
.../mirai/qqandroid/network/protocol/packet/PacketFactory.kt
+10
-27
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/MultiMsg.kt
.../mirai/qqandroid/network/protocol/packet/chat/MultiMsg.kt
+13
-99
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
+28
-18
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/utils/cryptor/ECDH.kt
...in/kotlin/net/mamoe/mirai/qqandroid/utils/cryptor/ECDH.kt
+5
-5
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/utils/cryptor/TEA.kt
...ain/kotlin/net/mamoe/mirai/qqandroid/utils/cryptor/TEA.kt
+2
-2
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/utils/io/output.kt
...nMain/kotlin/net/mamoe/mirai/qqandroid/utils/io/output.kt
+8
-10
mirai-core-qqandroid/src/jvmMain/kotlin/net/mamoe/mirai/qqandroid/utils/cryptor/ECDHJvm.kt
...kotlin/net/mamoe/mirai/qqandroid/utils/cryptor/ECDHJvm.kt
+2
-2
mirai-core/src/androidMain/kotlin/net/mamoe/mirai/Bot.kt
mirai-core/src/androidMain/kotlin/net/mamoe/mirai/Bot.kt
+2
-0
mirai-core/src/androidMain/kotlin/net/mamoe/mirai/BotJavaFriendlyAPI.kt
.../androidMain/kotlin/net/mamoe/mirai/BotJavaFriendlyAPI.kt
+4
-0
mirai-core/src/androidMain/kotlin/net/mamoe/mirai/contact/Contact.kt
...src/androidMain/kotlin/net/mamoe/mirai/contact/Contact.kt
+2
-0
mirai-core/src/androidMain/kotlin/net/mamoe/mirai/contact/ContactJavaFriendlyAPI.kt
.../kotlin/net/mamoe/mirai/contact/ContactJavaFriendlyAPI.kt
+2
-0
mirai-core/src/androidMain/kotlin/net/mamoe/mirai/contact/Group.kt
...e/src/androidMain/kotlin/net/mamoe/mirai/contact/Group.kt
+2
-0
mirai-core/src/androidMain/kotlin/net/mamoe/mirai/contact/Member.kt
.../src/androidMain/kotlin/net/mamoe/mirai/contact/Member.kt
+2
-0
mirai-core/src/androidMain/kotlin/net/mamoe/mirai/contact/QQ.kt
...core/src/androidMain/kotlin/net/mamoe/mirai/contact/QQ.kt
+2
-0
mirai-core/src/androidMain/kotlin/net/mamoe/mirai/message/MessageReceipt.kt
...roidMain/kotlin/net/mamoe/mirai/message/MessageReceipt.kt
+7
-2
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt
+11
-0
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt
.../src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt
+2
-0
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Group.kt
...re/src/commonMain/kotlin/net.mamoe.mirai/contact/Group.kt
+2
-0
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Member.kt
...e/src/commonMain/kotlin/net.mamoe.mirai/contact/Member.kt
+2
-0
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/QQ.kt
...-core/src/commonMain/kotlin/net.mamoe.mirai/contact/QQ.kt
+2
-0
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/lowLevelApi.kt
...core/src/commonMain/kotlin/net.mamoe.mirai/lowLevelApi.kt
+3
-1
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/MessagePacket.kt
...ommonMain/kotlin/net.mamoe.mirai/message/MessagePacket.kt
+2
-1
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/MessageReceipt.kt
...mmonMain/kotlin/net.mamoe.mirai/message/MessageReceipt.kt
+15
-1
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/Image.kt
...c/commonMain/kotlin/net.mamoe.mirai/message/data/Image.kt
+3
-3
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/MessageChain.kt
...nMain/kotlin/net.mamoe.mirai/message/data/MessageChain.kt
+13
-3
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/MessageSource.kt
...Main/kotlin/net.mamoe.mirai/message/data/MessageSource.kt
+20
-2
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/QuoteReply.kt
...monMain/kotlin/net.mamoe.mirai/message/data/QuoteReply.kt
+4
-1
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/Bot.kt
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/Bot.kt
+2
-0
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/BotJavaFriendlyAPI.kt
.../src/jvmMain/kotlin/net/mamoe/mirai/BotJavaFriendlyAPI.kt
+4
-0
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/contact/Contact.kt
...ore/src/jvmMain/kotlin/net/mamoe/mirai/contact/Contact.kt
+2
-0
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/contact/ContactJavaFriendlyAPI.kt
.../kotlin/net/mamoe/mirai/contact/ContactJavaFriendlyAPI.kt
+2
-0
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/contact/Group.kt
...-core/src/jvmMain/kotlin/net/mamoe/mirai/contact/Group.kt
+2
-0
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/contact/Member.kt
...core/src/jvmMain/kotlin/net/mamoe/mirai/contact/Member.kt
+2
-0
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/contact/QQ.kt
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/contact/QQ.kt
+2
-0
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/message/MessageReceipt.kt
.../jvmMain/kotlin/net/mamoe/mirai/message/MessageReceipt.kt
+5
-1
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/message/SendImageUtilsJvm.kt
...mMain/kotlin/net/mamoe/mirai/message/SendImageUtilsJvm.kt
+1
-1
No files found.
mirai-core-qqandroid/src/androidMain/kotlin/net/mamoe/mirai/qqandroid/utils/cryptor/ECDHAndroid.kt
View file @
f7040c18
...
@@ -32,9 +32,9 @@ internal actual class ECDHKeyPairImpl(
...
@@ -32,9 +32,9 @@ internal actual class ECDHKeyPairImpl(
}
}
@Suppress
(
"FunctionName"
)
@Suppress
(
"FunctionName"
)
actual
fun
ECDH
()
=
ECDH
(
ECDH
.
generateKeyPair
())
internal
actual
fun
ECDH
()
=
ECDH
(
ECDH
.
generateKeyPair
())
actual
class
ECDH
actual
constructor
(
actual
val
keyPair
:
ECDHKeyPair
)
{
internal
actual
class
ECDH
actual
constructor
(
actual
val
keyPair
:
ECDHKeyPair
)
{
actual
companion
object
{
actual
companion
object
{
@Suppress
(
"ObjectPropertyName"
)
@Suppress
(
"ObjectPropertyName"
)
private
var
_isECDHAvailable
:
Boolean
=
false
// because `runCatching` has no contract.
private
var
_isECDHAvailable
:
Boolean
=
false
// because `runCatching` has no contract.
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.kt
View file @
f7040c18
...
@@ -7,6 +7,8 @@
...
@@ -7,6 +7,8 @@
* https://github.com/mamoe/mirai/blob/master/LICENSE
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
*/
@
file
:
Suppress
(
"EXPERIMENTAL_API_USAGE"
)
package
net.mamoe.mirai.qqandroid
package
net.mamoe.mirai.qqandroid
import
io.ktor.client.HttpClient
import
io.ktor.client.HttpClient
...
@@ -29,12 +31,12 @@ import net.mamoe.mirai.contact.*
...
@@ -29,12 +31,12 @@ import net.mamoe.mirai.contact.*
import
net.mamoe.mirai.data.*
import
net.mamoe.mirai.data.*
import
net.mamoe.mirai.event.broadcast
import
net.mamoe.mirai.event.broadcast
import
net.mamoe.mirai.event.events.MessageRecallEvent
import
net.mamoe.mirai.event.events.MessageRecallEvent
import
net.mamoe.mirai.message.MessageReceipt
import
net.mamoe.mirai.message.data.*
import
net.mamoe.mirai.message.data.*
import
net.mamoe.mirai.qqandroid.contact.MemberInfoImpl
import
net.mamoe.mirai.qqandroid.contact.MemberInfoImpl
import
net.mamoe.mirai.qqandroid.contact.QQImpl
import
net.mamoe.mirai.qqandroid.contact.QQImpl
import
net.mamoe.mirai.qqandroid.contact.checkIsGroupImpl
import
net.mamoe.mirai.qqandroid.contact.checkIsGroupImpl
import
net.mamoe.mirai.qqandroid.io.serialization.toByteArray
import
net.mamoe.mirai.qqandroid.io.serialization.toByteArray
import
net.mamoe.mirai.qqandroid.message.MessageSourceFromSendFriend
import
net.mamoe.mirai.qqandroid.message.OnlineFriendImageImpl
import
net.mamoe.mirai.qqandroid.message.OnlineFriendImageImpl
import
net.mamoe.mirai.qqandroid.message.OnlineGroupImageImpl
import
net.mamoe.mirai.qqandroid.message.OnlineGroupImageImpl
import
net.mamoe.mirai.qqandroid.network.QQAndroidBotNetworkHandler
import
net.mamoe.mirai.qqandroid.network.QQAndroidBotNetworkHandler
...
@@ -162,6 +164,7 @@ internal abstract class QQAndroidBotBase constructor(
...
@@ -162,6 +164,7 @@ internal abstract class QQAndroidBotBase constructor(
TODO
(
"not implemented"
)
TODO
(
"not implemented"
)
}
}
@ExperimentalMessageSource
override
suspend
fun
recall
(
source
:
MessageSource
)
{
override
suspend
fun
recall
(
source
:
MessageSource
)
{
if
(
source
.
senderId
!=
uin
&&
source
.
groupId
!=
0L
)
{
if
(
source
.
senderId
!=
uin
&&
source
.
groupId
!=
0L
)
{
getGroup
(
source
.
groupId
).
checkBotPermissionOperator
()
getGroup
(
source
.
groupId
).
checkBotPermissionOperator
()
...
@@ -368,34 +371,21 @@ internal abstract class QQAndroidBotBase constructor(
...
@@ -368,34 +371,21 @@ internal abstract class QQAndroidBotBase constructor(
@LowLevelAPI
@LowLevelAPI
@MiraiExperimentalAPI
@MiraiExperimentalAPI
override
suspend
fun
_lowLevelSendLong
Message
(
groupCode
:
Long
,
message
:
Message
)
{
override
suspend
fun
_lowLevelSendLong
GroupMessage
(
groupCode
:
Long
,
message
:
Message
):
MessageReceipt
<
Group
>
{
val
chain
=
message
.
asMessageChain
()
val
chain
=
message
.
asMessageChain
()
check
(
chain
.
toString
().
length
<=
4500
&&
chain
.
count
{
it
is
Image
}
<=
50
)
{
"message is too large"
}
check
(
chain
.
toString
().
length
<=
4500
&&
chain
.
count
{
it
is
Image
}
<=
50
)
{
"message is too large
. Allow up to 4500 chars or 50 images
"
}
val
group
=
getGroup
(
groupCode
)
val
group
=
getGroup
(
groupCode
)
val
source
=
MessageSourceFromSendFriend
(
val
time
=
currentTimeSeconds
messageRandom
=
Random
.
nextInt
().
absoluteValue
,
senderId
=
client
.
uin
,
toUin
=
Group
.
calculateGroupUinByGroupCode
(
groupCode
),
time
=
currentTimeSeconds
,
groupId
=
groupCode
,
originalMessage
=
chain
,
sequenceId
=
client
.
atomicNextMessageSequenceId
()
// sourceMessage = message
)
// TODO: 2020/3/26 util 方法来添加单例元素
val
toSend
=
buildMessageChain
(
chain
.
size
)
{
source
.
originalMessage
.
forEach
{
if
(
it
!
is
MessageSource
)
{
add
(
it
)
}
}
add
(
source
)
}
network
.
run
{
network
.
run
{
val
data
=
toSend
.
calculateValidationDataForGroup
(
group
)
val
data
=
chain
.
calculateValidationDataForGroup
(
sequenceId
=
client
.
atomicNextMessageSequenceId
(),
time
=
time
.
toInt
(),
random
=
Random
.
nextInt
().
absoluteValue
.
toUInt
(),
groupCode
,
group
.
botAsMember
.
nameCardOrNick
)
val
response
=
val
response
=
MultiMsg
.
ApplyUp
.
createForGroupLongMessage
(
MultiMsg
.
ApplyUp
.
createForGroupLongMessage
(
...
@@ -441,17 +431,15 @@ internal abstract class QQAndroidBotBase constructor(
...
@@ -441,17 +431,15 @@ internal abstract class QQAndroidBotBase constructor(
}
}
}
}
group
.
sendMessage
(
return
group
.
sendMessage
(
RichMessage
.
longMessage
(
RichMessage
.
longMessage
(
brief
=
toSend
.
joinToString
(
limit
=
30
)
{
brief
=
chain
.
toString
().
let
{
// already cached
when
(
it
)
{
if
(
it
.
length
>
27
)
{
is
PlainText
->
it
.
stringValue
it
.
take
(
27
)
+
"..."
is
At
->
it
.
toString
()
}
else
it
else
->
""
}
},
},
resId
=
resId
,
resId
=
resId
,
timeSeconds
=
source
.
time
timeSeconds
=
time
)
)
)
)
}
}
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/GroupImpl.kt
View file @
f7040c18
...
@@ -23,9 +23,7 @@ import net.mamoe.mirai.event.broadcast
...
@@ -23,9 +23,7 @@ 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.event.events.MessageSendEvent.GroupMessageSendEvent
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.*
import
net.mamoe.mirai.message.data.OfflineGroupImage
import
net.mamoe.mirai.message.data.asMessageChain
import
net.mamoe.mirai.qqandroid.QQAndroidBot
import
net.mamoe.mirai.qqandroid.QQAndroidBot
import
net.mamoe.mirai.qqandroid.message.MessageSourceFromSendGroup
import
net.mamoe.mirai.qqandroid.message.MessageSourceFromSendGroup
import
net.mamoe.mirai.qqandroid.network.highway.HighwayHelper
import
net.mamoe.mirai.qqandroid.network.highway.HighwayHelper
...
@@ -273,13 +271,25 @@ internal class GroupImpl(
...
@@ -273,13 +271,25 @@ internal class GroupImpl(
return
members
.
delegate
.
filteringGetOrNull
{
it
.
id
==
id
}
return
members
.
delegate
.
filteringGetOrNull
{
it
.
id
==
id
}
}
}
@OptIn
(
MiraiExperimentalAPI
::
class
)
@JvmSynthetic
@JvmSynthetic
override
suspend
fun
sendMessage
(
message
:
Message
):
MessageReceipt
<
Group
>
{
override
suspend
fun
sendMessage
(
message
:
Message
):
MessageReceipt
<
Group
>
{
check
(!
isBotMuted
)
{
"bot is muted. Remaining seconds=$botMuteRemaining"
}
check
(!
isBotMuted
)
{
"bot is muted. Remaining seconds=$botMuteRemaining"
}
val
event
=
GroupMessageSendEvent
(
this
,
message
.
asMessageChain
()).
broadcast
()
val
event
=
GroupMessageSendEvent
(
this
,
message
.
asMessageChain
()).
broadcast
()
if
(
event
.
isCancelled
)
{
if
(
event
.
isCancelled
)
{
throw
EventCancelledException
(
"cancelled by FriendMessageSendEvent"
)
throw
EventCancelledException
(
"cancelled by GroupMessageSendEvent"
)
}
if
(
message
!
is
LongMessage
)
{
val
length
=
event
.
message
.
toString
().
length
if
(
length
>
4000
||
event
.
message
.
count
{
it
is
Image
}
>
3
||
(
event
.
message
.
any
<
QuoteReply
>()
&&
(
event
.
message
.
any
<
Image
>()
||
length
>
100
))
)
{
return
bot
.
_lowLevelSendLongGroupMessage
(
this
.
id
,
message
)
}
}
}
lateinit
var
source
:
MessageSourceFromSendGroup
lateinit
var
source
:
MessageSourceFromSendGroup
bot
.
network
.
run
{
bot
.
network
.
run
{
val
response
:
MessageSvc
.
PbSendMsg
.
Response
=
MessageSvc
.
PbSendMsg
.
ToGroup
(
val
response
:
MessageSvc
.
PbSendMsg
.
Response
=
MessageSvc
.
PbSendMsg
.
ToGroup
(
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/MemberImpl.kt
View file @
f7040c18
...
@@ -7,6 +7,8 @@
...
@@ -7,6 +7,8 @@
* https://github.com/mamoe/mirai/blob/master/LICENSE
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
*/
@
file
:
Suppress
(
"EXPERIMENTAL_API_USAGE"
)
package
net.mamoe.mirai.qqandroid.contact
package
net.mamoe.mirai.qqandroid.contact
import
kotlinx.coroutines.launch
import
kotlinx.coroutines.launch
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/QQImpl.kt
View file @
f7040c18
...
@@ -8,9 +8,12 @@
...
@@ -8,9 +8,12 @@
*/
*/
@
file
:
OptIn
(
MiraiInternalAPI
::
class
,
LowLevelAPI
::
class
)
@
file
:
OptIn
(
MiraiInternalAPI
::
class
,
LowLevelAPI
::
class
)
@
file
:
Suppress
(
"EXPERIMENTAL_API_USAGE"
)
package
net.mamoe.mirai.qqandroid.contact
package
net.mamoe.mirai.qqandroid.contact
import
kotlinx.atomicfu.AtomicInt
import
kotlinx.atomicfu.atomic
import
kotlinx.io.core.Closeable
import
kotlinx.io.core.Closeable
import
net.mamoe.mirai.LowLevelAPI
import
net.mamoe.mirai.LowLevelAPI
import
net.mamoe.mirai.contact.Contact
import
net.mamoe.mirai.contact.Contact
...
@@ -36,6 +39,8 @@ import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image.LongConn
...
@@ -36,6 +39,8 @@ import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image.LongConn
import
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.MessageSvc
import
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.MessageSvc
import
net.mamoe.mirai.utils.*
import
net.mamoe.mirai.utils.*
import
net.mamoe.mirai.utils.io.toUHexString
import
net.mamoe.mirai.utils.io.toUHexString
import
kotlin.contracts.ExperimentalContracts
import
kotlin.contracts.contract
import
kotlin.coroutines.CoroutineContext
import
kotlin.coroutines.CoroutineContext
import
kotlin.jvm.JvmSynthetic
import
kotlin.jvm.JvmSynthetic
...
@@ -46,12 +51,23 @@ internal inline class FriendInfoImpl(
...
@@ -46,12 +51,23 @@ internal inline class FriendInfoImpl(
override
val
uin
:
Long
get
()
=
jceFriendInfo
.
friendUin
override
val
uin
:
Long
get
()
=
jceFriendInfo
.
friendUin
}
}
@OptIn
(
ExperimentalContracts
::
class
)
internal
fun
QQ
.
checkIsQQImpl
():
QQImpl
{
contract
{
returns
()
implies
(
this
@
checkIsQQImpl
is
QQImpl
)
}
check
(
this
is
QQImpl
)
{
"A QQ instance is not instance of QQImpl. Don't interlace two protocol implementations together!"
}
return
this
}
internal
class
QQImpl
(
internal
class
QQImpl
(
bot
:
QQAndroidBot
,
bot
:
QQAndroidBot
,
override
val
coroutineContext
:
CoroutineContext
,
override
val
coroutineContext
:
CoroutineContext
,
override
val
id
:
Long
,
override
val
id
:
Long
,
private
val
friendInfo
:
FriendInfo
private
val
friendInfo
:
FriendInfo
)
:
QQ
()
{
)
:
QQ
()
{
var
lastMessageSequence
:
AtomicInt
=
atomic
(-
1
)
override
val
bot
:
QQAndroidBot
by
bot
.
unsafeWeakRef
()
override
val
bot
:
QQAndroidBot
by
bot
.
unsafeWeakRef
()
override
val
nick
:
String
override
val
nick
:
String
get
()
=
friendInfo
.
nick
get
()
=
friendInfo
.
nick
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/message/MessageSourceImpl.kt
View file @
f7040c18
...
@@ -7,6 +7,8 @@
...
@@ -7,6 +7,8 @@
* https://github.com/mamoe/mirai/blob/master/LICENSE
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
*/
@
file
:
Suppress
(
"EXPERIMENTAL_API_USAGE"
,
"EXPERIMENTAL_OVERRIDE"
)
package
net.mamoe.mirai.qqandroid.message
package
net.mamoe.mirai.qqandroid.message
import
kotlinx.coroutines.CoroutineScope
import
kotlinx.coroutines.CoroutineScope
...
@@ -146,7 +148,7 @@ internal abstract class MessageSourceFromSend : MessageSource {
...
@@ -146,7 +148,7 @@ internal abstract class MessageSourceFromSend : MessageSource {
}
}
private
val
elems
by
lazy
{
private
val
elems
by
lazy
{
originalMessage
.
toRichTextElems
(
groupId
!=
0L
)
originalMessage
.
toRichTextElems
(
groupId
!=
0L
,
true
)
}
}
private
fun
toJceDataImplForFriend
():
ImMsgBody
.
SourceMsg
{
private
fun
toJceDataImplForFriend
():
ImMsgBody
.
SourceMsg
{
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/message/messages.kt
View file @
f7040c18
...
@@ -7,6 +7,7 @@
...
@@ -7,6 +7,7 @@
* https://github.com/mamoe/mirai/blob/master/LICENSE
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
*/
@
file
:
OptIn
(
MiraiExperimentalAPI
::
class
,
MiraiInternalAPI
::
class
,
LowLevelAPI
::
class
,
ExperimentalUnsignedTypes
::
class
)
@
file
:
OptIn
(
MiraiExperimentalAPI
::
class
,
MiraiInternalAPI
::
class
,
LowLevelAPI
::
class
,
ExperimentalUnsignedTypes
::
class
)
@
file
:
Suppress
(
"EXPERIMENTAL_API_USAGE"
)
package
net.mamoe.mirai.qqandroid.message
package
net.mamoe.mirai.qqandroid.message
...
@@ -56,44 +57,6 @@ internal fun OfflineFriendImage.toJceData(): ImMsgBody.NotOnlineImage {
...
@@ -56,44 +57,6 @@ internal fun OfflineFriendImage.toJceData(): ImMsgBody.NotOnlineImage {
)
)
}
}
/*
CustomFace#24412994 {
guid=<Empty ByteArray>
filePath={01E9451B-70ED-EAE3-B37C-101F1EEBF5B5}.png
shortcut=
buffer=<Empty ByteArray>
flag=00 00 00 00
oldData=15 36 20 39 32 6B 41 31 00 38 37 32 66 30 36 36 30 33 61 65 31 30 33 62 37 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 30 31 45 39 34 35 31 42 2D 37 30 45 44 2D 45 41 45 33 2D 42 33 37 43 2D 31 30 31 46 31 45 45 42 46 35 42 35 7D 2E 70 6E 67 41
fileId=0x872F0660(-2026961312)
serverIp=0x3AE103B7(987825079)
serverPort=0x00000050(80)
fileType=0x00000000(0)
signature=<Empty ByteArray>
useful=0x00000001(1)
md5=01 E9 45 1B 70 ED EA E3 B3 7C 10 1F 1E EB F5 B5
thumbUrl=/gchatpic_new/1040400290/1041235568-2268005984-01E9451B70EDEAE3B37C101F1EEBF5B5/198?term=2
bigUrl=
origUrl=/gchatpic_new/1040400290/1041235568-2268005984-01E9451B70EDEAE3B37C101F1EEBF5B5/0?term=2
bizType=0x00000000(0)
repeatIndex=0x00000000(0)
repeatImage=0x00000000(0)
imageType=0x00000000(0)
index=0x00000000(0)
width=0x0000015F(351)
height=0x000000EB(235)
source=0x00000000(0)
size=0x0000057C(1404)
origin=0x00000000(0)
thumbWidth=0x000000C6(198)
thumbHeight=0x00000084(132)
showLen=0x00000000(0)
downloadLen=0x00000000(0)
_400Url=/gchatpic_new/1040400290/1041235568-2268005984-01E9451B70EDEAE3B37C101F1EEBF5B5/400?term=2
_400Width=0x0000015F(351)
_400Height=0x000000EB(235)
pbReserve=<Empty ByteArray>
}
*/
internal
val
FACE_BUF
=
"00 01 00 04 52 CC F5 D0"
.
hexToBytes
()
internal
val
FACE_BUF
=
"00 01 00 04 52 CC F5 D0"
.
hexToBytes
()
internal
fun
Face
.
toJceData
():
ImMsgBody
.
Face
{
internal
fun
Face
.
toJceData
():
ImMsgBody
.
Face
{
...
@@ -133,76 +96,6 @@ internal fun OfflineGroupImage.toJceData(): ImMsgBody.CustomFace {
...
@@ -133,76 +96,6 @@ internal fun OfflineGroupImage.toJceData(): ImMsgBody.CustomFace {
private
val
oldData
:
ByteArray
=
private
val
oldData
:
ByteArray
=
"15 36 20 39 32 6B 41 31 00 38 37 32 66 30 36 36 30 33 61 65 31 30 33 62 37 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 30 31 45 39 34 35 31 42 2D 37 30 45 44 2D 45 41 45 33 2D 42 33 37 43 2D 31 30 31 46 31 45 45 42 46 35 42 35 7D 2E 70 6E 67 41"
.
hexToBytes
()
"15 36 20 39 32 6B 41 31 00 38 37 32 66 30 36 36 30 33 61 65 31 30 33 62 37 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 30 31 45 39 34 35 31 42 2D 37 30 45 44 2D 45 41 45 33 2D 42 33 37 43 2D 31 30 31 46 31 45 45 42 46 35 42 35 7D 2E 70 6E 67 41"
.
hexToBytes
()
/*
customFace=CustomFace#2050019814 {
guid=<Empty ByteArray>
filePath=5F6C522DEAC4F36C0ED8EF362660EFD6.png
shortcut=
buffer=<Empty ByteArray>
flag=<Empty ByteArray>
oldData=<Empty ByteArray>
fileId=0xB40AF10E(-1274351346)
serverIp=0xB703E13A(-1224482502)
serverPort=0x00000050(80)
fileType=0x00000042(66)
signature=6B 44 61 76 72 79 68 79 57 67 70 52 41 45 78 49
useful=0x00000001(1)
md5=5F 6C 52 2D EA C4 F3 6C 0E D8 EF 36 26 60 EF D6
thumbUrl=
bigUrl=
origUrl=
bizType=0x00000005(5)
repeatIndex=0x00000000(0)
repeatImage=0x00000000(0)
imageType=0x000003E9(1001)
index=0x00000000(0)
width=0x0000005F(95)
height=0x00000054(84)
source=0x00000067(103)
size=0x000006E2(1762)
origin=0x00000000(0)
thumbWidth=0x00000000(0)
thumbHeight=0x00000000(0)
showLen=0x00000000(0)
downloadLen=0x00000000(0)
_400Url=
_400Width=0x00000000(0)
_400Height=0x00000000(0)
pbReserve=08 01 10 00 32 00 4A 0E 5B E5 8A A8 E7 94 BB E8 A1 A8 E6 83 85 5D 50 00 78 05
}
notOnlineImage=NotOnlineImage#2050019814 {
filePath=41AEF2D4B5BD24CF3791EFC5FEB67D60.jpg
fileLen=0x00000350(848)
downloadPath=/f2b7e5c0-acb3-4e83-aa5c-c8383840cc91
oldVerSendFile=<Empty ByteArray>
imgType=0x000003E8(1000)
previewsImage=<Empty ByteArray>
picMd5=41 AE F2 D4 B5 BD 24 CF 37 91 EF C5 FE B6 7D 60
picHeight=0x00000032(50)
picWidth=0x00000033(51)
resId=/f2b7e5c0-acb3-4e83-aa5c-c8383840cc91
flag=<Empty ByteArray>
thumbUrl=
original=0x00000000(0)
bigUrl=
origUrl=
bizType=0x00000005(5)
result=0x00000000(0)
index=0x00000000(0)
opFaceBuf=<Empty ByteArray>
oldPicMd5=false
thumbWidth=0x00000000(0)
thumbHeight=0x00000000(0)
fileId=0x00000000(0)
showLen=0x00000000(0)
downloadLen=0x00000000(0)
_400Url=
_400Width=0x00000000(0)
_400Height=0x00000000(0)
pbReserve=08 01 10 00 32 00 42 0E 5B E5 8A A8 E7 94 BB E8 A1 A8 E6 83 85 5D 50 00 78 05
}
*/
private
val
atAllData
=
ImMsgBody
.
Elem
(
private
val
atAllData
=
ImMsgBody
.
Elem
(
text
=
ImMsgBody
.
Text
(
text
=
ImMsgBody
.
Text
(
...
@@ -222,7 +115,7 @@ private val atAllData = ImMsgBody.Elem(
...
@@ -222,7 +115,7 @@ private val atAllData = ImMsgBody.Elem(
private
val
UNSUPPORTED_MERGED_MESSAGE_PLAIN
=
PlainText
(
"你的QQ暂不支持查看[转发多条消息],请期待后续版本。"
)
private
val
UNSUPPORTED_MERGED_MESSAGE_PLAIN
=
PlainText
(
"你的QQ暂不支持查看[转发多条消息],请期待后续版本。"
)
@OptIn
(
MiraiInternalAPI
::
class
,
MiraiExperimentalAPI
::
class
)
@OptIn
(
MiraiInternalAPI
::
class
,
MiraiExperimentalAPI
::
class
)
internal
fun
MessageChain
.
toRichTextElems
(
forGroup
:
Boolean
):
MutableList
<
ImMsgBody
.
Elem
>
{
internal
fun
MessageChain
.
toRichTextElems
(
forGroup
:
Boolean
,
withGeneralFlags
:
Boolean
):
MutableList
<
ImMsgBody
.
Elem
>
{
val
elements
=
mutableListOf
<
ImMsgBody
.
Elem
>()
val
elements
=
mutableListOf
<
ImMsgBody
.
Elem
>()
if
(
this
.
any
<
QuoteReply
>())
{
if
(
this
.
any
<
QuoteReply
>())
{
...
@@ -310,6 +203,7 @@ internal fun MessageChain.toRichTextElems(forGroup: Boolean): MutableList<ImMsgB
...
@@ -310,6 +203,7 @@ internal fun MessageChain.toRichTextElems(forGroup: Boolean): MutableList<ImMsgB
}
}
this
.
forEach
(
::
transformOneMessage
)
this
.
forEach
(
::
transformOneMessage
)
if
(
withGeneralFlags
)
{
when
{
when
{
longTextResId
!=
null
->
{
longTextResId
!=
null
->
{
elements
.
add
(
elements
.
add
(
...
@@ -324,14 +218,19 @@ internal fun MessageChain.toRichTextElems(forGroup: Boolean): MutableList<ImMsgB
...
@@ -324,14 +218,19 @@ internal fun MessageChain.toRichTextElems(forGroup: Boolean): MutableList<ImMsgB
}
}
this
.
any
<
RichMessage
>()
->
{
this
.
any
<
RichMessage
>()
->
{
// 08 09 78 00 A0 01 81 DC 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 02 08 03 90 04 80 80 80 10 B8 04 00 C0 04 00
// 08 09 78 00 A0 01 81 DC 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 02 08 03 90 04 80 80 80 10 B8 04 00 C0 04 00
elements
.
add
(
ImMsgBody
.
Elem
(
generalFlags
=
ImMsgBody
.
GeneralFlags
(
pbReserve
=
"08 09 78 00 C8 01 00 F0 01 00 F8 01 00 90 02 00 C8 02 00 98 03 00 A0 03 20 B0 03 00 C0 03 00 D0 03 00 E8 03 00 8A 04 02 08 03 90 04 80 80 80 10 B8 04 00 C0 04 00"
.
hexToBytes
())))
elements
.
add
(
ImMsgBody
.
Elem
(
generalFlags
=
ImMsgBody
.
GeneralFlags
(
pbReserve
=
PB_RESERVE_FOR_RICH_MESSAGE
)))
}
else
->
elements
.
add
(
ImMsgBody
.
Elem
(
generalFlags
=
ImMsgBody
.
GeneralFlags
(
pbReserve
=
PB_RESERVE_FOR_ELSE
)))
}
}
else
->
elements
.
add
(
ImMsgBody
.
Elem
(
generalFlags
=
ImMsgBody
.
GeneralFlags
(
pbReserve
=
"78 00 F8 01 00 C8 02 00"
.
hexToBytes
())))
}
}
return
elements
return
elements
}
}
private
val
PB_RESERVE_FOR_RICH_MESSAGE
=
"08 09 78 00 C8 01 00 F0 01 00 F8 01 00 90 02 00 C8 02 00 98 03 00 A0 03 20 B0 03 00 C0 03 00 D0 03 00 E8 03 00 8A 04 02 08 03 90 04 80 80 80 10 B8 04 00 C0 04 00"
.
hexToBytes
()
private
val
PB_RESERVE_FOR_ELSE
=
"78 00 F8 01 00 C8 02 00"
.
hexToBytes
()
internal
class
OnlineGroupImageImpl
(
internal
class
OnlineGroupImageImpl
(
internal
val
delegate
:
ImMsgBody
.
CustomFace
internal
val
delegate
:
ImMsgBody
.
CustomFace
)
:
OnlineGroupImage
()
{
)
:
OnlineGroupImage
()
{
...
@@ -416,17 +315,12 @@ private fun MessageChain.cleanupRubbishMessageElements(): MessageChain {
...
@@ -416,17 +315,12 @@ private fun MessageChain.cleanupRubbishMessageElements(): MessageChain {
var
last
:
SingleMessage
?
=
null
var
last
:
SingleMessage
?
=
null
return
buildMessageChain
(
initialSize
=
this
.
count
())
{
return
buildMessageChain
(
initialSize
=
this
.
count
())
{
this
@
cleanupRubbishMessageElements
.
forEach
{
element
->
this
@
cleanupRubbishMessageElements
.
forEach
{
element
->
if
(
last
==
null
)
{
last
=
element
return
@
forEach
}
else
{
if
(
last
is
LongMessage
&&
element
is
PlainText
)
{
if
(
last
is
LongMessage
&&
element
is
PlainText
)
{
if
(
element
==
UNSUPPORTED_MERGED_MESSAGE_PLAIN
)
{
if
(
element
==
UNSUPPORTED_MERGED_MESSAGE_PLAIN
)
{
last
=
element
last
=
element
return
@
forEach
return
@
forEach
}
}
}
}
}
add
(
element
)
add
(
element
)
last
=
element
last
=
element
...
@@ -443,19 +337,6 @@ internal inline fun <reified R> Iterable<*>.firstIsInstance(): R {
...
@@ -443,19 +337,6 @@ internal inline fun <reified R> Iterable<*>.firstIsInstance(): R {
throw
NoSuchElementException
(
"Collection contains no element matching the predicate."
)
throw
NoSuchElementException
(
"Collection contains no element matching the predicate."
)
}
}
/*
if (this.any<QuoteReply>()) {
var removed = false
this.filter {
if (it is At && !removed) {
false
} else {
removed = true
true
}
}.asMessageChain()
} else this*/
internal
fun
List
<
ImMsgBody
.
Elem
>.
joinToMessageChain
(
message
:
MessageChainBuilder
)
{
internal
fun
List
<
ImMsgBody
.
Elem
>.
joinToMessageChain
(
message
:
MessageChainBuilder
)
{
this
.
forEach
{
this
.
forEach
{
when
{
when
{
...
@@ -467,9 +348,6 @@ internal fun List<ImMsgBody.Elem>.joinToMessageChain(message: MessageChainBuilde
...
@@ -467,9 +348,6 @@ internal fun List<ImMsgBody.Elem>.joinToMessageChain(message: MessageChainBuilde
if
(
it
.
text
.
attr6Buf
.
isEmpty
())
{
if
(
it
.
text
.
attr6Buf
.
isEmpty
())
{
message
.
add
(
it
.
text
.
str
.
toMessage
())
message
.
add
(
it
.
text
.
str
.
toMessage
())
}
else
{
}
else
{
// 00 01 00 00 00 05 01 00 00 00 00 00 00 all
// 00 01 00 00 00 0A 00 3E 03 3F A2 00 00 one/nick
// 00 01 00 00 00 07 00 44 71 47 90 00 00 one/groupCard
val
id
:
Long
val
id
:
Long
it
.
text
.
attr6Buf
.
read
{
it
.
text
.
attr6Buf
.
read
{
discardExact
(
7
)
discardExact
(
7
)
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/PacketFactory.kt
View file @
f7040c18
...
@@ -27,14 +27,17 @@ import net.mamoe.mirai.qqandroid.network.protocol.packet.login.Heartbeat
...
@@ -27,14 +27,17 @@ import net.mamoe.mirai.qqandroid.network.protocol.packet.login.Heartbeat
import
net.mamoe.mirai.qqandroid.network.protocol.packet.login.StatSvc
import
net.mamoe.mirai.qqandroid.network.protocol.packet.login.StatSvc
import
net.mamoe.mirai.qqandroid.network.protocol.packet.login.WtLogin
import
net.mamoe.mirai.qqandroid.network.protocol.packet.login.WtLogin
import
net.mamoe.mirai.qqandroid.network.readUShortLVByteArray
import
net.mamoe.mirai.qqandroid.network.readUShortLVByteArray
import
net.mamoe.mirai.qqandroid.utils.cryptor.TEA
import
net.mamoe.mirai.qqandroid.utils.cryptor.adjustToPublicKey
import
net.mamoe.mirai.qqandroid.utils.io.readPacketExact
import
net.mamoe.mirai.qqandroid.utils.io.readPacketExact
import
net.mamoe.mirai.qqandroid.utils.io.readString
import
net.mamoe.mirai.qqandroid.utils.io.readString
import
net.mamoe.mirai.qqandroid.utils.io.useBytes
import
net.mamoe.mirai.qqandroid.utils.io.useBytes
import
net.mamoe.mirai.qqandroid.utils.io.withUse
import
net.mamoe.mirai.qqandroid.utils.io.withUse
import
net.mamoe.mirai.utils.*
import
net.mamoe.mirai.utils.*
import
net.mamoe.mirai.qqandroid.utils.cryptor.TEA
import
net.mamoe.mirai.utils.io.ByteArrayPool
import
net.mamoe.mirai.qqandroid.utils.cryptor.adjustToPublicKey
import
net.mamoe.mirai.utils.io.toInt
import
net.mamoe.mirai.utils.io.*
import
net.mamoe.mirai.utils.io.toReadPacket
import
net.mamoe.mirai.utils.io.toUHexString
import
kotlin.jvm.JvmName
import
kotlin.jvm.JvmName
...
@@ -171,9 +174,6 @@ internal object KnownPacketFactories {
...
@@ -171,9 +174,6 @@ internal object KnownPacketFactories {
?:
IncomingFactories
.
firstOrNull
{
it
.
receivingCommandName
==
commandName
}
?:
IncomingFactories
.
firstOrNull
{
it
.
receivingCommandName
==
commandName
}
}
}
/**
* full packet without length
*/
// do not inline. Exceptions thrown will not be reported correctly
// do not inline. Exceptions thrown will not be reported correctly
@OptIn
(
MiraiInternalAPI
::
class
)
@OptIn
(
MiraiInternalAPI
::
class
)
@Suppress
(
"UNCHECKED_CAST"
)
@Suppress
(
"UNCHECKED_CAST"
)
...
@@ -183,22 +183,12 @@ internal object KnownPacketFactories {
...
@@ -183,22 +183,12 @@ internal object KnownPacketFactories {
val
flag1
=
readInt
()
val
flag1
=
readInt
()
PacketLogger
.
verbose
{
"开始处理一个包"
}
PacketLogger
.
verbose
{
"开始处理一个包"
}
PacketLogger
.
verbose
{
"flag1(0A/0B) = ${flag1.toUByte().toUHexString()}"
}
val
flag2
=
readByte
().
toInt
()
val
flag2
=
readByte
().
toInt
()
PacketLogger
.
verbose
{
"包类型(flag2) = $flag2. (可能是 ${when (flag2) {
2
->
"OicqRequest"
1
->
"Uni/ProtoBuf"
0
->
"Heartbeat"
else
->
"未知"
}})
"
}
val
flag3
=
readByte
().
toInt
()
val
flag3
=
readByte
().
toInt
()
check
(
flag3
==
0
)
{
check
(
flag3
==
0
)
{
"Illegal flag3. Expected 0, whereas got $flag3. flag1=$flag1, flag2=$flag2.
Remaining=${this.readBytes()
"Illegal flag3. Expected 0, whereas got $flag3. flag1=$flag1, flag2=$flag2.
"
+
.
toUHexString
()}
"
"Remaining=${this.readBytes()
.toUHexString()}"
}
}
readString
(
readInt
()
-
4
)
// uinAccount
readString
(
readInt
()
-
4
)
// uinAccount
...
@@ -209,14 +199,11 @@ internal object KnownPacketFactories {
...
@@ -209,14 +199,11 @@ internal object KnownPacketFactories {
kotlin
.
runCatching
{
kotlin
.
runCatching
{
when
(
flag2
)
{
when
(
flag2
)
{
2
->
TEA
.
decrypt
(
data
,
DECRYPTER_16_ZERO
,
size
)
2
->
TEA
.
decrypt
(
data
,
DECRYPTER_16_ZERO
,
size
)
.
also
{
PacketLogger
.
verbose
{
"成功使用 16 zero 解密"
}
}
1
->
TEA
.
decrypt
(
data
,
bot
.
client
.
wLoginSigInfo
.
d2Key
,
size
)
1
->
TEA
.
decrypt
(
data
,
bot
.
client
.
wLoginSigInfo
.
d2Key
,
size
)
.
also
{
PacketLogger
.
verbose
{
"成功使用 d2Key 解密"
}
}
0
->
data
0
->
data
else
->
error
(
""
)
else
->
error
(
""
)
}
}
}.
getOrElse
{
}.
getOrElse
{
PacketLogger
.
verbose
{
"失败, 尝试其他各种key"
}
bot
.
client
.
tryDecryptOrNull
(
data
,
size
)
{
it
}
bot
.
client
.
tryDecryptOrNull
(
data
,
size
)
{
it
}
}
?.
toReadPacket
()
?.
let
{
decryptedData
->
}
?.
toReadPacket
()
?.
let
{
decryptedData
->
when
(
flag1
)
{
when
(
flag1
)
{
...
@@ -236,7 +223,7 @@ internal object KnownPacketFactories {
...
@@ -236,7 +223,7 @@ internal object KnownPacketFactories {
}
else
{
}
else
{
handleIncomingPacket
(
it
,
bot
,
flag2
,
consumer
)
handleIncomingPacket
(
it
,
bot
,
flag2
,
consumer
)
}
}
}
?:
inline
{
}
?:
kotlin
.
run
{
PacketLogger
.
error
{
"任何key都无法解密: ${data.take(size).toUHexString()}"
}
PacketLogger
.
error
{
"任何key都无法解密: ${data.take(size).toUHexString()}"
}
return
return
}
}
...
@@ -295,8 +282,6 @@ internal object KnownPacketFactories {
...
@@ -295,8 +282,6 @@ internal object KnownPacketFactories {
}
}
}
}
private
inline
fun
<
R
>
inline
(
block
:
()
->
R
):
R
=
block
()
class
IncomingPacket
<
T
:
Packet
?>(
class
IncomingPacket
<
T
:
Packet
?>(
val
packetFactory
:
PacketFactory
<
T
>?,
val
packetFactory
:
PacketFactory
<
T
>?,
val
sequenceId
:
Int
,
val
sequenceId
:
Int
,
...
@@ -358,9 +343,7 @@ internal object KnownPacketFactories {
...
@@ -358,9 +343,7 @@ internal object KnownPacketFactories {
}
}
}
}
}
}
8
->
{
8
->
input
input
}
else
->
error
(
"unknown dataCompressed flag: $dataCompressed"
)
else
->
error
(
"unknown dataCompressed flag: $dataCompressed"
)
}
}
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/MultiMsg.kt
View file @
f7040c18
This diff is collapsed.
Click to expand it.
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.kt
View file @
f7040c18
...
@@ -11,6 +11,7 @@
...
@@ -11,6 +11,7 @@
package
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive
package
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive
import
kotlinx.atomicfu.loop
import
kotlinx.coroutines.FlowPreview
import
kotlinx.coroutines.FlowPreview
import
kotlinx.coroutines.flow.*
import
kotlinx.coroutines.flow.*
import
kotlinx.io.core.ByteReadPacket
import
kotlinx.io.core.ByteReadPacket
...
@@ -19,16 +20,15 @@ import net.mamoe.mirai.LowLevelAPI
...
@@ -19,16 +20,15 @@ import net.mamoe.mirai.LowLevelAPI
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.qqandroid.network.MultiPacketByIterable
import
net.mamoe.mirai.qqandroid.network.Packet
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.getFriendOrNull
import
net.mamoe.mirai.getFriendOrNull
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.qqandroid.contact.GroupImpl
import
net.mamoe.mirai.qqandroid.QQAndroidBot
import
net.mamoe.mirai.qqandroid.QQAndroidBot
import
net.mamoe.mirai.qqandroid.contact.GroupImpl
import
net.mamoe.mirai.qqandroid.contact.checkIsQQImpl
import
net.mamoe.mirai.qqandroid.io.serialization.decodeUniPacket
import
net.mamoe.mirai.qqandroid.io.serialization.decodeUniPacket
import
net.mamoe.mirai.qqandroid.io.serialization.readProtoBuf
import
net.mamoe.mirai.qqandroid.io.serialization.readProtoBuf
import
net.mamoe.mirai.qqandroid.io.serialization.toByteArray
import
net.mamoe.mirai.qqandroid.io.serialization.toByteArray
...
@@ -37,6 +37,8 @@ import net.mamoe.mirai.qqandroid.message.MessageSourceFromSendFriend
...
@@ -37,6 +37,8 @@ import net.mamoe.mirai.qqandroid.message.MessageSourceFromSendFriend
import
net.mamoe.mirai.qqandroid.message.MessageSourceFromSendGroup
import
net.mamoe.mirai.qqandroid.message.MessageSourceFromSendGroup
import
net.mamoe.mirai.qqandroid.message.toMessageChain
import
net.mamoe.mirai.qqandroid.message.toMessageChain
import
net.mamoe.mirai.qqandroid.message.toRichTextElems
import
net.mamoe.mirai.qqandroid.message.toRichTextElems
import
net.mamoe.mirai.qqandroid.network.MultiPacketByIterable
import
net.mamoe.mirai.qqandroid.network.Packet
import
net.mamoe.mirai.qqandroid.network.QQAndroidClient
import
net.mamoe.mirai.qqandroid.network.QQAndroidClient
import
net.mamoe.mirai.qqandroid.network.protocol.data.jce.RequestPushForceOffline
import
net.mamoe.mirai.qqandroid.network.protocol.data.jce.RequestPushForceOffline
import
net.mamoe.mirai.qqandroid.network.protocol.data.jce.RequestPushNotify
import
net.mamoe.mirai.qqandroid.network.protocol.data.jce.RequestPushNotify
...
@@ -195,9 +197,8 @@ internal class MessageSvc {
...
@@ -195,9 +197,8 @@ internal class MessageSvc {
bot
.
groups
.
delegate
.
addLast
(
newGroup
)
bot
.
groups
.
delegate
.
addLast
(
newGroup
)
return
@
mapNotNull
BotJoinGroupEvent
(
newGroup
)
return
@
mapNotNull
BotJoinGroupEvent
(
newGroup
)
}
else
{
}
else
{
if
(
group
==
null
)
{
group
?:
return
@
mapNotNull
null
return
@
mapNotNull
null
}
if
(
group
.
members
.
contains
(
msg
.
msgHead
.
authUin
))
{
if
(
group
.
members
.
contains
(
msg
.
msgHead
.
authUin
))
{
return
@
mapNotNull
null
return
@
mapNotNull
null
}
}
...
@@ -207,22 +208,31 @@ internal class MessageSvc {
...
@@ -207,22 +208,31 @@ internal class MessageSvc {
override
val
specialTitle
:
String
get
()
=
""
override
val
specialTitle
:
String
get
()
=
""
override
val
muteTimestamp
:
Int
get
()
=
0
override
val
muteTimestamp
:
Int
get
()
=
0
override
val
uin
:
Long
get
()
=
msg
.
msgHead
.
authUin
override
val
uin
:
Long
get
()
=
msg
.
msgHead
.
authUin
override
val
nick
:
String
override
val
nick
:
String
=
msg
.
msgHead
.
authNick
.
takeIf
{
it
.
isNotEmpty
()
}
get
()
=
msg
.
msgHead
.
authNick
.
takeIf
{
it
.
isNotEmpty
()
}
?:
msg
.
msgHead
.
fromNick
?:
msg
.
msgHead
.
fromNick
}).
also
{
group
.
members
.
delegate
.
addLast
(
it
)
})
}).
also
{
group
.
members
.
delegate
.
addLast
(
it
)
})
}
}
}
}
166
->
{
166
->
{
val
friend
=
bot
.
getFriendOrNull
(
msg
.
msgHead
.
fromUin
)
?:
return
@
mapNotNull
null
val
friend
=
bot
.
getFriendOrNull
(
msg
.
msgHead
.
fromUin
)
?:
return
@
mapNotNull
null
return
@
mapNotNull
when
{
friend
.
checkIsQQImpl
()
msg
.
msgHead
.
fromUin
==
bot
.
uin
->
null
!
bot
.
firstLoginSucceed
->
null
if
(
msg
.
msgHead
.
fromUin
==
bot
.
uin
||
!
bot
.
firstLoginSucceed
)
{
else
->
FriendMessage
(
return
@
mapNotNull
null
}
friend
.
lastMessageSequence
.
loop
{
instant
->
if
(
msg
.
msgHead
.
msgSeq
>
instant
)
{
println
(
"bigger"
)
if
(
friend
.
lastMessageSequence
.
compareAndSet
(
instant
,
msg
.
msgHead
.
msgSeq
))
{
println
(
"set ok"
)
return
@
mapNotNull
FriendMessage
(
friend
,
friend
,
msg
.
toMessageChain
()
msg
.
toMessageChain
()
)
)
}
}
}
else
return
@
mapNotNull
null
}
}
}
else
->
return
@
mapNotNull
null
else
->
return
@
mapNotNull
null
}
}
...
@@ -319,7 +329,7 @@ internal class MessageSvc {
...
@@ -319,7 +329,7 @@ internal class MessageSvc {
contentHead
=
MsgComm
.
ContentHead
(
pkgNum
=
1
),
contentHead
=
MsgComm
.
ContentHead
(
pkgNum
=
1
),
msgBody
=
ImMsgBody
.
MsgBody
(
msgBody
=
ImMsgBody
.
MsgBody
(
richText
=
ImMsgBody
.
RichText
(
richText
=
ImMsgBody
.
RichText
(
elems
=
message
.
toRichTextElems
(
false
)
elems
=
message
.
toRichTextElems
(
false
,
true
)
)
)
),
),
msgSeq
=
source
.
sequenceId
,
msgSeq
=
source
.
sequenceId
,
...
@@ -372,7 +382,7 @@ internal class MessageSvc {
...
@@ -372,7 +382,7 @@ internal class MessageSvc {
contentHead
=
MsgComm
.
ContentHead
(
pkgNum
=
1
),
contentHead
=
MsgComm
.
ContentHead
(
pkgNum
=
1
),
msgBody
=
ImMsgBody
.
MsgBody
(
msgBody
=
ImMsgBody
.
MsgBody
(
richText
=
ImMsgBody
.
RichText
(
richText
=
ImMsgBody
.
RichText
(
elems
=
message
.
toRichTextElems
(
true
)
elems
=
message
.
toRichTextElems
(
true
,
true
)
)
)
),
),
msgSeq
=
client
.
atomicNextMessageSequenceId
(),
msgSeq
=
client
.
atomicNextMessageSequenceId
(),
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/utils/cryptor/ECDH.kt
View file @
f7040c18
...
@@ -21,7 +21,7 @@ expect interface ECDHPublicKey {
...
@@ -21,7 +21,7 @@ expect interface ECDHPublicKey {
internal
expect
class
ECDHKeyPairImpl
:
ECDHKeyPair
internal
expect
class
ECDHKeyPairImpl
:
ECDHKeyPair
interface
ECDHKeyPair
{
inter
nal
inter
face
ECDHKeyPair
{
val
privateKey
:
ECDHPrivateKey
val
privateKey
:
ECDHPrivateKey
val
publicKey
:
ECDHPublicKey
val
publicKey
:
ECDHPublicKey
...
@@ -43,7 +43,7 @@ interface ECDHKeyPair {
...
@@ -43,7 +43,7 @@ interface ECDHKeyPair {
/**
/**
* 椭圆曲线密码, ECDH 加密
* 椭圆曲线密码, ECDH 加密
*/
*/
expect
class
ECDH
(
keyPair
:
ECDHKeyPair
)
{
internal
expect
class
ECDH
(
keyPair
:
ECDHKeyPair
)
{
val
keyPair
:
ECDHKeyPair
val
keyPair
:
ECDHKeyPair
/**
/**
...
@@ -74,9 +74,9 @@ expect class ECDH(keyPair: ECDHKeyPair) {
...
@@ -74,9 +74,9 @@ expect class ECDH(keyPair: ECDHKeyPair) {
}
}
@Suppress
(
"FunctionName"
)
@Suppress
(
"FunctionName"
)
expect
fun
ECDH
():
ECDH
internal
expect
fun
ECDH
():
ECDH
val
initialPublicKey
internal
val
initialPublicKey
get
()
=
ECDH
.
constructPublicKey
(
"3046301006072A8648CE3D020106052B8104001F03320004928D8850673088B343264E0C6BACB8496D697799F37211DEB25BB73906CB089FEA9639B4E0260498B51A992D50813DA8"
.
chunkedHexToBytes
())
get
()
=
ECDH
.
constructPublicKey
(
"3046301006072A8648CE3D020106052B8104001F03320004928D8850673088B343264E0C6BACB8496D697799F37211DEB25BB73906CB089FEA9639B4E0260498B51A992D50813DA8"
.
chunkedHexToBytes
())
private
val
commonHeadFor02
=
"302E301006072A8648CE3D020106052B8104001F031A00"
.
chunkedHexToBytes
()
private
val
commonHeadFor02
=
"302E301006072A8648CE3D020106052B8104001F031A00"
.
chunkedHexToBytes
()
private
val
commonHeadForNot02
=
"3046301006072A8648CE3D020106052B8104001F033200"
.
chunkedHexToBytes
()
private
val
commonHeadForNot02
=
"3046301006072A8648CE3D020106052B8104001F033200"
.
chunkedHexToBytes
()
...
@@ -86,7 +86,7 @@ private val byteArray_04 = byteArrayOf(0x04)
...
@@ -86,7 +86,7 @@ private val byteArray_04 = byteArrayOf(0x04)
private
val
head1
=
"302E301006072A8648CE3D020106052B8104001F031A00"
.
chunkedHexToBytes
()
private
val
head1
=
"302E301006072A8648CE3D020106052B8104001F031A00"
.
chunkedHexToBytes
()
private
val
head2
=
"3046301006072A8648CE3D020106052B8104001F03320004"
.
chunkedHexToBytes
()
private
val
head2
=
"3046301006072A8648CE3D020106052B8104001F03320004"
.
chunkedHexToBytes
()
fun
ByteArray
.
adjustToPublicKey
():
ECDHPublicKey
{
internal
fun
ByteArray
.
adjustToPublicKey
():
ECDHPublicKey
{
val
head
=
if
(
this
.
size
<
30
)
head1
else
head2
val
head
=
if
(
this
.
size
<
30
)
head1
else
head2
return
ECDH
.
constructPublicKey
(
head
+
this
)
return
ECDH
.
constructPublicKey
(
head
+
this
)
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/utils/cryptor/TEA.kt
View file @
f7040c18
...
@@ -23,7 +23,7 @@ import kotlin.random.Random
...
@@ -23,7 +23,7 @@ import kotlin.random.Random
/**
/**
* 解密错误
* 解密错误
*/
*/
class
DecryptionFailedException
:
Exception
{
internal
class
DecryptionFailedException
:
Exception
{
constructor
()
:
super
()
constructor
()
:
super
()
constructor
(
message
:
String
?)
:
super
(
message
)
constructor
(
message
:
String
?)
:
super
(
message
)
}
}
...
@@ -34,7 +34,7 @@ class DecryptionFailedException : Exception {
...
@@ -34,7 +34,7 @@ class DecryptionFailedException : Exception {
* **注意**: 此为 Mirai 内部 API. 它可能会在任何时刻被改变.
* **注意**: 此为 Mirai 内部 API. 它可能会在任何时刻被改变.
*/
*/
@MiraiInternalAPI
@MiraiInternalAPI
object
TEA
{
internal
object
TEA
{
// TODO: 2020/2/28 使用 stream 式输入以避免缓存
// TODO: 2020/2/28 使用 stream 式输入以避免缓存
/**
/**
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/utils/io/output.kt
View file @
f7040c18
...
@@ -20,7 +20,7 @@ import net.mamoe.mirai.utils.MiraiInternalAPI
...
@@ -20,7 +20,7 @@ import net.mamoe.mirai.utils.MiraiInternalAPI
import
kotlin.jvm.JvmMultifileClass
import
kotlin.jvm.JvmMultifileClass
import
kotlin.jvm.JvmName
import
kotlin.jvm.JvmName
fun
BytePacketBuilder
.
writeShortLVByteArrayLimitedLength
(
array
:
ByteArray
,
maxLength
:
Int
)
{
internal
fun
BytePacketBuilder
.
writeShortLVByteArrayLimitedLength
(
array
:
ByteArray
,
maxLength
:
Int
)
{
if
(
array
.
size
<=
maxLength
)
{
if
(
array
.
size
<=
maxLength
)
{
writeShort
(
array
.
size
.
toShort
())
writeShort
(
array
.
size
.
toShort
())
writeFully
(
array
)
writeFully
(
array
)
...
@@ -32,13 +32,13 @@ fun BytePacketBuilder.writeShortLVByteArrayLimitedLength(array: ByteArray, maxLe
...
@@ -32,13 +32,13 @@ fun BytePacketBuilder.writeShortLVByteArrayLimitedLength(array: ByteArray, maxLe
}
}
}
}
inline
fun
BytePacketBuilder
.
writeShortLVByteArray
(
byteArray
:
ByteArray
):
Int
{
in
ternal
in
line
fun
BytePacketBuilder
.
writeShortLVByteArray
(
byteArray
:
ByteArray
):
Int
{
this
.
writeShort
(
byteArray
.
size
.
toShort
())
this
.
writeShort
(
byteArray
.
size
.
toShort
())
this
.
writeFully
(
byteArray
)
this
.
writeFully
(
byteArray
)
return
byteArray
.
size
return
byteArray
.
size
}
}
inline
fun
BytePacketBuilder
.
writeIntLVPacket
(
tag
:
UByte
?
=
null
,
lengthOffset
:
((
Long
)
->
Long
)
=
{
it
},
builder
:
BytePacketBuilder
.()
->
Unit
):
Int
=
in
ternal
in
line
fun
BytePacketBuilder
.
writeIntLVPacket
(
tag
:
UByte
?
=
null
,
lengthOffset
:
((
Long
)
->
Long
)
=
{
it
},
builder
:
BytePacketBuilder
.()
->
Unit
):
Int
=
BytePacketBuilder
().
apply
(
builder
).
build
().
use
{
BytePacketBuilder
().
apply
(
builder
).
build
().
use
{
if
(
tag
!=
null
)
writeUByte
(
tag
)
if
(
tag
!=
null
)
writeUByte
(
tag
)
val
length
=
lengthOffset
.
invoke
(
it
.
remaining
).
coerceAtMostOrFail
(
0
xFFFFFFFFL
)
val
length
=
lengthOffset
.
invoke
(
it
.
remaining
).
coerceAtMostOrFail
(
0
xFFFFFFFFL
)
...
@@ -47,7 +47,7 @@ inline fun BytePacketBuilder.writeIntLVPacket(tag: UByte? = null, lengthOffset:
...
@@ -47,7 +47,7 @@ inline fun BytePacketBuilder.writeIntLVPacket(tag: UByte? = null, lengthOffset:
return
length
.
toInt
()
return
length
.
toInt
()
}
}
inline
fun
BytePacketBuilder
.
writeShortLVPacket
(
tag
:
UByte
?
=
null
,
lengthOffset
:
((
Long
)
->
Long
)
=
{
it
},
builder
:
BytePacketBuilder
.()
->
Unit
):
Int
=
in
ternal
in
line
fun
BytePacketBuilder
.
writeShortLVPacket
(
tag
:
UByte
?
=
null
,
lengthOffset
:
((
Long
)
->
Long
)
=
{
it
},
builder
:
BytePacketBuilder
.()
->
Unit
):
Int
=
BytePacketBuilder
().
apply
(
builder
).
build
().
use
{
BytePacketBuilder
().
apply
(
builder
).
build
().
use
{
if
(
tag
!=
null
)
writeUByte
(
tag
)
if
(
tag
!=
null
)
writeUByte
(
tag
)
val
length
=
lengthOffset
.
invoke
(
it
.
remaining
).
coerceAtMostOrFail
(
0
xFFFFFFFFL
)
val
length
=
lengthOffset
.
invoke
(
it
.
remaining
).
coerceAtMostOrFail
(
0
xFFFFFFFFL
)
...
@@ -56,18 +56,16 @@ inline fun BytePacketBuilder.writeShortLVPacket(tag: UByte? = null, lengthOffset
...
@@ -56,18 +56,16 @@ inline fun BytePacketBuilder.writeShortLVPacket(tag: UByte? = null, lengthOffset
return
length
.
toInt
()
return
length
.
toInt
()
}
}
inline
fun
BytePacketBuilder
.
writeShortLVString
(
str
:
String
)
=
writeShortLVByteArray
(
str
.
toByteArray
())
in
ternal
in
line
fun
BytePacketBuilder
.
writeShortLVString
(
str
:
String
)
=
writeShortLVByteArray
(
str
.
toByteArray
())
fun
BytePacketBuilder
.
writeHex
(
uHex
:
String
)
{
internal
fun
BytePacketBuilder
.
writeHex
(
uHex
:
String
)
{
uHex
.
split
(
" "
).
forEach
{
uHex
.
split
(
" "
).
forEach
{
if
(
it
.
isNotBlank
())
{
if
(
it
.
isNotBlank
())
{
writeUByte
(
it
.
toUByte
(
16
))
writeUByte
(
it
.
toUByte
(
16
))
}
}
}
}
}
}
/**
* 会使用 [ByteArrayPool] 缓存
*/
@OptIn
(
MiraiInternalAPI
::
class
)
@OptIn
(
MiraiInternalAPI
::
class
)
inline
fun
BytePacketBuilder
.
encryptAndWrite
(
key
:
ByteArray
,
encoder
:
BytePacketBuilder
.()
->
Unit
)
=
in
ternal
in
line
fun
BytePacketBuilder
.
encryptAndWrite
(
key
:
ByteArray
,
encoder
:
BytePacketBuilder
.()
->
Unit
)
=
TEA
.
encrypt
(
BytePacketBuilder
().
apply
(
encoder
).
build
(),
key
)
{
decrypted
->
writeFully
(
decrypted
)
}
TEA
.
encrypt
(
BytePacketBuilder
().
apply
(
encoder
).
build
(),
key
)
{
decrypted
->
writeFully
(
decrypted
)
}
\ No newline at end of file
mirai-core-qqandroid/src/jvmMain/kotlin/net/mamoe/mirai/qqandroid/utils/cryptor/ECDHJvm.kt
View file @
f7040c18
...
@@ -32,10 +32,10 @@ internal actual class ECDHKeyPairImpl(
...
@@ -32,10 +32,10 @@ internal actual class ECDHKeyPairImpl(
}
}
@Suppress
(
"FunctionName"
)
@Suppress
(
"FunctionName"
)
actual
fun
ECDH
()
=
internal
actual
fun
ECDH
()
=
ECDH
(
ECDH
.
generateKeyPair
())
ECDH
(
ECDH
.
generateKeyPair
())
actual
class
ECDH
actual
constructor
(
actual
val
keyPair
:
ECDHKeyPair
)
{
internal
actual
class
ECDH
actual
constructor
(
actual
val
keyPair
:
ECDHKeyPair
)
{
actual
companion
object
{
actual
companion
object
{
actual
val
isECDHAvailable
:
Boolean
actual
val
isECDHAvailable
:
Boolean
...
...
mirai-core/src/androidMain/kotlin/net/mamoe/mirai/Bot.kt
View file @
f7040c18
...
@@ -7,6 +7,7 @@ import kotlinx.coroutines.io.ByteReadChannel
...
@@ -7,6 +7,7 @@ import kotlinx.coroutines.io.ByteReadChannel
import
net.mamoe.mirai.contact.*
import
net.mamoe.mirai.contact.*
import
net.mamoe.mirai.data.AddFriendResult
import
net.mamoe.mirai.data.AddFriendResult
import
net.mamoe.mirai.message.MessageReceipt
import
net.mamoe.mirai.message.MessageReceipt
import
net.mamoe.mirai.message.data.ExperimentalMessageSource
import
net.mamoe.mirai.message.data.Image
import
net.mamoe.mirai.message.data.Image
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
...
@@ -152,6 +153,7 @@ actual abstract class Bot actual constructor() : CoroutineScope, LowLevelBotAPIA
...
@@ -152,6 +153,7 @@ actual abstract class Bot actual constructor() : CoroutineScope, LowLevelBotAPIA
* @see _lowLevelRecallFriendMessage 低级 API
* @see _lowLevelRecallFriendMessage 低级 API
* @see _lowLevelRecallGroupMessage 低级 API
* @see _lowLevelRecallGroupMessage 低级 API
*/
*/
@ExperimentalMessageSource
@JvmSynthetic
@JvmSynthetic
actual
abstract
suspend
fun
recall
(
source
:
MessageSource
)
actual
abstract
suspend
fun
recall
(
source
:
MessageSource
)
...
...
mirai-core/src/androidMain/kotlin/net/mamoe/mirai/BotJavaFriendlyAPI.kt
View file @
f7040c18
...
@@ -5,6 +5,7 @@ import net.mamoe.mirai.contact.PermissionDeniedException
...
@@ -5,6 +5,7 @@ import net.mamoe.mirai.contact.PermissionDeniedException
import
net.mamoe.mirai.contact.recall
import
net.mamoe.mirai.contact.recall
import
net.mamoe.mirai.data.AddFriendResult
import
net.mamoe.mirai.data.AddFriendResult
import
net.mamoe.mirai.message.MessageReceipt
import
net.mamoe.mirai.message.MessageReceipt
import
net.mamoe.mirai.message.data.ExperimentalMessageSource
import
net.mamoe.mirai.message.data.Image
import
net.mamoe.mirai.message.data.Image
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
...
@@ -61,6 +62,7 @@ actual abstract class BotJavaFriendlyAPI actual constructor() {
...
@@ -61,6 +62,7 @@ actual abstract class BotJavaFriendlyAPI actual constructor() {
*
*
* @see Bot.recall (扩展函数) 接受参数 [MessageChain]
* @see Bot.recall (扩展函数) 接受参数 [MessageChain]
*/
*/
@ExperimentalMessageSource
@JvmName
(
"recall"
)
@JvmName
(
"recall"
)
fun
__recallBlockingForJava__
(
source
:
MessageSource
)
{
fun
__recallBlockingForJava__
(
source
:
MessageSource
)
{
runBlocking
{
recall
(
source
)
}
runBlocking
{
recall
(
source
)
}
...
@@ -88,6 +90,7 @@ actual abstract class BotJavaFriendlyAPI actual constructor() {
...
@@ -88,6 +90,7 @@ actual abstract class BotJavaFriendlyAPI actual constructor() {
* @param millis 延迟的时间, 单位为毫秒
* @param millis 延迟的时间, 单位为毫秒
* @see recall
* @see recall
*/
*/
@ExperimentalMessageSource
@JvmName
(
"recallIn"
)
@JvmName
(
"recallIn"
)
fun
__recallIn_MemberForJava__
(
source
:
MessageSource
,
millis
:
Long
)
{
fun
__recallIn_MemberForJava__
(
source
:
MessageSource
,
millis
:
Long
)
{
runBlocking
{
recallIn
(
source
,
millis
)
}
runBlocking
{
recallIn
(
source
,
millis
)
}
...
@@ -148,6 +151,7 @@ actual abstract class BotJavaFriendlyAPI actual constructor() {
...
@@ -148,6 +151,7 @@ actual abstract class BotJavaFriendlyAPI actual constructor() {
/**
/**
* 异步调用 [__recallBlockingForJava__]
* 异步调用 [__recallBlockingForJava__]
*/
*/
@ExperimentalMessageSource
@JvmName
(
"recallAsync"
)
@JvmName
(
"recallAsync"
)
fun
__recallAsyncForJava__
(
source
:
MessageSource
):
Future
<
Unit
>
{
fun
__recallAsyncForJava__
(
source
:
MessageSource
):
Future
<
Unit
>
{
return
future
{
recall
(
source
)
}
return
future
{
recall
(
source
)
}
...
...
mirai-core/src/androidMain/kotlin/net/mamoe/mirai/contact/Contact.kt
View file @
f7040c18
...
@@ -54,6 +54,8 @@ actual abstract class Contact : CoroutineScope, ContactJavaFriendlyAPI() {
...
@@ -54,6 +54,8 @@ actual abstract class Contact : CoroutineScope, ContactJavaFriendlyAPI() {
/**
/**
* 向这个对象发送消息.
* 向这个对象发送消息.
*
*
* 单条消息最大可发送 4500 字符或 50 张图片.
*
* @see FriendMessageSendEvent 发送好友信息事件, cancellable
* @see FriendMessageSendEvent 发送好友信息事件, cancellable
* @see GroupMessageSendEvent 发送群消息事件. cancellable
* @see GroupMessageSendEvent 发送群消息事件. cancellable
*
*
...
...
mirai-core/src/androidMain/kotlin/net/mamoe/mirai/contact/ContactJavaFriendlyAPI.kt
View file @
f7040c18
...
@@ -48,6 +48,8 @@ actual abstract class ContactJavaFriendlyAPI {
...
@@ -48,6 +48,8 @@ actual abstract class ContactJavaFriendlyAPI {
/**
/**
* 向这个对象发送消息.
* 向这个对象发送消息.
*
*
* 单条消息最大可发送 4500 字符或 50 张图片.
*
* @see FriendMessageSendEvent 发送好友信息事件, cancellable
* @see FriendMessageSendEvent 发送好友信息事件, cancellable
* @see GroupMessageSendEvent 发送群消息事件. cancellable
* @see GroupMessageSendEvent 发送群消息事件. cancellable
*
*
...
...
mirai-core/src/androidMain/kotlin/net/mamoe/mirai/contact/Group.kt
View file @
f7040c18
...
@@ -125,6 +125,8 @@ actual abstract class Group : Contact(), CoroutineScope {
...
@@ -125,6 +125,8 @@ actual abstract class Group : Contact(), CoroutineScope {
/**
/**
* 向这个对象发送消息.
* 向这个对象发送消息.
*
*
* 单条消息最大可发送 4500 字符或 50 张图片.
*
* @see FriendMessageSendEvent 发送好友信息事件, cancellable
* @see FriendMessageSendEvent 发送好友信息事件, cancellable
* @see GroupMessageSendEvent 发送群消息事件. cancellable
* @see GroupMessageSendEvent 发送群消息事件. cancellable
*
*
...
...
mirai-core/src/androidMain/kotlin/net/mamoe/mirai/contact/Member.kt
View file @
f7040c18
...
@@ -110,6 +110,8 @@ actual abstract class Member : MemberJavaFriendlyAPI() {
...
@@ -110,6 +110,8 @@ actual abstract class Member : MemberJavaFriendlyAPI() {
/**
/**
* 向这个对象发送消息.
* 向这个对象发送消息.
*
*
* 单条消息最大可发送 4500 字符或 50 张图片.
*
* @see FriendMessageSendEvent 发送好友信息事件, cancellable
* @see FriendMessageSendEvent 发送好友信息事件, cancellable
* @see GroupMessageSendEvent 发送群消息事件. cancellable
* @see GroupMessageSendEvent 发送群消息事件. cancellable
*
*
...
...
mirai-core/src/androidMain/kotlin/net/mamoe/mirai/contact/QQ.kt
View file @
f7040c18
...
@@ -78,6 +78,8 @@ actual abstract class QQ : Contact(), CoroutineScope {
...
@@ -78,6 +78,8 @@ actual abstract class QQ : Contact(), CoroutineScope {
/**
/**
* 向这个对象发送消息.
* 向这个对象发送消息.
*
*
* 单条消息最大可发送 4500 字符或 50 张图片.
*
* @see FriendMessageSendEvent 发送好友信息事件, cancellable
* @see FriendMessageSendEvent 发送好友信息事件, cancellable
* @see GroupMessageSendEvent 发送群消息事件. cancellable
* @see GroupMessageSendEvent 发送群消息事件. cancellable
*
*
...
...
mirai-core/src/androidMain/kotlin/net/mamoe/mirai/message/MessageReceipt.kt
View file @
f7040c18
...
@@ -29,7 +29,8 @@ import net.mamoe.mirai.utils.unsafeWeakRef
...
@@ -29,7 +29,8 @@ import net.mamoe.mirai.utils.unsafeWeakRef
*/
*/
@Suppress
(
"FunctionName"
)
@Suppress
(
"FunctionName"
)
@OptIn
(
MiraiInternalAPI
::
class
)
@OptIn
(
MiraiInternalAPI
::
class
)
actual
open
class
MessageReceipt
<
C
:
Contact
>
actual
constructor
(
actual
open
class
MessageReceipt
<
C
:
Contact
>
@OptIn
(
ExperimentalMessageSource
::
class
)
actual
constructor
(
actual
val
source
:
MessageSource
,
actual
val
source
:
MessageSource
,
target
:
C
,
target
:
C
,
private
val
botAsMember
:
Member
?
private
val
botAsMember
:
Member
?
...
@@ -56,6 +57,7 @@ actual open class MessageReceipt<C : Contact> actual constructor(
...
@@ -56,6 +57,7 @@ actual open class MessageReceipt<C : Contact> actual constructor(
* @see Bot.recall
* @see Bot.recall
* @throws IllegalStateException 当此消息已经被撤回或正计划撤回时
* @throws IllegalStateException 当此消息已经被撤回或正计划撤回时
*/
*/
@OptIn
(
ExperimentalMessageSource
::
class
)
actual
suspend
fun
recall
()
{
actual
suspend
fun
recall
()
{
@Suppress
(
"BooleanLiteralArgument"
)
@Suppress
(
"BooleanLiteralArgument"
)
if
(
_isRecalled
.
compareAndSet
(
false
,
true
))
{
if
(
_isRecalled
.
compareAndSet
(
false
,
true
))
{
...
@@ -82,7 +84,8 @@ actual open class MessageReceipt<C : Contact> actual constructor(
...
@@ -82,7 +84,8 @@ actual open class MessageReceipt<C : Contact> actual constructor(
if
(
_isRecalled
.
compareAndSet
(
false
,
true
))
{
if
(
_isRecalled
.
compareAndSet
(
false
,
true
))
{
return
when
(
val
contact
=
target
)
{
return
when
(
val
contact
=
target
)
{
is
QQ
,
is
QQ
,
is
Group
->
contact
.
bot
.
recallIn
(
source
,
millis
)
is
Group
,
->
contact
.
bot
.
recallIn
(
source
,
millis
)
else
->
error
(
"Unknown contact type"
)
else
->
error
(
"Unknown contact type"
)
}
}
}
else
error
(
"message is already or planned to be recalled"
)
}
else
error
(
"message is already or planned to be recalled"
)
...
@@ -92,6 +95,7 @@ actual open class MessageReceipt<C : Contact> actual constructor(
...
@@ -92,6 +95,7 @@ actual open class MessageReceipt<C : Contact> actual constructor(
* [确保 sequenceId可用][MessageSource.ensureSequenceIdAvailable] 然后引用这条消息.
* [确保 sequenceId可用][MessageSource.ensureSequenceIdAvailable] 然后引用这条消息.
* @see MessageChain.quote 引用一条消息
* @see MessageChain.quote 引用一条消息
*/
*/
@OptIn
(
ExperimentalMessageSource
::
class
)
actual
open
suspend
fun
quote
():
QuoteReplyToSend
{
actual
open
suspend
fun
quote
():
QuoteReplyToSend
{
this
.
source
.
ensureSequenceIdAvailable
()
this
.
source
.
ensureSequenceIdAvailable
()
@OptIn
(
LowLevelAPI
::
class
)
@OptIn
(
LowLevelAPI
::
class
)
...
@@ -105,6 +109,7 @@ actual open class MessageReceipt<C : Contact> actual constructor(
...
@@ -105,6 +109,7 @@ actual open class MessageReceipt<C : Contact> actual constructor(
*
*
* @see MessageChain.quote 引用一条消息
* @see MessageChain.quote 引用一条消息
*/
*/
@OptIn
(
ExperimentalMessageSource
::
class
)
@LowLevelAPI
@LowLevelAPI
@Suppress
(
"FunctionName"
)
@Suppress
(
"FunctionName"
)
actual
fun
_unsafeQuote
():
QuoteReplyToSend
{
actual
fun
_unsafeQuote
():
QuoteReplyToSend
{
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt
View file @
f7040c18
...
@@ -19,6 +19,7 @@ import kotlinx.coroutines.launch
...
@@ -19,6 +19,7 @@ import kotlinx.coroutines.launch
import
net.mamoe.mirai.contact.*
import
net.mamoe.mirai.contact.*
import
net.mamoe.mirai.data.AddFriendResult
import
net.mamoe.mirai.data.AddFriendResult
import
net.mamoe.mirai.message.MessageReceipt
import
net.mamoe.mirai.message.MessageReceipt
import
net.mamoe.mirai.message.data.ExperimentalMessageSource
import
net.mamoe.mirai.message.data.Image
import
net.mamoe.mirai.message.data.Image
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
...
@@ -33,6 +34,7 @@ import kotlin.jvm.JvmSynthetic
...
@@ -33,6 +34,7 @@ import kotlin.jvm.JvmSynthetic
/**
/**
* 登录, 返回 [this]
* 登录, 返回 [this]
*/
*/
@JvmSynthetic
suspend
inline
fun
<
B
:
Bot
>
B
.
alsoLogin
():
B
=
also
{
login
()
}
suspend
inline
fun
<
B
:
Bot
>
B
.
alsoLogin
():
B
=
also
{
login
()
}
// 任何人都能看到这个方法
// 任何人都能看到这个方法
...
@@ -167,6 +169,7 @@ expect abstract class Bot() : CoroutineScope, LowLevelBotAPIAccessor {
...
@@ -167,6 +169,7 @@ expect abstract class Bot() : CoroutineScope, LowLevelBotAPIAccessor {
* @see _lowLevelRecallFriendMessage 低级 API
* @see _lowLevelRecallFriendMessage 低级 API
* @see _lowLevelRecallGroupMessage 低级 API
* @see _lowLevelRecallGroupMessage 低级 API
*/
*/
@ExperimentalMessageSource
@JvmSynthetic
@JvmSynthetic
abstract
suspend
fun
recall
(
source
:
MessageSource
)
abstract
suspend
fun
recall
(
source
:
MessageSource
)
...
@@ -223,6 +226,7 @@ expect abstract class Bot() : CoroutineScope, LowLevelBotAPIAccessor {
...
@@ -223,6 +226,7 @@ expect abstract class Bot() : CoroutineScope, LowLevelBotAPIAccessor {
* @throws PermissionDeniedException 当 [Bot] 无权限操作时
* @throws PermissionDeniedException 当 [Bot] 无权限操作时
* @see Bot.recall
* @see Bot.recall
*/
*/
@JvmSynthetic
suspend
inline
fun
Bot
.
recall
(
message
:
MessageChain
)
=
this
.
recall
(
message
[
MessageSource
])
suspend
inline
fun
Bot
.
recall
(
message
:
MessageChain
)
=
this
.
recall
(
message
[
MessageSource
])
/**
/**
...
@@ -233,6 +237,7 @@ suspend inline fun Bot.recall(message: MessageChain) = this.recall(message[Messa
...
@@ -233,6 +237,7 @@ suspend inline fun Bot.recall(message: MessageChain) = this.recall(message[Messa
* @param coroutineContext 额外的 [CoroutineContext]
* @param coroutineContext 额外的 [CoroutineContext]
* @see recall
* @see recall
*/
*/
@JvmSynthetic
inline
fun
Bot
.
recallIn
(
inline
fun
Bot
.
recallIn
(
source
:
MessageSource
,
source
:
MessageSource
,
millis
:
Long
,
millis
:
Long
,
...
@@ -249,6 +254,7 @@ inline fun Bot.recallIn(
...
@@ -249,6 +254,7 @@ inline fun Bot.recallIn(
* @param coroutineContext 额外的 [CoroutineContext]
* @param coroutineContext 额外的 [CoroutineContext]
* @see recall
* @see recall
*/
*/
@JvmSynthetic
inline
fun
Bot
.
recallIn
(
inline
fun
Bot
.
recallIn
(
message
:
MessageChain
,
message
:
MessageChain
,
millis
:
Long
,
millis
:
Long
,
...
@@ -265,15 +271,20 @@ inline fun Bot.recallIn(
...
@@ -265,15 +271,20 @@ inline fun Bot.recallIn(
*
*
* @param cause 原因. 为 null 时视为正常关闭, 非 null 时视为异常关闭
* @param cause 原因. 为 null 时视为正常关闭, 非 null 时视为异常关闭
*/
*/
@JvmSynthetic
suspend
inline
fun
Bot
.
closeAndJoin
(
cause
:
Throwable
?
=
null
)
{
suspend
inline
fun
Bot
.
closeAndJoin
(
cause
:
Throwable
?
=
null
)
{
close
(
cause
)
close
(
cause
)
coroutineContext
[
Job
]
?.
join
()
coroutineContext
[
Job
]
?.
join
()
}
}
@JvmSynthetic
inline
fun
Bot
.
containsFriend
(
id
:
Long
):
Boolean
=
this
.
friends
.
contains
(
id
)
inline
fun
Bot
.
containsFriend
(
id
:
Long
):
Boolean
=
this
.
friends
.
contains
(
id
)
@JvmSynthetic
inline
fun
Bot
.
containsGroup
(
id
:
Long
):
Boolean
=
this
.
groups
.
contains
(
id
)
inline
fun
Bot
.
containsGroup
(
id
:
Long
):
Boolean
=
this
.
groups
.
contains
(
id
)
@JvmSynthetic
inline
fun
Bot
.
getFriendOrNull
(
id
:
Long
):
QQ
?
=
this
.
friends
.
getOrNull
(
id
)
inline
fun
Bot
.
getFriendOrNull
(
id
:
Long
):
QQ
?
=
this
.
friends
.
getOrNull
(
id
)
@JvmSynthetic
inline
fun
Bot
.
getGroupOrNull
(
id
:
Long
):
Group
?
=
this
.
groups
.
getOrNull
(
id
)
inline
fun
Bot
.
getGroupOrNull
(
id
:
Long
):
Group
?
=
this
.
groups
.
getOrNull
(
id
)
\ No newline at end of file
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt
View file @
f7040c18
...
@@ -57,6 +57,8 @@ expect abstract class Contact() : CoroutineScope, ContactJavaFriendlyAPI {
...
@@ -57,6 +57,8 @@ expect abstract class Contact() : CoroutineScope, ContactJavaFriendlyAPI {
/**
/**
* 向这个对象发送消息.
* 向这个对象发送消息.
*
*
* 单条消息最大可发送 4500 字符或 50 张图片.
*
* @see FriendMessageSendEvent 发送好友信息事件, cancellable
* @see FriendMessageSendEvent 发送好友信息事件, cancellable
* @see GroupMessageSendEvent 发送群消息事件. cancellable
* @see GroupMessageSendEvent 发送群消息事件. cancellable
*
*
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Group.kt
View file @
f7040c18
...
@@ -129,6 +129,8 @@ expect abstract class Group() : Contact, CoroutineScope {
...
@@ -129,6 +129,8 @@ expect abstract class Group() : Contact, CoroutineScope {
/**
/**
* 向这个对象发送消息.
* 向这个对象发送消息.
*
*
* 单条消息最大可发送 4500 字符或 50 张图片.
*
* @see FriendMessageSendEvent 发送好友信息事件, cancellable
* @see FriendMessageSendEvent 发送好友信息事件, cancellable
* @see GroupMessageSendEvent 发送群消息事件. cancellable
* @see GroupMessageSendEvent 发送群消息事件. cancellable
*
*
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Member.kt
View file @
f7040c18
...
@@ -132,6 +132,8 @@ expect abstract class Member() : MemberJavaFriendlyAPI {
...
@@ -132,6 +132,8 @@ expect abstract class Member() : MemberJavaFriendlyAPI {
/**
/**
* 向这个对象发送消息.
* 向这个对象发送消息.
*
*
* 单条消息最大可发送 4500 字符或 50 张图片.
*
* @see MessageSendEvent.FriendMessageSendEvent 发送好友信息事件, cancellable
* @see MessageSendEvent.FriendMessageSendEvent 发送好友信息事件, cancellable
* @see MessageSendEvent.GroupMessageSendEvent 发送群消息事件. cancellable
* @see MessageSendEvent.GroupMessageSendEvent 发送群消息事件. cancellable
*
*
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/QQ.kt
View file @
f7040c18
...
@@ -87,6 +87,8 @@ expect abstract class QQ() : Contact, CoroutineScope {
...
@@ -87,6 +87,8 @@ expect abstract class QQ() : Contact, CoroutineScope {
/**
/**
* 向这个对象发送消息.
* 向这个对象发送消息.
*
*
* 单条消息最大可发送 4500 字符或 50 张图片.
*
* @see FriendMessageSendEvent 发送好友信息事件, cancellable
* @see FriendMessageSendEvent 发送好友信息事件, cancellable
* @see GroupMessageSendEvent 发送群消息事件. cancellable
* @see GroupMessageSendEvent 发送群消息事件. cancellable
*
*
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/lowLevelApi.kt
View file @
f7040c18
...
@@ -13,6 +13,7 @@ import kotlinx.coroutines.Job
...
@@ -13,6 +13,7 @@ import kotlinx.coroutines.Job
import
net.mamoe.mirai.contact.Group
import
net.mamoe.mirai.contact.Group
import
net.mamoe.mirai.contact.QQ
import
net.mamoe.mirai.contact.QQ
import
net.mamoe.mirai.data.*
import
net.mamoe.mirai.data.*
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.MessageSource
import
net.mamoe.mirai.message.data.MessageSource
import
net.mamoe.mirai.utils.MiraiExperimentalAPI
import
net.mamoe.mirai.utils.MiraiExperimentalAPI
...
@@ -137,6 +138,7 @@ interface LowLevelBotAPIAccessor {
...
@@ -137,6 +138,7 @@ interface LowLevelBotAPIAccessor {
/**
/**
* 获取群活跃信息
* 获取群活跃信息
*/
*/
@SinceMirai
(
"0.29.0"
)
@LowLevelAPI
@LowLevelAPI
@MiraiExperimentalAPI
@MiraiExperimentalAPI
suspend
fun
_lowLevelGetGroupActiveData
(
groupId
:
Long
):
GroupActiveData
suspend
fun
_lowLevelGetGroupActiveData
(
groupId
:
Long
):
GroupActiveData
...
@@ -147,7 +149,7 @@ interface LowLevelBotAPIAccessor {
...
@@ -147,7 +149,7 @@ interface LowLevelBotAPIAccessor {
@SinceMirai
(
"0.31.0"
)
@SinceMirai
(
"0.31.0"
)
@LowLevelAPI
@LowLevelAPI
@MiraiExperimentalAPI
@MiraiExperimentalAPI
suspend
fun
_lowLevelSendLong
Message
(
groupCode
:
Long
,
message
:
Message
)
suspend
fun
_lowLevelSendLong
GroupMessage
(
groupCode
:
Long
,
message
:
Message
):
MessageReceipt
<
Group
>
}
}
/**
/**
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/MessagePacket.kt
View file @
f7040c18
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
* https://github.com/mamoe/mirai/blob/master/LICENSE
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
*/
@
file
:
Suppress
(
"EXPERIMENTAL_UNSIGNED_LITERALS"
,
"EXPERIMENTAL_API_USAGE"
)
@
file
:
Suppress
(
"EXPERIMENTAL_UNSIGNED_LITERALS"
,
"EXPERIMENTAL_API_USAGE"
,
"unused"
)
package
net.mamoe.mirai.message
package
net.mamoe.mirai.message
...
@@ -153,6 +153,7 @@ abstract class MessagePacketBase<TSender : QQ, TSubject : Contact> : Packet, Bot
...
@@ -153,6 +153,7 @@ abstract class MessagePacketBase<TSender : QQ, TSubject : Contact> : Packet, Bot
/**
/**
* 引用这个消息
* 引用这个消息
*/
*/
@ExperimentalMessageSource
inline
fun
MessageChain
.
quote
():
QuoteReplyToSend
=
this
.
quote
(
sender
)
inline
fun
MessageChain
.
quote
():
QuoteReplyToSend
=
this
.
quote
(
sender
)
operator
fun
<
M
:
Message
>
get
(
at
:
Message
.
Key
<
M
>):
M
{
operator
fun
<
M
:
Message
>
get
(
at
:
Message
.
Key
<
M
>):
M
{
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/MessageReceipt.kt
View file @
f7040c18
...
@@ -15,12 +15,16 @@ import net.mamoe.mirai.LowLevelAPI
...
@@ -15,12 +15,16 @@ import net.mamoe.mirai.LowLevelAPI
import
net.mamoe.mirai.contact.*
import
net.mamoe.mirai.contact.*
import
net.mamoe.mirai.message.data.*
import
net.mamoe.mirai.message.data.*
import
net.mamoe.mirai.recallIn
import
net.mamoe.mirai.recallIn
import
kotlin.jvm.JvmSynthetic
/**
/**
* 发送消息后得到的回执. 可用于撤回.
* 发送消息后得到的回执. 可用于撤回.
*
*
* 此对象持有 [Contact] 的弱引用, [Bot] 离线后将会释放引用, 届时 [target] 将无法访问.
* 此对象持有 [Contact] 的弱引用, [Bot] 离线后将会释放引用, 届时 [target] 将无法访问.
*
*
* @param source 指代发送出去的消息
* @param target 消息发送对象
*
* @see Group.sendMessage 发送群消息, 返回回执(此对象)
* @see Group.sendMessage 发送群消息, 返回回执(此对象)
* @see QQ.sendMessage 发送群消息, 返回回执(此对象)
* @see QQ.sendMessage 发送群消息, 返回回执(此对象)
*
*
...
@@ -28,11 +32,15 @@ import net.mamoe.mirai.recallIn
...
@@ -28,11 +32,15 @@ import net.mamoe.mirai.recallIn
* @see MessageReceipt.sourceSequenceId 源序列号
* @see MessageReceipt.sourceSequenceId 源序列号
* @see MessageReceipt.sourceTime 源时间
* @see MessageReceipt.sourceTime 源时间
*/
*/
expect
open
class
MessageReceipt
<
C
:
Contact
>(
expect
open
class
MessageReceipt
<
C
:
Contact
>
@OptIn
(
ExperimentalMessageSource
::
class
)
constructor
(
source
:
MessageSource
,
source
:
MessageSource
,
target
:
C
,
target
:
C
,
botAsMember
:
Member
?
botAsMember
:
Member
?
)
{
)
{
/**
* 指代发送出去的消息
*/
@ExperimentalMessageSource
val
source
:
MessageSource
val
source
:
MessageSource
/**
/**
...
@@ -90,6 +98,8 @@ expect open class MessageReceipt<C : Contact>(
...
@@ -90,6 +98,8 @@ expect open class MessageReceipt<C : Contact>(
*
*
* @see MessageSource.id
* @see MessageSource.id
*/
*/
@
get
:
JvmSynthetic
@ExperimentalMessageSource
inline
val
MessageReceipt
<*>.
sourceId
:
Long
get
()
=
this
.
source
.
id
inline
val
MessageReceipt
<*>.
sourceId
:
Long
get
()
=
this
.
source
.
id
/**
/**
...
@@ -97,6 +107,8 @@ inline val MessageReceipt<*>.sourceId: Long get() = this.source.id
...
@@ -97,6 +107,8 @@ inline val MessageReceipt<*>.sourceId: Long get() = this.source.id
*
*
* @see MessageSource.sequenceId
* @see MessageSource.sequenceId
*/
*/
@
get
:
JvmSynthetic
@ExperimentalMessageSource
inline
val
MessageReceipt
<*>.
sourceSequenceId
:
Int
get
()
=
this
.
source
.
sequenceId
inline
val
MessageReceipt
<*>.
sourceSequenceId
:
Int
get
()
=
this
.
source
.
sequenceId
/**
/**
...
@@ -104,6 +116,8 @@ inline val MessageReceipt<*>.sourceSequenceId: Int get() = this.source.sequenceI
...
@@ -104,6 +116,8 @@ inline val MessageReceipt<*>.sourceSequenceId: Int get() = this.source.sequenceI
*
*
* @see MessageSource.time
* @see MessageSource.time
*/
*/
@
get
:
JvmSynthetic
@ExperimentalMessageSource
inline
val
MessageReceipt
<*>.
sourceTime
:
Long
get
()
=
this
.
source
.
time
inline
val
MessageReceipt
<*>.
sourceTime
:
Long
get
()
=
this
.
source
.
time
suspend
inline
fun
MessageReceipt
<
out
Contact
>.
quoteReply
(
message
:
Message
)
{
suspend
inline
fun
MessageReceipt
<
out
Contact
>.
quoteReply
(
message
:
Message
)
{
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/Image.kt
View file @
f7040c18
...
@@ -37,7 +37,7 @@ interface Image : Message, MessageContent {
...
@@ -37,7 +37,7 @@ interface Image : Message, MessageContent {
* 图片的 id. 只需要有这个 id 即可发送图片.
* 图片的 id. 只需要有这个 id 即可发送图片.
*
*
* 示例:
* 示例:
* 好友图片的 id: `/f8f1ab55-bf8e-4236-b55e-955848d7069f`
* 好友图片的 id: `/f8f1ab55-bf8e-4236-b55e-955848d7069f`
或 `/000000000-3814297509-BFB7027B9354B8F899A062061D74E206`
* 群图片的 id: `{01E9451B-70ED-EAE3-B37C-101F1EEBF5B5}.png`
* 群图片的 id: `{01E9451B-70ED-EAE3-B37C-101F1EEBF5B5}.png`
*/
*/
val
imageId
:
String
val
imageId
:
String
...
@@ -53,7 +53,7 @@ interface Image : Message, MessageContent {
...
@@ -53,7 +53,7 @@ interface Image : Message, MessageContent {
@JsName
(
"newImage"
)
@JsName
(
"newImage"
)
@JvmName
(
"newImage"
)
@JvmName
(
"newImage"
)
fun
Image
(
imageId
:
String
):
Image
=
when
(
imageId
.
length
)
{
fun
Image
(
imageId
:
String
):
Image
=
when
(
imageId
.
length
)
{
37
->
OfflineFriendImage
(
imageId
)
// /f8f1ab55-bf8e-4236-b55e-955848d7069f
54
,
37
->
OfflineFriendImage
(
imageId
)
// /f8f1ab55-bf8e-4236-b55e-955848d7069f
42
->
OfflineGroupImage
(
imageId
)
// {01E9451B-70ED-EAE3-B37C-101F1EEBF5B5}.png
42
->
OfflineGroupImage
(
imageId
)
// {01E9451B-70ED-EAE3-B37C-101F1EEBF5B5}.png
else
->
throw
IllegalArgumentException
(
"Bad imageId, expecting length=37 or 42, got ${imageId.length}"
)
else
->
throw
IllegalArgumentException
(
"Bad imageId, expecting length=37 or 42, got ${imageId.length}"
)
}
}
...
@@ -211,7 +211,7 @@ abstract class OnlineGroupImage : GroupImage(), OnlineImage
...
@@ -211,7 +211,7 @@ abstract class OnlineGroupImage : GroupImage(), OnlineImage
/**
/**
* 好友图片
* 好友图片
*
*
* [imageId] 形如 `/f8f1ab55-bf8e-4236-b55e-955848d7069f` (37 长度)
* [imageId] 形如 `/f8f1ab55-bf8e-4236-b55e-955848d7069f` (37 长度)
或 `/000000000-3814297509-BFB7027B9354B8F899A062061D74E206` (54 长度)
*/
// NotOnlineImage
*/
// NotOnlineImage
@OptIn
(
MiraiInternalAPI
::
class
)
@OptIn
(
MiraiInternalAPI
::
class
)
sealed
class
FriendImage
:
AbstractImage
()
{
sealed
class
FriendImage
:
AbstractImage
()
{
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/MessageChain.kt
View file @
f7040c18
...
@@ -127,6 +127,7 @@ inline fun <reified M : Message> MessageChain.any(): Boolean = this.any { it is
...
@@ -127,6 +127,7 @@ inline fun <reified M : Message> MessageChain.any(): Boolean = this.any { it is
/**
/**
* 获取第一个 [M] 类型的 [Message] 实例
* 获取第一个 [M] 类型的 [Message] 实例
*/
*/
@OptIn
(
ExperimentalMessageSource
::
class
)
@JvmSynthetic
@JvmSynthetic
@Suppress
(
"UNCHECKED_CAST"
)
@Suppress
(
"UNCHECKED_CAST"
)
fun
<
M
:
Message
>
MessageChain
.
firstOrNull
(
key
:
Message
.
Key
<
M
>):
M
?
=
when
(
key
)
{
fun
<
M
:
Message
>
MessageChain
.
firstOrNull
(
key
:
Message
.
Key
<
M
>):
M
?
=
when
(
key
)
{
...
@@ -415,7 +416,10 @@ internal class MessageChainImplByIterable constructor(
...
@@ -415,7 +416,10 @@ internal class MessageChainImplByIterable constructor(
)
:
Message
,
Iterable
<
SingleMessage
>,
MessageChain
{
)
:
Message
,
Iterable
<
SingleMessage
>,
MessageChain
{
override
val
size
:
Int
by
lazy
{
delegate
.
count
()
}
override
val
size
:
Int
by
lazy
{
delegate
.
count
()
}
override
fun
iterator
():
Iterator
<
SingleMessage
>
=
delegate
.
iterator
()
override
fun
iterator
():
Iterator
<
SingleMessage
>
=
delegate
.
iterator
()
override
fun
toString
():
String
=
this
.
delegate
.
joinToString
(
""
)
{
it
.
toString
()
}
var
toStringTemp
:
String
?
=
null
override
fun
toString
():
String
=
toStringTemp
?:
this
.
delegate
.
joinToString
(
""
)
{
it
.
toString
()
}.
also
{
toStringTemp
=
it
}
override
operator
fun
contains
(
sub
:
String
):
Boolean
=
delegate
.
any
{
it
.
contains
(
sub
)
}
override
operator
fun
contains
(
sub
:
String
):
Boolean
=
delegate
.
any
{
it
.
contains
(
sub
)
}
}
}
...
@@ -428,7 +432,10 @@ internal class MessageChainImplByCollection constructor(
...
@@ -428,7 +432,10 @@ internal class MessageChainImplByCollection constructor(
)
:
Message
,
Iterable
<
SingleMessage
>,
MessageChain
{
)
:
Message
,
Iterable
<
SingleMessage
>,
MessageChain
{
override
val
size
:
Int
get
()
=
delegate
.
size
override
val
size
:
Int
get
()
=
delegate
.
size
override
fun
iterator
():
Iterator
<
SingleMessage
>
=
delegate
.
iterator
()
override
fun
iterator
():
Iterator
<
SingleMessage
>
=
delegate
.
iterator
()
override
fun
toString
():
String
=
this
.
delegate
.
joinToString
(
""
)
{
it
.
toString
()
}
var
toStringTemp
:
String
?
=
null
override
fun
toString
():
String
=
toStringTemp
?:
this
.
delegate
.
joinToString
(
""
)
{
it
.
toString
()
}.
also
{
toStringTemp
=
it
}
override
operator
fun
contains
(
sub
:
String
):
Boolean
=
delegate
.
any
{
it
.
contains
(
sub
)
}
override
operator
fun
contains
(
sub
:
String
):
Boolean
=
delegate
.
any
{
it
.
contains
(
sub
)
}
}
}
...
@@ -446,7 +453,10 @@ internal class MessageChainImplBySequence constructor(
...
@@ -446,7 +453,10 @@ internal class MessageChainImplBySequence constructor(
*/
*/
private
val
collected
:
List
<
SingleMessage
>
by
lazy
{
delegate
.
toList
()
}
private
val
collected
:
List
<
SingleMessage
>
by
lazy
{
delegate
.
toList
()
}
override
fun
iterator
():
Iterator
<
SingleMessage
>
=
collected
.
iterator
()
override
fun
iterator
():
Iterator
<
SingleMessage
>
=
collected
.
iterator
()
override
fun
toString
():
String
=
this
.
collected
.
joinToString
(
""
)
{
it
.
toString
()
}
var
toStringTemp
:
String
?
=
null
override
fun
toString
():
String
=
toStringTemp
?:
this
.
collected
.
joinToString
(
""
)
{
it
.
toString
()
}.
also
{
toStringTemp
=
it
}
override
operator
fun
contains
(
sub
:
String
):
Boolean
=
collected
.
any
{
it
.
contains
(
sub
)
}
override
operator
fun
contains
(
sub
:
String
):
Boolean
=
collected
.
any
{
it
.
contains
(
sub
)
}
}
}
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/MessageSource.kt
View file @
f7040c18
...
@@ -19,6 +19,12 @@ import kotlin.jvm.JvmMultifileClass
...
@@ -19,6 +19,12 @@ import kotlin.jvm.JvmMultifileClass
import
kotlin.jvm.JvmName
import
kotlin.jvm.JvmName
import
kotlin.jvm.JvmSynthetic
import
kotlin.jvm.JvmSynthetic
/**
* MessageSource 正计划于 0.32 或 0.33 或之后进行 API 不兼容的重写.
*/
@RequiresOptIn
(
message
=
"MessageSource 正计划于 0.32 或 0.33 或之后进行 API 不兼容的重写"
,
level
=
RequiresOptIn
.
Level
.
WARNING
)
annotation
class
ExperimentalMessageSource
/**
/**
* 消息源, 它存在于 [MessageChain] 中, 用于表示这个消息的来源.
* 消息源, 它存在于 [MessageChain] 中, 用于表示这个消息的来源.
*
*
...
@@ -29,6 +35,7 @@ import kotlin.jvm.JvmSynthetic
...
@@ -29,6 +35,7 @@ import kotlin.jvm.JvmSynthetic
* @see Bot.recall 撤回一条消息
* @see Bot.recall 撤回一条消息
* @see MessageSource.quote 引用这条消息, 创建 [MessageChain]
* @see MessageSource.quote 引用这条消息, 创建 [MessageChain]
*/
*/
@ExperimentalMessageSource
interface
MessageSource
:
Message
,
MessageMetadata
{
interface
MessageSource
:
Message
,
MessageMetadata
{
companion
object
Key
:
Message
.
Key
<
MessageSource
>
companion
object
Key
:
Message
.
Key
<
MessageSource
>
...
@@ -82,6 +89,7 @@ interface MessageSource : Message, MessageMetadata {
...
@@ -82,6 +89,7 @@ interface MessageSource : Message, MessageMetadata {
* 序列号. 若是机器人发出去的消息, 请先 [确保 sequenceId 可用][MessageSource.ensureSequenceIdAvailable]
* 序列号. 若是机器人发出去的消息, 请先 [确保 sequenceId 可用][MessageSource.ensureSequenceIdAvailable]
* @see MessageSource.id
* @see MessageSource.id
*/
*/
@ExperimentalMessageSource
@
get
:
JvmSynthetic
@
get
:
JvmSynthetic
inline
val
MessageSource
.
sequenceId
:
Int
inline
val
MessageSource
.
sequenceId
:
Int
get
()
=
(
this
.
id
shr
32
).
toInt
()
get
()
=
(
this
.
id
shr
32
).
toInt
()
...
@@ -90,6 +98,7 @@ inline val MessageSource.sequenceId: Int
...
@@ -90,6 +98,7 @@ inline val MessageSource.sequenceId: Int
* 消息随机数. 由服务器或客户端指定后不能更改. 它是消息 id 的一部分.
* 消息随机数. 由服务器或客户端指定后不能更改. 它是消息 id 的一部分.
* @see MessageSource.id
* @see MessageSource.id
*/
*/
@ExperimentalMessageSource
@
get
:
JvmSynthetic
@
get
:
JvmSynthetic
inline
val
MessageSource
.
messageRandom
:
Int
inline
val
MessageSource
.
messageRandom
:
Int
get
()
=
this
.
id
.
toInt
()
get
()
=
this
.
id
.
toInt
()
...
@@ -98,24 +107,33 @@ inline val MessageSource.messageRandom: Int
...
@@ -98,24 +107,33 @@ inline val MessageSource.messageRandom: Int
/**
/**
* 消息 id.
* 消息 id.
*
* 仅接收到的消息才可以获取这个 id.
*
* @see MessageSource.id
* @see MessageSource.id
*/
*/
@ExperimentalMessageSource
@
get
:
JvmSynthetic
@
get
:
JvmSynthetic
inline
val
MessageChain
.
id
:
Long
inline
val
MessageChain
.
id
:
Long
get
()
=
this
[
MessageSource
].
id
get
()
=
this
[
MessageSource
].
id
/**
/**
* 消息序列号, 可能来自服务器也可以发送时赋值, 不唯一.
* 消息序列号, 可能来自服务器也可以发送时赋值, 不唯一.
*
* 仅接收到的消息才可以获取这个序列号.
*
* @see MessageSource.id
* @see MessageSource.id
*/
*/
@ExperimentalMessageSource
@
get
:
JvmSynthetic
@
get
:
JvmSynthetic
inline
val
MessageChain
.
sequenceId
:
Int
inline
val
MessageChain
.
sequenceId
:
Int
get
()
=
this
[
MessageSource
].
sequenceId
get
()
=
this
.
getOrNull
(
MessageSource
)
?.
sequenceId
?:
error
(
"Only MessageChain from server has sequenceId"
)
/**
/**
* 消息随机数. 由服务器或客户端指定后不能更改. 它是消息 id 的一部分.
* 消息随机数. 由服务器或客户端指定后不能更改. 它是消息 id 的一部分.
* @see MessageSource.id
* @see MessageSource.id
*/
*/
@ExperimentalMessageSource
@
get
:
JvmSynthetic
@
get
:
JvmSynthetic
inline
val
MessageChain
.
messageRandom
:
Int
inline
val
MessageChain
.
messageRandom
:
Int
get
()
=
this
[
MessageSource
].
messageRandom
get
()
=
this
.
getOrNull
(
MessageSource
)
?.
messageRandom
?:
error
(
"Only MessageChain from server has sequenceId"
)
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/QuoteReply.kt
View file @
f7040c18
...
@@ -29,6 +29,7 @@ import kotlin.jvm.JvmName
...
@@ -29,6 +29,7 @@ import kotlin.jvm.JvmName
* 总是使用 [quote] 来构造这个实例.
* 总是使用 [quote] 来构造这个实例.
*/
*/
open
class
QuoteReply
open
class
QuoteReply
@OptIn
(
ExperimentalMessageSource
::
class
)
@MiraiInternalAPI
constructor
(
val
source
:
MessageSource
)
:
Message
,
MessageMetadata
{
@MiraiInternalAPI
constructor
(
val
source
:
MessageSource
)
:
Message
,
MessageMetadata
{
companion
object
Key
:
Message
.
Key
<
QuoteReply
>
companion
object
Key
:
Message
.
Key
<
QuoteReply
>
...
@@ -39,7 +40,7 @@ open class QuoteReply
...
@@ -39,7 +40,7 @@ open class QuoteReply
* 用于发送的引用回复.
* 用于发送的引用回复.
* 总是使用 [quote] 来构造实例.
* 总是使用 [quote] 来构造实例.
*/
*/
@OptIn
(
MiraiInternalAPI
::
class
)
@OptIn
(
MiraiInternalAPI
::
class
,
ExperimentalMessageSource
::
class
)
sealed
class
QuoteReplyToSend
sealed
class
QuoteReplyToSend
@MiraiInternalAPI
constructor
(
source
:
MessageSource
)
:
QuoteReply
(
source
)
{
@MiraiInternalAPI
constructor
(
source
:
MessageSource
)
:
QuoteReply
(
source
)
{
class
ToGroup
(
source
:
MessageSource
,
val
sender
:
QQ
)
:
QuoteReplyToSend
(
source
)
{
class
ToGroup
(
source
:
MessageSource
,
val
sender
:
QQ
)
:
QuoteReplyToSend
(
source
)
{
...
@@ -53,6 +54,7 @@ sealed class QuoteReplyToSend
...
@@ -53,6 +54,7 @@ sealed class QuoteReplyToSend
* 引用这条消息.
* 引用这条消息.
* @see sender 消息发送人.
* @see sender 消息发送人.
*/
*/
@ExperimentalMessageSource
@OptIn
(
MiraiInternalAPI
::
class
)
@OptIn
(
MiraiInternalAPI
::
class
)
fun
MessageChain
.
quote
(
sender
:
QQ
?):
QuoteReplyToSend
{
fun
MessageChain
.
quote
(
sender
:
QQ
?):
QuoteReplyToSend
{
this
.
firstOrNull
<
MessageSource
>()
?.
let
{
this
.
firstOrNull
<
MessageSource
>()
?.
let
{
...
@@ -65,6 +67,7 @@ fun MessageChain.quote(sender: QQ?): QuoteReplyToSend {
...
@@ -65,6 +67,7 @@ fun MessageChain.quote(sender: QQ?): QuoteReplyToSend {
* 引用这条消息.
* 引用这条消息.
* @see from 消息来源. 若是好友发送
* @see from 消息来源. 若是好友发送
*/
*/
@ExperimentalMessageSource
@OptIn
(
MiraiInternalAPI
::
class
)
@OptIn
(
MiraiInternalAPI
::
class
)
fun
MessageSource
.
quote
(
from
:
QQ
?):
QuoteReplyToSend
{
fun
MessageSource
.
quote
(
from
:
QQ
?):
QuoteReplyToSend
{
return
if
(
this
.
groupId
!=
0L
)
{
return
if
(
this
.
groupId
!=
0L
)
{
...
...
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/Bot.kt
View file @
f7040c18
...
@@ -7,6 +7,7 @@ import kotlinx.coroutines.io.ByteReadChannel
...
@@ -7,6 +7,7 @@ import kotlinx.coroutines.io.ByteReadChannel
import
net.mamoe.mirai.contact.*
import
net.mamoe.mirai.contact.*
import
net.mamoe.mirai.data.AddFriendResult
import
net.mamoe.mirai.data.AddFriendResult
import
net.mamoe.mirai.message.MessageReceipt
import
net.mamoe.mirai.message.MessageReceipt
import
net.mamoe.mirai.message.data.ExperimentalMessageSource
import
net.mamoe.mirai.message.data.Image
import
net.mamoe.mirai.message.data.Image
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
...
@@ -162,6 +163,7 @@ actual abstract class Bot actual constructor() : CoroutineScope, LowLevelBotAPIA
...
@@ -162,6 +163,7 @@ actual abstract class Bot actual constructor() : CoroutineScope, LowLevelBotAPIA
* @see _lowLevelRecallFriendMessage 低级 API
* @see _lowLevelRecallFriendMessage 低级 API
* @see _lowLevelRecallGroupMessage 低级 API
* @see _lowLevelRecallGroupMessage 低级 API
*/
*/
@ExperimentalMessageSource
@JvmSynthetic
@JvmSynthetic
actual
abstract
suspend
fun
recall
(
source
:
MessageSource
)
actual
abstract
suspend
fun
recall
(
source
:
MessageSource
)
...
...
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/BotJavaFriendlyAPI.kt
View file @
f7040c18
...
@@ -5,6 +5,7 @@ import net.mamoe.mirai.contact.PermissionDeniedException
...
@@ -5,6 +5,7 @@ import net.mamoe.mirai.contact.PermissionDeniedException
import
net.mamoe.mirai.contact.recall
import
net.mamoe.mirai.contact.recall
import
net.mamoe.mirai.data.AddFriendResult
import
net.mamoe.mirai.data.AddFriendResult
import
net.mamoe.mirai.message.MessageReceipt
import
net.mamoe.mirai.message.MessageReceipt
import
net.mamoe.mirai.message.data.ExperimentalMessageSource
import
net.mamoe.mirai.message.data.Image
import
net.mamoe.mirai.message.data.Image
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
...
@@ -61,6 +62,7 @@ actual abstract class BotJavaFriendlyAPI actual constructor() {
...
@@ -61,6 +62,7 @@ actual abstract class BotJavaFriendlyAPI actual constructor() {
*
*
* @see Bot.recall (扩展函数) 接受参数 [MessageChain]
* @see Bot.recall (扩展函数) 接受参数 [MessageChain]
*/
*/
@ExperimentalMessageSource
@JvmName
(
"recall"
)
@JvmName
(
"recall"
)
fun
__recallBlockingForJava__
(
source
:
MessageSource
)
{
fun
__recallBlockingForJava__
(
source
:
MessageSource
)
{
runBlocking
{
recall
(
source
)
}
runBlocking
{
recall
(
source
)
}
...
@@ -88,6 +90,7 @@ actual abstract class BotJavaFriendlyAPI actual constructor() {
...
@@ -88,6 +90,7 @@ actual abstract class BotJavaFriendlyAPI actual constructor() {
* @param millis 延迟的时间, 单位为毫秒
* @param millis 延迟的时间, 单位为毫秒
* @see recall
* @see recall
*/
*/
@ExperimentalMessageSource
@JvmName
(
"recallIn"
)
@JvmName
(
"recallIn"
)
fun
__recallIn_MemberForJava__
(
source
:
MessageSource
,
millis
:
Long
)
{
fun
__recallIn_MemberForJava__
(
source
:
MessageSource
,
millis
:
Long
)
{
runBlocking
{
recallIn
(
source
,
millis
)
}
runBlocking
{
recallIn
(
source
,
millis
)
}
...
@@ -148,6 +151,7 @@ actual abstract class BotJavaFriendlyAPI actual constructor() {
...
@@ -148,6 +151,7 @@ actual abstract class BotJavaFriendlyAPI actual constructor() {
/**
/**
* 异步调用 [__recallBlockingForJava__]
* 异步调用 [__recallBlockingForJava__]
*/
*/
@ExperimentalMessageSource
@JvmName
(
"recallAsync"
)
@JvmName
(
"recallAsync"
)
fun
__recallAsyncForJava__
(
source
:
MessageSource
):
Future
<
Unit
>
{
fun
__recallAsyncForJava__
(
source
:
MessageSource
):
Future
<
Unit
>
{
return
future
{
recall
(
source
)
}
return
future
{
recall
(
source
)
}
...
...
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/contact/Contact.kt
View file @
f7040c18
...
@@ -53,6 +53,8 @@ actual abstract class Contact : CoroutineScope, ContactJavaFriendlyAPI() {
...
@@ -53,6 +53,8 @@ actual abstract class Contact : CoroutineScope, ContactJavaFriendlyAPI() {
/**
/**
* 向这个对象发送消息.
* 向这个对象发送消息.
*
*
* 单条消息最大可发送 4500 字符或 50 张图片.
*
* @see FriendMessageSendEvent 发送好友信息事件, cancellable
* @see FriendMessageSendEvent 发送好友信息事件, cancellable
* @see GroupMessageSendEvent 发送群消息事件. cancellable
* @see GroupMessageSendEvent 发送群消息事件. cancellable
*
*
...
...
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/contact/ContactJavaFriendlyAPI.kt
View file @
f7040c18
...
@@ -48,6 +48,8 @@ actual abstract class ContactJavaFriendlyAPI {
...
@@ -48,6 +48,8 @@ actual abstract class ContactJavaFriendlyAPI {
/**
/**
* 向这个对象发送消息.
* 向这个对象发送消息.
*
*
* 单条消息最大可发送 4500 字符或 50 张图片.
*
* @see FriendMessageSendEvent 发送好友信息事件, cancellable
* @see FriendMessageSendEvent 发送好友信息事件, cancellable
* @see GroupMessageSendEvent 发送群消息事件. cancellable
* @see GroupMessageSendEvent 发送群消息事件. cancellable
*
*
...
...
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/contact/Group.kt
View file @
f7040c18
...
@@ -127,6 +127,8 @@ actual abstract class Group : Contact(), CoroutineScope {
...
@@ -127,6 +127,8 @@ actual abstract class Group : Contact(), CoroutineScope {
/**
/**
* 向这个对象发送消息.
* 向这个对象发送消息.
*
*
* 单条消息最大可发送 4500 字符或 50 张图片.
*
* @see FriendMessageSendEvent 发送好友信息事件, cancellable
* @see FriendMessageSendEvent 发送好友信息事件, cancellable
* @see GroupMessageSendEvent 发送群消息事件. cancellable
* @see GroupMessageSendEvent 发送群消息事件. cancellable
*
*
...
...
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/contact/Member.kt
View file @
f7040c18
...
@@ -118,6 +118,8 @@ actual abstract class Member : MemberJavaFriendlyAPI() {
...
@@ -118,6 +118,8 @@ actual abstract class Member : MemberJavaFriendlyAPI() {
/**
/**
* 向这个对象发送消息.
* 向这个对象发送消息.
*
*
* 单条消息最大可发送 4500 字符或 50 张图片.
*
* @see FriendMessageSendEvent 发送好友信息事件, cancellable
* @see FriendMessageSendEvent 发送好友信息事件, cancellable
* @see GroupMessageSendEvent 发送群消息事件. cancellable
* @see GroupMessageSendEvent 发送群消息事件. cancellable
*
*
...
...
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/contact/QQ.kt
View file @
f7040c18
...
@@ -78,6 +78,8 @@ actual abstract class QQ : Contact(), CoroutineScope {
...
@@ -78,6 +78,8 @@ actual abstract class QQ : Contact(), CoroutineScope {
/**
/**
* 向这个对象发送消息.
* 向这个对象发送消息.
*
*
* 单条消息最大可发送 4500 字符或 50 张图片.
*
* @see FriendMessageSendEvent 发送好友信息事件, cancellable
* @see FriendMessageSendEvent 发送好友信息事件, cancellable
* @see GroupMessageSendEvent 发送群消息事件. cancellable
* @see GroupMessageSendEvent 发送群消息事件. cancellable
*
*
...
...
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/message/MessageReceipt.kt
View file @
f7040c18
...
@@ -29,7 +29,8 @@ import net.mamoe.mirai.utils.unsafeWeakRef
...
@@ -29,7 +29,8 @@ import net.mamoe.mirai.utils.unsafeWeakRef
*/
*/
@Suppress
(
"FunctionName"
)
@Suppress
(
"FunctionName"
)
@OptIn
(
MiraiInternalAPI
::
class
)
@OptIn
(
MiraiInternalAPI
::
class
)
actual
open
class
MessageReceipt
<
C
:
Contact
>
actual
constructor
(
actual
open
class
MessageReceipt
<
C
:
Contact
>
@OptIn
(
ExperimentalMessageSource
::
class
)
actual
constructor
(
actual
val
source
:
MessageSource
,
actual
val
source
:
MessageSource
,
target
:
C
,
target
:
C
,
private
val
botAsMember
:
Member
?
private
val
botAsMember
:
Member
?
...
@@ -56,6 +57,7 @@ actual open class MessageReceipt<C : Contact> actual constructor(
...
@@ -56,6 +57,7 @@ actual open class MessageReceipt<C : Contact> actual constructor(
* @see Bot.recall
* @see Bot.recall
* @throws IllegalStateException 当此消息已经被撤回或正计划撤回时
* @throws IllegalStateException 当此消息已经被撤回或正计划撤回时
*/
*/
@OptIn
(
ExperimentalMessageSource
::
class
)
actual
suspend
fun
recall
()
{
actual
suspend
fun
recall
()
{
@Suppress
(
"BooleanLiteralArgument"
)
@Suppress
(
"BooleanLiteralArgument"
)
if
(
_isRecalled
.
compareAndSet
(
false
,
true
))
{
if
(
_isRecalled
.
compareAndSet
(
false
,
true
))
{
...
@@ -84,6 +86,7 @@ actual open class MessageReceipt<C : Contact> actual constructor(
...
@@ -84,6 +86,7 @@ actual open class MessageReceipt<C : Contact> actual constructor(
* [确保 sequenceId可用][MessageSource.ensureSequenceIdAvailable] 然后引用这条消息.
* [确保 sequenceId可用][MessageSource.ensureSequenceIdAvailable] 然后引用这条消息.
* @see MessageChain.quote 引用一条消息
* @see MessageChain.quote 引用一条消息
*/
*/
@OptIn
(
ExperimentalMessageSource
::
class
)
actual
open
suspend
fun
quote
():
QuoteReplyToSend
{
actual
open
suspend
fun
quote
():
QuoteReplyToSend
{
this
.
source
.
ensureSequenceIdAvailable
()
this
.
source
.
ensureSequenceIdAvailable
()
@OptIn
(
LowLevelAPI
::
class
)
@OptIn
(
LowLevelAPI
::
class
)
...
@@ -97,6 +100,7 @@ actual open class MessageReceipt<C : Contact> actual constructor(
...
@@ -97,6 +100,7 @@ actual open class MessageReceipt<C : Contact> actual constructor(
*
*
* @see MessageChain.quote 引用一条消息
* @see MessageChain.quote 引用一条消息
*/
*/
@OptIn
(
ExperimentalMessageSource
::
class
)
@LowLevelAPI
@LowLevelAPI
@Suppress
(
"FunctionName"
)
@Suppress
(
"FunctionName"
)
actual
fun
_unsafeQuote
():
QuoteReplyToSend
{
actual
fun
_unsafeQuote
():
QuoteReplyToSend
{
...
...
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/message/SendImageUtilsJvm.kt
View file @
f7040c18
...
@@ -116,7 +116,7 @@ suspend fun InputStream.uploadAsImage(contact: Contact): OfflineImage =
...
@@ -116,7 +116,7 @@ suspend fun InputStream.uploadAsImage(contact: Contact): OfflineImage =
*/
*/
@Throws
(
OverFileSizeMaxException
::
class
)
@Throws
(
OverFileSizeMaxException
::
class
)
suspend
fun
File
.
uploadAsImage
(
contact
:
Contact
):
OfflineImage
{
suspend
fun
File
.
uploadAsImage
(
contact
:
Contact
):
OfflineImage
{
require
(
this
.
exists
()
&&
this
.
canRead
())
require
(
this
.
isFile
&&
this
.
exists
()
&&
this
.
canRead
())
{
"file ${this.path} is not readable"
}
return
withContext
(
Dispatchers
.
IO
)
{
toExternalImage
()
}.
upload
(
contact
)
return
withContext
(
Dispatchers
.
IO
)
{
toExternalImage
()
}.
upload
(
contact
)
}
}
...
...
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