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
dcb8b0ac
Commit
dcb8b0ac
authored
Jan 25, 2020
by
jiahua.liu
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/master'
parents
5ff9bfa2
b6ae6ebd
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
67 additions
and
35 deletions
+67
-35
README.md
README.md
+24
-1
build.gradle
build.gradle
+1
-0
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt
...moe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt
+5
-7
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/LoginPacket.kt
...ai/qqandroid/network/protocol/packet/login/LoginPacket.kt
+35
-24
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/utils/BotConfiguration.kt
...mmonMain/kotlin/net.mamoe.mirai/utils/BotConfiguration.kt
+1
-2
No files found.
README.md
View file @
dcb8b0ac
...
@@ -28,8 +28,30 @@
...
@@ -28,8 +28,30 @@
您的 star 是对我们最大的鼓励(点击项目右上角);
您的 star 是对我们最大的鼓励(点击项目右上角);
## Features
#### mirai-core
通用 API 模块,请参考此模块调用 Mirai.
#### mirai-core-timpc
TIM PC (2.3.2 版本,2019 年 8 月)协议的实现,相较于 core,仅新增少量 API. 详见
[
README.md
](
mirai-core-timpc/
)
支持的功能:
-
消息收发:图片文字复合消息,图片消息
-
群管功能:群员列表,禁言
(目前不再更新,请关注安卓协议)
#### mirai-core-qqandroid
QQ for Android (8.2.0 版本,2019 年 12 月)协议的实现,目前还未完成。
-
高兼容性:Mirai 协议仅含极少部分为硬编码,其余全部随官方方式动态生成
-
高安全性:密匙随机,ECDH 动态计算,硬件信息真机模拟(Android 平台获取真机信息)
开发进度:
-
完成 密码登录 (2020/1/23)
-
进行中 验证码登录
-
进行中 消息解析
-
进行中 图片上传下载
## Use directly
## Use directly
**直接使用Mirai(终端环境/网页面板).**
**直接使用Mirai(终端环境/网页面板
(将来)
).**
[
Mirai-Console
](
https://github.com/mamoe/mirai/tree/master/mirai-console
)
插件支持, 在终端中启动Mirai并获得机器人服务
[
Mirai-Console
](
https://github.com/mamoe/mirai/tree/master/mirai-console
)
插件支持, 在终端中启动Mirai并获得机器人服务
## Use as a library
## Use as a library
...
@@ -48,6 +70,7 @@ repositories{
...
@@ -48,6 +70,7 @@ repositories{
**Mirai 目前还处于实验性阶段, 我们无法保证任何稳定性, API 也可能会随时修改.**
**Mirai 目前还处于实验性阶段, 我们无法保证任何稳定性, API 也可能会随时修改.**
现在 Mirai 只支持 TIM PC 协议. QQ Android 协议正在开发中.
现在 Mirai 只支持 TIM PC 协议. QQ Android 协议正在开发中.
**common**
**common**
```
kotlin
```
kotlin
implementation
(
"net.mamoe:mirai-core-timpc-common:VERSION"
)
implementation
(
"net.mamoe:mirai-core-timpc-common:VERSION"
)
...
...
build.gradle
View file @
dcb8b0ac
...
@@ -4,6 +4,7 @@ buildscript {
...
@@ -4,6 +4,7 @@ buildscript {
jcenter
()
jcenter
()
mavenCentral
()
mavenCentral
()
google
()
google
()
maven
{
url
'https://dl.bintray.com/kotlin/kotlin-dev/'
}
}
}
dependencies
{
dependencies
{
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt
View file @
dcb8b0ac
...
@@ -11,8 +11,7 @@ import net.mamoe.mirai.qqandroid.event.PacketReceivedEvent
...
@@ -11,8 +11,7 @@ import net.mamoe.mirai.qqandroid.event.PacketReceivedEvent
import
net.mamoe.mirai.qqandroid.network.protocol.packet.KnownPacketFactories
import
net.mamoe.mirai.qqandroid.network.protocol.packet.KnownPacketFactories
import
net.mamoe.mirai.qqandroid.network.protocol.packet.OutgoingPacket
import
net.mamoe.mirai.qqandroid.network.protocol.packet.OutgoingPacket
import
net.mamoe.mirai.qqandroid.network.protocol.packet.login.LoginPacket
import
net.mamoe.mirai.qqandroid.network.protocol.packet.login.LoginPacket
import
net.mamoe.mirai.qqandroid.network.protocol.packet.login.LoginPacket.LoginPacketResponse.Captcha
import
net.mamoe.mirai.qqandroid.network.protocol.packet.login.LoginPacket.LoginPacketResponse.*
import
net.mamoe.mirai.qqandroid.network.protocol.packet.login.LoginPacket.LoginPacketResponse.Success
import
net.mamoe.mirai.qqandroid.network.protocol.packet.login.SvcReqRegisterPacket
import
net.mamoe.mirai.qqandroid.network.protocol.packet.login.SvcReqRegisterPacket
import
net.mamoe.mirai.utils.*
import
net.mamoe.mirai.utils.*
import
net.mamoe.mirai.utils.io.*
import
net.mamoe.mirai.utils.io.*
...
@@ -31,7 +30,7 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
...
@@ -31,7 +30,7 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
launch
(
CoroutineName
(
"Incoming Packet Receiver"
))
{
processReceive
()
}
launch
(
CoroutineName
(
"Incoming Packet Receiver"
))
{
processReceive
()
}
bot
.
logger
.
info
(
"Trying login"
)
bot
.
logger
.
info
(
"Trying login"
)
when
(
val
response
=
LoginPacket
.
SubCommand9
(
bot
.
client
).
sendAndExpect
<
LoginPacket
.
LoginPacketResponse
>
())
{
when
(
val
response
:
LoginPacket
.
LoginPacketResponse
=
LoginPacket
.
SubCommand9
(
bot
.
client
).
sendAndExpect
())
{
is
Captcha
->
when
(
response
)
{
is
Captcha
->
when
(
response
)
{
is
Captcha
.
Picture
->
{
is
Captcha
.
Picture
->
{
bot
.
logger
.
info
(
"需要图片验证码"
)
bot
.
logger
.
info
(
"需要图片验证码"
)
...
@@ -41,6 +40,8 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
...
@@ -41,6 +40,8 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
}
}
}
}
is
Error
->
error
(
response
.
toString
())
is
Success
->
{
is
Success
->
{
bot
.
logger
.
info
(
"Login successful"
)
bot
.
logger
.
info
(
"Login successful"
)
}
}
...
@@ -207,10 +208,7 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
...
@@ -207,10 +208,7 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
suspend
fun
<
E
:
Packet
>
OutgoingPacket
.
sendAndExpect
():
E
{
suspend
fun
<
E
:
Packet
>
OutgoingPacket
.
sendAndExpect
():
E
{
val
handler
=
PacketListener
(
commandName
=
commandName
,
sequenceId
=
sequenceId
)
val
handler
=
PacketListener
(
commandName
=
commandName
,
sequenceId
=
sequenceId
)
packetListeners
.
addLast
(
handler
)
packetListeners
.
addLast
(
handler
)
//println(delegate.readBytes().toUHexString())
channel
.
send
(
delegate
)
println
(
"Sending length="
+
delegate
.
remaining
)
channel
.
send
(
delegate
)
//) { packetListeners.remove(handler); "Cannot send packet" }
println
(
"Packet sent"
)
@Suppress
(
"UNCHECKED_CAST"
)
@Suppress
(
"UNCHECKED_CAST"
)
return
handler
.
await
()
as
E
return
handler
.
await
()
as
E
}
}
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/LoginPacket.kt
View file @
dcb8b0ac
...
@@ -172,6 +172,12 @@ internal object LoginPacket : PacketFactory<LoginPacket.LoginPacketResponse>("wt
...
@@ -172,6 +172,12 @@ internal object LoginPacket : PacketFactory<LoginPacket.LoginPacketResponse>("wt
sealed
class
LoginPacketResponse
:
Packet
{
sealed
class
LoginPacketResponse
:
Packet
{
object
Success
:
LoginPacketResponse
()
object
Success
:
LoginPacketResponse
()
data class
Error
(
val
title
:
String
,
val
message
:
String
,
val
errorInfo
:
String
)
:
LoginPacketResponse
()
sealed
class
Captcha
:
LoginPacketResponse
()
{
sealed
class
Captcha
:
LoginPacketResponse
()
{
class
Slider
(
class
Slider
(
val
data
:
IoBuffer
val
data
:
IoBuffer
...
@@ -197,52 +203,56 @@ internal object LoginPacket : PacketFactory<LoginPacket.LoginPacketResponse>("wt
...
@@ -197,52 +203,56 @@ internal object LoginPacket : PacketFactory<LoginPacket.LoginPacketResponse>("wt
println
(
"subCommand=$subCommand"
)
println
(
"subCommand=$subCommand"
)
val
type
=
readByte
()
val
type
=
readByte
()
println
(
"type=$type"
)
println
(
"type=$type"
)
when
(
type
.
toInt
())
{
0
->
{
discardExact
(
2
)
onLoginSuccess
(
bot
)
val
tlvMap
:
Map
<
Int
,
ByteArray
>
=
this
.
readTLVMap
()
}
return
when
(
type
.
toInt
())
{
1
->
{
0
->
onLoginSuccess
(
tlvMap
,
bot
)
throw
Exception
(
"Wrong Password"
)
1
,
15
->
onErrorMessage
(
tlvMap
)
}
2
->
onSolveLoginCaptcha
(
tlvMap
,
bot
)
2
->
{
else
->
error
(
"unknown login result type: $type"
)
onSolveLoginCaptcha
(
bot
)
}
}
if
(
type
.
toInt
()
!=
0
)
{
DebugLogger
.
debug
(
"unknown login result type: $type"
)
}
}
return
LoginPacketResponse
.
Success
}
private
fun
onErrorMessage
(
tlvMap
:
Map
<
Int
,
ByteArray
>):
LoginPacketResponse
.
Error
{
return
tlvMap
[
0
x146
]
?.
toReadPacket
()
?.
run
{
readShort
()
// ver
readShort
()
// code
val
title
=
readUShortLVString
()
val
message
=
readUShortLVString
()
val
errorInfo
=
readUShortLVString
()
LoginPacketResponse
.
Error
(
title
,
message
,
errorInfo
)
}
?:
error
(
"Cannot find error message"
)
}
}
@UseExperimental
(
MiraiDebugAPI
::
class
)
@UseExperimental
(
MiraiDebugAPI
::
class
)
suspend
fun
ByteReadPacket
.
onSolveLoginCaptcha
(
bot
:
QQAndroidBot
)
=
this
.
debugPrint
(
"login验证码解析"
).
run
{
private
suspend
fun
onSolveLoginCaptcha
(
tlvMap
:
Map
<
Int
,
ByteArray
>,
bot
:
QQAndroidBot
):
LoginPacketResponse
.
Captcha
{
val
client
=
bot
.
client
val
client
=
bot
.
client
debugDiscardExact
(
2
)
// val ret = tlvMap[0x104]?.let { println(it.toUHexString()) }
val
tlvMap
:
Map
<
Int
,
ByteArray
>
=
this
.
readTLVMap
()
// val ret = tlvMap[0x104]?.let { println(it.toUHexString()) }
println
()
println
()
val
question
=
tlvMap
[
0
x165
]
?:
error
(
"CAPTCHA QUESTION UNKNOWN"
)
val
question
=
tlvMap
[
0
x165
]
?:
error
(
"CAPTCHA QUESTION UNKNOWN"
)
when
(
question
[
18
].
toUHexString
())
{
when
(
question
[
18
].
toUHexString
())
{
"36"
->
{
"36"
->
{
//图片验证
//图片验证
debugPrint
(
"是一个图片验证码"
)
DebugLogger
.
debug
(
"是一个图片验证码"
)
val
imageData
=
tlvMap
[
0
x165
]
val
imageData
=
tlvMap
[
0
x165
]
bot
.
configuration
.
captchaSolver
.
invoke
(
bot
.
configuration
.
captchaSolver
.
invoke
(
bot
,
bot
,
(
tlvMap
[
0
x1
6
5
]
?:
error
(
"Captcha Image Data Not Found"
)).
toIoBuffer
()
(
tlvMap
[
0
x1
0
5
]
?:
error
(
"Captcha Image Data Not Found"
)).
toIoBuffer
()
)
)
}
}
else
->
{
else
->
{
error
(
"UNKNOWN CAPTCHA QUESTION: $question"
)
error
(
"UNKNOWN CAPTCHA QUESTION: $question"
)
}
}
}
}
return
TODO
()
}
}
@UseExperimental
(
MiraiDebugAPI
::
class
)
@UseExperimental
(
MiraiDebugAPI
::
class
)
fun
ByteReadPacket
.
onLoginSuccess
(
bot
:
QQAndroidBot
)
=
this
.
debugPrint
(
"login成功解析"
).
run
{
private
fun
onLoginSuccess
(
tlvMap
:
Map
<
Int
,
ByteArray
>,
bot
:
QQAndroidBot
):
LoginPacketResponse
.
Success
{
val
client
=
bot
.
client
val
client
=
bot
.
client
debugDiscardExact
(
2
)
val
tlvMap
:
Map
<
Int
,
ByteArray
>
=
this
.
readTLVMap
()
println
(
"TLV KEYS: "
+
tlvMap
.
keys
.
joinToString
{
it
.
contentToString
()
})
println
(
"TLV KEYS: "
+
tlvMap
.
keys
.
joinToString
{
it
.
contentToString
()
})
tlvMap
[
0
x150
]
?.
let
{
client
.
analysisTlv150
(
it
)
}
tlvMap
[
0
x150
]
?.
let
{
client
.
analysisTlv150
(
it
)
}
...
@@ -446,6 +456,7 @@ internal object LoginPacket : PacketFactory<LoginPacket.LoginPacketResponse>("wt
...
@@ -446,6 +456,7 @@ internal object LoginPacket : PacketFactory<LoginPacket.LoginPacketResponse>("wt
}
}
}
}
return
LoginPacketResponse
.
Success
}
}
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotImpl.kt
View file @
dcb8b0ac
...
@@ -28,7 +28,7 @@ abstract class BotImpl<N : BotNetworkHandler> constructor(
...
@@ -28,7 +28,7 @@ abstract class BotImpl<N : BotNetworkHandler> constructor(
@UseExperimental
(
MiraiExperimentalAPI
::
class
)
@UseExperimental
(
MiraiExperimentalAPI
::
class
)
final
override
val
uin
:
Long
final
override
val
uin
:
Long
get
()
=
account
.
id
get
()
=
account
.
id
final
override
val
logger
:
MiraiLogger
=
configuration
.
logger
?:
DefaultLogger
(
"Bot($uin)"
)
final
override
val
logger
:
MiraiLogger
=
configuration
.
logger
?:
DefaultLogger
(
"Bot($uin)"
)
.
also
{
configuration
.
logger
=
it
}
init
{
init
{
@Suppress
(
"LeakingThis"
)
@Suppress
(
"LeakingThis"
)
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/BotConfiguration.kt
View file @
dcb8b0ac
...
@@ -4,7 +4,6 @@ import kotlinx.io.core.IoBuffer
...
@@ -4,7 +4,6 @@ import kotlinx.io.core.IoBuffer
import
net.mamoe.mirai.Bot
import
net.mamoe.mirai.Bot
import
kotlin.coroutines.CoroutineContext
import
kotlin.coroutines.CoroutineContext
import
kotlin.coroutines.EmptyCoroutineContext
import
kotlin.coroutines.EmptyCoroutineContext
import
kotlin.coroutines.coroutineContext
import
kotlin.jvm.JvmStatic
import
kotlin.jvm.JvmStatic
/**
/**
...
@@ -26,7 +25,7 @@ class BotConfiguration {
...
@@ -26,7 +25,7 @@ class BotConfiguration {
/**
/**
* 日志记录器
* 日志记录器
*/
*/
var
logger
:
Platform
Logger
?
=
null
var
logger
:
Mirai
Logger
?
=
null
/**
/**
* 父 [CoroutineContext]
* 父 [CoroutineContext]
...
...
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