Skip to content

Commit

Permalink
Text commands, preconditions, and some functions
Browse files Browse the repository at this point in the history
Glowstudent777 committed Apr 17, 2024
1 parent 8237d99 commit 8531e23
Showing 8 changed files with 403 additions and 0 deletions.
67 changes: 67 additions & 0 deletions src/Houston.Bot/Common/ApiClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Houston.Bot.Common;

public static class ApiClient
{
public static async Task<ApiResponse> GetAsync(string url, Dictionary<string, string> headers = null)
{
using (HttpClient httpClient = new HttpClient())
{
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, url);
request = AddHeaders(request, headers);

HttpResponseMessage response = await httpClient.SendAsync(request);

ApiResponse apiResponse = new ApiResponse
{
StatusCode = (int)response.StatusCode,
Message = await response.Content.ReadAsStringAsync()
};

return apiResponse;
}
}

public static async Task<ApiResponse> PostAsync(string url, string content, Dictionary<string, string> headers = null)
{
using (HttpClient httpClient = new HttpClient())
{
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, url);
request.Content = new StringContent(content);
request = AddHeaders(request, headers);

HttpResponseMessage response = await httpClient.SendAsync(request);

ApiResponse apiResponse = new ApiResponse
{
StatusCode = (int)response.StatusCode,
Message = await response.Content.ReadAsStringAsync()
};

return apiResponse;
}
}

private static HttpRequestMessage AddHeaders(HttpRequestMessage request, Dictionary<string, string> headers)
{
if (headers is not null)
{
foreach (KeyValuePair<string, string> header in headers)
{
request.Headers.Add(header.Key, header.Value);
}
}
return request;
}

public class ApiResponse
{
public int StatusCode { get; set; }
public string Message { get; set; }
}
}
74 changes: 74 additions & 0 deletions src/Houston.Bot/Common/GenerateMessage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using Discord;
using Discord.Commands;

namespace Houston.Bot.Common;

public class GenerateMessage
{
public static async Task Error(
dynamic context,
string? title = null,
string? description = null,
string? footer = null,
string? thumbnail = null,
string? image = null,
string? color = null,
bool embeded = true,
bool supportinvite = false,
bool ephemeral = false
)
{

var embedBuilder = new EmbedBuilder()
.WithColor(Config.Colors.Error)
.WithTitle("An Error has Occured");

// Support Invite Button
var SupportButton = new ComponentBuilder()
.WithButton("Support Server", null, ButtonStyle.Link, url: Config.SupportServer);

if (string.IsNullOrEmpty(description))
description = "If this error persists please open a support ticket.";

if (!string.IsNullOrEmpty(title))
embedBuilder.WithTitle(title);

if (!string.IsNullOrEmpty(description))
embedBuilder.WithDescription(description);

if (!string.IsNullOrEmpty(footer))
embedBuilder.WithFooter(footer);

if (!string.IsNullOrEmpty(thumbnail))
embedBuilder.WithThumbnailUrl(thumbnail);

if (!string.IsNullOrEmpty(image))
embedBuilder.WithImageUrl(image);

if (!string.IsNullOrEmpty(color))
embedBuilder.WithColor(new Color(Convert.ToUInt32(color, 16)));

if (context is IInteractionContext interactionContext)
{
if (embeded)
if (interactionContext.Interaction.HasResponded)
await interactionContext.Interaction.FollowupAsync(embed: embedBuilder.Build(), components: supportinvite ? SupportButton.Build() : null, ephemeral: ephemeral);
else
await interactionContext.Interaction.RespondAsync(embed: embedBuilder.Build(), components: supportinvite ? SupportButton.Build() : null, ephemeral: ephemeral);
else
if (interactionContext.Interaction.HasResponded)
await interactionContext.Interaction.FollowupAsync(description, components: supportinvite ? SupportButton.Build() : null, ephemeral: ephemeral);
else
await interactionContext.Interaction.RespondAsync(description, components: supportinvite ? SupportButton.Build() : null, ephemeral: ephemeral);
}
else if (context is ICommandContext commandContext)
{
if (embeded)
await commandContext.Channel.SendMessageAsync(embed: embedBuilder.Build(), components: supportinvite ? SupportButton.Build() : null);
else
await commandContext.Channel.SendMessageAsync(description, components: supportinvite ? SupportButton.Build() : null);
}
else
throw new Exception("Invalid context type");
}
}
54 changes: 54 additions & 0 deletions src/Houston.Bot/Common/Permissions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using Discord;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Houston.Bot.Common;

public class Permissions
{
public static string[] ParseGuild(GuildPermissions guildPerms)
{
var perms = new List<string>();

// Add in alphabetical order
if (guildPerms.Administrator) { perms.Add("Administrator"); }
if (guildPerms.AddReactions) { perms.Add("Add Reactions"); }
if (guildPerms.AttachFiles) { perms.Add("Attach Files"); }
if (guildPerms.BanMembers) { perms.Add("Ban Members"); }
if (guildPerms.ChangeNickname) { perms.Add("Change Nickname"); }
if (guildPerms.Connect) { perms.Add("Connect"); }
if (guildPerms.CreateInstantInvite) { perms.Add("Create Instant Invite"); }
if (guildPerms.DeafenMembers) { perms.Add("Deafen Members"); }
if (guildPerms.EmbedLinks) { perms.Add("Embed Links"); }
if (guildPerms.KickMembers) { perms.Add("Kick Members"); }
if (guildPerms.ManageChannels) { perms.Add("Manage Channels"); }
if (guildPerms.ManageEmojisAndStickers) { perms.Add("Manage Emojis and Stickers"); }
if (guildPerms.ManageGuild) { perms.Add("Manage Guild"); }
if (guildPerms.ManageMessages) { perms.Add("Manage Messages"); }
if (guildPerms.ManageNicknames) { perms.Add("Manage Nicknames"); }
if (guildPerms.ManageRoles) { perms.Add("Manage Roles"); }
if (guildPerms.ManageThreads) { perms.Add("Manage Threads"); }
if (guildPerms.ManageWebhooks) { perms.Add("Manage Webhooks"); }
if (guildPerms.MentionEveryone) { perms.Add("Mention Everyone"); }
if (guildPerms.MentionEveryone) { perms.Add("Mention Everyone"); }
if (guildPerms.MoveMembers) { perms.Add("Move Members"); }
if (guildPerms.MuteMembers) { perms.Add("Mute Members"); }
if (guildPerms.PrioritySpeaker) { perms.Add("Priority Speaker"); }
if (guildPerms.ReadMessageHistory) { perms.Add("Read Message History"); }
if (guildPerms.SendMessages) { perms.Add("Send Messages"); }
if (guildPerms.SendTTSMessages) { perms.Add("Send TTS Messages"); }
if (guildPerms.Speak) { perms.Add("Speak"); }
if (guildPerms.Stream) { perms.Add("Stream"); }
if (guildPerms.UseApplicationCommands) { perms.Add("Use Application Commands"); }
if (guildPerms.UseExternalEmojis) { perms.Add("Use External Emojis"); }
if (guildPerms.UseExternalStickers) { perms.Add("Use External Stickers"); }
if (guildPerms.ViewAuditLog) { perms.Add("View Audit Log"); }
if (guildPerms.ViewChannel) { perms.Add("View Channel"); }
if (guildPerms.ViewGuildInsights) { perms.Add("View Guild Insights"); }

return perms.ToArray();
}
}
26 changes: 26 additions & 0 deletions src/Houston.Bot/Modules/Text/AdminModule.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using Discord;
using Discord.Commands;
using Houston.Bot.Preconditions;
using Houston.Bot.Common;

namespace Houston.Bot.Modules.Text;

public class AdminModule : ModuleBase<ShardedCommandContext>
{
[RequireBotAdmin]
[Command("debug")]
[Summary("Debug")]
public async Task DebugAsync()
{
var message = await ReplyAsync("Debugging...");

var version = DiscordConfig.Version;
var guild = Context.Guild;
var shard = Context.Client.GetShardFor(Context.Guild).ShardId;

// TODO: Send to a hastebin
var guildPerms = Permissions.ParseGuild(Context.Guild.CurrentUser.GuildPermissions);

await message.ModifyAsync(x => x.Content = $"API Version: {version}\nShard: {shard}\nGuild ID: {guild.Id}\nCached Guild Count: {Context.Client.Guilds.Count}\nPermissions:\n{string.Join("\n", guildPerms.Select(x => $"- {x}"))}");
}
}
34 changes: 34 additions & 0 deletions src/Houston.Bot/Preconditions/BotAdmin.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using Discord;
using Discord.Commands;
using Discord.WebSocket;
using Houston.Bot.Common;


namespace Houston.Bot.Preconditions
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class RequireBotAdminAttribute : PreconditionAttribute
{
public override Task<PreconditionResult> CheckPermissionsAsync(ICommandContext context, CommandInfo commandInfo, IServiceProvider services)
{
if (context.Guild == null)
{
return Task.FromResult(PreconditionResult.FromError("This command can only be executed from within server channels."));
}

var user = context.User as SocketGuildUser;

if (user == null)
{
return Task.FromResult(PreconditionResult.FromError("This command can only be executed in a server."));
}

if (!Config.Admins.Contains(user.Id.ToString()))
{
return Task.FromResult(PreconditionResult.FromError($"You must have permission to run this command"));
}

return Task.FromResult(PreconditionResult.FromSuccess());
}
}
}
45 changes: 45 additions & 0 deletions src/Houston.Bot/Preconditions/Permissions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using Discord;
using Discord.Interactions;
using Discord.WebSocket;
using Houston.Bot.Common;

namespace Houston.Bot.Preconditions
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
class RequirePermissionsAttribute : Discord.Interactions.PreconditionAttribute
{
private readonly GuildPermission[] _permissions;

public RequirePermissionsAttribute(params GuildPermission[] permissions)
{
_permissions = permissions;
}

public async override Task<PreconditionResult> CheckRequirementsAsync(IInteractionContext context, Discord.Interactions.ICommandInfo commandInfo, IServiceProvider services)
{
if (context.Guild == null)
{
return PreconditionResult.FromError("This command can only be executed from within server channels.");
}

var user = context.User as SocketGuildUser;

if (user == null)
{
return PreconditionResult.FromError("This command can only be executed in a server.");
}

var missingPermissions = _permissions
.Where(permission => !user.GuildPermissions.Has(permission))
.ToList();

if (missingPermissions.Any() && !Config.Admins.Contains(user.Id.ToString()))
{
var missingPermissionNames = string.Join(", ", missingPermissions.Select(permission => permission.ToString()));
return PreconditionResult.FromError($"You must have the following permissions to run this command: {missingPermissionNames}");
}

return PreconditionResult.FromSuccess();
}
}
}
2 changes: 2 additions & 0 deletions src/Houston.Bot/Program.cs
Original file line number Diff line number Diff line change
@@ -80,7 +80,9 @@ private static void ConfigureServices(HostBuilderContext context, IServiceCollec
services.AddDbContext<DatabaseContext>();

services.AddSingleton<InteractionService>();
services.AddSingleton<CommandService>();
services.AddHostedService<InteractionHandlingService>();
services.AddHostedService<CommandHandlingService>();

services.AddQuartz(q => q.UseJobFactory<JobFactory>());
services.AddSingleton<JobSchedulerService>();
Loading

0 comments on commit 8531e23

Please sign in to comment.