예제 #1
0
        private EmbedBuilder CommunityGoalToEmbed(CommunityGoal cg)
        {
            string thumbnailURL       = _options.CurrentValue.ThumbnailURL;
            string descriptionTrimmed = cg.Description.Length <= EmbedBuilder.MaxDescriptionLength ? cg.Description :
                                        $"{cg.Description.Remove(EmbedBuilder.MaxDescriptionLength - 3)}...";
            EmbedBuilder builder = new EmbedBuilder()
                                   .WithAuthor("Elite Dangerous Community Goals", _client.CurrentUser.GetAvatarUrl() ?? _client.CurrentUser.GetDefaultAvatarUrl())
                                   .WithTitle(cg.Name)
                                   .WithDescription($"```\n{cg.Objective}\n```\n{descriptionTrimmed}")
                                   .AddField("System", cg.SystemName, true)
                                   .AddField("Station", cg.StationName, true)
                                   .AddField("Tier Reached", $"*{cg.TierReached}* / {cg.TierMax}")
                                   .AddField("Contributing Pilots", cg.ContributingPilotsCount.ToString(), true)
                                   .AddField("Contributions Count", cg.ContributionsCount.ToString(), true)
                                   .AddField("Last Updated", $"{(DateTime.UtcNow - cg.LastUpdateTime.ToUniversalTime()).ToLongFriendlyString()} ago")
                                   .AddField("Is Completed?", cg.IsCompleted ? "\u2705" : "\u274C", true)
                                   .WithUrl(cg.InaraURL)
                                   .WithColor(cg.IsCompleted ? Color.Green : (Color)System.Drawing.Color.Cyan)
                                   .WithFooter("Powered by Inara | CG expiration time: ")
                                   .WithTimestamp(cg.ExpirationTime);

            if (!string.IsNullOrWhiteSpace(thumbnailURL))
            {
                builder.WithThumbnailUrl(thumbnailURL);
            }
            if (!cg.IsCompleted)
            {
                builder.AddField("Time Left", (cg.ExpirationTime - DateTimeOffset.Now).ToLongFriendlyString());
            }

            if (!string.IsNullOrWhiteSpace(cg.Reward))
            {
                string rewardTrimmed = cg.Reward.Length <= EmbedFieldBuilder.MaxFieldValueLength ? cg.Reward :
                                       $"{cg.Reward.Remove(EmbedFieldBuilder.MaxFieldValueLength - 3)}...";
                builder.AddField("Reward", rewardTrimmed);
            }
            return(builder);
        }
예제 #2
0
        private void StartAutomaticNewsPosting()
        {
            if (_autoModeCTS != null)
            {
                return;
            }

            _autoModeCTS = new CancellationTokenSource();
            Task autoTask = Task.Run(async() =>
            {
                using IDisposable context           = _log.UseSource("Elite CGs");
                CancellationToken cancellationToken = _autoModeCTS.Token;
                // wait 5 seconds to let the client get connection state in check
                await Task.Delay(5 * 1000, cancellationToken).ConfigureAwait(false);
                _log.LogDebug("Starting automatic ED CG checker");
                DateTime _lastRetrievalTime = DateTime.MinValue;
                try
                {
                    while (!cancellationToken.IsCancellationRequested)
                    {
                        if (!this._enabled)
                        {
                            _log.LogWarning("Inara credentials missing. Elite Dangerous Community Goals feature will be disabled");
                            return;
                        }

                        TimeSpan nextUpdateIn = (_lastRetrievalTime + _options.CurrentValue.AutoNewsInterval) - DateTime.UtcNow;
                        // if still waiting, await time, and repeat iteration
                        if (nextUpdateIn > TimeSpan.Zero)
                        {
                            _log.LogTrace("Next update in: {TimeRemaining}", nextUpdateIn);
                            // this will not reflect on updates to options monitor, but that's ok
                            await Task.Delay(nextUpdateIn, cancellationToken).ConfigureAwait(false);
                            continue;
                        }

                        CommunityGoalsOptions options = _options.CurrentValue;

                        // get guild channel
                        if (!(_client.GetChannel(options.AutoNewsChannelID) is SocketTextChannel guildChannel))
                        {
                            throw new InvalidOperationException($"Channel {options.AutoNewsChannelID} is not a valid guild text channel.");
                        }

                        // retrieve CG data, take only new or finished ones, and then update cache
                        IEnumerable <CommunityGoal> allCGs         = await QueryCommunityGoalsAsync(cancellationToken).ConfigureAwait(false);
                        IList <CommunityGoal> newOrJustFinishedCGs = new List <CommunityGoal>(allCGs.Count());
                        foreach (CommunityGoal cg in allCGs)
                        {
                            CommunityGoal historyCg = await _cgHistoryStore.GetAsync(cg.ID, cancellationToken).ConfigureAwait(false);
                            if (historyCg == null || historyCg.IsCompleted != cg.IsCompleted)
                            {
                                newOrJustFinishedCGs.Add(cg);
                                await _cgHistoryStore.SetAsync(cg, cancellationToken).ConfigureAwait(false);
                            }
                        }
                        _log.LogTrace("New or just finished CGs count: {Count}", newOrJustFinishedCGs.Count);

                        // post all CGs
                        _log.LogTrace("Sending CGs");
                        foreach (CommunityGoal cg in newOrJustFinishedCGs)
                        {
                            await guildChannel.SendMessageAsync(null, false, CommunityGoalToEmbed(cg).Build(), cancellationToken).ConfigureAwait(false);
                        }
                        _lastRetrievalTime = DateTime.UtcNow;
                    }
                }
                catch (OperationCanceledException) { }
                catch (Exception ex) when(ex.LogAsError(_log, "Error occured in automatic ED CG checker loop"))
                {
                }
                finally
                {
                    _log.LogDebug("Stopping automatic ED CG checker");
                    // clear CTS on exiting if it wasn't cleared yet
                    if (_autoModeCTS?.Token == cancellationToken)
                    {
                        _autoModeCTS = null;
                    }
                }
            }, _autoModeCTS.Token);
        }