import (
"context"
"errors"
+ "fmt"
"github.com/coder/websocket"
"github.com/google/uuid"
"golang.org/x/time/rate"
subscribersMu sync.Mutex
subscribers map[*subscriber]string
+ // uuid to username
+ users map[string]string
+
gameCtxMu sync.Mutex
gameCtx *Context
randSeed *rand.PCG
}
-// uuid to username
-var Users map[string]string
-
func NewMonopolyServer() *MonopolyServer {
ms := &MonopolyServer{
subscriberMessageBuffer: 16,
logf: log.Printf,
subscribers: make(map[*subscriber]string),
+ users: make(map[string]string),
publishLimiter: rate.NewLimiter(rate.Every(time.Millisecond*100), 8),
gameCtx: nil,
randSeed: rand.NewPCG(20, 26),
}
- ms.serveMux.Handle("/", http.FileServer(http.Dir("../public/")))
+ ms.serveMux.Handle("/", http.FileServer(http.Dir("public/")))
ms.serveMux.HandleFunc("/login", ms.loginHandler)
+ ms.serveMux.HandleFunc("/loggedin", ms.loggedInHandler)
ms.serveMux.HandleFunc("/subscribe", ms.subscribeHandler)
ms.serveMux.HandleFunc("/start", ms.startHandler)
ms.serveMux.HandleFunc("/roll", ms.rollHandler)
}
}
+func (ms *MonopolyServer) loggedInHandler(w http.ResponseWriter, r *http.Request) {
+ if r.Method != "GET" {
+ 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.StatusNotFound), http.StatusNotFound)
+ return
+ }
+
+ http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
+ return
+ }
+
+ userUUID := cookie.Value
+
+ _, ok := ms.users[userUUID]
+ if !ok {
+ http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
+ return
+ }
+
+ w.WriteHeader(http.StatusOK)
+}
+
func (ms *MonopolyServer) loginHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != "POST" {
http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
}
userUUID := uuid.NewString()
- Users[userUUID] = string(username)
+ ms.users[userUUID] = string(username)
http.SetCookie(w, &http.Cookie{
Name: "user",
return
}
+ cookie, err := r.Cookie("user")
+ if err != nil {
+ if err == http.ErrNoCookie {
+ http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
+ return
+ }
+
+ http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
+ return
+ }
+
+ userUUID := cookie.Value
+ _, ok := ms.users[userUUID]
+ if !ok {
+ http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
+ return
+ }
+
ms.start()
w.WriteHeader(http.StatusAccepted)
if err != nil {
if err == http.ErrNoCookie {
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
+ return
}
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
+ return
}
userUUID := cookie.Value
+ _, ok := ms.users[userUUID]
+ if !ok {
+ http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
+ return
+ }
+
if ms.gameCtx == nil {
http.Error(w, "Game has not started yet", http.StatusConflict)
+ return
}
if !ms.gameCtx.ValidateCanRoll(userUUID) {
http.Error(w, "Not your turn", http.StatusForbidden)
+ return
}
ms.roll()
w.WriteHeader(http.StatusOK)
}
func (ms *MonopolyServer) roll() {
+ fmt.Printf("%#v\n", ms.gameCtx)
ms.gameCtx.RollDice()
+ fmt.Printf("%#v\n", ms.gameCtx)
ms.gameCtx.ProcessMovement()
}
if err != nil {
if err == http.ErrNoCookie {
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
+ return err
}
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
+ return err
}
userUUID := cookie.Value
; (() => {
let connected = false
-
function dial() {
const conn = new WebSocket(`ws://${location.host}/subscribe`)
appendGameLog(ev.data)
})
}
- // dial()
+ async function loggedIn() {
+ try {
+ const resp = await fetch('/loggedin', {
+ method: 'GET'
+ })
+ if (resp.status !== 200) {
+ throw new Error(`Unexpected HTTP Status ${resp.status} ${resp.statusText}`)
+ }
+ dial()
+ } catch (err) {
+ console.error(`Login check failed: ${err.message}`)
+ }
+ }
+ loggedIn()
const gameLog = document.getElementById('log')
const loginForm = document.getElementById('login-form')
body: msg,
})
if (resp.status !== 200) {
- throw new Error(`Unexpected HTTP Status ${resp.status} ${resp.statusText}`)
+ throw new Error(`Unexpected HTTP Status ${resp.status} ${resp.statusText} ${resp.message}`)
}
dial()
method: 'POST',
})
if (resp.status !== 202) {
- throw new Error(`Unexpected HTTP Status ${resp.status} ${resp.statusText}`)
+ throw new Error(`Unexpected HTTP Status ${resp.status} ${resp.statusText} ${resp.message}`)
}
} catch (err) {
console.error(`Start failed: ${err.message}`)
method: 'POST',
})
if (resp.status !== 200) {
- throw new Error(`Unexpected HTTP Status ${resp.status} ${resp.statusText}`)
+ throw new Error(`Unexpected HTTP Status ${resp.status} ${resp.statusText} ${resp.message}`)
}
} catch (err) {
console.error(`Start failed: ${err.message}`)