Fixed preconditions and some other stuff
This commit is contained in:
		 Submodule Discord.Net updated: ae614b68b3...cfc827404a
									
								
							@@ -12,7 +12,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
 | 
				
			|||||||
EndProject
 | 
					EndProject
 | 
				
			||||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "NadekoBot", "src\NadekoBot\NadekoBot.xproj", "{45EC1473-C678-4857-A544-07DFE0D0B478}"
 | 
					Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "NadekoBot", "src\NadekoBot\NadekoBot.xproj", "{45EC1473-C678-4857-A544-07DFE0D0B478}"
 | 
				
			||||||
EndProject
 | 
					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
 | 
					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}"
 | 
					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
 | 
					EndProject
 | 
				
			||||||
@@ -20,8 +20,6 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Discord.Net.Core", "discord
 | 
				
			|||||||
EndProject
 | 
					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}"
 | 
					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
 | 
					EndProject
 | 
				
			||||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Discord.Net.Rpc", "discord.net\src\Discord.Net.Rpc\Discord.Net.Rpc.xproj", "{0E741C78-869B-4E05-A300-0C5B32F07734}"
 | 
					 | 
				
			||||||
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}"
 | 
					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
 | 
					EndProject
 | 
				
			||||||
Global
 | 
					Global
 | 
				
			||||||
@@ -37,16 +35,16 @@ Global
 | 
				
			|||||||
		{45EC1473-C678-4857-A544-07DFE0D0B478}.GlobalNadeko|Any CPU.Build.0 = 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.ActiveCfg = Release|Any CPU
 | 
				
			||||||
		{45EC1473-C678-4857-A544-07DFE0D0B478}.Release|Any CPU.Build.0 = 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
 | 
							{834C70DF-1230-4AAA-9C13-48AB232E8D76}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 | 
				
			||||||
		{91E9E7BD-75C9-4E98-84AA-2C271922E5C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
 | 
							{834C70DF-1230-4AAA-9C13-48AB232E8D76}.Debug|Any CPU.Build.0 = Debug|Any CPU
 | 
				
			||||||
		{91E9E7BD-75C9-4E98-84AA-2C271922E5C2}.GlobalNadeko|Any CPU.ActiveCfg = Release|Any CPU
 | 
							{834C70DF-1230-4AAA-9C13-48AB232E8D76}.GlobalNadeko|Any CPU.ActiveCfg = Debug|Any CPU
 | 
				
			||||||
		{91E9E7BD-75C9-4E98-84AA-2C271922E5C2}.GlobalNadeko|Any CPU.Build.0 = Release|Any CPU
 | 
							{834C70DF-1230-4AAA-9C13-48AB232E8D76}.GlobalNadeko|Any CPU.Build.0 = Debug|Any CPU
 | 
				
			||||||
		{91E9E7BD-75C9-4E98-84AA-2C271922E5C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
 | 
							{834C70DF-1230-4AAA-9C13-48AB232E8D76}.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}.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.ActiveCfg = Debug|Any CPU
 | 
				
			||||||
		{078DD7E6-943D-4D09-AFC2-D2BA58B76C9C}.Debug|Any CPU.Build.0 = 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 = Release|Any CPU
 | 
							{078DD7E6-943D-4D09-AFC2-D2BA58B76C9C}.GlobalNadeko|Any CPU.ActiveCfg = Debug|Any CPU
 | 
				
			||||||
		{078DD7E6-943D-4D09-AFC2-D2BA58B76C9C}.GlobalNadeko|Any CPU.Build.0 = Release|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.ActiveCfg = Release|Any CPU
 | 
				
			||||||
		{078DD7E6-943D-4D09-AFC2-D2BA58B76C9C}.Release|Any CPU.Build.0 = 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.ActiveCfg = Debug|Any CPU
 | 
				
			||||||
@@ -61,12 +59,6 @@ Global
 | 
				
			|||||||
		{63F5B5C8-56FE-4B53-8003-B58CEB451EF9}.GlobalNadeko|Any CPU.Build.0 = 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.ActiveCfg = Release|Any CPU
 | 
				
			||||||
		{63F5B5C8-56FE-4B53-8003-B58CEB451EF9}.Release|Any CPU.Build.0 = Release|Any CPU
 | 
							{63F5B5C8-56FE-4B53-8003-B58CEB451EF9}.Release|Any CPU.Build.0 = Release|Any CPU
 | 
				
			||||||
		{0E741C78-869B-4E05-A300-0C5B32F07734}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 | 
					 | 
				
			||||||
		{0E741C78-869B-4E05-A300-0C5B32F07734}.Debug|Any CPU.Build.0 = Debug|Any CPU
 | 
					 | 
				
			||||||
		{0E741C78-869B-4E05-A300-0C5B32F07734}.GlobalNadeko|Any CPU.ActiveCfg = Debug|Any CPU
 | 
					 | 
				
			||||||
		{0E741C78-869B-4E05-A300-0C5B32F07734}.GlobalNadeko|Any CPU.Build.0 = Debug|Any CPU
 | 
					 | 
				
			||||||
		{0E741C78-869B-4E05-A300-0C5B32F07734}.Release|Any CPU.ActiveCfg = Release|Any CPU
 | 
					 | 
				
			||||||
		{0E741C78-869B-4E05-A300-0C5B32F07734}.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.ActiveCfg = Debug|Any CPU
 | 
				
			||||||
		{E9800F7A-3354-41B1-BDBB-2D59F8124EC9}.Debug|Any CPU.Build.0 = 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.ActiveCfg = Debug|Any CPU
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,7 +5,7 @@ namespace NadekoBot.Attributes
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    public class OwnerOnlyAttribute : PreconditionAttribute
 | 
					    public class OwnerOnlyAttribute : PreconditionAttribute
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        public override Task<PreconditionResult> CheckPermissions(CommandContext context, CommandInfo executingCommand,IDependencyMap depMap) =>
 | 
					        public override Task<PreconditionResult> CheckPermissions(ICommandContext context, CommandInfo executingCommand,IDependencyMap depMap) =>
 | 
				
			||||||
            Task.FromResult((NadekoBot.Credentials.IsOwner(context.User) ? PreconditionResult.FromSuccess() : PreconditionResult.FromError("Not owner")));
 | 
					            Task.FromResult((NadekoBot.Credentials.IsOwner(context.User) ? PreconditionResult.FromSuccess() : PreconditionResult.FromError("Not owner")));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -63,6 +63,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
        [RequireUserPermission(GuildPermission.Administrator)]
 | 
					        [RequireUserPermission(GuildPermission.Administrator)]
 | 
				
			||||||
        public async Task ResetPermissions()
 | 
					        public async Task ResetPermissions()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            var channel = (ITextChannel)Context.Channel;
 | 
				
			||||||
            using (var uow = DbHandler.UnitOfWork())
 | 
					            using (var uow = DbHandler.UnitOfWork())
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var config = uow.GuildConfigs.PermissionsFor(Context.Guild.Id);
 | 
					                var config = uow.GuildConfigs.PermissionsFor(Context.Guild.Id);
 | 
				
			||||||
@@ -78,7 +79,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
                await uow.CompleteAsync();
 | 
					                await uow.CompleteAsync();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            await Context.Channel.SendConfirmAsync($"{Context.Message.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]
 | 
					        [NadekoCommand, Usage, Description, Aliases]
 | 
				
			||||||
@@ -619,9 +620,11 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
                cnt -= 100;
 | 
					                cnt -= 100;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            var title = $"Chatlog-{Context.Guild.Name}/#{Context.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 (Context.User as IGuildUser).SendFileAsync(
 | 
					            await (Context.User as IGuildUser).SendFileAsync(
 | 
				
			||||||
                await JsonConvert.SerializeObject(grouping, Formatting.Indented).ToStream().ConfigureAwait(false),
 | 
					                await JsonConvert.SerializeObject(grouping, Formatting.Indented).ToStream().ConfigureAwait(false),
 | 
				
			||||||
                title, title).ConfigureAwait(false);
 | 
					title, title).ConfigureAwait(false);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -64,12 +64,12 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        conf.AutoAssignRoleId = 0;
 | 
					                        conf.AutoAssignRoleId = 0;
 | 
				
			||||||
                        ulong throwaway;
 | 
					                        ulong throwaway;
 | 
				
			||||||
                        AutoAssignedRoles.TryRemove(channel.Guild.Id, out throwaway);
 | 
					                        AutoAssignedRoles.TryRemove(Context.Guild.Id, out throwaway);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    else
 | 
					                    else
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        conf.AutoAssignRoleId = role.Id;
 | 
					                        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);
 | 
					                    await uow.CompleteAsync().ConfigureAwait(false);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -715,7 +715,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
					            [NadekoCommand, Usage, Description, Aliases]
 | 
				
			||||||
            [RequireContext(ContextType.Guild)]
 | 
					            [RequireContext(ContextType.Guild)]
 | 
				
			||||||
            [RequirePermission(GuildPermission.Administrator)]
 | 
					            [RequireUserPermission(GuildPermission.Administrator)]
 | 
				
			||||||
            [OwnerOnly]
 | 
					            [OwnerOnly]
 | 
				
			||||||
            public async Task LogServer(IUserMessage msg, PermissionAction action)
 | 
					            public async Task LogServer(IUserMessage msg, PermissionAction action)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
@@ -750,7 +750,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
					            [NadekoCommand, Usage, Description, Aliases]
 | 
				
			||||||
            [RequireContext(ContextType.Guild)]
 | 
					            [RequireContext(ContextType.Guild)]
 | 
				
			||||||
            [RequirePermission(GuildPermission.Administrator)]
 | 
					            [RequireUserPermission(GuildPermission.Administrator)]
 | 
				
			||||||
            [OwnerOnly]
 | 
					            [OwnerOnly]
 | 
				
			||||||
            public async Task LogIgnore(IUserMessage imsg)
 | 
					            public async Task LogIgnore(IUserMessage imsg)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
@@ -779,7 +779,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
					            [NadekoCommand, Usage, Description, Aliases]
 | 
				
			||||||
            [RequireContext(ContextType.Guild)]
 | 
					            [RequireContext(ContextType.Guild)]
 | 
				
			||||||
            [RequirePermission(GuildPermission.Administrator)]
 | 
					            [RequireUserPermission(GuildPermission.Administrator)]
 | 
				
			||||||
            [OwnerOnly]
 | 
					            [OwnerOnly]
 | 
				
			||||||
            public async Task LogEvents(IUserMessage imsg)
 | 
					            public async Task LogEvents(IUserMessage imsg)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
@@ -788,7 +788,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
					            [NadekoCommand, Usage, Description, Aliases]
 | 
				
			||||||
            [RequireContext(ContextType.Guild)]
 | 
					            [RequireContext(ContextType.Guild)]
 | 
				
			||||||
            [RequirePermission(GuildPermission.Administrator)]
 | 
					            [RequireUserPermission(GuildPermission.Administrator)]
 | 
				
			||||||
            [OwnerOnly]
 | 
					            [OwnerOnly]
 | 
				
			||||||
            public async Task Log(IUserMessage imsg, LogType type)
 | 
					            public async Task Log(IUserMessage imsg, LogType type)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -36,7 +36,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
                _log.Debug($"Loaded in {sw.Elapsed.TotalSeconds:F2}s");
 | 
					                _log.Debug($"Loaded in {sw.Elapsed.TotalSeconds:F2}s");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            private static async void UserUpdatedEventHandler(SocketUser iuser, IVoiceState before, IVoiceState after)
 | 
					            private static async void UserUpdatedEventHandler(SocketUser iuser, SocketVoiceState before, SocketVoiceState after)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var user = (iuser as SocketGuildUser);
 | 
					                var user = (iuser as SocketGuildUser);
 | 
				
			||||||
                var guild = user?.Guild;
 | 
					                var guild = user?.Guild;
 | 
				
			||||||
@@ -46,7 +46,7 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                try
 | 
					                try
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    var botUserPerms = guild.GetCurrentUser().GuildPermissions;
 | 
					                    var botUserPerms = guild.CurrentUser.GuildPermissions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    if (before.VoiceChannel == after.VoiceChannel) return;
 | 
					                    if (before.VoiceChannel == after.VoiceChannel) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -72,38 +72,37 @@ namespace NadekoBot.Modules.Administration
 | 
				
			|||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        var beforeVch = before.VoiceChannel;
 | 
					                    var beforeVch = before.VoiceChannel;
 | 
				
			||||||
                        if (beforeVch != null)
 | 
					                    if (beforeVch != null)
 | 
				
			||||||
                        {
 | 
					 | 
				
			||||||
                            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,
 | 
					 | 
				
			||||||
                                                       sendMessages: PermValue.Deny)).ConfigureAwait(false);
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                        var afterVch = after.VoiceChannel;
 | 
					 | 
				
			||||||
                        if (afterVch != null && guild.AFKChannelId != afterVch.Id)
 | 
					 | 
				
			||||||
                        {
 | 
					 | 
				
			||||||
                            var textChannel = (await guild.GetTextChannelsAsync())
 | 
					 | 
				
			||||||
                                                        .Where(t => t.Name ==  GetChannelName(afterVch.Name).ToLowerInvariant())
 | 
					 | 
				
			||||||
                                                        .FirstOrDefault();
 | 
					 | 
				
			||||||
                            if (textChannel == null)
 | 
					 | 
				
			||||||
                            {
 | 
					 | 
				
			||||||
                                textChannel = (await guild.CreateTextChannelAsync(GetChannelName(afterVch.Name).ToLowerInvariant()).ConfigureAwait(false));
 | 
					 | 
				
			||||||
                                await textChannel.AddPermissionOverwriteAsync(guild.EveryoneRole,
 | 
					 | 
				
			||||||
                                    new OverwritePermissions(readMessages: PermValue.Deny,
 | 
					 | 
				
			||||||
                                                       sendMessages: PermValue.Deny)).ConfigureAwait(false);
 | 
					 | 
				
			||||||
                            }
 | 
					 | 
				
			||||||
                            await textChannel.AddPermissionOverwriteAsync(user,
 | 
					 | 
				
			||||||
                                new OverwritePermissions(readMessages: PermValue.Allow,
 | 
					 | 
				
			||||||
                                                        sendMessages: PermValue.Allow)).ConfigureAwait(false);
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    catch (Exception ex)
 | 
					 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        Console.WriteLine(ex);
 | 
					                        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,
 | 
				
			||||||
 | 
					                                                   sendMessages: PermValue.Deny)).ConfigureAwait(false);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                });
 | 
					                    var afterVch = after.VoiceChannel;
 | 
				
			||||||
 | 
					                    if (afterVch != null && guild.AFKChannelId != afterVch.Id)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        var textChannel = (await guild.GetTextChannelsAsync())
 | 
				
			||||||
 | 
					                                                    .Where(t => t.Name == GetChannelName(afterVch.Name).ToLowerInvariant())
 | 
				
			||||||
 | 
					                                                    .FirstOrDefault();
 | 
				
			||||||
 | 
					                        if (textChannel == null)
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            textChannel = (await guild.CreateTextChannelAsync(GetChannelName(afterVch.Name).ToLowerInvariant()).ConfigureAwait(false));
 | 
				
			||||||
 | 
					                            await textChannel.AddPermissionOverwriteAsync(guild.EveryoneRole,
 | 
				
			||||||
 | 
					                                new OverwritePermissions(readMessages: PermValue.Deny,
 | 
				
			||||||
 | 
					                                                   sendMessages: PermValue.Deny)).ConfigureAwait(false);
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        await textChannel.AddPermissionOverwriteAsync(user,
 | 
				
			||||||
 | 
					                            new OverwritePermissions(readMessages: PermValue.Allow,
 | 
				
			||||||
 | 
					                                                    sendMessages: PermValue.Allow)).ConfigureAwait(false);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                catch (Exception ex)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    Console.WriteLine(ex);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            private static string GetChannelName(string voiceName) =>
 | 
					            private static string GetChannelName(string voiceName) =>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,6 +9,7 @@ using Discord;
 | 
				
			|||||||
using NadekoBot.Extensions;
 | 
					using NadekoBot.Extensions;
 | 
				
			||||||
using NLog;
 | 
					using NLog;
 | 
				
			||||||
using System.Diagnostics;
 | 
					using System.Diagnostics;
 | 
				
			||||||
 | 
					using Discord.WebSocket;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace NadekoBot.Modules.CustomReactions
 | 
					namespace NadekoBot.Modules.CustomReactions
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,6 +10,7 @@ using System.IO;
 | 
				
			|||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
using System.Text.RegularExpressions;
 | 
					using System.Text.RegularExpressions;
 | 
				
			||||||
using System.Threading.Tasks;
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					using Image = ImageSharp.Image;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace NadekoBot.Modules.Gambling
 | 
					namespace NadekoBot.Modules.Gambling
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -162,7 +163,7 @@ namespace NadekoBot.Modules.Gambling
 | 
				
			|||||||
                    var embed = new EmbedBuilder().WithOkColor().WithDescription($"{umsg.Author.Mention} rolled {n1} fate {(n1 == 1 ? "die" : "dice")}.")
 | 
					                    var embed = new EmbedBuilder().WithOkColor().WithDescription($"{umsg.Author.Mention} rolled {n1} fate {(n1 == 1 ? "die" : "dice")}.")
 | 
				
			||||||
                        .AddField(efb => efb.WithName(Format.Bold("Result"))
 | 
					                        .AddField(efb => efb.WithName(Format.Bold("Result"))
 | 
				
			||||||
                            .WithValue(string.Join(" ", rolls.Select(c => Format.Code($"[{c}]")))));
 | 
					                            .WithValue(string.Join(" ", rolls.Select(c => Format.Code($"[{c}]")))));
 | 
				
			||||||
                    await channel.EmbedAsync(embed.Build()).ConfigureAwait(false);
 | 
					                    await channel.EmbedAsync(embed).ConfigureAwait(false);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else if ((match = dndRegex.Match(arg)).Length != 0)
 | 
					                else if ((match = dndRegex.Match(arg)).Length != 0)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
@@ -185,7 +186,7 @@ namespace NadekoBot.Modules.Gambling
 | 
				
			|||||||
                        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($"{umsg.Author.Mention} rolled {n1} {(n1 == 1 ? "die" : "dice")} `1 to {n2}` +`{add}` -`{sub}`")
 | 
				
			||||||
                        .AddField(efb => efb.WithName(Format.Bold("Result"))
 | 
					                        .AddField(efb => efb.WithName(Format.Bold("Result"))
 | 
				
			||||||
                            .WithValue(string.Join(" ", (ordered ? arr.OrderBy(x => x).AsEnumerable() : arr).Select(x => Format.Code(x.ToString())))));
 | 
					                            .WithValue(string.Join(" ", (ordered ? arr.OrderBy(x => x).AsEnumerable() : arr).Select(x => Format.Code(x.ToString())))));
 | 
				
			||||||
                        await channel.EmbedAsync(embed.Build()).ConfigureAwait(false);
 | 
					                        await channel.EmbedAsync(embed).ConfigureAwait(false);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,7 @@ using NadekoBot.Extensions;
 | 
				
			|||||||
using NadekoBot.Services;
 | 
					using NadekoBot.Services;
 | 
				
			||||||
using NLog;
 | 
					using NLog;
 | 
				
			||||||
using Services.CleverBotApi;
 | 
					using Services.CleverBotApi;
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
using System.Collections.Concurrent;
 | 
					using System.Collections.Concurrent;
 | 
				
			||||||
using System.Diagnostics;
 | 
					using System.Diagnostics;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
@@ -92,6 +93,8 @@ namespace NadekoBot.Modules.Games
 | 
				
			|||||||
            [RequireUserPermission(ChannelPermission.ManageMessages)]
 | 
					            [RequireUserPermission(ChannelPermission.ManageMessages)]
 | 
				
			||||||
            public async Task Cleverbot()
 | 
					            public async Task Cleverbot()
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
 | 
					                var channel = (ITextChannel)Context.Channel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                Lazy<ChatterBotSession> throwaway;
 | 
					                Lazy<ChatterBotSession> throwaway;
 | 
				
			||||||
                if (CleverbotGuilds.TryRemove(channel.Guild.Id, out throwaway))
 | 
					                if (CleverbotGuilds.TryRemove(channel.Guild.Id, out throwaway))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -128,57 +128,58 @@ namespace NadekoBot.Modules.Games
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private async void Vote(IMessage imsg)
 | 
					            private async void Vote(IMessage imsg)
 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            try
 | 
					 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                // has to be a user message
 | 
					                try
 | 
				
			||||||
                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
 | 
					                    // has to be a user message
 | 
				
			||||||
                    if (originalMessage.Channel.Id != imsg.Channel.Id)
 | 
					                    var msg = imsg as IUserMessage;
 | 
				
			||||||
                        return;
 | 
					                    if (msg == null || msg.Author.IsBot)
 | 
				
			||||||
                    ch = imsg.Channel;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                else
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    //if private, channel must be dm channel
 | 
					 | 
				
			||||||
                    if ((ch = msg.Channel as IDMChannel) == null)
 | 
					 | 
				
			||||||
                        return;
 | 
					                        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    // user must be a member of the guild this poll is in
 | 
					                    // has to be an integer
 | 
				
			||||||
                    var guildUsers = await guild.GetUsersAsync().ConfigureAwait(false);
 | 
					                    int vote;
 | 
				
			||||||
                    if (!guildUsers.Any(u => u.Id == imsg.Author.Id))
 | 
					                    if (!int.TryParse(imsg.Content, out vote))
 | 
				
			||||||
 | 
					                        return;
 | 
				
			||||||
 | 
					                    if (vote < 1 || vote > answers.Length)
 | 
				
			||||||
                        return;
 | 
					                        return;
 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                //user can vote only once
 | 
					                    IMessageChannel ch;
 | 
				
			||||||
                if (participants.TryAdd(msg.Author.Id, vote))
 | 
					                    if (isPublic)
 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    if (!isPublic)
 | 
					 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        await ch.SendConfirmAsync($"Thanks for voting **{msg.Author.Username}**.").ConfigureAwait(false);
 | 
					                        //if public, channel must be the same the poll started in
 | 
				
			||||||
 | 
					                        if (originalMessage.Channel.Id != imsg.Channel.Id)
 | 
				
			||||||
 | 
					                            return;
 | 
				
			||||||
 | 
					                        ch = imsg.Channel;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    else
 | 
					                    else
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        var toDelete = await ch.SendConfirmAsync($"{msg.Author.Mention} cast their vote.").ConfigureAwait(false);
 | 
					                        //if private, channel must be dm channel
 | 
				
			||||||
                        toDelete.DeleteAfter(5);
 | 
					                        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 { }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -37,7 +37,7 @@ namespace NadekoBot.Modules.Music
 | 
				
			|||||||
            Directory.CreateDirectory(MusicDataPath);
 | 
					            Directory.CreateDirectory(MusicDataPath);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private async Task Client_UserVoiceStateUpdated(SocketUser iusr, SocketVoiceState oldState, SocketVoiceState newState)
 | 
					        private async void Client_UserVoiceStateUpdated(SocketUser iusr, SocketVoiceState oldState, SocketVoiceState newState)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var usr = iusr as SocketGuildUser;
 | 
					            var usr = iusr as SocketGuildUser;
 | 
				
			||||||
            if (usr == null ||
 | 
					            if (usr == null ||
 | 
				
			||||||
@@ -47,16 +47,22 @@ namespace NadekoBot.Modules.Music
 | 
				
			|||||||
            MusicPlayer player;
 | 
					            MusicPlayer player;
 | 
				
			||||||
            if (!MusicPlayers.TryGetValue(usr.Guild.Id, out player))
 | 
					            if (!MusicPlayers.TryGetValue(usr.Guild.Id, out player))
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
 | 
					            try
 | 
				
			||||||
            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();
 | 
					                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();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            catch (Exception ex)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                _log.Warn(ex);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -98,8 +104,7 @@ namespace NadekoBot.Modules.Music
 | 
				
			|||||||
        [RequireContext(ContextType.Guild)]
 | 
					        [RequireContext(ContextType.Guild)]
 | 
				
			||||||
        public async Task Destroy()
 | 
					        public async Task Destroy()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var channel = (ITextChannel)umsg.Channel;
 | 
					            await Context.Channel.SendErrorAsync("This command is temporarily disabled.").ConfigureAwait(false);
 | 
				
			||||||
            await channel.SendErrorAsync("This command is temporarily disabled.").ConfigureAwait(false);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            /*MusicPlayer musicPlayer;
 | 
					            /*MusicPlayer musicPlayer;
 | 
				
			||||||
            if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) return Task.CompletedTask;
 | 
					            if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) return Task.CompletedTask;
 | 
				
			||||||
@@ -128,7 +133,7 @@ namespace NadekoBot.Modules.Music
 | 
				
			|||||||
            var channel = (ITextChannel)Context.Channel;
 | 
					            var channel = (ITextChannel)Context.Channel;
 | 
				
			||||||
            MusicPlayer musicPlayer;
 | 
					            MusicPlayer musicPlayer;
 | 
				
			||||||
            if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) return;
 | 
					            if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) return;
 | 
				
			||||||
            if (((IGuildUser)umsg.Author).VoiceChannel != musicPlayer.PlaybackVoiceChannel)
 | 
					            if (((IGuildUser)Context.User).VoiceChannel != musicPlayer.PlaybackVoiceChannel)
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
            var val = musicPlayer.FairPlay = !musicPlayer.FairPlay;
 | 
					            var val = musicPlayer.FairPlay = !musicPlayer.FairPlay;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -153,7 +158,7 @@ namespace NadekoBot.Modules.Music
 | 
				
			|||||||
            await QueueSong(((IGuildUser)Context.User), (ITextChannel)Context.Channel, ((IGuildUser)Context.User).VoiceChannel, query, musicType: MusicType.Soundcloud).ConfigureAwait(false);
 | 
					            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)
 | 
					            if ((await Context.Guild.GetCurrentUserAsync()).GetPermissions((IGuildChannel)Context.Channel).ManageMessages)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                umsg.DeleteAfter(10);
 | 
					                Context.Message.DeleteAfter(10);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -174,7 +179,7 @@ namespace NadekoBot.Modules.Music
 | 
				
			|||||||
            var currentSong = musicPlayer.CurrentSong;
 | 
					            var currentSong = musicPlayer.CurrentSong;
 | 
				
			||||||
            if (currentSong == null)
 | 
					            if (currentSong == null)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                await channel.SendErrorAsync("🎵 No active music player.").ConfigureAwait(false);
 | 
					                await Context.Channel.SendErrorAsync("🎵 No active music player.").ConfigureAwait(false);
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -195,7 +200,7 @@ namespace NadekoBot.Modules.Music
 | 
				
			|||||||
                    .Select(v => $"`{++number}.` {v.PrettyFullName}")))
 | 
					                    .Select(v => $"`{++number}.` {v.PrettyFullName}")))
 | 
				
			||||||
                .WithFooter(ef => ef.WithText($"{musicPlayer.PrettyVolume} | {musicPlayer.Playlist.Count} " +
 | 
					                .WithFooter(ef => ef.WithText($"{musicPlayer.PrettyVolume} | {musicPlayer.Playlist.Count} " +
 | 
				
			||||||
$"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {(int)total.TotalHours}h {total.Minutes}m {total.Seconds}s | " +
 | 
					$"{("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();
 | 
					                .WithOkColor();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (musicPlayer.RepeatSong)
 | 
					            if (musicPlayer.RepeatSong)
 | 
				
			||||||
@@ -210,7 +215,7 @@ $"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {(int)total.TotalHours}h {tota
 | 
				
			|||||||
            {
 | 
					            {
 | 
				
			||||||
                embed.WithTitle("🎵 Song queue is full!");
 | 
					                embed.WithTitle("🎵 Song queue is full!");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            await channel.EmbedAsync(embed.Build()).ConfigureAwait(false);
 | 
					            await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
					        [NadekoCommand, Usage, Description, Aliases]
 | 
				
			||||||
@@ -228,10 +233,10 @@ $"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {(int)total.TotalHours}h {tota
 | 
				
			|||||||
            var embed = new EmbedBuilder().WithOkColor()
 | 
					            var embed = new EmbedBuilder().WithOkColor()
 | 
				
			||||||
                            .WithAuthor(eab => eab.WithName("Now Playing").WithMusicIcon())
 | 
					                            .WithAuthor(eab => eab.WithName("Now Playing").WithMusicIcon())
 | 
				
			||||||
                            .WithDescription(currentSong.PrettyName)
 | 
					                            .WithDescription(currentSong.PrettyName)
 | 
				
			||||||
                            .WithThumbnail(tn => tn.Url = currentSong.Thumbnail)
 | 
					                            .WithThumbnailUrl(currentSong.Thumbnail)
 | 
				
			||||||
                            .WithFooter(ef => ef.WithText(musicPlayer.PrettyVolume + " | " + currentSong.PrettyFullTime + $" | {currentSong.PrettyProvider} | {currentSong.QueuerName}"));
 | 
					                            .WithFooter(ef => ef.WithText(musicPlayer.PrettyVolume + " | " + currentSong.PrettyFullTime + $" | {currentSong.PrettyProvider} | {currentSong.QueuerName}"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            await channel.EmbedAsync(embed).ConfigureAwait(false);
 | 
					            await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
					        [NadekoCommand, Usage, Description, Aliases]
 | 
				
			||||||
@@ -315,11 +320,11 @@ $"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {(int)total.TotalHours}h {tota
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
            var count = ids.Count();
 | 
					            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 cancelSource = new CancellationTokenSource();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var gusr = (IGuildUser)umsg.Author;
 | 
					            var gusr = (IGuildUser)Context.User;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            while (ids.Any() && !cancelSource.IsCancellationRequested)
 | 
					            while (ids.Any() && !cancelSource.IsCancellationRequested)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
@@ -329,7 +334,7 @@ $"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {(int)total.TotalHours}h {tota
 | 
				
			|||||||
                        return;
 | 
					                        return;
 | 
				
			||||||
                    try
 | 
					                    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 (SongNotFoundException) { }
 | 
				
			||||||
                    catch { try { cancelSource.Cancel(); } catch { } }
 | 
					                    catch { try { cancelSource.Cancel(); } catch { } }
 | 
				
			||||||
@@ -393,7 +398,7 @@ $"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {(int)total.TotalHours}h {tota
 | 
				
			|||||||
                var dir = new DirectoryInfo(arg);
 | 
					                var dir = new DirectoryInfo(arg);
 | 
				
			||||||
                var fileEnum = dir.GetFiles("*", SearchOption.AllDirectories)
 | 
					                var fileEnum = dir.GetFiles("*", SearchOption.AllDirectories)
 | 
				
			||||||
                                    .Where(x => !x.Attributes.HasFlag(FileAttributes.Hidden | FileAttributes.System));
 | 
					                                    .Where(x => !x.Attributes.HasFlag(FileAttributes.Hidden | FileAttributes.System));
 | 
				
			||||||
                var gusr = (IGuildUser)umsg.Author;
 | 
					                var gusr = (IGuildUser)Context.User;
 | 
				
			||||||
                foreach (var file in fileEnum)
 | 
					                foreach (var file in fileEnum)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    try
 | 
					                    try
 | 
				
			||||||
@@ -479,7 +484,7 @@ $"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {(int)total.TotalHours}h {tota
 | 
				
			|||||||
                .WithFooter(ef => ef.WithText($"{song.PrettyProvider} | {song.QueuerName}"))
 | 
					                .WithFooter(ef => ef.WithText($"{song.PrettyProvider} | {song.QueuerName}"))
 | 
				
			||||||
                .WithErrorColor();
 | 
					                .WithErrorColor();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            await channel.EmbedAsync(embed).ConfigureAwait(false);
 | 
					            await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
					        [NadekoCommand, Usage, Description, Aliases]
 | 
				
			||||||
@@ -528,15 +533,15 @@ $"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {(int)total.TotalHours}h {tota
 | 
				
			|||||||
            playlist.Insert(n2 - 1, s);
 | 
					            playlist.Insert(n2 - 1, s);
 | 
				
			||||||
            var nn1 = n2 < n1 ? n1 : n1 - 1;
 | 
					            var nn1 = n2 < n1 ? n1 : n1 - 1;
 | 
				
			||||||
            playlist.RemoveAt(nn1);
 | 
					            playlist.RemoveAt(nn1);
 | 
				
			||||||
        
 | 
					
 | 
				
			||||||
        var embed = new EmbedBuilder()
 | 
					            var embed = new EmbedBuilder()
 | 
				
			||||||
            .WithTitle($"{s.SongInfo.Title.TrimTo(70)}")
 | 
					                .WithTitle($"{s.SongInfo.Title.TrimTo(70)}")
 | 
				
			||||||
        .WithUrl($"{s.SongInfo.Query}")
 | 
					            .WithUrl($"{s.SongInfo.Query}")
 | 
				
			||||||
        .WithAuthor(eab => eab.WithName("Song Moved").WithIconUrl("https://cdn.discordapp.com/attachments/155726317222887425/258605269972549642/music1.png"))
 | 
					            .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("**From Position**").WithValue($"#{n1}").WithIsInline(true))
 | 
				
			||||||
        .AddField(fb => fb.WithName("**To Position**").WithValue($"#{n2}").WithIsInline(true))
 | 
					            .AddField(fb => fb.WithName("**To Position**").WithValue($"#{n2}").WithIsInline(true))
 | 
				
			||||||
        .WithColor(NadekoBot.OkColor);
 | 
					            .WithColor(NadekoBot.OkColor);
 | 
				
			||||||
            await channel.EmbedAsync(embed.Build()).ConfigureAwait(false);
 | 
					            await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //await channel.SendConfirmAsync($"🎵Moved {s.PrettyName} `from #{n1} to #{n2}`").ConfigureAwait(false);
 | 
					            //await channel.SendConfirmAsync($"🎵Moved {s.PrettyName} `from #{n1} to #{n2}`").ConfigureAwait(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -549,8 +554,8 @@ $"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {(int)total.TotalHours}h {tota
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            MusicPlayer musicPlayer;
 | 
					            MusicPlayer musicPlayer;
 | 
				
			||||||
            if (!MusicPlayers.TryGetValue(Context.Guild.Id, out musicPlayer))
 | 
					            if (!MusicPlayers.TryGetValue(Context.Guild.Id, out musicPlayer))
 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            musicPlayer.MaxQueueSize = size;
 | 
					            musicPlayer.MaxQueueSize = size;
 | 
				
			||||||
            await Context.Channel.SendConfirmAsync($"🎵 Max queue set to {(size == 0 ? ("unlimited") : size + " tracks")}.");
 | 
					            await Context.Channel.SendConfirmAsync($"🎵 Max queue set to {(size == 0 ? ("unlimited") : size + " tracks")}.");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -567,7 +572,7 @@ $"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {(int)total.TotalHours}h {tota
 | 
				
			|||||||
            if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer))
 | 
					            if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer))
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
            musicPlayer.MaxPlaytimeSeconds = seconds;
 | 
					            musicPlayer.MaxPlaytimeSeconds = seconds;
 | 
				
			||||||
            if(seconds == 0)
 | 
					            if (seconds == 0)
 | 
				
			||||||
                await channel.SendConfirmAsync($"🎵 Max playtime has no limit now.");
 | 
					                await channel.SendConfirmAsync($"🎵 Max playtime has no limit now.");
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
                await channel.SendConfirmAsync($"🎵 Max playtime set to {seconds} seconds.");
 | 
					                await channel.SendConfirmAsync($"🎵 Max playtime set to {seconds} seconds.");
 | 
				
			||||||
@@ -587,7 +592,7 @@ $"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {(int)total.TotalHours}h {tota
 | 
				
			|||||||
            var currentValue = musicPlayer.ToggleRepeatSong();
 | 
					            var currentValue = musicPlayer.ToggleRepeatSong();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (currentValue)
 | 
					            if (currentValue)
 | 
				
			||||||
                await channel.EmbedAsync(new EmbedBuilder()
 | 
					                await Context.Channel.EmbedAsync(new EmbedBuilder()
 | 
				
			||||||
                    .WithOkColor()
 | 
					                    .WithOkColor()
 | 
				
			||||||
                    .WithAuthor(eab => eab.WithMusicIcon().WithName("🔂 Repeating track"))
 | 
					                    .WithAuthor(eab => eab.WithMusicIcon().WithName("🔂 Repeating track"))
 | 
				
			||||||
                    .WithDescription(currentSong.PrettyName)
 | 
					                    .WithDescription(currentSong.PrettyName)
 | 
				
			||||||
@@ -809,29 +814,27 @@ $"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {(int)total.TotalHours}h {tota
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
                var mp = new MusicPlayer(voiceCh, vol);
 | 
					                var mp = new MusicPlayer(voiceCh, vol);
 | 
				
			||||||
                IUserMessage playingMessage = null;
 | 
					                IUserMessage playingMessage = null;
 | 
				
			||||||
        IUserMessage lastFinishedMessage = null;
 | 
					                IUserMessage lastFinishedMessage = null;
 | 
				
			||||||
                mp.OnCompleted += async (s, song) =>
 | 
					                mp.OnCompleted += async (s, song) =>
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    try
 | 
					                    try
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        if (finishedMessage != null)
 | 
					                        if (lastFinishedMessage != null)
 | 
				
			||||||
                            finishedMessage.DeleteAfter(0);
 | 
					                            lastFinishedMessage.DeleteAfter(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        finishedMessage = await textCh.EmbedAsync(new EmbedBuilder().WithOkColor()
 | 
					                        lastFinishedMessage = await textCh.EmbedAsync(new EmbedBuilder().WithOkColor()
 | 
				
			||||||
                                                  .WithAuthor(eab => eab.WithName("Finished Song").WithMusicIcon())
 | 
					                                                  .WithAuthor(eab => eab.WithName("Finished Song").WithMusicIcon())
 | 
				
			||||||
                                                  .WithDescription(song.PrettyName)
 | 
					                                                  .WithDescription(song.PrettyName)
 | 
				
			||||||
                                                  .WithFooter(ef => ef.WithText(song.PrettyInfo))
 | 
					                                                  .WithFooter(ef => ef.WithText(song.PrettyInfo)))
 | 
				
			||||||
                                                  .Build())
 | 
					                                                    .ConfigureAwait(false);
 | 
				
			||||||
                                                  .ConfigureAwait(false);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        if (mp.Autoplay && mp.Playlist.Count == 0 && song.SongInfo.Provider == "YouTube")
 | 
					                        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 { }
 | 
					                    catch { }
 | 
				
			||||||
                };
 | 
					                };
 | 
				
			||||||
                IUserMessage playingMessage = null;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                mp.OnStarted += async (player, song) =>
 | 
					                mp.OnStarted += async (player, song) =>
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
@@ -852,17 +855,17 @@ $"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {(int)total.TotalHours}h {tota
 | 
				
			|||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    catch { }
 | 
					                    catch { }
 | 
				
			||||||
                };
 | 
					                };
 | 
				
			||||||
        mp.OnPauseChanged += async (paused) =>
 | 
					                mp.OnPauseChanged += async (paused) =>
 | 
				
			||||||
                {
 | 
					                        {
 | 
				
			||||||
                    try
 | 
					                            try
 | 
				
			||||||
                    {
 | 
					                            {
 | 
				
			||||||
                        if (paused)
 | 
					                                if (paused)
 | 
				
			||||||
                            await textCh.SendConfirmAsync("🎵 Music playback **paused**.").ConfigureAwait(false);
 | 
					                                    await textCh.SendConfirmAsync("🎵 Music playback **paused**.").ConfigureAwait(false);
 | 
				
			||||||
                        else
 | 
					                                else
 | 
				
			||||||
                            await textCh.SendConfirmAsync("🎵 Music playback **resumed**.").ConfigureAwait(false);
 | 
					                                    await textCh.SendConfirmAsync("🎵 Music playback **resumed**.").ConfigureAwait(false);
 | 
				
			||||||
                    }
 | 
					                            }
 | 
				
			||||||
                    catch { }
 | 
					                            catch { }
 | 
				
			||||||
                };
 | 
					                        };
 | 
				
			||||||
                return mp;
 | 
					                return mp;
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
            Song resolvedSong;
 | 
					            Song resolvedSong;
 | 
				
			||||||
@@ -889,7 +892,7 @@ $"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {(int)total.TotalHours}h {tota
 | 
				
			|||||||
                    var queuedMessage = await textCh.EmbedAsync(new EmbedBuilder().WithOkColor()
 | 
					                    var queuedMessage = await textCh.EmbedAsync(new EmbedBuilder().WithOkColor()
 | 
				
			||||||
                                                            .WithAuthor(eab => eab.WithName("Queued Song #" + (musicPlayer.Playlist.Count + 1)).WithMusicIcon())
 | 
					                                                            .WithAuthor(eab => eab.WithName("Queued Song #" + (musicPlayer.Playlist.Count + 1)).WithMusicIcon())
 | 
				
			||||||
                                                            .WithDescription($"{resolvedSong.PrettyName}\nQueue ")
 | 
					                                                            .WithDescription($"{resolvedSong.PrettyName}\nQueue ")
 | 
				
			||||||
                                                            .WithThumbnail(tn => tn.Url = resolvedSong.Thumbnail)
 | 
					                                                            .WithThumbnailUrl(resolvedSong.Thumbnail)
 | 
				
			||||||
                                                            .WithFooter(ef => ef.WithText(resolvedSong.PrettyProvider)))
 | 
					                                                            .WithFooter(ef => ef.WithText(resolvedSong.PrettyProvider)))
 | 
				
			||||||
                                                            .ConfigureAwait(false);
 | 
					                                                            .ConfigureAwait(false);
 | 
				
			||||||
                    if (queuedMessage != null)
 | 
					                    if (queuedMessage != null)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,6 +4,7 @@ using NadekoBot.Attributes;
 | 
				
			|||||||
using NadekoBot.Extensions;
 | 
					using NadekoBot.Extensions;
 | 
				
			||||||
using NadekoBot.Modules.Searches.Models;
 | 
					using NadekoBot.Modules.Searches.Models;
 | 
				
			||||||
using Newtonsoft.Json;
 | 
					using Newtonsoft.Json;
 | 
				
			||||||
 | 
					using NLog;
 | 
				
			||||||
using System.Net.Http;
 | 
					using System.Net.Http;
 | 
				
			||||||
using System.Text.RegularExpressions;
 | 
					using System.Text.RegularExpressions;
 | 
				
			||||||
using System.Threading.Tasks;
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
@@ -27,7 +28,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
                var battletag = Regex.Replace(query, "#", "-", RegexOptions.IgnoreCase);
 | 
					                var battletag = Regex.Replace(query, "#", "-", RegexOptions.IgnoreCase);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                await channel.TriggerTypingAsync().ConfigureAwait(false);
 | 
					                await Context.Channel.TriggerTypingAsync().ConfigureAwait(false);
 | 
				
			||||||
                try
 | 
					                try
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    await Context.Channel.TriggerTypingAsync().ConfigureAwait(false);
 | 
					                    await Context.Channel.TriggerTypingAsync().ConfigureAwait(false);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -190,7 +190,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
                await Context.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().WithColor(NadekoBot.OkColor)
 | 
					            await Context.Channel.EmbedAsync(new EmbedBuilder().WithColor(NadekoBot.OkColor)
 | 
				
			||||||
                                                           .AddField(efb => efb.WithName("Original Url")
 | 
					                                                           .AddField(efb => efb.WithName("Original Url")
 | 
				
			||||||
                                                                               .WithValue($"<{arg}>"))
 | 
					                                                                               .WithValue($"<{arg}>"))
 | 
				
			||||||
                                                            .AddField(efb => efb.WithName("Short Url")
 | 
					                                                            .AddField(efb => efb.WithName("Short Url")
 | 
				
			||||||
@@ -244,7 +244,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
                .WithAuthor(eab => eab.WithName("Search For: " + terms.TrimTo(50))
 | 
					                .WithAuthor(eab => eab.WithName("Search For: " + terms.TrimTo(50))
 | 
				
			||||||
                    .WithUrl(fullQueryLink)
 | 
					                    .WithUrl(fullQueryLink)
 | 
				
			||||||
                    .WithIconUrl("http://i.imgur.com/G46fm8J.png"))
 | 
					                    .WithIconUrl("http://i.imgur.com/G46fm8J.png"))
 | 
				
			||||||
                .WithTitle(umsg.Author.Mention)
 | 
					                .WithTitle(Context.User.Mention)
 | 
				
			||||||
                .WithFooter(efb => efb.WithText(totalResults));
 | 
					                .WithFooter(efb => efb.WithText(totalResults));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var desc = await Task.WhenAll(results.Select(async res => 
 | 
					            var desc = await Task.WhenAll(results.Select(async res => 
 | 
				
			||||||
@@ -612,12 +612,11 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
        public async Task Avatar([Remainder] IUser usr = null)
 | 
					        public async Task Avatar([Remainder] IUser usr = null)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (usr == null)
 | 
					            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")
 | 
					                .WithTitle($"{usr}'s Avatar")
 | 
				
			||||||
                .WithImageUrl(usr.AvatarUrl)
 | 
					                .WithImageUrl(usr.AvatarUrl)).ConfigureAwait(false);
 | 
				
			||||||
                .Build()).ConfigureAwait(false);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
					        [NadekoCommand, Usage, Description, Aliases]
 | 
				
			||||||
@@ -745,8 +744,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
                await channel.EmbedAsync(new EmbedBuilder().WithOkColor()
 | 
					                await channel.EmbedAsync(new EmbedBuilder().WithOkColor()
 | 
				
			||||||
                    .WithDescription(umsg.Author.Mention + " " + tag)
 | 
					                    .WithDescription(umsg.Author.Mention + " " + tag)
 | 
				
			||||||
                    .WithImageUrl(url)
 | 
					                    .WithImageUrl(url)
 | 
				
			||||||
                    .WithFooter(efb => efb.WithText(type.ToString()))
 | 
					                    .WithFooter(efb => efb.WithText(type.ToString()))).ConfigureAwait(false);
 | 
				
			||||||
                    .Build()).ConfigureAwait(false);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public static async Task<string> InternalDapiSearch(string tag, DapiSearchType type)
 | 
					        public static async Task<string> InternalDapiSearch(string tag, DapiSearchType type)
 | 
				
			||||||
@@ -793,7 +791,7 @@ namespace NadekoBot.Modules.Searches
 | 
				
			|||||||
                return null;
 | 
					                return null;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        public static async Task<bool> ValidateQuery(ITextChannel ch, string query)
 | 
					        public static async Task<bool> ValidateQuery(IMessageChannel ch, string query)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (!string.IsNullOrEmpty(query.Trim())) return true;
 | 
					            if (!string.IsNullOrEmpty(query.Trim())) return true;
 | 
				
			||||||
            await ch.SendErrorAsync("Please specify search parameters.").ConfigureAwait(false);
 | 
					            await ch.SendErrorAsync("Please specify search parameters.").ConfigureAwait(false);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,7 +23,6 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
					        [NadekoCommand, Usage, Description, Aliases]
 | 
				
			||||||
        [RequireContext(ContextType.Guild)]
 | 
					        [RequireContext(ContextType.Guild)]
 | 
				
			||||||
        public async Task WhosPlaying([Remainder] string game = null)
 | 
					 | 
				
			||||||
        public async Task TogetherTube(IUserMessage imsg)
 | 
					        public async Task TogetherTube(IUserMessage imsg)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            Uri target;
 | 
					            Uri target;
 | 
				
			||||||
@@ -191,18 +190,16 @@ namespace NadekoBot.Modules.Utility
 | 
				
			|||||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
					        [NadekoCommand, Usage, Description, Aliases]
 | 
				
			||||||
        public async Task Stats()
 | 
					        public async Task Stats()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var channel = Context.Channel;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            var stats = NadekoBot.Stats;
 | 
					            var stats = NadekoBot.Stats;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            await channel.EmbedAsync(
 | 
					            await Context.Channel.EmbedAsync(
 | 
				
			||||||
                new EmbedBuilder().WithOkColor()
 | 
					                new EmbedBuilder().WithOkColor()
 | 
				
			||||||
                    .WithAuthor(eab => eab.WithName($"NadekoBot v{StatsService.BotVersion}")
 | 
					                    .WithAuthor(eab => eab.WithName($"NadekoBot v{StatsService.BotVersion}")
 | 
				
			||||||
                                          .WithUrl("http://nadekobot.readthedocs.io/en/latest/")
 | 
					                                          .WithUrl("http://nadekobot.readthedocs.io/en/latest/")
 | 
				
			||||||
                                          .WithIconUrl("https://cdn.discordapp.com/avatars/116275390695079945/b21045e778ef21c96d175400e779f0fb.jpg"))
 | 
					                                          .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("Author")).WithValue(stats.Author).WithIsInline(true))
 | 
				
			||||||
                    .AddField(efb => efb.WithName(Format.Bold("Library")).WithValue(stats.Library).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("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("Messages")).WithValue($"{stats.MessageCounter} ({stats.MessagesPerSecond:F2}/sec)").WithIsInline(true))
 | 
				
			||||||
                    .AddField(efb => efb.WithName(Format.Bold("Memory")).WithValue($"{stats.Heap} MB").WithIsInline(true))
 | 
					                    .AddField(efb => efb.WithName(Format.Bold("Memory")).WithValue($"{stats.Heap} MB").WithIsInline(true))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -58,9 +58,9 @@ namespace NadekoBot.Services
 | 
				
			|||||||
            _client.MessageReceived += MessageReceivedHandler;
 | 
					            _client.MessageReceived += MessageReceivedHandler;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private async Task MessageReceivedHandler(SocketMessage msg)
 | 
					        private async void MessageReceivedHandler(SocketMessage msg)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
           var usrMsg = msg as SocketUserMessage;
 | 
					            var usrMsg = msg as SocketUserMessage;
 | 
				
			||||||
            if (usrMsg == null)
 | 
					            if (usrMsg == null)
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -135,87 +135,75 @@ namespace NadekoBot.Services
 | 
				
			|||||||
            catch { }
 | 
					            catch { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            string messageContent = usrMsg.Content;
 | 
					            string messageContent = usrMsg.Content;
 | 
				
			||||||
            //foreach (var k in NadekoBot.ModulePrefixes.Values)
 | 
					 | 
				
			||||||
            //{
 | 
					 | 
				
			||||||
            //    if (usrMsg.Content.ToLowerInvariant().StartsWith(k))
 | 
					 | 
				
			||||||
            //    {
 | 
					 | 
				
			||||||
            //        messageContent = messageContent.Insert(k.Length, " ");
 | 
					 | 
				
			||||||
            //        break;
 | 
					 | 
				
			||||||
            //    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //}
 | 
					            var sw = new Stopwatch();
 | 
				
			||||||
 | 
					            sw.Start();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            try
 | 
				
			||||||
            var throwaway = Task.Run(async () =>
 | 
					 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var sw = new Stopwatch();
 | 
					                var exec = await ExecuteCommand(new CommandContext(_client.MainClient, usrMsg), messageContent, DependencyMap.Empty, MultiMatchHandling.Best);
 | 
				
			||||||
                sw.Start();
 | 
					                var command = exec.CommandInfo;
 | 
				
			||||||
 | 
					                var permCache = exec.PermissionCache;
 | 
				
			||||||
                try
 | 
					                var result = exec.Result;
 | 
				
			||||||
 | 
					                sw.Stop();
 | 
				
			||||||
 | 
					                var channel = (msg.Channel as ITextChannel);
 | 
				
			||||||
 | 
					                if (result.IsSuccess)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    var exec = await ExecuteCommand(new CommandContext(_client.MainClient, usrMsg), messageContent, DependencyMap.Empty, MultiMatchHandling.Best);
 | 
					                    await CommandExecuted(usrMsg, command);
 | 
				
			||||||
                    var command = exec.CommandInfo;
 | 
					                    _log.Info("Command Executed after {4}s\n\t" +
 | 
				
			||||||
                    var permCache = exec.PermissionCache;
 | 
					                                "User: {0}\n\t" +
 | 
				
			||||||
                    var result = exec.Result;
 | 
					                                "Server: {1}\n\t" +
 | 
				
			||||||
                    sw.Stop();
 | 
					                                "Channel: {2}\n\t" +
 | 
				
			||||||
                    var channel = (msg.Channel as ITextChannel);
 | 
					                                "Message: {3}",
 | 
				
			||||||
                    if (result.IsSuccess)
 | 
					                                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}
 | 
				
			||||||
 | 
					                                sw.Elapsed.TotalSeconds // {4}
 | 
				
			||||||
 | 
					                                );
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                else if (!result.IsSuccess && result.Error != CommandError.UnknownCommand)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    _log.Warn("Command Errored after {5}s\n\t" +
 | 
				
			||||||
 | 
					                                "User: {0}\n\t" +
 | 
				
			||||||
 | 
					                                "Server: {1}\n\t" +
 | 
				
			||||||
 | 
					                                "Channel: {2}\n\t" +
 | 
				
			||||||
 | 
					                                "Message: {3}\n\t" +
 | 
				
			||||||
 | 
					                                "Error: {4}",
 | 
				
			||||||
 | 
					                                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}
 | 
				
			||||||
 | 
					                                result.ErrorReason, // {4}
 | 
				
			||||||
 | 
					                                sw.Elapsed.TotalSeconds // {5}
 | 
				
			||||||
 | 
					                                );
 | 
				
			||||||
 | 
					                    if (guild != null && command != null && result.Error == CommandError.Exception)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        await CommandExecuted(usrMsg, command);
 | 
					                        if (permCache != null && permCache.Verbose)
 | 
				
			||||||
                        _log.Info("Command Executed after {4}s\n\t" +
 | 
					                            try { await msg.Channel.SendMessageAsync("⚠️ " + result.ErrorReason).ConfigureAwait(false); } catch { }
 | 
				
			||||||
                                    "User: {0}\n\t" +
 | 
					 | 
				
			||||||
                                    "Server: {1}\n\t" +
 | 
					 | 
				
			||||||
                                    "Channel: {2}\n\t" +
 | 
					 | 
				
			||||||
                                    "Message: {3}",
 | 
					 | 
				
			||||||
                                    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}
 | 
					 | 
				
			||||||
                                    sw.Elapsed.TotalSeconds // {4}
 | 
					 | 
				
			||||||
                                    );
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    else if (!result.IsSuccess && result.Error != CommandError.UnknownCommand)
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        _log.Warn("Command Errored after {5}s\n\t" +
 | 
					 | 
				
			||||||
                                    "User: {0}\n\t" +
 | 
					 | 
				
			||||||
                                    "Server: {1}\n\t" +
 | 
					 | 
				
			||||||
                                    "Channel: {2}\n\t" +
 | 
					 | 
				
			||||||
                                    "Message: {3}\n\t" +
 | 
					 | 
				
			||||||
                                    "Error: {4}",
 | 
					 | 
				
			||||||
                                    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}
 | 
					 | 
				
			||||||
                                    result.ErrorReason, // {4}
 | 
					 | 
				
			||||||
                                    sw.Elapsed.TotalSeconds // {5}
 | 
					 | 
				
			||||||
                                    );
 | 
					 | 
				
			||||||
                        if (guild != null && command != null && result.Error == CommandError.Exception)
 | 
					 | 
				
			||||||
                        {
 | 
					 | 
				
			||||||
                            if (permCache != null && permCache.Verbose)
 | 
					 | 
				
			||||||
                                try { await msg.Channel.SendMessageAsync("⚠️ " + result.ErrorReason).ConfigureAwait(false); } catch { }
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    else
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        if (msg.Channel is IPrivateChannel)
 | 
					 | 
				
			||||||
                        {
 | 
					 | 
				
			||||||
                            //rofl, gotta do this to prevent this message from occuring on polls
 | 
					 | 
				
			||||||
                            int vote;
 | 
					 | 
				
			||||||
                            if (int.TryParse(msg.Content, out vote)) return; 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                            await msg.Channel.SendMessageAsync(Help.DMHelpString).ConfigureAwait(false);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                            await DMForwardCommands.HandleDMForwarding(msg, ownerChannels);
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                catch (Exception ex)
 | 
					                else
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    _log.Warn(ex, "Error in CommandHandler");
 | 
					                    if (msg.Channel is IPrivateChannel)
 | 
				
			||||||
                    if (ex.InnerException != null)
 | 
					                    {
 | 
				
			||||||
                        _log.Warn(ex.InnerException, "Inner Exception of the error in CommandHandler");
 | 
					                        //rofl, gotta do this to prevent this message from occuring on polls
 | 
				
			||||||
 | 
					                        int vote;
 | 
				
			||||||
 | 
					                        if (int.TryParse(msg.Content, out vote)) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        await msg.Channel.SendMessageAsync(Help.DMHelpString).ConfigureAwait(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        await DMForwardCommands.HandleDMForwarding(msg, ownerChannels);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            });
 | 
					            }
 | 
				
			||||||
 | 
					            catch (Exception ex)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                _log.Warn(ex, "Error in CommandHandler");
 | 
				
			||||||
 | 
					                if (ex.InnerException != null)
 | 
				
			||||||
 | 
					                    _log.Warn(ex.InnerException, "Inner Exception of the error in CommandHandler");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        public Task<ExecuteCommandResult> ExecuteCommandAsync(CommandContext context, int argPos, IDependencyMap dependencyMap = null, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception)
 | 
					        public Task<ExecuteCommandResult> ExecuteCommandAsync(CommandContext context, int argPos, IDependencyMap dependencyMap = null, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception)
 | 
				
			||||||
@@ -267,7 +255,7 @@ namespace NadekoBot.Services
 | 
				
			|||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var cmd = commands[i];
 | 
					                var cmd = commands[i].Command;
 | 
				
			||||||
                bool resetCommand = cmd.Name == "ResetPermissions";
 | 
					                bool resetCommand = cmd.Name == "ResetPermissions";
 | 
				
			||||||
                PermissionCache pc;
 | 
					                PermissionCache pc;
 | 
				
			||||||
                if (context.Guild != null)
 | 
					                if (context.Guild != null)
 | 
				
			||||||
@@ -326,4 +314,4 @@ namespace NadekoBot.Services
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -14,19 +14,19 @@ namespace NadekoBot
 | 
				
			|||||||
        private DiscordSocketConfig discordSocketConfig;
 | 
					        private DiscordSocketConfig discordSocketConfig;
 | 
				
			||||||
        private Logger _log { get; }
 | 
					        private Logger _log { get; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public event Action<IGuildUser> UserJoined = delegate { };
 | 
					        public event Action<SocketGuildUser> UserJoined = delegate { };
 | 
				
			||||||
        public event Action<IMessage> MessageReceived = delegate { };
 | 
					        public event Action<SocketMessage> MessageReceived = delegate { };
 | 
				
			||||||
        public event Action<IGuildUser> UserLeft = delegate { };
 | 
					        public event Action<SocketGuildUser> UserLeft = delegate { };
 | 
				
			||||||
        public event Action<IGuildUser, IGuildUser> UserUpdated = delegate { };
 | 
					        public event Action<SocketUser, SocketUser> UserUpdated = delegate { };
 | 
				
			||||||
        public event Action<Optional<IMessage>, IMessage> MessageUpdated = delegate { };
 | 
					        public event Action<Optional<SocketMessage>, SocketMessage> MessageUpdated = delegate { };
 | 
				
			||||||
        public event Action<ulong, Optional<IMessage>> MessageDeleted = delegate { };
 | 
					        public event Action<ulong, Optional<SocketMessage>> MessageDeleted = delegate { };
 | 
				
			||||||
        public event Action<IUser, IGuild> UserBanned = delegate { };
 | 
					        public event Action<SocketUser, SocketGuild> UserBanned = delegate { };
 | 
				
			||||||
        public event Action<IUser, IGuild> UserUnbanned = delegate { };
 | 
					        public event Action<SocketUser, SocketGuild> UserUnbanned = delegate { };
 | 
				
			||||||
        public event Action<IGuildUser, IPresence, IPresence> UserPresenceUpdated = delegate { };
 | 
					        public event Action<Optional<SocketGuild>, SocketUser, SocketPresence, SocketPresence> UserPresenceUpdated = delegate { };
 | 
				
			||||||
        public event Action<IUser, IVoiceState, IVoiceState> UserVoiceStateUpdated = delegate { };
 | 
					        public event Action<SocketUser, SocketVoiceState, SocketVoiceState> UserVoiceStateUpdated = delegate { };
 | 
				
			||||||
        public event Action<IChannel> ChannelCreated = delegate { };
 | 
					        public event Action<SocketChannel> ChannelCreated = delegate { };
 | 
				
			||||||
        public event Action<IChannel> ChannelDestroyed = delegate { };
 | 
					        public event Action<SocketChannel> ChannelDestroyed = delegate { };
 | 
				
			||||||
        public event Action<IChannel, IChannel> ChannelUpdated = delegate { };
 | 
					        public event Action<SocketChannel, SocketChannel> ChannelUpdated = delegate { };
 | 
				
			||||||
        public event Action<Exception> Disconnected = delegate { };
 | 
					        public event Action<Exception> Disconnected = delegate { };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private uint _connectedCount = 0;
 | 
					        private uint _connectedCount = 0;
 | 
				
			||||||
@@ -58,7 +58,7 @@ namespace NadekoBot
 | 
				
			|||||||
                client.MessageDeleted += (arg1, arg2) => { MessageDeleted(arg1, arg2); return Task.CompletedTask; };
 | 
					                client.MessageDeleted += (arg1, arg2) => { MessageDeleted(arg1, arg2); return Task.CompletedTask; };
 | 
				
			||||||
                client.UserBanned += (arg1, arg2) => { UserBanned(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.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.UserVoiceStateUpdated += (arg1, arg2, arg3) => { UserVoiceStateUpdated(arg1, arg2, arg3); return Task.CompletedTask; };
 | 
				
			||||||
                client.ChannelCreated += arg => { ChannelCreated(arg); return Task.CompletedTask; };
 | 
					                client.ChannelCreated += arg => { ChannelCreated(arg); return Task.CompletedTask; };
 | 
				
			||||||
                client.ChannelDestroyed += arg => { ChannelDestroyed(arg); return Task.CompletedTask; };
 | 
					                client.ChannelDestroyed += arg => { ChannelDestroyed(arg); return Task.CompletedTask; };
 | 
				
			||||||
@@ -119,7 +119,7 @@ namespace NadekoBot
 | 
				
			|||||||
                var sw = Stopwatch.StartNew();
 | 
					                var sw = Stopwatch.StartNew();
 | 
				
			||||||
                await c.DownloadAllUsersAsync().ConfigureAwait(false);
 | 
					                await c.DownloadAllUsersAsync().ConfigureAwait(false);
 | 
				
			||||||
                sw.Stop();
 | 
					                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 Task SetGame(string game) => Task.WhenAll(Clients.Select(ms => ms.SetGame(game)));
 | 
					        public Task SetGame(string game) => Task.WhenAll(Clients.Select(ms => ms.SetGame(game)));
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,7 +6,7 @@ namespace NadekoBot.TypeReaders
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    public class CommandTypeReader : TypeReader
 | 
					    public class CommandTypeReader : TypeReader
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        public override Task<TypeReaderResult> Read(CommandContext context, string input)
 | 
					        public override Task<TypeReaderResult> Read(ICommandContext context, string input)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            input = input.ToUpperInvariant();
 | 
					            input = input.ToUpperInvariant();
 | 
				
			||||||
            var cmd = NadekoBot.CommandService.Commands.FirstOrDefault(c => 
 | 
					            var cmd = NadekoBot.CommandService.Commands.FirstOrDefault(c => 
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,7 +6,7 @@ namespace NadekoBot.TypeReaders
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    public class GuildTypeReader : TypeReader
 | 
					    public class GuildTypeReader : TypeReader
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        public override Task<TypeReaderResult> Read(CommandContext context, string input)
 | 
					        public override Task<TypeReaderResult> Read(ICommandContext context, string input)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            input = input.Trim().ToLowerInvariant();
 | 
					            input = input.Trim().ToLowerInvariant();
 | 
				
			||||||
            var guilds = NadekoBot.Client.GetGuilds();
 | 
					            var guilds = NadekoBot.Client.GetGuilds();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,7 @@ namespace NadekoBot.TypeReaders
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    public class ModuleTypeReader : TypeReader
 | 
					    public class ModuleTypeReader : TypeReader
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        public override Task<TypeReaderResult> Read(CommandContext context, string input)
 | 
					        public override Task<TypeReaderResult> Read(ICommandContext context, string input)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            input = input.ToUpperInvariant();
 | 
					            input = input.ToUpperInvariant();
 | 
				
			||||||
            var module = NadekoBot.CommandService.Modules.GroupBy(m => m.GetTopLevelModule()).FirstOrDefault(m => m.Key.Name.ToUpperInvariant() == input);
 | 
					            var module = NadekoBot.CommandService.Modules.GroupBy(m => m.GetTopLevelModule()).FirstOrDefault(m => m.Key.Name.ToUpperInvariant() == input);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,7 +9,7 @@ namespace NadekoBot.TypeReaders
 | 
				
			|||||||
    /// </summary>
 | 
					    /// </summary>
 | 
				
			||||||
    public class PermissionActionTypeReader : TypeReader
 | 
					    public class PermissionActionTypeReader : TypeReader
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        public override Task<TypeReaderResult> Read(CommandContext context, string input)
 | 
					        public override Task<TypeReaderResult> Read(ICommandContext context, string input)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            input = input.ToUpperInvariant();
 | 
					            input = input.ToUpperInvariant();
 | 
				
			||||||
            switch (input)
 | 
					            switch (input)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,8 +23,7 @@ namespace NadekoBot.Extensions
 | 
				
			|||||||
            http.DefaultRequestHeaders.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
 | 
					            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) =>
 | 
					        public static DateTime ToUnixTimestamp(this double number) => new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(number);
 | 
				
			||||||
            eb.WithImage(eib => eib.WithUrl(url));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public static EmbedBuilder WithOkColor(this EmbedBuilder eb) =>
 | 
					        public static EmbedBuilder WithOkColor(this EmbedBuilder eb) =>
 | 
				
			||||||
            eb.WithColor(NadekoBot.OkColor);
 | 
					            eb.WithColor(NadekoBot.OkColor);
 | 
				
			||||||
@@ -131,16 +130,16 @@ namespace NadekoBot.Extensions
 | 
				
			|||||||
        public static Task<IUserMessage> EmbedAsync(this IMessageChannel ch, EmbedBuilder embed, string msg = "")
 | 
					        public static Task<IUserMessage> EmbedAsync(this IMessageChannel ch, EmbedBuilder embed, string msg = "")
 | 
				
			||||||
             => ch.SendMessageAsync(msg, embed: embed);
 | 
					             => ch.SendMessageAsync(msg, embed: embed);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public static Task<IUserMessage> SendErrorAsync(this IMessageChannel ch, string title, string error, string url = null, string error = null)
 | 
					        public static Task<IUserMessage> SendErrorAsync(this IMessageChannel ch, string title, string error, string url = null, string footer = null)
 | 
				
			||||||
             => ch.SendMessageAsync("", embed: new EmbedBuilder().WithColor(NadekoBot.ErrorColor).WithDescription(error)
 | 
					             => ch.SendMessageAsync("", embed: new EmbedBuilder().WithColor(NadekoBot.ErrorColor).WithDescription(error)
 | 
				
			||||||
                 .WithTitle(title).WithUrl(url).WithFooter(efb => efb.WithText(error));
 | 
					                 .WithTitle(title).WithUrl(url).WithFooter(efb => efb.WithText(footer)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public static Task<IUserMessage> SendErrorAsync(this IMessageChannel ch, string error)
 | 
					        public static Task<IUserMessage> SendErrorAsync(this IMessageChannel ch, string error)
 | 
				
			||||||
             => ch.SendMessageAsync("", embed: new EmbedBuilder().WithColor(NadekoBot.OkColor).WithDescription(error));
 | 
					             => ch.SendMessageAsync("", embed: new EmbedBuilder().WithColor(NadekoBot.OkColor).WithDescription(error));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public static Task<IUserMessage> SendConfirmAsync(this IMessageChannel ch, string title, string text, string url = null, string footer = null)
 | 
					        public static Task<IUserMessage> SendConfirmAsync(this IMessageChannel ch, string title, string text, string url = null, string footer = null)
 | 
				
			||||||
             => ch.SendMessageAsync("", embed: new EmbedBuilder().WithColor(NadekoBot.OkColor).WithDescription(text)
 | 
					             => ch.SendMessageAsync("", embed: new EmbedBuilder().WithColor(NadekoBot.OkColor).WithDescription(text)
 | 
				
			||||||
                 .WithTitle(title).WithUrl(url).WithFooter(efb => efb.WithText(footer));
 | 
					                 .WithTitle(title).WithUrl(url).WithFooter(efb => efb.WithText(footer)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public static Task<IUserMessage> SendConfirmAsync(this IMessageChannel ch, string text)
 | 
					        public static Task<IUserMessage> SendConfirmAsync(this IMessageChannel ch, string text)
 | 
				
			||||||
             => ch.SendMessageAsync("", embed: new EmbedBuilder().WithColor(NadekoBot.OkColor).WithDescription(text));
 | 
					             => ch.SendMessageAsync("", embed: new EmbedBuilder().WithColor(NadekoBot.OkColor).WithDescription(text));
 | 
				
			||||||
@@ -154,10 +153,8 @@ namespace NadekoBot.Extensions
 | 
				
			|||||||
```");
 | 
					```");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public static Task<IUserMessage> SendTableAsync<T>(this IMessageChannel ch, IEnumerable<T> items, Func<T, string> howToPrint, int columns = 3)
 | 
					        public static Task<IUserMessage> SendTableAsync<T>(this IMessageChannel ch, IEnumerable<T> items, Func<T, string> howToPrint, int columns = 3) => 
 | 
				
			||||||
        {
 | 
					            ch.SendTableAsync("", items, howToPrint, columns);
 | 
				
			||||||
            return ch.SendTableAsync("", items, howToPrint, columns);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// returns an IEnumerable with randomized element order
 | 
					        /// returns an IEnumerable with randomized element order
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,6 +17,7 @@
 | 
				
			|||||||
    "define": []
 | 
					    "define": []
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "dependencies": {
 | 
					  "dependencies": {
 | 
				
			||||||
 | 
					    "AngleSharp": "0.9.9",
 | 
				
			||||||
    "VideoLibrary": "1.3.4",
 | 
					    "VideoLibrary": "1.3.4",
 | 
				
			||||||
    "CoreCLR-NCalc": "2.1.2",
 | 
					    "CoreCLR-NCalc": "2.1.2",
 | 
				
			||||||
    "Google.Apis.Urlshortener.v1": "1.19.0.138",
 | 
					    "Google.Apis.Urlshortener.v1": "1.19.0.138",
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user