Ejemplo n.º 1
0
 public static void PatronageMilestoneReachedOccurred(PatronageMilestoneModel patronageMilestone)
 {
     if (GlobalEvents.OnPatronageMilestoneReachedOccurred != null)
     {
         GlobalEvents.OnPatronageMilestoneReachedOccurred(null, patronageMilestone);
     }
 }
        private void RefreshPatronageMilestoneData()
        {
            this.milestoneGroup = this.period.milestoneGroups.FirstOrDefault(mg => mg.id == this.status.currentMilestoneGroupId);
            if (this.milestoneGroup != null)
            {
                this.EmptyImageFilePath = this.milestoneGroup.uiComponents["vesselImageEmptyPath"].ToString();
                this.FullImageFilePath  = this.milestoneGroup.uiComponents["vesselImageFullPath"].ToString();

                this.milestone = this.milestoneGroup.milestones.FirstOrDefault(m => m.id == this.status.currentMilestoneId);
                if (this.milestone != null)
                {
                    this.Goal   = milestone.target;
                    this.Reward = milestone.PercentageAmountText();
                }

                this.Start = 0;
                if (this.status.currentMilestoneId > 0)
                {
                    PatronageMilestoneModel previousMilestone = this.period.milestoneGroups.SelectMany(mg => mg.milestones).FirstOrDefault(m => m.id == (this.status.currentMilestoneId - 1));
                    if (previousMilestone != null)
                    {
                        this.Start = previousMilestone.target;
                    }
                }
            }
        }
Ejemplo n.º 3
0
        public override async Task Initialize()
        {
            GlobalEvents.OnFollowOccurred                    -= GlobalEvents_OnFollowOccurred;
            GlobalEvents.OnUnfollowOccurred                  -= GlobalEvents_OnUnfollowOccurred;
            GlobalEvents.OnSubscribeOccurred                 -= GlobalEvents_OnSubscribeOccurred;
            GlobalEvents.OnResubscribeOccurred               -= GlobalEvents_OnResubscribeOccurred;
            GlobalEvents.OnDonationOccurred                  -= GlobalEvents_OnDonationOccurred;
            GlobalEvents.OnSparkUseOccurred                  -= GlobalEvents_OnSparkUseOccurred;
            GlobalEvents.OnEmberUseOccurred                  -= GlobalEvents_OnEmberUseOccurred;
            GlobalEvents.OnPatronageUpdateOccurred           -= GlobalEvents_OnPatronageUpdateOccurred;
            GlobalEvents.OnPatronageMilestoneReachedOccurred -= GlobalEvents_OnPatronageMilestoneReachedOccurred;

            if (this.ProgressBarType == ProgressBarTypeEnum.Followers)
            {
                totalFollowers = (int)ChannelSession.Channel.numFollowers;

                GlobalEvents.OnFollowOccurred   += GlobalEvents_OnFollowOccurred;
                GlobalEvents.OnUnfollowOccurred += GlobalEvents_OnUnfollowOccurred;
            }
            else if (this.ProgressBarType == ProgressBarTypeEnum.Subscribers)
            {
                GlobalEvents.OnSubscribeOccurred   += GlobalEvents_OnSubscribeOccurred;
                GlobalEvents.OnResubscribeOccurred += GlobalEvents_OnResubscribeOccurred;
            }
            else if (this.ProgressBarType == ProgressBarTypeEnum.Donations)
            {
                GlobalEvents.OnDonationOccurred += GlobalEvents_OnDonationOccurred;
            }
            else if (this.ProgressBarType == ProgressBarTypeEnum.Sparks)
            {
                GlobalEvents.OnSparkUseOccurred += GlobalEvents_OnSparkUseOccurred;
            }
            else if (this.ProgressBarType == ProgressBarTypeEnum.Embers)
            {
                GlobalEvents.OnEmberUseOccurred += GlobalEvents_OnEmberUseOccurred;
            }
            else if (this.ProgressBarType == ProgressBarTypeEnum.Milestones)
            {
                PatronageStatusModel patronageStatus = await ChannelSession.Connection.GetPatronageStatus(ChannelSession.Channel);

                if (patronageStatus != null)
                {
                    this.CurrentAmountNumber = patronageStatus.patronageEarned;
                }

                PatronageMilestoneModel currentMilestone = await ChannelSession.Connection.GetCurrentPatronageMilestone();

                if (currentMilestone != null)
                {
                    this.GoalAmountNumber = currentMilestone.target;
                }

                GlobalEvents.OnPatronageUpdateOccurred           += GlobalEvents_OnPatronageUpdateOccurred;
                GlobalEvents.OnPatronageMilestoneReachedOccurred += GlobalEvents_OnPatronageMilestoneReachedOccurred;
            }

            await base.Initialize();
        }
        public override async Task Initialize()
        {
            if (this.ResetAfterDays > 0 && this.LastReset.TotalDaysFromNow() > this.ResetAfterDays)
            {
                this.CurrentAmount = 0;
                this.LastReset     = DateTimeOffset.Now;
            }

            if (this.ProgressBarType == OverlayProgressBarItemTypeEnum.Followers)
            {
                this.CurrentAmount = (int)ChannelSession.Channel.numFollowers;

                GlobalEvents.OnFollowOccurred   += GlobalEvents_OnFollowOccurred;
                GlobalEvents.OnUnfollowOccurred += GlobalEvents_OnUnfollowOccurred;
            }
            else if (this.ProgressBarType == OverlayProgressBarItemTypeEnum.Subscribers)
            {
                GlobalEvents.OnSubscribeOccurred          += GlobalEvents_OnSubscribeOccurred;
                GlobalEvents.OnResubscribeOccurred        += GlobalEvents_OnResubscribeOccurred;
                GlobalEvents.OnSubscriptionGiftedOccurred += GlobalEvents_OnSubscriptionGiftedOccurred;
            }
            else if (this.ProgressBarType == OverlayProgressBarItemTypeEnum.Donations)
            {
                GlobalEvents.OnDonationOccurred += GlobalEvents_OnDonationOccurred;
            }
            else if (this.ProgressBarType == OverlayProgressBarItemTypeEnum.Sparks)
            {
                GlobalEvents.OnSparkUseOccurred += GlobalEvents_OnSparkUseOccurred;
            }
            else if (this.ProgressBarType == OverlayProgressBarItemTypeEnum.Embers)
            {
                GlobalEvents.OnEmberUseOccurred += GlobalEvents_OnEmberUseOccurred;
            }
            else if (this.ProgressBarType == OverlayProgressBarItemTypeEnum.Milestones)
            {
                PatronageStatusModel patronageStatus = await ChannelSession.Connection.GetPatronageStatus(ChannelSession.Channel);

                if (patronageStatus != null)
                {
                    this.CurrentAmount = patronageStatus.patronageEarned;
                }

                PatronageMilestoneModel currentMilestone = await ChannelSession.Connection.GetCurrentPatronageMilestone();

                if (currentMilestone != null)
                {
                    this.GoalAmount = currentMilestone.target;
                }

                GlobalEvents.OnPatronageUpdateOccurred           += GlobalEvents_OnPatronageUpdateOccurred;
                GlobalEvents.OnPatronageMilestoneReachedOccurred += GlobalEvents_OnPatronageMilestoneReachedOccurred;
            }

            await base.Initialize();
        }
Ejemplo n.º 5
0
 private void GlobalEvents_OnPatronageMilestoneReachedOccurred(object sender, PatronageMilestoneModel patronageMilestone)
 {
     this.refreshMilestone = true;
 }
Ejemplo n.º 6
0
        protected override async Task <Dictionary <string, string> > GetReplacementSets(UserViewModel user, IEnumerable <string> arguments, Dictionary <string, string> extraSpecialIdentifiers)
        {
            Dictionary <string, string> replacementSets = new Dictionary <string, string>();

            replacementSets["BACKGROUND_COLOR"] = this.BackgroundColor;
            replacementSets["PROGRESS_COLOR"]   = this.ProgressColor;
            replacementSets["TEXT_COLOR"]       = this.TextColor;
            replacementSets["BAR_WIDTH"]        = this.Width.ToString();
            replacementSets["BAR_HEIGHT"]       = this.Height.ToString();
            replacementSets["TEXT_FONT"]        = this.TextFont;
            replacementSets["TEXT_SIZE"]        = ((3 * this.Height) / 4).ToString();

            double amount = this.CurrentAmountNumber;
            double goal   = this.GoalAmountNumber;

            if (this.ProgressBarType == ProgressBarTypeEnum.Followers)
            {
                amount = this.totalFollowers;
                if (this.CurrentAmountNumber >= 0)
                {
                    amount = this.totalFollowers - this.CurrentAmountNumber;
                }
            }
            else if (this.ProgressBarType == ProgressBarTypeEnum.Milestones)
            {
                if (this.refreshMilestone)
                {
                    this.refreshMilestone = false;
                    PatronageMilestoneModel currentMilestone = await ChannelSession.Connection.GetCurrentPatronageMilestone();

                    if (currentMilestone != null)
                    {
                        goal = this.GoalAmountNumber = currentMilestone.target;
                    }
                }
            }
            else if (this.ProgressBarType == ProgressBarTypeEnum.Custom)
            {
                if (!string.IsNullOrEmpty(this.CurrentAmountCustom))
                {
                    string customAmount = await this.ReplaceStringWithSpecialModifiers(this.CurrentAmountCustom, user, arguments, extraSpecialIdentifiers);

                    double.TryParse(customAmount, out amount);
                }
                if (!string.IsNullOrEmpty(this.GoalAmountCustom))
                {
                    string customGoal = await this.ReplaceStringWithSpecialModifiers(this.GoalAmountCustom, user, arguments, extraSpecialIdentifiers);

                    double.TryParse(customGoal, out goal);
                }
            }

            double percentage = (amount / goal);

            if (!this.GoalReached && percentage >= 1.0)
            {
                this.GoalReached = true;
                if (this.GoalReachedCommand != null)
                {
                    await this.GoalReachedCommand.Perform();
                }
            }

            replacementSets["AMOUNT"]     = amount.ToString();
            replacementSets["GOAL"]       = goal.ToString();
            replacementSets["PERCENTAGE"] = ((int)(percentage * 100)).ToString();
            if (goal > 0)
            {
                int progressWidth = (int)(((double)this.Width) * percentage);
                progressWidth = MathHelper.Clamp(progressWidth, 0, this.Width);
                replacementSets["PROGRESS_WIDTH"] = progressWidth.ToString();
            }

            return(replacementSets);
        }
 public static string PercentageAmountText(this PatronageMilestoneModel patronageMilestone)
 {
     return(string.Format("{0}%", patronageMilestone.bonus));
 }
 public static double DollarAmount(this PatronageMilestoneModel patronageMilestone)
 {
     return(Math.Round(((double)patronageMilestone.reward) / 100.0, 2));
 }
 public static string DollarAmountText(this PatronageMilestoneModel patronageMilestone)
 {
     return(string.Format("{0:C}", patronageMilestone.DollarAmount()));
 }
        public async Task ReplaceCommonSpecialModifiers(UserViewModel user, IEnumerable <string> arguments = null)
        {
            foreach (string counter in ChannelSession.Counters.Keys)
            {
                this.ReplaceSpecialIdentifier(counter, ChannelSession.Counters[counter].ToString());
            }

            foreach (var kvp in SpecialIdentifierStringBuilder.CustomSpecialIdentifiers)
            {
                this.ReplaceSpecialIdentifier(kvp.Key, kvp.Value);
            }

            this.ReplaceSpecialIdentifier("timedigits", DateTimeOffset.Now.ToString("HHmm"));
            this.ReplaceSpecialIdentifier("dayoftheweek", DateTimeOffset.Now.DayOfWeek.ToString());
            this.ReplaceSpecialIdentifier("datetime", DateTimeOffset.Now.ToString("g"));
            this.ReplaceSpecialIdentifier("date", DateTimeOffset.Now.ToString("d"));
            this.ReplaceSpecialIdentifier("time", DateTimeOffset.Now.ToString("t"));
            this.ReplaceSpecialIdentifier("linebreak", Environment.NewLine);

            if (this.ContainsSpecialIdentifier(SpecialIdentifierStringBuilder.TopSpecialIdentifierHeader))
            {
                Dictionary <uint, UserDataViewModel> allUsersDictionary = ChannelSession.Settings.UserData.ToDictionary();
                allUsersDictionary.Remove(ChannelSession.Channel.user.id);

                IEnumerable <UserDataViewModel> allUsers = allUsersDictionary.Select(kvp => kvp.Value);
                allUsers = allUsers.Where(u => !u.IsCurrencyRankExempt);

                if (this.ContainsRegexSpecialIdentifier(SpecialIdentifierStringBuilder.TopSparksUsedRegexSpecialIdentifierHeader))
                {
                    await this.HandleSparksUsed("weekly", async (amount) => { return(await ChannelSession.Connection.GetWeeklySparksLeaderboard(ChannelSession.Channel, amount)); });

                    await this.HandleSparksUsed("monthly", async (amount) => { return(await ChannelSession.Connection.GetMonthlySparksLeaderboard(ChannelSession.Channel, amount)); });

                    await this.HandleSparksUsed("yearly", async (amount) => { return(await ChannelSession.Connection.GetYearlySparksLeaderboard(ChannelSession.Channel, amount)); });

                    await this.HandleSparksUsed("alltime", async (amount) => { return(await ChannelSession.Connection.GetAllTimeSparksLeaderboard(ChannelSession.Channel, amount)); });
                }

                if (this.ContainsRegexSpecialIdentifier(SpecialIdentifierStringBuilder.TopEmbersUsedRegexSpecialIdentifierHeader))
                {
                    await this.HandleEmbersUsed("weekly", async (amount) => { return(await ChannelSession.Connection.GetWeeklyEmbersLeaderboard(ChannelSession.Channel, amount)); });

                    await this.HandleEmbersUsed("monthly", async (amount) => { return(await ChannelSession.Connection.GetMonthlyEmbersLeaderboard(ChannelSession.Channel, amount)); });

                    await this.HandleEmbersUsed("yearly", async (amount) => { return(await ChannelSession.Connection.GetYearlyEmbersLeaderboard(ChannelSession.Channel, amount)); });

                    await this.HandleEmbersUsed("alltime", async (amount) => { return(await ChannelSession.Connection.GetAllTimeEmbersLeaderboard(ChannelSession.Channel, amount)); });
                }

                if (this.ContainsRegexSpecialIdentifier(SpecialIdentifierStringBuilder.TopTimeRegexSpecialIdentifier))
                {
                    await this.ReplaceNumberBasedRegexSpecialIdentifier(SpecialIdentifierStringBuilder.TopTimeRegexSpecialIdentifier, (total) =>
                    {
                        List <string> timeUserList = new List <string>();
                        int userPosition           = 1;
                        foreach (UserDataViewModel timeUser in allUsers.OrderByDescending(u => u.ViewingMinutes).Take(total))
                        {
                            timeUserList.Add($"#{userPosition}) {timeUser.UserName} - {timeUser.ViewingTimeShortString}");
                            userPosition++;
                        }

                        string result = "No users found.";
                        if (timeUserList.Count > 0)
                        {
                            result = string.Join(", ", timeUserList);
                        }
                        return(Task.FromResult(result));
                    });
                }

                foreach (UserCurrencyViewModel currency in ChannelSession.Settings.Currencies.Values)
                {
                    if (this.ContainsRegexSpecialIdentifier(currency.TopRegexSpecialIdentifier))
                    {
                        await this.ReplaceNumberBasedRegexSpecialIdentifier(currency.TopRegexSpecialIdentifier, (total) =>
                        {
                            List <string> currencyUserList = new List <string>();
                            int userPosition = 1;
                            foreach (UserDataViewModel currencyUser in allUsers.OrderByDescending(u => u.GetCurrencyAmount(currency)).Take(total))
                            {
                                currencyUserList.Add($"#{userPosition}) {currencyUser.UserName} - {currencyUser.GetCurrencyAmount(currency)}");
                                userPosition++;
                            }

                            string result = "No users found.";
                            if (currencyUserList.Count > 0)
                            {
                                result = string.Join(", ", currencyUserList);
                            }
                            return(Task.FromResult(result));
                        });
                    }
                }
            }

            if (this.ContainsSpecialIdentifier(CurrentSongIdentifierHeader) || this.ContainsSpecialIdentifier(NextSongIdentifierHeader))
            {
                if (ChannelSession.Services.SongRequestService != null && ChannelSession.Services.SongRequestService.IsEnabled)
                {
                    this.ReplaceSongRequestSpecialIdentifiers(CurrentSongIdentifierHeader, await ChannelSession.Services.SongRequestService.GetCurrentlyPlaying());
                    this.ReplaceSongRequestSpecialIdentifiers(NextSongIdentifierHeader, await ChannelSession.Services.SongRequestService.GetNextTrack());
                }
            }

            if (this.ContainsSpecialIdentifier(UptimeSpecialIdentifierHeader) || this.ContainsSpecialIdentifier(StartSpecialIdentifierHeader))
            {
                DateTimeOffset startTime = await UptimeChatCommand.GetStartTime();

                if (startTime > DateTimeOffset.MinValue)
                {
                    TimeSpan duration = DateTimeOffset.Now.Subtract(startTime);

                    this.ReplaceSpecialIdentifier(StartSpecialIdentifierHeader + "datetime", startTime.ToString("g"));
                    this.ReplaceSpecialIdentifier(StartSpecialIdentifierHeader + "date", startTime.ToString("d"));
                    this.ReplaceSpecialIdentifier(StartSpecialIdentifierHeader + "time", startTime.ToString("t"));

                    this.ReplaceSpecialIdentifier(UptimeSpecialIdentifierHeader + "total", (int)duration.TotalHours + duration.ToString("\\:mm"));
                    this.ReplaceSpecialIdentifier(UptimeSpecialIdentifierHeader + "hours", ((int)duration.TotalHours).ToString());
                    this.ReplaceSpecialIdentifier(UptimeSpecialIdentifierHeader + "minutes", duration.ToString("mm"));
                    this.ReplaceSpecialIdentifier(UptimeSpecialIdentifierHeader + "seconds", duration.ToString("ss"));
                }
            }

            if (this.ContainsSpecialIdentifier(QuoteSpecialIdentifierHeader) && ChannelSession.Settings.QuotesEnabled && ChannelSession.Settings.UserQuotes.Count > 0)
            {
                UserQuoteViewModel quote = ChannelSession.Settings.UserQuotes.PickRandom();
                if (quote != null)
                {
                    this.ReplaceSpecialIdentifier(QuoteSpecialIdentifierHeader + "random", quote.ToString());
                }

                if (this.ContainsRegexSpecialIdentifier(QuoteNumberRegexSpecialIdentifier))
                {
                    await this.ReplaceNumberBasedRegexSpecialIdentifier(QuoteNumberRegexSpecialIdentifier, (index) =>
                    {
                        if (index > 0 && index <= ChannelSession.Settings.UserQuotes.Count)
                        {
                            index--;
                            return(Task.FromResult(ChannelSession.Settings.UserQuotes[index].ToString()));
                        }
                        return(Task.FromResult <string>(null));
                    });
                }
            }

            if (this.ContainsSpecialIdentifier(CostreamUsersSpecialIdentifier))
            {
                this.ReplaceSpecialIdentifier(CostreamUsersSpecialIdentifier, await CostreamChatCommand.GetCostreamUsers());
            }

            if (ChannelSession.Services.Twitter != null && this.ContainsSpecialIdentifier("tweet"))
            {
                IEnumerable <Tweet> tweets = await ChannelSession.Services.Twitter.GetLatestTweets();

                if (tweets != null && tweets.Count() > 0)
                {
                    Tweet          latestTweet          = tweets.FirstOrDefault();
                    DateTimeOffset latestTweetLocalTime = latestTweet.DateTime.ToLocalTime();

                    this.ReplaceSpecialIdentifier("tweetlatesturl", latestTweet.TweetLink);
                    this.ReplaceSpecialIdentifier("tweetlatesttext", latestTweet.Text);
                    this.ReplaceSpecialIdentifier("tweetlatestdatetime", latestTweetLocalTime.ToString("g"));
                    this.ReplaceSpecialIdentifier("tweetlatestdate", latestTweetLocalTime.ToString("d"));
                    this.ReplaceSpecialIdentifier("tweetlatesttime", latestTweetLocalTime.ToString("t"));

                    Tweet streamTweet = tweets.FirstOrDefault(t => t.IsStreamTweet);
                    if (streamTweet != null)
                    {
                        DateTimeOffset streamTweetLocalTime = streamTweet.DateTime.ToLocalTime();
                        this.ReplaceSpecialIdentifier("tweetstreamurl", streamTweet.TweetLink);
                        this.ReplaceSpecialIdentifier("tweetstreamtext", streamTweet.Text);
                        this.ReplaceSpecialIdentifier("tweetstreamdatetime", streamTweetLocalTime.ToString("g"));
                        this.ReplaceSpecialIdentifier("tweetstreamdate", streamTweetLocalTime.ToString("d"));
                        this.ReplaceSpecialIdentifier("tweetstreamtime", streamTweetLocalTime.ToString("t"));
                    }
                }
            }

            if (ChannelSession.Services.Spotify != null && this.ContainsSpecialIdentifier("spotify"))
            {
                SpotifyUserProfile profile = await ChannelSession.Services.Spotify.GetCurrentProfile();

                if (profile != null)
                {
                    this.ReplaceSpecialIdentifier("spotifyprofileurl", profile.Link);
                }

                SpotifyCurrentlyPlaying currentlyPlaying = await ChannelSession.Services.Spotify.GetCurrentlyPlaying();

                if (currentlyPlaying != null)
                {
                    this.ReplaceSpecialIdentifier("spotifycurrentlyplaying", currentlyPlaying.ToString());
                }
            }

            if (ChannelSession.Services.ExtraLife.IsConnected() && this.ContainsSpecialIdentifier(ExtraLifeSpecialIdentifierHeader))
            {
                ExtraLifeTeam team = await ChannelSession.Services.ExtraLife.GetTeam();

                this.ReplaceSpecialIdentifier(ExtraLifeSpecialIdentifierHeader + "teamdonationgoal", team.fundraisingGoal.ToString());
                this.ReplaceSpecialIdentifier(ExtraLifeSpecialIdentifierHeader + "teamdonationcount", team.numDonations.ToString());
                this.ReplaceSpecialIdentifier(ExtraLifeSpecialIdentifierHeader + "teamdonationamount", team.sumDonations.ToString());

                ExtraLifeTeamParticipant participant = await ChannelSession.Services.ExtraLife.GetParticipant();

                this.ReplaceSpecialIdentifier(ExtraLifeSpecialIdentifierHeader + "userdonationgoal", participant.fundraisingGoal.ToString());
                this.ReplaceSpecialIdentifier(ExtraLifeSpecialIdentifierHeader + "userdonationcount", participant.numDonations.ToString());
                this.ReplaceSpecialIdentifier(ExtraLifeSpecialIdentifierHeader + "userdonationamount", participant.sumDonations.ToString());
            }

            if (this.ContainsSpecialIdentifier(FeaturedChannelsSpecialIdentifer))
            {
                IEnumerable <ExpandedChannelModel> featuredChannels = await ChannelSession.Connection.GetFeaturedChannels();

                if (featuredChannels != null)
                {
                    this.ReplaceSpecialIdentifier(FeaturedChannelsSpecialIdentifer, string.Join(", ", featuredChannels.Select(c => "@" + c.user.username)));
                }
            }

            if (this.ContainsSpecialIdentifier(StreamSpecialIdentifierHeader))
            {
                ChannelDetailsModel details = await ChannelSession.Connection.GetChannelDetails(ChannelSession.Channel);

                if (details != null)
                {
                    this.ReplaceSpecialIdentifier(StreamSpecialIdentifierHeader + "title", details.name);
                    this.ReplaceSpecialIdentifier(StreamSpecialIdentifierHeader + "agerating", details.audience);
                    this.ReplaceSpecialIdentifier(StreamSpecialIdentifierHeader + "viewercount", details.viewersCurrent.ToString());
                    this.ReplaceSpecialIdentifier(StreamSpecialIdentifierHeader + "followcount", details.numFollowers.ToString());
                    this.ReplaceSpecialIdentifier(StreamSpecialIdentifierHeader + "subcount", details.numSubscribers.ToString());
                }

                if (this.ContainsSpecialIdentifier(StreamHostCountSpecialIdentifier))
                {
                    IEnumerable <ChannelAdvancedModel> hosters = await ChannelSession.Connection.GetHosters(ChannelSession.Channel);

                    if (hosters != null)
                    {
                        this.ReplaceSpecialIdentifier(StreamHostCountSpecialIdentifier, hosters.Count().ToString());
                    }
                    else
                    {
                        this.ReplaceSpecialIdentifier(StreamHostCountSpecialIdentifier, "0");
                    }
                }
            }

            if (this.ContainsSpecialIdentifier(MilestoneSpecialIdentifierHeader))
            {
                PatronageStatusModel patronageStatus = await ChannelSession.Connection.GetPatronageStatus(ChannelSession.Channel);

                if (patronageStatus != null)
                {
                    PatronagePeriodModel patronagePeriod = await ChannelSession.Connection.GetPatronagePeriod(patronageStatus);

                    if (patronagePeriod != null)
                    {
                        IEnumerable <PatronageMilestoneModel> patronageMilestones = patronagePeriod.milestoneGroups.SelectMany(mg => mg.milestones);

                        PatronageMilestoneModel patronageMilestone = patronageMilestones.FirstOrDefault(m => m.id == patronageStatus.currentMilestoneId);
                        if (patronageMilestone != null)
                        {
                            this.ReplaceSpecialIdentifier(MilestoneSpecialIdentifierHeader + "amount", patronageMilestone.target.ToString());
                            this.ReplaceSpecialIdentifier(MilestoneSpecialIdentifierHeader + "remainingamount", (patronageMilestone.target - patronageStatus.patronageEarned).ToString());
                            this.ReplaceSpecialIdentifier(MilestoneSpecialIdentifierHeader + "reward", patronageMilestone.DollarAmountText());
                        }

                        PatronageMilestoneModel patronageNextMilestone = patronageMilestones.FirstOrDefault(m => m.id == (patronageStatus.currentMilestoneId + 1));
                        if (patronageNextMilestone != null)
                        {
                            this.ReplaceSpecialIdentifier(MilestoneSpecialIdentifierHeader + "nextamount", patronageNextMilestone.target.ToString());
                            this.ReplaceSpecialIdentifier(MilestoneSpecialIdentifierHeader + "remainingnextamount", (patronageNextMilestone.target - patronageStatus.patronageEarned).ToString());
                            this.ReplaceSpecialIdentifier(MilestoneSpecialIdentifierHeader + "nextreward", patronageNextMilestone.DollarAmountText());
                        }

                        PatronageMilestoneModel patronageFinalMilestone = patronageMilestones.OrderByDescending(m => m.id).FirstOrDefault();
                        if (patronageNextMilestone != null)
                        {
                            this.ReplaceSpecialIdentifier(MilestoneSpecialIdentifierHeader + "finalamount", patronageFinalMilestone.target.ToString());
                            this.ReplaceSpecialIdentifier(MilestoneSpecialIdentifierHeader + "remainingfinalamount", (patronageFinalMilestone.target - patronageStatus.patronageEarned).ToString());
                            this.ReplaceSpecialIdentifier(MilestoneSpecialIdentifierHeader + "finalreward", patronageFinalMilestone.DollarAmountText());
                        }

                        PatronageMilestoneModel patronageMilestoneHighestEarned         = null;
                        IEnumerable <PatronageMilestoneModel> patronageMilestonesEarned = patronageMilestones.Where(m => m.target <= patronageStatus.patronageEarned);
                        if (patronageMilestonesEarned != null && patronageMilestonesEarned.Count() > 0)
                        {
                            patronageMilestoneHighestEarned = patronageMilestonesEarned.OrderByDescending(m => m.reward).FirstOrDefault();
                        }

                        if (patronageMilestoneHighestEarned != null)
                        {
                            this.ReplaceSpecialIdentifier(MilestoneSpecialIdentifierHeader + "earnedamount", patronageStatus.patronageEarned.ToString());
                            this.ReplaceSpecialIdentifier(MilestoneSpecialIdentifierHeader + "earnedreward", patronageMilestoneHighestEarned.DollarAmountText());
                        }
                        else
                        {
                            this.ReplaceSpecialIdentifier(MilestoneSpecialIdentifierHeader + "earnedamount", "0");
                            this.ReplaceSpecialIdentifier(MilestoneSpecialIdentifierHeader + "earnedreward", "0");
                        }
                    }
                }
            }

            if (this.ContainsSpecialIdentifier(UserSpecialIdentifierHeader))
            {
                await this.HandleUserSpecialIdentifiers(user, string.Empty);
            }

            if (arguments != null)
            {
                for (int i = 0; i < arguments.Count(); i++)
                {
                    string currentArgumentSpecialIdentifierHeader = ArgSpecialIdentifierHeader + (i + 1);
                    if (this.ContainsSpecialIdentifier(currentArgumentSpecialIdentifierHeader))
                    {
                        UserViewModel argUser = await this.GetUserFromArgument(arguments.ElementAt(i));

                        if (argUser != null)
                        {
                            await this.HandleUserSpecialIdentifiers(argUser, currentArgumentSpecialIdentifierHeader);
                        }

                        this.ReplaceSpecialIdentifier(currentArgumentSpecialIdentifierHeader + "text", arguments.ElementAt(i));
                    }
                }

                this.ReplaceSpecialIdentifier("allargs", string.Join(" ", arguments));
                this.ReplaceSpecialIdentifier("argcount", arguments.Count().ToString());
            }

            if (this.ContainsSpecialIdentifier(TargetSpecialIdentifierHeader))
            {
                UserViewModel targetUser = null;
                if (arguments != null && arguments.Count() > 0)
                {
                    targetUser = await this.GetUserFromArgument(arguments.ElementAt(0));
                }

                if (targetUser == null)
                {
                    targetUser = user;
                }

                await this.HandleUserSpecialIdentifiers(targetUser, TargetSpecialIdentifierHeader);
            }

            if (this.ContainsSpecialIdentifier(StreamerSpecialIdentifierHeader))
            {
                await this.HandleUserSpecialIdentifiers(new UserViewModel(ChannelSession.Channel.user), StreamerSpecialIdentifierHeader);
            }

            if (this.ContainsSpecialIdentifier(StreamBossSpecialIdentifierHeader))
            {
                OverlayWidget streamBossWidget = ChannelSession.Settings.OverlayWidgets.FirstOrDefault(w => w.Item is OverlayStreamBoss);
                if (streamBossWidget != null)
                {
                    OverlayStreamBoss streamBossOverlay = (OverlayStreamBoss)streamBossWidget.Item;
                    if (streamBossOverlay != null && streamBossOverlay.CurrentBoss != null)
                    {
                        await this.HandleUserSpecialIdentifiers(streamBossOverlay.CurrentBoss, StreamBossSpecialIdentifierHeader);
                    }
                }
            }

            if (this.ContainsSpecialIdentifier(RandomSpecialIdentifierHeader))
            {
                if (this.randomUserSpecialIdentifierGroupID != Guid.Empty && RandomUserSpecialIdentifierGroups.ContainsKey(this.randomUserSpecialIdentifierGroupID))
                {
                    if (RandomUserSpecialIdentifierGroups[randomUserSpecialIdentifierGroupID].RandomUser != null && this.ContainsSpecialIdentifier(SpecialIdentifierStringBuilder.RandomSpecialIdentifierHeader + "user"))
                    {
                        await this.HandleUserSpecialIdentifiers(RandomUserSpecialIdentifierGroups[randomUserSpecialIdentifierGroupID].RandomUser, RandomSpecialIdentifierHeader);
                    }

                    if (RandomUserSpecialIdentifierGroups[randomUserSpecialIdentifierGroupID].RandomFollower != null && this.ContainsSpecialIdentifier(SpecialIdentifierStringBuilder.RandomFollowerSpecialIdentifierHeader + "user"))
                    {
                        await this.HandleUserSpecialIdentifiers(RandomUserSpecialIdentifierGroups[randomUserSpecialIdentifierGroupID].RandomFollower, RandomFollowerSpecialIdentifierHeader);
                    }

                    if (RandomUserSpecialIdentifierGroups[randomUserSpecialIdentifierGroupID].RandomSubscriber != null && this.ContainsSpecialIdentifier(SpecialIdentifierStringBuilder.RandomSubscriberSpecialIdentifierHeader + "user"))
                    {
                        await this.HandleUserSpecialIdentifiers(RandomUserSpecialIdentifierGroups[randomUserSpecialIdentifierGroupID].RandomSubscriber, RandomSubscriberSpecialIdentifierHeader);
                    }
                }

                if (this.ContainsRegexSpecialIdentifier(RandomNumberRegexSpecialIdentifier))
                {
                    await this.ReplaceNumberBasedRegexSpecialIdentifier(RandomNumberRegexSpecialIdentifier, (maxNumber) =>
                    {
                        int number = RandomHelper.GenerateRandomNumber(maxNumber) + 1;
                        return(Task.FromResult(number.ToString()));
                    });
                }
            }

            if (this.ContainsRegexSpecialIdentifier(UnicodeRegexSpecialIdentifier))
            {
                await this.ReplaceNumberBasedRegexSpecialIdentifier(UnicodeRegexSpecialIdentifier, (number) =>
                {
                    char uChar = (char)number;
                    return(Task.FromResult(uChar.ToString()));
                });
            }
        }
        private async void ConstellationClient_OnSubscribedEventOccurred(object sender, ConstellationLiveEventModel e)
        {
            try
            {
                UserViewModel user     = null;
                bool?         followed = null;
                ChannelModel  channel  = null;

                JToken payloadToken;
                if (e.payload.TryGetValue("user", out payloadToken))
                {
                    user = new UserViewModel(payloadToken.ToObject <UserModel>());

                    JToken subscribeStartToken;
                    if (e.payload.TryGetValue("since", out subscribeStartToken))
                    {
                        user.MixerSubscribeDate = subscribeStartToken.ToObject <DateTimeOffset>();
                    }

                    if (e.payload.TryGetValue("following", out JToken followedToken))
                    {
                        followed = (bool)followedToken;
                    }
                }
                else if (e.payload.TryGetValue("hoster", out payloadToken))
                {
                    channel = payloadToken.ToObject <ChannelModel>();
                    user    = new UserViewModel(channel.userId, channel.token);
                }

                if (user != null)
                {
                    user.UpdateLastActivity();
                }

                if (e.channel.Equals(ConstellationClientWrapper.ChannelUpdateEvent.ToString()))
                {
                    if (e.payload["online"] != null)
                    {
                        bool online = e.payload["online"].ToObject <bool>();
                        user = await ChannelSession.GetCurrentUser();

                        if (online)
                        {
                            if (this.CanUserRunEvent(user, EnumHelper.GetEnumName(OtherEventTypeEnum.MixerChannelStreamStart)))
                            {
                                this.LogUserRunEvent(user, EnumHelper.GetEnumName(OtherEventTypeEnum.MixerChannelStreamStart));
                                await this.RunEventCommand(this.FindMatchingEventCommand(EnumHelper.GetEnumName(OtherEventTypeEnum.MixerChannelStreamStart)), user);
                            }
                        }
                        else
                        {
                            if (this.CanUserRunEvent(user, EnumHelper.GetEnumName(OtherEventTypeEnum.MixerChannelStreamStop)))
                            {
                                this.LogUserRunEvent(user, EnumHelper.GetEnumName(OtherEventTypeEnum.MixerChannelStreamStop));
                                await this.RunEventCommand(this.FindMatchingEventCommand(EnumHelper.GetEnumName(OtherEventTypeEnum.MixerChannelStreamStop)), user);
                            }
                        }
                    }
                }
                else if (e.channel.Equals(ConstellationClientWrapper.ChannelFollowEvent.ToString()))
                {
                    if (followed.GetValueOrDefault())
                    {
                        if (this.CanUserRunEvent(user, ConstellationClientWrapper.ChannelFollowEvent.ToString()))
                        {
                            this.LogUserRunEvent(user, ConstellationClientWrapper.ChannelFollowEvent.ToString());

                            foreach (UserCurrencyViewModel currency in ChannelSession.Settings.Currencies.Values)
                            {
                                user.Data.AddCurrencyAmount(currency, currency.OnFollowBonus);
                            }

                            await this.RunEventCommand(this.FindMatchingEventCommand(e.channel), user);
                        }

                        GlobalEvents.FollowOccurred(user);
                    }
                    else
                    {
                        if (this.CanUserRunEvent(user, EnumHelper.GetEnumName(OtherEventTypeEnum.MixerUserUnfollow)))
                        {
                            this.LogUserRunEvent(user, EnumHelper.GetEnumName(OtherEventTypeEnum.MixerUserUnfollow));
                            await this.RunEventCommand(this.FindMatchingEventCommand(EnumHelper.GetEnumName(OtherEventTypeEnum.MixerUserUnfollow)), user);
                        }

                        GlobalEvents.UnfollowOccurred(user);
                    }
                }
                else if (e.channel.Equals(ConstellationClientWrapper.ChannelHostedEvent.ToString()))
                {
                    int viewerCount = 0;
                    if (channel != null)
                    {
                        viewerCount = (int)channel.viewersCurrent;
                    }

                    if (this.CanUserRunEvent(user, ConstellationClientWrapper.ChannelHostedEvent.ToString()))
                    {
                        this.LogUserRunEvent(user, ConstellationClientWrapper.ChannelHostedEvent.ToString());

                        foreach (UserCurrencyViewModel currency in ChannelSession.Settings.Currencies.Values)
                        {
                            user.Data.AddCurrencyAmount(currency, currency.OnHostBonus);
                        }

                        EventCommand command = this.FindMatchingEventCommand(e.channel);
                        if (command != null)
                        {
                            Dictionary <string, string> specialIdentifiers = new Dictionary <string, string>()
                            {
                                { "hostviewercount", viewerCount.ToString() }
                            };
                            await this.RunEventCommand(command, user, extraSpecialIdentifiers : specialIdentifiers);
                        }

                        GlobalEvents.HostOccurred(new Tuple <UserViewModel, int>(user, viewerCount));
                    }
                }
                else if (e.channel.Equals(ConstellationClientWrapper.ChannelSubscribedEvent.ToString()))
                {
                    if (this.CanUserRunEvent(user, ConstellationClientWrapper.ChannelSubscribedEvent.ToString()))
                    {
                        this.LogUserRunEvent(user, ConstellationClientWrapper.ChannelSubscribedEvent.ToString());

                        user.MixerSubscribeDate = DateTimeOffset.Now;
                        foreach (UserCurrencyViewModel currency in ChannelSession.Settings.Currencies.Values)
                        {
                            user.Data.AddCurrencyAmount(currency, currency.OnSubscribeBonus);
                        }

                        await this.RunEventCommand(this.FindMatchingEventCommand(e.channel), user);
                    }

                    GlobalEvents.SubscribeOccurred(user);
                }
                else if (e.channel.Equals(ConstellationClientWrapper.ChannelResubscribedEvent.ToString()) || e.channel.Equals(ConstellationClientWrapper.ChannelResubscribedSharedEvent.ToString()))
                {
                    int resubMonths = 0;
                    if (e.payload.TryGetValue("totalMonths", out JToken resubMonthsToken))
                    {
                        resubMonths = (int)resubMonthsToken;
                    }

                    if (this.CanUserRunEvent(user, ConstellationClientWrapper.ChannelResubscribedEvent.ToString()))
                    {
                        this.LogUserRunEvent(user, ConstellationClientWrapper.ChannelResubscribedEvent.ToString());

                        foreach (UserCurrencyViewModel currency in ChannelSession.Settings.Currencies.Values)
                        {
                            user.Data.AddCurrencyAmount(currency, currency.OnSubscribeBonus);
                        }

                        Dictionary <string, string> specialIdentifiers = new Dictionary <string, string>()
                        {
                            { "usersubmonths", resubMonths.ToString() }
                        };
                        await this.RunEventCommand(this.FindMatchingEventCommand(ConstellationClientWrapper.ChannelResubscribedEvent.ToString()), user, extraSpecialIdentifiers : specialIdentifiers);

                        GlobalEvents.ResubscribeOccurred(new Tuple <UserViewModel, int>(user, resubMonths));
                    }
                }
                else if (e.channel.Equals(ConstellationClientWrapper.ChannelSubscriptionGiftedEvent.ToString()))
                {
                    if (e.payload.TryGetValue("gifterId", out JToken gifterID) && e.payload.TryGetValue("giftReceiverId", out JToken receiverID))
                    {
                        UserModel gifterUserModel = await ChannelSession.Connection.GetUser(gifterID.ToObject <uint>());

                        UserModel receiverUserModel = await ChannelSession.Connection.GetUser(receiverID.ToObject <uint>());

                        if (gifterUserModel != null && receiverUserModel != null)
                        {
                            UserViewModel gifterUser   = new UserViewModel(gifterUserModel);
                            UserViewModel receiverUser = new UserViewModel(receiverUserModel);

                            EventCommand command = this.FindMatchingEventCommand(e.channel);
                            if (command != null)
                            {
                                await this.RunEventCommand(command, gifterUser, arguments : new List <string>()
                                {
                                    receiverUser.UserName
                                });
                            }

                            GlobalEvents.SubscriptionGiftedOccurred(gifterUser, receiverUser);
                        }
                    }
                }
                else if (e.channel.Equals(ConstellationClientWrapper.ProgressionLevelupEvent.ToString()))
                {
                    if (e.payload.TryGetValue("userId", out JToken userID))
                    {
                        UserModel userModel = await ChannelSession.Connection.GetUser(userID.ToObject <uint>());

                        if (userModel != null)
                        {
                            UserViewModel           userViewModel  = new UserViewModel(userModel);
                            UserFanProgressionModel fanProgression = e.payload.ToObject <UserFanProgressionModel>();
                            if (fanProgression != null)
                            {
                                EventCommand command = this.FindMatchingEventCommand(e.channel);
                                if (command != null)
                                {
                                    Dictionary <string, string> specialIdentifiers = new Dictionary <string, string>()
                                    {
                                        { "userfanprogressionnext", fanProgression.level.nextLevelXp.ToString() },
                                        { "userfanprogressionrank", fanProgression.level.level.ToString() },
                                        { "userfanprogressioncolor", fanProgression.level.color.ToString() },
                                        { "userfanprogressionimage", fanProgression.level.LargeGIFAssetURL.ToString() },
                                        { "userfanprogression", fanProgression.level.currentXp.ToString() },
                                    };
                                    await this.RunEventCommand(command, userViewModel, extraSpecialIdentifiers : specialIdentifiers);
                                }

                                GlobalEvents.ProgressionLevelUpOccurred(userViewModel);
                            }
                        }
                    }
                }
                else if (e.channel.Equals(ConstellationClientWrapper.ChannelSkillEvent.ToString()))
                {
                    if (e.payload["triggeringUserId"] != null)
                    {
                        uint userID = e.payload["triggeringUserId"].ToObject <uint>();
                        user = await ChannelSession.ActiveUsers.GetUserByID(userID);

                        if (user != null)
                        {
                            user = new UserViewModel(await ChannelSession.Connection.GetUser(userID));
                        }
                    }

                    SkillModel skill = null;
                    if (e.payload["skillId"] != null)
                    {
                        Guid skillID = e.payload["skillId"].ToObject <Guid>();
                        if (this.availableSkills.ContainsKey(skillID))
                        {
                            skill = this.availableSkills[skillID];
                        }
                    }

                    if (skill == null)
                    {
                        if (e.payload["manifest"] != null && e.payload["manifest"]["name"] != null)
                        {
                            string skillName = e.payload["manifest"]["name"].ToString();
                            if (skillName.Equals("beachball"))
                            {
                                skill = this.availableSkills.Values.FirstOrDefault(s => s.name.Equals("Beach Ball"));
                            }
                        }
                    }

                    uint price = e.payload["price"].ToObject <uint>();
                    if (user != null)
                    {
                        if (price > 0)
                        {
                            GlobalEvents.SparkUseOccurred(new Tuple <UserViewModel, int>(user, (int)price));
                        }

                        if (skill != null)
                        {
                            JObject            manifest      = (JObject)e.payload["manifest"];
                            JObject            parameters    = (JObject)e.payload["parameters"];
                            SkillInstanceModel skillInstance = new SkillInstanceModel(skill, manifest, parameters);

                            GlobalEvents.SkillUseOccurred(new SkillUsageModel(user, skillInstance));
                        }
                    }
                }
                else if (e.channel.Equals(ConstellationClientWrapper.ChannelPatronageUpdateEvent.ToString()))
                {
                    PatronageStatusModel patronageStatus = e.payload.ToObject <PatronageStatusModel>();
                    if (patronageStatus != null)
                    {
                        GlobalEvents.PatronageUpdateOccurred(patronageStatus);

                        bool milestoneUpdateOccurred = await this.patronageMilestonesSemaphore.WaitAndRelease(() =>
                        {
                            return(Task.FromResult(this.remainingPatronageMilestones.RemoveAll(m => m.target <= patronageStatus.patronageEarned) > 0));
                        });

                        if (milestoneUpdateOccurred)
                        {
                            PatronageMilestoneModel milestoneReached = this.allPatronageMilestones.OrderByDescending(m => m.target).FirstOrDefault(m => m.target <= patronageStatus.patronageEarned);
                            if (milestoneReached != null)
                            {
                                GlobalEvents.PatronageMilestoneReachedOccurred(milestoneReached);

                                Dictionary <string, string> specialIdentifiers = new Dictionary <string, string>()
                                {
                                    { SpecialIdentifierStringBuilder.MilestoneSpecialIdentifierHeader + "amount", milestoneReached.target.ToString() },
                                    { SpecialIdentifierStringBuilder.MilestoneSpecialIdentifierHeader + "reward", milestoneReached.DollarAmountText() },
                                };
                                await this.RunEventCommand(this.FindMatchingEventCommand(EnumHelper.GetEnumName(OtherEventTypeEnum.MixerMilestoneReached)), await ChannelSession.GetCurrentUser(), extraSpecialIdentifiers : specialIdentifiers);
                            }
                        }
                    }
                }

                if (this.OnEventOccurred != null)
                {
                    this.OnEventOccurred(this, e);
                }
            }
            catch (Exception ex) { Util.Logger.Log(ex); }
        }
Ejemplo n.º 12
0
        public StatisticsTracker()
        {
            this.StartTime = DateTimeOffset.Now;

            GlobalEvents.OnFollowOccurred             += Constellation_OnFollowOccurred;
            GlobalEvents.OnUnfollowOccurred           += Constellation_OnUnfollowOccurred;
            GlobalEvents.OnHostOccurred               += Constellation_OnHostedOccurred;
            GlobalEvents.OnSubscribeOccurred          += Constellation_OnSubscribedOccurred;
            GlobalEvents.OnResubscribeOccurred        += Constellation_OnResubscribedOccurred;
            GlobalEvents.OnSubscriptionGiftedOccurred += GlobalEvents_OnSubscriptionGiftedOccurred;

            ChannelSession.Interactive.OnInteractiveControlUsed += Interactive_OnInteractiveControlUsed;

            GlobalEvents.OnDonationOccurred += GlobalEvents_OnDonationOccurred;

            GlobalEvents.OnSparkUseOccurred += GlobalEvents_OnSparkUseOccurred;
            GlobalEvents.OnEmberUseOccurred += GlobalEvents_OnEmberUseOccurred;

            this.Statistics = new List <StatisticDataTrackerBase>();

            this.Statistics.Add(new TrackedNumberStatisticDataTracker("Viewers", "Eye", true, (StatisticDataTrackerBase stats) =>
            {
                TrackedNumberStatisticDataTracker numberStats = (TrackedNumberStatisticDataTracker)stats;

                int viewersCurrent = 0;
                if (ChannelSession.Channel != null)
                {
                    viewersCurrent = (int)ChannelSession.Channel.viewersCurrent;
                }

                numberStats.AddValue(viewersCurrent);
                return(Task.FromResult(0));
            }));

            this.Statistics.Add(new TrackedNumberStatisticDataTracker("Chatters", "MessageTextOutline", true, async(StatisticDataTrackerBase stats) =>
            {
                TrackedNumberStatisticDataTracker numberStats = (TrackedNumberStatisticDataTracker)stats;
                numberStats.AddValue(await ChannelSession.ActiveUsers.Count());
            }));

            this.Statistics.Add(this.followTracker);
            this.Statistics.Add(this.unfollowTracker);
            this.Statistics.Add(this.hostsTracker);
            this.Statistics.Add(this.subscriberTracker);
            this.Statistics.Add(this.resubscriberTracker);
            this.Statistics.Add(this.giftedSubscriptionsTracker);

            this.Statistics.Add(this.interactiveTracker);
            this.Statistics.Add(this.sparksTracker);
            this.Statistics.Add(new StaticTextStatisticDataTracker("Milestones", "Diamond", true, async(StatisticDataTrackerBase stats) =>
            {
                StaticTextStatisticDataTracker staticStats = (StaticTextStatisticDataTracker)stats;
                staticStats.ClearValues();

                if (ChannelSession.Connection != null && ChannelSession.Channel != null)
                {
                    PatronageStatusModel patronageStatus = await ChannelSession.Connection.GetPatronageStatus(ChannelSession.Channel);
                    if (patronageStatus != null)
                    {
                        PatronagePeriodModel patronagePeriod = await ChannelSession.Connection.GetPatronagePeriod(patronageStatus);
                        if (patronagePeriod != null)
                        {
                            IEnumerable <PatronageMilestoneModel> patronageMilestones       = patronagePeriod.milestoneGroups.SelectMany(mg => mg.milestones);
                            IEnumerable <PatronageMilestoneModel> patronageMilestonesEarned = patronageMilestones.Where(m => m.target <= patronageStatus.patronageEarned);
                            if (patronageMilestonesEarned.Count() > 0)
                            {
                                PatronageMilestoneModel patronageMilestoneHighestEarned = patronageMilestonesEarned.OrderByDescending(m => m.bonus).FirstOrDefault();
                                if (patronageMilestoneHighestEarned != null)
                                {
                                    staticStats.AddValue("Milestone #", patronageStatus.currentMilestoneId.ToString());
                                    staticStats.AddValue("Total Sparks", patronageStatus.patronageEarned.ToString());
                                    staticStats.AddValue("Total Boost", patronageMilestoneHighestEarned.PercentageAmountText());
                                    return;
                                }
                            }
                        }
                    }
                }

                staticStats.AddValue("Milestone #", "0");
                staticStats.AddValue("Total Sparks", "0");
                staticStats.AddValue("Total Boost", "0%");
            }));
            this.Statistics.Add(this.embersTracker);

            this.Statistics.Add(this.donationsTracker);
        }
 private async void GlobalEvents_OnPatronageMilestoneReachedOccurred(object sender, PatronageMilestoneModel patronageMilestone)
 {
     await this.AddEvent(string.Format("{0} Milestone", patronageMilestone.PercentageAmountText()), string.Format("{0} Sparks", patronageMilestone.target));
 }
        private async void GlobalEvents_OnPatronageMilestoneReachedOccurred(object sender, PatronageMilestoneModel milestone)
        {
            await this.patronageSemaphore.WaitAndRelease(() =>
            {
                this.ProgressMade     = false;
                this.MilestoneReached = true;

                this.RefreshPatronageMilestoneData();

                return(Task.FromResult(0));
            });

            this.SendUpdateRequired();
        }