diff --git a/.gitmodules b/.gitmodules index 0f1296be..38614ef7 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ -[submodule "discord.net"] - path = discord.net - url = https://github.com/kwoth/discord.net +[submodule "Discord.Net"] + path = Discord.Net + url = https://github.com/RogueException/Discord.Net branch = dev diff --git a/Discord.Net b/Discord.Net new file mode 160000 index 00000000..40fa35c8 --- /dev/null +++ b/Discord.Net @@ -0,0 +1 @@ +Subproject commit 40fa35c851076fb035fab06deb06f2b013281c15 diff --git a/NadekoBot.sln b/NadekoBot.sln index 7b8981b8..e0ebea17 100644 --- a/NadekoBot.sln +++ b/NadekoBot.sln @@ -12,10 +12,16 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution EndProject Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "NadekoBot", "src\NadekoBot\NadekoBot.xproj", "{45EC1473-C678-4857-A544-07DFE0D0B478}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Discord.Net", "discord.net\src\Discord.Net\Discord.Net.xproj", "{91E9E7BD-75C9-4E98-84AA-2C271922E5C2}" +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Discord.Net.API", "discord.net\src\Discord.Net.API\Discord.Net.API.xproj", "{834C70DF-1230-4AAA-9C13-48AB232E8D76}" EndProject Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Discord.Net.Commands", "discord.net\src\Discord.Net.Commands\Discord.Net.Commands.xproj", "{078DD7E6-943D-4D09-AFC2-D2BA58B76C9C}" EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Discord.Net.Core", "discord.net\src\Discord.Net.Core\Discord.Net.Core.xproj", "{E5F4786F-58F3-469E-8C87-1908A95436B7}" +EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Discord.Net.Rest", "discord.net\src\Discord.Net.Rest\Discord.Net.Rest.xproj", "{63F5B5C8-56FE-4B53-8003-B58CEB451EF9}" +EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Discord.Net.WebSocket", "discord.net\src\Discord.Net.WebSocket\Discord.Net.WebSocket.xproj", "{E9800F7A-3354-41B1-BDBB-2D59F8124EC9}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -25,22 +31,40 @@ Global GlobalSection(ProjectConfigurationPlatforms) = postSolution {45EC1473-C678-4857-A544-07DFE0D0B478}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {45EC1473-C678-4857-A544-07DFE0D0B478}.Debug|Any CPU.Build.0 = Debug|Any CPU - {45EC1473-C678-4857-A544-07DFE0D0B478}.GlobalNadeko|Any CPU.ActiveCfg = GlobalNadeko|Any CPU - {45EC1473-C678-4857-A544-07DFE0D0B478}.GlobalNadeko|Any CPU.Build.0 = GlobalNadeko|Any CPU + {45EC1473-C678-4857-A544-07DFE0D0B478}.GlobalNadeko|Any CPU.ActiveCfg = Release|Any CPU + {45EC1473-C678-4857-A544-07DFE0D0B478}.GlobalNadeko|Any CPU.Build.0 = Release|Any CPU {45EC1473-C678-4857-A544-07DFE0D0B478}.Release|Any CPU.ActiveCfg = Release|Any CPU {45EC1473-C678-4857-A544-07DFE0D0B478}.Release|Any CPU.Build.0 = Release|Any CPU - {91E9E7BD-75C9-4E98-84AA-2C271922E5C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {91E9E7BD-75C9-4E98-84AA-2C271922E5C2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {91E9E7BD-75C9-4E98-84AA-2C271922E5C2}.GlobalNadeko|Any CPU.ActiveCfg = GlobalNadeko|Any CPU - {91E9E7BD-75C9-4E98-84AA-2C271922E5C2}.GlobalNadeko|Any CPU.Build.0 = GlobalNadeko|Any CPU - {91E9E7BD-75C9-4E98-84AA-2C271922E5C2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {91E9E7BD-75C9-4E98-84AA-2C271922E5C2}.Release|Any CPU.Build.0 = Release|Any CPU + {834C70DF-1230-4AAA-9C13-48AB232E8D76}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {834C70DF-1230-4AAA-9C13-48AB232E8D76}.Debug|Any CPU.Build.0 = Debug|Any CPU + {834C70DF-1230-4AAA-9C13-48AB232E8D76}.GlobalNadeko|Any CPU.ActiveCfg = Debug|Any CPU + {834C70DF-1230-4AAA-9C13-48AB232E8D76}.GlobalNadeko|Any CPU.Build.0 = Debug|Any CPU + {834C70DF-1230-4AAA-9C13-48AB232E8D76}.Release|Any CPU.ActiveCfg = Release|Any CPU + {834C70DF-1230-4AAA-9C13-48AB232E8D76}.Release|Any CPU.Build.0 = Release|Any CPU {078DD7E6-943D-4D09-AFC2-D2BA58B76C9C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {078DD7E6-943D-4D09-AFC2-D2BA58B76C9C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {078DD7E6-943D-4D09-AFC2-D2BA58B76C9C}.GlobalNadeko|Any CPU.ActiveCfg = GlobalNadeko|Any CPU - {078DD7E6-943D-4D09-AFC2-D2BA58B76C9C}.GlobalNadeko|Any CPU.Build.0 = GlobalNadeko|Any CPU + {078DD7E6-943D-4D09-AFC2-D2BA58B76C9C}.GlobalNadeko|Any CPU.ActiveCfg = Debug|Any CPU + {078DD7E6-943D-4D09-AFC2-D2BA58B76C9C}.GlobalNadeko|Any CPU.Build.0 = Debug|Any CPU {078DD7E6-943D-4D09-AFC2-D2BA58B76C9C}.Release|Any CPU.ActiveCfg = Release|Any CPU {078DD7E6-943D-4D09-AFC2-D2BA58B76C9C}.Release|Any CPU.Build.0 = Release|Any CPU + {E5F4786F-58F3-469E-8C87-1908A95436B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E5F4786F-58F3-469E-8C87-1908A95436B7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E5F4786F-58F3-469E-8C87-1908A95436B7}.GlobalNadeko|Any CPU.ActiveCfg = Debug|Any CPU + {E5F4786F-58F3-469E-8C87-1908A95436B7}.GlobalNadeko|Any CPU.Build.0 = Debug|Any CPU + {E5F4786F-58F3-469E-8C87-1908A95436B7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E5F4786F-58F3-469E-8C87-1908A95436B7}.Release|Any CPU.Build.0 = Release|Any CPU + {63F5B5C8-56FE-4B53-8003-B58CEB451EF9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {63F5B5C8-56FE-4B53-8003-B58CEB451EF9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {63F5B5C8-56FE-4B53-8003-B58CEB451EF9}.GlobalNadeko|Any CPU.ActiveCfg = Debug|Any CPU + {63F5B5C8-56FE-4B53-8003-B58CEB451EF9}.GlobalNadeko|Any CPU.Build.0 = Debug|Any CPU + {63F5B5C8-56FE-4B53-8003-B58CEB451EF9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {63F5B5C8-56FE-4B53-8003-B58CEB451EF9}.Release|Any CPU.Build.0 = Release|Any CPU + {E9800F7A-3354-41B1-BDBB-2D59F8124EC9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E9800F7A-3354-41B1-BDBB-2D59F8124EC9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E9800F7A-3354-41B1-BDBB-2D59F8124EC9}.GlobalNadeko|Any CPU.ActiveCfg = Debug|Any CPU + {E9800F7A-3354-41B1-BDBB-2D59F8124EC9}.GlobalNadeko|Any CPU.Build.0 = Debug|Any CPU + {E9800F7A-3354-41B1-BDBB-2D59F8124EC9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E9800F7A-3354-41B1-BDBB-2D59F8124EC9}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/discord.net b/discord.net deleted file mode 160000 index ae614b68..00000000 --- a/discord.net +++ /dev/null @@ -1 +0,0 @@ -Subproject commit ae614b68b336941bf780b5f3c74bf7f6ea505316 diff --git a/global.json b/global.json index 9c989b51..cb8b27b5 100644 --- a/global.json +++ b/global.json @@ -1,3 +1,3 @@ { - "projects": [ "discord.net/src", "src" ] + "projects": [ "discord.net/src", "src", "../../../Documents/Visual Studio 2015/Projects/NadekoWebsite/nadekobot/discord.net/src" ] } diff --git a/src/NadekoBot/Attributes/NadekoModule.cs b/src/NadekoBot/Attributes/NadekoModule.cs index a4aba6c6..30ef1c51 100644 --- a/src/NadekoBot/Attributes/NadekoModule.cs +++ b/src/NadekoBot/Attributes/NadekoModule.cs @@ -7,7 +7,7 @@ using System.Linq; namespace NadekoBot.Attributes { [System.AttributeUsage(AttributeTargets.Class)] - sealed class NadekoModuleAttribute : ModuleAttribute + sealed class NadekoModuleAttribute : GroupAttribute { //modulename / prefix private static Dictionary modulePrefixes = null; @@ -26,9 +26,9 @@ namespace NadekoBot.Attributes } } - public NadekoModuleAttribute(string moduleName, string defaultPrefix) : base(GetModulePrefix(moduleName, defaultPrefix)) + public NadekoModuleAttribute(string moduleName, string defaultPrefix) : base(GetModulePrefix(moduleName, defaultPrefix), moduleName) { - AppendSpace = false; + //AppendSpace = false; } private static string GetModulePrefix(string moduleName, string defaultPrefix) diff --git a/src/NadekoBot/Attributes/OwnerOnlyAttribute.cs b/src/NadekoBot/Attributes/OwnerOnlyAttribute.cs index f04b6ef2..410a24af 100644 --- a/src/NadekoBot/Attributes/OwnerOnlyAttribute.cs +++ b/src/NadekoBot/Attributes/OwnerOnlyAttribute.cs @@ -1,12 +1,11 @@ using System.Threading.Tasks; using Discord.Commands; -using Discord; namespace NadekoBot.Attributes { public class OwnerOnlyAttribute : PreconditionAttribute { - public override Task CheckPermissions(IUserMessage context, Command executingCommand, object moduleInstance) => - Task.FromResult((NadekoBot.Credentials.IsOwner(context.Author) ? PreconditionResult.FromSuccess() : PreconditionResult.FromError("Not owner"))); + public override Task CheckPermissions(ICommandContext context, CommandInfo executingCommand,IDependencyMap depMap) => + Task.FromResult((NadekoBot.Credentials.IsOwner(context.User) ? PreconditionResult.FromSuccess() : PreconditionResult.FromError("Not owner"))); } } \ No newline at end of file diff --git a/src/NadekoBot/Migrations/20161122100602_Greet and bye improved.cs b/src/NadekoBot/Migrations/20161122100602_Greet and bye improved.cs index 8dabc472..8d3d5644 100644 --- a/src/NadekoBot/Migrations/20161122100602_Greet and bye improved.cs +++ b/src/NadekoBot/Migrations/20161122100602_Greet and bye improved.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Migrations; namespace NadekoBot.Migrations { diff --git a/src/NadekoBot/Migrations/20161127233843_PokeGame.cs b/src/NadekoBot/Migrations/20161127233843_PokeGame.cs index 1b1a2ab0..81f6f789 100644 --- a/src/NadekoBot/Migrations/20161127233843_PokeGame.cs +++ b/src/NadekoBot/Migrations/20161127233843_PokeGame.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Migrations; namespace NadekoBot.Migrations { diff --git a/src/NadekoBot/Migrations/20161213025624_mutedusers.cs b/src/NadekoBot/Migrations/20161213025624_mutedusers.cs index ec97cac5..8ac7dfa9 100644 --- a/src/NadekoBot/Migrations/20161213025624_mutedusers.cs +++ b/src/NadekoBot/Migrations/20161213025624_mutedusers.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Migrations; namespace NadekoBot.Migrations { diff --git a/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs b/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs index 022480a4..c9b359e1 100644 --- a/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs +++ b/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs @@ -2,10 +2,7 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Migrations; using NadekoBot.Services.Database; -using NadekoBot.Services.Database.Models; -using NadekoBot.Modules.Music.Classes; namespace NadekoBot.Migrations { diff --git a/src/NadekoBot/Modules/Administration/Administration.cs b/src/NadekoBot/Modules/Administration/Administration.cs index c75525bf..91c952a6 100644 --- a/src/NadekoBot/Modules/Administration/Administration.cs +++ b/src/NadekoBot/Modules/Administration/Administration.cs @@ -16,8 +16,6 @@ using System.IO; using static NadekoBot.Modules.Permissions.Permissions; using System.Collections.Concurrent; using NLog; -using NadekoBot.Services.Database; -using Microsoft.EntityFrameworkCore; namespace NadekoBot.Modules.Administration { @@ -27,34 +25,27 @@ namespace NadekoBot.Modules.Administration private static ConcurrentDictionary GuildMuteRoles { get; } = new ConcurrentDictionary(); - private new static Logger _log { get; } + private static ConcurrentHashSet DeleteMessagesOnCommand { get; } = new ConcurrentHashSet(); - public Administration() : base() - { - } + private new static Logger _log { get; } static Administration() { _log = LogManager.GetCurrentClassLogger(); NadekoBot.CommandHandler.CommandExecuted += DelMsgOnCmd_Handler; + + DeleteMessagesOnCommand = new ConcurrentHashSet(NadekoBot.AllGuildConfigs.Where(g => g.DeleteMessageOnCommand).Select(g => g.GuildId)); + } - private static async Task DelMsgOnCmd_Handler(IUserMessage msg, Command cmd) + private static async Task DelMsgOnCmd_Handler(SocketUserMessage msg, CommandInfo cmd) { try { - var channel = msg.Channel as ITextChannel; + var channel = msg.Channel as SocketTextChannel; if (channel == null) return; - - //todo cache this - bool shouldDelete; - using (var uow = DbHandler.UnitOfWork()) - { - shouldDelete = uow.GuildConfigs.For(channel.Guild.Id, set => set).DeleteMessageOnCommand; - } - - if (shouldDelete) + if (DeleteMessagesOnCommand.Contains(channel.Guild.Id)) await msg.DeleteAsync().ConfigureAwait(false); } catch (Exception ex) @@ -65,14 +56,13 @@ namespace NadekoBot.Modules.Administration [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.Administrator)] - public async Task ResetPermissions(IUserMessage imsg) + [RequireUserPermission(GuildPermission.Administrator)] + public async Task ResetPermissions() { - var channel = (ITextChannel)imsg.Channel; - + var channel = (ITextChannel)Context.Channel; using (var uow = DbHandler.UnitOfWork()) { - var config = uow.GuildConfigs.PermissionsFor(channel.Guild.Id); + var config = uow.GuildConfigs.PermissionsFor(Context.Guild.Id); config.RootPermission = Permission.GetDefaultRoot(); var toAdd = new PermissionCache() { @@ -85,143 +75,138 @@ namespace NadekoBot.Modules.Administration await uow.CompleteAsync(); } - await channel.SendConfirmAsync($"{imsg.Author.Mention} 🆗 **Permissions for this server are reset.**"); + await channel.SendConfirmAsync($"{Context.Message.Author.Mention} 🆗 **Permissions for this server are reset.**"); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.Administrator)] - public async Task Delmsgoncmd(IUserMessage umsg) + [RequireUserPermission(GuildPermission.Administrator)] + public async Task Delmsgoncmd() { - var channel = (ITextChannel)umsg.Channel; bool enabled; using (var uow = DbHandler.UnitOfWork()) { - var conf = uow.GuildConfigs.For(channel.Guild.Id, set => set); + var conf = uow.GuildConfigs.For(Context.Guild.Id, set => set); enabled = conf.DeleteMessageOnCommand = !conf.DeleteMessageOnCommand; await uow.CompleteAsync(); } if (enabled) - await channel.SendConfirmAsync("✅ **Now automatically deleting successful command invokations.**").ConfigureAwait(false); + { + DeleteMessagesOnCommand.Add(Context.Guild.Id); + await Context.Channel.SendConfirmAsync("✅ **Now automatically deleting successful command invokations.**").ConfigureAwait(false); + } else - await channel.SendConfirmAsync("❗**Stopped automatic deletion of successful command invokations.**").ConfigureAwait(false); + { + DeleteMessagesOnCommand.TryRemove(Context.Guild.Id); + await Context.Channel.SendConfirmAsync("❗**Stopped automatic deletion of successful command invokations.**").ConfigureAwait(false); + } } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageRoles)] - public async Task Setrole(IUserMessage umsg, IGuildUser usr, [Remainder] IRole role) + [RequireUserPermission(GuildPermission.ManageRoles)] + public async Task Setrole(IGuildUser usr, [Remainder] IRole role) { - var channel = (ITextChannel)umsg.Channel; try { await usr.AddRolesAsync(role).ConfigureAwait(false); - await channel.SendConfirmAsync($"ℹ️ Successfully added role **{role.Name}** to user **{usr.Username}**").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"ℹ️ Successfully added role **{role.Name}** to user **{usr.Username}**").ConfigureAwait(false); } catch (Exception ex) { - await channel.SendErrorAsync("⚠️ Failed to add role. **Bot has insufficient permissions.**\n").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("⚠️ Failed to add role. **Bot has insufficient permissions.**\n").ConfigureAwait(false); Console.WriteLine(ex.ToString()); } } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageRoles)] - public async Task Removerole(IUserMessage umsg, IGuildUser usr, [Remainder] IRole role) + [RequireUserPermission(GuildPermission.ManageRoles)] + public async Task Removerole(IGuildUser usr, [Remainder] IRole role) { - var channel = (ITextChannel)umsg.Channel; try { await usr.RemoveRolesAsync(role).ConfigureAwait(false); - await channel.SendConfirmAsync($"ℹ️ Successfully removed role **{role.Name}** from user **{usr.Username}**").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"ℹ️ Successfully removed role **{role.Name}** from user **{usr.Username}**").ConfigureAwait(false); } catch { - await channel.SendErrorAsync("⚠️ Failed to remove role. Most likely reason: **Insufficient permissions.**").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("⚠️ Failed to remove role. Most likely reason: **Insufficient permissions.**").ConfigureAwait(false); } } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageRoles)] - public async Task RenameRole(IUserMessage umsg, IRole roleToEdit, string newname) + [RequireUserPermission(GuildPermission.ManageRoles)] + public async Task RenameRole(IRole roleToEdit, string newname) { - var channel = (ITextChannel)umsg.Channel; try { - if (roleToEdit.Position > (await channel.Guild.GetCurrentUserAsync().ConfigureAwait(false)).Roles.Max(r => r.Position)) + if (roleToEdit.Position > (await Context.Guild.GetCurrentUserAsync().ConfigureAwait(false)).GetRoles().Max(r => r.Position)) { - await channel.SendErrorAsync("🚫 You can't edit roles higher than your highest role.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("🚫 You can't edit roles higher than your highest role.").ConfigureAwait(false); return; } await roleToEdit.ModifyAsync(g => g.Name = newname).ConfigureAwait(false); - await channel.SendConfirmAsync("✅ Role renamed.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("✅ Role renamed.").ConfigureAwait(false); } catch (Exception) { - await channel.SendErrorAsync("⚠️ Failed to rename role. Probably **insufficient permissions.**").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("⚠️ Failed to rename role. Probably **insufficient permissions.**").ConfigureAwait(false); } } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageRoles)] - public async Task RemoveAllRoles(IUserMessage umsg, [Remainder] IGuildUser user) + [RequireUserPermission(GuildPermission.ManageRoles)] + public async Task RemoveAllRoles([Remainder] IGuildUser user) { - var channel = (ITextChannel)umsg.Channel; - try { - await user.RemoveRolesAsync(user.Roles).ConfigureAwait(false); - await channel.SendConfirmAsync($"🗑 Successfully removed **all** roles from user **{user.Username}**").ConfigureAwait(false); + await user.RemoveRolesAsync(user.GetRoles()).ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"🗑 Successfully removed **all** roles from user **{user.Username}**").ConfigureAwait(false); } catch { - await channel.SendErrorAsync("⚠️ Failed to remove roles. Most likely reason: **Insufficient permissions.**").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("⚠️ Failed to remove roles. Most likely reason: **Insufficient permissions.**").ConfigureAwait(false); } } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageRoles)] - public async Task CreateRole(IUserMessage umsg, [Remainder] string roleName = null) + [RequireUserPermission(GuildPermission.ManageRoles)] + public async Task CreateRole([Remainder] string roleName = null) { - var channel = (ITextChannel)umsg.Channel; - - if (string.IsNullOrWhiteSpace(roleName)) return; try { - var r = await channel.Guild.CreateRoleAsync(roleName).ConfigureAwait(false); - await channel.SendConfirmAsync($"✅ Successfully created role **{r.Name}**.").ConfigureAwait(false); + var r = await Context.Guild.CreateRoleAsync(roleName).ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"✅ Successfully created role **{r.Name}**.").ConfigureAwait(false); } catch (Exception) { - await channel.SendErrorAsync("⚠️ Unspecified error.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("⚠️ Unspecified error.").ConfigureAwait(false); } } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageRoles)] - public async Task RoleColor(IUserMessage umsg, params string[] args) + [RequireUserPermission(GuildPermission.ManageRoles)] + public async Task RoleColor(params string[] args) { - var channel = (ITextChannel)umsg.Channel; - if (args.Count() != 2 && args.Count() != 4) { - await channel.SendErrorAsync("❌ The parameters specified are **invalid.**").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("❌ The parameters specified are **invalid.**").ConfigureAwait(false); return; } var roleName = args[0].ToUpperInvariant(); - var role = channel.Guild.Roles.Where(r => r.Name.ToUpperInvariant() == roleName).FirstOrDefault(); + var role = Context.Guild.Roles.Where(r=>r.Name.ToUpperInvariant() == roleName).FirstOrDefault(); if (role == null) { - await channel.SendErrorAsync("🚫 That role **does not exist.**").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("🚫 That role **does not exist.**").ConfigureAwait(false); return; } try @@ -232,110 +217,106 @@ namespace NadekoBot.Modules.Administration var red = Convert.ToByte(rgb ? int.Parse(arg1) : Convert.ToInt32(arg1.Substring(0, 2), 16)); var green = Convert.ToByte(rgb ? int.Parse(args[2]) : Convert.ToInt32(arg1.Substring(2, 2), 16)); var blue = Convert.ToByte(rgb ? int.Parse(args[3]) : Convert.ToInt32(arg1.Substring(4, 2), 16)); - - await role.ModifyAsync(r => r.Color = new Discord.Color(red, green, blue).RawValue).ConfigureAwait(false); - await channel.SendConfirmAsync($"☑️ Role **{role.Name}'s** color has been changed.").ConfigureAwait(false); + + await role.ModifyAsync(r => r.Color = new Color(red, green, blue)).ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"☑️ Role **{role.Name}'s** color has been changed.").ConfigureAwait(false); } catch (Exception) { - await channel.SendErrorAsync("⚠️ Error occured, most likely **invalid parameters** or **insufficient permissions.**").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("⚠️ Error occured, most likely **invalid parameters** or **insufficient permissions.**").ConfigureAwait(false); } } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.BanMembers)] - public async Task Ban(IUserMessage umsg, IGuildUser user, [Remainder] string msg = null) + [RequireUserPermission(GuildPermission.BanMembers)] + public async Task Ban(IGuildUser user, [Remainder] string msg = null) { - var channel = (ITextChannel)umsg.Channel; if (string.IsNullOrWhiteSpace(msg)) { msg = "❗️No reason provided."; } - if (umsg.Author.Id != user.Guild.OwnerId && user.Roles.Select(r => r.Position).Max() >= ((IGuildUser)umsg.Author).Roles.Select(r => r.Position).Max()) + if (Context.User.Id != user.Guild.OwnerId && ((IGuildUser)Context.User).GetRoles().Select(r=>r.Position).Max() >= ((IGuildUser)Context.User).GetRoles().Select(r => r.Position).Max()) { - await channel.SendErrorAsync("⚠️ You can't use this command on users with a role higher or equal to yours in the role hierarchy."); + await Context.Channel.SendErrorAsync("⚠️ You can't use this command on users with a role higher or equal to yours in the role hierarchy.").ConfigureAwait(false); return; } try { - await (await user.CreateDMChannelAsync()).SendErrorAsync($"⛔️ **You have been BANNED from `{channel.Guild.Name}` server.**\n" + + await (await user.CreateDMChannelAsync()).SendErrorAsync($"⛔️ **You have been BANNED from `{Context.Guild.Name}` server.**\n" + $"⚖ *Reason:* {msg}").ConfigureAwait(false); await Task.Delay(2000).ConfigureAwait(false); } catch { } try { - await channel.Guild.AddBanAsync(user, 7).ConfigureAwait(false); + await Context.Guild.AddBanAsync(user, 7).ConfigureAwait(false); - await channel.SendConfirmAsync("⛔️ **Banned** user **" + user.Username + "** ID: `" + user.Id + "`").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("⛔️ **Banned** user **" + user.Username + "** ID: `" + user.Id + "`").ConfigureAwait(false); } catch { - await channel.SendErrorAsync("⚠️ **Error.** Most likely I don't have sufficient permissions.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("⚠️ **Error.** Most likely I don't have sufficient permissions.").ConfigureAwait(false); } } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.KickMembers)] - [RequirePermission(GuildPermission.ManageMessages)] - public async Task Softban(IUserMessage umsg, IGuildUser user, [Remainder] string msg = null) + [RequireUserPermission(GuildPermission.KickMembers)] + [RequireUserPermission(GuildPermission.ManageMessages)] + public async Task Softban(IGuildUser user, [Remainder] string msg = null) { - var channel = (ITextChannel)umsg.Channel; if (string.IsNullOrWhiteSpace(msg)) { msg = "❗️No reason provided."; } - if (umsg.Author.Id != user.Guild.OwnerId && user.Roles.Select(r => r.Position).Max() >= ((IGuildUser)umsg.Author).Roles.Select(r => r.Position).Max()) + if (Context.User.Id != user.Guild.OwnerId && user.GetRoles().Select(r => r.Position).Max() >= ((IGuildUser)Context.User).GetRoles().Select(r => r.Position).Max()) { - await channel.SendErrorAsync("⚠️ You can't use this command on users with a role higher or equal to yours in the role hierarchy."); + await Context.Channel.SendErrorAsync("⚠️ You can't use this command on users with a role higher or equal to yours in the role hierarchy."); return; } try { - await user.SendErrorAsync($"☣ **You have been SOFT-BANNED from `{channel.Guild.Name}` server.**\n" + + await user.SendErrorAsync($"☣ **You have been SOFT-BANNED from `{Context.Guild.Name}` server.**\n" + $"⚖ *Reason:* {msg}").ConfigureAwait(false); await Task.Delay(2000).ConfigureAwait(false); } catch { } try { - await channel.Guild.AddBanAsync(user, 7).ConfigureAwait(false); - try { await channel.Guild.RemoveBanAsync(user).ConfigureAwait(false); } - catch { await channel.Guild.RemoveBanAsync(user).ConfigureAwait(false); } + await Context.Guild.AddBanAsync(user, 7).ConfigureAwait(false); + try { await Context.Guild.RemoveBanAsync(user).ConfigureAwait(false); } + catch { await Context.Guild.RemoveBanAsync(user).ConfigureAwait(false); } - await channel.SendConfirmAsync("☣ **Soft-Banned** user **" + user.Username + "** ID: `" + user.Id + "`").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("☣ **Soft-Banned** user **" + user.Username + "** ID: `" + user.Id + "`").ConfigureAwait(false); } catch { - await channel.SendErrorAsync("⚠️ Error. Most likely I don't have sufficient permissions.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("⚠️ Error. Most likely I don't have sufficient permissions.").ConfigureAwait(false); } } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.KickMembers)] - public async Task Kick(IUserMessage umsg, IGuildUser user, [Remainder] string msg = null) + [RequireUserPermission(GuildPermission.KickMembers)] + public async Task Kick(IGuildUser user, [Remainder] string msg = null) { - var channel = (ITextChannel)umsg.Channel; - if (user == null) { - await channel.SendErrorAsync("❗️User not found.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("❗️User not found.").ConfigureAwait(false); return; } - if (umsg.Author.Id != user.Guild.OwnerId && user.Roles.Select(r => r.Position).Max() >= ((IGuildUser)umsg.Author).Roles.Select(r => r.Position).Max()) + if (Context.Message.Author.Id != user.Guild.OwnerId && user.GetRoles().Select(r => r.Position).Max() >= ((IGuildUser)Context.User).GetRoles().Select(r => r.Position).Max()) { - await channel.SendErrorAsync("⚠️ You can't use this command on users with a role higher or equal to yours in the role hierarchy."); + await Context.Channel.SendErrorAsync("⚠️ You can't use this command on users with a role higher or equal to yours in the role hierarchy."); return; } if (!string.IsNullOrWhiteSpace(msg)) { try { - await user.SendErrorAsync($"‼️**You have been KICKED from `{channel.Guild.Name}` server.**\n" + + await user.SendErrorAsync($"‼️**You have been KICKED from `{Context.Guild.Name}` server.**\n" + $"⚖ *Reason:* {msg}").ConfigureAwait(false); await Task.Delay(2000).ConfigureAwait(false); } @@ -344,21 +325,19 @@ namespace NadekoBot.Modules.Administration try { await user.KickAsync().ConfigureAwait(false); - await channel.SendConfirmAsync("‼️**Kicked** user **" + user.Username + "** ID: `" + user.Id + "`").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("‼️**Kicked** user **" + user.Username + "** ID: `" + user.Id + "`").ConfigureAwait(false); } catch { - await channel.SendErrorAsync("⚠️ Error. Most likely I don't have sufficient permissions.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("⚠️ Error. Most likely I don't have sufficient permissions.").ConfigureAwait(false); } } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.DeafenMembers)] - public async Task Deafen(IUserMessage umsg, params IGuildUser[] users) + [RequireUserPermission(GuildPermission.DeafenMembers)] + public async Task Deafen(params IGuildUser[] users) { - var channel = (ITextChannel)umsg.Channel; - if (!users.Any()) return; try @@ -367,21 +346,19 @@ namespace NadekoBot.Modules.Administration { await u.ModifyAsync(usr => usr.Deaf = true).ConfigureAwait(false); } - await channel.SendConfirmAsync("🔇 **Deafen** successful.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("🔇 **Deafen** successful.").ConfigureAwait(false); } catch { - await channel.SendErrorAsync("⚠️ I most likely don't have the permission necessary for that.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("⚠️ I most likely don't have the permission necessary for that.").ConfigureAwait(false); } } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.DeafenMembers)] - public async Task UnDeafen(IUserMessage umsg, params IGuildUser[] users) + [RequireUserPermission(GuildPermission.DeafenMembers)] + public async Task UnDeafen(params IGuildUser[] users) { - var channel = (ITextChannel)umsg.Channel; - if (!users.Any()) return; try @@ -390,58 +367,56 @@ namespace NadekoBot.Modules.Administration { await u.ModifyAsync(usr => usr.Deaf = false).ConfigureAwait(false); } - await channel.SendConfirmAsync("🔊 **Undeafen** successful.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("🔊 **Undeafen** successful.").ConfigureAwait(false); } catch { - await channel.SendErrorAsync("⚠️ I most likely don't have the permission necessary for that.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("⚠️ I most likely don't have the permission necessary for that.").ConfigureAwait(false); } } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageChannels)] - public async Task DelVoiChanl(IUserMessage umsg, [Remainder] IVoiceChannel voiceChannel) + [RequireUserPermission(GuildPermission.ManageChannels)] + public async Task DelVoiChanl([Remainder] IVoiceChannel voiceChannel) { await voiceChannel.DeleteAsync().ConfigureAwait(false); - await umsg.Channel.SendConfirmAsync($"🗑 Removed voice channel **{voiceChannel.Name}** successfully.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"🗑 Removed voice channel **{voiceChannel.Name}** successfully.").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageChannels)] - public async Task CreatVoiChanl(IUserMessage umsg, [Remainder] string channelName) + [RequireUserPermission(GuildPermission.ManageChannels)] + public async Task CreatVoiChanl([Remainder] string channelName) { - var channel = (ITextChannel)umsg.Channel; - var ch = await channel.Guild.CreateVoiceChannelAsync(channelName).ConfigureAwait(false); - await channel.SendConfirmAsync($"✅ Created voice channel **{ch.Name}**. ID: `{ch.Id}`").ConfigureAwait(false); + var ch = await Context.Guild.CreateVoiceChannelAsync(channelName).ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"✅ Created voice channel **{ch.Name}**. ID: `{ch.Id}`").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageChannels)] - public async Task DelTxtChanl(IUserMessage umsg, [Remainder] ITextChannel toDelete) + [RequireUserPermission(GuildPermission.ManageChannels)] + public async Task DelTxtChanl([Remainder] ITextChannel toDelete) { await toDelete.DeleteAsync().ConfigureAwait(false); - await umsg.Channel.SendConfirmAsync($"🗑 Removed text channel **{toDelete.Name}**. ID: `{toDelete.Id}`").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"🗑 Removed text channel **{toDelete.Name}**. ID: `{toDelete.Id}`").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageChannels)] - public async Task CreaTxtChanl(IUserMessage umsg, [Remainder] string channelName) + [RequireUserPermission(GuildPermission.ManageChannels)] + public async Task CreaTxtChanl([Remainder] string channelName) { - var channel = (ITextChannel)umsg.Channel; - var txtCh = await channel.Guild.CreateTextChannelAsync(channelName).ConfigureAwait(false); - await channel.SendConfirmAsync($"✅ Added text channel **{txtCh.Name}**. ID: `{txtCh.Id}`").ConfigureAwait(false); + var txtCh = await Context.Guild.CreateTextChannelAsync(channelName).ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"✅ Added text channel **{txtCh.Name}**. ID: `{txtCh.Id}`").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageChannels)] - public async Task SetTopic(IUserMessage umsg, [Remainder] string topic = null) + [RequireUserPermission(GuildPermission.ManageChannels)] + public async Task SetTopic([Remainder] string topic = null) { - var channel = (ITextChannel)umsg.Channel; + var channel = (ITextChannel)Context.Channel; topic = topic ?? ""; await channel.ModifyAsync(c => c.Topic = topic); await channel.SendConfirmAsync("🆗 **New channel topic set.**").ConfigureAwait(false); @@ -449,11 +424,10 @@ namespace NadekoBot.Modules.Administration } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageChannels)] - public async Task SetChanlName(IUserMessage umsg, [Remainder] string name) + [RequireUserPermission(GuildPermission.ManageChannels)] + public async Task SetChanlName([Remainder] string name) { - var channel = (ITextChannel)umsg.Channel; - + var channel = (ITextChannel)Context.Channel; await channel.ModifyAsync(c => c.Name = name).ConfigureAwait(false); await channel.SendConfirmAsync("🆗 **New channel name set.**").ConfigureAwait(false); } @@ -462,183 +436,55 @@ namespace NadekoBot.Modules.Administration //delets her own messages, no perm required [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task Prune(IUserMessage umsg) + public async Task Prune() { - var channel = (ITextChannel)umsg.Channel; - - var user = channel.Guild.GetCurrentUser(); - - var enumerable = (await umsg.Channel.GetMessagesAsync()).AsEnumerable(); + var user = await Context.Guild.GetCurrentUserAsync().ConfigureAwait(false); + + var enumerable = (await Context.Channel.GetMessagesAsync().Flatten()).AsEnumerable(); enumerable = enumerable.Where(x => x.Author.Id == user.Id); - await umsg.Channel.DeleteMessagesAsync(enumerable).ConfigureAwait(false); + await Context.Channel.DeleteMessagesAsync(enumerable).ConfigureAwait(false); } // prune x [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(ChannelPermission.ManageMessages)] - public async Task Prune(IUserMessage msg, int count) + [RequireUserPermission(ChannelPermission.ManageMessages)] + public async Task Prune(int count) { - var channel = (ITextChannel)msg.Channel; - await (msg as IUserMessage).DeleteAsync(); + await Context.Message.DeleteAsync().ConfigureAwait(false); int limit = (count < 100) ? count : 100; - var enumerable = (await msg.Channel.GetMessagesAsync(limit: limit)); - await msg.Channel.DeleteMessagesAsync(enumerable).ConfigureAwait(false); + var enumerable = (await Context.Channel.GetMessagesAsync(limit: limit).Flatten().ConfigureAwait(false)); + await Context.Channel.DeleteMessagesAsync(enumerable).ConfigureAwait(false); } //prune @user [x] [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(ChannelPermission.ManageMessages)] - public async Task Prune(IUserMessage msg, IGuildUser user, int count = 100) + [RequireUserPermission(ChannelPermission.ManageMessages)] + public async Task Prune(IGuildUser user, int count = 100) { - var channel = (ITextChannel)msg.Channel; + int limit = (count < 100) ? count : 100; - var enumerable = (await msg.Channel.GetMessagesAsync(limit: limit)).Where(m => m.Author == user); - await msg.Channel.DeleteMessagesAsync(enumerable).ConfigureAwait(false); - } - - [NadekoCommand, Usage, Description, Aliases] - [OwnerOnly] - public async Task Die(IUserMessage umsg) - { - try { await umsg.Channel.SendConfirmAsync("ℹ️ **Shutting down.**").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); } - await Task.Delay(2000).ConfigureAwait(false); - Environment.Exit(0); - } - - [NadekoCommand, Usage, Description, Aliases] - [OwnerOnly] - public async Task SetName(IUserMessage umsg, [Remainder] string newName) - { - if (string.IsNullOrWhiteSpace(newName)) - return; - - await (await NadekoBot.Client.GetCurrentUserAsync()).ModifyAsync(u => u.Username = newName).ConfigureAwait(false); - - await umsg.Channel.SendConfirmAsync($"ℹ️ Successfully changed name to **{newName}**").ConfigureAwait(false); - } - - [NadekoCommand, Usage, Description, Aliases] - [OwnerOnly] - public async Task SetAvatar(IUserMessage umsg, [Remainder] string img = null) - { - if (string.IsNullOrWhiteSpace(img)) - return; - - using (var http = new HttpClient()) - { - using (var sr = await http.GetStreamAsync(img)) - { - var imgStream = new MemoryStream(); - await sr.CopyToAsync(imgStream); - imgStream.Position = 0; - - await (await NadekoBot.Client.GetCurrentUserAsync().ConfigureAwait(false)).ModifyAsync(u => u.Avatar = imgStream).ConfigureAwait(false); - } - } - - await umsg.Channel.SendConfirmAsync("🆒 **New avatar set.**").ConfigureAwait(false); - } - - [NadekoCommand, Usage, Description, Aliases] - [OwnerOnly] - public async Task SetGame(IUserMessage umsg, [Remainder] string game = null) - { - game = game ?? ""; - - await NadekoBot.Client.SetGame(game).ConfigureAwait(false); - - await umsg.Channel.SendConfirmAsync("👾 **New game set.**").ConfigureAwait(false); - } - - [NadekoCommand, Usage, Description, Aliases] - [OwnerOnly] - public async Task SetStream(IUserMessage umsg, string url, [Remainder] string name = null) - { - name = name ?? ""; - - await NadekoBot.Client.SetStream(name, url).ConfigureAwait(false); - - await umsg.Channel.SendConfirmAsync("ℹ️ **New stream set.**").ConfigureAwait(false); - } - - [NadekoCommand, Usage, Description, Aliases] - [OwnerOnly] - public async Task Send(IUserMessage umsg, string where, [Remainder] string msg = null) - { - if (string.IsNullOrWhiteSpace(msg)) - return; - - var ids = where.Split('|'); - if (ids.Length != 2) - return; - var sid = ulong.Parse(ids[0]); - var server = NadekoBot.Client.GetGuilds().Where(s => s.Id == sid).FirstOrDefault(); - - if (server == null) - return; - - if (ids[1].ToUpperInvariant().StartsWith("C:")) - { - var cid = ulong.Parse(ids[1].Substring(2)); - var ch = server.GetTextChannels().Where(c => c.Id == cid).FirstOrDefault(); - if (ch == null) - { - return; - } - await ch.SendMessageAsync(msg).ConfigureAwait(false); - } - else if (ids[1].ToUpperInvariant().StartsWith("U:")) - { - var uid = ulong.Parse(ids[1].Substring(2)); - var user = server.GetUsers().Where(u => u.Id == uid).FirstOrDefault(); - if (user == null) - { - return; - } - await user.SendMessageAsync(msg).ConfigureAwait(false); - } - else - { - await umsg.Channel.SendErrorAsync("⚠️ Invalid format.").ConfigureAwait(false); - } - } - - [NadekoCommand, Usage, Description, Aliases] - [OwnerOnly] - public async Task Announce(IUserMessage umsg, [Remainder] string message) - { - var channels = await Task.WhenAll(NadekoBot.Client.GetGuilds().Select(g => - g.GetDefaultChannelAsync() - )).ConfigureAwait(false); - - if (channels == null) - return; - await Task.WhenAll(channels.Where(c => c != null).Select(c => c.SendConfirmAsync($"🆕 Message from {umsg.Author} `[Bot Owner]`:", message))) - .ConfigureAwait(false); - - await umsg.Channel.SendConfirmAsync("🆗").ConfigureAwait(false); + var enumerable = (await Context.Channel.GetMessagesAsync(limit: limit).Flatten()).Where(m => m.Author == user); + await Context.Channel.DeleteMessagesAsync(enumerable).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] [OwnerOnly] - public async Task SaveChat(IUserMessage umsg, int cnt) + public async Task SaveChat(int cnt) { - var channel = (ITextChannel)umsg.Channel; - ulong? lastmsgId = null; var sb = new StringBuilder(); var msgs = new List(cnt); while (cnt > 0) { var dlcnt = cnt < 100 ? cnt : 100; - IReadOnlyCollection dledMsgs; + IEnumerable dledMsgs; if (lastmsgId == null) - dledMsgs = await umsg.Channel.GetMessagesAsync(cnt).ConfigureAwait(false); + dledMsgs = await Context.Channel.GetMessagesAsync(cnt).Flatten().ConfigureAwait(false); else - dledMsgs = await umsg.Channel.GetMessagesAsync(lastmsgId.Value, Direction.Before, dlcnt); + dledMsgs = await Context.Channel.GetMessagesAsync(lastmsgId.Value, Direction.Before, dlcnt).Flatten().ConfigureAwait(false); if (!dledMsgs.Any()) break; @@ -647,43 +493,41 @@ namespace NadekoBot.Modules.Administration lastmsgId = msgs[msgs.Count - 1].Id; cnt -= 100; } - var title = $"Chatlog-{channel.Guild.Name}/#{channel.Name}-{DateTime.Now}.txt"; + var title = $"Chatlog-{Context.Guild.Name}/#{Context.Channel.Name}-{DateTime.Now}.txt"; var grouping = msgs.GroupBy(x => $"{x.CreatedAt.Date:dd.MM.yyyy}") - .Select(g => new { date = g.Key, messages = g.OrderBy(x=>x.CreatedAt).Select(s => $"【{s.Timestamp:HH:mm:ss}】{s.Author}:" + s.ToString()) }); - await (umsg.Author as IGuildUser).SendFileAsync( + .Select(g => new { date = g.Key, messages = g.OrderBy(x => x.CreatedAt).Select(s => $"【{s.Timestamp:HH:mm:ss}】{s.Author}:" + s.ToString()) }); + await (Context.User as IGuildUser).SendFileAsync( await JsonConvert.SerializeObject(grouping, Formatting.Indented).ToStream().ConfigureAwait(false), - title, title).ConfigureAwait(false); +title, title).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.MentionEveryone)] - public async Task MentionRole(IUserMessage umsg, params IRole[] roles) + [RequireUserPermission(GuildPermission.MentionEveryone)] + public async Task MentionRole(params IRole[] roles) { - var channel = (ITextChannel)umsg.Channel; - - string send = $"❕{umsg.Author.Mention} has invoked a mention on the following roles ❕"; + string send = $"❕{Context.User.Mention} has invoked a mention on the following roles ❕"; foreach (var role in roles) { send += $"\n**{role.Name}**\n"; - send += string.Join(", ", (await channel.Guild.GetUsersAsync()).Where(u => u.Roles.Contains(role)).Distinct().Select(u => u.Mention)); + send += string.Join(", ", (await Context.Guild.GetUsersAsync()).Where(u => u.GetRoles().Contains(role)).Distinct().Select(u=>u.Mention)); } while (send.Length > 2000) { var curstr = send.Substring(0, 2000); - await channel.SendMessageAsync(curstr.Substring(0, + await Context.Channel.SendMessageAsync(curstr.Substring(0, curstr.LastIndexOf(", ", StringComparison.Ordinal) + 1)).ConfigureAwait(false); send = curstr.Substring(curstr.LastIndexOf(", ", StringComparison.Ordinal) + 1) + send.Substring(2000); } - await channel.SendMessageAsync(send).ConfigureAwait(false); + await Context.Channel.SendMessageAsync(send).ConfigureAwait(false); } IGuild nadekoSupportServer; [NadekoCommand, Usage, Description, Aliases] - public async Task Donators(IUserMessage umsg) + public async Task Donators() { IEnumerable donatorsOrdered; @@ -691,8 +535,8 @@ namespace NadekoBot.Modules.Administration { donatorsOrdered = uow.Donators.GetDonatorsOrdered(); } - await umsg.Channel.SendConfirmAsync("Thanks to the people listed below for making this project happen!", string.Join("⭐", donatorsOrdered.Select(d => d.Name))).ConfigureAwait(false); - + await Context.Channel.SendConfirmAsync("Thanks to the people listed below for making this project happen!", string.Join("⭐", donatorsOrdered.Select(d => d.Name))).ConfigureAwait(false); + nadekoSupportServer = nadekoSupportServer ?? NadekoBot.Client.GetGuild(117523346618318850); if (nadekoSupportServer == null) @@ -702,14 +546,14 @@ namespace NadekoBot.Modules.Administration if (patreonRole == null) return; - var usrs = nadekoSupportServer.GetUsers().Where(u => u.Roles.Contains(patreonRole)); - await umsg.Channel.SendConfirmAsync("Patreon supporters", string.Join("⭐", usrs.Select(d => d.Username))).ConfigureAwait(false); + var usrs = (await nadekoSupportServer.GetUsersAsync()).Where(u => u.RoleIds.Contains(236667642088259585u)); + await Context.Channel.SendConfirmAsync("Patreon supporters", string.Join("⭐", usrs.Select(d => d.Username))).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [OwnerOnly] - public async Task Donadd(IUserMessage umsg, IUser donator, int amount) + public async Task Donadd(IUser donator, int amount) { Donator don; using (var uow = DbHandler.UnitOfWork()) @@ -718,7 +562,7 @@ namespace NadekoBot.Modules.Administration await uow.CompleteAsync(); } - await umsg.Channel.SendConfirmAsync($"Successfuly added a new donator. Total donated amount from this user: {don.Amount} 👑").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"Successfuly added a new donator. Total donated amount from this user: {don.Amount} 👑").ConfigureAwait(false); } } } \ No newline at end of file diff --git a/src/NadekoBot/Modules/Administration/Commands/AntiRaidCommands.cs b/src/NadekoBot/Modules/Administration/Commands/AntiRaidCommands.cs index 8a6e8200..4551ef48 100644 --- a/src/NadekoBot/Modules/Administration/Commands/AntiRaidCommands.cs +++ b/src/NadekoBot/Modules/Administration/Commands/AntiRaidCommands.cs @@ -67,7 +67,7 @@ namespace NadekoBot.Modules.Administration } [Group] - public class AntiRaidCommands + public class AntiRaidCommands : ModuleBase { private static ConcurrentDictionary antiRaidGuilds = new ConcurrentDictionary(); @@ -152,7 +152,7 @@ namespace NadekoBot.Modules.Administration case PunishmentAction.Mute: try { - await MuteCommands.Mute(gu).ConfigureAwait(false); + await MuteCommands.MuteUser(gu).ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex, "I can't apply punishement"); } break; @@ -190,30 +190,28 @@ namespace NadekoBot.Modules.Administration [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.Administrator)] - public async Task AntiRaid(IUserMessage imsg, int userThreshold, int seconds, PunishmentAction action) + [RequireUserPermission(GuildPermission.Administrator)] + public async Task AntiRaid(int userThreshold, int seconds, PunishmentAction action) { - var channel = (ITextChannel)imsg.Channel; - if (userThreshold < 2 || userThreshold > 30) { - await channel.SendErrorAsync("❗️User threshold must be between **2** and **30**.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("❗️User threshold must be between **2** and **30**.").ConfigureAwait(false); return; } if (seconds < 2 || seconds > 300) { - await channel.SendErrorAsync("❗️Time must be between **2** and **300** seconds.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("❗️Time must be between **2** and **300** seconds.").ConfigureAwait(false); return; } try { - await MuteCommands.GetMuteRole(channel.Guild).ConfigureAwait(false); + await MuteCommands.GetMuteRole(Context.Guild).ConfigureAwait(false); } catch (Exception ex) { - await channel.SendConfirmAsync("⚠️ Failed creating a mute role. Give me ManageRoles permission" + + await Context.Channel.SendConfirmAsync("⚠️ Failed creating a mute role. Give me ManageRoles permission" + "or create 'nadeko-mute' role with disabled SendMessages and try again.") .ConfigureAwait(false); _log.Warn(ex); @@ -226,48 +224,46 @@ namespace NadekoBot.Modules.Administration Seconds = seconds, UserThreshold = userThreshold, }; - antiRaidGuilds.AddOrUpdate(channel.Guild.Id, setting, (id, old) => setting); + antiRaidGuilds.AddOrUpdate(Context.Guild.Id, setting, (id, old) => setting); - await channel.SendConfirmAsync($"ℹ️ {imsg.Author.Mention} If **{userThreshold}** or more users join within **{seconds}** seconds, I will **{action}** them.") + await Context.Channel.SendConfirmAsync($"ℹ️ {Context.User.Mention} If **{userThreshold}** or more users join within **{seconds}** seconds, I will **{action}** them.") .ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.Administrator)] - public async Task AntiSpam(IUserMessage imsg, int messageCount = 3, PunishmentAction action = PunishmentAction.Mute) + [RequireUserPermission(GuildPermission.Administrator)] + public async Task AntiSpam(int messageCount=3, PunishmentAction action = PunishmentAction.Mute) { - var channel = (ITextChannel)imsg.Channel; - if (messageCount < 2 || messageCount > 10) return; AntiSpamSetting throwaway; - if (antiSpamGuilds.TryRemove(channel.Guild.Id, out throwaway)) + if (antiSpamGuilds.TryRemove(Context.Guild.Id, out throwaway)) { - await channel.SendConfirmAsync("🆗 **Anti-Spam feature** has been **disabled** on this server.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("🆗 **Anti-Spam feature** has been **disabled** on this server.").ConfigureAwait(false); } else { try { - await MuteCommands.GetMuteRole(channel.Guild).ConfigureAwait(false); + await MuteCommands.GetMuteRole(Context.Guild).ConfigureAwait(false); } catch (Exception ex) { - await channel.SendErrorAsync("⚠️ Failed creating a mute role. Give me ManageRoles permission" + + await Context.Channel.SendErrorAsync("⚠️ Failed creating a mute role. Give me ManageRoles permission" + "or create 'nadeko-mute' role with disabled SendMessages and try again.") .ConfigureAwait(false); _log.Warn(ex); return; } - if (antiSpamGuilds.TryAdd(channel.Guild.Id, new AntiSpamSetting() + if (antiSpamGuilds.TryAdd(Context.Guild.Id, new AntiSpamSetting() { Action = action, MessageThreshold = messageCount, })) - await channel.SendConfirmAsync("✅ **Anti-Spam feature** has been **enabled** on this server.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("✅ **Anti-Spam feature** has been **enabled** on this server.").ConfigureAwait(false); } } diff --git a/src/NadekoBot/Modules/Administration/Commands/AutoAssignRoleCommands.cs b/src/NadekoBot/Modules/Administration/Commands/AutoAssignRoleCommands.cs index da6fc766..e3cb8380 100644 --- a/src/NadekoBot/Modules/Administration/Commands/AutoAssignRoleCommands.cs +++ b/src/NadekoBot/Modules/Administration/Commands/AutoAssignRoleCommands.cs @@ -16,7 +16,7 @@ namespace NadekoBot.Modules.Administration public partial class Administration { [Group] - public class AutoAssignRoleCommands + public class AutoAssignRoleCommands : ModuleBase { private static Logger _log { get; } //guildid/roleid @@ -53,25 +53,23 @@ namespace NadekoBot.Modules.Administration [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageRoles)] - public async Task AutoAssignRole(IUserMessage umsg, [Remainder] IRole role = null) + [RequireUserPermission(GuildPermission.ManageRoles)] + public async Task AutoAssignRole([Remainder] IRole role = null) { - var channel = (ITextChannel)umsg.Channel; - GuildConfig conf; using (var uow = DbHandler.UnitOfWork()) { - conf = uow.GuildConfigs.For(channel.Guild.Id, set => set); + conf = uow.GuildConfigs.For(Context.Guild.Id, set => set); if (role == null) { conf.AutoAssignRoleId = 0; ulong throwaway; - AutoAssignedRoles.TryRemove(channel.Guild.Id, out throwaway); + AutoAssignedRoles.TryRemove(Context.Guild.Id, out throwaway); } else { conf.AutoAssignRoleId = role.Id; - AutoAssignedRoles.AddOrUpdate(channel.Guild.Id, role.Id, (key, val) => role.Id); + AutoAssignedRoles.AddOrUpdate(Context.Guild.Id, role.Id, (key, val) => role.Id); } await uow.CompleteAsync().ConfigureAwait(false); @@ -79,11 +77,11 @@ namespace NadekoBot.Modules.Administration if (role == null) { - await channel.SendConfirmAsync("🆗 **Auto assign role** on user join is now **disabled**.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("🆗 **Auto assign role** on user join is now **disabled**.").ConfigureAwait(false); return; } - await channel.SendConfirmAsync("✅ **Auto assign role** on user join is now **enabled**.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("✅ **Auto assign role** on user join is now **enabled**.").ConfigureAwait(false); } } } diff --git a/src/NadekoBot/Modules/Administration/Commands/CrossServerTextChannel.cs b/src/NadekoBot/Modules/Administration/Commands/CrossServerTextChannel.cs index 5c9a47d4..62af02da 100644 --- a/src/NadekoBot/Modules/Administration/Commands/CrossServerTextChannel.cs +++ b/src/NadekoBot/Modules/Administration/Commands/CrossServerTextChannel.cs @@ -14,7 +14,7 @@ namespace NadekoBot.Modules.Administration public partial class Administration { [Group] - public class CrossServerTextChannel + public class CrossServerTextChannel : ModuleBase { static CrossServerTextChannel() { @@ -31,11 +31,11 @@ namespace NadekoBot.Modules.Administration var channel = imsg.Channel as ITextChannel; if (channel == null) return; - if (msg.Author.Id == NadekoBot.Client.GetCurrentUser().Id) return; + if (msg.Author.Id == NadekoBot.Client.CurrentUser().Id) return; foreach (var subscriber in Subscribers) { var set = subscriber.Value; - if (!set.Contains(msg.Channel)) + if (!set.Contains(channel)) continue; foreach (var chan in set.Except(new[] { channel })) { @@ -58,44 +58,39 @@ namespace NadekoBot.Modules.Administration [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] [OwnerOnly] - public async Task Scsc(IUserMessage msg) + public async Task Scsc() { - var channel = (ITextChannel)msg.Channel; var token = new NadekoRandom().Next(); var set = new ConcurrentHashSet(); if (Subscribers.TryAdd(token, set)) { - set.Add(channel); - await ((IGuildUser)msg.Author).SendConfirmAsync("This is your CSC token", token.ToString()).ConfigureAwait(false); + set.Add((ITextChannel)Context.Channel); + await ((IGuildUser)Context.User).SendConfirmAsync("This is your CSC token", token.ToString()).ConfigureAwait(false); } } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageGuild)] - public async Task Jcsc(IUserMessage imsg, int token) + [RequireUserPermission(GuildPermission.ManageGuild)] + public async Task Jcsc(int token) { - var channel = (ITextChannel)imsg.Channel; - ConcurrentHashSet set; if (!Subscribers.TryGetValue(token, out set)) return; - set.Add(channel); - await channel.SendConfirmAsync("Joined cross server channel.").ConfigureAwait(false); + set.Add((ITextChannel)Context.Channel); + await Context.Channel.SendConfirmAsync("Joined cross server channel.").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageGuild)] - public async Task Lcsc(IUserMessage imsg) + [RequireUserPermission(GuildPermission.ManageGuild)] + public async Task Lcsc() { - var channel = (ITextChannel)imsg.Channel; - foreach (var subscriber in Subscribers) { - subscriber.Value.TryRemove(channel); + subscriber.Value.TryRemove((ITextChannel)Context.Channel); } - await channel.SendMessageAsync("Left cross server channel.").ConfigureAwait(false); + await Context.Channel.SendMessageAsync("Left cross server channel.").ConfigureAwait(false); } } } diff --git a/src/NadekoBot/Modules/Administration/Commands/DMForwardCommands.cs b/src/NadekoBot/Modules/Administration/Commands/DMForwardCommands.cs index 5b7e927f..fd954a4b 100644 --- a/src/NadekoBot/Modules/Administration/Commands/DMForwardCommands.cs +++ b/src/NadekoBot/Modules/Administration/Commands/DMForwardCommands.cs @@ -1,5 +1,6 @@ using Discord; using Discord.Commands; +using Discord.WebSocket; using NadekoBot.Attributes; using NadekoBot.Extensions; using NadekoBot.Services; @@ -14,7 +15,7 @@ namespace NadekoBot.Modules.Administration public partial class Administration { [Group] - public class DMForwardCommands + public class DMForwardCommands : ModuleBase { private static bool ForwardDMs { get; set; } private static bool ForwardDMsToAllOwners { get; set; } @@ -35,10 +36,8 @@ namespace NadekoBot.Modules.Administration [NadekoCommand, Usage, Description, Aliases] [OwnerOnly] - public async Task ForwardMessages(IUserMessage imsg) + public async Task ForwardMessages() { - var channel = imsg.Channel; - using (var uow = DbHandler.UnitOfWork()) { var config = uow.BotConfig.GetOrCreate(); @@ -46,17 +45,15 @@ namespace NadekoBot.Modules.Administration uow.Complete(); } if (ForwardDMs) - await channel.SendConfirmAsync("✅ **I will forward DMs from now on.**").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("✅ **I will forward DMs from now on.**").ConfigureAwait(false); else - await channel.SendConfirmAsync("🆗 **I will stop forwarding DMs from now on.**").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("🆗 **I will stop forwarding DMs from now on.**").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [OwnerOnly] - public async Task ForwardToAll(IUserMessage imsg) + public async Task ForwardToAll() { - var channel = imsg.Channel; - using (var uow = DbHandler.UnitOfWork()) { var config = uow.BotConfig.GetOrCreate(); @@ -64,13 +61,13 @@ namespace NadekoBot.Modules.Administration uow.Complete(); } if (ForwardDMsToAllOwners) - await channel.SendConfirmAsync("ℹ️ **I will forward DMs to all owners.**").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("ℹ️ **I will forward DMs to all owners.**").ConfigureAwait(false); else - await channel.SendConfirmAsync("ℹ️ **I will forward DMs only to the first owner.**").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("ℹ️ **I will forward DMs only to the first owner.**").ConfigureAwait(false); } - public static async Task HandleDMForwarding(IMessage msg, List ownerChannels) + public static async Task HandleDMForwarding(SocketMessage msg, List ownerChannels) { if (ForwardDMs && ownerChannels.Any()) { diff --git a/src/NadekoBot/Modules/Administration/Commands/LogCommand.cs b/src/NadekoBot/Modules/Administration/Commands/LogCommand.cs index 481f2f6e..04bde59b 100644 --- a/src/NadekoBot/Modules/Administration/Commands/LogCommand.cs +++ b/src/NadekoBot/Modules/Administration/Commands/LogCommand.cs @@ -21,7 +21,7 @@ namespace NadekoBot.Modules.Administration public partial class Administration { [Group] - public class LogCommands + public class LogCommands : ModuleBase { private static ShardedDiscordClient _client { get; } private static Logger _log { get; } @@ -67,10 +67,7 @@ namespace NadekoBot.Modules.Administration sw.Stop(); _log.Debug($"Loaded in {sw.Elapsed.TotalSeconds:F2}s"); - } - public LogCommands() - { //_client.MessageReceived += _client_MessageReceived; _client.MessageUpdated += _client_MessageUpdated; _client.MessageDeleted += _client_MessageDeleted; @@ -91,7 +88,7 @@ namespace NadekoBot.Modules.Administration MuteCommands.UserUnmuted += MuteCommands_UserUnmuted; } - private async void _client_UserVoiceStateUpdated_TTS(IUser iusr, IVoiceState before, IVoiceState after) + private static async void _client_UserVoiceStateUpdated_TTS(SocketUser iusr, SocketVoiceState before, SocketVoiceState after) { try { @@ -111,7 +108,7 @@ namespace NadekoBot.Modules.Administration return; ITextChannel logChannel; - if ((logChannel = TryGetLogChannel(usr.Guild, logSetting, LogType.VoicePresenceTTS)) == null) + if ((logChannel = await TryGetLogChannel(usr.Guild, logSetting, LogType.VoicePresenceTTS)) == null) return; string str = null; @@ -133,7 +130,7 @@ namespace NadekoBot.Modules.Administration catch { } } - private async void MuteCommands_UserMuted(IGuildUser usr, MuteCommands.MuteType muteType) + private static async void MuteCommands_UserMuted(IGuildUser usr, MuteCommands.MuteType muteType) { try { @@ -143,7 +140,7 @@ namespace NadekoBot.Modules.Administration return; ITextChannel logChannel; - if ((logChannel = TryGetLogChannel(usr.Guild, logSetting, LogType.UserMuted)) == null) + if ((logChannel = await TryGetLogChannel(usr.Guild, logSetting, LogType.UserMuted)) == null) return; string mutes = ""; switch (muteType) @@ -163,7 +160,7 @@ namespace NadekoBot.Modules.Administration catch (Exception ex) { _log.Warn(ex); } } - private async void MuteCommands_UserUnmuted(IGuildUser usr, MuteCommands.MuteType muteType) + private static async void MuteCommands_UserUnmuted(IGuildUser usr, MuteCommands.MuteType muteType) { try { @@ -173,7 +170,7 @@ namespace NadekoBot.Modules.Administration return; ITextChannel logChannel; - if ((logChannel = TryGetLogChannel(usr.Guild, logSetting, LogType.UserMuted)) == null) + if ((logChannel = await TryGetLogChannel(usr.Guild, logSetting, LogType.UserMuted)) == null) return; string mutes = ""; @@ -206,7 +203,7 @@ namespace NadekoBot.Modules.Administration || (logSetting.LogOtherId == null)) return; ITextChannel logChannel; - if ((logChannel = TryGetLogChannel(users.First().Guild, logSetting, LogType.Other)) == null) + if ((logChannel = await TryGetLogChannel(users.First().Guild, logSetting, LogType.Other)) == null) return; var punishment = ""; @@ -226,47 +223,49 @@ namespace NadekoBot.Modules.Administration //punishment = "BANNED"; } await logChannel.SendMessageAsync(String.Join("\n", users.Select(user => $"‼️ {Format.Bold(user.ToString())} got **{punishment}** due to __**{protection}**__ protection on **{user.Guild.Name}** server."))) - //await logChannel.SendMessageAsync(String.Join("\n",users.Select(user=>$"{Format.Bold(user.ToString())} was **{punishment}** due to `{protection}` protection on **{user.Guild.Name}** server."))) .ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); } } - private async void _client_UserUpdated(IGuildUser before, IGuildUser after) + private static async void _client_UserUpdated(SocketUser uBefore, SocketUser uAfter) { try { + var before = uBefore as SocketGuildUser; + if (before == null) + return; + var after = uAfter as SocketGuildUser; + if (after == null) + return; + LogSetting logSetting; if (!GuildLogSettings.TryGetValue(before.Guild.Id, out logSetting) || (logSetting.UserUpdatedId == null)) return; ITextChannel logChannel; - if ((logChannel = TryGetLogChannel(before.Guild, logSetting, LogType.UserUpdated)) == null) + if ((logChannel = await TryGetLogChannel(before.Guild, logSetting, LogType.UserUpdated)) == null) return; string str = $"🕔`{prettyCurrentTime}`"; + if (before.Username != after.Username) - //str += $"**Name Changed**`{before.Username}#{before.Discriminator}`\n\t\t`New:`{after.ToString()}`"; str += $"👤__**{before.Username}#{before.Discriminator}**__ **| Name Changed |** 🆔 `{before.Id}`\n\t\t`New:` **{after.ToString()}**"; else if (before.Nickname != after.Nickname) str += $"👤__**{before.Username}#{before.Discriminator}**__ **| Nickname Changed |** 🆔 `{before.Id}`\n\t\t`Old:` **{before.Nickname}#{before.Discriminator}**\n\t\t`New:` **{after.Nickname}#{after.Discriminator}**"; - //str += $"**Nickname Changed**`{before.Username}#{before.Discriminator}`\n\t\t`Old:` {before.Nickname}#{before.Discriminator}\n\t\t`New:` {after.Nickname}#{after.Discriminator}"; else if (before.AvatarUrl != after.AvatarUrl) - //str += $"**Avatar Changed**👤`{before.Username}#{before.Discriminator}`\n\t {await _google.ShortenUrl(before.AvatarUrl)} `=>` {await _google.ShortenUrl(after.AvatarUrl)}"; - str += $"👤__**{before.Username}#{before.Discriminator}**__ **| Avatar Changed |** 🆔 `{before.Id}`\n\t🖼 {await _google.ShortenUrl(before.AvatarUrl)} `=>` {await _google.ShortenUrl(after.AvatarUrl)}"; - else if (!before.Roles.SequenceEqual(after.Roles)) + str += $"👤__**{before.Username}#{before.Discriminator}**__ **| Avatar Changed |** 🆔 `{before.Id}`\n\t🖼 {await NadekoBot.Google.ShortenUrl(before.AvatarUrl)} `=>` {await NadekoBot.Google.ShortenUrl(after.AvatarUrl)}"; + else if (!before.RoleIds.SequenceEqual(after.RoleIds)) { - if (before.Roles.Count() < after.Roles.Count()) + if (before.RoleIds.Count < after.RoleIds.Count) { - var diffRoles = after.Roles.Where(r => !before.Roles.Contains(r)).Select(r => "**" + r.Name + "**"); - //str += $"**User's Roles changed ⚔➕**👤`{before.ToString()}`\n\tNow has {string.Join(", ", diffRoles)} role."; - str += $"👤__**{before.ToString()}**__ **| User's Role Added |** 🆔 `{before.Id}`\n\t✅ {string.Join(", ", diffRoles).SanitizeMentions()}\n\t\t⚔ **`{string.Join(", ", after.Roles.Select(r => r.Name)).SanitizeMentions()}`** ⚔"; + var diffRoles = after.RoleIds.Where(r => !before.RoleIds.Contains(r)).Select(r => "**" + before.Guild.GetRole(r).Name + "**"); + str += $"👤__**{before.ToString()}**__ **| User's Role Added |** 🆔 `{before.Id}`\n\t✅ {string.Join(", ", diffRoles).SanitizeMentions()}\n\t\t⚔ **`{string.Join(", ", after.GetRoles().Select(r => r.Name)).SanitizeMentions()}`** ⚔"; } - else if (before.Roles.Count() > after.Roles.Count()) + else if (before.RoleIds.Count > after.RoleIds.Count) { - var diffRoles = before.Roles.Where(r => !after.Roles.Contains(r)).Select(r => "**" + r.Name + "**"); - //str += $"**User's Roles changed **`{before.ToString()}`\n\tNo longer has {string.Join(", ", diffRoles)} role."; - str += $"👤__**{before.ToString()}**__ **| User's Role Removed |** 🆔 `{before.Id}`\n\t🚮 {string.Join(", ", diffRoles).SanitizeMentions()}\n\t\t⚔ **`{string.Join(", ", after.Roles.Select(r => r.Name)).SanitizeMentions()}`** ⚔"; + var diffRoles = before.RoleIds.Where(r => !after.RoleIds.Contains(r)).Select(r => "**" + before.Guild.GetRole(r).Name + "**"); + str += $"👤__**{before.ToString()}**__ **| User's Role Removed |** 🆔 `{before.Id}`\n\t🚮 {string.Join(", ", diffRoles).SanitizeMentions()}\n\t\t⚔ **`{string.Join(", ", after.GetRoles().Select(r => r.Name)).SanitizeMentions()}`** ⚔"; } } else @@ -276,7 +275,7 @@ namespace NadekoBot.Modules.Administration catch (Exception ex) { _log.Warn(ex); } } - private async void _client_ChannelUpdated(IChannel cbefore, IChannel cafter) + private static async void _client_ChannelUpdated(IChannel cbefore, IChannel cafter) { try { @@ -292,15 +291,13 @@ namespace NadekoBot.Modules.Administration return; ITextChannel logChannel; - if ((logChannel = TryGetLogChannel(before.Guild, logSetting, LogType.ChannelUpdated)) == null) + if ((logChannel = await TryGetLogChannel(before.Guild, logSetting, LogType.ChannelUpdated)) == null) return; if (before.Name != after.Name) - //await logChannel.SendMessageAsync($@"`{prettyCurrentTime}` **Channel Name Changed** `#{after.Name}` ({after.Id}) await logChannel.SendMessageAsync($@"🕓`{prettyCurrentTime}`ℹ️ **| Channel Name Changed |** #⃣ `{after.Name} ({after.Id})` `Old:` {before.Name} **`New:`** {after.Name}").ConfigureAwait(false); else if ((before as ITextChannel).Topic != (after as ITextChannel).Topic) - //await logChannel.SendMessageAsync($@"`{prettyCurrentTime}` **Channel Topic Changed** `#{after.Name}` ({after.Id}) await logChannel.SendMessageAsync($@"🕘`{prettyCurrentTime}`ℹ️ **| Channel Topic Changed |** #⃣ `{after.Name} ({after.Id})` `Old:` {((ITextChannel)before).Topic} **`New:`** {((ITextChannel)after).Topic}").ConfigureAwait(false); @@ -308,7 +305,7 @@ namespace NadekoBot.Modules.Administration catch (Exception ex) { _log.Warn(ex); } } - private async void _client_ChannelDestroyed(IChannel ich) + private static async void _client_ChannelDestroyed(IChannel ich) { try { @@ -323,7 +320,7 @@ namespace NadekoBot.Modules.Administration return; ITextChannel logChannel; - if ((logChannel = TryGetLogChannel(ch.Guild, logSetting, LogType.ChannelDestroyed)) == null) + if ((logChannel = await TryGetLogChannel(ch.Guild, logSetting, LogType.ChannelDestroyed)) == null) return; await logChannel.SendMessageAsync($"🕕`{prettyCurrentTime}`🗑 **| {(ch is IVoiceChannel ? "Voice" : "Text")} Channel Deleted #⃣ {ch.Name}** `({ch.Id})`").ConfigureAwait(false); @@ -331,7 +328,7 @@ namespace NadekoBot.Modules.Administration catch (Exception ex) { _log.Warn(ex); } } - private async void _client_ChannelCreated(IChannel ich) + private static async void _client_ChannelCreated(IChannel ich) { try { @@ -345,7 +342,7 @@ namespace NadekoBot.Modules.Administration return; ITextChannel logChannel; - if ((logChannel = TryGetLogChannel(ch.Guild, logSetting, LogType.ChannelCreated)) == null) + if ((logChannel = await TryGetLogChannel(ch.Guild, logSetting, LogType.ChannelCreated)) == null) return; await logChannel.SendMessageAsync($"🕓`{prettyCurrentTime}`🆕 **| {(ch is IVoiceChannel ? "Voice" : "Text")} Channel Created: #⃣ {ch.Name}** `({ch.Id})`").ConfigureAwait(false); @@ -353,7 +350,7 @@ namespace NadekoBot.Modules.Administration catch (Exception ex) { _log.Warn(ex); } } - private async void _client_UserVoiceStateUpdated(IUser iusr, IVoiceState before, IVoiceState after) => await Task.Run(() => + private static async void _client_UserVoiceStateUpdated(SocketUser iusr, SocketVoiceState before, SocketVoiceState after) { try { @@ -373,7 +370,7 @@ namespace NadekoBot.Modules.Administration return; ITextChannel logChannel; - if ((logChannel = TryGetLogChannel(usr.Guild, logSetting, LogType.VoicePresence)) == null) + if ((logChannel = await TryGetLogChannel(usr.Guild, logSetting, LogType.VoicePresence)) == null) return; string str = null; @@ -396,20 +393,25 @@ namespace NadekoBot.Modules.Administration { _log.Warn(ex); } - }); + } - private async void _client_UserPresenceUpdated(IGuildUser usr, IPresence before, IPresence after) => await Task.Run(() => + private static async void _client_UserPresenceUpdated(Optional optGuild, SocketUser usr, SocketPresence before, SocketPresence after) { try { + var guild = optGuild.IsSpecified ? optGuild.Value : null; + + if (guild == null) + return; + LogSetting logSetting; - if (!GuildLogSettings.TryGetValue(usr.Guild.Id, out logSetting) + if (!GuildLogSettings.TryGetValue(guild.Id, out logSetting) || (logSetting.LogUserPresenceId == null) || before.Status == after.Status) return; ITextChannel logChannel; - if ((logChannel = TryGetLogChannel(usr.Guild, logSetting, LogType.UserPresence)) == null) + if ((logChannel = await TryGetLogChannel(guild, logSetting, LogType.UserPresence)) == null) return; string str; if (before.Status != after.Status) @@ -420,9 +422,9 @@ namespace NadekoBot.Modules.Administration UserPresenceUpdates.AddOrUpdate(logChannel, new List() { str }, (id, list) => { list.Add(str); return list; }); } catch { } - }); + } - private async void _client_UserLeft(IGuildUser usr) + private static async void _client_UserLeft(IGuildUser usr) { try { @@ -432,14 +434,14 @@ namespace NadekoBot.Modules.Administration return; ITextChannel logChannel; - if ((logChannel = TryGetLogChannel(usr.Guild, logSetting, LogType.UserLeft)) == null) + if ((logChannel = await TryGetLogChannel(usr.Guild, logSetting, LogType.UserLeft)) == null) return; await logChannel.SendMessageAsync($"❗️🕛`{prettyCurrentTime}`👤__**{usr.Username}#{usr.Discriminator}**__❌ **| USER LEFT |** 🆔 `{usr.Id}`").ConfigureAwait(false); } catch { } } - private async void _client_UserJoined(IGuildUser usr) + private static async void _client_UserJoined(IGuildUser usr) { try { @@ -449,7 +451,7 @@ namespace NadekoBot.Modules.Administration return; ITextChannel logChannel; - if ((logChannel = TryGetLogChannel(usr.Guild, logSetting, LogType.UserJoined)) == null) + if ((logChannel = await TryGetLogChannel(usr.Guild, logSetting, LogType.UserJoined)) == null) return; await logChannel.SendMessageAsync($"❕🕓`{prettyCurrentTime}`👤__**{usr.Username}#{usr.Discriminator}**__✅ **| USER JOINED |** 🆔 `{usr.Id}`").ConfigureAwait(false); @@ -457,7 +459,7 @@ namespace NadekoBot.Modules.Administration catch (Exception ex) { _log.Warn(ex); } } - private async void _client_UserUnbanned(IUser usr, IGuild guild) + private static async void _client_UserUnbanned(IUser usr, IGuild guild) { try { @@ -467,7 +469,7 @@ namespace NadekoBot.Modules.Administration return; ITextChannel logChannel; - if ((logChannel = TryGetLogChannel(guild, logSetting, LogType.UserUnbanned)) == null) + if ((logChannel = await TryGetLogChannel(guild, logSetting, LogType.UserUnbanned)) == null) return; await logChannel.SendMessageAsync($"❕🕘`{prettyCurrentTime}`👤__**{usr.Username}#{usr.Discriminator}**__♻️ **| USER UN-BANNED |** 🆔 `{usr.Id}`").ConfigureAwait(false); @@ -475,7 +477,7 @@ namespace NadekoBot.Modules.Administration catch (Exception ex) { _log.Warn(ex); } } - private async void _client_UserBanned(IUser usr, IGuild guild) + private static async void _client_UserBanned(IUser usr, IGuild guild) { try { @@ -485,14 +487,14 @@ namespace NadekoBot.Modules.Administration return; ITextChannel logChannel; - if ((logChannel = TryGetLogChannel(guild, logSetting, LogType.UserBanned)) == null) + if ((logChannel = await TryGetLogChannel(guild, logSetting, LogType.UserBanned)) == null) return; await logChannel.SendMessageAsync($"‼️🕕`{prettyCurrentTime}`👤__**{usr.Username}#{usr.Discriminator}**__🚫 **| USER BANNED |** 🆔 `{usr.Id}`").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); } } - private async void _client_MessageDeleted(ulong arg1, Optional imsg) + private static async void _client_MessageDeleted(ulong arg1, Optional imsg) { try @@ -512,10 +514,10 @@ namespace NadekoBot.Modules.Administration return; ITextChannel logChannel; - if ((logChannel = TryGetLogChannel(channel.Guild, logSetting, LogType.MessageDeleted)) == null || logChannel.Id == msg.Id) + if ((logChannel = await TryGetLogChannel(channel.Guild, logSetting, LogType.MessageDeleted)) == null || logChannel.Id == msg.Id) return; var str = $@"🕔`{prettyCurrentTime}`👤__**{msg.Author.Username}#{msg.Author.Discriminator}**__ **| Deleted Message |** 🆔 `{msg.Author.Id}` #⃣ `{channel.Name}` -🗑 {msg.Resolve(userHandling: UserMentionHandling.NameAndDiscriminator)}"; +🗑 {msg.Resolve(userHandling: TagHandling.FullName)}"; if (msg.Attachments.Any()) str += $"{Environment.NewLine}📎 {string.Join(", ", msg.Attachments.Select(a => a.ProxyUrl))}"; await logChannel.SendMessageAsync(str.SanitizeMentions()).ConfigureAwait(false); @@ -523,7 +525,7 @@ namespace NadekoBot.Modules.Administration catch (Exception ex) { _log.Warn(ex); } } - private async void _client_MessageUpdated(Optional optmsg, IMessage imsg2) + private static async void _client_MessageUpdated(Optional optmsg, SocketMessage imsg2) { try { @@ -549,11 +551,11 @@ namespace NadekoBot.Modules.Administration return; ITextChannel logChannel; - if ((logChannel = TryGetLogChannel(channel.Guild, logSetting, LogType.MessageUpdated)) == null || logChannel.Id == after.Channel.Id) + if ((logChannel = await TryGetLogChannel(channel.Guild, logSetting, LogType.MessageUpdated)) == null || logChannel.Id == after.Channel.Id) return; await logChannel.SendMessageAsync($@"🕔`{prettyCurrentTime}`👤__**{before.Author.Username}#{before.Author.Discriminator}**__ **| 📝 Edited Message |** 🆔 `{before.Author.Id}` #⃣ `{channel.Name}` - `Old:` {before.Resolve(userHandling: UserMentionHandling.NameAndDiscriminator).SanitizeMentions()} - **`New:`** {after.Resolve(userHandling: UserMentionHandling.NameAndDiscriminator).SanitizeMentions()}").ConfigureAwait(false); + `Old:` {before.Resolve(userHandling: TagHandling.FullName).SanitizeMentions()} + **`New:`** {after.Resolve(userHandling: TagHandling.FullName).SanitizeMentions()}").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); } } @@ -577,7 +579,7 @@ namespace NadekoBot.Modules.Administration UserMuted }; - private static ITextChannel TryGetLogChannel(IGuild guild, LogSetting logSetting, LogType logChannelType) + private static async Task TryGetLogChannel(IGuild guild, LogSetting logSetting, LogType logChannelType) { ulong? id = null; switch (logChannelType) @@ -636,7 +638,7 @@ namespace NadekoBot.Modules.Administration UnsetLogSetting(guild.Id, logChannelType); return null; } - var channel = guild.GetTextChannel(id.Value); + var channel = await guild.GetTextChannelAsync(id.Value).ConfigureAwait(false); if (channel == null) { @@ -715,11 +717,11 @@ namespace NadekoBot.Modules.Administration [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.Administrator)] + [RequireUserPermission(GuildPermission.Administrator)] [OwnerOnly] - public async Task LogServer(IUserMessage msg, PermissionAction action) + public async Task LogServer(PermissionAction action) { - var channel = (ITextChannel)msg.Channel; + var channel = (ITextChannel)Context.Channel; LogSetting logSetting; using (var uow = DbHandler.UnitOfWork()) { @@ -750,11 +752,11 @@ namespace NadekoBot.Modules.Administration [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.Administrator)] + [RequireUserPermission(GuildPermission.Administrator)] [OwnerOnly] - public async Task LogIgnore(IUserMessage imsg) + public async Task LogIgnore() { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)Context.Channel; int removed; using (var uow = DbHandler.UnitOfWork()) { @@ -779,20 +781,20 @@ namespace NadekoBot.Modules.Administration [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.Administrator)] + [RequireUserPermission(GuildPermission.Administrator)] [OwnerOnly] - public async Task LogEvents(IUserMessage imsg) + public async Task LogEvents() { - await imsg.Channel.SendConfirmAsync("Log events you can subscribe to:", String.Join(", ", Enum.GetNames(typeof(LogType)).Cast())); + await Context.Channel.SendConfirmAsync("Log events you can subscribe to:", String.Join(", ", Enum.GetNames(typeof(LogType)).Cast())); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.Administrator)] + [RequireUserPermission(GuildPermission.Administrator)] [OwnerOnly] - public async Task Log(IUserMessage imsg, LogType type) + public async Task Log(LogType type) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)Context.Channel; ulong? channelId = null; using (var uow = DbHandler.UnitOfWork()) { diff --git a/src/NadekoBot/Modules/Administration/Commands/MessageRepeater.cs b/src/NadekoBot/Modules/Administration/Commands/MessageRepeater.cs index 1bc8fdbe..8d50a80e 100644 --- a/src/NadekoBot/Modules/Administration/Commands/MessageRepeater.cs +++ b/src/NadekoBot/Modules/Administration/Commands/MessageRepeater.cs @@ -1,6 +1,5 @@ using Discord; using Discord.Commands; -using Discord.WebSocket; using NadekoBot.Attributes; using NadekoBot.Extensions; using NadekoBot.Services; @@ -18,7 +17,7 @@ namespace NadekoBot.Modules.Administration public partial class Administration { [Group] - public class RepeatCommands + public class RepeatCommands : ModuleBase { public static ConcurrentDictionary repeaters { get; } @@ -35,7 +34,7 @@ namespace NadekoBot.Modules.Administration { _log = LogManager.GetCurrentClassLogger(); this.Repeater = repeater; - this.Channel = channel ?? NadekoBot.Client.GetGuild(repeater.GuildId)?.GetTextChannel(repeater.ChannelId); + this.Channel = channel ?? NadekoBot.Client.GetGuild(repeater.GuildId)?.GetTextChannelAsync(repeater.ChannelId).GetAwaiter().GetResult(); if (Channel == null) return; Task.Run(Run); @@ -93,29 +92,26 @@ namespace NadekoBot.Modules.Administration [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageMessages)] - public async Task RepeatInvoke(IUserMessage imsg) + [RequireUserPermission(GuildPermission.ManageMessages)] + public async Task RepeatInvoke() { - var channel = (ITextChannel)imsg.Channel; - RepeatRunner rep; - if (!repeaters.TryGetValue(channel.Id, out rep)) + if (!repeaters.TryGetValue(Context.Channel.Id, out rep)) { - await channel.SendErrorAsync("ℹ️ **No repeating message found on this server.**").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("ℹ️ **No repeating message found on this server.**").ConfigureAwait(false); return; } rep.Reset(); - await channel.SendMessageAsync("🔄 " + rep.Repeater.Message).ConfigureAwait(false); + await Context.Channel.SendMessageAsync("🔄 " + rep.Repeater.Message).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageMessages)] - public async Task Repeat(IUserMessage imsg) + [RequireUserPermission(GuildPermission.ManageMessages)] + public async Task Repeat() { - var channel = (ITextChannel)imsg.Channel; RepeatRunner rep; - if (repeaters.TryRemove(channel.Id, out rep)) + if (repeaters.TryRemove(Context.Channel.Id, out rep)) { using (var uow = DbHandler.UnitOfWork()) { @@ -123,19 +119,17 @@ namespace NadekoBot.Modules.Administration await uow.CompleteAsync(); } rep.Stop(); - await channel.SendConfirmAsync("✅ **Stopped repeating a message.**").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("✅ **Stopped repeating a message.**").ConfigureAwait(false); } else - await channel.SendConfirmAsync("ℹ️ **No message is repeating.**").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("ℹ️ **No message is repeating.**").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageMessages)] - public async Task Repeat(IUserMessage imsg, int minutes, [Remainder] string message) + [RequireUserPermission(GuildPermission.ManageMessages)] + public async Task Repeat(int minutes, [Remainder] string message) { - var channel = (ITextChannel)imsg.Channel; - if (minutes < 1 || minutes > 10080) return; @@ -144,20 +138,20 @@ namespace NadekoBot.Modules.Administration RepeatRunner rep; - rep = repeaters.AddOrUpdate(channel.Id, (cid) => + rep = repeaters.AddOrUpdate(Context.Channel.Id, (cid) => { using (var uow = DbHandler.UnitOfWork()) { var localRep = new Repeater { - ChannelId = channel.Id, - GuildId = channel.Guild.Id, + ChannelId = Context.Channel.Id, + GuildId = Context.Guild.Id, Interval = TimeSpan.FromMinutes(minutes), Message = message, }; uow.Repeaters.Add(localRep); uow.Complete(); - return new RepeatRunner(localRep, channel); + return new RepeatRunner(localRep, (ITextChannel)Context.Channel); } }, (cid, old) => { @@ -172,7 +166,7 @@ namespace NadekoBot.Modules.Administration return old; }); - await channel.SendConfirmAsync($"🔁 Repeating **\"{rep.Repeater.Message}\"** every `{rep.Repeater.Interval.Days} day(s), {rep.Repeater.Interval.Hours} hour(s) and {rep.Repeater.Interval.Minutes} minute(s)`.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"🔁 Repeating **\"{rep.Repeater.Message}\"** every `{rep.Repeater.Interval.Days} day(s), {rep.Repeater.Interval.Hours} hour(s) and {rep.Repeater.Interval.Minutes} minute(s)`.").ConfigureAwait(false); } } } diff --git a/src/NadekoBot/Modules/Administration/Commands/Migration.cs b/src/NadekoBot/Modules/Administration/Commands/Migration.cs index 9d323245..433cfc7b 100644 --- a/src/NadekoBot/Modules/Administration/Commands/Migration.cs +++ b/src/NadekoBot/Modules/Administration/Commands/Migration.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; -using Discord; using Discord.Commands; using NadekoBot.Attributes; using NadekoBot.Services; @@ -21,23 +20,21 @@ namespace NadekoBot.Modules.Administration public partial class Administration { [Group] - public class Migration + public class Migration : ModuleBase { private const int CURRENT_VERSION = 1; - private Logger _log { get; } + private static Logger _log { get; } - public Migration() + static Migration() { _log = LogManager.GetCurrentClassLogger(); } [NadekoCommand, Usage, Description, Aliases] [OwnerOnly] - public async Task MigrateData(IUserMessage umsg) + public async Task MigrateData() { - var channel = (ITextChannel)umsg.Channel; - var version = 0; using (var uow = DbHandler.UnitOfWork()) { @@ -54,12 +51,12 @@ namespace NadekoBot.Modules.Administration break; } } - await umsg.Channel.SendMessageAsync("🆙 **Migration done.**").ConfigureAwait(false); + await Context.Channel.SendMessageAsync("🆙 **Migration done.**").ConfigureAwait(false); } catch (Exception ex) { _log.Error(ex); - await umsg.Channel.SendMessageAsync("⚠️ **Error while migrating, check `logs` for more informations.**").ConfigureAwait(false); + await Context.Channel.SendMessageAsync("⚠️ **Error while migrating, check `logs` for more informations.**").ConfigureAwait(false); } } diff --git a/src/NadekoBot/Modules/Administration/Commands/MuteCommands.cs b/src/NadekoBot/Modules/Administration/Commands/MuteCommands.cs index e53934d6..b4993bf2 100644 --- a/src/NadekoBot/Modules/Administration/Commands/MuteCommands.cs +++ b/src/NadekoBot/Modules/Administration/Commands/MuteCommands.cs @@ -1,6 +1,5 @@ using Discord; using Discord.Commands; -using Discord.WebSocket; using Microsoft.EntityFrameworkCore; using NadekoBot.Attributes; using NadekoBot.Extensions; @@ -12,7 +11,6 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Linq; -using System.Text; using System.Threading.Tasks; namespace NadekoBot.Modules.Administration @@ -20,7 +18,7 @@ namespace NadekoBot.Modules.Administration public partial class Administration { [Group] - public class MuteCommands + public class MuteCommands : ModuleBase { private static ConcurrentDictionary GuildMuteRoles { get; } = new ConcurrentDictionary(); @@ -67,7 +65,7 @@ namespace NadekoBot.Modules.Administration if (muted == null || !muted.Contains(usr.Id)) return; else - await Mute(usr).ConfigureAwait(false); + await MuteUser(usr).ConfigureAwait(false); } catch (Exception ex) { @@ -76,7 +74,7 @@ namespace NadekoBot.Modules.Administration } - public static async Task Mute(IGuildUser usr) + public static async Task MuteUser(IGuildUser usr) { await usr.ModifyAsync(x => x.Mute = true).ConfigureAwait(false); await usr.AddRolesAsync(await GetMuteRole(usr.Guild)).ConfigureAwait(false); @@ -96,7 +94,7 @@ namespace NadekoBot.Modules.Administration UserMuted(usr, MuteType.All); } - public static async Task Unmute(IGuildUser usr) + public static async Task UnmuteUser(IGuildUser usr) { await usr.ModifyAsync(x => x.Mute = false).ConfigureAwait(false); await usr.RemoveRolesAsync(await GetMuteRole(usr.Guild)).ConfigureAwait(false); @@ -134,7 +132,7 @@ namespace NadekoBot.Modules.Administration await guild.CreateRoleAsync(defaultMuteRoleName, GuildPermissions.None).ConfigureAwait(false); } - foreach (var toOverwrite in guild.GetTextChannels()) + foreach (var toOverwrite in (await guild.GetTextChannelsAsync())) { try { @@ -150,142 +148,131 @@ namespace NadekoBot.Modules.Administration [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageRoles)] + [RequireUserPermission(GuildPermission.ManageRoles)] [Priority(1)] - public async Task SetMuteRole(IUserMessage imsg, [Remainder] string name) + public async Task SetMuteRole([Remainder] string name) { - var channel = (ITextChannel)imsg.Channel; + //var channel = (ITextChannel)Context.Channel; name = name.Trim(); if (string.IsNullOrWhiteSpace(name)) return; using (var uow = DbHandler.UnitOfWork()) { - var config = uow.GuildConfigs.For(channel.Guild.Id, set => set); + var config = uow.GuildConfigs.For(Context.Guild.Id, set => set); config.MuteRoleName = name; - GuildMuteRoles.AddOrUpdate(channel.Guild.Id, name, (id, old) => name); + GuildMuteRoles.AddOrUpdate(Context.Guild.Id, name, (id, old) => name); await uow.CompleteAsync().ConfigureAwait(false); } - await channel.SendConfirmAsync("☑️ **New mute role set.**").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("☑️ **New mute role set.**").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageRoles)] + [RequireUserPermission(GuildPermission.ManageRoles)] [Priority(0)] - public Task SetMuteRole(IUserMessage imsg, [Remainder] IRole role) - => SetMuteRole(imsg, role.Name); + public Task SetMuteRole([Remainder] IRole role) + => SetMuteRole(role.Name); [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageRoles)] - [RequirePermission(GuildPermission.MuteMembers)] - public async Task Mute(IUserMessage umsg, IGuildUser user) + [RequireUserPermission(GuildPermission.ManageRoles)] + [RequireUserPermission(GuildPermission.MuteMembers)] + public async Task Mute(IGuildUser user) { - var channel = (ITextChannel)umsg.Channel; - try { - await Mute(user).ConfigureAwait(false); - await channel.SendConfirmAsync($"🔇 **{user}** has been **muted** from text and voice chat.").ConfigureAwait(false); + await MuteUser(user).ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"🔇 **{user}** has been **muted** from text and voice chat.").ConfigureAwait(false); } catch { - await channel.SendErrorAsync("⚠️ I most likely don't have the permission necessary for that.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("⚠️ I most likely don't have the permission necessary for that.").ConfigureAwait(false); } } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageRoles)] - [RequirePermission(GuildPermission.MuteMembers)] - public async Task Unmute(IUserMessage umsg, IGuildUser user) + [RequireUserPermission(GuildPermission.ManageRoles)] + [RequireUserPermission(GuildPermission.MuteMembers)] + public async Task Unmute(IGuildUser user) { - var channel = (ITextChannel)umsg.Channel; - try { - await Unmute(user).ConfigureAwait(false); - await channel.SendConfirmAsync($"🔉 **{user}** has been **unmuted** from text and voice chat.").ConfigureAwait(false); + await UnmuteUser(user).ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"🔉 **{user}** has been **unmuted** from text and voice chat.").ConfigureAwait(false); } catch { - await channel.SendErrorAsync("⚠️ I most likely don't have the permission necessary for that.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("⚠️ I most likely don't have the permission necessary for that.").ConfigureAwait(false); } } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageRoles)] - public async Task ChatMute(IUserMessage umsg, IGuildUser user) + [RequireUserPermission(GuildPermission.ManageRoles)] + public async Task ChatMute(IGuildUser user) { - var channel = (ITextChannel)umsg.Channel; - try { - await user.AddRolesAsync(await GetMuteRole(channel.Guild).ConfigureAwait(false)).ConfigureAwait(false); + await user.AddRolesAsync(await GetMuteRole(Context.Guild).ConfigureAwait(false)).ConfigureAwait(false); UserMuted(user, MuteType.Chat); - await channel.SendConfirmAsync($"✏️🚫 **{user}** has been **muted** from chatting.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"✏️🚫 **{user}** has been **muted** from chatting.").ConfigureAwait(false); } catch { - await channel.SendErrorAsync("⚠️ I most likely don't have the permission necessary for that.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("⚠️ I most likely don't have the permission necessary for that.").ConfigureAwait(false); } } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageRoles)] - public async Task ChatUnmute(IUserMessage umsg, IGuildUser user) + [RequireUserPermission(GuildPermission.ManageRoles)] + public async Task ChatUnmute(IGuildUser user) { - var channel = (ITextChannel)umsg.Channel; - try { - await user.RemoveRolesAsync(await GetMuteRole(channel.Guild).ConfigureAwait(false)).ConfigureAwait(false); + await user.RemoveRolesAsync(await GetMuteRole(Context.Guild).ConfigureAwait(false)).ConfigureAwait(false); UserUnmuted(user, MuteType.Chat); - await channel.SendConfirmAsync($"✏️✅ **{user}** has been **unmuted** from chatting.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"✏️✅ **{user}** has been **unmuted** from chatting.").ConfigureAwait(false); } catch { - await channel.SendErrorAsync("⚠️ I most likely don't have the permission necessary for that.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("⚠️ I most likely don't have the permission necessary for that.").ConfigureAwait(false); } } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.MuteMembers)] - public async Task VoiceMute(IUserMessage umsg, IGuildUser user) + [RequireUserPermission(GuildPermission.MuteMembers)] + public async Task VoiceMute(IGuildUser user) { - var channel = (ITextChannel)umsg.Channel; - try { await user.ModifyAsync(usr => usr.Mute = true).ConfigureAwait(false); UserMuted(user, MuteType.Voice); - await channel.SendConfirmAsync($"🎙🚫 **{user}** has been **voice muted**.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"🎙🚫 **{user}** has been **voice muted**.").ConfigureAwait(false); } catch { - await channel.SendErrorAsync("⚠️ I most likely don't have the permission necessary for that.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("⚠️ I most likely don't have the permission necessary for that.").ConfigureAwait(false); } } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.MuteMembers)] - public async Task VoiceUnmute(IUserMessage umsg, IGuildUser user) + [RequireUserPermission(GuildPermission.MuteMembers)] + public async Task VoiceUnmute(IGuildUser user) { - var channel = (ITextChannel)umsg.Channel; try { await user.ModifyAsync(usr => usr.Mute = false).ConfigureAwait(false); UserUnmuted(user, MuteType.Voice); - await channel.SendConfirmAsync($"🎙✅ **{user}** has been **voice unmuted**.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"🎙✅ **{user}** has been **voice unmuted**.").ConfigureAwait(false); } catch { - await channel.SendErrorAsync("⚠️ I most likely don't have the permission necessary for that.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("⚠️ I most likely don't have the permission necessary for that.").ConfigureAwait(false); } } } diff --git a/src/NadekoBot/Modules/Administration/Commands/PlayingRotateCommands.cs b/src/NadekoBot/Modules/Administration/Commands/PlayingRotateCommands.cs index c0ea4ad6..c9c49f60 100644 --- a/src/NadekoBot/Modules/Administration/Commands/PlayingRotateCommands.cs +++ b/src/NadekoBot/Modules/Administration/Commands/PlayingRotateCommands.cs @@ -1,6 +1,5 @@ using Discord; using Discord.Commands; -using Discord.WebSocket; using NadekoBot.Attributes; using NadekoBot.Extensions; using NadekoBot.Services; @@ -17,7 +16,7 @@ namespace NadekoBot.Modules.Administration public partial class Administration { [Group] - public class PlayingRotateCommands + public class PlayingRotateCommands : ModuleBase { private static Logger _log { get; } public static List RotatingStatusMessages { get; } @@ -73,7 +72,7 @@ namespace NadekoBot.Modules.Administration public static Dictionary> PlayingPlaceholders { get; } = new Dictionary> { {"%servers%", () => NadekoBot.Client.GetGuilds().Count().ToString()}, - {"%users%", () => NadekoBot.Client.GetGuilds().Select(s => s.GetUsers().Count).Sum().ToString()}, + {"%users%", () => NadekoBot.Client.GetGuilds().Select(s => s.Users.Count).Sum().ToString()}, {"%playing%", () => { var cnt = Music.Music.MusicPlayers.Count(kvp => kvp.Value.CurrentSong != null); if (cnt != 1) return cnt.ToString(); @@ -91,7 +90,7 @@ namespace NadekoBot.Modules.Administration [NadekoCommand, Usage, Description, Aliases] [OwnerOnly] - public async Task RotatePlaying(IUserMessage umsg) + public async Task RotatePlaying() { using (var uow = DbHandler.UnitOfWork()) { @@ -101,14 +100,14 @@ namespace NadekoBot.Modules.Administration await uow.CompleteAsync(); } if (RotatingStatuses) - await umsg.Channel.SendConfirmAsync("🆗 **Rotating playing status enabled.**").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("🆗 **Rotating playing status enabled.**").ConfigureAwait(false); else - await umsg.Channel.SendConfirmAsync("ℹ️ **Rotating playing status disabled.**").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("ℹ️ **Rotating playing status disabled.**").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [OwnerOnly] - public async Task AddPlaying(IUserMessage umsg, [Remainder] string status) + public async Task AddPlaying([Remainder] string status) { using (var uow = DbHandler.UnitOfWork()) { @@ -119,26 +118,26 @@ namespace NadekoBot.Modules.Administration await uow.CompleteAsync(); } - await umsg.Channel.SendConfirmAsync("✅ **Added.**").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("✅ **Added.**").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [OwnerOnly] - public async Task ListPlaying(IUserMessage umsg) + public async Task ListPlaying() { if (!RotatingStatusMessages.Any()) - await umsg.Channel.SendErrorAsync("❎ **No rotating playing statuses set.**"); + await Context.Channel.SendErrorAsync("❎ **No rotating playing statuses set.**"); else { var i = 1; - await umsg.Channel.SendConfirmAsync($"ℹ️ {umsg.Author.Mention} `Here is a list of rotating statuses:`\n\n\t" + string.Join("\n\t", RotatingStatusMessages.Select(rs => $"`{i++}.` {rs.Status}"))); + await Context.Channel.SendConfirmAsync($"ℹ️ {Context.User.Mention} `Here is a list of rotating statuses:`\n\n\t" + string.Join("\n\t", RotatingStatusMessages.Select(rs => $"`{i++}.` {rs.Status}"))); } } [NadekoCommand, Usage, Description, Aliases] [OwnerOnly] - public async Task RemovePlaying(IUserMessage umsg, int index) + public async Task RemovePlaying(int index) { index -= 1; @@ -154,7 +153,7 @@ namespace NadekoBot.Modules.Administration RotatingStatusMessages.RemoveAt(index); await uow.CompleteAsync(); } - await umsg.Channel.SendConfirmAsync($"🗑 **Removed the the playing message:** {msg}").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"🗑 **Removed the the playing message:** {msg}").ConfigureAwait(false); } } } diff --git a/src/NadekoBot/Modules/Administration/Commands/RatelimitCommand.cs b/src/NadekoBot/Modules/Administration/Commands/RatelimitCommand.cs index ec181f29..ccff187d 100644 --- a/src/NadekoBot/Modules/Administration/Commands/RatelimitCommand.cs +++ b/src/NadekoBot/Modules/Administration/Commands/RatelimitCommand.cs @@ -13,7 +13,7 @@ namespace NadekoBot.Modules.Administration public partial class Administration { [Group] - public class RatelimitCommand + public class RatelimitCommand : ModuleBase { public static ConcurrentDictionary RatelimitingChannels = new ConcurrentDictionary(); private static Logger _log { get; } @@ -88,42 +88,39 @@ namespace NadekoBot.Modules.Administration [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageMessages)] - public async Task Slowmode(IUserMessage umsg) + [RequireUserPermission(GuildPermission.ManageMessages)] + public async Task Slowmode() { - var channel = (ITextChannel)umsg.Channel; - Ratelimiter throwaway; - if (RatelimitingChannels.TryRemove(channel.Id, out throwaway)) + if (RatelimitingChannels.TryRemove(Context.Channel.Id, out throwaway)) { throwaway.cancelSource.Cancel(); - await channel.SendConfirmAsync("ℹ️ Slow mode disabled.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("ℹ️ Slow mode disabled.").ConfigureAwait(false); return; } } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageMessages)] - public async Task Slowmode(IUserMessage umsg, int msg, int perSec) + [RequireUserPermission(GuildPermission.ManageMessages)] + public async Task Slowmode(int msg, int perSec) { - await Slowmode(umsg).ConfigureAwait(false); // disable if exists - var channel = (ITextChannel)umsg.Channel; - + await Slowmode().ConfigureAwait(false); // disable if exists + if (msg < 1 || perSec < 1 || msg > 100 || perSec > 3600) { - await channel.SendErrorAsync("⚠️ Invalid parameters."); + await Context.Channel.SendErrorAsync("⚠️ Invalid parameters."); return; } var toAdd = new Ratelimiter() { - ChannelId = channel.Id, + ChannelId = Context.Channel.Id, MaxMessages = msg, PerSeconds = perSec, }; - if (RatelimitingChannels.TryAdd(channel.Id, toAdd)) + if(RatelimitingChannels.TryAdd(Context.Channel.Id, toAdd)) { - await channel.SendConfirmAsync("Slow mode initiated", + await Context.Channel.SendConfirmAsync("Slow mode initiated", $"Users can't send more than `{toAdd.MaxMessages} message(s)` every `{toAdd.PerSeconds} second(s)`.") .ConfigureAwait(false); } diff --git a/src/NadekoBot/Modules/Administration/Commands/SelfAssignedRolesCommand.cs b/src/NadekoBot/Modules/Administration/Commands/SelfAssignedRolesCommand.cs index e4e66155..1775e85e 100644 --- a/src/NadekoBot/Modules/Administration/Commands/SelfAssignedRolesCommand.cs +++ b/src/NadekoBot/Modules/Administration/Commands/SelfAssignedRolesCommand.cs @@ -16,84 +16,81 @@ namespace NadekoBot.Modules.Administration public partial class Administration { [Group] - public class SelfAssignedRolesCommands + public class SelfAssignedRolesCommands : ModuleBase { [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageMessages)] - public async Task AdSarm(IUserMessage imsg) + [RequireUserPermission(GuildPermission.ManageMessages)] + public async Task AdSarm() { - var channel = (ITextChannel)imsg.Channel; bool newval; using (var uow = DbHandler.UnitOfWork()) { - var config = uow.GuildConfigs.For(channel.Guild.Id, set => set); + var config = uow.GuildConfigs.For(Context.Guild.Id, set => set); newval = config.AutoDeleteSelfAssignedRoleMessages = !config.AutoDeleteSelfAssignedRoleMessages; await uow.CompleteAsync().ConfigureAwait(false); } - await channel.SendConfirmAsync($"ℹ️ Automatic deleting of `iam` and `iamn` confirmations has been {(newval ? "**enabled**" : "**disabled**")}.") + await Context.Channel.SendConfirmAsync($"ℹ️ Automatic deleting of `iam` and `iamn` confirmations has been {(newval ? "**enabled**" : "**disabled**")}.") .ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageRoles)] - public async Task Asar(IUserMessage umsg, [Remainder] IRole role) + [RequireUserPermission(GuildPermission.ManageRoles)] + public async Task Asar([Remainder] IRole role) { - var channel = (ITextChannel)umsg.Channel; - IEnumerable roles; string msg; using (var uow = DbHandler.UnitOfWork()) { - roles = uow.SelfAssignedRoles.GetFromGuild(channel.Guild.Id); - if (roles.Any(s => s.RoleId == role.Id && s.GuildId == role.GuildId)) + roles = uow.SelfAssignedRoles.GetFromGuild(Context.Guild.Id); + if (roles.Any(s => s.RoleId == role.Id && s.GuildId == role.Guild.Id)) { - await channel.SendMessageAsync($"💢 Role **{role.Name}** is already in the list.").ConfigureAwait(false); + await Context.Channel.SendMessageAsync($"💢 Role **{role.Name}** is already in the list.").ConfigureAwait(false); return; } else { uow.SelfAssignedRoles.Add(new SelfAssignedRole { RoleId = role.Id, - GuildId = role.GuildId + GuildId = role.Guild.Id }); await uow.CompleteAsync(); msg = $"🆗 Role **{role.Name}** added to the list."; } } - await channel.SendConfirmAsync(msg.ToString()).ConfigureAwait(false); + await Context.Channel.SendConfirmAsync(msg.ToString()).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageRoles)] - public async Task Rsar(IUserMessage umsg, [Remainder] IRole role) + [RequireUserPermission(GuildPermission.ManageRoles)] + public async Task Rsar([Remainder] IRole role) { - var channel = (ITextChannel)umsg.Channel; + //var channel = (ITextChannel)Context.Channel; bool success; using (var uow = DbHandler.UnitOfWork()) { - success = uow.SelfAssignedRoles.DeleteByGuildAndRoleId(role.GuildId, role.Id); + success = uow.SelfAssignedRoles.DeleteByGuildAndRoleId(role.Guild.Id, role.Id); await uow.CompleteAsync(); } if (!success) { - await channel.SendErrorAsync("❎ That role is not self-assignable.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("❎ That role is not self-assignable.").ConfigureAwait(false); return; } - await channel.SendConfirmAsync($"🗑 **{role.Name}** has been removed from the list of self-assignable roles.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"🗑 **{role.Name}** has been removed from the list of self-assignable roles.").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task Lsar(IUserMessage umsg) + public async Task Lsar() { - var channel = (ITextChannel)umsg.Channel; + //var channel = (ITextChannel)Context.Channel; var toRemove = new ConcurrentHashSet(); var removeMsg = new StringBuilder(); @@ -101,13 +98,13 @@ namespace NadekoBot.Modules.Administration var roleCnt = 0; using (var uow = DbHandler.UnitOfWork()) { - var roleModels = uow.SelfAssignedRoles.GetFromGuild(channel.Guild.Id).ToList(); + var roleModels = uow.SelfAssignedRoles.GetFromGuild(Context.Guild.Id).ToList(); roleCnt = roleModels.Count; msg.AppendLine(); foreach (var roleModel in roleModels) { - var role = channel.Guild.Roles.FirstOrDefault(r => r.Id == roleModel.RoleId); + var role = Context.Guild.Roles.FirstOrDefault(r => r.Id == roleModel.RoleId); if (role == null) { uow.SelfAssignedRoles.Remove(roleModel); @@ -123,61 +120,61 @@ namespace NadekoBot.Modules.Administration } await uow.CompleteAsync(); } - await channel.SendConfirmAsync($"ℹ️ There are `{roleCnt}` self assignable roles:", msg.ToString() + "\n\n" + removeMsg.ToString()).ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"ℹ️ There are `{roleCnt}` self assignable roles:", msg.ToString() + "\n\n" + removeMsg.ToString()).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageRoles)] - public async Task Tesar(IUserMessage umsg) + [RequireUserPermission(GuildPermission.ManageRoles)] + public async Task Tesar() { - var channel = (ITextChannel)umsg.Channel; + //var channel = (ITextChannel)Context.Channel; bool areExclusive; using (var uow = DbHandler.UnitOfWork()) { - var config = uow.GuildConfigs.For(channel.Guild.Id, set => set); + var config = uow.GuildConfigs.For(Context.Guild.Id, set => set); areExclusive = config.ExclusiveSelfAssignedRoles = !config.ExclusiveSelfAssignedRoles; await uow.CompleteAsync(); } string exl = areExclusive ? "**exclusive**." : "**not exclusive**."; - await channel.SendConfirmAsync("ℹ️ Self assigned roles are now " + exl); + await Context.Channel.SendConfirmAsync("ℹ️ Self assigned roles are now " + exl); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task Iam(IUserMessage umsg, [Remainder] IRole role) + public async Task Iam([Remainder] IRole role) { - var channel = (ITextChannel)umsg.Channel; - var guildUser = (IGuildUser)umsg.Author; - var usrMsg = (IUserMessage)umsg; + //var channel = (ITextChannel)Context.Channel; + var guildUser = (IGuildUser)Context.User; GuildConfig conf; IEnumerable roles; using (var uow = DbHandler.UnitOfWork()) { - conf = uow.GuildConfigs.For(channel.Guild.Id, set => set); - roles = uow.SelfAssignedRoles.GetFromGuild(channel.Guild.Id); + conf = uow.GuildConfigs.For(Context.Guild.Id, set => set); + roles = uow.SelfAssignedRoles.GetFromGuild(Context.Guild.Id); } SelfAssignedRole roleModel; if ((roleModel = roles.FirstOrDefault(r=>r.RoleId == role.Id)) == null) { - await channel.SendErrorAsync("That role is not self-assignable.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("That role is not self-assignable.").ConfigureAwait(false); return; } - if (guildUser.Roles.Contains(role)) + if (guildUser.RoleIds.Contains(role.Id)) { - await channel.SendErrorAsync($"You already have **{role.Name}** role.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync($"You already have **{role.Name}** role.").ConfigureAwait(false); return; } if (conf.ExclusiveSelfAssignedRoles) { - var sameRoles = guildUser.Roles.Where(r => roles.Any(rm => rm.RoleId == r.Id)); - if (sameRoles.Any()) + var sameRoleId = guildUser.RoleIds.Where(r => roles.Select(sar => sar.RoleId).Contains(r)).FirstOrDefault(); + var sameRole = Context.Guild.GetRole(sameRoleId); + if (sameRoleId != default(ulong)) { - await channel.SendErrorAsync($"You already have **{sameRoles.FirstOrDefault().Name}** `exclusive self-assigned` role.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync($"You already have **{sameRole?.Name}** `exclusive self-assigned` role.").ConfigureAwait(false); return; } } @@ -187,42 +184,41 @@ namespace NadekoBot.Modules.Administration } catch (Exception ex) { - await channel.SendErrorAsync($"⚠️ I am unable to add that role to you. `I can't add roles to owners or other roles higher than my role in the role hierarchy.`").ConfigureAwait(false); + await Context.Channel.SendErrorAsync($"⚠️ I am unable to add that role to you. `I can't add roles to owners or other roles higher than my role in the role hierarchy.`").ConfigureAwait(false); Console.WriteLine(ex); return; } - var msg = await channel.SendConfirmAsync($"🆗 You now have **{role.Name}** role.").ConfigureAwait(false); + var msg = await Context.Channel.SendConfirmAsync($"🆗 You now have **{role.Name}** role.").ConfigureAwait(false); if (conf.AutoDeleteSelfAssignedRoleMessages) { msg.DeleteAfter(3); - umsg.DeleteAfter(3); + Context.Message.DeleteAfter(3); } } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task Iamnot(IUserMessage umsg, [Remainder] IRole role) + public async Task Iamnot([Remainder] IRole role) { - var channel = (ITextChannel)umsg.Channel; - var guildUser = (IGuildUser)umsg.Author; + var guildUser = (IGuildUser)Context.User; bool autoDeleteSelfAssignedRoleMessages; IEnumerable roles; using (var uow = DbHandler.UnitOfWork()) { - autoDeleteSelfAssignedRoleMessages = uow.GuildConfigs.For(channel.Guild.Id, set => set).AutoDeleteSelfAssignedRoleMessages; - roles = uow.SelfAssignedRoles.GetFromGuild(channel.Guild.Id); + autoDeleteSelfAssignedRoleMessages = uow.GuildConfigs.For(Context.Guild.Id, set => set).AutoDeleteSelfAssignedRoleMessages; + roles = uow.SelfAssignedRoles.GetFromGuild(Context.Guild.Id); } SelfAssignedRole roleModel; if ((roleModel = roles.FirstOrDefault(r => r.RoleId == role.Id)) == null) { - await channel.SendErrorAsync("💢 That role is not self-assignable.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("💢 That role is not self-assignable.").ConfigureAwait(false); return; } - if (!guildUser.Roles.Contains(role)) + if (!guildUser.RoleIds.Contains(role.Id)) { - await channel.SendErrorAsync($"❎ You don't have **{role.Name}** role.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync($"❎ You don't have **{role.Name}** role.").ConfigureAwait(false); return; } try @@ -231,15 +227,15 @@ namespace NadekoBot.Modules.Administration } catch (Exception) { - await channel.SendErrorAsync($"⚠️ I am unable to add that role to you. `I can't remove roles to owners or other roles higher than my role in the role hierarchy.`").ConfigureAwait(false); + await Context.Channel.SendErrorAsync($"⚠️ I am unable to add that role to you. `I can't remove roles to owners or other roles higher than my role in the role hierarchy.`").ConfigureAwait(false); return; } - var msg = await channel.SendConfirmAsync($"🆗 You no longer have **{role.Name}** role.").ConfigureAwait(false); + var msg = await Context.Channel.SendConfirmAsync($"🆗 You no longer have **{role.Name}** role.").ConfigureAwait(false); if (autoDeleteSelfAssignedRoleMessages) { msg.DeleteAfter(3); - umsg.DeleteAfter(3); + Context.Message.DeleteAfter(3); } } } diff --git a/src/NadekoBot/Modules/Administration/Commands/SelfCommands.cs b/src/NadekoBot/Modules/Administration/Commands/SelfCommands.cs index b750a26c..589fa49a 100644 --- a/src/NadekoBot/Modules/Administration/Commands/SelfCommands.cs +++ b/src/NadekoBot/Modules/Administration/Commands/SelfCommands.cs @@ -2,7 +2,10 @@ using Discord.Commands; using NadekoBot.Attributes; using NadekoBot.Extensions; +using System; +using System.IO; using System.Linq; +using System.Net.Http; using System.Threading.Tasks; namespace NadekoBot.Modules.Administration @@ -10,42 +13,155 @@ namespace NadekoBot.Modules.Administration public partial class Administration { [Group] - class SelfCommands + class SelfCommands : ModuleBase { - private ShardedDiscordClient _client; - - public SelfCommands() - { - this._client = NadekoBot.Client; - } - [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] [OwnerOnly] - public async Task Leave(IUserMessage umsg, [Remainder] string guildStr) + public async Task Leave([Remainder] string guildStr) { - var channel = (ITextChannel)umsg.Channel; - guildStr = guildStr.Trim().ToUpperInvariant(); - var server = _client.GetGuilds().FirstOrDefault(g => g.Id.ToString().Trim().ToUpperInvariant() == guildStr) ?? - _client.GetGuilds().FirstOrDefault(g => g.Name.Trim().ToUpperInvariant() == guildStr); + var server = NadekoBot.Client.GetGuilds().FirstOrDefault(g => g.Id.ToString().Trim().ToUpperInvariant() == guildStr) ?? + NadekoBot.Client.GetGuilds().FirstOrDefault(g => g.Name.Trim().ToUpperInvariant() == guildStr); if (server == null) { - await channel.SendErrorAsync("⚠️ Cannot find that server").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("⚠️ Cannot find that server").ConfigureAwait(false); return; } - if (server.OwnerId != _client.GetCurrentUser().Id) + if (server.OwnerId != NadekoBot.Client.CurrentUser().Id) { await server.LeaveAsync().ConfigureAwait(false); - await channel.SendConfirmAsync("✅ Left server " + server.Name).ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("✅ Left server " + server.Name).ConfigureAwait(false); } else { await server.DeleteAsync().ConfigureAwait(false); - await channel.SendConfirmAsync("Deleted server " + server.Name).ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("Deleted server " + server.Name).ConfigureAwait(false); } } + + + [NadekoCommand, Usage, Description, Aliases] + [OwnerOnly] + public async Task Die() + { + try { await Context.Channel.SendConfirmAsync("ℹ️ **Shutting down.**").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); } + await Task.Delay(2000).ConfigureAwait(false); + Environment.Exit(0); + } + + [NadekoCommand, Usage, Description, Aliases] + [OwnerOnly] + public async Task SetName([Remainder] string newName) + { + if (string.IsNullOrWhiteSpace(newName)) + return; + + await NadekoBot.Client.CurrentUser().ModifyAsync(u => u.Username = newName).ConfigureAwait(false); + + await Context.Channel.SendConfirmAsync($"ℹ️ Successfully changed name to **{newName}**").ConfigureAwait(false); + } + + [NadekoCommand, Usage, Description, Aliases] + [OwnerOnly] + public async Task SetAvatar([Remainder] string img = null) + { + if (string.IsNullOrWhiteSpace(img)) + return; + + using (var http = new HttpClient()) + { + using (var sr = await http.GetStreamAsync(img)) + { + var imgStream = new MemoryStream(); + await sr.CopyToAsync(imgStream); + imgStream.Position = 0; + + await NadekoBot.Client.CurrentUser().ModifyAsync(u => u.Avatar = new Image(imgStream)).ConfigureAwait(false); + } + } + + await Context.Channel.SendConfirmAsync("🆒 **New avatar set.**").ConfigureAwait(false); + } + + [NadekoCommand, Usage, Description, Aliases] + [OwnerOnly] + public async Task SetGame([Remainder] string game = null) + { + game = game ?? ""; + + await NadekoBot.Client.SetGame(game).ConfigureAwait(false); + + await Context.Channel.SendConfirmAsync("👾 **New game set.**").ConfigureAwait(false); + } + + [NadekoCommand, Usage, Description, Aliases] + [OwnerOnly] + public async Task SetStream(string url, [Remainder] string name = null) + { + name = name ?? ""; + + await NadekoBot.Client.SetStream(name, url).ConfigureAwait(false); + + await Context.Channel.SendConfirmAsync("ℹ️ **New stream set.**").ConfigureAwait(false); + } + + [NadekoCommand, Usage, Description, Aliases] + [OwnerOnly] + public async Task Send(string where, [Remainder] string msg = null) + { + if (string.IsNullOrWhiteSpace(msg)) + return; + + var ids = where.Split('|'); + if (ids.Length != 2) + return; + var sid = ulong.Parse(ids[0]); + var server = NadekoBot.Client.GetGuilds().Where(s => s.Id == sid).FirstOrDefault(); + + if (server == null) + return; + + if (ids[1].ToUpperInvariant().StartsWith("C:")) + { + var cid = ulong.Parse(ids[1].Substring(2)); + var ch = (await server.GetTextChannelsAsync()).Where(c => c.Id == cid).FirstOrDefault(); + if (ch == null) + { + return; + } + await ch.SendMessageAsync(msg).ConfigureAwait(false); + } + else if (ids[1].ToUpperInvariant().StartsWith("U:")) + { + var uid = ulong.Parse(ids[1].Substring(2)); + var user = server.Users.Where(u => u.Id == uid).FirstOrDefault(); + if (user == null) + { + return; + } + await user.SendMessageAsync(msg).ConfigureAwait(false); + } + else + { + await Context.Channel.SendErrorAsync("⚠️ Invalid format.").ConfigureAwait(false); + } + } + + [NadekoCommand, Usage, Description, Aliases] + [OwnerOnly] + public async Task Announce([Remainder] string message) + { + var channels = await Task.WhenAll(NadekoBot.Client.GetGuilds().Select(g => + g.GetDefaultChannelAsync() + )).ConfigureAwait(false); + if (channels == null) + return; + await Task.WhenAll(channels.Where(c => c != null).Select(c => c.SendConfirmAsync($"🆕 Message from {Context.User} `[Bot Owner]`:", message))) + .ConfigureAwait(false); + + await Context.Channel.SendConfirmAsync("🆗").ConfigureAwait(false); + } } } } diff --git a/src/NadekoBot/Modules/Administration/Commands/ServerGreetCommands.cs b/src/NadekoBot/Modules/Administration/Commands/ServerGreetCommands.cs index 46130517..80b8c394 100644 --- a/src/NadekoBot/Modules/Administration/Commands/ServerGreetCommands.cs +++ b/src/NadekoBot/Modules/Administration/Commands/ServerGreetCommands.cs @@ -1,9 +1,9 @@ using Discord; using Discord.Commands; +using Discord.WebSocket; using NadekoBot.Attributes; using NadekoBot.Extensions; using NadekoBot.Services; -using NadekoBot.Services.Database; using NadekoBot.Services.Database.Models; using NLog; using System; @@ -15,7 +15,7 @@ namespace NadekoBot.Modules.Administration public partial class Administration { [Group] - public class ServerGreetCommands + public class ServerGreetCommands : ModuleBase { private static Logger _log { get; } @@ -108,19 +108,19 @@ namespace NadekoBot.Modules.Administration [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageGuild)] - public async Task GreetDel(IUserMessage umsg, int timer = 30) + [RequireUserPermission(GuildPermission.ManageGuild)] + public async Task GreetDel(int timer = 30) { - var channel = (ITextChannel)umsg.Channel; + var channel = (ITextChannel)Context.Channel; if (timer < 0 || timer > 600) return; - await ServerGreetCommands.SetGreetDel(channel.Guild.Id, timer).ConfigureAwait(false); + await ServerGreetCommands.SetGreetDel(Context.Guild.Id, timer).ConfigureAwait(false); if (timer > 0) - await channel.SendConfirmAsync($"🆗 Greet messages **will be deleted** after `{timer} seconds`.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"🆗 Greet messages **will be deleted** after `{timer} seconds`.").ConfigureAwait(false); else - await channel.SendConfirmAsync("ℹ️ Automatic deletion of greet messages has been **disabled**.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("ℹ️ Automatic deletion of greet messages has been **disabled**.").ConfigureAwait(false); } private static async Task SetGreetDel(ulong id, int timer) @@ -139,17 +139,15 @@ namespace NadekoBot.Modules.Administration [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageGuild)] - public async Task Greet(IUserMessage umsg) + [RequireUserPermission(GuildPermission.ManageGuild)] + public async Task Greet() { - var channel = (ITextChannel)umsg.Channel; - - var enabled = await ServerGreetCommands.SetGreet(channel.Guild.Id, channel.Id).ConfigureAwait(false); + var enabled = await ServerGreetCommands.SetGreet(Context.Guild.Id, Context.Channel.Id).ConfigureAwait(false); if (enabled) - await channel.SendConfirmAsync("✅ Greeting messages **enabled** on this channel.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("✅ Greeting messages **enabled** on this channel.").ConfigureAwait(false); else - await channel.SendConfirmAsync("ℹ️ Greeting messages **disabled**.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("ℹ️ Greeting messages **disabled**.").ConfigureAwait(false); } private static async Task SetGreet(ulong guildId, ulong channelId, bool? value = null) @@ -168,27 +166,25 @@ namespace NadekoBot.Modules.Administration [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageGuild)] - public async Task GreetMsg(IUserMessage umsg, [Remainder] string text = null) + [RequireUserPermission(GuildPermission.ManageGuild)] + public async Task GreetMsg([Remainder] string text = null) { - var channel = (ITextChannel)umsg.Channel; - if (string.IsNullOrWhiteSpace(text)) { string channelGreetMessageText; using (var uow = DbHandler.UnitOfWork()) { - channelGreetMessageText = uow.GuildConfigs.For(channel.Guild.Id, set => set).ChannelGreetMessageText; + channelGreetMessageText = uow.GuildConfigs.For(Context.Guild.Id, set => set).ChannelGreetMessageText; } - await channel.SendConfirmAsync("Current greet message: ", channelGreetMessageText?.SanitizeMentions()); + await Context.Channel.SendConfirmAsync("Current greet message: ", channelGreetMessageText?.SanitizeMentions()); return; } - var sendGreetEnabled = ServerGreetCommands.SetGreetMessage(channel.Guild.Id, ref text); + var sendGreetEnabled = ServerGreetCommands.SetGreetMessage(Context.Guild.Id, ref text); - await channel.SendConfirmAsync("🆗 New greet message **set**.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("🆗 New greet message **set**.").ConfigureAwait(false); if (!sendGreetEnabled) - await channel.SendConfirmAsync("ℹ️ Enable greet messsages by typing `.greet`").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("ℹ️ Enable greet messsages by typing `.greet`").ConfigureAwait(false); } public static bool SetGreetMessage(ulong guildId, ref string message) @@ -212,17 +208,15 @@ namespace NadekoBot.Modules.Administration [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageGuild)] - public async Task GreetDm(IUserMessage umsg) + [RequireUserPermission(GuildPermission.ManageGuild)] + public async Task GreetDm() { - var channel = (ITextChannel)umsg.Channel; - - var enabled = await ServerGreetCommands.SetGreetDm(channel.Guild.Id).ConfigureAwait(false); + var enabled = await ServerGreetCommands.SetGreetDm(Context.Guild.Id).ConfigureAwait(false); if (enabled) - await channel.SendConfirmAsync("🆗 DM Greet announcements **enabled**.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("🆗 DM Greet announcements **enabled**.").ConfigureAwait(false); else - await channel.SendConfirmAsync("ℹ️ Greet announcements **disabled**.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("ℹ️ Greet announcements **disabled**.").ConfigureAwait(false); } private static async Task SetGreetDm(ulong guildId, bool? value = null) @@ -240,27 +234,25 @@ namespace NadekoBot.Modules.Administration [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageGuild)] - public async Task GreetDmMsg(IUserMessage umsg, [Remainder] string text = null) + [RequireUserPermission(GuildPermission.ManageGuild)] + public async Task GreetDmMsg([Remainder] string text = null) { - var channel = (ITextChannel)umsg.Channel; - if (string.IsNullOrWhiteSpace(text)) { GuildConfig config; using (var uow = DbHandler.UnitOfWork()) { - config = uow.GuildConfigs.For(channel.Guild.Id); + config = uow.GuildConfigs.For(Context.Guild.Id); } - await channel.SendConfirmAsync("ℹ️ Current **DM greet** message: `" + config.DmGreetMessageText?.SanitizeMentions() + "`"); + await Context.Channel.SendConfirmAsync("ℹ️ Current **DM greet** message: `" + config.DmGreetMessageText?.SanitizeMentions() + "`"); return; } - var sendGreetEnabled = ServerGreetCommands.SetGreetDmMessage(channel.Guild.Id, ref text); + var sendGreetEnabled = ServerGreetCommands.SetGreetDmMessage(Context.Guild.Id, ref text); - await channel.SendConfirmAsync("🆗 New DM greet message **set**.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("🆗 New DM greet message **set**.").ConfigureAwait(false); if (!sendGreetEnabled) - await channel.SendConfirmAsync($"ℹ️ Enable DM greet messsages by typing `{NadekoBot.ModulePrefixes[typeof(Administration).Name]}greetdm`").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"ℹ️ Enable DM greet messsages by typing `{NadekoBot.ModulePrefixes[typeof(Administration).Name]}greetdm`").ConfigureAwait(false); } public static bool SetGreetDmMessage(ulong guildId, ref string message) @@ -284,17 +276,15 @@ namespace NadekoBot.Modules.Administration [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageGuild)] - public async Task Bye(IUserMessage umsg) + [RequireUserPermission(GuildPermission.ManageGuild)] + public async Task Bye() { - var channel = (ITextChannel)umsg.Channel; - - var enabled = await ServerGreetCommands.SetBye(channel.Guild.Id, channel.Id).ConfigureAwait(false); + var enabled = await ServerGreetCommands.SetBye(Context.Guild.Id, Context.Channel.Id).ConfigureAwait(false); if (enabled) - await channel.SendConfirmAsync("✅ Bye announcements **enabled** on this channel.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("✅ Bye announcements **enabled** on this channel.").ConfigureAwait(false); else - await channel.SendConfirmAsync("ℹ️ Bye announcements **disabled**.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("ℹ️ Bye announcements **disabled**.").ConfigureAwait(false); } private static async Task SetBye(ulong guildId, ulong channelId, bool? value = null) @@ -313,27 +303,25 @@ namespace NadekoBot.Modules.Administration [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageGuild)] - public async Task ByeMsg(IUserMessage umsg, [Remainder] string text = null) + [RequireUserPermission(GuildPermission.ManageGuild)] + public async Task ByeMsg([Remainder] string text = null) { - var channel = (ITextChannel)umsg.Channel; - if (string.IsNullOrWhiteSpace(text)) { string byeMessageText; using (var uow = DbHandler.UnitOfWork()) { - byeMessageText = uow.GuildConfigs.For(channel.Guild.Id, set => set).ChannelByeMessageText; + byeMessageText = uow.GuildConfigs.For(Context.Guild.Id, set => set).ChannelByeMessageText; } - await channel.SendConfirmAsync("ℹ️ Current **bye** message: `" + byeMessageText?.SanitizeMentions() + "`"); + await Context.Channel.SendConfirmAsync("ℹ️ Current **bye** message: `" + byeMessageText?.SanitizeMentions() + "`"); return; } - var sendByeEnabled = ServerGreetCommands.SetByeMessage(channel.Guild.Id, ref text); + var sendByeEnabled = ServerGreetCommands.SetByeMessage(Context.Guild.Id, ref text); - await channel.SendConfirmAsync("🆗 New bye message **set**.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("🆗 New bye message **set**.").ConfigureAwait(false); if (!sendByeEnabled) - await channel.SendConfirmAsync($"ℹ️ Enable bye messsages by typing `{NadekoBot.ModulePrefixes[typeof(Administration).Name]}bye`").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"ℹ️ Enable bye messsages by typing `{NadekoBot.ModulePrefixes[typeof(Administration).Name]}bye`").ConfigureAwait(false); } public static bool SetByeMessage(ulong guildId, ref string message) @@ -357,17 +345,15 @@ namespace NadekoBot.Modules.Administration [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageGuild)] - public async Task ByeDel(IUserMessage umsg, int timer = 30) + [RequireUserPermission(GuildPermission.ManageGuild)] + public async Task ByeDel(int timer = 30) { - var channel = (ITextChannel)umsg.Channel; - - await ServerGreetCommands.SetByeDel(channel.Guild.Id, timer).ConfigureAwait(false); + await ServerGreetCommands.SetByeDel(Context.Guild.Id, timer).ConfigureAwait(false); if (timer > 0) - await channel.SendConfirmAsync($"🆗 Bye messages **will be deleted** after `{timer} seconds`.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"🆗 Bye messages **will be deleted** after `{timer} seconds`.").ConfigureAwait(false); else - await channel.SendConfirmAsync("ℹ️ Automatic deletion of bye messages has been **disabled**.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("ℹ️ Automatic deletion of bye messages has been **disabled**.").ConfigureAwait(false); } private static async Task SetByeDel(ulong id, int timer) diff --git a/src/NadekoBot/Modules/Administration/Commands/VoicePlusTextCommands.cs b/src/NadekoBot/Modules/Administration/Commands/VoicePlusTextCommands.cs index 14dd4e30..1d76b1e7 100644 --- a/src/NadekoBot/Modules/Administration/Commands/VoicePlusTextCommands.cs +++ b/src/NadekoBot/Modules/Administration/Commands/VoicePlusTextCommands.cs @@ -17,7 +17,7 @@ namespace NadekoBot.Modules.Administration public partial class Administration { [Group] - public class VoicePlusTextCommands + public class VoicePlusTextCommands : ModuleBase { private static Regex channelNameRegex = new Regex(@"[^a-zA-Z0-9 -]", RegexOptions.Compiled); @@ -36,9 +36,9 @@ namespace NadekoBot.Modules.Administration _log.Debug($"Loaded in {sw.Elapsed.TotalSeconds:F2}s"); } - private static async void UserUpdatedEventHandler(IUser iuser, IVoiceState before, IVoiceState after) + private static async void UserUpdatedEventHandler(SocketUser iuser, SocketVoiceState before, SocketVoiceState after) { - var user = (iuser as IGuildUser); + var user = (iuser as SocketGuildUser); var guild = user?.Guild; if (guild == null) @@ -46,7 +46,7 @@ namespace NadekoBot.Modules.Administration try { - var botUserPerms = guild.GetCurrentUser().GuildPermissions; + var botUserPerms = guild.CurrentUser.GuildPermissions; if (before.VoiceChannel == after.VoiceChannel) return; @@ -75,7 +75,7 @@ namespace NadekoBot.Modules.Administration var beforeVch = before.VoiceChannel; if (beforeVch != null) { - var textChannel = guild.GetTextChannels().Where(t => t.Name == GetChannelName(beforeVch.Name).ToLowerInvariant()).FirstOrDefault(); + var textChannel = (await guild.GetTextChannelsAsync()).Where(t => t.Name == GetChannelName(beforeVch.Name).ToLowerInvariant()).FirstOrDefault(); if (textChannel != null) await textChannel.AddPermissionOverwriteAsync(user, new OverwritePermissions(readMessages: PermValue.Deny, @@ -84,7 +84,7 @@ namespace NadekoBot.Modules.Administration var afterVch = after.VoiceChannel; if (afterVch != null && guild.AFKChannelId != afterVch.Id) { - var textChannel = guild.GetTextChannels() + var textChannel = (await guild.GetTextChannelsAsync()) .Where(t => t.Name == GetChannelName(afterVch.Name).ToLowerInvariant()) .FirstOrDefault(); if (textChannel == null) @@ -110,17 +110,16 @@ namespace NadekoBot.Modules.Administration [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageRoles)] - [RequirePermission(GuildPermission.ManageChannels)] - public async Task VoicePlusText(IUserMessage msg) + [RequireUserPermission(GuildPermission.ManageRoles)] + [RequireUserPermission(GuildPermission.ManageChannels)] + public async Task VoicePlusText() { - var channel = (ITextChannel)msg.Channel; - var guild = channel.Guild; + var guild = Context.Guild; var botUser = await guild.GetCurrentUserAsync().ConfigureAwait(false); if (!botUser.GuildPermissions.ManageRoles || !botUser.GuildPermissions.ManageChannels) { - await channel.SendErrorAsync("I require atleast **manage roles** and **manage channels permissions** to enable this feature. `(preffered Administration permission)`"); + await Context.Channel.SendErrorAsync("I require atleast **manage roles** and **manage channels permissions** to enable this feature. `(preffered Administration permission)`"); return; } @@ -128,7 +127,7 @@ namespace NadekoBot.Modules.Administration { try { - await channel.SendErrorAsync("⚠️ You are enabling this feature and **I do not have ADMINISTRATOR permissions**. " + + await Context.Channel.SendErrorAsync("⚠️ You are enabling this feature and **I do not have ADMINISTRATOR permissions**. " + "`This may cause some issues, and you will have to clean up text channels yourself afterwards.`"); } catch { } @@ -145,39 +144,38 @@ namespace NadekoBot.Modules.Administration if (!isEnabled) { voicePlusTextCache.TryRemove(guild.Id); - foreach (var textChannel in guild.GetTextChannels().Where(c => c.Name.EndsWith("-voice"))) + foreach (var textChannel in (await guild.GetTextChannelsAsync().ConfigureAwait(false)).Where(c => c.Name.EndsWith("-voice"))) { try { await textChannel.DeleteAsync().ConfigureAwait(false); } catch { } } - await channel.SendConfirmAsync("ℹ️ Successfuly **removed** voice + text feature.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("ℹ️ Successfuly **removed** voice + text feature.").ConfigureAwait(false); return; } voicePlusTextCache.Add(guild.Id); - await channel.SendConfirmAsync("🆗 Successfuly **enabled** voice + text feature.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("🆗 Successfuly **enabled** voice + text feature.").ConfigureAwait(false); } catch (Exception ex) { - await channel.SendErrorAsync(ex.ToString()).ConfigureAwait(false); + await Context.Channel.SendErrorAsync(ex.ToString()).ConfigureAwait(false); } } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageChannels)] - [RequirePermission(GuildPermission.ManageRoles)] - public async Task CleanVPlusT(IUserMessage msg) + [RequireUserPermission(GuildPermission.ManageChannels)] + [RequireUserPermission(GuildPermission.ManageRoles)] + public async Task CleanVPlusT() { - var channel = (ITextChannel)msg.Channel; - var guild = channel.Guild; + var guild = Context.Guild; var botUser = await guild.GetCurrentUserAsync().ConfigureAwait(false); if (!botUser.GuildPermissions.Administrator) { - await channel.SendErrorAsync("I need **Administrator permission** to do that.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("I need **Administrator permission** to do that.").ConfigureAwait(false); return; } - var allTxtChannels = guild.GetTextChannels().Where(c => c.Name.EndsWith("-voice")); - var validTxtChannelNames = guild.GetVoiceChannels().Select(c => GetChannelName(c.Name).ToLowerInvariant()); + var allTxtChannels = (await guild.GetTextChannelsAsync()).Where(c => c.Name.EndsWith("-voice")); + var validTxtChannelNames = (await guild.GetVoiceChannelsAsync()).Select(c => GetChannelName(c.Name).ToLowerInvariant()); var invalidTxtChannels = allTxtChannels.Where(c => !validTxtChannelNames.Contains(c.Name)); @@ -187,7 +185,7 @@ namespace NadekoBot.Modules.Administration await Task.Delay(500); } - await channel.SendConfirmAsync("Cleaned v+t.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("Cleaned v+t.").ConfigureAwait(false); } } } diff --git a/src/NadekoBot/Modules/ClashOfClans/ClashOfClans.cs b/src/NadekoBot/Modules/ClashOfClans/ClashOfClans.cs index 53a22763..26b18995 100644 --- a/src/NadekoBot/Modules/ClashOfClans/ClashOfClans.cs +++ b/src/NadekoBot/Modules/ClashOfClans/ClashOfClans.cs @@ -7,7 +7,6 @@ using System.Threading.Tasks; using Discord; using NadekoBot.Services; using NadekoBot.Attributes; -using Discord.WebSocket; using NadekoBot.Services.Database.Models; using System.Linq; using NadekoBot.Extensions; @@ -38,7 +37,9 @@ namespace NadekoBot.Modules.ClashOfClans .Select(cw => { cw.Channel = NadekoBot.Client.GetGuild(cw.GuildId) - ?.GetTextChannel(cw.ChannelId); + ?.GetTextChannelAsync(cw.ChannelId) + .GetAwaiter() + .GetResult(); return cw; }) .Where(cw => cw.Channel != null) @@ -56,9 +57,6 @@ namespace NadekoBot.Modules.ClashOfClans } } }, null, TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1)); - - sw.Stop(); - _log.Debug($"Loaded in {sw.Elapsed.TotalSeconds:F2}s"); } private static async Task CheckWar(TimeSpan callExpire, ClashWar war) @@ -86,11 +84,9 @@ namespace NadekoBot.Modules.ClashOfClans [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task CreateWar(IUserMessage umsg, int size, [Remainder] string enemyClan = null) + public async Task CreateWar(int size, [Remainder] string enemyClan = null) { - var channel = (ITextChannel)umsg.Channel; - - if (!(umsg.Author as IGuildUser).GuildPermissions.ManageChannels) + if (!(Context.User as IGuildUser).GuildPermissions.ManageChannels) return; if (string.IsNullOrWhiteSpace(enemyClan)) @@ -98,67 +94,64 @@ namespace NadekoBot.Modules.ClashOfClans if (size < 10 || size > 50 || size % 5 != 0) { - await channel.SendErrorAsync("🔰 Not a Valid war size").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("🔰 Not a Valid war size").ConfigureAwait(false); return; } List wars; - if (!ClashWars.TryGetValue(channel.Guild.Id, out wars)) + if (!ClashWars.TryGetValue(Context.Guild.Id, out wars)) { wars = new List(); - if (!ClashWars.TryAdd(channel.Guild.Id, wars)) + if (!ClashWars.TryAdd(Context.Guild.Id, wars)) return; } - var cw = await CreateWar(enemyClan, size, channel.Guild.Id, umsg.Channel.Id); + var cw = await CreateWar(enemyClan, size, Context.Guild.Id, Context.Channel.Id); wars.Add(cw); - await channel.SendConfirmAsync($"❗🔰**CREATED CLAN WAR AGAINST {cw.ShortPrint()}**").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"❗🔰**CREATED CLAN WAR AGAINST {cw.ShortPrint()}**").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task StartWar(IUserMessage umsg, [Remainder] string number = null) + public async Task StartWar([Remainder] string number = null) { - var channel = (ITextChannel)umsg.Channel; - int num = 0; int.TryParse(number, out num); - var warsInfo = GetWarInfo(umsg, num); + var warsInfo = GetWarInfo(Context.Guild, num); if (warsInfo == null) { - await channel.SendErrorAsync("🔰 **That war does not exist.**").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("🔰 **That war does not exist.**").ConfigureAwait(false); return; } var war = warsInfo.Item1[warsInfo.Item2]; try { war.Start(); - await channel.SendConfirmAsync($"🔰**STARTED WAR AGAINST {war.ShortPrint()}**").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"🔰**STARTED WAR AGAINST {war.ShortPrint()}**").ConfigureAwait(false); } catch { - await channel.SendErrorAsync($"🔰**WAR AGAINST {war.ShortPrint()} HAS ALREADY STARTED**").ConfigureAwait(false); + await Context.Channel.SendErrorAsync($"🔰**WAR AGAINST {war.ShortPrint()} HAS ALREADY STARTED**").ConfigureAwait(false); } SaveWar(war); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task ListWar(IUserMessage umsg, [Remainder] string number = null) + public async Task ListWar([Remainder] string number = null) { - var channel = (ITextChannel)umsg.Channel; // if number is null, print all wars in a short way if (string.IsNullOrWhiteSpace(number)) { //check if there are any wars List wars = null; - ClashWars.TryGetValue(channel.Guild.Id, out wars); + ClashWars.TryGetValue(Context.Guild.Id, out wars); if (wars == null || wars.Count == 0) { - await channel.SendErrorAsync("🔰 **No active wars.**").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("🔰 **No active wars.**").ConfigureAwait(false); return; } @@ -171,90 +164,84 @@ namespace NadekoBot.Modules.ClashOfClans sb.AppendLine($"\t\t`Size:` **{wars[i].Size} v {wars[i].Size}**"); sb.AppendLine("**-------------------------**"); } - await channel.SendConfirmAsync(sb.ToString()).ConfigureAwait(false); + await Context.Channel.SendConfirmAsync(sb.ToString()).ConfigureAwait(false); return; } var num = 0; int.TryParse(number, out num); //if number is not null, print the war needed - var warsInfo = GetWarInfo(umsg, num); + var warsInfo = GetWarInfo(Context.Guild, num); if (warsInfo == null) { - await channel.SendErrorAsync("🔰 **That war does not exist.**").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("🔰 **That war does not exist.**").ConfigureAwait(false); return; } - await channel.SendConfirmAsync(warsInfo.Item1[warsInfo.Item2].ToPrettyString()).ConfigureAwait(false); + await Context.Channel.SendConfirmAsync(warsInfo.Item1[warsInfo.Item2].ToPrettyString()).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task Claim(IUserMessage umsg, int number, int baseNumber, [Remainder] string other_name = null) + public async Task Claim(int number, int baseNumber, [Remainder] string other_name = null) { - var channel = (ITextChannel)umsg.Channel; - var warsInfo = GetWarInfo(umsg, number); + var warsInfo = GetWarInfo(Context.Guild, number); if (warsInfo == null || warsInfo.Item1.Count == 0) { - await channel.SendErrorAsync("🔰 **That war does not exist.**").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("🔰 **That war does not exist.**").ConfigureAwait(false); return; } var usr = string.IsNullOrWhiteSpace(other_name) ? - umsg.Author.Username : + Context.User.Username : other_name; try { var war = warsInfo.Item1[warsInfo.Item2]; war.Call(usr, baseNumber - 1); SaveWar(war); - await channel.SendConfirmAsync($"🔰**{usr}** claimed a base #{baseNumber} for a war against {war.ShortPrint()}").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"🔰**{usr}** claimed a base #{baseNumber} for a war against {war.ShortPrint()}").ConfigureAwait(false); } catch (Exception ex) { - await channel.SendErrorAsync($"🔰 {ex.Message}").ConfigureAwait(false); + await Context.Channel.SendErrorAsync($"🔰 {ex.Message}").ConfigureAwait(false); } } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task ClaimFinish1(IUserMessage umsg, int number, int baseNumber = 0) + public async Task ClaimFinish1(int number, int baseNumber = 0) { - var channel = (ITextChannel)umsg.Channel; - await FinishClaim(umsg, number, baseNumber - 1, 1); + await FinishClaim(number, baseNumber - 1, 1); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task ClaimFinish2(IUserMessage umsg, int number, int baseNumber = 0) + public async Task ClaimFinish2(int number, int baseNumber = 0) { - var channel = (ITextChannel)umsg.Channel; - await FinishClaim(umsg, number, baseNumber - 1, 2); + await FinishClaim(number, baseNumber - 1, 2); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task ClaimFinish(IUserMessage umsg, int number, int baseNumber = 0) + public async Task ClaimFinish(int number, int baseNumber = 0) { - var channel = (ITextChannel)umsg.Channel; - await FinishClaim(umsg, number, baseNumber - 1); + await FinishClaim(number, baseNumber - 1); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task EndWar(IUserMessage umsg, int number) + public async Task EndWar(int number) { - var channel = (ITextChannel)umsg.Channel; - - var warsInfo = GetWarInfo(umsg, number); + var warsInfo = GetWarInfo(Context.Guild, number); if (warsInfo == null) { - await channel.SendErrorAsync("🔰 That war does not exist.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("🔰 That war does not exist.").ConfigureAwait(false); return; } var war = warsInfo.Item1[warsInfo.Item2]; war.End(); SaveWar(war); - await channel.SendConfirmAsync($"❗🔰**War against {warsInfo.Item1[warsInfo.Item2].ShortPrint()} ended.**").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"❗🔰**War against {warsInfo.Item1[warsInfo.Item2].ShortPrint()} ended.**").ConfigureAwait(false); var size = warsInfo.Item1[warsInfo.Item2].Size; warsInfo.Item1.RemoveAt(warsInfo.Item2); @@ -262,40 +249,37 @@ namespace NadekoBot.Modules.ClashOfClans [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task Unclaim(IUserMessage umsg, int number, [Remainder] string otherName = null) + public async Task Unclaim(int number, [Remainder] string otherName = null) { - var channel = (ITextChannel)umsg.Channel; - - var warsInfo = GetWarInfo(umsg, number); + var warsInfo = GetWarInfo(Context.Guild, number); if (warsInfo == null || warsInfo.Item1.Count == 0) { - await channel.SendErrorAsync("🔰 **That war does not exist.**").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("🔰 **That war does not exist.**").ConfigureAwait(false); return; } var usr = string.IsNullOrWhiteSpace(otherName) ? - umsg.Author.Username : + Context.User.Username : otherName; try { var war = warsInfo.Item1[warsInfo.Item2]; var baseNumber = war.Uncall(usr); SaveWar(war); - await channel.SendConfirmAsync($"🔰 @{usr} has **UNCLAIMED** a base #{baseNumber + 1} from a war against {war.ShortPrint()}").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"🔰 @{usr} has **UNCLAIMED** a base #{baseNumber + 1} from a war against {war.ShortPrint()}").ConfigureAwait(false); } catch (Exception ex) { - await channel.SendErrorAsync($"🔰 {ex.Message}").ConfigureAwait(false); + await Context.Channel.SendErrorAsync($"🔰 {ex.Message}").ConfigureAwait(false); } } - private async Task FinishClaim(IUserMessage umsg, int number, int baseNumber, int stars = 3) + private async Task FinishClaim(int number, int baseNumber, int stars = 3) { - var channel = (ITextChannel)umsg.Channel; - var warInfo = GetWarInfo(umsg, number); + var warInfo = GetWarInfo(Context.Guild, number); if (warInfo == null || warInfo.Item1.Count == 0) { - await channel.SendErrorAsync("🔰 **That war does not exist.**").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("🔰 **That war does not exist.**").ConfigureAwait(false); return; } var war = warInfo.Item1[warInfo.Item2]; @@ -303,27 +287,25 @@ namespace NadekoBot.Modules.ClashOfClans { if (baseNumber == -1) { - baseNumber = war.FinishClaim(umsg.Author.Username, stars); + baseNumber = war.FinishClaim(Context.User.Username, stars); SaveWar(war); } else { war.FinishClaim(baseNumber, stars); } - await channel.SendConfirmAsync($"❗🔰{umsg.Author.Mention} **DESTROYED** a base #{baseNumber + 1} in a war against {war.ShortPrint()}").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"❗🔰{Context.User.Mention} **DESTROYED** a base #{baseNumber + 1} in a war against {war.ShortPrint()}").ConfigureAwait(false); } catch (Exception ex) { - await channel.SendErrorAsync($"🔰 {ex.Message}").ConfigureAwait(false); + await Context.Channel.SendErrorAsync($"🔰 {ex.Message}").ConfigureAwait(false); } } - private static Tuple, int> GetWarInfo(IUserMessage umsg, int num) + private static Tuple, int> GetWarInfo(IGuild guild, int num) { - var channel = (ITextChannel)umsg.Channel; - //check if there are any wars List wars = null; - ClashWars.TryGetValue(channel.Guild.Id, out wars); + ClashWars.TryGetValue(guild.Id, out wars); if (wars == null || wars.Count == 0) { return null; @@ -340,6 +322,7 @@ namespace NadekoBot.Modules.ClashOfClans public static async Task CreateWar(string enemyClan, int size, ulong serverId, ulong channelId) { + var channel = await NadekoBot.Client.GetGuild(serverId)?.GetTextChannelAsync(channelId); using (var uow = DbHandler.UnitOfWork()) { var cw = new ClashWar @@ -349,8 +332,7 @@ namespace NadekoBot.Modules.ClashOfClans Bases = new List(size), GuildId = serverId, ChannelId = channelId, - Channel = NadekoBot.Client.GetGuild(serverId) - ?.GetTextChannel(channelId) + Channel = channel, }; cw.Bases.Capacity = size; for (int i = 0; i < size; i++) diff --git a/src/NadekoBot/Modules/CustomReactions/CustomReactions.cs b/src/NadekoBot/Modules/CustomReactions/CustomReactions.cs index dfbe7dc1..26a1b902 100644 --- a/src/NadekoBot/Modules/CustomReactions/CustomReactions.cs +++ b/src/NadekoBot/Modules/CustomReactions/CustomReactions.cs @@ -9,6 +9,7 @@ using Discord; using NadekoBot.Extensions; using NLog; using System.Diagnostics; +using Discord.WebSocket; namespace NadekoBot.Modules.CustomReactions { @@ -35,20 +36,18 @@ namespace NadekoBot.Modules.CustomReactions sw.Stop(); _log.Debug($"Loaded in {sw.Elapsed.TotalSeconds:F2}s"); } - public CustomReactions() : base() - { - } public void ClearStats() => ReactionStats.Clear(); - public static async Task TryExecuteCustomReaction(IUserMessage umsg) + public static async Task TryExecuteCustomReaction(SocketUserMessage umsg) { - var channel = umsg.Channel as ITextChannel; + var channel = umsg.Channel as SocketTextChannel; if (channel == null) return false; var content = umsg.Content.Trim().ToLowerInvariant(); ConcurrentHashSet reactions; + GuildReactions.TryGetValue(channel.Guild.Id, out reactions); if (reactions != null && reactions.Any()) { @@ -84,17 +83,17 @@ namespace NadekoBot.Modules.CustomReactions } [NadekoCommand, Usage, Description, Aliases] - public async Task AddCustReact(IUserMessage imsg, string key, [Remainder] string message) + public async Task AddCustReact(string key, [Remainder] string message) { - var channel = imsg.Channel as ITextChannel; + var channel = Context.Channel as ITextChannel; if (string.IsNullOrWhiteSpace(message) || string.IsNullOrWhiteSpace(key)) return; key = key.ToLowerInvariant(); - if ((channel == null && !NadekoBot.Credentials.IsOwner(imsg.Author)) || (channel != null && !((IGuildUser)imsg.Author).GuildPermissions.Administrator)) + if ((channel == null && !NadekoBot.Credentials.IsOwner(Context.User)) || (channel != null && !((IGuildUser)Context.User).GuildPermissions.Administrator)) { - try { await imsg.Channel.SendErrorAsync("Insufficient permissions. Requires Bot ownership for global custom reactions, and Administrator for guild custom reactions."); } catch { } + try { await Context.Channel.SendErrorAsync("Insufficient permissions. Requires Bot ownership for global custom reactions, and Administrator for guild custom reactions."); } catch { } return; } @@ -119,36 +118,34 @@ namespace NadekoBot.Modules.CustomReactions } else { - var reactions = GuildReactions.GetOrAdd(channel.Guild.Id, new ConcurrentHashSet()); + var reactions = GuildReactions.GetOrAdd(Context.Guild.Id, new ConcurrentHashSet()); reactions.Add(cr); } - await imsg.Channel.EmbedAsync(new EmbedBuilder().WithOkColor() + await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor() .WithTitle("New Custom Reaction") .WithDescription($"#{cr.Id}") .AddField(efb => efb.WithName("Trigger").WithValue(key)) .AddField(efb => efb.WithName("Response").WithValue(message)) - .Build()).ConfigureAwait(false); + ).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [Priority(0)] - public async Task ListCustReact(IUserMessage imsg, int page = 1) + public async Task ListCustReact(int page = 1) { - var channel = imsg.Channel as ITextChannel; - if (page < 1 || page > 1000) return; ConcurrentHashSet customReactions; - if (channel == null) + if (Context.Guild == null) customReactions = GlobalReactions; else - customReactions = GuildReactions.GetOrAdd(channel.Guild.Id, new ConcurrentHashSet()); + customReactions = GuildReactions.GetOrAdd(Context.Guild.Id, new ConcurrentHashSet()); if (customReactions == null || !customReactions.Any()) - await imsg.Channel.SendErrorAsync("No custom reactions found").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("No custom reactions found").ConfigureAwait(false); else - await imsg.Channel.SendConfirmAsync( + await Context.Channel.SendConfirmAsync( $"Page {page} of custom reactions:", string.Join("\n", customReactions.OrderBy(cr => cr.Trigger) .Skip((page - 1) * 20) @@ -164,18 +161,16 @@ namespace NadekoBot.Modules.CustomReactions [NadekoCommand, Usage, Description, Aliases] [Priority(1)] - public async Task ListCustReact(IUserMessage imsg, All x) + public async Task ListCustReact(All x) { - var channel = imsg.Channel as ITextChannel; - ConcurrentHashSet customReactions; - if (channel == null) + if (Context.Guild == null) customReactions = GlobalReactions; else - customReactions = GuildReactions.GetOrAdd(channel.Guild.Id, new ConcurrentHashSet()); + customReactions = GuildReactions.GetOrAdd(Context.Guild.Id, new ConcurrentHashSet()); if (customReactions == null || !customReactions.Any()) - await imsg.Channel.SendErrorAsync("No custom reactions found").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("No custom reactions found").ConfigureAwait(false); else { var txtStream = await customReactions.GroupBy(cr => cr.Trigger) @@ -184,29 +179,28 @@ namespace NadekoBot.Modules.CustomReactions .ToJson() .ToStream() .ConfigureAwait(false); - if (channel == null) // its a private one, just send back - await imsg.Channel.SendFileAsync(txtStream, "customreactions.txt", "List of all custom reactions").ConfigureAwait(false); + if (Context.Guild == null) // its a private one, just send back + await Context.Channel.SendFileAsync(txtStream, "customreactions.txt", "List of all custom reactions").ConfigureAwait(false); else - await ((IGuildUser)imsg.Author).SendFileAsync(txtStream, "customreactions.txt", "List of all custom reactions").ConfigureAwait(false); + await ((IGuildUser)Context.User).SendFileAsync(txtStream, "customreactions.txt", "List of all custom reactions").ConfigureAwait(false); } } [NadekoCommand, Usage, Description, Aliases] - public async Task ListCustReactG(IUserMessage imsg, int page = 1) + public async Task ListCustReactG(int page = 1) { - var channel = imsg.Channel as ITextChannel; if (page < 1 || page > 10000) return; ConcurrentHashSet customReactions; - if (channel == null) + if (Context.Guild == null) customReactions = GlobalReactions; else - customReactions = GuildReactions.GetOrAdd(channel.Guild.Id, new ConcurrentHashSet()); + customReactions = GuildReactions.GetOrAdd(Context.Guild.Id, new ConcurrentHashSet()); if (customReactions == null || !customReactions.Any()) - await imsg.Channel.SendErrorAsync("No custom reactions found").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("No custom reactions found").ConfigureAwait(false); else - await imsg.Channel.SendConfirmAsync($"Page {page} of custom reactions (grouped):", + await Context.Channel.SendConfirmAsync($"Page {page} of custom reactions (grouped):", string.Join("\r\n", customReactions .GroupBy(cr => cr.Trigger) .OrderBy(cr => cr.Key) @@ -217,38 +211,34 @@ namespace NadekoBot.Modules.CustomReactions } [NadekoCommand, Usage, Description, Aliases] - public async Task ShowCustReact(IUserMessage imsg, int id) + public async Task ShowCustReact(int id) { - var channel = imsg.Channel as ITextChannel; - ConcurrentHashSet customReactions; - if (channel == null) + if (Context.Guild == null) customReactions = GlobalReactions; else - customReactions = GuildReactions.GetOrAdd(channel.Guild.Id, new ConcurrentHashSet()); + customReactions = GuildReactions.GetOrAdd(Context.Guild.Id, new ConcurrentHashSet()); var found = customReactions.FirstOrDefault(cr => cr.Id == id); if (found == null) - await imsg.Channel.SendErrorAsync("No custom reaction found with that id.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("No custom reaction found with that id.").ConfigureAwait(false); else { - await imsg.Channel.EmbedAsync(new EmbedBuilder().WithOkColor() + await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor() .WithDescription($"#{id}") .AddField(efb => efb.WithName("Trigger").WithValue(found.Trigger)) .AddField(efb => efb.WithName("Response").WithValue(found.Response + "\n```css\n" + found.Response + "```")) - .Build()).ConfigureAwait(false); + ).ConfigureAwait(false); } } [NadekoCommand, Usage, Description, Aliases] - public async Task DelCustReact(IUserMessage imsg, int id) + public async Task DelCustReact(int id) { - var channel = imsg.Channel as ITextChannel; - - if ((channel == null && !NadekoBot.Credentials.IsOwner(imsg.Author)) || (channel != null && !((IGuildUser)imsg.Author).GuildPermissions.Administrator)) + if ((Context.Guild == null && !NadekoBot.Credentials.IsOwner(Context.User)) || (Context.Guild != null && !((IGuildUser)Context.User).GuildPermissions.Administrator)) { - try { await imsg.Channel.SendErrorAsync("Insufficient permissions. Requires Bot ownership for global custom reactions, and Administrator for guild custom reactions."); } catch { } + try { await Context.Channel.SendErrorAsync("Insufficient permissions. Requires Bot ownership for global custom reactions, and Administrator for guild custom reactions."); } catch { } return; } @@ -260,16 +250,16 @@ namespace NadekoBot.Modules.CustomReactions if (toDelete == null) //not found return; - if ((toDelete.GuildId == null || toDelete.GuildId == 0) && channel == null) + if ((toDelete.GuildId == null || toDelete.GuildId == 0) && Context.Guild == null) { uow.CustomReactions.Remove(toDelete); GlobalReactions.RemoveWhere(cr => cr.Id == toDelete.Id); success = true; } - else if ((toDelete.GuildId != null && toDelete.GuildId != 0) && channel?.Guild.Id == toDelete.GuildId) + else if ((toDelete.GuildId != null && toDelete.GuildId != 0) && Context.Guild.Id == toDelete.GuildId) { uow.CustomReactions.Remove(toDelete); - GuildReactions.GetOrAdd(channel.Guild.Id, new ConcurrentHashSet()).RemoveWhere(cr => cr.Id == toDelete.Id); + GuildReactions.GetOrAdd(Context.Guild.Id, new ConcurrentHashSet()).RemoveWhere(cr => cr.Id == toDelete.Id); success = true; } if (success) @@ -277,44 +267,44 @@ namespace NadekoBot.Modules.CustomReactions } if (success) - await imsg.Channel.SendConfirmAsync("Deleted custom reaction", toDelete.ToString()).ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("Deleted custom reaction", toDelete.ToString()).ConfigureAwait(false); else - await imsg.Channel.SendErrorAsync("Failed to find that custom reaction.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("Failed to find that custom reaction.").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] - public async Task CrStatsClear(IUserMessage imsg, string trigger = null) + public async Task CrStatsClear(string trigger = null) { if (string.IsNullOrWhiteSpace(trigger)) { ClearStats(); - await imsg.Channel.SendConfirmAsync($"Custom reaction stats cleared.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"Custom reaction stats cleared.").ConfigureAwait(false); } else { uint throwaway; if (ReactionStats.TryRemove(trigger, out throwaway)) { - await imsg.Channel.SendConfirmAsync($"Stats cleared for `{trigger}` custom reaction.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"Stats cleared for `{trigger}` custom reaction.").ConfigureAwait(false); } else { - await imsg.Channel.SendErrorAsync("No stats for that trigger found, no action taken.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("No stats for that trigger found, no action taken.").ConfigureAwait(false); } } } [NadekoCommand, Usage, Description, Aliases] - public async Task CrStats(IUserMessage imsg, int page = 1) + public async Task CrStats(int page = 1) { if (page < 1) return; - await imsg.Channel.EmbedAsync(ReactionStats.OrderByDescending(x => x.Value) + await Context.Channel.EmbedAsync(ReactionStats.OrderByDescending(x => x.Value) .Skip((page - 1) * 9) .Take(9) .Aggregate(new EmbedBuilder().WithOkColor().WithTitle($"Custom Reaction stats page #{page}"), (agg, cur) => agg.AddField(efb => efb.WithName(cur.Key).WithValue(cur.Value.ToString()).WithIsInline(true))) - .Build()) + ) .ConfigureAwait(false); } } diff --git a/src/NadekoBot/Modules/CustomReactions/Extensions.cs b/src/NadekoBot/Modules/CustomReactions/Extensions.cs index 49b2909f..c6fe16c7 100644 --- a/src/NadekoBot/Modules/CustomReactions/Extensions.cs +++ b/src/NadekoBot/Modules/CustomReactions/Extensions.cs @@ -18,7 +18,7 @@ namespace NadekoBot.Modules.CustomReactions public static Dictionary> placeholders = new Dictionary>() { - {"%mention%", (ctx) => { return $"<@{NadekoBot.Client.GetCurrentUser().Id}>"; } }, + {"%mention%", (ctx) => { return $"<@{NadekoBot.Client.CurrentUser().Id}>"; } }, {"%user%", (ctx) => { return ctx.Author.Mention; } }, {"%rnduser%", (ctx) => { var ch = ctx.Channel as ITextChannel; diff --git a/src/NadekoBot/Modules/DiscordModule.cs b/src/NadekoBot/Modules/DiscordModule.cs index c5b129dc..711431d5 100644 --- a/src/NadekoBot/Modules/DiscordModule.cs +++ b/src/NadekoBot/Modules/DiscordModule.cs @@ -1,10 +1,9 @@ using Discord.Commands; -using NadekoBot.Services; using NLog; namespace NadekoBot.Modules { - public class DiscordModule + public abstract class DiscordModule : ModuleBase { protected Logger _log { get; } protected string _prefix { get; } diff --git a/src/NadekoBot/Modules/Gambling/Commands/AnimalRacing.cs b/src/NadekoBot/Modules/Gambling/Commands/AnimalRacing.cs index b9d8af08..9acd88e4 100644 --- a/src/NadekoBot/Modules/Gambling/Commands/AnimalRacing.cs +++ b/src/NadekoBot/Modules/Gambling/Commands/AnimalRacing.cs @@ -1,5 +1,6 @@ using Discord; using Discord.Commands; +using Discord.WebSocket; using NadekoBot.Attributes; using NadekoBot.Extensions; using NadekoBot.Services; @@ -16,39 +17,36 @@ namespace NadekoBot.Modules.Gambling public partial class Gambling { [Group] - public class AnimalRacing + public class AnimalRacing : ModuleBase { public static ConcurrentDictionary AnimalRaces { get; } = new ConcurrentDictionary(); [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task Race(IUserMessage umsg) + public async Task Race() { - var channel = (ITextChannel)umsg.Channel; - - var ar = new AnimalRace(channel.Guild.Id, channel); + var ar = new AnimalRace(Context.Guild.Id, (ITextChannel)Context.Channel); if (ar.Fail) - await channel.SendErrorAsync("Animal Race", "Failed starting. Another race is probably running.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("🏁 `Failed starting a race. Another race is probably running.`").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task JoinRace(IUserMessage umsg, int amount = 0) + public async Task JoinRace(int amount = 0) { - var channel = (ITextChannel)umsg.Channel; if (amount < 0) amount = 0; AnimalRace ar; - if (!AnimalRaces.TryGetValue(channel.Guild.Id, out ar)) + if (!AnimalRaces.TryGetValue(Context.Guild.Id, out ar)) { - await channel.SendErrorAsync("No race exists on this server").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("No race exists on this server").ConfigureAwait(false); return; } - await ar.JoinRace(umsg.Author as IGuildUser, amount); + await ar.JoinRace(Context.User as IGuildUser, amount); } public class AnimalRace @@ -209,9 +207,9 @@ namespace NadekoBot.Modules.Gambling } - private void Client_MessageReceived(IMessage imsg) + private void Client_MessageReceived(SocketMessage imsg) { - var msg = imsg as IUserMessage; + var msg = imsg as SocketUserMessage; if (msg == null) return; if (msg.IsAuthor() || !(imsg.Channel is ITextChannel) || imsg.Channel != raceChannel) diff --git a/src/NadekoBot/Modules/Gambling/Commands/DiceRollCommand.cs b/src/NadekoBot/Modules/Gambling/Commands/DiceRollCommand.cs index f1c3252a..90c54e2d 100644 --- a/src/NadekoBot/Modules/Gambling/Commands/DiceRollCommand.cs +++ b/src/NadekoBot/Modules/Gambling/Commands/DiceRollCommand.cs @@ -10,13 +10,14 @@ using System.IO; using System.Linq; using System.Text.RegularExpressions; using System.Threading.Tasks; +using Image = ImageSharp.Image; namespace NadekoBot.Modules.Gambling { public partial class Gambling { [Group] - public class DriceRollCommands + public class DriceRollCommands : ModuleBase { private Regex dndRegex { get; } = new Regex(@"^(?\d+)d(?\d+)(?:\+(?\d+))?(?:\-(?\d+))?$", RegexOptions.Compiled); private Regex fudgeRegex { get; } = new Regex(@"^(?\d+)d(?:F|f)$", RegexOptions.Compiled); @@ -24,12 +25,8 @@ namespace NadekoBot.Modules.Gambling private readonly char[] fateRolls = new[] { '-', ' ', '+' }; [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Roll(IUserMessage umsg) + public async Task Roll() { - var channel = (ITextChannel)umsg.Channel; - if (channel == null) - return; var rng = new NadekoRandom(); var gen = rng.Next(1, 101); @@ -47,7 +44,7 @@ namespace NadekoBot.Modules.Gambling catch { return new MemoryStream(); } }); - await channel.SendFileAsync(imageStream, "dice.png", $"{umsg.Author.Mention} rolled " + Format.Code(gen.ToString())).ConfigureAwait(false); + await Context.Channel.SendFileAsync(imageStream, "dice.png", $"{Context.User.Mention} rolled " + Format.Code(gen.ToString())).ConfigureAwait(false); } public enum RollOrderType @@ -57,47 +54,39 @@ namespace NadekoBot.Modules.Gambling } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] [Priority(0)] - public async Task Roll(IUserMessage umsg, int num) + public async Task Roll(int num) { - await InternalRoll(umsg, num, true).ConfigureAwait(false); + await InternalRoll(num, true).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] [Priority(0)] - public async Task Rolluo(IUserMessage umsg, int num) + public async Task Rolluo(int num) { - await InternalRoll(umsg, num, false).ConfigureAwait(false); + await InternalRoll(num, false).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] [Priority(1)] - public async Task Roll(IUserMessage umsg, string arg) + public async Task Roll(string arg) { - await InternallDndRoll(umsg, arg, true).ConfigureAwait(false); + await InternallDndRoll(arg, true).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] [Priority(1)] - public async Task Rolluo(IUserMessage umsg, string arg) + public async Task Rolluo(string arg) { - await InternallDndRoll(umsg, arg, false).ConfigureAwait(false); + await InternallDndRoll(arg, false).ConfigureAwait(false); } - private async Task InternalRoll(IUserMessage umsg, int num, bool ordered) + private async Task InternalRoll( int num, bool ordered) { - var channel = (ITextChannel)umsg.Channel; - if (channel == null) - return; - if (num < 1 || num > 30) { - await channel.SendErrorAsync("Invalid number specified. You can roll up to 1-30 dice at a time.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("Invalid number specified. You can roll up to 1-30 dice at a time.").ConfigureAwait(false); return; } @@ -135,15 +124,11 @@ namespace NadekoBot.Modules.Gambling var ms = new MemoryStream(); bitmap.SaveAsPng(ms); ms.Position = 0; - await channel.SendFileAsync(ms, "dice.png", $"{umsg.Author.Mention} rolled {values.Count} {(values.Count == 1 ? "die" : "dice")}. Total: **{values.Sum()}** Average: **{(values.Sum() / (1.0f * values.Count)).ToString("N2")}**").ConfigureAwait(false); + await Context.Channel.SendFileAsync(ms, "dice.png", $"{Context.User.Mention} rolled {values.Count} {(values.Count == 1 ? "die" : "dice")}. Total: **{values.Sum()}** Average: **{(values.Sum() / (1.0f * values.Count)).ToString("N2")}**").ConfigureAwait(false); } - private async Task InternallDndRoll(IUserMessage umsg, string arg, bool ordered) + private async Task InternallDndRoll(string arg, bool ordered) { - var channel = (ITextChannel)umsg.Channel; - if (channel == null) - return; - Match match; int n1; int n2; @@ -159,10 +144,10 @@ namespace NadekoBot.Modules.Gambling { rolls.Add(fateRolls[rng.Next(0, fateRolls.Length)]); } - var embed = new EmbedBuilder().WithOkColor().WithDescription($"{umsg.Author.Mention} rolled {n1} fate {(n1 == 1 ? "die" : "dice")}.") + var embed = new EmbedBuilder().WithOkColor().WithDescription($"{Context.User.Mention} rolled {n1} fate {(n1 == 1 ? "die" : "dice")}.") .AddField(efb => efb.WithName(Format.Bold("Result")) .WithValue(string.Join(" ", rolls.Select(c => Format.Code($"[{c}]"))))); - await channel.EmbedAsync(embed.Build()).ConfigureAwait(false); + await Context.Channel.EmbedAsync(embed).ConfigureAwait(false); } else if ((match = dndRegex.Match(arg)).Length != 0) { @@ -182,20 +167,17 @@ namespace NadekoBot.Modules.Gambling arr[i] = rng.Next(1, n2 + 1) + add - sub; } - var embed = new EmbedBuilder().WithOkColor().WithDescription($"{umsg.Author.Mention} rolled {n1} {(n1 == 1 ? "die" : "dice")} `1 to {n2}` +`{add}` -`{sub}`") + var embed = new EmbedBuilder().WithOkColor().WithDescription($"{Context.User.Mention} rolled {n1} {(n1 == 1 ? "die" : "dice")} `1 to {n2}` +`{add}` -`{sub}`") .AddField(efb => efb.WithName(Format.Bold("Result")) .WithValue(string.Join(" ", (ordered ? arr.OrderBy(x => x).AsEnumerable() : arr).Select(x => Format.Code(x.ToString()))))); - await channel.EmbedAsync(embed.Build()).ConfigureAwait(false); + await Context.Channel.EmbedAsync(embed).ConfigureAwait(false); } } } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task NRoll(IUserMessage umsg, [Remainder] string range) + public async Task NRoll([Remainder] string range) { - var channel = (ITextChannel)umsg.Channel; - try { int rolled; @@ -214,11 +196,11 @@ namespace NadekoBot.Modules.Gambling rolled = new NadekoRandom().Next(0, int.Parse(range) + 1); } - await channel.SendConfirmAsync($"{umsg.Author.Mention} rolled **{rolled}**.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"{Context.User.Mention} rolled **{rolled}**.").ConfigureAwait(false); } catch (Exception ex) { - await channel.SendErrorAsync($":anger: {ex.Message}").ConfigureAwait(false); + await Context.Channel.SendErrorAsync($":anger: {ex.Message}").ConfigureAwait(false); } } diff --git a/src/NadekoBot/Modules/Gambling/Commands/DrawCommand.cs b/src/NadekoBot/Modules/Gambling/Commands/DrawCommand.cs index 0f76ce41..adbe4913 100644 --- a/src/NadekoBot/Modules/Gambling/Commands/DrawCommand.cs +++ b/src/NadekoBot/Modules/Gambling/Commands/DrawCommand.cs @@ -10,31 +10,24 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Threading.Tasks; +using Image = ImageSharp.Image; namespace NadekoBot.Modules.Gambling { public partial class Gambling { [Group] - public class DrawCommands + public class DrawCommands : ModuleBase { private static readonly ConcurrentDictionary AllDecks = new ConcurrentDictionary(); - - public DrawCommands() - { - _log = LogManager.GetCurrentClassLogger(); - } - private const string cardsPath = "data/images/cards"; - private Logger _log { get; } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task Draw(IUserMessage msg, int num = 1) + public async Task Draw(int num = 1) { - var channel = (ITextChannel)msg.Channel; - var cards = AllDecks.GetOrAdd(channel.Guild, (s) => new Cards()); + var cards = AllDecks.GetOrAdd(Context.Guild, (s) => new Cards()); var images = new List(); var cardObjects = new List(); if (num > 5) num = 5; @@ -42,7 +35,7 @@ namespace NadekoBot.Modules.Gambling { if (cards.CardPool.Count == 0 && i != 0) { - try { await channel.SendErrorAsync("No more cards in a deck.").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); } + try { await Context.Channel.SendErrorAsync("No more cards in a deck.").ConfigureAwait(false); } catch { } break; } var currentCard = cards.DrawACard(); @@ -53,21 +46,20 @@ namespace NadekoBot.Modules.Gambling MemoryStream bitmapStream = new MemoryStream(); images.Merge().SaveAsPng(bitmapStream); bitmapStream.Position = 0; - - var toSend = $"{msg.Author.Mention}"; + var toSend = $"{Context.User.Mention}"; if (cardObjects.Count == 5) toSend += $" drew `{Cards.GetHandValue(cardObjects)}`"; - await channel.SendFileAsync(bitmapStream, images.Count + " cards.jpg", toSend).ConfigureAwait(false); + await Context.Channel.SendFileAsync(bitmapStream, images.Count + " cards.jpg", toSend).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task ShuffleDeck(IUserMessage imsg) + public async Task ShuffleDeck() { - var channel = (ITextChannel)imsg.Channel; + //var channel = (ITextChannel)Context.Channel; - AllDecks.AddOrUpdate(channel.Guild, + AllDecks.AddOrUpdate(Context.Guild, (g) => new Cards(), (g, c) => { @@ -75,7 +67,7 @@ namespace NadekoBot.Modules.Gambling return c; }); - await channel.SendConfirmAsync("Deck reshuffled.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("Deck reshuffled.").ConfigureAwait(false); } } } diff --git a/src/NadekoBot/Modules/Gambling/Commands/FlipCoinCommand.cs b/src/NadekoBot/Modules/Gambling/Commands/FlipCoinCommand.cs index 2c1b9245..3e8c01a5 100644 --- a/src/NadekoBot/Modules/Gambling/Commands/FlipCoinCommand.cs +++ b/src/NadekoBot/Modules/Gambling/Commands/FlipCoinCommand.cs @@ -7,34 +7,33 @@ using NadekoBot.Services; using System; using System.IO; using System.Threading.Tasks; +using Image = ImageSharp.Image; namespace NadekoBot.Modules.Gambling { public partial class Gambling { [Group] - public class FlipCoinCommands + public class FlipCoinCommands : ModuleBase { private static NadekoRandom rng { get; } = new NadekoRandom(); private const string headsPath = "data/images/coins/heads.png"; private const string tailsPath = "data/images/coins/tails.png"; [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Flip(IUserMessage imsg, int count = 1) + public async Task Flip(int count = 1) { - var channel = (ITextChannel)imsg.Channel; if (count == 1) { if (rng.Next(0, 2) == 1) - await channel.SendFileAsync(headsPath, $"{imsg.Author.Mention} flipped " + Format.Code("Heads") + ".").ConfigureAwait(false); + await Context.Channel.SendFileAsync(headsPath, $"{Context.User.Mention} flipped " + Format.Code("Heads") + ".").ConfigureAwait(false); else - await channel.SendFileAsync(tailsPath, $"{imsg.Author.Mention} flipped " + Format.Code("Tails") + ".").ConfigureAwait(false); + await Context.Channel.SendFileAsync(tailsPath, $"{Context.User.Mention} flipped " + Format.Code("Tails") + ".").ConfigureAwait(false); return; } if (count > 10 || count < 1) { - await channel.SendErrorAsync("`Invalid number specified. You can flip 1 to 10 coins.`"); + await Context.Channel.SendErrorAsync("`Invalid number specified. You can flip 1 to 10 coins.`"); return; } var imgs = new Image[count]; @@ -44,29 +43,26 @@ namespace NadekoBot.Modules.Gambling new Image(File.OpenRead(headsPath)) : new Image(File.OpenRead(tailsPath)); } - await channel.SendFileAsync(imgs.Merge().ToStream(), $"{count} coins.png").ConfigureAwait(false); + await Context.Channel.SendFileAsync(imgs.Merge().ToStream(), $"{count} coins.png").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Betflip(IUserMessage umsg, int amount, string guess) + public async Task Betflip(int amount, string guess) { - var channel = (ITextChannel)umsg.Channel; - var guildUser = (IGuildUser)umsg.Author; var guessStr = guess.Trim().ToUpperInvariant(); if (guessStr != "H" && guessStr != "T" && guessStr != "HEADS" && guessStr != "TAILS") return; if (amount < 3) { - await channel.SendErrorAsync($"You can't bet less than 3{Gambling.CurrencySign}.") + await Context.Channel.SendErrorAsync($"You can't bet less than 3{Gambling.CurrencySign}.") .ConfigureAwait(false); return; } - var removed = await CurrencyHandler.RemoveCurrencyAsync(guildUser, "Betflip Gamble", amount, false).ConfigureAwait(false); + var removed = await CurrencyHandler.RemoveCurrencyAsync(Context.User, "Betflip Gamble", amount, false).ConfigureAwait(false); if (!removed) { - await channel.SendErrorAsync($"{guildUser.Mention} You don't have enough {Gambling.CurrencyPluralName}.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync($"{Context.User.Mention} You don't have enough {Gambling.CurrencyPluralName}.").ConfigureAwait(false); return; } //heads = true @@ -89,15 +85,15 @@ namespace NadekoBot.Modules.Gambling if (isHeads == result) { var toWin = (int)Math.Round(amount * 1.8); - str = $"{umsg.Author.Mention}`You guessed it!` You won {toWin}{Gambling.CurrencySign}"; - await CurrencyHandler.AddCurrencyAsync((IGuildUser)umsg.Author, "Betflip Gamble", toWin, false).ConfigureAwait(false); + str = $"{Context.User.Mention}`You guessed it!` You won {toWin}{Gambling.CurrencySign}"; + await CurrencyHandler.AddCurrencyAsync(Context.User, "Betflip Gamble", toWin, false).ConfigureAwait(false); } else { - str = $"{umsg.Author.Mention}`Better luck next time.`"; + str = $"{Context.User.Mention}`Better luck next time.`"; } - await channel.SendFileAsync(imgPathToSend, str).ConfigureAwait(false); + await Context.Channel.SendFileAsync(imgPathToSend, str).ConfigureAwait(false); } } } diff --git a/src/NadekoBot/Modules/Gambling/Gambling.cs b/src/NadekoBot/Modules/Gambling/Gambling.cs index 8c91ae77..b3bbe1bd 100644 --- a/src/NadekoBot/Modules/Gambling/Gambling.cs +++ b/src/NadekoBot/Modules/Gambling/Gambling.cs @@ -6,12 +6,8 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using NadekoBot.Services; -using Discord.WebSocket; using NadekoBot.Services.Database.Models; using System.Collections.Generic; -using NadekoBot.Services.Database; -using NLog; -using System.Diagnostics; namespace NadekoBot.Modules.Gambling { @@ -21,7 +17,7 @@ namespace NadekoBot.Modules.Gambling public static string CurrencyName { get; set; } public static string CurrencyPluralName { get; set; } public static string CurrencySign { get; set; } - + static Gambling() { using (var uow = DbHandler.UnitOfWork()) @@ -44,156 +40,138 @@ namespace NadekoBot.Modules.Gambling [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task Raffle(IUserMessage umsg, [Remainder] IRole role = null) + public async Task Raffle([Remainder] IRole role = null) { - var channel = (ITextChannel)umsg.Channel; - - role = role ?? channel.Guild.EveryoneRole; + role = role ?? Context.Guild.EveryoneRole; var members = role.Members().Where(u => u.Status != UserStatus.Offline && u.Status != UserStatus.Unknown); var membersArray = members as IUser[] ?? members.ToArray(); var usr = membersArray[new NadekoRandom().Next(0, membersArray.Length)]; - await channel.SendConfirmAsync("🎟 Raffled user", $"**{usr.Username}#{usr.Discriminator}** ID: `{usr.Id}`").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("🎟 Raffled user", $"**{usr.Username}#{usr.Discriminator}** ID: `{usr.Id}`").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [Priority(0)] - public async Task Cash(IUserMessage umsg, [Remainder] IUser user = null) + public async Task Cash([Remainder] IUser user = null) { - var channel = umsg.Channel; + user = user ?? Context.User; - user = user ?? umsg.Author; - - await channel.SendConfirmAsync($"{user.Username} has {GetCurrency(user.Id)} {CurrencySign}").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"{user.Username} has {GetCurrency(user.Id)} {CurrencySign}").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [Priority(1)] - public async Task Cash(IUserMessage umsg, ulong userId) + public async Task Cash(ulong userId) { - var channel = umsg.Channel; - - await channel.SendConfirmAsync($"`{userId}` has {GetCurrency(userId)} {CurrencySign}").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"`{userId}` has {GetCurrency(userId)} {CurrencySign}").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task Give(IUserMessage umsg, long amount, [Remainder] IGuildUser receiver) + public async Task Give(long amount, [Remainder] IGuildUser receiver) { - var channel = (ITextChannel)umsg.Channel; - if (amount <= 0 || umsg.Author.Id == receiver.Id) + if (amount <= 0 || Context.User.Id == receiver.Id) return; - var success = await CurrencyHandler.RemoveCurrencyAsync((IGuildUser)umsg.Author, $"Gift to {receiver.Username} ({receiver.Id}).", amount, true).ConfigureAwait(false); + var success = await CurrencyHandler.RemoveCurrencyAsync((IGuildUser)Context.User, $"Gift to {receiver.Username} ({receiver.Id}).", amount, true).ConfigureAwait(false); if (!success) { - await channel.SendErrorAsync($"{umsg.Author.Mention} You don't have enough {Gambling.CurrencyPluralName}.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync($"{Context.User.Mention} You don't have enough {Gambling.CurrencyPluralName}.").ConfigureAwait(false); return; } - await CurrencyHandler.AddCurrencyAsync(receiver, $"Gift from {umsg.Author.Username} ({umsg.Author.Id}).", amount, true).ConfigureAwait(false); - await channel.SendConfirmAsync($"{umsg.Author.Mention} successfully sent {amount} {(amount == 1 ? Gambling.CurrencyName : Gambling.CurrencyPluralName)} to {receiver.Mention}!").ConfigureAwait(false); + await CurrencyHandler.AddCurrencyAsync(receiver, $"Gift from {Context.User.Username} ({Context.User.Id}).", amount, true).ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"{Context.User.Mention} successfully sent {amount} {(amount == 1 ? Gambling.CurrencyName : Gambling.CurrencyPluralName)} to {receiver.Mention}!").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] [OwnerOnly] [Priority(2)] - public Task Award(IUserMessage umsg, int amount, [Remainder] IGuildUser usr) => - Award(umsg, amount, usr.Id); + public Task Award(int amount, [Remainder] IGuildUser usr) => + Award(amount, usr.Id); [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] [OwnerOnly] [Priority(1)] - public async Task Award(IUserMessage umsg, int amount, ulong usrId) + public async Task Award(int amount, ulong usrId) { - var channel = (ITextChannel)umsg.Channel; - if (amount <= 0) return; - await CurrencyHandler.AddCurrencyAsync(usrId, $"Awarded by bot owner. ({umsg.Author.Username}/{umsg.Author.Id})", amount).ConfigureAwait(false); + await CurrencyHandler.AddCurrencyAsync(usrId, $"Awarded by bot owner. ({Context.User.Username}/{Context.User.Id})", amount).ConfigureAwait(false); - await channel.SendConfirmAsync($"{umsg.Author.Mention} successfully awarded {amount} {(amount == 1 ? Gambling.CurrencyName : Gambling.CurrencyPluralName)} to <@{usrId}>!").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"{Context.User.Mention} successfully awarded {amount} {(amount == 1 ? Gambling.CurrencyName : Gambling.CurrencyPluralName)} to <@{usrId}>!").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] [OwnerOnly] [Priority(0)] - public async Task Award(IUserMessage umsg, int amount, [Remainder] IRole role) + public async Task Award(int amount, [Remainder] IRole role) { - var channel = (ITextChannel)umsg.Channel; - var users = channel.Guild.GetUsers() - .Where(u => u.Roles.Contains(role)) + var channel = (ITextChannel)Context.Channel; + var users = (await Context.Guild.GetUsersAsync()) + .Where(u => u.GetRoles().Contains(role)) .ToList(); await Task.WhenAll(users.Select(u => CurrencyHandler.AddCurrencyAsync(u.Id, - $"Awarded by bot owner to **{role.Name}** role. ({umsg.Author.Username}/{umsg.Author.Id})", + $"Awarded by bot owner to **{role.Name}** role. ({Context.User.Username}/{Context.User.Id})", amount))) .ConfigureAwait(false); - await channel.SendConfirmAsync($"Awarded `{amount}` {Gambling.CurrencyPluralName} to `{users.Count}` users from `{role.Name}` role.") + await Context.Channel.SendConfirmAsync($"Awarded `{amount}` {Gambling.CurrencyPluralName} to `{users.Count}` users from `{role.Name}` role.") .ConfigureAwait(false); } - - [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - [OwnerOnly] - public async Task Take(IUserMessage umsg, long amount, [Remainder] IGuildUser user) - { - var channel = (ITextChannel)umsg.Channel; - if (amount <= 0) - return; - - if(await CurrencyHandler.RemoveCurrencyAsync(user, $"Taken by bot owner.({umsg.Author.Username}/{umsg.Author.Id})", amount, true).ConfigureAwait(false)) - await channel.SendConfirmAsync($"{umsg.Author.Mention} successfully took {amount} {(amount == 1? Gambling.CurrencyName : Gambling.CurrencyPluralName)} from {user}!").ConfigureAwait(false); - else - await channel.SendErrorAsync($"{umsg.Author.Mention} was unable to take {amount} {(amount == 1 ? Gambling.CurrencyName : Gambling.CurrencyPluralName)} from {user} because the user doesn't have that much {Gambling.CurrencyPluralName}!").ConfigureAwait(false); - } - [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] [OwnerOnly] - public async Task Take(IUserMessage umsg, long amount, [Remainder] ulong usrId) + public async Task Take(long amount, [Remainder] IGuildUser user) { - var channel = (ITextChannel)umsg.Channel; if (amount <= 0) return; - if(await CurrencyHandler.RemoveCurrencyAsync(usrId, $"Taken by bot owner.({umsg.Author.Username}/{umsg.Author.Id})", amount).ConfigureAwait(false)) - await channel.SendConfirmAsync($"{umsg.Author.Mention} successfully took {amount} {(amount == 1 ? Gambling.CurrencyName : Gambling.CurrencyPluralName)} from <@{usrId}>!").ConfigureAwait(false); + if (await CurrencyHandler.RemoveCurrencyAsync(user, $"Taken by bot owner.({Context.User.Username}/{Context.User.Id})", amount, true).ConfigureAwait(false)) + await Context.Channel.SendConfirmAsync($"{Context.User.Mention} successfully took {amount} {(amount == 1 ? Gambling.CurrencyName : Gambling.CurrencyPluralName)} from {user}!").ConfigureAwait(false); else - await channel.SendErrorAsync($"{umsg.Author.Mention} was unable to take {amount} {(amount == 1 ? Gambling.CurrencyName : Gambling.CurrencyPluralName)} from `{usrId}` because the user doesn't have that much {Gambling.CurrencyPluralName}!").ConfigureAwait(false); + await Context.Channel.SendErrorAsync($"{Context.User.Mention} was unable to take {amount} {(amount == 1 ? Gambling.CurrencyName : Gambling.CurrencyPluralName)} from {user} because the user doesn't have that much {Gambling.CurrencyPluralName}!").ConfigureAwait(false); + } + + + [NadekoCommand, Usage, Description, Aliases] + [OwnerOnly] + public async Task Take(long amount, [Remainder] ulong usrId) + { + if (amount <= 0) + return; + + if (await CurrencyHandler.RemoveCurrencyAsync(usrId, $"Taken by bot owner.({Context.User.Username}/{Context.User.Id})", amount).ConfigureAwait(false)) + await Context.Channel.SendConfirmAsync($"{Context.User.Mention} successfully took {amount} {(amount == 1 ? Gambling.CurrencyName : Gambling.CurrencyPluralName)} from <@{usrId}>!").ConfigureAwait(false); + else + await Context.Channel.SendErrorAsync($"{Context.User.Mention} was unable to take {amount} {(amount == 1 ? Gambling.CurrencyName : Gambling.CurrencyPluralName)} from `{usrId}` because the user doesn't have that much {Gambling.CurrencyPluralName}!").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task BetRoll(IUserMessage umsg, long amount) + public async Task BetRoll(long amount) { - var channel = (ITextChannel)umsg.Channel; - if (amount < 1) return; - var guildUser = (IGuildUser)umsg.Author; - long userFlowers; using (var uow = DbHandler.UnitOfWork()) { - userFlowers = uow.Currency.GetOrCreate(umsg.Author.Id).Amount; + userFlowers = uow.Currency.GetOrCreate(Context.User.Id).Amount; } if (userFlowers < amount) { - await channel.SendErrorAsync($"{guildUser.Mention} You don't have enough {Gambling.CurrencyPluralName}. You only have {userFlowers}{Gambling.CurrencySign}.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync($"{Context.User.Mention} You don't have enough {Gambling.CurrencyPluralName}. You only have {userFlowers}{Gambling.CurrencySign}.").ConfigureAwait(false); return; } - await CurrencyHandler.RemoveCurrencyAsync(guildUser, "Betroll Gamble", amount, false).ConfigureAwait(false); + await CurrencyHandler.RemoveCurrencyAsync(Context.User, "Betroll Gamble", amount, false).ConfigureAwait(false); var rng = new NadekoRandom().Next(0, 101); - var str = $"{guildUser.Mention} `You rolled {rng}.` "; + var str = $"{Context.User.Mention} `You rolled {rng}.` "; if (rng < 67) { str += "Better luck next time."; @@ -201,28 +179,25 @@ namespace NadekoBot.Modules.Gambling else if (rng < 91) { str += $"Congratulations! You won {amount * 2}{Gambling.CurrencySign} for rolling above 66"; - await CurrencyHandler.AddCurrencyAsync(guildUser, "Betroll Gamble", amount * 2, false).ConfigureAwait(false); + await CurrencyHandler.AddCurrencyAsync(Context.User, "Betroll Gamble", amount * 2, false).ConfigureAwait(false); } else if (rng < 100) { str += $"Congratulations! You won {amount * 3}{Gambling.CurrencySign} for rolling above 90."; - await CurrencyHandler.AddCurrencyAsync(guildUser, "Betroll Gamble", amount * 3, false).ConfigureAwait(false); + await CurrencyHandler.AddCurrencyAsync(Context.User, "Betroll Gamble", amount * 3, false).ConfigureAwait(false); } else { str += $"👑 Congratulations! You won {amount * 10}{Gambling.CurrencySign} for rolling **100**. 👑"; - await CurrencyHandler.AddCurrencyAsync(guildUser, "Betroll Gamble", amount * 10, false).ConfigureAwait(false); + await CurrencyHandler.AddCurrencyAsync(Context.User, "Betroll Gamble", amount * 10, false).ConfigureAwait(false); } - await channel.SendConfirmAsync(str).ConfigureAwait(false); + await Context.Channel.SendConfirmAsync(str).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Leaderboard(IUserMessage umsg) + public async Task Leaderboard() { - var channel = (ITextChannel)umsg.Channel; - IEnumerable richest = new List(); using (var uow = DbHandler.UnitOfWork()) { @@ -230,14 +205,14 @@ namespace NadekoBot.Modules.Gambling } if (!richest.Any()) return; - await channel.SendMessageAsync( + await Context.Channel.SendMessageAsync( richest.Aggregate(new StringBuilder( $@"```xl ┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━┓ ┃ Id ┃ $$$ ┃ "), (cur, cs) => cur.AppendLine($@"┣━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━┫ -┃{(channel.Guild.GetUser(cs.UserId)?.Username?.TrimTo(18, true) ?? cs.UserId.ToString()),-20} ┃ {cs.Amount,6} ┃") +┃{(Context.Guild.GetUserAsync(cs.UserId).GetAwaiter().GetResult()?.Username?.TrimTo(18, true) ?? cs.UserId.ToString()),-20} ┃ {cs.Amount,6} ┃") ).ToString() + "┗━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━┛```").ConfigureAwait(false); } } diff --git a/src/NadekoBot/Modules/Games/Commands/Acropobia.cs b/src/NadekoBot/Modules/Games/Commands/Acropobia.cs index 6d27ee78..4160754b 100644 --- a/src/NadekoBot/Modules/Games/Commands/Acropobia.cs +++ b/src/NadekoBot/Modules/Games/Commands/Acropobia.cs @@ -1,5 +1,6 @@ using Discord; using Discord.Commands; +using Discord.WebSocket; using NadekoBot.Attributes; using NadekoBot.Extensions; using NadekoBot.Services; @@ -18,16 +19,16 @@ namespace NadekoBot.Modules.Games public partial class Games { [Group] - public class Acropobia + public class Acropobia : ModuleBase { //channelId, game public static ConcurrentDictionary AcrophobiaGames { get; } = new ConcurrentDictionary(); [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task Acro(IUserMessage imsg, int time = 60) + public async Task Acro(int time = 60) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)Context.Channel; var game = new AcrophobiaGame(channel, time); if (AcrophobiaGames.TryAdd(channel.Id, game)) @@ -123,7 +124,7 @@ namespace NadekoBot.Modules.Games var embed = GetEmbed(); //SUBMISSIONS PHASE - await channel.EmbedAsync(embed.Build()).ConfigureAwait(false); + await channel.EmbedAsync(embed).ConfigureAwait(false); try { await Task.Delay(time * 1000, source.Token).ConfigureAwait(false); @@ -144,13 +145,13 @@ namespace NadekoBot.Modules.Games { await channel.EmbedAsync(new EmbedBuilder().WithOkColor() .WithDescription($"{submissions.First().Value.Mention} is the winner for being the only user who made a submission!") - .WithFooter(efb => efb.WithText(submissions.First().Key.ToLowerInvariant().ToTitleCase())) - .Build()).ConfigureAwait(false); + .WithFooter(efb => efb.WithText(submissions.First().Key.ToLowerInvariant().ToTitleCase()))) + .ConfigureAwait(false); return; } var submissionClosedEmbed = GetEmbed(); - await channel.EmbedAsync(submissionClosedEmbed.Build()).ConfigureAwait(false); + await channel.EmbedAsync(submissionClosedEmbed).ConfigureAwait(false); //VOTING PHASE this.phase = AcroPhase.Voting; @@ -167,11 +168,11 @@ namespace NadekoBot.Modules.Games await End().ConfigureAwait(false); } - private async void PotentialAcro(IMessage arg) + private async void PotentialAcro(SocketMessage arg) { try { - var msg = arg as IUserMessage; + var msg = arg as SocketUserMessage; if (msg == null || msg.Author.IsBot || msg.Channel.Id != channel.Id) return; @@ -186,7 +187,7 @@ namespace NadekoBot.Modules.Games if (spamCount > 10) { spamCount = 0; - try { await channel.EmbedAsync(GetEmbed().Build()).ConfigureAwait(false); } + try { await channel.EmbedAsync(GetEmbed()).ConfigureAwait(false); } catch { } } //user didn't input something already @@ -226,7 +227,7 @@ namespace NadekoBot.Modules.Games if (spamCount > 10) { spamCount = 0; - try { await channel.EmbedAsync(GetEmbed().Build()).ConfigureAwait(false); } + try { await channel.EmbedAsync(GetEmbed()).ConfigureAwait(false); } catch { } } @@ -277,7 +278,7 @@ namespace NadekoBot.Modules.Games .WithDescription($"Winner is {submissions[winner.Key].Mention} with {winner.Value} points.\n") .WithFooter(efb => efb.WithText(winner.Key.ToLowerInvariant().ToTitleCase())); - await channel.EmbedAsync(embed.Build()).ConfigureAwait(false); + await channel.EmbedAsync(embed).ConfigureAwait(false); } public void EnsureStopped() diff --git a/src/NadekoBot/Modules/Games/Commands/CleverBotCommands.cs b/src/NadekoBot/Modules/Games/Commands/CleverBotCommands.cs index 3fd20cf1..9ec59147 100644 --- a/src/NadekoBot/Modules/Games/Commands/CleverBotCommands.cs +++ b/src/NadekoBot/Modules/Games/Commands/CleverBotCommands.cs @@ -1,5 +1,6 @@ using Discord; using Discord.Commands; +using Discord.WebSocket; using NadekoBot.Attributes; using NadekoBot.Extensions; using NadekoBot.Services; @@ -16,11 +17,12 @@ namespace NadekoBot.Modules.Games public partial class Games { [Group] - public class CleverBotCommands + public class CleverBotCommands : ModuleBase { private static Logger _log { get; } - class CleverAnswer { + class CleverAnswer + { public string Status { get; set; } public string Response { get; set; } } @@ -45,7 +47,8 @@ namespace NadekoBot.Modules.Games _log.Debug($"Loaded in {sw.Elapsed.TotalSeconds:F2}s"); } - public static async Task TryAsk(IUserMessage msg) { + public static async Task TryAsk(SocketUserMessage msg) + { var channel = msg.Channel as ITextChannel; if (channel == null) @@ -55,7 +58,7 @@ namespace NadekoBot.Modules.Games if (!CleverbotGuilds.TryGetValue(channel.Guild.Id, out cleverbot)) return false; - var nadekoId = NadekoBot.Client.GetCurrentUser().Id; + var nadekoId = NadekoBot.Client.CurrentUser().Id; var normalMention = $"<@{nadekoId}> "; var nickMention = $"<@!{nadekoId}> "; string message; @@ -88,35 +91,34 @@ namespace NadekoBot.Modules.Games [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(ChannelPermission.ManageMessages)] - public async Task Cleverbot(IUserMessage imsg) + [RequireUserPermission(ChannelPermission.ManageMessages)] + public async Task Cleverbot() { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)Context.Channel; Lazy throwaway; if (CleverbotGuilds.TryRemove(channel.Guild.Id, out throwaway)) { using (var uow = DbHandler.UnitOfWork()) { - uow.GuildConfigs.SetCleverbotEnabled(channel.Guild.Id, false); + uow.GuildConfigs.SetCleverbotEnabled(Context.Guild.Id, false); await uow.CompleteAsync().ConfigureAwait(false); } - await channel.SendConfirmAsync($"{imsg.Author.Mention} Disabled cleverbot on this server.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"{Context.User.Mention} Disabled cleverbot on this server.").ConfigureAwait(false); return; } var cleverbot = ChatterBotFactory.Create(ChatterBotType.CLEVERBOT); - var session = cleverbot.CreateSession(); - CleverbotGuilds.TryAdd(channel.Guild.Id, new Lazy(() => session, true)); + CleverbotGuilds.TryAdd(channel.Guild.Id, new Lazy(() => cleverbot.CreateSession(), true)); using (var uow = DbHandler.UnitOfWork()) { - uow.GuildConfigs.SetCleverbotEnabled(channel.Guild.Id, true); + uow.GuildConfigs.SetCleverbotEnabled(Context.Guild.Id, true); await uow.CompleteAsync().ConfigureAwait(false); } - await channel.SendConfirmAsync($"{imsg.Author.Mention} Enabled cleverbot on this server.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"{Context.User.Mention} Enabled cleverbot on this server.").ConfigureAwait(false); } } } diff --git a/src/NadekoBot/Modules/Games/Commands/Hangman/HangmanGame.cs b/src/NadekoBot/Modules/Games/Commands/Hangman/HangmanGame.cs index ab6daa9e..d096b452 100644 --- a/src/NadekoBot/Modules/Games/Commands/Hangman/HangmanGame.cs +++ b/src/NadekoBot/Modules/Games/Commands/Hangman/HangmanGame.cs @@ -1,4 +1,5 @@ using Discord; +using Discord.WebSocket; using NadekoBot.Extensions; using NadekoBot.Services; using Newtonsoft.Json; @@ -7,7 +8,6 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; -using System.Text; using System.Threading.Tasks; namespace NadekoBot.Modules.Games.Commands.Hangman @@ -121,19 +121,19 @@ namespace NadekoBot.Modules.Games.Commands.Hangman var embed = new EmbedBuilder().WithTitle("Hangman Game") .WithDescription(toSend) .AddField(efb => efb.WithName("It was").WithValue(Term.Word)) - .WithImage(eib => eib.WithUrl(Term.ImageUrl)) + .WithImageUrl(Term.ImageUrl) .WithFooter(efb => efb.WithText(string.Join(" ", Guesses))); if (Errors >= MaxErrors) - await GameChannel.EmbedAsync(embed.WithErrorColor().Build()).ConfigureAwait(false); + await GameChannel.EmbedAsync(embed.WithErrorColor()).ConfigureAwait(false); else - await GameChannel.EmbedAsync(embed.WithOkColor().Build()).ConfigureAwait(false); + await GameChannel.EmbedAsync(embed.WithOkColor()).ConfigureAwait(false); } - private async void PotentialGuess(IMessage msg) + private async void PotentialGuess(SocketMessage msg) { try { - if (!(msg is IUserMessage)) + if (!(msg is SocketUserMessage)) return; if (msg.Channel != GameChannel) diff --git a/src/NadekoBot/Modules/Games/Commands/Hangman/IHangmanObject.cs b/src/NadekoBot/Modules/Games/Commands/Hangman/IHangmanObject.cs index c7be7a2e..c2069477 100644 --- a/src/NadekoBot/Modules/Games/Commands/Hangman/IHangmanObject.cs +++ b/src/NadekoBot/Modules/Games/Commands/Hangman/IHangmanObject.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace NadekoBot.Modules.Games.Commands.Hangman +namespace NadekoBot.Modules.Games.Commands.Hangman { public class HangmanObject { diff --git a/src/NadekoBot/Modules/Games/Commands/HangmanCommands.cs b/src/NadekoBot/Modules/Games/Commands/HangmanCommands.cs index b3041d31..eba11193 100644 --- a/src/NadekoBot/Modules/Games/Commands/HangmanCommands.cs +++ b/src/NadekoBot/Modules/Games/Commands/HangmanCommands.cs @@ -1,54 +1,45 @@ -using Discord; -using Discord.Commands; +using Discord.Commands; using NadekoBot.Attributes; using NadekoBot.Extensions; using NadekoBot.Modules.Games.Commands.Hangman; using NLog; using System; using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Threading.Tasks; namespace NadekoBot.Modules.Games { public partial class Games { - [Group] - public class HangmanCommands + public class HangmanCommands : ModuleBase { private static Logger _log { get; } //channelId, game public static ConcurrentDictionary HangmanGames { get; } = new ConcurrentDictionary(); + private static string typesStr { get; } = ""; static HangmanCommands() { _log = LogManager.GetCurrentClassLogger(); - } - - string typesStr { get; } = ""; - public HangmanCommands() - { typesStr = $"`List of \"{NadekoBot.ModulePrefixes[typeof(Games).Name]}hangman\" term types:`\n" + String.Join(", ", Enum.GetNames(typeof(HangmanTermPool.HangmanTermType))); } [NadekoCommand, Usage, Description, Aliases] - public async Task Hangmanlist(IUserMessage imsg) + public async Task Hangmanlist() { - await imsg.Channel.SendConfirmAsync(typesStr); + await Context.Channel.SendConfirmAsync(typesStr); } [NadekoCommand, Usage, Description, Aliases] - public async Task Hangman(IUserMessage imsg, HangmanTermPool.HangmanTermType type = HangmanTermPool.HangmanTermType.All) + public async Task Hangman(HangmanTermPool.HangmanTermType type = HangmanTermPool.HangmanTermType.All) { - var hm = new HangmanGame(imsg.Channel, type); + var hm = new HangmanGame(Context.Channel, type); - if (!HangmanGames.TryAdd(imsg.Channel.Id, hm)) + if (!HangmanGames.TryAdd(Context.Channel.Id, hm)) { - await imsg.Channel.SendErrorAsync("Hangman game already running on this channel.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("Hangman game already running on this channel.").ConfigureAwait(false); return; } @@ -59,7 +50,7 @@ namespace NadekoBot.Modules.Games }; hm.Start(); - await imsg.Channel.SendConfirmAsync("Hangman game started", hm.ScrambledWord + "\n" + hm.GetHangman() + "\n" + hm.ScrambledWord); + await Context.Channel.SendConfirmAsync("Hangman game started", hm.ScrambledWord + "\n" + hm.GetHangman() + "\n" + hm.ScrambledWord); } } } diff --git a/src/NadekoBot/Modules/Games/Commands/LeetCommands.cs b/src/NadekoBot/Modules/Games/Commands/LeetCommands.cs index f877ebe7..62d2930e 100644 --- a/src/NadekoBot/Modules/Games/Commands/LeetCommands.cs +++ b/src/NadekoBot/Modules/Games/Commands/LeetCommands.cs @@ -13,15 +13,12 @@ namespace NadekoBot.Modules.Games public partial class Games { [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Leet(IUserMessage umsg, int level, [Remainder] string text = null) + public async Task Leet(int level, [Remainder] string text = null) { - var channel = (ITextChannel)umsg.Channel; - text = text.Trim(); if (string.IsNullOrWhiteSpace(text)) return; - await channel.SendConfirmAsync("L33t", ToLeet(text, level).SanitizeMentions()).ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("L33t", ToLeet(text, level).SanitizeMentions()).ConfigureAwait(false); } diff --git a/src/NadekoBot/Modules/Games/Commands/PlantAndPickCommands.cs b/src/NadekoBot/Modules/Games/Commands/PlantAndPickCommands.cs index 31246d71..d7fb96cc 100644 --- a/src/NadekoBot/Modules/Games/Commands/PlantAndPickCommands.cs +++ b/src/NadekoBot/Modules/Games/Commands/PlantAndPickCommands.cs @@ -28,7 +28,7 @@ namespace NadekoBot.Modules.Games /// https://discord.gg/0TYNJfCU4De7YIk8 /// [Group] - public class PlantPickCommands + public class PlantPickCommands : ModuleBase { private static ConcurrentHashSet generationChannels { get; } = new ConcurrentHashSet(); //channelid/message @@ -63,11 +63,11 @@ namespace NadekoBot.Modules.Games _log.Debug($"Loaded in {sw.Elapsed.TotalSeconds:F2}s"); } - private static async void PotentialFlowerGeneration(IMessage imsg) + private static async void PotentialFlowerGeneration(SocketMessage imsg) { try { - var msg = imsg as IUserMessage; + var msg = imsg as SocketUserMessage; if (msg == null || msg.IsAuthor() || msg.Author.IsBot) return; @@ -104,11 +104,11 @@ namespace NadekoBot.Modules.Games [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task Pick(IUserMessage imsg) + public async Task Pick() { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)Context.Channel; - if (!channel.Guild.GetCurrentUser().GetPermissions(channel).ManageMessages || !usersRecentlyPicked.Add(imsg.Author.Id)) + if (!(await channel.Guild.GetCurrentUserAsync()).GetPermissions(channel).ManageMessages || !usersRecentlyPicked.Add(Context.User.Id)) return; try @@ -116,58 +116,56 @@ namespace NadekoBot.Modules.Games List msgs; - try { await imsg.DeleteAsync().ConfigureAwait(false); } catch { } - if (!plantedFlowers.TryRemove(channel.Id, out msgs)) - return; + try { await Context.Message.DeleteAsync().ConfigureAwait(false); } catch { } + if (!plantedFlowers.TryRemove(channel.Id, out msgs)) + return; await Task.WhenAll(msgs.Select(toDelete => toDelete.DeleteAsync())).ConfigureAwait(false); - await CurrencyHandler.AddCurrencyAsync((IGuildUser)imsg.Author, "Picked flower(s).", msgs.Count, false).ConfigureAwait(false); - var msg = await channel.SendConfirmAsync($"**{imsg.Author}** picked {msgs.Count}{Gambling.Gambling.CurrencySign}!").ConfigureAwait(false); + await CurrencyHandler.AddCurrencyAsync((IGuildUser)Context.User, "Picked flower(s).", msgs.Count, false).ConfigureAwait(false); + var msg = await channel.SendConfirmAsync($"**{Context.User}** picked {msgs.Count}{Gambling.Gambling.CurrencySign}!").ConfigureAwait(false); msg.DeleteAfter(10); } finally { await Task.Delay(60000); - usersRecentlyPicked.TryRemove(imsg.Author.Id); + usersRecentlyPicked.TryRemove(Context.User.Id); } } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task Plant(IUserMessage imsg) + public async Task Plant() { - var channel = (ITextChannel)imsg.Channel; - - var removed = await CurrencyHandler.RemoveCurrencyAsync((IGuildUser)imsg.Author, "Planted a flower.", 1, false).ConfigureAwait(false); + var removed = await CurrencyHandler.RemoveCurrencyAsync((IGuildUser)Context.User, "Planted a flower.", 1, false).ConfigureAwait(false); if (!removed) { - await channel.SendErrorAsync($"You don't have any {Gambling.Gambling.CurrencyPluralName}.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync($"You don't have any {Gambling.Gambling.CurrencyPluralName}.").ConfigureAwait(false); return; } var file = GetRandomCurrencyImagePath(); IUserMessage msg; var vowelFirst = new[] { 'a', 'e', 'i', 'o', 'u' }.Contains(Gambling.Gambling.CurrencyName[0]); - - var msgToSend = $"Oh how Nice! **{imsg.Author.Username}** planted {(vowelFirst ? "an" : "a")} {Gambling.Gambling.CurrencyName}. Pick it using {NadekoBot.ModulePrefixes[typeof(Games).Name]}pick"; + + var msgToSend = $"Oh how Nice! **{Context.User.Username}** planted {(vowelFirst ? "an" : "a")} {Gambling.Gambling.CurrencyName}. Pick it using {NadekoBot.ModulePrefixes[typeof(Games).Name]}pick"; if (file == null) { - msg = await channel.SendConfirmAsync(Gambling.Gambling.CurrencySign).ConfigureAwait(false); + msg = await Context.Channel.SendConfirmAsync(Gambling.Gambling.CurrencySign).ConfigureAwait(false); } else { - msg = await channel.SendFileAsync(file, msgToSend).ConfigureAwait(false); + msg = await Context.Channel.SendFileAsync(file, msgToSend).ConfigureAwait(false); } - plantedFlowers.AddOrUpdate(channel.Id, new List() { msg }, (id, old) => { old.Add(msg); return old; }); + plantedFlowers.AddOrUpdate(Context.Channel.Id, new List() { msg }, (id, old) => { old.Add(msg); return old; }); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageMessages)] - public async Task GenCurrency(IUserMessage imsg) + [RequireUserPermission(GuildPermission.ManageMessages)] + public async Task GenCurrency() { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)Context.Channel; bool enabled; using (var uow = DbHandler.UnitOfWork()) diff --git a/src/NadekoBot/Modules/Games/Commands/PollCommands.cs b/src/NadekoBot/Modules/Games/Commands/PollCommands.cs index 07690253..f7321a72 100644 --- a/src/NadekoBot/Modules/Games/Commands/PollCommands.cs +++ b/src/NadekoBot/Modules/Games/Commands/PollCommands.cs @@ -1,5 +1,6 @@ using Discord; using Discord.Commands; +using Discord.WebSocket; using NadekoBot.Attributes; using NadekoBot.Extensions; using System; @@ -13,168 +14,172 @@ namespace NadekoBot.Modules.Games { public partial class Games { - public static ConcurrentDictionary ActivePolls = new ConcurrentDictionary(); - - [NadekoCommand, Usage, Description, Aliases] - [RequirePermission(GuildPermission.ManageMessages)] - [RequireContext(ContextType.Guild)] - public Task Poll(IUserMessage umsg, [Remainder] string arg = null) - => InternalStartPoll(umsg, arg, isPublic: false); - - [NadekoCommand, Usage, Description, Aliases] - [RequirePermission(GuildPermission.ManageMessages)] - [RequireContext(ContextType.Guild)] - public Task PublicPoll(IUserMessage umsg, [Remainder] string arg = null) - => InternalStartPoll(umsg, arg, isPublic: true); - - private async Task InternalStartPoll(IUserMessage umsg, string arg, bool isPublic = false) + [Group] + public class PollCommands : ModuleBase { - var channel = (ITextChannel)umsg.Channel; + public static ConcurrentDictionary ActivePolls = new ConcurrentDictionary(); - if (!(umsg.Author as IGuildUser).GuildPermissions.ManageChannels) - return; - if (string.IsNullOrWhiteSpace(arg) || !arg.Contains(";")) - return; - var data = arg.Split(';'); - if (data.Length < 3) - return; + [NadekoCommand, Usage, Description, Aliases] + [RequireUserPermission(GuildPermission.ManageMessages)] + [RequireContext(ContextType.Guild)] + public Task Poll([Remainder] string arg = null) + => InternalStartPoll(arg, isPublic: false); - var poll = new Poll(umsg, data[0], data.Skip(1), isPublic: isPublic); - if (ActivePolls.TryAdd(channel.Guild, poll)) + [NadekoCommand, Usage, Description, Aliases] + [RequireUserPermission(GuildPermission.ManageMessages)] + [RequireContext(ContextType.Guild)] + public Task PublicPoll([Remainder] string arg = null) + => InternalStartPoll(arg, isPublic: true); + + private async Task InternalStartPoll(string arg, bool isPublic = false) { - await poll.StartPoll().ConfigureAwait(false); - } - else - await channel.SendErrorAsync("Poll is already running on this server.").ConfigureAwait(false); - } + var channel = (ITextChannel)Context.Channel; - [NadekoCommand, Usage, Description, Aliases] - [RequirePermission(GuildPermission.ManageMessages)] - [RequireContext(ContextType.Guild)] - public async Task Pollend(IUserMessage umsg) - { - var channel = (ITextChannel)umsg.Channel; + if (!(Context.User as IGuildUser).GuildPermissions.ManageChannels) + return; + if (string.IsNullOrWhiteSpace(arg) || !arg.Contains(";")) + return; + var data = arg.Split(';'); + if (data.Length < 3) + return; - Poll poll; - ActivePolls.TryRemove(channel.Guild, out poll); - await poll.StopPoll().ConfigureAwait(false); - } - } - - public class Poll - { - private readonly IUserMessage originalMessage; - private readonly IGuild guild; - private readonly string[] answers; - private ConcurrentDictionary participants = new ConcurrentDictionary(); - private readonly string question; - private DateTime started; - private CancellationTokenSource pollCancellationSource = new CancellationTokenSource(); - private readonly bool isPublic; - - public Poll(IUserMessage umsg, string question, IEnumerable enumerable, bool isPublic = false) - { - this.originalMessage = umsg; - this.guild = ((ITextChannel)umsg.Channel).Guild; - this.question = question; - this.answers = enumerable as string[] ?? enumerable.ToArray(); - this.isPublic = isPublic; - } - - public async Task StartPoll() - { - started = DateTime.Now; - NadekoBot.Client.MessageReceived += Vote; - var msgToSend = $"📃**{originalMessage.Author.Username}** has created a poll which requires your attention:\n\n**{question}**\n"; - var num = 1; - msgToSend = answers.Aggregate(msgToSend, (current, answ) => current + $"`{num++}.` **{answ}**\n"); - if (!isPublic) - msgToSend += "\n**Private Message me with the corresponding number of the answer.**"; - else - msgToSend += "\n**Send a Message here with the corresponding number of the answer.**"; - await originalMessage.Channel.SendConfirmAsync(msgToSend).ConfigureAwait(false); - } - - public async Task StopPoll() - { - NadekoBot.Client.MessageReceived -= Vote; - try - { - var results = participants.GroupBy(kvp => kvp.Value) - .ToDictionary(x => x.Key, x => x.Sum(kvp => 1)) - .OrderByDescending(kvp => kvp.Value); - - var totalVotesCast = results.Sum(kvp => kvp.Value); - if (totalVotesCast == 0) + var poll = new Poll(Context.Message, data[0], data.Skip(1), isPublic: isPublic); + if (ActivePolls.TryAdd(channel.Guild, poll)) { - await originalMessage.Channel.SendMessageAsync("📄 **No votes have been cast.**").ConfigureAwait(false); - return; - } - var closeMessage = $"--------------**POLL CLOSED**--------------\n" + - $"📄 , here are the results:\n"; - closeMessage = results.Aggregate(closeMessage, (current, kvp) => current + $"`{kvp.Key}.` **[{answers[kvp.Key - 1]}]**" + - $" has {kvp.Value} votes." + - $"({kvp.Value * 1.0f / totalVotesCast * 100}%)\n"); - - await originalMessage.Channel.SendConfirmAsync($"📄 **Total votes cast**: {totalVotesCast}\n{closeMessage}").ConfigureAwait(false); - } - catch (Exception ex) - { - Console.WriteLine($"Error in poll game {ex}"); - } - } - - private async void Vote(IMessage imsg) - { - try - { - // has to be a user message - var msg = imsg as IUserMessage; - if (msg == null || msg.Author.IsBot) - return; - - // has to be an integer - int vote; - if (!int.TryParse(imsg.Content, out vote)) - return; - if (vote < 1 || vote > answers.Length) - return; - - IMessageChannel ch; - if (isPublic) - { - //if public, channel must be the same the poll started in - if (originalMessage.Channel.Id != imsg.Channel.Id) - return; - ch = imsg.Channel; + await poll.StartPoll().ConfigureAwait(false); } else - { - //if private, channel must be dm channel - if ((ch = msg.Channel as IDMChannel) == null) - return; + await channel.SendErrorAsync("Poll is already running on this server.").ConfigureAwait(false); + } - // user must be a member of the guild this poll is in - var guildUsers = await guild.GetUsersAsync().ConfigureAwait(false); - if (!guildUsers.Any(u => u.Id == imsg.Author.Id)) - return; - } + [NadekoCommand, Usage, Description, Aliases] + [RequireUserPermission(GuildPermission.ManageMessages)] + [RequireContext(ContextType.Guild)] + public async Task Pollend() + { + var channel = (ITextChannel)Context.Channel; - //user can vote only once - if (participants.TryAdd(msg.Author.Id, vote)) + Poll poll; + ActivePolls.TryRemove(channel.Guild, out poll); + await poll.StopPoll().ConfigureAwait(false); + } + } + + public class Poll + { + private readonly IUserMessage originalMessage; + private readonly IGuild guild; + private readonly string[] answers; + private ConcurrentDictionary participants = new ConcurrentDictionary(); + private readonly string question; + private DateTime started; + private CancellationTokenSource pollCancellationSource = new CancellationTokenSource(); + private readonly bool isPublic; + + public Poll(IUserMessage umsg, string question, IEnumerable enumerable, bool isPublic = false) + { + this.originalMessage = umsg; + this.guild = ((ITextChannel)umsg.Channel).Guild; + this.question = question; + this.answers = enumerable as string[] ?? enumerable.ToArray(); + this.isPublic = isPublic; + } + + public async Task StartPoll() + { + started = DateTime.Now; + NadekoBot.Client.MessageReceived += Vote; + var msgToSend = $"📃**{originalMessage.Author.Username}** has created a poll which requires your attention:\n\n**{question}**\n"; + var num = 1; + msgToSend = answers.Aggregate(msgToSend, (current, answ) => current + $"`{num++}.` **{answ}**\n"); + if (!isPublic) + msgToSend += "\n**Private Message me with the corresponding number of the answer.**"; + else + msgToSend += "\n**Send a Message here with the corresponding number of the answer.**"; + await originalMessage.Channel.SendConfirmAsync(msgToSend).ConfigureAwait(false); + } + + public async Task StopPoll() + { + NadekoBot.Client.MessageReceived -= Vote; + try { - if (!isPublic) + var results = participants.GroupBy(kvp => kvp.Value) + .ToDictionary(x => x.Key, x => x.Sum(kvp => 1)) + .OrderByDescending(kvp => kvp.Value); + + var totalVotesCast = results.Sum(kvp => kvp.Value); + if (totalVotesCast == 0) { - await ch.SendConfirmAsync($"Thanks for voting **{msg.Author.Username}**.").ConfigureAwait(false); + await originalMessage.Channel.SendMessageAsync("📄 **No votes have been cast.**").ConfigureAwait(false); + return; + } + var closeMessage = $"--------------**POLL CLOSED**--------------\n" + + $"📄 , here are the results:\n"; + closeMessage = results.Aggregate(closeMessage, (current, kvp) => current + $"`{kvp.Key}.` **[{answers[kvp.Key - 1]}]**" + + $" has {kvp.Value} votes." + + $"({kvp.Value * 1.0f / totalVotesCast * 100}%)\n"); + + await originalMessage.Channel.SendConfirmAsync($"📄 **Total votes cast**: {totalVotesCast}\n{closeMessage}").ConfigureAwait(false); + } + catch (Exception ex) + { + Console.WriteLine($"Error in poll game {ex}"); + } + } + + private async void Vote(SocketMessage imsg) + { + try + { + // has to be a user message + var msg = imsg as SocketUserMessage; + if (msg == null || msg.Author.IsBot) + return; + + // has to be an integer + int vote; + if (!int.TryParse(imsg.Content, out vote)) + return; + if (vote < 1 || vote > answers.Length) + return; + + IMessageChannel ch; + if (isPublic) + { + //if public, channel must be the same the poll started in + if (originalMessage.Channel.Id != imsg.Channel.Id) + return; + ch = imsg.Channel; } else { - var toDelete = await ch.SendConfirmAsync($"{msg.Author.Mention} cast their vote.").ConfigureAwait(false); - toDelete.DeleteAfter(5); + //if private, channel must be dm channel + if ((ch = msg.Channel as IDMChannel) == null) + return; + + // user must be a member of the guild this poll is in + var guildUsers = await guild.GetUsersAsync().ConfigureAwait(false); + if (!guildUsers.Any(u => u.Id == imsg.Author.Id)) + return; + } + + //user can vote only once + if (participants.TryAdd(msg.Author.Id, vote)) + { + if (!isPublic) + { + await ch.SendConfirmAsync($"Thanks for voting **{msg.Author.Username}**.").ConfigureAwait(false); + } + else + { + var toDelete = await ch.SendConfirmAsync($"{msg.Author.Mention} cast their vote.").ConfigureAwait(false); + toDelete.DeleteAfter(5); + } } } + catch { } } - catch { } } } } \ No newline at end of file diff --git a/src/NadekoBot/Modules/Games/Commands/SpeedTypingCommands.cs b/src/NadekoBot/Modules/Games/Commands/SpeedTypingCommands.cs index f3c8cf0b..bb69063f 100644 --- a/src/NadekoBot/Modules/Games/Commands/SpeedTypingCommands.cs +++ b/src/NadekoBot/Modules/Games/Commands/SpeedTypingCommands.cs @@ -1,5 +1,6 @@ using Discord; using Discord.Commands; +using Discord.WebSocket; using NadekoBot.Attributes; using NadekoBot.Extensions; using NadekoBot.Modules.Games.Commands.Models; @@ -105,13 +106,13 @@ namespace NadekoBot.Modules.Games NadekoBot.Client.MessageReceived += AnswerReceived; } - private async void AnswerReceived(IMessage imsg) + private async void AnswerReceived(SocketMessage imsg) { try { if (imsg.Author.IsBot) return; - var msg = imsg as IUserMessage; + var msg = imsg as SocketUserMessage; if (msg == null) return; @@ -125,15 +126,15 @@ namespace NadekoBot.Modules.Games { var wpm = CurrentSentence.Length / WORD_VALUE / sw.Elapsed.Seconds * 60; finishedUserIds.Add(msg.Author.Id); - await Extensions.Extensions.EmbedAsync(this.Channel, (Discord.API.Embed)new EmbedBuilder().WithColor((uint)NadekoBot.OkColor) + await this.Channel.EmbedAsync(new EmbedBuilder().WithOkColor() .WithTitle((string)$"{msg.Author} finished the race!") .AddField(efb => efb.WithName("Place").WithValue($"#{finishedUserIds.Count}").WithIsInline(true)) .AddField(efb => efb.WithName("WPM").WithValue($"{wpm:F2} *[{sw.Elapsed.Seconds.ToString()}sec]*").WithIsInline(true)) - .AddField(efb => efb.WithName((string)"Errors").WithValue((string)distance.ToString()).WithIsInline((bool)true)) - .Build()).ConfigureAwait(false); + .AddField(efb => efb.WithName((string)"Errors").WithValue((string)distance.ToString()).WithIsInline((bool)true))) + .ConfigureAwait(false); if (finishedUserIds.Count % 4 == 0) { - await Extensions.Extensions.SendConfirmAsync(this.Channel, (string)$":exclamation: A lot of people finished, here is the text for those still typing:\n\n**{Format.Sanitize((string)CurrentSentence.Replace((string)" ", (string)" \x200B")).SanitizeMentions()}**").ConfigureAwait(false); + await this.Channel.SendConfirmAsync($":exclamation: A lot of people finished, here is the text for those still typing:\n\n**{Format.Sanitize(CurrentSentence.Replace(" ", " \x200B")).SanitizeMentions()}**").ConfigureAwait(false); } } } @@ -145,9 +146,8 @@ namespace NadekoBot.Modules.Games } [Group] - public class SpeedTypingCommands + public class SpeedTypingCommands : ModuleBase { - public static List TypingArticles { get; } = new List(); const string typingArticlesPath = "data/typing_articles.json"; @@ -156,18 +156,13 @@ namespace NadekoBot.Modules.Games { try { TypingArticles = JsonConvert.DeserializeObject>(File.ReadAllText(typingArticlesPath)); } catch { } } - public static ConcurrentDictionary RunningContests; - - public SpeedTypingCommands() - { - RunningContests = new ConcurrentDictionary(); - } + public static ConcurrentDictionary RunningContests = new ConcurrentDictionary(); [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task TypeStart(IUserMessage msg) + public async Task TypeStart() { - var channel = (ITextChannel)msg.Channel; + var channel = (ITextChannel)Context.Channel; var game = RunningContests.GetOrAdd(channel.Guild.Id, id => new TypingGame(channel)); @@ -186,9 +181,9 @@ namespace NadekoBot.Modules.Games [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task TypeStop(IUserMessage imsg) + public async Task TypeStop() { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)Context.Channel; TypingGame game; if (RunningContests.TryRemove(channel.Guild.Id, out game)) { @@ -202,13 +197,13 @@ namespace NadekoBot.Modules.Games [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] [OwnerOnly] - public async Task Typeadd(IUserMessage imsg, [Remainder] string text) + public async Task Typeadd([Remainder] string text) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)Context.Channel; TypingArticles.Add(new TypingArticle { - Title = $"Text added on {DateTime.UtcNow} by {imsg.Author}", + Title = $"Text added on {DateTime.UtcNow} by {Context.User}", Text = text.SanitizeMentions(), }); @@ -219,9 +214,9 @@ namespace NadekoBot.Modules.Games [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task Typelist(IUserMessage imsg, int page = 1) + public async Task Typelist(int page = 1) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)Context.Channel; if (page < 1) return; @@ -230,7 +225,7 @@ namespace NadekoBot.Modules.Games if (!articles.Any()) { - await channel.SendErrorAsync($"{imsg.Author.Mention} `No articles found on that page.`").ConfigureAwait(false); + await channel.SendErrorAsync($"{Context.User.Mention} `No articles found on that page.`").ConfigureAwait(false); return; } var i = (page - 1) * 15; @@ -241,9 +236,9 @@ namespace NadekoBot.Modules.Games [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] [OwnerOnly] - public async Task Typedel(IUserMessage imsg, int index) + public async Task Typedel(int index) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)Context.Channel; index -= 1; if (index < 0 || index >= TypingArticles.Count) diff --git a/src/NadekoBot/Modules/Games/Commands/Trivia/TriviaGame.cs b/src/NadekoBot/Modules/Games/Commands/Trivia/TriviaGame.cs index 15d0b47f..83b71e1d 100644 --- a/src/NadekoBot/Modules/Games/Commands/Trivia/TriviaGame.cs +++ b/src/NadekoBot/Modules/Games/Commands/Trivia/TriviaGame.cs @@ -1,5 +1,6 @@ using Discord; using Discord.Net; +using Discord.WebSocket; using NadekoBot.Extensions; using NLog; using System; @@ -70,7 +71,7 @@ namespace NadekoBot.Modules.Games.Trivia .AddField(eab => eab.WithName("Category").WithValue(CurrentQuestion.Category)) .AddField(eab => eab.WithName("Question").WithValue(CurrentQuestion.Question)); - questionMessage = await channel.EmbedAsync(questionEmbed.Build()).ConfigureAwait(false); + questionMessage = await channel.EmbedAsync(questionEmbed).ConfigureAwait(false); } catch (HttpException ex) when (ex.StatusCode == System.Net.HttpStatusCode.NotFound || ex.StatusCode == System.Net.HttpStatusCode.Forbidden) { @@ -97,7 +98,7 @@ namespace NadekoBot.Modules.Games.Trivia if (ShowHints) try { - await questionMessage.ModifyAsync(m => m.Embed = questionEmbed.WithFooter(efb => efb.WithText(CurrentQuestion.GetHint())).Build()) + await questionMessage.ModifyAsync(m => m.Embed = questionEmbed.WithFooter(efb => efb.WithText(CurrentQuestion.GetHint()))) .ConfigureAwait(false); } catch (HttpException ex) when (ex.StatusCode == System.Net.HttpStatusCode.NotFound || ex.StatusCode == System.Net.HttpStatusCode.Forbidden) @@ -130,8 +131,7 @@ namespace NadekoBot.Modules.Games.Trivia await channel.EmbedAsync(new EmbedBuilder().WithOkColor() .WithAuthor(eab => eab.WithName("Trivia Game Ended")) .WithTitle("Final Results") - .WithDescription(GetLeaderboard()) - .Build()).ConfigureAwait(false); + .WithDescription(GetLeaderboard())).ConfigureAwait(false); } public async Task StopGame() @@ -142,14 +142,14 @@ namespace NadekoBot.Modules.Games.Trivia try { await channel.SendConfirmAsync("Trivia Game", "Stopping after this question.").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); } } - private async void PotentialGuess(IMessage imsg) + private async void PotentialGuess(SocketMessage imsg) { try { if (imsg.Author.IsBot) return; - var umsg = imsg as IUserMessage; + var umsg = imsg as SocketUserMessage; if (umsg == null) return; diff --git a/src/NadekoBot/Modules/Games/Commands/TriviaCommands.cs b/src/NadekoBot/Modules/Games/Commands/TriviaCommands.cs index 469653a9..6f43ff83 100644 --- a/src/NadekoBot/Modules/Games/Commands/TriviaCommands.cs +++ b/src/NadekoBot/Modules/Games/Commands/TriviaCommands.cs @@ -8,26 +8,26 @@ using System.Collections.Concurrent; using System.Linq; using System.Threading.Tasks; -//todo Rewrite? Fix trivia not stopping bug + namespace NadekoBot.Modules.Games { public partial class Games { [Group] - public class TriviaCommands + public class TriviaCommands : ModuleBase { - public static ConcurrentDictionary RunningTrivias = new ConcurrentDictionary(); + public static ConcurrentDictionary RunningTrivias { get; } = new ConcurrentDictionary(); [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public Task Trivia(IUserMessage umsg, [Remainder] string additionalArgs = "") - => Trivia(umsg, 10, additionalArgs); + public Task Trivia([Remainder] string additionalArgs = "") + => Trivia(10, additionalArgs); [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task Trivia(IUserMessage umsg, int winReq = 10, [Remainder] string additionalArgs = "") + public async Task Trivia(int winReq = 10, [Remainder] string additionalArgs = "") { - var channel = (ITextChannel)umsg.Channel; + var channel = (ITextChannel)Context.Channel; var showHints = !additionalArgs.Contains("nohint"); @@ -45,15 +45,15 @@ namespace NadekoBot.Modules.Games } return; } - - await channel.SendErrorAsync("Trivia game is already running on this server.\n" + trivia.CurrentQuestion).ConfigureAwait(false); + else + await Context.Channel.SendErrorAsync("Trivia game is already running on this server.\n" + trivia.CurrentQuestion).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task Tl(IUserMessage umsg) + public async Task Tl() { - var channel = (ITextChannel)umsg.Channel; + var channel = (ITextChannel)Context.Channel; TriviaGame trivia; if (RunningTrivias.TryGetValue(channel.Guild.Id, out trivia)) @@ -67,9 +67,9 @@ namespace NadekoBot.Modules.Games [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task Tq(IUserMessage umsg) + public async Task Tq() { - var channel = (ITextChannel)umsg.Channel; + var channel = (ITextChannel)Context.Channel; TriviaGame trivia; if (RunningTrivias.TryGetValue(channel.Guild.Id, out trivia)) diff --git a/src/NadekoBot/Modules/Games/Games.cs b/src/NadekoBot/Modules/Games/Games.cs index 021e070b..3278518e 100644 --- a/src/NadekoBot/Modules/Games/Games.cs +++ b/src/NadekoBot/Modules/Games/Games.cs @@ -24,41 +24,32 @@ namespace NadekoBot.Modules.Games [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Choose(IUserMessage umsg, [Remainder] string list = null) + public async Task Choose([Remainder] string list = null) { - var channel = (ITextChannel)umsg.Channel; if (string.IsNullOrWhiteSpace(list)) return; var listArr = list.Split(';'); if (listArr.Count() < 2) return; var rng = new NadekoRandom(); - await channel.SendConfirmAsync("🤔", listArr[rng.Next(0, listArr.Length)]).ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("🤔", listArr[rng.Next(0, listArr.Length)]).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task _8Ball(IUserMessage umsg, [Remainder] string question = null) + public async Task _8Ball([Remainder] string question = null) { - var channel = (ITextChannel)umsg.Channel; - if (string.IsNullOrWhiteSpace(question)) return; var rng = new NadekoRandom(); - await channel.EmbedAsync(new EmbedBuilder().WithOkColor() + await Context.Channel.EmbedAsync(new EmbedBuilder().WithColor(NadekoBot.OkColor) .AddField(efb => efb.WithName("❓ Question").WithValue(question).WithIsInline(false)) - .AddField(efb => efb.WithName("🎱 8Ball").WithValue(_8BallResponses.Shuffle().FirstOrDefault()).WithIsInline(false)) - .Build()); + .AddField(efb => efb.WithName("🎱 8Ball").WithValue(_8BallResponses.Shuffle().FirstOrDefault()).WithIsInline(false))); } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Rps(IUserMessage umsg, string input) + public async Task Rps(string input) { - var channel = (ITextChannel)umsg.Channel; - Func GetRPSPick = (p) => { if (p == 0) @@ -96,20 +87,17 @@ namespace NadekoBot.Modules.Games else if ((pick == 0 && nadekoPick == 1) || (pick == 1 && nadekoPick == 2) || (pick == 2 && nadekoPick == 0)) - msg = $"{NadekoBot.Client.GetCurrentUser().Mention} won! {GetRPSPick(nadekoPick)} beats {GetRPSPick(pick)}"; + msg = $"{NadekoBot.Client.CurrentUser().Mention} won! {GetRPSPick(nadekoPick)} beats {GetRPSPick(pick)}"; else - msg = $"{umsg.Author.Mention} won! {GetRPSPick(pick)} beats {GetRPSPick(nadekoPick)}"; + msg = $"{Context.User.Mention} won! {GetRPSPick(pick)} beats {GetRPSPick(nadekoPick)}"; - await channel.SendConfirmAsync(msg).ConfigureAwait(false); + await Context.Channel.SendConfirmAsync(msg).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Linux(IUserMessage umsg, string guhnoo, string loonix) + public async Task Linux(string guhnoo, string loonix) { - var channel = (ITextChannel)umsg.Channel; - - await channel.SendConfirmAsync( + await Context.Channel.SendConfirmAsync( $@"I'd just like to interject for moment. What you're refering to as {loonix}, is in fact, {guhnoo}/{loonix}, or as I've recently taken to calling it, {guhnoo} plus {loonix}. {loonix} is not an operating system unto itself, but rather another free component of a fully functioning {guhnoo} system made useful by the {guhnoo} corelibs, shell utilities and vital system components comprising a full OS as defined by POSIX. Many computer users run a modified version of the {guhnoo} system every day, without realizing it. Through a peculiar turn of events, the version of {guhnoo} which is widely used today is often called {loonix}, and many of its users are not aware that it is basically the {guhnoo} system, developed by the {guhnoo} Project. diff --git a/src/NadekoBot/Modules/Help/Help.cs b/src/NadekoBot/Modules/Help/Help.cs index 127eeeb2..3d32eaca 100644 --- a/src/NadekoBot/Modules/Help/Help.cs +++ b/src/NadekoBot/Modules/Help/Help.cs @@ -37,29 +37,28 @@ namespace NadekoBot.Modules.Help } [NadekoCommand, Usage, Description, Aliases] - public async Task Modules(IUserMessage umsg) + public async Task Modules() { var embed = new EmbedBuilder().WithOkColor().WithFooter(efb => efb.WithText($" ℹ️ Type `-cmds ModuleName` to get a list of commands in that module. eg `-cmds games`")) - .WithTitle("📜 List Of Modules").WithDescription("\n• " + string.Join("\n• ", NadekoBot.CommandService.Modules.Select(m => m.Name).OrderBy(s=>s))) - .Build(); - await umsg.Channel.EmbedAsync(embed).ConfigureAwait(false); + .WithTitle("📜 List Of Modules").WithDescription("\n• " + string.Join("\n• ", NadekoBot.CommandService.Modules.GroupBy(m => m.GetTopLevelModule()).Select(m => m.Key.Name).OrderBy(s => s))); + await Context.Channel.EmbedAsync(embed).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] - public async Task Commands(IUserMessage umsg, [Remainder] string module = null) + public async Task Commands([Remainder] string module = null) { - var channel = umsg.Channel; + var channel = Context.Channel; module = module?.Trim().ToUpperInvariant(); if (string.IsNullOrWhiteSpace(module)) return; - var cmds = NadekoBot.CommandService.Commands.Where(c => c.Module.Name.ToUpperInvariant().StartsWith(module)) - .OrderBy(c => c.Text) + var cmds = NadekoBot.CommandService.Commands.Where(c => c.Module.GetTopLevelModule().Name.ToUpperInvariant().StartsWith(module)) + .OrderBy(c => c.Aliases.First()) .Distinct(new CommandTextEqualityComparer()) .AsEnumerable(); - var cmdsArray = cmds as Command[] ?? cmds.ToArray(); + var cmdsArray = cmds as CommandInfo[] ?? cmds.ToArray(); if (!cmdsArray.Any()) { await channel.SendErrorAsync("That module does not exist.").ConfigureAwait(false); @@ -67,64 +66,63 @@ namespace NadekoBot.Modules.Help } if (module != "customreactions" && module != "conversations") { - await channel.SendTableAsync("📃 **List Of Commands:**\n", cmdsArray, el => $"{el.Text,-15} {"["+el.Aliases.Skip(1).FirstOrDefault()+"]",-8}").ConfigureAwait(false); + await channel.SendTableAsync("📃 **List Of Commands:**\n", cmdsArray, el => $"{el.Aliases.First(),-15} {"["+el.Aliases.Skip(1).FirstOrDefault()+"]",-8}").ConfigureAwait(false); } else { - await channel.SendMessageAsync("📃 **List Of Commands:**\n• " + string.Join("\n• ", cmdsArray.Select(c => $"{c.Text}"))); + await channel.SendMessageAsync("📃 **List Of Commands:**\n• " + string.Join("\n• ", cmdsArray.Select(c => $"{c.Aliases.First()}"))); } await channel.SendConfirmAsync($"ℹ️ **Type** `\"{NadekoBot.ModulePrefixes[typeof(Help).Name]}h CommandName\"` **to see the help for that specified command.** ***e.g.*** `-h >8ball`").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] - public async Task H(IUserMessage umsg, [Remainder] string comToFind = null) + public async Task H([Remainder] string comToFind = null) { - var channel = umsg.Channel; + var channel = Context.Channel; comToFind = comToFind?.ToLowerInvariant(); if (string.IsNullOrWhiteSpace(comToFind)) { - IMessageChannel ch = channel is ITextChannel ? await ((IGuildUser)umsg.Author).CreateDMChannelAsync() : channel; + IMessageChannel ch = channel is ITextChannel ? await ((IGuildUser)Context.User).CreateDMChannelAsync() : channel; await ch.SendMessageAsync(HelpString).ConfigureAwait(false); return; } - var com = NadekoBot.CommandService.Commands.FirstOrDefault(c => c.Text.ToLowerInvariant() == comToFind || c.Aliases.Select(a=>a.ToLowerInvariant()).Contains(comToFind)); + var com = NadekoBot.CommandService.Commands.FirstOrDefault(c => c.Aliases.Select(a=>a.ToLowerInvariant()).Contains(comToFind)); if (com == null) { await channel.SendErrorAsync("I can't find that command. Please check the **command** and **command prefix** before trying again."); return; } - var str = $"**`{com.Text}`**"; + var str = $"**`{com.Aliases.First()}`**"; var alias = com.Aliases.Skip(1).FirstOrDefault(); if (alias != null) str += $" **/ `{alias}`**"; var embed = new EmbedBuilder() - .AddField(fb => fb.WithIndex(1).WithName(str).WithValue($"{ string.Format(com.Summary, com.Module.Prefix)} { GetCommandRequirements(com)}").WithIsInline(true)) - .AddField(fb => fb.WithIndex(2).WithName("**Usage**").WithValue($"{string.Format(com.Remarks, com.Module.Prefix)}").WithIsInline(false)) - .WithOkColor(); - await channel.EmbedAsync(embed.Build()).ConfigureAwait(false); + .AddField(fb => fb.WithName(str).WithValue($"{ string.Format(com.Summary, com.Module.Aliases.First())} { GetCommandRequirements(com)}").WithIsInline(true)) + .AddField(fb => fb.WithName("**Usage**").WithValue($"{string.Format(com.Remarks, com.Module.Aliases.First())}").WithIsInline(false)) + .WithColor(NadekoBot.OkColor); + await channel.EmbedAsync(embed).ConfigureAwait(false); } - private string GetCommandRequirements(Command cmd) - { - return String.Join(" ", cmd.Source.CustomAttributes - .Where(ca => ca.AttributeType == typeof(OwnerOnlyAttribute) || ca.AttributeType == typeof(RequirePermissionAttribute)) - .Select(ca => - { - if (ca.AttributeType == typeof(OwnerOnlyAttribute)) - return "**Bot Owner only.**"; - else if (ca.AttributeType == typeof(RequirePermissionAttribute)) - return $"**Requires {(GuildPermission)ca.ConstructorArguments.FirstOrDefault().Value} server permission.**".Replace("Guild", "Server"); - else - return $"**Requires {(GuildPermission)ca.ConstructorArguments.FirstOrDefault().Value} channel permission.**".Replace("Guild", "Server"); - })); - } + private string GetCommandRequirements(CommandInfo cmd) => + String.Join(" ", cmd.Preconditions + .Where(ca => ca is OwnerOnlyAttribute || ca is RequireUserPermissionAttribute) + .Select(ca => + { + if (ca is OwnerOnlyAttribute) + return "**Bot Owner only.**"; + var cau = (RequireUserPermissionAttribute)ca; + if (cau.GuildPermission != null) + return $"**Requires {cau.GuildPermission} server permission.**".Replace("Guild", "Server"); + else + return $"**Requires {cau.ChannelPermission} channel permission.**".Replace("Guild", "Server"); + })); [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] [OwnerOnly] - public Task Hgit(IUserMessage umsg) + public Task Hgit() { var helpstr = new StringBuilder(); helpstr.AppendLine("You can support the project on patreon: or paypal: \n"); @@ -132,7 +130,7 @@ namespace NadekoBot.Modules.Help helpstr.AppendLine(string.Join("\n", NadekoBot.CommandService.Modules.Where(m => m.Name.ToLowerInvariant() != "help").OrderBy(m => m.Name).Prepend(NadekoBot.CommandService.Modules.FirstOrDefault(m=>m.Name.ToLowerInvariant()=="help")).Select(m => $"- [{m.Name}](#{m.Name.ToLowerInvariant()})"))); helpstr.AppendLine(); string lastModule = null; - foreach (var com in NadekoBot.CommandService.Commands.OrderBy(com=>com.Module.Name).GroupBy(c=>c.Text).Select(g=>g.First())) + foreach (var com in NadekoBot.CommandService.Commands.OrderBy(com => com.Module.Name).GroupBy(c => c.Aliases.First()).Select(g => g.First())) { if (com.Module.Name != lastModule) { @@ -147,18 +145,18 @@ namespace NadekoBot.Modules.Help helpstr.AppendLine("----------------|--------------|-------"); lastModule = com.Module.Name; } - helpstr.AppendLine($"`{com.Text}` {string.Join(" ", com.Aliases.Skip(1).Select(a=>"`"+a+"`"))} | {string.Format(com.Summary, com.Module.Prefix)} {GetCommandRequirements(com)} | {string.Format(com.Remarks, com.Module.Prefix)}"); + helpstr.AppendLine($"{string.Join(" ", com.Aliases.Select(a => "`" + a + "`"))} | {string.Format(com.Summary, com.Module.GetPrefix())} {GetCommandRequirements(com)} | {string.Format(com.Remarks, com.Module.GetPrefix())}"); } - helpstr = helpstr.Replace(NadekoBot.Client.GetCurrentUser().Username , "@BotName"); + helpstr = helpstr.Replace(NadekoBot.Client.CurrentUser().Username , "@BotName"); File.WriteAllText("../../docs/Commands List.md", helpstr.ToString()); return Task.CompletedTask; } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task Guide(IUserMessage umsg) + public async Task Guide() { - var channel = (ITextChannel)umsg.Channel; + var channel = (ITextChannel)Context.Channel; await channel.SendConfirmAsync( @"**LIST OF COMMANDS**: @@ -167,9 +165,9 @@ namespace NadekoBot.Modules.Help [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task Donate(IUserMessage umsg) + public async Task Donate() { - var channel = (ITextChannel)umsg.Channel; + var channel = (ITextChannel)Context.Channel; await channel.SendConfirmAsync( $@"You can support the NadekoBot project on patreon. or @@ -180,11 +178,11 @@ Don't forget to leave your discord name or id in the message. } } - public class CommandTextEqualityComparer : IEqualityComparer + public class CommandTextEqualityComparer : IEqualityComparer { - public bool Equals(Command x, Command y) => x.Text == y.Text; + public bool Equals(CommandInfo x, CommandInfo y) => x.Aliases.First() == y.Aliases.First(); - public int GetHashCode(Command obj) => obj.Text.GetHashCode(); + public int GetHashCode(CommandInfo obj) => obj.Aliases.First().GetHashCode(); } } diff --git a/src/NadekoBot/Modules/Music/Music.cs b/src/NadekoBot/Modules/Music/Music.cs index 7b9beda2..89ca9451 100644 --- a/src/NadekoBot/Modules/Music/Music.cs +++ b/src/NadekoBot/Modules/Music/Music.cs @@ -19,14 +19,15 @@ using System.Threading; namespace NadekoBot.Modules.Music { - [NadekoModule("Music", "!!", AutoLoad = false)] + [NadekoModule("Music", "!!")] + [DontAutoLoad] public partial class Music : DiscordModule { public static ConcurrentDictionary MusicPlayers { get; } = new ConcurrentDictionary(); public const string MusicDataPath = "data/musicdata"; - public Music() : base() + static Music() { //it can fail if its currenctly opened or doesn't exist. Either way i don't care try { Directory.Delete(MusicDataPath, true); } catch { } @@ -36,39 +37,42 @@ namespace NadekoBot.Modules.Music Directory.CreateDirectory(MusicDataPath); } - private void Client_UserVoiceStateUpdated(IUser iusr, IVoiceState oldState, IVoiceState newState) + private static async void Client_UserVoiceStateUpdated(SocketUser iusr, SocketVoiceState oldState, SocketVoiceState newState) { - var usr = iusr as IGuildUser; + var usr = iusr as SocketGuildUser; if (usr == null || oldState.VoiceChannel == newState.VoiceChannel) return; + MusicPlayer player; if (!MusicPlayers.TryGetValue(usr.Guild.Id, out player)) return; - if ((player.PlaybackVoiceChannel == newState.VoiceChannel && //if joined first, and player paused, unpause - player.Paused && - player.PlaybackVoiceChannel.GetUsers().Count == 2) || // keep in mind bot is in the channel (+1) - (player.PlaybackVoiceChannel == oldState.VoiceChannel && // if left last, and player unpaused, pause - !player.Paused && - player.PlaybackVoiceChannel.GetUsers().Count == 1)) + try { - player.TogglePause(); + var users = await player.PlaybackVoiceChannel.GetUsersAsync().Flatten().ConfigureAwait(false); + if ((player.PlaybackVoiceChannel == newState.VoiceChannel && //if joined first, and player paused, unpause + player.Paused && + users.Count() == 2) || // keep in mind bot is in the channel (+1) + (player.PlaybackVoiceChannel == oldState.VoiceChannel && // if left last, and player unpaused, pause + !player.Paused && + users.Count() == 1)) + { + player.TogglePause(); + } } - return; + catch { } } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public Task Next(IUserMessage umsg, int skipCount = 1) + public Task Next(int skipCount = 1) { - var channel = (ITextChannel)umsg.Channel; - if (skipCount < 1) return Task.CompletedTask; MusicPlayer musicPlayer; - if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) return Task.CompletedTask; - if (musicPlayer.PlaybackVoiceChannel == ((IGuildUser)umsg.Author).VoiceChannel) + if (!MusicPlayers.TryGetValue(Context.Guild.Id, out musicPlayer)) return Task.CompletedTask; + if (musicPlayer.PlaybackVoiceChannel == ((IGuildUser)Context.User).VoiceChannel) { while (--skipCount > 0) { @@ -81,13 +85,11 @@ namespace NadekoBot.Modules.Music [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public Task Stop(IUserMessage umsg) + public Task Stop() { - var channel = (ITextChannel)umsg.Channel; - MusicPlayer musicPlayer; - if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) return Task.CompletedTask; - if (((IGuildUser)umsg.Author).VoiceChannel == musicPlayer.PlaybackVoiceChannel) + if (!MusicPlayers.TryGetValue(Context.Guild.Id, out musicPlayer)) return Task.CompletedTask; + if (((IGuildUser)Context.User).VoiceChannel == musicPlayer.PlaybackVoiceChannel) { musicPlayer.Autoplay = false; musicPlayer.Stop(); @@ -97,10 +99,9 @@ namespace NadekoBot.Modules.Music [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task Destroy(IUserMessage umsg) + public async Task Destroy() { - var channel = (ITextChannel)umsg.Channel; - await channel.SendErrorAsync("This command is temporarily disabled.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("This command is temporarily disabled.").ConfigureAwait(false); /*MusicPlayer musicPlayer; if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) return Task.CompletedTask; @@ -112,13 +113,11 @@ namespace NadekoBot.Modules.Music [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public Task Pause(IUserMessage umsg) + public Task Pause() { - var channel = (ITextChannel)umsg.Channel; - MusicPlayer musicPlayer; - if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) return Task.CompletedTask; - if (((IGuildUser)umsg.Author).VoiceChannel != musicPlayer.PlaybackVoiceChannel) + if (!MusicPlayers.TryGetValue(Context.Guild.Id, out musicPlayer)) return Task.CompletedTask; + if (((IGuildUser)Context.User).VoiceChannel != musicPlayer.PlaybackVoiceChannel) return Task.CompletedTask; musicPlayer.TogglePause(); return Task.CompletedTask; @@ -126,12 +125,12 @@ namespace NadekoBot.Modules.Music [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task Fairplay(IUserMessage umsg) + public async Task Fairplay() { - var channel = (ITextChannel)umsg.Channel; + var channel = (ITextChannel)Context.Channel; MusicPlayer musicPlayer; if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) return; - if (((IGuildUser)umsg.Author).VoiceChannel != musicPlayer.PlaybackVoiceChannel) + if (((IGuildUser)Context.User).VoiceChannel != musicPlayer.PlaybackVoiceChannel) return; var val = musicPlayer.FairPlay = !musicPlayer.FairPlay; @@ -140,39 +139,35 @@ namespace NadekoBot.Modules.Music [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task Queue(IUserMessage umsg, [Remainder] string query) + public async Task Queue([Remainder] string query) { - var channel = (ITextChannel)umsg.Channel; - - await QueueSong(((IGuildUser)umsg.Author), channel, ((IGuildUser)umsg.Author).VoiceChannel, query).ConfigureAwait(false); - if (channel.Guild.GetCurrentUser().GetPermissions(channel).ManageMessages) + await QueueSong(((IGuildUser)Context.User), (ITextChannel)Context.Channel, ((IGuildUser)Context.User).VoiceChannel, query).ConfigureAwait(false); + if ((await Context.Guild.GetCurrentUserAsync()).GetPermissions((IGuildChannel)Context.Channel).ManageMessages) { - umsg.DeleteAfter(10); + Context.Message.DeleteAfter(10); } } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task SoundCloudQueue(IUserMessage umsg, [Remainder] string query) + public async Task SoundCloudQueue([Remainder] string query) { - var channel = (ITextChannel)umsg.Channel; - - await QueueSong(((IGuildUser)umsg.Author), channel, ((IGuildUser)umsg.Author).VoiceChannel, query, musicType: MusicType.Soundcloud).ConfigureAwait(false); - if (channel.Guild.GetCurrentUser().GetPermissions(channel).ManageMessages) + await QueueSong(((IGuildUser)Context.User), (ITextChannel)Context.Channel, ((IGuildUser)Context.User).VoiceChannel, query, musicType: MusicType.Soundcloud).ConfigureAwait(false); + if ((await Context.Guild.GetCurrentUserAsync()).GetPermissions((IGuildChannel)Context.Channel).ManageMessages) { - umsg.DeleteAfter(10); + Context.Message.DeleteAfter(10); } } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task ListQueue(IUserMessage umsg, int page = 1) + public async Task ListQueue(int page = 1) { - var channel = (ITextChannel)umsg.Channel; + MusicPlayer musicPlayer; - if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) + if (!MusicPlayers.TryGetValue(Context.Guild.Id, out musicPlayer)) { - await channel.SendErrorAsync("🎵 No active music player.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("🎵 No active music player.").ConfigureAwait(false); return; } if (page <= 0) @@ -181,7 +176,7 @@ namespace NadekoBot.Modules.Music var currentSong = musicPlayer.CurrentSong; if (currentSong == null) { - await channel.SendErrorAsync("🎵 No active music player.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("🎵 No active music player.").ConfigureAwait(false); return; } @@ -202,7 +197,7 @@ namespace NadekoBot.Modules.Music .Select(v => $"`{++number}.` {v.PrettyFullName}"))) .WithFooter(ef => ef.WithText($"{musicPlayer.PrettyVolume} | {musicPlayer.Playlist.Count} " + $"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {(int)total.TotalHours}h {total.Minutes}m {total.Seconds}s | " + -(musicPlayer.FairPlay? "✔️fairplay" : "✖️fairplay") + $" | " + (maxPlaytime == 0 ? "unlimited" : $"{maxPlaytime}s limit"))) +(musicPlayer.FairPlay ? "✔️fairplay" : "✖️fairplay") + $" | " + (maxPlaytime == 0 ? "unlimited" : $"{maxPlaytime}s limit"))) .WithOkColor(); if (musicPlayer.RepeatSong) @@ -217,17 +212,15 @@ $"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {(int)total.TotalHours}h {tota { embed.WithTitle("🎵 Song queue is full!"); } - await channel.EmbedAsync(embed.Build()).ConfigureAwait(false); + await Context.Channel.EmbedAsync(embed).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task NowPlaying(IUserMessage umsg) + public async Task NowPlaying() { - var channel = (ITextChannel)umsg.Channel; - MusicPlayer musicPlayer; - if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) + if (!MusicPlayers.TryGetValue(Context.Guild.Id, out musicPlayer)) return; var currentSong = musicPlayer.CurrentSong; if (currentSong == null) @@ -237,99 +230,98 @@ $"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {(int)total.TotalHours}h {tota var embed = new EmbedBuilder().WithOkColor() .WithAuthor(eab => eab.WithName("Now Playing").WithMusicIcon()) .WithDescription(currentSong.PrettyName) - .WithThumbnail(tn => tn.Url = currentSong.Thumbnail) + .WithThumbnailUrl(currentSong.Thumbnail) .WithFooter(ef => ef.WithText(musicPlayer.PrettyVolume + " | " + currentSong.PrettyFullTime + $" | {currentSong.PrettyProvider} | {currentSong.QueuerName}")); - await channel.EmbedAsync(embed.Build()).ConfigureAwait(false); + await Context.Channel.EmbedAsync(embed).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task Volume(IUserMessage umsg, int val) + public async Task Volume(int val) { - var channel = (ITextChannel)umsg.Channel; MusicPlayer musicPlayer; - if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) + if (!MusicPlayers.TryGetValue(Context.Guild.Id, out musicPlayer)) return; - if (((IGuildUser)umsg.Author).VoiceChannel != musicPlayer.PlaybackVoiceChannel) + if (((IGuildUser)Context.User).VoiceChannel != musicPlayer.PlaybackVoiceChannel) return; if (val < 0) return; var volume = musicPlayer.SetVolume(val); - await channel.SendConfirmAsync($"🎵 Volume set to {volume}%").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"🎵 Volume set to {volume}%").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task Defvol(IUserMessage umsg, [Remainder] int val) + public async Task Defvol([Remainder] int val) { - var channel = (ITextChannel)umsg.Channel; + if (val < 0 || val > 100) { - await channel.SendErrorAsync("Volume number invalid. Must be between 0 and 100").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("Volume number invalid. Must be between 0 and 100").ConfigureAwait(false); return; } using (var uow = DbHandler.UnitOfWork()) { - uow.GuildConfigs.For(channel.Guild.Id, set => set).DefaultMusicVolume = val / 100.0f; + uow.GuildConfigs.For(Context.Guild.Id, set => set).DefaultMusicVolume = val / 100.0f; uow.Complete(); } - await channel.SendConfirmAsync($"🎵 Default volume set to {val}%").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"🎵 Default volume set to {val}%").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task ShufflePlaylist(IUserMessage umsg) + public async Task ShufflePlaylist() { - var channel = (ITextChannel)umsg.Channel; + MusicPlayer musicPlayer; - if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) + if (!MusicPlayers.TryGetValue(Context.Guild.Id, out musicPlayer)) return; - if (((IGuildUser)umsg.Author).VoiceChannel != musicPlayer.PlaybackVoiceChannel) + if (((IGuildUser)Context.User).VoiceChannel != musicPlayer.PlaybackVoiceChannel) return; if (musicPlayer.Playlist.Count < 2) { - await channel.SendErrorAsync("💢 Not enough songs in order to perform the shuffle.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("💢 Not enough songs in order to perform the shuffle.").ConfigureAwait(false); return; } musicPlayer.Shuffle(); - await channel.SendConfirmAsync("🎵 Songs shuffled.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("🎵 Songs shuffled.").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task Playlist(IUserMessage umsg, [Remainder] string playlist) + public async Task Playlist([Remainder] string playlist) { - var channel = (ITextChannel)umsg.Channel; + var arg = playlist; if (string.IsNullOrWhiteSpace(arg)) return; - if (((IGuildUser)umsg.Author).VoiceChannel?.Guild != channel.Guild) + if (((IGuildUser)Context.User).VoiceChannel?.Guild != Context.Guild) { - await channel.SendErrorAsync("💢 You need to be in a **voice channel** on this server.\n If you are already in a voice channel, try rejoining it.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("💢 You need to be in a **voice channel** on this server.\n If you are already in a voice (ITextChannel)Context.Channel, try rejoining it.").ConfigureAwait(false); return; } var plId = (await NadekoBot.Google.GetPlaylistIdsByKeywordsAsync(arg).ConfigureAwait(false)).FirstOrDefault(); if (plId == null) { - await channel.SendErrorAsync("No search results for that query."); + await Context.Channel.SendErrorAsync("No search results for that query."); return; } var ids = await NadekoBot.Google.GetPlaylistTracksAsync(plId, 500).ConfigureAwait(false); if (!ids.Any()) { - await channel.SendErrorAsync($"🎵 Failed to find any songs.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync($"🎵 Failed to find any songs.").ConfigureAwait(false); return; } var count = ids.Count(); - var msg = await channel.SendMessageAsync($"🎵 Attempting to queue **{count}** songs".SnPl(count) + "...").ConfigureAwait(false); + var msg = await Context.Channel.SendMessageAsync($"🎵 Attempting to queue **{count}** songs".SnPl(count) + "...").ConfigureAwait(false); var cancelSource = new CancellationTokenSource(); - var gusr = (IGuildUser)umsg.Author; + var gusr = (IGuildUser)Context.User; while (ids.Any() && !cancelSource.IsCancellationRequested) { @@ -339,7 +331,7 @@ $"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {(int)total.TotalHours}h {tota return; try { - await QueueSong(gusr, channel, gusr.VoiceChannel, id, true).ConfigureAwait(false); + await QueueSong(gusr, (ITextChannel)Context.Channel, gusr.VoiceChannel, id, true).ConfigureAwait(false); } catch (SongNotFoundException) { } catch { try { cancelSource.Cancel(); } catch { } } @@ -354,9 +346,9 @@ $"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {(int)total.TotalHours}h {tota [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task SoundCloudPl(IUserMessage umsg, [Remainder] string pl) + public async Task SoundCloudPl([Remainder] string pl) { - var channel = (ITextChannel)umsg.Channel; + pl = pl?.Trim(); if (string.IsNullOrWhiteSpace(pl)) @@ -365,10 +357,10 @@ $"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {(int)total.TotalHours}h {tota using (var http = new HttpClient()) { var scvids = JObject.Parse(await http.GetStringAsync($"http://api.soundcloud.com/resolve?url={pl}&client_id={NadekoBot.Credentials.SoundCloudClientId}").ConfigureAwait(false))["tracks"].ToObject(); - await QueueSong(((IGuildUser)umsg.Author), channel, ((IGuildUser)umsg.Author).VoiceChannel, scvids[0].TrackLink).ConfigureAwait(false); + await QueueSong(((IGuildUser)Context.User), (ITextChannel)Context.Channel, ((IGuildUser)Context.User).VoiceChannel, scvids[0].TrackLink).ConfigureAwait(false); MusicPlayer mp; - if (!MusicPlayers.TryGetValue(channel.Guild.Id, out mp)) + if (!MusicPlayers.TryGetValue(Context.Guild.Id, out mp)) return; foreach (var svideo in scvids.Skip(1)) @@ -382,7 +374,7 @@ $"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {(int)total.TotalHours}h {tota Uri = svideo.StreamLink, ProviderType = MusicType.Normal, Query = svideo.TrackLink, - }), ((IGuildUser)umsg.Author).Username); + }), ((IGuildUser)Context.User).Username); } catch (PlaylistFullException) { break; } } @@ -392,9 +384,9 @@ $"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {(int)total.TotalHours}h {tota [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] [OwnerOnly] - public async Task LocalPl(IUserMessage umsg, [Remainder] string directory) + public async Task LocalPl([Remainder] string directory) { - var channel = (ITextChannel)umsg.Channel; + var arg = directory; if (string.IsNullOrWhiteSpace(arg)) return; @@ -403,12 +395,12 @@ $"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {(int)total.TotalHours}h {tota var dir = new DirectoryInfo(arg); var fileEnum = dir.GetFiles("*", SearchOption.AllDirectories) .Where(x => !x.Attributes.HasFlag(FileAttributes.Hidden | FileAttributes.System)); - var gusr = (IGuildUser)umsg.Author; + var gusr = (IGuildUser)Context.User; foreach (var file in fileEnum) { try { - await QueueSong(gusr, channel, gusr.VoiceChannel, file.FullName, true, MusicType.Local).ConfigureAwait(false); + await QueueSong(((IGuildUser)Context.User), (ITextChannel)Context.Channel, ((IGuildUser)Context.User).VoiceChannel, file.FullName, true, MusicType.Local).ConfigureAwait(false); } catch (PlaylistFullException) { @@ -416,49 +408,49 @@ $"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {(int)total.TotalHours}h {tota } catch { } } - await channel.SendConfirmAsync("🎵 Directory queue complete.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("🎵 Directory queue complete.").ConfigureAwait(false); } catch { } } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task Radio(IUserMessage umsg, string radio_link) + public async Task Radio(string radio_link) { - var channel = (ITextChannel)umsg.Channel; - if (((IGuildUser)umsg.Author).VoiceChannel?.Guild != channel.Guild) + + if (((IGuildUser)Context.User).VoiceChannel?.Guild != Context.Guild) { - await channel.SendErrorAsync("💢 You need to be in a voice channel on this server.\n If you are already in a voice channel, try rejoining it.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("💢 You need to be in a voice channel on this server.\n If you are already in a voice (ITextChannel)Context.Channel, try rejoining it.").ConfigureAwait(false); return; } - await QueueSong(((IGuildUser)umsg.Author), channel, ((IGuildUser)umsg.Author).VoiceChannel, radio_link, musicType: MusicType.Radio).ConfigureAwait(false); - if (channel.Guild.GetCurrentUser().GetPermissions(channel).ManageMessages) + await QueueSong(((IGuildUser)Context.User), (ITextChannel)Context.Channel, ((IGuildUser)Context.User).VoiceChannel, radio_link, musicType: MusicType.Radio).ConfigureAwait(false); + if ((await Context.Guild.GetCurrentUserAsync()).GetPermissions((IGuildChannel)Context.Channel).ManageMessages) { - umsg.DeleteAfter(10); + Context.Message.DeleteAfter(10); } } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] [OwnerOnly] - public async Task Local(IUserMessage umsg, [Remainder] string path) + public async Task Local([Remainder] string path) { - var channel = (ITextChannel)umsg.Channel; + var arg = path; if (string.IsNullOrWhiteSpace(arg)) return; - await QueueSong(((IGuildUser)umsg.Author), channel, ((IGuildUser)umsg.Author).VoiceChannel, path, musicType: MusicType.Local).ConfigureAwait(false); + await QueueSong(((IGuildUser)Context.User), (ITextChannel)Context.Channel, ((IGuildUser)Context.User).VoiceChannel, path, musicType: MusicType.Local).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task Move(IUserMessage umsg) + public async Task Move() { - var channel = (ITextChannel)umsg.Channel; + MusicPlayer musicPlayer; - var voiceChannel = ((IGuildUser)umsg.Author).VoiceChannel; - if (voiceChannel == null || voiceChannel.Guild != channel.Guild || !MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) + var voiceChannel = ((IGuildUser)Context.User).VoiceChannel; + if (voiceChannel == null || voiceChannel.Guild != Context.Guild || !MusicPlayers.TryGetValue(Context.Guild.Id, out musicPlayer)) return; await musicPlayer.MoveToVoiceChannel(voiceChannel); } @@ -466,16 +458,16 @@ $"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {(int)total.TotalHours}h {tota [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] [Priority(0)] - public async Task Remove(IUserMessage umsg, int num) + public async Task Remove(int num) { - var channel = (ITextChannel)umsg.Channel; + MusicPlayer musicPlayer; - if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) + if (!MusicPlayers.TryGetValue(Context.Guild.Id, out musicPlayer)) { return; } - if (((IGuildUser)umsg.Author).VoiceChannel != musicPlayer.PlaybackVoiceChannel) + if (((IGuildUser)Context.User).VoiceChannel != musicPlayer.PlaybackVoiceChannel) return; if (num <= 0 || num > musicPlayer.Playlist.Count) return; @@ -489,32 +481,32 @@ $"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {(int)total.TotalHours}h {tota .WithFooter(ef => ef.WithText($"{song.PrettyProvider} | {song.QueuerName}")) .WithErrorColor(); - await channel.EmbedAsync(embed.Build()).ConfigureAwait(false); + await Context.Channel.EmbedAsync(embed).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] [Priority(1)] - public async Task Remove(IUserMessage umsg, string all) + public async Task Remove(string all) { - var channel = (ITextChannel)umsg.Channel; + if (all.Trim().ToUpperInvariant() != "ALL") return; MusicPlayer musicPlayer; - if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) return; + if (!MusicPlayers.TryGetValue(Context.Guild.Id, out musicPlayer)) return; musicPlayer.ClearQueue(); - await channel.SendConfirmAsync($"🎵 Queue cleared!").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"🎵 Queue cleared!").ConfigureAwait(false); return; } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task MoveSong(IUserMessage umsg, [Remainder] string fromto) + public async Task MoveSong([Remainder] string fromto) { - var channel = (ITextChannel)umsg.Channel; + MusicPlayer musicPlayer; - if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) + if (!MusicPlayers.TryGetValue(Context.Guild.Id, out musicPlayer)) { return; } @@ -530,7 +522,7 @@ $"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {(int)total.TotalHours}h {tota !int.TryParse(fromtoArr[1], out n2) || n1 < 1 || n2 < 1 || n1 == n2 || n1 > playlist.Count || n2 > playlist.Count) { - await channel.SendErrorAsync("Invalid input.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("Invalid input.").ConfigureAwait(false); return; } @@ -540,41 +532,44 @@ $"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {(int)total.TotalHours}h {tota playlist.RemoveAt(nn1); var embed = new EmbedBuilder() - .WithTitle(s.SongInfo.Title.TrimTo(70)) - .WithUrl(s.SongInfo.Query) - .WithAuthor(eab => eab.WithName("Song Moved").WithMusicIcon()) + .WithTitle($"{s.SongInfo.Title.TrimTo(70)}") + .WithUrl($"{s.SongInfo.Query}") + .WithAuthor(eab => eab.WithName("Song Moved").WithIconUrl("https://cdn.discordapp.com/attachments/155726317222887425/258605269972549642/music1.png")) .AddField(fb => fb.WithName("**From Position**").WithValue($"#{n1}").WithIsInline(true)) .AddField(fb => fb.WithName("**To Position**").WithValue($"#{n2}").WithIsInline(true)) - .WithFooter(ef => ef.WithText($"{s.PrettyProvider} | {s.QueuerName}")) - .WithOkColor(); - await channel.EmbedAsync(embed.Build()).ConfigureAwait(false); + .WithColor(NadekoBot.OkColor); + await Context.Channel.EmbedAsync(embed).ConfigureAwait(false); + + //await channel.SendConfirmAsync($"🎵Moved {s.PrettyName} `from #{n1} to #{n2}`").ConfigureAwait(false); + + } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task SetMaxQueue(IUserMessage umsg, uint size) + public async Task SetMaxQueue(uint size) { - var channel = (ITextChannel)umsg.Channel; MusicPlayer musicPlayer; - if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) + if (!MusicPlayers.TryGetValue(Context.Guild.Id, out musicPlayer)) return; + musicPlayer.MaxQueueSize = size; - await channel.SendConfirmAsync($"🎵 Max queue set to {(size == 0 ? ("unlimited") : size + " tracks")}."); + await Context.Channel.SendConfirmAsync($"🎵 Max queue set to {(size == 0 ? ("unlimited") : size + " tracks")}."); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task SetMaxPlaytime(IUserMessage imsg, uint seconds) + public async Task SetMaxPlaytime(uint seconds) { if (seconds < 15 && seconds != 0) return; - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)Context.Channel; MusicPlayer musicPlayer; if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) return; musicPlayer.MaxPlaytimeSeconds = seconds; - if(seconds == 0) + if (seconds == 0) await channel.SendConfirmAsync($"🎵 Max playtime has no limit now."); else await channel.SendConfirmAsync($"🎵 Max playtime set to {seconds} seconds."); @@ -582,11 +577,11 @@ $"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {(int)total.TotalHours}h {tota [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task ReptCurSong(IUserMessage umsg) + public async Task ReptCurSong() { - var channel = (ITextChannel)umsg.Channel; + MusicPlayer musicPlayer; - if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) + if (!MusicPlayers.TryGetValue(Context.Guild.Id, out musicPlayer)) return; var currentSong = musicPlayer.CurrentSong; if (currentSong == null) @@ -594,36 +589,35 @@ $"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {(int)total.TotalHours}h {tota var currentValue = musicPlayer.ToggleRepeatSong(); if (currentValue) - await channel.EmbedAsync(new EmbedBuilder() + await Context.Channel.EmbedAsync(new EmbedBuilder() .WithOkColor() .WithAuthor(eab => eab.WithMusicIcon().WithName("🔂 Repeating track")) .WithDescription(currentSong.PrettyName) - .WithFooter(ef => ef.WithText(currentSong.PrettyInfo)) - .Build()).ConfigureAwait(false); + .WithFooter(ef => ef.WithText(currentSong.PrettyInfo))).ConfigureAwait(false); else - await channel.SendConfirmAsync($"🔂 Current track repeat stopped.") + await Context.Channel.SendConfirmAsync($"🔂 Current track repeat stopped.") .ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task RepeatPl(IUserMessage umsg) + public async Task RepeatPl() { - var channel = (ITextChannel)umsg.Channel; + MusicPlayer musicPlayer; - if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) + if (!MusicPlayers.TryGetValue(Context.Guild.Id, out musicPlayer)) return; var currentValue = musicPlayer.ToggleRepeatPlaylist(); - await channel.SendConfirmAsync($"🔁 Repeat playlist {(currentValue ? "**enabled**." : "**disabled**.")}").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"🔁 Repeat playlist {(currentValue ? "**enabled**." : "**disabled**.")}").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task Save(IUserMessage umsg, [Remainder] string name) + public async Task Save([Remainder] string name) { - var channel = (ITextChannel)umsg.Channel; + MusicPlayer musicPlayer; - if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) + if (!MusicPlayers.TryGetValue(Context.Guild.Id, out musicPlayer)) return; var curSong = musicPlayer.CurrentSong; @@ -643,23 +637,21 @@ $"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {(int)total.TotalHours}h {tota playlist = new MusicPlaylist { Name = name, - Author = umsg.Author.Username, - AuthorId = umsg.Author.Id, + Author = Context.User.Username, + AuthorId = Context.User.Id, Songs = songs, }; uow.MusicPlaylists.Add(playlist); await uow.CompleteAsync().ConfigureAwait(false); } - await channel.SendConfirmAsync(($"🎵 Saved playlist as **{name}**, ID: {playlist.Id}.")).ConfigureAwait(false); + await Context.Channel.SendConfirmAsync(($"🎵 Saved playlist as **{name}**, ID: {playlist.Id}.")).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task Load(IUserMessage umsg, [Remainder] int id) + public async Task Load([Remainder] int id) { - var channel = (ITextChannel)umsg.Channel; - MusicPlaylist mpl; using (var uow = DbHandler.UnitOfWork()) { @@ -668,18 +660,17 @@ $"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {(int)total.TotalHours}h {tota if (mpl == null) { - await channel.SendErrorAsync("Can't find playlist with that ID.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("Can't find playlist with that ID.").ConfigureAwait(false); return; } IUserMessage msg = null; - try { msg = await channel.SendMessageAsync($"🎶 Attempting to load **{mpl.Songs.Count}** songs...").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); } - - var usr = (IGuildUser)umsg.Author; + try { msg = await Context.Channel.SendMessageAsync($"🎶 Attempting to load **{mpl.Songs.Count}** songs...").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); } foreach (var item in mpl.Songs) { + var usr = (IGuildUser)Context.User; try { - await QueueSong(usr, channel, usr.VoiceChannel, item.Query, true, item.ProviderType).ConfigureAwait(false); + await QueueSong(usr, (ITextChannel)Context.Channel, usr.VoiceChannel, item.Query, true, item.ProviderType).ConfigureAwait(false); } catch (SongNotFoundException) { } catch { break; } @@ -690,9 +681,9 @@ $"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {(int)total.TotalHours}h {tota [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task Playlists(IUserMessage umsg, [Remainder] int num = 1) + public async Task Playlists([Remainder] int num = 1) { - var channel = (ITextChannel)umsg.Channel; + if (num <= 0) return; @@ -708,16 +699,16 @@ $"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {(int)total.TotalHours}h {tota .WithAuthor(eab => eab.WithName($"Page {num} of Saved Playlists").WithMusicIcon()) .WithDescription(string.Join("\n", playlists.Select(r => $"`#{r.Id}` - **{r.Name}** by *{r.Author}* ({r.Songs.Count} songs)"))) .WithOkColor(); - await channel.EmbedAsync(embed.Build()).ConfigureAwait(false); + await Context.Channel.EmbedAsync(embed).ConfigureAwait(false); } //todo only author or owner [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task DeletePlaylist(IUserMessage umsg, [Remainder] int id) + public async Task DeletePlaylist([Remainder] int id) { - var channel = (ITextChannel)umsg.Channel; + bool success = false; MusicPlaylist pl = null; @@ -729,7 +720,7 @@ $"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {(int)total.TotalHours}h {tota if (pl != null) { - if (NadekoBot.Credentials.IsOwner(umsg.Author) || pl.AuthorId == umsg.Author.Id) + if (NadekoBot.Credentials.IsOwner(Context.User) || pl.AuthorId == Context.User.Id) { uow.MusicPlaylists.Remove(pl); await uow.CompleteAsync().ConfigureAwait(false); @@ -741,9 +732,9 @@ $"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {(int)total.TotalHours}h {tota } if (!success) - await channel.SendErrorAsync("Failed to delete that playlist. It either doesn't exist, or you are not its author.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("Failed to delete that playlist. It either doesn't exist, or you are not its author.").ConfigureAwait(false); else - await channel.SendConfirmAsync("🗑 Playlist successfully **deleted**.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("🗑 Playlist successfully **deleted**.").ConfigureAwait(false); } catch (Exception ex) { @@ -753,14 +744,12 @@ $"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {(int)total.TotalHours}h {tota [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task Goto(IUserMessage umsg, int time) + public async Task Goto(int time) { - var channel = (ITextChannel)umsg.Channel; - MusicPlayer musicPlayer; - if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) + if (!MusicPlayers.TryGetValue(Context.Guild.Id, out musicPlayer)) return; - if (((IGuildUser)umsg.Author).VoiceChannel != musicPlayer.PlaybackVoiceChannel) + if (((IGuildUser)Context.User).VoiceChannel != musicPlayer.PlaybackVoiceChannel) return; if (time < 0) @@ -785,22 +774,21 @@ $"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {(int)total.TotalHours}h {tota if (seconds.Length == 1) seconds = "0" + seconds; - await channel.SendConfirmAsync($"Skipped to `{minutes}:{seconds}`").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"Skipped to `{minutes}:{seconds}`").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task Autoplay(IUserMessage umsg) + public async Task Autoplay() { - var channel = (ITextChannel)umsg.Channel; MusicPlayer musicPlayer; - if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) + if (!MusicPlayers.TryGetValue(Context.Guild.Id, out musicPlayer)) return; if (!musicPlayer.ToggleAutoplay()) - await channel.SendConfirmAsync("❌ Autoplay disabled.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("❌ Autoplay disabled.").ConfigureAwait(false); else - await channel.SendConfirmAsync("✅ Autoplay enabled.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("✅ Autoplay enabled.").ConfigureAwait(false); } public static async Task QueueSong(IGuildUser queuer, ITextChannel textCh, IVoiceChannel voiceCh, string query, bool silent = false, MusicType musicType = MusicType.Normal) @@ -808,7 +796,7 @@ $"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {(int)total.TotalHours}h {tota if (voiceCh == null || voiceCh.Guild != textCh.Guild) { if (!silent) - await textCh.SendErrorAsync("💢 You need to be in a voice channel on this server.\n If you are already in a voice channel, try rejoining.").ConfigureAwait(false); + await textCh.SendErrorAsync("💢 You need to be in a voice channel on this server.\n If you are already in a voice (ITextChannel)Context.Channel, try rejoining.").ConfigureAwait(false); throw new ArgumentNullException(nameof(voiceCh)); } if (string.IsNullOrWhiteSpace(query) || query.Length < 3) @@ -822,30 +810,28 @@ $"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {(int)total.TotalHours}h {tota vol = uow.GuildConfigs.For(textCh.Guild.Id, set => set).DefaultMusicVolume; } var mp = new MusicPlayer(voiceCh, vol); - - IUserMessage finishedMessage = null; + IUserMessage playingMessage = null; + IUserMessage lastFinishedMessage = null; mp.OnCompleted += async (s, song) => { try { - if (finishedMessage != null) - finishedMessage.DeleteAfter(0); + if (lastFinishedMessage != null) + lastFinishedMessage.DeleteAfter(0); - finishedMessage = await textCh.EmbedAsync(new EmbedBuilder().WithOkColor() + lastFinishedMessage = await textCh.EmbedAsync(new EmbedBuilder().WithOkColor() .WithAuthor(eab => eab.WithName("Finished Song").WithMusicIcon()) .WithDescription(song.PrettyName) - .WithFooter(ef => ef.WithText(song.PrettyInfo)) - .Build()) - .ConfigureAwait(false); + .WithFooter(ef => ef.WithText(song.PrettyInfo))) + .ConfigureAwait(false); if (mp.Autoplay && mp.Playlist.Count == 0 && song.SongInfo.Provider == "YouTube") { - await QueueSong(queuer.Guild.GetCurrentUser(), textCh, voiceCh, (await NadekoBot.Google.GetRelatedVideosAsync(song.SongInfo.Query, 4)).ToList().Shuffle().FirstOrDefault(), silent, musicType).ConfigureAwait(false); + await QueueSong(await queuer.Guild.GetCurrentUserAsync(), textCh, voiceCh, (await NadekoBot.Google.GetRelatedVideosAsync(song.SongInfo.Query, 4)).ToList().Shuffle().FirstOrDefault(), silent, musicType).ConfigureAwait(false); } } catch { } }; - IUserMessage playingMessage = null; mp.OnStarted += async (player, song) => { @@ -861,31 +847,22 @@ $"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {(int)total.TotalHours}h {tota playingMessage = await textCh.EmbedAsync(new EmbedBuilder().WithOkColor() .WithAuthor(eab => eab.WithName("Playing Song").WithMusicIcon()) .WithDescription(song.PrettyName) - .WithFooter(ef => ef.WithText(song.PrettyInfo)) - .Build()) + .WithFooter(ef => ef.WithText(song.PrettyInfo))) .ConfigureAwait(false); } catch { } }; - mp.OnPauseChanged += async (paused) => - { - try - { - IUserMessage pauseMessage = null; - if (paused) { - pauseMessage = await textCh.SendConfirmAsync("🎵 Music playback **paused**.").ConfigureAwait(false); - } - else - { - pauseMessage = await textCh.SendConfirmAsync("🎵 Music playback **resumed**.").ConfigureAwait(false); - } - if (pauseMessage != null) - pauseMessage.DeleteAfter(15); - } - catch { } - }; + try + { + if (paused) + await textCh.SendConfirmAsync("🎵 Music playback **paused**.").ConfigureAwait(false); + else + await textCh.SendConfirmAsync("🎵 Music playback **resumed**.").ConfigureAwait(false); + } + catch { } + }; return mp; }); Song resolvedSong; @@ -912,9 +889,8 @@ $"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {(int)total.TotalHours}h {tota var queuedMessage = await textCh.EmbedAsync(new EmbedBuilder().WithOkColor() .WithAuthor(eab => eab.WithName("Queued Song #" + (musicPlayer.Playlist.Count + 1)).WithMusicIcon()) .WithDescription($"{resolvedSong.PrettyName}\nQueue ") - .WithThumbnail(tn => tn.Url = resolvedSong.Thumbnail) - .WithFooter(ef => ef.WithText(resolvedSong.PrettyProvider)) - .Build()) + .WithThumbnailUrl(resolvedSong.Thumbnail) + .WithFooter(ef => ef.WithText(resolvedSong.PrettyProvider))) .ConfigureAwait(false); if (queuedMessage != null) queuedMessage.DeleteAfter(10); diff --git a/src/NadekoBot/Modules/NSFW/NSFW.cs b/src/NadekoBot/Modules/NSFW/NSFW.cs index 2268393f..4c4ce138 100644 --- a/src/NadekoBot/Modules/NSFW/NSFW.cs +++ b/src/NadekoBot/Modules/NSFW/NSFW.cs @@ -19,19 +19,10 @@ namespace NadekoBot.Modules.NSFW [NadekoModule("NSFW", "~")] public class NSFW : DiscordModule { - //ulong/cancel private static ConcurrentDictionary AutoHentaiTimers { get; } = new ConcurrentDictionary(); - public NSFW() : base() + private async Task InternalHentai(IMessageChannel channel, string tag, bool noError) { - } - - [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Hentai(IUserMessage umsg, [Remainder] string tag = null) - { - var channel = (ITextChannel)umsg.Channel; - tag = tag?.Trim() ?? ""; tag = "rating%3Aexplicit+" + tag; @@ -58,25 +49,27 @@ namespace NadekoBot.Modules.NSFW var link = await provider.ConfigureAwait(false); if (string.IsNullOrWhiteSpace(link)) await channel.SendErrorAsync("No results found.").ConfigureAwait(false); - else + else if (!noError) await channel.EmbedAsync(new EmbedBuilder().WithOkColor() .WithImageUrl(link) - .WithDescription("Tag: " + tag) - .Build()).ConfigureAwait(false); + .WithDescription("Tag: " + tag)).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task AutoHentai(IUserMessage umsg, int interval = 0, string tags = null) + public Task Hentai([Remainder] string tag = null) => + InternalHentai(Context.Channel, tag, false); + + [NadekoCommand, Usage, Description, Aliases] + public async Task AutoHentai(int interval = 0, string tags = null) { Timer t; if (interval == 0) { - if (AutoHentaiTimers.TryRemove(umsg.Channel.Id, out t)) + if (AutoHentaiTimers.TryRemove(Context.Channel.Id, out t)) { t.Change(Timeout.Infinite, Timeout.Infinite); //proper way to disable the timer - await umsg.Channel.SendConfirmAsync("Autohentai stopped.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("Autohentai stopped.").ConfigureAwait(false); } return; } @@ -91,28 +84,27 @@ namespace NadekoBot.Modules.NSFW try { if (tagsArr == null || tagsArr.Length == 0) - await Hentai(umsg, null).ConfigureAwait(false); + await InternalHentai(Context.Channel, null, true).ConfigureAwait(false); else - await Hentai(umsg, tagsArr[new NadekoRandom().Next(0, tagsArr.Length)]); + await InternalHentai(Context.Channel, tagsArr[new NadekoRandom().Next(0, tagsArr.Length)], true); } catch { } }, null, interval * 1000, interval * 1000); - AutoHentaiTimers.AddOrUpdate(umsg.Channel.Id, t, (key, old) => + AutoHentaiTimers.AddOrUpdate(Context.Channel.Id, t, (key, old) => { old.Change(Timeout.Infinite, Timeout.Infinite); return t; }); - await umsg.Channel.SendConfirmAsync($"Autohentai started. Reposting every {interval}s with one of the following tags:\n{string.Join(", ", tagsArr)}").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"Autohentai started. Reposting every {interval}s with one of the following tags:\n{string.Join(", ", tagsArr)}").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task HentaiBomb(IUserMessage umsg, [Remainder] string tag = null) + public async Task HentaiBomb([Remainder] string tag = null) { - var channel = (ITextChannel)umsg.Channel; + var channel = (ITextChannel)Context.Channel; tag = tag?.Trim() ?? ""; tag = "rating%3Aexplicit+" + tag; @@ -133,79 +125,64 @@ namespace NadekoBot.Modules.NSFW [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Danbooru(IUserMessage umsg, [Remainder] string tag = null) + public async Task Danbooru([Remainder] string tag = null) { - var channel = (ITextChannel)umsg.Channel; + var channel = (ITextChannel)Context.Channel; tag = tag?.Trim() ?? ""; var url = await GetDanbooruImageLink(tag).ConfigureAwait(false); if (url == null) - await channel.SendErrorAsync(umsg.Author.Mention + " No results."); + await channel.SendErrorAsync(Context.User.Mention + " No results."); else await channel.EmbedAsync(new EmbedBuilder().WithOkColor() - .WithDescription(umsg.Author.Mention + " " + tag) + .WithDescription(Context.User.Mention + " " + tag) .WithImageUrl(url) - .WithFooter(efb => efb.WithText("Danbooru")) - .Build()).ConfigureAwait(false); + .WithFooter(efb => efb.WithText("Danbooru"))).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public Task Yandere(IUserMessage umsg, [Remainder] string tag = null) - => Searches.Searches.InternalDapiCommand(umsg, tag, Searches.Searches.DapiSearchType.Yandere); + public Task Yandere([Remainder] string tag = null) + => Searches.Searches.InternalDapiCommand(Context.Message, tag, Searches.Searches.DapiSearchType.Yandere); [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public Task Konachan(IUserMessage umsg, [Remainder] string tag = null) - => Searches.Searches.InternalDapiCommand(umsg, tag, Searches.Searches.DapiSearchType.Konachan); + public Task Konachan([Remainder] string tag = null) + => Searches.Searches.InternalDapiCommand(Context.Message, tag, Searches.Searches.DapiSearchType.Konachan); [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public Task Gelbooru(IUserMessage umsg, [Remainder] string tag = null) - => Searches.Searches.InternalDapiCommand(umsg, tag, Searches.Searches.DapiSearchType.Gelbooru); + public Task Gelbooru([Remainder] string tag = null) + => Searches.Searches.InternalDapiCommand(Context.Message, tag, Searches.Searches.DapiSearchType.Gelbooru); [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public Task Rule34(IUserMessage umsg, [Remainder] string tag = null) - => Searches.Searches.InternalDapiCommand(umsg, tag, Searches.Searches.DapiSearchType.Rule34); + public Task Rule34([Remainder] string tag = null) + => Searches.Searches.InternalDapiCommand(Context.Message, tag, Searches.Searches.DapiSearchType.Rule34); [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task E621(IUserMessage umsg, [Remainder] string tag = null) + public async Task E621([Remainder] string tag = null) { - var channel = (ITextChannel)umsg.Channel; - tag = tag?.Trim() ?? ""; var url = await GetE621ImageLink(tag).ConfigureAwait(false); if (url == null) - await channel.SendErrorAsync(umsg.Author.Mention + " No results."); + await Context.Channel.SendErrorAsync(Context.User.Mention + " No results."); else - await channel.EmbedAsync(new EmbedBuilder().WithOkColor() - .WithDescription(umsg.Author.Mention + " " + tag) + await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor() + .WithDescription(Context.User.Mention + " " + tag) .WithImageUrl(url) - .WithFooter(efb => efb.WithText("e621")) - .Build()).ConfigureAwait(false); + .WithFooter(efb => efb.WithText("e621"))).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Cp(IUserMessage umsg) + public async Task Cp() { - var channel = (ITextChannel)umsg.Channel; - - await channel.SendMessageAsync("http://i.imgur.com/MZkY1md.jpg").ConfigureAwait(false); + await Context.Channel.SendMessageAsync("http://i.imgur.com/MZkY1md.jpg").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Boobs(IUserMessage umsg) + public async Task Boobs() { - var channel = (ITextChannel)umsg.Channel; try { JToken obj; @@ -213,20 +190,17 @@ namespace NadekoBot.Modules.NSFW { obj = JArray.Parse(await http.GetStringAsync($"http://api.oboobs.ru/boobs/{ new NadekoRandom().Next(0, 10229) }").ConfigureAwait(false))[0]; } - await channel.SendMessageAsync($"http://media.oboobs.ru/{ obj["preview"].ToString() }").ConfigureAwait(false); + await Context.Channel.SendMessageAsync($"http://media.oboobs.ru/{ obj["preview"].ToString() }").ConfigureAwait(false); } catch (Exception ex) { - await channel.SendErrorAsync(ex.Message).ConfigureAwait(false); + await Context.Channel.SendErrorAsync(ex.Message).ConfigureAwait(false); } } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Butts(IUserMessage umsg) + public async Task Butts() { - var channel = (ITextChannel)umsg.Channel; - try { JToken obj; @@ -234,11 +208,11 @@ namespace NadekoBot.Modules.NSFW { obj = JArray.Parse(await http.GetStringAsync($"http://api.obutts.ru/butts/{ new NadekoRandom().Next(0, 4222) }").ConfigureAwait(false))[0]; } - await channel.SendMessageAsync($"http://media.obutts.ru/{ obj["preview"].ToString() }").ConfigureAwait(false); + await Context.Channel.SendMessageAsync($"http://media.obutts.ru/{ obj["preview"].ToString() }").ConfigureAwait(false); } catch (Exception ex) { - await channel.SendErrorAsync(ex.Message).ConfigureAwait(false); + await Context.Channel.SendErrorAsync(ex.Message).ConfigureAwait(false); } } diff --git a/src/NadekoBot/Modules/Permissions/Commands/BlacklistCommands.cs b/src/NadekoBot/Modules/Permissions/Commands/BlacklistCommands.cs index af856f9b..72c41bc3 100644 --- a/src/NadekoBot/Modules/Permissions/Commands/BlacklistCommands.cs +++ b/src/NadekoBot/Modules/Permissions/Commands/BlacklistCommands.cs @@ -21,7 +21,7 @@ namespace NadekoBot.Modules.Permissions } [Group] - public class BlacklistCommands + public class BlacklistCommands : ModuleBase { public static ConcurrentHashSet BlacklistedItems { get; set; } = new ConcurrentHashSet(); @@ -35,33 +35,31 @@ namespace NadekoBot.Modules.Permissions [NadekoCommand, Usage, Description, Aliases] [OwnerOnly] - public Task UserBlacklist(IUserMessage imsg, AddRemove action, ulong id) - => Blacklist(imsg, action, id, BlacklistType.User); + public Task UserBlacklist(AddRemove action, ulong id) + => Blacklist(action, id, BlacklistType.User); [NadekoCommand, Usage, Description, Aliases] [OwnerOnly] - public Task UserBlacklist(IUserMessage imsg, AddRemove action, IUser usr) - => Blacklist(imsg, action, usr.Id, BlacklistType.User); + public Task UserBlacklist(AddRemove action, IUser usr) + => Blacklist(action, usr.Id, BlacklistType.User); [NadekoCommand, Usage, Description, Aliases] [OwnerOnly] - public Task ChannelBlacklist(IUserMessage imsg, AddRemove action, ulong id) - => Blacklist(imsg, action, id, BlacklistType.Channel); + public Task ChannelBlacklist(AddRemove action, ulong id) + => Blacklist(action, id, BlacklistType.Channel); [NadekoCommand, Usage, Description, Aliases] [OwnerOnly] - public Task ServerBlacklist(IUserMessage imsg, AddRemove action, ulong id) - => Blacklist(imsg, action, id, BlacklistType.Server); + public Task ServerBlacklist(AddRemove action, ulong id) + => Blacklist(action, id, BlacklistType.Server); [NadekoCommand, Usage, Description, Aliases] [OwnerOnly] - public Task ServerBlacklist(IUserMessage imsg, AddRemove action, IGuild guild) - => Blacklist(imsg, action, guild.Id, BlacklistType.Server); + public Task ServerBlacklist(AddRemove action, IGuild guild) + => Blacklist(action, guild.Id, BlacklistType.Server); - private async Task Blacklist(IUserMessage imsg, AddRemove action, ulong id, BlacklistType type) + private async Task Blacklist(AddRemove action, ulong id, BlacklistType type) { - var channel = imsg.Channel; - using (var uow = DbHandler.UnitOfWork()) { if (action == AddRemove.Add) @@ -106,9 +104,9 @@ namespace NadekoBot.Modules.Permissions } if(action == AddRemove.Add) - await channel.SendConfirmAsync($"Blacklisted a `{type}` with id `{id}`").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"Blacklisted a `{type}` with id `{id}`").ConfigureAwait(false); else - await channel.SendConfirmAsync($"Unblacklisted a `{type}` with id `{id}`").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"Unblacklisted a `{type}` with id `{id}`").ConfigureAwait(false); } } } diff --git a/src/NadekoBot/Modules/Permissions/Commands/CmdCdsCommands.cs b/src/NadekoBot/Modules/Permissions/Commands/CmdCdsCommands.cs index e8d5adb6..d00972eb 100644 --- a/src/NadekoBot/Modules/Permissions/Commands/CmdCdsCommands.cs +++ b/src/NadekoBot/Modules/Permissions/Commands/CmdCdsCommands.cs @@ -21,7 +21,7 @@ namespace NadekoBot.Modules.Permissions } [Group] - public class CmdCdsCommands + public class CmdCdsCommands : ModuleBase { public static ConcurrentDictionary> commandCooldowns { get; } private static ConcurrentDictionary> activeCooldowns { get; } = new ConcurrentDictionary>(); @@ -33,9 +33,9 @@ namespace NadekoBot.Modules.Permissions } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task CmdCooldown(IUserMessage imsg, Command command, int secs) + public async Task CmdCooldown(CommandInfo command, int secs) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)Context.Channel; if (secs < 0 || secs > 3600) { await channel.SendErrorAsync("Invalid second parameter. (Must be a number between 0 and 3600)").ConfigureAwait(false); @@ -47,13 +47,13 @@ namespace NadekoBot.Modules.Permissions var config = uow.GuildConfigs.For(channel.Guild.Id, set => set.Include(gc => gc.CommandCooldowns)); var localSet = commandCooldowns.GetOrAdd(channel.Guild.Id, new ConcurrentHashSet()); - config.CommandCooldowns.RemoveWhere(cc => cc.CommandName == command.Text.ToLowerInvariant()); - localSet.RemoveWhere(cc => cc.CommandName == command.Text.ToLowerInvariant()); + config.CommandCooldowns.RemoveWhere(cc => cc.CommandName == command.Aliases.First().ToLowerInvariant()); + localSet.RemoveWhere(cc => cc.CommandName == command.Aliases.First().ToLowerInvariant()); if (secs != 0) { var cc = new CommandCooldown() { - CommandName = command.Text.ToLowerInvariant(), + CommandName = command.Aliases.First().ToLowerInvariant(), Seconds = secs, }; config.CommandCooldowns.Add(cc); @@ -64,7 +64,7 @@ namespace NadekoBot.Modules.Permissions if (secs == 0) { var activeCds = activeCooldowns.GetOrAdd(channel.Guild.Id, new ConcurrentHashSet()); - activeCds.RemoveWhere(ac => ac.Command == command.Text.ToLowerInvariant()); + activeCds.RemoveWhere(ac => ac.Command == command.Aliases.First().ToLowerInvariant()); await channel.SendConfirmAsync($"🚮 Command **{command}** has no coooldown now and all existing cooldowns have been cleared.") .ConfigureAwait(false); } @@ -77,9 +77,9 @@ namespace NadekoBot.Modules.Permissions [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task AllCmdCooldowns(IUserMessage imsg) + public async Task AllCmdCooldowns() { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)Context.Channel; var localSet = commandCooldowns.GetOrAdd(channel.Guild.Id, new ConcurrentHashSet()); if (!localSet.Any()) @@ -88,16 +88,16 @@ namespace NadekoBot.Modules.Permissions await channel.SendTableAsync("", localSet.Select(c => c.CommandName + ": " + c.Seconds + " secs"), s => $"{s,-30}", 2).ConfigureAwait(false); } - public static bool HasCooldown(Command cmd, IGuild guild, IUser user) + public static bool HasCooldown(CommandInfo cmd, IGuild guild, IUser user) { if (guild == null) return false; var cmdcds = CmdCdsCommands.commandCooldowns.GetOrAdd(guild.Id, new ConcurrentHashSet()); CommandCooldown cdRule; - if ((cdRule = cmdcds.FirstOrDefault(cc => cc.CommandName == cmd.Text.ToLowerInvariant())) != null) + if ((cdRule = cmdcds.FirstOrDefault(cc => cc.CommandName == cmd.Aliases.First().ToLowerInvariant())) != null) { var activeCdsForGuild = activeCooldowns.GetOrAdd(guild.Id, new ConcurrentHashSet()); - if (activeCdsForGuild.FirstOrDefault(ac => ac.UserId == user.Id && ac.Command == cmd.Text.ToLowerInvariant()) != null) + if (activeCdsForGuild.FirstOrDefault(ac => ac.UserId == user.Id && ac.Command == cmd.Aliases.First().ToLowerInvariant()) != null) { return true; } @@ -106,14 +106,14 @@ namespace NadekoBot.Modules.Permissions activeCdsForGuild.Add(new ActiveCooldown() { UserId = user.Id, - Command = cmd.Text.ToLowerInvariant(), + Command = cmd.Aliases.First().ToLowerInvariant(), }); var t = Task.Run(async () => { try { await Task.Delay(cdRule.Seconds * 1000); - activeCdsForGuild.RemoveWhere(ac => ac.Command == cmd.Text.ToLowerInvariant() && ac.UserId == user.Id); + activeCdsForGuild.RemoveWhere(ac => ac.Command == cmd.Aliases.First().ToLowerInvariant() && ac.UserId == user.Id); } catch { } }); diff --git a/src/NadekoBot/Modules/Permissions/Commands/FilterCommands.cs b/src/NadekoBot/Modules/Permissions/Commands/FilterCommands.cs index ab2558f5..2d0376e1 100644 --- a/src/NadekoBot/Modules/Permissions/Commands/FilterCommands.cs +++ b/src/NadekoBot/Modules/Permissions/Commands/FilterCommands.cs @@ -13,7 +13,7 @@ namespace NadekoBot.Modules.Permissions public partial class Permissions { [Group] - public class FilterCommands + public class FilterCommands : ModuleBase { public static ConcurrentHashSet InviteFilteringChannels { get; } public static ConcurrentHashSet InviteFilteringServers { get; } @@ -63,9 +63,9 @@ namespace NadekoBot.Modules.Permissions [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task SrvrFilterInv(IUserMessage imsg) + public async Task SrvrFilterInv() { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)Context.Channel; bool enabled; using (var uow = DbHandler.UnitOfWork()) @@ -89,9 +89,9 @@ namespace NadekoBot.Modules.Permissions [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task ChnlFilterInv(IUserMessage imsg) + public async Task ChnlFilterInv() { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)Context.Channel; int removed; using (var uow = DbHandler.UnitOfWork()) @@ -122,9 +122,9 @@ namespace NadekoBot.Modules.Permissions [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task SrvrFilterWords(IUserMessage imsg) + public async Task SrvrFilterWords() { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)Context.Channel; bool enabled; using (var uow = DbHandler.UnitOfWork()) @@ -148,9 +148,9 @@ namespace NadekoBot.Modules.Permissions [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task ChnlFilterWords(IUserMessage imsg) + public async Task ChnlFilterWords() { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)Context.Channel; int removed; using (var uow = DbHandler.UnitOfWork()) @@ -181,9 +181,9 @@ namespace NadekoBot.Modules.Permissions [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task FilterWord(IUserMessage imsg, [Remainder] string word) + public async Task FilterWord([Remainder] string word) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)Context.Channel; word = word?.Trim().ToLowerInvariant(); @@ -221,9 +221,9 @@ namespace NadekoBot.Modules.Permissions [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task LstFilterWords(IUserMessage imsg) + public async Task LstFilterWords() { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)Context.Channel; ConcurrentHashSet filteredWords; ServerFilteredWords.TryGetValue(channel.Guild.Id, out filteredWords); diff --git a/src/NadekoBot/Modules/Permissions/PermissionExtensions.cs b/src/NadekoBot/Modules/Permissions/PermissionExtensions.cs index 8340b2f5..cf8f0ed3 100644 --- a/src/NadekoBot/Modules/Permissions/PermissionExtensions.cs +++ b/src/NadekoBot/Modules/Permissions/PermissionExtensions.cs @@ -10,7 +10,7 @@ namespace NadekoBot.Modules.Permissions { public static class PermissionExtensions { - public static bool CheckPermissions(this IEnumerable permsEnumerable, IUserMessage message, Command command) + public static bool CheckPermissions(this IEnumerable permsEnumerable, IUserMessage message, CommandInfo command) { var perms = permsEnumerable as List ?? permsEnumerable.ToList(); int throwaway; @@ -75,7 +75,7 @@ namespace NadekoBot.Modules.Permissions case PrimaryPermissionType.Role: if (guildUser == null) break; - if (guildUser.Roles.Any(r => r.Id == perm.PrimaryTargetId)) + if (guildUser.RoleIds.Contains(perm.PrimaryTargetId)) return perm.State; break; case PrimaryPermissionType.Server: @@ -86,7 +86,7 @@ namespace NadekoBot.Modules.Permissions return null; } - public static string GetCommand(this Permission perm, IGuild guild = null) + public static string GetCommand(this Permission perm, SocketGuild guild = null) { var com = ""; switch (perm.PrimaryTarget) diff --git a/src/NadekoBot/Modules/Permissions/Permissions.cs b/src/NadekoBot/Modules/Permissions/Permissions.cs index d0db3176..d2b282aa 100644 --- a/src/NadekoBot/Modules/Permissions/Permissions.cs +++ b/src/NadekoBot/Modules/Permissions/Permissions.cs @@ -8,8 +8,9 @@ using Discord; using NadekoBot.Services.Database.Models; using System.Collections.Concurrent; using NadekoBot.Extensions; -using NLog; +using Discord.WebSocket; using System.Diagnostics; +using NLog; namespace NadekoBot.Modules.Permissions { @@ -48,21 +49,15 @@ namespace NadekoBot.Modules.Permissions _log.Debug($"Loaded in {sw.Elapsed.TotalSeconds:F2}s"); } - public Permissions() : base() - { - } - [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task Verbose(IUserMessage msg, PermissionAction action) + public async Task Verbose(PermissionAction action) { - var channel = (ITextChannel)msg.Channel; - using (var uow = DbHandler.UnitOfWork()) { - var config = uow.GuildConfigs.For(channel.Guild.Id, set => set); + var config = uow.GuildConfigs.For(Context.Guild.Id, set => set); config.VerbosePermissions = action.Value; - Cache.AddOrUpdate(channel.Guild.Id, new PermissionCache() + Cache.AddOrUpdate(Context.Guild.Id, new PermissionCache() { PermRole = config.PermissionRole, RootPermission = Permission.GetDefaultRoot(), @@ -71,25 +66,24 @@ namespace NadekoBot.Modules.Permissions await uow.CompleteAsync().ConfigureAwait(false); } - await channel.SendConfirmAsync("ℹ️ I will " + (action.Value ? "now" : "no longer") + " show permission warnings.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("ℹ️ I will " + (action.Value ? "now" : "no longer") + " show permission warnings.").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task PermRole(IUserMessage msg, [Remainder] IRole role = null) + public async Task PermRole([Remainder] IRole role = null) { - var channel = (ITextChannel)msg.Channel; using (var uow = DbHandler.UnitOfWork()) { - var config = uow.GuildConfigs.For(channel.Guild.Id, set => set); + var config = uow.GuildConfigs.For(Context.Guild.Id, set => set); if (role == null) { - await channel.SendConfirmAsync($"ℹ️ Current permission role is **{config.PermissionRole}**.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"ℹ️ Current permission role is **{config.PermissionRole}**.").ConfigureAwait(false); return; } else { config.PermissionRole = role.Name.Trim(); - Cache.AddOrUpdate(channel.Guild.Id, new PermissionCache() + Cache.AddOrUpdate(Context.Guild.Id, new PermissionCache() { PermRole = config.PermissionRole, RootPermission = Permission.GetDefaultRoot(), @@ -99,40 +93,37 @@ namespace NadekoBot.Modules.Permissions } } - await channel.SendConfirmAsync($"Users now require **{role.Name}** role in order to edit permissions.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"Users now require **{role.Name}** role in order to edit permissions.").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task ListPerms(IUserMessage msg, int page = 1) + public async Task ListPerms(int page = 1) { - var channel = (ITextChannel)msg.Channel; - if (page < 1 || page > 4) return; string toSend = ""; using (var uow = DbHandler.UnitOfWork()) { - var perms = uow.GuildConfigs.PermissionsFor(channel.Guild.Id).RootPermission; + var perms = uow.GuildConfigs.PermissionsFor(Context.Guild.Id).RootPermission; var i = 1 + 20 * (page - 1); - toSend = Format.Code($"📄 Permissions page {page}") + "\n\n" + String.Join("\n", perms.AsEnumerable().Skip((page - 1) * 20).Take(20).Select(p => $"`{(i++)}.` {(p.Next == null ? Format.Bold(p.GetCommand(channel.Guild) + " [uneditable]") : (p.GetCommand(channel.Guild)))}")); + toSend = Format.Code($"📄 Permissions page {page}") + "\n\n" + String.Join("\n", perms.AsEnumerable().Skip((page - 1) * 20).Take(20).Select(p => $"`{(i++)}.` {(p.Next == null ? Format.Bold(p.GetCommand((SocketGuild)Context.Guild) + " [uneditable]") : (p.GetCommand((SocketGuild)Context.Guild)))}")); } - await channel.SendMessageAsync(toSend).ConfigureAwait(false); + await Context.Channel.SendMessageAsync(toSend).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task RemovePerm(IUserMessage imsg, int index) + public async Task RemovePerm(int index) { - var channel = (ITextChannel)imsg.Channel; index -= 1; try { Permission p; using (var uow = DbHandler.UnitOfWork()) { - var config = uow.GuildConfigs.PermissionsFor(channel.Guild.Id); + var config = uow.GuildConfigs.PermissionsFor(Context.Guild.Id); var perms = config.RootPermission; if (index == perms.Count() - 1) { @@ -147,7 +138,7 @@ namespace NadekoBot.Modules.Permissions { p = perms.RemoveAt(index); } - Cache.AddOrUpdate(channel.Guild.Id, new PermissionCache() + Cache.AddOrUpdate(Context.Guild.Id, new PermissionCache() { PermRole = config.PermissionRole, RootPermission = config.RootPermission, @@ -162,21 +153,20 @@ namespace NadekoBot.Modules.Permissions uow2._context.SaveChanges(); } - await channel.SendConfirmAsync($"✅ {imsg.Author.Mention} removed permission **{p.GetCommand(channel.Guild)}** from position #{index + 1}.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"✅ {Context.User.Mention} removed permission **{p.GetCommand((SocketGuild)Context.Guild)}** from position #{index + 1}.").ConfigureAwait(false); } catch (ArgumentOutOfRangeException) { - await channel.SendErrorAsync("❗️`No command on that index found.`").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("❗️`No command on that index found.`").ConfigureAwait(false); } } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task MovePerm(IUserMessage imsg, int from, int to) + public async Task MovePerm(int from, int to) { from -= 1; to -= 1; - var channel = (ITextChannel)imsg.Channel; if (!(from == to || from < 0 || to < 0)) { try @@ -185,7 +175,7 @@ namespace NadekoBot.Modules.Permissions Permission toPerm = null; using (var uow = DbHandler.UnitOfWork()) { - var config = uow.GuildConfigs.PermissionsFor(channel.Guild.Id); + var config = uow.GuildConfigs.PermissionsFor(Context.Guild.Id); var perms = config.RootPermission; var root = perms; var index = 0; @@ -214,13 +204,13 @@ namespace NadekoBot.Modules.Permissions { if (!fromFound) { - await channel.SendErrorAsync($"Can't find permission at index `#{++from}`").ConfigureAwait(false); + await Context.Channel.SendErrorAsync($"Can't find permission at index `#{++from}`").ConfigureAwait(false); return; } if (!toFound) { - await channel.SendErrorAsync($"Can't find permission at index `#{++to}`").ConfigureAwait(false); + await Context.Channel.SendErrorAsync($"Can't find permission at index `#{++to}`").ConfigureAwait(false); return; } } @@ -262,7 +252,7 @@ namespace NadekoBot.Modules.Permissions } config.RootPermission = fromPerm.GetRoot(); - Cache.AddOrUpdate(channel.Guild.Id, new PermissionCache() + Cache.AddOrUpdate(Context.Guild.Id, new PermissionCache() { PermRole = config.PermissionRole, RootPermission = config.RootPermission, @@ -270,22 +260,20 @@ namespace NadekoBot.Modules.Permissions }, (id, old) => { old.RootPermission = config.RootPermission; return old; }); await uow.CompleteAsync().ConfigureAwait(false); } - await channel.SendConfirmAsync($"`Moved permission:` \"{fromPerm.GetCommand(channel.Guild)}\" `from #{++from} to #{++to}.`").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"`Moved permission:` \"{fromPerm.GetCommand((SocketGuild)Context.Guild)}\" `from #{++from} to #{++to}.`").ConfigureAwait(false); return; } catch (Exception e) when (e is ArgumentOutOfRangeException || e is IndexOutOfRangeException) { } } - await channel.SendErrorAsync("`Invalid index(es) specified.`").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("`Invalid index(es) specified.`").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task SrvrCmd(IUserMessage imsg, Command command, PermissionAction action) + public async Task SrvrCmd(CommandInfo command, PermissionAction action) { - var channel = (ITextChannel)imsg.Channel; - using (var uow = DbHandler.UnitOfWork()) { var newPerm = new Permission @@ -293,11 +281,11 @@ namespace NadekoBot.Modules.Permissions PrimaryTarget = PrimaryPermissionType.Server, PrimaryTargetId = 0, SecondaryTarget = SecondaryPermissionType.Command, - SecondaryTargetName = command.Text.ToLowerInvariant(), + SecondaryTargetName = command.Aliases.First().ToLowerInvariant(), State = action.Value, }; - var config = uow.GuildConfigs.SetNewRootPermission(channel.Guild.Id, newPerm); - Cache.AddOrUpdate(channel.Guild.Id, new PermissionCache() + var config = uow.GuildConfigs.SetNewRootPermission(Context.Guild.Id, newPerm); + Cache.AddOrUpdate(Context.Guild.Id, new PermissionCache() { PermRole = config.PermissionRole, RootPermission = config.RootPermission, @@ -306,15 +294,13 @@ namespace NadekoBot.Modules.Permissions await uow.CompleteAsync().ConfigureAwait(false); } - await channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `{command.Text}` command on this server.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `{command.Aliases.First()}` command on this server.").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task SrvrMdl(IUserMessage imsg, Module module, PermissionAction action) + public async Task SrvrMdl(ModuleInfo module, PermissionAction action) { - var channel = (ITextChannel)imsg.Channel; - using (var uow = DbHandler.UnitOfWork()) { var newPerm = new Permission @@ -325,8 +311,8 @@ namespace NadekoBot.Modules.Permissions SecondaryTargetName = module.Name.ToLowerInvariant(), State = action.Value, }; - var config = uow.GuildConfigs.SetNewRootPermission(channel.Guild.Id, newPerm); - Cache.AddOrUpdate(channel.Guild.Id, new PermissionCache() + var config = uow.GuildConfigs.SetNewRootPermission(Context.Guild.Id, newPerm); + Cache.AddOrUpdate(Context.Guild.Id, new PermissionCache() { PermRole = config.PermissionRole, RootPermission = config.RootPermission, @@ -334,15 +320,13 @@ namespace NadekoBot.Modules.Permissions }, (id, old) => { old.RootPermission = config.RootPermission; return old; }); await uow.CompleteAsync().ConfigureAwait(false); } - await channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of **`{module.Name}`** module on this server.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of **`{module.Name}`** module on this server.").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task UsrCmd(IUserMessage imsg, Command command, PermissionAction action, [Remainder] IGuildUser user) + public async Task UsrCmd(CommandInfo command, PermissionAction action, [Remainder] IGuildUser user) { - var channel = (ITextChannel)imsg.Channel; - using (var uow = DbHandler.UnitOfWork()) { var newPerm = new Permission @@ -350,11 +334,11 @@ namespace NadekoBot.Modules.Permissions PrimaryTarget = PrimaryPermissionType.User, PrimaryTargetId = user.Id, SecondaryTarget = SecondaryPermissionType.Command, - SecondaryTargetName = command.Text.ToLowerInvariant(), + SecondaryTargetName = command.Aliases.First().ToLowerInvariant(), State = action.Value, }; - var config = uow.GuildConfigs.SetNewRootPermission(channel.Guild.Id, newPerm); - Cache.AddOrUpdate(channel.Guild.Id, new PermissionCache() + var config = uow.GuildConfigs.SetNewRootPermission(Context.Guild.Id, newPerm); + Cache.AddOrUpdate(Context.Guild.Id, new PermissionCache() { PermRole = config.PermissionRole, RootPermission = config.RootPermission, @@ -362,15 +346,13 @@ namespace NadekoBot.Modules.Permissions }, (id, old) => { old.RootPermission = config.RootPermission; return old; }); await uow.CompleteAsync().ConfigureAwait(false); } - await channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `{command.Text}` command for `{user}` user.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `{command.Aliases.First()}` command for `{user}` user.").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task UsrMdl(IUserMessage imsg, Module module, PermissionAction action, [Remainder] IGuildUser user) + public async Task UsrMdl(ModuleInfo module, PermissionAction action, [Remainder] IGuildUser user) { - var channel = (ITextChannel)imsg.Channel; - using (var uow = DbHandler.UnitOfWork()) { var newPerm = new Permission @@ -381,8 +363,8 @@ namespace NadekoBot.Modules.Permissions SecondaryTargetName = module.Name.ToLowerInvariant(), State = action.Value, }; - var config = uow.GuildConfigs.SetNewRootPermission(channel.Guild.Id, newPerm); - Cache.AddOrUpdate(channel.Guild.Id, new PermissionCache() + var config = uow.GuildConfigs.SetNewRootPermission(Context.Guild.Id, newPerm); + Cache.AddOrUpdate(Context.Guild.Id, new PermissionCache() { PermRole = config.PermissionRole, RootPermission = config.RootPermission, @@ -390,15 +372,13 @@ namespace NadekoBot.Modules.Permissions }, (id, old) => { old.RootPermission = config.RootPermission; return old; }); await uow.CompleteAsync().ConfigureAwait(false); } - await channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `{module.Name}` module for `{user}` user.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `{module.Name}` module for `{user}` user.").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task RoleCmd(IUserMessage imsg, Command command, PermissionAction action, [Remainder] IRole role) + public async Task RoleCmd(CommandInfo command, PermissionAction action, [Remainder] IRole role) { - var channel = (ITextChannel)imsg.Channel; - using (var uow = DbHandler.UnitOfWork()) { var newPerm = new Permission @@ -406,11 +386,11 @@ namespace NadekoBot.Modules.Permissions PrimaryTarget = PrimaryPermissionType.Role, PrimaryTargetId = role.Id, SecondaryTarget = SecondaryPermissionType.Command, - SecondaryTargetName = command.Text.ToLowerInvariant(), + SecondaryTargetName = command.Aliases.First().ToLowerInvariant(), State = action.Value, }; - var config = uow.GuildConfigs.SetNewRootPermission(channel.Guild.Id, newPerm); - Cache.AddOrUpdate(channel.Guild.Id, new PermissionCache() + var config = uow.GuildConfigs.SetNewRootPermission(Context.Guild.Id, newPerm); + Cache.AddOrUpdate(Context.Guild.Id, new PermissionCache() { PermRole = config.PermissionRole, RootPermission = config.RootPermission, @@ -418,15 +398,13 @@ namespace NadekoBot.Modules.Permissions }, (id, old) => { old.RootPermission = config.RootPermission; return old; }); await uow.CompleteAsync().ConfigureAwait(false); } - await channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `{command.Text}` command for `{role}` role.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `{command.Aliases.First()}` command for `{role}` role.").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task RoleMdl(IUserMessage imsg, Module module, PermissionAction action, [Remainder] IRole role) + public async Task RoleMdl(ModuleInfo module, PermissionAction action, [Remainder] IRole role) { - var channel = (ITextChannel)imsg.Channel; - using (var uow = DbHandler.UnitOfWork()) { var newPerm = new Permission @@ -437,8 +415,8 @@ namespace NadekoBot.Modules.Permissions SecondaryTargetName = module.Name.ToLowerInvariant(), State = action.Value, }; - var config = uow.GuildConfigs.SetNewRootPermission(channel.Guild.Id, newPerm); - Cache.AddOrUpdate(channel.Guild.Id, new PermissionCache() + var config = uow.GuildConfigs.SetNewRootPermission(Context.Guild.Id, newPerm); + Cache.AddOrUpdate(Context.Guild.Id, new PermissionCache() { PermRole = config.PermissionRole, RootPermission = config.RootPermission, @@ -446,14 +424,13 @@ namespace NadekoBot.Modules.Permissions }, (id, old) => { old.RootPermission = config.RootPermission; return old; }); await uow.CompleteAsync().ConfigureAwait(false); } - await channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `{module.Name}` module for `{role}` role.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `{module.Name}` module for `{role}` role.").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task ChnlCmd(IUserMessage imsg, Command command, PermissionAction action, [Remainder] ITextChannel chnl) + public async Task ChnlCmd(CommandInfo command, PermissionAction action, [Remainder] ITextChannel chnl) { - var channel = (ITextChannel)imsg.Channel; try { using (var uow = DbHandler.UnitOfWork()) @@ -463,11 +440,11 @@ namespace NadekoBot.Modules.Permissions PrimaryTarget = PrimaryPermissionType.Channel, PrimaryTargetId = chnl.Id, SecondaryTarget = SecondaryPermissionType.Command, - SecondaryTargetName = command.Text.ToLowerInvariant(), + SecondaryTargetName = command.Aliases.First().ToLowerInvariant(), State = action.Value, }; - var config = uow.GuildConfigs.SetNewRootPermission(channel.Guild.Id, newPerm); - Cache.AddOrUpdate(channel.Guild.Id, new PermissionCache() + var config = uow.GuildConfigs.SetNewRootPermission(Context.Guild.Id, newPerm); + Cache.AddOrUpdate(Context.Guild.Id, new PermissionCache() { PermRole = config.PermissionRole, RootPermission = config.RootPermission, @@ -479,15 +456,13 @@ namespace NadekoBot.Modules.Permissions catch (Exception ex) { _log.Error(ex); } - await channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `{command.Text}` command for `{chnl}` channel.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `{command.Aliases.First()}` command for `{chnl}` channel.").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task ChnlMdl(IUserMessage imsg, Module module, PermissionAction action, [Remainder] ITextChannel chnl) + public async Task ChnlMdl(ModuleInfo module, PermissionAction action, [Remainder] ITextChannel chnl) { - var channel = (ITextChannel)imsg.Channel; - using (var uow = DbHandler.UnitOfWork()) { var newPerm = new Permission @@ -498,8 +473,8 @@ namespace NadekoBot.Modules.Permissions SecondaryTargetName = module.Name.ToLowerInvariant(), State = action.Value, }; - var config = uow.GuildConfigs.SetNewRootPermission(channel.Guild.Id, newPerm); - Cache.AddOrUpdate(channel.Guild.Id, new PermissionCache() + var config = uow.GuildConfigs.SetNewRootPermission(Context.Guild.Id, newPerm); + Cache.AddOrUpdate(Context.Guild.Id, new PermissionCache() { PermRole = config.PermissionRole, RootPermission = config.RootPermission, @@ -507,15 +482,13 @@ namespace NadekoBot.Modules.Permissions }, (id, old) => { old.RootPermission = config.RootPermission; return old; }); await uow.CompleteAsync().ConfigureAwait(false); } - await channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `{module.Name}` module for `{chnl}` channel.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `{module.Name}` module for `{chnl}` channel.").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task AllChnlMdls(IUserMessage imsg, PermissionAction action, [Remainder] ITextChannel chnl) + public async Task AllChnlMdls(PermissionAction action, [Remainder] ITextChannel chnl) { - var channel = (ITextChannel)imsg.Channel; - using (var uow = DbHandler.UnitOfWork()) { var newPerm = new Permission @@ -526,8 +499,8 @@ namespace NadekoBot.Modules.Permissions SecondaryTargetName = "*", State = action.Value, }; - var config = uow.GuildConfigs.SetNewRootPermission(channel.Guild.Id, newPerm); - Cache.AddOrUpdate(channel.Guild.Id, new PermissionCache() + var config = uow.GuildConfigs.SetNewRootPermission(Context.Guild.Id, newPerm); + Cache.AddOrUpdate(Context.Guild.Id, new PermissionCache() { PermRole = config.PermissionRole, RootPermission = config.RootPermission, @@ -535,15 +508,13 @@ namespace NadekoBot.Modules.Permissions }, (id, old) => { old.RootPermission = config.RootPermission; return old; }); await uow.CompleteAsync().ConfigureAwait(false); } - await channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `ALL MODULES` for `{chnl}` channel.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `ALL MODULES` for `{chnl}` channel.").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task AllRoleMdls(IUserMessage imsg, PermissionAction action, [Remainder] IRole role) + public async Task AllRoleMdls(PermissionAction action, [Remainder] IRole role) { - var channel = (ITextChannel)imsg.Channel; - using (var uow = DbHandler.UnitOfWork()) { var newPerm = new Permission @@ -554,8 +525,8 @@ namespace NadekoBot.Modules.Permissions SecondaryTargetName = "*", State = action.Value, }; - var config = uow.GuildConfigs.SetNewRootPermission(channel.Guild.Id, newPerm); - Cache.AddOrUpdate(channel.Guild.Id, new PermissionCache() + var config = uow.GuildConfigs.SetNewRootPermission(Context.Guild.Id, newPerm); + Cache.AddOrUpdate(Context.Guild.Id, new PermissionCache() { PermRole = config.PermissionRole, RootPermission = config.RootPermission, @@ -563,15 +534,13 @@ namespace NadekoBot.Modules.Permissions }, (id, old) => { old.RootPermission = config.RootPermission; return old; }); await uow.CompleteAsync().ConfigureAwait(false); } - await channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `ALL MODULES` for `{role}` role.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `ALL MODULES` for `{role}` role.").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task AllUsrMdls(IUserMessage imsg, PermissionAction action, [Remainder] IUser user) + public async Task AllUsrMdls(PermissionAction action, [Remainder] IUser user) { - var channel = (ITextChannel)imsg.Channel; - using (var uow = DbHandler.UnitOfWork()) { var newPerm = new Permission @@ -582,8 +551,8 @@ namespace NadekoBot.Modules.Permissions SecondaryTargetName = "*", State = action.Value, }; - var config = uow.GuildConfigs.SetNewRootPermission(channel.Guild.Id, newPerm); - Cache.AddOrUpdate(channel.Guild.Id, new PermissionCache() + var config = uow.GuildConfigs.SetNewRootPermission(Context.Guild.Id, newPerm); + Cache.AddOrUpdate(Context.Guild.Id, new PermissionCache() { PermRole = config.PermissionRole, RootPermission = config.RootPermission, @@ -591,15 +560,13 @@ namespace NadekoBot.Modules.Permissions }, (id, old) => { old.RootPermission = config.RootPermission; return old; }); await uow.CompleteAsync().ConfigureAwait(false); } - await channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `ALL MODULES` for `{user}` user.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `ALL MODULES` for `{user}` user.").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task AllSrvrMdls(IUserMessage imsg, PermissionAction action) + public async Task AllSrvrMdls(PermissionAction action) { - var channel = (ITextChannel)imsg.Channel; - using (var uow = DbHandler.UnitOfWork()) { var newPerm = new Permission @@ -610,19 +577,19 @@ namespace NadekoBot.Modules.Permissions SecondaryTargetName = "*", State = action.Value, }; - uow.GuildConfigs.SetNewRootPermission(channel.Guild.Id, newPerm); + uow.GuildConfigs.SetNewRootPermission(Context.Guild.Id, newPerm); var allowUser = new Permission { PrimaryTarget = PrimaryPermissionType.User, - PrimaryTargetId = imsg.Author.Id, + PrimaryTargetId = Context.User.Id, SecondaryTarget = SecondaryPermissionType.AllModules, SecondaryTargetName = "*", State = true, }; - var config = uow.GuildConfigs.SetNewRootPermission(channel.Guild.Id, allowUser); - Cache.AddOrUpdate(channel.Guild.Id, new PermissionCache() + var config = uow.GuildConfigs.SetNewRootPermission(Context.Guild.Id, allowUser); + Cache.AddOrUpdate(Context.Guild.Id, new PermissionCache() { PermRole = config.PermissionRole, RootPermission = config.RootPermission, @@ -630,7 +597,7 @@ namespace NadekoBot.Modules.Permissions }, (id, old) => { old.RootPermission = config.RootPermission; return old; }); await uow.CompleteAsync().ConfigureAwait(false); } - await channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `ALL MODULES` on this server.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `ALL MODULES` on this server.").ConfigureAwait(false); } } } diff --git a/src/NadekoBot/Modules/Pokemon/Pokemon.cs b/src/NadekoBot/Modules/Pokemon/Pokemon.cs index 0861bc1d..7f51deb0 100644 --- a/src/NadekoBot/Modules/Pokemon/Pokemon.cs +++ b/src/NadekoBot/Modules/Pokemon/Pokemon.cs @@ -16,7 +16,6 @@ using static NadekoBot.Modules.Gambling.Gambling; namespace NadekoBot.Modules.Pokemon { - [NadekoModule("Pokemon", ">")] public partial class Pokemon : DiscordModule { @@ -25,18 +24,18 @@ namespace NadekoBot.Modules.Pokemon public const string PokemonTypesFile = "data/pokemon_types.json"; - private Logger _pokelog { get; } + private static new Logger _log { get; } - public Pokemon() : base() + static Pokemon() { - _pokelog = LogManager.GetCurrentClassLogger(); + _log = LogManager.GetCurrentClassLogger(); if (File.Exists(PokemonTypesFile)) { PokemonTypes = JsonConvert.DeserializeObject>(File.ReadAllText(PokemonTypesFile)); } else { - _pokelog.Warn(PokemonTypesFile + " is missing. Pokemon types not loaded."); + _log.Warn(PokemonTypesFile + " is missing. Pokemon types not loaded."); } } @@ -97,10 +96,9 @@ namespace NadekoBot.Modules.Pokemon [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task Attack(IUserMessage umsg, string move, IGuildUser targetUser = null) + public async Task Attack(string move, IGuildUser targetUser = null) { - var channel = (ITextChannel)umsg.Channel; - IGuildUser user = (IGuildUser)umsg.Author; + IGuildUser user = (IGuildUser)Context.User; if (string.IsNullOrWhiteSpace(move)) { return; @@ -108,12 +106,12 @@ namespace NadekoBot.Modules.Pokemon if (targetUser == null) { - await channel.SendMessageAsync("No such person.").ConfigureAwait(false); + await Context.Channel.SendMessageAsync("No such person.").ConfigureAwait(false); return; } else if (targetUser == user) { - await channel.SendMessageAsync("You can't attack yourself.").ConfigureAwait(false); + await Context.Channel.SendMessageAsync("You can't attack yourself.").ConfigureAwait(false); return; } @@ -127,17 +125,17 @@ namespace NadekoBot.Modules.Pokemon //User not able if HP < 0, has made more than 4 attacks if (userStats.Hp < 0) { - await channel.SendMessageAsync($"{user.Mention} has fainted and was not able to move!").ConfigureAwait(false); + await Context.Channel.SendMessageAsync($"{user.Mention} has fainted and was not able to move!").ConfigureAwait(false); return; } if (userStats.MovesMade >= 5) { - await channel.SendMessageAsync($"{user.Mention} has used too many moves in a row and was not able to move!").ConfigureAwait(false); + await Context.Channel.SendMessageAsync($"{user.Mention} has used too many moves in a row and was not able to move!").ConfigureAwait(false); return; } if (userStats.LastAttacked.Contains(targetUser.Id)) { - await channel.SendMessageAsync($"{user.Mention} can't attack again without retaliation!").ConfigureAwait(false); + await Context.Channel.SendMessageAsync($"{user.Mention} can't attack again without retaliation!").ConfigureAwait(false); return; } //get target stats @@ -147,7 +145,7 @@ namespace NadekoBot.Modules.Pokemon //If target's HP is below 0, no use attacking if (targetStats.Hp <= 0) { - await channel.SendMessageAsync($"{targetUser.Mention} has already fainted!").ConfigureAwait(false); + await Context.Channel.SendMessageAsync($"{targetUser.Mention} has already fainted!").ConfigureAwait(false); return; } @@ -157,7 +155,7 @@ namespace NadekoBot.Modules.Pokemon var enabledMoves = userType.Moves; if (!enabledMoves.Contains(move.ToLowerInvariant())) { - await channel.SendMessageAsync($"{user.Mention} is not able to use **{move}**. Type {NadekoBot.ModulePrefixes[typeof(Pokemon).Name]}ml to see moves").ConfigureAwait(false); + await Context.Channel.SendMessageAsync($"{user.Mention} is not able to use **{move}**. Type {NadekoBot.ModulePrefixes[typeof(Pokemon).Name]}ml to see moves").ConfigureAwait(false); return; } @@ -209,16 +207,15 @@ namespace NadekoBot.Modules.Pokemon Stats[user.Id] = userStats; Stats[targetUser.Id] = targetStats; - await channel.SendMessageAsync(response).ConfigureAwait(false); + await Context.Channel.SendMessageAsync(response).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task Movelist(IUserMessage umsg) + public async Task Movelist() { - var channel = (ITextChannel)umsg.Channel; - IGuildUser user = (IGuildUser)umsg.Author; + IGuildUser user = (IGuildUser)Context.User; var userType = GetPokeType(user.Id); var movesList = userType.Moves; @@ -227,18 +224,17 @@ namespace NadekoBot.Modules.Pokemon { str += $"\n{userType.Icon}{m}"; } - await channel.SendMessageAsync(str).ConfigureAwait(false); + await Context.Channel.SendMessageAsync(str).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task Heal(IUserMessage umsg, IGuildUser targetUser = null) + public async Task Heal(IGuildUser targetUser = null) { - var channel = (ITextChannel)umsg.Channel; - IGuildUser user = (IGuildUser)umsg.Author; + IGuildUser user = (IGuildUser)Context.User; if (targetUser == null) { - await channel.SendMessageAsync("No such person.").ConfigureAwait(false); + await Context.Channel.SendMessageAsync("No such person.").ConfigureAwait(false); return; } @@ -247,7 +243,7 @@ namespace NadekoBot.Modules.Pokemon var targetStats = Stats[targetUser.Id]; if (targetStats.Hp == targetStats.MaxHp) { - await channel.SendMessageAsync($"{targetUser.Mention} already has full HP!").ConfigureAwait(false); + await Context.Channel.SendMessageAsync($"{targetUser.Mention} already has full HP!").ConfigureAwait(false); return; } //Payment~ @@ -258,7 +254,7 @@ namespace NadekoBot.Modules.Pokemon { if (!await CurrencyHandler.RemoveCurrencyAsync(user, $"Poke-Heal {target}", amount, true).ConfigureAwait(false)) { - try { await channel.SendMessageAsync($"{user.Mention} You don't have enough {CurrencyName}s.").ConfigureAwait(false); } catch { } + try { await Context.Channel.SendMessageAsync($"{user.Mention} You don't have enough {CurrencyName}s.").ConfigureAwait(false); } catch { } return; } } @@ -271,30 +267,29 @@ namespace NadekoBot.Modules.Pokemon Stats[targetUser.Id].Hp = (targetStats.MaxHp / 2); if (target == "yourself") { - await channel.SendMessageAsync($"You revived yourself with one {CurrencySign}").ConfigureAwait(false); + await Context.Channel.SendMessageAsync($"You revived yourself with one {CurrencySign}").ConfigureAwait(false); } else { - await channel.SendMessageAsync($"{user.Mention} revived {targetUser.Mention} with one {CurrencySign}").ConfigureAwait(false); + await Context.Channel.SendMessageAsync($"{user.Mention} revived {targetUser.Mention} with one {CurrencySign}").ConfigureAwait(false); } return; } - await channel.SendMessageAsync($"{user.Mention} healed {targetUser.Mention} with one {CurrencySign}").ConfigureAwait(false); + await Context.Channel.SendMessageAsync($"{user.Mention} healed {targetUser.Mention} with one {CurrencySign}").ConfigureAwait(false); return; } else { - await channel.SendMessageAsync($"{targetUser.Mention} already has full HP!").ConfigureAwait(false); + await Context.Channel.SendMessageAsync($"{targetUser.Mention} already has full HP!").ConfigureAwait(false); } } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task Type(IUserMessage umsg, IGuildUser targetUser = null) + public async Task Type(IGuildUser targetUser = null) { - var channel = (ITextChannel)umsg.Channel; - IGuildUser user = (IGuildUser)umsg.Author; + IGuildUser user = (IGuildUser)Context.User; if (targetUser == null) { @@ -302,26 +297,29 @@ namespace NadekoBot.Modules.Pokemon } var pType = GetPokeType(targetUser.Id); - await channel.SendMessageAsync($"Type of {targetUser.Mention} is **{pType.Name.ToLowerInvariant()}**{pType.Icon}").ConfigureAwait(false); + await Context.Channel.SendMessageAsync($"Type of {targetUser.Mention} is **{pType.Name.ToLowerInvariant()}**{pType.Icon}").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task Settype(IUserMessage umsg, [Remainder] string typeTargeted = null) + public async Task Settype([Remainder] string typeTargeted = null) { - var channel = (ITextChannel)umsg.Channel; - IGuildUser user = (IGuildUser)umsg.Author; + IGuildUser user = (IGuildUser)Context.User; var targetType = StringToPokemonType(typeTargeted); if (targetType == null) { - await channel.EmbedAsync(PokemonTypes.Aggregate(new EmbedBuilder().WithDescription("List of the available types:"), (eb, pt) => eb.AddField(efb => efb.WithName(pt.Name).WithValue(pt.Icon).WithIsInline(true))).WithOkColor().Build()).ConfigureAwait(false); + await Context.Channel.EmbedAsync(PokemonTypes.Aggregate(new EmbedBuilder().WithDescription("List of the available types:"), + (eb, pt) => eb.AddField(efb => efb.WithName(pt.Name) + .WithValue(pt.Icon) + .WithIsInline(true))) + .WithColor(NadekoBot.OkColor)).ConfigureAwait(false); return; } if (targetType == GetPokeType(user.Id)) { - await channel.SendMessageAsync($"Your type is already {targetType.Name.ToLowerInvariant()}{targetType.Icon}").ConfigureAwait(false); + await Context.Channel.SendMessageAsync($"Your type is already {targetType.Name.ToLowerInvariant()}{targetType.Icon}").ConfigureAwait(false); return; } @@ -331,7 +329,7 @@ namespace NadekoBot.Modules.Pokemon { if (!await CurrencyHandler.RemoveCurrencyAsync(user, $"{user.Mention} change type to {typeTargeted}", amount, true).ConfigureAwait(false)) { - try { await channel.SendMessageAsync($"{user.Mention} You don't have enough {CurrencyName}s.").ConfigureAwait(false); } catch { } + try { await Context.Channel.SendMessageAsync($"{user.Mention} You don't have enough {CurrencyName}s.").ConfigureAwait(false); } catch { } return; } } @@ -364,7 +362,7 @@ namespace NadekoBot.Modules.Pokemon } //Now for the response - await channel.SendMessageAsync($"Set type of {user.Mention} to {typeTargeted}{targetType.Icon} for a {CurrencySign}").ConfigureAwait(false); + await Context.Channel.SendMessageAsync($"Set type of {user.Mention} to {typeTargeted}{targetType.Icon} for a {CurrencySign}").ConfigureAwait(false); } } diff --git a/src/NadekoBot/Modules/Pokemon/PokemonType.cs b/src/NadekoBot/Modules/Pokemon/PokemonType.cs index d4cf9007..b73dec6b 100644 --- a/src/NadekoBot/Modules/Pokemon/PokemonType.cs +++ b/src/NadekoBot/Modules/Pokemon/PokemonType.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Collections.Generic; namespace NadekoBot.Modules.Pokemon { diff --git a/src/NadekoBot/Modules/Searches/Commands/AnimeSearchCommands.cs b/src/NadekoBot/Modules/Searches/Commands/AnimeSearchCommands.cs index 52f9fda0..ed6c058b 100644 --- a/src/NadekoBot/Modules/Searches/Commands/AnimeSearchCommands.cs +++ b/src/NadekoBot/Modules/Searches/Commands/AnimeSearchCommands.cs @@ -1,5 +1,4 @@ using Discord; -using Discord.API; using Discord.Commands; using NadekoBot.Attributes; using NadekoBot.Extensions; @@ -18,7 +17,7 @@ namespace NadekoBot.Modules.Searches public partial class Searches { [Group] - public class AnimeSearchCommands + public class AnimeSearchCommands : ModuleBase { private static Timer anilistTokenRefresher { get; } private static Logger _log { get; } @@ -54,11 +53,8 @@ namespace NadekoBot.Modules.Searches } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Anime(IUserMessage umsg, [Remainder] string query) + public async Task Anime([Remainder] string query) { - var channel = (ITextChannel)umsg.Channel; - if (string.IsNullOrWhiteSpace(query)) return; @@ -66,7 +62,7 @@ namespace NadekoBot.Modules.Searches if (animeData == null) { - await umsg.Channel.SendErrorAsync("Failed finding that animu.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("Failed finding that animu.").ConfigureAwait(false); return; } @@ -79,15 +75,13 @@ namespace NadekoBot.Modules.Searches .AddField(efb => efb.WithName("Status").WithValue(animeData.AiringStatus.ToString()).WithIsInline(true)) .AddField(efb => efb.WithName("Genres").WithValue(String.Join(", ", animeData.Genres)).WithIsInline(true)) .WithFooter(efb => efb.WithText("Score: " + animeData.average_score + " / 100")); - await channel.EmbedAsync(embed.Build()).ConfigureAwait(false); + await Context.Channel.EmbedAsync(embed).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task Manga(IUserMessage umsg, [Remainder] string query) + public async Task Manga([Remainder] string query) { - var channel = (ITextChannel)umsg.Channel; - if (string.IsNullOrWhiteSpace(query)) return; @@ -95,7 +89,7 @@ namespace NadekoBot.Modules.Searches if (mangaData == null) { - await umsg.Channel.SendErrorAsync("Failed finding that mango.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("Failed finding that mango.").ConfigureAwait(false); return; } @@ -109,7 +103,7 @@ namespace NadekoBot.Modules.Searches .AddField(efb => efb.WithName("Genres").WithValue(String.Join(", ", mangaData.Genres)).WithIsInline(true)) .WithFooter(efb => efb.WithText("Score: " + mangaData.average_score + " / 100")); - await channel.EmbedAsync(embed.Build()).ConfigureAwait(false); + await Context.Channel.EmbedAsync(embed).ConfigureAwait(false); } private async Task GetAnimeData(string query) diff --git a/src/NadekoBot/Modules/Searches/Commands/JokeCommands.cs b/src/NadekoBot/Modules/Searches/Commands/JokeCommands.cs index 3ae4557c..1d5f3c99 100644 --- a/src/NadekoBot/Modules/Searches/Commands/JokeCommands.cs +++ b/src/NadekoBot/Modules/Searches/Commands/JokeCommands.cs @@ -1,5 +1,4 @@ -using Discord; -using Discord.Commands; +using Discord.Commands; using NadekoBot.Attributes; using NadekoBot.Extensions; using NadekoBot.Modules.Searches.Models; @@ -19,7 +18,7 @@ namespace NadekoBot.Modules.Searches public partial class Searches { [Group] - public class JokeCommands + public class JokeCommands : ModuleBase { private static List wowJokes { get; } = new List(); private static List magicItems { get; } = new List(); @@ -45,64 +44,58 @@ namespace NadekoBot.Modules.Searches } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Yomama(IUserMessage msg) + public async Task Yomama() { using (var http = new HttpClient()) { var response = await http.GetStringAsync("http://api.yomomma.info/").ConfigureAwait(false); - System.Console.WriteLine(response); - await msg.Channel.SendConfirmAsync(JObject.Parse(response)["joke"].ToString() + " 😆").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync(JObject.Parse(response)["joke"].ToString() + " 😆").ConfigureAwait(false); } } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Randjoke(IUserMessage msg) + public async Task Randjoke() { using (var http = new HttpClient()) { var response = await http.GetStringAsync("http://tambal.azurewebsites.net/joke/random").ConfigureAwait(false); - await msg.Channel.SendConfirmAsync(JObject.Parse(response)["joke"].ToString() + " 😆").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync(JObject.Parse(response)["joke"].ToString() + " 😆").ConfigureAwait(false); } } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task ChuckNorris(IUserMessage msg) + public async Task ChuckNorris() { using (var http = new HttpClient()) { var response = await http.GetStringAsync("http://api.icndb.com/jokes/random/").ConfigureAwait(false); - await msg.Channel.SendConfirmAsync(JObject.Parse(response)["value"]["joke"].ToString() + " 😆").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync(JObject.Parse(response)["value"]["joke"].ToString() + " 😆").ConfigureAwait(false); } } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task WowJoke(IUserMessage msg) + public async Task WowJoke() { if (!wowJokes.Any()) { - await msg.Channel.SendErrorAsync("Jokes not loaded.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("Jokes not loaded.").ConfigureAwait(false); return; } var joke = wowJokes[new NadekoRandom().Next(0, wowJokes.Count)]; - await msg.Channel.SendConfirmAsync(joke.Question, joke.Answer).ConfigureAwait(false); + await Context.Channel.SendConfirmAsync(joke.Question, joke.Answer).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task MagicItem(IUserMessage msg) + public async Task MagicItem() { if (!wowJokes.Any()) { - await msg.Channel.SendErrorAsync("MagicItems not loaded.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("MagicItems not loaded.").ConfigureAwait(false); return; } var item = magicItems[new NadekoRandom().Next(0, magicItems.Count)]; - await msg.Channel.SendConfirmAsync("✨" + item.Name, item.Description).ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("✨" + item.Name, item.Description).ConfigureAwait(false); } } } diff --git a/src/NadekoBot/Modules/Searches/Commands/LoLCommands.cs b/src/NadekoBot/Modules/Searches/Commands/LoLCommands.cs index 25c18267..308ccbd2 100644 --- a/src/NadekoBot/Modules/Searches/Commands/LoLCommands.cs +++ b/src/NadekoBot/Modules/Searches/Commands/LoLCommands.cs @@ -1,5 +1,4 @@ using Discord; -using Discord.Commands; using NadekoBot.Attributes; using NadekoBot.Extensions; using NadekoBot.Services; @@ -8,7 +7,6 @@ using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; -using System.Text; using System.Threading.Tasks; //todo drawing @@ -33,13 +31,8 @@ namespace NadekoBot.Modules.Searches [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Lolban(IUserMessage umsg) + public async Task Lolban() { - var channel = (ITextChannel)umsg.Channel; - - - var showCount = 8; //http://api.champion.gg/stats/champs/mostBanned?api_key=YOUR_API_TOKEN&page=1&limit=2 try @@ -58,12 +51,12 @@ namespace NadekoBot.Modules.Searches eb.AddField(efb => efb.WithName(champ["name"].ToString()).WithValue(champ["general"]["banRate"] + "%").WithIsInline(true)); } - await channel.EmbedAsync(eb.Build(), Format.Italics(trashTalk[new NadekoRandom().Next(0, trashTalk.Length)])).ConfigureAwait(false); + await Context.Channel.EmbedAsync(eb, Format.Italics(trashTalk[new NadekoRandom().Next(0, trashTalk.Length)])).ConfigureAwait(false); } } catch (Exception) { - await channel.SendMessageAsync("Something went wrong.").ConfigureAwait(false); + await Context.Channel.SendMessageAsync("Something went wrong.").ConfigureAwait(false); } } } @@ -112,7 +105,7 @@ namespace NadekoBot.Modules.Searches // public override void Init(CommandGroupBuilder cgb) // { -// cgb.CreateCommand(Module.Prefix + "lolchamp") +// cgb.CreateCommand(Module.Name + "lolchamp") // .Description($"Shows League Of Legends champion statistics. If there are spaces/apostrophes or in the name - omit them. Optional second parameter is a role. |`{Prefix}lolchamp Riven` or `{Prefix}lolchamp Annie sup`") // .Parameter("champ", ParameterType.Required) // .Parameter("position", ParameterType.Unparsed) diff --git a/src/NadekoBot/Modules/Searches/Commands/MemegenCommands.cs b/src/NadekoBot/Modules/Searches/Commands/MemegenCommands.cs index 541eac15..5f7b0064 100644 --- a/src/NadekoBot/Modules/Searches/Commands/MemegenCommands.cs +++ b/src/NadekoBot/Modules/Searches/Commands/MemegenCommands.cs @@ -1,10 +1,8 @@ -using Discord.Commands; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.IO; using System.Linq; -using Discord; using System.Threading.Tasks; using NadekoBot.Attributes; using System.Net.Http; @@ -15,10 +13,8 @@ namespace NadekoBot.Modules.Searches public partial class Searches { [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Memelist(IUserMessage umsg) + public async Task Memelist() { - var channel = (ITextChannel)umsg.Channel; HttpClientHandler handler = new HttpClientHandler(); handler.AllowAutoRedirect = false; @@ -29,19 +25,16 @@ namespace NadekoBot.Modules.Searches var data = JsonConvert.DeserializeObject>(rawJson) .Select(kvp => Path.GetFileName(kvp.Value)); - await channel.SendTableAsync(data, x => $"{x,-17}", 3).ConfigureAwait(false); + await Context.Channel.SendTableAsync(data, x => $"{x,-17}", 3).ConfigureAwait(false); } } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Memegen(IUserMessage umsg, string meme, string topText, string botText) + public async Task Memegen(string meme, string topText, string botText) { - var channel = (ITextChannel)umsg.Channel; - - var top = topText.Replace(' ', '-'); - var bot = botText.Replace(' ', '-'); - await channel.SendMessageAsync($"http://memegen.link/{meme}/{top}/{bot}.jpg") + var top = Uri.EscapeDataString(topText.Replace(' ', '-')); + var bot = Uri.EscapeDataString(botText.Replace(' ', '-')); + await Context.Channel.SendMessageAsync($"http://memegen.link/{meme}/{top}/{bot}.jpg") .ConfigureAwait(false); } } diff --git a/src/NadekoBot/Modules/Searches/Commands/Models/AnimeResult.cs b/src/NadekoBot/Modules/Searches/Commands/Models/AnimeResult.cs index e5d779c0..114515ad 100644 --- a/src/NadekoBot/Modules/Searches/Commands/Models/AnimeResult.cs +++ b/src/NadekoBot/Modules/Searches/Commands/Models/AnimeResult.cs @@ -1,5 +1,4 @@ using NadekoBot.Extensions; -using System.Globalization; namespace NadekoBot.Modules.Searches.Models { diff --git a/src/NadekoBot/Modules/Searches/Commands/Models/OverwatchApiModel.cs b/src/NadekoBot/Modules/Searches/Commands/Models/OverwatchApiModel.cs index 3c6399f5..9d57f52a 100644 --- a/src/NadekoBot/Modules/Searches/Commands/Models/OverwatchApiModel.cs +++ b/src/NadekoBot/Modules/Searches/Commands/Models/OverwatchApiModel.cs @@ -1,6 +1,5 @@ using Newtonsoft.Json; using System; -using System.Collections.Generic; using System.Text.RegularExpressions; namespace NadekoBot.Modules.Searches.Models diff --git a/src/NadekoBot/Modules/Searches/Commands/OMDB/OmdbProvider.cs b/src/NadekoBot/Modules/Searches/Commands/OMDB/OmdbProvider.cs index b73973a2..892f8fab 100644 --- a/src/NadekoBot/Modules/Searches/Commands/OMDB/OmdbProvider.cs +++ b/src/NadekoBot/Modules/Searches/Commands/OMDB/OmdbProvider.cs @@ -35,7 +35,7 @@ namespace NadekoBot.Modules.Searches.Commands.OMDB public string Plot { get; set; } public string Poster { get; set; } - public Embed GetEmbed() => + public EmbedBuilder GetEmbed() => new EmbedBuilder().WithOkColor() .WithTitle(Title) .WithUrl($"http://www.imdb.com/title/{ImdbId}/") @@ -43,8 +43,7 @@ namespace NadekoBot.Modules.Searches.Commands.OMDB .AddField(efb => efb.WithName("Rating").WithValue(ImdbRating).WithIsInline(true)) .AddField(efb => efb.WithName("Genre").WithValue(Genre).WithIsInline(true)) .AddField(efb => efb.WithName("Year").WithValue(Year).WithIsInline(true)) - .WithImage(eib => eib.WithUrl(Poster)) - .Build(); + .WithImageUrl(Poster); public override string ToString() => $@"`Title:` {Title} diff --git a/src/NadekoBot/Modules/Searches/Commands/OsuCommands.cs b/src/NadekoBot/Modules/Searches/Commands/OsuCommands.cs index 58d7dfdc..f7f83361 100644 --- a/src/NadekoBot/Modules/Searches/Commands/OsuCommands.cs +++ b/src/NadekoBot/Modules/Searches/Commands/OsuCommands.cs @@ -16,7 +16,7 @@ namespace NadekoBot.Modules.Searches public partial class Searches { [Group] - public class OsuCommands + public class OsuCommands : ModuleBase { private static Logger _log { get; } @@ -25,11 +25,8 @@ namespace NadekoBot.Modules.Searches _log = LogManager.GetCurrentClassLogger(); } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Osu(IUserMessage umsg, string usr, [Remainder] string mode = null) + public async Task Osu(string usr, [Remainder] string mode = null) { - var channel = (ITextChannel)umsg.Channel; - if (string.IsNullOrWhiteSpace(usr)) return; @@ -48,25 +45,22 @@ namespace NadekoBot.Modules.Searches MemoryStream ms = new MemoryStream(); res.CopyTo(ms); ms.Position = 0; - await channel.SendFileAsync(ms, $"{usr}.png", $"🎧 **Profile Link: **https://osu.ppy.sh/u/{Uri.EscapeDataString(usr)}\n`Image provided by https://lemmmy.pw/osusig`").ConfigureAwait(false); + await Context.Channel.SendFileAsync(ms, $"{usr}.png", $"🎧 **Profile Link: **https://osu.ppy.sh/u/{Uri.EscapeDataString(usr)}\n`Image provided by https://lemmmy.pw/osusig`").ConfigureAwait(false); } catch (Exception ex) { - await channel.SendErrorAsync("Failed retrieving osu signature.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("Failed retrieving osu signature.").ConfigureAwait(false); _log.Warn(ex, "Osu command failed"); } } } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Osub(IUserMessage umsg, [Remainder] string map) + public async Task Osub([Remainder] string map) { - var channel = (ITextChannel)umsg.Channel; - if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.OsuApiKey)) { - await channel.SendErrorAsync("An osu! API key is required.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("An osu! API key is required.").ConfigureAwait(false); return; } @@ -85,21 +79,20 @@ namespace NadekoBot.Modules.Searches var time = TimeSpan.FromSeconds(Double.Parse($"{obj["total_length"]}")).ToString(@"mm\:ss"); sb.AppendLine($"{obj["artist"]} - {obj["title"]}, mapped by {obj["creator"]}. https://osu.ppy.sh/s/{obj["beatmapset_id"]}"); sb.AppendLine($"{starRating} stars, {obj["bpm"]} BPM | AR{obj["diff_approach"]}, CS{obj["diff_size"]}, OD{obj["diff_overall"]} | Length: {time}"); - await channel.SendMessageAsync(sb.ToString()).ConfigureAwait(false); + await Context.Channel.SendMessageAsync(sb.ToString()).ConfigureAwait(false); } } catch (Exception ex) { - await channel.SendErrorAsync("Something went wrong."); + await Context.Channel.SendErrorAsync("Something went wrong."); _log.Warn(ex, "Osub command failed"); } } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Osu5(IUserMessage umsg, string user, [Remainder] string mode = null) + public async Task Osu5(string user, [Remainder] string mode = null) { - var channel = (ITextChannel)umsg.Channel; + var channel = (ITextChannel)Context.Channel; if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.OsuApiKey)) { await channel.SendErrorAsync("An osu! API key is required.").ConfigureAwait(false); diff --git a/src/NadekoBot/Modules/Searches/Commands/OverwatchCommands.cs b/src/NadekoBot/Modules/Searches/Commands/OverwatchCommands.cs index 4f50b9cf..019f7f20 100644 --- a/src/NadekoBot/Modules/Searches/Commands/OverwatchCommands.cs +++ b/src/NadekoBot/Modules/Searches/Commands/OverwatchCommands.cs @@ -3,10 +3,8 @@ using Discord.Commands; using NadekoBot.Attributes; using NadekoBot.Extensions; using NadekoBot.Modules.Searches.Models; -using Newtonsoft.Json; +using Newtonsoft.Json; using NLog; -using System; -using System.Linq; using System.Net.Http; using System.Text.RegularExpressions; using System.Threading.Tasks; @@ -16,7 +14,7 @@ namespace NadekoBot.Modules.Searches public partial class Searches { [Group] - public class OverwatchCommands + public class OverwatchCommands : ModuleBase { private readonly Logger _log; public OverwatchCommands() @@ -24,17 +22,16 @@ namespace NadekoBot.Modules.Searches _log = LogManager.GetCurrentClassLogger(); } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Overwatch(IUserMessage umsg, string region, [Remainder] string query = null) + public async Task Overwatch(string region, [Remainder] string query = null) { - var channel = (ITextChannel)umsg.Channel; if (string.IsNullOrWhiteSpace(query)) return; var battletag = Regex.Replace(query, "#", "-", RegexOptions.IgnoreCase); - await channel.TriggerTypingAsync().ConfigureAwait(false); + await Context.Channel.TriggerTypingAsync().ConfigureAwait(false); try { + await Context.Channel.TriggerTypingAsync().ConfigureAwait(false); var model = await GetProfile(region, battletag); var rankimg = $"{model.Competitive.rank_img}"; @@ -46,7 +43,7 @@ namespace NadekoBot.Modules.Searches .WithAuthor(eau => eau.WithName($"{model.username}") .WithUrl($"https://www.overbuff.com/players/pc/{battletag}") .WithIconUrl($"{model.avatar}")) - .WithThumbnail(th => th.WithUrl("https://cdn.discordapp.com/attachments/155726317222887425/255653487512256512/YZ4w2ey.png")) + .WithThumbnailUrl("https://cdn.discordapp.com/attachments/155726317222887425/255653487512256512/YZ4w2ey.png") .AddField(fb => fb.WithName("**Level**").WithValue($"{model.level}").WithIsInline(true)) .AddField(fb => fb.WithName("**Quick Wins**").WithValue($"{model.Games.Quick.wins}").WithIsInline(true)) .AddField(fb => fb.WithName("**Current Competitive Wins**").WithValue($"{model.Games.Competitive.wins}").WithIsInline(true)) @@ -56,7 +53,7 @@ namespace NadekoBot.Modules.Searches .AddField(fb => fb.WithName("**Competitive Playtime**").WithValue($"{model.Playtime.competitive}").WithIsInline(true)) .AddField(fb => fb.WithName("**Quick Playtime**").WithValue($"{model.Playtime.quick}").WithIsInline(true)) .WithOkColor(); - await channel.EmbedAsync(embed.Build()).ConfigureAwait(false); + await Context.Channel.EmbedAsync(embed).ConfigureAwait(false); } else { @@ -64,7 +61,7 @@ namespace NadekoBot.Modules.Searches .WithAuthor(eau => eau.WithName($"{model.username}") .WithUrl($"https://www.overbuff.com/players/pc/{battletag}") .WithIconUrl($"{model.avatar}")) - .WithThumbnail(th => th.WithUrl(rankimg)) + .WithThumbnailUrl(rankimg) .AddField(fb => fb.WithName("**Level**").WithValue($"{model.level}").WithIsInline(true)) .AddField(fb => fb.WithName("**Quick Wins**").WithValue($"{model.Games.Quick.wins}").WithIsInline(true)) .AddField(fb => fb.WithName("**Current Competitive Wins**").WithValue($"{model.Games.Competitive.wins}").WithIsInline(true)) @@ -73,27 +70,14 @@ namespace NadekoBot.Modules.Searches .AddField(fb => fb.WithName("**Competitive Rank**").WithValue(rank).WithIsInline(true)) .AddField(fb => fb.WithName("**Competitive Playtime**").WithValue($"{model.Playtime.competitive}").WithIsInline(true)) .AddField(fb => fb.WithName("**Quick Playtime**").WithValue($"{model.Playtime.quick}").WithIsInline(true)) - .WithOkColor(); - await channel.EmbedAsync(embed.Build()).ConfigureAwait(false); - } - if (string.IsNullOrWhiteSpace(competitiveplay)) - { - var embed = new EmbedBuilder() - .WithAuthor(eau => eau.WithName($"{model.username}") - .WithUrl($"https://www.overbuff.com/players/pc/{battletag}") - .WithIconUrl($"{model.avatar}")) - .WithThumbnail(th => th.WithUrl("https://cdn.discordapp.com/attachments/155726317222887425/255653487512256512/YZ4w2ey.png")) - .AddField(fb => fb.WithName("**Level**").WithValue($"{model.level}").WithIsInline(true)) - .AddField(fb => fb.WithName("**Quick Wins**").WithValue($"{model.Games.Quick.wins}").WithIsInline(true)) - .AddField(fb => fb.WithName("**Competitive Playtime**").WithValue($"0 hour").WithIsInline(true)) - .AddField(fb => fb.WithName("**Quick Playtime**").WithValue($"{model.Playtime.quick}").WithIsInline(true)) - .WithOkColor(); - await channel.EmbedAsync(embed.Build()).ConfigureAwait(false); + .WithColor(NadekoBot.OkColor); + await Context.Channel.EmbedAsync(embed).ConfigureAwait(false); + return; } } catch { - await channel.SendErrorAsync("Found no user! Please check the **Region** and **BattleTag** before trying again."); + await Context.Channel.SendErrorAsync("Found no user! Please check the **Region** and **BattleTag** before trying again."); } } public async Task GetProfile(string region, string battletag) diff --git a/src/NadekoBot/Modules/Searches/Commands/PlaceCommands.cs b/src/NadekoBot/Modules/Searches/Commands/PlaceCommands.cs index 2be2d88a..af8a1fb3 100644 --- a/src/NadekoBot/Modules/Searches/Commands/PlaceCommands.cs +++ b/src/NadekoBot/Modules/Searches/Commands/PlaceCommands.cs @@ -1,5 +1,4 @@ -using Discord; -using Discord.Commands; +using Discord.Commands; using NadekoBot.Attributes; using NadekoBot.Extensions; using NadekoBot.Services; @@ -11,13 +10,9 @@ namespace NadekoBot.Modules.Searches public partial class Searches { [Group] - public class PlaceCommands + public class PlaceCommands : ModuleBase { - string typesStr { get; } = ""; - public PlaceCommands() - { - typesStr = $"`List of \"{NadekoBot.ModulePrefixes[typeof(Searches).Name]}place\" tags:`\n" + String.Join(", ", Enum.GetNames(typeof(PlaceType))); - } + private static string typesStr { get; } = $"`List of \"{NadekoBot.ModulePrefixes[typeof(Searches).Name]}place\" tags:`\n" + String.Join(", ", Enum.GetNames(typeof(PlaceType))); public enum PlaceType { @@ -32,21 +27,15 @@ namespace NadekoBot.Modules.Searches } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Placelist(IUserMessage imsg) + public async Task Placelist() { - var channel = (ITextChannel)imsg.Channel; - - await channel.SendConfirmAsync(typesStr) + await Context.Channel.SendConfirmAsync(typesStr) .ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Place(IUserMessage imsg, PlaceType placeType, uint width = 0, uint height = 0) + public async Task Place(PlaceType placeType, uint width = 0, uint height = 0) { - var channel = (ITextChannel)imsg.Channel; - string url = ""; switch (placeType) { @@ -84,7 +73,7 @@ namespace NadekoBot.Modules.Searches url += $"/{width}/{height}"; - await channel.SendMessageAsync(url).ConfigureAwait(false); + await Context.Channel.SendMessageAsync(url).ConfigureAwait(false); } } } diff --git a/src/NadekoBot/Modules/Searches/Commands/PokemonSearchCommands.cs b/src/NadekoBot/Modules/Searches/Commands/PokemonSearchCommands.cs index 1eb83583..5f37c3d8 100644 --- a/src/NadekoBot/Modules/Searches/Commands/PokemonSearchCommands.cs +++ b/src/NadekoBot/Modules/Searches/Commands/PokemonSearchCommands.cs @@ -16,7 +16,7 @@ namespace NadekoBot.Modules.Searches public partial class Searches { [Group] - public class PokemonSearchCommands + public class PokemonSearchCommands : ModuleBase { private static Dictionary pokemons { get; } = new Dictionary(); private static Dictionary pokemonAbilities { get; } = new Dictionary(); @@ -43,11 +43,8 @@ namespace NadekoBot.Modules.Searches } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Pokemon(IUserMessage umsg, [Remainder] string pokemon = null) + public async Task Pokemon([Remainder] string pokemon = null) { - var channel = (ITextChannel)umsg.Channel; - pokemon = pokemon?.Trim().ToUpperInvariant(); if (string.IsNullOrWhiteSpace(pokemon)) return; @@ -57,25 +54,22 @@ namespace NadekoBot.Modules.Searches if (kvp.Key.ToUpperInvariant() == pokemon.ToUpperInvariant()) { var p = kvp.Value; - await channel.EmbedAsync(new EmbedBuilder().WithOkColor() + await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor() .WithTitle(kvp.Key.ToTitleCase()) .WithDescription(p.BaseStats.ToString()) .AddField(efb => efb.WithName("Types").WithValue(string.Join(",\n", p.Types)).WithIsInline(true)) .AddField(efb => efb.WithName("Height/Weight").WithValue($"{p.HeightM}m/{p.WeightKg}kg").WithIsInline(true)) .AddField(efb => efb.WithName("Abilitities").WithValue(string.Join(",\n", p.Abilities.Select(a => a.Value))).WithIsInline(true)) - .Build()); + ); return; } } - await channel.SendErrorAsync("No pokemon found."); + await Context.Channel.SendErrorAsync("No pokemon found."); } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task PokemonAbility(IUserMessage umsg, [Remainder] string ability = null) + public async Task PokemonAbility([Remainder] string ability = null) { - var channel = (ITextChannel)umsg.Channel; - ability = ability?.Trim().ToUpperInvariant().Replace(" ", ""); if (string.IsNullOrWhiteSpace(ability)) return; @@ -83,15 +77,15 @@ namespace NadekoBot.Modules.Searches { if (kvp.Key.ToUpperInvariant() == ability) { - await channel.EmbedAsync(new EmbedBuilder().WithOkColor() + await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor() .WithTitle(kvp.Value.Name) .WithDescription(kvp.Value.Desc) .AddField(efb => efb.WithName("Rating").WithValue(kvp.Value.Rating.ToString()).WithIsInline(true)) - .Build()).ConfigureAwait(false); + ).ConfigureAwait(false); return; } } - await channel.SendErrorAsync("No ability found."); + await Context.Channel.SendErrorAsync("No ability found."); } } } diff --git a/src/NadekoBot/Modules/Searches/Commands/StreamNotificationCommands.cs b/src/NadekoBot/Modules/Searches/Commands/StreamNotificationCommands.cs index 8308e175..36829953 100644 --- a/src/NadekoBot/Modules/Searches/Commands/StreamNotificationCommands.cs +++ b/src/NadekoBot/Modules/Searches/Commands/StreamNotificationCommands.cs @@ -1,21 +1,18 @@ using Discord.Commands; -using Newtonsoft.Json.Linq; +using Discord; using System; using System.Collections.Concurrent; using System.Linq; using System.Threading.Tasks; -using Discord; using NadekoBot.Services; using System.Threading; using System.Collections.Generic; using NadekoBot.Services.Database.Models; using System.Net.Http; -using Discord.WebSocket; using NadekoBot.Attributes; using Microsoft.EntityFrameworkCore; using Newtonsoft.Json; using NLog; -using NadekoBot.Services.Database; using NadekoBot.Extensions; using System.Diagnostics; @@ -68,7 +65,7 @@ namespace NadekoBot.Modules.Searches } [Group] - public class StreamNotificationCommands + public class StreamNotificationCommands : ModuleBase { private static Timer checkTimer { get; } private static ConcurrentDictionary oldCachedStatuses = new ConcurrentDictionary(); @@ -106,14 +103,14 @@ namespace NadekoBot.Modules.Searches oldStatus.IsLive != newStatus.IsLive) { var server = NadekoBot.Client.GetGuild(fs.GuildId); - var channel = server?.GetTextChannel(fs.ChannelId); + if (server == null) + return; + var channel = await server.GetTextChannelAsync(fs.ChannelId); if (channel == null) return; try { - var msg = await channel.EmbedAsync(fs.GetEmbed(newStatus).Build()).ConfigureAwait(false); - if (!newStatus.IsLive) - msg.DeleteAfter(60); + var msg = await channel.EmbedAsync(fs.GetEmbed(newStatus)).ConfigureAwait(false); } catch { } } @@ -199,66 +196,63 @@ namespace NadekoBot.Modules.Searches [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageMessages)] - public async Task Hitbox(IUserMessage msg, [Remainder] string username) => - await TrackStream((ITextChannel)msg.Channel, username, FollowedStream.FollowedStreamType.Hitbox) + [RequireUserPermission(GuildPermission.ManageMessages)] + public async Task Hitbox([Remainder] string username) => + await TrackStream((ITextChannel)Context.Channel, username, FollowedStream.FollowedStreamType.Hitbox) .ConfigureAwait(false); [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageMessages)] - public async Task Twitch(IUserMessage msg, [Remainder] string username) => - await TrackStream((ITextChannel)msg.Channel, username, FollowedStream.FollowedStreamType.Twitch) + [RequireUserPermission(GuildPermission.ManageMessages)] + public async Task Twitch([Remainder] string username) => + await TrackStream((ITextChannel)Context.Channel, username, FollowedStream.FollowedStreamType.Twitch) .ConfigureAwait(false); [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageMessages)] - public async Task Beam(IUserMessage msg, [Remainder] string username) => - await TrackStream((ITextChannel)msg.Channel, username, FollowedStream.FollowedStreamType.Beam) + [RequireUserPermission(GuildPermission.ManageMessages)] + public async Task Beam([Remainder] string username) => + await TrackStream((ITextChannel)Context.Channel, username, FollowedStream.FollowedStreamType.Beam) .ConfigureAwait(false); [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task ListStreams(IUserMessage imsg) + public async Task ListStreams() { - var channel = (ITextChannel)imsg.Channel; - IEnumerable streams; using (var uow = DbHandler.UnitOfWork()) { streams = uow.GuildConfigs - .For(channel.Guild.Id, + .For(Context.Guild.Id, set => set.Include(gc => gc.FollowedStreams)) .FollowedStreams; } if (!streams.Any()) { - await channel.SendConfirmAsync("You are not following any streams on this server.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("You are not following any streams on this server.").ConfigureAwait(false); return; } - var text = string.Join("\n", streams.Select(snc => + var text = string.Join("\n", await Task.WhenAll(streams.Select(async snc => { - return $"`{snc.Username}`'s stream on **{channel.Guild.GetTextChannel(snc.ChannelId)?.Name}** channel. 【`{snc.Type.ToString()}`】"; - })); + var ch = await Context.Guild.GetTextChannelAsync(snc.ChannelId); + return $"`{snc.Username}`'s stream on **{(ch)?.Name}** channel. 【`{snc.Type.ToString()}`】"; + }))); - await channel.SendConfirmAsync($"You are following **{streams.Count()}** streams on this server.\n\n" + text).ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"You are following **{streams.Count()}** streams on this server.\n\n" + text).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageMessages)] - public async Task RemoveStream(IUserMessage msg, FollowedStream.FollowedStreamType type, [Remainder] string username) + [RequireUserPermission(GuildPermission.ManageMessages)] + public async Task RemoveStream(FollowedStream.FollowedStreamType type, [Remainder] string username) { - var channel = (ITextChannel)msg.Channel; - username = username.ToLowerInvariant().Trim(); var fs = new FollowedStream() { - ChannelId = channel.Id, + ChannelId = Context.Channel.Id, Username = username, Type = type }; @@ -266,25 +260,23 @@ namespace NadekoBot.Modules.Searches bool removed; using (var uow = DbHandler.UnitOfWork()) { - var config = uow.GuildConfigs.For(channel.Guild.Id, set => set.Include(gc => gc.FollowedStreams)); + var config = uow.GuildConfigs.For(Context.Guild.Id, set => set.Include(gc => gc.FollowedStreams)); removed = config.FollowedStreams.Remove(fs); if (removed) await uow.CompleteAsync().ConfigureAwait(false); } if (!removed) { - await channel.SendErrorAsync("No such stream.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("No such stream.").ConfigureAwait(false); return; } - await channel.SendConfirmAsync($"Removed `{username}`'s stream ({type}) from notifications.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"Removed `{username}`'s stream ({type}) from notifications.").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task CheckStream(IUserMessage imsg, FollowedStream.FollowedStreamType platform, [Remainder] string username) + public async Task CheckStream(FollowedStream.FollowedStreamType platform, [Remainder] string username) { - var channel = (ITextChannel)imsg.Channel; - var stream = username?.Trim(); if (string.IsNullOrWhiteSpace(stream)) return; @@ -297,20 +289,20 @@ namespace NadekoBot.Modules.Searches })); if (streamStatus.IsLive) { - await channel.SendConfirmAsync($"Streamer {username} is online with {streamStatus.Views} viewers."); + await Context.Channel.SendConfirmAsync($"Streamer {username} is online with {streamStatus.Views} viewers."); } else { - await channel.SendConfirmAsync($"Streamer {username} is offline."); + await Context.Channel.SendConfirmAsync($"Streamer {username} is offline."); } } catch { - await channel.SendErrorAsync("No channel found."); + await Context.Channel.SendErrorAsync("No channel found."); } } - private async Task TrackStream(ITextChannel channel, string username, FollowedStream.FollowedStreamType type) + private static async Task TrackStream(ITextChannel channel, string username, FollowedStream.FollowedStreamType type) { username = username.ToLowerInvariant().Trim(); var fs = new FollowedStream @@ -339,7 +331,7 @@ namespace NadekoBot.Modules.Searches .Add(fs); await uow.CompleteAsync().ConfigureAwait(false); } - await channel.EmbedAsync(fs.GetEmbed(status).Build(), $"🆗 I will notify this channel when status changes.").ConfigureAwait(false); + await channel.EmbedAsync(fs.GetEmbed(status), $"🆗 I will notify this channel when status changes.").ConfigureAwait(false); } } } diff --git a/src/NadekoBot/Modules/Searches/Commands/Translator.cs b/src/NadekoBot/Modules/Searches/Commands/Translator.cs index f54bfb5d..3ee67e6c 100644 --- a/src/NadekoBot/Modules/Searches/Commands/Translator.cs +++ b/src/NadekoBot/Modules/Searches/Commands/Translator.cs @@ -6,6 +6,7 @@ using System; using System.Threading.Tasks; using System.Collections.Concurrent; using System.Linq; +using Discord.WebSocket; namespace NadekoBot.Modules.Searches { @@ -18,7 +19,7 @@ namespace NadekoBot.Modules.Searches } [Group] - public class TranslateCommands + public class TranslateCommands : ModuleBase { private static ConcurrentDictionary TranslatedChannels { get; } = new ConcurrentDictionary(); private static ConcurrentDictionary UserLanguages { get; } = new ConcurrentDictionary(); @@ -29,7 +30,7 @@ namespace NadekoBot.Modules.Searches { try { - var umsg = msg as IUserMessage; + var umsg = msg as SocketUserMessage; if (umsg == null) return; @@ -46,7 +47,7 @@ namespace NadekoBot.Modules.Searches if (!UserLanguages.TryGetValue(key, out langs)) return; - var text = await TranslateInternal(umsg, langs, umsg.Resolve(UserMentionHandling.Ignore), true) + var text = await TranslateInternal(langs, umsg.Resolve(TagHandling.Ignore), true) .ConfigureAwait(false); if (autoDelete) try { await umsg.DeleteAsync().ConfigureAwait(false); } catch { } @@ -57,24 +58,21 @@ namespace NadekoBot.Modules.Searches } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Translate(IUserMessage umsg, string langs, [Remainder] string text = null) + public async Task Translate(string langs, [Remainder] string text = null) { - var channel = (ITextChannel)umsg.Channel; - try { - await umsg.Channel.TriggerTypingAsync().ConfigureAwait(false); - var translation = await TranslateInternal(umsg, langs, text); - await channel.SendConfirmAsync("Translation " + langs, translation).ConfigureAwait(false); + await Context.Channel.TriggerTypingAsync().ConfigureAwait(false); + var translation = await TranslateInternal(langs, text); + await Context.Channel.SendConfirmAsync("Translation " + langs, translation).ConfigureAwait(false); } catch { - await channel.SendErrorAsync("Bad input format, or something went wrong...").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("Bad input format, or something went wrong...").ConfigureAwait(false); } } - private static async Task TranslateInternal(IUserMessage umsg, string langs, [Remainder] string text = null, bool silent = false) + private static async Task TranslateInternal(string langs, [Remainder] string text = null, bool silent = false) { var langarr = langs.ToLowerInvariant().Split('>'); if (langarr.Length != 2) @@ -95,11 +93,11 @@ namespace NadekoBot.Modules.Searches [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.Administrator)] + [RequireUserPermission(GuildPermission.Administrator)] [OwnerOnly] - public async Task AutoTranslate(IUserMessage msg, AutoDeleteAutoTranslate autoDelete = AutoDeleteAutoTranslate.Nodel) + public async Task AutoTranslate(AutoDeleteAutoTranslate autoDelete = AutoDeleteAutoTranslate.Nodel) { - var channel = (ITextChannel)msg.Channel; + var channel = (ITextChannel)Context.Channel; if (autoDelete == AutoDeleteAutoTranslate.Del) { @@ -122,20 +120,18 @@ namespace NadekoBot.Modules.Searches [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task AutoTransLang(IUserMessage msg, [Remainder] string langs = null) + public async Task AutoTransLang([Remainder] string langs = null) { - var channel = (ITextChannel)msg.Channel; - var ucp = new UserChannelPair { - UserId = msg.Author.Id, - ChannelId = msg.Channel.Id, + UserId = Context.User.Id, + ChannelId = Context.Channel.Id, }; if (string.IsNullOrWhiteSpace(langs)) { if (UserLanguages.TryRemove(ucp, out langs)) - await channel.SendConfirmAsync($"{msg.Author.Mention}'s auto-translate language has been removed.").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"{Context.User.Mention}'s auto-translate language has been removed.").ConfigureAwait(false); return; } @@ -147,22 +143,20 @@ namespace NadekoBot.Modules.Searches if (!GoogleTranslator.Instance.Languages.Contains(from) || !GoogleTranslator.Instance.Languages.Contains(to)) { - try { await channel.SendErrorAsync("Invalid source and/or target language.").ConfigureAwait(false); } catch { } + try { await Context.Channel.SendErrorAsync("Invalid source and/or target language.").ConfigureAwait(false); } catch { } return; } UserLanguages.AddOrUpdate(ucp, langs, (key, val) => langs); - await channel.SendConfirmAsync($"Your auto-translate language has been set to {from}>{to}").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"Your auto-translate language has been set to {from}>{to}").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task Translangs(IUserMessage umsg) + public async Task Translangs() { - var channel = (ITextChannel)umsg.Channel; - - await channel.SendTableAsync(GoogleTranslator.Instance.Languages, str => $"{str,-15}", columns: 3); + await Context.Channel.SendTableAsync(GoogleTranslator.Instance.Languages, str => $"{str,-15}", columns: 3); } } diff --git a/src/NadekoBot/Modules/Searches/Commands/XkcdCommands.cs b/src/NadekoBot/Modules/Searches/Commands/XkcdCommands.cs index 49478c2c..f6b0ad98 100644 --- a/src/NadekoBot/Modules/Searches/Commands/XkcdCommands.cs +++ b/src/NadekoBot/Modules/Searches/Commands/XkcdCommands.cs @@ -12,24 +12,21 @@ namespace NadekoBot.Modules.Searches public partial class Searches { [Group] - public class XkcdCommands + public class XkcdCommands : ModuleBase { private const string xkcdUrl = "https://xkcd.com"; [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] [Priority(1)] - public async Task Xkcd(IUserMessage msg, string arg = null) + public async Task Xkcd(string arg = null) { - var channel = (ITextChannel)msg.Channel; - if (arg?.ToLowerInvariant().Trim() == "latest") { using (var http = new HttpClient()) { var res = await http.GetStringAsync($"{xkcdUrl}/info.0.json").ConfigureAwait(false); var comic = JsonConvert.DeserializeObject(res); - var sent = await channel.SendMessageAsync($"{msg.Author.Mention} " + comic.ToString()) + var sent = await Context.Channel.SendMessageAsync($"{Context.User.Mention} " + comic.ToString()) .ConfigureAwait(false); await Task.Delay(10000).ConfigureAwait(false); @@ -38,16 +35,13 @@ namespace NadekoBot.Modules.Searches } return; } - await Xkcd(msg, new NadekoRandom().Next(1, 1750)).ConfigureAwait(false); + await Xkcd(new NadekoRandom().Next(1, 1750)).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] [Priority(0)] - public async Task Xkcd(IUserMessage msg, int num) + public async Task Xkcd(int num) { - var channel = (ITextChannel)msg.Channel; - if (num < 1) return; @@ -56,17 +50,17 @@ namespace NadekoBot.Modules.Searches var res = await http.GetStringAsync($"{xkcdUrl}/{num}/info.0.json").ConfigureAwait(false); var comic = JsonConvert.DeserializeObject(res); - var embed = new EmbedBuilder().WithOkColor() - .WithImage(eib => eib.WithUrl(comic.ImageLink)) + var embed = new EmbedBuilder().WithColor(NadekoBot.OkColor) + .WithImageUrl(comic.ImageLink) .WithAuthor(eab => eab.WithName(comic.Title).WithUrl($"{xkcdUrl}/{num}").WithIconUrl("http://xkcd.com/s/919f27.ico")) .AddField(efb => efb.WithName("Comic#").WithValue(comic.Num.ToString()).WithIsInline(true)) .AddField(efb => efb.WithName("Date").WithValue($"{comic.Month}/{comic.Year}").WithIsInline(true)); - var sent = await channel.EmbedAsync(embed.Build()) + var sent = await Context.Channel.EmbedAsync(embed) .ConfigureAwait(false); await Task.Delay(10000).ConfigureAwait(false); - await sent.ModifyAsync(m => m.Embed = embed.AddField(efb => efb.WithName("Alt").WithValue(comic.Alt.ToString()).WithIsInline(false)).Build()); + await sent.ModifyAsync(m => m.Embed = embed.AddField(efb => efb.WithName("Alt").WithValue(comic.Alt.ToString()).WithIsInline(false))); } } } diff --git a/src/NadekoBot/Modules/Searches/Searches.cs b/src/NadekoBot/Modules/Searches/Searches.cs index 9655189a..b919335c 100644 --- a/src/NadekoBot/Modules/Searches/Searches.cs +++ b/src/NadekoBot/Modules/Searches/Searches.cs @@ -31,10 +31,8 @@ namespace NadekoBot.Modules.Searches public partial class Searches : DiscordModule { [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Weather(IUserMessage umsg, [Remainder] string query) + public async Task Weather([Remainder] string query) { - var channel = (ITextChannel)umsg.Channel; if (string.IsNullOrWhiteSpace(query)) return; @@ -56,75 +54,63 @@ namespace NadekoBot.Modules.Searches .AddField(fb => fb.WithName("🌇 **Sunset (utc)**").WithValue($"{data.sys.sunset.ToUnixTimestamp():HH:mm}").WithIsInline(true)) .WithOkColor() .WithFooter(efb => efb.WithText("Powered by http://openweathermap.org")); - await channel.EmbedAsync(embed.Build()).ConfigureAwait(false); + await Context.Channel.EmbedAsync(embed).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Youtube(IUserMessage umsg, [Remainder] string query = null) + public async Task Youtube([Remainder] string query = null) { - var channel = (ITextChannel)umsg.Channel; - if (!(await ValidateQuery(channel, query).ConfigureAwait(false))) return; + if (!(await ValidateQuery(Context.Channel, query).ConfigureAwait(false))) return; var result = (await NadekoBot.Google.GetVideosByKeywordsAsync(query, 1)).FirstOrDefault(); if (string.IsNullOrWhiteSpace(result)) { - await channel.SendErrorAsync("No results found for that query.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("No results found for that query.").ConfigureAwait(false); return; } - await channel.SendMessageAsync(result).ConfigureAwait(false); + await Context.Channel.SendMessageAsync(result).ConfigureAwait(false); - //await channel.EmbedAsync(new Discord.API.Embed() { Video = new Discord.API.EmbedVideo() { Url = result.Replace("watch?v=", "embed/") }, Color = NadekoBot.OkColor }).ConfigureAwait(false); + //await Context.Channel.EmbedAsync(new Discord.API.Embed() { Video = new Discord.API.EmbedVideo() { Url = result.Replace("watch?v=", "embed/") }, Color = NadekoBot.OkColor }).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Imdb(IUserMessage umsg, [Remainder] string query = null) + public async Task Imdb([Remainder] string query = null) { - var channel = (ITextChannel)umsg.Channel; - - if (!(await ValidateQuery(channel, query).ConfigureAwait(false))) return; - await umsg.Channel.TriggerTypingAsync().ConfigureAwait(false); + if (!(await ValidateQuery(Context.Channel, query).ConfigureAwait(false))) return; + await Context.Channel.TriggerTypingAsync().ConfigureAwait(false); var movie = await OmdbProvider.FindMovie(query); if (movie == null) { - await channel.SendErrorAsync("Failed to find that movie.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("Failed to find that movie.").ConfigureAwait(false); return; } - await channel.EmbedAsync(movie.GetEmbed()).ConfigureAwait(false); + await Context.Channel.EmbedAsync(movie.GetEmbed()).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task RandomCat(IUserMessage umsg) + public async Task RandomCat() { - var channel = (ITextChannel)umsg.Channel; using (var http = new HttpClient()) { var res = JObject.Parse(await http.GetStringAsync("http://www.random.cat/meow").ConfigureAwait(false)); - await channel.SendMessageAsync(res["file"].ToString()).ConfigureAwait(false); + await Context.Channel.SendMessageAsync(res["file"].ToString()).ConfigureAwait(false); } } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task RandomDog(IUserMessage umsg) + public async Task RandomDog() { - var channel = (ITextChannel)umsg.Channel; using (var http = new HttpClient()) { - await channel.SendMessageAsync("http://random.dog/" + await http.GetStringAsync("http://random.dog/woof") + await Context.Channel.SendMessageAsync("http://random.dog/" + await http.GetStringAsync("http://random.dog/woof") .ConfigureAwait(false)).ConfigureAwait(false); } } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task I(IUserMessage umsg, [Remainder] string query = null) + public async Task I([Remainder] string query = null) { - var channel = (ITextChannel)umsg.Channel; - if (string.IsNullOrWhiteSpace(query)) return; try @@ -133,29 +119,26 @@ namespace NadekoBot.Modules.Searches { var reqString = $"https://www.googleapis.com/customsearch/v1?q={Uri.EscapeDataString(query)}&cx=018084019232060951019%3Ahs5piey28-e&num=1&searchType=image&fields=items%2Flink&key={NadekoBot.Credentials.GoogleApiKey}"; var obj = JObject.Parse(await http.GetStringAsync(reqString).ConfigureAwait(false)); - await channel.SendMessageAsync(obj["items"][0]["link"].ToString()).ConfigureAwait(false); + await Context.Channel.SendMessageAsync(obj["items"][0]["link"].ToString()).ConfigureAwait(false); } } catch (HttpRequestException exception) { if (exception.Message.Contains("403 (Forbidden)")) { - await channel.SendErrorAsync("Daily limit reached!"); + await Context.Channel.SendErrorAsync("Daily limit reached!"); } else { - await channel.SendErrorAsync("Something went wrong."); + await Context.Channel.SendErrorAsync("Something went wrong."); _log.Error(exception); } } } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Ir(IUserMessage umsg, [Remainder] string query = null) + public async Task Ir([Remainder] string query = null) { - var channel = (ITextChannel)umsg.Channel; - if (string.IsNullOrWhiteSpace(query)) return; try @@ -166,40 +149,35 @@ namespace NadekoBot.Modules.Searches var reqString = $"https://www.googleapis.com/customsearch/v1?q={Uri.EscapeDataString(query)}&cx=018084019232060951019%3Ahs5piey28-e&num=1&searchType=image&start={ rng.Next(1, 50) }&fields=items%2Flink&key={NadekoBot.Credentials.GoogleApiKey}"; var obj = JObject.Parse(await http.GetStringAsync(reqString).ConfigureAwait(false)); var items = obj["items"] as JArray; - await channel.SendMessageAsync(items[0]["link"].ToString()).ConfigureAwait(false); + await Context.Channel.SendMessageAsync(items[0]["link"].ToString()).ConfigureAwait(false); } } catch (HttpRequestException exception) { if (exception.Message.Contains("403 (Forbidden)")) { - await channel.SendErrorAsync("Daily limit reached!"); + await Context.Channel.SendErrorAsync("Daily limit reached!"); } else { - await channel.SendErrorAsync("Something went wrong."); + await Context.Channel.SendErrorAsync("Something went wrong."); _log.Error(exception); } } } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Lmgtfy(IUserMessage umsg, [Remainder] string ffs = null) + public async Task Lmgtfy([Remainder] string ffs = null) { - var channel = (ITextChannel)umsg.Channel; - - if (string.IsNullOrWhiteSpace(ffs)) return; - await channel.SendConfirmAsync(await NadekoBot.Google.ShortenUrl($"")) + await Context.Channel.SendConfirmAsync(await NadekoBot.Google.ShortenUrl($"")) .ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Shorten(IUserMessage msg, [Remainder] string arg) + public async Task Shorten([Remainder] string arg) { if (string.IsNullOrWhiteSpace(arg)) return; @@ -208,15 +186,14 @@ namespace NadekoBot.Modules.Searches if (shortened == arg) { - await msg.Channel.SendErrorAsync("Failed to shorten that url.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("Failed to shorten that url.").ConfigureAwait(false); } - await msg.Channel.EmbedAsync(new EmbedBuilder().WithOkColor() + await Context.Channel.EmbedAsync(new EmbedBuilder().WithColor(NadekoBot.OkColor) .AddField(efb => efb.WithName("Original Url") .WithValue($"<{arg}>")) .AddField(efb => efb.WithName("Short Url") - .WithValue($"<{shortened}>")) - .Build()) + .WithValue($"<{shortened}>"))) .ConfigureAwait(false); } @@ -224,11 +201,8 @@ namespace NadekoBot.Modules.Searches //private readonly Regex htmlReplace = new Regex(@"(?:(.*?)<\/b>|(.*?)<\/em>)", RegexOptions.Compiled); [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Google(IUserMessage umsg, [Remainder] string terms = null) + public async Task Google([Remainder] string terms = null) { - var channel = (ITextChannel)umsg.Channel; - terms = terms?.Trim(); if (string.IsNullOrWhiteSpace(terms)) return; @@ -269,28 +243,26 @@ namespace NadekoBot.Modules.Searches .WithAuthor(eab => eab.WithName("Search For: " + terms.TrimTo(50)) .WithUrl(fullQueryLink) .WithIconUrl("http://i.imgur.com/G46fm8J.png")) - .WithTitle(umsg.Author.Mention) + .WithTitle(Context.User.Mention) .WithFooter(efb => efb.WithText(totalResults)); var desc = await Task.WhenAll(results.Select(async res => $"[{Format.Bold(res?.Title)}]({(await NadekoBot.Google.ShortenUrl(res?.Link))})\n{res?.Text}\n\n")) .ConfigureAwait(false); - await channel.EmbedAsync(embed.WithDescription(String.Concat(desc)).Build()).ConfigureAwait(false); + await Context.Channel.EmbedAsync(embed.WithDescription(String.Concat(desc))).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task MagicTheGathering(IUserMessage umsg, [Remainder] string name = null) + public async Task MagicTheGathering([Remainder] string name = null) { - var channel = (ITextChannel)umsg.Channel; var arg = name; if (string.IsNullOrWhiteSpace(arg)) { - await channel.SendErrorAsync("Please enter a card name to search for.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("Please enter a card name to search for.").ConfigureAwait(false); return; } - await umsg.Channel.TriggerTypingAsync().ConfigureAwait(false); + await Context.Channel.TriggerTypingAsync().ConfigureAwait(false); string response = ""; using (var http = new HttpClient()) { @@ -311,40 +283,38 @@ namespace NadekoBot.Modules.Searches var embed = new EmbedBuilder().WithOkColor() .WithTitle(item["name"].ToString()) .WithDescription(desc) - .WithImage(eib => eib.WithUrl(img)) + .WithImageUrl(img) .AddField(efb => efb.WithName("Store Url").WithValue(storeUrl).WithIsInline(true)) .AddField(efb => efb.WithName("Cost").WithValue(cost).WithIsInline(true)) .AddField(efb => efb.WithName("Types").WithValue(types).WithIsInline(true)); //.AddField(efb => efb.WithName("Store Url").WithValue(await NadekoBot.Google.ShortenUrl(items[0]["store_url"].ToString())).WithIsInline(true)); - await channel.EmbedAsync(embed.Build()).ConfigureAwait(false); + await Context.Channel.EmbedAsync(embed).ConfigureAwait(false); } catch { - await channel.SendErrorAsync($"Error could not find the card '{arg}'.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync($"Error could not find the card '{arg}'.").ConfigureAwait(false); } } } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Hearthstone(IUserMessage umsg, [Remainder] string name = null) + public async Task Hearthstone([Remainder] string name = null) { - var channel = (ITextChannel)umsg.Channel; var arg = name; if (string.IsNullOrWhiteSpace(arg)) { - await channel.SendErrorAsync("Please enter a card name to search for.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("Please enter a card name to search for.").ConfigureAwait(false); return; } if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.MashapeKey)) { - await channel.SendErrorAsync("Bot owner didn't specify MashapeApiKey. You can't use this functionality.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("Bot owner didn't specify MashapeApiKey. You can't use this functionality.").ConfigureAwait(false); return; } - await umsg.Channel.TriggerTypingAsync().ConfigureAwait(false); + await Context.Channel.TriggerTypingAsync().ConfigureAwait(false); string response = ""; using (var http = new HttpClient()) { @@ -355,7 +325,7 @@ namespace NadekoBot.Modules.Searches try { var items = JArray.Parse(response).Shuffle().ToList(); - var images = new List(); + var images = new List(); if (items == null) throw new KeyNotFoundException("Cannot find a card by that name"); foreach (var item in items.Where(item => item.HasValues && item["img"] != null).Take(4)) @@ -365,7 +335,7 @@ namespace NadekoBot.Modules.Searches var imgStream = new MemoryStream(); await sr.CopyToAsync(imgStream); imgStream.Position = 0; - images.Add(new Image(imgStream)); + images.Add(new ImageSharp.Image(imgStream)); } } string msg = null; @@ -374,37 +344,34 @@ namespace NadekoBot.Modules.Searches msg = "⚠ Found over 4 images. Showing random 4."; } var ms = new MemoryStream(); - images.Merge().SaveAsPng(ms); + images.AsEnumerable().Merge().SaveAsPng(ms); ms.Position = 0; - await channel.SendFileAsync(ms, arg + ".png", msg).ConfigureAwait(false); + await Context.Channel.SendFileAsync(ms, arg + ".png", msg).ConfigureAwait(false); } catch (Exception ex) { - await channel.SendErrorAsync($"Error occured.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync($"Error occured.").ConfigureAwait(false); _log.Error(ex); } } } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Yodify(IUserMessage umsg, [Remainder] string query = null) + public async Task Yodify([Remainder] string query = null) { - var channel = (ITextChannel)umsg.Channel; - if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.MashapeKey)) { - await channel.SendErrorAsync("Bot owner didn't specify MashapeApiKey. You can't use this functionality.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("Bot owner didn't specify MashapeApiKey. You can't use this functionality.").ConfigureAwait(false); return; } var arg = query; if (string.IsNullOrWhiteSpace(arg)) { - await channel.SendErrorAsync("Please enter a sentence.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("Please enter a sentence.").ConfigureAwait(false); return; } - await umsg.Channel.TriggerTypingAsync().ConfigureAwait(false); + await Context.Channel.TriggerTypingAsync().ConfigureAwait(false); using (var http = new HttpClient()) { http.DefaultRequestHeaders.Clear(); @@ -418,34 +385,31 @@ namespace NadekoBot.Modules.Searches .WithAuthor(au => au.WithName("Yoda").WithIconUrl("http://www.yodaspeak.co.uk/yoda-small1.gif")) .WithDescription(res) .WithOkColor(); - await channel.EmbedAsync(embed.Build()).ConfigureAwait(false); + await Context.Channel.EmbedAsync(embed).ConfigureAwait(false); } catch { - await channel.SendErrorAsync("Failed to yodify your sentence.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("Failed to yodify your sentence.").ConfigureAwait(false); } } } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task UrbanDict(IUserMessage umsg, [Remainder] string query = null) + public async Task UrbanDict([Remainder] string query = null) { - var channel = (ITextChannel)umsg.Channel; - if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.MashapeKey)) { - await channel.SendErrorAsync("Bot owner didn't specify MashapeApiKey. You can't use this functionality.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("Bot owner didn't specify MashapeApiKey. You can't use this functionality.").ConfigureAwait(false); return; } var arg = query; if (string.IsNullOrWhiteSpace(arg)) { - await channel.SendErrorAsync("Please enter a search term.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("Please enter a search term.").ConfigureAwait(false); return; } - await umsg.Channel.TriggerTypingAsync().ConfigureAwait(false); + await Context.Channel.TriggerTypingAsync().ConfigureAwait(false); using (var http = new HttpClient()) { http.DefaultRequestHeaders.Clear(); @@ -462,21 +426,18 @@ namespace NadekoBot.Modules.Searches .WithUrl(link) .WithAuthor(eab => eab.WithIconUrl("http://i.imgur.com/nwERwQE.jpg").WithName(word)) .WithDescription(def); - await channel.EmbedAsync(embed.Build()).ConfigureAwait(false); + await Context.Channel.EmbedAsync(embed).ConfigureAwait(false); } catch { - await channel.SendErrorAsync("Failed finding a definition for that term.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("Failed finding a definition for that term.").ConfigureAwait(false); } } } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Define(IUserMessage msg, [Remainder] string word) + public async Task Define([Remainder] string word) { - var channel = (ITextChannel)msg.Channel; - if (string.IsNullOrWhiteSpace(word)) return; @@ -503,29 +464,26 @@ namespace NadekoBot.Modules.Searches if (sense.Examples != null) embed.AddField(efb => efb.WithName("Example").WithValue(sense.Examples.First().text)); - await channel.EmbedAsync(embed.Build()).ConfigureAwait(false); + await Context.Channel.EmbedAsync(embed).ConfigureAwait(false); } } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Hashtag(IUserMessage umsg, [Remainder] string query = null) + public async Task Hashtag([Remainder] string query = null) { - var channel = (ITextChannel)umsg.Channel; - var arg = query; if (string.IsNullOrWhiteSpace(arg)) { - await channel.SendErrorAsync("Please enter a search term.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("Please enter a search term.").ConfigureAwait(false); return; } if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.MashapeKey)) { - await channel.SendErrorAsync("Bot owner didn't specify MashapeApiKey. You can't use this functionality.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("Bot owner didn't specify MashapeApiKey. You can't use this functionality.").ConfigureAwait(false); return; } - await umsg.Channel.TriggerTypingAsync().ConfigureAwait(false); + await Context.Channel.TriggerTypingAsync().ConfigureAwait(false); string res = ""; using (var http = new HttpClient()) { @@ -541,24 +499,21 @@ namespace NadekoBot.Modules.Searches var hashtag = item["hashtag"].ToString(); var link = item["uri"].ToString(); var desc = item["text"].ToString(); - await channel.EmbedAsync(new EmbedBuilder().WithOkColor() + await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor() .WithAuthor(eab => eab.WithUrl(link) .WithIconUrl("http://res.cloudinary.com/urbandictionary/image/upload/a_exif,c_fit,h_200,w_200/v1394975045/b8oszuu3tbq7ebyo7vo1.jpg") .WithName(query)) - .WithDescription(desc) - .Build()); + .WithDescription(desc)); } catch { - await channel.SendErrorAsync("Failed finding a definition for that tag.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("Failed finding a definition for that tag.").ConfigureAwait(false); } } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Catfact(IUserMessage umsg) + public async Task Catfact() { - var channel = (ITextChannel)umsg.Channel; using (var http = new HttpClient()) { var response = await http.GetStringAsync("http://catfacts-api.appspot.com/api/facts").ConfigureAwait(false); @@ -566,44 +521,35 @@ namespace NadekoBot.Modules.Searches return; var fact = JObject.Parse(response)["facts"][0].ToString(); - await channel.SendConfirmAsync("🐈fact", fact).ConfigureAwait(false); + await Context.Channel.SendConfirmAsync("🐈fact", fact).ConfigureAwait(false); } } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Revav(IUserMessage umsg, [Remainder] IUser usr = null) + public async Task Revav([Remainder] IUser usr = null) { - var channel = (ITextChannel)umsg.Channel; - if (usr == null) - usr = umsg.Author; - await channel.SendConfirmAsync($"https://images.google.com/searchbyimage?image_url={usr.AvatarUrl}").ConfigureAwait(false); + usr = Context.User; + await Context.Channel.SendConfirmAsync($"https://images.google.com/searchbyimage?image_url={usr.AvatarUrl}").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Revimg(IUserMessage umsg, [Remainder] string imageLink = null) + public async Task Revimg([Remainder] string imageLink = null) { - var channel = (ITextChannel)umsg.Channel; imageLink = imageLink?.Trim() ?? ""; if (string.IsNullOrWhiteSpace(imageLink)) return; - await channel.SendConfirmAsync($"https://images.google.com/searchbyimage?image_url={imageLink}").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"https://images.google.com/searchbyimage?image_url={imageLink}").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public Task Safebooru(IUserMessage umsg, [Remainder] string tag = null) - => InternalDapiCommand(umsg, tag, DapiSearchType.Safebooru); + public Task Safebooru([Remainder] string tag = null) + => InternalDapiCommand(Context.Message, tag, DapiSearchType.Safebooru); [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Wiki(IUserMessage umsg, [Remainder] string query = null) + public async Task Wiki([Remainder] string query = null) { - var channel = (ITextChannel)umsg.Channel; - query = query?.Trim(); if (string.IsNullOrWhiteSpace(query)) return; @@ -612,22 +558,19 @@ namespace NadekoBot.Modules.Searches var result = await http.GetStringAsync("https://en.wikipedia.org//w/api.php?action=query&format=json&prop=info&redirects=1&formatversion=2&inprop=url&titles=" + Uri.EscapeDataString(query)); var data = JsonConvert.DeserializeObject(result); if (data.Query.Pages[0].Missing) - await channel.SendErrorAsync("That page could not be found."); + await Context.Channel.SendErrorAsync("That page could not be found."); else - await channel.SendMessageAsync(data.Query.Pages[0].FullUrl); + await Context.Channel.SendMessageAsync(data.Query.Pages[0].FullUrl); } } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Color(IUserMessage umsg, [Remainder] string color = null) + public async Task Color([Remainder] string color = null) { - var channel = (ITextChannel)umsg.Channel; - color = color?.Trim().Replace("#", ""); if (string.IsNullOrWhiteSpace((string)color)) return; - var img = new Image(50, 50); + var img = new ImageSharp.Image(50, 50); var red = Convert.ToInt32(color.Substring(0, 2), 16); var green = Convert.ToInt32(color.Substring(2, 2), 16); @@ -635,18 +578,15 @@ namespace NadekoBot.Modules.Searches img.BackgroundColor(new ImageSharp.Color(color)); - await channel.SendFileAsync(img.ToStream(), $"{color}.png"); + await Context.Channel.SendFileAsync(img.ToStream(), $"{color}.png"); } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Videocall(IUserMessage umsg, [Remainder] string arg = null) + public async Task Videocall([Remainder] params IUser[] users) { - var channel = (ITextChannel)umsg.Channel; - try { - var allUsrs = umsg.MentionedUsers.Append(umsg.Author); + var allUsrs = users.Append(Context.User); var allUsrsArray = allUsrs.ToArray(); var str = allUsrsArray.Aggregate("http://appear.in/", (current, usr) => current + Uri.EscapeUriString(usr.Username[0].ToString())); str += new NadekoRandom().Next(); @@ -662,31 +602,25 @@ namespace NadekoBot.Modules.Searches } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Avatar(IUserMessage umsg, [Remainder] IUser usr = null) + public async Task Avatar([Remainder] IUser usr = null) { - var channel = (ITextChannel)umsg.Channel; - if (usr == null) - usr = umsg.Author; + usr = Context.User; - await channel.EmbedAsync(new EmbedBuilder().WithOkColor() + await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor() .WithTitle($"{usr}'s Avatar") - .WithImageUrl(usr.AvatarUrl) - .Build()).ConfigureAwait(false); + .WithImageUrl(usr.AvatarUrl)).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task Wikia(IUserMessage umsg, string target, [Remainder] string query = null) + public async Task Wikia(string target, [Remainder] string query = null) { - var channel = (ITextChannel)umsg.Channel; if (string.IsNullOrWhiteSpace(target) || string.IsNullOrWhiteSpace(query)) { - await channel.SendErrorAsync("Please enter a target wikia, followed by search query.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("Please enter a target wikia, followed by search query.").ConfigureAwait(false); return; } - await umsg.Channel.TriggerTypingAsync().ConfigureAwait(false); + await Context.Channel.TriggerTypingAsync().ConfigureAwait(false); using (var http = new HttpClient()) { http.DefaultRequestHeaders.Clear(); @@ -698,27 +632,25 @@ namespace NadekoBot.Modules.Searches var response = $@"`Title:` {found["title"].ToString()} `Quality:` {found["quality"]} `URL:` {await NadekoBot.Google.ShortenUrl(found["url"].ToString()).ConfigureAwait(false)}"; - await channel.SendMessageAsync(response); + await Context.Channel.SendMessageAsync(response); } catch { - await channel.SendErrorAsync($"Failed finding `{query}`.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync($"Failed finding `{query}`.").ConfigureAwait(false); } } } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task MCPing(IUserMessage umsg, [Remainder] string query = null) + public async Task MCPing([Remainder] string query = null) { - var channel = (ITextChannel)umsg.Channel; var arg = query; if (string.IsNullOrWhiteSpace(arg)) { - await channel.SendErrorAsync("💢 Please enter a `ip:port`.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("💢 Please enter a `ip:port`.").ConfigureAwait(false); return; } - await umsg.Channel.TriggerTypingAsync().ConfigureAwait(false); + await Context.Channel.TriggerTypingAsync().ConfigureAwait(false); using (var http = new HttpClient()) { http.DefaultRequestHeaders.Clear(); @@ -735,27 +667,25 @@ namespace NadekoBot.Modules.Searches sb.AppendLine($"`Description:` {items["description"].ToString()}"); sb.AppendLine($"`Online Players:` {items["players"]["online"].ToString()}/{items["players"]["max"].ToString()}"); sb.Append($"`Latency:` {ping}"); - await channel.SendMessageAsync(sb.ToString()); + await Context.Channel.SendMessageAsync(sb.ToString()); } catch { - await channel.SendErrorAsync($"Failed finding `{arg}`.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync($"Failed finding `{arg}`.").ConfigureAwait(false); } } } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task MCQ(IUserMessage umsg, [Remainder] string query = null) + public async Task MCQ([Remainder] string query = null) { - var channel = (ITextChannel)umsg.Channel; var arg = query; if (string.IsNullOrWhiteSpace(arg)) { - await channel.SendErrorAsync("Please enter `ip:port`.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("Please enter `ip:port`.").ConfigureAwait(false); return; } - await umsg.Channel.TriggerTypingAsync().ConfigureAwait(false); + await Context.Channel.TriggerTypingAsync().ConfigureAwait(false); using (var http = new HttpClient()) { http.DefaultRequestHeaders.Clear(); @@ -775,11 +705,11 @@ namespace NadekoBot.Modules.Searches sb.AppendLine($"`Online Players:` {items["Players"]} / {items["MaxPlayers"]}"); sb.AppendLine($"`Plugins:` {items["Plugins"]}"); sb.Append($"`Version:` {items["Version"]}"); - await channel.SendMessageAsync(sb.ToString()); + await Context.Channel.SendMessageAsync(sb.ToString()); } catch { - await channel.SendErrorAsync($"Failed finding server `{arg}`.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync($"Failed finding server `{arg}`.").ConfigureAwait(false); } } } @@ -795,7 +725,7 @@ namespace NadekoBot.Modules.Searches public static async Task InternalDapiCommand(IUserMessage umsg, string tag, DapiSearchType type) { - var channel = (ITextChannel)umsg.Channel; + var channel = umsg.Channel; tag = tag?.Trim() ?? ""; @@ -807,8 +737,7 @@ namespace NadekoBot.Modules.Searches await channel.EmbedAsync(new EmbedBuilder().WithOkColor() .WithDescription(umsg.Author.Mention + " " + tag) .WithImageUrl(url) - .WithFooter(efb => efb.WithText(type.ToString())) - .Build()).ConfigureAwait(false); + .WithFooter(efb => efb.WithText(type.ToString()))).ConfigureAwait(false); } public static async Task InternalDapiSearch(string tag, DapiSearchType type) @@ -855,7 +784,7 @@ namespace NadekoBot.Modules.Searches return null; } } - public static async Task ValidateQuery(ITextChannel ch, string query) + public static async Task ValidateQuery(IMessageChannel ch, string query) { if (!string.IsNullOrEmpty(query.Trim())) return true; await ch.SendErrorAsync("Please specify search parameters.").ConfigureAwait(false); diff --git a/src/NadekoBot/Modules/Trello/Trello.cs b/src/NadekoBot/Modules/Trello/Trello.cs deleted file mode 100644 index fbda6fab..00000000 --- a/src/NadekoBot/Modules/Trello/Trello.cs +++ /dev/null @@ -1,145 +0,0 @@ -//using Discord.Modules; -//using Manatee.Trello; -//using Manatee.Trello.ManateeJson; -//using NadekoBot.Extensions; -//using NadekoBot.Modules.Permissions.Classes; -//using System; -//using System.Collections.Generic; -//using System.Linq; -//using System.Timers; -//using Action = Manatee.Trello.Action; -////todo rewrite -//namespace NadekoBot.Modules.Trello -//{ -// public class Trello : DiscordModule -// { -// private readonly Timer t = new Timer { Interval = 2000 }; -// public override string Prefix { get; } = NadekoBot.Config.CommandPrefixes.Trello; - -// public override void Install(ModuleManager manager) -// { - -// var client = manager.Client; - -// var serializer = new ManateeSerializer(); -// TrelloConfiguration.Serializer = serializer; -// TrelloConfiguration.Deserializer = serializer; -// TrelloConfiguration.JsonFactory = new ManateeFactory(); -// TrelloConfiguration.RestClientProvider = new Manatee.Trello.WebApi.WebApiClientProvider(); -// TrelloAuthorization.Default.AppKey = NadekoBot.Credentials.TrelloAppKey; -// //TrelloAuthorization.Default.UserToken = "[your user token]"; - -// Discord.Channel bound = null; -// Board board = null; - -// List last5ActionIDs = null; -// t.Elapsed += async (s, e) => -// { -// try -// { -// if (board == null || bound == null) -// return; //do nothing if there is no bound board - -// board.Refresh(); -// var cur5Actions = board.Actions.Take(board.Actions.Count() < 5 ? board.Actions.Count() : 5); -// var cur5ActionsArray = cur5Actions as Action[] ?? cur5Actions.ToArray(); - -// if (last5ActionIDs == null) -// { -// last5ActionIDs = cur5ActionsArray.Select(a => a.Id).ToList(); -// return; -// } - -// foreach (var a in cur5ActionsArray.Where(ca => !last5ActionIDs.Contains(ca.Id))) -// { -// await bound.Send("**--TRELLO NOTIFICATION--**\n" + a.ToString()).ConfigureAwait(false); -// } -// last5ActionIDs.Clear(); -// last5ActionIDs.AddRange(cur5ActionsArray.Select(a => a.Id)); -// } -// catch (Exception ex) -// { -// Console.WriteLine("Timer failed " + ex.ToString()); -// } -// }; - -// manager.CreateCommands("", cgb => -// { - -// cgb.AddCheck(PermissionChecker.Instance); - -// cgb.CreateCommand(Prefix + "bind") -// .Description("Bind a trello bot to a single channel. " + -// "You will receive notifications from your board when something is added or edited." + -// $" **Bot Owner Only!**| `{Prefix}bind [board_id]`") -// .Parameter("board_id", Discord.Commands.ParameterType.Required) -// .Do(async e => -// { -// if (!NadekoBot.IsOwner(umsg.Author.Id)) return; -// if (bound != null) return; -// try -// { -// bound = e.Channel; -// board = new Board(board_id.Trim()); -// board.Refresh(); -// await channel.SendMessageAsync("Successfully bound to this channel and board " + board.Name); -// t.Start(); -// } -// catch (Exception ex) -// { -// Console.WriteLine("Failed to join the board. " + ex.ToString()); -// } -// }); - -// cgb.CreateCommand(Prefix + "unbind") -// .Description($"Unbinds a bot from the channel and board. **Bot Owner Only!**| `{Prefix}unbind`") -// .Do(async e => -// { -// if (!NadekoBot.IsOwner(umsg.Author.Id)) return; -// if (bound == null || bound != e.Channel) return; -// t.Stop(); -// bound = null; -// board = null; -// await channel.SendMessageAsync("Successfully unbound trello from this channel.").ConfigureAwait(false); - -// }); - -// cgb.CreateCommand(Prefix + "lists") -// .Alias(Prefix + "list") -// .Description($"Lists all lists, yo ;) **Bot Owner Only!**| `{Prefix}list`") -// .Do(async e => -// { -// if (!NadekoBot.IsOwner(umsg.Author.Id)) return; -// if (bound == null || board == null || bound != e.Channel) return; -// await channel.SendMessageAsync("Lists for a board '" + board.Name + "'\n" + string.Join("\n", board.Lists.Select(l => "**• " + l.ToString() + "**"))) -// .ConfigureAwait(false); -// }); - -// cgb.CreateCommand(Prefix + "cards") -// .Description($"Lists all cards from the supplied list. You can supply either a name or an index. **Bot Owner Only!**| `{Prefix}cards index`") -// .Parameter("list_name", Discord.Commands.ParameterType.Unparsed) -// .Do(async e => -// { -// if (!NadekoBot.IsOwner(umsg.Author.Id)) return; -// if (bound == null || board == null || bound != e.Channel || list_name == null) return; - -// int num; -// var success = int.TryParse(list_name, out num); -// List list = null; -// if (success && num <= board.Lists.Count() && num > 0) -// list = board.Lists[num - 1]; -// else -// list = board.Lists.FirstOrDefault(l => l.Name == list_name); - - -// if (list != null) -// await channel.SendMessageAsync("There are " + list.Cards.Count() + " cards in a **" + list.Name + "** list\n" + string.Join("\n", list.Cards.Select(c => "**• " + c.ToString() + "**"))) -// .ConfigureAwait(false); -// else -// await channel.SendMessageAsync("No such list.") -// .ConfigureAwait(false); -// }); -// }); -// } -// } -//} diff --git a/src/NadekoBot/Modules/Utility/Commands/CalcCommand.cs b/src/NadekoBot/Modules/Utility/Commands/CalcCommand.cs index 120fc4fc..b4327c85 100644 --- a/src/NadekoBot/Modules/Utility/Commands/CalcCommand.cs +++ b/src/NadekoBot/Modules/Utility/Commands/CalcCommand.cs @@ -1,68 +1,70 @@ -using Discord; -using Discord.Commands; +using Discord.Commands; using NadekoBot.Attributes; using NadekoBot.Extensions; using System; -using System.Collections; using System.Collections.Generic; using System.Linq; using System.Reflection; -using System.Text; using System.Threading.Tasks; namespace NadekoBot.Modules.Utility { public partial class Utility { - [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public static async Task Calculate(IUserMessage msg, [Remainder] string expression) + [Group] + public class CalcCommands : ModuleBase { - var expr = new NCalc.Expression(expression, NCalc.EvaluateOptions.IgnoreCase); - expr.EvaluateParameter += Expr_EvaluateParameter; - var result = expr.Evaluate(); - if (expr.Error == null) - await msg.Channel.SendConfirmAsync("Result", $"{result}"); - else - await msg.Channel.SendErrorAsync($"⚙ Error", expr.Error); - } - - private static void Expr_EvaluateParameter(string name, NCalc.ParameterArgs args) - { - switch (name.ToLowerInvariant()) { - case "pi": args.Result= Math.PI; - break; - case "e": args.Result = Math.E; - break; - } - } - - [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task CalcOps(IUserMessage msg) - { - var selection = typeof(Math).GetTypeInfo().GetMethods().Except(typeof(object).GetTypeInfo().GetMethods()).Distinct(new MethodInfoEqualityComparer()).Select(x => + [NadekoCommand, Usage, Description, Aliases] + public async Task Calculate([Remainder] string expression) { - return x.Name; - }) - .Except(new[] { "ToString", + var expr = new NCalc.Expression(expression, NCalc.EvaluateOptions.IgnoreCase); + expr.EvaluateParameter += Expr_EvaluateParameter; + var result = expr.Evaluate(); + if (expr.Error == null) + await Context.Channel.SendConfirmAsync("Result", $"{result}"); + else + await Context.Channel.SendErrorAsync($"⚙ Error", expr.Error); + } + + private static void Expr_EvaluateParameter(string name, NCalc.ParameterArgs args) + { + switch (name.ToLowerInvariant()) + { + case "pi": + args.Result = Math.PI; + break; + case "e": + args.Result = Math.E; + break; + } + } + + [NadekoCommand, Usage, Description, Aliases] + public async Task CalcOps() + { + var selection = typeof(Math).GetTypeInfo().GetMethods().Except(typeof(object).GetTypeInfo().GetMethods()).Distinct(new MethodInfoEqualityComparer()).Select(x => + { + return x.Name; + }) + .Except(new[] { "ToString", "Equals", "GetHashCode", "GetType"}); - await msg.Channel.SendConfirmAsync("Available functions in calc", string.Join(", ", selection)); + await Context.Channel.SendConfirmAsync("Available functions in calc", string.Join(", ", selection)); + } } + + class MethodInfoEqualityComparer : IEqualityComparer + { + public bool Equals(MethodInfo x, MethodInfo y) => x.Name == y.Name; + + public int GetHashCode(MethodInfo obj) => obj.Name.GetHashCode(); + } + + class ExpressionContext + { + public double Pi { get; set; } = Math.PI; + } + } - - class MethodInfoEqualityComparer : IEqualityComparer - { - public bool Equals(MethodInfo x, MethodInfo y) => x.Name == y.Name; - - public int GetHashCode(MethodInfo obj) => obj.Name.GetHashCode(); - } - - class ExpressionContext - { - public double Pi { get; set; } = Math.PI; - } - -} +} \ No newline at end of file diff --git a/src/NadekoBot/Modules/Utility/Commands/InfoCommands.cs b/src/NadekoBot/Modules/Utility/Commands/InfoCommands.cs index c1cdf4c8..ca2ab738 100644 --- a/src/NadekoBot/Modules/Utility/Commands/InfoCommands.cs +++ b/src/NadekoBot/Modules/Utility/Commands/InfoCommands.cs @@ -4,7 +4,6 @@ using NadekoBot.Attributes; using NadekoBot.Extensions; using System; using System.Linq; -using System.Net.Http; using System.Text; using System.Threading.Tasks; @@ -12,88 +11,93 @@ namespace NadekoBot.Modules.Utility { public partial class Utility { - [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task ServerInfo(IUserMessage msg, string guildName = null) + [Group] + public class InfoCommands : ModuleBase { - var channel = (ITextChannel)msg.Channel; - guildName = guildName?.ToUpperInvariant(); - IGuild guild; - if (string.IsNullOrWhiteSpace(guildName)) - guild = channel.Guild; - else - guild = NadekoBot.Client.GetGuilds().Where(g => g.Name.ToUpperInvariant() == guildName.ToUpperInvariant()).FirstOrDefault(); - if (guild == null) - return; - var ownername = await guild.GetUserAsync(guild.OwnerId); - var textchn = (await guild.GetTextChannelsAsync()).Count(); - var voicechn = (await guild.GetVoiceChannelsAsync()).Count(); - - var createdAt = new DateTime(2015, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(guild.Id >> 22); - var sb = new StringBuilder(); - var users = await guild.GetUsersAsync().ConfigureAwait(false); - var embed = new EmbedBuilder() - .WithAuthor(eab => eab.WithName("Server Info")) - .WithTitle(guild.Name) - .AddField(fb => fb.WithName("**ID**").WithValue(guild.Id.ToString()).WithIsInline(true)) - .AddField(fb => fb.WithName("**Owner**").WithValue(ownername.ToString()).WithIsInline(true)) - .AddField(fb => fb.WithName("**Members**").WithValue(users.Count.ToString()).WithIsInline(true)) - .AddField(fb => fb.WithName("**Text Channels**").WithValue(textchn.ToString()).WithIsInline(true)) - .AddField(fb => fb.WithName("**Voice Channels**").WithValue(voicechn.ToString()).WithIsInline(true)) - .AddField(fb => fb.WithName("**Created At**").WithValue($"{createdAt.ToString("dd.MM.yyyy HH:mm")}").WithIsInline(true)) - .AddField(fb => fb.WithName("**Region**").WithValue(guild.VoiceRegionId.ToString()).WithIsInline(true)) - .AddField(fb => fb.WithName("**Roles**").WithValue(guild.Roles.Count().ToString()).WithIsInline(true)) - .WithImage(tn => tn.WithUrl(guild.IconUrl)) - .WithOkColor(); - if (guild.Emojis.Count() > 0) + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + public async Task ServerInfo(string guildName = null) { - embed.AddField(fb => fb.WithName("**Custom Emojis**").WithValue(Format.Italics(string.Join(", ", guild.Emojis))).WithIsInline(true)); + var channel = (ITextChannel)Context.Channel; + guildName = guildName?.ToUpperInvariant(); + IGuild guild; + if (string.IsNullOrWhiteSpace(guildName)) + guild = channel.Guild; + else + guild = NadekoBot.Client.GetGuilds().Where(g => g.Name.ToUpperInvariant() == guildName.ToUpperInvariant()).FirstOrDefault(); + if (guild == null) + return; + var ownername = await guild.GetUserAsync(guild.OwnerId); + var textchn = (await guild.GetTextChannelsAsync()).Count(); + var voicechn = (await guild.GetVoiceChannelsAsync()).Count(); + + var createdAt = new DateTime(2015, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(guild.Id >> 22); + var sb = new StringBuilder(); + var users = await guild.GetUsersAsync().ConfigureAwait(false); + var embed = new EmbedBuilder() + .WithAuthor(eab => eab.WithName("Server Info")) + .WithTitle(guild.Name) + .AddField(fb => fb.WithName("**ID**").WithValue(guild.Id.ToString()).WithIsInline(true)) + .AddField(fb => fb.WithName("**Owner**").WithValue(ownername.ToString()).WithIsInline(true)) + .AddField(fb => fb.WithName("**Members**").WithValue(users.Count.ToString()).WithIsInline(true)) + .AddField(fb => fb.WithName("**Text Channels**").WithValue(textchn.ToString()).WithIsInline(true)) + .AddField(fb => fb.WithName("**Voice Channels**").WithValue(voicechn.ToString()).WithIsInline(true)) + .AddField(fb => fb.WithName("**Created At**").WithValue($"{createdAt.ToString("dd.MM.yyyy HH:mm")}").WithIsInline(true)) + .AddField(fb => fb.WithName("**Region**").WithValue(guild.VoiceRegionId.ToString()).WithIsInline(true)) + .AddField(fb => fb.WithName("**Roles**").WithValue(guild.Roles.Count().ToString()).WithIsInline(true)) + .WithImageUrl(guild.IconUrl) + .WithColor(NadekoBot.OkColor); + if (guild.Emojis.Count() > 0) + { + embed.AddField(fb => fb.WithName("**Custom Emojis**").WithValue(Format.Italics(string.Join(", ", guild.Emojis))).WithIsInline(true)); + } + await Context.Channel.EmbedAsync(embed).ConfigureAwait(false); } - await msg.Channel.EmbedAsync(embed.Build()).ConfigureAwait(false); - } - [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task ChannelInfo(IUserMessage msg, ITextChannel channel = null) - { - var ch = channel ?? (ITextChannel)msg.Channel; - if (ch == null) - return; - var createdAt = new DateTime(2015, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(ch.Id >> 22); - var usercount = (await ch.GetUsersAsync()).Count(); - var embed = new EmbedBuilder() - .WithTitle(ch.Name) - .WithDescription(ch.Topic?.SanitizeMentions()) - .AddField(fb => fb.WithName("**ID**").WithValue(ch.Id.ToString()).WithIsInline(true)) - .AddField(fb => fb.WithName("**Created At**").WithValue($"{createdAt.ToString("dd.MM.yyyy HH:mm")}").WithIsInline(true)) - .AddField(fb => fb.WithName("**Users**").WithValue(usercount.ToString()).WithIsInline(true)) - .WithOkColor(); - await msg.Channel.EmbedAsync(embed.Build()).ConfigureAwait(false); - } - - [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task UserInfo(IUserMessage msg, IGuildUser usr = null) - { - var channel = (ITextChannel)msg.Channel; - var user = usr ?? msg.Author as IGuildUser; - - if (user == null) - return; - - var embed = new EmbedBuilder() - .AddField(fb => fb.WithName("**Name**").WithValue($"**{user.Username}**#{user.Discriminator}").WithIsInline(true)); - if (!string.IsNullOrWhiteSpace(user.Nickname)) { - embed.AddField(fb => fb.WithName("**Nickname**").WithValue(user.Nickname).WithIsInline(true)); + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + public async Task ChannelInfo(ITextChannel channel = null) + { + var ch = channel ?? (ITextChannel)Context.Channel; + if (ch == null) + return; + var createdAt = new DateTime(2015, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(ch.Id >> 22); + var usercount = (await ch.GetUsersAsync().Flatten()).Count(); + var embed = new EmbedBuilder() + .WithTitle(ch.Name) + .WithDescription(ch.Topic?.SanitizeMentions()) + .AddField(fb => fb.WithName("**ID**").WithValue(ch.Id.ToString()).WithIsInline(true)) + .AddField(fb => fb.WithName("**Created At**").WithValue($"{createdAt.ToString("dd.MM.yyyy HH:mm")}").WithIsInline(true)) + .AddField(fb => fb.WithName("**Users**").WithValue(usercount.ToString()).WithIsInline(true)) + .WithColor(NadekoBot.OkColor); + await Context.Channel.EmbedAsync(embed).ConfigureAwait(false); + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + public async Task UserInfo(IGuildUser usr = null) + { + var channel = (ITextChannel)Context.Channel; + var user = usr ?? Context.User as IGuildUser; + + if (user == null) + return; + + var embed = new EmbedBuilder() + .AddField(fb => fb.WithName("**Name**").WithValue($"**{user.Username}**#{user.Discriminator}").WithIsInline(true)); + if (!string.IsNullOrWhiteSpace(user.Nickname)) + { + embed.AddField(fb => fb.WithName("**Nickname**").WithValue(user.Nickname).WithIsInline(true)); + } + embed.AddField(fb => fb.WithName("**ID**").WithValue(user.Id.ToString()).WithIsInline(true)) + .AddField(fb => fb.WithName("**Joined Server**").WithValue($"{user.JoinedAt?.ToString("dd.MM.yyyy HH:mm")}").WithIsInline(true)) + .AddField(fb => fb.WithName("**Joined Discord**").WithValue($"{user.CreatedAt.ToString("dd.MM.yyyy HH:mm")}").WithIsInline(true)) + .AddField(fb => fb.WithName("**Current Game**").WithValue($"{(user.Game?.Name == null ? "-" : user.Game.Value.Name)}").WithIsInline(true)) + .AddField(fb => fb.WithName("**Roles**").WithValue($"**({user.RoleIds.Count})** - {string.Join(", ", user.GetRoles().Select(r => r.Name)).SanitizeMentions()}").WithIsInline(true)) + .WithThumbnailUrl(user.AvatarUrl) + .WithColor(NadekoBot.OkColor); + await Context.Channel.EmbedAsync(embed).ConfigureAwait(false); } - embed.AddField(fb => fb.WithName("**ID**").WithValue(user.Id.ToString()).WithIsInline(true)) - .AddField(fb => fb.WithName("**Joined Server**").WithValue($"{user.JoinedAt?.ToString("dd.MM.yyyy HH:mm")}").WithIsInline(true)) - .AddField(fb => fb.WithName("**Joined Discord**").WithValue($"{user.CreatedAt.ToString("dd.MM.yyyy HH:mm")}").WithIsInline(true)) - .AddField(fb => fb.WithName("**Current Game**").WithValue($"{(user.Game?.Name == null ? "-" : user.Game.Name)}").WithIsInline(true)) - .AddField(fb => fb.WithName("**Roles**").WithValue($"**({user.Roles.Count()})** - {string.Join(", ", user.Roles.Select(r => r.Name)).SanitizeMentions()}").WithIsInline(true)) - .WithThumbnail(tn => tn.WithUrl(user.AvatarUrl)) - .WithOkColor(); - await msg.Channel.EmbedAsync(embed.Build()).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -118,8 +122,7 @@ namespace NadekoBot.Modules.Utility await imsg.Channel.EmbedAsync(new EmbedBuilder().WithTitle($"Activity Page #{page}") .WithOkColor() .WithFooter(efb => efb.WithText($"{NadekoBot.CommandHandler.UserMessagesSent.Count} users total.")) - .WithDescription(str.ToString()) - .Build()); + .WithDescription(str.ToString())); } } -} +} \ No newline at end of file diff --git a/src/NadekoBot/Modules/Utility/Commands/QuoteCommands.cs b/src/NadekoBot/Modules/Utility/Commands/QuoteCommands.cs index 41ce9aa8..7796571d 100644 --- a/src/NadekoBot/Modules/Utility/Commands/QuoteCommands.cs +++ b/src/NadekoBot/Modules/Utility/Commands/QuoteCommands.cs @@ -13,133 +13,127 @@ namespace NadekoBot.Modules.Utility { public partial class Utility { - [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task ListQuotes(IUserMessage imsg, int page = 1) + [Group] + public class QuoteCommands : ModuleBase { - var channel = (ITextChannel)imsg.Channel; - - page -= 1; - - if (page < 0) - return; - - IEnumerable quotes; - using (var uow = DbHandler.UnitOfWork()) + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + public async Task ListQuotes(int page = 1) { - quotes = uow.Quotes.GetGroup(channel.Guild.Id, page * 16, 16); - } + page -= 1; - if (quotes.Any()) - await channel.SendConfirmAsync($"💬 **Page {page + 1} of quotes:**\n```xl\n" + String.Join("\n", quotes.Select((q) => $"{q.Keyword,-20} by {q.AuthorName}")) + "\n```") - .ConfigureAwait(false); - else - await channel.SendErrorAsync("No quotes on this page.").ConfigureAwait(false); - } - - [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task ShowQuote(IUserMessage umsg, [Remainder] string keyword) - { - var channel = (ITextChannel)umsg.Channel; - - if (string.IsNullOrWhiteSpace(keyword)) - return; - - keyword = keyword.ToUpperInvariant(); - - Quote quote; - using (var uow = DbHandler.Instance.GetUnitOfWork()) - { - quote = await uow.Quotes.GetRandomQuoteByKeywordAsync(channel.Guild.Id, keyword).ConfigureAwait(false); - } - - if (quote == null) - return; - - await channel.SendMessageAsync("📣 " + quote.Text.SanitizeMentions()); - } - - [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task AddQuote(IUserMessage umsg, string keyword, [Remainder] string text) - { - var channel = (ITextChannel)umsg.Channel; - - if (string.IsNullOrWhiteSpace(keyword) || string.IsNullOrWhiteSpace(text)) - return; - - keyword = keyword.ToUpperInvariant(); - - using (var uow = DbHandler.UnitOfWork()) - { - uow.Quotes.Add(new Quote - { - AuthorId = umsg.Author.Id, - AuthorName = umsg.Author.Username, - GuildId = channel.Guild.Id, - Keyword = keyword, - Text = text, - }); - await uow.CompleteAsync().ConfigureAwait(false); - } - await channel.SendConfirmAsync("✅ Quote added.").ConfigureAwait(false); - } - - [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task DeleteQuote(IUserMessage umsg, [Remainder] string keyword) - { - var channel = (ITextChannel)umsg.Channel; - - if (string.IsNullOrWhiteSpace(keyword)) - return; - - var isAdmin = ((IGuildUser)umsg.Author).GuildPermissions.Administrator; - - keyword = keyword.ToUpperInvariant(); - string response; - using (var uow = DbHandler.UnitOfWork()) - { - var qs = uow.Quotes.GetAllQuotesByKeyword(channel.Guild.Id, keyword); - - if (qs==null || !qs.Any()) - { - await channel.SendErrorAsync("No quotes found."); + if (page < 0) return; + + IEnumerable quotes; + using (var uow = DbHandler.UnitOfWork()) + { + quotes = uow.Quotes.GetGroup(Context.Guild.Id, page * 16, 16); } - var q = qs.Shuffle().FirstOrDefault(elem => isAdmin || elem.AuthorId == umsg.Author.Id); - - uow.Quotes.Remove(q); - await uow.CompleteAsync().ConfigureAwait(false); - response = "🗑 **Deleted a random quote.**"; + if (quotes.Any()) + await Context.Channel.SendConfirmAsync($"💬 **Page {page + 1} of quotes:**\n```xl\n" + String.Join("\n", quotes.Select((q) => $"{q.Keyword,-20} by {q.AuthorName}")) + "\n```") + .ConfigureAwait(false); + else + await Context.Channel.SendErrorAsync("No quotes on this page.").ConfigureAwait(false); } - await channel.SendConfirmAsync(response); - } - [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.Administrator)] - public async Task DelAllQuotes(IUserMessage umsg, [Remainder] string keyword) - { - var channel = (ITextChannel)umsg.Channel; - - if (string.IsNullOrWhiteSpace(keyword)) - return; - - keyword = keyword.ToUpperInvariant(); - - using (var uow = DbHandler.UnitOfWork()) + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + public async Task ShowQuote([Remainder] string keyword) { - var quotes = uow.Quotes.GetAllQuotesByKeyword(channel.Guild.Id, keyword); + if (string.IsNullOrWhiteSpace(keyword)) + return; - uow.Quotes.RemoveRange(quotes.ToArray());//wtf?! + keyword = keyword.ToUpperInvariant(); - await uow.CompleteAsync(); + Quote quote; + using (var uow = DbHandler.Instance.GetUnitOfWork()) + { + quote = await uow.Quotes.GetRandomQuoteByKeywordAsync(Context.Guild.Id, keyword).ConfigureAwait(false); + } + + if (quote == null) + return; + + await Context.Channel.SendMessageAsync("📣 " + quote.Text.SanitizeMentions()); } - await channel.SendConfirmAsync($"🗑 **Deleted all quotes** with **{keyword}** keyword."); + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + public async Task AddQuote(string keyword, [Remainder] string text) + { + if (string.IsNullOrWhiteSpace(keyword) || string.IsNullOrWhiteSpace(text)) + return; + + keyword = keyword.ToUpperInvariant(); + + using (var uow = DbHandler.UnitOfWork()) + { + uow.Quotes.Add(new Quote + { + AuthorId = Context.Message.Author.Id, + AuthorName = Context.Message.Author.Username, + GuildId = Context.Guild.Id, + Keyword = keyword, + Text = text, + }); + await uow.CompleteAsync().ConfigureAwait(false); + } + await Context.Channel.SendConfirmAsync("✅ Quote added.").ConfigureAwait(false); + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + public async Task DeleteQuote([Remainder] string keyword) + { + if (string.IsNullOrWhiteSpace(keyword)) + return; + + var isAdmin = ((IGuildUser)Context.Message.Author).GuildPermissions.Administrator; + + keyword = keyword.ToUpperInvariant(); + string response; + using (var uow = DbHandler.UnitOfWork()) + { + var qs = uow.Quotes.GetAllQuotesByKeyword(Context.Guild.Id, keyword); + + if (qs == null || !qs.Any()) + { + await Context.Channel.SendErrorAsync("No quotes found.").ConfigureAwait(false); + return; + } + + var q = qs.Shuffle().FirstOrDefault(elem => isAdmin || elem.AuthorId == Context.Message.Author.Id); + + uow.Quotes.Remove(q); + await uow.CompleteAsync().ConfigureAwait(false); + response = "🗑 **Deleted a random quote.**"; + } + await Context.Channel.SendConfirmAsync(response); + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [RequireUserPermission(GuildPermission.Administrator)] + public async Task DelAllQuotes([Remainder] string keyword) + { + if (string.IsNullOrWhiteSpace(keyword)) + return; + + keyword = keyword.ToUpperInvariant(); + + using (var uow = DbHandler.UnitOfWork()) + { + var quotes = uow.Quotes.GetAllQuotesByKeyword(Context.Guild.Id, keyword); + + uow.Quotes.RemoveRange(quotes.ToArray());//wtf?! + + await uow.CompleteAsync(); + } + + await Context.Channel.SendConfirmAsync($"🗑 **Deleted all quotes** with **{keyword}** keyword."); + } } } -} +} \ No newline at end of file diff --git a/src/NadekoBot/Modules/Utility/Commands/Remind.cs b/src/NadekoBot/Modules/Utility/Commands/Remind.cs index 60ba241a..6cb3965f 100644 --- a/src/NadekoBot/Modules/Utility/Commands/Remind.cs +++ b/src/NadekoBot/Modules/Utility/Commands/Remind.cs @@ -1,6 +1,5 @@ using Discord; using Discord.Commands; -using Discord.WebSocket; using NadekoBot.Attributes; using NadekoBot.Extensions; using NadekoBot.Services; @@ -17,23 +16,23 @@ namespace NadekoBot.Modules.Utility public partial class Utility { [Group] - public class RemindCommands + public class RemindCommands : ModuleBase { Regex regex = new Regex(@"^(?:(?\d)mo)?(?:(?\d)w)?(?:(?\d{1,2})d)?(?:(?\d{1,2})h)?(?:(?\d{1,2})m)?$", RegexOptions.Compiled | RegexOptions.Multiline); - private string RemindMessageFormat { get; } + private static string RemindMessageFormat { get; } - IDictionary> replacements = new Dictionary> + private static IDictionary> replacements = new Dictionary> { { "%message%" , (r) => r.Message }, { "%user%", (r) => $"<@!{r.UserId}>" }, { "%target%", (r) => r.IsPrivate ? "Direct Message" : $"<#{r.ChannelId}>"} }; - private Logger _log { get; } + private static Logger _log { get; } - public RemindCommands() + static RemindCommands() { _log = LogManager.GetCurrentClassLogger(); List reminders; @@ -50,7 +49,7 @@ namespace NadekoBot.Modules.Utility } } - private async Task StartReminder(Reminder r) + private static async Task StartReminder(Reminder r) { var now = DateTime.Now; var twoMins = new TimeSpan(0, 2, 0); @@ -62,14 +61,16 @@ namespace NadekoBot.Modules.Utility await Task.Delay(time); try { - IMessageChannel ch; + IMessageChannel ch = null; if (r.IsPrivate) { ch = await NadekoBot.Client.GetDMChannelAsync(r.ChannelId).ConfigureAwait(false); } else { - ch = NadekoBot.Client.GetGuild(r.ServerId)?.GetTextChannel(r.ChannelId); + var t = NadekoBot.Client.GetGuild(r.ServerId)?.GetTextChannelAsync(r.ChannelId).ConfigureAwait(false); + if (t != null) + ch = await t.Value; } if (ch == null) return; @@ -99,32 +100,30 @@ namespace NadekoBot.Modules.Utility [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] [Priority(1)] - public async Task Remind(IUserMessage umsg, MeOrHere meorhere, string timeStr, [Remainder] string message) + public async Task Remind(MeOrHere meorhere, string timeStr, [Remainder] string message) { - var channel = (ITextChannel)umsg.Channel; - IMessageChannel target; if (meorhere == MeOrHere.Me) { - target = await ((IGuildUser)umsg.Author).CreateDMChannelAsync().ConfigureAwait(false); + target = await ((IGuildUser)Context.User).CreateDMChannelAsync().ConfigureAwait(false); } else { - target = channel; + target = Context.Channel; } - await Remind(umsg, target, timeStr, message).ConfigureAwait(false); + await Remind(target, timeStr, message).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] [Priority(0)] - public async Task Remind(IUserMessage umsg, IMessageChannel ch, string timeStr, [Remainder] string message) + public async Task Remind(IMessageChannel ch, string timeStr, [Remainder] string message) { - var channel = (ITextChannel)umsg.Channel; + var channel = (ITextChannel)Context.Channel; if (ch == null) { - await channel.SendErrorAsync($"{umsg.Author.Mention} Something went wrong (channel cannot be found) ;(").ConfigureAwait(false); + await channel.SendErrorAsync($"{Context.User.Mention} Something went wrong (channel cannot be found) ;(").ConfigureAwait(false); return; } @@ -177,7 +176,7 @@ namespace NadekoBot.Modules.Utility IsPrivate = ch is IDMChannel, When = time, Message = message, - UserId = umsg.Author.Id, + UserId = Context.User.Id, ServerId = channel.Guild.Id }; @@ -187,16 +186,16 @@ namespace NadekoBot.Modules.Utility await uow.CompleteAsync(); } - try { await channel.SendConfirmAsync($"⏰ I will remind **\"{(ch is ITextChannel ? ((ITextChannel)ch).Name : umsg.Author.Username)}\"** to **\"{message.SanitizeMentions()}\"** in **{output}** `({time:d.M.yyyy.} at {time:HH:mm})`").ConfigureAwait(false); } catch { } + try { await channel.SendConfirmAsync($"⏰ I will remind **\"{(ch is ITextChannel ? ((ITextChannel)ch).Name : Context.User.Username)}\"** to **\"{message.SanitizeMentions()}\"** in **{output}** `({time:d.M.yyyy.} at {time:HH:mm})`").ConfigureAwait(false); } catch { } await StartReminder(rem); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] [OwnerOnly] - public async Task RemindTemplate(IUserMessage umsg, [Remainder] string arg) + public async Task RemindTemplate([Remainder] string arg) { - var channel = (ITextChannel)umsg.Channel; + var channel = (ITextChannel)Context.Channel; if (string.IsNullOrWhiteSpace(arg)) return; diff --git a/src/NadekoBot/Modules/Utility/Commands/UnitConversion.cs b/src/NadekoBot/Modules/Utility/Commands/UnitConversion.cs index 4ba6c05e..41ca8133 100644 --- a/src/NadekoBot/Modules/Utility/Commands/UnitConversion.cs +++ b/src/NadekoBot/Modules/Utility/Commands/UnitConversion.cs @@ -13,7 +13,6 @@ using System.Diagnostics; using System.IO; using System.Linq; using System.Net.Http; -using System.Text; using System.Threading; using System.Threading.Tasks; @@ -22,9 +21,8 @@ namespace NadekoBot.Modules.Utility public partial class Utility { [Group] - public class UnitConverterCommands + public class UnitConverterCommands : ModuleBase { - public static List Units { get; set; } = new List(); private static Logger _log { get; } private static Timer _timer; @@ -43,7 +41,7 @@ namespace NadekoBot.Modules.Utility }).ToArray(); using (var uow = DbHandler.UnitOfWork()) - { + { if (uow.ConverterUnits.Empty()) { uow.ConverterUnits.AddRange(data); @@ -56,16 +54,13 @@ namespace NadekoBot.Modules.Utility { _log.Warn("Could not load units: " + e.Message); } - } - public UnitConverterCommands() - { _timer = new Timer(async (obj) => await UpdateCurrency(), null, (int)updateInterval.TotalMilliseconds, (int)updateInterval.TotalMilliseconds); - } - public async Task UpdateCurrency() - {try + public static async Task UpdateCurrency() + { + try { var currencyRates = await UpdateCurrencyRates(); var unitTypeString = "currency"; @@ -96,36 +91,37 @@ namespace NadekoBot.Modules.Utility Units.AddRange(range); _log.Info("Updated Currency"); } - catch { + catch + { _log.Warn("Failed updating currency."); } } + [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task ConvertList(IUserMessage msg) + public async Task ConvertList() { var res = Units.GroupBy(x => x.UnitType) .Aggregate(new EmbedBuilder().WithTitle("__Units which can be used by the converter__") - .WithOkColor(), - (embed, g) => embed.AddField(efb => + .WithColor(NadekoBot.OkColor), + (embed, g) => embed.AddField(efb => efb.WithName(g.Key.ToTitleCase()) .WithValue(String.Join(", ", g.Select(x => x.Triggers.FirstOrDefault()) .OrderBy(x => x))))); - await msg.Channel.EmbedAsync(res.Build()); + await Context.Channel.EmbedAsync(res); } [NadekoCommand, Usage, Description, Aliases] - public async Task Convert(IUserMessage msg, string origin, string target, decimal value) + public async Task Convert(string origin, string target, decimal value) { var originUnit = Units.Find(x => x.Triggers.Select(y => y.ToLowerInvariant()).Contains(origin.ToLowerInvariant())); var targetUnit = Units.Find(x => x.Triggers.Select(y => y.ToLowerInvariant()).Contains(target.ToLowerInvariant())); if (originUnit == null || targetUnit == null) { - await msg.Channel.SendErrorAsync(string.Format("Cannot convert {0} to {1}: units not found", origin, target)); + await Context.Channel.SendErrorAsync(string.Format("Cannot convert {0} to {1}: units not found", origin, target)); return; } if (originUnit.UnitType != targetUnit.UnitType) { - await msg.Channel.SendErrorAsync(string.Format("Cannot convert {0} to {1}: types of unit are not equal", originUnit.Triggers.First(), targetUnit.Triggers.First())); + await Context.Channel.SendErrorAsync(string.Format("Cannot convert {0} to {1}: types of unit are not equal", originUnit.Triggers.First(), targetUnit.Triggers.First())); return; } decimal res; @@ -169,7 +165,7 @@ namespace NadekoBot.Modules.Utility } res = Math.Round(res, 4); - await msg.Channel.SendConfirmAsync(string.Format("{0} {1} is equal to {2} {3}", value, (originUnit.Triggers.First() + "s").SnPl(value.IsInteger() ? (int)value : 2), res, (targetUnit.Triggers.First() + "s").SnPl(res.IsInteger() ? (int)res : 2))); + await Context.Channel.SendConfirmAsync(string.Format("{0} {1} is equal to {2} {3}", value, (originUnit.Triggers.First() + "s").SnPl(value.IsInteger() ? (int)value : 2), res, (targetUnit.Triggers.First() + "s").SnPl(res.IsInteger() ? (int)res : 2))); } } diff --git a/src/NadekoBot/Modules/Utility/Utility.cs b/src/NadekoBot/Modules/Utility/Utility.cs index 5de70a5f..27f8d25e 100644 --- a/src/NadekoBot/Modules/Utility/Utility.cs +++ b/src/NadekoBot/Modules/Utility/Utility.cs @@ -4,36 +4,21 @@ using NadekoBot.Attributes; using System; using System.Linq; using System.Threading.Tasks; -using NadekoBot.Services; using System.Text; using NadekoBot.Extensions; using System.Text.RegularExpressions; using System.Reflection; -using Discord.WebSocket; using NadekoBot.Services.Impl; -using Discord.API; -using Embed = Discord.API.Embed; -using EmbedAuthor = Discord.API.EmbedAuthor; -using EmbedField = Discord.API.EmbedField; using System.Net.Http; namespace NadekoBot.Modules.Utility { - [NadekoModule("Utility", ".")] public partial class Utility : DiscordModule { - public Utility() : base() - { - - } - [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task TogetherTube(IUserMessage imsg) + public async Task TogetherTube() { - var channel = (ITextChannel)imsg.Channel; - Uri target; using (var http = new HttpClient()) { @@ -41,113 +26,110 @@ namespace NadekoBot.Modules.Utility target = res.RequestMessage.RequestUri; } - await channel.EmbedAsync(new EmbedBuilder().WithOkColor() + await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor() .WithAuthor(eab => eab.WithIconUrl("https://togethertube.com/assets/img/favicons/favicon-32x32.png") .WithName("Together Tube") .WithUrl("https://togethertube.com/")) - .WithDescription($"{imsg.Author.Mention} Here is your room link:\n{target}") - .Build()); + .WithDescription($"{Context.User.Mention} Here is your room link:\n{target}")); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task WhosPlaying(IUserMessage umsg, [Remainder] string game = null) + public async Task WhosPlaying([Remainder] string game = null) { - var channel = (ITextChannel)umsg.Channel; game = game.Trim().ToUpperInvariant(); if (string.IsNullOrWhiteSpace(game)) return; - var usrs = (await (umsg.Channel as IGuildChannel).Guild.GetUsersAsync()) + var arr = (await (Context.Channel as IGuildChannel).Guild.GetUsersAsync()) .Where(u => u.Game?.Name?.ToUpperInvariant() == game) .Select(u => u.Username) .ToList(); int i = 0; - if (!usrs.Any()) - await channel.SendErrorAsync("Nobody is playing that game.").ConfigureAwait(false); + if (!arr.Any()) + await Context.Channel.SendErrorAsync("Nobody is playing that game.").ConfigureAwait(false); else - await channel.SendConfirmAsync($"List of users playing {game} game. Total {usrs.Count}.", "```css\n" + string.Join("\n", usrs.Take(30).GroupBy(item => (i++) / 2) + await Context.Channel.SendConfirmAsync("```css\n" + string.Join("\n", arr.GroupBy(item => (i++) / 2) .Select(ig => string.Concat(ig.Select(el => $"• {el,-27}")))) + "\n```") .ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task InRole(IUserMessage umsg, [Remainder] string roles) + public async Task InRole([Remainder] string roles) { if (string.IsNullOrWhiteSpace(roles)) return; - var channel = (ITextChannel)umsg.Channel; var arg = roles.Split(',').Select(r => r.Trim().ToUpperInvariant()); string send = "ℹ️ **Here is a list of users in those roles:**"; foreach (var roleStr in arg.Where(str => !string.IsNullOrWhiteSpace(str) && str != "@EVERYONE" && str != "EVERYONE")) { - var role = channel.Guild.Roles.Where(r => r.Name.ToUpperInvariant() == roleStr).FirstOrDefault(); + var role = Context.Guild.Roles.Where(r => r.Name.ToUpperInvariant() == roleStr).FirstOrDefault(); if (role == null) continue; send += $"```css\n[{role.Name}]\n"; - send += string.Join(", ", channel.Guild.GetUsers().Where(u => u.Roles.Contains(role)).Select(u => u.ToString())); + send += string.Join(", ", (await Context.Guild.GetUsersAsync()).Where(u => u.RoleIds.Contains(role.Id)).Select(u => u.ToString())); send += $"\n```"; } - var usr = umsg.Author as IGuildUser; + var usr = Context.User as IGuildUser; while (send.Length > 2000) { - if (!usr.GetPermissions(channel).ManageMessages) + if (!usr.GetPermissions((ITextChannel)Context.Channel).ManageMessages) { - await channel.SendErrorAsync($"⚠️ {usr.Mention} **you are not allowed to use this command on roles with a lot of users in them to prevent abuse.**").ConfigureAwait(false); + await Context.Channel.SendErrorAsync($"⚠️ {usr.Mention} **you are not allowed to use this command on roles with a lot of users in them to prevent abuse.**").ConfigureAwait(false); return; } var curstr = send.Substring(0, 2000); - await channel.SendConfirmAsync(curstr.Substring(0, + await Context.Channel.SendConfirmAsync(curstr.Substring(0, curstr.LastIndexOf(", ", StringComparison.Ordinal) + 1)).ConfigureAwait(false); send = curstr.Substring(curstr.LastIndexOf(", ", StringComparison.Ordinal) + 1) + send.Substring(2000); } - await channel.SendConfirmAsync(send).ConfigureAwait(false); + await Context.Channel.SendConfirmAsync(send).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task CheckMyPerms(IUserMessage msg) + public async Task CheckMyPerms() { StringBuilder builder = new StringBuilder("```http\n"); - var user = msg.Author as IGuildUser; - var perms = user.GetPermissions((ITextChannel)msg.Channel); + var user = Context.User as IGuildUser; + var perms = user.GetPermissions((ITextChannel)Context.Channel); foreach (var p in perms.GetType().GetProperties().Where(p => !p.GetGetMethod().GetParameters().Any())) { builder.AppendLine($"{p.Name} : {p.GetValue(perms, null).ToString()}"); } builder.Append("```"); - await msg.Channel.SendConfirmAsync(builder.ToString()); + await Context.Channel.SendConfirmAsync(builder.ToString()); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task UserId(IUserMessage msg, IGuildUser target = null) + public async Task UserId(IGuildUser target = null) { - var usr = target ?? msg.Author; - await msg.Channel.SendConfirmAsync($"🆔 of the user **{ usr.Username }** is `{ usr.Id }`").ConfigureAwait(false); + var usr = target ?? Context.User; + await Context.Channel.SendConfirmAsync($"🆔 of the user **{ usr.Username }** is `{ usr.Id }`").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] - public async Task ChannelId(IUserMessage msg) + public async Task ChannelId() { - await msg.Channel.SendConfirmAsync($"🆔 of this channel is `{msg.Channel.Id}`").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"🆔 of this channel is `{Context.Channel.Id}`").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task ServerId(IUserMessage msg) + public async Task ServerId() { - await msg.Channel.SendConfirmAsync($"🆔 of this server is `{((ITextChannel)msg.Channel).Guild.Id}`").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"🆔 of this server is `{Context.Guild.Id}`").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task Roles(IUserMessage msg, IGuildUser target, int page = 1) + public async Task Roles(IGuildUser target, int page = 1) { - var channel = (ITextChannel)msg.Channel; + var channel = (ITextChannel)Context.Channel; var guild = channel.Guild; const int RolesPerPage = 20; @@ -157,7 +139,7 @@ namespace NadekoBot.Modules.Utility if (target != null) { - var roles = target.Roles.Except(new[] { guild.EveryoneRole }).OrderBy(r => -r.Position).Skip((page - 1) * RolesPerPage).Take(RolesPerPage); + var roles = target.GetRoles().Except(new[] { guild.EveryoneRole }).OrderBy(r => -r.Position).Skip((page - 1) * RolesPerPage).Take(RolesPerPage); if (!roles.Any()) { await channel.SendErrorAsync("No roles on this page.").ConfigureAwait(false); @@ -183,14 +165,14 @@ namespace NadekoBot.Modules.Utility [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public Task Roles(IUserMessage msg, int page = 1) => - Roles(msg, null, page); + public Task Roles(int page = 1) => + Roles(null, page); [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task ChannelTopic(IUserMessage umsg) + public async Task ChannelTopic() { - var channel = (ITextChannel)umsg.Channel; + var channel = (ITextChannel)Context.Channel; var topic = channel.Topic; if (string.IsNullOrWhiteSpace(topic)) @@ -200,20 +182,18 @@ namespace NadekoBot.Modules.Utility } [NadekoCommand, Usage, Description, Aliases] - public async Task Stats(IUserMessage umsg) + public async Task Stats() { - var channel = umsg.Channel; - var stats = NadekoBot.Stats; - await channel.EmbedAsync( + await Context.Channel.EmbedAsync( new EmbedBuilder().WithOkColor() .WithAuthor(eab => eab.WithName($"NadekoBot v{StatsService.BotVersion}") .WithUrl("http://nadekobot.readthedocs.io/en/latest/") .WithIconUrl("https://cdn.discordapp.com/avatars/116275390695079945/b21045e778ef21c96d175400e779f0fb.jpg")) .AddField(efb => efb.WithName(Format.Bold("Author")).WithValue(stats.Author).WithIsInline(true)) .AddField(efb => efb.WithName(Format.Bold("Library")).WithValue(stats.Library).WithIsInline(true)) - .AddField(efb => efb.WithName(Format.Bold("Bot ID")).WithValue(NadekoBot.Client.GetCurrentUser().Id.ToString()).WithIsInline(true)) + .AddField(efb => efb.WithName(Format.Bold("Bot ID")).WithValue(NadekoBot.Client.CurrentUser().Id.ToString()).WithIsInline(true)) .AddField(efb => efb.WithName(Format.Bold("Commands Ran")).WithValue(stats.CommandsRan.ToString()).WithIsInline(true)) .AddField(efb => efb.WithName(Format.Bold("Messages")).WithValue($"{stats.MessageCounter} ({stats.MessagesPerSecond:F2}/sec)").WithIsInline(true)) .AddField(efb => efb.WithName(Format.Bold("Memory")).WithValue($"{stats.Heap} MB").WithIsInline(true)) @@ -223,12 +203,12 @@ namespace NadekoBot.Modules.Utility #if !GLOBAL_NADEKO .WithFooter(efb => efb.WithText($"Playing {Music.Music.MusicPlayers.Where(mp => mp.Value.CurrentSong != null).Count()} songs, {Music.Music.MusicPlayers.Sum(mp => mp.Value.Playlist.Count)} queued.")) #endif - .Build()); + ); } private Regex emojiFinder { get; } = new Regex(@"<:(?.+?):(?\d*)>", RegexOptions.Compiled); [NadekoCommand, Usage, Description, Aliases] - public async Task Showemojis(IUserMessage msg, [Remainder] string emojis) + public async Task Showemojis([Remainder] string emojis) { var matches = emojiFinder.Matches(emojis); @@ -236,18 +216,15 @@ namespace NadekoBot.Modules.Utility .Select(m => $"**Name:** {m.Groups["name"]} **Link:** http://discordapp.com/api/emojis/{m.Groups["id"]}.png")); if (string.IsNullOrWhiteSpace(result)) - await msg.Channel.SendErrorAsync("No special emojis found."); + await Context.Channel.SendErrorAsync("No special emojis found."); else - await msg.Channel.SendMessageAsync(result).ConfigureAwait(false); + await Context.Channel.SendMessageAsync(result).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] [OwnerOnly] - public async Task ListServers(IUserMessage imsg, int page = 1) + public async Task ListServers(int page = 1) { - var channel = (ITextChannel)imsg.Channel; - page -= 1; if (page < 0) @@ -257,15 +234,14 @@ namespace NadekoBot.Modules.Utility if (!guilds.Any()) { - await channel.SendErrorAsync("No servers found on that page.").ConfigureAwait(false); + await Context.Channel.SendErrorAsync("No servers found on that page.").ConfigureAwait(false); return; } - await channel.EmbedAsync(guilds.Aggregate(new EmbedBuilder().WithOkColor(), + await Context.Channel.EmbedAsync(guilds.Aggregate(new EmbedBuilder().WithOkColor(), (embed, g) => embed.AddField(efb => efb.WithName(g.Name) - .WithValue($"```css\nID: {g.Id}\nMembers: {g.GetUsers().Count}\nOwnerID: {g.OwnerId} ```") - .WithIsInline(false))) - .Build()) + .WithValue($"```css\nID: {g.Id}\nMembers: {g.Users.Count}\nOwnerID: {g.OwnerId} ```") + .WithIsInline(false)))) .ConfigureAwait(false); } } diff --git a/src/NadekoBot/NadekoBot.cs b/src/NadekoBot/NadekoBot.cs index 6abab6c3..8b7bba44 100644 --- a/src/NadekoBot/NadekoBot.cs +++ b/src/NadekoBot/NadekoBot.cs @@ -12,12 +12,10 @@ using System.Reflection; using System.Threading.Tasks; using System.Collections.Generic; using NadekoBot.Modules.Permissions; -using Module = Discord.Commands.Module; using NadekoBot.TypeReaders; using System.Collections.Concurrent; using NadekoBot.Modules.Music; using NadekoBot.Services.Database.Models; -using NadekoBot.Modules.Games.Commands.Hangman; namespace NadekoBot { @@ -25,12 +23,12 @@ namespace NadekoBot { private Logger _log; - public static uint OkColor { get; } = 0x71cd40; - public static uint ErrorColor { get; } = 0xee281f; + public static Color OkColor { get; } = new Color(0x71cd40); + public static Color ErrorColor { get; } = new Color(0xee281f); public static CommandService CommandService { get; private set; } public static CommandHandler CommandHandler { get; private set; } - public static ShardedDiscordClient Client { get; private set; } + public static ShardedDiscordClient Client { get; private set; } public static BotCredentials Credentials { get; private set; } public static GoogleApiService Google { get; private set; } @@ -69,7 +67,9 @@ namespace NadekoBot }); //initialize Services - CommandService = new CommandService(); + CommandService = new CommandService(new CommandServiceConfig() { + CaseSensitiveCommands = false + }); Google = new GoogleApiService(); CommandHandler = new CommandHandler(Client, CommandService); Stats = new StatsService(Client, CommandHandler); @@ -84,8 +84,8 @@ namespace NadekoBot //setup typereaders CommandService.AddTypeReader(new PermissionActionTypeReader()); - CommandService.AddTypeReader(new CommandTypeReader()); - CommandService.AddTypeReader(new ModuleTypeReader()); + CommandService.AddTypeReader(new CommandTypeReader()); + CommandService.AddTypeReader(new ModuleTypeReader()); CommandService.AddTypeReader(new GuildTypeReader()); //connect @@ -98,14 +98,14 @@ namespace NadekoBot //load commands and prefixes using (var uow = DbHandler.UnitOfWork()) { - ModulePrefixes = new ConcurrentDictionary(uow.BotConfig.GetOrCreate().ModulePrefixes.ToDictionary(m => m.ModuleName, m => m.Prefix)); + ModulePrefixes = new ConcurrentDictionary(uow.BotConfig.GetOrCreate().ModulePrefixes.OrderByDescending(mp => mp.Prefix.Length).ToDictionary(m => m.ModuleName, m => m.Prefix)); } // start handling messages received in commandhandler await CommandHandler.StartHandling().ConfigureAwait(false); - await CommandService.LoadAssembly(this.GetType().GetTypeInfo().Assembly).ConfigureAwait(false); + await CommandService.AddModulesAsync(this.GetType().GetTypeInfo().Assembly).ConfigureAwait(false); #if !GLOBAL_NADEKO - await CommandService.Load(new Music()).ConfigureAwait(false); + await CommandService.AddModuleAsync().ConfigureAwait(false); #endif Ready = true; Console.WriteLine(await Stats.Print().ConfigureAwait(false)); diff --git a/src/NadekoBot/Services/CommandHandler.cs b/src/NadekoBot/Services/CommandHandler.cs index d61b4f00..9b2e2f51 100644 --- a/src/NadekoBot/Services/CommandHandler.cs +++ b/src/NadekoBot/Services/CommandHandler.cs @@ -34,7 +34,7 @@ namespace NadekoBot.Services private List ownerChannels { get; set; } - public event Func CommandExecuted = delegate { return Task.CompletedTask; }; + public event Func CommandExecuted = delegate { return Task.CompletedTask; }; //userid/msg count public ConcurrentDictionary UserMessagesSent { get; } = new ConcurrentDictionary(); @@ -47,7 +47,7 @@ namespace NadekoBot.Services } public async Task StartHandling() { - ownerChannels = (await Task.WhenAll(_client.GetGuilds().SelectMany(g => g.GetUsers()) + ownerChannels = (await Task.WhenAll(_client.GetGuilds().SelectMany(g => g.Users) .Where(u => NadekoBot.Credentials.OwnerIds.Contains(u.Id)) .Distinct(new IGuildUserComparer()) .Select(async u => { try { return await u.CreateDMChannelAsync(); } catch { return null; } }))) @@ -62,47 +62,27 @@ namespace NadekoBot.Services _client.MessageReceived += MessageReceivedHandler; } - private async void MessageReceivedHandler(IMessage msg) + private async void MessageReceivedHandler(SocketMessage msg) { - try + var usrMsg = msg as SocketUserMessage; + if (usrMsg == null) + return; + + if (!usrMsg.IsAuthor()) + UserMessagesSent.AddOrUpdate(usrMsg.Author.Id, 1, (key, old) => ++old); + + if (msg.Author.IsBot || !NadekoBot.Ready) //no bots + return; + + var guild = (msg.Channel as SocketTextChannel)?.Guild; + + if (guild != null && guild.OwnerId != msg.Author.Id) { - var usrMsg = msg as IUserMessage; - if (usrMsg == null) - return; - - if (!usrMsg.IsAuthor()) - UserMessagesSent.AddOrUpdate(usrMsg.Author.Id, 1, (key, old) => ++old); - - if (usrMsg.Author.IsBot || !NadekoBot.Ready) //no bots - return; - var sw = new Stopwatch(); - sw.Start(); - - - var guild = (msg.Channel as ITextChannel)?.Guild; - - if (guild != null && guild.OwnerId != usrMsg.Author.Id) + //todo split checks into their own modules + if (Permissions.FilterCommands.InviteFilteringChannels.Contains(msg.Channel.Id) || + Permissions.FilterCommands.InviteFilteringServers.Contains(guild.Id)) { - if (Permissions.FilterCommands.InviteFilteringChannels.Contains(usrMsg.Channel.Id) || - Permissions.FilterCommands.InviteFilteringServers.Contains(guild.Id)) - { - if (usrMsg.Content.IsDiscordInvite()) - { - try - { - await usrMsg.DeleteAsync().ConfigureAwait(false); - return; - } - catch (HttpException ex) - { - _log.Warn("I do not have permission to filter invites in channel with id " + usrMsg.Channel.Id, ex); - } - } - } - - var filteredWords = Permissions.FilterCommands.FilteredWordsForChannel(usrMsg.Channel.Id, guild.Id).Concat(Permissions.FilterCommands.FilteredWordsForServer(guild.Id)); - var wordsInMessage = usrMsg.Content.ToLowerInvariant().Split(' '); - if (filteredWords.Any(w => wordsInMessage.Contains(w))) + if (usrMsg.Content.IsDiscordInvite()) { try { @@ -111,46 +91,69 @@ namespace NadekoBot.Services } catch (HttpException ex) { - _log.Warn("I do not have permission to filter words in channel with id " + usrMsg.Channel.Id, ex); + _log.Warn("I do not have permission to filter invites in channel with id " + msg.Channel.Id, ex); } } } - BlacklistItem blacklistedItem; - if ((blacklistedItem = Permissions.BlacklistCommands.BlacklistedItems.FirstOrDefault(bi => - (bi.Type == BlacklistItem.BlacklistType.Server && bi.ItemId == guild?.Id) || - (bi.Type == BlacklistItem.BlacklistType.Channel && bi.ItemId == msg.Channel.Id) || - (bi.Type == BlacklistItem.BlacklistType.User && bi.ItemId == usrMsg.Author.Id))) != null) + var filteredWords = Permissions.FilterCommands.FilteredWordsForChannel(msg.Channel.Id, guild.Id).Concat(Permissions.FilterCommands.FilteredWordsForServer(guild.Id)); + var wordsInMessage = usrMsg.Content.ToLowerInvariant().Split(' '); + if (filteredWords.Any(w => wordsInMessage.Contains(w))) { + try + { + await usrMsg.DeleteAsync().ConfigureAwait(false); + return; + } + catch (HttpException ex) + { + _log.Warn("I do not have permission to filter words in channel with id " + msg.Channel.Id, ex); + } + } + } + + BlacklistItem blacklistedItem; + if ((blacklistedItem = Permissions.BlacklistCommands.BlacklistedItems.FirstOrDefault(bi => + (bi.Type == BlacklistItem.BlacklistType.Server && bi.ItemId == guild?.Id) || + (bi.Type == BlacklistItem.BlacklistType.Channel && bi.ItemId == msg.Channel.Id) || + (bi.Type == BlacklistItem.BlacklistType.User && bi.ItemId == msg.Author.Id))) != null) + { + return; + } + + try + { + var cleverbotExecuted = await Games.CleverBotCommands.TryAsk(usrMsg); + + if (cleverbotExecuted) return; - } + } + catch (Exception ex) { _log.Warn(ex, "Error in cleverbot"); } - try - { - var cleverbotExecuted = await Games.CleverBotCommands.TryAsk(usrMsg); + try + { + // maybe this message is a custom reaction + var crExecuted = await CustomReactions.TryExecuteCustomReaction(usrMsg).ConfigureAwait(false); - if (cleverbotExecuted) - return; - } - catch (Exception ex) { _log.Warn(ex, "Error in cleverbot"); } + //if it was, don't execute the command + if (crExecuted) + return; + } + catch { } - try - { - // maybe this message is a custom reaction - var crExecuted = await CustomReactions.TryExecuteCustomReaction(usrMsg).ConfigureAwait(false); + string messageContent = usrMsg.Content; - //if it was, don't execute the command - if (crExecuted) - return; - } - catch { } + var sw = new Stopwatch(); + sw.Start(); - var t = await ExecuteCommand(usrMsg, usrMsg.Content, guild, usrMsg.Author, MultiMatchHandling.Best); - var command = t.Item1; - var permCache = t.Item2; - var result = t.Item3; + try + { + var exec = await ExecuteCommand(new CommandContext(_client.MainClient, usrMsg), messageContent, DependencyMap.Empty, MultiMatchHandling.Best); + var command = exec.CommandInfo; + var permCache = exec.PermissionCache; + var result = exec.Result; sw.Stop(); - var channel = (usrMsg.Channel as ITextChannel); + var channel = (msg.Channel as ITextChannel); if (result.IsSuccess) { await CommandExecuted(usrMsg, command); @@ -159,7 +162,7 @@ namespace NadekoBot.Services "Server: {1}\n\t" + "Channel: {2}\n\t" + "Message: {3}", - usrMsg.Author + " [" + usrMsg.Author.Id + "]", // {0} + msg.Author + " [" + msg.Author.Id + "]", // {0} (channel == null ? "PRIVATE" : channel.Guild.Name + " [" + channel.Guild.Id + "]"), // {1} (channel == null ? "PRIVATE" : channel.Name + " [" + channel.Id + "]"), // {2} usrMsg.Content, // {3} @@ -174,7 +177,7 @@ namespace NadekoBot.Services "Channel: {2}\n\t" + "Message: {3}\n\t" + "Error: {4}", - usrMsg.Author + " [" + usrMsg.Author.Id + "]", // {0} + msg.Author + " [" + msg.Author.Id + "]", // {0} (channel == null ? "PRIVATE" : channel.Guild.Name + " [" + channel.Guild.Id + "]"), // {1} (channel == null ? "PRIVATE" : channel.Name + " [" + channel.Id + "]"), // {2} usrMsg.Content,// {3} @@ -207,27 +210,34 @@ namespace NadekoBot.Services if (ex.InnerException != null) _log.Warn(ex.InnerException, "Inner Exception of the error in CommandHandler"); } - } - public async Task> ExecuteCommand(IUserMessage message, string input, IGuild guild, IUser user, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Best) + return; + } + public Task ExecuteCommandAsync(CommandContext context, int argPos, IDependencyMap dependencyMap = null, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception) + => ExecuteCommand(context, context.Message.Content.Substring(argPos), dependencyMap, multiMatchHandling); + + + public async Task ExecuteCommand(CommandContext context, string input, IDependencyMap dependencyMap = null, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception) { - var searchResult = _commandService.Search(message, input); + dependencyMap = dependencyMap ?? DependencyMap.Empty; + + var searchResult = _commandService.Search(context, input); if (!searchResult.IsSuccess) - return new Tuple(null, null, searchResult); + return new ExecuteCommandResult(null, null, searchResult); var commands = searchResult.Commands; for (int i = commands.Count - 1; i >= 0; i--) { - var preconditionResult = await commands[i].CheckPreconditions(message); + var preconditionResult = await commands[i].CheckPreconditionsAsync(context).ConfigureAwait(false); if (!preconditionResult.IsSuccess) { if (commands.Count == 1) - return new Tuple(null, null, searchResult); + return new ExecuteCommandResult(null, null, preconditionResult); else continue; } - var parseResult = await commands[i].Parse(message, searchResult, preconditionResult); + var parseResult = await commands[i].ParseAsync(context, searchResult, preconditionResult).ConfigureAwait(false); if (!parseResult.IsSuccess) { if (parseResult.Error == CommandError.MultipleMatches) @@ -246,22 +256,22 @@ namespace NadekoBot.Services if (!parseResult.IsSuccess) { if (commands.Count == 1) - return new Tuple(null, null, parseResult); + return new ExecuteCommandResult(null, null, parseResult); else continue; } } - var cmd = commands[i]; + var cmd = commands[i].Command; bool resetCommand = cmd.Name == "ResetPermissions"; PermissionCache pc; - if (guild != null) + if (context.Guild != null) { - pc = Permissions.Cache.GetOrAdd(guild.Id, (id) => + pc = Permissions.Cache.GetOrAdd(context.Guild.Id, (id) => { using (var uow = DbHandler.UnitOfWork()) { - var config = uow.GuildConfigs.PermissionsFor(guild.Id); + var config = uow.GuildConfigs.PermissionsFor(context.Guild.Id); return new PermissionCache() { Verbose = config.VerbosePermissions, @@ -271,42 +281,44 @@ namespace NadekoBot.Services } }); int index; - if (!resetCommand && !pc.RootPermission.AsEnumerable().CheckPermissions(message, cmd.Text, cmd.Module.Name, out index)) + if (!resetCommand && !pc.RootPermission.AsEnumerable().CheckPermissions(context.Message, cmd.Aliases.First(), cmd.Module.Name, out index)) { - var returnMsg = $"Permission number #{index + 1} **{pc.RootPermission.GetAt(index).GetCommand(guild)}** is preventing this action."; - return new Tuple(cmd, pc, SearchResult.FromError(CommandError.Exception, returnMsg)); + var returnMsg = $"Permission number #{index + 1} **{pc.RootPermission.GetAt(index).GetCommand((SocketGuild)context.Guild)}** is preventing this action."; + return new ExecuteCommandResult(cmd, pc, SearchResult.FromError(CommandError.Exception, returnMsg)); } - if (cmd.Module.Source.Name == typeof(Permissions).Name) //permissions, you must have special role + if (cmd.Module.Name == typeof(Permissions).Name) { - if (!((IGuildUser)user).Roles.Any(r => r.Name.Trim().ToLowerInvariant() == pc.PermRole.Trim().ToLowerInvariant())) + if (!((IGuildUser)context.User).GetRoles().Any(r => r.Name.Trim().ToLowerInvariant() == pc.PermRole.Trim().ToLowerInvariant())) { - return new Tuple(cmd, pc, SearchResult.FromError(CommandError.Exception, $"You need the **{pc.PermRole}** role in order to use permission commands.")); + return new ExecuteCommandResult(cmd, pc, SearchResult.FromError(CommandError.Exception, $"You need the **{pc.PermRole}** role in order to use permission commands.")); } } } - if (CmdCdsCommands.HasCooldown(cmd, guild, user)) - return new Tuple(cmd, null, SearchResult.FromError(CommandError.Exception, $"That command is on cooldown for you.")); + if (CmdCdsCommands.HasCooldown(cmd, context.Guild, context.User)) + return new ExecuteCommandResult(cmd, null, SearchResult.FromError(CommandError.Exception, $"That command is on cooldown for you.")); - return new Tuple(commands[i], null, await commands[i].Execute(message, parseResult)); + return new ExecuteCommandResult(cmd, null, await commands[i].ExecuteAsync(context, parseResult, dependencyMap)); } - return new Tuple(null, null, SearchResult.FromError(CommandError.UnknownCommand, "This input does not match any overload.")); + return new ExecuteCommandResult(null, null, SearchResult.FromError(CommandError.UnknownCommand, "This input does not match any overload.")); } - } - public class CommandExecutedEventArgs - { - public Command Command { get; } - public IUserMessage Message { get; } - - public CommandExecutedEventArgs(IUserMessage msg, Command cmd) + public struct ExecuteCommandResult { - Message = msg; - Command = cmd; + public readonly CommandInfo CommandInfo; + public readonly PermissionCache PermissionCache; + public readonly IResult Result; + + public ExecuteCommandResult(CommandInfo commandInfo, PermissionCache cache, IResult result) + { + this.CommandInfo = commandInfo; + this.PermissionCache = cache; + this.Result = result; + } } } } \ No newline at end of file diff --git a/src/NadekoBot/Services/CurrencyHandler.cs b/src/NadekoBot/Services/CurrencyHandler.cs index 45383968..01e649a2 100644 --- a/src/NadekoBot/Services/CurrencyHandler.cs +++ b/src/NadekoBot/Services/CurrencyHandler.cs @@ -9,7 +9,7 @@ namespace NadekoBot.Services { public static class CurrencyHandler { - public static async Task RemoveCurrencyAsync(IGuildUser author, string reason, long amount, bool sendMessage) + public static async Task RemoveCurrencyAsync(IUser author, string reason, long amount, bool sendMessage) { var success = await RemoveCurrencyAsync(author.Id, reason, amount); @@ -42,7 +42,7 @@ namespace NadekoBot.Services return true; } - public static async Task AddCurrencyAsync(IGuildUser author, string reason, long amount, bool sendMessage) + public static async Task AddCurrencyAsync(IUser author, string reason, long amount, bool sendMessage) { await AddCurrencyAsync(author.Id, reason, amount); diff --git a/src/NadekoBot/Services/Database/Models/PokeType.cs b/src/NadekoBot/Services/Database/Models/PokeType.cs index 402ffd28..d4956c96 100644 --- a/src/NadekoBot/Services/Database/Models/PokeType.cs +++ b/src/NadekoBot/Services/Database/Models/PokeType.cs @@ -1,11 +1,4 @@ -using Discord; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace NadekoBot.Services.Database.Models +namespace NadekoBot.Services.Database.Models { public class UserPokeTypes : DbEntity { diff --git a/src/NadekoBot/Services/Database/Repositories/IPokeGameRepository.cs b/src/NadekoBot/Services/Database/Repositories/IPokeGameRepository.cs index ca698422..af9b003b 100644 --- a/src/NadekoBot/Services/Database/Repositories/IPokeGameRepository.cs +++ b/src/NadekoBot/Services/Database/Repositories/IPokeGameRepository.cs @@ -1,5 +1,4 @@ using NadekoBot.Services.Database.Models; -using System.Collections.Generic; namespace NadekoBot.Services.Database.Repositories { diff --git a/src/NadekoBot/Services/Database/Repositories/Impl/PokeGameRepository.cs b/src/NadekoBot/Services/Database/Repositories/Impl/PokeGameRepository.cs index f23f17ca..06662b06 100644 --- a/src/NadekoBot/Services/Database/Repositories/Impl/PokeGameRepository.cs +++ b/src/NadekoBot/Services/Database/Repositories/Impl/PokeGameRepository.cs @@ -1,7 +1,4 @@ using NadekoBot.Services.Database.Models; -using System; -using System.Collections.Generic; -using System.Linq; using Microsoft.EntityFrameworkCore; namespace NadekoBot.Services.Database.Repositories.Impl diff --git a/src/NadekoBot/Services/Impl/StatsService.cs b/src/NadekoBot/Services/Impl/StatsService.cs index 1b569e39..9a0d160c 100644 --- a/src/NadekoBot/Services/Impl/StatsService.cs +++ b/src/NadekoBot/Services/Impl/StatsService.cs @@ -1,5 +1,4 @@ using Discord; -using Discord.WebSocket; using NadekoBot.Extensions; using System; using System.Collections.Generic; @@ -15,7 +14,7 @@ namespace NadekoBot.Services.Impl private ShardedDiscordClient client; private DateTime started; - public const string BotVersion = "1.0.0"; + public const string BotVersion = "1.1.0-alpha"; public string Author => "Kwoth#2560"; public string Library => "Discord.Net"; @@ -23,8 +22,8 @@ namespace NadekoBot.Services.Impl public int CommandsRan { get; private set; } = 0; public string Heap => Math.Round((double)GC.GetTotalMemory(false) / 1.MiB(), 2).ToString(); public double MessagesPerSecond => MessageCounter / (double)GetUptime().TotalSeconds; - public int TextChannels => client.GetGuilds().SelectMany(g => g.GetChannels().Where(c => c is ITextChannel)).Count(); - public int VoiceChannels => client.GetGuilds().SelectMany(g => g.GetChannels().Where(c => c is IVoiceChannel)).Count(); + public int TextChannels => client.GetGuilds().SelectMany(g => g.Channels.Where(c => c is ITextChannel)).Count(); + public int VoiceChannels => client.GetGuilds().SelectMany(g => g.Channels.Where(c => c is IVoiceChannel)).Count(); public string OwnerIds => string.Join(", ", NadekoBot.Credentials.OwnerIds); @@ -65,10 +64,10 @@ namespace NadekoBot.Services.Impl catch { } }, null, TimeSpan.FromHours(1), TimeSpan.FromHours(1)); } - public async Task Print() + public Task Print() { - var curUser = await client.GetCurrentUserAsync(); - return $@" + var curUser = client.CurrentUser(); + return Task.FromResult($@" Author: [{Author}] | Library: [{Library}] Bot Version: [{BotVersion}] Bot ID: {curUser.Id} @@ -76,7 +75,7 @@ Owner ID(s): {OwnerIds} Uptime: {GetUptimeString()} Servers: {client.GetGuilds().Count} | TextChannels: {TextChannels} | VoiceChannels: {VoiceChannels} Commands Ran this session: {CommandsRan} -Messages: {MessageCounter} [{MessagesPerSecond:F2}/sec] Heap: [{Heap} MB]"; +Messages: {MessageCounter} [{MessagesPerSecond:F2}/sec] Heap: [{Heap} MB]"); } public Task Reset() diff --git a/src/NadekoBot/ShardedDiscordClient.cs b/src/NadekoBot/ShardedDiscordClient.cs index 738f2007..fcee8863 100644 --- a/src/NadekoBot/ShardedDiscordClient.cs +++ b/src/NadekoBot/ShardedDiscordClient.cs @@ -14,19 +14,19 @@ namespace NadekoBot private DiscordSocketConfig discordSocketConfig; private Logger _log { get; } - public event Action UserJoined = delegate { }; - public event Action MessageReceived = delegate { }; - public event Action UserLeft = delegate { }; - public event Action UserUpdated = delegate { }; - public event Action, IMessage> MessageUpdated = delegate { }; - public event Action> MessageDeleted = delegate { }; - public event Action UserBanned = delegate { }; - public event Action UserUnbanned = delegate { }; - public event Action UserPresenceUpdated = delegate { }; - public event Action UserVoiceStateUpdated = delegate { }; - public event Action ChannelCreated = delegate { }; - public event Action ChannelDestroyed = delegate { }; - public event Action ChannelUpdated = delegate { }; + public event Action UserJoined = delegate { }; + public event Action MessageReceived = delegate { }; + public event Action UserLeft = delegate { }; + public event Action UserUpdated = delegate { }; + public event Action, SocketMessage> MessageUpdated = delegate { }; + public event Action> MessageDeleted = delegate { }; + public event Action UserBanned = delegate { }; + public event Action UserUnbanned = delegate { }; + public event Action, SocketUser, SocketPresence, SocketPresence> UserPresenceUpdated = delegate { }; + public event Action UserVoiceStateUpdated = delegate { }; + public event Action ChannelCreated = delegate { }; + public event Action ChannelDestroyed = delegate { }; + public event Action ChannelUpdated = delegate { }; public event Action Disconnected = delegate { }; private uint _connectedCount = 0; @@ -58,7 +58,7 @@ namespace NadekoBot client.MessageDeleted += (arg1, arg2) => { MessageDeleted(arg1, arg2); return Task.CompletedTask; }; client.UserBanned += (arg1, arg2) => { UserBanned(arg1, arg2); return Task.CompletedTask; }; client.UserUnbanned += (arg1, arg2) => { UserUnbanned(arg1, arg2); return Task.CompletedTask; }; - client.UserPresenceUpdated += (arg1, arg2, arg3) => { UserPresenceUpdated(arg1, arg2, arg3); return Task.CompletedTask; }; + client.UserPresenceUpdated += (arg1, arg2, arg3, arg4) => { UserPresenceUpdated(arg1, arg2, arg3, arg4); return Task.CompletedTask; }; client.UserVoiceStateUpdated += (arg1, arg2, arg3) => { UserVoiceStateUpdated(arg1, arg2, arg3); return Task.CompletedTask; }; client.ChannelCreated += arg => { ChannelCreated(arg); return Task.CompletedTask; }; client.ChannelDestroyed += arg => { ChannelDestroyed(arg); return Task.CompletedTask; }; @@ -70,19 +70,16 @@ namespace NadekoBot Clients = clientList.AsReadOnly(); } - public ISelfUser GetCurrentUser() => - Clients[0].GetCurrentUser(); + public DiscordSocketClient MainClient => + Clients[0]; - public Task GetCurrentUserAsync() => - Clients[0].GetCurrentUserAsync(); + public SocketSelfUser CurrentUser() => + Clients[0].CurrentUser; - public Task GetAllCurrentUsersAsync() => - Task.WhenAll(Clients.Select(c => c.GetCurrentUserAsync())); + public IReadOnlyCollection GetGuilds() => + Clients.SelectMany(c => c.Guilds).ToList(); - public IReadOnlyCollection GetGuilds() => - Clients.SelectMany(c => c.GetGuilds()).ToArray(); - - public IGuild GetGuild(ulong id) => + public SocketGuild GetGuild(ulong id) => Clients.Select(c => c.GetGuild(id)).FirstOrDefault(g => g != null); public Task GetDMChannelAsync(ulong channelId) => @@ -122,20 +119,12 @@ namespace NadekoBot var sw = Stopwatch.StartNew(); await c.DownloadAllUsersAsync().ConfigureAwait(false); sw.Stop(); - _log.Info($"Shard #{c.ShardId} downloaded {c.GetGuilds().Sum(g => g.GetUsers().Count)} users after {sw.Elapsed.TotalSeconds:F2}s ({++_downloadedCount}/{Clients.Count})."); + _log.Info($"Shard #{c.ShardId} downloaded {c.Guilds.Sum(g => g.Users.Count)} users after {sw.Elapsed.TotalSeconds:F2}s ({++_downloadedCount}/{Clients.Count})."); })); - public async Task SetGame(string game) - { - await Task.WhenAll((await GetAllCurrentUsersAsync()) - .Select(u => u.ModifyStatusAsync(ms => ms.Game = new Discord.Game(game)))); - } + public Task SetGame(string game) => Task.WhenAll(Clients.Select(ms => ms.SetGame(game))); - public async Task SetStream(string name, string url) - { - await Task.WhenAll((await GetAllCurrentUsersAsync()) - .Select(u => u.ModifyStatusAsync(ms => ms.Game = new Discord.Game(name, url, StreamType.Twitch)))); - } + public Task SetStream(string name, string url) => Task.WhenAll(Clients.Select(ms => ms.SetGame(name, url, StreamType.NotStreaming))); } } \ No newline at end of file diff --git a/src/NadekoBot/TypeReaders/BotCommandTypeReader.cs b/src/NadekoBot/TypeReaders/BotCommandTypeReader.cs index 91763e8a..9b4e06c2 100644 --- a/src/NadekoBot/TypeReaders/BotCommandTypeReader.cs +++ b/src/NadekoBot/TypeReaders/BotCommandTypeReader.cs @@ -1,18 +1,16 @@ using Discord.Commands; using System.Linq; using System.Threading.Tasks; -using Discord; namespace NadekoBot.TypeReaders { public class CommandTypeReader : TypeReader { - public override Task Read(IUserMessage context, string input) + public override Task Read(ICommandContext context, string input) { input = input.ToUpperInvariant(); var cmd = NadekoBot.CommandService.Commands.FirstOrDefault(c => - c.Aliases.Select(a => a.ToUpperInvariant()).Contains(input) || - c.Text.ToUpperInvariant() == input); + c.Aliases.Select(a => a.ToUpperInvariant()).Contains(input)); if (cmd == null) return Task.FromResult(TypeReaderResult.FromError(CommandError.ParseFailed, "No such command found.")); diff --git a/src/NadekoBot/TypeReaders/GuildTypeReader.cs b/src/NadekoBot/TypeReaders/GuildTypeReader.cs index ab9a5259..ac017da3 100644 --- a/src/NadekoBot/TypeReaders/GuildTypeReader.cs +++ b/src/NadekoBot/TypeReaders/GuildTypeReader.cs @@ -1,13 +1,12 @@ using Discord.Commands; using System.Linq; using System.Threading.Tasks; -using Discord; namespace NadekoBot.TypeReaders { public class GuildTypeReader : TypeReader { - public override Task Read(IUserMessage context, string input) + public override Task Read(ICommandContext context, string input) { input = input.Trim().ToLowerInvariant(); var guilds = NadekoBot.Client.GetGuilds(); diff --git a/src/NadekoBot/TypeReaders/ModuleTypeReader.cs b/src/NadekoBot/TypeReaders/ModuleTypeReader.cs index 366429ec..c1696d0f 100644 --- a/src/NadekoBot/TypeReaders/ModuleTypeReader.cs +++ b/src/NadekoBot/TypeReaders/ModuleTypeReader.cs @@ -1,16 +1,16 @@ using Discord.Commands; +using NadekoBot.Extensions; using System.Linq; using System.Threading.Tasks; -using Discord; namespace NadekoBot.TypeReaders { public class ModuleTypeReader : TypeReader { - public override Task Read(IUserMessage context, string input) + public override Task Read(ICommandContext context, string input) { input = input.ToUpperInvariant(); - var module = NadekoBot.CommandService.Modules.FirstOrDefault(m => m.Name.ToUpperInvariant() == input); + var module = NadekoBot.CommandService.Modules.GroupBy(m => m.GetTopLevelModule()).FirstOrDefault(m => m.Key.Name.ToUpperInvariant() == input); if (module == null) return Task.FromResult(TypeReaderResult.FromError(CommandError.ParseFailed, "No such module found.")); diff --git a/src/NadekoBot/TypeReaders/PermissionActionTypeReader.cs b/src/NadekoBot/TypeReaders/PermissionActionTypeReader.cs index 209f69b1..aa3510a6 100644 --- a/src/NadekoBot/TypeReaders/PermissionActionTypeReader.cs +++ b/src/NadekoBot/TypeReaders/PermissionActionTypeReader.cs @@ -1,6 +1,5 @@ using Discord.Commands; using System.Threading.Tasks; -using Discord; using NadekoBot.Modules.Permissions; namespace NadekoBot.TypeReaders @@ -10,7 +9,7 @@ namespace NadekoBot.TypeReaders /// public class PermissionActionTypeReader : TypeReader { - public override Task Read(IUserMessage context, string input) + public override Task Read(ICommandContext context, string input) { input = input.ToUpperInvariant(); switch (input) diff --git a/src/NadekoBot/_Extensions/Extensions.cs b/src/NadekoBot/_Extensions/Extensions.cs index 439f8c1a..f9a8157b 100644 --- a/src/NadekoBot/_Extensions/Extensions.cs +++ b/src/NadekoBot/_Extensions/Extensions.cs @@ -1,6 +1,5 @@ using Discord; -using Discord.API; -using Discord.WebSocket; +using Discord.Commands; using ImageSharp; using Newtonsoft.Json; using System; @@ -10,7 +9,6 @@ using System.IO; using System.Linq; using System.Net.Http; using System.Security.Cryptography; -using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; @@ -25,8 +23,7 @@ namespace NadekoBot.Extensions http.DefaultRequestHeaders.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"); } - public static EmbedBuilder WithImageUrl(this EmbedBuilder eb, string url) => - eb.WithImage(eib => eib.WithUrl(url)); + public static DateTime ToUnixTimestamp(this double number) => new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(number); public static EmbedBuilder WithOkColor(this EmbedBuilder eb) => eb.WithColor(NadekoBot.OkColor); @@ -45,6 +42,16 @@ namespace NadekoBot.Extensions return msg; } + public static string GetPrefix(this ModuleInfo module) => NadekoBot.ModulePrefixes[module.GetTopLevelModule().Name]; + + public static ModuleInfo GetTopLevelModule(this ModuleInfo module) { + while (module.Parent != null) + { + module = module.Parent; + } + return module; + } + public static async Task SendMessageToOwnerAsync(this IGuild guild, string message) { var ownerPrivate = await (await guild.GetOwnerAsync().ConfigureAwait(false)).CreateDMChannelAsync() @@ -53,6 +60,12 @@ namespace NadekoBot.Extensions return await ownerPrivate.SendMessageAsync(message).ConfigureAwait(false); } + //public static async Task> MentionedUsers(this IUserMessage msg) => + + + public static IEnumerable GetRoles(this IGuildUser user) => + user.RoleIds.Select(r => user.Guild.GetRole(r)).Where(r => r != null); + public static IEnumerable ForEach(this IEnumerable elems, Action exec) { foreach (var elem in elems) @@ -85,69 +98,51 @@ namespace NadekoBot.Extensions public static double UnixTimestamp(this DateTime dt) => dt.ToUniversalTime().Subtract(new DateTime(1970, 1, 1)).TotalSeconds; - public static DateTime ToUnixTimestamp(this double number) => new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(number); - - public static async Task SendMessageAsync(this IGuildUser user, string message, bool isTTS = false) => + public static async Task SendMessageAsync(this IUser user, string message, bool isTTS = false) => await (await user.CreateDMChannelAsync().ConfigureAwait(false)).SendMessageAsync(message, isTTS).ConfigureAwait(false); - public static async Task SendConfirmAsync(this IGuildUser user, string text) - => await (await user.CreateDMChannelAsync()).SendMessageAsync("", embed: new Embed() { Description = text, Color = NadekoBot.OkColor }); + public static async Task SendConfirmAsync(this IUser user, string text) + => await (await user.CreateDMChannelAsync()).SendMessageAsync("", embed: new EmbedBuilder().WithColor(NadekoBot.OkColor).WithDescription(text)); - public static async Task SendConfirmAsync(this IGuildUser user, string title, string text, string url = null) - => await(await user.CreateDMChannelAsync()).SendMessageAsync("", embed: new Embed() { Description = text, Title = title, Url = url, Color = NadekoBot.OkColor }); + public static async Task SendConfirmAsync(this IUser user, string title, string text, string url = null) + => await(await user.CreateDMChannelAsync()).SendMessageAsync("", embed: new EmbedBuilder().WithColor(NadekoBot.OkColor).WithDescription(text) + .WithTitle(title).WithUrl(url)); - public static async Task SendErrorAsync(this IGuildUser user, string title, string error, string url = null) - => await (await user.CreateDMChannelAsync()).SendMessageAsync("", embed: new Embed() { Description = error, Title = title, Url = url, Color = NadekoBot.ErrorColor }); + public static async Task SendErrorAsync(this IUser user, string title, string error, string url = null) + => await (await user.CreateDMChannelAsync()).SendMessageAsync("", embed: new EmbedBuilder().WithColor(NadekoBot.OkColor).WithDescription(error) + .WithTitle(title).WithUrl(url)); - public static async Task SendErrorAsync(this IGuildUser user, string error) - => await (await user.CreateDMChannelAsync()).SendMessageAsync("", embed: new Embed() { Description = error, Color = NadekoBot.ErrorColor }); + public static async Task SendErrorAsync(this IUser user, string error) + => await (await user.CreateDMChannelAsync()).SendMessageAsync("", embed: new EmbedBuilder().WithColor(NadekoBot.OkColor).WithDescription(error)); - public static async Task SendFileAsync(this IGuildUser user, string filePath, string caption = null, bool isTTS = false) => - await (await user.CreateDMChannelAsync().ConfigureAwait(false)).SendFileAsync(filePath, caption, isTTS).ConfigureAwait(false); + public static async Task SendFileAsync(this IUser user, string filePath, string caption = null, string text = null, bool isTTS = false) => + await (await user.CreateDMChannelAsync().ConfigureAwait(false)).SendFileAsync(File.Open(filePath, FileMode.Open), caption ?? "x", text, isTTS).ConfigureAwait(false); - public static async Task SendFileAsync(this IGuildUser user, Stream fileStream, string fileName, string caption = null, bool isTTS = false) => + public static async Task SendFileAsync(this IUser user, Stream fileStream, string fileName, string caption = null, bool isTTS = false) => await (await user.CreateDMChannelAsync().ConfigureAwait(false)).SendFileAsync(fileStream, fileName, caption, isTTS).ConfigureAwait(false); public static bool IsAuthor(this IUserMessage msg) => - NadekoBot.Client.GetCurrentUser().Id == msg.Author.Id; + NadekoBot.Client.CurrentUser().Id == msg.Author.Id; public static IEnumerable Members(this IRole role) => - NadekoBot.Client.GetGuild(role.GuildId)?.GetUsers().Where(u => u.Roles.Contains(role)) ?? Enumerable.Empty(); + role.Guild.GetUsersAsync().GetAwaiter().GetResult().Where(u => u.RoleIds.Contains(role.Id)) ?? Enumerable.Empty(); - public static Task EmbedAsync(this IMessageChannel ch, Discord.API.Embed embed, string msg = "") + public static Task EmbedAsync(this IMessageChannel ch, EmbedBuilder embed, string msg = "") => ch.SendMessageAsync(msg, embed: embed); public static Task SendErrorAsync(this IMessageChannel ch, string title, string error, string url = null, string footer = null) - => ch.SendMessageAsync("", embed: new Embed() - { - Description = error, - Title = title, - Url = url, - Color = NadekoBot.ErrorColor, - Footer = new Discord.API.EmbedFooter() - { - Text = footer - } - }); + => ch.SendMessageAsync("", embed: new EmbedBuilder().WithColor(NadekoBot.ErrorColor).WithDescription(error) + .WithTitle(title).WithUrl(url).WithFooter(efb => efb.WithText(footer))); public static Task SendErrorAsync(this IMessageChannel ch, string error) - => ch.SendMessageAsync("", embed: new Embed() { Description = error, Color = NadekoBot.ErrorColor }); + => ch.SendMessageAsync("", embed: new EmbedBuilder().WithColor(NadekoBot.OkColor).WithDescription(error)); public static Task SendConfirmAsync(this IMessageChannel ch, string title, string text, string url = null, string footer = null) - => ch.SendMessageAsync("", embed: new Embed() - { - Description = text, - Title = title, - Url = url, - Color = NadekoBot.OkColor, - Footer = new Discord.API.EmbedFooter() - { - Text = footer - } - }); + => ch.SendMessageAsync("", embed: new EmbedBuilder().WithColor(NadekoBot.OkColor).WithDescription(text) + .WithTitle(title).WithUrl(url).WithFooter(efb => efb.WithText(footer))); public static Task SendConfirmAsync(this IMessageChannel ch, string text) - => ch.SendMessageAsync("", embed: new Embed() { Description = text, Color = NadekoBot.OkColor }); + => ch.SendMessageAsync("", embed: new EmbedBuilder().WithColor(NadekoBot.OkColor).WithDescription(text)); public static Task SendTableAsync(this IMessageChannel ch, string seed, IEnumerable items, Func howToPrint, int columns = 3) { @@ -158,10 +153,8 @@ namespace NadekoBot.Extensions ```"); } - public static Task SendTableAsync(this IMessageChannel ch, IEnumerable items, Func howToPrint, int columns = 3) - { - return ch.SendTableAsync("", items, howToPrint, columns); - } + public static Task SendTableAsync(this IMessageChannel ch, IEnumerable items, Func howToPrint, int columns = 3) => + ch.SendTableAsync("", items, howToPrint, columns); /// /// returns an IEnumerable with randomized element order @@ -316,11 +309,11 @@ namespace NadekoBot.Extensions public static string Unmention(this string str) => str.Replace("@", "ම"); - public static Image Merge(this IEnumerable images) + public static ImageSharp.Image Merge(this IEnumerable images) { var imgList = images.ToList(); - var canvas = new Image(imgList.Sum(img => img.Width), imgList.Max(img => img.Height)); + var canvas = new ImageSharp.Image(imgList.Sum(img => img.Width), imgList.Max(img => img.Height)); var canvasPixels = canvas.Lock(); int offsetX = 0; @@ -339,7 +332,7 @@ namespace NadekoBot.Extensions return canvas; } - public static Stream ToStream(this Image img) + public static Stream ToStream(this ImageSharp.Image img) { var imageStream = new MemoryStream(); img.SaveAsPng(imageStream); diff --git a/src/NadekoBot/project.json b/src/NadekoBot/project.json index 7a4e12f1..17dc48f1 100644 --- a/src/NadekoBot/project.json +++ b/src/NadekoBot/project.json @@ -17,15 +17,9 @@ "define": [] }, "dependencies": { + "AngleSharp": "0.9.9", "VideoLibrary": "1.3.4", "CoreCLR-NCalc": "2.1.2", - "Discord.Net.Commands": { - "target": "project" - }, - "Discord.Net": { - "target": "project" - }, - "AngleSharp": "0.9.9", "Google.Apis.Urlshortener.v1": "1.19.0.138", "Google.Apis.YouTube.v3": "1.20.0.701", "Google.Apis.Customsearch.v1": "1.20.0.466", @@ -46,7 +40,15 @@ "Newtonsoft.Json": "9.0.2-beta1", "NLog": "5.0.0-beta03", "System.Diagnostics.Contracts": "4.3.0", - "System.Xml.XPath": "4.3.0" + "System.Xml.XPath": "4.3.0", + "Discord.Net.Commands": { + "target": "project", + "version": "1.0.0-*" + }, + "Discord.Net.WebSocket": { + "target": "project", + "version": "1.0.0-*" + } }, "tools": { "Microsoft.EntityFrameworkCore.Tools.DotNet": "1.1.0-preview4-final",