package handlers import ( "context" "errors" "golias/models" "html/template" "net/http" ) func HandleCreateRoom(w http.ResponseWriter, r *http.Request) { // parse payload payload := &models.RoomReq{ RoomPass: r.PostFormValue("room_pass"), RoomName: r.PostFormValue("room_name"), } // create a room room, err := createRoom(r.Context(), payload) if err != nil { msg := "failed to create a room" log.Error(msg, "error", err) abortWithError(w, msg) return } ctx := context.WithValue(r.Context(), "current_room", room.ID) fi, err := getFullInfoByCtx(ctx) if err != nil { msg := "failed to get full info from ctx" log.Error(msg, "error", err) abortWithError(w, msg) return } fi.State.RoomID = room.ID fi.Room = room fi.Room.IsPublic = true // hardcode for local test; move to form if err := saveFullInfo(fi); err != nil { msg := "failed to set current room to session" log.Error(msg, "error", err) abortWithError(w, msg) return } notify(models.NotifyRoomListUpdate, "") tmpl, err := template.ParseGlob("components/*.html") if err != nil { abortWithError(w, err.Error()) return } tmpl.ExecuteTemplate(w, "base", fi) } func HandleRoomEnter(w http.ResponseWriter, r *http.Request) { // parse payload roomID := r.URL.Query().Get("id") if roomID == "" { // error return } // create a room room, err := getRoomByID(roomID) if err != nil { msg := "failed to find the room" log.Error(msg, "error", err, "room_id", roomID) abortWithError(w, msg) return } ctx := context.WithValue(r.Context(), "current_room", room.ID) ctx, err = updateRoomInSession(ctx, room.ID) if err != nil { msg := "failed to set current room to session" log.Error(msg, "error", err) abortWithError(w, msg) return } state, err := getStateByCtx(ctx) if err != nil { log.Error("failed to get state", "error", err) abortWithError(w, err.Error()) return } state.RoomID = room.ID // update state if err := saveStateByCtx(ctx, state); err != nil { log.Error("failed to update state", "error", err) abortWithError(w, err.Error()) return } // send msg of created room // h.Broker.Notifier <- broker.NotificationEvent{ // EventName: models.MsgRoomListUpdate, // Payload: fmt.Sprintf("%s created a room named %s", r.CreatorName, r.RoomName), // } // return html tmpl, err := template.ParseGlob("components/*.html") if err != nil { abortWithError(w, err.Error()) return } tmpl.ExecuteTemplate(w, "base", room) } func HandleJoinTeam(w http.ResponseWriter, r *http.Request) { r.ParseForm() team := r.PostFormValue("team") role := r.PostFormValue("role") if team == "" || role == "" { msg := "missing team or role" log.Error(msg) abortWithError(w, msg) return } // get username fi, err := getFullInfoByCtx(r.Context()) if err != nil { abortWithError(w, err.Error()) return } if fi.Room.IsRunning && role == "mime" { err = errors.New("cannot join as mime when game is running") abortWithError(w, err.Error()) return } fi, err = joinTeam(r.Context(), role, team) if err != nil { abortWithError(w, err.Error()) return } // reveal all cards if role == "mime" { fi.Room.RevealAllCards() } // return html tmpl, err := template.ParseGlob("components/*.html") if err != nil { abortWithError(w, err.Error()) return } notify(models.NotifyRoomUpdatePrefix+fi.Room.ID, "") tmpl.ExecuteTemplate(w, "base", fi) } func HandleEndTurn(w http.ResponseWriter, r *http.Request) { // get username fi, err := getFullInfoByCtx(r.Context()) if err != nil { abortWithError(w, err.Error()) return } // check if one who pressed it is from the team who has the turn if fi.Room.TeamTurn != string(fi.State.Team) { err = errors.New("unexpected team turn:" + fi.Room.TeamTurn) abortWithError(w, err.Error()) return } fi.Room.ChangeTurn() if err := saveFullInfo(fi); err != nil { abortWithError(w, err.Error()) return } // return html tmpl, err := template.ParseGlob("components/*.html") if err != nil { abortWithError(w, err.Error()) return } notify(models.NotifyRoomUpdatePrefix+fi.Room.ID, "") tmpl.ExecuteTemplate(w, "base", fi) } func HandleStartGame(w http.ResponseWriter, r *http.Request) { fi, err := getFullInfoByCtx(r.Context()) if err != nil { abortWithError(w, err.Error()) return } // TODO: check if enough players; also button should be hidden if already running fi.Room.IsRunning = true fi.Room.IsOver = false fi.Room.TeamTurn = "blue" fi.Room.LoadTestCards() fi.Room.UpdateCounter() fi.Room.TeamWon = "" if err := saveFullInfo(fi); err != nil { abortWithError(w, err.Error()) return } // reveal all cards if fi.State.Role == "mime" { fi.Room.RevealAllCards() } // return html tmpl, err := template.ParseGlob("components/*.html") if err != nil { abortWithError(w, err.Error()) return } // to update only the room that should be updated notify(models.NotifyRoomUpdatePrefix+fi.Room.ID, "") tmpl.ExecuteTemplate(w, "room", fi) } func HandleJoinRoom(w http.ResponseWriter, r *http.Request) { roomID := r.URL.Query().Get("id") room, err := getRoomByID(roomID) if err != nil { abortWithError(w, err.Error()) return } fi, err := getFullInfoByCtx(r.Context()) if err != nil { abortWithError(w, err.Error()) return } room.PlayerList = append(room.PlayerList, fi.State.Username) fi.State.RoomID = room.ID fi.Room = room fi.List = nil if err := saveFullInfo(fi); err != nil { abortWithError(w, err.Error()) return } // return html tmpl, err := template.ParseGlob("components/*.html") if err != nil { abortWithError(w, err.Error()) return } tmpl.ExecuteTemplate(w, "room", fi) } func HandleGiveClue(w http.ResponseWriter, r *http.Request) { if err := r.ParseForm(); err != nil { abortWithError(w, err.Error()) return } clue := r.PostFormValue("clue") num := r.PostFormValue("number") fi, err := getFullInfoByCtx(r.Context()) if err != nil { abortWithError(w, err.Error()) return } action := models.Action{ Actor: fi.State.Username, ActorColor: string(fi.State.Team), WordColor: string(fi.State.Team), Action: "gave clue", Word: clue, Number: num, } fi.Room.ActionHistory = append(fi.Room.ActionHistory, action) fi.Room.MimeDone = true notify(models.NotifyBacklogPrefix+fi.Room.ID, clue+num) if err := saveFullInfo(fi); err != nil { abortWithError(w, err.Error()) return } }