diff --git a/Mewdeko.GlobalBanAPI/Common/ApiKeyAuthorize.cs b/Mewdeko.GlobalBanAPI/Common/ApiKeyAuthorize.cs index 97080f3f0..577faa71a 100644 --- a/Mewdeko.GlobalBanAPI/Common/ApiKeyAuthorize.cs +++ b/Mewdeko.GlobalBanAPI/Common/ApiKeyAuthorize.cs @@ -1,6 +1,4 @@ namespace Mewdeko.GlobalBanAPI.Common; [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] -public class ApiKeyAuthorizeAttribute : Attribute -{ -} \ No newline at end of file +public class ApiKeyAuthorizeAttribute : Attribute; \ No newline at end of file diff --git a/src/Mewdeko.Coordinator/CoordStartup.cs b/src/Mewdeko.Coordinator/CoordStartup.cs index 49c883d55..fab676b4b 100644 --- a/src/Mewdeko.Coordinator/CoordStartup.cs +++ b/src/Mewdeko.Coordinator/CoordStartup.cs @@ -35,10 +35,8 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { endpoints.MapGrpcService(); - endpoints.MapGet("/", - async context => await context.Response.WriteAsync( - "Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909") - .ConfigureAwait(false)); + endpoints.MapGet("/", context => context.Response.WriteAsync( + "Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909")); }); } } \ No newline at end of file diff --git a/src/Mewdeko.Database/DbService.cs b/src/Mewdeko.Database/DbService.cs index 0560db171..685bceedf 100644 --- a/src/Mewdeko.Database/DbService.cs +++ b/src/Mewdeko.Database/DbService.cs @@ -45,7 +45,8 @@ public DbService(int shardCount, string token, bool usePostgres, string psqlConn else { if (Environment.OSVersion.Platform == PlatformID.Unix) - builder.DataSource = builder.DataSource = folderpath + $"/.local/share/Mewdeko/{clientId}/data/Mewdeko.db"; + builder.DataSource = builder.DataSource = + folderpath + $"/.local/share/Mewdeko/{clientId}/data/Mewdeko.db"; else builder.DataSource = builder.DataSource = folderpath + $"/Mewdeko/{clientId}/data/Mewdeko.db"; } @@ -64,10 +65,11 @@ public async void Setup() await context.SaveChangesAsync().ConfigureAwait(false); var env = Assembly.GetExecutingAssembly(); - var pmhs = env.GetTypes().Where(t => t.GetInterfaces().Any(i => i == typeof(IPostMigrationHandler))).ToList(); + var pmhs = env.GetTypes().Where(t => t.GetInterfaces().Any(i => i == typeof(IPostMigrationHandler))) + .ToList(); foreach (var id in toApply) { - var pmhToRuns = pmhs?.Where(pmh => pmh.GetCustomAttribute()?.Id == id).ToList(); + var pmhToRuns = pmhs.Where(pmh => pmh.GetCustomAttribute()?.Id == id).ToList(); foreach (var pmh in pmhToRuns) { pmh.GetMethod("PostMigrationHandler")?.Invoke(null, new object[] diff --git a/src/Mewdeko.Database/Extensions/AfkExtensions.cs b/src/Mewdeko.Database/Extensions/AfkExtensions.cs index 679f6645c..47cc54b32 100644 --- a/src/Mewdeko.Database/Extensions/AfkExtensions.cs +++ b/src/Mewdeko.Database/Extensions/AfkExtensions.cs @@ -6,11 +6,11 @@ namespace Mewdeko.Database.Extensions; public static class AfkExtensions { - public static async Task ForGuild(this DbSet set, ulong guildId) => - await set + public static Task ForGuild(this DbSet set, ulong guildId) => + set .AsQueryable() .AsNoTracking().Where(x => x.GuildId == guildId).ToArrayAsyncEF(); - public static async Task GetAll(this DbSet set) => - await set.AsQueryable().AsNoTracking().ToArrayAsyncEF(); + public static Task GetAll(this DbSet set) => + set.AsQueryable().AsNoTracking().ToArrayAsyncEF(); } \ No newline at end of file diff --git a/src/Mewdeko.Database/Extensions/ChatTriggersExtensions.cs b/src/Mewdeko.Database/Extensions/ChatTriggersExtensions.cs index d854e0259..5ffec26ac 100644 --- a/src/Mewdeko.Database/Extensions/ChatTriggersExtensions.cs +++ b/src/Mewdeko.Database/Extensions/ChatTriggersExtensions.cs @@ -39,6 +39,7 @@ await crs .Where(x => x.GuildId == id) .ToArrayAsyncEF(); - public static async Task GetByGuildIdAndInput(this DbSet crs, ulong? guildId, string input) => - await AsyncExtensions.FirstOrDefaultAsync(crs, x => x.GuildId == guildId && x.Trigger.ToUpper() == input).ConfigureAwait(false); + public static Task GetByGuildIdAndInput(this DbSet crs, ulong? guildId, string input) => + AsyncExtensions.FirstOrDefaultAsync(crs, + x => x.GuildId == guildId && x.Trigger.Equals(input, StringComparison.CurrentCultureIgnoreCase)); } \ No newline at end of file diff --git a/src/Mewdeko.Database/Extensions/ClubExtensions.cs b/src/Mewdeko.Database/Extensions/ClubExtensions.cs index 818e6c39c..4e3be0b36 100644 --- a/src/Mewdeko.Database/Extensions/ClubExtensions.cs +++ b/src/Mewdeko.Database/Extensions/ClubExtensions.cs @@ -6,7 +6,7 @@ namespace Mewdeko.Database.Extensions; public static class ClubExtensions { - private static IQueryable Include(this DbSet clubs) + private static IQueryable Include(this IQueryable clubs) => clubs.Include(x => x.Owner) .Include(x => x.Applicants) .ThenInclude(x => x.User) @@ -15,15 +15,15 @@ private static IQueryable Include(this DbSet clubs) .Include(x => x.Users) .AsQueryable(); - public static async Task GetByOwner(this DbSet clubs, ulong userId) - => await Include(clubs).FirstOrDefaultAsync(c => c.Owner.UserId == userId).ConfigureAwait(false); + public static Task GetByOwner(this DbSet clubs, ulong userId) + => Include(clubs).FirstOrDefaultAsync(c => c.Owner.UserId == userId); - public static async Task GetByOwnerOrAdmin(this DbSet clubs, ulong userId) - => await Include(clubs).FirstOrDefaultAsync(c => c.Owner.UserId == userId - || c.Users.Any(u => u.UserId == userId && u.IsClubAdmin == 1)).ConfigureAwait(false); + public static Task GetByOwnerOrAdmin(this DbSet clubs, ulong userId) + => Include(clubs).FirstOrDefaultAsync(c => c.Owner.UserId == userId + || c.Users.Any(u => u.UserId == userId && u.IsClubAdmin == 1)); - public static async Task GetByMember(this DbSet clubs, ulong userId) - => await Include(clubs).FirstOrDefaultAsync(c => c.Users.Any(u => u.UserId == userId)).ConfigureAwait(false); + public static Task GetByMember(this DbSet clubs, ulong userId) + => Include(clubs).FirstOrDefaultAsync(c => c.Users.Any(u => u.UserId == userId)); public static ClubInfo GetByName(this DbSet clubs, string name, int discrim) => Include(clubs).FirstOrDefault(c => c.Name.ToUpper() == name.ToUpper() && c.Discrim == discrim); @@ -35,8 +35,8 @@ public static async Task GetNextDiscrim(this DbSet clubs, string .DefaultIfEmpty() .MaxAsync().ConfigureAwait(false) + 1; - public static async Task> GetClubLeaderboardPage(this DbSet clubs, int page) => - await clubs + public static Task> GetClubLeaderboardPage(this DbSet clubs, int page) => + clubs .AsNoTracking() .OrderByDescending(x => x.Xp) .Skip(page * 9) diff --git a/src/Mewdeko.Database/Extensions/DbExtensions.cs b/src/Mewdeko.Database/Extensions/DbExtensions.cs index 8de2fa6e8..5419c5b45 100644 --- a/src/Mewdeko.Database/Extensions/DbExtensions.cs +++ b/src/Mewdeko.Database/Extensions/DbExtensions.cs @@ -6,8 +6,8 @@ namespace Mewdeko.Database.Extensions; public static class DbExtensions { - public static async Task GetById(this DbSet set, int id) where T : DbEntity - => await set.FirstOrDefaultAsync(x => x.Id == id); + public static Task GetById(this DbSet set, int id) where T : DbEntity + => set.FirstOrDefaultAsync(x => x.Id == id); public static IEnumerable GetActiveConfigs(this DbSet set, IEnumerable guildIds) { @@ -23,7 +23,8 @@ public static IEnumerable GetActiveConfigs(this DbSet return $"@p{index}"; }); - var sqlQuery = $"SELECT * FROM \"GuildConfigs\" WHERE \"GuildId\" = ANY (ARRAY[{string.Join(",", ids)}]::bigint[])"; + var sqlQuery = + $"SELECT * FROM \"GuildConfigs\" WHERE \"GuildId\" = ANY (ARRAY[{string.Join(",", ids)}]::bigint[])"; return set.FromSqlRaw(sqlQuery, parameters.ToArray()); } diff --git a/src/Mewdeko.Database/Extensions/DiscordUserExtensions.cs b/src/Mewdeko.Database/Extensions/DiscordUserExtensions.cs index cd3e4638e..4be0362b3 100644 --- a/src/Mewdeko.Database/Extensions/DiscordUserExtensions.cs +++ b/src/Mewdeko.Database/Extensions/DiscordUserExtensions.cs @@ -38,14 +38,17 @@ public static async Task GetOrCreateUser( string avatarId) { await ctx.EnsureUserCreated(userId, username, discrim, avatarId); - return await ctx.DiscordUser.Include(x => x.Club).FirstOrDefaultAsyncEF(u => u.UserId == userId).ConfigureAwait(false); + return await ctx.DiscordUser.Include(x => x.Club).FirstOrDefaultAsyncEF(u => u.UserId == userId) + .ConfigureAwait(false); } - public static async Task GetOrCreateUser(this MewdekoContext ctx, IUser original) => - await ctx.GetOrCreateUser(original.Id, original.Username, original.Discriminator, original.AvatarId).ConfigureAwait(false); + public static Task GetOrCreateUser(this MewdekoContext ctx, IUser original) => + ctx.GetOrCreateUser(original.Id, original.Username, original.Discriminator, original.AvatarId); public static async Task GetUserGlobalRank(this DbSet users, ulong id) => - await users.AsQueryable().CountAsyncEF(x => x.TotalXp > users.AsQueryable().Where(y => y.UserId == id).Select(y => y.TotalXp).FirstOrDefault()).ConfigureAwait(false) + await users.AsQueryable().CountAsyncEF(x => + x.TotalXp > users.AsQueryable().Where(y => y.UserId == id).Select(y => y.TotalXp).FirstOrDefault()) + .ConfigureAwait(false) + 1; public static DiscordUser[] GetUsersXpLeaderboardFor(this DbSet users, int page) => diff --git a/src/Mewdeko.Database/Extensions/MiniWarningsExtensions.cs b/src/Mewdeko.Database/Extensions/MiniWarningsExtensions.cs index 6eb1c372d..5b4f3466e 100644 --- a/src/Mewdeko.Database/Extensions/MiniWarningsExtensions.cs +++ b/src/Mewdeko.Database/Extensions/MiniWarningsExtensions.cs @@ -32,14 +32,15 @@ public static async Task Forgive(this DbSet set, ulong guildId, return true; } - public static async Task ForgiveAll(this DbSet set, ulong guildId, ulong userId, string mod) => - await set.AsQueryable().Where(x => x.GuildId == guildId && x.UserId == userId) + public static Task ForgiveAll(this DbSet set, ulong guildId, ulong userId, string mod) => + set.AsQueryable().Where(x => x.GuildId == guildId && x.UserId == userId) .ForEachAsync(x => { if (x.Forgiven == 1) return; x.Forgiven = 1; x.ForgivenBy = mod; - }).ConfigureAwait(false); + }); - public static Warning2[] GetForGuild(this DbSet set, ulong id) => set.AsQueryable().Where(x => x.GuildId == id).ToArray(); + public static Warning2[] GetForGuild(this DbSet set, ulong id) => + set.AsQueryable().Where(x => x.GuildId == id).ToArray(); } \ No newline at end of file diff --git a/src/Mewdeko.Database/Extensions/RoleGreetExtensions.cs b/src/Mewdeko.Database/Extensions/RoleGreetExtensions.cs index 837e97d65..64aa0ca05 100644 --- a/src/Mewdeko.Database/Extensions/RoleGreetExtensions.cs +++ b/src/Mewdeko.Database/Extensions/RoleGreetExtensions.cs @@ -6,6 +6,6 @@ namespace Mewdeko.Database.Extensions; public static class RoleGreetExtensions { - public static async Task ForRoleId(this DbSet set, ulong roleId) - => await set.AsQueryable().Where(x => x.RoleId == roleId).ToArrayAsyncEF(); + public static Task ForRoleId(this DbSet set, ulong roleId) + => set.AsQueryable().Where(x => x.RoleId == roleId).ToArrayAsyncEF(); } \ No newline at end of file diff --git a/src/Mewdeko.Database/Extensions/StarboardExtensions.cs b/src/Mewdeko.Database/Extensions/StarboardExtensions.cs index 816858b0b..7c5c9998a 100644 --- a/src/Mewdeko.Database/Extensions/StarboardExtensions.cs +++ b/src/Mewdeko.Database/Extensions/StarboardExtensions.cs @@ -6,8 +6,8 @@ namespace Mewdeko.Database.Extensions; public static class StarboardExtensions { - public static async Task ForMsgId(this DbSet set, ulong msgid) - => await set.AsQueryable().FirstOrDefaultAsyncEF(x => x.MessageId == msgid); + public static Task ForMsgId(this DbSet set, ulong msgid) + => set.AsQueryable().FirstOrDefaultAsyncEF(x => x.MessageId == msgid); public static async Task> All(this DbSet set) => await set.AsQueryable().ToArrayAsyncEF(); diff --git a/src/Mewdeko.Database/Extensions/SuggestionsExtensions.cs b/src/Mewdeko.Database/Extensions/SuggestionsExtensions.cs index c0f4686b4..4f014c9c5 100644 --- a/src/Mewdeko.Database/Extensions/SuggestionsExtensions.cs +++ b/src/Mewdeko.Database/Extensions/SuggestionsExtensions.cs @@ -6,9 +6,9 @@ namespace Mewdeko.Database.Extensions; public static class SuggestionsExtensions { - public static async Task ForId(this DbSet set, ulong guildId, ulong sugid) - => await set.AsQueryable().Where(x => x.GuildId == guildId && x.SuggestionId == sugid).ToArrayAsyncEF(); + public static Task ForId(this DbSet set, ulong guildId, ulong sugid) + => set.AsQueryable().Where(x => x.GuildId == guildId && x.SuggestionId == sugid).ToArrayAsyncEF(); - public static async Task ForUser(this DbSet set, ulong guildId, ulong userId) - => await set.AsQueryable().Where(x => x.GuildId == guildId && x.UserId == userId).ToArrayAsyncEF(); + public static Task ForUser(this DbSet set, ulong guildId, ulong userId) + => set.AsQueryable().Where(x => x.GuildId == guildId && x.UserId == userId).ToArrayAsyncEF(); } \ No newline at end of file diff --git a/src/Mewdeko.Database/Extensions/WaifuExtensions.cs b/src/Mewdeko.Database/Extensions/WaifuExtensions.cs index 9ed5e2394..fe6f4756d 100644 --- a/src/Mewdeko.Database/Extensions/WaifuExtensions.cs +++ b/src/Mewdeko.Database/Extensions/WaifuExtensions.cs @@ -19,18 +19,19 @@ public class WaifuInfoStats public static class WaifuExtensions { - public static async Task ByWaifuUserId(this DbSet waifus, ulong userId, Func, IQueryable> includes = null) + public static Task ByWaifuUserId(this DbSet waifus, ulong userId, + Func, IQueryable> includes = null) { if (includes is null) { - return await waifus.Include(wi => wi.Waifu) + return waifus.Include(wi => wi.Waifu) .Include(wi => wi.Affinity) .Include(wi => wi.Claimer) .Include(wi => wi.Items) .FirstOrDefaultAsyncEF(wi => wi.Waifu.UserId == userId); } - return await includes(waifus) + return includes(waifus) .AsQueryable() .FirstOrDefaultAsyncEF(wi => wi.Waifu.UserId == userId); } @@ -67,8 +68,8 @@ await waifus .Where(x => x.ClaimerId != null) .SumAsyncLinqToDB(x => x.Price); - public static async Task GetWaifuUserId(this DbSet waifus, ulong ownerId, string name) => - await waifus + public static Task GetWaifuUserId(this DbSet waifus, ulong ownerId, string name) => + waifus .AsQueryable() .AsNoTracking() .Where(x => x.Claimer.UserId == ownerId diff --git a/src/Mewdeko.Database/Extensions/WarningExtensions.cs b/src/Mewdeko.Database/Extensions/WarningExtensions.cs index 70c00b77a..56e0ab4fc 100644 --- a/src/Mewdeko.Database/Extensions/WarningExtensions.cs +++ b/src/Mewdeko.Database/Extensions/WarningExtensions.cs @@ -32,14 +32,14 @@ public static async Task Forgive(this DbSet set, ulong guildId, u return true; } - public static async Task ForgiveAll(this DbSet set, ulong guildId, ulong userId, string mod) => - await set.AsQueryable().Where(x => x.GuildId == guildId && x.UserId == userId) + public static Task ForgiveAll(this DbSet set, ulong guildId, ulong userId, string mod) => + set.AsQueryable().Where(x => x.GuildId == guildId && x.UserId == userId) .ForEachAsync(x => { if (x.Forgiven == 1) return; x.Forgiven = 1; x.ForgivenBy = mod; - }).ConfigureAwait(false); + }); public static async Task> GetForGuild(this DbSet set, ulong id) => await set.AsQueryable().Where(x => x.GuildId == id).ToArrayAsyncEF(); diff --git a/src/Mewdeko.Database/Extensions/XpExtensions.cs b/src/Mewdeko.Database/Extensions/XpExtensions.cs index cc0d58086..058c5090b 100644 --- a/src/Mewdeko.Database/Extensions/XpExtensions.cs +++ b/src/Mewdeko.Database/Extensions/XpExtensions.cs @@ -22,12 +22,12 @@ public static async Task GetOrCreateUser(this DbSet se return usr; } - public static async Task> GetUsersFor(this DbSet set, ulong guildId, int page) => - await set.AsQueryable().AsNoTracking().Where(x => x.GuildId == guildId).OrderByDescending(x => x.Xp + x.AwardedXp) + public static Task> GetUsersFor(this DbSet set, ulong guildId, int page) => + set.AsQueryable().AsNoTracking().Where(x => x.GuildId == guildId).OrderByDescending(x => x.Xp + x.AwardedXp) .Skip(page * 9).Take(9).ToListAsyncEF(); - public static async Task> GetTopUserXps(this DbSet set, ulong guildId) => - await set.AsQueryable().AsNoTracking().Where(x => x.GuildId == guildId).OrderByDescending(x => x.Xp + x.AwardedXp) + public static Task> GetTopUserXps(this DbSet set, ulong guildId) => + set.AsQueryable().AsNoTracking().Where(x => x.GuildId == guildId).OrderByDescending(x => x.Xp + x.AwardedXp) .ToListAsyncEF(); public static int GetUserGuildRanking(this DbSet set, ulong userId, ulong guildId) => diff --git a/src/Mewdeko.Database/Mewdeko.Database.csproj b/src/Mewdeko.Database/Mewdeko.Database.csproj index 21db58579..29ac0803e 100644 --- a/src/Mewdeko.Database/Mewdeko.Database.csproj +++ b/src/Mewdeko.Database/Mewdeko.Database.csproj @@ -4,7 +4,7 @@ enable disable True - 11 + 12 Mewdeko.Database net8.0 diff --git a/src/Mewdeko.Database/Migrations/PostgreSql/AddXpBanner.Designer.cs b/src/Mewdeko.Database/Migrations/PostgreSql/AddXpBanner.Designer.cs new file mode 100644 index 000000000..328ddbb3b --- /dev/null +++ b/src/Mewdeko.Database/Migrations/PostgreSql/AddXpBanner.Designer.cs @@ -0,0 +1,18 @@ +// + +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Mewdeko.Database.Migrations.PostgreSql +{ + [DbContext(typeof(MewdekoPostgresContext))] + [Migration("AddXpImage")] + partial class AddXpImage + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { + // required for reasons + } + } +} \ No newline at end of file diff --git a/src/Mewdeko.Database/Migrations/PostgreSql/AddXpBanner.cs b/src/Mewdeko.Database/Migrations/PostgreSql/AddXpBanner.cs new file mode 100644 index 000000000..d45940e43 --- /dev/null +++ b/src/Mewdeko.Database/Migrations/PostgreSql/AddXpBanner.cs @@ -0,0 +1,22 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Mewdeko.Database.Migrations.PostgreSql; + +public partial class AddXpImage : Migration +{ + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "XpImgUrl", + table: "GuildConfigs", + type: "text", + nullable: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "XpImgUrl", + table: "GuildConfigs"); + } +} \ No newline at end of file diff --git a/src/Mewdeko.Database/Migrations/SQLite/AddXpBanner.Designer.cs b/src/Mewdeko.Database/Migrations/SQLite/AddXpBanner.Designer.cs new file mode 100644 index 000000000..baec4e365 --- /dev/null +++ b/src/Mewdeko.Database/Migrations/SQLite/AddXpBanner.Designer.cs @@ -0,0 +1,18 @@ +// + +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Mewdeko.Database.Migrations.SQLite +{ + [DbContext(typeof(MewdekoSqLiteContext))] + [Migration("AddXpBanner")] + partial class AddXpBanner + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { + // required for reasons + } + } +} \ No newline at end of file diff --git a/src/Mewdeko.Database/Migrations/SQLite/AddXpBanner.cs b/src/Mewdeko.Database/Migrations/SQLite/AddXpBanner.cs new file mode 100644 index 000000000..5dca1d3d7 --- /dev/null +++ b/src/Mewdeko.Database/Migrations/SQLite/AddXpBanner.cs @@ -0,0 +1,11 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Mewdeko.Database.Migrations.SQLite; + +public partial class AddXpBanner : Migration +{ + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn("XpImgUrl", "GuildConfigs", "text", nullable: true); + } +} \ No newline at end of file diff --git a/src/Mewdeko.Database/Models/GuildConfig.cs b/src/Mewdeko.Database/Models/GuildConfig.cs index 0e9c665e6..afba0e816 100644 --- a/src/Mewdeko.Database/Models/GuildConfig.cs +++ b/src/Mewdeko.Database/Models/GuildConfig.cs @@ -18,6 +18,8 @@ public class GuildConfig : DbEntity public string? WarnMessage { get; set; } = "-"; public HashSet DelMsgOnCmdChannels { get; set; } = new(); public string? AutoAssignRoleId { get; set; } = "0"; + + public string XpImgUrl { get; set; } public long StatsOptOut { get; set; } = 0; public string CurrencyName { get; set; } = "Coins"; diff --git a/src/Mewdeko.Votes/Controllers/WebhookController.cs b/src/Mewdeko.Votes/Controllers/WebhookController.cs index 55d00f654..f2d2e244d 100644 --- a/src/Mewdeko.Votes/Controllers/WebhookController.cs +++ b/src/Mewdeko.Votes/Controllers/WebhookController.cs @@ -25,9 +25,9 @@ public Task TopggWebhook([FromBody] VoteModel data) data.User, data.Bot, "top.gg"); - _ = Task.Run(async () => + _ = Task.Run(() => { - await Events.InvokeTopGg(data, Request.Headers.Authorization); + return Events.InvokeTopGg(data, Request.Headers.Authorization); }); return Task.FromResult(Ok()); } diff --git a/src/Mewdeko.Votes/WebhookEvents.cs b/src/Mewdeko.Votes/WebhookEvents.cs index 6103655f8..7cf1ef62f 100644 --- a/src/Mewdeko.Votes/WebhookEvents.cs +++ b/src/Mewdeko.Votes/WebhookEvents.cs @@ -15,12 +15,12 @@ public WebhookEvents(IPubSub pubSub) typedKey = new TypedKey("uservoted"); } - public async Task InvokeTopGg(VoteModel data, string key) + public Task InvokeTopGg(VoteModel data, string key) { var compoundModel = new CompoundVoteModal { VoteModel = data, Password = key }; - await pubSub.Pub(typedKey, compoundModel); + return pubSub.Pub(typedKey, compoundModel); } } \ No newline at end of file diff --git a/src/Mewdeko/Common/MewdekoModuleBase.cs b/src/Mewdeko/Common/MewdekoModuleBase.cs index 7897aaeac..85a7fc207 100644 --- a/src/Mewdeko/Common/MewdekoModuleBase.cs +++ b/src/Mewdeko/Common/MewdekoModuleBase.cs @@ -43,9 +43,8 @@ public Task ReplyConfirmLocalizedAsync(string? textKey, params obj return ctx.Channel.SendConfirmAsync($"{Format.Bold(ctx.User.ToString())} {text}"); } - public async Task PromptUserConfirmAsync(string message, ulong userid) - => await PromptUserConfirmAsync(new EmbedBuilder().WithOkColor().WithDescription(message), userid) - .ConfigureAwait(false); + public Task PromptUserConfirmAsync(string message, ulong userid) + => PromptUserConfirmAsync(new EmbedBuilder().WithOkColor().WithDescription(message), userid); public async Task PromptUserConfirmAsync(EmbedBuilder embed, ulong userid) { @@ -62,7 +61,7 @@ public async Task PromptUserConfirmAsync(EmbedBuilder embed, ulong userid) } finally { - _ = Task.Run(async () => await msg.DeleteAsync().ConfigureAwait(false)); + _ = Task.Run(() => msg.DeleteAsync()); } } @@ -167,9 +166,9 @@ await Task.Run(async () => dsc.MessageReceived -= Interaction; } - async Task Interaction(SocketMessage arg) + Task Interaction(SocketMessage arg) { - await Task.Run(async () => + return Task.Run(async () => { if (arg.Author.Id != userId || arg.Channel.Id != channelId) return; userInputTask.TrySetResult(arg.Content); @@ -181,7 +180,7 @@ await Task.Run(async () => { //Exclude } - }).ConfigureAwait(false); + }); } } @@ -205,9 +204,9 @@ await Task.Run(async () => dsc.MessageReceived -= Interaction; } - async Task Interaction(SocketMessage arg) + Task Interaction(SocketMessage arg) { - await Task.Run(async () => + return Task.Run(async () => { if (arg.Author.Id != userId || arg.Channel.Id != channelId) return; userInputTask.TrySetResult(arg); @@ -219,7 +218,7 @@ await Task.Run(async () => { //Exclude } - }).ConfigureAwait(false); + }); } } } diff --git a/src/Mewdeko/Common/MewdekoSlashModuleBase.cs b/src/Mewdeko/Common/MewdekoSlashModuleBase.cs index e2526a819..0e7a4220a 100644 --- a/src/Mewdeko/Common/MewdekoSlashModuleBase.cs +++ b/src/Mewdeko/Common/MewdekoSlashModuleBase.cs @@ -20,29 +20,28 @@ public abstract class MewdekoSlashCommandModule : InteractionModuleBase protected string? GetText(string? key, params object?[] args) => Strings.GetText(key, CultureInfo, args); - public async Task ErrorLocalizedAsync(string? textKey, params object?[] args) + public Task ErrorLocalizedAsync(string? textKey, params object?[] args) { var text = GetText(textKey, args); - await ctx.Interaction.SendErrorAsync(text).ConfigureAwait(false); + return ctx.Interaction.SendErrorAsync(text); } - public async Task ReplyErrorLocalizedAsync(string? textKey, params object?[] args) + public Task ReplyErrorLocalizedAsync(string? textKey, params object?[] args) { var text = GetText(textKey, args); - await ctx.Interaction.SendErrorAsync($"{Format.Bold(ctx.User.ToString())} {text}").ConfigureAwait(false); + return ctx.Interaction.SendErrorAsync($"{Format.Bold(ctx.User.ToString())} {text}"); } - public async Task EphemeralReplyErrorLocalizedAsync(string? textKey, params object?[] args) + public Task EphemeralReplyErrorLocalizedAsync(string? textKey, params object?[] args) { var text = GetText(textKey, args); - await ctx.Interaction.SendEphemeralErrorAsync($"{Format.Bold(ctx.User.ToString())} {text}") - .ConfigureAwait(false); + return ctx.Interaction.SendEphemeralErrorAsync($"{Format.Bold(ctx.User.ToString())} {text}"); } - public async Task ConfirmLocalizedAsync(string? textKey, params object?[] args) + public Task ConfirmLocalizedAsync(string? textKey, params object?[] args) { var text = GetText(textKey, args); - await ctx.Interaction.SendConfirmAsync(text).ConfigureAwait(false); + return ctx.Interaction.SendConfirmAsync(text); } public Task ReplyConfirmLocalizedAsync(string? textKey, params object?[] args) @@ -57,10 +56,9 @@ public Task EphemeralReplyConfirmLocalizedAsync(string? textKey, params object?[ return ctx.Interaction.SendEphemeralConfirmAsync($"{Format.Bold(ctx.User.ToString())} {text}"); } - public async Task + public Task PromptUserConfirmAsync(string text, ulong uid, bool ephemeral = false, bool delete = true) => - await PromptUserConfirmAsync(new EmbedBuilder().WithOkColor().WithDescription(text), uid, ephemeral, delete) - .ConfigureAwait(false); + PromptUserConfirmAsync(new EmbedBuilder().WithOkColor().WithDescription(text), uid, ephemeral, delete); public async Task PromptUserConfirmAsync(EmbedBuilder embed, ulong userid, bool ephemeral = false, bool delete = true) @@ -81,7 +79,7 @@ public async Task PromptUserConfirmAsync(EmbedBuilder embed, ulong userid, finally { if (delete) - _ = Task.Run(async () => await msg.DeleteAsync().ConfigureAwait(false)); + _ = Task.Run(() => msg.DeleteAsync()); } } diff --git a/src/Mewdeko/Common/PubSub/EventPubSub.cs b/src/Mewdeko/Common/PubSub/EventPubSub.cs index 085f4ac46..2d2b266b7 100644 --- a/src/Mewdeko/Common/PubSub/EventPubSub.cs +++ b/src/Mewdeko/Common/PubSub/EventPubSub.cs @@ -24,7 +24,7 @@ public Task Sub(TypedKey key, Func action) return Task.CompletedTask; } - public async Task Pub(TypedKey key, TData data) where TData : notnull + public Task Pub(TypedKey key, TData data) where TData : notnull { if (actions.TryGetValue(key.Key, out var dictionary)) { @@ -44,8 +44,10 @@ public async Task Pub(TypedKey key, TData data) where TData : notn } } - await Task.WhenAll(tasks.Select(vt => vt.AsTask())); + return Task.WhenAll(tasks.Select(vt => vt.AsTask())); } + + return Task.CompletedTask; } public Task Unsub(in TypedKey key, Func action) diff --git a/src/Mewdeko/Extensions/Extensions.cs b/src/Mewdeko/Extensions/Extensions.cs index f82b5df81..e0321f7ff 100644 --- a/src/Mewdeko/Extensions/Extensions.cs +++ b/src/Mewdeko/Extensions/Extensions.cs @@ -9,7 +9,6 @@ using Fergun.Interactive; using Mewdeko.Common.Attributes.TextCommands; using Mewdeko.Common.TypeReaders; -using Mewdeko.Modules.Administration.Services; using Mewdeko.Services.strings; using SkiaSharp; using ModuleInfo = Discord.Commands.ModuleInfo; @@ -50,55 +49,51 @@ public static Task EmbedAsync(this IMessageChannel channel, CrEmbe return channel.SendMessageAsync(plainText, embed: crEmbed.IsEmbedValid ? crEmbed.ToEmbed().Build() : null); } - public static async Task SendConfirmAsync(this IDiscordInteraction interaction, string? message) - => await interaction.RespondAsync(embed: new EmbedBuilder().WithOkColor().WithDescription(message).Build()) - .ConfigureAwait(false); + public static Task SendConfirmAsync(this IDiscordInteraction interaction, string? message) + => interaction.RespondAsync(embed: new EmbedBuilder().WithOkColor().WithDescription(message).Build()); - public static async Task SendEphemeralConfirmAsync(this IDiscordInteraction interaction, string message) - => await interaction - .RespondAsync(embed: new EmbedBuilder().WithOkColor().WithDescription(message).Build(), ephemeral: true) - .ConfigureAwait(false); + public static Task SendEphemeralConfirmAsync(this IDiscordInteraction interaction, string message) + => interaction + .RespondAsync(embed: new EmbedBuilder().WithOkColor().WithDescription(message).Build(), ephemeral: true); - public static async Task SendErrorAsync(this IDiscordInteraction interaction, string? message) - => await interaction.RespondAsync(embed: new EmbedBuilder().WithErrorColor().WithDescription(message).Build(), + public static Task SendErrorAsync(this IDiscordInteraction interaction, string? message) + => interaction.RespondAsync(embed: new EmbedBuilder().WithErrorColor().WithDescription(message).Build(), components: new ComponentBuilder() .WithButton(label: "Support Server", style: ButtonStyle.Link, url: "https://discord.gg/mewdeko") - .Build()).ConfigureAwait(false); + .Build()); - public static async Task SendEphemeralErrorAsync(this IDiscordInteraction interaction, string? message) - => await interaction.RespondAsync(embed: new EmbedBuilder().WithErrorColor().WithDescription(message).Build(), + public static Task SendEphemeralErrorAsync(this IDiscordInteraction interaction, string? message) + => interaction.RespondAsync(embed: new EmbedBuilder().WithErrorColor().WithDescription(message).Build(), ephemeral: true, components: new ComponentBuilder() .WithButton(label: "Support Server", style: ButtonStyle.Link, url: "https://discord.gg/mewdeko") - .Build()).ConfigureAwait(false); + .Build()); - public static async Task SendConfirmFollowupAsync(this IDiscordInteraction interaction, + public static Task SendConfirmFollowupAsync(this IDiscordInteraction interaction, string message) - => await interaction.FollowupAsync(embed: new EmbedBuilder().WithOkColor().WithDescription(message).Build()) - .ConfigureAwait(false); + => interaction.FollowupAsync(embed: new EmbedBuilder().WithOkColor().WithDescription(message).Build()); - public static async Task SendConfirmFollowupAsync(this IDiscordInteraction interaction, + public static Task SendConfirmFollowupAsync(this IDiscordInteraction interaction, string message, ComponentBuilder builder) - => await interaction.FollowupAsync(embed: new EmbedBuilder().WithOkColor().WithDescription(message).Build(), - components: builder.Build()).ConfigureAwait(false); + => interaction.FollowupAsync(embed: new EmbedBuilder().WithOkColor().WithDescription(message).Build(), + components: builder.Build()); - public static async Task SendEphemeralFollowupConfirmAsync(this IDiscordInteraction interaction, + public static Task SendEphemeralFollowupConfirmAsync(this IDiscordInteraction interaction, string message) - => await interaction - .FollowupAsync(embed: new EmbedBuilder().WithOkColor().WithDescription(message).Build(), ephemeral: true) - .ConfigureAwait(false); + => interaction + .FollowupAsync(embed: new EmbedBuilder().WithOkColor().WithDescription(message).Build(), ephemeral: true); - public static async Task SendErrorFollowupAsync(this IDiscordInteraction interaction, string message) - => await interaction.FollowupAsync(embed: new EmbedBuilder().WithErrorColor().WithDescription(message).Build(), + public static Task SendErrorFollowupAsync(this IDiscordInteraction interaction, string message) + => interaction.FollowupAsync(embed: new EmbedBuilder().WithErrorColor().WithDescription(message).Build(), components: new ComponentBuilder() .WithButton(label: "Support Server", style: ButtonStyle.Link, url: "https://discord.gg/mewdeko") - .Build()).ConfigureAwait(false); + .Build()); - public static async Task SendEphemeralFollowupErrorAsync(this IDiscordInteraction interaction, + public static Task SendEphemeralFollowupErrorAsync(this IDiscordInteraction interaction, string message) - => await interaction.FollowupAsync(embed: new EmbedBuilder().WithErrorColor().WithDescription(message).Build(), + => interaction.FollowupAsync(embed: new EmbedBuilder().WithErrorColor().WithDescription(message).Build(), ephemeral: true, components: new ComponentBuilder() .WithButton(label: "Support Server", style: ButtonStyle.Link, url: "https://discord.gg/mewdeko") - .Build()).ConfigureAwait(false); + .Build()); public static bool IsValidAttachment(this IReadOnlyCollection attachments) { @@ -254,14 +249,13 @@ public static void AddFakeHeaders(this HttpHeaders dict) "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.202 Safari/535.1"); } - public static void DeleteAfter(this IUserMessage? msg, int seconds, LogCommandService? logService = null) + public static void DeleteAfter(this IUserMessage? msg, int seconds) { if (msg is null) return; Task.Run(async () => { await Task.Delay(seconds * 1000).ConfigureAwait(false); - logService?.AddDeleteIgnore(msg.Id); try { await msg.DeleteAsync().ConfigureAwait(false); @@ -273,14 +267,13 @@ public static void DeleteAfter(this IUserMessage? msg, int seconds, LogCommandSe }); } - public static void DeleteAfter(this IMessage? msg, int seconds, LogCommandService? logService = null) + public static void DeleteAfter(this IMessage? msg, int seconds) { if (msg is null) return; Task.Run(async () => { await Task.Delay(seconds * 1000).ConfigureAwait(false); - logService?.AddDeleteIgnore(msg.Id); try { await msg.DeleteAsync().ConfigureAwait(false); diff --git a/src/Mewdeko/Modules/Administration/Administration.cs b/src/Mewdeko/Modules/Administration/Administration.cs index cbe953d86..940b8b846 100644 --- a/src/Mewdeko/Modules/Administration/Administration.cs +++ b/src/Mewdeko/Modules/Administration/Administration.cs @@ -12,8 +12,8 @@ namespace Mewdeko.Modules.Administration; -public partial class Administration - (InteractiveService serv, BotConfigService configService) : MewdekoModuleBase +public partial class Administration(InteractiveService serv, BotConfigService configService) + : MewdekoModuleBase { public enum Channel { @@ -675,8 +675,8 @@ public async Task Edit(ITextChannel channel, ulong messageId, [Remainder] string public Task Delete(ulong messageId, StoopidTime? time = null) => Delete((ITextChannel)ctx.Channel, messageId, time); [Cmd, Aliases, RequireContext(ContextType.Guild)] - public async Task Delete(ITextChannel channel, ulong messageId, StoopidTime? time = null) => - await InternalMessageAction(channel, messageId, time).ConfigureAwait(false); + public Task Delete(ITextChannel channel, ulong messageId, StoopidTime? time = null) => + InternalMessageAction(channel, messageId, time); private async Task InternalMessageAction(ITextChannel channel, ulong messageId, StoopidTime? time) { diff --git a/src/Mewdeko/Modules/Administration/LogCommands.cs b/src/Mewdeko/Modules/Administration/LogCommands.cs index ef929ee0a..2b0716097 100644 --- a/src/Mewdeko/Modules/Administration/LogCommands.cs +++ b/src/Mewdeko/Modules/Administration/LogCommands.cs @@ -1,17 +1,17 @@ using Discord.Commands; using Mewdeko.Common.Attributes.TextCommands; using Mewdeko.Modules.Administration.Services; -using static Mewdeko.Modules.Administration.Services.LogCommandService; +using LogType = Mewdeko.Modules.Administration.Services.NewLogCommandService.LogType; namespace Mewdeko.Modules.Administration; public partial class Administration { [Group] - public class LogCommands : MewdekoSubmodule + public class LogCommands : MewdekoSubmodule { [Cmd, Aliases, RequireContext(ContextType.Guild), UserPerm(GuildPermission.Administrator), Priority(1)] - public async Task LogCategory(LogCategoryTypes type, ITextChannel? channel = null) + public async Task LogCategory(NewLogCommandService.LogCategoryTypes type, ITextChannel? channel = null) { await Service.LogSetByType(ctx.Guild.Id, channel?.Id ?? 0, type); if (channel is null) @@ -23,40 +23,40 @@ public async Task LogCategory(LogCategoryTypes type, ITextChannel? channel = nul await ctx.Channel.SendConfirmAsync(GetText("logging_category_enabled", type, channel.Mention)); } - [Cmd, Aliases, RequireContext(ContextType.Guild), UserPerm(GuildPermission.Administrator), Priority(0)] - public async Task LogIgnore() - { - var channel = (ITextChannel)ctx.Channel; - - var removed = await Service.LogIgnore(ctx.Guild.Id, ctx.Channel.Id); - - if (!removed) - await ReplyConfirmLocalizedAsync("log_ignore", Format.Bold($"{channel.Mention}({channel.Id})")).ConfigureAwait(false); - else - await ReplyConfirmLocalizedAsync("log_not_ignore", Format.Bold($"{channel.Mention}({channel.Id})")).ConfigureAwait(false); - } - - [Cmd, Aliases, RequireContext(ContextType.Guild), UserPerm(GuildPermission.Administrator), Priority(1)] - public async Task LogIgnore(ITextChannel channel) - { - var removed = await Service.LogIgnore(ctx.Guild.Id, channel.Id); - - if (!removed) - await ReplyConfirmLocalizedAsync("log_ignore", Format.Bold($"{channel.Mention}({channel.Id})")).ConfigureAwait(false); - else - await ReplyConfirmLocalizedAsync("log_not_ignore", Format.Bold($"{channel.Mention}({channel.Id})")).ConfigureAwait(false); - } - - [Cmd, Aliases, RequireContext(ContextType.Guild), UserPerm(GuildPermission.Administrator), Priority(2)] - public async Task LogIgnore(IVoiceChannel channel) - { - var removed = await Service.LogIgnore(ctx.Guild.Id, channel.Id); - - if (!removed) - await ReplyConfirmLocalizedAsync("log_ignore", Format.Bold($"{channel.Name}({channel.Id})")).ConfigureAwait(false); - else - await ReplyConfirmLocalizedAsync("log_not_ignore", Format.Bold($"{channel.Name}({channel.Id})")).ConfigureAwait(false); - } + // [Cmd, Aliases, RequireContext(ContextType.Guild), UserPerm(GuildPermission.Administrator), Priority(0)] + // public async Task LogIgnore() + // { + // var channel = (ITextChannel)ctx.Channel; + // + // var removed = await Service.LogIgnore(ctx.Guild.Id, ctx.Channel.Id); + // + // if (!removed) + // await ReplyConfirmLocalizedAsync("log_ignore", Format.Bold($"{channel.Mention}({channel.Id})")).ConfigureAwait(false); + // else + // await ReplyConfirmLocalizedAsync("log_not_ignore", Format.Bold($"{channel.Mention}({channel.Id})")).ConfigureAwait(false); + // } + // + // [Cmd, Aliases, RequireContext(ContextType.Guild), UserPerm(GuildPermission.Administrator), Priority(1)] + // public async Task LogIgnore(ITextChannel channel) + // { + // var removed = await Service.LogIgnore(ctx.Guild.Id, channel.Id); + // + // if (!removed) + // await ReplyConfirmLocalizedAsync("log_ignore", Format.Bold($"{channel.Mention}({channel.Id})")).ConfigureAwait(false); + // else + // await ReplyConfirmLocalizedAsync("log_not_ignore", Format.Bold($"{channel.Mention}({channel.Id})")).ConfigureAwait(false); + // } + // + // [Cmd, Aliases, RequireContext(ContextType.Guild), UserPerm(GuildPermission.Administrator), Priority(2)] + // public async Task LogIgnore(IVoiceChannel channel) + // { + // var removed = await Service.LogIgnore(ctx.Guild.Id, channel.Id); + // + // if (!removed) + // await ReplyConfirmLocalizedAsync("log_ignore", Format.Bold($"{channel.Name}({channel.Id})")).ConfigureAwait(false); + // else + // await ReplyConfirmLocalizedAsync("log_not_ignore", Format.Bold($"{channel.Name}({channel.Id})")).ConfigureAwait(false); + // } [Cmd, Aliases, RequireContext(ContextType.Guild), UserPerm(GuildPermission.Administrator)] public async Task LogEvents() @@ -125,19 +125,19 @@ public async Task Log(LogType type, ITextChannel? channel = null) await ConfirmLocalizedAsync("logging_event_disabled", type); } - [Cmd, Aliases, RequireContext(ContextType.Guild), UserPerm(GuildPermission.Administrator)] - public async Task CommandLogChannel(ITextChannel? channel = null) - { - if (channel is null) - { - await ConfirmLocalizedAsync("command_logging_disabled"); - await Service.UpdateCommandLogChannel(ctx.Guild, 0); - } - else - { - await ConfirmLocalizedAsync("command_logging_enabled"); - await Service.UpdateCommandLogChannel(ctx.Guild, channel.Id); - } - } + // [Cmd, Aliases, RequireContext(ContextType.Guild), UserPerm(GuildPermission.Administrator)] + // public async Task CommandLogChannel(ITextChannel? channel = null) + // { + // if (channel is null) + // { + // await ConfirmLocalizedAsync("command_logging_disabled"); + // await Service.UpdateCommandLogChannel(ctx.Guild, 0); + // } + // else + // { + // await ConfirmLocalizedAsync("command_logging_enabled"); + // await Service.UpdateCommandLogChannel(ctx.Guild, channel.Id); + // } + // } } } \ No newline at end of file diff --git a/src/Mewdeko/Modules/Administration/ProtectionCommands.cs b/src/Mewdeko/Modules/Administration/ProtectionCommands.cs index f6df9cad7..10f13344d 100644 --- a/src/Mewdeko/Modules/Administration/ProtectionCommands.cs +++ b/src/Mewdeko/Modules/Administration/ProtectionCommands.cs @@ -77,13 +77,14 @@ public async Task AntiRaid() [Cmd, Aliases, RequireContext(ContextType.Guild), UserPerm(GuildPermission.Administrator), Priority(1)] - public async Task AntiRaid(int userThreshold, int seconds, + public Task AntiRaid(int userThreshold, int seconds, PunishmentAction action, [Remainder] StoopidTime punishTime) => - await InternalAntiRaid(userThreshold, seconds, action, punishTime); + InternalAntiRaid(userThreshold, seconds, action, punishTime); [Cmd, Aliases, RequireContext(ContextType.Guild), UserPerm(GuildPermission.Administrator), Priority(2)] - public async Task AntiRaid(int userThreshold, int seconds, PunishmentAction action) => await InternalAntiRaid(userThreshold, seconds, action); + public Task AntiRaid(int userThreshold, int seconds, PunishmentAction action) => + InternalAntiRaid(userThreshold, seconds, action); private async Task InternalAntiRaid(int userThreshold, int seconds = 10, PunishmentAction action = PunishmentAction.Mute, StoopidTime? punishTime = null) @@ -148,21 +149,22 @@ public async Task AntiSpam() [Cmd, Aliases, RequireContext(ContextType.Guild), UserPerm(GuildPermission.Administrator), Priority(0)] - public async Task AntiSpam(int messageCount, PunishmentAction action, [Remainder] IRole role) + public Task AntiSpam(int messageCount, PunishmentAction action, [Remainder] IRole role) { if (action != PunishmentAction.AddRole) - return; + return Task.CompletedTask; - await InternalAntiSpam(messageCount, action, null, role); + return InternalAntiSpam(messageCount, action, null, role); } [Cmd, Aliases, RequireContext(ContextType.Guild), UserPerm(GuildPermission.Administrator), Priority(1)] - public async Task AntiSpam(int messageCount, PunishmentAction action, [Remainder] StoopidTime punishTime) => await InternalAntiSpam(messageCount, action, punishTime); + public Task AntiSpam(int messageCount, PunishmentAction action, [Remainder] StoopidTime punishTime) => + InternalAntiSpam(messageCount, action, punishTime); [Cmd, Aliases, RequireContext(ContextType.Guild), UserPerm(GuildPermission.Administrator), Priority(2)] - public async Task AntiSpam(int messageCount, PunishmentAction action) => await InternalAntiSpam(messageCount, action); + public Task AntiSpam(int messageCount, PunishmentAction action) => InternalAntiSpam(messageCount, action); public async Task InternalAntiSpam(int messageCount, PunishmentAction action, StoopidTime? timeData = null, IRole? role = null) diff --git a/src/Mewdeko/Modules/Administration/SelfAssignedRolesCommands.cs b/src/Mewdeko/Modules/Administration/SelfAssignedRolesCommands.cs index ef82cc2b6..2656c6d72 100644 --- a/src/Mewdeko/Modules/Administration/SelfAssignedRolesCommands.cs +++ b/src/Mewdeko/Modules/Administration/SelfAssignedRolesCommands.cs @@ -29,7 +29,7 @@ await ReplyConfirmLocalizedAsync("adsarm_disable", await guildSettings.GetPrefix [Cmd, Aliases, RequireContext(ContextType.Guild), UserPerm(GuildPermission.ManageRoles), BotPerm(GuildPermission.ManageRoles), Priority(1)] - public async Task Asar([Remainder] IRole role) => await Asar(0, role); + public Task Asar([Remainder] IRole role) => Asar(0, role); [Cmd, Aliases, RequireContext(ContextType.Guild), UserPerm(GuildPermission.ManageRoles), BotPerm(GuildPermission.ManageRoles), Priority(0)] diff --git a/src/Mewdeko/Modules/Administration/ServerGreetCommands.cs b/src/Mewdeko/Modules/Administration/ServerGreetCommands.cs index 6131526a5..7208096f8 100644 --- a/src/Mewdeko/Modules/Administration/ServerGreetCommands.cs +++ b/src/Mewdeko/Modules/Administration/ServerGreetCommands.cs @@ -261,11 +261,11 @@ await ctx.Channel.SendConfirmAsync(GetText("leavehookset2", [Cmd, Aliases, RequireContext(ContextType.Guild), UserPerm(GuildPermission.ManageGuild)] - public async Task GreetHook(string text) => await GreetHook(null, null, null, text).ConfigureAwait(false); + public Task GreetHook(string text) => GreetHook(null, null, null, text); [Cmd, Aliases, RequireContext(ContextType.Guild), UserPerm(GuildPermission.ManageGuild)] - public async Task LeaveHook(string text) => await LeaveHook(null, null, null, text).ConfigureAwait(false); + public Task LeaveHook(string text) => LeaveHook(null, null, null, text); [Cmd, Aliases, RequireContext(ContextType.Guild), UserPerm(GuildPermission.ManageGuild)] diff --git a/src/Mewdeko/Modules/Administration/Services/AdministrationService.cs b/src/Mewdeko/Modules/Administration/Services/AdministrationService.cs index c404084e7..4666232d8 100644 --- a/src/Mewdeko/Modules/Administration/Services/AdministrationService.cs +++ b/src/Mewdeko/Modules/Administration/Services/AdministrationService.cs @@ -7,22 +7,21 @@ namespace Mewdeko.Modules.Administration.Services; public class AdministrationService : INService { private readonly DbService db; - private readonly LogCommandService logService; private readonly GuildSettingsService guildSettings; public AdministrationService(CommandHandler cmdHandler, DbService db, - LogCommandService logService, GuildSettingsService guildSettings, Mewdeko bot) { var allgc = bot.AllGuildConfigs; using var uow = db.GetDbContext(); this.db = db; - this.logService = logService; this.guildSettings = guildSettings; - DeleteMessagesOnCommand = new ConcurrentHashSet(allgc.Where(g => g.DeleteMessageOnCommand == 1).Select(g => g.GuildId)); + DeleteMessagesOnCommand = + new ConcurrentHashSet(allgc.Where(g => g.DeleteMessageOnCommand == 1).Select(g => g.GuildId)); - DeleteMessagesOnCommandChannels = new ConcurrentDictionary(allgc.SelectMany(x => x.DelMsgOnCmdChannels) + DeleteMessagesOnCommandChannels = new ConcurrentDictionary(allgc + .SelectMany(x => x.DelMsgOnCmdChannels) .ToDictionary(x => x.ChannelId, x => x.State == 1) .ToConcurrent()); @@ -101,7 +100,7 @@ private Task DelMsgOnCmd_Handler(IUserMessage msg, CommandInfo cmd) { if (state && cmd.Name != "Purge" && cmd.Name != "pick") { - logService.AddDeleteIgnore(msg.Id); + //logService.AddDeleteIgnore(msg.Id); try { await msg.DeleteAsync().ConfigureAwait(false); @@ -116,7 +115,7 @@ private Task DelMsgOnCmd_Handler(IUserMessage msg, CommandInfo cmd) else if (DeleteMessagesOnCommand.Contains(channel.Guild.Id) && cmd.Name != "Purge" && cmd.Name != "pick") { - logService.AddDeleteIgnore(msg.Id); + //logService.AddDeleteIgnore(msg.Id); try { await msg.DeleteAsync().ConfigureAwait(false); @@ -225,7 +224,8 @@ public static async Task EditMessage(ICommandContext context, ITextChannel chanl .WithDefault(context) .Build(); - if (SmartEmbed.TryParse(rep.Replace(text), context.Guild?.Id, out var embed, out var plainText, out var components)) + if (SmartEmbed.TryParse(rep.Replace(text), context.Guild?.Id, out var embed, out var plainText, + out var components)) { await umsg.ModifyAsync(x => { diff --git a/src/Mewdeko/Modules/Administration/Services/LogCommandService.cs b/src/Mewdeko/Modules/Administration/Services/LogCommandService.cs index 95e59f5f2..efbf60422 100644 --- a/src/Mewdeko/Modules/Administration/Services/LogCommandService.cs +++ b/src/Mewdeko/Modules/Administration/Services/LogCommandService.cs @@ -1,1293 +1,1294 @@ -using System.Threading; -using Humanizer; -using Mewdeko.Common.Collections; -using Mewdeko.Modules.Administration.Common; -using Mewdeko.Modules.Moderation.Services; -using Mewdeko.Services.strings; -using Microsoft.Extensions.Caching.Memory; -using Embed = Discord.Embed; +// using System.Threading; +// using Humanizer; +// using Mewdeko.Common.Collections; +// using Mewdeko.Modules.Administration.Common; +// using Mewdeko.Modules.Moderation.Services; +// using Mewdeko.Services.strings; +// using Microsoft.Extensions.Caching.Memory; +// using Embed = Discord.Embed; +// +// namespace Mewdeko.Modules.Administration.Services; +// +// public class LogCommandService : INService +// { +// public enum LogType +// { +// Other, +// EventCreated, +// RoleUpdated, +// RoleCreated, +// RoleDeleted, +// ServerUpdated, +// ThreadCreated, +// UserRoleAdded, +// UserRoleRemoved, +// UsernameUpdated, +// NicknameUpdated, +// ThreadDeleted, +// ThreadUpdated, +// MessageUpdated, +// MessageDeleted, +// UserJoined, +// UserLeft, +// UserBanned, +// UserUnbanned, +// UserUpdated, +// ChannelCreated, +// ChannelDestroyed, +// ChannelUpdated, +// VoicePresence, +// VoicePresenceTts, +// UserMuted +// } +// +// public enum LogCategoryTypes +// { +// All, +// Users, +// Threads, +// Roles, +// Server, +// Channel, +// Messages, +// Moderation, +// None +// } +// +// private readonly DiscordSocketClient client; +// private readonly DbService db; +// private readonly ConcurrentHashSet ignoreMessageIds = new(); +// private readonly IMemoryCache memoryCache; +// private readonly IBotStrings strings; +// private readonly Mewdeko bot; +// private readonly GuildSettingsService gss; +// +// private readonly GuildTimezoneService tz; +// +// public readonly Timer ClearTimer; +// +// public LogCommandService(DiscordSocketClient client, IBotStrings strings, +// DbService db, MuteService mute, ProtectionService prot, GuildTimezoneService tz, +// IMemoryCache memoryCache, Mewdeko bot, EventHandler eventHandler, GuildSettingsService gss) +// { +// this.bot = bot; +// this.gss = gss; +// this.client = client; +// this.memoryCache = memoryCache; +// this.strings = strings; +// this.db = db; +// this.tz = tz; +// +// var allgc = bot.AllGuildConfigs; +// GuildLogSettings = allgc +// .ToDictionary(g => g.GuildId, g => g.LogSetting) +// .ToConcurrent(); +// +// //_client.MessageReceived += Client_MessageReceived; +// eventHandler.MessageUpdated += Client_MessageUpdated; +// eventHandler.MessageDeleted += Client_MessageDeleted; +// eventHandler.MessagesBulkDeleted += Client_BulkDelete; +// eventHandler.UserBanned += Client_UserBanned; +// eventHandler.UserUnbanned += Client_UserUnbanned; +// eventHandler.UserJoined += Client_UserJoined; +// eventHandler.UserLeft += Client_UserLeft; +// eventHandler.UserVoiceStateUpdated += Client_UserVoiceStateUpdated; +// eventHandler.UserVoiceStateUpdated += Client_UserVoiceStateUpdated_TTS; +// eventHandler.GuildMemberUpdated += Client_GuildUserUpdated; +// #if !GLOBAL_Mewdeko +// eventHandler.UserUpdated += Client_UserUpdated; +// #endif +// eventHandler.ChannelCreated += Client_ChannelCreated; +// eventHandler.ChannelDestroyed += Client_ChannelDestroyed; +// eventHandler.ChannelUpdated += Client_ChannelUpdated; +// eventHandler.RoleDeleted += Client_RoleDeleted; +// +// mute.UserMuted += MuteCommands_UserMuted; +// mute.UserUnmuted += MuteCommands_UserUnmuted; +// //_client.ThreadCreated += ThreadCreated; +// prot.OnAntiProtectionTriggered += TriggeredAntiProtection; +// +// ClearTimer = new Timer(_ => ignoreMessageIds.Clear(), null, TimeSpan.FromHours(1), +// TimeSpan.FromHours(1)); +// } +// +// public ConcurrentDictionary GuildLogSettings { get; } +// +// public void AddDeleteIgnore(ulong messageId) => ignoreMessageIds.Add(messageId); +// +// public async Task LogIgnore(ulong gid, ulong cid) +// { +// int removed; +// await using var uow = db.GetDbContext(); +// var config = await uow.LogSettingsFor(gid); +// var logSetting = GuildLogSettings.GetOrAdd(gid, _ => config.LogSetting); +// removed = logSetting.IgnoredChannels.RemoveWhere(ilc => ilc.ChannelId == cid); +// config.LogSetting.IgnoredChannels.RemoveWhere(ilc => ilc.ChannelId == cid); +// if (removed == 0) +// { +// var toAdd = new IgnoredLogChannel +// { +// ChannelId = cid +// }; +// logSetting.IgnoredChannels.Add(toAdd); +// config.LogSetting.IgnoredChannels.Add(toAdd); +// } +// +// await uow.SaveChangesAsync(); +// +// return removed > 0; +// } +// +// private string GetText(IGuild guild, string key, params object[] replacements) => +// strings.GetText(key, guild.Id, replacements); +// +// private string CurrentTime(IGuild? g) +// { +// var time = DateTime.UtcNow; +// if (g != null) +// time = TimeZoneInfo.ConvertTime(time, tz.GetTimeZoneOrUtc(g.Id)); +// +// return $"{time:HH:mm:ss}"; +// } +// +// public async Task SetLogChannel(ulong guildId, ulong channelId, LogType type) +// { +// await using var uow = db.GetDbContext(); +// var logSetting = (await uow.LogSettingsFor(guildId)).LogSetting; +// switch (type) +// { +// case LogType.Other: +// logSetting.LogOtherId = channelId; +// break; +// case LogType.EventCreated: +// logSetting.EventCreatedId = channelId; +// break; +// case LogType.RoleUpdated: +// logSetting.RoleUpdatedId = channelId; +// break; +// case LogType.RoleCreated: +// logSetting.RoleCreatedId = channelId; +// break; +// case LogType.ServerUpdated: +// logSetting.ServerUpdatedId = channelId; +// break; +// case LogType.ThreadCreated: +// logSetting.ThreadCreatedId = channelId; +// break; +// case LogType.UserRoleAdded: +// logSetting.UserRoleAddedId = channelId; +// break; +// case LogType.UserRoleRemoved: +// logSetting.UserRoleRemovedId = channelId; +// break; +// case LogType.UsernameUpdated: +// logSetting.UsernameUpdatedId = channelId; +// break; +// case LogType.NicknameUpdated: +// logSetting.NicknameUpdatedId = channelId; +// break; +// case LogType.ThreadDeleted: +// logSetting.ThreadDeletedId = channelId; +// break; +// case LogType.ThreadUpdated: +// logSetting.ThreadUpdatedId = channelId; +// break; +// case LogType.MessageUpdated: +// logSetting.MessageUpdatedId = channelId; +// break; +// case LogType.MessageDeleted: +// logSetting.MessageDeletedId = channelId; +// break; +// case LogType.UserJoined: +// logSetting.UserJoinedId = channelId; +// break; +// case LogType.UserLeft: +// logSetting.UserLeftId = channelId; +// break; +// case LogType.UserBanned: +// logSetting.UserBannedId = channelId; +// break; +// case LogType.UserUnbanned: +// logSetting.UserUnbannedId = channelId; +// break; +// case LogType.UserUpdated: +// logSetting.UserUpdatedId = channelId; +// break; +// case LogType.ChannelCreated: +// logSetting.ChannelCreatedId = channelId; +// break; +// case LogType.ChannelDestroyed: +// logSetting.ChannelDestroyedId = channelId; +// break; +// case LogType.ChannelUpdated: +// logSetting.ChannelUpdatedId = channelId; +// break; +// case LogType.VoicePresence: +// logSetting.LogVoicePresenceId = channelId; +// break; +// case LogType.VoicePresenceTts: +// logSetting.LogVoicePresenceTTSId = channelId; +// break; +// case LogType.UserMuted: +// logSetting.UserMutedId = channelId; +// break; +// } +// +// uow.LogSettings.Update(logSetting); +// await uow.SaveChangesAsync(); +// GuildLogSettings.AddOrUpdate(guildId, _ => logSetting, (_, _) => logSetting); +// } +// +// public async Task LogSetByType(ulong guildId, ulong channelId, LogCategoryTypes categoryTypes) +// { +// await using var uow = db.GetDbContext(); +// var logSetting = (await uow.LogSettingsFor(guildId)).LogSetting; +// switch (categoryTypes) +// { +// case LogCategoryTypes.All: +// logSetting.AvatarUpdatedId = channelId; +// logSetting.ChannelCreatedId = channelId; +// logSetting.ChannelDestroyedId = channelId; +// logSetting.ChannelUpdatedId = channelId; +// logSetting.EventCreatedId = channelId; +// logSetting.LogOtherId = channelId; +// logSetting.MessageDeletedId = channelId; +// logSetting.MessageUpdatedId = channelId; +// logSetting.NicknameUpdatedId = channelId; +// logSetting.RoleCreatedId = channelId; +// logSetting.RoleDeletedId = channelId; +// logSetting.RoleUpdatedId = channelId; +// logSetting.ServerUpdatedId = channelId; +// logSetting.ThreadCreatedId = channelId; +// logSetting.ThreadDeletedId = channelId; +// logSetting.ThreadUpdatedId = channelId; +// logSetting.UserBannedId = channelId; +// logSetting.UserJoinedId = channelId; +// logSetting.UserLeftId = channelId; +// logSetting.UserMutedId = channelId; +// logSetting.UsernameUpdatedId = channelId; +// logSetting.UserUnbannedId = channelId; +// logSetting.UserUpdatedId = channelId; +// logSetting.LogUserPresenceId = channelId; +// logSetting.LogVoicePresenceId = channelId; +// logSetting.UserRoleAddedId = channelId; +// logSetting.UserRoleRemovedId = channelId; +// logSetting.LogVoicePresenceTTSId = channelId; +// break; +// case LogCategoryTypes.Users: +// logSetting.NicknameUpdatedId = channelId; +// logSetting.AvatarUpdatedId = channelId; +// logSetting.UsernameUpdatedId = channelId; +// logSetting.UserRoleAddedId = channelId; +// logSetting.UserRoleRemovedId = channelId; +// logSetting.LogVoicePresenceId = channelId; +// break; +// case LogCategoryTypes.Threads: +// logSetting.ThreadCreatedId = channelId; +// logSetting.ThreadDeletedId = channelId; +// logSetting.ThreadUpdatedId = channelId; +// break; +// case LogCategoryTypes.Roles: +// logSetting.RoleCreatedId = channelId; +// logSetting.RoleDeletedId = channelId; +// logSetting.RoleUpdatedId = channelId; +// break; +// case LogCategoryTypes.Server: +// logSetting.ServerUpdatedId = channelId; +// logSetting.EventCreatedId = channelId; +// break; +// case LogCategoryTypes.Channel: +// logSetting.ChannelUpdatedId = channelId; +// logSetting.ChannelCreatedId = channelId; +// logSetting.ChannelDestroyedId = channelId; +// break; +// case LogCategoryTypes.Messages: +// logSetting.MessageDeletedId = channelId; +// logSetting.MessageUpdatedId = channelId; +// break; +// case LogCategoryTypes.Moderation: +// logSetting.UserMutedId = channelId; +// logSetting.UserBannedId = channelId; +// logSetting.UserUnbannedId = channelId; +// break; +// case LogCategoryTypes.None: +// logSetting.AvatarUpdatedId = 0; +// logSetting.ChannelCreatedId = 0; +// logSetting.ChannelDestroyedId = 0; +// logSetting.ChannelUpdatedId = 0; +// logSetting.EventCreatedId = 0; +// logSetting.LogOtherId = 0; +// logSetting.MessageDeletedId = 0; +// logSetting.MessageUpdatedId = 0; +// logSetting.NicknameUpdatedId = 0; +// logSetting.RoleCreatedId = 0; +// logSetting.RoleDeletedId = 0; +// logSetting.RoleUpdatedId = 0; +// logSetting.ServerUpdatedId = 0; +// logSetting.ThreadCreatedId = 0; +// logSetting.ThreadDeletedId = 0; +// logSetting.ThreadUpdatedId = 0; +// logSetting.UserBannedId = 0; +// logSetting.UserJoinedId = 0; +// logSetting.UserLeftId = 0; +// logSetting.UserMutedId = 0; +// logSetting.UsernameUpdatedId = 0; +// logSetting.UserUnbannedId = 0; +// logSetting.UserUpdatedId = 0; +// logSetting.LogUserPresenceId = 0; +// logSetting.LogVoicePresenceId = 0; +// logSetting.UserRoleAddedId = 0; +// logSetting.UserRoleRemovedId = 0; +// logSetting.LogVoicePresenceTTSId = 0; +// break; +// } +// +// uow.LogSettings.Update(logSetting); +// await uow.SaveChangesAsync(); +// GuildLogSettings.AddOrUpdate(guildId, _ => logSetting, (_, _) => logSetting); +// } +// +// private async Task Client_UserUpdated(SocketUser before, SocketUser uAfter) +// { +// try +// { +// await using var uow = db.GetDbContext(); +// if (uAfter is not SocketGuildUser guildUser) +// return; +// +// var g = guildUser.Guild; +// +// if (!GuildLogSettings.TryGetValue(g.Id, out var logSetting) +// || logSetting.UserUpdatedId == null && logSetting.NicknameUpdatedId == null && +// logSetting.UsernameUpdatedId == null && logSetting.AvatarUpdatedId == null) +// { +// return; +// } +// +// ITextChannel logChannel; +// if ((logChannel = +// await TryGetLogChannel(g, logSetting, LogType.UserUpdated).ConfigureAwait(false)) == null) +// { +// return; +// } +// +// var embeds = new List(); +// +// if (before.ToString() != guildUser.ToString()) +// { +// embeds.Add(new EmbedBuilder().WithTitle($"👥 {GetText(g, "username_changed")}") +// .WithTitle($"{before.Username}#{before.Discriminator} | {before.Id}") +// .WithDescription( +// $"**Old Username**\n=> {before}\n**New Username**\n=> {guildUser}\n**Date Changed**\n=>{TimestampTag.FromDateTime(DateTime.UtcNow)}") +// .WithOkColor().Build()); +// } +// else if (before.AvatarId != guildUser.AvatarId) +// { +// var bav = before.RealAvatarUrl(); +// embeds.Add(new EmbedBuilder().WithTitle($"👥{GetText(g, "avatar_changed")}") +// .WithDescription($"{before.Username}#{before.Discriminator} | {before.Id}") +// .AddField("Old Avatar", "_ _") +// .WithImageUrl(bav.ToString()) +// .WithFooter(fb => fb.WithText(CurrentTime(g))) +// .WithOkColor().Build()); +// +// var aav = guildUser.RealAvatarUrl(); +// embeds.Add(new EmbedBuilder().AddField("New Avatar", "_ _").WithImageUrl(aav.ToString()).WithOkColor() +// .Build()); +// } +// else +// { +// return; +// } +// +// await logChannel.SendMessageAsync(embeds: embeds.ToArray()).ConfigureAwait(false); +// } +// catch +// { +// // ignored +// } +// } +// +// +// public async Task UpdateCommandLogChannel(IGuild guild, ulong id) +// { +// await using var uow = db.GetDbContext(); +// var gc = await uow.ForGuildId(guild.Id, set => set); +// gc.CommandLogChannel = id; +// await uow.SaveChangesAsync(); +// await gss.UpdateGuildConfig(guild.Id, gc); +// } +// +// private async Task Client_UserVoiceStateUpdated_TTS(SocketUser iusr, SocketVoiceState before, +// SocketVoiceState after) +// { +// try +// { +// if (iusr is not IGuildUser usr) +// return; +// +// var beforeVch = before.VoiceChannel; +// var afterVch = after.VoiceChannel; +// +// if (beforeVch == afterVch) +// return; +// +// if (!GuildLogSettings.TryGetValue(usr.Guild.Id, out var logSetting) +// || logSetting.LogVoicePresenceTTSId == null) +// { +// return; +// } +// +// ITextChannel logChannel; +// if ((logChannel = await TryGetLogChannel(usr.Guild, logSetting, LogType.VoicePresenceTts) +// .ConfigureAwait(false)) == null) +// { +// return; +// } +// +// var str = ""; +// if (beforeVch?.Guild == afterVch?.Guild) +// str = GetText(logChannel.Guild, "log_vc_moved", usr.Username, beforeVch?.Name, afterVch?.Name); +// else if (beforeVch == null) +// str = GetText(logChannel.Guild, "log_vc_joined", usr.Username, afterVch.Name); +// else if (afterVch == null) +// str = GetText(logChannel.Guild, "log_vc_left", usr.Username, beforeVch.Name); +// +// var toDelete = await logChannel.SendMessageAsync(str, true).ConfigureAwait(false); +// toDelete.DeleteAfter(5); +// } +// catch +// { +// // ignored +// } +// } +// +// private async Task MuteCommands_UserMuted(IGuildUser usr, IUser mod, MuteType muteType, string reason) +// { +// try +// { +// if (!GuildLogSettings.TryGetValue(usr.Guild.Id, out var logSetting) +// || logSetting.UserMutedId == null) +// { +// return; +// } +// +// ITextChannel logChannel; +// if ((logChannel = await TryGetLogChannel(usr.Guild, logSetting, LogType.UserMuted) +// .ConfigureAwait(false)) == null) +// { +// return; +// } +// +// var mutes = ""; +// var mutedLocalized = GetText(logChannel.Guild, "muted_sn"); +// mutes = muteType switch +// { +// MuteType.Voice => $"🔇 {GetText(logChannel.Guild, "xmuted_voice", mutedLocalized, mod.ToString())}", +// MuteType.Chat => $"🔇 {GetText(logChannel.Guild, "xmuted_text", mutedLocalized, mod.ToString())}", +// MuteType.All => +// $"🔇 {GetText(logChannel.Guild, "xmuted_text_and_voice", mutedLocalized, mod.ToString())}", +// _ => mutes +// }; +// +// var embed = new EmbedBuilder().WithAuthor(eab => eab.WithName(mutes)) +// .WithTitle($"{usr.Username}#{usr.Discriminator} | {usr.Id}") +// .WithFooter(fb => fb.WithText(CurrentTime(usr.Guild))) +// .WithOkColor(); +// +// await logChannel.EmbedAsync(embed).ConfigureAwait(false); +// } +// catch +// { +// // ignored +// } +// } +// +// private async Task MuteCommands_UserUnmuted(IGuildUser usr, IUser mod, MuteType muteType, string reason) +// { +// try +// { +// if (!GuildLogSettings.TryGetValue(usr.Guild.Id, out var logSetting) +// || logSetting.UserMutedId == null) +// { +// return; +// } +// +// ITextChannel logChannel; +// if ((logChannel = await TryGetLogChannel(usr.Guild, logSetting, LogType.UserMuted) +// .ConfigureAwait(false)) == null) +// { +// return; +// } +// +// var mutes = ""; +// var unmutedLocalized = GetText(logChannel.Guild, "unmuted_sn"); +// mutes = muteType switch +// { +// MuteType.Voice => +// $"🔊 {GetText(logChannel.Guild, "xmuted_voice", unmutedLocalized, mod.ToString())}", +// MuteType.Chat => $"🔊 {GetText(logChannel.Guild, "xmuted_text", unmutedLocalized, mod.ToString())}", +// MuteType.All => +// $"🔊 {GetText(logChannel.Guild, "xmuted_text_and_voice", unmutedLocalized, mod.ToString())}", +// _ => mutes +// }; +// +// var embed = new EmbedBuilder().WithAuthor(eab => eab.WithName(mutes)) +// .WithTitle($"{usr.Username}#{usr.Discriminator} | {usr.Id}") +// .WithFooter(fb => fb.WithText($"{CurrentTime(usr.Guild)}")) +// .WithOkColor(); +// +// if (!string.IsNullOrWhiteSpace(reason)) +// embed.WithDescription(reason); +// +// await logChannel.EmbedAsync(embed).ConfigureAwait(false); +// } +// catch +// { +// // ignored +// } +// } +// +// private async Task TriggeredAntiProtection(PunishmentAction action, ProtectionType protection, +// params IGuildUser[] users) +// { +// try +// { +// if (users.Length == 0) +// return; +// +// if (!GuildLogSettings.TryGetValue(users.First().Guild.Id, out var logSetting) +// || logSetting.LogOtherId == null) +// { +// return; +// } +// +// ITextChannel logChannel; +// if ((logChannel = await TryGetLogChannel(users.First().Guild, logSetting, LogType.Other) +// .ConfigureAwait(false)) == null) +// { +// return; +// } +// +// var punishment = ""; +// switch (action) +// { +// case PunishmentAction.Mute: +// punishment = $"🔇 {GetText(logChannel.Guild, "muted_pl").ToUpperInvariant()}"; +// break; +// case PunishmentAction.Kick: +// punishment = $"👢 {GetText(logChannel.Guild, "kicked_pl").ToUpperInvariant()}"; +// break; +// case PunishmentAction.Softban: +// punishment = $"☣ {GetText(logChannel.Guild, "soft_banned_pl").ToUpperInvariant()}"; +// break; +// case PunishmentAction.Ban: +// punishment = $"⛔️ {GetText(logChannel.Guild, "banned_pl").ToUpperInvariant()}"; +// break; +// case PunishmentAction.RemoveRoles: +// punishment = $"⛔️ {GetText(logChannel.Guild, "remove_roles_pl").ToUpperInvariant()}"; +// break; +// case PunishmentAction.ChatMute: +// break; +// case PunishmentAction.VoiceMute: +// break; +// case PunishmentAction.AddRole: +// break; +// default: +// throw new ArgumentOutOfRangeException(nameof(action), action, null); +// } +// +// var embed = new EmbedBuilder().WithAuthor(eab => eab.WithName($"🛡 Anti-{protection}")) +// .WithTitle($"{GetText(logChannel.Guild, "users")} {punishment}") +// .WithDescription(string.Join("\n", users.Select(u => u.ToString()))) +// .WithFooter(fb => fb.WithText(CurrentTime(logChannel.Guild))) +// .WithOkColor(); +// +// await logChannel.EmbedAsync(embed).ConfigureAwait(false); +// } +// catch +// { +// // ignored +// } +// } +// +// private static string GetRoleDeletedKey(ulong roleId) => $"role_deleted_{roleId}"; +// +// private Task Client_RoleDeleted(SocketRole socketRole) +// { +// #if DEBUG +// Serilog.Log.Information("Role deleted {RoleId}", socketRole.Id); +// #endif +// memoryCache.Set(GetRoleDeletedKey(socketRole.Id), true, TimeSpan.FromMinutes(5)); +// return Task.CompletedTask; +// } +// +// private bool IsRoleDeleted(ulong roleId) +// => memoryCache.TryGetValue(GetRoleDeletedKey(roleId), out _); +// +// private async Task Client_GuildUserUpdated(Cacheable cacheable, SocketGuildUser? after) +// { +// try +// { +// if (!bot.Ready.Task.IsCompleted) +// return; +// +// if (!cacheable.HasValue) +// return; +// +// if (after is null) +// return; +// +// if (!GuildLogSettings.TryGetValue(cacheable.Value.Guild.Id, out var logSetting)) +// return; +// +// ITextChannel logChannel; +// if (logSetting.UserUpdatedId != null && +// (logChannel = await TryGetLogChannel(cacheable.Value.Guild, logSetting, LogType.UserUpdated) +// .ConfigureAwait(false)) != null) +// { +// var embed = new EmbedBuilder().WithOkColor() +// .WithTitle($"{cacheable.Value.Username}#{cacheable.Value.Discriminator} | {cacheable.Id}"); +// if (cacheable.Value.Nickname != after.Nickname) +// { +// var logChannel1 = logChannel; +// embed.WithAuthor(eab => eab.WithName($"👥 {GetText(logChannel1.Guild, "nick_change")}")) +// .WithDescription( +// $"**Old Nickname**\n=> {cacheable.Value.Nickname ?? cacheable.Value.Username}\n**New Nickname**\n=> {after.Nickname ?? after.Username}\n**Changed On**\n=>{TimestampTag.FromDateTime(DateTime.UtcNow)}"); +// +// await logChannel.EmbedAsync(embed).ConfigureAwait(false); +// } +// else if (!cacheable.Value.Roles.SequenceEqual(after.Roles)) +// { +// if (cacheable.Value.Roles.Count < after.Roles.Count) +// { +// var diffRoles = after.Roles.Where(r => !cacheable.Value.Roles.Contains(r)) +// .Select(r => r.Name); +// var channel = logChannel; +// embed.WithAuthor(eab => eab.WithName($"⚔ {GetText(channel.Guild, "user_role_add")}")) +// .WithDescription(string.Join(", ", diffRoles)); +// +// await logChannel.EmbedAsync(embed).ConfigureAwait(false); +// } +// else if (cacheable.Value.Roles.Count > after.Roles.Count) +// { +// await Task.Delay(1000).ConfigureAwait(false); +// var diffRoles = cacheable.Value.Roles +// .Where(r => !after.Roles.Contains(r) && !IsRoleDeleted(r.Id)) +// .Select(r => r.Name) +// .ToList(); +// +// if (diffRoles.Count > 0) +// { +// var channel = logChannel; +// embed.WithAuthor(eab => +// eab.WithName($"⚔ {GetText(channel.Guild, "user_role_rem")}")) +// .WithDescription(string.Join(", ", diffRoles).SanitizeMentions()); +// +// await logChannel.EmbedAsync(embed).ConfigureAwait(false); +// } +// } +// } +// } +// } +// catch +// { +// // ignored +// } +// } +// +// private async Task Client_ChannelUpdated(IChannel cbefore, IChannel cafter) +// { +// try +// { +// if (cbefore is not IGuildChannel before) +// return; +// +// var after = (IGuildChannel)cafter; +// +// if (!GuildLogSettings.TryGetValue(before.Guild.Id, out var logSetting) +// || logSetting.ChannelUpdatedId == null +// || logSetting.IgnoredChannels.Any(ilc => ilc.ChannelId == after.Id)) +// { +// return; +// } +// +// ITextChannel logChannel; +// if ((logChannel = await TryGetLogChannel(before.Guild, logSetting, LogType.ChannelUpdated) +// .ConfigureAwait(false)) == null) +// { +// return; +// } +// +// var embed = new EmbedBuilder().WithOkColor() +// .WithFooter(efb => efb.WithText(CurrentTime(before.Guild))); +// +// var beforeTextChannel = cbefore as ITextChannel; +// var afterTextChannel = cafter as ITextChannel; +// +// if (before.Name != after.Name) +// { +// embed.WithTitle($"ℹ️ {GetText(logChannel.Guild, "ch_name_change")}") +// .WithDescription($"{after} | {after.Id}") +// .AddField(efb => +// efb.WithName(GetText(logChannel.Guild, "ch_old_name")).WithValue(before.Name)); +// } +// else if (beforeTextChannel?.Topic != afterTextChannel?.Topic) +// { +// embed.WithTitle($"ℹ️ {GetText(logChannel.Guild, "ch_topic_change")}") +// .WithDescription($"{after} | {after.Id}") +// .AddField(efb => +// efb.WithName(GetText(logChannel.Guild, "old_topic")) +// .WithValue(beforeTextChannel?.Topic ?? "-")) +// .AddField(efb => +// efb.WithName(GetText(logChannel.Guild, "new_topic")) +// .WithValue(afterTextChannel?.Topic ?? "-")); +// } +// else +// { +// return; +// } +// +// await logChannel.EmbedAsync(embed).ConfigureAwait(false); +// } +// catch +// { +// // ignored +// } +// } +// +// private async Task Client_ChannelDestroyed(IChannel ich) +// { +// try +// { +// if (ich is not IGuildChannel ch) +// return; +// +// if (!GuildLogSettings.TryGetValue(ch.Guild.Id, out var logSetting) +// || logSetting.ChannelDestroyedId == null +// || logSetting.IgnoredChannels.Any(ilc => ilc.ChannelId == ch.Id)) +// { +// return; +// } +// +// ITextChannel logChannel; +// if ((logChannel = await TryGetLogChannel(ch.Guild, logSetting, LogType.ChannelDestroyed) +// .ConfigureAwait(false)) == null) +// { +// return; +// } +// +// var title = GetText(logChannel.Guild, ch is IVoiceChannel ? "voice_chan_destroyed" : "text_chan_destroyed"); +// +// var audits = await ch.Guild.GetAuditLogsAsync().ConfigureAwait(false); +// var e = audits.FirstOrDefault(x => x.Action == ActionType.ChannelDeleted); +// await logChannel.EmbedAsync(new EmbedBuilder() +// .WithOkColor() +// .WithTitle($"🆕 {title}") +// .WithDescription($"{ch.Name} | {ch.Id}") +// .AddField("Yeeted By", e?.User) +// .WithFooter(efb => efb.WithText(CurrentTime(ch.Guild)))).ConfigureAwait(false); +// } +// catch +// { +// // ignored +// } +// } +// +// private async Task Client_ChannelCreated(IChannel ich) +// { +// try +// { +// if (ich is not IGuildChannel ch) +// return; +// +// if (!GuildLogSettings.TryGetValue(ch.Guild.Id, out var logSetting) +// || logSetting.ChannelCreatedId == null) +// { +// return; +// } +// +// ITextChannel logChannel; +// if ((logChannel = await TryGetLogChannel(ch.Guild, logSetting, LogType.ChannelCreated) +// .ConfigureAwait(false)) == null) +// { +// return; +// } +// +// var title = GetText(logChannel.Guild, ch is IVoiceChannel ? "voice_chan_created" : "text_chan_created"); +// +// await logChannel.EmbedAsync(new EmbedBuilder() +// .WithOkColor() +// .WithTitle($"🆕 {title}") +// .WithDescription($"{ch.Name} | {ch.Id}") +// .WithFooter(efb => efb.WithText(CurrentTime(ch.Guild)))).ConfigureAwait(false); +// } +// catch (Exception) +// { +// // ignored +// } +// } +// +// private async Task Client_UserVoiceStateUpdated(SocketUser iusr, SocketVoiceState before, SocketVoiceState after) +// { +// try +// { +// if (iusr is not IGuildUser usr) +// return; +// +// var beforeVch = before.VoiceChannel; +// var afterVch = after.VoiceChannel; +// +// if (beforeVch == afterVch) +// return; +// +// if (!GuildLogSettings.TryGetValue(usr.Guild.Id, out var logSetting) +// || logSetting.LogVoicePresenceId == null) +// { +// return; +// } +// +// ITextChannel logChannel; +// if ((logChannel = await TryGetLogChannel(usr.Guild, logSetting, LogType.VoicePresence) +// .ConfigureAwait(false)) == null) +// { +// return; +// } +// +// var str = ""; +// if (beforeVch?.Guild == afterVch?.Guild) +// str = GetText(logChannel.Guild, "log_vc_moved", usr.Username, beforeVch?.Name, afterVch?.Name); +// else if (beforeVch == null) +// str = GetText(logChannel.Guild, "log_vc_joined", usr.Username, afterVch.Name); +// else if (afterVch == null) +// str = GetText(logChannel.Guild, "log_vc_left", usr.Username, beforeVch.Name); +// +// await logChannel.SendConfirmAsync(str).ConfigureAwait(false); +// } +// catch +// { +// // ignored +// } +// } +// +// private async Task Client_UserLeft(IGuild args, IUser arsg2) +// { +// try +// { +// if (arsg2 is not SocketGuildUser usr) return; +// if (!GuildLogSettings.TryGetValue(args.Id, out var logSetting) +// || logSetting.UserLeftId == null) +// { +// return; +// } +// +// ITextChannel logChannel; +// if ((logChannel = await TryGetLogChannel(args, logSetting, LogType.UserLeft) +// .ConfigureAwait(false)) == null) +// { +// return; +// } +// +// var embed = new EmbedBuilder() +// .WithOkColor() +// .WithTitle($"❌ {GetText(logChannel.Guild, "user_left")}") +// .WithDescription(usr.ToString()) +// .AddField(efb => efb.WithName("Id").WithValue(usr.Id.ToString())) +// .AddField("Roles", string.Join("|", usr.GetRoles().Select(x => x.Mention))) +// .AddField("Time Stayed:", (usr.JoinedAt - DateTime.Now).Value.Humanize()) +// .WithFooter(efb => efb.WithText(CurrentTime(usr.Guild))); +// +// if (Uri.IsWellFormedUriString(usr.GetAvatarUrl(), UriKind.Absolute)) +// embed.WithThumbnailUrl(usr.GetAvatarUrl()); +// +// await logChannel.EmbedAsync(embed).ConfigureAwait(false); +// } +// catch +// { +// // ignored +// } +// } +// +// private async Task Client_UserJoined(IGuildUser usr) +// { +// try +// { +// if (!GuildLogSettings.TryGetValue(usr.Guild.Id, out var logSetting) +// || logSetting.UserJoinedId == null) +// { +// return; +// } +// +// ITextChannel logChannel; +// if ((logChannel = await TryGetLogChannel(usr.Guild, logSetting, LogType.UserJoined) +// .ConfigureAwait(false)) == null) +// { +// return; +// } +// +// var embed = new EmbedBuilder() +// .WithOkColor() +// .WithTitle($"✅ {GetText(logChannel.Guild, "user_joined")}") +// .WithDescription($"{usr.Mention} `{usr}`") +// .AddField(efb => efb.WithName("Id").WithValue(usr.Id.ToString())) +// .AddField(fb => +// fb.WithName(GetText(logChannel.Guild, "joined_server")) +// .WithValue($"{usr.JoinedAt?.ToString("dd.MM.yyyy HH:mm") ?? "?"}").WithIsInline(true)) +// .AddField(fb => +// fb.WithName(GetText(logChannel.Guild, "joined_discord")) +// .WithValue($"{usr.CreatedAt:dd.MM.yyyy HH:mm}").WithIsInline(true)) +// .WithFooter(efb => efb.WithText(CurrentTime(usr.Guild))); +// +// if (Uri.IsWellFormedUriString(usr.GetAvatarUrl(), UriKind.Absolute)) +// embed.WithThumbnailUrl(usr.GetAvatarUrl()); +// +// await logChannel.EmbedAsync(embed).ConfigureAwait(false); +// } +// catch (Exception) +// { +// // ignored +// } +// } +// +// private async Task Client_UserUnbanned(IUser usr, IGuild guild) +// { +// try +// { +// if (!GuildLogSettings.TryGetValue(guild.Id, out var logSetting) +// || logSetting.UserUnbannedId == null) +// { +// return; +// } +// +// var unbannedby = (await guild.GetAuditLogsAsync(actionType: ActionType.Unban)).FirstOrDefault(); +// ITextChannel logChannel; +// if ((logChannel = await TryGetLogChannel(guild, logSetting, LogType.UserUnbanned) +// .ConfigureAwait(false)) == null) +// { +// return; +// } +// +// var embed = new EmbedBuilder() +// .WithOkColor() +// .WithTitle($"♻️ {GetText(logChannel.Guild, "user_unbanned")}") +// .WithDescription(usr.ToString()) +// .AddField(efb => efb.WithName("Id").WithValue(usr.Id.ToString())) +// .WithFooter(efb => efb.WithText(CurrentTime(guild))); +// +// if (unbannedby != null) +// { +// embed +// .AddField("Unbanned by", unbannedby.User) +// .AddField("Reason", unbannedby.Reason ?? "None"); +// } +// +// if (Uri.IsWellFormedUriString(usr.GetAvatarUrl(), UriKind.Absolute)) +// embed.WithThumbnailUrl(usr.GetAvatarUrl()); +// +// await logChannel.EmbedAsync(embed).ConfigureAwait(false); +// } +// catch (Exception) +// { +// // ignored +// } +// } +// +// private async Task Client_UserBanned(IUser usr, IGuild guild) +// { +// try +// { +// if (!GuildLogSettings.TryGetValue(guild.Id, out var logSetting) +// || logSetting.UserBannedId == null) +// { +// return; +// } +// +// var bannedby = (await guild.GetAuditLogsAsync(actionType: ActionType.Ban)).FirstOrDefault(); +// ITextChannel logChannel; +// if ((logChannel = +// await TryGetLogChannel(guild, logSetting, LogType.UserBanned).ConfigureAwait(false)) == +// null) +// { +// return; +// } +// +// var embed = new EmbedBuilder() +// .WithOkColor() +// .WithTitle($"🚫 {GetText(logChannel.Guild, "user_banned")}") +// .WithDescription(usr.ToString()); +// +// if (bannedby != null) +// { +// embed +// .AddField("Banned by", bannedby.User) +// .AddField("Reason", bannedby.Reason ?? "None"); +// } +// +// embed.AddField(efb => efb.WithName("Id").WithValue(usr.Id.ToString())) +// .WithFooter(efb => efb.WithText(CurrentTime(guild))); +// +// var avatarUrl = usr.GetAvatarUrl(); +// +// if (Uri.IsWellFormedUriString(avatarUrl, UriKind.Absolute)) +// embed.WithThumbnailUrl(usr.GetAvatarUrl()); +// +// await logChannel.EmbedAsync(embed).ConfigureAwait(false); +// } +// catch (Exception) +// { +// // ignored +// } +// } +// +// private async Task Client_BulkDelete(IReadOnlyCollection> messages, +// Cacheable channel) +// { +// if (channel.Value is not ITextChannel chan) +// return; +// +// if (!GuildLogSettings.TryGetValue(chan.Guild.Id, out var logSetting) +// || logSetting.MessageDeletedId == null +// || logSetting.IgnoredChannels.Any(ilc => ilc.ChannelId == channel.Id)) +// { +// return; +// } +// +// ITextChannel logChannel; +// if ((logChannel = await TryGetLogChannel(chan.Guild, logSetting, LogType.MessageDeleted) +// .ConfigureAwait(false)) == null) +// { +// return; +// } +// +// var toSend = new List(); +// foreach (var message in messages) +// { +// if ((message.HasValue ? message.Value : null) is IUserMessage msg && !msg.IsAuthor(client) && +// !ignoreMessageIds.Contains(msg.Id)) +// { +// toSend.Add(msg); +// } +// } +// +// var count = toSend.Count; +// +// if (count == 1) +// return; +// +// for (var i = 0; i < toSend.Count; i += 100) +// { +// var toBatch = toSend.Skip(i).Take(100); +// foreach (var group in toBatch.Chunk(20)) +// { +// var eb = new EmbedBuilder().WithOkColor(); +// eb.WithTitle($"🗑 {count} Messages bulk deleted in {channel.Value.Name}"); +// eb.WithDescription(string.Join("\n", +// group.Select(x => $"{x.Author}: {x.Content}".Truncate(202)))); +// await logChannel.SendMessageAsync(embed: eb.Build()).ConfigureAwait(false); +// } +// +// await Task.Delay(1000).ConfigureAwait(false); +// } +// } +// +// +// private async Task Client_MessageDeleted(Cacheable optMsg, Cacheable ch) +// { +// try +// { +// if ((optMsg.HasValue ? optMsg.Value : null) is not IUserMessage msg || msg.IsAuthor(client)) +// return; +// +// if (ignoreMessageIds.Contains(msg.Id)) +// return; +// +// if (ch.Value is not ITextChannel channel) +// return; +// +// if (!GuildLogSettings.TryGetValue(channel.Guild.Id, out var logSetting) +// || logSetting.MessageDeletedId == null +// || logSetting.IgnoredChannels.Any(ilc => ilc.ChannelId == channel.Id)) +// { +// return; +// } +// +// ITextChannel logChannel; +// if ((logChannel = await TryGetLogChannel(channel.Guild, logSetting, LogType.MessageDeleted) +// .ConfigureAwait(false)) == null || logChannel.Id == msg.Id) +// { +// return; +// } +// +// var resolvedMessage = msg.Resolve(TagHandling.FullName); +// var embed = new EmbedBuilder() +// .WithOkColor() +// .WithTitle($"🗑 {GetText(logChannel.Guild, "msg_del", ((ITextChannel)msg.Channel).Name)}") +// .WithDescription(msg.Author.ToString()) +// .AddField(efb => +// efb.WithName(GetText(logChannel.Guild, "content")) +// .WithValue(string.IsNullOrWhiteSpace(resolvedMessage) ? "-" : resolvedMessage) +// .WithIsInline(false)) +// .AddField(efb => efb.WithName("Id").WithValue(msg.Id.ToString()).WithIsInline(false)) +// .WithFooter(efb => efb.WithText(CurrentTime(channel.Guild))); +// if (msg.Attachments.Count > 0) +// { +// embed.AddField(efb => +// efb.WithName(GetText(logChannel.Guild, "attachments")) +// .WithValue(string.Join(", ", msg.Attachments.Select(a => a.Url))).WithIsInline(false)); +// } +// +// await logChannel.EmbedAsync(embed).ConfigureAwait(false); +// } +// catch (Exception) +// { +// // ignored +// } +// } +// +// private async Task Client_MessageUpdated(Cacheable optmsg, SocketMessage imsg2, +// ISocketMessageChannel ch) +// { +// try +// { +// if (imsg2 is not IUserMessage after || after.IsAuthor(client)) +// return; +// +// if ((optmsg.HasValue ? optmsg.Value : null) is not IUserMessage before) +// return; +// +// if (ch is not ITextChannel channel) +// return; +// +// if (before.Content == after.Content) +// return; +// +// if (before.Author.IsBot) +// return; +// +// if (!GuildLogSettings.TryGetValue(channel.Guild.Id, out var logSetting) +// || logSetting.MessageUpdatedId == null +// || logSetting.IgnoredChannels.Any(ilc => ilc.ChannelId == channel.Id)) +// { +// return; +// } +// +// ITextChannel logChannel; +// if ((logChannel = await TryGetLogChannel(channel.Guild, logSetting, LogType.MessageUpdated) +// .ConfigureAwait(false)) == null || logChannel.Id == after.Channel.Id) +// { +// return; +// } +// +// var embed = new EmbedBuilder() +// .WithOkColor() +// .WithTitle($"📝 {GetText(logChannel.Guild, "msg_update", ((ITextChannel)after.Channel).Name)}") +// .WithDescription(after.Author.ToString()) +// .AddField(efb => +// efb.WithName(GetText(logChannel.Guild, "old_msg")) +// .WithValue(string.IsNullOrWhiteSpace(before.Content) +// ? "-" +// : before.Resolve(TagHandling.FullName)).WithIsInline(false)) +// .AddField(efb => +// efb.WithName(GetText(logChannel.Guild, "new_msg")) +// .WithValue(string.IsNullOrWhiteSpace(after.Content) +// ? "-" +// : after.Resolve(TagHandling.FullName)).WithIsInline(false)) +// .AddField(efb => efb.WithName("Id").WithValue(after.Id.ToString()).WithIsInline(false)) +// .WithFooter(efb => efb.WithText(CurrentTime(channel.Guild))); +// +// await logChannel.EmbedAsync(embed).ConfigureAwait(false); +// } +// catch +// { +// // ignored +// } +// } +// +// private async Task TryGetLogChannel(IGuild guild, LogSetting logSetting, LogType logChannelType) +// { +// var id = logChannelType switch +// { +// LogType.Other => logSetting.LogOtherId, +// LogType.MessageUpdated => logSetting.MessageUpdatedId, +// LogType.MessageDeleted => logSetting.MessageDeletedId, +// LogType.UserJoined => logSetting.UserJoinedId, +// LogType.UserLeft => logSetting.UserLeftId, +// LogType.UserBanned => logSetting.UserBannedId, +// LogType.UserUnbanned => logSetting.UserUnbannedId, +// LogType.UserUpdated => logSetting.UserUpdatedId, +// LogType.ChannelCreated => logSetting.ChannelCreatedId, +// LogType.ChannelDestroyed => logSetting.ChannelDestroyedId, +// LogType.ChannelUpdated => logSetting.ChannelUpdatedId, +// LogType.VoicePresence => logSetting.LogVoicePresenceId, +// LogType.VoicePresenceTts => logSetting.LogVoicePresenceTTSId, +// LogType.UserMuted => logSetting.UserMutedId, +// _ => null +// }; +// +// if (id is null or 0) +// { +// UnsetLogSetting(guild.Id, logChannelType); +// return null; +// } +// +// var channel = await guild.GetTextChannelAsync(id.Value).ConfigureAwait(false); +// +// if (channel != null) return channel; +// UnsetLogSetting(guild.Id, logChannelType); +// return null; +// } +// +// private async void UnsetLogSetting(ulong guildId, LogType logChannelType) +// { +// await using var uow = db.GetDbContext(); +// var newLogSetting = (await uow.LogSettingsFor(guildId)).LogSetting; +// switch (logChannelType) +// { +// case LogType.Other: +// newLogSetting.LogOtherId = null; +// break; +// case LogType.MessageUpdated: +// newLogSetting.MessageUpdatedId = null; +// break; +// case LogType.MessageDeleted: +// newLogSetting.MessageDeletedId = null; +// break; +// case LogType.UserJoined: +// newLogSetting.UserJoinedId = null; +// break; +// case LogType.UserLeft: +// newLogSetting.UserLeftId = null; +// break; +// case LogType.UserBanned: +// newLogSetting.UserBannedId = null; +// break; +// case LogType.UserUnbanned: +// newLogSetting.UserUnbannedId = null; +// break; +// case LogType.UserUpdated: +// newLogSetting.UserUpdatedId = null; +// break; +// case LogType.UserMuted: +// newLogSetting.UserMutedId = null; +// break; +// case LogType.ChannelCreated: +// newLogSetting.ChannelCreatedId = null; +// break; +// case LogType.ChannelDestroyed: +// newLogSetting.ChannelDestroyedId = null; +// break; +// case LogType.ChannelUpdated: +// newLogSetting.ChannelUpdatedId = null; +// break; +// case LogType.VoicePresence: +// newLogSetting.LogVoicePresenceId = null; +// break; +// case LogType.VoicePresenceTts: +// newLogSetting.LogVoicePresenceTTSId = null; +// break; +// } +// +// GuildLogSettings.AddOrUpdate(guildId, newLogSetting, (_, _) => newLogSetting); +// await uow.SaveChangesAsync(); +// } +// } -namespace Mewdeko.Modules.Administration.Services; - -public class LogCommandService : INService -{ - public enum LogType - { - Other, - EventCreated, - RoleUpdated, - RoleCreated, - RoleDeleted, - ServerUpdated, - ThreadCreated, - UserRoleAdded, - UserRoleRemoved, - UsernameUpdated, - NicknameUpdated, - ThreadDeleted, - ThreadUpdated, - MessageUpdated, - MessageDeleted, - UserJoined, - UserLeft, - UserBanned, - UserUnbanned, - UserUpdated, - ChannelCreated, - ChannelDestroyed, - ChannelUpdated, - VoicePresence, - VoicePresenceTts, - UserMuted - } - - public enum LogCategoryTypes - { - All, - Users, - Threads, - Roles, - Server, - Channel, - Messages, - Moderation, - None - } - - private readonly DiscordSocketClient client; - private readonly DbService db; - private readonly ConcurrentHashSet ignoreMessageIds = new(); - private readonly IMemoryCache memoryCache; - private readonly IBotStrings strings; - private readonly Mewdeko bot; - private readonly GuildSettingsService gss; - - private readonly GuildTimezoneService tz; - - public readonly Timer ClearTimer; - - public LogCommandService(DiscordSocketClient client, IBotStrings strings, - DbService db, MuteService mute, ProtectionService prot, GuildTimezoneService tz, - IMemoryCache memoryCache, Mewdeko bot, EventHandler eventHandler, GuildSettingsService gss) - { - this.bot = bot; - this.gss = gss; - this.client = client; - this.memoryCache = memoryCache; - this.strings = strings; - this.db = db; - this.tz = tz; - - var allgc = bot.AllGuildConfigs; - GuildLogSettings = allgc - .ToDictionary(g => g.GuildId, g => g.LogSetting) - .ToConcurrent(); - - //_client.MessageReceived += Client_MessageReceived; - eventHandler.MessageUpdated += Client_MessageUpdated; - eventHandler.MessageDeleted += Client_MessageDeleted; - eventHandler.MessagesBulkDeleted += Client_BulkDelete; - eventHandler.UserBanned += Client_UserBanned; - eventHandler.UserUnbanned += Client_UserUnbanned; - eventHandler.UserJoined += Client_UserJoined; - eventHandler.UserLeft += Client_UserLeft; - eventHandler.UserVoiceStateUpdated += Client_UserVoiceStateUpdated; - eventHandler.UserVoiceStateUpdated += Client_UserVoiceStateUpdated_TTS; - eventHandler.GuildMemberUpdated += Client_GuildUserUpdated; -#if !GLOBAL_Mewdeko - eventHandler.UserUpdated += Client_UserUpdated; -#endif - eventHandler.ChannelCreated += Client_ChannelCreated; - eventHandler.ChannelDestroyed += Client_ChannelDestroyed; - eventHandler.ChannelUpdated += Client_ChannelUpdated; - eventHandler.RoleDeleted += Client_RoleDeleted; - - mute.UserMuted += MuteCommands_UserMuted; - mute.UserUnmuted += MuteCommands_UserUnmuted; - //_client.ThreadCreated += ThreadCreated; - prot.OnAntiProtectionTriggered += TriggeredAntiProtection; - - ClearTimer = new Timer(_ => ignoreMessageIds.Clear(), null, TimeSpan.FromHours(1), - TimeSpan.FromHours(1)); - } - - public ConcurrentDictionary GuildLogSettings { get; } - - public void AddDeleteIgnore(ulong messageId) => ignoreMessageIds.Add(messageId); - - public async Task LogIgnore(ulong gid, ulong cid) - { - int removed; - await using var uow = db.GetDbContext(); - var config = await uow.LogSettingsFor(gid); - var logSetting = GuildLogSettings.GetOrAdd(gid, _ => config.LogSetting); - removed = logSetting.IgnoredChannels.RemoveWhere(ilc => ilc.ChannelId == cid); - config.LogSetting.IgnoredChannels.RemoveWhere(ilc => ilc.ChannelId == cid); - if (removed == 0) - { - var toAdd = new IgnoredLogChannel - { - ChannelId = cid - }; - logSetting.IgnoredChannels.Add(toAdd); - config.LogSetting.IgnoredChannels.Add(toAdd); - } - - await uow.SaveChangesAsync(); - - return removed > 0; - } - - private string GetText(IGuild guild, string key, params object[] replacements) => - strings.GetText(key, guild.Id, replacements); - - private string CurrentTime(IGuild? g) - { - var time = DateTime.UtcNow; - if (g != null) - time = TimeZoneInfo.ConvertTime(time, tz.GetTimeZoneOrUtc(g.Id)); - - return $"{time:HH:mm:ss}"; - } - - public async Task SetLogChannel(ulong guildId, ulong channelId, LogType type) - { - await using var uow = db.GetDbContext(); - var logSetting = (await uow.LogSettingsFor(guildId)).LogSetting; - switch (type) - { - case LogType.Other: - logSetting.LogOtherId = channelId; - break; - case LogType.EventCreated: - logSetting.EventCreatedId = channelId; - break; - case LogType.RoleUpdated: - logSetting.RoleUpdatedId = channelId; - break; - case LogType.RoleCreated: - logSetting.RoleCreatedId = channelId; - break; - case LogType.ServerUpdated: - logSetting.ServerUpdatedId = channelId; - break; - case LogType.ThreadCreated: - logSetting.ThreadCreatedId = channelId; - break; - case LogType.UserRoleAdded: - logSetting.UserRoleAddedId = channelId; - break; - case LogType.UserRoleRemoved: - logSetting.UserRoleRemovedId = channelId; - break; - case LogType.UsernameUpdated: - logSetting.UsernameUpdatedId = channelId; - break; - case LogType.NicknameUpdated: - logSetting.NicknameUpdatedId = channelId; - break; - case LogType.ThreadDeleted: - logSetting.ThreadDeletedId = channelId; - break; - case LogType.ThreadUpdated: - logSetting.ThreadUpdatedId = channelId; - break; - case LogType.MessageUpdated: - logSetting.MessageUpdatedId = channelId; - break; - case LogType.MessageDeleted: - logSetting.MessageDeletedId = channelId; - break; - case LogType.UserJoined: - logSetting.UserJoinedId = channelId; - break; - case LogType.UserLeft: - logSetting.UserLeftId = channelId; - break; - case LogType.UserBanned: - logSetting.UserBannedId = channelId; - break; - case LogType.UserUnbanned: - logSetting.UserUnbannedId = channelId; - break; - case LogType.UserUpdated: - logSetting.UserUpdatedId = channelId; - break; - case LogType.ChannelCreated: - logSetting.ChannelCreatedId = channelId; - break; - case LogType.ChannelDestroyed: - logSetting.ChannelDestroyedId = channelId; - break; - case LogType.ChannelUpdated: - logSetting.ChannelUpdatedId = channelId; - break; - case LogType.VoicePresence: - logSetting.LogVoicePresenceId = channelId; - break; - case LogType.VoicePresenceTts: - logSetting.LogVoicePresenceTTSId = channelId; - break; - case LogType.UserMuted: - logSetting.UserMutedId = channelId; - break; - } - - uow.LogSettings.Update(logSetting); - await uow.SaveChangesAsync(); - GuildLogSettings.AddOrUpdate(guildId, _ => logSetting, (_, _) => logSetting); - } - - public async Task LogSetByType(ulong guildId, ulong channelId, LogCategoryTypes categoryTypes) - { - await using var uow = db.GetDbContext(); - var logSetting = (await uow.LogSettingsFor(guildId)).LogSetting; - switch (categoryTypes) - { - case LogCategoryTypes.All: - logSetting.AvatarUpdatedId = channelId; - logSetting.ChannelCreatedId = channelId; - logSetting.ChannelDestroyedId = channelId; - logSetting.ChannelUpdatedId = channelId; - logSetting.EventCreatedId = channelId; - logSetting.LogOtherId = channelId; - logSetting.MessageDeletedId = channelId; - logSetting.MessageUpdatedId = channelId; - logSetting.NicknameUpdatedId = channelId; - logSetting.RoleCreatedId = channelId; - logSetting.RoleDeletedId = channelId; - logSetting.RoleUpdatedId = channelId; - logSetting.ServerUpdatedId = channelId; - logSetting.ThreadCreatedId = channelId; - logSetting.ThreadDeletedId = channelId; - logSetting.ThreadUpdatedId = channelId; - logSetting.UserBannedId = channelId; - logSetting.UserJoinedId = channelId; - logSetting.UserLeftId = channelId; - logSetting.UserMutedId = channelId; - logSetting.UsernameUpdatedId = channelId; - logSetting.UserUnbannedId = channelId; - logSetting.UserUpdatedId = channelId; - logSetting.LogUserPresenceId = channelId; - logSetting.LogVoicePresenceId = channelId; - logSetting.UserRoleAddedId = channelId; - logSetting.UserRoleRemovedId = channelId; - logSetting.LogVoicePresenceTTSId = channelId; - break; - case LogCategoryTypes.Users: - logSetting.NicknameUpdatedId = channelId; - logSetting.AvatarUpdatedId = channelId; - logSetting.UsernameUpdatedId = channelId; - logSetting.UserRoleAddedId = channelId; - logSetting.UserRoleRemovedId = channelId; - logSetting.LogVoicePresenceId = channelId; - break; - case LogCategoryTypes.Threads: - logSetting.ThreadCreatedId = channelId; - logSetting.ThreadDeletedId = channelId; - logSetting.ThreadUpdatedId = channelId; - break; - case LogCategoryTypes.Roles: - logSetting.RoleCreatedId = channelId; - logSetting.RoleDeletedId = channelId; - logSetting.RoleUpdatedId = channelId; - break; - case LogCategoryTypes.Server: - logSetting.ServerUpdatedId = channelId; - logSetting.EventCreatedId = channelId; - break; - case LogCategoryTypes.Channel: - logSetting.ChannelUpdatedId = channelId; - logSetting.ChannelCreatedId = channelId; - logSetting.ChannelDestroyedId = channelId; - break; - case LogCategoryTypes.Messages: - logSetting.MessageDeletedId = channelId; - logSetting.MessageUpdatedId = channelId; - break; - case LogCategoryTypes.Moderation: - logSetting.UserMutedId = channelId; - logSetting.UserBannedId = channelId; - logSetting.UserUnbannedId = channelId; - break; - case LogCategoryTypes.None: - logSetting.AvatarUpdatedId = 0; - logSetting.ChannelCreatedId = 0; - logSetting.ChannelDestroyedId = 0; - logSetting.ChannelUpdatedId = 0; - logSetting.EventCreatedId = 0; - logSetting.LogOtherId = 0; - logSetting.MessageDeletedId = 0; - logSetting.MessageUpdatedId = 0; - logSetting.NicknameUpdatedId = 0; - logSetting.RoleCreatedId = 0; - logSetting.RoleDeletedId = 0; - logSetting.RoleUpdatedId = 0; - logSetting.ServerUpdatedId = 0; - logSetting.ThreadCreatedId = 0; - logSetting.ThreadDeletedId = 0; - logSetting.ThreadUpdatedId = 0; - logSetting.UserBannedId = 0; - logSetting.UserJoinedId = 0; - logSetting.UserLeftId = 0; - logSetting.UserMutedId = 0; - logSetting.UsernameUpdatedId = 0; - logSetting.UserUnbannedId = 0; - logSetting.UserUpdatedId = 0; - logSetting.LogUserPresenceId = 0; - logSetting.LogVoicePresenceId = 0; - logSetting.UserRoleAddedId = 0; - logSetting.UserRoleRemovedId = 0; - logSetting.LogVoicePresenceTTSId = 0; - break; - } - - uow.LogSettings.Update(logSetting); - await uow.SaveChangesAsync(); - GuildLogSettings.AddOrUpdate(guildId, _ => logSetting, (_, _) => logSetting); - } - - private async Task Client_UserUpdated(SocketUser before, SocketUser uAfter) - { - try - { - await using var uow = db.GetDbContext(); - if (uAfter is not SocketGuildUser guildUser) - return; - - var g = guildUser.Guild; - - if (!GuildLogSettings.TryGetValue(g.Id, out var logSetting) - || logSetting.UserUpdatedId == null && logSetting.NicknameUpdatedId == null && - logSetting.UsernameUpdatedId == null && logSetting.AvatarUpdatedId == null) - { - return; - } - - ITextChannel logChannel; - if ((logChannel = - await TryGetLogChannel(g, logSetting, LogType.UserUpdated).ConfigureAwait(false)) == null) - { - return; - } - - var embeds = new List(); - - if (before.ToString() != guildUser.ToString()) - { - embeds.Add(new EmbedBuilder().WithTitle($"👥 {GetText(g, "username_changed")}") - .WithTitle($"{before.Username}#{before.Discriminator} | {before.Id}") - .WithDescription( - $"**Old Username**\n=> {before}\n**New Username**\n=> {guildUser}\n**Date Changed**\n=>{TimestampTag.FromDateTime(DateTime.UtcNow)}") - .WithOkColor().Build()); - } - else if (before.AvatarId != guildUser.AvatarId) - { - var bav = before.RealAvatarUrl(); - embeds.Add(new EmbedBuilder().WithTitle($"👥{GetText(g, "avatar_changed")}") - .WithDescription($"{before.Username}#{before.Discriminator} | {before.Id}") - .AddField("Old Avatar", "_ _") - .WithImageUrl(bav.ToString()) - .WithFooter(fb => fb.WithText(CurrentTime(g))) - .WithOkColor().Build()); - - var aav = guildUser.RealAvatarUrl(); - embeds.Add(new EmbedBuilder().AddField("New Avatar", "_ _").WithImageUrl(aav.ToString()).WithOkColor() - .Build()); - } - else - { - return; - } - - await logChannel.SendMessageAsync(embeds: embeds.ToArray()).ConfigureAwait(false); - } - catch - { - // ignored - } - } - - - public async Task UpdateCommandLogChannel(IGuild guild, ulong id) - { - await using var uow = db.GetDbContext(); - var gc = await uow.ForGuildId(guild.Id, set => set); - gc.CommandLogChannel = id; - await uow.SaveChangesAsync(); - await gss.UpdateGuildConfig(guild.Id, gc); - } - - private async Task Client_UserVoiceStateUpdated_TTS(SocketUser iusr, SocketVoiceState before, - SocketVoiceState after) - { - try - { - if (iusr is not IGuildUser usr) - return; - - var beforeVch = before.VoiceChannel; - var afterVch = after.VoiceChannel; - - if (beforeVch == afterVch) - return; - - if (!GuildLogSettings.TryGetValue(usr.Guild.Id, out var logSetting) - || logSetting.LogVoicePresenceTTSId == null) - { - return; - } - - ITextChannel logChannel; - if ((logChannel = await TryGetLogChannel(usr.Guild, logSetting, LogType.VoicePresenceTts) - .ConfigureAwait(false)) == null) - { - return; - } - - var str = ""; - if (beforeVch?.Guild == afterVch?.Guild) - str = GetText(logChannel.Guild, "log_vc_moved", usr.Username, beforeVch?.Name, afterVch?.Name); - else if (beforeVch == null) - str = GetText(logChannel.Guild, "log_vc_joined", usr.Username, afterVch.Name); - else if (afterVch == null) - str = GetText(logChannel.Guild, "log_vc_left", usr.Username, beforeVch.Name); - - var toDelete = await logChannel.SendMessageAsync(str, true).ConfigureAwait(false); - toDelete.DeleteAfter(5); - } - catch - { - // ignored - } - } - - private async Task MuteCommands_UserMuted(IGuildUser usr, IUser mod, MuteType muteType, string reason) - { - try - { - if (!GuildLogSettings.TryGetValue(usr.Guild.Id, out var logSetting) - || logSetting.UserMutedId == null) - { - return; - } - - ITextChannel logChannel; - if ((logChannel = await TryGetLogChannel(usr.Guild, logSetting, LogType.UserMuted) - .ConfigureAwait(false)) == null) - { - return; - } - - var mutes = ""; - var mutedLocalized = GetText(logChannel.Guild, "muted_sn"); - mutes = muteType switch - { - MuteType.Voice => $"🔇 {GetText(logChannel.Guild, "xmuted_voice", mutedLocalized, mod.ToString())}", - MuteType.Chat => $"🔇 {GetText(logChannel.Guild, "xmuted_text", mutedLocalized, mod.ToString())}", - MuteType.All => - $"🔇 {GetText(logChannel.Guild, "xmuted_text_and_voice", mutedLocalized, mod.ToString())}", - _ => mutes - }; - - var embed = new EmbedBuilder().WithAuthor(eab => eab.WithName(mutes)) - .WithTitle($"{usr.Username}#{usr.Discriminator} | {usr.Id}") - .WithFooter(fb => fb.WithText(CurrentTime(usr.Guild))) - .WithOkColor(); - - await logChannel.EmbedAsync(embed).ConfigureAwait(false); - } - catch - { - // ignored - } - } - - private async Task MuteCommands_UserUnmuted(IGuildUser usr, IUser mod, MuteType muteType, string reason) - { - try - { - if (!GuildLogSettings.TryGetValue(usr.Guild.Id, out var logSetting) - || logSetting.UserMutedId == null) - { - return; - } - - ITextChannel logChannel; - if ((logChannel = await TryGetLogChannel(usr.Guild, logSetting, LogType.UserMuted) - .ConfigureAwait(false)) == null) - { - return; - } - - var mutes = ""; - var unmutedLocalized = GetText(logChannel.Guild, "unmuted_sn"); - mutes = muteType switch - { - MuteType.Voice => - $"🔊 {GetText(logChannel.Guild, "xmuted_voice", unmutedLocalized, mod.ToString())}", - MuteType.Chat => $"🔊 {GetText(logChannel.Guild, "xmuted_text", unmutedLocalized, mod.ToString())}", - MuteType.All => - $"🔊 {GetText(logChannel.Guild, "xmuted_text_and_voice", unmutedLocalized, mod.ToString())}", - _ => mutes - }; - - var embed = new EmbedBuilder().WithAuthor(eab => eab.WithName(mutes)) - .WithTitle($"{usr.Username}#{usr.Discriminator} | {usr.Id}") - .WithFooter(fb => fb.WithText($"{CurrentTime(usr.Guild)}")) - .WithOkColor(); - - if (!string.IsNullOrWhiteSpace(reason)) - embed.WithDescription(reason); - - await logChannel.EmbedAsync(embed).ConfigureAwait(false); - } - catch - { - // ignored - } - } - - private async Task TriggeredAntiProtection(PunishmentAction action, ProtectionType protection, - params IGuildUser[] users) - { - try - { - if (users.Length == 0) - return; - - if (!GuildLogSettings.TryGetValue(users.First().Guild.Id, out var logSetting) - || logSetting.LogOtherId == null) - { - return; - } - - ITextChannel logChannel; - if ((logChannel = await TryGetLogChannel(users.First().Guild, logSetting, LogType.Other) - .ConfigureAwait(false)) == null) - { - return; - } - - var punishment = ""; - switch (action) - { - case PunishmentAction.Mute: - punishment = $"🔇 {GetText(logChannel.Guild, "muted_pl").ToUpperInvariant()}"; - break; - case PunishmentAction.Kick: - punishment = $"👢 {GetText(logChannel.Guild, "kicked_pl").ToUpperInvariant()}"; - break; - case PunishmentAction.Softban: - punishment = $"☣ {GetText(logChannel.Guild, "soft_banned_pl").ToUpperInvariant()}"; - break; - case PunishmentAction.Ban: - punishment = $"⛔️ {GetText(logChannel.Guild, "banned_pl").ToUpperInvariant()}"; - break; - case PunishmentAction.RemoveRoles: - punishment = $"⛔️ {GetText(logChannel.Guild, "remove_roles_pl").ToUpperInvariant()}"; - break; - case PunishmentAction.ChatMute: - break; - case PunishmentAction.VoiceMute: - break; - case PunishmentAction.AddRole: - break; - default: - throw new ArgumentOutOfRangeException(nameof(action), action, null); - } - - var embed = new EmbedBuilder().WithAuthor(eab => eab.WithName($"🛡 Anti-{protection}")) - .WithTitle($"{GetText(logChannel.Guild, "users")} {punishment}") - .WithDescription(string.Join("\n", users.Select(u => u.ToString()))) - .WithFooter(fb => fb.WithText(CurrentTime(logChannel.Guild))) - .WithOkColor(); - - await logChannel.EmbedAsync(embed).ConfigureAwait(false); - } - catch - { - // ignored - } - } - - private static string GetRoleDeletedKey(ulong roleId) => $"role_deleted_{roleId}"; - - private Task Client_RoleDeleted(SocketRole socketRole) - { -#if DEBUG - Serilog.Log.Information("Role deleted {RoleId}", socketRole.Id); -#endif - memoryCache.Set(GetRoleDeletedKey(socketRole.Id), true, TimeSpan.FromMinutes(5)); - return Task.CompletedTask; - } - - private bool IsRoleDeleted(ulong roleId) - => memoryCache.TryGetValue(GetRoleDeletedKey(roleId), out _); - - private async Task Client_GuildUserUpdated(Cacheable cacheable, SocketGuildUser? after) - { - try - { - if (!bot.Ready.Task.IsCompleted) - return; - - if (!cacheable.HasValue) - return; - - if (after is null) - return; - - if (!GuildLogSettings.TryGetValue(cacheable.Value.Guild.Id, out var logSetting)) - return; - - ITextChannel logChannel; - if (logSetting.UserUpdatedId != null && - (logChannel = await TryGetLogChannel(cacheable.Value.Guild, logSetting, LogType.UserUpdated) - .ConfigureAwait(false)) != null) - { - var embed = new EmbedBuilder().WithOkColor() - .WithTitle($"{cacheable.Value.Username}#{cacheable.Value.Discriminator} | {cacheable.Id}"); - if (cacheable.Value.Nickname != after.Nickname) - { - var logChannel1 = logChannel; - embed.WithAuthor(eab => eab.WithName($"👥 {GetText(logChannel1.Guild, "nick_change")}")) - .WithDescription( - $"**Old Nickname**\n=> {cacheable.Value.Nickname ?? cacheable.Value.Username}\n**New Nickname**\n=> {after.Nickname ?? after.Username}\n**Changed On**\n=>{TimestampTag.FromDateTime(DateTime.UtcNow)}"); - - await logChannel.EmbedAsync(embed).ConfigureAwait(false); - } - else if (!cacheable.Value.Roles.SequenceEqual(after.Roles)) - { - if (cacheable.Value.Roles.Count < after.Roles.Count) - { - var diffRoles = after.Roles.Where(r => !cacheable.Value.Roles.Contains(r)) - .Select(r => r.Name); - var channel = logChannel; - embed.WithAuthor(eab => eab.WithName($"⚔ {GetText(channel.Guild, "user_role_add")}")) - .WithDescription(string.Join(", ", diffRoles)); - - await logChannel.EmbedAsync(embed).ConfigureAwait(false); - } - else if (cacheable.Value.Roles.Count > after.Roles.Count) - { - await Task.Delay(1000).ConfigureAwait(false); - var diffRoles = cacheable.Value.Roles - .Where(r => !after.Roles.Contains(r) && !IsRoleDeleted(r.Id)) - .Select(r => r.Name) - .ToList(); - - if (diffRoles.Count > 0) - { - var channel = logChannel; - embed.WithAuthor(eab => - eab.WithName($"⚔ {GetText(channel.Guild, "user_role_rem")}")) - .WithDescription(string.Join(", ", diffRoles).SanitizeMentions()); - - await logChannel.EmbedAsync(embed).ConfigureAwait(false); - } - } - } - } - } - catch - { - // ignored - } - } - - private async Task Client_ChannelUpdated(IChannel cbefore, IChannel cafter) - { - try - { - if (cbefore is not IGuildChannel before) - return; - - var after = (IGuildChannel)cafter; - - if (!GuildLogSettings.TryGetValue(before.Guild.Id, out var logSetting) - || logSetting.ChannelUpdatedId == null - || logSetting.IgnoredChannels.Any(ilc => ilc.ChannelId == after.Id)) - { - return; - } - - ITextChannel logChannel; - if ((logChannel = await TryGetLogChannel(before.Guild, logSetting, LogType.ChannelUpdated) - .ConfigureAwait(false)) == null) - { - return; - } - - var embed = new EmbedBuilder().WithOkColor() - .WithFooter(efb => efb.WithText(CurrentTime(before.Guild))); - - var beforeTextChannel = cbefore as ITextChannel; - var afterTextChannel = cafter as ITextChannel; - - if (before.Name != after.Name) - { - embed.WithTitle($"ℹ️ {GetText(logChannel.Guild, "ch_name_change")}") - .WithDescription($"{after} | {after.Id}") - .AddField(efb => - efb.WithName(GetText(logChannel.Guild, "ch_old_name")).WithValue(before.Name)); - } - else if (beforeTextChannel?.Topic != afterTextChannel?.Topic) - { - embed.WithTitle($"ℹ️ {GetText(logChannel.Guild, "ch_topic_change")}") - .WithDescription($"{after} | {after.Id}") - .AddField(efb => - efb.WithName(GetText(logChannel.Guild, "old_topic")) - .WithValue(beforeTextChannel?.Topic ?? "-")) - .AddField(efb => - efb.WithName(GetText(logChannel.Guild, "new_topic")) - .WithValue(afterTextChannel?.Topic ?? "-")); - } - else - { - return; - } - - await logChannel.EmbedAsync(embed).ConfigureAwait(false); - } - catch - { - // ignored - } - } - - private async Task Client_ChannelDestroyed(IChannel ich) - { - try - { - if (ich is not IGuildChannel ch) - return; - - if (!GuildLogSettings.TryGetValue(ch.Guild.Id, out var logSetting) - || logSetting.ChannelDestroyedId == null - || logSetting.IgnoredChannels.Any(ilc => ilc.ChannelId == ch.Id)) - { - return; - } - - ITextChannel logChannel; - if ((logChannel = await TryGetLogChannel(ch.Guild, logSetting, LogType.ChannelDestroyed) - .ConfigureAwait(false)) == null) - { - return; - } - - var title = GetText(logChannel.Guild, ch is IVoiceChannel ? "voice_chan_destroyed" : "text_chan_destroyed"); - - var audits = await ch.Guild.GetAuditLogsAsync().ConfigureAwait(false); - var e = audits.FirstOrDefault(x => x.Action == ActionType.ChannelDeleted); - await logChannel.EmbedAsync(new EmbedBuilder() - .WithOkColor() - .WithTitle($"🆕 {title}") - .WithDescription($"{ch.Name} | {ch.Id}") - .AddField("Yeeted By", e?.User) - .WithFooter(efb => efb.WithText(CurrentTime(ch.Guild)))).ConfigureAwait(false); - } - catch - { - // ignored - } - } - - private async Task Client_ChannelCreated(IChannel ich) - { - try - { - if (ich is not IGuildChannel ch) - return; - - if (!GuildLogSettings.TryGetValue(ch.Guild.Id, out var logSetting) - || logSetting.ChannelCreatedId == null) - { - return; - } - - ITextChannel logChannel; - if ((logChannel = await TryGetLogChannel(ch.Guild, logSetting, LogType.ChannelCreated) - .ConfigureAwait(false)) == null) - { - return; - } - - var title = GetText(logChannel.Guild, ch is IVoiceChannel ? "voice_chan_created" : "text_chan_created"); - - await logChannel.EmbedAsync(new EmbedBuilder() - .WithOkColor() - .WithTitle($"🆕 {title}") - .WithDescription($"{ch.Name} | {ch.Id}") - .WithFooter(efb => efb.WithText(CurrentTime(ch.Guild)))).ConfigureAwait(false); - } - catch (Exception) - { - // ignored - } - } - - private async Task Client_UserVoiceStateUpdated(SocketUser iusr, SocketVoiceState before, SocketVoiceState after) - { - try - { - if (iusr is not IGuildUser usr) - return; - - var beforeVch = before.VoiceChannel; - var afterVch = after.VoiceChannel; - - if (beforeVch == afterVch) - return; - - if (!GuildLogSettings.TryGetValue(usr.Guild.Id, out var logSetting) - || logSetting.LogVoicePresenceId == null) - { - return; - } - - ITextChannel logChannel; - if ((logChannel = await TryGetLogChannel(usr.Guild, logSetting, LogType.VoicePresence) - .ConfigureAwait(false)) == null) - { - return; - } - - var str = ""; - if (beforeVch?.Guild == afterVch?.Guild) - str = GetText(logChannel.Guild, "log_vc_moved", usr.Username, beforeVch?.Name, afterVch?.Name); - else if (beforeVch == null) - str = GetText(logChannel.Guild, "log_vc_joined", usr.Username, afterVch.Name); - else if (afterVch == null) - str = GetText(logChannel.Guild, "log_vc_left", usr.Username, beforeVch.Name); - - await logChannel.SendConfirmAsync(str).ConfigureAwait(false); - } - catch - { - // ignored - } - } - - private async Task Client_UserLeft(IGuild args, IUser arsg2) - { - try - { - if (arsg2 is not SocketGuildUser usr) return; - if (!GuildLogSettings.TryGetValue(args.Id, out var logSetting) - || logSetting.UserLeftId == null) - { - return; - } - - ITextChannel logChannel; - if ((logChannel = await TryGetLogChannel(args, logSetting, LogType.UserLeft) - .ConfigureAwait(false)) == null) - { - return; - } - - var embed = new EmbedBuilder() - .WithOkColor() - .WithTitle($"❌ {GetText(logChannel.Guild, "user_left")}") - .WithDescription(usr.ToString()) - .AddField(efb => efb.WithName("Id").WithValue(usr.Id.ToString())) - .AddField("Roles", string.Join("|", usr.GetRoles().Select(x => x.Mention))) - .AddField("Time Stayed:", (usr.JoinedAt - DateTime.Now).Value.Humanize()) - .WithFooter(efb => efb.WithText(CurrentTime(usr.Guild))); - - if (Uri.IsWellFormedUriString(usr.GetAvatarUrl(), UriKind.Absolute)) - embed.WithThumbnailUrl(usr.GetAvatarUrl()); - - await logChannel.EmbedAsync(embed).ConfigureAwait(false); - } - catch - { - // ignored - } - } - - private async Task Client_UserJoined(IGuildUser usr) - { - try - { - if (!GuildLogSettings.TryGetValue(usr.Guild.Id, out var logSetting) - || logSetting.UserJoinedId == null) - { - return; - } - - ITextChannel logChannel; - if ((logChannel = await TryGetLogChannel(usr.Guild, logSetting, LogType.UserJoined) - .ConfigureAwait(false)) == null) - { - return; - } - - var embed = new EmbedBuilder() - .WithOkColor() - .WithTitle($"✅ {GetText(logChannel.Guild, "user_joined")}") - .WithDescription($"{usr.Mention} `{usr}`") - .AddField(efb => efb.WithName("Id").WithValue(usr.Id.ToString())) - .AddField(fb => - fb.WithName(GetText(logChannel.Guild, "joined_server")) - .WithValue($"{usr.JoinedAt?.ToString("dd.MM.yyyy HH:mm") ?? "?"}").WithIsInline(true)) - .AddField(fb => - fb.WithName(GetText(logChannel.Guild, "joined_discord")) - .WithValue($"{usr.CreatedAt:dd.MM.yyyy HH:mm}").WithIsInline(true)) - .WithFooter(efb => efb.WithText(CurrentTime(usr.Guild))); - - if (Uri.IsWellFormedUriString(usr.GetAvatarUrl(), UriKind.Absolute)) - embed.WithThumbnailUrl(usr.GetAvatarUrl()); - - await logChannel.EmbedAsync(embed).ConfigureAwait(false); - } - catch (Exception) - { - // ignored - } - } - - private async Task Client_UserUnbanned(IUser usr, IGuild guild) - { - try - { - if (!GuildLogSettings.TryGetValue(guild.Id, out var logSetting) - || logSetting.UserUnbannedId == null) - { - return; - } - - var unbannedby = (await guild.GetAuditLogsAsync(actionType: ActionType.Unban)).FirstOrDefault(); - ITextChannel logChannel; - if ((logChannel = await TryGetLogChannel(guild, logSetting, LogType.UserUnbanned) - .ConfigureAwait(false)) == null) - { - return; - } - - var embed = new EmbedBuilder() - .WithOkColor() - .WithTitle($"♻️ {GetText(logChannel.Guild, "user_unbanned")}") - .WithDescription(usr.ToString()) - .AddField(efb => efb.WithName("Id").WithValue(usr.Id.ToString())) - .WithFooter(efb => efb.WithText(CurrentTime(guild))); - - if (unbannedby != null) - { - embed - .AddField("Unbanned by", unbannedby.User) - .AddField("Reason", unbannedby.Reason ?? "None"); - } - - if (Uri.IsWellFormedUriString(usr.GetAvatarUrl(), UriKind.Absolute)) - embed.WithThumbnailUrl(usr.GetAvatarUrl()); - - await logChannel.EmbedAsync(embed).ConfigureAwait(false); - } - catch (Exception) - { - // ignored - } - } - - private async Task Client_UserBanned(IUser usr, IGuild guild) - { - try - { - if (!GuildLogSettings.TryGetValue(guild.Id, out var logSetting) - || logSetting.UserBannedId == null) - { - return; - } - - var bannedby = (await guild.GetAuditLogsAsync(actionType: ActionType.Ban)).FirstOrDefault(); - ITextChannel logChannel; - if ((logChannel = - await TryGetLogChannel(guild, logSetting, LogType.UserBanned).ConfigureAwait(false)) == - null) - { - return; - } - - var embed = new EmbedBuilder() - .WithOkColor() - .WithTitle($"🚫 {GetText(logChannel.Guild, "user_banned")}") - .WithDescription(usr.ToString()); - - if (bannedby != null) - { - embed - .AddField("Banned by", bannedby.User) - .AddField("Reason", bannedby.Reason ?? "None"); - } - - embed.AddField(efb => efb.WithName("Id").WithValue(usr.Id.ToString())) - .WithFooter(efb => efb.WithText(CurrentTime(guild))); - - var avatarUrl = usr.GetAvatarUrl(); - - if (Uri.IsWellFormedUriString(avatarUrl, UriKind.Absolute)) - embed.WithThumbnailUrl(usr.GetAvatarUrl()); - - await logChannel.EmbedAsync(embed).ConfigureAwait(false); - } - catch (Exception) - { - // ignored - } - } - - private async Task Client_BulkDelete(IReadOnlyCollection> messages, - Cacheable channel) - { - if (channel.Value is not ITextChannel chan) - return; - - if (!GuildLogSettings.TryGetValue(chan.Guild.Id, out var logSetting) - || logSetting.MessageDeletedId == null - || logSetting.IgnoredChannels.Any(ilc => ilc.ChannelId == channel.Id)) - { - return; - } - - ITextChannel logChannel; - if ((logChannel = await TryGetLogChannel(chan.Guild, logSetting, LogType.MessageDeleted) - .ConfigureAwait(false)) == null) - { - return; - } - - var toSend = new List(); - foreach (var message in messages) - { - if ((message.HasValue ? message.Value : null) is IUserMessage msg && !msg.IsAuthor(client) && - !ignoreMessageIds.Contains(msg.Id)) - { - toSend.Add(msg); - } - } - - var count = toSend.Count; - - if (count == 1) - return; - - for (var i = 0; i < toSend.Count; i += 100) - { - var toBatch = toSend.Skip(i).Take(100); - foreach (var group in toBatch.Chunk(20)) - { - var eb = new EmbedBuilder().WithOkColor(); - eb.WithTitle($"🗑 {count} Messages bulk deleted in {channel.Value.Name}"); - eb.WithDescription(string.Join("\n", - group.Select(x => $"{x.Author}: {x.Content}".Truncate(202)))); - await logChannel.SendMessageAsync(embed: eb.Build()).ConfigureAwait(false); - } - - await Task.Delay(1000).ConfigureAwait(false); - } - } - - - private async Task Client_MessageDeleted(Cacheable optMsg, Cacheable ch) - { - try - { - if ((optMsg.HasValue ? optMsg.Value : null) is not IUserMessage msg || msg.IsAuthor(client)) - return; - - if (ignoreMessageIds.Contains(msg.Id)) - return; - - if (ch.Value is not ITextChannel channel) - return; - - if (!GuildLogSettings.TryGetValue(channel.Guild.Id, out var logSetting) - || logSetting.MessageDeletedId == null - || logSetting.IgnoredChannels.Any(ilc => ilc.ChannelId == channel.Id)) - { - return; - } - - ITextChannel logChannel; - if ((logChannel = await TryGetLogChannel(channel.Guild, logSetting, LogType.MessageDeleted) - .ConfigureAwait(false)) == null || logChannel.Id == msg.Id) - { - return; - } - - var resolvedMessage = msg.Resolve(TagHandling.FullName); - var embed = new EmbedBuilder() - .WithOkColor() - .WithTitle($"🗑 {GetText(logChannel.Guild, "msg_del", ((ITextChannel)msg.Channel).Name)}") - .WithDescription(msg.Author.ToString()) - .AddField(efb => - efb.WithName(GetText(logChannel.Guild, "content")) - .WithValue(string.IsNullOrWhiteSpace(resolvedMessage) ? "-" : resolvedMessage) - .WithIsInline(false)) - .AddField(efb => efb.WithName("Id").WithValue(msg.Id.ToString()).WithIsInline(false)) - .WithFooter(efb => efb.WithText(CurrentTime(channel.Guild))); - if (msg.Attachments.Count > 0) - { - embed.AddField(efb => - efb.WithName(GetText(logChannel.Guild, "attachments")) - .WithValue(string.Join(", ", msg.Attachments.Select(a => a.Url))).WithIsInline(false)); - } - - await logChannel.EmbedAsync(embed).ConfigureAwait(false); - } - catch (Exception) - { - // ignored - } - } - - private async Task Client_MessageUpdated(Cacheable optmsg, SocketMessage imsg2, - ISocketMessageChannel ch) - { - try - { - if (imsg2 is not IUserMessage after || after.IsAuthor(client)) - return; - - if ((optmsg.HasValue ? optmsg.Value : null) is not IUserMessage before) - return; - - if (ch is not ITextChannel channel) - return; - - if (before.Content == after.Content) - return; - - if (before.Author.IsBot) - return; - - if (!GuildLogSettings.TryGetValue(channel.Guild.Id, out var logSetting) - || logSetting.MessageUpdatedId == null - || logSetting.IgnoredChannels.Any(ilc => ilc.ChannelId == channel.Id)) - { - return; - } - - ITextChannel logChannel; - if ((logChannel = await TryGetLogChannel(channel.Guild, logSetting, LogType.MessageUpdated) - .ConfigureAwait(false)) == null || logChannel.Id == after.Channel.Id) - { - return; - } - - var embed = new EmbedBuilder() - .WithOkColor() - .WithTitle($"📝 {GetText(logChannel.Guild, "msg_update", ((ITextChannel)after.Channel).Name)}") - .WithDescription(after.Author.ToString()) - .AddField(efb => - efb.WithName(GetText(logChannel.Guild, "old_msg")) - .WithValue(string.IsNullOrWhiteSpace(before.Content) - ? "-" - : before.Resolve(TagHandling.FullName)).WithIsInline(false)) - .AddField(efb => - efb.WithName(GetText(logChannel.Guild, "new_msg")) - .WithValue(string.IsNullOrWhiteSpace(after.Content) - ? "-" - : after.Resolve(TagHandling.FullName)).WithIsInline(false)) - .AddField(efb => efb.WithName("Id").WithValue(after.Id.ToString()).WithIsInline(false)) - .WithFooter(efb => efb.WithText(CurrentTime(channel.Guild))); - - await logChannel.EmbedAsync(embed).ConfigureAwait(false); - } - catch - { - // ignored - } - } - - private async Task TryGetLogChannel(IGuild guild, LogSetting logSetting, LogType logChannelType) - { - var id = logChannelType switch - { - LogType.Other => logSetting.LogOtherId, - LogType.MessageUpdated => logSetting.MessageUpdatedId, - LogType.MessageDeleted => logSetting.MessageDeletedId, - LogType.UserJoined => logSetting.UserJoinedId, - LogType.UserLeft => logSetting.UserLeftId, - LogType.UserBanned => logSetting.UserBannedId, - LogType.UserUnbanned => logSetting.UserUnbannedId, - LogType.UserUpdated => logSetting.UserUpdatedId, - LogType.ChannelCreated => logSetting.ChannelCreatedId, - LogType.ChannelDestroyed => logSetting.ChannelDestroyedId, - LogType.ChannelUpdated => logSetting.ChannelUpdatedId, - LogType.VoicePresence => logSetting.LogVoicePresenceId, - LogType.VoicePresenceTts => logSetting.LogVoicePresenceTTSId, - LogType.UserMuted => logSetting.UserMutedId, - _ => null - }; - - if (id is null or 0) - { - UnsetLogSetting(guild.Id, logChannelType); - return null; - } - - var channel = await guild.GetTextChannelAsync(id.Value).ConfigureAwait(false); - - if (channel != null) return channel; - UnsetLogSetting(guild.Id, logChannelType); - return null; - } - - private async void UnsetLogSetting(ulong guildId, LogType logChannelType) - { - await using var uow = db.GetDbContext(); - var newLogSetting = (await uow.LogSettingsFor(guildId)).LogSetting; - switch (logChannelType) - { - case LogType.Other: - newLogSetting.LogOtherId = null; - break; - case LogType.MessageUpdated: - newLogSetting.MessageUpdatedId = null; - break; - case LogType.MessageDeleted: - newLogSetting.MessageDeletedId = null; - break; - case LogType.UserJoined: - newLogSetting.UserJoinedId = null; - break; - case LogType.UserLeft: - newLogSetting.UserLeftId = null; - break; - case LogType.UserBanned: - newLogSetting.UserBannedId = null; - break; - case LogType.UserUnbanned: - newLogSetting.UserUnbannedId = null; - break; - case LogType.UserUpdated: - newLogSetting.UserUpdatedId = null; - break; - case LogType.UserMuted: - newLogSetting.UserMutedId = null; - break; - case LogType.ChannelCreated: - newLogSetting.ChannelCreatedId = null; - break; - case LogType.ChannelDestroyed: - newLogSetting.ChannelDestroyedId = null; - break; - case LogType.ChannelUpdated: - newLogSetting.ChannelUpdatedId = null; - break; - case LogType.VoicePresence: - newLogSetting.LogVoicePresenceId = null; - break; - case LogType.VoicePresenceTts: - newLogSetting.LogVoicePresenceTTSId = null; - break; - } - - GuildLogSettings.AddOrUpdate(guildId, newLogSetting, (_, _) => newLogSetting); - await uow.SaveChangesAsync(); - } -} \ No newline at end of file diff --git a/src/Mewdeko/Modules/Administration/Services/NewLogCommandService.cs b/src/Mewdeko/Modules/Administration/Services/NewLogCommandService.cs index 4a23e7b92..509c0cf5e 100644 --- a/src/Mewdeko/Modules/Administration/Services/NewLogCommandService.cs +++ b/src/Mewdeko/Modules/Administration/Services/NewLogCommandService.cs @@ -1,1436 +1,1454 @@ -// using Mewdeko.Modules.Moderation.Services; -// using Microsoft.EntityFrameworkCore; -// -// namespace Mewdeko.Modules.Administration.Services; -// -// public class NewLogCommandService -// { -// private readonly DbService db; -// private readonly IDataCache cache; -// private readonly DiscordSocketClient client; -// public ConcurrentDictionary GuildLogSettings { get; } -// -// public enum LogType -// { -// Other, -// EventCreated, -// RoleUpdated, -// RoleCreated, -// RoleDeleted, -// ServerUpdated, -// ThreadCreated, -// UserRoleAdded, -// UserRoleRemoved, -// UsernameUpdated, -// NicknameUpdated, -// ThreadDeleted, -// ThreadUpdated, -// MessageUpdated, -// MessageDeleted, -// UserJoined, -// UserLeft, -// UserBanned, -// UserUnbanned, -// UserUpdated, -// ChannelCreated, -// ChannelDestroyed, -// ChannelUpdated, -// VoicePresence, -// VoicePresenceTts, -// UserMuted -// } -// -// public enum LogCategoryTypes -// { -// All, -// Users, -// Threads, -// Roles, -// Server, -// Channel, -// Messages, -// Moderation, -// None -// } -// -// -// public NewLogCommandService(DbService db, IDataCache cache, DiscordSocketClient client, EventHandler handler, MuteService muteService) -// { -// this.db = db; -// this.cache = cache; -// this.client = client; -// handler.EventCreated += OnEventCreated; -// handler.RoleUpdated += OnRoleUpdated; -// handler.RoleCreated += OnRoleCreated; -// handler.RoleDeleted += OnRoleDeleted; -// handler.GuildUpdated += OnGuildUpdated; -// handler.ThreadCreated += OnThreadCreated; -// handler.GuildMemberUpdated += OnUserRoleAdded; -// handler.GuildMemberUpdated += OnUserRoleRemoved; -// handler.UserUpdated += OnUsernameUpdated; -// handler.GuildMemberUpdated += OnNicknameUpdated; -// handler.ThreadDeleted += OnThreadDeleted; -// handler.ThreadUpdated += OnThreadUpdated; -// handler.MessageUpdated += OnMessageUpdated; -// handler.MessageDeleted += OnMessageDeleted; -// handler.UserJoined += OnUserJoined; -// handler.UserLeft += OnUserLeft; -// handler.UserBanned += OnUserBanned; -// handler.UserUnbanned += OnUserUnbanned; -// handler.UserUpdated += OnUserUpdated; -// handler.ChannelCreated += OnChannelCreated; -// handler.ChannelDestroyed += OnChannelDestroyed; -// handler.ChannelUpdated += OnChannelUpdated; -// handler.UserVoiceStateUpdated += OnVoicePresence; -// handler.UserVoiceStateUpdated += OnVoicePresenceTts; -// muteService.UserMuted += OnUserMuted; -// muteService.UserUnmuted += OnUserUnmuted; -// -// using var uow = db.GetDbContext(); -// var guildIds = client.Guilds.Select(x => x.Id).ToList(); -// var configs = uow.GuildConfigs -// .AsQueryable() -// .Include(gc => gc.LogSetting) -// .ThenInclude(ls => ls.IgnoredChannels) -// .Where(x => guildIds.Contains(x.GuildId)) -// .ToList(); -// -// GuildLogSettings = configs -// .ToDictionary(g => g.GuildId, g => g.LogSetting) -// .ToConcurrent(); -// } -// -// -// private async Task OnRoleCreated(SocketRole args) -// { -// if (GuildLogSettings.TryGetValue(args.Guild.Id, out var logSetting)) -// { -// if (logSetting.RoleCreatedId is null or 0) -// return; -// -// var channel = args.Guild.GetTextChannel(logSetting.RoleCreatedId.Value); -// -// if (channel is null) -// return; -// -// await Task.Delay(500); -// -// var auditLogs = await args.Guild.GetAuditLogsAsync(1, actionType: ActionType.RoleCreated).FlattenAsync(); -// -// var eb = new EmbedBuilder() -// .WithOkColor() -// .WithTitle("Role Created") -// .WithDescription($"`Name:` {args.Name}\n" + -// $"`Id:` {args.Id}\n" + -// $"`Color:` {args.Color}\n" + -// $"`Hoisted:` {args.IsHoisted}\n" + -// $"`Mentionable:` {args.IsMentionable}\n" + -// $"`Position:` {args.Position}\n" + -// $"`Permissions:` {string.Join(", ", args.Permissions.ToList())}\n" + -// $"`Created By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}\n" + -// $"`Managed:` {args.IsManaged}"); -// -// await channel.SendMessageAsync(embed: eb.Build()); -// } -// } -// -// private async Task OnGuildUpdated(SocketGuild args, SocketGuild arsg2) -// { -// if (GuildLogSettings.TryGetValue(args.Id, out var logSetting)) -// { -// if (logSetting.ServerUpdatedId is null or 0) -// return; -// -// var channel = args.GetTextChannel(logSetting.ServerUpdatedId.Value); -// -// if (channel is null) -// return; -// -// await Task.Delay(500); -// -// var auditLogs = await args.GetAuditLogsAsync(1, actionType: ActionType.GuildUpdated).FlattenAsync(); -// -// var eb = new EmbedBuilder(); -// -// if (args.Name != arsg2.Name) -// { -// eb = new EmbedBuilder() -// .WithOkColor() -// .WithTitle("Server Name Updated") -// .WithDescription($"`New Name:` {arsg2.Name}\n" + -// $"`Old Name:` {args.Name}\n" + -// $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); -// } -// -// if (args.IconUrl != arsg2.IconUrl) -// { -// eb = new EmbedBuilder() -// .WithOkColor() -// .WithTitle("Server Icon Updated") -// .WithDescription($"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}") -// .WithThumbnailUrl(args.IconUrl) -// .WithImageUrl(arsg2.IconUrl); -// } -// -// if (args.BannerUrl != arsg2.BannerUrl) -// { -// eb = new EmbedBuilder() -// .WithOkColor() -// .WithTitle("Server Banner Updated") -// .WithDescription($"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}") -// .WithThumbnailUrl(args.BannerUrl) -// .WithImageUrl(arsg2.BannerUrl); -// } -// -// if (args.SplashUrl != arsg2.SplashUrl) -// { -// eb = new EmbedBuilder() -// .WithOkColor() -// .WithTitle("Server Splash Updated") -// .WithDescription($"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}") -// .WithThumbnailUrl(args.SplashUrl) -// .WithImageUrl(arsg2.SplashUrl); -// } -// -// if (args.VanityURLCode != arsg2.VanityURLCode) -// { -// eb = new EmbedBuilder() -// .WithOkColor() -// .WithTitle("Server Vanity URL Updated") -// .WithDescription($"`New Vanity URL:` {arsg2.VanityURLCode}\n" + -// $"`Old Vanity URL:` {args.VanityURLCode}\n" + -// $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); -// } -// -// if (args.OwnerId != arsg2.OwnerId) -// { -// eb = new EmbedBuilder() -// .WithOkColor() -// .WithTitle("Server Owner Updated") -// .WithDescription($"`New Owner:` {arsg2.Owner.Mention} | {arsg2.Owner.Id}\n" + -// $"`Old Owner:` {args.Owner.Mention} | {args.Owner.Id}\n" + -// $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); -// } -// -// if (args.AFKChannel != arsg2.AFKChannel) -// { -// eb = new EmbedBuilder() -// .WithOkColor() -// .WithTitle("Server AFK Channel Updated") -// .WithDescription($"`New AFK Channel:` {arsg2.AFKChannel.Mention} | {arsg2.AFKChannel.Id}\n" + -// $"`Old AFK Channel:` {args.AFKChannel.Mention} | {args.AFKChannel.Id}\n" + -// $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); -// } -// -// if (args.AFKTimeout != arsg2.AFKTimeout) -// { -// eb = new EmbedBuilder() -// .WithOkColor() -// .WithTitle("Server AFK Timeout Updated") -// .WithDescription($"`New AFK Timeout:` {arsg2.AFKTimeout}\n" + -// $"`Old AFK Timeout:` {args.AFKTimeout}\n" + -// $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); -// } -// -// if (args.DefaultMessageNotifications != arsg2.DefaultMessageNotifications) -// { -// eb = new EmbedBuilder() -// .WithOkColor() -// .WithTitle("Server Default Message Notifications Updated") -// .WithDescription($"`New Default Message Notifications:` {arsg2.DefaultMessageNotifications}\n" + -// $"`Old Default Message Notifications:` {args.DefaultMessageNotifications}\n" + -// $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); -// } -// -// if (args.ExplicitContentFilter != arsg2.ExplicitContentFilter) -// { -// eb = new EmbedBuilder() -// .WithOkColor() -// .WithTitle("Server Explicit Content Filter Updated") -// .WithDescription($"`New Explicit Content Filter:` {arsg2.ExplicitContentFilter}\n" + -// $"`Old Explicit Content Filter:` {args.ExplicitContentFilter}\n" + -// $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); -// } -// -// if (args.MfaLevel != arsg2.MfaLevel) -// { -// eb = new EmbedBuilder() -// .WithOkColor() -// .WithTitle("Server MFA Level Updated") -// .WithDescription($"`New MFA Level:` {arsg2.MfaLevel}\n" + -// $"`Old MFA Level:` {args.MfaLevel}\n" + -// $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); -// } -// -// if (args.VerificationLevel != arsg2.VerificationLevel) -// { -// eb = new EmbedBuilder() -// .WithOkColor() -// .WithTitle("Server Verification Level Updated") -// .WithDescription($"`New Verification Level:` {arsg2.VerificationLevel}\n" + -// $"`Old Verification Level:` {args.VerificationLevel}\n" + -// $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); -// } -// -// if (args.SystemChannel != arsg2.SystemChannel) -// { -// eb = new EmbedBuilder() -// .WithOkColor() -// .WithTitle("Server System Channel Updated") -// .WithDescription($"`New System Channel:` {arsg2.SystemChannel.Mention} | {arsg2.SystemChannel.Id}\n" + -// $"`Old System Channel:` {args.SystemChannel.Mention} | {args.SystemChannel.Id}\n" + -// $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); -// } -// -// if (args.RulesChannel != arsg2.RulesChannel) -// { -// eb = new EmbedBuilder() -// .WithOkColor() -// .WithTitle("Server Rules Channel Updated") -// .WithDescription($"`New Rules Channel:` {arsg2.RulesChannel.Mention} | {arsg2.RulesChannel.Id}\n" + -// $"`Old Rules Channel:` {args.RulesChannel.Mention} | {args.RulesChannel.Id}\n" + -// $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); -// } -// -// if (args.PublicUpdatesChannel != arsg2.PublicUpdatesChannel) -// { -// eb = new EmbedBuilder() -// .WithOkColor() -// .WithTitle("Server Public Updates Channel Updated") -// .WithDescription($"`New Public Updates Channel:` {arsg2.PublicUpdatesChannel.Mention} | {arsg2.PublicUpdatesChannel.Id}\n" + -// $"`Old Public Updates Channel:` {args.PublicUpdatesChannel.Mention} | {args.PublicUpdatesChannel.Id}\n" + -// $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); -// } -// -// if (args.MaxVideoChannelUsers != arsg2.MaxVideoChannelUsers) -// { -// eb = new EmbedBuilder() -// .WithOkColor() -// .WithTitle("Server Max Video Channel Users Updated") -// .WithDescription($"`New Max Video Channel Users:` {arsg2.MaxVideoChannelUsers}\n" + -// $"`Old Max Video Channel Users:` {args.MaxVideoChannelUsers}\n" + -// $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); -// } -// -// if (args.MaxMembers != arsg2.MaxMembers) -// { -// eb = new EmbedBuilder() -// .WithOkColor() -// .WithTitle("Server Max Members Updated") -// .WithDescription($"`New Max Members:` {arsg2.MaxMembers}\n" + -// $"`Old Max Members:` {args.MaxMembers}\n" + -// $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); -// } -// -// await channel.SendMessageAsync(embed: eb.Build()); -// } -// } -// -// private async Task OnRoleDeleted(SocketRole args) -// { -// if (GuildLogSettings.TryGetValue(args.Guild.Id, out var logSetting)) -// { -// if (logSetting.RoleDeletedId is null or 0) -// return; -// -// var channel = args.Guild.GetTextChannel(logSetting.RoleDeletedId.Value); -// -// if (channel is null) -// return; -// -// await Task.Delay(500); -// -// var auditLogs = await args.Guild.GetAuditLogsAsync(1, actionType: ActionType.GuildUpdated).FlattenAsync(); -// -// -// var eb = new EmbedBuilder() -// .WithOkColor() -// .WithTitle("Role Deleted") -// .WithDescription($"`Role:` {args.Name}\n" + -// $"`Deleted By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}\n" + -// $"`Deleted At:` {DateTime.UtcNow}\n" + -// $"`Members:` {args.Members.Count()}"); -// -// await channel.SendMessageAsync(embed: eb.Build()); -// } -// } -// -// private async Task OnRoleUpdated(SocketRole args, SocketRole arsg2) -// { -// if (GuildLogSettings.TryGetValue(args.Guild.Id, out var logSetting)) -// { -// if (logSetting.RoleUpdatedId is null or 0) -// return; -// -// var channel = args.Guild.GetTextChannel(logSetting.RoleUpdatedId.Value); -// -// if (channel is null) -// return; -// -// await Task.Delay(500); -// -// var auditLogs = await args.Guild.GetAuditLogsAsync(1, actionType: ActionType.RoleUpdated).FlattenAsync(); -// -// var eb = new EmbedBuilder(); -// -// if (args.Name != arsg2.Name) -// { -// eb = new EmbedBuilder() -// .WithOkColor() -// .WithTitle("Role Name Updated") -// .WithDescription($"`New Role Name:` {arsg2.Name}\n" + -// $"`Old Role Name:` {args.Name}\n" + -// $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); -// } -// -// if (args.Color != arsg2.Color) -// { -// eb = new EmbedBuilder() -// .WithColor(arsg2.Color) -// .WithTitle("Role Color Updated") -// .WithDescription($"`New Role Color:` {arsg2.Color}\n" + -// $"`Old Role Color:` {args.Color}\n" + -// $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); -// } -// -// if (args.IsHoisted != arsg2.IsHoisted) -// { -// eb = new EmbedBuilder() -// .WithOkColor() -// .WithTitle("Role Property Hoisted Updated") -// .WithDescription($"`New Role Hoisted:` {arsg2.IsHoisted}\n" + -// $"`Old Role Hoisted:` {args.IsHoisted}\n" + -// $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); -// } -// -// if (args.IsMentionable != arsg2.IsMentionable) -// { -// eb = new EmbedBuilder() -// .WithOkColor() -// .WithTitle("Role Property Mentionable Updated") -// .WithDescription($"`New Role Mentionable:` {arsg2.IsMentionable}\n" + -// $"`Old Role Mentionable:` {args.IsMentionable}\n" + -// $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); -// } -// -// if (args.IsManaged != arsg2.IsManaged) -// { -// eb = new EmbedBuilder() -// .WithOkColor() -// .WithTitle("Role Property Managed Updated") -// .WithDescription($"`New Role Managed:` {arsg2.IsManaged}\n" + -// $"`Old Role Managed:` {args.IsManaged}\n" + -// $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); -// } -// -// if (args.Position != arsg2.Position) -// { -// eb = new EmbedBuilder() -// .WithOkColor() -// .WithTitle("Role Position Updated") -// .WithDescription($"`New Role Position:` {arsg2.Position}\n" + -// $"`Old Role Position:` {args.Position}\n" + -// $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); -// } -// -// if (!arsg2.Permissions.Equals(args.Permissions)) -// { -// eb = new EmbedBuilder() -// .WithOkColor() -// .WithTitle("Role Permissions Updated") -// .WithDescription($"`New Role Permissions:` {arsg2.Permissions}\n" + -// $"`Old Role Permissions:` {args.Permissions}\n" + -// $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); -// } -// -// if (args.Icon != arsg2.Icon) -// { -// eb = new EmbedBuilder() -// .WithOkColor() -// .WithTitle("Role Icon Updated") -// .WithDescription($"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}") -// .WithThumbnailUrl(args.GetIconUrl()) -// .WithImageUrl(arsg2.GetIconUrl()); -// } -// -// await channel.SendMessageAsync(embed: eb.Build()); -// } -// } -// -// private async Task OnEventCreated(SocketGuildEvent args) -// { -// if (GuildLogSettings.TryGetValue(args.Guild.Id, out var logSetting)) -// { -// if (logSetting.EventCreatedId is null or 0) -// return; -// -// var channel = args.Guild.GetTextChannel(logSetting.EventCreatedId.Value); -// -// if (channel is null) -// return; -// -// var eb = new EmbedBuilder() -// .WithOkColor() -// .WithTitle("Event Created") -// .WithDescription($"`Event:` {args.Name}\n" + -// $"`Created By:` {args.Creator.Mention} | {args.Creator.Id}\n" + -// $"`Created At:` {DateTime.UtcNow}\n" + -// $"`Description:` {args.Description}\n" + -// $"`Event Date:` {args.StartTime}\n" + -// $"`End Date:` {args.EndTime}\n" + -// $"`Event Location:` {args.Location}\n" + -// $"`Event Type:` {args.Type}\n" + -// $"`Event Id:` {args.Id}") -// .WithImageUrl(args.GetCoverImageUrl()); -// -// await channel.SendMessageAsync(embed: eb.Build()); -// } -// } -// -// private async Task OnThreadCreated(SocketThreadChannel socketThreadChannel) -// { -// if (GuildLogSettings.TryGetValue(socketThreadChannel.Guild.Id, out var logSetting)) -// { -// if (logSetting.ThreadCreatedId is null or 0) -// return; -// -// var channel = socketThreadChannel.Guild.GetTextChannel(logSetting.ThreadCreatedId.Value); -// -// if (channel is null) -// return; -// -// var eb = new EmbedBuilder() -// .WithOkColor() -// .WithTitle("Thread Created") -// .WithDescription($"`Name:` {socketThreadChannel.Name}\n" + -// $"`Created By:` {socketThreadChannel.Owner.Mention} | {socketThreadChannel.Owner.Id}\n" + -// $"`Created At:` {DateTime.UtcNow}\n" + -// $"`Thread Type:` {socketThreadChannel.Type}\n" + -// $"`Thread Tags:` {socketThreadChannel.AppliedTags}"); -// -// await channel.SendMessageAsync(embed: eb.Build()); -// } -// } -// -// private async Task OnUserRoleAdded(Cacheable cacheable, SocketGuildUser arsg2) -// { -// if (GuildLogSettings.TryGetValue(arsg2.Guild.Id, out var logSetting)) -// { -// if (!cacheable.HasValue) return; -// if (logSetting.UserRoleAddedId is null or 0) -// return; -// -// var channel = arsg2.Guild.GetTextChannel(logSetting.UserRoleAddedId.Value); -// -// if (channel is null) -// return; -// -// await Task.Delay(500); -// var auditLogs = await arsg2.Guild.GetAuditLogsAsync(1, actionType: ActionType.MemberRoleUpdated).FlattenAsync(); -// -// var added = arsg2.Roles.Except(cacheable.Value.Roles); -// if (!added.Any()) -// return; -// -// var eb = new EmbedBuilder() -// .WithOkColor() -// .WithTitle("User Role(s) Added") -// .WithDescription($"`Role(s):` {string.Join(",", added.Select(x => $"{x.Mention}"))}\n" + -// $"`Added By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); -// -// await channel.SendMessageAsync(embed: eb.Build()); -// } -// } -// -// private async Task OnUserRoleRemoved(Cacheable cacheable, SocketGuildUser arsg2) -// { -// if (GuildLogSettings.TryGetValue(arsg2.Guild.Id, out var logSetting)) -// { -// if (!cacheable.HasValue) return; -// if (logSetting.UserRoleRemovedId is null or 0) -// return; -// -// var channel = arsg2.Guild.GetTextChannel(logSetting.UserRoleRemovedId.Value); -// -// if (channel is null) -// return; -// -// await Task.Delay(500); -// var auditLogs = await arsg2.Guild.GetAuditLogsAsync(1, actionType: ActionType.MemberRoleUpdated).FlattenAsync(); -// -// var removed = arsg2.Roles.Except(cacheable.Value.Roles); -// if (!removed.Any()) return; -// -// var eb = new EmbedBuilder() -// .WithOkColor() -// .WithTitle("User Role(s) Removed") -// .WithDescription($"`Role(s):` {string.Join(",", removed.Select(x => $"{x.Mention}"))}\n" + -// $"`Added By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); -// -// await channel.SendMessageAsync(embed: eb.Build()); -// } -// } -// -// private async Task OnUsernameUpdated(SocketUser args, SocketUser arsg2) -// { -// if (args is not SocketGuildUser user) -// return; -// if (args.Username.Equals(arsg2.Username)) -// return; -// -// if (GuildLogSettings.TryGetValue(user.Guild.Id, out var logSetting)) -// { -// if (logSetting.UsernameUpdatedId is null or 0) -// return; -// -// var channel = user.Guild.GetTextChannel(logSetting.UsernameUpdatedId.Value); -// -// if (channel is null) -// return; -// -// var eb = new EmbedBuilder() -// .WithOkColor() -// .WithTitle("Username Updated") -// .WithDescription( -// $"`Old Username:` {args.Username}\n" + -// $"`New Username:` {arsg2.Username}"); -// -// await channel.SendMessageAsync(embed: eb.Build()); -// } -// } -// -// private async Task OnNicknameUpdated(Cacheable cacheable, SocketGuildUser arsg2) -// { -// if (!cacheable.HasValue) return; -// if (GuildLogSettings.TryGetValue(arsg2.Guild.Id, out var logSetting)) -// { -// if (cacheable.Value.Nickname.Equals(arsg2.Nickname)) -// return; -// -// if (logSetting.NicknameUpdatedId is null or 0) -// return; -// -// var auditLogs = await arsg2.Guild.GetAuditLogsAsync(1, actionType: ActionType.MemberUpdated).FlattenAsync(); -// -// var entry = auditLogs.FirstOrDefault(); -// -// var channel = arsg2.Guild.GetTextChannel(logSetting.NicknameUpdatedId.Value); -// -// if (channel is null) -// return; -// -// var eb = new EmbedBuilder() -// .WithOkColor() -// .WithTitle("Nickname Updated") -// .WithDescription( -// $"`Old Nickname:` {cacheable.Value.Nickname ?? cacheable.Value.Username}\n" + -// $"`New Nickname:` {arsg2.Nickname ?? arsg2.Username}" + -// $"`Updated By:` {entry.User.Mention} | {entry.User.Id}"); -// -// await channel.SendMessageAsync(embed: eb.Build()); -// } -// } -// -// private async Task OnThreadDeleted(Cacheable args) -// { -// if (!args.HasValue) return; -// if (GuildLogSettings.TryGetValue(args.Value.Guild.Id, out var logSetting)) -// { -// if (logSetting.ThreadDeletedId is null or 0) -// return; -// -// var channel = args.Value.Guild.GetTextChannel(logSetting.ThreadDeletedId.Value); -// -// if (channel is null) -// return; -// -// var auditLogs = await args.Value.Guild.GetAuditLogsAsync(1, actionType: ActionType.ThreadDelete).FlattenAsync(); -// -// var entry = auditLogs.FirstOrDefault(); -// -// var eb = new EmbedBuilder() -// .WithOkColor() -// .WithTitle("Thread Deleted") -// .WithDescription( -// $"`Thread Name:` {args.Value.Name}\n" + -// $"`Thread Id:` {args.Value.Id}" + -// $"`Deleted By:` {entry.User.Mention} | {entry.User.Id}"); -// -// await channel.SendMessageAsync(embed: eb.Build()); -// } -// } -// -// private async Task OnThreadUpdated(Cacheable cacheable, SocketThreadChannel arsg2) -// { -// if (!cacheable.HasValue) return; -// var oldThread = cacheable.Value; -// if (GuildLogSettings.TryGetValue(arsg2.Guild.Id, out var logSetting)) -// { -// if (logSetting.ThreadUpdatedId is null or 0) -// return; -// -// var channel = arsg2.Guild.GetTextChannel(logSetting.ThreadUpdatedId.Value); -// -// if (channel is null) -// return; -// -// var auditLogs = await arsg2.Guild.GetAuditLogsAsync(1, actionType: ActionType.ThreadUpdate).FlattenAsync(); -// -// var entry = auditLogs.FirstOrDefault(); -// -// var eb = new EmbedBuilder(); -// -// if (oldThread.Name != arsg2.Name) -// eb.WithOkColor() -// .WithTitle("Thread Name Updated") -// .WithDescription( -// $"`Old Thread Name:` {oldThread.Name}\n" + -// $"`New Thread Name:` {arsg2.Name}" + -// $"`Updated By:` {entry.User.Mention} | {entry.User.Id}"); -// -// if (oldThread.IsArchived != arsg2.IsArchived) -// eb.WithOkColor() -// .WithTitle("Thread Archival Status Updated") -// .WithDescription($"Before: {oldThread.IsArchived}\n" + -// $"After: {arsg2.IsArchived}\n" + -// $"`Updated By:` {entry.User.Mention} | {entry.User.Id}"); -// -// if (oldThread.IsLocked != arsg2.IsLocked) -// eb.WithOkColor() -// .WithTitle("Thread Lock Status Updated") -// .WithDescription($"Before: {oldThread.IsLocked}\n" + -// $"After: {arsg2.IsLocked}\n" + -// $"`Updated By:` {entry.User.Mention} | {entry.User.Id}"); -// -// await channel.SendMessageAsync(embed: eb.Build()); -// } -// } -// -// private async Task OnMessageUpdated(Cacheable cacheable, SocketMessage args2, ISocketMessageChannel args3) -// { -// if (!cacheable.HasValue) return; -// var oldMessage = cacheable.Value; -// if (args3 is not SocketTextChannel guildChannel) -// return; -// if (GuildLogSettings.TryGetValue(guildChannel.Guild.Id, out var logSetting)) -// { -// if (logSetting.MessageUpdatedId is null or 0) -// return; -// -// var channel = guildChannel.Guild.GetTextChannel(logSetting.MessageUpdatedId.Value); -// -// if (channel is null) -// return; -// -// var eb = new EmbedBuilder() -// .WithOkColor() -// .WithTitle("Message Updated") -// .WithDescription( -// $"`Message Author:` {oldMessage.Author.Mention}\n" + -// $"`Message Channel:` {guildChannel.Mention} | {guildChannel.Id}\n" + -// $"`Message Id:` {oldMessage.Id}\n" + -// $"`Old Message Content:` {oldMessage.Content}\n" + -// $"`Updated Message Content:` {args2.Content}"); -// -// var component = new ComponentBuilder().WithButton("Jump to Message", style: ButtonStyle.Link, url: oldMessage.GetJumpUrl()).Build(); -// -// await channel.SendMessageAsync(embed: eb.Build(), components: component); -// } -// } -// -// private async Task OnMessageDeleted(Cacheable args, Cacheable arsg2) -// { -// if (!args.HasValue) return; -// if (args.Value is not SocketUserMessage message) return; -// if (args.Value.Channel is not SocketTextChannel guildChannel) return; -// if (GuildLogSettings.TryGetValue(guildChannel.Guild.Id, out var logSetting)) -// { -// if (logSetting.MessageDeletedId is null or 0) -// return; -// -// var channel = guildChannel.Guild.GetTextChannel(logSetting.MessageDeletedId.Value); -// -// var auditLogs = await guildChannel.Guild.GetAuditLogsAsync(1, actionType: ActionType.MessageDeleted).FlattenAsync(); -// -// var entry = auditLogs.FirstOrDefault(); -// -// var eb = new EmbedBuilder() -// .WithOkColor() -// .WithTitle("Message Deleted") -// .WithDescription( -// $"`Message Author:` {message.Author.Mention}\n" + -// $"`Message Channel:` {guildChannel.Mention} | {guildChannel.Id}\n" + -// $"`Message Content:` {message.Content}\n" + -// $"`Deleted By:` {(entry is null ? message.Author.Mention : entry.User.Mention)} | {(entry is null ? message.Author.Id : entry.User.Id)}"); -// -// await channel.SendMessageAsync(embed: eb.Build()); -// } -// } -// -// private async Task OnUserJoined(IGuildUser guildUser) -// { -// if (GuildLogSettings.TryGetValue(guildUser.Guild.Id, out var logSetting)) -// { -// if (logSetting.UserJoinedId is null or 0) -// return; -// -// var channel = await guildUser.Guild.GetTextChannelAsync(logSetting.UserJoinedId.Value); -// -// if (channel is null) -// return; -// -// var eb = new EmbedBuilder() -// .WithOkColor() -// .WithTitle("User Joined") -// .WithDescription( -// $"`User:` {guildUser.Mention} | {guildUser.Id}\n" + -// $"`Account Created:` {guildUser.CreatedAt:dd/MM/yyyy}\n" + -// $"`Joined Server:` {guildUser.JoinedAt:dd/MM/yyyy}\n" + -// $"`User Status:` {guildUser.Status}" + -// $"`User Id:` {guildUser.Id}" + -// $"`User Global Name:` {guildUser.GlobalName ?? guildUser.Username}") -// .WithThumbnailUrl(guildUser.RealAvatarUrl().ToString()); -// -// var component = new ComponentBuilder().WithButton("View User", style: ButtonStyle.Link, url: $"discord://-/users/{guildUser.Id}").Build(); -// -// await channel.SendMessageAsync(components: component, embed: eb.Build()); -// } -// } -// -// private async Task OnUserLeft(IGuild guild, IUser arsg2) -// { -// if (arsg2 is not SocketGuildUser usr) return; -// if (GuildLogSettings.TryGetValue(guild.Id, out var logSetting)) -// { -// if (logSetting.UserLeftId is null or 0) -// return; -// -// var channel = await guild.GetTextChannelAsync(logSetting.UserLeftId.Value); -// -// if (channel is null) -// return; -// -// var eb = new EmbedBuilder() -// .WithOkColor() -// .WithTitle("User Left") -// .WithDescription( -// $"`User:` {usr.Mention} | {usr.Id}\n" + -// $"`User Id:` {usr.Id}" + -// $"`User Global Name:` {arsg2.GlobalName ?? arsg2.Username}" + -// $"`Account Created:` {usr.CreatedAt:dd/MM/yyyy}\n" + -// $"`Joined Server:` {usr.JoinedAt:dd/MM/yyyy}\n" + -// $"`Roles:` {string.Join(", ", usr.Roles.Select(x => x.Mention))}") -// .WithThumbnailUrl(arsg2.RealAvatarUrl().ToString()); -// -// var component = new ComponentBuilder().WithButton("View User (May not work)", style: ButtonStyle.Link, url: $"discord://-/users/{arsg2.Id}").Build(); -// -// await channel.SendMessageAsync(components: component, embed: eb.Build()); -// } -// } -// -// private async Task OnUserBanned(SocketUser args, SocketGuild arsg2) -// { -// if (args is not SocketGuildUser usr) return; -// if (GuildLogSettings.TryGetValue(arsg2.Id, out var logSetting)) -// { -// if (logSetting.UserBannedId is null or 0) -// return; -// -// var channel = usr.Guild.GetTextChannel(logSetting.UserBannedId.Value); -// -// if (channel is null) -// return; -// -// var auditLogs = await arsg2.GetAuditLogsAsync(1, actionType: ActionType.Ban).FlattenAsync(); -// -// var entry = auditLogs.FirstOrDefault(); -// -// var eb = new EmbedBuilder() -// .WithOkColor() -// .WithTitle("User Banned") -// .WithDescription( -// $"`User:` {args.Mention} | {args.Id}\n" + -// $"`User Id:` {args.Id}" + -// $"`User Global Name:` {args.GlobalName ?? args.Username}" + -// $"`Account Created:` {args.CreatedAt:dd/MM/yyyy}\n" + -// $"`Joined Server:` {usr.JoinedAt:dd/MM/yyyy}\n" + -// $"`Roles:` {string.Join(", ", usr.Roles.Select(x => x.Mention))}\n" + -// $"`Banned By:` {entry.User.Mention} | {entry.User.Id}") -// .WithThumbnailUrl(args.RealAvatarUrl().ToString()); -// -// var component = new ComponentBuilder().WithButton("View User (May not work)", style: ButtonStyle.Link, url: $"discord://-/users/{args.Id}").Build(); -// -// await channel.SendMessageAsync(components: component, embed: eb.Build()); -// } -// } -// -// private async Task OnUserUnbanned(SocketUser args, SocketGuild arsg2) -// { -// if (GuildLogSettings.TryGetValue(arsg2.Id, out var logSetting)) -// { -// if (logSetting.UserUnbannedId is null or 0) -// return; -// -// var channel = arsg2.GetTextChannel(logSetting.UserUnbannedId.Value); -// -// if (channel is null) -// return; -// -// var auditLogs = await arsg2.GetAuditLogsAsync(1, actionType: ActionType.Unban).FlattenAsync(); -// -// var entry = auditLogs.FirstOrDefault(); -// -// var eb = new EmbedBuilder() -// .WithOkColor() -// .WithTitle("User Unbanned") -// .WithDescription( -// $"`User:` {args.Mention} | {args.Id}\n" + -// $"`User Id:` {args.Id}" + -// $"`User Global Name:` {args.GlobalName ?? args.Username}" + -// $"`Account Created:` {args.CreatedAt:dd/MM/yyyy}\n" + -// $"`Unbanned By:` {entry.User.Mention} | {entry.User.Id}") -// .WithThumbnailUrl(args.RealAvatarUrl().ToString()); -// -// var component = new ComponentBuilder().WithButton("View User (May not work)", style: ButtonStyle.Link, url: $"discord://-/users/{args.Id}").Build(); -// -// await channel.SendMessageAsync(components: component, embed: eb.Build()); -// } -// } -// -// private async Task OnUserUpdated(SocketUser args, SocketUser arsg2) -// { -// if (args is not SocketGuildUser usr) return; -// -// if (GuildLogSettings.TryGetValue(usr.Guild.Id, out var logSetting)) -// { -// if (logSetting.UserUpdatedId is null or 0) -// return; -// -// var channel = usr.Guild.GetTextChannel(logSetting.UserUpdatedId.Value); -// -// if (channel is null) -// return; -// -// var eb = new EmbedBuilder(); -// -// if (args.AvatarId != arsg2.AvatarId) -// eb.WithOkColor() -// .WithTitle("User Avatar Updated") -// .WithThumbnailUrl(args.RealAvatarUrl().ToString()) -// .WithImageUrl(arsg2.RealAvatarUrl().ToString()); -// -// if (args.GlobalName != arsg2.GlobalName) -// eb.WithOkColor() -// .WithTitle("User Global Name Updated") -// .WithDescription( -// $"`User:` {args.Mention} | {args.Id}\n" + -// $"`User Id:` {args.Id}" + -// $"`User Global Name:` {args.GlobalName ?? args.Username}"); -// -// await channel.SendMessageAsync(embed: eb.Build()); -// } -// } -// -// private async Task OnChannelCreated(SocketChannel args) -// { -// if (args is not SocketGuildChannel channel) return; -// -// if (GuildLogSettings.TryGetValue(channel.Guild.Id, out var logSetting)) -// { -// if (logSetting.ChannelCreatedId is null or 0) -// return; -// -// var logChannel = channel.Guild.GetTextChannel(logSetting.ChannelCreatedId.Value); -// -// if (logChannel is null) -// return; -// -// string createdType; -// -// if (channel is SocketTextChannel) -// createdType = "Text"; -// else -// switch (args) -// { -// case SocketVoiceChannel: -// createdType = "Voice"; -// break; -// case SocketCategoryChannel: -// createdType = "Category"; -// break; -// case SocketNewsChannel: -// createdType = "News"; -// break; -// default: -// { -// createdType = channel is SocketStageChannel ? "Stage" : "Unknown"; -// break; -// } -// } -// -// var auditLogs = await channel.Guild.GetAuditLogsAsync(1, actionType: ActionType.ChannelCreated).FlattenAsync(); -// -// var entry = auditLogs.FirstOrDefault(); -// -// var eb = new EmbedBuilder() -// .WithOkColor() -// .WithTitle("Channel Created") -// .WithDescription( -// $"`Channel:` {channel.Name} | {channel.Id}\n" + -// $"`Channel Created By:` {entry.User.Mention} | {entry.User.Id}" + -// $"`Channel Created At:` {channel.CreatedAt:dd/MM/yyyy}\n" + -// $"`Channel Type:` {createdType}"); -// -// await logChannel.SendMessageAsync(embed: eb.Build()); -// } -// } -// -// private async Task OnChannelDestroyed(SocketChannel args) -// { -// if (args is not SocketGuildChannel channel) return; -// -// if (GuildLogSettings.TryGetValue(channel.Guild.Id, out var logSetting)) -// { -// if (logSetting.ChannelDestroyedId is null or 0) -// return; -// -// var logChannel = channel.Guild.GetTextChannel(logSetting.ChannelDestroyedId.Value); -// -// if (logChannel is null) -// return; -// -// string createdType; -// -// if (channel is SocketTextChannel) -// createdType = "Text"; -// else -// switch (args) -// { -// case SocketVoiceChannel: -// createdType = "Voice"; -// break; -// case SocketCategoryChannel: -// createdType = "Category"; -// break; -// case SocketNewsChannel: -// createdType = "News"; -// break; -// default: -// { -// createdType = channel is SocketStageChannel ? "Stage" : "Unknown"; -// break; -// } -// } -// -// var auditLogs = await channel.Guild.GetAuditLogsAsync(1, actionType: ActionType.ChannelDeleted).FlattenAsync(); -// -// var entry = auditLogs.FirstOrDefault(); -// -// var eb = new EmbedBuilder() -// .WithOkColor() -// .WithTitle("Channel Destroyed") -// .WithDescription( -// $"`Channel:` {channel.Name} | {channel.Id}\n" + -// $"`Channel Destroyed By:` {entry.User.Mention} | {entry.User.Id}" + -// $"`Channel Destroyed At:` {DateTime.UtcNow:dd/MM/yyyy}\n" + -// $"`Channel Type:` {createdType}"); -// -// await logChannel.SendMessageAsync(embed: eb.Build()); -// } -// } -// -// private async Task OnChannelUpdated(SocketChannel args, SocketChannel arsg2) -// { -// if (args is not SocketGuildChannel channel || arsg2 is not SocketGuildChannel channel2) return; -// -// if (GuildLogSettings.TryGetValue(channel.Guild.Id, out var logSetting)) -// { -// if (logSetting.ChannelUpdatedId is null or 0) -// return; -// -// var logChannel = channel.Guild.GetTextChannel(logSetting.ChannelUpdatedId.Value); -// -// if (logChannel is null) -// return; -// -// var audit = await channel.Guild.GetAuditLogsAsync(1, actionType: ActionType.ChannelUpdated).FlattenAsync(); -// -// var entry = audit.FirstOrDefault(); -// -// var eb = new EmbedBuilder() -// .WithOkColor(); -// -// if (channel.Name != channel2.Name) -// eb.WithTitle("Channel Name Updated") -// .WithDescription( -// $"`Old Name:` {channel.Name}\n" + -// $"`New Name:` {channel2.Name}\n" + -// $"`Channel Updated By:` {entry.User.Mention} | {entry.User.Id}"); -// -// if (channel.Position != channel2.Position) -// eb.WithTitle("Channel Position Updated") -// .WithDescription( -// $"`Old Position:` {channel.Position}\n" + -// $"`New Position:` {channel2.Position}\n" + -// $"`Channel Updated By:` {entry.User.Mention} | {entry.User.Id}"); -// -// if (channel is SocketTextChannel textChannel && channel2 is SocketTextChannel textChannel2) -// { -// if (textChannel.Topic != textChannel2.Topic) -// eb.WithTitle("Channel Topic Updated") -// .WithDescription( -// $"`Old Topic:` {textChannel.Topic}\n" + -// $"`New Topic:` {textChannel2.Topic}\n" + -// $"`Channel Updated By:` {entry.User.Mention} | {entry.User.Id}"); -// -// if (textChannel.IsNsfw != textChannel2.IsNsfw) -// eb.WithTitle("Channel NSFW Updated") -// .WithDescription( -// $"`Old NSFW:` {textChannel.IsNsfw}\n" + -// $"`New NSFW:` {textChannel2.IsNsfw}\n" + -// $"`Channel Updated By:` {entry.User.Mention} | {entry.User.Id}"); -// -// if (textChannel.SlowModeInterval != textChannel2.SlowModeInterval) -// eb.WithTitle("Channel Slowmode Interval Updated") -// .WithDescription( -// $"`Old Slowmode Interval:` {textChannel.SlowModeInterval}\n" + -// $"`New Slowmode Interval:` {textChannel2.SlowModeInterval}\n" + -// $"`Channel Updated By:` {entry.User.Mention} | {entry.User.Id}"); -// -// if (textChannel.CategoryId != textChannel2.CategoryId) -// eb.WithTitle("Channel Category Updated") -// .WithDescription( -// $"`Old Category:` {textChannel.Category}\n" + -// $"`New Category:` {textChannel2.Category}\n" + -// $"`Channel Updated By:` {entry.User.Mention} | {entry.User.Id}"); -// } -// -// if (channel is SocketVoiceChannel voiceChannel && channel2 is SocketVoiceChannel voiceChannel2) -// { -// if (voiceChannel.Bitrate != voiceChannel2.Bitrate) -// eb.WithTitle("Channel Bitrate Updated") -// .WithDescription( -// $"`Old Bitrate:` {voiceChannel.Bitrate}\n" + -// $"`New Bitrate:` {voiceChannel2.Bitrate}\n" + -// $"`Channel Updated By:` {entry.User.Mention} | {entry.User.Id}"); -// -// if (voiceChannel.UserLimit != voiceChannel2.UserLimit) -// eb.WithTitle("Channel User Limit Updated") -// .WithDescription( -// $"`Old User Limit:` {voiceChannel.UserLimit}\n" + -// $"`New User Limit:` {voiceChannel2.UserLimit}\n" + -// $"`Channel Updated By:` {entry.User.Mention} | {entry.User.Id}"); -// -// if (voiceChannel.CategoryId != voiceChannel2.CategoryId) -// eb.WithTitle("Channel Category Updated") -// .WithDescription( -// $"`Old Category:` {voiceChannel.Category}\n" + -// $"`New Category:` {voiceChannel2.Category}\n" + -// $"`Channel Updated By:` {entry.User.Mention} | {entry.User.Id}"); -// -// if (voiceChannel.Position != voiceChannel2.Position) -// eb.WithTitle("Channel Position Updated") -// .WithDescription( -// $"`Old Position:` {voiceChannel.Position}\n" + -// $"`New Position:` {voiceChannel2.Position}\n" + -// $"`Channel Updated By:` {entry.User.Mention} | {entry.User.Id}"); -// -// if (voiceChannel.VideoQualityMode != voiceChannel2.VideoQualityMode) -// eb.WithTitle("Channel Video Quality Mode Updated") -// .WithDescription( -// $"`Old Video Quality Mode:` {voiceChannel.VideoQualityMode}\n" + -// $"`New Video Quality Mode:` {voiceChannel2.VideoQualityMode}\n" + -// $"`Channel Updated By:` {entry.User.Mention} | {entry.User.Id}"); -// -// if (voiceChannel.RTCRegion != voiceChannel2.RTCRegion) -// eb.WithTitle("Channel RTC Region Updated") -// .WithDescription( -// $"`Old RTC Region:` {voiceChannel.RTCRegion}\n" + -// $"`New RTC Region:` {voiceChannel2.RTCRegion}\n" + -// $"`Channel Updated By:` {entry.User.Mention} | {entry.User.Id}"); -// } -// -// await logChannel.SendMessageAsync(embed: eb.Build()); -// } -// } -// -// private async Task OnVoicePresence(SocketUser args, SocketVoiceState args2, SocketVoiceState args3) -// { -// if (args.IsBot) -// return; -// -// if (args is not IGuildUser guildUser) -// return; -// -// if (GuildLogSettings.TryGetValue(guildUser.Guild.Id, out var logSetting)) -// { -// if (logSetting.LogVoicePresenceId is null or 0) -// return; -// -// var logChannel = await guildUser.Guild.GetTextChannelAsync(logSetting.LogVoicePresenceId.Value); -// -// if (logChannel is null) -// return; -// -// var eb = new EmbedBuilder(); -// -// if (args2.VoiceChannel is not null && args3.VoiceChannel is not null) -// eb.WithTitle("User Moved Voice Channels") -// .WithDescription( -// $"`User:` {args.Mention} | {args.Id}\n" + -// $"`Old Channel:` {args2.VoiceChannel.Name}\n" + -// $"`New Channel:` {args3.VoiceChannel.Name}"); -// -// if (args2.VoiceChannel is null && args3.VoiceChannel is not null) -// eb.WithTitle("User Joined Voice Channel") -// .WithDescription( -// $"`User:` {args.Mention} | {args.Id}\n" + -// $"`Channel:` {args3.VoiceChannel.Name}"); -// -// if (args2.VoiceChannel is not null && args3.VoiceChannel is null) -// eb.WithTitle("User Left Voice Channel") -// .WithDescription( -// $"`User:` {args.Mention} | {args.Id}\n" + -// $"`Channel:` {args2.VoiceChannel.Name}"); -// -// if (!args2.IsDeafened && args3.IsDeafened) -// eb.WithTitle($"User {(!args3.IsSelfDeafened ? "Server Voice Deafened" : "Self Voice Deafened")}") -// .WithDescription( -// $"`User:` {args.Mention} | {args.Id}\n" + -// $"`Channel:` {args2.VoiceChannel.Name}"); -// -// if (args2.IsDeafened && !args3.IsDeafened) -// eb.WithTitle("User UnDeafened") -// .WithDescription( -// $"`User:` {args.Mention} | {args.Id}\n" + -// $"`Channel:` {args2.VoiceChannel.Name}"); -// -// if (!args2.IsMuted && args3.IsMuted) -// eb.WithTitle($"User {(!args3.IsSelfMuted ? "Server Voice Muted" : "Self Voice Muted")}") -// .WithDescription( -// $"`User:` {args.Mention} | {args.Id}\n" + -// $"`Channel:` {args2.VoiceChannel.Name}"); -// -// if (args2.IsMuted && !args3.IsMuted) -// eb.WithTitle("User Voice UnMuted") -// .WithDescription( -// $"`User:` {args.Mention} | {args.Id}\n" + -// $"`Channel:` {args2.VoiceChannel.Name}"); -// -// -// await logChannel.SendMessageAsync(embed: eb.Build()); -// } -// } -// -// private async Task OnVoicePresenceTts(SocketUser args, SocketVoiceState args2, SocketVoiceState args3) -// { -// throw new NotImplementedException(); -// } -// -// private async Task OnUserMuted(IGuildUser guildUser, IUser args2, MuteType args3, string args4) -// { -// throw new NotImplementedException(); -// } -// -// private async Task OnUserUnmuted(IGuildUser args, IUser args2, MuteType args3, string args4) -// { -// throw new NotImplementedException(); -// } -// -// public async Task SetLogChannel(ulong guildId, ulong channelId, LogType type) -// { -// await using var uow = db.GetDbContext(); -// var logSetting = (await uow.LogSettingsFor(guildId)).LogSetting; -// switch (type) -// { -// case LogType.Other: -// logSetting.LogOtherId = channelId; -// break; -// case LogType.EventCreated: -// logSetting.EventCreatedId = channelId; -// break; -// case LogType.RoleUpdated: -// logSetting.RoleUpdatedId = channelId; -// break; -// case LogType.RoleCreated: -// logSetting.RoleCreatedId = channelId; -// break; -// case LogType.ServerUpdated: -// logSetting.ServerUpdatedId = channelId; -// break; -// case LogType.ThreadCreated: -// logSetting.ThreadCreatedId = channelId; -// break; -// case LogType.UserRoleAdded: -// logSetting.UserRoleAddedId = channelId; -// break; -// case LogType.UserRoleRemoved: -// logSetting.UserRoleRemovedId = channelId; -// break; -// case LogType.UsernameUpdated: -// logSetting.UsernameUpdatedId = channelId; -// break; -// case LogType.NicknameUpdated: -// logSetting.NicknameUpdatedId = channelId; -// break; -// case LogType.ThreadDeleted: -// logSetting.ThreadDeletedId = channelId; -// break; -// case LogType.ThreadUpdated: -// logSetting.ThreadUpdatedId = channelId; -// break; -// case LogType.MessageUpdated: -// logSetting.MessageUpdatedId = channelId; -// break; -// case LogType.MessageDeleted: -// logSetting.MessageDeletedId = channelId; -// break; -// case LogType.UserJoined: -// logSetting.UserJoinedId = channelId; -// break; -// case LogType.UserLeft: -// logSetting.UserLeftId = channelId; -// break; -// case LogType.UserBanned: -// logSetting.UserBannedId = channelId; -// break; -// case LogType.UserUnbanned: -// logSetting.UserUnbannedId = channelId; -// break; -// case LogType.UserUpdated: -// logSetting.UserUpdatedId = channelId; -// break; -// case LogType.ChannelCreated: -// logSetting.ChannelCreatedId = channelId; -// break; -// case LogType.ChannelDestroyed: -// logSetting.ChannelDestroyedId = channelId; -// break; -// case LogType.ChannelUpdated: -// logSetting.ChannelUpdatedId = channelId; -// break; -// case LogType.VoicePresence: -// logSetting.LogVoicePresenceId = channelId; -// break; -// case LogType.VoicePresenceTts: -// logSetting.LogVoicePresenceTTSId = channelId; -// break; -// case LogType.UserMuted: -// logSetting.UserMutedId = channelId; -// break; -// } -// -// uow.LogSettings.Update(logSetting); -// await uow.SaveChangesAsync(); -// GuildLogSettings.AddOrUpdate(guildId, _ => logSetting, (_, _) => logSetting); -// } -// -// public async Task LogSetByType(ulong guildId, ulong channelId, LogCategoryTypes categoryTypes) -// { -// await using var uow = db.GetDbContext(); -// var logSetting = (await uow.LogSettingsFor(guildId)).LogSetting; -// switch (categoryTypes) -// { -// case LogCategoryTypes.All: -// logSetting.AvatarUpdatedId = channelId; -// logSetting.ChannelCreatedId = channelId; -// logSetting.ChannelDestroyedId = channelId; -// logSetting.ChannelUpdatedId = channelId; -// logSetting.EventCreatedId = channelId; -// logSetting.LogOtherId = channelId; -// logSetting.MessageDeletedId = channelId; -// logSetting.MessageUpdatedId = channelId; -// logSetting.NicknameUpdatedId = channelId; -// logSetting.RoleCreatedId = channelId; -// logSetting.RoleDeletedId = channelId; -// logSetting.RoleUpdatedId = channelId; -// logSetting.ServerUpdatedId = channelId; -// logSetting.ThreadCreatedId = channelId; -// logSetting.ThreadDeletedId = channelId; -// logSetting.ThreadUpdatedId = channelId; -// logSetting.UserBannedId = channelId; -// logSetting.UserJoinedId = channelId; -// logSetting.UserLeftId = channelId; -// logSetting.UserMutedId = channelId; -// logSetting.UsernameUpdatedId = channelId; -// logSetting.UserUnbannedId = channelId; -// logSetting.UserUpdatedId = channelId; -// logSetting.LogUserPresenceId = channelId; -// logSetting.LogVoicePresenceId = channelId; -// logSetting.UserRoleAddedId = channelId; -// logSetting.UserRoleRemovedId = channelId; -// logSetting.LogVoicePresenceTTSId = channelId; -// break; -// case LogCategoryTypes.Users: -// logSetting.NicknameUpdatedId = channelId; -// logSetting.AvatarUpdatedId = channelId; -// logSetting.UsernameUpdatedId = channelId; -// logSetting.UserRoleAddedId = channelId; -// logSetting.UserRoleRemovedId = channelId; -// logSetting.LogVoicePresenceId = channelId; -// break; -// case LogCategoryTypes.Threads: -// logSetting.ThreadCreatedId = channelId; -// logSetting.ThreadDeletedId = channelId; -// logSetting.ThreadUpdatedId = channelId; -// break; -// case LogCategoryTypes.Roles: -// logSetting.RoleCreatedId = channelId; -// logSetting.RoleDeletedId = channelId; -// logSetting.RoleUpdatedId = channelId; -// break; -// case LogCategoryTypes.Server: -// logSetting.ServerUpdatedId = channelId; -// logSetting.EventCreatedId = channelId; -// break; -// case LogCategoryTypes.Channel: -// logSetting.ChannelUpdatedId = channelId; -// logSetting.ChannelCreatedId = channelId; -// logSetting.ChannelDestroyedId = channelId; -// break; -// case LogCategoryTypes.Messages: -// logSetting.MessageDeletedId = channelId; -// logSetting.MessageUpdatedId = channelId; -// break; -// case LogCategoryTypes.Moderation: -// logSetting.UserMutedId = channelId; -// logSetting.UserBannedId = channelId; -// logSetting.UserUnbannedId = channelId; -// break; -// case LogCategoryTypes.None: -// logSetting.AvatarUpdatedId = 0; -// logSetting.ChannelCreatedId = 0; -// logSetting.ChannelDestroyedId = 0; -// logSetting.ChannelUpdatedId = 0; -// logSetting.EventCreatedId = 0; -// logSetting.LogOtherId = 0; -// logSetting.MessageDeletedId = 0; -// logSetting.MessageUpdatedId = 0; -// logSetting.NicknameUpdatedId = 0; -// logSetting.RoleCreatedId = 0; -// logSetting.RoleDeletedId = 0; -// logSetting.RoleUpdatedId = 0; -// logSetting.ServerUpdatedId = 0; -// logSetting.ThreadCreatedId = 0; -// logSetting.ThreadDeletedId = 0; -// logSetting.ThreadUpdatedId = 0; -// logSetting.UserBannedId = 0; -// logSetting.UserJoinedId = 0; -// logSetting.UserLeftId = 0; -// logSetting.UserMutedId = 0; -// logSetting.UsernameUpdatedId = 0; -// logSetting.UserUnbannedId = 0; -// logSetting.UserUpdatedId = 0; -// logSetting.LogUserPresenceId = 0; -// logSetting.LogVoicePresenceId = 0; -// logSetting.UserRoleAddedId = 0; -// logSetting.UserRoleRemovedId = 0; -// logSetting.LogVoicePresenceTTSId = 0; -// break; -// } -// -// await uow.SaveChangesAsync(); -// GuildLogSettings.AddOrUpdate(guildId, _ => logSetting, (_, _) => logSetting); -// } -// } +using Mewdeko.Modules.Moderation.Services; +using Microsoft.EntityFrameworkCore; +namespace Mewdeko.Modules.Administration.Services; + +public class NewLogCommandService : INService +{ + private readonly DbService db; + private readonly IDataCache cache; + private readonly DiscordSocketClient client; + public ConcurrentDictionary GuildLogSettings { get; } + + public enum LogType + { + Other, + EventCreated, + RoleUpdated, + RoleCreated, + RoleDeleted, + ServerUpdated, + ThreadCreated, + UserRoleAdded, + UserRoleRemoved, + UsernameUpdated, + NicknameUpdated, + ThreadDeleted, + ThreadUpdated, + MessageUpdated, + MessageDeleted, + UserJoined, + UserLeft, + UserBanned, + UserUnbanned, + UserUpdated, + ChannelCreated, + ChannelDestroyed, + ChannelUpdated, + VoicePresence, + VoicePresenceTts, + UserMuted + } + + public enum LogCategoryTypes + { + All, + Users, + Threads, + Roles, + Server, + Channel, + Messages, + Moderation, + None + } + + + public NewLogCommandService(DbService db, IDataCache cache, DiscordSocketClient client, EventHandler handler, + MuteService muteService) + { + this.db = db; + this.cache = cache; + this.client = client; + handler.EventCreated += OnEventCreated; + handler.RoleUpdated += OnRoleUpdated; + handler.RoleCreated += OnRoleCreated; + handler.RoleDeleted += OnRoleDeleted; + handler.GuildUpdated += OnGuildUpdated; + handler.ThreadCreated += OnThreadCreated; + handler.GuildMemberUpdated += OnUserRoleAdded; + handler.GuildMemberUpdated += OnUserRoleRemoved; + handler.UserUpdated += OnUsernameUpdated; + handler.GuildMemberUpdated += OnNicknameUpdated; + handler.ThreadDeleted += OnThreadDeleted; + handler.ThreadUpdated += OnThreadUpdated; + handler.MessageUpdated += OnMessageUpdated; + handler.MessageDeleted += OnMessageDeleted; + handler.UserJoined += OnUserJoined; + handler.UserLeft += OnUserLeft; + handler.UserBanned += OnUserBanned; + handler.UserUnbanned += OnUserUnbanned; + handler.UserUpdated += OnUserUpdated; + handler.ChannelCreated += OnChannelCreated; + handler.ChannelDestroyed += OnChannelDestroyed; + handler.ChannelUpdated += OnChannelUpdated; + handler.UserVoiceStateUpdated += OnVoicePresence; + handler.UserVoiceStateUpdated += OnVoicePresenceTts; + muteService.UserMuted += OnUserMuted; + muteService.UserUnmuted += OnUserUnmuted; + + using var uow = db.GetDbContext(); + var guildIds = client.Guilds.Select(x => x.Id).ToList(); + var configs = uow.GuildConfigs + .AsQueryable() + .Include(gc => gc.LogSetting) + .ThenInclude(ls => ls.IgnoredChannels) + .Where(x => guildIds.Contains(x.GuildId)) + .ToList(); + + GuildLogSettings = configs + .ToDictionary(g => g.GuildId, g => g.LogSetting) + .ToConcurrent(); + } + + + private async Task OnRoleCreated(SocketRole args) + { + if (GuildLogSettings.TryGetValue(args.Guild.Id, out var logSetting)) + { + if (logSetting.RoleCreatedId is null or 0) + return; + + var channel = args.Guild.GetTextChannel(logSetting.RoleCreatedId.Value); + + if (channel is null) + return; + + await Task.Delay(500); + + var auditLogs = await args.Guild.GetAuditLogsAsync(1, actionType: ActionType.RoleCreated).FlattenAsync(); + + var eb = new EmbedBuilder() + .WithOkColor() + .WithTitle("Role Created") + .WithDescription($"`Name:` {args.Name}\n" + + $"`Id:` {args.Id}\n" + + $"`Color:` {args.Color}\n" + + $"`Hoisted:` {args.IsHoisted}\n" + + $"`Mentionable:` {args.IsMentionable}\n" + + $"`Position:` {args.Position}\n" + + $"`Permissions:` {string.Join(", ", args.Permissions.ToList())}\n" + + $"`Created By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}\n" + + $"`Managed:` {args.IsManaged}"); + + await channel.SendMessageAsync(embed: eb.Build()); + } + } + + private async Task OnGuildUpdated(SocketGuild args, SocketGuild arsg2) + { + if (GuildLogSettings.TryGetValue(args.Id, out var logSetting)) + { + if (logSetting.ServerUpdatedId is null or 0) + return; + + var channel = args.GetTextChannel(logSetting.ServerUpdatedId.Value); + + if (channel is null) + return; + + await Task.Delay(500); + + var auditLogs = await args.GetAuditLogsAsync(1, actionType: ActionType.GuildUpdated).FlattenAsync(); + + var eb = new EmbedBuilder(); + + if (args.Name != arsg2.Name) + { + eb = new EmbedBuilder() + .WithOkColor() + .WithTitle("Server Name Updated") + .WithDescription($"`New Name:` {arsg2.Name}\n" + + $"`Old Name:` {args.Name}\n" + + $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); + } + + if (args.IconUrl != arsg2.IconUrl) + { + eb = new EmbedBuilder() + .WithOkColor() + .WithTitle("Server Icon Updated") + .WithDescription( + $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}") + .WithThumbnailUrl(args.IconUrl) + .WithImageUrl(arsg2.IconUrl); + } + + if (args.BannerUrl != arsg2.BannerUrl) + { + eb = new EmbedBuilder() + .WithOkColor() + .WithTitle("Server Banner Updated") + .WithDescription( + $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}") + .WithThumbnailUrl(args.BannerUrl) + .WithImageUrl(arsg2.BannerUrl); + } + + if (args.SplashUrl != arsg2.SplashUrl) + { + eb = new EmbedBuilder() + .WithOkColor() + .WithTitle("Server Splash Updated") + .WithDescription( + $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}") + .WithThumbnailUrl(args.SplashUrl) + .WithImageUrl(arsg2.SplashUrl); + } + + if (args.VanityURLCode != arsg2.VanityURLCode) + { + eb = new EmbedBuilder() + .WithOkColor() + .WithTitle("Server Vanity URL Updated") + .WithDescription($"`New Vanity URL:` {arsg2.VanityURLCode}\n" + + $"`Old Vanity URL:` {args.VanityURLCode}\n" + + $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); + } + + if (args.OwnerId != arsg2.OwnerId) + { + eb = new EmbedBuilder() + .WithOkColor() + .WithTitle("Server Owner Updated") + .WithDescription($"`New Owner:` {arsg2.Owner.Mention} | {arsg2.Owner.Id}\n" + + $"`Old Owner:` {args.Owner.Mention} | {args.Owner.Id}\n" + + $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); + } + + if (args.AFKChannel != arsg2.AFKChannel) + { + eb = new EmbedBuilder() + .WithOkColor() + .WithTitle("Server AFK Channel Updated") + .WithDescription($"`New AFK Channel:` {arsg2.AFKChannel.Mention} | {arsg2.AFKChannel.Id}\n" + + $"`Old AFK Channel:` {args.AFKChannel.Mention} | {args.AFKChannel.Id}\n" + + $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); + } + + if (args.AFKTimeout != arsg2.AFKTimeout) + { + eb = new EmbedBuilder() + .WithOkColor() + .WithTitle("Server AFK Timeout Updated") + .WithDescription($"`New AFK Timeout:` {arsg2.AFKTimeout}\n" + + $"`Old AFK Timeout:` {args.AFKTimeout}\n" + + $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); + } + + if (args.DefaultMessageNotifications != arsg2.DefaultMessageNotifications) + { + eb = new EmbedBuilder() + .WithOkColor() + .WithTitle("Server Default Message Notifications Updated") + .WithDescription($"`New Default Message Notifications:` {arsg2.DefaultMessageNotifications}\n" + + $"`Old Default Message Notifications:` {args.DefaultMessageNotifications}\n" + + $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); + } + + if (args.ExplicitContentFilter != arsg2.ExplicitContentFilter) + { + eb = new EmbedBuilder() + .WithOkColor() + .WithTitle("Server Explicit Content Filter Updated") + .WithDescription($"`New Explicit Content Filter:` {arsg2.ExplicitContentFilter}\n" + + $"`Old Explicit Content Filter:` {args.ExplicitContentFilter}\n" + + $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); + } + + if (args.MfaLevel != arsg2.MfaLevel) + { + eb = new EmbedBuilder() + .WithOkColor() + .WithTitle("Server MFA Level Updated") + .WithDescription($"`New MFA Level:` {arsg2.MfaLevel}\n" + + $"`Old MFA Level:` {args.MfaLevel}\n" + + $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); + } + + if (args.VerificationLevel != arsg2.VerificationLevel) + { + eb = new EmbedBuilder() + .WithOkColor() + .WithTitle("Server Verification Level Updated") + .WithDescription($"`New Verification Level:` {arsg2.VerificationLevel}\n" + + $"`Old Verification Level:` {args.VerificationLevel}\n" + + $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); + } + + if (args.SystemChannel != arsg2.SystemChannel) + { + eb = new EmbedBuilder() + .WithOkColor() + .WithTitle("Server System Channel Updated") + .WithDescription( + $"`New System Channel:` {arsg2.SystemChannel.Mention} | {arsg2.SystemChannel.Id}\n" + + $"`Old System Channel:` {args.SystemChannel.Mention} | {args.SystemChannel.Id}\n" + + $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); + } + + if (args.RulesChannel != arsg2.RulesChannel) + { + eb = new EmbedBuilder() + .WithOkColor() + .WithTitle("Server Rules Channel Updated") + .WithDescription($"`New Rules Channel:` {arsg2.RulesChannel.Mention} | {arsg2.RulesChannel.Id}\n" + + $"`Old Rules Channel:` {args.RulesChannel.Mention} | {args.RulesChannel.Id}\n" + + $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); + } + + if (args.PublicUpdatesChannel != arsg2.PublicUpdatesChannel) + { + eb = new EmbedBuilder() + .WithOkColor() + .WithTitle("Server Public Updates Channel Updated") + .WithDescription( + $"`New Public Updates Channel:` {arsg2.PublicUpdatesChannel.Mention} | {arsg2.PublicUpdatesChannel.Id}\n" + + $"`Old Public Updates Channel:` {args.PublicUpdatesChannel.Mention} | {args.PublicUpdatesChannel.Id}\n" + + $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); + } + + if (args.MaxVideoChannelUsers != arsg2.MaxVideoChannelUsers) + { + eb = new EmbedBuilder() + .WithOkColor() + .WithTitle("Server Max Video Channel Users Updated") + .WithDescription($"`New Max Video Channel Users:` {arsg2.MaxVideoChannelUsers}\n" + + $"`Old Max Video Channel Users:` {args.MaxVideoChannelUsers}\n" + + $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); + } + + if (args.MaxMembers != arsg2.MaxMembers) + { + eb = new EmbedBuilder() + .WithOkColor() + .WithTitle("Server Max Members Updated") + .WithDescription($"`New Max Members:` {arsg2.MaxMembers}\n" + + $"`Old Max Members:` {args.MaxMembers}\n" + + $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); + } + + await channel.SendMessageAsync(embed: eb.Build()); + } + } + + private async Task OnRoleDeleted(SocketRole args) + { + if (GuildLogSettings.TryGetValue(args.Guild.Id, out var logSetting)) + { + if (logSetting.RoleDeletedId is null or 0) + return; + + var channel = args.Guild.GetTextChannel(logSetting.RoleDeletedId.Value); + + if (channel is null) + return; + + await Task.Delay(500); + + var auditLogs = await args.Guild.GetAuditLogsAsync(1, actionType: ActionType.GuildUpdated).FlattenAsync(); + + + var eb = new EmbedBuilder() + .WithOkColor() + .WithTitle("Role Deleted") + .WithDescription($"`Role:` {args.Name}\n" + + $"`Deleted By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}\n" + + $"`Deleted At:` {DateTime.UtcNow}\n" + + $"`Members:` {args.Members.Count()}"); + + await channel.SendMessageAsync(embed: eb.Build()); + } + } + + private async Task OnRoleUpdated(SocketRole args, SocketRole arsg2) + { + if (GuildLogSettings.TryGetValue(args.Guild.Id, out var logSetting)) + { + if (logSetting.RoleUpdatedId is null or 0) + return; + + var channel = args.Guild.GetTextChannel(logSetting.RoleUpdatedId.Value); + + if (channel is null) + return; + + await Task.Delay(500); + + var auditLogs = await args.Guild.GetAuditLogsAsync(1, actionType: ActionType.RoleUpdated).FlattenAsync(); + + var eb = new EmbedBuilder(); + + if (args.Name != arsg2.Name) + { + eb = new EmbedBuilder() + .WithOkColor() + .WithTitle("Role Name Updated") + .WithDescription($"`New Role Name:` {arsg2.Name}\n" + + $"`Old Role Name:` {args.Name}\n" + + $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); + } + + if (args.Color != arsg2.Color) + { + eb = new EmbedBuilder() + .WithColor(arsg2.Color) + .WithTitle("Role Color Updated") + .WithDescription($"`New Role Color:` {arsg2.Color}\n" + + $"`Old Role Color:` {args.Color}\n" + + $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); + } + + if (args.IsHoisted != arsg2.IsHoisted) + { + eb = new EmbedBuilder() + .WithOkColor() + .WithTitle("Role Property Hoisted Updated") + .WithDescription($"`New Role Hoisted:` {arsg2.IsHoisted}\n" + + $"`Old Role Hoisted:` {args.IsHoisted}\n" + + $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); + } + + if (args.IsMentionable != arsg2.IsMentionable) + { + eb = new EmbedBuilder() + .WithOkColor() + .WithTitle("Role Property Mentionable Updated") + .WithDescription($"`New Role Mentionable:` {arsg2.IsMentionable}\n" + + $"`Old Role Mentionable:` {args.IsMentionable}\n" + + $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); + } + + if (args.IsManaged != arsg2.IsManaged) + { + eb = new EmbedBuilder() + .WithOkColor() + .WithTitle("Role Property Managed Updated") + .WithDescription($"`New Role Managed:` {arsg2.IsManaged}\n" + + $"`Old Role Managed:` {args.IsManaged}\n" + + $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); + } + + if (args.Position != arsg2.Position) + { + eb = new EmbedBuilder() + .WithOkColor() + .WithTitle("Role Position Updated") + .WithDescription($"`New Role Position:` {arsg2.Position}\n" + + $"`Old Role Position:` {args.Position}\n" + + $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); + } + + if (!arsg2.Permissions.Equals(args.Permissions)) + { + eb = new EmbedBuilder() + .WithOkColor() + .WithTitle("Role Permissions Updated") + .WithDescription($"`New Role Permissions:` {arsg2.Permissions}\n" + + $"`Old Role Permissions:` {args.Permissions}\n" + + $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); + } + + if (args.Icon != arsg2.Icon) + { + eb = new EmbedBuilder() + .WithOkColor() + .WithTitle("Role Icon Updated") + .WithDescription( + $"`Updated By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}") + .WithThumbnailUrl(args.GetIconUrl()) + .WithImageUrl(arsg2.GetIconUrl()); + } + + await channel.SendMessageAsync(embed: eb.Build()); + } + } + + private async Task OnEventCreated(SocketGuildEvent args) + { + if (GuildLogSettings.TryGetValue(args.Guild.Id, out var logSetting)) + { + if (logSetting.EventCreatedId is null or 0) + return; + + var channel = args.Guild.GetTextChannel(logSetting.EventCreatedId.Value); + + if (channel is null) + return; + + var eb = new EmbedBuilder() + .WithOkColor() + .WithTitle("Event Created") + .WithDescription($"`Event:` {args.Name}\n" + + $"`Created By:` {args.Creator.Mention} | {args.Creator.Id}\n" + + $"`Created At:` {DateTime.UtcNow}\n" + + $"`Description:` {args.Description}\n" + + $"`Event Date:` {args.StartTime}\n" + + $"`End Date:` {args.EndTime}\n" + + $"`Event Location:` {args.Location}\n" + + $"`Event Type:` {args.Type}\n" + + $"`Event Id:` {args.Id}") + .WithImageUrl(args.GetCoverImageUrl()); + + await channel.SendMessageAsync(embed: eb.Build()); + } + } + + private async Task OnThreadCreated(SocketThreadChannel socketThreadChannel) + { + if (GuildLogSettings.TryGetValue(socketThreadChannel.Guild.Id, out var logSetting)) + { + if (logSetting.ThreadCreatedId is null or 0) + return; + + var channel = socketThreadChannel.Guild.GetTextChannel(logSetting.ThreadCreatedId.Value); + + if (channel is null) + return; + + var eb = new EmbedBuilder() + .WithOkColor() + .WithTitle("Thread Created") + .WithDescription($"`Name:` {socketThreadChannel.Name}\n" + + $"`Created By:` {socketThreadChannel.Owner.Mention} | {socketThreadChannel.Owner.Id}\n" + + $"`Created At:` {DateTime.UtcNow}\n" + + $"`Thread Type:` {socketThreadChannel.Type}\n" + + $"`Thread Tags:` {socketThreadChannel.AppliedTags}"); + + await channel.SendMessageAsync(embed: eb.Build()); + } + } + + private async Task OnUserRoleAdded(Cacheable cacheable, SocketGuildUser arsg2) + { + if (GuildLogSettings.TryGetValue(arsg2.Guild.Id, out var logSetting)) + { + if (!cacheable.HasValue) return; + if (logSetting.UserRoleAddedId is null or 0) + return; + + var channel = arsg2.Guild.GetTextChannel(logSetting.UserRoleAddedId.Value); + + if (channel is null) + return; + + await Task.Delay(500); + var auditLogs = await arsg2.Guild.GetAuditLogsAsync(1, actionType: ActionType.MemberRoleUpdated) + .FlattenAsync(); + + var added = arsg2.Roles.Except(cacheable.Value.Roles); + if (!added.Any()) + return; + + var eb = new EmbedBuilder() + .WithOkColor() + .WithTitle("User Role(s) Added") + .WithDescription($"`Role(s):` {string.Join(",", added.Select(x => $"{x.Mention}"))}\n" + + $"`Added By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); + + await channel.SendMessageAsync(embed: eb.Build()); + } + } + + private async Task OnUserRoleRemoved(Cacheable cacheable, SocketGuildUser arsg2) + { + if (GuildLogSettings.TryGetValue(arsg2.Guild.Id, out var logSetting)) + { + if (!cacheable.HasValue) return; + if (logSetting.UserRoleRemovedId is null or 0) + return; + + var channel = arsg2.Guild.GetTextChannel(logSetting.UserRoleRemovedId.Value); + + if (channel is null) + return; + + await Task.Delay(500); + var auditLogs = await arsg2.Guild.GetAuditLogsAsync(1, actionType: ActionType.MemberRoleUpdated) + .FlattenAsync(); + + var removed = arsg2.Roles.Except(cacheable.Value.Roles); + if (!removed.Any()) return; + + var eb = new EmbedBuilder() + .WithOkColor() + .WithTitle("User Role(s) Removed") + .WithDescription($"`Role(s):` {string.Join(",", removed.Select(x => $"{x.Mention}"))}\n" + + $"`Added By:` {auditLogs.FirstOrDefault().User.Mention} | {auditLogs.FirstOrDefault().User.Id}"); + + await channel.SendMessageAsync(embed: eb.Build()); + } + } + + private async Task OnUsernameUpdated(SocketUser args, SocketUser arsg2) + { + if (args is not SocketGuildUser user) + return; + if (args.Username.Equals(arsg2.Username)) + return; + + if (GuildLogSettings.TryGetValue(user.Guild.Id, out var logSetting)) + { + if (logSetting.UsernameUpdatedId is null or 0) + return; + + var channel = user.Guild.GetTextChannel(logSetting.UsernameUpdatedId.Value); + + if (channel is null) + return; + + var eb = new EmbedBuilder() + .WithOkColor() + .WithTitle("Username Updated") + .WithDescription( + $"`Old Username:` {args.Username}\n" + + $"`New Username:` {arsg2.Username}"); + + await channel.SendMessageAsync(embed: eb.Build()); + } + } + + private async Task OnNicknameUpdated(Cacheable cacheable, SocketGuildUser arsg2) + { + if (!cacheable.HasValue) return; + if (GuildLogSettings.TryGetValue(arsg2.Guild.Id, out var logSetting)) + { + if (cacheable.Value.Nickname.Equals(arsg2.Nickname)) + return; + + if (logSetting.NicknameUpdatedId is null or 0) + return; + + var auditLogs = await arsg2.Guild.GetAuditLogsAsync(1, actionType: ActionType.MemberUpdated).FlattenAsync(); + + var entry = auditLogs.FirstOrDefault(); + + var channel = arsg2.Guild.GetTextChannel(logSetting.NicknameUpdatedId.Value); + + if (channel is null) + return; + + var eb = new EmbedBuilder() + .WithOkColor() + .WithTitle("Nickname Updated") + .WithDescription( + $"`Old Nickname:` {cacheable.Value.Nickname ?? cacheable.Value.Username}\n" + + $"`New Nickname:` {arsg2.Nickname ?? arsg2.Username}" + + $"`Updated By:` {entry.User.Mention} | {entry.User.Id}"); + + await channel.SendMessageAsync(embed: eb.Build()); + } + } + + private async Task OnThreadDeleted(Cacheable args) + { + if (!args.HasValue) return; + if (GuildLogSettings.TryGetValue(args.Value.Guild.Id, out var logSetting)) + { + if (logSetting.ThreadDeletedId is null or 0) + return; + + var channel = args.Value.Guild.GetTextChannel(logSetting.ThreadDeletedId.Value); + + if (channel is null) + return; + + var auditLogs = await args.Value.Guild.GetAuditLogsAsync(1, actionType: ActionType.ThreadDelete) + .FlattenAsync(); + + var entry = auditLogs.FirstOrDefault(); + + var eb = new EmbedBuilder() + .WithOkColor() + .WithTitle("Thread Deleted") + .WithDescription( + $"`Thread Name:` {args.Value.Name}\n" + + $"`Thread Id:` {args.Value.Id}" + + $"`Deleted By:` {entry.User.Mention} | {entry.User.Id}"); + + await channel.SendMessageAsync(embed: eb.Build()); + } + } + + private async Task OnThreadUpdated(Cacheable cacheable, SocketThreadChannel arsg2) + { + if (!cacheable.HasValue) return; + var oldThread = cacheable.Value; + if (GuildLogSettings.TryGetValue(arsg2.Guild.Id, out var logSetting)) + { + if (logSetting.ThreadUpdatedId is null or 0) + return; + + var channel = arsg2.Guild.GetTextChannel(logSetting.ThreadUpdatedId.Value); + + if (channel is null) + return; + + var auditLogs = await arsg2.Guild.GetAuditLogsAsync(1, actionType: ActionType.ThreadUpdate).FlattenAsync(); + + var entry = auditLogs.FirstOrDefault(); + + var eb = new EmbedBuilder(); + + if (oldThread.Name != arsg2.Name) + eb.WithOkColor() + .WithTitle("Thread Name Updated") + .WithDescription( + $"`Old Thread Name:` {oldThread.Name}\n" + + $"`New Thread Name:` {arsg2.Name}" + + $"`Updated By:` {entry.User.Mention} | {entry.User.Id}"); + + if (oldThread.IsArchived != arsg2.IsArchived) + eb.WithOkColor() + .WithTitle("Thread Archival Status Updated") + .WithDescription($"Before: {oldThread.IsArchived}\n" + + $"After: {arsg2.IsArchived}\n" + + $"`Updated By:` {entry.User.Mention} | {entry.User.Id}"); + + if (oldThread.IsLocked != arsg2.IsLocked) + eb.WithOkColor() + .WithTitle("Thread Lock Status Updated") + .WithDescription($"Before: {oldThread.IsLocked}\n" + + $"After: {arsg2.IsLocked}\n" + + $"`Updated By:` {entry.User.Mention} | {entry.User.Id}"); + + await channel.SendMessageAsync(embed: eb.Build()); + } + } + + private async Task OnMessageUpdated(Cacheable cacheable, SocketMessage args2, + ISocketMessageChannel args3) + { + if (!cacheable.HasValue) return; + var oldMessage = cacheable.Value; + if (args3 is not SocketTextChannel guildChannel) + return; + if (GuildLogSettings.TryGetValue(guildChannel.Guild.Id, out var logSetting)) + { + if (logSetting.MessageUpdatedId is null or 0) + return; + + var channel = guildChannel.Guild.GetTextChannel(logSetting.MessageUpdatedId.Value); + + if (channel is null) + return; + + var eb = new EmbedBuilder() + .WithOkColor() + .WithTitle("Message Updated") + .WithDescription( + $"`Message Author:` {oldMessage.Author.Mention}\n" + + $"`Message Channel:` {guildChannel.Mention} | {guildChannel.Id}\n" + + $"`Message Id:` {oldMessage.Id}\n" + + $"`Old Message Content:` {oldMessage.Content}\n" + + $"`Updated Message Content:` {args2.Content}"); + + var component = new ComponentBuilder() + .WithButton("Jump to Message", style: ButtonStyle.Link, url: oldMessage.GetJumpUrl()).Build(); + + await channel.SendMessageAsync(embed: eb.Build(), components: component); + } + } + + private async Task OnMessageDeleted(Cacheable args, Cacheable arsg2) + { + if (!args.HasValue) return; + if (args.Value is not SocketUserMessage message) return; + if (args.Value.Channel is not SocketTextChannel guildChannel) return; + if (GuildLogSettings.TryGetValue(guildChannel.Guild.Id, out var logSetting)) + { + if (logSetting.MessageDeletedId is null or 0) + return; + + var channel = guildChannel.Guild.GetTextChannel(logSetting.MessageDeletedId.Value); + + var auditLogs = await guildChannel.Guild.GetAuditLogsAsync(1, actionType: ActionType.MessageDeleted) + .FlattenAsync(); + + var entry = auditLogs.FirstOrDefault(); + + var eb = new EmbedBuilder() + .WithOkColor() + .WithTitle("Message Deleted") + .WithDescription( + $"`Message Author:` {message.Author.Mention}\n" + + $"`Message Channel:` {guildChannel.Mention} | {guildChannel.Id}\n" + + $"`Message Content:` {message.Content}\n" + + $"`Deleted By:` {(entry is null ? message.Author.Mention : entry.User.Mention)} | {(entry is null ? message.Author.Id : entry.User.Id)}"); + + await channel.SendMessageAsync(embed: eb.Build()); + } + } + + private async Task OnUserJoined(IGuildUser guildUser) + { + if (GuildLogSettings.TryGetValue(guildUser.Guild.Id, out var logSetting)) + { + if (logSetting.UserJoinedId is null or 0) + return; + + var channel = await guildUser.Guild.GetTextChannelAsync(logSetting.UserJoinedId.Value); + + if (channel is null) + return; + + var eb = new EmbedBuilder() + .WithOkColor() + .WithTitle("User Joined") + .WithDescription( + $"`User:` {guildUser.Mention} | {guildUser.Id}\n" + + $"`Account Created:` {guildUser.CreatedAt:dd/MM/yyyy}\n" + + $"`Joined Server:` {guildUser.JoinedAt:dd/MM/yyyy}\n" + + $"`User Status:` {guildUser.Status}" + + $"`User Id:` {guildUser.Id}" + + $"`User Global Name:` {guildUser.GlobalName ?? guildUser.Username}") + .WithThumbnailUrl(guildUser.RealAvatarUrl().ToString()); + + var component = new ComponentBuilder() + .WithButton("View User", style: ButtonStyle.Link, url: $"discord://-/users/{guildUser.Id}").Build(); + + await channel.SendMessageAsync(components: component, embed: eb.Build()); + } + } + + private async Task OnUserLeft(IGuild guild, IUser arsg2) + { + if (arsg2 is not SocketGuildUser usr) return; + if (GuildLogSettings.TryGetValue(guild.Id, out var logSetting)) + { + if (logSetting.UserLeftId is null or 0) + return; + + var channel = await guild.GetTextChannelAsync(logSetting.UserLeftId.Value); + + if (channel is null) + return; + + var eb = new EmbedBuilder() + .WithOkColor() + .WithTitle("User Left") + .WithDescription( + $"`User:` {usr.Mention} | {usr.Id}\n" + + $"`User Id:` {usr.Id}" + + $"`User Global Name:` {arsg2.GlobalName ?? arsg2.Username}" + + $"`Account Created:` {usr.CreatedAt:dd/MM/yyyy}\n" + + $"`Joined Server:` {usr.JoinedAt:dd/MM/yyyy}\n" + + $"`Roles:` {string.Join(", ", usr.Roles.Select(x => x.Mention))}") + .WithThumbnailUrl(arsg2.RealAvatarUrl().ToString()); + + var component = new ComponentBuilder().WithButton("View User (May not work)", style: ButtonStyle.Link, + url: $"discord://-/users/{arsg2.Id}").Build(); + + await channel.SendMessageAsync(components: component, embed: eb.Build()); + } + } + + private async Task OnUserBanned(SocketUser args, SocketGuild arsg2) + { + if (args is not SocketGuildUser usr) return; + if (GuildLogSettings.TryGetValue(arsg2.Id, out var logSetting)) + { + if (logSetting.UserBannedId is null or 0) + return; + + var channel = usr.Guild.GetTextChannel(logSetting.UserBannedId.Value); + + if (channel is null) + return; + + var auditLogs = await arsg2.GetAuditLogsAsync(1, actionType: ActionType.Ban).FlattenAsync(); + + var entry = auditLogs.FirstOrDefault(); + + var eb = new EmbedBuilder() + .WithOkColor() + .WithTitle("User Banned") + .WithDescription( + $"`User:` {args.Mention} | {args.Id}\n" + + $"`User Id:` {args.Id}" + + $"`User Global Name:` {args.GlobalName ?? args.Username}" + + $"`Account Created:` {args.CreatedAt:dd/MM/yyyy}\n" + + $"`Joined Server:` {usr.JoinedAt:dd/MM/yyyy}\n" + + $"`Roles:` {string.Join(", ", usr.Roles.Select(x => x.Mention))}\n" + + $"`Banned By:` {entry.User.Mention} | {entry.User.Id}") + .WithThumbnailUrl(args.RealAvatarUrl().ToString()); + + var component = new ComponentBuilder().WithButton("View User (May not work)", style: ButtonStyle.Link, + url: $"discord://-/users/{args.Id}").Build(); + + await channel.SendMessageAsync(components: component, embed: eb.Build()); + } + } + + private async Task OnUserUnbanned(SocketUser args, SocketGuild arsg2) + { + if (GuildLogSettings.TryGetValue(arsg2.Id, out var logSetting)) + { + if (logSetting.UserUnbannedId is null or 0) + return; + + var channel = arsg2.GetTextChannel(logSetting.UserUnbannedId.Value); + + if (channel is null) + return; + + var auditLogs = await arsg2.GetAuditLogsAsync(1, actionType: ActionType.Unban).FlattenAsync(); + + var entry = auditLogs.FirstOrDefault(); + + var eb = new EmbedBuilder() + .WithOkColor() + .WithTitle("User Unbanned") + .WithDescription( + $"`User:` {args.Mention} | {args.Id}\n" + + $"`User Id:` {args.Id}" + + $"`User Global Name:` {args.GlobalName ?? args.Username}" + + $"`Account Created:` {args.CreatedAt:dd/MM/yyyy}\n" + + $"`Unbanned By:` {entry.User.Mention} | {entry.User.Id}") + .WithThumbnailUrl(args.RealAvatarUrl().ToString()); + + var component = new ComponentBuilder().WithButton("View User (May not work)", style: ButtonStyle.Link, + url: $"discord://-/users/{args.Id}").Build(); + + await channel.SendMessageAsync(components: component, embed: eb.Build()); + } + } + + private async Task OnUserUpdated(SocketUser args, SocketUser arsg2) + { + if (args is not SocketGuildUser usr) return; + + if (GuildLogSettings.TryGetValue(usr.Guild.Id, out var logSetting)) + { + if (logSetting.UserUpdatedId is null or 0) + return; + + var channel = usr.Guild.GetTextChannel(logSetting.UserUpdatedId.Value); + + if (channel is null) + return; + + var eb = new EmbedBuilder(); + + if (args.AvatarId != arsg2.AvatarId) + eb.WithOkColor() + .WithTitle("User Avatar Updated") + .WithThumbnailUrl(args.RealAvatarUrl().ToString()) + .WithImageUrl(arsg2.RealAvatarUrl().ToString()); + + if (args.GlobalName != arsg2.GlobalName) + eb.WithOkColor() + .WithTitle("User Global Name Updated") + .WithDescription( + $"`User:` {args.Mention} | {args.Id}\n" + + $"`User Id:` {args.Id}" + + $"`User Global Name:` {args.GlobalName ?? args.Username}"); + + await channel.SendMessageAsync(embed: eb.Build()); + } + } + + private async Task OnChannelCreated(SocketChannel args) + { + if (args is not SocketGuildChannel channel) return; + + if (GuildLogSettings.TryGetValue(channel.Guild.Id, out var logSetting)) + { + if (logSetting.ChannelCreatedId is null or 0) + return; + + var logChannel = channel.Guild.GetTextChannel(logSetting.ChannelCreatedId.Value); + + if (logChannel is null) + return; + + string createdType; + + if (channel is SocketTextChannel) + createdType = "Text"; + else + switch (args) + { + case SocketVoiceChannel: + createdType = "Voice"; + break; + case SocketCategoryChannel: + createdType = "Category"; + break; + case SocketNewsChannel: + createdType = "News"; + break; + default: + { + createdType = channel is SocketStageChannel ? "Stage" : "Unknown"; + break; + } + } + + var auditLogs = await channel.Guild.GetAuditLogsAsync(1, actionType: ActionType.ChannelCreated) + .FlattenAsync(); + + var entry = auditLogs.FirstOrDefault(); + + var eb = new EmbedBuilder() + .WithOkColor() + .WithTitle("Channel Created") + .WithDescription( + $"`Channel:` {channel.Name} | {channel.Id}\n" + + $"`Channel Created By:` {entry.User.Mention} | {entry.User.Id}" + + $"`Channel Created At:` {channel.CreatedAt:dd/MM/yyyy}\n" + + $"`Channel Type:` {createdType}"); + + await logChannel.SendMessageAsync(embed: eb.Build()); + } + } + + private async Task OnChannelDestroyed(SocketChannel args) + { + if (args is not SocketGuildChannel channel) return; + + if (GuildLogSettings.TryGetValue(channel.Guild.Id, out var logSetting)) + { + if (logSetting.ChannelDestroyedId is null or 0) + return; + + var logChannel = channel.Guild.GetTextChannel(logSetting.ChannelDestroyedId.Value); + + if (logChannel is null) + return; + + string createdType; + + if (channel is SocketTextChannel) + createdType = "Text"; + else + switch (args) + { + case SocketVoiceChannel: + createdType = "Voice"; + break; + case SocketCategoryChannel: + createdType = "Category"; + break; + case SocketNewsChannel: + createdType = "News"; + break; + default: + { + createdType = channel is SocketStageChannel ? "Stage" : "Unknown"; + break; + } + } + + var auditLogs = await channel.Guild.GetAuditLogsAsync(1, actionType: ActionType.ChannelDeleted) + .FlattenAsync(); + + var entry = auditLogs.FirstOrDefault(); + + var eb = new EmbedBuilder() + .WithOkColor() + .WithTitle("Channel Destroyed") + .WithDescription( + $"`Channel:` {channel.Name} | {channel.Id}\n" + + $"`Channel Destroyed By:` {entry.User.Mention} | {entry.User.Id}" + + $"`Channel Destroyed At:` {DateTime.UtcNow:dd/MM/yyyy}\n" + + $"`Channel Type:` {createdType}"); + + await logChannel.SendMessageAsync(embed: eb.Build()); + } + } + + private async Task OnChannelUpdated(SocketChannel args, SocketChannel arsg2) + { + if (args is not SocketGuildChannel channel || arsg2 is not SocketGuildChannel channel2) return; + + if (GuildLogSettings.TryGetValue(channel.Guild.Id, out var logSetting)) + { + if (logSetting.ChannelUpdatedId is null or 0) + return; + + var logChannel = channel.Guild.GetTextChannel(logSetting.ChannelUpdatedId.Value); + + if (logChannel is null) + return; + + var audit = await channel.Guild.GetAuditLogsAsync(1, actionType: ActionType.ChannelUpdated).FlattenAsync(); + + var entry = audit.FirstOrDefault(); + + var eb = new EmbedBuilder() + .WithOkColor(); + + if (channel.Name != channel2.Name) + eb.WithTitle("Channel Name Updated") + .WithDescription( + $"`Old Name:` {channel.Name}\n" + + $"`New Name:` {channel2.Name}\n" + + $"`Channel Updated By:` {entry.User.Mention} | {entry.User.Id}"); + + if (channel.Position != channel2.Position) + eb.WithTitle("Channel Position Updated") + .WithDescription( + $"`Old Position:` {channel.Position}\n" + + $"`New Position:` {channel2.Position}\n" + + $"`Channel Updated By:` {entry.User.Mention} | {entry.User.Id}"); + + if (channel is SocketTextChannel textChannel && channel2 is SocketTextChannel textChannel2) + { + if (textChannel.Topic != textChannel2.Topic) + eb.WithTitle("Channel Topic Updated") + .WithDescription( + $"`Old Topic:` {textChannel.Topic}\n" + + $"`New Topic:` {textChannel2.Topic}\n" + + $"`Channel Updated By:` {entry.User.Mention} | {entry.User.Id}"); + + if (textChannel.IsNsfw != textChannel2.IsNsfw) + eb.WithTitle("Channel NSFW Updated") + .WithDescription( + $"`Old NSFW:` {textChannel.IsNsfw}\n" + + $"`New NSFW:` {textChannel2.IsNsfw}\n" + + $"`Channel Updated By:` {entry.User.Mention} | {entry.User.Id}"); + + if (textChannel.SlowModeInterval != textChannel2.SlowModeInterval) + eb.WithTitle("Channel Slowmode Interval Updated") + .WithDescription( + $"`Old Slowmode Interval:` {textChannel.SlowModeInterval}\n" + + $"`New Slowmode Interval:` {textChannel2.SlowModeInterval}\n" + + $"`Channel Updated By:` {entry.User.Mention} | {entry.User.Id}"); + + if (textChannel.CategoryId != textChannel2.CategoryId) + eb.WithTitle("Channel Category Updated") + .WithDescription( + $"`Old Category:` {textChannel.Category}\n" + + $"`New Category:` {textChannel2.Category}\n" + + $"`Channel Updated By:` {entry.User.Mention} | {entry.User.Id}"); + } + + if (channel is SocketVoiceChannel voiceChannel && channel2 is SocketVoiceChannel voiceChannel2) + { + if (voiceChannel.Bitrate != voiceChannel2.Bitrate) + eb.WithTitle("Channel Bitrate Updated") + .WithDescription( + $"`Old Bitrate:` {voiceChannel.Bitrate}\n" + + $"`New Bitrate:` {voiceChannel2.Bitrate}\n" + + $"`Channel Updated By:` {entry.User.Mention} | {entry.User.Id}"); + + if (voiceChannel.UserLimit != voiceChannel2.UserLimit) + eb.WithTitle("Channel User Limit Updated") + .WithDescription( + $"`Old User Limit:` {voiceChannel.UserLimit}\n" + + $"`New User Limit:` {voiceChannel2.UserLimit}\n" + + $"`Channel Updated By:` {entry.User.Mention} | {entry.User.Id}"); + + if (voiceChannel.CategoryId != voiceChannel2.CategoryId) + eb.WithTitle("Channel Category Updated") + .WithDescription( + $"`Old Category:` {voiceChannel.Category}\n" + + $"`New Category:` {voiceChannel2.Category}\n" + + $"`Channel Updated By:` {entry.User.Mention} | {entry.User.Id}"); + + if (voiceChannel.Position != voiceChannel2.Position) + eb.WithTitle("Channel Position Updated") + .WithDescription( + $"`Old Position:` {voiceChannel.Position}\n" + + $"`New Position:` {voiceChannel2.Position}\n" + + $"`Channel Updated By:` {entry.User.Mention} | {entry.User.Id}"); + + if (voiceChannel.VideoQualityMode != voiceChannel2.VideoQualityMode) + eb.WithTitle("Channel Video Quality Mode Updated") + .WithDescription( + $"`Old Video Quality Mode:` {voiceChannel.VideoQualityMode}\n" + + $"`New Video Quality Mode:` {voiceChannel2.VideoQualityMode}\n" + + $"`Channel Updated By:` {entry.User.Mention} | {entry.User.Id}"); + + if (voiceChannel.RTCRegion != voiceChannel2.RTCRegion) + eb.WithTitle("Channel RTC Region Updated") + .WithDescription( + $"`Old RTC Region:` {voiceChannel.RTCRegion}\n" + + $"`New RTC Region:` {voiceChannel2.RTCRegion}\n" + + $"`Channel Updated By:` {entry.User.Mention} | {entry.User.Id}"); + } + + await logChannel.SendMessageAsync(embed: eb.Build()); + } + } + + private async Task OnVoicePresence(SocketUser args, SocketVoiceState args2, SocketVoiceState args3) + { + if (args.IsBot) + return; + + if (args is not IGuildUser guildUser) + return; + + if (GuildLogSettings.TryGetValue(guildUser.Guild.Id, out var logSetting)) + { + if (logSetting.LogVoicePresenceId is null or 0) + return; + + var logChannel = await guildUser.Guild.GetTextChannelAsync(logSetting.LogVoicePresenceId.Value); + + if (logChannel is null) + return; + + var eb = new EmbedBuilder(); + + if (args2.VoiceChannel is not null && args3.VoiceChannel is not null) + eb.WithTitle("User Moved Voice Channels") + .WithDescription( + $"`User:` {args.Mention} | {args.Id}\n" + + $"`Old Channel:` {args2.VoiceChannel.Name}\n" + + $"`New Channel:` {args3.VoiceChannel.Name}"); + + if (args2.VoiceChannel is null && args3.VoiceChannel is not null) + eb.WithTitle("User Joined Voice Channel") + .WithDescription( + $"`User:` {args.Mention} | {args.Id}\n" + + $"`Channel:` {args3.VoiceChannel.Name}"); + + if (args2.VoiceChannel is not null && args3.VoiceChannel is null) + eb.WithTitle("User Left Voice Channel") + .WithDescription( + $"`User:` {args.Mention} | {args.Id}\n" + + $"`Channel:` {args2.VoiceChannel.Name}"); + + if (!args2.IsDeafened && args3.IsDeafened) + eb.WithTitle($"User {(!args3.IsSelfDeafened ? "Server Voice Deafened" : "Self Voice Deafened")}") + .WithDescription( + $"`User:` {args.Mention} | {args.Id}\n" + + $"`Channel:` {args2.VoiceChannel.Name}"); + + if (args2.IsDeafened && !args3.IsDeafened) + eb.WithTitle("User UnDeafened") + .WithDescription( + $"`User:` {args.Mention} | {args.Id}\n" + + $"`Channel:` {args2.VoiceChannel.Name}"); + + if (!args2.IsMuted && args3.IsMuted) + eb.WithTitle($"User {(!args3.IsSelfMuted ? "Server Voice Muted" : "Self Voice Muted")}") + .WithDescription( + $"`User:` {args.Mention} | {args.Id}\n" + + $"`Channel:` {args2.VoiceChannel.Name}"); + + if (args2.IsMuted && !args3.IsMuted) + eb.WithTitle("User Voice UnMuted") + .WithDescription( + $"`User:` {args.Mention} | {args.Id}\n" + + $"`Channel:` {args2.VoiceChannel.Name}"); + + + await logChannel.SendMessageAsync(embed: eb.Build()); + } + } + + private async Task OnVoicePresenceTts(SocketUser args, SocketVoiceState args2, SocketVoiceState args3) + { + throw new NotImplementedException(); + } + + private async Task OnUserMuted(IGuildUser guildUser, IUser args2, MuteType args3, string args4) + { + throw new NotImplementedException(); + } + + private async Task OnUserUnmuted(IGuildUser args, IUser args2, MuteType args3, string args4) + { + throw new NotImplementedException(); + } + + public async Task SetLogChannel(ulong guildId, ulong channelId, LogType type) + { + await using var uow = db.GetDbContext(); + var logSetting = (await uow.LogSettingsFor(guildId)).LogSetting; + switch (type) + { + case LogType.Other: + logSetting.LogOtherId = channelId; + break; + case LogType.EventCreated: + logSetting.EventCreatedId = channelId; + break; + case LogType.RoleUpdated: + logSetting.RoleUpdatedId = channelId; + break; + case LogType.RoleCreated: + logSetting.RoleCreatedId = channelId; + break; + case LogType.ServerUpdated: + logSetting.ServerUpdatedId = channelId; + break; + case LogType.ThreadCreated: + logSetting.ThreadCreatedId = channelId; + break; + case LogType.UserRoleAdded: + logSetting.UserRoleAddedId = channelId; + break; + case LogType.UserRoleRemoved: + logSetting.UserRoleRemovedId = channelId; + break; + case LogType.UsernameUpdated: + logSetting.UsernameUpdatedId = channelId; + break; + case LogType.NicknameUpdated: + logSetting.NicknameUpdatedId = channelId; + break; + case LogType.ThreadDeleted: + logSetting.ThreadDeletedId = channelId; + break; + case LogType.ThreadUpdated: + logSetting.ThreadUpdatedId = channelId; + break; + case LogType.MessageUpdated: + logSetting.MessageUpdatedId = channelId; + break; + case LogType.MessageDeleted: + logSetting.MessageDeletedId = channelId; + break; + case LogType.UserJoined: + logSetting.UserJoinedId = channelId; + break; + case LogType.UserLeft: + logSetting.UserLeftId = channelId; + break; + case LogType.UserBanned: + logSetting.UserBannedId = channelId; + break; + case LogType.UserUnbanned: + logSetting.UserUnbannedId = channelId; + break; + case LogType.UserUpdated: + logSetting.UserUpdatedId = channelId; + break; + case LogType.ChannelCreated: + logSetting.ChannelCreatedId = channelId; + break; + case LogType.ChannelDestroyed: + logSetting.ChannelDestroyedId = channelId; + break; + case LogType.ChannelUpdated: + logSetting.ChannelUpdatedId = channelId; + break; + case LogType.VoicePresence: + logSetting.LogVoicePresenceId = channelId; + break; + case LogType.VoicePresenceTts: + logSetting.LogVoicePresenceTTSId = channelId; + break; + case LogType.UserMuted: + logSetting.UserMutedId = channelId; + break; + } + + uow.LogSettings.Update(logSetting); + await uow.SaveChangesAsync(); + GuildLogSettings.AddOrUpdate(guildId, _ => logSetting, (_, _) => logSetting); + } + + public async Task LogSetByType(ulong guildId, ulong channelId, LogCategoryTypes categoryTypes) + { + await using var uow = db.GetDbContext(); + var logSetting = (await uow.LogSettingsFor(guildId)).LogSetting; + switch (categoryTypes) + { + case LogCategoryTypes.All: + logSetting.AvatarUpdatedId = channelId; + logSetting.ChannelCreatedId = channelId; + logSetting.ChannelDestroyedId = channelId; + logSetting.ChannelUpdatedId = channelId; + logSetting.EventCreatedId = channelId; + logSetting.LogOtherId = channelId; + logSetting.MessageDeletedId = channelId; + logSetting.MessageUpdatedId = channelId; + logSetting.NicknameUpdatedId = channelId; + logSetting.RoleCreatedId = channelId; + logSetting.RoleDeletedId = channelId; + logSetting.RoleUpdatedId = channelId; + logSetting.ServerUpdatedId = channelId; + logSetting.ThreadCreatedId = channelId; + logSetting.ThreadDeletedId = channelId; + logSetting.ThreadUpdatedId = channelId; + logSetting.UserBannedId = channelId; + logSetting.UserJoinedId = channelId; + logSetting.UserLeftId = channelId; + logSetting.UserMutedId = channelId; + logSetting.UsernameUpdatedId = channelId; + logSetting.UserUnbannedId = channelId; + logSetting.UserUpdatedId = channelId; + logSetting.LogUserPresenceId = channelId; + logSetting.LogVoicePresenceId = channelId; + logSetting.UserRoleAddedId = channelId; + logSetting.UserRoleRemovedId = channelId; + logSetting.LogVoicePresenceTTSId = channelId; + break; + case LogCategoryTypes.Users: + logSetting.NicknameUpdatedId = channelId; + logSetting.AvatarUpdatedId = channelId; + logSetting.UsernameUpdatedId = channelId; + logSetting.UserRoleAddedId = channelId; + logSetting.UserRoleRemovedId = channelId; + logSetting.LogVoicePresenceId = channelId; + break; + case LogCategoryTypes.Threads: + logSetting.ThreadCreatedId = channelId; + logSetting.ThreadDeletedId = channelId; + logSetting.ThreadUpdatedId = channelId; + break; + case LogCategoryTypes.Roles: + logSetting.RoleCreatedId = channelId; + logSetting.RoleDeletedId = channelId; + logSetting.RoleUpdatedId = channelId; + break; + case LogCategoryTypes.Server: + logSetting.ServerUpdatedId = channelId; + logSetting.EventCreatedId = channelId; + break; + case LogCategoryTypes.Channel: + logSetting.ChannelUpdatedId = channelId; + logSetting.ChannelCreatedId = channelId; + logSetting.ChannelDestroyedId = channelId; + break; + case LogCategoryTypes.Messages: + logSetting.MessageDeletedId = channelId; + logSetting.MessageUpdatedId = channelId; + break; + case LogCategoryTypes.Moderation: + logSetting.UserMutedId = channelId; + logSetting.UserBannedId = channelId; + logSetting.UserUnbannedId = channelId; + break; + case LogCategoryTypes.None: + logSetting.AvatarUpdatedId = 0; + logSetting.ChannelCreatedId = 0; + logSetting.ChannelDestroyedId = 0; + logSetting.ChannelUpdatedId = 0; + logSetting.EventCreatedId = 0; + logSetting.LogOtherId = 0; + logSetting.MessageDeletedId = 0; + logSetting.MessageUpdatedId = 0; + logSetting.NicknameUpdatedId = 0; + logSetting.RoleCreatedId = 0; + logSetting.RoleDeletedId = 0; + logSetting.RoleUpdatedId = 0; + logSetting.ServerUpdatedId = 0; + logSetting.ThreadCreatedId = 0; + logSetting.ThreadDeletedId = 0; + logSetting.ThreadUpdatedId = 0; + logSetting.UserBannedId = 0; + logSetting.UserJoinedId = 0; + logSetting.UserLeftId = 0; + logSetting.UserMutedId = 0; + logSetting.UsernameUpdatedId = 0; + logSetting.UserUnbannedId = 0; + logSetting.UserUpdatedId = 0; + logSetting.LogUserPresenceId = 0; + logSetting.LogVoicePresenceId = 0; + logSetting.UserRoleAddedId = 0; + logSetting.UserRoleRemovedId = 0; + logSetting.LogVoicePresenceTTSId = 0; + break; + } + + await uow.SaveChangesAsync(); + GuildLogSettings.AddOrUpdate(guildId, _ => logSetting, (_, _) => logSetting); + } +} \ No newline at end of file diff --git a/src/Mewdeko/Modules/Administration/SlashServerRecovery.cs b/src/Mewdeko/Modules/Administration/SlashServerRecovery.cs index 2ea966bb5..05fe5bbfc 100644 --- a/src/Mewdeko/Modules/Administration/SlashServerRecovery.cs +++ b/src/Mewdeko/Modules/Administration/SlashServerRecovery.cs @@ -118,8 +118,8 @@ await ctx.Interaction.FollowupWithFileAsync(new MemoryStream(qrCodeImage), } [ComponentInteraction("recoverykey", true)] - public async Task SendRecoveryKeyModal() - => await RespondWithModalAsync("recoverykeymodal"); + public Task SendRecoveryKeyModal() + => RespondWithModalAsync("recoverykeymodal"); [ModalInteraction("recoverykeymodal", true)] public async Task HandleRecoveryKey(RecoveryKeyModal modal) @@ -147,8 +147,8 @@ public async Task HandleRecoveryKey(RecoveryKeyModal modal) } [ComponentInteraction("2fa-verify-*", true)] - public async Task SendTwoFactorModal(string type) - => await RespondWithModalAsync($"twofactormodal-{type}"); + public Task SendTwoFactorModal(string type) + => RespondWithModalAsync($"twofactormodal-{type}"); [ModalInteraction("twofactormodal-*", true)] public async Task HandleTwoFactor(string type, TwoFactorModal modal) diff --git a/src/Mewdeko/Modules/Afk/Services/AFKService.cs b/src/Mewdeko/Modules/Afk/Services/AFKService.cs index bf8f087ea..ff56fce7e 100644 --- a/src/Mewdeko/Modules/Afk/Services/AFKService.cs +++ b/src/Mewdeko/Modules/Afk/Services/AFKService.cs @@ -34,7 +34,7 @@ public AfkService( eventHandler.MessageReceived += MessageReceived; eventHandler.MessageUpdated += MessageUpdated; eventHandler.UserIsTyping += UserTyping; - _ = Task.Run(async () => await StartTimedAfkLoop()); + _ = Task.Run(() => StartTimedAfkLoop()); } private async Task StartTimedAfkLoop() @@ -88,14 +88,9 @@ private async Task StartTimedAfkLoop() private async Task TimedAfkFinished(Database.Models.Afk afk) { - await using var uow = db.GetDbContext(); if (!IsAfk(afk.GuildId, afk.UserId)) { - var current1 = cache.GetAfkForGuild(afk.GuildId) ?? new List(); - current1.Remove(afk); - await cache.AddAfkToCache(afk.GuildId, current1).ConfigureAwait(false); - uow.Afk.Remove(afk); - await uow.SaveChangesAsync(); + await RemoveAfk(afk); return; } @@ -111,11 +106,7 @@ private async Task TimedAfkFinished(Database.Models.Afk afk) //ignored } - var current = cache.GetAfkForGuild(afk.GuildId) ?? new List(); - current.Remove(afk); - await cache.AddAfkToCache(afk.GuildId, current).ConfigureAwait(false); - uow.Afk.Remove(afk); - await uow.SaveChangesAsync(); + await RemoveAfk(afk); } public async Task OnReadyAsync() @@ -128,9 +119,9 @@ public async Task OnReadyAsync() var afk = allafk.FirstOrDefault(x => x.GuildId == i); if (afk is null) continue; - _ = Task.Run(async () => + _ = Task.Run(() => { - await cache.CacheAfk(i, allafk.Where(x => x.GuildId == i).ToList()).ConfigureAwait(false); + return cache.CacheAfk(i, allafk.Where(x => x.GuildId == i).ToList()); }); } @@ -317,7 +308,7 @@ public async Task GetAfkUsers(IGuild guild) => ? Array.Empty() : await cache.GetAfkForGuild(guild.Id).GroupBy(m => m.UserId) .Where(m => !string.IsNullOrEmpty(m.Last().Message)) - .Select(async m => await guild.GetUserAsync(m.Key).ConfigureAwait(false)) + .Select(m => guild.GetUserAsync(m.Key)) .WhenAll().ConfigureAwait(false); public async Task SetCustomAfkMessage(IGuild guild, string afkMessage) @@ -329,17 +320,6 @@ public async Task SetCustomAfkMessage(IGuild guild, string afkMessage) await guildSettings.UpdateGuildConfig(guild.Id, gc); } - public async Task TimedAfk( - IGuild guild, - IUser user, - string message, - TimeSpan time) - { - await AfkSet(guild, user as IGuildUser, message, 1).ConfigureAwait(false); - await Task.Delay(time.Milliseconds).ConfigureAwait(false); - await AfkSet(guild, user as IGuildUser, "", 0).ConfigureAwait(false); - } - public bool IsAfk(IGuild guild, IGuildUser user) { var afkmsg = GetAfkMessage(guild.Id, user.Id); @@ -480,9 +460,22 @@ public async Task AfkSet( await uow.SaveChangesAsync().ConfigureAwait(false); var current = cache.GetAfkForGuild(guildId) ?? new List(); current.Add(afk); + + await cache.AddAfkToCache(guildId, current).ConfigureAwait(false); } + private async Task RemoveAfk(Database.Models.Afk afk) + { + var current = cache.GetAfkForGuild(afk.GuildId) ?? new List(); + current.Remove(afk); + await cache.AddAfkToCache(afk.GuildId, current).ConfigureAwait(false); + + await using var uow = db.GetDbContext(); + uow.Afk.Remove(afk); + await uow.SaveChangesAsync(); + } + public IEnumerable GetAfkMessage(ulong gid, ulong uid) { var e = cache.GetAfkForGuild(gid); diff --git a/src/Mewdeko/Modules/Chat Triggers/Services/ChatTriggersService.cs b/src/Mewdeko/Modules/Chat Triggers/Services/ChatTriggersService.cs index 4a9878c66..ee26691fb 100644 --- a/src/Mewdeko/Modules/Chat Triggers/Services/ChatTriggersService.cs +++ b/src/Mewdeko/Modules/Chat Triggers/Services/ChatTriggersService.cs @@ -695,22 +695,22 @@ public async Task ResetCrReactions(ulong? maybeGuildId, int id) await uow.SaveChangesAsync().ConfigureAwait(false); } - private async Task UpdateInternalAsync(ulong? maybeGuildId, CTModel ct) + private Task UpdateInternalAsync(ulong? maybeGuildId, CTModel ct) { if (maybeGuildId is { } guildId) UpdateInternal(guildId, ct); else { _ = pubSub.Pub(gcrEditedKey, ct); - return; + return Task.CompletedTask; } // handle interaction updates if (ct.ApplicationCommandType == CtApplicationCommandType.None) - return; + return Task.CompletedTask; var guild = client.GetGuild(guildId); - await RegisterTriggersToGuildAsync(guild).ConfigureAwait(false); + return RegisterTriggersToGuildAsync(guild); } private void UpdateInternal(ulong? maybeGuildId, CTModel ct) diff --git a/src/Mewdeko/Modules/Chat Triggers/SlashChatTriggers.cs b/src/Mewdeko/Modules/Chat Triggers/SlashChatTriggers.cs index 5b4a9ad13..93f289a43 100644 --- a/src/Mewdeko/Modules/Chat Triggers/SlashChatTriggers.cs +++ b/src/Mewdeko/Modules/Chat Triggers/SlashChatTriggers.cs @@ -79,8 +79,8 @@ public async Task CtsImport( // respond with a modal to support multiline responces. [SlashCommand("add", "Add new chat trigger."), SlashUserPerm(GuildPermission.Administrator), CheckPermissions] - public async Task AddChatTrigger([Summary("regex", "Should the trigger use regex.")] bool regex = false) - => await RespondWithModalAsync($"chat_trigger_add:{regex}").ConfigureAwait(false); + public Task AddChatTrigger([Summary("regex", "Should the trigger use regex.")] bool regex = false) + => RespondWithModalAsync($"chat_trigger_add:{regex}"); [ModalInteraction("chat_trigger_add:*", true), SlashUserPerm(GuildPermission.Administrator), CheckPermissions] @@ -112,10 +112,11 @@ public async Task EditChatTrigger { var trigger = await Service.GetChatTriggers(ctx.Guild?.Id, id); await ctx.Interaction.RespondWithModalAsync($"chat_trigger_edit:{id},{regex}", null, - x => x - .WithTitle("Chat Trigger Edit") - .UpdateTextInput("key", textInputBuilder => textInputBuilder.Value = trigger.Trigger) - .UpdateTextInput("message", textInputBuilder => textInputBuilder.Value = trigger.Response)).ConfigureAwait(false); + x => x + .WithTitle("Chat Trigger Edit") + .UpdateTextInput("key", textInputBuilder => textInputBuilder.Value = trigger.Trigger) + .UpdateTextInput("message", textInputBuilder => textInputBuilder.Value = trigger.Response)) + .ConfigureAwait(false); await FollowupWithTriggerStatus().ConfigureAwait(false); } @@ -209,7 +210,9 @@ public async Task ListChatTriggers() .WithActionOnCancellation(ActionOnStop.DeleteMessage) .Build(); - await interactivity.SendPaginatorAsync(paginator, ctx.Interaction as SocketInteraction, TimeSpan.FromMinutes(60)).ConfigureAwait(false); + await interactivity + .SendPaginatorAsync(paginator, ctx.Interaction as SocketInteraction, TimeSpan.FromMinutes(60)) + .ConfigureAwait(false); async Task PageFactory(int page) { @@ -264,7 +267,9 @@ public async Task ListChatTriggersGroup() .WithActionOnCancellation(ActionOnStop.DeleteMessage) .Build(); - await interactivity.SendPaginatorAsync(paginator, Context.Interaction as SocketInteraction, TimeSpan.FromMinutes(60)).ConfigureAwait(false); + await interactivity + .SendPaginatorAsync(paginator, Context.Interaction as SocketInteraction, TimeSpan.FromMinutes(60)) + .ConfigureAwait(false); async Task PageFactory(int page) { @@ -281,21 +286,24 @@ async Task PageFactory(int page) [SlashCommand("show", "Shows the responce of a chat trigger."), SlashUserPerm(GuildPermission.Administrator), CheckPermissions] - public async Task ShowChatTrigger([Summary("id", "The chat trigger's id"), Autocomplete(typeof(ChatTriggerAutocompleter))] int id) + public async Task ShowChatTrigger( + [Summary("id", "The chat trigger's id"), Autocomplete(typeof(ChatTriggerAutocompleter))] int id) { var found = await Service.GetChatTriggers(ctx.Guild?.Id, id); if (found == null) await ctx.Interaction.SendErrorAsync(GetText("no_found_id")).ConfigureAwait(false); else - await ctx.Interaction.RespondAsync(embed: Service.GetEmbed(found, ctx.Guild?.Id).Build()).ConfigureAwait(false); + await ctx.Interaction.RespondAsync(embed: Service.GetEmbed(found, ctx.Guild?.Id).Build()) + .ConfigureAwait(false); await FollowupWithTriggerStatus().ConfigureAwait(false); } [SlashCommand("delete", "delete a chat trigger."), SlashUserPerm(GuildPermission.Administrator), CheckPermissions] - public async Task DeleteChatTrigger([Summary("id", "The chat trigger's id"), Autocomplete(typeof(ChatTriggerAutocompleter))] int id) + public async Task DeleteChatTrigger( + [Summary("id", "The chat trigger's id"), Autocomplete(typeof(ChatTriggerAutocompleter))] int id) { var ct = await Service.DeleteAsync(ctx.Guild?.Id, id).ConfigureAwait(false); @@ -376,7 +384,8 @@ string emoji await Service.SetCrReactions(ctx.Guild?.Id, id, succ).ConfigureAwait(false); var text = GetText("ctr_set", Format.Bold(id.ToString()), string.Join(',', succ.Select(x => x.ToString()))); - await message.ModifyAsync(x => x.Embed = new EmbedBuilder().WithOkColor().WithDescription(text).Build()).ConfigureAwait(false); + await message.ModifyAsync(x => x.Embed = new EmbedBuilder().WithOkColor().WithDescription(text).Build()) + .ConfigureAwait(false); await FollowupWithTriggerStatus().ConfigureAwait(false); } @@ -464,7 +473,8 @@ public async Task CtsClear() [Group("crossposting", "crossposting")] public class Crossposting : MewdekoSlashModuleBase { - [SlashCommand("webhook", "crosspost triggers using a webhook"), SlashUserPerm(GuildPermission.Administrator), CheckPermissions] + [SlashCommand("webhook", "crosspost triggers using a webhook"), SlashUserPerm(GuildPermission.Administrator), + CheckPermissions] public async Task CtCpSetWebhook ( [Summary("trigger", "The chat trigger to edit."), Autocomplete(typeof(ChatTriggerAutocompleter))] @@ -572,7 +582,8 @@ IRole role ? "ct_role_add_enabled" : "ct_role_add_disabled"; - await ReplyConfirmLocalizedAsync(str, Format.Bold(role.Name), Format.Code(id.ToString())).ConfigureAwait(false); + await ReplyConfirmLocalizedAsync(str, Format.Bold(role.Name), Format.Code(id.ToString())) + .ConfigureAwait(false); await FollowupWithTriggerStatus().ConfigureAwait(false); } @@ -614,12 +625,14 @@ IRole role ? "ct_role_remove_enabled" : "cr_role_remove_disabled"; - await ReplyConfirmLocalizedAsync(str, Format.Bold(role.Name), Format.Code(id.ToString())).ConfigureAwait(false); + await ReplyConfirmLocalizedAsync(str, Format.Bold(role.Name), Format.Code(id.ToString())) + .ConfigureAwait(false); await FollowupWithTriggerStatus().ConfigureAwait(false); } - [SlashCommand("mode", "Changes the way roles are added to chat triggers."), CheckPermissions, SlashUserPerm(GuildPermission.Administrator)] + [SlashCommand("mode", "Changes the way roles are added to chat triggers."), CheckPermissions, + SlashUserPerm(GuildPermission.Administrator)] public async Task ChatTriggerRoleGrantType( [Autocomplete(typeof(ChatTriggerAutocompleter)), Summary("trigger", "The trigger to remove roles from.")] int id, @@ -634,7 +647,8 @@ public async Task ChatTriggerRoleGrantType( } else { - await RespondAsync(embed: Service.GetEmbed(res, ctx.Guild?.Id, GetText("edited_chat_trig")).Build()).ConfigureAwait(false); + await RespondAsync(embed: Service.GetEmbed(res, ctx.Guild?.Id, GetText("edited_chat_trig")).Build()) + .ConfigureAwait(false); } await FollowupWithTriggerStatus().ConfigureAwait(false); @@ -775,13 +789,15 @@ private async Task FollowupWithTriggerStatus() await ctx.Interaction.FollowupAsync(embed: embed.Build(), ephemeral: true).ConfigureAwait(false); } - [SlashCommand("errors", "Check for errors in your interaction chat triggers."), CheckPermissions, SlashUserPerm(GuildPermission.Administrator)] + [SlashCommand("errors", "Check for errors in your interaction chat triggers."), CheckPermissions, + SlashUserPerm(GuildPermission.Administrator)] // ReSharper disable once UnusedMember.Local - private async Task CtInterErrors() + private Task CtInterErrors() { var errors = Service.GetAcctErrors(ctx.Guild?.Id); var eb = new EmbedBuilder(); - var cb = new ComponentBuilder().WithButton("Support Server", style: ButtonStyle.Link, url: "https://discord.gg/Mewdeko", + var cb = new ComponentBuilder().WithButton("Support Server", style: ButtonStyle.Link, + url: "https://discord.gg/Mewdeko", emote: Emote.Parse("<:IconInvite:778931752835088426>")); if (errors?.Any() ?? false) { @@ -797,7 +813,7 @@ private async Task CtInterErrors() .WithDescription(GetText("ct_interaction_errors_none_desc")); } - await RespondAsync(embed: eb.Build(), components: cb.Build()).ConfigureAwait(false); + return RespondAsync(embed: eb.Build(), components: cb.Build()); } } @@ -819,6 +835,7 @@ public async Task HandleMultitriggers(ulong? guildId, string _) var values = (Context.Interaction as SocketMessageComponent).Data.Values; var i = -1; foreach (var n in values) - await Service.RunInteractionTrigger(ctx.Interaction as SocketInteraction, await Service.GetChatTriggers(guildId, Convert.ToInt32(n)), ++i >= 1); + await Service.RunInteractionTrigger(ctx.Interaction as SocketInteraction, + await Service.GetChatTriggers(guildId, Convert.ToInt32(n)), ++i >= 1); } } \ No newline at end of file diff --git a/src/Mewdeko/Modules/Games/PollCommands.cs b/src/Mewdeko/Modules/Games/PollCommands.cs index 0ae3912b1..ee9104835 100644 --- a/src/Mewdeko/Modules/Games/PollCommands.cs +++ b/src/Mewdeko/Modules/Games/PollCommands.cs @@ -12,8 +12,8 @@ public class PollCommands : MewdekoSubmodule { [Cmd, Aliases, UserPerm(GuildPermission.ManageMessages), RequireContext(ContextType.Guild)] - public async Task Poll([Remainder] string input) - => await Poll(PollType.SingleAnswer, input); + public Task Poll([Remainder] string input) + => Poll(PollType.SingleAnswer, input); [Cmd, Aliases, UserPerm(GuildPermission.ManageMessages), RequireContext(ContextType.Guild)] diff --git a/src/Mewdeko/Modules/Games/TicTacToeCommands.cs b/src/Mewdeko/Modules/Games/TicTacToeCommands.cs index 52019ac99..ef2f863b9 100644 --- a/src/Mewdeko/Modules/Games/TicTacToeCommands.cs +++ b/src/Mewdeko/Modules/Games/TicTacToeCommands.cs @@ -25,7 +25,7 @@ public async Task TicTacToe(params string[] args) { if (Service.TicTacToeGames.TryGetValue(channel.Id, out var game)) { - _ = Task.Run(async () => await game.Start((IGuildUser)ctx.User).ConfigureAwait(false)); + _ = Task.Run(() => game.Start((IGuildUser)ctx.User)); return; } diff --git a/src/Mewdeko/Modules/Giveaways/Services/GiveawayService.cs b/src/Mewdeko/Modules/Giveaways/Services/GiveawayService.cs index a9d3d159d..aad500b23 100644 --- a/src/Mewdeko/Modules/Giveaways/Services/GiveawayService.cs +++ b/src/Mewdeko/Modules/Giveaways/Services/GiveawayService.cs @@ -6,8 +6,11 @@ namespace Mewdeko.Modules.Giveaways.Services; -public class GiveawayService(DiscordSocketClient client, DbService db, IBotCredentials creds, - GuildSettingsService guildSettings) +public class GiveawayService( + DiscordSocketClient client, + DbService db, + IBotCredentials creds, + GuildSettingsService guildSettings) : INService, IReadyExecutor { public async Task OnReadyAsync() @@ -61,25 +64,22 @@ private async Task UpdateGiveaways(List g) await using var uow = db.GetDbContext(); foreach (var i in g) { - var toupdate = new Database.Models.Giveaways - { - When = i.When, - BlacklistRoles = i.BlacklistRoles, - BlacklistUsers = i.BlacklistUsers, - ChannelId = i.ChannelId, - Ended = 1, - MessageId = i.MessageId, - RestrictTo = i.RestrictTo, - Item = i.Item, - ServerId = i.ServerId, - UserId = i.UserId, - Winners = i.Winners, - Emote = i.Emote - }; - uow.Giveaways.Remove(i); - uow.Giveaways.Add(toupdate); - await uow.SaveChangesAsync().ConfigureAwait(false); + var toupdate = await uow.Giveaways.FindAsync(i.Id); + if (toupdate == null) continue; + toupdate.When = i.When; + toupdate.BlacklistRoles = i.BlacklistRoles; + toupdate.BlacklistUsers = i.BlacklistUsers; + toupdate.ChannelId = i.ChannelId; + toupdate.Ended = 1; + toupdate.MessageId = i.MessageId; + toupdate.RestrictTo = i.RestrictTo; + toupdate.Item = i.Item; + toupdate.UserId = i.UserId; + toupdate.Winners = i.Winners; + toupdate.Emote = i.Emote; } + + await uow.SaveChangesAsync().ConfigureAwait(false); } private IEnumerable GetGiveawaysBeforeAsync(DateTime now) @@ -434,7 +434,7 @@ await ch.Channel.SendMessageAsync($"Congratulations to {user.Mention}! {r.Emote} { var rand = new Random(); var users = (await Task.WhenAll(reacts.Where(x => !x.IsBot) - .Select(async x => await guild.GetUserAsync(x.Id)).Where(x => x is not null))).ToHashSet(); + .Select(x => guild.GetUserAsync(x.Id)).Where(x => x is not null))).ToHashSet(); if (r.RestrictTo is not null) { var parsedreqs = new List(); diff --git a/src/Mewdeko/Modules/Help/HelpSlashCommand.cs b/src/Mewdeko/Modules/Help/HelpSlashCommand.cs index d8835165e..0fe54b03c 100644 --- a/src/Mewdeko/Modules/Help/HelpSlashCommand.cs +++ b/src/Mewdeko/Modules/Help/HelpSlashCommand.cs @@ -14,13 +14,14 @@ namespace Mewdeko.Modules.Help; [Discord.Interactions.Group("help", "Help Commands, what else is there to say?")] -public class HelpSlashCommand(GlobalPermissionService permissionService, - InteractiveService interactivity, - IServiceProvider serviceProvider, - CommandService cmds, - CommandHandler ch, - GuildSettingsService guildSettings, - BotConfigService config) +public class HelpSlashCommand( + GlobalPermissionService permissionService, + InteractiveService interactivity, + IServiceProvider serviceProvider, + CommandService cmds, + CommandHandler ch, + GuildSettingsService guildSettings, + BotConfigService config) : MewdekoSlashModuleBase { private static readonly ConcurrentDictionary HelpMessages = new(); @@ -139,7 +140,7 @@ async Task PageFactory(int page) } [SlashCommand("invite", "You should invite me to your server and check all my features!"), CheckPermissions] - public async Task Invite() + public Task Invite() { var eb = new EmbedBuilder() .AddField("Invite Link", @@ -147,7 +148,7 @@ public async Task Invite() .AddField("Website/Docs", "https://mewdeko.tech") .AddField("Support Server", config.Data.SupportServer) .WithOkColor(); - await ctx.Interaction.RespondAsync(embed: eb.Build()).ConfigureAwait(false); + return ctx.Interaction.RespondAsync(embed: eb.Build()); } [SlashCommand("search", "get information on a specific command"), CheckPermissions] diff --git a/src/Mewdeko/Modules/Help/Services/HelpService.cs b/src/Mewdeko/Modules/Help/Services/HelpService.cs index ee81f1894..d34891d55 100644 --- a/src/Mewdeko/Modules/Help/Services/HelpService.cs +++ b/src/Mewdeko/Modules/Help/Services/HelpService.cs @@ -61,9 +61,11 @@ public Task LateExecute(DiscordSocketClient discordSocketClient, IGuild? guild, if (guild != null) return Task.CompletedTask; if (string.IsNullOrWhiteSpace(settings.DmHelpText) || settings.DmHelpText == "-") return Task.CompletedTask; - var replacer = new ReplacementBuilder().WithDefault(msg.Author, msg.Channel, guild as SocketGuild, discordSocketClient).Build(); - return SmartEmbed.TryParse(replacer.Replace(settings.DmHelpText), null, out var embed, out var plainText, out var components) - ? msg.Channel.SendMessageAsync(plainText, embeds: embed, components: components.Build()) + var replacer = new ReplacementBuilder() + .WithDefault(msg.Author, msg.Channel, guild as SocketGuild, discordSocketClient).Build(); + return SmartEmbed.TryParse(replacer.Replace(settings.DmHelpText), null, out var embed, out var plainText, + out var components) + ? msg.Channel.SendMessageAsync(plainText, embeds: embed, components: components?.Build()) : msg.Channel.SendMessageAsync(settings.DmHelpText); } @@ -76,10 +78,12 @@ public ComponentBuilder GetHelpComponents(IGuild? guild, IUser user, bool descri for (var j = 0; j < menuCount; j++) { var selMenu = new SelectMenuBuilder().WithCustomId($"helpselect:{j}"); - foreach (var i in modules.Skip(j * 25).Take(25).Where(x => !x.Attributes.Any(attribute => attribute is HelpDisabled))) + foreach (var i in modules.Skip(j * 25).Take(25) + .Where(x => !x.Attributes.Any(attribute => attribute is HelpDisabled))) { selMenu.Options.Add(new SelectMenuOptionBuilder() - .WithLabel(i.Name).WithDescription(GetText($"module_description_{i.Name.ToLower()}", guild)).WithValue(i.Name.ToLower())); + .WithLabel(i.Name).WithDescription(GetText($"module_description_{i.Name.ToLower()}", guild)) + .WithValue(i.Name.ToLower())); } compBuilder.WithSelectMenu(selMenu); // add the select menu to the component builder @@ -87,7 +91,8 @@ public ComponentBuilder GetHelpComponents(IGuild? guild, IUser user, bool descri compBuilder.WithButton(GetText("toggle_descriptions", guild), $"toggle-descriptions:{descriptions},{user.Id}"); compBuilder.WithButton(GetText("invite_me", guild), style: ButtonStyle.Link, - url: "https://discord.com/oauth2/authorize?client_id=752236274261426212&scope=bot&permissions=66186303&scope=bot%20applications.commands"); + url: + "https://discord.com/oauth2/authorize?client_id=752236274261426212&scope=bot&permissions=66186303&scope=bot%20applications.commands"); compBuilder.WithButton(GetText("donatetext", guild), style: ButtonStyle.Link, url: "https://ko-fi.com/mewdeko"); return compBuilder; } @@ -95,21 +100,25 @@ public ComponentBuilder GetHelpComponents(IGuild? guild, IUser user, bool descri public async Task GetHelpEmbed(bool description, IGuild? guild, IMessageChannel channel, IUser user) { + var prefix = await guildSettings.GetPrefix(guild); EmbedBuilder embed = new(); - embed.WithAuthor(new EmbedAuthorBuilder().WithName(GetText("helpmenu_helptext", guild, client.CurrentUser)).WithIconUrl(client.CurrentUser.RealAvatarUrl().AbsoluteUri)); + embed.WithAuthor(new EmbedAuthorBuilder().WithName(GetText("helpmenu_helptext", guild, client.CurrentUser)) + .WithIconUrl(client.CurrentUser.RealAvatarUrl().AbsoluteUri)); embed.WithOkColor(); embed.WithDescription( - GetText("command_help_description", guild, await guildSettings.GetPrefix(guild)) + - $"\n{GetText("module_help_description", guild, await guildSettings.GetPrefix(guild))}" + - "\n\n**Youtube Tutorials**\nhttps://www.youtube.com/channel/UCKJEaaZMJQq6lH33L3b_sTg\n\n**Links**\n" + - $"[Documentation](https://mewdeko.tech) | [Support Server](https://discord.gg/mewdeko) | [Invite Me](https://discord.com/oauth2/authorize?client_id={bot.Client.CurrentUser.Id}&scope=bot&permissions=66186303&scope=bot%20applications.commands) | [Top.gg Listing](https://top.gg/bot/752236274261426212) | [Donate!](https://ko-fi.com/mewdeko)"); - var modules = cmds.Commands.Select(x => x.Module).Where(x => !x.IsSubmodule && !x.Attributes.Any(attribute => attribute is HelpDisabled)).Distinct(); + GetText("command_help_description", guild, prefix + + $"\n{GetText("module_help_description", guild, prefix)}" + + "\n\n**Youtube Tutorials**\nhttps://www.youtube.com/channel/UCKJEaaZMJQq6lH33L3b_sTg\n\n**Links**\n" + + $"[Documentation](https://mewdeko.tech) | [Support Server]({bss.Data.SupportServer}) | [Invite Me](https://discord.com/oauth2/authorize?client_id={bot.Client.CurrentUser.Id}&scope=bot&permissions=66186303&scope=bot%20applications.commands) | [Top.gg Listing](https://top.gg/bot/752236274261426212) | [Donate!](https://ko-fi.com/mewdeko)")); + var modules = cmds.Commands.Select(x => x.Module) + .Where(x => !x.IsSubmodule && !x.Attributes.Any(attribute => attribute is HelpDisabled)).Distinct(); var count = 0; if (description) { foreach (var mod in modules) { - embed.AddField($"{await CheckEnabled(guild?.Id, channel, user, mod.Name)} {mod.Name}", $">>> {GetModuleDescription(mod.Name, guild)}", true); + embed.AddField($"{await CheckEnabled(guild?.Id, channel, user, mod.Name)} {mod.Name}", + $">>> {GetModuleDescription(mod.Name, guild)}", true); } } else @@ -117,7 +126,10 @@ public async Task GetHelpEmbed(bool description, IGuild? guild, IM foreach (var i in modules.Batch(modules.Count() / 2)) { embed.AddField(count == 0 ? "Categories" : "_ _", - string.Join("\n", i.Select(x => $"> {CheckEnabled(guild?.Id, channel, user, x.Name).GetAwaiter().GetResult()} {Format.Bold(x.Name)}")), true); + string.Join("\n", + i.Select(x => + $"> {CheckEnabled(guild?.Id, channel, user, x.Name).GetAwaiter().GetResult()} {Format.Bold(x.Name)}")), + true); count++; } } @@ -125,39 +137,38 @@ public async Task GetHelpEmbed(bool description, IGuild? guild, IM return embed; } - public async Task CheckEnabled(ulong? guildId, IMessageChannel channel, IUser user, string moduleName) + private async Task CheckEnabled(ulong? guildId, IMessageChannel channel, IUser user, string moduleName) { - if (!guildId.HasValue || guildId is null) + if (!guildId.HasValue) return "✅"; var pc = await nPerms.GetCacheFor(guildId.Value); if (perms.BlockedModules.Contains(moduleName.ToLower())) return "🌐❌"; return !pc.Permissions.CheckSlashPermissions(moduleName, "none", user, channel, out _) ? "❌" : "✅"; } - public string? GetModuleDescription(string module, IGuild? guild) => GetText($"module_description_{module.ToLower()}", guild); + private string? GetModuleDescription(string module, IGuild? guild) => + GetText($"module_description_{module.ToLower()}", guild); - private Task HandlePing(SocketMessage msg) + private async Task HandlePing(SocketMessage msg) { - _ = Task.Run(async () => + if (msg.Content == $"<@{client.CurrentUser.Id}>" || msg.Content == $"<@!{client.CurrentUser.Id}>") { - if (msg.Content == $"<@{client.CurrentUser.Id}>" || msg.Content == $"<@!{client.CurrentUser.Id}>") + if (msg.Channel is ITextChannel chan) { - if (msg.Channel is ITextChannel chan) - { - var eb = new EmbedBuilder(); - eb.WithOkColor(); - eb.WithDescription( - $"Hi there! To see my command categories do `{await guildSettings.GetPrefix(chan.Guild)}cmds`\nMy current Prefix is `{await guildSettings.GetPrefix(chan.Guild)}`\nIf you need help using the bot feel free to join the [Support Server](https://discord.gg/mewdeko)!\n**Please support me! While this bot is free it's not free to run! https://ko-fi.com/mewdeko**\n\n I hope you have a great day!"); - eb.WithThumbnailUrl("https://cdn.discordapp.com/emojis/914307922287276052.gif"); - eb.WithFooter(new EmbedFooterBuilder().WithText(client.CurrentUser.Username).WithIconUrl(client.CurrentUser.RealAvatarUrl().ToString())); - await chan.SendMessageAsync(embed: eb.Build()).ConfigureAwait(false); - } + var prefix = await guildSettings.GetPrefix(chan.Guild); + var eb = new EmbedBuilder(); + eb.WithOkColor(); + eb.WithDescription( + $"Hi there! To see my command categories do `{prefix}cmds`\nMy current Prefix is `{prefix}`\nIf you need help using the bot feel free to join the [Support Server]({bss.Data.SupportServer})!\n**Please support me! While this bot is free it's not free to run! https://ko-fi.com/mewdeko**\n\n I hope you have a great day!"); + eb.WithThumbnailUrl("https://cdn.discordapp.com/emojis/914307922287276052.gif"); + eb.WithFooter(new EmbedFooterBuilder().WithText(client.CurrentUser.Username) + .WithIconUrl(client.CurrentUser.RealAvatarUrl().ToString())); + await chan.SendMessageAsync(embed: eb.Build()).ConfigureAwait(false); } - }); - return Task.CompletedTask; + } } - public async Task HandleJoin(IGuild guild) + private async Task HandleJoin(IGuild guild) { if (blacklistService.BlacklistEntries.Select(x => x.ItemId).Contains(guild.Id)) return; @@ -171,7 +182,8 @@ public async Task HandleJoin(IGuild guild) }; eb.AddField("How to look for commands", $"1) Use the {px}cmds command to see all the categories\n2) use {px}cmds with the category name to glance at what commands it has. ex: `{px}cmds mod`\n3) Use {px}h with a command name to view its help. ex: `{px}h purge`"); - eb.AddField("Have any questions, or need my invite link?", "Support Server: https://discord.gg/mewdeko \nInvite Link: https://mewdeko.tech/invite"); + eb.AddField("Have any questions, or need my invite link?", + "Support Server: https://discord.gg/mewdeko \nInvite Link: https://mewdeko.tech/invite"); eb.AddField("Youtube Channel", "https://youtube.com/channel/UCKJEaaZMJQq6lH33L3b_sTg"); eb.WithThumbnailUrl( "https://cdn.discordapp.com/emojis/968564817784877066.gif"); @@ -184,7 +196,8 @@ public async Task HandleJoin(IGuild guild) if (com.Attributes.Any(x => x is HelpDisabled)) return (new EmbedBuilder().WithDescription("Help is disabled for this command."), new()); var prefix = await guildSettings.GetPrefix(guild); - var potentialCommand = interactionService.SlashCommands.FirstOrDefault(x => string.Equals(x.MethodName, com.MethodName(), StringComparison.CurrentCultureIgnoreCase)); + var potentialCommand = interactionService.SlashCommands.FirstOrDefault(x => + string.Equals(x.MethodName, com.MethodName(), StringComparison.CurrentCultureIgnoreCase)); var str = $"**{prefix + com.Aliases[0]}**"; var alias = com.Aliases.Skip(1).FirstOrDefault(); if (alias != null) @@ -202,7 +215,7 @@ public async Task HandleJoin(IGuild guild) em.AddField("Bot Permissions", string.Join("\n", botReqs)); if (attribute?.Seconds > 0) { - em.AddField("Ratelimit", $"{attribute.Seconds} seconds"); + em.AddField("Cooldown", $"{attribute.Seconds} seconds"); } var cb = new ComponentBuilder() @@ -219,16 +232,23 @@ public async Task HandleJoin(IGuild guild) var globalCommand = globalCommands.FirstOrDefault(x => x.Name == potentialCommand.Module.SlashGroupName); var guildCommand = guildCommands.FirstOrDefault(x => x.Name == potentialCommand.Module.SlashGroupName); if (globalCommand is not null) - em.AddField("Slash Command", potentialCommand == null ? "`None`" : $""); + em.AddField("Slash Command", + potentialCommand == null + ? "`None`" + : $""); else if (guildCommand is not null) - em.AddField("Slash Command", potentialCommand == null ? "`None`" : $""); + em.AddField("Slash Command", + potentialCommand == null + ? "`None`" + : $""); } em.AddField(fb => fb.WithName(GetText("usage", guild)).WithValue(string.Join("\n", Array.ConvertAll(com.RealRemarksArr(strings, guild?.Id, prefix), arg => Format.Code(arg)))) .WithIsInline(false)) - .WithFooter($"Module: {com.Module.GetTopLevelModule().Name} || Submodule: {com.Module.Name.Replace("Commands", "")} || Method Name: {com.MethodName()}") + .WithFooter( + $"Module: {com.Module.GetTopLevelModule().Name} || Submodule: {com.Module.Name.Replace("Commands", "")} || Method Name: {com.MethodName()}") .WithColor(Mewdeko.OkColor); var opt = ((MewdekoOptionsAttribute)com.Attributes.FirstOrDefault(x => x is MewdekoOptionsAttribute)) @@ -241,14 +261,14 @@ public async Task HandleJoin(IGuild guild) return (em, cb); } - public static string GetCommandOptionHelp(Type opt) + private static string GetCommandOptionHelp(Type opt) { var strs = GetCommandOptionHelpList(opt); return string.Join("\n", strs); } - public static List GetCommandOptionHelpList(Type opt) => + private static List GetCommandOptionHelpList(Type opt) => opt.GetProperties() .Select(x => Array.Find(x.GetCustomAttributes(true), a => a is OptionAttribute)) .Where(x => x != null).Cast().Select(x => @@ -262,7 +282,7 @@ public static List GetCommandOptionHelpList(Type opt) => return toReturn; }).ToList(); - public static string[] GetCommandRequirements(CommandInfo cmd, GuildPermission? overrides = null) + private static string[] GetCommandRequirements(CommandInfo cmd, GuildPermission? overrides = null) { var toReturn = new List(); @@ -296,7 +316,7 @@ public static string[] GetCommandRequirements(CommandInfo cmd, GuildPermission? return toReturn.ToArray(); } - public static string[] GetCommandBotRequirements(CommandInfo cmd) + private static string[] GetCommandBotRequirements(CommandInfo cmd) { var toReturn = new List(); @@ -320,10 +340,10 @@ public static string[] GetCommandBotRequirements(CommandInfo cmd) return toReturn.ToArray(); } - public static string GetPreconditionString(ChannelPermission perm) => + private static string GetPreconditionString(ChannelPermission perm) => (perm + " Channel Permission").Replace("Guild", "Server", StringComparison.InvariantCulture); - public static string GetPreconditionString(GuildPermission perm) => + private static string GetPreconditionString(GuildPermission perm) => (perm + " Server Permission").Replace("Guild", "Server", StringComparison.InvariantCulture); private string? GetText(string? text, IGuild? guild, params object?[] replacements) => diff --git a/src/Mewdeko/Modules/Highlights/Services/HighlightsService.cs b/src/Mewdeko/Modules/Highlights/Services/HighlightsService.cs index 5643a82e5..08fa4f441 100644 --- a/src/Mewdeko/Modules/Highlights/Services/HighlightsService.cs +++ b/src/Mewdeko/Modules/Highlights/Services/HighlightsService.cs @@ -59,16 +59,15 @@ public Task OnReadyAsync() var hlSettings = allHighlightSettings.FirstOrDefault(x => x.GuildId == i.Id); if (highlights is not null) { - _ = Task.Run(async () => - await cache.CacheHighlights(i.Id, allHighlights.Where(x => x.GuildId == i.Id).ToList()) - .ConfigureAwait(false)); + _ = Task.Run(() => + cache.CacheHighlights(i.Id, allHighlights.Where(x => x.GuildId == i.Id).ToList())); } if (hlSettings is not null) { - _ = Task.Run(async () => - await cache.CacheHighlightSettings(i.Id, - allHighlightSettings.Where(x => x.GuildId == i.Id).ToList()).ConfigureAwait(false)); + _ = Task.Run(() => + cache.CacheHighlightSettings(i.Id, + allHighlightSettings.Where(x => x.GuildId == i.Id).ToList())); } } diff --git a/src/Mewdeko/Modules/Moderation/MuteCommands.cs b/src/Mewdeko/Modules/Moderation/MuteCommands.cs index 1783af3be..18a91b94c 100644 --- a/src/Mewdeko/Modules/Moderation/MuteCommands.cs +++ b/src/Mewdeko/Modules/Moderation/MuteCommands.cs @@ -15,7 +15,7 @@ public class MuteCommands : MewdekoSubmodule { [Cmd, Aliases, RequireContext(ContextType.Guild), UserPerm(GuildPermission.MuteMembers), Priority(1)] - public async Task Stfu(StoopidTime time, IGuildUser user) => await Stfu(user, time).ConfigureAwait(false); + public Task Stfu(StoopidTime time, IGuildUser user) => Stfu(user, time); [Cmd, Aliases, RequireContext(ContextType.Guild), UserPerm(GuildPermission.Administrator)] @@ -34,7 +34,8 @@ public async Task RemoveOnMute(string yesnt) } else { - await ctx.Channel.SendErrorAsync("Hey! Its either yes or no, Not that I care anyway, hmph.").ConfigureAwait(false); + await ctx.Channel.SendErrorAsync("Hey! Its either yes or no, Not that I care anyway, hmph.") + .ConfigureAwait(false); } } @@ -46,12 +47,14 @@ public async Task Stfu(IGuildUser user, StoopidTime? time = null) return; var channel = ctx.Channel as SocketGuildChannel; var currentPerms = channel.GetPermissionOverwrite(user) ?? new OverwritePermissions(); - await channel.AddPermissionOverwriteAsync(user, currentPerms.Modify(sendMessages: PermValue.Deny)).ConfigureAwait(false); + await channel.AddPermissionOverwriteAsync(user, currentPerms.Modify(sendMessages: PermValue.Deny)) + .ConfigureAwait(false); if (time is null) await ctx.Channel.SendConfirmAsync($"{user} has been muted in this channel!").ConfigureAwait(false); if (time != null) { - await channel.AddPermissionOverwriteAsync(user, currentPerms.Modify(sendMessages: PermValue.Deny)).ConfigureAwait(false); + await channel.AddPermissionOverwriteAsync(user, currentPerms.Modify(sendMessages: PermValue.Deny)) + .ConfigureAwait(false); await ctx.Channel.SendConfirmAsync( $"{user} has been muted in this channel for {time.Time.Humanize()}!").ConfigureAwait(false); await Task.Delay((int)time.Time.TotalMilliseconds).ConfigureAwait(false); @@ -75,7 +78,8 @@ public async Task UnmuteAll([Remainder] string? reason = null) .Where(x => x.RoleIds.ToList().Contains(Service.GetMuteRole(ctx.Guild).Result.Id)); if (!users.Any()) { - await ctx.Channel.SendErrorAsync("There are no muted users or you don't have a mute role set.").ConfigureAwait(false); + await ctx.Channel.SendErrorAsync("There are no muted users or you don't have a mute role set.") + .ConfigureAwait(false); return; } @@ -86,10 +90,13 @@ public async Task UnmuteAll([Remainder] string? reason = null) { if (reason is null) { - if (await PromptUserConfirmAsync(new EmbedBuilder().WithOkColor().WithDescription("Would you like to add a reason for the unmute?"), ctx.User.Id) + if (await PromptUserConfirmAsync( + new EmbedBuilder().WithOkColor() + .WithDescription("Would you like to add a reason for the unmute?"), ctx.User.Id) .ConfigureAwait(false)) { - var msg = await ctx.Channel.SendMessageAsync("Please type out the unmute reason.").ConfigureAwait(false); + var msg = await ctx.Channel.SendMessageAsync("Please type out the unmute reason.") + .ConfigureAwait(false); reason = await NextMessageAsync(ctx.Channel.Id, ctx.User.Id).ConfigureAwait(false); var eb = new EmbedBuilder().WithDescription($"Unmuting {users.Count()} users..."); await msg.ModifyAsync(x => x.Embed = eb.Build()).ConfigureAwait(false); @@ -97,7 +104,8 @@ public async Task UnmuteAll([Remainder] string? reason = null) { try { - await Service.UnmuteUser(i.GuildId, i.Id, ctx.User, MuteType.All, reason).ConfigureAwait(false); + await Service.UnmuteUser(i.GuildId, i.Id, ctx.User, MuteType.All, reason) + .ConfigureAwait(false); } catch { @@ -106,7 +114,9 @@ public async Task UnmuteAll([Remainder] string? reason = null) } await msg.ModifyAsync(x => - x.Embed = new EmbedBuilder().WithOkColor().WithDescription("Unmuted all users!").Build()).ConfigureAwait(false); + x.Embed = new EmbedBuilder().WithOkColor().WithDescription("Unmuted all users!") + .Build()) + .ConfigureAwait(false); } else { @@ -125,7 +135,9 @@ await msg.ModifyAsync(x => } await msg.ModifyAsync(x => - x.Embed = new EmbedBuilder().WithOkColor().WithDescription("Unmuted all users!").Build()).ConfigureAwait(false); + x.Embed = new EmbedBuilder().WithOkColor().WithDescription("Unmuted all users!") + .Build()) + .ConfigureAwait(false); } } else @@ -136,7 +148,8 @@ await msg.ModifyAsync(x => { try { - await Service.UnmuteUser(i.GuildId, i.Id, ctx.User, MuteType.All, reason).ConfigureAwait(false); + await Service.UnmuteUser(i.GuildId, i.Id, ctx.User, MuteType.All, reason) + .ConfigureAwait(false); } catch { @@ -145,7 +158,8 @@ await msg.ModifyAsync(x => } await msg.ModifyAsync(x => - x.Embed = new EmbedBuilder().WithOkColor().WithDescription("Unmuted all users!").Build()).ConfigureAwait(false); + x.Embed = new EmbedBuilder().WithOkColor().WithDescription("Unmuted all users!").Build()) + .ConfigureAwait(false); } } } @@ -158,7 +172,8 @@ public async Task Unstfu(IGuildUser user) return; var channel = ctx.Channel as SocketGuildChannel; var currentPerms = channel.GetPermissionOverwrite(user) ?? new OverwritePermissions(); - await channel.AddPermissionOverwriteAsync(user, currentPerms.Modify(sendMessages: PermValue.Inherit)).ConfigureAwait(false); + await channel.AddPermissionOverwriteAsync(user, currentPerms.Modify(sendMessages: PermValue.Inherit)) + .ConfigureAwait(false); await ctx.Channel.SendConfirmAsync($"{user} has been unmuted in this channel!").ConfigureAwait(false); } @@ -207,7 +222,7 @@ await ReplyConfirmLocalizedAsync("user_muted", Format.Bold(target.ToString())) [Cmd, Aliases, RequireContext(ContextType.Guild), UserPerm(GuildPermission.ManageRoles | GuildPermission.MuteMembers), Priority(2)] - public async Task Mute(IGuildUser user, StoopidTime time, string reason = "") => await Mute(time, user, reason).ConfigureAwait(false); + public Task Mute(IGuildUser user, StoopidTime time, string reason = "") => Mute(time, user, reason); [Cmd, Aliases, RequireContext(ContextType.Guild), UserPerm(GuildPermission.ManageRoles | GuildPermission.MuteMembers), Priority(1)] diff --git a/src/Mewdeko/Modules/Moderation/PruneCommands.cs b/src/Mewdeko/Modules/Moderation/PruneCommands.cs index 818f40b21..4c507caab 100644 --- a/src/Mewdeko/Modules/Moderation/PruneCommands.cs +++ b/src/Mewdeko/Modules/Moderation/PruneCommands.cs @@ -145,7 +145,7 @@ public Task Purge(IGuildUser user, ulong count = 100, string? parameter = null) //Purge userid [x] [Cmd, Aliases, RequireContext(ContextType.Guild), UserPerm(ChannelPermission.ManageMessages), BotPerm(ChannelPermission.ManageMessages), Priority(0)] - public async Task Purge(ulong userId, ulong count = 100, string? parameter = null) + public Task Purge(ulong userId, ulong count = 100, string? parameter = null) { if (userId == ctx.User.Id) count++; @@ -153,7 +153,7 @@ public async Task Purge(ulong userId, ulong count = 100, string? parameter = nul switch (count) { case < 1: - return; + return Task.CompletedTask; case > 1000: count = 1000; break; @@ -161,14 +161,13 @@ public async Task Purge(ulong userId, ulong count = 100, string? parameter = nul if (parameter is "-s" or "--safe") { - await Service.PurgeWhere((ITextChannel)ctx.Channel, count, - m => m.Author.Id == userId && DateTime.UtcNow - m.CreatedAt < TwoWeeks && !m.IsPinned) - .ConfigureAwait(false); + return Service.PurgeWhere((ITextChannel)ctx.Channel, count, + m => m.Author.Id == userId && DateTime.UtcNow - m.CreatedAt < TwoWeeks && !m.IsPinned); } else { - await Service.PurgeWhere((ITextChannel)ctx.Channel, count, - m => m.Author.Id == userId && DateTime.UtcNow - m.CreatedAt < TwoWeeks).ConfigureAwait(false); + return Service.PurgeWhere((ITextChannel)ctx.Channel, count, + m => m.Author.Id == userId && DateTime.UtcNow - m.CreatedAt < TwoWeeks); } } } diff --git a/src/Mewdeko/Modules/Moderation/SlashPunishCommands.cs b/src/Mewdeko/Modules/Moderation/SlashPunishCommands.cs index 32587d978..596c4e234 100644 --- a/src/Mewdeko/Modules/Moderation/SlashPunishCommands.cs +++ b/src/Mewdeko/Modules/Moderation/SlashPunishCommands.cs @@ -49,17 +49,20 @@ public async Task SetWarnChannel(ITextChannel channel) if (warnlogChannel == 0) { await Service.SetWarnlogChannelId(ctx.Guild, channel).ConfigureAwait(false); - await ctx.Interaction.SendConfirmAsync($"Your warnlog channel has been set to {channel.Mention}").ConfigureAwait(false); + await ctx.Interaction.SendConfirmAsync($"Your warnlog channel has been set to {channel.Mention}") + .ConfigureAwait(false); return; } var oldWarnChannel = await ctx.Guild.GetTextChannelAsync(warnlogChannel).ConfigureAwait(false); await Service.SetWarnlogChannelId(ctx.Guild, channel).ConfigureAwait(false); await ctx.Interaction.SendConfirmAsync( - $"Your warnlog channel has been changed from {oldWarnChannel.Mention} to {channel.Mention}").ConfigureAwait(false); + $"Your warnlog channel has been changed from {oldWarnChannel.Mention} to {channel.Mention}") + .ConfigureAwait(false); } - [SlashCommand("timeout", "Time a user out."), RequireContext(ContextType.Guild), SlashUserPerm(GuildPermission.ModerateMembers), BotPerm(GuildPermission.ModerateMembers), + [SlashCommand("timeout", "Time a user out."), RequireContext(ContextType.Guild), + SlashUserPerm(GuildPermission.ModerateMembers), BotPerm(GuildPermission.ModerateMembers), CheckPermissions] public async Task Timeout(string inputTime, IGuildUser user, string? reason = null) { @@ -88,10 +91,12 @@ public async Task Timeout(string inputTime, IGuildUser user, string? reason = nu { AuditLogReason = reason }).ConfigureAwait(false); - await ReplyConfirmLocalizedAsync("timeout_set", user.Mention, time.Time.Humanize(maxUnit: TimeUnit.Day)).ConfigureAwait(false); + await ReplyConfirmLocalizedAsync("timeout_set", user.Mention, time.Time.Humanize(maxUnit: TimeUnit.Day)) + .ConfigureAwait(false); } - [SlashCommand("untimeout", "Remove a users timeout."), RequireContext(ContextType.Guild), SlashUserPerm(GuildPermission.ModerateMembers), + [SlashCommand("untimeout", "Remove a users timeout."), RequireContext(ContextType.Guild), + SlashUserPerm(GuildPermission.ModerateMembers), BotPerm(GuildPermission.ModerateMembers), CheckPermissions] public async Task UnTimeOut(IGuildUser user) { @@ -183,7 +188,8 @@ await channel.EmbedAsync(new EmbedBuilder().WithErrorColor() [SlashCommand("setwarnexpire", "Set when warns expire in days"), RequireContext(ContextType.Guild), SlashUserPerm(GuildPermission.Administrator), CheckPermissions] - public async Task WarnExpire(int days, [Summary("todelete", "Set whether warns are deleted instead of cleared.")] bool delete) + public async Task WarnExpire(int days, + [Summary("todelete", "Set whether warns are deleted instead of cleared.")] bool delete) { if (days is < 0 or > 366) return; @@ -210,13 +216,14 @@ await ReplyConfirmLocalizedAsync("warn_expire_set_clear", Format.Bold(days.ToStr } [SlashCommand("warnlog", "Check a users warn amount"), RequireContext(ContextType.Guild)] - public async Task Warnlog(IGuildUser? user = null) + public Task Warnlog(IGuildUser? user = null) { user ??= (IGuildUser)ctx.User; if (ctx.User.Id == user.Id || ((IGuildUser)ctx.User).GuildPermissions.BanMembers) - await InternalWarnlog(user.Id); + return InternalWarnlog(user.Id); else - await ctx.Interaction.SendEphemeralErrorAsync("You are missing the permissions to view another user's warns."); + return ctx.Interaction.SendEphemeralErrorAsync( + "You are missing the permissions to view another user's warns."); } private async Task InternalWarnlog(ulong userId) @@ -231,7 +238,8 @@ private async Task InternalWarnlog(ulong userId) .WithDefaultEmotes() .WithActionOnCancellation(ActionOnStop.DeleteMessage) .Build(); - await interactivity.SendPaginatorAsync(paginator, Context.Interaction, TimeSpan.FromMinutes(60)).ConfigureAwait(false); + await interactivity.SendPaginatorAsync(paginator, Context.Interaction, TimeSpan.FromMinutes(60)) + .ConfigureAwait(false); async Task PageFactory(int page) { @@ -285,7 +293,8 @@ public async Task WarnlogAll() .WithActionOnCancellation(ActionOnStop.DeleteMessage) .Build(); - await interactivity.SendPaginatorAsync(paginator, Context.Interaction, TimeSpan.FromMinutes(60)).ConfigureAwait(false); + await interactivity.SendPaginatorAsync(paginator, Context.Interaction, TimeSpan.FromMinutes(60)) + .ConfigureAwait(false); async Task PageFactory(int page) { @@ -317,7 +326,8 @@ public async Task Warnclear(IGuildUser user, int index = 0) return; if (!await CheckRoleHierarchy(user)) return; - var success = await Service.WarnClearAsync(ctx.Guild.Id, user.Id, index, ctx.User.ToString()).ConfigureAwait(false); + var success = await Service.WarnClearAsync(ctx.Guild.Id, user.Id, index, ctx.User.ToString()) + .ConfigureAwait(false); var userStr = user.ToString(); if (index == 0) { @@ -401,7 +411,8 @@ await ReplyConfirmLocalizedAsync("warn_punish_set_timed", } } - [SlashCommand("warnpunishlist", "See how many warns does what"), RequireContext(ContextType.Guild), CheckPermissions] + [SlashCommand("warnpunishlist", "See how many warns does what"), RequireContext(ContextType.Guild), + CheckPermissions] public async Task WarnPunishList() { var ps = await Service.WarnPunishList(ctx.Guild.Id); @@ -489,7 +500,8 @@ private async Task InternalBanAsync( AuditLogReason = $"{ctx.User} | {reason}" }).ConfigureAwait(false); - await ctx.Interaction.RespondAsync(embed: new EmbedBuilder().WithOkColor().WithTitle($"⛔️ {GetText("banned_user")}") + await ctx.Interaction.RespondAsync(embed: new EmbedBuilder().WithOkColor() + .WithTitle($"⛔️ {GetText("banned_user")}") .AddField(efb => efb.WithName("ID").WithValue(userId.ToString()).WithIsInline(true)).Build()) .ConfigureAwait(false); } @@ -515,11 +527,14 @@ private async Task InternalBanAsync( try { var defaultMessage = GetText("bandm", Format.Bold(ctx.Guild.Name), reason); - var (embedBuilder, message, components) = await Service.GetBanUserDmEmbed(Context, user, defaultMessage, reason, null).ConfigureAwait(false); + var (embedBuilder, message, components) = await Service + .GetBanUserDmEmbed(Context, user, defaultMessage, reason, null).ConfigureAwait(false); if (embedBuilder is not null || message is not null) { var userChannel = await user.CreateDMChannelAsync().ConfigureAwait(false); - await userChannel.SendMessageAsync(message, embeds: embedBuilder, components: components?.Build()).ConfigureAwait(false); + await userChannel + .SendMessageAsync(message, embeds: embedBuilder, components: components?.Build()) + .ConfigureAwait(false); } } catch @@ -550,11 +565,14 @@ await ctx.Interaction.RespondAsync(embed: toSend.Build()) try { var defaultMessage = GetText("bandm", Format.Bold(ctx.Guild.Name), reason); - var (embedBuilder, message, components) = await Service.GetBanUserDmEmbed(ctx, user, defaultMessage, reason, null).ConfigureAwait(false); + var (embedBuilder, message, components) = await Service + .GetBanUserDmEmbed(ctx, user, defaultMessage, reason, null).ConfigureAwait(false); if (embedBuilder is not null || message is not null) { var userChannel = await user.CreateDMChannelAsync().ConfigureAwait(false); - await userChannel.SendMessageAsync(message, embeds: embedBuilder, components: components?.Build()).ConfigureAwait(false); + await userChannel + .SendMessageAsync(message, embeds: embedBuilder, components: components?.Build()) + .ConfigureAwait(false); } } catch @@ -605,8 +623,9 @@ private async Task UnbanInternal(IUser user) } [SlashCommand("softban", "Bans then unbans a user."), RequireContext(ContextType.Guild), - SlashUserPerm(GuildPermission.KickMembers | GuildPermission.ManageMessages), BotPerm(GuildPermission.BanMembers), CheckPermissions] - public async Task Softban(IGuildUser user, string? msg = null) => await SoftbanInternal(user, msg); + SlashUserPerm(GuildPermission.KickMembers | GuildPermission.ManageMessages), BotPerm(GuildPermission.BanMembers), + CheckPermissions] + public Task Softban(IGuildUser user, string? msg = null) => SoftbanInternal(user, msg); private async Task SoftbanInternal(IGuildUser user, string? msg = null) { @@ -651,7 +670,7 @@ await ctx.Interaction.RespondAsync(embed: toSend.Build()) [SlashCommand("kick", "Kicks a user with an optional reason"), RequireContext(ContextType.Guild), SlashUserPerm(GuildPermission.KickMembers), BotPerm(GuildPermission.KickMembers)] - public async Task Kick(IGuildUser user, string? msg = null) => await KickInternal(user, msg); + public Task Kick(IGuildUser user, string? msg = null) => KickInternal(user, msg); public async Task KickInternal(IGuildUser user, string? msg = null) diff --git a/src/Mewdeko/Modules/Moderation/SlashRoleMetadataCommands.cs b/src/Mewdeko/Modules/Moderation/SlashRoleMetadataCommands.cs index 226e0f48f..4f6e6fb79 100644 --- a/src/Mewdeko/Modules/Moderation/SlashRoleMetadataCommands.cs +++ b/src/Mewdeko/Modules/Moderation/SlashRoleMetadataCommands.cs @@ -17,8 +17,8 @@ public class SlashRoleMetadataCommands : MewdekoSlashSubmodule public DbService DbService { get; set; } [ComponentInteraction("auth_code.enter", true), RequireDragon] - public async Task HandleAuthStepTwo() - => await RespondWithModalAsync("auth_code.handshake"); + public Task HandleAuthStepTwo() + => RespondWithModalAsync("auth_code.handshake"); [ModalInteraction("auth_code.handshake", true)] public async Task HandleAuthHandshake(AuthHandshakeStepTwoModal modal) diff --git a/src/Mewdeko/Modules/Moderation/UserPunishCommands.cs b/src/Mewdeko/Modules/Moderation/UserPunishCommands.cs index 49a11677c..6c2d281e8 100644 --- a/src/Mewdeko/Modules/Moderation/UserPunishCommands.cs +++ b/src/Mewdeko/Modules/Moderation/UserPunishCommands.cs @@ -18,9 +18,12 @@ namespace Mewdeko.Modules.Moderation; public partial class Moderation : MewdekoModule { [Group] - public class UserPunishCommands(MuteService mute, DbService db, - InteractiveService serv, - NekosBestApi nekos, BotConfigService config) + public class UserPunishCommands( + MuteService mute, + DbService db, + InteractiveService serv, + NekosBestApi nekos, + BotConfigService config) : MewdekoSubmodule { public enum AddRole @@ -398,13 +401,13 @@ await ReplyConfirmLocalizedAsync("warn_expire_set_clear", Format.Bold(days.ToStr } [Cmd, Aliases, RequireContext(ContextType.Guild), Priority(3), UserPerm(GuildPermission.BanMembers)] - public async Task Warnlog(IGuildUser user) => await InternalWarnlog(user.Id); + public Task Warnlog(IGuildUser user) => InternalWarnlog(user.Id); - public async Task Warnlog() => await InternalWarnlog(ctx.User.Id); + public Task Warnlog() => InternalWarnlog(ctx.User.Id); [Cmd, Aliases, RequireContext(ContextType.Guild), UserPerm(GuildPermission.BanMembers), Priority(1)] - public async Task Warnlog(ulong userId) => await InternalWarnlog(userId); + public Task Warnlog(ulong userId) => InternalWarnlog(userId); private async Task InternalWarnlog(ulong userId) { @@ -826,10 +829,10 @@ public async Task BanMessage([Remainder] string? message = null) [Cmd, Aliases, RequireContext(ContextType.Guild), UserPerm(GuildPermission.BanMembers), BotPerm(GuildPermission.BanMembers)] - public async Task BanMsgReset() + public Task BanMsgReset() { Service.SetBanTemplate(Context.Guild.Id, null); - await ctx.OkAsync().ConfigureAwait(false); + return ctx.OkAsync(); } [Cmd, Aliases, RequireContext(ContextType.Guild), diff --git a/src/Mewdeko/Modules/MultiGreets/SlashMultiGreets.cs b/src/Mewdeko/Modules/MultiGreets/SlashMultiGreets.cs index e0bcbb031..64a09fa24 100644 --- a/src/Mewdeko/Modules/MultiGreets/SlashMultiGreets.cs +++ b/src/Mewdeko/Modules/MultiGreets/SlashMultiGreets.cs @@ -21,24 +21,26 @@ public enum MultiGreetTypes Off } - [SlashCommand("add", "Add a channel to MultiGreets."), SlashUserPerm(GuildPermission.Administrator), CheckPermissions] - public async Task MultiGreetAdd(ITextChannel? channel = null) + [SlashCommand("add", "Add a channel to MultiGreets."), SlashUserPerm(GuildPermission.Administrator), + CheckPermissions] + public Task MultiGreetAdd(ITextChannel? channel = null) { channel ??= ctx.Channel as ITextChannel; var added = Service.AddMultiGreet(ctx.Guild.Id, channel.Id); switch (added) { case true: - await ctx.Interaction.SendConfirmAsync($"Added {channel.Mention} as a MultiGreet channel!").ConfigureAwait(false); + return ctx.Interaction.SendConfirmAsync($"Added {channel.Mention} as a MultiGreet channel!"); break; case false: - await ctx.Interaction.SendErrorAsync( - "Seems like you have reached your 5 greets per channel limit or your 30 greets per guild limit! Remove a MultiGreet and try again").ConfigureAwait(false); + return ctx.Interaction.SendErrorAsync( + "Seems like you have reached your 5 greets per channel limit or your 30 greets per guild limit! Remove a MultiGreet and try again"); break; } } - [SlashCommand("remove", "Remove a channel from MultiGreets"), RequireContext(ContextType.Guild), SlashUserPerm(GuildPermission.Administrator), CheckPermissions] + [SlashCommand("remove", "Remove a channel from MultiGreets"), RequireContext(ContextType.Guild), + SlashUserPerm(GuildPermission.Administrator), CheckPermissions] public async Task MultiGreetRemove(int id) { var greet = Service.GetGreets(ctx.Guild.Id).ElementAt(id - 1); @@ -52,7 +54,8 @@ public async Task MultiGreetRemove(int id) await ctx.Interaction.SendConfirmAsync("MultiGreet removed!").ConfigureAwait(false); } - [SlashCommand("removechannel", "Removes all MultiGreets on that channel."), RequireContext(ContextType.Guild), SlashUserPerm(GuildPermission.Administrator), CheckPermissions] + [SlashCommand("removechannel", "Removes all MultiGreets on that channel."), RequireContext(ContextType.Guild), + SlashUserPerm(GuildPermission.Administrator), CheckPermissions] public async Task MultiGreetRemove(ITextChannel channel) { await ctx.Interaction.DeferAsync().ConfigureAwait(false); @@ -63,7 +66,10 @@ public async Task MultiGreetRemove(ITextChannel channel) return; } - if (await PromptUserConfirmAsync(new EmbedBuilder().WithOkColor().WithDescription("Are you sure you want to remove all MultiGreets for this channel?"), ctx.User.Id) + if (await PromptUserConfirmAsync( + new EmbedBuilder().WithOkColor() + .WithDescription("Are you sure you want to remove all MultiGreets for this channel?"), + ctx.User.Id) .ConfigureAwait(false)) { await Service.MultiRemoveMultiGreetInternal(greet.ToArray()).ConfigureAwait(false); @@ -71,9 +77,11 @@ public async Task MultiGreetRemove(ITextChannel channel) } } - [SlashCommand("delete", "Set how long it takes for a greet to delete"), RequireContext(ContextType.Guild), SlashUserPerm(GuildPermission.Administrator), + [SlashCommand("delete", "Set how long it takes for a greet to delete"), RequireContext(ContextType.Guild), + SlashUserPerm(GuildPermission.Administrator), RequireBotPermission(GuildPermission.ManageMessages), CheckPermissions] - public async Task MultiGreetDelete(int id, [Summary("Seconds", "After how long in seconds it should delete.")] int howlong) + public async Task MultiGreetDelete(int id, + [Summary("Seconds", "After how long in seconds it should delete.")] int howlong) { var greet = Service.GetGreets(ctx.Guild.Id).ElementAt(id - 1); if (greet is null) @@ -85,12 +93,14 @@ public async Task MultiGreetDelete(int id, [Summary("Seconds", "After how long i await Service.ChangeMgDelete(greet, howlong).ConfigureAwait(false); if (howlong > 0) await ctx.Interaction.SendConfirmAsync( - $"Successfully updated MultiGreet #{id} to delete after {TimeSpan.FromSeconds(howlong).Humanize()}.").ConfigureAwait(false); + $"Successfully updated MultiGreet #{id} to delete after {TimeSpan.FromSeconds(howlong).Humanize()}.") + .ConfigureAwait(false); else await ctx.Interaction.SendConfirmAsync($"MultiGreet #{id} will no longer delete.").ConfigureAwait(false); } - [SlashCommand("disable", "Disable a MultiGreet using its Id"), RequireContext(ContextType.Guild), SlashUserPerm(GuildPermission.Administrator), CheckPermissions] + [SlashCommand("disable", "Disable a MultiGreet using its Id"), RequireContext(ContextType.Guild), + SlashUserPerm(GuildPermission.Administrator), CheckPermissions] public async Task RoleGreetDisable(int num, bool enabled) { var greet = Service.GetGreets(ctx.Guild.Id).ElementAt(num - 1); @@ -104,7 +114,8 @@ public async Task RoleGreetDisable(int num, bool enabled) await ctx.Interaction.SendConfirmAsync($"MultiGreet {num} set to {enabled}").ConfigureAwait(false); } - [SlashCommand("type", "Enable RandomGreet, MultiGreet, or turn off the entire system."), RequireContext(ContextType.Guild), SlashUserPerm(GuildPermission.Administrator), + [SlashCommand("type", "Enable RandomGreet, MultiGreet, or turn off the entire system."), + RequireContext(ContextType.Guild), SlashUserPerm(GuildPermission.Administrator), CheckPermissions] public async Task MultiGreetType(MultiGreetTypes types) { @@ -125,7 +136,8 @@ public async Task MultiGreetType(MultiGreetTypes types) } } - [SlashCommand("webhook", "Set a custom name and avatar to use for each MultiGreet"), RequireContext(ContextType.Guild), SlashUserPerm(GuildPermission.Administrator), + [SlashCommand("webhook", "Set a custom name and avatar to use for each MultiGreet"), + RequireContext(ContextType.Guild), SlashUserPerm(GuildPermission.Administrator), RequireBotPermission(GuildPermission.ManageWebhooks), CheckPermissions] public async Task MultiGreetWebhook(int id, string? name = null, string? avatar = null) { @@ -149,7 +161,8 @@ public async Task MultiGreetWebhook(int id, string? name = null, string? avatar if (!Uri.IsWellFormedUriString(avatar, UriKind.Absolute)) { await ctx.Interaction.SendErrorAsync( - "The avatar url used is not a direct url or is invalid! Please use a different url.").ConfigureAwait(false); + "The avatar url used is not a direct url or is invalid! Please use a different url.") + .ConfigureAwait(false); return; } @@ -160,18 +173,22 @@ await ctx.Interaction.SendErrorAsync( var imgStream = imgData.ToStream(); await using var _ = imgStream.ConfigureAwait(false); var webhook = await channel.CreateWebhookAsync(name, imgStream).ConfigureAwait(false); - await Service.ChangeMgWebhook(greet, $"https://discord.com/api/webhooks/{webhook.Id}/{webhook.Token}").ConfigureAwait(false); + await Service.ChangeMgWebhook(greet, $"https://discord.com/api/webhooks/{webhook.Id}/{webhook.Token}") + .ConfigureAwait(false); await ctx.Interaction.SendConfirmAsync("Webhook set!").ConfigureAwait(false); } else { var webhook = await channel.CreateWebhookAsync(name).ConfigureAwait(false); - await Service.ChangeMgWebhook(greet, $"https://discord.com/api/webhooks/{webhook.Id}/{webhook.Token}").ConfigureAwait(false); + await Service.ChangeMgWebhook(greet, $"https://discord.com/api/webhooks/{webhook.Id}/{webhook.Token}") + .ConfigureAwait(false); await ctx.Interaction.SendConfirmAsync("Webhook set!").ConfigureAwait(false); } } - [SlashCommand("message", "Set a custom message for each MultiGreet. https://mewdeko.tech/placeholders https://eb.mewdeko.tech"), RequireContext(ContextType.Guild), + [SlashCommand("message", + "Set a custom message for each MultiGreet. https://mewdeko.tech/placeholders https://eb.mewdeko.tech"), + RequireContext(ContextType.Guild), SlashUserPerm(GuildPermission.Administrator), CheckPermissions] public async Task MultiGreetMessage(int id, string? message = null) { @@ -187,18 +204,23 @@ public async Task MultiGreetMessage(int id, string? message = null) { var components = new ComponentBuilder().WithButton("Preview", "preview").WithButton("Regular", "regular"); var msg = await ctx.Interaction.SendConfirmFollowupAsync( - "Would you like to view this as regular text or would you like to preview how it actually looks?", components).ConfigureAwait(false); + "Would you like to view this as regular text or would you like to preview how it actually looks?", + components).ConfigureAwait(false); var response = await GetButtonInputAsync(ctx.Interaction.Id, msg.Id, ctx.User.Id).ConfigureAwait(false); switch (response) { case "preview": await msg.DeleteAsync().ConfigureAwait(false); - var replacer = new ReplacementBuilder().WithUser(ctx.User).WithClient(ctx.Client as DiscordSocketClient) + var replacer = new ReplacementBuilder().WithUser(ctx.User) + .WithClient(ctx.Client as DiscordSocketClient) .WithServer(ctx.Client as DiscordSocketClient, ctx.Guild as SocketGuild).Build(); var content = replacer.Replace(greet.Message); - if (SmartEmbed.TryParse(content, ctx.Guild.Id, out var embedData, out var plainText, out var components2)) + if (SmartEmbed.TryParse(content, ctx.Guild.Id, out var embedData, out var plainText, + out var components2)) { - await ctx.Interaction.FollowupAsync(plainText, embeds: embedData, components: components2.Build()).ConfigureAwait(false); + await ctx.Interaction + .FollowupAsync(plainText, embeds: embedData, components: components2.Build()) + .ConfigureAwait(false); } else { @@ -214,10 +236,12 @@ public async Task MultiGreetMessage(int id, string? message = null) } await Service.ChangeMgMessage(greet, message).ConfigureAwait(false); - await ctx.Interaction.SendConfirmFollowupAsync($"MultiGreet Message for MultiGreet #{id} set!").ConfigureAwait(false); + await ctx.Interaction.SendConfirmFollowupAsync($"MultiGreet Message for MultiGreet #{id} set!") + .ConfigureAwait(false); } - [SlashCommand("list", "Lists all current MultiGreets"), RequireContext(ContextType.Guild), SlashUserPerm(GuildPermission.Administrator), CheckPermissions] + [SlashCommand("list", "Lists all current MultiGreets"), RequireContext(ContextType.Guild), + SlashUserPerm(GuildPermission.Administrator), CheckPermissions] public async Task MultiGreetList() { var greets = Service.GetGreets(ctx.Guild.Id); diff --git a/src/Mewdeko/Modules/Nsfw/Nsfw.cs b/src/Mewdeko/Modules/Nsfw/Nsfw.cs index 67b6bc90a..6e4080b77 100644 --- a/src/Mewdeko/Modules/Nsfw/Nsfw.cs +++ b/src/Mewdeko/Modules/Nsfw/Nsfw.cs @@ -16,9 +16,13 @@ namespace Mewdeko.Modules.Nsfw; -public class Nsfw(InteractiveService interactivity, MartineApi martineApi, - GuildSettingsService guildSettings, HttpClient client, - BotConfigService config, IBotCredentials credentials) +public class Nsfw( + InteractiveService interactivity, + MartineApi martineApi, + GuildSettingsService guildSettings, + HttpClient client, + BotConfigService config, + IBotCredentials credentials) : MewdekoModuleBase { private static readonly ConcurrentHashSet HentaiBombBlacklist = new(); @@ -199,39 +203,39 @@ async Task PageFactory(int page1) } [Cmd, Aliases, RequireContext(ContextType.Guild), RequireNsfw] - public async Task HentaiGif() => await RedditNsfw("HENTAI_GIF").ConfigureAwait(false); + public Task HentaiGif() => RedditNsfw("HENTAI_GIF"); [Cmd, Aliases, RequireContext(ContextType.Guild), RequireNsfw] - public async Task Pussy() => await RedditNsfw("pussy").ConfigureAwait(false); + public Task Pussy() => RedditNsfw("pussy"); [Cmd, Aliases, RequireContext(ContextType.Guild), RequireNsfw] - public async Task Anal() => await RedditNsfw("anal").ConfigureAwait(false); + public Task Anal() => RedditNsfw("anal"); [Cmd, Aliases, RequireContext(ContextType.Guild), RequireNsfw] - public async Task Porn() => await RedditNsfw("porn").ConfigureAwait(false); + public Task Porn() => RedditNsfw("porn"); [Cmd, Aliases, RequireContext(ContextType.Guild), RequireNsfw] - public async Task Bondage() => await RedditNsfw("bondage").ConfigureAwait(false); + public Task Bondage() => RedditNsfw("bondage"); [Cmd, Aliases, RequireContext(ContextType.Guild), RequireNsfw] - public async Task NHentaiSearch([Remainder] string search) => - await InternalNHentaiSearch(search).ConfigureAwait(false); + public Task NHentaiSearch([Remainder] string search) => + InternalNHentaiSearch(search); [Cmd, Aliases, RequireContext(ContextType.Guild), RequireNsfw] - public async Task NHentaiSearch(string search, [Remainder] string blacklist) => - await InternalNHentaiSearch(search, 1, blacklist).ConfigureAwait(false); + public Task NHentaiSearch(string search, [Remainder] string blacklist) => + InternalNHentaiSearch(search, 1, blacklist); [Cmd, Aliases, RequireContext(ContextType.Guild), RequireNsfw] - public async Task NHentaiSearch(string search, int page) => - await InternalNHentaiSearch(search, page).ConfigureAwait(false); + public Task NHentaiSearch(string search, int page) => + InternalNHentaiSearch(search, page); [Cmd, Aliases, RequireContext(ContextType.Guild), RequireNsfw] - public async Task NHentaiSearch(string search, int page, string type) => - await InternalNHentaiSearch(search, page, type).ConfigureAwait(false); + public Task NHentaiSearch(string search, int page, string type) => + InternalNHentaiSearch(search, page, type); [Cmd, Aliases, RequireContext(ContextType.Guild), RequireNsfw] - public async Task NHentaiSearch(string search, int page, string type, [Remainder] string blacklist) => - await InternalNHentaiSearch(search, page, type, blacklist).ConfigureAwait(false); + public Task NHentaiSearch(string search, int page, string type, [Remainder] string blacklist) => + InternalNHentaiSearch(search, page, type, blacklist); [Cmd, Aliases] [RequireNsfw] @@ -496,11 +500,11 @@ public Task Realbooru(params string[] tags) [Cmd, Aliases] [RequireNsfw(Group = "nsfw_or_dm"), RequireContext(ContextType.DM, Group = "nsfw_or_dm")] - public async Task Boobs() => await RedditNsfw("boobs").ConfigureAwait(false); + public Task Boobs() => RedditNsfw("boobs"); [Cmd, Aliases] [RequireNsfw(Group = "nsfw_or_dm"), RequireContext(ContextType.DM, Group = "nsfw_or_dm")] - public async Task Butts() => await RedditNsfw("ass").ConfigureAwait(false); + public Task Butts() => RedditNsfw("ass"); [Cmd, Aliases] [RequireContext(ContextType.Guild)] diff --git a/src/Mewdeko/Modules/OwnerOnly/OwnerOnly.cs b/src/Mewdeko/Modules/OwnerOnly/OwnerOnly.cs index 3be59276a..215797c1d 100644 --- a/src/Mewdeko/Modules/OwnerOnly/OwnerOnly.cs +++ b/src/Mewdeko/Modules/OwnerOnly/OwnerOnly.cs @@ -207,7 +207,7 @@ public async Task Sudo(IGuildUser user, [Remainder] string args) Content = $"{await guildSettings.GetPrefix(ctx.Guild)}{args}", Author = user, Channel = ctx.Channel }; commandHandler.AddCommandToParseQueue(msg); - _ = Task.Run(async () => await commandHandler.ExecuteCommandsInChannelAsync(ctx.Channel.Id)) + _ = Task.Run(() => commandHandler.ExecuteCommandsInChannelAsync(ctx.Channel.Id)) .ConfigureAwait(false); } @@ -221,7 +221,7 @@ public async Task Sudo([Remainder] string args) Channel = ctx.Channel }; commandHandler.AddCommandToParseQueue(msg); - _ = Task.Run(async () => await commandHandler.ExecuteCommandsInChannelAsync(ctx.Channel.Id)) + _ = Task.Run(() => commandHandler.ExecuteCommandsInChannelAsync(ctx.Channel.Id)) .ConfigureAwait(false); } @@ -907,8 +907,8 @@ public async Task SetStream(string url, [Remainder] string? name = null) } [Cmd, Aliases] - public async Task Send(ulong whereOrTo, [Remainder] string msg) - => await Send(whereOrTo, 0, msg).ConfigureAwait(false); + public Task Send(ulong whereOrTo, [Remainder] string msg) + => Send(whereOrTo, 0, msg); [Cmd, Aliases] public async Task Send(ulong whereOrTo, ulong to = 0, [Remainder] string? msg = null) diff --git a/src/Mewdeko/Modules/OwnerOnly/SlashOwnerOnly.cs b/src/Mewdeko/Modules/OwnerOnly/SlashOwnerOnly.cs index 60f6fc9f3..e8a720158 100644 --- a/src/Mewdeko/Modules/OwnerOnly/SlashOwnerOnly.cs +++ b/src/Mewdeko/Modules/OwnerOnly/SlashOwnerOnly.cs @@ -63,7 +63,7 @@ public async Task Sudo([Remainder] string args, IUser user = null) Content = $"{await guildSettings.GetPrefix(ctx.Guild)}{args}", Author = user, Channel = ctx.Channel }; commandHandler.AddCommandToParseQueue(msg); - _ = Task.Run(async () => await commandHandler.ExecuteCommandsInChannelAsync(ctx.Interaction.Id)) + _ = Task.Run(() => commandHandler.ExecuteCommandsInChannelAsync(ctx.Interaction.Id)) .ConfigureAwait(false); } @@ -368,44 +368,44 @@ public async Task AutoCommandRemove([Remainder] int index) [SlashCommand("startupcommandremove", "Removes a startup command"), Discord.Interactions.RequireContext(Discord.Interactions.ContextType.Guild)] - public async Task StartupCommandRemove([Remainder] int index) + public Task StartupCommandRemove([Remainder] int index) { if (!Service.RemoveStartupCommand(--index, out _)) - await ReplyErrorLocalizedAsync("scrm_fail").ConfigureAwait(false); + return ReplyErrorLocalizedAsync("scrm_fail"); else - await ReplyConfirmLocalizedAsync("scrm").ConfigureAwait(false); + return ReplyConfirmLocalizedAsync("scrm"); } [SlashCommand("startupcommandsclear", "Clears all startup commands"), Discord.Interactions.RequireContext(Discord.Interactions.ContextType.Guild), SlashUserPerm(GuildPermission.Administrator)] - public async Task StartupCommandsClear() + public Task StartupCommandsClear() { Service.ClearStartupCommands(); - await ReplyConfirmLocalizedAsync("startcmds_cleared").ConfigureAwait(false); + return ReplyConfirmLocalizedAsync("startcmds_cleared"); } [SlashCommand("forwardmessages", "Toggles whether to forward dms to the bot to owner dms")] - public async Task ForwardMessages() + public Task ForwardMessages() { var enabled = Service.ForwardMessages(); if (enabled) - await ReplyConfirmLocalizedAsync("fwdm_start").ConfigureAwait(false); + return ReplyConfirmLocalizedAsync("fwdm_start"); else - await ReplyConfirmLocalizedAsync("fwdm_stop").ConfigureAwait(false); + return ReplyConfirmLocalizedAsync("fwdm_stop"); } [SlashCommand("forwardtoall", "Toggles whether to forward dms to the bot to all bot owners")] - public async Task ForwardToAll() + public Task ForwardToAll() { var enabled = Service.ForwardToAll(); if (enabled) - await ReplyConfirmLocalizedAsync("fwall_start").ConfigureAwait(false); + return ReplyConfirmLocalizedAsync("fwall_start"); else - await ReplyConfirmLocalizedAsync("fwall_stop").ConfigureAwait(false); + return ReplyConfirmLocalizedAsync("fwall_stop"); } [SlashCommand("setname", "Sets the bots name")] @@ -571,12 +571,12 @@ private static string GetPropsAndValuesString(IConfigService config, IEnumerable public class StatusCommands(Mewdeko bot, DiscordSocketClient client) : MewdekoSlashModuleBase { [SlashCommand("rotateplaying", "Toggles rotating playing status")] - public async Task RotatePlaying() + public Task RotatePlaying() { if (Service.ToggleRotatePlaying()) - await ReplyConfirmLocalizedAsync("ropl_enabled").ConfigureAwait(false); + return ReplyConfirmLocalizedAsync("ropl_enabled"); else - await ReplyConfirmLocalizedAsync("ropl_disabled").ConfigureAwait(false); + return ReplyConfirmLocalizedAsync("ropl_disabled"); } [SlashCommand("addplaying", "Adds a playing status to the rotating status list")] @@ -588,20 +588,19 @@ public async Task AddPlaying(ActivityType t, [Remainder] string status) } [SlashCommand("listplaying", "Lists all rotating statuses")] - public async Task ListPlaying() + public Task ListPlaying() { var statuses = Service.GetRotatingStatuses(); if (statuses.Count == 0) { - await ReplyErrorLocalizedAsync("ropl_not_set").ConfigureAwait(false); + return ReplyErrorLocalizedAsync("ropl_not_set"); } else { var i = 1; - await ReplyConfirmLocalizedAsync("ropl_list", - string.Join("\n\t", statuses.Select(rs => $"`{i++}.` *{rs.Type}* {rs.Status}"))) - .ConfigureAwait(false); + return ReplyConfirmLocalizedAsync("ropl_list", + string.Join("\n\t", statuses.Select(rs => $"`{i++}.` *{rs.Type}* {rs.Status}"))); } } @@ -712,13 +711,13 @@ private static string ConnectionStateToEmoji(ShardStatus status) } [SlashCommand("restartshard", "Restarts a shard by its number")] - public async Task RestartShard(int shardId) + public Task RestartShard(int shardId) { var success = coord.RestartShard(shardId); if (success) - await ReplyConfirmLocalizedAsync("shard_reconnecting", Format.Bold($"#{shardId}")).ConfigureAwait(false); + return ReplyConfirmLocalizedAsync("shard_reconnecting", Format.Bold($"#{shardId}")); else - await ReplyErrorLocalizedAsync("no_shard_id").ConfigureAwait(false); + return ReplyErrorLocalizedAsync("no_shard_id"); } [SlashCommand("leaveserver", "Leaves a server by id or name")] @@ -848,17 +847,17 @@ await ctx.Interaction.SendConfirmAsync($"Message sent to {potentialServer} in {u } [SlashCommand("imagesreload", "Recaches and redownloads all images")] - public async Task ImagesReload() + public Task ImagesReload() { Service.ReloadImages(); - await ReplyConfirmLocalizedAsync("images_loading", 0).ConfigureAwait(false); + return ReplyConfirmLocalizedAsync("images_loading", 0); } [SlashCommand("stringsreload", "Reloads localized strings")] - public async Task StringsReload() + public Task StringsReload() { strings.Reload(); - await ReplyConfirmLocalizedAsync("bot_strings_reloaded").ConfigureAwait(false); + return ReplyConfirmLocalizedAsync("bot_strings_reloaded"); } private static UserStatus SettableUserStatusToUserStatus(SettableUserStatus sus) => @@ -969,8 +968,8 @@ await ctx.Interaction.FollowupAsync("The process was hanging and has been termin } [SlashCommand("eval", "Eval C# code"), OwnerOnly] - public async Task Evaluate() - => await ctx.Interaction.RespondWithModalAsync("evalhandle"); + public Task Evaluate() + => ctx.Interaction.RespondWithModalAsync("evalhandle"); [ModalInteraction("evalhandle", true)] public async Task EvaluateModalInteraction(EvalModal modal) diff --git a/src/Mewdeko/Modules/Permissions/SlashPermissions.cs b/src/Mewdeko/Modules/Permissions/SlashPermissions.cs index 02d2df6b5..fc55a6cc4 100644 --- a/src/Mewdeko/Modules/Permissions/SlashPermissions.cs +++ b/src/Mewdeko/Modules/Permissions/SlashPermissions.cs @@ -922,7 +922,7 @@ public async Task ToggleCommanddisabled(string commandName) [ComponentInteraction("local_perms_reset.*", true)] [SlashUserPerm(GuildPermission.Administrator)] - public async Task LocalPermsReset(string commandName) + public Task LocalPermsReset(string commandName) { IList perms; @@ -939,12 +939,12 @@ public async Task LocalPermsReset(string commandName) if (dpoS.TryGetOverrides(ctx.Guild.Id, commandName, out _)) _ = dpoS.RemoveOverride(ctx.Guild.Id, commandName); - await UpdateMessageWithPermenu(commandName); + return UpdateMessageWithPermenu(commandName); } [ComponentInteraction("cmd_perm_spawner.*", true)] [SlashUserPerm(GuildPermission.Administrator)] - public async Task CommandPermSpawner(string commandName, string[] values) => await (values.First() switch + public Task CommandPermSpawner(string commandName, string[] values) => values.First() switch { "dpo" => CommandPermsDpo(commandName), "usr" => CommandPermsUsr(commandName, true, true, ""), @@ -952,12 +952,12 @@ public async Task LocalPermsReset(string commandName) "chn" => CommandPermsChn(commandName, true, true, ""), "cat" => CommandPermsCat(commandName, true, true, ""), _ => UpdateMessageWithPermenu(commandName) - }); + }; [ComponentInteraction("cmd_perm_spawner_dpo.*", true)] [SlashUserPerm(GuildPermission.Administrator)] - public async Task CommandPermsDpo(string commandName) + public Task CommandPermsDpo(string commandName) { var perms = Enum.GetValues(); List selects = new(); @@ -996,7 +996,7 @@ public async Task CommandPermsDpo(string commandName) .WithButton(GetText("back"), $"permenu_update.{commandName}", emote: "<:perms_back_arrow:1085352564943491102>".ToIEmote()); - await (ctx.Interaction as SocketMessageComponent).UpdateAsync(x => x.Components = cb.Build()); + return (ctx.Interaction as SocketMessageComponent).UpdateAsync(x => x.Components = cb.Build()); } [ComponentInteraction("update_cmd_dpo.*$*", true)] @@ -1032,7 +1032,7 @@ public async Task UpdateCommandDpo(string commandName, int index, string[] value [ComponentInteraction("command_perm_spawner_usr.*.*.*$*", true)] [SlashUserPerm(GuildPermission.Administrator)] - public async Task CommandPermsUsr(string commandName, bool overwright, bool allow, string _) + public Task CommandPermsUsr(string commandName, bool overwright, bool allow, string _) { // perm testing code, quickly add dummy allow or deny objects to the end of the perm list // please do not remove or enable without dissabling before commiting @@ -1114,7 +1114,7 @@ public async Task CommandPermsUsr(string commandName, bool overwright, bool allo placeholder: GetText("perm_quick_options_add_users"), minValues: 1, maxValues: 10, type: ComponentType.UserSelect, options: null); - await (Context.Interaction as SocketMessageComponent).UpdateAsync(x => x.Components = cb.Build()); + return (Context.Interaction as SocketMessageComponent).UpdateAsync(x => x.Components = cb.Build()); } [ComponentInteraction("perm_quick_options_user_remove.*.*.*$*", true)] @@ -1205,18 +1205,18 @@ public async Task AddUserOveride(string commandName, bool overwright, bool allow [ComponentInteraction("help_component_restore.*", true)] - public async Task HelpComponentRestore(string commandName) + public Task HelpComponentRestore(string commandName) { var cb = new ComponentBuilder() .WithButton(GetText("help_run_cmd"), $"runcmd.{commandName}", ButtonStyle.Success) .WithButton(GetText("help_permenu_link"), $"permenu_update.{commandName}", ButtonStyle.Primary, Emote.Parse("<:IconPrivacySettings:845090111976636446>")); - await (ctx.Interaction as SocketMessageComponent).UpdateAsync(x => x.Components = cb.Build()); + return (ctx.Interaction as SocketMessageComponent).UpdateAsync(x => x.Components = cb.Build()); } [ComponentInteraction("command_perm_spawner_rol.*.*.*$*", true)] [SlashUserPerm(GuildPermission.Administrator)] - public async Task CommandPermsRol(string commandName, bool overwright, bool allow, string _) + public Task CommandPermsRol(string commandName, bool overwright, bool allow, string _) { // perm testing code, quickly add dummy allow or deny objects to the end of the perm list // please do not remove or enable without dissabling before commiting @@ -1297,7 +1297,7 @@ public async Task CommandPermsRol(string commandName, bool overwright, bool allo placeholder: GetText("perm_quick_options_add_roles"), minValues: 1, maxValues: 10, type: ComponentType.RoleSelect, options: null); - await (Context.Interaction as SocketMessageComponent).UpdateAsync(x => x.Components = cb.Build()); + return (Context.Interaction as SocketMessageComponent).UpdateAsync(x => x.Components = cb.Build()); } [ComponentInteraction("perm_quick_options_role_remove.*.*.*$*", true)] @@ -1386,7 +1386,7 @@ public async Task AddRoleOveride(string commandName, bool overwright, bool allow [ComponentInteraction("command_perm_spawner_chn.*.*.*$*", true)] [SlashUserPerm(GuildPermission.Administrator)] - public async Task CommandPermsChn(string commandName, bool overwright, bool allow, string _) + public Task CommandPermsChn(string commandName, bool overwright, bool allow, string _) { // perm testing code, quickly add dummy allow or deny objects to the end of the perm list // please do not remove or enable without dissabling before commiting @@ -1467,7 +1467,7 @@ public async Task CommandPermsChn(string commandName, bool overwright, bool allo type: ComponentType.ChannelSelect, options: null, channelTypes: Enum.GetValues().Where(x => x != ChannelType.Category).ToArray()); - await (Context.Interaction as SocketMessageComponent).UpdateAsync(x => x.Components = cb.Build()); + return (Context.Interaction as SocketMessageComponent).UpdateAsync(x => x.Components = cb.Build()); } @@ -1560,7 +1560,7 @@ public async Task AddChannelOveride(string commandName, bool overwright, bool al [ComponentInteraction("command_perm_spawner_cat.*.*.*$*", true)] [SlashUserPerm(GuildPermission.Administrator)] - public async Task CommandPermsCat(string commandName, bool overwright, bool allow, string _) + public Task CommandPermsCat(string commandName, bool overwright, bool allow, string _) { // perm testing code, quickly add dummy allow or deny objects to the end of the perm list // please do not remove or enable without dissabling before commiting @@ -1645,7 +1645,7 @@ public async Task CommandPermsCat(string commandName, bool overwright, bool allo ChannelType.Category }); - await (Context.Interaction as SocketMessageComponent).UpdateAsync(x => x.Components = cb.Build()); + return (Context.Interaction as SocketMessageComponent).UpdateAsync(x => x.Components = cb.Build()); } diff --git a/src/Mewdeko/Modules/RoleStates/Services/RoleStatesService.cs b/src/Mewdeko/Modules/RoleStates/Services/RoleStatesService.cs index d1b99816a..7a71587eb 100644 --- a/src/Mewdeko/Modules/RoleStates/Services/RoleStatesService.cs +++ b/src/Mewdeko/Modules/RoleStates/Services/RoleStatesService.cs @@ -147,9 +147,9 @@ public async Task ToggleRoleStates(ulong guildId) return await db.UserRoleStates.FirstOrDefaultAsync(x => x.GuildId == guildId && x.UserId == userId) ?? null; } - public async Task> GetAllUserRoleStates(ulong guildId) + public Task> GetAllUserRoleStates(ulong guildId) { - return await dbService.GetDbContext().UserRoleStates.Where(x => x.GuildId == guildId).ToListAsync(); + return dbService.GetDbContext().UserRoleStates.Where(x => x.GuildId == guildId).ToListAsync(); } public async Task UpdateRoleStateSettings(RoleStateSettings roleStateSettings) diff --git a/src/Mewdeko/Modules/Searches/AnimeCommands.cs b/src/Mewdeko/Modules/Searches/AnimeCommands.cs index 77d0dfab0..4c17840e4 100644 --- a/src/Mewdeko/Modules/Searches/AnimeCommands.cs +++ b/src/Mewdeko/Modules/Searches/AnimeCommands.cs @@ -20,9 +20,12 @@ namespace Mewdeko.Modules.Searches; public partial class Searches { [Group] - public class AnimeCommands(InteractiveService service, MartineApi martineApi, NekosBestApi nekosBestApi, - HttpClient httpClient, - BotConfigService config) + public class AnimeCommands( + InteractiveService service, + MartineApi martineApi, + NekosBestApi nekosBestApi, + HttpClient httpClient, + BotConfigService config) : MewdekoSubmodule { public readonly NekosBestApi NekosBestApi = nekosBestApi; @@ -77,8 +80,8 @@ await ctx.Channel.SendFileAsync(ms, "ship.png", } [Cmd, Aliases] - public async Task Ship(IUser user) - => await Ship(ctx.User, user); + public Task Ship(IUser user) + => Ship(ctx.User, user); [Cmd, Aliases] public async Task RandomNeko() diff --git a/src/Mewdeko/Modules/Searches/Searches.cs b/src/Mewdeko/Modules/Searches/Searches.cs index 5ee64b7c7..2e5ea0cbd 100644 --- a/src/Mewdeko/Modules/Searches/Searches.cs +++ b/src/Mewdeko/Modules/Searches/Searches.cs @@ -25,12 +25,17 @@ namespace Mewdeko.Modules.Searches; -public partial class Searches(IBotCredentials creds, IGoogleApiService google, IHttpClientFactory factory, - IMemoryCache cache, - GuildTimezoneService tzSvc, - InteractiveService serv, - MartineApi martineApi, ToneTagService toneTagService, - BotConfigService config, INsfwSpy nsfwSpy) +public partial class Searches( + IBotCredentials creds, + IGoogleApiService google, + IHttpClientFactory factory, + IMemoryCache cache, + GuildTimezoneService tzSvc, + InteractiveService serv, + MartineApi martineApi, + ToneTagService toneTagService, + BotConfigService config, + INsfwSpy nsfwSpy) : MewdekoModuleBase { private static readonly ConcurrentDictionary CachedShortenedLinks = new(); @@ -734,14 +739,14 @@ public async Task Catfact() [Cmd, Aliases, RequireContext(ContextType.Guild)] - public async Task Revav([Remainder] IGuildUser? usr = null) + public Task Revav([Remainder] IGuildUser? usr = null) { usr ??= (IGuildUser)ctx.User; var av = usr.RealAvatarUrl(); // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract - await Revimg(av.ToString()); + return Revimg(av.ToString()); } diff --git a/src/Mewdeko/Modules/Searches/Services/SearchesService.cs b/src/Mewdeko/Modules/Searches/Services/SearchesService.cs index 39171fd41..094dc187d 100644 --- a/src/Mewdeko/Modules/Searches/Services/SearchesService.cs +++ b/src/Mewdeko/Modules/Searches/Services/SearchesService.cs @@ -174,11 +174,11 @@ public Task Unload() return Task.CompletedTask; } - public async Task SetShip(ulong user1, ulong user2, int score) - => await cache.SetShip(user1, user2, score); + public Task SetShip(ulong user1, ulong user2, int score) + => cache.SetShip(user1, user2, score); - public async Task GetShip(ulong user1, ulong user2) - => await cache.GetShip(user1, user2); + public Task GetShip(ulong user1, ulong user2) + => cache.GetShip(user1, user2); public async Task GetRipPictureAsync(string text, Uri imgUrl) { diff --git a/src/Mewdeko/Modules/Searches/SlashToneTags.cs b/src/Mewdeko/Modules/Searches/SlashToneTags.cs index e748c3d14..19ee1bb47 100644 --- a/src/Mewdeko/Modules/Searches/SlashToneTags.cs +++ b/src/Mewdeko/Modules/Searches/SlashToneTags.cs @@ -8,11 +8,11 @@ namespace Mewdeko.Modules.Searches; public class SlashToneTags : MewdekoSlashModuleBase { [SlashCommand("tone-tags", "Search for a specified tone tag."), CheckPermissions] - public async Task Search( + public Task Search( [Summary("query", "the tone tag to search for.")] [Autocomplete(typeof(ToneTagAutocompleter))] string query) => - await RespondAsync(embed: Service.GetEmbed(Service.ParseTags(query)).Build(), ephemeral: true).ConfigureAwait(false); + RespondAsync(embed: Service.GetEmbed(Service.ParseTags(query)).Build(), ephemeral: true); [MessageCommand("Tone Tags")] - public async Task ToneTags(SocketMessage message) => await Search(message.Content).ConfigureAwait(false); + public Task ToneTags(SocketMessage message) => Search(message.Content); } \ No newline at end of file diff --git a/src/Mewdeko/Modules/Server Management/ChannelCommands.cs b/src/Mewdeko/Modules/Server Management/ChannelCommands.cs index 4ed2afad2..22607fabf 100644 --- a/src/Mewdeko/Modules/Server Management/ChannelCommands.cs +++ b/src/Mewdeko/Modules/Server Management/ChannelCommands.cs @@ -314,22 +314,22 @@ await ctx.Channel.SendMessageAsync($"{config.Data.SuccessEmote} Unlocked {channe [Cmd, Aliases, RequireContext(ContextType.Guild), UserPerm(GuildPermission.ManageChannels)] - public static async Task Slowmode(StoopidTime time, ITextChannel channel) => - await InternalSlowmode(channel, (int)time.Time.TotalSeconds).ConfigureAwait(false); + public static Task Slowmode(StoopidTime time, ITextChannel channel) => + InternalSlowmode(channel, (int)time.Time.TotalSeconds); [Cmd, Aliases, RequireContext(ContextType.Guild), UserPerm(GuildPermission.ManageChannels)] - public async Task Slowmode(StoopidTime time) => - await InternalSlowmode(ctx.Channel as ITextChannel, (int)time.Time.TotalSeconds).ConfigureAwait(false); + public Task Slowmode(StoopidTime time) => + InternalSlowmode(ctx.Channel as ITextChannel, (int)time.Time.TotalSeconds); [Cmd, Aliases, RequireContext(ContextType.Guild), UserPerm(GuildPermission.ManageChannels)] - public static async Task Slowmode(ITextChannel channel) => - await InternalSlowmode(channel).ConfigureAwait(false); + public static Task Slowmode(ITextChannel channel) => + InternalSlowmode(channel); [Cmd, Aliases, RequireContext(ContextType.Guild), UserPerm(GuildPermission.ManageChannels)] - public async Task Slowmode() => await InternalSlowmode((ITextChannel)ctx.Channel).ConfigureAwait(false); + public Task Slowmode() => InternalSlowmode((ITextChannel)ctx.Channel); private static async Task InternalSlowmode(ITextChannel channel, int time = 0) { diff --git a/src/Mewdeko/Modules/StatusRoles/Services/StatusRolesService.cs b/src/Mewdeko/Modules/StatusRoles/Services/StatusRolesService.cs index 9581123b0..c54c97f8a 100644 --- a/src/Mewdeko/Modules/StatusRoles/Services/StatusRolesService.cs +++ b/src/Mewdeko/Modules/StatusRoles/Services/StatusRolesService.cs @@ -9,7 +9,7 @@ public class StatusRolesService : INService, IReadyExecutor private readonly DiscordSocketClient client; private readonly DbService db; private readonly IDataCache cache; - private readonly HashSet statusRoles = new(); + private readonly HashSet statusRoles = []; public StatusRolesService(DiscordSocketClient client, DbService db, EventHandler eventHandler, IDataCache cache) { @@ -34,141 +34,83 @@ private async Task EventHandlerOnPresenceUpdated(SocketUser args, SocketPresence { try { - if (!this.statusRoles.Any()) + // Early exit if there are no status roles + if (this.statusRoles.Count == 0) return; + // Ensure the incoming user is a guild user if (args is not SocketGuildUser user) return; + // Get the status of the user before and after the event var beforeStatus = args2?.Activities?.FirstOrDefault() as CustomStatusGame; - if (args3.Activities?.FirstOrDefault() is not CustomStatusGame status) - { - return; - } + var afterStatus = args3.Activities?.FirstOrDefault() as CustomStatusGame; - if (status.State is null && beforeStatus?.State is null || status.State == beforeStatus?.State) - { + // Continue only if the event is non-null and status has changed + if (afterStatus == null || afterStatus.State == beforeStatus?.State) return; - } - if (!await cache.SetUserStatusCache(args.Id, - status.State?.ToBase64() is null ? "none" : status.State.ToBase64())) - { + // Update user status in cache only if status has changed + var newStatusBase64 = afterStatus.State?.ToBase64() ?? "none"; + if (!await cache.SetUserStatusCache(args.Id, newStatusBase64)) return; - } - await using var uow = db.GetDbContext(); - var statusRolesConfigs = this.statusRoles; - if (statusRolesConfigs is null || !statusRolesConfigs.Any()) - { + // Check for any statusRoles, if there are none, no further actions needed + if (statusRoles.Count == 0) return; - } - var statusRolesTables = statusRolesConfigs.Where(x => x.GuildId == user.Guild.Id).ToList(); + // Fetch role ids of user to local variable + var userRoleIds = user.Roles.Select(x => x.Id).ToList(); + + // Filter statusRoles for a particular guild + var statusRolesTables = statusRoles.Where(x => x.GuildId == user.Guild.Id); - foreach (var i in statusRolesTables) + // Loops through each status role in the guild + foreach (var config in statusRolesTables) { - var toAdd = new List(); - var toRemove = new List(); - if (!string.IsNullOrWhiteSpace(i.ToAdd)) - toAdd = i.ToAdd.Split(" ").Select(ulong.Parse).ToList(); - if (!string.IsNullOrWhiteSpace(i.ToRemove)) - toRemove = i.ToRemove.Split(" ").Select(ulong.Parse).ToList(); - if (status.State is null || !status.State.Contains(i.Status)) - { - if (beforeStatus is not null && beforeStatus.State.Contains(i.Status)) - { - if (i.RemoveAdded == 1) - { - if (toAdd.Any()) - { - foreach (var role in toAdd.Where(socketRole => - user.Roles.Select(x => x.Id).Contains(socketRole))) - { - try - { - await user.RemoveRoleAsync(role); - } - catch - { - Log.Error( - "Unable to remove added role {Role} for {User} in {UserGuild} due to permission issues", - role, user, user.Guild); - } - } - } - } + var toAdd = string.IsNullOrWhiteSpace(config.ToAdd) + ? new List() + : config.ToAdd.Split(" ").Select(ulong.Parse).Where(role => !userRoleIds.Contains(role)).ToList(); - if (i.ReaddRemoved == 1) - { - if (toRemove.Any()) - { - foreach (var role in toRemove.Where(socketRole => - !user.Roles.Select(x => x.Id).Contains(socketRole))) - { - try - { - await user.AddRoleAsync(role); - } - catch - { - Log.Error( - $"Unable to add removed role {role} for {user} in {user.Guild} due to permission issues."); - } - } - } - } - } - else - { - continue; - } - } + var toRemove = string.IsNullOrWhiteSpace(config.ToRemove) + ? new List() + : config.ToRemove.Split(" ").Select(ulong.Parse).Where(role => userRoleIds.Contains(role)).ToList(); - if (beforeStatus is not null && beforeStatus.State.Contains(i.Status)) - { + var channel = user.Guild.GetTextChannel(config.StatusChannelId); + // If the StatusEmbed field is empty or channel is null, continue to the next statusRole + if (string.IsNullOrWhiteSpace(config.StatusEmbed) || channel == null) continue; - } - if (toRemove.Any()) + if (afterStatus.State.Contains(config.Status) && beforeStatus?.State != afterStatus.State) { + // On Status Add try { - await user.RemoveRolesAsync(toRemove); + await user.AddRolesAsync(toAdd); } catch { - Log.Error($"Unable to remove statusroles in {user.Guild} due to permission issues."); + Log.Error($"Unable to add status roles in {user.Guild} due to permission issues."); } } - - if (toAdd.Any()) + else if ((beforeStatus?.State.Contains(config.Status) ?? false) && + beforeStatus?.State != afterStatus.State) { + // On Status Remove try { - await user.AddRolesAsync(toAdd); + await user.RemoveRolesAsync(toRemove); } catch { - Log.Error($"Unable to add statusroles in {user.Guild} due to permission issues."); + Log.Error($"Unable to remove status roles in {user.Guild} due to permission issues."); } } - var channel = user.Guild.GetTextChannel(i.StatusChannelId); - - if (channel is null) - { - continue; - } - - if (string.IsNullOrWhiteSpace(i.StatusEmbed)) - { - continue; - } - var rep = new ReplacementBuilder().WithDefault(user, channel, user.Guild, client).Build(); - if (SmartEmbed.TryParse(rep.Replace(i.StatusEmbed), user.Guild.Id, out var embeds, out var plainText, + if (SmartEmbed.TryParse(rep.Replace(config.StatusEmbed), user.Guild.Id, out var embeds, + out var plainText, out var components)) { await channel.SendMessageAsync(plainText ?? null, embeds: embeds ?? Array.Empty(), @@ -176,15 +118,16 @@ await channel.SendMessageAsync(plainText ?? null, embeds: embeds ?? Array.Empty< } else { - await channel.SendMessageAsync(rep.Replace(i.StatusEmbed)); + await channel.SendMessageAsync(rep.Replace(config.StatusEmbed)); } } } catch (Exception e) { var status = args3.Activities?.FirstOrDefault() as CustomStatusGame; - Log.Error("Error in StatusRolesService. After Status: {Status} args: {Args2} args2: {Args3}\n{Exception}", - status.State, args2, args3, e); + Log.Error( + "Error in StatusRolesService: {Exception}, After Status: {Status}, args2: {Args2}, args3: {Args3}", + e, status?.State, args2, args3); } } diff --git a/src/Mewdeko/Modules/Suggestions/Services/SuggestButtonService.cs b/src/Mewdeko/Modules/Suggestions/Services/SuggestButtonService.cs index de4418792..d352410f5 100644 --- a/src/Mewdeko/Modules/Suggestions/Services/SuggestButtonService.cs +++ b/src/Mewdeko/Modules/Suggestions/Services/SuggestButtonService.cs @@ -153,10 +153,10 @@ await ctx.Interaction.SendEphemeralErrorAsync($"There is already a thread open. } [ComponentInteraction("suggestbutton")] - public async Task SendSuggestModal() - => await ctx.Interaction.RespondWithModalAsync("suggest.sendsuggestion", + public Task SendSuggestModal() + => ctx.Interaction.RespondWithModalAsync("suggest.sendsuggestion", null, x => x.UpdateTextInput("suggestion", async s => s.WithMaxLength(Math.Min(4000, await Service.GetMaxLength(ctx.Guild.Id))) - .WithMinLength(Math.Min(await Service.GetMinLength(ctx.Guild.Id), 4000)))).ConfigureAwait(false); + .WithMinLength(Math.Min(await Service.GetMinLength(ctx.Guild.Id), 4000)))); } \ No newline at end of file diff --git a/src/Mewdeko/Modules/Suggestions/SlashSuggestions.cs b/src/Mewdeko/Modules/Suggestions/SlashSuggestions.cs index fd8bb4af5..e19f78472 100644 --- a/src/Mewdeko/Modules/Suggestions/SlashSuggestions.cs +++ b/src/Mewdeko/Modules/Suggestions/SlashSuggestions.cs @@ -21,54 +21,62 @@ public async Task SetSuggestChannel(ITextChannel? channel = null) else { await Service.SetSuggestionChannelId(ctx.Guild, channel.Id).ConfigureAwait(false); - var chn2 = await ctx.Guild.GetTextChannelAsync(await Service.GetSuggestionChannel(ctx.Guild.Id)).ConfigureAwait(false); - await ctx.Interaction.SendConfirmAsync($"Your Suggestion channel has been set to {chn2.Mention}").ConfigureAwait(false); + var chn2 = await ctx.Guild.GetTextChannelAsync(await Service.GetSuggestionChannel(ctx.Guild.Id)) + .ConfigureAwait(false); + await ctx.Interaction.SendConfirmAsync($"Your Suggestion channel has been set to {chn2.Mention}") + .ConfigureAwait(false); } } [SlashCommand("suggest", "Sends a suggestion to the suggestion channel, if there is one set.", true), RequireContext(ContextType.Guild), CheckPermissions] - public async Task Suggest() => await ctx.Interaction.RespondWithModalAsync("suggest.sendsuggestion", - null, - x => x.UpdateTextInput("suggestion", async s => s.WithMaxLength(Math.Min(4000, await Service.GetMaxLength(ctx.Guild.Id))) - .WithMinLength(Math.Min(await Service.GetMinLength(ctx.Guild.Id), 4000)))) - .ConfigureAwait(false); - - [ComponentInteraction("accept:*", true), RequireContext(ContextType.Guild), CheckPermissions, SlashUserPerm(ChannelPermission.ManageMessages)] - public async Task Accept(string suggestId) - => await ctx.Interaction.RespondWithModalAsync($"suggeststate:accept.{suggestId}").ConfigureAwait(false); - - [ComponentInteraction("deny:*", true), RequireContext(ContextType.Guild), CheckPermissions, SlashUserPerm(ChannelPermission.ManageMessages)] - public async Task Deny(string suggestId) - => await ctx.Interaction.RespondWithModalAsync($"suggeststate:deny.{suggestId}").ConfigureAwait(false); - - [ComponentInteraction("consider:*", true), RequireContext(ContextType.Guild), CheckPermissions, SlashUserPerm(ChannelPermission.ManageMessages)] - public async Task Consider(string suggestId) - => await ctx.Interaction.RespondWithModalAsync($"suggeststate:consider.{suggestId}").ConfigureAwait(false); - - [ComponentInteraction("implement:*", true), RequireContext(ContextType.Guild), CheckPermissions, SlashUserPerm(ChannelPermission.ManageMessages)] - public async Task Implemented(string suggestId) - => await ctx.Interaction.RespondWithModalAsync($"suggeststate:implement.{suggestId}").ConfigureAwait(false); + public Task Suggest() => ctx.Interaction.RespondWithModalAsync("suggest.sendsuggestion", + null, + x => x.UpdateTextInput("suggestion", async s => s + .WithMaxLength(Math.Min(4000, await Service.GetMaxLength(ctx.Guild.Id))) + .WithMinLength(Math.Min(await Service.GetMinLength(ctx.Guild.Id), 4000)))); + + [ComponentInteraction("accept:*", true), RequireContext(ContextType.Guild), CheckPermissions, + SlashUserPerm(ChannelPermission.ManageMessages)] + public Task Accept(string suggestId) + => ctx.Interaction.RespondWithModalAsync($"suggeststate:accept.{suggestId}"); + + [ComponentInteraction("deny:*", true), RequireContext(ContextType.Guild), CheckPermissions, + SlashUserPerm(ChannelPermission.ManageMessages)] + public Task Deny(string suggestId) + => ctx.Interaction.RespondWithModalAsync($"suggeststate:deny.{suggestId}"); + + [ComponentInteraction("consider:*", true), RequireContext(ContextType.Guild), CheckPermissions, + SlashUserPerm(ChannelPermission.ManageMessages)] + public Task Consider(string suggestId) + => ctx.Interaction.RespondWithModalAsync($"suggeststate:consider.{suggestId}"); + + [ComponentInteraction("implement:*", true), RequireContext(ContextType.Guild), CheckPermissions, + SlashUserPerm(ChannelPermission.ManageMessages)] + public Task Implemented(string suggestId) + => ctx.Interaction.RespondWithModalAsync($"suggeststate:implement.{suggestId}"); [ModalInteraction("suggeststate:*.*", true), CheckPermissions, RequireContext(ContextType.Guild)] - public async Task HandleStateModal(string state, string suggestId, SuggestStateModal modal) + public Task HandleStateModal(string state, string suggestId, SuggestStateModal modal) { ulong.TryParse(suggestId, out var sugId); switch (state) { case "accept": - await Accept(sugId, modal.Reason.EscapeWeirdStuff()).ConfigureAwait(false); + return Accept(sugId, modal.Reason.EscapeWeirdStuff()); break; case "deny": - await Deny(sugId, modal.Reason.EscapeWeirdStuff()).ConfigureAwait(false); + return Deny(sugId, modal.Reason.EscapeWeirdStuff()); break; case "consider": - await Consider(sugId, modal.Reason.EscapeWeirdStuff()).ConfigureAwait(false); + return Consider(sugId, modal.Reason.EscapeWeirdStuff()); break; case "implement": - await Implemented(sugId, modal.Reason.EscapeWeirdStuff()).ConfigureAwait(false); + return Implemented(sugId, modal.Reason.EscapeWeirdStuff()); break; } + + return Task.CompletedTask; } [ModalInteraction("suggest.sendsuggestion", true), RequireContext(ContextType.Guild), CheckPermissions] @@ -84,14 +92,16 @@ public async Task HandleSuggestion(SuggestionModal modal) if (modal.Suggestion.Length > await Service.GetMaxLength(ctx.Guild.Id)) { await ctx.Interaction.SendEphemeralFollowupConfirmAsync( - $"Cannot send this suggestion as its over the max length (`{await Service.GetMaxLength(ctx.Guild.Id)}`) set in this server!").ConfigureAwait(false); + $"Cannot send this suggestion as its over the max length (`{await Service.GetMaxLength(ctx.Guild.Id)}`) set in this server!") + .ConfigureAwait(false); return; } if (modal.Suggestion.Length < await Service.GetMinLength(ctx.Guild.Id)) { await ctx.Interaction.SendEphemeralFollowupErrorAsync( - $"Cannot send this suggestion as its under the minimum length (`{await Service.GetMinLength(ctx.Guild.Id)}`) set in this server!").ConfigureAwait(false); + $"Cannot send this suggestion as its under the minimum length (`{await Service.GetMinLength(ctx.Guild.Id)}`) set in this server!") + .ConfigureAwait(false); return; } @@ -110,7 +120,8 @@ public async Task SuggestClear() return; } - if (await PromptUserConfirmAsync("Are you sure you want to clear all suggestions? ***This cannot be undone.***", ctx.User.Id).ConfigureAwait(false)) + if (await PromptUserConfirmAsync("Are you sure you want to clear all suggestions? ***This cannot be undone.***", + ctx.User.Id).ConfigureAwait(false)) { await Service.SuggestReset(ctx.Guild).ConfigureAwait(false); await ctx.Interaction.SendConfirmFollowupAsync("Suggestions cleared.").ConfigureAwait(false); @@ -119,25 +130,33 @@ public async Task SuggestClear() [SlashCommand("deny", "Denies a suggestion"), RequireContext(ContextType.Guild), SlashUserPerm(GuildPermission.ManageMessages), CheckPermissions] - public async Task Deny([Summary(description: "The number of the suggestion.")] [Autocomplete(typeof(SuggestionAutocompleter))] ulong suggestid, string? reason = null) => - await Service.SendDenyEmbed(ctx.Guild, ctx.Client as DiscordSocketClient, ctx.User, suggestid, - ctx.Channel as ITextChannel, reason.EscapeWeirdStuff(), ctx.Interaction).ConfigureAwait(false); + public Task Deny( + [Summary(description: "The number of the suggestion.")] [Autocomplete(typeof(SuggestionAutocompleter))] + ulong suggestid, string? reason = null) => + Service.SendDenyEmbed(ctx.Guild, ctx.Client as DiscordSocketClient, ctx.User, suggestid, + ctx.Channel as ITextChannel, reason.EscapeWeirdStuff(), ctx.Interaction); [SlashCommand("accept", "Accepts a suggestion"), RequireContext(ContextType.Guild), SlashUserPerm(GuildPermission.ManageMessages), CheckPermissions] - public async Task Accept([Summary(description: "The number of the suggestion.")] [Autocomplete(typeof(SuggestionAutocompleter))] ulong suggestid, string? reason = null) => - await Service.SendAcceptEmbed(ctx.Guild, ctx.Client as DiscordSocketClient, ctx.User, suggestid, - ctx.Channel as ITextChannel, reason.EscapeWeirdStuff(), ctx.Interaction).ConfigureAwait(false); + public Task Accept( + [Summary(description: "The number of the suggestion.")] [Autocomplete(typeof(SuggestionAutocompleter))] + ulong suggestid, string? reason = null) => + Service.SendAcceptEmbed(ctx.Guild, ctx.Client as DiscordSocketClient, ctx.User, suggestid, + ctx.Channel as ITextChannel, reason.EscapeWeirdStuff(), ctx.Interaction); [SlashCommand("implement", "Sets a suggestion as implemented"), RequireContext(ContextType.Guild), SlashUserPerm(GuildPermission.ManageMessages), CheckPermissions] - public async Task Implemented([Summary(description: "The number of the suggestion.")] [Autocomplete(typeof(SuggestionAutocompleter))] ulong suggestid, string? reason = null) => - await Service.SendImplementEmbed(ctx.Guild, ctx.Client as DiscordSocketClient, ctx.User, suggestid, - ctx.Channel as ITextChannel, reason.EscapeWeirdStuff(), ctx.Interaction).ConfigureAwait(false); + public Task Implemented( + [Summary(description: "The number of the suggestion.")] [Autocomplete(typeof(SuggestionAutocompleter))] + ulong suggestid, string? reason = null) => + Service.SendImplementEmbed(ctx.Guild, ctx.Client as DiscordSocketClient, ctx.User, suggestid, + ctx.Channel as ITextChannel, reason.EscapeWeirdStuff(), ctx.Interaction); [SlashCommand("consider", "Sets a suggestion as considered"), RequireContext(ContextType.Guild), SlashUserPerm(GuildPermission.ManageMessages), CheckPermissions] - public async Task Consider([Summary(description: "The number of the suggestion.")] [Autocomplete(typeof(SuggestionAutocompleter))] ulong suggestid, string? reason = null) => - await Service.SendConsiderEmbed(ctx.Guild, ctx.Client as DiscordSocketClient, ctx.User, suggestid, - ctx.Channel as ITextChannel, reason.EscapeWeirdStuff(), ctx.Interaction).ConfigureAwait(false); + public Task Consider( + [Summary(description: "The number of the suggestion.")] [Autocomplete(typeof(SuggestionAutocompleter))] + ulong suggestid, string? reason = null) => + Service.SendConsiderEmbed(ctx.Guild, ctx.Client as DiscordSocketClient, ctx.User, suggestid, + ctx.Channel as ITextChannel, reason.EscapeWeirdStuff(), ctx.Interaction); } \ No newline at end of file diff --git a/src/Mewdeko/Modules/Suggestions/Suggestions.cs b/src/Mewdeko/Modules/Suggestions/Suggestions.cs index e701ace28..70e7a92f9 100644 --- a/src/Mewdeko/Modules/Suggestions/Suggestions.cs +++ b/src/Mewdeko/Modules/Suggestions/Suggestions.cs @@ -19,8 +19,10 @@ public async Task SetSuggestChannel(ITextChannel? channel = null) else { await Service.SetSuggestionChannelId(ctx.Guild, channel.Id).ConfigureAwait(false); - var chn2 = await ctx.Guild.GetTextChannelAsync(await Service.GetSuggestionChannel(ctx.Guild.Id)).ConfigureAwait(false); - await ctx.Channel.SendConfirmAsync($"Your Suggestion channel has been set to {chn2.Mention}").ConfigureAwait(false); + var chn2 = await ctx.Guild.GetTextChannelAsync(await Service.GetSuggestionChannel(ctx.Guild.Id)) + .ConfigureAwait(false); + await ctx.Channel.SendConfirmAsync($"Your Suggestion channel has been set to {chn2.Mention}") + .ConfigureAwait(false); } } @@ -30,7 +32,8 @@ public async Task SuggestInfo(ulong num) var suggest = (await Service.Suggestions(ctx.Guild.Id, num)).FirstOrDefault(); if (suggest is null) { - await ctx.Channel.SendErrorAsync("That suggestion wasn't found! Please double check the number.").ConfigureAwait(false); + await ctx.Channel.SendErrorAsync("That suggestion wasn't found! Please double check the number.") + .ConfigureAwait(false); return; } @@ -41,7 +44,8 @@ public async Task SuggestInfo(ulong num) { foreach (var i in emotes.Split(",")) { - emoteCount.Add($"{i.ToIEmote()} `{await Service.GetCurrentCount(suggest.MessageId, ++count).ConfigureAwait(false)}`"); + emoteCount.Add( + $"{i.ToIEmote()} `{await Service.GetCurrentCount(suggest.MessageId, ++count).ConfigureAwait(false)}`"); } } else @@ -61,7 +65,8 @@ public async Task SuggestInfo(ulong num) $"{suggest.Suggestion.Truncate(256)} \n[Jump To Suggestion](https://discord.com/channels/{ctx.Guild.Id}/{Service.GetSuggestionChannel(ctx.Guild.Id)}/{suggest.MessageId})") .AddField("Suggested By", $"<@{suggest.UserId}> `{suggest.UserId}`") .AddField("Curerent State", (SuggestionsService.SuggestState)suggest.CurrentState) - .AddField("Last Changed By", suggest.StateChangeUser == 0 ? "Nobody" : $"<@{suggest.StateChangeUser}> `{suggest.StateChangeUser}`") + .AddField("Last Changed By", + suggest.StateChangeUser == 0 ? "Nobody" : $"<@{suggest.StateChangeUser}> `{suggest.StateChangeUser}`") .AddField("State Change Count", suggest.StateChangeCount) .AddField("Emote Count", string.Join("\n", emoteCount)); await ctx.Channel.SendMessageAsync(embed: eb.Build(), components: components.Build()).ConfigureAwait(false); @@ -77,7 +82,8 @@ public async Task SuggestClear() return; } - if (await PromptUserConfirmAsync("Are you sure you want to clear all suggestions? ***This cannot be undone.***", ctx.User.Id).ConfigureAwait(false)) + if (await PromptUserConfirmAsync("Are you sure you want to clear all suggestions? ***This cannot be undone.***", + ctx.User.Id).ConfigureAwait(false)) { await Service.SuggestReset(ctx.Guild).ConfigureAwait(false); await ctx.Channel.SendConfirmAsync("Suggestions cleared.").ConfigureAwait(false); @@ -100,7 +106,8 @@ public async Task Suggest([Remainder] string suggestion) if (suggestion.Length > await Service.GetMaxLength(ctx.Guild.Id)) { var msg = await ctx.Channel.SendErrorAsync( - $"Cannot send this suggestion as its over the max length (`{await Service.GetMaxLength(ctx.Guild.Id)}`) set in this server!").ConfigureAwait(false); + $"Cannot send this suggestion as its over the max length (`{await Service.GetMaxLength(ctx.Guild.Id)}`) set in this server!") + .ConfigureAwait(false); msg.DeleteAfter(5); return; } @@ -108,7 +115,8 @@ public async Task Suggest([Remainder] string suggestion) if (suggestion.Length < await Service.GetMinLength(ctx.Guild.Id)) { var message = await ctx.Channel.SendErrorAsync( - $"Cannot send this suggestion as its under the minimum length (`{await Service.GetMinLength(ctx.Guild.Id)}`) set in this server!").ConfigureAwait(false); + $"Cannot send this suggestion as its under the minimum length (`{await Service.GetMinLength(ctx.Guild.Id)}`) set in this server!") + .ConfigureAwait(false); message.DeleteAfter(5); return; } @@ -119,25 +127,25 @@ await Service.SendSuggestion(ctx.Guild, ctx.User as IGuildUser, ctx.Client as Di [Cmd, Aliases, RequireContext(ContextType.Guild), UserPerm(GuildPermission.ManageMessages)] - public async Task Deny(ulong sid, [Remainder] string? reason = null) => - await Service.SendDenyEmbed(ctx.Guild, ctx.Client as DiscordSocketClient, ctx.User, sid, - ctx.Channel as ITextChannel, reason.EscapeWeirdStuff()).ConfigureAwait(false); + public Task Deny(ulong sid, [Remainder] string? reason = null) => + Service.SendDenyEmbed(ctx.Guild, ctx.Client as DiscordSocketClient, ctx.User, sid, + ctx.Channel as ITextChannel, reason.EscapeWeirdStuff()); [Cmd, Aliases, RequireContext(ContextType.Guild), UserPerm(GuildPermission.ManageMessages)] - public async Task Accept(ulong sid, [Remainder] string? reason = null) => - await Service.SendAcceptEmbed(ctx.Guild, ctx.Client as DiscordSocketClient, ctx.User, sid, - ctx.Channel as ITextChannel, reason.EscapeWeirdStuff()).ConfigureAwait(false); + public Task Accept(ulong sid, [Remainder] string? reason = null) => + Service.SendAcceptEmbed(ctx.Guild, ctx.Client as DiscordSocketClient, ctx.User, sid, + ctx.Channel as ITextChannel, reason.EscapeWeirdStuff()); [Cmd, Aliases, RequireContext(ContextType.Guild), UserPerm(GuildPermission.ManageMessages)] - public async Task Implemented(ulong sid, [Remainder] string? reason = null) => - await Service.SendImplementEmbed(ctx.Guild, ctx.Client as DiscordSocketClient, ctx.User, sid, - ctx.Channel as ITextChannel, reason.EscapeWeirdStuff()).ConfigureAwait(false); + public Task Implemented(ulong sid, [Remainder] string? reason = null) => + Service.SendImplementEmbed(ctx.Guild, ctx.Client as DiscordSocketClient, ctx.User, sid, + ctx.Channel as ITextChannel, reason.EscapeWeirdStuff()); [Cmd, Aliases, RequireContext(ContextType.Guild), UserPerm(GuildPermission.ManageMessages)] - public async Task Consider(ulong sid, [Remainder] string? reason = null) => - await Service.SendConsiderEmbed(ctx.Guild, ctx.Client as DiscordSocketClient, ctx.User, sid, - ctx.Channel as ITextChannel, reason.EscapeWeirdStuff()).ConfigureAwait(false); + public Task Consider(ulong sid, [Remainder] string? reason = null) => + Service.SendConsiderEmbed(ctx.Guild, ctx.Client as DiscordSocketClient, ctx.User, sid, + ctx.Channel as ITextChannel, reason.EscapeWeirdStuff()); } \ No newline at end of file diff --git a/src/Mewdeko/Modules/UserProfile/SlashUserProfile.cs b/src/Mewdeko/Modules/UserProfile/SlashUserProfile.cs index 45f60efcc..55f97a6eb 100644 --- a/src/Mewdeko/Modules/UserProfile/SlashUserProfile.cs +++ b/src/Mewdeko/Modules/UserProfile/SlashUserProfile.cs @@ -158,8 +158,8 @@ public async Task SetPrivacy(DiscordUser.ProfilePrivacyEnum privacyEnum) } [ComponentInteraction("pronouns_overwrite", true)] - public async Task OverwritePronouns() => - await RespondWithModalAsync("pronouns_overwrite_modal").ConfigureAwait(false); + public Task OverwritePronouns() => + RespondWithModalAsync("pronouns_overwrite_modal"); [ComponentInteraction("pronouns_overwrite_clear", true)] public async Task ClearPronounsOverwrite() @@ -228,29 +228,27 @@ public async Task ReportPronouns(string sId) } [ComponentInteraction("pronouns_clear:*,*", true), SlashOwnerOnly] - public async Task ClearPronouns(string sId, string sDisable) => - await Context.Interaction.RespondWithModalAsync($"pronouns_fc_action:{sId},{sDisable},false", - null, x => x.WithTitle("Clear Pronouns")) - .ConfigureAwait(false); + public Task ClearPronouns(string sId, string sDisable) => + Context.Interaction.RespondWithModalAsync($"pronouns_fc_action:{sId},{sDisable},false", + null, x => x.WithTitle("Clear Pronouns")); [ComponentInteraction("pronouns_blacklist:*", true), SlashOwnerOnly] - public async Task BlacklistPronouns(string sId) => - await ctx.Interaction.RespondWithModalAsync($"pronouns_fc_action:{sId},true,true", null, - x => x.WithTitle("Blacklist User and Clear Pronouns")) - .ConfigureAwait(false); + public Task BlacklistPronouns(string sId) => + ctx.Interaction.RespondWithModalAsync($"pronouns_fc_action:{sId},true,true", null, + x => x.WithTitle("Blacklist User and Clear Pronouns")); [ComponentInteraction("pronouns_blacklist_guild:*", true), SlashOwnerOnly] - public async Task BlacklistGuildPronouns(string sId) => - await ctx.Interaction - .RespondWithModalAsync($"pronouns_fcb_g:{sId}", null, x => x.WithTitle("Blacklist Guild")) - .ConfigureAwait(false); + public Task BlacklistGuildPronouns(string sId) => + ctx.Interaction + .RespondWithModalAsync($"pronouns_fcb_g:{sId}", null, + x => x.WithTitle("Blacklist Guild")); [ModalInteraction("pronouns_fcb_g:*", true), SlashOwnerOnly] - public async Task PronounsGuildBlacklist(string sId, PronounsFcbModal modal) + public Task PronounsGuildBlacklist(string sId, PronounsFcbModal modal) { var id = ulong.Parse(sId); bss.Blacklist(BlacklistType.Server, id, modal.FcbReason); - await RespondAsync("blacklisted the server").ConfigureAwait(false); + return RespondAsync("blacklisted the server"); } [ModalInteraction("pronouns_fc_action:*,*,*", true), SlashOwnerOnly] @@ -326,10 +324,9 @@ await RespondAsync(GetText("pronouns_internal_self", user.Pronouns), components: } [ComponentInteraction("pronouns_reportdm:*", true), SlashOwnerOnly] - public async Task DmUser(string uIdStr) => - await ctx.Interaction - .RespondWithModalAsync($"pronouns_reportdm_modal:{uIdStr}", null, x => x.WithTitle("dm user")) - .ConfigureAwait(false); + public Task DmUser(string uIdStr) => + ctx.Interaction + .RespondWithModalAsync($"pronouns_reportdm_modal:{uIdStr}", null, x => x.WithTitle("dm user")); [ModalInteraction("pronouns_reportdm_modal:*", true), SlashOwnerOnly] public async Task DmUserModal(string uIdStr, DmUserModal modal) diff --git a/src/Mewdeko/Modules/Utility/Common/RepeatRunner.cs b/src/Mewdeko/Modules/Utility/Common/RepeatRunner.cs index 50e0aa0af..0f18d4a2d 100644 --- a/src/Mewdeko/Modules/Utility/Common/RepeatRunner.cs +++ b/src/Mewdeko/Modules/Utility/Common/RepeatRunner.cs @@ -88,7 +88,8 @@ private void Run() else { // if repeater is not running daily, it's initial time is the time it was Added at, plus the interval - if (Repeater.DateAdded != null) CalculateInitialInterval(Repeater.DateAdded.Value + TimeSpan.Parse(Repeater.Interval)); + if (Repeater.DateAdded != null) + CalculateInitialInterval(Repeater.DateAdded.Value + TimeSpan.Parse(Repeater.Interval)); } // wait at least a minute for the bot to have all data needed in the cache @@ -148,12 +149,12 @@ private void CalculateInitialInterval(DateTime initialDateTime) public async Task Trigger() { - async Task ChannelMissingError() + Task ChannelMissingError() { Log.Warning("Channel not found or insufficient permissions. Repeater stopped. ChannelId : {0}", Channel?.Id); Stop(); - await mrs.RemoveRepeater(Repeater).ConfigureAwait(false); + return mrs.RemoveRepeater(Repeater); } // next execution is interval amount of time after now @@ -199,9 +200,11 @@ async Task ChannelMissingError() .Build(); IMessage newMsg; - if (SmartEmbed.TryParse(rep.Replace(toSend), Channel.GuildId, out var embed, out var plainText, out var components)) + if (SmartEmbed.TryParse(rep.Replace(toSend), Channel.GuildId, out var embed, out var plainText, + out var components)) { - newMsg = await Channel.SendMessageAsync(plainText ?? "", embeds: embed, components: components?.Build()).ConfigureAwait(false); + newMsg = await Channel.SendMessageAsync(plainText ?? "", embeds: embed, components: components?.Build()) + .ConfigureAwait(false); } else { diff --git a/src/Mewdeko/Modules/Utility/Services/StreamRoleService.cs b/src/Mewdeko/Modules/Utility/Services/StreamRoleService.cs index 7d3f035b4..875ac2693 100644 --- a/src/Mewdeko/Modules/Utility/Services/StreamRoleService.cs +++ b/src/Mewdeko/Modules/Utility/Services/StreamRoleService.cs @@ -47,11 +47,12 @@ public Task Unload() private Task Client_GuildMemberUpdated(Cacheable cacheable, SocketGuildUser after) { - _ = Task.Run(async () => + _ = Task.Run(() => { //if user wasn't streaming or didn't have a game status at all if (guildSettings.TryGetValue(after.Guild.Id, out var setting)) - await RescanUser(after, setting).ConfigureAwait(false); + return RescanUser(after, setting); + return Task.CompletedTask; }); return Task.CompletedTask; diff --git a/src/Mewdeko/Modules/Utility/Services/UtilityService.cs b/src/Mewdeko/Modules/Utility/Services/UtilityService.cs index 721bff33d..7656e4fb1 100644 --- a/src/Mewdeko/Modules/Utility/Services/UtilityService.cs +++ b/src/Mewdeko/Modules/Utility/Services/UtilityService.cs @@ -30,8 +30,8 @@ public UtilityService( this.client = client; } - public async Task> GetSnipes(ulong guildId) => - await cache.GetSnipesForGuild(guildId).ConfigureAwait(false); + public Task> GetSnipes(ulong guildId) => + cache.GetSnipesForGuild(guildId); public async Task GetPLinks(ulong id) => (await guildSettings.GetGuildConfig(id)).PreviewLinks; @@ -220,10 +220,10 @@ public async Task MsgReciev2(IMessage msg) } } - public static async Task UrlChecker(string url) + public static Task UrlChecker(string url) { var vcheck = new VirusTotal("e49046afa41fdf4e8ca72ea58a5542d0b8fbf72189d54726eed300d2afe5d9a9"); - return await vcheck.GetUrlReportAsync(url, true).ConfigureAwait(false); + return vcheck.GetUrlReportAsync(url, true); } public async Task MsgReciev(IMessage msg) diff --git a/src/Mewdeko/Modules/Utility/SlashSnipes.cs b/src/Mewdeko/Modules/Utility/SlashSnipes.cs index f95aa008b..41ed75491 100644 --- a/src/Mewdeko/Modules/Utility/SlashSnipes.cs +++ b/src/Mewdeko/Modules/Utility/SlashSnipes.cs @@ -12,9 +12,11 @@ namespace Mewdeko.Modules.Utility; public partial class Utility { [Group("snipe", "Snipe edited or delete messages!")] - public class SlashSnipes(DiscordSocketClient client, InteractiveService interactiveService, - GuildSettingsService guildSettings, - BotConfigService config) + public class SlashSnipes( + DiscordSocketClient client, + InteractiveService interactiveService, + GuildSettingsService guildSettings, + BotConfigService config) : MewdekoSlashModuleBase { [SlashCommand("deleted", "Snipes deleted messages for the current or mentioned channel"), @@ -198,16 +200,16 @@ async Task PageFactory(int page) [SlashCommand("deletedlist", "Lists the last 5 delete snipes unless specified otherwise."), RequireContext(ContextType.Guild), CheckPermissions] - public async Task SnipeList(int amount = 5, ITextChannel channel = null, IUser user = null) + public Task SnipeList(int amount = 5, ITextChannel channel = null, IUser user = null) { - await SnipeListBase(false, amount, channel, user); + return SnipeListBase(false, amount, channel, user); } [SlashCommand("editedlist", "Lists the last 5 edit snipes unless specified otherwise."), RequireContext(ContextType.Guild), CheckPermissions] - public async Task EditSnipeList(int amount = 5, ITextChannel channel = null, IUser user = null) + public Task EditSnipeList(int amount = 5, ITextChannel channel = null, IUser user = null) { - await SnipeListBase(true, amount, channel, user); + return SnipeListBase(true, amount, channel, user); } diff --git a/src/Mewdeko/Modules/Utility/SlashUtility.cs b/src/Mewdeko/Modules/Utility/SlashUtility.cs index 47c302ff0..0f9a5a861 100644 --- a/src/Mewdeko/Modules/Utility/SlashUtility.cs +++ b/src/Mewdeko/Modules/Utility/SlashUtility.cs @@ -86,7 +86,8 @@ await componentInteraction.UpdateAsync(x => var avatarUrlGuild = user.GuildAvatarId.StartsWith("a_", StringComparison.InvariantCulture) ? $"{DiscordConfig.CDNUrl}guilds/{ctx.Guild.Id}/users/{user.Id}/avatars/{user.GuildAvatarId}.gif?size=2048" : $"{DiscordConfig.CDNUrl}guilds/{ctx.Guild.Id}/users/{user.Id}/avatars/{user.GuildAvatarId}.png?size=2048"; - var componentbuilderGuild = new ComponentBuilder().WithButton("Real Avatar", $"avatartype:real,{userId}"); + var componentbuilderGuild = + new ComponentBuilder().WithButton("Real Avatar", $"avatartype:real,{userId}"); var ebGuild = new EmbedBuilder() .WithOkColor() .AddField(efb => efb.WithName("Username").WithValue(user.ToString()).WithIsInline(true)) @@ -127,7 +128,8 @@ await componentInteraction.UpdateAsync(x => break; case "guild": var avatarUrlGuild = guildUser.GetBannerUrl(size: 2048); - var componentbuilderGuild = new ComponentBuilder().WithButton("Real Banner", $"bannertype:real,{userId}"); + var componentbuilderGuild = + new ComponentBuilder().WithButton("Real Banner", $"bannertype:real,{userId}"); var ebGuild = new EmbedBuilder() .WithOkColor() .AddField(efb => efb.WithName("Username").WithValue(user.ToString()).WithIsInline(true)) @@ -144,7 +146,8 @@ await componentInteraction.UpdateAsync(x => } - [SlashCommand("getjson", "Gets the json from a message to use with our embed builder!"), RequireContext(ContextType.Guild), SlashUserPerm(GuildPermission.ManageMessages)] + [SlashCommand("getjson", "Gets the json from a message to use with our embed builder!"), + RequireContext(ContextType.Guild), SlashUserPerm(GuildPermission.ManageMessages)] public async Task GetJson(ulong messageId, ITextChannel channel = null) { channel ??= ctx.Channel as ITextChannel; @@ -165,11 +168,13 @@ public async Task GetJson(ulong messageId, ITextChannel channel = null) await writer.DisposeAsync(); } - [SlashCommand("say", "Send a message to a channel or the current channel"), CheckPermissions, SlashUserPerm(ChannelPermission.ManageMessages)] - public async Task Say([Summary("SendTo", "The channel to send to. Defaults to the current channel.")] ITextChannel channel = null) + [SlashCommand("say", "Send a message to a channel or the current channel"), CheckPermissions, + SlashUserPerm(ChannelPermission.ManageMessages)] + public Task Say( + [Summary("SendTo", "The channel to send to. Defaults to the current channel.")] ITextChannel channel = null) { channel ??= ctx.Channel as ITextChannel; - await RespondWithModalAsync($"saymodal:{channel.Id}"); + return RespondWithModalAsync($"saymodal:{channel.Id}"); } [ModalInteraction("saymodal:*", ignoreGroupNames: true)] @@ -177,12 +182,15 @@ public async Task SayModal(ulong channelId, SayModal modal) { var channel = await ctx.Guild.GetTextChannelAsync(channelId); var canMention = ((IGuildUser)ctx.User).GuildPermissions.MentionEveryone; - var rep = new ReplacementBuilder().WithDefault(ctx.User, channel, (SocketGuild)ctx.Guild, (DiscordSocketClient)ctx.Client).Build(); + var rep = new ReplacementBuilder() + .WithDefault(ctx.User, channel, (SocketGuild)ctx.Guild, (DiscordSocketClient)ctx.Client).Build(); - if (SmartEmbed.TryParse(rep.Replace(modal.Message), ctx.Guild?.Id, out var embedData, out var plainText, out var components)) + if (SmartEmbed.TryParse(rep.Replace(modal.Message), ctx.Guild?.Id, out var embedData, out var plainText, + out var components)) { await channel.SendMessageAsync(plainText, embeds: embedData, components: components?.Build(), - allowedMentions: !canMention ? new AllowedMentions(AllowedMentionTypes.Users) : AllowedMentions.All).ConfigureAwait(false); + allowedMentions: !canMention ? new AllowedMentions(AllowedMentionTypes.Users) : AllowedMentions.All) + .ConfigureAwait(false); await ctx.Interaction.SendEphemeralConfirmAsync($"Message sent to {channel.Mention}."); } else @@ -194,11 +202,13 @@ await channel.SendMessageAsync(plainText, embeds: embedData, components: compone await ctx.Interaction.SendEphemeralConfirmAsync($"Message sent to {channel.Mention}."); } else - await ctx.Interaction.SendEphemeralErrorAsync("The message was empty after variable replacements. Please double check your input."); + await ctx.Interaction.SendEphemeralErrorAsync( + "The message was empty after variable replacements. Please double check your input."); } } - [SlashCommand("stats", "Shows the bots current stats"), CheckPermissions, SlashUserPerm(GuildPermission.SendMessages)] + [SlashCommand("stats", "Shows the bots current stats"), CheckPermissions, + SlashUserPerm(GuildPermission.SendMessages)] public async Task Stats() { await using var uow = db.GetDbContext(); @@ -207,7 +217,8 @@ public async Task Stats() var user = await client.Rest.GetUserAsync(280835732728184843).ConfigureAwait(false); await ctx.Interaction.RespondAsync(embed: new EmbedBuilder().WithOkColor() - .WithAuthor($"{client.CurrentUser.Username} v{StatsService.BotVersion}", client.CurrentUser.GetAvatarUrl(), config.Data.SupportServer) + .WithAuthor($"{client.CurrentUser.Username} v{StatsService.BotVersion}", + client.CurrentUser.GetAvatarUrl(), config.Data.SupportServer) .AddField(GetText("author"), $"{user.Mention} | {user.Username}#{user.Discriminator}") .AddField(GetText("commands_ran"), $"{commandStats}/5s") .AddField("Library", stats.Library) @@ -222,16 +233,20 @@ await ctx.Interaction.RespondAsync(embed: [SlashCommand("roleinfo", "Shows info for a role")] public async Task RInfo(IRole role) { - var eb = new EmbedBuilder().WithTitle(role.Name).AddField("Users in role", (await ctx.Guild.GetUsersAsync().ConfigureAwait(false)).Count(x => x.RoleIds.Contains(role.Id))) - .AddField("Is Mentionable", role.IsMentionable).AddField("Is Hoisted", role.IsHoisted).AddField("Color", role.Color.RawValue) + var eb = new EmbedBuilder().WithTitle(role.Name).AddField("Users in role", + (await ctx.Guild.GetUsersAsync().ConfigureAwait(false)).Count(x => x.RoleIds.Contains(role.Id))) + .AddField("Is Mentionable", role.IsMentionable).AddField("Is Hoisted", role.IsHoisted) + .AddField("Color", role.Color.RawValue) .AddField("Is Managed", role.IsManaged).AddField("Permissions", string.Join(",", role.Permissions)) - .AddField("Creation Date", TimestampTag.FromDateTimeOffset(role.CreatedAt)).AddField("Position", role.Position).AddField("ID", role.Id) + .AddField("Creation Date", TimestampTag.FromDateTimeOffset(role.CreatedAt)) + .AddField("Position", role.Position).AddField("ID", role.Id) .WithThumbnailUrl(role.GetIconUrl()).WithColor(role.Color); await ctx.Interaction.RespondAsync(embed: eb.Build()).ConfigureAwait(false); } - [SlashCommand("voiceinfo", "Shows info for a voice channel"), CheckPermissions, SlashUserPerm(GuildPermission.SendMessages)] + [SlashCommand("voiceinfo", "Shows info for a voice channel"), CheckPermissions, + SlashUserPerm(GuildPermission.SendMessages)] public async Task VInfo(IVoiceChannel channel = null) { var voiceChannel = ((IGuildUser)ctx.User).VoiceChannel; @@ -239,7 +254,10 @@ public async Task VInfo(IVoiceChannel channel = null) switch (voiceChannel) { case null when channel == null: - await ctx.Interaction.SendEphemeralErrorAsync("You arent in a voice channel, and you haven't mentioned one either to use this command!").ConfigureAwait(false); + await ctx.Interaction + .SendEphemeralErrorAsync( + "You arent in a voice channel, and you haven't mentioned one either to use this command!") + .ConfigureAwait(false); return; // ReSharper disable once ConditionIsAlwaysTrueOrFalse case null when channel is not null: @@ -279,8 +297,10 @@ public async Task VInfo(IVoiceChannel channel = null) } } - [SlashCommand("fetch", "Gets a user, even if they aren't in the server."), CheckPermissions, SlashUserPerm(GuildPermission.SendMessages)] - public async Task Fetch([Summary("userId", "The user's ID. Looks like this: 280835732728184843")] string userIdstring) + [SlashCommand("fetch", "Gets a user, even if they aren't in the server."), CheckPermissions, + SlashUserPerm(GuildPermission.SendMessages)] + public async Task Fetch( + [Summary("userId", "The user's ID. Looks like this: 280835732728184843")] string userIdstring) { // Because discord is ass and uses int32 instead of int64 if (!ulong.TryParse(userIdstring, out var userId)) @@ -292,17 +312,20 @@ public async Task Fetch([Summary("userId", "The user's ID. Looks like this: 2808 var usr = await client.Rest.GetUserAsync(userId).ConfigureAwait(false); if (usr is null) { - await ctx.Interaction.SendErrorAsync("That user could not be found. Please ensure that was the correct ID."); + await ctx.Interaction.SendErrorAsync( + "That user could not be found. Please ensure that was the correct ID."); } else { - var embed = new EmbedBuilder().WithTitle("info for fetched user").AddField("Username", usr).AddField("Created At", TimestampTag.FromDateTimeOffset(usr.CreatedAt)) + var embed = new EmbedBuilder().WithTitle("info for fetched user").AddField("Username", usr) + .AddField("Created At", TimestampTag.FromDateTimeOffset(usr.CreatedAt)) .AddField("Public Flags", usr.PublicFlags).WithImageUrl(usr.RealAvatarUrl().ToString()).WithOkColor(); await ctx.Interaction.RespondAsync(embed: embed.Build()).ConfigureAwait(false); } } - [SlashCommand("serverinfo", "Shows info for this server."), CheckPermissions, SlashUserPerm(GuildPermission.SendMessages)] + [SlashCommand("serverinfo", "Shows info for this server."), CheckPermissions, + SlashUserPerm(GuildPermission.SendMessages)] public async Task ServerInfo() { await DeferAsync(); @@ -313,7 +336,8 @@ public async Task ServerInfo() var voicechn = guild.VoiceChannels.Count; var component = new ComponentBuilder().WithButton("More Info", "moreinfo"); - var embed = new EmbedBuilder().WithAuthor(eab => eab.WithName(GetText("server_info"))).WithTitle(guild.Name).AddField("Id", guild.Id.ToString()) + var embed = new EmbedBuilder().WithAuthor(eab => eab.WithName(GetText("server_info"))).WithTitle(guild.Name) + .AddField("Id", guild.Id.ToString()) .AddField("Owner", ownername.Mention).AddField("Total Users", guild.Users.Count.ToString()) .AddField("Created On", TimestampTag.FromDateTimeOffset(guild.CreatedAt)).WithColor(Mewdeko.OkColor); if (guild.SplashUrl != null) @@ -323,17 +347,20 @@ public async Task ServerInfo() if (guild.Emotes.Count > 0) { embed.AddField(fb => - fb.WithName($"{GetText("custom_emojis")}({guild.Emotes.Count})").WithValue(string.Join(" ", guild.Emotes.Shuffle().Take(30).Select(e => $"{e}")).TrimTo(1024))); + fb.WithName($"{GetText("custom_emojis")}({guild.Emotes.Count})") + .WithValue(string.Join(" ", guild.Emotes.Shuffle().Take(30).Select(e => $"{e}")).TrimTo(1024))); } - var msg = await ctx.Interaction.FollowupAsync(embed: embed.Build(), components: component.Build()).ConfigureAwait(false); + var msg = await ctx.Interaction.FollowupAsync(embed: embed.Build(), components: component.Build()) + .ConfigureAwait(false); var input = await GetButtonInputAsync(ctx.Channel.Id, msg.Id, ctx.User.Id).ConfigureAwait(false); if (input == "moreinfo") { var vals = Enum.GetValues(typeof(GuildFeature)).Cast(); var setFeatures = vals.Where(x => guild.Features.Value.HasFlag(x)); embed.AddField("Bots", (await ctx.Guild.GetUsersAsync().ConfigureAwait(false)).Count(x => x.IsBot)) - .AddField("Users", (await ctx.Guild.GetUsersAsync().ConfigureAwait(false)).Count(x => !x.IsBot)).AddField("Text Channels", textchn.ToString()) + .AddField("Users", (await ctx.Guild.GetUsersAsync().ConfigureAwait(false)).Count(x => !x.IsBot)) + .AddField("Text Channels", textchn.ToString()) .AddField("Voice Channels", voicechn.ToString()).AddField("Roles", (guild.Roles.Count - 1).ToString()) .AddField("Server Features", Format.Code(string.Join("\n", setFeatures))); await msg.ModifyAsync(x => @@ -344,12 +371,15 @@ await msg.ModifyAsync(x => } } - [SlashCommand("channelinfo", "Shows info for the current or mentioned channel"), CheckPermissions, SlashUserPerm(GuildPermission.SendMessages)] + [SlashCommand("channelinfo", "Shows info for the current or mentioned channel"), CheckPermissions, + SlashUserPerm(GuildPermission.SendMessages)] public async Task ChannelInfo(ITextChannel channel = null) { var ch = channel ?? (ITextChannel)ctx.Channel; - var embed = new EmbedBuilder().WithTitle(ch.Name).AddField(GetText("id"), ch.Id.ToString()).AddField(GetText("created_at"), TimestampTag.FromDateTimeOffset(ch.CreatedAt)) - .AddField(GetText("users"), (await ch.GetUsersAsync().FlattenAsync().ConfigureAwait(false)).Count()).AddField("NSFW", ch.IsNsfw) + var embed = new EmbedBuilder().WithTitle(ch.Name).AddField(GetText("id"), ch.Id.ToString()) + .AddField(GetText("created_at"), TimestampTag.FromDateTimeOffset(ch.CreatedAt)) + .AddField(GetText("users"), (await ch.GetUsersAsync().FlattenAsync().ConfigureAwait(false)).Count()) + .AddField("NSFW", ch.IsNsfw) .AddField("Slowmode Interval", TimeSpan.FromSeconds(ch.SlowModeInterval).Humanize()) .AddField("Default Thread Archive Duration", ch.DefaultArchiveDuration).WithColor(Mewdeko.OkColor); if (!string.IsNullOrWhiteSpace(ch.Topic)) @@ -357,7 +387,8 @@ public async Task ChannelInfo(ITextChannel channel = null) await ctx.Interaction.RespondAsync(embed: embed.Build()).ConfigureAwait(false); } - [SlashCommand("userinfo", "Shows info for a mentioned or current user"), CheckPermissions, SlashUserPerm(GuildPermission.SendMessages)] + [SlashCommand("userinfo", "Shows info for a mentioned or current user"), CheckPermissions, + SlashUserPerm(GuildPermission.SendMessages)] [UserCommand("User Info")] public async Task UserInfo(IUser usr = null) { @@ -370,17 +401,21 @@ public async Task UserInfo(IUser usr = null) var userbanner = (await client.Rest.GetUserAsync(user.Id).ConfigureAwait(false)).GetBannerUrl(size: 2048); var serverUserType = user.GuildPermissions.Administrator ? "Administrator" : "Regular User"; var restUser = await client.Rest.GetUserAsync(user.Id); - var embed = new EmbedBuilder().AddField("Username", user.ToString()).WithColor(restUser.AccentColor ?? Mewdeko.OkColor); + var embed = new EmbedBuilder().AddField("Username", user.ToString()) + .WithColor(restUser.AccentColor ?? Mewdeko.OkColor); if (!string.IsNullOrWhiteSpace(user.Nickname)) embed.AddField("Nickname", user.Nickname); - embed.AddField("User Id", user.Id).AddField("User Type", serverUserType).AddField("Joined Server", TimestampTag.FromDateTimeOffset(user.JoinedAt.GetValueOrDefault())) - .AddField("Joined Discord", TimestampTag.FromDateTimeOffset(user.CreatedAt)).AddField("Role Count", user.GetRoles().Count(r => r.Id != r.Guild.EveryoneRole.Id)); + embed.AddField("User Id", user.Id).AddField("User Type", serverUserType).AddField("Joined Server", + TimestampTag.FromDateTimeOffset(user.JoinedAt.GetValueOrDefault())) + .AddField("Joined Discord", TimestampTag.FromDateTimeOffset(user.CreatedAt)).AddField("Role Count", + user.GetRoles().Count(r => r.Id != r.Guild.EveryoneRole.Id)); if (user.Activities.Count > 0) { - embed.AddField("Activities", string.Join("\n", user.Activities.Select(x => string.Format($"{x.Name}: {x.Details ?? ""}")))); + embed.AddField("Activities", + string.Join("\n", user.Activities.Select(x => string.Format($"{x.Name}: {x.Details ?? ""}")))); } var av = user.RealAvatarUrl(); @@ -397,18 +432,21 @@ public async Task UserInfo(IUser usr = null) } } - var msg = await ctx.Interaction.FollowupAsync(embed: embed.Build(), components: component.Build()).ConfigureAwait(false); + var msg = await ctx.Interaction.FollowupAsync(embed: embed.Build(), components: component.Build()) + .ConfigureAwait(false); var input = await GetButtonInputAsync(ctx.Channel.Id, msg.Id, ctx.User.Id).ConfigureAwait(false); if (input == "moreinfo") { if (user.GetRoles().Any(x => x.Id != ctx.Guild.EveryoneRole.Id)) { - embed.AddField("Roles", string.Join("", user.GetRoles().OrderBy(x => x.Position).Select(x => x.Mention))); + embed.AddField("Roles", + string.Join("", user.GetRoles().OrderBy(x => x.Position).Select(x => x.Mention))); } embed.AddField("Deafened", user.IsDeafened); embed.AddField("Is VC Muted", user.IsMuted); - embed.AddField("Is Server Muted", user.GetRoles().Contains(await muteService.GetMuteRole(ctx.Guild).ConfigureAwait(false))); + embed.AddField("Is Server Muted", + user.GetRoles().Contains(await muteService.GetMuteRole(ctx.Guild).ConfigureAwait(false))); await ctx.Interaction.ModifyOriginalResponseAsync(x => { x.Embed = embed.Build(); @@ -418,14 +456,15 @@ await ctx.Interaction.ModifyOriginalResponseAsync(x => } [MessageCommand("User Info"), CheckPermissions, SlashUserPerm(ChannelPermission.SendMessages)] - public async Task UserInfo(IMessage message) => await UserInfo(message.Author); + public Task UserInfo(IMessage message) => UserInfo(message.Author); [SlashCommand("userid", "Grabs the ID of a user."), CheckPermissions, SlashUserPerm(GuildPermission.SendMessages)] [UserCommand("User ID")] - public async Task UserId(IUser user = null) => await ctx.Interaction.RespondAsync(user?.Id.ToString() ?? ctx.User.Id.ToString(), ephemeral: true); + public Task UserId(IUser user = null) => + ctx.Interaction.RespondAsync(user?.Id.ToString() ?? ctx.User.Id.ToString(), ephemeral: true); [MessageCommand("User ID"), CheckPermissions, SlashUserPerm(GuildPermission.SendMessages)] - public async Task UserId(IMessage message) => await UserId(message.Author); + public Task UserId(IMessage message) => UserId(message.Author); [SlashCommand("avatar", "Shows a user's avatar"), CheckPermissions, SlashUserPerm(GuildPermission.SendMessages)] [UserCommand("Avatar")] @@ -454,15 +493,17 @@ public async Task Avatar(IUser usr = null) : $"{DiscordConfig.CDNUrl}guilds/{ctx.Guild.Id}/users/{usr.Id}/avatars/{av.GuildAvatarId}.png?size=2048"; await ctx.Interaction.FollowupAsync(embed: new EmbedBuilder() - .WithOkColor() - .AddField(efb => efb.WithName("Username").WithValue(usr.ToString()).WithIsInline(true)) - .AddField(efb => - efb.WithName($"{(av.GuildAvatarId is null ? "" : "Guild")} Avatar Url").WithValue($"[Link]({avatarUrl})").WithIsInline(true)) - .WithImageUrl(avatarUrl).Build(), components: av.GuildAvatarId is null ? null : components.Build()).ConfigureAwait(false); + .WithOkColor() + .AddField(efb => efb.WithName("Username").WithValue(usr.ToString()).WithIsInline(true)) + .AddField(efb => + efb.WithName($"{(av.GuildAvatarId is null ? "" : "Guild")} Avatar Url") + .WithValue($"[Link]({avatarUrl})").WithIsInline(true)) + .WithImageUrl(avatarUrl).Build(), components: av.GuildAvatarId is null ? null : components.Build()) + .ConfigureAwait(false); } [SlashCommand("timestamp", "Converts your local time to a universal timestamp")] - public async Task GenerateTimestamp + public Task GenerateTimestamp ( [Autocomplete(typeof(TimeZoneAutocompleter)), Summary("timezone", "your timezone")] string tz, @@ -475,7 +516,7 @@ public async Task GenerateTimestamp var timezone = TimeZoneInfo.FindSystemTimeZoneById(tz); var utc = TimeZoneInfo.ConvertTimeToUtc(time, timezone); var tag = TimestampTag.FromDateTimeOffset(utc, format); - await ctx.Interaction.SendEphemeralConfirmAsync($"{tag} (`{tag}`)"); + return ctx.Interaction.SendEphemeralConfirmAsync($"{tag} (`{tag}`)"); } [ComponentInteraction("moresinfo", true)] @@ -517,7 +558,8 @@ public async Task MoreUInfo(ulong userId) embed.AddField("Deafened", user.IsDeafened); embed.AddField("Is VC Muted", user.IsMuted); - embed.AddField("Is Server Muted", user.GetRoles().Contains(await muteService.GetMuteRole(ctx.Guild).ConfigureAwait(false))); + embed.AddField("Is Server Muted", + user.GetRoles().Contains(await muteService.GetMuteRole(ctx.Guild).ConfigureAwait(false))); await componentInteraction.Message.ModifyAsync(x => { x.Embed = embed.Build(); diff --git a/src/Mewdeko/Modules/Utility/Utility.cs b/src/Mewdeko/Modules/Utility/Utility.cs index 099d21c19..c32f029b5 100644 --- a/src/Mewdeko/Modules/Utility/Utility.cs +++ b/src/Mewdeko/Modules/Utility/Utility.cs @@ -19,12 +19,17 @@ namespace Mewdeko.Modules.Utility; -public partial class Utility(DiscordSocketClient client, - IStatsService stats, IBotCredentials creds, DownloadTracker tracker, InteractiveService serv, - ICoordinator coordinator, - GuildSettingsService guildSettings, - HttpClient httpClient, - BotConfigService config, DbService db) +public partial class Utility( + DiscordSocketClient client, + IStatsService stats, + IBotCredentials creds, + DownloadTracker tracker, + InteractiveService serv, + ICoordinator coordinator, + GuildSettingsService guildSettings, + HttpClient httpClient, + BotConfigService config, + DbService db) : MewdekoModuleBase { private static readonly SemaphoreSlim Sem = new(1, 1); @@ -107,8 +112,8 @@ async Task PageFactory(int pagenum) } [Cmd, Aliases, RequireContext(ContextType.Guild)] - public async Task RolePermList(params GuildPermission[] perms) - => await RolePermList(PermissionType.And, perms); + public Task RolePermList(params GuildPermission[] perms) + => RolePermList(PermissionType.And, perms); [Cmd, Aliases, RequireContext(ContextType.Guild), UserPerm(GuildPermission.ManageMessages)] public async Task GetJson(ulong id, ITextChannel channel = null) @@ -132,8 +137,8 @@ public async Task GetJson(ulong id, ITextChannel channel = null) } [Cmd, Aliases, RequireContext(ContextType.Guild), UserPerm(GuildPermission.ManageMessages)] - public async Task GetJson(ITextChannel channel, ulong messageId) - => await GetJson(messageId, channel); + public Task GetJson(ITextChannel channel, ulong messageId) + => GetJson(messageId, channel); [Cmd, Aliases, RequireContext(ContextType.Guild), UserPerm(GuildPermission.ManageMessages)] public async Task SaveChat(StoopidTime time, ITextChannel? channel = null) @@ -1576,7 +1581,7 @@ await PromptUserConfirmAsync("Do you want to use the text file in your attachmen [Cmd, Aliases, RequireContext(ContextType.Guild), UserPerm(GuildPermission.ManageMessages), Priority(0)] - public async Task Say([Remainder] string? message = null) => await Say((ITextChannel)ctx.Channel, message); + public Task Say([Remainder] string? message = null) => Say((ITextChannel)ctx.Channel, message); [Cmd, Aliases] public async Task Stats() diff --git a/src/Mewdeko/Modules/Votes/VoteSlashCommands.cs b/src/Mewdeko/Modules/Votes/VoteSlashCommands.cs index 0cf2b0e94..8eaef304b 100644 --- a/src/Mewdeko/Modules/Votes/VoteSlashCommands.cs +++ b/src/Mewdeko/Modules/Votes/VoteSlashCommands.cs @@ -16,14 +16,16 @@ public class VoteSlashCommands : MewdekoSlashModuleBase public VoteSlashCommands(InteractiveService interactivity) => this.interactivity = interactivity; - [SlashCommand("channel", "Set the channel"), SlashUserPerm(GuildPermission.ManageGuild), CheckPermissions, RequireContext(ContextType.Guild)] + [SlashCommand("channel", "Set the channel"), SlashUserPerm(GuildPermission.ManageGuild), CheckPermissions, + RequireContext(ContextType.Guild)] public async Task VoteChannel(ITextChannel channel) { await Service.SetVoteChannel(ctx.Guild.Id, channel.Id); await ctx.Interaction.SendConfirmAsync("Sucessfully set the vote channel!"); } - [SlashCommand("message", "Set the embed/text message when a vote is recieved"), SlashUserPerm(GuildPermission.ManageGuild), CheckPermissions, RequireContext(ContextType.Guild)] + [SlashCommand("message", "Set the embed/text message when a vote is recieved"), + SlashUserPerm(GuildPermission.ManageGuild), CheckPermissions, RequireContext(ContextType.Guild)] public async Task VoteMessage(string message = null) { await DeferAsync(); @@ -48,9 +50,12 @@ public async Task VoteMessage(string message = null) var rep = new ReplacementBuilder() .WithDefault(ctx.User, null, ctx.Guild as SocketGuild, ctx.Client as DiscordSocketClient) .WithOverride("%votestotalcount%", () => votes.Count.ToString()) - .WithOverride("%votesmonthcount%", () => votes.Count(x => x.DateAdded.Value.Month == DateTime.UtcNow.Month).ToString()).Build(); + .WithOverride("%votesmonthcount%", + () => votes.Count(x => x.DateAdded.Value.Month == DateTime.UtcNow.Month).ToString()) + .Build(); - if (SmartEmbed.TryParse(rep.Replace(voteMessage), ctx.Guild.Id, out var embeds, out var plainText, out var components)) + if (SmartEmbed.TryParse(rep.Replace(voteMessage), ctx.Guild.Id, out var embeds, out var plainText, + out var components)) { await ctx.Interaction.FollowupAsync(plainText, embeds: embeds, components: components.Build()); } @@ -79,7 +84,8 @@ public async Task VoteMessage(string message = null) } } - [SlashCommand("password", "Sets the password using a modal."), SlashUserPerm(GuildPermission.ManageGuild), RequireContext(ContextType.Guild), CheckPermissions] + [SlashCommand("password", "Sets the password using a modal."), SlashUserPerm(GuildPermission.ManageGuild), + RequireContext(ContextType.Guild), CheckPermissions] public async Task VotePassword() { await DeferAsync(); @@ -87,12 +93,14 @@ public async Task VotePassword() "Please make absolute sure nobody else sees this password, otherwise this will lead to improper data. ***Mewdeko and it's team are not responsible for stolen passwords***. \n\nDo you agree to these terms?", ctx.User.Id)) { - var component = new ComponentBuilder().WithButton("Press this to set the password. Remember, do not share it to anyone else.", "setvotepassword"); + var component = new ComponentBuilder().WithButton( + "Press this to set the password. Remember, do not share it to anyone else.", "setvotepassword"); await ctx.Interaction.FollowupAsync("_ _", components: component.Build()); } } - [SlashCommand("roleadd", "Add a role as a vote role"), SlashUserPerm(GuildPermission.ManageGuild), RequireContext(ContextType.Guild), CheckPermissions] + [SlashCommand("roleadd", "Add a role as a vote role"), SlashUserPerm(GuildPermission.ManageGuild), + RequireContext(ContextType.Guild), CheckPermissions] public async Task VoteRoleAdd(IRole role, string time = null) { var parsedTime = StoopidTime.FromInput("0s"); @@ -114,11 +122,13 @@ public async Task VoteRoleAdd(IRole role, string time = null) var added = await Service.AddVoteRole(ctx.Guild.Id, role.Id, (int)parsedTime.Time.TotalSeconds); if (!added.Item1) { - await ctx.Interaction.SendErrorAsync($"Adding vote role failed for the following reason: {added.Item2}"); + await ctx.Interaction.SendErrorAsync( + $"Adding vote role failed for the following reason: {added.Item2}"); } else { - await ctx.Interaction.SendConfirmAsync($"{role.Mention} added as a vote role and will last {parsedTime.Time.Humanize()} when a person votes."); + await ctx.Interaction.SendConfirmAsync( + $"{role.Mention} added as a vote role and will last {parsedTime.Time.Humanize()} when a person votes."); } } else @@ -126,7 +136,8 @@ public async Task VoteRoleAdd(IRole role, string time = null) var added = await Service.AddVoteRole(ctx.Guild.Id, role.Id); if (!added.Item1) { - await ctx.Interaction.SendErrorAsync($"Adding vote role failed for the following reason: {added.Item2}"); + await ctx.Interaction.SendErrorAsync( + $"Adding vote role failed for the following reason: {added.Item2}"); } else { @@ -135,7 +146,8 @@ public async Task VoteRoleAdd(IRole role, string time = null) } } - [SlashCommand("roleedit", "Edits a vote roles expire timer."), SlashUserPerm(GuildPermission.ManageGuild), RequireContext(ContextType.Guild), CheckPermissions] + [SlashCommand("roleedit", "Edits a vote roles expire timer."), SlashUserPerm(GuildPermission.ManageGuild), + RequireContext(ContextType.Guild), CheckPermissions] public async Task VoteRoleEdit(IRole role, string time) { StoopidTime parsedTime; @@ -152,42 +164,51 @@ public async Task VoteRoleEdit(IRole role, string time) var update = await Service.UpdateTimer(role.Id, (int)parsedTime.Time.TotalSeconds); if (!update.Item1) { - await ctx.Interaction.SendErrorAsync($"Updating vote role time failed due to the following reason: {update.Item2}"); + await ctx.Interaction.SendErrorAsync( + $"Updating vote role time failed due to the following reason: {update.Item2}"); } else { - await ctx.Interaction.SendConfirmAsync($"Successfuly updated the vote role time to {parsedTime.Time.Humanize()}"); + await ctx.Interaction.SendConfirmAsync( + $"Successfuly updated the vote role time to {parsedTime.Time.Humanize()}"); } } - [ComponentInteraction("setvotepassword", true), SlashUserPerm(GuildPermission.ManageGuild), CheckPermissions, RequireContext(ContextType.Guild)] - public async Task VotePasswordButton() - => await RespondWithModalAsync("votepassmodal"); + [ComponentInteraction("setvotepassword", true), SlashUserPerm(GuildPermission.ManageGuild), CheckPermissions, + RequireContext(ContextType.Guild)] + public Task VotePasswordButton() + => RespondWithModalAsync("votepassmodal"); - [ModalInteraction("votepassmodal", true), SlashUserPerm(GuildPermission.ManageGuild), CheckPermissions, RequireContext(ContextType.Guild)] + [ModalInteraction("votepassmodal", true), SlashUserPerm(GuildPermission.ManageGuild), CheckPermissions, + RequireContext(ContextType.Guild)] public async Task VotePassModal(VotePasswordModal modal) { await ctx.Interaction.SendEphemeralConfirmAsync("Vote password set."); await Service.SetVotePassword(ctx.Guild.Id, modal.Password); } - [SlashCommand("votes", "Shows your total and this months votes"), RequireContext(ContextType.Guild), CheckPermissions] + [SlashCommand("votes", "Shows your total and this months votes"), RequireContext(ContextType.Guild), + CheckPermissions] public async Task Votes(IUser user = null) { var curUser = user ?? ctx.User; await ctx.Interaction.RespondAsync(embed: (await Service.GetTotalVotes(curUser, ctx.Guild)).Build()); } - [SlashCommand("leaderboard", "Shows the current or monthly leaderboard for votes"), RequireContext(ContextType.Guild), CheckPermissions] + [SlashCommand("leaderboard", "Shows the current or monthly leaderboard for votes"), + RequireContext(ContextType.Guild), CheckPermissions] public async Task VotesLeaderboard(bool monthly = false) { List votes; if (monthly) - votes = (await Service.GetVotes(ctx.Guild.Id)).Where(x => x.DateAdded.Value.Month == DateTime.UtcNow.Month).ToList(); + votes = (await Service.GetVotes(ctx.Guild.Id)).Where(x => x.DateAdded.Value.Month == DateTime.UtcNow.Month) + .ToList(); else votes = await Service.GetVotes(ctx.Guild.Id); if (votes is null || !votes.Any()) { - await ctx.Channel.SendErrorAsync(monthly ? "Not enough monthly votes for a leaderboard." : "Not enough votes for a leaderboard."); + await ctx.Channel.SendErrorAsync(monthly + ? "Not enough monthly votes for a leaderboard." + : "Not enough votes for a leaderboard."); return; } @@ -221,13 +242,15 @@ public async Task VotesLeaderboard(bool monthly = false) .WithActionOnCancellation(ActionOnStop.DeleteMessage) .Build(); - await interactivity.SendPaginatorAsync(paginator, Context.Interaction, TimeSpan.FromMinutes(60)).ConfigureAwait(false); + await interactivity.SendPaginatorAsync(paginator, Context.Interaction, TimeSpan.FromMinutes(60)) + .ConfigureAwait(false); async Task PageFactory(int page) { await Task.CompletedTask; - var eb = new PageBuilder().WithTitle(monthly ? "Votes leaaderboard for this month" : "Votes Leaderboard").WithOkColor(); + var eb = new PageBuilder().WithTitle(monthly ? "Votes leaaderboard for this month" : "Votes Leaderboard") + .WithOkColor(); for (var i = 0; i < voteList.Count; i++) { diff --git a/src/Mewdeko/Modules/Xp/Club.cs b/src/Mewdeko/Modules/Xp/Club.cs index 5be3f23e0..864e628c9 100644 --- a/src/Mewdeko/Modules/Xp/Club.cs +++ b/src/Mewdeko/Modules/Xp/Club.cs @@ -302,7 +302,7 @@ public async Task Clubleave() } [Cmd, Aliases, Priority(1)] - public async Task ClubKick([Remainder] IUser user) => await ClubKick(user.ToString()).ConfigureAwait(false); + public Task ClubKick([Remainder] IUser user) => ClubKick(user.ToString()); [Cmd, Aliases, Priority(0)] public async Task ClubKick([Remainder] string userName) @@ -319,7 +319,7 @@ await ReplyConfirmLocalizedAsync("club_user_kick", Format.Bold(userName), } [Cmd, Aliases, Priority(1)] - public async Task ClubBan([Remainder] IUser user) => await ClubBan(user.ToString()); + public Task ClubBan([Remainder] IUser user) => ClubBan(user.ToString()); [Cmd, Aliases, Priority(0)] public async Task ClubBan([Remainder] string userName) @@ -336,7 +336,7 @@ await ReplyConfirmLocalizedAsync("club_user_banned", Format.Bold(userName), } [Cmd, Aliases, Priority(1)] - public async Task ClubUnBan([Remainder] IUser user) => await ClubUnBan(user.ToString()).ConfigureAwait(false); + public Task ClubUnBan([Remainder] IUser user) => ClubUnBan(user.ToString()); [Cmd, Aliases, Priority(0)] public async Task ClubUnBan([Remainder] string userName) diff --git a/src/Mewdeko/Modules/Xp/Services/XpService.cs b/src/Mewdeko/Modules/Xp/Services/XpService.cs index e538738c3..a84b09092 100644 --- a/src/Mewdeko/Modules/Xp/Services/XpService.cs +++ b/src/Mewdeko/Modules/Xp/Services/XpService.cs @@ -78,7 +78,8 @@ public XpService( XpTxtTimeouts = allGuildConfigs.ToDictionary(x => x.GuildId, x => x.XpTxtTimeout).ToConcurrent(); XpVoiceRates = allGuildConfigs.ToDictionary(x => x.GuildId, x => x.XpVoiceRate).ToConcurrent(); XpVoiceTimeouts = allGuildConfigs.ToDictionary(x => x.GuildId, x => x.XpVoiceTimeout).ToConcurrent(); - excludedChannels = allGuildConfigs.Where(x => x.XpSettings?.ExclusionList.Count > 0).ToDictionary(x => x.GuildId, + excludedChannels = allGuildConfigs.Where(x => x.XpSettings?.ExclusionList.Count > 0).ToDictionary( + x => x.GuildId, x => new ConcurrentHashSet(x.XpSettings?.ExclusionList .Where(ex => ex.ItemType == ExcludedItemType.Channel) .Select(ex => ex.ItemId).Distinct())).ToConcurrent(); @@ -91,6 +92,10 @@ public XpService( excludedServers = new ConcurrentHashSet( allGuildConfigs.Where(x => x.XpSettings?.ServerExcluded == 1).Select(x => x.GuildId)); + XpImages = new NonBlocking.ConcurrentDictionary(allGuildConfigs + .Where(x => !string.IsNullOrWhiteSpace(x.XpImgUrl)) + .ToDictionary(x => x.GuildId, x => x.XpImgUrl)); + this.cmd.OnMessageNoTrigger += Cmd_OnMessageNoTrigger; #if !GLOBAL_Mewdeko @@ -107,6 +112,7 @@ public XpService( private NonBlocking.ConcurrentDictionary XpVoiceRates { get; } private NonBlocking.ConcurrentDictionary XpTxtTimeouts { get; } private NonBlocking.ConcurrentDictionary XpVoiceTimeouts { get; } + private NonBlocking.ConcurrentDictionary XpImages { get; } public Task Unload() { @@ -217,7 +223,8 @@ await Task.WhenAll(toNotify.Select(async x => if (chan != null) { await chan.SendConfirmAsync(strings.GetText("level_up_dm", x.Guild.Id, x.User.Mention, - Format.Bold(x.Level.ToString()), Format.Bold(x.Guild.ToString() ?? "-"))).ConfigureAwait(false); + Format.Bold(x.Level.ToString()), Format.Bold(x.Guild.ToString() ?? "-"))) + .ConfigureAwait(false); } } else if (x.MessageChannel != null) // channel @@ -444,7 +451,9 @@ private void UserJoinedVoiceChannel(SocketGuildUser user) { var key = $"{creds.RedisKey()}_user_xp_vc_join_{user.Id}"; var value = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); - var e = GetVoiceXpTimeout(user.Guild.Id) == 0 ? xpConfig.Data.VoiceMaxMinutes : GetVoiceXpTimeout(user.Guild.Id); + var e = GetVoiceXpTimeout(user.Guild.Id) == 0 + ? xpConfig.Data.VoiceMaxMinutes + : GetVoiceXpTimeout(user.Guild.Id); if (memoryCache.Get(key) is not null) return; memoryCache.Set(key, value, TimeSpan.FromMinutes(e)); @@ -725,7 +734,23 @@ public async Task GenerateXpImageAsync(IGuildUser user) private async Task GenerateXpImageAsync(FullUserStats stats, Template template) { // Load the background image - await using var xpstream = new MemoryStream(images.XpBackground); + await using var xpstream = new MemoryStream(); + if (XpImages.TryGetValue(stats.FullGuildStats.GuildId, out var bannerUrl)) + { + using var httpClient = new HttpClient(); + var httpResponse = await httpClient.GetAsync(bannerUrl); + if (httpResponse.IsSuccessStatusCode) + { + await httpResponse.Content.CopyToAsync(xpstream); + xpstream.Position = 0; + } + } + else + { + await xpstream.WriteAsync(images.XpBackground.AsMemory(0, images.XpBackground.Length)); + xpstream.Position = 0; + } + var imgData = SKData.Create(xpstream); var img = SKBitmap.Decode(imgData); var canvas = new SKCanvas(img); @@ -741,7 +766,8 @@ private async Task GenerateXpImageAsync(FullUserStats stats, Template te var color = SKColor.Parse(template.TemplateUser.TextColor); textPaint.Color = color; textPaint.TextSize = template.TemplateUser.FontSize; - textPaint.Typeface = SKTypeface.FromFamilyName("NotoSans", SKFontStyleWeight.Bold, SKFontStyleWidth.Normal, SKFontStyleSlant.Upright); + textPaint.Typeface = SKTypeface.FromFamilyName("NotoSans", SKFontStyleWeight.Bold, SKFontStyleWidth.Normal, + SKFontStyleSlant.Upright); var username = stats.User.Username; canvas.DrawText(username, template.TemplateUser.TextX, template.TemplateUser.TextY, textPaint); } @@ -752,7 +778,8 @@ private async Task GenerateXpImageAsync(FullUserStats stats, Template te textPaint.TextSize = template.TemplateGuild.GuildLevelFontSize; var color = SKColor.Parse(template.TemplateGuild.GuildLevelColor); textPaint.Color = color; - canvas.DrawText(stats.Guild.Level.ToString(), template.TemplateGuild.GuildLevelX, template.TemplateGuild.GuildLevelY, textPaint); + canvas.DrawText(stats.Guild.Level.ToString(), template.TemplateGuild.GuildLevelX, + template.TemplateGuild.GuildLevelY, textPaint); } var guild = stats.Guild; @@ -781,7 +808,8 @@ private async Task GenerateXpImageAsync(FullUserStats stats, Template te textPaint.TextSize = template.TemplateGuild.GuildRankFontSize; var color = SKColor.Parse(template.TemplateGuild.GuildRankColor); textPaint.Color = color; - canvas.DrawText(stats.GuildRanking.ToString(), template.TemplateGuild.GuildRankX, template.TemplateGuild.GuildRankY, textPaint); + canvas.DrawText(stats.GuildRanking.ToString(), template.TemplateGuild.GuildRankX, + template.TemplateGuild.GuildRankY, textPaint); } // Draw time on level @@ -810,7 +838,10 @@ private async Task GenerateXpImageAsync(FullUserStats stats, Template te var avatarImg = SKBitmap.Decode(avatarImgData); // resize the avatar - var resizedAvatar = avatarImg.Resize(new SKImageInfo(template.TemplateUser.IconSizeX, template.TemplateUser.IconSizeY), SKFilterQuality.High); + var resizedAvatar = + avatarImg.Resize( + new SKImageInfo(template.TemplateUser.IconSizeX, template.TemplateUser.IconSizeY), + SKFilterQuality.High); // apply rounded corners var roundedAvatar = ApplyRoundedCorners(resizedAvatar, template.TemplateUser.IconSizeX / 2); @@ -965,4 +996,53 @@ private enum NotifOf Server, Global } // is it a server level-up or global level-up notification + + public async Task SetImageUrl(ulong guildId, string imageUrl) + { + await using var uow = db.GetDbContext(); + var set = await uow.ForGuildId(guildId); + set.XpImgUrl = imageUrl; + uow.GuildConfigs.Update(set); + await uow.SaveChangesAsync(); + if (XpImages.TryGetValue(guildId, out _)) + { + XpImages.TryRemove(guildId, out _); + XpImages.TryAdd(guildId, imageUrl); + } + else + XpImages.TryAdd(guildId, imageUrl); + } + + public async Task<(string, bool)> ValidateImageUrl(string url) + { + if (!Uri.IsWellFormedUriString(url, UriKind.Absolute)) + return ("Malformed URL", false); + + var formatAllowed = url.EndsWith(".png") || url.EndsWith(".jpg"); + if (!formatAllowed) + return ("Must end with png or jpg", false); + + using var httpClient = new HttpClient(); + var httpRequest = new HttpRequestMessage(HttpMethod.Head, url); + + try + { + var response = await httpClient.SendAsync(httpRequest); + if (!response.IsSuccessStatusCode) + { + // not a valid URL or couldn't fetch the document + return ("Url provided was unreachable", false); + } + + var contentLength = response.Content.Headers.ContentLength; + var contentLengthMb = contentLength / (1024 * 1024); // convert bytes to MB + return ("File is over 20MB", !(contentLengthMb > 20)); + // File is too large (over 20MB) + } + catch + { + // Something went wrong with fetching info about the resource. + return ("An unknown error occured while attempting to fetch the image", false); + } + } } \ No newline at end of file diff --git a/src/Mewdeko/Modules/Xp/Xp.cs b/src/Mewdeko/Modules/Xp/Xp.cs index 012e4f05c..882c32856 100644 --- a/src/Mewdeko/Modules/Xp/Xp.cs +++ b/src/Mewdeko/Modules/Xp/Xp.cs @@ -10,8 +10,12 @@ namespace Mewdeko.Modules.Xp; -public partial class Xp(DownloadTracker tracker, XpConfigService xpconfig, InteractiveService serv, - BotConfigService bss, DbService db) +public partial class Xp( + DownloadTracker tracker, + XpConfigService xpconfig, + InteractiveService serv, + BotConfigService bss, + DbService db) : MewdekoModuleBase { public enum Channel @@ -39,77 +43,60 @@ public enum Server private async Task SendXpSettings(ITextChannel chan) { var list = new List(); - if (Service.GetTxtXpRate(ctx.Guild.Id) == 0) - { - var toadd = new XpStuffs - { - Setting = "xptextrate", Value = $"{xpconfig.Data.XpPerMessage} (Global Default)" - }; - list.Add(toadd); - } - else - { - var toadd = new XpStuffs - { - Setting = "xptextrate", Value = $"{Service.GetTxtXpRate(ctx.Guild.Id)} (Server Set)" - }; - list.Add(toadd); - } - if (Service.GetVoiceXpRate(ctx.Guild.Id) == 0) - { - var toadd = new XpStuffs - { - Setting = "voicexprate", Value = $"{xpconfig.Data.VoiceXpPerMinute} (Global Default)" - }; - list.Add(toadd); - } - else + list.Add(CreateXpStuffs("xptextrate", Service.GetTxtXpRate(ctx.Guild.Id), xpconfig.Data.XpPerMessage)); + list.Add(CreateXpStuffs("voicexprate", Service.GetVoiceXpRate(ctx.Guild.Id), xpconfig.Data.VoiceXpPerMinute)); + list.Add(CreateXpStuffs("txtxptimeout", Service.GetXpTimeout(ctx.Guild.Id), xpconfig.Data.MessageXpCooldown)); + list.Add(CreateXpStuffs("voiceminutestimeout", Service.GetVoiceXpTimeout(ctx.Guild.Id), + xpconfig.Data.VoiceMaxMinutes)); + + var strings = list.Select(i => $"{i.Setting,-25} = {i.Value}\n").ToList(); + await chan.SendConfirmAsync(Format.Code(string.Concat(strings), "hs")).ConfigureAwait(false); + } + + private static XpStuffs CreateXpStuffs(string settingName, double xpRate, double defaultValue) + { + var settingValue = xpRate == 0 + ? $"{defaultValue} (Global Default)" + : $"{xpRate} (Server Set)"; + + return new XpStuffs { - var toadd = new XpStuffs - { - Setting = "xpvoicerate", Value = $"{Service.GetVoiceXpRate(ctx.Guild.Id)} (Server Set)" - }; - list.Add(toadd); - } + Setting = settingName, Value = settingValue + }; + } - if (Service.GetXpTimeout(ctx.Guild.Id) == 0) + [Cmd, Aliases, RequireContext(ContextType.Guild), UserPerm(GuildPermission.ManageGuild)] + public async Task SetXpImage(string url = null) + { + if (url is null) { - var toadd = new XpStuffs + var attachments = Context.Message.Attachments; + if (attachments.Count != 0) { - Setting = "txtxptimeout", Value = $"{xpconfig.Data.MessageXpCooldown} (Global Default)" - }; - list.Add(toadd); - } - else - { - var toadd = new XpStuffs + var attachment = attachments.FirstOrDefault(); + if (attachment != null) + { + url = attachment.Url; + } + } + else { - Setting = "txtxptimeout", Value = $"{Service.GetXpTimeout(ctx.Guild.Id)} (Server Set)" - }; - list.Add(toadd); + await ctx.Channel.SendErrorAsync("Please provide a valid URL or attachment.").ConfigureAwait(false); + return; + } } - if (Service.GetVoiceXpTimeout(ctx.Guild.Id) == 0) - { - var toadd = new XpStuffs - { - Setting = "voiceminutestimeout", Value = $"{xpconfig.Data.VoiceMaxMinutes} (Global Default)" - }; - list.Add(toadd); - } - else + var (reason, success) = await Service.ValidateImageUrl(url); + + if (!success) { - var toadd = new XpStuffs - { - Setting = "voiceminutestimeout", Value = $"{Service.GetXpTimeout(ctx.Guild.Id)} (Server Set)" - }; - list.Add(toadd); + await ctx.Channel.SendErrorAsync(reason).ConfigureAwait(false); + return; } - var strings = list.Select(i => $"{i.Setting,-25} = {i.Value}\n").ToList(); - - await chan.SendConfirmAsync(Format.Code(string.Concat(strings), "hs")).ConfigureAwait(false); + await Service.SetImageUrl(Context.Guild.Id, url); + await ctx.Channel.SendConfirmAsync("XP image URL has been set.").ConfigureAwait(false); } [Cmd, Aliases, RequireContext(ContextType.Guild), Ratelimit(60)] diff --git a/src/Mewdeko/Program.cs b/src/Mewdeko/Program.cs index 10d385c5c..73d5d3954 100644 --- a/src/Mewdeko/Program.cs +++ b/src/Mewdeko/Program.cs @@ -4,158 +4,96 @@ using Mewdeko.Services.Impl; using Serilog; -Console.WriteLine( - FiggleFonts.Ogre.Render("Mewdeko v8")); +// Setup and Initialization +Console.WriteLine(FiggleFonts.Ogre.Render("Mewdeko v8")); -var pid = Environment.ProcessId; -var shardId = 0; - -if (args.Length > 0) +var shardId = ExtractArgument(args, 0, "shard id"); +if (shardId < 0) { - if (!int.TryParse(args[0], out shardId)) - { - Console.Error.WriteLine("Invalid first argument (shard id): {0}", args[0]); - return; - } - - if (args.Length > 1) - { - if (!int.TryParse(args[1], out _)) - { - Console.Error.WriteLine("Invalid second argument (total shards): {0}", args[1]); - return; - } - } + Console.WriteLine("Please provide a valid shard id as an argument. Exiting..."); + return; } LogSetup.SetupLogger(shardId); + var credentials = new BotCredentials(); if (string.IsNullOrEmpty(credentials.Token)) { - Console.Error.WriteLine("No token provided. Exiting..."); - return; + throw new ArgumentException("No token provided. Exiting..."); } -var tokenPart = credentials.Token.Split(".")[0]; -var paddingNeeded = 28 - tokenPart.Length; -if (paddingNeeded > 0 && tokenPart.Length % 4 != 0) -{ - tokenPart = tokenPart.PadRight(28, '='); -} +var clientId = ExtractToken(credentials.Token); -var clientId = Encoding.UTF8.GetString(Convert.FromBase64String(tokenPart)); +// Database Migration +var folderPath = Environment.OSVersion.Platform == PlatformID.Unix + ? Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + : Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); -Log.Information("Attempting to migrate database to a less annoying place..."); -var dbPath = Path.Combine(AppContext.BaseDirectory, "data/Mewdeko.db"); -if (Environment.OSVersion.Platform == PlatformID.Unix) +MigrateDatabase(clientId, folderPath); + +// Final Steps +Environment.SetEnvironmentVariable($"AFK_CACHED_{shardId}", "0"); +Log.Information($"Pid: {Environment.ProcessId}"); + +await new Mewdeko.Mewdeko(shardId).RunAndBlockAsync().ConfigureAwait(false); +return; + +// Extract and check arguments +int ExtractArgument(IReadOnlyList args, int index, string argName) { - var folderpath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); - try + if (args.Count <= index || !int.TryParse(args[index], out var arg)) { - if (Directory.Exists(folderpath + "/.local/share/Mewdeko")) - { - if (File.Exists(folderpath + $"/.local/share/Mewdeko/{clientId}/data/Mewdeko.db")) - { - Log.Information("Mewdeko db already exists!"); - } - else - { - Directory.CreateDirectory(folderpath + $"/.local/share/Mewdeko/{clientId}/data"); - File.Copy(dbPath, folderpath + $"/.local/share/Mewdeko/{clientId}/data/Mewdeko.db"); - try - { - File.Copy(dbPath + "-wal", folderpath + $"/.local/share/Mewdeko/{clientId}/data/Mewdeko.db-wal"); - File.Copy(dbPath + "-shm", folderpath + $"/.local/share/Mewdeko/{clientId}/data/Mewdeko.db-shm"); - } - catch - { - // ignored, used if the bot didnt shutdown properly and left behind db files - } - - Log.Information("Mewdeko folder created!"); - Log.Information( - $"Mewdeko folder created! Your database has been migrated to {folderpath}/.local/share/Mewdeko/Mewdeko/{clientId}/data"); - } - } - else - { - Directory.CreateDirectory(folderpath + $"/.local/share/Mewdeko/{clientId}/data"); - File.Copy(dbPath, folderpath + $"/.local/share/Mewdeko/{clientId}/data/Mewdeko.db"); - try - { - File.Copy(dbPath + "-wal", folderpath + $"/.local/share/Mewdeko/{clientId}/data/Mewdeko.db-wal"); - File.Copy(dbPath + "-shm", folderpath + $"/.local/share/Mewdeko/{clientId}/data/Mewdeko.db-shm"); - } - catch - { - // ignored, used if the bot didnt shutdown properly and left behind db files - } - - Log.Information( - $"Mewdeko folder created! Your database has been migrated to {folderpath}/.local/share/Mewdeko/Mewdeko/{clientId}/data"); - } + return 0; } - catch (Exception e) + + return arg; +} + +// Extract Token +string ExtractToken(string token) +{ + var tokenPart = token.Split(".")[0]; + var paddingNeeded = 28 - tokenPart.Length; + if (paddingNeeded > 0 && tokenPart.Length % 4 != 0) { - Log.Error(e, "Failed to create Mewdeko folder! The application may be missing permissions!"); - Console.Read(); + tokenPart = tokenPart.PadRight(28, '='); } + + return Encoding.UTF8.GetString(Convert.FromBase64String(tokenPart)); } -else + +// Migrate database +void MigrateDatabase(string clientId, string folderPath) { - var folderpath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); - try + var dbPath = Path.Combine(AppContext.BaseDirectory, "data/Mewdeko.db"); + MigrateData(dbPath, folderPath + $"/.local/share/Mewdeko/{clientId}/data", clientId); +} + +// Create directories and copy database files +void MigrateData(string sourcePath, string targetPath, string clientId) +{ + if (!Directory.Exists(targetPath)) { - if (Directory.Exists(folderpath + "/Mewdeko")) + Directory.CreateDirectory(targetPath); + } + + if (!File.Exists($"{targetPath}/Mewdeko.db")) + { + File.Copy(Path.Combine(sourcePath, "Mewdeko.db"), Path.Combine(targetPath, "Mewdeko.db")); + try { - if (File.Exists(folderpath + $"/Mewdeko/{clientId}/data/Mewdeko.db")) - { - Log.Information("Mewdeko folder already exists!"); - } - else - { - Directory.CreateDirectory(folderpath + $"/Mewdeko/{clientId}/data"); - File.Copy(dbPath, folderpath + $"/Mewdeko/{clientId}/data/Mewdeko.db"); - try - { - File.Copy(dbPath + "-wal", folderpath + $"/Mewdeko/{clientId}/data/Mewdeko.db-wal"); - File.Copy(dbPath + "-shm", folderpath + $"/Mewdeko/{clientId}/data/Mewdeko.db-shm"); - } - catch - { - // ignored, used if the bot didnt shutdown properly and left behind db files - } - - Log.Information( - $"Mewdeko folder created! Your database has been migrated to {folderpath}/Mewdeko/{clientId}"); - } + File.Copy(Path.Combine(sourcePath, "Mewdeko.db-wal"), Path.Combine(targetPath, "Mewdeko.db-wal")); + File.Copy(Path.Combine(sourcePath, "Mewdeko.db-shm"), Path.Combine(targetPath, "Mewdeko.db-shm")); } - else + catch { - Directory.CreateDirectory(folderpath + $"/Mewdeko/{clientId}/data"); - File.Copy(dbPath, folderpath + $"/Mewdeko/{clientId}/data/Mewdeko.db"); - try - { - File.Copy(dbPath + "-wal", folderpath + $"/Mewdeko/{clientId}/data/Mewdeko.db-wal"); - File.Copy(dbPath + "-shm", folderpath + $"/Mewdeko/{clientId}/data/Mewdeko.db-shm"); - } - catch - { - // ignored, used if the bot didnt shutdown properly and left behind db files - } - - Log.Information( - $"Mewdeko folder created! Your database has been migrated to {folderpath}/Mewdeko/{clientId}"); + // ignored, used if the bot didn't shut down properly and left behind db files } + + Log.Information("Mewdeko folder created! Your database has been migrated to {TargetPath}", targetPath); } - catch (Exception e) + else { - Log.Error(e, "Failed to create Mewdeko folder! The application may be missing permissions!"); - Console.Read(); + Log.Information("Mewdeko db already exists!"); } -} - -Environment.SetEnvironmentVariable($"AFK_CACHED_{shardId}", "0"); -Log.Information($"Pid: {pid}"); - -await new Mewdeko.Mewdeko(shardId).RunAndBlockAsync().ConfigureAwait(false); \ No newline at end of file +} \ No newline at end of file diff --git a/src/Mewdeko/Services/CommandHandler.cs b/src/Mewdeko/Services/CommandHandler.cs index 0a96b8774..95e4a6fc1 100644 --- a/src/Mewdeko/Services/CommandHandler.cs +++ b/src/Mewdeko/Services/CommandHandler.cs @@ -725,10 +725,10 @@ private async Task TryRunCommand(IGuild? guild, IChannel channel, IUserMessage u } - private async Task<(bool Success, string Error, CommandInfo Info)> ExecuteCommandAsync(CommandContext context, + private Task<(bool Success, string Error, CommandInfo Info)> ExecuteCommandAsync(CommandContext context, string input, int argPos, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception) => - await ExecuteCommand(context, input[argPos..], multiMatchHandling).ConfigureAwait(false); + ExecuteCommand(context, input[argPos..], multiMatchHandling); private async Task<(bool Success, string Error, CommandInfo Info)> ExecuteCommand(CommandContext context, string input, diff --git a/src/Mewdeko/Services/GuildSettingsService.cs b/src/Mewdeko/Services/GuildSettingsService.cs index 5fe780d77..6d6716bdb 100644 --- a/src/Mewdeko/Services/GuildSettingsService.cs +++ b/src/Mewdeko/Services/GuildSettingsService.cs @@ -17,7 +17,7 @@ public async Task SetPrefix(IGuild guild, string prefix) return prefix; } - public async Task GetPrefix(IGuild? guild) => await GetPrefix(guild.Id); + public Task GetPrefix(IGuild? guild) => GetPrefix(guild.Id); public async Task GetPrefix(ulong? id) {