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
93607e49
Commit
93607e49
authored
Oct 14, 2019
by
Him188
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Platform specified Contact
parent
ad43a92b
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
268 additions
and
173 deletions
+268
-173
README.md
README.md
+15
-28
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt
+1
-0
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt
.../src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt
+10
-12
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Group.kt
...re/src/commonMain/kotlin/net.mamoe.mirai/contact/Group.kt
+89
-107
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/QQ.kt
...-core/src/commonMain/kotlin/net.mamoe.mirai/contact/QQ.kt
+3
-11
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/events/FriendEvents.kt
...nMain/kotlin/net.mamoe.mirai/event/events/FriendEvents.kt
+0
-2
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/events/GroupEvents.kt
...onMain/kotlin/net.mamoe.mirai/event/events/GroupEvents.kt
+0
-2
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/internal/MessageDataInternal.kt
...n/net.mamoe.mirai/message/internal/MessageDataInternal.kt
+3
-0
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/BotNetworkHandler.kt
...nMain/kotlin/net.mamoe.mirai/network/BotNetworkHandler.kt
+6
-1
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/HandlerClosedException.kt
.../kotlin/net.mamoe.mirai/network/HandlerClosedException.kt
+0
-2
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/handler/EventPacketHandler.kt
....mirai/network/protocol/tim/handler/EventPacketHandler.kt
+3
-0
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/Heartbeat.kt
.../net.mamoe.mirai/network/protocol/tim/packet/Heartbeat.kt
+2
-2
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/ServerEvent.kt
...et.mamoe.mirai/network/protocol/tim/packet/ServerEvent.kt
+17
-2
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/contact/ContactJvm.kt
.../src/jvmMain/kotlin/net/mamoe/mirai/contact/ContactJvm.kt
+118
-0
mirai-demos/mirai-demo-1/src/main/java/demo1/Main.kt
mirai-demos/mirai-demo-1/src/main/java/demo1/Main.kt
+1
-4
No files found.
README.md
View file @
93607e49
# Mirai
# Mirai
[

](http://hits.dwyl.io/him188/mamoe/mirai)
[

](http://hits.dwyl.io/him188/mamoe/mirai)
一个以
**TIM
QQ协议(非web)**
驱动的QQ机器人服务端核心
一个以
**TIM
PC协议(非web)**
驱动的跨平台QQ机器人服务端核心, 虽然目前仅支持 JVM
采用服务端-插件模式运行,同时提供独立的
核心库
采用服务端-插件模式运行,同时提供独立的
跨平台核心库.
Mirai 的所有模块均开源
Mirai 的所有模块均开源
项目处于开发阶段,学生无法每日大量更新。
项目处于开发阶段, 还有很多未完善的地方. 欢迎任何的代码贡献, 或是 issue.
项目还有很多未完善的地方, 欢迎任何的代码贡献, 或是 issue.
部分协议来自网络上开源项目
部分协议来自网络上开源项目
**一切开发旨在学习,请勿用于非法用途**
**一切开发旨在学习,请勿用于非法用途**
...
@@ -22,7 +21,8 @@ Mirai 的所有模块均开源
...
@@ -22,7 +21,8 @@ Mirai 的所有模块均开源
3.
Run demo main
[
Demo 1 Main
](
mirai-demos/mirai-demo-1/src/main/java/demo1/Main.kt#L22
)
3.
Run demo main
[
Demo 1 Main
](
mirai-demos/mirai-demo-1/src/main/java/demo1/Main.kt#L22
)
### 事件
### 事件
#### Kotlin
#### 使用 Kotlin
这里只演示进行不终止地监听。
这里只演示进行不终止地监听。
##### Top-level reified
##### Top-level reified
多数情况下这是最好的方式。
多数情况下这是最好的方式。
...
@@ -35,7 +35,7 @@ subscribeAlways<FriendMessageEvent>{
...
@@ -35,7 +35,7 @@ subscribeAlways<FriendMessageEvent>{
```
```
##### DSL
##### DSL
查看更多:
[
ListenerBuilder
](
mirai-core/src/
jvmMain/kotlin/net/mamoe/mirai/event/Subscribers.kt#L69
)
查看更多:
[
ListenerBuilder
](
mirai-core/src/
commonMain/kotlin/net.mamoe.mirai/event/Subscribers.kt#L87
)
```
kotlin
```
kotlin
inline
fun
<
reified
E
:
Event
>
subscribeAll
(
builder
:
ListenerBuilder
.()
->
Unit
)
inline
fun
<
reified
E
:
Event
>
subscribeAll
(
builder
:
ListenerBuilder
.()
->
Unit
)
...
@@ -66,38 +66,25 @@ FriendMessageEvent::class.subscribeAlways{
...
@@ -66,38 +66,25 @@ FriendMessageEvent::class.subscribeAlways{


### 图片测试
### 图片测试
**现在可以接收图片消息**
(并解析为消息链):
现在可以接收图片消息
(并解析为消息链):




发送图片已经完成,但我们还在开发上传图片至服务器。
发送图片已经完成,但我们还在开发上传图片至服务器。
现在你可以通过发送一张图片给机器人账号,再让机器人账号发送这张图片。你可以查看
[
Image.kt
](
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/message/Message.kt#L81
)
机器人可以转发图片消息.详情查看
[
Image.kt
](
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/Message.kt#L81
)
# TODO
# 现已支持
-
[x] 事件(Event)模块
-
发送好友/群消息(2019/10/14)
-
[ ] 插件(Plugin)模块
-
接收好友/群消息, 消息链解析(2019/10/14)
-
[x] Network - Touch
-
好友在线状态改变(2019/10/14)
-
[X] Network - Login
-
[X] Network - Session
-
[X] Network - Verification Code
-
[X] Network - Message Receiving
-
[X] Network - Message Sending
-
[ ] Network - Events
-
[ ] Bot - Friend/group list
-
[ ] Bot - Actions(joining group, adding friend, etc.)
-
[x] Message Section
-
[ ] Image uploading
-
[ ] Contact
-
[ ] UI
-
[ ] Console
<br>
<br>
# 使用方法
# 使用方法
## 要求
## 要求
-
Kotlin 1.3+
-
Kotlin 1.3+
###
JVM
###
用于 JVM 平台
-
Java
11
-
Java
8
## 插件开发
## 插件开发
```
text
```
text
to be continued
to be continued
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt
View file @
93607e49
...
@@ -5,6 +5,7 @@ import kotlinx.coroutines.sync.Mutex
...
@@ -5,6 +5,7 @@ import kotlinx.coroutines.sync.Mutex
import
net.mamoe.mirai.Bot.ContactSystem
import
net.mamoe.mirai.Bot.ContactSystem
import
net.mamoe.mirai.contact.Group
import
net.mamoe.mirai.contact.Group
import
net.mamoe.mirai.contact.QQ
import
net.mamoe.mirai.contact.QQ
import
net.mamoe.mirai.contact.groupIdToNumber
import
net.mamoe.mirai.network.BotNetworkHandler
import
net.mamoe.mirai.network.BotNetworkHandler
import
net.mamoe.mirai.network.protocol.tim.TIMBotNetworkHandler
import
net.mamoe.mirai.network.protocol.tim.TIMBotNetworkHandler
import
net.mamoe.mirai.network.protocol.tim.packet.login.LoginResult
import
net.mamoe.mirai.network.protocol.tim.packet.login.LoginResult
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt
View file @
93607e49
...
@@ -7,15 +7,11 @@ import net.mamoe.mirai.message.PlainText
...
@@ -7,15 +7,11 @@ import net.mamoe.mirai.message.PlainText
import
net.mamoe.mirai.message.toChain
import
net.mamoe.mirai.message.toChain
/**
/**
* 联系人.
* 联系人
平台基础. 包含所有平台通用的函数等
.
*
*
* A contact is a [QQ] or a [Group] for one particular [Bot] instance only.
*
* @param bot the Owner [Bot]
* @param number the id number of this contact
* @author Him188moe
* @author Him188moe
*/
*/
abstract
class
Contact
internal
constructor
(
val
bot
:
Bot
,
val
number
:
Long
)
{
abstract
class
PlatformContactBase
internal
constructor
(
val
bot
:
Bot
,
val
number
:
Long
)
{
abstract
suspend
fun
sendMessage
(
message
:
MessageChain
)
abstract
suspend
fun
sendMessage
(
message
:
MessageChain
)
...
@@ -26,13 +22,15 @@ abstract class Contact internal constructor(val bot: Bot, val number: Long) {
...
@@ -26,13 +22,15 @@ abstract class Contact internal constructor(val bot: Bot, val number: Long) {
return
sendMessage
(
message
.
toChain
())
return
sendMessage
(
message
.
toChain
())
}
}
suspend
fun
sendMessage
(
plain
:
String
)
{
suspend
fun
sendMessage
(
plain
:
String
)
=
this
.
sendMessage
(
PlainText
(
plain
))
this
.
sendMessage
(
PlainText
(
plain
))
}
suspend
fun
sendMessage
(
message
:
List
<
Message
>)
{
this
.
sendMessage
(
MessageChain
(
message
))
}
abstract
suspend
fun
sendXMLMessage
(
message
:
String
)
abstract
suspend
fun
sendXMLMessage
(
message
:
String
)
}
}
/**
* 所有的 [QQ], [Group] 都继承自这个类.
* 在不同平台可能有不同的实现.
* 如在 JVM, suspend 调用不便, [Contact] 中有简化调用的 `blocking`() 和 `async`
*/
expect
sealed
class
Contact
(
bot
:
Bot
,
number
:
Long
)
:
PlatformContactBase
\ No newline at end of file
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Group.kt
View file @
93607e49
package
net.mamoe.mirai.contact
package
net.mamoe.mirai.contact
import
net.mamoe.mirai.Bot
import
net.mamoe.mirai.Bot
import
net.mamoe.mirai.contact.Group.Companion.groupNumberToId
import
net.mamoe.mirai.message.MessageChain
import
net.mamoe.mirai.message.MessageChain
import
net.mamoe.mirai.network.protocol.tim.handler.EventPacketHandler
import
net.mamoe.mirai.utils.ContactList
import
net.mamoe.mirai.utils.ContactList
import
kotlin.jvm.JvmStatic
/**
/**
* 群.
* 群.
...
@@ -14,125 +11,110 @@ import kotlin.jvm.JvmStatic
...
@@ -14,125 +11,110 @@ import kotlin.jvm.JvmStatic
* - Group Number([Group.number]) 是通常使用的群号码.(在 QQ 客户端中可见)
* - Group Number([Group.number]) 是通常使用的群号码.(在 QQ 客户端中可见)
* - Group ID([Group.groupId]) 是与服务器通讯时使用的 id.(在 QQ 客户端中不可见)
* - Group ID([Group.groupId]) 是与服务器通讯时使用的 id.(在 QQ 客户端中不可见)
*
*
* Java 获取 groupNumber: `group.getNumber()`
* Java 获取所属 bot: `group.getBot()`
* Java 获取群成员列表: `group.getMembers()`
* Java 获取 groupId: `group.getGroupId()`
*
* Java 调用 [groupNumberToId] : `Group.groupNumberToId(number)`
* @author Him188moe
* @author Him188moe
*/
*/
class
Group
(
bot
:
Bot
,
number
:
Long
)
:
Contact
(
bot
,
number
)
{
expect
class
Group
(
bot
:
Bot
,
number
:
Long
)
:
Contact
{
val
groupId
=
groupNumberToId
(
number
)
val
groupId
:
Long
val
members
:
ContactList
<
QQ
>
val
members
:
ContactList
<
QQ
>
//todo members
get
()
=
throw
UnsupportedOperationException
(
"Not yet supported"
)
override
suspend
fun
sendMessage
(
message
:
MessageChain
)
{
override
suspend
fun
sendMessage
(
message
:
MessageChain
)
bot
.
network
[
EventPacketHandler
].
sendGroupMessage
(
this
,
message
)
override
suspend
fun
sendXMLMessage
(
message
:
String
)
companion
object
}
fun
Group
.
Companion
.
groupNumberToId
(
number
:
Long
):
Long
{
//求你别出错
val
left
:
Long
=
number
.
toString
().
let
{
if
(
it
.
length
<
6
)
{
return
@
groupNumberToId
number
}
it
.
substring
(
0
,
it
.
length
-
6
).
toLong
()
}
val
right
:
Long
=
number
.
toString
().
let
{
it
.
substring
(
it
.
length
-
6
).
toLong
()
}
}
override
suspend
fun
sendXMLMessage
(
message
:
String
)
{
return
when
(
left
)
{
in
1
..
10
->
{
((
left
+
202
).
toString
()
+
right
.
toString
()).
toLong
()
}
in
11
..
19
->
{
((
left
+
469
).
toString
()
+
right
.
toString
()).
toLong
()
}
in
20
..
66
->
{
((
left
+
208
).
toString
()
+
right
.
toString
()).
toLong
()
}
in
67
..
156
->
{
((
left
+
1943
).
toString
()
+
right
.
toString
()).
toLong
()
}
in
157
..
209
->
{
((
left
+
199
).
toString
()
+
right
.
toString
()).
toLong
()
}
in
210
..
309
->
{
((
left
+
389
).
toString
()
+
right
.
toString
()).
toLong
()
}
in
310
..
499
->
{
((
left
+
349
).
toString
()
+
right
.
toString
()).
toLong
()
}
else
->
number
}
}
fun
Group
.
Companion
.
groupIdToNumber
(
id
:
Long
):
Long
{
//求你别出错
var
left
:
Long
=
id
.
toString
().
let
{
if
(
it
.
length
<
6
)
{
return
@
groupIdToNumber
id
}
it
.
substring
(
0
until
it
.
length
-
6
).
toLong
()
}
}
companion
object
{
return
when
(
left
)
{
@JvmStatic
in
203
..
212
->
{
fun
groupNumberToId
(
number
:
Long
):
Long
{
//求你别出错
val
right
:
Long
=
id
.
toString
().
let
{
val
left
:
Long
=
number
.
toString
().
let
{
it
.
substring
(
it
.
length
-
6
).
toLong
()
if
(
it
.
length
<
6
)
{
return
@
groupNumberToId
number
}
it
.
substring
(
0
,
it
.
length
-
6
).
toLong
()
}
}
val
right
:
Long
=
number
.
toString
().
let
{
((
left
-
202
).
toString
()
+
right
.
toString
()).
toLong
()
}
in
480
..
488
->
{
val
right
:
Long
=
id
.
toString
().
let
{
it
.
substring
(
it
.
length
-
6
).
toLong
()
it
.
substring
(
it
.
length
-
6
).
toLong
()
}
}
((
left
-
469
).
toString
()
+
right
.
toString
()).
toLong
()
return
when
(
left
)
{
}
in
1
..
10
->
{
in
2100
..
2146
->
{
((
left
+
202
).
toString
()
+
right
.
toString
()).
toLong
()
val
right
:
Long
=
id
.
toString
().
let
{
}
it
.
substring
(
it
.
length
-
7
).
toLong
()
in
11
..
19
->
{
((
left
+
469
).
toString
()
+
right
.
toString
()).
toLong
()
}
in
20
..
66
->
{
((
left
+
208
).
toString
()
+
right
.
toString
()).
toLong
()
}
in
67
..
156
->
{
((
left
+
1943
).
toString
()
+
right
.
toString
()).
toLong
()
}
in
157
..
209
->
{
((
left
+
199
).
toString
()
+
right
.
toString
()).
toLong
()
}
in
210
..
309
->
{
((
left
+
389
).
toString
()
+
right
.
toString
()).
toLong
()
}
in
310
..
499
->
{
((
left
+
349
).
toString
()
+
right
.
toString
()).
toLong
()
}
else
->
number
}
}
left
=
left
.
toString
().
substring
(
0
until
3
).
toLong
()
((
left
-
208
).
toString
()
+
right
.
toString
()).
toLong
()
}
}
in
2010
..
2099
->
{
@JvmStatic
val
right
:
Long
=
id
.
toString
().
let
{
fun
groupIdToNumber
(
id
:
Long
):
Long
{
//求你别出错
it
.
substring
(
it
.
length
-
6
).
toLong
()
var
left
:
Long
=
id
.
toString
().
let
{
if
(
it
.
length
<
6
)
{
return
@
groupIdToNumber
id
}
it
.
substring
(
0
until
it
.
length
-
6
).
toLong
()
}
}
((
left
-
1943
).
toString
()
+
right
.
toString
()).
toLong
()
return
when
(
left
)
{
}
in
203
..
212
->
{
in
2147
..
2199
->
{
val
right
:
Long
=
id
.
toString
().
let
{
val
right
:
Long
=
id
.
toString
().
let
{
it
.
substring
(
it
.
length
-
6
).
toLong
()
it
.
substring
(
it
.
length
-
7
).
toLong
()
}
}
((
left
-
202
).
toString
()
+
right
.
toString
()).
toLong
()
left
=
left
.
toString
().
substring
(
0
until
3
).
toLong
()
}
((
left
-
199
).
toString
()
+
right
.
toString
()).
toLong
()
in
480
..
488
->
{
}
val
right
:
Long
=
id
.
toString
().
let
{
in
4100
..
4199
->
{
it
.
substring
(
it
.
length
-
6
).
toLong
()
val
right
:
Long
=
id
.
toString
().
let
{
}
it
.
substring
(
it
.
length
-
7
).
toLong
()
((
left
-
469
).
toString
()
+
right
.
toString
()).
toLong
()
}
in
2100
..
2146
->
{
val
right
:
Long
=
id
.
toString
().
let
{
it
.
substring
(
it
.
length
-
7
).
toLong
()
}
left
=
left
.
toString
().
substring
(
0
until
3
).
toLong
()
((
left
-
208
).
toString
()
+
right
.
toString
()).
toLong
()
}
in
2010
..
2099
->
{
val
right
:
Long
=
id
.
toString
().
let
{
it
.
substring
(
it
.
length
-
6
).
toLong
()
}
((
left
-
1943
).
toString
()
+
right
.
toString
()).
toLong
()
}
in
2147
..
2199
->
{
val
right
:
Long
=
id
.
toString
().
let
{
it
.
substring
(
it
.
length
-
7
).
toLong
()
}
left
=
left
.
toString
().
substring
(
0
until
3
).
toLong
()
((
left
-
199
).
toString
()
+
right
.
toString
()).
toLong
()
}
in
4100
..
4199
->
{
val
right
:
Long
=
id
.
toString
().
let
{
it
.
substring
(
it
.
length
-
7
).
toLong
()
}
left
=
left
.
toString
().
substring
(
0
until
3
).
toLong
()
((
left
-
389
).
toString
()
+
right
.
toString
()).
toLong
()
}
in
3800
..
3989
->
{
val
right
:
Long
=
id
.
toString
().
let
{
it
.
substring
(
it
.
length
-
7
).
toLong
()
}
left
=
left
.
toString
().
substring
(
0
until
3
).
toLong
()
((
left
-
349
).
toString
()
+
right
.
toString
()).
toLong
()
}
else
->
id
}
}
left
=
left
.
toString
().
substring
(
0
until
3
).
toLong
()
((
left
-
389
).
toString
()
+
right
.
toString
()).
toLong
()
}
}
in
3800
..
3989
->
{
val
right
:
Long
=
id
.
toString
().
let
{
it
.
substring
(
it
.
length
-
7
).
toLong
()
}
left
=
left
.
toString
().
substring
(
0
until
3
).
toLong
()
((
left
-
349
).
toString
()
+
right
.
toString
()).
toLong
()
}
else
->
id
}
}
}
}
\ No newline at end of file
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/QQ.kt
View file @
93607e49
...
@@ -4,28 +4,20 @@ import net.mamoe.mirai.Bot
...
@@ -4,28 +4,20 @@ import net.mamoe.mirai.Bot
import
net.mamoe.mirai.message.At
import
net.mamoe.mirai.message.At
import
net.mamoe.mirai.message.Message
import
net.mamoe.mirai.message.Message
import
net.mamoe.mirai.message.MessageChain
import
net.mamoe.mirai.message.MessageChain
import
net.mamoe.mirai.network.protocol.tim.handler.EventPacketHandler
/**
/**
* QQ 账号.
* QQ 账号.
* 注意: 一个 [QQ] 实例并不是独立的, 它属于一个 [Bot].
* 注意: 一个 [QQ] 实例并不是独立的, 它属于一个 [Bot].
*
*
* Java 获取 qq 号: `qq.getNumber()`
* Java 获取所属 bot: `qq.getBot()`
*
* A QQ instance helps you to receive event from or sendPacket event to.
* A QQ instance helps you to receive event from or sendPacket event to.
* Notice that, one QQ instance belong to one [Bot], that is, QQ instances from different [Bot] are NOT the same.
* Notice that, one QQ instance belong to one [Bot], that is, QQ instances from different [Bot] are NOT the same.
*
*
* @author Him188moe
* @author Him188moe
*/
*/
class
QQ
(
bot
:
Bot
,
number
:
Long
)
:
Contact
(
bot
,
number
)
{
expect
class
QQ
(
bot
:
Bot
,
number
:
Long
)
:
Contact
{
override
suspend
fun
sendMessage
(
message
:
MessageChain
)
{
override
suspend
fun
sendMessage
(
message
:
MessageChain
)
bot
.
network
[
EventPacketHandler
].
sendFriendMessage
(
this
,
message
)
}
override
suspend
fun
sendXMLMessage
(
message
:
String
)
{
}
override
suspend
fun
sendXMLMessage
(
message
:
String
)
}
}
/**
/**
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/events/FriendEvents.kt
View file @
93607e49
...
@@ -18,7 +18,5 @@ class FriendMessageEvent(bot: Bot, sender: QQ, val message: MessageChain) : Frie
...
@@ -18,7 +18,5 @@ class FriendMessageEvent(bot: Bot, sender: QQ, val message: MessageChain) : Frie
suspend
inline
fun
reply
(
message
:
String
)
=
sender
.
sendMessage
(
message
)
suspend
inline
fun
reply
(
message
:
String
)
=
sender
.
sendMessage
(
message
)
suspend
inline
fun
reply
(
message
:
List
<
Message
>)
=
sender
.
sendMessage
(
message
)
suspend
inline
fun
reply
(
message
:
MessageChain
)
=
sender
.
sendMessage
(
message
)
//shortcut
suspend
inline
fun
reply
(
message
:
MessageChain
)
=
sender
.
sendMessage
(
message
)
//shortcut
}
}
\ No newline at end of file
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/events/GroupEvents.kt
View file @
93607e49
...
@@ -15,7 +15,5 @@ class GroupMessageEvent(bot: Bot, group: Group, val sender: QQ, val message: Mes
...
@@ -15,7 +15,5 @@ class GroupMessageEvent(bot: Bot, group: Group, val sender: QQ, val message: Mes
suspend
inline
fun
reply
(
message
:
String
)
=
group
.
sendMessage
(
message
)
suspend
inline
fun
reply
(
message
:
String
)
=
group
.
sendMessage
(
message
)
suspend
inline
fun
reply
(
message
:
List
<
Message
>)
=
group
.
sendMessage
(
message
)
suspend
inline
fun
reply
(
message
:
MessageChain
)
=
group
.
sendMessage
(
message
)
suspend
inline
fun
reply
(
message
:
MessageChain
)
=
group
.
sendMessage
(
message
)
}
}
\ No newline at end of file
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/internal/MessageDataInternal.kt
View file @
93607e49
...
@@ -70,7 +70,10 @@ internal fun ByteReadPacket.readMessage(): Message? {
...
@@ -70,7 +70,10 @@ internal fun ByteReadPacket.readMessage(): Message? {
0
x19
->
{
//未知, 可能是长文本?
0
x19
->
{
//未知, 可能是长文本?
//bot手机自己跟自己发消息会出这个
//bot手机自己跟自己发消息会出这个
//似乎手机发消息就会有这个?
//sectionData: 01 00 1C AA 02 19 08 00 88 01 00 9A 01 11 78 00 C8 01 00 F0 01 00 F8 01 00 90 02 00 C8 02 00
//sectionData: 01 00 1C AA 02 19 08 00 88 01 00 9A 01 11 78 00 C8 01 00 F0 01 00 F8 01 00 90 02 00 C8 02 00
// 01 00 1C AA 02 19 08 00 88 01 00 9A 01 11 78 00 C8 01 00 F0 01 00 F8 01 00 90 02 00 C8 02 00
return
null
sectionData
.
readBytes
().
debugPrint
(
"sectionData"
)
sectionData
.
readBytes
().
debugPrint
(
"sectionData"
)
return
PlainText
(
"[UNKNOWN(${this.readBytes().toUHexString()})]"
)
return
PlainText
(
"[UNKNOWN(${this.readBytes().toUHexString()})]"
)
println
()
println
()
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/BotNetworkHandler.kt
View file @
93607e49
...
@@ -71,4 +71,9 @@ interface BotNetworkHandler<Socket : DataPacketSocket> : Closeable {
...
@@ -71,4 +71,9 @@ interface BotNetworkHandler<Socket : DataPacketSocket> : Closeable {
override
fun
close
()
{
override
fun
close
()
{
NetworkScope
.
cancel
(
"handler closed"
,
HandlerClosedException
())
NetworkScope
.
cancel
(
"handler closed"
,
HandlerClosedException
())
}
}
}
}
\ No newline at end of file
/**
* [BotNetworkHandler] closed
*/
class
HandlerClosedException
:
Exception
()
\ No newline at end of file
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/HandlerClosedException.kt
View file @
93607e49
package
net.mamoe.mirai.network
package
net.mamoe.mirai.network
class
HandlerClosedException
:
Exception
()
\ No newline at end of file
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/handler/EventPacketHandler.kt
View file @
93607e49
...
@@ -70,6 +70,9 @@ class EventPacketHandler(session: LoginSession) : PacketHandler(session) {
...
@@ -70,6 +70,9 @@ class EventPacketHandler(session: LoginSession) : PacketHandler(session) {
//TODO
//TODO
}
}
is
IgnoredServerEventPacket
->
{
}
else
->
{
else
->
{
//ignored
//ignored
}
}
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/Heartbeat.kt
View file @
93607e49
...
@@ -8,7 +8,7 @@ import net.mamoe.mirai.utils.*
...
@@ -8,7 +8,7 @@ import net.mamoe.mirai.utils.*
@PacketId
(
"00 58"
)
@PacketId
(
"00 58"
)
class
ClientHeartbeatPacket
(
class
ClientHeartbeatPacket
(
private
val
qq
:
Long
,
private
val
bot
:
Long
,
private
val
sessionKey
:
ByteArray
private
val
sessionKey
:
ByteArray
)
:
ClientPacket
()
{
)
:
ClientPacket
()
{
override
val
idHex
:
String
by
lazy
{
override
val
idHex
:
String
by
lazy
{
...
@@ -16,7 +16,7 @@ class ClientHeartbeatPacket(
...
@@ -16,7 +16,7 @@ class ClientHeartbeatPacket(
}
}
override
fun
encode
(
builder
:
BytePacketBuilder
)
=
with
(
builder
)
{
override
fun
encode
(
builder
:
BytePacketBuilder
)
=
with
(
builder
)
{
this
.
writeQQ
(
qq
)
this
.
writeQQ
(
bot
)
this
.
writeHex
(
TIMProtocol
.
fixVer
)
this
.
writeHex
(
TIMProtocol
.
fixVer
)
this
.
encryptAndWrite
(
sessionKey
)
{
this
.
encryptAndWrite
(
sessionKey
)
{
writeHex
(
"00 01 00 01"
)
writeHex
(
"00 01 00 01"
)
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/ServerEvent.kt
View file @
93607e49
...
@@ -9,6 +9,9 @@ import net.mamoe.mirai.network.protocol.tim.TIMProtocol
...
@@ -9,6 +9,9 @@ import net.mamoe.mirai.network.protocol.tim.TIMProtocol
import
net.mamoe.mirai.utils.*
import
net.mamoe.mirai.utils.*
import
kotlin.properties.Delegates
import
kotlin.properties.Delegates
/**
* 事件的识别 ID. 在 [事件确认包][ServerEventPacket.ResponsePacket] 中被使用.
*/
data class
EventPacketIdentity
(
data class
EventPacketIdentity
(
val
from
:
UInt
,
//对于好友消息, 这个是发送人
val
from
:
UInt
,
//对于好友消息, 这个是发送人
val
to
:
UInt
,
//对于好友消息, 这个是bot
val
to
:
UInt
,
//对于好友消息, 这个是bot
...
@@ -37,8 +40,9 @@ abstract class ServerEventPacket(input: ByteReadPacket, val eventIdentity: Event
...
@@ -37,8 +40,9 @@ abstract class ServerEventPacket(input: ByteReadPacket, val eventIdentity: Event
to
=
readUInt
(),
to
=
readUInt
(),
uniqueId
=
readIoBuffer
(
8
)
uniqueId
=
readIoBuffer
(
8
)
)
)
readBytes
(
2
).
takeIf
{
it
[
0
].
toUInt
()
!=
0
x1Fu
&&
it
[
1
].
toUInt
()
!=
0
x40u
}
?.
debugPrint
(
"type前面2个byte"
)
discardExact
(
2
)
val
type
=
readBytes
(
2
)
val
type
=
readBytes
(
2
)
//DebugLogger.logPurple("unknown2Byte+byte = ${unknown2Byte.toUHexString()} ${type.toUHexString()}")
return
when
(
type
.
toUHexString
())
{
return
when
(
type
.
toUHexString
())
{
"00 C4"
->
{
"00 C4"
->
{
discardExact
(
13
)
discardExact
(
13
)
...
@@ -56,11 +60,17 @@ abstract class ServerEventPacket(input: ByteReadPacket, val eventIdentity: Event
...
@@ -56,11 +60,17 @@ abstract class ServerEventPacket(input: ByteReadPacket, val eventIdentity: Event
//00 00 00 08 00 0A 00 04 01 00 00 00 00 00 00 16 00 00 00 37 08 02 1A 12 08 95 02 10 90 04 40 98 E1 8C ED 05 48 AF 96 C3 A4 03 08 A2 FF 8C F0 03 10 DD F1 92 B7 07 1A 29 08 00 10 05 18 98 E1 8C ED 05 20 01 28 FF FF FF FF 0F 32 15 E5 AF B9 E6 96 B9 E6 AD A3 E5 9C A8 E8 BE 93 E5 85 A5 2E 2E 2E
//00 00 00 08 00 0A 00 04 01 00 00 00 00 00 00 16 00 00 00 37 08 02 1A 12 08 95 02 10 90 04 40 98 E1 8C ED 05 48 AF 96 C3 A4 03 08 A2 FF 8C F0 03 10 DD F1 92 B7 07 1A 29 08 00 10 05 18 98 E1 8C ED 05 20 01 28 FF FF FF FF 0F 32 15 E5 AF B9 E6 96 B9 E6 AD A3 E5 9C A8 E8 BE 93 E5 85 A5 2E 2E 2E
//00 00 00 08 00 0A 00 04 01 00 00 00 00 00 00 07 00 00 00
"02 10"
->
{
"02 10"
->
{
discardExact
(
19
)
discardExact
(
19
)
println
(
readUByte
().
toUInt
())
//todo 错了. 可能是 00 79 才是.
return
@
with
ServerFriendTypingCanceledPacket
(
input
,
eventIdentity
)
if
(
readUByte
().
toUInt
()
==
0
x37u
)
ServerFriendTypingStartedPacket
(
input
,
eventIdentity
)
if
(
readUByte
().
toUInt
()
==
0
x37u
)
ServerFriendTypingStartedPacket
(
input
,
eventIdentity
)
else
/*0x22*/
ServerFriendTypingCanceledPacket
(
input
,
eventIdentity
)
else
/*0x22*/
ServerFriendTypingCanceledPacket
(
input
,
eventIdentity
)
}
}
"00 79"
->
IgnoredServerEventPacket
(
type
,
input
,
eventIdentity
)
//"02 10", "00 12" -> ServerUnknownEventPacket(input, eventIdentity)
//"02 10", "00 12" -> ServerUnknownEventPacket(input, eventIdentity)
...
@@ -95,6 +105,12 @@ abstract class ServerEventPacket(input: ByteReadPacket, val eventIdentity: Event
...
@@ -95,6 +105,12 @@ abstract class ServerEventPacket(input: ByteReadPacket, val eventIdentity: Event
}
}
}
}
/**
* 忽略的事件.
* 如 00 79: 总是与 01 12 一起发生, 但 00 79 却没多大意义
*/
class
IgnoredServerEventPacket
(
val
eventId
:
ByteArray
/*2*/
,
input
:
ByteReadPacket
,
eventIdentity
:
EventPacketIdentity
)
:
ServerEventPacket
(
input
,
eventIdentity
)
/**
/**
* Unknown event
* Unknown event
*/
*/
...
@@ -121,7 +137,6 @@ class ServerFriendTypingStartedPacket(input: ByteReadPacket, eventIdentity: Even
...
@@ -121,7 +137,6 @@ class ServerFriendTypingStartedPacket(input: ByteReadPacket, eventIdentity: Even
class
ServerFriendTypingCanceledPacket
(
input
:
ByteReadPacket
,
eventIdentity
:
EventPacketIdentity
)
:
ServerFriendTypingPacket
(
input
,
eventIdentity
)
class
ServerFriendTypingCanceledPacket
(
input
:
ByteReadPacket
,
eventIdentity
:
EventPacketIdentity
)
:
ServerFriendTypingPacket
(
input
,
eventIdentity
)
/**
/**
* Android 客户端上线
* Android 客户端上线
*/
*/
...
...
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/contact/ContactJvm.kt
0 → 100644
View file @
93607e49
package
net.mamoe.mirai.contact
import
kotlinx.coroutines.launch
import
kotlinx.coroutines.runBlocking
import
net.mamoe.mirai.Bot
import
net.mamoe.mirai.message.Message
import
net.mamoe.mirai.message.MessageChain
import
net.mamoe.mirai.network.protocol.tim.handler.EventPacketHandler
import
net.mamoe.mirai.utils.ContactList
/**
* 联系人.
*
* A contact is a [QQ] or a [Group] for one particular [Bot] instance only.
*
* @param bot the Owner [Bot]
* @param number the id number of this contact
* @author Him188moe
*/
@Suppress
(
"unused"
)
actual
sealed
class
Contact
actual
constructor
(
bot
:
Bot
,
number
:
Long
)
:
PlatformContactBase
(
bot
,
number
)
{
abstract
override
suspend
fun
sendMessage
(
message
:
MessageChain
)
abstract
override
suspend
fun
sendXMLMessage
(
message
:
String
)
/**
* 阻塞发送一个消息. 仅应在 Java 使用
*/
fun
blockingSendMessage
(
chain
:
MessageChain
)
=
runBlocking
{
sendMessage
(
chain
)
}
/**
* 阻塞发送一个消息. 仅应在 Java 使用
*/
fun
blockingSendMessage
(
message
:
Message
)
=
runBlocking
{
sendMessage
(
message
)
}
/**
* 阻塞发送一个消息. 仅应在 Java 使用
*/
fun
blockingSendMessage
(
plain
:
String
)
=
runBlocking
{
sendMessage
(
plain
)
}
/**
* 异步发送一个消息. 仅应在 Java 使用
*/
fun
asyncSendMessage
(
chain
:
MessageChain
)
{
bot
.
network
.
NetworkScope
.
launch
{
sendMessage
(
chain
)
}
}
/**
* 异步发送一个消息. 仅应在 Java 使用
*/
fun
asyncSendMessage
(
message
:
Message
)
{
bot
.
network
.
NetworkScope
.
launch
{
sendMessage
(
message
)
}
}
/**
* 异步发送一个消息. 仅应在 Java 使用
*/
fun
asyncSendMessage
(
plain
:
String
)
{
bot
.
network
.
NetworkScope
.
launch
{
sendMessage
(
plain
)
}
}
}
/**
* 群.
*
* Group ID 与 Group Number 并不是同一个值.
* - Group Number([Group.number]) 是通常使用的群号码.(在 QQ 客户端中可见)
* - Group ID([Group.groupId]) 是与服务器通讯时使用的 id.(在 QQ 客户端中不可见)
*
* Java 获取 groupNumber: `group.getNumber()`
* Java 获取所属 bot: `group.getBot()`
* Java 获取群成员列表: `group.getMembers()`
* Java 获取 groupId: `group.getGroupId()`
*
* Java 调用 [groupNumberToId] : `Group.groupNumberToId(number)`
* @author Him188moe
*/
actual
class
Group
actual
constructor
(
bot
:
Bot
,
number
:
Long
)
:
Contact
(
bot
,
number
)
{
actual
val
groupId
=
groupNumberToId
(
number
)
actual
val
members
:
ContactList
<
QQ
>
//todo members
get
()
=
throw
UnsupportedOperationException
(
"Not yet supported"
)
actual
override
suspend
fun
sendMessage
(
message
:
MessageChain
)
{
bot
.
network
[
EventPacketHandler
].
sendGroupMessage
(
this
,
message
)
}
actual
override
suspend
fun
sendXMLMessage
(
message
:
String
)
{
}
actual
companion
object
}
/**
* QQ 账号.
* 注意: 一个 [QQ] 实例并不是独立的, 它属于一个 [Bot].
*
* Java 获取 qq 号: `qq.getNumber()`
* Java 获取所属 bot: `qq.getBot()`
*
* A QQ instance helps you to receive event from or sendPacket event to.
* Notice that, one QQ instance belong to one [Bot], that is, QQ instances from different [Bot] are NOT the same.
*
* @author Him188moe
*/
actual
class
QQ
actual
constructor
(
bot
:
Bot
,
number
:
Long
)
:
Contact
(
bot
,
number
)
{
actual
override
suspend
fun
sendMessage
(
message
:
MessageChain
)
{
bot
.
network
[
EventPacketHandler
].
sendFriendMessage
(
this
,
message
)
}
actual
override
suspend
fun
sendXMLMessage
(
message
:
String
)
{
TODO
()
}
}
\ No newline at end of file
mirai-demos/mirai-demo-1/src/main/java/demo1/Main.kt
View file @
93607e49
...
@@ -49,10 +49,7 @@ suspend fun main() {
...
@@ -49,10 +49,7 @@ suspend fun main() {
"复读"
in
it
.
message
->
it
.
sender
.
sendMessage
(
it
.
message
)
"复读"
in
it
.
message
->
it
.
sender
.
sendMessage
(
it
.
message
)
"发群"
in
it
.
message
->
{
"发群"
in
it
.
message
->
{
it
.
message
.
list
.
toMutableList
().
let
{
messages
->
messages
.
removeAt
(
0
)
Group
(
bot
,
580266363
).
sendMessage
(
messages
)
}
}
}
/*it.event eq "发图片群" -> sendGroupMessage(Group(session.bot, 580266363), PlainText("test") + UnsolvedImage(File("C:\\Users\\Him18\\Desktop\\faceImage_1559564477775.jpg")).also { image ->
/*it.event eq "发图片群" -> sendGroupMessage(Group(session.bot, 580266363), PlainText("test") + UnsolvedImage(File("C:\\Users\\Him18\\Desktop\\faceImage_1559564477775.jpg")).also { image ->
...
...
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