/// <summary>
        ///     Posts a new announcement message and alerts playtester role
        /// </summary>
        /// <returns></returns>
        public async Task PlaytestStartingInTask(PlaytestEvent playtestEvent)
        {
            _ = _log.LogMessage($"Running playtesting starting in X minutes task for {playtestEvent.Title}", true,
                                color: LOG_COLOR);

            await playtestEvent.PlaytestStartingInTask(_rconService, _srcdsLogService, _announcementMessage);
        }
        /// <summary>
        ///     Posts a new playtest announcement
        /// </summary>
        /// <returns></returns>
        private async Task PostNewAnnouncement(PlaytestEvent testEvent)
        {
            if (_dataService.RSettings.ProgramSettings.Debug)
            {
                _ = _log.LogMessage($"Posting new announcement for {testEvent.Title}", false, color: LOG_COLOR);
            }

            try
            {
                //Make the announcement and store to a variable
                var playtestAnnouncementMessage = await testEvent.AnnouncmentChannel.SendMessageAsync(
                    embed : _announcementMessage.CreatePlaytestEmbed(testEvent));

                //Hand off the message and time to be stored in the DB for use on restarts
                DatabaseUtil.StoreAnnouncement(playtestAnnouncementMessage, testEvent.Title, testEvent.Game.ToString());

                SchedulePlaytestAnnouncements(testEvent);

                testEvent.SetAnnouncementMessage(playtestAnnouncementMessage);

                //Store the titles along with the game key so we can check against them later.
                if (_knownTests.ContainsKey(testEvent.Game))
                {
                    _knownTests.Remove(testEvent.Game);
                }

                _knownTests.Add(testEvent.Game, testEvent.EventEditTime.Value);
            }
            catch
            {
                _ = _log.LogMessage("Attempted to post new announcement, but failed", false, color: LOG_COLOR);
            }
        }
        /// <summary>
        ///     Announcement for playtest starting
        /// </summary>
        /// <returns></returns>
        private async Task PlaytestStartingTask(PlaytestEvent playtestEvent)
        {
            _ = _log.LogMessage("Running playtesting starting now task...", false, color: LOG_COLOR);

            await _reservationService.DisableReservations();

            JobManager.RemoveJob("[AllowReservationsStopCount]");

            await playtestEvent.PlaytestStartingTask(_rconService, _srcdsLogService, _announcementMessage);
        }
        /// <summary>
        ///     Server setup tasks for 15 minutes before a test
        /// </summary>
        /// <returns></returns>
        private async Task PlaytestFifteenMinuteTask(PlaytestEvent playtestEvent)
        {
            _ = _log.LogMessage("Running playtesting starting in 15 minutes task...", true, color: LOG_COLOR);

            await _reservationService.DisableReservations();

            JobManager.RemoveJob("[AllowReservationsStopCount]");

            await playtestEvent.PlaytestFifteenMinuteTask(_rconService, _srcdsLogService);
        }
        /// <summary>
        ///     Attempts to update the existing announcement message.
        ///     If failure to update after
        ///     <value>_failedRetryCount</value>
        ///     (default 60) tries, the message is
        ///     assumed to be lost, and will be recreated. This may result in double announcement messages that require
        ///     manual cleanup.
        /// </summary>
        /// <returns></returns>
        private async Task UpdateAnnouncementMessage(PlaytestEvent playtestEvent)
        {
            if (_dataService.RSettings.ProgramSettings.Debug)
            {
                _ = _log.LogMessage($"Updating playtest announcement for {playtestEvent.Title}", false,
                                    color: LOG_COLOR);
            }

            try
            {
                //Compare the current title and the last known title.
                if (_knownTests.ContainsKey(playtestEvent.Game) &&
                    playtestEvent.EventEditTime.Value.Equals(_knownTests[playtestEvent.Game]))
                {
                    await playtestEvent.AnnouncementMessage.ModifyAsync(x =>
                    {
                        x.Embed = _announcementMessage.CreatePlaytestEmbed(playtestEvent);
                    });

                    _failedToFetch = 0;
                }
                else
                {
                    //Being in this else means we know the message is different, remake it.
                    await playtestEvent.AnnouncmentChannel.DeleteMessageAsync(playtestEvent.AnnouncementMessage);
                    await PostNewAnnouncement(playtestEvent);
                }
            }
            catch
            {
                //Have we failed enough to rebuild?
                if (_failedToFetch >= _failedRetryCount)
                {
                    _ = _log.LogMessage($"Tried to update announcement message {_failedToFetch} times, but failed." +
                                        "\nCreated a new message next time.", false, color: LOG_COLOR);
                    playtestEvent.SetAnnouncementMessage(null);
                }
                else
                {
                    //Have not failed enough, lets keep trying.
                    _failedToFetch++;
                    if (_dataService.RSettings.ProgramSettings.Debug)
                    {
                        _ = _log.LogMessage($"Failed to update playtest announcement {_failedToFetch} times", false,
                                            color: LOG_COLOR);
                    }
                }
            }
        }
Beispiel #6
0
        public VoiceFeedbackSession(DataService dataService, DiscordSocketClient client, PlaytestEvent playtestEvent,
                                    RconService rconService)
        {
            _dataService   = dataService;
            _client        = client;
            _playtestEvent = playtestEvent;
            _rconService   = rconService;

            _client.UserVoiceStateUpdated += UserVoiceStateUpdated;

            _duration = TimeSpan.FromMinutes(_dataService.RSettings.General.FeedbackDuration);

            //Mute everyone on start
            foreach (var user in _dataService.LevelTestVoiceChannel.Users)
            {
                _ = ProcessMute(true, user);
            }

            _ = _rconService.RconCommand(_playtestEvent.ServerLocation,
                                         "say Feedback Queue Started!;say Feedback Queue Started!;say Feedback Queue Started!");

            _ = _client.SetStatusAsync(UserStatus.AFK);
        }
        public void SchedulePlaytestAnnouncements(PlaytestEvent testEvent)
        {
            //If the test is null, likely only when first starting, abort.
            if (testEvent == null)
            {
                return;
            }

            if (_dataService.RSettings.ProgramSettings.Debug)
            {
                _ = _log.LogMessage($"SchedulePlaytestAnnouncements for {testEvent.Title}", false, color: LOG_COLOR);
            }

            var game = testEvent.Game.ToString();

            //Clear old jobs, if any.
            ClearScheduledAnnouncements(game);

            if (!testEvent.IsValid)
            {
                return;
            }

            var startDateTime = testEvent.StartDateTime;

            _ = _log.LogMessage($"Playtest of {testEvent.Title} scheduled for: {startDateTime}", false,
                                color: LOG_COLOR);

            if (startDateTime != null && DateTime.Compare(DateTime.Now.AddMinutes(60), startDateTime.Value) < 0)
            {
                //Subtract 60.2 minutes. If .2 isn't added the announcement states wrong time.
                JobManager.AddJob(async() => await PlaytestStartingInTask(testEvent), s => s
                                  .WithName($"[Playtest1Hour_{game}]").ToRunOnceAt(startDateTime.Value.AddMinutes(-60.2)));

                _ = _log.LogMessage("1 hour playtest announcement scheduled for:" +
                                    $"\n{JobManager.GetSchedule($"[Playtest1Hour_{game}]").NextRun}", false,
                                    color: LOG_COLOR);
            }

            if (startDateTime != null && DateTime.Compare(DateTime.Now.AddMinutes(20), startDateTime.Value) < 0)
            {
                JobManager.AddJob(async() => await PlaytestTwentyMinuteTask(testEvent), s => s
                                  .WithName($"[Playtest20Minute_{game}]").ToRunOnceAt(startDateTime.Value.AddMinutes(-20)));

                _ = _log.LogMessage("20 minute playtest announcement scheduled for:" +
                                    $"\n{JobManager.GetSchedule($"[Playtest20Minute_{game}]").NextRun}", false,
                                    color: LOG_COLOR);
            }

            if (startDateTime != null && DateTime.Compare(DateTime.Now.AddMinutes(15), startDateTime.Value) < 0)
            {
                JobManager.AddJob(async() => await PlaytestFifteenMinuteTask(testEvent), s => s
                                  .WithName($"[Playtest15Minute_{game}]").ToRunOnceAt(startDateTime.Value.AddMinutes(-15)));

                _ = _log.LogMessage("15 minute playtest announcement scheduled for:" +
                                    $"\n{JobManager.GetSchedule($"[Playtest15Minute_{game}]").NextRun}", false,
                                    color: LOG_COLOR);
            }

            if (startDateTime != null && DateTime.Compare(DateTime.Now, startDateTime.Value) < 0)
            {
                JobManager.AddJob(async() => await PlaytestStartingTask(testEvent), s => s
                                  .WithName($"[PlaytestStarting_{game}]").ToRunOnceAt(startDateTime.Value));

                _ = _log.LogMessage("Starting playtest announcement scheduled for:" +
                                    $"\n{JobManager.GetSchedule($"[PlaytestStarting_{game}]").NextRun}", false,
                                    color: LOG_COLOR);
            }
        }
Beispiel #8
0
        /// <summary>
        ///     Creates a playtest embed with all information setup as needed.
        ///     This expects the calendar to have the latest even cached.
        /// </summary>
        /// <param name="isCasual">If true, shows password. Otherwise password will be hidden</param>
        /// <param name="testEvent"></param>
        /// <param name="smallEmbed">Should the message be formatted in small style</param>
        /// <param name="fullMessage">ID of full message, used in small embeds</param>
        /// <returns>Prebuilt embed</returns>
        public Embed CreatePlaytestEmbed(PlaytestEvent testEvent, bool smallEmbed = false, ulong fullMessage = 0)
        {
            if (_dataService.RSettings.ProgramSettings.Debug)
            {
                _ = _log.LogMessage("Creating Playtest Embed", false, color: LOG_COLOR);
            }

            //What type of test
            var testType = "Casual";

            if (!testEvent.IsCasual)
            {
                testType = "Competitive";
            }

            var creatorIndex    = 0;
            var creatorSpelling = "Creator";
            var creatorProfile  = "Unable to get creator(s)";
            var thumbnailUrl    = _dataService.Guild.IconUrl;

            try
            {
                //Try set thumbnail to creator icons
                thumbnailUrl = testEvent.Creators[creatorIndex].GetAvatarUrl();

                //If more than 1 creator, randomly change between them for their index on the thumbnail
                creatorProfile = testEvent.Creators[0].ToString();
                if (testEvent.Creators.Count > 1)
                {
                    if (_dataService.RSettings.ProgramSettings.Debug)
                    {
                        _ = _log.LogMessage($"Multiple Test Creators found for embed [{testEvent.Creators.Count}]",
                                            false, color: LOG_COLOR);
                    }

                    creatorIndex    = _random.Next(0, testEvent.Creators.Count);
                    creatorSpelling = "Creators";

                    for (var i = 1; i < testEvent.Creators.Count; i++)
                    {
                        creatorProfile +=
                            $"\n{testEvent.Creators[i]}";
                    }

                    thumbnailUrl = testEvent.Creators[creatorIndex].GetAvatarUrl();
                }
            }
            catch
            {
                _ = _log.LogMessage(
                    "```Failed to get all creators while building the playtest embed. This is likely because " +
                    "they have left the server. Remove the creator from the test event.```", color: LOG_COLOR);
            }


            if (_dataService.RSettings.ProgramSettings.Debug)
            {
                _ = _log.LogMessage(
                    $"Creators string\n{creatorProfile}\nUsing creator index {creatorIndex} of {testEvent.Creators.Count - 1} (0 Index!)",
                    false, color: LOG_COLOR);
            }

            //Timezone information
            var utcTime = testEvent.StartDateTime.GetValueOrDefault().ToUniversalTime();
            var est     = TimeZoneInfo
                          .ConvertTimeFromUtc(utcTime, TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time"))
                          .ToString("ddd HH:mm");
            var pst = TimeZoneInfo
                      .ConvertTimeFromUtc(utcTime, TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time"))
                      .ToString("ddd HH:mm");
            var utc = utcTime.ToString("ddd HH:mm");
            //No more GMT, replaced by UTC
            //            var gmt = TimeZoneInfo.ConvertTimeFromUtc(utcTime, TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time"))
            //                .ToString("ddd HH:mm");

            //Figure out how far away from start we are
            string countdownString = null;
            var    countdown       = testEvent.StartDateTime.GetValueOrDefault().Subtract(DateTime.Now);

            if (testEvent.StartDateTime.GetValueOrDefault().CompareTo(DateTime.Now) < 0)
            {
                countdownString = $"Started: {countdown:h\'H \'m\'M\'} ago!";
            }
            else
            {
                countdownString = countdown.ToString("d'D 'h'H 'm'M'").TrimStart(' ', 'D', 'H', '0');
            }

            //What image should be displayed
            var embedImageUrl = _dataService.RSettings.General.FallbackTestImageUrl;

            if (testEvent.CanUseGallery)
            {
                var randomIndex = _random.Next(testEvent.GalleryImages.Count);
                while (_lastImageIndex == randomIndex)
                {
                    randomIndex = _random.Next(testEvent.GalleryImages.Count);
                }

                if (_dataService.RSettings.ProgramSettings.Debug)
                {
                    _ = _log.LogMessage(
                        $"Using random gallery index {randomIndex} of {testEvent.GalleryImages.Count - 1} (0 Index!)",
                        false, color: LOG_COLOR);
                }

                _lastImageIndex = randomIndex;
                embedImageUrl   = testEvent.GalleryImages[randomIndex];
            }

            //Display the correct password, or omit for comp
            string displayedConnectionInfo;
            string footer;

            if (testEvent.IsCasual)
            {
                displayedConnectionInfo =
                    $"`connect {testEvent.ServerLocation}; password {_dataService.RSettings.General.CasualPassword}`";
                footer = "All players welcome to join";
            }
            else
            {
                displayedConnectionInfo = "*This is a competitive 5v5 test, where not everyone can play.*";
                footer = "Connection info hidden due to competitive test";
            }

            //Setup the basic embed
            var playtestEmbed = new EmbedBuilder()
                                .WithAuthor($"{testEvent.Title} | {testType}")
                                .WithTitle("Workshop Link")
                                .WithUrl(testEvent.WorkshopLink.ToString())
                                .WithDescription(testEvent.Description)
                                .WithColor(new Color(243, 128, 72))
                                .WithFooter(footer);

            playtestEmbed.AddField("Test Starts In", countdownString, true);
            playtestEmbed.AddField(creatorSpelling, creatorProfile, true);
            playtestEmbed.AddField("Moderator", testEvent.Moderator.ToString(), true);

            //Make sure player count isn't null. It may be null if RCON is failing for some reason.
            if (_dataService.GetIncludePlayerCount() && _dataService.GetPlayerCount() != null)
            {
                var playerCount = _dataService.GetPlayerCount();
                playtestEmbed.AddField("Players Connected", playerCount, true);
            }

            playtestEmbed.AddField("Connect to",
                                   $"{displayedConnectionInfo}");

            //Small VS large embed differences
            string information;

            if (smallEmbed)
            {
                playtestEmbed.ThumbnailUrl = embedImageUrl;
                information = $"[Screenshots]({testEvent.ImageGallery}) | " +
                              "[Testing Information](https://www.tophattwaffle.com/playtesting) | " +
                              $"[More Information](https://discordapp.com/channels/{_dataService.Guild.Id}/{_dataService.CSGOAnnouncementChannel.Id}/{fullMessage})";
            }
            else
            {
                information = $"[Screenshots]({testEvent.ImageGallery}) | " +
                              "[Testing Information](https://www.tophattwaffle.com/playtesting)";
                playtestEmbed.ImageUrl     = embedImageUrl;
                playtestEmbed.ThumbnailUrl = thumbnailUrl;
                playtestEmbed.AddField("When",
                                       $"{testEvent.StartDateTime.GetValueOrDefault():MMMM ddd d, HH:mm} | {est} EST | {pst} PST | {utc} UTC");
            }

            playtestEmbed.AddField("Information", information);

            return(playtestEmbed.Build());
        }