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
7fb588be
Commit
7fb588be
authored
Sep 07, 2019
by
Him188moe
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Enhanced output & login flow
parent
2c108b17
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
151 additions
and
73 deletions
+151
-73
mirai-core/src/main/java/net/mamoe/mirai/MiraiServer.java
mirai-core/src/main/java/net/mamoe/mirai/MiraiServer.java
+49
-4
mirai-core/src/main/java/net/mamoe/mirai/network/RobotNetworkHandler.kt
.../main/java/net/mamoe/mirai/network/RobotNetworkHandler.kt
+19
-39
mirai-core/src/main/java/net/mamoe/mirai/network/packet/GradeInfo.kt
...src/main/java/net/mamoe/mirai/network/packet/GradeInfo.kt
+4
-0
mirai-core/src/main/java/net/mamoe/mirai/network/packet/Heartbeat.kt
...src/main/java/net/mamoe/mirai/network/packet/Heartbeat.kt
+4
-0
mirai-core/src/main/java/net/mamoe/mirai/network/packet/SKey.kt
...core/src/main/java/net/mamoe/mirai/network/packet/SKey.kt
+4
-0
mirai-core/src/main/java/net/mamoe/mirai/network/packet/ServerPacket.kt
.../main/java/net/mamoe/mirai/network/packet/ServerPacket.kt
+33
-8
mirai-core/src/main/java/net/mamoe/mirai/network/packet/Touch.kt
...ore/src/main/java/net/mamoe/mirai/network/packet/Touch.kt
+4
-3
mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ClientLogin.kt
.../java/net/mamoe/mirai/network/packet/login/ClientLogin.kt
+9
-9
mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/LoginState.kt
...n/java/net/mamoe/mirai/network/packet/login/LoginState.kt
+1
-1
mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ServerLoginResponseKeyExchangePacket.kt
...work/packet/login/ServerLoginResponseKeyExchangePacket.kt
+10
-4
mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ServerLoginResponsePasswordVerifiedPacket.kt
...packet/login/ServerLoginResponsePasswordVerifiedPacket.kt
+5
-3
mirai-core/src/main/java/net/mamoe/mirai/utils/TEA.java
mirai-core/src/main/java/net/mamoe/mirai/utils/TEA.java
+9
-1
mirai-core/src/test/java/BadQQFilter.kt
mirai-core/src/test/java/BadQQFilter.kt
+0
-1
No files found.
mirai-core/src/main/java/net/mamoe/mirai/MiraiServer.java
View file @
7fb588be
...
...
@@ -8,6 +8,8 @@ import net.mamoe.mirai.network.packet.login.LoginState;
import
net.mamoe.mirai.task.MiraiTaskManager
;
import
net.mamoe.mirai.utils.LoggerTextFormat
;
import
net.mamoe.mirai.utils.MiraiLogger
;
import
net.mamoe.mirai.utils.MiraiLoggerKt
;
import
net.mamoe.mirai.utils.RobotAccount
;
import
net.mamoe.mirai.utils.config.MiraiConfig
;
import
net.mamoe.mirai.utils.config.MiraiConfigSection
;
import
net.mamoe.mirai.utils.setting.MiraiSettingListSection
;
...
...
@@ -16,7 +18,9 @@ import net.mamoe.mirai.utils.setting.MiraiSettings;
import
java.io.File
;
import
java.io.IOException
;
import
java.util.List
;
import
java.util.Scanner
;
import
java.util.concurrent.ExecutionException
;
/**
* @author NaturalHG
...
...
@@ -174,17 +178,24 @@ public class MiraiServer {
getLogger
().
info
(
"Initializing [Robot]s"
);
try
{
getAvailableRobot
();
}
catch
(
ExecutionException
|
InterruptedException
e
)
{
e
.
printStackTrace
();
}
/*
this.qqs.keySet().stream().map(key -> this.qqs.getSection(key)).forEach(section -> {
getLogger().info("Initializing [Robot] " + section.getString("account"));
try {
Robot robot = new Robot(section);
var state = robot.network.tryLogin$mirai_core().get();
//robot.network.tryLogin$mirai_core().whenComplete((state, e) -> {
if
(
state
==
LoginState
.
SUCCE
ED
)
{
if (state == LoginState.SUCCE
SS
) {
Robot.instances.add(robot);
getLogger
().
success
(
"
Login Succeed"
);
getLogger().success(" Login Succeed");
} else {
getLogger
().
error
(
"
Login Failed with error "
+
state
);
getLogger().error(" Login Failed with error " + state);
robot.close();
}
// }).get();
...
...
@@ -194,8 +205,42 @@ public class MiraiServer {
getLogger().error("Could not load QQ robots config!");
System.exit(1);
}
});
});
*/
}
String
qqList
=
"3150499752----1234567890\n"
+
"3119292829----987654321\n"
+
"2399148773----12345678910\n"
+
"3145561616----987654321\n"
+
"2374150554----12345678910\n"
+
"2375307394----12345678910\n"
+
"1531848970----1234567890\n"
+
"1947293188----a123456789\n"
+
"1771231721----123456789a\n"
+
"2401645747----12345678910\n"
+
"3338427598----987654321\n"
+
"3055657369----1234567890\n"
+
"3502771486----987654321\n"
+
"1515419818----1234567890\n"
+
"2402273360----12345678910\n"
+
"3107367848----987654321\n"
+
"3487109947----123456789a\n"
+
"3489288352----123456789a\n"
+
"2385617018----12345678910\n"
+
"1251003390----123456789a\n"
;
private
Robot
getAvailableRobot
()
throws
ExecutionException
,
InterruptedException
{
for
(
String
it
:
qqList
.
split
(
"\n"
))
{
var
strings
=
it
.
split
(
"----"
);
var
robot
=
new
Robot
(
new
RobotAccount
(
Long
.
parseLong
(
strings
[
0
]),
strings
[
1
]),
List
.
of
());
if
(
robot
.
network
.
tryLogin
$mirai_core
().
get
()
==
LoginState
.
SUCCESS
)
{
MiraiLoggerKt
.
success
(
robot
,
"Login succeed"
);
return
robot
;
}
}
throw
new
RuntimeException
();
}
}
mirai-core/src/main/java/net/mamoe/mirai/network/RobotNetworkHandler.kt
View file @
7fb588be
...
...
@@ -90,7 +90,7 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
/**
* 仅当 [LoginState] 非 [LoginState.UNKNOWN] 且非 [LoginState.TIMEOUT] 才会调用 [loginHook].
* 如果要输入验证码, 那么会以参数 [LoginState.VERIFICATION_CODE] 调用 [loginHandler], 登录完成后再以 [LoginState.SUCCE
ED
] 调用 [loginHandler]
* 如果要输入验证码, 那么会以参数 [LoginState.VERIFICATION_CODE] 调用 [loginHandler], 登录完成后再以 [LoginState.SUCCE
SS
] 调用 [loginHandler]
*
* @param touchingTimeoutMillis 连接每个服务器的 timeout
*/
...
...
@@ -296,7 +296,7 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
private
lateinit
var
token0825
:
ByteArray
private
var
loginTime
:
Int
=
0
private
lateinit
var
loginIP
:
String
private
var
tgtgtKey
:
ByteArray
?
=
null
private
var
tgtgtKey
:
ByteArray
=
getRandomByteArray
(
16
)
private
var
tlv0105
:
ByteArray
=
lazyEncode
{
it
.
writeHex
(
"01 05 00 30"
)
...
...
@@ -329,8 +329,7 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
this
.
loginIP
=
packet
.
loginIP
this
.
loginTime
=
packet
.
loginTime
this
.
token0825
=
packet
.
token0825
this
.
tgtgtKey
=
packet
.
tgtgtKey
sendPacket
(
ClientPasswordSubmissionPacket
(
robot
.
account
.
qqNumber
,
robot
.
account
.
password
,
packet
.
loginTime
,
packet
.
loginIP
,
packet
.
tgtgtKey
,
packet
.
token0825
))
sendPacket
(
ClientPasswordSubmissionPacket
(
robot
.
account
.
qqNumber
,
robot
.
account
.
password
,
packet
.
loginTime
,
packet
.
loginIP
,
this
.
tgtgtKey
!!
,
packet
.
token0825
))
}
}
...
...
@@ -367,10 +366,14 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
this
.
token00BA
=
packet
.
token00BA
if
(
packet
.
transmissionCompleted
)
{
(
MiraiServer
.
getInstance
().
parentFolder
+
"VerificationCode.png"
).
writeBytes
(
this
.
captchaCache
!!
)
robot
notice
(
CharImageUtil
.
createCharImg
(
ImageIO
.
read
(
this
.
captchaCache
!!
.
inputStream
())))
robot
notice
(
"需要验证码登录"
)
robot
notice
(
"若看不清请查根目录下 VerificationCode.png"
)
robot
notice
(
"需要验证码登录, 验证码为 4 字母"
)
try
{
(
MiraiServer
.
getInstance
().
parentFolder
+
"VerificationCode.png"
).
writeBytes
(
this
.
captchaCache
!!
)
robot
notice
(
"若看不清字符图片, 请查看 Mirai 根目录下 VerificationCode.png"
)
}
catch
(
e
:
Exception
)
{
robot
notice
"无法写出验证码文件, 请尝试查看以上字符图片"
}
robot
notice
(
"若要更换验证码, 请直接回车"
)
val
code
=
Scanner
(
System
.
`in`
).
nextLine
()
if
(
code
.
isEmpty
()
||
code
.
length
!=
4
)
{
...
...
@@ -391,40 +394,18 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
}
//是ClientPasswordSubmissionPacket之后服务器回复的
is
ServerLoginResponse
Resend
Packet
->
{
is
ServerLoginResponse
KeyExchange
Packet
->
{
//if (packet.tokenUnknown != null) {
//this.token00BA = packet.token00BA!!
//println("token00BA changed!!! to " + token00BA.toUByteArray())
//}
if
(
packet
.
flag
==
ServerLoginResponse
Resend
Packet
.
Flag
.
`
08
36
31
03
`
)
{
if
(
packet
.
flag
==
ServerLoginResponse
KeyExchange
Packet
.
Flag
.
`
08
36
31
03
`
)
{
this
.
tgtgtKey
=
packet
.
tgtgtKey
sendPacket
(
ClientLoginResendPacket3104
(
robot
.
account
.
qqNumber
,
robot
.
account
.
password
,
loginTime
,
loginIP
,
tgtgtKey
!!
,
token0825
,
when
(
packet
.
tokenUnknown
!=
null
)
{
true
->
packet
.
tokenUnknown
!!
false
->
this
.
token00BA
},
packet
.
_0836_tlv0006_encr
))
sendPacket
(
ClientLoginResendPacket3104
(
robot
.
account
.
qqNumber
,
robot
.
account
.
password
,
loginTime
,
loginIP
,
tgtgtKey
,
token0825
,
packet
.
tokenUnknown
?:
this
.
token00BA
,
packet
.
tlv0006
))
}
else
{
sendPacket
(
ClientLoginResendPacket3106
(
robot
.
account
.
qqNumber
,
robot
.
account
.
password
,
loginTime
,
loginIP
,
tgtgtKey
!!
,
token0825
,
when
(
packet
.
tokenUnknown
!=
null
)
{
true
->
packet
.
tokenUnknown
!!
false
->
this
.
token00BA
},
packet
.
_0836_tlv0006_encr
))
sendPacket
(
ClientLoginResendPacket3106
(
robot
.
account
.
qqNumber
,
robot
.
account
.
password
,
loginTime
,
loginIP
,
tgtgtKey
,
token0825
,
packet
.
tokenUnknown
?:
token00BA
,
packet
.
tlv0006
))
}
}
...
...
@@ -446,7 +427,7 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
}
is
ServerLoginSuccessPacket
->
{
socketHandler
.
loginFuture
!!
.
complete
(
LoginState
.
SUCCE
ED
)
socketHandler
.
loginFuture
!!
.
complete
(
LoginState
.
SUCCE
SS
)
sendPacket
(
ClientSKeyRequestPacket
(
robot
.
account
.
qqNumber
,
sessionKey
))
}
...
...
@@ -467,8 +448,8 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
is
ServerVerificationCodePacket
.
Encrypted
->
distributePacket
(
packet
.
decrypt
())
is
ServerLoginResponseVerificationCodeInitPacket
.
Encrypted
->
distributePacket
(
packet
.
decrypt
())
is
ServerLoginResponse
ResendPacket
.
Encrypted
->
distributePacket
(
packet
.
decrypt
(
this
.
tgtgtKey
!!
))
is
ServerLoginResponseSuccessPacket
.
Encrypted
->
distributePacket
(
packet
.
decrypt
(
this
.
tgtgtKey
!!
))
is
ServerLoginResponse
KeyExchangePacket
.
Encrypted
->
distributePacket
(
packet
.
decrypt
(
this
.
tgtgtKey
))
is
ServerLoginResponseSuccessPacket
.
Encrypted
->
distributePacket
(
packet
.
decrypt
(
this
.
tgtgtKey
))
is
ServerSessionKeyResponsePacket
.
Encrypted
->
distributePacket
(
packet
.
decrypt
(
this
.
sessionResponseDecryptionKey
))
is
ServerTouchResponsePacket
.
Encrypted
->
distributePacket
(
packet
.
decrypt
())
is
ServerSKeyResponsePacket
.
Encrypted
->
distributePacket
(
packet
.
decrypt
(
sessionKey
))
...
...
@@ -489,7 +470,6 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
override
fun
close
()
{
this
.
captchaCache
=
null
this
.
tgtgtKey
=
null
this
.
heartbeatFuture
?.
cancel
(
true
)
this
.
sKeyRefresherFuture
?.
cancel
(
true
)
...
...
mirai-core/src/main/java/net/mamoe/mirai/network/packet/GradeInfo.kt
View file @
7fb588be
...
...
@@ -26,6 +26,10 @@ class ClientAccountInfoRequestPacket(
it
.
writeByte
(
0
x00
)
}
}
override
fun
getFixedId
():
String
{
return
this
.
idHex
+
" ?? ??"
}
}
@PacketId
(
"00 5C"
)
...
...
mirai-core/src/main/java/net/mamoe/mirai/network/packet/Heartbeat.kt
View file @
7fb588be
...
...
@@ -22,6 +22,10 @@ class ClientHeartbeatPacket(
it
.
writeHex
(
"00 01 00 01"
)
}
}
override
fun
getFixedId
():
String
{
return
this
.
idHex
+
" ?? ??"
}
}
class
ServerHeartbeatResponsePacket
(
input
:
DataInputStream
)
:
ServerPacket
(
input
)
\ No newline at end of file
mirai-core/src/main/java/net/mamoe/mirai/network/packet/SKey.kt
View file @
7fb588be
...
...
@@ -23,6 +23,10 @@ class ClientSKeyRequestPacket(
it
.
writeHex
(
"33 00 05 00 08 74 2E 71 71 2E 63 6F 6D 00 0A 71 75 6E 2E 71 71 2E 63 6F 6D 00 0C 71 7A 6F 6E 65 2E 71 71 2E 63 6F 6D 00 0C 6A 75 62 61 6F 2E 71 71 2E 63 6F 6D 00 09 6B 65 2E 71 71 2E 63 6F 6D"
)
}
}
override
fun
getFixedId
():
String
{
return
this
.
idHex
+
" ?? ??"
}
}
/**
...
...
mirai-core/src/main/java/net/mamoe/mirai/network/packet/ServerPacket.kt
View file @
7fb588be
...
...
@@ -5,7 +5,10 @@ import net.mamoe.mirai.network.packet.PacketNameFormatter.adjustName
import
net.mamoe.mirai.network.packet.action.ServerSendFriendMessageResponsePacket
import
net.mamoe.mirai.network.packet.action.ServerSendGroupMessageResponsePacket
import
net.mamoe.mirai.network.packet.login.*
import
net.mamoe.mirai.utils.*
import
net.mamoe.mirai.utils.TEA
import
net.mamoe.mirai.utils.getAllDeclaredFields
import
net.mamoe.mirai.utils.hexToBytes
import
net.mamoe.mirai.utils.toUHexString
import
java.io.DataInputStream
/**
...
...
@@ -50,11 +53,10 @@ abstract class ServerPacket(val input: DataInputStream) : Packet {
"08 36 31 03"
,
"08 36 31 04"
,
"08 36 31 05"
,
"08 36 31 06"
->
{
when
(
bytes
.
size
)
{
271
,
207
->
return
ServerLoginResponseResendPacket
.
Encrypted
(
stream
,
when
(
idHex
)
{
"08 36 31 03"
->
ServerLoginResponseResendPacket
.
Flag
.
`
08
36
31
03
`
else
->
{
MiraiLogger
debug
(
"ServerLoginResponseResendPacketEncrypted: flag=$idHex"
);
ServerLoginResponseResendPacket
.
Flag
.
OTHER
}
271
,
207
->
return
ServerLoginResponseKeyExchangePacket
.
Encrypted
(
stream
,
when
(
idHex
)
{
"08 36 31 03"
->
ServerLoginResponseKeyExchangePacket
.
Flag
.
`
08
36
31
03
`
else
->
ServerLoginResponseKeyExchangePacket
.
Flag
.
OTHER
}).
apply
{
this
.
idHex
=
idHex
}
871
->
return
ServerLoginResponseVerificationCodeInitPacket
.
Encrypted
(
stream
).
apply
{
this
.
idHex
=
idHex
}
}
...
...
@@ -132,14 +134,37 @@ abstract class ServerPacket(val input: DataInputStream) : Packet {
}
fun
decryptBy
(
key
:
ByteArray
):
DataInputStream
{
input
.
goto
(
14
)
return
DataInputStream
(
TEA
.
decrypt
(
input
.
readAllBytes
().
let
{
it
.
copyOfRange
(
0
,
it
.
size
-
1
)
},
key
).
inputStream
())
return
decryptAsByteArray
(
key
).
dataInputStream
()
}
@ExperimentalUnsignedTypes
fun
decryptBy
(
keyHex
:
String
):
DataInputStream
{
return
this
.
decryptBy
(
keyHex
.
hexToBytes
())
}
fun
decryptBy
(
key1
:
ByteArray
,
key2
:
ByteArray
):
DataInputStream
{
return
TEA
.
decrypt
(
this
.
decryptAsByteArray
(
key1
),
key2
).
dataInputStream
();
}
@ExperimentalUnsignedTypes
fun
decryptBy
(
key1
:
String
,
key2
:
ByteArray
):
DataInputStream
{
return
this
.
decryptBy
(
key1
.
hexToBytes
(),
key2
)
}
@ExperimentalUnsignedTypes
fun
decryptBy
(
key1
:
ByteArray
,
key2
:
String
):
DataInputStream
{
return
this
.
decryptBy
(
key1
,
key2
.
hexToBytes
())
}
@ExperimentalUnsignedTypes
fun
decryptBy
(
keyHex1
:
String
,
keyHex2
:
String
):
DataInputStream
{
return
this
.
decryptBy
(
keyHex1
.
hexToBytes
(),
keyHex2
.
hexToBytes
())
}
private
fun
decryptAsByteArray
(
key
:
ByteArray
):
ByteArray
{
input
.
goto
(
14
)
return
TEA
.
decrypt
(
input
.
readAllBytes
().
cutTail
(
1
),
key
)
}
}
...
...
mirai-core/src/main/java/net/mamoe/mirai/network/packet/Touch.kt
View file @
7fb588be
package
net.mamoe.mirai.network.packet
import
net.mamoe.mirai.network.Protocol
import
net.mamoe.mirai.utils.*
import
net.mamoe.mirai.utils.ByteArrayDataOutputStream
import
net.mamoe.mirai.utils.TEA
import
net.mamoe.mirai.utils.hexToBytes
import
net.mamoe.mirai.utils.toUHexString
import
java.io.DataInputStream
import
java.io.IOException
...
...
@@ -20,7 +23,6 @@ class ServerTouchResponsePacket(inputStream: DataInputStream) : ServerPacket(inp
var
loginTime
:
Int
=
0
lateinit
var
loginIP
:
String
lateinit
var
token0825
:
ByteArray
lateinit
var
tgtgtKey
:
ByteArray
enum
class
Type
{
TYPE_08_25_31_01
,
...
...
@@ -41,7 +43,6 @@ class ServerTouchResponsePacket(inputStream: DataInputStream) : ServerPacket(inp
loginTime
=
input
.
readInt
()
loginIP
=
input
.
readIP
()
tgtgtKey
=
getRandomByteArray
(
16
)
}
else
->
{
...
...
mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ClientLogin.kt
View file @
7fb588be
...
...
@@ -41,8 +41,8 @@ class ClientPasswordSubmissionPacket(
@PacketId
(
"08 36 31 04"
)
@ExperimentalUnsignedTypes
class
ClientLoginResendPacket3104
(
qq
:
Long
,
password
:
String
,
loginTime
:
Int
,
loginIP
:
String
,
tgtgtKey
:
ByteArray
,
token0825
:
ByteArray
,
token00BA
:
ByteArray
,
tlv
_0006_encr
:
ByteArray
?
=
null
)
:
ClientLoginResendPacket
(
qq
,
password
,
loginTime
,
loginIP
,
tgtgtKey
,
token0825
,
token00BA
,
tlv
_0006_encr
)
class
ClientLoginResendPacket3104
(
qq
:
Long
,
password
:
String
,
loginTime
:
Int
,
loginIP
:
String
,
tgtgtKey
:
ByteArray
,
token0825
:
ByteArray
,
token00BA
:
ByteArray
,
tlv
0006
:
ByteArray
?
=
null
)
:
ClientLoginResendPacket
(
qq
,
password
,
loginTime
,
loginIP
,
tgtgtKey
,
token0825
,
token00BA
,
tlv
0006
)
@PacketId
(
"08 36 31 05"
)
@ExperimentalUnsignedTypes
...
...
@@ -51,8 +51,8 @@ class ClientLoginResendPacket3105(qq: Long, password: String, loginTime: Int, lo
@PacketId
(
"08 36 31 06"
)
@ExperimentalUnsignedTypes
class
ClientLoginResendPacket3106
(
qq
:
Long
,
password
:
String
,
loginTime
:
Int
,
loginIP
:
String
,
tgtgtKey
:
ByteArray
,
token0825
:
ByteArray
,
token00BA
:
ByteArray
,
tlv
_0006_encr
:
ByteArray
?
=
null
)
:
ClientLoginResendPacket
(
qq
,
password
,
loginTime
,
loginIP
,
tgtgtKey
,
token0825
,
token00BA
,
tlv
_0006_encr
)
class
ClientLoginResendPacket3106
(
qq
:
Long
,
password
:
String
,
loginTime
:
Int
,
loginIP
:
String
,
tgtgtKey
:
ByteArray
,
token0825
:
ByteArray
,
token00BA
:
ByteArray
,
tlv
0006
:
ByteArray
?
=
null
)
:
ClientLoginResendPacket
(
qq
,
password
,
loginTime
,
loginIP
,
tgtgtKey
,
token0825
,
token00BA
,
tlv
0006
)
@ExperimentalUnsignedTypes
open
class
ClientLoginResendPacket
internal
constructor
(
...
...
@@ -63,7 +63,7 @@ open class ClientLoginResendPacket internal constructor(
val
tgtgtKey
:
ByteArray
,
val
token0825
:
ByteArray
,
val
token00BA
:
ByteArray
,
val
tlv
_0006_encr
:
ByteArray
?
=
null
val
tlv
0006
:
ByteArray
?
=
null
)
:
ClientPacket
()
{
override
fun
encode
()
{
this
.
writeQQ
(
qq
)
...
...
@@ -74,7 +74,7 @@ open class ClientLoginResendPacket internal constructor(
this
.
write
(
TEA
.
encrypt
(
object
:
ByteArrayDataOutputStream
()
{
override
fun
toByteArray
():
ByteArray
{
this
.
writePart1
(
qq
,
password
,
loginTime
,
loginIP
,
tgtgtKey
,
token0825
,
tlv
_0006_encr
)
this
.
writePart1
(
qq
,
password
,
loginTime
,
loginIP
,
tgtgtKey
,
token0825
,
tlv
0006
)
this
.
writeHex
(
"01 10"
)
//tag
this
.
writeHex
(
"00 3C"
)
//length
...
...
@@ -94,7 +94,7 @@ open class ClientLoginResendPacket internal constructor(
* @author Him188moe
*/
@ExperimentalUnsignedTypes
private
fun
DataOutputStream
.
writePart1
(
qq
:
Long
,
password
:
String
,
loginTime
:
Int
,
loginIP
:
String
,
tgtgtKey
:
ByteArray
,
token0825
:
ByteArray
,
tlv
_0006_encr
:
ByteArray
?
=
null
)
{
private
fun
DataOutputStream
.
writePart1
(
qq
:
Long
,
password
:
String
,
loginTime
:
Int
,
loginIP
:
String
,
tgtgtKey
:
ByteArray
,
token0825
:
ByteArray
,
tlv
0006
:
ByteArray
?
=
null
)
{
//this.writeInt(System.currentTimeMillis().toInt())
this
.
writeHex
(
"01 12"
)
//tag
...
...
@@ -107,8 +107,8 @@ private fun DataOutputStream.writePart1(qq: Long, password: String, loginTime: I
this
.
writeQQ
(
qq
)
this
.
writeHex
(
"00 06"
)
//tag
this
.
writeHex
(
"00 78"
)
//length
if
(
tlv
_0006_encr
!=
null
)
{
this
.
write
(
tlv
_0006_encr
)
if
(
tlv
0006
!=
null
)
{
this
.
write
(
tlv
0006
)
}
else
{
this
.
writeTLV0006
(
qq
,
password
,
loginTime
,
loginIP
,
tgtgtKey
)
}
...
...
mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/LoginState.kt
View file @
7fb588be
...
...
@@ -7,7 +7,7 @@ enum class LoginState {
/**
* 登录成功
*/
SUCCE
ED
,
SUCCE
SS
,
/**
* 密码错误
...
...
mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ServerLoginResponse
Resend
Packet.kt
→
mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ServerLoginResponse
KeyExchange
Packet.kt
View file @
7fb588be
package
net.mamoe.mirai.network.packet.login
import
net.mamoe.mirai.network.Protocol
import
net.mamoe.mirai.network.packet.PacketId
import
net.mamoe.mirai.network.packet.ServerPacket
import
net.mamoe.mirai.network.packet.goto
...
...
@@ -7,16 +8,18 @@ import net.mamoe.mirai.utils.TestedSuccessfully
import
java.io.DataInputStream
/**
* 服务器进行加密后返回 tgtgtKey
*
* @author NaturalHG
*/
@PacketId
(
"08 36 31 03"
)
class
ServerLoginResponse
Resend
Packet
(
input
:
DataInputStream
,
val
flag
:
Flag
)
:
ServerPacket
(
input
)
{
class
ServerLoginResponse
KeyExchange
Packet
(
input
:
DataInputStream
,
val
flag
:
Flag
)
:
ServerPacket
(
input
)
{
enum
class
Flag
{
`
08
36
31
03
`
,
OTHER
,
}
lateinit
var
_0836_tlv0006_encr
:
ByteArray
;
//120bytes
lateinit
var
tlv0006
:
ByteArray
;
//120bytes
var
tokenUnknown
:
ByteArray
?
=
null
lateinit
var
tgtgtKey
:
ByteArray
//16bytes
...
...
@@ -26,7 +29,7 @@ class ServerLoginResponseResendPacket(input: DataInputStream, val flag: Flag) :
tgtgtKey
=
this
.
input
.
readNBytes
(
16
)
//22
//this.input.skip(2)//25
this
.
input
.
goto
(
25
)
_0836_tlv0006_encr
=
this
.
input
.
readNBytes
(
120
)
tlv0006
=
this
.
input
.
readNBytes
(
120
)
when
(
flag
)
{
Flag
.
`
08
36
31
03
`
->
{
...
...
@@ -43,7 +46,10 @@ class ServerLoginResponseResendPacket(input: DataInputStream, val flag: Flag) :
}
class
Encrypted
(
input
:
DataInputStream
,
private
val
flag
:
Flag
)
:
ServerPacket
(
input
)
{
@ExperimentalUnsignedTypes
@TestedSuccessfully
fun
decrypt
(
tgtgtKey
:
ByteArray
):
ServerLoginResponseResendPacket
=
ServerLoginResponseResendPacket
(
this
.
decryptBy
(
tgtgtKey
),
flag
).
setId
(
this
.
idHex
)
fun
decrypt
(
tgtgtKey
:
ByteArray
):
ServerLoginResponseKeyExchangePacket
{
return
ServerLoginResponseKeyExchangePacket
(
this
.
decryptBy
(
Protocol
.
shareKey
,
tgtgtKey
),
flag
).
setId
(
this
.
idHex
)
}
}
}
mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ServerLoginResponsePasswordVerifiedPacket.kt
View file @
7fb588be
package
net.mamoe.mirai.network.packet.login
import
net.mamoe.mirai.network.Protocol
import
net.mamoe.mirai.network.packet.*
import
net.mamoe.mirai.utils.TEA
import
net.mamoe.mirai.network.packet.ServerPacket
import
net.mamoe.mirai.network.packet.goto
import
net.mamoe.mirai.network.packet.readNBytesAt
import
net.mamoe.mirai.network.packet.readVarString
import
net.mamoe.mirai.utils.TestedSuccessfully
import
net.mamoe.mirai.utils.toUHexString
import
java.io.DataInputStream
...
...
@@ -53,7 +55,7 @@ class ServerLoginResponseSuccessPacket(input: DataInputStream) : ServerPacket(in
@ExperimentalUnsignedTypes
fun
decrypt
(
tgtgtKey
:
ByteArray
):
ServerLoginResponseSuccessPacket
{
input
goto
14
return
ServerLoginResponseSuccessPacket
(
TEA
.
decrypt
(
TEA
.
decrypt
(
input
.
readAllBytes
().
cutTail
(
1
),
Protocol
.
shareKey
),
tgtgtKey
).
dataInputStream
(
)).
setId
(
this
.
idHex
)
return
ServerLoginResponseSuccessPacket
(
this
.
decryptBy
(
Protocol
.
shareKey
,
tgtgtKey
)).
setId
(
this
.
idHex
)
}
}
...
...
mirai-core/src/main/java/net/mamoe/mirai/utils/TEA.java
View file @
7fb588be
...
...
@@ -17,6 +17,7 @@ public final class TEA {
private
static
final
long
UINT32_MASK
=
0xffffffff
L
;
private
final
long
[]
mKey
;
private
final
Random
mRandom
;
private
final
byte
[]
key
;
private
byte
[]
mOutput
;
private
byte
[]
mInBlock
;
private
int
mIndexPos
;
...
...
@@ -26,6 +27,7 @@ public final class TEA {
private
boolean
isFirstBlock
;
public
TEA
(
byte
[]
key
)
{
this
.
key
=
key
;
mKey
=
new
long
[
4
];
for
(
int
i
=
0
;
i
<
4
;
i
++)
{
mKey
[
i
]
=
pack
(
key
,
i
*
4
,
4
);
...
...
@@ -250,6 +252,12 @@ public final class TEA {
}
public
byte
[]
decrypt
(
byte
[]
ciphertext
)
{
return
decrypt
(
ciphertext
,
0
,
ciphertext
.
length
);
try
{
return
decrypt
(
ciphertext
,
0
,
ciphertext
.
length
);
}
catch
(
Exception
e
)
{
System
.
out
.
println
(
"Source: "
+
UtilsKt
.
toUHexString
(
ciphertext
,
" "
));
System
.
out
.
println
(
"Key: "
+
UtilsKt
.
toUHexString
(
this
.
key
,
" "
));
throw
e
;
}
}
}
\ No newline at end of file
mirai-core/src/test/java/BadQQFilter.kt
View file @
7fb588be
...
...
@@ -88,4 +88,3 @@ fun main() {
println
(
goodRobotList
.
joinToString
(
"\n"
)
{
it
.
account
.
qqNumber
.
toString
()
+
" "
+
it
.
account
.
password
})
}
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