From: Skullheadx Date: Mon, 8 Jun 2026 19:20:43 +0000 (-0400) Subject: backend for roll dice and login X-Git-Url: http://git.skullheadx.com/nixos/static/gitweb.js?a=commitdiff_plain;h=9278f0b216f4a0743274bb2c797205cc730597fe;p=monopoly-web.git backend for roll dice and login --- diff --git a/game/game.go b/game/game.go index 1da75b3..50a6220 100644 --- a/game/game.go +++ b/game/game.go @@ -31,6 +31,9 @@ type MonopolyServer struct { randSeed *rand.PCG } +// uuid to username +var Users map[string]string + func NewMonopolyServer() *MonopolyServer { ms := &MonopolyServer{ subscriberMessageBuffer: 16, @@ -41,8 +44,10 @@ func NewMonopolyServer() *MonopolyServer { randSeed: rand.NewPCG(20, 26), } ms.serveMux.Handle("/", http.FileServer(http.Dir("../public/"))) + ms.serveMux.HandleFunc("/login", ms.loginHandler) ms.serveMux.HandleFunc("/subscribe", ms.subscribeHandler) - ms.serveMux.HandleFunc("/publish", ms.publishHandler) + ms.serveMux.HandleFunc("/start", ms.startHandler) + ms.serveMux.HandleFunc("/roll", ms.rollHandler) return ms } @@ -72,24 +77,90 @@ func (ms *MonopolyServer) subscribeHandler(w http.ResponseWriter, r *http.Reques } } -func (ms *MonopolyServer) publishHandler(w http.ResponseWriter, r *http.Request) { +func (ms *MonopolyServer) loginHandler(w http.ResponseWriter, r *http.Request) { if r.Method != "POST" { http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed) return } body := http.MaxBytesReader(w, r.Body, 8192) - msg, err := io.ReadAll(body) + username, err := io.ReadAll(body) if err != nil { http.Error(w, http.StatusText(http.StatusRequestEntityTooLarge), http.StatusRequestEntityTooLarge) return } + userUUID := uuid.NewString() + + Users[userUUID] = string(username) + + http.SetCookie(w, &http.Cookie{ + Name: "user", + Value: userUUID, + Path: "/", + Domain: "", + MaxAge: int(7 * 24 * time.Hour / time.Second), + HttpOnly: true, + Secure: true, + SameSite: http.SameSiteLaxMode, + }) + w.WriteHeader(http.StatusOK) +} + +func (ms *MonopolyServer) startHandler(w http.ResponseWriter, r *http.Request) { + if r.Method != "POST" { + http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed) + return + } + + ms.start() + + w.WriteHeader(http.StatusAccepted) +} + +func (ms *MonopolyServer) rollHandler(w http.ResponseWriter, r *http.Request) { + if r.Method != "POST" { + http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed) + return + } + + cookie, err := r.Cookie("user") + if err != nil { + if err == http.ErrNoCookie { + http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) + } + + http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) + } - ms.publish(msg) + userUUID := cookie.Value + + if ms.gameCtx == nil { + http.Error(w, "Game has not started yet", http.StatusConflict) + } + if !ms.gameCtx.ValidateCanRoll(userUUID) { + http.Error(w, "Not your turn", http.StatusForbidden) + } + ms.roll() w.WriteHeader(http.StatusAccepted) } +func (ms *MonopolyServer) roll() { + ms.gameCtx.RollDice() + ms.gameCtx.ProcessMovement() +} + func (ms *MonopolyServer) subscribe(w http.ResponseWriter, r *http.Request) error { + cookie, err := r.Cookie("user") + if err != nil { + if err == http.ErrNoCookie { + http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) + } + + http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) + } + + userUUID := cookie.Value + var mu sync.Mutex var c *websocket.Conn var closed bool @@ -105,7 +176,7 @@ func (ms *MonopolyServer) subscribe(w http.ResponseWriter, r *http.Request) erro } }, } - ms.addSubscriber(s, uuid.NewString()) + ms.addSubscriber(s, userUUID) defer ms.deleteSubscriber(s) c2, err := websocket.Accept(w, r, nil) @@ -137,15 +208,15 @@ func (ms *MonopolyServer) subscribe(w http.ResponseWriter, r *http.Request) erro } } -func (ms *MonopolyServer) startGame() { +func (ms *MonopolyServer) start() { ms.subscribersMu.Lock() defer ms.subscribersMu.Unlock() ms.publishLimiter.Wait(context.Background()) var players []Player - for _, uuid := range ms.subscribers { - players = append(players, InitPlayer(uuid)) + for _, userUUID := range ms.subscribers { + players = append(players, InitPlayer(userUUID)) } ms.gameCtxMu.Lock() @@ -163,25 +234,25 @@ func (ms *MonopolyServer) startGame() { } -func (ms *MonopolyServer) publish(msg []byte) { - ms.subscribersMu.Lock() - defer ms.subscribersMu.Unlock() - - ms.publishLimiter.Wait(context.Background()) - - for s := range ms.subscribers { - select { - case s.msgs <- msg: - default: - go s.closeSlow() - } - } - -} - -func (ms *MonopolyServer) addSubscriber(s *subscriber, uuid string) { +// func (ms *MonopolyServer) publish(msg []byte) { +// ms.subscribersMu.Lock() +// defer ms.subscribersMu.Unlock() +// +// ms.publishLimiter.Wait(context.Background()) +// +// for s := range ms.subscribers { +// select { +// case s.msgs <- msg: +// default: +// go s.closeSlow() +// } +// } +// +// } + +func (ms *MonopolyServer) addSubscriber(s *subscriber, userUUID string) { ms.subscribersMu.Lock() - ms.subscribers[s] = uuid + ms.subscribers[s] = userUUID ms.subscribersMu.Unlock() } @@ -271,9 +342,9 @@ func InitCtx(randSeed rand.Source, players []Player) *Context { } } -func InitPlayer(uuid string) Player { +func InitPlayer(userUUID string) Player { return Player{ - UUID: uuid, + userUUID: userUUID, Money: StartingMoney, CurrentSpaceID: SpecialSpaces.Go, GetOutOfJailCards: StartingGetOutOfJailFreeCards, @@ -293,30 +364,30 @@ func (ctx *Context) GetCurrentTurnPlayer() *Player { return &ctx.Players.Alive[ctx.Turn.Current.Index()] } -func (ctx *Context) ValidateIsTurn(UUID string) bool { - if ctx.GetCurrentTurnPlayer().UUID == UUID { +func (ctx *Context) ValidateIsTurn(userUUID string) bool { + if ctx.GetCurrentTurnPlayer().userUUID == userUUID { return true } return false } -func (ctx *Context) ValidateCanRoll(UUID string) bool { - if ctx.ValidateIsTurn(UUID) && ctx.Turn.DiceRollsRemaining > 0 { +func (ctx *Context) ValidateCanRoll(userUUID string) bool { + if ctx.ValidateIsTurn(userUUID) && ctx.Turn.DiceRollsRemaining > 0 { return true } return false } -func (ctx *Context) ValidateCanEndTurn(UUID string) bool { - if !(ctx.ValidateIsTurn(UUID) || ctx.Turn.DiceRollsRemaining > 0 || ctx.GetCurrentTurnPlayer().Money < 0) { +func (ctx *Context) ValidateCanEndTurn(userUUID string) bool { + if !(ctx.ValidateIsTurn(userUUID) || ctx.Turn.DiceRollsRemaining > 0 || ctx.GetCurrentTurnPlayer().Money < 0) { return true } return false } -func (ctx *Context) ValidateCanExitJail(UUID string) bool { +func (ctx *Context) ValidateCanExitJail(userUUD string) bool { for _, iJV := range ctx.Visitors.InJail { - if ctx.Players.Alive[iJV.visitorID.Index()].UUID == UUID { + if ctx.Players.Alive[iJV.visitorID.Index()].userUUID == userUUD { return true } } diff --git a/game/types.go b/game/types.go index 20c2cf0..dfb38c5 100644 --- a/game/types.go +++ b/game/types.go @@ -5,7 +5,7 @@ import ( ) type Player struct { - UUID string + userUUID string Money int32 CurrentSpaceID SpaceID GetOutOfJailCards int32 diff --git a/main.go b/main.go index 42fb8d6..f51c0dd 100644 --- a/main.go +++ b/main.go @@ -1,9 +1,7 @@ package main import ( - "io" "log" - "math/rand/v2" "monopoly-web/game" "net/http" @@ -57,12 +55,6 @@ func run() error { return s.Shutdown(ctx) } -// func (r *Room) rollDiceHandler(w http.ResponseWriter, req *http.Request) { -// if r.gameCtx.ValidateCanRoll(UUID) { -// r.gameCtx.RollDice() -// r.gameCtx.ProcessMovement() -// } -// } // // func (r *Room) endTurnHandler(w http.ResponseWriter, req *http.Request) { // if r.gameCtx.ValidateCanEndTurn(UUID) {