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
d3270bb3
Commit
d3270bb3
authored
Oct 28, 2019
by
Him188
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Adjust running coroutineContext
parent
ead17724
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
47 additions
and
41 deletions
+47
-41
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt
.../src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt
+4
-6
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/BotNetworkHandler.kt
...nMain/kotlin/net.mamoe.mirai/network/BotNetworkHandler.kt
+4
-3
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/BotSession.kt
...c/commonMain/kotlin/net.mamoe.mirai/network/BotSession.kt
+4
-4
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/TIMBotNetworkHandler.kt
....mamoe.mirai/network/protocol/tim/TIMBotNetworkHandler.kt
+11
-14
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/handler/TemporaryPacketHandler.kt
...ai/network/protocol/tim/handler/TemporaryPacketHandler.kt
+16
-7
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/login/Captcha.kt
....mamoe.mirai/network/protocol/tim/packet/login/Captcha.kt
+6
-6
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/Tested.kt
...ore/src/commonMain/kotlin/net.mamoe.mirai/utils/Tested.kt
+2
-1
No files found.
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt
View file @
d3270bb3
...
...
@@ -14,8 +14,7 @@ import net.mamoe.mirai.withSession
class
ContactList
<
C
:
Contact
>
:
MutableMap
<
UInt
,
C
>
by
mutableMapOf
()
/**
* 联系人. 虽然叫做联系人, 但它直营
* 现支持的联系人只有 [QQ号][QQ] 和 [群][Group].
* 联系人. 虽然叫做联系人, 但他的子类有 [QQ] 和 [群][Group].
*
* @param bot 这个联系人所属 [Bot]
* @param id 可以是 QQ 号码或者群号码 [GroupId].
...
...
@@ -70,8 +69,7 @@ inline class GroupInternalId(val value: UInt)
class
Group
internal
constructor
(
bot
:
Bot
,
val
groupId
:
GroupId
)
:
Contact
(
bot
,
groupId
.
value
)
{
val
internalId
=
GroupId
(
id
).
toInternalId
()
val
members
:
ContactList
<
QQ
>
//todo members
get
()
=
throw
UnsupportedOperationException
(
"Not yet supported"
)
get
()
=
TODO
(
"Implementing group members is less important"
)
override
suspend
fun
sendMessage
(
message
:
MessageChain
)
{
bot
.
network
[
EventPacketHandler
].
sendGroupMessage
(
this
,
message
)
...
...
@@ -87,7 +85,7 @@ class Group internal constructor(bot: Bot, val groupId: GroupId) : Contact(bot,
inline
fun
<
R
>
Group
.
withSession
(
block
:
BotSession
.()
->
R
):
R
=
bot
.
withSession
(
block
)
/**
* QQ
账号
.
* QQ
对象
.
* 注意: 一个 [QQ] 实例并不是独立的, 它属于一个 [Bot].
*
* A QQ instance helps you to receive event from or sendPacket event to.
...
...
@@ -95,7 +93,7 @@ inline fun <R> Group.withSession(block: BotSession.() -> R): R = bot.withSession
*
* @author Him188moe
*/
class
QQ
internal
constructor
(
bot
:
Bot
,
number
:
UInt
)
:
Contact
(
bot
,
number
)
{
class
QQ
internal
constructor
(
bot
:
Bot
,
id
:
UInt
)
:
Contact
(
bot
,
id
)
{
override
suspend
fun
sendMessage
(
message
:
MessageChain
)
{
bot
.
network
[
EventPacketHandler
].
sendFriendMessage
(
this
,
message
)
}
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/BotNetworkHandler.kt
View file @
d3270bb3
...
...
@@ -2,6 +2,7 @@ package net.mamoe.mirai.network
import
kotlinx.coroutines.CancellationException
import
kotlinx.coroutines.CoroutineScope
import
kotlinx.coroutines.Job
import
kotlinx.coroutines.cancelChildren
import
net.mamoe.mirai.network.protocol.tim.TIMBotNetworkHandler.BotSocketAdapter
import
net.mamoe.mirai.network.protocol.tim.TIMBotNetworkHandler.LoginHandler
...
...
@@ -15,7 +16,6 @@ import net.mamoe.mirai.network.protocol.tim.packet.login.LoginResult
import
net.mamoe.mirai.network.protocol.tim.packet.login.RequestSKeyPacket
import
net.mamoe.mirai.utils.BotNetworkConfiguration
import
net.mamoe.mirai.utils.io.PlatformDatagramChannel
import
kotlin.coroutines.ContinuationInterceptor
/**
* Mirai 的网络处理器, 它承担所有数据包([Packet])的处理任务.
...
...
@@ -86,7 +86,8 @@ interface BotNetworkHandler<Socket : DataPacketSocketAdapter> : CoroutineScope {
* 关闭网络接口, 停止所有有关协程和任务
*/
suspend
fun
close
(
cause
:
Throwable
?
=
null
)
{
//todo check??
coroutineContext
[
ContinuationInterceptor
]
!!
.
cancelChildren
(
CancellationException
(
"handler closed"
,
cause
))
val
job
=
coroutineContext
[
Job
]
checkNotNull
(
job
)
{
"Job should not be null because there will always be a SupervisorJob. There may be a internal mistake"
}
job
.
cancelChildren
(
CancellationException
(
"handler closed"
,
cause
))
}
}
\ No newline at end of file
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/BotSession.kt
View file @
d3270bb3
...
...
@@ -33,7 +33,7 @@ internal inline fun TIMBotNetworkHandler.BotSession(
*/
class
BotSession
(
val
bot
:
Bot
,
val
sessionKey
:
ByteArray
,
//TODO 协议抽象? 可能并不是所有协议均需要 sessionKey
val
sessionKey
:
ByteArray
,
val
socket
:
DataPacketSocketAdapter
,
val
NetworkScope
:
CoroutineScope
)
{
...
...
@@ -61,7 +61,7 @@ class BotSession(
/**
* 发送一个数据包, 并期待接受一个特定的 [ServerPacket][P].
*
发送成功后, 该方法会等待收到 [ServerPacket][P] 直到超时
.
*
这个方法会立即返回
.
*
* 实现方法:
* ```kotlin
...
...
@@ -75,13 +75,13 @@ class BotSession(
*
* @param checkSequence 是否期待 [ServerPacket.sequenceId] 与 [OutgoingPacket.sequenceId] 相同的包.
* @param P 期待的包
* @param handler 处理期待的包
* @param handler 处理期待的包
. 将会在调用 [sendAndExpect] 的函数所在 [coroutineContext] 下执行.
*
* @see Bot.withSession 转换接收器 (receiver, 即 `this` 的指向) 为 [BotSession]
*/
suspend
inline
fun
<
reified
P
:
ServerPacket
,
R
>
OutgoingPacket
.
sendAndExpect
(
checkSequence
:
Boolean
=
true
,
noinline
handler
:
suspend
(
P
)
->
R
):
CompletableDeferred
<
R
>
{
val
deferred
:
CompletableDeferred
<
R
>
=
CompletableDeferred
(
coroutineContext
[
Job
])
bot
.
network
.
addHandler
(
TemporaryPacketHandler
(
P
::
class
,
deferred
,
this
@BotSession
,
checkSequence
).
also
{
bot
.
network
.
addHandler
(
TemporaryPacketHandler
(
P
::
class
,
deferred
,
this
@BotSession
,
checkSequence
,
coroutineContext
+
deferred
).
also
{
it
.
toSend
(
this
)
it
.
onExpect
(
handler
)
})
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/TIMBotNetworkHandler.kt
View file @
d3270bb3
...
...
@@ -36,7 +36,8 @@ internal class TIMBotNetworkHandler internal constructor(private val bot: Bot) :
BotNetworkHandler
<
TIMBotNetworkHandler
.
BotSocketAdapter
>,
PacketHandlerList
()
{
override
val
coroutineContext
:
CoroutineContext
=
Dispatchers
.
Default
+
CoroutineExceptionHandler
{
_
,
e
->
bot
.
logger
.
log
(
e
)
}
Dispatchers
.
Default
+
CoroutineExceptionHandler
{
_
,
e
->
bot
.
logger
.
log
(
e
)
}
+
SupervisorJob
()
override
lateinit
var
socket
:
BotSocketAdapter
private
set
...
...
@@ -156,7 +157,7 @@ internal class TIMBotNetworkHandler internal constructor(private val bot: Bot) :
}
}
internal
suspend
fun
resendTouch
():
LoginResult
{
internal
suspend
fun
resendTouch
():
LoginResult
=
coroutineScope
{
if
(
::
loginHandler
.
isInitialized
)
loginHandler
.
close
()
loginHandler
=
LoginHandler
(
configuration
)
...
...
@@ -169,9 +170,9 @@ internal class TIMBotNetworkHandler internal constructor(private val bot: Bot) :
loginResult
.
complete
(
LoginResult
.
TIMEOUT
)
}
}
sendPacket
(
TouchPacket
(
bot
.
qqAccount
,
this
.
serverIp
))
sendPacket
(
TouchPacket
(
bot
.
qqAccount
,
serverIp
))
return
loginResult
.
await
()
return
@
coroutineScope
loginResult
.
await
()
}
private
suspend
inline
fun
<
reified
P
:
ServerPacket
>
expectPacket
():
CompletableDeferred
<
P
>
{
...
...
@@ -199,20 +200,19 @@ internal class TIMBotNetworkHandler internal constructor(private val bot: Bot) :
}
packet
.
use
{
val
name
=
packet
::
class
.
simpleName
if
(
name
!=
null
&&
!
name
.
endsWith
(
"Encrypted"
)
&&
!
name
.
endsWith
(
"Raw"
))
{
packet
::
class
.
simpleName
?.
takeIf
{
!
it
.
endsWith
(
"Encrypted"
)
&&
!
it
.
endsWith
(
"Raw"
)
}
?.
let
{
bot
.
logger
.
logCyan
(
"Packet received: $packet"
)
}
//Remove first to release the lock
//
Remove first to release the lock
handlersLock
.
withLock
{
temporaryPacketHandlers
.
filter
{
it
.
filter
(
session
,
packet
)
}
}.
forEach
{
it
.
doReceive
(
packet
)
it
.
doReceive
WithoutExceptions
(
packet
)
}
if
(
packet
is
ServerEventPacket
)
{
//
e
nsure the response packet is sent
//
E
nsure the response packet is sent
sendPacket
(
packet
.
ResponsePacket
(
bot
.
qqAccount
,
sessionKey
))
}
...
...
@@ -220,7 +220,7 @@ internal class TIMBotNetworkHandler internal constructor(private val bot: Bot) :
return
@
coroutineScope
}
//
t
hey should be called in sequence otherwise because packet is lock-free
//
T
hey should be called in sequence otherwise because packet is lock-free
loginHandler
.
onPacketReceived
(
packet
)
this
@TIMBotNetworkHandler
.
forEach
{
it
.
instance
.
onPacketReceived
(
packet
)
...
...
@@ -293,9 +293,6 @@ internal class TIMBotNetworkHandler internal constructor(private val bot: Bot) :
private
lateinit
var
loginIP
:
String
private
var
privateKey
:
ByteArray
=
getRandomByteArray
(
16
)
/**
* 0828_decr_key
*/
private
lateinit
var
sessionResponseDecryptionKey
:
IoBuffer
private
var
captchaSectionId
:
Int
=
1
...
...
@@ -406,7 +403,7 @@ internal class TIMBotNetworkHandler internal constructor(private val bot: Bot) :
bot
.
qqAccount
,
token0825
,
code
,
packet
.
verification
Token
packet
.
captcha
Token
)
)
}
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/handler/TemporaryPacketHandler.kt
View file @
d3270bb3
@
file
:
Suppress
(
"EXPERIMENTAL_API_USAGE"
)
package
net.mamoe.mirai.network.protocol.tim.handler
import
kotlinx.coroutines.CompletableDeferred
import
kotlinx.coroutines.withContext
import
net.mamoe.mirai.network.BotSession
import
net.mamoe.mirai.network.protocol.tim.packet.OutgoingPacket
import
net.mamoe.mirai.network.protocol.tim.packet.ServerPacket
import
kotlin.coroutines.CoroutineContext
import
kotlin.reflect.KClass
/**
...
...
@@ -23,7 +27,11 @@ class TemporaryPacketHandler<P : ServerPacket, R>(
private
val
expectationClass
:
KClass
<
P
>,
private
val
deferred
:
CompletableDeferred
<
R
>,
private
val
fromSession
:
BotSession
,
private
val
checkSequence
:
Boolean
private
val
checkSequence
:
Boolean
,
/**
* 调用者的 [CoroutineContext]
*/
private
val
callerContext
:
CoroutineContext
)
{
private
lateinit
var
toSend
:
OutgoingPacket
...
...
@@ -40,21 +48,22 @@ class TemporaryPacketHandler<P : ServerPacket, R>(
this
.
handler
=
handler
}
suspend
fun
send
(
session
:
BotSession
)
{
internal
suspend
fun
send
(
session
:
BotSession
)
{
require
(
::
handler
.
isInitialized
)
{
"handler is not initialized"
}
this
.
session
=
session
session
.
socket
.
sendPacket
(
toSend
)
}
@ExperimentalUnsignedTypes
fun
filter
(
session
:
BotSession
,
packet
:
ServerPacket
):
Boolean
=
internal
fun
filter
(
session
:
BotSession
,
packet
:
ServerPacket
):
Boolean
=
expectationClass
.
isInstance
(
packet
)
&&
session
===
this
.
fromSession
&&
if
(
checkSequence
)
packet
.
sequenceId
==
toSend
.
sequenceId
else
true
suspend
fun
doReceive
(
packet
:
ServerPacket
)
{
internal
suspend
fun
doReceiveWithoutExceptions
(
packet
:
ServerPacket
)
{
@Suppress
(
"UNCHECKED_CAST"
)
val
ret
=
try
{
handler
(
packet
as
P
)
}
catch
(
e
:
Exception
)
{
withContext
(
callerContext
)
{
handler
(
packet
as
P
)
}
}
catch
(
e
:
Throwable
)
{
deferred
.
completeExceptionally
(
e
)
return
}
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/login/Captcha.kt
View file @
d3270bb3
...
...
@@ -15,7 +15,7 @@ import net.mamoe.mirai.utils.io.*
class
RequestCaptchaTransmissionPacket
(
private
val
bot
:
UInt
,
private
val
token0825
:
ByteArray
,
private
val
verification
Sequence
:
Int
,
private
val
captcha
Sequence
:
Int
,
private
val
token00BA
:
ByteArray
)
:
OutgoingPacket
()
{
@Tested
...
...
@@ -31,7 +31,7 @@ class RequestCaptchaTransmissionPacket(
writeHex
(
"01 03 00 19"
)
writeHex
(
TIMProtocol
.
publicKey
)
writeHex
(
"13 00 05 00 00 00 00"
)
writeUByte
(
verification
Sequence
.
toUByte
())
writeUByte
(
captcha
Sequence
.
toUByte
())
writeHex
(
"00 28"
)
writeFully
(
token00BA
)
writeHex
(
"00 10"
)
...
...
@@ -48,7 +48,7 @@ class SubmitCaptchaPacket(
private
val
bot
:
UInt
,
private
val
token0825
:
ByteArray
,
private
val
captcha
:
String
,
private
val
verification
Token
:
IoBuffer
private
val
captcha
Token
:
IoBuffer
)
:
OutgoingPacket
()
{
init
{
require
(
captcha
.
length
==
4
)
{
"captcha.length must == 4"
}
...
...
@@ -71,7 +71,7 @@ class SubmitCaptchaPacket(
writeHex
(
"14 00 05 00 00 00 00 00 04"
)
writeStringUtf8
(
captcha
.
toUpperCase
())
writeHex
(
"00 38"
)
writeFully
(
verification
Token
)
writeFully
(
captcha
Token
)
writeShort
(
16
)
writeHex
(
TIMProtocol
.
key00BAFix
)
//16
...
...
@@ -113,14 +113,14 @@ class OutgoingCaptchaRefreshPacket(
open
class
CaptchaTransmissionResponsePacket
(
input
:
ByteReadPacket
)
:
ServerCaptchaPacket
(
input
)
{
lateinit
var
captchaSectionN
:
IoBuffer
lateinit
var
verification
Token
:
IoBuffer
//56bytes
lateinit
var
captcha
Token
:
IoBuffer
//56bytes
var
transmissionCompleted
:
Boolean
=
false
//验证码是否已经传输完成
lateinit
var
token00BA
:
ByteArray
//40 bytes
override
fun
decode
()
=
with
(
input
)
{
input
.
discardExact
(
10
)
//13 00 05 01 00 00 01 23 00 38
verification
Token
=
readIoBuffer
(
56
)
captcha
Token
=
readIoBuffer
(
56
)
val
length
=
readShort
()
captchaSectionN
=
readIoBuffer
(
length
)
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/Tested.kt
View file @
d3270bb3
...
...
@@ -5,4 +5,5 @@ package net.mamoe.mirai.utils
*
* @author Him188moe
*/
internal
annotation
class
Tested
\ No newline at end of file
@Suppress
(
"unused"
)
internal
annotation
class
Tested
(
val
date
:
String
=
""
)
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment