Skip to content

Commit

Permalink
Merge pull request #31 from vituchon/fix-client-registration-system
Browse files Browse the repository at this point in the history
Fix client registration system
  • Loading branch information
vituchon authored Aug 23, 2024
2 parents 3525b71 + f6c4f85 commit c86d297
Show file tree
Hide file tree
Showing 10 changed files with 68 additions and 54 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/vituchon/escobita
go 1.19

require (
github.com/google/uuid v1.6.0
github.com/gorilla/handlers v1.5.1
github.com/gorilla/mux v1.8.0
github.com/gorilla/securecookie v1.1.1
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ=
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4=
github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
Expand Down
21 changes: 11 additions & 10 deletions presentation/web/controllers/clients.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package controllers

import (
"net/http"
"sync"

"math/big"

"github.com/google/uuid"
"github.com/gorilla/sessions"
)

Expand All @@ -13,20 +15,19 @@ func InitSessionStore(key []byte) {
clientSessions = sessions.NewCookieStore(key)
}

var clientSequenceId int = 0
var mutex sync.Mutex

func GetOrCreateClientSession(request *http.Request) (*sessions.Session, error) {
clientSession, err := clientSessions.Get(request, "client_session")
clientSession, err := clientSessions.Get(request, "escoba_client")
if err != nil {
return nil, err
}
if clientSession.IsNew {
mutex.Lock()
defer mutex.Unlock()
nextId := clientSequenceId + 1
clientSession.Values["clientId"] = nextId
clientSequenceId++
uuid := uuid.New()
uuidBytes := uuid[:]
nextId := int(big.NewInt(0).SetBytes(uuidBytes[:8]).Int64())
min := -1000000000
max := 1000000000
scaledNextId := (nextId % (max - min + 1)) + min // los escalo pues los navegadores pueden no soportar números tan grandes y luego hay conflicto a la hora de actualziar el jugador cuando se registra el nombre
clientSession.Values["clientId"] = scaledNextId
}
return clientSession, nil
}
Expand Down
10 changes: 5 additions & 5 deletions presentation/web/controllers/games.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func GetGameById(response http.ResponseWriter, request *http.Request) {
const MAX_GAMES_PER_PLAYER = 1

func CreateGame(response http.ResponseWriter, request *http.Request) {
playerId := services.GetWebPlayerId(request) // will be the game's owner
playerId := services.GetClientId(request) // will be the game's owner
if gamesRepository.GetGamesCreatedCount(playerId) == MAX_GAMES_PER_PLAYER {
msg := fmt.Sprintf("Player(id='%d') has reached the maximum game creation limit: '%v'", playerId, MAX_GAMES_PER_PLAYER)
log.Println(msg)
Expand Down Expand Up @@ -148,7 +148,7 @@ func StartGame(response http.ResponseWriter, request *http.Request) {
return
}

playerId := services.GetWebPlayerId(request)
playerId := services.GetClientId(request)
if game.Owner.Id != playerId {
log.Printf("error while starting game: request doesn't cames from the owner, in cames from %d\n", playerId)
response.WriteHeader(http.StatusBadRequest)
Expand Down Expand Up @@ -176,7 +176,7 @@ func JoinGame(response http.ResponseWriter, request *http.Request) {
return
}

playerId := services.GetWebPlayerId(request)
playerId := services.GetClientId(request)
player, err := playersRepository.GetPlayerById(playerId)
if err != nil {
msg := fmt.Sprintf("error while getting player by id, error was: '%v'\n", player)
Expand Down Expand Up @@ -211,7 +211,7 @@ func QuitGame(response http.ResponseWriter, request *http.Request) {
return
}

playerId := services.GetWebPlayerId(request)
playerId := services.GetClientId(request)
player, err := playersRepository.GetPlayerById(playerId)
if err != nil {
msg := fmt.Sprintf("error while getting player by id, error was: '%v'\n", player)
Expand Down Expand Up @@ -440,7 +440,7 @@ func UnbindClientWebSocketInGame(response http.ResponseWriter, request *http.Req
services.GameWebSockets.UnbindClientWebSocketInGame(conn, request)
response.WriteHeader(http.StatusOK)
} else {
log.Printf("No need to release web socket as it was not adquired (or already released) for client(id='%d')\n", services.GetWebPlayerId(request))
log.Printf("No need to release web socket as it was not adquired (or already released) for client(id='%d')\n", services.GetClientId(request))
response.WriteHeader(http.StatusBadRequest)
}
}
Expand Down
7 changes: 6 additions & 1 deletion presentation/web/controllers/players.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package controllers
import (
"log"
"net/http"
"sync"

"github.com/vituchon/escobita/model"

Expand All @@ -24,9 +25,13 @@ func GetPlayers(response http.ResponseWriter, request *http.Request) {
WriteJsonResponse(response, http.StatusOK, players)
}

var getClientPlayerMutex sync.Mutex

// Gets the web client's correspondant player (There is only ONE player per client!)
func GetClientPlayer(response http.ResponseWriter, request *http.Request) {
id := services.GetWebPlayerId(request)
getClientPlayerMutex.Lock()
defer getClientPlayerMutex.Unlock()
id := services.GetClientId(request)
player, err := playersRepository.GetPlayerById(id)
if err != nil {
if err == repositories.EntityNotExistsErr {
Expand Down
12 changes: 6 additions & 6 deletions presentation/web/controllers/websockets.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ func AdquireWebSocket(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusInternalServerError)
}
if !isNew {
msg := fmt.Sprintf("Web socket already adquired for client(id='%d')", services.GetWebPlayerId(r))
msg := fmt.Sprintf("Web socket already adquired for client(id='%d')", services.GetClientId(r))
log.Println(msg)
http.Error(w, msg, http.StatusBadRequest)
} else {
log.Printf("Web socket(RemoteAddr='%s') adquired OK (connection \"upgraded\") for client(id='%d')\n", conn.RemoteAddr().String(), services.GetWebPlayerId(r))
log.Printf("Web socket(RemoteAddr='%s') adquired OK (connection \"upgraded\") for client(id='%d')\n", conn.RemoteAddr().String(), services.GetClientId(r))
}
}

Expand All @@ -32,13 +32,13 @@ func ReleaseWebSocket(response http.ResponseWriter, request *http.Request) {
services.GameWebSockets.UnbindClientWebSocketInGame(conn, request) // just in case the ws is associated with a game, then delete the association
err := services.WebSocketsHandler.Release(request, "Connection closed gracefully")
if err != nil {
log.Printf("Error releasingWeb socket(RemoteAddr='%s') for client(id='%d')\n: %v\n", conn.RemoteAddr().String(), services.GetWebPlayerId(request), err)
log.Printf("Error releasingWeb socket(RemoteAddr='%s') for client(id='%d')\n: %v\n", conn.RemoteAddr().String(), services.GetClientId(request), err)
response.WriteHeader(http.StatusInternalServerError)
} else {
log.Printf("Web socket(RemoteAddr='%s') released OK for client(id='%d')\n", conn.RemoteAddr().String(), services.GetWebPlayerId(request))
log.Printf("Web socket(RemoteAddr='%s') released OK for client(id='%d')\n", conn.RemoteAddr().String(), services.GetClientId(request))
}
} else {
log.Printf("No need to release web socket as it was not adquired (or already released) for client(id='%d')\n", services.GetWebPlayerId(request))
log.Printf("No need to release web socket as it was not adquired (or already released) for client(id='%d')\n", services.GetClientId(request))
response.WriteHeader(http.StatusBadRequest)
}
}
Expand All @@ -49,7 +49,7 @@ type ServerMessage struct {
}

func SendMessageWebSocket(response http.ResponseWriter, request *http.Request) {
playerId := services.GetWebPlayerId(request)
playerId := services.GetClientId(request)
message, err := getPingMessageOrDefault(request)
if err != nil {
log.Printf("error getting ping message: '%v'", err)
Expand Down
40 changes: 20 additions & 20 deletions presentation/web/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,35 +132,35 @@ func buildRouter() *mux.Router {
apiDelete := BuildSetHandleFunc(apiRouter, "DELETE")

apiGet("/games", controllers.GetGames)
apiGet("/games/{id:[0-9]+}", controllers.GetGameById)
apiGet("/games/{id:[+-]?[0-9]+}", controllers.GetGameById)
apiPost("/games", controllers.CreateGame)
apiPost("/games/{id:[0-9]+}/message", controllers.SendMessage)
apiPost("/games/{id:[+-]?[0-9]+}/message", controllers.SendMessage)
// TODO : usage of game's id instead of game as parameter for game related endpoints.
//apiPut("/games/{id:[0-9]+}", controllers.UpdateGame)
apiDelete("/games/{id:[0-9]+}", controllers.DeleteGame)
apiPost("/games/{id:[0-9]+}/start", controllers.StartGame)
apiPost("/games/{id:[0-9]+}/join", controllers.JoinGame)
apiPost("/games/{id:[0-9]+}/quit", controllers.QuitGame)
apiPost("/games/{id:[0-9]+}/add-computer", controllers.AddComputer)
apiPost("/games/{id:[0-9]+}/perform-take-action", controllers.PerformTakeAction)
apiPost("/games/{id:[0-9]+}/perform-drop-action", controllers.PerformDropAction)
apiGet("/games/{id:[0-9]+}/calculate-stats", controllers.CalculateGameStats)

apiGet("/games/{id:[0-9]+}/bind-ws", controllers.BindClientWebSocketToGame)
apiGet("/games/{id:[0-9]+}/unbind-ws", controllers.UnbindClientWebSocketInGame)
//apiPut("/games/{id:[+-]?[0-9]+}", controllers.UpdateGame)
apiDelete("/games/{id:[+-]?[0-9]+}", controllers.DeleteGame)
apiPost("/games/{id:[+-]?[0-9]+}/start", controllers.StartGame)
apiPost("/games/{id:[+-]?[0-9]+}/join", controllers.JoinGame)
apiPost("/games/{id:[+-]?[0-9]+}/quit", controllers.QuitGame)
apiPost("/games/{id:[+-]?[0-9]+}/add-computer", controllers.AddComputer)
apiPost("/games/{id:[+-]?[0-9]+}/perform-take-action", controllers.PerformTakeAction)
apiPost("/games/{id:[+-]?[0-9]+}/perform-drop-action", controllers.PerformDropAction)
apiGet("/games/{id:[+-]?[0-9]+}/calculate-stats", controllers.CalculateGameStats)

apiGet("/games/{id:[+-]?[0-9]+}/bind-ws", controllers.BindClientWebSocketToGame)
apiGet("/games/{id:[+-]?[0-9]+}/unbind-ws", controllers.UnbindClientWebSocketInGame)

apiGet("/players", controllers.GetPlayers)
apiGet("/players-by-game", controllers.GetPlayersByGame) // TODO: Implement if necessary...
apiGet("/player", controllers.GetClientPlayer)
apiGet("/players/{id:[0-9]+}", controllers.GetPlayerById)
apiPut("/players/{id:[0-9]+}", controllers.UpdatePlayer)
apiGet("/players/{id:[+-]?[0-9]+}", controllers.GetPlayerById)
apiPut("/players/{id:[+-]?[0-9]+}", controllers.UpdatePlayer)

apiGet("/messages", controllers.GetMessages) // TODO : add optional parameter "since", default beign server start up time
apiGet("/messages/{id:[0-9]+}", controllers.GetMessageById)
apiGet("/messages/get-by-game/{id:[0-9]+}", controllers.GetMessagesByGame)
apiGet("/messages/{id:[+-]?[0-9]+}", controllers.GetMessageById)
apiGet("/messages/get-by-game/{id:[+-]?[0-9]+}", controllers.GetMessagesByGame)
apiPost("/messages", controllers.CreateMessage)
apiPut("/messages/{id:[0-9]+}", controllers.UpdateMessage)
apiDelete("/messages/{id:[0-9]+}", controllers.DeleteMessage)
apiPut("/messages/{id:[+-]?[0-9]+}", controllers.UpdateMessage)
apiDelete("/messages/{id:[+-]?[0-9]+}", controllers.DeleteMessage)

return router
}
Expand Down
13 changes: 13 additions & 0 deletions presentation/web/services/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package services

import (
"net/http"

"github.com/gorilla/sessions"
)

func GetClientId(request *http.Request) int {
clientSession := request.Context().Value("clientSession").(*sessions.Session)
wrappedInt, _ := clientSession.Values["clientId"]
return wrappedInt.(int)
}
6 changes: 3 additions & 3 deletions presentation/web/services/games_websockets.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func (gws *gameWebSockets) NotifyGameConns(gameId int, kind string, data interfa
}

func (gws *gameWebSockets) BindClientWebSocketToGame(response http.ResponseWriter, request *http.Request, gameId int) {
log.Printf("Binding web socket from client(id=%d) in game(id=%d)...", GetWebPlayerId(request), gameId)
log.Printf("Binding web socket from client(id=%d) in game(id=%d)...", GetClientId(request), gameId)
conn, _, err := WebSocketsHandler.AdquireOrRetrieve(response, request)
if err != nil {
log.Println(err)
Expand All @@ -56,15 +56,15 @@ func (gws *gameWebSockets) BindClientWebSocketToGame(response http.ResponseWrite

for _, exstingConn := range gws.ConnsByGameId[gameId] {
if exstingConn == conn {
msg := fmt.Sprintf("Web socket(remoteAddr='%s') from client(id=%d) already binded in game(id=%d)", conn.RemoteAddr().String(), GetWebPlayerId(request), gameId)
msg := fmt.Sprintf("Web socket(remoteAddr='%s') from client(id=%d) already binded in game(id=%d)", conn.RemoteAddr().String(), GetClientId(request), gameId)
log.Println(msg)
http.Error(response, msg, http.StatusBadRequest)
return
}
}

gws.ConnsByGameId[gameId] = append(gws.ConnsByGameId[gameId], conn)
log.Printf("Binded web socket(remoteAddr='%s') from client(id=%d) in game(id=%d)", conn.RemoteAddr().String(), GetWebPlayerId(request), gameId)
log.Printf("Binded web socket(remoteAddr='%s') from client(id=%d) in game(id=%d)", conn.RemoteAddr().String(), GetClientId(request), gameId)
}

func (gws *gameWebSockets) UnbindAllWebSocketsInGame(gameId int, request *http.Request) {
Expand Down
10 changes: 1 addition & 9 deletions presentation/web/services/websockets.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import (
"sync"
"time"

"github.com/gorilla/sessions"

"github.com/gorilla/websocket"
)

Expand Down Expand Up @@ -82,11 +80,5 @@ func (h *webSocketsHandler) DoRelease(clientId int, reason string) error {

var (
ConnectionDoesntExistErr = errors.New("Connection doesn't exists")
WebSocketsHandler = NewWebSocketsHandler(GetWebPlayerId)
WebSocketsHandler = NewWebSocketsHandler(GetClientId)
)

func GetWebPlayerId(request *http.Request) int {
clientSession := request.Context().Value("clientSession").(*sessions.Session)
wrappedInt, _ := clientSession.Values["clientId"]
return wrappedInt.(int)
}

0 comments on commit c86d297

Please sign in to comment.