public async Task <Dictionary <string, object> > GetSyncResponse(int eventId, int teamId, int puzzleId, List <int> query_puzzle_ids, int?min_solve_count, string annotations, string last_sync_time) { SyncResponse response = new SyncResponse(); // Get information for the puzzle that's being sync'ed. Puzzle thisPuzzle = await context.Puzzles.Where(puz => puz.ID == puzzleId).FirstOrDefaultAsync(); if (thisPuzzle == null) { response.AddError("Could not find the puzzle you tried to sync."); return(response.GetResult()); } // Check to make sure that they're not trying to sync a puzzle and event that don't go together. // That could be a security issue, allowing them to unlock pieces for a puzzle using the progress // they made in a whole different event! if (thisPuzzle.Event.ID != eventId) { response.AddError("That puzzle doesn't belong to that event."); return(response.GetResult()); } // Get the site version for this puzzle, so that if it's changed since the last time the // requester sync'ed, the requester will know to reload itself. response.SetSiteVersion(GetSiteVersion(thisPuzzle)); // Decode the request. If there are any errors, return an error response. DecodedSyncRequest request = new DecodedSyncRequest(query_puzzle_ids, min_solve_count, annotations, last_sync_time, thisPuzzle.MaxAnnotationKey, ref response); // Do any processing that requires fetching the list of all puzzles this team has // solved. Pass thisPuzzle.Group as the groupExcludedFromSolveCount parameter so that, // when counting solves, we don't count solves in the same group as this puzzle as part // of the solve count. await HandleSyncAspectsRequiringListOfSolvedPuzzles(request, response, thisPuzzle.Group, teamId, eventId); // Store any annotations the requester provided await StoreAnnotations(request, response, thisPuzzle.ID, teamId); // Fetch and return any annotations that the requester may not have yet await GetAnnotationsRequesterLacks(request, response, thisPuzzle.ID, teamId); return(response.GetResult()); }