searches localizable o.o

This commit is contained in:
Kwoth 2017-02-24 17:10:44 +01:00
parent 2ef3006ac0
commit 1bfa8becb3
17 changed files with 1542 additions and 432 deletions

View File

@ -7,8 +7,6 @@ using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using NadekoBot.Services; using NadekoBot.Services;
using System.Net.Http; using System.Net.Http;
using System.Text.RegularExpressions;
using System.Xml.Linq;
using NadekoBot.Extensions; using NadekoBot.Extensions;
using System.Xml; using System.Xml;
using System.Threading; using System.Threading;
@ -20,8 +18,8 @@ namespace NadekoBot.Modules.NSFW
public class NSFW : NadekoTopLevelModule public class NSFW : NadekoTopLevelModule
{ {
private static readonly ConcurrentDictionary<ulong, Timer> AutoHentaiTimers = new ConcurrentDictionary<ulong, Timer>(); private static readonly ConcurrentDictionary<ulong, Timer> _autoHentaiTimers = new ConcurrentDictionary<ulong, Timer>();
private static readonly ConcurrentHashSet<ulong> HentaiBombBlacklist = new ConcurrentHashSet<ulong>(); private static readonly ConcurrentHashSet<ulong> _hentaiBombBlacklist = new ConcurrentHashSet<ulong>();
private async Task InternalHentai(IMessageChannel channel, string tag, bool noError) private async Task InternalHentai(IMessageChannel channel, string tag, bool noError)
{ {
@ -72,7 +70,7 @@ namespace NadekoBot.Modules.NSFW
if (interval == 0) if (interval == 0)
{ {
if (!AutoHentaiTimers.TryRemove(Context.Channel.Id, out t)) return; if (!_autoHentaiTimers.TryRemove(Context.Channel.Id, out t)) return;
t.Change(Timeout.Infinite, Timeout.Infinite); //proper way to disable the timer t.Change(Timeout.Infinite, Timeout.Infinite); //proper way to disable the timer
await ReplyConfirmLocalized("autohentai_stopped").ConfigureAwait(false); await ReplyConfirmLocalized("autohentai_stopped").ConfigureAwait(false);
@ -99,7 +97,7 @@ namespace NadekoBot.Modules.NSFW
} }
}, null, interval * 1000, interval * 1000); }, null, interval * 1000, interval * 1000);
AutoHentaiTimers.AddOrUpdate(Context.Channel.Id, t, (key, old) => _autoHentaiTimers.AddOrUpdate(Context.Channel.Id, t, (key, old) =>
{ {
old.Change(Timeout.Infinite, Timeout.Infinite); old.Change(Timeout.Infinite, Timeout.Infinite);
return t; return t;
@ -114,7 +112,7 @@ namespace NadekoBot.Modules.NSFW
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
public async Task HentaiBomb([Remainder] string tag = null) public async Task HentaiBomb([Remainder] string tag = null)
{ {
if (!HentaiBombBlacklist.Add(Context.User.Id)) if (!_hentaiBombBlacklist.Add(Context.User.Id))
return; return;
try try
{ {
@ -138,17 +136,17 @@ namespace NadekoBot.Modules.NSFW
finally finally
{ {
await Task.Delay(5000).ConfigureAwait(false); await Task.Delay(5000).ConfigureAwait(false);
HentaiBombBlacklist.TryRemove(Context.User.Id); _hentaiBombBlacklist.TryRemove(Context.User.Id);
} }
} }
#endif #endif
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
public Task Yandere([Remainder] string tag = null) public Task Yandere([Remainder] string tag = null)
=> Searches.Searches.InternalDapiCommand(Context.Message, tag, Searches.Searches.DapiSearchType.Yandere); => InternalDapiCommand(Context.Message, tag, Searches.Searches.DapiSearchType.Yandere);
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
public Task Konachan([Remainder] string tag = null) public Task Konachan([Remainder] string tag = null)
=> Searches.Searches.InternalDapiCommand(Context.Message, tag, Searches.Searches.DapiSearchType.Konachan); => InternalDapiCommand(Context.Message, tag, Searches.Searches.DapiSearchType.Konachan);
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
public async Task E621([Remainder] string tag = null) public async Task E621([Remainder] string tag = null)
@ -169,7 +167,7 @@ namespace NadekoBot.Modules.NSFW
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
public Task Rule34([Remainder] string tag = null) public Task Rule34([Remainder] string tag = null)
=> Searches.Searches.InternalDapiCommand(Context.Message, tag, Searches.Searches.DapiSearchType.Rule34); => InternalDapiCommand(Context.Message, tag, Searches.Searches.DapiSearchType.Rule34);
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
public async Task Danbooru([Remainder] string tag = null) public async Task Danbooru([Remainder] string tag = null)
@ -212,7 +210,7 @@ namespace NadekoBot.Modules.NSFW
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
public Task Gelbooru([Remainder] string tag = null) public Task Gelbooru([Remainder] string tag = null)
=> Searches.Searches.InternalDapiCommand(Context.Message, tag, Searches.Searches.DapiSearchType.Gelbooru); => InternalDapiCommand(Context.Message, tag, Searches.Searches.DapiSearchType.Gelbooru);
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
public async Task Cp() public async Task Cp()
@ -289,5 +287,22 @@ namespace NadekoBot.Modules.NSFW
public static Task<string> GetGelbooruImageLink(string tag) => public static Task<string> GetGelbooruImageLink(string tag) =>
Searches.Searches.InternalDapiSearch(tag, Searches.Searches.DapiSearchType.Gelbooru); Searches.Searches.InternalDapiSearch(tag, Searches.Searches.DapiSearchType.Gelbooru);
public async Task InternalDapiCommand(IUserMessage umsg, string tag, Searches.Searches.DapiSearchType type)
{
var channel = umsg.Channel;
tag = tag?.Trim() ?? "";
var url = await Searches.Searches.InternalDapiSearch(tag, type).ConfigureAwait(false);
if (url == null)
await channel.SendErrorAsync(umsg.Author.Mention + " " + GetText("no_results"));
else
await channel.EmbedAsync(new EmbedBuilder().WithOkColor()
.WithDescription(umsg.Author.Mention + " " + tag)
.WithImageUrl(url)
.WithFooter(efb => efb.WithText(type.ToString()))).ConfigureAwait(false);
}
} }
} }

View File

@ -1,6 +1,5 @@
using AngleSharp; using AngleSharp;
using AngleSharp.Dom.Html; using AngleSharp.Dom.Html;
using AngleSharp.Extensions;
using Discord; using Discord;
using Discord.Commands; using Discord.Commands;
using NadekoBot.Attributes; using NadekoBot.Attributes;
@ -8,7 +7,6 @@ using NadekoBot.Extensions;
using NadekoBot.Modules.Searches.Models; using NadekoBot.Modules.Searches.Models;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using NLog;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -21,15 +19,13 @@ namespace NadekoBot.Modules.Searches
public partial class Searches public partial class Searches
{ {
[Group] [Group]
public class AnimeSearchCommands : ModuleBase public class AnimeSearchCommands : NadekoSubmodule
{ {
private static Timer anilistTokenRefresher { get; } private static readonly Timer anilistTokenRefresher;
private static Logger _log { get; }
private static string anilistToken { get; set; } private static string anilistToken { get; set; }
static AnimeSearchCommands() static AnimeSearchCommands()
{ {
_log = LogManager.GetCurrentClassLogger();
anilistTokenRefresher = new Timer(async (state) => anilistTokenRefresher = new Timer(async (state) =>
{ {
try try
@ -49,9 +45,9 @@ namespace NadekoBot.Modules.Searches
anilistToken = JObject.Parse(stringContent)["access_token"].ToString(); anilistToken = JObject.Parse(stringContent)["access_token"].ToString();
} }
} }
catch (Exception ex) catch
{ {
_log.Error(ex); // ignored
} }
}, null, TimeSpan.FromSeconds(0), TimeSpan.FromMinutes(29)); }, null, TimeSpan.FromSeconds(0), TimeSpan.FromMinutes(29));
} }
@ -75,7 +71,7 @@ namespace NadekoBot.Modules.Searches
var favorites = document.QuerySelectorAll("div.user-favorites > div.di-tc"); var favorites = document.QuerySelectorAll("div.user-favorites > div.di-tc");
var favAnime = "No favorite anime yet"; var favAnime = GetText("anime_no_fav");
if (favorites[0].QuerySelector("p") == null) if (favorites[0].QuerySelector("p") == null)
favAnime = string.Join("\n", favorites[0].QuerySelectorAll("ul > li > div.di-tc.va-t > a") favAnime = string.Join("\n", favorites[0].QuerySelectorAll("ul > li > div.di-tc.va-t > a")
.Shuffle() .Shuffle()
@ -106,14 +102,14 @@ namespace NadekoBot.Modules.Searches
var embed = new EmbedBuilder() var embed = new EmbedBuilder()
.WithOkColor() .WithOkColor()
.WithTitle($"{name}'s MAL profile") .WithTitle(GetText("mal_profile", name))
.AddField(efb => efb.WithName("💚 Watching").WithValue(stats[0]).WithIsInline(true)) .AddField(efb => efb.WithName("💚 " + GetText("watching")).WithValue(stats[0]).WithIsInline(true))
.AddField(efb => efb.WithName("💙 Completed").WithValue(stats[1]).WithIsInline(true)); .AddField(efb => efb.WithName("💙 " + GetText("completed")).WithValue(stats[1]).WithIsInline(true));
if (info.Count < 3) if (info.Count < 3)
embed.AddField(efb => efb.WithName("💛 On-Hold").WithValue(stats[2]).WithIsInline(true)); embed.AddField(efb => efb.WithName("💛 " + GetText("on_hold")).WithValue(stats[2]).WithIsInline(true));
embed embed
.AddField(efb => efb.WithName("💔 Dropped").WithValue(stats[3]).WithIsInline(true)) .AddField(efb => efb.WithName("💔 " + GetText("dropped")).WithValue(stats[3]).WithIsInline(true))
.AddField(efb => efb.WithName("⚪ Plan to watch").WithValue(stats[4]).WithIsInline(true)) .AddField(efb => efb.WithName("⚪ " + GetText("plan_to_watch")).WithValue(stats[4]).WithIsInline(true))
.AddField(efb => efb.WithName("🕐 " + daysAndMean[0][0]).WithValue(daysAndMean[0][1]).WithIsInline(true)) .AddField(efb => efb.WithName("🕐 " + daysAndMean[0][0]).WithValue(daysAndMean[0][1]).WithIsInline(true))
.AddField(efb => efb.WithName("📊 " + daysAndMean[1][0]).WithValue(daysAndMean[1][1]).WithIsInline(true)) .AddField(efb => efb.WithName("📊 " + daysAndMean[1][0]).WithValue(daysAndMean[1][1]).WithIsInline(true))
.AddField(efb => efb.WithName(MalInfoToEmoji(info[0].Item1) + " " + info[0].Item1).WithValue(info[0].Item2.TrimTo(20)).WithIsInline(true)) .AddField(efb => efb.WithName(MalInfoToEmoji(info[0].Item1) + " " + info[0].Item1).WithValue(info[0].Item2.TrimTo(20)).WithIsInline(true))
@ -126,7 +122,7 @@ namespace NadekoBot.Modules.Searches
.WithDescription($@" .WithDescription($@"
** https://myanimelist.net/animelist/{ name } ** ** https://myanimelist.net/animelist/{ name } **
**Top 3 Favorite Anime:** **{GetText("top_3_fav_anime")}**
{favAnime}" {favAnime}"
//**[Manga List](https://myanimelist.net/mangalist/{name})** //**[Manga List](https://myanimelist.net/mangalist/{name})**
@ -176,7 +172,7 @@ namespace NadekoBot.Modules.Searches
if (animeData == null) if (animeData == null)
{ {
await Context.Channel.SendErrorAsync("Failed finding that animu.").ConfigureAwait(false); await ReplyErrorLocalized("failed_finding_anime").ConfigureAwait(false);
return; return;
} }
@ -185,10 +181,10 @@ namespace NadekoBot.Modules.Searches
.WithTitle(animeData.title_english) .WithTitle(animeData.title_english)
.WithUrl(animeData.Link) .WithUrl(animeData.Link)
.WithImageUrl(animeData.image_url_lge) .WithImageUrl(animeData.image_url_lge)
.AddField(efb => efb.WithName("Episodes").WithValue(animeData.total_episodes.ToString()).WithIsInline(true)) .AddField(efb => efb.WithName(GetText("episodes")).WithValue(animeData.total_episodes.ToString()).WithIsInline(true))
.AddField(efb => efb.WithName("Status").WithValue(animeData.AiringStatus.ToString()).WithIsInline(true)) .AddField(efb => efb.WithName(GetText("status")).WithValue(animeData.AiringStatus.ToString()).WithIsInline(true))
.AddField(efb => efb.WithName("Genres").WithValue(String.Join(", ", animeData.Genres)).WithIsInline(true)) .AddField(efb => efb.WithName(GetText("genres")).WithValue(String.Join(",\n", animeData.Genres)).WithIsInline(true))
.WithFooter(efb => efb.WithText("Score: " + animeData.average_score + " / 100")); .WithFooter(efb => efb.WithText(GetText("score") + " " + animeData.average_score + " / 100"));
await Context.Channel.EmbedAsync(embed).ConfigureAwait(false); await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
} }
@ -203,7 +199,7 @@ namespace NadekoBot.Modules.Searches
if (mangaData == null) if (mangaData == null)
{ {
await Context.Channel.SendErrorAsync("Failed finding that mango.").ConfigureAwait(false); await ReplyErrorLocalized("failed_finding_manga").ConfigureAwait(false);
return; return;
} }
@ -212,10 +208,10 @@ namespace NadekoBot.Modules.Searches
.WithTitle(mangaData.title_english) .WithTitle(mangaData.title_english)
.WithUrl(mangaData.Link) .WithUrl(mangaData.Link)
.WithImageUrl(mangaData.image_url_lge) .WithImageUrl(mangaData.image_url_lge)
.AddField(efb => efb.WithName("Episodes").WithValue(mangaData.total_chapters.ToString()).WithIsInline(true)) .AddField(efb => efb.WithName(GetText("chapters")).WithValue(mangaData.total_chapters.ToString()).WithIsInline(true))
.AddField(efb => efb.WithName("Status").WithValue(mangaData.publishing_status.ToString()).WithIsInline(true)) .AddField(efb => efb.WithName(GetText("status")).WithValue(mangaData.publishing_status.ToString()).WithIsInline(true))
.AddField(efb => efb.WithName("Genres").WithValue(String.Join(", ", mangaData.Genres)).WithIsInline(true)) .AddField(efb => efb.WithName(GetText("genres")).WithValue(String.Join(",\n", mangaData.Genres)).WithIsInline(true))
.WithFooter(efb => efb.WithText("Score: " + mangaData.average_score + " / 100")); .WithFooter(efb => efb.WithText(GetText("score") + " " + mangaData.average_score + " / 100"));
await Context.Channel.EmbedAsync(embed).ConfigureAwait(false); await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
} }

View File

@ -13,7 +13,7 @@ namespace NadekoBot.Modules.Searches
public static GoogleTranslator Instance = _instance ?? (_instance = new GoogleTranslator()); public static GoogleTranslator Instance = _instance ?? (_instance = new GoogleTranslator());
public IEnumerable<string> Languages => _languageDictionary.Keys.OrderBy(x => x); public IEnumerable<string> Languages => _languageDictionary.Keys.OrderBy(x => x);
private Dictionary<string, string> _languageDictionary; private readonly Dictionary<string, string> _languageDictionary;
static GoogleTranslator() { } static GoogleTranslator() { }
private GoogleTranslator() { private GoogleTranslator() {
@ -153,13 +153,13 @@ namespace NadekoBot.Modules.Searches
public async Task<string> Translate(string sourceText, string sourceLanguage, string targetLanguage) public async Task<string> Translate(string sourceText, string sourceLanguage, string targetLanguage)
{ {
string text = string.Empty; string text;
string url = string.Format("https://translate.googleapis.com/translate_a/single?client=gtx&sl={0}&tl={1}&dt=t&q={2}", var url = string.Format("https://translate.googleapis.com/translate_a/single?client=gtx&sl={0}&tl={1}&dt=t&q={2}",
ConvertToLanguageCode(sourceLanguage), ConvertToLanguageCode(sourceLanguage),
ConvertToLanguageCode(targetLanguage), ConvertToLanguageCode(targetLanguage),
WebUtility.UrlEncode(sourceText)); WebUtility.UrlEncode(sourceText));
using (HttpClient http = new HttpClient()) using (var http = new HttpClient())
{ {
http.DefaultRequestHeaders.Add("user-agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36"); http.DefaultRequestHeaders.Add("user-agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36");
text = await http.GetStringAsync(url).ConfigureAwait(false); text = await http.GetStringAsync(url).ConfigureAwait(false);
@ -170,7 +170,7 @@ namespace NadekoBot.Modules.Searches
private string ConvertToLanguageCode(string language) private string ConvertToLanguageCode(string language)
{ {
string mode = string.Empty; string mode;
_languageDictionary.TryGetValue(language, out mode); _languageDictionary.TryGetValue(language, out mode);
return mode; return mode;
} }

View File

@ -7,7 +7,6 @@ using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using NLog; using NLog;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Net.Http; using System.Net.Http;
@ -18,11 +17,11 @@ namespace NadekoBot.Modules.Searches
public partial class Searches public partial class Searches
{ {
[Group] [Group]
public class JokeCommands : ModuleBase public class JokeCommands : NadekoSubmodule
{ {
private static List<WoWJoke> wowJokes { get; } = new List<WoWJoke>(); private static List<WoWJoke> wowJokes { get; } = new List<WoWJoke>();
private static List<MagicItem> magicItems { get; } = new List<MagicItem>(); private static List<MagicItem> magicItems { get; } = new List<MagicItem>();
private static Logger _log { get; } private new static readonly Logger _log;
static JokeCommands() static JokeCommands()
{ {
@ -78,7 +77,7 @@ namespace NadekoBot.Modules.Searches
{ {
if (!wowJokes.Any()) if (!wowJokes.Any())
{ {
await Context.Channel.SendErrorAsync("Jokes not loaded.").ConfigureAwait(false); await ReplyErrorLocalized("jokes_not_loaded").ConfigureAwait(false);
return; return;
} }
var joke = wowJokes[new NadekoRandom().Next(0, wowJokes.Count)]; var joke = wowJokes[new NadekoRandom().Next(0, wowJokes.Count)];
@ -90,7 +89,7 @@ namespace NadekoBot.Modules.Searches
{ {
if (!wowJokes.Any()) if (!wowJokes.Any())
{ {
await Context.Channel.SendErrorAsync("MagicItems not loaded.").ConfigureAwait(false); await ReplyErrorLocalized("magicitems_not_loaded").ConfigureAwait(false);
return; return;
} }
var item = magicItems[new NadekoRandom().Next(0, magicItems.Count)]; var item = magicItems[new NadekoRandom().Next(0, magicItems.Count)];

View File

@ -33,7 +33,7 @@ namespace NadekoBot.Modules.Searches
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
public async Task Lolban() public async Task Lolban()
{ {
var showCount = 8; const int showCount = 8;
//http://api.champion.gg/stats/champs/mostBanned?api_key=YOUR_API_TOKEN&page=1&limit=2 //http://api.champion.gg/stats/champs/mostBanned?api_key=YOUR_API_TOKEN&page=1&limit=2
try try
{ {
@ -44,19 +44,20 @@ namespace NadekoBot.Modules.Searches
$"limit={showCount}") $"limit={showCount}")
.ConfigureAwait(false))["data"] as JArray; .ConfigureAwait(false))["data"] as JArray;
var dataList = data.Distinct(new ChampionNameComparer()).Take(showCount).ToList(); var dataList = data.Distinct(new ChampionNameComparer()).Take(showCount).ToList();
var eb = new EmbedBuilder().WithOkColor().WithTitle(Format.Underline($"{dataList.Count} most banned champions")); var eb = new EmbedBuilder().WithOkColor().WithTitle(Format.Underline(GetText("x_most_banned_champs",dataList.Count)));
for (var i = 0; i < dataList.Count; i++) foreach (var champ in dataList)
{ {
var champ = dataList[i]; var champ1 = champ;
eb.AddField(efb => efb.WithName(champ["name"].ToString()).WithValue(champ["general"]["banRate"] + "%").WithIsInline(true)); eb.AddField(efb => efb.WithName(champ1["name"].ToString()).WithValue(champ1["general"]["banRate"] + "%").WithIsInline(true));
} }
await Context.Channel.EmbedAsync(eb, Format.Italics(trashTalk[new NadekoRandom().Next(0, trashTalk.Length)])).ConfigureAwait(false); await Context.Channel.EmbedAsync(eb, Format.Italics(trashTalk[new NadekoRandom().Next(0, trashTalk.Length)])).ConfigureAwait(false);
} }
} }
catch (Exception) catch (Exception ex)
{ {
await Context.Channel.SendMessageAsync("Something went wrong.").ConfigureAwait(false); _log.Warn(ex);
await ReplyErrorLocalized("something_went_wrong").ConfigureAwait(false);
} }
} }
} }

View File

@ -1,39 +1,44 @@
using Newtonsoft.Json; using Newtonsoft.Json;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using NadekoBot.Attributes; using NadekoBot.Attributes;
using System.Net.Http; using System.Net.Http;
using System.Text; using System.Text;
using Discord.Commands;
using NadekoBot.Extensions; using NadekoBot.Extensions;
namespace NadekoBot.Modules.Searches namespace NadekoBot.Modules.Searches
{ {
public partial class Searches public partial class Searches
{ {
[Group]
Dictionary<char, string> map = new Dictionary<char, string>(); public class MemegenCommands : NadekoSubmodule
public Searches()
{ {
map.Add('?', "~q"); private static readonly ImmutableDictionary<char, string> _map = new Dictionary<char, string>()
map.Add('%', "~p"); {
map.Add('#', "~h"); {'?', "~q"},
map.Add('/', "~s"); {'%', "~p"},
map.Add(' ', "-"); {'#', "~h"},
map.Add('-', "--"); {'/', "~s"},
map.Add('_', "__"); {' ', "-"},
map.Add('"', "''"); {'-', "--"},
} {'_', "__"},
{'"', "''"}
}.ToImmutableDictionary();
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
public async Task Memelist() public async Task Memelist()
{ {
HttpClientHandler handler = new HttpClientHandler(); var handler = new HttpClientHandler
{
AllowAutoRedirect = false
};
handler.AllowAutoRedirect = false;
using (var http = new HttpClient(handler)) using (var http = new HttpClient(handler))
{ {
@ -54,14 +59,14 @@ namespace NadekoBot.Modules.Searches
.ConfigureAwait(false); .ConfigureAwait(false);
} }
private string Replace(string input) private static string Replace(string input)
{ {
StringBuilder sb = new StringBuilder(); var sb = new StringBuilder();
string tmp;
foreach (var c in input) foreach (var c in input)
{ {
if (map.TryGetValue(c, out tmp)) string tmp;
if (_map.TryGetValue(c, out tmp))
sb.Append(tmp); sb.Append(tmp);
else else
sb.Append(c); sb.Append(c);
@ -71,3 +76,4 @@ namespace NadekoBot.Modules.Searches
} }
} }
} }
}

View File

@ -3,7 +3,6 @@ using Discord.Commands;
using NadekoBot.Attributes; using NadekoBot.Attributes;
using NadekoBot.Extensions; using NadekoBot.Extensions;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using NLog;
using System; using System;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
@ -16,21 +15,15 @@ namespace NadekoBot.Modules.Searches
public partial class Searches public partial class Searches
{ {
[Group] [Group]
public class OsuCommands : ModuleBase public class OsuCommands : NadekoSubmodule
{ {
private static Logger _log { get; }
static OsuCommands()
{
_log = LogManager.GetCurrentClassLogger();
}
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
public async Task Osu(string usr, [Remainder] string mode = null) public async Task Osu(string usr, [Remainder] string mode = null)
{ {
if (string.IsNullOrWhiteSpace(usr)) if (string.IsNullOrWhiteSpace(usr))
return; return;
using (HttpClient http = new HttpClient()) using (var http = new HttpClient())
{ {
try try
{ {
@ -42,15 +35,15 @@ namespace NadekoBot.Modules.Searches
http.AddFakeHeaders(); http.AddFakeHeaders();
var res = await http.GetStreamAsync(new Uri($"http://lemmmy.pw/osusig/sig.php?uname={ usr }&flagshadow&xpbar&xpbarhex&pp=2&mode={m}")).ConfigureAwait(false); var res = await http.GetStreamAsync(new Uri($"http://lemmmy.pw/osusig/sig.php?uname={ usr }&flagshadow&xpbar&xpbarhex&pp=2&mode={m}")).ConfigureAwait(false);
MemoryStream ms = new MemoryStream(); var ms = new MemoryStream();
res.CopyTo(ms); res.CopyTo(ms);
ms.Position = 0; ms.Position = 0;
await Context.Channel.SendFileAsync(ms, $"{usr}.png", $"🎧 **Profile Link:** <https://new.ppy.sh/u/{Uri.EscapeDataString(usr)}>\n`Image provided by https://lemmmy.pw/osusig`").ConfigureAwait(false); await Context.Channel.SendFileAsync(ms, $"{usr}.png", $"🎧 **{GetText("profile_link")}** <https://new.ppy.sh/u/{Uri.EscapeDataString(usr)}>\n`Image provided by https://lemmmy.pw/osusig`").ConfigureAwait(false);
} }
catch (Exception ex) catch (Exception ex)
{ {
await Context.Channel.SendErrorAsync("Failed retrieving osu signature.").ConfigureAwait(false); await ReplyErrorLocalized("osu_failed").ConfigureAwait(false);
_log.Warn(ex, "Osu command failed"); _log.Warn(ex);
} }
} }
} }
@ -60,7 +53,7 @@ namespace NadekoBot.Modules.Searches
{ {
if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.OsuApiKey)) if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.OsuApiKey))
{ {
await Context.Channel.SendErrorAsync("An osu! API key is required.").ConfigureAwait(false); await ReplyErrorLocalized("osu_api_key").ConfigureAwait(false);
return; return;
} }
@ -75,8 +68,8 @@ namespace NadekoBot.Modules.Searches
var reqString = $"https://osu.ppy.sh/api/get_beatmaps?k={NadekoBot.Credentials.OsuApiKey}&{mapId}"; var reqString = $"https://osu.ppy.sh/api/get_beatmaps?k={NadekoBot.Credentials.OsuApiKey}&{mapId}";
var obj = JArray.Parse(await http.GetStringAsync(reqString).ConfigureAwait(false))[0]; var obj = JArray.Parse(await http.GetStringAsync(reqString).ConfigureAwait(false))[0];
var sb = new System.Text.StringBuilder(); var sb = new System.Text.StringBuilder();
var starRating = Math.Round(Double.Parse($"{obj["difficultyrating"]}", CultureInfo.InvariantCulture), 2); var starRating = Math.Round(double.Parse($"{obj["difficultyrating"]}", CultureInfo.InvariantCulture), 2);
var time = TimeSpan.FromSeconds(Double.Parse($"{obj["total_length"]}")).ToString(@"mm\:ss"); var time = TimeSpan.FromSeconds(double.Parse($"{obj["total_length"]}")).ToString(@"mm\:ss");
sb.AppendLine($"{obj["artist"]} - {obj["title"]}, mapped by {obj["creator"]}. https://osu.ppy.sh/s/{obj["beatmapset_id"]}"); sb.AppendLine($"{obj["artist"]} - {obj["title"]}, mapped by {obj["creator"]}. https://osu.ppy.sh/s/{obj["beatmapset_id"]}");
sb.AppendLine($"{starRating} stars, {obj["bpm"]} BPM | AR{obj["diff_approach"]}, CS{obj["diff_size"]}, OD{obj["diff_overall"]} | Length: {time}"); sb.AppendLine($"{starRating} stars, {obj["bpm"]} BPM | AR{obj["diff_approach"]}, CS{obj["diff_size"]}, OD{obj["diff_overall"]} | Length: {time}");
await Context.Channel.SendMessageAsync(sb.ToString()).ConfigureAwait(false); await Context.Channel.SendMessageAsync(sb.ToString()).ConfigureAwait(false);
@ -84,8 +77,8 @@ namespace NadekoBot.Modules.Searches
} }
catch (Exception ex) catch (Exception ex)
{ {
await Context.Channel.SendErrorAsync("Something went wrong."); await ReplyErrorLocalized("something_went_wrong").ConfigureAwait(false);
_log.Warn(ex, "Osub command failed"); _log.Warn(ex);
} }
} }
@ -121,54 +114,53 @@ namespace NadekoBot.Modules.Searches
{ {
var mapReqString = $"https://osu.ppy.sh/api/get_beatmaps?k={NadekoBot.Credentials.OsuApiKey}&b={item["beatmap_id"]}"; var mapReqString = $"https://osu.ppy.sh/api/get_beatmaps?k={NadekoBot.Credentials.OsuApiKey}&b={item["beatmap_id"]}";
var map = JArray.Parse(await http.GetStringAsync(mapReqString).ConfigureAwait(false))[0]; var map = JArray.Parse(await http.GetStringAsync(mapReqString).ConfigureAwait(false))[0];
var pp = Math.Round(Double.Parse($"{item["pp"]}", CultureInfo.InvariantCulture), 2); var pp = Math.Round(double.Parse($"{item["pp"]}", CultureInfo.InvariantCulture), 2);
var acc = CalculateAcc(item, m); var acc = CalculateAcc(item, m);
var mods = ResolveMods(Int32.Parse($"{item["enabled_mods"]}")); var mods = ResolveMods(int.Parse($"{item["enabled_mods"]}"));
if (mods != "+") sb.AppendLine(mods != "+"
sb.AppendLine($"{pp + "pp",-7} | {acc + "%",-7} | {map["artist"] + "-" + map["title"] + " (" + map["version"] + ")",-40} | **{mods,-10}** | /b/{item["beatmap_id"]}"); ? $"{pp + "pp",-7} | {acc + "%",-7} | {map["artist"] + "-" + map["title"] + " (" + map["version"] + ")",-40} | **{mods,-10}** | /b/{item["beatmap_id"]}"
else : $"{pp + "pp",-7} | {acc + "%",-7} | {map["artist"] + "-" + map["title"] + " (" + map["version"] + ")",-40} | /b/{item["beatmap_id"]}");
sb.AppendLine($"{pp + "pp",-7} | {acc + "%",-7} | {map["artist"] + "-" + map["title"] + " (" + map["version"] + ")",-40} | /b/{item["beatmap_id"]}");
} }
sb.Append("```"); sb.Append("```");
await channel.SendMessageAsync(sb.ToString()).ConfigureAwait(false); await channel.SendMessageAsync(sb.ToString()).ConfigureAwait(false);
} }
catch (Exception ex) catch (Exception ex)
{ {
await channel.SendErrorAsync("Something went wrong."); await ReplyErrorLocalized("something_went_wrong").ConfigureAwait(false);
_log.Warn(ex, "Osu5 command failed"); _log.Warn(ex);
} }
} }
} }
//https://osu.ppy.sh/wiki/Accuracy //https://osu.ppy.sh/wiki/Accuracy
private static Double CalculateAcc(JToken play, int mode) private static double CalculateAcc(JToken play, int mode)
{ {
if (mode == 0) if (mode == 0)
{ {
var hitPoints = Double.Parse($"{play["count50"]}") * 50 + Double.Parse($"{play["count100"]}") * 100 + Double.Parse($"{play["count300"]}") * 300; var hitPoints = double.Parse($"{play["count50"]}") * 50 + double.Parse($"{play["count100"]}") * 100 + double.Parse($"{play["count300"]}") * 300;
var totalHits = Double.Parse($"{play["count50"]}") + Double.Parse($"{play["count100"]}") + Double.Parse($"{play["count300"]}") + Double.Parse($"{play["countmiss"]}"); var totalHits = double.Parse($"{play["count50"]}") + double.Parse($"{play["count100"]}") + double.Parse($"{play["count300"]}") + double.Parse($"{play["countmiss"]}");
totalHits *= 300; totalHits *= 300;
return Math.Round(hitPoints / totalHits * 100, 2); return Math.Round(hitPoints / totalHits * 100, 2);
} }
else if (mode == 1) else if (mode == 1)
{ {
var hitPoints = Double.Parse($"{play["countmiss"]}") * 0 + Double.Parse($"{play["count100"]}") * 0.5 + Double.Parse($"{play["count300"]}") * 1; var hitPoints = double.Parse($"{play["countmiss"]}") * 0 + double.Parse($"{play["count100"]}") * 0.5 + double.Parse($"{play["count300"]}") * 1;
var totalHits = Double.Parse($"{play["countmiss"]}") + Double.Parse($"{play["count100"]}") + Double.Parse($"{play["count300"]}"); var totalHits = double.Parse($"{play["countmiss"]}") + double.Parse($"{play["count100"]}") + double.Parse($"{play["count300"]}");
hitPoints *= 300; hitPoints *= 300;
totalHits *= 300; totalHits *= 300;
return Math.Round(hitPoints / totalHits * 100, 2); return Math.Round(hitPoints / totalHits * 100, 2);
} }
else if (mode == 2) else if (mode == 2)
{ {
var fruitsCaught = Double.Parse($"{play["count50"]}") + Double.Parse($"{play["count100"]}") + Double.Parse($"{play["count300"]}"); var fruitsCaught = double.Parse($"{play["count50"]}") + double.Parse($"{play["count100"]}") + double.Parse($"{play["count300"]}");
var totalFruits = Double.Parse($"{play["countmiss"]}") + Double.Parse($"{play["count50"]}") + Double.Parse($"{play["count100"]}") + Double.Parse($"{play["count300"]}") + Double.Parse($"{play["countkatu"]}"); var totalFruits = double.Parse($"{play["countmiss"]}") + double.Parse($"{play["count50"]}") + double.Parse($"{play["count100"]}") + double.Parse($"{play["count300"]}") + double.Parse($"{play["countkatu"]}");
return Math.Round(fruitsCaught / totalFruits * 100, 2); return Math.Round(fruitsCaught / totalFruits * 100, 2);
} }
else else
{ {
var hitPoints = Double.Parse($"{play["count50"]}") * 50 + Double.Parse($"{play["count100"]}") * 100 + Double.Parse($"{play["countkatu"]}") * 200 + (Double.Parse($"{play["count300"]}") + Double.Parse($"{play["countgeki"]}")) * 300; var hitPoints = double.Parse($"{play["count50"]}") * 50 + double.Parse($"{play["count100"]}") * 100 + double.Parse($"{play["countkatu"]}") * 200 + (double.Parse($"{play["count300"]}") + double.Parse($"{play["countgeki"]}")) * 300;
var totalHits = Double.Parse($"{play["countmiss"]}") + Double.Parse($"{play["count50"]}") + Double.Parse($"{play["count100"]}") + Double.Parse($"{play["countkatu"]}") + Double.Parse($"{play["count300"]}") + Double.Parse($"{play["countgeki"]}"); var totalHits = double.Parse($"{play["countmiss"]}") + double.Parse($"{play["count50"]}") + double.Parse($"{play["count100"]}") + double.Parse($"{play["countkatu"]}") + double.Parse($"{play["count300"]}") + double.Parse($"{play["countgeki"]}");
totalHits *= 300; totalHits *= 300;
return Math.Round(hitPoints / totalHits * 100, 2); return Math.Round(hitPoints / totalHits * 100, 2);
} }
@ -176,10 +168,10 @@ namespace NadekoBot.Modules.Searches
private static string ResolveMap(string mapLink) private static string ResolveMap(string mapLink)
{ {
Match s = new Regex(@"osu.ppy.sh\/s\/", RegexOptions.IgnoreCase).Match(mapLink); var s = new Regex(@"osu.ppy.sh\/s\/", RegexOptions.IgnoreCase).Match(mapLink);
Match b = new Regex(@"osu.ppy.sh\/b\/", RegexOptions.IgnoreCase).Match(mapLink); var b = new Regex(@"osu.ppy.sh\/b\/", RegexOptions.IgnoreCase).Match(mapLink);
Match p = new Regex(@"osu.ppy.sh\/p\/", RegexOptions.IgnoreCase).Match(mapLink); var p = new Regex(@"osu.ppy.sh\/p\/", RegexOptions.IgnoreCase).Match(mapLink);
Match m = new Regex(@"&m=", RegexOptions.IgnoreCase).Match(mapLink); var m = new Regex(@"&m=", RegexOptions.IgnoreCase).Match(mapLink);
if (s.Success) if (s.Success)
{ {
var mapId = mapLink.Substring(mapLink.IndexOf("/s/") + 3); var mapId = mapLink.Substring(mapLink.IndexOf("/s/") + 3);

View File

@ -4,7 +4,6 @@ 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;
@ -14,13 +13,8 @@ namespace NadekoBot.Modules.Searches
public partial class Searches public partial class Searches
{ {
[Group] [Group]
public class OverwatchCommands : ModuleBase public class OverwatchCommands : NadekoSubmodule
{ {
private readonly Logger _log;
public OverwatchCommands()
{
_log = LogManager.GetCurrentClassLogger();
}
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
public async Task Overwatch(string region, [Remainder] string query = null) public async Task Overwatch(string region, [Remainder] string query = null)
{ {
@ -34,9 +28,9 @@ namespace NadekoBot.Modules.Searches
await Context.Channel.TriggerTypingAsync().ConfigureAwait(false); await Context.Channel.TriggerTypingAsync().ConfigureAwait(false);
var model = await GetProfile(region, battletag); var model = await GetProfile(region, battletag);
var rankimg = $"{model.Competitive.rank_img}"; var rankimg = model.Competitive.rank_img;
var rank = $"{model.Competitive.rank}"; var rank = model.Competitive.rank;
//var competitiveplay = $"{model.Games.Competitive.played}";
if (string.IsNullOrWhiteSpace(rank)) if (string.IsNullOrWhiteSpace(rank))
{ {
var embed = new EmbedBuilder() var embed = new EmbedBuilder()
@ -44,10 +38,10 @@ namespace NadekoBot.Modules.Searches
.WithUrl($"https://www.overbuff.com/players/pc/{battletag}") .WithUrl($"https://www.overbuff.com/players/pc/{battletag}")
.WithIconUrl($"{model.avatar}")) .WithIconUrl($"{model.avatar}"))
.WithThumbnailUrl("https://cdn.discordapp.com/attachments/155726317222887425/255653487512256512/YZ4w2ey.png") .WithThumbnailUrl("https://cdn.discordapp.com/attachments/155726317222887425/255653487512256512/YZ4w2ey.png")
.AddField(fb => fb.WithName("**Level**").WithValue($"{model.level}").WithIsInline(true)) .AddField(fb => fb.WithName(GetText("level")).WithValue($"{model.level}").WithIsInline(true))
.AddField(fb => fb.WithName("**Quick Wins**").WithValue($"{model.Games.Quick.wins}").WithIsInline(true)) .AddField(fb => fb.WithName(GetText("quick_wins")).WithValue($"{model.Games.Quick.wins}").WithIsInline(true))
.AddField(fb => fb.WithName("**Competitive Rank**").WithValue("0").WithIsInline(true)) .AddField(fb => fb.WithName(GetText("compet_rank")).WithValue("0").WithIsInline(true))
.AddField(fb => fb.WithName("**Quick Playtime**").WithValue($"{model.Playtime.quick}").WithIsInline(true)) .AddField(fb => fb.WithName(GetText("quick_playtime")).WithValue($"{model.Playtime.quick}").WithIsInline(true))
.WithOkColor(); .WithOkColor();
await Context.Channel.EmbedAsync(embed).ConfigureAwait(false); await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
} }
@ -58,22 +52,21 @@ namespace NadekoBot.Modules.Searches
.WithUrl($"https://www.overbuff.com/players/pc/{battletag}") .WithUrl($"https://www.overbuff.com/players/pc/{battletag}")
.WithIconUrl($"{model.avatar}")) .WithIconUrl($"{model.avatar}"))
.WithThumbnailUrl(rankimg) .WithThumbnailUrl(rankimg)
.AddField(fb => fb.WithName("**Level**").WithValue($"{model.level}").WithIsInline(true)) .AddField(fb => fb.WithName(GetText("level")).WithValue($"{model.level}").WithIsInline(true))
.AddField(fb => fb.WithName("**Quick Wins**").WithValue($"{model.Games.Quick.wins}").WithIsInline(true)) .AddField(fb => fb.WithName(GetText("quick_wins")).WithValue($"{model.Games.Quick.wins}").WithIsInline(true))
.AddField(fb => fb.WithName("**Competitive Wins**").WithValue($"{model.Games.Competitive.wins}").WithIsInline(true)) .AddField(fb => fb.WithName(GetText("compet_wins")).WithValue($"{model.Games.Competitive.wins}").WithIsInline(true))
.AddField(fb => fb.WithName("**Competitive Loses**").WithValue($"{model.Games.Competitive.lost}").WithIsInline(true)) .AddField(fb => fb.WithName(GetText("compet_losses")).WithValue($"{model.Games.Competitive.lost}").WithIsInline(true))
.AddField(fb => fb.WithName("**Competitive Played**").WithValue($"{model.Games.Competitive.played}").WithIsInline(true)) .AddField(fb => fb.WithName(GetText("compet_played")).WithValue($"{model.Games.Competitive.played}").WithIsInline(true))
.AddField(fb => fb.WithName("**Competitive Rank**").WithValue(rank).WithIsInline(true)) .AddField(fb => fb.WithName(GetText("compet_rank")).WithValue(rank).WithIsInline(true))
.AddField(fb => fb.WithName("**Competitive Playtime**").WithValue($"{model.Playtime.competitive}").WithIsInline(true)) .AddField(fb => fb.WithName(GetText("compet_played")).WithValue($"{model.Playtime.competitive}").WithIsInline(true))
.AddField(fb => fb.WithName("**Quick Playtime**").WithValue($"{model.Playtime.quick}").WithIsInline(true)) .AddField(fb => fb.WithName(GetText("quick_playtime")).WithValue($"{model.Playtime.quick}").WithIsInline(true))
.WithColor(NadekoBot.OkColor); .WithColor(NadekoBot.OkColor);
await Context.Channel.EmbedAsync(embed).ConfigureAwait(false); await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
return;
} }
} }
catch catch
{ {
await Context.Channel.SendErrorAsync("Found no user! Please check the **Region** and **BattleTag** before trying again."); await ReplyErrorLocalized("ow_user_not_found").ConfigureAwait(false);
} }
} }
public async Task<OverwatchApiModel.OverwatchPlayer.Data> GetProfile(string region, string battletag) public async Task<OverwatchApiModel.OverwatchPlayer.Data> GetProfile(string region, string battletag)
@ -82,8 +75,8 @@ namespace NadekoBot.Modules.Searches
{ {
using (var http = new HttpClient()) using (var http = new HttpClient())
{ {
var Url = await http.GetStringAsync($"https://api.lootbox.eu/pc/{region.ToLower()}/{battletag}/profile"); var url = await http.GetStringAsync($"https://api.lootbox.eu/pc/{region.ToLower()}/{battletag}/profile");
var model = JsonConvert.DeserializeObject<OverwatchApiModel.OverwatchPlayer>(Url); var model = JsonConvert.DeserializeObject<OverwatchApiModel.OverwatchPlayer>(url);
return model.data; return model.data;
} }
} }

View File

@ -10,10 +10,9 @@ namespace NadekoBot.Modules.Searches
public partial class Searches public partial class Searches
{ {
[Group] [Group]
public class PlaceCommands : ModuleBase public class PlaceCommands : NadekoSubmodule
{ {
private static string typesStr { get; } = private static string typesStr { get; } = string.Join(", ", Enum.GetNames(typeof(PlaceType)));
string.Format("`List of \"{0}place\" tags:`\n", NadekoBot.ModulePrefixes[typeof(Searches).Name]) + String.Join(", ", Enum.GetNames(typeof(PlaceType)));
public enum PlaceType public enum PlaceType
{ {
@ -30,14 +29,15 @@ namespace NadekoBot.Modules.Searches
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
public async Task Placelist() public async Task Placelist()
{ {
await Context.Channel.SendConfirmAsync(typesStr) await Context.Channel.SendConfirmAsync(GetText("list_of_place_tags", NadekoBot.ModulePrefixes[typeof(Searches).Name]),
typesStr)
.ConfigureAwait(false); .ConfigureAwait(false);
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
public async Task Place(PlaceType placeType, uint width = 0, uint height = 0) public async Task Place(PlaceType placeType, uint width = 0, uint height = 0)
{ {
string url = ""; var url = "";
switch (placeType) switch (placeType)
{ {
case PlaceType.Cage: case PlaceType.Cage:

View File

@ -6,7 +6,6 @@ using NadekoBot.Modules.Searches.Models;
using Newtonsoft.Json; using Newtonsoft.Json;
using NLog; using NLog;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -16,7 +15,7 @@ namespace NadekoBot.Modules.Searches
public partial class Searches public partial class Searches
{ {
[Group] [Group]
public class PokemonSearchCommands : ModuleBase public class PokemonSearchCommands : NadekoSubmodule
{ {
private static Dictionary<string, SearchPokemon> pokemons { get; } = new Dictionary<string, SearchPokemon>(); private static Dictionary<string, SearchPokemon> pokemons { get; } = new Dictionary<string, SearchPokemon>();
private static Dictionary<string, SearchPokemonAbility> pokemonAbilities { get; } = new Dictionary<string, SearchPokemonAbility>(); private static Dictionary<string, SearchPokemonAbility> pokemonAbilities { get; } = new Dictionary<string, SearchPokemonAbility>();
@ -24,7 +23,7 @@ namespace NadekoBot.Modules.Searches
public const string PokemonAbilitiesFile = "data/pokemon/pokemon_abilities7.json"; public const string PokemonAbilitiesFile = "data/pokemon/pokemon_abilities7.json";
public const string PokemonListFile = "data/pokemon/pokemon_list7.json"; public const string PokemonListFile = "data/pokemon/pokemon_list7.json";
private static Logger _log { get; } private new static readonly Logger _log;
static PokemonSearchCommands() static PokemonSearchCommands()
{ {
@ -57,14 +56,13 @@ namespace NadekoBot.Modules.Searches
await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor() await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor()
.WithTitle(kvp.Key.ToTitleCase()) .WithTitle(kvp.Key.ToTitleCase())
.WithDescription(p.BaseStats.ToString()) .WithDescription(p.BaseStats.ToString())
.AddField(efb => efb.WithName("Types").WithValue(string.Join(",\n", p.Types)).WithIsInline(true)) .AddField(efb => efb.WithName(GetText("types")).WithValue(string.Join(",\n", p.Types)).WithIsInline(true))
.AddField(efb => efb.WithName("Height/Weight").WithValue($"{p.HeightM}m/{p.WeightKg}kg").WithIsInline(true)) .AddField(efb => efb.WithName(GetText("height_weight")).WithValue(GetText("height_weight_val", p.HeightM, p.WeightKg)).WithIsInline(true))
.AddField(efb => efb.WithName("Abilitities").WithValue(string.Join(",\n", p.Abilities.Select(a => a.Value))).WithIsInline(true)) .AddField(efb => efb.WithName(GetText("abilities")).WithValue(string.Join(",\n", p.Abilities.Select(a => a.Value))).WithIsInline(true)));
);
return; return;
} }
} }
await Context.Channel.SendErrorAsync("No pokemon found."); await ReplyErrorLocalized("pokemon_none").ConfigureAwait(false);
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
@ -80,12 +78,12 @@ namespace NadekoBot.Modules.Searches
await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor() await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor()
.WithTitle(kvp.Value.Name) .WithTitle(kvp.Value.Name)
.WithDescription(kvp.Value.Desc) .WithDescription(kvp.Value.Desc)
.AddField(efb => efb.WithName("Rating").WithValue(kvp.Value.Rating.ToString()).WithIsInline(true)) .AddField(efb => efb.WithName(GetText("rating")).WithValue(kvp.Value.Rating.ToString(_cultureInfo)).WithIsInline(true))
).ConfigureAwait(false); ).ConfigureAwait(false);
return; return;
} }
} }
await Context.Channel.SendErrorAsync("No ability found."); await ReplyErrorLocalized("pokemon_ability_none").ConfigureAwait(false);
} }
} }
} }

View File

@ -12,9 +12,7 @@ using System.Net.Http;
using NadekoBot.Attributes; using NadekoBot.Attributes;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json; using Newtonsoft.Json;
using NLog;
using NadekoBot.Extensions; using NadekoBot.Extensions;
using System.Diagnostics;
namespace NadekoBot.Modules.Searches namespace NadekoBot.Modules.Searches
{ {
@ -65,23 +63,19 @@ namespace NadekoBot.Modules.Searches
} }
[Group] [Group]
public class StreamNotificationCommands : ModuleBase public class StreamNotificationCommands : NadekoSubmodule
{ {
private static Timer checkTimer { get; } private static readonly Timer _checkTimer;
private static ConcurrentDictionary<string, StreamStatus> oldCachedStatuses = new ConcurrentDictionary<string, StreamStatus>(); private static readonly ConcurrentDictionary<string, StreamStatus> _cachedStatuses = new ConcurrentDictionary<string, StreamStatus>();
private static ConcurrentDictionary<string, StreamStatus> cachedStatuses = new ConcurrentDictionary<string, StreamStatus>();
private static Logger _log { get; }
private static bool FirstPass { get; set; } = true; private static bool firstPass { get; set; } = true;
static StreamNotificationCommands() static StreamNotificationCommands()
{ {
_log = LogManager.GetCurrentClassLogger(); _checkTimer = new Timer(async (state) =>
checkTimer = new Timer(async (state) =>
{ {
oldCachedStatuses = new ConcurrentDictionary<string, StreamStatus>(cachedStatuses); var oldCachedStatuses = new ConcurrentDictionary<string, StreamStatus>(_cachedStatuses);
cachedStatuses.Clear(); _cachedStatuses.Clear();
IEnumerable<FollowedStream> streams; IEnumerable<FollowedStream> streams;
using (var uow = DbHandler.UnitOfWork()) using (var uow = DbHandler.UnitOfWork())
{ {
@ -93,7 +87,7 @@ namespace NadekoBot.Modules.Searches
try try
{ {
var newStatus = await GetStreamStatus(fs).ConfigureAwait(false); var newStatus = await GetStreamStatus(fs).ConfigureAwait(false);
if (FirstPass) if (firstPass)
{ {
return; return;
} }
@ -108,7 +102,7 @@ namespace NadekoBot.Modules.Searches
return; return;
try try
{ {
var msg = await channel.EmbedAsync(fs.GetEmbed(newStatus)).ConfigureAwait(false); await channel.EmbedAsync(fs.GetEmbed(newStatus, channel.Guild.Id)).ConfigureAwait(false);
} }
catch catch
{ {
@ -122,7 +116,7 @@ namespace NadekoBot.Modules.Searches
} }
})); }));
FirstPass = false; firstPass = false;
}, null, TimeSpan.Zero, TimeSpan.FromSeconds(60)); }, null, TimeSpan.Zero, TimeSpan.FromSeconds(60));
} }
@ -134,7 +128,7 @@ namespace NadekoBot.Modules.Searches
{ {
case FollowedStream.FollowedStreamType.Hitbox: case FollowedStream.FollowedStreamType.Hitbox:
var hitboxUrl = $"https://api.hitbox.tv/media/status/{stream.Username.ToLowerInvariant()}"; var hitboxUrl = $"https://api.hitbox.tv/media/status/{stream.Username.ToLowerInvariant()}";
if (checkCache && cachedStatuses.TryGetValue(hitboxUrl, out result)) if (checkCache && _cachedStatuses.TryGetValue(hitboxUrl, out result))
return result; return result;
using (var http = new HttpClient()) using (var http = new HttpClient())
{ {
@ -149,11 +143,11 @@ namespace NadekoBot.Modules.Searches
ApiLink = hitboxUrl, ApiLink = hitboxUrl,
Views = hbData.Views Views = hbData.Views
}; };
cachedStatuses.AddOrUpdate(hitboxUrl, result, (key, old) => result); _cachedStatuses.AddOrUpdate(hitboxUrl, result, (key, old) => result);
return result; return result;
case FollowedStream.FollowedStreamType.Twitch: case FollowedStream.FollowedStreamType.Twitch:
var twitchUrl = $"https://api.twitch.tv/kraken/streams/{Uri.EscapeUriString(stream.Username.ToLowerInvariant())}?client_id=67w6z9i09xv2uoojdm9l0wsyph4hxo6"; var twitchUrl = $"https://api.twitch.tv/kraken/streams/{Uri.EscapeUriString(stream.Username.ToLowerInvariant())}?client_id=67w6z9i09xv2uoojdm9l0wsyph4hxo6";
if (checkCache && cachedStatuses.TryGetValue(twitchUrl, out result)) if (checkCache && _cachedStatuses.TryGetValue(twitchUrl, out result))
return result; return result;
using (var http = new HttpClient()) using (var http = new HttpClient())
{ {
@ -170,11 +164,11 @@ namespace NadekoBot.Modules.Searches
ApiLink = twitchUrl, ApiLink = twitchUrl,
Views = twData.Stream?.Viewers.ToString() ?? "0" Views = twData.Stream?.Viewers.ToString() ?? "0"
}; };
cachedStatuses.AddOrUpdate(twitchUrl, result, (key, old) => result); _cachedStatuses.AddOrUpdate(twitchUrl, result, (key, old) => result);
return result; return result;
case FollowedStream.FollowedStreamType.Beam: case FollowedStream.FollowedStreamType.Beam:
var beamUrl = $"https://beam.pro/api/v1/channels/{stream.Username.ToLowerInvariant()}"; var beamUrl = $"https://beam.pro/api/v1/channels/{stream.Username.ToLowerInvariant()}";
if (checkCache && cachedStatuses.TryGetValue(beamUrl, out result)) if (checkCache && _cachedStatuses.TryGetValue(beamUrl, out result))
return result; return result;
using (var http = new HttpClient()) using (var http = new HttpClient())
{ {
@ -190,7 +184,7 @@ namespace NadekoBot.Modules.Searches
ApiLink = beamUrl, ApiLink = beamUrl,
Views = bmData.ViewersCurrent.ToString() Views = bmData.ViewersCurrent.ToString()
}; };
cachedStatuses.AddOrUpdate(beamUrl, result, (key, old) => result); _cachedStatuses.AddOrUpdate(beamUrl, result, (key, old) => result);
return result; return result;
default: default:
break; break;
@ -234,17 +228,21 @@ namespace NadekoBot.Modules.Searches
if (!streams.Any()) if (!streams.Any())
{ {
await Context.Channel.SendConfirmAsync("You are not following any streams on this server.").ConfigureAwait(false); await ReplyErrorLocalized("streams_none").ConfigureAwait(false);
return; return;
} }
var text = string.Join("\n", await Task.WhenAll(streams.Select(async snc => var text = string.Join("\n", await Task.WhenAll(streams.Select(async snc =>
{ {
var ch = await Context.Guild.GetTextChannelAsync(snc.ChannelId); var ch = await Context.Guild.GetTextChannelAsync(snc.ChannelId);
return $"`{snc.Username}`'s stream on **{(ch)?.Name}** channel. 【`{snc.Type.ToString()}`】"; return string.Format("{0}'s stream on {1} channel. 【{2}】",
Format.Code(snc.Username),
Format.Bold(ch?.Name ?? "deleted-channel"),
Format.Code(snc.Type.ToString()));
}))); })));
await Context.Channel.SendConfirmAsync($"You are following **{streams.Count()}** streams on this server.\n\n" + text).ConfigureAwait(false); await Context.Channel.SendConfirmAsync(GetText("streams_following", streams.Count()) + "\n\n" + text)
.ConfigureAwait(false);
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
@ -271,10 +269,13 @@ namespace NadekoBot.Modules.Searches
} }
if (!removed) if (!removed)
{ {
await Context.Channel.SendErrorAsync("No such stream.").ConfigureAwait(false); await ReplyErrorLocalized("stream_no").ConfigureAwait(false);
return; return;
} }
await Context.Channel.SendConfirmAsync($"Removed `{username}`'s stream ({type}) from notifications.").ConfigureAwait(false);
await ReplyConfirmLocalized("stream_removed",
Format.Code(username),
type).ConfigureAwait(false);
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
@ -293,20 +294,24 @@ namespace NadekoBot.Modules.Searches
})); }));
if (streamStatus.IsLive) if (streamStatus.IsLive)
{ {
await Context.Channel.SendConfirmAsync($"Streamer {username} is online with {streamStatus.Views} viewers."); await ReplyConfirmLocalized("streamer_online",
username,
streamStatus.Views)
.ConfigureAwait(false);
} }
else else
{ {
await Context.Channel.SendConfirmAsync($"Streamer {username} is offline."); await ReplyConfirmLocalized("streamer_offline",
username).ConfigureAwait(false);
} }
} }
catch catch
{ {
await Context.Channel.SendErrorAsync("No channel found."); await ReplyErrorLocalized("no_channel_found").ConfigureAwait(false);
} }
} }
private static async Task TrackStream(ITextChannel channel, string username, FollowedStream.FollowedStreamType type) private async Task TrackStream(ITextChannel channel, string username, FollowedStream.FollowedStreamType type)
{ {
username = username.ToLowerInvariant().Trim(); username = username.ToLowerInvariant().Trim();
var fs = new FollowedStream var fs = new FollowedStream
@ -324,7 +329,7 @@ namespace NadekoBot.Modules.Searches
} }
catch catch
{ {
await channel.SendErrorAsync("Stream probably doesn't exist.").ConfigureAwait(false); await ReplyErrorLocalized("stream_not_exist").ConfigureAwait(false);
return; return;
} }
@ -335,24 +340,24 @@ namespace NadekoBot.Modules.Searches
.Add(fs); .Add(fs);
await uow.CompleteAsync().ConfigureAwait(false); await uow.CompleteAsync().ConfigureAwait(false);
} }
await channel.EmbedAsync(fs.GetEmbed(status), $"🆗 I will notify this channel when status changes.").ConfigureAwait(false); await channel.EmbedAsync(fs.GetEmbed(status, Context.Guild.Id), GetText("stream_tracked")).ConfigureAwait(false);
} }
} }
} }
public static class FollowedStreamExtensions public static class FollowedStreamExtensions
{ {
public static EmbedBuilder GetEmbed(this FollowedStream fs, Searches.StreamStatus status) public static EmbedBuilder GetEmbed(this FollowedStream fs, Searches.StreamStatus status, ulong guildId)
{ {
var embed = new EmbedBuilder().WithTitle(fs.Username) var embed = new EmbedBuilder().WithTitle(fs.Username)
.WithUrl(fs.GetLink()) .WithUrl(fs.GetLink())
.AddField(efb => efb.WithName("Status") .AddField(efb => efb.WithName(fs.GetText("status"))
.WithValue(status.IsLive ? "Online" : "Offline") .WithValue(status.IsLive ? "Online" : "Offline")
.WithIsInline(true)) .WithIsInline(true))
.AddField(efb => efb.WithName("Viewers") .AddField(efb => efb.WithName(fs.GetText("viewers"))
.WithValue(status.IsLive ? status.Views : "-") .WithValue(status.IsLive ? status.Views : "-")
.WithIsInline(true)) .WithIsInline(true))
.AddField(efb => efb.WithName("Platform") .AddField(efb => efb.WithName(fs.GetText("platform"))
.WithValue(fs.Type.ToString()) .WithValue(fs.Type.ToString())
.WithIsInline(true)) .WithIsInline(true))
.WithColor(status.IsLive ? NadekoBot.OkColor : NadekoBot.ErrorColor); .WithColor(status.IsLive ? NadekoBot.OkColor : NadekoBot.ErrorColor);
@ -360,14 +365,20 @@ namespace NadekoBot.Modules.Searches
return embed; return embed;
} }
public static string GetLink(this FollowedStream fs) { public static string GetText(this FollowedStream fs, string key, params object[] replacements) =>
NadekoTopLevelModule.GetTextStatic(key,
NadekoBot.Localization.GetCultureInfo(fs.GuildId),
typeof(Searches).Name.ToLowerInvariant(),
replacements);
public static string GetLink(this FollowedStream fs)
{
if (fs.Type == FollowedStream.FollowedStreamType.Hitbox) if (fs.Type == FollowedStream.FollowedStreamType.Hitbox)
return $"http://www.hitbox.tv/{fs.Username}/"; return $"http://www.hitbox.tv/{fs.Username}/";
else if (fs.Type == FollowedStream.FollowedStreamType.Twitch) if (fs.Type == FollowedStream.FollowedStreamType.Twitch)
return $"http://www.twitch.tv/{fs.Username}/"; return $"http://www.twitch.tv/{fs.Username}/";
else if (fs.Type == FollowedStream.FollowedStreamType.Beam) if (fs.Type == FollowedStream.FollowedStreamType.Beam)
return $"https://beam.pro/{fs.Username}/"; return $"https://beam.pro/{fs.Username}/";
else
return "??"; return "??";
} }
} }

View File

@ -19,10 +19,10 @@ namespace NadekoBot.Modules.Searches
} }
[Group] [Group]
public class TranslateCommands : ModuleBase public class TranslateCommands : NadekoSubmodule
{ {
private static ConcurrentDictionary<ulong, bool> TranslatedChannels { get; } = new ConcurrentDictionary<ulong, bool>(); private static ConcurrentDictionary<ulong, bool> translatedChannels { get; } = new ConcurrentDictionary<ulong, bool>();
private static ConcurrentDictionary<UserChannelPair, string> UserLanguages { get; } = new ConcurrentDictionary<UserChannelPair, string>(); private static ConcurrentDictionary<UserChannelPair, string> userLanguages { get; } = new ConcurrentDictionary<UserChannelPair, string>();
static TranslateCommands() static TranslateCommands()
{ {
@ -35,7 +35,7 @@ namespace NadekoBot.Modules.Searches
return; return;
bool autoDelete; bool autoDelete;
if (!TranslatedChannels.TryGetValue(umsg.Channel.Id, out autoDelete)) if (!translatedChannels.TryGetValue(umsg.Channel.Id, out autoDelete))
return; return;
var key = new UserChannelPair() var key = new UserChannelPair()
{ {
@ -44,10 +44,10 @@ namespace NadekoBot.Modules.Searches
}; };
string langs; string langs;
if (!UserLanguages.TryGetValue(key, out langs)) if (!userLanguages.TryGetValue(key, out langs))
return; return;
var text = await TranslateInternal(langs, umsg.Resolve(TagHandling.Ignore), true) var text = await TranslateInternal(langs, umsg.Resolve(TagHandling.Ignore))
.ConfigureAwait(false); .ConfigureAwait(false);
if (autoDelete) if (autoDelete)
try { await umsg.DeleteAsync().ConfigureAwait(false); } catch { } try { await umsg.DeleteAsync().ConfigureAwait(false); } catch { }
@ -64,21 +64,21 @@ namespace NadekoBot.Modules.Searches
{ {
await Context.Channel.TriggerTypingAsync().ConfigureAwait(false); await Context.Channel.TriggerTypingAsync().ConfigureAwait(false);
var translation = await TranslateInternal(langs, text); var translation = await TranslateInternal(langs, text);
await Context.Channel.SendConfirmAsync("Translation " + langs, translation).ConfigureAwait(false); await Context.Channel.SendConfirmAsync(GetText("translation") + " " + langs, translation).ConfigureAwait(false);
} }
catch catch
{ {
await Context.Channel.SendErrorAsync("Bad input format, or something went wrong...").ConfigureAwait(false); await ReplyErrorLocalized("bad_input_format").ConfigureAwait(false);
} }
} }
private static async Task<string> TranslateInternal(string langs, [Remainder] string text = null, bool silent = false) private static async Task<string> TranslateInternal(string langs, [Remainder] string text = null)
{ {
var langarr = langs.ToLowerInvariant().Split('>'); var langarr = langs.ToLowerInvariant().Split('>');
if (langarr.Length != 2) if (langarr.Length != 2)
throw new ArgumentException(); throw new ArgumentException();
string from = langarr[0]; var from = langarr[0];
string to = langarr[1]; var to = langarr[1];
text = text?.Trim(); text = text?.Trim();
if (string.IsNullOrWhiteSpace(text)) if (string.IsNullOrWhiteSpace(text))
throw new ArgumentException(); throw new ArgumentException();
@ -101,20 +101,20 @@ namespace NadekoBot.Modules.Searches
if (autoDelete == AutoDeleteAutoTranslate.Del) if (autoDelete == AutoDeleteAutoTranslate.Del)
{ {
TranslatedChannels.AddOrUpdate(channel.Id, true, (key, val) => true); translatedChannels.AddOrUpdate(channel.Id, true, (key, val) => true);
try { await channel.SendConfirmAsync("Started automatic translation of messages on this channel. User messages will be auto-deleted.").ConfigureAwait(false); } catch { } await ReplyConfirmLocalized("atl_ad_started").ConfigureAwait(false);
return; return;
} }
bool throwaway; bool throwaway;
if (TranslatedChannels.TryRemove(channel.Id, out throwaway)) if (translatedChannels.TryRemove(channel.Id, out throwaway))
{ {
try { await channel.SendConfirmAsync("Stopped automatic translation of messages on this channel.").ConfigureAwait(false); } catch { } await ReplyConfirmLocalized("atl_stopped").ConfigureAwait(false);
return; return;
} }
else if (TranslatedChannels.TryAdd(channel.Id, autoDelete == AutoDeleteAutoTranslate.Del)) if (translatedChannels.TryAdd(channel.Id, autoDelete == AutoDeleteAutoTranslate.Del))
{ {
try { await channel.SendConfirmAsync("Started automatic translation of messages on this channel.").ConfigureAwait(false); } catch { } await ReplyConfirmLocalized("atl_started").ConfigureAwait(false);
} }
} }
@ -130,8 +130,8 @@ namespace NadekoBot.Modules.Searches
if (string.IsNullOrWhiteSpace(langs)) if (string.IsNullOrWhiteSpace(langs))
{ {
if (UserLanguages.TryRemove(ucp, out langs)) if (userLanguages.TryRemove(ucp, out langs))
await Context.Channel.SendConfirmAsync($"{Context.User.Mention}'s auto-translate language has been removed.").ConfigureAwait(false); await ReplyConfirmLocalized("atl_removed").ConfigureAwait(false);
return; return;
} }
@ -143,20 +143,20 @@ namespace NadekoBot.Modules.Searches
if (!GoogleTranslator.Instance.Languages.Contains(from) || !GoogleTranslator.Instance.Languages.Contains(to)) if (!GoogleTranslator.Instance.Languages.Contains(from) || !GoogleTranslator.Instance.Languages.Contains(to))
{ {
try { await Context.Channel.SendErrorAsync("Invalid source and/or target language.").ConfigureAwait(false); } catch { } await ReplyErrorLocalized("invalid_lang").ConfigureAwait(false);
return; return;
} }
UserLanguages.AddOrUpdate(ucp, langs, (key, val) => langs); userLanguages.AddOrUpdate(ucp, langs, (key, val) => langs);
await Context.Channel.SendConfirmAsync($"Your auto-translate language has been set to {from}>{to}").ConfigureAwait(false); await ReplyConfirmLocalized("atl_set", from, to).ConfigureAwait(false);
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]
public async Task Translangs() public async Task Translangs()
{ {
await Context.Channel.SendTableAsync(GoogleTranslator.Instance.Languages, str => $"{str,-15}", columns: 3); await Context.Channel.SendTableAsync(GoogleTranslator.Instance.Languages, str => $"{str,-15}", 3);
} }
} }

View File

@ -12,9 +12,9 @@ namespace NadekoBot.Modules.Searches
public partial class Searches public partial class Searches
{ {
[Group] [Group]
public class XkcdCommands : ModuleBase public class XkcdCommands : NadekoSubmodule
{ {
private const string xkcdUrl = "https://xkcd.com"; private const string _xkcdUrl = "https://xkcd.com";
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
[Priority(1)] [Priority(1)]
@ -24,9 +24,9 @@ namespace NadekoBot.Modules.Searches
{ {
using (var http = new HttpClient()) using (var http = new HttpClient())
{ {
var res = await http.GetStringAsync($"{xkcdUrl}/info.0.json").ConfigureAwait(false); var res = await http.GetStringAsync($"{_xkcdUrl}/info.0.json").ConfigureAwait(false);
var comic = JsonConvert.DeserializeObject<XkcdComic>(res); var comic = JsonConvert.DeserializeObject<XkcdComic>(res);
var sent = await Context.Channel.SendMessageAsync($"{Context.User.Mention} " + comic.ToString()) var sent = await Context.Channel.SendMessageAsync($"{Context.User.Mention} " + comic)
.ConfigureAwait(false); .ConfigureAwait(false);
await Task.Delay(10000).ConfigureAwait(false); await Task.Delay(10000).ConfigureAwait(false);
@ -47,14 +47,14 @@ namespace NadekoBot.Modules.Searches
using (var http = new HttpClient()) using (var http = new HttpClient())
{ {
var res = await http.GetStringAsync($"{xkcdUrl}/{num}/info.0.json").ConfigureAwait(false); var res = await http.GetStringAsync($"{_xkcdUrl}/{num}/info.0.json").ConfigureAwait(false);
var comic = JsonConvert.DeserializeObject<XkcdComic>(res); var comic = JsonConvert.DeserializeObject<XkcdComic>(res);
var embed = new EmbedBuilder().WithColor(NadekoBot.OkColor) var embed = new EmbedBuilder().WithColor(NadekoBot.OkColor)
.WithImageUrl(comic.ImageLink) .WithImageUrl(comic.ImageLink)
.WithAuthor(eab => eab.WithName(comic.Title).WithUrl($"{xkcdUrl}/{num}").WithIconUrl("http://xkcd.com/s/919f27.ico")) .WithAuthor(eab => eab.WithName(comic.Title).WithUrl($"{_xkcdUrl}/{num}").WithIconUrl("http://xkcd.com/s/919f27.ico"))
.AddField(efb => efb.WithName("Comic#").WithValue(comic.Num.ToString()).WithIsInline(true)) .AddField(efb => efb.WithName(GetText("comic_number")).WithValue(comic.Num.ToString()).WithIsInline(true))
.AddField(efb => efb.WithName("Date").WithValue($"{comic.Month}/{comic.Year}").WithIsInline(true)); .AddField(efb => efb.WithName(GetText("date")).WithValue($"{comic.Month}/{comic.Year}").WithIsInline(true));
var sent = await Context.Channel.EmbedAsync(embed) var sent = await Context.Channel.EmbedAsync(embed)
.ConfigureAwait(false); .ConfigureAwait(false);
@ -75,9 +75,6 @@ namespace NadekoBot.Modules.Searches
[JsonProperty("img")] [JsonProperty("img")]
public string ImageLink { get; set; } public string ImageLink { get; set; }
public string Alt { get; set; } public string Alt { get; set; }
public override string ToString()
=> $"`Comic:` #{Num} `Title:` {Title} `Date:` {Month}/{Year}\n{ImageLink}";
} }
} }
} }

View File

@ -41,15 +41,15 @@ namespace NadekoBot.Modules.Searches
var data = JsonConvert.DeserializeObject<WeatherData>(response); var data = JsonConvert.DeserializeObject<WeatherData>(response);
var embed = new EmbedBuilder() var embed = new EmbedBuilder()
.AddField(fb => fb.WithName("🌍 **Location**").WithValue(data.name + ", " + data.sys.country).WithIsInline(true)) .AddField(fb => fb.WithName("🌍 " + GetText("location")).WithValue(data.name + ", " + data.sys.country).WithIsInline(true))
.AddField(fb => fb.WithName("📏 **Lat,Long**").WithValue($"{data.coord.lat}, {data.coord.lon}").WithIsInline(true)) .AddField(fb => fb.WithName("📏 " + GetText("latlong")).WithValue($"{data.coord.lat}, {data.coord.lon}").WithIsInline(true))
.AddField(fb => fb.WithName("☁ **Condition**").WithValue(String.Join(", ", data.weather.Select(w => w.main))).WithIsInline(true)) .AddField(fb => fb.WithName("☁ " + GetText("condition")).WithValue(string.Join(", ", data.weather.Select(w => w.main))).WithIsInline(true))
.AddField(fb => fb.WithName("😓 **Humidity**").WithValue($"{data.main.humidity}%").WithIsInline(true)) .AddField(fb => fb.WithName("😓 " + GetText("humidity")).WithValue($"{data.main.humidity}%").WithIsInline(true))
.AddField(fb => fb.WithName("💨 **Wind Speed**").WithValue(data.wind.speed + " km/h").WithIsInline(true)) .AddField(fb => fb.WithName("💨 " + GetText("wind_speed")).WithValue(data.wind.speed + " km/h").WithIsInline(true))
.AddField(fb => fb.WithName("🌡 **Temperature**").WithValue(data.main.temp + "°C").WithIsInline(true)) .AddField(fb => fb.WithName("🌡 " + GetText("temperature")).WithValue(data.main.temp + "°C").WithIsInline(true))
.AddField(fb => fb.WithName("🔆 **Min - Max**").WithValue($"{data.main.temp_min}°C - {data.main.temp_max}°C").WithIsInline(true)) .AddField(fb => fb.WithName("🔆 " + GetText("min_max")).WithValue($"{data.main.temp_min}°C - {data.main.temp_max}°C").WithIsInline(true))
.AddField(fb => fb.WithName("🌄 **Sunrise (utc)**").WithValue($"{data.sys.sunrise.ToUnixTimestamp():HH:mm}").WithIsInline(true)) .AddField(fb => fb.WithName("🌄 " + GetText("sunrise")).WithValue($"{data.sys.sunrise.ToUnixTimestamp():HH:mm}").WithIsInline(true))
.AddField(fb => fb.WithName("🌇 **Sunset (utc)**").WithValue($"{data.sys.sunset.ToUnixTimestamp():HH:mm}").WithIsInline(true)) .AddField(fb => fb.WithName("🌇 " + GetText("sunset")).WithValue($"{data.sys.sunset.ToUnixTimestamp():HH:mm}").WithIsInline(true))
.WithOkColor() .WithOkColor()
.WithFooter(efb => efb.WithText("Powered by http://openweathermap.org")); .WithFooter(efb => efb.WithText("Powered by http://openweathermap.org"));
await Context.Channel.EmbedAsync(embed).ConfigureAwait(false); await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
@ -58,17 +58,15 @@ namespace NadekoBot.Modules.Searches
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
public async Task Youtube([Remainder] string query = null) public async Task Youtube([Remainder] string query = null)
{ {
if (!(await ValidateQuery(Context.Channel, query).ConfigureAwait(false))) return; if (!await ValidateQuery(Context.Channel, query).ConfigureAwait(false)) return;
var result = (await NadekoBot.Google.GetVideosByKeywordsAsync(query, 1)).FirstOrDefault(); var result = (await NadekoBot.Google.GetVideosByKeywordsAsync(query, 1)).FirstOrDefault();
if (string.IsNullOrWhiteSpace(result)) if (string.IsNullOrWhiteSpace(result))
{ {
await Context.Channel.SendErrorAsync("No results found for that query.").ConfigureAwait(false); await ReplyErrorLocalized("no_results").ConfigureAwait(false);
return; return;
} }
await Context.Channel.SendMessageAsync(result).ConfigureAwait(false); await Context.Channel.SendMessageAsync(result).ConfigureAwait(false);
//await Context.Channel.EmbedAsync(new Discord.API.Embed() { Video = new Discord.API.EmbedVideo() { Url = result.Replace("watch?v=", "embed/") }, Color = NadekoBot.OkColor }).ConfigureAwait(false);
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
@ -80,7 +78,7 @@ namespace NadekoBot.Modules.Searches
var movie = await OmdbProvider.FindMovie(query); var movie = await OmdbProvider.FindMovie(query);
if (movie == null) if (movie == null)
{ {
await Context.Channel.SendErrorAsync("Failed to find that movie.").ConfigureAwait(false); await ReplyErrorLocalized("imdb_fail").ConfigureAwait(false);
return; return;
} }
await Context.Channel.EmbedAsync(movie.GetEmbed()).ConfigureAwait(false); await Context.Channel.EmbedAsync(movie.GetEmbed()).ConfigureAwait(false);
@ -120,7 +118,7 @@ namespace NadekoBot.Modules.Searches
var res = await NadekoBot.Google.GetImageAsync(terms).ConfigureAwait(false); var res = await NadekoBot.Google.GetImageAsync(terms).ConfigureAwait(false);
var embed = new EmbedBuilder() var embed = new EmbedBuilder()
.WithOkColor() .WithOkColor()
.WithAuthor(eab => eab.WithName("Image Search For: " + terms.TrimTo(50)) .WithAuthor(eab => eab.WithName(GetText("image_search_for") + " " + terms.TrimTo(50))
.WithUrl("https://www.google.rs/search?q=" + terms + "&source=lnms&tbm=isch") .WithUrl("https://www.google.rs/search?q=" + terms + "&source=lnms&tbm=isch")
.WithIconUrl("http://i.imgur.com/G46fm8J.png")) .WithIconUrl("http://i.imgur.com/G46fm8J.png"))
.WithDescription(res.Link) .WithDescription(res.Link)
@ -172,7 +170,7 @@ namespace NadekoBot.Modules.Searches
var res = await NadekoBot.Google.GetImageAsync(terms, new NadekoRandom().Next(0, 50)).ConfigureAwait(false); var res = await NadekoBot.Google.GetImageAsync(terms, new NadekoRandom().Next(0, 50)).ConfigureAwait(false);
var embed = new EmbedBuilder() var embed = new EmbedBuilder()
.WithOkColor() .WithOkColor()
.WithAuthor(eab => eab.WithName("Image Search For: " + terms.TrimTo(50)) .WithAuthor(eab => eab.WithName(GetText("image_search_for") + " " + terms.TrimTo(50))
.WithUrl("https://www.google.rs/search?q=" + terms + "&source=lnms&tbm=isch") .WithUrl("https://www.google.rs/search?q=" + terms + "&source=lnms&tbm=isch")
.WithIconUrl("http://i.imgur.com/G46fm8J.png")) .WithIconUrl("http://i.imgur.com/G46fm8J.png"))
.WithDescription(res.Link) .WithDescription(res.Link)
@ -203,7 +201,7 @@ namespace NadekoBot.Modules.Searches
var embed = new EmbedBuilder() var embed = new EmbedBuilder()
.WithOkColor() .WithOkColor()
.WithAuthor(eab => eab.WithName("Image Search For: " + terms.TrimTo(50)) .WithAuthor(eab => eab.WithName(GetText("image_search_for") + " " + terms.TrimTo(50))
.WithUrl(fullQueryLink) .WithUrl(fullQueryLink)
.WithIconUrl("http://s.imgur.com/images/logo-1200-630.jpg?")) .WithIconUrl("http://s.imgur.com/images/logo-1200-630.jpg?"))
.WithDescription(source) .WithDescription(source)
@ -233,13 +231,14 @@ namespace NadekoBot.Modules.Searches
if (shortened == arg) if (shortened == arg)
{ {
await Context.Channel.SendErrorAsync("Failed to shorten that url.").ConfigureAwait(false); await ReplyErrorLocalized("shorten_fail").ConfigureAwait(false);
return;
} }
await Context.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(GetText("original_url"))
.WithValue($"<{arg}>")) .WithValue($"<{arg}>"))
.AddField(efb => efb.WithName("Short Url") .AddField(efb => efb.WithName(GetText("short_url"))
.WithValue($"<{shortened}>"))) .WithValue($"<{shortened}>")))
.ConfigureAwait(false); .ConfigureAwait(false);
} }
@ -287,7 +286,7 @@ namespace NadekoBot.Modules.Searches
var embed = new EmbedBuilder() var embed = new EmbedBuilder()
.WithOkColor() .WithOkColor()
.WithAuthor(eab => eab.WithName("Search For: " + terms.TrimTo(50)) .WithAuthor(eab => eab.WithName(GetText("search_for") + " " + terms.TrimTo(50))
.WithUrl(fullQueryLink) .WithUrl(fullQueryLink)
.WithIconUrl("http://i.imgur.com/G46fm8J.png")) .WithIconUrl("http://i.imgur.com/G46fm8J.png"))
.WithTitle(Context.User.ToString()) .WithTitle(Context.User.ToString())
@ -296,25 +295,21 @@ namespace NadekoBot.Modules.Searches
var desc = await Task.WhenAll(results.Select(async res => var desc = await Task.WhenAll(results.Select(async res =>
$"[{Format.Bold(res?.Title)}]({(await NadekoBot.Google.ShortenUrl(res?.Link))})\n{res?.Text}\n\n")) $"[{Format.Bold(res?.Title)}]({(await NadekoBot.Google.ShortenUrl(res?.Link))})\n{res?.Text}\n\n"))
.ConfigureAwait(false); .ConfigureAwait(false);
await Context.Channel.EmbedAsync(embed.WithDescription(String.Concat(desc))).ConfigureAwait(false); await Context.Channel.EmbedAsync(embed.WithDescription(string.Concat(desc))).ConfigureAwait(false);
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
public async Task MagicTheGathering([Remainder] string name = null) public async Task MagicTheGathering([Remainder] string name)
{ {
var arg = name; var arg = name;
if (string.IsNullOrWhiteSpace(arg)) if (string.IsNullOrWhiteSpace(arg))
{
await Context.Channel.SendErrorAsync("Please enter a card name to search for.").ConfigureAwait(false);
return; return;
}
await Context.Channel.TriggerTypingAsync().ConfigureAwait(false); await Context.Channel.TriggerTypingAsync().ConfigureAwait(false);
string response = "";
using (var http = new HttpClient()) using (var http = new HttpClient())
{ {
http.DefaultRequestHeaders.Clear(); http.DefaultRequestHeaders.Clear();
response = await http.GetStringAsync($"https://api.deckbrew.com/mtg/cards?name={Uri.EscapeUriString(arg)}") var response = await http.GetStringAsync($"https://api.deckbrew.com/mtg/cards?name={Uri.EscapeUriString(arg)}")
.ConfigureAwait(false); .ConfigureAwait(false);
try try
{ {
@ -325,49 +320,45 @@ namespace NadekoBot.Modules.Searches
var storeUrl = await NadekoBot.Google.ShortenUrl(item["store_url"].ToString()); var storeUrl = await NadekoBot.Google.ShortenUrl(item["store_url"].ToString());
var cost = item["cost"].ToString(); var cost = item["cost"].ToString();
var desc = item["text"].ToString(); var desc = item["text"].ToString();
var types = String.Join(",\n", item["types"].ToObject<string[]>()); var types = string.Join(",\n", item["types"].ToObject<string[]>());
var img = item["editions"][0]["image_url"].ToString(); var img = item["editions"][0]["image_url"].ToString();
var embed = new EmbedBuilder().WithOkColor() var embed = new EmbedBuilder().WithOkColor()
.WithTitle(item["name"].ToString()) .WithTitle(item["name"].ToString())
.WithDescription(desc) .WithDescription(desc)
.WithImageUrl(img) .WithImageUrl(img)
.AddField(efb => efb.WithName("Store Url").WithValue(storeUrl).WithIsInline(true)) .AddField(efb => efb.WithName(GetText("store_url")).WithValue(storeUrl).WithIsInline(true))
.AddField(efb => efb.WithName("Cost").WithValue(cost).WithIsInline(true)) .AddField(efb => efb.WithName(GetText("cost")).WithValue(cost).WithIsInline(true))
.AddField(efb => efb.WithName("Types").WithValue(types).WithIsInline(true)); .AddField(efb => efb.WithName(GetText("types")).WithValue(types).WithIsInline(true));
//.AddField(efb => efb.WithName("Store Url").WithValue(await NadekoBot.Google.ShortenUrl(items[0]["store_url"].ToString())).WithIsInline(true)); //.AddField(efb => efb.WithName("Store Url").WithValue(await NadekoBot.Google.ShortenUrl(items[0]["store_url"].ToString())).WithIsInline(true));
await Context.Channel.EmbedAsync(embed).ConfigureAwait(false); await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
} }
catch catch
{ {
await Context.Channel.SendErrorAsync($"Error could not find the card '{arg}'.").ConfigureAwait(false); await ReplyErrorLocalized("card_not_found").ConfigureAwait(false);
} }
} }
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
public async Task Hearthstone([Remainder] string name = null) public async Task Hearthstone([Remainder] string name)
{ {
var arg = name; var arg = name;
if (string.IsNullOrWhiteSpace(arg)) if (string.IsNullOrWhiteSpace(arg))
{
await Context.Channel.SendErrorAsync("Please enter a card name to search for.").ConfigureAwait(false);
return; return;
}
if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.MashapeKey)) if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.MashapeKey))
{ {
await Context.Channel.SendErrorAsync("Bot owner didn't specify MashapeApiKey. You can't use this functionality.").ConfigureAwait(false); await ReplyErrorLocalized("mashape_api_missing").ConfigureAwait(false);
return; return;
} }
await Context.Channel.TriggerTypingAsync().ConfigureAwait(false); await Context.Channel.TriggerTypingAsync().ConfigureAwait(false);
string response = "";
using (var http = new HttpClient()) using (var http = new HttpClient())
{ {
http.DefaultRequestHeaders.Clear(); http.DefaultRequestHeaders.Clear();
http.DefaultRequestHeaders.Add("X-Mashape-Key", NadekoBot.Credentials.MashapeKey); http.DefaultRequestHeaders.Add("X-Mashape-Key", NadekoBot.Credentials.MashapeKey);
response = await http.GetStringAsync($"https://omgvamp-hearthstone-v1.p.mashape.com/cards/search/{Uri.EscapeUriString(arg)}") var response = await http.GetStringAsync($"https://omgvamp-hearthstone-v1.p.mashape.com/cards/search/{Uri.EscapeUriString(arg)}")
.ConfigureAwait(false); .ConfigureAwait(false);
try try
{ {
@ -391,7 +382,7 @@ namespace NadekoBot.Modules.Searches
string msg = null; string msg = null;
if (items.Count > 4) if (items.Count > 4)
{ {
msg = "⚠ Found over 4 images. Showing random 4."; msg = GetText("hs_over_x", 4);
} }
var ms = new MemoryStream(); var ms = new MemoryStream();
await Task.Run(() => images.AsEnumerable().Merge().Save(ms)); await Task.Run(() => images.AsEnumerable().Merge().Save(ms));
@ -400,8 +391,8 @@ namespace NadekoBot.Modules.Searches
} }
catch (Exception ex) catch (Exception ex)
{ {
await Context.Channel.SendErrorAsync($"Error occured.").ConfigureAwait(false);
_log.Error(ex); _log.Error(ex);
await ReplyErrorLocalized("error_occured").ConfigureAwait(false);
} }
} }
} }
@ -411,23 +402,20 @@ namespace NadekoBot.Modules.Searches
{ {
if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.MashapeKey)) if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.MashapeKey))
{ {
await Context.Channel.SendErrorAsync("Bot owner didn't specify MashapeApiKey. You can't use this functionality.").ConfigureAwait(false); await ReplyErrorLocalized("mashape_api_missing").ConfigureAwait(false);
return; return;
} }
var arg = query; if (string.IsNullOrWhiteSpace(query))
if (string.IsNullOrWhiteSpace(arg))
{
await Context.Channel.SendErrorAsync("Please enter a sentence.").ConfigureAwait(false);
return; return;
}
await Context.Channel.TriggerTypingAsync().ConfigureAwait(false); await Context.Channel.TriggerTypingAsync().ConfigureAwait(false);
using (var http = new HttpClient()) using (var http = new HttpClient())
{ {
http.DefaultRequestHeaders.Clear(); http.DefaultRequestHeaders.Clear();
http.DefaultRequestHeaders.Add("X-Mashape-Key", NadekoBot.Credentials.MashapeKey); http.DefaultRequestHeaders.Add("X-Mashape-Key", NadekoBot.Credentials.MashapeKey);
http.DefaultRequestHeaders.Add("Accept", "text/plain"); http.DefaultRequestHeaders.Add("Accept", "text/plain");
var res = await http.GetStringAsync($"https://yoda.p.mashape.com/yoda?sentence={Uri.EscapeUriString(arg)}").ConfigureAwait(false); var res = await http.GetStringAsync($"https://yoda.p.mashape.com/yoda?sentence={Uri.EscapeUriString(query)}").ConfigureAwait(false);
try try
{ {
var embed = new EmbedBuilder() var embed = new EmbedBuilder()
@ -439,7 +427,7 @@ namespace NadekoBot.Modules.Searches
} }
catch catch
{ {
await Context.Channel.SendErrorAsync("Failed to yodify your sentence.").ConfigureAwait(false); await ReplyErrorLocalized("yodify_error").ConfigureAwait(false);
} }
} }
} }
@ -449,22 +437,19 @@ namespace NadekoBot.Modules.Searches
{ {
if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.MashapeKey)) if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.MashapeKey))
{ {
await Context.Channel.SendErrorAsync("Bot owner didn't specify MashapeApiKey. You can't use this functionality.").ConfigureAwait(false); await ReplyErrorLocalized("mashape_api_missing").ConfigureAwait(false);
return; return;
} }
var arg = query; if (string.IsNullOrWhiteSpace(query))
if (string.IsNullOrWhiteSpace(arg))
{
await Context.Channel.SendErrorAsync("Please enter a search term.").ConfigureAwait(false);
return; return;
}
await Context.Channel.TriggerTypingAsync().ConfigureAwait(false); await Context.Channel.TriggerTypingAsync().ConfigureAwait(false);
using (var http = new HttpClient()) using (var http = new HttpClient())
{ {
http.DefaultRequestHeaders.Clear(); http.DefaultRequestHeaders.Clear();
http.DefaultRequestHeaders.Add("Accept", "application/json"); http.DefaultRequestHeaders.Add("Accept", "application/json");
var res = await http.GetStringAsync($"http://api.urbandictionary.com/v0/define?term={Uri.EscapeUriString(arg)}").ConfigureAwait(false); var res = await http.GetStringAsync($"http://api.urbandictionary.com/v0/define?term={Uri.EscapeUriString(query)}").ConfigureAwait(false);
try try
{ {
var items = JObject.Parse(res); var items = JObject.Parse(res);
@ -480,7 +465,7 @@ namespace NadekoBot.Modules.Searches
} }
catch catch
{ {
await Context.Channel.SendErrorAsync("Failed finding a definition for that term.").ConfigureAwait(false); await ReplyErrorLocalized("ud_error").ConfigureAwait(false);
} }
} }
} }
@ -507,39 +492,36 @@ namespace NadekoBot.Modules.Searches
definition = ((JArray)JToken.Parse(sense.Definition.ToString())).First.ToString(); definition = ((JArray)JToken.Parse(sense.Definition.ToString())).First.ToString();
var embed = new EmbedBuilder().WithOkColor() var embed = new EmbedBuilder().WithOkColor()
.WithTitle("Define: " + word) .WithTitle(GetText("define") + " " + word)
.WithDescription(definition) .WithDescription(definition)
.WithFooter(efb => efb.WithText(sense.Gramatical_info?.type)); .WithFooter(efb => efb.WithText(sense.Gramatical_info?.type));
if (sense.Examples != null) if (sense.Examples != null)
embed.AddField(efb => efb.WithName("Example").WithValue(sense.Examples.First().text)); embed.AddField(efb => efb.WithName(GetText("example")).WithValue(sense.Examples.First().text));
await Context.Channel.EmbedAsync(embed).ConfigureAwait(false); await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
} }
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
public async Task Hashtag([Remainder] string query = null) public async Task Hashtag([Remainder] string query)
{ {
var arg = query; if (string.IsNullOrWhiteSpace(query))
if (string.IsNullOrWhiteSpace(arg))
{
await Context.Channel.SendErrorAsync("Please enter a search term.").ConfigureAwait(false);
return; return;
}
if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.MashapeKey)) if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.MashapeKey))
{ {
await Context.Channel.SendErrorAsync("Bot owner didn't specify MashapeApiKey. You can't use this functionality.").ConfigureAwait(false); await ReplyErrorLocalized("mashape_api_missing").ConfigureAwait(false);
return; return;
} }
await Context.Channel.TriggerTypingAsync().ConfigureAwait(false); await Context.Channel.TriggerTypingAsync().ConfigureAwait(false);
var res = ""; string res;
using (var http = new HttpClient()) using (var http = new HttpClient())
{ {
http.DefaultRequestHeaders.Clear(); http.DefaultRequestHeaders.Clear();
http.DefaultRequestHeaders.Add("X-Mashape-Key", NadekoBot.Credentials.MashapeKey); http.DefaultRequestHeaders.Add("X-Mashape-Key", NadekoBot.Credentials.MashapeKey);
res = await http.GetStringAsync($"https://tagdef.p.mashape.com/one.{Uri.EscapeUriString(arg)}.json").ConfigureAwait(false); res = await http.GetStringAsync($"https://tagdef.p.mashape.com/one.{Uri.EscapeUriString(query)}.json").ConfigureAwait(false);
} }
try try
@ -558,7 +540,7 @@ namespace NadekoBot.Modules.Searches
} }
catch catch
{ {
await Context.Channel.SendErrorAsync("Failed finding a definition for that tag.").ConfigureAwait(false); await ReplyErrorLocalized("hashtag_error").ConfigureAwait(false);
} }
} }
@ -572,7 +554,7 @@ namespace NadekoBot.Modules.Searches
return; return;
var fact = JObject.Parse(response)["facts"][0].ToString(); var fact = JObject.Parse(response)["facts"][0].ToString();
await Context.Channel.SendConfirmAsync("🐈fact", fact).ConfigureAwait(false); await Context.Channel.SendConfirmAsync("🐈" + GetText("catfact"), fact).ConfigureAwait(false);
} }
} }
@ -609,7 +591,7 @@ namespace NadekoBot.Modules.Searches
var result = await http.GetStringAsync("https://en.wikipedia.org//w/api.php?action=query&format=json&prop=info&redirects=1&formatversion=2&inprop=url&titles=" + Uri.EscapeDataString(query)); var result = await http.GetStringAsync("https://en.wikipedia.org//w/api.php?action=query&format=json&prop=info&redirects=1&formatversion=2&inprop=url&titles=" + Uri.EscapeDataString(query));
var data = JsonConvert.DeserializeObject<WikipediaApiModel>(result); var data = JsonConvert.DeserializeObject<WikipediaApiModel>(result);
if (data.Query.Pages[0].Missing) if (data.Query.Pages[0].Missing)
await Context.Channel.SendErrorAsync("That page could not be found.").ConfigureAwait(false); await ReplyErrorLocalized("wiki_page_not_found").ConfigureAwait(false);
else else
await Context.Channel.SendMessageAsync(data.Query.Pages[0].FullUrl).ConfigureAwait(false); await Context.Channel.SendMessageAsync(data.Query.Pages[0].FullUrl).ConfigureAwait(false);
} }
@ -625,13 +607,11 @@ namespace NadekoBot.Modules.Searches
img.ApplyProcessor(new BackgroundColorProcessor<ImageSharp.Color>(ImageSharp.Color.FromHex(color)), img.Bounds); img.ApplyProcessor(new BackgroundColorProcessor<ImageSharp.Color>(ImageSharp.Color.FromHex(color)), img.Bounds);
await Context.Channel.SendFileAsync(img.ToStream(), $"{color}.png").ConfigureAwait(false); ; await Context.Channel.SendFileAsync(img.ToStream(), $"{color}.png").ConfigureAwait(false);
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
public async Task Videocall([Remainder] params IUser[] users) public async Task Videocall([Remainder] params IUser[] users)
{
try
{ {
var allUsrs = users.Append(Context.User); var allUsrs = users.Append(Context.User);
var allUsrsArray = allUsrs.ToArray(); var allUsrsArray = allUsrs.ToArray();
@ -639,12 +619,7 @@ namespace NadekoBot.Modules.Searches
str += new NadekoRandom().Next(); str += new NadekoRandom().Next();
foreach (var usr in allUsrsArray) foreach (var usr in allUsrsArray)
{ {
await (await (usr as IGuildUser).CreateDMChannelAsync()).SendConfirmAsync(str).ConfigureAwait(false); await (await usr.CreateDMChannelAsync()).SendConfirmAsync(str).ConfigureAwait(false);
}
}
catch (Exception ex)
{
_log.Error(ex);
} }
} }
@ -664,11 +639,11 @@ namespace NadekoBot.Modules.Searches
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
public async Task Wikia(string target, [Remainder] string query = null) public async Task Wikia(string target, [Remainder] string query)
{ {
if (string.IsNullOrWhiteSpace(target) || string.IsNullOrWhiteSpace(query)) if (string.IsNullOrWhiteSpace(target) || string.IsNullOrWhiteSpace(query))
{ {
await Context.Channel.SendErrorAsync("Please enter a target wikia, followed by search query.").ConfigureAwait(false); await ReplyErrorLocalized("wikia_input_error").ConfigureAwait(false);
return; return;
} }
await Context.Channel.TriggerTypingAsync().ConfigureAwait(false); await Context.Channel.TriggerTypingAsync().ConfigureAwait(false);
@ -680,90 +655,87 @@ namespace NadekoBot.Modules.Searches
var res = await http.GetStringAsync($"http://www.{Uri.EscapeUriString(target)}.wikia.com/api/v1/Search/List?query={Uri.EscapeUriString(query)}&limit=25&minArticleQuality=10&batch=1&namespaces=0%2C14").ConfigureAwait(false); var res = await http.GetStringAsync($"http://www.{Uri.EscapeUriString(target)}.wikia.com/api/v1/Search/List?query={Uri.EscapeUriString(query)}&limit=25&minArticleQuality=10&batch=1&namespaces=0%2C14").ConfigureAwait(false);
var items = JObject.Parse(res); var items = JObject.Parse(res);
var found = items["items"][0]; var found = items["items"][0];
var response = $@"`Title:` {found["title"].ToString()} var response = $@"`{GetText("title")}` {found["title"]}
`Quality:` {found["quality"]} `{GetText("quality")}` {found["quality"]}
`URL:` {await NadekoBot.Google.ShortenUrl(found["url"].ToString()).ConfigureAwait(false)}"; `{GetText("url")}:` {await NadekoBot.Google.ShortenUrl(found["url"].ToString()).ConfigureAwait(false)}";
await Context.Channel.SendMessageAsync(response).ConfigureAwait(false); await Context.Channel.SendMessageAsync(response).ConfigureAwait(false);
} }
catch catch
{ {
await Context.Channel.SendErrorAsync($"Failed finding `{query}`.").ConfigureAwait(false); await ReplyErrorLocalized("wikia_error").ConfigureAwait(false);
} }
} }
} }
[NadekoCommand, Usage, Description, Aliases] //[NadekoCommand, Usage, Description, Aliases]
public async Task MCPing([Remainder] string query = null) //public async Task MCPing([Remainder] string query2 = null)
{ //{
var arg = query; // var query = query2;
if (string.IsNullOrWhiteSpace(arg)) // if (string.IsNullOrWhiteSpace(query))
{ // return;
await Context.Channel.SendErrorAsync("💢 Please enter a `ip:port`.").ConfigureAwait(false); // await Context.Channel.TriggerTypingAsync().ConfigureAwait(false);
return; // using (var http = new HttpClient())
} // {
await Context.Channel.TriggerTypingAsync().ConfigureAwait(false); // http.DefaultRequestHeaders.Clear();
using (var http = new HttpClient()) // var ip = query.Split(':')[0];
{ // var port = query.Split(':')[1];
http.DefaultRequestHeaders.Clear(); // var res = await http.GetStringAsync($"https://api.minetools.eu/ping/{Uri.EscapeUriString(ip)}/{Uri.EscapeUriString(port)}").ConfigureAwait(false);
string ip = arg.Split(':')[0]; // try
string port = arg.Split(':')[1]; // {
var res = await http.GetStringAsync($"https://api.minetools.eu/ping/{Uri.EscapeUriString(ip)}/{Uri.EscapeUriString(port)}").ConfigureAwait(false); // var items = JObject.Parse(res);
try // var sb = new StringBuilder();
{ // var ping = (int)Math.Ceiling(double.Parse(items["latency"].ToString()));
var items = JObject.Parse(res); // sb.AppendLine($"`Server:` {query}");
var sb = new StringBuilder(); // sb.AppendLine($"`Version:` {items["version"]["name"]} / Protocol {items["version"]["protocol"]}");
int ping = (int)Math.Ceiling(Double.Parse(items["latency"].ToString())); // sb.AppendLine($"`Description:` {items["description"]}");
sb.AppendLine($"`Server:` {arg}"); // sb.AppendLine($"`Online Players:` {items["players"]["online"]}/{items["players"]["max"]}");
sb.AppendLine($"`Version:` {items["version"]["name"].ToString()} / Protocol {items["version"]["protocol"].ToString()}"); // sb.Append($"`Latency:` {ping}");
sb.AppendLine($"`Description:` {items["description"].ToString()}"); // await Context.Channel.SendMessageAsync(sb.ToString());
sb.AppendLine($"`Online Players:` {items["players"]["online"].ToString()}/{items["players"]["max"].ToString()}"); // }
sb.Append($"`Latency:` {ping}"); // catch
await Context.Channel.SendMessageAsync(sb.ToString()); // {
} // await Context.Channel.SendErrorAsync($"Failed finding `{query}`.").ConfigureAwait(false);
catch // }
{ // }
await Context.Channel.SendErrorAsync($"Failed finding `{arg}`.").ConfigureAwait(false); //}
}
}
}
[NadekoCommand, Usage, Description, Aliases] //[NadekoCommand, Usage, Description, Aliases]
public async Task MCQ([Remainder] string query = null) //public async Task MCQ([Remainder] string query = null)
{ //{
var arg = query; // var arg = query;
if (string.IsNullOrWhiteSpace(arg)) // if (string.IsNullOrWhiteSpace(arg))
{ // {
await Context.Channel.SendErrorAsync("Please enter `ip:port`.").ConfigureAwait(false); // await Context.Channel.SendErrorAsync("Please enter `ip:port`.").ConfigureAwait(false);
return; // return;
} // }
await Context.Channel.TriggerTypingAsync().ConfigureAwait(false); // await Context.Channel.TriggerTypingAsync().ConfigureAwait(false);
using (var http = new HttpClient()) // using (var http = new HttpClient())
{ // {
http.DefaultRequestHeaders.Clear(); // http.DefaultRequestHeaders.Clear();
try // try
{ // {
string ip = arg.Split(':')[0]; // var ip = arg.Split(':')[0];
string port = arg.Split(':')[1]; // var port = arg.Split(':')[1];
var res = await http.GetStringAsync($"https://api.minetools.eu/query/{Uri.EscapeUriString(ip)}/{Uri.EscapeUriString(port)}").ConfigureAwait(false); // var res = await http.GetStringAsync($"https://api.minetools.eu/query/{Uri.EscapeUriString(ip)}/{Uri.EscapeUriString(port)}").ConfigureAwait(false);
var items = JObject.Parse(res); // var items = JObject.Parse(res);
var sb = new StringBuilder(); // var sb = new StringBuilder();
sb.AppendLine($"`Server:` {arg.ToString()} 〘Status: {items["status"]}〙"); // sb.AppendLine($"`Server:` {arg} 〘Status: {items["status"]}〙");
sb.AppendLine($"`Player List (First 5):`"); // sb.AppendLine("`Player List (First 5):`");
foreach (var item in items["Playerlist"].Take(5)) // foreach (var item in items["Playerlist"].Take(5))
{ // {
sb.AppendLine($":rosette: {item}"); // sb.AppendLine($":rosette: {item}");
} // }
sb.AppendLine($"`Online Players:` {items["Players"]} / {items["MaxPlayers"]}"); // sb.AppendLine($"`Online Players:` {items["Players"]} / {items["MaxPlayers"]}");
sb.AppendLine($"`Plugins:` {items["Plugins"]}"); // sb.AppendLine($"`Plugins:` {items["Plugins"]}");
sb.Append($"`Version:` {items["Version"]}"); // sb.Append($"`Version:` {items["Version"]}");
await Context.Channel.SendMessageAsync(sb.ToString()); // await Context.Channel.SendMessageAsync(sb.ToString());
} // }
catch // catch
{ // {
await Context.Channel.SendErrorAsync($"Failed finding server `{arg}`.").ConfigureAwait(false); // await Context.Channel.SendErrorAsync($"Failed finding server `{arg}`.").ConfigureAwait(false);
} // }
} // }
} //}
public enum DapiSearchType public enum DapiSearchType
{ {
@ -774,7 +746,7 @@ namespace NadekoBot.Modules.Searches
Yandere Yandere
} }
public static async Task InternalDapiCommand(IUserMessage umsg, string tag, DapiSearchType type) public async Task InternalDapiCommand(IUserMessage umsg, string tag, DapiSearchType type)
{ {
var channel = umsg.Channel; var channel = umsg.Channel;
@ -783,7 +755,7 @@ namespace NadekoBot.Modules.Searches
var url = await InternalDapiSearch(tag, type).ConfigureAwait(false); var url = await InternalDapiSearch(tag, type).ConfigureAwait(false);
if (url == null) if (url == null)
await channel.SendErrorAsync(umsg.Author.Mention + " No results."); await channel.SendErrorAsync(umsg.Author.Mention + " " + GetText("no_results"));
else else
await channel.EmbedAsync(new EmbedBuilder().WithOkColor() await channel.EmbedAsync(new EmbedBuilder().WithOkColor()
.WithDescription(umsg.Author.Mention + " " + tag) .WithDescription(umsg.Author.Mention + " " + tag)
@ -794,7 +766,7 @@ namespace NadekoBot.Modules.Searches
public static async Task<string> InternalDapiSearch(string tag, DapiSearchType type) public static async Task<string> InternalDapiSearch(string tag, DapiSearchType type)
{ {
tag = tag?.Replace(" ", "_"); tag = tag?.Replace(" ", "_");
string website = ""; var website = "";
switch (type) switch (type)
{ {
case DapiSearchType.Safebooru: case DapiSearchType.Safebooru:
@ -839,10 +811,10 @@ namespace NadekoBot.Modules.Searches
return null; return null;
} }
} }
public static async Task<bool> ValidateQuery(IMessageChannel ch, string query) public async Task<bool> ValidateQuery(IMessageChannel ch, string query)
{ {
if (!string.IsNullOrEmpty(query.Trim())) return true; if (!string.IsNullOrWhiteSpace(query)) return true;
await ch.SendErrorAsync("Please specify search parameters.").ConfigureAwait(false); await ch.SendErrorAsync(GetText("specify_search_params")).ConfigureAwait(false);
return false; return false;
} }
} }

View File

@ -3,4 +3,5 @@
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=modules_005Cgambling_005Ccommands/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=modules_005Cgambling_005Ccommands/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=modules_005Cgames_005Ccommands/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=modules_005Cgames_005Ccommands/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=modules_005Cpermissions_005Ccommands/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=modules_005Cpermissions_005Ccommands/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=modules_005Csearches_005Ccommands/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=modules_005Cutility_005Ccommands/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary> <s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=modules_005Cutility_005Ccommands/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

View File

@ -4073,6 +4073,852 @@ namespace NadekoBot.Resources {
} }
} }
/// <summary>
/// Looks up a localized string similar to Abilities.
/// </summary>
public static string searches_abilities {
get {
return ResourceManager.GetString("searches_abilities", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to No favorite anime yet.
/// </summary>
public static string searches_anime_no_fav {
get {
return ResourceManager.GetString("searches_anime_no_fav", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Started automatic translation of messages on this channel. User messages will be auto-deleted..
/// </summary>
public static string searches_atl_ad_started {
get {
return ResourceManager.GetString("searches_atl_ad_started", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to your auto-translate language has been removed..
/// </summary>
public static string searches_atl_removed {
get {
return ResourceManager.GetString("searches_atl_removed", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Your auto-translate language has been set to {from}&gt;{to}.
/// </summary>
public static string searches_atl_set {
get {
return ResourceManager.GetString("searches_atl_set", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Started automatic translation of messages on this channel..
/// </summary>
public static string searches_atl_started {
get {
return ResourceManager.GetString("searches_atl_started", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Stopped automatic translation of messages on this channel..
/// </summary>
public static string searches_atl_stopped {
get {
return ResourceManager.GetString("searches_atl_stopped", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Bad input format, or something went wrong..
/// </summary>
public static string searches_bad_input_format {
get {
return ResourceManager.GetString("searches_bad_input_format", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Couldn&apos;t find that card..
/// </summary>
public static string searches_card_not_found {
get {
return ResourceManager.GetString("searches_card_not_found", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to fact.
/// </summary>
public static string searches_catfact {
get {
return ResourceManager.GetString("searches_catfact", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Chapters.
/// </summary>
public static string searches_chapters {
get {
return ResourceManager.GetString("searches_chapters", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Comic #.
/// </summary>
public static string searches_comic_number {
get {
return ResourceManager.GetString("searches_comic_number", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Competitive Loses.
/// </summary>
public static string searches_compet_loses {
get {
return ResourceManager.GetString("searches_compet_loses", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Competitive Played.
/// </summary>
public static string searches_compet_played {
get {
return ResourceManager.GetString("searches_compet_played", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Competitive Rank.
/// </summary>
public static string searches_compet_rank {
get {
return ResourceManager.GetString("searches_compet_rank", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Competitive Wins.
/// </summary>
public static string searches_compet_wins {
get {
return ResourceManager.GetString("searches_compet_wins", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Completed.
/// </summary>
public static string searches_completed {
get {
return ResourceManager.GetString("searches_completed", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Condition.
/// </summary>
public static string searches_condition {
get {
return ResourceManager.GetString("searches_condition", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Cost.
/// </summary>
public static string searches_cost {
get {
return ResourceManager.GetString("searches_cost", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Date.
/// </summary>
public static string searches_date {
get {
return ResourceManager.GetString("searches_date", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Define:.
/// </summary>
public static string searches_define {
get {
return ResourceManager.GetString("searches_define", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Dropped.
/// </summary>
public static string searches_dropped {
get {
return ResourceManager.GetString("searches_dropped", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Episodes.
/// </summary>
public static string searches_episodes {
get {
return ResourceManager.GetString("searches_episodes", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Error occured..
/// </summary>
public static string searches_error_occured {
get {
return ResourceManager.GetString("searches_error_occured", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Example.
/// </summary>
public static string searches_example {
get {
return ResourceManager.GetString("searches_example", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Failed finding that animu..
/// </summary>
public static string searches_failed_finding_anime {
get {
return ResourceManager.GetString("searches_failed_finding_anime", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Failed finding that mango..
/// </summary>
public static string searches_failed_finding_manga {
get {
return ResourceManager.GetString("searches_failed_finding_manga", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Genres.
/// </summary>
public static string searches_genres {
get {
return ResourceManager.GetString("searches_genres", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Failed finding a definition for that tag..
/// </summary>
public static string searches_hashtag_error {
get {
return ResourceManager.GetString("searches_hashtag_error", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Height/Weight.
/// </summary>
public static string searches_height_weight {
get {
return ResourceManager.GetString("searches_height_weight", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to {0}m/{1}kg.
/// </summary>
public static string searches_height_weight_val {
get {
return ResourceManager.GetString("searches_height_weight_val", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Humidity.
/// </summary>
public static string searches_humidity {
get {
return ResourceManager.GetString("searches_humidity", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Image Search For:.
/// </summary>
public static string searches_image_search_for {
get {
return ResourceManager.GetString("searches_image_search_for", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Failed to find that movie..
/// </summary>
public static string searches_imdb_fail {
get {
return ResourceManager.GetString("searches_imdb_fail", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Invalid source or target language..
/// </summary>
public static string searches_invalid_lang {
get {
return ResourceManager.GetString("searches_invalid_lang", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Joes not loaded..
/// </summary>
public static string searches_jokes_not_loaded {
get {
return ResourceManager.GetString("searches_jokes_not_loaded", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Lat/Long.
/// </summary>
public static string searches_latlong {
get {
return ResourceManager.GetString("searches_latlong", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Level.
/// </summary>
public static string searches_level {
get {
return ResourceManager.GetString("searches_level", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Lsit of {0}place tags.
/// </summary>
public static string searches_list_of_place_tags {
get {
return ResourceManager.GetString("searches_list_of_place_tags", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Location.
/// </summary>
public static string searches_location {
get {
return ResourceManager.GetString("searches_location", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Magic Items not loaded..
/// </summary>
public static string searches_magicitems_not_loaded {
get {
return ResourceManager.GetString("searches_magicitems_not_loaded", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to {0}&apos;s MAL profile.
/// </summary>
public static string searches_mal_profile {
get {
return ResourceManager.GetString("searches_mal_profile", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Bot owner didn&apos;t specify MashapeApiKey. You can&apos;t use this functionality..
/// </summary>
public static string searches_mashape_api_missing {
get {
return ResourceManager.GetString("searches_mashape_api_missing", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Min/Max.
/// </summary>
public static string searches_min_max {
get {
return ResourceManager.GetString("searches_min_max", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to No channel found..
/// </summary>
public static string searches_no_channel_found {
get {
return ResourceManager.GetString("searches_no_channel_found", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to No results found..
/// </summary>
public static string searches_no_results {
get {
return ResourceManager.GetString("searches_no_results", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to On-Hold.
/// </summary>
public static string searches_on_hold {
get {
return ResourceManager.GetString("searches_on_hold", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Original Url.
/// </summary>
public static string searches_original_url {
get {
return ResourceManager.GetString("searches_original_url", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to An osu! API key is required..
/// </summary>
public static string searches_osu_api_key {
get {
return ResourceManager.GetString("searches_osu_api_key", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Failed retreiving osu signature..
/// </summary>
public static string searches_osu_failed {
get {
return ResourceManager.GetString("searches_osu_failed", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Found over {0} images. Showing random {0}..
/// </summary>
public static string searches_over_x {
get {
return ResourceManager.GetString("searches_over_x", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to User not found! Please check the Region and BattleTag before trying again..
/// </summary>
public static string searches_ow_user_not_found {
get {
return ResourceManager.GetString("searches_ow_user_not_found", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Plan to watch.
/// </summary>
public static string searches_plan_to_watch {
get {
return ResourceManager.GetString("searches_plan_to_watch", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Platform.
/// </summary>
public static string searches_platform {
get {
return ResourceManager.GetString("searches_platform", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to No ability found..
/// </summary>
public static string searches_pokemon_ability_none {
get {
return ResourceManager.GetString("searches_pokemon_ability_none", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to No pokemon found..
/// </summary>
public static string searches_pokemon_none {
get {
return ResourceManager.GetString("searches_pokemon_none", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Profile Link:.
/// </summary>
public static string searches_profile_link {
get {
return ResourceManager.GetString("searches_profile_link", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Quality:.
/// </summary>
public static string searches_quality {
get {
return ResourceManager.GetString("searches_quality", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Quick Playtime.
/// </summary>
public static string searches_quick_playtime {
get {
return ResourceManager.GetString("searches_quick_playtime", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Quick Wins.
/// </summary>
public static string searches_quick_wins {
get {
return ResourceManager.GetString("searches_quick_wins", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Rating.
/// </summary>
public static string searches_rating {
get {
return ResourceManager.GetString("searches_rating", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Score:.
/// </summary>
public static string searches_score {
get {
return ResourceManager.GetString("searches_score", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Search For:.
/// </summary>
public static string searches_search_for {
get {
return ResourceManager.GetString("searches_search_for", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Short Url.
/// </summary>
public static string searches_short_url {
get {
return ResourceManager.GetString("searches_short_url", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Failed to shorten that url..
/// </summary>
public static string searches_shorten_fail {
get {
return ResourceManager.GetString("searches_shorten_fail", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Something went wrong..
/// </summary>
public static string searches_something_went_wrong {
get {
return ResourceManager.GetString("searches_something_went_wrong", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Please specify search parameters..
/// </summary>
public static string searches_specify_search_params {
get {
return ResourceManager.GetString("searches_specify_search_params", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Status.
/// </summary>
public static string searches_status {
get {
return ResourceManager.GetString("searches_status", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Store Url.
/// </summary>
public static string searches_store_url {
get {
return ResourceManager.GetString("searches_store_url", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to No such stream..
/// </summary>
public static string searches_stream_no {
get {
return ResourceManager.GetString("searches_stream_no", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Stream probably doesn&apos;t exist..
/// </summary>
public static string searches_stream_not_exist {
get {
return ResourceManager.GetString("searches_stream_not_exist", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Removed {0}&apos;s stream ({1}) from notifications..
/// </summary>
public static string searches_stream_removed {
get {
return ResourceManager.GetString("searches_stream_removed", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to I will notify this channel when status changes..
/// </summary>
public static string searches_stream_tracked {
get {
return ResourceManager.GetString("searches_stream_tracked", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Streamer {0} is offline..
/// </summary>
public static string searches_streamer_offline {
get {
return ResourceManager.GetString("searches_streamer_offline", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Streamer {0} is online with {1} viewers..
/// </summary>
public static string searches_streamer_online {
get {
return ResourceManager.GetString("searches_streamer_online", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to You are following {0} streams on this server..
/// </summary>
public static string searches_streams_following {
get {
return ResourceManager.GetString("searches_streams_following", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to You are not following any streams on this server..
/// </summary>
public static string searches_streams_none {
get {
return ResourceManager.GetString("searches_streams_none", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Sunrise.
/// </summary>
public static string searches_sunrise {
get {
return ResourceManager.GetString("searches_sunrise", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Sunset.
/// </summary>
public static string searches_sunset {
get {
return ResourceManager.GetString("searches_sunset", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Temperature.
/// </summary>
public static string searches_temperature {
get {
return ResourceManager.GetString("searches_temperature", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Title:.
/// </summary>
public static string searches_title {
get {
return ResourceManager.GetString("searches_title", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Top 3 favorite anime:.
/// </summary>
public static string searches_top_3_fav_anime {
get {
return ResourceManager.GetString("searches_top_3_fav_anime", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Translation:.
/// </summary>
public static string searches_translation {
get {
return ResourceManager.GetString("searches_translation", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Types.
/// </summary>
public static string searches_types {
get {
return ResourceManager.GetString("searches_types", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Failed finding definition for that term..
/// </summary>
public static string searches_ud_error {
get {
return ResourceManager.GetString("searches_ud_error", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Url.
/// </summary>
public static string searches_url {
get {
return ResourceManager.GetString("searches_url", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Viewers.
/// </summary>
public static string searches_viewers {
get {
return ResourceManager.GetString("searches_viewers", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Watching.
/// </summary>
public static string searches_watching {
get {
return ResourceManager.GetString("searches_watching", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Page not found..
/// </summary>
public static string searches_wiki_page_not_found {
get {
return ResourceManager.GetString("searches_wiki_page_not_found", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Failed finding that term on the specified wikia..
/// </summary>
public static string searches_wikia_error {
get {
return ResourceManager.GetString("searches_wikia_error", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Please enter a target wikia, followed by search query..
/// </summary>
public static string searches_wikia_input_error {
get {
return ResourceManager.GetString("searches_wikia_input_error", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Wind Speed.
/// </summary>
public static string searches_wind_speed {
get {
return ResourceManager.GetString("searches_wind_speed", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The {0} most banned champions.
/// </summary>
public static string searches_x_most_banned_champs {
get {
return ResourceManager.GetString("searches_x_most_banned_champs", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Failed to yodify your sentence..
/// </summary>
public static string searches_yodify_error {
get {
return ResourceManager.GetString("searches_yodify_error", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Joined. /// Looks up a localized string similar to Joined.
/// </summary> /// </summary>

View File

@ -1485,6 +1485,289 @@ Don't forget to leave your discord name or id in the message.
<data name="permissions_word_filter_server_on" xml:space="preserve"> <data name="permissions_word_filter_server_on" xml:space="preserve">
<value>Word filtering enabled on this server.</value> <value>Word filtering enabled on this server.</value>
</data> </data>
<data name="searches_abilities" xml:space="preserve">
<value>Abilities</value>
</data>
<data name="searches_anime_no_fav" xml:space="preserve">
<value>No favorite anime yet</value>
</data>
<data name="searches_atl_ad_started" xml:space="preserve">
<value>Started automatic translation of messages on this channel. User messages will be auto-deleted.</value>
</data>
<data name="searches_atl_removed" xml:space="preserve">
<value>your auto-translate language has been removed.</value>
</data>
<data name="searches_atl_set" xml:space="preserve">
<value>Your auto-translate language has been set to {from}&gt;{to}</value>
</data>
<data name="searches_atl_started" xml:space="preserve">
<value>Started automatic translation of messages on this channel.</value>
</data>
<data name="searches_atl_stopped" xml:space="preserve">
<value>Stopped automatic translation of messages on this channel.</value>
</data>
<data name="searches_bad_input_format" xml:space="preserve">
<value>Bad input format, or something went wrong.</value>
</data>
<data name="searches_card_not_found" xml:space="preserve">
<value>Couldn't find that card.</value>
</data>
<data name="searches_catfact" xml:space="preserve">
<value>fact</value>
</data>
<data name="searches_chapters" xml:space="preserve">
<value>Chapters</value>
</data>
<data name="searches_comic_number" xml:space="preserve">
<value>Comic #</value>
</data>
<data name="searches_compet_loses" xml:space="preserve">
<value>Competitive Loses</value>
</data>
<data name="searches_compet_played" xml:space="preserve">
<value>Competitive Played</value>
</data>
<data name="searches_compet_rank" xml:space="preserve">
<value>Competitive Rank</value>
</data>
<data name="searches_compet_wins" xml:space="preserve">
<value>Competitive Wins</value>
</data>
<data name="searches_completed" xml:space="preserve">
<value>Completed</value>
</data>
<data name="searches_condition" xml:space="preserve">
<value>Condition</value>
</data>
<data name="searches_cost" xml:space="preserve">
<value>Cost</value>
</data>
<data name="searches_date" xml:space="preserve">
<value>Date</value>
</data>
<data name="searches_define" xml:space="preserve">
<value>Define:</value>
</data>
<data name="searches_dropped" xml:space="preserve">
<value>Dropped</value>
</data>
<data name="searches_episodes" xml:space="preserve">
<value>Episodes</value>
</data>
<data name="searches_error_occured" xml:space="preserve">
<value>Error occured.</value>
</data>
<data name="searches_example" xml:space="preserve">
<value>Example</value>
</data>
<data name="searches_failed_finding_anime" xml:space="preserve">
<value>Failed finding that animu.</value>
</data>
<data name="searches_failed_finding_manga" xml:space="preserve">
<value>Failed finding that mango.</value>
</data>
<data name="searches_genres" xml:space="preserve">
<value>Genres</value>
</data>
<data name="searches_hashtag_error" xml:space="preserve">
<value>Failed finding a definition for that tag.</value>
</data>
<data name="searches_height_weight" xml:space="preserve">
<value>Height/Weight</value>
</data>
<data name="searches_height_weight_val" xml:space="preserve">
<value>{0}m/{1}kg</value>
</data>
<data name="searches_humidity" xml:space="preserve">
<value>Humidity</value>
</data>
<data name="searches_image_search_for" xml:space="preserve">
<value>Image Search For:</value>
</data>
<data name="searches_imdb_fail" xml:space="preserve">
<value>Failed to find that movie.</value>
</data>
<data name="searches_invalid_lang" xml:space="preserve">
<value>Invalid source or target language.</value>
</data>
<data name="searches_jokes_not_loaded" xml:space="preserve">
<value>Joes not loaded.</value>
</data>
<data name="searches_latlong" xml:space="preserve">
<value>Lat/Long</value>
</data>
<data name="searches_level" xml:space="preserve">
<value>Level</value>
</data>
<data name="searches_list_of_place_tags" xml:space="preserve">
<value>Lsit of {0}place tags</value>
<comment>Don't translate {0}place</comment>
</data>
<data name="searches_location" xml:space="preserve">
<value>Location</value>
</data>
<data name="searches_magicitems_not_loaded" xml:space="preserve">
<value>Magic Items not loaded.</value>
</data>
<data name="searches_mal_profile" xml:space="preserve">
<value>{0}'s MAL profile</value>
</data>
<data name="searches_mashape_api_missing" xml:space="preserve">
<value>Bot owner didn't specify MashapeApiKey. You can't use this functionality.</value>
</data>
<data name="searches_min_max" xml:space="preserve">
<value>Min/Max</value>
</data>
<data name="searches_no_channel_found" xml:space="preserve">
<value>No channel found.</value>
</data>
<data name="searches_no_results" xml:space="preserve">
<value>No results found.</value>
</data>
<data name="searches_on_hold" xml:space="preserve">
<value>On-Hold</value>
</data>
<data name="searches_original_url" xml:space="preserve">
<value>Original Url</value>
</data>
<data name="searches_osu_api_key" xml:space="preserve">
<value>An osu! API key is required.</value>
</data>
<data name="searches_osu_failed" xml:space="preserve">
<value>Failed retreiving osu signature.</value>
</data>
<data name="searches_over_x" xml:space="preserve">
<value>Found over {0} images. Showing random {0}.</value>
</data>
<data name="searches_ow_user_not_found" xml:space="preserve">
<value>User not found! Please check the Region and BattleTag before trying again.</value>
</data>
<data name="searches_plan_to_watch" xml:space="preserve">
<value>Plan to watch</value>
</data>
<data name="searches_platform" xml:space="preserve">
<value>Platform</value>
</data>
<data name="searches_pokemon_ability_none" xml:space="preserve">
<value>No ability found.</value>
</data>
<data name="searches_pokemon_none" xml:space="preserve">
<value>No pokemon found.</value>
</data>
<data name="searches_profile_link" xml:space="preserve">
<value>Profile Link:</value>
</data>
<data name="searches_quality" xml:space="preserve">
<value>Quality:</value>
</data>
<data name="searches_quick_playtime" xml:space="preserve">
<value>Quick Playtime</value>
</data>
<data name="searches_quick_wins" xml:space="preserve">
<value>Quick Wins</value>
</data>
<data name="searches_rating" xml:space="preserve">
<value>Rating</value>
</data>
<data name="searches_score" xml:space="preserve">
<value>Score:</value>
</data>
<data name="searches_search_for" xml:space="preserve">
<value>Search For:</value>
</data>
<data name="searches_shorten_fail" xml:space="preserve">
<value>Failed to shorten that url.</value>
</data>
<data name="searches_short_url" xml:space="preserve">
<value>Short Url</value>
</data>
<data name="searches_something_went_wrong" xml:space="preserve">
<value>Something went wrong.</value>
</data>
<data name="searches_specify_search_params" xml:space="preserve">
<value>Please specify search parameters.</value>
</data>
<data name="searches_status" xml:space="preserve">
<value>Status</value>
</data>
<data name="searches_store_url" xml:space="preserve">
<value>Store Url</value>
</data>
<data name="searches_streamer_offline" xml:space="preserve">
<value>Streamer {0} is offline.</value>
</data>
<data name="searches_streamer_online" xml:space="preserve">
<value>Streamer {0} is online with {1} viewers.</value>
</data>
<data name="searches_streams_following" xml:space="preserve">
<value>You are following {0} streams on this server.</value>
</data>
<data name="searches_streams_none" xml:space="preserve">
<value>You are not following any streams on this server.</value>
</data>
<data name="searches_stream_no" xml:space="preserve">
<value>No such stream.</value>
</data>
<data name="searches_stream_not_exist" xml:space="preserve">
<value>Stream probably doesn't exist.</value>
</data>
<data name="searches_stream_removed" xml:space="preserve">
<value>Removed {0}'s stream ({1}) from notifications.</value>
</data>
<data name="searches_stream_tracked" xml:space="preserve">
<value>I will notify this channel when status changes.</value>
</data>
<data name="searches_sunrise" xml:space="preserve">
<value>Sunrise</value>
</data>
<data name="searches_sunset" xml:space="preserve">
<value>Sunset</value>
</data>
<data name="searches_temperature" xml:space="preserve">
<value>Temperature</value>
</data>
<data name="searches_title" xml:space="preserve">
<value>Title:</value>
</data>
<data name="searches_top_3_fav_anime" xml:space="preserve">
<value>Top 3 favorite anime:</value>
</data>
<data name="searches_translation" xml:space="preserve">
<value>Translation:</value>
</data>
<data name="searches_types" xml:space="preserve">
<value>Types</value>
</data>
<data name="searches_ud_error" xml:space="preserve">
<value>Failed finding definition for that term.</value>
</data>
<data name="searches_url" xml:space="preserve">
<value>Url</value>
</data>
<data name="searches_viewers" xml:space="preserve">
<value>Viewers</value>
</data>
<data name="searches_watching" xml:space="preserve">
<value>Watching</value>
</data>
<data name="searches_wikia_error" xml:space="preserve">
<value>Failed finding that term on the specified wikia.</value>
</data>
<data name="searches_wikia_input_error" xml:space="preserve">
<value>Please enter a target wikia, followed by search query.</value>
</data>
<data name="searches_wiki_page_not_found" xml:space="preserve">
<value>Page not found.</value>
</data>
<data name="searches_wind_speed" xml:space="preserve">
<value>Wind Speed</value>
</data>
<data name="searches_x_most_banned_champs" xml:space="preserve">
<value>The {0} most banned champions</value>
</data>
<data name="searches_yodify_error" xml:space="preserve">
<value>Failed to yodify your sentence.</value>
</data>
<data name="utiliity_joined" xml:space="preserve"> <data name="utiliity_joined" xml:space="preserve">
<value>Joined</value> <value>Joined</value>
</data> </data>