예제 #1
0
        /// <summary>
        ///   This routine handles sync request aspects that require fetching a list of all the puzzles the team
        ///   has solved.
        /// </summary>
        private async Task HandleSyncAspectsRequiringListOfSolvedPuzzles(DecodedSyncRequest request, SyncResponse response,
                                                                         string puzzleGroup, int teamId, int eventId, int puzzleId)
        {
            // If the requester isn't asking for pieces (by setting MinSolveCount to null), and isn't asking about
            // whether any puzzle IDs are solved, we can save time by not querying the list of solved puzzles.

            if (request.MinSolveCount == null && (request.QueryPuzzleIds == null || request.QueryPuzzleIds.Count == 0))
            {
                return;
            }

            // If the request is asking which of the puzzle IDs in request.QueryPuzzleIds has been
            // solved, create a HashSet so that we can quickly look up if an ID is in that list.

            HashSet <int> queryPuzzleIdSet = null;

            if (request.QueryPuzzleIds != null)
            {
                queryPuzzleIdSet = new HashSet <int>();
                foreach (var queryPuzzleId in request.QueryPuzzleIds)
                {
                    queryPuzzleIdSet.Add(queryPuzzleId);
                }
            }

            // Get a list of all the puzzles this team has solved from this event.

            List <Puzzle> solves = await(from state in context.PuzzleStatePerTeam
                                         where state.TeamID == teamId && state.SolvedTime != null
                                         select state.Puzzle).ToListAsync();

            int        maxSolveCount = 0;
            List <int> solvedPuzzles = new List <int>();

            foreach (var solvedPuzzle in solves)
            {
                // If the request is asking whether certain puzzles are solved, check if it's
                // in the set and, if so, put it in the list of solved puzzles to inform the
                // requester of.  Also, if we've been asked to query all puzzles in the puzzle's
                // group and this is one of them, put it in the list of solved puzzles.

                if (queryPuzzleIdSet != null && queryPuzzleIdSet.Contains(solvedPuzzle.ID))
                {
                    solvedPuzzles.Add(solvedPuzzle.ID);
                }
                else if (request.QueryAllInGroup && solvedPuzzle.Group == puzzleGroup)
                {
                    solvedPuzzles.Add(solvedPuzzle.ID);
                }

                // When counting solves, only count puzzles if they're not in the same group
                // as the puzzle being synced, and only if they're worth at least 10 points
                // and exactly 0 hint coins.

                if (puzzleGroup == null || solvedPuzzle.Group != puzzleGroup)
                {
                    if (solvedPuzzle.SolveValue >= 10 && solvedPuzzle.HintCoinsForSolve == 0)
                    {
                        maxSolveCount += 1;
                    }
                }

                // If the user solved a cheat code in this group, treat it as a solve count of 1000.
                // The reason we require the cheat code to be in the same group as the puzzle being
                // sync'ed is to defend against mistakes by authors in other groups.  If an author
                // of a puzzle in another group accidentally sets the cheat-code flag on their
                // puzzle, we don't want to consequently give all teams that solve it all pieces of
                // the puzzle being sync'ed.

                if (solvedPuzzle.IsCheatCode && solvedPuzzle.Group == puzzleGroup)
                {
                    maxSolveCount += 1000;
                }
            }

            // If the requester is asking for puzzle pieces (by setting request.MinSolveCount != null)
            // and if there are pieces of the puzzle that the requester has now earned but hasn't
            // yet received, because the maximum solve count they've earned is at least as high
            // as the minimum solve count the requester is asking for, then return those pieces.
            // Note that request.MinSolveCount is the minimum solve count of tokens the requester
            // *hasn't* seen yet.

            if (request.MinSolveCount != null && maxSolveCount >= request.MinSolveCount)
            {
                List <Piece> pieces = await(from piece in context.Pieces
                                            where piece.ProgressLevel >= request.MinSolveCount && piece.ProgressLevel <= maxSolveCount &&
                                            piece.PuzzleID == puzzleId
                                            select piece).ToListAsync();
                response.SetMinAndMaxSolveCountAndPieces(request.MinSolveCount.Value, maxSolveCount, pieces);
            }

            // If we found some solved puzzles in request.QueryPuzzleIds, return those in the
            // response.

            if (solvedPuzzles.Count > 0)
            {
                response.SetSolvedPuzzles(solvedPuzzles);
            }
        }
예제 #2
0
        /// <summary>
        ///   This routine handles sync request aspects that require fetching a list of all the puzzles the team
        ///   has solved.
        /// </summary>
        private async Task HandleSyncAspectsRequiringListOfSolvedPuzzles(DecodedSyncRequest request, SyncResponse response,
                                                                         string groupExcludedFromSolveCount, int teamId, int eventId)
        {
            // If the requester isn't asking for pieces (by setting MinSolveCount to null), and isn't asking about
            // whether any puzzle IDs are solved, we can save time by not querying the list of solved puzzles.

            if (request.MinSolveCount == null && (request.QueryPuzzleIds == null || request.QueryPuzzleIds.Count == 0))
            {
                return;
            }

            // If the request is asking which of the puzzle IDs in request.QueryPuzzleIds has been
            // solved, create a HashSet so that we can quickly look up if an ID is in that list.

            HashSet <int> queryPuzzleIdSet = null;

            if (request.QueryPuzzleIds != null)
            {
                queryPuzzleIdSet = new HashSet <int>();
                foreach (var queryPuzzleId in request.QueryPuzzleIds)
                {
                    queryPuzzleIdSet.Add(queryPuzzleId);
                }
            }

            // Get a list of all the puzzles this team has solved from this event.

            List <Puzzle> solves = await(from state in context.PuzzleStatePerTeam
                                         where state.TeamID == teamId && state.SolvedTime != null && state.Puzzle.Event.ID == eventId
                                         select state.Puzzle).ToListAsync();

            int        maxSolveCount = 0;
            List <int> solvedPuzzles = new List <int>();

            foreach (var solvedPuzzle in solves)
            {
                // If the request is asking whether certain puzzles are solved, check if it's
                // in the set and, if so, put it in the list of solved puzzles to inform the
                // requester of.

                if (queryPuzzleIdSet != null && queryPuzzleIdSet.Contains(solvedPuzzle.ID))
                {
                    solvedPuzzles.Add(solvedPuzzle.ID);
                }

                // When counting solves, only count puzzles if they're not in the group that doesn't
                // count toward the solve count, and only if they're worth at least 10 points.

                if (groupExcludedFromSolveCount == null || solvedPuzzle.Group != groupExcludedFromSolveCount)
                {
                    if (solvedPuzzle.SolveValue >= 10)
                    {
                        maxSolveCount += 1;
                    }
                }

                // If the user solved a cheat code, treat it as a solve count of 1000.

                if (solvedPuzzle.IsCheatCode)
                {
                    maxSolveCount += 1000;
                }
            }

            // If the requester is asking for puzzle pieces (by setting request.MinSolveCount != null)
            // and if there are pieces of the puzzle that the requester has now earned but hasn't
            // yet received, because the maximum solve count they've earned is at least as high
            // as the minimum solve count the requester is asking for, then return those pieces.
            // Note that request.MinSolveCount is the minimum solve count of tokens the requester
            // *hasn't* seen yet.

            if (request.MinSolveCount != null && maxSolveCount >= request.MinSolveCount)
            {
                List <Piece> pieces = await(from piece in context.Pieces
                                            where piece.ProgressLevel >= request.MinSolveCount && piece.ProgressLevel <= maxSolveCount
                                            select piece).ToListAsync();
                response.SetMinAndMaxSolveCountAndPieces(request.MinSolveCount.Value, maxSolveCount, pieces);
            }

            // If we found some solved puzzles in request.QueryPuzzleIds, return those in the
            // response.

            if (solvedPuzzles.Count > 0)
            {
                response.SetSolvedPuzzles(solvedPuzzles);
            }
        }