Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: resolve conflict
Browse files Browse the repository at this point in the history
dogdie233 committed Oct 8, 2024

Verified

This commit was signed with the committer’s verified signature.
dogdie233 dogdie233
2 parents a491756 + efa35d0 commit cc3d489
Showing 16 changed files with 391 additions and 33 deletions.
39 changes: 39 additions & 0 deletions Lagrange.Core/Common/Entity/BotFriendRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
namespace Lagrange.Core.Common.Entity;

[Serializable]
public class BotFriendRequest
{
public BotFriendRequest(string targetUid, string sourceUid, uint eventState, string comment, string source, uint time)
{
TargetUid = targetUid;
SourceUid = sourceUid;
EventState = (State)eventState;
Comment = comment;
Source = source;
Time = DateTime.UnixEpoch.AddSeconds(time);
}

public string TargetUid { get; set; }

public uint TargetUin { get; set; }

public string SourceUid { get; set; }

public uint SourceUin { get; set; }

public State EventState { get; set; }


public string Comment { get; set; }

public string Source { get; set; }

public DateTime Time { get; set; }

public enum State
{
Pending = 1,
Disapproved = 2,
Approved = 3,
}
}
6 changes: 6 additions & 0 deletions Lagrange.Core/Common/Interface/Api/GroupExt.cs
Original file line number Diff line number Diff line change
@@ -192,6 +192,12 @@ public static Task<bool> GroupSetAvatar(this BotContext bot, uint groupUin, Imag
public static Task<bool> GroupSetAvatar(this BotContext bot, uint groupUin, ImageEntity imageEntity, CancellationToken ct)
=> bot.ContextCollection.Business.OperationLogic.GroupSetAvatar(groupUin, imageEntity, ct);

public static Task<(uint, uint)> GroupRemainAtAll(this BotContext bot, uint groupUin)
=> bot.ContextCollection.Business.OperationLogic.GroupRemainAtAll(groupUin, CancellationToken.None);

public static Task<(uint, uint)> GroupRemainAtAll(this BotContext bot, uint groupUin, CancellationToken ct)
=> bot.ContextCollection.Business.OperationLogic.GroupRemainAtAll(groupUin, ct);

#region Group File System

public static Task<ulong> FetchGroupFSSpace(this BotContext bot, uint groupUin)
4 changes: 2 additions & 2 deletions Lagrange.Core/Common/Interface/Api/OperationExt.cs
Original file line number Diff line number Diff line change
@@ -225,7 +225,7 @@ public static Task<bool> RecallFriendMessage(this BotContext bot, MessageChain c
/// </summary>
/// <param name="bot"></param>
/// <returns></returns>
public static Task<List<dynamic>?> FetchFriendRequests(this BotContext bot)
public static Task<List<BotFriendRequest>?> FetchFriendRequests(this BotContext bot)
=> bot.ContextCollection.Business.OperationLogic.FetchFriendRequests(CancellationToken.None);

/// <summary>
@@ -234,7 +234,7 @@ public static Task<bool> RecallFriendMessage(this BotContext bot, MessageChain c
/// <param name="bot"></param>
/// <param name="ct">The cancellation token</param>
/// <returns></returns>
public static Task<List<dynamic>?> FetchFriendRequests(this BotContext bot, CancellationToken ct)
public static Task<List<BotFriendRequest>?> FetchFriendRequests(this BotContext bot, CancellationToken ct)
=> bot.ContextCollection.Business.OperationLogic.FetchFriendRequests(ct);

/// <summary>
Original file line number Diff line number Diff line change
@@ -337,13 +337,30 @@ async Task<uint> ResolveUid(string? uid)
}
}

public async Task<List<dynamic>?> FetchFriendRequests(CancellationToken ct)
public async Task<List<BotFriendRequest>?> FetchFriendRequests(CancellationToken ct)
{
var fetchRequestsEvent = FetchFriendsRequestsEvent.Create();
var events = await Collection.Business.SendEvent(fetchRequestsEvent, ct);
if (events.Count == 0) return null;

return null;
var resolved = ((FetchFriendsRequestsEvent)events[0]).Requests;
foreach (var result in resolved)
{
var uins = await Task.WhenAll(ResolveUid(result.TargetUid), ResolveUid(result.SourceUid));
result.TargetUin = uins[0];
result.SourceUin = uins[1];
}

return resolved;

async Task<uint> ResolveUid(string? uid)
{
if (uid == null) return 0;

var fetchUidEvent = FetchUserInfoEvent.Create(uid);
var e = await Collection.Business.SendEvent(fetchUidEvent, ct);
return e.Count == 0 ? 0 : ((FetchUserInfoEvent)e[0]).UserInfo.Uin;
}
}

public async Task<bool> GroupTransfer(uint groupUin, uint targetUin, CancellationToken ct)
@@ -624,4 +641,14 @@ public async Task<bool> GroupSetAvatar(uint groupUin, ImageEntity avatar, Cancel
}.Serialize().ToArray();
return await Collection.Highway.UploadSrcByStreamAsync(3000, avatar.ImageStream.Value, ticket, md5, ct, extendInfo: extra);
}

public async Task<(uint, uint)> GroupRemainAtAll(uint groupUin, CancellationToken ct)
{
var groupRemainAtAllEvent = FetchGroupAtAllRemainEvent.Create(groupUin);
var results = await Collection.Business.SendEvent(groupRemainAtAllEvent, ct);
if (results.Count == 0) return (0, 0);

var ret = (FetchGroupAtAllRemainEvent)results[0];
return (ret.RemainAtAllCountForUin, ret.RemainAtAllCountForGroup);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Net.Http.Json;
using System.Runtime.Serialization;
using System.Text;
using System.Text.Json;
using System.Web;
@@ -29,16 +28,17 @@ internal class WtExchangeLogic : LogicBase

private readonly Timer _reLoginTimer;

private readonly TaskCompletionSource<bool> _transEmpTask;
private TaskCompletionSource<(string, string)>? _captchaTask;
private TaskCompletionSource<bool> _transEmpTask = new();
private TaskCompletionSource<(string, string)> _captchaTask = new();

private const string Interface = "https://ntlogin.qq.com/qr/getFace";

private const string QueryEvent = "wtlogin.trans_emp CMD0x12";
private const string HeartbeatEvent = "Heartbeat.Alive";
private const string SsoHeartbeatEvent = "SsoHeartBeat";

internal WtExchangeLogic(ContextCollection collection) : base(collection)
{
_transEmpTask = new TaskCompletionSource<bool>();
_reLoginTimer = new Timer(async _ => await ReLogin(), null, Timeout.Infinite, Timeout.Infinite);
}

@@ -57,6 +57,20 @@ public override async Task Incoming(ProtocolEvent e, CancellationToken _)
}
}

private void Reset()
{
_transEmpTask = new TaskCompletionSource<bool>();
_captchaTask = new TaskCompletionSource<(string, string)>();
}

private void OnCancellation()
{
Collection.Scheduler.Cancel(QueryEvent);
Collection.Scheduler.Cancel(HeartbeatEvent);
_transEmpTask.TrySetCanceled();
_captchaTask.TrySetCanceled();
}

/// <summary>
/// <para>1. resolve wtlogin.trans_emp CMD0x31 packet</para>
/// <para>2. Schedule wtlogin.trans_emp CMD0x12 Task</para>
@@ -65,7 +79,15 @@ public override async Task Incoming(ProtocolEvent e, CancellationToken _)
{
Collection.Log.LogInfo(Tag, "Connecting Servers...");
if (!await Collection.Socket.Connect()) return null;
Collection.Scheduler.Interval("Heartbeat.Alive", 10 * 1000, async () => await Collection.Business.PushEvent(AliveEvent.Create(), CancellationToken.None));
Collection.Scheduler.Interval(HeartbeatEvent, 10 * 1000, async () =>
{
if (ct.IsCancellationRequested)
{
Collection.Scheduler.Cancel(HeartbeatEvent);
return;
}
await Collection.Business.PushEvent(AliveEvent.Create(), CancellationToken.None);
});

if (Collection.Keystore.Session.D2.Length != 0)
{
@@ -91,6 +113,9 @@ public override async Task Incoming(ProtocolEvent e, CancellationToken _)

public Task LoginByQrCode(CancellationToken ct)
{
Reset();
ct.Register(OnCancellation);

Collection.Scheduler.Interval(QueryEvent, 2 * 1000, async () => await QueryTransEmpState(async @event =>
{
if (@event.TgtgtKey != null)
@@ -108,10 +133,13 @@ public Task LoginByQrCode(CancellationToken ct)

public async Task<bool> LoginByPassword(CancellationToken ct)
{
Reset();
ct.Register(OnCancellation);

if (!Collection.Socket.Connected) // if socket not connected, try to connect
{
if (!await Collection.Socket.Connect()) return false;
Collection.Scheduler.Interval("Heartbeat.Alive", 10 * 1000, async () => await Collection.Business.PushEvent(AliveEvent.Create(), CancellationToken.None));
Collection.Scheduler.Interval(HeartbeatEvent, 10 * 1000, async () => await Collection.Business.PushEvent(AliveEvent.Create(), CancellationToken.None));
}

if (Collection.Keystore.Session.D2.Length > 0 && Collection.Keystore.Session.Tgt.Length > 0 &&
@@ -134,7 +162,7 @@ public async Task<bool> LoginByPassword(CancellationToken ct)
{
Collection.Keystore.ClearSession();

if (!await KeyExchange(ct))
if (!await KeyExchange())
{
Collection.Log.LogInfo(Tag, "Key Exchange Failed, please try again later");
return false;
@@ -145,7 +173,7 @@ public async Task<bool> LoginByPassword(CancellationToken ct)
{
Collection.Log.LogInfo(Tag, "Trying to Login by EasyLogin...");
var easyLoginEvent = EasyLoginEvent.Create();
var easyLoginResult = await Collection.Business.SendEvent(easyLoginEvent, ct);
var easyLoginResult = await Collection.Business.SendEvent(easyLoginEvent, CancellationToken.None);

if (easyLoginResult.Count != 0)
{
@@ -160,7 +188,7 @@ public async Task<bool> LoginByPassword(CancellationToken ct)
{
Collection.Log.LogInfo(Tag, "Verification needed");

if (!await FetchUnusual(ct))
if (!await FetchUnusual())
{
Collection.Log.LogInfo(Tag, "Fetch unusual state failed");
return false;
@@ -171,7 +199,7 @@ public async Task<bool> LoginByPassword(CancellationToken ct)
if (e.TempPassword != null)
{
Collection.Keystore.Session.TempPassword = e.TempPassword;
return await DoUnusualEasyLogin(ct);
return await DoUnusualEasyLogin();
}

return false;
@@ -193,7 +221,7 @@ public async Task<bool> LoginByPassword(CancellationToken ct)
{
Collection.Log.LogInfo(Tag, "Trying to Login by Password...");
var passwordLoginEvent = PasswordLoginEvent.Create();
var passwordLoginResult = await Collection.Business.SendEvent(passwordLoginEvent, ct);
var passwordLoginResult = await Collection.Business.SendEvent(passwordLoginEvent, CancellationToken.None);

if (passwordLoginResult.Count != 0)
{
@@ -222,7 +250,6 @@ public async Task<bool> LoginByPassword(CancellationToken ct)
Collection.Invoker.PostEvent(captchaEvent);

string aid = Collection.Keystore.Session.CaptchaUrl.Split("&sid=")[1].Split("&")[0];
_captchaTask = new TaskCompletionSource<(string, string)>();
var (ticket, randStr) = await _captchaTask.Task;
Collection.Keystore.Session.Captcha = new ValueTuple<string, string, string>(ticket, randStr, aid);

@@ -306,8 +333,7 @@ public async Task<bool> LoginByPassword(CancellationToken ct)
Collection.Log.LogWarning(Tag, @event is { Message: not null, Tag: not null }
? $"Login Failed: {(LoginCommon.Error)@event.ResultCode} | {@event.Tag}: {@event.Message}"
: $"Login Failed: {(LoginCommon.Error)@event.ResultCode}");

Collection.Invoker.Dispose();

return false;
}
}
@@ -317,10 +343,10 @@ public async Task<bool> LoginByPassword(CancellationToken ct)
return false;
}

private async Task<bool> KeyExchange(CancellationToken ct)
private async Task<bool> KeyExchange()
{
var keyExchangeEvent = KeyExchangeEvent.Create();
var exchangeResult = await Collection.Business.SendEvent(keyExchangeEvent, ct);
var exchangeResult = await Collection.Business.SendEvent(keyExchangeEvent, CancellationToken.None);
if (exchangeResult.Count != 0)
{
Collection.Log.LogInfo(Tag, "Key Exchange successfully!");
@@ -402,7 +428,6 @@ private async Task QueryTransEmpState(Func<TransEmpEvent, Task<bool>> callback,
{
Collection.Log.LogWarning(Tag, "QrCode Expired, Please Fetch QrCode Again");
Collection.Scheduler.Cancel(QueryEvent);
Collection.Scheduler.Dispose();

_transEmpTask.SetResult(false);
return;
@@ -411,7 +436,6 @@ private async Task QueryTransEmpState(Func<TransEmpEvent, Task<bool>> callback,
{
Collection.Log.LogWarning(Tag, "QrCode Canceled, Please Fetch QrCode Again");
Collection.Scheduler.Cancel(QueryEvent);
Collection.Scheduler.Dispose();

_transEmpTask.SetResult(false);
return;
@@ -439,7 +463,7 @@ public async Task<bool> BotOnline(BotOnlineEvent.OnlineReason reason = BotOnline
bool result = resp.Message.Contains("register success");
if (result)
{
Collection.Scheduler.Interval("SsoHeartBeat", (int)(4.5 * 60 * 1000), heartbeatDelegate);
Collection.Scheduler.Interval(SsoHeartbeatEvent, (int)(4.5 * 60 * 1000), heartbeatDelegate);

var onlineEvent = new BotOnlineEvent(reason);
Collection.Invoker.PostEvent(onlineEvent);
@@ -456,10 +480,10 @@ public async Task<bool> BotOnline(BotOnlineEvent.OnlineReason reason = BotOnline
return false;
}

private async Task<bool> FetchUnusual(CancellationToken ct)
private async Task<bool> FetchUnusual()
{
var transEmp = TransEmpEvent.Create(TransEmpEvent.State.FetchQrCode);
var result = await Collection.Business.SendEvent(transEmp, ct);
var result = await Collection.Business.SendEvent(transEmp, CancellationToken.None);

if (result.Count != 0)
{
@@ -470,11 +494,11 @@ private async Task<bool> FetchUnusual(CancellationToken ct)
return false;
}

private async Task<bool> DoUnusualEasyLogin(CancellationToken ct)
private async Task<bool> DoUnusualEasyLogin()
{
Collection.Log.LogInfo(Tag, "Trying to Login by EasyLogin...");
var unusualEvent = UnusualEasyLoginEvent.Create();
var result = await Collection.Business.SendEvent(unusualEvent, ct);
var result = await Collection.Business.SendEvent(unusualEvent, CancellationToken.None);
return result.Count != 0 && ((UnusualEasyLoginEvent)result[0]).Success;
}

@@ -495,7 +519,7 @@ private async Task ReLogin()
Collection.Keystore.ClearSession();
await Collection.Socket.Connect();

if (await KeyExchange(CancellationToken.None))
if (await KeyExchange())
{
var easyLoginEvent = EasyLoginEvent.Create();
var easyLoginResult = await Collection.Business.SendEvent(easyLoginEvent, CancellationToken.None);
@@ -523,5 +547,5 @@ private async Task ReLogin()
await BotOnline(BotOnlineEvent.OnlineReason.Reconnect);
}

public bool SubmitCaptcha(string ticket, string randStr) => _captchaTask?.TrySetResult((ticket, randStr)) ?? false;
public bool SubmitCaptcha(string ticket, string randStr) => _captchaTask.TrySetResult((ticket, randStr));
}
26 changes: 26 additions & 0 deletions Lagrange.Core/Internal/Event/Action/FetchGroupAtAllRemainEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
namespace Lagrange.Core.Internal.Event.Action;

internal class FetchGroupAtAllRemainEvent : ProtocolEvent
{
public uint GroupUin { get; set; }

public uint RemainAtAllCountForUin { get; set; }

public uint RemainAtAllCountForGroup { get; set; }

private FetchGroupAtAllRemainEvent(uint groupUin) : base(true)
{
GroupUin = groupUin;
}

private FetchGroupAtAllRemainEvent(int resultCode, uint remainAtAllCountForUin, uint remainAtAllCountForGroup) : base(resultCode)
{
RemainAtAllCountForUin = remainAtAllCountForUin;
RemainAtAllCountForGroup = remainAtAllCountForGroup;
}

public static FetchGroupAtAllRemainEvent Create(uint groupUin) => new(groupUin);

public static FetchGroupAtAllRemainEvent Result(int resultCode, uint remainAtAllCountForUin, uint remainAtAllCountForGroup) =>
new(resultCode, remainAtAllCountForUin, remainAtAllCountForGroup);
}
Loading

0 comments on commit cc3d489

Please sign in to comment.