diff --git a/mirai-core/src/main/java/net/mamoe/mirai/MiraiServer.java b/mirai-core/src/main/java/net/mamoe/mirai/MiraiServer.java
index 1b654f688..7d91d7c15 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/MiraiServer.java
+++ b/mirai-core/src/main/java/net/mamoe/mirai/MiraiServer.java
@@ -21,9 +21,12 @@ import java.util.LinkedList;
 import java.util.Scanner;
 
 public class MiraiServer {
-    @Getter
     private static MiraiServer instance;
 
+    public static MiraiServer getInstance() {
+        return instance;
+    }
+
     //mirai version
     private final static String MIRAI_VERSION = "1.0.0";
 
@@ -35,7 +38,7 @@ public class MiraiServer {
     private boolean unix;
 
     @Getter//file path
-    private File parentFolder;
+    public File parentFolder;
 
     @Getter
     MiraiEventManager eventManager;
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/RobotNetworkHandler.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/RobotNetworkHandler.kt
index 6844f0957..17f4129b2 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/network/RobotNetworkHandler.kt
+++ b/mirai-core/src/main/java/net/mamoe/mirai/network/RobotNetworkHandler.kt
@@ -1,18 +1,24 @@
 package net.mamoe.mirai.network
 
 import io.netty.channel.Channel
+import net.mamoe.mirai.MiraiServer
 import net.mamoe.mirai.network.packet.client.ClientPacket
 import net.mamoe.mirai.network.packet.client.login.*
+import net.mamoe.mirai.network.packet.client.session.ClientHandshake1Packet
+import net.mamoe.mirai.network.packet.client.session.ClientLoginStatusPacket
+import net.mamoe.mirai.network.packet.client.session.ClientSKeyRequestPacket
 import net.mamoe.mirai.network.packet.client.writeHex
 import net.mamoe.mirai.network.packet.client.writeRandom
 import net.mamoe.mirai.network.packet.server.ServerPacket
 import net.mamoe.mirai.network.packet.server.login.*
-import net.mamoe.mirai.network.packet.server.security.ServerSessionKeyResponsePacket
-import net.mamoe.mirai.network.packet.server.security.ServerSessionKeyResponsePacketEncrypted
+import net.mamoe.mirai.network.packet.server.security.*
 import net.mamoe.mirai.network.packet.server.touch.ServerTouchResponsePacket
 import net.mamoe.mirai.network.packet.server.touch.ServerTouchResponsePacketEncrypted
+import net.mamoe.mirai.task.MiraiTaskManager
 import net.mamoe.mirai.util.*
 import net.mamoe.mirai.utils.MiraiLogger
+import java.io.ByteArrayInputStream
+import java.io.FileOutputStream
 import java.net.DatagramPacket
 import java.net.DatagramSocket
 import java.net.InetSocketAddress
@@ -24,6 +30,7 @@ import java.util.*
  * @author Him188moe
  */
 class RobotNetworkHandler(val number: Int, private val password: String) {
+
     private var sequence: Int = 0
 
     private var channel: Channel? = null
@@ -36,16 +43,23 @@ class RobotNetworkHandler(val number: Int, private val password: String) {
 
     private lateinit var serverAddress: InetSocketAddress
 
-    private lateinit var token00BA: ByteArray
+    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
+    private lateinit var _0828_rec_decr_key: ByteArray
+
+
+    private lateinit var sessionKey: ByteArray//这两个是登录成功后得到的
+    private lateinit var sKey: String
 
     /**
-     * Kind of key, similar to sessionKey
+     * Used to access web API(for friends list etc.)
      */
-    private var tlv0105: ByteArray
+    private lateinit var cookies: String
+    private var gtk: Int = 0
 
     init {
         tlv0105 = lazyEncode {
@@ -57,11 +71,6 @@ class RobotNetworkHandler(val number: Int, private val password: String) {
         }
     }
 
-    private lateinit var sessionKey: ByteArray
-    /**
-     * Kind of key, similar to sessionKey
-     */
-    private lateinit var _0828_rec_decr_key: ByteArray
 
     @ExperimentalUnsignedTypes
     private var md5_32: ByteArray = getRandomKey(32)
@@ -100,6 +109,12 @@ class RobotNetworkHandler(val number: Int, private val password: String) {
                     sendPacket(ClientLoginVerificationCodePacket(this.number, this.token0825, this.sequence, this.token00BA))
                 }
 
+                with(MiraiServer.getInstance().parentFolder + "verifyCode.png") {
+                    ByteArrayInputStream(packet.verifyCode).transferTo(FileOutputStream(this))
+                    println("验证码已写入到 " + this.path)
+                }
+
+
             }
 
             is ServerLoginResponseSuccessPacket -> {
@@ -148,12 +163,30 @@ class RobotNetworkHandler(val number: Int, private val password: String) {
             is ServerSessionKeyResponsePacket -> {
                 this.sessionKey = packet.sessionKey
                 this.tlv0105 = packet.tlv0105
+                sendPacket(ClientLoginStatusPacket(this.number, sessionKey, ClientLoginStatus.ONLINE))
             }
 
+            is ServerLoginSuccessPacket -> {
+                sendPacket(ClientSKeyRequestPacket(this.number, this.sessionKey))
+            }
+
+            is ServerSKeyResponsePacket -> {
+                this.sKey = packet.sKey
+                this.cookies = "uin=o" + this.number + ";skey=" + this.sKey + ";"
+
+                MiraiTaskManager.getInstance().repeatingTask({
+                    TODO("时钟_refreshSkey")
+                }, 1800000)
+                this.gtk = getGTK(sKey)
+                sendPacket(ClientHandshake1Packet(this.number, this.sessionKey))
+            }
+
+            is ServerLoginResponseVerificationCodePacketEncrypted -> onPacketReceived(packet.decrypt())
             is ServerLoginResponseResendPacketEncrypted -> onPacketReceived(packet.decrypt(this.tgtgtKey!!))
             is ServerLoginResponseSuccessPacketEncrypted -> onPacketReceived(packet.decrypt(this.tgtgtKey!!))
             is ServerSessionKeyResponsePacketEncrypted -> onPacketReceived(packet.decrypt(this._0828_rec_decr_key))
             is ServerTouchResponsePacketEncrypted -> onPacketReceived(packet.decrypt())
+            is ServerSKeyResponsePacketEncrypted -> onPacketReceived(packet.decrypt(this.sessionKey))
 
             else -> throw IllegalArgumentException(packet.toString())
         }
@@ -328,3 +361,4 @@ private lateinit var ctx: ChannelHandlerContext
         }
     }*/
 }
+
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/session/ClientLoginStatusPacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/session/ClientLoginStatusPacket.kt
new file mode 100644
index 000000000..c3b94b626
--- /dev/null
+++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/session/ClientLoginStatusPacket.kt
@@ -0,0 +1,29 @@
+package net.mamoe.mirai.network.packet.client.session
+
+import net.mamoe.mirai.network.Protocol
+import net.mamoe.mirai.network.packet.PacketId
+import net.mamoe.mirai.network.packet.client.*
+import net.mamoe.mirai.util.ClientLoginStatus
+
+/**
+ * @author Him188moe
+ */
+@ExperimentalUnsignedTypes
+@PacketId("00 EC")
+class ClientLoginStatusPacket(
+        private val qq: Int,
+        private val sessionKey: ByteArray,
+        private val loginStatus: ClientLoginStatus
+
+) : ClientPacket() {
+    override fun encode() {
+        this.writeRandom(2)//part of packet id
+        this.writeQQ(qq)
+        this.writeHex(Protocol._fixVer)
+        this.encryptAndWrite(sessionKey) {
+            it.writeHex("01 00")
+            it.writeByte(loginStatus.id)
+            it.writeHex("00 01 00 01 00 04 00 00 00 00")
+        }
+    }
+}
\ No newline at end of file
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/session/ClientSKeyRequestPacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/session/ClientSKeyRequestPacket.kt
new file mode 100644
index 000000000..cb64b5695
--- /dev/null
+++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/session/ClientSKeyRequestPacket.kt
@@ -0,0 +1,25 @@
+package net.mamoe.mirai.network.packet.client.session
+
+import net.mamoe.mirai.network.Protocol
+import net.mamoe.mirai.network.packet.PacketId
+import net.mamoe.mirai.network.packet.client.*
+
+/**
+ * @author Him188moe
+ */
+@ExperimentalUnsignedTypes
+@PacketId("00 1D")
+class ClientSKeyRequestPacket(
+        private val qq: Int,
+        private val sessionKey: ByteArray
+) : ClientPacket() {
+    override fun encode() {
+        this.writeRandom(2)//part of packet id
+
+        this.writeQQ(qq)
+        this.writeHex(Protocol._fixVer)
+        this.encryptAndWrite(sessionKey) {
+            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")
+        }
+    }
+}
\ No newline at end of file
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/session/Handshake.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/session/Handshake.kt
new file mode 100644
index 000000000..e8576102f
--- /dev/null
+++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/session/Handshake.kt
@@ -0,0 +1,34 @@
+package net.mamoe.mirai.network.packet.client.session
+
+import net.mamoe.mirai.network.Protocol
+import net.mamoe.mirai.network.packet.PacketId
+import net.mamoe.mirai.network.packet.client.*
+import net.mamoe.mirai.network.packet.server.ServerPacket
+import java.io.DataInputStream
+
+/**
+ * @author Him188moe
+ */
+@ExperimentalUnsignedTypes
+@PacketId("00 5C")
+class ClientHandshake1Packet(
+        val qq: Int,
+        val sessionKey: ByteArray
+) : ClientPacket() {
+    override fun encode() {
+        this.writeRandom(2)//part of packet id
+        this.writeQQ(qq)
+        this.writeHex(Protocol._fixVer)
+        this.encryptAndWrite(sessionKey) {
+            it.writeByte(0x88)
+            it.writeQQ(qq)
+            it.writeByte(0x00)
+        }
+    }
+}
+
+class ServerHandshake1ResponsePacket(input: DataInputStream) : ServerPacket(input) {
+    override fun decode() {
+
+    }
+}
\ No newline at end of file
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/touch/ClientHeartbeatPacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/touch/ClientHeartbeatPacket.kt
index 94d8f69b6..d459c17db 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/touch/ClientHeartbeatPacket.kt
+++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/touch/ClientHeartbeatPacket.kt
@@ -2,27 +2,25 @@ package net.mamoe.mirai.network.packet.client.touch
 
 import net.mamoe.mirai.network.Protocol
 import net.mamoe.mirai.network.packet.PacketId
-import net.mamoe.mirai.network.packet.client.ClientPacket
-import net.mamoe.mirai.network.packet.client.writeHex
-import net.mamoe.mirai.network.packet.client.writeQQ
-import net.mamoe.mirai.network.packet.client.writeRandom
-import net.mamoe.mirai.util.TEACryptor
+import net.mamoe.mirai.network.packet.client.*
 import java.io.IOException
 
 /**
  * @author Him188moe
  */
 @ExperimentalUnsignedTypes
-@PacketId("00 58")//todo check
-class ClientHeartbeatPacket : ClientPacket() {
-    var qq: Int = 0
-    var sessionKey: ByteArray? = null//登录后获得
-
+@PacketId("00 58")
+class ClientHeartbeatPacket(
+        private val qq: Int,
+        private val sessionKey: ByteArray
+) : ClientPacket() {
     @Throws(IOException::class)
     override fun encode() {
         this.writeRandom(2)
         this.writeQQ(qq)
         this.writeHex(Protocol.fixVer)
-        this.write(TEACryptor.encrypt(byteArrayOf(0x00, 0x01, 0x00, 0x01), sessionKey))
+        this.encryptAndWrite(sessionKey) {
+            it.writeHex("00 01 00 01")
+        }
     }
 }
\ No newline at end of file
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/ServerPacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/ServerPacket.kt
index 4d312c9d0..ca78889bc 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/ServerPacket.kt
+++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/ServerPacket.kt
@@ -3,6 +3,9 @@ package net.mamoe.mirai.network.packet.server
 import net.mamoe.mirai.network.packet.Packet
 import net.mamoe.mirai.network.packet.client.toHexString
 import net.mamoe.mirai.network.packet.server.login.*
+import net.mamoe.mirai.network.packet.server.security.ServerLoginSuccessPacket
+import net.mamoe.mirai.network.packet.server.security.ServerSKeyResponsePacketEncrypted
+import net.mamoe.mirai.network.packet.server.security.ServerSessionKeyResponsePacketEncrypted
 import net.mamoe.mirai.network.packet.server.touch.ServerTouchResponsePacket
 import net.mamoe.mirai.network.packet.server.touch.ServerTouchResponsePacketEncrypted
 import net.mamoe.mirai.util.getAllDeclaredFields
@@ -28,7 +31,9 @@ abstract class ServerPacket(val input: DataInputStream) : Packet {
 
             return when (val idHex = stream.readInt().toHexString(" ")) {
                 "08 25 31 01" -> ServerTouchResponsePacketEncrypted(ServerTouchResponsePacket.Type.TYPE_08_25_31_01, stream)
+
                 "08 25 31 02" -> ServerTouchResponsePacketEncrypted(ServerTouchResponsePacket.Type.TYPE_08_25_31_02, stream)
+
                 "08 36 31 03", "08 36 31 04", "08 36 31 05", "08 36 31 06" -> {
                     when (bytes.size) {
                         271, 207 -> return ServerLoginResponseResendPacketEncrypted(stream, when (idHex) {
@@ -37,7 +42,7 @@ abstract class ServerPacket(val input: DataInputStream) : Packet {
                                 println("flag=$idHex"); ServerLoginResponseResendPacket.Flag.OTHER
                             }
                         })
-                        871 -> return ServerLoginResponseVerificationCodePacket(stream, bytes.size)
+                        871 -> return ServerLoginResponseVerificationCodePacketEncrypted(stream)
                     }
 
                     if (bytes.size > 700) {
@@ -53,14 +58,23 @@ abstract class ServerPacket(val input: DataInputStream) : Packet {
                         359 -> ServerLoginResponseFailedPacket.State.TAKEN_BACK
 
                         //unknown
-                        63 -> throw IllegalArgumentException(bytes.size.toString())//可能是已经完成登录, 服务器拒绝第二次登录
-                        351 -> throw IllegalArgumentException(bytes.size.toString())
+                        63 -> throw IllegalArgumentException(bytes.size.toString() + " (Already logged in)")//可能是已经完成登录, 服务器拒绝第二次登录
+                        351 -> throw IllegalArgumentException(bytes.size.toString() + " (Illegal package data)")//包数据有误
 
                         else -> throw IllegalArgumentException(bytes.size.toString())
                     }, stream)
                 }
 
-                else -> throw IllegalArgumentException(idHex)
+                "08 28 04 34" -> ServerSessionKeyResponsePacketEncrypted(stream)
+
+
+                else -> when (idHex.substring(0, 2)) {
+                    "00 EC" -> ServerLoginSuccessPacket(stream)
+                    "00 1D" -> ServerSKeyResponsePacketEncrypted(stream)
+                    // "00 5C" ->
+
+                    else -> throw IllegalArgumentException(idHex)
+                }
             }
         }
     }
@@ -79,10 +93,6 @@ abstract class ServerPacket(val input: DataInputStream) : Packet {
 }
 
 
-fun DataInputStream.skipUntil(byte: Byte) {
-    while (readByte() != byte);
-}
-
 fun DataInputStream.readUntil(byte: Byte): ByteArray {
     var buff = byteArrayOf()
     var b: Byte
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/login/ServerLoginResponseSuccessPacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/login/ServerLoginResponsePasswordVerifiedPacket.kt
similarity index 100%
rename from mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/login/ServerLoginResponseSuccessPacket.kt
rename to mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/login/ServerLoginResponsePasswordVerifiedPacket.kt
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/login/ServerLoginResponseVerificationCodePacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/login/ServerLoginResponseVerificationCodePacket.kt
index 6664fef58..798fa1c86 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/login/ServerLoginResponseVerificationCodePacket.kt
+++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/login/ServerLoginResponseVerificationCodePacket.kt
@@ -4,7 +4,6 @@ import net.mamoe.mirai.network.packet.server.ServerPacket
 import net.mamoe.mirai.network.packet.server.dataInputStream
 import net.mamoe.mirai.network.packet.server.goto
 import net.mamoe.mirai.util.TEACryptor
-import net.mamoe.mirai.util.toUHexString
 import java.io.DataInputStream
 
 /**
@@ -30,8 +29,7 @@ class ServerLoginResponseVerificationCodePacket(input: DataInputStream, val pack
 
         this.input.skip(1)
 
-        val b = this.input.readByte()
-        println(b.toUHexString())
+        this.unknownBoolean = this.input.readByte().toInt() == 1
 
         this.token00BA = this.input.goto(packetLength - 60).readNBytes(40)
     }
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/security/ServerLoginSuccessPacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/security/ServerLoginSuccessPacket.kt
new file mode 100644
index 000000000..4b8cbfb46
--- /dev/null
+++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/security/ServerLoginSuccessPacket.kt
@@ -0,0 +1,13 @@
+package net.mamoe.mirai.network.packet.server.security
+
+import net.mamoe.mirai.network.packet.server.ServerPacket
+import java.io.DataInputStream
+
+/**
+ * @author Him188moe
+ */
+class ServerLoginSuccessPacket(input: DataInputStream) : ServerPacket(input) {
+    override fun decode() {
+
+    }
+}
\ No newline at end of file
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/security/ServerSKeyResponsePacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/security/ServerSKeyResponsePacket.kt
new file mode 100644
index 000000000..b6326d818
--- /dev/null
+++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/security/ServerSKeyResponsePacket.kt
@@ -0,0 +1,35 @@
+package net.mamoe.mirai.network.packet.server.security
+
+import net.mamoe.mirai.network.packet.server.ServerPacket
+import net.mamoe.mirai.network.packet.server.dataInputStream
+import net.mamoe.mirai.network.packet.server.goto
+import net.mamoe.mirai.util.TEACryptor
+import java.io.DataInputStream
+
+/**
+ * @author Him188moe
+ */
+class ServerSKeyResponsePacket(input: DataInputStream) : ServerPacket(input) {
+    lateinit var sKey: String
+
+    override fun decode() {
+        this.sKey = String(this.input.goto(4).readNBytes(10))
+    }
+}
+
+/**
+ * Encrypted using [0828_rec_decr_key], decrypting in RobotNetworkHandler
+ *
+ * @author Him188moe
+ */
+class ServerSKeyResponsePacketEncrypted(inputStream: DataInputStream) : ServerPacket(inputStream) {
+    override fun decode() {
+
+    }
+
+    fun decrypt(sessionKey: ByteArray): ServerSKeyResponsePacket {
+        this.input goto 14
+        val data = this.input.readAllBytes().let { it.copyOfRange(0, it.size - 1) }
+        return ServerSKeyResponsePacket(TEACryptor.decrypt(data, sessionKey).dataInputStream());
+    }
+}
\ No newline at end of file
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/security/ServerSessionKeyResponsePacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/security/ServerSessionKeyResponsePacket.kt
new file mode 100644
index 000000000..6abeaf27b
--- /dev/null
+++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/security/ServerSessionKeyResponsePacket.kt
@@ -0,0 +1,71 @@
+package net.mamoe.mirai.network.packet.server.security
+
+import net.mamoe.mirai.network.packet.client.writeHex
+import net.mamoe.mirai.network.packet.server.ServerPacket
+import net.mamoe.mirai.network.packet.server.dataInputStream
+import net.mamoe.mirai.network.packet.server.goto
+import net.mamoe.mirai.util.TEACryptor
+import net.mamoe.mirai.util.lazyEncode
+import java.io.DataInputStream
+
+/**
+ * Dispose_0828
+ *
+ * @author Him188moe
+ */
+class ServerSessionKeyResponsePacket(inputStream: DataInputStream, val dataLength: Int) : ServerPacket(inputStream) {
+    lateinit var sessionKey: ByteArray
+    lateinit var tlv0105: ByteArray
+
+    @ExperimentalUnsignedTypes
+    override fun decode() {
+        when (dataLength) {
+            407 -> {
+                input goto 25
+                sessionKey = input.readNBytes(16)
+            }
+
+            439 -> {
+                input.goto(63)
+                sessionKey = input.readNBytes(16)
+            }
+
+            512,
+            527 -> {
+                input.goto(63)
+                sessionKey = input.readNBytes(16)
+                tlv0105 = lazyEncode {
+                    it.writeHex("01 05 00 88 00 01 01 02 00 40 02 01 03 3C 01 03 00 00")
+                    input.goto(dataLength - 122)
+                    it.write(input.readNBytes(56))
+                    it.writeHex("00 40 02 02 03 3C 01 03 00 00")
+                    input.goto(dataLength - 55)
+                    it.write(input.readNBytes(56))
+                } //todo 这个 tlv0105似乎可以保存起来然后下次登录时使用.
+            }
+
+            else -> throw IllegalArgumentException(dataLength.toString())
+        }
+
+
+        //tlv0105 = "01 05 00 88 00 01 01 02 00 40 02 01 03 3C 01 03 00 00" + 取文本中间(data, 取文本长度(data) - 367, 167) + “00 40 02 02 03 3C 01 03 00 00 ” + 取文本中间 (data, 取文本长度 (data) - 166, 167)
+
+    }
+}
+
+/**
+ * Encrypted using [0828_rec_decr_key], decrypting in RobotNetworkHandler
+ *
+ * @author Him188moe
+ */
+class ServerSessionKeyResponsePacketEncrypted(inputStream: DataInputStream) : ServerPacket(inputStream) {
+    override fun decode() {
+
+    }
+
+    fun decrypt(_0828_rec_decr_key: ByteArray): ServerSessionKeyResponsePacket {
+        this.input goto 14
+        val data = this.input.readAllBytes().let { it.copyOfRange(0, it.size - 1) }
+        return ServerSessionKeyResponsePacket(TEACryptor.decrypt(data, _0828_rec_decr_key).dataInputStream(), data.size);
+    }
+}
\ No newline at end of file
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/security/ServerSessionKeyResponsePacketEncrypted.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/security/ServerSessionKeyResponsePacketEncrypted.kt
deleted file mode 100644
index 88d952031..000000000
--- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/security/ServerSessionKeyResponsePacketEncrypted.kt
+++ /dev/null
@@ -1,54 +0,0 @@
-package net.mamoe.mirai.network.packet.server.security
-
-import net.mamoe.mirai.network.packet.server.ServerPacket
-import net.mamoe.mirai.network.packet.server.dataInputStream
-import net.mamoe.mirai.util.TEACryptor
-import java.io.DataInputStream
-
-/**
- * Dispose_0828
- *
- * @author Him188moe
- */
-class ServerSessionKeyResponsePacket(inputStream: DataInputStream) : ServerPacket(inputStream) {
-    lateinit var sessionKey: ByteArray
-    lateinit var tlv0105: ByteArray
-    override fun decode() {
-        var data = this.input.readAllBytes();
-        val input = data.dataInputStream()
-
-        sessionKey = when (data.size) {
-            407 -> {
-                input.skip(25)
-                input.readNBytes(16)
-            }
-
-            439, 527 -> {
-                input.skip(63)
-                input.readNBytes(16)
-            }
-
-            else -> throw IllegalStateException()
-        }
-
-        //tlv0105 = "01 05 00 88 00 01 01 02 00 40 02 01 03 3C 01 03 00 00" + 取文本中间(data, 取文本长度(data) - 367, 167) + “00 40 02 02 03 3C 01 03 00 00 ” + 取文本中间 (data, 取文本长度 (data) - 166, 167)
-
-    }
-}
-
-/**
- * Encrypted using []0828_rec_decr_key], decrypting in RobotNetworkHandler
- *
- * @author Him188moe
- */
-class ServerSessionKeyResponsePacketEncrypted(inputStream: DataInputStream) : ServerPacket(inputStream) {
-    override fun decode() {
-
-    }
-
-    fun decrypt(_0828_rec_decr_key: ByteArray): ServerSessionKeyResponsePacket {//todo test
-        this.input.skip(7)
-        return ServerSessionKeyResponsePacket(TEACryptor.decrypt(this.input.readAllBytes().let { it.copyOfRange(0, it.size - 1) }, _0828_rec_decr_key).dataInputStream());
-        //TeaDecrypt(取文本中间(data, 43, 取文本长度(data) - 45), m_0828_rec_decr_key)
-    }
-}
\ No newline at end of file
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/task/MiraiTaskManager.java b/mirai-core/src/main/java/net/mamoe/mirai/task/MiraiTaskManager.java
index 58cd21e9d..bb6858602 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/task/MiraiTaskManager.java
+++ b/mirai-core/src/main/java/net/mamoe/mirai/task/MiraiTaskManager.java
@@ -1,7 +1,6 @@
 package net.mamoe.mirai.task;
 
 
-import net.mamoe.mirai.MiraiServer;
 import net.mamoe.mirai.event.MiraiEventHook;
 import net.mamoe.mirai.event.events.server.ServerDisableEvent;
 
@@ -90,26 +89,26 @@ public class MiraiTaskManager {
      定时任务
      */
 
-    public void repeatingTask(Runnable runnable, long interval){
-        this.repeatingTask(runnable,interval, MiraiTaskExceptionHandler.byDefault());
+    public void repeatingTask(Runnable runnable, long intervalMillis) {
+        this.repeatingTask(runnable, intervalMillis, MiraiTaskExceptionHandler.byDefault());
     }
 
-    public void repeatingTask(Runnable runnable, long interval,  MiraiTaskExceptionHandler handler){
-        this.repeatingTask(runnable,interval,a -> true,handler);
+    public void repeatingTask(Runnable runnable, long intervalMillis, MiraiTaskExceptionHandler handler) {
+        this.repeatingTask(runnable, intervalMillis, a -> true, handler);
     }
 
-    public void repeatingTask(Runnable runnable, long interval, int times){
-        this.repeatingTask(runnable,interval,times, MiraiTaskExceptionHandler.byDefault());
+    public void repeatingTask(Runnable runnable, long intervalMillis, int times) {
+        this.repeatingTask(runnable, intervalMillis, times, MiraiTaskExceptionHandler.byDefault());
     }
 
-    public void repeatingTask(Runnable runnable, long interval, int times,  MiraiTaskExceptionHandler handler){
+    public void repeatingTask(Runnable runnable, long intervalMillis, int times, MiraiTaskExceptionHandler handler) {
         AtomicInteger integer = new AtomicInteger(times-1);
         this.repeatingTask(
-                runnable,interval, a ->  integer.getAndDecrement() > 0, handler
+                runnable, intervalMillis, a -> integer.getAndDecrement() > 0, handler
         );
     }
 
-    public <D extends Runnable> void repeatingTask(D runnable, long interval, Predicate<D> shouldContinue, MiraiTaskExceptionHandler handler){
+    public <D extends Runnable> void repeatingTask(D runnable, long intervalMillis, Predicate<D> shouldContinue, MiraiTaskExceptionHandler handler) {
         new Thread(() -> {
             do {
                 this.pool.execute(() -> {
@@ -120,7 +119,7 @@ public class MiraiTaskManager {
                     }
                 });
                 try {
-                    Thread.sleep(interval);
+                    Thread.sleep(intervalMillis);
                 } catch (InterruptedException e) {
                     e.printStackTrace();
                 }
@@ -128,10 +127,10 @@ public class MiraiTaskManager {
         }).start();
     }
 
-    public void deletingTask(Runnable runnable, long interval){
+    public void deletingTask(Runnable runnable, long intervalMillis) {
         new Thread(() -> {
             try{
-                Thread.sleep(interval);
+                Thread.sleep(intervalMillis);
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/util/ClientLoginStatus.java b/mirai-core/src/main/java/net/mamoe/mirai/util/ClientLoginStatus.java
new file mode 100644
index 000000000..31d96b662
--- /dev/null
+++ b/mirai-core/src/main/java/net/mamoe/mirai/util/ClientLoginStatus.java
@@ -0,0 +1,15 @@
+package net.mamoe.mirai.util;
+
+/**
+ * @author Him188moe
+ */
+public enum ClientLoginStatus {
+    ONLINE(0x0A);
+
+    // TODO: 2019/8/31 add more
+    public final int id;//1byte
+
+    ClientLoginStatus(int id) {
+        this.id = id;
+    }
+}
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/util/DebugLogger.kt b/mirai-core/src/main/java/net/mamoe/mirai/util/DebugLogger.kt
index 07a3845e4..484c91464 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/util/DebugLogger.kt
+++ b/mirai-core/src/main/java/net/mamoe/mirai/util/DebugLogger.kt
@@ -24,11 +24,11 @@ fun ByteArray.decryptionDebugLogging() {
 }
 
 fun ServerPacket.logging() {
-    DebugLogger.buff.append(this.toString())
+    DebugLogger.buff.append(this.toString()).append("\n")
 
 }
 
 @ExperimentalUnsignedTypes
 fun ClientPacket.logging() {
-    DebugLogger.buff.append(this.toString())
+    DebugLogger.buff.append(this.toString()).append("\n")
 }
\ No newline at end of file
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/util/Utils.kt b/mirai-core/src/main/java/net/mamoe/mirai/util/Utils.kt
index e160d68c5..67d887b6d 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/util/Utils.kt
+++ b/mirai-core/src/main/java/net/mamoe/mirai/util/Utils.kt
@@ -3,6 +3,7 @@ package net.mamoe.mirai.util
 import net.mamoe.mirai.network.Protocol
 import java.io.ByteArrayOutputStream
 import java.io.DataOutputStream
+import java.io.File
 import java.lang.reflect.Field
 import java.util.*
 import java.util.zip.CRC32
@@ -79,6 +80,24 @@ fun getRandomKey(length: Int): ByteArray {
     return bytes.toByteArray()
 }
 
+operator fun File.plus(child: String): File = File(this, child)
+
+private const val GTK_BASE_VALUE: Int = 5381
+
+fun getGTK(sKey: String): Int {
+    var value = GTK_BASE_VALUE
+    for (c in sKey.toCharArray()) {
+        value += (value shl 5) + c.toInt()
+    }
+
+    value = value and Int.MAX_VALUE
+    return value
+}
+
+fun main() {
+    println(getGTK("ABCDEFGEFC"))
+}
+
 fun getCrc32(key: ByteArray): Int = CRC32().let { it.update(key); it.value.toInt() }