-
Notifications
You must be signed in to change notification settings - Fork 34
/
Copy pathPull.cs
148 lines (142 loc) · 7.05 KB
/
Pull.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
using Discord.WebSocket;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using RestoreCord.Miscellaneous;
using RestoreCord.Schema.DiscordModels;
namespace RestoreCord.Commands
{
public class Pull
{
private static HashSet<ulong> ActiveDiscordServers = new();
public static async Task Execute(SocketSlashCommand cmd)
{
try
{
//check perms in the server
Services.Database database = new();
var guild = (cmd.Channel as SocketGuildChannel).Guild;
if (guild is null)
{
await cmd.ReplyWithEmbedAsync("Server Error", "This command can only executed in guilds/servers.");
return;
}
var serverentry = await database.servers.FirstOrDefaultAsync(x => x.guildid == guild.Id);
if (serverentry is null)
{
await cmd.ReplyWithEmbedAsync("Server Error", "Server doesn't exist in the database...");
return;
}
//if (serverentry.owner != cmd.User.Id)//not guild owner
//{
// await cmd.ReplyWithEmbedAsync("Permission Error", "not owner of guild");
// return;
//}
if (!database.members.Any(x => x.server == guild.Id))
{
await cmd.ReplyWithEmbedAsync("Member Error", "You have no members backed up!");
return;
}
if (ActiveDiscordServers.Contains(guild.Id))
{
await cmd.ReplyWithEmbedAsync("Migration Progress", "Already pulling all users to this guild, please wait.");
return;
}
await JoinUsersToGuild(cmd, database, serverentry);
}
catch (Exception e)
{
ActiveDiscordServers.Remove((cmd.Channel as SocketGuildChannel).Guild.Id);
await e.LogErrorAsync();
await cmd.SendEmbedAsync("Migration Error", "An error, occured while migrating the database, please try again. If the error persists, please contact support.");
}
}
private static async Task JoinUsersToGuild(SocketSlashCommand cmd, Services.Database database, Schema.Server server)
{
int memberCount = 0, successfulPullCount = 0;
ActiveDiscordServers.Add((ulong)server.guildid);
await cmd.ReplyWithEmbedAsync("Migration Progress", "Attempting to pull all users from database into this guild, please wait...");
var members = await database.members.ToListAsync();
foreach (var member in members)
{
if (member.server is null)
continue;
if (member.server != server.guildid)
continue;
memberCount++;
//await cmd.SendEmbedAsync("member info", $"{member.userid}\n{member.access_token}\n{member.refresh_token}");
if (await cmd.AddUserToGuild(member, server) != HttpStatusCode.OK)
{
//failed to join guild
if (await RefreshUserToken(cmd, member, database) != HttpStatusCode.OK)
{
//failed to refresh token
//check possible failure & then delete token if it was a bad response
continue;
}
if (await cmd.AddUserToGuild(member, server) != HttpStatusCode.OK)
{
//failed to join guild after the token refresh
//investigate whats going on here & delete entry
continue;
}
}
successfulPullCount++;
await Task.Delay(60);
}
ActiveDiscordServers.Remove((ulong)server.guildid);
await cmd.SendEmbedAsync("Migration Progress", (successfulPullCount == memberCount) ? $"Finished pulling & joining all {memberCount} users from the database to this guild!" : $"Finished successfully pulling & joining {successfulPullCount} out of {memberCount} users from the database to this guild!");
}
private static async Task<HttpStatusCode> RefreshUserToken(SocketSlashCommand cmd, Schema.Member member, Services.Database database)
{
try
{
var web = new WebClient();
web.Headers.Add("Content-Type", $"application/x-www-form-urlencoded");
var result = JsonConvert.DeserializeObject<API.RefreshTokenInfo>(Encoding.Default.GetString(web.UploadValues("https://discordapp.com/api/oauth2/token", new NameValueCollection
{
["client_id"] = Properties.Resources.ClientID,
["client_secret"] = Properties.Resources.ClientSecret,
["grant_type"] = "refresh_token",
["refresh_token"] = member.refresh_token,
["redirect_uri"] = "https://restorecord.com/auth/",
["scope"] = "identify guilds.join"
})));
if (result is null)
return HttpStatusCode.BadRequest;
//await cmd.SendEmbedAsync("test", $"token was refreshed, should be saving it to the db now\n{result.access_token}\n{result.refresh_token}");
member.access_token = result.access_token;
member.refresh_token = result.refresh_token;
await database.SaveChangesAsync();
//await cmd.SendEmbedAsync("test", $"{member.access_token}\n{member.refresh_token}");
return HttpStatusCode.OK;
}
catch (WebException webex)
{
var response = (HttpWebResponse)webex.Response;
switch (response.StatusCode)
{
case HttpStatusCode.TooManyRequests:
var headervalue = webex.Response.Headers.getHeader("Retry-After");
if (headervalue is not null)
{
Thread.Sleep(Convert.ToInt32(headervalue));
//run it again
if (await RefreshUserToken(cmd, member, database) == HttpStatusCode.OK)
return HttpStatusCode.OK;
}
return response.StatusCode;
default:
//await cmd.SendEmbedAsync("refresh token exception", $"{response.StatusCode}\n{webex}\n{response}");
return response.StatusCode;
}
}
}
}
}