submodule对gitea不管用,所以直接拉了一份拉格兰
This commit is contained in:
14
Lagrange.Core/Lagrange.Core.Test/Lagrange.Core.Test.csproj
Normal file
14
Lagrange.Core/Lagrange.Core.Test/Lagrange.Core.Test.csproj
Normal file
@@ -0,0 +1,14 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Lagrange.Core\Lagrange.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
13
Lagrange.Core/Lagrange.Core.Test/Program.cs
Normal file
13
Lagrange.Core/Lagrange.Core.Test/Program.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using Lagrange.Core.Test.Tests;
|
||||
|
||||
namespace Lagrange.Core.Test;
|
||||
|
||||
internal static class Program
|
||||
{
|
||||
public static async Task Main(string[] args)
|
||||
{
|
||||
// BenchmarkRunner.Run<ProtoBufTest>(new DebugBuildConfig());
|
||||
await new NTLoginTest().LoginByPassword();
|
||||
// await new WtLoginTest().FetchQrCode();
|
||||
}
|
||||
}
|
||||
24
Lagrange.Core/Lagrange.Core.Test/Protobuf.cs
Normal file
24
Lagrange.Core/Lagrange.Core.Test/Protobuf.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using Lagrange.Core.Internal.Packets.Login.Ecdh;
|
||||
using Lagrange.Core.Utility.Extension;
|
||||
using ProtoBuf;
|
||||
|
||||
namespace Lagrange.Core.Test;
|
||||
|
||||
public class Protobuf
|
||||
{
|
||||
public void Test()
|
||||
{
|
||||
|
||||
var test = new SsoKeyExchange()
|
||||
{
|
||||
PubKey = new byte[] { 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11 },
|
||||
GcmCalc2 = new byte[] { 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11 },
|
||||
GcmCalc1 = new byte[] { 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11 },
|
||||
Timestamp = 23456789,
|
||||
Type = 1
|
||||
};
|
||||
using var stream = new MemoryStream();
|
||||
Serializer.Serialize(stream, test);
|
||||
Console.WriteLine(stream.ToArray().Hex(false, true));
|
||||
}
|
||||
}
|
||||
32
Lagrange.Core/Lagrange.Core.Test/Tests/BinaryTest.cs
Normal file
32
Lagrange.Core/Lagrange.Core.Test/Tests/BinaryTest.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using Lagrange.Core.Utility.Binary;
|
||||
using Lagrange.Core.Utility.Extension;
|
||||
|
||||
namespace Lagrange.Core.Test.Tests;
|
||||
|
||||
public class BinaryTest
|
||||
{
|
||||
public class Binary
|
||||
{
|
||||
[BinaryProperty] public uint Value { get; set; } = 114514;
|
||||
|
||||
[BinaryProperty] public ulong Value2 { get; set; } = 1919810;
|
||||
}
|
||||
|
||||
public void Test()
|
||||
{
|
||||
var binary = new Binary();
|
||||
var bytes = BinarySerializer.Serialize(binary);
|
||||
Console.WriteLine(bytes.ToArray().Hex());
|
||||
Console.WriteLine(bytes.Length);
|
||||
|
||||
var binary2 = new BinaryPacket();
|
||||
binary2.WriteUint(114514);
|
||||
binary2.WriteUlong(1919810);
|
||||
Console.WriteLine(binary2.ToArray().Hex());
|
||||
|
||||
var newPacket = new BinaryPacket(bytes.ToArray());
|
||||
var binary3 = newPacket.Deserialize<Binary>();
|
||||
Console.WriteLine(binary3.Value);
|
||||
Console.WriteLine(binary3.Value2);
|
||||
}
|
||||
}
|
||||
82
Lagrange.Core/Lagrange.Core.Test/Tests/EcdhTest.cs
Normal file
82
Lagrange.Core/Lagrange.Core.Test/Tests/EcdhTest.cs
Normal file
@@ -0,0 +1,82 @@
|
||||
using Lagrange.Core.Utility.Crypto.Provider.Ecdh;
|
||||
|
||||
namespace Lagrange.Core.Test.Tests;
|
||||
|
||||
public class EcdhTest
|
||||
{
|
||||
public static void Test()
|
||||
{
|
||||
{
|
||||
var uncompressedPublicKey = new byte[]
|
||||
{
|
||||
0x04,
|
||||
0xEB, 0xCA, 0x94, 0xD7, 0x33, 0xE3, 0x99, 0xB2,
|
||||
0xDB, 0x96, 0xEA, 0xCD, 0xD3, 0xF6, 0x9A, 0x8B,
|
||||
0xB0, 0xF7, 0x42, 0x24, 0xE2, 0xB4, 0x4E, 0x33,
|
||||
0x57, 0x81, 0x22, 0x11, 0xD2, 0xE6, 0x2E, 0xFB,
|
||||
0xC9, 0x1B, 0xB5, 0x53, 0x09, 0x8E, 0x25, 0xE3,
|
||||
0x3A, 0x79, 0x9A, 0xDC, 0x7F, 0x76, 0xFE, 0xB2,
|
||||
0x08, 0xDA, 0x7C, 0x65, 0x22, 0xCD, 0xB0, 0x71,
|
||||
0x9A, 0x30, 0x51, 0x80, 0xCC, 0x54, 0xA8, 0x2E
|
||||
};
|
||||
var compressedPublicKey = new byte[]
|
||||
{
|
||||
0x02,
|
||||
0xEB, 0xCA, 0x94, 0xD7, 0x33, 0xE3, 0x99, 0xB2,
|
||||
0xDB, 0x96, 0xEA, 0xCD, 0xD3, 0xF6, 0x9A, 0x8B,
|
||||
0xB0, 0xF7, 0x42, 0x24, 0xE2, 0xB4, 0x4E, 0x33,
|
||||
0x57, 0x81, 0x22, 0x11, 0xD2, 0xE6, 0x2E, 0xFB
|
||||
};
|
||||
|
||||
EcdhProvider ecdhProvider = new EcdhProvider(EllipticCurve.Prime256V1);
|
||||
|
||||
var unpacked1 = ecdhProvider.UnpackPublic(uncompressedPublicKey);
|
||||
var unpacked2 = ecdhProvider.UnpackPublic(compressedPublicKey);
|
||||
|
||||
if (unpacked1.X == unpacked2.X && unpacked1.Y == unpacked2.Y)
|
||||
{
|
||||
Console.WriteLine("UnpackPublic() works correctly");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("UnpackPublic() does not work correctly");
|
||||
}
|
||||
}
|
||||
{
|
||||
// from https://github.com/KonataDev/Konata.Core/blob/develop/Konata.Core.Test/UtilTest/EcdhTest.cs
|
||||
var uncompressedPublicKey = new byte[]
|
||||
{
|
||||
0x04,
|
||||
0xD5, 0xCF, 0xB0, 0x2D, 0x5D, 0x4F, 0xCA, 0x2C,
|
||||
0x84, 0xF6, 0xF1, 0x29, 0x4B, 0x45, 0x5B, 0xAB,
|
||||
0x4C, 0x96, 0x98, 0xDD, 0x57, 0x2B, 0xF8, 0x63,
|
||||
0x82, 0xA9, 0xDA, 0xF8, 0xAD, 0xE9, 0xD4, 0x5A,
|
||||
0x57, 0xDE, 0x14, 0x04, 0xFA, 0x5D, 0x41, 0x29,
|
||||
0x1E, 0x0A, 0x56, 0xCB, 0x45, 0x08, 0xD3, 0x2F
|
||||
};
|
||||
var compressedPublicKey = new byte[]
|
||||
{
|
||||
0x03,
|
||||
0xD5, 0xCF, 0xB0, 0x2D, 0x5D, 0x4F, 0xCA, 0x2C,
|
||||
0x84, 0xF6, 0xF1, 0x29, 0x4B, 0x45, 0x5B, 0xAB,
|
||||
0x4C, 0x96, 0x98, 0xDD, 0x57, 0x2B, 0xF8, 0x63
|
||||
};
|
||||
|
||||
EcdhProvider ecdhProvider = new EcdhProvider(EllipticCurve.Secp192K1);
|
||||
|
||||
var unpacked1 = ecdhProvider.UnpackPublic(uncompressedPublicKey);
|
||||
var unpacked2 = ecdhProvider.UnpackPublic(compressedPublicKey);
|
||||
|
||||
if (unpacked1.X == unpacked2.X && unpacked1.Y == unpacked2.Y)
|
||||
{
|
||||
Console.WriteLine("UnpackPublic() works correctly");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("UnpackPublic() does not work correctly");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
65
Lagrange.Core/Lagrange.Core.Test/Tests/NTLoginTest.cs
Normal file
65
Lagrange.Core/Lagrange.Core.Test/Tests/NTLoginTest.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
using Lagrange.Core.Common;
|
||||
using Lagrange.Core.Common.Interface;
|
||||
using Lagrange.Core.Common.Interface.Api;
|
||||
using Lagrange.Core.Message;
|
||||
|
||||
namespace Lagrange.Core.Test.Tests;
|
||||
|
||||
// ReSharper disable once InconsistentNaming
|
||||
|
||||
public class NTLoginTest
|
||||
{
|
||||
public async Task LoginByPassword()
|
||||
{
|
||||
var deviceInfo = WtLoginTest.GetDeviceInfo();
|
||||
var keyStore = WtLoginTest.LoadKeystore();
|
||||
|
||||
if (keyStore == null)
|
||||
{
|
||||
Console.WriteLine("Please login by QrCode first");
|
||||
return;
|
||||
}
|
||||
|
||||
var bot = BotFactory.Create(new BotConfig()
|
||||
{
|
||||
UseIPv6Network = false,
|
||||
GetOptimumServer = true,
|
||||
AutoReconnect = true,
|
||||
Protocol = Protocols.Linux
|
||||
}, deviceInfo, keyStore);
|
||||
|
||||
bot.Invoker.OnBotLogEvent += (_, @event) =>
|
||||
{
|
||||
Utility.Console.ChangeColorByTitle(@event.Level);
|
||||
Console.WriteLine(@event.ToString());
|
||||
};
|
||||
|
||||
bot.Invoker.OnBotOnlineEvent += (_, @event) =>
|
||||
{
|
||||
Console.WriteLine(@event.ToString());
|
||||
WtLoginTest.SaveKeystore(bot.UpdateKeystore());
|
||||
};
|
||||
|
||||
bot.Invoker.OnBotCaptchaEvent += (_, @event) =>
|
||||
{
|
||||
Console.WriteLine(@event.ToString());
|
||||
var captcha = Console.ReadLine();
|
||||
var randStr = Console.ReadLine();
|
||||
if (captcha != null && randStr != null) bot.SubmitCaptcha(captcha, randStr);
|
||||
};
|
||||
|
||||
bot.Invoker.OnGroupInvitationReceived += (_, @event) =>
|
||||
{
|
||||
Console.WriteLine(@event.ToString());
|
||||
};
|
||||
|
||||
await bot.LoginByPassword();
|
||||
|
||||
var friendChain = MessageBuilder.Group(411240674)
|
||||
.Text("This is the friend message sent by Lagrange.Core")
|
||||
.Mention(1925648680);
|
||||
await bot.SendMessage(friendChain.Build());
|
||||
|
||||
await Task.Delay(1000);
|
||||
}
|
||||
}
|
||||
79
Lagrange.Core/Lagrange.Core.Test/Tests/WtLoginTest.cs
Normal file
79
Lagrange.Core/Lagrange.Core.Test/Tests/WtLoginTest.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using Lagrange.Core.Common;
|
||||
using Lagrange.Core.Common.Interface;
|
||||
using Lagrange.Core.Common.Interface.Api;
|
||||
|
||||
namespace Lagrange.Core.Test.Tests;
|
||||
|
||||
public class WtLoginTest
|
||||
{
|
||||
public async Task FetchQrCode()
|
||||
{
|
||||
var deviceInfo = GetDeviceInfo();
|
||||
var keyStore = LoadKeystore() ?? new BotKeystore();
|
||||
|
||||
var bot = BotFactory.Create(new BotConfig
|
||||
{
|
||||
UseIPv6Network = false,
|
||||
GetOptimumServer = true,
|
||||
AutoReconnect = true,
|
||||
Protocol = Protocols.Linux
|
||||
}, deviceInfo, keyStore);
|
||||
|
||||
bot.Invoker.OnBotLogEvent += (context, @event) =>
|
||||
{
|
||||
Utility.Console.ChangeColorByTitle(@event.Level);
|
||||
Console.WriteLine(@event.ToString());
|
||||
};
|
||||
|
||||
bot.Invoker.OnBotOnlineEvent += (context, @event) =>
|
||||
{
|
||||
Console.WriteLine(@event.ToString());
|
||||
SaveKeystore(bot.UpdateKeystore());
|
||||
};
|
||||
|
||||
var qrCode = await bot.FetchQrCode();
|
||||
if (qrCode != null)
|
||||
{
|
||||
await File.WriteAllBytesAsync("qr.png", qrCode.Value.QrCode);
|
||||
await bot.LoginByQrCode();
|
||||
}
|
||||
}
|
||||
|
||||
public static BotDeviceInfo GetDeviceInfo()
|
||||
{
|
||||
if (File.Exists("Test/DeviceInfo.json"))
|
||||
{
|
||||
var info = JsonSerializer.Deserialize<BotDeviceInfo>(File.ReadAllText("Test/DeviceInfo.json"));
|
||||
if (info != null) return info;
|
||||
|
||||
info = BotDeviceInfo.GenerateInfo();
|
||||
File.WriteAllText("Test/DeviceInfo.json", JsonSerializer.Serialize(info));
|
||||
return info;
|
||||
}
|
||||
|
||||
var deviceInfo = BotDeviceInfo.GenerateInfo();
|
||||
File.WriteAllText("Test/DeviceInfo.json", JsonSerializer.Serialize(deviceInfo));
|
||||
return deviceInfo;
|
||||
}
|
||||
|
||||
public static void SaveKeystore(BotKeystore keystore) =>
|
||||
File.WriteAllText("Test/Keystore.json", JsonSerializer.Serialize(keystore));
|
||||
|
||||
public static BotKeystore? LoadKeystore()
|
||||
{
|
||||
try
|
||||
{
|
||||
var text = File.ReadAllText("Test/Keystore.json");
|
||||
return JsonSerializer.Deserialize<BotKeystore>(text, new JsonSerializerOptions()
|
||||
{
|
||||
ReferenceHandler = ReferenceHandler.Preserve
|
||||
});
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
16
Lagrange.Core/Lagrange.Core.Test/Utility/Console.cs
Normal file
16
Lagrange.Core/Lagrange.Core.Test/Utility/Console.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using Lagrange.Core.Event.EventArg;
|
||||
|
||||
namespace Lagrange.Core.Test.Utility;
|
||||
|
||||
public static class Console
|
||||
{
|
||||
public static void ChangeColorByTitle(this LogLevel level) => System.Console.ForegroundColor = level switch
|
||||
{
|
||||
LogLevel.Debug => ConsoleColor.White,
|
||||
LogLevel.Verbose => ConsoleColor.DarkGray,
|
||||
LogLevel.Information => ConsoleColor.Blue,
|
||||
LogLevel.Warning => ConsoleColor.Yellow,
|
||||
LogLevel.Fatal => ConsoleColor.Red,
|
||||
_ => System.Console.ForegroundColor
|
||||
};
|
||||
}
|
||||
61
Lagrange.Core/Lagrange.Core.Test/Utility/ProtoGen.cs
Normal file
61
Lagrange.Core/Lagrange.Core.Test/Utility/ProtoGen.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using ProtoBuf;
|
||||
|
||||
namespace Lagrange.Core.Test.Utility;
|
||||
|
||||
internal static class ProtoGen
|
||||
{
|
||||
public static void GenerateProtoFiles()
|
||||
{
|
||||
var assembly = typeof(Lagrange.Core.Utility.ServiceInjector).Assembly;
|
||||
var types = assembly.GetTypes();
|
||||
var sb = new StringBuilder();
|
||||
|
||||
sb.AppendLine("syntax = \"proto3\";");
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("package Lagrange.Core;");
|
||||
|
||||
foreach (var type in types)
|
||||
{
|
||||
if (type.Namespace?.StartsWith("Lagrange.Core.Internal.Packets") != true) continue;
|
||||
|
||||
sb.AppendLine($"message {type.Name} {{");
|
||||
var properties = type.GetProperties();
|
||||
foreach (var property in properties)
|
||||
{
|
||||
string typeString = ParseType(property.PropertyType);
|
||||
sb.AppendLine($" {GetLastToken(typeString, '.')} {property.Name} = {property.GetCustomAttribute<ProtoMemberAttribute>()?.Tag};");
|
||||
}
|
||||
sb.AppendLine("}");
|
||||
sb.AppendLine();
|
||||
}
|
||||
|
||||
string proto = sb.ToString();
|
||||
|
||||
File.WriteAllText("packets.proto", proto);
|
||||
}
|
||||
|
||||
private static string ParseType(Type type)
|
||||
{
|
||||
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>))
|
||||
{
|
||||
return $"repeated {ParseType(type.GetGenericArguments()[0])}";
|
||||
}
|
||||
|
||||
return type.ToString() switch
|
||||
{
|
||||
"System.UInt64" => "varint",
|
||||
"System.UInt32" => "varint",
|
||||
"System.UInt16" => "varint",
|
||||
"System.Int64" => "varint",
|
||||
"System.Int32" => "varint",
|
||||
"System.String" => "string",
|
||||
"System.Boolean" => "bool",
|
||||
"System.Byte[]" => "bytes",
|
||||
_ => type.ToString()
|
||||
};
|
||||
}
|
||||
|
||||
private static string GetLastToken(string str, char separator) => str.Split(separator)[^1];
|
||||
}
|
||||
35
Lagrange.Core/Lagrange.Core.Test/Utility/Tlv.cs
Normal file
35
Lagrange.Core/Lagrange.Core.Test/Utility/Tlv.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using System.Text;
|
||||
using Lagrange.Core.Utility.Extension;
|
||||
using static Lagrange.Core.Utility.Binary.BitConverter;
|
||||
|
||||
namespace Lagrange.Core.Test.Utility;
|
||||
|
||||
public static class Tlv
|
||||
{
|
||||
public static Dictionary<string, string> GetTlvDictionary(byte[] tlvs, bool isCommand = true)
|
||||
{
|
||||
var result = new Dictionary<string, string>();
|
||||
|
||||
using var reader = new BinaryReader(new MemoryStream(tlvs));
|
||||
|
||||
ushort command;
|
||||
if (isCommand)
|
||||
{
|
||||
command = ToUInt16(reader.ReadBytes(2), false);
|
||||
}
|
||||
|
||||
ushort tlvCount = ToUInt16(reader.ReadBytes(2), false);
|
||||
|
||||
for (int i = 0; i < tlvCount; i++)
|
||||
{
|
||||
ushort tlvTag = ToUInt16(reader.ReadBytes(2), false);
|
||||
ushort tlvLength = ToUInt16(reader.ReadBytes(2), false);
|
||||
byte[] tlvValue = reader.ReadBytes(tlvLength);
|
||||
|
||||
result.Add($"0x{tlvTag:X} {tlvLength}", tlvValue.Hex());
|
||||
result.Add($"0x{tlvTag:X} UTF8 {tlvLength}", Encoding.UTF8.GetString(tlvValue));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user