diff --git a/components/index.html b/components/index.html index 40a60b3..4b0f94a 100644 --- a/components/index.html +++ b/components/index.html @@ -10,10 +10,13 @@
+
+ {{template "roomlist" .List}} +
{{else}} - +
{{template "room" .}}
-{{end}} + {{end}} {{end}} diff --git a/components/roomlist.html b/components/roomlist.html new file mode 100644 index 0000000..8cc4ca4 --- /dev/null +++ b/components/roomlist.html @@ -0,0 +1,27 @@ +{{define "roomlist"}} +
+{{range .}} +

+ {{.ID}} +

+
+
+
+
+ Created {{.CreatedAt.Format "2 Jan 2006 15:04"}} by + {{.CreatorName}} +
+
+ + {{if .IsRunning}}Game Active{{else}}Waiting Room{{end}} + + + + +
+
+
+
+{{end}} +
+{{end}} diff --git a/handlers/actions.go b/handlers/actions.go index 24a502e..a3342e0 100644 --- a/handlers/actions.go +++ b/handlers/actions.go @@ -6,6 +6,7 @@ import ( "errors" "golias/models" "golias/utils" + "strings" ) func createRoom(ctx context.Context, req *models.RoomReq) (*models.Room, error) { @@ -22,11 +23,13 @@ func createRoom(ctx context.Context, req *models.RoomReq) (*models.Room, error) } func saveRoom(room *models.Room) error { + key := models.CacheRoomPrefix + room.ID data, err := json.Marshal(room) if err != nil { return err } memcache.Set(models.CacheRoomPrefix+room.ID, data) + log.Debug("saved room", "room", room, "key", key) return nil } @@ -208,3 +211,24 @@ func joinTeam(ctx context.Context, role, team string) (*models.FullInfo, error) } return fi, nil } + +// get all rooms +func listPublicRooms() []*models.Room { + cacheMap := memcache.GetAll() + publicRooms := []*models.Room{} + // no way to know if room is public until unmarshal -_-; + for key, value := range cacheMap { + if strings.HasPrefix(key, models.CacheRoomPrefix) { + room := &models.Room{} + if err := json.Unmarshal(value, &room); err != nil { + log.Warn("failed to unmarshal room", "error", err) + continue + } + log.Debug("consider room for list", "room", room, "key", key) + if room.IsPublic { + publicRooms = append(publicRooms, room) + } + } + } + return publicRooms +} diff --git a/handlers/auth.go b/handlers/auth.go index 8726b1d..7482944 100644 --- a/handlers/auth.go +++ b/handlers/auth.go @@ -17,7 +17,7 @@ import ( ) func abortWithError(w http.ResponseWriter, msg string) { - w.WriteHeader(500) + w.WriteHeader(200) // must be 200 for htmx to replace components tmpl := template.Must(template.ParseGlob("components/*.html")) tmpl.ExecuteTemplate(w, "error", msg) } @@ -109,9 +109,9 @@ func makeCookie(username string, remote string) (*http.Cookie, error) { cookieValue := base64.URLEncoding.EncodeToString([]byte( string(signature) + sessionToken)) cookie := &http.Cookie{ - Name: cookieName, - Value: cookieValue, - // Secure: true, + Name: cookieName, + Value: cookieValue, + Secure: true, HttpOnly: true, SameSite: http.SameSiteNoneMode, Domain: cfg.ServerConfig.Host, diff --git a/handlers/elements.go b/handlers/elements.go index 53473c2..8d96225 100644 --- a/handlers/elements.go +++ b/handlers/elements.go @@ -1,6 +1,7 @@ package handlers import ( + "errors" "golias/models" "html/template" "net/http" @@ -45,6 +46,12 @@ func HandleShowColor(w http.ResponseWriter, r *http.Request) { abortWithError(w, err.Error()) return } + // TODO: whos move it is? + if state.Role != "guesser" { + err = errors.New("need to guesser to open the card") + abortWithError(w, err.Error()) + return + } log.Debug("got state", "state", state) // TODO: update room score color, exists := roundWords[word] diff --git a/handlers/game.go b/handlers/game.go index cf0a323..526dcdd 100644 --- a/handlers/game.go +++ b/handlers/game.go @@ -8,6 +8,16 @@ import ( "net/http" ) +// func HandleRoomList(w http.ResponseWriter, r *http.Request) { +// pubRooms := listPublicRooms() +// tmpl, err := template.ParseGlob("components/*.html") +// if err != nil { +// abortWithError(w, err.Error()) +// return +// } +// tmpl.ExecuteTemplate(w, "base", pubRooms) +// } + func HandleCreateRoom(w http.ResponseWriter, r *http.Request) { // parse payload payload := &models.RoomReq{ @@ -32,6 +42,7 @@ func HandleCreateRoom(w http.ResponseWriter, r *http.Request) { } 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) @@ -103,9 +114,6 @@ func HandleRoomEnter(w http.ResponseWriter, r *http.Request) { } func HandleJoinTeam(w http.ResponseWriter, r *http.Request) { - // parse payload - // team := r.URL.Query().Get("team") - // role := r.URL.Query().Get("role") r.ParseForm() team := r.PostFormValue("team") role := r.PostFormValue("role") @@ -121,11 +129,20 @@ func HandleJoinTeam(w http.ResponseWriter, r *http.Request) { 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 { @@ -177,6 +194,39 @@ func HandleStartGame(w http.ResponseWriter, r *http.Request) { 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 + } + 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 { diff --git a/handlers/handlers.go b/handlers/handlers.go index 23e3217..4fcc60b 100644 --- a/handlers/handlers.go +++ b/handlers/handlers.go @@ -63,6 +63,15 @@ func HandleHome(w http.ResponseWriter, r *http.Request) { return } fi, _ := getFullInfoByCtx(r.Context()) + if fi != nil && fi.Room != nil && fi.State != nil { + if fi.State.Role == "mime" { + fi.Room.RevealAllCards() + } + } + if fi != nil && fi.Room == nil { + log.Debug("loading list") + fi.List = listPublicRooms() + } log.Debug("data debug", "fi", fi) if err := tmpl.ExecuteTemplate(w, "base", fi); err != nil { log.Error("failed to exec templ;", "error", err, "templ", "base") diff --git a/main.go b/main.go index 0468bbc..1dd8529 100644 --- a/main.go +++ b/main.go @@ -27,6 +27,8 @@ func ListenToRequests(port string) error { mux.HandleFunc("GET /end-turn", handlers.HandleEndTurn) mux.HandleFunc("POST /room-create", handlers.HandleCreateRoom) mux.HandleFunc("GET /start-game", handlers.HandleStartGame) + mux.HandleFunc("GET /room-join", handlers.HandleJoinRoom) + // mux.HandleFunc("GET /roomlist", handlers.HandleRoomList) //elements mux.HandleFunc("GET /room/createform", handlers.HandleShowCreateForm) mux.HandleFunc("GET /room/hideform", handlers.HandleHideCreateForm) diff --git a/models/main.go b/models/main.go index b3d8941..fd5712a 100644 --- a/models/main.go +++ b/models/main.go @@ -52,6 +52,7 @@ type Room struct { BlueCounter uint8 RedCounter uint8 RedTurn bool // false is blue turn + IsPublic bool // GameSettings *GameSettings `json:"settings"` IsRunning bool `json:"is_running"` Language string `json:"language" example:"en" form:"language"` @@ -102,6 +103,12 @@ func (r *Room) ChangeTurn() { } } +func (r *Room) RevealAllCards() { + for i := range r.Cards { + r.Cards[i].Revealed = true + } +} + type WordCard struct { Word string Color WordColor @@ -142,4 +149,5 @@ func (rr *RoomReq) CreateRoom(creator string) *Room { type FullInfo struct { State *UserState Room *Room + List []*Room } diff --git a/todos.md b/todos.md index db60698..3123ed1 100644 --- a/todos.md +++ b/todos.md @@ -17,4 +17,5 @@ ### issues -- new client login rewrites room creator (test room issue); +- after the game started (isrunning) players should be able join guessers, but not switch team, or join as a mime; +- do not let wrong team press buttons;