Пример #1
0
func advanceState(c appengine.Context, h *hunt.Hunt, currentState int) {
	err := datastore.RunInTransaction(c, func(c appengine.Context) error {
		h := hunt.ID(c, h.ID)
		if h == nil || h.State != currentState {
			// TODO(dneal): Return a real error.
			return nil
		}
		switch h.State {
		case hunt.StatePreLaunch:
			teams := team.All(c, h)
			nonPaperOrder := rand.Perm(len(teams))
			paperOrder := rand.Perm(len(teams))
			for i := range teams {
				puzzle.New(c, h, teams[i], nonPaperOrder[i]+1, false)
				puzzle.New(c, h, teams[i], len(teams)+paperOrder[i]+1, true)
			}
		case hunt.StateSurveying:
			tally.BuildFinalTally(c, h)
		}
		h.State++
		h.Write(c)
		broadcast.SendRefresh(c, h)
		return nil
	}, nil)
	if err != nil {
		c.Errorf("Error: %v", err)
	}
}
Пример #2
0
func AdminHandler(w http.ResponseWriter, r *http.Request) {
	path := strings.Split(r.URL.Path, "/")
	if len(path) != 4 {
		http.Error(w, "Not found", 404)
		return
	}

	c := appengine.NewContext(r)

	w.Header().Set("Content-Type", "application/json")
	enc := json.NewEncoder(w)

	var h *hunt.Hunt
	if id := r.FormValue("hunt_id"); id != "" {
		h = hunt.ID(c, id)
	}

	var t *team.Team
	if id := r.FormValue("team_id"); h != nil && id != "" {
		t = team.ID(c, id)
	}

	var p *puzzle.Puzzle
	if id := r.FormValue("puzzleid"); h != nil && id != "" {
		p = puzzle.ID(c, id)
	}

	var err error
	switch path[3] {
	case "hunts":
		hunts := hunt.All(c)
		err = enc.Encode(hunts)
	case "addhunt":
		hunt.New(c, r.FormValue("name"), r.FormValue("path"))
	case "deletehunt":
		h.Delete(c)
	case "updateingredients":
		if h != nil && h.State < hunt.StateEarlyAccess {
			h.Ingredients = r.FormValue("ingredients")
			h.Write(c)
			broadcast.SendIngredientsUpdate(c, h)
		}
	case "teams":
		if h != nil {
			err = enc.Encode(TeamsInfo{
				Editable: true,
				Teams:    team.All(c, h),
			})
		}
	case "addteam":
		if h != nil && h.State < hunt.StateEarlyAccess {
			team.New(c, h, r.FormValue("name"), r.FormValue("password"), r.FormValue("novice") == "true")
			broadcast.SendTeamsUpdate(c, h)
		}
	case "deleteteam":
		if t != nil && h.State < hunt.StateEarlyAccess {
			t.Delete(c)
			broadcast.SendTeamsUpdate(c, h)
		}
	case "state":
		if h != nil {
			err = enc.Encode(h.State)
		}
	case "advancestate":
		if h != nil {
			currentState, err := strconv.Atoi(r.FormValue("currentstate"))
			if err == nil {
				advanceState(c, h, currentState)
				broadcast.SendRefresh(c, h)
			}
		}
	case "puzzles":
		if h != nil {
			puzzles := puzzle.All(c, h, nil)
			var admin []*puzzle.AdminPuzzle
			for _, p := range puzzles {
				admin = append(admin, p.Admin(c))
			}
			err = enc.Encode(PuzzleInfo{false, admin})
		}
	case "ingredients":
		err = enc.Encode(IngredientInfo{
			Display:     true,
			Editable:    true,
			Ingredients: h.Ingredients,
		})
	case "leaderboard":
		if h.State >= hunt.StateSolving {
			var l LeaderboardInfo
			fillLeaderboardInfo(c, h, nil, &l)
			err = enc.Encode(l)
		}
	case "leaderboardupdate":
		if p != nil {
			err = enc.Encode(p.UpdatableProgressInfo(c, h, nil))
		}
	case "channel":
		if h != nil {
			err = enc.Encode(broadcast.GetToken(c, h, nil, true))
		}
	case "console":
		if h != nil {
			err = enc.Encode(adminconsole.Logs(c, h))
		}
	case "adminsurvey":
		if h != nil && h.State == hunt.StateSurveying {
			var info AdminSurveyInfo
			info.Display = true
			for _, t := range team.All(c, h) {
				info.Teams = append(info.Teams, TeamSurveyInfo{t.Name, t.Survey != ""})
			}
			err = enc.Encode(info)
		}
	case "finalscores":
		finalScores := tally.Get(c, h, true)
		err = enc.Encode(finalScores)
	}

	if err != nil {
		c.Errorf("Error: %v", err)
		return
	}
}