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 NadekoBot.Services;
using System.Net.Http;
using System.Text.RegularExpressions;
using System.Xml.Linq;
using NadekoBot.Extensions;
using System.Xml;
using System.Threading;
@ -20,8 +18,8 @@ namespace NadekoBot.Modules.NSFW
public class NSFW : NadekoTopLevelModule
{
private static readonly ConcurrentDictionary<ulong, Timer> AutoHentaiTimers = new ConcurrentDictionary<ulong, Timer>();
private static readonly ConcurrentHashSet<ulong> HentaiBombBlacklist = new ConcurrentHashSet<ulong>();
private static readonly ConcurrentDictionary<ulong, Timer> _autoHentaiTimers = new ConcurrentDictionary<ulong, Timer>();
private static readonly ConcurrentHashSet<ulong> _hentaiBombBlacklist = new ConcurrentHashSet<ulong>();
private async Task InternalHentai(IMessageChannel channel, string tag, bool noError)
{
@ -72,7 +70,7 @@ namespace NadekoBot.Modules.NSFW
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
await ReplyConfirmLocalized("autohentai_stopped").ConfigureAwait(false);
@ -99,7 +97,7 @@ namespace NadekoBot.Modules.NSFW
}
}, 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);
return t;
@ -114,7 +112,7 @@ namespace NadekoBot.Modules.NSFW
[NadekoCommand, Usage, Description, Aliases]
public async Task HentaiBomb([Remainder] string tag = null)
{
if (!HentaiBombBlacklist.Add(Context.User.Id))
if (!_hentaiBombBlacklist.Add(Context.User.Id))
return;
try
{
@ -138,17 +136,17 @@ namespace NadekoBot.Modules.NSFW
finally
{
await Task.Delay(5000).ConfigureAwait(false);
HentaiBombBlacklist.TryRemove(Context.User.Id);
_hentaiBombBlacklist.TryRemove(Context.User.Id);
}
}
#endif
[NadekoCommand, Usage, Description, Aliases]
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]
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]
public async Task E621([Remainder] string tag = null)
@ -169,7 +167,7 @@ namespace NadekoBot.Modules.NSFW
[NadekoCommand, Usage, Description, Aliases]
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]
public async Task Danbooru([Remainder] string tag = null)
@ -212,7 +210,7 @@ namespace NadekoBot.Modules.NSFW
[NadekoCommand, Usage, Description, Aliases]
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]
public async Task Cp()
@ -289,5 +287,22 @@ namespace NadekoBot.Modules.NSFW
public static Task<string> GetGelbooruImageLink(string tag) =>
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.Dom.Html;
using AngleSharp.Extensions;
using Discord;
using Discord.Commands;
using NadekoBot.Attributes;
@ -8,7 +7,6 @@ using NadekoBot.Extensions;
using NadekoBot.Modules.Searches.Models;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NLog;
using System;
using System.Collections.Generic;
using System.Linq;
@ -21,15 +19,13 @@ namespace NadekoBot.Modules.Searches
public partial class Searches
{
[Group]
public class AnimeSearchCommands : ModuleBase
public class AnimeSearchCommands : NadekoSubmodule
{
private static Timer anilistTokenRefresher { get; }
private static Logger _log { get; }
private static readonly Timer anilistTokenRefresher;
private static string anilistToken { get; set; }
static AnimeSearchCommands()
{
_log = LogManager.GetCurrentClassLogger();
anilistTokenRefresher = new Timer(async (state) =>
{
try
@ -49,9 +45,9 @@ namespace NadekoBot.Modules.Searches
anilistToken = JObject.Parse(stringContent)["access_token"].ToString();
}
}
catch (Exception ex)
catch
{
_log.Error(ex);
// ignored
}
}, 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 favAnime = "No favorite anime yet";
var favAnime = GetText("anime_no_fav");
if (favorites[0].QuerySelector("p") == null)
favAnime = string.Join("\n", favorites[0].QuerySelectorAll("ul > li > div.di-tc.va-t > a")
.Shuffle()
@ -106,14 +102,14 @@ namespace NadekoBot.Modules.Searches
var embed = new EmbedBuilder()
.WithOkColor()
.WithTitle($"{name}'s MAL profile")
.AddField(efb => efb.WithName("💚 Watching").WithValue(stats[0]).WithIsInline(true))
.AddField(efb => efb.WithName("💙 Completed").WithValue(stats[1]).WithIsInline(true));
.WithTitle(GetText("mal_profile", name))
.AddField(efb => efb.WithName("💚 " + GetText("watching")).WithValue(stats[0]).WithIsInline(true))
.AddField(efb => efb.WithName("💙 " + GetText("completed")).WithValue(stats[1]).WithIsInline(true));
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
.AddField(efb => efb.WithName("💔 Dropped").WithValue(stats[3]).WithIsInline(true))
.AddField(efb => efb.WithName("⚪ Plan to watch").WithValue(stats[4]).WithIsInline(true))
.AddField(efb => efb.WithName("💔 " + GetText("dropped")).WithValue(stats[3]).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[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))
@ -126,7 +122,7 @@ namespace NadekoBot.Modules.Searches
.WithDescription($@"
** https://myanimelist.net/animelist/{ name } **
**Top 3 Favorite Anime:**
**{GetText("top_3_fav_anime")}**
{favAnime}"
//**[Manga List](https://myanimelist.net/mangalist/{name})**
@ -176,7 +172,7 @@ namespace NadekoBot.Modules.Searches
if (animeData == null)
{
await Context.Channel.SendErrorAsync("Failed finding that animu.").ConfigureAwait(false);
await ReplyErrorLocalized("failed_finding_anime").ConfigureAwait(false);
return;
}
@ -185,10 +181,10 @@ namespace NadekoBot.Modules.Searches
.WithTitle(animeData.title_english)
.WithUrl(animeData.Link)
.WithImageUrl(animeData.image_url_lge)
.AddField(efb => efb.WithName("Episodes").WithValue(animeData.total_episodes.ToString()).WithIsInline(true))
.AddField(efb => efb.WithName("Status").WithValue(animeData.AiringStatus.ToString()).WithIsInline(true))
.AddField(efb => efb.WithName("Genres").WithValue(String.Join(", ", animeData.Genres)).WithIsInline(true))
.WithFooter(efb => efb.WithText("Score: " + animeData.average_score + " / 100"));
.AddField(efb => efb.WithName(GetText("episodes")).WithValue(animeData.total_episodes.ToString()).WithIsInline(true))
.AddField(efb => efb.WithName(GetText("status")).WithValue(animeData.AiringStatus.ToString()).WithIsInline(true))
.AddField(efb => efb.WithName(GetText("genres")).WithValue(String.Join(",\n", animeData.Genres)).WithIsInline(true))
.WithFooter(efb => efb.WithText(GetText("score") + " " + animeData.average_score + " / 100"));
await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
}
@ -203,7 +199,7 @@ namespace NadekoBot.Modules.Searches
if (mangaData == null)
{
await Context.Channel.SendErrorAsync("Failed finding that mango.").ConfigureAwait(false);
await ReplyErrorLocalized("failed_finding_manga").ConfigureAwait(false);
return;
}
@ -212,10 +208,10 @@ namespace NadekoBot.Modules.Searches
.WithTitle(mangaData.title_english)
.WithUrl(mangaData.Link)
.WithImageUrl(mangaData.image_url_lge)
.AddField(efb => efb.WithName("Episodes").WithValue(mangaData.total_chapters.ToString()).WithIsInline(true))
.AddField(efb => efb.WithName("Status").WithValue(mangaData.publishing_status.ToString()).WithIsInline(true))
.AddField(efb => efb.WithName("Genres").WithValue(String.Join(", ", mangaData.Genres)).WithIsInline(true))
.WithFooter(efb => efb.WithText("Score: " + mangaData.average_score + " / 100"));
.AddField(efb => efb.WithName(GetText("chapters")).WithValue(mangaData.total_chapters.ToString()).WithIsInline(true))
.AddField(efb => efb.WithName(GetText("status")).WithValue(mangaData.publishing_status.ToString()).WithIsInline(true))
.AddField(efb => efb.WithName(GetText("genres")).WithValue(String.Join(",\n", mangaData.Genres)).WithIsInline(true))
.WithFooter(efb => efb.WithText(GetText("score") + " " + mangaData.average_score + " / 100"));
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 IEnumerable<string> Languages => _languageDictionary.Keys.OrderBy(x => x);
private Dictionary<string, string> _languageDictionary;
private readonly Dictionary<string, string> _languageDictionary;
static GoogleTranslator() { }
private GoogleTranslator() {
@ -153,13 +153,13 @@ namespace NadekoBot.Modules.Searches
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(targetLanguage),
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");
text = await http.GetStringAsync(url).ConfigureAwait(false);
@ -170,7 +170,7 @@ namespace NadekoBot.Modules.Searches
private string ConvertToLanguageCode(string language)
{
string mode = string.Empty;
string mode;
_languageDictionary.TryGetValue(language, out mode);
return mode;
}

View File

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

View File

@ -33,7 +33,7 @@ namespace NadekoBot.Modules.Searches
[NadekoCommand, Usage, Description, Aliases]
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
try
{
@ -44,19 +44,20 @@ namespace NadekoBot.Modules.Searches
$"limit={showCount}")
.ConfigureAwait(false))["data"] as JArray;
var dataList = data.Distinct(new ChampionNameComparer()).Take(showCount).ToList();
var eb = new EmbedBuilder().WithOkColor().WithTitle(Format.Underline($"{dataList.Count} most banned champions"));
for (var i = 0; i < dataList.Count; i++)
var eb = new EmbedBuilder().WithOkColor().WithTitle(Format.Underline(GetText("x_most_banned_champs",dataList.Count)));
foreach (var champ in dataList)
{
var champ = dataList[i];
eb.AddField(efb => efb.WithName(champ["name"].ToString()).WithValue(champ["general"]["banRate"] + "%").WithIsInline(true));
var champ1 = champ;
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);
}
}
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,73 +1,79 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using NadekoBot.Attributes;
using System.Net.Http;
using System.Text;
using Discord.Commands;
using NadekoBot.Extensions;
namespace NadekoBot.Modules.Searches
{
public partial class Searches
{
Dictionary<char, string> map = new Dictionary<char, string>();
public Searches()
[Group]
public class MemegenCommands : NadekoSubmodule
{
map.Add('?', "~q");
map.Add('%', "~p");
map.Add('#', "~h");
map.Add('/', "~s");
map.Add(' ', "-");
map.Add('-', "--");
map.Add('_', "__");
map.Add('"', "''");
}
[NadekoCommand, Usage, Description, Aliases]
public async Task Memelist()
{
HttpClientHandler handler = new HttpClientHandler();
handler.AllowAutoRedirect = false;
using (var http = new HttpClient(handler))
private static readonly ImmutableDictionary<char, string> _map = new Dictionary<char, string>()
{
var rawJson = await http.GetStringAsync("https://memegen.link/api/templates/").ConfigureAwait(false);
var data = JsonConvert.DeserializeObject<Dictionary<string, string>>(rawJson)
.Select(kvp => Path.GetFileName(kvp.Value));
{'?', "~q"},
{'%', "~p"},
{'#', "~h"},
{'/', "~s"},
{' ', "-"},
{'-', "--"},
{'_', "__"},
{'"', "''"}
await Context.Channel.SendTableAsync(data, x => $"{x,-17}", 3).ConfigureAwait(false);
}
}
}.ToImmutableDictionary();
[NadekoCommand, Usage, Description, Aliases]
public async Task Memegen(string meme, string topText, string botText)
{
var top = Replace(topText);
var bot = Replace(botText);
await Context.Channel.SendMessageAsync($"http://memegen.link/{meme}/{top}/{bot}.jpg")
.ConfigureAwait(false);
}
private string Replace(string input)
{
StringBuilder sb = new StringBuilder();
string tmp;
foreach (var c in input)
[NadekoCommand, Usage, Description, Aliases]
public async Task Memelist()
{
if (map.TryGetValue(c, out tmp))
sb.Append(tmp);
else
sb.Append(c);
var handler = new HttpClientHandler
{
AllowAutoRedirect = false
};
using (var http = new HttpClient(handler))
{
var rawJson = await http.GetStringAsync("https://memegen.link/api/templates/").ConfigureAwait(false);
var data = JsonConvert.DeserializeObject<Dictionary<string, string>>(rawJson)
.Select(kvp => Path.GetFileName(kvp.Value));
await Context.Channel.SendTableAsync(data, x => $"{x,-17}", 3).ConfigureAwait(false);
}
}
return sb.ToString();
[NadekoCommand, Usage, Description, Aliases]
public async Task Memegen(string meme, string topText, string botText)
{
var top = Replace(topText);
var bot = Replace(botText);
await Context.Channel.SendMessageAsync($"http://memegen.link/{meme}/{top}/{bot}.jpg")
.ConfigureAwait(false);
}
private static string Replace(string input)
{
var sb = new StringBuilder();
foreach (var c in input)
{
string tmp;
if (_map.TryGetValue(c, out tmp))
sb.Append(tmp);
else
sb.Append(c);
}
return sb.ToString();
}
}
}
}
}

View File

@ -3,7 +3,6 @@ using Discord.Commands;
using NadekoBot.Attributes;
using NadekoBot.Extensions;
using Newtonsoft.Json.Linq;
using NLog;
using System;
using System.Globalization;
using System.IO;
@ -16,21 +15,15 @@ namespace NadekoBot.Modules.Searches
public partial class Searches
{
[Group]
public class OsuCommands : ModuleBase
public class OsuCommands : NadekoSubmodule
{
private static Logger _log { get; }
static OsuCommands()
{
_log = LogManager.GetCurrentClassLogger();
}
[NadekoCommand, Usage, Description, Aliases]
public async Task Osu(string usr, [Remainder] string mode = null)
{
if (string.IsNullOrWhiteSpace(usr))
return;
using (HttpClient http = new HttpClient())
using (var http = new HttpClient())
{
try
{
@ -42,15 +35,15 @@ namespace NadekoBot.Modules.Searches
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);
MemoryStream ms = new MemoryStream();
var ms = new MemoryStream();
res.CopyTo(ms);
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)
{
await Context.Channel.SendErrorAsync("Failed retrieving osu signature.").ConfigureAwait(false);
_log.Warn(ex, "Osu command failed");
await ReplyErrorLocalized("osu_failed").ConfigureAwait(false);
_log.Warn(ex);
}
}
}
@ -60,7 +53,7 @@ namespace NadekoBot.Modules.Searches
{
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;
}
@ -75,8 +68,8 @@ namespace NadekoBot.Modules.Searches
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 sb = new System.Text.StringBuilder();
var starRating = Math.Round(Double.Parse($"{obj["difficultyrating"]}", CultureInfo.InvariantCulture), 2);
var time = TimeSpan.FromSeconds(Double.Parse($"{obj["total_length"]}")).ToString(@"mm\:ss");
var starRating = Math.Round(double.Parse($"{obj["difficultyrating"]}", CultureInfo.InvariantCulture), 2);
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($"{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);
@ -84,8 +77,8 @@ namespace NadekoBot.Modules.Searches
}
catch (Exception ex)
{
await Context.Channel.SendErrorAsync("Something went wrong.");
_log.Warn(ex, "Osub command failed");
await ReplyErrorLocalized("something_went_wrong").ConfigureAwait(false);
_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 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 mods = ResolveMods(Int32.Parse($"{item["enabled_mods"]}"));
if (mods != "+")
sb.AppendLine($"{pp + "pp",-7} | {acc + "%",-7} | {map["artist"] + "-" + map["title"] + " (" + map["version"] + ")",-40} | **{mods,-10}** | /b/{item["beatmap_id"]}");
else
sb.AppendLine($"{pp + "pp",-7} | {acc + "%",-7} | {map["artist"] + "-" + map["title"] + " (" + map["version"] + ")",-40} | /b/{item["beatmap_id"]}");
var mods = ResolveMods(int.Parse($"{item["enabled_mods"]}"));
sb.AppendLine(mods != "+"
? $"{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} | /b/{item["beatmap_id"]}");
}
sb.Append("```");
await channel.SendMessageAsync(sb.ToString()).ConfigureAwait(false);
}
catch (Exception ex)
{
await channel.SendErrorAsync("Something went wrong.");
_log.Warn(ex, "Osu5 command failed");
await ReplyErrorLocalized("something_went_wrong").ConfigureAwait(false);
_log.Warn(ex);
}
}
}
//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)
{
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 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"]}");
totalHits *= 300;
return Math.Round(hitPoints / totalHits * 100, 2);
}
else if (mode == 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 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"]}");
hitPoints *= 300;
totalHits *= 300;
return Math.Round(hitPoints / totalHits * 100, 2);
}
else if (mode == 2)
{
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 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"]}");
return Math.Round(fruitsCaught / totalFruits * 100, 2);
}
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 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 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"]}");
totalHits *= 300;
return Math.Round(hitPoints / totalHits * 100, 2);
}
@ -176,10 +168,10 @@ namespace NadekoBot.Modules.Searches
private static string ResolveMap(string mapLink)
{
Match s = new Regex(@"osu.ppy.sh\/s\/", RegexOptions.IgnoreCase).Match(mapLink);
Match b = new Regex(@"osu.ppy.sh\/b\/", RegexOptions.IgnoreCase).Match(mapLink);
Match p = new Regex(@"osu.ppy.sh\/p\/", RegexOptions.IgnoreCase).Match(mapLink);
Match m = new Regex(@"&m=", RegexOptions.IgnoreCase).Match(mapLink);
var s = new Regex(@"osu.ppy.sh\/s\/", RegexOptions.IgnoreCase).Match(mapLink);
var b = new Regex(@"osu.ppy.sh\/b\/", RegexOptions.IgnoreCase).Match(mapLink);
var p = new Regex(@"osu.ppy.sh\/p\/", RegexOptions.IgnoreCase).Match(mapLink);
var m = new Regex(@"&m=", RegexOptions.IgnoreCase).Match(mapLink);
if (s.Success)
{
var mapId = mapLink.Substring(mapLink.IndexOf("/s/") + 3);

View File

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

View File

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

View File

@ -6,7 +6,6 @@ using NadekoBot.Modules.Searches.Models;
using Newtonsoft.Json;
using NLog;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
@ -16,7 +15,7 @@ namespace NadekoBot.Modules.Searches
public partial class Searches
{
[Group]
public class PokemonSearchCommands : ModuleBase
public class PokemonSearchCommands : NadekoSubmodule
{
private static Dictionary<string, SearchPokemon> pokemons { get; } = new Dictionary<string, SearchPokemon>();
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 PokemonListFile = "data/pokemon/pokemon_list7.json";
private static Logger _log { get; }
private new static readonly Logger _log;
static PokemonSearchCommands()
{
@ -57,14 +56,13 @@ namespace NadekoBot.Modules.Searches
await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor()
.WithTitle(kvp.Key.ToTitleCase())
.WithDescription(p.BaseStats.ToString())
.AddField(efb => efb.WithName("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("Abilitities").WithValue(string.Join(",\n", p.Abilities.Select(a => a.Value))).WithIsInline(true))
);
.AddField(efb => efb.WithName(GetText("types")).WithValue(string.Join(",\n", p.Types)).WithIsInline(true))
.AddField(efb => efb.WithName(GetText("height_weight")).WithValue(GetText("height_weight_val", p.HeightM, p.WeightKg)).WithIsInline(true))
.AddField(efb => efb.WithName(GetText("abilities")).WithValue(string.Join(",\n", p.Abilities.Select(a => a.Value))).WithIsInline(true)));
return;
}
}
await Context.Channel.SendErrorAsync("No pokemon found.");
await ReplyErrorLocalized("pokemon_none").ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
@ -80,12 +78,12 @@ namespace NadekoBot.Modules.Searches
await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor()
.WithTitle(kvp.Value.Name)
.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);
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 Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using NLog;
using NadekoBot.Extensions;
using System.Diagnostics;
namespace NadekoBot.Modules.Searches
{
@ -65,23 +63,19 @@ namespace NadekoBot.Modules.Searches
}
[Group]
public class StreamNotificationCommands : ModuleBase
public class StreamNotificationCommands : NadekoSubmodule
{
private static Timer checkTimer { get; }
private static ConcurrentDictionary<string, StreamStatus> oldCachedStatuses = new ConcurrentDictionary<string, StreamStatus>();
private static ConcurrentDictionary<string, StreamStatus> cachedStatuses = new ConcurrentDictionary<string, StreamStatus>();
private static Logger _log { get; }
private static readonly Timer _checkTimer;
private static readonly ConcurrentDictionary<string, StreamStatus> _cachedStatuses = new ConcurrentDictionary<string, StreamStatus>();
private static bool FirstPass { get; set; } = true;
private static bool firstPass { get; set; } = true;
static StreamNotificationCommands()
{
_log = LogManager.GetCurrentClassLogger();
checkTimer = new Timer(async (state) =>
_checkTimer = new Timer(async (state) =>
{
oldCachedStatuses = new ConcurrentDictionary<string, StreamStatus>(cachedStatuses);
cachedStatuses.Clear();
var oldCachedStatuses = new ConcurrentDictionary<string, StreamStatus>(_cachedStatuses);
_cachedStatuses.Clear();
IEnumerable<FollowedStream> streams;
using (var uow = DbHandler.UnitOfWork())
{
@ -93,7 +87,7 @@ namespace NadekoBot.Modules.Searches
try
{
var newStatus = await GetStreamStatus(fs).ConfigureAwait(false);
if (FirstPass)
if (firstPass)
{
return;
}
@ -108,7 +102,7 @@ namespace NadekoBot.Modules.Searches
return;
try
{
var msg = await channel.EmbedAsync(fs.GetEmbed(newStatus)).ConfigureAwait(false);
await channel.EmbedAsync(fs.GetEmbed(newStatus, channel.Guild.Id)).ConfigureAwait(false);
}
catch
{
@ -122,7 +116,7 @@ namespace NadekoBot.Modules.Searches
}
}));
FirstPass = false;
firstPass = false;
}, null, TimeSpan.Zero, TimeSpan.FromSeconds(60));
}
@ -134,7 +128,7 @@ namespace NadekoBot.Modules.Searches
{
case FollowedStream.FollowedStreamType.Hitbox:
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;
using (var http = new HttpClient())
{
@ -149,11 +143,11 @@ namespace NadekoBot.Modules.Searches
ApiLink = hitboxUrl,
Views = hbData.Views
};
cachedStatuses.AddOrUpdate(hitboxUrl, result, (key, old) => result);
_cachedStatuses.AddOrUpdate(hitboxUrl, result, (key, old) => result);
return result;
case FollowedStream.FollowedStreamType.Twitch:
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;
using (var http = new HttpClient())
{
@ -170,11 +164,11 @@ namespace NadekoBot.Modules.Searches
ApiLink = twitchUrl,
Views = twData.Stream?.Viewers.ToString() ?? "0"
};
cachedStatuses.AddOrUpdate(twitchUrl, result, (key, old) => result);
_cachedStatuses.AddOrUpdate(twitchUrl, result, (key, old) => result);
return result;
case FollowedStream.FollowedStreamType.Beam:
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;
using (var http = new HttpClient())
{
@ -190,7 +184,7 @@ namespace NadekoBot.Modules.Searches
ApiLink = beamUrl,
Views = bmData.ViewersCurrent.ToString()
};
cachedStatuses.AddOrUpdate(beamUrl, result, (key, old) => result);
_cachedStatuses.AddOrUpdate(beamUrl, result, (key, old) => result);
return result;
default:
break;
@ -234,17 +228,21 @@ namespace NadekoBot.Modules.Searches
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;
}
var text = string.Join("\n", await Task.WhenAll(streams.Select(async snc =>
{
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]
@ -271,10 +269,13 @@ namespace NadekoBot.Modules.Searches
}
if (!removed)
{
await Context.Channel.SendErrorAsync("No such stream.").ConfigureAwait(false);
await ReplyErrorLocalized("stream_no").ConfigureAwait(false);
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]
@ -293,20 +294,24 @@ namespace NadekoBot.Modules.Searches
}));
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
{
await Context.Channel.SendConfirmAsync($"Streamer {username} is offline.");
await ReplyConfirmLocalized("streamer_offline",
username).ConfigureAwait(false);
}
}
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();
var fs = new FollowedStream
@ -324,7 +329,7 @@ namespace NadekoBot.Modules.Searches
}
catch
{
await channel.SendErrorAsync("Stream probably doesn't exist.").ConfigureAwait(false);
await ReplyErrorLocalized("stream_not_exist").ConfigureAwait(false);
return;
}
@ -335,24 +340,24 @@ namespace NadekoBot.Modules.Searches
.Add(fs);
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 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)
.WithUrl(fs.GetLink())
.AddField(efb => efb.WithName("Status")
.AddField(efb => efb.WithName(fs.GetText("status"))
.WithValue(status.IsLive ? "Online" : "Offline")
.WithIsInline(true))
.AddField(efb => efb.WithName("Viewers")
.AddField(efb => efb.WithName(fs.GetText("viewers"))
.WithValue(status.IsLive ? status.Views : "-")
.WithIsInline(true))
.AddField(efb => efb.WithName("Platform")
.AddField(efb => efb.WithName(fs.GetText("platform"))
.WithValue(fs.Type.ToString())
.WithIsInline(true))
.WithColor(status.IsLive ? NadekoBot.OkColor : NadekoBot.ErrorColor);
@ -360,15 +365,21 @@ namespace NadekoBot.Modules.Searches
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)
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}/";
else if (fs.Type == FollowedStream.FollowedStreamType.Beam)
if (fs.Type == FollowedStream.FollowedStreamType.Beam)
return $"https://beam.pro/{fs.Username}/";
else
return "??";
return "??";
}
}
}

View File

@ -19,10 +19,10 @@ namespace NadekoBot.Modules.Searches
}
[Group]
public class TranslateCommands : ModuleBase
public class TranslateCommands : NadekoSubmodule
{
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<ulong, bool> translatedChannels { get; } = new ConcurrentDictionary<ulong, bool>();
private static ConcurrentDictionary<UserChannelPair, string> userLanguages { get; } = new ConcurrentDictionary<UserChannelPair, string>();
static TranslateCommands()
{
@ -35,7 +35,7 @@ namespace NadekoBot.Modules.Searches
return;
bool autoDelete;
if (!TranslatedChannels.TryGetValue(umsg.Channel.Id, out autoDelete))
if (!translatedChannels.TryGetValue(umsg.Channel.Id, out autoDelete))
return;
var key = new UserChannelPair()
{
@ -44,10 +44,10 @@ namespace NadekoBot.Modules.Searches
};
string langs;
if (!UserLanguages.TryGetValue(key, out langs))
if (!userLanguages.TryGetValue(key, out langs))
return;
var text = await TranslateInternal(langs, umsg.Resolve(TagHandling.Ignore), true)
var text = await TranslateInternal(langs, umsg.Resolve(TagHandling.Ignore))
.ConfigureAwait(false);
if (autoDelete)
try { await umsg.DeleteAsync().ConfigureAwait(false); } catch { }
@ -64,21 +64,21 @@ namespace NadekoBot.Modules.Searches
{
await Context.Channel.TriggerTypingAsync().ConfigureAwait(false);
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
{
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('>');
if (langarr.Length != 2)
throw new ArgumentException();
string from = langarr[0];
string to = langarr[1];
var from = langarr[0];
var to = langarr[1];
text = text?.Trim();
if (string.IsNullOrWhiteSpace(text))
throw new ArgumentException();
@ -101,20 +101,20 @@ namespace NadekoBot.Modules.Searches
if (autoDelete == AutoDeleteAutoTranslate.Del)
{
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 { }
translatedChannels.AddOrUpdate(channel.Id, true, (key, val) => true);
await ReplyConfirmLocalized("atl_ad_started").ConfigureAwait(false);
return;
}
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;
}
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 (UserLanguages.TryRemove(ucp, out langs))
await Context.Channel.SendConfirmAsync($"{Context.User.Mention}'s auto-translate language has been removed.").ConfigureAwait(false);
if (userLanguages.TryRemove(ucp, out langs))
await ReplyConfirmLocalized("atl_removed").ConfigureAwait(false);
return;
}
@ -143,20 +143,20 @@ namespace NadekoBot.Modules.Searches
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;
}
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]
[RequireContext(ContextType.Guild)]
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
{
[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]
[Priority(1)]
@ -24,9 +24,9 @@ namespace NadekoBot.Modules.Searches
{
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 sent = await Context.Channel.SendMessageAsync($"{Context.User.Mention} " + comic.ToString())
var sent = await Context.Channel.SendMessageAsync($"{Context.User.Mention} " + comic)
.ConfigureAwait(false);
await Task.Delay(10000).ConfigureAwait(false);
@ -47,14 +47,14 @@ namespace NadekoBot.Modules.Searches
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 embed = new EmbedBuilder().WithColor(NadekoBot.OkColor)
.WithImageUrl(comic.ImageLink)
.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("Date").WithValue($"{comic.Month}/{comic.Year}").WithIsInline(true));
.WithAuthor(eab => eab.WithName(comic.Title).WithUrl($"{_xkcdUrl}/{num}").WithIconUrl("http://xkcd.com/s/919f27.ico"))
.AddField(efb => efb.WithName(GetText("comic_number")).WithValue(comic.Num.ToString()).WithIsInline(true))
.AddField(efb => efb.WithName(GetText("date")).WithValue($"{comic.Month}/{comic.Year}").WithIsInline(true));
var sent = await Context.Channel.EmbedAsync(embed)
.ConfigureAwait(false);
@ -75,9 +75,6 @@ namespace NadekoBot.Modules.Searches
[JsonProperty("img")]
public string ImageLink { 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 embed = new EmbedBuilder()
.AddField(fb => fb.WithName("🌍 **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("☁ **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("💨 **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("🔆 **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("🌇 **Sunset (utc)**").WithValue($"{data.sys.sunset.ToUnixTimestamp():HH:mm}").WithIsInline(true))
.AddField(fb => fb.WithName("🌍 " + GetText("location")).WithValue(data.name + ", " + data.sys.country).WithIsInline(true))
.AddField(fb => fb.WithName("📏 " + GetText("latlong")).WithValue($"{data.coord.lat}, {data.coord.lon}").WithIsInline(true))
.AddField(fb => fb.WithName("☁ " + GetText("condition")).WithValue(string.Join(", ", data.weather.Select(w => w.main))).WithIsInline(true))
.AddField(fb => fb.WithName("😓 " + GetText("humidity")).WithValue($"{data.main.humidity}%").WithIsInline(true))
.AddField(fb => fb.WithName("💨 " + GetText("wind_speed")).WithValue(data.wind.speed + " km/h").WithIsInline(true))
.AddField(fb => fb.WithName("🌡 " + GetText("temperature")).WithValue(data.main.temp + "°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("🌄 " + GetText("sunrise")).WithValue($"{data.sys.sunrise.ToUnixTimestamp():HH:mm}").WithIsInline(true))
.AddField(fb => fb.WithName("🌇 " + GetText("sunset")).WithValue($"{data.sys.sunset.ToUnixTimestamp():HH:mm}").WithIsInline(true))
.WithOkColor()
.WithFooter(efb => efb.WithText("Powered by http://openweathermap.org"));
await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
@ -58,17 +58,15 @@ namespace NadekoBot.Modules.Searches
[NadekoCommand, Usage, Description, Aliases]
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();
if (string.IsNullOrWhiteSpace(result))
{
await Context.Channel.SendErrorAsync("No results found for that query.").ConfigureAwait(false);
await ReplyErrorLocalized("no_results").ConfigureAwait(false);
return;
}
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]
@ -80,7 +78,7 @@ namespace NadekoBot.Modules.Searches
var movie = await OmdbProvider.FindMovie(query);
if (movie == null)
{
await Context.Channel.SendErrorAsync("Failed to find that movie.").ConfigureAwait(false);
await ReplyErrorLocalized("imdb_fail").ConfigureAwait(false);
return;
}
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 embed = new EmbedBuilder()
.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")
.WithIconUrl("http://i.imgur.com/G46fm8J.png"))
.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 embed = new EmbedBuilder()
.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")
.WithIconUrl("http://i.imgur.com/G46fm8J.png"))
.WithDescription(res.Link)
@ -203,7 +201,7 @@ namespace NadekoBot.Modules.Searches
var embed = new EmbedBuilder()
.WithOkColor()
.WithAuthor(eab => eab.WithName("Image Search For: " + terms.TrimTo(50))
.WithAuthor(eab => eab.WithName(GetText("image_search_for") + " " + terms.TrimTo(50))
.WithUrl(fullQueryLink)
.WithIconUrl("http://s.imgur.com/images/logo-1200-630.jpg?"))
.WithDescription(source)
@ -233,13 +231,14 @@ namespace NadekoBot.Modules.Searches
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)
.AddField(efb => efb.WithName("Original Url")
.AddField(efb => efb.WithName(GetText("original_url"))
.WithValue($"<{arg}>"))
.AddField(efb => efb.WithName("Short Url")
.AddField(efb => efb.WithName(GetText("short_url"))
.WithValue($"<{shortened}>")))
.ConfigureAwait(false);
}
@ -287,7 +286,7 @@ namespace NadekoBot.Modules.Searches
var embed = new EmbedBuilder()
.WithOkColor()
.WithAuthor(eab => eab.WithName("Search For: " + terms.TrimTo(50))
.WithAuthor(eab => eab.WithName(GetText("search_for") + " " + terms.TrimTo(50))
.WithUrl(fullQueryLink)
.WithIconUrl("http://i.imgur.com/G46fm8J.png"))
.WithTitle(Context.User.ToString())
@ -296,26 +295,22 @@ namespace NadekoBot.Modules.Searches
var desc = await Task.WhenAll(results.Select(async res =>
$"[{Format.Bold(res?.Title)}]({(await NadekoBot.Google.ShortenUrl(res?.Link))})\n{res?.Text}\n\n"))
.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]
public async Task MagicTheGathering([Remainder] string name = null)
public async Task MagicTheGathering([Remainder] string name)
{
var arg = name;
if (string.IsNullOrWhiteSpace(arg))
{
await Context.Channel.SendErrorAsync("Please enter a card name to search for.").ConfigureAwait(false);
return;
}
await Context.Channel.TriggerTypingAsync().ConfigureAwait(false);
string response = "";
using (var http = new HttpClient())
{
http.DefaultRequestHeaders.Clear();
response = await http.GetStringAsync($"https://api.deckbrew.com/mtg/cards?name={Uri.EscapeUriString(arg)}")
.ConfigureAwait(false);
var response = await http.GetStringAsync($"https://api.deckbrew.com/mtg/cards?name={Uri.EscapeUriString(arg)}")
.ConfigureAwait(false);
try
{
var items = JArray.Parse(response).ToArray();
@ -325,50 +320,46 @@ namespace NadekoBot.Modules.Searches
var storeUrl = await NadekoBot.Google.ShortenUrl(item["store_url"].ToString());
var cost = item["cost"].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 embed = new EmbedBuilder().WithOkColor()
.WithTitle(item["name"].ToString())
.WithDescription(desc)
.WithImageUrl(img)
.AddField(efb => efb.WithName("Store Url").WithValue(storeUrl).WithIsInline(true))
.AddField(efb => efb.WithName("Cost").WithValue(cost).WithIsInline(true))
.AddField(efb => efb.WithName("Types").WithValue(types).WithIsInline(true));
.AddField(efb => efb.WithName(GetText("store_url")).WithValue(storeUrl).WithIsInline(true))
.AddField(efb => efb.WithName(GetText("cost")).WithValue(cost).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));
await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
}
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]
public async Task Hearthstone([Remainder] string name = null)
public async Task Hearthstone([Remainder] string name)
{
var arg = name;
if (string.IsNullOrWhiteSpace(arg))
{
await Context.Channel.SendErrorAsync("Please enter a card name to search for.").ConfigureAwait(false);
return;
}
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;
}
await Context.Channel.TriggerTypingAsync().ConfigureAwait(false);
string response = "";
using (var http = new HttpClient())
{
http.DefaultRequestHeaders.Clear();
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)}")
.ConfigureAwait(false);
var response = await http.GetStringAsync($"https://omgvamp-hearthstone-v1.p.mashape.com/cards/search/{Uri.EscapeUriString(arg)}")
.ConfigureAwait(false);
try
{
var items = JArray.Parse(response).Shuffle().ToList();
@ -391,7 +382,7 @@ namespace NadekoBot.Modules.Searches
string msg = null;
if (items.Count > 4)
{
msg = "⚠ Found over 4 images. Showing random 4.";
msg = GetText("hs_over_x", 4);
}
var ms = new MemoryStream();
await Task.Run(() => images.AsEnumerable().Merge().Save(ms));
@ -400,8 +391,8 @@ namespace NadekoBot.Modules.Searches
}
catch (Exception ex)
{
await Context.Channel.SendErrorAsync($"Error occured.").ConfigureAwait(false);
_log.Error(ex);
await ReplyErrorLocalized("error_occured").ConfigureAwait(false);
}
}
}
@ -411,23 +402,20 @@ namespace NadekoBot.Modules.Searches
{
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;
}
var arg = query;
if (string.IsNullOrWhiteSpace(arg))
{
await Context.Channel.SendErrorAsync("Please enter a sentence.").ConfigureAwait(false);
if (string.IsNullOrWhiteSpace(query))
return;
}
await Context.Channel.TriggerTypingAsync().ConfigureAwait(false);
using (var http = new HttpClient())
{
http.DefaultRequestHeaders.Clear();
http.DefaultRequestHeaders.Add("X-Mashape-Key", NadekoBot.Credentials.MashapeKey);
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
{
var embed = new EmbedBuilder()
@ -439,7 +427,7 @@ namespace NadekoBot.Modules.Searches
}
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))
{
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;
}
var arg = query;
if (string.IsNullOrWhiteSpace(arg))
{
await Context.Channel.SendErrorAsync("Please enter a search term.").ConfigureAwait(false);
if (string.IsNullOrWhiteSpace(query))
return;
}
await Context.Channel.TriggerTypingAsync().ConfigureAwait(false);
using (var http = new HttpClient())
{
http.DefaultRequestHeaders.Clear();
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
{
var items = JObject.Parse(res);
@ -480,7 +465,7 @@ namespace NadekoBot.Modules.Searches
}
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();
var embed = new EmbedBuilder().WithOkColor()
.WithTitle("Define: " + word)
.WithTitle(GetText("define") + " " + word)
.WithDescription(definition)
.WithFooter(efb => efb.WithText(sense.Gramatical_info?.type));
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);
}
}
[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(arg))
{
await Context.Channel.SendErrorAsync("Please enter a search term.").ConfigureAwait(false);
if (string.IsNullOrWhiteSpace(query))
return;
}
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;
}
await Context.Channel.TriggerTypingAsync().ConfigureAwait(false);
var res = "";
string res;
using (var http = new HttpClient())
{
http.DefaultRequestHeaders.Clear();
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
@ -558,7 +540,7 @@ namespace NadekoBot.Modules.Searches
}
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;
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 data = JsonConvert.DeserializeObject<WikipediaApiModel>(result);
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
await Context.Channel.SendMessageAsync(data.Query.Pages[0].FullUrl).ConfigureAwait(false);
}
@ -625,26 +607,19 @@ namespace NadekoBot.Modules.Searches
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]
public async Task Videocall([Remainder] params IUser[] users)
{
try
var allUsrs = users.Append(Context.User);
var allUsrsArray = allUsrs.ToArray();
var str = allUsrsArray.Aggregate("http://appear.in/", (current, usr) => current + Uri.EscapeUriString(usr.Username[0].ToString()));
str += new NadekoRandom().Next();
foreach (var usr in allUsrsArray)
{
var allUsrs = users.Append(Context.User);
var allUsrsArray = allUsrs.ToArray();
var str = allUsrsArray.Aggregate("http://appear.in/", (current, usr) => current + Uri.EscapeUriString(usr.Username[0].ToString()));
str += new NadekoRandom().Next();
foreach (var usr in allUsrsArray)
{
await (await (usr as IGuildUser).CreateDMChannelAsync()).SendConfirmAsync(str).ConfigureAwait(false);
}
}
catch (Exception ex)
{
_log.Error(ex);
await (await usr.CreateDMChannelAsync()).SendConfirmAsync(str).ConfigureAwait(false);
}
}
@ -664,11 +639,11 @@ namespace NadekoBot.Modules.Searches
}
[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))
{
await Context.Channel.SendErrorAsync("Please enter a target wikia, followed by search query.").ConfigureAwait(false);
await ReplyErrorLocalized("wikia_input_error").ConfigureAwait(false);
return;
}
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 items = JObject.Parse(res);
var found = items["items"][0];
var response = $@"`Title:` {found["title"].ToString()}
`Quality:` {found["quality"]}
`URL:` {await NadekoBot.Google.ShortenUrl(found["url"].ToString()).ConfigureAwait(false)}";
var response = $@"`{GetText("title")}` {found["title"]}
`{GetText("quality")}` {found["quality"]}
`{GetText("url")}:` {await NadekoBot.Google.ShortenUrl(found["url"].ToString()).ConfigureAwait(false)}";
await Context.Channel.SendMessageAsync(response).ConfigureAwait(false);
}
catch
{
await Context.Channel.SendErrorAsync($"Failed finding `{query}`.").ConfigureAwait(false);
await ReplyErrorLocalized("wikia_error").ConfigureAwait(false);
}
}
}
[NadekoCommand, Usage, Description, Aliases]
public async Task MCPing([Remainder] string query = null)
{
var arg = query;
if (string.IsNullOrWhiteSpace(arg))
{
await Context.Channel.SendErrorAsync("💢 Please enter a `ip:port`.").ConfigureAwait(false);
return;
}
await Context.Channel.TriggerTypingAsync().ConfigureAwait(false);
using (var http = new HttpClient())
{
http.DefaultRequestHeaders.Clear();
string ip = arg.Split(':')[0];
string port = arg.Split(':')[1];
var res = await http.GetStringAsync($"https://api.minetools.eu/ping/{Uri.EscapeUriString(ip)}/{Uri.EscapeUriString(port)}").ConfigureAwait(false);
try
{
var items = JObject.Parse(res);
var sb = new StringBuilder();
int ping = (int)Math.Ceiling(Double.Parse(items["latency"].ToString()));
sb.AppendLine($"`Server:` {arg}");
sb.AppendLine($"`Version:` {items["version"]["name"].ToString()} / Protocol {items["version"]["protocol"].ToString()}");
sb.AppendLine($"`Description:` {items["description"].ToString()}");
sb.AppendLine($"`Online Players:` {items["players"]["online"].ToString()}/{items["players"]["max"].ToString()}");
sb.Append($"`Latency:` {ping}");
await Context.Channel.SendMessageAsync(sb.ToString());
}
catch
{
await Context.Channel.SendErrorAsync($"Failed finding `{arg}`.").ConfigureAwait(false);
}
}
}
//[NadekoCommand, Usage, Description, Aliases]
//public async Task MCPing([Remainder] string query2 = null)
//{
// var query = query2;
// if (string.IsNullOrWhiteSpace(query))
// return;
// await Context.Channel.TriggerTypingAsync().ConfigureAwait(false);
// using (var http = new HttpClient())
// {
// http.DefaultRequestHeaders.Clear();
// var ip = query.Split(':')[0];
// var port = query.Split(':')[1];
// var res = await http.GetStringAsync($"https://api.minetools.eu/ping/{Uri.EscapeUriString(ip)}/{Uri.EscapeUriString(port)}").ConfigureAwait(false);
// try
// {
// var items = JObject.Parse(res);
// var sb = new StringBuilder();
// var ping = (int)Math.Ceiling(double.Parse(items["latency"].ToString()));
// sb.AppendLine($"`Server:` {query}");
// sb.AppendLine($"`Version:` {items["version"]["name"]} / Protocol {items["version"]["protocol"]}");
// sb.AppendLine($"`Description:` {items["description"]}");
// sb.AppendLine($"`Online Players:` {items["players"]["online"]}/{items["players"]["max"]}");
// sb.Append($"`Latency:` {ping}");
// await Context.Channel.SendMessageAsync(sb.ToString());
// }
// catch
// {
// await Context.Channel.SendErrorAsync($"Failed finding `{query}`.").ConfigureAwait(false);
// }
// }
//}
[NadekoCommand, Usage, Description, Aliases]
public async Task MCQ([Remainder] string query = null)
{
var arg = query;
if (string.IsNullOrWhiteSpace(arg))
{
await Context.Channel.SendErrorAsync("Please enter `ip:port`.").ConfigureAwait(false);
return;
}
await Context.Channel.TriggerTypingAsync().ConfigureAwait(false);
using (var http = new HttpClient())
{
http.DefaultRequestHeaders.Clear();
try
{
string ip = arg.Split(':')[0];
string port = arg.Split(':')[1];
var res = await http.GetStringAsync($"https://api.minetools.eu/query/{Uri.EscapeUriString(ip)}/{Uri.EscapeUriString(port)}").ConfigureAwait(false);
var items = JObject.Parse(res);
var sb = new StringBuilder();
sb.AppendLine($"`Server:` {arg.ToString()} 〘Status: {items["status"]}〙");
sb.AppendLine($"`Player List (First 5):`");
foreach (var item in items["Playerlist"].Take(5))
{
sb.AppendLine($":rosette: {item}");
}
sb.AppendLine($"`Online Players:` {items["Players"]} / {items["MaxPlayers"]}");
sb.AppendLine($"`Plugins:` {items["Plugins"]}");
sb.Append($"`Version:` {items["Version"]}");
await Context.Channel.SendMessageAsync(sb.ToString());
}
catch
{
await Context.Channel.SendErrorAsync($"Failed finding server `{arg}`.").ConfigureAwait(false);
}
}
}
//[NadekoCommand, Usage, Description, Aliases]
//public async Task MCQ([Remainder] string query = null)
//{
// var arg = query;
// if (string.IsNullOrWhiteSpace(arg))
// {
// await Context.Channel.SendErrorAsync("Please enter `ip:port`.").ConfigureAwait(false);
// return;
// }
// await Context.Channel.TriggerTypingAsync().ConfigureAwait(false);
// using (var http = new HttpClient())
// {
// http.DefaultRequestHeaders.Clear();
// try
// {
// var ip = arg.Split(':')[0];
// var port = arg.Split(':')[1];
// var res = await http.GetStringAsync($"https://api.minetools.eu/query/{Uri.EscapeUriString(ip)}/{Uri.EscapeUriString(port)}").ConfigureAwait(false);
// var items = JObject.Parse(res);
// var sb = new StringBuilder();
// sb.AppendLine($"`Server:` {arg} 〘Status: {items["status"]}〙");
// sb.AppendLine("`Player List (First 5):`");
// foreach (var item in items["Playerlist"].Take(5))
// {
// sb.AppendLine($":rosette: {item}");
// }
// sb.AppendLine($"`Online Players:` {items["Players"]} / {items["MaxPlayers"]}");
// sb.AppendLine($"`Plugins:` {items["Plugins"]}");
// sb.Append($"`Version:` {items["Version"]}");
// await Context.Channel.SendMessageAsync(sb.ToString());
// }
// catch
// {
// await Context.Channel.SendErrorAsync($"Failed finding server `{arg}`.").ConfigureAwait(false);
// }
// }
//}
public enum DapiSearchType
{
@ -774,7 +746,7 @@ namespace NadekoBot.Modules.Searches
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;
@ -783,7 +755,7 @@ namespace NadekoBot.Modules.Searches
var url = await InternalDapiSearch(tag, type).ConfigureAwait(false);
if (url == null)
await channel.SendErrorAsync(umsg.Author.Mention + " No results.");
await channel.SendErrorAsync(umsg.Author.Mention + " " + GetText("no_results"));
else
await channel.EmbedAsync(new EmbedBuilder().WithOkColor()
.WithDescription(umsg.Author.Mention + " " + tag)
@ -794,7 +766,7 @@ namespace NadekoBot.Modules.Searches
public static async Task<string> InternalDapiSearch(string tag, DapiSearchType type)
{
tag = tag?.Replace(" ", "_");
string website = "";
var website = "";
switch (type)
{
case DapiSearchType.Safebooru:
@ -839,10 +811,10 @@ namespace NadekoBot.Modules.Searches
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;
await ch.SendErrorAsync("Please specify search parameters.").ConfigureAwait(false);
if (!string.IsNullOrWhiteSpace(query)) return true;
await ch.SendErrorAsync(GetText("specify_search_params")).ConfigureAwait(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_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_005Csearches_005Ccommands/@EntryIndexedValue">True</s:Boolean>
<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>
/// Looks up a localized string similar to Joined.
/// </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">
<value>Word filtering enabled on this server.</value>
</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">
<value>Joined</value>
</data>