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
5d46d1c4
Commit
5d46d1c4
authored
Feb 02, 2020
by
Him188
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
C2C message send support
parent
6ac9acc6
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
134 additions
and
83 deletions
+134
-83
mirai-core-qqandroid/src/androidMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.kt
...roidMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.kt
+4
-1
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt
...moe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt
+4
-4
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/MsgCommon.kt
.../mirai/qqandroid/network/protocol/data/proto/MsgCommon.kt
+1
-1
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/SyncCookie.kt
...mirai/qqandroid/network/protocol/data/proto/SyncCookie.kt
+5
-4
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
+20
-19
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/OnlinePush.PbPushGroupMsg.kt
...protocol/packet/chat/receive/OnlinePush.PbPushGroupMsg.kt
+2
-3
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/utils/MessageQQA.kt
...Main/kotlin/net/mamoe/mirai/qqandroid/utils/MessageQQA.kt
+92
-38
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt
+2
-5
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt
.../src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt
+1
-1
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/ContactList.kt
.../commonMain/kotlin/net.mamoe.mirai/contact/ContactList.kt
+1
-1
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/MessagePacket.kt
...ommonMain/kotlin/net.mamoe.mirai/message/MessagePacket.kt
+2
-6
No files found.
mirai-core-qqandroid/src/androidMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.kt
View file @
5d46d1c4
...
@@ -3,8 +3,11 @@ package net.mamoe.mirai.qqandroid
...
@@ -3,8 +3,11 @@ package net.mamoe.mirai.qqandroid
import
net.mamoe.mirai.BotAccount
import
net.mamoe.mirai.BotAccount
import
net.mamoe.mirai.utils.BotConfiguration
import
net.mamoe.mirai.utils.BotConfiguration
import
net.mamoe.mirai.utils.Context
import
net.mamoe.mirai.utils.Context
import
net.mamoe.mirai.utils.MiraiInternalAPI
internal
actual
class
QQAndroidBot
actual
constructor
(
@UseExperimental
(
MiraiInternalAPI
::
class
)
internal
actual
class
QQAndroidBot
actual
constructor
(
context
:
Context
,
context
:
Context
,
account
:
BotAccount
,
account
:
BotAccount
,
configuration
:
BotConfiguration
configuration
:
BotConfiguration
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt
View file @
5d46d1c4
...
@@ -18,16 +18,15 @@ import net.mamoe.mirai.qqandroid.QQAndroidBot
...
@@ -18,16 +18,15 @@ import net.mamoe.mirai.qqandroid.QQAndroidBot
import
net.mamoe.mirai.qqandroid.QQImpl
import
net.mamoe.mirai.qqandroid.QQImpl
import
net.mamoe.mirai.qqandroid.event.ForceOfflineEvent
import
net.mamoe.mirai.qqandroid.event.ForceOfflineEvent
import
net.mamoe.mirai.qqandroid.event.PacketReceivedEvent
import
net.mamoe.mirai.qqandroid.event.PacketReceivedEvent
import
net.mamoe.mirai.qqandroid.network.protocol.data.proto.MsgSvc
import
net.mamoe.mirai.qqandroid.network.protocol.packet.*
import
net.mamoe.mirai.qqandroid.network.protocol.packet.*
import
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.MessageSvc
import
net.mamoe.mirai.qqandroid.network.protocol.packet.list.FriendList
import
net.mamoe.mirai.qqandroid.network.protocol.packet.list.FriendList
import
net.mamoe.mirai.qqandroid.network.protocol.packet.login.LoginPacket
import
net.mamoe.mirai.qqandroid.network.protocol.packet.login.LoginPacket
import
net.mamoe.mirai.qqandroid.network.protocol.packet.login.StatSvc
import
net.mamoe.mirai.qqandroid.network.protocol.packet.login.StatSvc
import
net.mamoe.mirai.utils.LockFreeLinkedList
import
net.mamoe.mirai.utils.*
import
net.mamoe.mirai.utils.MiraiInternalAPI
import
net.mamoe.mirai.utils.cryptor.contentToString
import
net.mamoe.mirai.utils.cryptor.contentToString
import
net.mamoe.mirai.utils.getValue
import
net.mamoe.mirai.utils.io.*
import
net.mamoe.mirai.utils.io.*
import
net.mamoe.mirai.utils.unsafeWeakRef
import
kotlin.coroutines.CoroutineContext
import
kotlin.coroutines.CoroutineContext
import
kotlin.coroutines.EmptyCoroutineContext
import
kotlin.coroutines.EmptyCoroutineContext
import
kotlin.jvm.Volatile
import
kotlin.jvm.Volatile
...
@@ -107,6 +106,7 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
...
@@ -107,6 +106,7 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
override
suspend
fun
init
()
{
override
suspend
fun
init
()
{
// delay(5000)
// delay(5000)
MessageSvc
.
PbGetMsg
(
bot
.
client
,
MsgSvc
.
SyncFlag
.
START
,
currentTimeSeconds
).
sendWithoutExpect
()
this
@QQAndroidBotNetworkHandler
.
subscribeAlways
<
ForceOfflineEvent
>
{
this
@QQAndroidBotNetworkHandler
.
subscribeAlways
<
ForceOfflineEvent
>
{
if
(
this
@QQAndroidBotNetworkHandler
.
bot
==
this
.
bot
)
{
if
(
this
@QQAndroidBotNetworkHandler
.
bot
==
this
.
bot
)
{
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/MsgCommon.kt
View file @
5d46d1c4
...
@@ -145,7 +145,7 @@ internal class MsgComm : ProtoBuf {
...
@@ -145,7 +145,7 @@ internal class MsgComm : ProtoBuf {
@SerialId
(
1
)
val
lastReadTime
:
Int
=
0
,
@SerialId
(
1
)
val
lastReadTime
:
Int
=
0
,
@SerialId
(
2
)
val
peerUin
:
Long
=
0L
,
@SerialId
(
2
)
val
peerUin
:
Long
=
0L
,
@SerialId
(
3
)
val
msgCompleted
:
Int
=
0
,
@SerialId
(
3
)
val
msgCompleted
:
Int
=
0
,
@SerialId
(
4
)
val
msg
:
List
<
Msg
>,
@SerialId
(
4
)
val
msg
:
List
<
Msg
>
?
=
null
,
@SerialId
(
5
)
val
unreadMsgNum
:
Int
=
0
,
@SerialId
(
5
)
val
unreadMsgNum
:
Int
=
0
,
@SerialId
(
8
)
val
c2cType
:
Int
=
0
,
@SerialId
(
8
)
val
c2cType
:
Int
=
0
,
@SerialId
(
9
)
val
serviceType
:
Int
=
0
,
@SerialId
(
9
)
val
serviceType
:
Int
=
0
,
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/SyncCookie.kt
View file @
5d46d1c4
...
@@ -3,14 +3,15 @@ package net.mamoe.mirai.qqandroid.network.protocol.data.proto
...
@@ -3,14 +3,15 @@ package net.mamoe.mirai.qqandroid.network.protocol.data.proto
import
kotlinx.serialization.SerialId
import
kotlinx.serialization.SerialId
import
kotlinx.serialization.Serializable
import
kotlinx.serialization.Serializable
import
net.mamoe.mirai.qqandroid.io.ProtoBuf
import
net.mamoe.mirai.qqandroid.io.ProtoBuf
import
kotlin.math.absoluteValue
import
kotlin.random.Random
import
kotlin.random.Random
@Serializable
@Serializable
class
SyncCookie
(
class
SyncCookie
(
@SerialId
(
1
)
val
time1
:
Long
?
=
null
,
// 1580277992
@SerialId
(
1
)
val
time1
:
Long
?
=
null
,
// 1580277992
@SerialId
(
2
)
val
time
:
Long
,
// 1580277992
@SerialId
(
2
)
val
time
:
Long
,
// 1580277992
@SerialId
(
3
)
val
unknown1
:
Long
=
Random
.
nextLong
(),
// 678328038
@SerialId
(
3
)
val
unknown1
:
Long
=
Random
.
nextLong
()
.
absoluteValue
,
// 678328038
@SerialId
(
4
)
val
unknown2
:
Long
=
Random
.
nextLong
(),
// 1687142153
@SerialId
(
4
)
val
unknown2
:
Long
=
Random
.
nextLong
()
.
absoluteValue
,
// 1687142153
@SerialId
(
5
)
val
const1
:
Long
=
const1_
,
// 1458467940
@SerialId
(
5
)
val
const1
:
Long
=
const1_
,
// 1458467940
@SerialId
(
11
)
val
const2
:
Long
=
const2_
,
// 2683038258
@SerialId
(
11
)
val
const2
:
Long
=
const2_
,
// 2683038258
@SerialId
(
12
)
val
unknown3
:
Long
=
0
x1d
,
@SerialId
(
12
)
val
unknown3
:
Long
=
0
x1d
,
...
@@ -18,8 +19,8 @@ class SyncCookie(
...
@@ -18,8 +19,8 @@ class SyncCookie(
@SerialId
(
14
)
val
unknown4
:
Long
=
0
@SerialId
(
14
)
val
unknown4
:
Long
=
0
)
:
ProtoBuf
)
:
ProtoBuf
private
val
const1_
:
Long
=
Random
.
nextLong
()
private
val
const1_
:
Long
=
Random
.
nextLong
()
.
absoluteValue
private
val
const2_
:
Long
=
Random
.
nextLong
()
private
val
const2_
:
Long
=
Random
.
nextLong
()
.
absoluteValue
/*
/*
@Serializable
@Serializable
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.kt
View file @
5d46d1c4
...
@@ -4,6 +4,7 @@ import kotlinx.io.core.ByteReadPacket
...
@@ -4,6 +4,7 @@ import kotlinx.io.core.ByteReadPacket
import
kotlinx.io.core.discardExact
import
kotlinx.io.core.discardExact
import
net.mamoe.mirai.data.MultiPacket
import
net.mamoe.mirai.data.MultiPacket
import
net.mamoe.mirai.data.Packet
import
net.mamoe.mirai.data.Packet
import
net.mamoe.mirai.event.BroadcastControllable
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.QQAndroidBot
import
net.mamoe.mirai.qqandroid.QQAndroidBot
...
@@ -29,7 +30,6 @@ import net.mamoe.mirai.utils.MiraiInternalAPI
...
@@ -29,7 +30,6 @@ import net.mamoe.mirai.utils.MiraiInternalAPI
import
net.mamoe.mirai.utils.cryptor.contentToString
import
net.mamoe.mirai.utils.cryptor.contentToString
import
net.mamoe.mirai.utils.currentTimeSeconds
import
net.mamoe.mirai.utils.currentTimeSeconds
import
net.mamoe.mirai.utils.io.hexToBytes
import
net.mamoe.mirai.utils.io.hexToBytes
import
net.mamoe.mirai.utils.io.toUHexString
import
kotlin.math.absoluteValue
import
kotlin.math.absoluteValue
import
kotlin.random.Random
import
kotlin.random.Random
...
@@ -39,14 +39,14 @@ internal class MessageSvc {
...
@@ -39,14 +39,14 @@ internal class MessageSvc {
*/
*/
internal
object
PushNotify
:
IncomingPacketFactory
<
RequestPushNotify
>(
"MessageSvc.PushNotify"
)
{
internal
object
PushNotify
:
IncomingPacketFactory
<
RequestPushNotify
>(
"MessageSvc.PushNotify"
)
{
override
suspend
fun
ByteReadPacket
.
decode
(
bot
:
QQAndroidBot
,
sequenceId
:
Int
):
RequestPushNotify
{
override
suspend
fun
ByteReadPacket
.
decode
(
bot
:
QQAndroidBot
,
sequenceId
:
Int
):
RequestPushNotify
{
discardExact
(
4
)
discardExact
(
4
)
// don't remove
return
decodeUniPacket
(
RequestPushNotify
.
serializer
())
return
decodeUniPacket
(
RequestPushNotify
.
serializer
())
}
}
override
suspend
fun
QQAndroidBot
.
handle
(
packet
:
RequestPushNotify
,
sequenceId
:
Int
):
OutgoingPacket
?
{
override
suspend
fun
QQAndroidBot
.
handle
(
packet
:
RequestPushNotify
,
sequenceId
:
Int
):
OutgoingPacket
?
{
network
.
run
{
network
.
run
{
return
PbGetMsg
(
client
,
MsgSvc
.
SyncFlag
.
START
,
packet
.
stMsgInfo
?.
uMsgTime
?:
0
)
return
PbGetMsg
(
client
,
MsgSvc
.
SyncFlag
.
START
,
packet
.
stMsgInfo
?.
uMsgTime
?:
currentTimeSeconds
)
}
}
}
}
}
}
...
@@ -57,9 +57,6 @@ internal class MessageSvc {
...
@@ -57,9 +57,6 @@ internal class MessageSvc {
*/
*/
@UseExperimental
(
MiraiInternalAPI
::
class
)
@UseExperimental
(
MiraiInternalAPI
::
class
)
internal
object
PbGetMsg
:
OutgoingPacketFactory
<
PbGetMsg
.
Response
>(
"MessageSvc.PbGetMsg"
)
{
internal
object
PbGetMsg
:
OutgoingPacketFactory
<
PbGetMsg
.
Response
>(
"MessageSvc.PbGetMsg"
)
{
val
EXTRA_DATA
=
"08 00 12 33 6D 6F 64 65 6C 3A 78 69 67 6F 6D 69 20 36 3B 6F 73 3A 32 32 3B 76 65 72 73 69 6F 6E 3A 76 32 6D 61 6E 3A 78 69 61 6F 6D 69 73 79 73 3A 4C 4D 59 34 38 5A 18 E4 E1 A4 FF FE 2D 20 E9 E1 A4 FF FE 2D 28 A8 E1 A4 FF FE 2D 30 99 E1 A4 FF FE 2D"
.
hexToBytes
()
operator
fun
invoke
(
operator
fun
invoke
(
client
:
QQAndroidClient
,
client
:
QQAndroidClient
,
syncFlag
:
MsgSvc
.
SyncFlag
=
MsgSvc
.
SyncFlag
.
START
,
syncFlag
:
MsgSvc
.
SyncFlag
=
MsgSvc
.
SyncFlag
.
START
,
...
@@ -67,7 +64,7 @@ internal class MessageSvc {
...
@@ -67,7 +64,7 @@ internal class MessageSvc {
):
OutgoingPacket
=
buildOutgoingUniPacket
(
):
OutgoingPacket
=
buildOutgoingUniPacket
(
client
client
)
{
)
{
println
(
"syncCookie=${client.c2cMessageSync.syncCookie?.toUHexString()}"
)
//
println("syncCookie=${client.c2cMessageSync.syncCookie?.toUHexString()}")
writeProtoBuf
(
writeProtoBuf
(
MsgSvc
.
PbGetMsgReq
.
serializer
(),
MsgSvc
.
PbGetMsgReq
.
serializer
(),
MsgSvc
.
PbGetMsgReq
(
MsgSvc
.
PbGetMsgReq
(
...
@@ -96,7 +93,11 @@ internal class MessageSvc {
...
@@ -96,7 +93,11 @@ internal class MessageSvc {
* 不要直接 expect 这个 class. 它可能
* 不要直接 expect 这个 class. 它可能
*/
*/
@MiraiInternalAPI
@MiraiInternalAPI
open
class
Response
(
internal
val
syncFlagFromServer
:
MsgSvc
.
SyncFlag
,
delegate
:
MutableList
<
FriendMessage
>)
:
MultiPacket
<
FriendMessage
>(
delegate
)
{
open
class
Response
(
internal
val
syncFlagFromServer
:
MsgSvc
.
SyncFlag
,
delegate
:
MutableList
<
FriendMessage
>)
:
MultiPacket
<
FriendMessage
>(
delegate
),
BroadcastControllable
{
override
val
shouldBroadcast
:
Boolean
get
()
=
syncFlagFromServer
==
MsgSvc
.
SyncFlag
.
STOP
override
fun
toString
():
String
{
override
fun
toString
():
String
{
return
"MessageSvc.PbGetMsg.Response($syncFlagFromServer=$syncFlagFromServer, messages=List(size=${this.size}))"
return
"MessageSvc.PbGetMsg.Response($syncFlagFromServer=$syncFlagFromServer, messages=List(size=${this.size}))"
}
}
...
@@ -120,7 +121,7 @@ internal class MessageSvc {
...
@@ -120,7 +121,7 @@ internal class MessageSvc {
return
GetMsgSuccess
(
mutableListOf
())
return
GetMsgSuccess
(
mutableListOf
())
}
}
val
messages
=
resp
.
uinPairMsgs
.
asSequence
().
f
latMap
{
it
.
msg
.
asSequence
()
}.
mapNotNull
{
val
messages
=
resp
.
uinPairMsgs
.
asSequence
().
f
ilterNot
{
it
.
msg
==
null
}.
flatMap
{
it
.
msg
!!
.
asSequence
()
}.
mapNotNull
{
when
(
it
.
msgHead
.
msgType
)
{
when
(
it
.
msgHead
.
msgType
)
{
166
->
{
166
->
{
FriendMessage
(
FriendMessage
(
...
@@ -134,7 +135,7 @@ internal class MessageSvc {
...
@@ -134,7 +135,7 @@ internal class MessageSvc {
}
}
}.
toMutableList
()
}.
toMutableList
()
if
(
resp
.
syncFlag
==
MsgSvc
.
SyncFlag
.
STOP
)
{
if
(
resp
.
syncFlag
==
MsgSvc
.
SyncFlag
.
STOP
)
{
return
GetMsgSuccess
(
m
essages
)
return
GetMsgSuccess
(
m
utableListOf
(
messages
.
last
())
)
}
}
return
Response
(
resp
.
syncFlag
,
messages
)
return
Response
(
resp
.
syncFlag
,
messages
)
}
}
...
@@ -146,7 +147,7 @@ internal class MessageSvc {
...
@@ -146,7 +147,7 @@ internal class MessageSvc {
MsgSvc
.
SyncFlag
.
CONTINUE
->
{
MsgSvc
.
SyncFlag
.
CONTINUE
->
{
network
.
run
{
network
.
run
{
PbGetMsg
(
client
,
MsgSvc
.
SyncFlag
.
CONTINUE
,
currentTimeSeconds
)
PbGetMsg
(
client
,
MsgSvc
.
SyncFlag
.
CONTINUE
,
currentTimeSeconds
)
.
sendWithoutExpect
()
}
}
return
return
}
}
...
@@ -199,8 +200,7 @@ internal class MessageSvc {
...
@@ -199,8 +200,7 @@ internal class MessageSvc {
),
),
msgSeq
=
client
.
atomicNextMessageSequenceId
(),
msgSeq
=
client
.
atomicNextMessageSequenceId
(),
msgRand
=
Random
.
nextInt
().
absoluteValue
,
msgRand
=
Random
.
nextInt
().
absoluteValue
,
syncCookie
=
client
.
c2cMessageSync
.
syncCookie
?.
takeIf
{
it
.
isNotEmpty
()
}
syncCookie
=
SyncCookie
(
time
=
currentTimeSeconds
).
toByteArray
(
SyncCookie
.
serializer
())
?:
SyncCookie
(
time
=
currentTimeSeconds
).
toByteArray
(
SyncCookie
.
serializer
())
// msgVia = 1
// msgVia = 1
)
)
)
)
...
@@ -217,21 +217,22 @@ internal class MessageSvc {
...
@@ -217,21 +217,22 @@ internal class MessageSvc {
///writeFully("0A 08 0A 06 08 89 FC A6 8C 0B 12 06 08 01 10 00 18 00 1A 1F 0A 1D 12 08 0A 06 0A 04 F0 9F 92 A9 12 11 AA 02 0E 88 01 00 9A 01 08 78 00 F8 01 00 C8 02 00 20 9B 7A 28 F4 CA 9B B8 03 32 34 08 92 C2 C4 F1 05 10 92 C2 C4 F1 05 18 E6 ED B9 C3 02 20 89 FE BE A4 06 28 89 84 F9 A2 06 48 DE 8C EA E5 0E 58 D9 BD BB A0 09 60 1D 68 92 C2 C4 F1 05 70 00 40 01".hexToBytes())
///writeFully("0A 08 0A 06 08 89 FC A6 8C 0B 12 06 08 01 10 00 18 00 1A 1F 0A 1D 12 08 0A 06 0A 04 F0 9F 92 A9 12 11 AA 02 0E 88 01 00 9A 01 08 78 00 F8 01 00 C8 02 00 20 9B 7A 28 F4 CA 9B B8 03 32 34 08 92 C2 C4 F1 05 10 92 C2 C4 F1 05 18 E6 ED B9 C3 02 20 89 FE BE A4 06 28 89 84 F9 A2 06 48 DE 8C EA E5 0E 58 D9 BD BB A0 09 60 1D 68 92 C2 C4 F1 05 70 00 40 01".hexToBytes())
val
seq
=
client
.
atomicNextMessageSequenceId
()
///return@buildOutgoingUniPacket
///return@buildOutgoingUniPacket
writeProtoBuf
(
writeProtoBuf
(
MsgSvc
.
PbSendMsgReq
.
serializer
(),
MsgSvc
.
PbSendMsgReq
(
MsgSvc
.
PbSendMsgReq
.
serializer
(),
MsgSvc
.
PbSendMsgReq
(
routingHead
=
MsgSvc
.
RoutingHead
(
grp
=
MsgSvc
.
Grp
(
groupCode
=
groupId
)),
// TODO: 2020/1/30 确认这里是 id 还是 internalId
routingHead
=
MsgSvc
.
RoutingHead
(
grp
=
MsgSvc
.
Grp
(
groupCode
=
groupId
)),
// TODO: 2020/1/30 确认这里是 id 还是 internalId
contentHead
=
MsgComm
.
ContentHead
(
pkgNum
=
1
),
contentHead
=
MsgComm
.
ContentHead
(
pkgNum
=
1
,
divSeq
=
seq
),
msgBody
=
ImMsgBody
.
MsgBody
(
msgBody
=
ImMsgBody
.
MsgBody
(
richText
=
ImMsgBody
.
RichText
(
richText
=
ImMsgBody
.
RichText
(
elems
=
message
.
toRichTextElems
()
elems
=
message
.
toRichTextElems
()
)
)
),
),
msgSeq
=
client
.
atomicNextMessageSequenceId
()
,
msgSeq
=
seq
,
//msgRand = Random.nextInt() and 0x7FFF
,
msgRand
=
Random
.
nextInt
().
absoluteValue
,
syncCookie
=
SyncCookie
(
time
=
currentTimeSeconds
).
toByteArray
(
SyncCookie
.
serializer
()
)
syncCookie
=
"08 A0 C2 C4 F1 05 10 A0 C2 C4 F1 05 18 E6 ED B9 C3 02 20 89 FE BE A4 06 28 E4 C2 B1 95 03 48 A1 9F E0 C7 08 58 D3 C2 8F A0 09 60 1D 68 A0 C2 C4 F1 05 70 00"
.
hexToBytes
(
)
//SyncCookie(currentTimeSeconds, Random.nextLong().absoluteValue, Random.nextLong().absoluteValue).toByteArray(SyncCookie.serializer())
?:
SyncCookie
(
time
=
currentTimeSeconds
+
client
.
timeDifference
).
toByteArray
(
SyncCookie
.
serializer
()),
// msgVia = 1
msgVia
=
0
)
)
)
)
}
}
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/OnlinePush.PbPushGroupMsg.kt
View file @
5d46d1c4
...
@@ -3,11 +3,10 @@
...
@@ -3,11 +3,10 @@
package
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive
package
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive
import
kotlinx.io.core.ByteReadPacket
import
kotlinx.io.core.ByteReadPacket
import
kotlinx.io.core.readBytes
import
net.mamoe.mirai.contact.MemberPermission
import
net.mamoe.mirai.contact.MemberPermission
import
net.mamoe.mirai.message.GroupMessage
import
net.mamoe.mirai.message.GroupMessage
import
net.mamoe.mirai.qqandroid.QQAndroidBot
import
net.mamoe.mirai.qqandroid.QQAndroidBot
import
net.mamoe.mirai.qqandroid.io.serialization.
ProtoBufWithNullableSupport
import
net.mamoe.mirai.qqandroid.io.serialization.
readProtoBuf
import
net.mamoe.mirai.qqandroid.network.protocol.data.proto.ImMsgBody
import
net.mamoe.mirai.qqandroid.network.protocol.data.proto.ImMsgBody
import
net.mamoe.mirai.qqandroid.network.protocol.data.proto.MsgOnlinePush
import
net.mamoe.mirai.qqandroid.network.protocol.data.proto.MsgOnlinePush
import
net.mamoe.mirai.qqandroid.network.protocol.packet.IncomingPacketFactory
import
net.mamoe.mirai.qqandroid.network.protocol.packet.IncomingPacketFactory
...
@@ -22,7 +21,7 @@ internal class OnlinePush {
...
@@ -22,7 +21,7 @@ internal class OnlinePush {
@UseExperimental
(
ExperimentalStdlibApi
::
class
)
@UseExperimental
(
ExperimentalStdlibApi
::
class
)
override
suspend
fun
ByteReadPacket
.
decode
(
bot
:
QQAndroidBot
,
sequenceId
:
Int
):
GroupMessage
{
override
suspend
fun
ByteReadPacket
.
decode
(
bot
:
QQAndroidBot
,
sequenceId
:
Int
):
GroupMessage
{
// 00 00 02 E4 0A D5 05 0A 4F 08 A2 FF 8C F0 03 10 DD F1 92 B7 07 18 52 20 00 28 BC 3D 30 8C 82 AB F1 05 38 D2 80 E0 8C 80 80 80 80 02 4A 21 08 E7 C1 AD B8 02 10 01 18 BA 05 22 09 48 69 6D 31 38 38 6D 6F 65 30 06 38 02 42 05 4D 69 72 61 69 50 01 58 01 60 00 88 01 08 12 06 08 01 10 00 18 00 1A F9 04 0A F6 04 0A 26 08 00 10 87 82 AB F1 05 18 B7 B4 BF 30 20 00 28 0C 30 00 38 86 01 40 22 4A 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91 12 E6 03 42 E3 03 12 2A 7B 34 45 31 38 35 38 32 32 2D 30 45 37 42 2D 46 38 30 46 2D 43 35 42 31 2D 33 34 34 38 38 33 37 34 44 33 39 43 7D 2E 6A 70 67 22 00 2A 04 03 00 00 00 32 60 15 36 20 39 36 6B 45 31 41 38 35 32 32 39 64 63 36 39 38 34 37 39 37 37 62 20 20 20 20 20 20 35 30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 7B 34 45 31 38 35 38 32 32 2D 30 45 37 42 2D 46 38 30 46 2D 43 35 42 31 2D 33 34 34 38 38 33 37 34 44 33 39 43 7D 2E 6A 70 67 31 32 31 32 41 38 C6 BB 8A A9 08 40 FB AE 9E C2 09 48 50 50 41 5A 00 60 01 6A 10 4E 18 58 22 0E 7B F8 0F C5 B1 34 48 83 74 D3 9C 72 59 2F 67 63 68 61 74 70 69 63 5F 6E 65 77 2F 31 30 34 30 34 30 30 32 39 30 2F 36 35 35 30 35 37 31 32 37 2D 32 32 33 33 36 33 38 33 34 32 2D 34 45 31 38 35 38 32 32 30 45 37 42 46 38 30 46 43 35 42 31 33 34 34 38 38 33 37 34 44 33 39 43 2F 31 39 38 3F 74 65 72 6D 3D 32 82 01 57 2F 67 63 68 61 74 70 69 63 5F 6E 65 77 2F 31 30 34 30 34 30 30 32 39 30 2F 36 35 35 30 35 37 31 32 37 2D 32 32 33 33 36 33 38 33 34 32 2D 34 45 31 38 35 38 32 32 30 45 37 42 46 38 30 46 43 35 42 31 33 34 34 38 38 33 37 34 44 33 39 43 2F 30 3F 74 65 72 6D 3D 32 B0 01 4D B8 01 2E C8 01 FF 05 D8 01 4D E0 01 2E FA 01 59 2F 67 63 68 61 74 70 69 63 5F 6E 65 77 2F 31 30 34 30 34 30 30 32 39 30 2F 36 35 35 30 35 37 31 32 37 2D 32 32 33 33 36 33 38 33 34 32 2D 34 45 31 38 35 38 32 32 30 45 37 42 46 38 30 46 43 35 42 31 33 34 34 38 38 33 37 34 44 33 39 43 2F 34 30 30 3F 74 65 72 6D 3D 32 80 02 4D 88 02 2E 12 45 AA 02 42 50 03 60 00 68 00 9A 01 39 08 09 20 BF 50 80 01 01 C8 01 00 F0 01 00 F8 01 00 90 02 00 98 03 00 A0 03 20 B0 03 00 C0 03 00 D0 03 00 E8 03 00 8A 04 04 08 02 08 01 90 04 80 80 80 10 B8 04 00 C0 04 00 12 06 4A 04 08 00 40 01 12 14 82 01 11 0A 09 48 69 6D 31 38 38 6D 6F 65 18 06 20 08 28 03 10 8A CA 9D A1 07 1A 00
// 00 00 02 E4 0A D5 05 0A 4F 08 A2 FF 8C F0 03 10 DD F1 92 B7 07 18 52 20 00 28 BC 3D 30 8C 82 AB F1 05 38 D2 80 E0 8C 80 80 80 80 02 4A 21 08 E7 C1 AD B8 02 10 01 18 BA 05 22 09 48 69 6D 31 38 38 6D 6F 65 30 06 38 02 42 05 4D 69 72 61 69 50 01 58 01 60 00 88 01 08 12 06 08 01 10 00 18 00 1A F9 04 0A F6 04 0A 26 08 00 10 87 82 AB F1 05 18 B7 B4 BF 30 20 00 28 0C 30 00 38 86 01 40 22 4A 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91 12 E6 03 42 E3 03 12 2A 7B 34 45 31 38 35 38 32 32 2D 30 45 37 42 2D 46 38 30 46 2D 43 35 42 31 2D 33 34 34 38 38 33 37 34 44 33 39 43 7D 2E 6A 70 67 22 00 2A 04 03 00 00 00 32 60 15 36 20 39 36 6B 45 31 41 38 35 32 32 39 64 63 36 39 38 34 37 39 37 37 62 20 20 20 20 20 20 35 30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 7B 34 45 31 38 35 38 32 32 2D 30 45 37 42 2D 46 38 30 46 2D 43 35 42 31 2D 33 34 34 38 38 33 37 34 44 33 39 43 7D 2E 6A 70 67 31 32 31 32 41 38 C6 BB 8A A9 08 40 FB AE 9E C2 09 48 50 50 41 5A 00 60 01 6A 10 4E 18 58 22 0E 7B F8 0F C5 B1 34 48 83 74 D3 9C 72 59 2F 67 63 68 61 74 70 69 63 5F 6E 65 77 2F 31 30 34 30 34 30 30 32 39 30 2F 36 35 35 30 35 37 31 32 37 2D 32 32 33 33 36 33 38 33 34 32 2D 34 45 31 38 35 38 32 32 30 45 37 42 46 38 30 46 43 35 42 31 33 34 34 38 38 33 37 34 44 33 39 43 2F 31 39 38 3F 74 65 72 6D 3D 32 82 01 57 2F 67 63 68 61 74 70 69 63 5F 6E 65 77 2F 31 30 34 30 34 30 30 32 39 30 2F 36 35 35 30 35 37 31 32 37 2D 32 32 33 33 36 33 38 33 34 32 2D 34 45 31 38 35 38 32 32 30 45 37 42 46 38 30 46 43 35 42 31 33 34 34 38 38 33 37 34 44 33 39 43 2F 30 3F 74 65 72 6D 3D 32 B0 01 4D B8 01 2E C8 01 FF 05 D8 01 4D E0 01 2E FA 01 59 2F 67 63 68 61 74 70 69 63 5F 6E 65 77 2F 31 30 34 30 34 30 30 32 39 30 2F 36 35 35 30 35 37 31 32 37 2D 32 32 33 33 36 33 38 33 34 32 2D 34 45 31 38 35 38 32 32 30 45 37 42 46 38 30 46 43 35 42 31 33 34 34 38 38 33 37 34 44 33 39 43 2F 34 30 30 3F 74 65 72 6D 3D 32 80 02 4D 88 02 2E 12 45 AA 02 42 50 03 60 00 68 00 9A 01 39 08 09 20 BF 50 80 01 01 C8 01 00 F0 01 00 F8 01 00 90 02 00 98 03 00 A0 03 20 B0 03 00 C0 03 00 D0 03 00 E8 03 00 8A 04 04 08 02 08 01 90 04 80 80 80 10 B8 04 00 C0 04 00 12 06 4A 04 08 00 40 01 12 14 82 01 11 0A 09 48 69 6D 31 38 38 6D 6F 65 18 06 20 08 28 03 10 8A CA 9D A1 07 1A 00
val
pbPushMsg
=
ProtoBufWithNullableSupport
.
load
(
MsgOnlinePush
.
PbPushMsg
.
serializer
(),
readBytes
())
val
pbPushMsg
=
readProtoBuf
(
MsgOnlinePush
.
PbPushMsg
.
serializer
())
val
extraInfo
:
ImMsgBody
.
ExtraInfo
?
=
pbPushMsg
.
msg
.
msgBody
.
richText
.
elems
.
firstOrNull
{
it
.
extraInfo
!=
null
}
?.
extraInfo
val
extraInfo
:
ImMsgBody
.
ExtraInfo
?
=
pbPushMsg
.
msg
.
msgBody
.
richText
.
elems
.
firstOrNull
{
it
.
extraInfo
!=
null
}
?.
extraInfo
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/utils/MessageQQA.kt
View file @
5d46d1c4
...
@@ -5,62 +5,123 @@ import net.mamoe.mirai.message.data.*
...
@@ -5,62 +5,123 @@ import net.mamoe.mirai.message.data.*
import
net.mamoe.mirai.qqandroid.network.protocol.data.proto.ImMsgBody
import
net.mamoe.mirai.qqandroid.network.protocol.data.proto.ImMsgBody
import
net.mamoe.mirai.utils.io.hexToBytes
import
net.mamoe.mirai.utils.io.hexToBytes
internal
fun
NotOnlineImageFromFile
.
toJceData
():
ImMsgBody
.
NotOnlineImage
{
return
ImMsgBody
.
NotOnlineImage
(
filePath
=
this
.
filepath
,
resId
=
this
.
resourceId
,
oldPicMd5
=
false
,
picMd5
=
this
.
md5
,
fileLen
=
this
.
fileLength
,
picHeight
=
this
.
height
,
picWidth
=
this
.
width
,
bizType
=
this
.
bizType
,
imgType
=
this
.
imageType
,
downloadPath
=
this
.
downloadPath
)
}
/*
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
}
*/
internal
fun
MessageChain
.
toRichTextElems
():
MutableList
<
ImMsgBody
.
Elem
>
{
internal
fun
MessageChain
.
toRichTextElems
():
MutableList
<
ImMsgBody
.
Elem
>
{
val
elems
=
mutableListOf
<
ImMsgBody
.
Elem
>()
val
elem
ent
s
=
mutableListOf
<
ImMsgBody
.
Elem
>()
this
.
forEach
{
this
.
forEach
{
when
(
it
)
{
when
(
it
)
{
is
PlainText
->
{
is
PlainText
->
{
elems
.
add
(
ImMsgBody
.
Elem
(
text
=
ImMsgBody
.
Text
(
str
=
it
.
stringValue
)))
elem
ent
s
.
add
(
ImMsgBody
.
Elem
(
text
=
ImMsgBody
.
Text
(
str
=
it
.
stringValue
)))
}
}
is
At
->
{
is
At
->
{
}
}
is
Image
->
{
is
NotOnlineImageFromServer
->
{
elems
.
add
(
elements
.
add
(
ImMsgBody
.
Elem
(
notOnlineImage
=
it
.
delegate
))
ImMsgBody
.
Elem
(
elements
.
add
(
ImMsgBody
.
Elem
(
generalFlags
=
ImMsgBody
.
GeneralFlags
(
pbReserve
=
"78 00 90 01 01 F8 01 00 A0 02 00 C8 02 00"
.
hexToBytes
())))
notOnlineImage
=
ImMsgBody
.
NotOnlineImage
(
}
filePath
=
it
.
id
.
value
,
// 错了, 应该是 2B23D705CAD1F2CF3710FE582692FCC4.jpg
is
NotOnlineImageFromFile
->
{
fileLen
=
1149
,
// 假的
elements
.
add
(
ImMsgBody
.
Elem
(
notOnlineImage
=
it
.
toJceData
()))
downloadPath
=
it
.
id
.
value
,
elements
.
add
(
ImMsgBody
.
Elem
(
generalFlags
=
ImMsgBody
.
GeneralFlags
(
pbReserve
=
"78 00 90 01 01 F8 01 00 A0 02 00 C8 02 00"
.
hexToBytes
())))
imgType
=
1000
,
// 不确定
picMd5
=
"2B 23 D7 05 CA D1 F2 CF 37 10 FE 58 26 92 FC C4"
.
hexToBytes
(),
picHeight
=
66
,
picWidth
=
66
,
resId
=
it
.
id
.
value
,
bizType
=
5
,
pbReserve
=
ImMsgBody
.
PbReserve
.
DEFAULT
// 可能还可以改变 `[动画表情]`
)
)
)
}
}
}
}
}
}
return
elems
return
elem
ent
s
}
}
internal
class
NotOnlineImageFromServer
(
internal
val
delegate
:
ImMsgBody
.
NotOnlineImage
)
:
NotOnlineImage
()
{
override
val
resourceId
:
String
get
()
=
delegate
.
resId
override
val
md5
:
ByteArray
get
()
=
delegate
.
picMd5
override
val
filepath
:
String
get
()
=
delegate
.
filePath
override
val
fileLength
:
Int
get
()
=
delegate
.
fileLen
override
val
height
:
Int
get
()
=
delegate
.
picHeight
override
val
width
:
Int
get
()
=
delegate
.
picWidth
override
val
bizType
:
Int
get
()
=
delegate
.
bizType
override
val
imageType
:
Int
get
()
=
delegate
.
imgType
override
val
downloadPath
:
String
get
()
=
delegate
.
downloadPath
}
internal
fun
ImMsgBody
.
RichText
.
toMessageChain
():
MessageChain
{
internal
fun
ImMsgBody
.
RichText
.
toMessageChain
():
MessageChain
{
val
message
=
MessageChain
(
initialCapacity
=
elems
.
size
)
val
message
=
MessageChain
(
initialCapacity
=
elems
.
size
)
elems
.
forEach
{
elems
.
forEach
{
when
{
when
{
it
.
notOnlineImage
!=
null
->
message
.
add
(
it
.
notOnlineImage
!=
null
->
message
.
add
(
Image
(
NotOnlineImageFromServer
(
it
.
notOnlineImage
)
ImageIdQQA
(
it
.
notOnlineImage
.
resId
,
it
.
notOnlineImage
.
origUrl
)
)
)
)
it
.
customFace
!=
null
->
message
.
add
(
it
.
customFace
!=
null
->
message
.
add
(
Image
(
NotOnlineImageFromFile
(
ImageIdQQA
(
it
.
customFace
.
filePath
,
it
.
customFace
.
filePath
,
it
.
customFace
.
md5
,
it
.
customFace
.
origUrl
it
.
customFace
.
origUrl
,
)
it
.
customFace
.
downloadLen
,
it
.
customFace
.
height
,
it
.
customFace
.
width
,
it
.
customFace
.
bizType
,
it
.
customFace
.
imageType
,
it
.
customFace
.
filePath
)
)
)
)
it
.
text
!=
null
->
message
.
add
(
it
.
text
.
str
.
toMessage
())
it
.
text
!=
null
->
message
.
add
(
it
.
text
.
str
.
toMessage
())
...
@@ -70,12 +131,5 @@ internal fun ImMsgBody.RichText.toMessageChain(): MessageChain {
...
@@ -70,12 +131,5 @@ internal fun ImMsgBody.RichText.toMessageChain(): MessageChain {
return
message
return
message
}
}
internal
class
ImageIdQQA
(
override
val
value
:
String
,
originalLink
:
String
)
:
ImageId
{
val
link
:
ImageLink
=
ImageLinkQQA
(
"http://gchat.qpic.cn$originalLink"
)
}
internal
inline
class
ImageLinkQQA
(
override
val
original
:
String
)
:
ImageLink
internal
inline
class
ImageLinkQQA
(
override
val
original
:
String
)
:
ImageLink
\ No newline at end of file
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt
View file @
5d46d1c4
...
@@ -8,7 +8,6 @@ import kotlinx.io.core.ByteReadPacket
...
@@ -8,7 +8,6 @@ import kotlinx.io.core.ByteReadPacket
import
kotlinx.io.core.use
import
kotlinx.io.core.use
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.data.ImageLink
import
net.mamoe.mirai.message.data.Image
import
net.mamoe.mirai.message.data.Image
import
net.mamoe.mirai.network.BotNetworkHandler
import
net.mamoe.mirai.network.BotNetworkHandler
import
net.mamoe.mirai.utils.GroupNotFoundException
import
net.mamoe.mirai.utils.GroupNotFoundException
...
@@ -104,11 +103,9 @@ abstract class Bot : CoroutineScope {
...
@@ -104,11 +103,9 @@ abstract class Bot : CoroutineScope {
// region actions
// region actions
abstract
suspend
fun
Image
.
getLink
():
ImageLink
abstract
suspend
fun
Image
.
downloadAsByteArray
():
ByteArray
suspend
fun
Image
.
downloadAsByteArray
():
ByteArray
=
getLink
().
downloadAsByteArray
()
abstract
suspend
fun
Image
.
download
():
ByteReadPacket
suspend
fun
Image
.
download
():
ByteReadPacket
=
getLink
().
download
()
/**
/**
* 添加一个好友
* 添加一个好友
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt
View file @
5d46d1c4
...
@@ -36,7 +36,7 @@ interface Contact : CoroutineScope {
...
@@ -36,7 +36,7 @@ interface Contact : CoroutineScope {
*/
*/
suspend
fun
sendMessage
(
message
:
MessageChain
)
suspend
fun
sendMessage
(
message
:
MessageChain
)
suspend
fun
uploadImage
(
image
:
ExternalImage
):
Image
Id
suspend
fun
uploadImage
(
image
:
ExternalImage
):
Image
}
}
suspend
inline
fun
Contact
.
sendMessage
(
message
:
Message
)
=
sendMessage
(
message
.
toChain
())
suspend
inline
fun
Contact
.
sendMessage
(
message
:
Message
)
=
sendMessage
(
message
.
toChain
())
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/ContactList.kt
View file @
5d46d1c4
...
@@ -37,7 +37,7 @@ class ContactList<C : Contact>(@MiraiInternalAPI val delegate: LockFreeLinkedLis
...
@@ -37,7 +37,7 @@ class ContactList<C : Contact>(@MiraiInternalAPI val delegate: LockFreeLinkedLis
operator
fun
<
C
:
Contact
>
LockFreeLinkedList
<
C
>.
get
(
id
:
Long
):
C
{
operator
fun
<
C
:
Contact
>
LockFreeLinkedList
<
C
>.
get
(
id
:
Long
):
C
{
forEach
{
if
(
it
.
id
==
id
)
return
it
}
forEach
{
if
(
it
.
id
==
id
)
return
it
}
throw
NoSuchElementException
()
throw
NoSuchElementException
(
"No such contact with id $id"
)
}
}
fun
<
C
:
Contact
>
LockFreeLinkedList
<
C
>.
getOrNull
(
id
:
Long
):
C
?
{
fun
<
C
:
Contact
>
LockFreeLinkedList
<
C
>.
getOrNull
(
id
:
Long
):
C
?
{
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/MessagePacket.kt
View file @
5d46d1c4
...
@@ -6,7 +6,6 @@ import kotlinx.io.core.ByteReadPacket
...
@@ -6,7 +6,6 @@ import kotlinx.io.core.ByteReadPacket
import
net.mamoe.mirai.Bot
import
net.mamoe.mirai.Bot
import
net.mamoe.mirai.contact.*
import
net.mamoe.mirai.contact.*
import
net.mamoe.mirai.data.EventPacket
import
net.mamoe.mirai.data.EventPacket
import
net.mamoe.mirai.data.ImageLink
import
net.mamoe.mirai.event.events.BotEvent
import
net.mamoe.mirai.event.events.BotEvent
import
net.mamoe.mirai.message.data.*
import
net.mamoe.mirai.message.data.*
import
net.mamoe.mirai.utils.*
import
net.mamoe.mirai.utils.*
...
@@ -65,17 +64,14 @@ abstract class MessagePacketBase<TSender : QQ, TSubject : Contact>(_bot: Bot) :
...
@@ -65,17 +64,14 @@ abstract class MessagePacketBase<TSender : QQ, TSubject : Contact>(_bot: Bot) :
suspend
inline
fun
ExternalImage
.
upload
():
Image
=
this
.
upload
(
subject
)
suspend
inline
fun
ExternalImage
.
upload
():
Image
=
this
.
upload
(
subject
)
suspend
inline
fun
Image
.
send
()
=
this
.
sendTo
(
subject
)
suspend
inline
fun
Image
.
send
()
=
this
.
sendTo
(
subject
)
suspend
inline
fun
ImageId
.
send
()
=
this
.
sendTo
(
subject
)
suspend
inline
fun
Message
.
send
()
=
this
.
sendTo
(
subject
)
suspend
inline
fun
Message
.
send
()
=
this
.
sendTo
(
subject
)
suspend
inline
fun
String
.
send
()
=
this
.
toMessage
().
sendTo
(
subject
)
suspend
inline
fun
String
.
send
()
=
this
.
toMessage
().
sendTo
(
subject
)
// endregion
// endregion
// region Image download
// region Image download
suspend
inline
fun
Image
.
getLink
():
ImageLink
=
with
(
bot
)
{
getLink
()
}
suspend
inline
fun
Image
.
downloadAsByteArray
():
ByteArray
=
bot
.
run
{
downloadAsByteArray
()
}
suspend
inline
fun
Image
.
download
():
ByteReadPacket
=
bot
.
run
{
download
()
}
suspend
inline
fun
Image
.
downloadAsByteArray
():
ByteArray
=
getLink
().
downloadAsByteArray
()
suspend
inline
fun
Image
.
download
():
ByteReadPacket
=
getLink
().
download
()
// endregion
// endregion
fun
At
.
qq
():
QQ
=
bot
.
getQQ
(
this
.
target
)
fun
At
.
qq
():
QQ
=
bot
.
getQQ
(
this
.
target
)
...
...
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