コード例 #1
0
        public static async Task UpdateChannelTopicAsync(ulong RaceId)
        {
            DatabaseHandler database = new DatabaseHandler(Globals.MySqlConnectionString);

            RaceItem        race            = database.GetRaceInformation(RaceId);
            EntrantsSummary entrantsSummary = database.GetEntrantsSummary(race.RaceId);

            database.Dispose();

            SocketTextChannel raceChannel = (SocketTextChannel)client.GetChannel(race.TextChannelId);
            string            newTopic    = "**" + race.Status + "** | " + race.Description;

            if (race.Status == "Entry Open")
            {
                newTopic += " | Entered: " + (entrantsSummary.NotReady + entrantsSummary.Ready) + " | Ready: " + entrantsSummary.Ready;
            }

            else
            {
                newTopic += " | Racing: " + (entrantsSummary.Ready + entrantsSummary.Done + entrantsSummary.Forfeited + entrantsSummary.Disqalified) + " | Done: " + entrantsSummary.Done + " | Forfeited: " + entrantsSummary.Forfeited;
            }

            await raceChannel.ModifyAsync(x =>
            {
                x.Topic = newTopic;
            });
        }
コード例 #2
0
        public static async Task MarkEntrantDoneAsync(RaceItem Race, ulong UserId)
        {
            //Get the required information from Discord
            var raceServer  = client.GetGuild(Globals.GuildId);
            var entrant     = raceServer.GetUser(UserId);
            var raceChannel = raceServer.GetTextChannel(Race.TextChannelId);

            //Attempt to update the database. If the update function returns null, then the user isn't entered in the race
            DatabaseHandler database           = new DatabaseHandler(Globals.MySqlConnectionString);
            EntrantItem     entrantInformation = database.MarkEntrantFinished(Race.RaceId, UserId, Race.StartTime);

            database.Dispose();

            //if we get a result back from MarkEntrantFinished, let the racer know their place and finish time
            if (entrantInformation == null)
            {
                return;
            }

            var raceRole = raceServer.GetRole(Race.RoleId);
            await entrant.RemoveRoleAsync(raceRole);

            await raceChannel.SendMessageAsync(entrant.Mention + ", you finished in **" + AddOrdinal(entrantInformation.Place) + "** place with a time of **" + entrantInformation.FinishedTime + "**");

            await AttemptRaceFinishAsync(Race);
        }
コード例 #3
0
        public static async Task MarkEntrantNotDoneAsync(RaceItem Race, ulong UserId)
        {
            //Get the required information from Discord
            var raceServer  = client.GetGuild(Globals.GuildId);
            var entrant     = raceServer.GetUser(UserId);
            var raceChannel = raceServer.GetTextChannel(Race.TextChannelId);


            //Attempt to update the database. If the update function returns null, then the user isn't entered in the race
            DatabaseHandler database = new DatabaseHandler(Globals.MySqlConnectionString);

            if (database.MarkEntrantNotFinished(Race.RaceId, UserId))
            {
                return;
            }
            var raceRole = raceServer.GetRole(Race.RoleId);
            await entrant.AddRoleAsync(raceRole);

            await raceChannel.SendMessageAsync(entrant.Mention + ", I marked you as not done. Keep racing!");

            if (Race.Status == "Recently Completed")
            {
                database.UpdateRace(Race.RaceId, Status: "In Progress");
                RemoveTimer(_completedRaceTimerList, Race.RaceId);
                _ = UpdateRacesChannelAsync();
            }
            _ = UpdateChannelTopicAsync(Race.RaceId);
            database.Dispose();
        }
コード例 #4
0
        public static async Task AddEntrantAsync(RaceItem Race, ulong UserId)
        {
            //get the required information from Discord
            var raceServer  = client.GetGuild(Globals.GuildId);
            var entrant     = raceServer.GetUser(UserId);
            var raceChannel = raceServer.GetTextChannel(Race.TextChannelId);

            DatabaseHandler database = new DatabaseHandler(Globals.MySqlConnectionString);

            //attempt to join the race. if the command returns true, then the user is probably already joined
            if (!database.JoinRace(Race.RaceId, UserId))
            {
                //get the race role from Discord
                var raceRole = raceServer.GetRole(Race.RoleId);

                //assign the correct race role to the user
                await entrant.AddRoleAsync(raceRole);

                await raceChannel.SendMessageAsync(entrant.Mention + ", you are entered in the race. Type '.ready' when you are ready to start.");

                //Update the race channel topic to reflect the correct number of people joined.
                _ = UpdateChannelTopicAsync(Race.RaceId);
            }
            database.Dispose();
        }
コード例 #5
0
        public Task CommandNotDone()
        {
            //We can't process this message if it's not in a race channel, so we need to make sure it's coming from one
            SocketTextChannel messageChannel = (SocketTextChannel)Context.Client.GetChannel(Context.Channel.Id);

            if (!(messageChannel.CategoryId == Globals.RacesCategoryId))
            {
                return(Task.CompletedTask);
            }

            //we need to get the race information from the database
            ulong           RaceId   = GetRaceId(Context.Channel.Name);
            DatabaseHandler database = new DatabaseHandler(Globals.MySqlConnectionString);
            RaceItem        race     = database.GetRaceInformation(RaceId);
            EntrantItem     entrant  = database.GetEntrantInformation(RaceId, Context.User.Id);

            database.Dispose();

            //don't continue with this command if the entrant isn't marked done.
            if (entrant.Status != "Done")
            {
                return(Task.CompletedTask);
            }

            if (race.Status != "In Progress" && race.Status != "Recently Completed")
            {
                return(Task.CompletedTask);
            }

            return(Task.Factory.StartNew(() => RaceManager.MarkEntrantNotDoneAsync(race, Context.User.Id)));
        }
コード例 #6
0
        public static async Task <bool> AttemptRaceFinishAsync(RaceItem Race)
        {
            DatabaseHandler database = new DatabaseHandler(Globals.MySqlConnectionString);

            EntrantsSummary entrantsSummary = database.GetEntrantsSummary(Race.RaceId);

            var raceServer  = client.GetGuild(Globals.GuildId);
            var raceRole    = raceServer.GetRole(Race.RoleId);
            var raceChannel = raceServer.GetTextChannel(Race.TextChannelId);

            //we sometimes may need to know if the race is actually finishing
            bool raceIsFinishing = false;

            //Racers are stored as "Ready" until they finish, forfeit, or are disqualified
            if (entrantsSummary.Ready == 0)
            {
                await raceChannel.SendMessageAsync("Everyone is finished! GGs all around! This channel will be deleted in 10 minutes.");

                database.UpdateRace(Race.RaceId, Status: "Recently Completed");
                var newTimer = new CountdownTimer();
                newTimer.Interval  = 600000;
                newTimer.race      = Race;
                newTimer.AutoReset = false;
                newTimer.Elapsed  += DeleteFinishedRaceAsync;
                newTimer.Enabled   = true;
                newTimer.Start();
                _completedRaceTimerList.Add(newTimer);
                raceIsFinishing = true;
                _ = UpdateRacesChannelAsync();
            }

            _ = UpdateChannelTopicAsync(Race.RaceId);
            database.Dispose();
            return(raceIsFinishing);
        }
コード例 #7
0
        public static async Task DeleteRaceAsync(RaceItem Race, string Status)
        {
            //Don't use this command if the status is anything other than "Aborted" or "Complete"
            if (Status != "Aborted" && Status != "Complete")
            {
                return;
            }

            //Update the database with the appropriate status
            DatabaseHandler database = new DatabaseHandler(Globals.MySqlConnectionString);

            database.UpdateRace(Race.RaceId, Status: Status);
            database.Dispose();

            //Get the channels and role from Discord
            var guild        = client.GetGuild(Globals.GuildId);
            var textChannel  = guild.GetChannel(Race.TextChannelId);
            var voiceChannel = guild.GetChannel(Race.VoiceChannelId);
            var raceRole     = guild.GetRole(Race.RoleId);

            //Delete the channels and role from the Discord server
            await textChannel.DeleteAsync();

            await voiceChannel.DeleteAsync();

            await raceRole.DeleteAsync();

            //check for and remove any force start timers that may be waiting to fire
            RemoveTimer(_forceStartTimerList, Race.RaceId);
        }
コード例 #8
0
        public Task CommandJoinRace()
        {
            //We can't process this message if it's not in a race channel, so we need to make sure it's coming from one
            SocketTextChannel messageChannel = (SocketTextChannel)Context.Client.GetChannel(Context.Channel.Id);

            if (!(messageChannel.CategoryId == Globals.RacesCategoryId))
            {
                return(Task.CompletedTask);
            }

            //get the RaceId by removing "race-" from the channel name we're in
            ulong RaceId = GetRaceId(Context.Channel.Name);

            //get the race information from the database
            DatabaseHandler database = new DatabaseHandler(Globals.MySqlConnectionString);
            RaceItem        race     = database.GetRaceInformation(RaceId);

            database.Dispose();

            //Verify that the race is still open to entry
            if (race.Status != "Entry Open")
            {
                return(Task.CompletedTask);
            }

            return(Task.Factory.StartNew(() => RaceManager.AddEntrantAsync(race, Context.User.Id)));
        }
コード例 #9
0
        public Task CommandTime()
        {
            //We can't process this message if it's not in a race channel, so we need to make sure it's coming from one
            SocketTextChannel messageChannel = (SocketTextChannel)Context.Client.GetChannel(Context.Channel.Id);

            if (!(messageChannel.CategoryId == Globals.RacesCategoryId))
            {
                return(Task.CompletedTask);
            }

            //we need the race information from the database
            ulong           RaceId   = GetRaceId(Context.Channel.Name);
            DatabaseHandler database = new DatabaseHandler(Globals.MySqlConnectionString);
            RaceItem        race     = database.GetRaceInformation(RaceId);

            database.Dispose();

            //Verify that the race is still open to entry
            if (race.Status != "In Progress")
            {
                return(Task.CompletedTask);
            }

            return(Task.Factory.StartNew(() => RaceManager.ShowTimeAsync(race)));
        }
コード例 #10
0
        public Task CommandQuit()
        {
            //We can't process this message if it's not in a race channel, so we need to make sure it's coming from one
            SocketTextChannel messageChannel = (SocketTextChannel)Context.Client.GetChannel(Context.Channel.Id);

            if (!(messageChannel.CategoryId == Globals.RacesCategoryId))
            {
                return(Task.CompletedTask);
            }

            //we need to get the race information from the database
            ulong           RaceId   = GetRaceId(Context.Channel.Name);
            DatabaseHandler database = new DatabaseHandler(Globals.MySqlConnectionString);
            RaceItem        race     = database.GetRaceInformation(RaceId);

            database.Dispose();

            //depending on the race status, choose the correct way to handle the withdrawal (either remove outright or mark as forfeited.
            if (race.Status == "Entry Open" || race.Status == "Countdown")
            {
                return(Task.Factory.StartNew(() => RaceManager.RemoveEntrantAsync(race, Context.User.Id)));
            }
            else if (race.Status == "In Progress")
            {
                return(Task.Factory.StartNew(() => RaceManager.ForfeitEntrantAsync(race, Context.User.Id)));
            }

            return(Task.CompletedTask);
        }
コード例 #11
0
        public static async Task BeginForceStartAsync(RaceItem Race)
        {
            var raceServer  = client.GetGuild(Globals.GuildId);
            var raceRole    = raceServer.GetRole(Race.RoleId);
            var raceChannel = raceServer.GetTextChannel(Race.TextChannelId);

            //Set the race status to "Countdown" so no new entrants can join
            DatabaseHandler database = new DatabaseHandler(Globals.MySqlConnectionString);

            database.UpdateRace(Race.RaceId, Status: "Countdown");
            database.Dispose();

            //We're going to set a timer to give the remaining entrants time to ready up
            await raceChannel.SendMessageAsync(raceRole.Mention + ", a moderator is force starting this race. Entrants who are not ready within 30 seconds will be kicked from the race.");

            var newTimer = new CountdownTimer();

            newTimer.Interval  = 30000;
            newTimer.race      = Race;
            newTimer.AutoReset = false;
            newTimer.Elapsed  += ForceStartRaceAsync;
            newTimer.Enabled   = true;
            newTimer.Start();
            _forceStartTimerList.Add(newTimer);

            _ = UpdateChannelTopicAsync(Race.RaceId);
            _ = UpdateRacesChannelAsync();
        }
コード例 #12
0
        private static async void DeleteFinishedRaceAsync(Object source, ElapsedEventArgs e)
        {
            RaceItem race = ((CountdownTimer)source).race;

            await DeleteRaceAsync(race, "Complete");
            await UpdateRacesChannelAsync();
        }
コード例 #13
0
        public Task CommandCancel()
        {
            //We can't process this message if it's not in a race channel, so we need to make sure it's coming from one
            SocketTextChannel messageChannel = (SocketTextChannel)Context.Client.GetChannel(Context.Channel.Id);

            if (!(messageChannel.CategoryId == Globals.RacesCategoryId))
            {
                return(Task.CompletedTask);
            }

            ulong RaceId = GetRaceId(Context.Channel.Name);
            //get the race information from the database
            DatabaseHandler database = new DatabaseHandler(Globals.MySqlConnectionString);
            RaceItem        race     = database.GetRaceInformation(RaceId);

            database.Dispose();

            //we need to check to see if the user has permission to cancel this race
            var user = Context.Guild.GetUser(Context.User.Id);
            List <SocketRole> userRoles = user.Roles.ToList();
            bool userHasPermission      = false;

            //check to see if the user is a moderator first.
            foreach (SocketRole item in userRoles)
            {
                if (item.Name.ToLower() == "moderator")
                {
                    userHasPermission = true;
                    break;
                }
            }

            //if the user is not a moderator and they are the owner of the race, they can still cancel it if it's open for entry.
            if (!userHasPermission && race.Owner == Context.User.Id)
            {
                if (race.Status == "Entry Open")
                {
                    userHasPermission = true;
                }
            }

            //If the user isn't allowed to use this command, return
            if (!userHasPermission)
            {
                return(Task.CompletedTask);
            }

            //users can only cancel "Entry Open" or "In Progress" races
            if (race.Status == "Entry Open" || race.Status == "In Progress")
            {
                return(Task.Factory.StartNew(
                           () =>
                {
                    _ = RaceManager.DeleteRaceAsync(race, "Aborted");
                    _ = RaceManager.UpdateRacesChannelAsync();
                }));
            }
            return(Task.CompletedTask);
        }
コード例 #14
0
        public Task CommandSetDescription([Remainder][Summary("Description for the race channel")] string description)
        {
            //We can't process this message if it's not in a race channel, so we need to make sure it's coming from one
            SocketTextChannel messageChannel = (SocketTextChannel)Context.Client.GetChannel(Context.Channel.Id);

            if (!(messageChannel.CategoryId == Globals.RacesCategoryId))
            {
                return(Task.CompletedTask);
            }

            ulong RaceId = GetRaceId(Context.Channel.Name);
            //get the race information from the database
            DatabaseHandler database = new DatabaseHandler(Globals.MySqlConnectionString);
            RaceItem        race     = database.GetRaceInformation(RaceId);

            //we need to check to see if the user has permission to cancel this race
            var user = Context.Guild.GetUser(Context.User.Id);
            List <SocketRole> userRoles = user.Roles.ToList();
            bool userHasPermission      = false;

            //check to see if the user is a moderator first.
            foreach (SocketRole item in userRoles)
            {
                if (item.Name.ToLower() == "moderator")
                {
                    userHasPermission = true;
                    break;
                }
            }

            //if the user is not a moderator and they are the owner of the race, they can still set the description it if it's open for entry.
            if (!userHasPermission && race.Owner == Context.User.Id)
            {
                if (race.Status == "Entry Open")
                {
                    userHasPermission = true;
                }
            }

            //If the user isn't allowed to use this command, return
            if (!userHasPermission)
            {
                database.Dispose();
                return(Task.CompletedTask);
            }

            //Clean the description, then set the new description.
            return(Task.Factory.StartNew(
                       () =>
            {
                string cleanedDescription = CleanDescription(description);
                database.UpdateRace(race.RaceId, Description: cleanedDescription);
                database.Dispose();
                _ = RaceManager.UpdateChannelTopicAsync(race.RaceId);
                _ = ReplyAsync("Race description changed successfully.");
            }));
        }
コード例 #15
0
        public static async Task ShowTimeAsync(RaceItem Race)
        {
            var raceServer  = client.GetGuild(Globals.GuildId);
            var raceChannel = raceServer.GetTextChannel(Race.TextChannelId);

            //calculate how much time has passed since the race start time and now
            TimeSpan elapsedTime = Race.StartTime - DateTime.Now;

            //Reply with elapsed time
            await raceChannel.SendMessageAsync("Elapsed time: **" + elapsedTime.ToString(@"hh\:mm\:ss") + "**");
        }
コード例 #16
0
        public Task CommandRefresh()
        {
            //We can't process this message if it's not in a race channel, so we need to make sure it's coming from one
            SocketTextChannel messageChannel = (SocketTextChannel)Context.Client.GetChannel(Context.Channel.Id);

            if (!(messageChannel.CategoryId == Globals.RacesCategoryId))
            {
                return(Task.CompletedTask);
            }

            //This is a moderator only command
            var user = Context.Guild.GetUser(Context.User.Id);
            List <SocketRole> userRoles = user.Roles.ToList();
            bool userHasPermission      = false;

            foreach (SocketRole item in userRoles)
            {
                if (item.Name.ToLower() == "moderator")
                {
                    userHasPermission = true;
                    break;
                }
            }

            //return if the user doesn't have permission to use the command
            if (!userHasPermission)
            {
                return(Task.CompletedTask);
            }

            return(Task.Factory.StartNew(
                       () =>
            {
                ulong RaceId = GetRaceId(Context.Channel.Name);
                //get the race information from the database
                DatabaseHandler database = new DatabaseHandler(Globals.MySqlConnectionString);
                RaceItem race = database.GetRaceInformation(RaceId);
                database.Dispose();

                _ = RaceManager.UpdateChannelTopicAsync(RaceId);
                if (race.Status == "Entry Open")
                {
                    _ = RaceManager.AttemptRaceStartAsync(race);
                }
                else if (race.Status == "In Progress")
                {
                    _ = RaceManager.AttemptRaceFinishAsync(race);
                }
            }));
        }
コード例 #17
0
        public static async Task SetEntrantStatusAsync(RaceItem Race, ulong UserId, string Status)
        {
            var             raceServer  = client.GetGuild(Globals.GuildId);
            var             entrant     = raceServer.GetUser(UserId);
            var             raceChannel = raceServer.GetTextChannel(Race.TextChannelId);
            DatabaseHandler database    = new DatabaseHandler(Globals.MySqlConnectionString);

            //Attempt to update the database. If the update function returns true, then the user isn't entered in the race
            if (!database.UpdateEntry(Race.RaceId, UserId, Status))
            {
                await raceChannel.SendMessageAsync(entrant.Username + " is **" + Status + "**");
                await AttemptRaceStartAsync(Race);
            }
            database.Dispose();
        }
コード例 #18
0
        public Task CommandForceStart()
        {
            //We can't process this message if it's not in a race channel, so we need to make sure it's coming from one
            SocketTextChannel messageChannel = (SocketTextChannel)Context.Client.GetChannel(Context.Channel.Id);

            if (!(messageChannel.CategoryId == Globals.RacesCategoryId))
            {
                return(Task.CompletedTask);
            }

            //This is a moderator-only command
            var user = Context.Guild.GetUser(Context.User.Id);
            List <SocketRole> userRoles = user.Roles.ToList();
            bool userHasPermission      = false;

            //check to see if the user is a moderator first.
            foreach (SocketRole item in userRoles)
            {
                if (item.Name.ToLower() == "moderator")
                {
                    userHasPermission = true;
                    break;
                }
            }

            //If the user isn't allowed to use this command, let them know and return
            if (!userHasPermission)
            {
                return(Task.CompletedTask);
            }

            //get the race information from the database
            ulong           RaceId   = GetRaceId(Context.Channel.Name);
            DatabaseHandler database = new DatabaseHandler(Globals.MySqlConnectionString);
            RaceItem        race     = database.GetRaceInformation(RaceId);

            database.Dispose();

            //We can only force start races that have the Entry Open status
            if (race.Status != "Entry Open")
            {
                return(Task.CompletedTask);
            }

            return(Task.Factory.StartNew(() => RaceManager.BeginForceStartAsync(race)));
        }
コード例 #19
0
        public static async Task <bool> AttemptRaceStartAsync(RaceItem Race)
        {
            DatabaseHandler database = new DatabaseHandler(Globals.MySqlConnectionString);

            EntrantsSummary entrantsSummary = database.GetEntrantsSummary(Race.RaceId);

            var raceServer  = client.GetGuild(Globals.GuildId);
            var raceRole    = raceServer.GetRole(Race.RoleId);
            var raceChannel = raceServer.GetTextChannel(Race.TextChannelId);

            //sometimes we need to know if we're actually starting the race.
            bool raceIsStarting = false;

            //See if the number of ready entrants + disqualified entrants equals the total number of entrants
            //It is possible (but rare) for an entrant to be marked disqualified before a race starts
            //Excessive DQs may result in a penalty at some point, so it's important to record them
            if (entrantsSummary.Ready + entrantsSummary.Disqalified == entrantsSummary.TotalEntrants)
            {
                //we don't want a situation where there is only one racer who is ready, but the race starts
                //because of DQed entrants.
                if (entrantsSummary.Ready > 1)
                {
                    //All of the entrants are ready, and we have enough entrants, so we can start the race
                    await raceChannel.SendMessageAsync(raceRole.Mention + " Everyone is ready! Race will start in 10 seconds.");

                    database.UpdateRace(Race.RaceId, Status: "Countdown");
                    var newTimer = new CountdownTimer();
                    newTimer.Interval  = 7000;
                    newTimer.race      = Race;
                    newTimer.AutoReset = false;
                    newTimer.Elapsed  += CountdownRaceAsync;
                    newTimer.Enabled   = true;
                    newTimer.Start();

                    //check for and remove any force start timers that may be waiting to fire
                    RemoveTimer(_forceStartTimerList, Race.RaceId);
                    _ = UpdateRacesChannelAsync();
                    raceIsStarting = true;
                }
            }

            _ = UpdateChannelTopicAsync(Race.RaceId);
            database.Dispose();
            return(raceIsStarting);
        }
コード例 #20
0
        /*
         * GetRaceInformation(): Returns the race information for [RaceId]
         */
        public RaceItem GetRaceInformation(ulong RaceId)
        {
            MySqlCommand    cmd;
            MySqlDataReader dataReader; //for reading the results of the query

            try
            {
                cmd             = _connection.CreateCommand();
                cmd.CommandText = "SELECT * from races WHERE ID = @RaceId";
                cmd.Parameters.AddWithValue("@RaceId", RaceId);
                dataReader = cmd.ExecuteReader();
            }
            catch (Exception e)
            {
                Console.WriteLine("Exception thrown: " + e.Message);
                throw;
            }
            //we should never read in more than one result, so we don't have to mess with a loop for dataReader.Read()
            dataReader.Read();

            DateTime convertedDateTime;

            if (dataReader["StartTime"] == DBNull.Value)
            {
                convertedDateTime = DateTime.MinValue;
            }
            else
            {
                convertedDateTime = Convert.ToDateTime(dataReader["StartTime"]);
            }
            RaceItem Race = new RaceItem(
                RaceId,
                (ulong)dataReader["TextChannelId"],
                (ulong)dataReader["VoiceChannelId"],
                (ulong)dataReader["RoleId"],
                (ulong)dataReader["Owner"],
                (string)dataReader["Description"],
                (string)dataReader["Status"],
                convertedDateTime);

            dataReader.Close();
            dataReader.Dispose();

            return(Race);
        }
コード例 #21
0
        public static async Task ForfeitEntrantAsync(RaceItem Race, ulong UserId)
        {
            //get required info from Discord
            var guild       = client.GetGuild(Globals.GuildId);
            var raceChannel = guild.GetTextChannel(Race.TextChannelId);
            var raceRole    = guild.GetRole(Race.RoleId);
            var entrant     = guild.GetUser(UserId);

            DatabaseHandler database = new DatabaseHandler(Globals.MySqlConnectionString);

            //Get the get the entrant's status.
            EntrantItem entrantStatus = database.GetEntrantInformation(Race.RaceId, UserId);

            //if no result was returned, the user isn't entered
            if (entrantStatus == null)
            {
                database.Dispose();
                return;
            }

            //We can't forfeit a player who isn't still racing.
            if (entrantStatus.Status != "Ready")
            {
                database.Dispose();
                return;
            }

            //attempt to forfeit the racer
            if (!database.UpdateEntry(Race.RaceId, UserId, "Forfeited"))
            {
                await entrant.RemoveRoleAsync(raceRole);

                await raceChannel.SendMessageAsync(entrant.Mention + ", you have forfeited from the race.");
                await AttemptRaceFinishAsync(Race);
            }
            //UpdateEntry shouldn't return true since we've already checked to see if the racer is entered, but if it does, we need to let the racer know.
            else
            {
                await raceChannel.SendMessageAsync(entrant.Mention + ", something went wrong when I tried to remove you. Please let a moderator know.");
            }

            database.Dispose();
        }
コード例 #22
0
        private static async void ForceStartRaceAsync(Object source, ElapsedEventArgs e)
        {
            RaceItem race        = ((CountdownTimer)source).race;
            var      raceChannel = (SocketTextChannel)client.GetChannel(race.TextChannelId);
            var      guild       = client.GetGuild(Globals.GuildId);
            var      raceRole    = guild.GetRole(race.RoleId);

            //get the list of players who are not ready
            DatabaseHandler    database        = new DatabaseHandler(Globals.MySqlConnectionString);
            List <EntrantItem> playersToRemove = database.GetEntrantList(race.RaceId, "Not Ready");

            int kickedPlayers = 0;

            foreach (EntrantItem entrant in playersToRemove)
            {
                var discordEntrant = guild.GetUser(entrant.UserId);
                if (!database.DeleteEntrant(race.RaceId, entrant.UserId))
                {
                    kickedPlayers++;
                    await discordEntrant.RemoveRoleAsync(raceRole);

                    await discordEntrant.SendMessageAsync("You were kicked from **Race " + race.RaceId + ": " + race.Description + "** because you did not make yourself ready in a timely manner.");
                }
            }

            //Attempt to force start the race. If the race doesn't start, let everyone know and set
            //the race status back to "Entry Open"
            bool raceIsStarting = await AttemptRaceStartAsync(race);

            if (!raceIsStarting)
            {
                await raceChannel.SendMessageAsync("I could not force start this race because there aren't enough participants who are ready.");

                database.UpdateRace(race.RaceId, Status: "Entry Open");
                await UpdateChannelTopicAsync(race.RaceId);
            }

            database.Dispose();

            //remove the timer from our list of force start timers
            _forceStartTimerList.Remove((CountdownTimer)source);
        }
コード例 #23
0
        public static async Task RemoveEntrantAsync(RaceItem Race, ulong UserId)
        {
            //get required info from Discord
            var guild       = client.GetGuild(Globals.GuildId);
            var raceChannel = guild.GetTextChannel(Race.TextChannelId);
            var raceRole    = guild.GetRole(Race.RoleId);
            var entrant     = guild.GetUser(UserId);

            DatabaseHandler database = new DatabaseHandler(Globals.MySqlConnectionString);

            //attempt to delete the entrant from the race. If DeleteEntrant returns true, they aren't entered in the race
            if (!database.DeleteEntrant(Race.RaceId, UserId))
            {
                await entrant.RemoveRoleAsync(raceRole);

                await raceChannel.SendMessageAsync(entrant.Mention + ", you have been removed from the race.");
                await AttemptRaceStartAsync(Race);
            }
            database.Dispose();
        }
コード例 #24
0
        public Task CommandReady()
        {
            //We can't process this message if it's not in a race channel, so we need to make sure it's coming from one
            SocketTextChannel messageChannel = (SocketTextChannel)Context.Client.GetChannel(Context.Channel.Id);

            if (!(messageChannel.CategoryId == Globals.RacesCategoryId))
            {
                return(Task.CompletedTask);
            }

            //This command is only available when the race is open for entry, so we need to get the race information from the database
            ulong           RaceId   = GetRaceId(Context.Channel.Name);
            DatabaseHandler database = new DatabaseHandler(Globals.MySqlConnectionString);
            RaceItem        race     = database.GetRaceInformation(RaceId);

            database.Dispose();

            if (race.Status != "Entry Open" && race.Status != "Countdown")
            {
                return(Task.CompletedTask);
            }

            return(Task.Factory.StartNew(() => RaceManager.SetEntrantStatusAsync(race, Context.User.Id, "Ready")));
        }
コード例 #25
0
        private static async void CountdownRaceAsync(Object source, ElapsedEventArgs e)
        {
            RaceItem race        = ((CountdownTimer)source).race;
            var      raceChannel = (SocketTextChannel)client.GetChannel(race.TextChannelId);

            await raceChannel.SendMessageAsync("**3**");

            Thread.Sleep(1000);
            await raceChannel.SendMessageAsync("**2**");

            Thread.Sleep(1000);
            await raceChannel.SendMessageAsync("**1**");

            Thread.Sleep(1000);
            await raceChannel.SendMessageAsync("**GO!**");

            string          startTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            DatabaseHandler database  = new DatabaseHandler(Globals.MySqlConnectionString);

            database.UpdateRace(race.RaceId, Status: "In Progress", StartTime: startTime);
            database.Dispose();
            await UpdateRacesChannelAsync();
            await UpdateChannelTopicAsync(race.RaceId);
        }