Huge amount of work done on Searches module

This commit is contained in:
Kwoth
2016-08-16 14:11:45 +02:00
parent b54f5e161d
commit b8d7eedaf7
68 changed files with 2658 additions and 2214 deletions

View File

@@ -0,0 +1,99 @@
//using Discord;
//using Discord.Commands;
//using NadekoBot.Attributes;
//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Threading.Tasks;
//// todo RestSharp
//namespace NadekoBot.Modules.Searches.Commands
//{
// public partial class SearchesModule
// {
// [LocalizedCommand, LocalizedDescription, LocalizedSummary]
// [RequireContext(ContextType.Guild)]
// public async Task Anime(IMessage imsg, [Remainder] string query)
// {
// var channel = imsg.Channel as IGuildChannel;
// if (!(await ValidateQuery(imsg.Channel as ITextChannel, query).ConfigureAwait(false))) return;
// string result;
// try
// {
// result = (await GetAnimeData(query).ConfigureAwait(false)).ToString();
// }
// catch
// {
// await imsg.Channel.SendMessageAsync("Failed to find that anime.").ConfigureAwait(false);
// return;
// }
// await imsg.Channel.SendMessageAsync(result.ToString()).ConfigureAwait(false);
// }
// [LocalizedCommand, LocalizedDescription, LocalizedSummary]
// [RequireContext(ContextType.Guild)]
// public async Task Manga(IMessage imsg, [Remainder] string query)
// {
// var channel = imsg.Channel as IGuildChannel;
// if (!(await ValidateQuery(imsg.Channel as ITextChannel, query).ConfigureAwait(false))) return;
// string result;
// try
// {
// result = (await GetMangaData(query).ConfigureAwait(false)).ToString();
// }
// catch
// {
// await imsg.Channel.SendMessageAsync("Failed to find that manga.").ConfigureAwait(false);
// return;
// }
// await imsg.Channel.SendMessageAsync(result).ConfigureAwait(false);
// }
// public static async Task<AnimeResult> GetAnimeData(string query)
// {
// if (string.IsNullOrWhiteSpace(query))
// throw new ArgumentNullException(nameof(query));
// await RefreshAnilistToken().ConfigureAwait(false);
// var link = "http://anilist.co/api/anime/search/" + Uri.EscapeUriString(query);
// var smallContent = "";
// var cl = new RestSharp.RestClient("http://anilist.co/api");
// var rq = new RestSharp.RestRequest("/anime/search/" + Uri.EscapeUriString(query));
// rq.AddParameter("access_token", token);
// smallContent = cl.Execute(rq).Content;
// var smallObj = JArray.Parse(smallContent)[0];
// rq = new RestSharp.RestRequest("/anime/" + smallObj["id"]);
// rq.AddParameter("access_token", token);
// var content = cl.Execute(rq).Content;
// return await Task.Run(() => JsonConvert.DeserializeObject<AnimeResult>(content)).ConfigureAwait(false);
// }
// public static async Task<MangaResult> GetMangaData(string query)
// {
// if (string.IsNullOrWhiteSpace(query))
// throw new ArgumentNullException(nameof(query));
// await RefreshAnilistToken().ConfigureAwait(false);
// var link = "http://anilist.co/api/anime/search/" + Uri.EscapeUriString(query);
// var smallContent = "";
// var cl = new RestSharp.RestClient("http://anilist.co/api");
// var rq = new RestSharp.RestRequest("/manga/search/" + Uri.EscapeUriString(query));
// rq.AddParameter("access_token", token);
// smallContent = cl.Execute(rq).Content;
// var smallObj = JArray.Parse(smallContent)[0];
// rq = new RestSharp.RestRequest("/manga/" + smallObj["id"]);
// rq.AddParameter("access_token", token);
// var content = cl.Execute(rq).Content;
// return await Task.Run(() => JsonConvert.DeserializeObject<MangaResult>(content)).ConfigureAwait(false);
// }
// }
//}

View File

@@ -1,171 +0,0 @@
using Discord.Commands;
using NadekoBot.Classes;
using ScaredFingers.UnitsConversion;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Threading;
using System.Threading.Tasks;
namespace NadekoBot.Modules.Searches.Commands
{
class ConverterCommand : DiscordCommand
{
public ConverterCommand(DiscordModule module) : base(module)
{
if (unitTables == null)
{
CultureInfo ci = new CultureInfo("en-US");
Thread.CurrentThread.CurrentCulture = ci;
unitTables = new List<UnitTable>();
unitTables.Add(UnitTable.LengthTable);
unitTables.Add(UnitTable.TemperatureTable);
unitTables.Add(UnitTable.VolumeTable);
unitTables.Add(UnitTable.WeightTable);
reInitCurrencyConverterTable();
}
}
internal override void Init(CommandGroupBuilder cgb)
{
cgb.CreateCommand(Module.Prefix + "convert")
.Description($"Convert quantities from>to. | `{Prefix}convert m>km 1000`")
.Parameter("from-to", ParameterType.Required)
.Parameter("quantity", ParameterType.Optional)
.Do(ConvertFunc());
cgb.CreateCommand(Module.Prefix + "convertlist")
.Description("List of the convertable dimensions and currencies.")
.Do(ConvertListFunc());
}
private Func<CommandEventArgs, Task> ConvertListFunc() =>
async e =>
{
reInitCurrencyConverterTable();
string msg = "";
foreach (var tmpTable in unitTables)
{
int i = 1;
while (tmpTable.IsKnownUnit(i))
{
msg += tmpTable.GetUnitName(i) + " (" + tmpTable.GetUnitSymbol(i) + "); ";
i++;
}
msg += "\n";
}
foreach (var curr in exchangeRateProvider.Currencies)
{
msg += curr + "; ";
}
await channel.SendMessageAsync(msg).ConfigureAwait(false);
};
private Func<CommandEventArgs, Task> ConvertFunc() =>
async e =>
{
try
{
await e.Channel.SendIsTyping().ConfigureAwait(false);
string from = e.GetArg("from-to").ToLowerInvariant().Split('>')[0];
string to = e.GetArg("from-to").ToLowerInvariant().Split('>')[1];
float quantity = 1.0f;
if (!float.TryParse(e.GetArg("quantity"), out quantity))
{
quantity = 1.0f;
}
int fromCode, toCode = 0;
UnitTable table = null;
ResolveUnitCodes(from, to, out table, out fromCode, out toCode);
if (table != null)
{
Unit inUnit = new Unit(fromCode, quantity, table);
Unit outUnit = inUnit.Convert(toCode);
await channel.SendMessageAsync(inUnit.ToString() + " = " + outUnit.ToString()).ConfigureAwait(false);
}
else
{
CultureInfo ci = new CultureInfo("en-US");
Thread.CurrentThread.CurrentCulture = ci;
reInitCurrencyConverterTable();
Unit inUnit = currTable.CreateUnit(quantity, from.ToUpperInvariant());
Unit outUnit = inUnit.Convert(currTable.CurrencyCode(to.ToUpperInvariant()));
await channel.SendMessageAsync(inUnit.ToString() + " = " + outUnit.ToString()).ConfigureAwait(false);
}
}
catch //(Exception ex)
{
//Console.WriteLine(ex.ToString());
await channel.SendMessageAsync("Bad input format, or sth went wrong... Try to list them with `" + Module.Prefix + "`convertlist").ConfigureAwait(false);
}
};
private void reInitCurrencyConverterTable()
{
if (lastChanged == null || lastChanged.DayOfYear != DateTime.Now.DayOfYear)
{
try
{
exchangeRateProvider = new WebExchangeRatesProvider();
currTable = new CurrencyExchangeTable(exchangeRateProvider);
lastChanged = DateTime.Now;
}
catch
{
Console.WriteLine("Error with the currency download.");
}
}
}
private void ResolveUnitCodes(string from, string to, out UnitTable table, out int fromCode, out int toCode)
{
foreach (var tmpTable in unitTables)
{
int f = LookupUnit(tmpTable, from);
int t = LookupUnit(tmpTable, to);
if (f > 0 && t > 0)
{
table = tmpTable;
fromCode = f;
toCode = t;
return;
}
}
table = null;
fromCode = 0;
toCode = 0;
}
private int LookupUnit(UnitTable table, string lookup)
{
string wellformedLookup = lookup.ToLowerInvariant().Replace("°", "");
int i = 1;
while (table.IsKnownUnit(i))
{
if (wellformedLookup == table.GetUnitName(i).ToLowerInvariant().Replace("°", "") ||
wellformedLookup == table.GetUnitPlural(i).ToLowerInvariant().Replace("°", "") ||
wellformedLookup == table.GetUnitSymbol(i).ToLowerInvariant().Replace("°", ""))
{
return i;
}
i++;
}
return 0;
}
private static List<UnitTable> unitTables;
private static CurrencyExchangeRatesProvider exchangeRateProvider;
private static CurrencyExchangeTable currTable;
private static DateTime lastChanged;
}
}

View File

@@ -0,0 +1,171 @@
//using Discord.Commands;
//using NadekoBot.Classes;
//using ScaredFingers.UnitsConversion;
//using System;
//using System.Collections.Generic;
//using System.Globalization;
//using System.Threading;
//using System.Threading.Tasks;
//namespace NadekoBot.Modules.Searches.Commands
//{
// class ConverterCommand : DiscordCommand
// {
// public ConverterCommand(DiscordModule module) : base(module)
// {
// if (unitTables == null)
// {
// CultureInfo ci = new CultureInfo("en-US");
// Thread.CurrentThread.CurrentCulture = ci;
// unitTables = new List<UnitTable>();
// unitTables.Add(UnitTable.LengthTable);
// unitTables.Add(UnitTable.TemperatureTable);
// unitTables.Add(UnitTable.VolumeTable);
// unitTables.Add(UnitTable.WeightTable);
// reInitCurrencyConverterTable();
// }
// }
// internal override void Init(CommandGroupBuilder cgb)
// {
// cgb.CreateCommand(Module.Prefix + "convert")
// .Description($"Convert quantities from>to. | `{Prefix}convert m>km 1000`")
// .Parameter("from-to", ParameterType.Required)
// .Parameter("quantity", ParameterType.Optional)
// .Do(ConvertFunc());
// cgb.CreateCommand(Module.Prefix + "convertlist")
// .Description("List of the convertable dimensions and currencies.")
// .Do(ConvertListFunc());
// }
// private Func<CommandEventArgs, Task> ConvertListFunc() =>
// async e =>
// {
// reInitCurrencyConverterTable();
// string msg = "";
// foreach (var tmpTable in unitTables)
// {
// int i = 1;
// while (tmpTable.IsKnownUnit(i))
// {
// msg += tmpTable.GetUnitName(i) + " (" + tmpTable.GetUnitSymbol(i) + "); ";
// i++;
// }
// msg += "\n";
// }
// foreach (var curr in exchangeRateProvider.Currencies)
// {
// msg += curr + "; ";
// }
// await imsg.Channel.SendMessageAsync(msg).ConfigureAwait(false);
// };
// private Func<CommandEventArgs, Task> ConvertFunc() =>
// async e =>
// {
// try
// {
// await e.Channel.SendIsTyping().ConfigureAwait(false);
// string from = e.GetArg("from-to").ToLowerInvariant().Split('>')[0];
// string to = e.GetArg("from-to").ToLowerInvariant().Split('>')[1];
// float quantity = 1.0f;
// if (!float.TryParse(e.GetArg("quantity"), out quantity))
// {
// quantity = 1.0f;
// }
// int fromCode, toCode = 0;
// UnitTable table = null;
// ResolveUnitCodes(from, to, out table, out fromCode, out toCode);
// if (table != null)
// {
// Unit inUnit = new Unit(fromCode, quantity, table);
// Unit outUnit = inUnit.Convert(toCode);
// await imsg.Channel.SendMessageAsync(inUnit.ToString() + " = " + outUnit.ToString()).ConfigureAwait(false);
// }
// else
// {
// CultureInfo ci = new CultureInfo("en-US");
// Thread.CurrentThread.CurrentCulture = ci;
// reInitCurrencyConverterTable();
// Unit inUnit = currTable.CreateUnit(quantity, from.ToUpperInvariant());
// Unit outUnit = inUnit.Convert(currTable.CurrencyCode(to.ToUpperInvariant()));
// await imsg.Channel.SendMessageAsync(inUnit.ToString() + " = " + outUnit.ToString()).ConfigureAwait(false);
// }
// }
// catch //(Exception ex)
// {
// //Console.WriteLine(ex.ToString());
// await imsg.Channel.SendMessageAsync("Bad input format, or sth went wrong... Try to list them with `" + Module.Prefix + "`convertlist").ConfigureAwait(false);
// }
// };
// private void reInitCurrencyConverterTable()
// {
// if (lastChanged == null || lastChanged.DayOfYear != DateTime.Now.DayOfYear)
// {
// try
// {
// exchangeRateProvider = new WebExchangeRatesProvider();
// currTable = new CurrencyExchangeTable(exchangeRateProvider);
// lastChanged = DateTime.Now;
// }
// catch
// {
// Console.WriteLine("Error with the currency download.");
// }
// }
// }
// private void ResolveUnitCodes(string from, string to, out UnitTable table, out int fromCode, out int toCode)
// {
// foreach (var tmpTable in unitTables)
// {
// int f = LookupUnit(tmpTable, from);
// int t = LookupUnit(tmpTable, to);
// if (f > 0 && t > 0)
// {
// table = tmpTable;
// fromCode = f;
// toCode = t;
// return;
// }
// }
// table = null;
// fromCode = 0;
// toCode = 0;
// }
// private int LookupUnit(UnitTable table, string lookup)
// {
// string wellformedLookup = lookup.ToLowerInvariant().Replace("°", "");
// int i = 1;
// while (table.IsKnownUnit(i))
// {
// if (wellformedLookup == table.GetUnitName(i).ToLowerInvariant().Replace("°", "") ||
// wellformedLookup == table.GetUnitPlural(i).ToLowerInvariant().Replace("°", "") ||
// wellformedLookup == table.GetUnitSymbol(i).ToLowerInvariant().Replace("°", ""))
// {
// return i;
// }
// i++;
// }
// return 0;
// }
// private static List<UnitTable> unitTables;
// private static CurrencyExchangeRatesProvider exchangeRateProvider;
// private static CurrencyExchangeTable currTable;
// private static DateTime lastChanged;
// }
//}

View File

@@ -1,85 +1,85 @@
using Discord.Commands;
using Mathos.Parser;
using NadekoBot.Classes;
using System;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
//using Discord.Commands;
//using Mathos.Parser;
//using NadekoBot.Classes;
//using System;
//using System.Text.RegularExpressions;
//using System.Threading.Tasks;
namespace NadekoBot.Modules.Searches.Commands
{
class CalcCommand : DiscordCommand
{
public CalcCommand(DiscordModule module) : base(module)
{
}
//namespace NadekoBot.Modules.Searches.Commands
//{
// class CalcCommand : DiscordCommand
// {
// public CalcCommand(DiscordModule module) : base(module)
// {
// }
internal override void Init(CommandGroupBuilder cgb)
{
cgb.CreateCommand(Module.Prefix + "calculate")
.Alias(Module.Prefix + "calc")
.Description($"Evaluate a mathematical expression. | `{Prefix}calc 1+1`")
.Parameter("expression", ParameterType.Unparsed)
.Do(EvalFunc());
}
// internal override void Init(CommandGroupBuilder cgb)
// {
// cgb.CreateCommand(Module.Prefix + "calculate")
// .Alias(Module.Prefix + "calc")
// .Description($"Evaluate a mathematical expression. | `{Prefix}calc 1+1`")
// .Parameter("expression", ParameterType.Unparsed)
// .Do(EvalFunc());
// }
private CustomParser parser = new CustomParser();
private Func<CommandEventArgs, Task> EvalFunc() => async e =>
{
string expression = e.GetArg("expression")?.Trim();
if (string.IsNullOrWhiteSpace(expression))
{
return;
}
string answer = Evaluate(expression);
if (answer == null)
{
await channel.SendMessageAsync($"Expression {expression} failed to evaluate");
return;
}
await channel.SendMessageAsync($"⚙ `{answer}`");
};
// private CustomParser parser = new CustomParser();
// private Func<CommandEventArgs, Task> EvalFunc() => async e =>
// {
// string expression = e.GetArg("expression")?.Trim();
// if (string.IsNullOrWhiteSpace(expression))
// {
// return;
// }
// string answer = Evaluate(expression);
// if (answer == null)
// {
// await imsg.Channel.SendMessageAsync($"Expression {expression} failed to evaluate");
// return;
// }
// await imsg.Channel.SendMessageAsync($"⚙ `{answer}`");
// };
private string Evaluate(string expression)
{
//check for factorial
expression = Regex.Replace(expression, @"\d+!", x => x.Value + "0");
try
{
string result = parser.Parse(expression).ToString();
return result;
}
catch (OverflowException)
{
return $"Overflow error on {expression}";
}
catch (FormatException)
{
return $"\"{expression}\" was not formatted correctly";
}
}
// private string Evaluate(string expression)
// {
// //check for factorial
// expression = Regex.Replace(expression, @"\d+!", x => x.Value + "0");
// try
// {
// string result = parser.Parse(expression).ToString();
// return result;
// }
// catch (OverflowException)
// {
// return $"Overflow error on {expression}";
// }
// catch (FormatException)
// {
// return $"\"{expression}\" was not formatted correctly";
// }
// }
class CustomParser : MathParser
{
public CustomParser() : base()
{
OperatorList.Add("!");
OperatorAction.Add("!", (x, y) => Factorial(x));
}
// class CustomParser : MathParser
// {
// public CustomParser() : base()
// {
// OperatorList.Add("!");
// OperatorAction.Add("!", (x, y) => Factorial(x));
// }
static decimal Factorial(decimal x)
{
decimal y = x - 1;
while (y > 0)
{
x = x * y--;
}
return x;
}
}
// static decimal Factorial(decimal x)
// {
// decimal y = x - 1;
// while (y > 0)
// {
// x = x * y--;
// }
// return x;
// }
// }
}
}
// }
//}

View File

@@ -1,6 +1,6 @@
using NadekoBot.Extensions;
using System.Collections.Generic;
using System.Web;
using System.Net;
namespace NadekoBot.Modules.Searches.Commands.IMDB
{
@@ -15,48 +15,18 @@ namespace NadekoBot.Modules.Searches.Commands.IMDB
public string Plot { get; set; }
public string Poster { get; set; }
public List<string> Genres { get; set; }
//public ArrayList Directors { get; set; }
//public ArrayList Writers { get; set; }
//public ArrayList Cast { get; set; }
//public ArrayList Producers { get; set; }
//public ArrayList Musicians { get; set; }
//public ArrayList Cinematographers { get; set; }
//public ArrayList Editors { get; set; }
//public string MpaaRating { get; set; }
//public string ReleaseDate { get; set; }
//public ArrayList PlotKeywords { get; set; }
//public string PosterLarge { get; set; }
//public string PosterFull { get; set; }
//public string Runtime { get; set; }
//public string Top250 { get; set; }
//public string Oscars { get; set; }
//public string Awards { get; set; }
//public string Nominations { get; set; }
//public string Storyline { get; set; }
//public string Tagline { get; set; }
//public string Votes { get; set; }
//public ArrayList Languages { get; set; }
//public ArrayList Countries { get; set; }
//public Dictionary<string, string> ReleaseDates { get; set; }
//public ArrayList MediaImages { get; set; }
//public ArrayList RecommendedTitles { get; set; }
public string ImdbURL { get; set; }
public Dictionary<string, string> Aka { get; set; }
public override string ToString() =>
$@"`Title:` {HttpUtility.HtmlDecode(Title)} {(string.IsNullOrEmpty(OriginalTitle) ? "" : $"({OriginalTitle})")}
$@"`Title:` {WebUtility.HtmlDecode(Title)} {(string.IsNullOrEmpty(OriginalTitle) ? "" : $"({OriginalTitle})")}
`Year:` {Year}
`Rating:` {Rating}
`Genre:` {GenresAsString}
`Link:` <{ImdbURL}>
`Plot:` {System.Net.WebUtility.HtmlDecode(Plot.TrimTo(500))}
`img:` " + Poster.ShortenUrl().Result;
//public string EnglishTitle => Aka.ContainsKey("USA") ? Aka["USA"] :
// (Aka.ContainsKey("UK") ? Aka["UK"] :
// (Aka.ContainsKey("(original title)") ? Aka["(original title)"] :
// (Aka.ContainsKey("(original)") ? Aka["(original)"] : OriginalTitle)));
public string GenresAsString =>
string.Join(", ", Genres);
}

View File

@@ -4,8 +4,10 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
/*******************************************************************************
* Free ASP.net IMDb Scraper API for the new IMDb Template.
@@ -24,57 +26,48 @@ namespace NadekoBot.Modules.Searches.Commands.IMDB
{
//Search Engine URLs
private static string GoogleSearch = "https://www.google.com/search?q=imdb+";
private static string BingSearch = "http://www.bing.com/search?q=imdb+";
private static string AskSearch = "http://www.ask.com/web?q=imdb+";
//Constructor
public static ImdbMovie ImdbScrape(string MovieName, bool GetExtraInfo = true)
public static async Task<ImdbMovie> ImdbScrape(string MovieName, bool GetExtraInfo = true)
{
ImdbMovie mov = new ImdbMovie();
string imdbUrl = GetIMDbUrl(System.Uri.EscapeUriString(MovieName));
string imdbUrl = await GetIMDbUrlAsync(System.Uri.EscapeUriString(MovieName));
mov.Status = false;
if (!string.IsNullOrWhiteSpace(imdbUrl))
{
ParseIMDbPage(imdbUrl, GetExtraInfo, mov);
await ParseIMDbPage(imdbUrl, GetExtraInfo, mov);
}
return mov;
}
public static ImdbMovie ImdbScrapeFromId(string imdbId, bool GetExtraInfo = true)
public static async Task<ImdbMovie> ImdbScrapeFromId(string imdbId, bool GetExtraInfo = true)
{
ImdbMovie mov = new ImdbMovie();
string imdbUrl = "http://www.imdb.com/title/" + imdbId + "/";
mov.Status = false;
ParseIMDbPage(imdbUrl, GetExtraInfo, mov);
await ParseIMDbPage(imdbUrl, GetExtraInfo, mov);
return mov;
}
public static string GetIMDBId(string MovieName)
public static async Task<string> GetIMDBId(string MovieName)
{
string imdbUrl = GetIMDbUrl(System.Uri.EscapeUriString(MovieName));
string imdbUrl = await GetIMDbUrlAsync(System.Uri.EscapeUriString(MovieName));
return match(@"http://www.imdb.com/title/(tt\d{7})", imdbUrl);
}
//Get IMDb URL from search results
private static string GetIMDbUrl(string MovieName, string searchEngine = "google")
private static async Task<string> GetIMDbUrlAsync(string MovieName)
{
string url = GoogleSearch + MovieName; //default to Google search
if (searchEngine.ToLower().Equals("bing")) url = BingSearch + MovieName;
if (searchEngine.ToLower().Equals("ask")) url = AskSearch + MovieName;
string html = GetUrlData(url);
ArrayList imdbUrls = MatchAll(@"<a href=""(http://www.imdb.com/title/tt\d{7}/)"".*?>.*?</a>", html);
string url = GoogleSearch + MovieName;
string html = await GetUrlDataAsync(url);
List<string> imdbUrls = MatchAll(@"<a href=""(http://www.imdb.com/title/tt\d{7}/)"".*?>.*?</a>", html);
if (imdbUrls.Count > 0)
return (string)imdbUrls[0]; //return first IMDb result
else if (searchEngine.ToLower().Equals("google")) //if Google search fails
return GetIMDbUrl(MovieName, "bing"); //search using Bing
else if (searchEngine.ToLower().Equals("bing")) //if Bing search fails
return GetIMDbUrl(MovieName, "ask"); //search using Ask
else //search fails
return string.Empty;
return (string)imdbUrls[0];
else return String.Empty;
}
//Parse IMDb page data
private static void ParseIMDbPage(string imdbUrl, bool GetExtraInfo, ImdbMovie mov)
private static async Task ParseIMDbPage(string imdbUrl, bool GetExtraInfo, ImdbMovie mov)
{
string html = GetUrlData(imdbUrl + "combined");
string html = await GetUrlDataAsync(imdbUrl + "combined");
mov.Id = match(@"<link rel=""canonical"" href=""http://www.imdb.com/title/(tt\d{7})/combined"" />", html);
if (!string.IsNullOrEmpty(mov.Id))
{
@@ -85,55 +78,28 @@ namespace NadekoBot.Modules.Searches.Commands.IMDB
mov.Rating = match(@"<b>(\d.\d)/10</b>", html);
mov.Genres = MatchAll(@"<a.*?>(.*?)</a>", match(@"Genre.?:(.*?)(</div>|See more)", html)).Cast<string>().ToList();
mov.Plot = match(@"Plot:</h5>.*?<div class=""info-content"">(.*?)(<a|</div)", html);
//mov.Directors = matchAll(@"<td valign=""top""><a.*?href=""/name/.*?/"">(.*?)</a>", match(@"Directed by</a></h5>(.*?)</table>", html));
//mov.Writers = matchAll(@"<td valign=""top""><a.*?href=""/name/.*?/"">(.*?)</a>", match(@"Writing credits</a></h5>(.*?)</table>", html));
//mov.Producers = matchAll(@"<td valign=""top""><a.*?href=""/name/.*?/"">(.*?)</a>", match(@"Produced by</a></h5>(.*?)</table>", html));
//mov.Musicians = matchAll(@"<td valign=""top""><a.*?href=""/name/.*?/"">(.*?)</a>", match(@"Original Music by</a></h5>(.*?)</table>", html));
//mov.Cinematographers = matchAll(@"<td valign=""top""><a.*?href=""/name/.*?/"">(.*?)</a>", match(@"Cinematography by</a></h5>(.*?)</table>", html));
//mov.Editors = matchAll(@"<td valign=""top""><a.*?href=""/name/.*?/"">(.*?)</a>", match(@"Film Editing by</a></h5>(.*?)</table>", html));
//mov.Cast = matchAll(@"<td class=""nm""><a.*?href=""/name/.*?/"".*?>(.*?)</a>", match(@"<h3>Cast</h3>(.*?)</table>", html));
//mov.PlotKeywords = matchAll(@"<a.*?>(.*?)</a>", match(@"Plot Keywords:</h5>.*?<div class=""info-content"">(.*?)</div", html));
//mov.ReleaseDate = match(@"Release Date:</h5>.*?<div class=""info-content"">.*?(\d{1,2} (January|February|March|April|May|June|July|August|September|October|November|December) (19|20)\d{2})", html);
//mov.Runtime = match(@"Runtime:</h5><div class=""info-content"">(\d{1,4}) min[\s]*.*?</div>", html);
//mov.Top250 = match(@"Top 250: #(\d{1,3})<", html);
//mov.Oscars = match(@"Won (\d+) Oscars?\.", html);
//if (string.IsNullOrEmpty(mov.Oscars) && "Won Oscar.".Equals(match(@"(Won Oscar\.)", html))) mov.Oscars = "1";
//mov.Awards = match(@"(\d{1,4}) wins", html);
//mov.Nominations = match(@"(\d{1,4}) nominations", html);
//mov.Tagline = match(@"Tagline:</h5>.*?<div class=""info-content"">(.*?)(<a|</div)", html);
//mov.MpaaRating = match(@"MPAA</a>:</h5><div class=""info-content"">Rated (G|PG|PG-13|PG-14|R|NC-17|X) ", html);
//mov.Votes = match(@">(\d+,?\d*) votes<", html);
//mov.Languages = matchAll(@"<a.*?>(.*?)</a>", match(@"Language.?:(.*?)(</div>|>.?and )", html));
//mov.Countries = matchAll(@"<a.*?>(.*?)</a>", match(@"Country:(.*?)(</div>|>.?and )", html));
mov.Poster = match(@"<div class=""photo"">.*?<a name=""poster"".*?><img.*?src=""(.*?)"".*?</div>", html);
if (!string.IsNullOrEmpty(mov.Poster) && mov.Poster.IndexOf("media-imdb.com") > 0)
{
mov.Poster = Regex.Replace(mov.Poster, @"_V1.*?.jpg", "_V1._SY200.jpg");
//mov.PosterLarge = Regex.Replace(mov.Poster, @"_V1.*?.jpg", "_V1._SY500.jpg");
//mov.PosterFull = Regex.Replace(mov.Poster, @"_V1.*?.jpg", "_V1._SY0.jpg");
}
else
{
mov.Poster = string.Empty;
//mov.PosterLarge = string.Empty;
//mov.PosterFull = string.Empty;
}
mov.ImdbURL = "http://www.imdb.com/title/" + mov.Id + "/";
if (GetExtraInfo)
{
string plotHtml = GetUrlData(imdbUrl + "plotsummary");
//mov.Storyline = match(@"<p class=""plotpar"">(.*?)(<i>|</p>)", plotHtml);
GetReleaseDatesAndAka(mov);
//mov.MediaImages = getMediaImages(mov);
//mov.RecommendedTitles = getRecommendedTitles(mov);
string plotHtml = await GetUrlDataAsync(imdbUrl + "plotsummary");
await GetReleaseDatesAndAka(mov);
}
}
}
//Get all release dates and aka-s
private static void GetReleaseDatesAndAka(ImdbMovie mov)
private static async Task GetReleaseDatesAndAka(ImdbMovie mov)
{
Dictionary<string, string> release = new Dictionary<string, string>();
string releasehtml = GetUrlData("http://www.imdb.com/title/" + mov.Id + "/releaseinfo");
string releasehtml = await GetUrlDataAsync("http://www.imdb.com/title/" + mov.Id + "/releaseinfo");
foreach (string r in MatchAll(@"<tr class="".*?"">(.*?)</tr>", match(@"<table id=""release_dates"" class=""subpage_data spFirst"">\n*?(.*?)</table>", releasehtml)))
{
Match rd = new Regex(@"<td>(.*?)</td>\n*?.*?<td class=.*?>(.*?)</td>", RegexOptions.Multiline).Match(r);
@@ -142,7 +108,7 @@ namespace NadekoBot.Modules.Searches.Commands.IMDB
//mov.ReleaseDates = release;
Dictionary<string, string> aka = new Dictionary<string, string>();
ArrayList list = MatchAll(@".*?<tr class="".*?"">(.*?)</tr>", match(@"<table id=""akas"" class=.*?>\n*?(.*?)</table>", releasehtml));
List<string> list = MatchAll(@".*?<tr class="".*?"">(.*?)</tr>", match(@"<table id=""akas"" class=.*?>\n*?(.*?)</table>", releasehtml));
foreach (string r in list)
{
Match rd = new Regex(@"\n*?.*?<td>(.*?)</td>\n*?.*?<td>(.*?)</td>", RegexOptions.Multiline).Match(r);
@@ -154,15 +120,15 @@ namespace NadekoBot.Modules.Searches.Commands.IMDB
}
//Get all media images
private static ArrayList GetMediaImages(ImdbMovie mov)
private static async Task<List<string>> GetMediaImages(ImdbMovie mov)
{
ArrayList list = new ArrayList();
List<string> list = new List<string>();
string mediaurl = "http://www.imdb.com/title/" + mov.Id + "/mediaindex";
string mediahtml = GetUrlData(mediaurl);
string mediahtml = await GetUrlDataAsync(mediaurl);
int pagecount = MatchAll(@"<a href=""\?page=(.*?)"">", match(@"<span style=""padding: 0 1em;"">(.*?)</span>", mediahtml)).Count;
for (int p = 1; p <= pagecount + 1; p++)
{
mediahtml = GetUrlData(mediaurl + "?page=" + p);
mediahtml = await GetUrlDataAsync(mediaurl + "?page=" + p);
foreach (Match m in new Regex(@"src=""(.*?)""", RegexOptions.Multiline).Matches(match(@"<div class=""thumb_list"" style=""font-size: 0px;"">(.*?)</div>", mediahtml)))
{
String image = m.Groups[1].Value;
@@ -172,15 +138,15 @@ namespace NadekoBot.Modules.Searches.Commands.IMDB
return list;
}
//Get Recommended Titles
private static ArrayList GetRecommendedTitles(ImdbMovie mov)
private static async Task<List<string>> GetRecommendedTitlesAsync(ImdbMovie mov)
{
ArrayList list = new ArrayList();
List<string> list = new List<string>();
string recUrl = "http://www.imdb.com/widget/recommendations/_ajax/get_more_recs?specs=p13nsims%3A" + mov.Id;
string json = GetUrlData(recUrl);
string json = await GetUrlDataAsync(recUrl);
list = MatchAll(@"title=\\""(.*?)\\""", json);
HashSet<String> set = new HashSet<string>();
foreach (String rec in list) set.Add(rec);
return new ArrayList(set.ToList());
return new List<string>(set.ToList());
}
/*******************************[ Helper Methods ]********************************/
//Match single instance
@@ -188,10 +154,10 @@ namespace NadekoBot.Modules.Searches.Commands.IMDB
{
return new Regex(regex, RegexOptions.Multiline).Match(html).Groups[i].Value.Trim();
}
//Match all instances and return as ArrayList
private static ArrayList MatchAll(string regex, string html, int i = 1)
//Match all instances and return as List<string>
private static List<string> MatchAll(string regex, string html, int i = 1)
{
ArrayList list = new ArrayList();
List<string> list = new List<string>();
foreach (Match m in new Regex(regex, RegexOptions.Multiline).Matches(html))
list.Add(m.Groups[i].Value.Trim());
return list;
@@ -202,22 +168,13 @@ namespace NadekoBot.Modules.Searches.Commands.IMDB
return Regex.Replace(inputString, @"<.*?>", string.Empty);
}
//Get URL Data
private static string GetUrlData(string url)
private static Task<string> GetUrlDataAsync(string url)
{
WebClient client = new WebClient();
Random r = new Random();
//Random IP Address
//client.Headers["X-Forwarded-For"] = r.Next(0, 255) + "." + r.Next(0, 255) + "." + r.Next(0, 255) + "." + r.Next(0, 255);
//Random User-Agent
client.Headers["User-Agent"] = "Mozilla/" + r.Next(3, 5) + ".0 (Windows NT " + r.Next(3, 5) + "." + r.Next(0, 2) + "; rv:37.0) Gecko/20100101 Firefox/" + r.Next(30, 37) + "." + r.Next(0, 5);
Stream datastream = client.OpenRead(url);
StreamReader reader = new StreamReader(datastream);
StringBuilder sb = new StringBuilder();
//TODO: Coud be reader error must catch and drop!!!
while (!reader.EndOfStream)
sb.Append(reader.ReadLine());
return sb.ToString();
using (var http = new HttpClient())
{
http.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.202 Safari/535.1");
return http.GetStringAsync(url);
}
}
}
}

View File

@@ -0,0 +1,91 @@
using Discord;
using Discord.Commands;
using NadekoBot.Attributes;
using NadekoBot.Modules.Searches.Commands.Models;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
namespace NadekoBot.Modules.Searches.Commands
{
public partial class SearchesModule
{
[Group]
public class JokeCommands
{
//todo DB
private List<WoWJoke> wowJokes;
private List<MagicItem> magicItems;
public JokeCommands()
{
wowJokes = JsonConvert.DeserializeObject<List<WoWJoke>>(File.ReadAllText("data/wowjokes.json"));
magicItems = JsonConvert.DeserializeObject<List<MagicItem>>(File.ReadAllText("data/magicitems.json"));
}
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
[RequireContext(ContextType.Guild)]
public async Task Yomama(IMessage imsg)
{
var channel = imsg.Channel as IGuildChannel;
using (var http = new HttpClient())
{
var response = await http.GetStringAsync("http://api.yomomma.info/").ConfigureAwait(false);
await imsg.Channel.SendMessageAsync("`" + JObject.Parse(response)["joke"].ToString() + "` 😆").ConfigureAwait(false);
}
}
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
[RequireContext(ContextType.Guild)]
public async Task Randjoke(IMessage imsg)
{
var channel = imsg.Channel as IGuildChannel;
using (var http = new HttpClient())
{
var response = await http.GetStringAsync("http://tambal.azurewebsites.net/joke/random").ConfigureAwait(false);
await imsg.Channel.SendMessageAsync("`" + JObject.Parse(response)["joke"].ToString() + "` 😆").ConfigureAwait(false);
}
}
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
[RequireContext(ContextType.Guild)]
public async Task ChuckNorris(IMessage imsg)
{
var channel = imsg.Channel as IGuildChannel;
using (var http = new HttpClient())
{
var response = await http.GetStringAsync("http://tambal.azurewebsites.net/joke/random").ConfigureAwait(false);
await imsg.Channel.SendMessageAsync("`" + JObject.Parse(response)["joke"].ToString() + "` 😆").ConfigureAwait(false);
}
}
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
[RequireContext(ContextType.Guild)]
public async Task WowJoke(IMessage imsg)
{
var channel = imsg.Channel as IGuildChannel;
if (!wowJokes.Any())
{
}
await imsg.Channel.SendMessageAsync(wowJokes[new Random().Next(0, wowJokes.Count)].ToString());
}
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
[RequireContext(ContextType.Guild)]
public async Task MagicItem(IMessage imsg)
{
var channel = imsg.Channel as IGuildChannel;
var rng = new Random();
var item = magicItems[rng.Next(0, magicItems.Count)].ToString();
await imsg.Channel.SendMessageAsync(item).ConfigureAwait(false);
}
}
}
}

View File

@@ -1,383 +1,384 @@
using Discord.Commands;
using NadekoBot.Classes;
using NadekoBot.Extensions;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//using Discord.Commands;
//using NadekoBot.Classes;
//using NadekoBot.Extensions;
//using Newtonsoft.Json.Linq;
//using System;
//using System.Collections.Generic;
//using System.Drawing;
//using System.Linq;
//using System.Text;
//using System.Threading.Tasks;
namespace NadekoBot.Modules.Searches.Commands
{
internal class LoLCommands : DiscordCommand
{
////todo drawing
//namespace NadekoBot.Modules.Searches.Commands
//{
// internal class LoLCommands : DiscordCommand
// {
private class CachedChampion
{
public System.IO.Stream ImageStream { get; set; }
public DateTime AddedAt { get; set; }
public string Name { get; set; }
}
// private class CachedChampion
// {
// public System.IO.Stream ImageStream { get; set; }
// public DateTime AddedAt { get; set; }
// public string Name { get; set; }
// }
private class ChampionNameComparer : IEqualityComparer<JToken>
{
public bool Equals(JToken a, JToken b) => a["name"].ToString() == b["name"].ToString();
// private class ChampionNameComparer : IEqualityComparer<JToken>
// {
// public bool Equals(JToken a, JToken b) => a["name"].ToString() == b["name"].ToString();
public int GetHashCode(JToken obj) =>
obj["name"].GetHashCode();
}
// public int GetHashCode(JToken obj) =>
// obj["name"].GetHashCode();
// }
private static Dictionary<string, CachedChampion> CachedChampionImages = new Dictionary<string, CachedChampion>();
// private static Dictionary<string, CachedChampion> CachedChampionImages = new Dictionary<string, CachedChampion>();
private System.Timers.Timer clearTimer { get; } = new System.Timers.Timer();
public LoLCommands(DiscordModule module) : base(module)
{
clearTimer.Interval = new TimeSpan(0, 10, 0).TotalMilliseconds;
clearTimer.Start();
clearTimer.Elapsed += (s, e) =>
{
try
{
CachedChampionImages = CachedChampionImages
.Where(kvp => DateTime.Now - kvp.Value.AddedAt > new TimeSpan(1, 0, 0))
.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
}
catch { }
};
}
// private System.Timers.Timer clearTimer { get; } = new System.Timers.Timer();
// public LoLCommands(DiscordModule module) : base(module)
// {
// clearTimer.Interval = new TimeSpan(0, 10, 0).TotalMilliseconds;
// clearTimer.Start();
// clearTimer.Elapsed += (s, e) =>
// {
// try
// {
// CachedChampionImages = CachedChampionImages
// .Where(kvp => DateTime.Now - kvp.Value.AddedAt > new TimeSpan(1, 0, 0))
// .ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
// }
// catch { }
// };
// }
private readonly string[] trashTalk = { "Better ban your counters. You are going to carry the game anyway.",
"Go with the flow. Don't think. Just ban one of these.",
"DONT READ BELOW! Ban Urgot mid OP 100%. Im smurf Diamond 1.",
"Ask your teammates what would they like to play, and ban that.",
"If you consider playing teemo, do it. If you consider teemo, you deserve him.",
"Doesn't matter what you ban really. Enemy will ban your main and you will lose." };
// private readonly string[] trashTalk = { "Better ban your counters. You are going to carry the game anyway.",
// "Go with the flow. Don't think. Just ban one of these.",
// "DONT READ BELOW! Ban Urgot mid OP 100%. Im smurf Diamond 1.",
// "Ask your teammates what would they like to play, and ban that.",
// "If you consider playing teemo, do it. If you consider teemo, you deserve him.",
// "Doesn't matter what you ban really. Enemy will ban your main and you will lose." };
public Func<CommandEventArgs, Task> DoFunc()
{
throw new NotImplementedException();
}
// public Func<CommandEventArgs, Task> DoFunc()
// {
// throw new NotImplementedException();
// }
private class MatchupModel
{
public int Games { get; set; }
public float WinRate { get; set; }
[Newtonsoft.Json.JsonProperty("key")]
public string Name { get; set; }
public float StatScore { get; set; }
}
// private class MatchupModel
// {
// public int Games { get; set; }
// public float WinRate { get; set; }
// [Newtonsoft.Json.JsonProperty("key")]
// public string Name { get; set; }
// public float StatScore { get; set; }
// }
internal override void Init(CommandGroupBuilder cgb)
{
cgb.CreateCommand(Module.Prefix + "lolchamp")
.Description($"Shows League Of Legends champion statistics. If there are spaces/apostrophes or in the name - omit them. Optional second parameter is a role. |`{Prefix}lolchamp Riven` or `{Prefix}lolchamp Annie sup`")
.Parameter("champ", ParameterType.Required)
.Parameter("position", ParameterType.Unparsed)
.Do(async e =>
{
try
{
//get role
var role = ResolvePos(e.GetArg("position"));
var resolvedRole = role;
var name = e.GetArg("champ").Replace(" ", "").ToLower();
CachedChampion champ = null;
// internal override void Init(CommandGroupBuilder cgb)
// {
// cgb.CreateCommand(Module.Prefix + "lolchamp")
// .Description($"Shows League Of Legends champion statistics. If there are spaces/apostrophes or in the name - omit them. Optional second parameter is a role. |`{Prefix}lolchamp Riven` or `{Prefix}lolchamp Annie sup`")
// .Parameter("champ", ParameterType.Required)
// .Parameter("position", ParameterType.Unparsed)
// .Do(async e =>
// {
// try
// {
// //get role
// var role = ResolvePos(e.GetArg("position"));
// var resolvedRole = role;
// var name = e.GetArg("champ").Replace(" ", "").ToLower();
// CachedChampion champ = null;
if(CachedChampionImages.TryGetValue(name + "_" + resolvedRole, out champ))
if (champ != null)
{
champ.ImageStream.Position = 0;
await e.Channel.SendFile("champ.png", champ.ImageStream).ConfigureAwait(false);
return;
}
var allData = JArray.Parse(await Classes.http.GetStringAsync($"http://api.champion.gg/champion/{name}?api_key={NadekoBot.Creds.LOLAPIKey}").ConfigureAwait(false));
JToken data = null;
if (role != null)
{
for (var i = 0; i < allData.Count; i++)
{
if (allData[i]["role"].ToString().Equals(role))
{
data = allData[i];
break;
}
}
if (data == null)
{
await channel.SendMessageAsync("💢 Data for that role does not exist.").ConfigureAwait(false);
return;
}
}
else
{
data = allData[0];
role = allData[0]["role"].ToString();
resolvedRole = ResolvePos(role);
}
if(CachedChampionImages.TryGetValue(name + "_" + resolvedRole, out champ))
if (champ != null)
{
champ.ImageStream.Position = 0;
await e.Channel.SendFile("champ.png", champ.ImageStream).ConfigureAwait(false);
return;
}
//name = data["title"].ToString();
// get all possible roles, and "select" the shown one
var roles = new string[allData.Count];
for (var i = 0; i < allData.Count; i++)
{
roles[i] = allData[i]["role"].ToString();
if (roles[i] == role)
roles[i] = ">" + roles[i] + "<";
}
var general = JArray.Parse(await http.GetStringAsync($"http://api.champion.gg/stats/" +
$"champs/{name}?api_key={NadekoBot.Creds.LOLAPIKey}")
.ConfigureAwait(false))
.FirstOrDefault(jt => jt["role"].ToString() == role)?["general"];
if (general == null)
{
Console.WriteLine("General is null.");
return;
}
//get build data for this role
var buildData = data["items"]["mostGames"]["items"];
var items = new string[6];
for (var i = 0; i < 6; i++)
{
items[i] = buildData[i]["id"].ToString();
}
// if(CachedChampionImages.TryGetValue(name + "_" + resolvedRole, out champ))
// if (champ != null)
// {
// champ.ImageStream.Position = 0;
// await e.Channel.SendFile("champ.png", champ.ImageStream).ConfigureAwait(false);
// return;
// }
// var allData = JArray.Parse(await Classes.http.GetStringAsync($"http://api.champion.gg/champion/{name}?api_key={NadekoBot.Creds.LOLAPIKey}").ConfigureAwait(false));
// JToken data = null;
// if (role != null)
// {
// for (var i = 0; i < allData.Count; i++)
// {
// if (allData[i]["role"].ToString().Equals(role))
// {
// data = allData[i];
// break;
// }
// }
// if (data == null)
// {
// await imsg.Channel.SendMessageAsync("💢 Data for that role does not exist.").ConfigureAwait(false);
// return;
// }
// }
// else
// {
// data = allData[0];
// role = allData[0]["role"].ToString();
// resolvedRole = ResolvePos(role);
// }
// if(CachedChampionImages.TryGetValue(name + "_" + resolvedRole, out champ))
// if (champ != null)
// {
// champ.ImageStream.Position = 0;
// await e.Channel.SendFile("champ.png", champ.ImageStream).ConfigureAwait(false);
// return;
// }
// //name = data["title"].ToString();
// // get all possible roles, and "select" the shown one
// var roles = new string[allData.Count];
// for (var i = 0; i < allData.Count; i++)
// {
// roles[i] = allData[i]["role"].ToString();
// if (roles[i] == role)
// roles[i] = ">" + roles[i] + "<";
// }
// var general = JArray.Parse(await http.GetStringAsync($"http://api.champion.gg/stats/" +
// $"champs/{name}?api_key={NadekoBot.Creds.LOLAPIKey}")
// .ConfigureAwait(false))
// .FirstOrDefault(jt => jt["role"].ToString() == role)?["general"];
// if (general == null)
// {
// Console.WriteLine("General is null.");
// return;
// }
// //get build data for this role
// var buildData = data["items"]["mostGames"]["items"];
// var items = new string[6];
// for (var i = 0; i < 6; i++)
// {
// items[i] = buildData[i]["id"].ToString();
// }
//get matchup data to show counters and countered champions
var matchupDataIE = data["matchups"].ToObject<List<MatchupModel>>();
// //get matchup data to show counters and countered champions
// var matchupDataIE = data["matchups"].ToObject<List<MatchupModel>>();
var matchupData = matchupDataIE.OrderBy(m => m.StatScore).ToArray();
// var matchupData = matchupDataIE.OrderBy(m => m.StatScore).ToArray();
var countered = new[] { matchupData[0].Name, matchupData[1].Name, matchupData[2].Name };
var counters = new[] { matchupData[matchupData.Length - 1].Name, matchupData[matchupData.Length - 2].Name, matchupData[matchupData.Length - 3].Name };
// var countered = new[] { matchupData[0].Name, matchupData[1].Name, matchupData[2].Name };
// var counters = new[] { matchupData[matchupData.Length - 1].Name, matchupData[matchupData.Length - 2].Name, matchupData[matchupData.Length - 3].Name };
//get runes data
var runesJArray = data["runes"]["mostGames"]["runes"] as JArray;
var runes = string.Join("\n", runesJArray.OrderBy(jt => int.Parse(jt["number"].ToString())).Select(jt => jt["number"].ToString() + "x" + jt["name"]));
// //get runes data
// var runesJArray = data["runes"]["mostGames"]["runes"] as JArray;
// var runes = string.Join("\n", runesJArray.OrderBy(jt => int.Parse(jt["number"].ToString())).Select(jt => jt["number"].ToString() + "x" + jt["name"]));
// get masteries data
// // get masteries data
var masteries = (data["masteries"]["mostGames"]["masteries"] as JArray);
// var masteries = (data["masteries"]["mostGames"]["masteries"] as JArray);
//get skill order data<API_KEY>
// //get skill order data<API_KEY>
var orderArr = (data["skills"]["mostGames"]["order"] as JArray);
// var orderArr = (data["skills"]["mostGames"]["order"] as JArray);
var img = Image.FromFile("data/lol/bg.png");
using (var g = Graphics.FromImage(img))
{
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
//g.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;
const int margin = 5;
const int imageSize = 75;
var normalFont = new Font("Monaco", 8, FontStyle.Regular);
var smallFont = new Font("Monaco", 7, FontStyle.Regular);
//draw champ image
var champName = data["key"].ToString().Replace(" ", "");
// var img = Image.FromFile("data/lol/bg.png");
// using (var g = Graphics.FromImage(img))
// {
// g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
// //g.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;
// const int margin = 5;
// const int imageSize = 75;
// var normalFont = new Font("Monaco", 8, FontStyle.Regular);
// var smallFont = new Font("Monaco", 7, FontStyle.Regular);
// //draw champ image
// var champName = data["key"].ToString().Replace(" ", "");
g.DrawImage(GetImage(champName), new Rectangle(margin, margin, imageSize, imageSize));
//draw champ name
if (champName == "MonkeyKing")
champName = "Wukong";
g.DrawString($"{champName}", new Font("Times New Roman", 24, FontStyle.Regular), Brushes.WhiteSmoke, margin + imageSize + margin, margin);
//draw champ surname
// g.DrawImage(GetImage(champName), new Rectangle(margin, margin, imageSize, imageSize));
// //draw champ name
// if (champName == "MonkeyKing")
// champName = "Wukong";
// g.DrawString($"{champName}", new Font("Times New Roman", 24, FontStyle.Regular), Brushes.WhiteSmoke, margin + imageSize + margin, margin);
// //draw champ surname
//draw skill order
if (orderArr.Count != 0)
{
float orderFormula = 120 / orderArr.Count;
const float orderVerticalSpacing = 10;
for (var i = 0; i < orderArr.Count; i++)
{
var orderX = margin + margin + imageSize + orderFormula * i + i;
float orderY = margin + 35;
var spellName = orderArr[i].ToString().ToLowerInvariant();
// //draw skill order
// if (orderArr.Count != 0)
// {
// float orderFormula = 120 / orderArr.Count;
// const float orderVerticalSpacing = 10;
// for (var i = 0; i < orderArr.Count; i++)
// {
// var orderX = margin + margin + imageSize + orderFormula * i + i;
// float orderY = margin + 35;
// var spellName = orderArr[i].ToString().ToLowerInvariant();
switch (spellName)
{
case "w":
orderY += orderVerticalSpacing;
break;
case "e":
orderY += orderVerticalSpacing * 2;
break;
case "r":
orderY += orderVerticalSpacing * 3;
break;
default:
break;
}
// switch (spellName)
// {
// case "w":
// orderY += orderVerticalSpacing;
// break;
// case "e":
// orderY += orderVerticalSpacing * 2;
// break;
// case "r":
// orderY += orderVerticalSpacing * 3;
// break;
// default:
// break;
// }
g.DrawString(spellName.ToUpperInvariant(), new Font("Monaco", 7), Brushes.LimeGreen, orderX, orderY);
}
}
//draw roles
g.DrawString("Roles: " + string.Join(", ", roles), normalFont, Brushes.WhiteSmoke, margin, margin + imageSize + margin);
// g.DrawString(spellName.ToUpperInvariant(), new Font("Monaco", 7), Brushes.LimeGreen, orderX, orderY);
// }
// }
// //draw roles
// g.DrawString("Roles: " + string.Join(", ", roles), normalFont, Brushes.WhiteSmoke, margin, margin + imageSize + margin);
//draw average stats
g.DrawString(
$@" Average Stats
// //draw average stats
// g.DrawString(
//$@" Average Stats
Kills: {general["kills"]} CS: {general["minionsKilled"]}
Deaths: {general["deaths"]} Win: {general["winPercent"]}%
Assists: {general["assists"]} Ban: {general["banRate"]}%
", normalFont, Brushes.WhiteSmoke, img.Width - 150, margin);
//draw masteries
g.DrawString($"Masteries: {string.Join(" / ", masteries?.Select(jt => jt["total"]))}", normalFont, Brushes.WhiteSmoke, margin, margin + imageSize + margin + 20);
//draw runes
g.DrawString($"{runes}", smallFont, Brushes.WhiteSmoke, margin, margin + imageSize + margin + 40);
//draw counters
g.DrawString($"Best against", smallFont, Brushes.WhiteSmoke, margin, img.Height - imageSize + margin);
var smallImgSize = 50;
//Kills: {general["kills"]} CS: {general["minionsKilled"]}
//Deaths: {general["deaths"]} Win: {general["winPercent"]}%
//Assists: {general["assists"]} Ban: {general["banRate"]}%
//", normalFont, Brushes.WhiteSmoke, img.Width - 150, margin);
// //draw masteries
// g.DrawString($"Masteries: {string.Join(" / ", masteries?.Select(jt => jt["total"]))}", normalFont, Brushes.WhiteSmoke, margin, margin + imageSize + margin + 20);
// //draw runes
// g.DrawString($"{runes}", smallFont, Brushes.WhiteSmoke, margin, margin + imageSize + margin + 40);
// //draw counters
// g.DrawString($"Best against", smallFont, Brushes.WhiteSmoke, margin, img.Height - imageSize + margin);
// var smallImgSize = 50;
for (var i = 0; i < counters.Length; i++)
{
g.DrawImage(GetImage(counters[i]),
new Rectangle(i * (smallImgSize + margin) + margin, img.Height - smallImgSize - margin,
smallImgSize,
smallImgSize));
}
//draw countered by
g.DrawString($"Worst against", smallFont, Brushes.WhiteSmoke, img.Width - 3 * (smallImgSize + margin), img.Height - imageSize + margin);
// for (var i = 0; i < counters.Length; i++)
// {
// g.DrawImage(GetImage(counters[i]),
// new Rectangle(i * (smallImgSize + margin) + margin, img.Height - smallImgSize - margin,
// smallImgSize,
// smallImgSize));
// }
// //draw countered by
// g.DrawString($"Worst against", smallFont, Brushes.WhiteSmoke, img.Width - 3 * (smallImgSize + margin), img.Height - imageSize + margin);
for (var i = 0; i < countered.Length; i++)
{
var j = countered.Length - i;
g.DrawImage(GetImage(countered[i]),
new Rectangle(img.Width - (j * (smallImgSize + margin) + margin), img.Height - smallImgSize - margin,
smallImgSize,
smallImgSize));
}
//draw item build
g.DrawString("Popular build", normalFont, Brushes.WhiteSmoke, img.Width - (3 * (smallImgSize + margin) + margin), 77);
// for (var i = 0; i < countered.Length; i++)
// {
// var j = countered.Length - i;
// g.DrawImage(GetImage(countered[i]),
// new Rectangle(img.Width - (j * (smallImgSize + margin) + margin), img.Height - smallImgSize - margin,
// smallImgSize,
// smallImgSize));
// }
// //draw item build
// g.DrawString("Popular build", normalFont, Brushes.WhiteSmoke, img.Width - (3 * (smallImgSize + margin) + margin), 77);
for (var i = 0; i < 6; i++)
{
var inverseI = 5 - i;
var j = inverseI % 3 + 1;
var k = inverseI / 3;
g.DrawImage(GetImage(items[i], GetImageType.Item),
new Rectangle(img.Width - (j * (smallImgSize + margin) + margin), 92 + k * (smallImgSize + margin),
smallImgSize,
smallImgSize));
}
}
var cachedChamp = new CachedChampion { AddedAt = DateTime.Now, ImageStream = img.ToStream(System.Drawing.Imaging.ImageFormat.Png), Name = name.ToLower() + "_" + resolvedRole };
CachedChampionImages.Add(cachedChamp.Name, cachedChamp);
await e.Channel.SendFile(data["title"] + "_stats.png", cachedChamp.ImageStream).ConfigureAwait(false);
}
catch (Exception ex)
{
Console.WriteLine(ex);
await channel.SendMessageAsync("💢 Failed retreiving data for that champion.").ConfigureAwait(false);
}
});
// for (var i = 0; i < 6; i++)
// {
// var inverseI = 5 - i;
// var j = inverseI % 3 + 1;
// var k = inverseI / 3;
// g.DrawImage(GetImage(items[i], GetImageType.Item),
// new Rectangle(img.Width - (j * (smallImgSize + margin) + margin), 92 + k * (smallImgSize + margin),
// smallImgSize,
// smallImgSize));
// }
// }
// var cachedChamp = new CachedChampion { AddedAt = DateTime.Now, ImageStream = img.ToStream(System.Drawing.Imaging.ImageFormat.Png), Name = name.ToLower() + "_" + resolvedRole };
// CachedChampionImages.Add(cachedChamp.Name, cachedChamp);
// await e.Channel.SendFile(data["title"] + "_stats.png", cachedChamp.ImageStream).ConfigureAwait(false);
// }
// catch (Exception ex)
// {
// Console.WriteLine(ex);
// await imsg.Channel.SendMessageAsync("💢 Failed retreiving data for that champion.").ConfigureAwait(false);
// }
// });
cgb.CreateCommand(Module.Prefix + "lolban")
.Description($"Shows top 6 banned champions ordered by ban rate. Ban these champions and you will be Plat 5 in no time. | `{Prefix}lolban`")
.Do(async e =>
{
// cgb.CreateCommand(Module.Prefix + "lolban")
// .Description($"Shows top 6 banned champions ordered by ban rate. Ban these champions and you will be Plat 5 in no time. | `{Prefix}lolban`")
// .Do(async e =>
// {
var showCount = 8;
//http://api.champion.gg/stats/champs/mostBanned?api_key=YOUR_API_TOKEN&page=1&limit=2
try
{
var data = JObject.Parse(
await Classes
.SearchHelper
.GetResponseStringAsync($"http://api.champion.gg/stats/champs/mostBanned?" +
$"api_key={NadekoBot.Creds.LOLAPIKey}&page=1&" +
$"limit={showCount}")
.ConfigureAwait(false))["data"] as JArray;
var dataList = data.Distinct(new ChampionNameComparer()).Take(showCount).ToList();
var sb = new StringBuilder();
sb.AppendLine($"**Showing {showCount} top banned champions.**");
sb.AppendLine($"`{trashTalk[new Random().Next(0, trashTalk.Length)]}`");
for (var i = 0; i < dataList.Count; i++)
{
if (i % 2 == 0 && i != 0)
sb.AppendLine();
sb.Append($"`{i + 1}.` **{dataList[i]["name"]}** ");
//sb.AppendLine($" ({dataList[i]["general"]["banRate"]}%)");
}
// var showCount = 8;
// //http://api.champion.gg/stats/champs/mostBanned?api_key=YOUR_API_TOKEN&page=1&limit=2
// try
// {
// var data = JObject.Parse(
// await Classes
// .SearchHelper
// .GetResponseStringAsync($"http://api.champion.gg/stats/champs/mostBanned?" +
// $"api_key={NadekoBot.Creds.LOLAPIKey}&page=1&" +
// $"limit={showCount}")
// .ConfigureAwait(false))["data"] as JArray;
// var dataList = data.Distinct(new ChampionNameComparer()).Take(showCount).ToList();
// var sb = new StringBuilder();
// sb.AppendLine($"**Showing {showCount} top banned champions.**");
// sb.AppendLine($"`{trashTalk[new Random().Next(0, trashTalk.Length)]}`");
// for (var i = 0; i < dataList.Count; i++)
// {
// if (i % 2 == 0 && i != 0)
// sb.AppendLine();
// sb.Append($"`{i + 1}.` **{dataList[i]["name"]}** ");
// //sb.AppendLine($" ({dataList[i]["general"]["banRate"]}%)");
// }
await channel.SendMessageAsync(sb.ToString()).ConfigureAwait(false);
}
catch (Exception)
{
await channel.SendMessageAsync($":anger: Fail: Champion.gg didsabled ban data until next patch. Sorry for the inconvenience.").ConfigureAwait(false);
}
});
}
// await imsg.Channel.SendMessageAsync(sb.ToString()).ConfigureAwait(false);
// }
// catch (Exception)
// {
// await imsg.Channel.SendMessageAsync($":anger: Fail: Champion.gg didsabled ban data until next patch. Sorry for the inconvenience.").ConfigureAwait(false);
// }
// });
// }
private enum GetImageType
{
Champion,
Item
}
private static Image GetImage(string id, GetImageType imageType = GetImageType.Champion)
{
try
{
switch (imageType)
{
case GetImageType.Champion:
return Image.FromFile($"data/lol/champions/{id}.png");
case GetImageType.Item:
default:
return Image.FromFile($"data/lol/items/{id}.png");
}
}
catch (Exception)
{
return Image.FromFile("data/lol/_ERROR.png");
}
}
// private enum GetImageType
// {
// Champion,
// Item
// }
// private static Image GetImage(string id, GetImageType imageType = GetImageType.Champion)
// {
// try
// {
// switch (imageType)
// {
// case GetImageType.Champion:
// return Image.FromFile($"data/lol/champions/{id}.png");
// case GetImageType.Item:
// default:
// return Image.FromFile($"data/lol/items/{id}.png");
// }
// }
// catch (Exception)
// {
// return Image.FromFile("data/lol/_ERROR.png");
// }
// }
private static string ResolvePos(string pos)
{
if (string.IsNullOrWhiteSpace(pos))
return null;
switch (pos.ToLowerInvariant())
{
case "m":
case "mid":
case "midorfeed":
case "midd":
case "middle":
return "Middle";
case "top":
case "topp":
case "t":
case "toporfeed":
return "Top";
case "j":
case "jun":
case "jungl":
case "jungle":
return "Jungle";
case "a":
case "ad":
case "adc":
case "carry":
case "ad carry":
case "adcarry":
case "c":
return "ADC";
case "s":
case "sup":
case "supp":
case "support":
return "Support";
default:
return pos;
}
}
}
}
// private static string ResolvePos(string pos)
// {
// if (string.IsNullOrWhiteSpace(pos))
// return null;
// switch (pos.ToLowerInvariant())
// {
// case "m":
// case "mid":
// case "midorfeed":
// case "midd":
// case "middle":
// return "Middle";
// case "top":
// case "topp":
// case "t":
// case "toporfeed":
// return "Top";
// case "j":
// case "jun":
// case "jungl":
// case "jungle":
// return "Jungle";
// case "a":
// case "ad":
// case "adc":
// case "carry":
// case "ad carry":
// case "adcarry":
// case "c":
// return "ADC";
// case "s":
// case "sup":
// case "supp":
// case "support":
// return "Support";
// default:
// return pos;
// }
// }
// }
//}

View File

@@ -5,42 +5,44 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Discord;
using NadekoBot.Services;
using System.Threading.Tasks;
using NadekoBot.Attributes;
using System.Net.Http;
using NadekoBot.Extensions;
namespace NadekoBot.Modules.Searches.Commands
{
class MemegenCommands : DiscordCommand
public partial class SearchesModule : DiscordModule
{
public MemegenCommands(DiscordModule module) : base(module)
public SearchesModule(ILocalization loc, CommandService cmds, IBotConfiguration config, IDiscordClient client) : base(loc, cmds, config, client)
{
}
internal override void Init(CommandGroupBuilder cgb)
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
[RequireContext(ContextType.Guild)]
public async Task Memelist(IMessage imsg)
{
cgb.CreateCommand(Prefix + "memelist")
.Description($"Pulls a list of memes you can use with `~memegen` from http://memegen.link/templates/ | `{Prefix}memelist`")
.Do(async e =>
{
int i = 0;
await channel.SendMessageAsync("`List Of Commands:`\n```xl\n" +
string.Join("\n", JsonConvert.DeserializeObject<Dictionary<string, string>>(await http.GetStringAsync("http://memegen.link/templates/"))
.Select(kvp => Path.GetFileName(kvp.Value))
.GroupBy(item => (i++) / 4)
.Select(ig => string.Concat(ig.Select(el => $"{el,-17}"))))
+ $"\n```").ConfigureAwait(false);
});
var channel = imsg.Channel as IGuildChannel;
using (var http = new HttpClient())
{
var data = JsonConvert.DeserializeObject<Dictionary<string, string>>(await http.GetStringAsync("http://memegen.link/templates/"))
.Select(kvp => Path.GetFileName(kvp.Value));
cgb.CreateCommand(Prefix + "memegen")
.Description($"Generates a meme from memelist with top and bottom text. | `{Prefix}memegen biw \"gets iced coffee\" \"in the winter\"`")
.Parameter("meme", ParameterType.Required)
.Parameter("toptext", ParameterType.Required)
.Parameter("bottext", ParameterType.Required)
.Do(async e =>
{
var meme = e.GetArg("meme");
var top = Uri.EscapeDataString(e.GetArg("toptext").Replace(' ', '-'));
var bot = Uri.EscapeDataString(e.GetArg("bottext").Replace(' ', '-'));
await channel.SendMessageAsync($"http://memegen.link/{meme}/{top}/{bot}.jpg");
});
await imsg.Channel.SendTableAsync(data, x => $"{x,-17}", 3);
}
}
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
[RequireContext(ContextType.Guild)]
public async Task Memegen(IMessage imsg, string meme, string topText, string botText)
{
var channel = imsg.Channel as IGuildChannel;
var top = Uri.EscapeDataString(topText.Replace(' ', '-'));
var bot = Uri.EscapeDataString(botText.Replace(' ', '-'));
await imsg.Channel.SendMessageAsync($"http://memegen.link/{meme}/{top}/{bot}.jpg");
}
}
}

View File

@@ -0,0 +1,10 @@
namespace NadekoBot.Modules.Searches.Commands.Models
{
class MagicItem
{
public string Name { get; set; }
public string Description { get; set; }
public override string ToString() =>
$"✨`{Name}`\n\t*{Description}*";
}
}

View File

@@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NadekoBot.Modules.Searches.Commands.Models
{
public class SearchPokemon
{
public class GenderRatioClass
{
public float M { get; set; }
public float F { get; set; }
}
public class BaseStatsClass
{
public int HP { get; set; }
public int ATK { get; set; }
public int DEF { get; set; }
public int SPA { get; set; }
public int SPD { get; set; }
public int SPE { get; set; }
public override string ToString() => $@"
**HP:** {HP,-4} **ATK:** {ATK,-4} **DEF:** {DEF,-4}
**SPA:** {SPA,-4} **SPD:** {SPD,-4} **SPE:** {SPE,-4}";
}
public int Id { get; set; }
public string Species { get; set; }
public string[] Types { get; set; }
public GenderRatioClass GenderRatio { get; set; }
public BaseStatsClass BaseStats { get; set; }
public Dictionary<string, string> Abilities { get; set; }
public float HeightM { get; set; }
public float WeightKg { get; set; }
public string Color { get; set; }
public string[] Evos { get; set; }
public string[] EggGroups { get; set; }
public override string ToString() => $@"`Name:` {Species}
`Types:` {string.Join(", ", Types)}
`Stats:` {BaseStats}
`Height:` {HeightM,4}m `Weight:` {WeightKg}kg
`Abilities:` {string.Join(", ", Abilities.Values)}";
}
public class SearchPokemonAbility
{
public string Desc { get; set; }
public string Name { get; set; }
public float Rating { get; set; }
public override string ToString() => $@"`Name:` : {Name}
`Rating:` {Rating}
`Description:` {Desc}";
}
}

View File

@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace NadekoBot.Modules.Searches.Commands.Models
{
public class WikipediaApiModel
{
public WikipediaQuery Query { get; set; }
public class WikipediaQuery
{
public WikipediaPage[] Pages { get; set; }
public class WikipediaPage
{
public bool Missing { get; set; } = false;
public string FullUrl { get; set; }
}
}
}
}

View File

@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace NadekoBot.Modules.Searches.Commands.Models
{
public class WoWJoke
{
public string Question { get; set; }
public string Answer { get; set; }
public override string ToString() => $"`{Question}`\n\n**{Answer}**";
}
}

View File

@@ -1,268 +1,268 @@
using Discord.Commands;
using NadekoBot.Classes;
using Newtonsoft.Json.Linq;
using System;
using System.IO;
using System.Net;
using System.Text.RegularExpressions;
//using Discord.Commands;
//using NadekoBot.Classes;
//using Newtonsoft.Json.Linq;
//using System;
//using System.IO;
//using System.Net;
//using System.Text.RegularExpressions;
namespace NadekoBot.Modules.Searches.Commands
{
internal class OsuCommands : DiscordCommand
{
public OsuCommands(DiscordModule module) : base(module)
{
}
//namespace NadekoBot.Modules.Searches.Commands
//{
// internal class OsuCommands : DiscordCommand
// {
// public OsuCommands(DiscordModule module) : base(module)
// {
// }
internal override void Init(CommandGroupBuilder cgb)
{
cgb.CreateCommand(Module.Prefix + "osu")
.Description($"Shows osu stats for a player. | `{Prefix}osu Name` or `{Prefix}osu Name taiko`")
.Parameter("usr", ParameterType.Required)
.Parameter("mode", ParameterType.Unparsed)
.Do(async e =>
{
if (string.IsNullOrWhiteSpace(e.GetArg("usr")))
return;
// internal override void Init(CommandGroupBuilder cgb)
// {
// cgb.CreateCommand(Module.Prefix + "osu")
// .Description($"Shows osu stats for a player. | `{Prefix}osu Name` or `{Prefix}osu Name taiko`")
// .Parameter("usr", ParameterType.Required)
// .Parameter("mode", ParameterType.Unparsed)
// .Do(async e =>
// {
// if (string.IsNullOrWhiteSpace(e.GetArg("usr")))
// return;
using (WebClient cl = new WebClient())
{
try
{
var m = 0;
if (!string.IsNullOrWhiteSpace(e.GetArg("mode")))
{
m = ResolveGameMode(e.GetArg("mode"));
}
// using (WebClient cl = new WebClient())
// {
// try
// {
// var m = 0;
// if (!string.IsNullOrWhiteSpace(e.GetArg("mode")))
// {
// m = ResolveGameMode(e.GetArg("mode"));
// }
cl.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.NoCacheNoStore);
cl.Headers.Add(HttpRequestHeader.UserAgent, "Mozilla/5.0 (Windows NT 6.2; Win64; x64)");
cl.DownloadDataAsync(new Uri($"http://lemmmy.pw/osusig/sig.php?uname={ e.GetArg("usr") }&flagshadow&xpbar&xpbarhex&pp=2&mode={m}"));
cl.DownloadDataCompleted += async (s, cle) =>
{
try
{
await e.Channel.SendFile($"{e.GetArg("usr")}.png", new MemoryStream(cle.Result)).ConfigureAwait(false);
await channel.SendMessageAsync($"`Profile Link:`https://osu.ppy.sh/u/{Uri.EscapeDataString(e.GetArg("usr"))}\n`Image provided by https://lemmmy.pw/osusig`").ConfigureAwait(false);
}
catch { }
};
}
catch
{
await channel.SendMessageAsync("💢 Failed retrieving osu signature :\\").ConfigureAwait(false);
}
}
});
// cl.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.NoCacheNoStore);
// cl.Headers.Add(HttpRequestHeader.UserAgent, "Mozilla/5.0 (Windows NT 6.2; Win64; x64)");
// cl.DownloadDataAsync(new Uri($"http://lemmmy.pw/osusig/sig.php?uname={ e.GetArg("usr") }&flagshadow&xpbar&xpbarhex&pp=2&mode={m}"));
// cl.DownloadDataCompleted += async (s, cle) =>
// {
// try
// {
// await e.Channel.SendFile($"{e.GetArg("usr")}.png", new MemoryStream(cle.Result)).ConfigureAwait(false);
// await imsg.Channel.SendMessageAsync($"`Profile Link:`https://osu.ppy.sh/u/{Uri.EscapeDataString(e.GetArg("usr"))}\n`Image provided by https://lemmmy.pw/osusig`").ConfigureAwait(false);
// }
// catch { }
// };
// }
// catch
// {
// await imsg.Channel.SendMessageAsync("💢 Failed retrieving osu signature :\\").ConfigureAwait(false);
// }
// }
// });
cgb.CreateCommand(Module.Prefix + "osu b")
.Description($"Shows information about an osu beatmap. |`{Prefix}osu b` https://osu.ppy.sh/s/127712`")
.Parameter("map", ParameterType.Unparsed)
.Do(async e =>
{
if (string.IsNullOrWhiteSpace(NadekoBot.Creds.OsuAPIKey))
{
await channel.SendMessageAsync("💢 An osu! API key is required.").ConfigureAwait(false);
return;
}
// cgb.CreateCommand(Module.Prefix + "osu b")
// .Description($"Shows information about an osu beatmap. |`{Prefix}osu b` https://osu.ppy.sh/s/127712`")
// .Parameter("map", ParameterType.Unparsed)
// .Do(async e =>
// {
// if (string.IsNullOrWhiteSpace(NadekoBot.Creds.OsuAPIKey))
// {
// await imsg.Channel.SendMessageAsync("💢 An osu! API key is required.").ConfigureAwait(false);
// return;
// }
if (string.IsNullOrWhiteSpace(e.GetArg("map")))
return;
// if (string.IsNullOrWhiteSpace(e.GetArg("map")))
// return;
try
{
var mapId = ResolveMap(e.GetArg("map"));
var reqString = $"https://osu.ppy.sh/api/get_beatmaps?k={NadekoBot.Creds.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"]}"), 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 channel.SendMessageAsync(sb.ToString()).ConfigureAwait(false);
}
catch
{
await channel.SendMessageAsync("Something went wrong.");
}
});
// try
// {
// var mapId = ResolveMap(e.GetArg("map"));
// var reqString = $"https://osu.ppy.sh/api/get_beatmaps?k={NadekoBot.Creds.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"]}"), 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 imsg.Channel.SendMessageAsync(sb.ToString()).ConfigureAwait(false);
// }
// catch
// {
// await imsg.Channel.SendMessageAsync("Something went wrong.");
// }
// });
cgb.CreateCommand(Module.Prefix + "osu top5")
.Description($"Displays a user's top 5 plays. |`{Prefix}osu top5 Name`")
.Parameter("usr", ParameterType.Required)
.Parameter("mode", ParameterType.Unparsed)
.Do(async e =>
{
if (string.IsNullOrWhiteSpace(NadekoBot.Creds.OsuAPIKey))
{
await channel.SendMessageAsync("💢 An osu! API key is required.").ConfigureAwait(false);
return;
}
// cgb.CreateCommand(Module.Prefix + "osu top5")
// .Description($"Displays a user's top 5 plays. |`{Prefix}osu top5 Name`")
// .Parameter("usr", ParameterType.Required)
// .Parameter("mode", ParameterType.Unparsed)
// .Do(async e =>
// {
// if (string.IsNullOrWhiteSpace(NadekoBot.Creds.OsuAPIKey))
// {
// await imsg.Channel.SendMessageAsync("💢 An osu! API key is required.").ConfigureAwait(false);
// return;
// }
if (string.IsNullOrWhiteSpace(e.GetArg("usr")))
{
await channel.SendMessageAsync("💢 Please provide a username.").ConfigureAwait(false);
return;
}
// if (string.IsNullOrWhiteSpace(e.GetArg("usr")))
// {
// await imsg.Channel.SendMessageAsync("💢 Please provide a username.").ConfigureAwait(false);
// return;
// }
try
{
var m = 0;
if (!string.IsNullOrWhiteSpace(e.GetArg("mode")))
{
m = ResolveGameMode(e.GetArg("mode"));
}
// try
// {
// var m = 0;
// if (!string.IsNullOrWhiteSpace(e.GetArg("mode")))
// {
// m = ResolveGameMode(e.GetArg("mode"));
// }
var reqString = $"https://osu.ppy.sh/api/get_user_best?k={NadekoBot.Creds.OsuAPIKey}&u={Uri.EscapeDataString(e.GetArg("usr"))}&type=string&limit=5&m={m}";
var obj = JArray.Parse(await http.GetStringAsync(reqString).ConfigureAwait(false));
var sb = new System.Text.StringBuilder($"`Top 5 plays for {e.GetArg("usr")}:`\n```xl" + Environment.NewLine);
foreach (var item in obj)
{
var mapReqString = $"https://osu.ppy.sh/api/get_beatmaps?k={NadekoBot.Creds.OsuAPIKey}&b={item["beatmap_id"]}";
var map = JArray.Parse(await http.GetStringAsync(mapReqString).ConfigureAwait(false))[0];
var pp = Math.Round(Double.Parse($"{item["pp"]}"), 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"]}");
}
sb.Append("```");
await channel.SendMessageAsync(sb.ToString()).ConfigureAwait(false);
}
catch
{
await channel.SendMessageAsync("Something went wrong.");
}
});
}
// var reqString = $"https://osu.ppy.sh/api/get_user_best?k={NadekoBot.Creds.OsuAPIKey}&u={Uri.EscapeDataString(e.GetArg("usr"))}&type=string&limit=5&m={m}";
// var obj = JArray.Parse(await http.GetStringAsync(reqString).ConfigureAwait(false));
// var sb = new System.Text.StringBuilder($"`Top 5 plays for {e.GetArg("usr")}:`\n```xl" + Environment.NewLine);
// foreach (var item in obj)
// {
// var mapReqString = $"https://osu.ppy.sh/api/get_beatmaps?k={NadekoBot.Creds.OsuAPIKey}&b={item["beatmap_id"]}";
// var map = JArray.Parse(await http.GetStringAsync(mapReqString).ConfigureAwait(false))[0];
// var pp = Math.Round(Double.Parse($"{item["pp"]}"), 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"]}");
// }
// sb.Append("```");
// await imsg.Channel.SendMessageAsync(sb.ToString()).ConfigureAwait(false);
// }
// catch
// {
// await imsg.Channel.SendMessageAsync("Something went wrong.");
// }
// });
// }
//https://osu.ppy.sh/wiki/Accuracy
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"]}");
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"]}");
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"]}");
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"]}");
totalHits *= 300;
return Math.Round(hitPoints / totalHits * 100, 2);
}
}
// //https://osu.ppy.sh/wiki/Accuracy
// 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"]}");
// 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"]}");
// 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"]}");
// 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"]}");
// totalHits *= 300;
// return Math.Round(hitPoints / totalHits * 100, 2);
// }
// }
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);
if (s.Success)
{
var mapId = mapLink.Substring(mapLink.IndexOf("/s/") + 3);
return $"s={mapId}";
}
else if (b.Success)
{
if (m.Success)
return $"b={mapLink.Substring(mapLink.IndexOf("/b/") + 3, mapLink.IndexOf("&m") - (mapLink.IndexOf("/b/") + 3))}";
else
return $"b={mapLink.Substring(mapLink.IndexOf("/b/") + 3)}";
}
else if (p.Success)
{
if (m.Success)
return $"b={mapLink.Substring(mapLink.IndexOf("?b=") + 3, mapLink.IndexOf("&m") - (mapLink.IndexOf("?b=") + 3))}";
else
return $"b={mapLink.Substring(mapLink.IndexOf("?b=") + 3)}";
}
else
{
return $"s={mapLink}"; //just a default incase an ID number was provided by itself (non-url)?
}
}
// 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);
// if (s.Success)
// {
// var mapId = mapLink.Substring(mapLink.IndexOf("/s/") + 3);
// return $"s={mapId}";
// }
// else if (b.Success)
// {
// if (m.Success)
// return $"b={mapLink.Substring(mapLink.IndexOf("/b/") + 3, mapLink.IndexOf("&m") - (mapLink.IndexOf("/b/") + 3))}";
// else
// return $"b={mapLink.Substring(mapLink.IndexOf("/b/") + 3)}";
// }
// else if (p.Success)
// {
// if (m.Success)
// return $"b={mapLink.Substring(mapLink.IndexOf("?b=") + 3, mapLink.IndexOf("&m") - (mapLink.IndexOf("?b=") + 3))}";
// else
// return $"b={mapLink.Substring(mapLink.IndexOf("?b=") + 3)}";
// }
// else
// {
// return $"s={mapLink}"; //just a default incase an ID number was provided by itself (non-url)?
// }
// }
private static int ResolveGameMode(string mode)
{
switch (mode.ToLower())
{
case "std":
case "standard":
return 0;
case "taiko":
return 1;
case "ctb":
case "catchthebeat":
return 2;
case "mania":
case "osu!mania":
return 3;
default:
return 0;
}
}
// private static int ResolveGameMode(string mode)
// {
// switch (mode.ToLower())
// {
// case "std":
// case "standard":
// return 0;
// case "taiko":
// return 1;
// case "ctb":
// case "catchthebeat":
// return 2;
// case "mania":
// case "osu!mania":
// return 3;
// default:
// return 0;
// }
// }
//https://github.com/ppy/osu-api/wiki#mods
private static string ResolveMods(int mods)
{
var modString = $"+";
// //https://github.com/ppy/osu-api/wiki#mods
// private static string ResolveMods(int mods)
// {
// var modString = $"+";
if (IsBitSet(mods, 0))
modString += "NF";
if (IsBitSet(mods, 1))
modString += "EZ";
if (IsBitSet(mods, 8))
modString += "HT";
// if (IsBitSet(mods, 0))
// modString += "NF";
// if (IsBitSet(mods, 1))
// modString += "EZ";
// if (IsBitSet(mods, 8))
// modString += "HT";
if (IsBitSet(mods, 3))
modString += "HD";
if (IsBitSet(mods, 4))
modString += "HR";
if (IsBitSet(mods, 6) && !IsBitSet(mods, 9))
modString += "DT";
if (IsBitSet(mods, 9))
modString += "NC";
if (IsBitSet(mods, 10))
modString += "FL";
// if (IsBitSet(mods, 3))
// modString += "HD";
// if (IsBitSet(mods, 4))
// modString += "HR";
// if (IsBitSet(mods, 6) && !IsBitSet(mods, 9))
// modString += "DT";
// if (IsBitSet(mods, 9))
// modString += "NC";
// if (IsBitSet(mods, 10))
// modString += "FL";
if (IsBitSet(mods, 5))
modString += "SD";
if (IsBitSet(mods, 14))
modString += "PF";
// if (IsBitSet(mods, 5))
// modString += "SD";
// if (IsBitSet(mods, 14))
// modString += "PF";
if (IsBitSet(mods, 7))
modString += "RX";
if (IsBitSet(mods, 11))
modString += "AT";
if (IsBitSet(mods, 12))
modString += "SO";
return modString;
}
// if (IsBitSet(mods, 7))
// modString += "RX";
// if (IsBitSet(mods, 11))
// modString += "AT";
// if (IsBitSet(mods, 12))
// modString += "SO";
// return modString;
// }
private static bool IsBitSet(int mods, int pos)
{
return (mods & (1 << pos)) != 0;
}
// private static bool IsBitSet(int mods, int pos)
// {
// return (mods & (1 << pos)) != 0;
// }
}
}
// }
//}

View File

@@ -1,116 +1,69 @@
using Discord.Commands;
using NadekoBot.Classes;
using Discord;
using Discord.Commands;
using NadekoBot.Attributes;
using NadekoBot.Modules.Searches.Commands.Models;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
namespace NadekoBot.Modules.Searches.Commands
{
class PokemonSearchCommands : DiscordCommand
public partial class SearchesModule : DiscordModule
{
private static Dictionary<string, SearchPokemon> pokemons;
private static Dictionary<string, SearchPokemonAbility> pokemonAbilities;
public PokemonSearchCommands(DiscordModule module) : base(module)
[Group]
public class PokemonSearchCommands
{
//todo DB
private static Dictionary<string, SearchPokemon> pokemons;
private static Dictionary<string, SearchPokemonAbility> pokemonAbilities;
pokemons = JsonConvert.DeserializeObject<Dictionary<string, SearchPokemon>>(File.ReadAllText("data/pokemon/pokemon_list.json"));
pokemonAbilities = JsonConvert.DeserializeObject<Dictionary<string, SearchPokemonAbility>>(File.ReadAllText("data/pokemon/pokemon_abilities.json"));
}
public PokemonSearchCommands()
{
pokemons = JsonConvert.DeserializeObject<Dictionary<string, SearchPokemon>>(File.ReadAllText("data/pokemon/pokemon_list.json"));
pokemonAbilities = JsonConvert.DeserializeObject<Dictionary<string, SearchPokemonAbility>>(File.ReadAllText("data/pokemon/pokemon_abilities.json"));
}
internal override void Init(CommandGroupBuilder cgb)
{
cgb.CreateCommand(Prefix + "pokemon")
.Alias(Prefix + "poke")
.Description($"Searches for a pokemon. | `{Prefix}poke Sylveon`")
.Parameter("pokemon", ParameterType.Unparsed)
.Do(async e =>
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
[RequireContext(ContextType.Guild)]
public async Task Pokemon(IMessage imsg, [Remainder] string pokemon)
{
var channel = imsg.Channel as IGuildChannel;
pokemon = pokemon?.Trim().ToUpperInvariant();
if (string.IsNullOrWhiteSpace(pokemon))
return;
foreach (var kvp in pokemons)
{
var pok = e.GetArg("pokemon")?.Trim().ToUpperInvariant();
if (string.IsNullOrWhiteSpace(pok))
return;
foreach (var kvp in pokemons)
if (kvp.Key.ToUpperInvariant() == pokemon.ToUpperInvariant())
{
if (kvp.Key.ToUpperInvariant() == pok.ToUpperInvariant())
{
await channel.SendMessageAsync($"`Stats for \"{kvp.Key}\" pokemon:`\n{kvp.Value}");
return;
}
await imsg.Channel.SendMessageAsync($"`Stats for \"{kvp.Key}\" pokemon:`\n{kvp.Value}");
return;
}
await channel.SendMessageAsync("`No pokemon found.`");
});
}
await imsg.Channel.SendMessageAsync("`No pokemon found.`");
}
cgb.CreateCommand(Prefix + "pokemonability")
.Alias(Prefix + "pokeab")
.Description($"Searches for a pokemon ability. | `{Prefix}pokeab \"water gun\"`")
.Parameter("abil", ParameterType.Unparsed)
.Do(async e =>
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
[RequireContext(ContextType.Guild)]
public async Task PokemonAbility(IMessage imsg, [Remainder] string ability)
{
var channel = imsg.Channel as IGuildChannel;
ability = ability?.Trim().ToUpperInvariant().Replace(" ", "");
if (string.IsNullOrWhiteSpace(ability))
return;
foreach (var kvp in pokemonAbilities)
{
var ab = e.GetArg("abil")?.Trim().ToUpperInvariant().Replace(" ", "");
if (string.IsNullOrWhiteSpace(ab))
return;
foreach (var kvp in pokemonAbilities)
if (kvp.Key.ToUpperInvariant() == ability)
{
if (kvp.Key.ToUpperInvariant() == ab)
{
await channel.SendMessageAsync($"`Info for \"{kvp.Key}\" ability:`\n{kvp.Value}");
return;
}
await imsg.Channel.SendMessageAsync($"`Info for \"{kvp.Key}\" ability:`\n{kvp.Value}");
return;
}
await channel.SendMessageAsync("`No ability found.`");
});
}
await imsg.Channel.SendMessageAsync("`No ability found.`");
}
}
}
public class SearchPokemon
{
public class GenderRatioClass
{
public float M { get; set; }
public float F { get; set; }
}
public class BaseStatsClass
{
public int HP { get; set; }
public int ATK { get; set; }
public int DEF { get; set; }
public int SPA { get; set; }
public int SPD { get; set; }
public int SPE { get; set; }
public override string ToString() => $@"
**HP:** {HP,-4} **ATK:** {ATK,-4} **DEF:** {DEF,-4}
**SPA:** {SPA,-4} **SPD:** {SPD,-4} **SPE:** {SPE,-4}";
}
public int Id { get; set; }
public string Species { get; set; }
public string[] Types { get; set; }
public GenderRatioClass GenderRatio { get; set; }
public BaseStatsClass BaseStats { get; set; }
public Dictionary<string, string> Abilities { get; set; }
public float HeightM { get; set; }
public float WeightKg { get; set; }
public string Color { get; set; }
public string[] Evos { get; set; }
public string[] EggGroups { get; set; }
public override string ToString() => $@"`Name:` {Species}
`Types:` {string.Join(", ", Types)}
`Stats:` {BaseStats}
`Height:` {HeightM,4}m `Weight:` {WeightKg}kg
`Abilities:` {string.Join(", ", Abilities.Values)}";
}
public class SearchPokemonAbility
{
public string Desc { get; set; }
public string Name { get; set; }
public float Rating { get; set; }
public override string ToString() => $@"`Name:` : {Name}
`Rating:` {Rating}
`Description:` {Desc}";
}
}

View File

@@ -1,17 +0,0 @@
using Discord.Commands;
using NadekoBot.Classes;
namespace NadekoBot.Modules.Searches.Commands
{
class RedditCommand : DiscordCommand
{
public RedditCommand(DiscordModule module) : base(module)
{
}
internal override void Init(CommandGroupBuilder cgb)
{
//throw new NotImplementedException();
}
}
}

View File

@@ -0,0 +1,347 @@
//using Discord.Commands;
//using NadekoBot.Classes;
//using Newtonsoft.Json.Linq;
//using System;
//using System.Collections.Concurrent;
//using System.Linq;
//using System.Threading.Tasks;
//using Discord;
//using NadekoBot.Services;
//using System.Threading;
//namespace NadekoBot.Modules.Searches.Commands
//{
// public partial class SearchesModule : DiscordModule
// {
// [Group]
// public class StreamNotificationCommands
// {
// private readonly Timer checkTimer;
// private ConcurrentDictionary<string, Tuple<bool, string>> cachedStatuses = new ConcurrentDictionary<string, Tuple<bool, string>>();
// private bool FirstPass { get; set; } = true;
// public StreamNotifications(DiscordModule module)
// {
// checkTimer = new Timer(async (state) =>
// {
// cachedStatuses.Clear();
// try
// {
// var streams = SpecificConfigurations.Default.AllConfigs.SelectMany(c => c.ObservingStreams);
// if (!streams.Any()) return;
// foreach (var stream in streams)
// {
// Tuple<bool, string> data;
// try
// {
// data = await GetStreamStatus(stream).ConfigureAwait(false);
// }
// catch
// {
// continue;
// }
// if (data.Item1 != stream.LastStatus)
// {
// stream.LastStatus = data.Item1;
// if (FirstPass)
// continue;
// var server = NadekoBot.Client.GetServer(stream.ServerId);
// var channel = server?.GetChannel(stream.ChannelId);
// if (channel == null)
// continue;
// var msg = $"`{stream.Username}`'s stream is now " +
// $"**{(data.Item1 ? "ONLINE" : "OFFLINE")}** with " +
// $"**{data.Item2}** viewers.";
// if (stream.LastStatus)
// if (stream.Type == StreamNotificationConfig.StreamType.Hitbox)
// msg += $"\n`Here is the Link:`【 http://www.hitbox.tv/{stream.Username}/ 】";
// else if (stream.Type == StreamNotificationConfig.StreamType.Twitch)
// msg += $"\n`Here is the Link:`【 http://www.twitch.tv/{stream.Username}/ 】";
// else if (stream.Type == StreamNotificationConfig.StreamType.Beam)
// msg += $"\n`Here is the Link:`【 http://www.beam.pro/{stream.Username}/ 】";
// else if (stream.Type == StreamNotificationConfig.StreamType.YoutubeGaming)
// msg += $"\n`Here is the Link:`【 not implemented yet - {stream.Username} 】";
// await channel.SendMessage(msg).ConfigureAwait(false);
// }
// }
// FirstPass = false;
// }
// catch { }
// }, null, TimeSpan.Zero, TimeSpan.FromSeconds(15));
// }
// public StreamNotifications(ILocalization loc, CommandService cmds, IBotConfiguration config, IDiscordClient client) : base(loc, cmds, config, client)
// {
// }
// private async Task<Tuple<bool, string>> GetStreamStatus(StreamNotificationConfig stream, bool checkCache = true)
// {
// bool isLive;
// string response;
// JObject data;
// Tuple<bool, string> result;
// switch (stream.Type)
// {
// case StreamNotificationConfig.StreamType.Hitbox:
// var hitboxUrl = $"https://api.hitbox.tv/media/status/{stream.Username}";
// if (checkCache && cachedStatuses.TryGetValue(hitboxUrl, out result))
// return result;
// response = await http.GetStringAsync(hitboxUrl).ConfigureAwait(false);
// data = JObject.Parse(response);
// isLive = data["media_is_live"].ToString() == "1";
// result = new Tuple<bool, string>(isLive, data["media_views"].ToString());
// cachedStatuses.TryAdd(hitboxUrl, result);
// return result;
// case StreamNotificationConfig.StreamType.Twitch:
// var twitchUrl = $"https://api.twitch.tv/kraken/streams/{Uri.EscapeUriString(stream.Username)}";
// if (checkCache && cachedStatuses.TryGetValue(twitchUrl, out result))
// return result;
// response = await http.GetStringAsync(twitchUrl).ConfigureAwait(false);
// data = JObject.Parse(response);
// isLive = !string.IsNullOrWhiteSpace(data["stream"].ToString());
// result = new Tuple<bool, string>(isLive, isLive ? data["stream"]["viewers"].ToString() : "0");
// cachedStatuses.TryAdd(twitchUrl, result);
// return result;
// case StreamNotificationConfig.StreamType.Beam:
// var beamUrl = $"https://beam.pro/api/v1/channels/{stream.Username}";
// if (checkCache && cachedStatuses.TryGetValue(beamUrl, out result))
// return result;
// response = await http.GetStringAsync(beamUrl).ConfigureAwait(false);
// data = JObject.Parse(response);
// isLive = data["online"].ToObject<bool>() == true;
// result = new Tuple<bool, string>(isLive, data["viewersCurrent"].ToString());
// cachedStatuses.TryAdd(beamUrl, result);
// return result;
// default:
// break;
// }
// return new Tuple<bool, string>(false, "0");
// }
// internal override void Init(CommandGroupBuilder cgb)
// {
// cgb.CreateCommand(Module.Prefix + "hitbox")
// .Alias(Module.Prefix + "hb")
// .Description("Notifies this channel when a certain user starts streaming." +
// $" | `{Prefix}hitbox SomeStreamer`")
// .Parameter("username", ParameterType.Unparsed)
// .AddCheck(SimpleCheckers.ManageServer())
// .Do(TrackStream(StreamNotificationConfig.StreamType.Hitbox));
// cgb.CreateCommand(Module.Prefix + "twitch")
// .Alias(Module.Prefix + "tw")
// .Description("Notifies this channel when a certain user starts streaming." +
// $" | `{Prefix}twitch SomeStreamer`")
// .AddCheck(SimpleCheckers.ManageServer())
// .Parameter("username", ParameterType.Unparsed)
// .Do(TrackStream(StreamNotificationConfig.StreamType.Twitch));
// cgb.CreateCommand(Module.Prefix + "beam")
// .Alias(Module.Prefix + "bm")
// .Description("Notifies this channel when a certain user starts streaming." +
// $" | `{Prefix}beam SomeStreamer`")
// .AddCheck(SimpleCheckers.ManageServer())
// .Parameter("username", ParameterType.Unparsed)
// .Do(TrackStream(StreamNotificationConfig.StreamType.Beam));
// cgb.CreateCommand(Module.Prefix + "checkhitbox")
// .Alias(Module.Prefix + "chhb")
// .Description("Checks if a certain user is streaming on the hitbox platform." +
// $" | `{Prefix}chhb SomeStreamer`")
// .Parameter("username", ParameterType.Unparsed)
// .AddCheck(SimpleCheckers.ManageServer())
// .Do(async e =>
// {
// var stream = e.GetArg("username")?.Trim();
// if (string.IsNullOrWhiteSpace(stream))
// return;
// try
// {
// var streamStatus = (await GetStreamStatus(new StreamNotificationConfig
// {
// Username = stream,
// Type = StreamNotificationConfig.StreamType.Hitbox
// }));
// if (streamStatus.Item1)
// {
// await imsg.Channel.SendMessageAsync($"`Streamer {streamStatus.Item2} is online.`");
// }
// }
// catch
// {
// await imsg.Channel.SendMessageAsync("No channel found.");
// }
// });
// cgb.CreateCommand(Module.Prefix + "checktwitch")
// .Alias(Module.Prefix + "chtw")
// .Description("Checks if a certain user is streaming on the twitch platform." +
// $" | `{Prefix}chtw SomeStreamer`")
// .AddCheck(SimpleCheckers.ManageServer())
// .Parameter("username", ParameterType.Unparsed)
// .Do(async e =>
// {
// var stream = e.GetArg("username")?.Trim();
// if (string.IsNullOrWhiteSpace(stream))
// return;
// try
// {
// var streamStatus = (await GetStreamStatus(new StreamNotificationConfig
// {
// Username = stream,
// Type = StreamNotificationConfig.StreamType.Twitch
// }));
// if (streamStatus.Item1)
// {
// await imsg.Channel.SendMessageAsync($"`Streamer {streamStatus.Item2} is online.`");
// }
// }
// catch
// {
// await imsg.Channel.SendMessageAsync("No channel found.");
// }
// });
// cgb.CreateCommand(Module.Prefix + "checkbeam")
// .Alias(Module.Prefix + "chbm")
// .Description("Checks if a certain user is streaming on the beam platform." +
// $" | `{Prefix}chbm SomeStreamer`")
// .AddCheck(SimpleCheckers.ManageServer())
// .Parameter("username", ParameterType.Unparsed)
// .Do(async e =>
// {
// var stream = e.GetArg("username")?.Trim();
// if (string.IsNullOrWhiteSpace(stream))
// return;
// try
// {
// var streamStatus = (await GetStreamStatus(new StreamNotificationConfig
// {
// Username = stream,
// Type = StreamNotificationConfig.StreamType.Beam
// }));
// if (streamStatus.Item1)
// {
// await imsg.Channel.SendMessageAsync($"`Streamer {streamStatus.Item2} is online.`");
// }
// }
// catch
// {
// await imsg.Channel.SendMessageAsync("No channel found.");
// }
// });
// cgb.CreateCommand(Module.Prefix + "removestream")
// .Alias(Module.Prefix + "rms")
// .Description("Removes notifications of a certain streamer on this channel." +
// $" | `{Prefix}rms SomeGuy`")
// .AddCheck(SimpleCheckers.ManageServer())
// .Parameter("username", ParameterType.Unparsed)
// .Do(async e =>
// {
// var username = e.GetArg("username")?.ToLower().Trim();
// if (string.IsNullOrWhiteSpace(username))
// return;
// var config = SpecificConfigurations.Default.Of(e.Server.Id);
// var toRemove = config.ObservingStreams
// .FirstOrDefault(snc => snc.ChannelId == e.Channel.Id &&
// snc.Username.ToLower().Trim() == username);
// if (toRemove == null)
// {
// await imsg.Channel.SendMessageAsync(":anger: No such stream.").ConfigureAwait(false);
// return;
// }
// config.ObservingStreams.Remove(toRemove);
// await ConfigHandler.SaveConfig().ConfigureAwait(false);
// await imsg.Channel.SendMessageAsync($":ok: Removed `{toRemove.Username}`'s stream from notifications.").ConfigureAwait(false);
// });
// cgb.CreateCommand(Module.Prefix + "liststreams")
// .Alias(Module.Prefix + "ls")
// .Description("Lists all streams you are following on this server." +
// $" | `{Prefix}ls`")
// .Do(async e =>
// {
// var config = SpecificConfigurations.Default.Of(e.Server.Id);
// var streams = config.ObservingStreams.Where(snc =>
// snc.ServerId == e.Server.Id);
// var streamsArray = streams as StreamNotificationConfig[] ?? streams.ToArray();
// if (streamsArray.Length == 0)
// {
// await imsg.Channel.SendMessageAsync("You are not following any streams on this server.").ConfigureAwait(false);
// return;
// }
// var text = string.Join("\n", streamsArray.Select(snc =>
// {
// try
// {
// return $"`{snc.Username}`'s stream on **{e.Server.GetChannel(e.Channel.Id).Name}** channel. 【`{snc.Type.ToString()}`】";
// }
// catch { }
// return "";
// }));
// await imsg.Channel.SendMessageAsync($"You are following **{streamsArray.Length}** streams on this server.\n\n" + text).ConfigureAwait(false);
// });
// }
// private Func<CommandEventArgs, Task> TrackStream(StreamNotificationConfig.StreamType type) =>
// async e =>
// {
// var username = e.GetArg("username")?.ToLowerInvariant();
// if (string.IsNullOrWhiteSpace(username))
// return;
// var config = SpecificConfigurations.Default.Of(e.Server.Id);
// var stream = new StreamNotificationConfig
// {
// ServerId = e.Server.Id,
// ChannelId = e.Channel.Id,
// Username = username,
// Type = type,
// };
// var exists = config.ObservingStreams.Contains(stream);
// if (exists)
// {
// await imsg.Channel.SendMessageAsync(":anger: I am already notifying that stream on this channel.").ConfigureAwait(false);
// return;
// }
// Tuple<bool, string> data;
// try
// {
// data = await GetStreamStatus(stream).ConfigureAwait(false);
// }
// catch
// {
// await imsg.Channel.SendMessageAsync(":anger: Stream probably doesn't exist.").ConfigureAwait(false);
// return;
// }
// var msg = $"Stream is currently **{(data.Item1 ? "ONLINE" : "OFFLINE")}** with **{data.Item2}** viewers";
// if (data.Item1)
// if (type == StreamNotificationConfig.StreamType.Hitbox)
// msg += $"\n`Here is the Link:`【 http://www.hitbox.tv/{stream.Username}/ 】";
// else if (type == StreamNotificationConfig.StreamType.Twitch)
// msg += $"\n`Here is the Link:`【 http://www.twitch.tv/{stream.Username}/ 】";
// else if (type == StreamNotificationConfig.StreamType.Beam)
// msg += $"\n`Here is the Link:`【 https://beam.pro/{stream.Username}/ 】";
// else if (type == StreamNotificationConfig.StreamType.YoutubeGaming)
// msg += $"\n`Here is the Link:` not implemented yet - {stream.Username}";
// stream.LastStatus = data.Item1;
// if (!exists)
// msg = $":ok: I will notify this channel when status changes.\n{msg}";
// await imsg.Channel.SendMessageAsync(msg).ConfigureAwait(false);
// config.ObservingStreams.Add(stream);
// };
// }
// }
//}

View File

@@ -1,344 +0,0 @@
using Discord.Commands;
using NadekoBot.Classes;
using NadekoBot.Classes.JSONModels;
using NadekoBot.Modules.Permissions.Classes;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading.Tasks;
using System.Timers;
namespace NadekoBot.Modules.Searches.Commands
{
internal class StreamNotifications : DiscordCommand
{
private readonly Timer checkTimer = new Timer
{
Interval = new TimeSpan(0, 0, 15).TotalMilliseconds,
};
private ConcurrentDictionary<string, Tuple<bool, string>> cachedStatuses = new ConcurrentDictionary<string, Tuple<bool, string>>();
public StreamNotifications(DiscordModule module) : base(module)
{
checkTimer.Elapsed += async (s, e) =>
{
cachedStatuses.Clear();
try
{
var streams = SpecificConfigurations.Default.AllConfigs.SelectMany(c => c.ObservingStreams);
if (!streams.Any()) return;
foreach (var stream in streams)
{
Tuple<bool, string> data;
try
{
data = await GetStreamStatus(stream).ConfigureAwait(false);
}
catch
{
continue;
}
if (data.Item1 != stream.LastStatus)
{
stream.LastStatus = data.Item1;
var server = NadekoBot.Client.GetServer(stream.ServerId);
var channel = server?.GetChannel(stream.ChannelId);
if (channel == null)
continue;
var msg = $"`{stream.Username}`'s stream is now " +
$"**{(data.Item1 ? "ONLINE" : "OFFLINE")}** with " +
$"**{data.Item2}** viewers.";
if (stream.LastStatus)
if (stream.Type == StreamNotificationConfig.StreamType.Hitbox)
msg += $"\n`Here is the Link:`【 http://www.hitbox.tv/{stream.Username}/ 】";
else if (stream.Type == StreamNotificationConfig.StreamType.Twitch)
msg += $"\n`Here is the Link:`【 http://www.twitch.tv/{stream.Username}/ 】";
else if (stream.Type == StreamNotificationConfig.StreamType.Beam)
msg += $"\n`Here is the Link:`【 http://www.beam.pro/{stream.Username}/ 】";
else if (stream.Type == StreamNotificationConfig.StreamType.YoutubeGaming)
msg += $"\n`Here is the Link:`【 not implemented yet - {stream.Username} 】";
await channel.SendMessage(msg).ConfigureAwait(false);
}
}
}
catch { }
await ConfigHandler.SaveConfig().ConfigureAwait(false);
};
checkTimer.Start();
}
private async Task<Tuple<bool, string>> GetStreamStatus(StreamNotificationConfig stream, bool checkCache = true)
{
bool isLive;
string response;
JObject data;
Tuple<bool, string> result;
switch (stream.Type)
{
case StreamNotificationConfig.StreamType.Hitbox:
var hitboxUrl = $"https://api.hitbox.tv/media/status/{stream.Username}";
if (checkCache && cachedStatuses.TryGetValue(hitboxUrl, out result))
return result;
response = await http.GetStringAsync(hitboxUrl).ConfigureAwait(false);
data = JObject.Parse(response);
isLive = data["media_is_live"].ToString() == "1";
result = new Tuple<bool, string>(isLive, data["media_views"].ToString());
cachedStatuses.TryAdd(hitboxUrl, result);
return result;
case StreamNotificationConfig.StreamType.Twitch:
var twitchUrl = $"https://api.twitch.tv/kraken/streams/{Uri.EscapeUriString(stream.Username)}";
if (checkCache && cachedStatuses.TryGetValue(twitchUrl, out result))
return result;
response = await http.GetStringAsync(twitchUrl).ConfigureAwait(false);
data = JObject.Parse(response);
isLive = !string.IsNullOrWhiteSpace(data["stream"].ToString());
result = new Tuple<bool, string>(isLive, isLive ? data["stream"]["viewers"].ToString() : "0");
cachedStatuses.TryAdd(twitchUrl, result);
return result;
case StreamNotificationConfig.StreamType.Beam:
var beamUrl = $"https://beam.pro/api/v1/channels/{stream.Username}";
if (checkCache && cachedStatuses.TryGetValue(beamUrl, out result))
return result;
response = await http.GetStringAsync(beamUrl).ConfigureAwait(false);
data = JObject.Parse(response);
isLive = data["online"].ToObject<bool>() == true;
result = new Tuple<bool, string>(isLive, data["viewersCurrent"].ToString());
cachedStatuses.TryAdd(beamUrl, result);
return result;
default:
break;
}
return new Tuple<bool, string>(false, "0");
}
internal override void Init(CommandGroupBuilder cgb)
{
cgb.CreateCommand(Module.Prefix + "hitbox")
.Alias(Module.Prefix + "hb")
.Description("Notifies this channel when a certain user starts streaming." +
$" | `{Prefix}hitbox SomeStreamer`")
.Parameter("username", ParameterType.Unparsed)
.AddCheck(SimpleCheckers.ManageServer())
.Do(TrackStream(StreamNotificationConfig.StreamType.Hitbox));
cgb.CreateCommand(Module.Prefix + "twitch")
.Alias(Module.Prefix + "tw")
.Description("Notifies this channel when a certain user starts streaming." +
$" | `{Prefix}twitch SomeStreamer`")
.AddCheck(SimpleCheckers.ManageServer())
.Parameter("username", ParameterType.Unparsed)
.Do(TrackStream(StreamNotificationConfig.StreamType.Twitch));
cgb.CreateCommand(Module.Prefix + "beam")
.Alias(Module.Prefix + "bm")
.Description("Notifies this channel when a certain user starts streaming." +
$" | `{Prefix}beam SomeStreamer`")
.AddCheck(SimpleCheckers.ManageServer())
.Parameter("username", ParameterType.Unparsed)
.Do(TrackStream(StreamNotificationConfig.StreamType.Beam));
cgb.CreateCommand(Module.Prefix + "checkhitbox")
.Alias(Module.Prefix + "chhb")
.Description("Checks if a certain user is streaming on the hitbox platform." +
$" | `{Prefix}chhb SomeStreamer`")
.Parameter("username", ParameterType.Unparsed)
.AddCheck(SimpleCheckers.ManageServer())
.Do(async e =>
{
var stream = e.GetArg("username")?.Trim();
if (string.IsNullOrWhiteSpace(stream))
return;
try
{
var streamStatus = (await GetStreamStatus(new StreamNotificationConfig
{
Username = stream,
Type = StreamNotificationConfig.StreamType.Hitbox
}));
if (streamStatus.Item1)
{
await channel.SendMessageAsync($"`Streamer {streamStatus.Item2} is online.`");
}
}
catch
{
await channel.SendMessageAsync("No channel found.");
}
});
cgb.CreateCommand(Module.Prefix + "checktwitch")
.Alias(Module.Prefix + "chtw")
.Description("Checks if a certain user is streaming on the twitch platform." +
$" | `{Prefix}chtw SomeStreamer`")
.AddCheck(SimpleCheckers.ManageServer())
.Parameter("username", ParameterType.Unparsed)
.Do(async e =>
{
var stream = e.GetArg("username")?.Trim();
if (string.IsNullOrWhiteSpace(stream))
return;
try
{
var streamStatus = (await GetStreamStatus(new StreamNotificationConfig
{
Username = stream,
Type = StreamNotificationConfig.StreamType.Twitch
}));
if (streamStatus.Item1)
{
await channel.SendMessageAsync($"`Streamer {streamStatus.Item2} is online.`");
}
}
catch
{
await channel.SendMessageAsync("No channel found.");
}
});
cgb.CreateCommand(Module.Prefix + "checkbeam")
.Alias(Module.Prefix + "chbm")
.Description("Checks if a certain user is streaming on the beam platform." +
$" | `{Prefix}chbm SomeStreamer`")
.AddCheck(SimpleCheckers.ManageServer())
.Parameter("username", ParameterType.Unparsed)
.Do(async e =>
{
var stream = e.GetArg("username")?.Trim();
if (string.IsNullOrWhiteSpace(stream))
return;
try
{
var streamStatus = (await GetStreamStatus(new StreamNotificationConfig
{
Username = stream,
Type = StreamNotificationConfig.StreamType.Beam
}));
if (streamStatus.Item1)
{
await channel.SendMessageAsync($"`Streamer {streamStatus.Item2} is online.`");
}
}
catch
{
await channel.SendMessageAsync("No channel found.");
}
});
cgb.CreateCommand(Module.Prefix + "removestream")
.Alias(Module.Prefix + "rms")
.Description("Removes notifications of a certain streamer on this channel." +
$" | `{Prefix}rms SomeGuy`")
.AddCheck(SimpleCheckers.ManageServer())
.Parameter("username", ParameterType.Unparsed)
.Do(async e =>
{
var username = e.GetArg("username")?.ToLower().Trim();
if (string.IsNullOrWhiteSpace(username))
return;
var config = SpecificConfigurations.Default.Of(e.Server.Id);
var toRemove = config.ObservingStreams
.FirstOrDefault(snc => snc.ChannelId == e.Channel.Id &&
snc.Username.ToLower().Trim() == username);
if (toRemove == null)
{
await channel.SendMessageAsync(":anger: No such stream.").ConfigureAwait(false);
return;
}
config.ObservingStreams.Remove(toRemove);
await ConfigHandler.SaveConfig().ConfigureAwait(false);
await channel.SendMessageAsync($":ok: Removed `{toRemove.Username}`'s stream from notifications.").ConfigureAwait(false);
});
cgb.CreateCommand(Module.Prefix + "liststreams")
.Alias(Module.Prefix + "ls")
.Description("Lists all streams you are following on this server." +
$" | `{Prefix}ls`")
.Do(async e =>
{
var config = SpecificConfigurations.Default.Of(e.Server.Id);
var streams = config.ObservingStreams.Where(snc =>
snc.ServerId == e.Server.Id);
var streamsArray = streams as StreamNotificationConfig[] ?? streams.ToArray();
if (streamsArray.Length == 0)
{
await channel.SendMessageAsync("You are not following any streams on this server.").ConfigureAwait(false);
return;
}
var text = string.Join("\n", streamsArray.Select(snc =>
{
try
{
return $"`{snc.Username}`'s stream on **{e.Server.GetChannel(e.Channel.Id).Name}** channel. 【`{snc.Type.ToString()}`】";
}
catch { }
return "";
}));
await channel.SendMessageAsync($"You are following **{streamsArray.Length}** streams on this server.\n\n" + text).ConfigureAwait(false);
});
}
private Func<CommandEventArgs, Task> TrackStream(StreamNotificationConfig.StreamType type) =>
async e =>
{
var username = e.GetArg("username")?.ToLowerInvariant();
if (string.IsNullOrWhiteSpace(username))
return;
var config = SpecificConfigurations.Default.Of(e.Server.Id);
var stream = new StreamNotificationConfig
{
ServerId = e.Server.Id,
ChannelId = e.Channel.Id,
Username = username,
Type = type,
};
var exists = config.ObservingStreams.Contains(stream);
if (exists)
{
await channel.SendMessageAsync(":anger: I am already notifying that stream on this channel.").ConfigureAwait(false);
return;
}
Tuple<bool, string> data;
try
{
data = await GetStreamStatus(stream).ConfigureAwait(false);
}
catch
{
await channel.SendMessageAsync(":anger: Stream probably doesn't exist.").ConfigureAwait(false);
return;
}
var msg = $"Stream is currently **{(data.Item1 ? "ONLINE" : "OFFLINE")}** with **{data.Item2}** viewers";
if (data.Item1)
if (type == StreamNotificationConfig.StreamType.Hitbox)
msg += $"\n`Here is the Link:`【 http://www.hitbox.tv/{stream.Username}/ 】";
else if (type == StreamNotificationConfig.StreamType.Twitch)
msg += $"\n`Here is the Link:`【 http://www.twitch.tv/{stream.Username}/ 】";
else if (type == StreamNotificationConfig.StreamType.Beam)
msg += $"\n`Here is the Link:`【 https://beam.pro/{stream.Username}/ 】";
else if (type == StreamNotificationConfig.StreamType.YoutubeGaming)
msg += $"\n`Here is the Link:` not implemented yet - {stream.Username}";
stream.LastStatus = data.Item1;
if (!exists)
msg = $":ok: I will notify this channel when status changes.\n{msg}";
await channel.SendMessageAsync(msg).ConfigureAwait(false);
config.ObservingStreams.Add(stream);
};
}
}

View File

@@ -1,36 +0,0 @@
using Discord.Commands;
using NadekoBot.Classes;
using NadekoBot.Classes.JSONModels;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace NadekoBot.Modules.Searches.Commands
{
class WowJokeCommand : DiscordCommand
{
List<WoWJoke> jokes = new List<WoWJoke>();
public WowJokeCommand(DiscordModule module) : base(module)
{
}
internal override void Init(CommandGroupBuilder cgb)
{
cgb.CreateCommand(Module.Prefix + "wowjoke")
.Description($"Get one of Kwoth's penultimate WoW jokes. | `{Prefix}wowjoke`")
.Do(async e =>
{
if (!jokes.Any())
{
jokes = JsonConvert.DeserializeObject<List<WoWJoke>>(File.ReadAllText("data/wowjokes.json"));
}
await channel.SendMessageAsync(jokes[new Random().Next(0, jokes.Count)].ToString());
});
}
}
}

View File

@@ -14,6 +14,9 @@ using NadekoBot.Attributes;
using NadekoBot.Extensions;
using Discord.API;
using System.Text.RegularExpressions;
using System.Net;
using NadekoBot.Modules.Searches.Commands.Models;
using Google.Apis.YouTube.v3;
namespace NadekoBot.Modules.Searches
{
@@ -22,9 +25,12 @@ namespace NadekoBot.Modules.Searches
{
private readonly Random rng;
public SearchesModule(ILocalization loc, CommandService cmds, IBotConfiguration config, IDiscordClient client) : base(loc, cmds, config, client)
private IYoutubeService _yt { get; }
public SearchesModule(ILocalization loc, CommandService cmds, IBotConfiguration config, IDiscordClient client, IYoutubeService youtube) : base(loc, cmds, config, client)
{
rng = new Random();
_yt = youtube;
}
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
@@ -54,59 +60,16 @@ $@"🌍 **Weather for** 【{obj["target"]}】
{
var channel = imsg.Channel as IGuildChannel;
if (!(await ValidateQuery(imsg.Channel as ITextChannel, query).ConfigureAwait(false))) return;
var link = await FindYoutubeUrlByKeywords(query).ConfigureAwait(false);
if (string.IsNullOrWhiteSpace(link))
var result = (await _yt.FindVideosByKeywordsAsync(query, 1)).FirstOrDefault();
if (string.IsNullOrWhiteSpace(result))
{
await imsg.Channel.SendMessageAsync("No results found for that query.");
return;
}
var shortUrl = await link.ShortenUrl().ConfigureAwait(false);
var shortUrl = await result.ShortenUrl().ConfigureAwait(false);
await imsg.Channel.SendMessageAsync(shortUrl).ConfigureAwait(false);
}
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
[RequireContext(ContextType.Guild)]
public async Task Anime(IMessage imsg, [Remainder] string query)
{
var channel = imsg.Channel as IGuildChannel;
if (!(await ValidateQuery(imsg.Channel as ITextChannel, query).ConfigureAwait(false))) return;
string result;
try
{
result = (await GetAnimeData(query).ConfigureAwait(false)).ToString();
}
catch
{
await imsg.Channel.SendMessageAsync("Failed to find that anime.").ConfigureAwait(false);
return;
}
await imsg.Channel.SendMessageAsync(result.ToString()).ConfigureAwait(false);
}
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
[RequireContext(ContextType.Guild)]
public async Task Manga(IMessage imsg, [Remainder] string query)
{
var channel = imsg.Channel as IGuildChannel;
if (!(await ValidateQuery(imsg.Channel as ITextChannel, query).ConfigureAwait(false))) return;
string result;
try
{
result = (await GetMangaData(query).ConfigureAwait(false)).ToString();
}
catch
{
await imsg.Channel.SendMessageAsync("Failed to find that manga.").ConfigureAwait(false);
return;
}
await imsg.Channel.SendMessageAsync(result).ConfigureAwait(false);
}
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
[RequireContext(ContextType.Guild)]
public async Task Imdb(IMessage imsg, [Remainder] string query)
@@ -114,11 +77,11 @@ $@"🌍 **Weather for** 【{obj["target"]}】
var channel = imsg.Channel as IGuildChannel;
if (!(await ValidateQuery(imsg.Channel as ITextChannel, query).ConfigureAwait(false))) return;
await e.Channel.SendIsTyping().ConfigureAwait(false);
await imsg.Channel.TriggerTypingAsync().ConfigureAwait(false);
string result;
try
{
var movie = ImdbScraper.ImdbScrape(query, true);
var movie = await ImdbScraper.ImdbScrape(query, true);
if (movie.Status) result = movie.ToString();
else result = "Failed to find that movie.";
}
@@ -240,55 +203,54 @@ $@"🌍 **Weather for** 【{obj["target"]}】
terms = terms?.Trim();
if (string.IsNullOrWhiteSpace(terms))
return;
await imsg.Channel.SendMessageAsync($"https://google.com/search?q={ HttpUtility.UrlEncode(terms).Replace(' ', '+') }")
await imsg.Channel.SendMessageAsync($"https://google.com/search?q={ WebUtility.UrlEncode(terms).Replace(' ', '+') }")
.ConfigureAwait(false);
}
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
[RequireContext(ContextType.Guild)]
public async Task Hearthstone(IMessage imsg, [Remainder] string name)
{
var channel = imsg.Channel as IGuildChannel;
var arg = e.GetArg("name");
if (string.IsNullOrWhiteSpace(arg))
{
await imsg.Channel.SendMessageAsync("💢 Please enter a card name to search for.").ConfigureAwait(false);
return;
}
await imsg.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)}", headers)
.ConfigureAwait(false);
try
{
var items = JArray.Parse(response);
var images = new List<Image>();
if (items == null)
throw new KeyNotFoundException("Cannot find a card by that name");
var cnt = 0;
items.Shuffle();
foreach (var item in items.TakeWhile(item => cnt++ < 4).Where(item => item.HasValues && item["img"] != null))
{
images.Add(
Image.FromStream(await http.GetStreamAsync(item["img"].ToString()).ConfigureAwait(false)));
}
if (items.Count > 4)
{
await imsg.Channel.SendMessageAsync("⚠ Found over 4 images. Showing random 4.").ConfigureAwait(false);
}
await imsg.Channel.SendMessageAsync(arg + ".png", (await images.MergeAsync()).ToStream(System.Drawing.Imaging.ImageFormat.Png))
.ConfigureAwait(false);
}
catch (Exception ex)
{
await imsg.Channel.SendMessageAsync($"💢 Error {ex.Message}").ConfigureAwait(false);
}
}
}
////todo drawing
//[LocalizedCommand, LocalizedDescription, LocalizedSummary]
//[RequireContext(ContextType.Guild)]
//public async Task Hearthstone(IMessage imsg, [Remainder] string name)
//{
// var channel = imsg.Channel as IGuildChannel;
// var arg = e.GetArg("name");
// if (string.IsNullOrWhiteSpace(arg))
// {
// await imsg.Channel.SendMessageAsync("💢 Please enter a card name to search for.").ConfigureAwait(false);
// return;
// }
// await imsg.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)}", headers)
// .ConfigureAwait(false);
// try
// {
// var items = JArray.Parse(response).Shuffle().ToList();
// var images = new List<Image>();
// if (items == null)
// throw new KeyNotFoundException("Cannot find a card by that name");
// var cnt = 0;
// foreach (var item in items.TakeWhile(item => cnt++ < 4).Where(item => item.HasValues && item["img"] != null))
// {
// images.Add(
// Image.FromStream(await http.GetStreamAsync(item["img"].ToString()).ConfigureAwait(false)));
// }
// if (items.Count > 4)
// {
// await imsg.Channel.SendMessageAsync("⚠ Found over 4 images. Showing random 4.").ConfigureAwait(false);
// }
// await imsg.Channel.SendMessageAsync(arg + ".png", (await images.MergeAsync()).ToStream(System.Drawing.Imaging.ImageFormat.Png))
// .ConfigureAwait(false);
// }
// catch (Exception ex)
// {
// await imsg.Channel.SendMessageAsync($"💢 Error {ex.Message}").ConfigureAwait(false);
// }
// }
//}
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
[RequireContext(ContextType.Guild)]
@@ -307,7 +269,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】
{
http.DefaultRequestHeaders.Clear();
http.DefaultRequestHeaders.Add("X-Mashape-Key", NadekoBot.Credentials.MashapeKey);
var res = await http.GetStringAsync($"https://mashape-community-urban-dictionary.p.mashape.com/define?term={Uri.EscapeUriString(arg)}", headers).ConfigureAwait(false);
var res = await http.GetStringAsync($"https://mashape-community-urban-dictionary.p.mashape.com/define?term={Uri.EscapeUriString(arg)}").ConfigureAwait(false);
try
{
var items = JObject.Parse(res);
@@ -350,7 +312,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】
var items = JObject.Parse(res);
var str = $@"`Hashtag:` {items["defs"]["def"]["hashtag"].ToString()}
`Definition:` {items["defs"]["def"]["text"].ToString()}
`Link:` <{await items["defs"]["def"]["uri"].ToString().ShortenUrl().ConfigureAwait(false)}>");
`Link:` <{await items["defs"]["def"]["uri"].ToString().ShortenUrl().ConfigureAwait(false)}>";
await imsg.Channel.SendMessageAsync(str);
}
catch
@@ -358,16 +320,16 @@ $@"🌍 **Weather for** 【{obj["target"]}】
await imsg.Channel.SendMessageAsync("💢 Failed finding a definition for that tag.").ConfigureAwait(false);
}
}
//todo DB
//[LocalizedCommand, LocalizedDescription, LocalizedSummary]
//[RequireContext(ContextType.Guild)]
//public async Task Quote(IMessage imsg)
//{
// var channel = imsg.Channel as IGuildChannel;
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
[RequireContext(ContextType.Guild)]
public async Task Quote(IMessage imsg)
{
var channel = imsg.Channel as IGuildChannel;
var quote = NadekoBot.Config.Quotes[rng.Next(0, NadekoBot.Config.Quotes.Count)].ToString();
await imsg.Channel.SendMessageAsync(quote).ConfigureAwait(false);
}
// var quote = NadekoBot.Config.Quotes[rng.Next(0, NadekoBot.Config.Quotes.Count)].ToString();
// await imsg.Channel.SendMessageAsync(quote).ConfigureAwait(false);
//}
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
[RequireContext(ContextType.Guild)]
@@ -383,54 +345,6 @@ $@"🌍 **Weather for** 【{obj["target"]}】
}
}
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
[RequireContext(ContextType.Guild)]
public async Task Yomama(IMessage imsg)
{
var channel = imsg.Channel as IGuildChannel;
using (var http = new HttpClient())
{
var response = await http.GetStringAsync("http://api.yomomma.info/").ConfigureAwait(false);
await imsg.Channel.SendMessageAsync("`" + JObject.Parse(response)["joke"].ToString() + "` 😆").ConfigureAwait(false);
}
}
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
[RequireContext(ContextType.Guild)]
public async Task Randjoke(IMessage imsg)
{
var channel = imsg.Channel as IGuildChannel;
using (var http = new HttpClient())
{
var response = await http.GetStringAsync("http://tambal.azurewebsites.net/joke/random").ConfigureAwait(false);
await imsg.Channel.SendMessageAsync("`" + JObject.Parse(response)["joke"].ToString() + "` 😆").ConfigureAwait(false);
}
}
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
[RequireContext(ContextType.Guild)]
public async Task ChuckNorris(IMessage imsg)
{
var channel = imsg.Channel as IGuildChannel;
using (var http = new HttpClient())
{
var response = await http.GetStringAsync("http://tambal.azurewebsites.net/joke/random").ConfigureAwait(false);
await imsg.Channel.SendMessageAsync("`" + JObject.Parse(response)["joke"].ToString() + "` 😆").ConfigureAwait(false);
}
}
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
[RequireContext(ContextType.Guild)]
public async Task MagicItem(IMessage imsg)
{
var channel = imsg.Channel as IGuildChannel;
var magicItems = JsonConvert.DeserializeObject<List<MagicItem>>(File.ReadAllText("data/magicitems.json"));
var item = magicItems[rng.Next(0, magicItems.Count)].ToString();
await imsg.Channel.SendMessageAsync(item).ConfigureAwait(false);
}
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
[RequireContext(ContextType.Guild)]
public async Task Revav(IMessage imsg, [Remainder] string arg)
@@ -494,30 +408,31 @@ $@"🌍 **Weather for** 【{obj["target"]}】
}
}
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
[RequireContext(ContextType.Guild)]
public async Task Clr(IMessage imsg, [Remainder] string color)
{
var channel = imsg.Channel as IGuildChannel;
////todo Drawing
//[LocalizedCommand, LocalizedDescription, LocalizedSummary]
//[RequireContext(ContextType.Guild)]
//public async Task Clr(IMessage imsg, [Remainder] string color)
//{
// var channel = imsg.Channel as IGuildChannel;
var arg1 = e.GetArg("color")?.Trim()?.Replace("#", "");
if (string.IsNullOrWhiteSpace(arg1))
return;
var img = new Bitmap(50, 50);
// color = color?.Trim().Replace("#", "");
// if (string.IsNullOrWhiteSpace((string)color))
// return;
// var img = new Bitmap(50, 50);
var red = Convert.ToInt32(arg1.Substring(0, 2), 16);
var green = Convert.ToInt32(arg1.Substring(2, 2), 16);
var blue = Convert.ToInt32(arg1.Substring(4, 2), 16);
var brush = new SolidBrush(System.Drawing.Color.FromArgb(red, green, blue));
// var red = Convert.ToInt32(color.Substring(0, 2), 16);
// var green = Convert.ToInt32(color.Substring(2, 2), 16);
// var blue = Convert.ToInt32(color.Substring(4, 2), 16);
// var brush = new SolidBrush(System.Drawing.Color.FromArgb(red, green, blue));
using (Graphics g = Graphics.FromImage(img))
{
g.FillRectangle(brush, 0, 0, 50, 50);
g.Flush();
}
// using (Graphics g = Graphics.FromImage(img))
// {
// g.FillRectangle(brush, 0, 0, 50, 50);
// g.Flush();
// }
await imsg.Channel.SendFileAsync("arg1.png", img.ToStream());
}
// await imsg.Channel.SendFileAsync("arg1.png", img.ToStream());
//}
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
[RequireContext(ContextType.Guild)]

View File

@@ -1,94 +1,23 @@
// Copyright (c) 2015 Ravi Bhavnani
// License: Code Project Open License
// http://www.codeproject.com/info/cpol10.aspx
using Newtonsoft.Json.Linq;
using System;
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web;
namespace NadekoBot.Modules.Translator.Helpers
namespace NadekoBot.Modules.Translator
{
/// <summary>
/// Translates text using Google's online language tools.
/// </summary>
public class GoogleTranslator
{
#region Properties
private static GoogleTranslator _instance;
public static GoogleTranslator Instance = _instance ?? (_instance = new GoogleTranslator());
/// <summary>
/// Gets the supported languages.
/// </summary>
public static IEnumerable<string> Languages {
get {
GoogleTranslator.EnsureInitialized();
return GoogleTranslator._languageModeMap.Keys.OrderBy(p => p);
}
}
#endregion
public IEnumerable<string> Languages => _languageDictionary.Keys.OrderBy(x => x);
private Dictionary<string, string> _languageDictionary;
#region Public methods
/// <summary>
/// Translates the specified source text.
/// </summary>
/// <param name="sourceText">The source text.</param>
/// <param name="sourceLanguage">The source language.</param>
/// <param name="targetLanguage">The target language.</param>
/// <returns>The translation.</returns>
public async Task<string> Translate
(string sourceText,
string sourceLanguage,
string targetLanguage)
{
// Initialize
DateTime tmStart = DateTime.Now;
string text = string.Empty;
// Download translation
string url = string.Format("https://translate.googleapis.com/translate_a/single?client=gtx&sl={0}&tl={1}&dt=t&q={2}",
GoogleTranslator.LanguageEnumToIdentifier(sourceLanguage),
GoogleTranslator.LanguageEnumToIdentifier(targetLanguage),
HttpUtility.UrlEncode(sourceText));
using (HttpClient 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);
}
return (string.Concat(JArray.Parse(text)[0].Select(x => x[0])));
}
#endregion
#region Private methods
/// <summary>
/// Converts a language to its identifier.
/// </summary>
/// <param name="language">The language."</param>
/// <returns>The identifier or <see cref="string.Empty"/> if none.</returns>
private static string LanguageEnumToIdentifier
(string language)
{
string mode = string.Empty;
GoogleTranslator.EnsureInitialized();
GoogleTranslator._languageModeMap.TryGetValue(language, out mode);
return mode;
}
/// <summary>
/// Ensures the translator has been initialized.
/// </summary>
public static void EnsureInitialized()
{
if (GoogleTranslator._languageModeMap == null)
{
GoogleTranslator._languageModeMap = new Dictionary<string, string>() {
static GoogleTranslator() { }
private GoogleTranslator() {
_languageDictionary = new Dictionary<string, string>() {
{ "afrikaans", "af"},
{ "albanian", "sq"},
{ "arabic", "ar"},
@@ -99,6 +28,8 @@ namespace NadekoBot.Modules.Translator.Helpers
{ "bengali", "bn"},
{ "bulgarian", "bg"},
{ "catalan", "ca"},
{ "chinese-traditional", "zh-TW"},
{ "chinese-simplified", "zh-CN"},
{ "chinese", "zh-CN"},
{ "croatian", "hr"},
{ "czech", "cs"},
@@ -217,18 +148,30 @@ namespace NadekoBot.Modules.Translator.Helpers
{ "cy", "cy"},
{ "yi", "yi"},
};
}
}
#endregion
public async Task<string> Translate(string sourceText, string sourceLanguage, string targetLanguage)
{
string text = string.Empty;
#region Fields
string 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())
{
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);
}
/// <summary>
/// The language to translation mode map.
/// </summary>
public static Dictionary<string, string> _languageModeMap;
return (string.Concat(JArray.Parse(text)[0].Select(x => x[0])));
}
#endregion
private string ConvertToLanguageCode(string language)
{
string mode = string.Empty;
_languageDictionary.TryGetValue(language, out mode);
return mode;
}
}
}

View File

@@ -1,45 +0,0 @@
using Discord.Commands;
using NadekoBot.Classes;
using NadekoBot.Modules.Translator.Helpers;
using System;
using System.Threading.Tasks;
namespace NadekoBot.Modules.Translator
{
class TranslateCommand : DiscordCommand
{
public TranslateCommand(DiscordModule module) : base(module) { }
internal override void Init(CommandGroupBuilder cgb)
{
cgb.CreateCommand(Module.Prefix + "translate")
.Alias(Module.Prefix + "trans")
.Description($"Translates from>to text. From the given language to the destiation language. | `{Module.Prefix}trans en>fr Hello`")
.Parameter("langs", ParameterType.Required)
.Parameter("text", ParameterType.Unparsed)
.Do(TranslateFunc());
}
private GoogleTranslator t = new GoogleTranslator();
private Func<CommandEventArgs, Task> TranslateFunc() => async e =>
{
try
{
await e.Channel.SendIsTyping().ConfigureAwait(false);
string from = e.GetArg("langs").ToLowerInvariant().Split('>')[0];
string to = e.GetArg("langs").ToLowerInvariant().Split('>')[1];
var text = e.GetArg("text")?.Trim();
if (string.IsNullOrWhiteSpace(text))
return;
string translation = await t.Translate(text, from, to).ConfigureAwait(false);
await channel.SendMessageAsync(translation).ConfigureAwait(false);
}
catch (Exception ex)
{
Console.WriteLine(ex);
await channel.SendMessageAsync("Bad input format, or something went wrong...").ConfigureAwait(false);
}
};
}
}

View File

@@ -1,26 +1,54 @@
using Discord.Modules;
using Discord;
using Discord.Commands;
using NadekoBot.Attributes;
using NadekoBot.Extensions;
using NadekoBot.Modules.Permissions.Classes;
using System;
using System.Threading.Tasks;
using NadekoBot.Services;
namespace NadekoBot.Modules.Translator
{
internal class TranslatorModule : DiscordModule
public class TranslatorModule : DiscordModule
{
public TranslatorModule()
public TranslatorModule(ILocalization loc, CommandService cmds, IBotConfiguration config, IDiscordClient client) : base(loc, cmds, config, client)
{
commands.Add(new TranslateCommand(this));
commands.Add(new ValidLanguagesCommand(this));
}
public override string Prefix { get; } = NadekoBot.Config.CommandPrefixes.Searches;
public override void Install(ModuleManager manager)
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
[RequireContext(ContextType.Guild)]
public async Task Translate(IMessage imsg, string langs, [Remainder] string text)
{
manager.CreateCommands("", cgb =>
var channel = imsg.Channel as IGuildChannel;
try
{
cgb.AddCheck(PermissionChecker.Instance);
commands.ForEach(cmd => cmd.Init(cgb));
});
var langarr = langs.ToLowerInvariant().Split('>');
if (langarr.Length != 2)
return;
string from = langarr[0];
string to = langarr[1];
text = text?.Trim();
if (string.IsNullOrWhiteSpace(text))
return;
await imsg.Channel.TriggerTypingAsync().ConfigureAwait(false);
string translation = await GoogleTranslator.Instance.Translate(text, from, to).ConfigureAwait(false);
await imsg.Channel.SendMessageAsync(translation).ConfigureAwait(false);
}
catch (Exception ex)
{
Console.WriteLine(ex);
await imsg.Channel.SendMessageAsync("Bad input format, or something went wrong...").ConfigureAwait(false);
}
}
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
[RequireContext(ContextType.Guild)]
public async Task Translangs(IMessage imsg)
{
var channel = imsg.Channel as IGuildChannel;
await imsg.Channel.SendTableAsync(GoogleTranslator.Instance.Languages, str => str, columns: 4);
}
}

View File

@@ -19,31 +19,6 @@ namespace NadekoBot.Modules.Translator
}
private Func<CommandEventArgs, Task> ListLanguagesFunc() => async e =>
{
try
{
GoogleTranslator.EnsureInitialized();
string s = e.GetArg("search");
string ret = "";
foreach (string key in GoogleTranslator._languageModeMap.Keys)
{
if (!s.Equals(""))
{
if (key.ToLower().Contains(s))
{
ret += " " + key + ";";
}
}
else
{
ret += " " + key + ";";
}
}
await channel.SendMessageAsync(ret).ConfigureAwait(false);
}
catch
{
await channel.SendMessageAsync("Bad input format, or sth went wrong...").ConfigureAwait(false);
}
};
}

View File

@@ -113,7 +113,7 @@
// if (ch == null)
// {
// await channel.SendMessageAsync($"{e.User.Mention} Something went wrong (channel cannot be found) ;(").ConfigureAwait(false);
// await imsg.Channel.SendMessageAsync($"{e.User.Mention} Something went wrong (channel cannot be found) ;(").ConfigureAwait(false);
// return;
// }
@@ -123,7 +123,7 @@
// if (m.Length == 0)
// {
// await channel.SendMessageAsync("Not a valid time format blablabla").ConfigureAwait(false);
// await imsg.Channel.SendMessageAsync("Not a valid time format blablabla").ConfigureAwait(false);
// return;
// }
@@ -148,7 +148,7 @@
// (groupName == "hours" && value > 23) ||
// (groupName == "minutes" && value > 59))
// {
// await channel.SendMessageAsync($"Invalid {groupName} value.").ConfigureAwait(false);
// await imsg.Channel.SendMessageAsync($"Invalid {groupName} value.").ConfigureAwait(false);
// return;
// }
// else
@@ -175,7 +175,7 @@
// reminders.Add(StartNewReminder(rem));
// await channel.SendMessageAsync($"⏰ I will remind \"{ch.Name}\" to \"{e.GetArg("message").ToString()}\" in {output}. ({time:d.M.yyyy.} at {time:HH:mm})").ConfigureAwait(false);
// await imsg.Channel.SendMessageAsync($"⏰ I will remind \"{ch.Name}\" to \"{e.GetArg("message").ToString()}\" in {output}. ({time:d.M.yyyy.} at {time:HH:mm})").ConfigureAwait(false);
// });
// cgb.CreateCommand(Module.Prefix + "remindmsg")
// .Description("Sets message for when the remind is triggered. " +
@@ -190,7 +190,7 @@
// return;
// NadekoBot.Config.RemindMessageFormat = arg;
// await channel.SendMessageAsync("`New remind message set.`");
// await imsg.Channel.SendMessageAsync("`New remind message set.`");
// });
// }
// }

View File

@@ -138,7 +138,7 @@ namespace NadekoBot.Modules.Utility
if (string.IsNullOrWhiteSpace(target))
{
var enumerable = (await msg.Channel.GetMessagesAsync(limit: 100)).Where(x => x.Author.Id == user.Id);
var enumerable = (await msg.Channel.GetMessagesAsync()).Where(x => x.Author.Id == user.Id);
await msg.Channel.DeleteMessagesAsync(enumerable);
return;
}
@@ -156,6 +156,7 @@ namespace NadekoBot.Modules.Utility
int limit = (count < 100) ? count : 100;
var enumerable = (await msg.Channel.GetMessagesAsync(limit: limit));
await msg.Channel.DeleteMessagesAsync(enumerable);
await Task.Delay(1000); // there is a 1 per second per guild ratelimit for deletemessages
if (enumerable.Count < limit) break;
count -= limit;
}
@@ -181,8 +182,14 @@ namespace NadekoBot.Modules.Utility
{
toDel.AddRange(messages.Where(m => m.Author.Id == mention.Id));
}
//TODO check if limit == 100 or there is no limit
await msg.Channel.DeleteMessagesAsync(toDel);
var messagesEnum = messages.AsEnumerable();
while (messagesEnum.Count() > 0)
{
await msg.Channel.DeleteMessagesAsync(messagesEnum.Take(100));
await Task.Delay(1000); // 1 second ratelimit
messagesEnum = messagesEnum.Skip(100);
}
}
}
}