/// <summary> /// Event fired when the stream commands need to be update. /// </summary> private void OnUpdate() { if (!this.IsConnected) { return; } try { lock (this.VoteLock) { if (!this.IsConnected || !BrowseViewModel.GetInstance().IsLoggedIn) { return; } AccessTokens accessTokens = SettingsViewModel.GetInstance().AccessTokens; IEnumerable <CheatVotes> cheatVotes = SqualrApi.GetStreamActivationIds(accessTokens.AccessToken); IEnumerable <Cheat> candidateCheats = LibraryViewModel.GetInstance().CheatsInLibrary; if (candidateCheats == null || this.PreviousCheatVotes == null || cheatVotes == null || this.PreviousCheatVotes.Count() != cheatVotes.Count()) { this.PreviousCheatVotes = cheatVotes; return; } // Get cheat IDs to activate based on increased vote counts IEnumerable <Int32> cheatIdsToActivate = cheatVotes .Join( this.PreviousCheatVotes, currentVote => currentVote.CheatId, previousVote => previousVote.CheatId, (currentVote, previousVote) => new { cheatId = currentVote.CheatId, currentCount = currentVote.VoteCount, previousCount = previousVote.VoteCount }) .Where(combinedVote => combinedVote.currentCount != combinedVote.previousCount) .Select(combinedVote => combinedVote.cheatId); // Add in new votes with no previous vote count cheatIdsToActivate = cheatVotes .Select(vote => vote.CheatId) .Except(this.PreviousCheatVotes.Select(vote => vote.CheatId)) .Concat(cheatIdsToActivate) .Distinct(); IEnumerable <Cheat> projectItemsToActivate = cheatIdsToActivate .Join( candidateCheats, cheatId => cheatId, projectItem => projectItem?.CheatId, (cheatId, projectItem) => projectItem); IEnumerable <Cheat> projectItemsToDeactivate = cheatVotes .Join( candidateCheats, cheatVote => cheatVote.CheatId, projectItem => projectItem?.CheatId, (cheatId, projectItem) => projectItem) .Except(projectItemsToActivate); // Handle activations projectItemsToActivate.ForEach(item => { item.IsActivated = true; // Reset duration always item.Duration = 0.0f; }); // Notify which project items were activated such that Squalr can update the stream overlay if (projectItemsToActivate.Count() > 0) { Task.Run(() => { IEnumerable <Cheat> activatedProjectItems = candidateCheats .Select(item => item) .Where(item => !item.IsStreamDisabled) .Where(item => item.IsActivated); IEnumerable <OverlayMeta> overlayMeta = activatedProjectItems .Select(item => new OverlayMeta(item.CheatId, item.Cooldown, item.Duration)); if (overlayMeta.Count() > 0) { try { SqualrApi.UpdateOverlayMeta(accessTokens.AccessToken, overlayMeta.ToArray()); } catch (Exception ex) { OutputViewModel.GetInstance().Log(OutputViewModel.LogLevel.Error, "Error updating overlay cooldowns and durations", ex); } } }); } this.PreviousCheatVotes = cheatVotes; } } catch (Exception ex) { OutputViewModel.GetInstance().Log(OutputViewModel.LogLevel.Warn, "Error fetching activated cheats", ex); } }