Made events run async where needed, fixed .startevent flowerreaction and running commands in DMs

This commit is contained in:
Master Kwoth 2017-06-06 00:46:58 +02:00
parent ec5a5c42a9
commit fa29131818
26 changed files with 1089 additions and 931 deletions

View File

@ -0,0 +1,34 @@
[16:25-2017-06-05]
System.Net.Http.HttpRequestException: An error occurred while sending the request. ---> System.Net.Http.WinHttpException: The server name or address could not be resolved
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Net.Http.WinHttpHandler.<StartRequest>d__105.MoveNext()
--- End of inner exception stack trace ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Net.Http.HttpClient.<FinishSendAsync>d__58.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Net.Http.HttpClient.<GetContentAsync>d__32`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
at NadekoBot.Modules.Searches.Searches.JokeCommands.<Randjoke>d__3.MoveNext() in C:\Users\Kwoth\Documents\projekti\NadekoBot1.0\src\NadekoBot\Modules\Searches\Commands\JokeCommands.cs:line 40
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Discord.Commands.ModuleClassBuilder.<>c__DisplayClass6_1.<<BuildCommand>b__1>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Discord.Commands.CommandInfo.<ExecuteAsyncInternal>d__38.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Discord.Commands.CommandInfo.<ExecuteAsyncInternal>d__38.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Discord.Commands.CommandInfo.<ExecuteAsync>d__37.MoveNext()
------

View File

@ -16,8 +16,6 @@ namespace NadekoBot.Modules.Administration
[Group] [Group]
public class LocalizationCommands : NadekoSubmodule public class LocalizationCommands : NadekoSubmodule
{ {
//Română, România
//Bahasa Indonesia, Indonesia
private static ImmutableDictionary<string, string> supportedLocales { get; } = new Dictionary<string, string>() private static ImmutableDictionary<string, string> supportedLocales { get; } = new Dictionary<string, string>()
{ {
{"ar", "العربية" }, {"ar", "العربية" },

View File

@ -255,7 +255,7 @@ namespace NadekoBot.Modules.Gambling
return Task.CompletedTask; return Task.CompletedTask;
if ((msg.Author.Id == _client.CurrentUser.Id) || !(imsg.Channel is ITextChannel) || imsg.Channel != _raceChannel) if ((msg.Author.Id == _client.CurrentUser.Id) || !(imsg.Channel is ITextChannel) || imsg.Channel != _raceChannel)
return Task.CompletedTask; return Task.CompletedTask;
_messagesSinceGameStarted++; Interlocked.Increment(ref _messagesSinceGameStarted);
return Task.CompletedTask; return Task.CompletedTask;
} }

View File

@ -194,10 +194,10 @@ namespace NadekoBot.Modules.Gambling
StartingMessage = umsg; StartingMessage = umsg;
_client.MessageDeleted += MessageDeletedEventHandler; _client.MessageDeleted += MessageDeletedEventHandler;
try { await StartingMessage.AddReactionAsync(Emote.Parse("🌸")).ConfigureAwait(false); } try { await StartingMessage.AddReactionAsync(new Emoji("🌸")).ConfigureAwait(false); }
catch catch
{ {
try { await StartingMessage.AddReactionAsync(Emote.Parse("🌸")).ConfigureAwait(false); } try { await StartingMessage.AddReactionAsync(new Emoji("🌸")).ConfigureAwait(false); }
catch catch
{ {
try { await StartingMessage.DeleteAsync().ConfigureAwait(false); } try { await StartingMessage.DeleteAsync().ConfigureAwait(false); }

View File

@ -186,101 +186,105 @@ $@"--
private async Task PotentialAcro(SocketMessage arg) private async Task PotentialAcro(SocketMessage arg)
{ {
try await Task.Yield();
var _ = Task.Run(async () =>
{ {
var msg = arg as SocketUserMessage; try
if (msg == null || msg.Author.IsBot || msg.Channel.Id != _channel.Id)
return;
++_spamCount;
var guildUser = (IGuildUser)msg.Author;
var input = msg.Content.ToUpperInvariant().Trim();
if (phase == AcroPhase.Submitting)
{ {
if (_spamCount > 10) var msg = arg as SocketUserMessage;
{ if (msg == null || msg.Author.IsBot || msg.Channel.Id != _channel.Id)
_spamCount = 0;
try { await _channel.EmbedAsync(GetEmbed()).ConfigureAwait(false); }
catch { }
}
var inputWords = input.Split(' '); //get all words
if (inputWords.Length != _startingLetters.Length) // number of words must be the same as the number of the starting letters
return; return;
for (int i = 0; i < _startingLetters.Length; i++) ++_spamCount;
{
var letter = _startingLetters[i];
if (!inputWords[i].StartsWith(letter.ToString())) // all first letters must match var guildUser = (IGuildUser)msg.Author;
var input = msg.Content.ToUpperInvariant().Trim();
if (phase == AcroPhase.Submitting)
{
if (_spamCount > 10)
{
_spamCount = 0;
try { await _channel.EmbedAsync(GetEmbed()).ConfigureAwait(false); }
catch { }
}
var inputWords = input.Split(' '); //get all words
if (inputWords.Length != _startingLetters.Length) // number of words must be the same as the number of the starting letters
return; return;
}
for (int i = 0; i < _startingLetters.Length; i++)
{
var letter = _startingLetters[i];
if (!inputWords[i].StartsWith(letter.ToString())) // all first letters must match
return;
}
if (!_usersWhoSubmitted.Add(guildUser.Id)) if (!_usersWhoSubmitted.Add(guildUser.Id))
return;
//try adding it to the list of answers
if (!_submissions.TryAdd(input, guildUser))
{
_usersWhoSubmitted.TryRemove(guildUser.Id);
return;
}
// all good. valid input. answer recorded
await _channel.SendConfirmAsync(GetText("acrophobia"),
GetText("acro_submit", guildUser.Mention,
_submissions.Count));
try
{
await msg.DeleteAsync();
}
catch
{
await msg.DeleteAsync(); //try twice
}
}
else if (phase == AcroPhase.Voting)
{
if (_spamCount > 10)
{
_spamCount = 0;
try { await _channel.EmbedAsync(GetEmbed()).ConfigureAwait(false); }
catch { }
}
//if (submissions.TryGetValue(input, out usr) && usr.Id != guildUser.Id)
//{
// if (!usersWhoVoted.Add(guildUser.Id))
// return;
// votes.AddOrUpdate(input, 1, (key, old) => ++old);
// await channel.SendConfirmAsync("Acrophobia", $"{guildUser.Mention} cast their vote!").ConfigureAwait(false);
// await msg.DeleteAsync().ConfigureAwait(false);
// return;
//}
int num;
if (int.TryParse(input, out num) && num > 0 && num <= _submissions.Count)
{
var kvp = _submissions.Skip(num - 1).First();
var usr = kvp.Value;
//can't vote for yourself, can't vote multiple times
if (usr.Id == guildUser.Id || !_usersWhoVoted.Add(guildUser.Id))
return; return;
_votes.AddOrUpdate(kvp.Key, 1, (key, old) => ++old); //try adding it to the list of answers
if (!_submissions.TryAdd(input, guildUser))
{
_usersWhoSubmitted.TryRemove(guildUser.Id);
return;
}
// all good. valid input. answer recorded
await _channel.SendConfirmAsync(GetText("acrophobia"), await _channel.SendConfirmAsync(GetText("acrophobia"),
GetText("acro_vote_cast", Format.Bold(guildUser.ToString()))).ConfigureAwait(false); GetText("acro_submit", guildUser.Mention,
await msg.DeleteAsync().ConfigureAwait(false); _submissions.Count));
try
{
await msg.DeleteAsync();
}
catch
{
await msg.DeleteAsync(); //try twice
}
} }
else if (phase == AcroPhase.Voting)
{
if (_spamCount > 10)
{
_spamCount = 0;
try { await _channel.EmbedAsync(GetEmbed()).ConfigureAwait(false); }
catch { }
}
//if (submissions.TryGetValue(input, out usr) && usr.Id != guildUser.Id)
//{
// if (!usersWhoVoted.Add(guildUser.Id))
// return;
// votes.AddOrUpdate(input, 1, (key, old) => ++old);
// await channel.SendConfirmAsync("Acrophobia", $"{guildUser.Mention} cast their vote!").ConfigureAwait(false);
// await msg.DeleteAsync().ConfigureAwait(false);
// return;
//}
int num;
if (int.TryParse(input, out num) && num > 0 && num <= _submissions.Count)
{
var kvp = _submissions.Skip(num - 1).First();
var usr = kvp.Value;
//can't vote for yourself, can't vote multiple times
if (usr.Id == guildUser.Id || !_usersWhoVoted.Add(guildUser.Id))
return;
_votes.AddOrUpdate(kvp.Key, 1, (key, old) => ++old);
await _channel.SendConfirmAsync(GetText("acrophobia"),
GetText("acro_vote_cast", Format.Bold(guildUser.ToString()))).ConfigureAwait(false);
await msg.DeleteAsync().ConfigureAwait(false);
}
}
} }
} catch (Exception ex)
catch (Exception ex) {
{ _log.Warn(ex);
_log.Warn(ex); }
} });
} }
public async Task End() public async Task End()

View File

@ -119,77 +119,81 @@ namespace NadekoBot.Modules.Games.Hangman
private async Task PotentialGuess(SocketMessage msg) private async Task PotentialGuess(SocketMessage msg)
{ {
try await Task.Yield();
var _ = Task.Run(async () =>
{ {
if (!(msg is SocketUserMessage)) try
return;
if (msg.Channel != GameChannel)
return; // message's channel has to be the same as game's
if (msg.Content.Length == 1) // message must be 1 char long
{ {
if (++MessagesSinceLastPost > 10) if (!(msg is SocketUserMessage))
return;
if (msg.Channel != GameChannel)
return; // message's channel has to be the same as game's
if (msg.Content.Length == 1) // message must be 1 char long
{ {
MessagesSinceLastPost = 0; if (++MessagesSinceLastPost > 10)
try
{ {
await GameChannel.SendConfirmAsync("Hangman Game", MessagesSinceLastPost = 0;
ScrambledWord + "\n" + GetHangman(), try
footer: string.Join(" ", Guesses)).ConfigureAwait(false); {
await GameChannel.SendConfirmAsync("Hangman Game",
ScrambledWord + "\n" + GetHangman(),
footer: string.Join(" ", Guesses)).ConfigureAwait(false);
}
catch { }
} }
catch { }
}
if (!(char.IsLetter(msg.Content[0]) || char.IsDigit(msg.Content[0])))// and a letter or a digit if (!(char.IsLetter(msg.Content[0]) || char.IsDigit(msg.Content[0])))// and a letter or a digit
return; return;
var guess = char.ToUpperInvariant(msg.Content[0]); var guess = char.ToUpperInvariant(msg.Content[0]);
if (Guesses.Contains(guess)) if (Guesses.Contains(guess))
{
MessagesSinceLastPost = 0;
++Errors;
if (Errors < MaxErrors)
await GameChannel.SendErrorAsync("Hangman Game", $"{msg.Author} Letter `{guess}` has already been used.\n" + ScrambledWord + "\n" + GetHangman(),
footer: string.Join(" ", Guesses)).ConfigureAwait(false);
else
await End().ConfigureAwait(false);
return;
}
Guesses.Add(guess);
if (Term.Word.ToUpperInvariant().Contains(guess))
{
if (GuessedAll)
{ {
try { await GameChannel.SendConfirmAsync("Hangman Game", $"{msg.Author} guessed a letter `{guess}`!").ConfigureAwait(false); } catch { } MessagesSinceLastPost = 0;
++Errors;
await End().ConfigureAwait(false); if (Errors < MaxErrors)
await GameChannel.SendErrorAsync("Hangman Game", $"{msg.Author} Letter `{guess}` has already been used.\n" + ScrambledWord + "\n" + GetHangman(),
footer: string.Join(" ", Guesses)).ConfigureAwait(false);
else
await End().ConfigureAwait(false);
return; return;
} }
MessagesSinceLastPost = 0;
try Guesses.Add(guess);
if (Term.Word.ToUpperInvariant().Contains(guess))
{ {
await GameChannel.SendConfirmAsync("Hangman Game", $"{msg.Author} guessed a letter `{guess}`!\n" + ScrambledWord + "\n" + GetHangman(), if (GuessedAll)
footer: string.Join(" ", Guesses)).ConfigureAwait(false); {
try { await GameChannel.SendConfirmAsync("Hangman Game", $"{msg.Author} guessed a letter `{guess}`!").ConfigureAwait(false); } catch { }
await End().ConfigureAwait(false);
return;
}
MessagesSinceLastPost = 0;
try
{
await GameChannel.SendConfirmAsync("Hangman Game", $"{msg.Author} guessed a letter `{guess}`!\n" + ScrambledWord + "\n" + GetHangman(),
footer: string.Join(" ", Guesses)).ConfigureAwait(false);
}
catch { }
} }
catch { }
}
else
{
MessagesSinceLastPost = 0;
++Errors;
if (Errors < MaxErrors)
await GameChannel.SendErrorAsync("Hangman Game", $"{msg.Author} Letter `{guess}` does not exist.\n" + ScrambledWord + "\n" + GetHangman(),
footer: string.Join(" ", Guesses)).ConfigureAwait(false);
else else
await End().ConfigureAwait(false); {
} MessagesSinceLastPost = 0;
++Errors;
if (Errors < MaxErrors)
await GameChannel.SendErrorAsync("Hangman Game", $"{msg.Author} Letter `{guess}` does not exist.\n" + ScrambledWord + "\n" + GetHangman(),
footer: string.Join(" ", Guesses)).ConfigureAwait(false);
else
await End().ConfigureAwait(false);
}
}
} }
} catch (Exception ex) { _log.Warn(ex); }
catch (Exception ex) { _log.Warn(ex); } });
} }
public string GetHangman() => $@". ┌─────┐ public string GetHangman() => $@". ┌─────┐

View File

@ -109,38 +109,42 @@ namespace NadekoBot.Modules.Games.Models
private async Task AnswerReceived(SocketMessage imsg) private async Task AnswerReceived(SocketMessage imsg)
{ {
try await Task.Yield();
var _ = Task.Run(async () =>
{ {
if (imsg.Author.IsBot) try
return;
var msg = imsg as SocketUserMessage;
if (msg == null)
return;
if (this.Channel == null || this.Channel.Id != msg.Channel.Id) return;
var guess = msg.Content;
var distance = CurrentSentence.LevenshteinDistance(guess);
var decision = Judge(distance, guess.Length);
if (decision && !finishedUserIds.Contains(msg.Author.Id))
{ {
var elapsed = sw.Elapsed; if (imsg.Author.IsBot)
var wpm = CurrentSentence.Length / WORD_VALUE / elapsed.TotalSeconds * 60; return;
finishedUserIds.Add(msg.Author.Id); var msg = imsg as SocketUserMessage;
await this.Channel.EmbedAsync(new EmbedBuilder().WithOkColor() if (msg == null)
.WithTitle($"{msg.Author} finished the race!") return;
.AddField(efb => efb.WithName("Place").WithValue($"#{finishedUserIds.Count}").WithIsInline(true))
.AddField(efb => efb.WithName("WPM").WithValue($"{wpm:F1} *[{elapsed.TotalSeconds:F2}sec]*").WithIsInline(true)) if (this.Channel == null || this.Channel.Id != msg.Channel.Id) return;
.AddField(efb => efb.WithName("Errors").WithValue(distance.ToString()).WithIsInline(true)))
.ConfigureAwait(false); var guess = msg.Content;
if (finishedUserIds.Count % 4 == 0)
var distance = CurrentSentence.LevenshteinDistance(guess);
var decision = Judge(distance, guess.Length);
if (decision && !finishedUserIds.Contains(msg.Author.Id))
{ {
await this.Channel.SendConfirmAsync($":exclamation: A lot of people finished, here is the text for those still typing:\n\n**{Format.Sanitize(CurrentSentence.Replace(" ", " \x200B")).SanitizeMentions()}**").ConfigureAwait(false); var elapsed = sw.Elapsed;
var wpm = CurrentSentence.Length / WORD_VALUE / elapsed.TotalSeconds * 60;
finishedUserIds.Add(msg.Author.Id);
await this.Channel.EmbedAsync(new EmbedBuilder().WithOkColor()
.WithTitle($"{msg.Author} finished the race!")
.AddField(efb => efb.WithName("Place").WithValue($"#{finishedUserIds.Count}").WithIsInline(true))
.AddField(efb => efb.WithName("WPM").WithValue($"{wpm:F1} *[{elapsed.TotalSeconds:F2}sec]*").WithIsInline(true))
.AddField(efb => efb.WithName("Errors").WithValue(distance.ToString()).WithIsInline(true)))
.ConfigureAwait(false);
if (finishedUserIds.Count % 4 == 0)
{
await this.Channel.SendConfirmAsync($":exclamation: A lot of people finished, here is the text for those still typing:\n\n**{Format.Sanitize(CurrentSentence.Replace(" ", " \x200B")).SanitizeMentions()}**").ConfigureAwait(false);
}
} }
} }
} catch (Exception ex) { _log.Warn(ex); }
catch (Exception ex) { _log.Warn(ex); } });
} }
private bool Judge(int errors, int textLength) => errors <= textLength / 25; private bool Judge(int errors, int textLength) => errors <= textLength / 25;

View File

@ -237,7 +237,7 @@ namespace NadekoBot.Modules.Games
return true; return true;
} }
private Task Client_MessageReceived(Discord.WebSocket.SocketMessage msg) private Task Client_MessageReceived(SocketMessage msg)
{ {
var _ = Task.Run(async () => var _ = Task.Run(async () =>
{ {

View File

@ -180,64 +180,68 @@ namespace NadekoBot.Modules.Games.Trivia
private async Task PotentialGuess(SocketMessage imsg) private async Task PotentialGuess(SocketMessage imsg)
{ {
try await Task.Yield();
var _ = Task.Run(async () =>
{ {
if (imsg.Author.IsBot)
return;
var umsg = imsg as SocketUserMessage;
var textChannel = umsg?.Channel as ITextChannel;
if (textChannel == null || textChannel.Guild != Guild)
return;
var guildUser = (IGuildUser)umsg.Author;
var guess = false;
await _guessLock.WaitAsync().ConfigureAwait(false);
try try
{ {
if (GameActive && CurrentQuestion.IsAnswerCorrect(umsg.Content) && !triviaCancelSource.IsCancellationRequested) if (imsg.Author.IsBot)
{ return;
Users.AddOrUpdate(guildUser, 1, (gu, old) => ++old);
guess = true;
}
}
finally { _guessLock.Release(); }
if (!guess) return;
triviaCancelSource.Cancel();
var umsg = imsg as SocketUserMessage;
if (Users[guildUser] == WinRequirement) var textChannel = umsg?.Channel as ITextChannel;
{ if (textChannel == null || textChannel.Guild != Guild)
ShouldStopGame = true; return;
var guildUser = (IGuildUser)umsg.Author;
var guess = false;
await _guessLock.WaitAsync().ConfigureAwait(false);
try try
{ {
await Channel.EmbedAsync(new EmbedBuilder().WithOkColor() if (GameActive && CurrentQuestion.IsAnswerCorrect(umsg.Content) && !triviaCancelSource.IsCancellationRequested)
.WithTitle(GetText("trivia_game")) {
.WithDescription(GetText("trivia_win", Users.AddOrUpdate(guildUser, 1, (gu, old) => ++old);
guildUser.Mention, guess = true;
Format.Bold(CurrentQuestion.Answer))) }
.WithImageUrl(CurrentQuestion.AnswerImageUrl))
.ConfigureAwait(false);
} }
catch finally { _guessLock.Release(); }
{ if (!guess) return;
// ignored triviaCancelSource.Cancel();
}
var reward = _bc.TriviaCurrencyReward;
if (reward > 0)
await _cs.AddAsync(guildUser, "Won trivia", reward, true).ConfigureAwait(false);
return;
}
await Channel.EmbedAsync(new EmbedBuilder().WithOkColor()
.WithTitle(GetText("trivia_game")) if (Users[guildUser] == WinRequirement)
.WithDescription(GetText("trivia_guess", guildUser.Mention, Format.Bold(CurrentQuestion.Answer))) {
.WithImageUrl(CurrentQuestion.AnswerImageUrl)) ShouldStopGame = true;
.ConfigureAwait(false); try
} {
catch (Exception ex) { _log.Warn(ex); } await Channel.EmbedAsync(new EmbedBuilder().WithOkColor()
.WithTitle(GetText("trivia_game"))
.WithDescription(GetText("trivia_win",
guildUser.Mention,
Format.Bold(CurrentQuestion.Answer)))
.WithImageUrl(CurrentQuestion.AnswerImageUrl))
.ConfigureAwait(false);
}
catch
{
// ignored
}
var reward = _bc.TriviaCurrencyReward;
if (reward > 0)
await _cs.AddAsync(guildUser, "Won trivia", reward, true).ConfigureAwait(false);
return;
}
await Channel.EmbedAsync(new EmbedBuilder().WithOkColor()
.WithTitle(GetText("trivia_game"))
.WithDescription(GetText("trivia_guess", guildUser.Mention, Format.Bold(CurrentQuestion.Answer)))
.WithImageUrl(CurrentQuestion.AnswerImageUrl))
.ConfigureAwait(false);
}
catch (Exception ex) { _log.Warn(ex); }
});
} }
public string GetLeaderboard() public string GetLeaderboard()

View File

@ -4,13 +4,9 @@ using Discord;
using Discord.Commands; using Discord.Commands;
using NadekoBot.Attributes; using NadekoBot.Attributes;
using NadekoBot.Extensions; using NadekoBot.Extensions;
using NadekoBot.Modules.Searches.Models; using NadekoBot.Services.Searches;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Net.Http;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -21,37 +17,11 @@ namespace NadekoBot.Modules.Searches
[Group] [Group]
public class AnimeSearchCommands : NadekoSubmodule public class AnimeSearchCommands : NadekoSubmodule
{ {
private static readonly Timer anilistTokenRefresher; private readonly AnimeSearchService _service;
private static string anilistToken { get; set; }
static AnimeSearchCommands() public AnimeSearchCommands(AnimeSearchService service)
{ {
anilistTokenRefresher = new Timer(async (state) => _service = service;
{
try
{
var headers = new Dictionary<string, string>
{
{"grant_type", "client_credentials"},
{"client_id", "kwoth-w0ki9"},
{"client_secret", "Qd6j4FIAi1ZK6Pc7N7V4Z"},
};
using (var http = new HttpClient())
{
//http.AddFakeHeaders();
http.DefaultRequestHeaders.Clear();
var formContent = new FormUrlEncodedContent(headers);
var response = await http.PostAsync("https://anilist.co/api/auth/access_token", formContent).ConfigureAwait(false);
var stringContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
anilistToken = JObject.Parse(stringContent)["access_token"].ToString();
}
}
catch
{
// ignored
}
}, null, TimeSpan.FromSeconds(0), TimeSpan.FromMinutes(29));
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
@ -171,7 +141,7 @@ namespace NadekoBot.Modules.Searches
if (string.IsNullOrWhiteSpace(query)) if (string.IsNullOrWhiteSpace(query))
return; return;
var animeData = await GetAnimeData(query).ConfigureAwait(false); var animeData = await _service.GetAnimeData(query).ConfigureAwait(false);
if (animeData == null) if (animeData == null)
{ {
@ -198,7 +168,7 @@ namespace NadekoBot.Modules.Searches
if (string.IsNullOrWhiteSpace(query)) if (string.IsNullOrWhiteSpace(query))
return; return;
var mangaData = await GetMangaData(query).ConfigureAwait(false); var mangaData = await _service.GetMangaData(query).ConfigureAwait(false);
if (mangaData == null) if (mangaData == null)
{ {
@ -218,52 +188,6 @@ namespace NadekoBot.Modules.Searches
await Context.Channel.EmbedAsync(embed).ConfigureAwait(false); await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
} }
private async Task<AnimeResult> GetAnimeData(string query)
{
if (string.IsNullOrWhiteSpace(query))
throw new ArgumentNullException(nameof(query));
try
{
var link = "http://anilist.co/api/anime/search/" + Uri.EscapeUriString(query);
using (var http = new HttpClient())
{
var res = await http.GetStringAsync(link + $"?access_token={anilistToken}").ConfigureAwait(false);
var smallObj = JArray.Parse(res)[0];
var aniData = await http.GetStringAsync("http://anilist.co/api/anime/" + smallObj["id"] + $"?access_token={anilistToken}").ConfigureAwait(false);
return await Task.Run(() => { try { return JsonConvert.DeserializeObject<AnimeResult>(aniData); } catch { return null; } }).ConfigureAwait(false);
}
}
catch (Exception ex)
{
_log.Warn(ex, "Failed anime search for {0}", query);
return null;
}
}
private async Task<MangaResult> GetMangaData(string query)
{
if (string.IsNullOrWhiteSpace(query))
throw new ArgumentNullException(nameof(query));
try
{
using (var http = new HttpClient())
{
var res = await http.GetStringAsync("http://anilist.co/api/manga/search/" + Uri.EscapeUriString(query) + $"?access_token={anilistToken}").ConfigureAwait(false);
var smallObj = JArray.Parse(res)[0];
var aniData = await http.GetStringAsync("http://anilist.co/api/manga/" + smallObj["id"] + $"?access_token={anilistToken}").ConfigureAwait(false);
return await Task.Run(() => { try { return JsonConvert.DeserializeObject<MangaResult>(aniData); } catch { return null; } }).ConfigureAwait(false);
}
}
catch (Exception ex)
{
_log.Warn(ex, "Failed anime search for {0}", query);
return null;
}
}
} }
} }
} }

View File

@ -132,6 +132,7 @@ namespace NadekoBot
#region Searches #region Searches
var searchesService = new SearchesService(Client, GoogleApi, Db); var searchesService = new SearchesService(Client, GoogleApi, Db);
var streamNotificationService = new StreamNotificationService(Db, Client, Strings); var streamNotificationService = new StreamNotificationService(Db, Client, Strings);
var animeSearchService = new AnimeSearchService();
#endregion #endregion
var clashService = new ClashOfClansService(Client, Db, Localization, Strings); var clashService = new ClashOfClansService(Client, Db, Localization, Strings);
@ -184,6 +185,7 @@ namespace NadekoBot
.Add(converterService) .Add(converterService)
.Add<SearchesService>(searchesService) .Add<SearchesService>(searchesService)
.Add(streamNotificationService) .Add(streamNotificationService)
.Add(animeSearchService)
.Add<ClashOfClansService>(clashService) .Add<ClashOfClansService>(clashService)
.Add<MusicService>(musicService) .Add<MusicService>(musicService)
.Add<GreetSettingsService>(greetSettingsService) .Add<GreetSettingsService>(greetSettingsService)

View File

@ -31,6 +31,9 @@
<ItemGroup> <ItemGroup>
<Compile Remove="data\**\*;credentials.json" /> <Compile Remove="data\**\*;credentials.json" />
<Compile Remove="Modules\Utility\Models\**" />
<EmbeddedResource Remove="Modules\Utility\Models\**" />
<None Remove="Modules\Utility\Models\**" />
<None Update="credentials_example.json"> <None Update="credentials_example.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
@ -87,6 +90,5 @@
<ItemGroup> <ItemGroup>
<Folder Include="Modules\Music\Classes\" /> <Folder Include="Modules\Music\Classes\" />
<Folder Include="Modules\Utility\Models\" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -5,6 +5,7 @@ using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks;
namespace NadekoBot.Services.Administration namespace NadekoBot.Services.Administration
{ {
@ -25,21 +26,25 @@ namespace NadekoBot.Services.Administration
gcs.Where(x => x.AutoAssignRoleId != 0) gcs.Where(x => x.AutoAssignRoleId != 0)
.ToDictionary(k => k.GuildId, v => v.AutoAssignRoleId)); .ToDictionary(k => k.GuildId, v => v.AutoAssignRoleId));
_client.UserJoined += async (user) => _client.UserJoined += (user) =>
{ {
try var _ = Task.Run(async () =>
{ {
AutoAssignedRoles.TryGetValue(user.Guild.Id, out ulong roleId); try
{
AutoAssignedRoles.TryGetValue(user.Guild.Id, out ulong roleId);
if (roleId == 0) if (roleId == 0)
return; return;
var role = user.Guild.Roles.FirstOrDefault(r => r.Id == roleId); var role = user.Guild.Roles.FirstOrDefault(r => r.Id == roleId);
if (role != null) if (role != null)
await user.AddRoleAsync(role).ConfigureAwait(false); await user.AddRoleAsync(role).ConfigureAwait(false);
} }
catch (Exception ex) { _log.Warn(ex); } catch (Exception ex) { _log.Warn(ex); }
});
return Task.CompletedTask;
}; };
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -71,20 +71,21 @@ namespace NadekoBot.Services.Administration
_client.UserJoined += Client_UserJoined; _client.UserJoined += Client_UserJoined;
} }
private async Task Client_UserJoined(IGuildUser usr) private Task Client_UserJoined(IGuildUser usr)
{ {
try try
{ {
MutedUsers.TryGetValue(usr.Guild.Id, out ConcurrentHashSet<ulong> muted); MutedUsers.TryGetValue(usr.Guild.Id, out ConcurrentHashSet<ulong> muted);
if (muted == null || !muted.Contains(usr.Id)) if (muted == null || !muted.Contains(usr.Id))
return; return Task.CompletedTask;
await MuteUser(usr).ConfigureAwait(false); Task.Run(() => MuteUser(usr).ConfigureAwait(false));
} }
catch (Exception ex) catch (Exception ex)
{ {
LogManager.GetCurrentClassLogger().Warn(ex); _log.Warn(ex);
} }
return Task.CompletedTask;
} }
public async Task MuteUser(IGuildUser usr, MuteType type = MuteType.All) public async Task MuteUser(IGuildUser usr, MuteType type = MuteType.All)

View File

@ -258,7 +258,7 @@ namespace NadekoBot.Services
break; break;
} }
} }
var prefix = GetPrefix(guild.Id); var prefix = GetPrefix(guild?.Id);
// execute the command and measure the time it took // execute the command and measure the time it took
if (messageContent.StartsWith(prefix)) if (messageContent.StartsWith(prefix))
{ {

View File

@ -99,6 +99,7 @@ namespace NadekoBot.Services.Games
private async Task PotentialFlowerGeneration(SocketMessage imsg) private async Task PotentialFlowerGeneration(SocketMessage imsg)
{ {
await Task.Yield();
var msg = imsg as SocketUserMessage; var msg = imsg as SocketUserMessage;
if (msg == null || msg.Author.IsBot) if (msg == null || msg.Author.IsBot)
return; return;
@ -109,48 +110,51 @@ namespace NadekoBot.Services.Games
if (!GenerationChannels.Contains(channel.Id)) if (!GenerationChannels.Contains(channel.Id))
return; return;
try var _ = Task.Run(async () =>
{ {
var lastGeneration = LastGenerations.GetOrAdd(channel.Id, DateTime.MinValue); try
var rng = new NadekoRandom();
if (DateTime.Now - TimeSpan.FromSeconds(_bc.CurrencyGenerationCooldown) < lastGeneration) //recently generated in this channel, don't generate again
return;
var num = rng.Next(1, 101) + _bc.CurrencyGenerationChance * 100;
if (num > 100 && LastGenerations.TryUpdate(channel.Id, DateTime.Now, lastGeneration))
{ {
var dropAmount = _bc.CurrencyDropAmount; var lastGeneration = LastGenerations.GetOrAdd(channel.Id, DateTime.MinValue);
var rng = new NadekoRandom();
if (dropAmount > 0) if (DateTime.Now - TimeSpan.FromSeconds(_bc.CurrencyGenerationCooldown) < lastGeneration) //recently generated in this channel, don't generate again
return;
var num = rng.Next(1, 101) + _bc.CurrencyGenerationChance * 100;
if (num > 100 && LastGenerations.TryUpdate(channel.Id, DateTime.Now, lastGeneration))
{ {
var msgs = new IUserMessage[dropAmount]; var dropAmount = _bc.CurrencyDropAmount;
var prefix = _cmdHandler.GetPrefix(channel.Guild.Id);
var toSend = dropAmount == 1 if (dropAmount > 0)
? GetText(channel, "curgen_sn", _bc.CurrencySign)
+ " " + GetText(channel, "pick_sn", prefix)
: GetText(channel, "curgen_pl", dropAmount, _bc.CurrencySign)
+ " " + GetText(channel, "pick_pl", prefix);
var file = GetRandomCurrencyImage();
using (var fileStream = file.Data.ToStream())
{ {
var sent = await channel.SendFileAsync( var msgs = new IUserMessage[dropAmount];
fileStream, var prefix = _cmdHandler.GetPrefix(channel.Guild.Id);
file.Name, var toSend = dropAmount == 1
toSend).ConfigureAwait(false); ? GetText(channel, "curgen_sn", _bc.CurrencySign)
+ " " + GetText(channel, "pick_sn", prefix)
: GetText(channel, "curgen_pl", dropAmount, _bc.CurrencySign)
+ " " + GetText(channel, "pick_pl", prefix);
var file = GetRandomCurrencyImage();
using (var fileStream = file.Data.ToStream())
{
var sent = await channel.SendFileAsync(
fileStream,
file.Name,
toSend).ConfigureAwait(false);
msgs[0] = sent; msgs[0] = sent;
}
PlantedFlowers.AddOrUpdate(channel.Id, msgs.ToList(), (id, old) => { old.AddRange(msgs); return old; });
} }
PlantedFlowers.AddOrUpdate(channel.Id, msgs.ToList(), (id, old) => { old.AddRange(msgs); return old; });
} }
} }
} catch (Exception ex)
catch (Exception ex) {
{ LogManager.GetCurrentClassLogger().Warn(ex);
LogManager.GetCurrentClassLogger().Warn(ex); }
} });
return; return;
} }
} }

View File

@ -0,0 +1,98 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NLog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace NadekoBot.Services.Searches
{
public class AnimeSearchService
{
private readonly Timer _anilistTokenRefresher;
private readonly Logger _log;
private static string anilistToken { get; set; }
public AnimeSearchService()
{
_log = LogManager.GetCurrentClassLogger();
_anilistTokenRefresher = new Timer(async (state) =>
{
try
{
var headers = new Dictionary<string, string>
{
{"grant_type", "client_credentials"},
{"client_id", "kwoth-w0ki9"},
{"client_secret", "Qd6j4FIAi1ZK6Pc7N7V4Z"},
};
using (var http = new HttpClient())
{
//http.AddFakeHeaders();
http.DefaultRequestHeaders.Clear();
var formContent = new FormUrlEncodedContent(headers);
var response = await http.PostAsync("https://anilist.co/api/auth/access_token", formContent).ConfigureAwait(false);
var stringContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
anilistToken = JObject.Parse(stringContent)["access_token"].ToString();
}
}
catch
{
// ignored
}
}, null, TimeSpan.FromSeconds(0), TimeSpan.FromMinutes(29));
}
public async Task<AnimeResult> GetAnimeData(string query)
{
if (string.IsNullOrWhiteSpace(query))
throw new ArgumentNullException(nameof(query));
try
{
var link = "http://anilist.co/api/anime/search/" + Uri.EscapeUriString(query);
using (var http = new HttpClient())
{
var res = await http.GetStringAsync(link + $"?access_token={anilistToken}").ConfigureAwait(false);
var smallObj = JArray.Parse(res)[0];
var aniData = await http.GetStringAsync("http://anilist.co/api/anime/" + smallObj["id"] + $"?access_token={anilistToken}").ConfigureAwait(false);
return await Task.Run(() => { try { return JsonConvert.DeserializeObject<AnimeResult>(aniData); } catch { return null; } }).ConfigureAwait(false);
}
}
catch (Exception ex)
{
_log.Warn(ex, "Failed anime search for {0}", query);
return null;
}
}
public async Task<MangaResult> GetMangaData(string query)
{
if (string.IsNullOrWhiteSpace(query))
throw new ArgumentNullException(nameof(query));
try
{
using (var http = new HttpClient())
{
var res = await http.GetStringAsync("http://anilist.co/api/manga/search/" + Uri.EscapeUriString(query) + $"?access_token={anilistToken}").ConfigureAwait(false);
var smallObj = JArray.Parse(res)[0];
var aniData = await http.GetStringAsync("http://anilist.co/api/manga/" + smallObj["id"] + $"?access_token={anilistToken}").ConfigureAwait(false);
return await Task.Run(() => { try { return JsonConvert.DeserializeObject<MangaResult>(aniData); } catch { return null; } }).ConfigureAwait(false);
}
}
catch (Exception ex)
{
_log.Warn(ex, "Failed anime search for {0}", query);
return null;
}
}
}
}

View File

@ -1,6 +1,6 @@
using NadekoBot.Extensions; using NadekoBot.Extensions;
namespace NadekoBot.Modules.Searches.Models namespace NadekoBot.Services.Searches
{ {
public class AnimeResult public class AnimeResult
{ {

View File

@ -1,4 +1,4 @@
namespace NadekoBot.Modules.Searches.Models namespace NadekoBot.Services.Searches
{ {
public class MangaResult public class MangaResult
{ {

View File

@ -41,32 +41,35 @@ namespace NadekoBot.Services.Searches
//translate commands //translate commands
_client.MessageReceived += async (msg) => _client.MessageReceived += async (msg) =>
{ {
try await Task.Yield();
var _ = Task.Run(async () =>
{ {
var umsg = msg as SocketUserMessage; try
if (umsg == null)
return;
if (!TranslatedChannels.TryGetValue(umsg.Channel.Id, out var autoDelete))
return;
var key = new UserChannelPair()
{ {
UserId = umsg.Author.Id, var umsg = msg as SocketUserMessage;
ChannelId = umsg.Channel.Id, if (umsg == null)
}; return;
string langs; if (!TranslatedChannels.TryGetValue(umsg.Channel.Id, out var autoDelete))
if (!UserLanguages.TryGetValue(key, out langs)) return;
return;
var text = await Translate(langs, umsg.Resolve(TagHandling.Ignore)) var key = new UserChannelPair()
.ConfigureAwait(false); {
if (autoDelete) UserId = umsg.Author.Id,
try { await umsg.DeleteAsync().ConfigureAwait(false); } catch { } ChannelId = umsg.Channel.Id,
await umsg.Channel.SendConfirmAsync($"{umsg.Author.Mention} `:` " + text.Replace("<@ ", "<@").Replace("<@! ", "<@!")).ConfigureAwait(false); };
}
catch { } if (!UserLanguages.TryGetValue(key, out string langs))
return;
var text = await Translate(langs, umsg.Resolve(TagHandling.Ignore))
.ConfigureAwait(false);
if (autoDelete)
try { await umsg.DeleteAsync().ConfigureAwait(false); } catch { }
await umsg.Channel.SendConfirmAsync($"{umsg.Author.Mention} `:` " + text.Replace("<@ ", "<@").Replace("<@! ", "<@!")).ConfigureAwait(false);
}
catch { }
});
}; };
//pokemon commands //pokemon commands

View File

@ -21,42 +21,46 @@ namespace NadekoBot.Services.Utility
_client.MessageReceived += Client_MessageReceived; _client.MessageReceived += Client_MessageReceived;
} }
private async Task Client_MessageReceived(SocketMessage imsg) private Task Client_MessageReceived(SocketMessage imsg)
{ {
try var _ = Task.Run(async () => {
{ try
if (imsg.Author.IsBot)
return;
var msg = imsg as IUserMessage;
if (msg == null)
return;
var channel = imsg.Channel as ITextChannel;
if (channel == null)
return;
if (msg.Author.Id == _client.CurrentUser.Id) return;
foreach (var subscriber in Subscribers)
{ {
var set = subscriber.Value; if (imsg.Author.IsBot)
if (!set.Contains(channel)) return;
continue; var msg = imsg as IUserMessage;
foreach (var chan in set.Except(new[] { channel })) if (msg == null)
return;
var channel = imsg.Channel as ITextChannel;
if (channel == null)
return;
if (msg.Author.Id == _client.CurrentUser.Id) return;
foreach (var subscriber in Subscribers)
{ {
try var set = subscriber.Value;
if (!set.Contains(channel))
continue;
foreach (var chan in set.Except(new[] { channel }))
{ {
await chan.SendMessageAsync(GetMessage(channel, (IGuildUser)msg.Author, try
msg)).ConfigureAwait(false); {
} await chan.SendMessageAsync(GetMessage(channel, (IGuildUser)msg.Author,
catch msg)).ConfigureAwait(false);
{ }
// ignored catch
{
// ignored
}
} }
} }
} }
} catch
catch {
{ // ignored
// ignored }
} });
return Task.CompletedTask;
} }
private string GetMessage(ITextChannel channel, IGuildUser user, IUserMessage message) => private string GetMessage(ITextChannel channel, IGuildUser user, IUserMessage message) =>