public static async Task Run(SocketSlashCommand command, DiscordSocketClient client, StorageClient storageClient, Dictionary <string, SocketSlashCommandDataOption> options, Guild guild, ISocketMessageChannel recruitingChannel, List <Team> teams)
        {
            var guildUser   = (SocketGuildUser)options["username"].Value;
            var discordUser = guildUser.Nickname ?? guildUser.Username;

            // Player not exist? -> respond with error
            (var oldTeam, var player) = Team.FindPlayer(teams, discordUser);
            if (player == null)
            {
                await command.FollowupAsync($"User {discordUser} does not exist in the recruiting table", ephemeral : true);

                return;
            }

            oldTeam.RemovePlayer(player);

            // Update old team message
            if (oldTeam.Players.Count > 0)
            {
                await recruitingChannel.ModifyMessageAsync(oldTeam.MsgId, (message) => message.Content = oldTeam.ToMessage());

                await storageClient.SaveTableRow(Team.TableName, oldTeam.Name, guild.RowKey, oldTeam);
            }
            else
            {
                await recruitingChannel.DeleteMessageAsync(oldTeam.MsgId);

                await storageClient.DeleteTableRow(Team.TableName, oldTeam.Name, guild.RowKey);
            }

            await command.FollowupAsync($"You have removed user {discordUser} from {oldTeam.Name}", ephemeral : true);
        }
Exemple #2
0
        public static async Task Run(SocketSlashCommand command, DiscordSocketClient client, StorageClient storageClient, Dictionary <string, SocketSlashCommandDataOption> options, Guild guild, ISocketMessageChannel recruitingChannel, List <Team> teams)
        {
            var guildUser = (SocketGuildUser)options["username"].Value;
            var teamName  = String.Empty;

            if (options.TryGetValue("team", out SocketSlashCommandDataOption teamOption))
            {
                teamName = teamOption.Value.ToString();
            }

            // Construct new player from parameters
            var newPlayer = new Player();

            newPlayer.DiscordUser = guildUser.Nickname ?? guildUser.Username;
            newPlayer.Platform    = (Platform)Enum.Parse(typeof(Platform), options["platform"].Value.ToString());
            newPlayer.PlatformId  = options["id"].Value.ToString();

            if (newPlayer.Platform == Platform.Tracker && !Player.ValidateTrackerLink(newPlayer.PlatformId))
            {
                await command.FollowupAsync($"Your RL tracker link is invalid", ephemeral : true);

                return;
            }

            // Is player just updating tracker link? -> Update link
            (var team, var existingPlayer) = Team.FindPlayer(teams, newPlayer.DiscordUser);

            if (existingPlayer != null && !string.Equals(team.Name, teamName, StringComparison.InvariantCultureIgnoreCase))
            {
                await command.FollowupAsync($"Invalid use of add command. Please use the move command to change a user between teams", ephemeral : true);

                return;
            }

            if (team == null)
            {
                teamName = string.IsNullOrEmpty(teamName) ? "Free_Agents" : teamName;
                team     = Team.AddPlayer(teams, teamName, newPlayer);
            }
            else
            {
                existingPlayer.Platform   = newPlayer.Platform;
                existingPlayer.PlatformId = newPlayer.PlatformId;
            }

            // Have we added this team message yet? -> Write team message and move to next team
            if (team.MsgId == 0)
            {
                team.MsgId = (await recruitingChannel.SendMessageAsync(team.ToMessage())).Id;
            }
            else
            {
                // This is an existing team -> Modify old team message
                await recruitingChannel.ModifyMessageAsync(team.MsgId, (message) => message.Content = team.ToMessage());
            }

            await storageClient.SaveTableRow(Team.TableName, team.Name, guild.RowKey, team);

            await command.FollowupAsync($"{newPlayer.DiscordUser}'s RL tracker has been added to the recruiting board in channel <#{recruitingChannel.Id}>", ephemeral : true);
        }
Exemple #3
0
        public static async Task Run(SocketSlashCommand command, DiscordSocketClient client, StorageClient storageClient, Dictionary <string, SocketSlashCommandDataOption> options, Guild guild, ISocketMessageChannel recruitingChannel, List <Team> teams)
        {
            var user = command.User as SocketGuildUser;

            // Construct new player from parameters
            var newPlayer = new Player();

            newPlayer.DiscordUser = user.Nickname ?? user.Username;
            newPlayer.Platform    = (Platform)Enum.Parse(typeof(Platform), options["platform"].Value.ToString());
            newPlayer.PlatformId  = options["id"].Value.ToString();

            if (newPlayer.Platform == Platform.Tracker && !Player.ValidateTrackerLink(newPlayer.PlatformId))
            {
                await command.FollowupAsync($"Your RL tracker link is invalid", ephemeral : true);

                return;
            }

            // Is player just updating tracker link? -> Update link
            (var team, var existingPlayer) = Team.FindPlayer(teams, newPlayer.DiscordUser);

            // Is player not on a team? -> Add to FreeAgents
            if (team == null)
            {
                team = Team.AddPlayer(teams, "Free_Agents", newPlayer);
            }
            else
            {
                existingPlayer.Platform   = newPlayer.Platform;
                existingPlayer.PlatformId = newPlayer.PlatformId;
            }

            // Have we added this team message yet? -> Write team message and move to next team
            if (team.MsgId == 0)
            {
                team.MsgId = (await recruitingChannel.SendMessageAsync(team.ToMessage())).Id;
            }
            else
            {
                // This is an existing team -> Modify old team message
                await recruitingChannel.ModifyMessageAsync(team.MsgId, (message) => message.Content = team.ToMessage());
            }

            await storageClient.SaveTableRow(Team.TableName, team.Name, guild.RowKey, team);

            await command.FollowupAsync($"Your RL tracker has been added to the recruiting board in channel <#{recruitingChannel.Id}>", ephemeral : true);
        }
        public static async Task Run(SocketSlashCommand command, DiscordSocketClient client, StorageClient storageClient, Dictionary <string, SocketSlashCommandDataOption> options, Guild guild, ISocketMessageChannel recruitingChannel, List <Team> teams)
        {
            var teamName = options["team"].Value.ToString();

            // Player not exist? -> respond with error
            var team = Team.FindTeam(teams, teamName);

            if (team == null)
            {
                await command.FollowupAsync($"Team {teamName} does not exist in the recruiting table", ephemeral : true);

                return;
            }

            // Remove old team message
            await recruitingChannel.DeleteMessageAsync(team.MsgId);

            await storageClient.DeleteTableRow(Team.TableName, team.Name, guild.RowKey);

            await command.FollowupAsync($"You have removed team {teamName}", ephemeral : true);
        }
Exemple #5
0
        public static async Task Run(SocketSlashCommand command, DiscordSocketClient client, StorageClient storageClient, Dictionary <string, SocketSlashCommandDataOption> options, Guild guild, ISocketMessageChannel recruitingChannel, List <Team> teams)
        {
            var teamName          = options["team"].Value.ToString();
            var lookingForPlayers = (bool)options["looking"].Value;

            // Player not exist? -> respond with error
            var team = Team.FindTeam(teams, teamName);

            if (team == null)
            {
                await command.FollowupAsync($"Team {teamName} does not exist in the recruiting table", ephemeral : true);

                return;
            }

            team.LookingForPlayers = lookingForPlayers;

            await recruitingChannel.ModifyMessageAsync(team.MsgId, (message) => message.Content = team.ToMessage());

            await storageClient.SaveTableRow(Team.TableName, teamName, guild.RowKey, team);

            await command.FollowupAsync($"You marked team {team.Name} as looking for players {lookingForPlayers}", ephemeral : true);
        }
Exemple #6
0
        public static async Task Print(SocketSlashCommand command)
        {
            var data = await WebUtils.DownloadString("https://www.rottentomatoes.com/browse/in-theaters?minTomato=0&maxTomato=100&genres=1;2;4;5;6;8;9;10;11;13;18;14&sortBy=popularity");

            data = data.CutBeforeAndAfter("document.getElementById('main-row')", "mps,")
                   .CutBefore("},")
                   .CutBefore("},");

            data = data.Substring(0, data.LastIndexOf("]") + 1);

            dynamic resultItems = JsonConvert.DeserializeObject(data);

            var result = new StringBuilder();

            string icon;

            for (int i = 0; i < 10; i++)
            {
                switch (resultItems[i].tomatoIcon.ToString())
                {
                case "certified_fresh":
                    icon = "<:certified_fresh:737761619375030422>";
                    break;

                case "fresh":
                    icon = "<:fresh:737761619299270737>";
                    break;

                case "rotten":
                    icon = "<:rotten:737761619299532874>";
                    break;

                default:
                    icon = "";
                    break;
                }

                result.AppendLine($"`{i + 1}` {resultItems[i].title} `{resultItems[i].theaterReleaseDate}` {(resultItems[i].tomatoScore == null ? "N/A" : resultItems[i].tomatoScore + "%")} {icon}");
            }

            await command.FollowupAsync(null, embed : new EmbedBuilder()
                                        .WithTitle("Top Box Office")
                                        .WithColor(EmbedUtils.Red)
                                        .WithFooter("Via RottenTomatoes.com")
                                        .WithDescription(result.ToString())
                                        .Build());
        }
Exemple #7
0
        public static async Task Run(SocketSlashCommand command, DiscordSocketClient client, StorageClient storageClient, Dictionary <string, SocketSlashCommandDataOption> options, Guild guild, ISocketMessageChannel recruitingChannel, List <Team> teams)
        {
            var guildUser   = (SocketGuildUser)options["username"].Value;
            var discordUser = guildUser.Nickname ?? guildUser.Username;
            var teamName    = options["team"].Value.ToString();
            var captain     = options.ContainsKey("captain") && (bool)options["captain"].Value;

            // Player not exist? -> respond with error
            (var oldTeam, var player) = Team.FindPlayer(teams, discordUser);
            if (player == null)
            {
                await command.FollowupAsync($"User {discordUser} does not exist in the recruiting table", ephemeral : true);

                return;
            }

            oldTeam.RemovePlayer(player);
            var  newTeam   = Team.AddPlayer(teams, teamName, player, captain);
            bool isNewTeam = newTeam.MsgId == 0;

            // Update old team message
            if (oldTeam.Players.Count > 0)
            {
                await recruitingChannel.ModifyMessageAsync(oldTeam.MsgId, (message) => message.Content = oldTeam.ToMessage());
            }
            else
            {
                await recruitingChannel.DeleteMessageAsync(oldTeam.MsgId);
            }

            // Update new team message
            if (newTeam.MsgId == 0)
            {
                newTeam.MsgId = (await recruitingChannel.SendMessageAsync(newTeam.ToMessage())).Id;
            }
            else
            {
                await recruitingChannel.ModifyMessageAsync(newTeam.MsgId, (message) => message.Content = newTeam.ToMessage());
            }

            var transactions = new List <(string, TableTransactionActionType, Team, ETag)>();

            if (oldTeam.Players.Count > 0)
            {
                transactions.Add((oldTeam.Name, TableTransactionActionType.UpdateMerge, oldTeam, oldTeam.etag));
            }
            else
            {
                transactions.Add((oldTeam.Name, TableTransactionActionType.Delete, null, oldTeam.etag));
            }

            if (!string.Equals(newTeam.Name, oldTeam.Name, StringComparison.OrdinalIgnoreCase))
            {
                transactions.Add((newTeam.Name, isNewTeam ? TableTransactionActionType.UpsertMerge : TableTransactionActionType.UpdateMerge, newTeam, newTeam.etag));
            }

            // if the transaction fails it should retry, and then the message will be updated to reflect the actual value in storage.
            await storageClient.ExecuteTransaction(Team.TableName, transactions, guild.RowKey);

            await command.FollowupAsync($"You have moved user {discordUser} from {oldTeam.Name} -> {newTeam.Name}", ephemeral : true);
        }
Exemple #8
0
        public override async Task HandleCommandAsync(SocketSlashCommand command, DiscordSocketClient client, StorageClient storageClient, Guild guild)
        {
            if (guild.RecruitingChannelId == default)
            {
                await command.RespondAsync("Channel is not part of a guild that supports recruiting", ephemeral : true);

                return;
            }

            var channel    = command.Channel as SocketGuildChannel;
            var subCommand = command.Data.Options.First();
            var options    = subCommand.Options.ToDictionary(o => o.Name, o => o);

            await command.RespondAsync($"Starting Command {command.CommandName} {subCommand.Name}", ephemeral : true);

            // Get all messages in channel
            var recruitingChannel = await client.GetChannelAsync(guild.RecruitingChannelId) as ISocketMessageChannel;

            // What do we do if the policy fails 3 times and the board has values that aren't in the table. We could save values first if we didn't need the message id from new teams, but we do.
            await Policy.Handle <RequestFailedException>(e => e.Status == 412).RetryAsync(3).ExecuteAsync(async() =>
            {
                // cache these values eventually as well to improve performance
                var teams = await storageClient.GetAllRowsAsync <Team>(Team.TableName, guild.Id.ToString());

                if (teams.Count == 0)
                {
                    var messages = await GetAllChannelMessages(recruitingChannel);

                    // Parse messages into teams
                    teams = ParseMessageAsync(messages);

                    if (teams.Count > 0)
                    {
                        await ConvertMessageTeamsToStorage(teams, guild.RowKey, storageClient);
                    }

                    // get etags after for optimistic concurrency
                    teams = await storageClient.GetAllRowsAsync <Team>(Team.TableName, guild.Id.ToString());
                }

                switch (subCommand.Name)
                {
                case "add":
                    await AddTrackerCommand.Run(command, client, storageClient, options, guild, recruitingChannel, teams);
                    break;

                case "adminadd":
                    await AdminAddTrackerCommand.Run(command, client, storageClient, options, guild, recruitingChannel, teams);
                    break;

                case "move":
                    await MoveTrackedUserCommand.Run(command, client, storageClient, options, guild, recruitingChannel, teams);
                    break;

                case "remove":
                    await RemoveTrackedUserCommand.Run(command, client, storageClient, options, guild, recruitingChannel, teams);
                    break;

                case "deleteteam":
                    await DeleteTeamTrackerCommand.Run(command, client, storageClient, options, guild, recruitingChannel, teams);
                    break;

                case "lookingforplayers":
                    await LookingForPlayersCommand.Run(command, client, storageClient, options, guild, recruitingChannel, teams);
                    break;

                default:
                    await command.FollowupAsync($"SubCommand {subCommand} not supported", ephemeral: true);
                    return;
                }
            });
        }
        // Search Rotten Tomatoes for movies and create a selection
        public static async Task SearchRottenTomatoes(SocketSlashCommand command)
        {
            // Get our input from the interaction
            var search = command.Data.Options.ElementAt(0).Value.ToString();

            // Make a list of results
            var resultItems = new List <SearchResultItem>();

            // Get the website html
            var data = await WebUtils.DownloadString($"https://www.rottentomatoes.com/search?search={search}");

            //If there's no result, tell the user and then stop.
            if (data.Contains("Sorry, no results found for"))
            {
                await command.FollowupAsync(embed : new EmbedBuilder()
                                            .WithTitle("Rotten Tomatoes Search")
                                            .WithDescription($"Sorry, no results were found for \"{search}\"\n\nTry reformatting your search if the title contains colons, hyphens, etc.")
                                            .WithColor(EmbedUtils.Red)
                                            .Build());

                return;
            }

            // Slim down the data
            data = data
                   .CutBefore(
                "<search-page-result slot=\"movie\" skeleton=\"panel\" type=\"movie\" data-qa=\"search-result\">")
                   .CutBeforeAndAfter("<ul slot=\"list\">", "</ul>");

            do
            {
                var temp = data.CutAfter("</search-page-media-row>");
                resultItems.Add(new SearchResultItem(new Movie(temp)));

                data = data.CutBefore("</search-page-media-row>");
            } while (data.Contains("search-page-media-row"));

            var buttons = new ComponentBuilder();

            for (int i = 0; i < (resultItems.Count <= 5 ? resultItems.Count : 5); i++)
            {
                var text = $"{resultItems[i].Movie.CriticScore} {resultItems[i].Movie.Name} ({resultItems[i].Movie.Year})";

                // Decode the HTML
                text = HttpUtility.HtmlDecode(text);

                // Button Labels can only be 80 characters
                if (text.Length > 80)
                {
                    text = $"{text.Substring(0, 77)}...";
                }

                var customId = resultItems[i].Movie.Url.CutBefore("/m/");

                // Custom IDs can only be 100 characters (skip it otherwise)
                if (customId.Length > 100)
                {
                    continue;
                }

                buttons.WithButton(text, customId: customId, ButtonStyle.Danger, row: i, emote: Emote.Parse(resultItems[i].Movie.CriticScoreIcon));
            }

            await command.FollowupAsync("Please select a result or search again.", component : buttons.Build());
        }