public async Task ShowLeaderboard(LeaderboardType type = LeaderboardType.Global) { if (type == LeaderboardType.Global) { var top = _leaderboard.GetTopRank(15); await ReplyAsync(embed : await FormatLeaderboard(top)); } else if (type == LeaderboardType.Current) { var challenge = await _challenges.GetCurrentChallenge(); if (challenge == null) { await ReplyAsync("There is no currently running challenge"); return; } await DisplayChallengeLeaderboard(challenge); } else { throw new InvalidOperationException("Unknown leaderboard type"); } }
public async Task SubmitSolution([Remainder] string input) { var challenge = await _challenges.GetCurrentChallenge(); if (challenge == null) { await ReplyAsync("There is no currently running challenge!"); return; } await SubmitSolution(challenge, input, true); }
public async Task SetDifficulty(ChallengeDifficulty difficulty) { var current = await _challenges.GetCurrentChallenge(); if (current == null) { await ReplyAsync("There is no current challenge"); } else { await _challenges.ChangeChallengeDifficulty(current, difficulty); await ReplyAsync($"Changed difficulty from `{current.Difficulty}` to `{difficulty}`"); } }
public async Task ShowLeaderboard(LeaderboardType type = LeaderboardType.Global) { if (type == LeaderboardType.Global) { var top = _leaderboard.GetTopRank(15); await ReplyAsync(embed : await FormatLeaderboard(top)); } else if (type == LeaderboardType.Current) { var challenge = await _challenges.GetCurrentChallenge(); if (challenge == null) { await ReplyAsync("There is no currently running challenge"); return; } // Get the top N solutions var top5 = _solutions.GetSolutions(challenge.Id, 20).Select(a => new RankInfo(a.Solution.UserId, a.Rank, a.Solution.Score)); // Get your own rank var self = await _solutions.GetRank(challenge.Id, Context.User.Id); RankInfo?selfRank = null; if (self.HasValue) { selfRank = new RankInfo(self.Value.Solution.UserId, self.Value.Rank, self.Value.Solution.Score); } await ReplyAsync(embed : await FormatLeaderboard(top5, selfRank)); } else { throw new InvalidOperationException("Unknown leaderboard type"); } }
public async Task CurrentCompetition() { var current = await _challenges.GetCurrentChallenge(); if (current == null) { await ReplyAsync("There is no challenge currently running"); } else { var message = await ReplyAsync(embed : current.ToEmbed().Build()); _cron.Schedule(TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(1), uint.MaxValue, async() => { // Get current challenge var c = await _challenges.GetCurrentChallenge(); // Update embed await message.ModifyAsync(a => a.Embed = current.ToEmbed().Build()); // Keep running this task while the challenge is the same challenge that was initially scheduled return(c?.Id == current.Id); }); } }
public async Task CurrentCompetition() { var current = await _challenges.GetCurrentChallenge(); if (current == null) { await ReplyAsync("There is no challenge currently running"); } else { var message = await ReplyAsync(embed : current.ToEmbed().Build()); await _messages.TrackMessage(message.Channel.Id, message.Id, current.Id, MessageType.Current); } }
public async Task UpdateCurrentMessage(Message message) { var currentChallenge = await _challenges.GetCurrentChallenge(); var challenge = await _challenges.GetChallenges(id : message.ChallengeID).FirstAsync(); if (challenge == null) { Console.WriteLine("Message exists for inexistant challenge " + message.ChallengeID); await RemoveMessage(message); } else { if (!(_client.GetChannel(message.ChannelID) is ISocketMessageChannel channel)) { Console.WriteLine($"No such channel: {message.ChannelID}"); await RemoveMessage(message); return; } if (!((await channel.GetMessageAsync(message.MessageID)) is IUserMessage msg)) { Console.WriteLine($"No such message: {message.MessageID}"); await RemoveMessage(message); return; } await msg.ModifyAsync(a => a.Embed = challenge.ToEmbed().Build()); if (currentChallenge == null || challenge.Id != currentChallenge.Id) { await RemoveMessage(message); } } }
public async Task Start() { while (true) { State = SchedulerState.StartingChallenge; // Find the currently running challenge var current = await _challenges.GetCurrentChallenge(); // If there is no challenge running try to start a new one if (current == null) { Console.WriteLine("There is no current challenge - attempting to start a new one"); // Start the next challenge, if there isn't one wait a while var next = await _challenges.StartNext(); if (next == null) { Console.WriteLine("No challenges available, waiting for a while..."); State = SchedulerState.WaitingNoChallengesInPool; await Task.Delay(TimeSpan.FromMinutes(1)); continue; } Console.WriteLine($"Starting new challenge {next.Name}"); // Notify all subscribed channels about the new challenge await NotifyStart(next); current = next; } else { Console.WriteLine($"{current.Name} challenge is currently running"); } //There is a challenge running, wait until the end time or until someone externally pokes us awake var endTime = current.EndTime; while (endTime != null && endTime > DateTime.UtcNow) { var delay = endTime.Value - DateTime.UtcNow; if (delay > TimeSpan.Zero) { State = SchedulerState.WaitingChallengeEnd; await Task.WhenAny(_poker.WaitAsync(), Task.Delay(delay)); } } // If endtime is after now then something else poked the scheduler awake, reset scheduler logic if (endTime != null && endTime > DateTime.UtcNow) { continue; } State = SchedulerState.EndingChallenge; // Finish the current challenge await _challenges.EndCurrentChallenge(); // Transfer scores to leaderboard await UpdateLeaderboard(current, _solutions.GetSolutions(current.Id, uint.MaxValue)); // Get the leaderboard for the challenge that just finished and notify everyone await NotifyEnd(current, _solutions.GetSolutions(current.Id, uint.MaxValue)); // Wait for a cooldown period State = SchedulerState.WaitingCooldown; await Task.WhenAny(_poker.WaitAsync(), Task.Delay(TimeSpan.FromHours(23))); } }
public async Task SubmitSolution([Remainder] string input) { var code = input.ExtractYololCodeBlock(); if (code == null) { await ReplyAsync(@"Failed to parse a yolol program from message - ensure you have enclosed your solution in triple backticks \`\`\`like this\`\`\`"); return; } var challenge = await _challenges.GetCurrentChallenge(); if (challenge == null) { await ReplyAsync("There is no currently running challenge!"); return; } var(success, failure) = await _verification.Verify(challenge, code); if (failure != null) { var message = failure.Type switch { FailureType.ParseFailed => $"Code is not valid Yolol code: {failure.Hint}", FailureType.RuntimeTooLong => "Program took too long to produce a result", FailureType.IncorrectResult => $"Program produced an incorrect value! {failure.Hint}", FailureType.ProgramTooLarge => "Program is too large - it must be 20 lines by 70 characters per line", _ => throw new ArgumentOutOfRangeException() }; await ReplyAsync($"Verification failed! {message}."); } else if (success != null) { var solution = await _solutions.GetSolution(Context.User.Id, challenge.Id); if (solution.HasValue && success.Score < solution.Value.Score) { await ReplyAsync($"Verification complete! You score {success.Score} points. Less than your current best of {solution.Value.Score}"); } else { // Get the current top solution var topBefore = await _solutions.GetTopRank(challenge.Id).ToArrayAsync(); // Submit this solution await _solutions.SetSolution(new Solution(challenge.Id, Context.User.Id, success.Score, code)); var rank = await _solutions.GetRank(challenge.Id, Context.User.Id); var rankNum = uint.MaxValue; if (rank.HasValue) { rankNum = rank.Value.Rank; } await ReplyAsync($"Verification complete! You scored {success.Score} points. You are currently rank {rankNum} for this challenge."); // If this is the top ranking score, and there was a top ranking score before, and it wasn't this user: alert everyone if (rankNum == 1 && topBefore.Length > 0 && topBefore.All(a => a.Solution.UserId != Context.User.Id)) { var embed = new EmbedBuilder { Title = "Rank Alert", Color = Color.Gold, Footer = new EmbedFooterBuilder().WithText("A Cylon Project") }; var self = await _client.GetUserName(Context.User.Id); var prev = (await topBefore.ToAsyncEnumerable().SelectAwait(async a => await _client.GetUserName(a.Solution.UserId)).ToArrayAsync()).Humanize("&"); embed.Description = success.Score == topBefore[0].Solution.Score ? $"{self} ties for rank #1" : $"{self} takes rank #1 from {prev}!"; await _broadcast.Broadcast(embed.Build()); } } } else { throw new InvalidOperationException("Failed to verify solution (this is a bug, please contact @Martin#2468)"); } }