From 139fc375e424830924d5806ce4d6bfc1975a5a55 Mon Sep 17 00:00:00 2001 From: femsci Date: Wed, 22 Feb 2023 22:03:01 +0100 Subject: [PATCH] Initial --- .gitignore | 2 ++ .nyoki | 3 +++ Delete.cs | 37 ++++++++++++++++++++++++++++ Disforget.csproj | 14 +++++++++++ Model.cs | 34 +++++++++++++++++++++++++ Program.cs | 15 ++++++++++++ Search.cs | 64 ++++++++++++++++++++++++++++++++++++++++++++++++ Utils.cs | 28 +++++++++++++++++++++ 8 files changed, 197 insertions(+) create mode 100644 .gitignore create mode 100644 .nyoki create mode 100644 Delete.cs create mode 100644 Disforget.csproj create mode 100644 Model.cs create mode 100644 Program.cs create mode 100644 Search.cs create mode 100644 Utils.cs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..afec7c2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +**/obj/ +**/bin/ diff --git a/.nyoki b/.nyoki new file mode 100644 index 0000000..470667a --- /dev/null +++ b/.nyoki @@ -0,0 +1,3 @@ +{ + "instanceId": "4676232f-d0d1-4991-9f13-65b4f3593d80" +} \ No newline at end of file diff --git a/Delete.cs b/Delete.cs new file mode 100644 index 0000000..133dbf6 --- /dev/null +++ b/Delete.cs @@ -0,0 +1,37 @@ +namespace Disforget; + +public class Delete +{ + public Delete(List messages) + { + _messages = messages; + _cli = Utils.CreateClient(); + } + + private HttpClient _cli; + private List _messages; + + public async Task StartDeletion() + { + int cnt = 1; + int repeats = 0; + foreach (var msg in _messages) + { + await Task.Delay(1500); + + REQ: + var resp = await _cli.DeleteAsync($"https://discord.com/api/v9/channels/{msg.ChannelId}/messages/{msg.Id}"); + + Console.Write($"\x1b[2K\rRequest {cnt}/{_messages.Count} Status: {resp.StatusCode} [{(resp.IsSuccessStatusCode ? "OK" : "REPEATING")}] ... ({_messages.Count - cnt} left)"); + if (!resp.IsSuccessStatusCode) + { + await Task.Delay(30000); + repeats++; + goto REQ; + } + cnt++; + } + + return repeats; + } +} diff --git a/Disforget.csproj b/Disforget.csproj new file mode 100644 index 0000000..c58d21f --- /dev/null +++ b/Disforget.csproj @@ -0,0 +1,14 @@ + + + + Exe + net6.0 + enable + enable + true + true + linux-x64 + true + + + diff --git a/Model.cs b/Model.cs new file mode 100644 index 0000000..52a4932 --- /dev/null +++ b/Model.cs @@ -0,0 +1,34 @@ +using System.Text.Json.Serialization; + +namespace Disforget; + +public record Response +{ + [JsonPropertyName("total_results")] + public int TotalResults { get; set; } + + [JsonPropertyName("messages")] + public IEnumerable> MessagesInternal { get; set; } = null!; + + [JsonIgnore] + public ICollection Messages => MessagesInternal.Select(m => m.First()).ToList(); +} + +public record Message +{ + [JsonPropertyName("id")] + public ulong Id { get; set; } + [JsonPropertyName("channel_id")] + public ulong ChannelId { get; set; } + + [JsonPropertyName("content")] + public string Content { get; set; } = null!; +} + +public record IdChn +{ + [JsonPropertyName("id")] + public ulong Id { get; set; } + [JsonPropertyName("chn")] + public ulong Channel { get; set; } +} diff --git a/Program.cs b/Program.cs new file mode 100644 index 0000000..a4ed7b6 --- /dev/null +++ b/Program.cs @@ -0,0 +1,15 @@ +using Disforget; + +int pages = int.Parse(args[0]); +ulong channel = ulong.Parse(args[1]); + +Console.WriteLine("Starting..."); + +Search search = new(channel, pages); + +var messages = await search.Perform(); + +Delete deletion = new(messages); +int reps = await deletion.StartDeletion(); + +Console.WriteLine($"\n\nDeleted {messages.Count} messages.\nResent {reps} deletion requests."); diff --git a/Search.cs b/Search.cs new file mode 100644 index 0000000..1f59615 --- /dev/null +++ b/Search.cs @@ -0,0 +1,64 @@ +using System.Net; +using System.Net.Http.Json; + +namespace Disforget; + +public class Search +{ + public Search(ulong channel, int pages) + { + _channel = channel; + _pages = pages; + _cli = Utils.CreateClient(); + } + + private HttpClient _cli; + private List _messages = new(); + private ulong _channel; + private int _pages, _total; + + public async Task> Perform() + { + int page = 0; + + while (page < _pages) + { + await DoSearch(page); + await Task.Delay(1500); + page++; + } + + Console.WriteLine($"\nFound and processed {_messages.Count} messages."); + + return _messages; + } + + private async Task DoSearch(int page) + { + var reqstr = $"https://discord.com/api/v9/guilds/790954455621304330/messages/search?author_id=340510759588986882&channel_id={_channel}&include_nsfw=true{(page > 0 ? $"&offset={page * 25}" : "")}"; + + REQ: + var resp = await _cli.GetAsync(reqstr); + + if (resp.StatusCode == HttpStatusCode.TooManyRequests) + { + await Task.Delay(30000); + Console.Write($"\x1b[2K\rRequest {++page}/{_pages} FAILED [REPEATING] ({_messages.Count}/{_total})"); + goto REQ; + } + + Response? result = await resp.Content.ReadFromJsonAsync(); + + if (result == null) + { + Console.WriteLine("Failed (null)..."); + Environment.Exit(3); + } + + _total = result.TotalResults; + + _messages.AddRange(result.Messages); + + Console.Write($"\x1b[2K\rRequest {++page}/{_pages} Status: {resp.StatusCode} ({_messages.Count}/{_total})"); + } +} diff --git a/Utils.cs b/Utils.cs new file mode 100644 index 0000000..b852b85 --- /dev/null +++ b/Utils.cs @@ -0,0 +1,28 @@ +namespace Disforget; + +public static class Utils +{ + public static void AddHeader(this HttpClient client, string h, string v) + { + if (!client.DefaultRequestHeaders.TryAddWithoutValidation(h, v)) + { + Console.Error.WriteLine($"Cannot add {h}: {v}"); + Environment.Exit(-3); + + } + } + + public static HttpClient CreateClient() + { + HttpClient cli = new(); + cli.AddHeader("authority", "discord.com"); + cli.AddHeader("x-discord-locale", "en-US"); + cli.AddHeader("accept-language", "en-US"); + cli.AddHeader("authorization", $""); + cli.AddHeader("user-agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) discord/0.0.21 Chrome/91.0.4472.164 Electron/13.6.6 Safari/537.36"); + cli.AddHeader("accept", "*/*"); + cli.AddHeader("cookie", ""); + + return cli; + } +}