diff --git a/document/protocol/log.txgt b/document/protocol/log.txgt
deleted file mode 100644
index f4be108bd..000000000
--- a/document/protocol/log.txgt
+++ /dev/null
@@ -1,72 +0,0 @@
-g_count = 0
-paccket sent: 02 37 13 08 25 31 01 76 E4 B8 DD 03 00 00 00 01 2E 01 00 00 68 52 00 00 00 00 A4 F1 91 88 C9 82 14 99 0C 9E 56 55 91 23 C8 3D 9F A7 43 90 2A 9D 29 B5 EA DB 50 7F D3 78 1C AE 31 7E 7E 4F A9 1B B5 C9 8D A8 4C 78 98 13 E1 45 FC 35 2E 22 3D E0 39 1A 3F C6 8B CA 06 A8 F3 B3 6F 95 D8 64 1A B0 E9 29 06 DB 5C F4 9B 32 47 5A B7 10 57 C5 2F C9 D9 7B 17 22 7F 09 A6 8C 30 04 24 0F 1D 61 A1 42 E2 7A AA 15 36 AC 67 9B 7A 4D 42 14 AD F5 2D D2 A3 CA 03
-DataArrived >>
-DataArrived >> flag = 08 25 31 01
-DataArrived >> dispose_0825 >>
-DataArrived >> dispose_0825 >> redirect
-DataArrived >> dispose_0825 >> g_server = 125.39.132.167
-DataArrived >> dispose_0825 >> g_count = 0
-DataArrived >> dispose_0825 >> paccket sent: 02 37 13 08 25 31 02 76 E4 B8 DD 03 00 00 00 01 2E 01 00 00 68 52 00 00 00 00 A8 F2 14 5F 58 12 60 AF 07 63 97 D6 76 B2 1A 3B 23 89 DB A3 07 80 49 63 01 76 69 F1 E1 11 32 06 E9 7F E4 6A 6B 98 07 75 EF 0E 1F 81 10 85 86 EB 96 8E 65 78 0F C3 BC F8 FF 51 3E 36 4F 48 3C 78 52 26 3F 4C 20 65 85 69 AC B8 36 B6 50 50 CC 01 4A 35 44 15 5C 80 B9 F7 A7 56 D4 B2 D4 A4 D9 09 56 29 93 39 0C C8 9C 0B F7 2D CE BE B0 D5 4C CE 48 B3 2D 18 28 A2 3C DD 26 C1 F1 6E A1 4B EC 8A 03
-DataArrived >>
-DataArrived >> flag = 08 25 31 02
-DataArrived >> dispose_0825 >>
-DataArrived >> dispose_0825 >> g_count = 0
-DataArrived >> dispose_0825 >> 不需要redirect
-DataArrived >> dispose_0825 >> m_loginTime = 5D 59 7D A6
-DataArrived >> dispose_0825 >> m_loginIP = B7 5F F8 D4
-DataArrived >> dispose_0825 >> m_0825token = 16 5A 4A C4 FE D1 F8 A3 CB B7 37 DD A5 AE 5C F7 04 74 36 91 4E CD 4A E6 EF 43 31 A7 D1 97 CC 6B 93 C7 9B 15 62 FD 11 3E 19 E1 69 62 B3 BC F4 9A E1 17 19 47 CC A3 1E AC
-DataArrived >> dispose_0825 >> m_tgtgtKey = DB DE AE DD C7 ED 35 B6 DD 2B 71 6B C4 14 C6 6B
-DataArrived >> dispose_0825 >> g_count = 0
-DataArrived >> dispose_0825 >> Construct_0836_622 >>
-DataArrived >> dispose_0825 >> Construct_0836_622 >> PCName = DESKTOP-M17JREU
-DataArrived >> dispose_0825 >> Construct_0836_622 >> PCName = 44 45 53 4B 54 4F 50 2D 4D 31 37 4A 52 45 55
-DataArrived >> dispose_0825 >> Construct_0836_622 >> g_pass = xiaoqqq
-DataArrived >> dispose_0825 >> Construct_0836_622 >> g_QQ = 76 E4 B8 DD
-DataArrived >> dispose_0825 >> Construct_0836_622 >> crc32_code(Random) = 0C 69 01 0E FF CE E7 78 BA CA C7 66 AF 7B 07 22
-DataArrived >> dispose_0825 >> Construct_0836_622 >> crc32_data = 8B D9 F6 A1
-DataArrived >> dispose_0825 >> Construct_0836_622 >> getTLV0006 >>
-DataArrived >> dispose_0825 >> Construct_0836_622 >> getTLV0006 >> m_tgtgtKey = DB DE AE DD C7 ED 35 B6 DD 2B 71 6B C4 14 C6 6B
-DataArrived >> dispose_0825 >> Construct_0836_622 >> getTLV0006 >> packet = A9 4E DF FB 00 02 76 E4 B8 DD 00 00 04 53 00 00 00 01 00 00 15 85 00 00 01 95 5B 96 CB 95 CF 1C A6 94 C4 B7 79 07 9A BB 15 5D 59 7D A6 00 00 00 00 00 00 00 00 00 00 00 00 00 B7 5F F8 D4 00 00 00 00 00 00 00 00 00 10 15 74 C4 89 85 7A 19 F5 5E A9 C9 A3 5E 8A 5A 9B DB DE AE DD C7 ED 35 B6 DD 2B 71 6B C4 14 C6 6B
-DataArrived >> dispose_0825 >> Construct_0836_622 >>
-DataArrived >> dispose_0825 >> Construct_0836_622 >> PCName = DESKTOP-M17JREU
-DataArrived >> dispose_0825 >> Construct_0836_622 >> PCName = 44 45 53 4B 54 4F 50 2D 4D 31 37 4A 52 45 55
-DataArrived >> dispose_0825 >> Construct_0836_622 >> g_pass = xiaoqqq
-DataArrived >> dispose_0825 >> Construct_0836_622 >> g_QQ = 76 E4 B8 DD
-DataArrived >> dispose_0825 >> Construct_0836_622 >> crc32_code(Random) = 1B A6 09 08 3C CB 94 A1 9D 76 2C A0 B7 AC 98 44
-DataArrived >> dispose_0825 >> Construct_0836_622 >> crc32_data = 57 4F 04 4B
-DataArrived >> dispose_0825 >> Construct_0836_622 >> getTLV0006 >>
-DataArrived >> dispose_0825 >> Construct_0836_622 >> getTLV0006 >> m_tgtgtKey = DB DE AE DD C7 ED 35 B6 DD 2B 71 6B C4 14 C6 6B
-DataArrived >> dispose_0825 >> Construct_0836_622 >> getTLV0006 >> packet = 7F E3 7A 1F 00 02 76 E4 B8 DD 00 00 04 53 00 00 00 01 00 00 15 85 00 00 01 95 5B 96 CB 95 CF 1C A6 94 C4 B7 79 07 9A BB 15 5D 59 7D A6 00 00 00 00 00 00 00 00 00 00 00 00 00 B7 5F F8 D4 00 00 00 00 00 00 00 00 00 10 15 74 C4 89 85 7A 19 F5 5E A9 C9 A3 5E 8A 5A 9B DB DE AE DD C7 ED 35 B6 DD 2B 71 6B C4 14 C6 6B
-DataArrived >> dispose_0825 >> paccket sent: 02 37 13 08 36 31 03 76 E4 B8 DD 03 00 00 00 01 01 01 00 00 68 20 00 00 00 00 00 01 01 03 00 19 02 6D 28 41 D2 A5 6F D2 FC 3E 2A 1F 03 75 DE 6E 28 8F A8 19 3E 5F 16 49 D3 00 00 00 10 EF 4A 36 6A 16 A8 E6 3D 2E EA BD 1F 98 C1 3C DA 12 58 AF 79 C5 60 54 5F A9 30 38 87 E9 B0 68 FA D3 83 A7 6A EA B6 7F 54 10 78 F0 47 60 24 1B E2 91 2D FD 60 F4 C7 DE 3C 7C 56 83 BE B4 66 49 60 5F E0 D3 2B 18 BD 5D 64 28 D1 98 8F 83 84 98 03 97 DE 97 83 5A BD 0B AC 1B 63 7C A2 C8 13 C2 26 8A C1 AA 6D B8 5D 4A 91 E7 C8 7B AF 3C 89 76 DF EA F3 F3 53 AD 69 2F 4C 45 90 69 B7 69 3E 05 C9 DE 1B B1 C9 DE D3 F6 4B 70 3D 27 54 BC D6 2B AB 68 13 2D E7 E3 11 FF 98 3F 1E 51 BC D6 F5 AB 26 DA 53 82 7B 3C 23 99 D8 77 95 32 64 C9 11 C5 8D 40 EA F6 E7 84 C6 B0 94 EE 4A 7E 22 1E 30 34 59 AB D1 66 79 EA A5 D4 AD A2 7D 4D 47 B8 FC 86 BC DD 5D 27 15 94 E0 1B 68 00 DD 5E 5A 09 08 E0 F5 91 EF 98 95 CC 92 B9 A0 EB AC 62 B5 5D DD AA EC 4F 36 48 6E C9 7C 2D 1F 21 98 F5 27 28 E5 8E 4A 51 BC 9A 2A BE 50 31 21 EC DF C8 97 35 58 76 B3 CD F9 92 7A 86 0E C4 1D 90 62 86 99 20 92 6C 12 C9 E2 E9 7F 0B 6B AC 59 00 55 7E B6 45 B1 C4 01 37 A6 1D B3 6E 16 06 96 40 59 CD 59 5D 6F 96 E9 B4 97 0D 55 AE 3B BF FA 54 73 D3 06 B3 47 AA 7E A1 89 F5 04 79 62 7C 11 B4 1C 4D F7 24 92 71 42 17 DC 52 67 9C 66 97 5F 64 1D CD 35 68 7D D5 D7 51 9B BA 29 92 E7 8B 6F B4 74 9E 84 54 5F E8 0D 81 89 15 FB 30 A0 1B AD B2 A3 46 3F F1 A7 A7 A1 A2 A6 D1 7D B0 4E D4 E9 87 AA 20 ED 9A 04 22 5F 57 45 20 05 2B 48 CD 06 4B BC 6F F2 92 D5 09 07 DF 83 DA FC 9D 75 50 C3 75 98 56 8C B3 B0 02 80 FD ED 61 03 00 86 EA E1 03 D2 08 68 B4 1F B9 9C EB 7B 75 9C 2D 94 10 F1 C0 40 E8 D9 9A DB 4A 0F 42 90 78 F6 AB 5B 7D 5A 18 ED 3F 45 8E 1F 98 D0 97 79 51 1D 2D 64 23 8D 30 93 FF C1 B2 05 1D 22 0C E6 51 CD F3 D5 F6 D9 DB 31 EC B2 2F B1 D1 ED F3 54 5F B3 F9 B9 74 0B 10 21 4D 84 52 CD 61 A2 39 51 CD 38 AF 2B DD BD CC 70 76 31 76 51 49 B7 03
-DataArrived >>
-DataArrived >> flag = 08 36 31 03
-DataArrived >> Dispose_0836 >>
-DataArrived >> Dispose_0836 >> m_0828_rec_decr_key = 37 61 4D 6D 48 73 77 6D 38 70 4B 23 6D 5F 21 5F
-DataArrived >> Dispose_0836 >> nick_length = 20
-DataArrived >> Dispose_0836 >> m_nick = (?ω)
-DataArrived >> Dispose_0836 >> m_age = 5
-DataArrived >> Dispose_0836 >> m_gender = 02
-DataArrived >> Dispose_0836 >> g_clientKey = 00015D597DA60068666D5741D077D580228800B480E93195D2165593A44A6D42D81D38AC1A1E914F89D0B9FC15DFADB2D7257DF2B15D90FB2F6B4B9CF0EE4C38C9556C8FFCA43E688FD0CEE570350500A626547C4A76CFAF7586AC1B2CE400A93F9384FF7037B11FD5602EFAE870CD0F
-DataArrived >> Dispose_0836 >> token38 = BA 24 BF EA 76 94 2C 9B 91 A8 8F 0E 7C EC F5 41 77 3C B9 D4 95 50 F2 00 FD CB E3 48 36 FB 89 13 CE E4 EA 76 A2 2F 20 86 F6 0F E0 54 55 6E D4 0B 9B EA 07 6B E1 D4 87 56
-DataArrived >> Dispose_0836 >> token88 = 00 04 5D 59 7D A6 B7 5F F8 D4 00 00 00 00 00 78 AA 32 D3 89 86 C9 B0 41 6F 37 4F 2C 51 BA EC 9A C7 38 05 91 5C D9 3E 13 FC 5F E7 77 D0 A1 E8 B3 40 E3 3E 4E 27 B8 C2 0E F9 62 67 FA 65 E1 C9 DB F3 0B A5 F0 4B 13 7A B6 EA 1D 3C AD 8C 34 D4 3B FD 75 0C FE F5 4B 28 33 76 57 AA 68 F9 94 E1 72 41 D1 9C E5 D4 7C C6 2C 25 C5 07 A5 42 95 51 2F E0 88 41 DE 3E 9D 4F 4D 70 32 5E 44 28 5C 88 DA A6 8F 13 2B 79 C8 93 1D
-DataArrived >> Dispose_0836 >> encryptionKey = C9 E2 F2 CB 45 79 DE F7 6C 51 7C 9B 97 CC D0 47
-DataArrived >> Dispose_0836 >> g_count = 0
-DataArrived >> Dispose_0836 >> Construct_0828 >>
-DataArrived >> Dispose_0836 >> paccket sent: 02 37 13 08 28 04 34 76 E4 B8 DD 02 00 00 00 01 2E 01 00 00 68 52 00 30 00 3A 00 38 BA 24 BF EA 76 94 2C 9B 91 A8 8F 0E 7C EC F5 41 77 3C B9 D4 95 50 F2 00 FD CB E3 48 36 FB 89 13 CE E4 EA 76 A2 2F 20 86 F6 0F E0 54 55 6E D4 0B 9B EA 07 6B E1 D4 87 56 F9 99 8F FA 12 8E 22 A6 5A 9D A6 DC C9 B6 5C 5A EC BE BF CC 38 BD E1 5A 23 21 CE 02 31 F1 E1 BD FB 8E 4D E9 59 E6 BB FB B2 36 0C 47 0A C0 F7 94 63 C3 2F AB 6E AE 00 01 1F 5F 60 8E B5 79 97 EB 10 59 A0 29 B3 3B 9C BA 5D 33 C4 2A 57 CA CF 94 7A 2D DD F7 B3 9C BC 65 5D D5 62 53 A8 1D D2 F1 5B DD D7 24 32 63 60 60 DD 33 1F 3A C0 71 38 86 BC 78 D3 7C 7A E1 97 71 AB B7 59 AD 27 32 D5 AF F3 DC 1B 7B 70 3B 08 C0 91 D8 BC F1 C4 DA E3 DA 86 A1 27 8A EE C3 5F D6 25 42 A0 CB 19 7F 08 80 F8 65 2C 27 31 B7 D4 85 C3 49 BD 99 48 FE A9 63 78 6D 18 C3 4E BB F7 8A C4 80 8C 8A 17 EB 47 AF 2A 12 73 71 08 A6 E7 C3 08 2B 9A 6F 8A C2 6C 3B 1A CF 05 D8 57 63 33 AC BD 45 98 C1 85 56 08 0F 9F 36 FD 60 69 BC D0 94 1A 11 4D C6 3E 78 1D F1 67 D2 1D C4 C8 17 2F DC F4 B6 4F 5F F5 EE 8B 73 68 AA 3B BA C6 94 C8 21 1E 95 6D C2 7A BE 8B 1D 92 21 8D 2C D8 B6 86 D1 30 BB 72 34 B9 A0 D2 2E 4C 98 3C 17 E2 B2 6A AD 75 E8 B0 DE F4 1A 6F 15 93 47 B3 4D DA 6F BE A3 47 D3 9B 58 2D 4B A3 76 0E 39 ED A5 C3 0A 34 BA 78 01 AE 20 A3 38 CE BA CD F6 D7 1B C9 E7 4C 83 6E 31 34 25 16 64 BA EE 4B 8D E7 0E 2F C8 08 72 50 AE 91 16 7F 68 14 60 7E D8 3F CC 26 2D F6 BC 65 72 C8 F4 EA 55 E6 1B E0 BF F4 9F 9C FD A9 93 B6 62 78 F0 A1 19 D2 87 6E B8 B7 E3 70 13 09 95 29 C9 05 EC 99 36 5C 96 47 C1 C4 06 5C 23 5C A3 AD B0 39 BC 70 75 3D AA E9 16 03 0E 62 1B D0 78 EA F2 5C FD 9C 04 D9 AB 75 00 F8 37 F1 A8 DD 7B 65 91 D3 58 DE C5 BA 9E AC 13 DE 35 BA 17 DC D1 AB A5 96 C4 99 81 8E 21 4B 2F C1 9B 4C E1 56 A7 5D AC 26 71 EC 49 F0 A6 B1 F5 43 EA AC BE E6 9F A0 C2 E1 68 35 97 7B 81 76 AF 9E BD BC A7 D8 9E FC C0 E8 21 B0 BA 20 6A D0 BD E7 00 59 06 61 A1 DF AA 9F BA F4 5D A6 7B 5B A1 D8 6B B5 E9 72 66 51 8A D3 CE 51 A9 08 C7 11 4B FB 29 2E 6C 48 5B 8A 50 C6 5D 3A C1 9E A1 51 B6 56 DD 6B F5 D2 FD AE AB A4 4A A8 1F 99 BA 7D 4F 62 D7 64 22 31 04 62 36 62 65 96 B3 5A 35 03
-DataArrived >>
-DataArrived >> flag = 08 28 04 34
-DataArrived >> Dispose_0828 >>
-DataArrived >> Dispose_0828 >> g_count = 0
-DataArrived >> Dispose_0828 >> g_sessionKey = D1 ED 7E 0B 6B BC 6F F0 2C 7E 31 8F 58 49 6D 20
-DataArrived >> Dispose_0828 >> g_tlv0105 = 01 05 00 88 00 01 01 02 00 40 02 01 03 3C 01 03 00 00 C2 D9 3F A5 A0 1B 6C 03 A2 EF AB CB 42 92 44 8E 15 97 28 1F DE B6 E9 0A 5C 53 01 CE A2 CC 95 3F E0 CB 30 3F 5C 67 09 22 83 CC 8A 80 8F D6 26 F5 EF EC 24 15 95 8E CE 99 00 40 02 02 03 3C 01 03 00 00 A1 4D 57 52 9E 5B 1F BB 48 75 09 67 F8 C0 64 F6 9B 2A 44 61 78 29 C1 26 9C 3C 59 0E DF 9B D1 59 97 0B 0C 2B 09 27 C6 7C 20 63 11 02 E1 4E A4 DE E2 59 CF A7 A1 47 0A B6
-DataArrived >> Dispose_0828 >> g_loginStatus = 0A
-DataArrived >> Dispose_0828 >> paccket sent: 02 37 13 00 EC 6E 8E 76 E4 B8 DD 02 00 00 00 01 01 01 00 00 68 20 C4 28 24 D6 67 13 CE 5F F7 F8 38 79 F4 56 1F CA 13 95 22 4D 7B 5D B6 59 03
-DataArrived >>
-DataArrived >> flag = 00 EC 6E 8E
-DataArrived >> g_count = 0
-DataArrived >> paccket sent: 02 37 13 00 1D C5 CB 76 E4 B8 DD 02 00 00 00 01 01 01 00 00 68 20 F3 B2 B9 BF F9 C9 87 EB C2 33 FD BA 6B 16 44 E8 B2 C1 8C 7E 4F 97 01 13 88 D8 00 BF 5F 6C 38 22 E0 50 4F 9B 73 7F 5F 31 64 72 9A C1 11 79 F5 B9 33 C0 EC 81 5E F7 D5 A4 BF C6 29 9F 18 9E C0 99 CE B7 16 E5 E8 BF EE E7 5A C3 5C 28 68 3E 48 18 03
-DataArrived >>
-DataArrived >> flag = 00 1D C5 CB
-DataArrived >> paccket sent: 02 37 13 00 5C 7B 2E 76 E4 B8 DD 02 00 00 00 01 01 01 00 00 68 20 E7 E2 64 22 9C 2F 33 27 A3 8B 4D 9C DE C5 A8 0D 03
-DataArrived >>
-DataArrived >> flag = 00 5C 7B 2E
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 618d9de28..926691d9c 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/MiraiServer.java
+++ b/mirai-core/src/main/java/net/mamoe/mirai/MiraiServer.java
@@ -150,7 +150,6 @@ public class MiraiServer {
 
         MiraiConfigSection<Object> section = new MiraiConfigSection<>();
 
-        System.out.println("/");
         Scanner scanner = new Scanner(System.in);
         getLogger().info("Input a " + LoggerTextFormat.RED + " QQ number " + LoggerTextFormat.GREEN + "for default robotNetworkHandler");
         getLogger().info("输入用于默认机器人的QQ号");
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/Robot.java b/mirai-core/src/main/java/net/mamoe/mirai/Robot.java
index d4e711deb..352eca716 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/Robot.java
+++ b/mirai-core/src/main/java/net/mamoe/mirai/Robot.java
@@ -11,6 +11,7 @@ import org.jetbrains.annotations.NotNull;
 
 import java.io.Closeable;
 import java.util.*;
+import java.util.concurrent.atomic.AtomicInteger;
 
 /**
  * Mirai 的机器人. 一个机器人实例登录一个 QQ 账号.
@@ -34,12 +35,20 @@ import java.util.*;
 public final class Robot implements Closeable {
     public static final List<Robot> instances = Collections.synchronizedList(new LinkedList<>());
 
+    public final int id = _id.getAndAdd(1);
+    private static final AtomicInteger _id = new AtomicInteger(0);
+
     public final RobotAccount account;
 
     public final ContactSystem contacts = new ContactSystem();
 
     public final RobotNetworkHandler network;
 
+    @Override
+    public String toString() {
+        return String.format("Robot{id=%d,qq=%d}", id, this.account.qqNumber);
+    }
+
     /**
      * Robot 联系人管理.
      *
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/event/events/network/BeforePacketSendEvent.java b/mirai-core/src/main/java/net/mamoe/mirai/event/events/network/BeforePacketSendEvent.java
index 97672e5d8..80854d43a 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/event/events/network/BeforePacketSendEvent.java
+++ b/mirai-core/src/main/java/net/mamoe/mirai/event/events/network/BeforePacketSendEvent.java
@@ -1,16 +1,17 @@
 package net.mamoe.mirai.event.events.network;
 
+import net.mamoe.mirai.Robot;
 import net.mamoe.mirai.event.Cancellable;
 import net.mamoe.mirai.network.packet.ClientPacket;
 import org.jetbrains.annotations.NotNull;
 
 /**
- * Packet 已经 {@link ClientPacket#encode()}, 即将被发送
+ * Packet 已经 encoded, 即将被发送
  *
  * @author Him188moe
  */
 public final class BeforePacketSendEvent extends ClientPacketEvent implements Cancellable {
-    public BeforePacketSendEvent(@NotNull ClientPacket packet) {
-        super(packet);
+    public BeforePacketSendEvent(@NotNull Robot robot, @NotNull ClientPacket packet) {
+        super(robot, packet);
     }
 }
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/event/events/network/ClientPacketEvent.java b/mirai-core/src/main/java/net/mamoe/mirai/event/events/network/ClientPacketEvent.java
index e25920e95..ba7c12cca 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/event/events/network/ClientPacketEvent.java
+++ b/mirai-core/src/main/java/net/mamoe/mirai/event/events/network/ClientPacketEvent.java
@@ -1,5 +1,6 @@
 package net.mamoe.mirai.event.events.network;
 
+import net.mamoe.mirai.Robot;
 import net.mamoe.mirai.network.packet.ClientPacket;
 import org.jetbrains.annotations.NotNull;
 
@@ -7,8 +8,8 @@ import org.jetbrains.annotations.NotNull;
  * @author Him188moe
  */
 public abstract class ClientPacketEvent extends PacketEvent {
-    public ClientPacketEvent(@NotNull ClientPacket packet) {
-        super(packet);
+    public ClientPacketEvent(@NotNull Robot robot, @NotNull ClientPacket packet) {
+        super(robot, packet);
     }
 
     @Override
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/event/events/network/PacketEvent.java b/mirai-core/src/main/java/net/mamoe/mirai/event/events/network/PacketEvent.java
index 08d4b6a79..af75f839a 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/event/events/network/PacketEvent.java
+++ b/mirai-core/src/main/java/net/mamoe/mirai/event/events/network/PacketEvent.java
@@ -1,6 +1,7 @@
 package net.mamoe.mirai.event.events.network;
 
-import net.mamoe.mirai.event.MiraiEvent;
+import net.mamoe.mirai.Robot;
+import net.mamoe.mirai.event.events.robot.RobotEvent;
 import net.mamoe.mirai.network.packet.Packet;
 import org.jetbrains.annotations.NotNull;
 
@@ -9,10 +10,11 @@ import java.util.Objects;
 /**
  * @author Him188moe
  */
-public abstract class PacketEvent extends MiraiEvent {
+public abstract class PacketEvent extends RobotEvent {
     private final Packet packet;
 
-    public PacketEvent(@NotNull Packet packet) {
+    public PacketEvent(@NotNull Robot robot, @NotNull Packet packet) {
+        super(robot);
         this.packet = Objects.requireNonNull(packet);
     }
 
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/event/events/network/PacketSentEvent.java b/mirai-core/src/main/java/net/mamoe/mirai/event/events/network/PacketSentEvent.java
index 963812029..1215a95d0 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/event/events/network/PacketSentEvent.java
+++ b/mirai-core/src/main/java/net/mamoe/mirai/event/events/network/PacketSentEvent.java
@@ -1,5 +1,6 @@
 package net.mamoe.mirai.event.events.network;
 
+import net.mamoe.mirai.Robot;
 import net.mamoe.mirai.network.packet.ClientPacket;
 import org.jetbrains.annotations.NotNull;
 
@@ -9,7 +10,7 @@ import org.jetbrains.annotations.NotNull;
  * @author Him188moe
  */
 public final class PacketSentEvent extends ClientPacketEvent {
-    public PacketSentEvent(@NotNull ClientPacket packet) {
-        super(packet);
+    public PacketSentEvent(@NotNull Robot robot, @NotNull ClientPacket packet) {
+        super(robot, packet);
     }
 }
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/event/events/network/ServerPacketEvent.java b/mirai-core/src/main/java/net/mamoe/mirai/event/events/network/ServerPacketEvent.java
index c90e6a284..7f5849e9d 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/event/events/network/ServerPacketEvent.java
+++ b/mirai-core/src/main/java/net/mamoe/mirai/event/events/network/ServerPacketEvent.java
@@ -1,13 +1,14 @@
 package net.mamoe.mirai.event.events.network;
 
+import net.mamoe.mirai.Robot;
 import net.mamoe.mirai.network.packet.ServerPacket;
 
 /**
  * @author Him188moe
  */
 public abstract class ServerPacketEvent extends PacketEvent {
-    public ServerPacketEvent(ServerPacket packet) {
-        super(packet);
+    public ServerPacketEvent(Robot robot, ServerPacket packet) {
+        super(robot, packet);
     }
 
     @Override
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/event/events/network/ServerPacketReceivedEvent.java b/mirai-core/src/main/java/net/mamoe/mirai/event/events/network/ServerPacketReceivedEvent.java
index 79a302b46..f92300882 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/event/events/network/ServerPacketReceivedEvent.java
+++ b/mirai-core/src/main/java/net/mamoe/mirai/event/events/network/ServerPacketReceivedEvent.java
@@ -1,5 +1,6 @@
 package net.mamoe.mirai.event.events.network;
 
+import net.mamoe.mirai.Robot;
 import net.mamoe.mirai.event.Cancellable;
 import net.mamoe.mirai.network.packet.ServerPacket;
 import net.mamoe.mirai.network.packet.ServerVerificationCodePacket;
@@ -11,7 +12,7 @@ import net.mamoe.mirai.network.packet.ServerVerificationCodePacket;
  * @author Him188moe
  */
 public final class ServerPacketReceivedEvent extends ServerPacketEvent implements Cancellable {
-    public ServerPacketReceivedEvent(ServerPacket packet) {
-        super(packet);
+    public ServerPacketReceivedEvent(Robot robot, ServerPacket packet) {
+        super(robot, packet);
     }
 }
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/Protocol.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/Protocol.kt
index 2a8335158..afaf2405e 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/network/Protocol.kt
+++ b/mirai-core/src/main/java/net/mamoe/mirai/network/Protocol.kt
@@ -10,10 +10,10 @@ import java.util.stream.Collectors
 object Protocol {
     val SERVER_IP: List<String> = object : ArrayList<String>() {
         init {
-            add("183.60.56.29")
+            //add("183.60.56.29")
 
             arrayOf(
-                    "sz3.tencent.com",
+                    //"sz3.tencent.com",
                     "sz4.tencent.com",
                     "sz5.tencent.com",
                     "sz6.tencent.com",
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 e4f713128..0950f2c09 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
@@ -85,7 +85,7 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
 
     //private | internal
 
-    internal fun tryLogin(): CompletableFuture<LoginState> = this.tryLogin(300)//登录回复非常快, 没必要等太久.
+    internal fun tryLogin(): CompletableFuture<LoginState> = this.tryLogin(200)//登录回复非常快, 没必要等太久.
 
 
     /**
@@ -99,6 +99,7 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
         val future = CompletableFuture<LoginState>()
 
         fun login() {
+            this.socketHandler.close()
             val ip = ipQueue.poll()
             if (ip == null) {
                 future.complete(LoginState.UNKNOWN)//所有服务器均返回 UNKNOWN
@@ -122,8 +123,17 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
      */
     @ExperimentalUnsignedTypes
     internal fun distributePacket(packet: ServerPacket) {
-        packet.decode()
-        if (ServerPacketReceivedEvent(packet).broadcast().isCancelled) {
+        try {
+            packet.decode()
+        } catch (e: java.lang.Exception) {
+            e.printStackTrace()
+            robot.debug("Packet=$packet")
+            robot.debug("Packet size=" + packet.input.goto(0).readAllBytes().size)
+            robot.debug("Packet data=" + packet.input.goto(0).readAllBytes().toUHexString())
+            return
+        }
+
+        if (ServerPacketReceivedEvent(robot, packet).broadcast().isCancelled) {
             debugHandler.onPacketReceived(packet)
             return
         }
@@ -145,6 +155,7 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
 
         internal var loginFuture: CompletableFuture<LoginState>? = null
 
+        @Synchronized
         private fun restartSocket() {
             socket?.close()
             socket = DatagramSocket(0)
@@ -176,18 +187,19 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
          * Start network and touch the server
          */
         internal fun touch(serverAddress: String, timeoutMillis: Long): CompletableFuture<LoginState> {
-            MiraiLogger.info("Connecting server: $serverAddress")
+            robot.info("Connecting server: $serverAddress")
             this.loginFuture = CompletableFuture()
 
             socketHandler.serverIP = serverAddress
-            sendPacket(ClientTouchPacket(robot.account.qqNumber, socketHandler.serverIP))
-            waitForPacket(ServerTouchResponsePacket::class, timeoutMillis) {
+            waitForPacket(ServerPacket::class, timeoutMillis) {
                 loginFuture!!.complete(LoginState.TIMEOUT)
             }
+            sendPacket(ClientTouchPacket(robot.account.qqNumber, socketHandler.serverIP))
 
             return this.loginFuture!!
         }
 
+        @Synchronized
         /**
          * Not async
          */
@@ -201,25 +213,25 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
             try {
                 packet.encodePacket()
 
-                if (BeforePacketSendEvent(packet).broadcast().isCancelled) {
+                if (BeforePacketSendEvent(robot, packet).broadcast().isCancelled) {
                     return
                 }
 
                 val data = packet.toByteArray()
                 socket!!.send(DatagramPacket(data, data.size))
-                MiraiLogger info "Packet sent: $packet"
+                robot purple "Packet sent:     $packet"
 
-                PacketSentEvent(packet).broadcast()
+                PacketSentEvent(robot, packet).broadcast()
             } catch (e: Throwable) {
                 e.printStackTrace()
             }
         }
 
         @Suppress("UNCHECKED_CAST")
-        private fun <P : ServerPacket> waitForPacket(packetClass: KClass<P>, timeoutMillis: Long, timeout: () -> Unit) {
+        internal fun <P : ServerPacket> waitForPacket(packetClass: KClass<P>, timeoutMillis: Long, timeout: () -> Unit) {
             var got = false
             ServerPacketReceivedEvent::class.hookWhile {
-                if (packetClass.isInstance(it.packet)) {
+                if (packetClass.isInstance(it.packet) && it.robot == robot) {
                     got = true
                     true
                 } else {
@@ -227,6 +239,7 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
                 }
             }
 
+
             MiraiThreadPool.getInstance().submit {
                 val startingTime = System.currentTimeMillis()
                 while (!got) {
@@ -266,7 +279,7 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
      */
     inner class DebugHandler : PacketHandler() {
         override fun onPacketReceived(packet: ServerPacket) {
-            MiraiLogger info "Packet received: $packet"
+            robot notice "Packet received: $packet"
             if (packet is ServerEventPacket) {
                 sendPacket(ClientMessageResponsePacket(robot.account.qqNumber, packet.packetId, sessionKey, packet.eventIdentity))
             }
@@ -296,8 +309,8 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
          */
         private lateinit var sessionResponseDecryptionKey: ByteArray
 
-        private var verificationCodeCacheId: Int = 0
-        private var verificationCodeCache: ByteArray? = byteArrayOf()//每次包只发一部分验证码来
+        private var captchaSectionId: Int = 1
+        private var captchaCache: ByteArray? = byteArrayOf()//每次包只发一部分验证码来
 
 
         private var heartbeatFuture: ScheduledFuture<*>? = null
@@ -324,49 +337,52 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
                     return
                 }
 
-                is ServerLoginResponseVerificationCodeInitPacket -> {
-                    //[token00BA]来源之一: 验证码
-                    this.token00BA = packet.token00BA
-                    this.verificationCodeCache = packet.verifyCodePart1
-
-                    if (packet.unknownBoolean != null && packet.unknownBoolean!!) {
-                        this.verificationCodeCacheId = 1
-                        sendPacket(ClientVerificationCodeTransmissionRequestPacket(1, robot.account.qqNumber, this.token0825, this.verificationCodeCacheId, this.token00BA))
-                    }
-                }
-
                 is ServerVerificationCodeCorrectPacket -> {
                     this.tgtgtKey = getRandomByteArray(16)
                     this.token00BA = packet.token00BA
                     sendPacket(ClientLoginResendPacket3105(robot.account.qqNumber, robot.account.password, this.loginTime, this.loginIP, this.tgtgtKey!!, this.token0825, this.token00BA))
                 }
 
+                is ServerLoginResponseVerificationCodeInitPacket -> {
+                    //[token00BA]来源之一: 验证码
+                    this.token00BA = packet.token00BA
+                    this.captchaCache = packet.verifyCodePart1
+
+                    if (packet.unknownBoolean != null && packet.unknownBoolean!!) {
+                        this.captchaSectionId = 1
+                        sendPacket(ClientVerificationCodeTransmissionRequestPacket(1, robot.account.qqNumber, this.token0825, this.captchaSectionId++, this.token00BA))
+                    }
+                }
+
+                is ServerVerificationCodeUnknownPacket -> {
+                    sendPacket(ClientVerificationCodeRefreshPacket(88, robot.account.qqNumber, token0825))
+                }
 
                 is ServerVerificationCodeTransmissionPacket -> {
                     if (packet is ServerVerificationCodeWrongPacket) {
-                        this.verificationCodeCacheId = 0
-                        this.verificationCodeCache = byteArrayOf()
+                        robot error "验证码错误, 请重新输入"
+                        captchaSectionId = 1
+                        this.captchaCache = byteArrayOf()
                     }
 
-                    this.verificationCodeCacheId++
-                    this.verificationCodeCache = this.verificationCodeCache!! + packet.verificationCodePartN
-
+                    this.captchaCache = this.captchaCache!! + packet.captchaSectionN
                     this.token00BA = packet.token00BA
 
                     if (packet.transmissionCompleted) {
-                        (MiraiServer.getInstance().parentFolder + "VerificationCode.png").writeBytes(this.verificationCodeCache!!)
-                        println(CharImageUtil.createCharImg(ImageIO.read(this.verificationCodeCache!!.inputStream())))
-                        println("需要验证码登录")
-                        println("若看不清请查根目录下 VerificationCode.png")
-                        println("若要更换验证码, 请直接回车")
+                        (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 ("若要更换验证码, 请直接回车")
                         val code = Scanner(System.`in`).nextLine()
-                        if (code.isEmpty()) {
-                            sendPacket(ClientVerificationCodeRefreshPacket(robot.account.qqNumber, token0825, packet.verificationSessionId + 1))
+                        if (code.isEmpty() || code.length != 4) {
+                            this.captchaCache = byteArrayOf()
+                            sendPacket(ClientVerificationCodeRefreshPacket(packet.packetIdLast + 1, robot.account.qqNumber, token0825))
                         } else {
-                            sendPacket(ClientVerificationCodeSubmitPacket(robot.account.qqNumber, token0825, packet.verificationSessionId + 1, code, packet.verificationToken))
+                            sendPacket(ClientVerificationCodeSubmitPacket(packet.packetIdLast + 1, robot.account.qqNumber, token0825, code, packet.verificationToken))
                         }
                     } else {
-                        sendPacket(ClientVerificationCodeTransmissionRequestPacket(packet.verificationSessionId + 1, robot.account.qqNumber, this.token0825, this.verificationCodeCacheId, this.token00BA))
+                        sendPacket(ClientVerificationCodeTransmissionRequestPacket(packet.packetIdLast + 1, robot.account.qqNumber, token0825, captchaSectionId++, token00BA))
                     }
                 }
 
@@ -386,10 +402,10 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
                         sendPacket(ClientLoginResendPacket3104(
                                 robot.account.qqNumber,
                                 robot.account.password,
-                                this.loginTime,
-                                this.loginIP,
-                                this.tgtgtKey!!,
-                                this.token0825,
+                                loginTime,
+                                loginIP,
+                                tgtgtKey!!,
+                                token0825,
                                 when (packet.tokenUnknown != null) {
                                     true -> packet.tokenUnknown!!
                                     false -> this.token00BA
@@ -400,10 +416,10 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
                         sendPacket(ClientLoginResendPacket3106(
                                 robot.account.qqNumber,
                                 robot.account.password,
-                                this.loginTime,
-                                this.loginIP,
-                                this.tgtgtKey!!,
-                                this.token0825,
+                                loginTime,
+                                loginIP,
+                                tgtgtKey!!,
+                                token0825,
                                 when (packet.tokenUnknown != null) {
                                     true -> packet.tokenUnknown!!
                                     false -> this.token00BA
@@ -473,7 +489,7 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
         }
 
         override fun close() {
-            this.verificationCodeCache = null
+            this.captchaCache = null
             this.tgtgtKey = null
 
             this.heartbeatFuture?.cancel(true)
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ClientPacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ClientPacket.kt
index 7446d5c78..23ab2b2cd 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ClientPacket.kt
+++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ClientPacket.kt
@@ -20,7 +20,7 @@ abstract class ClientPacket : ByteArrayDataOutputStream(), Packet {
 
     init {
         val annotation = this.javaClass.getAnnotation(PacketId::class.java)
-        idHex = annotation.value
+        idHex = annotation.value.trim()
 
         try {
             this.writeHex(Protocol.head)
@@ -60,10 +60,19 @@ abstract class ClientPacket : ByteArrayDataOutputStream(), Packet {
         return toByteArray()
     }
 
+    open fun getFixedId(): String = when (this.idHex.length) {
+        0 -> "__ __ __ __"
+        2 -> this.idHex + " __ __"
+        5 -> this.idHex + " __"
+        else -> this.idHex
+    }
+
+
     override fun toString(): String {
-        return this.javaClass.simpleName + this.getAllDeclaredFields().joinToString(", ", "{", "}") {
+        return this.javaClass.simpleName + "(${this.getFixedId()})" + this.getAllDeclaredFields().joinToString(", ", "{", "}") {
             it.trySetAccessible(); it.name + "=" + it.get(this).let { value ->
             when (value) {
+                null -> null
                 is ByteArray -> value.toUHexString()
                 is UByteArray -> value.toUHexString()
                 else -> value.toString()
@@ -144,12 +153,6 @@ fun DataOutputStream.writeTLV0006(qq: Long, password: String, loginTime: Int, lo
     }
 }
 
-/*
-@ExperimentalUnsignedTypes
-fun main() {
-    println(lazyEncode { it.writeTLV0006(1994701021, "D1 A5 C8 BB E1 Q3 CC DD", 131513, "123.123.123.123", "AA BB CC DD EE FF AA BB CC".hexToBytes()) }.toUByteArray().toUHexString())
-}*/
-
 @ExperimentalUnsignedTypes
 @TestedSuccessfully
 fun DataOutputStream.writeCRC32() = writeCRC32(getRandomByteArray(16))
@@ -209,7 +212,7 @@ fun Int.toLByteArray(): ByteArray = byteArrayOf(
 )
 
 @ExperimentalUnsignedTypes
-fun Int.toHexString(separator: String = " "): String = this.toByteArray().toUByteArray().toUHexString(separator)
+fun Int.toUHexString(separator: String = " "): String = this.toByteArray().toUByteArray().toUHexString(separator)
 
 internal fun md5(str: String): ByteArray = MessageDigest.getInstance("MD5").digest(str.toByteArray())
 
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/GradeInfo.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/GradeInfo.kt
index 73e1e38bc..c208c07f0 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/GradeInfo.kt
+++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/GradeInfo.kt
@@ -42,7 +42,7 @@ class ServerAccountInfoResponsePacket(input: DataInputStream) : ServerPacket(inp
         fun decrypt(sessionKey: ByteArray): ServerAccountInfoResponsePacket {
             this.input goto 14
             val data = this.input.readAllBytes().let { it.copyOfRange(0, it.size - 1) }
-            return ServerAccountInfoResponsePacket(TEA.decrypt(data, sessionKey).dataInputStream());
+            return ServerAccountInfoResponsePacket(TEA.decrypt(data, sessionKey).dataInputStream()).setId(this.idHex)
         }
     }
 }
\ No newline at end of file
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/SKey.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/SKey.kt
index 4ffb53ca3..30f8c16b3 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/SKey.kt
+++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/SKey.kt
@@ -58,7 +58,7 @@ class ServerSKeyResponsePacket(input: DataInputStream) : ServerPacket(input) {
         fun decrypt(sessionKey: ByteArray): ServerSKeyResponsePacket {
             this.input goto 14
             val data = this.input.readAllBytes().let { it.copyOfRange(0, it.size - 1) }
-            return ServerSKeyResponsePacket(TEA.decrypt(data, sessionKey).dataInputStream());
+            return ServerSKeyResponsePacket(TEA.decrypt(data, sessionKey).dataInputStream()).setId(this.idHex)
         }
     }
 }
\ No newline at end of file
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ServerEvent.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ServerEvent.kt
index 943e14368..d7e4769d9 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ServerEvent.kt
+++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ServerEvent.kt
@@ -39,12 +39,12 @@ open class ServerEventPacket(input: DataInputStream, val packetId: ByteArray, va
                 //"02 10", "00 12" -> ServerUnknownEventPacket(this.input, packetId, eventIdentity)
 
                 else -> UnknownServerEventPacket(this.input, packetId, eventIdentity)
-            }
+            }.setId(this.idHex)
         }
 
         @PacketId("00 17")
         class Encrypted(input: DataInputStream, private val packetId: ByteArray) : ServerPacket(input) {
-            fun decrypt(sessionKey: ByteArray): Raw = Raw(decryptBy(sessionKey), packetId)
+            fun decrypt(sessionKey: ByteArray): Raw = Raw(decryptBy(sessionKey), packetId).setId(this.idHex)
         }
     }
 }
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ServerPacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ServerPacket.kt
index ee5a44a67..397fa86dc 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ServerPacket.kt
+++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ServerPacket.kt
@@ -1,5 +1,6 @@
 package net.mamoe.mirai.network.packet
 
+import lombok.Getter
 import net.mamoe.mirai.network.packet.action.ServerSendFriendMessageResponsePacket
 import net.mamoe.mirai.network.packet.action.ServerSendGroupMessageResponsePacket
 import net.mamoe.mirai.network.packet.login.*
@@ -10,6 +11,24 @@ import java.io.DataInputStream
  * @author Him188moe
  */
 abstract class ServerPacket(val input: DataInputStream) : Packet {
+    @Getter
+    var idHex: String
+
+    var encoded: Boolean = false
+
+    init {
+        idHex = try {
+            val annotation = this.javaClass.getAnnotation(PacketId::class.java)
+            annotation.value.trim()
+        } catch (e: NullPointerException) {
+            ""
+        }
+    }
+
+    fun <P : ServerPacket> P.setId(idHex: String): P {
+        this.idHex = idHex
+        return this
+    }
 
     open fun decode() {
 
@@ -19,14 +38,12 @@ abstract class ServerPacket(val input: DataInputStream) : Packet {
 
         @ExperimentalUnsignedTypes
         fun ofByteArray(bytes: ByteArray): ServerPacket {
-            //println("Raw received: ${bytes.toUByteArray().toUHexString()}")
-
             val stream = bytes.dataInputStream()
 
             stream.skip(3)
 
-
-            return when (val idHex = stream.readInt().toHexString(" ")) {
+            val idHex = stream.readInt().toUHexString(" ")
+            return when (idHex) {
                 "08 25 31 01" -> ServerTouchResponsePacket.Encrypted(ServerTouchResponsePacket.Type.TYPE_08_25_31_01, stream)
                 "08 25 31 02" -> ServerTouchResponsePacket.Encrypted(ServerTouchResponsePacket.Type.TYPE_08_25_31_02, stream)
 
@@ -37,12 +54,12 @@ abstract class ServerPacket(val input: DataInputStream) : Packet {
                             else -> {
                                 MiraiLogger debug ("ServerLoginResponseResendPacketEncrypted: flag=$idHex"); ServerLoginResponseResendPacket.Flag.OTHER
                             }
-                        })
-                        871 -> return ServerLoginResponseVerificationCodeInitPacket.Encrypted(stream)
+                        }).apply { this.idHex = idHex }
+                        871 -> return ServerLoginResponseVerificationCodeInitPacket.Encrypted(stream).apply { this.idHex = idHex }
                     }
 
                     if (bytes.size > 700) {
-                        return ServerLoginResponseSuccessPacket.Encrypted(stream)
+                        return ServerLoginResponseSuccessPacket.Encrypted(stream).apply { this.idHex = idHex }
                     }
 
                     return ServerLoginResponseFailedPacket(when (bytes.size) {
@@ -60,7 +77,7 @@ abstract class ServerPacket(val input: DataInputStream) : Packet {
                         351 -> throw IllegalArgumentException(bytes.size.toString() + " (Illegal package data or Unknown error)")//包数据有误
 
                         else -> throw IllegalArgumentException(bytes.size.toString())*/
-                    }, stream)
+                    }, stream).apply { this.idHex = idHex }
                 }
 
                 "08 28 04 34" -> ServerSessionKeyResponsePacket.Encrypted(stream)
@@ -85,13 +102,14 @@ abstract class ServerPacket(val input: DataInputStream) : Packet {
 
                     else -> throw IllegalArgumentException(idHex)
                 }
-            }
+            }.apply { this.idHex = idHex }
         }
     }
 
+
     @ExperimentalUnsignedTypes
     override fun toString(): String {
-        return this.javaClass.simpleName + this.getAllDeclaredFields().joinToString(", \n", "{", "}") {
+        return this.javaClass.simpleName + "(${this.getFixedId()})" + this.getAllDeclaredFields().joinToString(", ", "{", "}") {
             it.trySetAccessible(); it.name + "=" + it.get(this).let { value ->
             when (value) {
                 is ByteArray -> value.toUHexString()
@@ -102,6 +120,15 @@ abstract class ServerPacket(val input: DataInputStream) : Packet {
         }
     }
 
+    open fun getFixedId(): String = getFixedId(this.idHex)
+
+    fun getFixedId(id: String): String = when (id.length) {
+        0 -> "__ __ __ __"
+        2 -> "$id __ __"
+        5 -> "$id __"
+        else -> id
+    }
+
     fun decryptBy(key: ByteArray): DataInputStream {
         input.goto(14)
         return DataInputStream(TEA.decrypt(input.readAllBytes().let { it.copyOfRange(0, it.size - 1) }, key).inputStream())
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/Session.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/Session.kt
index 0477615dc..2484adfb8 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/Session.kt
+++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/Session.kt
@@ -107,7 +107,7 @@ class ServerSessionKeyResponsePacket(inputStream: DataInputStream, private val d
         fun decrypt(sessionResponseDecryptionKey: ByteArray): ServerSessionKeyResponsePacket {
             this.input goto 14
             val data = this.input.readAllBytes().let { it.copyOfRange(0, it.size - 1) }
-            return ServerSessionKeyResponsePacket(TEA.decrypt(data, sessionResponseDecryptionKey).dataInputStream(), data.size)
+            return ServerSessionKeyResponsePacket(TEA.decrypt(data, sessionResponseDecryptionKey).dataInputStream(), data.size).setId(this.idHex)
         }
     }
 }
\ No newline at end of file
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/Touch.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/Touch.kt
index 666246a27..e069a02cc 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/Touch.kt
+++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/Touch.kt
@@ -13,8 +13,9 @@ import java.io.IOException
  *
  * @author Him188moe
  */
+@PacketId("08 25 31 0?")
 class ServerTouchResponsePacket(inputStream: DataInputStream) : ServerPacket(inputStream) {
-    var serverIP: String? = null;
+    var serverIP: String? = null
 
     var loginTime: Int = 0
     lateinit var loginIP: String
@@ -54,7 +55,7 @@ class ServerTouchResponsePacket(inputStream: DataInputStream) : ServerPacket(inp
         fun decrypt(): ServerTouchResponsePacket = ServerTouchResponsePacket(decryptBy(when (type) {
             Type.TYPE_08_25_31_02 -> Protocol.redirectionKey.hexToBytes()
             Type.TYPE_08_25_31_01 -> Protocol.key0825.hexToBytes()
-        }))
+        })).setId(this.idHex)
     }
 }
 
@@ -83,7 +84,6 @@ class ClientTouchPacket(val qq: Long, val serverIp: String) : ClientPacket() {
                 this.writeIP(serverIp);
                 this.writeHex("00 02 00 36 00 12 00 02 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 14 00 1D 01 02 00 19")
                 this.writeHex(Protocol.publicKey)
-                println(super.toUByteArray().toUHexString())
                 return super.toByteArray()
             }
         }.toByteArray()))
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/VerificationCode.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/VerificationCode.kt
index 4a0d39711..008e3a76e 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/VerificationCode.kt
+++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/VerificationCode.kt
@@ -1,10 +1,7 @@
 package net.mamoe.mirai.network.packet
 
 import net.mamoe.mirai.network.Protocol
-import net.mamoe.mirai.utils.MiraiLogger
-import net.mamoe.mirai.utils.TEA
-import net.mamoe.mirai.utils.TestedSuccessfully
-import net.mamoe.mirai.utils.hexToBytes
+import net.mamoe.mirai.utils.*
 import java.io.DataInputStream
 
 /**
@@ -13,7 +10,7 @@ import java.io.DataInputStream
 @ExperimentalUnsignedTypes
 @PacketId("00 BA 31")
 class ClientVerificationCodeTransmissionRequestPacket(
-        private val verificationSessionId: Int,
+        private val packetId: Int,
         private val qq: Long,
         private val token0825: ByteArray,
         private val verificationSequence: Int,
@@ -21,10 +18,10 @@ class ClientVerificationCodeTransmissionRequestPacket(
 ) : ClientPacket() {
     @TestedSuccessfully
     override fun encode() {
-        MiraiLogger debug "verificationSessionId=$verificationSessionId"
+        MiraiLogger debug "packetId=$packetId"
         MiraiLogger debug "verificationSequence=$verificationSequence"
 
-        this.writeByte(verificationSessionId)//part of packet id
+        this.writeByte(packetId)//part of packet id
 
         this.writeQQ(qq)
         this.writeHex(Protocol.fixVer)
@@ -52,14 +49,18 @@ class ClientVerificationCodeTransmissionRequestPacket(
 @PacketId("00 BA 32")
 @ExperimentalUnsignedTypes
 class ClientVerificationCodeSubmitPacket(
+        private val packetId: Int,
         private val qq: Long,
         private val token0825: ByteArray,
-        private val verificationSessionId: Int,
         private val verificationCode: String,
         private val verificationToken: ByteArray
 ) : ClientPacket() {
+    init {
+        require(verificationCode.length == 4) { "verificationCode.length must == 4" }
+    }
+
     override fun encode() {
-        this.writeByte(verificationSessionId)//part of packet id
+        this.writeByte(packetId)//part of packet id
 
         this.writeQQ(qq)
         this.writeHex(Protocol.fixVer)
@@ -69,17 +70,47 @@ class ClientVerificationCodeSubmitPacket(
             it.writeHex(Protocol.constantData2)
             it.writeHex("01 00 38")
             it.write(token0825)
-            it.writeHex("01 03 00 19")
+            it.writeHex("01 03")
+
+            it.writeShort(25)
             it.writeHex(Protocol.publicKey)
+
             it.writeHex("14 00 05 00 00 00 00 00 04")
-            it.write(verificationCode.substring(0..3).toByteArray())
-            it.writeByte(0x38)
+            it.write(verificationCode.toUpperCase().toByteArray())
+            it.writeHex("00 38")
             it.write(verificationToken)
 
             it.writeHex("00 10")
             it.writeHex(Protocol.key00BAFix)
         }
-        this.writeHex("")
+    }
+}
+
+@ExperimentalUnsignedTypes
+fun main() {
+    val token0825 = "6E AF F9 2C 20 2B DE 21 B6 13 6F 26 43 F4 04 7B 1F 88 08 4E 8E BE E5 D1 3F E7 93 DE DD E0 6E 38 65 C7 C7 D3 20 7D AC 73 AD F9 85 F9 CC 2A 2C 26 C6 B1 5B FD 34 3F D4 F2".hexToBytes()
+    val verificationCode = "AAAA"
+    val verificationToken = "84 2D 1D 9D 07 04 34 80 17 9E 3F 58 02 20 9A 1C 22 D0 73 7D 8A 90 1B 2F F8 E6 79 A6 84 2F 98 F5 1E 66 3D 9A 24 59 18 34 42 BD 45 DA E1 22 2D BC 2D 36 80 86 AD 44 C2 94".hexToBytes()
+//00 02 00 00 08 04 01 E0 00 00 04 53 00 00 00 01 00 00 15 85 01 00 38 6E AF F9 2C 20 2B DE 21 B6 13 6F 26 43 F4 04 7B 1F 88 08 4E 8E BE E5 D1 3F E7 93 DE DD E0 6E 38 65 C7 C7 D3 20 7D AC 73 AD F9 85 F9 CC 2A 2C 26 C6 B1 5B FD 34 3F D4 F2 01 03 00 19 02 6D 28 41 D2 A5 6F D2 FC 3E 2A 1F 03 75 DE 6E 28 8F A8 19 3E 5F 16 49 D3 14 00 05 00 00 00 00 00 04 58 51 4E 44 00 38 84 2D 1D 9D 07 04 34 80 17 9E 3F 58 02 20 9A 1C 22 D0 73 7D 8A 90 1B 2F F8 E6 79 A6 84 2F 98 F5 1E 66 3D 9A 24 59 18 34 42 BD 45 DA E1 22 2D BC 2D 36 80 86 AD 44 C2 94 00 10 69 20 D1 14 74 F5 B3 93 E4 D5 02 B3 71 1A CD 2A
+    ByteArrayDataOutputStream().let {
+        it.writeHex("00 02 00 00 08 04 01 E0")
+        it.writeHex(Protocol.constantData2)
+        it.writeHex("01 00 38")
+        it.write(token0825)
+        it.writeHex("01 03")
+
+        it.writeShort(25)
+        it.writeHex(Protocol.publicKey)
+
+        it.writeHex("14 00 05 00 00 00 00 00 04")
+        it.write(verificationCode.substring(0..3).toByteArray())
+        it.writeHex("00 38")
+        it.write(verificationToken)
+
+        it.writeHex("00 10")
+        it.writeHex(Protocol.key00BAFix)
+
+        println(it.toByteArray().toUHexString())
     }
 }
 
@@ -89,12 +120,12 @@ class ClientVerificationCodeSubmitPacket(
 @PacketId("00 BA 31")
 @ExperimentalUnsignedTypes
 class ClientVerificationCodeRefreshPacket(
+        private val packetId: Int,
         private val qq: Long,
-        private val token0825: ByteArray,
-        private val verificationSessionId: Int
+        private val token0825: ByteArray
 ) : ClientPacket() {
     override fun encode() {
-        this.writeByte(verificationSessionId)//part of packet id
+        this.writeByte(packetId)//part of packet id
 
         this.writeQQ(qq)
         this.writeHex(Protocol.fixVer)
@@ -109,15 +140,19 @@ class ClientVerificationCodeRefreshPacket(
             it.writeHex("13 00 05 00 00 00 00 00 00 00 00 10")
             it.writeHex(Protocol.key00BAFix)
         }
-        this.writeHex("")
     }
 }
 
 /**
  * 验证码输入错误
  */
-class ServerVerificationCodeWrongPacket(input: DataInputStream, dataSize: Int, packetId: ByteArray) : ServerVerificationCodeTransmissionPacket(input, dataSize, packetId) {
+@PacketId("00 BA 32")
+class ServerVerificationCodeWrongPacket(input: DataInputStream, val dataSize: Int, packetId: ByteArray) : ServerVerificationCodeTransmissionPacket(input, dataSize, packetId) {
 
+    override fun decode() {
+        MiraiLogger debug dataSize
+        super.decode()
+    }
 }
 
 /**
@@ -128,42 +163,43 @@ class ServerVerificationCodeWrongPacket(input: DataInputStream, dataSize: Int, p
 @PacketId("00 BA 31")
 open class ServerVerificationCodeTransmissionPacket(input: DataInputStream, private val dataSize: Int, private val packetId: ByteArray) : ServerVerificationCodePacket(input) {
 
-    lateinit var verificationCodePartN: ByteArray
+    lateinit var captchaSectionN: ByteArray
     lateinit var verificationToken: ByteArray//56bytes
     var transmissionCompleted: Boolean = false//验证码是否已经传输完成
     lateinit var token00BA: ByteArray//40 bytes
-    var verificationSessionId: Int = 0
+    var packetIdLast: Int = 0
 
     @ExperimentalUnsignedTypes
     override fun decode() {
         this.verificationToken = this.input.readNBytesAt(10, 56)
 
         val length = this.input.readShortAt(66)
-        this.verificationCodePartN = this.input.readNBytes(length)
+        this.captchaSectionN = this.input.readNBytes(length)
 
         this.input.skip(1)
         val byte = this.input.readByteAt(69 + length).toInt()
         this.transmissionCompleted = byte == 0
 
         this.token00BA = this.input.readNBytesAt(dataSize - 56 - 2, 40)
-        this.verificationSessionId = packetId[3].toInt()
+        this.packetIdLast = packetId[3].toInt()
     }
 }
 
-
+/*
 fun main() {
-    val data = "13 00 05 01 00 00 01 23 00 38 41 8A 4F 49 BF 68 90 72 9E F6 DB 2A 85 12 81 BF 95 0A 64 60 3C 1A 12 20 41 74 CA BC B8 C3 0D 48 28 7B F6 C1 D2 7D B3 3D E2 12 FA 64 58 9C 79 9A 8B 6A 58 14 6C 86 25 6B 02 BC F5 EE 11 59 90 F9 12 46 D1 B0 14 DF CE DB 34 CD 0E 4C 62 5B D7 7D D7 A2 F3 51 AB EB 8B E0 CE 5C 32 A6 8A D3 D6 1D 44 22 1D E8 38 E8 F5 03 E0 91 E9 56 FB 55 91 20 36 89 F7 10 B3 ED A9 D9 11 F7 2A AB 4D 0E 6D DE 8F A1 AE A5 6F D2 91 CE D3 58 D8 04 3E BF 2C D3 3E 13 12 08 18 A8 92 F2 0D 32 40 79 B6 07 40 83 F6 6A 28 BD 94 0C 31 EA E1 C4 A3 11 46 8D 48 C8 7A E2 4E 4F 20 24 EC 48 9A 2D 14 FE 66 90 ED 8E 8A 7F D7 6D 08 64 46 90 82 37 65 A2 0C 4D 64 DC 2F AC 1F D4 9F D7 54 61 34 34 35 2A B0 CE B1 64 62 24 6B A5 33 C4 B4 9C 26 10 B6 0E 0C DA EC 20 70 43 DC 3C FB A5 A9 E3 61 49 0D A2 0F C6 DC B1 20 A7 DE 42 83 9F 48 C2 C3 98 7D 6D 3C F3 53 86 58 D6 5A 4D 0A 52 A3 39 6A FE 41 A9 9C FB C8 7A 63 1A 40 06 58 EE D7 BA 62 29 CB 9A BC 72 6B D2 FD B9 3C 94 B4 42 BE F4 F8 BD F7 06 50 9E 64 E0 27 FD 62 53 5A AA 7A C9 5C DA B2 5E BC F2 40 05 98 D8 30 74 47 9A E3 BA 85 CE 5B CC DF 3F C7 1F 0D 9E B2 03 59 6B C1 4B 75 4E C5 F3 E9 E8 86 28 D6 FC A9 1C A3 25 DF 78 91 39 8B BB 66 B5 AA FF 53 D3 0B 7D 93 A8 EF 96 70 E9 3B D3 CB 66 99 B0 33 33 62 DB D3 44 02 77 3A 26 ED 2B ED 19 98 8A 25 39 7B 9B 0B D4 26 FA AC 77 83 76 DF 22 F3 EF 37 3C 16 A6 19 9F 73 65 C4 56 5F E6 D2 E3 A9 BC F5 1A 57 F5 D0 A0 09 CA 8A 70 F1 97 41 AD 36 C1 74 B2 9A F0 FE 6B C6 B5 86 1D C2 F6 7B BE 4B 2B A3 C0 B3 14 9C B3 9E D8 D9 C8 05 A3 55 02 92 34 2F C5 52 5C 44 E3 6B 31 B8 73 3F 34 21 5D 5D EF 7D 10 EF 19 F6 45 2E C2 EE 1F 47 81 7C 9B BA 99 5D 40 0F A3 05 12 00 B8 9E FC CA 7A 50 8F 90 1D F1 D4 27 6F F6 4B 41 D6 39 A1 3A 91 0C 7D 8B 17 0D D7 F6 42 EA D1 6D 55 F8 34 C2 A5 D2 F1 1E A5 C1 1A 95 A3 7C 95 E0 D4 E5 00 5F D3 D0 33 43 F6 FA 0E 26 D4 04 2B 9B 87 71 9E 77 4D 3F E7 DC 63 2A 72 47 38 94 58 57 DA 93 B4 A8 1D A0 9D 9F 35 68 54 A3 DE 50 74 87 38 CD 08 CE 35 BE E3 50 13 C1 8C F3 09 D7 BD 70 A1 A7 33 C6 A5 1E FC 17 9F 93 FA 77 2F EF EE 6D 89 B0 96 0F 49 30 53 81 BB 2A E7 5C CD BD 98 65 3D E1 75 E7 06 77 E3 F9 45 EF E0 52 48 75 2D 52 55 01 70 5D 11 C2 A7 1B CC 81 46 E9 B4 E1 E5 CB 3E 47 89 5F 3F 47 AA 3B 1D 7D 2A 30 FE 6F EC 03 59 BA F1 0E 09 7D 4F B5 9D AB FF DB F5 B4 26 1B 40 F5 BE FF 03 E7 64 A0 DE A1 0C 6B 62 39 1F 01 01 00 28 57 1B 29 6C A0 FD FB 82 34 7D 92 07 77 CF CE 7A C9 19 FA 46 9C 9B 0A 43 30 6F 1D EE D3 E0 46 A4 83 20 CD 0A 6C AF 1A 1E 00 10 E0 5A E1 E7 FE 45 53 0B 2B 70 68 40 CB C1 D6 7A".hexToBytes()
+    val data = "13 00 05 01 00 00 01 23 00 38 59 32 29 5A 3E 3D 2D FC F5 22 EB 9E 2D FB 9C 4F AA 06 C8 32 3D F0 3C 2C 2B BA 8D 05 C4 9B C1 74 3B 70 F1 99 90 BB 6E 3E 6F 74 48 97 D3 61 B7 04 C0 A3 F1 DF 40 A4 DC 2B 00 A2 01 2D BB BB E8 FE B8 AF B3 6F 39 7C EA E2 5B 91 BE DB 59 38 CF 58 BC F2 88 F1 09 CF 92 E9 F7 FB 13 76 C5 68 29 23 3F 8E 43 16 2E 50 D7 FA 4D C1 F7 67 EF 27 FB C6 F1 A7 25 A4 BC 45 39 3A EA B2 A5 38 02 FF 4B C9 FF EB BD 89 E5 5D B9 4A 2A BE 5F 52 F1 EB 09 29 CB 3E 66 CF EF 97 89 47 BB 6B E0 7B 4A 3E A1 BC 3F FB F2 0A 83 CB E3 EA B9 43 E1 26 88 03 0B A7 E0 B2 AD 7F 83 CC DA 74 85 83 72 08 EC D2 F9 95 05 15 05 96 F7 1C FF 00 82 C3 90 22 A4 BA 90 D5 00 00 00 00 49 45 4E 44 AE 42 60 82 03 00 00 28 EA 32 5A 85 C8 D2 73 B3 40 39 77 85 65 98 00 FE 03 A2 A5 95 B4 2F E6 79 7A DE 5A 03 10 C8 3D BF 6D 3D 8B 51 84 C2 6D 49 00 10 92 AA 69 FB C6 3D 60 5A 7A A4 AC 7A B0 71 00 36".hexToBytes()
     ServerVerificationCodeTransmissionPacket(data.dataInputStream(), data.size, "00 BA 31 01".hexToBytes()).let {
         it.decode()
         println(it.toString())
     }
-}
+}*/
 
 /**
  * 验证码正确
  *
  * @author Him188moe
  */
+@PacketId("00 BA 32")
 class ServerVerificationCodeCorrectPacket(input: DataInputStream) : ServerVerificationCodePacket(input) {
 
     lateinit var token00BA: ByteArray//56 bytes
@@ -174,23 +210,32 @@ class ServerVerificationCodeCorrectPacket(input: DataInputStream) : ServerVerifi
     }
 }
 
+class ServerVerificationCodeUnknownPacket(input: DataInputStream) : ServerVerificationCodePacket(input) {
+    override fun decode() {
+        MiraiLogger.debug(this.input.goto(0).readAllBytes())
+    }
+}
+
 abstract class ServerVerificationCodePacket(input: DataInputStream) : ServerPacket(input) {
 
     @PacketId("00 BA")
-    class Encrypted(input: DataInputStream, val idHex: String) : ServerPacket(input) {
+    class Encrypted(input: DataInputStream, private val id: String) : ServerPacket(input) {
         @ExperimentalUnsignedTypes
         fun decrypt(): ServerVerificationCodePacket {
             this.input goto 14
             val data = TEA.decrypt(this.input.readAllBytes().cutTail(1), Protocol.key00BA.hexToBytes())
-            if (idHex.startsWith("00 BA 32")) {
-                if (data.size == 95) {
-                    ServerVerificationCodeCorrectPacket(data.dataInputStream())
-                } else {
-                    return ServerVerificationCodeWrongPacket(data.dataInputStream(), data.size, this.input.readNBytesAt(3, 4))
-                }
+            if (id.startsWith("00 BA 32")) {
+                return when (data.size) {
+                    66,
+                    95 -> ServerVerificationCodeCorrectPacket(data.dataInputStream())
+                    //66 -> ServerVerificationCodeUnknownPacket(data.dataInputStream())
+                    else -> return ServerVerificationCodeWrongPacket(data.dataInputStream(), data.size, this.input.readNBytesAt(3, 4))
+                }.setId(this.idHex)
             }
 
-            return ServerVerificationCodeTransmissionPacket(data.dataInputStream(), data.size, this.input.readNBytesAt(3, 4))
+            return ServerVerificationCodeTransmissionPacket(data.dataInputStream(), data.size, this.input.readNBytesAt(3, 4)).setId(this.idHex)
         }
+
+        override fun getFixedId(): String = this.getFixedId(id)
     }
 }
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ClientLogin.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ClientLogin.kt
index 1381e378b..5c7c4ae61 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ClientLogin.kt
+++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ClientLogin.kt
@@ -2,7 +2,10 @@ package net.mamoe.mirai.network.packet.login
 
 import net.mamoe.mirai.network.Protocol
 import net.mamoe.mirai.network.packet.*
-import net.mamoe.mirai.utils.*
+import net.mamoe.mirai.utils.ByteArrayDataOutputStream
+import net.mamoe.mirai.utils.TEA
+import net.mamoe.mirai.utils.TestedSuccessfully
+import net.mamoe.mirai.utils.hexToBytes
 import java.io.DataOutputStream
 
 /**
@@ -32,7 +35,6 @@ class ClientPasswordSubmissionPacket(
         this.encryptAndWrite(Protocol.shareKey.hexToBytes()) {
             it.writePart1(qq, password, loginTime, loginIP, tgtgtKey, token0825)
             it.writePart2()
-            println(it.toByteArray().toUHexString())
         }
     }
 }
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ServerLoginResponsePasswordVerifiedPacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ServerLoginResponsePasswordVerifiedPacket.kt
index b6b8f448c..786391fb8 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ServerLoginResponsePasswordVerifiedPacket.kt
+++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ServerLoginResponsePasswordVerifiedPacket.kt
@@ -53,7 +53,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());
+            return ServerLoginResponseSuccessPacket(TEA.decrypt(TEA.decrypt(input.readAllBytes().cutTail(1), Protocol.shareKey), tgtgtKey).dataInputStream()).setId(this.idHex)
         }
     }
 
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ServerLoginResponseResendPacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ServerLoginResponseResendPacket.kt
index 37a9862d0..def2bc103 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ServerLoginResponseResendPacket.kt
+++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ServerLoginResponseResendPacket.kt
@@ -44,6 +44,6 @@ class ServerLoginResponseResendPacket(input: DataInputStream, val flag: Flag) :
 
     class Encrypted(input: DataInputStream, private val flag: Flag) : ServerPacket(input) {
         @TestedSuccessfully
-        fun decrypt(tgtgtKey: ByteArray): ServerLoginResponseResendPacket = ServerLoginResponseResendPacket(decryptBy(tgtgtKey), flag)
+        fun decrypt(tgtgtKey: ByteArray): ServerLoginResponseResendPacket = ServerLoginResponseResendPacket(decryptBy(tgtgtKey), flag).setId(this.idHex)
     }
 }
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ServerLoginResponseVerificationCodeInitPacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ServerLoginResponseVerificationCodeInitPacket.kt
index 448d1413c..3d5ab55b0 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ServerLoginResponseVerificationCodeInitPacket.kt
+++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ServerLoginResponseVerificationCodeInitPacket.kt
@@ -43,7 +43,7 @@ class ServerLoginResponseVerificationCodeInitPacket(input: DataInputStream, priv
         fun decrypt(): ServerLoginResponseVerificationCodeInitPacket {
             this.input goto 14
             val data = TEA.CRYPTOR_SHARE_KEY.decrypt(this.input.readAllBytes().cutTail(1));
-            return ServerLoginResponseVerificationCodeInitPacket(data.dataInputStream(), data.size)
+            return ServerLoginResponseVerificationCodeInitPacket(data.dataInputStream(), data.size).setId(this.idHex)
         }
     }
 }
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/utils/MiraiLogger.kt b/mirai-core/src/main/java/net/mamoe/mirai/utils/MiraiLogger.kt
index 915d69e67..53ce7f0c8 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/utils/MiraiLogger.kt
+++ b/mirai-core/src/main/java/net/mamoe/mirai/utils/MiraiLogger.kt
@@ -1,5 +1,6 @@
 package net.mamoe.mirai.utils
 
+import net.mamoe.mirai.Robot
 import java.text.SimpleDateFormat
 import java.util.*
 
@@ -34,6 +35,31 @@ object MiraiLogger {
     }
 }
 
+infix fun Robot.log(o: Any?) = info(o)
+infix fun Robot.println(o: Any?) = info(o)
+infix fun Robot.info(o: Any?) = print(this, o.toString(), LoggerTextFormat.RESET)
+
+infix fun Robot.error(o: Any?) = print(this, o.toString(), LoggerTextFormat.RED)
+
+infix fun Robot.notice(o: Any?) = print(this, o.toString(), LoggerTextFormat.LIGHT_BLUE)
+
+infix fun Robot.purple(o: Any?) = print(this, o.toString(), LoggerTextFormat.PURPLE)
+
+infix fun Robot.success(o: Any?) = print(this, o.toString(), LoggerTextFormat.GREEN)
+
+infix fun Robot.debug(o: Any?) = print(this, o.toString(), LoggerTextFormat.YELLOW)
+
+
+private fun print(robot: Robot, value: String?, color: LoggerTextFormat = LoggerTextFormat.WHITE) {
+    val s = SimpleDateFormat("MM-dd HH:mm:ss").format(Date())
+    kotlin.io.println("$color[Mirai] $s #R${robot.id}: $value")
+}
+
+
+private fun print(value: String?, color: LoggerTextFormat = LoggerTextFormat.WHITE) {
+    val s = SimpleDateFormat("MM-dd HH:mm:ss").format(Date())
+    kotlin.io.println("$color[Mirai] $s : $value")
+}
 
 fun Any.logInfo() = MiraiLogger.info(this)
 
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/utils/Utils.kt b/mirai-core/src/main/java/net/mamoe/mirai/utils/Utils.kt
index bcf62f885..6b805a8a3 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/utils/Utils.kt
+++ b/mirai-core/src/main/java/net/mamoe/mirai/utils/Utils.kt
@@ -60,9 +60,6 @@ fun String.hexToShort(): Short = hexToBytes().let { ((it[1].toInt() shl 8) + it[
 @ExperimentalUnsignedTypes
 fun String.hexToInt(): Int = hexToBytes().let { ((it[0].toInt() shl 24) + (it[1].toInt() shl 16) + (it[2].toInt() shl 8) + it[3]) }
 
-@ExperimentalUnsignedTypes
-fun String.hexToByte(): Byte = hexToBytes()[0]
-
 open class ByteArrayDataOutputStream : DataOutputStream(ByteArrayOutputStream()) {
     open fun toByteArray(): ByteArray = (out as ByteArrayOutputStream).toByteArray()
     @ExperimentalUnsignedTypes
diff --git a/mirai-core/src/test/java/HexComparator.java b/mirai-core/src/test/java/HexComparator.java
index 51f6677e2..6cadeb451 100644
--- a/mirai-core/src/test/java/HexComparator.java
+++ b/mirai-core/src/test/java/HexComparator.java
@@ -51,9 +51,9 @@ public class HexComparator {
         @SuppressWarnings({"unused", "NonAsciiCharacters"})
         private static class TestConsts {
             private static final String 牛逼 = UtilsKt.toUHexString("牛逼".getBytes(), " ");
-            private static final String _1994701021 = ClientPacketKt.toHexString(1994701021, " ");
-            private static final String _1040400290 = ClientPacketKt.toHexString(1040400290, " ");
-            private static final String _580266363 = ClientPacketKt.toHexString(580266363, " ");
+            private static final String _1994701021 = ClientPacketKt.toUHexString(1994701021, " ");
+            private static final String _1040400290 = ClientPacketKt.toUHexString(1040400290, " ");
+            private static final String _580266363 = ClientPacketKt.toUHexString(580266363, " ");
         }
 
         private final List<Match> matches = new LinkedList<>();