Commit 74fff88a authored by Him188moe's avatar Him188moe

Captcha finished

parent 36f1980a
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
...@@ -150,7 +150,6 @@ public class MiraiServer { ...@@ -150,7 +150,6 @@ public class MiraiServer {
MiraiConfigSection<Object> section = new MiraiConfigSection<>(); MiraiConfigSection<Object> section = new MiraiConfigSection<>();
System.out.println("/");
Scanner scanner = new Scanner(System.in); Scanner scanner = new Scanner(System.in);
getLogger().info("Input a " + LoggerTextFormat.RED + " QQ number " + LoggerTextFormat.GREEN + "for default robotNetworkHandler"); getLogger().info("Input a " + LoggerTextFormat.RED + " QQ number " + LoggerTextFormat.GREEN + "for default robotNetworkHandler");
getLogger().info("输入用于默认机器人的QQ号"); getLogger().info("输入用于默认机器人的QQ号");
......
...@@ -11,6 +11,7 @@ import org.jetbrains.annotations.NotNull; ...@@ -11,6 +11,7 @@ import org.jetbrains.annotations.NotNull;
import java.io.Closeable; import java.io.Closeable;
import java.util.*; import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
/** /**
* Mirai 的机器人. 一个机器人实例登录一个 QQ 账号. * Mirai 的机器人. 一个机器人实例登录一个 QQ 账号.
...@@ -34,12 +35,20 @@ import java.util.*; ...@@ -34,12 +35,20 @@ import java.util.*;
public final class Robot implements Closeable { public final class Robot implements Closeable {
public static final List<Robot> instances = Collections.synchronizedList(new LinkedList<>()); 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 RobotAccount account;
public final ContactSystem contacts = new ContactSystem(); public final ContactSystem contacts = new ContactSystem();
public final RobotNetworkHandler network; public final RobotNetworkHandler network;
@Override
public String toString() {
return String.format("Robot{id=%d,qq=%d}", id, this.account.qqNumber);
}
/** /**
* Robot 联系人管理. * Robot 联系人管理.
* *
......
package net.mamoe.mirai.event.events.network; package net.mamoe.mirai.event.events.network;
import net.mamoe.mirai.Robot;
import net.mamoe.mirai.event.Cancellable; import net.mamoe.mirai.event.Cancellable;
import net.mamoe.mirai.network.packet.ClientPacket; import net.mamoe.mirai.network.packet.ClientPacket;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
/** /**
* Packet 已经 {@link ClientPacket#encode()}, 即将被发送 * Packet 已经 encoded, 即将被发送
* *
* @author Him188moe * @author Him188moe
*/ */
public final class BeforePacketSendEvent extends ClientPacketEvent implements Cancellable { public final class BeforePacketSendEvent extends ClientPacketEvent implements Cancellable {
public BeforePacketSendEvent(@NotNull ClientPacket packet) { public BeforePacketSendEvent(@NotNull Robot robot, @NotNull ClientPacket packet) {
super(packet); super(robot, packet);
} }
} }
package net.mamoe.mirai.event.events.network; package net.mamoe.mirai.event.events.network;
import net.mamoe.mirai.Robot;
import net.mamoe.mirai.network.packet.ClientPacket; import net.mamoe.mirai.network.packet.ClientPacket;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
...@@ -7,8 +8,8 @@ import org.jetbrains.annotations.NotNull; ...@@ -7,8 +8,8 @@ import org.jetbrains.annotations.NotNull;
* @author Him188moe * @author Him188moe
*/ */
public abstract class ClientPacketEvent extends PacketEvent { public abstract class ClientPacketEvent extends PacketEvent {
public ClientPacketEvent(@NotNull ClientPacket packet) { public ClientPacketEvent(@NotNull Robot robot, @NotNull ClientPacket packet) {
super(packet); super(robot, packet);
} }
@Override @Override
......
package net.mamoe.mirai.event.events.network; 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 net.mamoe.mirai.network.packet.Packet;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
...@@ -9,10 +10,11 @@ import java.util.Objects; ...@@ -9,10 +10,11 @@ import java.util.Objects;
/** /**
* @author Him188moe * @author Him188moe
*/ */
public abstract class PacketEvent extends MiraiEvent { public abstract class PacketEvent extends RobotEvent {
private final Packet packet; private final Packet packet;
public PacketEvent(@NotNull Packet packet) { public PacketEvent(@NotNull Robot robot, @NotNull Packet packet) {
super(robot);
this.packet = Objects.requireNonNull(packet); this.packet = Objects.requireNonNull(packet);
} }
......
package net.mamoe.mirai.event.events.network; package net.mamoe.mirai.event.events.network;
import net.mamoe.mirai.Robot;
import net.mamoe.mirai.network.packet.ClientPacket; import net.mamoe.mirai.network.packet.ClientPacket;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
...@@ -9,7 +10,7 @@ import org.jetbrains.annotations.NotNull; ...@@ -9,7 +10,7 @@ import org.jetbrains.annotations.NotNull;
* @author Him188moe * @author Him188moe
*/ */
public final class PacketSentEvent extends ClientPacketEvent { public final class PacketSentEvent extends ClientPacketEvent {
public PacketSentEvent(@NotNull ClientPacket packet) { public PacketSentEvent(@NotNull Robot robot, @NotNull ClientPacket packet) {
super(packet); super(robot, packet);
} }
} }
package net.mamoe.mirai.event.events.network; package net.mamoe.mirai.event.events.network;
import net.mamoe.mirai.Robot;
import net.mamoe.mirai.network.packet.ServerPacket; import net.mamoe.mirai.network.packet.ServerPacket;
/** /**
* @author Him188moe * @author Him188moe
*/ */
public abstract class ServerPacketEvent extends PacketEvent { public abstract class ServerPacketEvent extends PacketEvent {
public ServerPacketEvent(ServerPacket packet) { public ServerPacketEvent(Robot robot, ServerPacket packet) {
super(packet); super(robot, packet);
} }
@Override @Override
......
package net.mamoe.mirai.event.events.network; package net.mamoe.mirai.event.events.network;
import net.mamoe.mirai.Robot;
import net.mamoe.mirai.event.Cancellable; import net.mamoe.mirai.event.Cancellable;
import net.mamoe.mirai.network.packet.ServerPacket; import net.mamoe.mirai.network.packet.ServerPacket;
import net.mamoe.mirai.network.packet.ServerVerificationCodePacket; import net.mamoe.mirai.network.packet.ServerVerificationCodePacket;
...@@ -11,7 +12,7 @@ import net.mamoe.mirai.network.packet.ServerVerificationCodePacket; ...@@ -11,7 +12,7 @@ import net.mamoe.mirai.network.packet.ServerVerificationCodePacket;
* @author Him188moe * @author Him188moe
*/ */
public final class ServerPacketReceivedEvent extends ServerPacketEvent implements Cancellable { public final class ServerPacketReceivedEvent extends ServerPacketEvent implements Cancellable {
public ServerPacketReceivedEvent(ServerPacket packet) { public ServerPacketReceivedEvent(Robot robot, ServerPacket packet) {
super(packet); super(robot, packet);
} }
} }
...@@ -10,10 +10,10 @@ import java.util.stream.Collectors ...@@ -10,10 +10,10 @@ import java.util.stream.Collectors
object Protocol { object Protocol {
val SERVER_IP: List<String> = object : ArrayList<String>() { val SERVER_IP: List<String> = object : ArrayList<String>() {
init { init {
add("183.60.56.29") //add("183.60.56.29")
arrayOf( arrayOf(
"sz3.tencent.com", //"sz3.tencent.com",
"sz4.tencent.com", "sz4.tencent.com",
"sz5.tencent.com", "sz5.tencent.com",
"sz6.tencent.com", "sz6.tencent.com",
......
...@@ -85,7 +85,7 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable { ...@@ -85,7 +85,7 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
//private | internal //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 { ...@@ -99,6 +99,7 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
val future = CompletableFuture<LoginState>() val future = CompletableFuture<LoginState>()
fun login() { fun login() {
this.socketHandler.close()
val ip = ipQueue.poll() val ip = ipQueue.poll()
if (ip == null) { if (ip == null) {
future.complete(LoginState.UNKNOWN)//所有服务器均返回 UNKNOWN future.complete(LoginState.UNKNOWN)//所有服务器均返回 UNKNOWN
...@@ -122,8 +123,17 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable { ...@@ -122,8 +123,17 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
*/ */
@ExperimentalUnsignedTypes @ExperimentalUnsignedTypes
internal fun distributePacket(packet: ServerPacket) { internal fun distributePacket(packet: ServerPacket) {
packet.decode() try {
if (ServerPacketReceivedEvent(packet).broadcast().isCancelled) { 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) debugHandler.onPacketReceived(packet)
return return
} }
...@@ -145,6 +155,7 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable { ...@@ -145,6 +155,7 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
internal var loginFuture: CompletableFuture<LoginState>? = null internal var loginFuture: CompletableFuture<LoginState>? = null
@Synchronized
private fun restartSocket() { private fun restartSocket() {
socket?.close() socket?.close()
socket = DatagramSocket(0) socket = DatagramSocket(0)
...@@ -176,18 +187,19 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable { ...@@ -176,18 +187,19 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
* Start network and touch the server * Start network and touch the server
*/ */
internal fun touch(serverAddress: String, timeoutMillis: Long): CompletableFuture<LoginState> { internal fun touch(serverAddress: String, timeoutMillis: Long): CompletableFuture<LoginState> {
MiraiLogger.info("Connecting server: $serverAddress") robot.info("Connecting server: $serverAddress")
this.loginFuture = CompletableFuture() this.loginFuture = CompletableFuture()
socketHandler.serverIP = serverAddress socketHandler.serverIP = serverAddress
sendPacket(ClientTouchPacket(robot.account.qqNumber, socketHandler.serverIP)) waitForPacket(ServerPacket::class, timeoutMillis) {
waitForPacket(ServerTouchResponsePacket::class, timeoutMillis) {
loginFuture!!.complete(LoginState.TIMEOUT) loginFuture!!.complete(LoginState.TIMEOUT)
} }
sendPacket(ClientTouchPacket(robot.account.qqNumber, socketHandler.serverIP))
return this.loginFuture!! return this.loginFuture!!
} }
@Synchronized
/** /**
* Not async * Not async
*/ */
...@@ -201,25 +213,25 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable { ...@@ -201,25 +213,25 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
try { try {
packet.encodePacket() packet.encodePacket()
if (BeforePacketSendEvent(packet).broadcast().isCancelled) { if (BeforePacketSendEvent(robot, packet).broadcast().isCancelled) {
return return
} }
val data = packet.toByteArray() val data = packet.toByteArray()
socket!!.send(DatagramPacket(data, data.size)) 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) { } catch (e: Throwable) {
e.printStackTrace() e.printStackTrace()
} }
} }
@Suppress("UNCHECKED_CAST") @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 var got = false
ServerPacketReceivedEvent::class.hookWhile { ServerPacketReceivedEvent::class.hookWhile {
if (packetClass.isInstance(it.packet)) { if (packetClass.isInstance(it.packet) && it.robot == robot) {
got = true got = true
true true
} else { } else {
...@@ -227,6 +239,7 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable { ...@@ -227,6 +239,7 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
} }
} }
MiraiThreadPool.getInstance().submit { MiraiThreadPool.getInstance().submit {
val startingTime = System.currentTimeMillis() val startingTime = System.currentTimeMillis()
while (!got) { while (!got) {
...@@ -266,7 +279,7 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable { ...@@ -266,7 +279,7 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
*/ */
inner class DebugHandler : PacketHandler() { inner class DebugHandler : PacketHandler() {
override fun onPacketReceived(packet: ServerPacket) { override fun onPacketReceived(packet: ServerPacket) {
MiraiLogger info "Packet received: $packet" robot notice "Packet received: $packet"
if (packet is ServerEventPacket) { if (packet is ServerEventPacket) {
sendPacket(ClientMessageResponsePacket(robot.account.qqNumber, packet.packetId, sessionKey, packet.eventIdentity)) sendPacket(ClientMessageResponsePacket(robot.account.qqNumber, packet.packetId, sessionKey, packet.eventIdentity))
} }
...@@ -296,8 +309,8 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable { ...@@ -296,8 +309,8 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
*/ */
private lateinit var sessionResponseDecryptionKey: ByteArray private lateinit var sessionResponseDecryptionKey: ByteArray
private var verificationCodeCacheId: Int = 0 private var captchaSectionId: Int = 1
private var verificationCodeCache: ByteArray? = byteArrayOf()//每次包只发一部分验证码来 private var captchaCache: ByteArray? = byteArrayOf()//每次包只发一部分验证码来
private var heartbeatFuture: ScheduledFuture<*>? = null private var heartbeatFuture: ScheduledFuture<*>? = null
...@@ -324,49 +337,52 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable { ...@@ -324,49 +337,52 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
return return
} }
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 -> { is ServerLoginResponseVerificationCodeInitPacket -> {
//[token00BA]来源之一: 验证码 //[token00BA]来源之一: 验证码
this.token00BA = packet.token00BA this.token00BA = packet.token00BA
this.verificationCodeCache = packet.verifyCodePart1 this.captchaCache = packet.verifyCodePart1
if (packet.unknownBoolean != null && packet.unknownBoolean!!) { if (packet.unknownBoolean != null && packet.unknownBoolean!!) {
this.verificationCodeCacheId = 1 this.captchaSectionId = 1
sendPacket(ClientVerificationCodeTransmissionRequestPacket(1, robot.account.qqNumber, this.token0825, this.verificationCodeCacheId, this.token00BA)) sendPacket(ClientVerificationCodeTransmissionRequestPacket(1, robot.account.qqNumber, this.token0825, this.captchaSectionId++, this.token00BA))
} }
} }
is ServerVerificationCodeCorrectPacket -> { is ServerVerificationCodeUnknownPacket -> {
this.tgtgtKey = getRandomByteArray(16) sendPacket(ClientVerificationCodeRefreshPacket(88, robot.account.qqNumber, token0825))
this.token00BA = packet.token00BA
sendPacket(ClientLoginResendPacket3105(robot.account.qqNumber, robot.account.password, this.loginTime, this.loginIP, this.tgtgtKey!!, this.token0825, this.token00BA))
} }
is ServerVerificationCodeTransmissionPacket -> { is ServerVerificationCodeTransmissionPacket -> {
if (packet is ServerVerificationCodeWrongPacket) { if (packet is ServerVerificationCodeWrongPacket) {
this.verificationCodeCacheId = 0 robot error "验证码错误, 请重新输入"
this.verificationCodeCache = byteArrayOf() captchaSectionId = 1
this.captchaCache = byteArrayOf()
} }
this.verificationCodeCacheId++ this.captchaCache = this.captchaCache!! + packet.captchaSectionN
this.verificationCodeCache = this.verificationCodeCache!! + packet.verificationCodePartN
this.token00BA = packet.token00BA this.token00BA = packet.token00BA
if (packet.transmissionCompleted) { if (packet.transmissionCompleted) {
(MiraiServer.getInstance().parentFolder + "VerificationCode.png").writeBytes(this.verificationCodeCache!!) (MiraiServer.getInstance().parentFolder + "VerificationCode.png").writeBytes(this.captchaCache!!)
println(CharImageUtil.createCharImg(ImageIO.read(this.verificationCodeCache!!.inputStream()))) robot notice (CharImageUtil.createCharImg(ImageIO.read(this.captchaCache!!.inputStream())))
println("需要验证码登录") robot notice ("需要验证码登录")
println("若看不清请查根目录下 VerificationCode.png") robot notice ("若看不清请查根目录下 VerificationCode.png")
println("若要更换验证码, 请直接回车") robot notice ("若要更换验证码, 请直接回车")
val code = Scanner(System.`in`).nextLine() val code = Scanner(System.`in`).nextLine()
if (code.isEmpty()) { if (code.isEmpty() || code.length != 4) {
sendPacket(ClientVerificationCodeRefreshPacket(robot.account.qqNumber, token0825, packet.verificationSessionId + 1)) this.captchaCache = byteArrayOf()
sendPacket(ClientVerificationCodeRefreshPacket(packet.packetIdLast + 1, robot.account.qqNumber, token0825))
} else { } 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 { } 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 { ...@@ -386,10 +402,10 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
sendPacket(ClientLoginResendPacket3104( sendPacket(ClientLoginResendPacket3104(
robot.account.qqNumber, robot.account.qqNumber,
robot.account.password, robot.account.password,
this.loginTime, loginTime,
this.loginIP, loginIP,
this.tgtgtKey!!, tgtgtKey!!,
this.token0825, token0825,
when (packet.tokenUnknown != null) { when (packet.tokenUnknown != null) {
true -> packet.tokenUnknown!! true -> packet.tokenUnknown!!
false -> this.token00BA false -> this.token00BA
...@@ -400,10 +416,10 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable { ...@@ -400,10 +416,10 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
sendPacket(ClientLoginResendPacket3106( sendPacket(ClientLoginResendPacket3106(
robot.account.qqNumber, robot.account.qqNumber,
robot.account.password, robot.account.password,
this.loginTime, loginTime,
this.loginIP, loginIP,
this.tgtgtKey!!, tgtgtKey!!,
this.token0825, token0825,
when (packet.tokenUnknown != null) { when (packet.tokenUnknown != null) {
true -> packet.tokenUnknown!! true -> packet.tokenUnknown!!
false -> this.token00BA false -> this.token00BA
...@@ -473,7 +489,7 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable { ...@@ -473,7 +489,7 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
} }
override fun close() { override fun close() {
this.verificationCodeCache = null this.captchaCache = null
this.tgtgtKey = null this.tgtgtKey = null
this.heartbeatFuture?.cancel(true) this.heartbeatFuture?.cancel(true)
......
...@@ -20,7 +20,7 @@ abstract class ClientPacket : ByteArrayDataOutputStream(), Packet { ...@@ -20,7 +20,7 @@ abstract class ClientPacket : ByteArrayDataOutputStream(), Packet {
init { init {
val annotation = this.javaClass.getAnnotation(PacketId::class.java) val annotation = this.javaClass.getAnnotation(PacketId::class.java)
idHex = annotation.value idHex = annotation.value.trim()
try { try {
this.writeHex(Protocol.head) this.writeHex(Protocol.head)
...@@ -60,10 +60,19 @@ abstract class ClientPacket : ByteArrayDataOutputStream(), Packet { ...@@ -60,10 +60,19 @@ abstract class ClientPacket : ByteArrayDataOutputStream(), Packet {
return toByteArray() return toByteArray()
} }
open fun getFixedId(): String = when (this.idHex.length) {
0 -> "__ __ __ __"
2 -> this.idHex + " __ __"
5 -> this.idHex + " __"
else -> this.idHex
}
override fun toString(): String { 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 -> it.trySetAccessible(); it.name + "=" + it.get(this).let { value ->
when (value) { when (value) {
null -> null
is ByteArray -> value.toUHexString() is ByteArray -> value.toUHexString()
is UByteArray -> value.toUHexString() is UByteArray -> value.toUHexString()
else -> value.toString() else -> value.toString()
...@@ -144,12 +153,6 @@ fun DataOutputStream.writeTLV0006(qq: Long, password: String, loginTime: Int, lo ...@@ -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 @ExperimentalUnsignedTypes
@TestedSuccessfully @TestedSuccessfully
fun DataOutputStream.writeCRC32() = writeCRC32(getRandomByteArray(16)) fun DataOutputStream.writeCRC32() = writeCRC32(getRandomByteArray(16))
...@@ -209,7 +212,7 @@ fun Int.toLByteArray(): ByteArray = byteArrayOf( ...@@ -209,7 +212,7 @@ fun Int.toLByteArray(): ByteArray = byteArrayOf(
) )
@ExperimentalUnsignedTypes @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()) internal fun md5(str: String): ByteArray = MessageDigest.getInstance("MD5").digest(str.toByteArray())
......
...@@ -42,7 +42,7 @@ class ServerAccountInfoResponsePacket(input: DataInputStream) : ServerPacket(inp ...@@ -42,7 +42,7 @@ class ServerAccountInfoResponsePacket(input: DataInputStream) : ServerPacket(inp
fun decrypt(sessionKey: ByteArray): ServerAccountInfoResponsePacket { fun decrypt(sessionKey: ByteArray): ServerAccountInfoResponsePacket {
this.input goto 14 this.input goto 14
val data = this.input.readAllBytes().let { it.copyOfRange(0, it.size - 1) } 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
...@@ -58,7 +58,7 @@ class ServerSKeyResponsePacket(input: DataInputStream) : ServerPacket(input) { ...@@ -58,7 +58,7 @@ class ServerSKeyResponsePacket(input: DataInputStream) : ServerPacket(input) {
fun decrypt(sessionKey: ByteArray): ServerSKeyResponsePacket { fun decrypt(sessionKey: ByteArray): ServerSKeyResponsePacket {
this.input goto 14 this.input goto 14
val data = this.input.readAllBytes().let { it.copyOfRange(0, it.size - 1) } 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
...@@ -39,12 +39,12 @@ open class ServerEventPacket(input: DataInputStream, val packetId: ByteArray, va ...@@ -39,12 +39,12 @@ open class ServerEventPacket(input: DataInputStream, val packetId: ByteArray, va
//"02 10", "00 12" -> ServerUnknownEventPacket(this.input, packetId, eventIdentity) //"02 10", "00 12" -> ServerUnknownEventPacket(this.input, packetId, eventIdentity)
else -> UnknownServerEventPacket(this.input, packetId, eventIdentity) else -> UnknownServerEventPacket(this.input, packetId, eventIdentity)
} }.setId(this.idHex)
} }
@PacketId("00 17") @PacketId("00 17")
class Encrypted(input: DataInputStream, private val packetId: ByteArray) : ServerPacket(input) { 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)
} }
} }
} }
......
package net.mamoe.mirai.network.packet package net.mamoe.mirai.network.packet
import lombok.Getter
import net.mamoe.mirai.network.packet.action.ServerSendFriendMessageResponsePacket import net.mamoe.mirai.network.packet.action.ServerSendFriendMessageResponsePacket
import net.mamoe.mirai.network.packet.action.ServerSendGroupMessageResponsePacket import net.mamoe.mirai.network.packet.action.ServerSendGroupMessageResponsePacket
import net.mamoe.mirai.network.packet.login.* import net.mamoe.mirai.network.packet.login.*
...@@ -10,6 +11,24 @@ import java.io.DataInputStream ...@@ -10,6 +11,24 @@ import java.io.DataInputStream
* @author Him188moe * @author Him188moe
*/ */
abstract class ServerPacket(val input: DataInputStream) : Packet { 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() { open fun decode() {
...@@ -19,14 +38,12 @@ abstract class ServerPacket(val input: DataInputStream) : Packet { ...@@ -19,14 +38,12 @@ abstract class ServerPacket(val input: DataInputStream) : Packet {
@ExperimentalUnsignedTypes @ExperimentalUnsignedTypes
fun ofByteArray(bytes: ByteArray): ServerPacket { fun ofByteArray(bytes: ByteArray): ServerPacket {
//println("Raw received: ${bytes.toUByteArray().toUHexString()}")
val stream = bytes.dataInputStream() val stream = bytes.dataInputStream()
stream.skip(3) stream.skip(3)
val idHex = stream.readInt().toUHexString(" ")
return when (val idHex = stream.readInt().toHexString(" ")) { return when (idHex) {
"08 25 31 01" -> ServerTouchResponsePacket.Encrypted(ServerTouchResponsePacket.Type.TYPE_08_25_31_01, stream) "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) "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 { ...@@ -37,12 +54,12 @@ abstract class ServerPacket(val input: DataInputStream) : Packet {
else -> { else -> {
MiraiLogger debug ("ServerLoginResponseResendPacketEncrypted: flag=$idHex"); ServerLoginResponseResendPacket.Flag.OTHER MiraiLogger debug ("ServerLoginResponseResendPacketEncrypted: flag=$idHex"); ServerLoginResponseResendPacket.Flag.OTHER
} }
}) }).apply { this.idHex = idHex }
871 -> return ServerLoginResponseVerificationCodeInitPacket.Encrypted(stream) 871 -> return ServerLoginResponseVerificationCodeInitPacket.Encrypted(stream).apply { this.idHex = idHex }
} }
if (bytes.size > 700) { if (bytes.size > 700) {
return ServerLoginResponseSuccessPacket.Encrypted(stream) return ServerLoginResponseSuccessPacket.Encrypted(stream).apply { this.idHex = idHex }
} }
return ServerLoginResponseFailedPacket(when (bytes.size) { return ServerLoginResponseFailedPacket(when (bytes.size) {
...@@ -60,7 +77,7 @@ abstract class ServerPacket(val input: DataInputStream) : Packet { ...@@ -60,7 +77,7 @@ abstract class ServerPacket(val input: DataInputStream) : Packet {
351 -> throw IllegalArgumentException(bytes.size.toString() + " (Illegal package data or Unknown error)")//包数据有误 351 -> throw IllegalArgumentException(bytes.size.toString() + " (Illegal package data or Unknown error)")//包数据有误
else -> throw IllegalArgumentException(bytes.size.toString())*/ else -> throw IllegalArgumentException(bytes.size.toString())*/
}, stream) }, stream).apply { this.idHex = idHex }
} }
"08 28 04 34" -> ServerSessionKeyResponsePacket.Encrypted(stream) "08 28 04 34" -> ServerSessionKeyResponsePacket.Encrypted(stream)
...@@ -85,13 +102,14 @@ abstract class ServerPacket(val input: DataInputStream) : Packet { ...@@ -85,13 +102,14 @@ abstract class ServerPacket(val input: DataInputStream) : Packet {
else -> throw IllegalArgumentException(idHex) else -> throw IllegalArgumentException(idHex)
} }
} }.apply { this.idHex = idHex }
} }
} }
@ExperimentalUnsignedTypes @ExperimentalUnsignedTypes
override fun toString(): String { 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 -> it.trySetAccessible(); it.name + "=" + it.get(this).let { value ->
when (value) { when (value) {
is ByteArray -> value.toUHexString() is ByteArray -> value.toUHexString()
...@@ -102,6 +120,15 @@ abstract class ServerPacket(val input: DataInputStream) : Packet { ...@@ -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 { fun decryptBy(key: ByteArray): DataInputStream {
input.goto(14) input.goto(14)
return DataInputStream(TEA.decrypt(input.readAllBytes().let { it.copyOfRange(0, it.size - 1) }, key).inputStream()) return DataInputStream(TEA.decrypt(input.readAllBytes().let { it.copyOfRange(0, it.size - 1) }, key).inputStream())
......
...@@ -107,7 +107,7 @@ class ServerSessionKeyResponsePacket(inputStream: DataInputStream, private val d ...@@ -107,7 +107,7 @@ class ServerSessionKeyResponsePacket(inputStream: DataInputStream, private val d
fun decrypt(sessionResponseDecryptionKey: ByteArray): ServerSessionKeyResponsePacket { fun decrypt(sessionResponseDecryptionKey: ByteArray): ServerSessionKeyResponsePacket {
this.input goto 14 this.input goto 14
val data = this.input.readAllBytes().let { it.copyOfRange(0, it.size - 1) } 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
...@@ -13,8 +13,9 @@ import java.io.IOException ...@@ -13,8 +13,9 @@ import java.io.IOException
* *
* @author Him188moe * @author Him188moe
*/ */
@PacketId("08 25 31 0?")
class ServerTouchResponsePacket(inputStream: DataInputStream) : ServerPacket(inputStream) { class ServerTouchResponsePacket(inputStream: DataInputStream) : ServerPacket(inputStream) {
var serverIP: String? = null; var serverIP: String? = null
var loginTime: Int = 0 var loginTime: Int = 0
lateinit var loginIP: String lateinit var loginIP: String
...@@ -54,7 +55,7 @@ class ServerTouchResponsePacket(inputStream: DataInputStream) : ServerPacket(inp ...@@ -54,7 +55,7 @@ class ServerTouchResponsePacket(inputStream: DataInputStream) : ServerPacket(inp
fun decrypt(): ServerTouchResponsePacket = ServerTouchResponsePacket(decryptBy(when (type) { fun decrypt(): ServerTouchResponsePacket = ServerTouchResponsePacket(decryptBy(when (type) {
Type.TYPE_08_25_31_02 -> Protocol.redirectionKey.hexToBytes() Type.TYPE_08_25_31_02 -> Protocol.redirectionKey.hexToBytes()
Type.TYPE_08_25_31_01 -> Protocol.key0825.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() { ...@@ -83,7 +84,6 @@ class ClientTouchPacket(val qq: Long, val serverIp: String) : ClientPacket() {
this.writeIP(serverIp); 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("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) this.writeHex(Protocol.publicKey)
println(super.toUByteArray().toUHexString())
return super.toByteArray() return super.toByteArray()
} }
}.toByteArray())) }.toByteArray()))
......
package net.mamoe.mirai.network.packet package net.mamoe.mirai.network.packet
import net.mamoe.mirai.network.Protocol import net.mamoe.mirai.network.Protocol
import net.mamoe.mirai.utils.MiraiLogger import net.mamoe.mirai.utils.*
import net.mamoe.mirai.utils.TEA
import net.mamoe.mirai.utils.TestedSuccessfully
import net.mamoe.mirai.utils.hexToBytes
import java.io.DataInputStream import java.io.DataInputStream
/** /**
...@@ -13,7 +10,7 @@ import java.io.DataInputStream ...@@ -13,7 +10,7 @@ import java.io.DataInputStream
@ExperimentalUnsignedTypes @ExperimentalUnsignedTypes
@PacketId("00 BA 31") @PacketId("00 BA 31")
class ClientVerificationCodeTransmissionRequestPacket( class ClientVerificationCodeTransmissionRequestPacket(
private val verificationSessionId: Int, private val packetId: Int,
private val qq: Long, private val qq: Long,
private val token0825: ByteArray, private val token0825: ByteArray,
private val verificationSequence: Int, private val verificationSequence: Int,
...@@ -21,10 +18,10 @@ class ClientVerificationCodeTransmissionRequestPacket( ...@@ -21,10 +18,10 @@ class ClientVerificationCodeTransmissionRequestPacket(
) : ClientPacket() { ) : ClientPacket() {
@TestedSuccessfully @TestedSuccessfully
override fun encode() { override fun encode() {
MiraiLogger debug "verificationSessionId=$verificationSessionId" MiraiLogger debug "packetId=$packetId"
MiraiLogger debug "verificationSequence=$verificationSequence" MiraiLogger debug "verificationSequence=$verificationSequence"
this.writeByte(verificationSessionId)//part of packet id this.writeByte(packetId)//part of packet id
this.writeQQ(qq) this.writeQQ(qq)
this.writeHex(Protocol.fixVer) this.writeHex(Protocol.fixVer)
...@@ -52,14 +49,18 @@ class ClientVerificationCodeTransmissionRequestPacket( ...@@ -52,14 +49,18 @@ class ClientVerificationCodeTransmissionRequestPacket(
@PacketId("00 BA 32") @PacketId("00 BA 32")
@ExperimentalUnsignedTypes @ExperimentalUnsignedTypes
class ClientVerificationCodeSubmitPacket( class ClientVerificationCodeSubmitPacket(
private val packetId: Int,
private val qq: Long, private val qq: Long,
private val token0825: ByteArray, private val token0825: ByteArray,
private val verificationSessionId: Int,
private val verificationCode: String, private val verificationCode: String,
private val verificationToken: ByteArray private val verificationToken: ByteArray
) : ClientPacket() { ) : ClientPacket() {
init {
require(verificationCode.length == 4) { "verificationCode.length must == 4" }
}
override fun encode() { override fun encode() {
this.writeByte(verificationSessionId)//part of packet id this.writeByte(packetId)//part of packet id
this.writeQQ(qq) this.writeQQ(qq)
this.writeHex(Protocol.fixVer) this.writeHex(Protocol.fixVer)
...@@ -69,17 +70,47 @@ class ClientVerificationCodeSubmitPacket( ...@@ -69,17 +70,47 @@ class ClientVerificationCodeSubmitPacket(
it.writeHex(Protocol.constantData2) it.writeHex(Protocol.constantData2)
it.writeHex("01 00 38") it.writeHex("01 00 38")
it.write(token0825) it.write(token0825)
it.writeHex("01 03 00 19") it.writeHex("01 03")
it.writeShort(25)
it.writeHex(Protocol.publicKey) it.writeHex(Protocol.publicKey)
it.writeHex("14 00 05 00 00 00 00 00 04") it.writeHex("14 00 05 00 00 00 00 00 04")
it.write(verificationCode.substring(0..3).toByteArray()) it.write(verificationCode.toUpperCase().toByteArray())
it.writeByte(0x38) it.writeHex("00 38")
it.write(verificationToken) it.write(verificationToken)
it.writeHex("00 10") it.writeHex("00 10")
it.writeHex(Protocol.key00BAFix) 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( ...@@ -89,12 +120,12 @@ class ClientVerificationCodeSubmitPacket(
@PacketId("00 BA 31") @PacketId("00 BA 31")
@ExperimentalUnsignedTypes @ExperimentalUnsignedTypes
class ClientVerificationCodeRefreshPacket( class ClientVerificationCodeRefreshPacket(
private val packetId: Int,
private val qq: Long, private val qq: Long,
private val token0825: ByteArray, private val token0825: ByteArray
private val verificationSessionId: Int
) : ClientPacket() { ) : ClientPacket() {
override fun encode() { override fun encode() {
this.writeByte(verificationSessionId)//part of packet id this.writeByte(packetId)//part of packet id
this.writeQQ(qq) this.writeQQ(qq)
this.writeHex(Protocol.fixVer) this.writeHex(Protocol.fixVer)
...@@ -109,15 +140,19 @@ class ClientVerificationCodeRefreshPacket( ...@@ -109,15 +140,19 @@ class ClientVerificationCodeRefreshPacket(
it.writeHex("13 00 05 00 00 00 00 00 00 00 00 10") it.writeHex("13 00 05 00 00 00 00 00 00 00 00 10")
it.writeHex(Protocol.key00BAFix) 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 ...@@ -128,42 +163,43 @@ class ServerVerificationCodeWrongPacket(input: DataInputStream, dataSize: Int, p
@PacketId("00 BA 31") @PacketId("00 BA 31")
open class ServerVerificationCodeTransmissionPacket(input: DataInputStream, private val dataSize: Int, private val packetId: ByteArray) : ServerVerificationCodePacket(input) { 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 lateinit var verificationToken: ByteArray//56bytes
var transmissionCompleted: Boolean = false//验证码是否已经传输完成 var transmissionCompleted: Boolean = false//验证码是否已经传输完成
lateinit var token00BA: ByteArray//40 bytes lateinit var token00BA: ByteArray//40 bytes
var verificationSessionId: Int = 0 var packetIdLast: Int = 0
@ExperimentalUnsignedTypes @ExperimentalUnsignedTypes
override fun decode() { override fun decode() {
this.verificationToken = this.input.readNBytesAt(10, 56) this.verificationToken = this.input.readNBytesAt(10, 56)
val length = this.input.readShortAt(66) val length = this.input.readShortAt(66)
this.verificationCodePartN = this.input.readNBytes(length) this.captchaSectionN = this.input.readNBytes(length)
this.input.skip(1) this.input.skip(1)
val byte = this.input.readByteAt(69 + length).toInt() val byte = this.input.readByteAt(69 + length).toInt()
this.transmissionCompleted = byte == 0 this.transmissionCompleted = byte == 0
this.token00BA = this.input.readNBytesAt(dataSize - 56 - 2, 40) this.token00BA = this.input.readNBytesAt(dataSize - 56 - 2, 40)
this.verificationSessionId = packetId[3].toInt() this.packetIdLast = packetId[3].toInt()
} }
} }
/*
fun main() { 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 { ServerVerificationCodeTransmissionPacket(data.dataInputStream(), data.size, "00 BA 31 01".hexToBytes()).let {
it.decode() it.decode()
println(it.toString()) println(it.toString())
} }
} }*/
/** /**
* 验证码正确 * 验证码正确
* *
* @author Him188moe * @author Him188moe
*/ */
@PacketId("00 BA 32")
class ServerVerificationCodeCorrectPacket(input: DataInputStream) : ServerVerificationCodePacket(input) { class ServerVerificationCodeCorrectPacket(input: DataInputStream) : ServerVerificationCodePacket(input) {
lateinit var token00BA: ByteArray//56 bytes lateinit var token00BA: ByteArray//56 bytes
...@@ -174,23 +210,32 @@ class ServerVerificationCodeCorrectPacket(input: DataInputStream) : ServerVerifi ...@@ -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) { abstract class ServerVerificationCodePacket(input: DataInputStream) : ServerPacket(input) {
@PacketId("00 BA") @PacketId("00 BA")
class Encrypted(input: DataInputStream, val idHex: String) : ServerPacket(input) { class Encrypted(input: DataInputStream, private val id: String) : ServerPacket(input) {
@ExperimentalUnsignedTypes @ExperimentalUnsignedTypes
fun decrypt(): ServerVerificationCodePacket { fun decrypt(): ServerVerificationCodePacket {
this.input goto 14 this.input goto 14
val data = TEA.decrypt(this.input.readAllBytes().cutTail(1), Protocol.key00BA.hexToBytes()) val data = TEA.decrypt(this.input.readAllBytes().cutTail(1), Protocol.key00BA.hexToBytes())
if (idHex.startsWith("00 BA 32")) { if (id.startsWith("00 BA 32")) {
if (data.size == 95) { return when (data.size) {
ServerVerificationCodeCorrectPacket(data.dataInputStream()) 66,
} else { 95 -> ServerVerificationCodeCorrectPacket(data.dataInputStream())
return ServerVerificationCodeWrongPacket(data.dataInputStream(), data.size, this.input.readNBytesAt(3, 4)) //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)
} }
} }
...@@ -2,7 +2,10 @@ package net.mamoe.mirai.network.packet.login ...@@ -2,7 +2,10 @@ package net.mamoe.mirai.network.packet.login
import net.mamoe.mirai.network.Protocol import net.mamoe.mirai.network.Protocol
import net.mamoe.mirai.network.packet.* 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 import java.io.DataOutputStream
/** /**
...@@ -32,7 +35,6 @@ class ClientPasswordSubmissionPacket( ...@@ -32,7 +35,6 @@ class ClientPasswordSubmissionPacket(
this.encryptAndWrite(Protocol.shareKey.hexToBytes()) { this.encryptAndWrite(Protocol.shareKey.hexToBytes()) {
it.writePart1(qq, password, loginTime, loginIP, tgtgtKey, token0825) it.writePart1(qq, password, loginTime, loginIP, tgtgtKey, token0825)
it.writePart2() it.writePart2()
println(it.toByteArray().toUHexString())
} }
} }
} }
......
...@@ -53,7 +53,7 @@ class ServerLoginResponseSuccessPacket(input: DataInputStream) : ServerPacket(in ...@@ -53,7 +53,7 @@ class ServerLoginResponseSuccessPacket(input: DataInputStream) : ServerPacket(in
@ExperimentalUnsignedTypes @ExperimentalUnsignedTypes
fun decrypt(tgtgtKey: ByteArray): ServerLoginResponseSuccessPacket { fun decrypt(tgtgtKey: ByteArray): ServerLoginResponseSuccessPacket {
input goto 14 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)
} }
} }
......
...@@ -44,6 +44,6 @@ class ServerLoginResponseResendPacket(input: DataInputStream, val flag: Flag) : ...@@ -44,6 +44,6 @@ class ServerLoginResponseResendPacket(input: DataInputStream, val flag: Flag) :
class Encrypted(input: DataInputStream, private val flag: Flag) : ServerPacket(input) { class Encrypted(input: DataInputStream, private val flag: Flag) : ServerPacket(input) {
@TestedSuccessfully @TestedSuccessfully
fun decrypt(tgtgtKey: ByteArray): ServerLoginResponseResendPacket = ServerLoginResponseResendPacket(decryptBy(tgtgtKey), flag) fun decrypt(tgtgtKey: ByteArray): ServerLoginResponseResendPacket = ServerLoginResponseResendPacket(decryptBy(tgtgtKey), flag).setId(this.idHex)
} }
} }
...@@ -43,7 +43,7 @@ class ServerLoginResponseVerificationCodeInitPacket(input: DataInputStream, priv ...@@ -43,7 +43,7 @@ class ServerLoginResponseVerificationCodeInitPacket(input: DataInputStream, priv
fun decrypt(): ServerLoginResponseVerificationCodeInitPacket { fun decrypt(): ServerLoginResponseVerificationCodeInitPacket {
this.input goto 14 this.input goto 14
val data = TEA.CRYPTOR_SHARE_KEY.decrypt(this.input.readAllBytes().cutTail(1)); 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)
} }
} }
} }
......
package net.mamoe.mirai.utils package net.mamoe.mirai.utils
import net.mamoe.mirai.Robot
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
...@@ -34,6 +35,31 @@ object MiraiLogger { ...@@ -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) fun Any.logInfo() = MiraiLogger.info(this)
......
...@@ -60,9 +60,6 @@ fun String.hexToShort(): Short = hexToBytes().let { ((it[1].toInt() shl 8) + it[ ...@@ -60,9 +60,6 @@ fun String.hexToShort(): Short = hexToBytes().let { ((it[1].toInt() shl 8) + it[
@ExperimentalUnsignedTypes @ExperimentalUnsignedTypes
fun String.hexToInt(): Int = hexToBytes().let { ((it[0].toInt() shl 24) + (it[1].toInt() shl 16) + (it[2].toInt() shl 8) + it[3]) } 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 class ByteArrayDataOutputStream : DataOutputStream(ByteArrayOutputStream()) {
open fun toByteArray(): ByteArray = (out as ByteArrayOutputStream).toByteArray() open fun toByteArray(): ByteArray = (out as ByteArrayOutputStream).toByteArray()
@ExperimentalUnsignedTypes @ExperimentalUnsignedTypes
......
...@@ -51,9 +51,9 @@ public class HexComparator { ...@@ -51,9 +51,9 @@ public class HexComparator {
@SuppressWarnings({"unused", "NonAsciiCharacters"}) @SuppressWarnings({"unused", "NonAsciiCharacters"})
private static class TestConsts { private static class TestConsts {
private static final String 牛逼 = UtilsKt.toUHexString("牛逼".getBytes(), " "); private static final String 牛逼 = UtilsKt.toUHexString("牛逼".getBytes(), " ");
private static final String _1994701021 = ClientPacketKt.toHexString(1994701021, " "); private static final String _1994701021 = ClientPacketKt.toUHexString(1994701021, " ");
private static final String _1040400290 = ClientPacketKt.toHexString(1040400290, " "); private static final String _1040400290 = ClientPacketKt.toUHexString(1040400290, " ");
private static final String _580266363 = ClientPacketKt.toHexString(580266363, " "); private static final String _580266363 = ClientPacketKt.toUHexString(580266363, " ");
} }
private final List<Match> matches = new LinkedList<>(); private final List<Match> matches = new LinkedList<>();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment