get-lobby-from-passphrase #11
@ -1,25 +1,49 @@
|
|||||||
package handler
|
package handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
"mchess_server/api"
|
"mchess_server/api"
|
||||||
|
"mchess_server/chess"
|
||||||
lobbies "mchess_server/lobby_registry"
|
lobbies "mchess_server/lobby_registry"
|
||||||
|
"mchess_server/usher"
|
||||||
"mchess_server/utils"
|
"mchess_server/utils"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetLobbyFromPassphraseHandler(c *gin.Context) {
|
var mut sync.Mutex
|
||||||
reqPassphrase := api.Passphrase{}
|
|
||||||
|
|
||||||
err := c.ShouldBindJSON(&reqPassphrase)
|
func HostPrivateGameHandler(c *gin.Context) {
|
||||||
if err != nil || reqPassphrase.Value == nil || *reqPassphrase.Value == "" {
|
player := chess.NewPlayer(uuid.New())
|
||||||
c.IndentedJSON(http.StatusNotFound, reqPassphrase)
|
u := usher.GetUsher()
|
||||||
|
|
||||||
|
mut.Lock()
|
||||||
|
defer mut.Unlock()
|
||||||
|
lobby := u.CreateNewPrivateLobby(player)
|
||||||
|
u.AddPlayerToLobbyAndStartGameIfFull(player, lobby)
|
||||||
|
|
||||||
|
passphrase := lobby.Passphrase.String()
|
||||||
|
info := api.PlayerInfo{
|
||||||
|
PlayerID: &player.Uuid,
|
||||||
|
LobbyID: &lobby.Uuid,
|
||||||
|
Passphrase: &passphrase,
|
||||||
|
}
|
||||||
|
c.Header("Access-Control-Allow-Origin", "*")
|
||||||
|
c.IndentedJSON(http.StatusOK, info)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetLobbyForPassphraseHandler(c *gin.Context) {
|
||||||
|
reqPassphrase := c.Param("phrase")
|
||||||
|
if reqPassphrase == "" {
|
||||||
|
c.IndentedJSON(http.StatusBadRequest, reqPassphrase)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
lobby := lobbies.GetLobbyRegistry().GetLobbyByPassphrase(
|
passPhraseWithSpaces := utils.ConvertToPassphraseWithSpaces(reqPassphrase)
|
||||||
utils.NewPassphraseFromString(*reqPassphrase.Value))
|
lobby := lobbies.GetLobbyRegistry().GetLobbyByPassphrase(passPhraseWithSpaces)
|
||||||
|
|
||||||
if lobby == nil {
|
if lobby == nil {
|
||||||
c.IndentedJSON(http.StatusNotFound, reqPassphrase)
|
c.IndentedJSON(http.StatusNotFound, reqPassphrase)
|
||||||
@ -32,3 +56,73 @@ func GetLobbyFromPassphraseHandler(c *gin.Context) {
|
|||||||
|
|
||||||
c.IndentedJSON(http.StatusOK, lobbyInfo)
|
c.IndentedJSON(http.StatusOK, lobbyInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func RegisterForRandomGame(c *gin.Context) {
|
||||||
|
player := chess.NewPlayer(uuid.New())
|
||||||
|
usher := usher.GetUsher()
|
||||||
|
|
||||||
|
mut.Lock()
|
||||||
|
defer mut.Unlock()
|
||||||
|
lobby := usher.WelcomeNewPlayer(player)
|
||||||
|
usher.AddPlayerToLobbyAndStartGameIfFull(player, lobby)
|
||||||
|
|
||||||
|
info := api.PlayerInfo{
|
||||||
|
PlayerID: &player.Uuid,
|
||||||
|
LobbyID: &lobby.Uuid,
|
||||||
|
}
|
||||||
|
log.Println("responding with info ", info)
|
||||||
|
|
||||||
|
c.Header("Access-Control-Allow-Origin", "*")
|
||||||
|
c.IndentedJSON(http.StatusOK, info)
|
||||||
|
}
|
||||||
|
|
||||||
|
func JoinPrivateGame(c *gin.Context) {
|
||||||
|
req := api.PlayerInfo{}
|
||||||
|
log.Println(c.Request.Body)
|
||||||
|
err := c.ShouldBindJSON(&req)
|
||||||
|
if err != nil || req.Passphrase == nil || *req.Passphrase == "" {
|
||||||
|
c.IndentedJSON(http.StatusNotFound, req)
|
||||||
|
}
|
||||||
|
|
||||||
|
u := usher.GetUsher()
|
||||||
|
|
||||||
|
if req.Passphrase != nil &&
|
||||||
|
*req.Passphrase != "" &&
|
||||||
|
req.PlayerID != nil &&
|
||||||
|
req.LobbyID != nil { //is reconnect
|
||||||
|
lobby := u.FindExistingPrivateLobby(utils.Passphrase(*req.Passphrase))
|
||||||
|
_, found := lobby.GetPlayerByUUID(*req.PlayerID)
|
||||||
|
if found {
|
||||||
|
c.IndentedJSON(
|
||||||
|
http.StatusOK,
|
||||||
|
api.PlayerInfo{
|
||||||
|
PlayerID: req.PlayerID,
|
||||||
|
LobbyID: req.LobbyID,
|
||||||
|
Passphrase: req.Passphrase,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
c.IndentedJSON(http.StatusNotFound, req)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
player := chess.NewPlayer(uuid.New())
|
||||||
|
|
||||||
|
mut.Lock()
|
||||||
|
defer mut.Unlock()
|
||||||
|
lobby := u.FindExistingPrivateLobby(utils.Passphrase(*req.Passphrase))
|
||||||
|
if lobby != nil {
|
||||||
|
u.AddPlayerToLobbyAndStartGameIfFull(player, lobby)
|
||||||
|
} else {
|
||||||
|
c.IndentedJSON(http.StatusNotFound, req)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
info := api.PlayerInfo{
|
||||||
|
PlayerID: &player.Uuid,
|
||||||
|
LobbyID: &lobby.Uuid,
|
||||||
|
Passphrase: req.Passphrase,
|
||||||
|
}
|
||||||
|
c.Header("Access-Control-Allow-Origin", "*")
|
||||||
|
c.IndentedJSON(http.StatusOK, info)
|
||||||
|
}
|
||||||
|
57
handler/handler_test.go
Normal file
57
handler/handler_test.go
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"mchess_server/api"
|
||||||
|
"mchess_server/utils"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_GetLobbyFromPassphraseHandler(t *testing.T) {
|
||||||
|
var passphraseURLParameter string
|
||||||
|
var hostedLobbyId uuid.UUID
|
||||||
|
|
||||||
|
t.Run("host a lobby", func(t *testing.T) {
|
||||||
|
r1 := httptest.NewRecorder()
|
||||||
|
ctx1, e1 := gin.CreateTestContext(r1)
|
||||||
|
e1.GET("/api/hostPrivate", HostPrivateGameHandler)
|
||||||
|
hostGameRequest, _ := http.NewRequest("GET", "/api/hostPrivate", nil)
|
||||||
|
ctx1.Request = hostGameRequest
|
||||||
|
|
||||||
|
e1.ServeHTTP(r1, hostGameRequest)
|
||||||
|
|
||||||
|
playerInfo := api.PlayerInfo{}
|
||||||
|
err := json.Unmarshal(r1.Body.Bytes(), &playerInfo)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
receivedPhrase := *playerInfo.Passphrase
|
||||||
|
hostedLobbyId = *playerInfo.LobbyID
|
||||||
|
|
||||||
|
passphrase := utils.NewPassphraseFromString(receivedPhrase)
|
||||||
|
passphraseURLParameter = passphrase.AsURLParam()
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("see if the lobby can be fetched by using the passphrase", func(t *testing.T) {
|
||||||
|
r2 := httptest.NewRecorder()
|
||||||
|
ctx2, engine := gin.CreateTestContext(r2)
|
||||||
|
engine.GET("/api/getLobbyForPassphrase/:phrase", GetLobbyForPassphraseHandler)
|
||||||
|
|
||||||
|
url := "/api/getLobbyForPassphrase/" + passphraseURLParameter
|
||||||
|
getLobbyRequest, _ := http.NewRequest("GET", url, nil)
|
||||||
|
ctx2.Request = getLobbyRequest
|
||||||
|
|
||||||
|
engine.ServeHTTP(r2, getLobbyRequest)
|
||||||
|
|
||||||
|
lobbyInfo := api.LobbyInfo{}
|
||||||
|
err := json.Unmarshal(r2.Body.Bytes(), &lobbyInfo)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, hostedLobbyId, *lobbyInfo.ID)
|
||||||
|
})
|
||||||
|
}
|
104
main.go
104
main.go
@ -7,22 +7,16 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"mchess_server/api"
|
"mchess_server/api"
|
||||||
"mchess_server/chess"
|
"mchess_server/handler"
|
||||||
lobbies "mchess_server/lobby_registry"
|
lobbies "mchess_server/lobby_registry"
|
||||||
"mchess_server/usher"
|
|
||||||
"mchess_server/utils"
|
|
||||||
"net/http"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/google/uuid"
|
|
||||||
"nhooyr.io/websocket"
|
"nhooyr.io/websocket"
|
||||||
)
|
)
|
||||||
|
|
||||||
var cert_path = "/etc/letsencrypt/live/chess.sw-gross.de/"
|
var cert_path = "/etc/letsencrypt/live/chess.sw-gross.de/"
|
||||||
var cert_file = cert_path + "fullchain.pem"
|
var cert_file = cert_path + "fullchain.pem"
|
||||||
var key_file = cert_path + "privkey.pem"
|
var key_file = cert_path + "privkey.pem"
|
||||||
var mut sync.Mutex
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var debugMode bool
|
var debugMode bool
|
||||||
@ -35,10 +29,11 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
router := gin.Default()
|
router := gin.Default()
|
||||||
router.GET("/api/random", registerForRandomGame)
|
router.GET("/api/random", handler.RegisterForRandomGame)
|
||||||
router.GET("/api/hostPrivate", hostPrivateGame)
|
router.GET("/api/hostPrivate", handler.HostPrivateGameHandler)
|
||||||
router.POST("/api/joinPrivate", joinPrivateGame)
|
router.POST("/api/joinPrivate", handler.JoinPrivateGame)
|
||||||
router.GET("/api/ws", registerWebSocketConnection)
|
router.GET("/api/ws", registerWebSocketConnection)
|
||||||
|
router.GET("/api/getLobbyForPassphrase/:phrase", handler.GetLobbyForPassphraseHandler)
|
||||||
|
|
||||||
if debugMode {
|
if debugMode {
|
||||||
log.Println("Starting service WITHOUT TLS")
|
log.Println("Starting service WITHOUT TLS")
|
||||||
@ -51,95 +46,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func registerForRandomGame(c *gin.Context) {
|
|
||||||
player := chess.NewPlayer(uuid.New())
|
|
||||||
usher := usher.GetUsher()
|
|
||||||
|
|
||||||
mut.Lock()
|
|
||||||
defer mut.Unlock()
|
|
||||||
lobby := usher.WelcomeNewPlayer(player)
|
|
||||||
usher.AddPlayerToLobbyAndStartGameIfFull(player, lobby)
|
|
||||||
|
|
||||||
info := api.PlayerInfo{
|
|
||||||
PlayerID: &player.Uuid,
|
|
||||||
LobbyID: &lobby.Uuid,
|
|
||||||
}
|
|
||||||
log.Println("responding with info ", info)
|
|
||||||
|
|
||||||
c.Header("Access-Control-Allow-Origin", "*")
|
|
||||||
c.IndentedJSON(http.StatusOK, info)
|
|
||||||
}
|
|
||||||
|
|
||||||
func hostPrivateGame(c *gin.Context) {
|
|
||||||
player := chess.NewPlayer(uuid.New())
|
|
||||||
u := usher.GetUsher()
|
|
||||||
|
|
||||||
mut.Lock()
|
|
||||||
defer mut.Unlock()
|
|
||||||
lobby := u.CreateNewPrivateLobby(player)
|
|
||||||
u.AddPlayerToLobbyAndStartGameIfFull(player, lobby)
|
|
||||||
|
|
||||||
passphrase := lobby.Passphrase.String()
|
|
||||||
info := api.PlayerInfo{
|
|
||||||
PlayerID: &player.Uuid,
|
|
||||||
LobbyID: &lobby.Uuid,
|
|
||||||
Passphrase: &passphrase,
|
|
||||||
}
|
|
||||||
c.Header("Access-Control-Allow-Origin", "*")
|
|
||||||
c.IndentedJSON(http.StatusOK, info)
|
|
||||||
}
|
|
||||||
|
|
||||||
func joinPrivateGame(c *gin.Context) {
|
|
||||||
req := api.PlayerInfo{}
|
|
||||||
log.Println(c.Request.Body)
|
|
||||||
err := c.ShouldBindJSON(&req)
|
|
||||||
if err != nil || req.Passphrase == nil || *req.Passphrase == "" {
|
|
||||||
c.IndentedJSON(http.StatusNotFound, req)
|
|
||||||
}
|
|
||||||
|
|
||||||
u := usher.GetUsher()
|
|
||||||
|
|
||||||
if req.Passphrase != nil &&
|
|
||||||
*req.Passphrase != "" &&
|
|
||||||
req.PlayerID != nil &&
|
|
||||||
req.LobbyID != nil { //is reconnect
|
|
||||||
lobby := u.FindExistingPrivateLobby(utils.Passphrase(*req.Passphrase))
|
|
||||||
_, found := lobby.GetPlayerByUUID(*req.PlayerID)
|
|
||||||
if found {
|
|
||||||
c.IndentedJSON(
|
|
||||||
http.StatusOK,
|
|
||||||
api.PlayerInfo{
|
|
||||||
PlayerID: req.PlayerID,
|
|
||||||
LobbyID: req.LobbyID,
|
|
||||||
Passphrase: req.Passphrase,
|
|
||||||
})
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
c.IndentedJSON(http.StatusNotFound, req)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
player := chess.NewPlayer(uuid.New())
|
|
||||||
|
|
||||||
mut.Lock()
|
|
||||||
defer mut.Unlock()
|
|
||||||
lobby := u.FindExistingPrivateLobby(utils.Passphrase(*req.Passphrase))
|
|
||||||
if lobby != nil {
|
|
||||||
u.AddPlayerToLobbyAndStartGameIfFull(player, lobby)
|
|
||||||
} else {
|
|
||||||
c.IndentedJSON(http.StatusNotFound, req)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
info := api.PlayerInfo{
|
|
||||||
PlayerID: &player.Uuid,
|
|
||||||
LobbyID: &lobby.Uuid,
|
|
||||||
Passphrase: req.Passphrase,
|
|
||||||
}
|
|
||||||
c.Header("Access-Control-Allow-Origin", "*")
|
|
||||||
c.IndentedJSON(http.StatusOK, info)
|
|
||||||
}
|
|
||||||
|
|
||||||
func registerWebSocketConnection(c *gin.Context) {
|
func registerWebSocketConnection(c *gin.Context) {
|
||||||
webSocketConn, err := websocket.Accept(c.Writer, c.Request, &websocket.AcceptOptions{OriginPatterns: []string{"chess.sw-gross.de", "localhost:*"}})
|
webSocketConn, err := websocket.Accept(c.Writer, c.Request, &websocket.AcceptOptions{OriginPatterns: []string{"chess.sw-gross.de", "localhost:*"}})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -28006,7 +28006,6 @@ var CleanWords = []string{
|
|||||||
"joystick",
|
"joystick",
|
||||||
"joysticks",
|
"joysticks",
|
||||||
"jpeg",
|
"jpeg",
|
||||||
"jpn",
|
|
||||||
"juan",
|
"juan",
|
||||||
"juana",
|
"juana",
|
||||||
"juanita",
|
"juanita",
|
||||||
|
@ -2,6 +2,7 @@ package utils
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
|
"unicode"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Passphrase string
|
type Passphrase string
|
||||||
@ -24,6 +25,33 @@ func NewPassphraseFromString(s string) Passphrase {
|
|||||||
return Passphrase(s)
|
return Passphrase(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p Passphrase) AsURLParam() string {
|
||||||
|
var result string
|
||||||
|
phraseAsString := p.String()
|
||||||
|
|
||||||
|
segments := strings.Split(phraseAsString, " ")
|
||||||
|
|
||||||
|
for _, segment := range segments {
|
||||||
|
runes := []rune(segment)
|
||||||
|
runes[0] = unicode.ToUpper(runes[0])
|
||||||
|
result += string(runes)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertToPassphraseWithSpaces(s string) Passphrase {
|
||||||
|
result := ""
|
||||||
|
for _, rune := range s {
|
||||||
|
if unicode.IsUpper(rune) {
|
||||||
|
result += " "
|
||||||
|
}
|
||||||
|
result += strings.ToLower(string(rune))
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewPassphraseFromString(strings.Trim(result, " "))
|
||||||
|
}
|
||||||
|
|
||||||
func (p Passphrase) String() string {
|
func (p Passphrase) String() string {
|
||||||
return string(p)
|
return string(p)
|
||||||
}
|
}
|
||||||
|
@ -19,3 +19,18 @@ func Test_onlyUniqueWords(t *testing.T) {
|
|||||||
|
|
||||||
assert.Equal(t, numberOfCleanWords, len(wordsDistribution))
|
assert.Equal(t, numberOfCleanWords, len(wordsDistribution))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_Passphrase_AsURLParam(t *testing.T) {
|
||||||
|
phrase := NewPassphraseFromString("this is a Test phrase")
|
||||||
|
|
||||||
|
asParams := phrase.AsURLParam()
|
||||||
|
|
||||||
|
assert.Equal(t, "ThisIsATestPhrase", asParams)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_Passphrase_ConvertToPassphraseWithSpaces(t *testing.T) {
|
||||||
|
fromURL := "ThisIsATestPhraseWithManyWords"
|
||||||
|
phrase := ConvertToPassphraseWithSpaces(fromURL)
|
||||||
|
|
||||||
|
assert.Equal(t, NewPassphraseFromString("this is a test phrase with many words"), phrase)
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user