mirror of
https://github.com/wiz0u/WTelegramClient.git
synced 2026-01-09 02:00:29 +01:00
renamed Channels_GetAllParticipantsSlow. use clever alphabet and detect lying subcounts to fetch more entries. (WIP)
This commit is contained in:
parent
e36ea252fb
commit
5e5e51102f
|
|
@ -1630,13 +1630,18 @@ namespace WTelegram
|
|||
/// <summary>Helper method that tries to fetch all participants from a Channel (beyond Telegram server-side limitations)</summary>
|
||||
/// <param name="channel">The channel to query</param>
|
||||
/// <param name="includeKickBan">Also fetch the kicked/banned members?</param>
|
||||
/// <param name="alphabet1">first letters used to search for in participants names<br/>(default values crafted with ♥ to find most latin and cyrillic names)</param>
|
||||
/// <param name="alphabet2">second (and further) letters used to search for in participants names</param>
|
||||
/// <returns>Field count indicates the total count of members. Field participants contains those that were successfully fetched</returns>
|
||||
/// <remarks>This method can take a few minutes to complete on big channels. It likely won't be able to obtain the full total count of members</remarks>
|
||||
public async Task<Channels_ChannelParticipants> Channels_GetAllParticipants(InputChannelBase channel, bool includeKickBan = false)
|
||||
/// <remarks>⚠ This method can take a few minutes to complete on big broadcast channels. It likely won't be able to obtain the full total count of members</remarks>
|
||||
public async Task<Channels_ChannelParticipants> Channels_GetAllParticipantsSlow(InputChannelBase channel, bool includeKickBan = false, string alphabet1 = "АБCДЕЄЖФГHИІJКЛМНОПQРСТУВWХЦЧШЩЫЮЯЗ", string alphabet2 = "АCЕHИJЛМНОРСТУВWЫ")
|
||||
{
|
||||
alphabet2 ??= alphabet1;
|
||||
File.AppendAllText("AllPart.txt", alphabet1 + "\n");
|
||||
var sw = System.Diagnostics.Stopwatch.StartNew();
|
||||
var result = new Channels_ChannelParticipants { chats = new(), users = new() };
|
||||
|
||||
var sem = new SemaphoreSlim(10); // prevents flooding Telegram with requests
|
||||
var sem = new SemaphoreSlim(1); // prevents flooding Telegram with requests
|
||||
var user_ids = new HashSet<long>();
|
||||
var participants = new List<ChannelParticipantBase>();
|
||||
|
||||
|
|
@ -1644,30 +1649,33 @@ namespace WTelegram
|
|||
{
|
||||
GetWithFilter(new ChannelParticipantsAdmins()),
|
||||
GetWithFilter(new ChannelParticipantsBots()),
|
||||
GetWithFilter(new ChannelParticipantsSearch { q = "" }, (f, c) => new ChannelParticipantsSearch { q = f.q + c }),
|
||||
GetWithFilter(new ChannelParticipantsSearch { q = "" }, (f, c) => new ChannelParticipantsSearch { q = f.q + c }, alphabet1),
|
||||
};
|
||||
var mcf = this.Channels_GetFullChannel(channel);
|
||||
tasks.Add(mcf);
|
||||
if (includeKickBan)
|
||||
{
|
||||
tasks.Add(GetWithFilter(new ChannelParticipantsKicked { q = "" }, (f, c) => new ChannelParticipantsKicked { q = f.q + c }));
|
||||
tasks.Add(GetWithFilter(new ChannelParticipantsBanned { q = "" }, (f, c) => new ChannelParticipantsBanned { q = f.q + c }));
|
||||
tasks.Add(GetWithFilter(new ChannelParticipantsKicked { q = "" }, (f, c) => new ChannelParticipantsKicked { q = f.q + c }, alphabet1));
|
||||
tasks.Add(GetWithFilter(new ChannelParticipantsBanned { q = "" }, (f, c) => new ChannelParticipantsBanned { q = f.q + c }, alphabet1));
|
||||
}
|
||||
await Task.WhenAll(tasks);
|
||||
|
||||
result.count = ((ChannelFull)mcf.Result.full_chat).participants_count;
|
||||
result.participants = participants.ToArray();
|
||||
File.AppendAllText("AllPart.txt", $"{alphabet1} {participants.Count}/{result.count} in {sw.Elapsed}\n");
|
||||
return result;
|
||||
|
||||
async Task GetWithFilter<T>(T filter, Func<T, char, T> recurse = null) where T : ChannelParticipantsFilter
|
||||
async Task GetWithFilter<T>(T filter, Func<T, char, T> recurse = null, string alphabet = null) where T : ChannelParticipantsFilter
|
||||
{
|
||||
Channels_ChannelParticipants ccp;
|
||||
int maxCount = 0;
|
||||
for (int offset = 0; ;)
|
||||
{
|
||||
await sem.WaitAsync();
|
||||
try
|
||||
{
|
||||
ccp = await this.Channels_GetParticipants(channel, filter, offset, 1024, 0);
|
||||
if (ccp.count > maxCount) maxCount = ccp.count;
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
|
@ -1682,8 +1690,10 @@ namespace WTelegram
|
|||
offset += ccp.participants.Length;
|
||||
if (offset >= ccp.count || ccp.participants.Length == 0) break;
|
||||
}
|
||||
if (recurse != null && (ccp.count == 200 || ccp.count == 1000))
|
||||
await Task.WhenAll(Enumerable.Range('a', 26).Select(c => GetWithFilter(recurse(filter, (char)c), recurse)));
|
||||
Console.WriteLine($"{participants.Count} {(filter as ChannelParticipantsSearch)?.q} {ccp.count} {maxCount}");
|
||||
File.AppendAllText("AllPart.txt", $"{(filter as ChannelParticipantsSearch)?.q}\t{participants.Count,4}\t{ccp.count}/{maxCount}\n");
|
||||
if (recurse != null && (ccp.count < maxCount - 100 || ccp.count == 200 || ccp.count == 1000))
|
||||
await Task.WhenAll(alphabet.Select(c => GetWithFilter(recurse(filter, (char)c), recurse, c == 'А' ? alphabet : alphabet2)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue