Skip to content

Commit

Permalink
Add !debug overrides add
Browse files Browse the repository at this point in the history
  • Loading branch information
FloatingMilkshake committed Jul 31, 2024
1 parent 25f500c commit 8e86957
Show file tree
Hide file tree
Showing 3 changed files with 194 additions and 0 deletions.
36 changes: 36 additions & 0 deletions Commands/Debug.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
{
internal class Debug : BaseCommandModule
{
public static Dictionary<ulong, PendingUserOverride> OverridesPendingAddition = new();

[Group("debug")]
[Aliases("troubleshoot", "unbug", "bugn't", "helpsomethinghasgoneverywrong")]
[Description("Commands and things for fixing the bot in the unlikely event that it breaks a bit.")]
Expand Down Expand Up @@ -345,6 +347,40 @@ public async Task ImportAll(CommandContext ctx)
await msg.ModifyAsync($"{Program.cfgjson.Emoji.Success} All overrides imported successfully!");
}

[Command("add")]
[Description("Insert an override into the db. Useful if you want to add an override for a user who has left.")]
[IsBotOwner]
public async Task Add(CommandContext ctx,
[Description("The user to add an override for.")] DiscordUser user,
[Description("The channel to add the override to.")] DiscordChannel channel,
[Description("Allowed permissions. Use a permission integer. See https://discordlookup.com/permissions-calculator.")] int allowedPermissions,
[Description("Denied permissions. Use a permission integer. See https://discordlookup.com/permissions-calculator.")] int deniedPermissions)
{
// Confirm permission overrides before we do anything.
var parsedAllowedPerms = (DiscordPermissions)allowedPermissions;
var parsedDeniedPerms = (DiscordPermissions)deniedPermissions;

var confirmButton = new DiscordButtonComponent(DiscordButtonStyle.Success, "debug-overrides-add-confirm-callback", "Yes");
var cancelButton = new DiscordButtonComponent(DiscordButtonStyle.Danger, "debug-overrides-add-cancel-callback", "No");

var confirmationMessage = await ctx.RespondAsync(new DiscordMessageBuilder().WithContent(
$"{Program.cfgjson.Emoji.ShieldHelp} Just to confirm, you want to add the following override for {user.Mention} to {channel.Mention}?\n" +
$"**Allowed:** {parsedAllowedPerms}\n" +
$"**Denied:** {parsedDeniedPerms}\n")
.AddComponents([confirmButton, cancelButton]));

OverridesPendingAddition.Add(confirmationMessage.Id, new PendingUserOverride
{
ChannelId = channel.Id,
Overwrite = new MockUserOverwrite
{
Id = user.Id,
Allowed = parsedAllowedPerms,
Denied = parsedDeniedPerms
}
});
}

[Command("remove")]
[Description("Remove a user's overrides for a channel from the database.")]
public async Task Remove(CommandContext ctx,
Expand Down
134 changes: 134 additions & 0 deletions Events/InteractionEvents.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,140 @@ await LogChannelHelper.LogDeletedMessagesAsync(

await e.Interaction.CreateFollowupMessageAsync(new DiscordFollowupMessageBuilder().WithContent($"{cfgjson.Emoji.Success} Done!").AsEphemeral(true));
}
else if (e.Id == "debug-overrides-add-confirm-callback")
{
await e.Interaction.CreateResponseAsync(DiscordInteractionResponseType.DeferredMessageUpdate);

var overridesPendingAddition = Commands.Debug.OverridesPendingAddition;
if (!overridesPendingAddition.ContainsKey(e.Message.Id))
{
await e.Channel.SendMessageAsync(new DiscordMessageBuilder().WithContent($"{cfgjson.Emoji.Error} {e.User.Mention}, this action has already been completed!").WithReply(e.Message.Id));

// Remove buttons from original message so this doesn't happen again
var originalMsgWithoutButtons = new DiscordMessageBuilder(e.Message);
originalMsgWithoutButtons.ClearComponents();
await e.Message.ModifyAsync(originalMsgWithoutButtons);

return;
}

// Get override data
var pendingOverride = overridesPendingAddition.GetValueOrDefault(e.Message.Id);
var mockOverwrite = pendingOverride.Overwrite;
var channelId = pendingOverride.ChannelId;

// 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.
// 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.
var newOverwrite = JsonConvert.DeserializeObject<DiscordOverwrite>(JsonConvert.SerializeObject(mockOverwrite));

// Get current overrides for user in db
var userOverwrites = await db.HashGetAsync("overrides", mockOverwrite.Id);
if (userOverwrites.IsNullOrEmpty)
{
// No overwrites for this user yet, create a list and add to it

var overwrites = new Dictionary<string, DiscordOverwrite> { { channelId.ToString(), newOverwrite } };
await db.HashSetAsync("overrides", mockOverwrite.Id, JsonConvert.SerializeObject(overwrites));
}
else
{
// Overwrites for user exist, add to them

var overwrites = JsonConvert.DeserializeObject<Dictionary<string, DiscordOverwrite>>(userOverwrites);
if (overwrites.ContainsKey(channelId.ToString()))
{
// Require extra confirmation for merging permissions!
var mergeConfirmResponse = new DiscordMessageBuilder()
.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}")
.AddComponents(new DiscordButtonComponent(DiscordButtonStyle.Danger, "debug-overrides-add-merge-confirm-callback", "Merge"), new DiscordButtonComponent(DiscordButtonStyle.Primary, "debug-overrides-add-cancel-callback", "Cancel"));

await e.Message.ModifyAsync(mergeConfirmResponse);
return;
}
else
{
overwrites.Add(channelId.ToString(), newOverwrite);
}
// Update db
await db.HashSetAsync("overrides", mockOverwrite.Id, JsonConvert.SerializeObject(overwrites));
}

// Remove from db so the override is not added again
overridesPendingAddition.Remove(e.Message.Id);

// Respond
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}"));
}
else if (e.Id == "debug-overrides-add-cancel-callback")
{
await e.Interaction.CreateResponseAsync(DiscordInteractionResponseType.DeferredMessageUpdate);

var overridesPendingAddition = Commands.Debug.OverridesPendingAddition;
if (!overridesPendingAddition.ContainsKey(e.Message.Id))
{
await e.Channel.SendMessageAsync(new DiscordMessageBuilder().WithContent($"{cfgjson.Emoji.Error} {e.User.Mention}, this action has already been completed!").WithReply(e.Message.Id));

// Remove buttons from original message so this doesn't happen again
var originalMsgWithoutButtons = new DiscordMessageBuilder(e.Message);
originalMsgWithoutButtons.ClearComponents();
await e.Message.ModifyAsync(originalMsgWithoutButtons);

return;
}

await e.Message.ModifyAsync(new DiscordMessageBuilder().WithContent($"{Program.cfgjson.Emoji.Error} Cancelled! Nothing was changed."));
overridesPendingAddition.Remove(e.Message.Id);
}
else if (e.Id == "debug-overrides-add-merge-confirm-callback")
{
// User already has an overwrite for the requested channel!
// Merge the permissions of the current & new overrides.

await e.Interaction.CreateResponseAsync(DiscordInteractionResponseType.DeferredMessageUpdate);

var overridesPendingAddition = Commands.Debug.OverridesPendingAddition;
if (!overridesPendingAddition.ContainsKey(e.Message.Id))
{
await e.Channel.SendMessageAsync(new DiscordMessageBuilder().WithContent($"{cfgjson.Emoji.Error} {e.User.Mention}, this action has already been completed!").WithReply(e.Message.Id));

// Remove buttons from original message so this doesn't happen again
var originalMsgWithoutButtons = new DiscordMessageBuilder(e.Message);
originalMsgWithoutButtons.ClearComponents();
await e.Message.ModifyAsync(originalMsgWithoutButtons);

return;
}

// Get new override data
var pendingOverride = overridesPendingAddition.GetValueOrDefault(e.Message.Id);
var mockOverwrite = pendingOverride.Overwrite;
var channelId = pendingOverride.ChannelId;
var newOverwrite = JsonConvert.DeserializeObject<DiscordOverwrite>(JsonConvert.SerializeObject(mockOverwrite));

// Existing override data
var userOverwrites = await db.HashGetAsync("overrides", mockOverwrite.Id);
var overwrites = JsonConvert.DeserializeObject<Dictionary<string, DiscordOverwrite>>(userOverwrites);

// Merge permissions
var existingOverwrite = overwrites[channelId.ToString()];
var newMockOverwrite = new MockUserOverwrite
{
Id = mockOverwrite.Id,
Allowed = newOverwrite.Allowed | existingOverwrite.Allowed,
Denied = newOverwrite.Denied | existingOverwrite.Denied
};

// Cursed conversion again
newOverwrite = JsonConvert.DeserializeObject<DiscordOverwrite>(JsonConvert.SerializeObject(newMockOverwrite));

overwrites[channelId.ToString()] = newOverwrite;

// Update db
await db.HashSetAsync("overrides", mockOverwrite.Id, JsonConvert.SerializeObject(overwrites));

// Respond
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}"));
}
else
{
await e.Interaction.CreateResponseAsync(DiscordInteractionResponseType.ChannelMessageWithSource, new DiscordInteractionResponseBuilder().WithContent("Unknown interaction. I don't know what you are asking me for.").AsEphemeral(true));
Expand Down
24 changes: 24 additions & 0 deletions Structs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -611,4 +611,28 @@ public class UserNote
public WarningType Type { get; set; }
}

public class PendingUserOverride
{
[JsonProperty("channelId")]
public ulong ChannelId { get; set; }

[JsonProperty("overwrite")]
public MockUserOverwrite Overwrite { get; set; }
}

public class MockUserOverwrite
{
[JsonProperty("type")]
public int Type { get; } = 1;

[JsonProperty("allow")]
public DiscordPermissions Allowed { get; set; }

[JsonProperty("deny")]
public DiscordPermissions Denied { get; set; }

[JsonProperty("id")]
public ulong Id { get; set; }
}

}

0 comments on commit 8e86957

Please sign in to comment.