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
b9eacbcf
Commit
b9eacbcf
authored
Jan 30, 2020
by
jiahua.liu
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/master'
parents
ef9938a0
b28a786e
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
99 additions
and
74 deletions
+99
-74
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/ContactImpl.kt
...ommonMain/kotlin/net/mamoe/mirai/qqandroid/ContactImpl.kt
+12
-24
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt
...moe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt
+22
-12
mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/ContactImpl.kt
...nMain/kotlin/net.mamoe.mirai.timpc/network/ContactImpl.kt
+3
-0
mirai-core/src/androidMain/kotlin/net/mamoe/mirai/utils/defaultLoginSolver.kt
...idMain/kotlin/net/mamoe/mirai/utils/defaultLoginSolver.kt
+1
-6
mirai-core/src/androidMain/kotlin/net/mamoe/mirai/utils/io/PlatformSocket.kt
...oidMain/kotlin/net/mamoe/mirai/utils/io/PlatformSocket.kt
+8
-0
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotImpl.kt
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotImpl.kt
+9
-1
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Member.kt
...e/src/commonMain/kotlin/net.mamoe.mirai/contact/Member.kt
+1
-0
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/QQ.kt
...-core/src/commonMain/kotlin/net.mamoe.mirai/contact/QQ.kt
+6
-1
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/io/PlatformSocket.kt
...monMain/kotlin/net.mamoe.mirai/utils/io/PlatformSocket.kt
+5
-0
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/utils/DefaultCaptchaSolverJvm.kt
...n/kotlin/net/mamoe/mirai/utils/DefaultCaptchaSolverJvm.kt
+23
-25
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/utils/io/PlatformSocket.kt
...jvmMain/kotlin/net/mamoe/mirai/utils/io/PlatformSocket.kt
+8
-0
mirai-demos/mirai-demo-android/src/main/kotlin/net/mamoe/mirai/demo/MiraiService.kt
...roid/src/main/kotlin/net/mamoe/mirai/demo/MiraiService.kt
+1
-5
No files found.
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/ContactImpl.kt
View file @
b9eacbcf
...
...
@@ -26,6 +26,9 @@ internal class QQImpl(bot: QQAndroidBot, override val coroutineContext: Coroutin
TODO
(
"not implemented"
)
}
override
val
isOnline
:
Boolean
get
()
=
true
override
suspend
fun
queryProfile
():
Profile
{
TODO
(
"not implemented"
)
}
...
...
@@ -40,11 +43,16 @@ internal class QQImpl(bot: QQAndroidBot, override val coroutineContext: Coroutin
}
internal
class
MemberImpl
(
bot
:
QQAndroidBot
,
group
:
Group
,
override
val
coroutineContext
:
CoroutineContext
,
override
val
id
:
Long
)
:
ContactImpl
(),
Member
{
override
val
group
:
Group
by
group
.
unsafeWeakRef
()
internal
class
MemberImpl
(
qq
:
QQImpl
,
group
:
GroupImpl
,
override
val
coroutineContext
:
CoroutineContext
)
:
ContactImpl
(),
Member
,
QQ
by
qq
{
override
val
group
:
GroupImpl
by
group
.
unsafeWeakRef
()
val
qq
:
QQImpl
by
qq
.
unsafeWeakRef
()
override
val
permission
:
MemberPermission
get
()
=
TODO
(
"not implemented"
)
override
val
bot
:
QQAndroidBot
by
bot
.
unsafeWeakRef
()
override
suspend
fun
mute
(
durationSeconds
:
Int
):
Boolean
{
TODO
(
"not implemented"
)
...
...
@@ -54,26 +62,6 @@ internal class MemberImpl(bot: QQAndroidBot, group: Group, override val coroutin
TODO
(
"not implemented"
)
}
override
suspend
fun
queryProfile
():
Profile
{
TODO
(
"not implemented"
)
}
override
suspend
fun
queryPreviousNameList
():
PreviousNameList
{
TODO
(
"not implemented"
)
}
override
suspend
fun
queryRemark
():
FriendNameRemark
{
TODO
(
"not implemented"
)
}
override
suspend
fun
sendMessage
(
message
:
MessageChain
)
{
TODO
(
"not implemented"
)
}
override
suspend
fun
uploadImage
(
image
:
ExternalImage
):
ImageId
{
TODO
(
"not implemented"
)
}
}
...
...
@@ -89,7 +77,7 @@ internal class GroupImpl(bot: QQAndroidBot, override val coroutineContext: Corou
override
val
members
:
ContactList
<
Member
>
=
ContactList
(
LockFreeLinkedList
())
override
fun
getMember
(
id
:
Long
):
Member
=
members
.
delegate
.
filteringGetOrAdd
({
it
.
id
==
id
},
{
MemberImpl
(
bot
as
QQAndroidBot
,
this
,
coroutineContext
,
id
)
})
members
.
delegate
.
filteringGetOrAdd
({
it
.
id
==
id
},
{
MemberImpl
(
bot
.
getQQ
(
id
)
as
QQImpl
,
this
,
coroutineContext
)
})
override
suspend
fun
updateGroupInfo
():
GroupInfo
{
TODO
(
"not implemented"
)
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt
View file @
b9eacbcf
...
...
@@ -14,17 +14,11 @@ import net.mamoe.mirai.event.broadcast
import
net.mamoe.mirai.network.BotNetworkHandler
import
net.mamoe.mirai.qqandroid.QQAndroidBot
import
net.mamoe.mirai.qqandroid.event.PacketReceivedEvent
import
net.mamoe.mirai.qqandroid.network.protocol.data.jce.GetFriendListReq
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.PacketFactory
import
net.mamoe.mirai.qqandroid.network.protocol.packet.PacketLogger
import
net.mamoe.mirai.qqandroid.network.protocol.packet.list.FriendList
import
net.mamoe.mirai.qqandroid.network.protocol.packet.*
import
net.mamoe.mirai.qqandroid.network.protocol.packet.login.LoginPacket
import
net.mamoe.mirai.qqandroid.network.protocol.packet.login.LoginPacket.LoginPacketResponse.*
import
net.mamoe.mirai.qqandroid.network.protocol.packet.login.StatSvc
import
net.mamoe.mirai.utils.*
import
net.mamoe.mirai.utils.cryptor.contentToString
import
net.mamoe.mirai.utils.io.*
import
kotlin.coroutines.CoroutineContext
...
...
@@ -56,7 +50,9 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
is
Captcha
->
when
(
response
)
{
is
Captcha
.
Picture
->
{
var
result
=
bot
.
configuration
.
loginSolver
.
onSolvePicCaptcha
(
bot
,
response
.
data
)
var
result
=
response
.
data
.
withUse
{
bot
.
configuration
.
loginSolver
.
onSolvePicCaptcha
(
bot
,
this
)
}
if
(
result
==
null
||
result
.
length
!=
4
)
{
//refresh captcha
result
=
"ABCD"
...
...
@@ -325,19 +321,33 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
/**
* 发送一个包, 并挂起直到接收到指定的返回包或超时(3000ms)
*/
suspend
fun
<
E
:
Packet
>
OutgoingPacket
.
sendAndExpect
(
timoutMillis
:
Long
=
3000
):
E
{
suspend
fun
<
E
:
Packet
>
OutgoingPacket
.
sendAndExpect
(
timeoutMillis
:
Long
=
3000
,
retry
:
Int
=
1
):
E
{
require
(
timeoutMillis
>
0
)
{
"timeoutMillis must > 0"
}
require
(
retry
>=
0
)
{
"retry must >= 0"
}
val
handler
=
PacketListener
(
commandName
=
commandName
,
sequenceId
=
sequenceId
)
packetListeners
.
addLast
(
handler
)
bot
.
logger
.
info
(
"Send: ${this.commandName}"
)
var
lastException
:
Exception
?
=
null
repeat
(
retry
+
1
)
{
try
{
return
doSendAndReceive
(
timeoutMillis
,
handler
)
}
catch
(
e
:
Exception
)
{
lastException
=
e
}
}
throw
lastException
!!
}
private
suspend
inline
fun
<
E
:
Packet
>
OutgoingPacket
.
doSendAndReceive
(
timeoutMillis
:
Long
=
3000
,
handler
:
PacketListener
):
E
{
channel
.
send
(
delegate
)
return
withTimeoutOrNull
(
timoutMillis
)
{
return
withTimeoutOrNull
(
tim
e
outMillis
)
{
@Suppress
(
"UNCHECKED_CAST"
)
handler
.
await
()
as
E
// 不要 `withTimeout`. timeout 的异常会不知道去哪了.
}
?:
net
.
mamoe
.
mirai
.
qqandroid
.
utils
.
inline
{
packetListeners
.
remove
(
handler
)
error
(
"timeout when sending $
{commandName}
"
)
error
(
"timeout when sending $
commandName
"
)
}
}
...
...
mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/ContactImpl.kt
View file @
b9eacbcf
...
...
@@ -139,6 +139,9 @@ internal class QQImpl @PublishedApi internal constructor(bot: TIMPCBot, override
}
}
override
val
isOnline
:
Boolean
get
()
=
true
override
suspend
fun
queryProfile
():
Profile
=
withTIMPCBot
{
RequestProfileDetailsPacket
(
bot
.
uin
,
id
,
sessionKey
).
sendAndExpect
<
RequestProfileDetailsResponse
>().
profile
}
...
...
mirai-core/src/androidMain/kotlin/net/mamoe/mirai/utils/defaultLoginSolver.kt
View file @
b9eacbcf
...
...
@@ -15,12 +15,7 @@ actual var defaultLoginSolver: LoginSolver = object : LoginSolver() {
error
(
"should be implemented manually by you"
)
}
override
suspend
fun
on
GetPhoneNumber
():
String
{
override
suspend
fun
on
SolveUnsafeDeviceLoginVerify
(
bot
:
Bot
,
url
:
String
):
String
?
{
error
(
"should be implemented manually by you"
)
}
override
suspend
fun
onGetSMSVerifyCode
():
String
{
error
(
"should be implemented manually by you"
)
}
}
\ No newline at end of file
mirai-core/src/androidMain/kotlin/net/mamoe/mirai/utils/io/PlatformSocket.kt
View file @
b9eacbcf
...
...
@@ -34,6 +34,14 @@ actual class PlatformSocket : Closeable {
@PublishedApi
internal
lateinit
var
readChannel
:
ByteReadChannel
actual
suspend
inline
fun
send
(
packet
:
ByteArray
,
offset
:
Int
,
length
:
Int
)
{
try
{
writeChannel
.
writeFully
(
packet
,
offset
,
length
)
}
catch
(
e
:
Exception
)
{
throw
SendPacketInternalException
(
e
)
}
}
/**
* @throws SendPacketInternalException
*/
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotImpl.kt
View file @
b9eacbcf
...
...
@@ -98,7 +98,15 @@ abstract class BotImpl<N : BotNetworkHandler> constructor(
}
_network
=
createNetworkHandler
(
this
.
coroutineContext
)
_network
.
login
()
while
(
true
){
try
{
return
_network
.
login
()
}
catch
(
e
:
Exception
){
e
.
logStacktrace
(
"Exception when login"
)
}
delay
(
3000
)
logger
.
warning
(
"Login failed. Retrying in 3s..."
)
}
}
protected
abstract
fun
createNetworkHandler
(
coroutineContext
:
CoroutineContext
):
N
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Member.kt
View file @
b9eacbcf
...
...
@@ -13,6 +13,7 @@ interface Member : QQ, Contact {
/**
* 所在的群
*/
@WeakRefProperty
val
group
:
Group
/**
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/QQ.kt
View file @
b9eacbcf
...
...
@@ -21,10 +21,15 @@ import net.mamoe.mirai.data.Profile
* @author Him188moe
*/
interface
QQ
:
Contact
,
CoroutineScope
{
/**
* 是否在线. 这个属性的值将会与服务器同步更新.
*/
val
isOnline
:
Boolean
/**
* 请求头像下载链接
*/
// @MiraiExperimentalAPI
// @MiraiExperimentalAPI
//suspend fun queryAvatar(): AvatarLink
/**
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/io/PlatformSocket.kt
View file @
b9eacbcf
...
...
@@ -12,6 +12,11 @@ import net.mamoe.mirai.utils.MiraiInternalAPI
expect
class
PlatformSocket
()
:
Closeable
{
suspend
fun
connect
(
serverHost
:
String
,
serverPort
:
Int
)
/**
* @throws SendPacketInternalException
*/
suspend
inline
fun
send
(
packet
:
ByteArray
,
offset
:
Int
=
0
,
length
:
Int
=
packet
.
size
-
offset
)
/**
* @throws SendPacketInternalException
*/
...
...
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/utils/DefaultCaptchaSolverJvm.kt
View file @
b9eacbcf
...
...
@@ -29,36 +29,34 @@ actual var defaultLoginSolver: LoginSolver = DefaultLoginSolver()
class
DefaultLoginSolver
:
LoginSolver
()
{
override
suspend
fun
onSolvePicCaptcha
(
bot
:
Bot
,
data
:
IoBuffer
):
String
?
{
loginSolverLock
.
withLock
{
val
tempFile
:
File
=
createTempFile
(
suffix
=
".png"
).
apply
{
deleteOnExit
()
}
withContext
(
Dispatchers
.
IO
)
{
tempFile
.
createNewFile
()
bot
.
logger
.
info
(
"需要图片验证码登录, 验证码为 4 字母"
)
try
{
tempFile
.
writeChannel
().
use
{
writeFully
(
data
)
}
bot
.
logger
.
info
(
"将会显示字符图片. 若看不清字符图片, 请查看文件 ${tempFile.absolutePath}"
)
}
catch
(
e
:
Exception
)
{
bot
.
logger
.
info
(
"无法写出验证码文件(${e.message}), 请尝试查看以上字符图片"
)
}
override
suspend
fun
onSolvePicCaptcha
(
bot
:
Bot
,
data
:
IoBuffer
):
String
?
=
loginSolverLock
.
withLock
{
val
tempFile
:
File
=
createTempFile
(
suffix
=
".png"
).
apply
{
deleteOnExit
()
}
withContext
(
Dispatchers
.
IO
)
{
tempFile
.
createNewFile
()
bot
.
logger
.
info
(
"需要图片验证码登录, 验证码为 4 字母"
)
try
{
tempFile
.
writeChannel
().
use
{
writeFully
(
data
)
}
bot
.
logger
.
info
(
"将会显示字符图片. 若看不清字符图片, 请查看文件 ${tempFile.absolutePath}"
)
}
catch
(
e
:
Exception
)
{
bot
.
logger
.
info
(
"无法写出验证码文件(${e.message}), 请尝试查看以上字符图片"
)
}
tempFile
.
inputStream
().
use
{
val
img
=
ImageIO
.
read
(
it
)
if
(
img
==
null
)
{
bot
.
logger
.
info
(
"无法创建字符图片. 请查看文件"
)
}
else
{
bot
.
logger
.
info
(
img
.
createCharImg
())
}
tempFile
.
inputStream
().
use
{
val
img
=
ImageIO
.
read
(
it
)
if
(
img
==
null
)
{
bot
.
logger
.
info
(
"无法创建字符图片. 请查看文件"
)
}
else
{
bot
.
logger
.
info
(
img
.
createCharImg
())
}
}
bot
.
logger
.
info
(
"请输入 4 位字母验证码. 若要更换验证码, 请直接回车"
)
return
readLine
()
?.
takeUnless
{
it
.
isEmpty
()
||
it
.
length
!=
4
}.
also
{
bot
.
logger
.
info
(
"正在提交["
+
it
+
"]中..."
)
}
}
bot
.
logger
.
info
(
"请输入 4 位字母验证码. 若要更换验证码, 请直接回车"
)
return
readLine
()
?.
takeUnless
{
it
.
isEmpty
()
||
it
.
length
!=
4
}.
also
{
bot
.
logger
.
info
(
"正在提交[$it]中..."
)
}
}
override
suspend
fun
onSolveSliderCaptcha
(
bot
:
Bot
,
url
:
String
):
String
?
{
override
suspend
fun
onSolveSliderCaptcha
(
bot
:
Bot
,
url
:
String
):
String
?
=
loginSolverLock
.
withLock
{
bot
.
logger
.
info
(
"需要滑动验证码"
)
bot
.
logger
.
info
(
"请在任意浏览器中打开以下链接并完成验证码. "
)
bot
.
logger
.
info
(
"完成后请输入任意字符 "
)
...
...
@@ -68,7 +66,7 @@ class DefaultLoginSolver : LoginSolver() {
}
}
override
suspend
fun
onSolveUnsafeDeviceLoginVerify
(
bot
:
Bot
,
url
:
String
):
String
?
{
override
suspend
fun
onSolveUnsafeDeviceLoginVerify
(
bot
:
Bot
,
url
:
String
):
String
?
=
loginSolverLock
.
withLock
{
bot
.
logger
.
info
(
"需要进行账户安全认证"
)
bot
.
logger
.
info
(
"该账户有[设备锁]/[不常用登陆地点]/[不常用设备登陆]的问题"
)
bot
.
logger
.
info
(
"完成以下账号认证即可成功登陆|理论本认证在mirai每个账户中最多出现1次"
)
...
...
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/utils/io/PlatformSocket.kt
View file @
b9eacbcf
...
...
@@ -34,6 +34,14 @@ actual class PlatformSocket : Closeable {
@PublishedApi
internal
lateinit
var
readChannel
:
ByteReadChannel
actual
suspend
inline
fun
send
(
packet
:
ByteArray
,
offset
:
Int
,
length
:
Int
)
{
try
{
writeChannel
.
writeFully
(
packet
,
offset
,
length
)
}
catch
(
e
:
Exception
)
{
throw
SendPacketInternalException
(
e
)
}
}
/**
* @throws SendPacketInternalException
*/
...
...
mirai-demos/mirai-demo-android/src/main/kotlin/net/mamoe/mirai/demo/MiraiService.kt
View file @
b9eacbcf
...
...
@@ -57,11 +57,7 @@ class MiraiService : Service() {
TODO
(
"not implemented"
)
}
override
suspend
fun
onGetPhoneNumber
():
String
{
TODO
(
"not implemented"
)
}
override
suspend
fun
onGetSMSVerifyCode
():
String
{
override
suspend
fun
onSolveUnsafeDeviceLoginVerify
(
bot
:
Bot
,
url
:
String
):
String
?
{
TODO
(
"not implemented"
)
}
...
...
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