public async Task Score(CommandContext ctx) { Set playerSet = Matchmaker.Sets.FirstOrDefault(e => e.AllPlayers.Any(f => f.DiscordId == ctx.User.Id)); DiscordRole modRole = ctx.Guild.Roles.First(e => e.Name == "Moderator"); if (playerSet == null) { return; } if (playerSet.DraftPlayers.Any()) { return; } if (playerSet.BravoTeam.Score > SET_MATCH_NUMBER / 2 || playerSet.AlphaTeam.Score > SET_MATCH_NUMBER / 2) { return; } if (playerSet.Locked) { await ctx.RespondAsync("This set will be locked until a moderator addresses the report. Please wait."); return; } if (playerSet.ResolveMode > 0) { return; } if (ctx.Channel.Id != (await CommandHelper.ChannelFromSet(playerSet.SetNumber)).Id) { return; } if (!playerSet.AlphaTeam.IsCaptain(ctx.User.Id) && !playerSet.BravoTeam.IsCaptain(ctx.User.Id)) { await ctx.RespondAsync("Only the captain of the losing team can report the score."); return; } string team = playerSet.AlphaTeam.IsCaptain(ctx.User.Id) ? "bravo" : "alpha"; playerSet.ReportScore(team); if (playerSet.AlphaTeam.Score > SET_MATCH_NUMBER / 2 || playerSet.BravoTeam.Score > SET_MATCH_NUMBER / 2 || playerSet.MatchNum == SET_MATCH_NUMBER) { string winner = playerSet.AlphaTeam.Score > playerSet.BravoTeam.Score ? "Alpha" : "Bravo"; string loser = playerSet.AlphaTeam.Score < playerSet.BravoTeam.Score ? "Alpha" : "Bravo"; DiscordEmbedBuilder builder = new DiscordEmbedBuilder(); builder.WithTitle("__Results__"); builder.AddField(e => { e.Name = "Score"; e.IsInline = true; e.Value = $"{winner} Wins {playerSet.AlphaTeam.Score} - {playerSet.BravoTeam.Score}"; }); await ctx.RespondAsync($"The winner of this set is Team {winner}!", embed : builder.Build()); DiscordRole loserRole = loser == "Alpha" ? ctx.Guild.Roles.First(e => e.Name == $"Alpha ({playerSet.SetNumber})") : ctx.Guild.Roles.First(e => e.Name == $"Bravo ({playerSet.SetNumber})"); await ctx.RespondAsync( $"{loserRole.Mention}, please acknowledge these results by either sending \"confirm\" or \"deny\"."); InteractivityModule interactivity = ctx.Client.GetInteractivityModule(); DateTime timeoutDateTime = DateTime.Now + TimeSpan.FromMinutes(2); MessageContext replyMessage; try { replyMessage = await interactivity.WaitForMessageAsync(x => { return(((DiscordMember)x.Author).Roles.Select(e => e.Id).Contains(loserRole.Id)); }, TimeSpan.FromMinutes(1)); } catch (Exception e) { Console.WriteLine(e); Logger.Error(e); throw; } while (true) { if (replyMessage.Message == null) { await ctx.RespondAsync("Time's up! Assuming the losing team has accepted their loss."); await this.EndMatchAsync(playerSet, ctx); return; } if (replyMessage.Message.Content.ToLower() == "confirm") { await this.EndMatchAsync(playerSet, ctx); return; } if (replyMessage.Message.Content.ToLower() == "deny") { await ctx.RespondAsync($"{modRole.Mention} issue reported by {replyMessage.Message.Author.Mention}. " + $"To resolve the error, use `%resolve` and follow the resulting instructions." + $" Otherwise, use `%resolve deny` to continue reporting the current score."); return; } TimeSpan timeSpan = timeoutDateTime - DateTime.Now; if (timeSpan <= TimeSpan.Zero) { await ctx.RespondAsync("Time's up! Assuming the losing team has accepted their loss."); await this.EndMatchAsync(playerSet, ctx); return; } replyMessage = await interactivity.WaitForMessageAsync(x => { return(((DiscordMember)x.Author).Roles.Select(e => e.Id).Contains(loserRole.Id)); }, timeSpan); } } else { try { playerSet.MatchNum++; Stage selectedStage = playerSet.GetCurrentStage(); await ctx.RespondAsync(embed : selectedStage .GetEmbedBuilder($"Match {playerSet.MatchNum} of 7: {selectedStage.MapName}") .AddField(e => { e.Name = "Alpha Team's Score"; e.Value = playerSet.AlphaTeam.Score; e.IsInline = true; }) .AddField(e => { e.Name = "Bravo Team's Score"; e.Value = playerSet.BravoTeam.Score; e.IsInline = true; }) .Build()); DiscordMessage feedMessage = (DiscordMessage)await ctx.Guild.GetChannel(666563839646760960).GetMessageAsync(OrderedFeedMessages[playerSet.SetNumber - 1]); await feedMessage.ModifyAsync(embed : playerSet.GetFeedEmbedBuilder(ctx.Channel).Build()); } catch (Exception e) { Console.WriteLine(e); throw; } } }
public async Task Overwrite(CommandContext ctx, string team, int set = 0) { Set selectedSet; DiscordRole modRole = ctx.Guild.Roles.First(e => e.Name == "Moderator"); if (set == 0) { selectedSet = CommandHelper.SetFromChannel(ctx.Channel.Id); if (selectedSet == null) { await ctx.RespondAsync("Please specify set number or use the correct channel as context."); return; } if (selectedSet.ResolveMode <= 0) { // Force report score by moderator. selectedSet.ReportScore(team); if (selectedSet.AlphaTeam.Score > SET_MATCH_NUMBER / 2 || selectedSet.BravoTeam.Score > SET_MATCH_NUMBER / 2 || selectedSet.MatchNum == SET_MATCH_NUMBER) { string winner = selectedSet.AlphaTeam.Score > selectedSet.BravoTeam.Score ? "Alpha" : "Bravo"; string loser = selectedSet.AlphaTeam.Score < selectedSet.BravoTeam.Score ? "Alpha" : "Bravo"; DiscordEmbedBuilder builder = new DiscordEmbedBuilder(); builder.WithTitle("__Results__"); builder.AddField(e => { e.Name = "Score"; e.IsInline = true; e.Value = $"{winner} Wins {selectedSet.AlphaTeam.Score} - {selectedSet.BravoTeam.Score}"; }); await ctx.RespondAsync($"The winner of this set is Team {winner}!", embed : builder.Build()); DiscordRole loserRole = loser == "Alpha" ? ctx.Guild.Roles.First(e => e.Name == $"Alpha ({selectedSet.SetNumber})") : ctx.Guild.Roles.First(e => e.Name == $"Bravo ({selectedSet.SetNumber})"); await ctx.RespondAsync( $"{loserRole.Mention}, please acknowledge these results by either sending \"confirm\" or \"deny\"."); InteractivityModule interactivity = ctx.Client.GetInteractivityModule(); DateTime timeoutDateTime = DateTime.Now + TimeSpan.FromMinutes(2); MessageContext replyMessage; try { replyMessage = await interactivity.WaitForMessageAsync(x => { return(((DiscordMember)x.Author).Roles.Select(e => e.Id).Contains(loserRole.Id)); }, TimeSpan.FromMinutes(1)); } catch (Exception e) { Console.WriteLine(e); Logger.Error(e); throw; } while (true) { if (replyMessage.Message == null) { await ctx.RespondAsync("Time's up! Assuming the losing team has accepted their loss."); await this.EndMatchAsync(selectedSet, ctx); return; } if (replyMessage.Message.Content.ToLower() == "confirm") { await this.EndMatchAsync(selectedSet, ctx); return; } if (replyMessage.Message.Content.ToLower() == "deny") { await ctx.RespondAsync($"{modRole.Mention} issue reported by {replyMessage.Message.Author.Mention}. " + $"To resolve the error, use `%resolve` and follow the resulting instructions." + $" Otherwise, use `%resolve deny` to continue reporting the current score."); return; } replyMessage = await interactivity.WaitForMessageAsync(x => { return(((DiscordMember)x.Author).Roles.Select(e => e.Id).Contains(loserRole.Id)); }, timeoutDateTime - DateTime.Now); } } else { try { selectedSet.MatchNum++; Stage selectedStage = selectedSet.GetCurrentStage(); await ctx.RespondAsync(embed : selectedStage .GetEmbedBuilder($"Match {selectedSet.MatchNum} of 7: {selectedStage.MapName}") .AddField(e => { e.Name = "Alpha Team's Score"; e.Value = selectedSet.AlphaTeam.Score; e.IsInline = true; }) .AddField(e => { e.Name = "Bravo Team's Score"; e.Value = selectedSet.BravoTeam.Score; e.IsInline = true; }) .Build()); DiscordMessage feedMessage = (DiscordMessage)await ctx.Guild.GetChannel(666563839646760960).GetMessageAsync(OrderedFeedMessages[selectedSet.SetNumber - 1]); await feedMessage.ModifyAsync(embed : selectedSet.GetFeedEmbedBuilder(ctx.Channel).Build()); } catch (Exception e) { Console.WriteLine(e); throw; } } return; // End force report logic. } } else { selectedSet = Matchmaker.Sets[set - 1]; } team = team.ToLower(); selectedSet.ReportScore(team); selectedSet.MatchNum++; selectedSet.ResolveMode--; if (selectedSet.ResolveMode == 0) { if (selectedSet.AlphaTeam.Score > SET_MATCH_NUMBER / 2 || selectedSet.BravoTeam.Score > SET_MATCH_NUMBER / 2 || selectedSet.MatchNum == SET_MATCH_NUMBER) { await ctx.RespondAsync("Resolved all issues! All scores will be reported to Airtable."); await this.EndMatchAsync(selectedSet, ctx); } else { await ctx.RespondAsync("Resolved all issues! Teams, continue with your matches."); selectedSet.MatchNum++; Stage selectedStage = selectedSet.Stages[selectedSet.MatchNum - 1]; await ctx.RespondAsync(embed : selectedStage .GetEmbedBuilder($"Match {selectedSet.MatchNum} of 7: {selectedStage.MapName}") .AddField(e => { e.Name = "Alpha Team's Score"; e.Value = selectedSet.AlphaTeam.Score; e.IsInline = true; }) .AddField(e => { e.Name = "Bravo Team's Score"; e.Value = selectedSet.BravoTeam.Score; e.IsInline = true; }) .Build()); DiscordMessage feedMessage = await ctx.Guild.GetChannel(666563839646760960).GetMessageAsync(OrderedFeedMessages[selectedSet.SetNumber - 1]); await feedMessage.ModifyAsync(embed : selectedSet.GetFeedEmbedBuilder(ctx.Channel).Build()); } } else { Stage selectedStage = selectedSet.Stages[selectedSet.MatchNum]; await ctx.RespondAsync("Moderator, use `%overwrite [Team]` to select the winner for this map.", embed : selectedStage.GetEmbedBuilder($"Match {selectedSet.MatchNum + 1} of 7: {selectedStage.MapName}") .AddField(e => { e.Name = "Alpha Team's Score"; e.Value = selectedSet.AlphaTeam.Score; e.IsInline = true; }) .AddField(e => { e.Name = "Bravo Team's Score"; e.Value = selectedSet.BravoTeam.Score; e.IsInline = true; }) .Build()); } }
private async Task JoinLobby(CommandContext ctx, SdlPlayer sdlPlayer, bool debugFill = false, int?lobbyNumber = null) { try { Lobby matchedLobby; if (lobbyNumber != null) { LobbySelectResponse lobbySelectResponse = Matchmaker.SelectLobbyByNumber(sdlPlayer, lobbyNumber.Value); if (!lobbySelectResponse.Success) { if (lobbySelectResponse.Exception != null) { Logger.Error(lobbySelectResponse.Exception); } if (!string.IsNullOrEmpty(lobbySelectResponse.Message)) { await ctx.RespondAsync(lobbySelectResponse.Message); } return; } matchedLobby = lobbySelectResponse.Result; if (!string.IsNullOrEmpty(lobbySelectResponse.Message)) { await ctx.RespondAsync(lobbySelectResponse.Message); } } else { LobbySelectResponse lobbySelectResponse = Matchmaker.FindLobby(sdlPlayer); if (!lobbySelectResponse.Success) { if (lobbySelectResponse.Exception != null) { Logger.Error(lobbySelectResponse.Exception); } if (!string.IsNullOrEmpty(lobbySelectResponse.Message)) { await ctx.RespondAsync(lobbySelectResponse.Message); } return; } if (!string.IsNullOrEmpty(lobbySelectResponse.Message)) { await ctx.RespondAsync(lobbySelectResponse.Message); } matchedLobby = lobbySelectResponse.Result; } matchedLobby.AddPlayer(sdlPlayer); if (debugFill) { foreach (SdlPlayer nextPlayer in (await MySqlClient.RetrieveAllSdlPlayers()).Where(e => e != sdlPlayer).Take(7)) { matchedLobby.AddPlayer(nextPlayer, true); } } if (matchedLobby.IsFull) { MoveToSetResponse moveToSetResponse = Matchmaker.MoveLobbyToSet(matchedLobby); if (!moveToSetResponse.Success) { if (moveToSetResponse.Exception != null) { Logger.Error(moveToSetResponse.Exception); } if (moveToSetResponse.Message != null) { await ctx.RespondAsync(moveToSetResponse.Message, embed : matchedLobby.GetEmbedBuilder().Build()); } return; } if (!string.IsNullOrEmpty(moveToSetResponse.Message)) { await ctx.RespondAsync(moveToSetResponse.Message); } Set newSet = moveToSetResponse.Result; newSet.Closed += this.NewMatch_Closed; DiscordRole setRole = ctx.Guild.Roles.First(e => e.Name == $"In Set ({newSet.SetNumber})"); foreach (SdlPlayer setPlayer in newSet.AllPlayers) { DiscordMember member = await ctx.Guild.GetMemberAsync(setPlayer.DiscordId); await member.GrantRoleAsync(setRole); } DiscordChannel setChannel = await CommandHelper.ChannelFromSet(newSet.SetNumber); await ctx.RespondAsync($"Lobby filled! Please move to {setChannel.Mention}."); await ctx.Guild.UpdateRoleAsync(setRole, mentionable : true); DiscordMessage lastMessage = await setChannel.SendMessageAsync( $"{setRole.Mention} Welcome to set #{newSet.SetNumber}! To begin, " + $"{(await ctx.Guild.GetMemberAsync(newSet.BravoTeam.Captain.DiscordId)).Mention} will have " + $"one minute to pick a player using `%pick [player]`.", embed : newSet.GetEmbedBuilder().Build()); await ctx.Guild.UpdateRoleAsync(setRole, mentionable : false); newSet.DraftTimeout += NewSet_DraftTimeout; newSet.ResetTimeout(); } else { string message = $"{sdlPlayer.DiscordId.ToUserMention()} has been added to " + $"Lobby #{matchedLobby.LobbyNumber}. {8 - matchedLobby.Players.Count} players needed to begin."; DiscordRole classOneRole = ctx.Guild.GetRole(600770643075661824); DiscordRole classTwoRole = ctx.Guild.GetRole(600770814521901076); DiscordRole classThreeRole = ctx.Guild.GetRole(600770862307606542); DiscordRole classFourRole = ctx.Guild.GetRole(600770905282576406); DiscordRole[] notifRoles = { classOneRole, classTwoRole, classThreeRole, classFourRole }; if (matchedLobby.Players.Count == 1) { matchedLobby.DeltaUpdated += MatchedLobby_DeltaUpdated; message = $"{notifRoles[(int)matchedLobby.Class - 1].Mention} " + $"{((int)matchedLobby.Class - 2 > 0 ? notifRoles[(int)matchedLobby.Class - 2].Mention + " " : "")}" + $"A new lobby has been started! {message}"; } DiscordEmbedBuilder builder = matchedLobby.GetEmbedBuilder(); await ctx.RespondAsync(message, false, builder.Build()); } } catch (Exception e) { Console.WriteLine(e); Logger.Error(e); throw; } }
public async Task Resolve(CommandContext ctx, string deny = null, int setNumber = 0) { Set playerSet; if (setNumber == 0) { playerSet = CommandHelper.SetFromChannel(ctx.Channel.Id); if (playerSet == null) { await ctx.RespondAsync("Please specify set number or use the correct channel as context."); return; } } else { playerSet = Matchmaker.Sets[setNumber - 1]; } playerSet.Locked = false; if (deny == "deny") { if (playerSet.AlphaTeam.Score > SET_MATCH_NUMBER / 2 || playerSet.BravoTeam.Score > SET_MATCH_NUMBER / 2 || playerSet.MatchNum == SET_MATCH_NUMBER) { await this.EndMatchAsync(playerSet, ctx); return; } await ctx.RespondAsync("The report has been resolved by a moderator. This is a final decision. Please continue with the set."); Stage selectedRandomStage = playerSet.GetCurrentStage(); await ctx.RespondAsync(embed : selectedRandomStage .GetEmbedBuilder($"Match {playerSet.MatchNum} of 7: {selectedRandomStage.MapName}") .AddField(e => { e.Name = "Alpha Team's Score"; e.Value = playerSet.AlphaTeam.Score; e.IsInline = true; }) .AddField(e => { e.Name = "Bravo Team's Score"; e.Value = playerSet.BravoTeam.Score; e.IsInline = true; }) .Build()); return; } playerSet.MatchNum--; playerSet.ResolveMode = playerSet.MatchNum; playerSet.MatchNum = 0; playerSet.AlphaTeam.OrderedMatchResults.Clear(); playerSet.BravoTeam.OrderedMatchResults.Clear(); Stage selectedStage = playerSet.Stages[0]; await ctx.RespondAsync("Moderator, use `%overwrite [Team]` to select the winner for this map.", embed : selectedStage.GetEmbedBuilder($"Match 1 of 7: {selectedStage.MapName}") .AddField(e => { e.Name = "Alpha Team's Score"; e.Value = playerSet.AlphaTeam.Score; e.IsInline = true; }) .AddField(e => { e.Name = "Bravo Team's Score"; e.Value = playerSet.BravoTeam.Score; e.IsInline = true; }) .Build()); }
public async Task Leave(CommandContext ctx) { try { if (!(ctx.User is DiscordMember user)) { return; } Lobby joinedLobby = Matchmaker.Lobbies.FirstOrDefault(e => e.Players.Any(f => f.DiscordId == user.Id)); if (joinedLobby != null) { joinedLobby.RemovePlayer(joinedLobby.Players.FirstOrDefault(e => e.DiscordId == user.Id)); await ctx.RespondAsync($"You have left lobby #{joinedLobby.LobbyNumber}."); if (joinedLobby.Players.Count == 0) { joinedLobby.Close(); await ctx.RespondAsync($"Lobby #{joinedLobby.LobbyNumber} has been disbanded."); } } else { Set joinedSet = Matchmaker.Sets.FirstOrDefault(e => e.AllPlayers.Any(f => f.DiscordId == user.Id)); if (joinedSet == null) { return; } if (ctx.Channel.Id != (await CommandHelper.ChannelFromSet(joinedSet.SetNumber)).Id) { return; } decimal penalty = MatchModule.CalculatePoints(joinedSet) / 2 + 10; string penaltyDir = Directory.CreateDirectory(Path.Combine(Globals.AppPath, "Penalties")).FullName; string penaltyFile = Path.Combine(penaltyDir, $"{user.Id}.penalty"); string penaltyMessage = $"If you leave the set, you will be instated with a penalty of {penalty} points. "; Record record; if (File.Exists(penaltyFile)) { record = JsonConvert.DeserializeObject <Record>(File.ReadAllText(penaltyFile)); int infractionCount = record.InfractionsThisMonth() + 1; switch (infractionCount) { case 1: penaltyMessage += ""; break; case 2: penaltyMessage += "In addition, you will be banned from participating in SDL for 24 hours."; break; case 3: penaltyMessage += "In addition, you will be banned from participating in SDL for 1 week."; break; default: penaltyMessage += "In addition, you will be banned from participating in SDL for 1 week AND will be barred from participating in cups."; break; } } else { penaltyMessage += " Otherwise, this time will be just a warning."; record = new Record { AllInfractions = new List <Infraction>() }; } await ctx.RespondAsync(penaltyMessage + "\nAre you sure you wish to leave the set? (Y/N)"); InteractivityModule interactivity = ctx.Client.GetInteractivityModule(); MessageContext response = await interactivity.WaitForMessageAsync(x => user.Id == x.Author.Id, TimeSpan.FromMinutes(1)); if (response == null) { await ctx.RespondAsync($"{user.Mention} took too long to respond. Assuming you changed your mind, please continue with the set."); } else if (response.Message.Content.ToLower() == "y") { decimal points = await MatchModule.ReportScores(joinedSet, true); await MySqlClient.PenalizePlayer(await MySqlClient.RetrieveSdlPlayer(user.Id), (int)penalty, "Left a set."); record.AllInfractions.Add(new Infraction { Penalty = (int)penalty, Notes = "Left a set.", TimeOfOffense = DateTime.Now }); if (joinedSet.AlphaTeam.Players.Any(e => e.DiscordId == user.Id)) { joinedSet.AlphaTeam.RemovePlayer( joinedSet.AlphaTeam.Players.First(e => e.DiscordId == user.Id)); } else if (joinedSet.BravoTeam.Players.Any(e => e.DiscordId == user.Id)) { joinedSet.BravoTeam.RemovePlayer( joinedSet.BravoTeam.Players.First(e => e.DiscordId == user.Id)); } else if (joinedSet.DraftPlayers.Any(e => e.DiscordId == user.Id)) { joinedSet.DraftPlayers.Remove( joinedSet.DraftPlayers.First(e => e.DiscordId == user.Id)); } List <DiscordMember> remainingUsers = ctx.Guild.Members.Where(x => joinedSet.AllPlayers.Any(y => y.DiscordId == x.Id)).ToList(); File.WriteAllText(penaltyFile, JsonConvert.SerializeObject(record, Formatting.Indented)); await ctx.RespondAsync( $"{user.Mention} Aforementioned penalty applied. Don't make a habit of this! " + $"As for the rest of the set, you will return to <#572536965833162753> to requeue. " + $"Beginning removal of access to this channel in 30 seconds. " + $"Rate limiting may cause the full process to take up to two minutes.", embed : joinedSet.GetScoreEmbedBuilder(points, points / 2).Build()); /*Lobby movedLobby = Matchmaker.Lobbies.First(e => !e.Players.Any()); * * if (movedLobby == null) * { * // TODO Not sure what to do if all lobbies are filled. * return; * } * * foreach (SdlPlayer joinedSetPlayer in joinedSet.AllPlayers) * { * movedLobby.AddPlayer(joinedSetPlayer, true); * }*/ joinedSet.Close(); await Task.Delay(TimeSpan.FromSeconds(30)); List <DiscordRole> roleRemovalList = CommandHelper.DraftRoleIds.Select(e => ctx.Guild.GetRole(e)).ToList(); await user.RemoveRolesAsync(roleRemovalList.Where(x => user.Roles.Select(xr => xr.Id).Contains(x.Id))); foreach (DiscordMember member in remainingUsers) { await member.RemoveRolesAsync(roleRemovalList.Where(x => member.Roles.Any(f => f.Id == x.Id))); } /*await (await ctx.Client.GetChannelAsync(572536965833162753)) * .SendMessageAsync($"{8 - movedLobby.Players.Count} players needed to begin.", * embed: movedLobby.GetEmbedBuilder().Build());*/ } else { await ctx.RespondAsync("Assuming you declined leaving since you did not reply with \"Y\". Please continue with the set."); } } } catch (Exception e) { Console.WriteLine(e); throw; } }