Merge remote-tracking branch 'upstream/dev' into dev
This commit is contained in:
		| @@ -147,13 +147,13 @@ namespace NadekoBot.Modules.Administration | ||||
|                             { | ||||
|                                 var diffRoles = after.Roles.Where(r => !before.Roles.Contains(r)).Select(r => "**" + r.Name + "**"); | ||||
|                                 //str += $"**User's Roles changed ⚔➕**👤`{before.ToString()}`\n\tNow has {string.Join(", ", diffRoles)} role."; | ||||
|                                 str += $"👤__**{before.ToString()}**__ **| User's Role Added |** 🆔 `{before.Id}`\n\t✅ {string.Join(", ", diffRoles)}\n\t\t⚔ **`{string.Join(", ", after.Roles.Select(r => r.Name)).SanitizeMentions()}`** ⚔"; | ||||
|                                 str += $"👤__**{before.ToString()}**__ **| User's Role Added |** 🆔 `{before.Id}`\n\t✅ {string.Join(", ", diffRoles).SanitizeMentions()}\n\t\t⚔ **`{string.Join(", ", after.Roles.Select(r => r.Name)).SanitizeMentions()}`** ⚔"; | ||||
|                             } | ||||
|                             else if (before.Roles.Count() > after.Roles.Count()) | ||||
|                             { | ||||
|                                 var diffRoles = before.Roles.Where(r => !after.Roles.Contains(r)).Select(r => "**" + r.Name + "**"); | ||||
|                                 //str += $"**User's Roles changed **`{before.ToString()}`\n\tNo longer has {string.Join(", ", diffRoles)} role."; | ||||
|                                 str += $"👤__**{before.ToString()}**__ **| User's Role Removed |** 🆔 `{before.Id}`\n\t🚮 {string.Join(", ", diffRoles)}\n\t\t⚔ **`{string.Join(", ", after.Roles.Select(r => r.Name)).SanitizeMentions()}`** ⚔"; | ||||
|                                 str += $"👤__**{before.ToString()}**__ **| User's Role Removed |** 🆔 `{before.Id}`\n\t🚮 {string.Join(", ", diffRoles).SanitizeMentions()}\n\t\t⚔ **`{string.Join(", ", after.Roles.Select(r => r.Name)).SanitizeMentions()}`** ⚔"; | ||||
|                             } | ||||
|                         } | ||||
|                         else | ||||
|   | ||||
| @@ -6,7 +6,6 @@ namespace NadekoBot.Modules | ||||
| { | ||||
|     public class DiscordModule | ||||
|     { | ||||
|         protected ILocalization _l { get; } | ||||
|         protected CommandService _commands { get; } | ||||
|         protected ShardedDiscordClient  _client { get; } | ||||
|         protected Logger _log { get; } | ||||
| @@ -20,7 +19,6 @@ namespace NadekoBot.Modules | ||||
|             else | ||||
|                 _prefix = "?missing_prefix?"; | ||||
|  | ||||
|             _l = loc; | ||||
|             _commands = cmds; | ||||
|             _client = client; | ||||
|             _log = LogManager.GetCurrentClassLogger(); | ||||
|   | ||||
| @@ -88,15 +88,7 @@ namespace NadekoBot.Modules.Help | ||||
|  | ||||
|             if (com == null) | ||||
|             { | ||||
|                 //await channel.SendMessageAsync("🔍 **I can't find that command.**"); | ||||
|                 var erro = new EmbedBuilder() | ||||
|                     .WithAuthor(eau => eau.WithName("Sorry!") | ||||
|                     .WithUrl("http://nadekobot.readthedocs.io/en/latest/Commands%20List/") | ||||
|                     .WithIconUrl(NadekoBot.Client.GetCurrentUser().AvatarUrl)) | ||||
|                     //.WithTitle("Sorry!") | ||||
|                     .WithDescription("I can't find that command. Please check the **command** and **command prefix** before trying again.") | ||||
|                     .WithColor(NadekoBot.ErrorColor); | ||||
|                 await channel.EmbedAsync(erro.Build()); | ||||
|                 await channel.SendErrorAsync("I can't find that command. Please check the **command** and **command prefix** before trying again."); | ||||
|                 return; | ||||
|             } | ||||
|             var str = $"**`{com.Text}`**"; | ||||
| @@ -104,19 +96,11 @@ namespace NadekoBot.Modules.Help | ||||
|             if (alias != null) | ||||
|                 str += $" **/** **`{alias}`**"; | ||||
|                 var embed = new EmbedBuilder() | ||||
|                 .WithAuthor(eau => eau.WithName("Command") | ||||
|                 .WithUrl("http://nadekobot.readthedocs.io/en/latest/Commands%20List/") | ||||
|                 .WithIconUrl(NadekoBot.Client.GetCurrentUser().AvatarUrl)) | ||||
|                 //.WithTitle(str) | ||||
|                 //.WithDescription($"{ string.Format(com.Summary, com.Module.Prefix)}{ GetCommandRequirements(com)}") | ||||
|                 .AddField(fb => fb.WithIndex(1).WithName(str).WithValue($"{ string.Format(com.Summary, com.Module.Prefix)} { GetCommandRequirements(com)}").WithIsInline(true)) | ||||
|                 .AddField(fb => fb.WithIndex(2).WithName("**Usage**").WithValue($"{string.Format(com.Remarks, com.Module.Prefix)}").WithIsInline(false)) | ||||
|                 //.AddField(fb => fb.WithIndex(3).WithName("**Description**").WithValue($"{ string.Format(com.Summary, com.Module.Prefix)}{ GetCommandRequirements(com)}").WithIsInline(true)) | ||||
|                 .WithColor(NadekoBot.OkColor); | ||||
|             if (com != null) | ||||
|                 await channel.EmbedAsync(embed.Build()).ConfigureAwait(false); | ||||
|                 //await channel.SendMessageAsync(str + $@"{Environment.NewLine}**Desc:** {string.Format(com.Summary, com.Module.Prefix)} {GetCommandRequirements(com)} | ||||
| //**Usage:** {string.Format(com.Remarks, com.Module.Prefix)}").ConfigureAwait(false); | ||||
|         } | ||||
|  | ||||
|         private string GetCommandRequirements(Command cmd) | ||||
|   | ||||
| @@ -316,7 +316,7 @@ namespace NadekoBot.Modules.Pokemon | ||||
|             var targetType = StringToPokemonType(typeTargeted); | ||||
|             if (targetType == null) | ||||
|             { | ||||
|                 await channel.SendTableAsync<PokemonType>("`Available types:`\n", PokemonTypes, (t) => $"{t.Icon} {t.Name,-10}").ConfigureAwait(false); | ||||
|                 await channel.EmbedAsync(PokemonTypes.Aggregate(new EmbedBuilder().WithDescription("List of the available types:"), (eb, pt) => eb.AddField(efb => efb.WithName(pt.Name).WithValue(pt.Icon).WithIsInline(true))).WithColor(NadekoBot.OkColor).Build()).ConfigureAwait(false); | ||||
|                 return; | ||||
|             } | ||||
|             if (targetType == GetPokeType(user.Id)) | ||||
|   | ||||
| @@ -111,10 +111,7 @@ namespace NadekoBot.Modules.Searches | ||||
|                                                 try { await channel.EmbedAsync(fs.GetEmbed(newStatus).Build()).ConfigureAwait(false); } catch { } | ||||
|                                             } | ||||
|                                         } | ||||
|                                         catch (Exception ex) | ||||
|                                         { | ||||
|  | ||||
|                                         } | ||||
|                                         catch { } | ||||
|                                     })); | ||||
|  | ||||
|                     FirstPass = false; | ||||
|   | ||||
| @@ -379,8 +379,8 @@ namespace NadekoBot.Modules.Searches | ||||
|             using (var http = new HttpClient()) | ||||
|             { | ||||
|                 http.DefaultRequestHeaders.Clear(); | ||||
|                 http.DefaultRequestHeaders.Add("X-Mashape-Key", NadekoBot.Credentials.MashapeKey); | ||||
|                 var res = await http.GetStringAsync($"https://mashape-community-urban-dictionary.p.mashape.com/define?term={Uri.EscapeUriString(arg)}").ConfigureAwait(false); | ||||
|                 http.DefaultRequestHeaders.Add("Accept", "application/json"); | ||||
|                 var res = await http.GetStringAsync($"http://api.urbandictionary.com/v0/define?term={Uri.EscapeUriString(arg)}").ConfigureAwait(false); | ||||
|                 try | ||||
|                 { | ||||
|                     var items = JObject.Parse(res); | ||||
|   | ||||
| @@ -3,6 +3,8 @@ using Discord.Commands; | ||||
| using NadekoBot.Attributes; | ||||
| using NadekoBot.Extensions; | ||||
| using System; | ||||
| using System.Collections; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Reflection; | ||||
| using System.Text; | ||||
| @@ -10,24 +12,19 @@ using System.Threading.Tasks; | ||||
|  | ||||
| namespace NadekoBot.Modules.Utility | ||||
| { | ||||
|     [Group] | ||||
|     public partial class Utility | ||||
|     { | ||||
|         [NadekoCommand, Usage, Description, Aliases] | ||||
|         [RequireContext(ContextType.Guild)] | ||||
|         public static async Task Calculate(IUserMessage msg, [Remainder] string expression) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 var expr = new NCalc.Expression(expression, NCalc.EvaluateOptions.IgnoreCase); | ||||
|                 expr.EvaluateParameter += Expr_EvaluateParameter; | ||||
|                 var result = expr.Evaluate(); | ||||
|                 await msg.Reply(string.Format("⚙ `{0}`", expr.Error ?? result)); | ||||
|             } | ||||
|             catch (Exception e) | ||||
|             { | ||||
|                 await msg.Reply($"Failed to evaluate: {e.Message} "); | ||||
|             } | ||||
|             var expr = new NCalc.Expression(expression, NCalc.EvaluateOptions.IgnoreCase); | ||||
|             expr.EvaluateParameter += Expr_EvaluateParameter; | ||||
|             var result = expr.Evaluate(); | ||||
|             if (expr.Error == null) | ||||
|                 await msg.Channel.SendConfirmAsync("Result", $"{result}"); | ||||
|             else | ||||
|                 await msg.Channel.SendErrorAsync($"⚙ Error", expr.Error); | ||||
|         } | ||||
|  | ||||
|         private static void Expr_EvaluateParameter(string name, NCalc.ParameterArgs args) | ||||
| @@ -44,20 +41,25 @@ namespace NadekoBot.Modules.Utility | ||||
|         [RequireContext(ContextType.Guild)] | ||||
|         public async Task CalcOps(IUserMessage msg) | ||||
|         { | ||||
|             StringBuilder builder = new StringBuilder(); | ||||
|             var selection = typeof(Math).GetTypeInfo().GetMethods().Except(typeof(object).GetTypeInfo().GetMethods()).Select(x => | ||||
|             var selection = typeof(Math).GetTypeInfo().GetMethods().Except(typeof(object).GetTypeInfo().GetMethods()).Distinct(new MethodInfoEqualityComparer()).Select(x => | ||||
|             { | ||||
|                 var name = x.Name; | ||||
|                 if (x.GetParameters().Any()) | ||||
|                 { | ||||
|                     name += " (" + string.Join(", ", x.GetParameters().Select(y => y.IsOptional ? $"[{y.ParameterType.Name + " " + y.Name }]" : y.ParameterType.Name + " " + y.Name)) + ")"; | ||||
|                 } | ||||
|                 return name; | ||||
|             }); | ||||
|             foreach (var method in selection) builder.AppendLine(method); | ||||
|             await msg.ReplyLong(builder.ToString()); | ||||
|                 return x.Name; | ||||
|             }) | ||||
|             .Except(new[] { "ToString", | ||||
|                             "Equals", | ||||
|                             "GetHashCode", | ||||
|                             "GetType"}); | ||||
|             await msg.Channel.SendConfirmAsync(string.Join(", ",selection)); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     class MethodInfoEqualityComparer : IEqualityComparer<MethodInfo> | ||||
|     { | ||||
|         public bool Equals(MethodInfo x, MethodInfo y) => x.Name == y.Name; | ||||
|  | ||||
|         public int GetHashCode(MethodInfo obj) => obj.Name.GetHashCode(); | ||||
|     } | ||||
|  | ||||
|     class ExpressionContext | ||||
|     { | ||||
|         public double Pi { get; set; } = Math.PI; | ||||
|   | ||||
| @@ -10,25 +10,8 @@ using System.Threading.Tasks; | ||||
|  | ||||
| namespace NadekoBot.Modules.Utility | ||||
| { | ||||
|     partial class Utility : DiscordModule | ||||
|     public partial class Utility | ||||
|     { | ||||
|         [NadekoCommand, Usage, Description, Aliases] | ||||
|         [RequireContext(ContextType.Guild)] | ||||
|         public async Task TogetherTube(IUserMessage imsg) | ||||
|         { | ||||
|             var channel = (ITextChannel)imsg.Channel; | ||||
|  | ||||
|             Uri target; | ||||
|             using (var http = new HttpClient()) | ||||
|             { | ||||
|                 var res = await http.GetAsync("https://togethertube.com/room/create").ConfigureAwait(false); | ||||
|                 target = res.RequestMessage.RequestUri; | ||||
|             } | ||||
|  | ||||
|             await channel.SendMessageAsync($"🎞 {imsg.Author.Mention}, **Your new video room created. Join and invite to watch videos together with friends:** {target}") | ||||
|                          .ConfigureAwait(false); | ||||
|         } | ||||
|  | ||||
|         [NadekoCommand, Usage, Description, Aliases] | ||||
|         [RequireContext(ContextType.Guild)] | ||||
|         public async Task ServerInfo(IUserMessage msg, string guild = null) | ||||
| @@ -61,7 +44,7 @@ __`Created At:`__ **{createdAt.ToString("dd.MM.yyyy HH:mm")}** | ||||
|                 sb.AppendLine($"__`Features:`__ **{string.Join(", ", server.Features)}**"); | ||||
|             if (!string.IsNullOrWhiteSpace(server.SplashUrl)) | ||||
|                 sb.AppendLine($"__`Region:`__ **{server.VoiceRegionId}**"); | ||||
|             await msg.Reply(sb.ToString()).ConfigureAwait(false); | ||||
|             await channel.SendConfirmAsync(sb.ToString()).ConfigureAwait(false); | ||||
|         } | ||||
|  | ||||
|         [NadekoCommand, Usage, Description, Aliases] | ||||
| @@ -77,7 +60,7 @@ __`ID:`__ **{ch.Id}** | ||||
| __`Created At:`__ **{createdAt.ToString("dd.MM.yyyy HH:mm")}** | ||||
| __`Topic:`__ {ch.Topic} | ||||
| __`Users:`__ **{(await ch.GetUsersAsync()).Count()}**"; | ||||
|             await msg.Reply(toReturn).ConfigureAwait(false); | ||||
|             await msg.Channel.SendConfirmAsync(toReturn).ConfigureAwait(false); | ||||
|         } | ||||
|  | ||||
|         [NadekoCommand, Usage, Description, Aliases] | ||||
| @@ -99,7 +82,7 @@ __`Users:`__ **{(await ch.GetUsersAsync()).Count()}**"; | ||||
|             if (!string.IsNullOrWhiteSpace(user.AvatarUrl)) | ||||
|                 toReturn += $@" | ||||
| 📷 __`Avatar URL:`__ **{await NadekoBot.Google.ShortenUrl(user.AvatarUrl).ConfigureAwait(false)}**"; | ||||
|                 await msg.Reply(toReturn).ConfigureAwait(false); | ||||
|                 await msg.Channel.SendConfirmAsync(toReturn).ConfigureAwait(false); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -31,10 +31,10 @@ namespace NadekoBot.Modules.Utility | ||||
|             } | ||||
|  | ||||
|             if (quotes.Any()) | ||||
|                 await channel.SendMessageAsync($"💬 **Page {page + 1} of quotes:**\n```xl\n" + String.Join("\n", quotes.Select((q) => $"{q.Keyword,-20} by {q.AuthorName}")) + "\n```") | ||||
|                 await channel.SendConfirmAsync($"💬 **Page {page + 1} of quotes:**\n```xl\n" + String.Join("\n", quotes.Select((q) => $"{q.Keyword,-20} by {q.AuthorName}")) + "\n```") | ||||
|                              .ConfigureAwait(false); | ||||
|             else | ||||
|                 await channel.SendMessageAsync("ℹ️ **No quotes on this page.**").ConfigureAwait(false); | ||||
|                 await channel.SendErrorAsync("No quotes on this page.").ConfigureAwait(false); | ||||
|         } | ||||
|  | ||||
|         [NadekoCommand, Usage, Description, Aliases] | ||||
| @@ -57,7 +57,7 @@ namespace NadekoBot.Modules.Utility | ||||
|             if (quote == null) | ||||
|                 return; | ||||
|  | ||||
|             await channel.SendMessageAsync("📣 " + quote.Text.SanitizeMentions()); | ||||
|             await channel.SendConfirmAsync("📣 " + quote.Text.SanitizeMentions()); | ||||
|         } | ||||
|  | ||||
|         [NadekoCommand, Usage, Description, Aliases] | ||||
| @@ -83,7 +83,7 @@ namespace NadekoBot.Modules.Utility | ||||
|                 }); | ||||
|                 await uow.CompleteAsync().ConfigureAwait(false); | ||||
|             } | ||||
|             await channel.SendMessageAsync("✅ **Quote added.**").ConfigureAwait(false); | ||||
|             await channel.SendConfirmAsync("✅ Quote added.").ConfigureAwait(false); | ||||
|         } | ||||
|  | ||||
|         [NadekoCommand, Usage, Description, Aliases] | ||||
| @@ -105,7 +105,7 @@ namespace NadekoBot.Modules.Utility | ||||
|  | ||||
|                 if (qs==null || !qs.Any()) | ||||
|                 { | ||||
|                     response = "ℹ️ **No quotes found.**"; | ||||
|                     await channel.SendErrorAsync("No quotes found."); | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
| @@ -115,7 +115,7 @@ namespace NadekoBot.Modules.Utility | ||||
|                 await uow.CompleteAsync().ConfigureAwait(false); | ||||
|                 response = "🗑 **Deleted a random quote.**"; | ||||
|             } | ||||
|             await channel.SendMessageAsync(response); | ||||
|             await channel.SendConfirmAsync(response); | ||||
|         } | ||||
|  | ||||
|         [NadekoCommand, Usage, Description, Aliases] | ||||
| @@ -139,7 +139,7 @@ namespace NadekoBot.Modules.Utility | ||||
|                 await uow.CompleteAsync(); | ||||
|             } | ||||
|  | ||||
|             await channel.SendMessageAsync($"🗑 **Deleted all quotes** with **{keyword}** keyword."); | ||||
|             await channel.SendConfirmAsync($"🗑 **Deleted all quotes** with **{keyword}** keyword."); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -74,7 +74,7 @@ namespace NadekoBot.Modules.Utility | ||||
|                     if (ch == null) | ||||
|                         return; | ||||
|  | ||||
|                     await ch.SendMessageAsync( | ||||
|                     await ch.SendConfirmAsync( | ||||
|                         replacements.Aggregate(RemindMessageFormat, | ||||
|                             (cur, replace) => cur.Replace(replace.Key, replace.Value(r))) | ||||
|                             .SanitizeMentions() | ||||
| @@ -124,7 +124,7 @@ namespace NadekoBot.Modules.Utility | ||||
|  | ||||
|                 if (ch == null) | ||||
|                 { | ||||
|                     await channel.SendMessageAsync($"⚠️ {umsg.Author.Mention} Something went wrong (channel cannot be found) ;(").ConfigureAwait(false); | ||||
|                     await channel.SendErrorAsync($"{umsg.Author.Mention} Something went wrong (channel cannot be found) ;(").ConfigureAwait(false); | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
| @@ -132,7 +132,7 @@ namespace NadekoBot.Modules.Utility | ||||
|  | ||||
|                 if (m.Length == 0) | ||||
|                 { | ||||
|                     await channel.SendMessageAsync("❎ **Not a valid time format.** type `-h .remind`").ConfigureAwait(false); | ||||
|                     await channel.SendErrorAsync("Not a valid time format. Type `-h .remind`").ConfigureAwait(false); | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
| @@ -157,7 +157,7 @@ namespace NadekoBot.Modules.Utility | ||||
|                         (groupName == "hours" && value > 23) || | ||||
|                         (groupName == "minutes" && value > 59)) | ||||
|                     { | ||||
|                         await channel.SendMessageAsync($"⚠️ Invalid {groupName} value.").ConfigureAwait(false); | ||||
|                         await channel.SendErrorAsync($"Invalid {groupName} value.").ConfigureAwait(false); | ||||
|                         return; | ||||
|                     } | ||||
|                     else | ||||
| @@ -187,7 +187,7 @@ namespace NadekoBot.Modules.Utility | ||||
|                     await uow.CompleteAsync(); | ||||
|                 } | ||||
|  | ||||
|                 try { await channel.SendMessageAsync($"⏰ I will remind **\"{(ch is ITextChannel ? ((ITextChannel)ch).Name : umsg.Author.Username)}\"** to **\"{message.SanitizeMentions()}\"** in **{output}** `({time:d.M.yyyy.} at {time:HH:mm})`").ConfigureAwait(false); } catch { } | ||||
|                 try { await channel.SendConfirmAsync($"⏰ I will remind **\"{(ch is ITextChannel ? ((ITextChannel)ch).Name : umsg.Author.Username)}\"** to **\"{message.SanitizeMentions()}\"** in **{output}** `({time:d.M.yyyy.} at {time:HH:mm})`").ConfigureAwait(false); } catch { } | ||||
|                 await StartReminder(rem); | ||||
|             } | ||||
|              | ||||
| @@ -206,7 +206,7 @@ namespace NadekoBot.Modules.Utility | ||||
|                     uow.BotConfig.GetOrCreate().RemindMessageFormat = arg.Trim(); | ||||
|                     await uow.CompleteAsync().ConfigureAwait(false); | ||||
|                 } | ||||
|                 await channel.SendMessageAsync("🆗 New remind template set."); | ||||
|                 await channel.SendConfirmAsync("🆗 New remind template set."); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -104,15 +104,14 @@ namespace NadekoBot.Modules.Utility | ||||
|             [RequireContext(ContextType.Guild)] | ||||
|             public async Task ConvertList(IUserMessage msg) | ||||
|             { | ||||
|                 var sb = new StringBuilder("Units that can be used by the converter: \n"); | ||||
|                 var res = Units.GroupBy(x => x.UnitType); | ||||
|                 foreach (var group in res) | ||||
|                 { | ||||
|                     sb.AppendLine($"{group.Key}: ```xl"); | ||||
|                     sb.AppendLine(string.Join(",", group.Select(x => x.Triggers.FirstOrDefault()).OrderBy(x => x))); | ||||
|                     sb.AppendLine("```"); | ||||
|                 } | ||||
|                 await msg.ReplyLong(sb.ToString(),  breakOn: new[] { "```xl\n", "\n" }); | ||||
|                 var res = Units.GroupBy(x => x.UnitType) | ||||
|                                .Aggregate(new EmbedBuilder().WithTitle("__Units which can be used by the converter__") | ||||
|                                                             .WithColor(NadekoBot.OkColor), | ||||
|                                           (embed, g) => embed.AddField(efb =>  | ||||
|                                                                          efb.WithName(g.Key.ToTitleCase()) | ||||
|                                                                          .WithValue(String.Join(", ", g.Select(x => x.Triggers.FirstOrDefault()) | ||||
|                                                                                                        .OrderBy(x => x))))); | ||||
|                 await msg.Channel.EmbedAsync(res.Build()); | ||||
|             } | ||||
|             [NadekoCommand, Usage, Description, Aliases] | ||||
|             public async Task Convert(IUserMessage msg, string origin, string target, decimal value) | ||||
| @@ -121,12 +120,12 @@ namespace NadekoBot.Modules.Utility | ||||
|                 var targetUnit = Units.Find(x => x.Triggers.Select(y => y.ToLowerInvariant()).Contains(target.ToLowerInvariant())); | ||||
|                 if (originUnit == null || targetUnit == null) | ||||
|                 { | ||||
|                     await msg.Reply(string.Format("Cannot convert {0} to {1}: units not found", origin, target)); | ||||
|                     await msg.Channel.SendErrorAsync(string.Format("Cannot convert {0} to {1}: units not found", origin, target)); | ||||
|                     return; | ||||
|                 } | ||||
|                 if (originUnit.UnitType != targetUnit.UnitType) | ||||
|                 { | ||||
|                     await msg.Reply(string.Format("Cannot convert {0} to {1}: types of unit are not equal", originUnit.Triggers.First(), targetUnit.Triggers.First())); | ||||
|                     await msg.Channel.SendErrorAsync(string.Format("Cannot convert {0} to {1}: types of unit are not equal", originUnit.Triggers.First(), targetUnit.Triggers.First())); | ||||
|                     return; | ||||
|                 } | ||||
|                 decimal res; | ||||
| @@ -170,7 +169,7 @@ namespace NadekoBot.Modules.Utility | ||||
|                 } | ||||
|                 res = Math.Round(res, 4); | ||||
|  | ||||
|                 await msg.Reply(string.Format("{0} {1} is equal to {2} {3}", value, (originUnit.Triggers.First() + "s").SnPl(value.IsInteger() ? (int)value : 2), res, (targetUnit.Triggers.First() + "s").SnPl(res.IsInteger() ? (int)res : 2))); | ||||
|                 await msg.Channel.SendConfirmAsync(string.Format("{0} {1} is equal to {2} {3}", value, (originUnit.Triggers.First() + "s").SnPl(value.IsInteger() ? (int)value : 2), res, (targetUnit.Triggers.First() + "s").SnPl(res.IsInteger() ? (int)res : 2))); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -44,7 +44,9 @@ namespace NadekoBot.Modules.Utility | ||||
|             if (!arr.Any()) | ||||
|                 await channel.SendErrorAsync("Nobody is playing that game.").ConfigureAwait(false); | ||||
|             else | ||||
|                 await channel.SendMessageAsync("```css\n" + string.Join("\n", arr.GroupBy(item => (i++) / 3).Select(ig => string.Concat(ig.Select(el => $"• {el,-35}")))) + "\n```").ConfigureAwait(false); | ||||
|                 await channel.SendConfirmAsync("```css\n" + string.Join("\n", arr.GroupBy(item => (i++) / 2) | ||||
|                                                                                  .Select(ig => string.Concat(ig.Select(el => $"• {el,-27}")))) + "\n```") | ||||
|                                                                                  .ConfigureAwait(false); | ||||
|         } | ||||
|  | ||||
|         [NadekoCommand, Usage, Description, Aliases] | ||||
| @@ -55,7 +57,7 @@ namespace NadekoBot.Modules.Utility | ||||
|                 return; | ||||
|             var channel = (ITextChannel)umsg.Channel; | ||||
|             var arg = roles.Split(',').Select(r => r.Trim().ToUpperInvariant()); | ||||
|             string send = _l["ℹ️ **Here is a list of users in a specfic role:**"]; | ||||
|             string send = "ℹ️ **Here is a list of users in those roles:**"; | ||||
|             foreach (var roleStr in arg.Where(str => !string.IsNullOrWhiteSpace(str) && str != "@EVERYONE" && str != "EVERYONE")) | ||||
|             { | ||||
|                 var role = channel.Guild.Roles.Where(r => r.Name.ToUpperInvariant() == roleStr).FirstOrDefault(); | ||||
| @@ -69,16 +71,16 @@ namespace NadekoBot.Modules.Utility | ||||
|             { | ||||
|                 if (!usr.GetPermissions(channel).ManageMessages) | ||||
|                 { | ||||
|                     await channel.SendMessageAsync($"⚠️ {usr.Mention} **you are not allowed to use this command on roles with a lot of users in them to prevent abuse.**").ConfigureAwait(false); | ||||
|                     await channel.SendErrorAsync($"⚠️ {usr.Mention} **you are not allowed to use this command on roles with a lot of users in them to prevent abuse.**").ConfigureAwait(false); | ||||
|                     return; | ||||
|                 } | ||||
|                 var curstr = send.Substring(0, 2000); | ||||
|                 await channel.SendMessageAsync(curstr.Substring(0, | ||||
|                 await channel.SendConfirmAsync(curstr.Substring(0, | ||||
|                         curstr.LastIndexOf(", ", StringComparison.Ordinal) + 1)).ConfigureAwait(false); | ||||
|                 send = curstr.Substring(curstr.LastIndexOf(", ", StringComparison.Ordinal) + 1) + | ||||
|                        send.Substring(2000); | ||||
|             } | ||||
|             await channel.SendMessageAsync(send).ConfigureAwait(false); | ||||
|             await channel.SendConfirmAsync(send).ConfigureAwait(false); | ||||
|         } | ||||
|  | ||||
|         [NadekoCommand, Usage, Description, Aliases] | ||||
| @@ -95,7 +97,7 @@ namespace NadekoBot.Modules.Utility | ||||
|             } | ||||
|  | ||||
|             builder.Append("```"); | ||||
|             await msg.Reply(builder.ToString()); | ||||
|             await msg.Channel.SendConfirmAsync(builder.ToString()); | ||||
|         } | ||||
|  | ||||
|         [NadekoCommand, Usage, Description, Aliases] | ||||
| @@ -103,20 +105,20 @@ namespace NadekoBot.Modules.Utility | ||||
|         public async Task UserId(IUserMessage msg, IGuildUser target = null) | ||||
|         { | ||||
|             var usr = target ?? msg.Author; | ||||
|             await msg.Reply($"🆔 of the user **{ usr.Username }** is `{ usr.Id }`").ConfigureAwait(false); | ||||
|             await msg.Channel.SendConfirmAsync($"🆔 of the user **{ usr.Username }** is `{ usr.Id }`").ConfigureAwait(false); | ||||
|         } | ||||
|  | ||||
|         [NadekoCommand, Usage, Description, Aliases] | ||||
|         public async Task ChannelId(IUserMessage msg) | ||||
|         { | ||||
|             await msg.Reply($"ℹ️ This **Channel's ID** is `{msg.Channel.Id}`").ConfigureAwait(false); | ||||
|             await msg.Channel.SendConfirmAsync($"🆔 of this channel is `{msg.Channel.Id}`").ConfigureAwait(false); | ||||
|         } | ||||
|  | ||||
|         [NadekoCommand, Usage, Description, Aliases] | ||||
|         [RequireContext(ContextType.Guild)] | ||||
|         public async Task ServerId(IUserMessage msg) | ||||
|         { | ||||
|             await msg.Reply($"ℹ️ This **Server's ID** is `{((ITextChannel)msg.Channel).Guild.Id}`").ConfigureAwait(false); | ||||
|             await msg.Channel.SendConfirmAsync($"🆔 of this server is `{((ITextChannel)msg.Channel).Guild.Id}`").ConfigureAwait(false); | ||||
|         } | ||||
|  | ||||
|         [NadekoCommand, Usage, Description, Aliases] | ||||
| @@ -132,11 +134,11 @@ namespace NadekoBot.Modules.Utility | ||||
|                 return; | ||||
|             if (target != null) | ||||
|             { | ||||
|                 await msg.Reply($"⚔ **Page #{page} of roles for {target.Username}:** ```css\n• " + string.Join("\n• ", target.Roles.Except(new[] { guild.EveryoneRole }).OrderBy(r => r.Position).Skip((page - 1) * RolesPerPage).Take(RolesPerPage)).SanitizeMentions() + "\n```"); | ||||
|                 await channel.SendConfirmAsync($"⚔ **Page #{page} of roles for {target.Username}**", $"```css\n• " + string.Join("\n• ", target.Roles.Except(new[] { guild.EveryoneRole }).OrderBy(r => -r.Position).Skip((page - 1) * RolesPerPage).Take(RolesPerPage)).SanitizeMentions() + "\n```"); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 await msg.Reply($"⚔ **Page #{page} of all roles on this server:** ```css\n• " + string.Join("\n• ", guild.Roles.Except(new[] { guild.EveryoneRole }).OrderBy(r => r.Position).Skip((page - 1) * RolesPerPage).Take(RolesPerPage)).SanitizeMentions() + "\n```"); | ||||
|                 await channel.SendConfirmAsync($"⚔ **Page #{page} of all roles on this server:**", $"```css\n• " + string.Join("\n• ", guild.Roles.Except(new[] { guild.EveryoneRole }).OrderBy(r => -r.Position).Skip((page - 1) * RolesPerPage).Take(RolesPerPage)).SanitizeMentions() + "\n```"); | ||||
|             } | ||||
|         } | ||||
|  | ||||
| @@ -153,9 +155,9 @@ namespace NadekoBot.Modules.Utility | ||||
|  | ||||
|             var topic = channel.Topic; | ||||
|             if (string.IsNullOrWhiteSpace(topic)) | ||||
|                 await channel.SendMessageAsync("❎ **No topic set.**"); | ||||
|                 await channel.SendErrorAsync("No topic set."); | ||||
|             else | ||||
|                 await channel.SendMessageAsync("ℹ️ **Topic:** " + topic); | ||||
|                 await channel.SendConfirmAsync("Channel topic", topic); | ||||
|         } | ||||
|  | ||||
|         [NadekoCommand, Usage, Description, Aliases] | ||||
| @@ -254,42 +256,16 @@ namespace NadekoBot.Modules.Utility | ||||
|  | ||||
|             if (!guilds.Any()) | ||||
|             { | ||||
|                 await channel.SendMessageAsync("❎ No servers found on that page.").ConfigureAwait(false); | ||||
|                 await channel.SendErrorAsync("No servers found on that page.").ConfigureAwait(false); | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             await channel.SendMessageAsync(String.Join("\n", guilds.Select(g => $"```css\nName: {g.Name} ID:{g.Id} Members:#{g.GetUsers().Count} OwnerID: {g.OwnerId} ```"))).ConfigureAwait(false); | ||||
|             await channel.EmbedAsync(guilds.Aggregate(new EmbedBuilder().WithColor(NadekoBot.OkColor), | ||||
|                                      (embed, g) => embed.AddField(efb => efb.WithName(g.Name) | ||||
|                                                                            .WithValue($"```css\nID: {g.Id}\nMembers: {g.GetUsers().Count}\nOwnerID: {g.OwnerId} ```") | ||||
|                                                                            .WithIsInline(false))) | ||||
|                                            .Build()) | ||||
|                          .ConfigureAwait(false); | ||||
|         } | ||||
|  | ||||
|         //[NadekoCommand, Usage, Description, Aliases] | ||||
|         //[RequireContext(ContextType.Guild)] | ||||
|         //public async Task TextToImage(IUserMessage msg, [Remainder] string arg) | ||||
|         //{ | ||||
|         //    var channel = (ITextChannel)msg.Channel; | ||||
|  | ||||
|         //    const string bgName = "xbiy3"; | ||||
|  | ||||
|         //    if (string.IsNullOrWhiteSpace(arg)) | ||||
|         //        return; | ||||
|  | ||||
|         //    using (var http = new HttpClient()) | ||||
|         //    { | ||||
|         //        http.AddFakeHeaders(); | ||||
|  | ||||
|         //        http.DefaultRequestHeaders.Add("Host", "www.tagsmaker.com"); | ||||
|         //        http.DefaultRequestHeaders.Add("Referer", "http://www.tagsmaker.com/"); | ||||
|         //        http.DefaultRequestHeaders.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"); | ||||
|         //        http.DefaultRequestHeaders.Add("Alt-Used", "www.tagsmaker.com:443"); | ||||
|  | ||||
|         //        var res = await http.GetAsync($"http://www.tagsmaker.com/tagsmaker.php?background_name=0011&tag_text={arg}&font_name=applejuiced&text_color=white&text_size=48&text_alignment=middle").ConfigureAwait(false); | ||||
|  | ||||
|         //        var img = res.RequestMessage.RequestUri.Segments[1].Replace("image-", "").Replace("tag-", ""); | ||||
|         //        var imgStream = await http.GetStreamAsync($"http://www.tagsmaker.com/upload/www.tagsmaker.com_{ img.ToString() }.png"); | ||||
|         //        var ms = new MemoryStream(); | ||||
|         //        await imgStream.CopyToAsync(ms).ConfigureAwait(false); | ||||
|         //        ms.Position = 0; | ||||
|         //        await channel.SendFileAsync(ms, arg+".png", "Provided by www.tagsmaker.com").ConfigureAwait(false); | ||||
|         //    } | ||||
|         //} | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -13,20 +13,20 @@ namespace NadekoBot | ||||
|         private DiscordSocketConfig discordSocketConfig; | ||||
|         private Logger _log { get; } | ||||
|  | ||||
|         public Func<IGuildUser, Task> UserJoined { get; internal set; } = delegate { return Task.CompletedTask; }; | ||||
|         public Func<IMessage, Task> MessageReceived { get; internal set; } = delegate { return Task.CompletedTask; }; | ||||
|         public Func<IGuildUser, Task> UserLeft { get; internal set; } = delegate { return Task.CompletedTask; }; | ||||
|         public Func<IGuildUser, IGuildUser, Task> UserUpdated { get; internal set; } = delegate { return Task.CompletedTask; }; | ||||
|         public Func<Optional<IMessage>, IMessage, Task> MessageUpdated { get; internal set; } = delegate { return Task.CompletedTask; }; | ||||
|         public Func<ulong, Optional<IMessage>, Task> MessageDeleted { get; internal set; } = delegate { return Task.CompletedTask; }; | ||||
|         public Func<IUser, IGuild, Task> UserBanned { get; internal set; } = delegate { return Task.CompletedTask; }; | ||||
|         public Func<IUser, IGuild, Task> UserUnbanned { get; internal set; } = delegate { return Task.CompletedTask; }; | ||||
|         public Func<IGuildUser, IPresence, IPresence, Task> UserPresenceUpdated { get; internal set; } = delegate { return Task.CompletedTask; }; | ||||
|         public Func<IUser, IVoiceState, IVoiceState, Task> UserVoiceStateUpdated { get; internal set; } = delegate { return Task.CompletedTask; }; | ||||
|         public Func<IChannel, Task> ChannelCreated { get; internal set; } = delegate { return Task.CompletedTask; }; | ||||
|         public Func<IChannel, Task> ChannelDestroyed { get; internal set; } = delegate { return Task.CompletedTask; }; | ||||
|         public Func<IChannel, IChannel, Task> ChannelUpdated { get; internal set; } = delegate { return Task.CompletedTask; }; | ||||
|         public Func<Exception, Task> Disconnected { get; internal set; } = delegate { return Task.CompletedTask; }; | ||||
|         public event Func<IGuildUser, Task> UserJoined = delegate { return Task.CompletedTask; }; | ||||
|         public event Func<IMessage, Task> MessageReceived = delegate { return Task.CompletedTask; }; | ||||
|         public event Func<IGuildUser, Task> UserLeft = delegate { return Task.CompletedTask; }; | ||||
|         public event Func<IGuildUser, IGuildUser, Task> UserUpdated = delegate { return Task.CompletedTask; }; | ||||
|         public event Func<Optional<IMessage>, IMessage, Task> MessageUpdated = delegate { return Task.CompletedTask; }; | ||||
|         public event Func<ulong, Optional<IMessage>, Task> MessageDeleted = delegate { return Task.CompletedTask; }; | ||||
|         public event Func<IUser, IGuild, Task> UserBanned = delegate { return Task.CompletedTask; }; | ||||
|         public event Func<IUser, IGuild, Task> UserUnbanned = delegate { return Task.CompletedTask; }; | ||||
|         public event Func<IGuildUser, IPresence, IPresence, Task> UserPresenceUpdated = delegate { return Task.CompletedTask; }; | ||||
|         public event Func<IUser, IVoiceState, IVoiceState, Task> UserVoiceStateUpdated = delegate { return Task.CompletedTask; }; | ||||
|         public event Func<IChannel, Task> ChannelCreated = delegate { return Task.CompletedTask; }; | ||||
|         public event Func<IChannel, Task> ChannelDestroyed = delegate { return Task.CompletedTask; }; | ||||
|         public event Func<IChannel, IChannel, Task> ChannelUpdated = delegate { return Task.CompletedTask; }; | ||||
|         public event Func<Exception, Task> Disconnected = delegate { return Task.CompletedTask; }; | ||||
|  | ||||
|         private IReadOnlyList<DiscordSocketClient> Clients { get; } | ||||
|  | ||||
|   | ||||
| @@ -74,9 +74,6 @@ namespace NadekoBot.Extensions | ||||
|         public static async Task<IUserMessage> SendFileAsync(this IGuildUser user, Stream fileStream, string fileName, string caption = null, bool isTTS = false) => | ||||
|             await (await user.CreateDMChannelAsync().ConfigureAwait(false)).SendFileAsync(fileStream, fileName, caption, isTTS).ConfigureAwait(false); | ||||
|  | ||||
|         public static async Task<IUserMessage> Reply(this IUserMessage msg, string content) => | ||||
|             await msg.Channel.SendMessageAsync(content).ConfigureAwait(false); | ||||
|  | ||||
|         public static bool IsAuthor(this IUserMessage msg) => | ||||
|             NadekoBot.Client.GetCurrentUser().Id == msg.Author.Id; | ||||
|  | ||||
| @@ -159,9 +156,18 @@ namespace NadekoBot.Extensions | ||||
|         public static Task<IUserMessage> EmbedAsync(this IMessageChannel ch, Discord.API.Embed embed, string msg = "") | ||||
|              => ch.SendMessageAsync(msg, embed: embed); | ||||
|  | ||||
|         public static Task<IUserMessage> SendErrorAsync(this IMessageChannel ch, string error, string title = null, string url = null) | ||||
|         public static Task<IUserMessage> SendErrorAsync(this IMessageChannel ch, string title, string error, string url = null) | ||||
|              => ch.SendMessageAsync("", embed: new Embed() { Description = error, Title = title, Url = url, Color = NadekoBot.ErrorColor }); | ||||
|  | ||||
|         public static Task<IUserMessage> SendErrorAsync(this IMessageChannel ch, string error) | ||||
|              => ch.SendMessageAsync("", embed: new Embed() { Description = error, Color = NadekoBot.ErrorColor }); | ||||
|  | ||||
|         public static Task<IUserMessage> SendConfirmAsync(this IMessageChannel ch, string title, string text, string url = null) | ||||
|              => ch.SendMessageAsync("", embed: new Embed() { Description = text, Title = title, Url = url, Color = NadekoBot.OkColor }); | ||||
|  | ||||
|         public static Task<IUserMessage> SendConfirmAsync(this IMessageChannel ch, string text) | ||||
|              => ch.SendMessageAsync("", embed: new Embed() { Description = text, Color = NadekoBot.OkColor }); | ||||
|  | ||||
|         public static Task<IUserMessage> SendTableAsync<T>(this IMessageChannel ch, string seed, IEnumerable<T> items, Func<T, string> howToPrint, int columns = 3) | ||||
|         { | ||||
|             var i = 0; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user