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
6cf563c8
Commit
6cf563c8
authored
Feb 25, 2020
by
jiahua.liu
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/master'
parents
5402505a
8b9cef05
Changes
22
Hide whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
250 additions
and
145 deletions
+250
-145
CHANGELOG.md
CHANGELOG.md
+9
-0
gradle.properties
gradle.properties
+2
-1
mirai-api-http/README_CH.md
mirai-api-http/README_CH.md
+45
-43
mirai-api-http/src/main/kotlin/net/mamoe/mirai/api/http/data/common/BotEventDTO.kt
...otlin/net/mamoe/mirai/api/http/data/common/BotEventDTO.kt
+1
-1
mirai-api-http/src/main/kotlin/net/mamoe/mirai/api/http/data/common/MessageDTO.kt
...kotlin/net/mamoe/mirai/api/http/data/common/MessageDTO.kt
+30
-22
mirai-api-http/src/main/kotlin/net/mamoe/mirai/api/http/queue/MessageQueue.kt
...ain/kotlin/net/mamoe/mirai/api/http/queue/MessageQueue.kt
+12
-10
mirai-api-http/src/main/kotlin/net/mamoe/mirai/api/http/route/AuthRouteModule.kt
.../kotlin/net/mamoe/mirai/api/http/route/AuthRouteModule.kt
+1
-1
mirai-api-http/src/main/kotlin/net/mamoe/mirai/api/http/route/MessageRouteModule.kt
...tlin/net/mamoe/mirai/api/http/route/MessageRouteModule.kt
+49
-18
mirai-console/build.gradle.kts
mirai-console/build.gradle.kts
+1
-1
mirai-console/src/main/kotlin/net/mamoe/mirai/console/MiraiConsole.kt
...e/src/main/kotlin/net/mamoe/mirai/console/MiraiConsole.kt
+11
-15
mirai-console/src/main/kotlin/net/mamoe/mirai/console/Setu.kt
...i-console/src/main/kotlin/net/mamoe/mirai/console/Setu.kt
+0
-2
mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugins/PluginBase.kt
...main/kotlin/net/mamoe/mirai/console/plugins/PluginBase.kt
+2
-2
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/ContactImpl.kt
...ommonMain/kotlin/net/mamoe/mirai/qqandroid/ContactImpl.kt
+2
-1
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.kt
...mmonMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.kt
+7
-1
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/PbMessageSvc.kt
...ai/qqandroid/network/protocol/packet/chat/PbMessageSvc.kt
+29
-0
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
+32
-11
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/BotImpl.kt
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotImpl.kt
+1
-1
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt
.../src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt
+2
-0
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/MessageReceipt.kt
...mmonMain/kotlin/net.mamoe.mirai/message/MessageReceipt.kt
+5
-9
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/MessageSource.kt
...Main/kotlin/net.mamoe.mirai/message/data/MessageSource.kt
+5
-2
mirai-core/src/jvmTest/kotlin/net/mamoe/mirai/utils/LockFreeLinkedListTest.kt
...st/kotlin/net/mamoe/mirai/utils/LockFreeLinkedListTest.kt
+3
-3
No files found.
CHANGELOG.md
View file @
6cf563c8
...
...
@@ -2,6 +2,15 @@
开发版本. 频繁更新, 不保证高稳定性
## `0.22.0` 2020/2/24
### mirai-core
-
重构
`MessageChain`
, 引入
`CombinedMessage`
. (兼容大部分原 API)
-
新增
`MessageChainBuilder`
,
`buildMessageChain`
-
`ExternalImage`
现在接收多种输入参数
### mirai-core-qqandroid
-
修复访问好友消息回执
`.sequenceId`
时抛出异常的问题
## `0.21.0` 2020/2/23
-
支持好友消息的引用回复
-
更加结构化的
`QuoteReply`
架构, 支持引用任意群/好友消息回复给任意群/好友.
...
...
gradle.properties
View file @
6cf563c8
# style guide
kotlin.code.style
=
official
# config
mirai_version
=
0.2
1
.0
mirai_version
=
0.2
2
.0
mirai_japt_version
=
1.1.0
mirai_console_version
=
0.1.1
kotlin.incremental.multiplatform
=
true
kotlin.parallel.tasks.in.project
=
true
# kotlin
...
...
mirai-api-http/README_CH.md
View file @
6cf563c8
...
...
@@ -173,14 +173,16 @@ fun main() {
| ------------ | ------ | ----- | ----------- | -------------------------------- |
| sessionKey | String | false | YourSession | 已经激活的Session |
| target | Long | false | 987654321 | 发送消息目标好友的QQ号 |
| quote | Long | true | 135798642 | 引用一条消息的messageId进行回复 |
| messageChain | Array | false | [] | 消息链,是一个消息对象构成的数组 |
#### 响应: 返回统一状态码
#### 响应: 返回统一状态码
(并携带messageId)
```
json5
{
"code": 0,
"msg": "success"
"msg": "success",
"messageId": 1234567890 // 一个Long类型属性,标识本条消息,用于撤回和引用回复
}
```
...
...
@@ -211,52 +213,16 @@ fun main() {
| ------------ | ------ | ----- | ----------- | -------------------------------- |
| sessionKey | String | false | YourSession | 已经激活的Session |
| target | Long | false | 987654321 | 发送消息目标群的群号 |
| quote | Long | true | 135798642 | 引用一条消息的messageId进行回复 |
| messageChain | Array | false | [] | 消息链,是一个消息对象构成的数组 |
#### 响应: 返回统一状态码
```
json5
{
"code": 0,
"msg": "success"
}
```
### 发送引用回复消息(仅支持群消息)
```
[POST] /sendQuoteMessage
```
使用此方法向指定的消息进行引用回复
#### 请求
```
json5
{
"sessionKey": "YourSession",
"target": 987654321,
"messageChain": [
{ "type": "Plain", "text":"hello\n" },
{ "type": "Plain", "text":"world" }
]
}
```
| 名字 | 类型 | 可选 | 举例 | 说明 |
| ------------ | ------ | ----- | ----------- | -------------------------------- |
| sessionKey | String | false | YourSession | 已经激活的Session |
| target | Long | false | 987654321 | 引用消息的Message Source的Uid |
| messageChain | Array | false | [] | 消息链,是一个消息对象构成的数组 |
#### 响应: 返回统一状态码
#### 响应: 返回统一状态码(并携带messageId)
```
json5
{
"code": 0,
"msg": "success"
"msg": "success",
"messageId": 1234567890 // 一个Long类型属性,标识本条消息,用于撤回和引用回复
}
```
...
...
@@ -331,6 +297,39 @@ Content-Type:multipart/form-data
### 撤回消息
```
[POST] /recall
```
使用此方法撤回指定消息。对于bot发送的消息,又2分钟时间限制。对于撤回群聊中群员的消息,需要有相应权限
#### 请求
```
json5
{
"sessionKey": "YourSession",
"target": 987654321
}
```
| 名字 | 类型 | 可选 | 举例 | 说明 |
| ------------ | ------ | ----- | ----------- | -------------------------------- |
| sessionKey | String | false | YourSession | 已经激活的Session |
| target | Long | false | 987654321 | 需要撤回的消息的messageId |
#### 响应: 返回统一状态码
```
json5
{
"code": 0,
"msg": "success"
}
```
### 获取Bot收到的消息和事件
```
...
...
@@ -370,7 +369,10 @@ Content-Type:multipart/form-data
}
},{
"type": "FriendMessage", // 消息类型:GroupMessage或FriendMessage或各类Event
"messageChain": [{ // 消息链,是一个消息对象构成的数组
"messageChain": [{ // 消息链,是一个消息对象构成的数组
"type": "Source",
"uid": 123456
},{
"type": "Plain",
"text": "Miral牛逼"
}],
...
...
mirai-api-http/src/main/kotlin/net/mamoe/mirai/api/http/data/common/BotEventDTO.kt
View file @
6cf563c8
...
...
@@ -12,7 +12,7 @@ import net.mamoe.mirai.utils.MiraiExperimentalAPI
sealed
class
BotEventDTO
:
EventDTO
()
@UseExperimental
(
MiraiExperimentalAPI
::
class
)
fun
BotEvent
.
toDTO
()
=
when
(
this
)
{
suspend
fun
BotEvent
.
toDTO
()
=
when
(
this
)
{
is
MessagePacket
<
*
,
*
>
->
toDTO
()
else
->
when
(
this
)
{
is
BotOnlineEvent
->
BotOnlineEventDTO
(
bot
.
uin
)
...
...
mirai-api-http/src/main/kotlin/net/mamoe/mirai/api/http/data/common/MessageDTO.kt
View file @
6cf563c8
...
...
@@ -17,8 +17,9 @@ import net.mamoe.mirai.message.FriendMessage
import
net.mamoe.mirai.message.GroupMessage
import
net.mamoe.mirai.message.MessagePacket
import
net.mamoe.mirai.message.data.*
import
net.mamoe.mirai.
utils.MiraiExperimentalAPI
import
net.mamoe.mirai.
message.uploadImage
import
net.mamoe.mirai.utils.MiraiInternalAPI
import
java.net.URL
/*
* DTO data class
...
...
@@ -57,7 +58,7 @@ data class PlainDTO(val text: String) : MessageDTO()
@Serializable
@SerialName
(
"Image"
)
data class
ImageDTO
(
val
imageId
:
String
)
:
MessageDTO
()
data class
ImageDTO
(
val
imageId
:
String
?
=
null
,
val
url
:
String
?
=
null
)
:
MessageDTO
()
@Serializable
@SerialName
(
"Xml"
)
...
...
@@ -84,42 +85,49 @@ sealed class MessageDTO : DTO
/*
Extend function
*/
fun
MessagePacket
<*,
*>.
toDTO
()
=
when
(
this
)
{
suspend
fun
MessagePacket
<*,
*>.
toDTO
()
=
when
(
this
)
{
is
FriendMessage
->
FriendMessagePacketDTO
(
QQDTO
(
sender
))
is
GroupMessage
->
GroupMessagePacketDTO
(
MemberDTO
(
sender
))
else
->
IgnoreEventDTO
}.
apply
{
if
(
this
is
MessagePacketDTO
)
{
messageChain
=
message
.
toDTOChain
()
}
// else: `this` is bot event
if
(
this
is
MessagePacketDTO
)
{
// 将MessagePacket中的所有Message转为DTO对象,并添加到messageChain
// foreachContent会忽略MessageSource,一次主动获取
messageChain
=
mutableListOf
(
messageDTO
(
message
[
MessageSource
])).
apply
{
message
.
foreachContent
{
content
->
messageDTO
(
content
).
takeUnless
{
it
==
UnknownMessageDTO
}
?.
let
(
::
add
)
}
}
// else: `this` is bot event
}
}
fun
MessageChain
.
toDTOChain
()
=
mutableListOf
(
this
[
MessageSource
].
toDTO
()).
apply
{
foreachContent
{
content
->
content
.
toDTO
().
takeUnless
{
it
==
UnknownMessageDTO
}
?.
let
(
::
add
)
}
}
suspend
fun
MessageChainDTO
.
toMessageChain
(
contact
:
Contact
)
=
buildMessageChain
{
this
@
toMessageChain
.
forEach
{
it
.
toMessage
(
contact
)
?.
let
(
::
add
)
}
}
fun
MessageChainDTO
.
toMessageChain
(
contact
:
Contact
)
=
buildMessageChain
{
this
@
toMessageChain
.
forEach
{
add
(
it
.
toMessage
(
contact
))
}
}
@UseExperimental
(
ExperimentalUnsignedTypes
::
class
,
MiraiExperimentalAPI
::
class
)
fun
Message
.
toDTO
()
=
when
(
this
)
{
is
MessageSource
->
MessageSourceDTO
(
id
)
is
At
->
AtDTO
(
target
,
display
)
@UseExperimental
(
ExperimentalUnsignedTypes
::
class
)
suspend
fun
MessagePacket
<*,
*>.
messageDTO
(
message
:
Message
)
=
when
(
message
)
{
is
MessageSource
->
MessageSourceDTO
(
message
.
id
)
is
At
->
AtDTO
(
message
.
target
,
message
.
display
)
is
AtAll
->
AtAllDTO
(
0L
)
is
Face
->
FaceDTO
(
id
)
is
PlainText
->
PlainDTO
(
stringValue
)
is
Image
->
ImageDTO
(
imageId
)
is
XMLMessage
->
XmlDTO
(
stringValue
)
is
Face
->
FaceDTO
(
message
.
id
)
is
PlainText
->
PlainDTO
(
message
.
stringValue
)
is
Image
->
ImageDTO
(
message
.
imageId
,
message
.
url
()
)
is
XMLMessage
->
XmlDTO
(
message
.
stringValue
)
else
->
UnknownMessageDTO
}
@UseExperimental
(
ExperimentalUnsignedTypes
::
class
,
MiraiInternalAPI
::
class
,
MiraiExperimentalAPI
::
class
)
fun
MessageDTO
.
toMessage
(
contact
:
Contact
)
=
when
(
this
)
{
@UseExperimental
(
ExperimentalUnsignedTypes
::
class
,
MiraiInternalAPI
::
class
)
suspend
fun
MessageDTO
.
toMessage
(
contact
:
Contact
)
=
when
(
this
)
{
is
AtDTO
->
At
((
contact
as
Group
)[
target
])
is
AtAllDTO
->
AtAll
is
FaceDTO
->
Face
(
faceId
)
is
PlainDTO
->
PlainText
(
text
)
is
ImageDTO
->
Image
(
imageId
)
is
ImageDTO
->
when
{
!
imageId
.
isNullOrBlank
()
->
Image
(
imageId
)
!
url
.
isNullOrBlank
()
->
contact
.
uploadImage
(
URL
(
url
))
else
->
null
}
is
XmlDTO
->
XMLMessage
(
xml
)
is
MessageSourceDTO
,
is
UnknownMessageDTO
->
PlainText
(
"assert cannot reach"
)
is
MessageSourceDTO
,
is
UnknownMessageDTO
->
null
}
mirai-api-http/src/main/kotlin/net/mamoe/mirai/api/http/queue/MessageQueue.kt
View file @
6cf563c8
...
...
@@ -13,17 +13,17 @@ import net.mamoe.mirai.api.http.data.common.EventDTO
import
net.mamoe.mirai.api.http.data.common.IgnoreEventDTO
import
net.mamoe.mirai.api.http.data.common.toDTO
import
net.mamoe.mirai.event.events.BotEvent
import
net.mamoe.mirai.message.
GroupMessage
import
net.mamoe.mirai.message.
MessagePacket
import
net.mamoe.mirai.message.data.MessageSource
import
net.mamoe.mirai.utils.firstKey
import
java.util.concurrent.ConcurrentLinkedDeque
class
MessageQueue
:
ConcurrentLinkedDeque
<
BotEvent
>()
{
val
quoteC
acheSize
=
4096
val
quoteCache
=
LinkedHashMap
<
Long
,
GroupMessage
>()
val
c
acheSize
=
4096
val
cache
=
LinkedHashMap
<
Long
,
MessagePacket
<
*
,
*
>
>()
fun
fetch
(
size
:
Int
):
List
<
EventDTO
>
{
suspend
fun
fetch
(
size
:
Int
):
List
<
EventDTO
>
{
var
count
=
size
val
ret
=
ArrayList
<
EventDTO
>(
count
)
...
...
@@ -37,18 +37,20 @@ class MessageQueue : ConcurrentLinkedDeque<BotEvent>() {
}
}
// TODO: 等FriendMessage支持quote
if
(
event
is
GroupMessage
)
{
if
(
event
is
MessagePacket
<
*
,
*
>)
{
addQuoteCache
(
event
)
}
}
return
ret
}
private
fun
addQuoteCache
(
msg
:
GroupMessage
)
{
quoteCache
[
msg
.
message
[
MessageSource
].
id
]
=
msg
if
(
quoteCache
.
size
>
quoteCacheSize
)
{
quoteCache
.
remove
(
quoteCache
.
firstKey
())
fun
cache
(
messageId
:
Long
)
=
cache
[
messageId
]
?:
throw
NoSuchElementException
()
fun
addQuoteCache
(
msg
:
MessagePacket
<
*
,
*
>)
{
cache
[
msg
.
message
[
MessageSource
].
id
]
=
msg
if
(
cache
.
size
>
cacheSize
)
{
cache
.
remove
(
cache
.
firstKey
())
}
}
}
\ No newline at end of file
mirai-api-http/src/main/kotlin/net/mamoe/mirai/api/http/route/AuthRouteModule.kt
View file @
6cf563c8
...
...
@@ -63,7 +63,7 @@ private data class AuthRetDTO(val code: Int, val session: String) : DTO
private
data class
BindDTO
(
override
val
sessionKey
:
String
,
val
qq
:
Long
)
:
VerifyDTO
()
private
fun
getBotOrThrow
(
qq
:
Long
)
=
try
{
Bot
.
instanceWhos
e
(
qq
)
Bot
.
getInstanc
e
(
qq
)
}
catch
(
e
:
NoSuchElementException
)
{
throw
NoSuchBotException
}
\ No newline at end of file
mirai-api-http/src/main/kotlin/net/mamoe/mirai/api/http/route/MessageRouteModule.kt
View file @
6cf563c8
...
...
@@ -20,15 +20,19 @@ import io.ktor.response.respondText
import
io.ktor.routing.post
import
io.ktor.routing.routing
import
kotlinx.serialization.Serializable
import
kotlinx.serialization.Transient
import
net.mamoe.mirai.api.http.AuthedSession
import
net.mamoe.mirai.api.http.SessionManager
import
net.mamoe.mirai.api.http.data.*
import
net.mamoe.mirai.api.http.data.common.DTO
import
net.mamoe.mirai.api.http.data.common.MessageChainDTO
import
net.mamoe.mirai.api.http.data.common.VerifyDTO
import
net.mamoe.mirai.api.http.data.common.toMessageChain
import
net.mamoe.mirai.api.http.util.toJson
import
net.mamoe.mirai.message.data.MessageChain
import
net.mamoe.mirai.contact.Contact
import
net.mamoe.mirai.message.FriendMessage
import
net.mamoe.mirai.message.GroupMessage
import
net.mamoe.mirai.message.MessageReceipt
import
net.mamoe.mirai.message.data.*
import
net.mamoe.mirai.message.uploadImage
import
java.net.URL
...
...
@@ -42,23 +46,47 @@ fun Application.messageModule() {
call
.
respondJson
(
fetch
.
toJson
())
}
suspend
fun
<
C
:
Contact
>
sendMessage
(
quote
:
QuoteReplyToSend
?,
messageChain
:
MessageChain
,
target
:
C
):
MessageReceipt
<
out
Contact
>
{
val
send
=
if
(
quote
==
null
)
{
messageChain
}
else
{
(
quote
+
messageChain
).
toChain
()
}
return
target
.
sendMessage
(
send
)
}
miraiVerify
<
SendDTO
>(
"/sendFriendMessage"
)
{
val
quote
=
it
.
quote
?.
let
{
q
->
it
.
session
.
messageQueue
.
cache
(
q
).
run
{
this
[
MessageSource
].
quote
(
sender
)
}}
it
.
session
.
bot
.
getFriend
(
it
.
target
).
apply
{
sendMessage
(
it
.
messageChain
.
toMessageChain
(
this
))
// this aka QQ
val
receipt
=
sendMessage
(
quote
,
it
.
messageChain
.
toMessageChain
(
this
),
this
)
receipt
.
source
.
ensureSequenceIdAvailable
()
it
.
session
.
messageQueue
.
addQuoteCache
(
FriendMessage
(
bot
.
selfQQ
,
receipt
.
source
.
toChain
()))
call
.
respondDTO
(
SendRetDTO
(
messageId
=
receipt
.
source
.
id
))
}
}
miraiVerify
<
SendDTO
>(
"/sendGroupMessage"
)
{
val
quote
=
it
.
quote
?.
let
{
q
->
it
.
session
.
messageQueue
.
cache
(
q
).
run
{
this
[
MessageSource
].
quote
(
sender
)
}}
it
.
session
.
bot
.
getGroup
(
it
.
target
).
apply
{
sendMessage
(
it
.
messageChain
.
toMessageChain
(
this
))
// this aka Group
}
}
val
receipt
=
sendMessage
(
quote
,
it
.
messageChain
.
toMessageChain
(
this
),
this
)
receipt
.
source
.
ensureSequenceIdAvailable
()
miraiVerify
<
SendDTO
>(
"/sendQuoteMessage"
)
{
it
.
session
.
messageQueue
.
quoteCache
[
it
.
target
]
?.
apply
{
quoteReply
(
it
.
messageChain
.
toMessageChain
(
group
))
}
?:
throw
NoSuchElementException
()
call
.
respondStateCode
(
StateCode
.
Success
)
it
.
session
.
messageQueue
.
addQuoteCache
(
GroupMessage
(
""
,
botPermission
,
botAsMember
,
receipt
.
source
.
toChain
()))
call
.
respondDTO
(
SendRetDTO
(
messageId
=
receipt
.
source
.
id
))
}
}
miraiVerify
<
SendImageDTO
>(
"sendImageMessage"
)
{
...
...
@@ -101,8 +129,10 @@ fun Application.messageModule() {
}
miraiVerify
<
RecallDTO
>(
"recall"
)
{
// TODO
call
.
respond
(
HttpStatusCode
.
NotFound
,
"未完成"
)
it
.
session
.
messageQueue
.
cache
(
it
.
target
).
apply
{
it
.
session
.
bot
.
recall
(
get
(
MessageSource
))
}
call
.
respondStateCode
(
StateCode
.
Success
)
}
}
}
...
...
@@ -110,6 +140,7 @@ fun Application.messageModule() {
@Serializable
private
data class
SendDTO
(
override
val
sessionKey
:
String
,
val
quote
:
Long
?
=
null
,
val
target
:
Long
,
val
messageChain
:
MessageChainDTO
)
:
VerifyDTO
()
...
...
@@ -125,13 +156,13 @@ private data class SendImageDTO(
@Serializable
private
class
SendRetDTO
(
val
messageId
:
Long
,
@Transient
val
stateCode
:
StateCode
=
Success
)
:
StateCode
(
stateCode
.
code
,
stateCode
.
msg
)
val
code
:
Int
=
0
,
val
msg
:
String
=
"success"
,
val
messageId
:
Long
)
:
DTO
@Serializable
private
data class
RecallDTO
(
override
val
sessionKey
:
String
,
val
target
:
Long
,
val
sender
:
Long
val
target
:
Long
)
:
VerifyDTO
()
mirai-console/build.gradle.kts
View file @
6cf563c8
...
...
@@ -32,7 +32,7 @@ tasks.withType<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar>() {
dependencies
{
api
(
project
(
":mirai-core"
))
api
(
project
(
":mirai-core-qqandroid"
))
api
(
project
(
":mirai-api-http"
))
//
api(project(":mirai-api-http"))
runtimeOnly
(
files
(
"../mirai-core-qqandroid/build/classes/kotlin/jvm/main"
))
runtimeOnly
(
files
(
"../mirai-core/build/classes/kotlin/jvm/main"
))
api
(
kotlin
(
"serialization"
))
...
...
mirai-console/src/main/kotlin/net/mamoe/mirai/console/MiraiConsole.kt
View file @
6cf563c8
...
...
@@ -12,32 +12,26 @@ package net.mamoe.mirai.console
import
kotlinx.coroutines.*
import
kotlinx.coroutines.channels.Channel
import
net.mamoe.mirai.Bot
import
net.mamoe.mirai.api.http.MiraiHttpAPIServer
import
net.mamoe.mirai.api.http.generateSessionKey
import
net.mamoe.mirai.console.MiraiConsole.CommandProcessor.processNextCommandLine
import
net.mamoe.mirai.console.command.*
import
net.mamoe.mirai.console.command.CommandManager
import
net.mamoe.mirai.console.command.CommandSender
import
net.mamoe.mirai.console.command.ConsoleCommandSender
import
net.mamoe.mirai.console.command.DefaultCommands
import
net.mamoe.mirai.console.plugins.PluginManager
import
net.mamoe.mirai.console.plugins.loadAsConfig
import
net.mamoe.mirai.console.plugins.withDefaultWrite
import
net.mamoe.mirai.console.plugins.withDefaultWriteSave
import
net.mamoe.mirai.console.utils.MiraiConsoleUI
import
net.mamoe.mirai.console.utils.checkManager
import
net.mamoe.mirai.contact.sendMessage
import
net.mamoe.mirai.event.subscribeMessages
import
net.mamoe.mirai.utils.SimpleLogger
import
net.mamoe.mirai.utils.cryptor.ECDH
import
java.io.File
import
java.security.Security
import
java.util.*
object
MiraiConsole
{
/**
* 发布的版本号 统一修改位置
*/
val
version
=
"v0.01
"
var
coreVersion
=
"v0.18.0"
val
build
=
"Alpha"
const
val
version
=
"0.1.0
"
const
val
coreVersion
=
"v0.18.0"
const
val
build
=
"Alpha"
/**
...
...
@@ -194,13 +188,15 @@ object MiraiProperties {
var
HTTP_API_ENABLE
:
Boolean
by
config
.
withDefaultWrite
{
true
}
var
HTTP_API_PORT
:
Int
by
config
.
withDefaultWrite
{
8080
}
/*
var HTTP_API_AUTH_KEY: String by config.withDefaultWriteSave {
"InitKey" + generateSessionKey()
}
}
*/
}
object
HTTPAPIAdaptar
{
operator
fun
invoke
()
{
/*
if (MiraiProperties.HTTP_API_ENABLE) {
if (MiraiProperties.HTTP_API_AUTH_KEY.startsWith("InitKey")) {
MiraiConsole.logger("请尽快更改初始生成的HTTP API AUTHKEY")
...
...
@@ -214,7 +210,7 @@ object HTTPAPIAdaptar {
MiraiProperties.HTTP_API_AUTH_KEY
)
MiraiConsole.logger("HTTPAPI启动完成; 端口= " + MiraiProperties.HTTP_API_PORT)
}
}
*/
}
}
...
...
mirai-console/src/main/kotlin/net/mamoe/mirai/console/Setu.kt
deleted
100644 → 0
View file @
5402505a
package
net.mamoe.mirai.console
mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugins/PluginBase.kt
View file @
6cf563c8
...
...
@@ -9,9 +9,9 @@
package
net.mamoe.mirai.console.plugins
import
net.mamoe.mirai.console.command.Command
import
kotlinx.coroutines.*
import
net.mamoe.mirai.console.MiraiConsole
import
net.mamoe.mirai.console.command.Command
import
net.mamoe.mirai.utils.DefaultLogger
import
net.mamoe.mirai.utils.MiraiLogger
import
net.mamoe.mirai.utils.SimpleLogger
...
...
@@ -303,7 +303,7 @@ object PluginManager {
}
return
try
{
val
subClass
=
pluginClass
.
asSubclass
(
PluginBase
::
class
.
java
)
val
plugin
:
PluginBase
=
subClass
.
getDeclaredConstructor
().
newInstance
()
val
plugin
:
PluginBase
=
subClass
.
kotlin
.
objectInstance
?:
subClass
.
getDeclaredConstructor
().
newInstance
()
description
.
loaded
=
true
logger
.
info
(
"successfully loaded plugin "
+
description
.
name
+
" version "
+
description
.
version
+
" by "
+
description
.
author
)
logger
.
info
(
description
.
info
)
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/ContactImpl.kt
View file @
6cf563c8
...
...
@@ -542,7 +542,7 @@ internal class GroupImpl(
if
(
event
.
isCancelled
)
{
throw
EventCancelledException
(
"cancelled by FriendMessageSendEvent"
)
}
lateinit
var
source
:
MessageSvc
.
PbSendMsg
.
MessageSourceFromSend
lateinit
var
source
:
MessageSvc
.
PbSendMsg
.
MessageSourceFromSend
Group
bot
.
network
.
run
{
val
response
:
MessageSvc
.
PbSendMsg
.
Response
=
MessageSvc
.
PbSendMsg
.
ToGroup
(
bot
.
client
,
...
...
@@ -579,6 +579,7 @@ internal class GroupImpl(
when
(
response
)
{
is
ImgStore
.
GroupPicUp
.
Response
.
Failed
->
{
ImageUploadEvent
.
Failed
(
this
@GroupImpl
,
image
,
response
.
resultCode
,
response
.
message
).
broadcast
()
if
(
response
.
message
==
"over file size max"
)
throw
OverFileSizeMaxException
()
error
(
"upload group image failed with reason ${response.message}"
)
}
is
ImgStore
.
GroupPicUp
.
Response
.
FileExists
->
{
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.kt
View file @
6cf563c8
...
...
@@ -129,9 +129,15 @@ internal abstract class QQAndroidBotBase constructor(
source
.
ensureSequenceIdAvailable
()
network
.
run
{
val
response
:
PbMessageSvc
.
PbMsgWithDraw
.
Response
=
val
response
:
PbMessageSvc
.
PbMsgWithDraw
.
Response
=
if
(
source
.
groupId
==
0L
)
{
PbMessageSvc
.
PbMsgWithDraw
.
Friend
(
bot
.
client
,
source
.
senderId
,
source
.
sequenceId
,
source
.
messageRandom
,
source
.
time
)
.
sendAndExpect
()
}
else
{
PbMessageSvc
.
PbMsgWithDraw
.
Group
(
bot
.
client
,
source
.
groupId
,
source
.
sequenceId
,
source
.
messageRandom
)
.
sendAndExpect
()
}
check
(
response
is
PbMessageSvc
.
PbMsgWithDraw
.
Response
.
Success
)
{
"Failed to recall message #${source.sequenceId}: $response"
}
}
}
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/PbMessageSvc.kt
View file @
6cf563c8
...
...
@@ -71,6 +71,35 @@ internal class PbMessageSvc {
)
}
fun
Friend
(
client
:
QQAndroidClient
,
toUin
:
Long
,
messageSequenceId
:
Int
,
// 56639
messageRandom
:
Int
,
// 921878719
time
:
Long
,
messageType
:
Int
=
0
):
OutgoingPacket
=
buildOutgoingUniPacket
(
client
)
{
writeProtoBuf
(
MsgSvc
.
PbMsgWithDrawReq
.
serializer
(),
MsgSvc
.
PbMsgWithDrawReq
(
c2cWithDraw
=
listOf
(
MsgSvc
.
PbC2CMsgWithDrawReq
(
subCmd
=
1
,
msgInfo
=
listOf
(
MsgSvc
.
PbC2CMsgWithDrawReq
.
MsgInfo
(
fromUin
=
client
.
bot
.
uin
,
toUin
=
toUin
,
msgSeq
=
messageSequenceId
,
msgUid
=
messageRandom
.
toLong
()
and
0
xffffffff
,
msgTime
=
time
and
0
xffffffff
)
)
)
)
)
)
}
override
suspend
fun
ByteReadPacket
.
decode
(
bot
:
QQAndroidBot
):
Response
{
val
resp
=
readProtoBuf
(
MsgSvc
.
PbMsgWithDrawResp
.
serializer
())
resp
.
groupWithDraw
?.
firstOrNull
()
?.
let
{
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.kt
View file @
6cf563c8
...
...
@@ -269,7 +269,28 @@ internal class MessageSvc {
}
}
internal
class
MessageSourceFromSend
(
internal
class
MessageSourceFromSendFriend
(
val
messageRandom
:
Int
,
override
val
time
:
Long
,
override
val
senderId
:
Long
,
override
val
groupId
:
Long
,
val
sequenceId
:
Int
)
:
MessageSource
{
@UseExperimental
(
ExperimentalCoroutinesApi
::
class
)
override
val
id
:
Long
get
()
=
sequenceId
.
toLong
().
shl
(
32
)
or
messageRandom
.
toLong
().
and
(
0
xFFFFFFFF
)
override
suspend
fun
ensureSequenceIdAvailable
()
{
// nothing to do
}
override
fun
toString
():
String
{
return
""
}
}
internal
class
MessageSourceFromSendGroup
(
val
messageRandom
:
Int
,
override
val
time
:
Long
,
override
val
senderId
:
Long
,
...
...
@@ -286,7 +307,7 @@ internal class MessageSvc {
@UseExperimental
(
MiraiExperimentalAPI
::
class
)
fun
startWaitingSequenceId
(
contact
:
Contact
)
{
sequenceIdDeferred
=
contact
.
subscribingGetAsync
<
OnlinePush
.
PbPushGroupMsg
.
SendGroupMessageReceipt
,
Int
>(
timeoutMillis
=
3000
)
{
if
(
it
.
messageRandom
==
this
@MessageSourceFromSend
.
messageRandom
)
{
if
(
it
.
messageRandom
==
this
@MessageSourceFromSend
Group
.
messageRandom
)
{
it
.
sequenceId
}
else
null
}
...
...
@@ -305,14 +326,14 @@ internal class MessageSvc {
client
:
QQAndroidClient
,
toUin
:
Long
,
message
:
MessageChain
,
crossinline
sourceCallback
:
(
MessageSource
)
->
Unit
crossinline
sourceCallback
:
(
MessageSource
FromSendFriend
)
->
Unit
):
OutgoingPacket
{
val
source
=
MessageSourceFromSend
(
val
source
=
MessageSourceFromSend
Friend
(
messageRandom
=
Random
.
nextInt
().
absoluteValue
,
senderId
=
client
.
uin
,
time
=
currentTimeSeconds
+
client
.
timeDifference
,
groupId
=
0
//
// sourceMessage = message
groupId
=
0
,
sequenceId
=
client
.
atomicNextMessageSequenceId
()
)
sourceCallback
(
source
)
return
ToFriend
(
client
,
toUin
,
message
,
source
)
...
...
@@ -326,7 +347,7 @@ internal class MessageSvc {
client
:
QQAndroidClient
,
toUin
:
Long
,
message
:
MessageChain
,
source
:
MessageSourceFromSend
source
:
MessageSourceFromSend
Friend
):
OutgoingPacket
=
buildOutgoingUniPacket
(
client
)
{
///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())
...
...
@@ -340,7 +361,7 @@ internal class MessageSvc {
elems
=
message
.
toRichTextElems
(
false
)
)
),
msgSeq
=
client
.
atomicNextMessageSequenceId
()
,
msgSeq
=
source
.
sequenceId
,
msgRand
=
source
.
messageRandom
,
syncCookie
=
SyncCookie
(
time
=
source
.
time
).
toByteArray
(
SyncCookie
.
serializer
())
// msgVia = 1
...
...
@@ -353,10 +374,10 @@ internal class MessageSvc {
client
:
QQAndroidClient
,
groupCode
:
Long
,
message
:
MessageChain
,
sourceCallback
:
(
MessageSourceFromSend
)
->
Unit
sourceCallback
:
(
MessageSourceFromSend
Group
)
->
Unit
):
OutgoingPacket
{
val
source
=
MessageSourceFromSend
(
val
source
=
MessageSourceFromSend
Group
(
messageRandom
=
Random
.
nextInt
().
absoluteValue
,
senderId
=
client
.
uin
,
time
=
currentTimeSeconds
+
client
.
timeDifference
,
...
...
@@ -375,7 +396,7 @@ internal class MessageSvc {
client
:
QQAndroidClient
,
groupCode
:
Long
,
message
:
MessageChain
,
source
:
MessageSourceFromSend
source
:
MessageSourceFromSend
Group
):
OutgoingPacket
=
buildOutgoingUniPacket
(
client
)
{
///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())
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt
View file @
6cf563c8
...
...
@@ -59,7 +59,7 @@ abstract class Bot : CoroutineScope {
* 获取一个 [Bot] 实例, 找不到则 [NoSuchElementException]
*/
@JvmStatic
fun
instanceWhose
(
qq
:
Long
):
Bot
=
BotImpl
.
instanceWhos
e
(
qq
=
qq
)
fun
getInstance
(
qq
:
Long
):
Bot
=
BotImpl
.
getInstanc
e
(
qq
=
qq
)
}
/**
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotImpl.kt
View file @
6cf563c8
...
...
@@ -60,7 +60,7 @@ abstract class BotImpl<N : BotNetworkHandler> constructor(
it
.
get
()
?.
let
(
block
)
}
fun
instanceWhos
e
(
qq
:
Long
):
Bot
{
fun
getInstanc
e
(
qq
:
Long
):
Bot
{
instances
.
forEach
{
it
.
get
()
?.
let
{
bot
->
if
(
bot
.
uin
==
qq
)
{
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt
View file @
6cf563c8
...
...
@@ -25,6 +25,7 @@ import net.mamoe.mirai.recall
import
net.mamoe.mirai.recallIn
import
net.mamoe.mirai.utils.ExternalImage
import
net.mamoe.mirai.utils.MiraiExperimentalAPI
import
net.mamoe.mirai.utils.OverFileSizeMaxException
import
net.mamoe.mirai.utils.WeakRefProperty
import
kotlin.coroutines.CoroutineContext
import
kotlin.coroutines.EmptyCoroutineContext
...
...
@@ -74,6 +75,7 @@ interface Contact : CoroutineScope {
* @see ImageUploadEvent 图片发送完成事件
*
* @throws EventCancelledException 当发送消息事件被取消
* @throws OverFileSizeMaxException 当图片文件过大而被服务器拒绝上传时. (最大大小约为 20 MB)
*/
suspend
fun
uploadImage
(
image
:
ExternalImage
):
Image
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/MessageReceipt.kt
View file @
6cf563c8
...
...
@@ -31,7 +31,7 @@ import net.mamoe.mirai.utils.unsafeWeakRef
* @see QQ.sendMessage 发送群消息, 返回回执(此对象)
*/
open
class
MessageReceipt
<
C
:
Contact
>(
private
val
source
:
MessageSource
,
val
source
:
MessageSource
,
target
:
C
)
{
init
{
...
...
@@ -48,7 +48,7 @@ open class MessageReceipt<C : Contact>(
/**
* 撤回这条消息. [recall] 或 [recallIn] 只能被调用一次.
*
* @see
Group
.recall
* @see
Bot
.recall
* @throws IllegalStateException 当此消息已经被撤回或正计划撤回时
*/
@UseExperimental
(
MiraiExperimentalAPI
::
class
)
...
...
@@ -78,13 +78,9 @@ open class MessageReceipt<C : Contact>(
fun
recallIn
(
millis
:
Long
):
Job
{
@Suppress
(
"BooleanLiteralArgument"
)
if
(
_isRecalled
.
compareAndSet
(
false
,
true
))
{
when
(
val
contact
=
target
)
{
is
Group
->
{
return
contact
.
bot
.
recallIn
(
source
,
millis
)
}
is
QQ
->
{
TODO
()
}
return
when
(
val
contact
=
target
)
{
is
QQ
,
is
Group
->
contact
.
bot
.
recallIn
(
source
,
millis
)
else
->
error
(
"Unknown contact type"
)
}
}
else
error
(
"message is already or planned to be recalled"
)
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/MessageSource.kt
View file @
6cf563c8
...
...
@@ -12,15 +12,18 @@
package
net.mamoe.mirai.message.data
import
net.mamoe.mirai.Bot
import
kotlin.jvm.JvmMultifileClass
import
kotlin.jvm.JvmName
/**
* 消息源, 用于被引用. 它将由协议模块实现.
* 消息源只用于 [QuoteReply]
* 消息源, 它存在于 [MessageChain] 中, 用于表示这个消息的来源.
*
* 消息源只用于 [引用回复][QuoteReply] 或 [撤回][Bot.recall].
*
* `mirai-core-qqandroid`: `net.mamoe.mirai.qqandroid.message.MessageSourceFromMsg`
*
* @see Bot.recall 撤回一条消息
* @see MessageSource.quote 引用这条消息, 创建 [MessageChain]
*/
interface
MessageSource
:
Message
,
MessageMetadata
{
...
...
mirai-core/src/jvmTest/kotlin/net/mamoe/mirai/utils/LockFreeLinkedListTest.kt
View file @
6cf563c8
...
...
@@ -161,7 +161,7 @@ internal class LockFreeLinkedListTest {
println
(
"Check value"
)
value
shouldBeEqualTo
6
println
(
"Check size"
)
println
(
list
.
getLinkStructure
())
//
println(list.getLinkStructure())
list
.
size
shouldBeEqualTo
6
}
...
...
@@ -174,7 +174,7 @@ internal class LockFreeLinkedListTest {
println
(
"Check value"
)
value
shouldBeEqualTo
2
println
(
"Check size"
)
println
(
list
.
getLinkStructure
())
//
println(list.getLinkStructure())
list
.
size
shouldBeEqualTo
5
}
...
...
@@ -198,7 +198,7 @@ internal class LockFreeLinkedListTest {
println
(
"Check value"
)
value
shouldBeEqualTo
2
println
(
"Check size"
)
println
(
list
.
getLinkStructure
())
//
println(list.getLinkStructure())
list
.
size
shouldBeEqualTo
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