diff --git a/cmd/mothd/server.go b/cmd/mothd/server.go index 061f45a..1a569da 100644 --- a/cmd/mothd/server.go +++ b/cmd/mothd/server.go @@ -45,6 +45,7 @@ type StateProvider interface { PointsLog() []*Award TeamName(teamId string) (string, error) SetTeamName(teamId, teamName string) error + AwardPoints(teamId string, cat string, points int) error Component } @@ -82,19 +83,22 @@ type MothRequestHandler struct { } func (mh *MothRequestHandler) PuzzlesOpen(cat string, points int, path string) (ReadSeekCloser, time.Time, error) { - // XXX: Make sure this puzzle is unlocked - return mh.Puzzles.Open(cat, points, path) + export := mh.ExportAllState() + fmt.Println(export.Puzzles) + for _, p := range export.Puzzles[cat] { + fmt.Println(points, p) + if p == points { + return mh.Puzzles.Open(cat, points, path) + } + } + + return nil, time.Time{}, fmt.Errorf("Puzzle locked") } func (mh *MothRequestHandler) ThemeOpen(path string) (ReadSeekCloser, time.Time, error) { return mh.Theme.Open(path) } -func (mh *MothRequestHandler) xxxTeamName() string { - teamName, _ := mh.State.TeamName(mh.teamId) - return teamName -} - func (mh *MothRequestHandler) Register(teamName string) error { // XXX: Should we just return success if the team is already registered? // XXX: Should this function be renamed to Login? @@ -105,10 +109,18 @@ func (mh *MothRequestHandler) Register(teamName string) error { } func (mh *MothRequestHandler) CheckAnswer(cat string, points int, answer string) error { - return mh.Puzzles.CheckAnswer(cat, points, answer) + if err := mh.Puzzles.CheckAnswer(cat, points, answer); err != nil { + return err + } + + if err := mh.State.AwardPoints(mh.teamId, cat, points); err != nil { + return err + } + + return nil } -func (mh *MothRequestHandler) ExportState() *StateExport { +func (mh *MothRequestHandler) ExportAllState() *StateExport { export := StateExport{} teamName, _ := mh.State.TeamName(mh.teamId) @@ -142,8 +154,6 @@ func (mh *MothRequestHandler) ExportState() *StateExport { export.Puzzles = make(map[string][]int) - - //XXX: move to brains.go for _, category := range mh.Puzzles.Inventory() { // Append sentry (end of puzzles) allPuzzles := append(category.Puzzles, 0) @@ -161,4 +171,18 @@ func (mh *MothRequestHandler) ExportState() *StateExport { } return &export -} \ No newline at end of file +} + +func (mh *MothRequestHandler) ExportState() *StateExport { + export := mh.ExportAllState() + + // We don't give this out to just anybody, + // because back when we did, + // we got a bad reputation on some secretive blacklist, + // and now the Navy can't register for events. + if export.TeamNames["self"] == "" { + export.Puzzles = map[string][]int{} + } + + return export +} diff --git a/cmd/mothd/state.go b/cmd/mothd/state.go index 7055ba0..a7bebdc 100644 --- a/cmd/mothd/state.go +++ b/cmd/mothd/state.go @@ -82,6 +82,7 @@ func (s *State) UpdateEnabled() { // Returns team name given a team ID. func (s *State) TeamName(teamId string) (string, error) { + // XXX: directory traversal teamFile := filepath.Join("teams", teamId) teamNameBytes, err := afero.ReadFile(s, teamFile) teamName := strings.TrimSpace(string(teamNameBytes)) diff --git a/theme/moth.js b/theme/moth.js index c773f21..4d656ef 100644 --- a/theme/moth.js +++ b/theme/moth.js @@ -144,7 +144,6 @@ function showPuzzles() { document.getElementById("login").style.display = "none" document.getElementById("puzzles").appendChild(spinner) - heartbeat() } async function fetchAll(puzzles) { @@ -191,6 +190,7 @@ function login(e) { sessionStorage.id = teamId sessionStorage.pid = participantId showPuzzles() + heartbeat() } else { toast(obj.data.description) } @@ -211,10 +211,6 @@ function login(e) { } function init() { - // Already signed in? - if (sessionStorage.id) { - showPuzzles() - } heartbeat() setInterval(e => heartbeat(), 40000)