diff --git a/scripts/NadekoInstallerLatest.bat b/scripts/Latest.bat similarity index 99% rename from scripts/NadekoInstallerLatest.bat rename to scripts/Latest.bat index 8cb53ee4..8256adbc 100644 --- a/scripts/NadekoInstallerLatest.bat +++ b/scripts/Latest.bat @@ -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 diff --git a/scripts/NadekoInstaller.bat b/scripts/Stable.bat similarity index 97% rename from scripts/NadekoInstaller.bat rename to scripts/Stable.bat index f52d1e07..f617ac8b 100644 --- a/scripts/NadekoInstaller.bat +++ b/scripts/Stable.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 diff --git a/src/NadekoBot/Modules/Help/Help.cs b/src/NadekoBot/Modules/Help/Help.cs index c026e996..11dd9437 100644 --- a/src/NadekoBot/Modules/Help/Help.cs +++ b/src/NadekoBot/Modules/Help/Help.cs @@ -156,8 +156,8 @@ You can support the project on patreon: or paypa var channel = (ITextChannel)umsg.Channel; await channel.SendMessageAsync( -@"**LIST OF COMMANDS**: -**Hosting Guides and docs can be found here**: ").ConfigureAwait(false); +@"**LIST OF COMMANDS**: +**Hosting Guides and docs can be found here**: ").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] diff --git a/src/NadekoBot/Modules/Searches/Commands/AnimeSearchCommands.cs b/src/NadekoBot/Modules/Searches/Commands/AnimeSearchCommands.cs index 6563d8cf..8571846b 100644 --- a/src/NadekoBot/Modules/Searches/Commands/AnimeSearchCommands.cs +++ b/src/NadekoBot/Modules/Searches/Commands/AnimeSearchCommands.cs @@ -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 GetAnimeData(string query) diff --git a/src/NadekoBot/Modules/Searches/Commands/Models/AnimeResult.cs b/src/NadekoBot/Modules/Searches/Commands/Models/AnimeResult.cs index d2a6152d..3d08da6e 100644 --- a/src/NadekoBot/Modules/Searches/Commands/Models/AnimeResult.cs +++ b/src/NadekoBot/Modules/Searches/Commands/Models/AnimeResult.cs @@ -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) + "..."; } } \ No newline at end of file diff --git a/src/NadekoBot/Modules/Searches/Commands/Models/MangaResult.cs b/src/NadekoBot/Modules/Searches/Commands/Models/MangaResult.cs index f5269017..5e262209 100644 --- a/src/NadekoBot/Modules/Searches/Commands/Models/MangaResult.cs +++ b/src/NadekoBot/Modules/Searches/Commands/Models/MangaResult.cs @@ -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) + "..."; } } \ No newline at end of file diff --git a/src/NadekoBot/Modules/Searches/Searches.cs b/src/NadekoBot/Modules/Searches/Searches.cs index 82bf2ece..dd5e7808 100644 --- a/src/NadekoBot/Modules/Searches/Searches.cs +++ b/src/NadekoBot/Modules/Searches/Searches.cs @@ -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] diff --git a/src/NadekoBot/Modules/Utility/Commands/InfoCommands.cs b/src/NadekoBot/Modules/Utility/Commands/InfoCommands.cs index 4f7ffd2f..7bd94198 100644 --- a/src/NadekoBot/Modules/Utility/Commands/InfoCommands.cs +++ b/src/NadekoBot/Modules/Utility/Commands/InfoCommands.cs @@ -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); } } } diff --git a/src/NadekoBot/NadekoBot.cs b/src/NadekoBot/NadekoBot.cs index 2d0be0ab..a0d80f36 100644 --- a/src/NadekoBot/NadekoBot.cs +++ b/src/NadekoBot/NadekoBot.cs @@ -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; } diff --git a/src/NadekoBot/Resources/CommandStrings.Designer.cs b/src/NadekoBot/Resources/CommandStrings.Designer.cs index f534b0c8..d64bce83 100644 --- a/src/NadekoBot/Resources/CommandStrings.Designer.cs +++ b/src/NadekoBot/Resources/CommandStrings.Designer.cs @@ -96,7 +96,7 @@ namespace NadekoBot.Resources { } /// - /// 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/>. /// public static string addcustreact_desc { get { diff --git a/src/NadekoBot/Resources/CommandStrings.resx b/src/NadekoBot/Resources/CommandStrings.resx index 010bc1aa..e2df60fe 100644 --- a/src/NadekoBot/Resources/CommandStrings.resx +++ b/src/NadekoBot/Resources/CommandStrings.resx @@ -427,7 +427,7 @@ addcustreact acr - 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/> + 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/> `{0}acr "hello" Hi there %user%` diff --git a/src/NadekoBot/Services/Database/Models/BotConfig.cs b/src/NadekoBot/Services/Database/Models/BotConfig.cs index e8216c7e..b20263c8 100644 --- a/src/NadekoBot/Services/Database/Models/BotConfig.cs +++ b/src/NadekoBot/Services/Database/Models/BotConfig.cs @@ -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** - + Nadeko Support Server: https://discord.gg/0ehQwTK2RBjAxzEY"; diff --git a/src/NadekoBot/_Extensions/Extensions.cs b/src/NadekoBot/_Extensions/Extensions.cs index 166e41b0..dc330324 100644 --- a/src/NadekoBot/_Extensions/Extensions.cs +++ b/src/NadekoBot/_Extensions/Extensions.cs @@ -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 EmbedAsync(this IMessageChannel ch, Discord.API.Embed embed) + => ch.SendMessageAsync("", embed: embed); + public static Task SendTableAsync(this IMessageChannel ch, string seed, IEnumerable items, Func 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); + } + /// /// Removes trailing S or ES (if specified) on the given string if the num is 1 ///