Skip to content

Commit

Permalink
feat: Add more impl
Browse files Browse the repository at this point in the history
  • Loading branch information
Yushu2606 committed Jul 21, 2024
1 parent 18df2b4 commit 8a9b0c3
Show file tree
Hide file tree
Showing 11 changed files with 127 additions and 79 deletions.
27 changes: 19 additions & 8 deletions src/Bot/BotInstance.cs
Original file line number Diff line number Diff line change
@@ -1,23 +1,34 @@
using DXKumaBot.Bot.Lagrange;
using DXKumaBot.Bot.Telegram;
using DXKumaBot.Functions;
using DXKumaBot.Utils;

namespace DXKumaBot.Bot;

public sealed class BotInstance
public sealed class BotInstance(Config config)
{
private readonly QQBot _qqBot = new();
private readonly TgBot _tgBot = new();
private readonly QqBot _qqBot = new();
private readonly TgBot _tgBot = new(config.Telegram);

public static event AsyncEventHandler<MessageReceivedEventArgs> MessageReceived;
public static event AsyncEventHandler<MessageReceivedEventArgs>? MessageReceived;

public async Task RunAsync()
private static void RegisterFunctions()
{
await Task.WhenAll(_qqBot.RunAsync(), _tgBot.RunAsync());
LoveYou loveYou = new();
loveYou.Register();
}

public async Task SendMessageAsync(object message)
private void RegisterEvents()
{
_qqBot.MessageReceived += MessageReceived;
_tgBot.MessageReceived += MessageReceived;
}

public async Task RunAsync()
{
throw new NotImplementedException();
RegisterFunctions();
RegisterEvents();
_tgBot.Run();
await _qqBot.RunAsync();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,16 @@

namespace DXKumaBot.Bot.Lagrange;

public class OneBotSigner : SignProvider
public class CustomSignProvider : SignProvider
{
private readonly HttpClient _client;
private readonly string _signServer;
private readonly Timer _timer;

public OneBotSigner()
public CustomSignProvider()
{
_signServer = "https://sign.lagrangecore.org/api/sign";
_client = new();

if (string.IsNullOrEmpty(_signServer))
{
Available = false;
Console.WriteLine("Signature Service is not available, login may be failed");
}
else
{
Console.WriteLine("Signature Service is successfully established");
}

_timer = new(_ =>
{
bool reconnect = Available = Test();
Expand All @@ -53,7 +42,7 @@ public OneBotSigner()
return null;
}

if (!Available || string.IsNullOrEmpty(_signServer))
if (!Available)
{
return new byte[35]; // Dummy signature
}
Expand Down Expand Up @@ -81,7 +70,6 @@ public OneBotSigner()
Available = false;
_timer.Change(0, 5000);

Console.WriteLine("Failed to get signature, using dummy signature");
return new byte[35]; // Dummy signature
}
}
Expand All @@ -95,13 +83,7 @@ public override bool Test()
uriBuilder.Query = query.ToString();
using HttpResponseMessage response = _client.GetAsync(uriBuilder.Uri).Result;
string responseStr = response.Content.ReadAsStringAsync().Result;
if (JsonSerializer.Deserialize<JsonObject>(responseStr)?["code"]?.GetValue<int>() is not 0)
{
return false;
}

Console.WriteLine("Reconnected to Signature Service successfully");
return true;
return JsonSerializer.Deserialize<JsonObject>(responseStr)?["code"]?.GetValue<int>() is 0;
}
catch
{
Expand Down
72 changes: 45 additions & 27 deletions src/Bot/Lagrange/QQBot.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using DXKumaBot.Bot.Message;
using DXKumaBot.Utils;
using Lagrange.Core;
using Lagrange.Core.Common;
using Lagrange.Core.Common.Interface;
Expand All @@ -9,23 +10,22 @@

namespace DXKumaBot.Bot.Lagrange;

public class QQBot : IBot
public class QqBot : IBot
{
private readonly BotContext _bot;
private readonly BotKeystore? _keyStore;

public QQBot()
public QqBot()
{
BotDeviceInfo deviceInfo = GetDeviceInfo();
_keyStore = LoadKeystore();

_bot = BotFactory.Create(new()
{
UseIPv6Network = false,
GetOptimumServer = true,
AutoReconnect = true,
Protocol = Protocols.Linux,
CustomSignProvider = new OneBotSigner()
CustomSignProvider = new CustomSignProvider()
}, deviceInfo, _keyStore ?? new BotKeystore());
}

Expand All @@ -34,96 +34,114 @@ public async Task SendMessageAsync(MessageReceivedEventArgs messageToReply, Mess
await SendMessageAsync(messageToReply.QqMessage!.Chain.GroupUin, messages);
}

public event AsyncEventHandler<MessageReceivedEventArgs>? MessageReceived;

private void RegisterEvents()
{
_bot.Invoker.OnBotCaptchaEvent += (_, @event) => { Console.WriteLine(@event.ToString()); };
_bot.Invoker.OnBotOfflineEvent += (_, @event) => { Console.WriteLine(@event.ToString()); };
_bot.Invoker.OnBotOnlineEvent += (_, @event) => { Console.WriteLine(@event.ToString()); };
_bot.Invoker.OnBotNewDeviceVerify += (_, @event) => { Console.WriteLine(@event.ToString()); };
_bot.Invoker.OnGroupMessageReceived += async (sender, args) =>
{
if (MessageReceived is null)
{
return;
}
await MessageReceived.Invoke(sender, new(this, args));
};
}

public async Task RunAsync()
{
RegisterEvents();
if (_keyStore is null)
{
Console.WriteLine("try fetching qr code");
(string Url, byte[] QrCode)? qrCode = await _bot.FetchQrCode();
if (qrCode is null)
{
return;
throw new NotSupportedException();
}

await File.WriteAllBytesAsync("qr.png", qrCode.Value.QrCode);
await _bot.LoginByQrCode();
SaveKeystore(_bot.UpdateKeystore());
return;
}
else
{
await _bot.LoginByPassword();
}

await _bot.LoginByPassword();
}

private static BotDeviceInfo GetDeviceInfo()
{
if (!File.Exists("Config/DeviceInfo.json"))
if (!File.Exists("DeviceInfo.json"))
{
BotDeviceInfo deviceInfo = BotDeviceInfo.GenerateInfo();
File.WriteAllText("Config/DeviceInfo.json", JsonSerializer.Serialize(deviceInfo));
File.WriteAllText("DeviceInfo.json", JsonSerializer.Serialize(deviceInfo));
return deviceInfo;
}

string text = File.ReadAllText("Config/DeviceInfo.json");
string text = File.ReadAllText("DeviceInfo.json");
BotDeviceInfo? info = JsonSerializer.Deserialize<BotDeviceInfo>(text);
if (info is not null)
{
return info;
}

info = BotDeviceInfo.GenerateInfo();
File.WriteAllText("Config/DeviceInfo.json", JsonSerializer.Serialize(info));

File.WriteAllText("DeviceInfo.json", JsonSerializer.Serialize(info));
return info;
}

private static void SaveKeystore(BotKeystore keystore)
{
File.WriteAllText("Config/Keystore.json", JsonSerializer.Serialize(keystore));
File.WriteAllText("Keystore.json", JsonSerializer.Serialize(keystore));
}

private static BotKeystore? LoadKeystore()
{
if (!File.Exists("Config/Keystore.json"))
if (!File.Exists("Keystore.json"))
{
return null;
}

string text = File.ReadAllText("Config/Keystore.json");
string text = File.ReadAllText("Keystore.json");
return JsonSerializer.Deserialize<BotKeystore>(text, new JsonSerializerOptions
{
ReferenceHandler = ReferenceHandler.Preserve
});
}

public async Task SendMessageAsync(uint? id, MessagePair messages)
private async Task SendMessageAsync(uint? id, MessagePair messages)
{
if (id is null)
{
throw new ArgumentNullException(nameof(id));
}

MessageBuilder messageBuilder = MessageBuilder.Group((uint)id);
if (messages.Text is not null)
{
messageBuilder.Text(messages.Text);
}

if (messages.Media is not null)
{
byte[] dataStream = messages.Media.Data.ToArray();
byte[] data = await File.ReadAllBytesAsync(messages.Media.Path);
switch (messages.Media.Type)
{
case MediaType.Audio:
messageBuilder.Record(dataStream);
messageBuilder.Record(data);
break;
case MediaType.Photo:
messageBuilder.Image(dataStream);
messageBuilder.Image(data);
break;
default:
throw new ArgumentOutOfRangeException(nameof(messages));
}
}

if (messages.Text is not null)
{
messageBuilder.Text(messages.Text);
}

await _bot.SendMessage(messageBuilder.Build());
}
}
4 changes: 2 additions & 2 deletions src/Bot/Message/MediaMessage.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
namespace DXKumaBot.Bot.Message;

public class MediaMessage(MediaType type, MemoryStream stream)
public class MediaMessage(MediaType type, string path)
{
public MediaType Type { get; } = type;

public MemoryStream Data { get; } = stream;
public string Path { get; } = path;

public static implicit operator MessagePair(MediaMessage message)
{
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion src/Bot/MessageRecivedEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public MessageReceivedEventArgs(IBot bot, TgMessage message)

public GroupMessageEvent? QqMessage { get; }
public TgMessage? TgMessage { get; }
public string Text => QqMessage?.EventMessage ?? TgMessage?.Text ?? throw new NullReferenceException();
public string Text => QqMessage?.Chain.ToPreviewText() ?? TgMessage?.Text ?? throw new NullReferenceException();

public async Task Reply(MessagePair messages)
{
Expand Down
40 changes: 28 additions & 12 deletions src/Bot/Telegram/TgBot.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
using DXKumaBot.Bot.Message;
using System.Net;
using Telegram.Bot;
using Telegram.Bot.Types;
using Telegram.Bot.Types.Enums;
using File = System.IO.File;

namespace DXKumaBot.Bot.Telegram;

public class TgBot : IBot
public class TgBot(TelegramConfig config) : IBot
{
private readonly TelegramBotClient _bot;

public TgBot()
{
// _bot = new TelegramBotClient();
}
private readonly TelegramBotClient _bot = new(config.BotToken,
config.Proxy.Enabled ? new(new HttpClientHandler { Proxy = new WebProxy(config.Proxy.Url, true) }) : default);

public async Task SendMessageAsync(MessageReceivedEventArgs messageToReply, MessagePair messages)
{
Expand All @@ -21,23 +19,41 @@ public async Task SendMessageAsync(MessageReceivedEventArgs messageToReply, Mess
throw new ArgumentNullException(nameof(messageToReply));
}

await SendMessageAsync(messageToReply.TgMessage.MessageId, messages);
await SendMessageAsync(messageToReply.TgMessage.Chat.Id, messages);
}

public async Task RunAsync()
public event Utils.AsyncEventHandler<MessageReceivedEventArgs>? MessageReceived;

public void Run()
{
throw new NotImplementedException();
_bot.StartReceiving(async (bot, update, _) =>
{
if (update is not
{
Type: UpdateType.Message,
Message:
{
Type: MessageType.Text,
Text: not null
}
} || MessageReceived is null)
{
return;
}
await MessageReceived.Invoke(bot, new(this, update.Message));
}, (_, e, _) => { Console.WriteLine(e); });
}

public async Task SendMessageAsync(long id, MessagePair messages, int? threadId = null)
private async Task SendMessageAsync(long id, MessagePair messages, int? threadId = null)
{
if (messages.Media is null)
{
await _bot.SendTextMessageAsync(id, messages.Text!.Text, threadId, ParseMode.MarkdownV2);
return;
}

InputFileStream file = InputFile.FromStream(messages.Media.Data);
InputFile file = InputFile.FromStream(File.OpenRead(messages.Media.Path));
switch (messages.Media.Type)
{
case MediaType.Audio:
Expand Down
7 changes: 7 additions & 0 deletions src/Config.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace DXKumaBot;

public record Config(TelegramConfig Telegram);

public record TelegramConfig(string BotToken, ProxyConfig Proxy);

public record ProxyConfig(bool Enabled, string Url);
5 changes: 5 additions & 0 deletions src/DXKumaBot.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,13 @@
<ItemGroup>
<PackageReference Include="Lagrange.Core" Version="0.2.2"/>
<PackageReference Include="LiteDB" Version="5.0.21"/>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.0-preview.6.24327.7"/>
<PackageReference Include="SixLabors.Fonts" Version="2.0.4"/>
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.4"/>
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="2.1.3"/>
<PackageReference Include="Telegram.Bot" Version="21.7.0"/>
<PackageReference Include="Tomlyn" Version="0.17.0"/>
<PackageReference Include="Tomlyn.Extensions.Configuration" Version="1.0.6"/>
</ItemGroup>

</Project>
Loading

0 comments on commit 8a9b0c3

Please sign in to comment.