| @@ -107,4 +107,4 @@ IF EXIST "%root%NadekoBot\" (GOTO :backupinstall) | ||||
| 	ECHO. | ||||
| 	ECHO Installation complete, press any key to close this window! | ||||
| 	PAUSE >nul 2>&1 | ||||
| 	del NadekoLatest.bat | ||||
| 	del Latest.bat | ||||
| @@ -20,7 +20,7 @@ CD /D %installtemp% | ||||
| ::Downloads the latest version of Nadeko | ||||
| ECHO Downloading Nadeko... | ||||
| ECHO. | ||||
| git clone -b 1.0 --recursive --depth 1 --progress https://github.com/Kwoth/NadekoBot.git >nul | ||||
| git clone -b master --recursive --depth 1 --progress https://github.com/Kwoth/NadekoBot.git >nul | ||||
| IF %ERRORLEVEL% EQU 128 (GOTO :giterror) | ||||
| TITLE Installing NadekoBot, please wait | ||||
| ECHO. | ||||
| @@ -107,4 +107,4 @@ IF EXIST "%root%NadekoBot\" (GOTO :backupinstall) | ||||
| 	ECHO. | ||||
| 	ECHO Installation complete, press any key to close this window! | ||||
| 	PAUSE >nul 2>&1 | ||||
| 	del NadekoStable.bat | ||||
| 	del Stable.bat | ||||
| @@ -156,8 +156,8 @@ You can support the project on patreon: <https://patreon.com/nadekobot> or paypa | ||||
|             var channel = (ITextChannel)umsg.Channel; | ||||
|  | ||||
|             await channel.SendMessageAsync( | ||||
| @"**LIST OF COMMANDS**: <http://nadekobot.readthedocs.io/en/1.0/Commands%20List/> | ||||
| **Hosting Guides and docs can be found here**: <http://nadekobot.readthedocs.io/en/1.0/>").ConfigureAwait(false); | ||||
| @"**LIST OF COMMANDS**: <http://nadekobot.readthedocs.io/en/latest/Commands%20List/> | ||||
| **Hosting Guides and docs can be found here**: <http://nadekobot.readthedocs.io/en/latest/>").ConfigureAwait(false); | ||||
|         } | ||||
|  | ||||
|         [NadekoCommand, Usage, Description, Aliases] | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| using Discord; | ||||
| using Discord.API; | ||||
| using Discord.Commands; | ||||
| using NadekoBot.Attributes; | ||||
| using NadekoBot.Extensions; | ||||
| @@ -37,9 +38,36 @@ namespace NadekoBot.Modules.Searches | ||||
|                 if (string.IsNullOrWhiteSpace(query)) | ||||
|                     return; | ||||
|  | ||||
|                 var result = await GetAnimeData(query).ConfigureAwait(false); | ||||
|                 var animeData = await GetAnimeData(query).ConfigureAwait(false); | ||||
|  | ||||
|                 await channel.SendMessageAsync(result.ToString() ?? "`No anime found.`").ConfigureAwait(false); | ||||
|                 var embed = new Discord.API.Embed() | ||||
|                 { | ||||
|                     Description = animeData.Synopsis, | ||||
|                     Title = animeData.title_english, | ||||
|                     Url = animeData.Link, | ||||
|                     Image = new Discord.API.EmbedImage() { | ||||
|                         Url = animeData.image_url_lge | ||||
|                     }, | ||||
|                     Fields = new[] { | ||||
|                         new Discord.API.EmbedField() { | ||||
|                             Inline = true, | ||||
|                             Name = "Episodes", | ||||
|                             Value = animeData.total_episodes.ToString() | ||||
|                         }, | ||||
|                         new Discord.API.EmbedField() { | ||||
|                             Inline = true, | ||||
|                             Name = "Status", | ||||
|                             Value =  animeData.AiringStatus.ToString() | ||||
|                         }, | ||||
|                         new Discord.API.EmbedField() { | ||||
|                             Inline = true, | ||||
|                             Name = "Genres", | ||||
|                             Value = String.Join(", ", animeData.Genres) | ||||
|                         } | ||||
|                     }, | ||||
|                     Color = NadekoBot.OkColor | ||||
|                 }; | ||||
|                 await channel.EmbedAsync(embed).ConfigureAwait(false); | ||||
|             } | ||||
|  | ||||
|             [NadekoCommand, Usage, Description, Aliases] | ||||
| @@ -51,9 +79,38 @@ namespace NadekoBot.Modules.Searches | ||||
|                 if (string.IsNullOrWhiteSpace(query)) | ||||
|                     return; | ||||
|  | ||||
|                 var result = await GetMangaData(query).ConfigureAwait(false); | ||||
|                 var animeData = await GetMangaData(query).ConfigureAwait(false); | ||||
|  | ||||
|                 await channel.SendMessageAsync(result.ToString() ?? "`No manga found.`").ConfigureAwait(false); | ||||
|                 var embed = new Discord.API.Embed() | ||||
|                 { | ||||
|                     Description = animeData.Synopsis, | ||||
|                     Title = animeData.title_english, | ||||
|                     Url = animeData.Link, | ||||
|                     Image = new Discord.API.EmbedImage() | ||||
|                     { | ||||
|                         Url = animeData.image_url_lge | ||||
|                     }, | ||||
|                     Fields = new[] { | ||||
|                         new Discord.API.EmbedField() { | ||||
|                             Inline = true, | ||||
|                             Name = "Chapters", | ||||
|                             Value = animeData.total_chapters.ToString() | ||||
|                         }, | ||||
|                         new Discord.API.EmbedField() { | ||||
|                             Inline = true, | ||||
|                             Name = "Status", | ||||
|                             Value =  animeData.publishing_status.ToString() | ||||
|                         }, | ||||
|                         new Discord.API.EmbedField() { | ||||
|                             Inline = true, | ||||
|                             Name = "Genres", | ||||
|                             Value = String.Join(", ", animeData.Genres) | ||||
|                         } | ||||
|                     }, | ||||
|                     Color = NadekoBot.OkColor | ||||
|                 }; | ||||
|  | ||||
|                 await channel.EmbedAsync(embed).ConfigureAwait(false); | ||||
|             } | ||||
|  | ||||
|             private async Task<AnimeResult> GetAnimeData(string query) | ||||
|   | ||||
| @@ -1,20 +1,19 @@ | ||||
| namespace NadekoBot.Modules.Searches.Models | ||||
| using NadekoBot.Extensions; | ||||
| using System.Globalization; | ||||
|  | ||||
| namespace NadekoBot.Modules.Searches.Models | ||||
| { | ||||
|     public class AnimeResult | ||||
|     { | ||||
|         public int id; | ||||
|         public string AiringStatus => airing_status.ToTitleCase(); | ||||
|         public string airing_status; | ||||
|         public string title_english; | ||||
|         public int total_episodes; | ||||
|         public string description; | ||||
|         public string image_url_lge; | ||||
|  | ||||
|         public override string ToString() => | ||||
|             "`Title:` **" + title_english + | ||||
|             "**\n`Status:` " + airing_status + | ||||
|             "\n`Episodes:` " + total_episodes + | ||||
|             "\n`Link:` http://anilist.co/anime/" + id + | ||||
|             "\n`Synopsis:` " + description.Substring(0, description.Length > 500 ? 500 : description.Length) + "..." + | ||||
|             "\n`img:` " + image_url_lge; | ||||
|         public string[] Genres; | ||||
|         public string Link => "http://anilist.co/anime/" + id; | ||||
|         public string Synopsis => description?.Substring(0, description.Length > 500 ? 500 : description.Length) + "..."; | ||||
|     } | ||||
| } | ||||
| @@ -9,14 +9,8 @@ namespace NadekoBot.Modules.Searches.Models | ||||
|         public int total_chapters; | ||||
|         public int total_volumes; | ||||
|         public string description; | ||||
|  | ||||
|         public override string ToString() => | ||||
|             "`Title:` **" + title_english + | ||||
|             "**\n`Status:` " + publishing_status + | ||||
|             "\n`Chapters:` " + total_chapters + | ||||
|             "\n`Volumes:` " + total_volumes + | ||||
|             "\n`Link:` http://anilist.co/manga/" + id + | ||||
|             "\n`Synopsis:` " + description.Substring(0, description.Length > 500 ? 500 : description.Length) + "..." + | ||||
|             "\n`img:` " + image_url_lge; | ||||
|         public string[] Genres; | ||||
|         public string Link => "http://anilist.co/manga/" + id; | ||||
|         public string Synopsis => description?.Substring(0, description.Length > 500 ? 500 : description.Length) + "..."; | ||||
|     } | ||||
| } | ||||
| @@ -43,12 +43,18 @@ namespace NadekoBot.Modules.Searches | ||||
|  | ||||
|             var obj = JObject.Parse(response)["weather"]; | ||||
|  | ||||
|             await channel.SendMessageAsync( | ||||
| $@"🌍 **Weather for** 【{obj["target"]}】 | ||||
| 📏 **Lat,Long:** ({obj["latitude"]}, {obj["longitude"]}) ☁ **Condition:** {obj["condition"]} | ||||
| 😓 **Humidity:** {obj["humidity"]}% 💨 **Wind Speed:** {obj["windspeedk"]}km/h / {obj["windspeedm"]}mph  | ||||
| 🌡 **Temperature:** {obj["centigrade"]}°C / {obj["fahrenheit"]}°F 🔆 **Feels like:** {obj["feelscentigrade"]}°C / {obj["feelsfahrenheit"]}°F | ||||
| 🌄 **Sunrise:** {obj["sunrise"]} 🌇 **Sunset:** {obj["sunset"]}").ConfigureAwait(false); | ||||
|             var embed = new EmbedBuilder() | ||||
|                 .AddField(fb => fb.WithName("🌍 Location").WithValue($"{obj["target"]}").WithIsInline(true)) | ||||
|                 .AddField(fb => fb.WithName("📏 Lat,Long").WithValue($"{obj["latitude"]}, {obj["longitude"]}").WithIsInline(true)) | ||||
|                 .AddField(fb => fb.WithName("☁ Condition").WithValue($"{obj["condition"]}").WithIsInline(true)) | ||||
|                 .AddField(fb => fb.WithName("😓 Humidity").WithValue($"{obj["humidity"]}%").WithIsInline(true)) | ||||
|                 .AddField(fb => fb.WithName("💨 Wind Speed").WithValue($"{obj["windspeedk"]}km/h / {obj["windspeedm"]}mph").WithIsInline(true)) | ||||
|                 .AddField(fb => fb.WithName("🌡 Temperature").WithValue($"{obj["centigrade"]}°C / {obj["fahrenheit"]}°F").WithIsInline(true)) | ||||
|                 .AddField(fb => fb.WithName("🔆 Feels like").WithValue($"{obj["feelscentigrade"]}°C / {obj["feelsfahrenheit"]}°F").WithIsInline(true)) | ||||
|                 .AddField(fb => fb.WithName("🌄 Sunrise").WithValue($"{obj["sunrise"]}").WithIsInline(true)) | ||||
|                 .AddField(fb => fb.WithName("🌇 Sunset").WithValue($"{obj["sunset"]}").WithIsInline(true)) | ||||
|                 .WithColor(NadekoBot.OkColor); | ||||
|             await channel.EmbedAsync(embed.Build()).ConfigureAwait(false); | ||||
|         } | ||||
|  | ||||
|         [NadekoCommand, Usage, Description, Aliases] | ||||
|   | ||||
| @@ -91,13 +91,14 @@ __`Users:`__ **{(await ch.GetUsersAsync()).Count()}**"; | ||||
|             var toReturn = $"👤 __`Name:`__ **{user.Username}#{user.Discriminator}**\n"; | ||||
|             if (!string.IsNullOrWhiteSpace(user.Nickname)) | ||||
|                 toReturn += $"🆕 __`Nickname:`__ **{user.Nickname}** "; | ||||
|             toReturn += $@"🏷 __`ID:`__ **{user.Id}** | ||||
|                 toReturn += $@"🏷 __`ID:`__ **{user.Id}** | ||||
| 🎮 __`Current Game:`__ **{(user.Game?.Name == null ? "-" : user.Game.Name)}** | ||||
| 📅 __`Joined Server:`__ **{user.JoinedAt?.ToString("dd.MM.yyyy HH:mm")}**  | ||||
| 🗓 __`Joined Discord:`__ **{user.CreatedAt.ToString("dd.MM.yyyy HH:mm")}** | ||||
| ⚔ __`Roles:`__ **({user.Roles.Count()}) - {string.Join(", ", user.Roles.Select(r => r.Name)).SanitizeMentions()}** | ||||
| 📷 __`Avatar URL:`__ **{await NadekoBot.Google.ShortenUrl(user.AvatarUrl).ConfigureAwait(false)}**"; | ||||
|             await msg.Reply(toReturn).ConfigureAwait(false); | ||||
| ⚔ __`Roles:`__ **({user.Roles.Count()}) - {string.Join(", ", user.Roles.Select(r => r.Name)).SanitizeMentions()}**"; | ||||
|             if (!string.IsNullOrWhiteSpace(user.AvatarUrl)) | ||||
|                 toReturn += $@"📷 __`Avatar URL:`__ **{await NadekoBot.Google.ShortenUrl(user.AvatarUrl).ConfigureAwait(false)}**"; | ||||
|                 await msg.Reply(toReturn).ConfigureAwait(false); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -23,6 +23,9 @@ namespace NadekoBot | ||||
|     public class NadekoBot | ||||
|     { | ||||
|         private Logger _log; | ||||
|          | ||||
|         public static uint OkColor { get; } = 0x00ff00; | ||||
|         public static uint ErrorColor { get; } = 0xff0000; | ||||
|  | ||||
|         public static CommandService CommandService { get; private set; } | ||||
|         public static CommandHandler CommandHandler { get; private set; } | ||||
|   | ||||
| @@ -96,7 +96,7 @@ namespace NadekoBot.Resources { | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         ///    Looks up a localized string similar to Add a custom reaction with a trigger and a response. Running this command in server requires Administration permission. Running this command in DM is Bot Owner only and adds a new global custom reaction. Guide here: <http://nadekobot.readthedocs.io/en/1.0/Custom%20Reactions/>. | ||||
|         ///    Looks up a localized string similar to Add a custom reaction with a trigger and a response. Running this command in server requires Administration permission. Running this command in DM is Bot Owner only and adds a new global custom reaction. Guide here: <http://nadekobot.readthedocs.io/en/latest/Custom%20Reactions/>. | ||||
|         /// </summary> | ||||
|         public static string addcustreact_desc { | ||||
|             get { | ||||
|   | ||||
| @@ -427,7 +427,7 @@ | ||||
|     <value>addcustreact acr</value> | ||||
|   </data> | ||||
|   <data name="addcustreact_desc" xml:space="preserve"> | ||||
|     <value>Add a custom reaction with a trigger and a response. Running this command in server requires Administration permission. Running this command in DM is Bot Owner only and adds a new global custom reaction. Guide here: <http://nadekobot.readthedocs.io/en/1.0/Custom%20Reactions/></value> | ||||
|     <value>Add a custom reaction with a trigger and a response. Running this command in server requires Administration permission. Running this command in DM is Bot Owner only and adds a new global custom reaction. Guide here: <http://nadekobot.readthedocs.io/en/latest/Custom%20Reactions/></value> | ||||
|   </data> | ||||
|   <data name="addcustreact_usage" xml:space="preserve"> | ||||
|     <value>`{0}acr "hello" Hi there %user%`</value> | ||||
|   | ||||
| @@ -36,7 +36,7 @@ For a specific command help, use `{1}h CommandName` (for example {1}h !!q) | ||||
|  | ||||
|  | ||||
| **LIST OF COMMANDS CAN BE FOUND ON THIS LINK** | ||||
| <http://nadekobot.readthedocs.io/en/1.0/Commands%20List/> | ||||
| <http://nadekobot.readthedocs.io/en/latest/Commands%20List/> | ||||
|  | ||||
|  | ||||
| Nadeko Support Server: https://discord.gg/0ehQwTK2RBjAxzEY"; | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| using Discord; | ||||
| using Discord.API; | ||||
| using Discord.WebSocket; | ||||
| using ImageSharp; | ||||
| using Newtonsoft.Json; | ||||
| @@ -155,6 +156,9 @@ namespace NadekoBot.Extensions | ||||
|             return list.ToArray(); | ||||
|         } | ||||
|  | ||||
|         public static Task<IUserMessage> EmbedAsync(this IMessageChannel ch, Discord.API.Embed embed) | ||||
|              => ch.SendMessageAsync("", embed: embed); | ||||
|  | ||||
|         public static Task<IUserMessage> SendTableAsync<T>(this IMessageChannel ch, string seed, IEnumerable<T> items, Func<T, string> howToPrint, int columns = 3) | ||||
|         { | ||||
|             var i = 0; | ||||
| @@ -214,6 +218,18 @@ namespace NadekoBot.Extensions | ||||
|             return string.Concat(str.Take(maxLength - 3)) + (hideDots ? "" : "..."); | ||||
|         } | ||||
|  | ||||
|         public static string ToTitleCase(this string str) | ||||
|         { | ||||
|             var tokens = str.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries); | ||||
|             for (var i = 0; i < tokens.Length; i++) | ||||
|             { | ||||
|                 var token = tokens[i]; | ||||
|                 tokens[i] = token.Substring(0, 1).ToUpper() + token.Substring(1); | ||||
|             } | ||||
|  | ||||
|             return string.Join(" ", tokens); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Removes trailing S or ES (if specified) on the given string if the num is 1 | ||||
|         /// </summary> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user