Skip to content

Commit 8e86957

Browse files
Add !debug overrides add
1 parent 25f500c commit 8e86957

File tree

3 files changed

+194
-0
lines changed

3 files changed

+194
-0
lines changed

Commands/Debug.cs

+36
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
{
33
internal class Debug : BaseCommandModule
44
{
5+
public static Dictionary<ulong, PendingUserOverride> OverridesPendingAddition = new();
6+
57
[Group("debug")]
68
[Aliases("troubleshoot", "unbug", "bugn't", "helpsomethinghasgoneverywrong")]
79
[Description("Commands and things for fixing the bot in the unlikely event that it breaks a bit.")]
@@ -345,6 +347,40 @@ public async Task ImportAll(CommandContext ctx)
345347
await msg.ModifyAsync($"{Program.cfgjson.Emoji.Success} All overrides imported successfully!");
346348
}
347349

350+
[Command("add")]
351+
[Description("Insert an override into the db. Useful if you want to add an override for a user who has left.")]
352+
[IsBotOwner]
353+
public async Task Add(CommandContext ctx,
354+
[Description("The user to add an override for.")] DiscordUser user,
355+
[Description("The channel to add the override to.")] DiscordChannel channel,
356+
[Description("Allowed permissions. Use a permission integer. See https://discordlookup.com/permissions-calculator.")] int allowedPermissions,
357+
[Description("Denied permissions. Use a permission integer. See https://discordlookup.com/permissions-calculator.")] int deniedPermissions)
358+
{
359+
// Confirm permission overrides before we do anything.
360+
var parsedAllowedPerms = (DiscordPermissions)allowedPermissions;
361+
var parsedDeniedPerms = (DiscordPermissions)deniedPermissions;
362+
363+
var confirmButton = new DiscordButtonComponent(DiscordButtonStyle.Success, "debug-overrides-add-confirm-callback", "Yes");
364+
var cancelButton = new DiscordButtonComponent(DiscordButtonStyle.Danger, "debug-overrides-add-cancel-callback", "No");
365+
366+
var confirmationMessage = await ctx.RespondAsync(new DiscordMessageBuilder().WithContent(
367+
$"{Program.cfgjson.Emoji.ShieldHelp} Just to confirm, you want to add the following override for {user.Mention} to {channel.Mention}?\n" +
368+
$"**Allowed:** {parsedAllowedPerms}\n" +
369+
$"**Denied:** {parsedDeniedPerms}\n")
370+
.AddComponents([confirmButton, cancelButton]));
371+
372+
OverridesPendingAddition.Add(confirmationMessage.Id, new PendingUserOverride
373+
{
374+
ChannelId = channel.Id,
375+
Overwrite = new MockUserOverwrite
376+
{
377+
Id = user.Id,
378+
Allowed = parsedAllowedPerms,
379+
Denied = parsedDeniedPerms
380+
}
381+
});
382+
}
383+
348384
[Command("remove")]
349385
[Description("Remove a user's overrides for a channel from the database.")]
350386
public async Task Remove(CommandContext ctx,

Events/InteractionEvents.cs

+134
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,140 @@ await LogChannelHelper.LogDeletedMessagesAsync(
6666

6767
await e.Interaction.CreateFollowupMessageAsync(new DiscordFollowupMessageBuilder().WithContent($"{cfgjson.Emoji.Success} Done!").AsEphemeral(true));
6868
}
69+
else if (e.Id == "debug-overrides-add-confirm-callback")
70+
{
71+
await e.Interaction.CreateResponseAsync(DiscordInteractionResponseType.DeferredMessageUpdate);
72+
73+
var overridesPendingAddition = Commands.Debug.OverridesPendingAddition;
74+
if (!overridesPendingAddition.ContainsKey(e.Message.Id))
75+
{
76+
await e.Channel.SendMessageAsync(new DiscordMessageBuilder().WithContent($"{cfgjson.Emoji.Error} {e.User.Mention}, this action has already been completed!").WithReply(e.Message.Id));
77+
78+
// Remove buttons from original message so this doesn't happen again
79+
var originalMsgWithoutButtons = new DiscordMessageBuilder(e.Message);
80+
originalMsgWithoutButtons.ClearComponents();
81+
await e.Message.ModifyAsync(originalMsgWithoutButtons);
82+
83+
return;
84+
}
85+
86+
// Get override data
87+
var pendingOverride = overridesPendingAddition.GetValueOrDefault(e.Message.Id);
88+
var mockOverwrite = pendingOverride.Overwrite;
89+
var channelId = pendingOverride.ChannelId;
90+
91+
// This is really cursed, but it effectively converts our mock DiscordOverwrite into an actual one so that it can be added to the current list of overwrites.
92+
// Since the mock overwrite serializes into the same format as a DiscordOverwrite, we can serialize it and then deserialize it back to DiscordOverwrite to convert it.
93+
var newOverwrite = JsonConvert.DeserializeObject<DiscordOverwrite>(JsonConvert.SerializeObject(mockOverwrite));
94+
95+
// Get current overrides for user in db
96+
var userOverwrites = await db.HashGetAsync("overrides", mockOverwrite.Id);
97+
if (userOverwrites.IsNullOrEmpty)
98+
{
99+
// No overwrites for this user yet, create a list and add to it
100+
101+
var overwrites = new Dictionary<string, DiscordOverwrite> { { channelId.ToString(), newOverwrite } };
102+
await db.HashSetAsync("overrides", mockOverwrite.Id, JsonConvert.SerializeObject(overwrites));
103+
}
104+
else
105+
{
106+
// Overwrites for user exist, add to them
107+
108+
var overwrites = JsonConvert.DeserializeObject<Dictionary<string, DiscordOverwrite>>(userOverwrites);
109+
if (overwrites.ContainsKey(channelId.ToString()))
110+
{
111+
// Require extra confirmation for merging permissions!
112+
var mergeConfirmResponse = new DiscordMessageBuilder()
113+
.WithContent($"{cfgjson.Emoji.Warning} **Caution:** This user already has an override for <#{channelId}>! Do you want to merge the permissions? Here are their **current** permissions:\n**Allowed:** {overwrites[channelId.ToString()].Allowed}\n**Denied:** {overwrites[channelId.ToString()].Denied}")
114+
.AddComponents(new DiscordButtonComponent(DiscordButtonStyle.Danger, "debug-overrides-add-merge-confirm-callback", "Merge"), new DiscordButtonComponent(DiscordButtonStyle.Primary, "debug-overrides-add-cancel-callback", "Cancel"));
115+
116+
await e.Message.ModifyAsync(mergeConfirmResponse);
117+
return;
118+
}
119+
else
120+
{
121+
overwrites.Add(channelId.ToString(), newOverwrite);
122+
}
123+
// Update db
124+
await db.HashSetAsync("overrides", mockOverwrite.Id, JsonConvert.SerializeObject(overwrites));
125+
}
126+
127+
// Remove from db so the override is not added again
128+
overridesPendingAddition.Remove(e.Message.Id);
129+
130+
// Respond
131+
await e.Message.ModifyAsync(new DiscordMessageBuilder().WithContent($"{cfgjson.Emoji.Success} Successfully added the following override for <@{newOverwrite.Id}> to <#{pendingOverride.ChannelId}>!\n**Allowed:** {newOverwrite.Allowed}\n**Denied:** {newOverwrite.Denied}"));
132+
}
133+
else if (e.Id == "debug-overrides-add-cancel-callback")
134+
{
135+
await e.Interaction.CreateResponseAsync(DiscordInteractionResponseType.DeferredMessageUpdate);
136+
137+
var overridesPendingAddition = Commands.Debug.OverridesPendingAddition;
138+
if (!overridesPendingAddition.ContainsKey(e.Message.Id))
139+
{
140+
await e.Channel.SendMessageAsync(new DiscordMessageBuilder().WithContent($"{cfgjson.Emoji.Error} {e.User.Mention}, this action has already been completed!").WithReply(e.Message.Id));
141+
142+
// Remove buttons from original message so this doesn't happen again
143+
var originalMsgWithoutButtons = new DiscordMessageBuilder(e.Message);
144+
originalMsgWithoutButtons.ClearComponents();
145+
await e.Message.ModifyAsync(originalMsgWithoutButtons);
146+
147+
return;
148+
}
149+
150+
await e.Message.ModifyAsync(new DiscordMessageBuilder().WithContent($"{Program.cfgjson.Emoji.Error} Cancelled! Nothing was changed."));
151+
overridesPendingAddition.Remove(e.Message.Id);
152+
}
153+
else if (e.Id == "debug-overrides-add-merge-confirm-callback")
154+
{
155+
// User already has an overwrite for the requested channel!
156+
// Merge the permissions of the current & new overrides.
157+
158+
await e.Interaction.CreateResponseAsync(DiscordInteractionResponseType.DeferredMessageUpdate);
159+
160+
var overridesPendingAddition = Commands.Debug.OverridesPendingAddition;
161+
if (!overridesPendingAddition.ContainsKey(e.Message.Id))
162+
{
163+
await e.Channel.SendMessageAsync(new DiscordMessageBuilder().WithContent($"{cfgjson.Emoji.Error} {e.User.Mention}, this action has already been completed!").WithReply(e.Message.Id));
164+
165+
// Remove buttons from original message so this doesn't happen again
166+
var originalMsgWithoutButtons = new DiscordMessageBuilder(e.Message);
167+
originalMsgWithoutButtons.ClearComponents();
168+
await e.Message.ModifyAsync(originalMsgWithoutButtons);
169+
170+
return;
171+
}
172+
173+
// Get new override data
174+
var pendingOverride = overridesPendingAddition.GetValueOrDefault(e.Message.Id);
175+
var mockOverwrite = pendingOverride.Overwrite;
176+
var channelId = pendingOverride.ChannelId;
177+
var newOverwrite = JsonConvert.DeserializeObject<DiscordOverwrite>(JsonConvert.SerializeObject(mockOverwrite));
178+
179+
// Existing override data
180+
var userOverwrites = await db.HashGetAsync("overrides", mockOverwrite.Id);
181+
var overwrites = JsonConvert.DeserializeObject<Dictionary<string, DiscordOverwrite>>(userOverwrites);
182+
183+
// Merge permissions
184+
var existingOverwrite = overwrites[channelId.ToString()];
185+
var newMockOverwrite = new MockUserOverwrite
186+
{
187+
Id = mockOverwrite.Id,
188+
Allowed = newOverwrite.Allowed | existingOverwrite.Allowed,
189+
Denied = newOverwrite.Denied | existingOverwrite.Denied
190+
};
191+
192+
// Cursed conversion again
193+
newOverwrite = JsonConvert.DeserializeObject<DiscordOverwrite>(JsonConvert.SerializeObject(newMockOverwrite));
194+
195+
overwrites[channelId.ToString()] = newOverwrite;
196+
197+
// Update db
198+
await db.HashSetAsync("overrides", mockOverwrite.Id, JsonConvert.SerializeObject(overwrites));
199+
200+
// Respond
201+
await e.Message.ModifyAsync(new DiscordMessageBuilder().WithContent($"{cfgjson.Emoji.Success} Override successfully added. <@{newOverwrite.Id}> already had an override in <#{pendingOverride.ChannelId}>, so here are their new permissions:\n**Allowed:** {newOverwrite.Allowed}\n**Denied:** {newOverwrite.Denied}"));
202+
}
69203
else
70204
{
71205
await e.Interaction.CreateResponseAsync(DiscordInteractionResponseType.ChannelMessageWithSource, new DiscordInteractionResponseBuilder().WithContent("Unknown interaction. I don't know what you are asking me for.").AsEphemeral(true));

Structs.cs

+24
Original file line numberDiff line numberDiff line change
@@ -611,4 +611,28 @@ public class UserNote
611611
public WarningType Type { get; set; }
612612
}
613613

614+
public class PendingUserOverride
615+
{
616+
[JsonProperty("channelId")]
617+
public ulong ChannelId { get; set; }
618+
619+
[JsonProperty("overwrite")]
620+
public MockUserOverwrite Overwrite { get; set; }
621+
}
622+
623+
public class MockUserOverwrite
624+
{
625+
[JsonProperty("type")]
626+
public int Type { get; } = 1;
627+
628+
[JsonProperty("allow")]
629+
public DiscordPermissions Allowed { get; set; }
630+
631+
[JsonProperty("deny")]
632+
public DiscordPermissions Denied { get; set; }
633+
634+
[JsonProperty("id")]
635+
public ulong Id { get; set; }
636+
}
637+
614638
}

0 commit comments

Comments
 (0)