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
e129719d
Commit
e129719d
authored
Sep 05, 2019
by
Him188moe
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Updated robot & network structure
parent
c353e8e8
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
450 additions
and
365 deletions
+450
-365
mirai-core/src/main/java/net/mamoe/mirai/contact/Group.kt
mirai-core/src/main/java/net/mamoe/mirai/contact/Group.kt
+1
-1
mirai-core/src/main/java/net/mamoe/mirai/contact/QQ.kt
mirai-core/src/main/java/net/mamoe/mirai/contact/QQ.kt
+1
-1
mirai-core/src/main/java/net/mamoe/mirai/network/Protocol.kt
mirai-core/src/main/java/net/mamoe/mirai/network/Protocol.kt
+68
-70
mirai-core/src/main/java/net/mamoe/mirai/network/RobotNetworkHandler.kt
.../main/java/net/mamoe/mirai/network/RobotNetworkHandler.kt
+359
-275
mirai-core/src/main/java/net/mamoe/mirai/network/packet/AccountInfo.kt
...c/main/java/net/mamoe/mirai/network/packet/AccountInfo.kt
+1
-0
mirai-core/src/main/java/net/mamoe/mirai/network/packet/ServerPacket.kt
.../main/java/net/mamoe/mirai/network/packet/ServerPacket.kt
+3
-12
mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/LoginState.kt
...n/java/net/mamoe/mirai/network/packet/login/LoginState.kt
+3
-1
mirai-core/src/main/java/net/mamoe/mirai/utils/TEA.java
mirai-core/src/main/java/net/mamoe/mirai/utils/TEA.java
+2
-3
mirai-core/src/main/java/net/mamoe/mirai/utils/Utils.kt
mirai-core/src/main/java/net/mamoe/mirai/utils/Utils.kt
+12
-2
No files found.
mirai-core/src/main/java/net/mamoe/mirai/contact/Group.kt
View file @
e129719d
...
@@ -10,7 +10,7 @@ class Group(robot: Robot, number: Long) : Contact(robot, number), Closeable {
...
@@ -10,7 +10,7 @@ class Group(robot: Robot, number: Long) : Contact(robot, number), Closeable {
val
members
=
ContactList
<
QQ
>()
val
members
=
ContactList
<
QQ
>()
override
fun
sendMessage
(
message
:
Message
)
{
override
fun
sendMessage
(
message
:
Message
)
{
robot
.
network
.
packetSystem
.
sendGroupMessage
(
this
,
message
)
robot
.
network
.
messageHandler
.
sendGroupMessage
(
this
,
message
)
}
}
override
fun
sendXMLMessage
(
message
:
String
)
{
override
fun
sendXMLMessage
(
message
:
String
)
{
...
...
mirai-core/src/main/java/net/mamoe/mirai/contact/QQ.kt
View file @
e129719d
...
@@ -12,7 +12,7 @@ import net.mamoe.mirai.message.defaults.At
...
@@ -12,7 +12,7 @@ import net.mamoe.mirai.message.defaults.At
*/
*/
class
QQ
(
robot
:
Robot
,
number
:
Long
)
:
Contact
(
robot
,
number
)
{
class
QQ
(
robot
:
Robot
,
number
:
Long
)
:
Contact
(
robot
,
number
)
{
override
fun
sendMessage
(
message
:
Message
)
{
override
fun
sendMessage
(
message
:
Message
)
{
robot
.
network
.
packetSystem
.
sendFriendMessage
(
this
,
message
)
robot
.
network
.
messageHandler
.
sendFriendMessage
(
this
,
message
)
}
}
override
fun
sendXMLMessage
(
message
:
String
)
{
override
fun
sendXMLMessage
(
message
:
String
)
{
...
...
mirai-core/src/main/java/net/mamoe/mirai/network/Protocol.kt
View file @
e129719d
...
@@ -7,9 +7,8 @@ import java.util.stream.Collectors
...
@@ -7,9 +7,8 @@ import java.util.stream.Collectors
/**
/**
* @author Him188moe
* @author Him188moe
*/
*/
interface
Protocol
{
object
Protocol
{
companion
object
{
val
SERVER_IP
:
List
<
String
>
=
object
:
ArrayList
<
String
>()
{
val
SERVER_IP
:
ArrayList
<
String
>
=
object
:
ArrayList
<
String
>()
{
init
{
init
{
add
(
"183.60.56.29"
)
add
(
"183.60.56.29"
)
...
@@ -25,7 +24,7 @@ interface Protocol {
...
@@ -25,7 +24,7 @@ interface Protocol {
}
}
}
}
get
()
=
Collections
.
unmodifiableList
(
field
)
const
val
head
=
"02"
const
val
head
=
"02"
const
val
ver
=
"37 13"
const
val
ver
=
"37 13"
...
@@ -90,5 +89,4 @@ interface Protocol {
...
@@ -90,5 +89,4 @@ interface Protocol {
.
map
{
s
->
s
.
toUByte
(
16
)
}
.
map
{
s
->
s
.
toUByte
(
16
)
}
.
collect
(
Collectors
.
toList
()).
toUByteArray
()
.
collect
(
Collectors
.
toList
()).
toUByteArray
()
}
}
}
mirai-core/src/main/java/net/mamoe/mirai/network/RobotNetworkHandler.kt
View file @
e129719d
...
@@ -11,15 +11,15 @@ import net.mamoe.mirai.network.packet.action.ServerSendFriendMessageResponsePack
...
@@ -11,15 +11,15 @@ import net.mamoe.mirai.network.packet.action.ServerSendFriendMessageResponsePack
import
net.mamoe.mirai.network.packet.action.ServerSendGroupMessageResponsePacket
import
net.mamoe.mirai.network.packet.action.ServerSendGroupMessageResponsePacket
import
net.mamoe.mirai.network.packet.login.*
import
net.mamoe.mirai.network.packet.login.*
import
net.mamoe.mirai.task.MiraiThreadPool
import
net.mamoe.mirai.task.MiraiThreadPool
import
net.mamoe.mirai.utils.ClientLoginStatus
import
net.mamoe.mirai.utils.*
import
net.mamoe.mirai.utils.MiraiLogger
import
net.mamoe.mirai.utils.getGTK
import
net.mamoe.mirai.utils.lazyEncode
import
java.io.Closeable
import
java.io.Closeable
import
java.net.DatagramPacket
import
java.net.DatagramPacket
import
java.net.DatagramSocket
import
java.net.DatagramSocket
import
java.net.InetSocketAddress
import
java.net.InetSocketAddress
import
java.util.*
import
java.util.concurrent.ScheduledFuture
import
java.util.concurrent.TimeUnit
import
java.util.concurrent.TimeUnit
import
kotlin.reflect.KClass
/**
/**
* A RobotNetworkHandler is used to connect with Tencent servers.
* A RobotNetworkHandler is used to connect with Tencent servers.
...
@@ -28,150 +28,230 @@ import java.util.concurrent.TimeUnit
...
@@ -28,150 +28,230 @@ import java.util.concurrent.TimeUnit
*/
*/
@Suppress
(
"EXPERIMENTAL_API_USAGE"
)
//to simplify code
@Suppress
(
"EXPERIMENTAL_API_USAGE"
)
//to simplify code
internal
class
RobotNetworkHandler
(
private
val
robot
:
Robot
)
:
Closeable
{
internal
class
RobotNetworkHandler
(
private
val
robot
:
Robot
)
:
Closeable
{
private
val
socketHandler
:
SocketHandler
=
SocketHandler
()
private
var
socket
:
DatagramSocket
=
DatagramSocket
((
15314
+
Math
.
random
()
*
100
).
toInt
())
val
debugHandler
=
DebugHandler
()
val
loginHandler
=
LoginHandler
()
val
messageHandler
=
MessageHandler
()
val
actionHandler
=
ActionHandler
()
private
var
serverIP
:
String
=
""
private
val
packetHandlers
:
Map
<
KClass
<
out
PacketHandler
>,
PacketHandler
>
=
mapOf
(
set
(
value
)
{
DebugHandler
::
class
to debug
Handler
,
serverAddress
=
InetSocketAddress
(
value
,
8000
)
LoginHandler
::
class
to login
Handler
,
field
=
value
MessageHandler
::
class
to message
Handler
,
ActionHandler
::
class
to action
Handler
)
restartSocket
()
}
private
lateinit
var
serverAddress
:
InetSocketAddress
private
var
closed
:
Boolean
=
false
private
var
closed
:
Boolean
=
false
private
lateinit
var
token00BA
:
ByteArray
//这些数据全部是login用的
private
lateinit
var
token0825
:
ByteArray
private
var
loginTime
:
Int
=
0
private
lateinit
var
loginIP
:
String
private
var
tgtgtKey
:
ByteArray
?
=
null
private
var
tlv0105
:
ByteArray
/**
* 0828_decr_key
*/
private
lateinit
var
sessionResponseDecryptionKey
:
ByteArray
private
var
verificationCodeSequence
:
Int
=
0
//这两个验证码使用
private
var
verificationCodeCache
:
ByteArray
?
=
null
//每次包只发一部分验证码来
private
var
verificationCodeCacheCount
:
Int
=
1
//
private
lateinit
var
verificationToken
:
ByteArray
private
lateinit
var
sessionKey
:
ByteArray
//这两个是登录成功后得到的
private
lateinit
var
sKey
:
String
/**
/**
*
Used to access web API(for friends list etc.)
*
Not async
*/
*/
private
lateinit
var
cookies
:
String
@ExperimentalUnsignedTypes
private
var
gtk
:
Int
=
0
fun
sendPacket
(
packet
:
ClientPacket
)
{
private
var
ignoreMessage
:
Boolean
=
false
socketHandler
.
sendPacket
(
packet
)
}
private
var
loginState
:
LoginState
?
=
null
override
fun
close
()
{
set
(
value
)
{
this
.
packetHandlers
.
values
.
forEach
{
field
=
value
it
.
close
()
if
(
value
!=
null
)
{
loginHook
?.
invoke
(
value
)
}
}
this
.
socketHandler
.
close
()
}
}
private
var
loginHook
:
((
LoginState
)
->
Unit
)?
=
null
init
{
//private | internal
tlv0105
=
lazyEncode
{
it
.
writeHex
(
"01 05 00 30"
)
internal
fun
tryLogin
(
loginHook
:
((
LoginState
)
->
Unit
)?
=
null
)
{
it
.
writeHex
(
"00 01 01 02 00 14 01 01 00 10"
)
val
ipQueue
:
LinkedList
<
String
>
=
LinkedList
(
Protocol
.
SERVER_IP
)
it
.
writeRandom
(
16
)
fun
login
():
Boolean
{
it
.
writeHex
(
"00 14 01 02 00 10"
)
val
ip
=
ipQueue
.
poll
()
it
.
writeRandom
(
16
)
return
if
(
ip
!=
null
)
{
this
@RobotNetworkHandler
.
socketHandler
.
touch
(
ip
)
{
state
->
if
(
state
==
LoginState
.
UNKNOWN
)
{
login
()
}
else
{
loginHook
?.
invoke
(
state
)
}
}
}
}
true
}
else
false
}
login
()
}
/**
@ExperimentalUnsignedTypes
* Try to login to server
internal
fun
onPacketReceived
(
packet
:
ServerPacket
)
{
*/
this
.
packetHandlers
.
values
.
forEach
{
internal
fun
tryLogin
(
loginHook
:
((
LoginState
)
->
Unit
)?
=
null
)
{
it
.
onPacketReceived
(
packet
)
//"14.116.136.106",
}
tryLogin
()
}
}
/**
* Try to login to server
*/
private
fun
tryLogin
(
serverAddress
:
String
,
loginHook
:
((
LoginState
)
->
Unit
)?
=
null
)
{
touch
(
serverAddress
,
loginHook
)
private
inner
class
SocketHandler
:
Closeable
{
private
lateinit
var
socket
:
DatagramSocket
internal
var
serverIP
:
String
=
""
set
(
value
)
{
serverAddress
=
InetSocketAddress
(
value
,
8000
)
field
=
value
restartSocket
()
}
}
/**
private
var
loginHook
:
((
LoginState
)
->
Unit
)?
=
null
* Start network
internal
var
loginState
:
LoginState
?
=
null
*/
set
(
value
)
{
private
fun
touch
(
serverAddress
:
String
,
loginHook
:
((
LoginState
)
->
Unit
)?
=
null
)
{
field
=
value
serverIP
=
serverAddress
if
(
value
!=
null
&&
value
!=
LoginState
.
UNKNOWN
)
{
if
(
loginHook
!=
null
)
{
loginHook
?.
invoke
(
value
)
this
.
loginHook
=
loginHook
}
}
this
.
sendPacket
(
ClientTouchPacket
(
this
.
robot
.
account
.
qqNumber
,
this
.
serverIP
))
}
}
private
lateinit
var
serverAddress
:
InetSocketAddress
private
fun
restartSocket
()
{
private
fun
restartSocket
()
{
socket
.
close
()
socket
=
DatagramSocket
((
15314
+
Math
.
random
()
*
100
).
toInt
())
socket
=
DatagramSocket
((
15314
+
Math
.
random
()
*
100
).
toInt
())
socket
.
close
()
socket
.
connect
(
this
.
serverAddress
)
socket
.
connect
(
this
.
serverAddress
)
val
zeroByte
:
Byte
=
0
Thread
{
Thread
{
while
(
true
)
{
while
(
socket
.
isConnected
)
{
val
dp1
=
DatagramPacket
(
ByteArray
(
2048
),
2048
)
val
packet
=
DatagramPacket
(
ByteArray
(
2048
),
2048
)
kotlin
.
runCatching
{
socket
.
receive
(
packet
)
}
.
onSuccess
{
MiraiThreadPool
.
getInstance
().
submit
{
try
{
try
{
socket
.
receive
(
dp1
)
onPacketReceived
(
ServerPacket
.
ofByteArray
(
packet
.
data
.
removeZeroTail
())
)
}
catch
(
e
:
Exception
)
{
}
catch
(
e
:
Exception
)
{
if
(
e
.
message
==
"socket closed"
)
{
e
.
printStackTrace
()
}
}
}.
onFailure
{
if
(
it
.
message
==
"socket closed"
)
{
if
(!
closed
)
{
if
(!
closed
)
{
restartSocket
()
restartSocket
()
}
}
return
@Thread
return
@Thread
}
}
it
.
printStackTrace
()
}
}
MiraiThreadPool
.
getInstance
().
submit
{
var
i
=
dp1
.
data
.
size
-
1
}
while
(
dp1
.
data
[
i
]
==
zeroByte
)
{
}.
start
()
--
i
}
/**
* Start network and touch the server
*/
internal
fun
touch
(
serverAddress
:
String
,
loginHook
:
((
LoginState
)
->
Unit
)?
=
null
)
{
socketHandler
.
serverIP
=
serverAddress
if
(
loginHook
!=
null
)
{
this
.
loginHook
=
loginHook
}
}
sendPacket
(
ClientTouchPacket
(
robot
.
account
.
qqNumber
,
socketHandler
.
serverIP
))
}
/**
* Not async
*/
@ExperimentalUnsignedTypes
internal
fun
sendPacket
(
packet
:
ClientPacket
)
{
try
{
try
{
onPacketReceived
(
ServerPacket
.
ofByteArray
(
dp1
.
data
.
copyOfRange
(
0
,
i
+
1
)))
packet
.
encode
()
}
catch
(
e
:
Exception
)
{
packet
.
writeHex
(
Protocol
.
tail
)
val
data
=
packet
.
toByteArray
()
socket
.
send
(
DatagramPacket
(
data
,
data
.
size
))
MiraiLogger
info
"Packet sent: $packet"
}
catch
(
e
:
Throwable
)
{
e
.
printStackTrace
()
e
.
printStackTrace
()
}
}
}
}
override
fun
close
()
{
this
.
socket
.
close
()
this
.
loginState
=
null
this
.
loginHook
=
null
}
}
}.
start
()
}
}
@ExperimentalUnsignedTypes
internal
fun
onPacketReceived
(
packet
:
ServerPacket
)
{
private
lateinit
var
sessionKey
:
ByteArray
abstract
inner
class
PacketHandler
:
Closeable
{
abstract
fun
onPacketReceived
(
packet
:
ServerPacket
)
override
fun
close
()
{
}
}
/**
* Kind of [PacketHandler] that prints all packets received in the format of hex byte array.
*/
inner
class
DebugHandler
:
PacketHandler
()
{
override
fun
onPacketReceived
(
packet
:
ServerPacket
)
{
packet
.
decode
()
packet
.
decode
()
MiraiLogger
info
"Packet received: $packet"
MiraiLogger
info
"Packet received: $packet"
if
(
packet
is
ServerEventPacket
)
{
if
(
packet
is
ServerEventPacket
)
{
sendPacket
(
ClientMessageResponsePacket
(
this
.
robot
.
account
.
qqNumber
,
packet
.
packetId
,
this
.
sessionKey
,
packet
.
eventIdentity
))
sendPacket
(
ClientMessageResponsePacket
(
robot
.
account
.
qqNumber
,
packet
.
packetId
,
sessionKey
,
packet
.
eventIdentity
))
}
}
}
}
/**
* 处理登录过程
*/
inner
class
LoginHandler
:
PacketHandler
()
{
private
lateinit
var
token00BA
:
ByteArray
private
lateinit
var
token0825
:
ByteArray
private
var
loginTime
:
Int
=
0
private
lateinit
var
loginIP
:
String
private
var
tgtgtKey
:
ByteArray
?
=
null
private
var
tlv0105
:
ByteArray
=
lazyEncode
{
it
.
writeHex
(
"01 05 00 30"
)
it
.
writeHex
(
"00 01 01 02 00 14 01 01 00 10"
)
it
.
writeRandom
(
16
)
it
.
writeHex
(
"00 14 01 02 00 10"
)
it
.
writeRandom
(
16
)
}
/**
* 0828_decr_key
*/
private
lateinit
var
sessionResponseDecryptionKey
:
ByteArray
private
var
verificationCodeSequence
:
Int
=
0
//这两个验证码使用
private
var
verificationCodeCache
:
ByteArray
?
=
null
//每次包只发一部分验证码来
private
var
verificationCodeCacheCount
:
Int
=
1
//
private
lateinit
var
verificationToken
:
ByteArray
private
var
heartbeatFuture
:
ScheduledFuture
<
*
>?
=
null
private
var
sKeyRefresherFuture
:
ScheduledFuture
<
*
>?
=
null
override
fun
onPacketReceived
(
packet
:
ServerPacket
)
{
when
(
packet
)
{
when
(
packet
)
{
is
ServerTouchResponsePacket
->
{
is
ServerTouchResponsePacket
->
{
if
(
packet
.
serverIP
!=
null
)
{
//redirection
if
(
packet
.
serverIP
!=
null
)
{
//redirection
serverIP
=
packet
.
serverIP
!!
socketHandler
.
serverIP
=
packet
.
serverIP
!!
//connect(packet.serverIP!!)
//connect(packet.serverIP!!)
sendPacket
(
ClientServerRedirectionPacket
(
packet
.
serverIP
!!
,
this
.
robot
.
account
.
qqNumber
))
sendPacket
(
ClientServerRedirectionPacket
(
packet
.
serverIP
!!
,
robot
.
account
.
qqNumber
))
}
else
{
//password submission
}
else
{
//password submission
this
.
loginIP
=
packet
.
loginIP
this
.
loginIP
=
packet
.
loginIP
this
.
loginTime
=
packet
.
loginTime
this
.
loginTime
=
packet
.
loginTime
this
.
token0825
=
packet
.
token0825
this
.
token0825
=
packet
.
token0825
this
.
tgtgtKey
=
packet
.
tgtgtKey
this
.
tgtgtKey
=
packet
.
tgtgtKey
sendPacket
(
ClientPasswordSubmissionPacket
(
this
.
robot
.
account
.
qqNumber
,
this
.
robot
.
account
.
password
,
packet
.
loginTime
,
packet
.
loginIP
,
packet
.
tgtgtKey
,
packet
.
token0825
))
sendPacket
(
ClientPasswordSubmissionPacket
(
robot
.
account
.
qqNumber
,
robot
.
account
.
password
,
packet
.
loginTime
,
packet
.
loginIP
,
packet
.
tgtgtKey
,
packet
.
token0825
))
}
}
}
}
is
ServerLoginResponseFailedPacket
->
{
is
ServerLoginResponseFailedPacket
->
{
this
.
loginState
=
packet
.
loginState
socketHandler
.
loginState
=
packet
.
loginState
MiraiLogger
error
"Login failed: "
+
packet
.
loginState
.
toString
()
MiraiLogger
error
"Login failed: "
+
packet
.
loginState
.
toString
()
return
return
}
}
...
@@ -181,18 +261,16 @@ internal class RobotNetworkHandler(private val robot: Robot) : Closeable {
...
@@ -181,18 +261,16 @@ internal class RobotNetworkHandler(private val robot: Robot) : Closeable {
this
.
token00BA
=
packet
.
token00BA
this
.
token00BA
=
packet
.
token00BA
this
.
verificationCodeCache
=
packet
.
verifyCodePart1
this
.
verificationCodeCache
=
packet
.
verifyCodePart1
if
(
packet
.
unknownBoolean
!=
null
&&
packet
.
unknownBoolean
!!
)
{
if
(
packet
.
unknownBoolean
!=
null
&&
packet
.
unknownBoolean
!!
)
{
this
.
verificationCodeSequence
=
1
this
.
verificationCodeSequence
=
1
sendPacket
(
ClientVerificationCodeTransmissionRequestPacket
(
1
,
this
.
robot
.
account
.
qqNumber
,
this
.
token0825
,
this
.
verificationCodeSequence
,
this
.
token00BA
))
sendPacket
(
ClientVerificationCodeTransmissionRequestPacket
(
1
,
robot
.
account
.
qqNumber
,
this
.
token0825
,
this
.
verificationCodeSequence
,
this
.
token00BA
))
}
}
}
}
is
ServerVerificationCodeRepeatPacket
->
{
//todo 这个名字正确么
is
ServerVerificationCodeRepeatPacket
->
{
//todo 这个名字正确么
this
.
tgtgtKey
=
packet
.
tgtgtKeyUpdate
this
.
tgtgtKey
=
packet
.
tgtgtKeyUpdate
this
.
token00BA
=
packet
.
token00BA
this
.
token00BA
=
packet
.
token00BA
sendPacket
(
ClientLoginResendPacket3105
(
this
.
robot
.
account
.
qqNumber
,
this
.
robot
.
account
.
password
,
this
.
loginTime
,
this
.
loginIP
,
this
.
tgtgtKey
!!
,
this
.
token0825
,
this
.
token00BA
))
sendPacket
(
ClientLoginResendPacket3105
(
robot
.
account
.
qqNumber
,
robot
.
account
.
password
,
this
.
loginTime
,
this
.
loginIP
,
this
.
tgtgtKey
!!
,
this
.
token0825
,
this
.
token00BA
))
}
}
is
ServerVerificationCodeTransmissionPacket
->
{
is
ServerVerificationCodeTransmissionPacket
->
{
...
@@ -207,18 +285,17 @@ internal class RobotNetworkHandler(private val robot: Robot) : Closeable {
...
@@ -207,18 +285,17 @@ internal class RobotNetworkHandler(private val robot: Robot) : Closeable {
//todo 看易语言 count 和 sequence 是怎样变化的
//todo 看易语言 count 和 sequence 是怎样变化的
if
(
packet
.
transmissionCompleted
)
{
if
(
packet
.
transmissionCompleted
)
{
this
.
verificationCodeCache
this
.
verificationCodeCache
TODO
(
"验证码好了"
)
TODO
(
"验证码好了"
)
}
else
{
}
else
{
sendPacket
(
ClientVerificationCodeTransmissionRequestPacket
(
this
.
verificationCodeCacheCount
,
this
.
robot
.
account
.
qqNumber
,
this
.
token0825
,
this
.
verificationCodeSequence
,
this
.
token00BA
))
sendPacket
(
ClientVerificationCodeTransmissionRequestPacket
(
this
.
verificationCodeCacheCount
,
robot
.
account
.
qqNumber
,
this
.
token0825
,
this
.
verificationCodeSequence
,
this
.
token00BA
))
}
}
}
}
is
ServerLoginResponseSuccessPacket
->
{
is
ServerLoginResponseSuccessPacket
->
{
this
.
sessionResponseDecryptionKey
=
packet
.
sessionResponseDecryptionKey
this
.
sessionResponseDecryptionKey
=
packet
.
sessionResponseDecryptionKey
sendPacket
(
ClientSessionRequestPacket
(
this
.
robot
.
account
.
qqNumber
,
this
.
serverIP
,
packet
.
token38
,
packet
.
token88
,
packet
.
encryptionKey
,
this
.
tlv0105
))
sendPacket
(
ClientSessionRequestPacket
(
robot
.
account
.
qqNumber
,
socketHandler
.
serverIP
,
packet
.
token38
,
packet
.
token88
,
packet
.
encryptionKey
,
this
.
tlv0105
))
}
}
//是ClientPasswordSubmissionPacket之后服务器回复的
//是ClientPasswordSubmissionPacket之后服务器回复的
...
@@ -230,8 +307,8 @@ internal class RobotNetworkHandler(private val robot: Robot) : Closeable {
...
@@ -230,8 +307,8 @@ internal class RobotNetworkHandler(private val robot: Robot) : Closeable {
if
(
packet
.
flag
==
ServerLoginResponseResendPacket
.
Flag
.
`
08
36
31
03
`
)
{
if
(
packet
.
flag
==
ServerLoginResponseResendPacket
.
Flag
.
`
08
36
31
03
`
)
{
this
.
tgtgtKey
=
packet
.
tgtgtKey
this
.
tgtgtKey
=
packet
.
tgtgtKey
sendPacket
(
ClientLoginResendPacket3104
(
sendPacket
(
ClientLoginResendPacket3104
(
this
.
robot
.
account
.
qqNumber
,
robot
.
account
.
qqNumber
,
this
.
robot
.
account
.
password
,
robot
.
account
.
password
,
this
.
loginTime
,
this
.
loginTime
,
this
.
loginIP
,
this
.
loginIP
,
this
.
tgtgtKey
!!
,
this
.
tgtgtKey
!!
,
...
@@ -244,8 +321,8 @@ internal class RobotNetworkHandler(private val robot: Robot) : Closeable {
...
@@ -244,8 +321,8 @@ internal class RobotNetworkHandler(private val robot: Robot) : Closeable {
))
))
}
else
{
}
else
{
sendPacket
(
ClientLoginResendPacket3106
(
sendPacket
(
ClientLoginResendPacket3106
(
this
.
robot
.
account
.
qqNumber
,
robot
.
account
.
qqNumber
,
this
.
robot
.
account
.
password
,
robot
.
account
.
password
,
this
.
loginTime
,
this
.
loginTime
,
this
.
loginIP
,
this
.
loginIP
,
this
.
tgtgtKey
!!
,
this
.
tgtgtKey
!!
,
...
@@ -259,98 +336,113 @@ internal class RobotNetworkHandler(private val robot: Robot) : Closeable {
...
@@ -259,98 +336,113 @@ internal class RobotNetworkHandler(private val robot: Robot) : Closeable {
}
}
}
}
is
ServerSessionKeyResponsePacket
->
{
is
ServerSessionKeyResponsePacket
->
{
this
.
sessionKey
=
packet
.
sessionKey
sessionKey
=
packet
.
sessionKey
MiraiThreadPool
.
getInstance
().
scheduleWithFixedDelay
({
heartbeatFuture
=
MiraiThreadPool
.
getInstance
().
scheduleWithFixedDelay
({
sendPacket
(
ClientHeartbeatPacket
(
this
.
robot
.
account
.
qqNumber
,
this
.
sessionKey
))
sendPacket
(
ClientHeartbeatPacket
(
robot
.
account
.
qqNumber
,
sessionKey
))
},
90000
,
90000
,
TimeUnit
.
MILLISECONDS
)
},
90000
,
90000
,
TimeUnit
.
MILLISECONDS
)
RobotLoginSucceedEvent
(
robot
).
broadcast
()
RobotLoginSucceedEvent
(
robot
).
broadcast
()
//登录成功后会收到大量上次的消息, 忽略掉
MiraiThreadPool
.
getInstance
().
schedule
({
MiraiThreadPool
.
getInstance
().
schedule
({
ignoreMessage
=
false
(
packetHandlers
[
MessageHandler
::
class
]
as
MessageHandler
).
ignoreMessage
=
false
},
2
,
TimeUnit
.
SECONDS
)
},
2
,
TimeUnit
.
SECONDS
)
this
.
tlv0105
=
packet
.
tlv0105
this
.
tlv0105
=
packet
.
tlv0105
sendPacket
(
ClientChangeOnlineStatusPacket
(
this
.
robot
.
account
.
qqNumber
,
this
.
sessionKey
,
ClientLoginStatus
.
ONLINE
))
sendPacket
(
ClientChangeOnlineStatusPacket
(
robot
.
account
.
qqNumber
,
sessionKey
,
ClientLoginStatus
.
ONLINE
))
}
}
is
ServerLoginSuccessPacket
->
{
is
ServerLoginSuccessPacket
->
{
loginState
=
LoginState
.
SUCCEED
socketHandler
.
loginState
=
LoginState
.
SUCCEED
sendPacket
(
ClientSKeyRequestPacket
(
this
.
robot
.
account
.
qqNumber
,
this
.
sessionKey
))
sendPacket
(
ClientSKeyRequestPacket
(
robot
.
account
.
qqNumber
,
sessionKey
))
}
}
is
ServerSKeyResponsePacket
->
{
is
ServerSKeyResponsePacket
->
{
this
.
sKey
=
packet
.
sKey
val
actionHandler
=
packetHandlers
[
ActionHandler
::
class
]
as
ActionHandler
this
.
cookies
=
"uin=o"
+
this
.
robot
.
account
.
qqNumber
+
";skey="
+
this
.
sKey
+
";"
actionHandler
.
sKey
=
packet
.
sKey
actionHandler
.
cookies
=
"uin=o"
+
robot
.
account
.
qqNumber
+
";skey="
+
actionHandler
.
sKey
+
";"
MiraiThreadPool
.
getInstance
().
scheduleWithFixedDelay
({
sKeyRefresherFuture
=
MiraiThreadPool
.
getInstance
().
scheduleWithFixedDelay
({
sendPacket
(
ClientSKeyRefreshmentRequestPacket
(
this
.
robot
.
account
.
qqNumber
,
this
.
sessionKey
))
sendPacket
(
ClientSKeyRefreshmentRequestPacket
(
robot
.
account
.
qqNumber
,
sessionKey
))
},
1800000
,
1800000
,
TimeUnit
.
MILLISECONDS
)
},
1800000
,
1800000
,
TimeUnit
.
MILLISECONDS
)
this
.
gtk
=
getGTK
(
sKey
)
actionHandler
.
gtk
=
getGTK
(
actionHandler
.
sKey
)
sendPacket
(
ClientAccountInfoRequestPacket
(
this
.
robot
.
account
.
qqNumber
,
this
.
sessionKey
))
sendPacket
(
ClientAccountInfoRequestPacket
(
robot
.
account
.
qqNumber
,
sessionKey
))
}
}
is
ServerHeartbeatResponsePacket
->
{
is
ServerEventPacket
.
Raw
->
onPacketReceived
(
packet
.
distribute
())
}
is
ServerVerificationCodePacket
.
Encrypted
->
onPacketReceived
(
packet
.
decrypt
())
is
ServerLoginResponseVerificationCodeInitPacket
.
Encrypted
->
onPacketReceived
(
packet
.
decrypt
())
is
ServerLoginResponseResendPacket
.
Encrypted
->
onPacketReceived
(
packet
.
decrypt
(
this
.
tgtgtKey
!!
))
is
ServerLoginResponseSuccessPacket
.
Encrypted
->
onPacketReceived
(
packet
.
decrypt
(
this
.
tgtgtKey
!!
))
is
ServerSessionKeyResponsePacket
.
Encrypted
->
onPacketReceived
(
packet
.
decrypt
(
this
.
sessionResponseDecryptionKey
))
is
ServerTouchResponsePacket
.
Encrypted
->
onPacketReceived
(
packet
.
decrypt
())
is
ServerSKeyResponsePacket
.
Encrypted
->
onPacketReceived
(
packet
.
decrypt
(
sessionKey
))
is
ServerAccountInfoResponsePacket
.
Encrypted
->
onPacketReceived
(
packet
.
decrypt
(
sessionKey
))
is
ServerEventPacket
.
Raw
.
Encrypted
->
onPacketReceived
(
packet
.
decrypt
(
sessionKey
))
is
ServerAccountInfoResponsePacket
->
{
is
ServerAccountInfoResponsePacket
,
is
ServerHeartbeatResponsePacket
,
is
UnknownServerPacket
->
{
//ignored
}
}
else
->
{
is
ServerFriendMessageEventPacket
->
{
if
(
ignoreMessage
)
{
return
}
}
FriendMessageEvent
(
this
.
robot
,
this
.
robot
.
contacts
.
getQQ
(
packet
.
qq
),
packet
.
message
)
}
}
is
ServerGroupMessageEventPacket
->
{
//todo message chain
//GroupMessageEvent(this.robot, this.robot.contacts.getGroupByNumber(packet.groupNumber), this.robot.contacts.getQQ(packet.qq), packet.message)
}
}
is
UnknownServerEventPacket
->
{
override
fun
close
()
{
//unknown message event
this
.
verificationCodeCache
=
null
}
this
.
tgtgtKey
=
null
is
UnknownServerPacket
->
{
this
.
heartbeatFuture
?.
cancel
(
true
)
this
.
sKeyRefresherFuture
?.
cancel
(
true
)
this
.
heartbeatFuture
=
null
this
.
sKeyRefresherFuture
=
null
}
}
}
is
ServerGroupUploadFileEventPacket
->
{
/**
* 处理消息事件, 承担消息发送任务.
*/
inner
class
MessageHandler
:
PacketHandler
()
{
internal
var
ignoreMessage
:
Boolean
=
false
override
fun
onPacketReceived
(
packet
:
ServerPacket
)
{
when
(
packet
)
{
is
ServerGroupUploadFileEventPacket
->
{
//todo
}
}
is
ServerEventPacket
.
Raw
->
onPacketReceived
(
packet
.
distribute
())
is
ServerFriendMessageEventPacket
->
{
if
(
ignoreMessage
)
{
return
}
is
ServerVerificationCodePacket
.
Encrypted
->
onPacketReceived
(
packet
.
decrypt
())
FriendMessageEvent
(
robot
,
robot
.
contacts
.
getQQ
(
packet
.
qq
),
packet
.
message
)
is
ServerLoginResponseVerificationCodeInitPacket
.
Encrypted
->
onPacketReceived
(
packet
.
decrypt
())
}
is
ServerLoginResponseResendPacket
.
Encrypted
->
onPacketReceived
(
packet
.
decrypt
(
this
.
tgtgtKey
!!
))
is
ServerLoginResponseSuccessPacket
.
Encrypted
->
onPacketReceived
(
packet
.
decrypt
(
this
.
tgtgtKey
!!
))
is
ServerSessionKeyResponsePacket
.
Encrypted
->
onPacketReceived
(
packet
.
decrypt
(
this
.
sessionResponseDecryptionKey
))
is
ServerTouchResponsePacket
.
Encrypted
->
onPacketReceived
(
packet
.
decrypt
())
is
ServerSKeyResponsePacket
.
Encrypted
->
onPacketReceived
(
packet
.
decrypt
(
this
.
sessionKey
))
is
ServerAccountInfoResponsePacket
.
Encrypted
->
onPacketReceived
(
packet
.
decrypt
(
this
.
sessionKey
))
is
ServerEventPacket
.
Raw
.
Encrypted
->
onPacketReceived
(
packet
.
decrypt
(
this
.
sessionKey
))
is
ServerGroupMessageEventPacket
->
{
//todo message chain
//GroupMessageEvent(this.robot, robot.contacts.getGroupByNumber(packet.groupNumber), robot.contacts.getQQ(packet.qq), packet.message)
}
is
UnknownServerEventPacket
,
is
ServerSendFriendMessageResponsePacket
,
is
ServerSendFriendMessageResponsePacket
,
is
ServerSendGroupMessageResponsePacket
->
{
is
ServerSendGroupMessageResponsePacket
->
{
//ignored
}
else
->
{
//ignored
}
}
else
->
throw
IllegalArgumentException
(
packet
.
toString
())
}
}
}
}
internal
val
packetSystem
:
PacketSystem
=
PacketSystem
()
inner
class
PacketSystem
{
fun
sendFriendMessage
(
qq
:
QQ
,
message
:
Message
)
{
fun
sendFriendMessage
(
qq
:
QQ
,
message
:
Message
)
{
TODO
()
TODO
()
//sendPacket(ClientSendFriendMessagePacket(robot.account.qqNumber, qq.number, sessionKey, message))
//sendPacket(ClientSendFriendMessagePacket(robot.account.qqNumber, qq.number, sessionKey, message))
...
@@ -360,31 +452,23 @@ internal class RobotNetworkHandler(private val robot: Robot) : Closeable {
...
@@ -360,31 +452,23 @@ internal class RobotNetworkHandler(private val robot: Robot) : Closeable {
TODO
()
TODO
()
//sendPacket(ClientSendGroupMessagePacket(group.groupId, robot.account.qqNumber, sessionKey, message))
//sendPacket(ClientSendGroupMessagePacket(group.groupId, robot.account.qqNumber, sessionKey, message))
}
}
}
}
/**
/**
* Not async
* 动作: 获取好友列表, 点赞, 踢人等.
* 处理动作事件, 承担动作任务.
*/
*/
@ExperimentalUnsignedTypes
inner
class
ActionHandler
:
PacketHandler
()
{
fun
sendPacket
(
packet
:
ClientPacket
)
{
internal
lateinit
var
cookies
:
String
try
{
internal
lateinit
var
sKey
:
String
packet
.
encode
()
internal
var
gtk
:
Int
=
0
packet
.
writeHex
(
Protocol
.
tail
)
override
fun
onPacketReceived
(
packet
:
ServerPacket
)
{
val
data
=
packet
.
toByteArray
()
socket
.
send
(
DatagramPacket
(
data
,
data
.
size
))
MiraiLogger
info
"Packet sent: $packet"
}
catch
(
e
:
Throwable
)
{
e
.
printStackTrace
()
}
}
}
override
fun
close
()
{
override
fun
close
()
{
this
.
socket
.
close
()
this
.
loginState
=
null
}
this
.
loginHook
=
null
this
.
verificationCodeCache
=
null
this
.
tgtgtKey
=
null
}
}
}
}
\ No newline at end of file
mirai-core/src/main/java/net/mamoe/mirai/network/packet/AccountInfo.kt
View file @
e129719d
...
@@ -17,6 +17,7 @@ class ClientAccountInfoRequestPacket(
...
@@ -17,6 +17,7 @@ class ClientAccountInfoRequestPacket(
)
:
ClientPacket
()
{
)
:
ClientPacket
()
{
override
fun
encode
()
{
override
fun
encode
()
{
this
.
writeRandom
(
2
)
//part of packet id
this
.
writeRandom
(
2
)
//part of packet id
this
.
writeQQ
(
qq
)
this
.
writeQQ
(
qq
)
this
.
writeHex
(
Protocol
.
fixVer2
)
this
.
writeHex
(
Protocol
.
fixVer2
)
this
.
encryptAndWrite
(
sessionKey
)
{
this
.
encryptAndWrite
(
sessionKey
)
{
...
...
mirai-core/src/main/java/net/mamoe/mirai/network/packet/ServerPacket.kt
View file @
e129719d
...
@@ -53,11 +53,13 @@ abstract class ServerPacket(val input: DataInputStream) : Packet {
...
@@ -53,11 +53,13 @@ abstract class ServerPacket(val input: DataInputStream) : Packet {
551
,
487
->
LoginState
.
DEVICE_LOCK
551
,
487
->
LoginState
.
DEVICE_LOCK
359
->
LoginState
.
TAKEN_BACK
359
->
LoginState
.
TAKEN_BACK
else
->
LoginState
.
UNKNOWN
/*
//unknown
//unknown
63 -> throw IllegalArgumentException(bytes.size.toString() + " (Unknown error)")
63 -> throw IllegalArgumentException(bytes.size.toString() + " (Unknown error)")
351 -> throw IllegalArgumentException(bytes.size.toString() + " (Illegal package data or Unknown error)")//包数据有误
351 -> throw IllegalArgumentException(bytes.size.toString() + " (Illegal package data or Unknown error)")//包数据有误
else
->
throw
IllegalArgumentException
(
bytes
.
size
.
toString
())
else -> throw IllegalArgumentException(bytes.size.toString())
*/
},
stream
)
},
stream
)
}
}
...
@@ -112,17 +114,6 @@ abstract class ServerPacket(val input: DataInputStream) : Packet {
...
@@ -112,17 +114,6 @@ abstract class ServerPacket(val input: DataInputStream) : Packet {
}
}
fun
DataInputStream
.
readUntil
(
byte
:
Byte
):
ByteArray
{
var
buff
=
byteArrayOf
()
var
b
:
Byte
b
=
readByte
()
while
(
b
!=
byte
)
{
buff
+=
b
b
=
readByte
()
}
return
buff
}
@ExperimentalUnsignedTypes
@ExperimentalUnsignedTypes
fun
DataInputStream
.
readIP
():
String
{
fun
DataInputStream
.
readIP
():
String
{
var
buff
=
""
var
buff
=
""
...
...
mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/LoginState.kt
View file @
e129719d
...
@@ -14,5 +14,7 @@ enum class LoginState {
...
@@ -14,5 +14,7 @@ enum class LoginState {
DEVICE_LOCK
,
//设备锁
DEVICE_LOCK
,
//设备锁
TAKEN_BACK
,
//被回收
TAKEN_BACK
,
//被回收
// VERIFICATION_CODE,//需要验证码
// VERIFICATION_CODE,//需要验证码
// SUCCEED,
UNKNOWN
,
}
}
\ No newline at end of file
mirai-core/src/main/java/net/mamoe/mirai/utils/TEA.java
View file @
e129719d
...
@@ -11,9 +11,8 @@ import java.util.Random;
...
@@ -11,9 +11,8 @@ import java.util.Random;
* @author iweiz https://github.com/iweizime/StepChanger/blob/master/app/src/main/java/me/iweizi/stepchanger/qq/Cryptor.java
* @author iweiz https://github.com/iweizime/StepChanger/blob/master/app/src/main/java/me/iweizi/stepchanger/qq/Cryptor.java
*/
*/
public
final
class
TEA
{
public
final
class
TEA
{
public
static
final
TEA
CRYPTOR_SHARE_KEY
=
new
TEA
(
Protocol
.
Companion
.
hexToBytes
(
Protocol
.
shareKey
));
public
static
final
TEA
CRYPTOR_SHARE_KEY
=
new
TEA
(
Protocol
.
INSTANCE
.
hexToBytes
(
Protocol
.
shareKey
));
public
static
final
TEA
CRYPTOR_0825KEY
=
new
TEA
(
Protocol
.
Companion
.
hexToBytes
(
Protocol
.
key0825
));
public
static
final
TEA
CRYPTOR_0825KEY
=
new
TEA
(
Protocol
.
INSTANCE
.
hexToBytes
(
Protocol
.
key0825
));
public
static
final
TEA
CRYPTOR_00BAKEY
=
new
TEA
(
Protocol
.
Companion
.
hexToBytes
(
Protocol
.
key00BA
));
private
static
final
long
UINT32_MASK
=
0xffffffff
L
;
private
static
final
long
UINT32_MASK
=
0xffffffff
L
;
private
final
long
[]
mKey
;
private
final
long
[]
mKey
;
...
...
mirai-core/src/main/java/net/mamoe/mirai/utils/Utils.kt
View file @
e129719d
...
@@ -79,7 +79,7 @@ operator fun File.plus(child: String): File = File(this, child)
...
@@ -79,7 +79,7 @@ operator fun File.plus(child: String): File = File(this, child)
private
const
val
GTK_BASE_VALUE
:
Int
=
5381
private
const
val
GTK_BASE_VALUE
:
Int
=
5381
fun
getGTK
(
sKey
:
String
):
Int
{
internal
fun
getGTK
(
sKey
:
String
):
Int
{
var
value
=
GTK_BASE_VALUE
var
value
=
GTK_BASE_VALUE
for
(
c
in
sKey
.
toCharArray
())
{
for
(
c
in
sKey
.
toCharArray
())
{
value
+=
(
value
shl
5
)
+
c
.
toInt
()
value
+=
(
value
shl
5
)
+
c
.
toInt
()
...
@@ -89,7 +89,7 @@ fun getGTK(sKey: String): Int {
...
@@ -89,7 +89,7 @@ fun getGTK(sKey: String): Int {
return
value
return
value
}
}
fun
getCrc32
(
key
:
ByteArray
):
Int
=
CRC32
().
let
{
it
.
update
(
key
);
it
.
value
.
toInt
()
}
internal
fun
getCrc32
(
key
:
ByteArray
):
Int
=
CRC32
().
let
{
it
.
update
(
key
);
it
.
value
.
toInt
()
}
/**
/**
...
@@ -122,3 +122,13 @@ fun Any.getAllDeclaredFields(): List<Field> {
...
@@ -122,3 +122,13 @@ fun Any.getAllDeclaredFields(): List<Field> {
return
list
return
list
}
}
private
const
val
ZERO_BYTE
:
Byte
=
0
fun
ByteArray
.
removeZeroTail
():
ByteArray
{
var
i
=
this
.
size
-
1
while
(
this
[
i
]
==
ZERO_BYTE
)
{
--
i
}
return
this
.
copyOfRange
(
0
,
i
+
1
)
}
\ No newline at end of file
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