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
5c287faf
Commit
5c287faf
authored
Feb 21, 2020
by
ryoii
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin'
parents
068de995
06381e8b
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
211 additions
and
28 deletions
+211
-28
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/ContactImpl.kt
...ommonMain/kotlin/net/mamoe/mirai/qqandroid/ContactImpl.kt
+15
-1
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
+8
-12
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Member.kt
...e/src/commonMain/kotlin/net.mamoe.mirai/contact/Member.kt
+3
-0
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/linear.kt
...ore/src/commonMain/kotlin/net.mamoe.mirai/event/linear.kt
+101
-0
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/subscriber.kt
...src/commonMain/kotlin/net.mamoe.mirai/event/subscriber.kt
+3
-0
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/GroupMessage.kt
...commonMain/kotlin/net.mamoe.mirai/message/GroupMessage.kt
+9
-8
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/MessagePacket.kt
...ommonMain/kotlin/net.mamoe.mirai/message/MessagePacket.kt
+49
-0
mirai-demos/mirai-demo-1/src/main/java/demo/subscribe/SubscribeSamples.kt
...i-demo-1/src/main/java/demo/subscribe/SubscribeSamples.kt
+23
-7
No files found.
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/ContactImpl.kt
View file @
5c287faf
...
...
@@ -166,7 +166,7 @@ internal class QQImpl(
}
@Suppress
(
"MemberVisibilityCanBePrivate"
,
"DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE"
)
@Suppress
(
"MemberVisibilityCanBePrivate"
)
internal
class
MemberImpl
(
qq
:
QQImpl
,
group
:
GroupImpl
,
...
...
@@ -286,6 +286,20 @@ internal class MemberImpl(
}
}
override
fun
hashCode
():
Int
{
var
result
=
bot
.
hashCode
()
result
=
31
*
result
+
id
.
hashCode
()
return
result
}
@Suppress
(
"DuplicatedCode"
)
override
fun
equals
(
other
:
Any
?):
Boolean
{
// 不要删除. trust me
if
(
this
===
other
)
return
true
if
(
other
!
is
Contact
)
return
false
if
(
this
::
class
!= other::class) return false
return this.id == other.id && this.bot == other.bot
}
override fun to
String
():
String
{
return
"Member($id)"
}
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.kt
View file @
5c287faf
...
...
@@ -9,7 +9,7 @@
package
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive
import
kotlinx.coroutines.
Completable
Deferred
import
kotlinx.coroutines.Deferred
import
kotlinx.coroutines.ExperimentalCoroutinesApi
import
kotlinx.io.core.ByteReadPacket
import
kotlinx.io.core.discardExact
...
...
@@ -19,11 +19,10 @@ import net.mamoe.mirai.contact.MemberPermission
import
net.mamoe.mirai.data.MemberInfo
import
net.mamoe.mirai.data.MultiPacket
import
net.mamoe.mirai.data.Packet
import
net.mamoe.mirai.event.ListeningStatus
import
net.mamoe.mirai.event.events.BotJoinGroupEvent
import
net.mamoe.mirai.event.events.BotOfflineEvent
import
net.mamoe.mirai.event.events.MemberJoinEvent
import
net.mamoe.mirai.event.subscrib
e
import
net.mamoe.mirai.event.subscrib
ingGetAsync
import
net.mamoe.mirai.message.FriendMessage
import
net.mamoe.mirai.message.data.MessageChain
import
net.mamoe.mirai.message.data.MessageSource
...
...
@@ -279,17 +278,14 @@ internal class MessageSvc {
override
val
groupId
:
Long
,
override
val
sourceMessage
:
MessageChain
)
:
MessageSource
{
lateinit
var
sequenceIdDeferred
:
Completable
Deferred
<
Int
>
lateinit
var
sequenceIdDeferred
:
Deferred
<
Int
>
@UseExperimental
(
MiraiExperimentalAPI
::
class
)
fun
startWaitingSequenceId
(
contact
:
Contact
)
{
sequenceIdDeferred
=
CompletableDeferred
()
contact
.
subscribe
<
OnlinePush
.
PbPushGroupMsg
.
SendGroupMessageReceipt
>
{
event
->
if
(
event
.
messageRandom
==
messageUid
.
toInt
())
{
sequenceIdDeferred
.
complete
(
event
.
sequenceId
)
return
@
subscribe
ListeningStatus
.
STOPPED
}
return
@
subscribe
ListeningStatus
.
LISTENING
sequenceIdDeferred
=
contact
.
subscribingGetAsync
<
OnlinePush
.
PbPushGroupMsg
.
SendGroupMessageReceipt
,
Int
>
{
if
(
it
.
messageRandom
==
messageUid
.
toInt
())
{
it
.
sequenceId
}
else
null
}
}
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Member.kt
View file @
5c287faf
...
...
@@ -72,6 +72,9 @@ interface Member : QQ, Contact {
/**
* 禁言.
*
* QQ 中最小操作和显示的时间都是一分钟.
* 机器人可以实现精确到秒, 会被客户端显示为 1 分钟但不影响实际禁言时间.
*
* 管理员可禁言成员, 群主可禁言管理员和群员.
*
* @param durationSeconds 持续时间. 精确到秒. 范围区间表示为 `(0s, 30days]`. 超过范围则会抛出异常.
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/linear.kt
View file @
5c287faf
...
...
@@ -9,3 +9,104 @@
package
net.mamoe.mirai.event
import
kotlinx.coroutines.*
import
net.mamoe.mirai.utils.MiraiExperimentalAPI
import
kotlin.coroutines.CoroutineContext
import
kotlin.coroutines.EmptyCoroutineContext
/**
* 挂起当前协程, 监听这个事件, 并尝试从这个事件中获取一个值.
*
* 若 [filter] 抛出了一个异常, 本函数会立即抛出这个异常.
*
* @param timeoutMillis 超时. 单位为毫秒. `-1` 为不限制
* @param filter 过滤器. 返回非 null 则代表得到了需要的值. [subscribingGet] 会返回这个值
*
* @see subscribingGetAsync 本函数的异步版本
*/
@MiraiExperimentalAPI
suspend
inline
fun
<
reified
E
:
Event
,
R
:
Any
>
subscribingGet
(
timeoutMillis
:
Long
=
-
1
,
noinline
filter
:
E
.(
E
)
->
R
?
// 不要 crossinline: crossinline 后 stacktrace 会不正常
):
R
{
require
(
timeoutMillis
==
-
1L
||
timeoutMillis
>
0
)
{
"timeoutMillis must be -1 or > 0"
}
return
subscribingGetOrNull
(
timeoutMillis
,
filter
)
?:
error
(
"timeout subscribingGet"
)
}
/**
* 挂起当前协程, 监听这个事件, 并尝试从这个事件中获取一个值.
*
* 若 [filter] 抛出了一个异常, 本函数会立即抛出这个异常.
*
* @param timeoutMillis 超时. 单位为毫秒. `-1` 为不限制
* @param filter 过滤器. 返回非 null 则代表得到了需要的值. [subscribingGet] 会返回这个值
*
* @see subscribingGetAsync 本函数的异步版本
*/
@MiraiExperimentalAPI
suspend
inline
fun
<
reified
E
:
Event
,
R
:
Any
>
subscribingGetOrNull
(
timeoutMillis
:
Long
=
-
1
,
noinline
filter
:
E
.(
E
)
->
R
?
// 不要 crossinline: crossinline 后 stacktrace 会不正常
):
R
?
{
require
(
timeoutMillis
==
-
1L
||
timeoutMillis
>
0
)
{
"timeoutMillis must be -1 or > 0"
}
var
result
:
R
?
=
null
var
resultThrowable
:
Throwable
?
=
null
if
(
timeoutMillis
==
-
1L
)
{
@Suppress
(
"DuplicatedCode"
)
// for better performance
coroutineScope
{
var
listener
:
Listener
<
E
>?
=
null
listener
=
this
.
subscribe
{
val
value
=
try
{
filter
.
invoke
(
this
,
it
)
}
catch
(
e
:
Exception
)
{
resultThrowable
=
e
return
@
subscribe
ListeningStatus
.
STOPPED
.
also
{
listener
!!
.
complete
()
}
}
if
(
value
!=
null
)
{
result
=
value
return
@
subscribe
ListeningStatus
.
STOPPED
.
also
{
listener
!!
.
complete
()
}
}
else
return
@
subscribe
ListeningStatus
.
LISTENING
}
}
}
else
{
withTimeoutOrNull
(
timeoutMillis
)
{
var
listener
:
Listener
<
E
>?
=
null
@Suppress
(
"DuplicatedCode"
)
// for better performance
listener
=
this
.
subscribe
{
val
value
=
try
{
filter
.
invoke
(
this
,
it
)
}
catch
(
e
:
Exception
)
{
resultThrowable
=
e
return
@
subscribe
ListeningStatus
.
STOPPED
.
also
{
listener
!!
.
complete
()
}
}
if
(
value
!=
null
)
{
result
=
value
return
@
subscribe
ListeningStatus
.
STOPPED
.
also
{
listener
!!
.
complete
()
}
}
else
return
@
subscribe
ListeningStatus
.
LISTENING
}
}
}
resultThrowable
?.
let
{
throw
it
}
return
result
}
/**
* 异步监听这个事件, 并尝试从这个事件中获取一个值.
*
* 若 [filter] 抛出了一个异常, [Deferred.await] 会抛出这个异常或.
*
* @param timeoutMillis 超时. 单位为毫秒. `-1` 为不限制
* @param coroutineContext 额外的 [CoroutineContext]
* @param filter 过滤器. 返回非 null 则代表得到了需要的值. [subscribingGet] 会返回这个值
*/
@MiraiExperimentalAPI
inline
fun
<
reified
E
:
Event
,
R
:
Any
>
CoroutineScope
.
subscribingGetAsync
(
coroutineContext
:
CoroutineContext
=
EmptyCoroutineContext
,
timeoutMillis
:
Long
=
-
1
,
noinline
filter
:
E
.(
E
)
->
R
?
// 不要 crossinline: crossinline 后 stacktrace 会不正常
):
Deferred
<
R
>
=
this
.
async
(
coroutineContext
)
{
subscribingGet
(
timeoutMillis
,
filter
)
}
\ No newline at end of file
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/subscriber.kt
View file @
5c287faf
...
...
@@ -101,6 +101,9 @@ interface Listener<in E : Event> : CompletableJob {
*
*
@
param
coroutineContext
给事件监听协程的额外的
[
CoroutineContext
]
*
*
@
see
subscribingGet
监听一个事件
,
并尝试从这个事件中获取一个值
.
*
@
see
subscribingGetAsync
异步监听一个事件
,
并尝试从这个事件中获取一个值
.
*
*
@
see
subscribeAlways
一直监听
*
@
see
subscribeOnce
只监听一次
*
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/GroupMessage.kt
View file @
5c287faf
...
...
@@ -9,6 +9,7 @@
package
net.mamoe.mirai.message
import
kotlinx.coroutines.Job
import
net.mamoe.mirai.Bot
import
net.mamoe.mirai.contact.*
import
net.mamoe.mirai.event.Event
...
...
@@ -44,25 +45,25 @@ class GroupMessage(
* 对于好友消息事件, 这个方法将会给好友 ([subject]) 发送消息
* 对于群消息事件, 这个方法将会给群 ([subject]) 发送消息
*/
suspend
inline
fun
quoteReply
(
message
:
MessageChain
)
=
reply
(
this
.
message
.
quote
()
+
message
)
suspend
inline
fun
quoteReply
(
message
:
MessageChain
)
:
MessageReceipt
<
Group
>
=
reply
(
this
.
message
.
quote
()
+
message
)
suspend
inline
fun
quoteReply
(
message
:
Message
)
=
reply
(
this
.
message
.
quote
()
+
message
)
suspend
inline
fun
quoteReply
(
plain
:
String
)
=
reply
(
this
.
message
.
quote
()
+
plain
)
suspend
inline
fun
quoteReply
(
message
:
Message
)
:
MessageReceipt
<
Group
>
=
reply
(
this
.
message
.
quote
()
+
message
)
suspend
inline
fun
quoteReply
(
plain
:
String
)
:
MessageReceipt
<
Group
>
=
reply
(
this
.
message
.
quote
()
+
plain
)
@JvmName
(
"reply2"
)
suspend
inline
fun
String
.
quoteReply
()
=
quoteReply
(
this
)
suspend
inline
fun
String
.
quoteReply
()
:
MessageReceipt
<
Group
>
=
quoteReply
(
this
)
@JvmName
(
"reply2"
)
suspend
inline
fun
Message
.
quoteReply
()
=
quoteReply
(
this
)
suspend
inline
fun
Message
.
quoteReply
()
:
MessageReceipt
<
Group
>
=
quoteReply
(
this
)
@JvmName
(
"reply2"
)
suspend
inline
fun
MessageChain
.
quoteReply
()
=
quoteReply
(
this
)
suspend
inline
fun
MessageChain
.
quoteReply
()
:
MessageReceipt
<
Group
>
=
quoteReply
(
this
)
suspend
inline
fun
MessageChain
.
recall
()
=
group
.
recall
(
this
)
suspend
inline
fun
MessageSource
.
recall
()
=
group
.
recall
(
this
)
inline
fun
MessageSource
.
recallIn
(
delay
:
Long
)
=
group
.
recallIn
(
this
,
delay
)
inline
fun
MessageChain
.
recallIn
(
delay
:
Long
)
=
group
.
recallIn
(
this
,
delay
)
inline
fun
MessageSource
.
recallIn
(
delay
:
Long
)
:
Job
=
group
.
recallIn
(
this
,
delay
)
inline
fun
MessageChain
.
recallIn
(
delay
:
Long
)
:
Job
=
group
.
recallIn
(
this
,
delay
)
override
fun
toString
():
String
=
"GroupMessage(group=${group.id}, senderName=$senderName, sender=${sender.id}, permission=${permission.name}, message=$message)"
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/MessagePacket.kt
View file @
5c287faf
...
...
@@ -21,6 +21,8 @@ import net.mamoe.mirai.contact.Member
import
net.mamoe.mirai.contact.QQ
import
net.mamoe.mirai.data.Packet
import
net.mamoe.mirai.event.events.BotEvent
import
net.mamoe.mirai.event.subscribingGet
import
net.mamoe.mirai.event.subscribingGetAsync
import
net.mamoe.mirai.message.data.*
import
net.mamoe.mirai.utils.*
import
kotlin.jvm.JvmName
...
...
@@ -109,6 +111,10 @@ abstract class MessagePacketBase<TSender : QQ, TSubject : Contact>(_bot: Bot) :
suspend
inline
fun
String
.
send
()
=
this
.
toMessage
().
sendTo
(
subject
)
// endregion
operator
fun
<
M
:
Message
>
get
(
at
:
Message
.
Key
<
M
>):
M
{
return
this
.
message
[
at
]
}
/**
* 创建 @ 这个账号的消息. 当且仅当消息为群消息时可用. 否则将会抛出 [IllegalArgumentException]
*/
...
...
@@ -134,4 +140,47 @@ abstract class MessagePacketBase<TSender : QQ, TSubject : Contact>(_bot: Bot) :
*/
suspend
inline
fun
Image
.
download
():
ByteReadPacket
=
bot
.
run
{
download
()
}
// endregion
}
/**
* 判断两个 [MessagePacket] 的 [MessagePacket.sender] 和 [MessagePacket.subject] 是否相同
*/
fun
MessagePacket
<*,
*>.
isContextIdenticalWith
(
another
:
MessagePacket
<
*
,
*
>):
Boolean
{
return
this
.
sender
==
another
.
sender
&&
this
.
subject
==
another
.
subject
}
/**
* 挂起当前协程, 等待下一条 [MessagePacket.sender] 和 [MessagePacket.subject] 与 [P] 相同且通过 [筛选][filter] 的 [MessagePacket]
*
* 若 [filter] 抛出了一个异常, 本函数会立即抛出这个异常.
*
* @param timeoutMillis 超时. 单位为毫秒. `-1` 为不限制
* @param filter 过滤器. 返回非 null 则代表得到了需要的值. [subscribingGet] 会返回这个值
*
* @see subscribingGetAsync 本函数的异步版本
*/
suspend
inline
fun
<
reified
P
:
MessagePacket
<
*
,
*
>>
P
.
nextMessage
(
timeoutMillis
:
Long
=
-
1
,
crossinline
filter
:
P
.(
P
)
->
Boolean
):
P
{
return
subscribingGet
<
P
,
P
>(
timeoutMillis
)
{
takeIf
{
this
.
isContextIdenticalWith
(
this
@
nextMessage
)
}
?.
takeIf
{
filter
(
it
,
it
)
}
}
}
/**
* 挂起当前协程, 等待下一条 [MessagePacket.sender] 和 [MessagePacket.subject] 与 [P] 相同的 [MessagePacket]
*
* 若 [filter] 抛出了一个异常, 本函数会立即抛出这个异常.
*
* @param timeoutMillis 超时. 单位为毫秒. `-1` 为不限制
*
* @see subscribingGetAsync 本函数的异步版本
*/
suspend
inline
fun
<
reified
P
:
MessagePacket
<
*
,
*
>>
P
.
nextMessage
(
timeoutMillis
:
Long
=
-
1
):
P
{
return
subscribingGet
<
P
,
P
>(
timeoutMillis
)
{
takeIf
{
this
.
isContextIdenticalWith
(
this
@
nextMessage
)
}
}
}
\ No newline at end of file
mirai-demos/mirai-demo-1/src/main/java/demo/subscribe/SubscribeSamples.kt
View file @
5c287faf
...
...
@@ -16,17 +16,14 @@ import net.mamoe.mirai.Bot
import
net.mamoe.mirai.BotAccount
import
net.mamoe.mirai.alsoLogin
import
net.mamoe.mirai.contact.QQ
import
net.mamoe.mirai.contact.isOperator
import
net.mamoe.mirai.contact.sendMessage
import
net.mamoe.mirai.event.*
import
net.mamoe.mirai.message.FriendMessage
import
net.mamoe.mirai.message.GroupMessage
import
net.mamoe.mirai.message.data.AtAll
import
net.mamoe.mirai.message.data.Image
import
net.mamoe.mirai.message.data.PlainText
import
net.mamoe.mirai.message.data.firstOrNull
import
net.mamoe.mirai.message.data.*
import
net.mamoe.mirai.message.nextMessage
import
net.mamoe.mirai.message.sendAsImageTo
import
net.mamoe.mirai.qqandroid.Bot
import
net.mamoe.mirai.qqandroid.QQAndroid
import
net.mamoe.mirai.utils.FileBasedDeviceInfo
import
net.mamoe.mirai.utils.MiraiInternalAPI
import
java.io.File
...
...
@@ -49,7 +46,7 @@ private fun readTestAccount(): BotAccount? {
@Suppress
(
"UNUSED_VARIABLE"
)
suspend
fun
main
()
{
val
bot
=
QQAndroid
.
Bot
(
// JVM 下也可以不写 `QQAndroid.` 引用顶层函数
val
bot
=
Bot
(
// JVM 下也可以不写 `QQAndroid.` 引用顶层函数
123456789
,
"123456"
)
{
...
...
@@ -207,6 +204,25 @@ fun Bot.messageDSL() {
// sender: QQ
// it: String (来自 MessageChain.toString)
// group: Group
case
(
"recall"
)
{
reply
(
"😎"
).
recallIn
(
3000
)
// 3 秒后自动撤回这条消息
}
case
(
"禁言"
)
{
// 挂起当前协程, 等待下一条满足条件的消息.
// 发送 "禁言" 后需要再发送一条消息 at 一个人.
val
value
:
At
=
nextMessage
{
message
.
any
(
At
)
}[
At
]
value
.
member
().
mute
(
10
)
}
startsWith
(
"群名="
)
{
if
(!
sender
.
isOperator
())
{
sender
.
mute
(
5
)
return
@
startsWith
}
group
.
name
=
it
}
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment