randSeed *rand.PCG
}
+// uuid to username
+var Users map[string]string
+
func NewMonopolyServer() *MonopolyServer {
ms := &MonopolyServer{
subscriberMessageBuffer: 16,
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
}
}
}
-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
}
},
}
- ms.addSubscriber(s, uuid.NewString())
+ ms.addSubscriber(s, userUUID)
defer ms.deleteSubscriber(s)
c2, err := websocket.Accept(w, r, nil)
}
}
-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()
}
-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()
}
}
}
-func InitPlayer(uuid string) Player {
+func InitPlayer(userUUID string) Player {
return Player{
- UUID: uuid,
+ userUUID: userUUID,
Money: StartingMoney,
CurrentSpaceID: SpecialSpaces.Go,
GetOutOfJailCards: StartingGetOutOfJailFreeCards,
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
}
}