Merge branch 'main' into feat-website

This commit is contained in:
luooooob 2023-10-17 13:22:34 +08:00 committed by GitHub
commit 6590d75bfb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 184 additions and 125 deletions

17
.gitignore vendored
View File

@ -1,13 +1,22 @@
# .net build artiifacts
bin/
obj/
/packages/
riderModule.iml
/_ReSharper.Caches/
Lagrange.Core/Utility/Crypto/Provider/Dandelion/*.cs
.DS_Store
# vscode files
.vscode/
# rider files
.idea/
*.DotSettings.user
riderModule.iml
/_ReSharper.Caches/
.DS_Store
docs/node_modules
docs/.vitepress/dist
docs/.vitepress/cache
docs/api
docs/api

View File

@ -36,7 +36,7 @@ public class WtLoginTest
var qrCode = await bot.FetchQrCode();
if (qrCode != null)
{
await File.WriteAllBytesAsync("qr.png", qrCode);
await File.WriteAllBytesAsync("qr.png", qrCode.Value.QrCode);
await bot.LoginByQrCode();
}
}

View File

@ -8,6 +8,10 @@ public class BotContext : IDisposable
{
public readonly EventInvoker Invoker;
public uint BotUin => ContextCollection.Keystore.Uin;
public string? BotName => ContextCollection.Keystore.Info?.Name;
internal readonly Utility.TaskScheduler Scheduler;
internal readonly ContextCollection ContextCollection;

View File

@ -7,9 +7,9 @@ public static class BotExt
/// <summary>
/// Fetch the qrcode for QRCode Login
/// </summary>
/// <returns>the byte of QRCode, usually in the form of PNG</returns>
public static async Task<byte[]?> FetchQrCode(this BotContext bot)
=> await bot.ContextCollection.Business.WtExchangeLogic.FetchQrCode();
/// <returns>return url and qrcode image in PNG format</returns>
public static Task<(string Url, byte[] QrCode)?> FetchQrCode(this BotContext bot)
=> bot.ContextCollection.Business.WtExchangeLogic.FetchQrCode();
/// <summary>
/// Use this method to login by QrCode, you should call <see cref="FetchQrCode"/> first
@ -20,8 +20,8 @@ public static class BotExt
/// <summary>
/// Use this method to login by password, EasyLogin may be preformed if there is sig in <see cref="BotKeystore"/>
/// </summary>
public static async Task<bool> LoginByPassword(this BotContext bot)
=> await bot.ContextCollection.Business.WtExchangeLogic.LoginByPassword();
public static Task<bool> LoginByPassword(this BotContext bot)
=> bot.ContextCollection.Business.WtExchangeLogic.LoginByPassword();
/// <summary>
/// Submit the captcha of the url given by the <see cref="EventInvoker.OnBotCaptchaEvent"/>

View File

@ -56,7 +56,7 @@ internal class WtExchangeLogic : LogicBase
/// <para>1. resolve wtlogin.trans_emp CMD0x31 packet</para>
/// <para>2. Schedule wtlogin.trans_emp CMD0x12 Task</para>
/// </summary>
public async Task<byte[]?> FetchQrCode()
public async Task<(string, byte[])?> FetchQrCode()
{
Collection.Log.LogInfo(Tag, "Connecting Servers...");
if (!await Collection.Socket.Connect()) return null;
@ -73,7 +73,7 @@ internal class WtExchangeLogic : LogicBase
Collection.Keystore.Session.QrUrl = @event.Url;
Collection.Log.LogInfo(Tag, $"QrCode Fetched, Expiration: {@event.Expiration} seconds");
return @event.QrCode;
return (@event.Url, @event.QrCode);
}
return null;
}

View File

@ -81,6 +81,12 @@ public sealed class MessageBuilder
return this;
}
public MessageBuilder Add(IMessageEntity entity)
{
_chain.Add(entity);
return this;
}
public MessageChain Build() => _chain;
}

View File

@ -10,6 +10,8 @@ public class OneBotResult(object? data, int retCode, string status, string echo)
[JsonPropertyName("retcode")] public int RetCode { get; set; } = retCode;
[JsonPropertyName("data")] public object? Data { get; set; } = data;
[JsonPropertyName("echo")] public string Echo { get; set; } = echo;
}
[JsonIgnore] public string? Identifier { get; internal set; }
}

View File

@ -8,7 +8,7 @@ namespace Lagrange.OneBot.Core.Network;
public sealed class HttpPostService : ILagrangeWebService
{
public event EventHandler<string>? OnMessageReceived = delegate { };
public event EventHandler<MsgRecvEventArgs>? OnMessageReceived = delegate { };
private readonly HttpClient _client;

View File

@ -4,7 +4,7 @@ namespace Lagrange.OneBot.Core.Network;
public interface ILagrangeWebService : IHostedService
{
public event EventHandler<string> OnMessageReceived;
public event EventHandler<MsgRecvEventArgs> OnMessageReceived;
public Task SendJsonAsync<T>(T json, CancellationToken cancellationToken = default);
}

View File

@ -0,0 +1,10 @@
using Microsoft.Extensions.Hosting;
namespace Lagrange.OneBot.Core.Network;
public class MsgRecvEventArgs(string data, string? identifier = null) : EventArgs
{
public string? Identifier { get; init; } = identifier;
public string Data { get; init; } = data;
}

View File

@ -10,7 +10,9 @@ namespace Lagrange.OneBot.Core.Network;
public sealed class ReverseWSService : ILagrangeWebService
{
public event EventHandler<string> OnMessageReceived = delegate { };
private const string Tag = nameof(ReverseWSService);
public event EventHandler<MsgRecvEventArgs> OnMessageReceived = delegate { };
private readonly WebsocketClient _socket;
@ -45,7 +47,11 @@ public sealed class ReverseWSService : ILagrangeWebService
});
_timer = new Timer(OnHeartbeat, null, int.MaxValue, config.GetValue<int>("Implementation:ReverseWebSocket:HeartBeatInterval"));
_socket.MessageReceived.Subscribe(resp => OnMessageReceived.Invoke(this, resp.Text ?? ""));
_socket.MessageReceived.Subscribe(resp =>
{
_logger.LogTrace($"[{Tag}] Receive: {resp.Text}");
OnMessageReceived.Invoke(this, new MsgRecvEventArgs(resp.Text ?? ""));
});
}
public async Task StartAsync(CancellationToken cancellationToken)
@ -66,7 +72,9 @@ public sealed class ReverseWSService : ILagrangeWebService
public Task SendJsonAsync<T>(T json, CancellationToken cancellationToken = default)
{
var payload = JsonSerializer.SerializeToUtf8Bytes(json);
string payload = JsonSerializer.Serialize(json);
_logger.LogTrace($"[{Tag}] Send: {payload}");
return _socket.SendInstant(payload);
}

View File

@ -25,7 +25,7 @@ public sealed class OperationService
if (attribute != null) _operations[attribute.Api] = (IOperation)type.CreateInstance(false);
}
service.OnMessageReceived += async (_, s) => await HandleOperation(s);
service.OnMessageReceived += async (_, e) => await HandleOperation(e.Data);
}
private async Task HandleOperation(string data)

View File

@ -72,7 +72,7 @@ public class LagrangeApp : IHost
var qrCode = await Instance.FetchQrCode();
if (qrCode != null)
{
QrCodeHelper.Output(Instance.ContextCollection.Keystore.Session.QrUrl ?? "");
QrCodeHelper.Output(qrCode.Value.Url ?? "");
await Instance.LoginByQrCode();
}
}

228
README.md
View File

@ -11,7 +11,7 @@ An Implementation of NTQQ Protocol, with Pure C#, Derived from Konata.Core
</div>
## Disclaimer:
## Disclaimer
The Lagrange.Core project, including its developers, contributors, and affiliated individuals or entities, hereby explicitly disclaim any association with, support for, or endorsement of any form of illegal behavior. This disclaimer extends to any use or application of the Lagrange.Core project that may be contrary to local, national, or international laws, regulations, or ethical guidelines.
@ -26,22 +26,23 @@ By using or accessing Lagrange.Core, the user acknowledges and agrees to release
Please use Lagrange.Core responsibly and in accordance with the law.
## Features List
| Protocol | Support | Login | Support | Messages | Support | Operations | Support | Events | Support |
|----------|---------|---------------------------|---------|:-----------------|:-----------|:------------------|:-----------|:-----------------------|:--------|
| Windows | 🟢 | QrCode | 🟢 | Images | 🟢 | ~~Poke~~ | 🔴 | Captcha | 🟢 |
| macOS | 🟢 | Password | 🟢 | Text / At | 🟢 | Recall | 🟡 | BotOnline | 🟢 |
| Linux | 🟢 | EasyLogin | 🟢 | ~~Records~~ | 🔴 | Leave Group | 🟢 | BotOffline | 🟢 |
| | | UnusalDevice<br/>Password | 🔴 | QFace | 🟢 | ~~Special Title~~ | 🔴 | Message | 🟢 |
| | | UnusalDevice<br/>Easy | 🟢 | Json | 🟡 | Kick Member | 🟢 | ~~Poke~~ | 🔴 |
| | | NewDeviceVerify | 🔴 | Xml | 🟢 | Mute Member | 🟢 | MessageRecall | 🔴 |
| | | | | Forward | 🟢 | Set Admin | 🟢 | GroupMemberDecrease | 🟢 |
| | | | | Video | 🔴 | Friend Request | 🔴 | GroupMemberIncrease | 🟢 |
| | | | | ~~Flash Image~~ | 🔴 | Group Request | 🔴 | GroupPromoteAdmin | 🟢 |
| | | | | Reply | 🟢 | ~~Voice Call~~ | 🔴 | GroupInvite | 🟢 |
| | | | | File | 🟡 | Client Key | 🟢 | GroupRequestJoin | 🔴 |
| | | | | | | Cookies | 🟢 | FriendRequest | 🔴 |
| | | | | | | Send Message | 🟢 | ~~FriendTyping~~ | 🔴 |
| | | | | | | | | ~~FriendVoiceCall~~ | 🔴 |
| Protocol | Support | Login | Support | Messages | Support | Operations | Support | Events | Support |
| -------- | :-----: | ------------------------- | :-----: | :-------------- | :-----: | :---------------- | :-----: | :------------------ | :-----: |
| Windows | 🟢 | QrCode | 🟢 | Images | 🟢 | ~~Poke~~ | 🔴 | Captcha | 🟢 |
| macOS | 🟢 | Password | 🟢 | Text / At | 🟢 | Recall | 🟡 | BotOnline | 🟢 |
| Linux | 🟢 | EasyLogin | 🟢 | ~~Records~~ | 🔴 | Leave Group | 🟢 | BotOffline | 🟢 |
| | | UnusalDevice<br/>Password | 🔴 | QFace | 🟢 | ~~Special Title~~ | 🔴 | Message | 🟢 |
| | | UnusalDevice<br/>Easy | 🟢 | Json | 🟡 | Kick Member | 🟢 | ~~Poke~~ | 🔴 |
| | | NewDeviceVerify | 🔴 | Xml | 🟢 | Mute Member | 🟢 | MessageRecall | 🔴 |
| | | | | Forward | 🟢 | Set Admin | 🟢 | GroupMemberDecrease | 🟢 |
| | | | | Video | 🔴 | Friend Request | 🔴 | GroupMemberIncrease | 🟢 |
| | | | | ~~Flash Image~~ | 🔴 | Group Request | 🔴 | GroupPromoteAdmin | 🟢 |
| | | | | Reply | 🟢 | ~~Voice Call~~ | 🔴 | GroupInvite | 🟢 |
| | | | | File | 🟡 | Client Key | 🟢 | GroupRequestJoin | 🔴 |
| | | | | | | Cookies | 🟢 | FriendRequest | 🔴 |
| | | | | | | Send Message | 🟢 | ~~FriendTyping~~ | 🔴 |
| | | | | | | | | ~~FriendVoiceCall~~ | 🔴 |
## Lagrange.OneBot
@ -50,28 +51,28 @@ Please use Lagrange.Core responsibly and in accordance with the law.
<Details>
<Summary>Message Segement</Summary>
| Message Segement| Support |
| ------------ | ------------|
| [Text] | 🟢 |
| [Face] | 🟢 |
| [Image] | 🟢 |
| [Record] | 🔴 |
| [Video] | 🔴 |
| [At] | 🟢 |
| [Rps] | 🔴 |
| [Dice] | 🔴 |
| [Shake] | 🔴 |
| [Poke] | 🔴 |
| [Anonymous] | 🔴 |
| [Share] | 🔴 |
| [Contact] | 🔴 |
| [Location] | 🔴 |
| [Music] | 🔴 |
| [Reply] | 🔴 |
| [Forward] | 🔴 |
| [Node] | 🔴 |
| [Xml] | 🔴 |
| [Json] | 🔴 |
| Message Segement | Support |
| ---------------- | :-----: |
| [Text] | 🟢 |
| [Face] | 🟢 |
| [Image] | 🟢 |
| [Record] | 🔴 |
| [Video] | 🔴 |
| [At] | 🟢 |
| [Rps] | 🔴 |
| [Dice] | 🔴 |
| [Shake] | 🔴 |
| [Poke] | 🔴 |
| [Anonymous] | 🔴 |
| [Share] | 🔴 |
| [Contact] | 🔴 |
| [Location] | 🔴 |
| [Music] | 🔴 |
| [Reply] | 🔴 |
| [Forward] | 🔴 |
| [Node] | 🔴 |
| [Xml] | 🔴 |
| [Json] | 🔴 |
[Text]: https://github.com/botuniverse/onebot-11/blob/master/message/segment.md#qq-%E8%A1%A8%E6%83%85
[Record]: https://github.com/botuniverse/onebot-11/blob/master/message/segment.md#%E8%AF%AD%E9%9F%B3
@ -99,46 +100,46 @@ Please use Lagrange.Core responsibly and in accordance with the law.
<Details>
<Summary>API</Summary>
| API | Support |
| ------------------------ | -------- |
| [/send_private_msg] | 🔴 |
| [/send_group_msg] | 🔴 |
| [/send_msg] | 🟢 |
| [/delete_msg] | 🔴 |
| [/get_msg] | 🔴 |
| [/get_forward_msg] | 🔴 |
| ~~[/send_like]~~ | 🔴 |
| [/set_group_kick] | 🟢 |
| [/set_group_ban] | 🟢 |
| [/set_group_anonymous_ban] | 🔴 |
| [/set_group_whole_ban] | 🟢 |
| [/set_group_admin] | 🟢 |
| [/set_group_anonymous] | 🔴 |
| [/set_group_card] | 🟢 |
| [/set_group_name] | 🟢 |
| [/set_group_leave] | 🟢 |
| [/set_group_special_title] | 🔴 |
| [/set_friend_add_request] | 🔴 |
| [/set_group_add_request] | 🔴 |
| [/get_login_info] | 🟢 |
| [/get_stranger_info] | 🔴 |
| [/get_friend_list] | 🔴 |
| [/get_group_info] | 🟢 |
| [/get_group_list] | 🟢 |
| [/get_group_member_info] | 🔴 |
| [/get_group_member_list] | 🔴 |
| [/get_group_honor_info] | 🔴 |
| [/get_cookies] | 🔴 |
| [/get_csrf_token] | 🔴 |
| [/get_credentials] | 🔴 |
| [/get_record] | 🔴 |
| [/get_image] | 🔴 |
| [/can_send_image] | 🔴 |
| [/can_send_record] | 🔴 |
| [/get_status] | 🔴 |
| [/get_version_info] | 🟢 |
| [/set_restart] | 🔴 |
| [/clean_cache] | 🔴 |
| API | Support |
| -------------------------- | :-----: |
| [/send_private_msg] | 🔴 |
| [/send_group_msg] | 🔴 |
| [/send_msg] | 🟢 |
| [/delete_msg] | 🔴 |
| [/get_msg] | 🔴 |
| [/get_forward_msg] | 🔴 |
| ~~[/send_like]~~ | 🔴 |
| [/set_group_kick] | 🟢 |
| [/set_group_ban] | 🟢 |
| [/set_group_anonymous_ban] | 🔴 |
| [/set_group_whole_ban] | 🟢 |
| [/set_group_admin] | 🟢 |
| [/set_group_anonymous] | 🔴 |
| [/set_group_card] | 🟢 |
| [/set_group_name] | 🟢 |
| [/set_group_leave] | 🟢 |
| [/set_group_special_title] | 🔴 |
| [/set_friend_add_request] | 🔴 |
| [/set_group_add_request] | 🔴 |
| [/get_login_info] | 🟢 |
| [/get_stranger_info] | 🔴 |
| [/get_friend_list] | 🔴 |
| [/get_group_info] | 🟢 |
| [/get_group_list] | 🟢 |
| [/get_group_member_info] | 🔴 |
| [/get_group_member_list] | 🔴 |
| [/get_group_honor_info] | 🔴 |
| [/get_cookies] | 🔴 |
| [/get_csrf_token] | 🔴 |
| [/get_credentials] | 🔴 |
| [/get_record] | 🔴 |
| [/get_image] | 🔴 |
| [/can_send_image] | 🔴 |
| [/can_send_record] | 🔴 |
| [/get_status] | 🔴 |
| [/get_version_info] | 🟢 |
| [/set_restart] | 🔴 |
| [/clean_cache] | 🔴 |
[/send_private_msg]: https://github.com/botuniverse/onebot-11/blob/master/api/public.md#send_private_msg-%E5%8F%91%E9%80%81%E7%A7%81%E8%81%8A%E6%B6%88%E6%81%AF
[/send_group_msg]: https://github.com/botuniverse/onebot-11/blob/master/api/public.md#send_group_msg-%E5%8F%91%E9%80%81%E7%BE%A4%E6%B6%88%E6%81%AF
@ -184,25 +185,25 @@ Please use Lagrange.Core responsibly and in accordance with the law.
<Details>
<Summary>Event</Summary>
| PostType| EventName | Support |
| --------| -----------------------------|----------|
| Message | [Private Message] | 🔴 |
| Message | [Group Message] | 🟢 |
| Notice | [Group File Upload] | 🔴 |
| Notice | [Group Admin Change] | 🔴 |
| Notice | [Group Member Decrease] | 🔴 |
| Notice | [Group Member Increase] | 🔴 |
| Notice | [Group Mute] | 🔴 |
| Notice | [Friend Add] | 🔴 |
| Notice | [Group Recall Message] | 🔴 |
| Notice | [Friend Recall Message] | 🔴 |
| Notice | [Group Poke] | 🔴 |
| Notice | [Group red envelope luck king]| 🔴 |
| Notice | [Group Member Honor Changed] | 🔴 |
| Request| [Add Friend Request] | 🔴 |
| Request| [Group Request/Invitations] | 🔴 |
| Meta | [LifeCycle] | 🟢 |
| Meta | [Heartbeat] | 🟢 |
| PostType | EventName | Support |
| -------- | ------------------------------ | :-----: |
| Message | [Private Message] | 🔴 |
| Message | [Group Message] | 🟢 |
| Notice | [Group File Upload] | 🔴 |
| Notice | [Group Admin Change] | 🔴 |
| Notice | [Group Member Decrease] | 🔴 |
| Notice | [Group Member Increase] | 🔴 |
| Notice | [Group Mute] | 🔴 |
| Notice | [Friend Add] | 🔴 |
| Notice | [Group Recall Message] | 🔴 |
| Notice | [Friend Recall Message] | 🔴 |
| Notice | [Group Poke] | 🔴 |
| Notice | [Group red envelope luck king] | 🔴 |
| Notice | [Group Member Honor Changed] | 🔴 |
| Request | [Add Friend Request] | 🔴 |
| Request | [Group Request/Invitations] | 🔴 |
| Meta | [LifeCycle] | 🟢 |
| Meta | [Heartbeat] | 🟢 |
[Private Message]: https://github.com/botuniverse/onebot-11/blob/master/event/message.md#%E7%A7%81%E8%81%8A%E6%B6%88%E6%81%AF
[Group Message]: https://github.com/botuniverse/onebot-11/blob/master/event/message.md#%E7%BE%A4%E6%B6%88%E6%81%AF
@ -224,8 +225,26 @@ Please use Lagrange.Core responsibly and in accordance with the law.
</Details>
<Details>
<Summary>Communication</Summary>
| CommunicationType | Support |
| ------------------ | :-----: |
| [Http] | 🔴 |
| [Http-Post] | 🟢 |
| [ForwardWebSocket] | 🟢 |
| [ReverseWebSocket] | 🟢 |
[Http]: https://github.com/botuniverse/onebot-11/blob/master/communication/http.md
[Http-Post]: https://github.com/botuniverse/onebot-11/blob/master/communication/http-post.md
[ForwardWebSocket]: https://github.com/botuniverse/onebot-11/blob/master/communication/ws.md
[ReverseWebSocket]: https://github.com/botuniverse/onebot-11/blob/master/communication/ws-reverse.md
</Details>
#### appsettings.json Example
```C#
```json
{
"Logging": {
"LogLevel": {
@ -244,15 +263,14 @@ Please use Lagrange.Core responsibly and in accordance with the law.
},
"Implementation": {
"ForwardWebSocket": {
"Host": "",
"Port": 0,
"HeartBeatIntetval": 0
"Port": 8081,
"HeartBeatIntetval": 5000
},
"ReverseWebSocket": {
"Host": "127.0.0.1",
"Port": 8080,
"Suffix": "/onebot/v11/ws",
"ReconnectInterval": 0,
"ReconnectInterval": 5000,
"HeartBeatInterval": 5000
},
"Http": {
@ -269,11 +287,13 @@ Please use Lagrange.Core responsibly and in accordance with the law.
}
}
```
- Create a file named 'appsettings.json' under Lagrange.OneBot executable directory
- Create a file named 'appsettings.json' under Lagrange.OneBot executable directory
- As the Uin is 0 here, this indicates that QRCode login is used
- After the QRCode Login, write Uin back to perform EasyLogin
## Known Problem
~~- [ ] Signature Service is currently not established, so the login tend to be failed and return code may be 45, you can establish your own sign service by rewriting the `Signature` static class.~~
Thanks KonataDev/TheSnowfield for Provision of Signature API