예제 #1
0
        /// <summary>
        /// Get the name of a voter that is referenced if that is the only
        /// reference in the vote.
        /// </summary>
        /// <param name="post">The post.</param>
        /// <returns></returns>
        private string GetPureRankReference(PostComponents post)
        {
            if (post.VoteLines.Count == 1)
            {
                var refNames = VoteString.GetVoteReferenceNames(post.VoteLines.First());

                var refVoter = refNames[ReferenceType.Voter].FirstOrDefault(n => n != post.Author && VoteCounter.HasUserEnteredVoter(n, VoteType.Rank));

                return(refVoter);
            }

            return(null);
        }
예제 #2
0
        /// <summary>
        /// Determine if there are any references to future (unprocessed) user votes
        /// within the current vote.
        /// </summary>
        /// <param name="post">Post containing the current vote.</param>
        /// <returns>Returns true if a future reference is found. Otherwise false.</returns>
        private bool HasFutureReference(PostComponents post, IQuest quest)
        {
            // If we decide it has to be forced, ignore all checks in here.
            if (post.ForceProcess)
            {
                return(false);
            }

            // If proxy votes are disabled, we don't need to look for proxy names, so there can't be future references.
            // Likewise, if we're forcing all proxy votes to be pinned, there can't be any future references.
            if (quest.DisableProxyVotes || quest.ForcePinnedProxyVotes)
            {
                return(false);
            }

            foreach (var line in post.WorkingVote)
            {
                // Get the possible proxy references this line contains
                var refNames = VoteString.GetVoteReferenceNames(line);

                // Pinned references (^ or pin keywords) are explicitly not future references
                if (refNames[ReferenceType.Label].Any(a => a == "^" || a == "pin"))
                {
                    continue;
                }

                // Any references to plans automatically work, as they are defined in a preprocess phase.
                if (refNames[ReferenceType.Plan].Any(VoteCounter.HasPlan))
                {
                    continue;
                }

                string refVoter = refNames[ReferenceType.Voter].FirstOrDefault(n => VoteCounter.ReferenceVoters.Contains(n, Agnostic.StringComparer))
                                  ?.AgnosticMatch(VoteCounter.ReferenceVoters);

                if (refVoter != null && refVoter != post.Author)
                {
                    var refVoterPosts = VoteCounter.PostsList.Where(p => p.Author == refVoter).ToList();

                    // If ref voter has no posts (how did we get here?), it can't be a future reference.
                    if (!refVoterPosts.Any())
                    {
                        continue;
                    }

                    // If the referenced voter never made a real vote (eg: only made base plans or rank votes),
                    // then this can't be treated as a future reference.
                    var refWorkingVotes = refVoterPosts.Where(p => p.WorkingVote.Count > 0);

                    if (!refWorkingVotes.Any())
                    {
                        continue;
                    }

                    // If there's no 'plan' label, then we need to verify that the last vote that the
                    // ref voter made (has a working vote) was processed.
                    // If it's been processed, then we're OK to let this vote through.
                    if (refWorkingVotes.Last().Processed)
                    {
                        continue;
                    }

                    // If none of the conditions above are met, then consider this a future reference.
                    return(true);
                }
            }

            // No future references were found.
            return(false);
        }