Made events run async where needed, fixed .startevent flowerreaction and running commands in DMs
This commit is contained in:
parent
ec5a5c42a9
commit
fa29131818
34
src/NadekoBot/Command Errors 2017-06-05.txt
Normal file
34
src/NadekoBot/Command Errors 2017-06-05.txt
Normal 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()
|
||||||
|
------
|
@ -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", "العربية" },
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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); }
|
||||||
|
@ -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()
|
||||||
|
@ -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() => $@". ┌─────┐
|
||||||
|
@ -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;
|
||||||
|
@ -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 () =>
|
||||||
{
|
{
|
||||||
|
@ -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()
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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)
|
||||||
|
@ -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>
|
||||||
|
@ -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
@ -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)
|
||||||
|
@ -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))
|
||||||
{
|
{
|
||||||
|
@ -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;
|
||||||
@ -110,47 +111,50 @@ 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
98
src/NadekoBot/Services/Searches/AnimeSearchService.cs
Normal file
98
src/NadekoBot/Services/Searches/AnimeSearchService.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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
|
||||||
{
|
{
|
@ -1,4 +1,4 @@
|
|||||||
namespace NadekoBot.Modules.Searches.Models
|
namespace NadekoBot.Services.Searches
|
||||||
{
|
{
|
||||||
public class MangaResult
|
public class MangaResult
|
||||||
{
|
{
|
@ -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
|
||||||
|
@ -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) =>
|
||||||
|
Loading…
Reference in New Issue
Block a user