/// <summary> /// Stops the current trivia. Returns false if trivia is not running /// </summary> /// <returns>success</returns> public async Task <bool> StopTriviaAsync() { if (!(status == TriviaStatus.Running)) { return(false); } var embedBuilder = new EmbedBuilder() .WithColor(new Color(46, 191, 84)) .WithTitle("The quiz has ended"); var currentScores = GetCurrentHighScores(); if (!currentScores.IsEmptyOrWhiteSpace()) { embedBuilder.AddField("Final scores:", currentScores, true); } var globalScores = await GetGlobalHighScoresAsync(int.MaxValue, guildID).ConfigureAwait(false); if (!globalScores.IsEmptyOrWhiteSpace()) { embedBuilder.AddField("Global top scores:", globalScores); } await MonkeyHelpers.SendChannelMessageAsync(discordClient, guildID, channelID, "", embed : embedBuilder.Build()).ConfigureAwait(false); userScoresCurrent.Clear(); status = TriviaStatus.Stopped; return(true); }
public async Task BuildDocumentationAsync() { string docuHTML = DocumentationBuilder.BuildDocumentation(commandService, DocumentationOutputTypes.HTML); string fileHTML = Path.Combine(AppContext.BaseDirectory, "documentation.html"); await MonkeyHelpers.WriteTextAsync(fileHTML, docuHTML).ConfigureAwait(false); string docuMD = DocumentationBuilder.BuildDocumentation(commandService, DocumentationOutputTypes.MarkDown); string fileMD = Path.Combine(AppContext.BaseDirectory, "documentation.md"); await MonkeyHelpers.WriteTextAsync(fileMD, docuMD).ConfigureAwait(false); }
private string ParseHtml(string html) { if (html.IsEmptyOrWhiteSpace()) { return(string.Empty); } var htmlDoc = new HtmlDocument(); try { html = MonkeyHelpers.CleanHtmlString(html); htmlDoc.LoadHtml(html); } catch (Exception ex) { logger.LogError(ex, "Error parsing html"); return(html); } var sb = new StringBuilder(); var textNodes = htmlDoc?.DocumentNode?.SelectNodes("//text()"); var iframes = htmlDoc?.DocumentNode?.SelectNodes("//iframe[@src]"); if (textNodes != null) { foreach (HtmlNode node in textNodes) { if (!node.InnerText.IsEmptyOrWhiteSpace()) { sb.Append(node.InnerText.Trim() + "|"); } } } if (iframes != null) { foreach (HtmlNode node in iframes) { if (node.HasAttributes && node.Attributes.Contains("src") && !node.Attributes["src"].Value.IsEmptyOrWhiteSpace()) { sb.Append(node.Attributes["src"].Value); } } } var result = sb.ToString(); if (!result.IsEmpty()) { return(result); } return(html); }
private static OTDBQuestion CleanQuestion(OTDBQuestion x) { return(new OTDBQuestion { Category = MonkeyHelpers.CleanHtmlString(x.Category), Question = MonkeyHelpers.CleanHtmlString(x.Question), CorrectAnswer = MonkeyHelpers.CleanHtmlString(x.CorrectAnswer), IncorrectAnswers = x.IncorrectAnswers.Select(MonkeyHelpers.CleanHtmlString).ToList(), Type = x.Type, Difficulty = x.Difficulty }); }
/// <summary> /// Starts a new quiz with the specified amount of questions /// </summary> /// <param name="questionsToPlay">Amount of questions to be played (max 50)</param> /// <returns>success</returns> public async Task <bool> StartTriviaAsync(int questionsToPlay) { if (questionsToPlay < 1) { _ = await MonkeyHelpers.SendChannelMessageAsync(discordClient, guildID, channelID, "At least one question has to be played").ConfigureAwait(false); return(false); } if (status == TriviaStatus.Running) { _ = await MonkeyHelpers.SendChannelMessageAsync(discordClient, guildID, channelID, "There is already a quiz running").ConfigureAwait(false); return(false); } this.questionsToPlay = questionsToPlay; questions?.Clear(); var embed = new EmbedBuilder() .WithColor(new Color(26, 137, 185)) .WithTitle("Trivia") .WithDescription( $"Starting trivia with {questionsToPlay} question{ (questionsToPlay == 1 ? "" : "s")}." + Environment.NewLine + "- Answer each question by clicking on the corresponding Emoji" + Environment.NewLine + "- Each question has a value of 1-3 points" + Environment.NewLine + $"- You have {timeout.TotalSeconds} seconds for each question." + "- Only your first answer counts!" + Environment.NewLine + "- Each wrong answer will reduce your points by 1 until you are back to zero" + Environment.NewLine ) .Build(); _ = await MonkeyHelpers.SendChannelMessageAsync(discordClient, guildID, channelID, "", embed : embed).ConfigureAwait(false); await LoadQuestionsAsync(questionsToPlay).ConfigureAwait(false); if (questions == null || questions.Count == 0) { _ = await MonkeyHelpers.SendChannelMessageAsync(discordClient, guildID, channelID, "Questions could not be loaded").ConfigureAwait(false); return(false); } userScoresCurrent = new Dictionary <ulong, int>(); currentQuestionMessage = null; correctAnswerUsers.Clear(); wrongAnswerUsers.Clear(); currentIndex = 0; status = TriviaStatus.Running; await GetNextQuestionAsync().ConfigureAwait(false); return(true); }
private async Task <string> GetJokeAsync(Uri uri) { HttpClient httpClient = clientFactory.CreateClient(); string json = await httpClient.GetStringAsync(uri).ConfigureAwait(false); if (!json.IsEmpty()) { ChuckResponse chuckResponse = JsonSerializer.Deserialize <ChuckResponse>(json); if (chuckResponse.Type == "success" && chuckResponse.Value != null) { return(MonkeyHelpers.CleanHtmlString(chuckResponse.Value.Joke)); } } return(string.Empty); }
public async Task <string> GetChuckFactAsync() { using (var httpClient = new HttpClient()) { var json = await httpClient.GetStringAsync(randomJokeApiUrl).ConfigureAwait(false); if (!json.IsEmpty()) { var chuckResponse = JsonConvert.DeserializeObject <ChuckResponse>(json); if (chuckResponse.Type == "success" && chuckResponse.Value != null) { return(MonkeyHelpers.CleanHtmlString(chuckResponse.Value.Joke)); } } return(string.Empty); } }
public async Task StartPollAsync([Summary("The question")] string question, [Summary("The list of answers")] params string[] answers) { if (answers == null || answers.Length <= 0) { await StartPollAsync(question).ConfigureAwait(false); return; } if (answers.Length < 2) { await ReplyAsync("Please provide at least 2 answers").ConfigureAwait(false); return; } if (answers.Length > 7) { await ReplyAsync("Please provide a maximum of 7 answers").ConfigureAwait(false); return; } question = question.Trim('\"'); if (question.IsEmptyOrWhiteSpace()) { await ReplyAsync("Please enter a question").ConfigureAwait(false); return; } Poll poll = new Poll { GuildId = Context.Guild.Id, ChannelId = Context.Channel.Id, Question = question, Answers = answers.Select((ans, i) => new PollAnswer(ans, new Emoji(MonkeyHelpers.GetUnicodeRegionalLetter(i)))).ToList() }; await InlineReactionReplyAsync(GeneratePoll(poll), false).ConfigureAwait(false); }
public async Task <string> GetChuckFactAsync(string userName) { if (userName.IsEmpty()) { return(string.Empty); } using (var httpClient = new HttpClient()) { var url = new UriBuilder(randomJokeApiUrl); url.Query = $"firstName={userName}"; var json = await httpClient.GetStringAsync(url.Uri).ConfigureAwait(false); if (!json.IsEmpty()) { var chuckResponse = JsonConvert.DeserializeObject <ChuckResponse>(json); if (chuckResponse.Type == "success" && chuckResponse.Value != null) { return(MonkeyHelpers.CleanHtmlString(chuckResponse.Value.Joke.Replace("Norris", "").Replace(" ", " "))); } } return(string.Empty); } }
private async Task GetNextQuestionAsync() { if (status == TriviaStatus.Stopped) { return; } if (currentQuestionMessage != null) { interactiveService.RemoveReactionCallback(currentQuestionMessage); int points = QuestionToPoints(currentQuestion); var embedBuilder = new EmbedBuilder() .WithColor(new Color(46, 191, 84)) .WithTitle("Time is up") .WithDescription($"The correct answer was: **{ currentQuestion.CorrectAnswer}**"); string msg = ""; if (correctAnswerUsers.Count > 0) { correctAnswerUsers.ForEach(async usr => await AddPointsToUserAsync(usr, points).ConfigureAwait(false)); msg = $"*{string.Join(", ", correctAnswerUsers.Select(u => u.Username))}* had it right! Here, have {points} point{(points == 1 ? "" : "s")}."; } else { msg = "No one had it right"; } embedBuilder.AddField("Correct answers", msg, true); if (wrongAnswerUsers.Count > 0) { wrongAnswerUsers.ForEach(async usr => await AddPointsToUserAsync(usr, -1).ConfigureAwait(false)); msg = $"*{string.Join(", ", wrongAnswerUsers.Select(u => u.Username))}* had it wrong! You lose 1 point."; } else { msg = "No one had it wrong."; } embedBuilder.AddField("Incorrect answers", msg, true); var highScores = GetCurrentHighScores(3); if (!highScores.IsEmptyOrWhiteSpace()) { embedBuilder.AddField("Top 3:", highScores, true); } await MonkeyHelpers.SendChannelMessageAsync(discordClient, guildID, channelID, "", embed : embedBuilder.Build()).ConfigureAwait(false); correctAnswerUsers.Clear(); wrongAnswerUsers.Clear(); } if (currentIndex < questionsToPlay) { if (currentIndex >= questions.Count) // we want to play more questions than available { await LoadQuestionsAsync(10).ConfigureAwait(false); // load more questions } currentQuestion = questions.ElementAt(currentIndex); var builder = new EmbedBuilder { Color = new Color(26, 137, 185), Title = $"Question {currentIndex + 1}" }; int points = QuestionToPoints(currentQuestion); builder.Description = $"{currentQuestion.Category} - {currentQuestion.Difficulty} : {points} point{(points == 1 ? "" : "s")}"; if (currentQuestion.Type == TriviaQuestionType.TrueFalse) { builder.AddField($"{currentQuestion.Question}", "True or false?"); var trueEmoji = new Emoji("👍"); var falseEmoji = new Emoji("👎"); var correctAnswerEmoji = currentQuestion.CorrectAnswer.Equals("true", StringComparison.OrdinalIgnoreCase) ? trueEmoji : falseEmoji; currentQuestionMessage = await interactiveService.SendMessageWithReactionCallbacksAsync(commandContext, new ReactionCallbackData("", builder.Build(), false, true, true, timeout, _ => GetNextQuestionAsync()) .WithCallback(trueEmoji, (c, r) => CheckAnswer(r, correctAnswerEmoji)) .WithCallback(falseEmoji, (c, r) => CheckAnswer(r, correctAnswerEmoji)), false ).ConfigureAwait(false); } else if (currentQuestion.Type == TriviaQuestionType.MultipleChoice) { // add the correct answer to the list of correct answers to form the list of possible answers var answers = currentQuestion.IncorrectAnswers.Append(currentQuestion.CorrectAnswer); Random rand = new Random(); // randomize the order of the answers var randomizedAnswers = answers.OrderBy(_ => rand.Next()).ToList(); var correctAnswerEmoji = new Emoji(MonkeyHelpers.GetUnicodeRegionalLetter(randomizedAnswers.IndexOf(currentQuestion.CorrectAnswer))); builder.AddField($"{currentQuestion.Question}", string.Join(Environment.NewLine, randomizedAnswers.Select((s, i) => $"{MonkeyHelpers.GetUnicodeRegionalLetter(i)} {s}"))); currentQuestionMessage = await interactiveService.SendMessageWithReactionCallbacksAsync(commandContext, new ReactionCallbackData("", builder.Build(), false, true, true, timeout, _ => GetNextQuestionAsync()) .WithCallback(new Emoji(MonkeyHelpers.GetUnicodeRegionalLetter(0)), (c, r) => CheckAnswer(r, correctAnswerEmoji)) .WithCallback(new Emoji(MonkeyHelpers.GetUnicodeRegionalLetter(1)), (c, r) => CheckAnswer(r, correctAnswerEmoji)) .WithCallback(new Emoji(MonkeyHelpers.GetUnicodeRegionalLetter(2)), (c, r) => CheckAnswer(r, correctAnswerEmoji)) .WithCallback(new Emoji(MonkeyHelpers.GetUnicodeRegionalLetter(3)), (c, r) => CheckAnswer(r, correctAnswerEmoji)) , false).ConfigureAwait(false); } currentIndex++; } else { await StopTriviaAsync().ConfigureAwait(false); } }
private Task AnnounceAsync(string message, ulong guildID, ulong channelID) => MonkeyHelpers.SendChannelMessageAsync(discordClient, guildID, channelID, message);
protected static async Task <string> GenerateHistoryChartAsync(GameServer discordGameServer, int currentPlayers, int maxPlayers) { string id = discordGameServer.ServerIP.ToString().Replace(".", "_").Replace(":", "_"); var historyPeriod = TimeSpan.FromMinutes(90); const string folder = "Gameservers"; if (!Directory.Exists(folder)) { Directory.CreateDirectory(folder); } string baseFilePath = Path.Combine(folder, id); string storedValuesPath = $"{baseFilePath}.txt"; DateTime now = DateTime.Now; DateTime minTime = now.Subtract(historyPeriod); var historicData = new List <HistoricData <int> >(); if (File.Exists(storedValuesPath)) { string json = await MonkeyHelpers.ReadTextAsync(storedValuesPath); List <HistoricData <int> > loadedData = JsonSerializer.Deserialize <List <HistoricData <int> > >(json); historicData = loadedData .Where(x => x.Time > minTime) .ToList(); } historicData.Add(new HistoricData <int>(now, Math.Min(currentPlayers, maxPlayers))); await MonkeyHelpers.WriteTextAsync(storedValuesPath, JsonSerializer.Serialize(historicData, new JsonSerializerOptions() { WriteIndented = true })) ; int maxIntervals = 10; int interval = 10; for (int i = (int)Math.Ceiling(1.0 * maxPlayers / maxIntervals); i < 10; i++) { if (maxPlayers % i == 0) { interval = i; break; } } List <int> roundedPlayerCounts = Enumerable .Range(0, 10) .Reverse() .Select(mins => now.Subtract(TimeSpan.FromMinutes(mins * 10))) // Last 90 minutes .Select(t => historicData.FirstOrDefault(hd => Math.Abs(hd.Time.Subtract(t).TotalMinutes) < 1)?.Value ?? 0) .Select(v => (int)Math.Round(v / (1.0 * interval))) .ToList(); //Bottom up var lines = new List <string> { " minutes ago", " 0┊0┊0┊0┊0┊0┊0┊0┊0┊0", " 9┊8┊7┊6┊5┊4┊3┊2┊1┊0" }; int maxI = maxPlayers / interval; for (int i = 0; i <= maxI; i++) { string line = $"{i * interval,2}"; line += i == 0 ? "┴" : i == maxI ? "┐" : "┤"; string joinChar = i == 0 ? "┼" : i == maxI ? "┬" : "┊"; line += string.Join(joinChar, Enumerable .Range(0, 10) .Select(n => roundedPlayerCounts[n]) .Select(cnt => (i, cnt) switch { (0, 0) => "─", (_, 0) => " ", (0, _) => "╨", var(ii, c) when ii < c => "║", var(ii, c) when ii == c => "╥", _ => " " })
private async Task AnnounceAsync(string message, ulong guildID, ulong channelID) { await MonkeyHelpers.SendChannelMessageAsync(discordClient, guildID, channelID, message).ConfigureAwait(false); }
private Task RemindAsync(string message, ulong guildId, ulong channelId) => MonkeyHelpers.SendChannelMessageAsync(_discordClient, guildId, channelId, message);
private (string TextContent, string ImgLink) ParseHtml(string html) { if (html.IsEmptyOrWhiteSpace()) { return(new(string.Empty, string.Empty)); } var htmlDoc = new HtmlDocument(); try { html = MonkeyHelpers.CleanHtmlString(html); htmlDoc.LoadHtml(html); } catch (Exception ex) { _logger.LogError(ex, "Error parsing html"); return(new(html, string.Empty)); } var sb = new StringBuilder(); HtmlNodeCollection textNodes = htmlDoc?.DocumentNode?.SelectNodes("//text()"); HtmlNodeCollection iframes = htmlDoc?.DocumentNode?.SelectNodes("//iframe[@src]"); if (textNodes != null) { foreach (HtmlNode node in textNodes) { if (!node.InnerText.IsEmptyOrWhiteSpace()) { sb.Append(node.InnerText.Trim() + "|"); } } } if (iframes != null) { foreach (HtmlNode node in iframes) { if (node.HasAttributes && node.Attributes.Contains("src") && !node.Attributes["src"].Value.IsEmptyOrWhiteSpace()) { sb.Append(node.Attributes["src"].Value); } } } string textContent = sb.Length > 0 ? sb.ToString().Trim('|') : html; var imgNodes = htmlDoc? .DocumentNode? .SelectNodes("//img"); string imgLink = imgNodes? .Where(x => x.HasAttributes && x.Attributes.Contains("src") && !x.Attributes["src"].Value.IsEmptyOrWhiteSpace())? .Select(x => x.Attributes["src"].Value)? .Where(l => !l.EndsWith("gif"))? .FirstOrDefault() ?? string.Empty; return(new(textContent.Trim(), imgLink)); }