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
4e27ad32
Commit
4e27ad32
authored
Oct 27, 2019
by
Him188
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Improve concurrency
parent
fa0f4e49
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
149 additions
and
68 deletions
+149
-68
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt
+1
-1
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt
.../src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt
+2
-1
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/Event.kt
...core/src/commonMain/kotlin/net.mamoe.mirai/event/Event.kt
+24
-1
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/MessageSubscribers.kt
...onMain/kotlin/net.mamoe.mirai/event/MessageSubscribers.kt
+37
-10
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/internal/InternalEventListeners.kt
.../net.mamoe.mirai/event/internal/InternalEventListeners.kt
+23
-5
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/BotNetworkHandler.kt
...nMain/kotlin/net.mamoe.mirai/network/BotNetworkHandler.kt
+2
-2
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/BotSession.kt
...c/commonMain/kotlin/net.mamoe.mirai/network/BotSession.kt
+1
-2
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/TIMBotNetworkHandler.kt
....mamoe.mirai/network/protocol/tim/TIMBotNetworkHandler.kt
+13
-8
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/handler/PacketHandler.kt
...mamoe.mirai/network/protocol/tim/handler/PacketHandler.kt
+3
-5
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/handler/TemporaryPacketHandler.kt
...ai/network/protocol/tim/handler/TemporaryPacketHandler.kt
+14
-16
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/UploadGroupImage.kt
...ai/network/protocol/tim/packet/action/UploadGroupImage.kt
+18
-13
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/MiraiLogger.kt
...rc/commonMain/kotlin/net.mamoe.mirai/utils/MiraiLogger.kt
+4
-0
mirai-demos/mirai-demo-1/src/main/java/demo/subscribe/SubscribeSamples.kt
...i-demo-1/src/main/java/demo/subscribe/SubscribeSamples.kt
+3
-3
mirai-demos/mirai-demo-gentleman/build.gradle
mirai-demos/mirai-demo-gentleman/build.gradle
+4
-1
No files found.
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt
View file @
4e27ad32
...
@@ -127,7 +127,7 @@ class Bot(val account: BotAccount, val logger: MiraiLogger) {
...
@@ -127,7 +127,7 @@ class Bot(val account: BotAccount, val logger: MiraiLogger) {
suspend
fun
getGroup
(
id
:
GroupId
):
Group
=
id
.
value
.
let
{
suspend
fun
getGroup
(
id
:
GroupId
):
Group
=
id
.
value
.
let
{
if
(
groups
.
containsKey
(
it
))
groups
[
it
]
!!
if
(
groups
.
containsKey
(
it
))
groups
[
it
]
!!
else
groupsLock
.
withLock
{
else
groupsLock
.
withLock
{
groups
.
getOrPut
(
it
)
{
Group
(
this
@Bot
,
i
t
)
}
groups
.
getOrPut
(
it
)
{
Group
(
this
@Bot
,
i
d
)
}
}
}
}
}
}
}
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt
View file @
4e27ad32
...
@@ -66,7 +66,8 @@ inline class GroupInternalId(val value: UInt)
...
@@ -66,7 +66,8 @@ inline class GroupInternalId(val value: UInt)
* - Group ID([Group.internalId]) 是与调用 API 时使用的 id.(在 QQ 客户端中不可见)
* - Group ID([Group.internalId]) 是与调用 API 时使用的 id.(在 QQ 客户端中不可见)
* @author Him188moe
* @author Him188moe
*/
*/
class
Group
internal
constructor
(
bot
:
Bot
,
id
:
UInt
)
:
Contact
(
bot
,
id
)
{
@Suppress
(
"MemberVisibilityCanBePrivate"
,
"CanBeParameter"
)
class
Group
internal
constructor
(
bot
:
Bot
,
val
groupId
:
GroupId
)
:
Contact
(
bot
,
groupId
.
value
)
{
val
internalId
=
GroupId
(
id
).
toInternalId
()
val
internalId
=
GroupId
(
id
).
toInternalId
()
val
members
:
ContactList
<
QQ
>
val
members
:
ContactList
<
QQ
>
//todo members
//todo members
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/Event.kt
View file @
4e27ad32
...
@@ -8,6 +8,8 @@ import kotlinx.coroutines.withContext
...
@@ -8,6 +8,8 @@ import kotlinx.coroutines.withContext
import
net.mamoe.mirai.contact.Contact
import
net.mamoe.mirai.contact.Contact
import
net.mamoe.mirai.event.internal.broadcastInternal
import
net.mamoe.mirai.event.internal.broadcastInternal
import
net.mamoe.mirai.network.BotNetworkHandler
import
net.mamoe.mirai.network.BotNetworkHandler
import
net.mamoe.mirai.utils.DefaultLogger
import
net.mamoe.mirai.utils.MiraiLogger
import
net.mamoe.mirai.utils.log
import
net.mamoe.mirai.utils.log
import
kotlin.coroutines.CoroutineContext
import
kotlin.coroutines.CoroutineContext
import
kotlin.coroutines.EmptyCoroutineContext
import
kotlin.coroutines.EmptyCoroutineContext
...
@@ -39,6 +41,18 @@ abstract class Event {
...
@@ -39,6 +41,18 @@ abstract class Event {
fun
cancel
()
{
fun
cancel
()
{
cancelled
=
true
cancelled
=
true
}
}
init
{
if
(
EventDebuggingFlag
)
{
EventLogger
.
logDebug
(
this
::
class
.
simpleName
+
" created"
)
}
}
}
internal
object
EventLogger
:
MiraiLogger
by
DefaultLogger
(
"Event"
)
val
EventDebuggingFlag
:
Boolean
by
lazy
{
false
}
}
/**
/**
...
@@ -58,7 +72,16 @@ interface Cancellable {
...
@@ -58,7 +72,16 @@ interface Cancellable {
@Suppress
(
"UNCHECKED_CAST"
)
@Suppress
(
"UNCHECKED_CAST"
)
@JvmOverloads
@JvmOverloads
suspend
fun
<
E
:
Event
>
E
.
broadcast
(
context
:
CoroutineContext
=
EmptyCoroutineContext
):
E
{
suspend
fun
<
E
:
Event
>
E
.
broadcast
(
context
:
CoroutineContext
=
EmptyCoroutineContext
):
E
{
return
withContext
(
EventScope
.
coroutineContext
+
context
)
{
this
@
broadcast
.
broadcastInternal
()
}
if
(
EventDebuggingFlag
)
{
EventLogger
.
logDebug
(
this
::
class
.
simpleName
+
" pre broadcast"
)
}
try
{
return
withContext
(
EventScope
.
coroutineContext
+
context
)
{
this
@
broadcast
.
broadcastInternal
()
}
}
finally
{
if
(
EventDebuggingFlag
)
{
EventLogger
.
logDebug
(
this
::
class
.
simpleName
+
" after broadcast"
)
}
}
}
}
/**
/**
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/MessageSubscribers.kt
View file @
4e27ad32
...
@@ -10,6 +10,9 @@ import net.mamoe.mirai.event.events.BotEvent
...
@@ -10,6 +10,9 @@ import net.mamoe.mirai.event.events.BotEvent
import
net.mamoe.mirai.event.events.FriendMessageEvent
import
net.mamoe.mirai.event.events.FriendMessageEvent
import
net.mamoe.mirai.event.events.GroupMessageEvent
import
net.mamoe.mirai.event.events.GroupMessageEvent
import
net.mamoe.mirai.message.*
import
net.mamoe.mirai.message.*
import
net.mamoe.mirai.utils.ExternalImage
import
net.mamoe.mirai.utils.sendTo
import
net.mamoe.mirai.utils.upload
import
kotlin.jvm.JvmName
import
kotlin.jvm.JvmName
/**
/**
...
@@ -33,8 +36,19 @@ abstract class SenderAndMessage<S : Contact>(
...
@@ -33,8 +36,19 @@ abstract class SenderAndMessage<S : Contact>(
*/
*/
suspend
fun
reply
(
message
:
MessageChain
)
=
subject
.
sendMessage
(
message
)
suspend
fun
reply
(
message
:
MessageChain
)
=
subject
.
sendMessage
(
message
)
suspend
fun
reply
(
plain
:
String
)
=
reply
(
PlainText
(
plain
))
suspend
fun
reply
(
message
:
Message
)
=
reply
(
message
.
toChain
())
suspend
fun
reply
(
message
:
Message
)
=
reply
(
message
.
toChain
())
suspend
fun
reply
(
plain
:
String
)
=
reply
(
PlainText
(
plain
))
// region Send to subject
suspend
inline
fun
ExternalImage
.
send
()
=
this
.
sendTo
(
subject
)
suspend
inline
fun
ExternalImage
.
upload
():
Image
=
this
.
upload
(
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
)
// endregion
}
}
/**
/**
...
@@ -134,11 +148,16 @@ suspend inline fun Bot.subscribeFriendMessages(noinline listeners: suspend Messa
...
@@ -134,11 +148,16 @@ suspend inline fun Bot.subscribeFriendMessages(noinline listeners: suspend Messa
internal
typealias
MessageListener
<
T
>
=
@MessageListenerDsl
suspend
T
.(
String
)
->
Unit
internal
typealias
MessageListener
<
T
>
=
@MessageListenerDsl
suspend
T
.(
String
)
->
Unit
internal
typealias
MessageReplier
<
T
>
=
@MessageListenerDsl
suspend
T
.(
String
)
->
String
internal
typealias
MessageReplier
<
T
>
=
@MessageListenerDsl
suspend
T
.(
String
)
->
Message
internal
typealias
StringReplier
<
T
>
=
@MessageListenerDsl
suspend
T
.(
String
)
->
String
internal
suspend
inline
operator
fun
<
T
:
SenderAndMessage
<
*
>>
MessageListener
<
T
>.
invoke
(
t
:
T
)
=
this
.
invoke
(
t
,
t
.
message
.
toString
()
)
internal
suspend
inline
operator
fun
<
T
:
SenderAndMessage
<
*
>>
MessageListener
<
T
>.
invoke
(
t
:
T
)
=
this
.
invoke
(
t
,
t
.
message
.
stringValue
)
@JvmName
(
"invoke1"
)
//Avoid Platform declaration clash
@JvmName
(
"invoke1"
)
//Avoid Platform declaration clash
internal
suspend
inline
operator
fun
<
T
:
SenderAndMessage
<
*
>>
MessageReplier
<
T
>.
invoke
(
t
:
T
)
=
this
.
invoke
(
t
,
t
.
message
.
toString
())
internal
suspend
inline
operator
fun
<
T
:
SenderAndMessage
<
*
>>
StringReplier
<
T
>.
invoke
(
t
:
T
):
String
=
this
.
invoke
(
t
,
t
.
message
.
stringValue
)
@JvmName
(
"invoke2"
)
//Avoid Platform declaration clash
internal
suspend
inline
operator
fun
<
T
:
SenderAndMessage
<
*
>>
MessageReplier
<
T
>.
invoke
(
t
:
T
):
Message
=
this
.
invoke
(
t
,
t
.
message
.
stringValue
)
/**
/**
* 消息订阅构造器
* 消息订阅构造器
...
@@ -148,27 +167,35 @@ internal suspend inline operator fun <T : SenderAndMessage<*>> MessageReplier<T>
...
@@ -148,27 +167,35 @@ internal suspend inline operator fun <T : SenderAndMessage<*>> MessageReplier<T>
*/
*/
@Suppress
(
"unused"
)
@Suppress
(
"unused"
)
@MessageListenerDsl
@MessageListenerDsl
inline
class
MessageSubscribersBuilder
<
T
:
SenderAndMessage
<
*
>>(
//TODO 将这个类 inline 后会导致 kotlin 编译错误. 等待修复后再 inline
class
MessageSubscribersBuilder
<
T
:
SenderAndMessage
<
*
>>(
val
handlerConsumer
:
suspend
(
MessageListener
<
T
>)
->
Unit
val
handlerConsumer
:
suspend
(
MessageListener
<
T
>)
->
Unit
)
{
)
{
suspend
inline
fun
case
(
equals
:
String
,
trim
:
Boolean
=
true
,
noinline
listener
:
MessageListener
<
T
>)
=
content
({
equals
==
if
(
trim
)
it
.
trim
()
else
it
},
listener
)
suspend
inline
fun
case
(
equals
:
String
,
trim
:
Boolean
=
true
,
noinline
listener
:
MessageListener
<
T
>)
=
content
({
equals
==
if
(
trim
)
it
.
trim
()
else
it
},
listener
)
suspend
inline
fun
contains
(
value
:
String
,
noinline
listener
:
MessageListener
<
T
>)
=
content
({
value
in
it
},
listener
)
suspend
inline
fun
contains
(
value
:
String
,
noinline
listener
:
MessageListener
<
T
>)
=
content
({
value
in
it
},
listener
)
suspend
inline
fun
replyEndsWith
(
value
:
String
,
noinline
replier
:
MessageReplier
<
T
>)
=
content
({
it
.
endsWith
(
value
)
})
{
replier
(
this
)
}
suspend
inline
fun
startsWith
(
start
:
String
,
noinline
listener
:
MessageListener
<
T
>)
=
content
({
it
.
startsWith
(
start
)
},
listener
)
suspend
inline
fun
startsWith
(
start
:
String
,
noinline
listener
:
MessageListener
<
T
>)
=
content
({
it
.
startsWith
(
start
)
},
listener
)
suspend
inline
fun
endsWith
(
start
:
String
,
noinline
listener
:
MessageListener
<
T
>)
=
content
({
it
.
endsWith
(
start
)
},
listener
)
suspend
inline
fun
endsWith
(
start
:
String
,
noinline
listener
:
MessageListener
<
T
>)
=
content
({
it
.
endsWith
(
start
)
},
listener
)
suspend
inline
fun
sentBy
(
id
:
UInt
,
noinline
listener
:
MessageListener
<
T
>)
=
content
({
sender
.
id
==
id
},
listener
)
suspend
inline
fun
sentBy
(
id
:
UInt
,
noinline
listener
:
MessageListener
<
T
>)
=
content
({
sender
.
id
==
id
},
listener
)
suspend
inline
fun
sentBy
(
id
:
Long
,
noinline
listener
:
MessageListener
<
T
>)
=
sentBy
(
id
.
toUInt
(),
listener
)
suspend
inline
fun
sentBy
(
id
:
Long
,
noinline
listener
:
MessageListener
<
T
>)
=
sentBy
(
id
.
toUInt
(),
listener
)
suspend
inline
fun
<
reified
M
:
Message
>
has
(
noinline
listener
:
MessageListener
<
T
>)
=
handlerConsumer
{
if
(
message
.
any
<
M
>())
listener
(
this
)
}
suspend
inline
fun
<
reified
M
:
Message
>
has
(
noinline
listener
:
MessageListener
<
T
>)
=
handlerConsumer
{
if
(
message
.
any
<
M
>())
listener
(
this
)
}
suspend
inline
fun
content
(
noinline
filter
:
T
.(
String
)
->
Boolean
,
noinline
listener
:
MessageListener
<
T
>)
=
suspend
inline
fun
content
(
noinline
filter
:
T
.(
String
)
->
Boolean
,
noinline
listener
:
MessageListener
<
T
>)
=
handlerConsumer
{
if
(
this
.
filter
(
message
.
toString
()))
listener
(
this
)
}
handlerConsumer
{
if
(
this
.
filter
(
message
.
stringValue
))
listener
(
this
)
}
suspend
infix
fun
String
.
caseReply
(
replier
:
StringReplier
<
T
>)
=
case
(
this
,
true
)
{
this
@
case
.
reply
(
replier
(
this
))
}
suspend
infix
fun
String
.
containsReply
(
replier
:
StringReplier
<
T
>)
=
content
({
this
@
containsReply
in
it
})
{
replier
(
this
)
}
suspend
infix
fun
String
.
startsWithReply
(
replier
:
StringReplier
<
T
>)
=
content
({
it
.
startsWith
(
this
@
startsWithReply
)
})
{
replier
(
this
)
}
suspend
infix
fun
String
.
endswithReply
(
replier
:
StringReplier
<
T
>)
=
content
({
it
.
endsWith
(
this
@
endswithReply
)
})
{
replier
(
this
)
}
suspend
infix
fun
String
.
reply
(
reply
:
String
)
=
case
(
this
)
{
this
@
case
.
reply
(
reply
)
}
suspend
infix
fun
String
.
reply
(
reply
:
StringReplier
<
T
>)
=
case
(
this
)
{
this
@
case
.
reply
(
reply
(
this
))
}
/* 易产生迷惑感
suspend inline fun replyCase(equals: String, trim: Boolean = true, noinline replier: MessageReplier<T>) = case(equals, trim) { reply(replier(this)) }
suspend inline fun replyCase(equals: String, trim: Boolean = true, noinline replier: MessageReplier<T>) = case(equals, trim) { reply(replier(this)) }
suspend inline fun replyContains(value: String, noinline replier: MessageReplier<T>) = content({ value in it }) { replier(this) }
suspend inline fun replyContains(value: String, noinline replier: MessageReplier<T>) = content({ value in it }) { replier(this) }
suspend inline fun replyStartsWith(value: String, noinline replier: MessageReplier<T>) = content({ it.startsWith(value) }) { replier(this) }
suspend inline fun replyStartsWith(value: String, noinline replier: MessageReplier<T>) = content({ it.startsWith(value) }) { replier(this) }
suspend inline fun replyEndsWith(value: String, noinline replier: MessageReplier<T>) = content({ it.endsWith(value) }) { replier(this) }
suspend
infix
fun
String
.
reply
(
reply
:
String
)
=
case
(
this
)
{
this
.
reply
(
reply
)
}
*/
suspend
infix
fun
String
.
reply
(
reply
:
MessageReplier
<
T
>)
=
case
(
this
)
{
this
.
reply
(
reply
(
this
))
}
}
}
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/internal/InternalEventListeners.kt
View file @
4e27ad32
...
@@ -21,11 +21,11 @@ import kotlin.reflect.KClass
...
@@ -21,11 +21,11 @@ import kotlin.reflect.KClass
* @author Him188moe
* @author Him188moe
*/
*/
internal
suspend
fun
<
E
:
Event
>
KClass
<
E
>.
subscribeInternal
(
listener
:
Listener
<
E
>):
Unit
=
with
(
this
.
listeners
())
{
internal
suspend
fun
<
E
:
Event
>
KClass
<
E
>.
subscribeInternal
(
listener
:
Listener
<
E
>):
Unit
=
with
(
this
.
listeners
())
{
if
(
mainMutex
.
tryLock
())
{
//能锁则代表这个事件目前没有正在广播.
if
(
mainMutex
.
tryLock
(
listener
))
{
//能锁则代表这个事件目前没有正在广播.
try
{
try
{
add
(
listener
)
//直接修改主监听者列表
add
(
listener
)
//直接修改主监听者列表
}
finally
{
}
finally
{
mainMutex
.
unlock
()
mainMutex
.
unlock
(
listener
)
}
}
return
return
}
}
...
@@ -38,7 +38,7 @@ internal suspend fun <E : Event> KClass<E>.subscribeInternal(listener: Listener<
...
@@ -38,7 +38,7 @@ internal suspend fun <E : Event> KClass<E>.subscribeInternal(listener: Listener<
EventScope
.
launch
{
EventScope
.
launch
{
//启动协程并等待正在进行的广播结束, 然后将缓存转移到主监听者列表
//启动协程并等待正在进行的广播结束, 然后将缓存转移到主监听者列表
//启动后的协程马上就会因为锁而被挂起
//启动后的协程马上就会因为锁而被挂起
mainMutex
.
withLock
{
mainMutex
.
withLock
(
listener
)
{
cacheMutex
.
withLock
{
cacheMutex
.
withLock
{
if
(
cache
.
size
!=
0
)
{
if
(
cache
.
size
!=
0
)
{
addAll
(
cache
)
addAll
(
cache
)
...
@@ -55,6 +55,7 @@ internal suspend fun <E : Event> KClass<E>.subscribeInternal(listener: Listener<
...
@@ -55,6 +55,7 @@ internal suspend fun <E : Event> KClass<E>.subscribeInternal(listener: Listener<
* @author Him188moe
* @author Him188moe
*/
*/
sealed
class
Listener
<
in
E
:
Event
>
{
sealed
class
Listener
<
in
E
:
Event
>
{
internal
val
lock
=
Mutex
()
abstract
suspend
fun
onEvent
(
event
:
E
):
ListeningStatus
abstract
suspend
fun
onEvent
(
event
:
E
):
ListeningStatus
}
}
...
@@ -127,8 +128,25 @@ internal object EventListenerManger {
...
@@ -127,8 +128,25 @@ internal object EventListenerManger {
@Suppress
(
"UNCHECKED_CAST"
)
@Suppress
(
"UNCHECKED_CAST"
)
internal
suspend
fun
<
E
:
Event
>
E
.
broadcastInternal
():
E
{
internal
suspend
fun
<
E
:
Event
>
E
.
broadcastInternal
():
E
{
suspend
fun
callListeners
(
listeners
:
EventListeners
<
in
E
>)
=
listeners
.
mainMutex
.
withLock
{
suspend
fun
callListeners
(
listeners
:
EventListeners
<
in
E
>)
{
listeners
.
inlinedRemoveIf
{
it
.
onEvent
(
this
)
==
ListeningStatus
.
STOPPED
}
suspend
fun
callAndRemoveIfRequired
()
{
listeners
.
inlinedRemoveIf
{
if
(
it
.
lock
.
tryLock
())
{
try
{
it
.
onEvent
(
this
)
==
ListeningStatus
.
STOPPED
}
finally
{
it
.
lock
.
unlock
()
}
}
else
false
}
}
//自己持有, 则是在一个事件中
if
(
listeners
.
mainMutex
.
holdsLock
(
listeners
))
{
callAndRemoveIfRequired
()
}
else
listeners
.
mainMutex
.
withLock
(
listeners
)
{
callAndRemoveIfRequired
()
}
}
}
callListeners
(
this
::
class
.
listeners
()
as
EventListeners
<
in
E
>)
callListeners
(
this
::
class
.
listeners
()
as
EventListeners
<
in
E
>)
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/BotNetworkHandler.kt
View file @
4e27ad32
...
@@ -2,7 +2,6 @@ package net.mamoe.mirai.network
...
@@ -2,7 +2,6 @@ package net.mamoe.mirai.network
import
kotlinx.coroutines.CancellationException
import
kotlinx.coroutines.CancellationException
import
kotlinx.coroutines.CoroutineScope
import
kotlinx.coroutines.CoroutineScope
import
kotlinx.coroutines.Job
import
kotlinx.coroutines.cancelChildren
import
kotlinx.coroutines.cancelChildren
import
net.mamoe.mirai.network.protocol.tim.TIMBotNetworkHandler.BotSocketAdapter
import
net.mamoe.mirai.network.protocol.tim.TIMBotNetworkHandler.BotSocketAdapter
import
net.mamoe.mirai.network.protocol.tim.TIMBotNetworkHandler.LoginHandler
import
net.mamoe.mirai.network.protocol.tim.TIMBotNetworkHandler.LoginHandler
...
@@ -16,6 +15,7 @@ import net.mamoe.mirai.network.protocol.tim.packet.login.LoginResult
...
@@ -16,6 +15,7 @@ import net.mamoe.mirai.network.protocol.tim.packet.login.LoginResult
import
net.mamoe.mirai.network.protocol.tim.packet.login.RequestSKeyPacket
import
net.mamoe.mirai.network.protocol.tim.packet.login.RequestSKeyPacket
import
net.mamoe.mirai.utils.BotNetworkConfiguration
import
net.mamoe.mirai.utils.BotNetworkConfiguration
import
net.mamoe.mirai.utils.io.PlatformDatagramChannel
import
net.mamoe.mirai.utils.io.PlatformDatagramChannel
import
kotlin.coroutines.ContinuationInterceptor
/**
/**
* Mirai 的网络处理器, 它承担所有数据包([Packet])的处理任务.
* Mirai 的网络处理器, 它承担所有数据包([Packet])的处理任务.
...
@@ -87,6 +87,6 @@ interface BotNetworkHandler<Socket : DataPacketSocketAdapter> : CoroutineScope {
...
@@ -87,6 +87,6 @@ interface BotNetworkHandler<Socket : DataPacketSocketAdapter> : CoroutineScope {
*/
*/
suspend
fun
close
(
cause
:
Throwable
?
=
null
)
{
suspend
fun
close
(
cause
:
Throwable
?
=
null
)
{
//todo check??
//todo check??
coroutineContext
[
Job
]
!!
.
cancelChildren
(
CancellationException
(
"handler closed"
,
cause
))
coroutineContext
[
ContinuationInterceptor
]
!!
.
cancelChildren
(
CancellationException
(
"handler closed"
,
cause
))
}
}
}
}
\ No newline at end of file
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/BotSession.kt
View file @
4e27ad32
...
@@ -79,8 +79,7 @@ class BotSession(
...
@@ -79,8 +79,7 @@ class BotSession(
* @see Bot.withSession 转换接收器 (receiver, 即 `this` 的指向) 为 [BotSession]
* @see Bot.withSession 转换接收器 (receiver, 即 `this` 的指向) 为 [BotSession]
*/
*/
suspend
inline
fun
<
reified
P
:
ServerPacket
,
R
>
OutgoingPacket
.
sendAndExpect
(
noinline
handler
:
suspend
(
P
)
->
R
):
CompletableDeferred
<
R
>
{
suspend
inline
fun
<
reified
P
:
ServerPacket
,
R
>
OutgoingPacket
.
sendAndExpect
(
noinline
handler
:
suspend
(
P
)
->
R
):
CompletableDeferred
<
R
>
{
val
deferred
:
CompletableDeferred
<
R
>
=
val
deferred
:
CompletableDeferred
<
R
>
=
CompletableDeferred
(
coroutineContext
[
Job
])
coroutineContext
[
Job
].
takeIf
{
it
!=
null
}
?.
let
{
CompletableDeferred
<
R
>(
it
)
}
?:
CompletableDeferred
()
bot
.
network
.
addHandler
(
TemporaryPacketHandler
(
P
::
class
,
deferred
,
this
@BotSession
).
also
{
bot
.
network
.
addHandler
(
TemporaryPacketHandler
(
P
::
class
,
deferred
,
this
@BotSession
).
also
{
it
.
toSend
(
this
)
it
.
toSend
(
this
)
it
.
onExpect
(
handler
)
it
.
onExpect
(
handler
)
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/TIMBotNetworkHandler.kt
View file @
4e27ad32
...
@@ -24,7 +24,6 @@ import net.mamoe.mirai.network.protocol.tim.packet.login.*
...
@@ -24,7 +24,6 @@ import net.mamoe.mirai.network.protocol.tim.packet.login.*
import
net.mamoe.mirai.network.session
import
net.mamoe.mirai.network.session
import
net.mamoe.mirai.qqAccount
import
net.mamoe.mirai.qqAccount
import
net.mamoe.mirai.utils.*
import
net.mamoe.mirai.utils.*
import
net.mamoe.mirai.utils.internal.inlinedRemoveIf
import
net.mamoe.mirai.utils.io.*
import
net.mamoe.mirai.utils.io.*
import
kotlin.coroutines.CoroutineContext
import
kotlin.coroutines.CoroutineContext
...
@@ -129,10 +128,11 @@ internal class TIMBotNetworkHandler internal constructor(private val bot: Bot) :
...
@@ -129,10 +128,11 @@ internal class TIMBotNetworkHandler internal constructor(private val bot: Bot) :
try
{
try
{
channel
.
read
(
buffer
)
// JVM: withContext(IO)
channel
.
read
(
buffer
)
// JVM: withContext(IO)
}
catch
(
e
:
ReadPacketInternalException
)
{
}
catch
(
e
:
ReadPacketInternalException
)
{
// read failed, continue and reread
bot
.
logger
.
logError
(
"Socket channel read failed: ${e.message}"
)
continue
continue
}
catch
(
e
:
Throwable
)
{
}
catch
(
e
:
Throwable
)
{
e
.
log
()
// other unexpected exceptions caught.
bot
.
logger
.
logError
(
"Caught unexpected exceptions"
)
bot
.
logger
.
logError
(
e
)
continue
continue
}
finally
{
}
finally
{
if
(!
buffer
.
canRead
()
||
buffer
.
readRemaining
==
0
)
{
//size==0
if
(!
buffer
.
canRead
()
||
buffer
.
readRemaining
==
0
)
{
//size==0
...
@@ -146,7 +146,11 @@ internal class TIMBotNetworkHandler internal constructor(private val bot: Bot) :
...
@@ -146,7 +146,11 @@ internal class TIMBotNetworkHandler internal constructor(private val bot: Bot) :
// `.use`: Ensure that the packet is consumed **totally**
// `.use`: Ensure that the packet is consumed **totally**
// so that all the buffers are released
// so that all the buffers are released
ByteReadPacket
(
buffer
,
IoBuffer
.
Pool
).
use
{
ByteReadPacket
(
buffer
,
IoBuffer
.
Pool
).
use
{
distributePacket
(
it
.
parseServerPacket
(
buffer
.
readRemaining
))
try
{
distributePacket
(
it
.
parseServerPacket
(
buffer
.
readRemaining
))
}
catch
(
e
:
Exception
)
{
bot
.
logger
.
logError
(
e
)
}
}
}
}
}
}
}
...
@@ -200,14 +204,15 @@ internal class TIMBotNetworkHandler internal constructor(private val bot: Bot) :
...
@@ -200,14 +204,15 @@ internal class TIMBotNetworkHandler internal constructor(private val bot: Bot) :
bot
.
logger
.
logCyan
(
"Packet received: $packet"
)
bot
.
logger
.
logCyan
(
"Packet received: $packet"
)
}
}
//Remove first to release the lock
handlersLock
.
withLock
{
handlersLock
.
withLock
{
temporaryPacketHandlers
.
inlinedRemoveIf
{
temporaryPacketHandlers
.
filter
{
it
.
filter
(
session
,
packet
)
}
it
.
shouldRemove
(
this
@TIMBotNetworkHandler
[
ActionPacketHandler
].
session
,
packet
)
}.
forEach
{
}
it
.
doReceive
(
packet
)
}
}
if
(
packet
is
ServerEventPacket
)
{
if
(
packet
is
ServerEventPacket
)
{
//
must
ensure the response packet is sent
//ensure the response packet is sent
sendPacket
(
packet
.
ResponsePacket
(
bot
.
qqAccount
,
sessionKey
))
sendPacket
(
packet
.
ResponsePacket
(
bot
.
qqAccount
,
sessionKey
))
}
}
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/handler/PacketHandler.kt
View file @
4e27ad32
...
@@ -2,7 +2,6 @@ package net.mamoe.mirai.network.protocol.tim.handler
...
@@ -2,7 +2,6 @@ package net.mamoe.mirai.network.protocol.tim.handler
import
net.mamoe.mirai.network.BotSession
import
net.mamoe.mirai.network.BotSession
import
net.mamoe.mirai.network.protocol.tim.packet.ServerPacket
import
net.mamoe.mirai.network.protocol.tim.packet.ServerPacket
import
kotlin.reflect.KClass
/**
/**
* 数据包(接受/发送)处理器
* 数据包(接受/发送)处理器
...
@@ -20,14 +19,13 @@ abstract class PacketHandler(
...
@@ -20,14 +19,13 @@ abstract class PacketHandler(
}
}
internal
class
PacketHandlerNode
<
T
:
PacketHandler
>(
internal
class
PacketHandlerNode
<
T
:
PacketHandler
>(
val
clazz
:
KClass
<
T
>,
val
instance
:
T
,
val
instance
:
T
,
val
key
:
PacketHandler
.
Key
<
T
>
val
key
:
PacketHandler
.
Key
<
T
>
)
)
internal
fun
<
T
:
PacketHandler
>
T
.
asNode
(
key
:
PacketHandler
.
Key
<
T
>):
PacketHandlerNode
<
T
>
{
internal
fun
<
T
:
PacketHandler
>
T
.
asNode
(
key
:
PacketHandler
.
Key
<
T
>):
PacketHandlerNode
<
T
>
{
@Suppress
(
"UNCHECKED_CAST"
)
@Suppress
(
"UNCHECKED_CAST"
)
return
PacketHandlerNode
(
this
::
class
as
KClass
<
T
>,
this
,
key
)
return
PacketHandlerNode
(
this
,
key
)
}
}
internal
open
class
PacketHandlerList
:
MutableList
<
PacketHandlerNode
<
*
>>
by
mutableListOf
()
{
internal
open
class
PacketHandlerList
:
MutableList
<
PacketHandlerNode
<
*
>>
by
mutableListOf
()
{
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/handler/TemporaryPacketHandler.kt
View file @
4e27ad32
...
@@ -20,9 +20,9 @@ import kotlin.reflect.KClass
...
@@ -20,9 +20,9 @@ import kotlin.reflect.KClass
* @see BotSession.sendAndExpect
* @see BotSession.sendAndExpect
*/
*/
class
TemporaryPacketHandler
<
P
:
ServerPacket
,
R
>(
class
TemporaryPacketHandler
<
P
:
ServerPacket
,
R
>(
private
val
expectationClass
:
KClass
<
P
>,
private
val
expectationClass
:
KClass
<
P
>,
private
val
deferred
:
CompletableDeferred
<
R
>,
private
val
deferred
:
CompletableDeferred
<
R
>,
private
val
fromSession
:
BotSession
private
val
fromSession
:
BotSession
)
{
)
{
private
lateinit
var
toSend
:
OutgoingPacket
private
lateinit
var
toSend
:
OutgoingPacket
...
@@ -45,19 +45,17 @@ class TemporaryPacketHandler<P : ServerPacket, R>(
...
@@ -45,19 +45,17 @@ class TemporaryPacketHandler<P : ServerPacket, R>(
session
.
socket
.
sendPacket
(
toSend
)
session
.
socket
.
sendPacket
(
toSend
)
}
}
suspend
fun
shouldRemove
(
session
:
BotSession
,
packet
:
ServerPacket
):
Boolean
{
suspend
fun
filter
(
session
:
BotSession
,
packet
:
ServerPacket
):
Boolean
=
expectationClass
.
isInstance
(
packet
)
&&
session
===
this
.
fromSession
if
(
expectationClass
.
isInstance
(
packet
)
&&
session
===
this
.
fromSession
)
{
suspend
fun
doReceive
(
packet
:
ServerPacket
)
{
@Suppress
(
"UNCHECKED_CAST"
)
@Suppress
(
"UNCHECKED_CAST"
)
val
ret
=
try
{
val
ret
=
try
{
handler
(
packet
as
P
)
handler
(
packet
as
P
)
}
catch
(
e
:
Exception
)
{
}
catch
(
e
:
Exception
)
{
deferred
.
completeExceptionally
(
e
)
deferred
.
completeExceptionally
(
e
)
return
true
return
}
deferred
.
complete
(
ret
)
return
true
}
}
return
false
deferred
.
complete
(
ret
)
return
}
}
}
}
\ No newline at end of file
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/UploadGroupImage.kt
View file @
4e27ad32
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
package
net.mamoe.mirai.network.protocol.tim.packet.action
package
net.mamoe.mirai.network.protocol.tim.packet.action
import
kotlinx.coroutines.withContext
import
kotlinx.io.core.*
import
kotlinx.io.core.*
import
net.mamoe.mirai.contact.Group
import
net.mamoe.mirai.contact.Group
import
net.mamoe.mirai.contact.GroupId
import
net.mamoe.mirai.contact.GroupId
...
@@ -16,6 +17,7 @@ import net.mamoe.mirai.qqAccount
...
@@ -16,6 +17,7 @@ import net.mamoe.mirai.qqAccount
import
net.mamoe.mirai.utils.ExternalImage
import
net.mamoe.mirai.utils.ExternalImage
import
net.mamoe.mirai.utils.httpPostGroupImage
import
net.mamoe.mirai.utils.httpPostGroupImage
import
net.mamoe.mirai.utils.io.*
import
net.mamoe.mirai.utils.io.*
import
kotlin.coroutines.coroutineContext
/**
/**
...
@@ -32,24 +34,27 @@ class OverFileSizeMaxException : IllegalStateException()
...
@@ -32,24 +34,27 @@ class OverFileSizeMaxException : IllegalStateException()
* @throws OverFileSizeMaxException 如果文件过大, 服务器拒绝接收时
* @throws OverFileSizeMaxException 如果文件过大, 服务器拒绝接收时
*/
*/
suspend
fun
Group
.
uploadImage
(
image
:
ExternalImage
):
ImageId
=
withSession
{
suspend
fun
Group
.
uploadImage
(
image
:
ExternalImage
):
ImageId
=
withSession
{
val
userContext
=
coroutineContext
GroupImageIdRequestPacket
(
bot
.
qqAccount
,
internalId
,
image
,
sessionKey
)
GroupImageIdRequestPacket
(
bot
.
qqAccount
,
internalId
,
image
,
sessionKey
)
.
sendAndExpect
<
GroupImageIdRequestPacket
.
Response
,
Unit
>
{
.
sendAndExpect
<
GroupImageIdRequestPacket
.
Response
,
Unit
>
{
when
(
it
.
state
)
{
withContext
(
userContext
)
{
GroupImageIdRequestPacket
.
Response
.
State
.
REQUIRE_UPLOAD
->
{
when
(
it
.
state
)
{
httpPostGroupImage
(
GroupImageIdRequestPacket
.
Response
.
State
.
REQUIRE_UPLOAD
->
{
botAccount
=
bot
.
qqAccount
,
httpPostGroupImage
(
groupId
=
GroupId
(
id
),
botAccount
=
bot
.
qqAccount
,
imageInput
=
image
.
input
,
groupId
=
GroupId
(
id
),
inputSize
=
image
.
inputSize
,
imageInput
=
image
.
input
,
uKeyHex
=
it
.
uKey
!!
.
toUHexString
(
""
)
inputSize
=
image
.
inputSize
,
)
uKeyHex
=
it
.
uKey
!!
.
toUHexString
(
""
)
}
)
}
GroupImageIdRequestPacket
.
Response
.
State
.
ALREADY_EXISTS
->
{
GroupImageIdRequestPacket
.
Response
.
State
.
ALREADY_EXISTS
->
{
}
}
GroupImageIdRequestPacket
.
Response
.
State
.
OVER_FILE_SIZE_MAX
->
throw
OverFileSizeMaxException
()
GroupImageIdRequestPacket
.
Response
.
State
.
OVER_FILE_SIZE_MAX
->
throw
OverFileSizeMaxException
()
}
}
}
}.
join
()
}.
join
()
image
.
groupImageId
image
.
groupImageId
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/MiraiLogger.kt
View file @
4e27ad32
...
@@ -42,6 +42,8 @@ interface MiraiLogger {
...
@@ -42,6 +42,8 @@ interface MiraiLogger {
fun
logError
(
any
:
Any
?)
fun
logError
(
any
:
Any
?)
fun
logError
(
e
:
Throwable
)
=
log
(
e
)
fun
logDebug
(
any
:
Any
?)
fun
logDebug
(
any
:
Any
?)
fun
logCyan
(
any
:
Any
?)
fun
logCyan
(
any
:
Any
?)
...
@@ -94,6 +96,8 @@ abstract class MiraiLoggerPlatformBase : MiraiLogger {
...
@@ -94,6 +96,8 @@ abstract class MiraiLoggerPlatformBase : MiraiLogger {
follower
?.
logError
(
any
)
follower
?.
logError
(
any
)
}
}
override
fun
logError
(
e
:
Throwable
)
=
log
(
e
)
final
override
fun
logDebug
(
any
:
Any
?)
{
final
override
fun
logDebug
(
any
:
Any
?)
{
logDebug0
(
any
)
logDebug0
(
any
)
follower
?.
logDebug
(
any
)
follower
?.
logDebug
(
any
)
...
...
mirai-demos/mirai-demo-1/src/main/java/demo/subscribe/SubscribeSamples.kt
View file @
4e27ad32
...
@@ -47,7 +47,7 @@ private fun readTestAccount(): BotAccount? {
...
@@ -47,7 +47,7 @@ private fun readTestAccount(): BotAccount? {
suspend
fun
Bot
.
messageDSL
()
{
suspend
fun
Bot
.
messageDSL
()
{
//监听所有 bot 的来自所有群和好友的消息
//监听所有 bot 的来自所有群和好友的消息
subscribeMessages
{
subscribeMessages
{
replyCase
(
"你好"
)
{
"你好"
}
"你好"
reply
"你好!"
has
<
Image
>
{
has
<
Image
>
{
// this: SenderAndMessage
// this: SenderAndMessage
...
@@ -65,9 +65,9 @@ suspend fun Bot.messageDSL() {
...
@@ -65,9 +65,9 @@ suspend fun Bot.messageDSL() {
reply
(
message
)
reply
(
message
)
}
}
replyContains
(
"123"
)
{
"你的消息里面包含 123"
}
"123"
reply
"你的消息里面包含 123"
replyCase
(
"我的qq"
)
{
sender
.
id
.
toString
()
}
"我的qq"
reply
{
sender
.
id
.
toString
()
}
sentBy
(
1040400290
)
{
sentBy
(
1040400290
)
{
reply
(
"是你!"
)
reply
(
"是你!"
)
...
...
mirai-demos/mirai-demo-gentleman/build.gradle
View file @
4e27ad32
...
@@ -2,7 +2,10 @@ apply plugin: "kotlin"
...
@@ -2,7 +2,10 @@ apply plugin: "kotlin"
apply
plugin:
"java"
apply
plugin:
"java"
dependencies
{
dependencies
{
compile
project
(
":mirai-core"
)
implementation
project
(
":mirai-core"
)
api
group:
'org.jetbrains.kotlin'
,
name:
'kotlin-stdlib-jdk8'
,
version:
kotlin_version
api
group:
'org.jetbrains.kotlin'
,
name:
'kotlin-stdlib-jdk8'
,
version:
kotlin_version
api
group:
'org.jetbrains.kotlinx'
,
name:
'kotlinx-coroutines-core'
,
version:
coroutines_version
api
group:
'org.jetbrains.kotlinx'
,
name:
'kotlinx-coroutines-core'
,
version:
coroutines_version
compile
group:
'com.alibaba'
,
name:
'fastjson'
,
version:
'1.2.62'
implementation
'org.jsoup:jsoup:1.12.1'
}
}
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